@byyuurin/ui 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE +20 -20
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +2 -2
  4. package/dist/runtime/components/Accordion.vue +43 -43
  5. package/dist/runtime/components/Alert.vue +65 -64
  6. package/dist/runtime/components/App.vue +10 -10
  7. package/dist/runtime/components/Avatar.vue +31 -30
  8. package/dist/runtime/components/AvatarGroup.vue +6 -5
  9. package/dist/runtime/components/Badge.vue +36 -35
  10. package/dist/runtime/components/Breadcrumb.vue +51 -51
  11. package/dist/runtime/components/Button.vue +54 -55
  12. package/dist/runtime/components/Calendar.vue +76 -75
  13. package/dist/runtime/components/Card.vue +43 -42
  14. package/dist/runtime/components/Carousel.vue +68 -67
  15. package/dist/runtime/components/Checkbox.vue +50 -48
  16. package/dist/runtime/components/CheckboxGroup.vue +33 -32
  17. package/dist/runtime/components/Chip.vue +20 -16
  18. package/dist/runtime/components/Collapsible.vue +16 -15
  19. package/dist/runtime/components/Drawer.vue +78 -77
  20. package/dist/runtime/components/DropdownMenu.vue +29 -29
  21. package/dist/runtime/components/DropdownMenuContent.vue +152 -152
  22. package/dist/runtime/components/FieldGroup.vue +5 -4
  23. package/dist/runtime/components/FileUpload.vue +267 -0
  24. package/dist/runtime/components/FileUpload.vue.d.ts +178 -0
  25. package/dist/runtime/components/Form.vue +11 -10
  26. package/dist/runtime/components/FormField.vue +39 -38
  27. package/dist/runtime/components/Icon.vue +2 -2
  28. package/dist/runtime/components/Input.vue +52 -52
  29. package/dist/runtime/components/InputNumber.vue +50 -49
  30. package/dist/runtime/components/InputTags.vue +55 -55
  31. package/dist/runtime/components/Kbd.vue +5 -4
  32. package/dist/runtime/components/Link.vue +25 -24
  33. package/dist/runtime/components/LinkBase.vue +3 -3
  34. package/dist/runtime/components/Marquee.vue +7 -6
  35. package/dist/runtime/components/Modal.vue +76 -75
  36. package/dist/runtime/components/NavigationMenu.vue +230 -230
  37. package/dist/runtime/components/OverlayProvider.vue +9 -9
  38. package/dist/runtime/components/Pagination.vue +49 -48
  39. package/dist/runtime/components/PinInput.vue +25 -25
  40. package/dist/runtime/components/Popover.vue +23 -23
  41. package/dist/runtime/components/Progress.vue +27 -26
  42. package/dist/runtime/components/RadioGroup.vue +53 -53
  43. package/dist/runtime/components/ScrollArea.vue +34 -33
  44. package/dist/runtime/components/Select.vue +203 -203
  45. package/dist/runtime/components/Separator.vue +32 -31
  46. package/dist/runtime/components/Skeleton.vue +13 -12
  47. package/dist/runtime/components/Slider.vue +27 -26
  48. package/dist/runtime/components/Stepper.vue +53 -52
  49. package/dist/runtime/components/Stepper.vue.d.ts +2 -2
  50. package/dist/runtime/components/Switch.vue +33 -34
  51. package/dist/runtime/components/Table.vue +139 -138
  52. package/dist/runtime/components/Tabs.vue +76 -76
  53. package/dist/runtime/components/Textarea.vue +50 -50
  54. package/dist/runtime/components/Timeline.vue +49 -48
  55. package/dist/runtime/components/Toast.vue +95 -94
  56. package/dist/runtime/components/ToastProvider.vue +31 -31
  57. package/dist/runtime/components/Tooltip.vue +26 -25
  58. package/dist/runtime/components/Tree.vue +133 -133
  59. package/dist/runtime/composables/useFileUpload.d.ts +19 -0
  60. package/dist/runtime/composables/useFileUpload.js +79 -0
  61. package/dist/runtime/composables/useLocale.d.ts +6 -0
  62. package/dist/runtime/locale/en.d.ts +3 -0
  63. package/dist/runtime/locale/en.js +3 -0
  64. package/dist/runtime/locale/zh_tw.d.ts +3 -0
  65. package/dist/runtime/locale/zh_tw.js +3 -0
  66. package/dist/runtime/types/index.d.ts +1 -0
  67. package/dist/runtime/types/index.js +1 -0
  68. package/dist/runtime/types/locale.d.ts +3 -0
  69. package/dist/runtime/types/unocss.d.ts +4 -4
  70. package/dist/runtime/types/utils.d.ts +1 -1
  71. package/dist/runtime/vue/components/Icon.vue +2 -2
  72. package/dist/setup.d.mts +1 -1
  73. package/dist/shared/{ui.D8Bg1HWt.d.mts → ui.CGCKYv7g.d.mts} +4 -2
  74. package/dist/shared/{ui.9kQouwss.mjs → ui.DYMXCXO6.mjs} +4 -2
  75. package/dist/shared/{ui.DpkP12cX.mjs → ui.DcEKQd0n.mjs} +230 -5
  76. package/dist/unocss.mjs +1 -1
  77. package/dist/unplugin.d.mts +1 -1
  78. package/dist/unplugin.mjs +2 -2
  79. package/dist/vite.d.mts +1 -1
  80. package/dist/vite.mjs +2 -2
  81. package/package.json +10 -10
  82. package/vue-plugin.d.ts +5 -5
