@nuxt/ui 4.11.0 → 4.11.2

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 (101) hide show
  1. package/README.md +3 -3
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +2 -2
  4. package/dist/runtime/components/Accordion.d.vue.ts +1 -1
  5. package/dist/runtime/components/Accordion.vue.d.ts +1 -1
  6. package/dist/runtime/components/Breadcrumb.d.vue.ts +1 -1
  7. package/dist/runtime/components/Breadcrumb.vue.d.ts +1 -1
  8. package/dist/runtime/components/Carousel.d.vue.ts +7 -7
  9. package/dist/runtime/components/Carousel.vue.d.ts +7 -7
  10. package/dist/runtime/components/ChatMessages.d.vue.ts +2 -2
  11. package/dist/runtime/components/ChatMessages.vue.d.ts +2 -2
  12. package/dist/runtime/components/CheckboxGroup.d.vue.ts +1 -1
  13. package/dist/runtime/components/CheckboxGroup.vue.d.ts +1 -1
  14. package/dist/runtime/components/CommandPalette.d.vue.ts +1 -1
  15. package/dist/runtime/components/CommandPalette.vue.d.ts +1 -1
  16. package/dist/runtime/components/ContextMenu.d.vue.ts +1 -1
  17. package/dist/runtime/components/ContextMenu.vue.d.ts +1 -1
  18. package/dist/runtime/components/DashboardNavbar.vue +1 -1
  19. package/dist/runtime/components/DropdownMenu.d.vue.ts +1 -1
  20. package/dist/runtime/components/DropdownMenu.vue.d.ts +1 -1
  21. package/dist/runtime/components/FooterColumns.d.vue.ts +1 -1
  22. package/dist/runtime/components/FooterColumns.vue.d.ts +1 -1
  23. package/dist/runtime/components/Form.vue +2 -2
  24. package/dist/runtime/components/Input.vue +5 -5
  25. package/dist/runtime/components/InputDate.vue +12 -6
  26. package/dist/runtime/components/InputMenu.d.vue.ts +1 -1
  27. package/dist/runtime/components/InputMenu.vue +18 -7
  28. package/dist/runtime/components/InputMenu.vue.d.ts +1 -1
  29. package/dist/runtime/components/InputNumber.vue +8 -5
  30. package/dist/runtime/components/InputTime.vue +12 -6
  31. package/dist/runtime/components/Link.vue +61 -7
  32. package/dist/runtime/components/LinkBase.vue +3 -1
  33. package/dist/runtime/components/Listbox.d.vue.ts +1 -1
  34. package/dist/runtime/components/Listbox.vue.d.ts +1 -1
  35. package/dist/runtime/components/NavigationMenu.d.vue.ts +1 -1
  36. package/dist/runtime/components/NavigationMenu.vue +10 -10
  37. package/dist/runtime/components/NavigationMenu.vue.d.ts +1 -1
  38. package/dist/runtime/components/PageAnchors.d.vue.ts +1 -1
  39. package/dist/runtime/components/PageAnchors.vue.d.ts +1 -1
  40. package/dist/runtime/components/PageLinks.d.vue.ts +1 -1
  41. package/dist/runtime/components/PageLinks.vue.d.ts +1 -1
  42. package/dist/runtime/components/PinInput.d.vue.ts +3 -1
  43. package/dist/runtime/components/PinInput.vue +15 -7
  44. package/dist/runtime/components/PinInput.vue.d.ts +3 -1
  45. package/dist/runtime/components/ProgressGroup.d.vue.ts +1 -1
  46. package/dist/runtime/components/ProgressGroup.vue.d.ts +1 -1
  47. package/dist/runtime/components/RadioGroup.d.vue.ts +1 -1
  48. package/dist/runtime/components/RadioGroup.vue.d.ts +1 -1
  49. package/dist/runtime/components/Select.d.vue.ts +3 -1
  50. package/dist/runtime/components/Select.vue +2 -0
  51. package/dist/runtime/components/Select.vue.d.ts +3 -1
  52. package/dist/runtime/components/SelectMenu.d.vue.ts +4 -1
  53. package/dist/runtime/components/SelectMenu.vue +24 -4
  54. package/dist/runtime/components/SelectMenu.vue.d.ts +4 -1
  55. package/dist/runtime/components/Slider.vue +1 -1
  56. package/dist/runtime/components/Splitter.d.vue.ts +1 -1
  57. package/dist/runtime/components/Splitter.vue.d.ts +1 -1
  58. package/dist/runtime/components/Stepper.d.vue.ts +1 -1
  59. package/dist/runtime/components/Stepper.vue.d.ts +1 -1
  60. package/dist/runtime/components/Table.vue +29 -7
  61. package/dist/runtime/components/Tabs.d.vue.ts +1 -1
  62. package/dist/runtime/components/Tabs.vue.d.ts +1 -1
  63. package/dist/runtime/components/Textarea.vue +5 -5
  64. package/dist/runtime/components/Timeline.d.vue.ts +1 -1
  65. package/dist/runtime/components/Timeline.vue.d.ts +1 -1
  66. package/dist/runtime/components/Toaster.vue +1 -1
  67. package/dist/runtime/components/Tree.d.vue.ts +1 -1
  68. package/dist/runtime/components/Tree.vue +1 -1
  69. package/dist/runtime/components/Tree.vue.d.ts +1 -1
  70. package/dist/runtime/components/color-mode/ColorModeSelect.vue +1 -0
  71. package/dist/runtime/components/content/ContentNavigation.d.vue.ts +1 -1
  72. package/dist/runtime/components/content/ContentNavigation.vue.d.ts +1 -1
  73. package/dist/runtime/components/content/ContentSurround.d.vue.ts +1 -1
  74. package/dist/runtime/components/content/ContentSurround.vue.d.ts +1 -1
  75. package/dist/runtime/components/content/ContentToc.d.vue.ts +1 -1
  76. package/dist/runtime/components/content/ContentToc.vue.d.ts +1 -1
  77. package/dist/runtime/components/locale/LocaleSelect.vue +1 -0
  78. package/dist/runtime/components/prose/CodeTree.vue +31 -18
  79. package/dist/runtime/composables/useForwardProps.js +2 -2
  80. package/dist/runtime/composables/useResizable.js +1 -1
  81. package/dist/runtime/utils/form.d.ts +1 -1
  82. package/dist/runtime/utils/form.js +3 -1
  83. package/dist/runtime/utils/prefetch.d.ts +5 -0
  84. package/dist/runtime/utils/prefetch.js +45 -0
  85. package/dist/runtime/utils/search.js +8 -6
  86. package/dist/runtime/utils/virtualizer.d.ts +1 -1
  87. package/dist/runtime/utils/virtualizer.js +9 -11
  88. package/dist/runtime/vue/components/color-mode/ColorModeSelect.vue +1 -0
  89. package/dist/runtime/vue/overrides/inertia/LinkBase.vue +3 -1
  90. package/dist/shared/{ui.DNq7CNkE.mjs → ui.oNygBd3N.mjs} +40 -12
  91. package/dist/unplugin.d.mts +2 -1
  92. package/dist/unplugin.mjs +22 -10
  93. package/dist/vite.mjs +1 -1
  94. package/package.json +79 -83
  95. package/cli/commands/make/component.mjs +0 -86
  96. package/cli/commands/make/index.mjs +0 -14
  97. package/cli/commands/make/locale.mjs +0 -93
  98. package/cli/index.mjs +0 -15
  99. package/cli/package.json +0 -13
  100. package/cli/templates.mjs +0 -256
  101. package/cli/utils.mjs +0 -50
