diff --git a/packages/react-aria-components/src/ColorField.tsx b/packages/react-aria-components/src/ColorField.tsx
index 6bfbe0a7249..98dd799e728 100644
--- a/packages/react-aria-components/src/ColorField.tsx
+++ b/packages/react-aria-components/src/ColorField.tsx
@@ -44,6 +44,16 @@ export interface ColorFieldRenderProps {
* @selector [data-invalid]
*/
isInvalid: boolean,
+ /**
+ * Whether the color field is read only.
+ * @selector [data-readonly]
+ */
+ isReadOnly: boolean,
+ /**
+ * Whether the color field is required.
+ * @selector [data-required]
+ */
+ isRequired: boolean,
/**
* The color channel that this field edits, or "hex" if no `channel` prop is set.
* @selector [data-channel="hex | hue | saturation | ..."]
@@ -192,7 +202,9 @@ function useChildren(
state,
channel: props.channel || 'hex',
isDisabled: props.isDisabled || false,
- isInvalid: validation.isInvalid || false
+ isInvalid: validation.isInvalid || false,
+ isReadOnly: props.isReadOnly || false,
+ isRequired: props.isRequired || false
},
defaultClassName: 'react-aria-ColorField'
});
@@ -222,7 +234,9 @@ function useChildren(
slot={props.slot || undefined}
data-channel={props.channel || 'hex'}
data-disabled={props.isDisabled || undefined}
- data-invalid={validation.isInvalid || undefined} />
+ data-invalid={validation.isInvalid || undefined}
+ data-readonly={props.isReadOnly || undefined}
+ data-required={props.isRequired || undefined} />
);
}
diff --git a/packages/react-aria-components/test/ColorField.test.js b/packages/react-aria-components/test/ColorField.test.js
index 7b53495c326..987d3c31ae6 100644
--- a/packages/react-aria-components/test/ColorField.test.js
+++ b/packages/react-aria-components/test/ColorField.test.js
@@ -84,6 +84,30 @@ describe('ColorField', () => {
expect(input).toHaveValue('');
});
+ it('should support read-only state', async () => {
+ let {getByRole, rerender} = render(
+
+ );
+
+ let input = getByRole('textbox');
+
+ expect(input.closest('.react-aria-ColorField')).not.toHaveAttribute('data-readonly');
+ rerender();
+ expect(input.closest('.react-aria-ColorField')).toHaveAttribute('data-readonly');
+ });
+
+ it('should support required state', async () => {
+ let {getByRole, rerender} = render(
+
+ );
+
+ let input = getByRole('textbox');
+
+ expect(input.closest('.react-aria-ColorField')).not.toHaveAttribute('data-required');
+ rerender();
+ expect(input.closest('.react-aria-ColorField')).toHaveAttribute('data-required');
+ });
+
it('should render data- attributes only on the outer element', () => {
let {getAllByTestId} = render(