diff --git a/packages/react/src/components/fieldset/fieldset.test.tsx b/packages/react/src/components/fieldset/fieldset.test.tsx index 5c04f00ec4..f7d4cc3616 100644 --- a/packages/react/src/components/fieldset/fieldset.test.tsx +++ b/packages/react/src/components/fieldset/fieldset.test.tsx @@ -21,67 +21,115 @@ describe('Fieldset Component', () => { it('generates an ID if none is provided', () => { const tree = mountWithProviders( -
+
Test Content
, ); const fieldset = tree.find('fieldset'); + const legend = tree.find(Legend); expect(fieldset.props()).toHaveProperty('id'); + expect(legend.props()).toHaveProperty('id', `${fieldset.props().id}-legend`); }); - it('does not render a legend when not provided', () => { + it('renders a legend with provided text', () => { const tree = mountWithProviders( -
+
Test Content
, ); const legend = tree.find(Legend); - expect(legend.exists()).toBeFalsy(); + expect(legend.prop('children')).toBe('Legend Text'); + }); + + it('updates legend text dynamically', () => { + const tree = mountWithProviders( +
+ Test Content +
, + ); + + tree.setProps({ legend: { text: 'Updated Legend Text' } }); + + expect(tree.find(Legend).text()).toContain('Updated Legend Text'); }); - it('renders a legend when props provided', () => { + it('handles string legend prop', () => { const tree = mountWithProviders( -
+
Test Content
, ); const legend = tree.find(Legend); + expect(legend.prop('children')).toBe('Simple Legend Text'); + }); - expect(legend.prop('children')).toBe('Legend text'); + it('handles object legend prop with additional properties', () => { + const tree = mountWithProviders( +
+ Test Content +
, + ); + + const legend = tree.find(Legend); + expect(legend.prop('children')).toBe('Complex Legend Text'); + expect(legend.prop('size')).toBe('large'); + expect(legend.prop('bold')).toBe(true); }); - it('updates legend text dynamically', () => { + it('updates legend from string to object prop', () => { const tree = mountWithProviders( -
+
Test Content
, ); - tree.setProps({ legend: { text: 'Updated Legend Text' } }); + tree.setProps({ + legend: { + text: 'Complex Legend', + size: 'large', + }, + }); - expect(tree.find(Legend).text()).toContain('Updated Legend Text'); + const legend = tree.find(Legend); + expect(legend.prop('children')).toBe('Complex Legend'); + expect(legend.prop('size')).toBe('large'); }); - }); - describe('Styling', () => { - it('matches default', () => { + it('updates legend from object to string prop', () => { const tree = mountWithProviders( -
+
Test Content
, ); - expect(tree).toMatchSnapshot(); + tree.setProps({ legend: 'Simple Legend' }); + + const legend = tree.find(Legend); + expect(legend.prop('children')).toBe('Simple Legend'); + expect(legend.prop('size')).toBeUndefined(); }); + }); - it('matches with bold legend', () => { + describe('Styling', () => { + it('matches default', () => { const tree = mountWithProviders( -
+
Test Content
, ); @@ -89,9 +137,9 @@ describe('Fieldset Component', () => { expect(tree).toMatchSnapshot(); }); - it('matches with disabled legend', () => { + it('matches with bold legend', () => { const tree = mountWithProviders( -
+
Test Content
, ); @@ -99,37 +147,33 @@ describe('Fieldset Component', () => { expect(tree).toMatchSnapshot(); }); - it('matches vertical orientation', () => { + it('matches with disabled legend', () => { const tree = mountWithProviders( -
+
Test Content
, ); - const fieldset = tree.find('fieldset'); - expect(tree).toMatchSnapshot(); - expect(fieldset.props()).toHaveProperty('data-orientation', 'vertical'); }); - it('matches horizontal orientation', () => { + it('matches with string legend', () => { const tree = mountWithProviders( -
+
Test Content
, ); - const fieldset = tree.find('fieldset'); - expect(tree).toMatchSnapshot(); - expect(fieldset.props()).toHaveProperty('data-orientation', 'horizontal'); }); }); describe('Accessibility', () => { it('applies aria-label when provided', () => { const tree = mountWithProviders( -
Test Content
, +
+ Test Content +
, ); const fieldset = tree.find('fieldset'); @@ -139,24 +183,14 @@ describe('Fieldset Component', () => { it('applies aria-disabled when provided', () => { const tree = mountWithProviders( -
Test Content
, - ); - - const fieldset = tree.find('fieldset'); - - expect(fieldset.props()).toHaveProperty('aria-disabled', true); - }); - - it('applies role to specified group role', () => { - const tree = mountWithProviders( -
+
Test Content
, ); const fieldset = tree.find('fieldset'); - expect(fieldset.props()).toHaveProperty('role', 'group'); + expect(fieldset.props()).toHaveProperty('aria-disabled', true); }); }); }); diff --git a/packages/react/src/components/fieldset/fieldset.test.tsx.snap b/packages/react/src/components/fieldset/fieldset.test.tsx.snap index 8884241a8f..acdfd5cd64 100644 --- a/packages/react/src/components/fieldset/fieldset.test.tsx.snap +++ b/packages/react/src/components/fieldset/fieldset.test.tsx.snap @@ -1,48 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Fieldset Component Styling matches default 1`] = ` -.c0 { - border: 0; - border: none; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - gap: var(--spacing-1x); - margin: 0; - min-inline-size: 0; - min-width: 0; - padding: 0; -} - -.c0:disabled legend, -.c0[aria-disabled='true'] legend { - color: #B7BBC2; +.c1 { + color: #1B1C1E; + font-size: 0.75rem; + font-weight: var(--font-normal); + margin: 0 0 var(--spacing-1x); } - - -
- Test Content -
-
-
-`; - -exports[`Fieldset Component Styling matches horizontal orientation 1`] = ` .c0 { border: 0; border: none; @@ -50,9 +15,6 @@ exports[`Fieldset Component Styling matches horizontal orientation 1`] = ` display: -webkit-flex; display: -ms-flexbox; display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; gap: var(--spacing-1x); margin: 0; min-inline-size: 0; @@ -66,27 +28,52 @@ exports[`Fieldset Component Styling matches horizontal orientation 1`] = ` }
+ + + + Default Legend + + + Test Content
`; -exports[`Fieldset Component Styling matches vertical orientation 1`] = ` +exports[`Fieldset Component Styling matches with bold legend 1`] = ` +.c1 { + color: #1B1C1E; + font-size: 0.75rem; + font-weight: var(--font-bold); + margin: 0 0 var(--spacing-1x); +} + .c0 { border: 0; border: none; @@ -94,9 +81,6 @@ exports[`Fieldset Component Styling matches vertical orientation 1`] = ` display: -webkit-flex; display: -ms-flexbox; display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; gap: var(--spacing-1x); margin: 0; min-inline-size: 0; @@ -110,31 +94,52 @@ exports[`Fieldset Component Styling matches vertical orientation 1`] = ` }
+ + + + Bold Legend + + + Test Content
`; -exports[`Fieldset Component Styling matches with bold legend 1`] = ` +exports[`Fieldset Component Styling matches with disabled legend 1`] = ` .c1 { color: #1B1C1E; font-size: 0.75rem; - font-weight: var(--font-bold); + font-weight: var(--font-normal); margin: 0 0 var(--spacing-1x); } @@ -145,9 +150,6 @@ exports[`Fieldset Component Styling matches with bold legend 1`] = ` display: -webkit-flex; display: -ms-flexbox; display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; gap: var(--spacing-1x); margin: 0; min-inline-size: 0; @@ -161,40 +163,40 @@ exports[`Fieldset Component Styling matches with bold legend 1`] = ` }
- Text Legend + Disabled Legend @@ -204,7 +206,7 @@ exports[`Fieldset Component Styling matches with bold legend 1`] = ` `; -exports[`Fieldset Component Styling matches with disabled legend 1`] = ` +exports[`Fieldset Component Styling matches with string legend 1`] = ` .c1 { color: #1B1C1E; font-size: 0.75rem; @@ -219,9 +221,6 @@ exports[`Fieldset Component Styling matches with disabled legend 1`] = ` display: -webkit-flex; display: -ms-flexbox; display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; gap: var(--spacing-1x); margin: 0; min-inline-size: 0; @@ -235,42 +234,31 @@ exports[`Fieldset Component Styling matches with disabled legend 1`] = ` }
- Text Legend + Simple Legend diff --git a/packages/react/src/components/fieldset/fieldset.tsx b/packages/react/src/components/fieldset/fieldset.tsx index d8355ca62d..06ce7faf21 100644 --- a/packages/react/src/components/fieldset/fieldset.tsx +++ b/packages/react/src/components/fieldset/fieldset.tsx @@ -7,33 +7,30 @@ import { FieldsetProps } from './types'; export const Fieldset = forwardRef(({ id: providedId, children, - orientation = 'vertical', legend, disabled, ...props }: FieldsetProps, ref: Ref): ReactElement => { const id = useId(providedId); - const { text, ...legendProps } = legend || {}; + const legendProps = typeof legend === 'string' + ? { text: legend } + : legend; return ( - {legend && ( - - {text} - - )} + + {legendProps.text} + {children} ); diff --git a/packages/react/src/components/fieldset/legend.test.tsx b/packages/react/src/components/fieldset/legend.test.tsx index 010264dff0..f088463193 100644 --- a/packages/react/src/components/fieldset/legend.test.tsx +++ b/packages/react/src/components/fieldset/legend.test.tsx @@ -4,7 +4,7 @@ import { Legend } from './legend'; import { LegendSize } from './types'; describe('Legend Component', () => { - const sizes: LegendSize[] = ['small', 'medium', 'large']; + const sizes: LegendSize[] = ['xxsmall', 'xsmall', 'small', 'medium', 'large']; const boldStates = [true, false]; const devices: DeviceContextProviderProps['staticDevice'][] = ['mobile', 'desktop']; diff --git a/packages/react/src/components/fieldset/legend.test.tsx.snap b/packages/react/src/components/fieldset/legend.test.tsx.snap index 4d08175685..ab7fcfb28c 100644 --- a/packages/react/src/components/fieldset/legend.test.tsx.snap +++ b/packages/react/src/components/fieldset/legend.test.tsx.snap @@ -3,7 +3,7 @@ exports[`Legend Component Styling Device: desktop Size: large Bold: false 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.875rem; + font-size: 1.5rem; font-weight: var(--font-normal); margin: 0 0 var(--spacing-1x); } @@ -14,7 +14,6 @@ exports[`Legend Component Styling Device: desktop Size: large Bold: false 1`] = > @@ -30,7 +29,7 @@ exports[`Legend Component Styling Device: desktop Size: large Bold: false 1`] = exports[`Legend Component Styling Device: desktop Size: large Bold: true 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.875rem; + font-size: 1.5rem; font-weight: var(--font-bold); margin: 0 0 var(--spacing-1x); } @@ -41,7 +40,6 @@ exports[`Legend Component Styling Device: desktop Size: large Bold: true 1`] = ` > @@ -57,7 +55,7 @@ exports[`Legend Component Styling Device: desktop Size: large Bold: true 1`] = ` exports[`Legend Component Styling Device: desktop Size: medium Bold: false 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.75rem; + font-size: 1.25rem; font-weight: var(--font-normal); margin: 0 0 var(--spacing-1x); } @@ -68,7 +66,6 @@ exports[`Legend Component Styling Device: desktop Size: medium Bold: false 1`] = > @@ -84,7 +81,7 @@ exports[`Legend Component Styling Device: desktop Size: medium Bold: false 1`] = exports[`Legend Component Styling Device: desktop Size: medium Bold: true 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.75rem; + font-size: 1.25rem; font-weight: var(--font-bold); margin: 0 0 var(--spacing-1x); } @@ -95,7 +92,6 @@ exports[`Legend Component Styling Device: desktop Size: medium Bold: true 1`] = > @@ -111,7 +107,7 @@ exports[`Legend Component Styling Device: desktop Size: medium Bold: true 1`] = exports[`Legend Component Styling Device: desktop Size: small Bold: false 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.625rem; + font-size: 1rem; font-weight: var(--font-normal); margin: 0 0 var(--spacing-1x); } @@ -122,7 +118,6 @@ exports[`Legend Component Styling Device: desktop Size: small Bold: false 1`] = > @@ -138,7 +133,7 @@ exports[`Legend Component Styling Device: desktop Size: small Bold: false 1`] = exports[`Legend Component Styling Device: desktop Size: small Bold: true 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.625rem; + font-size: 1rem; font-weight: var(--font-bold); margin: 0 0 var(--spacing-1x); } @@ -149,7 +144,6 @@ exports[`Legend Component Styling Device: desktop Size: small Bold: true 1`] = ` > @@ -162,10 +156,114 @@ exports[`Legend Component Styling Device: desktop Size: small Bold: true 1`] = ` `; +exports[`Legend Component Styling Device: desktop Size: xsmall Bold: false 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.875rem; + font-weight: var(--font-normal); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; + +exports[`Legend Component Styling Device: desktop Size: xsmall Bold: true 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.875rem; + font-weight: var(--font-bold); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; + +exports[`Legend Component Styling Device: desktop Size: xxsmall Bold: false 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.75rem; + font-weight: var(--font-normal); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; + +exports[`Legend Component Styling Device: desktop Size: xxsmall Bold: true 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.75rem; + font-weight: var(--font-bold); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; + exports[`Legend Component Styling Device: mobile Size: large Bold: false 1`] = ` .c0 { color: #1B1C1E; - font-size: 1rem; + font-size: 1.5rem; font-weight: var(--font-normal); margin: 0 0 var(--spacing-1x); } @@ -176,7 +274,6 @@ exports[`Legend Component Styling Device: mobile Size: large Bold: false 1`] = ` > @@ -192,7 +289,7 @@ exports[`Legend Component Styling Device: mobile Size: large Bold: false 1`] = ` exports[`Legend Component Styling Device: mobile Size: large Bold: true 1`] = ` .c0 { color: #1B1C1E; - font-size: 1rem; + font-size: 1.5rem; font-weight: var(--font-bold); margin: 0 0 var(--spacing-1x); } @@ -203,7 +300,6 @@ exports[`Legend Component Styling Device: mobile Size: large Bold: true 1`] = ` > @@ -219,7 +315,7 @@ exports[`Legend Component Styling Device: mobile Size: large Bold: true 1`] = ` exports[`Legend Component Styling Device: mobile Size: medium Bold: false 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.875rem; + font-size: 1.25rem; font-weight: var(--font-normal); margin: 0 0 var(--spacing-1x); } @@ -230,7 +326,6 @@ exports[`Legend Component Styling Device: mobile Size: medium Bold: false 1`] = > @@ -246,7 +341,7 @@ exports[`Legend Component Styling Device: mobile Size: medium Bold: false 1`] = exports[`Legend Component Styling Device: mobile Size: medium Bold: true 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.875rem; + font-size: 1.25rem; font-weight: var(--font-bold); margin: 0 0 var(--spacing-1x); } @@ -257,7 +352,6 @@ exports[`Legend Component Styling Device: mobile Size: medium Bold: true 1`] = ` > @@ -273,7 +367,7 @@ exports[`Legend Component Styling Device: mobile Size: medium Bold: true 1`] = ` exports[`Legend Component Styling Device: mobile Size: small Bold: false 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.75rem; + font-size: 1rem; font-weight: var(--font-normal); margin: 0 0 var(--spacing-1x); } @@ -284,7 +378,6 @@ exports[`Legend Component Styling Device: mobile Size: small Bold: false 1`] = ` > @@ -300,7 +393,7 @@ exports[`Legend Component Styling Device: mobile Size: small Bold: false 1`] = ` exports[`Legend Component Styling Device: mobile Size: small Bold: true 1`] = ` .c0 { color: #1B1C1E; - font-size: 0.75rem; + font-size: 1rem; font-weight: var(--font-bold); margin: 0 0 var(--spacing-1x); } @@ -311,7 +404,6 @@ exports[`Legend Component Styling Device: mobile Size: small Bold: true 1`] = ` > @@ -323,3 +415,107 @@ exports[`Legend Component Styling Device: mobile Size: small Bold: true 1`] = ` `; + +exports[`Legend Component Styling Device: mobile Size: xsmall Bold: false 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.875rem; + font-weight: var(--font-normal); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; + +exports[`Legend Component Styling Device: mobile Size: xsmall Bold: true 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.875rem; + font-weight: var(--font-bold); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; + +exports[`Legend Component Styling Device: mobile Size: xxsmall Bold: false 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.75rem; + font-weight: var(--font-normal); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; + +exports[`Legend Component Styling Device: mobile Size: xxsmall Bold: true 1`] = ` +.c0 { + color: #1B1C1E; + font-size: 0.75rem; + font-weight: var(--font-bold); + margin: 0 0 var(--spacing-1x); +} + + + + + Sample Legend + + + +`; diff --git a/packages/react/src/components/fieldset/legend.tsx b/packages/react/src/components/fieldset/legend.tsx index 033ddbaf06..96a893d17f 100644 --- a/packages/react/src/components/fieldset/legend.tsx +++ b/packages/react/src/components/fieldset/legend.tsx @@ -1,5 +1,4 @@ import { FC } from 'react'; -import { useDeviceContext } from '../device-context-provider/device-context-provider'; import { StyledLegend } from './styled'; import { LegendProps } from './types'; @@ -8,18 +7,13 @@ export const Legend: FC = ({ size, bold, ...props -}) => { - const { isMobile } = useDeviceContext(); - - return ( - - {children} - - ); -}; +}) => ( + + {children} + +); diff --git a/packages/react/src/components/fieldset/styled.ts b/packages/react/src/components/fieldset/styled.ts index 8cedcf7b28..a496666e3b 100644 --- a/packages/react/src/components/fieldset/styled.ts +++ b/packages/react/src/components/fieldset/styled.ts @@ -1,17 +1,20 @@ import styled from 'styled-components'; import { FieldsetProps, LegendProps } from './types'; -function getFontSize({ $isMobile, $size = 'medium' }: { $isMobile: boolean, $size?: LegendProps['size'] }): string { - const mobileSizes = { small: '0.75rem', medium: '0.875rem', large: '1rem' }; - const desktopSizes = { small: '0.625rem', medium: '0.75rem', large: '0.875rem' }; - const sizes = $isMobile ? mobileSizes : desktopSizes; +function getFontSize({ $size = 'xxsmall' }: { $size?: LegendProps['size'] }): string { + const sizes = { + xxsmall: '0.75rem', + xsmall: '0.875rem', + small: '1rem', + medium: '1.25rem', + large: '1.5rem', + }; return sizes[$size] || sizes.medium; } export const StyledLegend = styled.legend<{ $size: LegendProps['size'], $bold: LegendProps['bold'], - $isMobile: boolean, }>` color: ${({ theme }) => theme.component['legend-text-color']}; font-size: ${getFontSize}; @@ -19,13 +22,10 @@ export const StyledLegend = styled.legend<{ margin: 0 0 var(--spacing-1x); `; -export const StyledFieldset = styled.fieldset<{ - $orientation: FieldsetProps['orientation'], -}>` +export const StyledFieldset = styled.fieldset>` border: 0; border: none; display: flex; - flex-direction: ${({ $orientation }) => ($orientation === 'horizontal' ? 'row' : 'column')}; gap: var(--spacing-1x); margin: 0; min-inline-size: 0; diff --git a/packages/react/src/components/fieldset/types.ts b/packages/react/src/components/fieldset/types.ts index 983d1a1620..af0d798391 100644 --- a/packages/react/src/components/fieldset/types.ts +++ b/packages/react/src/components/fieldset/types.ts @@ -1,6 +1,6 @@ import { FieldsetHTMLAttributes, HTMLAttributes, ReactNode } from 'react'; -export type LegendSize = 'small' | 'medium' | 'large'; +export type LegendSize = 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large'; export interface LegendProps extends HTMLAttributes { className?: string; @@ -8,14 +8,11 @@ export interface LegendProps extends HTMLAttributes { bold?: boolean; } -export type FieldsetOrientation = 'horizontal' | 'vertical'; - type BaseFieldsetProps = Pick, - 'disabled' | 'id' | 'aria-disabled' | 'aria-label' | 'role' + 'disabled' | 'id' | 'aria-disabled' | 'aria-label' >; export interface FieldsetProps extends BaseFieldsetProps { - legend?: Omit & { text: string }; - orientation?: FieldsetOrientation; + legend: string | (Omit & { text: string }); children: ReactNode; } diff --git a/packages/storybook/stories/fieldset.stories.tsx b/packages/storybook/stories/fieldset.stories.tsx index 32ed8f4b69..b8561dad3c 100644 --- a/packages/storybook/stories/fieldset.stories.tsx +++ b/packages/storybook/stories/fieldset.stories.tsx @@ -13,11 +13,12 @@ export default fieldsetMeta; type Story = StoryObj; const withCheckboxes = ( - <> +
+ {/* replace inline style with grid */} - +
); const withRadioButtons = ( @@ -46,43 +47,29 @@ const withRadioCards = ( export const Default: Story = { args: { - children: withCheckboxes, - }, -}; - -export const Legend: Story = { - args: { - legend: { text: 'This is a legend!', bold: true, size: 'large' }, - children: withCheckboxes, + legend: 'This is a legend!', + children: withTextInputs, }, }; export const Disabled: Story = { args: { disabled: true, - legend: { text: 'This is disabled!', size: 'large' }, + legend: { text: 'This is disabled!', size: 'xxsmall' }, children: withCheckboxes, }, }; -export const Horizontal: Story = { - args: { - orientation: 'horizontal', - legend: { text: 'This is horizontal with text inputs!', size: 'large' }, - children: withTextInputs, - }, -}; - export const WithRadioButtons: Story = { args: { - legend: { text: 'With Radio Buttons!', size: 'large' }, + legend: { text: 'With Radio Buttons!', size: 'xxsmall' }, children: withRadioButtons, }, }; export const WithRadioCards: Story = { args: { - legend: { text: 'With Radio Buttons!', size: 'large' }, + legend: { text: 'With Radio Buttons!', size: 'xxsmall' }, children: withRadioCards, }, };