Skip to content
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

[WNMGDS-2723] Choice web component #3047

Merged
merged 23 commits into from
Apr 18, 2024
Merged

[WNMGDS-2723] Choice web component #3047

merged 23 commits into from
Apr 18, 2024

Conversation

zarahzachz
Copy link
Collaborator

WNMGDS-2723

Implement Choice as a web component.

checkedChildren and uncheckedChildren are being used as slots instead of proper attributes and that's OK!

return (
<ds-choice {...args}>
<div slot="checked-children">
<div className="ds-c-alert">{args['checked-children']}</div>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for some reason hooking the story up to the args caused the html to be stripped away. if the value is hard-coded it's fine, so this seems like a storybook problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: @zarahzachz wrote a follow-up ticket for adding partial attribute pass-through support.

@zarahzachz zarahzachz added this to the 11.0.0-beta.1 milestone Apr 17, 2024
@zarahzachz zarahzachz added Impacts: Core Impacts the core DS primarily, changes may occur in other themes as well. Type: Added Indicates a new feature. labels Apr 17, 2024
@zarahzachz zarahzachz requested a review from pwolfert April 17, 2024 18:28
Copy link
Contributor

@pwolfert pwolfert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made changes for all my feedback items except the unit tests

const Template = (args) => {
useEffect(() => {
const onChange = (event) => {
action('ds-change')(event);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the Storybook action output is too shallow to show all the properties for event.detail.target, but I made sure that event.detail.target.checked changed when checking and unchecking.

Comment on lines 110 to 111
<code>event.details.target.value</code> - The <code>value</code> of the selected
option
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also reference event.detail.target.checked because that's probably the most relevant piece of information

decorators: [webComponentDecorator],
};

const Template = (args) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checked-children and unchecked-children attributes should be destructured from this so they don't also get spread onto the ds-choice element itself.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it gets removed from the attributes on the element, the alert divs start showing up correctly

describe('Button', () => {
describe('Dropdown', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update the snapshots after this change

Comment on lines 159 to 187
describe('event handlers and emitters', () => {
let props;

beforeEach(() => {
props = {
onBlur: jest.fn(),
onChange: jest.fn(),
};
});

it('calls the onChange handler', () => {
renderChoice(props);
const el = screen.getByRole('checkbox');
userEvent.click(el);

expect(props.onBlur).toHaveBeenCalledTimes(0);
expect(props.onChange).toHaveBeenCalledTimes(1);
});

it('calls the onBlur handler', () => {
renderChoice(props);
const el = screen.getByLabelText('George Washington');
el.focus();
userEvent.tab();

expect(props.onBlur).toHaveBeenCalledTimes(1);
expect(props.onChange).toHaveBeenCalledTimes(0);
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be updated to use addEventListener and the custom events. I think these are only being passed down successfully by a trick of Preact in the unit tests.

Comment on lines +193 to +202
<div slot="checked-children">
<strong data-testid="checked" className="checked-child">
I am checked
</strong>
</div>
<div slot="unchecked-children">
<strong data-testid="unchecked" className="unchecked-child">
I am unchecked
</strong>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're adding both, maybe we should do a check for internal state management in this unit test where we click on the checkbox and see if the other one becomes visible and the first one gets hidden.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I now see that's what you were doing in the next test

return (
<ds-choice {...args}>
<div slot="checked-children">
<div className="ds-c-alert">{args['checked-children']}</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: @zarahzachz wrote a follow-up ticket for adding partial attribute pass-through support.

Copy link
Contributor

@pwolfert pwolfert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied the unit test feedback too. LGTM

const input = screen.getByRole('checkbox');
userEvent.click(input);

expect(mockHandler).toHaveBeenCalledTimes(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to assert here that mockHandler.mock.lastCall[0].details.target.checked was true, but the event object is kind of messed up. I'm wondering if it's a limitation with jsdom and custom events. It seems to work right in Storybook.

@zarahzachz zarahzachz merged commit 1eb1757 into main Apr 18, 2024
1 check passed
@zarahzachz zarahzachz deleted the WNMGDS-2723/choice-wc branch April 18, 2024 14:04
@pwolfert pwolfert modified the milestones: 11.0.0-beta.1, 10.1.0 May 3, 2024
pwolfert added a commit that referenced this pull request May 10, 2024
* init choice web component.

* WIP checked children implementation

* init tests.

* export choice, add inversed prop, slots.

* add choice to astro wc

* add conditional rendering of slots

* add conditional rendering of slots for astro

* get choice examples working

* fix typo in dropdown test.

* implement choice unit tests

* remove unneeded logic from storybook

* Update unit test snapshot

* Apply Storybook feedback

* Add missing attributes in choice and dropdown

* Update storybook doc snapshots

* Update VRT refs

* Make some quasi-realistic use-case scenario for the checkbox in the example

* Update examples VRT refs

* Updated unit tests

* Order of these changed

---------

Co-authored-by: Patrick Wolfert <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Impacts: Core Impacts the core DS primarily, changes may occur in other themes as well. Type: Added Indicates a new feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants