diff --git a/packages/components/select/src/option.vue b/packages/components/select/src/option.vue index 98bba945..b5171368 100644 --- a/packages/components/select/src/option.vue +++ b/packages/components/select/src/option.vue @@ -13,7 +13,7 @@ 'puik-option--disabled': disabled, }" > - {{ label }} + {{ label }} , required: true, }, + customLabel: { + type: String, + required: false, + default: undefined, + }, labelKey: { type: String, required: false, @@ -68,6 +73,11 @@ export const selectProps = buildProps({ required: false, default: 1000, }, + fullWidth: { + type: Boolean, + required: false, + default: true, + }, } as const) export type SelectProps = ExtractPropTypes diff --git a/packages/components/select/src/select.vue b/packages/components/select/src/select.vue index 9c966695..797b16c3 100644 --- a/packages/components/select/src/select.vue +++ b/packages/components/select/src/select.vue @@ -44,6 +44,7 @@ v-show="isOpen(open)" static class="puik-select__options" + :class="{ 'puik-select__options--full-width': fullWidth }" as="div" :style="{ 'z-index': zindex }" > @@ -133,7 +134,7 @@ const selectedValue = computed({ return props.modelValue }, set(option: any) { - currentLabel.value = option.label + currentLabel.value = props.customLabel || option.label return emit('update:modelValue', option.value) }, }) diff --git a/packages/components/select/stories/select.stories.ts b/packages/components/select/stories/select.stories.ts index bee381cd..a34b96aa 100644 --- a/packages/components/select/stories/select.stories.ts +++ b/packages/components/select/stories/select.stories.ts @@ -7,6 +7,14 @@ export default { title: 'Components/Select', components: PuikSelect, argTypes: { + customLabel: { + control: 'text', + description: + 'Use custom label when the label is different from the option selected', + table: { + category: 'Common', + }, + }, labelKey: { control: 'text', description: @@ -92,6 +100,15 @@ export default { category: 'Searchable', }, }, + fullWidth: { + control: 'boolean', + description: + 'Keep same width for the dropdown and select input. True by default', + table: { + defaultValue: true, + category: 'Common', + }, + }, }, args: { labelKey: '', @@ -593,3 +610,141 @@ export const NoMatchCustomText: StoryObj = { }, }, } + +export const customLabel = { + render: () => ({ + components: { + PuikSelect, + PuikOption, + }, + setup() { + const myValue = ref('') + return { myValue } + }, + template: ` + + + + `, + }), + parameters: { + docs: { + source: { + code: ` + + + + + + + +
+
+ + +
+
    +
  • + Test 1 +
  • + +
+
+
+
+ `, + language: 'html', + }, + }, + }, +} + +export const maxContentOption = { + render: () => ({ + components: { + PuikSelect, + PuikOption, + }, + setup() { + const myValue = ref('') + return { myValue } + }, + template: ` + + + + `, + }), + parameters: { + docs: { + source: { + code: ` + + + + + + + +
+
+ + +
+
    +
  • + Test 1 +
  • + +
+
+
+
+ `, + language: 'html', + }, + }, + }, +} diff --git a/packages/components/select/test/select.spec.ts b/packages/components/select/test/select.spec.ts index 900bff46..40d81163 100644 --- a/packages/components/select/test/select.spec.ts +++ b/packages/components/select/test/select.spec.ts @@ -17,6 +17,7 @@ describe('Select tests', () => { const findSelected = () => wrapper.find('.puik-select__selected') const findAllOptions = () => wrapper.findAllComponents(PuikOption) const findErrorMsg = () => wrapper.find('.puik-select__error') + const findFullWidth = () => wrapper.find('.puik-select__selected--full-width') const factory = ( template: string, @@ -296,4 +297,44 @@ describe('Select tests', () => { await findInputComponent().setValue(query) expect(customFilterMethod).toHaveBeenCalledOnce() }) + + it('should display the list of options with a maximum content width', () => { + factory( + ` + + `, + () => ({ + value: '', + }) + ) + expect(findSelected().classes(findFullWidth())).toBe(false) + }) + + it('should display the custom label', async () => { + const items = [ + { + label: 'Test', + value: 'test', + }, + { + label: 'Test2', + value: 'test2', + }, + { + label: 'Test3', + value: 'test3', + }, + ] + factory( + ` + + `, + () => ({ + items, + value: '', + }) + ) + await findAllOptions().at(0)?.trigger('click') + expect(findSelected().element.value).toBe('Custom Label') + }) }) diff --git a/packages/theme/src/select.scss b/packages/theme/src/select.scss index 46704abb..246dfad4 100644 --- a/packages/theme/src/select.scss +++ b/packages/theme/src/select.scss @@ -3,7 +3,7 @@ @apply relative; @extend .puik-body-default; &__button { - @apply relative w-full cursor-default bg-white min-h-[36px] text-left + @apply relative w-full h-full cursor-default bg-white min-h-[36px] text-left border border-primary-400 hover:border-primary text-primary @@ -34,8 +34,11 @@ @apply p-2 truncate; } &__options { - @apply absolute mt-2 w-full rounded bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 + @apply absolute mt-2 rounded bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus-visible:outline-none sm:text-sm overflow-x-hidden; + &--full-width { + @apply w-full; + } } &__options-list { @apply max-h-60 overflow-y-auto overflow-x-hidden; @@ -74,4 +77,7 @@ } } } + .puik-select__options:not(.puik-select__options--full-width) .puik-option { + @apply pr-10; + } }