@sewadah/selaras 0.3.0 → 0.3.1

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 (141) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +14 -1
  3. package/dist/runtime/components/Autocomplete.vue +3 -1
  4. package/dist/runtime/components/Calendar.d.vue.ts +69 -0
  5. package/dist/runtime/components/Calendar.vue +163 -0
  6. package/dist/runtime/components/Calendar.vue.d.ts +69 -0
  7. package/dist/runtime/components/Callout.vue +12 -1
  8. package/dist/runtime/components/CodeGroup.vue +13 -3
  9. package/dist/runtime/components/CodeTree.d.vue.ts +2 -0
  10. package/dist/runtime/components/CodeTree.vue +52 -1
  11. package/dist/runtime/components/CodeTree.vue.d.ts +2 -0
  12. package/dist/runtime/components/ColorPicker.d.vue.ts +8 -0
  13. package/dist/runtime/components/ColorPicker.vue +66 -45
  14. package/dist/runtime/components/ColorPicker.vue.d.ts +8 -0
  15. package/dist/runtime/components/Column.js +1 -1
  16. package/dist/runtime/components/CommandPalette.d.vue.ts +3 -1
  17. package/dist/runtime/components/CommandPalette.vue +5 -0
  18. package/dist/runtime/components/CommandPalette.vue.d.ts +3 -1
  19. package/dist/runtime/components/ContentNavigation.d.vue.ts +8 -1
  20. package/dist/runtime/components/ContentNavigation.vue +9 -2
  21. package/dist/runtime/components/ContentNavigation.vue.d.ts +8 -1
  22. package/dist/runtime/components/ContextMenu.d.vue.ts +8 -1
  23. package/dist/runtime/components/ContextMenu.vue +16 -4
  24. package/dist/runtime/components/ContextMenu.vue.d.ts +8 -1
  25. package/dist/runtime/components/DatePicker.d.vue.ts +10 -3
  26. package/dist/runtime/components/DatePicker.vue +24 -16
  27. package/dist/runtime/components/DatePicker.vue.d.ts +10 -3
  28. package/dist/runtime/components/Dropdown.d.vue.ts +33 -6
  29. package/dist/runtime/components/Dropdown.vue +143 -11
  30. package/dist/runtime/components/Dropdown.vue.d.ts +33 -6
  31. package/dist/runtime/components/FileTree.d.vue.ts +2 -0
  32. package/dist/runtime/components/FileTree.vue +8 -4
  33. package/dist/runtime/components/FileTree.vue.d.ts +2 -0
  34. package/dist/runtime/components/FormField.d.vue.ts +4 -0
  35. package/dist/runtime/components/FormField.vue +19 -4
  36. package/dist/runtime/components/FormField.vue.d.ts +4 -0
  37. package/dist/runtime/components/Input.vue +3 -2
  38. package/dist/runtime/components/Kbd.vue +12 -2
  39. package/dist/runtime/components/NavigationMenu.d.vue.ts +10 -10
  40. package/dist/runtime/components/NavigationMenu.vue +13 -9
  41. package/dist/runtime/components/NavigationMenu.vue.d.ts +10 -10
  42. package/dist/runtime/components/NavigationMenuAccordionItem.vue +5 -1
  43. package/dist/runtime/components/NavigationMenuFlyoutList.vue +7 -4
  44. package/dist/runtime/components/Popover.d.vue.ts +8 -2
  45. package/dist/runtime/components/Popover.vue +9 -4
  46. package/dist/runtime/components/Popover.vue.d.ts +8 -2
  47. package/dist/runtime/components/ProsePre.d.vue.ts +2 -0
  48. package/dist/runtime/components/ProsePre.vue +2 -1
  49. package/dist/runtime/components/ProsePre.vue.d.ts +2 -0
  50. package/dist/runtime/components/Select.vue +3 -1
  51. package/dist/runtime/components/SplitterPanel.d.vue.ts +2 -2
  52. package/dist/runtime/components/SplitterPanel.vue.d.ts +2 -2
  53. package/dist/runtime/components/Table.vue +95 -26
  54. package/dist/runtime/components/Tabs.d.vue.ts +44 -4
  55. package/dist/runtime/components/Tabs.vue +171 -18
  56. package/dist/runtime/components/Tabs.vue.d.ts +44 -4
  57. package/dist/runtime/components/Textarea.vue +3 -2
  58. package/dist/runtime/components/Timeline.d.vue.ts +19 -0
  59. package/dist/runtime/components/Timeline.vue +99 -0
  60. package/dist/runtime/components/Timeline.vue.d.ts +19 -0
  61. package/dist/runtime/components/Toast.d.vue.ts +10 -1
  62. package/dist/runtime/components/Toast.vue +94 -8
  63. package/dist/runtime/components/Toast.vue.d.ts +10 -1
  64. package/dist/runtime/components/Tooltip.d.vue.ts +8 -2
  65. package/dist/runtime/components/Tooltip.vue +9 -4
  66. package/dist/runtime/components/Tooltip.vue.d.ts +8 -2
  67. package/dist/runtime/composables/use-form-field.d.ts +1 -0
  68. package/dist/runtime/composables/use-table.d.ts +3 -0
  69. package/dist/runtime/composables/use-table.js +10 -4
  70. package/dist/runtime/composables/use-toast.js +5 -1
  71. package/dist/runtime/directives/hotkey.d.ts +13 -0
  72. package/dist/runtime/directives/hotkey.js +107 -0
  73. package/dist/runtime/directives/index.d.ts +2 -0
  74. package/dist/runtime/directives/index.js +2 -0
  75. package/dist/runtime/directives/mask.d.ts +30 -0
  76. package/dist/runtime/directives/mask.js +165 -0
  77. package/dist/runtime/internal/ComboboxSelectBase.d.vue.ts +29 -25
  78. package/dist/runtime/internal/ComboboxSelectBase.vue +103 -19
  79. package/dist/runtime/internal/ComboboxSelectBase.vue.d.ts +29 -25
  80. package/dist/runtime/internal/ComboboxSelectBody.d.vue.ts +16 -11
  81. package/dist/runtime/internal/ComboboxSelectBody.vue +49 -10
  82. package/dist/runtime/internal/ComboboxSelectBody.vue.d.ts +16 -11
  83. package/dist/runtime/internal/DatePickerCalendarBody.vue +1 -1
  84. package/dist/runtime/internal/DatePickerRangeCalendarBody.vue +1 -1
  85. package/dist/runtime/internal/ShortcutHint.d.vue.ts +6 -0
  86. package/dist/runtime/internal/ShortcutHint.vue +13 -0
  87. package/dist/runtime/internal/ShortcutHint.vue.d.ts +6 -0
  88. package/dist/runtime/internal/ToastItemRenderer.d.vue.ts +9 -1
  89. package/dist/runtime/internal/ToastItemRenderer.vue +55 -8
  90. package/dist/runtime/internal/ToastItemRenderer.vue.d.ts +9 -1
  91. package/dist/runtime/internal/combobox-select.js +2 -1
  92. package/dist/runtime/internal/programmatic-services.d.ts +2 -0
  93. package/dist/runtime/internal/programmatic-services.js +8 -0
  94. package/dist/runtime/internal/toast-stack.d.ts +36 -0
  95. package/dist/runtime/internal/toast-stack.js +36 -0
  96. package/dist/runtime/structural.css +1 -1
  97. package/dist/runtime/table.d.ts +1 -1
  98. package/dist/runtime/theme/alert-dialog.js +1 -1
  99. package/dist/runtime/theme/calendar.d.ts +86 -0
  100. package/dist/runtime/theme/calendar.js +19 -0
  101. package/dist/runtime/theme/callout.d.ts +0 -12
  102. package/dist/runtime/theme/callout.js +8 -8
  103. package/dist/runtime/theme/code-tree.js +1 -1
  104. package/dist/runtime/theme/command-palette.js +1 -1
  105. package/dist/runtime/theme/content-navigation.d.ts +3 -0
  106. package/dist/runtime/theme/content-navigation.js +1 -0
  107. package/dist/runtime/theme/drawer.js +1 -1
  108. package/dist/runtime/theme/dropdown.d.ts +21 -0
  109. package/dist/runtime/theme/dropdown.js +15 -2
  110. package/dist/runtime/theme/file-tree.js +1 -1
  111. package/dist/runtime/theme/form-field.d.ts +18 -0
  112. package/dist/runtime/theme/form-field.js +6 -1
  113. package/dist/runtime/theme/modal.js +1 -1
  114. package/dist/runtime/theme/slideover.js +1 -1
  115. package/dist/runtime/theme/table.d.ts +27 -0
  116. package/dist/runtime/theme/table.js +11 -2
  117. package/dist/runtime/theme/tabs.d.ts +87 -3
  118. package/dist/runtime/theme/tabs.js +46 -22
  119. package/dist/runtime/theme/timeline.d.ts +251 -0
  120. package/dist/runtime/theme/timeline.js +84 -0
  121. package/dist/runtime/theme/toast.d.ts +92 -0
  122. package/dist/runtime/theme/toast.js +29 -7
  123. package/dist/runtime/theme-config.d.ts +12 -1
  124. package/dist/runtime/types/index.d.ts +6 -1
  125. package/dist/runtime/utils/arrow.d.ts +21 -0
  126. package/dist/runtime/utils/arrow.js +10 -0
  127. package/dist/runtime/utils/file-icons.js +2 -0
  128. package/dist/runtime/utils/icons.d.ts +2 -0
  129. package/dist/runtime/utils/icons.js +2 -0
  130. package/dist/runtime/utils/messages.d.ts +6 -0
  131. package/dist/runtime/utils/messages.js +6 -0
  132. package/dist/runtime/utils/navigation-menu.d.ts +7 -0
  133. package/dist/runtime/utils/navigation-menu.js +3 -0
  134. package/dist/runtime/utils/overlay.d.ts +17 -0
  135. package/dist/runtime/utils/overlay.js +7 -0
  136. package/dist/runtime/utils/select-contracts.d.ts +7 -1
  137. package/dist/runtime/utils/table-columns.js +1 -1
  138. package/dist/runtime/utils/table-contracts.d.ts +9 -1
  139. package/dist/runtime/utils/timeline-contracts.d.ts +42 -0
  140. package/dist/runtime/utils/timeline-contracts.js +0 -0
  141. package/package.json +2 -1
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "selaras",
3
3
  "configKey": "selaras",
