@leavepulse/ui 0.78.1 → 0.78.3

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 (147) hide show
  1. package/dist/chunks/{DropzoneLinkField-CLLhd3WB.js → DropzoneLinkField-CyE7TJ5f.js} +1 -1
  2. package/dist/chunks/LpAddressInput-ft8fQOGx.js +401 -0
  3. package/dist/chunks/{LpAppShell-BKbYCHkx.js → LpAppShell-DRHoQtr-.js} +34 -17
  4. package/dist/chunks/LpAutocomplete-CrZbd0uv.js +310 -0
  5. package/dist/chunks/LpCheckbox-CCWCwD0y.js +129 -0
  6. package/dist/chunks/{LpCodeDisplay-D3BUAhV1.js → LpCodeDisplay-D59uPwRb.js} +1 -1
  7. package/dist/chunks/LpColorPicker-BONURBFN.js +574 -0
  8. package/dist/chunks/LpDatePicker-C2AOtxgF.js +171 -0
  9. package/dist/chunks/{LpDateRangePicker-CNQXdTVv.js → LpDateRangePicker-CiXdIAyh.js} +43 -35
  10. package/dist/chunks/{LpFileTree-C-rJKzEQ.js → LpFileTree-CpNurwZp.js} +2 -2
  11. package/dist/chunks/{LpFileTreeNode-BgYn4U1J.js → LpFileTreeNode-DdF8Cq-s.js} +1 -1
  12. package/dist/chunks/{LpInput-D0O6dpuA.js → LpInput-CbI7z5fQ.js} +3 -4
  13. package/dist/chunks/{LpLogInspector-BdQlX6S-.js → LpLogInspector-CcSJSGan.js} +1 -1
  14. package/dist/chunks/{LpLogViewer-umCZBapN.js → LpLogViewer-CWu49Dko.js} +2 -2
  15. package/dist/chunks/{LpModalNav-gOi1Giz1.js → LpModalNav-DI3BW5ff.js} +1 -1
  16. package/dist/chunks/LpNumberField-C8LfUz_R.js +154 -0
  17. package/dist/chunks/LpOtpInput-B1X9l9no.js +140 -0
  18. package/dist/chunks/{LpPaletteTheme-BIXpZLGe.js → LpPaletteTheme-B-xuZiKK.js} +2 -2
  19. package/dist/chunks/{LpPasswordInput-D4HPhqfV.js → LpPasswordInput-Duc_3wPv.js} +1 -1
  20. package/dist/chunks/{LpPhoneInput-BSL7NX4z.js → LpPhoneInput-CctcRK9K.js} +124 -118
  21. package/dist/chunks/LpRadioGroup-DTM0nd9G.js +103 -0
  22. package/dist/chunks/LpRangeSlider-DJsEZXad.js +97 -0
  23. package/dist/chunks/LpRepeater-Czib3rmv.js +193 -0
  24. package/dist/chunks/{LpSecretField-B2roc4Iz.js → LpSecretField-BtlCk3IH.js} +1 -1
  25. package/dist/chunks/LpSegmented-sskrJKJJ.js +128 -0
  26. package/dist/chunks/LpSelect-JFZehOkd.js +515 -0
  27. package/dist/chunks/{LpSidebar-DDNJzb69.js → LpSidebar-CvRvVBTt.js} +1 -1
  28. package/dist/chunks/LpSlider-C4ilCtZX.js +76 -0
  29. package/dist/chunks/LpSwitch-DyAYTchz.js +122 -0
  30. package/dist/chunks/{LpTableFilter-B_XMOeAh.js → LpTableFilter-CJg5eIcV.js} +2 -2
  31. package/dist/chunks/{LpTagsInput-Dt0mteSj.js → LpTagsInput-CkNxpNYa.js} +4 -3
  32. package/dist/chunks/{LpTextarea-Co0b9PVx.js → LpTextarea-CFK_5QB8.js} +3 -2
  33. package/dist/chunks/{LpThemeStudio-ChU0_Ga8.js → LpThemeStudio-R-wohbCY.js} +2 -2
  34. package/dist/chunks/{LpThemeSwitcher-DmCZ21P_.js → LpThemeSwitcher-Bzy15MCP.js} +1 -1
  35. package/dist/chunks/LpTimeField-B5n0m8m0.js +115 -0
  36. package/dist/chunks/{LpTopologyCanvas-jqz1KCq2.js → LpTopologyCanvas-BNgw9RyZ.js} +2 -2
  37. package/dist/chunks/{LpWorkspaceSwitcher-BeNHCLd5.js → LpWorkspaceSwitcher-ugv-fyig.js} +1 -1
  38. package/dist/components/DropzoneLinkField.vue.js +1 -1
  39. package/dist/components/LpAddressInput.vue.d.ts +4 -0
  40. package/dist/components/LpAddressInput.vue.js +1 -1
  41. package/dist/components/LpAlert.vue.d.ts +3 -3
  42. package/dist/components/LpAppShell.vue.d.ts +19 -1
  43. package/dist/components/LpAppShell.vue.js +1 -1
  44. package/dist/components/LpAutocomplete.vue.d.ts +4 -0
  45. package/dist/components/LpAutocomplete.vue.js +1 -1
  46. package/dist/components/LpBadge.vue.d.ts +2 -2
  47. package/dist/components/LpChart.vue.d.ts +1 -1
  48. package/dist/components/LpCheckbox.vue.d.ts +4 -0
  49. package/dist/components/LpCheckbox.vue.js +1 -1
  50. package/dist/components/LpCodeDisplay.vue.js +1 -1
  51. package/dist/components/LpCollapse.vue.d.ts +1 -1
  52. package/dist/components/LpColorPicker.vue.d.ts +5 -3
  53. package/dist/components/LpColorPicker.vue.js +1 -1
  54. package/dist/components/LpDatePicker.vue.js +1 -1
  55. package/dist/components/LpDateRangePicker.vue.js +1 -1
  56. package/dist/components/LpDropzone.vue.js +1 -1
  57. package/dist/components/LpFileTree.vue.js +1 -1
  58. package/dist/components/LpFileTreeNode.vue.js +1 -1
  59. package/dist/components/LpImageEditor.vue.d.ts +1 -1
  60. package/dist/components/LpInput.vue.js +1 -1
  61. package/dist/components/LpLogInspector.vue.js +1 -1
  62. package/dist/components/LpLogViewer.vue.js +1 -1
  63. package/dist/components/LpModalNav.vue.js +1 -1
  64. package/dist/components/LpNumberField.vue.d.ts +4 -0
  65. package/dist/components/LpNumberField.vue.js +1 -1
  66. package/dist/components/LpOtpInput.vue.d.ts +4 -0
  67. package/dist/components/LpOtpInput.vue.js +1 -1
  68. package/dist/components/LpPaletteTheme.vue.js +1 -1
  69. package/dist/components/LpPasswordInput.vue.js +1 -1
  70. package/dist/components/LpPhoneInput.vue.d.ts +4 -0
  71. package/dist/components/LpPhoneInput.vue.js +1 -1
  72. package/dist/components/LpRadioGroup.vue.d.ts +4 -0
  73. package/dist/components/LpRadioGroup.vue.js +1 -1
  74. package/dist/components/LpRangeSlider.vue.d.ts +4 -0
  75. package/dist/components/LpRangeSlider.vue.js +1 -1
  76. package/dist/components/LpRepeater.vue.d.ts +2 -0
  77. package/dist/components/LpRepeater.vue.js +1 -1
  78. package/dist/components/LpScrollArea.vue.d.ts +1 -1
  79. package/dist/components/LpSecretField.vue.js +1 -1
  80. package/dist/components/LpSegmented.vue.d.ts +4 -0
  81. package/dist/components/LpSegmented.vue.js +1 -1
  82. package/dist/components/LpSelect.vue.d.ts +2 -0
  83. package/dist/components/LpSelect.vue.js +1 -1
  84. package/dist/components/LpShinyText.vue.d.ts +1 -1
  85. package/dist/components/LpSidebar.vue.d.ts +1 -1
  86. package/dist/components/LpSidebar.vue.js +1 -1
  87. package/dist/components/LpSlider.vue.d.ts +4 -0
  88. package/dist/components/LpSlider.vue.js +1 -1
  89. package/dist/components/LpSwitch.vue.d.ts +4 -0
  90. package/dist/components/LpSwitch.vue.js +1 -1
  91. package/dist/components/LpTable.vue.js +2 -2
  92. package/dist/components/LpTableFilter.vue.js +1 -1
  93. package/dist/components/LpTabs.vue.d.ts +1 -1
  94. package/dist/components/LpTagsInput.vue.js +1 -1
  95. package/dist/components/LpTextarea.vue.js +1 -1
  96. package/dist/components/LpThemeStudio.vue.js +1 -1
  97. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  98. package/dist/components/LpTimeField.vue.d.ts +4 -0
  99. package/dist/components/LpTimeField.vue.js +1 -1
  100. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  101. package/dist/components/LpWorkspaceSwitcher.vue.js +1 -1
  102. package/dist/components/calendar.d.ts +2 -0
  103. package/dist/composables/useField.d.ts +50 -0
  104. package/dist/composables/useField.js +31 -2
  105. package/dist/composables/useMergedClass.d.ts +6 -2
  106. package/dist/composables/useMergedClass.js +6 -6
  107. package/dist/index.js +34 -34
  108. package/package.json +1 -1
  109. package/src/components/LpAddressInput.vue +8 -4
  110. package/src/components/LpAppShell.vue +56 -18
  111. package/src/components/LpAutocomplete.vue +11 -5
  112. package/src/components/LpCheckbox.vue +8 -6
  113. package/src/components/LpColorPicker.vue +7 -4
  114. package/src/components/LpDatePicker.vue +8 -4
  115. package/src/components/LpDateRangePicker.vue +8 -4
  116. package/src/components/LpInput.vue +3 -4
  117. package/src/components/LpNumberField.vue +11 -6
  118. package/src/components/LpOtpInput.vue +8 -6
  119. package/src/components/LpPhoneInput.vue +11 -6
  120. package/src/components/LpRadioGroup.vue +9 -5
  121. package/src/components/LpRangeSlider.vue +8 -4
  122. package/src/components/LpRepeater.vue +16 -4
  123. package/src/components/LpSegmented.vue +8 -4
  124. package/src/components/LpSelect.vue +8 -7
  125. package/src/components/LpSlider.vue +8 -4
  126. package/src/components/LpSwitch.vue +8 -5
  127. package/src/components/LpTagsInput.vue +4 -3
  128. package/src/components/LpTextarea.vue +3 -2
  129. package/src/components/LpTimeField.vue +8 -6
  130. package/src/components/calendar.ts +2 -0
  131. package/src/composables/useField.ts +52 -0
  132. package/src/composables/useMergedClass.ts +11 -5
  133. package/dist/chunks/LpAddressInput-BSS49jpm.js +0 -393
  134. package/dist/chunks/LpAutocomplete-DkY6CSyD.js +0 -302
  135. package/dist/chunks/LpCheckbox-D6RuDW4X.js +0 -124
  136. package/dist/chunks/LpColorPicker-COHzV68R.js +0 -567
  137. package/dist/chunks/LpDatePicker-DwSDY0mt.js +0 -163
  138. package/dist/chunks/LpNumberField-Csg-1Zh_.js +0 -148
  139. package/dist/chunks/LpOtpInput-BRpLBbOD.js +0 -132
  140. package/dist/chunks/LpRadioGroup-BrazjLY_.js +0 -95
  141. package/dist/chunks/LpRangeSlider-fz61tzc-.js +0 -89
  142. package/dist/chunks/LpRepeater-BkJHSPI1.js +0 -180
  143. package/dist/chunks/LpSegmented-DbEJhbv-.js +0 -123
  144. package/dist/chunks/LpSelect-Y-iuSymW.js +0 -512
  145. package/dist/chunks/LpSlider-A4ixovgS.js +0 -68
  146. package/dist/chunks/LpSwitch-DnC2-0aV.js +0 -115
  147. package/dist/chunks/LpTimeField-DeOcKWJq.js +0 -110