@@ -13,7 +13,7 @@ import { useFieldGroup } from "../composables/useFieldGroup";
13
13
  import { useFormField } from "../composables/useFormField";
14
14
  import { useLocale } from "../composables/useLocale";
15
15
  import { usePortal } from "../composables/usePortal";
16
- import { compare, get, getDisplayValue, isArrayOfArray, looseToNumber } from "../utils";
16
+ import { compare, get, getDisplayValue, isArrayOfArray, looseToNumber, pick } from "../utils";
17
17
  import { cv, merge } from "../utils/style";
18
18
  import Avatar from "./Avatar.vue";
19
19
  import Button from "./Button.vue";
@@ -90,13 +90,13 @@ const { isLeading, isTrailing, leadingIconName, trailingIconName } = useComponen
90
90
  const ui = computed(() => {
91
91
  const styler = cv(merge(theme, appConfig.ui.select));
92
92
  return styler({
93
- ...props,
94
- fieldGroup: orientation.value,
95
- size: fieldGroupSize.value || formFieldSize.value,
93
+ ...pick(props, ["variant", "loading"]),
96
94
  color: color.value,
95
+ size: fieldGroupSize.value || formFieldSize.value,
97
96
  highlight: highlight.value,
98
97
  leading: isLeading.value || !!props.avatar || !!slots.leading,
99
98
  trailing: isTrailing.value || !!slots.trailing,
99
+ fieldGroup: orientation.value,
100
100
  searchInput: !!props.searchInput
101
101
  });
102
102
  });
