@sparklingopinions/sparkling-ui 0.7.0 → 0.8.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.
Files changed (54) hide show
  1. package/README.md +2 -2
  2. package/dist/aliases.d.ts +23 -2
  3. package/dist/components/Button/Button.js.map +1 -1
  4. package/dist/components/Button/Button.vue.d.ts +4 -0
  5. package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js +21 -11
  6. package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
  8. package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js +29 -20
  9. package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/DataList/DataList.js.map +1 -1
  11. package/dist/components/DataList/DataList.vue.d.ts +30 -3
  12. package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +188 -100
  13. package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/components/DataList/types.d.ts +2 -0
  15. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  16. package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +32 -23
  17. package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  18. package/dist/components/Icon/iconSet.js +1 -0
  19. package/dist/components/Icon/iconSet.js.map +1 -1
  20. package/dist/components/Popover/PopoverDialog.js +7 -0
  21. package/dist/components/Popover/PopoverDialog.js.map +1 -0
  22. package/dist/components/Popover/PopoverDialog.vue.d.ts +56 -0
  23. package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js +158 -0
  24. package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  25. package/dist/components/Popover/index.d.ts +2 -0
  26. package/dist/components/Table/Table.js.map +1 -1
  27. package/dist/components/Table/Table.vue.d.ts +2 -0
  28. package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +5 -1
  29. package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/Tag/Tag.js.map +1 -1
  31. package/dist/components/Tag/Tag.vue.d.ts +3 -0
  32. package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +3 -2
  33. package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/Toast/Toaster.js.map +1 -1
  35. package/dist/components/Toast/Toaster.vue.d.ts +4 -0
  36. package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js +49 -32
  37. package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/components/Toolbar/Toolbar.js +7 -0
  39. package/dist/components/Toolbar/Toolbar.js.map +1 -0
  40. package/dist/components/Toolbar/Toolbar.vue.d.ts +23 -0
  41. package/dist/components/Toolbar/Toolbar.vue_vue_type_script_setup_true_lang.js +52 -0
  42. package/dist/components/Toolbar/Toolbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  43. package/dist/components/Toolbar/index.d.ts +2 -0
  44. package/dist/components/internal/MenuItemContent.js.map +1 -1
  45. package/dist/components/internal/MenuItemContent.vue.d.ts +1 -0
  46. package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js +30 -14
  47. package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/internal/menu.d.ts +5 -1
  49. package/dist/components/internal/menu.js +17 -14
  50. package/dist/components/internal/menu.js.map +1 -1
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.js +18 -16
  53. package/package.json +1 -1
  54. package/src/styles/tailwind.css +22 -0
@@ -1,43 +1,52 @@
1
1
  import { removeToast as e, toastActions as t, toasts as n } from "../../composables/toast.js";
2
2
  import r from "./ToastMessage.js";
3
- import { Fragment as i, TransitionGroup as a, createBlock as o, createElementBlock as s, createVNode as c, defineComponent as l, openBlock as u, reactive as d, renderList as f, unref as p, withCtx as m } from "vue";
4
- import { ToastProvider as h, ToastRoot as g, ToastViewport as _ } from "reka-ui";
3
+ import { Fragment as i, TransitionGroup as a, computed as o, createBlock as s, createElementBlock as c, createVNode as l, defineComponent as u, normalizeClass as d, normalizeStyle as f, openBlock as p, reactive as m, renderList as h, unref as g, withCtx as _ } from "vue";
4
+ import { ToastProvider as v, ToastRoot as y, ToastViewport as b } from "reka-ui";
5
5
  //#region src/components/Toast/Toaster.vue?vue&type=script&setup=true&lang.ts
