From 57e7fac384a4e7185ff523047f4afcba5cf950ef Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Thu, 1 Oct 2026 16:50:37 -0400 Subject: [PATCH 1/2] feat(mosaic): support checkboxes in Field with a horizontal orientation Co-authored-by: Claude Opus 5.5 --- .../mosaic-field-horizontal-checkbox.md | 2 + .../src/components/checkbox/checkbox.tsx | 28 +++++++++- .../src/components/field/field.context.tsx | 9 ++- .../src/components/field/field.styles.ts | 9 +++ .../src/components/field/field.test.tsx | 55 +++++++++++++++++++ .../mosaic/src/components/field/field.tsx | 46 ++++++++++++++-- .../swingset/src/stories/field.component.mdx | 21 ++++++- .../src/stories/field.component.stories.tsx | 22 ++++++++ 8 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 .changeset/mosaic-field-horizontal-checkbox.md diff --git a/.changeset/mosaic-field-horizontal-checkbox.md b/.changeset/mosaic-field-horizontal-checkbox.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/mosaic-field-horizontal-checkbox.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/mosaic/src/components/checkbox/checkbox.tsx b/packages/mosaic/src/components/checkbox/checkbox.tsx index a5e25adb302..16492d09efc 100644 --- a/packages/mosaic/src/components/checkbox/checkbox.tsx +++ b/packages/mosaic/src/components/checkbox/checkbox.tsx @@ -5,6 +5,7 @@ import type { MosaicStyleProps } from '../../props'; import { mergeStyleProps, themeProps } from '../../props'; import { focusOutline } from '../../utils/focus-outline.styles'; import { reset } from '../../utils/reset.styles'; +import { useOptionalFieldControlProps } from '../field/field.context'; import { Icon } from '../icon'; import { checkboxInputMarker } from './checkbox.markers.stylex'; import { indicatorSizes, sizes, styles } from './checkbox.styles'; @@ -16,9 +17,29 @@ export interface CheckboxProps } export const Checkbox = React.forwardRef(function MosaicCheckbox( - { size = 'md', indeterminate = false, disabled, xstyle, ...rest }, + { + size = 'md', + indeterminate = false, + disabled: disabledProp, + required: requiredProp, + id, + 'aria-invalid': ariaInvalid, + 'aria-labelledby': ariaLabelledBy, + 'aria-describedby': ariaDescribedBy, + xstyle, + ...rest + }, ref, ) { + const fieldProps = useOptionalFieldControlProps({ + id, + disabled: disabledProp, + required: requiredProp, + ariaInvalid, + ariaLabelledBy, + ariaDescribedBy, + }); + const disabled = fieldProps?.disabled ?? disabledProp; const setInputRef = React.useCallback( (node: HTMLInputElement | null) => { if (node) { @@ -44,6 +65,11 @@ export const Checkbox = React.forwardRef(functi ref={setInputRef} type='checkbox' disabled={disabled} + required={fieldProps?.required ?? requiredProp} + id={fieldProps?.id ?? id} + aria-invalid={fieldProps?.['aria-invalid'] ?? ariaInvalid} + aria-labelledby={fieldProps?.['aria-labelledby'] ?? ariaLabelledBy} + aria-describedby={fieldProps?.['aria-describedby'] ?? ariaDescribedBy} {...mergeStyleProps( themeProps('checkbox-input'), stylex.props( diff --git a/packages/mosaic/src/components/field/field.context.tsx b/packages/mosaic/src/components/field/field.context.tsx index 514e0f0541e..d1895463cea 100644 --- a/packages/mosaic/src/components/field/field.context.tsx +++ b/packages/mosaic/src/components/field/field.context.tsx @@ -4,6 +4,8 @@ import React from 'react'; /** `label` for natively labelable controls; `span` for a control a `