-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ✨ sd-checkbox & sd-checkbox-group (#507)
Co-authored-by: Hargesheimer, Daniel <[email protected]>
- Loading branch information
1 parent
d5d951f
commit ea9bda2
Showing
9 changed files
with
763 additions
and
184 deletions.
There are no files selected for viewing
26 changes: 0 additions & 26 deletions
26
packages/components/src/_components/checkbox/checkbox.stories.ts
This file was deleted.
Oops, something went wrong.
118 changes: 0 additions & 118 deletions
118
packages/components/src/_components/checkbox/checkbox.styles.ts
This file was deleted.
Oops, something went wrong.
141 changes: 141 additions & 0 deletions
141
packages/components/src/components/checkbox-group/checkbox-group.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import '../../solid-components'; | ||
import { html } from 'lit-html'; | ||
import { storybookDefaults, storybookHelpers, storybookTemplate } from '../../../scripts/storybook/helper'; | ||
import { userEvent } from '@storybook/testing-library'; | ||
import { waitUntil } from '@open-wc/testing-helpers'; | ||
|
||
const { argTypes, parameters } = storybookDefaults('sd-checkbox-group'); | ||
const { generateTemplate } = storybookTemplate('sd-checkbox-group'); | ||
const { overrideArgs } = storybookHelpers('sd-checkbox-group'); | ||
|
||
export default { | ||
title: 'Components/sd-checkbox-group', | ||
component: 'sd-checkbox-group', | ||
args: overrideArgs([ | ||
{ type: 'slot', name: 'label', value: `<label slot="label">Group Label</label>` }, | ||
{ | ||
type: 'slot', | ||
name: 'default', | ||
value: `<sd-checkbox name="checkbox" value="1">Checkbox 1</sd-checkbox><sd-checkbox name="checkbox" value="2">Checkbox 2</sd-checkbox><sd-checkbox name="checkbox" value="3">Checkbox 3</sd-checkbox>` | ||
} | ||
]), | ||
argTypes, | ||
parameters: { | ||
...parameters, | ||
design: { | ||
type: 'figma', | ||
url: 'https://www.figma.com/file/Q7E9GTBET7Gs2HyH1kbpu5/Checkbox-%2F-Checkbox-Group?type=design&node-id=0-1&mode=design&t=DV2yJRUqqYBrskyb-0' | ||
} | ||
} | ||
}; | ||
|
||
/** | ||
* Default: This shows sd-checkbox-group in its default state. | ||
*/ | ||
|
||
export const Default = { | ||
render: (args: any) => { | ||
return generateTemplate({ args }); | ||
} | ||
}; | ||
|
||
/** | ||
* The sd-checkbox in all possible combinations of `orientation` and `size`. | ||
*/ | ||
|
||
export const Orientation = { | ||
parameters: { controls: { exclude: ['orientation', 'size', 'default'] } }, | ||
render: (args: any) => { | ||
return generateTemplate({ | ||
axis: { | ||
x: { type: 'attribute', name: 'orientation' }, | ||
y: { type: 'attribute', name: 'size' } | ||
}, | ||
args | ||
}); | ||
} | ||
}; | ||
|
||
/** | ||
* Use the disabled attribute to disable an input checkbox. Clicks will be suppressed until the disabled state is removed | ||
*/ | ||
|
||
export const Disabled = { | ||
name: 'Disabled x Size', | ||
parameters: { controls: { exclude: ['size', 'default'] } }, | ||
render: (args: any) => { | ||
return generateTemplate({ | ||
axis: { | ||
x: [ | ||
{ | ||
type: 'slot', | ||
name: 'default', | ||
title: 'disabled', | ||
values: [ | ||
{ | ||
value: | ||
'<sd-checkbox value="1" disabled>Option 1</sd-checkbox><sd-checkbox value="2">Option 2</sd-checkbox><sd-checkbox value="3">Option 3</sd-checkbox>', | ||
title: 'true' | ||
}, | ||
{ | ||
value: | ||
'<sd-checkbox value="1">Option 1</sd-checkbox><sd-checkbox value="2">Option 2</sd-checkbox><sd-checkbox value="3">Option 3</sd-checkbox>', | ||
title: 'false' | ||
} | ||
] | ||
} | ||
], | ||
y: { type: 'attribute', name: 'size' } | ||
}, | ||
args | ||
}); | ||
} | ||
}; | ||
|
||
/** | ||
* Use the `form-control`, `form-control-label` and `form-control-input` part selectors to customize the checkbox-group. | ||
*/ | ||
export const Parts = { | ||
parameters: { | ||
controls: { exclude: ['form-control', 'form-control-label', 'form-control-input'] } | ||
}, | ||
render: (args: any) => { | ||
return generateTemplate({ | ||
axis: { | ||
y: { | ||
type: 'template', | ||
name: 'sd-checkbox-group::part(...){outline: solid 2px red}', | ||
values: ['form-control', 'form-control-label', 'form-control-input'].map(part => { | ||
return { | ||
title: part, | ||
value: `<style>#part-${part} sd-checkbox-group::part(${part}){outline: solid 2px red}</style><div id="part-${part}">%TEMPLATE%</div>` | ||
}; | ||
}) | ||
} | ||
}, | ||
constants: [{ type: 'template', name: 'width', value: '<div style="width: 300px">%TEMPLATE%</div>' }], | ||
args | ||
}); | ||
} | ||
}; | ||
|
||
/** | ||
* sd-checkbox-group is fully accessibile via keyboard. | ||
*/ | ||
export const Mouseless = { | ||
render: (args: any) => { | ||
return html`<div class="mouseless">${generateTemplate({ args })}</div>`; | ||
}, | ||
|
||
play: async ({ canvasElement }: { canvasElement: HTMLUnknownElement }) => { | ||
const el = canvasElement.querySelector('.mouseless sd-checkbox-group'); | ||
await waitUntil(() => el?.shadowRoot?.querySelector('label')); | ||
|
||
if (el?.shadowRoot) { | ||
const label = el.shadowRoot.querySelector('label'); | ||
if (label) { | ||
await userEvent.type(label, '{space}', { pointerEventsCheck: 0 }); | ||
} | ||
} | ||
} | ||
}; |
52 changes: 52 additions & 0 deletions
52
packages/components/src/components/checkbox-group/checkbox-group.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { expect, fixture, html, waitUntil } from '@open-wc/testing'; | ||
import sinon from 'sinon'; | ||
|
||
describe('when submitting a form', () => { | ||
it('should submit the correct value when a value is provided', async () => { | ||
const form = await fixture<HTMLFormElement>(html` | ||
<form> | ||
<sd-checkbox-group> | ||
<sd-checkbox id="checkbox-1" name="a" value="1"></sd-checkbox> | ||
<sd-checkbox id="checkbox-2" name="a" value="2"></sd-checkbox> | ||
<sd-checkbox id="checkbox-3" name="a" value="3"></sd-checkbox> | ||
</sd-checkbox-group> | ||
<sd-button type="submit">Submit</sd-button> | ||
</form> | ||
`); | ||
const button = form.querySelector('sd-button')!; | ||
const checkbox = form.querySelectorAll('sd-checkbox')[1]!; | ||
const checkbox2 = form.querySelectorAll('sd-checkbox')[2]!; | ||
const submitHandler = sinon.spy((event: SubmitEvent) => { | ||
formData = new FormData(form); | ||
|
||
event.preventDefault(); | ||
}); | ||
let formData: FormData; | ||
|
||
form.addEventListener('submit', submitHandler); | ||
checkbox2.click(); | ||
checkbox.click(); | ||
button.click(); | ||
await waitUntil(() => submitHandler.calledOnce); | ||
expect(formData!.getAll('a')).to.eql(['2', '3']); | ||
}); | ||
|
||
it('should be present in form data when using the form attribute and located outside of a <form>', async () => { | ||
const el = await fixture<HTMLFormElement>(html` | ||
<div> | ||
<form id="f"> | ||
<sd-button type="submit">Submit</sd-button> | ||
</form> | ||
<sd-checkbox-group> | ||
<sd-checkbox id="checkbox-1" name="a" value="1" checked form="f"></sd-checkbox> | ||
<sd-checkbox id="checkbox-2" name="a" value="2" form="f"></sd-checkbox> | ||
<sd-checkbox id="checkbox-3" name="a" value="3" checked form="f"></sd-checkbox> | ||
</sd-checkbox-group> | ||
</div> | ||
`); | ||
const form = el.querySelector('form')!; | ||
const formData = new FormData(form); | ||
|
||
expect(formData.getAll('a')).to.eql(['1', '3']); | ||
}); | ||
}); |
Oops, something went wrong.