6
- var v = /*@__PURE__*/ l({
6
+ var x = /*@__PURE__*/ u({
7
7
  __name: "Toaster",
8
8
  props: {
9
+ position: { default: "bottom-center" },
9
10
  label: { default: "Notifications ({hotkey})" },
10
11
  closeLabel: { default: "Close" },
11
12
  preview: { default: void 0 }
12
13
  },
13
14
  emits: ["close"],
14
- setup(l, { emit: v }) {
15
- let y = v, b = d(/* @__PURE__ */ new Set());
16
- function x(t, n) {
15
+ setup(u, { emit: x }) {
16
+ let S = u, C = x, w = m(/* @__PURE__ */ new Set()), T = (e) => `calc(var(--sui-toaster-margin) + var(--sui-toaster-inset-${e}))`, E = o(() => {
17
+ let [e, t] = S.position.split("-");
18
+ return {
19
+ [e]: `calc(var(--sui-toaster-margin) + var(--sui-toaster-inset-${e}) + env(safe-area-inset-${e}))`,
20
+ left: t === "right" ? "auto" : T("left"),
21
+ right: t === "left" ? "auto" : T("right"),
22
+ width: `min(var(--sui-toaster-width), 100vw - ${T("left")} - ${T("right")})`
23
+ };
24
+ }), D = o(() => S.position.startsWith("top"));
25
+ function O(t, n) {
17
26
  n.onClick(), e(t, "action");
18
27
  }
19
- function S(e, t) {
20
- t.onClick(), y("close", e, "action");
28
+ function k(e, t) {
29
+ t.onClick(), C("close", e, "action");
21
30
  }
22
- return (d, v) => l.preview ? (u(), o(a, {
31
+ return (o, m) => u.preview ? (p(), s(a, {
23
32
  key: 0,
24
33
  class: "flex w-full max-w-96 flex-col",
25
34
  "enter-active-class": "animate-sui-toast-in",
26
35
  "leave-active-class": "animate-sui-toast-out overflow-hidden",
27
36
  tag: "div"
28
37
  }, {
29
- default: m(() => [(u(!0), s(i, null, f(l.preview, (e, n) => (u(), o(r, {
38
+ default: _(() => [(p(!0), c(i, null, h(u.preview, (e, n) => (p(), s(r, {
30
39
  key: e.id ?? n,
31
- actions: p(t)(e),
40
+ actions: g(t)(e),
32
41
  closable: e.closable,
33
- "close-label": l.closeLabel,
42
+ "close-label": u.closeLabel,
34
43
  detail: e.detail,
35
44
  life: e.life,
36
45
  severity: e.severity,
37
46
  summary: e.summary,
38
- onAction: (t) => S(e.id ?? n, t),
39
- onClose: (t) => y("close", e.id ?? n, "close"),
40
- onExpire: (t) => y("close", e.id ?? n, "timeout")
47
+ onAction: (t) => k(e.id ?? n, t),
48
+ onClose: (t) => C("close", e.id ?? n, "close"),
49
+ onExpire: (t) => C("close", e.id ?? n, "timeout")
41
50
  }, null, 8, [
42
51
  "actions",
43
52
  "closable",
@@ -51,35 +60,36 @@ var v = /*@__PURE__*/ l({
51
60
  "onExpire"
52
61
  ]))), 128))]),
53
62
  _: 1
54
- })) : (u(), o(p(h), {
63
+ })) : (p(), s(g(v), {
55
64
  key: 1,
56
65
  "swipe-threshold": Infinity
57
66
  }, {
58
- default: m(() => [(u(!0), s(i, null, f(p(n), (t) => (u(), o(p(g), {
67
+ default: _(() => [(p(!0), c(i, null, h(g(n), (t) => (p(), s(g(y), {
59
68
  key: t.id,
60
69
  "as-child": "",
61
70
  duration: t.life || Infinity,
62
71
  open: t.open,
63
72
  type: t.severity === "error" ? "foreground" : "background",
64
- onEscapeKeyDown: (n) => p(e)(t.id, "close"),
65
- onPause: (e) => b.add(t.id),
66
- onResume: (e) => b.delete(t.id),
67
- "onUpdate:open": (n) => !n && p(e)(t.id, "timeout")
73
+ onEscapeKeyDown: (n) => g(e)(t.id, "close"),
74
+ onPause: (e) => w.add(t.id),
75
+ onResume: (e) => w.delete(t.id),
76
+ "onUpdate:open": (n) => !n && g(e)(t.id, "timeout")
68
77
  }, {
69
- default: m(() => [c(r, {
78
+ default: _(() => [l(r, {
70
79
  actions: t.actions,
71
- class: "pointer-events-auto data-[state=closed]:animate-sui-toast-out data-[state=closed]:overflow-hidden data-[state=open]:animate-sui-toast-in",
80
+ class: d(["pointer-events-auto data-[state=closed]:overflow-hidden data-[state=closed]:animate-sui-toast-out motion-reduce:data-[state=closed]:animate-sui-toast-fade", D.value ? "data-[state=open]:animate-sui-toast-in-top motion-reduce:data-[state=open]:animate-sui-fade-in" : "data-[state=open]:animate-sui-toast-in motion-reduce:data-[state=open]:animate-sui-fade-in"]),
72
81
  closable: t.closable,
73
- "close-label": l.closeLabel,
82
+ "close-label": u.closeLabel,
74
83
  detail: t.detail,
75
84
  life: t.life,
76
- paused: b.has(t.id),
85
+ paused: w.has(t.id),
77
86
  severity: t.severity,
78
87
  summary: t.summary,
79
- onAction: (e) => x(t.id, e),
80
- onClose: (n) => p(e)(t.id, "close")
88
+ onAction: (e) => O(t.id, e),
89
+ onClose: (n) => g(e)(t.id, "close")
81
90
  }, null, 8, [
82
91
  "actions",
92
+ "class",
83
93
  "closable",
84
94
  "close-label",
85
95
  "detail",
@@ -99,17 +109,24 @@ var v = /*@__PURE__*/ l({
99
109
  "onPause",
100
110
  "onResume",
101
111
  "onUpdate:open"
102
- ]))), 128)), c(p(_), {
112
+ ]))), 128)), l(g(b), {
103
113
  as: "div",
104
- class: "pointer-events-none fixed bottom-5 left-1/2 z-[1200] flex w-96 max-w-[calc(100vw-2.5rem)] -translate-x-1/2 flex-col rounded-md outline-hidden",
114
+ class: d(["pointer-events-none fixed z-[1200] mx-auto flex rounded-md outline-hidden", D.value ? "flex-col-reverse" : "flex-col"]),
115
+ "data-sui-position": u.position,
105
116
  "data-sui-toasts": "",
106
- label: l.label
107
- }, null, 8, ["label"])]),
117
+ label: u.label,
118
+ style: f(E.value)
119
+ }, null, 8, [
120
+ "class",
121
+ "data-sui-position",
122
+ "label",
123
+ "style"
124
+ ])]),
108
125
  _: 1
109
126
  }, 8, ["swipe-threshold"]));
110
127
  }
111
128
  });
112
129
  //#endregion
113
- export { v as default };
130
+ export { x as default };
114
131
 
115
132
  //# sourceMappingURL=Toaster.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_TransitionGroup","_withCtx","_createElementBlock","_Fragment","_renderList","ToastMessage","_unref","_createVNode","ToastMessage_default","Toaster_vue_vue_type_script_setup_true_lang_default","__emit","emit","paused","reactive","runLive","action","removeToast","id","runPreview","__props","openBlock","createBlock","TransitionGroup","withCtx","createElementBlock","Fragment","renderList","item","index","unref","toastActions","$event","ToastProvider","toasts","ToastRoot","open","createVNode","ToastViewport"],"sources":["../../../src/components/Toast/Toaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { reactive } from 'vue'\n\nimport { ToastProvider, ToastRoot, ToastViewport } from 'reka-ui'\n\nimport {\n type ToastAction,\n type ToastDismissReason,\n type ToastSeverity,\n removeToast,\n toastActions,\n toasts\n} from '../../composables/toast'\nimport ToastMessage from './ToastMessage.vue'\n\nexport interface ToastPreview {\n /** Keeps its place as the list changes, so toasts animate in and out like live ones. Defaults to its index. */\n id?: string | number\n summary: string\n detail?: string\n severity?: ToastSeverity\n closable?: boolean\n action?: ToastAction\n actions?: ToastAction[]\n /** With actions, the countdown bar's length in ms; it emits `close` with `timeout` when it runs out. */\n life?: number\n}\n\nexport interface ToasterProps {\n /** The toast region's name for assistive tech; `{hotkey}` is F8, which focuses it. */\n label?: string\n closeLabel?: string\n /**\n * Toasts drawn in place, for docs, designs and demos, instead of the live ones fixed to the viewport. The list is\n * yours: add and remove items, and handle `close`.\n */\n preview?: ToastPreview[]\n}\n\nwithDefaults(defineProps<ToasterProps>(), {\n label: 'Notifications ({hotkey})',\n closeLabel: 'Close',\n preview: undefined\n})\n\nconst emit = defineEmits<{\n /** A preview toast left, with its `id` (or index): its close button, one of its actions, or its countdown. */\n close: [id: string | number, reason: ToastDismissReason]\n}>()\n\n// Reka pauses every toast's timer while the region is hovered or focused, or the window is in the background; the\n// countdown bars follow it.\nconst paused = reactive(new Set<number>())\n\nfunction runLive(id: number, action: ToastAction) {\n action.onClick()\n removeToast(id, 'action')\n}\n\nfunction runPreview(id: string | number, action: ToastAction) {\n action.onClick()\n emit('close', id, 'action')\n}\n</script>\n\n<!-- Mount once near the app root; `toast.info(...)` and friends show here. Swiping is off. -->\n<template>\n <TransitionGroup\n v-if=\"preview\"\n class=\"flex w-full max-w-96 flex-col\"\n enter-active-class=\"animate-sui-toast-in\"\n leave-active-class=\"animate-sui-toast-out overflow-hidden\"\n tag=\"div\"\n >\n <ToastMessage\n v-for=\"(item, index) in preview\"\n :key=\"item.id ?? index\"\n :actions=\"toastActions(item)\"\n :closable=\"item.closable\"\n :close-label=\"closeLabel\"\n :detail=\"item.detail\"\n :life=\"item.life\"\n :severity=\"item.severity\"\n :summary=\"item.summary\"\n @action=\"runPreview(item.id ?? index, $event)\"\n @close=\"emit('close', item.id ?? index, 'close')\"\n @expire=\"emit('close', item.id ?? index, 'timeout')\"\n />\n </TransitionGroup>\n <ToastProvider v-else :swipe-threshold=\"Number.POSITIVE_INFINITY\">\n <ToastRoot\n v-for=\"item in toasts\"\n :key=\"item.id\"\n as-child\n :duration=\"item.life || Number.POSITIVE_INFINITY\"\n :open=\"item.open\"\n :type=\"item.severity === 'error' ? 'foreground' : 'background'\"\n @escape-key-down=\"removeToast(item.id, 'close')\"\n @pause=\"paused.add(item.id)\"\n @resume=\"paused.delete(item.id)\"\n @update:open=\"(open) => !open && removeToast(item.id, 'timeout')\"\n >\n <ToastMessage\n :actions=\"item.actions\"\n class=\"pointer-events-auto data-[state=closed]:animate-sui-toast-out data-[state=closed]:overflow-hidden data-[state=open]:animate-sui-toast-in\"\n :closable=\"item.closable\"\n :close-label=\"closeLabel\"\n :detail=\"item.detail\"\n :life=\"item.life\"\n :paused=\"paused.has(item.id)\"\n :severity=\"item.severity\"\n :summary=\"item.summary\"\n @action=\"runLive(item.id, $event)\"\n @close=\"removeToast(item.id, 'close')\"\n />\n </ToastRoot>\n <!-- A div, not Reka's default ol: the toasts are divs, so a page can draw one alone. -->\n <ToastViewport\n as=\"div\"\n class=\"pointer-events-none fixed bottom-5 left-1/2 z-[1200] flex w-96 max-w-[calc(100vw-2.5rem)] -translate-x-1/2 flex-col rounded-md outline-hidden\"\n data-sui-toasts\n :label=\"label\"\n />\n </ToastProvider>\n</template>\n"],"mappings":";;;;;;;;;;;;;;EA6CA,IAAMa,IAAOD,GAOPE,IAASC,kBAAS,IAAI,IAAY,CAAC;EAEzC,SAASC,EAAQ,GAAY,GAAqB;GAEhD,AADAC,EAAO,QAAQ,GACfC,EAAYC,GAAI,QAAQ;EAC1B;EAEA,SAASC,EAAW,GAAqB,GAAqB;GAE5D,AADAH,EAAO,QAAQ,GACfJ,EAAK,SAASM,GAAI,QAAQ;EAC5B;E,iBAMUE,EAAA,WADRrB,EAAA,GAAAC,EAqBkBC,GAAA;;GAnBhB,OAAM;GACN,sBAAmB;GACnB,sBAAmB;GACnB,KAAI;;GAGF,SAAAC,QAAgC,EADlCH,EAAA,EAAA,GAAAI,EAaEC,GAAA,MAAAC,EAZwBe,EAAA,UAAhB,GAAM,OADhBrB,EAAA,GAAAC,EAaEM,GAAA;IAXC,KAAKsB,EAAK,MAAMC;IAChB,SAAStB,EAAAwB,CAAA,CAAY,CAACH,CAAI;IAC1B,UAAUA,EAAK;IACf,eAAaR,EAAA;IACb,QAAQQ,EAAK;IACb,MAAMA,EAAK;IACX,UAAUA,EAAK;IACf,SAASA,EAAK;IACd,WAAM,MAAET,EAAWS,EAAK,MAAMC,GAAOG,CAAM;IAC3C,UAAK,MAAEpB,EAAI,SAAUgB,EAAK,MAAMC,GAAK,OAAA;IACrC,WAAM,MAAEjB,EAAI,SAAUgB,EAAK,MAAMC,GAAK,SAAA;;;;;;;;;;;;;;E,OAG3C9B,EAAA,GAAAC,EAkCgBO,EAAA0B,CAAA,GAAA;;GAlCO,mBAAiB;;GAEpC,SAAA/B,QAAsB,EADxBH,EAAA,EAAA,GAAAI,EAyBYC,GAAA,MAAAC,EAxBKE,EAAA2B,CAAA,IAAR,OADTnC,EAAA,GAAAC,EAyBYO,EAAA4B,CAAA,GAAA;IAvBT,KAAKP,EAAK;IACX,YAAA;IACC,UAAUA,EAAK,QAAQ;IACvB,MAAMA,EAAK;IACX,MAAMA,EAAK,aAAQ,UAAA,eAAA;IACnB,kBAAe,MAAErB,EAAAU,CAAA,CAAW,CAACW,EAAK,IAAE,OAAA;IACpC,UAAK,MAAEf,EAAO,IAAIe,EAAK,EAAE;IACzB,WAAM,MAAEf,EAAO,OAAOe,EAAK,EAAE;IAC7B,kBAAc,MAAI,CAAMQ,KAAQ7B,EAAAU,CAAA,CAAW,CAACW,EAAK,IAAE,SAAA;;IAEpD,SAAA1B,QAYE,CAZFM,EAYEF,GAAA;KAXC,SAASsB,EAAK;KACf,OAAM;KACL,UAAUA,EAAK;KACf,eAAaR,EAAA;KACb,QAAQQ,EAAK;KACb,MAAMA,EAAK;KACX,QAAQf,EAAO,IAAIe,EAAK,EAAE;KAC1B,UAAUA,EAAK;KACf,SAASA,EAAK;KACd,WAAM,MAAEb,EAAQa,EAAK,IAAII,CAAM;KAC/B,UAAK,MAAEzB,EAAAU,CAAA,CAAW,CAACW,EAAK,IAAE,OAAA;;;;;;;;;;;;;;;;;;;;;;G,aAI/BpB,EAKED,EAAA+B,CAAA,GAAA;IAJA,IAAG;IACH,OAAM;IACN,mBAAA;IACC,OAAOlB,EAAA"}
1
+ {"version":3,"file":"Toaster.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_TransitionGroup","_withCtx","_createElementBlock","_Fragment","_renderList","ToastMessage","_unref","_createVNode","_normalizeClass","_normalizeStyle","ToastMessage_default","Toaster_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","paused","reactive","side","edge","placement","computed","vertical","horizontal","fromTop","runLive","action","removeToast","id","runPreview","openBlock","createBlock","TransitionGroup","withCtx","createElementBlock","Fragment","renderList","item","index","unref","toastActions","$event","ToastProvider","toasts","ToastRoot","open","createVNode","normalizeClass","ToastViewport","normalizeStyle"],"sources":["../../../src/components/Toast/Toaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, reactive } from 'vue'\n\nimport { ToastProvider, ToastRoot, ToastViewport } from 'reka-ui'\n\nimport {\n type ToastAction,\n type ToastDismissReason,\n type ToastSeverity,\n removeToast,\n toastActions,\n toasts\n} from '../../composables/toast'\nimport ToastMessage from './ToastMessage.vue'\n\nexport interface ToastPreview {\n /** Keeps its place as the list changes, so toasts animate in and out like live ones. Defaults to its index. */\n id?: string | number\n summary: string\n detail?: string\n severity?: ToastSeverity\n closable?: boolean\n action?: ToastAction\n actions?: ToastAction[]\n /** With actions, the countdown bar's length in ms; it emits `close` with `timeout` when it runs out. */\n life?: number\n}\n\nexport type ToasterPosition = 'bottom-center' | 'bottom-left' | 'bottom-right' | 'top-center' | 'top-left' | 'top-right'\n\nexport interface ToasterProps {\n /** Where live toasts sit. Move them clear of the app's own chrome with the `--sui-toaster-inset-*` tokens. */\n position?: ToasterPosition\n /** The toast region's name for assistive tech; `{hotkey}` is F8, which focuses it. */\n label?: string\n closeLabel?: string\n /**\n * Toasts drawn in place, for docs, designs and demos, instead of the live ones fixed to the viewport. The list is\n * yours: add and remove items, and handle `close`.\n */\n preview?: ToastPreview[]\n}\n\nconst props = withDefaults(defineProps<ToasterProps>(), {\n position: 'bottom-center',\n label: 'Notifications ({hotkey})',\n closeLabel: 'Close',\n preview: undefined\n})\n\nconst emit = defineEmits<{\n /** A preview toast left, with its `id` (or index): its close button, one of its actions, or its countdown. */\n close: [id: string | number, reason: ToastDismissReason]\n}>()\n\n// Reka pauses every toast's timer while the region is hovered or focused, or the window is in the background; the\n// countdown bars follow it.\nconst paused = reactive(new Set<number>())\n\n// The region sits `--sui-toaster-margin` in from the viewport's edges plus the app's insets, and the safe area\n// beyond them; centred, it centres in what's left between the side insets.\nconst side = (edge: 'left' | 'right') => `calc(var(--sui-toaster-margin) + var(--sui-toaster-inset-${edge}))`\nconst placement = computed(() => {\n const [vertical, horizontal] = props.position.split('-') as ['top' | 'bottom', 'left' | 'center' | 'right']\n return {\n [vertical]: `calc(var(--sui-toaster-margin) + var(--sui-toaster-inset-${vertical}) + env(safe-area-inset-${vertical}))`,\n left: horizontal === 'right' ? 'auto' : side('left'),\n right: horizontal === 'left' ? 'auto' : side('right'),\n width: `min(var(--sui-toaster-width), 100vw - ${side('left')} - ${side('right')})`\n }\n})\nconst fromTop = computed(() => props.position.startsWith('top'))\n\nfunction runLive(id: number, action: ToastAction) {\n action.onClick()\n removeToast(id, 'action')\n}\n\nfunction runPreview(id: string | number, action: ToastAction) {\n action.onClick()\n emit('close', id, 'action')\n}\n</script>\n\n<!-- Mount once near the app root; `toast.info(...)` and friends show here. Swiping is off. -->\n<template>\n <TransitionGroup\n v-if=\"preview\"\n class=\"flex w-full max-w-96 flex-col\"\n enter-active-class=\"animate-sui-toast-in\"\n leave-active-class=\"animate-sui-toast-out overflow-hidden\"\n tag=\"div\"\n >\n <ToastMessage\n v-for=\"(item, index) in preview\"\n :key=\"item.id ?? index\"\n :actions=\"toastActions(item)\"\n :closable=\"item.closable\"\n :close-label=\"closeLabel\"\n :detail=\"item.detail\"\n :life=\"item.life\"\n :severity=\"item.severity\"\n :summary=\"item.summary\"\n @action=\"runPreview(item.id ?? index, $event)\"\n @close=\"emit('close', item.id ?? index, 'close')\"\n @expire=\"emit('close', item.id ?? index, 'timeout')\"\n />\n </TransitionGroup>\n <ToastProvider v-else :swipe-threshold=\"Number.POSITIVE_INFINITY\">\n <ToastRoot\n v-for=\"item in toasts\"\n :key=\"item.id\"\n as-child\n :duration=\"item.life || Number.POSITIVE_INFINITY\"\n :open=\"item.open\"\n :type=\"item.severity === 'error' ? 'foreground' : 'background'\"\n @escape-key-down=\"removeToast(item.id, 'close')\"\n @pause=\"paused.add(item.id)\"\n @resume=\"paused.delete(item.id)\"\n @update:open=\"(open) => !open && removeToast(item.id, 'timeout')\"\n >\n <ToastMessage\n :actions=\"item.actions\"\n class=\"pointer-events-auto data-[state=closed]:overflow-hidden data-[state=closed]:animate-sui-toast-out motion-reduce:data-[state=closed]:animate-sui-toast-fade\"\n :class=\"\n fromTop\n ? 'data-[state=open]:animate-sui-toast-in-top motion-reduce:data-[state=open]:animate-sui-fade-in'\n : 'data-[state=open]:animate-sui-toast-in motion-reduce:data-[state=open]:animate-sui-fade-in'\n \"\n :closable=\"item.closable\"\n :close-label=\"closeLabel\"\n :detail=\"item.detail\"\n :life=\"item.life\"\n :paused=\"paused.has(item.id)\"\n :severity=\"item.severity\"\n :summary=\"item.summary\"\n @action=\"runLive(item.id, $event)\"\n @close=\"removeToast(item.id, 'close')\"\n />\n </ToastRoot>\n <!-- A div, not Reka's default ol: the toasts are divs, so a page can draw one alone. From the top, the newest is\n nearest the edge, as it is at the bottom. -->\n <ToastViewport\n as=\"div\"\n class=\"pointer-events-none fixed z-[1200] mx-auto flex rounded-md outline-hidden\"\n :class=\"fromTop ? 'flex-col-reverse' : 'flex-col'\"\n :data-sui-position=\"position\"\n data-sui-toasts\n :label=\"label\"\n :style=\"placement\"\n />\n </ToastProvider>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;EA2CA,IAAMe,IAAQC,GAORC,IAAOH,GAOPI,IAASC,kBAAS,IAAI,IAAY,CAAC,GAInCC,KAAQ,MAA2B,4DAA4DC,EAAK,KACpGC,IAAYC,QAAe;GAC/B,IAAM,CAACC,GAAUC,KAAcV,EAAM,SAAS,MAAM,GAAG;GACvD,OAAO;KACJS,IAAW,4DAA4DA,EAAS,0BAA0BA,EAAS;IACpH,MAAMC,MAAe,UAAU,SAASL,EAAK,MAAM;IACnD,OAAOK,MAAe,SAAS,SAASL,EAAK,OAAO;IACpD,OAAO,yCAAyCA,EAAK,MAAM,EAAE,KAAKA,EAAK,OAAO,EAAE;GAClF;EACF,CAAC,GACKM,IAAUH,QAAeR,EAAM,SAAS,WAAW,KAAK,CAAC;EAE/D,SAASY,EAAQ,GAAY,GAAqB;GAEhD,AADAC,EAAO,QAAQ,GACfC,EAAYC,GAAI,QAAQ;EAC1B;EAEA,SAASC,EAAW,GAAqB,GAAqB;GAE5D,AADAH,EAAO,QAAQ,GACfX,EAAK,SAASa,GAAI,QAAQ;EAC5B;E,iBAMUd,EAAA,WADRhB,EAAA,GAAAC,EAqBkBC,GAAA;;GAnBhB,OAAM;GACN,sBAAmB;GACnB,sBAAmB;GACnB,KAAI;;GAGF,SAAAC,QAAgC,EADlCH,EAAA,EAAA,GAAAI,EAaEC,GAAA,MAAAC,EAZwBU,EAAA,UAAhB,GAAM,OADhBhB,EAAA,GAAAC,EAaEM,GAAA;IAXC,KAAKgC,EAAK,MAAMC;IAChB,SAAShC,EAAAkC,CAAA,CAAY,CAACH,CAAI;IAC1B,UAAUA,EAAK;IACf,eAAavB,EAAA;IACb,QAAQuB,EAAK;IACb,MAAMA,EAAK;IACX,UAAUA,EAAK;IACf,SAASA,EAAK;IACd,WAAM,MAAER,EAAWQ,EAAK,MAAMC,GAAOG,CAAM;IAC3C,UAAK,MAAE1B,EAAI,SAAUsB,EAAK,MAAMC,GAAK,OAAA;IACrC,WAAM,MAAEvB,EAAI,SAAUsB,EAAK,MAAMC,GAAK,SAAA;;;;;;;;;;;;;;E,OAG3CxC,EAAA,GAAAC,EA2CgBO,EAAAoC,CAAA,GAAA;;GA3CO,mBAAiB;;GAEpC,SAAAzC,QAAsB,EADxBH,EAAA,EAAA,GAAAI,EA8BYC,GAAA,MAAAC,EA7BKE,EAAAqC,CAAA,IAAR,OADT7C,EAAA,GAAAC,EA8BYO,EAAAsC,CAAA,GAAA;IA5BT,KAAKP,EAAK;IACX,YAAA;IACC,UAAUA,EAAK,QAAQ;IACvB,MAAMA,EAAK;IACX,MAAMA,EAAK,aAAQ,UAAA,eAAA;IACnB,kBAAe,MAAE/B,EAAAqB,CAAA,CAAW,CAACU,EAAK,IAAE,OAAA;IACpC,UAAK,MAAErB,EAAO,IAAIqB,EAAK,EAAE;IACzB,WAAM,MAAErB,EAAO,OAAOqB,EAAK,EAAE;IAC7B,kBAAc,MAAI,CAAMQ,KAAQvC,EAAAqB,CAAA,CAAW,CAACU,EAAK,IAAE,SAAA;;IAEpD,SAAApC,QAiBE,CAjBFM,EAiBEF,GAAA;KAhBC,SAASgC,EAAK;KACf,OAAK7B,EAAA,CAAC,8JACagB,EAAA,Q;KAKlB,UAAUa,EAAK;KACf,eAAavB,EAAA;KACb,QAAQuB,EAAK;KACb,MAAMA,EAAK;KACX,QAAQrB,EAAO,IAAIqB,EAAK,EAAE;KAC1B,UAAUA,EAAK;KACf,SAASA,EAAK;KACd,WAAM,MAAEZ,EAAQY,EAAK,IAAII,CAAM;KAC/B,UAAK,MAAEnC,EAAAqB,CAAA,CAAW,CAACU,EAAK,IAAE,OAAA;;;;;;;;;;;;;;;;;;;;;;;G,aAK/B9B,EAQED,EAAA0C,CAAA,GAAA;IAPA,IAAG;IACH,OAAKxC,EAAA,CAAC,6EACEgB,EAAA,QAAO,qBAAA,UAAA,CAAA;IACd,qBAAmBV,EAAA;IACpB,mBAAA;IACC,OAAOA,EAAA;IACP,OAAKL,EAAEW,EAAA,KAAS"}
@@ -0,0 +1,7 @@
1
+ import e from "./Toolbar.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/Toolbar/Toolbar.vue
3
+ var t = e;
4
+ //#endregion
5
+ export { t as default };
6
+
7
+ //# sourceMappingURL=Toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolbar.js","names":["_sfc_main","Toolbar_vue_vue_type_script_setup_true_lang_default","Toolbar_default"],"sources":["../../../src/components/Toolbar/Toolbar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onMounted, onUpdated, ref, useTemplateRef } from 'vue'\n\nexport interface ToolbarProps {\n /** Its accessible name, e.g. \"Text formatting\". */\n label: string\n orientation?: 'horizontal' | 'vertical'\n /** The arrow keys wrap from the last control to the first. */\n loop?: boolean\n}\n\nconst props = withDefaults(defineProps<ToolbarProps>(), { orientation: 'horizontal', loop: true })\n\nconst root = useTemplateRef<HTMLElement>('root')\n// The control Tab lands on: the last one focused, else the first.\nconst current = ref<HTMLElement | null>(null)\n\nconst controls = () => [...(root.value?.querySelectorAll<HTMLElement>('button, a[href], input, [role=\"button\"]') ?? [])]\nconst items = () => controls().filter((el) => !el.matches(':disabled, [aria-disabled=\"true\"]'))\n\n// The controls are the app's: the toolbar only sets their tabindex, so one of them is in the Tab order.\nfunction rove() {\n const all = items()\n const active = current.value && all.includes(current.value) ? current.value : all[0]\n for (const el of controls()) el.tabIndex = el === active ? 0 : -1\n}\n\nonMounted(rove)\nonUpdated(rove)\n\nfunction onFocusin(event: FocusEvent) {\n const target = items().find((el) => el === event.target)\n if (!target) return\n current.value = target\n rove()\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n const [back, next] = props.orientation === 'vertical' ? ['ArrowUp', 'ArrowDown'] : ['ArrowLeft', 'ArrowRight']\n if (![back, next, 'Home', 'End'].includes(event.key) || event.altKey || event.metaKey || event.ctrlKey) return\n // A field inside keeps its arrow keys.\n if ((event.target as HTMLElement).matches('input, textarea')) return\n const all = items()\n const i = all.indexOf(event.target as HTMLElement)\n if (i < 0) return\n const last = all.length - 1\n let to = event.key === 'Home' ? 0 : event.key === 'End' ? last : i + (event.key === next ? 1 : -1)\n if (to < 0) to = props.loop ? last : 0\n if (to > last) to = props.loop ? 0 : last\n event.preventDefault()\n all[to]?.focus()\n}\n</script>\n\n<!-- A row of controls, such as format toggles, that Tab enters once and the arrow keys move through. -->\n<template>\n <div\n ref=\"root\"\n :aria-label=\"label\"\n :aria-orientation=\"orientation\"\n class=\"flex gap-0.5\"\n :class=\"orientation === 'vertical' ? 'flex-col items-stretch' : 'items-center'\"\n role=\"toolbar\"\n @focusin=\"onFocusin\"\n @keydown=\"onKeydown\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":""}
@@ -0,0 +1,23 @@
1
+ export interface ToolbarProps {
2
+ /** Its accessible name, e.g. "Text formatting". */
3
+ label: string;
4
+ orientation?: 'horizontal' | 'vertical';
5
+ /** The arrow keys wrap from the last control to the first. */
6
+ loop?: boolean;
7
+ }
8
+ declare var __VLS_1: {};
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_1) => any;
11
+ };
12
+ declare const __VLS_base: import("vue").DefineComponent<ToolbarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ToolbarProps> & Readonly<{}>, {
13
+ loop: boolean;
14
+ orientation: "vertical" | "horizontal";
15
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,52 @@
1
+ import { createElementBlock as e, defineComponent as t, normalizeClass as n, onMounted as r, onUpdated as i, openBlock as a, ref as o, renderSlot as s, useTemplateRef as c } from "vue";
2
+ //#region src/components/Toolbar/Toolbar.vue?vue&type=script&setup=true&lang.ts
3
+ var l = ["aria-label", "aria-orientation"], u = /*@__PURE__*/ t({
4
+ __name: "Toolbar",
5
+ props: {
6
+ label: {},
7
+ orientation: { default: "horizontal" },
8
+ loop: {
9
+ type: Boolean,
10
+ default: !0
11
+ }
12
+ },
13
+ setup(t) {
14
+ let u = t, d = c("root"), f = o(null), p = () => [...d.value?.querySelectorAll("button, a[href], input, [role=\"button\"]") ?? []], m = () => p().filter((e) => !e.matches(":disabled, [aria-disabled=\"true\"]"));
15
+ function h() {
16
+ let e = m(), t = f.value && e.includes(f.value) ? f.value : e[0];
17
+ for (let e of p()) e.tabIndex = e === t ? 0 : -1;
18
+ }
19
+ r(h), i(h);
20
+ function g(e) {
21
+ let t = m().find((t) => t === e.target);
22
+ t && (f.value = t, h());
23
+ }
24
+ function _(e) {
25
+ let [t, n] = u.orientation === "vertical" ? ["ArrowUp", "ArrowDown"] : ["ArrowLeft", "ArrowRight"];
26
+ if (![
27
+ t,
28
+ n,
29
+ "Home",
30
+ "End"
31
+ ].includes(e.key) || e.altKey || e.metaKey || e.ctrlKey || e.target.matches("input, textarea")) return;
32
+ let r = m(), i = r.indexOf(e.target);
33
+ if (i < 0) return;
34
+ let a = r.length - 1, o = e.key === "Home" ? 0 : e.key === "End" ? a : i + (e.key === n ? 1 : -1);
35
+ o < 0 && (o = u.loop ? a : 0), o > a && (o = u.loop ? 0 : a), e.preventDefault(), r[o]?.focus();
36
+ }
37
+ return (r, i) => (a(), e("div", {
38
+ ref_key: "root",
39
+ ref: d,
40
+ "aria-label": t.label,
41
+ "aria-orientation": t.orientation,
42
+ class: n(["flex gap-0.5", t.orientation === "vertical" ? "flex-col items-stretch" : "items-center"]),
43
+ role: "toolbar",
44
+ onFocusin: g,
45
+ onKeydown: _
46
+ }, [s(r.$slots, "default")], 42, l));
47
+ }
48
+ });
49
+ //#endregion
50
+ export { u as default };
51
+
52
+ //# sourceMappingURL=Toolbar.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toolbar.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_renderSlot","_hoisted_1","Toolbar_vue_vue_type_script_setup_true_lang_default","props","__props","root","useTemplateRef","current","ref","controls","items","el","rove","all","active","onMounted","onUpdated","onFocusin","target","event","onKeydown","back","next","last","to","openBlock","createElementBlock","normalizeClass","renderSlot","_ctx"],"sources":["../../../src/components/Toolbar/Toolbar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onMounted, onUpdated, ref, useTemplateRef } from 'vue'\n\nexport interface ToolbarProps {\n /** Its accessible name, e.g. \"Text formatting\". */\n label: string\n orientation?: 'horizontal' | 'vertical'\n /** The arrow keys wrap from the last control to the first. */\n loop?: boolean\n}\n\nconst props = withDefaults(defineProps<ToolbarProps>(), { orientation: 'horizontal', loop: true })\n\nconst root = useTemplateRef<HTMLElement>('root')\n// The control Tab lands on: the last one focused, else the first.\nconst current = ref<HTMLElement | null>(null)\n\nconst controls = () => [...(root.value?.querySelectorAll<HTMLElement>('button, a[href], input, [role=\"button\"]') ?? [])]\nconst items = () => controls().filter((el) => !el.matches(':disabled, [aria-disabled=\"true\"]'))\n\n// The controls are the app's: the toolbar only sets their tabindex, so one of them is in the Tab order.\nfunction rove() {\n const all = items()\n const active = current.value && all.includes(current.value) ? current.value : all[0]\n for (const el of controls()) el.tabIndex = el === active ? 0 : -1\n}\n\nonMounted(rove)\nonUpdated(rove)\n\nfunction onFocusin(event: FocusEvent) {\n const target = items().find((el) => el === event.target)\n if (!target) return\n current.value = target\n rove()\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n const [back, next] = props.orientation === 'vertical' ? ['ArrowUp', 'ArrowDown'] : ['ArrowLeft', 'ArrowRight']\n if (![back, next, 'Home', 'End'].includes(event.key) || event.altKey || event.metaKey || event.ctrlKey) return\n // A field inside keeps its arrow keys.\n if ((event.target as HTMLElement).matches('input, textarea')) return\n const all = items()\n const i = all.indexOf(event.target as HTMLElement)\n if (i < 0) return\n const last = all.length - 1\n let to = event.key === 'Home' ? 0 : event.key === 'End' ? last : i + (event.key === next ? 1 : -1)\n if (to < 0) to = props.loop ? last : 0\n if (to > last) to = props.loop ? 0 : last\n event.preventDefault()\n all[to]?.focus()\n}\n</script>\n\n<!-- A row of controls, such as format toggles, that Tab enters once and the arrow keys move through. -->\n<template>\n <div\n ref=\"root\"\n :aria-label=\"label\"\n :aria-orientation=\"orientation\"\n class=\"flex gap-0.5\"\n :class=\"orientation === 'vertical' ? 'flex-col items-stretch' : 'items-center'\"\n role=\"toolbar\"\n @focusin=\"onFocusin\"\n @keydown=\"onKeydown\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;EAWA,IAAMM,IAAQC,GAERC,IAAOC,EAA4B,MAAM,GAEzCC,IAAUC,EAAwB,IAAI,GAEtCC,UAAiB,CAAC,GAAIJ,EAAK,OAAO,iBAA8B,2CAAyC,KAAK,CAAC,CAAE,GACjHK,UAAcD,EAAS,CAAC,CAAC,QAAQ,MAAO,CAACE,EAAG,QAAQ,qCAAmC,CAAC;EAG9F,SAASC,IAAO;GACd,IAAMC,IAAMH,EAAM,GACZI,IAASP,EAAQ,SAASM,EAAI,SAASN,EAAQ,KAAK,IAAIA,EAAQ,QAAQM,EAAI;GAClF,KAAK,IAAMF,KAAMF,EAAS,GAAG,EAAG,WAAWE,MAAOG,IAAS,IAAI;EACjE;EAGA,AADAC,EAAUH,CAAI,GACdI,EAAUJ,CAAI;EAEd,SAASK,EAAU,GAAmB;GACpC,IAAMC,IAASR,EAAM,CAAC,CAAC,MAAM,MAAOC,MAAOQ,EAAM,MAAM;GACvD,AAAKD,MACL,EAAQ,QAAQA,GAChBN,EAAK;EACP;EAEA,SAASQ,EAAU,GAAsB;GACvC,IAAM,CAACC,GAAMC,KAAQnB,EAAM,gBAAgB,aAAa,CAAC,WAAW,WAAW,IAAI,CAAC,aAAa,YAAY;GAG7G,IAFI,CAAC;IAACkB;IAAMC;IAAM;IAAQ;GAAK,CAAC,CAAC,SAASH,EAAM,GAAG,KAAKA,EAAM,UAAUA,EAAM,WAAWA,EAAM,WAE1FA,EAAM,OAAuB,QAAQ,iBAAiB,GAAG;GAC9D,IAAMN,IAAMH,EAAM,GACZ,IAAIG,EAAI,QAAQM,EAAM,MAAqB;GACjD,IAAI,IAAI,GAAG;GACX,IAAMI,IAAOV,EAAI,SAAS,GACtBW,IAAKL,EAAM,QAAQ,SAAS,IAAIA,EAAM,QAAQ,QAAQI,IAAO,KAAKJ,EAAM,QAAQG,IAAO,IAAI;GAI/F,AAHIE,IAAK,MAAG,IAAKrB,EAAM,OAAOoB,IAAO,IACjCC,IAAKD,MAAM,IAAKpB,EAAM,OAAO,IAAIoB,IACrCJ,EAAM,eAAe,GACrBN,EAAIW,EAAG,EAAE,MAAM;EACjB;E,kBAKE3B,EAAA,GAAAC,EAWM,OAAA;GAVA,SAAA;GAAJ,KAAIO;GACH,cAAYD,EAAA;GACZ,oBAAkBA,EAAA;GACnB,OAAKL,EAAA,CAAC,gBACEK,EAAA,gBAAW,aAAA,2BAAA,cAAA,CAAA;GACnB,MAAK;GACK;GACA;E,IAEVJ,EAAQ6B,EAAA,QAAA,SAAA,C"}
@@ -0,0 +1,2 @@
1
+ export { default as Toolbar } from './Toolbar.vue';
2
+ export type { ToolbarProps } from './Toolbar.vue';
@@ -1 +1 @@
1
- {"version":3,"file":"MenuItemContent.js","names":["_sfc_main","MenuItemContent_vue_vue_type_script_setup_true_lang_default","MenuItemContent_default"],"sources":["../../../src/components/internal/MenuItemContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport Icon from '../Icon/Icon.vue'\nimport type { DropdownMenuAction } from './menu'\n\ndefineProps<{ item: DropdownMenuAction }>()\n</script>\n\n<!-- One menu item as drawn: an icon, the label and a shortcut. -->\n<template>\n <div\n class=\"flex cursor-pointer items-center gap-2.5 px-2.5 py-1.5\"\n :class=\"item.variant === 'danger' ? 'text-sui-danger' : 'text-sui-ink'\"\n >\n <Icon\n v-if=\"item.icon\"\n class=\"h-4 w-4 shrink-0\"\n :color=\"item.variant === 'danger' ? 'danger' : 'ink-muted'\"\n :name=\"item.icon\"\n />\n <span class=\"flex-1 text-13\">{{ item.label }}</span>\n <span v-if=\"item.shortcut\" class=\"text-11 text-sui-ink-muted\">{{ item.shortcut }}</span>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"MenuItemContent.js","names":["_sfc_main","MenuItemContent_vue_vue_type_script_setup_true_lang_default","MenuItemContent_default"],"sources":["../../../src/components/internal/MenuItemContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport Icon from '../Icon/Icon.vue'\nimport type { DropdownMenuAction } from './menu'\n\n// Reka's item attributes come first, so a disabled item's own win over its `aria-disabled`.\ndefineOptions({ inheritAttrs: false })\n\ndefineProps<{ item: DropdownMenuAction; reasonId?: string }>()\n</script>\n\n<!-- One menu item as drawn: an icon, the label and a shortcut; disabled, dimmed, with its reason underneath. It's the\n menu item itself (its Reka item renders as-child). A disabled item isn't Reka's `disabled`, which arrow keys skip:\n the WAI-ARIA menu pattern keeps it reachable, and the menu's `select` ignores it. -->\n<template>\n <div\n v-bind=\"$attrs\"\n :aria-describedby=\"item.disabled && item.disabledReason ? reasonId : undefined\"\n :aria-disabled=\"item.disabled ? 'true' : undefined\"\n class=\"flex items-center gap-2.5 px-2.5 py-1.5\"\n :class=\"[\n item.variant === 'danger' ? 'text-sui-danger' : 'text-sui-ink',\n item.disabled ? 'cursor-default' : 'cursor-pointer'\n ]\"\n >\n <Icon\n v-if=\"item.icon\"\n class=\"h-4 w-4 shrink-0\"\n :class=\"item.disabled && 'opacity-50'\"\n :color=\"item.variant === 'danger' ? 'danger' : 'ink-muted'\"\n :name=\"item.icon\"\n />\n <span class=\"flex min-w-0 flex-1 flex-col\">\n <span class=\"text-13\" :class=\"item.disabled && 'opacity-50'\">{{ item.label }}</span>\n <span v-if=\"item.disabled && item.disabledReason\" :id=\"reasonId\" class=\"text-xs text-sui-ink-muted\">{{\n item.disabledReason\n }}</span>\n </span>\n <span v-if=\"item.shortcut\" class=\"text-11 text-sui-ink-muted\" :class=\"item.disabled && 'opacity-50'\">{{\n item.shortcut\n }}</span>\n </div>\n</template>\n"],"mappings":""}
@@ -1,6 +1,7 @@
1
1
  import type { DropdownMenuAction } from './menu';
2
2
  type __VLS_Props = {
3
3
  item: DropdownMenuAction;
4
+ reasonId?: string;
4
5
  };
5
6
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
7
  declare const _default: typeof __VLS_export;
@@ -1,26 +1,42 @@
1
1
  import e from "../Icon/Icon.js";
2
- import { createBlock as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, defineComponent as a, normalizeClass as o, openBlock as s, toDisplayString as c } from "vue";
2
+ import { createBlock as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, defineComponent as a, mergeProps as o, normalizeClass as s, openBlock as c, toDisplayString as l } from "vue";
3
3
  //#region src/components/internal/MenuItemContent.vue?vue&type=script&setup=true&lang.ts
4
- var l = { class: "flex-1 text-13" }, u = {
5
- key: 1,
6
- class: "text-11 text-sui-ink-muted"
7
- }, d = /*@__PURE__*/ a({
4
+ var u = ["aria-describedby", "aria-disabled"], d = { class: "flex min-w-0 flex-1 flex-col" }, f = ["id"], p = /*@__PURE__*/ a({
5
+ inheritAttrs: !1,
8
6
  __name: "MenuItemContent",
9
- props: { item: {} },
7
+ props: {
8
+ item: {},
9
+ reasonId: {}
10
+ },
10
11
  setup(a) {
11
- return (d, f) => (s(), r("div", { class: o(["flex cursor-pointer items-center gap-2.5 px-2.5 py-1.5", a.item.variant === "danger" ? "text-sui-danger" : "text-sui-ink"]) }, [
12
- a.item.icon ? (s(), t(e, {
12
+ return (p, m) => (c(), r("div", o(p.$attrs, {
13
+ "aria-describedby": a.item.disabled && a.item.disabledReason ? a.reasonId : void 0,
14
+ "aria-disabled": a.item.disabled ? "true" : void 0,
15
+ class: ["flex items-center gap-2.5 px-2.5 py-1.5", [a.item.variant === "danger" ? "text-sui-danger" : "text-sui-ink", a.item.disabled ? "cursor-default" : "cursor-pointer"]]
16
+ }), [
17
+ a.item.icon ? (c(), t(e, {
13
18
  key: 0,
14
- class: "h-4 w-4 shrink-0",
19
+ class: s(["h-4 w-4 shrink-0", a.item.disabled && "opacity-50"]),
15
20
  color: a.item.variant === "danger" ? "danger" : "ink-muted",
16
21
  name: a.item.icon
17
- }, null, 8, ["color", "name"])) : n("", !0),
18
- i("span", l, c(a.item.label), 1),
19
- a.item.shortcut ? (s(), r("span", u, c(a.item.shortcut), 1)) : n("", !0)
20
- ], 2));
22
+ }, null, 8, [
23
+ "class",
24
+ "color",
25
+ "name"
26
+ ])) : n("", !0),
27
+ i("span", d, [i("span", { class: s(["text-13", a.item.disabled && "opacity-50"]) }, l(a.item.label), 3), a.item.disabled && a.item.disabledReason ? (c(), r("span", {
28
+ key: 0,
29
+ id: a.reasonId,
30
+ class: "text-xs text-sui-ink-muted"
31
+ }, l(a.item.disabledReason), 9, f)) : n("", !0)]),
32
+ a.item.shortcut ? (c(), r("span", {
33
+ key: 1,
34
+ class: s(["text-11 text-sui-ink-muted", a.item.disabled && "opacity-50"])
35
+ }, l(a.item.shortcut), 3)) : n("", !0)
36
+ ], 16, u));
21
37
  }
22
38
  });
23
39
  //#endregion
24
- export { d as default };
40
+ export { p as default };
25
41
 
26
42
  //# sourceMappingURL=MenuItemContent.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MenuItemContent.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_createBlock","Icon","_createCommentVNode","_createElementVNode","_toDisplayString","Icon_default","_hoisted_1","_hoisted_2","MenuItemContent_vue_vue_type_script_setup_true_lang_default","openBlock","createElementBlock","normalizeClass","__props","createBlock","createCommentVNode","createElementVNode","toDisplayString"],"sources":["../../../src/components/internal/MenuItemContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport Icon from '../Icon/Icon.vue'\nimport type { DropdownMenuAction } from './menu'\n\ndefineProps<{ item: DropdownMenuAction }>()\n</script>\n\n<!-- One menu item as drawn: an icon, the label and a shortcut. -->\n<template>\n <div\n class=\"flex cursor-pointer items-center gap-2.5 px-2.5 py-1.5\"\n :class=\"item.variant === 'danger' ? 'text-sui-danger' : 'text-sui-ink'\"\n >\n <Icon\n v-if=\"item.icon\"\n class=\"h-4 w-4 shrink-0\"\n :color=\"item.variant === 'danger' ? 'danger' : 'ink-muted'\"\n :name=\"item.icon\"\n />\n <span class=\"flex-1 text-13\">{{ item.label }}</span>\n <span v-if=\"item.shortcut\" class=\"text-11 text-sui-ink-muted\">{{ item.shortcut }}</span>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;E,kBASEA,EAAA,GAAAC,EAYM,OAAA,EAXJ,OAAKC,EAAA,CAAC,0DACEa,EAAA,KAAK,YAAO,WAAA,oBAAA,cAAA,CAAA,E;GAGZA,EAAA,KAAK,QADbf,EAAA,GAAAG,EAKEC,GAAA;;IAHA,OAAM;IACL,OAAOW,EAAA,KAAK,YAAO,WAAA,WAAA;IACnB,MAAMA,EAAA,KAAK;;GAEdT,EAAoD,QAApDG,GAAoDF,EAApBQ,EAAA,KAAK,KAAK,GAAA,CAAA;GAC9BA,EAAA,KAAK,YAAjBf,EAAA,GAAAC,EAAwF,QAAxFS,GAAwFH,EAAvBQ,EAAA,KAAK,QAAQ,GAAA,CAAA,K"}
1
+ {"version":3,"file":"MenuItemContent.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createElementBlock","_mergeProps","_createBlock","Icon","_normalizeClass","_createCommentVNode","_createElementVNode","_toDisplayString","Icon_default","_hoisted_1","_hoisted_2","_hoisted_3","MenuItemContent_vue_vue_type_script_setup_true_lang_default","openBlock","createElementBlock","mergeProps","_ctx","__props","createBlock","normalizeClass","createCommentVNode","createElementVNode","toDisplayString"],"sources":["../../../src/components/internal/MenuItemContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport Icon from '../Icon/Icon.vue'\nimport type { DropdownMenuAction } from './menu'\n\n// Reka's item attributes come first, so a disabled item's own win over its `aria-disabled`.\ndefineOptions({ inheritAttrs: false })\n\ndefineProps<{ item: DropdownMenuAction; reasonId?: string }>()\n</script>\n\n<!-- One menu item as drawn: an icon, the label and a shortcut; disabled, dimmed, with its reason underneath. It's the\n menu item itself (its Reka item renders as-child). A disabled item isn't Reka's `disabled`, which arrow keys skip:\n the WAI-ARIA menu pattern keeps it reachable, and the menu's `select` ignores it. -->\n<template>\n <div\n v-bind=\"$attrs\"\n :aria-describedby=\"item.disabled && item.disabledReason ? reasonId : undefined\"\n :aria-disabled=\"item.disabled ? 'true' : undefined\"\n class=\"flex items-center gap-2.5 px-2.5 py-1.5\"\n :class=\"[\n item.variant === 'danger' ? 'text-sui-danger' : 'text-sui-ink',\n item.disabled ? 'cursor-default' : 'cursor-pointer'\n ]\"\n >\n <Icon\n v-if=\"item.icon\"\n class=\"h-4 w-4 shrink-0\"\n :class=\"item.disabled && 'opacity-50'\"\n :color=\"item.variant === 'danger' ? 'danger' : 'ink-muted'\"\n :name=\"item.icon\"\n />\n <span class=\"flex min-w-0 flex-1 flex-col\">\n <span class=\"text-13\" :class=\"item.disabled && 'opacity-50'\">{{ item.label }}</span>\n <span v-if=\"item.disabled && item.disabledReason\" :id=\"reasonId\" class=\"text-xs text-sui-ink-muted\">{{\n item.disabledReason\n }}</span>\n </span>\n <span v-if=\"item.shortcut\" class=\"text-11 text-sui-ink-muted\" :class=\"item.disabled && 'opacity-50'\">{{\n item.shortcut\n }}</span>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;E,kBAcEC,EAAA,GAAAC,EA0BM,OA1BNC,EACUH,EAyBJ,QAzBU;GACb,oBAAkBmB,EAAA,KAAK,YAAYA,EAAA,KAAK,iBAAiBA,EAAA,WAAW,KAAA;GACpE,iBAAeA,EAAA,KAAK,WAAQ,SAAY,KAAA;GACzC,OAAK,CAAC,2CAAyC,CAC/BA,EAAA,KAAK,YAAO,WAAA,oBAAA,gBAA0DA,EAAA,KAAK,WAAQ,mBAAA,gB;;GAM3FA,EAAA,KAAK,QADblB,EAAA,GAAAG,EAMEC,GAAA;;IAJA,OAAKC,EAAA,CAAC,oBACEa,EAAA,KAAK,YAAQ,YAAA,CAAA;IACpB,OAAOA,EAAA,KAAK,YAAO,WAAA,WAAA;IACnB,MAAMA,EAAA,KAAK;;;;;;GAEdX,EAKO,QALPI,GAKO,CAJLJ,EAAoF,QAAA,EAA9E,OAAKF,EAAA,CAAC,WAAkBa,EAAA,KAAK,YAAQ,YAAA,CAAA,EAAqB,GAAAV,EAAAU,EAAA,KAAK,KAAK,GAAA,CAAA,GAC9DA,EAAA,KAAK,YAAYA,EAAA,KAAK,kBAAlClB,EAAA,GAAAC,EAES,QAAA;;IAF0C,IAAIiB,EAAA;IAAU,OAAM;GACrE,GAAAV,EAAAU,EAAA,KAAK,cAAc,GAAA,GAAAN,CAAA,K;GAGXM,EAAA,KAAK,YAAjBlB,EAAA,GAAAC,EAES,QAAA;;IAFkB,OAAKI,EAAA,CAAC,8BAAqCa,EAAA,KAAK,YAAQ,YAAA,CAAA;GACjF,GAAAV,EAAAU,EAAA,KAAK,QAAQ,GAAA,CAAA,K"}
@@ -12,6 +12,10 @@ export interface DropdownMenuAction {
12
12
  acceptLabel?: string;
13
13
  };
14
14
  confirmed?: boolean;
15
+ /** Dimmed and inert, but still reached with the arrow keys and announced as unavailable. */
16
+ disabled?: boolean;
17
+ /** Why it's disabled, shown under its label. */
18
+ disabledReason?: string;
15
19
  [key: string]: unknown;
16
20
  }
17
21
  export type DropdownMenuEntry = DropdownMenuAction | {
@@ -43,4 +47,4 @@ export declare function useMenuSelect(props: Required<Omit<MenuConfirmLabels, 'i
43
47
  id?: string;
44
48
  }, emit: (item: DropdownMenuAction & {
45
49
  id?: string;
46
- }) => void): (item: DropdownMenuAction) => Promise<void>;
50
+ }) => void): (item: DropdownMenuAction, event?: Event) => Promise<void>;
@@ -10,21 +10,24 @@ var t = {
10
10
  }, n = "z-[1100] rounded-xl border border-sui-line-subtle bg-sui-surface p-1 shadow-lg outline-hidden data-[state=open]:animate-sui-menu-in", r = "relative rounded-lg text-sm text-sui-ink transition-colors duration-150 outline-hidden hover:bg-sui-sunken focus-visible:sui-ring-inset data-highlighted:bg-sui-sunken", i = "my-1 border-t border-sui-line-subtle";
11
11
  function a(t, n) {
12
12
  let r = e();
13
- return async function(e) {
14
- if (e.confirm || e.confirmed) {
15
- let n = e.variant === "danger" || e.action === "delete";
16
- if (!await r({
17
- title: e.confirm?.title ?? t.confirmTitle,
18
- message: e.confirm?.message ?? t.confirmMessage,
19
- cancelLabel: t.cancelLabel,
20
- confirmLabel: e.confirm?.acceptLabel ?? (e.action === "delete" ? t.deleteLabel : t.confirmLabel),
21
- confirmVariant: n ? "danger" : "primary"
22
- })) return;
13
+ return async function(e, i) {
14
+ if (e.disabled) i?.preventDefault();
15
+ else {
16
+ if (e.confirm || e.confirmed) {
17
+ let n = e.variant === "danger" || e.action === "delete";
18
+ if (!await r({
19
+ title: e.confirm?.title ?? t.confirmTitle,
20
+ message: e.confirm?.message ?? t.confirmMessage,
21
+ cancelLabel: t.cancelLabel,
22
+ confirmLabel: e.confirm?.acceptLabel ?? (e.action === "delete" ? t.deleteLabel : t.confirmLabel),
23
+ confirmVariant: n ? "danger" : "primary"
24
+ })) return;
25
+ }
26
+ n({
27
+ id: t.id,
28
+ ...e
29
+ });
23
30
  }
24
- n({
25
- id: t.id,
26
- ...e
27
- });
28
31
  };
29
32
  }
30
33
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","names":["menuConfirmDefaults","menuContentClass","menuItemClass","menuSeparatorClass","useMenuSelect","confirm","useConfirm","item","destructive","props"],"sources":["../../../src/components/internal/menu.ts"],"sourcesContent":["import { useConfirm } from '../../composables/useConfirm'\n\nexport interface DropdownMenuAction {\n type: 'action'\n label: string\n action?: string\n icon?: string\n variant?: 'danger'\n shortcut?: string\n /** Asks first, with this wording; `confirmed: true` asks with the generic wording. */\n confirm?: { message: string; title?: string; acceptLabel?: string }\n confirmed?: boolean\n [key: string]: unknown\n}\n\nexport type DropdownMenuEntry = DropdownMenuAction | { type: 'separator' }\n\n/** The confirm step's wording, shared by DropdownMenu and ContextMenu. */\nexport interface MenuConfirmLabels {\n /** Passed back with every clicked item, e.g. the record the menu acts on. */\n id?: string\n confirmTitle?: string\n confirmMessage?: string\n confirmLabel?: string\n deleteLabel?: string\n cancelLabel?: string\n}\n\nexport const menuConfirmDefaults = {\n id: undefined,\n confirmTitle: 'Are you sure?',\n confirmMessage: \"This can't be undone.\",\n confirmLabel: 'Confirm',\n deleteLabel: 'Delete',\n cancelLabel: 'Cancel'\n}\n\nexport const menuContentClass =\n 'z-[1100] rounded-xl border border-sui-line-subtle bg-sui-surface p-1 shadow-lg outline-hidden data-[state=open]:animate-sui-menu-in'\nexport const menuItemClass =\n 'relative rounded-lg text-sm text-sui-ink transition-colors duration-150 outline-hidden hover:bg-sui-sunken focus-visible:sui-ring-inset data-highlighted:bg-sui-sunken'\nexport const menuSeparatorClass = 'my-1 border-t border-sui-line-subtle'\n\n/** Runs an item: asks first when it says so, then emits it with the menu's `id`. */\nexport function useMenuSelect(\n props: Required<Omit<MenuConfirmLabels, 'id'>> & { id?: string },\n emit: (item: DropdownMenuAction & { id?: string }) => void\n) {\n const confirm = useConfirm()\n\n return async function select(item: DropdownMenuAction) {\n if (item.confirm || item.confirmed) {\n const destructive = item.variant === 'danger' || item.action === 'delete'\n const confirmed = await confirm({\n title: item.confirm?.title ?? props.confirmTitle,\n message: item.confirm?.message ?? props.confirmMessage,\n cancelLabel: props.cancelLabel,\n confirmLabel: item.confirm?.acceptLabel ?? (item.action === 'delete' ? props.deleteLabel : props.confirmLabel),\n confirmVariant: destructive ? 'danger' : 'primary'\n })\n if (!confirmed) return\n }\n emit({ id: props.id, ...item })\n }\n}\n"],"mappings":";;AA4BA,IAAaA,IAAsB;CACjC,IAAI,KAAA;CACJ,cAAc;CACd,gBAAgB;CAChB,cAAc;CACd,aAAa;CACb,aAAa;AACf,GAEaC,IACX,uIACWC,IACX,0KACWC,IAAqB;AAGlC,SAAgBC,EACd,GACA,GACA;CACA,IAAMC,IAAUC,EAAW;CAE3B,OAAO,eAAsB,GAA0B;EACrD,IAAIC,EAAK,WAAWA,EAAK,WAAW;GAClC,IAAMC,IAAcD,EAAK,YAAY,YAAYA,EAAK,WAAW;GAQjE,IAAI,CAAC,MAPmBF,EAAQ;IAC9B,OAAOE,EAAK,SAAS,SAASE,EAAM;IACpC,SAASF,EAAK,SAAS,WAAWE,EAAM;IACxC,aAAaA,EAAM;IACnB,cAAcF,EAAK,SAAS,gBAAgBA,EAAK,WAAW,WAAWE,EAAM,cAAcA,EAAM;IACjG,gBAAgBD,IAAc,WAAW;GAC3C,CAAC,GACe;EAClB;EACA,EAAK;GAAE,IAAIC,EAAM;GAAI,GAAGF;EAAK,CAAC;CAChC;AACF"}
1
+ {"version":3,"file":"menu.js","names":["menuConfirmDefaults","menuContentClass","menuItemClass","menuSeparatorClass","useMenuSelect","confirm","useConfirm","item","destructive","props"],"sources":["../../../src/components/internal/menu.ts"],"sourcesContent":["import { useConfirm } from '../../composables/useConfirm'\n\nexport interface DropdownMenuAction {\n type: 'action'\n label: string\n action?: string\n icon?: string\n variant?: 'danger'\n shortcut?: string\n /** Asks first, with this wording; `confirmed: true` asks with the generic wording. */\n confirm?: { message: string; title?: string; acceptLabel?: string }\n confirmed?: boolean\n /** Dimmed and inert, but still reached with the arrow keys and announced as unavailable. */\n disabled?: boolean\n /** Why it's disabled, shown under its label. */\n disabledReason?: string\n [key: string]: unknown\n}\n\nexport type DropdownMenuEntry = DropdownMenuAction | { type: 'separator' }\n\n/** The confirm step's wording, shared by DropdownMenu and ContextMenu. */\nexport interface MenuConfirmLabels {\n /** Passed back with every clicked item, e.g. the record the menu acts on. */\n id?: string\n confirmTitle?: string\n confirmMessage?: string\n confirmLabel?: string\n deleteLabel?: string\n cancelLabel?: string\n}\n\nexport const menuConfirmDefaults = {\n id: undefined,\n confirmTitle: 'Are you sure?',\n confirmMessage: \"This can't be undone.\",\n confirmLabel: 'Confirm',\n deleteLabel: 'Delete',\n cancelLabel: 'Cancel'\n}\n\nexport const menuContentClass =\n 'z-[1100] rounded-xl border border-sui-line-subtle bg-sui-surface p-1 shadow-lg outline-hidden data-[state=open]:animate-sui-menu-in'\nexport const menuItemClass =\n 'relative rounded-lg text-sm text-sui-ink transition-colors duration-150 outline-hidden hover:bg-sui-sunken focus-visible:sui-ring-inset data-highlighted:bg-sui-sunken'\nexport const menuSeparatorClass = 'my-1 border-t border-sui-line-subtle'\n\n/** Runs an item: asks first when it says so, then emits it with the menu's `id`. */\nexport function useMenuSelect(\n props: Required<Omit<MenuConfirmLabels, 'id'>> & { id?: string },\n emit: (item: DropdownMenuAction & { id?: string }) => void\n) {\n const confirm = useConfirm()\n\n return async function select(item: DropdownMenuAction, event?: Event) {\n if (item.disabled) {\n // Keeps the menu open.\n event?.preventDefault()\n return\n }\n if (item.confirm || item.confirmed) {\n const destructive = item.variant === 'danger' || item.action === 'delete'\n const confirmed = await confirm({\n title: item.confirm?.title ?? props.confirmTitle,\n message: item.confirm?.message ?? props.confirmMessage,\n cancelLabel: props.cancelLabel,\n confirmLabel: item.confirm?.acceptLabel ?? (item.action === 'delete' ? props.deleteLabel : props.confirmLabel),\n confirmVariant: destructive ? 'danger' : 'primary'\n })\n if (!confirmed) return\n }\n emit({ id: props.id, ...item })\n }\n}\n"],"mappings":";;AAgCA,IAAaA,IAAsB;CACjC,IAAI,KAAA;CACJ,cAAc;CACd,gBAAgB;CAChB,cAAc;CACd,aAAa;CACb,aAAa;AACf,GAEaC,IACX,uIACWC,IACX,0KACWC,IAAqB;AAGlC,SAAgBC,EACd,GACA,GACA;CACA,IAAMC,IAAUC,EAAW;CAE3B,OAAO,eAAsB,GAA0B,GAAe;EACpE,IAAIC,EAAK,UAEP,GAAO,eAAe;OAGxB;OAAIA,EAAK,WAAWA,EAAK,WAAW;IAClC,IAAMC,IAAcD,EAAK,YAAY,YAAYA,EAAK,WAAW;IAQjE,IAAI,CAAC,MAPmBF,EAAQ;KAC9B,OAAOE,EAAK,SAAS,SAASE,EAAM;KACpC,SAASF,EAAK,SAAS,WAAWE,EAAM;KACxC,aAAaA,EAAM;KACnB,cAAcF,EAAK,SAAS,gBAAgBA,EAAK,WAAW,WAAWE,EAAM,cAAcA,EAAM;KACjG,gBAAgBD,IAAc,WAAW;IAC3C,CAAC,GACe;GAClB;GACA,EAAK;IAAE,IAAIC,EAAM;IAAI,GAAGF;GAAK,CAAC;EAD9B;CAEF;AACF"}
package/dist/index.d.ts CHANGED
@@ -32,6 +32,7 @@ export * from './components/Table';
32
32
  export * from './components/Tag';
33
33
  export * from './components/Textarea';
34
34
  export * from './components/Toast';
35
+ export * from './components/Toolbar';
35
36
  export * from './components/Tooltip';
36
37
  export * from './components/TypingIndicator';
37
38
  export { hueFor, type Hue } from './utils/hues';
package/dist/index.js CHANGED
@@ -31,19 +31,21 @@ import N from "./components/ImageUpload/ImageUpload.js";
31
31
  import P from "./components/Kbd/Kbd.js";
32
32
  import F from "./components/Pagination/Pagination.js";
33
33
  import I from "./components/Popover/Popover.js";
34
- import L from "./components/Spinner/Spinner.js";
35
- import R from "./components/Tag/Tag.js";
36
- import z from "./components/Select/Select.js";
37
- import B from "./components/Textarea/Textarea.js";
38
- import V from "./components/PropertyList/Editable.js";
39
- import H from "./components/PropertyList/PropertyList.js";
40
- import U from "./components/PropertyRow/Collapsible.js";
41
- import W from "./components/PropertyRow/PropertyRow.js";
42
- import G from "./components/Radio/Radio.js";
43
- import K from "./components/Table/Table.js";
44
- import { toast as q } from "./composables/toast.js";
45
- import J from "./components/Toast/Toaster.js";
46
- import Y from "./components/TypingIndicator/TypingIndicator.js";
47
- import { initColorMode as X, useColorMode as Z, useForceLightMode as Q } from "./composables/useColorMode.js";
48
- import { Banner as $, BulkActions as ee, CalendarMonth as te, Chip as ne, ConfirmDialog as re, Field as ie, FilterFieldPicker as ae, FormErrors as oe, ImageInput as se, InlineField as ce, InlineForm as le, LedgerMore as ue, LedgerRow as de, List as fe, Modal as pe, OptionsMenu as me, Pill as he, SortControl as ge, TextInput as _e, TypingDots as ve } from "./aliases.js";
49
- export { a as ActionBar, o as Alert, c as AlertDialog, u as Avatar, d as Badge, $ as Banner, p as Board, ee as BulkActions, e as Button, m as Calendar, te as CalendarMonth, h as Checkbox, ne as Chip, U as Collapsible, re as ConfirmDialog, g as ContextMenu, _ as DataList, y as Dialog, b as DropdownMenu, V as Editable, x as EmptyState, S as ErrorSummary, ie as Field, k as FilterChip, ae as FilterFieldPicker, A as FilterMenu, oe as FormErrors, M as FormField, r as Icon, se as ImageInput, N as ImageUpload, ce as InlineField, le as InlineForm, C as Input, P as Kbd, ue as LedgerMore, de as LedgerRow, fe as List, pe as Modal, me as OptionsMenu, F as Pagination, he as Pill, I as Popover, H as PropertyList, W as PropertyRow, G as Radio, w as SegmentedControl, z as Select, f as Skeleton, ge as SortControl, j as SortMenu, L as Spinner, K as Table, R as Tag, _e as TextInput, B as Textarea, J as Toaster, i as Tooltip, ve as TypingDots, Y as TypingIndicator, T as datePresets, E as describeFilter, D as filterOperators, l as hueFor, t as iconNames, X as initColorMode, v as saveHint, n as setIconResolver, O as sortDirections, q as toast, Z as useColorMode, s as useConfirm, Q as useForceLightMode };
34
+ import L from "./components/Popover/PopoverDialog.js";
35
+ import R from "./components/Spinner/Spinner.js";
36
+ import z from "./components/Tag/Tag.js";
37
+ import B from "./components/Select/Select.js";
38
+ import V from "./components/Textarea/Textarea.js";
39
+ import H from "./components/PropertyList/Editable.js";
40
+ import U from "./components/PropertyList/PropertyList.js";
41
+ import W from "./components/PropertyRow/Collapsible.js";
42
+ import G from "./components/PropertyRow/PropertyRow.js";
43
+ import K from "./components/Radio/Radio.js";
44
+ import q from "./components/Table/Table.js";
45
+ import { toast as J } from "./composables/toast.js";
46
+ import Y from "./components/Toast/Toaster.js";
47
+ import X from "./components/Toolbar/Toolbar.js";
48
+ import Z from "./components/TypingIndicator/TypingIndicator.js";
49
+ import { initColorMode as Q, useColorMode as $, useForceLightMode as ee } from "./composables/useColorMode.js";
50
+ import { Banner as te, BulkActions as ne, CalendarMonth as re, Chip as ie, ConfirmDialog as ae, Field as oe, FilterFieldPicker as se, FormErrors as ce, ImageInput as le, InlineField as ue, InlineForm as de, LedgerMore as fe, LedgerRow as pe, List as me, Modal as he, OptionsMenu as ge, Pill as _e, SortControl as ve, TextInput as ye, TypingDots as be } from "./aliases.js";
51
+ export { a as ActionBar, o as Alert, c as AlertDialog, u as Avatar, d as Badge, te as Banner, p as Board, ne as BulkActions, e as Button, m as Calendar, re as CalendarMonth, h as Checkbox, ie as Chip, W as Collapsible, ae as ConfirmDialog, g as ContextMenu, _ as DataList, y as Dialog, b as DropdownMenu, H as Editable, x as EmptyState, S as ErrorSummary, oe as Field, k as FilterChip, se as FilterFieldPicker, A as FilterMenu, ce as FormErrors, M as FormField, r as Icon, le as ImageInput, N as ImageUpload, ue as InlineField, de as InlineForm, C as Input, P as Kbd, fe as LedgerMore, pe as LedgerRow, me as List, he as Modal, ge as OptionsMenu, F as Pagination, _e as Pill, I as Popover, L as PopoverDialog, U as PropertyList, G as PropertyRow, K as Radio, w as SegmentedControl, B as Select, f as Skeleton, ve as SortControl, j as SortMenu, R as Spinner, q as Table, z as Tag, ye as TextInput, V as Textarea, Y as Toaster, X as Toolbar, i as Tooltip, be as TypingDots, Z as TypingIndicator, T as datePresets, E as describeFilter, D as filterOperators, l as hueFor, t as iconNames, Q as initColorMode, v as saveHint, n as setIconResolver, O as sortDirections, J as toast, $ as useColorMode, s as useConfirm, ee as useForceLightMode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparklingopinions/sparkling-ui",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "A product-agnostic Vue 3 component library, themed by semantic tokens",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -298,6 +298,19 @@
298
298
  --sui-radius-sheet: 1.25rem;
299
299
  /* Table rows and headers at one height, e.g. 44px; unset (initial), each Table's size decides. */
300
300
  --sui-table-row: initial;
301
+ /* The header row's own height, e.g. 36px over 44px rows; unset, it follows the rows. */
302
+ --sui-table-header: initial;
303
+ /* DataList rows and group headers at set heights, e.g. 44px and 40px; unset, 40px and 36px. */
304
+ --sui-list-row: initial;
305
+ --sui-list-header: initial;
306
+ /* Live toasts: their width, their gap to the viewport's edges, and insets an app sets to keep them clear of its own
307
+ chrome (a sidebar, a tab bar), per route or breakpoint. The safe area is added on top. */
308
+ --sui-toaster-width: 24rem;
309
+ --sui-toaster-margin: 1.25rem;
310
+ --sui-toaster-inset-top: 0px;
311
+ --sui-toaster-inset-right: 0px;
312
+ --sui-toaster-inset-bottom: 0px;
313
+ --sui-toaster-inset-left: 0px;
301
314
  --sui-shadow-raised: 0 1px 2px 0 rgb(0 0 0 / 0.05);
302
315
  --sui-focus-width: 2px;
303
316
  --sui-focus-offset: 2px;
@@ -364,9 +377,11 @@
364
377
  --animate-sui-sheet-in: sui-sheet-in 300ms cubic-bezier(0.32, 0.72, 0, 1);
365
378
  --animate-sui-sheet-out: sui-sheet-out 200ms cubic-bezier(0.4, 0, 1, 1) forwards;
366
379
  --animate-sui-toast-in: sui-toast-in 300ms cubic-bezier(0.4, 0, 0.2, 1);
380
+ --animate-sui-toast-in-top: sui-toast-in-top 300ms cubic-bezier(0.4, 0, 0.2, 1);
367
381
  --animate-sui-toast-out:
368
382
  sui-toast-collapse 450ms cubic-bezier(0, 1, 0, 1) forwards,
369
383
  sui-toast-fade 300ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
384
+ --animate-sui-toast-fade: sui-toast-fade 200ms linear forwards;
370
385
  /* Its duration is the toast's life, set inline. */
371
386
  --animate-sui-toast-timer: sui-toast-timer linear forwards;
372
387
 
@@ -457,6 +472,13 @@
457
472
  }
458
473
  }
459
474
 
475
+ @keyframes sui-toast-in-top {
476
+ from {
477
+ opacity: 0;
478
+ transform: translateY(-50%);
479
+ }
480
+ }
481
+
460
482
  @keyframes sui-toast-collapse {
461
483
  from {
462
484
  max-height: 1000px;