Skip to content

Commit b9adc83

Browse files
J-MichalekJakubbenjamincanac
authored
feat(components): add ui field in items (#4060)
Co-authored-by: Jakub <[email protected]> Co-authored-by: Benjamin Canac <[email protected]>
1 parent d7a4d02 commit b9adc83

32 files changed

+223
-156
lines changed

docs/content/3.components/accordion.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Use the `items` prop as an array of objects with the following properties:
2323
- `value?: string`{lang="ts-type"}
2424
- `disabled?: boolean`{lang="ts-type"}
2525
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
26+
- `class?: any`{lang="ts-type"}
27+
- `ui?: { item?: ClassNameValue, header?: ClassNameValue, trigger?: ClassNameValue, leadingIcon?: ClassNameValue, label?: ClassNameValue, trailingIcon?: ClassNameValue, content?: ClassNameValue, body?: ClassNameValue }`{lang="ts-type"}
2628

2729
::component-code
2830
---

docs/content/3.components/breadcrumb.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ Use the `items` prop as an array of objects with the following properties:
1616
- `label?: string`{lang="ts-type"}
1717
- `icon?: string`{lang="ts-type"}
1818
- `avatar?: AvatarProps`{lang="ts-type"}
19-
- `class?: any`{lang="ts-type"}
2019
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
20+
- `class?: any`{lang="ts-type"}
21+
- `ui?: { item?: ClassNameValue, link?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLeadingAvatar?: ClassNameValue, linkLabel?: ClassNameValue, separator?: ClassNameValue, separatorIcon?: ClassNameValue }`{lang="ts-type"}
2122

2223
You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc.
2324

docs/content/3.components/carousel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ class: 'p-8'
2727
---
2828
::
2929

30+
You can also pass an array of objects with the following properties:
31+
32+
- `class?: any`{lang="ts-type"}
33+
- `ui?: { item?: ClassNameValue }`{lang="ts-type"}
34+
3035
You can control how many items are visible by using the [`basis`](https://tailwindcss.com/docs/flex-basis) / [`width`](https://tailwindcss.com/docs/width) utility classes on the `item`:
3136

3237
::component-example

docs/content/3.components/checkbox-group.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ You can also pass an array of objects with the following properties:
4949
- `description?: string`{lang="ts-type"}
5050
- [`value?: string`{lang="ts-type"}](#value-key)
5151
- `disabled?: boolean`{lang="ts-type"}
52+
- `class?: any`{lang="ts-type"}
53+
- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, icon?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"}
5254

5355
::component-code
5456
---

docs/content/3.components/command-palette.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Each group contains an `items` array of objects that define the commands. Each i
5353
- `disabled?: boolean`{lang="ts-type"}
5454
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
5555
- `onSelect?(e?: Event): void`{lang="ts-type"}
56+
- `class?: any`{lang="ts-type"}
57+
- `ui?: { item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelPrefix?: ClassNameValue, itemLabelBase?: ClassNameValue, itemLabelSuffix?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue, itemTrailingHighlightedIcon?: ClassNameValue, itemTrailingIcon?: ClassNameValue,}`{lang="ts-type"}
5658

5759
You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc.
5860

docs/content/3.components/context-menu.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ Use the `items` prop as an array of objects with the following properties:
2828
- [`color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"`{lang="ts-type"}](#with-color-items)
2929
- [`checked?: boolean`{lang="ts-type"}](#with-checkbox-items)
3030
- `disabled?: boolean`{lang="ts-type"}
31-
- `class?: any`{lang="ts-type"}
3231
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
3332
- `onSelect?(e: Event): void`{lang="ts-type"}
3433
- [`onUpdateChecked?(checked: boolean): void`{lang="ts-type"}](#with-checkbox-items)
3534
- `children?: ContextMenuItem[] | ContextMenuItem[][]`{lang="ts-type"}
35+
- `class?: any`{lang="ts-type"}
36+
- `ui?: { item?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelExternalIcon?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue }`{lang="ts-type"}
3637

3738
You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc.
3839

docs/content/3.components/dropdown-menu.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ Use the `items` prop as an array of objects with the following properties:
2828
- [`color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"`{lang="ts-type"}](#with-color-items)
2929
- [`checked?: boolean`{lang="ts-type"}](#with-checkbox-items)
3030
- `disabled?: boolean`{lang="ts-type"}
31-
- `class?: any`{lang="ts-type"}
3231
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
3332
- `onSelect?(e: Event): void`{lang="ts-type"}
3433
- [`onUpdateChecked?(checked: boolean): void`{lang="ts-type"}](#with-checkbox-items)
3534
- `children?: DropdownMenuItem[] | DropdownMenuItem[][]`{lang="ts-type"}
35+
- `class?: any`{lang="ts-type"}
36+
- `ui?: { item?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelExternalIcon?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue }`{lang="ts-type"}
3637

3738
You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc.
3839

docs/content/3.components/input-menu.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ You can also pass an array of objects with the following properties:
5555
- [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items)
5656
- `disabled?: boolean`{lang="ts-type"}
5757
- `onSelect?(e: Event): void`{lang="ts-type"}
58+
- `class?: any`{lang="ts-type"}
59+
- `ui?: { tagsItem?: ClassNameValue, tagsItemText?: ClassNameValue, tagsItemDelete?: ClassNameValue, tagsItemDeleteIcon?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLabel?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue }`{lang="ts-type"}
5860

5961
::component-code
6062
---

docs/content/3.components/navigation-menu.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ Use the `items` prop as an array of objects with the following properties:
2929
- `open?: boolean`{lang="ts-type"}
3030
- `value?: string`{lang="ts-type"}
3131
- `disabled?: boolean`{lang="ts-type"}
32-
- `class?: any`{lang="ts-type"}
3332
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
3433
- `onSelect?(e: Event): void`{lang="ts-type"}
3534
- `children?: NavigationMenuChildItem[]`{lang="ts-type"}
35+
- `class?: any`{lang="ts-type"}
36+
- `ui?: { linkLeadingAvatarSize?: ClassNameValue, linkLeadingAvatar?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLabel?: ClassNameValue, linkLabelExternalIcon?: ClassNameValue, linkTrailing?: ClassNameValue, linkTrailingBadgeSize?: ClassNameValue, linkTrailingBadge?: ClassNameValue, linkTrailingIcon?: ClassNameValue, label?: ClassNameValue, link?: ClassNameValue, content?: ClassNameValue, childList?: ClassNameValue, childItem?: ClassNameValue, childLink?: ClassNameValue, childLinkIcon?: ClassNameValue, childLinkWrapper?: ClassNameValue, childLinkLabel?: ClassNameValue, childLinkLabelExternalIcon?: ClassNameValue, childLinkDescription?: ClassNameValue }`{lang="ts-type"}
3637

3738
You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc.
3839

@@ -134,8 +135,8 @@ Each item can take a `children` array of objects with the following properties t
134135
- `label: string`
135136
- `description?: string`
136137
- `icon?: string`
137-
- `class?: any`
138138
- `onSelect?(e: Event): void`
139+
- `class?: any`
139140

140141
::
141142

docs/content/3.components/radio-group.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ You can also pass an array of objects with the following properties:
4646
- `description?: string`{lang="ts-type"}
4747
- [`value?: string`{lang="ts-type"}](#value-key)
4848
- `disabled?: boolean`{lang="ts-type"}
49+
- `class?: any`{lang="ts-type"}
50+
- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"}
4951

5052
::component-code
5153
---

docs/content/3.components/select-menu.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ You can also pass an array of objects with the following properties:
5757
- [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items)
5858
- `disabled?: boolean`{lang="ts-type"}
5959
- `onSelect?(e: Event): void`{lang="ts-type"}
60+
- `class?: any`{lang="ts-type"}
61+
- `ui?: { label?: ClassNameValue, separator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLabel?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue }`{lang="ts-type"}
6062

6163
::component-code
6264
---

docs/content/3.components/select.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ You can also pass an array of objects with the following properties:
4848
- [`avatar?: AvatarProps`{lang="ts-type"}](#with-avatar-in-items)
4949
- [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items)
5050
- `disabled?: boolean`{lang="ts-type"}
51+
- `class?: any`{lang="ts-type"}
52+
- `ui?: { label?: ClassNameValue, separator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLabel?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue }`{lang="ts-type"}
5153

5254
::component-code
5355
---

docs/content/3.components/stepper.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Use the `items` prop as an array of objects with the following properties:
2323
- `value?: string | number`{lang="ts-type"}
2424
- `disabled?: boolean`{lang="ts-type"}
2525
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
26+
- `class?: any`{lang="ts-type"}
27+
- `ui?: { item?: ClassNameValue, container?: ClassNameValue, trigger?: ClassNameValue, indicator?: ClassNameValue, icon?: ClassNameValue, separator?: ClassNameValue, wrapper?: ClassNameValue, title?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"}
2628

2729
::component-code
2830
---

docs/content/3.components/tabs.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Use the `items` prop as an array of objects with the following properties:
2323
- `value?: string | number`{lang="ts-type"}
2424
- `disabled?: boolean`{lang="ts-type"}
2525
- [`slot?: string`{lang="ts-type"}](#with-custom-slot)
26+
- `class?: any`{lang="ts-type"}
27+
- `ui?: { trigger?: ClassNameValue, leadingIcon?: ClassNameValue, leadingAvatar?: ClassNameValue, label?: ClassNameValue, content?: ClassNameValue }`{lang="ts-type"}
2628

2729
::component-code
2830
---

docs/content/3.components/tree.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Use the `items` prop as an array of objects with the following properties:
2626
- `children?: TreeItem[]`{lang="ts-type"}
2727
- `onToggle?(e: Event): void`{lang="ts-type"}
2828
- `onSelect?(e?: Event): void`{lang="ts-type"}
29+
- `class?: any`{lang="ts-type"}
30+
- `ui?: { item?: ClassNameValue, itemWithChildren?: ClassNameValue, link?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLabel?: ClassNameValue, linkTrailing?: ClassNameValue, linkTrailingIcon?: ClassNameValue, listWithChildren?: ClassNameValue }`{lang="ts-type"}
2931

3032
::note
3133
A unique identifier is required for each item. The component will use the `value` prop as identifier, falling back to `label` if `value` is not provided. One of these must be provided for the component to work properly.

src/runtime/components/Accordion.vue

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export interface AccordionItem {
2222
/** A unique value for the accordion item. Defaults to the index. */
2323
value?: string
2424
disabled?: boolean
25+
class?: any
26+
ui?: Pick<Accordion['slots'], 'item' | 'header' | 'trigger' | 'leadingIcon' | 'label' | 'trailingIcon' | 'content' | 'body'>
2527
[key: string]: any
2628
}
2729
@@ -96,27 +98,27 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.accordion ||
9698
:key="index"
9799
:value="item.value || String(index)"
98100
:disabled="item.disabled"
99-
:class="ui.item({ class: props.ui?.item })"
101+
:class="ui.item({ class: [props.ui?.item, item.ui?.item, item.class] })"
100102
>
101-
<AccordionHeader as="div" :class="ui.header({ class: props.ui?.header })">
102-
<AccordionTrigger :class="ui.trigger({ class: props.ui?.trigger, disabled: item.disabled })">
103+
<AccordionHeader as="div" :class="ui.header({ class: [props.ui?.header, item.ui?.header] })">
104+
<AccordionTrigger :class="ui.trigger({ class: [props.ui?.trigger, item.ui?.trigger], disabled: item.disabled })">
103105
<slot name="leading" :item="item" :index="index" :open="open">
104-
<UIcon v-if="item.icon" :name="item.icon" :class="ui.leadingIcon({ class: props.ui?.leadingIcon })" />
106+
<UIcon v-if="item.icon" :name="item.icon" :class="ui.leadingIcon({ class: [props.ui?.leadingIcon, item?.ui?.leadingIcon] })" />
105107
</slot>
106108

107-
<span v-if="get(item, props.labelKey as string) || !!slots.default" :class="ui.label({ class: props.ui?.label })">
109+
<span v-if="get(item, props.labelKey as string) || !!slots.default" :class="ui.label({ class: [props.ui?.label, item.ui?.label] })">
108110
<slot :item="item" :index="index" :open="open">{{ get(item, props.labelKey as string) }}</slot>
109111
</span>
110112

111113
<slot name="trailing" :item="item" :index="index" :open="open">
112-
<UIcon :name="item.trailingIcon || trailingIcon || appConfig.ui.icons.chevronDown" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" />
114+
<UIcon :name="item.trailingIcon || trailingIcon || appConfig.ui.icons.chevronDown" :class="ui.trailingIcon({ class: [props.ui?.trailingIcon, item.ui?.trailingIcon] })" />
113115
</slot>
114116
</AccordionTrigger>
115117
</AccordionHeader>
116118

117-
<AccordionContent v-if="item.content || !!slots.content || (item.slot && !!slots[item.slot as keyof AccordionSlots<T>]) || !!slots.body || (item.slot && !!slots[`${item.slot}-body` as keyof AccordionSlots<T>])" :class="ui.content({ class: props.ui?.content })">
119+
<AccordionContent v-if="item.content || !!slots.content || (item.slot && !!slots[item.slot as keyof AccordionSlots<T>]) || !!slots.body || (item.slot && !!slots[`${item.slot}-body` as keyof AccordionSlots<T>])" :class="ui.content({ class: [props.ui?.content, item.ui?.content] })">
118120
<slot :name="((item.slot || 'content') as keyof AccordionSlots<T>)" :item="(item as Extract<T, { slot: string; }>)" :index="index" :open="open">
119-
<div :class="ui.body({ class: props.ui?.body })">
121+
<div :class="ui.body({ class: [props.ui?.body, item.ui?.body] })">
120122
<slot :name="((item.slot ? `${item.slot}-body`: 'body') as keyof AccordionSlots<T>)" :item="(item as Extract<T, { slot: string; }>)" :index="index" :open="open">
121123
{{ item.content }}
122124
</slot>

src/runtime/components/Breadcrumb.vue

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export interface BreadcrumbItem extends Omit<LinkProps, 'raw' | 'custom'> {
1515
icon?: string
1616
avatar?: AvatarProps
1717
slot?: string
18+
class?: any
19+
ui?: Pick<Breadcrumb['slots'], 'item' | 'link' | 'linkLeadingIcon' | 'linkLeadingAvatar' | 'linkLabel' | 'separator' | 'separatorIcon'>
1820
[key: string]: any
1921
}
2022
@@ -84,16 +86,16 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.breadcrumb |
8486
<Primitive :as="as" aria-label="breadcrumb" :class="ui.root({ class: [props.ui?.root, props.class] })">
8587
<ol :class="ui.list({ class: props.ui?.list })">
8688
<template v-for="(item, index) in items" :key="index">
87-
<li :class="ui.item({ class: props.ui?.item })">
89+
<li :class="ui.item({ class: [props.ui?.item, item.ui?.item, item.class] })">
8890
<ULink v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
89-
<ULinkBase v-bind="slotProps" as="span" :aria-current="active && (index === items!.length - 1) ? 'page' : undefined" :class="ui.link({ class: [props.ui?.link, item.class], active: index === items!.length - 1, disabled: !!item.disabled, to: !!item.to })">
91+
<ULinkBase v-bind="slotProps" as="span" :aria-current="active && (index === items!.length - 1) ? 'page' : undefined" :class="ui.link({ class: [props.ui?.link, item.ui?.link], active: index === items!.length - 1, disabled: !!item.disabled, to: !!item.to })">
9092
<slot :name="((item.slot || 'item') as keyof BreadcrumbSlots<T>)" :item="item" :index="index">
9193
<slot :name="((item.slot ? `${item.slot}-leading`: 'item-leading') as keyof BreadcrumbSlots<T>)" :item="item" :active="index === items!.length - 1" :index="index">
92-
<UIcon v-if="item.icon" :name="item.icon" :class="ui.linkLeadingIcon({ class: props.ui?.linkLeadingIcon, active: index === items!.length - 1 })" />
93-
<UAvatar v-else-if="item.avatar" :size="((props.ui?.linkLeadingAvatarSize || ui.linkLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.linkLeadingAvatar({ class: props.ui?.linkLeadingAvatar, active: index === items!.length - 1 })" />
94+
<UIcon v-if="item.icon" :name="item.icon" :class="ui.linkLeadingIcon({ class: [props.ui?.linkLeadingIcon, item.ui?.linkLeadingIcon], active: index === items!.length - 1 })" />
95+
<UAvatar v-else-if="item.avatar" :size="((props.ui?.linkLeadingAvatarSize || ui.linkLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="ui.linkLeadingAvatar({ class: [props.ui?.linkLeadingAvatar, item.ui?.linkLeadingAvatar], active: index === items!.length - 1 })" />
9496
</slot>
9597

96-
<span v-if="get(item, props.labelKey as string) || !!slots[(item.slot ? `${item.slot}-label`: 'item-label') as keyof BreadcrumbSlots<T>]" :class="ui.linkLabel({ class: props.ui?.linkLabel })">
98+
<span v-if="get(item, props.labelKey as string) || !!slots[(item.slot ? `${item.slot}-label`: 'item-label') as keyof BreadcrumbSlots<T>]" :class="ui.linkLabel({ class: [props.ui?.linkLabel, item.ui?.linkLabel] })">
9799
<slot :name="((item.slot ? `${item.slot}-label`: 'item-label') as keyof BreadcrumbSlots<T>)" :item="item" :active="index === items!.length - 1" :index="index">
98100
{{ get(item, props.labelKey as string) }}
99101
</slot>
@@ -105,9 +107,9 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.breadcrumb |
105107
</ULink>
106108
</li>
107109

108-
<li v-if="index < items!.length - 1" role="presentation" aria-hidden="true" :class="ui.separator({ class: props.ui?.separator })">
110+
<li v-if="index < items!.length - 1" role="presentation" aria-hidden="true" :class="ui.separator({ class: [props.ui?.separator, item.ui?.separator] })">
109111
<slot name="separator">
110-
<UIcon :name="separatorIcon" :class="ui.separatorIcon({ class: props.ui?.separatorIcon })" />
112+
<UIcon :name="separatorIcon" :class="ui.separatorIcon({ class: [props.ui?.separatorIcon, item.ui?.separatorIcon] })" />
111113
</slot>
112114
</li>
113115
</template>

src/runtime/components/Carousel.vue

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ import type { ComponentConfig } from '../types/utils'
1515
1616
type Carousel = ComponentConfig<typeof theme, AppConfig, 'carousel'>
1717
18-
export type CarouselItem = AcceptableValue
18+
interface _CarouselItem {
19+
class?: any
20+
ui?: Pick<Carousel['slots'], 'item'>
21+
[key: string]: any
22+
}
23+
24+
export type CarouselItem = _CarouselItem | AcceptableValue
1925
2026
export interface CarouselProps<T extends CarouselItem = CarouselItem> extends Omit<EmblaOptionsType, 'axis' | 'container' | 'slides' | 'direction'> {
2127
/**
@@ -254,6 +260,10 @@ function onSelect(api: EmblaCarouselType) {
254260
emits('select', selectedIndex.value)
255261
}
256262
263+
function isCarouselItem(item: CarouselItem): item is _CarouselItem {
264+
return typeof item === 'object' && item !== null
265+
}
266+
257267
onMounted(() => {
258268
if (!emblaApi.value) {
259269
return
@@ -288,7 +298,7 @@ defineExpose({
288298
:key="index"
289299
role="group"
290300
aria-roledescription="slide"
291-
:class="ui.item({ class: props.ui?.item })"
301+
:class="ui.item({ class: [props.ui?.item, isCarouselItem(item) && item.ui?.item, isCarouselItem(item) && item.class] })"
292302
>
293303
<slot :item="item" :index="index" />
294304
</div>

0 commit comments

Comments
 (0)