@@ -35,7 +35,7 @@ defineOptions({ inheritAttrs: false });
35
35
  const props = useComponentProps("slider", _props);
36
36
  const modelValue = defineModel({ type: null });
37
37
  const appConfig = useAppConfig();
38
- const rootProps = useForwardProps(reactivePick(props, "as", "orientation", "min", "max", "step", "minStepsBetweenThumbs", "inverted"), emits);
38
+ const rootProps = useForwardProps(reactivePick(props, "as", "orientation", "min", "max", "step", "minStepsBetweenThumbs", "inverted"));
39
39
  const { id, emitFormChange, emitFormInput, size: formFieldSize, color: formFieldColor, name, disabled: formFieldDisabled, ariaAttrs } = useFormField(_props);
40
40
  const color = computed(() => formFieldColor.value ?? props.color);
41
41
  const size = computed(() => formFieldSize.value ?? props.size);
@@ -12,7 +12,7 @@ export interface SplitterItem extends Omit<SplitterPanelProps, 'as' | 'asChild'>
12
12
  id?: string;
13
13
  slot?: string;
14
14
  class?: any;
15
- ui?: Pick<Splitter['slots'], 'panel'>;
15
+ ui?: Partial<Pick<Splitter['slots'], 'panel'>>;
16
16
  [key: string]: any;
17
17
  }
18
18
  export interface SplitterProps<T extends SplitterItem = SplitterItem> extends Pick<SplitterGroupProps, 'autoSaveId' | 'keyboardResizeBy' | 'storage'>, Pick<SplitterResizeHandleProps, 'hitAreaMargins'> {
@@ -12,7 +12,7 @@ export interface SplitterItem extends Omit<SplitterPanelProps, 'as' | 'asChild'>
12
12
  id?: string;
13
13
  slot?: string;
14
14
  class?: any;
15
- ui?: Pick<Splitter['slots'], 'panel'>;
15
+ ui?: Partial<Pick<Splitter['slots'], 'panel'>>;
16
16
  [key: string]: any;
17
17
  }
