@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
|
@@ -3,16 +3,18 @@ import t from "../internal/CheckIcon.js";
|
|
|
3
3
|
import n from "./FilterFrame.js";
|
|
4
4
|
import r from "./FilterGlyph.js";
|
|
5
5
|
import { sortDirections as i } from "./defaults.js";
|
|
6
|
-
import a from "./
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
6
|
+
import { useCustomTrigger as a } from "./trigger.js";
|
|
7
|
+
import o from "./SortArrow.js";
|
|
8
|
+
import { Fragment as s, computed as c, createBlock as l, createCommentVNode as u, createElementBlock as d, createElementVNode as f, createTextVNode as p, createVNode as m, defineComponent as h, mergeModels as g, mergeProps as _, normalizeClass as v, openBlock as y, renderList as b, renderSlot as x, toDisplayString as S, unref as C, useAttrs as w, useModel as T, withCtx as E } from "vue";
|
|
9
|
+
import { PopoverAnchor as D, PopoverContent as O, PopoverPortal as k, PopoverRoot as A, PopoverTrigger as j, RadioGroupItem as M, RadioGroupRoot as N } from "reka-ui";
|
|
9
10
|
//#region src/components/Filters/SortMenu.vue?vue&type=script&setup=true&lang.ts
|
|
10
|
-
var
|
|
11
|
+
var P = { class: "font-medium" }, F = { class: "flex h-11 items-center gap-1.5 pr-1.5 pl-3.5 text-sui-ink-muted" }, I = { class: "text-sm font-semibold text-sui-ink" }, L = { class: "min-w-0 flex-1 truncate" }, R = "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", z = /*@__PURE__*/ h({
|
|
11
12
|
inheritAttrs: !1,
|
|
12
13
|
__name: "SortMenu",
|
|
13
|
-
props: /*@__PURE__*/
|
|
14
|
+
props: /*@__PURE__*/ g({
|
|
14
15
|
options: {},
|
|
15
16
|
as: { default: "chip" },
|
|
17
|
+
variant: { default: void 0 },
|
|
16
18
|
disabled: { type: Boolean },
|
|
17
19
|
status: { default: void 0 },
|
|
18
20
|
directionLabels: { default: () => ({}) },
|
|
@@ -32,126 +34,142 @@ var j = { class: "font-medium" }, M = { class: "flex h-11 items-center gap-1.5 p
|
|
|
32
34
|
openModifiers: {}
|
|
33
35
|
}),
|
|
34
36
|
emits: ["update:modelValue", "update:open"],
|
|
35
|
-
setup(
|
|
36
|
-
let
|
|
37
|
-
function
|
|
38
|
-
let t =
|
|
39
|
-
|
|
37
|
+
setup(h) {
|
|
38
|
+
let g = h, z = T(h, "modelValue"), B = T(h, "open"), V = w(), H = a(B), U = c(() => z.value ? g.options.find((e) => e.name === z.value.name) : void 0), W = (e) => g.directionLabels[e] ?? i[e], G = c(() => U.value ? W(U.value.type)[+(z.value.dir === "desc")] : "");
|
|
39
|
+
function K(e) {
|
|
40
|
+
let t = g.options.find((t) => t.name === e);
|
|
41
|
+
z.value = {
|
|
40
42
|
name: e,
|
|
41
|
-
dir:
|
|
43
|
+
dir: z.value?.name === e ? z.value.dir : t?.sortDir ?? "asc"
|
|
42
44
|
};
|
|
43
45
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
+
function q() {
|
|
47
|
+
z.value = null, B.value = !1;
|
|
46
48
|
}
|
|
47
|
-
return (i,
|
|
49
|
+
return (i, a) => i.$slots.trigger || h.as === "button" || U.value ? (y(), l(C(A), {
|
|
48
50
|
key: 0,
|
|
49
|
-
open:
|
|
50
|
-
"onUpdate:open":
|
|
51
|
+
open: B.value,
|
|
52
|
+
"onUpdate:open": a[3] ||= (e) => B.value = e
|
|
51
53
|
}, {
|
|
52
|
-
default:
|
|
54
|
+
default: E(() => [i.$slots.trigger ? (y(), l(C(D), {
|
|
53
55
|
key: 0,
|
|
54
56
|
"as-child": ""
|
|
55
57
|
}, {
|
|
56
|
-
default:
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
default: E(() => [x(i.$slots, "trigger", {
|
|
59
|
+
active: !!U.value,
|
|
60
|
+
label: U.value ? `${U.value.label}, ${G.value}` : "",
|
|
61
|
+
open: B.value,
|
|
62
|
+
props: C(H).props.value,
|
|
63
|
+
toggle: C(H).toggle
|
|
64
|
+
})]),
|
|
65
|
+
_: 3
|
|
66
|
+
})) : h.as === "button" ? (y(), l(C(j), {
|
|
67
|
+
key: 1,
|
|
68
|
+
"as-child": ""
|
|
69
|
+
}, {
|
|
70
|
+
default: E(() => [m(e, _(C(V), {
|
|
71
|
+
disabled: h.disabled,
|
|
72
|
+
variant: h.variant ?? (U.value ? "tinted" : "secondary")
|
|
59
73
|
}), {
|
|
60
|
-
default:
|
|
74
|
+
default: E(() => [a[4] ||= f("svg", {
|
|
61
75
|
"aria-hidden": "true",
|
|
62
76
|
class: "size-4 fill-none stroke-current",
|
|
63
77
|
"stroke-linecap": "round",
|
|
64
78
|
"stroke-linejoin": "round",
|
|
65
79
|
"stroke-width": "1.5",
|
|
66
80
|
viewBox: "0 0 16 16"
|
|
67
|
-
}, [
|
|
81
|
+
}, [f("path", { d: "M5 13V3M2.5 5.5 5 3l2.5 2.5M11 3v10M8.5 10.5 11 13l2.5-2.5" })], -1), p(" " + S(h.buttonLabel), 1)]),
|
|
68
82
|
_: 1
|
|
69
83
|
}, 16, ["disabled", "variant"])]),
|
|
70
84
|
_: 1
|
|
71
|
-
})) : (
|
|
72
|
-
default:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
})) : (y(), l(C(j), _({ key: 2 }, C(V), { 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))]" }), {
|
|
86
|
+
default: E(() => [
|
|
87
|
+
m(o, { dir: z.value.dir }, null, 8, ["dir"]),
|
|
88
|
+
f("span", null, [f("span", P, S(U.value.label) + ",", 1), p(S(" ") + S(G.value), 1)]),
|
|
89
|
+
a[5] ||= f("svg", {
|
|
76
90
|
"aria-hidden": "true",
|
|
77
91
|
class: "size-3.5 shrink-0 fill-none stroke-current opacity-70",
|
|
78
92
|
"stroke-linecap": "round",
|
|
79
93
|
"stroke-width": "2.2",
|
|
80
94
|
viewBox: "0 0 24 24"
|
|
81
|
-
}, [
|
|
95
|
+
}, [f("path", { d: "M6 9l6 6 6-6" })], -1)
|
|
82
96
|
]),
|
|
83
97
|
_: 1
|
|
84
|
-
}, 16)),
|
|
85
|
-
default:
|
|
98
|
+
}, 16)), m(C(k), null, {
|
|
99
|
+
default: E(() => [m(C(O), {
|
|
86
100
|
align: "start",
|
|
101
|
+
"aria-label": i.$slots.trigger ? h.title : void 0,
|
|
87
102
|
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",
|
|
88
|
-
"
|
|
103
|
+
"data-sui-panel": C(H).panelKey,
|
|
104
|
+
"side-offset": 8,
|
|
105
|
+
onCloseAutoFocus: C(H).returnFocus,
|
|
106
|
+
onInteractOutside: C(H).ignoreTrigger
|
|
89
107
|
}, {
|
|
90
|
-
default:
|
|
91
|
-
"close-label":
|
|
92
|
-
"enter-label":
|
|
93
|
-
status:
|
|
94
|
-
onEnter:
|
|
108
|
+
default: E(() => [m(n, {
|
|
109
|
+
"close-label": h.closeLabel,
|
|
110
|
+
"enter-label": h.doneLabel,
|
|
111
|
+
status: h.status,
|
|
112
|
+
onEnter: a[2] ||= (e) => B.value = !1
|
|
95
113
|
}, {
|
|
96
|
-
default:
|
|
97
|
-
|
|
98
|
-
|
|
114
|
+
default: E(() => [
|
|
115
|
+
f("div", F, [
|
|
116
|
+
a[6] ||= f("svg", {
|
|
99
117
|
"aria-hidden": "true",
|
|
100
118
|
class: "size-4 fill-none stroke-current",
|
|
101
119
|
"stroke-linecap": "round",
|
|
102
120
|
"stroke-linejoin": "round",
|
|
103
121
|
"stroke-width": "1.5",
|
|
104
122
|
viewBox: "0 0 16 16"
|
|
105
|
-
}, [
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
}, [f("path", { d: "M5 13V3M2.5 5.5 5 3l2.5 2.5M11 3v10M8.5 10.5 11 13l2.5-2.5" })], -1),
|
|
124
|
+
f("span", I, S(h.title), 1),
|
|
125
|
+
U.value ? (y(), d("button", {
|
|
108
126
|
key: 0,
|
|
109
127
|
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",
|
|
110
128
|
type: "button",
|
|
111
|
-
onClick:
|
|
112
|
-
},
|
|
129
|
+
onClick: q
|
|
130
|
+
}, S(h.clearLabel), 1)) : u("", !0)
|
|
113
131
|
]),
|
|
114
|
-
|
|
115
|
-
"aria-label":
|
|
132
|
+
m(C(N), {
|
|
133
|
+
"aria-label": h.title,
|
|
116
134
|
class: "max-h-64 overflow-auto px-1.5 pt-1 pb-1.5",
|
|
117
|
-
"model-value":
|
|
118
|
-
"onUpdate:modelValue":
|
|
135
|
+
"model-value": z.value?.name,
|
|
136
|
+
"onUpdate:modelValue": a[0] ||= (e) => K(e)
|
|
119
137
|
}, {
|
|
120
|
-
default:
|
|
138
|
+
default: E(() => [(y(!0), d(s, null, b(h.options, (e) => (y(), l(C(M), {
|
|
121
139
|
key: e.name,
|
|
122
|
-
class:
|
|
140
|
+
class: v([R, e.name === z.value?.name ? "bg-sui-accent-wash font-semibold text-sui-accent" : "text-sui-ink hover:bg-sui-sunken"]),
|
|
123
141
|
value: e.name
|
|
124
142
|
}, {
|
|
125
|
-
default:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
e.name ===
|
|
143
|
+
default: E(() => [
|
|
144
|
+
f("span", { class: v(["flex size-6 shrink-0 items-center justify-center rounded-md", e.name === z.value?.name ? "bg-sui-surface text-sui-accent" : "bg-sui-sunken text-sui-ink-body"]) }, [m(r, { name: e.type }, null, 8, ["name"])], 2),
|
|
145
|
+
f("span", L, S(e.label), 1),
|
|
146
|
+
e.name === z.value?.name ? (y(), l(t, { key: 0 })) : u("", !0)
|
|
129
147
|
]),
|
|
130
148
|
_: 2
|
|
131
149
|
}, 1032, ["class", "value"]))), 128))]),
|
|
132
150
|
_: 1
|
|
133
151
|
}, 8, ["aria-label", "model-value"]),
|
|
134
|
-
|
|
152
|
+
U.value ? (y(), l(C(N), {
|
|
135
153
|
key: 0,
|
|
136
|
-
"aria-label":
|
|
154
|
+
"aria-label": h.directionLabel,
|
|
137
155
|
class: "mx-3 mb-3 grid grid-cols-2 gap-0.5 rounded-lg bg-sui-sunken p-0.75",
|
|
138
|
-
"model-value":
|
|
156
|
+
"model-value": z.value.dir,
|
|
139
157
|
orientation: "horizontal",
|
|
140
|
-
"onUpdate:modelValue":
|
|
141
|
-
name:
|
|
158
|
+
"onUpdate:modelValue": a[1] ||= (e) => z.value = {
|
|
159
|
+
name: z.value.name,
|
|
142
160
|
dir: e
|
|
143
161
|
}
|
|
144
162
|
}, {
|
|
145
|
-
default:
|
|
163
|
+
default: E(() => [(y(), d(s, null, b(["asc", "desc"], (e, t) => m(C(M), {
|
|
146
164
|
key: e,
|
|
147
|
-
class:
|
|
165
|
+
class: v(["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", z.value.dir === e ? "bg-sui-surface text-sui-ink shadow-(--sui-shadow-raised) ring-1 ring-sui-line-subtle" : "text-sui-ink-body hover:text-sui-ink"]),
|
|
148
166
|
value: e
|
|
149
167
|
}, {
|
|
150
|
-
default:
|
|
168
|
+
default: E(() => [m(o, { dir: e }, null, 8, ["dir"]), p(" " + S(W(U.value.type)[t]), 1)]),
|
|
151
169
|
_: 2
|
|
152
170
|
}, 1032, ["class", "value"])), 64))]),
|
|
153
171
|
_: 1
|
|
154
|
-
}, 8, ["aria-label", "model-value"])) :
|
|
172
|
+
}, 8, ["aria-label", "model-value"])) : u("", !0)
|
|
155
173
|
]),
|
|
156
174
|
_: 1
|
|
157
175
|
}, 8, [
|
|
@@ -160,14 +178,19 @@ var j = { class: "font-medium" }, M = { class: "flex h-11 items-center gap-1.5 p
|
|
|
160
178
|
"status"
|
|
161
179
|
])]),
|
|
162
180
|
_: 1
|
|
163
|
-
}
|
|
181
|
+
}, 8, [
|
|
182
|
+
"aria-label",
|
|
183
|
+
"data-sui-panel",
|
|
184
|
+
"onCloseAutoFocus",
|
|
185
|
+
"onInteractOutside"
|
|
186
|
+
])]),
|
|
164
187
|
_: 1
|
|
165
188
|
})]),
|
|
166
|
-
_:
|
|
167
|
-
}, 8, ["open"])) :
|
|
189
|
+
_: 3
|
|
190
|
+
}, 8, ["open"])) : u("", !0);
|
|
168
191
|
}
|
|
169
192
|
});
|
|
170
193
|
//#endregion
|
|
171
|
-
export {
|
|
194
|
+
export { z as default };
|
|
172
195
|
|
|
173
196
|
//# sourceMappingURL=SortMenu.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SortMenu.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","Button","_mergeProps","_createElementVNode","_createTextVNode","_toDisplayString","SortArrow","FilterFrame","_createElementBlock","_createCommentVNode","_Fragment","_renderList","_normalizeClass","FilterGlyph","CheckIcon","Button_default","CheckIcon_default","FilterFrame_default","FilterGlyph_default","SortArrow_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","row","SortMenu_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","\"open\"","\"openModifiers\"","props","__props","sort","useModel","open","attrs","useAttrs","current","computed","o","words","type","sortDirections","dirLabel","pickField","field","name","clear","openBlock","createBlock","unref","PopoverRoot","_cache","$event","withCtx","PopoverTrigger","createVNode","mergeProps","createElementVNode","createTextVNode","toDisplayString","PopoverPortal","PopoverContent","createElementBlock","createCommentVNode","RadioGroupRoot","Fragment","renderList","RadioGroupItem","option","normalizeClass","dir","i"],"sources":["../../../src/components/Filters/SortMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport { PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger, RadioGroupItem, RadioGroupRoot } 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 { 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 /** 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 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\nconst attrs = useAttrs()\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=\"as === 'button' || current\" v-model:open=\"open\">\n <PopoverTrigger v-if=\"as === 'button'\" as-child>\n <Button v-bind=\"attrs\" :disabled=\"disabled\" :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 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 <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":"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"}
|
|
1
|
+
{"version":3,"file":"SortMenu.vue_vue_type_script_setup_true_lang.js","names":["$slots","_useModel","_openBlock","_createBlock","_unref","_withCtx","_renderSlot","_createVNode","Button","_mergeProps","_createElementVNode","_createTextVNode","_toDisplayString","SortArrow","FilterFrame","_createElementBlock","_createCommentVNode","_Fragment","_renderList","_normalizeClass","FilterGlyph","CheckIcon","Button_default","CheckIcon_default","FilterFrame_default","FilterGlyph_default","SortArrow_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","row","SortMenu_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","\"open\"","\"openModifiers\"","props","__props","sort","useModel","open","attrs","useAttrs","custom","useCustomTrigger","current","computed","o","words","type","sortDirections","dirLabel","pickField","field","name","clear","_ctx","openBlock","createBlock","unref","PopoverRoot","_cache","$event","withCtx","PopoverAnchor","renderSlot","PopoverTrigger","createVNode","mergeProps","createElementVNode","createTextVNode","toDisplayString","PopoverPortal","PopoverContent","createElementBlock","createCommentVNode","RadioGroupRoot","Fragment","renderList","RadioGroupItem","option","normalizeClass","dir","i"],"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":"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"}
|
|
@@ -4,5 +4,6 @@ export { default as FilterMenu } from './FilterMenu.vue';
|
|
|
4
4
|
export type { FilterMenuProps } from './FilterMenu.vue';
|
|
5
5
|
export { default as SortMenu } from './SortMenu.vue';
|
|
6
6
|
export type { SortMenuProps } from './SortMenu.vue';
|
|
7
|
+
export type { FilterTriggerProps } from './trigger';
|
|
7
8
|
export { datePresets, describeFilter, filterOperators, sortDirections } from './defaults';
|
|
8
9
|
export type { FilterField, FilterFieldType, FilterOperator, FilterOption, FilterSummary, FilterValue, ViewSort } from './types';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ComponentPublicInstance, type Ref } from 'vue';
|
|
2
|
+
/** What a `#trigger` slot's opener spreads with `v-bind="props"`. */
|
|
3
|
+
export interface FilterTriggerProps {
|
|
4
|
+
'aria-haspopup': 'dialog';
|
|
5
|
+
'aria-expanded': boolean;
|
|
6
|
+
'aria-controls': string | undefined;
|
|
7
|
+
'data-state': 'open' | 'closed';
|
|
8
|
+
onClick: () => void;
|
|
9
|
+
ref: (node: Element | ComponentPublicInstance | null) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function useCustomTrigger(open: Ref<boolean>): {
|
|
12
|
+
props: import("vue").ComputedRef<FilterTriggerProps>;
|
|
13
|
+
toggle: () => boolean;
|
|
14
|
+
ignoreTrigger: (event: Event) => void;
|
|
15
|
+
returnFocus: (event: Event) => void;
|
|
16
|
+
panelKey: string;
|
|
17
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { computed as e, nextTick as t, ref as n, shallowRef as r, useId as i, watch as a } from "vue";
|
|
2
|
+
//#region src/components/Filters/trigger.ts
|
|
3
|
+
function o(o) {
|
|
4
|
+
let s = r(null), c = i(), l = n();
|
|
5
|
+
a(o, async (e) => {
|
|
6
|
+
await t(), l.value = e ? document.querySelector(`[data-sui-panel="${c}"]`)?.id ?? void 0 : void 0;
|
|
7
|
+
});
|
|
8
|
+
let u = (e) => e instanceof Element ? e : e?.$el ?? null, d = () => o.value = !o.value, f = e(() => ({
|
|
9
|
+
"aria-haspopup": "dialog",
|
|
10
|
+
"aria-expanded": o.value,
|
|
11
|
+
"aria-controls": l.value,
|
|
12
|
+
"data-state": o.value ? "open" : "closed",
|
|
13
|
+
onClick: d,
|
|
14
|
+
ref: (e) => s.value = u(e)
|
|
15
|
+
}));
|
|
16
|
+
function p(e) {
|
|
17
|
+
s.value?.contains(e.target) && e.preventDefault();
|
|
18
|
+
}
|
|
19
|
+
function m(e) {
|
|
20
|
+
s.value && (e.preventDefault(), s.value.focus());
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
props: f,
|
|
24
|
+
toggle: d,
|
|
25
|
+
ignoreTrigger: p,
|
|
26
|
+
returnFocus: m,
|
|
27
|
+
panelKey: c
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { o as useCustomTrigger };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=trigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger.js","names":["useCustomTrigger","element","shallowRef","panelKey","useId","panelId","ref","open","nextTick","isOpen","elementOf","node","toggle","props","computed","ignoreTrigger","event","returnFocus"],"sources":["../../../src/components/Filters/trigger.ts"],"sourcesContent":["import { type ComponentPublicInstance, type Ref, computed, nextTick, ref, shallowRef, useId, watch } from 'vue'\n\n/** What a `#trigger` slot's opener spreads with `v-bind=\"props\"`. */\nexport interface FilterTriggerProps {\n 'aria-haspopup': 'dialog'\n 'aria-expanded': boolean\n 'aria-controls': string | undefined\n 'data-state': 'open' | 'closed'\n onClick: () => void\n ref: (node: Element | ComponentPublicInstance | null) => void\n}\n\n// An opener drawn by the app sits outside Reka's PopoverTrigger, so the panel needs telling that clicks on it aren't\n// outside clicks, and where focus goes back to when it closes.\nexport function useCustomTrigger(open: Ref<boolean>) {\n const element = shallowRef<HTMLElement | null>(null)\n // Reka names the panel itself; the opener reads that id once the panel is open.\n const panelKey = useId()\n const panelId = ref<string>()\n watch(open, async (isOpen) => {\n await nextTick()\n panelId.value = isOpen ? (document.querySelector(`[data-sui-panel=\"${panelKey}\"]`)?.id ?? undefined) : undefined\n })\n const elementOf = (node: Element | ComponentPublicInstance | null) =>\n node instanceof Element ? (node as HTMLElement) : ((node?.$el as HTMLElement | undefined) ?? null)\n const toggle = () => (open.value = !open.value)\n\n const props = computed<FilterTriggerProps>(() => ({\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open.value,\n 'aria-controls': panelId.value,\n 'data-state': open.value ? 'open' : 'closed',\n onClick: toggle,\n ref: (node) => (element.value = elementOf(node))\n }))\n\n function ignoreTrigger(event: Event) {\n if (element.value?.contains(event.target as Node)) event.preventDefault()\n }\n\n function returnFocus(event: Event) {\n if (!element.value) return\n event.preventDefault()\n element.value.focus()\n }\n\n return { props, toggle, ignoreTrigger, returnFocus, panelKey }\n}\n"],"mappings":";;AAcA,SAAgBA,EAAiB,GAAoB;CACnD,IAAMC,IAAUC,EAA+B,IAAI,GAE7CC,IAAWC,EAAM,GACjBC,IAAUC,EAAY;CAC5B,EAAMC,GAAM,OAAO,MAAW;EAE5B,AADA,MAAMC,EAAS,GACf,EAAQ,QAAQC,IAAU,SAAS,cAAc,oBAAoBN,EAAS,GAAG,CAAC,EAAE,MAAM,KAAA,IAAa,KAAA;CACzG,CAAC;CACD,IAAMO,KAAa,MACjBC,aAAgB,UAAWA,IAAyBA,GAAM,OAAmC,MACzFC,UAAgB,EAAK,QAAQ,CAACL,EAAK,OAEnCM,IAAQC,SAAoC;EAChD,iBAAiB;EACjB,iBAAiBP,EAAK;EACtB,iBAAiBF,EAAQ;EACzB,cAAcE,EAAK,QAAQ,SAAS;EACpC,SAASK;EACT,MAAM,MAAU,EAAQ,QAAQF,EAAUC,CAAI;CAChD,EAAE;CAEF,SAASI,EAAc,GAAc;EACnC,AAAId,EAAQ,OAAO,SAASe,EAAM,MAAc,KAAGA,EAAM,eAAe;CAC1E;CAEA,SAASC,EAAY,GAAc;EACjC,AAAKhB,EAAQ,UACbe,EAAM,eAAe,GACrBf,EAAQ,MAAM,MAAM;CACtB;CAEA,OAAO;EAAE;EAAO;EAAQ;EAAe;EAAa;CAAS;AAC/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormField.js","names":["_sfc_main","FormField_vue_vue_type_script_setup_true_lang_default","FormField_default"],"sources":["../../../src/components/FormField/FormField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, provide, ref, useId } from 'vue'\n\nimport { fieldKey } from './context'\n\nexport interface FormFieldProps {\n label?: string\n hint?: string\n /** Replaces the hint and marks the control invalid. Say what to fix. */\n error?: string | null\n required?: boolean\n /** A muted \"Optional\" after the label, for forms where most fields are required. */\n optional?: boolean\n /** Shows a count; over the limit it and the control turn danger. */\n maxLength?: number\n /** Label above the control, or `inline` in an 88px column like PropertyRow. */\n layout?: 'stacked' | 'inline'\n /** The control's id, which the label points to. Set it here, not on the control. */\n id?: string\n optionalLabel?: string\n requiredLabel?: string\n /** The counter's name for assistive tech; `{count}` and `{max}` are replaced. */\n counterLabel?: string\n}\n\nconst props = withDefaults(defineProps<FormFieldProps>(), {\n label: undefined,\n hint: undefined,\n error: undefined,\n maxLength: undefined,\n layout: 'stacked',\n id: undefined,\n optionalLabel: 'Optional',\n requiredLabel: 'required',\n counterLabel: '{count} of {max} characters'\n})\n\nconst autoId = useId()\nconst controlId = computed(() => props.id ?? autoId)\nconst messageId = computed(() => `${controlId.value}-message`)\nconst countId = computed(() => `${controlId.value}-count`)\n\nconst text = ref<string>()\nconst count = computed(() => text.value?.length ?? 0)\nconst over = computed(() => props.maxLength !== undefined && count.value > props.maxLength)\nconst message = computed(() => props.error || props.hint)\nconst invalid = computed(() => !!props.error || over.value)\nconst describedBy = computed(\n () =>\n [message.value && messageId.value,
|
|
1
|
+
{"version":3,"file":"FormField.js","names":["_sfc_main","FormField_vue_vue_type_script_setup_true_lang_default","FormField_default"],"sources":["../../../src/components/FormField/FormField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, provide, ref, useId } from 'vue'\n\nimport { fieldKey } from './context'\n\nexport interface FormFieldProps {\n label?: string\n hint?: string\n /** Replaces the hint and marks the control invalid. Say what to fix. */\n error?: string | null\n required?: boolean\n /** A muted \"Optional\" after the label, for forms where most fields are required. */\n optional?: boolean\n /** Shows a count; over the limit it and the control turn danger. */\n maxLength?: number\n /** A recommended length (a title's 60, a description's 160): past it the count turns warning, but the control stays\n * valid and the value saves. A `maxLength` set too stays the hard limit, and takes the counter once passed. */\n softLimit?: number\n /** Label above the control, or `inline` in an 88px column like PropertyRow. */\n layout?: 'stacked' | 'inline'\n /** The control's id, which the label points to. Set it here, not on the control. */\n id?: string\n optionalLabel?: string\n requiredLabel?: string\n /** The counter's name for assistive tech; `{count}` and `{max}` are replaced. */\n counterLabel?: string\n /** The same, while counting against `softLimit`. */\n softCounterLabel?: string\n /** Added to the counter's name past `softLimit`. */\n overSoftLabel?: string\n}\n\nconst props = withDefaults(defineProps<FormFieldProps>(), {\n label: undefined,\n hint: undefined,\n error: undefined,\n maxLength: undefined,\n softLimit: undefined,\n layout: 'stacked',\n id: undefined,\n optionalLabel: 'Optional',\n requiredLabel: 'required',\n counterLabel: '{count} of {max} characters',\n softCounterLabel: '{count} of {max} recommended characters',\n overSoftLabel: 'Longer than recommended'\n})\n\nconst autoId = useId()\nconst controlId = computed(() => props.id ?? autoId)\nconst messageId = computed(() => `${controlId.value}-message`)\nconst countId = computed(() => `${controlId.value}-count`)\n\nconst text = ref<string>()\nconst count = computed(() => text.value?.length ?? 0)\nconst over = computed(() => props.maxLength !== undefined && count.value > props.maxLength)\n// The soft limit counts until the hard one is passed.\nconst soft = computed(() => props.softLimit !== undefined && !over.value)\nconst limit = computed(() => (soft.value ? props.softLimit : props.maxLength))\nconst pastSoft = computed(() => soft.value && count.value > props.softLimit!)\nconst counterName = computed(\n () =>\n (soft.value ? props.softCounterLabel : props.counterLabel)\n .replace('{count}', String(count.value))\n .replace('{max}', String(limit.value)) + (pastSoft.value ? `. ${props.overSoftLabel}` : '')\n)\nconst message = computed(() => props.error || props.hint)\nconst invalid = computed(() => !!props.error || over.value)\nconst describedBy = computed(\n () =>\n [message.value && messageId.value, limit.value !== undefined && countId.value].filter(Boolean).join(' ') ||\n undefined\n)\n\nprovide(fieldKey, {\n get id() {\n return controlId.value\n },\n describedBy,\n required: computed(() => props.required),\n invalid,\n text\n})\n</script>\n\n<!-- Label, hint, error and counter around one control. Input, Textarea and Select inside it are wired up on their\n own; another control takes the slot's `id`, `describedBy` and `invalid`. -->\n<template>\n <div\n :class=\"\n layout === 'inline' ? 'grid grid-cols-[88px_minmax(0,1fr)] items-start gap-3' : 'flex min-w-0 flex-col gap-1.5'\n \"\n >\n <label\n v-if=\"label\"\n class=\"flex items-baseline gap-1 text-13 leading-5\"\n :class=\"layout === 'inline' ? 'pt-2 text-sui-ink-muted' : 'font-medium text-sui-ink-emphasis'\"\n :for=\"controlId\"\n >\n {{ label }}\n <template v-if=\"required\">\n <span aria-hidden=\"true\" class=\"text-sui-danger\">*</span>\n <span class=\"sr-only\"> ({{ requiredLabel }})</span>\n </template>\n <span v-else-if=\"optional\" class=\"ml-1 text-xs font-normal text-sui-ink-muted\">{{ optionalLabel }}</span>\n </label>\n <div class=\"flex min-w-0 flex-col gap-1.5\">\n <slot :id=\"controlId\" :described-by=\"describedBy\" :invalid=\"invalid\" />\n <div v-if=\"message || limit !== undefined\" class=\"flex items-start justify-between gap-3\">\n <p\n v-if=\"message\"\n :id=\"messageId\"\n class=\"m-0 flex items-start gap-1.25 text-xs leading-4\"\n :class=\"error ? 'text-sui-danger' : 'text-sui-ink-muted'\"\n :role=\"error ? 'alert' : undefined\"\n >\n <svg\n v-if=\"error\"\n aria-hidden=\"true\"\n class=\"mt-px size-3.5 shrink-0 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <circle cx=\"8\" cy=\"8\" r=\"6.25\" />\n <path d=\"M8 4.75v3.5M8 11h.01\" />\n </svg>\n {{ message }}\n </p>\n <span\n v-if=\"limit !== undefined\"\n :id=\"countId\"\n :aria-label=\"counterName\"\n aria-live=\"polite\"\n class=\"ml-auto text-xs leading-4 tabular-nums\"\n :class=\"\n over\n ? 'font-medium text-sui-danger'\n : pastSoft\n ? 'inline-flex items-center gap-1 font-medium text-sui-warning'\n : 'text-sui-ink-muted'\n \"\n >\n <svg\n v-if=\"pastSoft\"\n aria-hidden=\"true\"\n class=\"size-3 shrink-0 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=\"M7.13 2.6a1 1 0 0 1 1.74 0l5.4 9.4a1 1 0 0 1-.87 1.5H2.6a1 1 0 0 1-.87-1.5Z\" />\n <path d=\"M8 6.5v2.5M8 11.25h.01\" />\n </svg>\n {{ count }}/{{ limit }}\n </span>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -8,6 +8,9 @@ export interface FormFieldProps {
|
|
|
8
8
|
optional?: boolean;
|
|
9
9
|
/** Shows a count; over the limit it and the control turn danger. */
|
|
10
10
|
maxLength?: number;
|
|
11
|
+
/** A recommended length (a title's 60, a description's 160): past it the count turns warning, but the control stays
|
|
12
|
+
* valid and the value saves. A `maxLength` set too stays the hard limit, and takes the counter once passed. */
|
|
13
|
+
softLimit?: number;
|
|
11
14
|
/** Label above the control, or `inline` in an 88px column like PropertyRow. */
|
|
12
15
|
layout?: 'stacked' | 'inline';
|
|
13
16
|
/** The control's id, which the label points to. Set it here, not on the control. */
|
|
@@ -16,6 +19,10 @@ export interface FormFieldProps {
|
|
|
16
19
|
requiredLabel?: string;
|
|
17
20
|
/** The counter's name for assistive tech; `{count}` and `{max}` are replaced. */
|
|
18
21
|
counterLabel?: string;
|
|
22
|
+
/** The same, while counting against `softLimit`. */
|
|
23
|
+
softCounterLabel?: string;
|
|
24
|
+
/** Added to the counter's name past `softLimit`. */
|
|
25
|
+
overSoftLabel?: string;
|
|
19
26
|
}
|
|
20
27
|
declare var __VLS_1: {
|
|
21
28
|
id: string;
|
|
@@ -31,10 +38,13 @@ declare const __VLS_base: import("vue").DefineComponent<FormFieldProps, {}, {},
|
|
|
31
38
|
id: string;
|
|
32
39
|
hint: string;
|
|
33
40
|
maxLength: number;
|
|
41
|
+
softLimit: number;
|
|
34
42
|
layout: "stacked" | "inline";
|
|
35
43
|
optionalLabel: string;
|
|
36
44
|
requiredLabel: string;
|
|
37
45
|
counterLabel: string;
|
|
46
|
+
softCounterLabel: string;
|
|
47
|
+
overSoftLabel: string;
|
|
38
48
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
39
49
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
40
50
|
declare const _default: typeof __VLS_export;
|
|
@@ -14,7 +14,15 @@ var h = ["for"], g = { class: "sr-only" }, _ = {
|
|
|
14
14
|
"stroke-linecap": "round",
|
|
15
15
|
"stroke-width": "1.5",
|
|
16
16
|
viewBox: "0 0 16 16"
|
|
17
|
-
}, S = ["id", "aria-label"], C =
|
|
17
|
+
}, S = ["id", "aria-label"], C = {
|
|
18
|
+
key: 0,
|
|
19
|
+
"aria-hidden": "true",
|
|
20
|
+
class: "size-3 shrink-0 fill-none stroke-current",
|
|
21
|
+
"stroke-linecap": "round",
|
|
22
|
+
"stroke-linejoin": "round",
|
|
23
|
+
"stroke-width": "1.5",
|
|
24
|
+
viewBox: "0 0 16 16"
|
|
25
|
+
}, w = /*@__PURE__*/ s({
|
|
18
26
|
__name: "FormField",
|
|
19
27
|
props: {
|
|
20
28
|
label: { default: void 0 },
|
|
@@ -23,52 +31,55 @@ var h = ["for"], g = { class: "sr-only" }, _ = {
|
|
|
23
31
|
required: { type: Boolean },
|
|
24
32
|
optional: { type: Boolean },
|
|
25
33
|
maxLength: { default: void 0 },
|
|
34
|
+
softLimit: { default: void 0 },
|
|
26
35
|
layout: { default: "stacked" },
|
|
27
36
|
id: { default: void 0 },
|
|
28
37
|
optionalLabel: { default: "Optional" },
|
|
29
38
|
requiredLabel: { default: "required" },
|
|
30
|
-
counterLabel: { default: "{count} of {max} characters" }
|
|
39
|
+
counterLabel: { default: "{count} of {max} characters" },
|
|
40
|
+
softCounterLabel: { default: "{count} of {max} recommended characters" },
|
|
41
|
+
overSoftLabel: { default: "Longer than recommended" }
|
|
31
42
|
},
|
|
32
43
|
setup(s) {
|
|
33
|
-
let
|
|
44
|
+
let w = s, T = m(), E = n(() => w.id ?? T), D = n(() => `${E.value}-message`), O = n(() => `${E.value}-count`), k = d(), A = n(() => k.value?.length ?? 0), j = n(() => w.maxLength !== void 0 && A.value > w.maxLength), M = n(() => w.softLimit !== void 0 && !j.value), N = n(() => M.value ? w.softLimit : w.maxLength), P = n(() => M.value && A.value > w.softLimit), F = n(() => (M.value ? w.softCounterLabel : w.counterLabel).replace("{count}", String(A.value)).replace("{max}", String(N.value)) + (P.value ? `. ${w.overSoftLabel}` : "")), I = n(() => w.error || w.hint), L = n(() => !!w.error || j.value), R = n(() => [I.value && D.value, N.value !== void 0 && O.value].filter(Boolean).join(" ") || void 0);
|
|
34
45
|
return u(e, {
|
|
35
46
|
get id() {
|
|
36
|
-
return
|
|
47
|
+
return E.value;
|
|
37
48
|
},
|
|
38
|
-
describedBy:
|
|
39
|
-
required: n(() =>
|
|
40
|
-
invalid:
|
|
41
|
-
text:
|
|
49
|
+
describedBy: R,
|
|
50
|
+
required: n(() => w.required),
|
|
51
|
+
invalid: L,
|
|
52
|
+
text: k
|
|
42
53
|
}), (e, n) => (l(), i("div", { class: c(s.layout === "inline" ? "grid grid-cols-[88px_minmax(0,1fr)] items-start gap-3" : "flex min-w-0 flex-col gap-1.5") }, [s.label ? (l(), i("label", {
|
|
43
54
|
key: 0,
|
|
44
55
|
class: c(["flex items-baseline gap-1 text-13 leading-5", s.layout === "inline" ? "pt-2 text-sui-ink-muted" : "font-medium text-sui-ink-emphasis"]),
|
|
45
|
-
for:
|
|
56
|
+
for: E.value
|
|
46
57
|
}, [o(p(s.label) + " ", 1), s.required ? (l(), i(t, { key: 0 }, [n[0] ||= a("span", {
|
|
47
58
|
"aria-hidden": "true",
|
|
48
59
|
class: "text-sui-danger"
|
|
49
60
|
}, "*", -1), a("span", g, " (" + p(s.requiredLabel) + ")", 1)], 64)) : s.optional ? (l(), i("span", _, p(s.optionalLabel), 1)) : r("", !0)], 10, h)) : r("", !0), a("div", v, [f(e.$slots, "default", {
|
|
50
|
-
id: T.value,
|
|
51
|
-
describedBy: N.value,
|
|
52
|
-
invalid: M.value
|
|
53
|
-
}), j.value || s.maxLength !== void 0 ? (l(), i("div", y, [j.value ? (l(), i("p", {
|
|
54
|
-
key: 0,
|
|
55
61
|
id: E.value,
|
|
62
|
+
describedBy: R.value,
|
|
63
|
+
invalid: L.value
|
|
64
|
+
}), I.value || N.value !== void 0 ? (l(), i("div", y, [I.value ? (l(), i("p", {
|
|
65
|
+
key: 0,
|
|
66
|
+
id: D.value,
|
|
56
67
|
class: c(["m-0 flex items-start gap-1.25 text-xs leading-4", s.error ? "text-sui-danger" : "text-sui-ink-muted"]),
|
|
57
68
|
role: s.error ? "alert" : void 0
|
|
58
69
|
}, [s.error ? (l(), i("svg", x, [...n[1] ||= [a("circle", {
|
|
59
70
|
cx: "8",
|
|
60
71
|
cy: "8",
|
|
61
72
|
r: "6.25"
|
|
62
|
-
}, null, -1), a("path", { d: "M8 4.75v3.5M8 11h.01" }, null, -1)]])) : r("", !0), o(" " + p(
|
|
73
|
+
}, null, -1), a("path", { d: "M8 4.75v3.5M8 11h.01" }, null, -1)]])) : r("", !0), o(" " + p(I.value), 1)], 10, b)) : r("", !0), N.value === void 0 ? r("", !0) : (l(), i("span", {
|
|
63
74
|
key: 1,
|
|
64
|
-
id:
|
|
65
|
-
"aria-label":
|
|
75
|
+
id: O.value,
|
|
76
|
+
"aria-label": F.value,
|
|
66
77
|
"aria-live": "polite",
|
|
67
|
-
class: c(["ml-auto text-xs leading-4 tabular-nums",
|
|
68
|
-
}, p(
|
|
78
|
+
class: c(["ml-auto text-xs leading-4 tabular-nums", j.value ? "font-medium text-sui-danger" : P.value ? "inline-flex items-center gap-1 font-medium text-sui-warning" : "text-sui-ink-muted"])
|
|
79
|
+
}, [P.value ? (l(), i("svg", C, [...n[2] ||= [a("path", { d: "M7.13 2.6a1 1 0 0 1 1.74 0l5.4 9.4a1 1 0 0 1-.87 1.5H2.6a1 1 0 0 1-.87-1.5Z" }, null, -1), a("path", { d: "M8 6.5v2.5M8 11.25h.01" }, null, -1)]])) : r("", !0), o(" " + p(A.value) + "/" + p(N.value), 1)], 10, S))])) : r("", !0)])], 2));
|
|
69
80
|
}
|
|
70
81
|
});
|
|
71
82
|
//#endregion
|
|
72
|
-
export {
|
|
83
|
+
export { w as default };
|
|
73
84
|
|
|
74
85
|
//# sourceMappingURL=FormField.vue_vue_type_script_setup_true_lang.js.map
|