@sparklingopinions/sparkling-ui 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/aliases.d.ts +176 -26
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/Avatar.vue.d.ts +3 -2
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +20 -14
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Board/Board.js.map +1 -1
- package/dist/components/Board/Board.vue.d.ts +6 -2
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js +142 -74
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Button/Button.vue.d.ts +1 -1
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js +7 -0
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -0
- package/dist/components/ContextMenu/ContextMenu.vue.d.ts +44 -0
- package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js +84 -0
- package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/ContextMenu/index.d.ts +2 -0
- package/dist/components/DataList/DataList.js.map +1 -1
- package/dist/components/DataList/DataList.vue.d.ts +8 -0
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +71 -52
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DataList/types.d.ts +5 -1
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/Dialog/Dialog.vue.d.ts +22 -6
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +174 -72
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/useSheetDrag.d.ts +16 -0
- package/dist/components/Dialog/useSheetDrag.js +37 -0
- package/dist/components/Dialog/useSheetDrag.js.map +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.vue.d.ts +6 -30
- package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +54 -74
- package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.vue.d.ts +9 -3
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +35 -7
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterChip.js.map +1 -1
- package/dist/components/Filters/FilterChip.vue.d.ts +4 -1
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js +29 -24
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterMenu.js.map +1 -1
- package/dist/components/Filters/FilterMenu.vue.d.ts +20 -1
- package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js +78 -56
- package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/SortMenu.js.map +1 -1
- package/dist/components/Filters/SortMenu.vue.d.ts +21 -1
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js +90 -66
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/index.d.ts +2 -1
- package/dist/components/Filters/trigger.d.ts +17 -0
- package/dist/components/Filters/trigger.js +33 -0
- package/dist/components/Filters/trigger.js.map +1 -0
- package/dist/components/Filters/types.d.ts +8 -0
- package/dist/components/FormField/FormField.js.map +1 -1
- package/dist/components/FormField/FormField.vue.d.ts +10 -0
- package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js +31 -20
- package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Icon/iconSet.js +9 -1
- package/dist/components/Icon/iconSet.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.vue.d.ts +6 -3
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +20 -17
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/Table.vue.d.ts +4 -0
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +66 -56
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Table/types.d.ts +2 -0
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Tag/Tag.vue.d.ts +16 -3
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +42 -19
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Toast/ToastMessage.js.map +1 -1
- package/dist/components/Toast/ToastMessage.vue.d.ts +13 -1
- package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js +58 -23
- package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Toast/Toaster.js.map +1 -1
- package/dist/components/Toast/Toaster.vue.d.ts +7 -3
- package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js +50 -21
- package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/internal/MenuItemContent.js +7 -0
- package/dist/components/internal/MenuItemContent.js.map +1 -0
- package/dist/components/internal/MenuItemContent.vue.d.ts +7 -0
- package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js +26 -0
- package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/internal/menu.d.ts +46 -0
- package/dist/components/internal/menu.js +33 -0
- package/dist/components/internal/menu.js.map +1 -0
- package/dist/composables/toast.d.ts +20 -5
- package/dist/composables/toast.js +28 -20
- package/dist/composables/toast.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +34 -33
- package/package.json +1 -1
- package/src/styles/tailwind.css +29 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import e from "../Icon/Icon.js";
|
|
2
2
|
import t from "../Checkbox/Checkbox.js";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
3
|
+
import ee from "../Input/Input.js";
|
|
4
|
+
import te from "../SegmentedControl/SegmentedControl.js";
|
|
5
|
+
import n from "../internal/CheckIcon.js";
|
|
6
|
+
import r from "./FilterFrame.js";
|
|
7
7
|
import i from "./FilterGlyph.js";
|
|
8
8
|
import { datePresets as a, describeFilter as o, filterOperators as s } from "./defaults.js";
|
|
9
9
|
import { Fragment as c, computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createTextVNode as m, createVNode as h, defineComponent as g, mergeModels as _, mergeProps as v, normalizeClass as y, openBlock as b, ref as ne, renderList as x, renderSlot as re, toDisplayString as S, unref as C, useAttrs as ie, useModel as w, vModelText as ae, withCtx as T, withDirectives as oe } from "vue";
|
|
@@ -34,6 +34,7 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
34
34
|
icon: { default: void 0 },
|
|
35
35
|
operators: { default: void 0 },
|
|
36
36
|
options: { default: () => [] },
|
|
37
|
+
summary: { default: void 0 },
|
|
37
38
|
status: { default: void 0 },
|
|
38
39
|
valueLabel: { default: "values" },
|
|
39
40
|
datePresets: { default: () => a },
|
|
@@ -76,25 +77,29 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
76
77
|
"update:open"
|
|
77
78
|
],
|
|
78
79
|
setup(a) {
|
|
79
|
-
let g = a, _ = w(a, "op"), G = w(a, "modelValue"), K = w(a, "open"), q = ie(), J = l(() => g.operators ?? s[g.type]), Y = l(() => J.value.find((e) => e.value === _.value)), X = l(() => !Y.value?.noValue),
|
|
80
|
+
let g = a, _ = w(a, "op"), G = w(a, "modelValue"), K = w(a, "open"), q = ie(), J = l(() => g.operators ?? s[g.type]), Y = l(() => J.value.find((e) => e.value === _.value)), X = l(() => !Y.value?.noValue), _e = l(() => X.value ? o(G.value, g.options, {
|
|
80
81
|
valueLabel: g.valueLabel,
|
|
81
82
|
yesLabel: g.yesLabel,
|
|
82
83
|
noLabel: g.noLabel
|
|
83
|
-
}) : ""),
|
|
84
|
+
}) : ""), Z = l(() => ({
|
|
85
|
+
field: g.summary?.field ?? g.field,
|
|
86
|
+
op: g.summary ? g.summary.op : Y.value?.label,
|
|
87
|
+
value: g.summary ? g.summary.value : _e.value
|
|
88
|
+
})), ve = l(() => [
|
|
84
89
|
"enum",
|
|
85
90
|
"person",
|
|
86
91
|
"company"
|
|
87
|
-
].includes(g.type)), Q = ne(""),
|
|
92
|
+
].includes(g.type)), Q = ne(""), ye = l(() => {
|
|
88
93
|
let e = Q.value.trim().toLowerCase();
|
|
89
94
|
return e ? g.options.filter((t) => t.label.toLowerCase().includes(e)) : g.options;
|
|
90
95
|
}), $ = l(() => Array.isArray(G.value) ? G.value : []);
|
|
91
|
-
function
|
|
96
|
+
function be(e) {
|
|
92
97
|
G.value = $.value.includes(e) ? $.value.filter((t) => t !== e) : [...$.value, e];
|
|
93
98
|
}
|
|
94
|
-
function
|
|
99
|
+
function xe() {
|
|
95
100
|
K.value = !1, g.onRemove?.();
|
|
96
101
|
}
|
|
97
|
-
let
|
|
102
|
+
let Se = {
|
|
98
103
|
blue: "bg-sui-hue-blue-ink",
|
|
99
104
|
green: "bg-sui-hue-green-ink",
|
|
100
105
|
orange: "bg-sui-hue-orange-ink",
|
|
@@ -125,9 +130,9 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
125
130
|
name: a.type
|
|
126
131
|
}, null, 8, ["name"])),
|
|
127
132
|
p("span", null, [
|
|
128
|
-
p("span", j, S(
|
|
129
|
-
|
|
130
|
-
Z.value ? (b(), f(c, { key: 1 }, [s[7] ||= m(S(" "), -1), p("span", M, S(Z.value), 1)], 64)) : d("", !0)
|
|
133
|
+
p("span", j, S(Z.value.field), 1),
|
|
134
|
+
Z.value.op ? (b(), f(c, { key: 0 }, [m(S(" ") + S(Z.value.op), 1)], 64)) : d("", !0),
|
|
135
|
+
Z.value.value ? (b(), f(c, { key: 1 }, [s[7] ||= m(S(" "), -1), p("span", M, S(Z.value.value), 1)], 64)) : d("", !0)
|
|
131
136
|
]),
|
|
132
137
|
s[8] ||= p("svg", {
|
|
133
138
|
"aria-hidden": "true",
|
|
@@ -144,7 +149,7 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
144
149
|
class: "z-[1100] w-85 max-w-[calc(100vw-2rem)] origin-(--reka-popover-content-transform-origin) rounded-xl border border-sui-line bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-overlay-in",
|
|
145
150
|
"side-offset": 8
|
|
146
151
|
}, {
|
|
147
|
-
default: T(() => [h(
|
|
152
|
+
default: T(() => [h(r, {
|
|
148
153
|
"close-label": a.closeLabel,
|
|
149
154
|
"enter-label": a.doneLabel,
|
|
150
155
|
status: a.status,
|
|
@@ -189,7 +194,7 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
189
194
|
class: "flex h-8 cursor-pointer items-center justify-between rounded-md px-2.5 text-13.5 text-sui-ink-body outline-hidden select-none data-highlighted:bg-sui-sunken data-[state=checked]:font-semibold data-[state=checked]:text-sui-ink",
|
|
190
195
|
value: e.value
|
|
191
196
|
}, {
|
|
192
|
-
default: T(() => [m(S(e.label) + " ", 1), e.value === _.value ? (b(), u(
|
|
197
|
+
default: T(() => [m(S(e.label) + " ", 1), e.value === _.value ? (b(), u(n, { key: 0 })) : d("", !0)]),
|
|
193
198
|
_: 2
|
|
194
199
|
}, 1032, ["value"]))), 128))]),
|
|
195
200
|
_: 1
|
|
@@ -204,9 +209,9 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
204
209
|
key: 4,
|
|
205
210
|
class: "ml-auto inline-flex h-7 items-center gap-1.5 rounded-lg px-2 text-12.5 font-medium text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-danger-soft hover:text-sui-danger focus-visible:sui-ring-inset",
|
|
206
211
|
type: "button",
|
|
207
|
-
onClick:
|
|
212
|
+
onClick: xe
|
|
208
213
|
}, [h(i, { name: "trash" }), m(" " + S(a.removeLabel), 1)])) : d("", !0)
|
|
209
|
-
]), o.$slots.default ? re(o.$slots, "default", {}, void 0, void 0, 0) : X.value ? (b(), f(c, { key: 1 }, [
|
|
214
|
+
]), o.$slots.default ? re(o.$slots, "default", {}, void 0, void 0, 0) : X.value ? (b(), f(c, { key: 1 }, [ve.value ? (b(), f(c, { key: 0 }, [a.options.length > 6 ? (b(), f("div", I, [h(i, {
|
|
210
215
|
class: "size-4",
|
|
211
216
|
name: "search"
|
|
212
217
|
}), oe(p("input", {
|
|
@@ -215,21 +220,21 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
215
220
|
autofocus: "",
|
|
216
221
|
class: "h-full min-w-0 flex-1 border-none bg-transparent p-0 text-sm text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden",
|
|
217
222
|
placeholder: a.searchPlaceholder
|
|
218
|
-
}, null, 8, L), [[ae, Q.value]])])) : d("", !0), p("div", R, [(b(!0), f(c, null, x(
|
|
223
|
+
}, null, 8, L), [[ae, Q.value]])])) : d("", !0), p("div", R, [(b(!0), f(c, null, x(ye.value, (e) => (b(), f("label", {
|
|
219
224
|
key: e.value,
|
|
220
225
|
class: y([H, $.value.includes(e.value) ? U : W])
|
|
221
226
|
}, [
|
|
222
227
|
h(t, {
|
|
223
228
|
"model-value": $.value.includes(e.value),
|
|
224
|
-
"onUpdate:modelValue": (t) =>
|
|
229
|
+
"onUpdate:modelValue": (t) => be(e.value)
|
|
225
230
|
}, null, 8, ["model-value", "onUpdate:modelValue"]),
|
|
226
231
|
e.color ? (b(), f("span", {
|
|
227
232
|
key: 0,
|
|
228
|
-
class: y(["size-1.5 shrink-0 rounded-full",
|
|
233
|
+
class: y(["size-1.5 shrink-0 rounded-full", Se[e.color]])
|
|
229
234
|
}, null, 2)) : d("", !0),
|
|
230
235
|
p("span", z, S(e.label), 1),
|
|
231
236
|
e.count == null ? d("", !0) : (b(), f("span", B, S(e.count), 1))
|
|
232
|
-
], 2))), 128))])], 64)) : a.type === "text" || a.type === "number" ? (b(), f("div", me, [h(
|
|
237
|
+
], 2))), 128))])], 64)) : a.type === "text" || a.type === "number" ? (b(), f("div", me, [h(ee, {
|
|
233
238
|
"aria-label": a.field,
|
|
234
239
|
autofocus: "",
|
|
235
240
|
"model-value": G.value == null ? "" : String(G.value),
|
|
@@ -259,14 +264,14 @@ var j = { class: "font-medium" }, M = { class: "font-semibold" }, N = { class: "
|
|
|
259
264
|
name: "date"
|
|
260
265
|
}, null, 8, ["class"]),
|
|
261
266
|
p("span", he, S(e), 1),
|
|
262
|
-
e === G.value ? (b(), u(
|
|
267
|
+
e === G.value ? (b(), u(n, { key: 0 })) : d("", !0)
|
|
263
268
|
]),
|
|
264
269
|
_: 2
|
|
265
270
|
}, 1032, ["class", "value"]))), 128))]),
|
|
266
271
|
_: 1
|
|
267
|
-
}, 8, ["aria-label", "model-value"])) : a.type === "boolean" ? (b(), f("div", ge, [h(
|
|
272
|
+
}, 8, ["aria-label", "model-value"])) : a.type === "boolean" ? (b(), f("div", ge, [h(te, {
|
|
268
273
|
"aria-label": a.field,
|
|
269
|
-
"model-value": G.value ? "yes" : "no",
|
|
274
|
+
"model-value": G.value === null ? "" : G.value ? "yes" : "no",
|
|
270
275
|
options: [{
|
|
271
276
|
value: "yes",
|
|
272
277
|
label: a.yesLabel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterChip.vue_vue_type_script_setup_true_lang.js","names":["$slots","defaultDatePresets","_useModel","_openBlock","_createElementBlock","_mergeProps","_unref","_createVNode","FilterGlyph","_createTextVNode","_toDisplayString","_createBlock","_withCtx","Icon","_createElementVNode","_Fragment","_createCommentVNode","FilterFrame","_renderList","CheckIcon","_renderSlot","_withDirectives","_vModelText","_normalizeClass","Checkbox","Input","SegmentedControl","Icon_default","Checkbox_default","Input_default","SegmentedControl_default","CheckIcon_default","FilterFrame_default","FilterGlyph_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","chip","row","rowOn","rowOff","FilterChip_vue_vue_type_script_setup_true_lang_default","datePresets","\"op\"","\"opModifiers\"","\"modelValue\"","\"modelModifiers\"","\"open\"","\"openModifiers\"","props","__props","op","useModel","value","open","attrs","useAttrs","ops","computed","filterOperators","current","o","needsValue","text","describeFilter","isChecklist","query","ref","listed","q","picked","toggle","choice","v","remove","hueDots","openBlock","createElementBlock","mergeProps","unref","createVNode","createTextVNode","toDisplayString","createBlock","PopoverRoot","_cache","$event","withCtx","PopoverTrigger","createElementVNode","Fragment","createCommentVNode","PopoverPortal","PopoverContent","DropdownMenuRoot","DropdownMenuTrigger","DropdownMenuPortal","DropdownMenuContent","DropdownMenuRadioGroup","renderList","DropdownMenuRadioItem","operator","_ctx","renderSlot","withDirectives","vModelText","option","normalizeClass","RadioGroupRoot","RadioGroupItem","preset"],"sources":["../../../src/components/Filters/FilterChip.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs } from 'vue'\n\nimport {\n DropdownMenuContent,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuRoot,\n DropdownMenuTrigger,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n RadioGroupItem,\n RadioGroupRoot\n} from 'reka-ui'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Icon from '../Icon/Icon.vue'\nimport Input from '../Input/Input.vue'\nimport SegmentedControl from '../SegmentedControl/SegmentedControl.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport FilterFrame from './FilterFrame.vue'\nimport FilterGlyph from './FilterGlyph.vue'\nimport { datePresets as defaultDatePresets, describeFilter, filterOperators } from './defaults'\nimport type { FilterFieldType, FilterOperator, FilterOption, FilterValue } from './types'\n\nexport interface FilterChipProps {\n /** A filter, read as a sentence; `add` is the quiet \"+ Filter\" that starts one (FilterMenu includes it). */\n kind?: 'filter' | 'add'\n field?: string\n /** Picks the editor: a checklist for enum, person and company, an input for text and number, presets for date, Yes / No for boolean. */\n type?: FilterFieldType\n /** An app icon for the field, instead of the type's glyph. */\n icon?: string\n /** The operators offered; English ones by type by default. */\n operators?: FilterOperator[]\n /** The choices for enum, person and company. */\n options?: FilterOption[]\n /** The live result count in the panel's footer, e.g. \"120 people\". */\n status?: string\n /** The plural noun once more than two values are picked: \"3 stages\". */\n valueLabel?: string\n datePresets?: string[]\n /** Adds a Remove action to the panel (`@remove`). */\n onRemove?: () => void\n removeLabel?: string\n addLabel?: string\n operatorLabel?: string\n searchPlaceholder?: string\n valuePlaceholder?: string\n doneLabel?: string\n closeLabel?: string\n yesLabel?: string\n noLabel?: string\n}\n\n// Attributes and listeners go to the chip itself; the root is a renderless popover.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<FilterChipProps>(), {\n kind: 'filter',\n field: undefined,\n type: 'enum',\n icon: undefined,\n operators: undefined,\n options: () => [],\n status: undefined,\n valueLabel: 'values',\n datePresets: () => defaultDatePresets,\n onRemove: undefined,\n removeLabel: 'Remove',\n addLabel: 'Filter',\n operatorLabel: 'Operator',\n searchPlaceholder: 'Search…',\n valuePlaceholder: 'Type a value',\n doneLabel: 'Done',\n closeLabel: 'Close',\n yesLabel: 'Yes',\n noLabel: 'No'\n})\n\nconst op = defineModel<string>('op')\nconst value = defineModel<FilterValue>({ default: null })\nconst open = defineModel<boolean>('open', { default: false })\n\ndefineSlots<{\n /** Your own editor, in place of the type's. */\n default?: () => unknown\n}>()\n\nconst attrs = useAttrs()\n\nconst ops = computed(() => props.operators ?? filterOperators[props.type])\nconst current = computed(() => ops.value.find((o) => o.value === op.value))\nconst needsValue = computed(() => !current.value?.noValue)\nconst text = computed(() =>\n needsValue.value\n ? describeFilter(value.value, props.options, {\n valueLabel: props.valueLabel,\n yesLabel: props.yesLabel,\n noLabel: props.noLabel\n })\n : ''\n)\nconst isChecklist = computed(() => ['enum', 'person', 'company'].includes(props.type))\n\nconst query = ref('')\nconst listed = computed(() => {\n const q = query.value.trim().toLowerCase()\n return q ? props.options.filter((o) => o.label.toLowerCase().includes(q)) : props.options\n})\n\nconst picked = computed(() => (Array.isArray(value.value) ? value.value : []))\n\nfunction toggle(choice: string | number) {\n value.value = picked.value.includes(choice) ? picked.value.filter((v) => v !== choice) : [...picked.value, choice]\n}\n\nfunction remove() {\n open.value = false\n props.onRemove?.()\n}\n\nconst chip =\n 'inline-flex h-7.5 items-center gap-1.5 rounded-lg border text-13 whitespace-nowrap outline-hidden transition-[border-color,box-shadow] duration-150 focus-visible:sui-ring'\nconst row =\n 'flex min-h-8 w-full cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1 text-left text-13.5 outline-hidden transition-colors duration-100 focus-visible:sui-ring-inset'\nconst rowOn = 'bg-sui-accent-wash font-semibold text-sui-accent'\nconst rowOff = 'text-sui-ink hover:bg-sui-sunken'\nconst hueDots: Record<string, string> = {\n blue: 'bg-sui-hue-blue-ink',\n green: 'bg-sui-hue-green-ink',\n orange: 'bg-sui-hue-orange-ink',\n pink: 'bg-sui-hue-pink-ink',\n purple: 'bg-sui-hue-purple-ink',\n slate: 'bg-sui-hue-slate-ink',\n red: 'bg-sui-hue-red-ink',\n amber: 'bg-sui-hue-amber-ink'\n}\n</script>\n\n<!-- A view's filter as a sentence chip (\"Stage is any of Lead, Customer\"), whose panel changes it as you go. -->\n<template>\n <button\n v-if=\"kind === 'add'\"\n v-bind=\"attrs\"\n class=\"border-dashed border-sui-line-strong px-2 font-medium text-sui-ink-muted hover:border-sui-ink-muted hover:text-sui-ink-body\"\n :class=\"chip\"\n type=\"button\"\n >\n <FilterGlyph name=\"plus\" />\n {{ addLabel }}\n </button>\n <PopoverRoot v-else v-model:open=\"open\">\n <PopoverTrigger\n v-bind=\"attrs\"\n class=\"border-sui-accent-line bg-sui-accent-wash pr-1.5 pl-2 text-sui-accent hover:border-sui-accent-bright data-[state=open]:border-sui-accent-solid data-[state=open]:shadow-[0_0_0_3px_rgb(var(--sui-focus-ring))]\"\n :class=\"chip\"\n >\n <Icon v-if=\"icon\" class=\"size-3.5 opacity-80\" color=\"accent\" :name=\"icon\" />\n <FilterGlyph v-else class=\"opacity-80\" :name=\"type\" />\n <!-- Real spaces between the words, so the chip's name reads as a sentence. -->\n <span\n ><span class=\"font-medium\">{{ field }}</span\n ><template v-if=\"current\">{{ ' ' }}{{ current.label }}</template\n ><template v-if=\"text\"\n >{{ ' ' }}<span class=\"font-semibold\">{{ text }}</span></template\n ></span\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 shrink-0 fill-none stroke-current opacity-70\"\n stroke-linecap=\"round\"\n stroke-width=\"2.2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n align=\"start\"\n class=\"z-[1100] w-85 max-w-[calc(100vw-2rem)] origin-(--reka-popover-content-transform-origin) rounded-xl border border-sui-line bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-overlay-in\"\n :side-offset=\"8\"\n >\n <FilterFrame :close-label=\"closeLabel\" :enter-label=\"doneLabel\" :status=\"status\" @enter=\"open = false\">\n <div class=\"flex h-11 items-center gap-1.5 pr-1.5 pl-3.5 text-sui-ink-muted\">\n <Icon v-if=\"icon\" color=\"ink-muted\" :name=\"icon\" />\n <FilterGlyph v-else class=\"size-4\" :name=\"type\" />\n <span class=\"text-sm font-semibold text-sui-ink\">{{ field }}</span>\n <DropdownMenuRoot v-if=\"ops.length > 1\">\n <DropdownMenuTrigger\n :aria-label=\"`${operatorLabel}: ${current?.label ?? ''}`\"\n class=\"inline-flex h-7 items-center gap-0.5 rounded-md pr-1 pl-1.5 text-13.5 font-medium text-sui-accent outline-hidden transition-colors duration-150 hover:bg-sui-accent-wash focus-visible:sui-ring-inset data-[state=open]:bg-sui-accent-wash\"\n >\n {{ current?.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"2.2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </DropdownMenuTrigger>\n <DropdownMenuPortal>\n <DropdownMenuContent\n align=\"start\"\n class=\"z-[1100] w-44 rounded-lg border border-sui-line bg-sui-surface p-1 shadow-lg data-[state=open]:animate-sui-menu-in\"\n :side-offset=\"4\"\n >\n <DropdownMenuRadioGroup v-model=\"op\">\n <DropdownMenuRadioItem\n v-for=\"operator in ops\"\n :key=\"operator.value\"\n class=\"flex h-8 cursor-pointer items-center justify-between rounded-md px-2.5 text-13.5 text-sui-ink-body outline-hidden select-none data-highlighted:bg-sui-sunken data-[state=checked]:font-semibold data-[state=checked]:text-sui-ink\"\n :value=\"operator.value\"\n >\n {{ operator.label }}\n <CheckIcon v-if=\"operator.value === op\" />\n </DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenuPortal>\n </DropdownMenuRoot>\n <span v-else class=\"text-13.5 text-sui-ink-muted\">{{ current?.label }}</span>\n <button\n v-if=\"onRemove\"\n class=\"ml-auto inline-flex h-7 items-center gap-1.5 rounded-lg px-2 text-12.5 font-medium text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-danger-soft hover:text-sui-danger focus-visible:sui-ring-inset\"\n type=\"button\"\n @click=\"remove\"\n >\n <FilterGlyph name=\"trash\" />\n {{ removeLabel }}\n </button>\n </div>\n\n <slot v-if=\"$slots.default\" />\n <template v-else-if=\"needsValue\">\n <template v-if=\"isChecklist\">\n <div\n v-if=\"options.length > 6\"\n class=\"mx-2 mb-1 flex h-9 items-center gap-2 rounded-lg border border-sui-line-subtle px-2.5 text-sui-ink-muted\"\n >\n <FilterGlyph class=\"size-4\" name=\"search\" />\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <input\n v-model=\"query\"\n :aria-label=\"searchPlaceholder\"\n autofocus\n class=\"h-full min-w-0 flex-1 border-none bg-transparent p-0 text-sm text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n :placeholder=\"searchPlaceholder\"\n />\n </div>\n <div class=\"max-h-64 overflow-auto px-1.5 pt-1 pb-1.5\">\n <label\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"[row, picked.includes(option.value) ? rowOn : rowOff]\"\n >\n <Checkbox :model-value=\"picked.includes(option.value)\" @update:model-value=\"toggle(option.value)\" />\n <span v-if=\"option.color\" class=\"size-1.5 shrink-0 rounded-full\" :class=\"hueDots[option.color]\" />\n <span class=\"min-w-0 flex-1 truncate\">{{ option.label }}</span>\n <span v-if=\"option.count != null\" class=\"text-xs font-normal text-sui-ink-muted tabular-nums\">{{\n option.count\n }}</span>\n </label>\n </div>\n </template>\n <div v-else-if=\"type === 'text' || type === 'number'\" class=\"px-2 pt-1 pb-2\">\n <Input\n :aria-label=\"field\"\n autofocus\n :model-value=\"value == null ? '' : String(value)\"\n :placeholder=\"valuePlaceholder\"\n :type=\"type === 'number' ? 'number' : 'text'\"\n @update:model-value=\"value = $event ?? null\"\n />\n </div>\n <RadioGroupRoot\n v-else-if=\"type === 'date'\"\n :aria-label=\"field\"\n class=\"max-h-64 overflow-auto px-1.5 pt-1 pb-1.5\"\n :model-value=\"typeof value === 'string' ? value : undefined\"\n @update:model-value=\"value = String($event)\"\n >\n <RadioGroupItem\n v-for=\"preset in datePresets\"\n :key=\"preset\"\n :class=\"[row, preset === value ? rowOn : rowOff]\"\n :value=\"preset\"\n >\n <FilterGlyph\n class=\"size-4\"\n :class=\"preset === value ? 'text-sui-accent' : 'text-sui-ink-muted'\"\n name=\"date\"\n />\n <span class=\"min-w-0 flex-1 truncate\">{{ preset }}</span>\n <CheckIcon v-if=\"preset === value\" />\n </RadioGroupItem>\n </RadioGroupRoot>\n <div v-else-if=\"type === 'boolean'\" class=\"px-2.5 pt-1 pb-2.5\">\n <SegmentedControl\n :aria-label=\"field\"\n :model-value=\"value ? 'yes' : 'no'\"\n :options=\"[\n { value: 'yes', label: yesLabel },\n { value: 'no', label: noLabel }\n ]\"\n @update:model-value=\"value = $event === 'yes'\"\n />\n </div>\n </template>\n </FilterFrame>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FilterChip.vue_vue_type_script_setup_true_lang.js","names":["$slots","defaultDatePresets","_useModel","_openBlock","_createElementBlock","_mergeProps","_unref","_createVNode","FilterGlyph","_createTextVNode","_toDisplayString","_createBlock","_withCtx","Icon","_createElementVNode","_Fragment","_createCommentVNode","FilterFrame","_renderList","CheckIcon","_renderSlot","_withDirectives","_vModelText","_normalizeClass","Checkbox","Input","SegmentedControl","Icon_default","Checkbox_default","Input_default","SegmentedControl_default","CheckIcon_default","FilterFrame_default","FilterGlyph_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","chip","row","rowOn","rowOff","FilterChip_vue_vue_type_script_setup_true_lang_default","datePresets","\"op\"","\"opModifiers\"","\"modelValue\"","\"modelModifiers\"","\"open\"","\"openModifiers\"","props","__props","op","useModel","value","open","attrs","useAttrs","ops","computed","filterOperators","current","o","needsValue","text","describeFilter","words","isChecklist","query","ref","listed","q","picked","toggle","choice","v","remove","hueDots","openBlock","createElementBlock","mergeProps","unref","createVNode","createTextVNode","toDisplayString","createBlock","PopoverRoot","_cache","$event","withCtx","PopoverTrigger","createElementVNode","Fragment","createCommentVNode","PopoverPortal","PopoverContent","DropdownMenuRoot","DropdownMenuTrigger","DropdownMenuPortal","DropdownMenuContent","DropdownMenuRadioGroup","renderList","DropdownMenuRadioItem","operator","_ctx","renderSlot","withDirectives","vModelText","option","normalizeClass","RadioGroupRoot","RadioGroupItem","preset"],"sources":["../../../src/components/Filters/FilterChip.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs } from 'vue'\n\nimport {\n DropdownMenuContent,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuRoot,\n DropdownMenuTrigger,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n RadioGroupItem,\n RadioGroupRoot\n} from 'reka-ui'\n\nimport Checkbox from '../Checkbox/Checkbox.vue'\nimport Icon from '../Icon/Icon.vue'\nimport Input from '../Input/Input.vue'\nimport SegmentedControl from '../SegmentedControl/SegmentedControl.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport FilterFrame from './FilterFrame.vue'\nimport FilterGlyph from './FilterGlyph.vue'\nimport { datePresets as defaultDatePresets, describeFilter, filterOperators } from './defaults'\nimport type { FilterFieldType, FilterOperator, FilterOption, FilterSummary, FilterValue } from './types'\n\nexport interface FilterChipProps {\n /** A filter, read as a sentence; `add` is the quiet \"+ Filter\" that starts one (FilterMenu includes it). */\n kind?: 'filter' | 'add'\n field?: string\n /** Picks the editor: a checklist for enum, person and company, an input for text and number, presets for date, Yes / No for boolean. */\n type?: FilterFieldType\n /** An app icon for the field, instead of the type's glyph. */\n icon?: string\n /** The operators offered; English ones by type by default. */\n operators?: FilterOperator[]\n /** The choices for enum, person and company. */\n options?: FilterOption[]\n /** Your own wording for the chip, in place of field, operator and value: \"Not archived\", \"Created in the last 7 days\". */\n summary?: FilterSummary\n /** The live result count in the panel's footer, e.g. \"120 people\". */\n status?: string\n /** The plural noun once more than two values are picked: \"3 stages\". */\n valueLabel?: string\n datePresets?: string[]\n /** Adds a Remove action to the panel (`@remove`). */\n onRemove?: () => void\n removeLabel?: string\n addLabel?: string\n operatorLabel?: string\n searchPlaceholder?: string\n valuePlaceholder?: string\n doneLabel?: string\n closeLabel?: string\n yesLabel?: string\n noLabel?: string\n}\n\n// Attributes and listeners go to the chip itself; the root is a renderless popover.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<FilterChipProps>(), {\n kind: 'filter',\n field: undefined,\n type: 'enum',\n icon: undefined,\n operators: undefined,\n options: () => [],\n summary: undefined,\n status: undefined,\n valueLabel: 'values',\n datePresets: () => defaultDatePresets,\n onRemove: undefined,\n removeLabel: 'Remove',\n addLabel: 'Filter',\n operatorLabel: 'Operator',\n searchPlaceholder: 'Search…',\n valuePlaceholder: 'Type a value',\n doneLabel: 'Done',\n closeLabel: 'Close',\n yesLabel: 'Yes',\n noLabel: 'No'\n})\n\nconst op = defineModel<string>('op')\nconst value = defineModel<FilterValue>({ default: null })\nconst open = defineModel<boolean>('open', { default: false })\n\ndefineSlots<{\n /** Your own editor, in place of the type's. */\n default?: () => unknown\n}>()\n\nconst attrs = useAttrs()\n\nconst ops = computed(() => props.operators ?? filterOperators[props.type])\nconst current = computed(() => ops.value.find((o) => o.value === op.value))\nconst needsValue = computed(() => !current.value?.noValue)\nconst text = computed(() =>\n needsValue.value\n ? describeFilter(value.value, props.options, {\n valueLabel: props.valueLabel,\n yesLabel: props.yesLabel,\n noLabel: props.noLabel\n })\n : ''\n)\nconst words = computed(() => ({\n field: props.summary?.field ?? props.field,\n op: props.summary ? props.summary.op : current.value?.label,\n value: props.summary ? props.summary.value : text.value\n}))\nconst isChecklist = computed(() => ['enum', 'person', 'company'].includes(props.type))\n\nconst query = ref('')\nconst listed = computed(() => {\n const q = query.value.trim().toLowerCase()\n return q ? props.options.filter((o) => o.label.toLowerCase().includes(q)) : props.options\n})\n\nconst picked = computed(() => (Array.isArray(value.value) ? value.value : []))\n\nfunction toggle(choice: string | number) {\n value.value = picked.value.includes(choice) ? picked.value.filter((v) => v !== choice) : [...picked.value, choice]\n}\n\nfunction remove() {\n open.value = false\n props.onRemove?.()\n}\n\nconst chip =\n 'inline-flex h-7.5 items-center gap-1.5 rounded-lg border text-13 whitespace-nowrap outline-hidden transition-[border-color,box-shadow] duration-150 focus-visible:sui-ring'\nconst row =\n 'flex min-h-8 w-full cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1 text-left text-13.5 outline-hidden transition-colors duration-100 focus-visible:sui-ring-inset'\nconst rowOn = 'bg-sui-accent-wash font-semibold text-sui-accent'\nconst rowOff = 'text-sui-ink hover:bg-sui-sunken'\nconst hueDots: Record<string, string> = {\n blue: 'bg-sui-hue-blue-ink',\n green: 'bg-sui-hue-green-ink',\n orange: 'bg-sui-hue-orange-ink',\n pink: 'bg-sui-hue-pink-ink',\n purple: 'bg-sui-hue-purple-ink',\n slate: 'bg-sui-hue-slate-ink',\n red: 'bg-sui-hue-red-ink',\n amber: 'bg-sui-hue-amber-ink'\n}\n</script>\n\n<!-- A view's filter as a sentence chip (\"Stage is any of Lead, Customer\"), whose panel changes it as you go. -->\n<template>\n <button\n v-if=\"kind === 'add'\"\n v-bind=\"attrs\"\n class=\"border-dashed border-sui-line-strong px-2 font-medium text-sui-ink-muted hover:border-sui-ink-muted hover:text-sui-ink-body\"\n :class=\"chip\"\n type=\"button\"\n >\n <FilterGlyph name=\"plus\" />\n {{ addLabel }}\n </button>\n <PopoverRoot v-else v-model:open=\"open\">\n <PopoverTrigger\n v-bind=\"attrs\"\n class=\"border-sui-accent-line bg-sui-accent-wash pr-1.5 pl-2 text-sui-accent hover:border-sui-accent-bright data-[state=open]:border-sui-accent-solid data-[state=open]:shadow-[0_0_0_3px_rgb(var(--sui-focus-ring))]\"\n :class=\"chip\"\n >\n <Icon v-if=\"icon\" class=\"size-3.5 opacity-80\" color=\"accent\" :name=\"icon\" />\n <FilterGlyph v-else class=\"opacity-80\" :name=\"type\" />\n <!-- Real spaces between the words, so the chip's name reads as a sentence. -->\n <span\n ><span class=\"font-medium\">{{ words.field }}</span\n ><template v-if=\"words.op\">{{ ' ' }}{{ words.op }}</template\n ><template v-if=\"words.value\"\n >{{ ' ' }}<span class=\"font-semibold\">{{ words.value }}</span></template\n ></span\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 shrink-0 fill-none stroke-current opacity-70\"\n stroke-linecap=\"round\"\n stroke-width=\"2.2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n align=\"start\"\n class=\"z-[1100] w-85 max-w-[calc(100vw-2rem)] origin-(--reka-popover-content-transform-origin) rounded-xl border border-sui-line bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-overlay-in\"\n :side-offset=\"8\"\n >\n <FilterFrame :close-label=\"closeLabel\" :enter-label=\"doneLabel\" :status=\"status\" @enter=\"open = false\">\n <div class=\"flex h-11 items-center gap-1.5 pr-1.5 pl-3.5 text-sui-ink-muted\">\n <Icon v-if=\"icon\" color=\"ink-muted\" :name=\"icon\" />\n <FilterGlyph v-else class=\"size-4\" :name=\"type\" />\n <span class=\"text-sm font-semibold text-sui-ink\">{{ field }}</span>\n <DropdownMenuRoot v-if=\"ops.length > 1\">\n <DropdownMenuTrigger\n :aria-label=\"`${operatorLabel}: ${current?.label ?? ''}`\"\n class=\"inline-flex h-7 items-center gap-0.5 rounded-md pr-1 pl-1.5 text-13.5 font-medium text-sui-accent outline-hidden transition-colors duration-150 hover:bg-sui-accent-wash focus-visible:sui-ring-inset data-[state=open]:bg-sui-accent-wash\"\n >\n {{ current?.label }}\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"2.2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </DropdownMenuTrigger>\n <DropdownMenuPortal>\n <DropdownMenuContent\n align=\"start\"\n class=\"z-[1100] w-44 rounded-lg border border-sui-line bg-sui-surface p-1 shadow-lg data-[state=open]:animate-sui-menu-in\"\n :side-offset=\"4\"\n >\n <DropdownMenuRadioGroup v-model=\"op\">\n <DropdownMenuRadioItem\n v-for=\"operator in ops\"\n :key=\"operator.value\"\n class=\"flex h-8 cursor-pointer items-center justify-between rounded-md px-2.5 text-13.5 text-sui-ink-body outline-hidden select-none data-highlighted:bg-sui-sunken data-[state=checked]:font-semibold data-[state=checked]:text-sui-ink\"\n :value=\"operator.value\"\n >\n {{ operator.label }}\n <CheckIcon v-if=\"operator.value === op\" />\n </DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenuPortal>\n </DropdownMenuRoot>\n <span v-else class=\"text-13.5 text-sui-ink-muted\">{{ current?.label }}</span>\n <button\n v-if=\"onRemove\"\n class=\"ml-auto inline-flex h-7 items-center gap-1.5 rounded-lg px-2 text-12.5 font-medium text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-danger-soft hover:text-sui-danger focus-visible:sui-ring-inset\"\n type=\"button\"\n @click=\"remove\"\n >\n <FilterGlyph name=\"trash\" />\n {{ removeLabel }}\n </button>\n </div>\n\n <slot v-if=\"$slots.default\" />\n <template v-else-if=\"needsValue\">\n <template v-if=\"isChecklist\">\n <div\n v-if=\"options.length > 6\"\n class=\"mx-2 mb-1 flex h-9 items-center gap-2 rounded-lg border border-sui-line-subtle px-2.5 text-sui-ink-muted\"\n >\n <FilterGlyph class=\"size-4\" name=\"search\" />\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <input\n v-model=\"query\"\n :aria-label=\"searchPlaceholder\"\n autofocus\n class=\"h-full min-w-0 flex-1 border-none bg-transparent p-0 text-sm text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n :placeholder=\"searchPlaceholder\"\n />\n </div>\n <div class=\"max-h-64 overflow-auto px-1.5 pt-1 pb-1.5\">\n <label\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"[row, picked.includes(option.value) ? rowOn : rowOff]\"\n >\n <Checkbox :model-value=\"picked.includes(option.value)\" @update:model-value=\"toggle(option.value)\" />\n <span v-if=\"option.color\" class=\"size-1.5 shrink-0 rounded-full\" :class=\"hueDots[option.color]\" />\n <span class=\"min-w-0 flex-1 truncate\">{{ option.label }}</span>\n <span v-if=\"option.count != null\" class=\"text-xs font-normal text-sui-ink-muted tabular-nums\">{{\n option.count\n }}</span>\n </label>\n </div>\n </template>\n <div v-else-if=\"type === 'text' || type === 'number'\" class=\"px-2 pt-1 pb-2\">\n <Input\n :aria-label=\"field\"\n autofocus\n :model-value=\"value == null ? '' : String(value)\"\n :placeholder=\"valuePlaceholder\"\n :type=\"type === 'number' ? 'number' : 'text'\"\n @update:model-value=\"value = $event ?? null\"\n />\n </div>\n <RadioGroupRoot\n v-else-if=\"type === 'date'\"\n :aria-label=\"field\"\n class=\"max-h-64 overflow-auto px-1.5 pt-1 pb-1.5\"\n :model-value=\"typeof value === 'string' ? value : undefined\"\n @update:model-value=\"value = String($event)\"\n >\n <RadioGroupItem\n v-for=\"preset in datePresets\"\n :key=\"preset\"\n :class=\"[row, preset === value ? rowOn : rowOff]\"\n :value=\"preset\"\n >\n <FilterGlyph\n class=\"size-4\"\n :class=\"preset === value ? 'text-sui-accent' : 'text-sui-ink-muted'\"\n name=\"date\"\n />\n <span class=\"min-w-0 flex-1 truncate\">{{ preset }}</span>\n <CheckIcon v-if=\"preset === value\" />\n </RadioGroupItem>\n </RadioGroupRoot>\n <div v-else-if=\"type === 'boolean'\" class=\"px-2.5 pt-1 pb-2.5\">\n <SegmentedControl\n :aria-label=\"field\"\n :model-value=\"value === null ? '' : value ? 'yes' : 'no'\"\n :options=\"[\n { value: 'yes', label: yesLabel },\n { value: 'no', label: noLabel }\n ]\"\n @update:model-value=\"value = $event === 'yes'\"\n />\n </div>\n </template>\n </FilterFrame>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;A,GAqIM+C,IACJ,8KACIC,IACJ,+KACIC,IAAQ,oDACRC,IAAS,oC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA3Ef,IAAMS,IAAQC,GAuBRC,IAAK3D,EAAmB0D,GAAC,IAAI,GAC7BG,IAAQ7D,EAAwB0D,GAAA,YAAkB,GAClDI,IAAO9D,EAAoB0D,GAAC,MAA0B,GAOtDK,IAAQC,GAAS,GAEjBC,IAAMC,QAAeT,EAAM,aAAaU,EAAgBV,EAAM,KAAK,GACnEW,IAAUF,QAAeD,EAAI,MAAM,MAAM,MAAMI,EAAE,UAAUV,EAAG,KAAK,CAAC,GACpEW,IAAaJ,QAAe,CAACE,EAAQ,OAAO,OAAO,GACnDG,KAAOL,QACXI,EAAW,QACPE,EAAeX,EAAM,OAAOJ,EAAM,SAAS;GACzC,YAAYA,EAAM;GAClB,UAAUA,EAAM;GAChB,SAASA,EAAM;EACjB,CAAC,IACD,EACN,GACMgB,IAAQP,SAAgB;GAC5B,OAAOT,EAAM,SAAS,SAASA,EAAM;GACrC,IAAIA,EAAM,UAAUA,EAAM,QAAQ,KAAKW,EAAQ,OAAO;GACtD,OAAOX,EAAM,UAAUA,EAAM,QAAQ,QAAQc,GAAK;EACpD,EAAE,GACIG,KAAcR,QAAe;GAAC;GAAQ;GAAU;EAAS,CAAC,CAAC,SAAST,EAAM,IAAI,CAAC,GAE/EkB,IAAQC,GAAI,EAAE,GACdC,KAASX,QAAe;GAC5B,IAAMY,IAAIH,EAAM,MAAM,KAAK,CAAC,CAAC,YAAY;GACzC,OAAOG,IAAIrB,EAAM,QAAQ,QAAQ,MAAMY,EAAE,MAAM,YAAY,CAAC,CAAC,SAASS,CAAC,CAAC,IAAIrB,EAAM;EACpF,CAAC,GAEKsB,IAASb,QAAgB,MAAM,QAAQL,EAAM,KAAK,IAAIA,EAAM,QAAQ,CAAC,CAAE;EAE7E,SAASmB,GAAO,GAAyB;GACvC,EAAM,QAAQD,EAAO,MAAM,SAASE,CAAM,IAAIF,EAAO,MAAM,QAAQ,MAAMG,MAAMD,CAAM,IAAI,CAAC,GAAGF,EAAO,OAAOE,CAAM;EACnH;EAEA,SAASE,KAAS;GAEhB,AADA,EAAK,QAAQ,IACb1B,EAAM,WAAW;EACnB;EAQA,IAAM2B,KAAkC;GACtC,MAAM;GACN,OAAO;GACP,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,OAAO;GACP,KAAK;GACL,OAAO;EACT;E,iBAMU1B,EAAA,SAAI,SADZzD,EAAA,GAAAC,EASS,UATTC,EASS,EAAA,KAAA,EAAA,GAPCC,EAAA2D,CAAA,GAAK;GACb,OAAK,CAAC,+HACElB,CAAI;GACZ,MAAK;E,KAELxC,EAA2BC,GAAA,EAAd,MAAK,OAAM,CAAA,GAAGC,EAAA,MAC3BC,EAAGkD,EAAA,QAAQ,GAAA,CAAA,C,WAEbzD,EAAA,GAAAQ,EAoKcL,EAAAyF,CAAA,GAAA;;GApKc,MAAM/B,EAAA;GAAA,iBAAA,AAAAgC,EAAA,QAAA,MAAA,EAAI,QAAAC;;GACpC,SAAArF,QAwBiB,CAxBjBL,EAwBiBD,EAAA6F,CAAA,GAxBjB9F,EACUC,EAuBO2D,CAAA,GAvBF,EACb,OAAK,CAAC,kNACElB,CAAI,E;IAEZ,SAAAnC,QAA4E;KAAhEgD,EAAA,QAAZzD,EAAA,GAAAQ,EAA4EE,GAAA;;MAA1D,OAAM;MAAsB,OAAM;MAAU,MAAM+C,EAAA;K,0BACpEzD,EAAA,GAAAQ,EAAsDH,GAAA;;MAAlC,OAAM;MAAc,MAAMoD,EAAA;;KAE9C9C,EAMC,QAAA,MAAA;MALEA,EACA,QADAoB,GACAxB,EAD6BiE,EAAA,MAAM,KAAK,GAAA,CAAA;MACxBA,EAAA,MAAM,MAAtBxE,EAAA,GAAAC,EACAW,GAAA,EAAA,KAAA,EAAA,GAAA,CAD6BN,EAAAC,EAAA,GAAG,IAAAA,EAAMiE,EAAA,MAAM,EAAE,GAAA,CAAA,C;MAC9BA,EAAA,MAAM,SAAtBxE,EAAA,GAAAC,EAEAW,GAAA,EAAA,KAAA,EAAA,GAAA,CADK,AAAAiF,EAAA,OAAAvF,EAAAC,EAAA,GAAG,GAAA,EAAA,GAAGI,EAAoD,QAApDqB,GAAoDzB,EAArBiE,EAAA,MAAM,KAAK,GAAA,CAAA,C;;KAGxD,AAAAqB,EAAA,OAAAlF,EAQM,OAAA;MAPJ,eAAY;MACZ,OAAM;MACN,kBAAe;MACf,gBAAa;MACb,SAAQ;K,IAERA,EAAyB,QAAA,EAAnB,GAAE,eAAc,CAAA,C;;;G,QAG1BP,EAyIgBD,EAAAiG,CAAA,GAAA,MAAA;IAxId,SAAA3F,QAuIiB,CAvIjBL,EAuIiBD,EAAAkG,EAAA,GAAA;KAtIf,OAAM;KACN,OAAM;KACL,eAAa;;KAEd,SAAA5F,QAiIc,CAjIdL,EAiIcU,GAAA;MAjIA,eAAa2C,EAAA;MAAa,eAAaA,EAAA;MAAY,QAAQA,EAAA;MAAS,SAAK,AAAAoC,EAAA,QAAA,MAAE,EAAA,QAAI;;MAC3F,SAAApF,QAkDM,CAlDNE,EAkDM,OAlDNsB,GAkDM;OAjDQwB,EAAA,QAAZzD,EAAA,GAAAQ,EAAmDE,GAAA;;QAAjC,OAAM;QAAa,MAAM+C,EAAA;O,0BAC3CzD,EAAA,GAAAQ,EAAkDH,GAAA;;QAA9B,OAAM;QAAU,MAAMoD,EAAA;;OAC1C9C,EAAmE,QAAnEuB,GAAmE3B,EAAfkD,EAAA,KAAK,GAAA,CAAA;OACjCO,EAAA,MAAI,SAAM,KAAlChE,EAAA,GAAAQ,EAmCmBL,EAAAmG,EAAA,GAAA,EAAA,KAAA,EAAA,GAAA;QAlCjB,SAAA7F,QAcsB,CAdtBL,EAcsBD,EAAAoG,EAAA,GAAA;SAbnB,cAAU,GAAK9C,EAAA,cAAa,IAAKU,EAAA,OAAS,SAAK;SAChD,OAAM;;SAEN,SAAA1D,QAAoB,CAAjBH,EAAAC,EAAA4D,EAAA,OAAS,KAAK,IAAG,KACpB,CAAA,GAAA,AAAA0B,EAAA,OAAAlF,EAQM,OAAA;UAPJ,eAAY;UACZ,OAAM;UACN,kBAAe;UACf,gBAAa;UACb,SAAQ;S,IAERA,EAAyB,QAAA,EAAnB,GAAE,eAAc,CAAA,C;;Q,uBAG1BP,EAkBqBD,EAAAqG,EAAA,GAAA,MAAA;SAjBnB,SAAA/F,QAgBsB,CAhBtBL,EAgBsBD,EAAAsG,EAAA,GAAA;UAfpB,OAAM;UACN,OAAM;UACL,eAAa;;UAEd,SAAAhG,QAUyB,CAVzBL,EAUyBD,EAAAuG,EAAA,GAAA;WAVQ,YAAAhD,EAAA;WAAA,uBAAA,AAAAmC,EAAA,QAAA,MAAA,EAAE,QAAAC;;WAE/B,SAAArF,QAAuB,EADzBT,EAAA,EAAA,GAAAC,EAQwBW,GAAA,MAAAG,EAPHiD,EAAA,QAAZ,OADThE,EAAA,GAAAQ,EAQwBL,EAAAyG,EAAA,GAAA;YANrB,KAAKC,EAAS;YACf,OAAM;YACL,OAAOA,EAAS;;YAEjB,SAAApG,QAAoB,CAAjBH,EAAAC,EAAAsG,EAAS,KAAK,IAAG,KACpB,CAAA,GAAiBA,EAAS,UAAUnD,EAAA,SAApC1D,EAAA,GAAAQ,EAA0CQ,GAAA,EAAA,KAAA,EAAA,CAAA,K;;;;;;;;;;O,OAMpDhB,EAAA,GAAAC,EAA6E,QAA7EkC,GAA6E5B,EAAxB4D,EAAA,OAAS,KAAK,GAAA,CAAA;OAE3DV,EAAA,YADRzD,EAAA,GAAAC,EAQS,UAAA;;QANP,OAAM;QACN,MAAK;QACJ,SAAOiF;O,IAER9E,EAA4BC,GAAA,EAAf,MAAK,QAAO,CAAA,GAAGC,EAAA,MAC5BC,EAAGkD,EAAA,WAAW,GAAA,CAAA,C;M,IAIN5D,EAAAA,OAAO,UAAnBoB,GAA8B6F,EAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IACTzC,EAAA,SAArBrE,EAAA,GAAAC,EA0EWW,GAAA,EAAA,KAAA,EAAA,GAAA,CAzEO6D,GAAA,SAAhBzE,EAAA,GAAAC,EA6BWW,GAAA,EAAA,KAAA,EAAA,GAAA,CA3BD6C,EAAA,QAAQ,SAAM,KADtBzD,EAAA,GAAAC,EAaM,OAbNmC,GAaM,CATJhC,EAA4CC,GAAA;OAA/B,OAAM;OAAS,MAAK;M,IAEjCa,GAAAP,EAME,SAAA;OALS,uBAAA,AAAAkF,EAAA,QAAA,MAAA,EAAK,QAAAC;OACb,cAAYrC,EAAA;OACb,WAAA;OACA,OAAM;OACL,aAAaA,EAAA;M,iBAJL,CAAAtC,IAAAuD,EAAA,KAAK,C,mBAOlB/D,EAaM,OAbN2B,GAaM,EAZJtC,EAAA,EAAA,GAAAC,EAWQW,GAAA,MAAAG,EAVW6D,GAAA,QAAV,OADT5E,EAAA,GAAAC,EAWQ,SAAA;OATL,KAAKiH,EAAO;OACZ,OAAK9F,EAAA,CAAGyB,GAAKiC,EAAA,MAAO,SAASoC,EAAO,KAAK,IAAIpE,IAAQC,CAAM,CAAA;;OAE5D3C,EAAoGiB,GAAA;QAAzF,eAAayD,EAAA,MAAO,SAASoC,EAAO,KAAK;QAAI,wBAAkB,MAAEnC,GAAOmC,EAAO,KAAK;;OACnFA,EAAO,SAAnBlH,EAAA,GAAAC,EAAkG,QAAA;;QAAxE,OAAKmB,EAAA,CAAC,kCAAyC+D,GAAQ+B,EAAO,MAAK,CAAA;;OAC7FvG,EAA+D,QAA/D4B,GAA+DhC,EAAtB2G,EAAO,KAAK,GAAA,CAAA;OACzCA,EAAO,SAAK,O,aAAxBlH,EAAA,GAAAC,EAES,QAFTuC,GAESjC,EADP2G,EAAO,KAAK,GAAA,CAAA;M,0BAKJzD,EAAA,SAAI,UAAeA,EAAA,SAAI,YAAvCzD,EAAA,GAAAC,EASM,OATNwC,IASM,CARJrC,EAOEkB,IAAA;OANC,cAAYmC,EAAA;OACb,WAAA;OACC,eAAaG,EAAA,SAAK,OAAA,KAAgB,OAAOA,EAAA,KAAK;OAC9C,aAAaH,EAAA;OACb,MAAMA,EAAA,SAAI,WAAA,WAAA;OACV,uBAAkB,AAAAoC,EAAA,QAAA,MAAE,EAAA,QAAQC,KAAM;;;;;;M,QAI1BrC,EAAA,SAAI,UADjBzD,EAAA,GAAAQ,EAqBiBL,EAAAiH,CAAA,GAAA;;OAnBd,cAAY3D,EAAA;OACb,OAAM;OACL,eAAW,OAASG,EAAA,SAAK,WAAgBA,EAAA,QAAQ,KAAA;OACjD,uBAAkB,AAAAiC,EAAA,QAAA,MAAE,EAAA,QAAQ,OAAOC,CAAM;;OAGxC,SAAArF,QAA6B,EAD/BT,EAAA,EAAA,GAAAC,EAaiBW,GAAA,MAAAG,EAZE0C,EAAA,cAAV,OADTzD,EAAA,GAAAQ,EAaiBL,EAAAkH,CAAA,GAAA;QAXd,KAAKC;QACL,OAAKlG,EAAA,CAAGyB,GAAKyE,MAAW1D,EAAA,QAAQd,IAAQC,CAAM,CAAA;QAC9C,OAAOuE;;QAER,SAAA7G,QAIE;SAJFL,EAIEC,GAAA;UAHA,OAAKe,EAAA,CAAC,UACEkG,MAAW1D,EAAA,QAAK,oBAAA,oBAAA,CAAA;UACxB,MAAK;;SAEPjD,EAAyD,QAAzD+B,IAAyDnC,EAAhB+G,CAAM,GAAA,CAAA;SAC9BA,MAAW1D,EAAA,SAA5B5D,EAAA,GAAAQ,EAAqCQ,GAAA,EAAA,KAAA,EAAA,CAAA,K;;;;;M,wCAGzByC,EAAA,SAAI,aAApBzD,EAAA,GAAAC,EAUM,OAVN0C,IAUM,CATJvC,EAQEmB,IAAA;OAPC,cAAYkC,EAAA;OACZ,eAAaG,EAAA,UAAK,OAAA,KAAiBA,EAAA,QAAK,QAAA;OACxC,SAAO,CAA6C;QAAA,OAAA;QAAA,OAAAH,EAAA;OAAQ,GAA4C;QAAA,OAAA;QAAA,OAAAA,EAAA;OAAO,C;OAI/G,uBAAkB,AAAAoC,EAAA,QAAA,MAAE,EAAA,QAAQC,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterMenu.js","names":["_sfc_main","FilterMenu_vue_vue_type_script_setup_true_lang_default","FilterMenu_default"],"sources":["../../../src/components/Filters/FilterMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxGroup,\n ListboxGroupLabel,\n ListboxItem,\n ListboxRoot,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger\n} from 'reka-ui'\n\nimport Button from '../Button/Button.vue'\nimport FilterFrame from './FilterFrame.vue'\nimport FilterGlyph from './FilterGlyph.vue'\nimport type { FilterField } from './types'\n\nexport interface FilterMenuProps {\n fields: FilterField[]\n /** Fields already filtering, marked \"In use\"; picking one should open its chip, not add a second. */\n inUse?: string[]\n /** chip: the dashed \"+ Filter\" in the view bar. button: the page header's Filters button, tinted while filters are in use. */\n as?: 'chip' | 'button'\n /** The footer's status; \"{count} fields\" by default. */\n status?: string\n label?: string\n buttonLabel?: string\n searchPlaceholder?: string\n inUseLabel?: string\n addLabel?: string\n closeLabel?: string\n /** `{count}` is the number of fields. */\n fieldsLabel?: string\n /** `{query}` is what was typed. */\n noMatchLabel?: string\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<FilterMenuProps>(), {\n inUse: () => [],\n as: 'chip',\n status: undefined,\n label: 'Filter',\n buttonLabel: 'Filters',\n searchPlaceholder: 'Filter by…',\n inUseLabel: 'In use',\n addLabel: 'Add',\n closeLabel: 'Close',\n fieldsLabel: '{count} fields',\n noMatchLabel: 'No field matches “{query}”.'\n})\n\nconst emit = defineEmits<{ pick: [name: string] }>()\n\nconst open = defineModel<boolean>('open', { default: false })\n\nconst attrs = useAttrs()\nconst query = ref('')\n// Only the keyboard's highlight gets the focus ring; the pointer's is just a tint.\nconst keyboard = ref(false)\n\nconst groups = computed(() => {\n const q = query.value.trim().toLowerCase()\n const shown = props.fields.filter((f) => !q || f.label.toLowerCase().includes(q))\n return [...new Set(shown.map((f) => f.group ?? ''))].map((name) => ({\n name,\n fields: shown.filter((f) => (f.group ?? '') === name)\n }))\n})\n\nfunction pick(name: unknown) {\n if (typeof name !== 'string') return\n open.value = false\n query.value = ''\n emit('pick', name)\n}\n\nfunction onOpen(isOpen: boolean) {\n if (!isOpen) query.value = ''\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n}\n</script>\n\n<!-- The field list behind \"+ Filter\": search, fields grouped with their type, and which are already filtering. -->\n<template>\n <PopoverRoot v-model:open=\"open\" @update:open=\"onOpen\">\n <PopoverTrigger v-if=\"as === 'button'\" as-child>\n <Button v-bind=\"attrs\" :variant=\"inUse.length ? 'tinted' : 'secondary'\">\n <svg\n aria-hidden=\"true\"\n class=\"size-4 fill-none stroke-current\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M2.5 3.5h11l-4.25 5v4l-2.5 1v-5z\" />\n </svg>\n {{ buttonLabel }}\n </Button>\n </PopoverTrigger>\n <PopoverTrigger\n v-else\n v-bind=\"attrs\"\n class=\"inline-flex h-7.5 items-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong px-2 text-13 font-medium whitespace-nowrap text-sui-ink-muted outline-hidden transition-[border-color,box-shadow] duration-150 hover:border-sui-ink-muted hover:text-sui-ink-body focus-visible:sui-ring data-[state=open]:border-solid data-[state=open]:border-sui-accent-solid data-[state=open]:text-sui-accent data-[state=open]:shadow-[0_0_0_3px_rgb(var(--sui-focus-ring))]\"\n >\n <FilterGlyph name=\"plus\" />\n {{ label }}\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n align=\"start\"\n class=\"z-[1100] w-85 max-w-[calc(100vw-2rem)] origin-(--reka-popover-content-transform-origin) rounded-xl border border-sui-line bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-overlay-in\"\n :side-offset=\"8\"\n @keydown=\"onKeydown\"\n @pointermove=\"keyboard = false\"\n >\n <ListboxRoot highlight-on-hover @update:model-value=\"pick\">\n <FilterFrame\n :close-label=\"closeLabel\"\n :enter-label=\"addLabel\"\n :status=\"status ?? fieldsLabel.replace('{count}', String(fields.length))\"\n >\n <div class=\"flex h-11 items-center gap-2 border-b border-sui-line-subtle px-3.5 text-sui-ink-muted\">\n <FilterGlyph class=\"size-4\" name=\"search\" />\n <ListboxFilter\n v-model=\"query\"\n :aria-label=\"searchPlaceholder\"\n auto-focus\n class=\"h-full min-w-0 flex-1 border-none bg-transparent p-0 text-sm text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n :placeholder=\"searchPlaceholder\"\n />\n </div>\n <ListboxContent\n :aria-label=\"searchPlaceholder\"\n class=\"group/list max-h-64 overflow-auto px-1.5 pt-1 pb-1.5 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxGroup v-for=\"group in groups\" :key=\"group.name\">\n <ListboxGroupLabel\n v-if=\"group.name\"\n class=\"m-0 px-2 pt-2.5 pb-1 text-11 font-semibold tracking-caps text-sui-ink-muted uppercase\"\n >\n {{ group.name }}\n </ListboxGroupLabel>\n <ListboxItem\n v-for=\"field in group.fields\"\n :key=\"field.name\"\n class=\"flex min-h-8 cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1 text-13.5 text-sui-ink outline-hidden select-none data-highlighted:bg-sui-sunken group-data-keyboard/list:data-highlighted:sui-ring-inset\"\n :value=\"field.name\"\n >\n <span\n class=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-sui-sunken text-sui-ink-body\"\n >\n <FilterGlyph :name=\"field.type\" />\n </span>\n <span class=\"min-w-0 flex-1 truncate\">{{ field.label }}</span>\n <span\n v-if=\"inUse.includes(field.name)\"\n class=\"inline-flex items-center gap-1.5 text-xs font-medium text-sui-accent\"\n >\n <span class=\"size-1.5 rounded-full bg-sui-accent-solid\" />\n {{ inUseLabel }}\n </span>\n </ListboxItem>\n </ListboxGroup>\n <p v-if=\"!groups.length\" class=\"m-0 px-2 py-3 text-13 text-sui-ink-body\">\n {{ noMatchLabel.replace('{query}', query) }}\n </p>\n </ListboxContent>\n </FilterFrame>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"FilterMenu.js","names":["_sfc_main","FilterMenu_vue_vue_type_script_setup_true_lang_default","FilterMenu_default"],"sources":["../../../src/components/Filters/FilterMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxGroup,\n ListboxGroupLabel,\n ListboxItem,\n ListboxRoot,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger\n} from 'reka-ui'\n\nimport Button from '../Button/Button.vue'\nimport FilterFrame from './FilterFrame.vue'\nimport FilterGlyph from './FilterGlyph.vue'\nimport { type FilterTriggerProps, useCustomTrigger } from './trigger'\nimport type { FilterField } from './types'\n\nexport interface FilterMenuProps {\n fields: FilterField[]\n /** Fields already filtering, marked \"In use\"; picking one should open its chip, not add a second. */\n inUse?: string[]\n /** chip: the dashed \"+ Filter\" in the view bar. button: the page header's Filters button, tinted while filters are in use. */\n as?: 'chip' | 'button'\n /** as=\"button\" only: ghost for a page header. Secondary by default, tinted while filters are in use. */\n variant?: 'secondary' | 'ghost' | 'tinted'\n /** The footer's status; \"{count} fields\" by default. */\n status?: string\n label?: string\n buttonLabel?: string\n searchPlaceholder?: string\n inUseLabel?: string\n addLabel?: string\n closeLabel?: string\n /** `{count}` is the number of fields. */\n fieldsLabel?: string\n /** `{query}` is what was typed. */\n noMatchLabel?: string\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<FilterMenuProps>(), {\n inUse: () => [],\n as: 'chip',\n variant: undefined,\n status: undefined,\n label: 'Filter',\n buttonLabel: 'Filters',\n searchPlaceholder: 'Filter by…',\n inUseLabel: 'In use',\n addLabel: 'Add',\n closeLabel: 'Close',\n fieldsLabel: '{count} fields',\n noMatchLabel: 'No field matches “{query}”.'\n})\n\nconst emit = defineEmits<{ pick: [name: string] }>()\n\nconst open = defineModel<boolean>('open', { default: false })\n\ndefineSlots<{\n /** Your own opener in place of the chip or button: spread `props` on it. `count` is the filters in use. */\n trigger?: (props: { open: boolean; toggle: () => void; count: number; props: FilterTriggerProps }) => unknown\n}>()\n\nconst attrs = useAttrs()\nconst custom = useCustomTrigger(open)\nconst query = ref('')\n// Only the keyboard's highlight gets the focus ring; the pointer's is just a tint.\nconst keyboard = ref(false)\n\nconst groups = computed(() => {\n const q = query.value.trim().toLowerCase()\n const shown = props.fields.filter((f) => !q || f.label.toLowerCase().includes(q))\n return [...new Set(shown.map((f) => f.group ?? ''))].map((name) => ({\n name,\n fields: shown.filter((f) => (f.group ?? '') === name)\n }))\n})\n\nfunction pick(name: unknown) {\n if (typeof name !== 'string') return\n open.value = false\n query.value = ''\n emit('pick', name)\n}\n\nfunction onOpen(isOpen: boolean) {\n if (!isOpen) query.value = ''\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n}\n</script>\n\n<!-- The field list behind \"+ Filter\": search, fields grouped with their type, and which are already filtering. -->\n<template>\n <PopoverRoot v-model:open=\"open\" @update:open=\"onOpen\">\n <PopoverAnchor v-if=\"$slots.trigger\" as-child>\n <slot :count=\"inUse.length\" name=\"trigger\" :open=\"open\" :props=\"custom.props.value\" :toggle=\"custom.toggle\" />\n </PopoverAnchor>\n <PopoverTrigger v-else-if=\"as === 'button'\" as-child>\n <Button v-bind=\"attrs\" :variant=\"variant ?? (inUse.length ? 'tinted' : 'secondary')\">\n <svg\n aria-hidden=\"true\"\n class=\"size-4 fill-none stroke-current\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M2.5 3.5h11l-4.25 5v4l-2.5 1v-5z\" />\n </svg>\n {{ buttonLabel }}\n </Button>\n </PopoverTrigger>\n <PopoverTrigger\n v-else\n v-bind=\"attrs\"\n class=\"inline-flex h-7.5 items-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong px-2 text-13 font-medium whitespace-nowrap text-sui-ink-muted outline-hidden transition-[border-color,box-shadow] duration-150 hover:border-sui-ink-muted hover:text-sui-ink-body focus-visible:sui-ring data-[state=open]:border-solid data-[state=open]:border-sui-accent-solid data-[state=open]:text-sui-accent data-[state=open]:shadow-[0_0_0_3px_rgb(var(--sui-focus-ring))]\"\n >\n <FilterGlyph name=\"plus\" />\n {{ label }}\n </PopoverTrigger>\n <PopoverPortal>\n <PopoverContent\n align=\"start\"\n :aria-label=\"$slots.trigger ? searchPlaceholder : undefined\"\n class=\"z-[1100] w-85 max-w-[calc(100vw-2rem)] origin-(--reka-popover-content-transform-origin) rounded-xl border border-sui-line bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-overlay-in\"\n :data-sui-panel=\"custom.panelKey\"\n :side-offset=\"8\"\n @close-auto-focus=\"custom.returnFocus\"\n @interact-outside=\"custom.ignoreTrigger\"\n @keydown=\"onKeydown\"\n @pointermove=\"keyboard = false\"\n >\n <ListboxRoot highlight-on-hover @update:model-value=\"pick\">\n <FilterFrame\n :close-label=\"closeLabel\"\n :enter-label=\"addLabel\"\n :status=\"status ?? fieldsLabel.replace('{count}', String(fields.length))\"\n >\n <div class=\"flex h-11 items-center gap-2 border-b border-sui-line-subtle px-3.5 text-sui-ink-muted\">\n <FilterGlyph class=\"size-4\" name=\"search\" />\n <ListboxFilter\n v-model=\"query\"\n :aria-label=\"searchPlaceholder\"\n auto-focus\n class=\"h-full min-w-0 flex-1 border-none bg-transparent p-0 text-sm text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n :placeholder=\"searchPlaceholder\"\n />\n </div>\n <ListboxContent\n :aria-label=\"searchPlaceholder\"\n class=\"group/list max-h-64 overflow-auto px-1.5 pt-1 pb-1.5 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxGroup v-for=\"group in groups\" :key=\"group.name\">\n <ListboxGroupLabel\n v-if=\"group.name\"\n class=\"m-0 px-2 pt-2.5 pb-1 text-11 font-semibold tracking-caps text-sui-ink-muted uppercase\"\n >\n {{ group.name }}\n </ListboxGroupLabel>\n <ListboxItem\n v-for=\"field in group.fields\"\n :key=\"field.name\"\n class=\"flex min-h-8 cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1 text-13.5 text-sui-ink outline-hidden select-none data-highlighted:bg-sui-sunken group-data-keyboard/list:data-highlighted:sui-ring-inset\"\n :value=\"field.name\"\n >\n <span\n class=\"flex size-6 shrink-0 items-center justify-center rounded-md bg-sui-sunken text-sui-ink-body\"\n >\n <FilterGlyph :name=\"field.type\" />\n </span>\n <span class=\"min-w-0 flex-1 truncate\">{{ field.label }}</span>\n <span\n v-if=\"inUse.includes(field.name)\"\n class=\"inline-flex items-center gap-1.5 text-xs font-medium text-sui-accent\"\n >\n <span class=\"size-1.5 rounded-full bg-sui-accent-solid\" />\n {{ inUseLabel }}\n </span>\n </ListboxItem>\n </ListboxGroup>\n <p v-if=\"!groups.length\" class=\"m-0 px-2 py-3 text-13 text-sui-ink-body\">\n {{ noMatchLabel.replace('{query}', query) }}\n </p>\n </ListboxContent>\n </FilterFrame>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type FilterTriggerProps } from './trigger';
|
|
1
2
|
import type { FilterField } from './types';
|
|
2
3
|
export interface FilterMenuProps {
|
|
3
4
|
fields: FilterField[];
|
|
@@ -5,6 +6,8 @@ export interface FilterMenuProps {
|
|
|
5
6
|
inUse?: string[];
|
|
6
7
|
/** chip: the dashed "+ Filter" in the view bar. button: the page header's Filters button, tinted while filters are in use. */
|
|
7
8
|
as?: 'chip' | 'button';
|
|
9
|
+
/** as="button" only: ghost for a page header. Secondary by default, tinted while filters are in use. */
|
|
10
|
+
variant?: 'secondary' | 'ghost' | 'tinted';
|
|
8
11
|
/** The footer's status; "{count} fields" by default. */
|
|
9
12
|
status?: string;
|
|
10
13
|
label?: string;
|
|
@@ -19,17 +22,27 @@ export interface FilterMenuProps {
|
|
|
19
22
|
noMatchLabel?: string;
|
|
20
23
|
}
|
|
21
24
|
type __VLS_Props = FilterMenuProps;
|
|
25
|
+
type __VLS_Slots = {
|
|
26
|
+
/** Your own opener in place of the chip or button: spread `props` on it. `count` is the filters in use. */
|
|
27
|
+
trigger?: (props: {
|
|
28
|
+
open: boolean;
|
|
29
|
+
toggle: () => void;
|
|
30
|
+
count: number;
|
|
31
|
+
props: FilterTriggerProps;
|
|
32
|
+
}) => unknown;
|
|
33
|
+
};
|
|
22
34
|
type __VLS_ModelProps = {
|
|
23
35
|
'open'?: boolean;
|
|
24
36
|
};
|
|
25
37
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
26
|
-
declare const
|
|
38
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
27
39
|
pick: (name: string) => any;
|
|
28
40
|
"update:open": (value: boolean) => any;
|
|
29
41
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
30
42
|
onPick?: ((name: string) => any) | undefined;
|
|
31
43
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
32
44
|
}>, {
|
|
45
|
+
variant: "secondary" | "tinted" | "ghost";
|
|
33
46
|
as: "button" | "chip";
|
|
34
47
|
label: string;
|
|
35
48
|
closeLabel: string;
|
|
@@ -42,5 +55,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
42
55
|
fieldsLabel: string;
|
|
43
56
|
noMatchLabel: string;
|
|
44
57
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
58
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
45
59
|
declare const _default: typeof __VLS_export;
|
|
46
60
|
export default _default;
|
|
61
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
62
|
+
new (): {
|
|
63
|
+
$slots: S;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import e from "../Button/Button.js";
|
|
2
2
|
import t from "./FilterFrame.js";
|
|
3
3
|
import n from "./FilterGlyph.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { useCustomTrigger as r } from "./trigger.js";
|
|
5
|
+
import { Fragment as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, mergeModels as p, mergeProps as m, openBlock as h, ref as g, renderList as _, renderSlot as v, toDisplayString as y, unref as b, useAttrs as x, useModel as S, withCtx as C } from "vue";
|
|
6
|
+
import { ListboxContent as w, ListboxFilter as T, ListboxGroup as E, ListboxGroupLabel as D, ListboxItem as O, ListboxRoot as k, PopoverAnchor as A, PopoverContent as j, PopoverPortal as M, PopoverRoot as N, PopoverTrigger as P } from "reka-ui";
|
|
6
7
|
//#region src/components/Filters/FilterMenu.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
-
var
|
|
8
|
+
var F = { class: "flex h-11 items-center gap-2 border-b border-sui-line-subtle px-3.5 text-sui-ink-muted" }, I = { class: "flex size-6 shrink-0 items-center justify-center rounded-md bg-sui-sunken text-sui-ink-body" }, L = { class: "min-w-0 flex-1 truncate" }, R = {
|
|
8
9
|
key: 0,
|
|
9
10
|
class: "inline-flex items-center gap-1.5 text-xs font-medium text-sui-accent"
|
|
10
|
-
},
|
|
11
|
+
}, z = {
|
|
11
12
|
key: 0,
|
|
12
13
|
class: "m-0 px-2 py-3 text-13 text-sui-ink-body"
|
|
13
|
-
},
|
|
14
|
+
}, B = /*@__PURE__*/ f({
|
|
14
15
|
inheritAttrs: !1,
|
|
15
16
|
__name: "FilterMenu",
|
|
16
|
-
props: /*@__PURE__*/
|
|
17
|
+
props: /*@__PURE__*/ p({
|
|
17
18
|
fields: {},
|
|
18
19
|
inUse: { default: () => [] },
|
|
19
20
|
as: { default: "chip" },
|
|
21
|
+
variant: { default: void 0 },
|
|
20
22
|
status: { default: void 0 },
|
|
21
23
|
label: { default: "Filter" },
|
|
22
24
|
buttonLabel: { default: "Filters" },
|
|
@@ -33,108 +35,123 @@ var M = { class: "flex h-11 items-center gap-2 border-b border-sui-line-subtle p
|
|
|
33
35
|
},
|
|
34
36
|
openModifiers: {}
|
|
35
37
|
}),
|
|
36
|
-
emits: /*@__PURE__*/
|
|
37
|
-
setup(
|
|
38
|
-
let
|
|
39
|
-
let e =
|
|
38
|
+
emits: /*@__PURE__*/ p(["pick"], ["update:open"]),
|
|
39
|
+
setup(f, { emit: p }) {
|
|
40
|
+
let B = f, V = p, H = S(f, "open"), U = x(), W = r(H), G = g(""), K = g(!1), q = a(() => {
|
|
41
|
+
let e = G.value.trim().toLowerCase(), t = B.fields.filter((t) => !e || t.label.toLowerCase().includes(e));
|
|
40
42
|
return [...new Set(t.map((e) => e.group ?? ""))].map((e) => ({
|
|
41
43
|
name: e,
|
|
42
44
|
fields: t.filter((t) => (t.group ?? "") === e)
|
|
43
45
|
}));
|
|
44
46
|
});
|
|
45
|
-
function
|
|
46
|
-
typeof e == "string" && (
|
|
47
|
+
function J(e) {
|
|
48
|
+
typeof e == "string" && (H.value = !1, G.value = "", V("pick", e));
|
|
47
49
|
}
|
|
48
|
-
function
|
|
49
|
-
e || (
|
|
50
|
+
function Y(e) {
|
|
51
|
+
e || (G.value = "");
|
|
50
52
|
}
|
|
51
|
-
function
|
|
53
|
+
function X(e) {
|
|
52
54
|
[
|
|
53
55
|
"ArrowUp",
|
|
54
56
|
"ArrowDown",
|
|
55
57
|
"Home",
|
|
56
58
|
"End"
|
|
57
|
-
].includes(e.key) && (
|
|
59
|
+
].includes(e.key) && (K.value = !0);
|
|
58
60
|
}
|
|
59
|
-
return (
|
|
60
|
-
open:
|
|
61
|
-
"onUpdate:open": [
|
|
61
|
+
return (r, a) => (h(), o(b(N), {
|
|
62
|
+
open: H.value,
|
|
63
|
+
"onUpdate:open": [a[2] ||= (e) => H.value = e, Y]
|
|
62
64
|
}, {
|
|
63
|
-
default:
|
|
65
|
+
default: C(() => [r.$slots.trigger ? (h(), o(b(A), {
|
|
64
66
|
key: 0,
|
|
65
67
|
"as-child": ""
|
|
66
68
|
}, {
|
|
67
|
-
default:
|
|
68
|
-
|
|
69
|
+
default: C(() => [v(r.$slots, "trigger", {
|
|
70
|
+
count: f.inUse.length,
|
|
71
|
+
open: H.value,
|
|
72
|
+
props: b(W).props.value,
|
|
73
|
+
toggle: b(W).toggle
|
|
74
|
+
})]),
|
|
75
|
+
_: 3
|
|
76
|
+
})) : f.as === "button" ? (h(), o(b(P), {
|
|
77
|
+
key: 1,
|
|
78
|
+
"as-child": ""
|
|
79
|
+
}, {
|
|
80
|
+
default: C(() => [d(e, m(b(U), { variant: f.variant ?? (f.inUse.length ? "tinted" : "secondary") }), {
|
|
81
|
+
default: C(() => [a[3] ||= l("svg", {
|
|
69
82
|
"aria-hidden": "true",
|
|
70
83
|
class: "size-4 fill-none stroke-current",
|
|
71
84
|
"stroke-linejoin": "round",
|
|
72
85
|
"stroke-width": "1.5",
|
|
73
86
|
viewBox: "0 0 16 16"
|
|
74
|
-
}, [
|
|
87
|
+
}, [l("path", { d: "M2.5 3.5h11l-4.25 5v4l-2.5 1v-5z" })], -1), u(" " + y(f.buttonLabel), 1)]),
|
|
75
88
|
_: 1
|
|
76
89
|
}, 16, ["variant"])]),
|
|
77
90
|
_: 1
|
|
78
|
-
})) : (
|
|
79
|
-
default:
|
|
91
|
+
})) : (h(), o(b(P), m({ key: 2 }, b(U), { class: "inline-flex h-7.5 items-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong px-2 text-13 font-medium whitespace-nowrap text-sui-ink-muted outline-hidden transition-[border-color,box-shadow] duration-150 hover:border-sui-ink-muted hover:text-sui-ink-body focus-visible:sui-ring data-[state=open]:border-solid data-[state=open]:border-sui-accent-solid data-[state=open]:text-sui-accent data-[state=open]:shadow-[0_0_0_3px_rgb(var(--sui-focus-ring))]" }), {
|
|
92
|
+
default: C(() => [d(n, { name: "plus" }), u(" " + y(f.label), 1)]),
|
|
80
93
|
_: 1
|
|
81
|
-
}, 16)),
|
|
82
|
-
default:
|
|
94
|
+
}, 16)), d(b(M), null, {
|
|
95
|
+
default: C(() => [d(b(j), {
|
|
83
96
|
align: "start",
|
|
97
|
+
"aria-label": r.$slots.trigger ? f.searchPlaceholder : void 0,
|
|
84
98
|
class: "z-[1100] w-85 max-w-[calc(100vw-2rem)] origin-(--reka-popover-content-transform-origin) rounded-xl border border-sui-line bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-overlay-in",
|
|
99
|
+
"data-sui-panel": b(W).panelKey,
|
|
85
100
|
"side-offset": 8,
|
|
86
|
-
|
|
87
|
-
|
|
101
|
+
onCloseAutoFocus: b(W).returnFocus,
|
|
102
|
+
onInteractOutside: b(W).ignoreTrigger,
|
|
103
|
+
onKeydown: X,
|
|
104
|
+
onPointermove: a[1] ||= (e) => K.value = !1
|
|
88
105
|
}, {
|
|
89
|
-
default:
|
|
106
|
+
default: C(() => [d(b(k), {
|
|
90
107
|
"highlight-on-hover": "",
|
|
91
|
-
"onUpdate:modelValue":
|
|
108
|
+
"onUpdate:modelValue": J
|
|
92
109
|
}, {
|
|
93
|
-
default:
|
|
94
|
-
"close-label":
|
|
95
|
-
"enter-label":
|
|
96
|
-
status:
|
|
110
|
+
default: C(() => [d(t, {
|
|
111
|
+
"close-label": f.closeLabel,
|
|
112
|
+
"enter-label": f.addLabel,
|
|
113
|
+
status: f.status ?? f.fieldsLabel.replace("{count}", String(f.fields.length))
|
|
97
114
|
}, {
|
|
98
|
-
default:
|
|
115
|
+
default: C(() => [l("div", F, [d(n, {
|
|
99
116
|
class: "size-4",
|
|
100
117
|
name: "search"
|
|
101
|
-
}),
|
|
102
|
-
modelValue:
|
|
103
|
-
"onUpdate:modelValue":
|
|
104
|
-
"aria-label":
|
|
118
|
+
}), d(b(T), {
|
|
119
|
+
modelValue: G.value,
|
|
120
|
+
"onUpdate:modelValue": a[0] ||= (e) => G.value = e,
|
|
121
|
+
"aria-label": f.searchPlaceholder,
|
|
105
122
|
"auto-focus": "",
|
|
106
123
|
class: "h-full min-w-0 flex-1 border-none bg-transparent p-0 text-sm text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden",
|
|
107
|
-
placeholder:
|
|
124
|
+
placeholder: f.searchPlaceholder
|
|
108
125
|
}, null, 8, [
|
|
109
126
|
"modelValue",
|
|
110
127
|
"aria-label",
|
|
111
128
|
"placeholder"
|
|
112
|
-
])]),
|
|
113
|
-
"aria-label":
|
|
129
|
+
])]), d(b(w), {
|
|
130
|
+
"aria-label": f.searchPlaceholder,
|
|
114
131
|
class: "group/list max-h-64 overflow-auto px-1.5 pt-1 pb-1.5 outline-hidden",
|
|
115
|
-
"data-keyboard":
|
|
132
|
+
"data-keyboard": K.value || void 0
|
|
116
133
|
}, {
|
|
117
|
-
default:
|
|
118
|
-
default:
|
|
134
|
+
default: C(() => [(h(!0), c(i, null, _(q.value, (e) => (h(), o(b(E), { key: e.name }, {
|
|
135
|
+
default: C(() => [e.name ? (h(), o(b(D), {
|
|
119
136
|
key: 0,
|
|
120
137
|
class: "m-0 px-2 pt-2.5 pb-1 text-11 font-semibold tracking-caps text-sui-ink-muted uppercase"
|
|
121
138
|
}, {
|
|
122
|
-
default:
|
|
139
|
+
default: C(() => [u(y(e.name), 1)]),
|
|
123
140
|
_: 2
|
|
124
|
-
}, 1024)) :
|
|
141
|
+
}, 1024)) : s("", !0), (h(!0), c(i, null, _(e.fields, (e) => (h(), o(b(O), {
|
|
125
142
|
key: e.name,
|
|
126
143
|
class: "flex min-h-8 cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1 text-13.5 text-sui-ink outline-hidden select-none data-highlighted:bg-sui-sunken group-data-keyboard/list:data-highlighted:sui-ring-inset",
|
|
127
144
|
value: e.name
|
|
128
145
|
}, {
|
|
129
|
-
default:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
146
|
+
default: C(() => [
|
|
147
|
+
l("span", I, [d(n, { name: e.type }, null, 8, ["name"])]),
|
|
148
|
+
l("span", L, y(e.label), 1),
|
|
149
|
+
f.inUse.includes(e.name) ? (h(), c("span", R, [a[4] ||= l("span", { class: "size-1.5 rounded-full bg-sui-accent-solid" }, null, -1), u(" " + y(f.inUseLabel), 1)])) : s("", !0)
|
|
133
150
|
]),
|
|
134
151
|
_: 2
|
|
135
152
|
}, 1032, ["value"]))), 128))]),
|
|
136
153
|
_: 2
|
|
137
|
-
}, 1024))), 128)),
|
|
154
|
+
}, 1024))), 128)), q.value.length ? s("", !0) : (h(), c("p", z, y(f.noMatchLabel.replace("{query}", G.value)), 1))]),
|
|
138
155
|
_: 1
|
|
139
156
|
}, 8, ["aria-label", "data-keyboard"])]),
|
|
140
157
|
_: 1
|
|
@@ -146,14 +163,19 @@ var M = { class: "flex h-11 items-center gap-2 border-b border-sui-line-subtle p
|
|
|
146
163
|
_: 1
|
|
147
164
|
})]),
|
|
148
165
|
_: 1
|
|
149
|
-
}
|
|
166
|
+
}, 8, [
|
|
167
|
+
"aria-label",
|
|
168
|
+
"data-sui-panel",
|
|
169
|
+
"onCloseAutoFocus",
|
|
170
|
+
"onInteractOutside"
|
|
171
|
+
])]),
|
|
150
172
|
_: 1
|
|
151
173
|
})]),
|
|
152
|
-
_:
|
|
174
|
+
_: 3
|
|
153
175
|
}, 8, ["open"]));
|
|
154
176
|
}
|
|
155
177
|
});
|
|
156
178
|
//#endregion
|
|
157
|
-
export {
|
|
179
|
+
export { B as default };
|
|
158
180
|
|
|
159
181
|
//# sourceMappingURL=FilterMenu.vue_vue_type_script_setup_true_lang.js.map
|