feat(cdk-experimental/ui-patterns): listbox ui pattern#30495
feat(cdk-experimental/ui-patterns): listbox ui pattern#30495wagnermaciel merged 11 commits intoangular:mainfrom
Conversation
afdc290 to
3e8455d
Compare
jelbourn
left a comment
There was a problem hiding this comment.
First batch of comments, I'm still going
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/keyboard-event-manager.ts
Outdated
Show resolved
Hide resolved
| * An event manager that is specialized for handling mouse events. By default this manager stops | ||
| * propagation and prevents default on all events it handles. |
There was a problem hiding this comment.
I'm not sure that pointer events should always preventDefault and stopPropogation the way that keyboard events do. What's your thinking here?
There was a problem hiding this comment.
There was no thinking on this, I wasn't really sure what the default behaviors should be. This is just what I put in the prototype.
Thinking about it more right now, I would suggest:
keyboard:
- preventDefualt (yes)
- stopPropagation (yes? - motivation for this is things like stacks of dialog, menu, etc where escape should probably close the top one, not all of them)
mouse:
- preventDefault (no - e.g. this is probably not desired for mousedown where preventDefault would cancel focusing of the element)
- stopPropagation (maybe? not really sure about this one)
Anyways that's just my thought for the default defaults. People could always create a manager with different defaults new KeydownEventManager({preventDefault: false}) or register a handler with a different setting than the manager's default manager.on('x', () => {...}, {preventDefault: false})
src/cdk-experimental/ui-patterns/behaviors/event-manager/mouse-event-manager.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/keyboard-event-manager.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/keyboard-event-manager.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/mouse-event-manager.ts
Outdated
Show resolved
Hide resolved
| 'cdk-experimental/scrolling', | ||
| 'cdk-experimental/selection', | ||
| 'cdk-experimental/table-scroll-container', | ||
| 'cdk-experimental/ui-patterns', |
There was a problem hiding this comment.
Why don't we call this patterns? The ui- seems a bit redundant.
There was a problem hiding this comment.
@jelbourn Do you recall the reason for keeping the ui- prefix?
There was a problem hiding this comment.
I like the ui-, patterns by itself makes me think of like GoF design patterns or something
There was a problem hiding this comment.
Yeah, the thinking was that just "patterns" by itself was too generic
There was a problem hiding this comment.
Isn't everything we do related to building UI though? It seems a bit redundant to have it in the name. Then again, if we don't intend to make this public it might not matter 🤷♂️
| label = input<string>(); | ||
|
|
||
| /** The text used by the typeahead search. */ | ||
| searchTerm = computed(() => this.label() ?? this.element().textContent); |
There was a problem hiding this comment.
Should we make the label required so we don't have to hit the DOM every time the computed runs?
There was a problem hiding this comment.
IMO the devex is worth the performance cost in this case. If I understand correctly, this computed will only rerun if the label is set/unset or if the element changes (which I would assume is rare)
There was a problem hiding this comment.
I think that initially it runs so the runtime can figure out the dependencies and afterwards it only runs on changes. That being said, it might be a bit misleading because it's not going to update if the textContent changes. I expect it might come up, given that we had to account for it in mat-option: https://github.com/angular/components/blob/main/src/material/core/option/option.ts#L267
My thinking was that it's easier to introduce it later than having consumers depend on it and us having to change it later.
There was a problem hiding this comment.
That's a good point, I hadn't considered the text content changing. I still lean against making the label required because I think it's too much boilerplate. Would it be ok to leave this for a follow-up PR so that we can discuss when we review the public API design doc?
There was a problem hiding this comment.
Another option can be to only derive the label from the input and if there isn't one, we just don't do typeahead.
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/event-manager/event-manager.ts
Outdated
Show resolved
Hide resolved
devversion
left a comment
There was a problem hiding this comment.
LGTM for dev-infra; leaving naming to others
9d6a824 to
89cb225
Compare
src/cdk-experimental/ui-patterns/behaviors/list-focus/list-focus.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-focus/list-focus.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-navigation/list-navigation.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-navigation/list-navigation.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-selection/list-selection.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-selection/list-selection.ts
Outdated
Show resolved
Hide resolved
| multiselectable: Signal<boolean>; | ||
|
|
||
| /** The ids of the current selected items. */ | ||
| selectedIds: WritableSignal<string[]>; |
There was a problem hiding this comment.
Not necessarily for this PR, but one thing we should discuss in a bit more detail is how we're managing selected IDs, since I worry that the array isn't the best data structure vs. a Set, but we don't have a pattern established yet for a Set that plays well with signals
src/cdk-experimental/ui-patterns/behaviors/list-typeahead/list-typeahead.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-typeahead/list-typeahead.ts
Outdated
Show resolved
Hide resolved
src/components-examples/cdk-experimental/listbox/cdk-listbox/cdk-listbox-example.css
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-focus/list-focus.ts
Outdated
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-navigation/list-navigation.ts
Show resolved
Hide resolved
src/cdk-experimental/ui-patterns/behaviors/list-navigation/list-navigation.ts
Show resolved
Hide resolved
jelbourn
left a comment
There was a problem hiding this comment.
LGTM aside from a last few minor comments
| private readonly _generatedId = inject(_IdGenerator).getId('cdk-option-'); | ||
|
|
||
| /** A unique identifier for the option. */ | ||
| protected id = computed(() => this._generatedId); |
There was a problem hiding this comment.
This can be a TODO / cleanup for a next PR, but these generally shouldn't be computed for things that won't change.
I think the reason that you're doing this is because the e.g. OptionInputs expects a signal. However, you don't really want those to be a Signal<T>, but instead a () => T (which would also make the types work for Wiz) . You could optionally introduce a convenience type for this that's something like
export type Reactive<T> = () => T;We probably want to do this before build too many more ___Input types
src/cdk-experimental/ui-patterns/behaviors/list-navigation/list-navigation.ts
Show resolved
Hide resolved
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
No description provided.