@alfakit/vue 0.1.8 → 0.1.10

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 (168) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/app/components.d.ts.map +1 -1
  3. package/dist/app/components.js +1 -0
  4. package/dist/app/components.js.map +1 -1
  5. package/dist/components/actions/ActionModal.js.map +1 -1
  6. package/dist/components/actions/ActionModal.vue.d.ts.map +1 -1
  7. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js +1 -1
  8. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/dev-tools/DevToolsInspector.js.map +1 -1
  10. package/dist/components/dev-tools/DevToolsInspector.vue.d.ts.map +1 -1
  11. package/dist/components/dev-tools/DevToolsInspector.vue_vue_type_script_setup_true_lang.js +1 -1
  12. package/dist/components/dev-tools/DevToolsInspector.vue_vue_type_script_setup_true_lang.js.map +1 -1
  13. package/dist/components/fields/CheckboxListField.js.map +1 -1
  14. package/dist/components/fields/CheckboxListField.vue.d.ts.map +1 -1
  15. package/dist/components/fields/CheckboxListField.vue_vue_type_script_setup_true_lang.js +2 -2
  16. package/dist/components/fields/CheckboxListField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/components/fields/DatePickerField.js.map +1 -1
  18. package/dist/components/fields/DatePickerField.vue.d.ts.map +1 -1
  19. package/dist/components/fields/DatePickerField.vue_vue_type_script_setup_true_lang.js +34 -32
  20. package/dist/components/fields/DatePickerField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/fields/RichEditorSuggestions.js.map +1 -1
  22. package/dist/components/fields/RichEditorSuggestions.vue.d.ts +1 -1
  23. package/dist/components/fields/RichEditorSuggestions.vue.d.ts.map +1 -1
  24. package/dist/components/fields/RichEditorSuggestions.vue_vue_type_script_setup_true_lang.js +29 -23
  25. package/dist/components/fields/RichEditorSuggestions.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/fields/RichEditorToolbarGroup.js.map +1 -1
  27. package/dist/components/fields/RichEditorToolbarGroup.vue.d.ts.map +1 -1
  28. package/dist/components/fields/RichEditorToolbarGroup.vue_vue_type_script_setup_true_lang.js +9 -4
  29. package/dist/components/fields/RichEditorToolbarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/file-manager/FileManagerView.js.map +1 -1
  31. package/dist/components/file-manager/FileManagerView.vue.d.ts.map +1 -1
  32. package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js +5 -1
  33. package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/form/FormBlock.js.map +1 -1
  35. package/dist/components/form/FormBlock.vue.d.ts.map +1 -1
  36. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js +79 -78
  37. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/components/layout/CalloutComponent.js.map +1 -1
  39. package/dist/components/layout/CalloutComponent.vue.d.ts.map +1 -1
  40. package/dist/components/layout/CalloutComponent.vue_vue_type_script_setup_true_lang.js +43 -39
  41. package/dist/components/layout/CalloutComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/layout/EmptyStateComponent.js.map +1 -1
  43. package/dist/components/layout/EmptyStateComponent.vue.d.ts.map +1 -1
  44. package/dist/components/layout/EmptyStateComponent.vue_vue_type_script_setup_true_lang.js +29 -26
  45. package/dist/components/layout/EmptyStateComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/components/layout/MixedContent.js.map +1 -1
  47. package/dist/components/layout/MixedContent.vue.d.ts +5 -3
  48. package/dist/components/layout/MixedContent.vue.d.ts.map +1 -1
  49. package/dist/components/layout/MixedContent.vue_vue_type_script_setup_true_lang.js +5 -4
  50. package/dist/components/layout/MixedContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/layout/SectionComponent.js.map +1 -1
  52. package/dist/components/layout/SectionComponent.vue.d.ts.map +1 -1
  53. package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js +12 -8
  54. package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/components/notifications/NotificationsMenu.js.map +1 -1
  56. package/dist/components/notifications/NotificationsMenu.vue.d.ts.map +1 -1
  57. package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js +133 -104
  58. package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  59. package/dist/components/panel/BottomNav.js.map +1 -1
  60. package/dist/components/panel/BottomNav.vue_vue_type_script_setup_true_lang.js +2 -2
  61. package/dist/components/panel/BottomNav.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/panel/KeyboardShortcuts.js.map +1 -1
  63. package/dist/components/panel/KeyboardShortcuts.vue_vue_type_script_setup_true_lang.js +1 -1
  64. package/dist/components/panel/KeyboardShortcuts.vue_vue_type_script_setup_true_lang.js.map +1 -1
  65. package/dist/components/panel/NavGroup.js.map +1 -1
  66. package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js +3 -3
  67. package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/panel/NavItem.js.map +1 -1
  69. package/dist/components/panel/NavItem.vue.d.ts.map +1 -1
  70. package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js +1 -1
  71. package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/panel/NavSubItem.js.map +1 -1
  73. package/dist/components/panel/NavSubItem.vue.d.ts.map +1 -1
  74. package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js +1 -1
  75. package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  76. package/dist/components/panel/ShortcutsOverlay.js.map +1 -1
  77. package/dist/components/panel/ShortcutsOverlay.vue.d.ts.map +1 -1
  78. package/dist/components/panel/ShortcutsOverlay.vue_vue_type_script_setup_true_lang.js +20 -19
  79. package/dist/components/panel/ShortcutsOverlay.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/table/ColumnManager.js.map +1 -1
  81. package/dist/components/table/ColumnManager.vue.d.ts.map +1 -1
  82. package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js +6 -6
  83. package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/components/table/Spreadsheet.js.map +1 -1
  85. package/dist/components/table/Spreadsheet.vue.d.ts.map +1 -1
  86. package/dist/components/table/Spreadsheet.vue_vue_type_script_setup_true_lang.js +37 -33
  87. package/dist/components/table/Spreadsheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/translation-manager/TranslationManagerView.js.map +1 -1
  89. package/dist/components/translation-manager/TranslationManagerView.vue.d.ts.map +1 -1
  90. package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js +1 -1
  91. package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  92. package/dist/components/ui/SidebarMenuButton.js.map +1 -1
  93. package/dist/components/ui/SidebarMenuButton.vue.d.ts.map +1 -1
  94. package/dist/components/ui/SidebarMenuButton.vue_vue_type_script_setup_true_lang.js +12 -12
  95. package/dist/components/ui/SidebarMenuButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  96. package/dist/components/ui/TooltipTrigger.js.map +1 -1
  97. package/dist/components/ui/TooltipTrigger.vue.d.ts +2 -2
  98. package/dist/components/ui/TooltipTrigger.vue.d.ts.map +1 -1
  99. package/dist/components/ui/TooltipTrigger.vue_vue_type_script_setup_true_lang.js +10 -7
  100. package/dist/components/ui/TooltipTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
  101. package/dist/components/widgets/StatCard.js.map +1 -1
  102. package/dist/components/widgets/StatCard.vue.d.ts.map +1 -1
  103. package/dist/components/widgets/StatCard.vue_vue_type_script_setup_true_lang.js +30 -30
  104. package/dist/components/widgets/StatCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/eject-manifest.json +2 -2
  106. package/dist/layouts/TopNavLayout.js.map +1 -1
  107. package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js +2 -2
  108. package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
  109. package/dist/layouts/TopNavMenu.js.map +1 -1
  110. package/dist/layouts/TopNavMenu.vue_vue_type_script_setup_true_lang.js +1 -1
  111. package/dist/layouts/TopNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/pages/AlfakitPage.js.map +1 -1
  113. package/dist/pages/AlfakitPage.vue.d.ts.map +1 -1
  114. package/dist/pages/AlfakitPage.vue_vue_type_script_setup_true_lang.js +16 -19
  115. package/dist/pages/AlfakitPage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  116. package/dist/standalone/AlfakitComponent.js.map +1 -1
  117. package/dist/standalone/AlfakitComponent.vue.d.ts.map +1 -1
  118. package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js +29 -24
  119. package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/standalone/runtime.d.ts.map +1 -1
  121. package/dist/standalone/runtime.js +25 -25
  122. package/dist/standalone/runtime.js.map +1 -1
  123. package/dist/standalone.css +12 -7
  124. package/dist/starter-kit/AlfakitStarterKitRoot.js.map +1 -1
  125. package/dist/starter-kit/AlfakitStarterKitRoot.vue.d.ts.map +1 -1
  126. package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js +25 -21
  127. package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  128. package/dist/starter-kit/navigation.d.ts +6 -1
  129. package/dist/starter-kit/navigation.d.ts.map +1 -1
  130. package/dist/starter-kit/navigation.js +11 -10
  131. package/dist/starter-kit/navigation.js.map +1 -1
  132. package/dist/styles.css +2 -1
  133. package/dist/themes.css +4 -0
  134. package/package.json +2 -2
  135. package/src/app/components.ts +3 -0
  136. package/src/components/actions/ActionModal.vue +2 -0
  137. package/src/components/dev-tools/DevToolsInspector.vue +1 -1
  138. package/src/components/fields/CheckboxListField.vue +2 -2
  139. package/src/components/fields/DatePickerField.vue +1 -0
  140. package/src/components/fields/RichEditorSuggestions.vue +13 -6
  141. package/src/components/fields/RichEditorToolbarGroup.vue +16 -1
  142. package/src/components/file-manager/FileManagerView.vue +3 -1
  143. package/src/components/form/FormBlock.vue +15 -2
  144. package/src/components/layout/CalloutComponent.vue +15 -2
  145. package/src/components/layout/EmptyStateComponent.vue +10 -1
  146. package/src/components/layout/MixedContent.vue +12 -4
  147. package/src/components/layout/SectionComponent.vue +20 -4
  148. package/src/components/notifications/NotificationsMenu.vue +45 -1
  149. package/src/components/panel/BottomNav.vue +2 -2
  150. package/src/components/panel/KeyboardShortcuts.vue +1 -1
  151. package/src/components/panel/NavGroup.vue +3 -3
  152. package/src/components/panel/NavItem.vue +5 -1
  153. package/src/components/panel/NavSubItem.vue +5 -1
  154. package/src/components/panel/ShortcutsOverlay.vue +27 -22
  155. package/src/components/table/ColumnManager.vue +6 -4
  156. package/src/components/table/Spreadsheet.vue +9 -4
  157. package/src/components/translation-manager/TranslationManagerView.vue +1 -1
  158. package/src/components/ui/SidebarMenuButton.vue +6 -0
  159. package/src/components/ui/TooltipTrigger.vue +4 -1
  160. package/src/components/widgets/StatCard.vue +6 -3
  161. package/src/layouts/TopNavLayout.vue +2 -2
  162. package/src/layouts/TopNavMenu.vue +1 -1
  163. package/src/pages/AlfakitPage.vue +13 -3
  164. package/src/standalone/AlfakitComponent.vue +16 -5
  165. package/src/standalone/runtime.ts +3 -0
  166. package/src/starter-kit/AlfakitStarterKitRoot.vue +7 -0
  167. package/src/starter-kit/navigation.ts +12 -1
  168. package/src/styles.css +2 -1
