@sparklingopinions/sparkling-ui 0.5.0 → 0.7.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/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/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 -67
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/index.d.ts +1 -0
- 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/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 +25 -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 +65 -56
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- 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,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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterMenu.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","Button","_mergeProps","_createElementVNode","_createTextVNode","_toDisplayString","FilterGlyph","FilterFrame","_createElementBlock","_Fragment","_renderList","_createCommentVNode","Button_default","FilterFrame_default","FilterGlyph_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","FilterMenu_vue_vue_type_script_setup_true_lang_default","\"open\"","\"openModifiers\"","__emit","props","__props","emit","open","useModel","attrs","useAttrs","query","ref","keyboard","groups","computed","q","shown","f","name","pick","onOpen","isOpen","onKeydown","event","openBlock","createBlock","unref","PopoverRoot","_cache","$event","withCtx","PopoverTrigger","createVNode","mergeProps","createElementVNode","createTextVNode","toDisplayString","PopoverPortal","PopoverContent","ListboxRoot","ListboxFilter","ListboxContent","createElementBlock","Fragment","renderList","ListboxGroup","group","ListboxGroupLabel","createCommentVNode","ListboxItem","field"],"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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CA,IAAM6B,IAAQC,GAcRC,IAAOH,GAEPI,IAAOhC,EAAoB8B,GAAC,MAA0B,GAEtDI,IAAQC,EAAS,GACjBC,IAAQC,EAAI,EAAE,GAEdC,IAAWD,EAAI,EAAK,GAEpBE,IAASC,QAAe;GAC5B,IAAMC,IAAIL,EAAM,MAAM,KAAK,CAAC,CAAC,YAAY,GACnCM,IAAQb,EAAM,OAAO,QAAQ,MAAM,CAACY,KAAKE,EAAE,MAAM,YAAY,CAAC,CAAC,SAASF,CAAC,CAAC;GAChF,OAAO,CAAC,GAAG,IAAI,IAAIC,EAAM,KAAK,MAAMC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,OAAU;IAClE;IACA,QAAQD,EAAM,QAAQ,OAAOC,EAAE,SAAS,QAAQC,CAAI;GACtD,EAAE;EACJ,CAAC;EAED,SAASC,EAAK,GAAe;GAC3B,AAAI,OAAOD,KAAS,aACpB,EAAK,QAAQ,IACb,EAAM,QAAQ,IACdb,EAAK,QAAQa,CAAI;EACnB;EAEA,SAASE,EAAO,GAAiB;GAC/B,AAAKC,MAAQ,EAAM,QAAQ;EAC7B;EAEA,SAASC,EAAU,GAAsB;GACvC,AAAI;IAAC;IAAW;IAAa;IAAQ;GAAK,CAAC,CAAC,SAASC,EAAM,GAAG,MAAG,EAAS,QAAQ;EACpF;E,kBAKEhD,EAAA,GAAAC,EAwFcC,EAAAkD,CAAA,GAAA;GAxFO,MAAMrB,EAAA;G,kBAAA,AAAAsB,EAAA,QAAA,MAAA,EAAI,QAAAC,GAAgBT,C;;GAC7C,SAAA1C,QAaiB,CAbK0B,EAAA,OAAE,YAAxB7B,EAAA,GAAAC,EAaiBC,EAAAsD,CAAA,GAAA;;IAbsB,YAAA;;IACrC,SAAArD,QAWS,CAXTC,EAWSC,GAXTC,EAAgBJ,EAWP+B,CAAA,GAXY,EAAG,SAASJ,EAAA,MAAM,SAAM,WAAA,Y;KAC3C,SAAA1B,QAQM,CARN,AAAAkD,EAAA,OAAA9C,EAQM,OAAA;MAPJ,eAAY;MACZ,OAAM;MACN,mBAAgB;MAChB,gBAAa;MACb,SAAQ;K,IAERA,EAA6C,QAAA,EAAvC,GAAE,mCAAkC,CAAA,C,QACtCC,EAAA,MACNC,EAAGoB,EAAA,WAAW,GAAA,CAAA,C;;;;G,OAGlB7B,EAAA,GAAAC,EAOiBC,EAAAsD,CAAA,GAPjBlD,EAOiB,EAAA,KAAA,EAAA,GALPJ,EAAA+B,CAAA,GAAK,EACb,OAAM,odAAmd,CAAA,GAAA;IAEzd,SAAA9B,QAA2B,CAA3BC,EAA2BM,GAAA,EAAd,MAAK,OAAM,CAAA,GAAGF,EAAA,MAC3BC,EAAGoB,EAAA,KAAK,GAAA,CAAA,C;;G,SAEVzB,EAgEgBF,EAAA4D,CAAA,GAAA,MAAA;IA/Dd,SAAA3D,QA8DiB,CA9DjBC,EA8DiBF,EAAA6D,CAAA,GAAA;KA7Df,OAAM;KACN,OAAM;KACL,eAAa;KACJ;KACT,eAAW,AAAAV,EAAA,QAAA,MAAE,EAAA,QAAQ;;KAEtB,SAAAlD,QAsDc,CAtDdC,EAsDcF,EAAA8D,CAAA,GAAA;MAtDD,sBAAA;MAAoB,uBAAoBpB;;MACnD,SAAAzC,QAoDc,CApDdC,EAoDcO,GAAA;OAnDX,eAAakB,EAAA;OACb,eAAaA,EAAA;OACb,QAAQA,EAAA,UAAUA,EAAA,YAAY,QAAO,WAAY,OAAOA,EAAA,OAAO,MAAM,CAAA;;OAEtE,SAAA1B,QASM,CATNI,EASM,OATNY,GASM,CARJf,EAA4CM,GAAA;QAA/B,OAAM;QAAS,MAAK;O,IACjCN,EAMEF,EAAA+D,CAAA,GAAA;QALS,YAAA9B,EAAA;QAAA,uBAAA,AAAAkB,EAAA,QAAA,MAAA,EAAK,QAAAC;QACb,cAAYzB,EAAA;QACb,cAAA;QACA,OAAM;QACL,aAAaA,EAAA;;;;;O,MAGlBzB,EAoCiBF,EAAAgE,CAAA,GAAA;QAnCd,cAAYrC,EAAA;QACb,OAAM;QACL,iBAAeQ,EAAA,SAAY,KAAA;;QAEd,SAAAlC,QAAuB,EAArCH,EAAA,EAAA,GAAAY,EA2BeC,GAAA,MAAAC,EA3BewB,EAAA,QAAT,OAArBtC,EAAA,GAAAC,EA2BeC,EAAAoE,CAAA,GAAA,EA3BwB,KAAKC,EAAM,K;SAChD,SAAApE,QAKoB,CAJZoE,EAAM,QADdvE,EAAA,GAAAC,EAKoBC,EAAAsE,CAAA,GAAA;;UAHlB,OAAM;;UAEN,SAAArE,QAAgB,CAAbK,EAAAC,EAAA8D,EAAM,IAAI,GAAA,CAAA,C;;S,wBAEfvE,EAAA,EAAA,GAAAY,EAmBcC,GAAA,MAAAC,EAlBIyD,EAAM,SAAf,OADTvE,EAAA,GAAAC,EAmBcC,EAAAwE,CAAA,GAAA;UAjBX,KAAKC,EAAM;UACZ,OAAM;UACL,OAAOA,EAAM;;UAEd,SAAAxE,QAIO;WAJPI,EAIO,QAJPa,GAIO,CADLhB,EAAkCM,GAAA,EAApB,MAAMiE,EAAM,K;WAE5BpE,EAA8D,QAA9Dc,GAA8DZ,EAArBkE,EAAM,KAAK,GAAA,CAAA;WAE5C9C,EAAA,MAAM,SAAS8C,EAAM,IAAI,KADjC3E,EAAA,GAAAY,EAMO,QANPU,GAMO,CAFL,AAAA+B,EAAA,OAAA9C,EAA0D,QAAA,EAApD,OAAM,4CAA2C,GAAA,MAAA,EAAA,GAAGC,EAAA,MAC1DC,EAAGoB,EAAA,UAAU,GAAA,CAAA,C;;;;;Q,mBAITS,EAAA,MAAO,S,aAAjBtC,EAAA,GAAAY,EAEI,KAFJW,GAEId,EADCoB,EAAA,aAAa,QAAO,WAAYM,EAAA,KAAK,CAAA,GAAA,CAAA,E"}
|
|
1
|
+
{"version":3,"file":"FilterMenu.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_openBlock","_createBlock","_unref","_withCtx","_renderSlot","_createVNode","Button","_mergeProps","_createElementVNode","_createTextVNode","_toDisplayString","FilterGlyph","FilterFrame","_createElementBlock","_Fragment","_renderList","_createCommentVNode","Button_default","FilterFrame_default","FilterGlyph_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","FilterMenu_vue_vue_type_script_setup_true_lang_default","\"open\"","\"openModifiers\"","__emit","props","__props","emit","open","useModel","attrs","useAttrs","custom","useCustomTrigger","query","ref","keyboard","groups","computed","q","shown","f","name","pick","onOpen","isOpen","onKeydown","event","openBlock","createBlock","unref","PopoverRoot","_cache","$event","withCtx","_ctx","PopoverAnchor","renderSlot","PopoverTrigger","createVNode","mergeProps","createElementVNode","createTextVNode","toDisplayString","PopoverPortal","PopoverContent","ListboxRoot","ListboxFilter","ListboxContent","createElementBlock","Fragment","renderList","ListboxGroup","group","ListboxGroupLabel","createCommentVNode","ListboxItem","field"],"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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SortMenu.js","names":["_sfc_main","SortMenu_vue_vue_type_script_setup_true_lang_default","SortMenu_default"],"sources":["../../../src/components/Filters/SortMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport {
|
|
1
|
+
{"version":3,"file":"SortMenu.js","names":["_sfc_main","SortMenu_vue_vue_type_script_setup_true_lang_default","SortMenu_default"],"sources":["../../../src/components/Filters/SortMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport {\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n RadioGroupItem,\n RadioGroupRoot\n} from 'reka-ui'\n\nimport Button from '../Button/Button.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport FilterFrame from './FilterFrame.vue'\nimport FilterGlyph from './FilterGlyph.vue'\nimport SortArrow from './SortArrow.vue'\nimport { sortDirections } from './defaults'\nimport { type FilterTriggerProps, useCustomTrigger } from './trigger'\nimport type { FilterField, FilterFieldType, ViewSort } from './types'\n\nexport interface SortMenuProps {\n /** The sortable fields. */\n options: FilterField[]\n /** chip: the sort in the view bar, which shows only while there is one. button: the page header's Sort button. */\n as?: 'chip' | 'button'\n /** as=\"button\" only: ghost for a page header. Secondary by default, tinted while sorted. */\n variant?: 'secondary' | 'ghost' | 'tinted'\n /** Boards can't sort: disable the button, with a Tooltip saying why. */\n disabled?: boolean\n status?: string\n /** The two directions' words for each field type, ascending first. */\n directionLabels?: Partial<Record<FilterFieldType, [string, string]>>\n title?: string\n buttonLabel?: string\n clearLabel?: string\n directionLabel?: string\n doneLabel?: string\n closeLabel?: string\n}\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SortMenuProps>(), {\n as: 'chip',\n variant: undefined,\n status: undefined,\n directionLabels: () => ({}),\n title: 'Sort by',\n buttonLabel: 'Sort',\n clearLabel: 'Clear sort',\n directionLabel: 'Direction',\n doneLabel: 'Done',\n closeLabel: 'Close'\n})\n\nconst sort = defineModel<ViewSort | null>({ default: null })\nconst open = defineModel<boolean>('open', { default: false })\n\ndefineSlots<{\n /** Your own opener in place of the chip or button: spread `props` on it. `label` reads like the chip. */\n trigger?: (props: {\n open: boolean\n toggle: () => void\n active: boolean\n label: string\n props: FilterTriggerProps\n }) => unknown\n}>()\n\nconst attrs = useAttrs()\nconst custom = useCustomTrigger(open)\n\nconst current = computed(() => (sort.value ? props.options.find((o) => o.name === sort.value!.name) : undefined))\nconst words = (type: FilterFieldType) => props.directionLabels[type] ?? sortDirections[type]\nconst dirLabel = computed(() => (current.value ? words(current.value.type)[sort.value!.dir === 'desc' ? 1 : 0] : ''))\n\nfunction pickField(name: string) {\n const field = props.options.find((o) => o.name === name)\n sort.value = { name, dir: sort.value?.name === name ? sort.value.dir : (field?.sortDir ?? 'asc') }\n}\n\nfunction clear() {\n sort.value = null\n open.value = false\n}\n\nconst row =\n 'flex min-h-9 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'\n</script>\n\n<!-- A view's sort: the header's Sort button or the view bar's chip (\"Name, A → Z\") open a panel of fields and a direction. -->\n<template>\n <PopoverRoot v-if=\"$slots.trigger || as === 'button' || current\" v-model:open=\"open\">\n <PopoverAnchor v-if=\"$slots.trigger\" as-child>\n <slot\n :active=\"!!current\"\n :label=\"current ? `${current.label}, ${dirLabel}` : ''\"\n name=\"trigger\"\n :open=\"open\"\n :props=\"custom.props.value\"\n :toggle=\"custom.toggle\"\n />\n </PopoverAnchor>\n <PopoverTrigger v-else-if=\"as === 'button'\" as-child>\n <Button v-bind=\"attrs\" :disabled=\"disabled\" :variant=\"variant ?? (current ? 'tinted' : 'secondary')\">\n <svg\n aria-hidden=\"true\"\n class=\"size-4 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M5 13V3M2.5 5.5 5 3l2.5 2.5M11 3v10M8.5 10.5 11 13l2.5-2.5\" />\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-sui-accent-line bg-sui-accent-wash pr-1.5 pl-2 text-13 whitespace-nowrap text-sui-accent outline-hidden transition-[border-color,box-shadow] duration-150 hover:border-sui-accent-bright focus-visible:sui-ring data-[state=open]:border-sui-accent-solid data-[state=open]:shadow-[0_0_0_3px_rgb(var(--sui-focus-ring))]\"\n >\n <SortArrow :dir=\"sort!.dir\" />\n <span\n ><span class=\"font-medium\">{{ current!.label }},</span>{{ ' ' }}{{ dirLabel }}</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 :aria-label=\"$slots.trigger ? title : 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 >\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 <svg\n aria-hidden=\"true\"\n class=\"size-4 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M5 13V3M2.5 5.5 5 3l2.5 2.5M11 3v10M8.5 10.5 11 13l2.5-2.5\" />\n </svg>\n <span class=\"text-sm font-semibold text-sui-ink\">{{ title }}</span>\n <button\n v-if=\"current\"\n class=\"ml-auto inline-flex h-7 items-center rounded-lg px-2 text-12.5 font-medium text-sui-ink-muted outline-hidden transition-colors duration-150 hover:bg-sui-sunken hover:text-sui-ink focus-visible:sui-ring-inset\"\n type=\"button\"\n @click=\"clear\"\n >\n {{ clearLabel }}\n </button>\n </div>\n <RadioGroupRoot\n :aria-label=\"title\"\n class=\"max-h-64 overflow-auto px-1.5 pt-1 pb-1.5\"\n :model-value=\"sort?.name\"\n @update:model-value=\"pickField($event as string)\"\n >\n <RadioGroupItem\n v-for=\"option in options\"\n :key=\"option.name\"\n :class=\"[\n row,\n option.name === sort?.name\n ? 'bg-sui-accent-wash font-semibold text-sui-accent'\n : 'text-sui-ink hover:bg-sui-sunken'\n ]\"\n :value=\"option.name\"\n >\n <span\n class=\"flex size-6 shrink-0 items-center justify-center rounded-md\"\n :class=\"\n option.name === sort?.name ? 'bg-sui-surface text-sui-accent' : 'bg-sui-sunken text-sui-ink-body'\n \"\n >\n <FilterGlyph :name=\"option.type\" />\n </span>\n <span class=\"min-w-0 flex-1 truncate\">{{ option.label }}</span>\n <CheckIcon v-if=\"option.name === sort?.name\" />\n </RadioGroupItem>\n </RadioGroupRoot>\n <RadioGroupRoot\n v-if=\"current\"\n :aria-label=\"directionLabel\"\n class=\"mx-3 mb-3 grid grid-cols-2 gap-0.5 rounded-lg bg-sui-sunken p-0.75\"\n :model-value=\"sort!.dir\"\n orientation=\"horizontal\"\n @update:model-value=\"sort = { name: sort!.name, dir: $event as ViewSort['dir'] }\"\n >\n <RadioGroupItem\n v-for=\"(dir, i) in ['asc', 'desc'] as const\"\n :key=\"dir\"\n class=\"flex h-9 items-center justify-center gap-1.5 rounded-md text-13 font-medium outline-hidden transition-colors duration-150 focus-visible:sui-ring-inset\"\n :class=\"\n sort!.dir === dir\n ? 'bg-sui-surface text-sui-ink shadow-(--sui-shadow-raised) ring-1 ring-sui-line-subtle'\n : 'text-sui-ink-body hover:text-sui-ink'\n \"\n :value=\"dir\"\n >\n <SortArrow :dir=\"dir\" />\n {{ words(current.type)[i] }}\n </RadioGroupItem>\n </RadioGroupRoot>\n </FilterFrame>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { type FilterTriggerProps } from './trigger';
|
|
1
2
|
import type { FilterField, FilterFieldType, ViewSort } from './types';
|
|
2
3
|
export interface SortMenuProps {
|
|
3
4
|
/** The sortable fields. */
|
|
4
5
|
options: FilterField[];
|
|
5
6
|
/** chip: the sort in the view bar, which shows only while there is one. button: the page header's Sort button. */
|
|
6
7
|
as?: 'chip' | 'button';
|
|
8
|
+
/** as="button" only: ghost for a page header. Secondary by default, tinted while sorted. */
|
|
9
|
+
variant?: 'secondary' | 'ghost' | 'tinted';
|
|
7
10
|
/** Boards can't sort: disable the button, with a Tooltip saying why. */
|
|
8
11
|
disabled?: boolean;
|
|
9
12
|
status?: string;
|
|
@@ -17,18 +20,29 @@ export interface SortMenuProps {
|
|
|
17
20
|
closeLabel?: string;
|
|
18
21
|
}
|
|
19
22
|
type __VLS_Props = SortMenuProps;
|
|
23
|
+
type __VLS_Slots = {
|
|
24
|
+
/** Your own opener in place of the chip or button: spread `props` on it. `label` reads like the chip. */
|
|
25
|
+
trigger?: (props: {
|
|
26
|
+
open: boolean;
|
|
27
|
+
toggle: () => void;
|
|
28
|
+
active: boolean;
|
|
29
|
+
label: string;
|
|
30
|
+
props: FilterTriggerProps;
|
|
31
|
+
}) => unknown;
|
|
32
|
+
};
|
|
20
33
|
type __VLS_ModelProps = {
|
|
21
34
|
modelValue?: ViewSort | null;
|
|
22
35
|
'open'?: boolean;
|
|
23
36
|
};
|
|
24
37
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
25
|
-
declare const
|
|
38
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
26
39
|
"update:modelValue": (value: ViewSort | null) => any;
|
|
27
40
|
"update:open": (value: boolean) => any;
|
|
28
41
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
29
42
|
"onUpdate:modelValue"?: ((value: ViewSort | null) => any) | undefined;
|
|
30
43
|
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
31
44
|
}>, {
|
|
45
|
+
variant: "secondary" | "tinted" | "ghost";
|
|
32
46
|
as: "button" | "chip";
|
|
33
47
|
title: string;
|
|
34
48
|
clearLabel: string;
|
|
@@ -39,5 +53,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
39
53
|
directionLabel: string;
|
|
40
54
|
doneLabel: string;
|
|
41
55
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
56
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
42
57
|
declare const _default: typeof __VLS_export;
|
|
43
58
|
export default _default;
|
|
59
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
60
|
+
new (): {
|
|
61
|
+
$slots: S;
|
|
62
|
+
};
|
|
63
|
+
};
|