-
Notifications
You must be signed in to change notification settings - Fork 77
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(combobox, stepper, table): respect user hidden attribute #10983
fix(combobox, stepper, table): respect user hidden attribute #10983
Conversation
@josercarcamo This is missing the utilities mentioned in item 2 from the previous review. Could you update your PR to include them? Since this supersedes the previous PR, can you close it? |
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.
Good progress, @josercarcamo! 😎 This needs a few more tweaks, and it'll be good to go!
@@ -97,10 +97,8 @@ | |||
} | |||
|
|||
@mixin base-component() { | |||
:host([hidden]) { |
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.
Since the internal hide-item
attribute is only applicable to certain components, can you create a separate mixin and include in applicable children?
* Specifies whether the user set the hidden attribute in the HTML | ||
* | ||
*/ | ||
@property() hideItem = 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.
Thanks for removing user
from the prop name! To align with hidden
, WDYT about hiddenItem
?
@@ -262,37 +262,48 @@ describe("calcite-stepper", () => { | |||
<calcite-stepper-item heading="Step 3" id="step-3"> | |||
<div>Step 3 content</div> | |||
</calcite-stepper-item> | |||
<calcite-stepper-item heading="Step 4" id="step-4" hide-item> |
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.
@@ -1642,9 +1689,8 @@ describe("keyboard navigation", () => { | |||
await page.keyboard.press("PageUp"); | |||
await page.waitForChanges(); | |||
expect(await getFocusedElementProp(page, "id")).toBe("head-1b"); | |||
await page.keyboard.down("ControlRight"); | |||
page.keyboard.press("ControlRight"); |
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.
This should use await
and changing it to press
will cause it to no longer go into the expected End
+ ControlRight
path here (i.e., ControlRight
is pressed and released before End
is pressed).
This PR has been automatically marked as stale because it has not had recent activity. Please close your PR if it is no longer relevant. Thank you for your contributions. |
@jcfranco please review 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.
Great stuff, @josercarcamo! One more pass and this should be good to go!
BTW, these changes caused some combobox
and input-time-zone
tests to fail, so they'll need to be updated.
@@ -863,6 +863,56 @@ describe("calcite-combobox", () => { | |||
} | |||
}); | |||
|
|||
it("should show correct number of items when child hidden", async () => { | |||
const page = await newE2EPage(); | |||
await page.setContent(` |
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.
Can you use the html
formatting helper, so prettier formats embedded HTML? Applies to other test page markup.
</calcite-stepper>`, | ||
); | ||
it("should select the next enabled stepper-item if first stepper-item is disabled or hidden", async () => { | ||
for (const n of ["disabled", "hidden"]) { |
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.
Let's use it.each
for this instead.
@@ -843,6 +877,9 @@ describe("calcite-stepper", () => { | |||
<calcite-stepper-item heading="Step 2" id="step-2" disabled> | |||
<div>Step 2 content</div> | |||
</calcite-stepper-item> | |||
<calcite-stepper-item heading="Step 2.1" id="step-2.1" hidden> |
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.
For consistency, can you update all steps to be integers?
@@ -274,6 +281,8 @@ export class StepperItem extends LitElement implements InteractiveComponent, Loa | |||
private handleItemClick(event: MouseEvent): void { | |||
if ( | |||
this.disabled || | |||
this.hiddenItem || |
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.
This can use isHidden
, right?
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.
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.
Can you try passing the element instead of the instance? You'll get that error if you pass the latter.
@@ -26,3 +29,7 @@ export function warnIfMissingRequiredProp<C extends LitElement>( | |||
logger.warn(`[${component.el.localName}] "${newProp.toString()}" or "${deprecatedProp.toString()}" is required.`); | |||
} | |||
} | |||
|
|||
export function isHidden<C extends ComboboxChildElement | StepperItem["el"] | TableRow["el"]>(component: C): boolean { | |||
return component?.hidden || component?.hiddenItem; |
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.
Can component
be undefined
here?
const items = await page.findAll("calcite-table-row"); | ||
for (let i = 0; i < items.length; i++) { | ||
const style = await items[i].getComputedStyle(); | ||
expect(style["display"]).toBe(i === 2 || i === 3 ? "none" : "contents"); |
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.
This test might go away, but I think you can use E2EElement.isVisible
for these assertions.
@@ -34,6 +34,41 @@ describe("calcite-table", () => { | |||
</calcite-table>`, | |||
{ display: "flex" }, | |||
); | |||
|
|||
it("renders only non-hidden rows", async () => { |
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 can drop this test since it's testing native browser behavior.
@@ -26,3 +29,7 @@ export function warnIfMissingRequiredProp<C extends LitElement>( | |||
logger.warn(`[${component.el.localName}] "${newProp.toString()}" or "${deprecatedProp.toString()}" is required.`); | |||
} | |||
} | |||
|
|||
export function isHidden<C extends ComboboxChildElement | StepperItem["el"] | TableRow["el"]>(component: C): boolean { |
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.
For consistency, can we rename the input argument to el
?
@jcfranco one more review please. |
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.
👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻
👻✅👻👻👻✅👻✅✅✅👻👻✅✅✅👻✅✅✅✅👻✅👻
👻✅✅👻👻✅👻👻✅👻👻✅👻👻👻👻✅👻👻👻👻✅👻
👻✅👻✅👻✅👻👻✅👻👻✅👻👻👻👻✅✅✅👻👻✅👻
👻✅👻👻✅✅👻👻✅👻👻✅👻👻👻👻✅👻👻👻👻👻👻
👻✅👻👻👻✅👻✅✅✅👻👻✅✅✅👻✅✅✅✅👻✅👻
👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻👻
Once comments are addressed, this will be good to merge! Thanks, @josercarcamo!
@@ -53,6 +53,13 @@ export class ComboboxItemGroup extends LitElement { | |||
*/ | |||
@property() scale: Scale = "m"; | |||
|
|||
/** | |||
* Specifies whether the user set the hidden attribute in the HTML |
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.
This comment doesn't seem to be accurate. Can you give it another look? Applies to most hiddenItem
prop doc.
); | ||
it.each(["disabled", "hidden"])( | ||
"should select the next enabled stepper-item if first stepper-item is %s", | ||
async (accessibility) => { |
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.
IMO, accessibility
seems out of place here. Would stateProp
be a better fit?
@@ -390,7 +391,8 @@ export class Stepper extends LitElement { | |||
|
|||
private handleDefaultSlotChange(event: Event): void { | |||
const items = slotChangeGetAssignedElements(event).filter( | |||
(el): el is StepperItem["el"] => el?.tagName === "CALCITE-STEPPER-ITEM", | |||
(el): el is StepperItem["el"] => | |||
el?.tagName === "CALCITE-STEPPER-ITEM" && !isHidden(el as StepperItem["el"]), |
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.
Can you confirm if you need to typecast here? It looks like el
is properly typed by the filter's return type.
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.
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.
Looking good @josercarcamo 👍
@@ -26,3 +29,7 @@ export function warnIfMissingRequiredProp<C extends LitElement>( | |||
logger.warn(`[${component.el.localName}] "${newProp.toString()}" or "${deprecatedProp.toString()}" is required.`); | |||
} | |||
} | |||
|
|||
export function isHidden<C extends ComboboxChildElement | StepperItem["el"] | TableRow["el"]>(el: C): boolean { |
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.
Maybe we could have an interface for HiddenItem
that each of these components could implement? Then this utility may not be necessary.
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 don't think an interface is appropriate here since they all behave the same. A parent class would be more appropriate. This way we wouldn't need to pass anything to the method. However, we would only have this one method.
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.
Now that we're using lit, we may be able to have a class that these could extend.
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.
We're moving more towards controllers, so we could enforce the interface this way. This would be handled separately from this PR.
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.
We can handle this separately with a followup
* | ||
* @private | ||
*/ | ||
@property({ reflect: true }) hiddenItem = 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.
Should we have e2e defaults
and reflects
tests for each of these new private properties?
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.
Not for internal props, but the controller approach could help us test this behavior.
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.
Not for internal props, but the controller approach could help us test this behavior.
It would be beneficial even for internal props because if this property isn't reflected then the CSS and querySelector logic won't work. I would think it would be beneficial
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.
That should be handled by the controller testing.
…github.com:Esri/calcite-design-system into josercarcamo/8623-respect-user-hidden-attribute-v2
@driskull are you ok with handling your two comments in a separate PR and merge this PR for now? |
* | ||
* @private | ||
* */ | ||
@property({ reflect: true }) hiddenItem = 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.
nitpick: would itemHidden
be preferred here? it aligns better with our other props like feature-disabled
.
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 had proposed that but it was decided to go with hiddenItem
.
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.
@jcfranco what you think? 🤔 It doesn't matter much since its a private property but would align better with other props as itemHidden
or even calciteHidden
to illustrate that calcite is hiding this.
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.
Renaming sounds good for consistency. @josercarcamo I'll defer to you whether you want to tackle that here or separately.
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'll tackle it here. I'll change it to calciteHidden
, if there are no objections.
Should we have a followup issue to use |
@driskull I'll create a separate issue as renaming in other components might need further changes and testing. I just want to close this one knowing that it is solid. Then we can make further changes. |
Sounds good. I like |
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.
👍
Sorry for chiming in late here, but This can be done as a follow-up since it is internal. |
* origin/dev: (34 commits) build: update browserslist db (#11339) build(deps): update dependency lint-staged to v15.4.1 (#11343) chore: release next feat(graph): add component tokens (#11355) chore: release next fix(popover, tooltip): drop relative-positioning to reduce risk of clipping (#11373) chore: release next fix(date-picker): no longer disable min/max value month in select menu (#11350) chore(icon): improve icon load error message (#11367) fix(date-picker): remove outline for header actions (#11369) chore: release next fix(carousel): Ensure correct `autoplay` display and animation (#11338) chore: release next fix(flow): process items on loaded (#11364) chore: release next fix(combobox, stepper, table): respect user hidden attribute (#10983) refactor(action-pad): restore rounded styling (#11358) test(combobox): avoid emitting change event for value property update (#11281) chore: release next refactor(action-pad): remove unnecessary overflow css styling. (#11349) ...
Related Issue: #8623
Summary
Made items with the hide-item attribute added by the user stay hidden.
This PR supersedes #10515
Wiki page
https://github.com/Esri/calcite-design-system/wiki/hiddenItem-Property