ui icon indicating copy to clipboard operation
ui copied to clipboard

fix(SelectMenu): use `by` prop to compare objects for selected values

Open cernymatej opened this issue 1 year ago โ€ข 1 comments

๐Ÿ”— Linked issue

fixes https://github.com/nuxt/ui/issues/2028

โ“ Type of change

  • [ ] ๐Ÿ“– Documentation (updates to the documentation or readme)
  • [x] ๐Ÿž Bug fix (a non-breaking change that fixes an issue)
  • [x] ๐Ÿ‘Œ Enhancement (improving an existing functionality)
  • [ ] โœจ 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

This PR fixes a bug introduced in https://github.com/nuxt/ui/pull/1349, where the by prop was not being consiederd when computing the selected values. It also adds the possibility to combine the by prop with the value-attribute prop to compare nested objects like in the following example:

<template>
  <USelectMenu
    v-model="selected"
    :options="options"
    multiple
    value-attribute="object"
    by="id"
  />
</template>

<script lang="ts" setup>
const selected = ref([{
  id: 1,
  title: 'Hello'
}])

const options = [
  {
    key: 'id',
    label: 'ID',
    object: {         // ๐Ÿ‘ˆ this will be the selected value
      id: 1,             // ๐Ÿ‘ˆ the objects will be compared by this attribute
      title: 'Hello'
    }
  },
  {
    key: 'title',
    label: 'Title',
    object: {
      id: 2,             // ๐Ÿ‘ˆ the objects will be compared by this attribute
      title: 'Hi'
    }
  }
]
</script>

๐Ÿ“ Checklist

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

cernymatej avatar Sep 20 '24 15:09 cernymatej

I also added the possibility to compare nested objects using the by prop when the value-attribute prop is set

Consider the following example:

<template>
  <USelectMenu
    v-model="selected"
    :options="options"
    multiple
    value-attribute="object"
    by="id"
  />
</template>

<script lang="ts" setup>
const selected = ref([{
  id: 1,
  title: 'Hello'
}])

const options = [
  {
    key: 'id',
    label: 'ID',
    object: {
      id: 1,
      title: 'Hello'
    }
  },
  {
    key: 'title',
    label: 'Title',
    object: {
      id: 2,
      title: 'Hi'
    }
  },
  {
    key: 'status',
    label: 'Status',
    object: {
      id: 3,
      title: 'Hey'
    }
  }
]
</script>

Previously (even before the introduction of the selected computed) it was not possible to combine these 2 props. This approach made sense to me, but Iโ€™m happy to hear any feedback on this.

cernymatej avatar Sep 20 '24 16:09 cernymatej

Would you mind fixing the same thing on the InputMenu? Both have the same code.

benjamincanac avatar Nov 06 '24 18:11 benjamincanac

@benjamincanac sure! However, I'll have to postpone it to tomorrow if that's ok

cernymatej avatar Nov 06 '24 18:11 cernymatej

I've updated the code to support dot notation for the value-attribute prop in <SelectMenu>. I also wanted to add dot notation support for the by prop, but ran into a limitation with HeadlessUI: the HCombobox and HListbox components don't support it. The by prop is passed as a string to these components, so there's currently no way to support it in NuxtUI unless HeadlessUI adds support.

It should also be noted that the by prop should only be used when the final value is an object. Using it with other types results in strange behavior, which we cannot reasonably fix due to limitations with HCombobox, which is the source of these issues. This has been the case before as well. We should maybe document that more explicitly.

cernymatej avatar Nov 07 '24 00:11 cernymatej

Closing in favor of #2566.

benjamincanac avatar Nov 10 '24 09:11 benjamincanac