@@ -0,0 +1,515 @@
1
+ import { defineComponent, computed, ref, useAttrs, useId, reactive, watch, nextTick, openBlock, createBlock, normalizeProps, guardReactiveProps, unref, withCtx, createVNode, mergeProps, normalizeClass, createElementVNode, toDisplayString, createElementBlock, TransitionGroup, Fragment, renderList, createCommentVNode, withModifiers, createTextVNode, normalizeStyle } from "vue";
2
+ import { _ as _sfc_main$4 } from "./IconCloseButton-COZEsa9u.js";
3
+ import { CONTROL_SIZE } from "../components/controlSize.js";
4
+ import { usePaletteControl } from "../composables/usePaletteCommands.js";
5
+ import { ComboboxRoot, ComboboxAnchor, ComboboxTrigger, ComboboxPortal, ComboboxContent, ComboboxInput, ComboboxViewport, ComboboxEmpty, ComboboxItem, ComboboxItemIndicator } from "reka-ui";
6
+ import { _ as _sfc_main$1 } from "./FieldWrapper-DnuMTrqW.js";
7
+ import { useOwnField, useFieldBlur, mergeDescribedBy } from "../composables/useField.js";
8
+ import { useLabels } from "../composables/useLpConfig.js";
9
+ import { useMergedAttrs } from "../composables/useMergedClass.js";
10
+ import { POPOVER_PANEL, OPTION_ITEM, optionStagger } from "../components/dropdown.js";
11
+ import { _ as _sfc_main$2 } from "./LpIcon-C6JpQ5td.js";
12
+ import { _ as _sfc_main$5 } from "./OptionContent-CGb8QlHA.js";
13
+ import { _ as _sfc_main$3 } from "./LpRollingText-B54Pje7P.js";
14
+ import { evictOldest, fitChips, toggledValues } from "../components/select.js";
15
+ import { usePortalTarget, useOutsideGuard } from "../composables/useView.js";
16
+ import { useResizeObserver } from "../composables/useResizeObserver.js";
17
+ import { nodeWindow } from "../composables/realm.js";
18
+ const _hoisted_1 = { class: "sr-only" };
19
+ const _hoisted_2 = ["src"];
20
+ const _hoisted_3 = { class: "truncate" };
21
+ const _hoisted_4 = {
22
+ key: "lp-select-more",
23
+ "aria-hidden": "true",
24
+ class: "inline-flex shrink-0 items-center rounded-pill bg-surface-raised px-2 py-0.5 text-xs font-medium text-muted"
25
+ };
26
+ const _hoisted_5 = {
27
+ key: 0,
28
+ class: "size-4 shrink-0"
29
+ };
30
+ const _hoisted_6 = {
31
+ key: 1,
32
+ class: "ml-1 size-3 shrink-0"
33
+ };
34
+ const _hoisted_7 = { class: "truncate" };
35
+ const _hoisted_8 = { class: "inline-flex px-2 py-0.5 text-xs font-medium" };
36
+ const _hoisted_9 = { class: "flex min-w-0 items-center gap-2" };
37
+ const _hoisted_10 = ["src"];
38
+ const _hoisted_11 = {
39
+ key: 2,
40
+ class: "min-w-0 truncate text-muted"
41
+ };
42
+ const _hoisted_12 = {
43
+ key: 0,
44
+ class: "border-b border-line p-2"
45
+ };
46
+ const _hoisted_13 = {
47
+ key: 0,
48
+ class: "px-3 py-4 text-center text-sm italic text-muted"
49
+ };
50
+ const __default__ = { inheritAttrs: false };
51
+ const _sfc_main = /* @__PURE__ */ defineComponent({
52
+ ...__default__,
53
+ __name: "LpSelect",
54
+ props: {
55
+ palette: { type: [Boolean, Object], default: void 0 },
56
+ modelValue: {},
57
+ options: {},
58
+ placeholder: {},
59
+ searchPlaceholder: {},
60
+ searchable: { type: Boolean, default: false },
61
+ multiple: { type: Boolean, default: false },
62
+ clearable: { type: Boolean, default: false },
63
+ disabled: { type: Boolean, default: false },
64
+ invalid: { type: Boolean },
65
+ error: {},
66
+ emptyText: {},
67
+ searchTerm: { default: void 0 },
68
+ loading: { type: Boolean, default: false },
69
+ loadingText: {},
70
+ size: { default: "md" },
71
+ selected: {},
72
+ labels: {}
73
+ },
74
+ emits: ["update:modelValue", "change", "update:searchTerm", "blur"],
75
+ setup(__props, { emit: __emit }) {
76
+ const props = __props;
77
+ const SIZE_HEIGHT = CONTROL_SIZE;
78
+ const anchorHeight = computed(() => SIZE_HEIGHT[props.size]);
79
+ const { field, wrapper, ownAttrs } = useOwnField(() => ({ error: props.error, invalid: props.invalid, disabled: props.disabled }));
80
+ const labels = useLabels(
81
+ "select",
82
+ {
83
+ clear: "Clear",
84
+ selected: "{count} selected",
85
+ placeholder: "Select…",
86
+ search: "Search…",
87
+ searchLabel: "Search options",
88
+ empty: "Nothing found",
89
+ loading: "Searching…"
90
+ },
91
+ () => props.labels
92
+ );
93
+ const placeholderText = computed(() => props.placeholder ?? labels.value.placeholder);
94
+ const searchPlaceholderText = computed(() => props.searchPlaceholder ?? labels.value.search);
95
+ const emptyLabel = computed(() => props.emptyText ?? labels.value.empty);
96
+ const loadingLabel = computed(() => props.loadingText ?? labels.value.loading);
97
+ const { class: rootClass, attrs: rootAttrs } = useMergedAttrs("relative", ownAttrs);
98
+ const emit = __emit;
99
+ const serverSide = computed(() => props.searchTerm !== void 0);
100
+ const localQuery = ref("");
101
+ const query = computed({
102
+ get: () => serverSide.value ? props.searchTerm ?? "" : localQuery.value,
103
+ set: (v) => {
104
+ if (serverSide.value) emit("update:searchTerm", v);
105
+ else localQuery.value = v;
106
+ }
107
+ });
108
+ const isOpen = ref(false);
109
+ function onOpenChange(open) {
110
+ isOpen.value = open;
111
+ query.value = "";
112
+ }
113
+ async function openFromKeyboard(event) {
114
+ if (field.value.disabled || isOpen.value || !["ArrowDown", "ArrowUp"].includes(event.key)) return;
115
+ event.preventDefault();
116
+ event.stopPropagation();
117
+ const trigger = event.currentTarget;
118
+ trigger.click();
119
+ await nextTick();
120
+ const panel = trigger.ownerDocument.getElementById(trigger.getAttribute("aria-controls") ?? "");
121
+ const search = panel?.querySelector("input:not([disabled])");
122
+ const items = panel?.querySelectorAll('[role="option"]:not([data-disabled])');
123
+ const selected = panel?.querySelector('[role="option"][aria-selected="true"]:not([data-disabled])');
124
+ const target = search ?? selected ?? (event.key === "ArrowUp" ? items?.[items.length - 1] : items?.[0]);
125
+ if (isOpen.value) target?.focus();
126
+ }
127
+ const LIST_KEYS = ["ArrowDown", "ArrowUp", "Home", "End", "Enter"];
128
+ function moveInList(event) {
129
+ if (props.searchable || serverSide.value || !LIST_KEYS.includes(event.key)) return;
130
+ const list = event.currentTarget;
131
+ const items = Array.from(list.querySelectorAll('[role="option"]:not([data-disabled])'));
132
+ if (!items.length) return;
133
+ event.preventDefault();
134
+ event.stopPropagation();
135
+ const at = items.indexOf(list.ownerDocument.activeElement);
136
+ if (event.key === "Enter") {
137
+ items[at]?.click();
138
+ return;
139
+ }
140
+ const last = items.length - 1;
141
+ const next = {
142
+ ArrowDown: at === last ? 0 : at + 1,
143
+ ArrowUp: at <= 0 ? last : at - 1,
144
+ Home: 0,
145
+ End: last
146
+ }[event.key];
147
+ items[next ?? 0]?.focus();
148
+ }
149
+ const { partId, onFocusOut } = useFieldBlur((event) => emit("blur", event));
150
+ const triggerRef = ref(null);
151
+ function onListFocusOut(event) {
152
+ const trigger = triggerRef.value?.$el;
153
+ if (isOpen.value || event.relatedTarget || !trigger?.isConnected) {
154
+ onFocusOut(event);
155
+ return;
156
+ }
157
+ trigger.focus({ preventScroll: true });
158
+ }
159
+ const attrs = useAttrs();
160
+ const valueId = `lp-select-${useId()}-value`;
161
+ const valueText = computed(() => chips.value.length ? chipNames.value : displayLabel.value || placeholderText.value);
162
+ const triggerName = computed(
163
+ () => field.value.labelId ? { "aria-labelledby": `${field.value.labelId} ${valueId}`, "aria-label": void 0 } : { "aria-label": [attrs["aria-label"], valueText.value].filter(Boolean).join(", ") }
164
+ );
165
+ const EMPTY_SENTINEL = "\0__lp_empty__";
166
+ function encode(v) {
167
+ return v === "" ? EMPTY_SENTINEL : v;
168
+ }
169
+ function decode(v) {
170
+ return v === EMPTY_SENTINEL ? "" : v;
171
+ }
172
+ const hasEmptyOption = computed(
173
+ () => props.options.some((o) => o.value === "")
174
+ );
175
+ const comboModel = computed(() => {
176
+ const v = props.modelValue;
177
+ if (Array.isArray(v)) return v.map((item) => encode(item));
178
+ if (v === "" && !hasEmptyOption.value) return void 0;
179
+ return encode(v);
180
+ });
181
+ const filtered = computed(() => {
182
+ if (serverSide.value) return props.options;
183
+ const q = query.value.trim().toLowerCase();
184
+ if (!props.searchable || !q) return props.options;
185
+ return props.options.filter(
186
+ (o) => o.label.toLowerCase().includes(q) || o.description?.toLowerCase().includes(q)
187
+ );
188
+ });
189
+ const remembered = reactive(/* @__PURE__ */ new Map());
190
+ const REMEMBERED_LIMIT = 500;
191
+ function fromOption(o) {
192
+ return { label: o.label, hint: o.description, image: o.image, icon: o.icon };
193
+ }
194
+ function remember(values) {
195
+ for (const v of values) {
196
+ const o = props.options.find((x) => x.value === v);
197
+ if (o) remembered.set(v, fromOption(o));
198
+ }
199
+ evictOldest(remembered, new Set(values), REMEMBERED_LIMIT);
200
+ }
201
+ const modelList = computed(() => {
202
+ const v = props.modelValue;
203
+ if (Array.isArray(v)) return v;
204
+ return v === void 0 || v === "" && !hasEmptyOption.value ? [] : [v];
205
+ });
206
+ watch([modelList, () => props.options], ([values]) => remember(values), { immediate: true });
207
+ function shown(v, index) {
208
+ const sel = props.selected;
209
+ const given = Array.isArray(sel) ? sel[index] : index === 0 ? sel : void 0;
210
+ if (given?.label) return given;
211
+ const o = props.options.find((x) => x.value === v);
212
+ return o ? fromOption(o) : remembered.get(v);
213
+ }
214
+ const current = computed(() => {
215
+ if (props.multiple) return void 0;
216
+ const v = modelList.value[0];
217
+ return v === void 0 ? void 0 : shown(v, 0);
218
+ });
219
+ const chips = computed(
220
+ () => props.multiple ? modelList.value.flatMap((value, i) => {
221
+ const s = shown(value, i);
222
+ return s ? [{ value, ...s }] : [];
223
+ }) : []
224
+ );
225
+ const displayLabel = computed(() => {
226
+ if (props.multiple) {
227
+ const count = modelList.value.length;
228
+ return count ? labels.value.selected.replace("{count}", String(count)) : "";
229
+ }
230
+ return current.value?.label ?? "";
231
+ });
232
+ const rollKey = computed(() => {
233
+ const c = current.value;
234
+ return c ? [c.label, c.hint ?? "", c.image ?? c.icon ?? ""].join("\0") : `\0${placeholderText.value}`;
235
+ });
236
+ const chipRow = ref(null);
237
+ const probeRow = ref(null);
238
+ const fit = ref(Number.POSITIVE_INFINITY);
239
+ function measure() {
240
+ const row = chipRow.value;
241
+ const probe = probeRow.value;
242
+ if (!row || !probe) return;
243
+ const kids = Array.from(probe.children);
244
+ const more = kids.pop();
245
+ const gap = Number.parseFloat(nodeWindow(probe).getComputedStyle(probe).columnGap) || 0;
246
+ fit.value = fitChips(
247
+ kids.map((k) => k.offsetWidth),
248
+ row.clientWidth,
249
+ gap,
250
+ more?.offsetWidth ?? 0
251
+ );
252
+ }
253
+ useResizeObserver(chipRow, () => measure());
254
+ useResizeObserver(probeRow, () => measure());
255
+ watch(chips, () => void nextTick(measure), { flush: "post", deep: true });
256
+ const shownChips = computed(() => chips.value.slice(0, fit.value));
257
+ const hiddenCount = computed(() => modelList.value.length - shownChips.value.length);
258
+ const chipNames = computed(() => {
259
+ const names = chips.value.map((c) => c.label);
260
+ const unnamed = modelList.value.length - names.length;
261
+ if (unnamed) names.push(labels.value.selected.replace("{count}", String(unnamed)));
262
+ return names.join(", ");
263
+ });
264
+ const hasValue = computed(() => modelList.value.length > 0);
265
+ function onUpdate(value) {
266
+ const decoded = Array.isArray(value) ? value.map((item) => decode(item)) : decode(value);
267
+ remember(Array.isArray(decoded) ? decoded : [decoded]);
268
+ const previous = modelList.value;
269
+ emit("update:modelValue", decoded);
270
+ if (!Array.isArray(decoded)) {
271
+ emit("change", decoded);
272
+ return;
273
+ }
274
+ for (const v of toggledValues(previous, decoded)) emit("change", v);
275
+ }
276
+ function clear() {
277
+ if (field.value.disabled) return;
278
+ emit("update:modelValue", props.multiple ? [] : void 0);
279
+ }
280
+ const portalTo = usePortalTarget();
281
+ const guardOutside = useOutsideGuard();
282
+ usePaletteControl({ disabled: () => field.value.disabled, invalid: () => field.value.invalid, editorProps: () => ({ selected: props.multiple ? modelList.value.map((value, index) => shown(value, index)) : current.value }) });
283
+ return (_ctx, _cache) => {
284
+ return openBlock(), createBlock(_sfc_main$1, normalizeProps(guardReactiveProps(unref(wrapper))), {
285
+ default: withCtx(() => [
286
+ createVNode(unref(ComboboxRoot), mergeProps({
287
+ "model-value": comboModel.value,
288
+ multiple: __props.multiple,
289
+ disabled: unref(field).disabled,
290
+ required: unref(field).required,
291
+ "ignore-filter": true,
292
+ "reset-search-term-on-select": false,
293
+ "reset-search-term-on-blur": false,
294
+ class: unref(rootClass)
295
+ }, unref(rootAttrs), {
296
+ "onUpdate:modelValue": onUpdate,
297
+ "onUpdate:open": onOpenChange
298
+ }), {
299
+ default: withCtx(() => [
300
+ createVNode(unref(ComboboxAnchor), {
301
+ "data-lp-field-part": unref(partId),
302
+ onFocusout: unref(onFocusOut),
303
+ class: normalizeClass([
304
+ anchorHeight.value,
305
+ "group flex w-full items-center gap-2 rounded-control border bg-surface-soft px-3 text-ink transition-colors duration-[var(--duration-fast)] focus-within:ring-2",
306
+ unref(field).disabled && "cursor-not-allowed opacity-55",
307
+ unref(field).invalid ? "border-danger focus-within:border-danger focus-within:ring-danger-soft" : "border-line focus-within:border-brand focus-within:ring-ring"
308
+ ])
309
+ }, {
310
+ default: withCtx(() => [
311
+ createElementVNode("span", {
312
+ id: valueId,
313
+ hidden: ""
314
+ }, toDisplayString(valueText.value), 1),
315
+ createVNode(unref(ComboboxTrigger), mergeProps({
316
+ ref_key: "triggerRef",
317
+ ref: triggerRef,
318
+ id: unref(field).id,
319
+ tabindex: unref(field).disabled ? -1 : 0,
320
+ onKeydown: openFromKeyboard
321
+ }, triggerName.value, {
322
+ "aria-invalid": unref(field).invalid || void 0,
323
+ "aria-describedby": unref(mergeDescribedBy)(unref(rootAttrs)["aria-describedby"], unref(field).describedBy),
324
+ class: "flex min-w-0 flex-1 items-center gap-2 outline-none"
325
+ }), {
326
+ default: withCtx(() => [
327
+ chips.value.length ? (openBlock(), createElementBlock("span", {
328
+ key: 0,
329
+ ref_key: "chipRow",
330
+ ref: chipRow,
331
+ class: "relative flex min-w-0 flex-1 items-center gap-1 overflow-hidden"
332
+ }, [
333
+ createElementVNode("span", _hoisted_1, toDisplayString(chipNames.value), 1),
334
+ createVNode(TransitionGroup, {
335
+ "enter-active-class": "animate-[chip-in_var(--duration-fast)_var(--ease-emphasized)] motion-reduce:animate-none",
336
+ "leave-active-class": "animate-[chip-out_var(--duration-fast)_ease] motion-reduce:animate-none"
337
+ }, {
338
+ default: withCtx(() => [
339
+ (openBlock(true), createElementBlock(Fragment, null, renderList(shownChips.value, (chip, i) => {
340
+ return openBlock(), createElementBlock("span", {
341
+ key: String(chip.value),
342
+ "aria-hidden": "true",
343
+ class: normalizeClass(["inline-flex max-w-40 min-w-0 items-center gap-1 rounded-pill bg-surface-raised py-0.5 pr-2 text-xs font-medium text-ink", [chip.image || chip.icon ? "pl-0.5" : "pl-2", i === shownChips.value.length - 1 ? "" : "shrink-0"]])
344
+ }, [
345
+ chip.image ? (openBlock(), createElementBlock("img", {
346
+ key: 0,
347
+ src: chip.image,
348
+ alt: "",
349
+ class: "size-4 shrink-0 rounded-full object-cover"
350
+ }, null, 8, _hoisted_2)) : chip.icon ? (openBlock(), createBlock(_sfc_main$2, {
351
+ key: 1,
352
+ name: chip.icon,
353
+ size: 12,
354
+ class: "ml-1 shrink-0 text-muted"
355
+ }, null, 8, ["name"])) : createCommentVNode("", true),
356
+ createElementVNode("span", _hoisted_3, toDisplayString(chip.label), 1)
357
+ ], 2);
358
+ }), 128)),
359
+ hiddenCount.value ? (openBlock(), createElementBlock("span", _hoisted_4, [
360
+ createVNode(_sfc_main$3, {
361
+ value: `+${hiddenCount.value}`
362
+ }, null, 8, ["value"])
363
+ ])) : createCommentVNode("", true)
364
+ ]),
365
+ _: 1
366
+ }),
367
+ createElementVNode("span", {
368
+ ref_key: "probeRow",
369
+ ref: probeRow,
370
+ "aria-hidden": "true",
371
+ class: "pointer-events-none invisible absolute top-0 left-0 flex w-max gap-1"
372
+ }, [
373
+ (openBlock(true), createElementBlock(Fragment, null, renderList(chips.value, (chip) => {
374
+ return openBlock(), createElementBlock("span", {
375
+ key: String(chip.value),
376
+ class: normalizeClass(["inline-flex max-w-40 items-center gap-1 rounded-pill py-0.5 pr-2 text-xs font-medium", chip.image || chip.icon ? "pl-0.5" : "pl-2"])
377
+ }, [
378
+ chip.image ? (openBlock(), createElementBlock("span", _hoisted_5)) : chip.icon ? (openBlock(), createElementBlock("span", _hoisted_6)) : createCommentVNode("", true),
379
+ createElementVNode("span", _hoisted_7, toDisplayString(chip.label), 1)
380
+ ], 2);
381
+ }), 128)),
382
+ createElementVNode("span", _hoisted_8, "+" + toDisplayString(modelList.value.length), 1)
383
+ ], 512)
384
+ ], 512)) : (openBlock(), createBlock(_sfc_main$3, {
385
+ key: 1,
386
+ value: rollKey.value,
387
+ align: "start",
388
+ class: "min-w-0 flex-1"
389
+ }, {
390
+ default: withCtx(() => [
391
+ createElementVNode("span", _hoisted_9, [
392
+ current.value?.image ? (openBlock(), createElementBlock("img", {
393
+ key: 0,
394
+ src: current.value.image,
395
+ alt: "",
396
+ class: "block size-5 shrink-0 rounded-full object-cover"
397
+ }, null, 8, _hoisted_10)) : current.value?.icon ? (openBlock(), createBlock(_sfc_main$2, {
398
+ key: 1,
399
+ name: current.value.icon,
400
+ size: 16,
401
+ class: "block shrink-0 text-muted"
402
+ }, null, 8, ["name"])) : createCommentVNode("", true),
403
+ createElementVNode("span", {
404
+ class: normalizeClass(["min-w-0 truncate", displayLabel.value ? "" : "text-muted"])
405
+ }, toDisplayString(displayLabel.value || placeholderText.value), 3),
406
+ current.value?.hint ? (openBlock(), createElementBlock("span", _hoisted_11, toDisplayString(current.value.hint), 1)) : createCommentVNode("", true)
407
+ ])
408
+ ]),
409
+ _: 1
410
+ }, 8, ["value"]))
411
+ ]),
412
+ _: 1
413
+ }, 16, ["id", "tabindex", "aria-invalid", "aria-describedby"]),
414
+ __props.clearable && hasValue.value && !unref(field).disabled ? (openBlock(), createBlock(_sfc_main$4, {
415
+ key: 0,
416
+ inline: "",
417
+ label: unref(labels).clear,
418
+ onPointerdown: _cache[0] || (_cache[0] = withModifiers(() => {
419
+ }, ["prevent"])),
420
+ onClick: clear
421
+ }, null, 8, ["label"])) : createCommentVNode("", true),
422
+ createVNode(unref(ComboboxTrigger), {
423
+ tabindex: "-1",
424
+ "aria-hidden": "true",
425
+ class: "group/trig flex shrink-0 items-center text-muted transition-[rotate,color] duration-200 ease-[var(--ease-emphasized)] group-hover:text-ink data-[state=open]:rotate-180"
426
+ }, {
427
+ default: withCtx(() => [
428
+ createVNode(_sfc_main$2, {
429
+ name: "lucide:chevron-down",
430
+ size: 16,
431
+ class: "transition-transform duration-200 ease-[var(--ease-emphasized)] group-data-[state=closed]/trig:group-hover:translate-y-1"
432
+ })
433
+ ]),
434
+ _: 1
435
+ })
436
+ ]),
437
+ _: 1
438
+ }, 8, ["data-lp-field-part", "onFocusout", "class"]),
439
+ createVNode(unref(ComboboxPortal), { to: unref(portalTo) }, {
440
+ default: withCtx(() => [
441
+ createVNode(unref(ComboboxContent), {
442
+ "data-lp-field-part": unref(partId),
443
+ onFocusout: onListFocusOut,
444
+ onKeydownCapture: moveInList,
445
+ onInteractOutside: unref(guardOutside),
446
+ onEscapeKeyDown: unref(guardOutside),
447
+ position: "popper",
448
+ "side-offset": 6,
449
+ class: normalizeClass([unref(POPOVER_PANEL), "z-(--z-popover) max-h-72 w-(--reka-combobox-trigger-width) overflow-hidden"])
450
+ }, {
451
+ default: withCtx(() => [
452
+ __props.searchable || serverSide.value ? (openBlock(), createElementBlock("div", _hoisted_12, [
453
+ createVNode(unref(ComboboxInput), {
454
+ modelValue: query.value,
455
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => query.value = $event),
456
+ placeholder: searchPlaceholderText.value,
457
+ "aria-label": unref(labels).searchLabel,
458
+ class: "h-(--size-control-sm) w-full rounded-md border border-line bg-surface-soft px-2.5 text-sm text-ink outline-none placeholder:text-muted focus:border-brand"
459
+ }, null, 8, ["modelValue", "placeholder", "aria-label"])
460
+ ])) : createCommentVNode("", true),
461
+ createVNode(unref(ComboboxViewport), { class: "max-h-56 overflow-y-auto p-1" }, {
462
+ default: withCtx(() => [
463
+ __props.loading ? (openBlock(), createElementBlock("div", _hoisted_13, toDisplayString(loadingLabel.value), 1)) : (openBlock(), createBlock(unref(ComboboxEmpty), {
464
+ key: 1,
465
+ class: "px-3 py-4 text-center text-sm italic text-muted"
466
+ }, {
467
+ default: withCtx(() => [
468
+ createTextVNode(toDisplayString(emptyLabel.value), 1)
469
+ ]),
470
+ _: 1
471
+ })),
472
+ (openBlock(true), createElementBlock(Fragment, null, renderList(filtered.value, (opt, i) => {
473
+ return openBlock(), createBlock(unref(ComboboxItem), {
474
+ key: String(opt.value),
475
+ value: encode(opt.value),
476
+ disabled: opt.disabled,
477
+ style: normalizeStyle(unref(optionStagger)(i)),
478
+ class: normalizeClass([unref(OPTION_ITEM), "justify-between data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50"])
479
+ }, {
480
+ default: withCtx(() => [
481
+ createVNode(_sfc_main$5, { option: opt }, null, 8, ["option"]),
482
+ createVNode(unref(ComboboxItemIndicator), { class: "flex shrink-0 items-center text-brand" }, {
483
+ default: withCtx(() => [
484
+ createVNode(_sfc_main$2, {
485
+ name: "lucide:check",
486
+ size: 16
487
+ })
488
+ ]),
489
+ _: 1
490
+ })
491
+ ]),
492
+ _: 2
493
+ }, 1032, ["value", "disabled", "style", "class"]);
494
+ }), 128))
495
+ ]),
496
+ _: 1
497
+ })
498
+ ]),
499
+ _: 1
500
+ }, 8, ["data-lp-field-part", "onInteractOutside", "onEscapeKeyDown", "class"])
501
+ ]),
502
+ _: 1
503
+ }, 8, ["to"])
504
+ ]),
505
+ _: 1
506
+ }, 16, ["model-value", "multiple", "disabled", "required", "class"])
507
+ ]),
508
+ _: 1
509
+ }, 16);
510
+ };
511
+ }
512
+ });
513
+ export {
514
+ _sfc_main as _
515
+ };
@@ -6,7 +6,7 @@ import { usePersisted } from "../composables/usePersisted.js";
6
6
  import { useLabels } from "../composables/useLpConfig.js";