@@ -1,52 +1,53 @@
1
- import { useDirection as e, useFormatter as t, usePanel as ee, useT as te } from "../../context.js";
2
- import { cn as n } from "../../lib/utils.js";
3
- import { useStore as ne } from "../../composables/use-store.js";
4
- import { cssColor as r, textColorClasses as i } from "../../lib/colors.js";
5
- import a from "../../lib/Icon.js";
6
- import o from "../ui/Button2.js";
7
- import s from "../ui/Spinner.js";
8
- import re from "./NotificationActionButton.js";
9
- import c from "../ui/Popover.js";
10
- import l from "../ui/PopoverContent.js";
11
- import u from "../ui/PopoverTrigger.js";
12
- import d from "../ui/ScrollArea.js";
13
- import { NotificationCenter as f, notificationTintStyles as ie, onDatabaseNotificationsSent as ae, onOpenDatabaseNotifications as oe } from "@alfakit/core";
14
- import { Fragment as p, computed as se, createBlock as m, createCommentVNode as h, createElementBlock as g, createElementVNode as _, createTextVNode as v, createVNode as y, defineComponent as b, normalizeClass as x, normalizeStyle as ce, onMounted as S, onScopeDispose as C, openBlock as w, ref as le, renderList as T, toDisplayString as E, unref as D, watch as O, withCtx as k } from "vue";
15
- import { BellIcon as A, CheckCheckIcon as j, Trash2Icon as M } from "@lucide/vue";
1
+ import { useDirection as e, useFormatter as t, usePanel as ee, useT as n } from "../../context.js";
2
+ import { cn as r } from "../../lib/utils.js";
3
+ import { useStore as i } from "../../composables/use-store.js";
4
+ import { cssColor as a, textColorClasses as te } from "../../lib/colors.js";
5
+ import o from "../../lib/Icon.js";
6
+ import s from "../ui/Button2.js";
7
+ import c from "../ui/Spinner.js";
8
+ import ne from "./NotificationActionButton.js";
9
+ import re from "../ui/Popover.js";
10
+ import ie from "../ui/PopoverContent.js";
11
+ import l from "../ui/PopoverTrigger.js";
12
+ import u from "../ui/ScrollArea.js";
13
+ import { NotificationCenter as d, notificationTintStyles as ae, onDatabaseNotificationsSent as oe, onOpenDatabaseNotifications as se, pwaStore as ce, startPwa as le, togglePushNotifications as ue } from "@alfakit/core";
14
+ import { Fragment as f, computed as p, createBlock as m, createCommentVNode as h, createElementBlock as g, createElementVNode as _, createTextVNode as v, createVNode as y, defineComponent as b, normalizeClass as x, normalizeStyle as S, onMounted as C, onScopeDispose as w, openBlock as T, ref as de, renderList as E, toDisplayString as D, unref as O, watch as k, withCtx as A } from "vue";
15
+ import { BellIcon as j, BellOffIcon as M, BellRingIcon as N, CheckCheckIcon as P, Trash2Icon as F } from "@lucide/vue";
16
+ import { toast as I } from "vue-sonner";
16
17
  //#region src/components/notifications/NotificationsMenu.vue?vue&type=script&setup=true&lang.ts