@@ -223,203 +223,203 @@ defineExpose({
223
223
  </script>
224
224
 
225
225
  <template>
226
- <DefineCreateItemTemplate>
227
- <ComboboxItem
228
- :value="searchTerm"
229
- :class="ui.item({ class: props.ui?.item })"
230
- data-part="item"
231
- @select="onCreate"
232
- >
233
- <span :class="ui.itemLabel({ class: props.ui?.itemLabel })" data-part="itemLabel">
234
- <slot name="create-item-label" :item="searchTerm">
235
- {{ t("select.create", { label: searchTerm }) }}
236
- </slot>
237
- </span>
238
- </ComboboxItem>
239
- </DefineCreateItemTemplate>
240
-
241
- <ComboboxRoot
242
- :id="id"
243
- v-slot="{ modelValue, open }"
244
- v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
245
- :name="name"
246
- :disabled="disabled"
247
- ignore-filter
248
- as-child
249
- @update:model-value="onUpdate"
250
- @update:open="onUpdateOpen"
251
- >
252
- <ComboboxAnchor as-child>
253
- <ComboboxTrigger ref="triggerRef" :class="ui.base({ class: [props.ui?.base, props.class] })" data-part="base" tabindex="0">
254
- <span v-if="isLeading || !!props.avatar || slots.leading" :class="ui.leading({ class: props.ui?.leading })" data-part="leading">
255
- <slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
256
- <Icon
257
- v-if="isLeading && leadingIconName"
258
- :name="leadingIconName"
259
- :class="ui.leadingIcon({ class: props.ui?.leadingIcon })"
260
- data-part="leadingIcon"
261
- />
262
- <Avatar
263
- v-else-if="props.avatar"
264
- :size="props.ui?.itemLeadingChipSize || ui.itemLeadingAvatarSize()"
265
- v-bind="props.avatar"
266
- :class="ui.leadingAvatar({ class: props.ui?.leadingAvatar })"
267
- data-part="leadingAvatar"
268
- />
269
- </slot>
270
- </span>
271
-
272
- <slot :model-value="modelValue" :open="open" :ui="ui">
273
- <template v-for="displayedModelValue in [displayValue(modelValue)]" :key="displayedModelValue">
274
- <span v-if="displayedModelValue != null" :class="ui.value({ class: props.ui?.value })" data-part="value">
275
- {{ displayedModelValue }}
276
- </span>
277
- <span v-else :class="ui.placeholder({ class: props.ui?.placeholder })" data-part="placeholder">
278
- <template v-if="props.placeholder">{{ props.placeholder }}</template>
279
- <template v-else>&nbsp;</template>
280
- </span>
281
- </template>
282
- </slot>
283
-
284
- <span v-if="isTrailing || !!slots.trailing || props.clear" :class="ui.trailing({ class: props.ui?.trailing })" data-part="trailing">
285
- <slot name="trailing" :model-value="modelValue" :open="open" :ui="ui">
286
- <ComboboxCancel v-if="props.clear && !isModelValueEmpty(modelValue)" as-child>
287
- <Button
288
- as="span"
289
- :icon="props.clearIcon || appConfig.ui.icons.close"
290
- variant="link"
291
- color="neutral"
292
- tabindex="-1"
293
- v-bind="clearProps"
294
- :class="ui.trailingClear({ class: props.ui?.trailingClear })"
295
- data-part="trailingClear"
296
- @click.stop="onClear"
297
- />
298
- </ComboboxCancel>
299
- <Icon v-else-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" data-part="trailingIcon" />
300
- </slot>
301
- </span>
302
- </ComboboxTrigger>
303
- </ComboboxAnchor>
304
-
305
- <ComboboxPortal v-bind="portalProps">
306
- <ComboboxContent v-bind="contentProps" :class="ui.content({ class: props.ui?.content })" data-part="content">
307
- <FocusScope trapped :class="ui.focusScope({ class: props.ui?.focusScope })" data-part="focusScope">
308
- <slot name="content-top"></slot>
309
-
310
- <ComboboxInput v-model="searchTerm" :display-value="() => searchTerm" as-child>
311
- <Input
312
- autofocus
313
- autocomplete="off"
314
- :size="props.size"
315
- v-bind="searchInputProps"
316
- :class="ui.input({ class: props.ui?.input })"
317
- data-part="input"
318
- @change.stop
319
- />
320
- </ComboboxInput>
321
-
322
- <ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })" data-part="empty">
323
- <slot name="empty" :search-term="searchTerm">
324
- {{ searchTerm ? t("select.noMatch", { searchTerm }) : t("select.noData") }}
325
- </slot>
326
- </ComboboxEmpty>
327
-
328
- <div role="presentation" :class="ui.viewport({ class: props.ui?.viewport })" data-part="viewport">
329
- <ComboboxGroup v-if="createItem && createItemPosition === 'top'" :class="ui.group({ class: props.ui?.group })" data-part="group">
330
- <ReuseCreateItemTemplate />
331
- </ComboboxGroup>
332
-
333
- <ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })" data-part="group">
334
- <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
335
- <ComboboxLabel
336
- v-if="isSelectItem(item) && item.type === 'label'"
337
- :class="ui.label({ class: [props.ui?.label, item.ui?.label, item.class] })"
338
- data-part="label"
339
- >
340
- {{ get(item, props.labelKey) }}
341
- </ComboboxLabel>
342
-
343
- <ComboboxSeparator
344
- v-else-if="isSelectItem(item) && item.type === 'separator'"
345
- :class="ui.separator({ class: [props.ui?.separator, item.ui?.separator, item.class] })"
346
- data-part="separator"
347
- />
348
-
349
- <ComboboxItem
350
- v-else
351
- :value="props.valueKey && isSelectItem(item) ? get(item, props.valueKey) : item"
352
- :disabled="isSelectItem(item) && item.disabled"
353
- :class="ui.item({ class: [props.ui?.item, ...isSelectItem(item) ? [item.ui?.item, item.class] : []] })"
354
- data-part="item"
355
- @select="onSelect($event, item)"
356
- >
357
- <slot name="item" :item="item" :index="index" :ui="ui">
358
- <slot name="item-leading" :item="item" :index="index" :ui="ui">
359
- <Icon
360
- v-if="isSelectItem(item) && item.icon"
361
- :name="item.icon"
362
- :class="ui.itemLeadingIcon({ class: [props.ui?.itemLeadingIcon, item.ui?.itemLeadingIcon] })"
363
- data-part="itemLeadingIcon"
364
- />
365
- <Avatar
366
- v-else-if="isSelectItem(item) && item.avatar"
367
- :size="item.ui?.itemLeadingAvatarSize || props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()"
368
- v-bind="item.avatar"
369
- :class="ui.itemLeadingAvatar({ class: [props.ui?.leadingAvatar, item.ui?.itemLeadingAvatar] })"
370
- data-part="itemLeadingAvatar"
371
- />
372
- <Chip
373
- v-else-if="isSelectItem(item) && item.chip"
374
- :size="item.ui?.itemLeadingChipSize || props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()"
375
- inset
376
- standalone
377
- v-bind="item.chip"
378
- :class="ui.itemLeadingChip({ class: [props.ui?.itemLeadingChip, item.ui?.itemLeadingChip] })"
379
- data-part="itemLeadingChip"
380
- />
381
- </slot>
382
-
383
- <span :class="ui.itemWrapper({ class: [props.ui?.itemWrapper, isSelectItem(item) && item.ui?.itemWrapper] })" data-part="itemWrapper">
384
- <span :class="ui.itemLabel({ class: [props.ui?.itemLabel, isSelectItem(item) && item.ui?.itemLabel] })" data-part="itemLabel">
385
- <slot name="item-label" :item="item" :index="index">
386
- {{ isSelectItem(item) ? get(item, props.labelKey) : item }}
387
- </slot>
388
- </span>
389
-
390
- <span
391
- v-if="isSelectItem(item) && get(item, props.descriptionKey) || !!slots['item-description']"
392
- :class="ui.itemDescription({ class: [props.ui?.itemDescription, isSelectItem(item) && item.ui?.itemDescription] })"
393
- data-part="itemDescription"
394
- >
395
- <slot name="item-description" :item="item" :index="index">
396
- {{ isSelectItem(item) ? get(item, props.descriptionKey) : "" }}
397
- </slot>
398
- </span>
399
- </span>
400
-
401
- <span :class="ui.itemTrailing({ class: [props.ui?.itemTrailing, isSelectItem(item) && item.ui?.itemTrailing] })" data-part="itemTrailing">
402
- <slot name="item-trailing" :item="item" :index="index" :ui="ui"></slot>
403
-
404
- <ComboboxItemIndicator as-child>
405
- <Icon :name="props.selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: [props.ui?.itemTrailingIcon, isSelectItem(item) && item.ui?.itemTrailingIcon] })" data-part="itemTrailingIcon" />
406
- </ComboboxItemIndicator>
407
- </span>
408
- </slot>
409
- </ComboboxItem>
410
- </template>
411
- </ComboboxGroup>
412
-
413
- <ComboboxGroup v-if="createItem && createItemPosition === 'bottom'" :class="ui.group({ class: props.ui?.group })" data-part="group">
414
- <ReuseCreateItemTemplate />
415
- </ComboboxGroup>
416
- </div>
417
-
418
- <slot name="content-bottom"></slot>
419
- </FocusScope>
420
-
421
- <ComboboxArrow v-if="props.arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" data-part="arrow" />
422
- </ComboboxContent>
423
- </ComboboxPortal>
424
- </ComboboxRoot>
226
+ <DefineCreateItemTemplate>
227
+ <ComboboxItem
228
+ :value="searchTerm"
229
+ :class="ui.item({ class: props.ui?.item })"
230
+ data-part="item"
231
+ @select="onCreate"
232
+ >
233
+ <span :class="ui.itemLabel({ class: props.ui?.itemLabel })" data-part="itemLabel">
234
+ <slot name="create-item-label" :item="searchTerm">
235
+ {{ t("select.create", { label: searchTerm }) }}
236
+ </slot>
237
+ </span>
238
+ </ComboboxItem>
239
+ </DefineCreateItemTemplate>
240
+
241
+ <ComboboxRoot
242
+ :id="id"
243
+ v-slot="{ modelValue, open }"
244
+ v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
245
+ :name="name"
246
+ :disabled="disabled"
247
+ ignore-filter
248
+ as-child
249
+ @update:model-value="onUpdate"
250
+ @update:open="onUpdateOpen"
251
+ >
252
+ <ComboboxAnchor as-child>
253
+ <ComboboxTrigger ref="triggerRef" :class="ui.base({ class: [props.ui?.base, props.class] })" data-part="base" tabindex="0">
254
+ <span v-if="isLeading || !!props.avatar || slots.leading" :class="ui.leading({ class: props.ui?.leading })" data-part="leading">
255
+ <slot name="leading" :model-value="modelValue" :open="open" :ui="ui">
256
+ <Icon
257
+ v-if="isLeading && leadingIconName"
258
+ :name="leadingIconName"
259
+ :class="ui.leadingIcon({ class: props.ui?.leadingIcon })"
260
+ data-part="leadingIcon"
261
+ />
262
+ <Avatar
263
+ v-else-if="props.avatar"
264
+ :size="props.ui?.itemLeadingChipSize || ui.itemLeadingAvatarSize()"
265
+ v-bind="props.avatar"
266
+ :class="ui.leadingAvatar({ class: props.ui?.leadingAvatar })"
267
+ data-part="leadingAvatar"
268
+ />
269
+ </slot>
270
+ </span>
271
+
272
+ <slot :model-value="modelValue" :open="open" :ui="ui">
273
+ <template v-for="displayedModelValue in [displayValue(modelValue)]" :key="displayedModelValue">
274
+ <span v-if="displayedModelValue != null" :class="ui.value({ class: props.ui?.value })" data-part="value">
275
+ {{ displayedModelValue }}
276
+ </span>
277
+ <span v-else :class="ui.placeholder({ class: props.ui?.placeholder })" data-part="placeholder">
278
+ <template v-if="props.placeholder">{{ props.placeholder }}</template>
279
+ <template v-else>&nbsp;</template>
280
+ </span>
281
+ </template>
282
+ </slot>
283
+
284
+ <span v-if="isTrailing || !!slots.trailing || props.clear" :class="ui.trailing({ class: props.ui?.trailing })" data-part="trailing">
285
+ <slot name="trailing" :model-value="modelValue" :open="open" :ui="ui">
286
+ <ComboboxCancel v-if="props.clear && !isModelValueEmpty(modelValue)" as-child>
287
+ <Button
288
+ as="span"
289
+ :icon="props.clearIcon || appConfig.ui.icons.close"
290
+ variant="link"
291
+ color="neutral"
292
+ tabindex="-1"
293
+ v-bind="clearProps"
294
+ :class="ui.trailingClear({ class: props.ui?.trailingClear })"
295
+ data-part="trailingClear"
296
+ @click.stop="onClear"
297
+ />
298
+ </ComboboxCancel>
299
+ <Icon v-else-if="trailingIconName" :name="trailingIconName" :class="ui.trailingIcon({ class: props.ui?.trailingIcon })" data-part="trailingIcon" />
300
+ </slot>
301
+ </span>
302
+ </ComboboxTrigger>
303
+ </ComboboxAnchor>
304
+
305
+ <ComboboxPortal v-bind="portalProps">
306
+ <ComboboxContent v-bind="contentProps" :class="ui.content({ class: props.ui?.content })" data-part="content">
307
+ <FocusScope trapped :class="ui.focusScope({ class: props.ui?.focusScope })" data-part="focusScope">
308
+ <slot name="content-top"></slot>
309
+
310
+ <ComboboxInput v-model="searchTerm" :display-value="() => searchTerm" as-child>
311
+ <Input
312
+ autofocus
313
+ autocomplete="off"
314
+ :size="props.size"
315
+ v-bind="searchInputProps"
316
+ :class="ui.input({ class: props.ui?.input })"
317
+ data-part="input"
318
+ @change.stop
319
+ />
320
+ </ComboboxInput>
321
+
322
+ <ComboboxEmpty :class="ui.empty({ class: props.ui?.empty })" data-part="empty">
323
+ <slot name="empty" :search-term="searchTerm">
324
+ {{ searchTerm ? t("select.noMatch", { searchTerm }) : t("select.noData") }}
325
+ </slot>
326
+ </ComboboxEmpty>
327
+
328
+ <div role="presentation" :class="ui.viewport({ class: props.ui?.viewport })" data-part="viewport">
329
+ <ComboboxGroup v-if="createItem && createItemPosition === 'top'" :class="ui.group({ class: props.ui?.group })" data-part="group">
330
+ <ReuseCreateItemTemplate />
331
+ </ComboboxGroup>
332
+
333
+ <ComboboxGroup v-for="(group, groupIndex) in filteredGroups" :key="`group-${groupIndex}`" :class="ui.group({ class: props.ui?.group })" data-part="group">
334
+ <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
335
+ <ComboboxLabel
336
+ v-if="isSelectItem(item) && item.type === 'label'"
337
+ :class="ui.label({ class: [props.ui?.label, item.ui?.label, item.class] })"
338
+ data-part="label"
339
+ >
340
+ {{ get(item, props.labelKey) }}
341
+ </ComboboxLabel>
342
+
343
+ <ComboboxSeparator
344
+ v-else-if="isSelectItem(item) && item.type === 'separator'"
345
+ :class="ui.separator({ class: [props.ui?.separator, item.ui?.separator, item.class] })"
346
+ data-part="separator"
347
+ />
348
+
349
+ <ComboboxItem
350
+ v-else
351
+ :value="props.valueKey && isSelectItem(item) ? get(item, props.valueKey) : item"
352
+ :disabled="isSelectItem(item) && item.disabled"
353
+ :class="ui.item({ class: [props.ui?.item, ...isSelectItem(item) ? [item.ui?.item, item.class] : []] })"
354
+ data-part="item"
355
+ @select="onSelect($event, item)"
356
+ >
357
+ <slot name="item" :item="item" :index="index" :ui="ui">
358
+ <slot name="item-leading" :item="item" :index="index" :ui="ui">
359
+ <Icon
360
+ v-if="isSelectItem(item) && item.icon"
361
+ :name="item.icon"
362
+ :class="ui.itemLeadingIcon({ class: [props.ui?.itemLeadingIcon, item.ui?.itemLeadingIcon] })"
363
+ data-part="itemLeadingIcon"
364
+ />
365
+ <Avatar
366
+ v-else-if="isSelectItem(item) && item.avatar"
367
+ :size="item.ui?.itemLeadingAvatarSize || props.ui?.itemLeadingAvatarSize || ui.itemLeadingAvatarSize()"
368
+ v-bind="item.avatar"
369
+ :class="ui.itemLeadingAvatar({ class: [props.ui?.leadingAvatar, item.ui?.itemLeadingAvatar] })"
370
+ data-part="itemLeadingAvatar"
371
+ />
372
+ <Chip
373
+ v-else-if="isSelectItem(item) && item.chip"
374
+ :size="item.ui?.itemLeadingChipSize || props.ui?.itemLeadingChipSize || ui.itemLeadingChipSize()"
375
+ inset
376
+ standalone
377
+ v-bind="item.chip"
378
+ :class="ui.itemLeadingChip({ class: [props.ui?.itemLeadingChip, item.ui?.itemLeadingChip] })"
379
+ data-part="itemLeadingChip"
380
+ />
381
+ </slot>
382
+
383
+ <span :class="ui.itemWrapper({ class: [props.ui?.itemWrapper, isSelectItem(item) && item.ui?.itemWrapper] })" data-part="itemWrapper">
384
+ <span :class="ui.itemLabel({ class: [props.ui?.itemLabel, isSelectItem(item) && item.ui?.itemLabel] })" data-part="itemLabel">
385
+ <slot name="item-label" :item="item" :index="index">
386
+ {{ isSelectItem(item) ? get(item, props.labelKey) : item }}
387
+ </slot>
388
+ </span>
389
+
390
+ <span
391
+ v-if="isSelectItem(item) && get(item, props.descriptionKey) || !!slots['item-description']"
392
+ :class="ui.itemDescription({ class: [props.ui?.itemDescription, isSelectItem(item) && item.ui?.itemDescription] })"
393
+ data-part="itemDescription"
394
+ >
395
+ <slot name="item-description" :item="item" :index="index">
396
+ {{ isSelectItem(item) ? get(item, props.descriptionKey) : "" }}
397
+ </slot>
398
+ </span>
399
+ </span>
400
+
401
+ <span :class="ui.itemTrailing({ class: [props.ui?.itemTrailing, isSelectItem(item) && item.ui?.itemTrailing] })" data-part="itemTrailing">
402
+ <slot name="item-trailing" :item="item" :index="index" :ui="ui"></slot>
403
+
404
+ <ComboboxItemIndicator as-child>
405
+ <Icon :name="props.selectedIcon || appConfig.ui.icons.check" :class="ui.itemTrailingIcon({ class: [props.ui?.itemTrailingIcon, isSelectItem(item) && item.ui?.itemTrailingIcon] })" data-part="itemTrailingIcon" />
406
+ </ComboboxItemIndicator>
407
+ </span>
408
+ </slot>
409
+ </ComboboxItem>
410
+ </template>
411
+ </ComboboxGroup>
412
+
413
+ <ComboboxGroup v-if="createItem && createItemPosition === 'bottom'" :class="ui.group({ class: props.ui?.group })" data-part="group">
414
+ <ReuseCreateItemTemplate />
415
+ </ComboboxGroup>
416
+ </div>
417
+
418
+ <slot name="content-bottom"></slot>
419
+ </FocusScope>
420
+
421
+ <ComboboxArrow v-if="props.arrow" v-bind="arrowProps" :class="ui.arrow({ class: props.ui?.arrow })" data-part="arrow" />
422
+ </ComboboxContent>
423
+ </ComboboxPortal>
424
+ </ComboboxRoot>
425
425
  </template>
