-
Notifications
You must be signed in to change notification settings - Fork 1.9k
fix: controlled tag component for selected prop #19228 #19231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: controlled tag component for selected prop #19228 #19231
Conversation
All contributors have signed the DCO. |
d62f987
to
b024f41
Compare
✅ Deploy Preview for v11-carbon-web-components ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
recheck |
✅ Deploy Preview for v11-carbon-react ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ Deploy Preview for v11-carbon-web-components ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
I have read the DCO document and I hereby sign the DCO. |
✅ Deploy Preview for v11-carbon-react ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing a test to cover this! I made a more isolated repro for what it's worth: https://stackblitz.com/edit/github-g93j9mdu?file=src%2FApp.jsx
useEffect(() => { | ||
if (selected !== selectedTag) { | ||
setSelectedTag(selected); | ||
} | ||
}, [selected]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need an effect?
https://react.dev/learn/you-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we still need useEffect here. selected
and onChange
are optional props to the component, so if parent component not passing selected
prop Tag component should handle is inside own state.
Do you agree? 🤔
if (selected !== selectedTag) {
setSelectedTag(selected);
}
If we add this to render, i think it is good to remove the state and use value directly from prop, but this case props needs to be mandatory.
Otherwise i can check if props passed or not in the condition
if (typeof selected == "boolean" && onChange && selected !== selectedTag) {
setSelectedTag(selected);
}
🤔.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tay1orjones Please have a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sojinantony01 I forgot we have the useControllableState
hook you can use for this.
export const useControllableState = <T>({ |
It'll handle the whole thing for you. We'll need to add a defaultSelected
boolean prop to SelectableTag to pass to the hook. Probably the closest usage example you could follow is in Toggle:
carbon/packages/react/src/components/Toggle/Toggle.tsx
Lines 121 to 125 in a6eb265
const [checked, setChecked] = useControllableState({ | |
value: toggled, | |
onChange: onToggle, | |
defaultValue: defaultToggled, | |
}); |
We'll want to make sure there's clear passing tests for both controlled and uncontrolled modes here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thats really a useful hook. Thanks @tay1orjones.
I have updated the component using the useControllableState
hook. we already have tests for uncontrolled state and i have added couple of tests for the controlled case - All passing.
And have manually tested the component using storybook.
Please have a look in the latest code.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #19231 +/- ##
==========================================
- Coverage 84.78% 84.78% -0.01%
==========================================
Files 371 371
Lines 14411 14410 -1
Branches 4744 4692 -52
==========================================
- Hits 12218 12217 -1
- Misses 2044 2045 +1
+ Partials 149 148 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
986ed4a
to
ced22db
Compare
ced22db
to
d66b4be
Compare
const selectableTag = container.firstChild; | ||
|
||
await userEvent.click(selectableTag); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer the tests to use screen.getByRole
instead of container.firstChild
and assert aria-pressed
in addition to the toHaveClass
assertions (since a user doesn't directly interact with the classnames), but it's not a blocker to merge.
const selectableTag = container.firstChild; | |
await userEvent.click(selectableTag); | |
await userEvent.click(screen.getByRole("button", {name: "Tag content"})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, Updated the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor thing, I think the default should be configurable
const [selectedTag, setSelectedTag] = useControllableState({ | ||
value: selected, | ||
onChange: onChange, | ||
defaultValue: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be configurable through a new defaultSelected
prop, similar to what's done in other usages like Toggle and Tabs?
defaultValue: defaultSelectedIndex, |
It would have a default function param of false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, Thanks @tay1orjones
Added a new defaultSelected prop and tests for same.
4915f6d
to
58a5600
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks again!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!!
ab5a320
…19228 (carbon-design-system#19231) * fix: controlled tag component for selected prop carbon-design-system#19228 * fix: fix tests for tag * fix: controlled tag component for selected prop carbon-design-system#19228 * fix: controlled tag added a default selected prop and tests carbon-design-system#19228 * fix: controlled tag added a default selected prop and tests carbon-design-system#19228 * fix: controlled tag added a default selected prop and tests carbon-design-system#19228 * fix: controlled tag fix tests carbon-design-system#19228 * fix: add profile * fix: add profile
* fix(icons): fix icons invisible in high contrast mode If the system has a dark high-contrast theme, then icons need to be displayed in white (or a light color), and vice-versa. Otherwise, icons become invisible. Importantly, this must happen regardless of the Carbon theme setting. Fixes #17147, #18830, #19015, #19023, #19140. * fix(icons): fix tooltip story Use proper color for icon, not background color. * fix(icons): remove vestigial high-contrast-mode('icon-fill') When you use standard tokens like $icon-primary you don't need it anymore. Note: I didn't convert $support-error and $support-warning usages to a system color. Previously the inline notification icon 🚫 was converted from red to ButtonText. Also $support-error and $support-warning usages in _list-box.scss. Also, inline-notification has a dodgy use of $black-100 that I didn't change. * fix(icons): handle weird values for fill Replace $text-primary with $icon-primary as they are the same. Likewise $tab-text-disabled --> $icon-disabled. Updated _theme.scss to handle the other weird fill settings. * fix(icons): fix comment * fix(icons): fix background colors * fix(icons): fix checkmark * fix(icons): remove unused imports of high-contrast-mode * fix: remove unexpected shadow from web-component button (#19347) * fix: controlled tag component for selected prop #19228 (#19231) * fix: controlled tag component for selected prop #19228 * fix: fix tests for tag * fix: controlled tag component for selected prop #19228 * fix: controlled tag added a default selected prop and tests #19228 * fix: controlled tag added a default selected prop and tests #19228 * fix: controlled tag added a default selected prop and tests #19228 * fix: controlled tag fix tests #19228 * fix: add profile * fix: add profile * fix(date-picker): clear flatpickr instance on reset (#19239) * fix(date-picker): clear flatpickr instance on reset * fix(date-picker): clear flatpickr instance on reset * fix(date-picker): update comments and storybook docs to clarify changes * fix(date-picker): update comments and storybook docs to clarify changes * Update packages/react/src/components/DatePicker/DatePicker.tsx Co-authored-by: kennylam <[email protected]> --------- Co-authored-by: kennylam <[email protected]> * fix: modal footer buttons were not fully visible in zoom to 400 (#19288) * fix: modal footer buttons were not fully visible in zoom to 400 * fix: added test story * fix: remove test story --------- Co-authored-by: Heloise Lui <[email protected]> * fix(icons): another inverted background * chore(icons): fix merge error --------- Co-authored-by: Heloise Lui <[email protected]> Co-authored-by: Sojin antony <[email protected]> Co-authored-by: Warren Blood <[email protected]> Co-authored-by: kennylam <[email protected]> Co-authored-by: Preeti Bansal <[email protected]>
Closes #19228
Controlled selectable tag component
Changelog
New
Testing / Reviewing
https://stackblitz.com/edit/github-g93j9mdu?file=src%2FApp.jsx - component should be controllable with latest version