18
18
  export interface SplitterProps<T extends SplitterItem = SplitterItem> extends Pick<SplitterGroupProps, 'autoSaveId' | 'keyboardResizeBy' | 'storage'>, Pick<SplitterResizeHandleProps, 'hitAreaMargins'> {
@@ -18,7 +18,7 @@ export interface StepperItem {
18
18
  content?: string;
19
19
  disabled?: boolean;
20
20
  class?: any;
21
- ui?: Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>;
21
+ ui?: Partial<Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>>;
22
22
  [key: string]: any;
23
23
  }
24
24
  export interface StepperProps<T extends StepperItem = StepperItem> extends Pick<StepperRootProps, 'linear'> {
@@ -18,7 +18,7 @@ export interface StepperItem {
18
18
  content?: string;
19
19
  disabled?: boolean;
20
20
  class?: any;
21
- ui?: Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>;
21
+ ui?: Partial<Pick<Stepper['slots'], 'item' | 'container' | 'trigger' | 'indicator' | 'icon' | 'separator' | 'wrapper' | 'title' | 'description'>>;
22
22
  [key: string]: any;
23
23
  }
24
24
  export interface StepperProps<T extends StepperItem = StepperItem> extends Pick<StepperRootProps, 'linear'> {
@@ -259,12 +259,15 @@ function onRowSelect(e, row) {
259
259
  return;
260
260
  }
261
261
  const target = e.target;
262
- const isInteractive = target.closest("button") || target.closest("a");
262
+ const isInteractive = target.closest("a, button, input, label, select, textarea");
263
263
  if (isInteractive) {
264
264
  return;
265
265
  }
266
266
  e.preventDefault();
267
267
  e.stopPropagation();
268
+ if (e.repeat) {
269
+ return;
270
+ }
268
271
  props.onSelect(e, row);
269
272
  }
270
273
  function onRowHover(e, row) {
@@ -299,6 +302,24 @@ function getColumnStyles(column) {
299
302
  }
300
303
  return styles;
301
304
  }
305
+ function isSortable(column) {
306
+ return column.columnDef.enableSorting === true && column.getCanSort();
307
+ }
308
+ function getAriaSort(header) {
309
+ if (header.isPlaceholder || !isSortable(header.column)) {
310
+ return void 0;
311
+ }
312
+ const sorted = header.column.getIsSorted();
313
+ if (!sorted) {
314
+ return "none";
315
+ }
316
+ const sortableIds = new Set(tableApi.getVisibleLeafColumns().filter(isSortable).map((column) => column.id));
317
+ const primary = tableApi.getState().sorting.find(({ id }) => sortableIds.has(id));
318
+ if (primary?.id !== header.column.id) {
319
+ return "none";
320
+ }
321
+ return sorted === "asc" ? "ascending" : "descending";
322
+ }
302
323
  watch(() => props.data, () => {
303
324
  data.value = props.data ? [...props.data] : [];
304
325
  }, props.watchOptions);
@@ -318,7 +339,6 @@ defineExpose({
318
339
  :data-selectable="!!props.onSelect || !!props.onHover || !!props.onContextmenu"
319
340
  :data-expanded="row.getIsExpanded()"
320
341
  :data-pinned="row.getIsPinned() || void 0"
321
- :role="props.onSelect ? 'button' : void 0"
322
342
  :tabindex="props.onSelect ? 0 : void 0"
323
343
  data-slot="tr"
324
344
  :class="ui.tr({
@@ -329,6 +349,7 @@ defineExpose({
329
349
  })"
330
350
  :style="[resolveValue(tableApi.options.meta?.style?.tr, row), style]"
331
351
  @click="onRowSelect($event, row)"
352
+ @keydown.self.exact.enter.space="onRowSelect($event, row)"
332
353
  @pointerenter="onRowHover($event, row)"
333
354
  @pointerleave="onRowHover($event, null)"
334
355
  @contextmenu="onRowContextmenu($event, row)"
@@ -359,7 +380,7 @@ defineExpose({
359
380
  </tr>
360
381
 
361
382
  <tr v-if="row.getIsExpanded()" data-slot="tr" :class="ui.tr({ class: [props.ui?.tr] })">
362
- <td :colspan="row.getAllCells().length" data-slot="td" :class="ui.td({ class: [props.ui?.td] })">
383
+ <td :colspan="row.getVisibleCells().length" data-slot="td" :class="ui.td({ class: [props.ui?.td] })">
363
384
  <slot name="expanded" :row="row" />
364
385
  </td>
365
386
  </tr>
@@ -382,6 +403,7 @@ defineExpose({
382
403
  :scope="header.colSpan > 1 ? 'colgroup' : 'col'"
383
404
  :colspan="header.colSpan > 1 ? header.colSpan : void 0"
384
405
  :rowspan="header.rowSpan > 1 ? header.rowSpan : void 0"
406
+ :aria-sort="getAriaSort(header)"
385
407
  data-slot="th"
386
408
  :class="ui.th({
387
409
  class: [
@@ -412,7 +434,7 @@ defineExpose({
412
434
 
413
435
  <template v-if="virtualizer">
414
436
  <tr v-if="virtualPaddingTop > 0" :style="{ height: `${virtualPaddingTop}px` }" aria-hidden="true">
415
- <td :colspan="tableApi.getAllLeafColumns().length" />
437
+ <td :colspan="tableApi.getVisibleLeafColumns().length" />
416
438
  </tr>
417
439
  <template v-for="virtualRow in virtualItems" :key="centerRows[virtualRow.index]?.id ?? `virtual-${virtualRow.index}`">
418
440
  <ReuseRowTemplate
@@ -422,7 +444,7 @@ defineExpose({
422
444
  />
423
445
  </template>
424
446
  <tr v-if="virtualPaddingBottom > 0" :style="{ height: `${virtualPaddingBottom}px` }" aria-hidden="true">
425
- <td :colspan="tableApi.getAllLeafColumns().length" />
447
+ <td :colspan="tableApi.getVisibleLeafColumns().length" />
426
448
  </tr>
427
449
  </template>
428
450
 
@@ -434,13 +456,13 @@ defineExpose({
434
456
  </template>
435
457
 
436
458
  <tr v-else-if="props.loading && !!slots['loading']">
437
- <td :colspan="tableApi.getAllLeafColumns().length" data-slot="loading" :class="ui.loading({ class: props.ui?.loading })">
459
+ <td :colspan="tableApi.getVisibleLeafColumns().length" data-slot="loading" :class="ui.loading({ class: props.ui?.loading })">
438
460
  <slot name="loading" />
439
461
  </td>
440
462
  </tr>
441
463
 
442
464
  <tr v-else>
443
- <td :colspan="tableApi.getAllLeafColumns().length" data-slot="empty" :class="ui.empty({ class: props.ui?.empty })">
465
+ <td :colspan="tableApi.getVisibleLeafColumns().length" data-slot="empty" :class="ui.empty({ class: props.ui?.empty })">
444
466
  <slot name="empty">
445
467
  {{ props.empty || t("table.noData") }}
446
468
  </slot>
@@ -30,7 +30,7 @@ export interface TabsItem {
30
30
  value?: string | number;
31
31
  disabled?: boolean;
32
32
  class?: any;
33
- ui?: Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>;
33
+ ui?: Partial<Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>>;
34
34
  [key: string]: any;
35
35
  }
36
36
  export interface TabsProps<T extends TabsItem = TabsItem> extends Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
@@ -30,7 +30,7 @@ export interface TabsItem {
30
30
  value?: string | number;
31
31
  disabled?: boolean;
32
32
  class?: any;
33
- ui?: Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>;
33
+ ui?: Partial<Pick<Tabs['slots'], 'trigger' | 'leadingIcon' | 'leadingAvatar' | 'leadingAvatarSize' | 'label' | 'trailingBadge' | 'trailingBadgeSize' | 'content'>>;
34
34
  [key: string]: any;
35
35
  }
36
36
  export interface TabsProps<T extends TabsItem = TabsItem> extends Pick<TabsRootProps<string | number>, 'defaultValue' | 'modelValue' | 'activationMode' | 'unmountOnHide'> {
@@ -10,7 +10,7 @@ import { useAppConfig } from "#imports";
10
10
  import { useComponentProps } from "../composables/useComponentProps";
11
11
  import { useComponentIcons } from "../composables/useComponentIcons";
12
12
  import { useFormField } from "../composables/useFormField";
13
- import { looseToNumber } from "../utils";
13
+ import { isEmpty, looseToNumber } from "../utils";
14
14
  import { tv } from "../utils/tv";
15
15
  import UIcon from "./Icon.vue";
16
16
  import UAvatar from "./Avatar.vue";
@@ -77,11 +77,11 @@ function updateInput(value) {
77
77
  if (props.modelModifiers?.number) {
78
78
  value = looseToNumber(value);
79
79
  }
80
- if (props.modelModifiers?.nullable) {
81
- value ||= null;
80
+ if (props.modelModifiers?.nullable && isEmpty(value)) {
81
+ value = null;
82
82
  }
83
- if (props.modelModifiers?.optional && !props.modelModifiers?.nullable && value !== null) {
84
- value ||= void 0;
83
+ if (props.modelModifiers?.optional && !props.modelModifiers?.nullable && value !== null && isEmpty(value)) {
84
+ value = void 0;
85
85
  }
86
86
  modelValue.value = value;
87
87
  emitFormInput();
@@ -15,7 +15,7 @@ export interface TimelineItem {
15
15
  value?: string | number;
16
16
  slot?: string;
17
17
  class?: any;
18
- ui?: Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>;
18
+ ui?: Partial<Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>>;
19
19
  [key: string]: any;
20
20
  }
21
21
  export interface TimelineProps<T extends TimelineItem = TimelineItem> {
@@ -15,7 +15,7 @@ export interface TimelineItem {
15
15
  value?: string | number;
16
16
  slot?: string;
17
17
  class?: any;
18
- ui?: Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>;
18
+ ui?: Partial<Pick<Timeline['slots'], 'item' | 'container' | 'indicator' | 'separator' | 'wrapper' | 'date' | 'title' | 'description'>>;
19
19
  [key: string]: any;
20
20
  }
21
21
  export interface TimelineProps<T extends TimelineItem = TimelineItem> {
@@ -81,7 +81,7 @@ function getOffset(index) {
81
81
  :key="toast.id"
82
82
  ref="refs"
83
83
  :progress="props.progress"
84
- v-bind="omit(toast, ['id', 'close', '_duplicate', '_updated'])"
84
+ v-bind="omit(toast, ['id', 'close', '_duplicate', '_updated', 'onClick'])"
85
85
  :close="toast.close"
86
86
  :data-expanded="expanded"
87
87
  :data-front="!expanded && index === toasts.length - 1"
@@ -23,7 +23,7 @@ export type TreeItem = {
23
23
  onToggle?: (e: TreeItemToggleEvent<TreeItem>) => void;
24
24
  onSelect?: (e: TreeItemSelectEvent<TreeItem>) => void;
25
25
  class?: any;
26
- ui?: Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>;
26
+ ui?: Partial<Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>>;
27
27
  [key: string]: any;
28
28
  };
29
29
  export interface TreeProps<T extends TreeItem[] = TreeItem[], M extends boolean = false> extends Pick<TreeRootProps<T>, 'expanded' | 'defaultExpanded' | 'selectionBehavior' | 'propagateSelect' | 'disabled' | 'bubbleSelect'> {
@@ -66,7 +66,7 @@ const flattenedPaddingFormula = computed(() => {
66
66
  xl: { base: 3, perLevel: 7.5 }
67
67
  // px-3, ms-6 + ps-1.5
68
68
  };
69
- const config = sizeConfig[props.size || "md"];
69
+ const config = sizeConfig[props.size] ?? sizeConfig.md;
70
70
  return (level) => `calc(var(--spacing) * ${(level - 1) * config.perLevel + config.base})`;
71
71
  });
72
72
  const virtualizerProps = toRef(() => {
@@ -23,7 +23,7 @@ export type TreeItem = {
23
23
  onToggle?: (e: TreeItemToggleEvent<TreeItem>) => void;
24
24
  onSelect?: (e: TreeItemSelectEvent<TreeItem>) => void;
25
25
  class?: any;
26
- ui?: Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>;
26
+ ui?: Partial<Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>>;
27
27
  [key: string]: any;
28
28
  };
29
29
  export interface TreeProps<T extends TreeItem[] = TreeItem[], M extends boolean = false> extends Pick<TreeRootProps<T>, 'expanded' | 'defaultExpanded' | 'selectionBehavior' | 'propagateSelect' | 'disabled' | 'bubbleSelect'> {
@@ -32,6 +32,7 @@ const props = defineProps({
32
32
  modelModifiers: { type: null, required: false },
33
33
  multiple: { type: Boolean, required: false },
34
34
  highlight: { type: Boolean, required: false },
35
+ fixed: { type: Boolean, required: false },
35
36
  createItem: { type: [Boolean, String, Object], required: false },
36
37
  filterFields: { type: Array, required: false },
37
38
  ignoreFilter: { type: Boolean, required: false },
@@ -28,7 +28,7 @@ export interface ContentNavigationLink extends ContentNavigationItem {
28
28
  defaultOpen?: boolean;
29
29
  active?: boolean;
30
30
  class?: any;
31
- ui?: Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>;
31
+ ui?: Partial<Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>>;
32
32
  }
33
33
  export interface ContentNavigationProps<T extends ContentNavigationLink = ContentNavigationLink> extends Pick<AccordionRootProps, 'disabled' | 'type' | 'unmountOnHide'> {
34
34
  /**
@@ -28,7 +28,7 @@ export interface ContentNavigationLink extends ContentNavigationItem {
28
28
  defaultOpen?: boolean;
29
29
  active?: boolean;
30
30
  class?: any;
31
- ui?: Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>;
31
+ ui?: Partial<Pick<ContentNavigation['slots'], 'link' | 'linkLeadingIcon' | 'linkTitle' | 'linkTrailing' | 'linkTrailingIcon' | 'linkTrailingBadge' | 'linkTrailingBadgeSize' | 'linkTrailingIcon' | 'linkTitleExternalIcon' | 'trigger' | 'content' | 'item' | 'itemWithChildren'>>;
32
32
  }
33
33
  export interface ContentNavigationProps<T extends ContentNavigationLink = ContentNavigationLink> extends Pick<AccordionRootProps, 'disabled' | 'type' | 'unmountOnHide'> {
34
34
  /**
@@ -12,7 +12,7 @@ export interface ContentSurroundLink extends ContentNavigationItem {
12
12
  */
13
13
  icon?: IconProps['name'];
14
14
  class?: any;
15
- ui?: Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>;
15
+ ui?: Partial<Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>>;
16
16
  }
17
17
  export interface ContentSurroundProps<T extends ContentSurroundLink = ContentSurroundLink> {
18
18
  /**
@@ -12,7 +12,7 @@ export interface ContentSurroundLink extends ContentNavigationItem {
12
12
  */
13
13
  icon?: IconProps['name'];
14
14
  class?: any;
15
- ui?: Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>;
15
+ ui?: Partial<Pick<ContentSurround['slots'], 'link' | 'linkLeading' | 'linkLeadingIcon' | 'linkTitle' | 'linkDescription'>>;
16
16
  }
17
17
  export interface ContentSurroundProps<T extends ContentSurroundLink = ContentSurroundLink> {
18
18
  /**
@@ -8,7 +8,7 @@ import type { ComponentConfig } from '../../types/tv';
8
8
  type ContentToc = ComponentConfig<typeof theme, AppConfig, 'contentToc'>;
9
9
  export type ContentTocLink = TocLink & {
10
10
  class?: any;
11
- ui?: Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>;
11
+ ui?: Partial<Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>>;
12
12
  };
13
13
  export interface ContentTocProps<T extends ContentTocLink = ContentTocLink> extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open'> {
14
14
  /**
@@ -8,7 +8,7 @@ import type { ComponentConfig } from '../../types/tv';
8
8
  type ContentToc = ComponentConfig<typeof theme, AppConfig, 'contentToc'>;
9
9
  export type ContentTocLink = TocLink & {
10
10
  class?: any;
11
- ui?: Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>;
11
+ ui?: Partial<Pick<ContentToc['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkText'>>;
12
12
  };
13
13
  export interface ContentTocProps<T extends ContentTocLink = ContentTocLink> extends Pick<CollapsibleRootProps, 'defaultOpen' | 'open'> {
14
14
  /**
@@ -31,6 +31,7 @@ const props = defineProps({
31
31
  modelModifiers: { type: null, required: false },
32
32
  multiple: { type: Boolean, required: false },
33
33
  highlight: { type: Boolean, required: false },
34
+ fixed: { type: Boolean, required: false },
34
35
  createItem: { type: [Boolean, String, Object], required: false },
35
36
  filterFields: { type: Array, required: false },
36
37
  ignoreFilter: { type: Boolean, required: false },
@@ -3,7 +3,7 @@ import theme from "#build/ui/prose/code-tree";
3
3
  </script>
4
4
 
5
5
  <script setup>
6
- import { computed, watch, onBeforeUpdate, ref } from "vue";
6
+ import { computed, watch, onBeforeUpdate, onMounted, ref } from "vue";
7
7
  import { TreeRoot, TreeItem } from "reka-ui";
8
8
  import { createReusableTemplate } from "@vueuse/core";
9
9
  import { useAppConfig } from "#imports";
@@ -28,7 +28,6 @@ const [DefineTreeTemplate, ReuseTreeTemplate] = createReusableTemplate();
28
28
  const ui = computed(() => tv({ extend: theme, ...appConfig.ui?.prose?.codeTree || {} })());
29
29
  const initialPath = props.modelValue ?? props.defaultValue;
30
30
  const model = ref(initialPath ? { path: initialPath } : void 0);
31
- const lastSelectedItem = ref();
32
31
  watch(model, (value) => {
33
32
  if (value?.path !== props.modelValue) {
34
33
  emits("update:modelValue", value?.path);
@@ -37,12 +36,13 @@ watch(model, (value) => {
37
36
  watch(() => props.modelValue, (value) => {
38
37
  if (value === model.value?.path) return;
39
38
  model.value = value ? { path: value } : void 0;
40
- const pathsToExpand = getExpandedPaths(value);
41
- for (const path of pathsToExpand) {
42
- if (!expanded.value.includes(path)) {
43
- expanded.value.push(path);
39
+ const next = [...expanded.value];
40
+ for (const path of getExpandedPaths(value)) {
41
+ if (!next.includes(path)) {
42
+ next.push(path);
44
43
  }
45
44
  }
45
+ expanded.value = next;
46
46
  });
47
47
  const rerenderCount = ref(1);
48
48
  const flatItems = computed(() => {
@@ -101,21 +101,34 @@ function getExpandedPaths(path) {
101
101
  const parts = path.split("/");
102
102
  return parts.slice(0, -1).map((_, index) => parts.slice(0, index + 1).join("/"));
103
103
  }
104
- const expanded = ref(getExpandedPaths(model.value?.path));
105
- watch(flatItems, (newItems, oldItems) => {
106
- if (!props.expandAll) return;
107
- const newLabels = newItems.map((i) => i.label).join("\n");
108
- const oldLabels = oldItems?.map((i) => i.label).join("\n") ?? "";
109
- if (newLabels !== oldLabels) {
110
- expanded.value = getExpandedPaths();
104
+ const expandedOverride = ref(props.expandAll ? null : getExpandedPaths(model.value?.path));
105
+ const expanded = computed({
106
+ get: () => expandedOverride.value ?? getExpandedPaths(),
107
+ set: (value) => {
108
+ expandedOverride.value = value;
111
109
  }
112
110
  });
113
- watch(model, (value) => {
114
- const item = flatItems.value.find((item2) => value?.path === item2.label);
111
+ watch(() => props.expandAll, (value) => {
112
+ expandedOverride.value = value ? null : getExpandedPaths(model.value?.path);
113
+ });
114
+ onMounted(() => {
115
+ watch(flatItems, (newItems, oldItems) => {
116
+ if (!props.expandAll) return;
117
+ const newLabels = newItems.map((i) => i.label).join("\n");
118
+ const oldLabels = oldItems?.map((i) => i.label).join("\n") ?? "";
119
+ if (newLabels !== oldLabels) {
120
+ expandedOverride.value = null;
121
+ }
122
+ });
123
+ });
124
+ let lastFile;
125
+ const currentFile = computed(() => {
126
+ const item = flatItems.value.find((item2) => model.value?.path === item2.label);
115
127
  if (item?.component) {
116
- lastSelectedItem.value = item;
128
+ lastFile = item;
117
129
  }
118
- }, { immediate: true });
130
+ return lastFile;
131
+ });
119
132
  onBeforeUpdate(() => rerenderCount.value++);
120
133
  </script>
121
134
 
@@ -183,7 +196,7 @@ onBeforeUpdate(() => rerenderCount.value++);
183
196
  </TreeRoot>
184
197
 
185
198
  <div :class="ui.content({ class: props.ui?.content })">
186
- <component :is="lastSelectedItem?.component" />
199
+ <component :is="currentFile?.component" />
187
200
  </div>
188
201
  </div>
189
202
  </template>
@@ -1,9 +1,9 @@
1
- import { computed, isRef } from "vue";
1
+ import { computed, unref } from "vue";
2
2
  import { useEmitAsProps } from "reka-ui";
3
3
  export function useForwardProps(source, emits) {
4
4
  const emitAsProps = emits ? useEmitAsProps(emits) : {};
5
5
  return computed(() => {
6
- const src = isRef(source) ? source.value : source;
6
+ const src = unref(source);
7
7
  const out = { ...emitAsProps };
8
8
  for (const key in src) {
9
9
  const value = src[key];
@@ -15,7 +15,7 @@ export function useResizable(key, options = {}, { collapsed = ref(false) } = {})
15
15
  collapsedSize: 0,
16
16
  resizable: true,
17
17
  unit: "%",
18
- ...isRef(options) ? options.value : options
18
+ ...unref(options)
19
19
  }));
20
20
  const { dir } = useLocale();
21
21
  const defaultStorageValue = {
@@ -4,6 +4,6 @@ import type { FormSchema, ValidateReturnSchema } from '../types/form';
4
4
  export declare function isSuperStructSchema(schema: any): schema is Struct<any, any>;
5
5
  export declare function isStandardSchema(schema: any): schema is StandardSchemaV1;
6
6
  export declare function validateStandardSchema(state: any, schema: StandardSchemaV1): Promise<ValidateReturnSchema<typeof state>>;
7
- export declare function validateSchema<T extends object>(state: T, schema: FormSchema<T>): Promise<ValidateReturnSchema<typeof state>>;
7
+ export declare function validateSchema<T extends object>(state: T, _schema: FormSchema<T>): Promise<ValidateReturnSchema<typeof state>>;
8
8
  export declare function getAtPath<T extends object>(data: T, path?: string): any;
9
9
  export declare function setAtPath<T extends object>(data: T, path: string, value: any): T;
@@ -1,3 +1,4 @@
1
+ import { toRaw } from "vue";
1
2
  export function isSuperStructSchema(schema) {
2
3
  return "schema" in schema && typeof schema.coercer === "function" && typeof schema.validator === "function" && typeof schema.refiner === "function";
3
4
  }
@@ -37,7 +38,8 @@ async function validateSuperstructSchema(state, schema) {
37
38
  result
38
39
  };
39
40
  }
40
- export function validateSchema(state, schema) {
41
+ export function validateSchema(state, _schema) {
42
+ const schema = toRaw(_schema);
41
43
  if (isStandardSchema(schema)) {
42
44
  return validateStandardSchema(state, schema);
43
45
  } else if (isSuperStructSchema(schema)) {
@@ -0,0 +1,5 @@
1
+ type IdleCallbackHandle = ReturnType<typeof setTimeout> | number;
2
+ export declare function requestIdleCallback(callback: () => void): IdleCallbackHandle | undefined;
3
+ export declare function cancelIdleCallback(handle: IdleCallbackHandle | undefined): void;
4
+ export declare function observeIntersection(element: Element, callback: () => void): () => void;
5
+ export {};
@@ -0,0 +1,45 @@
1
+ export function requestIdleCallback(callback) {
2
+ if (typeof window === "undefined") {
3
+ return;
4
+ }
5
+ if (typeof window.requestIdleCallback === "function") {
6
+ return window.requestIdleCallback(callback);
7
+ }
8
+ return setTimeout(callback, 1);
9
+ }
10
+ export function cancelIdleCallback(handle) {
11
+ if (typeof window === "undefined" || handle === void 0) {
12
+ return;
13
+ }
14
+ if (typeof window.cancelIdleCallback === "function") {
15
+ window.cancelIdleCallback(handle);
16
+ return;
17
+ }
18
+ clearTimeout(handle);
19
+ }
20
+ let observer = null;
21
+ const callbacks = /* @__PURE__ */ new Map();
22
+ export function observeIntersection(element, callback) {
23
+ if (typeof IntersectionObserver === "undefined") {
24
+ return () => {
25
+ };
26
+ }
27
+ observer ||= new IntersectionObserver((entries) => {
28
+ for (const entry of entries) {
29
+ const callback2 = callbacks.get(entry.target);
30
+ if ((entry.isIntersecting || entry.intersectionRatio > 0) && callback2) {
31
+ callback2();
32
+ }
33
+ }
34
+ });
35
+ callbacks.set(element, callback);
36
+ observer.observe(element);
37
+ return () => {
38
+ callbacks.delete(element);
39
+ observer?.unobserve(element);
40
+ if (callbacks.size === 0) {
41
+ observer?.disconnect();
42
+ observer = null;
43
+ }
44
+ };
45
+ }
@@ -12,19 +12,21 @@ function truncateHTMLFromStart(html, maxLength) {
12
12
  let truncated = "";
13
13
  let totalLength = 0;
14
14
  let insideTag = false;
15
- for (let i = html.length - 1; i >= 0; i--) {
16
- if (html[i] === ">") {
15
+ const chars = Array.from(html);
16
+ for (let i = chars.length - 1; i >= 0; i--) {
17
+ const char = chars[i];
18
+ if (char === ">") {
17
19
  insideTag = true;
18
- } else if (html[i] === "<") {
20
+ } else if (char === "<") {
19
21
  insideTag = false;
20
- truncated = html[i] + truncated;
22
+ truncated = char + truncated;
21
23
  continue;
22
24
  }
23
25
  if (!insideTag) {
24
26
  totalLength++;
25
27
  }
26
28
  if (totalLength <= maxLength) {
27
- truncated = html[i] + truncated;
29
+ truncated = char + truncated;
28
30
  } else {
29
31
  truncated = "..." + truncated;
30
32
  break;
@@ -63,7 +65,7 @@ export function highlight(item, searchTerm, forceKey, omitKeys, useTokenSearch)
63
65
  content += escapeHTML(value.substring(nextUnhighlightedRegionStartingIndex));
64
66
  const markIndex = content.indexOf("<mark>");
65
67
  if (markIndex !== -1) {
66
- content = truncateHTMLFromStart(content, content.length - markIndex);
68
+ content = truncateHTMLFromStart(content, Array.from(content.slice(markIndex)).length);
67
69
  }
68
70
  return content;
69
71
  }
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Get estimate size for virtualizers that checks each item individually
3
3
  */
4
- export declare function getEstimateSize(items: any[], size: 'xs' | 'sm' | 'md' | 'lg' | 'xl', descriptionKey?: string, hasDescriptionSlot?: boolean): (index: number) => number;
4
+ export declare function getEstimateSize(items: any[], size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | (string & {}), descriptionKey?: string, hasDescriptionSlot?: boolean): (index: number) => number;
@@ -7,22 +7,20 @@ function itemHasDescription(item, descriptionKey) {
7
7
  return value !== void 0 && value !== null && value !== "";
8
8
  }
9
9
  function getSize(size, hasDescription) {
10
- if (hasDescription) {
11
- return {
12
- xs: 44,
13
- sm: 48,
14
- md: 52,
15
- lg: 56,
16
- xl: 60
17
- }[size];
18
- }
19
- return {
10
+ const sizes = hasDescription ? {
11
+ xs: 44,
12
+ sm: 48,
13
+ md: 52,
14
+ lg: 56,
15
+ xl: 60
16
+ } : {
20
17
  xs: 24,
21
18
  sm: 28,
22
19
  md: 32,
23
20
  lg: 36,
24
21
  xl: 40
25
- }[size];
22
+ };
23
+ return sizes[size] ?? sizes.md;
26
24
  }
27
25
  export function getEstimateSize(items, size, descriptionKey, hasDescriptionSlot) {
28
26
  const sizeWithDescription = getSize(size, true);
@@ -32,6 +32,7 @@ const props = defineProps({
32
32
  modelModifiers: { type: null, required: false },
33
33
  multiple: { type: Boolean, required: false },
34
34
  highlight: { type: Boolean, required: false },
35
+ fixed: { type: Boolean, required: false },
35
36
  createItem: { type: [Boolean, String, Object], required: false },
36
37
  filterFields: { type: Array, required: false },
37
38
  ignoreFilter: { type: Boolean, required: false },