7
7
  import { _ as _sfc_main$5 } from "./LpDrawer-DXNQFpAA.js";
8
8
  import { _ as _sfc_main$2 } from "./LpIcon-C6JpQ5td.js";
9
- import { _ as _sfc_main$3 } from "./LpInput-D0O6dpuA.js";
9
+ import { _ as _sfc_main$3 } from "./LpInput-CbI7z5fQ.js";
10
10
  import { _ as _sfc_main$1 } from "./LpTooltip-Bz_rrq5S.js";
11
11
  import { _ as _sfc_main$4 } from "./LpSidebarNav-CE0jQS8i.js";
12
12
  const _hoisted_1 = ["data-compact", "aria-label"];
@@ -0,0 +1,76 @@
1
+ import { defineComponent, openBlock, createBlock, normalizeProps, guardReactiveProps, unref, withCtx, createVNode, mergeProps } from "vue";
2
+ import { _ as _sfc_main$1 } from "./FieldWrapper-DnuMTrqW.js";
3
+ import { _ as _sfc_main$2 } from "./SliderRail-DhPREa_R.js";
4
+ import { usePaletteControl } from "../composables/usePaletteCommands.js";
5
+ import { SliderRoot, SliderThumb } from "reka-ui";
6
+ import { useOwnField, mergeDescribedBy } from "../composables/useField.js";
7
+ import { useMergedAttrs } from "../composables/useMergedClass.js";
8
+ import { SLIDER_GLIDE, useSliderDrag } from "../components/slider.js";
9
+ const __default__ = { inheritAttrs: false };
10
+ const _sfc_main = /* @__PURE__ */ defineComponent({
11
+ ...__default__,
12
+ __name: "LpSlider",
13
+ props: {
14
+ palette: { type: [Boolean, Object], default: void 0 },
15
+ modelValue: { default: 0 },
16
+ min: { default: 0 },
17
+ max: { default: 100 },
18
+ step: { default: 1 },
19
+ disabled: { type: Boolean },
20
+ error: {},
21
+ ariaLabel: {}
22
+ },
23
+ emits: ["update:modelValue", "change"],
24
+ setup(__props, { emit: __emit }) {
25
+ const props = __props;
26
+ const emit = __emit;
27
+ function onUpdate(v) {
28
+ if (v && v.length) emit("update:modelValue", v[0]);
29
+ }
30
+ function onCommit(v) {
31
+ if (v && v.length) emit("change", v[0]);
32
+ }
33
+ const { field, wrapper, ownAttrs } = useOwnField(() => ({ error: props.error, disabled: props.disabled }));
34
+ const { class: rootClass, attrs: rest } = useMergedAttrs(
35
+ `relative flex h-5 w-full touch-none select-none items-center data-[disabled]:opacity-55 ${SLIDER_GLIDE}`,
36
+ () => ownAttrs()
37
+ );
38
+ const { dragging, onPointerDown } = useSliderDrag();
39
+ usePaletteControl({ disabled: () => field.value.disabled });
40
+ return (_ctx, _cache) => {
41
+ return openBlock(), createBlock(_sfc_main$1, normalizeProps(guardReactiveProps(unref(wrapper))), {
42
+ default: withCtx(() => [
43
+ createVNode(unref(SliderRoot), mergeProps({
44
+ "model-value": [props.modelValue],
45
+ min: __props.min,
46
+ max: __props.max,
47
+ step: __props.step,
48
+ disabled: unref(field).disabled,
49
+ class: unref(rootClass)
50
+ }, unref(rest), {
51
+ "data-dragging": unref(dragging) || void 0,
52
+ onPointerdown: unref(onPointerDown),
53
+ "onUpdate:modelValue": onUpdate,
54
+ onValueCommit: onCommit
55
+ }), {
56
+ default: withCtx(() => [
57
+ createVNode(_sfc_main$2),
58
+ createVNode(unref(SliderThumb), {
59
+ id: unref(field).id,
60
+ "aria-label": __props.ariaLabel,
61
+ "aria-labelledby": __props.ariaLabel ? void 0 : unref(field).labelId,
62
+ "aria-describedby": unref(mergeDescribedBy)(unref(rest)["aria-describedby"], unref(field).describedBy),
63
+ class: "block size-4 rounded-pill border-2 border-brand bg-surface shadow outline-none transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] hover:scale-110 active:scale-95 focus-visible:ring-2 focus-visible:ring-ring motion-reduce:hover:scale-100 motion-reduce:active:scale-100"
64
+ }, null, 8, ["id", "aria-label", "aria-labelledby", "aria-describedby"])
65
+ ]),
66
+ _: 1
67
+ }, 16, ["model-value", "min", "max", "step", "disabled", "class", "data-dragging", "onPointerdown"])
68
+ ]),
69
+ _: 1
70
+ }, 16);
71
+ };
72
+ }
73
+ });
74
+ export {
75
+ _sfc_main as _
76
+ };