@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.
- package/dist/module.json +1 -1
- package/dist/module.mjs +14 -1
- package/dist/runtime/components/Autocomplete.vue +3 -1
- package/dist/runtime/components/Calendar.d.vue.ts +69 -0
- package/dist/runtime/components/Calendar.vue +163 -0
- package/dist/runtime/components/Calendar.vue.d.ts +69 -0
- package/dist/runtime/components/Callout.vue +12 -1
- package/dist/runtime/components/CodeGroup.vue +13 -3
- package/dist/runtime/components/CodeTree.d.vue.ts +2 -0
- package/dist/runtime/components/CodeTree.vue +52 -1
- package/dist/runtime/components/CodeTree.vue.d.ts +2 -0
- package/dist/runtime/components/ColorPicker.d.vue.ts +8 -0
- package/dist/runtime/components/ColorPicker.vue +66 -45
- package/dist/runtime/components/ColorPicker.vue.d.ts +8 -0
- package/dist/runtime/components/Column.js +1 -1
- package/dist/runtime/components/CommandPalette.d.vue.ts +3 -1
- package/dist/runtime/components/CommandPalette.vue +5 -0
- package/dist/runtime/components/CommandPalette.vue.d.ts +3 -1
- package/dist/runtime/components/ContentNavigation.d.vue.ts +8 -1
- package/dist/runtime/components/ContentNavigation.vue +9 -2
- package/dist/runtime/components/ContentNavigation.vue.d.ts +8 -1
- package/dist/runtime/components/ContextMenu.d.vue.ts +8 -1
- package/dist/runtime/components/ContextMenu.vue +16 -4
- package/dist/runtime/components/ContextMenu.vue.d.ts +8 -1
- package/dist/runtime/components/DatePicker.d.vue.ts +10 -3
- package/dist/runtime/components/DatePicker.vue +24 -16
- package/dist/runtime/components/DatePicker.vue.d.ts +10 -3
- package/dist/runtime/components/Dropdown.d.vue.ts +33 -6
- package/dist/runtime/components/Dropdown.vue +143 -11
- package/dist/runtime/components/Dropdown.vue.d.ts +33 -6
- package/dist/runtime/components/FileTree.d.vue.ts +2 -0
- package/dist/runtime/components/FileTree.vue +8 -4
- package/dist/runtime/components/FileTree.vue.d.ts +2 -0
- package/dist/runtime/components/FormField.d.vue.ts +4 -0
- package/dist/runtime/components/FormField.vue +19 -4
- package/dist/runtime/components/FormField.vue.d.ts +4 -0
- package/dist/runtime/components/Input.vue +3 -2
- package/dist/runtime/components/Kbd.vue +12 -2
- package/dist/runtime/components/NavigationMenu.d.vue.ts +10 -10
- package/dist/runtime/components/NavigationMenu.vue +13 -9
- package/dist/runtime/components/NavigationMenu.vue.d.ts +10 -10
- package/dist/runtime/components/NavigationMenuAccordionItem.vue +5 -1
- package/dist/runtime/components/NavigationMenuFlyoutList.vue +7 -4
- package/dist/runtime/components/Popover.d.vue.ts +8 -2
- package/dist/runtime/components/Popover.vue +9 -4
- package/dist/runtime/components/Popover.vue.d.ts +8 -2
- package/dist/runtime/components/ProsePre.d.vue.ts +2 -0
- package/dist/runtime/components/ProsePre.vue +2 -1
- package/dist/runtime/components/ProsePre.vue.d.ts +2 -0
- package/dist/runtime/components/Select.vue +3 -1
- package/dist/runtime/components/SplitterPanel.d.vue.ts +2 -2
- package/dist/runtime/components/SplitterPanel.vue.d.ts +2 -2
- package/dist/runtime/components/Table.vue +95 -26
- package/dist/runtime/components/Tabs.d.vue.ts +44 -4
- package/dist/runtime/components/Tabs.vue +171 -18
- package/dist/runtime/components/Tabs.vue.d.ts +44 -4
- package/dist/runtime/components/Textarea.vue +3 -2
- package/dist/runtime/components/Timeline.d.vue.ts +19 -0
- package/dist/runtime/components/Timeline.vue +99 -0
- package/dist/runtime/components/Timeline.vue.d.ts +19 -0
- package/dist/runtime/components/Toast.d.vue.ts +10 -1
- package/dist/runtime/components/Toast.vue +94 -8
- package/dist/runtime/components/Toast.vue.d.ts +10 -1
- package/dist/runtime/components/Tooltip.d.vue.ts +8 -2
- package/dist/runtime/components/Tooltip.vue +9 -4
- package/dist/runtime/components/Tooltip.vue.d.ts +8 -2
- package/dist/runtime/composables/use-form-field.d.ts +1 -0
- package/dist/runtime/composables/use-table.d.ts +3 -0
- package/dist/runtime/composables/use-table.js +10 -4
- package/dist/runtime/composables/use-toast.js +5 -1
- package/dist/runtime/directives/hotkey.d.ts +13 -0
- package/dist/runtime/directives/hotkey.js +107 -0
- package/dist/runtime/directives/index.d.ts +2 -0
- package/dist/runtime/directives/index.js +2 -0
- package/dist/runtime/directives/mask.d.ts +30 -0
- package/dist/runtime/directives/mask.js +165 -0
- package/dist/runtime/internal/ComboboxSelectBase.d.vue.ts +29 -25
- package/dist/runtime/internal/ComboboxSelectBase.vue +103 -19
- package/dist/runtime/internal/ComboboxSelectBase.vue.d.ts +29 -25
- package/dist/runtime/internal/ComboboxSelectBody.d.vue.ts +16 -11
- package/dist/runtime/internal/ComboboxSelectBody.vue +49 -10
- package/dist/runtime/internal/ComboboxSelectBody.vue.d.ts +16 -11
- package/dist/runtime/internal/DatePickerCalendarBody.vue +1 -1
- package/dist/runtime/internal/DatePickerRangeCalendarBody.vue +1 -1
- package/dist/runtime/internal/ShortcutHint.d.vue.ts +6 -0
- package/dist/runtime/internal/ShortcutHint.vue +13 -0
- package/dist/runtime/internal/ShortcutHint.vue.d.ts +6 -0
- package/dist/runtime/internal/ToastItemRenderer.d.vue.ts +9 -1
- package/dist/runtime/internal/ToastItemRenderer.vue +55 -8
- package/dist/runtime/internal/ToastItemRenderer.vue.d.ts +9 -1
- package/dist/runtime/internal/combobox-select.js +2 -1
- package/dist/runtime/internal/programmatic-services.d.ts +2 -0
- package/dist/runtime/internal/programmatic-services.js +8 -0
- package/dist/runtime/internal/toast-stack.d.ts +36 -0
- package/dist/runtime/internal/toast-stack.js +36 -0
- package/dist/runtime/structural.css +1 -1
- package/dist/runtime/table.d.ts +1 -1
- package/dist/runtime/theme/alert-dialog.js +1 -1
- package/dist/runtime/theme/calendar.d.ts +86 -0
- package/dist/runtime/theme/calendar.js +19 -0
- package/dist/runtime/theme/callout.d.ts +0 -12
- package/dist/runtime/theme/callout.js +8 -8
- package/dist/runtime/theme/code-tree.js +1 -1
- package/dist/runtime/theme/command-palette.js +1 -1
- package/dist/runtime/theme/content-navigation.d.ts +3 -0
- package/dist/runtime/theme/content-navigation.js +1 -0
- package/dist/runtime/theme/drawer.js +1 -1
- package/dist/runtime/theme/dropdown.d.ts +21 -0
- package/dist/runtime/theme/dropdown.js +15 -2
- package/dist/runtime/theme/file-tree.js +1 -1
- package/dist/runtime/theme/form-field.d.ts +18 -0
- package/dist/runtime/theme/form-field.js +6 -1
- package/dist/runtime/theme/modal.js +1 -1
- package/dist/runtime/theme/slideover.js +1 -1
- package/dist/runtime/theme/table.d.ts +27 -0
- package/dist/runtime/theme/table.js +11 -2
- package/dist/runtime/theme/tabs.d.ts +87 -3
- package/dist/runtime/theme/tabs.js +46 -22
- package/dist/runtime/theme/timeline.d.ts +251 -0
- package/dist/runtime/theme/timeline.js +84 -0
- package/dist/runtime/theme/toast.d.ts +92 -0
- package/dist/runtime/theme/toast.js +29 -7
- package/dist/runtime/theme-config.d.ts +12 -1
- package/dist/runtime/types/index.d.ts +6 -1
- package/dist/runtime/utils/arrow.d.ts +21 -0
- package/dist/runtime/utils/arrow.js +10 -0
- package/dist/runtime/utils/file-icons.js +2 -0
- package/dist/runtime/utils/icons.d.ts +2 -0
- package/dist/runtime/utils/icons.js +2 -0
- package/dist/runtime/utils/messages.d.ts +6 -0
- package/dist/runtime/utils/messages.js +6 -0
- package/dist/runtime/utils/navigation-menu.d.ts +7 -0
- package/dist/runtime/utils/navigation-menu.js +3 -0
- package/dist/runtime/utils/overlay.d.ts +17 -0
- package/dist/runtime/utils/overlay.js +7 -0
- package/dist/runtime/utils/select-contracts.d.ts +7 -1
- package/dist/runtime/utils/table-columns.js +1 -1
- package/dist/runtime/utils/table-contracts.d.ts +9 -1
- package/dist/runtime/utils/timeline-contracts.d.ts +42 -0
- package/dist/runtime/utils/timeline-contracts.js +0 -0
- package/package.json +2 -1
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ColorSwatch } from "reka-ui";
|
|
2
|
+
import { ColorSwatch, PopoverArrow, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from "reka-ui";
|
|
3
3
|
import { computed, getCurrentInstance, onMounted, onUnmounted, ref, watch } from "vue";
|
|
4
|
+
import { useFormField } from "../composables/use-form-field";
|
|
4
5
|
import { useIsMobile } from "../composables/use-media-query";
|
|
5
6
|
import { useMessages } from "../composables/use-messages";
|
|
6
7
|
import ColorPickerBody from "../internal/ColorPickerBody.vue";
|
|
7
8
|
import { colorPickerTheme } from "../theme/color-picker";
|
|
9
|
+
import { popoverTheme } from "../theme/popover";
|
|
10
|
+
import { arrowContentProps, arrowElementProps } from "../utils/arrow";
|
|
11
|
+
import { overlayPortalProps } from "../utils/overlay";
|
|
8
12
|
import { resolveRegisteredColorRole } from "../utils/registered-colors";
|
|
9
13
|
import { resolveSlot, useComponentTheme, useThemeBindings } from "../utils/ui";
|
|
10
14
|
import Modal from "./Modal.vue";
|
|
11
|
-
import Popover from "./Popover.vue";
|
|
12
15
|
const props = defineProps({
|
|
13
16
|
name: { type: String, required: false },
|
|
14
17
|
form: { type: String, required: false },
|
|
@@ -21,12 +24,17 @@ const props = defineProps({
|
|
|
21
24
|
swatches: { type: Array, required: false },
|
|
22
25
|
placeholder: { type: String, required: false },
|
|
23
26
|
adaptive: { type: Boolean, required: false },
|
|
27
|
+
arrow: { type: [Boolean, Object], required: false },
|
|
28
|
+
positioning: { type: Object, required: false },
|
|
29
|
+
portal: { type: [Boolean, String], required: false, skipCheck: true, default: void 0 },
|
|
24
30
|
size: { type: null, required: false },
|
|
25
31
|
color: { type: null, required: false },
|
|
26
32
|
ui: { type: Object, required: false }
|
|
27
33
|
});
|
|
28
34
|
const emit = defineEmits(["update:open", "update:modelValue"]);
|
|
29
35
|
const messages = useMessages();
|
|
36
|
+
const field = useFormField();
|
|
37
|
+
const formName = computed(() => props.name ?? field?.name);
|
|
30
38
|
const instance = getCurrentInstance();
|
|
31
39
|
const formAnchor = ref();
|
|
32
40
|
const initialColor = props.defaultValue ?? "#000000";
|
|
@@ -104,55 +112,68 @@ const bodyProps = computed(() => ({
|
|
|
104
112
|
swatchIndicatorProps: swatchIndicatorProps.value,
|
|
105
113
|
colorRoleMarker: colorRoleMarker.value
|
|
106
114
|
}));
|
|
107
|
-
const
|
|
115
|
+
const popoverThemeFn = useComponentTheme("popover", popoverTheme);
|
|
116
|
+
const popoverUi = computed(() => popoverThemeFn.value());
|
|
117
|
+
const popoverContentProps = computed(() => ({
|
|
118
|
+
...resolveSlot(popoverUi.value.content, resolveSlot(ui.value.content, props.ui?.content)),
|
|
119
|
+
...arrowContentProps(props.arrow),
|
|
120
|
+
...props.positioning
|
|
121
|
+
}));
|
|
122
|
+
const popoverArrowProps = computed(() => ({ ...resolveSlot(popoverUi.value.arrow, void 0), ...arrowElementProps(props.arrow) }));
|
|
123
|
+
const popoverPortalProps = computed(() => overlayPortalProps(props.portal));
|
|
108
124
|
const adaptiveUi = computed(() => ({ content: "rounded-[var(--selaras-resolved-radius-md)]" }));
|
|
109
125
|
const mobileContentProps = computed(() => resolveSlot(ui.value.mobileContent, props.ui?.mobileContent));
|
|
110
126
|
</script>
|
|
111
127
|
|
|
112
128
|
<template>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
129
|
+
<!--
|
|
130
|
+
The root and trigger stay mounted for both presentations. Only the
|
|
131
|
+
content switches: the anchored panel is removed outright while the
|
|
132
|
+
adaptive Modal is showing, and the Modal returns focus to this same
|
|
133
|
+
trigger on close.
|
|
134
|
+
-->
|
|
135
|
+
<PopoverRoot :open="open" @update:open="onUpdateOpen">
|
|
136
|
+
<PopoverTrigger as-child>
|
|
137
|
+
<button
|
|
138
|
+
type="button"
|
|
139
|
+
:disabled="disabled"
|
|
140
|
+
:aria-label="messages.colorPicker"
|
|
141
|
+
:data-selaras-color="colorRoleMarker"
|
|
142
|
+
:data-selaras-theme="themeBindings['data-selaras-theme']"
|
|
143
|
+
:data-selaras-mode="themeBindings['data-selaras-mode']"
|
|
144
|
+
:style="themeBindings.style"
|
|
145
|
+
v-bind="triggerProps"
|
|
146
|
+
>
|
|
147
|
+
<ColorSwatch :color="internalColor" v-bind="triggerSwatchProps" />
|
|
148
|
+
<span v-bind="triggerValueProps">{{ internalColor }}</span>
|
|
149
|
+
</button>
|
|
150
|
+
</PopoverTrigger>
|
|
127
151
|
|
|
128
|
-
<
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
152
|
+
<PopoverPortal v-if="!showMobileModal" v-bind="popoverPortalProps">
|
|
153
|
+
<PopoverContent
|
|
154
|
+
:data-selaras-theme="themeBindings['data-selaras-theme']"
|
|
155
|
+
:data-selaras-mode="themeBindings['data-selaras-mode']"
|
|
156
|
+
:style="themeBindings.style"
|
|
157
|
+
side="bottom"
|
|
158
|
+
align="start"
|
|
159
|
+
:side-offset="8"
|
|
160
|
+
v-bind="popoverContentProps"
|
|
161
|
+
>
|
|
162
|
+
<ColorPickerBody v-bind="bodyProps" @update:model-value="onUpdateColor" />
|
|
163
|
+
<PopoverArrow v-if="arrow" v-bind="popoverArrowProps" />
|
|
164
|
+
</PopoverContent>
|
|
165
|
+
</PopoverPortal>
|
|
132
166
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
>
|
|
137
|
-
<button
|
|
138
|
-
type="button"
|
|
139
|
-
:disabled="disabled"
|
|
140
|
-
:aria-label="messages.colorPicker"
|
|
141
|
-
:data-selaras-color="colorRoleMarker"
|
|
142
|
-
:data-selaras-theme="themeBindings['data-selaras-theme']"
|
|
143
|
-
:data-selaras-mode="themeBindings['data-selaras-mode']"
|
|
144
|
-
:style="themeBindings.style"
|
|
145
|
-
v-bind="triggerProps"
|
|
167
|
+
<Modal
|
|
168
|
+
v-else :open="open" :title="messages.colorPicker" :description="messages.colorPickerDescription"
|
|
169
|
+
:ui="adaptiveUi" @update:open="onUpdateOpen"
|
|
146
170
|
>
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
</template>
|
|
156
|
-
</Modal>
|
|
157
|
-
<input ref="formAnchor" type="hidden" :name="name" :form="form" :value="internalColor">
|
|
171
|
+
<template #content>
|
|
172
|
+
<div v-bind="mobileContentProps">
|
|
173
|
+
<ColorPickerBody v-bind="bodyProps" @update:model-value="onUpdateColor" />
|
|
174
|
+
</div>
|
|
175
|
+
</template>
|
|
176
|
+
</Modal>
|
|
177
|
+
</PopoverRoot>
|
|
178
|
+
<input ref="formAnchor" type="hidden" :name="formName" :form="form" :value="internalColor" :disabled="disabled">
|
|
158
179
|
</template>
|
|
@@ -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>;
|
|
@@ -3,8 +3,10 @@ import type { UiProp } from '../utils/ui.js';
|
|
|
3
3
|
export interface CommandPaletteItem {
|
|
4
4
|
label: string;
|
|
5
5
|
icon?: string;
|
|
6
|
-
/**
|
|
6
|
+
/** Displayed via Kbd. */
|
|
7
7
|
shortcut?: string;
|
|
8
|
+
/** Bind `shortcut` while this palette is open; activation uses this item's normal selection behavior. */
|
|
9
|
+
hotkey?: boolean;
|
|
8
10
|
disabled?: boolean;
|
|
9
11
|
onSelect?: () => void;
|
|
10
12
|
}
|
|
@@ -4,6 +4,7 @@ import { computed, onMounted, onUnmounted, ref, useId, watch } from "vue";
|
|
|
4
4
|
import { useCommandPalette } from "../composables/use-command-palette";
|
|
5
5
|
import { useIcons } from "../composables/use-icons";
|
|
6
6
|
import { useMessages } from "../composables/use-messages";
|
|
7
|
+
import { vHotkey } from "../directives/hotkey";
|
|
7
8
|
import { commandPaletteTheme } from "../theme/command-palette";
|
|
8
9
|
import { fuzzyScore } from "../utils/fuzzy-match";
|
|
9
10
|
import { applyClassPrefix, resolveSlot, useComponentTheme, useRootProps, useThemeBindings } from "../utils/ui";
|
|
@@ -40,6 +41,9 @@ const query = ref("");
|
|
|
40
41
|
const highlightedIndex = ref(0);
|
|
41
42
|
const inputRef = ref();
|
|
42
43
|
const listboxId = `selaras-command-palette-list-${useId()}`;
|
|
44
|
+
function hotkeyFor(item) {
|
|
45
|
+
return item.hotkey && item.shortcut && !item.disabled ? { keys: item.shortcut, when: () => isOpen.value, allowInEditable: true } : void 0;
|
|
46
|
+
}
|
|
43
47
|
watch(isOpen, (open) => {
|
|
44
48
|
if (!open) {
|
|
45
49
|
query.value = "";
|
|
@@ -178,6 +182,7 @@ function itemId(index) {
|
|
|
178
182
|
v-for="item in group.items"
|
|
179
183
|
:id="itemId(allItems.indexOf(item))"
|
|
180
184
|
:key="item.label"
|
|
185
|
+
v-hotkey="hotkeyFor(item)"
|
|
181
186
|
role="option"
|
|
182
187
|
:aria-selected="isHighlighted(item)"
|
|
183
188
|
:aria-disabled="item.disabled"
|
|
@@ -3,8 +3,10 @@ import type { UiProp } from '../utils/ui.js';
|
|
|
3
3
|
export interface CommandPaletteItem {
|
|
4
4
|
label: string;
|
|
5
5
|
icon?: string;
|
|
6
|
-
/**
|
|
6
|
+
/** Displayed via Kbd. */
|
|
7
7
|
shortcut?: string;
|
|
8
|
+
/** Bind `shortcut` while this palette is open; activation uses this item's normal selection behavior. */
|
|
9
|
+
hotkey?: boolean;
|
|
8
10
|
disabled?: boolean;
|
|
9
11
|
onSelect?: () => void;
|
|
10
12
|
}
|
|
@@ -4,7 +4,12 @@ import type { UiProp } from '../utils/ui.js';
|
|
|
4
4
|
export interface ContentNavigationLink {
|
|
5
5
|
title: string;
|
|
6
6
|
path: string;
|
|
7
|
-
icon?: string;
|
|
7
|
+
icon?: string | false;
|
|
8
|
+
order?: number;
|
|
9
|
+
collapse?: boolean;
|
|
10
|
+
navBadges?: Array<string | {
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
8
13
|
children?: ContentNavigationLink[];
|
|
9
14
|
}
|
|
10
15
|
type __VLS_Slots = ContentNavigationSlots;
|
|
@@ -12,6 +17,8 @@ export interface ContentNavigationProps {
|
|
|
12
17
|
navigation: ContentNavigationLink[];
|
|
13
18
|
/** The active-link accent. @default 'primary' */
|
|
14
19
|
color?: ColorRole;
|
|
20
|
+
/** Collapse every group initially unless the item's own `collapse` metadata overrides it. @default false */
|
|
21
|
+
collapsed?: boolean;
|
|
15
22
|
/** Set only by this component's own recursive self-call, one level down for each nested group - gates the tree-connector rail (see `content-navigation.ts`'s own `isNested` variant), since a root-level entry has no parent trunk to its left to branch off of. */
|
|
16
23
|
isNested?: boolean;
|
|
17
24
|
ui?: UiProp<ContentNavigationThemeSlots>;
|
|
@@ -10,6 +10,7 @@ defineOptions({ inheritAttrs: false });
|
|
|
10
10
|
const props = defineProps({
|
|
11
11
|
navigation: { type: Array, required: true },
|
|
12
12
|
color: { type: null, required: false },
|
|
13
|
+
collapsed: { type: Boolean, required: false },
|
|
13
14
|
isNested: { type: Boolean, required: false },
|
|
14
15
|
ui: { type: Object, required: false }
|
|
15
16
|
});
|
|
@@ -37,19 +38,22 @@ const groupUi = computed(() => ({
|
|
|
37
38
|
<Accordion
|
|
38
39
|
v-if="link.children?.length"
|
|
39
40
|
:items="[{ value: link.path, label: link.title }]"
|
|
40
|
-
:default-value="[link.path]"
|
|
41
|
+
:default-value="link.collapse ?? collapsed ? [] : [link.path]"
|
|
41
42
|
:ui="groupUi"
|
|
42
43
|
>
|
|
43
44
|
<template #label>
|
|
44
45
|
<slot name="link" :link="link" :active="false">
|
|
45
46
|
<Icon v-if="link.icon" :name="link.icon" v-bind="resolveSlot(ui.icon, props.ui?.icon)" />
|
|
46
47
|
{{ link.title }}
|
|
48
|
+
<span v-for="(badge, index) in link.navBadges" :key="`${link.path}:badge:${index}`" v-bind="resolveSlot(ui.badge, props.ui?.badge)">
|
|
49
|
+
{{ typeof badge === "string" ? badge : badge.text }}
|
|
50
|
+
</span>
|
|
47
51
|
</slot>
|
|
48
52
|
</template>
|
|
49
53
|
<template #[link.path]>
|
|
50
54
|
<!-- Vue's SFC self-recursion resolves by this file's own bare name -
|
|
51
55
|
keep it unprefixed even though the public component is SContentNavigation. -->
|
|
52
|
-
<ContentNavigation :navigation="link.children" is-nested :color="color" :ui="props.ui">
|
|
56
|
+
<ContentNavigation :navigation="link.children" is-nested :color="color" :collapsed="collapsed" :ui="props.ui">
|
|
53
57
|
<template #link="scope">
|
|
54
58
|
<slot name="link" v-bind="scope" />
|
|
55
59
|
</template>
|
|
@@ -60,6 +64,9 @@ const groupUi = computed(() => ({
|
|
|
60
64
|
<slot name="link" :link="link" :active="isActive(link)">
|
|
61
65
|
<Icon v-if="link.icon" :name="link.icon" v-bind="resolveSlot(ui.icon, props.ui?.icon)" />
|
|
62
66
|
{{ link.title }}
|
|
67
|
+
<span v-for="(badge, index) in link.navBadges" :key="`${link.path}:badge:${index}`" v-bind="resolveSlot(ui.badge, props.ui?.badge)">
|
|
68
|
+
{{ typeof badge === "string" ? badge : badge.text }}
|
|
69
|
+
</span>
|
|
63
70
|
</slot>
|
|
64
71
|
</NuxtLink>
|
|
65
72
|
</li>
|
|
@@ -4,7 +4,12 @@ import type { UiProp } from '../utils/ui.js';
|
|
|
4
4
|
export interface ContentNavigationLink {
|
|
5
5
|
title: string;
|
|
6
6
|
path: string;
|
|
7
|
-
icon?: string;
|
|
7
|
+
icon?: string | false;
|
|
8
|
+
order?: number;
|
|
9
|
+
collapse?: boolean;
|
|
10
|
+
navBadges?: Array<string | {
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
8
13
|
children?: ContentNavigationLink[];
|
|
9
14
|
}
|
|
10
15
|
type __VLS_Slots = ContentNavigationSlots;
|
|
@@ -12,6 +17,8 @@ export interface ContentNavigationProps {
|
|
|
12
17
|
navigation: ContentNavigationLink[];
|
|
13
18
|
/** The active-link accent. @default 'primary' */
|
|
14
19
|
color?: ColorRole;
|
|
20
|
+
/** Collapse every group initially unless the item's own `collapse` metadata overrides it. @default false */
|
|
21
|
+
collapsed?: boolean;
|
|
15
22
|
/** Set only by this component's own recursive self-call, one level down for each nested group - gates the tree-connector rail (see `content-navigation.ts`'s own `isNested` variant), since a root-level entry has no parent trunk to its left to branch off of. */
|
|
16
23
|
isNested?: boolean;
|
|
17
24
|
ui?: UiProp<ContentNavigationThemeSlots>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ContextMenuThemeSlots } from '../theme/context-menu.js';
|
|
2
|
+
import type { ContextMenuPositioning, OverlayPortal } from '../utils/overlay.js';
|
|
2
3
|
import type { UiProp } from '../utils/ui.js';
|
|
3
4
|
export interface ContextMenuItemDef {
|
|
4
5
|
label: string;
|
|
@@ -7,12 +8,18 @@ export interface ContextMenuItemDef {
|
|
|
7
8
|
/** Styles this item for a delete/remove-style action (danger text, danger-tinted hover) - matches Dropdown's own `destructive` flag. */
|
|
8
9
|
destructive?: boolean;
|
|
9
10
|
onSelect?: () => void;
|
|
10
|
-
/**
|
|
11
|
+
/** Displays a keyboard shortcut hint. */
|
|
11
12
|
shortcut?: string;
|
|
13
|
+
/** Bind `shortcut` while this menu is open; activation follows the normal menu item click path. */
|
|
14
|
+
hotkey?: boolean;
|
|
12
15
|
}
|
|
13
16
|
type __VLS_Slots = ContextMenuSlots;
|
|
14
17
|
export interface ContextMenuProps {
|
|
15
18
|
items: ContextMenuItemDef[][];
|
|
19
|
+
/** Collision and offset controls for the menu anchored to the right-click point. */
|
|
20
|
+
positioning?: ContextMenuPositioning;
|
|
21
|
+
/** Teleport target, or `false` to render inline. Defaults to `body`. */
|
|
22
|
+
portal?: OverlayPortal;
|
|
16
23
|
ui?: UiProp<ContextMenuThemeSlots>;
|
|
17
24
|
}
|
|
18
25
|
export interface ContextMenuSlots {
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ContextMenuContent, ContextMenuItem, ContextMenuPortal, ContextMenuRoot, ContextMenuSeparator, ContextMenuTrigger } from "reka-ui";
|
|
3
|
-
import { computed } from "vue";
|
|
3
|
+
import { computed, ref } from "vue";
|
|
4
|
+
import { vHotkey } from "../directives/hotkey";
|
|
5
|
+
import ShortcutHint from "../internal/ShortcutHint.vue";
|
|
4
6
|
import { contextMenuTheme } from "../theme/context-menu";
|
|
7
|
+
import { overlayPortalProps } from "../utils/overlay";
|
|
5
8
|
import { resolveSlot, useComponentTheme, useThemeBindings } from "../utils/ui";
|
|
6
9
|
import Icon from "./Icon.vue";
|
|
7
10
|
const props = defineProps({
|
|
8
11
|
items: { type: Array, required: true },
|
|
12
|
+
positioning: { type: Object, required: false },
|
|
13
|
+
portal: { type: [Boolean, String], required: false, skipCheck: true, default: void 0 },
|
|
9
14
|
ui: { type: Object, required: false }
|
|
10
15
|
});
|
|
11
16
|
defineSlots();
|
|
12
17
|
const theme = useComponentTheme("contextMenu", contextMenuTheme);
|
|
18
|
+
const open = ref(false);
|
|
13
19
|
const themeBindings = useThemeBindings();
|
|
14
20
|
const ui = computed(() => theme.value());
|
|
15
|
-
const contentProps = computed(() => resolveSlot(ui.value.content, props.ui?.content));
|
|
21
|
+
const contentProps = computed(() => ({ ...resolveSlot(ui.value.content, props.ui?.content), ...props.positioning }));
|
|
22
|
+
const portalProps = computed(() => overlayPortalProps(props.portal));
|
|
16
23
|
function itemPropsFor(item) {
|
|
17
24
|
return resolveSlot(theme.value({ destructive: item.destructive }).item, props.ui?.item);
|
|
18
25
|
}
|
|
@@ -20,20 +27,24 @@ function iconPropsFor(item) {
|
|
|
20
27
|
return resolveSlot(theme.value({ destructive: item.destructive }).icon, props.ui?.icon);
|
|
21
28
|
}
|
|
22
29
|
const separatorProps = computed(() => resolveSlot(ui.value.separator, props.ui?.separator));
|
|
30
|
+
function hotkeyFor(item) {
|
|
31
|
+
return item.hotkey && item.shortcut && !item.disabled ? { keys: item.shortcut, when: () => open.value } : void 0;
|
|
32
|
+
}
|
|
23
33
|
</script>
|
|
24
34
|
|
|
25
35
|
<template>
|
|
26
|
-
<ContextMenuRoot>
|
|
36
|
+
<ContextMenuRoot :open="open" @update:open="open = $event">
|
|
27
37
|
<ContextMenuTrigger as-child>
|
|
28
38
|
<slot />
|
|
29
39
|
</ContextMenuTrigger>
|
|
30
|
-
<ContextMenuPortal>
|
|
40
|
+
<ContextMenuPortal v-bind="portalProps">
|
|
31
41
|
<ContextMenuContent :data-selaras-theme="themeBindings['data-selaras-theme']" :data-selaras-mode="themeBindings['data-selaras-mode']" :style="themeBindings.style" v-bind="contentProps">
|
|
32
42
|
<template v-for="(group, groupIndex) in items" :key="groupIndex">
|
|
33
43
|
<ContextMenuSeparator v-if="groupIndex > 0" v-bind="separatorProps" />
|
|
34
44
|
<ContextMenuItem
|
|
35
45
|
v-for="(item, itemIndex) in group"
|
|
36
46
|
:key="itemIndex"
|
|
47
|
+
v-hotkey="hotkeyFor(item)"
|
|
37
48
|
:disabled="item.disabled"
|
|
38
49
|
v-bind="itemPropsFor(item)"
|
|
39
50
|
@select="item.onSelect?.()"
|
|
@@ -41,6 +52,7 @@ const separatorProps = computed(() => resolveSlot(ui.value.separator, props.ui?.
|
|
|
41
52
|
<Icon v-if="item.icon" :name="item.icon" v-bind="iconPropsFor(item)" />
|
|
42
53
|
<slot name="item" :item="item">
|
|
43
54
|
{{ item.label }}
|
|
55
|
+
<ShortcutHint :shortcut="item.shortcut" />
|
|
44
56
|
</slot>
|
|
45
57
|
</ContextMenuItem>
|
|
46
58
|
</template>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ContextMenuThemeSlots } from '../theme/context-menu.js';
|
|
2
|
+
import type { ContextMenuPositioning, OverlayPortal } from '../utils/overlay.js';
|
|
2
3
|
import type { UiProp } from '../utils/ui.js';
|
|
3
4
|
export interface ContextMenuItemDef {
|
|
4
5
|
label: string;
|
|
@@ -7,12 +8,18 @@ export interface ContextMenuItemDef {
|
|
|
7
8
|
/** Styles this item for a delete/remove-style action (danger text, danger-tinted hover) - matches Dropdown's own `destructive` flag. */
|
|
8
9
|
destructive?: boolean;
|
|
9
10
|
onSelect?: () => void;
|
|
10
|
-
/**
|
|
11
|
+
/** Displays a keyboard shortcut hint. */
|
|
11
12
|
shortcut?: string;
|
|
13
|
+
/** Bind `shortcut` while this menu is open; activation follows the normal menu item click path. */
|
|
14
|
+
hotkey?: boolean;
|
|
12
15
|
}
|
|
13
16
|
type __VLS_Slots = ContextMenuSlots;
|
|
14
17
|
export interface ContextMenuProps {
|
|
15
18
|
items: ContextMenuItemDef[][];
|
|
19
|
+
/** Collision and offset controls for the menu anchored to the right-click point. */
|
|
20
|
+
positioning?: ContextMenuPositioning;
|
|
21
|
+
/** Teleport target, or `false` to render inline. Defaults to `body`. */
|
|
22
|
+
portal?: OverlayPortal;
|
|
16
23
|
ui?: UiProp<ContextMenuThemeSlots>;
|
|
17
24
|
}
|
|
18
25
|
export interface ContextMenuSlots {
|
|
@@ -2,7 +2,9 @@ import type { DateValue } from '@internationalized/date';
|
|
|
2
2
|
import type { DateRange } from 'reka-ui';
|
|
3
3
|
import type { VariantProps } from 'tailwind-variants';
|
|
4
4
|
import type { DatePickerThemeSlots } from '../theme/date-picker.js';
|
|
5
|
+
import type { RoundedArrowConfig } from '../utils/arrow.js';
|
|
5
6
|
import type { ColorRole } from '../utils/color-registry.js';
|
|
7
|
+
import type { OverlayPortal, OverlayPositioning } from '../utils/overlay.js';
|
|
6
8
|
import type { UiProp } from '../utils/ui.js';
|
|
7
9
|
import { Time } from '@internationalized/date';
|
|
8
10
|
import { datePickerTheme } from '../theme/date-picker.js';
|
|
@@ -73,7 +75,12 @@ export interface DatePickerProps {
|
|
|
73
75
|
activeColor?: ColorRole;
|
|
74
76
|
size?: DatePickerVariants['size'];
|
|
75
77
|
/** Shows a small pointer triangle connecting the panel to its trigger. */
|
|
76
|
-
|
|
78
|
+
/** Shows the pointer; an object configures its size, rounding, and edge clearance. */
|
|
79
|
+
arrow?: boolean | RoundedArrowConfig;
|
|
80
|
+
/** Positioning of the anchored calendar (the adaptive modal uses its own layout). */
|
|
81
|
+
positioning?: OverlayPositioning;
|
|
82
|
+
/** Teleport target for the anchored calendar, or `false` to render it inline. */
|
|
83
|
+
portal?: OverlayPortal;
|
|
77
84
|
/** Opts into the calendar's accessible small-screen modal presentation. It is selected when the calendar opens and held until close. */
|
|
78
85
|
adaptive?: boolean;
|
|
79
86
|
ui?: UiProp<DatePickerThemeSlots>;
|
|
@@ -158,11 +165,11 @@ type __VLS_Slots = {} & {
|
|
|
158
165
|
declare const __VLS_base: import("vue").DefineComponent<DatePickerProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
159
166
|
"update:modelValue": (value: DateValue | DateRange | Time | undefined) => any;
|
|
160
167
|
"update:open": (value: boolean) => any;
|
|
161
|
-
"update:view": (view: "
|
|
168
|
+
"update:view": (view: "date" | "month" | "year") => any;
|
|
162
169
|
}, string, import("vue").PublicProps, Readonly<DatePickerProps> & Readonly<{
|
|
163
170
|
"onUpdate:modelValue"?: ((value: DateValue | DateRange | Time | undefined) => any) | undefined;
|
|
164
171
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
165
|
-
"onUpdate:view"?: ((view: "
|
|
172
|
+
"onUpdate:view"?: ((view: "date" | "month" | "year") => any) | undefined;
|
|
166
173
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
167
174
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
168
175
|
declare const _default: typeof __VLS_export;
|
|
@@ -34,6 +34,8 @@ import DatePickerCalendarBody from "../internal/DatePickerCalendarBody.vue";
|
|
|
34
34
|
import DatePickerRangeCalendarBody from "../internal/DatePickerRangeCalendarBody.vue";
|
|
35
35
|
import DatePickerTimeBody from "../internal/DatePickerTimeBody.vue";
|
|
36
36
|
import { datePickerTheme } from "../theme/date-picker";
|
|
37
|
+
import { arrowContentProps, arrowElementProps } from "../utils/arrow";
|
|
38
|
+
import { overlayPortalProps } from "../utils/overlay";
|
|
37
39
|
import { resolveRegisteredColorRole } from "../utils/registered-colors";
|
|
38
40
|
import { applyClassPrefix, resolveSlot, useComponentTheme, useRootProps, useThemeBindings } from "../utils/ui";
|
|
39
41
|
import Button from "./Button.vue";
|
|
@@ -81,7 +83,9 @@ const props = defineProps({
|
|
|
81
83
|
color: { type: null, required: false, default: "neutral" },
|
|
82
84
|
activeColor: { type: null, required: false, default: "primary" },
|
|
83
85
|
size: { type: null, required: false },
|
|
84
|
-
arrow: { type: Boolean, required: false, default: false },
|
|
86
|
+
arrow: { type: [Boolean, Object], required: false, default: false },
|
|
87
|
+
positioning: { type: Object, required: false },
|
|
88
|
+
portal: { type: [Boolean, String], required: false, skipCheck: true, default: void 0 },
|
|
85
89
|
adaptive: { type: Boolean, required: false },
|
|
86
90
|
ui: { type: Object, required: false }
|
|
87
91
|
});
|
|
@@ -360,8 +364,9 @@ const rootProps = useRootProps(() => ui.value.root, () => props.ui?.root);
|
|
|
360
364
|
const fieldProps = computed(() => resolveSlot(ui.value.field, props.ui?.field));
|
|
361
365
|
const segmentProps = computed(() => resolveSlot(ui.value.segment, props.ui?.segment));
|
|
362
366
|
const separatorProps = computed(() => resolveSlot(ui.value.separator, props.ui?.separator));
|
|
363
|
-
const contentProps = computed(() => resolveSlot(ui.value.content, props.ui?.content));
|
|
364
|
-
const
|
|
367
|
+
const contentProps = computed(() => ({ ...resolveSlot(ui.value.content, props.ui?.content), ...arrowContentProps(props.arrow), ...props.positioning }));
|
|
368
|
+
const portalProps = computed(() => overlayPortalProps(props.portal));
|
|
369
|
+
const arrowProps = computed(() => ({ ...resolveSlot(ui.value.arrow, props.ui?.arrow), ...arrowElementProps(props.arrow) }));
|
|
365
370
|
const headerProps = computed(() => resolveSlot(ui.value.header, props.ui?.header));
|
|
366
371
|
const headingProps = computed(() => resolveSlot(ui.value.heading, props.ui?.heading));
|
|
367
372
|
const gridsProps = computed(() => resolveSlot(ui.value.grids, props.ui?.grids));
|
|
@@ -492,7 +497,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
492
497
|
@update:model-value="(value) => updateModelValue(value)"
|
|
493
498
|
>
|
|
494
499
|
<DateRangePickerAnchor as-child>
|
|
495
|
-
<div v-if="triggerMode === 'field'" :data-selaras-color="fieldColor" :aria-invalid="datePickerInvalid || void 0" :aria-describedby="describedBy" v-bind="fieldProps" :aria-labelledby="field?.labelId">
|
|
500
|
+
<div v-if="triggerMode === 'field'" data-selaras-field-segmented :data-selaras-color="fieldColor" :data-selaras-field-filled="hasValue ? '' : void 0" :data-selaras-field-active="open ? '' : void 0" :aria-invalid="datePickerInvalid || void 0" :aria-describedby="describedBy" v-bind="fieldProps" :aria-labelledby="field?.labelId">
|
|
496
501
|
<DateRangePickerField v-slot="{ segments }" :aria-labelledby="field?.labelId" :aria-describedby="describedBy" :aria-invalid="datePickerInvalid || void 0">
|
|
497
502
|
<template v-for="segment in segments.start" :key="`start-${segment.part}`">
|
|
498
503
|
<DateRangePickerInput as="span" type="start" :part="segment.part" v-bind="segmentProps">
|
|
@@ -533,9 +538,10 @@ const buttonTriggerUi = computed(() => ({
|
|
|
533
538
|
</div>
|
|
534
539
|
</div>
|
|
535
540
|
|
|
536
|
-
<div v-else :class="applyClassPrefix('relative inline-block w-full')">
|
|
541
|
+
<div v-else :class="applyClassPrefix('relative inline-block w-full')" :data-selaras-field-filled="hasValue ? '' : void 0" :data-selaras-field-active="open ? '' : void 0">
|
|
537
542
|
<DateRangePickerTrigger as-child>
|
|
538
543
|
<Button
|
|
544
|
+
:id="datePickerId"
|
|
539
545
|
variant="text"
|
|
540
546
|
:color="color"
|
|
541
547
|
:size="effectiveSize"
|
|
@@ -544,7 +550,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
544
550
|
:aria-labelledby="field?.labelId"
|
|
545
551
|
:ui="buttonTriggerUi"
|
|
546
552
|
>
|
|
547
|
-
{{ hasValue ? formattedValue : messages.pickDate }}
|
|
553
|
+
{{ hasValue ? formattedValue : field?.floatingLabel.value ? "" : messages.pickDate }}
|
|
548
554
|
<template v-if="!(clearable && hasValue)" #trailing-icon="{ class: iconClass }">
|
|
549
555
|
<slot name="trigger-icon">
|
|
550
556
|
<Icon :name="icons.calendar" :class="iconClass" />
|
|
@@ -570,7 +576,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
570
576
|
</div>
|
|
571
577
|
</DateRangePickerAnchor>
|
|
572
578
|
|
|
573
|
-
<DateRangePickerContent v-if="!showMobileModal" :side-offset="6" align="start" :data-selaras-theme="themeBindings['data-selaras-theme']" :data-selaras-mode="themeBindings['data-selaras-mode']" :style="themeBindings.style" v-bind="contentProps">
|
|
579
|
+
<DateRangePickerContent v-if="!showMobileModal" :side-offset="6" align="start" :portal="portalProps" :data-selaras-theme="themeBindings['data-selaras-theme']" :data-selaras-mode="themeBindings['data-selaras-mode']" :style="themeBindings.style" v-bind="contentProps">
|
|
574
580
|
<DatePickerRangeCalendarBody v-bind="rangeBodyProps">
|
|
575
581
|
<template #day="scope">
|
|
576
582
|
<slot name="day" v-bind="scope" />
|
|
@@ -610,7 +616,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
610
616
|
|
|
611
617
|
<PopoverRoot v-else-if="timeOnly" :open="open" :data-selaras-color="fieldColor" @update:open="onUpdateOpen">
|
|
612
618
|
<PopoverAnchor as-child>
|
|
613
|
-
<div v-if="triggerMode === 'field'" :data-selaras-color="fieldColor" :aria-invalid="datePickerInvalid || void 0" :aria-describedby="describedBy" v-bind="fieldProps" :aria-labelledby="field?.labelId">
|
|
619
|
+
<div v-if="triggerMode === 'field'" data-selaras-field-segmented :data-selaras-color="fieldColor" :data-selaras-field-filled="hasValue ? '' : void 0" :data-selaras-field-active="open ? '' : void 0" :aria-invalid="datePickerInvalid || void 0" :aria-describedby="describedBy" v-bind="fieldProps" :aria-labelledby="field?.labelId">
|
|
614
620
|
<TimeFieldRoot
|
|
615
621
|
:id="datePickerId"
|
|
616
622
|
v-slot="{ segments }"
|
|
@@ -660,9 +666,10 @@ const buttonTriggerUi = computed(() => ({
|
|
|
660
666
|
</div>
|
|
661
667
|
</div>
|
|
662
668
|
|
|
663
|
-
<div v-else :class="applyClassPrefix('relative inline-block w-full')">
|
|
669
|
+
<div v-else :class="applyClassPrefix('relative inline-block w-full')" :data-selaras-field-filled="hasValue ? '' : void 0" :data-selaras-field-active="open ? '' : void 0">
|
|
664
670
|
<PopoverTrigger as-child>
|
|
665
671
|
<Button
|
|
672
|
+
:id="datePickerId"
|
|
666
673
|
variant="text"
|
|
667
674
|
:color="color"
|
|
668
675
|
:size="effectiveSize"
|
|
@@ -671,7 +678,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
671
678
|
:aria-labelledby="field?.labelId"
|
|
672
679
|
:ui="buttonTriggerUi"
|
|
673
680
|
>
|
|
674
|
-
{{ hasValue ? formattedTimeValue : messages.pickTime }}
|
|
681
|
+
{{ hasValue ? formattedTimeValue : field?.floatingLabel.value ? "" : messages.pickTime }}
|
|
675
682
|
<template v-if="!(clearable && hasValue)" #trailing-icon="{ class: iconClass }">
|
|
676
683
|
<slot name="trigger-icon">
|
|
677
684
|
<Icon :name="icons.clock" :class="iconClass" />
|
|
@@ -697,7 +704,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
697
704
|
</div>
|
|
698
705
|
</PopoverAnchor>
|
|
699
706
|
|
|
700
|
-
<PopoverPortal v-if="!showMobileModal">
|
|
707
|
+
<PopoverPortal v-if="!showMobileModal" v-bind="portalProps">
|
|
701
708
|
<PopoverContent :side-offset="6" align="start" :data-selaras-theme="themeBindings['data-selaras-theme']" :data-selaras-mode="themeBindings['data-selaras-mode']" :style="themeBindings.style" v-bind="contentProps">
|
|
702
709
|
<DatePickerTimeBody v-bind="timeBodyProps">
|
|
703
710
|
<template #footer>
|
|
@@ -753,7 +760,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
753
760
|
@update:model-value="(value) => updateModelValue(normalizeForGranularity(value))"
|
|
754
761
|
>
|
|
755
762
|
<DatePickerAnchor as-child>
|
|
756
|
-
<div v-if="triggerMode === 'field'" :data-selaras-color="fieldColor" :aria-invalid="datePickerInvalid || void 0" :aria-describedby="describedBy" v-bind="fieldProps" :aria-labelledby="field?.labelId">
|
|
763
|
+
<div v-if="triggerMode === 'field'" data-selaras-field-segmented :data-selaras-color="fieldColor" :data-selaras-field-filled="hasValue ? '' : void 0" :data-selaras-field-active="open ? '' : void 0" :aria-invalid="datePickerInvalid || void 0" :aria-describedby="describedBy" v-bind="fieldProps" :aria-labelledby="field?.labelId">
|
|
757
764
|
<DatePickerField v-slot="{ segments }" :aria-labelledby="field?.labelId" :aria-describedby="describedBy" :aria-invalid="datePickerInvalid || void 0">
|
|
758
765
|
<template v-for="(segment, index) in visibleSegments(segments)" :key="`${segment.part}-${index}`">
|
|
759
766
|
<DatePickerInput as="span" :part="segment.part" v-bind="segmentProps">
|
|
@@ -788,9 +795,10 @@ const buttonTriggerUi = computed(() => ({
|
|
|
788
795
|
</div>
|
|
789
796
|
</div>
|
|
790
797
|
|
|
791
|
-
<div v-else :class="applyClassPrefix('relative inline-block w-full')">
|
|
798
|
+
<div v-else :class="applyClassPrefix('relative inline-block w-full')" :data-selaras-field-filled="hasValue ? '' : void 0" :data-selaras-field-active="open ? '' : void 0">
|
|
792
799
|
<DatePickerTrigger as-child>
|
|
793
800
|
<Button
|
|
801
|
+
:id="datePickerId"
|
|
794
802
|
variant="text"
|
|
795
803
|
:color="color"
|
|
796
804
|
:size="effectiveSize"
|
|
@@ -799,7 +807,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
799
807
|
:aria-labelledby="field?.labelId"
|
|
800
808
|
:ui="buttonTriggerUi"
|
|
801
809
|
>
|
|
802
|
-
{{ hasValue ? formattedValue : messages.pickDate }}
|
|
810
|
+
{{ hasValue ? formattedValue : field?.floatingLabel.value ? "" : messages.pickDate }}
|
|
803
811
|
<template v-if="!(clearable && hasValue)" #trailing-icon="{ class: iconClass }">
|
|
804
812
|
<slot name="trigger-icon">
|
|
805
813
|
<Icon :name="icons.calendar" :class="iconClass" />
|
|
@@ -832,7 +840,7 @@ const buttonTriggerUi = computed(() => ({
|
|
|
832
840
|
center without clipping, so it silently hides instead. Centering the
|
|
833
841
|
panel on the trigger only when `arrow` is on sidesteps that without
|
|
834
842
|
changing the default (start-aligned) layout everyone already sees. -->
|
|
835
|
-
<DatePickerContent v-if="!showMobileModal" :side-offset="6" :align="arrow ? 'center' : 'start'" :data-selaras-theme="themeBindings['data-selaras-theme']" :data-selaras-mode="themeBindings['data-selaras-mode']" :style="themeBindings.style" v-bind="contentProps">
|
|
843
|
+
<DatePickerContent v-if="!showMobileModal" :side-offset="6" :align="arrow ? 'center' : 'start'" :portal="portalProps" :data-selaras-theme="themeBindings['data-selaras-theme']" :data-selaras-mode="themeBindings['data-selaras-mode']" :style="themeBindings.style" v-bind="contentProps">
|
|
836
844
|
<DatePickerCalendarBody v-bind="calendarBodyProps">
|
|
837
845
|
<template #day="scope">
|
|
838
846
|
<slot name="day" v-bind="scope" />
|
|
@@ -862,5 +870,5 @@ const buttonTriggerUi = computed(() => ({
|
|
|
862
870
|
</template>
|
|
863
871
|
</Modal>
|
|
864
872
|
</DatePickerRoot>
|
|
865
|
-
<input ref="formAnchor" type="hidden" :name="formName" :form="form" :value="nativeFormValue">
|
|
873
|
+
<input ref="formAnchor" type="hidden" :name="formName" :form="form" :value="nativeFormValue" :disabled="disabled">
|
|
866
874
|
</template>
|