17
- var N = { class: "flex-1 text-start group-data-[collapsible=icon]:sr-only" }, P = {
18
+ var L = { class: "flex-1 text-start group-data-[collapsible=icon]:sr-only" }, R = {
18
19
  key: 0,
19
20
  class: "bg-primary text-primary-foreground flex h-5 min-w-5 items-center justify-center rounded-full px-1 text-xs font-medium group-data-[collapsible=icon]:absolute group-data-[collapsible=icon]:-end-1 group-data-[collapsible=icon]:-top-1 group-data-[collapsible=icon]:h-4 group-data-[collapsible=icon]:min-w-4 group-data-[collapsible=icon]:text-[10px]"
20
- }, F = { class: "sr-only" }, I = {
21
+ }, z = { class: "sr-only" }, B = {
21
22
  key: 0,
22
23
  class: "bg-primary text-primary-foreground absolute -end-0.5 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-medium"
23
- }, L = { class: "flex items-center justify-between border-b px-3 py-2" }, R = { class: "text-sm font-semibold" }, z = { class: "flex items-center gap-1" }, B = {
24
+ }, V = { class: "flex items-center justify-between border-b px-3 py-2" }, H = { class: "text-sm font-semibold" }, fe = { class: "flex items-center gap-1" }, pe = {
24
25
  key: 0,
25
26
  class: "flex justify-center py-8"
26
- }, ue = {
27
+ }, me = {
27
28
  key: 1,
28
29
  class: "text-muted-foreground px-3 py-8 text-center text-sm"
29
- }, V = {
30
+ }, he = {
30
31
  key: 2,
31
32
  class: "divide-y"
32
- }, H = { class: "flex min-w-0 flex-1 flex-col gap-1" }, U = { class: "flex items-start justify-between gap-2" }, de = { class: "text-sm font-medium" }, fe = ["aria-label", "onClick"], pe = ["innerHTML"], me = {
33
+ }, ge = { class: "flex min-w-0 flex-1 flex-col gap-1" }, _e = { class: "flex items-start justify-between gap-2" }, ve = { class: "text-sm font-medium" }, ye = ["aria-label", "onClick"], be = ["innerHTML"], xe = {
33
34
  key: 1,
34
35
  class: "text-muted-foreground text-xs"
35
- }, he = {
36
+ }, Se = {
36
37
  key: 2,
37
38
  class: "flex flex-wrap gap-1"
38
- }, ge = {
39
+ }, Ce = {
39
40
  key: 3,
40
41
  class: "flex justify-center border-t p-2"
41
- }, W = /*@__PURE__*/ b({
42
+ }, U = /*@__PURE__*/ b({
42
43
  __name: "NotificationsMenu",
43
44
  props: { variant: { default: "topbar" } },
44
45
  setup(b) {
45
- let W = b, G = te(), _e = e(), K = ee(), q = se(() => K.value.databaseNotifications), J = K.value.endpoints, Y = J.notifications && J.notificationsReadAll && J.notificationsDestroyAll ? new f({
46
- notifications: J.notifications,
47
- notificationsReadAll: J.notificationsReadAll,
48
- notificationsDestroyAll: J.notificationsDestroyAll
49
- }, q.value?.unreadCount ?? 0) : null, X = le(!1), Z = ne(Y?.store ?? {
46
+ let U = b, W = n(), we = e(), G = ee(), K = p(() => G.value.databaseNotifications), q = G.value.endpoints, J = q.notifications && q.notificationsReadAll && q.notificationsDestroyAll ? new d({
47
+ notifications: q.notifications,
48
+ notificationsReadAll: q.notificationsReadAll,
49
+ notificationsDestroyAll: q.notificationsDestroyAll
50
+ }, K.value?.unreadCount ?? 0) : null, Y = de(!1), X = i(J?.store ?? {
50
51
  get: () => ({
51
52
  notifications: [],
52
53
  unreadCount: 0,
@@ -56,29 +57,36 @@ var N = { class: "flex-1 text-start group-data-[collapsible=icon]:sr-only" }, P
56
57
  }),
57
58
  subscribe: () => () => {}
58
59
  });
59
- S(() => {
60
- O(() => q.value?.pollingInterval, (e) => Y?.startPolling(e), { immediate: !0 });
61
- }), O(X, (e) => {
62
- e && Y?.load();
63
- }), O(() => q.value?.unreadCount, (e) => {
64
- Y && typeof e == "number" && e !== Y.store.get().unreadCount && Y.store.update({ unreadCount: e });
60
+ C(() => {
61
+ k(() => K.value?.pollingInterval, (e) => J?.startPolling(e), { immediate: !0 });
62
+ }), k(Y, (e) => {
63
+ e && J?.load();
64
+ }), k(() => K.value?.unreadCount, (e) => {
65
+ J && typeof e == "number" && e !== J.store.get().unreadCount && J.store.update({ unreadCount: e });
65
66
  });
67
+ let Z = null;
68
+ C(() => {
69
+ Z = J ? oe(() => void J.load()) : null;
70
+ }), w(() => Z?.());
66
71
  let Q = null;
67
- S(() => {
68
- Q = Y ? ae(() => void Y.load()) : null;
69
- }), C(() => Q?.());
70
- let $ = null;
71
- S(() => {
72
- $ = oe(() => X.value = !0);
73
- }), C(() => $?.()), C(() => Y?.stopPolling());
74
- let ve = t();
75
- return (e, t) => q.value && D(Y) ? (w(), m(c, {
72
+ C(() => {
73
+ Q = se(() => Y.value = !0);
74
+ }), w(() => Q?.()), w(() => J?.stopPolling());
75
+ let Te = t(), $ = i(ce), Ee = p(() => !!(G.value.starterKit && G.value.pwa?.push) && $.value.push !== "unsupported");
76
+ C(() => {
77
+ G.value.starterKit && G.value.pwa?.push && le(G.value.pwa);
78
+ });
79
+ async function De() {
80
+ let { message: e } = await ue(), t = W(e.key, {}, e.fallback);
81
+ e.error ? I.error(t) : I.success(t);
82
+ }
83
+ return (e, t) => K.value && O(J) ? (T(), m(re, {
76
84
  key: 0,
77
- open: X.value,
78
- "onUpdate:open": t[3] ||= (e) => X.value = e
85
+ open: Y.value,
86
+ "onUpdate:open": t[4] ||= (e) => Y.value = e
79
87
  }, {
80
- default: k(() => [y(u, { "as-child": "" }, {
81
- default: k(() => [W.variant === "sidebar" ? (w(), m(o, {
88
+ default: A(() => [y(l, { "as-child": "" }, {
89
+ default: A(() => [U.variant === "sidebar" ? (T(), m(s, {
82
90
  key: 0,
83
91
  type: "button",
84
92
  variant: "ghost",
@@ -86,100 +94,121 @@ var N = { class: "flex-1 text-start group-data-[collapsible=icon]:sr-only" }, P
86
94
  "data-slot": "notifications-trigger",
87
95
  "data-variant": "sidebar"
88
96
  }, {
89
- default: k(() => [
90
- y(D(a), {
97
+ default: A(() => [
98
+ y(O(o), {
91
99
  name: "alfakit::panels.topbar.open-database-notifications-button",
92
- fallback: D(A)
100
+ fallback: O(j)
93
101
  }, null, 8, ["fallback"]),
94
- _("span", N, E(D(G)("notifications", {}, "Notifications")), 1),
95
- D(Z).unreadCount > 0 ? (w(), g("span", P, [v(E(D(Z).unreadCount > 99 ? "99+" : D(Z).unreadCount) + " ", 1), _("span", F, E(D(G)("unread_notifications", {}, "unread")), 1)])) : h("", !0)
102
+ _("span", L, D(O(W)("notifications", {}, "Notifications")), 1),
103
+ O(X).unreadCount > 0 ? (T(), g("span", R, [v(D(O(X).unreadCount > 99 ? "99+" : O(X).unreadCount) + " ", 1), _("span", z, D(O(W)("unread_notifications", {}, "unread")), 1)])) : h("", !0)
96
104
  ]),
97
105
  _: 1
98
- })) : (w(), m(o, {
106
+ })) : (T(), m(s, {
99
107
  key: 1,
100
108
  type: "button",
101
109
  variant: "ghost",
102
110
  size: "icon",
103
111
  class: "relative",
104
112
  "data-slot": "notifications-trigger",
105
- "aria-label": D(G)("notifications", {}, "Notifications")
113
+ "aria-label": O(W)("notifications", {}, "Notifications")
106
114
  }, {
107
- default: k(() => [y(D(a), {
115
+ default: A(() => [y(O(o), {
108
116
  name: "alfakit::panels.topbar.open-database-notifications-button",
109
- fallback: D(A)
110
- }, null, 8, ["fallback"]), D(Z).unreadCount > 0 ? (w(), g("span", I, E(D(Z).unreadCount > 99 ? "99+" : D(Z).unreadCount), 1)) : h("", !0)]),
117
+ fallback: O(j)
118
+ }, null, 8, ["fallback"]), O(X).unreadCount > 0 ? (T(), g("span", B, D(O(X).unreadCount > 99 ? "99+" : O(X).unreadCount), 1)) : h("", !0)]),
111
119
  _: 1
112
120
  }, 8, ["aria-label"]))]),
113
121
  _: 1
114
- }), y(l, {
115
- align: W.variant === "sidebar" ? "start" : "end",
116
- side: W.variant === "sidebar" ? D(_e) === "rtl" ? "left" : "right" : "bottom",
122
+ }), y(ie, {
123
+ align: U.variant === "sidebar" ? "start" : "end",
124
+ side: U.variant === "sidebar" ? O(we) === "rtl" ? "left" : "right" : "bottom",
117
125
  class: "w-80 p-0 sm:w-96"
118
126
  }, {
119
- default: k(() => [_("div", L, [_("span", R, E(D(G)("notifications", {}, "Notifications")), 1), _("div", z, [D(Z).unreadCount > 0 ? (w(), m(o, {
120
- key: 0,
121
- type: "button",
122
- variant: "ghost",
123
- size: "icon-sm",
124
- title: D(G)("mark_all_read", {}, "Mark all as read"),
125
- onClick: t[0] ||= (e) => void D(Y).markAllAsRead()
126
- }, {
127
- default: k(() => [y(D(j))]),
128
- _: 1
129
- }, 8, ["title"])) : h("", !0), D(Z).notifications.length > 0 ? (w(), m(o, {
130
- key: 1,
131
- type: "button",
132
- variant: "ghost",
133
- size: "icon-sm",
134
- title: D(G)("clear_notifications", {}, "Clear notifications"),
135
- onClick: t[1] ||= (e) => void D(Y).clear()
136
- }, {
137
- default: k(() => [y(D(M))]),
138
- _: 1
139
- }, 8, ["title"])) : h("", !0)])]), y(d, { class: "max-h-96" }, {
140
- default: k(() => [D(Z).loading && D(Z).notifications.length === 0 ? (w(), g("div", B, [y(s)])) : D(Z).notifications.length === 0 ? (w(), g("p", ue, E(D(G)("no_notifications", {}, "You have no notifications.")), 1)) : (w(), g("ul", V, [(w(!0), g(p, null, T(D(Z).notifications, (e) => (w(), g("li", {
127
+ default: A(() => [_("div", V, [_("span", H, D(O(W)("notifications", {}, "Notifications")), 1), _("div", fe, [
128
+ Ee.value ? (T(), m(s, {
129
+ key: 0,
130
+ type: "button",
131
+ variant: "ghost",
132
+ size: "icon-sm",
133
+ "data-slot": "pwa-push",
134
+ disabled: O($).pushBusy || O($).push === "denied",
135
+ title: O($).push === "subscribed" ? O(W)("pwa.notifications.disable", {}, "Turn off notifications") : O(W)("pwa.notifications.enable", {}, "Turn on notifications"),
136
+ "aria-label": O($).push === "subscribed" ? O(W)("pwa.notifications.disable", {}, "Turn off notifications") : O(W)("pwa.notifications.enable", {}, "Turn on notifications"),
137
+ onClick: t[0] ||= (e) => void De()
138
+ }, {
139
+ default: A(() => [O($).push === "subscribed" ? (T(), m(O(M), { key: 0 })) : (T(), m(O(N), { key: 1 }))]),
140
+ _: 1
141
+ }, 8, [
142
+ "disabled",
143
+ "title",
144
+ "aria-label"
145
+ ])) : h("", !0),
146
+ O(X).unreadCount > 0 ? (T(), m(s, {
147
+ key: 1,
148
+ type: "button",
149
+ variant: "ghost",
150
+ size: "icon-sm",
151
+ title: O(W)("mark_all_read", {}, "Mark all as read"),
152
+ onClick: t[1] ||= (e) => void O(J).markAllAsRead()
153
+ }, {
154
+ default: A(() => [y(O(P))]),
155
+ _: 1
156
+ }, 8, ["title"])) : h("", !0),
157
+ O(X).notifications.length > 0 ? (T(), m(s, {
158
+ key: 2,
159
+ type: "button",
160
+ variant: "ghost",
161
+ size: "icon-sm",
162
+ title: O(W)("clear_notifications", {}, "Clear notifications"),
163
+ onClick: t[2] ||= (e) => void O(J).clear()
164
+ }, {
165
+ default: A(() => [y(O(F))]),
166
+ _: 1
167
+ }, 8, ["title"])) : h("", !0)
168
+ ])]), y(u, { class: "max-h-96" }, {
169
+ default: A(() => [O(X).loading && O(X).notifications.length === 0 ? (T(), g("div", pe, [y(c)])) : O(X).notifications.length === 0 ? (T(), g("p", me, D(O(W)("no_notifications", {}, "You have no notifications.")), 1)) : (T(), g("ul", he, [(T(!0), g(f, null, E(O(X).notifications, (e) => (T(), g("li", {
141
170
  key: e.id,
142
- class: x(D(n)("flex gap-3 px-3 py-3", !e.readAt && "bg-primary/5")),
143
- style: ce(e.color ? D(ie)(D(r)(e.color)).item : void 0)
144
- }, [e.icon ? (w(), m(D(a), {
171
+ class: x(O(r)("flex gap-3 px-3 py-3", !e.readAt && "bg-primary/5")),
172
+ style: S(e.color ? O(ae)(O(a)(e.color)).item : void 0)
173
+ }, [e.icon ? (T(), m(O(o), {
145
174
  key: 0,
146
175
  name: e.icon,
147
- class: x(D(n)("mt-0.5 size-5 shrink-0", e.iconColor && D(i)[e.iconColor]))
148
- }, null, 8, ["name", "class"])) : h("", !0), _("div", H, [
149
- _("div", U, [_("p", de, E(e.title), 1), e.readAt ? h("", !0) : (w(), g("button", {
176
+ class: x(O(r)("mt-0.5 size-5 shrink-0", e.iconColor && O(te)[e.iconColor]))
177
+ }, null, 8, ["name", "class"])) : h("", !0), _("div", ge, [
178
+ _("div", _e, [_("p", ve, D(e.title), 1), e.readAt ? h("", !0) : (T(), g("button", {
150
179
  key: 0,
151
180
  type: "button",
152
181
  class: "focus-visible:ring-ring/50 -me-2 -mt-0.5 flex size-6 shrink-0 items-center justify-center rounded-full outline-none focus-visible:ring-[3px]",
153
- "aria-label": D(G)("mark_as_read", {}, "Mark as read"),
154
- onClick: (t) => void D(Y).markAsRead(e.id)
155
- }, [...t[4] ||= [_("span", {
182
+ "aria-label": O(W)("mark_as_read", {}, "Mark as read"),
183
+ onClick: (t) => void O(J).markAsRead(e.id)
184
+ }, [...t[5] ||= [_("span", {
156
185
  class: "bg-primary size-2 rounded-full",
157
186
  "aria-hidden": "true"
158
- }, null, -1)]], 8, fe))]),
159
- e.body ? (w(), g("p", {
187
+ }, null, -1)]], 8, ye))]),
188
+ e.body ? (T(), g("p", {
160
189
  key: 0,
161
190
  class: "text-muted-foreground text-sm",
162
191
  innerHTML: e.body
163
- }, null, 8, pe)) : h("", !0),
164
- e.date ? (w(), g("time", me, E(D(ve).relative(e.date)), 1)) : h("", !0),
165
- e.actions ? (w(), g("div", he, [(w(!0), g(p, null, T(e.actions, (t) => (w(), m(re, {
192
+ }, null, 8, be)) : h("", !0),
193
+ e.date ? (T(), g("time", xe, D(O(Te).relative(e.date)), 1)) : h("", !0),
194
+ e.actions ? (T(), g("div", Se, [(T(!0), g(f, null, E(e.actions, (t) => (T(), m(ne, {
166
195
  key: t.name,
167
196
  action: t,
168
- "on-mark-as-read": () => void D(Y).markAsRead(e.id),
169
- "on-mark-as-unread": () => void D(Y).markAsUnread(e.id)
197
+ "on-mark-as-read": () => void O(J).markAsRead(e.id),
198
+ "on-mark-as-unread": () => void O(J).markAsUnread(e.id)
170
199
  }, null, 8, [
171
200
  "action",
172
201
  "on-mark-as-read",
173
202
  "on-mark-as-unread"
174
203
  ]))), 128))])) : h("", !0)
175
- ])], 6))), 128))])), D(Z).hasMore && D(Z).notifications.length > 0 ? (w(), g("div", ge, [y(o, {
204
+ ])], 6))), 128))])), O(X).hasMore && O(X).notifications.length > 0 ? (T(), g("div", Ce, [y(s, {
176
205
  type: "button",
177
206
  variant: "ghost",
178
207
  size: "sm",
179
- disabled: D(Z).loading,
180
- onClick: t[2] ||= (e) => void D(Y).loadMore()
208
+ disabled: O(X).loading,
209
+ onClick: t[3] ||= (e) => void O(J).loadMore()
181
210
  }, {
182
- default: k(() => [D(Z).loading ? (w(), m(s, { key: 0 })) : h("", !0), v(" " + E(D(G)("load_more", {}, "Load more")), 1)]),
211
+ default: A(() => [O(X).loading ? (T(), m(c, { key: 0 })) : h("", !0), v(" " + D(O(W)("load_more", {}, "Load more")), 1)]),
183
212
  _: 1
184
213
  }, 8, ["disabled"])])) : h("", !0)]),
185
214
  _: 1
@@ -191,6 +220,6 @@ var N = { class: "flex-1 text-start group-data-[collapsible=icon]:sr-only" }, P
191
220
  }
192
221
  });
193
222
  //#endregion
194
- export { W as default };
223
+ export { U as default };
195
224
 
196
225
  //# sourceMappingURL=NotificationsMenu.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsMenu.vue_vue_type_script_setup_true_lang.js","names":["_unref","_openBlock","_createBlock","Popover","_withCtx","_createVNode","PopoverTrigger","Button","Icon","_createElementVNode","_toDisplayString","_createElementBlock","_createTextVNode","_createCommentVNode","PopoverContent","ScrollArea","Spinner","_Fragment","_renderList","_normalizeClass","_normalizeStyle","NotificationActionButton","Icon_default","Button_default","Spinner_default","NotificationActionButton_default","Popover_default","PopoverContent_default","PopoverTrigger_default","ScrollArea_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","NotificationsMenu_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","direction","useDirection","panel","usePanel","config","computed","endpoints","center","NotificationCenter","open","ref","state","useStore","onMounted","interval","watch","isOpen","count","stopListening","onDatabaseNotificationsSent","onScopeDispose","stopOpenListener","onOpenDatabaseNotifications","format","useFormatter","unref","openBlock","createBlock","_cache","$event","withCtx","createVNode","BellIcon","createElementVNode","toDisplayString","createElementBlock","createTextVNode","createCommentVNode","CheckCheckIcon","Trash2Icon","Fragment","renderList","notification","normalizeClass","cn","normalizeStyle","notificationTintStyles","cssColor","textColorClasses","action"],"sources":["../../../src/components/notifications/NotificationsMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n NotificationCenter,\n notificationTintStyles,\n onDatabaseNotificationsSent,\n onOpenDatabaseNotifications,\n} from '@alfakit/core'\nimport { BellIcon, CheckCheckIcon, Trash2Icon } from '@lucide/vue'\nimport { computed, onMounted, onScopeDispose, ref, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useDirection, useFormatter, usePanel, useT } from '../../context'\nimport { cssColor, textColorClasses } from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport Button from '../ui/Button.vue'\nimport Popover from '../ui/Popover.vue'\nimport PopoverContent from '../ui/PopoverContent.vue'\nimport PopoverTrigger from '../ui/PopoverTrigger.vue'\nimport ScrollArea from '../ui/ScrollArea.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport NotificationActionButton from './NotificationActionButton.vue'\n\n/**\n * Bell menu for database notifications. It also opens when something calls\n * `openDatabaseNotifications()` (or an action with `->openDatabaseNotifications()`).\n * `variant=\"sidebar\"`: a full-width row with a label, for layouts that put it in the sidebar.\n */\nconst props = withDefaults(defineProps<{ variant?: 'topbar' | 'sidebar' }>(), {\n variant: 'topbar',\n})\nconst t = useT()\nconst direction = useDirection()\nconst panel = usePanel()\nconst config = computed(() => panel.value.databaseNotifications)\nconst endpoints = panel.value.endpoints\n\nconst center =\n endpoints.notifications && endpoints.notificationsReadAll && endpoints.notificationsDestroyAll\n ? new NotificationCenter(\n {\n notifications: endpoints.notifications,\n notificationsReadAll: endpoints.notificationsReadAll,\n notificationsDestroyAll: endpoints.notificationsDestroyAll,\n },\n config.value?.unreadCount ?? 0,\n )\n : null\n\nconst open = ref(false)\nconst state = useStore(\n center?.store ?? {\n get: () => ({ notifications: [], unreadCount: 0, loading: false, hasMore: false, page: 0 }),\n subscribe: () => () => {},\n },\n)\n\n// Polling starts in the browser only: a server render must not leave timers behind.\nonMounted(() => {\n watch(\n () => config.value?.pollingInterval,\n (interval) => center?.startPolling(interval),\n { immediate: true },\n )\n})\n\nwatch(open, (isOpen) => {\n if (isOpen) void center?.load()\n})\n\n// Every visit brings the server's unread count (another user after impersonating, or\n// notifications read in another tab): follow it instead of waiting for the next poll.\nwatch(\n () => config.value?.unreadCount,\n (count) => {\n if (center && typeof count === 'number' && count !== center.store.get().unreadCount) {\n center.store.update({ unreadCount: count })\n }\n },\n)\n\n// Realtime notifications announce stored ones, so the unread count updates right away.\nlet stopListening: (() => void) | null = null\nonMounted(() => {\n stopListening = center ? onDatabaseNotificationsSent(() => void center.load()) : null\n})\nonScopeDispose(() => stopListening?.())\n\n// `openDatabaseNotifications()`: opened from code or an action.\nlet stopOpenListener: (() => void) | null = null\nonMounted(() => {\n stopOpenListener = onOpenDatabaseNotifications(() => (open.value = true))\n})\nonScopeDispose(() => stopOpenListener?.())\n\nonScopeDispose(() => center?.stopPolling())\nconst format = useFormatter()\n</script>\n\n<template>\n <Popover v-if=\"config && center\" :open=\"open\" @update:open=\"open = $event\">\n <PopoverTrigger as-child>\n <Button\n v-if=\"props.variant === 'sidebar'\"\n type=\"button\"\n variant=\"ghost\"\n class=\"relative w-full justify-start gap-2 group-data-[collapsible=icon]:size-8 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0\"\n data-slot=\"notifications-trigger\"\n data-variant=\"sidebar\"\n >\n <!-- In a collapsed (icon) sidebar only the bell and its badge stay visible. -->\n <Icon\n name=\"alfakit::panels.topbar.open-database-notifications-button\"\n :fallback=\"BellIcon\"\n />\n <span class=\"flex-1 text-start group-data-[collapsible=icon]:sr-only\">{{\n t('notifications', {}, 'Notifications')\n }}</span>\n <span\n v-if=\"state.unreadCount > 0\"\n class=\"bg-primary text-primary-foreground flex h-5 min-w-5 items-center justify-center rounded-full px-1 text-xs font-medium group-data-[collapsible=icon]:absolute group-data-[collapsible=icon]:-end-1 group-data-[collapsible=icon]:-top-1 group-data-[collapsible=icon]:h-4 group-data-[collapsible=icon]:min-w-4 group-data-[collapsible=icon]:text-[10px]\"\n >{{ state.unreadCount > 99 ? '99+' : state.unreadCount }}\n <span class=\"sr-only\">{{ t('unread_notifications', {}, 'unread') }}</span></span\n >\n </Button>\n <Button\n v-else\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n class=\"relative\"\n data-slot=\"notifications-trigger\"\n :aria-label=\"t('notifications', {}, 'Notifications')\"\n >\n <Icon\n name=\"alfakit::panels.topbar.open-database-notifications-button\"\n :fallback=\"BellIcon\"\n />\n <span\n v-if=\"state.unreadCount > 0\"\n class=\"bg-primary text-primary-foreground absolute -end-0.5 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-medium\"\n >{{ state.unreadCount > 99 ? '99+' : state.unreadCount }}</span\n >\n </Button>\n </PopoverTrigger>\n <PopoverContent\n :align=\"props.variant === 'sidebar' ? 'start' : 'end'\"\n :side=\"props.variant === 'sidebar' ? (direction === 'rtl' ? 'left' : 'right') : 'bottom'\"\n class=\"w-80 p-0 sm:w-96\"\n >\n <div class=\"flex items-center justify-between border-b px-3 py-2\">\n <span class=\"text-sm font-semibold\">{{ t('notifications', {}, 'Notifications') }}</span>\n <div class=\"flex items-center gap-1\">\n <Button\n v-if=\"state.unreadCount > 0\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n :title=\"t('mark_all_read', {}, 'Mark all as read')\"\n @click=\"void center.markAllAsRead()\"\n ><CheckCheckIcon\n /></Button>\n <Button\n v-if=\"state.notifications.length > 0\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n :title=\"t('clear_notifications', {}, 'Clear notifications')\"\n @click=\"void center.clear()\"\n ><Trash2Icon\n /></Button>\n </div>\n </div>\n <ScrollArea class=\"max-h-96\">\n <div\n v-if=\"state.loading && state.notifications.length === 0\"\n class=\"flex justify-center py-8\"\n >\n <Spinner />\n </div>\n <p\n v-else-if=\"state.notifications.length === 0\"\n class=\"text-muted-foreground px-3 py-8 text-center text-sm\"\n >\n {{ t('no_notifications', {}, 'You have no notifications.') }}\n </p>\n <ul v-else class=\"divide-y\">\n <li\n v-for=\"notification in state.notifications\"\n :key=\"notification.id\"\n :class=\"cn('flex gap-3 px-3 py-3', !notification.readAt && 'bg-primary/5')\"\n :style=\"\n notification.color\n ? notificationTintStyles(cssColor(notification.color)).item\n : undefined\n \"\n >\n <Icon\n v-if=\"notification.icon\"\n :name=\"notification.icon\"\n :class=\"\n cn(\n 'mt-0.5 size-5 shrink-0',\n notification.iconColor && textColorClasses[notification.iconColor],\n )\n \"\n />\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-start justify-between gap-2\">\n <p class=\"text-sm font-medium\">{{ notification.title }}</p>\n <button\n v-if=\"!notification.readAt\"\n type=\"button\"\n class=\"focus-visible:ring-ring/50 -me-2 -mt-0.5 flex size-6 shrink-0 items-center justify-center rounded-full outline-none focus-visible:ring-[3px]\"\n :aria-label=\"t('mark_as_read', {}, 'Mark as read')\"\n @click=\"void center.markAsRead(notification.id)\"\n >\n <span class=\"bg-primary size-2 rounded-full\" aria-hidden=\"true\" />\n </button>\n </div>\n <p\n v-if=\"notification.body\"\n class=\"text-muted-foreground text-sm\"\n v-html=\"notification.body\"\n />\n <time v-if=\"notification.date\" class=\"text-muted-foreground text-xs\">{{\n format.relative(notification.date)\n }}</time>\n <div v-if=\"notification.actions\" class=\"flex flex-wrap gap-1\">\n <NotificationActionButton\n v-for=\"action in notification.actions\"\n :key=\"action.name\"\n :action=\"action\"\n :on-mark-as-read=\"() => void center!.markAsRead(notification.id)\"\n :on-mark-as-unread=\"() => void center!.markAsUnread(notification.id)\"\n />\n </div>\n </div>\n </li>\n </ul>\n <div\n v-if=\"state.hasMore && state.notifications.length > 0\"\n class=\"flex justify-center border-t p-2\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"state.loading\"\n @click=\"void center!.loadMore()\"\n >\n <Spinner v-if=\"state.loading\" />\n {{ t('load_more', {}, 'Load more') }}\n </Button>\n </div>\n </ScrollArea>\n </PopoverContent>\n </Popover>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"NotificationsMenu.vue_vue_type_script_setup_true_lang.js","names":["_unref","_openBlock","_createBlock","Popover","_withCtx","_createVNode","PopoverTrigger","Button","Icon","_createElementVNode","_toDisplayString","_createElementBlock","_createTextVNode","_createCommentVNode","PopoverContent","ScrollArea","Spinner","_Fragment","_renderList","_normalizeClass","_normalizeStyle","NotificationActionButton","Icon_default","Button_default","Spinner_default","NotificationActionButton_default","Popover_default","PopoverContent_default","PopoverTrigger_default","ScrollArea_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","NotificationsMenu_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","direction","useDirection","panel","usePanel","config","computed","endpoints","center","NotificationCenter","open","ref","state","useStore","onMounted","interval","watch","isOpen","count","stopListening","onDatabaseNotificationsSent","onScopeDispose","stopOpenListener","onOpenDatabaseNotifications","format","useFormatter","pwa","pwaStore","pushToggle","startPwa","togglePush","togglePushNotifications","text","message","toast","unref","openBlock","createBlock","_cache","$event","withCtx","createVNode","BellIcon","createElementVNode","toDisplayString","createElementBlock","createTextVNode","createCommentVNode","BellOffIcon","BellRingIcon","CheckCheckIcon","Trash2Icon","Fragment","renderList","notification","normalizeClass","cn","normalizeStyle","notificationTintStyles","cssColor","textColorClasses","action"],"sources":["../../../src/components/notifications/NotificationsMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n NotificationCenter,\n notificationTintStyles,\n onDatabaseNotificationsSent,\n onOpenDatabaseNotifications,\n pwaStore,\n startPwa,\n togglePushNotifications,\n} from '@alfakit/core'\nimport { BellIcon, BellOffIcon, BellRingIcon, CheckCheckIcon, Trash2Icon } from '@lucide/vue'\nimport { computed, onMounted, onScopeDispose, ref, watch } from 'vue'\nimport { toast } from 'vue-sonner'\nimport { useStore } from '../../composables/use-store'\nimport { useDirection, useFormatter, usePanel, useT } from '../../context'\nimport { cssColor, textColorClasses } from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport Button from '../ui/Button.vue'\nimport Popover from '../ui/Popover.vue'\nimport PopoverContent from '../ui/PopoverContent.vue'\nimport PopoverTrigger from '../ui/PopoverTrigger.vue'\nimport ScrollArea from '../ui/ScrollArea.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport NotificationActionButton from './NotificationActionButton.vue'\n\n/**\n * Bell menu for database notifications. It also opens when something calls\n * `openDatabaseNotifications()` (or an action with `->openDatabaseNotifications()`).\n * `variant=\"sidebar\"`: a full-width row with a label, for layouts that put it in the sidebar.\n */\nconst props = withDefaults(defineProps<{ variant?: 'topbar' | 'sidebar' }>(), {\n variant: 'topbar',\n})\nconst t = useT()\nconst direction = useDirection()\nconst panel = usePanel()\nconst config = computed(() => panel.value.databaseNotifications)\nconst endpoints = panel.value.endpoints\n\nconst center =\n endpoints.notifications && endpoints.notificationsReadAll && endpoints.notificationsDestroyAll\n ? new NotificationCenter(\n {\n notifications: endpoints.notifications,\n notificationsReadAll: endpoints.notificationsReadAll,\n notificationsDestroyAll: endpoints.notificationsDestroyAll,\n },\n config.value?.unreadCount ?? 0,\n )\n : null\n\nconst open = ref(false)\nconst state = useStore(\n center?.store ?? {\n get: () => ({ notifications: [], unreadCount: 0, loading: false, hasMore: false, page: 0 }),\n subscribe: () => () => {},\n },\n)\n\n// Polling starts in the browser only: a server render must not leave timers behind.\nonMounted(() => {\n watch(\n () => config.value?.pollingInterval,\n (interval) => center?.startPolling(interval),\n { immediate: true },\n )\n})\n\nwatch(open, (isOpen) => {\n if (isOpen) void center?.load()\n})\n\n// Every visit brings the server's unread count (another user after impersonating, or\n// notifications read in another tab): follow it instead of waiting for the next poll.\nwatch(\n () => config.value?.unreadCount,\n (count) => {\n if (center && typeof count === 'number' && count !== center.store.get().unreadCount) {\n center.store.update({ unreadCount: count })\n }\n },\n)\n\n// Realtime notifications announce stored ones, so the unread count updates right away.\nlet stopListening: (() => void) | null = null\nonMounted(() => {\n stopListening = center ? onDatabaseNotificationsSent(() => void center.load()) : null\n})\nonScopeDispose(() => stopListening?.())\n\n// `openDatabaseNotifications()`: opened from code or an action.\nlet stopOpenListener: (() => void) | null = null\nonMounted(() => {\n stopOpenListener = onOpenDatabaseNotifications(() => (open.value = true))\n})\nonScopeDispose(() => stopOpenListener?.())\n\nonScopeDispose(() => center?.stopPolling())\nconst format = useFormatter()\n\n// `pwa(push: true)` in a starter kit: the app's user menu has no AlfaKit entries, so Web\n// Push is turned on or off from the bell's menu.\nconst pwa = useStore(pwaStore)\nconst pushToggle = computed(\n () =>\n Boolean(panel.value.starterKit && panel.value.pwa?.push) && pwa.value.push !== 'unsupported',\n)\nonMounted(() => {\n if (panel.value.starterKit && panel.value.pwa?.push) startPwa(panel.value.pwa)\n})\nasync function togglePush() {\n const { message } = await togglePushNotifications()\n const text = t(message.key, {}, message.fallback)\n\n if (message.error) toast.error(text)\n else toast.success(text)\n}\n</script>\n\n<template>\n <Popover v-if=\"config && center\" :open=\"open\" @update:open=\"open = $event\">\n <PopoverTrigger as-child>\n <Button\n v-if=\"props.variant === 'sidebar'\"\n type=\"button\"\n variant=\"ghost\"\n class=\"relative w-full justify-start gap-2 group-data-[collapsible=icon]:size-8 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0\"\n data-slot=\"notifications-trigger\"\n data-variant=\"sidebar\"\n >\n <!-- In a collapsed (icon) sidebar only the bell and its badge stay visible. -->\n <Icon\n name=\"alfakit::panels.topbar.open-database-notifications-button\"\n :fallback=\"BellIcon\"\n />\n <span class=\"flex-1 text-start group-data-[collapsible=icon]:sr-only\">{{\n t('notifications', {}, 'Notifications')\n }}</span>\n <span\n v-if=\"state.unreadCount > 0\"\n class=\"bg-primary text-primary-foreground flex h-5 min-w-5 items-center justify-center rounded-full px-1 text-xs font-medium group-data-[collapsible=icon]:absolute group-data-[collapsible=icon]:-end-1 group-data-[collapsible=icon]:-top-1 group-data-[collapsible=icon]:h-4 group-data-[collapsible=icon]:min-w-4 group-data-[collapsible=icon]:text-[10px]\"\n >{{ state.unreadCount > 99 ? '99+' : state.unreadCount }}\n <span class=\"sr-only\">{{ t('unread_notifications', {}, 'unread') }}</span></span\n >\n </Button>\n <Button\n v-else\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n class=\"relative\"\n data-slot=\"notifications-trigger\"\n :aria-label=\"t('notifications', {}, 'Notifications')\"\n >\n <Icon\n name=\"alfakit::panels.topbar.open-database-notifications-button\"\n :fallback=\"BellIcon\"\n />\n <span\n v-if=\"state.unreadCount > 0\"\n class=\"bg-primary text-primary-foreground absolute -end-0.5 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-medium\"\n >{{ state.unreadCount > 99 ? '99+' : state.unreadCount }}</span\n >\n </Button>\n </PopoverTrigger>\n <PopoverContent\n :align=\"props.variant === 'sidebar' ? 'start' : 'end'\"\n :side=\"props.variant === 'sidebar' ? (direction === 'rtl' ? 'left' : 'right') : 'bottom'\"\n class=\"w-80 p-0 sm:w-96\"\n >\n <div class=\"flex items-center justify-between border-b px-3 py-2\">\n <span class=\"text-sm font-semibold\">{{ t('notifications', {}, 'Notifications') }}</span>\n <div class=\"flex items-center gap-1\">\n <Button\n v-if=\"pushToggle\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n data-slot=\"pwa-push\"\n :disabled=\"pwa.pushBusy || pwa.push === 'denied'\"\n :title=\"\n pwa.push === 'subscribed'\n ? t('pwa.notifications.disable', {}, 'Turn off notifications')\n : t('pwa.notifications.enable', {}, 'Turn on notifications')\n \"\n :aria-label=\"\n pwa.push === 'subscribed'\n ? t('pwa.notifications.disable', {}, 'Turn off notifications')\n : t('pwa.notifications.enable', {}, 'Turn on notifications')\n \"\n @click=\"void togglePush()\"\n >\n <BellOffIcon v-if=\"pwa.push === 'subscribed'\" />\n <BellRingIcon v-else />\n </Button>\n <Button\n v-if=\"state.unreadCount > 0\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n :title=\"t('mark_all_read', {}, 'Mark all as read')\"\n @click=\"void center.markAllAsRead()\"\n ><CheckCheckIcon\n /></Button>\n <Button\n v-if=\"state.notifications.length > 0\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n :title=\"t('clear_notifications', {}, 'Clear notifications')\"\n @click=\"void center.clear()\"\n ><Trash2Icon\n /></Button>\n </div>\n </div>\n <ScrollArea class=\"max-h-96\">\n <div\n v-if=\"state.loading && state.notifications.length === 0\"\n class=\"flex justify-center py-8\"\n >\n <Spinner />\n </div>\n <p\n v-else-if=\"state.notifications.length === 0\"\n class=\"text-muted-foreground px-3 py-8 text-center text-sm\"\n >\n {{ t('no_notifications', {}, 'You have no notifications.') }}\n </p>\n <ul v-else class=\"divide-y\">\n <li\n v-for=\"notification in state.notifications\"\n :key=\"notification.id\"\n :class=\"cn('flex gap-3 px-3 py-3', !notification.readAt && 'bg-primary/5')\"\n :style=\"\n notification.color\n ? notificationTintStyles(cssColor(notification.color)).item\n : undefined\n \"\n >\n <Icon\n v-if=\"notification.icon\"\n :name=\"notification.icon\"\n :class=\"\n cn(\n 'mt-0.5 size-5 shrink-0',\n notification.iconColor && textColorClasses[notification.iconColor],\n )\n \"\n />\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div class=\"flex items-start justify-between gap-2\">\n <p class=\"text-sm font-medium\">{{ notification.title }}</p>\n <button\n v-if=\"!notification.readAt\"\n type=\"button\"\n class=\"focus-visible:ring-ring/50 -me-2 -mt-0.5 flex size-6 shrink-0 items-center justify-center rounded-full outline-none focus-visible:ring-[3px]\"\n :aria-label=\"t('mark_as_read', {}, 'Mark as read')\"\n @click=\"void center.markAsRead(notification.id)\"\n >\n <span class=\"bg-primary size-2 rounded-full\" aria-hidden=\"true\" />\n </button>\n </div>\n <p\n v-if=\"notification.body\"\n class=\"text-muted-foreground text-sm\"\n v-html=\"notification.body\"\n />\n <time v-if=\"notification.date\" class=\"text-muted-foreground text-xs\">{{\n format.relative(notification.date)\n }}</time>\n <div v-if=\"notification.actions\" class=\"flex flex-wrap gap-1\">\n <NotificationActionButton\n v-for=\"action in notification.actions\"\n :key=\"action.name\"\n :action=\"action\"\n :on-mark-as-read=\"() => void center!.markAsRead(notification.id)\"\n :on-mark-as-unread=\"() => void center!.markAsUnread(notification.id)\"\n />\n </div>\n </div>\n </li>\n </ul>\n <div\n v-if=\"state.hasMore && state.notifications.length > 0\"\n class=\"flex justify-center border-t p-2\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n :disabled=\"state.loading\"\n @click=\"void center!.loadMore()\"\n >\n <Spinner v-if=\"state.loading\" />\n {{ t('load_more', {}, 'Load more') }}\n </Button>\n </div>\n </ScrollArea>\n </PopoverContent>\n </Popover>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BottomNav.js","names":["_sfc_main","BottomNav_vue_vue_type_script_setup_true_lang_default","BottomNav_default"],"sources":["../../../src/components/panel/BottomNav.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport NavLabel from './NavLabel.vue'\nimport {\n PREFETCH_CACHE_FOR,\n bottomNavigationItems,\n isNavigationItemActive,\n navigationItemUrl,\n type NavigationItemSchema,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/vue3'\nimport { MenuIcon } from '@lucide/vue'\nimport { computed, ref } from 'vue'\nimport { usePanel, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\n\n/**\n * The mobile preset's bottom navigation bar (`Panel::mobile()`): the top-level items, with\n * the rest behind a \"More\" button that opens a sheet. Hidden from `md` up; replace it\n * everywhere with `createAlfakit({ components: { 'panel:bottom-nav': … } })`.\n */\nconst panel = usePanel()\nconst t = useT()\nconst open = ref(false)\nconst items = computed(() => bottomNavigationItems(panel.value.navigation))\nconst overflowActive = computed(() => items.value.overflow.some(isNavigationItemActive))\nconst overflowLinks = computed(() =>\n items.value.overflow.flatMap((item) => [item, ...(item.children ?? [])]),\n)\nconst url = (item: NavigationItemSchema): string => navigationItemUrl(item) ?? '#'\n</script>\n\n<template>\n <nav\n v-if=\"items.primary.length > 0 || items.overflow.length > 0\"\n data-slot=\"bottom-nav\"\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"md:hidden\"\n >\n <template v-for=\"item in items.primary\" :key=\"item.label\">\n <a\n v-if=\"item.openInNewTab\"\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-slot=\"bottom-nav-item\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </a>\n <Link\n v-else\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n prefetch\n :cache-for=\"PREFETCH_CACHE_FOR\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n :aria-current=\"isNavigationItemActive(item) ? 'page' : undefined\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </template>\n <Sheet v-if=\"items.overflow.length > 0\" :open=\"open\" @update:open=\"open = $event\">\n <button\n type=\"button\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"overflowActive ? 'true' : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"open\"\n class=\"min-w-0 bg-transparent\"\n @click=\"open = true\"\n >\n <Icon name=\"alfakit::panels.topbar.open-sidebar-button\" :fallback=\"MenuIcon\" />\n <span class=\"max-w-full truncate\">{{ t('more', {}, 'More') }}</span>\n </button>\n <SheetContent side=\"bottom\" class=\"max-h-[80dvh] overflow-y-auto rounded-t-xl p-0\">\n <SheetHeader class=\"border-b\">\n <SheetTitle>{{ t('more', {}, 'More') }}</SheetTitle>\n </SheetHeader>\n <nav\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"flex flex-col gap-1 p-3 text-sm\"\n >\n <Link\n v-for=\"item in overflowLinks\"\n :key=\"item.label\"\n :href=\"url(item)\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n class=\"hover:bg-accent data-[active=true]:bg-accent flex min-h-11 items-center gap-3 rounded-md px-3 font-medium [&_svg]:size-4\"\n @click=\"open = false\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </nav>\n </SheetContent>\n </Sheet>\n </nav>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"BottomNav.js","names":["_sfc_main","BottomNav_vue_vue_type_script_setup_true_lang_default","BottomNav_default"],"sources":["../../../src/components/panel/BottomNav.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport NavLabel from './NavLabel.vue'\nimport {\n PREFETCH_CACHE_FOR,\n bottomNavigationItems,\n isNavigationItemActive,\n navigationItemUrl,\n type NavigationItemSchema,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/vue3'\nimport { MenuIcon } from '@lucide/vue'\nimport { computed, ref } from 'vue'\nimport { usePanel, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\n\n/**\n * The mobile preset's bottom navigation bar (`Panel::mobile()`): the top-level items, with\n * the rest behind a \"More\" button that opens a sheet. Hidden from `md` up; replace it\n * everywhere with `createAlfakit({ components: { 'panel:bottom-nav': … } })`.\n */\nconst panel = usePanel()\nconst t = useT()\nconst open = ref(false)\nconst items = computed(() => bottomNavigationItems(panel.value.navigation))\nconst overflowActive = computed(() => items.value.overflow.some(isNavigationItemActive))\nconst overflowLinks = computed(() =>\n items.value.overflow.flatMap((item) => [item, ...(item.children ?? [])]),\n)\nconst url = (item: NavigationItemSchema): string => navigationItemUrl(item) ?? '#'\n</script>\n\n<template>\n <nav\n v-if=\"items.primary.length > 0 || items.overflow.length > 0\"\n data-slot=\"bottom-nav\"\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"md:hidden\"\n >\n <template v-for=\"item in items.primary\" :key=\"item.url ?? item.label\">\n <a\n v-if=\"item.openInNewTab\"\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-slot=\"bottom-nav-item\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </a>\n <Link\n v-else\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n prefetch\n :cache-for=\"PREFETCH_CACHE_FOR\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n :aria-current=\"isNavigationItemActive(item) ? 'page' : undefined\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </template>\n <Sheet v-if=\"items.overflow.length > 0\" :open=\"open\" @update:open=\"open = $event\">\n <button\n type=\"button\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"overflowActive ? 'true' : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"open\"\n class=\"min-w-0 bg-transparent\"\n @click=\"open = true\"\n >\n <Icon name=\"alfakit::panels.topbar.open-sidebar-button\" :fallback=\"MenuIcon\" />\n <span class=\"max-w-full truncate\">{{ t('more', {}, 'More') }}</span>\n </button>\n <SheetContent side=\"bottom\" class=\"max-h-[80dvh] overflow-y-auto rounded-t-xl p-0\">\n <SheetHeader class=\"border-b\">\n <SheetTitle>{{ t('more', {}, 'More') }}</SheetTitle>\n </SheetHeader>\n <nav\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"flex flex-col gap-1 p-3 text-sm\"\n >\n <Link\n v-for=\"item in overflowLinks\"\n :key=\"item.url ?? item.label\"\n :href=\"url(item)\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n class=\"hover:bg-accent data-[active=true]:bg-accent flex min-h-11 items-center gap-3 rounded-md px-3 font-medium [&_svg]:size-4\"\n @click=\"open = false\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </nav>\n </SheetContent>\n </Sheet>\n </nav>\n</template>\n"],"mappings":""}
@@ -19,7 +19,7 @@ var A = ["aria-label"], j = ["href"], M = ["data-active", "aria-expanded"], N =
19
19
  "data-slot": "bottom-nav",
20
20
  "aria-label": D(I)("navigation", {}, "Navigation"),
21
21
  class: "md:hidden"
22
- }, [(C(!0), _(p, null, T(R.value.primary, (e) => (C(), _(p, { key: e.label }, [e.openInNewTab ? (C(), _("a", S({
22
+ }, [(C(!0), _(p, null, T(R.value.primary, (e) => (C(), _(p, { key: e.url ?? e.label }, [e.openInNewTab ? (C(), _("a", S({
23
23
  key: 0,
24
24
  ref_for: !0
25
25
  }, e.extraAttributes ?? {}, {
@@ -91,7 +91,7 @@ var A = ["aria-label"], j = ["href"], M = ["data-active", "aria-expanded"], N =
91
91
  "aria-label": D(I)("navigation", {}, "Navigation"),
92
92
  class: "flex flex-col gap-1 p-3 text-sm"
93
93
  }, [(C(!0), _(p, null, T(B.value, (e) => (C(), h(D(f), {
94
- key: e.label,
94
+ key: e.url ?? e.label,
95
95
  href: V(e),
96
96
  "data-active": D(u)(e) ? "true" : void 0,
97
97
  class: "hover:bg-accent data-[active=true]:bg-accent flex min-h-11 items-center gap-3 rounded-md px-3 font-medium [&_svg]:size-4",
@@ -1 +1 @@
1
- {"version":3,"file":"BottomNav.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_unref","_Fragment","_renderList","_mergeProps","_createBlock","Icon","_createCommentVNode","_createVNode","NavLabel","_withCtx","Sheet","_createElementVNode","_toDisplayString","SheetContent","SheetHeader","SheetTitle","_createTextVNode","Icon_default","Sheet_default","SheetContent_default","SheetHeader_default","SheetTitle_default","NavLabel_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","BottomNav_vue_vue_type_script_setup_true_lang_default","panel","usePanel","t","useT","open","ref","items","computed","bottomNavigationItems","overflowActive","isNavigationItemActive","overflowLinks","item","url","navigationItemUrl","openBlock","createElementBlock","unref","Fragment","renderList","mergeProps","createBlock","createCommentVNode","createVNode","Link","PREFETCH_CACHE_FOR","withCtx","_cache","$event","createElementVNode","MenuIcon","toDisplayString","createTextVNode"],"sources":["../../../src/components/panel/BottomNav.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport NavLabel from './NavLabel.vue'\nimport {\n PREFETCH_CACHE_FOR,\n bottomNavigationItems,\n isNavigationItemActive,\n navigationItemUrl,\n type NavigationItemSchema,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/vue3'\nimport { MenuIcon } from '@lucide/vue'\nimport { computed, ref } from 'vue'\nimport { usePanel, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\n\n/**\n * The mobile preset's bottom navigation bar (`Panel::mobile()`): the top-level items, with\n * the rest behind a \"More\" button that opens a sheet. Hidden from `md` up; replace it\n * everywhere with `createAlfakit({ components: { 'panel:bottom-nav': … } })`.\n */\nconst panel = usePanel()\nconst t = useT()\nconst open = ref(false)\nconst items = computed(() => bottomNavigationItems(panel.value.navigation))\nconst overflowActive = computed(() => items.value.overflow.some(isNavigationItemActive))\nconst overflowLinks = computed(() =>\n items.value.overflow.flatMap((item) => [item, ...(item.children ?? [])]),\n)\nconst url = (item: NavigationItemSchema): string => navigationItemUrl(item) ?? '#'\n</script>\n\n<template>\n <nav\n v-if=\"items.primary.length > 0 || items.overflow.length > 0\"\n data-slot=\"bottom-nav\"\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"md:hidden\"\n >\n <template v-for=\"item in items.primary\" :key=\"item.label\">\n <a\n v-if=\"item.openInNewTab\"\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-slot=\"bottom-nav-item\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </a>\n <Link\n v-else\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n prefetch\n :cache-for=\"PREFETCH_CACHE_FOR\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n :aria-current=\"isNavigationItemActive(item) ? 'page' : undefined\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </template>\n <Sheet v-if=\"items.overflow.length > 0\" :open=\"open\" @update:open=\"open = $event\">\n <button\n type=\"button\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"overflowActive ? 'true' : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"open\"\n class=\"min-w-0 bg-transparent\"\n @click=\"open = true\"\n >\n <Icon name=\"alfakit::panels.topbar.open-sidebar-button\" :fallback=\"MenuIcon\" />\n <span class=\"max-w-full truncate\">{{ t('more', {}, 'More') }}</span>\n </button>\n <SheetContent side=\"bottom\" class=\"max-h-[80dvh] overflow-y-auto rounded-t-xl p-0\">\n <SheetHeader class=\"border-b\">\n <SheetTitle>{{ t('more', {}, 'More') }}</SheetTitle>\n </SheetHeader>\n <nav\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"flex flex-col gap-1 p-3 text-sm\"\n >\n <Link\n v-for=\"item in overflowLinks\"\n :key=\"item.label\"\n :href=\"url(item)\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n class=\"hover:bg-accent data-[active=true]:bg-accent flex min-h-11 items-center gap-3 rounded-md px-3 font-medium [&_svg]:size-4\"\n @click=\"open = false\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </nav>\n </SheetContent>\n </Sheet>\n </nav>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"BottomNav.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_unref","_Fragment","_renderList","_mergeProps","_createBlock","Icon","_createCommentVNode","_createVNode","NavLabel","_withCtx","Sheet","_createElementVNode","_toDisplayString","SheetContent","SheetHeader","SheetTitle","_createTextVNode","Icon_default","Sheet_default","SheetContent_default","SheetHeader_default","SheetTitle_default","NavLabel_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","BottomNav_vue_vue_type_script_setup_true_lang_default","panel","usePanel","t","useT","open","ref","items","computed","bottomNavigationItems","overflowActive","isNavigationItemActive","overflowLinks","item","url","navigationItemUrl","openBlock","createElementBlock","unref","Fragment","renderList","mergeProps","createBlock","createCommentVNode","createVNode","Link","PREFETCH_CACHE_FOR","withCtx","_cache","$event","createElementVNode","MenuIcon","toDisplayString","createTextVNode"],"sources":["../../../src/components/panel/BottomNav.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport NavLabel from './NavLabel.vue'\nimport {\n PREFETCH_CACHE_FOR,\n bottomNavigationItems,\n isNavigationItemActive,\n navigationItemUrl,\n type NavigationItemSchema,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/vue3'\nimport { MenuIcon } from '@lucide/vue'\nimport { computed, ref } from 'vue'\nimport { usePanel, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\n\n/**\n * The mobile preset's bottom navigation bar (`Panel::mobile()`): the top-level items, with\n * the rest behind a \"More\" button that opens a sheet. Hidden from `md` up; replace it\n * everywhere with `createAlfakit({ components: { 'panel:bottom-nav': … } })`.\n */\nconst panel = usePanel()\nconst t = useT()\nconst open = ref(false)\nconst items = computed(() => bottomNavigationItems(panel.value.navigation))\nconst overflowActive = computed(() => items.value.overflow.some(isNavigationItemActive))\nconst overflowLinks = computed(() =>\n items.value.overflow.flatMap((item) => [item, ...(item.children ?? [])]),\n)\nconst url = (item: NavigationItemSchema): string => navigationItemUrl(item) ?? '#'\n</script>\n\n<template>\n <nav\n v-if=\"items.primary.length > 0 || items.overflow.length > 0\"\n data-slot=\"bottom-nav\"\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"md:hidden\"\n >\n <template v-for=\"item in items.primary\" :key=\"item.url ?? item.label\">\n <a\n v-if=\"item.openInNewTab\"\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-slot=\"bottom-nav-item\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </a>\n <Link\n v-else\n v-bind=\"item.extraAttributes ?? {}\"\n :href=\"url(item)\"\n prefetch\n :cache-for=\"PREFETCH_CACHE_FOR\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n :aria-current=\"isNavigationItemActive(item) ? 'page' : undefined\"\n class=\"min-w-0\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel class=\"max-w-full truncate\" :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </template>\n <Sheet v-if=\"items.overflow.length > 0\" :open=\"open\" @update:open=\"open = $event\">\n <button\n type=\"button\"\n data-slot=\"bottom-nav-item\"\n :data-active=\"overflowActive ? 'true' : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"open\"\n class=\"min-w-0 bg-transparent\"\n @click=\"open = true\"\n >\n <Icon name=\"alfakit::panels.topbar.open-sidebar-button\" :fallback=\"MenuIcon\" />\n <span class=\"max-w-full truncate\">{{ t('more', {}, 'More') }}</span>\n </button>\n <SheetContent side=\"bottom\" class=\"max-h-[80dvh] overflow-y-auto rounded-t-xl p-0\">\n <SheetHeader class=\"border-b\">\n <SheetTitle>{{ t('more', {}, 'More') }}</SheetTitle>\n </SheetHeader>\n <nav\n :aria-label=\"t('navigation', {}, 'Navigation')\"\n class=\"flex flex-col gap-1 p-3 text-sm\"\n >\n <Link\n v-for=\"item in overflowLinks\"\n :key=\"item.url ?? item.label\"\n :href=\"url(item)\"\n :data-active=\"isNavigationItemActive(item) ? 'true' : undefined\"\n class=\"hover:bg-accent data-[active=true]:bg-accent flex min-h-11 items-center gap-3 rounded-md px-3 font-medium [&_svg]:size-4\"\n @click=\"open = false\"\n >\n <Icon v-if=\"item.icon\" :name=\"item.icon\" />\n <NavLabel :text=\"item.label\" :html=\"item.labelHtml\" />\n </Link>\n </nav>\n </SheetContent>\n </Sheet>\n </nav>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"KeyboardShortcuts.js","names":["_sfc_main","KeyboardShortcuts_vue_vue_type_script_setup_true_lang_default","KeyboardShortcuts_default"],"sources":["../../../src/components/panel/KeyboardShortcuts.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { CommandSchema } from '@alfakit/core'\nimport {\n commandShortcutId,\n COMMANDS_COMPONENT,\n focusTableSearch,\n SHORTCUT_IDS,\n shortcuts,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { computed, ref, shallowRef, watch, type Component } from 'vue'\nimport { useActionRunner, usePageSchema, usePanel, useT } from '../../context'\nimport { shortcutsOverlay } from './lazy-chrome'\n\n/**\n * Keyboard shortcuts of the panel: `/` (focus the table search), `g d` (dashboard), `?`\n * (the overlay) and the panel commands' `shortcut()`, with the user's customised keys\n * (`alfakit.keyboardShortcuts`).\n */\nconst t = useT()\nconst panel = usePanel()\nconst page = usePageSchema()\nconst runner = useActionRunner()\nconst open = ref(false)\n// Null on the server and during hydration (nothing loads there), so the markup matches.\nconst Overlay = shallowRef<Component | null>(shortcutsOverlay.current)\n\n// `?` (or the palette's \"Keyboard shortcuts\") before the code has arrived keeps `open` set;\n// the overlay mounts open once it has loaded.\nwatch(open, (value, _old, onCleanup) => {\n if (!value) return\n\n // Already loaded (by another instance): mount it straight away.\n if (shortcutsOverlay.current) {\n Overlay.value = shortcutsOverlay.current\n\n return\n }\n\n let active = true\n onCleanup(() => {\n active = false\n })\n\n shortcutsOverlay.load().then(\n (component) => {\n if (active) Overlay.value = component\n },\n () => {\n if (active) open.value = false\n },\n )\n})\nconst config = computed(() => panel.value.keyboardShortcuts)\nconst overrides = computed(() => JSON.stringify(config.value ? (config.value.overrides ?? {}) : {}))\n\nwatch(\n [config, overrides],\n ([value, stored]) => {\n if (typeof window === 'undefined') return\n\n shortcuts.setEnabled(value !== false)\n shortcuts.setOverrides(JSON.parse(stored) as Record<string, string[]>)\n },\n { immediate: true },\n)\n\n// Keyed on what the registrations depend on, so reloads (a new panel object) don't churn.\nconst registrations = computed(() =>\n config.value\n ? JSON.stringify({\n token: page.value?.token ?? '',\n home: panel.value.url ?? null,\n commands: (panel.value.commandPalette?.commands ?? []).filter(\n (command) => command.keyBindings?.length && !command.disabled,\n ),\n })\n : '',\n)\n\nwatch(\n registrations,\n (value, _old, onCleanup) => {\n if (!value || typeof window === 'undefined') return\n\n const { token, home, commands } = JSON.parse(value) as {\n token: string\n home: string | null\n commands: CommandSchema[]\n }\n\n const disposers = [\n shortcuts.register({\n id: SHORTCUT_IDS.overlay,\n keys: ['?'],\n label: t('shortcuts.show_overlay', {}, 'Show keyboard shortcuts'),\n group: 'general',\n handler: () => {\n open.value = true\n },\n }),\n // Declined (`false`) on pages without a table search, so `/` keeps its default.\n shortcuts.register({\n id: SHORTCUT_IDS.search,\n keys: ['/'],\n label: t('shortcuts.focus_search', {}, 'Search the table'),\n group: 'general',\n handler: () => focusTableSearch(),\n }),\n ...(home\n ? [\n shortcuts.register({\n id: SHORTCUT_IDS.dashboard,\n keys: ['g d'],\n label: t('shortcuts.go_dashboard', {}, 'Go to the dashboard'),\n group: 'navigation',\n handler: () => router.visit(home),\n }),\n ]\n : []),\n ...commands.map((command) =>\n shortcuts.register({\n id: commandShortcutId(command.name),\n keys: command.keyBindings ?? [],\n label: command.label ?? command.name,\n group: command.url ? 'navigation' : 'commands',\n handler: () => void runner.trigger(command, { token, component: COMMANDS_COMPONENT }),\n }),\n ),\n ]\n\n onCleanup(() => disposers.forEach((dispose) => dispose()))\n },\n { immediate: true },\n)\n\nconst customizable = computed(() =>\n Boolean(config.value && config.value.customizable && panel.value.endpoints.shortcuts),\n)\n</script>\n\n<template>\n <component\n :is=\"Overlay\"\n v-if=\"config && Overlay\"\n :open=\"open\"\n :customizable=\"customizable\"\n :endpoint=\"panel.endpoints.shortcuts\"\n @update:open=\"open = $event\"\n />\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"KeyboardShortcuts.js","names":["_sfc_main","KeyboardShortcuts_vue_vue_type_script_setup_true_lang_default","KeyboardShortcuts_default"],"sources":["../../../src/components/panel/KeyboardShortcuts.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { CommandSchema } from '@alfakit/core'\nimport {\n commandShortcutId,\n COMMANDS_COMPONENT,\n focusTableSearch,\n SHORTCUT_IDS,\n shortcuts,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { computed, ref, shallowRef, watch, type Component } from 'vue'\nimport { useActionRunner, usePageSchema, usePanel, useT } from '../../context'\nimport { shortcutsOverlay } from './lazy-chrome'\n\n/**\n * Keyboard shortcuts of the panel: `/` (focus the table search), `g d` (dashboard), `?`\n * (the overlay) and the panel commands' `shortcut()`, with the user's customised keys\n * (`alfakit.keyboardShortcuts`).\n */\nconst t = useT()\nconst panel = usePanel()\nconst page = usePageSchema()\nconst runner = useActionRunner()\nconst open = ref(false)\n// Null on the server and during hydration (nothing loads there), so the markup matches.\nconst Overlay = shallowRef<Component | null>(shortcutsOverlay.current)\n\n// `?` (or the palette's \"Keyboard shortcuts\") before the code has arrived keeps `open` set;\n// the overlay mounts open once it has loaded.\nwatch(open, (value, _old, onCleanup) => {\n if (!value) return\n\n // Already loaded (by another instance): mount it straight away.\n if (shortcutsOverlay.current) {\n Overlay.value = shortcutsOverlay.current\n\n return\n }\n\n let active = true\n onCleanup(() => {\n active = false\n })\n\n shortcutsOverlay.load().then(\n (component) => {\n if (active) Overlay.value = component\n },\n () => {\n if (active) open.value = false\n },\n )\n})\nconst config = computed(() => panel.value.keyboardShortcuts)\nconst overrides = computed(() => JSON.stringify(config.value ? (config.value.overrides ?? {}) : {}))\n\nwatch(\n [config, overrides],\n ([value, stored]) => {\n if (typeof window === 'undefined') return\n\n shortcuts.setEnabled(value !== false)\n shortcuts.setOverrides(JSON.parse(stored) as Record<string, string[]>)\n },\n { immediate: true },\n)\n\n// Keyed on what the registrations depend on, so reloads (a new panel object) don't churn.\nconst registrations = computed(() =>\n config.value\n ? JSON.stringify({\n token: page.value?.token ?? '',\n home: panel.value.dashboardUrl ?? panel.value.url ?? null,\n commands: (panel.value.commandPalette?.commands ?? []).filter(\n (command) => command.keyBindings?.length && !command.disabled,\n ),\n })\n : '',\n)\n\nwatch(\n registrations,\n (value, _old, onCleanup) => {\n if (!value || typeof window === 'undefined') return\n\n const { token, home, commands } = JSON.parse(value) as {\n token: string\n home: string | null\n commands: CommandSchema[]\n }\n\n const disposers = [\n shortcuts.register({\n id: SHORTCUT_IDS.overlay,\n keys: ['?'],\n label: t('shortcuts.show_overlay', {}, 'Show keyboard shortcuts'),\n group: 'general',\n handler: () => {\n open.value = true\n },\n }),\n // Declined (`false`) on pages without a table search, so `/` keeps its default.\n shortcuts.register({\n id: SHORTCUT_IDS.search,\n keys: ['/'],\n label: t('shortcuts.focus_search', {}, 'Search the table'),\n group: 'general',\n handler: () => focusTableSearch(),\n }),\n ...(home\n ? [\n shortcuts.register({\n id: SHORTCUT_IDS.dashboard,\n keys: ['g d'],\n label: t('shortcuts.go_dashboard', {}, 'Go to the dashboard'),\n group: 'navigation',\n handler: () => router.visit(home),\n }),\n ]\n : []),\n ...commands.map((command) =>\n shortcuts.register({\n id: commandShortcutId(command.name),\n keys: command.keyBindings ?? [],\n label: command.label ?? command.name,\n group: command.url ? 'navigation' : 'commands',\n handler: () => void runner.trigger(command, { token, component: COMMANDS_COMPONENT }),\n }),\n ),\n ]\n\n onCleanup(() => disposers.forEach((dispose) => dispose()))\n },\n { immediate: true },\n)\n\nconst customizable = computed(() =>\n Boolean(config.value && config.value.customizable && panel.value.endpoints.shortcuts),\n)\n</script>\n\n<template>\n <component\n :is=\"Overlay\"\n v-if=\"config && Overlay\"\n :open=\"open\"\n :customizable=\"customizable\"\n :endpoint=\"panel.endpoints.shortcuts\"\n @update:open=\"open = $event\"\n />\n</template>\n"],"mappings":""}
@@ -29,7 +29,7 @@ var x = /*@__PURE__*/ m({
29
29
  }, { immediate: !0 });
30
30
  let k = d(() => D.value ? JSON.stringify({
31
31
  token: C.value?.token ?? "",
32
- home: S.value.url ?? null,
32
+ home: S.value.dashboardUrl ?? S.value.url ?? null,
33
33
  commands: (S.value.commandPalette?.commands ?? []).filter((e) => e.keyBindings?.length && !e.disabled)
34
34
  }) : "");
35
35
  b(k, (e, t, n) => {