@@ -7,6 +7,7 @@ import { reactivePick } from "@vueuse/core";
7
7
  import { Separator, useForwardProps } from "reka-ui";
8
8
  import { computed } from "vue";
9
9
  import { useAppConfig } from "#imports";
10
+ import { pick } from "../utils";
10
11
  import { cv, merge } from "../utils/style";
11
12
  import Avatar from "./Avatar.vue";
12
13
  import Icon from "./Icon.vue";
@@ -29,39 +30,39 @@ const rootProps = useForwardProps(reactivePick(props, "as", "decorative", "orien
29
30
  const appConfig = useAppConfig();
30
31
  const ui = computed(() => {
31
32
  const styler = cv(merge(theme, appConfig.ui.separator));
32
- return styler(props);
33
+ return styler(pick(props, ["color", "orientation", "size", "type"]));
33
34
  });
34
35
  </script>
35
36
 
36
37
  <template>
37
- <Separator v-bind="rootProps" :class="ui.root({ class: [props.ui?.root, props.class] })" data-part="root">
38
- <div :class="ui.border({ class: props.ui?.border, start: props.align === 'start' })" data-part="border"></div>
39
-
40
- <template v-if="props.label || props.icon || props.avatar || !!slots.default">
41
- <div :class="ui.container({ class: props.ui?.container })" data-part="container">
42
- <slot :ui="ui">
43
- <span
44
- v-if="props.label"
45
- :class="ui.label({ class: props.ui?.label })"
46
- data-part="label"
47
- >{{ props.label }}</span>
48
- <Icon
49
- v-else-if="props.icon"
50
- :name="props.icon"
51
- :class="ui.icon({ class: props.ui?.icon })"
52
- data-part="icon"
53
- />
54
- <Avatar
55
- v-else-if="props.avatar"
56
- :size="props.ui?.avatarSize || ui.avatarSize()"
57
- v-bind="props.avatar"
58
- :class="ui.avatar({ class: props.ui?.avatar })"
59
- data-part="avatar"
60
- />
61
- </slot>
62
- </div>
63
-
64
- <div :class="ui.border({ class: props.ui?.border, end: props.align === 'end' })" data-part="border"></div>
65
- </template>
66
- </Separator>
38
+ <Separator v-bind="rootProps" :class="ui.root({ class: [props.ui?.root, props.class] })" data-part="root">
39
+ <div :class="ui.border({ class: props.ui?.border, start: props.align === 'start' })" data-part="border"></div>
40
+
41
+ <template v-if="props.label || props.icon || props.avatar || !!slots.default">
42
+ <div :class="ui.container({ class: props.ui?.container })" data-part="container">
43
+ <slot :ui="ui">
44
+ <span
45
+ v-if="props.label"
46
+ :class="ui.label({ class: props.ui?.label })"
47
+ data-part="label"
48
+ >{{ props.label }}</span>
49
+ <Icon
50
+ v-else-if="props.icon"
51
+ :name="props.icon"
52
+ :class="ui.icon({ class: props.ui?.icon })"
53
+ data-part="icon"
54
+ />
55
+ <Avatar
56
+ v-else-if="props.avatar"
57
+ :size="props.ui?.avatarSize || ui.avatarSize()"
58
+ v-bind="props.avatar"
59
+ :class="ui.avatar({ class: props.ui?.avatar })"
60
+ data-part="avatar"
61
+ />
62
+ </slot>
63
+ </div>
64
+
65
+ <div :class="ui.border({ class: props.ui?.border, end: props.align === 'end' })" data-part="border"></div>
66
+ </template>
67
+ </Separator>
67
68
  </template>
@@ -6,6 +6,7 @@ import { useAppConfig } from "#imports";
6
6
  import { Primitive } from "reka-ui";
7
7
  import { computed } from "vue";
8
8
  import theme from "#build/ui/skeleton";
9
+ import { pick } from "../utils";
9
10
  import { cv, merge } from "../utils/style";
10
11
  const props = defineProps({
11
12
  as: { type: null, required: false },
@@ -14,20 +15,20 @@ const props = defineProps({
14
15
  const appConfig = useAppConfig();
15
16
  const ui = computed(() => {
16
17
  const styler = cv(merge(theme, appConfig.ui.skeleton));
17
- return styler(props);
18
+ return styler(pick(props, []));
18
19
  });
19
20
  </script>
20
21
 
21
22
  <template>
22
- <Primitive
23
- :as="props.as"
24
- aria-busy="true"
25
- aria-label="loading"
26
- aria-live="polite"
27
- role="alert"
28
- :class="ui.base({ class: props.class })"
29
- data-part="base"
30
- >
31
- <slot></slot>
32
- </Primitive>
23
+ <Primitive
24
+ :as="props.as"
25
+ aria-busy="true"
26
+ aria-label="loading"
27
+ aria-live="polite"
28
+ role="alert"
29
+ :class="ui.base({ class: props.class })"
30
+ data-part="base"
31
+ >
32
+ <slot></slot>
33
+ </Primitive>
33
34
  </template>
@@ -8,6 +8,7 @@ import { SliderRange, SliderRoot, SliderThumb, SliderTrack, useForwardPropsEmits
8
8
  import { computed } from "vue";
9
9
  import { useAppConfig } from "#imports";
10
10
  import { useFormField } from "../composables/useFormField";
11
+ import { pick } from "../utils";
11
12
  import { cv, merge } from "../utils/style";
12
13
  import Tooltip from "./Tooltip.vue";
13
14
  const props = defineProps({
@@ -52,7 +53,7 @@ const appConfig = useAppConfig();
52
53
  const ui = computed(() => {
53
54
  const styler = cv(merge(theme, appConfig.ui.slider));
54
55
  return styler({
55
- ...props,
56
+ ...pick(props, ["orientation"]),
56
57
  size: size.value,
57
58
  color: color.value,
58
59
  disabled: disabled.value
@@ -66,29 +67,29 @@ function onChange(value) {
66
67
  </script>
67
68
 
68
69
  <template>
69
- <SliderRoot
70
- v-bind="{ ...rootProps, ...ariaAttrs, id, name, disabled }"
71
- v-model="sliderValue"
72
- :default-value="defaultSliderValue"
73
- :class="ui.root({ class: [props.ui?.root, props.class] })"
74
- :data-steps="thumbs"
75
- data-part="root"
76
- @update:model-value="emitFormInput()"
77
- @value-commit="onChange"
78
- >
79
- <SliderTrack :class="ui.track({ class: props.ui?.track })" data-part="track">
80
- <SliderRange :class="ui.range({ class: props.ui?.range })" data-part="range" />
81
- </SliderTrack>
82
-
83
- <Tooltip
84
- v-for="thumb in thumbs"
85
- :key="thumb"
86
- v-bind="typeof props.tooltip === 'object' ? props.tooltip : {}"
87
- :text="String(thumbs > 1 ? sliderValue?.[thumb - 1] : sliderValue)"
88
- :disabled="!props.tooltip"
89
- disable-closing-trigger
90
- >
91
- <SliderThumb :class="ui.thumb({ class: props.ui?.thumb })" data-part="thumb" :aria-label="thumbs === 1 ? 'Thumb' : `Thumb ${thumb} of ${thumbs}`" />
92
- </Tooltip>
93
- </SliderRoot>
70
+ <SliderRoot
71
+ v-bind="{ ...rootProps, ...ariaAttrs, id, name, disabled }"
72
+ v-model="sliderValue"
73
+ :default-value="defaultSliderValue"
74
+ :class="ui.root({ class: [props.ui?.root, props.class] })"
75
+ :data-steps="thumbs"
76
+ data-part="root"
77
+ @update:model-value="emitFormInput()"
78
+ @value-commit="onChange"
79
+ >
80
+ <SliderTrack :class="ui.track({ class: props.ui?.track })" data-part="track">
81
+ <SliderRange :class="ui.range({ class: props.ui?.range })" data-part="range" />
82
+ </SliderTrack>
83
+
84
+ <Tooltip
85
+ v-for="thumb in thumbs"
86
+ :key="thumb"
87
+ v-bind="typeof props.tooltip === 'object' ? props.tooltip : {}"
88
+ :text="String(thumbs > 1 ? sliderValue?.[thumb - 1] : sliderValue)"
89
+ :disabled="!props.tooltip"
90
+ disable-closing-trigger
91
+ >
92
+ <SliderThumb :class="ui.thumb({ class: props.ui?.thumb })" data-part="thumb" :aria-label="thumbs === 1 ? 'Thumb' : `Thumb ${thumb} of ${thumbs}`" />
93
+ </Tooltip>
94
+ </SliderRoot>
94
95
  </template>