Skip to content

Commit

Permalink
fix(Switch): use field for consistent component api (#2773)
Browse files Browse the repository at this point in the history
- Convert Switch to use Field component
- Design adjustments will be done in #2664
  • Loading branch information
eirikbacker authored Nov 14, 2024
1 parent 70fea86 commit 581863a
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 500 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-moles-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@digdir/designsystemet-react": major
---

Switch: Use `label` prop instead of `children` to render label
10 changes: 4 additions & 6 deletions apps/theme/components/Previews/Components/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,10 @@ export const Components = () => {
<Fieldset.Description>
Her kan du justere på innstillingene dine
</Fieldset.Description>
<Switch defaultChecked>TV-visning</Switch>
<Switch>Desktopvisning</Switch>
<Switch defaultChecked readOnly>
Tabletvisning
</Switch>
<Switch disabled>Mobilvisning</Switch>
<Switch label='TV-visning' defaultChecked />
<Switch label='Desktopvisning' />
<Switch label='Tabletvisning' defaultChecked readOnly />
<Switch label='Mobilvisning' disabled />
</Fieldset>
</div>
<div className={cl(classes.card, classes.toggleGroup)}>
Expand Down
11 changes: 9 additions & 2 deletions packages/css/field.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
&:has(input:is([type='radio'], [type='checkbox'])) {
border-radius: var(--ds-border-radius-md);
display: grid;
grid-template-areas: 'input content';
grid-template-columns: auto 1fr;
row-gap: 0;
width: fit-content; /* Rather do display: grid + width: fit-content than display: inline-grid to encourage stacked radios */

& > * {
grid-column: 2; /* Only allow input in column 1 */
grid-column: content; /* Only allow input in column 1 */
}

& label {
Expand All @@ -40,7 +41,7 @@
}

& input {
grid-column: 1; /* Always place input in column 1 */
grid-column: input; /* Always place input in column 1 */
grid-row: 1; /* Always place input in row 1 */
}

Expand All @@ -55,6 +56,12 @@
&:has(input:only-child) {
gap: 0; /* No gap only <input> with aria-label/aria-labelledby */
}

&[data-position='end'] {
grid-template-areas: 'content input';
grid-template-columns: 1fr auto;
width: auto;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/css/fieldset.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
padding: 0;

/* Add lock icon to legend when only containing readonly inputs */
&:has([readonly]):not(:has(:read-write)) > legend {
&:has(input[readonly]):not(:has(input:not([readonly]))) > legend {
--dsc-label--readonly: ; /* Using technique https://css-tricks.com/the-css-custom-property-toggle-trick/ */
}

Expand Down
1 change: 0 additions & 1 deletion packages/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
@import url('./popover.css') layer(ds.components);
@import url('./skiplink.css') layer(ds.components);
@import url('./accordion.css') layer(ds.components);
@import url('./switch.css') layer(ds.components);
@import url('./search.css') layer(ds.components);
@import url('./textfield.css') layer(ds.components);
@import url('./helptext.css') layer(ds.components);
Expand Down
246 changes: 0 additions & 246 deletions packages/css/switch.css

This file was deleted.

26 changes: 13 additions & 13 deletions packages/react/src/components/form/Combobox/Combobox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,13 @@ export const WithDescription: StoryFn<typeof Combobox> = (args) => {
return (
<>
<Switch
label='Multiple'
checked={multiple}
onChange={(e) => {
setMultiple(e.target.checked);
setValue([]);
}}
>
Multiple
</Switch>
/>
<Combobox
key={multiple ? 'multiple' : 'single'}
{...args}
Expand Down Expand Up @@ -233,14 +232,13 @@ export const Controlled: StoryFn<typeof Combobox> = (args) => {
<Divider style={{ marginTop: 'var(--ds-spacing-4)' }} />

<Switch
label='Multiple'
checked={multiple}
onChange={(e) => {
setMultiple(e.target.checked);
setValue([]);
}}
>
Multiple
</Switch>
/>

<Paragraph style={{ margin: 'var(--ds-spacing-2) 0' }}>
Value er: {value.join(', ')}
Expand Down Expand Up @@ -602,13 +600,15 @@ export const RemoveAllOptions: StoryFn<typeof Combobox> = (args) => {
);
})}
</Combobox>
<Switch onChange={(event) => changeAllValues(event.target.checked)}>
Remove Values (Selected values remain unchanged as the combobox does not
update when options are empty.)
</Switch>
<Switch onChange={(event) => changeSomeValues(event.target.checked)}>
Remove test2 (this works)
</Switch>
<Switch
label='Remove Values (Selected values remain unchanged as the combobox does not
update when options are empty.)'
onChange={(event) => changeAllValues(event.target.checked)}
/>
<Switch
label='Remove test2 (this works)'
onChange={(event) => changeSomeValues(event.target.checked)}
/>
</>
);
};
Expand Down
9 changes: 8 additions & 1 deletion packages/react/src/components/form/Field/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { forwardRef, useEffect, useRef } from 'react';
import type { DefaultProps } from '../../../types';
import { fieldObserver } from './fieldObserver';

export type FieldProps = HTMLAttributes<HTMLDivElement> & DefaultProps;
export type FieldProps = {
/** Position of toggle inputs (radio, checkbox, switch) in field
* @default start
*/
position?: 'start' | 'end';
} & HTMLAttributes<HTMLDivElement> &
DefaultProps;

export const Field = forwardRef<HTMLDivElement, FieldProps>(function Field(
{ className, ...rest },
ref,
Expand Down
Loading

0 comments on commit 581863a

Please sign in to comment.