feat(input) - update radio and checkbox components for shine
Fri Dec 12, 2025 updates from @dancormier
I made some significant changes to this PR and the overall structure of checkbox/radio and related elements/components. Here are the notable changes in this PR:
- Replaced
.s-check-groupwith.s-check, which now contains all styling applied to child checkbox and radio elements - Removed
.s-checkboxand.s-radioclasses. The correct styling will apply as long as the parent includes.s-check - Added
CheckandCheckGroupSvelte components - Renames "Checkbox & Radio" docs page to "Check"
Links
Stacks Classic
Stacks Svelte
Screenshots
Checkbox
Radio
Checkmark
Original PR description
PR to update radio and checkbox components to SHINE designs. Added Checkmark component too.
Stacks Svelte components created for all of the above
Menu component updated to use checkmark styling instead of custom styling
Story: https://stackoverflow.atlassian.net/browse/SPARK-77 Figma: https://www.figma.com/design/do4Ug0Yws8xCfRjHe9cJfZ/Project-SHINE---Product-UI?node-id=2344-22923&m=dev
NOTE: I haven't updated the migration guide because there are no breaking changes and I don't think its needed for new components. Let me know if this is correct
@CGuindon , I spoke to Dan and decided to remove the Focus column in the docs, with the way the browser works there's no easy way to get several elements to focus at once
🦋 Changeset detected
Latest commit: 9113a05f5a0524294eaa13855c1d3c4e720e0675
The changes in this PR will be included in the next version bump.
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
Deploy Preview for stacks-svelte ready!
| Name | Link |
|---|---|
| Latest commit | 9113a05f5a0524294eaa13855c1d3c4e720e0675 |
| Latest deploy log | https://app.netlify.com/projects/stacks-svelte/deploys/6949950eb70972000857ea2a |
| Deploy Preview | https://deploy-preview-2060--stacks-svelte.netlify.app |
| Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify project configuration.
Deploy Preview for stacks ready!
| Name | Link |
|---|---|
| Latest commit | 9113a05f5a0524294eaa13855c1d3c4e720e0675 |
| Latest deploy log | https://app.netlify.com/projects/stacks/deploys/6949950edda00f00081e8ac7 |
| Deploy Preview | https://deploy-preview-2060--stacks.netlify.app |
| Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify project configuration.
Deploy for Svelte preview failed....?
@dancormier There are some issue in the code previews. Probably something related to some markup error I think.
✅ This should be resolved
@mukunku @giamir @CGuindon ~~This PR is ready for rereview~~ I need to do the CHANGELOG updates but feel free to review the rest if you feel so inclined 🙂.
Since the last reviews, I've made the following changes:
Stacks Classic
- Replaced
.s-checkwith.s-checkboxand.s-radio - Split Stacks Classic docs pages up into independent
CheckboxandRadiopages - Split
.s-check-groupinto.s-form-group
Stacks Svelte
- Split the
Checkcomponent up intoCheckboxandRadio - Split the
CheckGroupcomponent up intoFormGroup
[!NOTE] I reverted many of the test images because it created lots of noise. The visual regression tests pass locally and I'll update the images once reviews are completed.
Love this second iteration @dancormier. I really like to see us moving closer to what other systems are doing with a clear distinction between
radioandcheckboxat the API level for consumers. I think this is a huge devx improvement! ❤️I think the PR is almost ready to be merged. I have 2 major suggestions:
* **Remove the CheckboxGroup and RadioGroup separate stories files** since they don't make sense in isolation (instead just add one or 2 extra stories to the Checkbox and Radio stories the Group component could be added as a subcomponent in the story file) . In fact what about keeping things in the same folder as well (Radio contains Radio and RadioGroup - Checkbox contains Checkbox and CheckboxGroup - [Internal]Check contains Check and CheckGroup). I think this will simplify our structure a bit and the amount of code we add to the repo.
✅ I took inspiration from a few other component libraries (bits-ui, MUI, shadcn/ui) and included story files for Checkbox and RadioGroup. Checkbox includes a story demonstrating CheckboxGroup and RadioGroup includes a story for Radio. I also consolidated files into directories /Checkbox and /RadioGroup and updated tests files to include related components.
* **Currently the Radio and Checkbox components don't have a way for consumers to listen to user changes**. We need to be probably do a couple of things: * Make the `checked` prop `$bindable` to the underling input element so that consumers can listen to user changing it and react accordingly in their app `<Checkbox bind:checked />` (you can check what they are doing in [this system](https://bits-ui.com/docs/components/checkbox#api-reference) as a reference) * We should probably also add an `onchange` prop as an alternative way for consumer to react to the changes the user make (this would be the one way binding popularized by React) `<Checkbox onchange={() => 'update state'} />` * Add one or two stories (and one or two tests) showcasing how a consumer will listen to the user changes (either with two way binding `$bindable` or one way binding `onchange`)
✅ I've added $bindable and an onchange prop, as well as stories to demonstrate.
* Nice to have (for a follow up ticket/PR): RadioGroup and CheckboxGroup could be smarter for our consumers and do quite a bit of the heavy lifting for them. We could add to them a `value` and `onValueChange` prop which will make life for consumers so much easier. As I said though this is something we can iterate on after. Maybe we can create a ticket though for it.<RadioGroup value={state} onValueChange={(newState) => state = newState}> <Radio name="group" id="banana" label="Banana" /> <Radio name="group" id="apple" label="Apple" /> <Radio name="group" id="pear" label="Pear" /> </RadioGroup>instead of
<RadioGroup> <Radio name="group" id="banana" label="Banana" checked={state === "banana"} onchange={() => state = "banana"} /> <Radio name="group" id="apple" label="Apple" checked={state === "apple"} onchange={() => state = "apple"} /> <Radio name="group" id="pear" label="Pear" checked={state === "pear"} onchange={() => state = "pear"} /> </RadioGroup>The former version is much nicer for consumers (but they can still get the job done with latter one for now).
✅ I took this just a little further by adding an options prop to RadioGroup and CheckboxGroup so consumers can just pass an array of options. I've also added onValueChange to the underlying FormGroup so that consumers can execute functions when the value changes. If this isn't solid, let me know and I'll remove it for now and leave it for a round 2.
Happy to chat sync about my suggestions if something is unclear. Thanks again for getting us closer to industry standards with this PR. ❤️
@giamir Let me know how this PR looks after this last round of changes (it can wait until the new year… please don't rush to review!). It's a pretty beefy PR, so let me know if you think it needs to be split up at all and I'm happy to do so.