4
- "version": "0.3.0",
4
+ "version": "0.3.1",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.3",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -41,7 +41,10 @@ function createBuiltinColorRegistry(classPrefix) {
41
41
  fill,
42
42
  fillHover: hover,
43
43
  fillPressed: pressed,
44
- onFill: foundation("neutral", brightIntent ? 950 : dark ? 950 : 25),
44
+ // The vivid light-mode intent fills intentionally use white text.
45
+ // Dark mode restores the shared dark foreground on its lighter fills.
46
+ // Consumers can override onFill in their own recipe.
47
+ onFill: brightIntent && !dark ? "#ffffff" : foundation("neutral", dark ? 950 : 25),
45
48
  indicator,
46
49
  subtle,
47
50
  subtleHover: brightIntent ? `color-mix(in oklab, ${subtle} 96%, ${text})` : dark ? `color-mix(in oklab, ${foundation(role, 500)} 32%, var(--selaras-resolved-surface-default))` : `color-mix(in oklab, ${subtle} 94%, ${text})`,
@@ -135,6 +138,16 @@ const module$1 = defineNuxtModule({
135
138
  from: resolver.resolve("./runtime/directives/ripple"),
136
139
  meta: { vueDirective: true }
137
140
  });
141
+ addImports({
142
+ name: "vMask",
143
+ from: resolver.resolve("./runtime/directives/mask"),
144
+ meta: { vueDirective: true }
145
+ });
146
+ addImports({
147
+ name: "vHotkey",
148
+ from: resolver.resolve("./runtime/directives/hotkey"),
149
+ meta: { vueDirective: true }
150
+ });
138
151
  addTemplate({
139
152
  filename: "selaras-class-prefix.mjs",
140
153
  getContents: () => `export const classPrefix = ${JSON.stringify(options.classPrefix ?? null)}
@@ -30,7 +30,9 @@ const props = defineProps({
30
30
  searchTerm: { type: String, required: false },
31
31
  resetSearchTermOnBlur: { type: Boolean, required: false },
32
32
  resetSearchTermOnSelect: { type: Boolean, required: false },
33
- arrow: { type: Boolean, required: false },
33
+ arrow: { type: [Boolean, Object], required: false },
34
+ positioning: { type: Object, required: false },
35
+ portal: { type: [Boolean, String], required: false, skipCheck: true, default: void 0 },
34
36
  adaptive: { type: Boolean, required: false },
35
37
  ui: { type: Object, required: false }
36
38
  });
@@ -0,0 +1,69 @@
1
+ import type { DateValue } from '@internationalized/date';
2
+ import type { CalendarThemeSlots } from '../theme/calendar.js';
3
+ import type { ColorRole } from '../utils/color-registry.js';
4
+ import type { UiProp } from '../utils/ui.js';
5
+ type __VLS_Slots = {
6
+ 'day'?: (props: CalendarDaySlotProps) => any;
7
+ /** Renders beside the date trigger within its grid cell. Safe for event links/buttons. */
8
+ 'day-details'?: (props: {
9
+ date: DateValue;
10
+ month: DateValue;
11
+ }) => any;
12
+ 'footer'?: () => any;
13
+ };
14
+ export interface CalendarProps {
15
+ modelValue?: DateValue;
16
+ defaultValue?: DateValue;
17
+ /** The displayed month when controlled independently of the selected date. */
18
+ placeholder?: DateValue;
19
+ defaultPlaceholder?: DateValue;
20
+ minValue?: DateValue;
21
+ maxValue?: DateValue;
22
+ isDateDisabled?: (date: DateValue) => boolean;
23
+ isDateUnavailable?: (date: DateValue) => boolean;
24
+ locale?: string;
25
+ numberOfMonths?: number;
26
+ pagedNavigation?: boolean;
27
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
28
+ weekdayFormat?: 'narrow' | 'short' | 'long';
29
+ fixedWeeks?: boolean;
30
+ disableDaysOutsideCurrentView?: boolean;
31
+ preventDeselect?: boolean;
32
+ disabled?: boolean;
33
+ readonly?: boolean;
34
+ initialFocus?: boolean;
35
+ calendarLabel?: string;
36
+ color?: ColorRole;
37
+ activeColor?: ColorRole;
38
+ ui?: UiProp<CalendarThemeSlots>;
39
+ }
40
+ export interface CalendarEmits {
41
+ 'update:modelValue': [value: DateValue | undefined];
42
+ 'update:placeholder': [value: DateValue];
43
+ }
44
+ export interface CalendarDaySlotProps {
45
+ date: DateValue;
46
+ month: DateValue;
47
+ dayValue: string;
48
+ selected: boolean;
49
+ today: boolean;
50
+ disabled: boolean;
51
+ unavailable: boolean;
52
+ outsideView: boolean;
53
+ outsideVisibleView: boolean;
54
+ }
55
+ declare const __VLS_base: import("vue").DefineComponent<CalendarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
56
+ "update:modelValue": (value: DateValue | undefined) => any;
57
+ "update:placeholder": (value: DateValue) => any;
58
+ }, string, import("vue").PublicProps, Readonly<CalendarProps> & Readonly<{
59
+ "onUpdate:modelValue"?: ((value: DateValue | undefined) => any) | undefined;
60
+ "onUpdate:placeholder"?: ((value: DateValue) => any) | undefined;
61
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
62
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
63
+ declare const _default: typeof __VLS_export;
64
+ export default _default;
65
+ type __VLS_WithSlots<T, S> = T & {
66
+ new (): {
67
+ $slots: S;
68
+ };
69
+ };
@@ -0,0 +1,163 @@
1
+ <script setup>
2
+ import {
3
+ CalendarCell,
4
+ CalendarCellTrigger,
5
+ CalendarGrid,
6
+ CalendarGridBody,
7
+ CalendarGridHead,
8
+ CalendarGridRow,
9
+ CalendarHeadCell,
10
+ CalendarHeader,
11
+ CalendarHeading,
12
+ CalendarNext,
13
+ CalendarPrev,
14
+ CalendarRoot
15
+ } from "reka-ui";
16
+ import { computed, getCurrentInstance, useId, useSlots } from "vue";
17
+ import { useIcons } from "../composables/use-icons";
18
+ import { useMessages } from "../composables/use-messages";
19
+ import { calendarTheme } from "../theme/calendar";
20
+ import { resolveRegisteredColorRole } from "../utils/registered-colors";
21
+ import { resolveSlot, useComponentTheme, useRootProps } from "../utils/ui";
22
+ import Button from "./Button.vue";
23
+ defineOptions({ inheritAttrs: false });
24
+ const props = defineProps({
25
+ modelValue: { type: Object, required: false },
26
+ defaultValue: { type: Object, required: false },
27
+ placeholder: { type: Object, required: false },
28
+ defaultPlaceholder: { type: Object, required: false },
29
+ minValue: { type: Object, required: false },
30
+ maxValue: { type: Object, required: false },
31
+ isDateDisabled: { type: Function, required: false },
32
+ isDateUnavailable: { type: Function, required: false },
33
+ locale: { type: String, required: false },
34
+ numberOfMonths: { type: Number, required: false },
35
+ pagedNavigation: { type: Boolean, required: false },
36
+ weekStartsOn: { type: Number, required: false },
37
+ weekdayFormat: { type: String, required: false },
38
+ fixedWeeks: { type: Boolean, required: false },
39
+ disableDaysOutsideCurrentView: { type: Boolean, required: false },
40
+ preventDeselect: { type: Boolean, required: false },
41
+ disabled: { type: Boolean, required: false },
42
+ readonly: { type: Boolean, required: false },
43
+ initialFocus: { type: Boolean, required: false },
44
+ calendarLabel: { type: String, required: false },
45
+ color: { type: null, required: false, default: "neutral" },
46
+ activeColor: { type: null, required: false, default: "primary" },
47
+ ui: { type: Object, required: false }
48
+ });
49
+ const emit = defineEmits(["update:modelValue", "update:placeholder"]);
50
+ defineSlots();
51
+ const slots = useSlots();
52
+ const instance = getCurrentInstance();
53
+ const detailsId = useId();
54
+ const icons = useIcons();
55
+ const messages = useMessages();
56
+ const theme = useComponentTheme("calendar", calendarTheme);
57
+ const ui = computed(() => theme.value());
58
+ const color = computed(() => resolveRegisteredColorRole(props.color, "neutral"));
59
+ const activeColor = computed(() => resolveRegisteredColorRole(props.activeColor, "primary"));
60
+ const rootModelValue = computed(() => {
61
+ const vnodeProps = instance.vnode.props ?? {};
62
+ const isControlled = Object.hasOwn(vnodeProps, "modelValue") || Object.hasOwn(vnodeProps, "model-value");
63
+ return isControlled && props.modelValue === void 0 ? null : props.modelValue;
64
+ });
65
+ const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root);
66
+ const headerProps = computed(() => resolveSlot(ui.value.header, props.ui?.header));
67
+ const headingProps = computed(() => resolveSlot(ui.value.heading, props.ui?.heading));
68
+ const gridsProps = computed(() => resolveSlot(ui.value.grids, props.ui?.grids));
69
+ const gridProps = computed(() => resolveSlot(ui.value.grid, props.ui?.grid));
70
+ const gridHeadProps = computed(() => resolveSlot(ui.value.gridHead, props.ui?.gridHead));
71
+ const headCellProps = computed(() => resolveSlot(ui.value.headCell, props.ui?.headCell));
72
+ const cellProps = computed(() => resolveSlot(ui.value.cell, props.ui?.cell));
73
+ const dayButtonProps = computed(() => resolveSlot(ui.value.dayButton, props.ui?.dayButton));
74
+ const dayDetailsProps = computed(() => resolveSlot(ui.value.dayDetails, props.ui?.dayDetails));
75
+ const footerProps = computed(() => resolveSlot(ui.value.footer, props.ui?.footer));
76
+ const navButtonUi = { leadingIcon: "rtl:-scale-x-100" };
77
+ const dayDetailsId = (month, date) => `${detailsId}-${month.toString()}-${date.toString()}`;
78
+ </script>
79
+
80
+ <template>
81
+ <CalendarRoot
82
+ :model-value="rootModelValue"
83
+ :default-value="defaultValue"
84
+ :placeholder="placeholder"
85
+ :default-placeholder="defaultPlaceholder"
86
+ :min-value="minValue"
87
+ :max-value="maxValue"
88
+ :is-date-disabled="isDateDisabled"
89
+ :is-date-unavailable="isDateUnavailable"
90
+ :locale="locale"
91
+ :number-of-months="numberOfMonths"
92
+ :paged-navigation="pagedNavigation"
93
+ :week-starts-on="weekStartsOn"
94
+ :weekday-format="weekdayFormat"
95
+ :fixed-weeks="fixedWeeks"
96
+ :disable-days-outside-current-view="disableDaysOutsideCurrentView"
97
+ :prevent-deselect="preventDeselect"
98
+ :disabled="disabled"
99
+ :readonly="readonly"
100
+ :initial-focus="initialFocus"
101
+ :calendar-label="calendarLabel"
102
+ :data-selaras-color="activeColor"
103
+ v-bind="rootProps"
104
+ @update:model-value="(value) => emit('update:modelValue', value)"
105
+ @update:placeholder="(value) => emit('update:placeholder', value)"
106
+ >
107
+ <template #default="{ grid, weekDays }">
108
+ <CalendarHeader v-bind="headerProps">
109
+ <CalendarPrev as-child>
110
+ <Button variant="ghost" :color="color" size="sm" :icon="icons.chevronLeft" :aria-label="messages.previousMonth" :ui="navButtonUi" />
111
+ </CalendarPrev>
112
+ <CalendarHeading v-bind="headingProps" />
113
+ <CalendarNext as-child>
114
+ <Button variant="ghost" :color="color" size="sm" :icon="icons.chevronRight" :aria-label="messages.nextMonth" :ui="navButtonUi" />
115
+ </CalendarNext>
116
+ </CalendarHeader>
117
+
118
+ <div v-bind="gridsProps">
119
+ <CalendarGrid v-for="month in grid" :key="month.value.toString()" v-bind="gridProps">
120
+ <CalendarGridHead v-bind="gridHeadProps">
121
+ <CalendarGridRow>
122
+ <CalendarHeadCell v-for="(day, index) in weekDays" :key="index" v-bind="headCellProps">
123
+ {{ day }}
124
+ </CalendarHeadCell>
125
+ </CalendarGridRow>
126
+ </CalendarGridHead>
127
+ <CalendarGridBody>
128
+ <CalendarGridRow v-for="(week, weekIndex) in month.rows" :key="weekIndex">
129
+ <CalendarCell v-for="date in week" :key="date.toString()" :date="date" v-bind="cellProps">
130
+ <CalendarCellTrigger
131
+ v-slot="dayState"
132
+ :day="date"
133
+ :month="month.value"
134
+ as-child
135
+ >
136
+ <Button
137
+ :variant="dayState.selected ? 'solid' : 'ghost'"
138
+ :color="dayState.selected ? activeColor : color"
139
+ size="sm"
140
+ square
141
+ :disabled="dayState.disabled"
142
+ :aria-describedby="slots['day-details'] ? dayDetailsId(month.value, date) : void 0"
143
+ v-bind="dayButtonProps"
144
+ >
145
+ <slot name="day" :date="date" :month="month.value" v-bind="dayState">
146
+ {{ dayState.dayValue }}
147
+ </slot>
148
+ </Button>
149
+ </CalendarCellTrigger>
150
+ <div v-if="slots['day-details']" :id="dayDetailsId(month.value, date)" v-bind="dayDetailsProps">
151
+ <slot name="day-details" :date="date" :month="month.value" />
152
+ </div>
153
+ </CalendarCell>
154
+ </CalendarGridRow>
155
+ </CalendarGridBody>
156
+ </CalendarGrid>
157
+ </div>
158
+ <div v-if="slots.footer" v-bind="footerProps">
159
+ <slot name="footer" />
160
+ </div>
161
+ </template>
162
+ </CalendarRoot>
163
+ </template>
@@ -0,0 +1,69 @@
1
+ import type { DateValue } from '@internationalized/date';
2
+ import type { CalendarThemeSlots } from '../theme/calendar.js';
3
+ import type { ColorRole } from '../utils/color-registry.js';
4
+ import type { UiProp } from '../utils/ui.js';
5
+ type __VLS_Slots = {
6
+ 'day'?: (props: CalendarDaySlotProps) => any;
7
+ /** Renders beside the date trigger within its grid cell. Safe for event links/buttons. */
8
+ 'day-details'?: (props: {
9
+ date: DateValue;
10
+ month: DateValue;
11
+ }) => any;
12
+ 'footer'?: () => any;
13
+ };
14
+ export interface CalendarProps {
15
+ modelValue?: DateValue;
16
+ defaultValue?: DateValue;
17
+ /** The displayed month when controlled independently of the selected date. */
18
+ placeholder?: DateValue;
19
+ defaultPlaceholder?: DateValue;
20
+ minValue?: DateValue;
21
+ maxValue?: DateValue;
22
+ isDateDisabled?: (date: DateValue) => boolean;
23
+ isDateUnavailable?: (date: DateValue) => boolean;
24
+ locale?: string;
25
+ numberOfMonths?: number;
26
+ pagedNavigation?: boolean;
27
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
28
+ weekdayFormat?: 'narrow' | 'short' | 'long';
29
+ fixedWeeks?: boolean;
30
+ disableDaysOutsideCurrentView?: boolean;
31
+ preventDeselect?: boolean;
32
+ disabled?: boolean;
33
+ readonly?: boolean;
34
+ initialFocus?: boolean;
35
+ calendarLabel?: string;
36
+ color?: ColorRole;
37
+ activeColor?: ColorRole;
38
+ ui?: UiProp<CalendarThemeSlots>;
39
+ }
40
+ export interface CalendarEmits {
41
+ 'update:modelValue': [value: DateValue | undefined];
42
+ 'update:placeholder': [value: DateValue];
43
+ }
44
+ export interface CalendarDaySlotProps {
45
+ date: DateValue;
46
+ month: DateValue;
47
+ dayValue: string;
48
+ selected: boolean;
49
+ today: boolean;
50
+ disabled: boolean;
51
+ unavailable: boolean;
52
+ outsideView: boolean;
53
+ outsideVisibleView: boolean;
54
+ }
55
+ declare const __VLS_base: import("vue").DefineComponent<CalendarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
56
+ "update:modelValue": (value: DateValue | undefined) => any;
57
+ "update:placeholder": (value: DateValue) => any;
58
+ }, string, import("vue").PublicProps, Readonly<CalendarProps> & Readonly<{
59
+ "onUpdate:modelValue"?: ((value: DateValue | undefined) => any) | undefined;
60
+ "onUpdate:placeholder"?: ((value: DateValue) => any) | undefined;
61
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
62
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
63
+ declare const _default: typeof __VLS_export;
64
+ export default _default;
65
+ type __VLS_WithSlots<T, S> = T & {
66
+ new (): {
67
+ $slots: S;
68
+ };
69
+ };
@@ -24,6 +24,13 @@ const iconName = computed(() => {
24
24
  return void 0;
25
25
  return props.icon ?? icons.value[DEFAULT_ICON[props.type ?? "note"]];
26
26
  });
27
+ const colorForType = {
28
+ note: "info",
29
+ tip: "success",
30
+ warning: "warning",
31
+ danger: "danger"
32
+ };
33
+ const effectiveColor = computed(() => colorForType[props.type ?? "note"]);
27
34
  const theme = useComponentTheme("callout", calloutTheme);
28
35
  const ui = computed(() => theme.value({ type: props.type }));
29
36
  const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root);
@@ -33,7 +40,7 @@ const titleProps = computed(() => resolveSlot(ui.value.title, props.ui?.title));
33
40
  </script>
34
41
 
35
42
  <template>
36
- <div v-bind="rootProps" role="note">
43
+ <div v-bind="rootProps" data-selaras-callout :data-selaras-color="effectiveColor" role="note">
37
44
  <Icon v-if="iconName" :name="iconName" v-bind="iconProps" />
38
45
  <div v-bind="contentProps">
39
46
  <p v-if="title || $slots.title" v-bind="titleProps">
@@ -45,3 +52,7 @@ const titleProps = computed(() => resolveSlot(ui.value.title, props.ui?.title));
45
52
  </div>
46
53
  </div>
47
54
  </template>
55
+
56
+ <style scoped>
57
+ [data-selaras-callout]:before{-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude}
58
+ </style>
@@ -1,6 +1,8 @@
1
1
  <script setup>
2
2
  import { cloneVNode, Comment, computed, Fragment, ref, Text, useSlots } from "vue";
3
3
  import { useMessages } from "../composables/use-messages";
4
+ import { resolveFileIcon } from "../utils/file-icons";
5
+ import ProsePre from "./ProsePre.vue";
4
6
  import Tabs from "./Tabs.vue";
5
7
  const slots = useSlots();
6
8
  const messages = useMessages();
@@ -22,15 +24,23 @@ function labelFor(child, index) {
22
24
  const props = child.props ?? {};
23
25
  return props.filename || props.language || messages.value.codeTabFallback(index + 1);
24
26
  }
27
+ function iconFor(child) {
28
+ const props = child.props ?? {};
29
+ return props.icon ?? resolveFileIcon(props.language, props.filename);
30
+ }
31
+ function cloneForTab(child) {
32
+ return cloneVNode(child, child.type === ProsePre ? { showHeader: false } : void 0);
33
+ }
25
34
  const tabItems = computed(() => children.value.map((child, index) => ({
26
35
  label: labelFor(child, index),
27
- value: String(index)
36
+ value: String(index),
37
+ icon: iconFor(child)
28
38
  })));
29
39
  const activeTab = ref("0");
30
40
  </script>
31
41
 
32
42
  <template>
33
- <Tabs v-model="activeTab" :items="tabItems">
43
+ <Tabs v-model="activeTab" :items="tabItems" variant="pill">
34
44
  <template v-for="(child, index) in children" :key="index" #[String(index)]>
35
45
  <!--
36
46
  cloneVNode is required, not optional: this vnode was captured from
@@ -40,7 +50,7 @@ const activeTab = ref("0");
40
50
  hydration-shape mismatch (Fragment vs text) the first time this
41
51
  panel mounts. Cloning gives it a fresh identity for its new spot.
42
52
  -->
43
- <component :is="() => cloneVNode(child)" />
53
+ <component :is="() => cloneForTab(child)" />
44
54
  </template>
45
55
  </Tabs>
46
56
  </template>
@@ -4,6 +4,8 @@ import type { FileTreeNode } from './FileTree.vue.js';
4
4
  export interface CodeTreeFile extends FileTreeNode {
5
5
  /** The file's content - read for a leaf node once selected, ignored for a directory. */
6
6
  code?: string;
7
+ /** Overrides the language inferred from the filename. */
8
+ language?: string;
7
9
  children?: CodeTreeFile[];
8
10
  }
9
11
  export interface CodeTreeProps {
@@ -21,6 +21,56 @@ function findFirstFile(nodes) {
21
21
  return void 0;
22
22
  }
23
23
  const selected = ref(findFirstFile(props.items));
24
+ const highlightedCode = ref("");
25
+ const languageByExtension = {
26
+ bash: "bash",
27
+ cjs: "javascript",
28
+ css: "css",
29
+ htm: "html",
30
+ html: "html",
31
+ js: "javascript",
32
+ jsx: "jsx",
33
+ json: "json",
34
+ jsonc: "jsonc",
35
+ md: "markdown",
36
+ mjs: "javascript",
37
+ mts: "typescript",
38
+ sh: "bash",
39
+ ts: "typescript",
40
+ tsx: "tsx",
41
+ vue: "vue",
42
+ yaml: "yaml",
43
+ yml: "yaml"
44
+ };
45
+ function languageFor(file) {
46
+ if (file.language)
47
+ return file.language;
48
+ const extension = file.name.split(".").pop()?.toLowerCase() ?? "";
49
+ return languageByExtension[extension] ?? "text";
50
+ }
51
+ watch(selected, async (file, _previous, onCleanup) => {
52
+ let stale = false;
53
+ onCleanup(() => {
54
+ stale = true;
55
+ });
56
+ highlightedCode.value = "";
57
+ if (!file?.code)
58
+ return;
59
+ try {
60
+ const { codeToHtml } = await import("shiki");
61
+ const html = await codeToHtml(file.code, {
62
+ lang: languageFor(file),
63
+ themes: { light: "github-light", dark: "github-dark" },
64
+ defaultColor: false
65
+ });
66
+ if (stale)
67
+ return;
68
+ highlightedCode.value = html.match(/<code(?:\s[^>]*)?>([\s\S]*?)<\/code>/)?.[1] ?? "";
69
+ } catch {
70
+ if (!stale)
71
+ highlightedCode.value = "";
72
+ }
73
+ }, { immediate: true });
24
74
  watch(() => props.items, () => {
25
75
  selected.value = findFirstFile(props.items);
26
76
  });
@@ -28,6 +78,7 @@ const messages = useMessages();
28
78
  const theme = useComponentTheme("codeTree", codeTreeTheme);
29
79
  const ui = computed(() => theme.value());
30
80
  const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root);
81
+ const codeMode = computed(() => rootProps.value["data-selaras-mode"]);
31
82
  const treeProps = computed(() => resolveSlot(ui.value.tree, props.ui?.tree));
32
83
  const contentProps = computed(() => resolveSlot(ui.value.content, props.ui?.content));
33
84
  const preProps = computed(() => resolveSlot(ui.value.pre, props.ui?.pre));
@@ -47,7 +98,7 @@ const fileTreeUi = { root: "rounded-none border-0 bg-transparent p-0" };
47
98
  />
48
99
  </div>
49
100
  <div v-if="selected" v-bind="contentProps">
50
- <pre v-bind="preProps">{{ selected.code }}</pre>
101
+ <pre v-bind="preProps"><code v-if="highlightedCode" class="selaras-code-tree-code" :data-selaras-code-mode="codeMode" v-html="highlightedCode" /><code v-else>{{ selected.code }}</code></pre>
51
102
  </div>
52
103
  <div v-else v-bind="emptyProps">
53
104
  {{ messages.selectFile }}
@@ -4,6 +4,8 @@ import type { FileTreeNode } from './FileTree.vue.js';
4
4
  export interface CodeTreeFile extends FileTreeNode {
5
5
  /** The file's content - read for a leaf node once selected, ignored for a directory. */
6
6
  code?: string;
7
+ /** Overrides the language inferred from the filename. */
8
+ language?: string;
7
9
  children?: CodeTreeFile[];
8
10
  }
9
11
  export interface CodeTreeProps {
@@ -1,6 +1,8 @@
1
1
  import type { VariantProps } from 'tailwind-variants';
2
2
  import type { ColorPickerThemeSlots } from '../theme/color-picker.js';
3
+ import type { RoundedArrowConfig } from '../utils/arrow.js';
3
4
  import type { ColorRole } from '../utils/color-registry.js';
5
+ import type { OverlayPortal, OverlayPositioning } from '../utils/overlay.js';
4
6
  import type { UiProp } from '../utils/ui.js';
5
7
  import { colorPickerTheme } from '../theme/color-picker.js';
6
8
  type ColorPickerVariants = VariantProps<typeof colorPickerTheme>;
@@ -21,6 +23,12 @@ export interface ColorPickerProps {
21
23
  placeholder?: string;
22
24
  /** Opts into the picker's accessible small-screen modal presentation. */
23
25
  adaptive?: boolean;
26
+ /** Shows a pointer on the anchored picker; the adaptive modal has no arrow. */
27
+ arrow?: boolean | RoundedArrowConfig;
28
+ /** Positioning of the anchored picker (the adaptive modal uses its own layout). */
29
+ positioning?: OverlayPositioning;
30
+ /** Teleport target for the anchored picker, or `false` to render it inline. */
31
+ portal?: OverlayPortal;
24
32
  size?: ColorPickerVariants['size'];
25
33
  color?: ColorRole;
26
34
  ui?: UiProp<ColorPickerThemeSlots>;