ui icon indicating copy to clipboard operation
ui copied to clipboard

feat(CommandPalette/InputMenu/Select/SelectMenu): unite object matching options

Open J-Michalek opened this issue 4 months ago โ€ข 13 comments

๐Ÿ”— Linked issue

โ“ Type of change

  • [ ] ๐Ÿ“– Documentation (updates to the documentation or readme)
  • [ ] ๐Ÿž Bug fix (a non-breaking change that fixes an issue)
  • [ ] ๐Ÿ‘Œ Enhancement (improving an existing functionality)
  • [x] โœจ New feature (a non-breaking change that adds functionality)
  • [ ] ๐Ÿงน Chore (updates to the build process or auxiliary tools and libraries)
  • [ ] โš ๏ธ Breaking change (fix or feature that would cause existing functionality to change)

๐Ÿ“š Description

I found it very useful to be able to compare objects by a certain key or by custom logic as comparison by reference is not always easily achievable.

๐Ÿ“ Checklist

  • [ ] I have linked an issue or discussion.
  • [ ] I have updated the documentation accordingly.

J-Michalek avatar Oct 06 '25 10:10 J-Michalek

npm i https://pkg.pr.new/@nuxt/ui@5158

commit: c97ece3

pkg-pr-new[bot] avatar Oct 06 '25 10:10 pkg-pr-new[bot]

@J-Michalek This prop should also be implemented in Select, SelectMenu and InputMenu no? ๐Ÿค”

benjamincanac avatar Oct 06 '25 13:10 benjamincanac

@benjamincanac Hmm there may be more to this than I initially though. The Select, SelectMenu and InputMenu components already have valueKey prop which helps with the matching of objects by certain key, we can add the by prop to them as another option for object matching.

We could also add the valueKey to the CommandPalette for the sake of consistency, what do you think?

J-Michalek avatar Oct 06 '25 16:10 J-Michalek

Indeed, adding a value-key would be better for consistency!

benjamincanac avatar Oct 06 '25 16:10 benjamincanac

@benjamincanac I've added the by prop to Select, SelectMenu and InputMenu. I also added the valueKey prop to CommandPalette, but I got stuck on a TS issue where it seems that the modelValue/defaultValue somehow conflicts with groups[number]['items'] type, but I could not figure out what is going on. When I tried to manually input the types into CommandPaletteProps the type looked correct, perhaps I am missing something regarding the generic types in a SFC?

J-Michalek avatar Oct 07 '25 17:10 J-Michalek

Will happily take a look tomorrow, but in general I'm not a super fun of by naming. My first reaction before reading the description and comments on this PR was like "by what? is this an alias for as?". What about a more descriptive prop like compareBy?

sandros94 avatar Oct 15 '25 16:10 sandros94

The by props are overridden here to handle our types but it's inherited from Reka UI so I think keeping the same naming is the right move: https://github.com/unovue/reka-ui/blob/v2/packages/core/src/Listbox/ListboxRoot.vue#L22

benjamincanac avatar Oct 15 '25 16:10 benjamincanac

Pushed a commit mainly focused on ordering generics with their sequential use, but I'm noticing a strange never for items which breaks various things starting from modelValue

sandros94 avatar Oct 17 '25 15:10 sandros94

@sandros94 @J-Michalek What's left to do on this?

benjamincanac avatar Oct 21 '25 12:10 benjamincanac

@sandros94 @J-Michalek What's left to do on this?

On my end a type improvement for the model value (which gets typed as never in some cases)

sandros94 avatar Oct 21 '25 12:10 sandros94

Maybe we should split the work of CommandPalette (value-key + generics) and by prop in two different PRs? ๐Ÿค”

benjamincanac avatar Oct 21 '25 12:10 benjamincanac

I've merged all the conflicts but @sandros94 I think the generics are wrong, it should be generic="T extends CommandPaletteItem[]" right? We should also be using DynamicSlots I believe ๐Ÿค”

benjamincanac avatar Oct 23 '25 10:10 benjamincanac

I've merged all the conflicts but @sandros94 I think the generics are wrong, it should be generic="T extends CommandPaletteItem[]" right? We should also be using DynamicSlots I believe ๐Ÿค”

Yes, but actually no ๐Ÿฅฒ. But yes, generics are wrong

T should actually be a union of all the groups, each with its own CommandPaletteItem[]. Other components only have nested arrays, which in typescript is far easier to handle, but in this case we have the nested array as part of a key inside an object that is part of an array. The issue I'm having (other than lack of time and work) is that I still need to objectively understand: which came first, the chicken or the egg? (aka CommandPaletteItem or CommandPaletteGroup)

sandros94 avatar Oct 23 '25 11:10 sandros94