@alfakit/vue 0.1.0 → 0.1.2

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 (136) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/components/actions/ActionButton.js.map +1 -1
  3. package/dist/components/actions/ActionButton.vue.d.ts.map +1 -1
  4. package/dist/components/actions/ActionButton.vue_vue_type_script_setup_true_lang.js +160 -159
  5. package/dist/components/actions/ActionButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/actions/ActionModal.js.map +1 -1
  7. package/dist/components/actions/ActionModal.vue.d.ts.map +1 -1
  8. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js +214 -214
  9. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/cms/CmsLinkButton.vue.d.ts +1 -1
  11. package/dist/components/fields/ColorPickerField.js.map +1 -1
  12. package/dist/components/fields/ColorPickerField.vue.d.ts.map +1 -1
  13. package/dist/components/fields/ColorPickerField.vue_vue_type_script_setup_true_lang.js +1 -0
  14. package/dist/components/fields/ColorPickerField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/fields/ComboboxSelect.js.map +1 -1
  16. package/dist/components/fields/ComboboxSelect.vue.d.ts.map +1 -1
  17. package/dist/components/fields/ComboboxSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  18. package/dist/components/fields/ComboboxSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/fields/FileUploadField.js.map +1 -1
  20. package/dist/components/fields/FileUploadField.vue.d.ts.map +1 -1
  21. package/dist/components/fields/FileUploadField.vue_vue_type_script_setup_true_lang.js +183 -183
  22. package/dist/components/fields/FileUploadField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/fields/OneTimeCodeInputField.js.map +1 -1
  24. package/dist/components/fields/OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js +1 -2
  25. package/dist/components/fields/OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/fields/SelectField.js.map +1 -1
  27. package/dist/components/fields/SelectField.vue.d.ts.map +1 -1
  28. package/dist/components/fields/SelectField.vue_vue_type_script_setup_true_lang.js +2 -2
  29. package/dist/components/fields/SelectField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/fields/TableColumnHeaders.js.map +1 -1
  31. package/dist/components/fields/TableColumnHeaders.vue.d.ts.map +1 -1
  32. package/dist/components/fields/TableColumnHeaders.vue_vue_type_script_setup_true_lang.js +6 -3
  33. package/dist/components/fields/TableColumnHeaders.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/file-manager/FileManagerView.js.map +1 -1
  35. package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js +1 -1
  36. package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/form/FormBlock.js.map +1 -1
  38. package/dist/components/form/FormBlock.vue.d.ts.map +1 -1
  39. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js +81 -77
  40. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/form/form-context.js +25 -25
  42. package/dist/components/form/form-context.js.map +1 -1
  43. package/dist/components/layout/FusedGroupComponent.js.map +1 -1
  44. package/dist/components/layout/FusedGroupComponent.vue.d.ts.map +1 -1
  45. package/dist/components/layout/FusedGroupComponent.vue_vue_type_script_setup_true_lang.js +1 -0
  46. package/dist/components/layout/FusedGroupComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  47. package/dist/components/layout/TabsComponent.js.map +1 -1
  48. package/dist/components/layout/TabsComponent.vue.d.ts.map +1 -1
  49. package/dist/components/layout/TabsComponent.vue_vue_type_script_setup_true_lang.js +76 -55
  50. package/dist/components/layout/TabsComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/notifications/NotificationsMenu.js.map +1 -1
  52. package/dist/components/notifications/NotificationsMenu.vue.d.ts.map +1 -1
  53. package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js +44 -42
  54. package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/components/panel/GlobalSearch.js.map +1 -1
  56. package/dist/components/panel/GlobalSearch.vue.d.ts.map +1 -1
  57. package/dist/components/panel/GlobalSearch.vue_vue_type_script_setup_true_lang.js +1 -0
  58. package/dist/components/panel/GlobalSearch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  59. package/dist/components/panel/ShortcutKeys.js.map +1 -1
  60. package/dist/components/panel/ShortcutKeys.vue.d.ts.map +1 -1
  61. package/dist/components/panel/ShortcutKeys.vue_vue_type_script_setup_true_lang.js +4 -1
  62. package/dist/components/panel/ShortcutKeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/panel/TenantMenu.js.map +1 -1
  64. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js +2 -2
  65. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/components/table/GroupHeaderRow.js.map +1 -1
  67. package/dist/components/table/GroupHeaderRow.vue.d.ts.map +1 -1
  68. package/dist/components/table/GroupHeaderRow.vue_vue_type_script_setup_true_lang.js +55 -34
  69. package/dist/components/table/GroupHeaderRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/table/SelectCell.js.map +1 -1
  71. package/dist/components/table/SelectCell.vue.d.ts.map +1 -1
  72. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js +24 -19
  73. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/table/TextInputCell.js.map +1 -1
  75. package/dist/components/table/TextInputCell.vue.d.ts.map +1 -1
  76. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js +38 -33
  77. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components.css +347 -0
  79. package/dist/eject-manifest.json +2 -2
  80. package/dist/lib/Icon.js.map +1 -1
  81. package/dist/lib/Icon.vue.d.ts.map +1 -1
  82. package/dist/lib/Icon.vue_vue_type_script_setup_true_lang.js +18 -19
  83. package/dist/lib/Icon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/lib/hydration.d.ts +9 -0
  85. package/dist/lib/hydration.d.ts.map +1 -0
  86. package/dist/lib/hydration.js +17 -0
  87. package/dist/lib/hydration.js.map +1 -0
  88. package/dist/lib/icons.d.ts +3 -5
  89. package/dist/lib/icons.d.ts.map +1 -1
  90. package/dist/lib/icons.js +19 -22
  91. package/dist/lib/icons.js.map +1 -1
  92. package/dist/lib/lazy.d.ts +1 -1
  93. package/dist/lib/lazy.d.ts.map +1 -1
  94. package/dist/lib/lazy.js +12 -11
  95. package/dist/lib/lazy.js.map +1 -1
  96. package/dist/standalone/AlfakitToaster.js.map +1 -1
  97. package/dist/standalone/AlfakitToaster.vue.d.ts.map +1 -1
  98. package/dist/standalone/AlfakitToaster.vue_vue_type_script_setup_true_lang.js +23 -15
  99. package/dist/standalone/AlfakitToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/standalone.css +47 -0
  101. package/dist/starter-kit/widgets/SearchTrigger.js.map +1 -1
  102. package/dist/starter-kit/widgets/SearchTrigger.vue.d.ts.map +1 -1
  103. package/dist/starter-kit/widgets/SearchTrigger.vue_vue_type_script_setup_true_lang.js +1 -0
  104. package/dist/starter-kit/widgets/SearchTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/starter-kit/widgets/TenantChooser.js.map +1 -1
  106. package/dist/starter-kit/widgets/TenantChooser.vue_vue_type_script_setup_true_lang.js +1 -1
  107. package/dist/starter-kit/widgets/TenantChooser.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/themes.css +2 -334
  109. package/package.json +3 -3
  110. package/src/components/actions/ActionButton.vue +14 -6
  111. package/src/components/actions/ActionModal.vue +3 -1
  112. package/src/components/fields/ColorPickerField.vue +1 -0
  113. package/src/components/fields/ComboboxSelect.vue +1 -1
  114. package/src/components/fields/FileUploadField.vue +14 -11
  115. package/src/components/fields/OneTimeCodeInputField.vue +1 -1
  116. package/src/components/fields/SelectField.vue +4 -2
  117. package/src/components/fields/TableColumnHeaders.vue +6 -1
  118. package/src/components/file-manager/FileManagerView.vue +1 -1
  119. package/src/components/form/FormBlock.vue +24 -0
  120. package/src/components/form/form-context.ts +2 -2
  121. package/src/components/layout/FusedGroupComponent.vue +1 -0
  122. package/src/components/layout/TabsComponent.vue +61 -5
  123. package/src/components/notifications/NotificationsMenu.vue +11 -0
  124. package/src/components/panel/GlobalSearch.vue +1 -0
  125. package/src/components/panel/ShortcutKeys.vue +1 -0
  126. package/src/components/panel/TenantMenu.vue +2 -2
  127. package/src/components/table/GroupHeaderRow.vue +27 -0
  128. package/src/components/table/SelectCell.vue +5 -2
  129. package/src/components/table/TextInputCell.vue +11 -5
  130. package/src/lib/Icon.vue +6 -5
  131. package/src/lib/hydration.ts +35 -0
  132. package/src/lib/icons.ts +6 -11
  133. package/src/lib/lazy.ts +5 -6
  134. package/src/standalone/AlfakitToaster.vue +12 -2
  135. package/src/starter-kit/widgets/SearchTrigger.vue +1 -0
  136. package/src/starter-kit/widgets/TenantChooser.vue +1 -1
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "package": "@alfakit/vue",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "adapter": "vue",
5
- "generatedAt": "2026-10-19T06:11:33.237Z",
5
+ "generatedAt": "2026-10-19T11:54:13.615Z",
6
6
  "components": {
7
7
  "TextInput": {
8
8
  "file": "src/components/fields/TextInputField.vue",
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.js","names":["_sfc_main","Icon_vue_vue_type_script_setup_true_lang_default","Icon_default"],"sources":["../../src/lib/Icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { iconAlias, iconAliasOverride, iconSource, isIconAlias } from '@alfakit/core'\nimport { computed, onMounted, type Component, type HTMLAttributes } from 'vue'\nimport { useOptionalRegistry } from '../context'\nimport { iconMap, markIconsMounted, resolveIcon } from './icons'\nimport { cn } from './utils'\n\n/**\n * Renders an icon resolved by the server (`Icons::resolve()`): a Lucide name (`users`,\n * `shopping-cart`), an image URL or sanitised `<svg>` markup. `alfakit::` aliases use the\n * app's replacement (`Icons::register()`) or `fallback`. Unknown Lucide names render the\n * `fallback` icon (if any) or nothing. `fallback` may also be a statically imported glyph\n * (`:fallback=\"SearchIcon\"`): renderer chrome uses it so an unreplaced alias draws at once,\n * without loading anything.\n */\nconst props = defineProps<{\n name?: string | null\n fallback?: string | Component | null\n class?: HTMLAttributes['class']\n}>()\n\n// `createAlfakit({ components: { 'panel:icon': MyIcon } })` renders every named icon with\n// another icon set; it receives `name`, `fallback` and `class`.\nconst custom = useOptionalRegistry()?.resolve('panel:icon')\n// Named icons render once the page has hydrated (the server render shows none).\nonMounted(markIconsMounted)\n\nconst fallbackName = computed(() =>\n typeof props.fallback === 'string' ? props.fallback : undefined,\n)\nconst glyph = computed(() =>\n props.fallback && typeof props.fallback !== 'string' ? props.fallback : null,\n)\n\n// Chrome icons (`<Icon name=\"alfakit::…\" :fallback=\"SearchIcon\" />`) draw their bundled glyph\n// synchronously unless the app replaced the alias with `Icons::register()`.\nconst useGlyph = computed(\n () =>\n glyph.value !== null &&\n !!props.name &&\n isIconAlias(props.name) &&\n iconAliasOverride(props.name) === undefined,\n)\n\nconst source = computed(() =>\n props.name && !useGlyph.value ? iconSource(iconAlias(props.name, fallbackName.value)) : null,\n)\n\nconst component = computed(() => {\n if (source.value?.type !== 'name' || custom) return null\n\n const icons = iconMap()\n\n // Nothing until the icon map has loaded (and during the server render and hydration).\n if (!icons) return null\n\n return (\n resolveIcon(source.value.name, icons) ??\n glyph.value ??\n (fallbackName.value ? resolveIcon(fallbackName.value, icons) : null)\n )\n})\n</script>\n\n<template>\n <component :is=\"glyph\" v-if=\"useGlyph && glyph\" :class=\"cn('size-4 shrink-0', props.class)\" />\n <!-- Sanitised on the server (SvgSanitizer): drawing elements only. -->\n <!-- eslint-disable vue/no-v-html -->\n <span\n v-else-if=\"source?.type === 'svg'\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('inline-flex size-4 shrink-0 [&>svg]:size-full', props.class)\"\n v-html=\"source.svg\"\n />\n <!-- eslint-enable vue/no-v-html -->\n <img\n v-else-if=\"source?.type === 'url'\"\n :src=\"source.url\"\n alt=\"\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('size-4 shrink-0 object-contain', props.class)\"\n />\n <component\n :is=\"custom\"\n v-else-if=\"custom && source?.type === 'name'\"\n :name=\"source.name\"\n :fallback=\"fallbackName\"\n :class=\"cn('size-4 shrink-0', props.class)\"\n />\n <component :is=\"component\" v-else-if=\"component\" :class=\"cn('size-4 shrink-0', props.class)\" />\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Icon.js","names":["_sfc_main","Icon_vue_vue_type_script_setup_true_lang_default","Icon_default"],"sources":["../../src/lib/Icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { iconAlias, iconAliasOverride, iconSource, isIconAlias } from '@alfakit/core'\nimport { computed, type Component, type HTMLAttributes } from 'vue'\nimport { useOptionalRegistry } from '../context'\nimport { useAppMounted } from './hydration'\nimport { iconMap, resolveIcon } from './icons'\nimport { cn } from './utils'\n\n/**\n * Renders an icon resolved by the server (`Icons::resolve()`): a Lucide name (`users`,\n * `shopping-cart`), an image URL or sanitised `<svg>` markup. `alfakit::` aliases use the\n * app's replacement (`Icons::register()`) or `fallback`. Unknown Lucide names render the\n * `fallback` icon (if any) or nothing. `fallback` may also be a statically imported glyph\n * (`:fallback=\"SearchIcon\"`): renderer chrome uses it so an unreplaced alias draws at once,\n * without loading anything.\n */\nconst props = defineProps<{\n name?: string | null\n fallback?: string | Component | null\n class?: HTMLAttributes['class']\n}>()\n\n// `createAlfakit({ components: { 'panel:icon': MyIcon } })` renders every named icon with\n// another icon set; it receives `name`, `fallback` and `class`.\nconst custom = useOptionalRegistry()?.resolve('panel:icon')\n// Named icons render once this app has hydrated (the server render shows none).\nconst mounted = useAppMounted()\n\nconst fallbackName = computed(() =>\n typeof props.fallback === 'string' ? props.fallback : undefined,\n)\nconst glyph = computed(() =>\n props.fallback && typeof props.fallback !== 'string' ? props.fallback : null,\n)\n\n// Chrome icons (`<Icon name=\"alfakit::…\" :fallback=\"SearchIcon\" />`) draw their bundled glyph\n// synchronously unless the app replaced the alias with `Icons::register()`.\nconst useGlyph = computed(\n () =>\n glyph.value !== null &&\n !!props.name &&\n isIconAlias(props.name) &&\n iconAliasOverride(props.name) === undefined,\n)\n\nconst source = computed(() =>\n props.name && !useGlyph.value ? iconSource(iconAlias(props.name, fallbackName.value)) : null,\n)\n\nconst component = computed(() => {\n if (source.value?.type !== 'name' || custom) return null\n\n const icons = iconMap(mounted.value)\n\n // Nothing until the icon map has loaded (and during the server render and hydration).\n if (!icons) return null\n\n return (\n resolveIcon(source.value.name, icons) ??\n glyph.value ??\n (fallbackName.value ? resolveIcon(fallbackName.value, icons) : null)\n )\n})\n</script>\n\n<template>\n <component :is=\"glyph\" v-if=\"useGlyph && glyph\" :class=\"cn('size-4 shrink-0', props.class)\" />\n <!-- Sanitised on the server (SvgSanitizer): drawing elements only. -->\n <!-- eslint-disable vue/no-v-html -->\n <span\n v-else-if=\"source?.type === 'svg'\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('inline-flex size-4 shrink-0 [&>svg]:size-full', props.class)\"\n v-html=\"source.svg\"\n />\n <!-- eslint-enable vue/no-v-html -->\n <img\n v-else-if=\"source?.type === 'url'\"\n :src=\"source.url\"\n alt=\"\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('size-4 shrink-0 object-contain', props.class)\"\n />\n <component\n :is=\"custom\"\n v-else-if=\"custom && source?.type === 'name'\"\n :name=\"source.name\"\n :fallback=\"fallbackName\"\n :class=\"cn('size-4 shrink-0', props.class)\"\n />\n <component :is=\"component\" v-else-if=\"component\" :class=\"cn('size-4 shrink-0', props.class)\" />\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.vue.d.ts","sourceRoot":"","sources":["../../src/lib/Icon.vue"],"names":[],"mappings":"AAgGA,OAAO,EAAuB,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAK9E;;;;;;;GAOG;AACH,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IACpC,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;CAChC,CAAC;;AAuIF,wBAMG"}
1
+ {"version":3,"file":"Icon.vue.d.ts","sourceRoot":"","sources":["../../src/lib/Icon.vue"],"names":[],"mappings":"AAiGA,OAAO,EAAY,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAMnE;;;;;;;GAOG;AACH,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IACpC,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;CAChC,CAAC;;AAuIF,wBAMG"}
@@ -1,10 +1,11 @@
1
1
  import { useOptionalRegistry as e } from "../context.js";
2
2
  import { cn as t } from "./utils.js";
3
- import { iconMap as n, markIconsMounted as r, resolveIcon as i } from "./icons.js";
3
+ import { useAppMounted as n } from "./hydration.js";
4
+ import { iconMap as r, resolveIcon as i } from "./icons.js";
4
5
  import { iconAlias as a, iconAliasOverride as o, iconSource as s, isIconAlias as c } from "@alfakit/core";
5
- import { computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, defineComponent as p, normalizeClass as m, onMounted as h, openBlock as g, resolveDynamicComponent as _, unref as v } from "vue";
6
+ import { computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, defineComponent as p, normalizeClass as m, openBlock as h, resolveDynamicComponent as g, unref as _ } from "vue";
6
7
  //#region src/lib/Icon.vue?vue&type=script&setup=true&lang.ts
7
- var y = ["innerHTML"], b = ["src"], x = /*@__PURE__*/ p({
8
+ var v = ["innerHTML"], y = ["src"], b = /*@__PURE__*/ p({
8
9
  __name: "Icon",
9
10
  props: {
10
11
  name: {},
@@ -18,45 +19,43 @@ var y = ["innerHTML"], b = ["src"], x = /*@__PURE__*/ p({
18
19
  ] }
19
20
  },
20
21
  setup(p) {
21
- let x = p, S = e()?.resolve("panel:icon");
22
- h(r);
23
- let C = l(() => typeof x.fallback == "string" ? x.fallback : void 0), w = l(() => x.fallback && typeof x.fallback != "string" ? x.fallback : null), T = l(() => w.value !== null && !!x.name && c(x.name) && o(x.name) === void 0), E = l(() => x.name && !T.value ? s(a(x.name, C.value)) : null), D = l(() => {
24
- if (E.value?.type !== "name" || S) return null;
25
- let e = n();
22
+ let b = p, x = e()?.resolve("panel:icon"), S = n(), C = l(() => typeof b.fallback == "string" ? b.fallback : void 0), w = l(() => b.fallback && typeof b.fallback != "string" ? b.fallback : null), T = l(() => w.value !== null && !!b.name && c(b.name) && o(b.name) === void 0), E = l(() => b.name && !T.value ? s(a(b.name, C.value)) : null), D = l(() => {
23
+ if (E.value?.type !== "name" || x) return null;
24
+ let e = r(S.value);
26
25
  return e ? i(E.value.name, e) ?? w.value ?? (C.value ? i(C.value, e) : null) : null;
27
26
  });
28
- return (e, n) => T.value && w.value ? (g(), u(_(w.value), {
27
+ return (e, n) => T.value && w.value ? (h(), u(g(w.value), {
29
28
  key: 0,
30
- class: m(v(t)("size-4 shrink-0", x.class))
31
- }, null, 8, ["class"])) : E.value?.type === "svg" ? (g(), f("span", {
29
+ class: m(_(t)("size-4 shrink-0", b.class))
30
+ }, null, 8, ["class"])) : E.value?.type === "svg" ? (h(), f("span", {
32
31
  key: 1,
33
32
  "aria-hidden": "true",
34
33
  "data-slot": "icon",
35
- class: m(v(t)("inline-flex size-4 shrink-0 [&>svg]:size-full", x.class)),
34
+ class: m(_(t)("inline-flex size-4 shrink-0 [&>svg]:size-full", b.class)),
36
35
  innerHTML: E.value.svg
37
- }, null, 10, y)) : E.value?.type === "url" ? (g(), f("img", {
36
+ }, null, 10, v)) : E.value?.type === "url" ? (h(), f("img", {
38
37
  key: 2,
39
38
  src: E.value.url,
40
39
  alt: "",
41
40
  "aria-hidden": "true",
42
41
  "data-slot": "icon",
43
- class: m(v(t)("size-4 shrink-0 object-contain", x.class))
44
- }, null, 10, b)) : v(S) && E.value?.type === "name" ? (g(), u(_(v(S)), {
42
+ class: m(_(t)("size-4 shrink-0 object-contain", b.class))
43
+ }, null, 10, y)) : _(x) && E.value?.type === "name" ? (h(), u(g(_(x)), {
45
44
  key: 3,
46
45
  name: E.value.name,
47
46
  fallback: C.value,
48
- class: m(v(t)("size-4 shrink-0", x.class))
47
+ class: m(_(t)("size-4 shrink-0", b.class))
49
48
  }, null, 8, [
50
49
  "name",
51
50
  "fallback",
52
51
  "class"
53
- ])) : D.value ? (g(), u(_(D.value), {
52
+ ])) : D.value ? (h(), u(g(D.value), {
54
53
  key: 4,
55
- class: m(v(t)("size-4 shrink-0", x.class))
54
+ class: m(_(t)("size-4 shrink-0", b.class))
56
55
  }, null, 8, ["class"])) : d("", !0);
57
56
  }
58
57
  });
59
58
  //#endregion
60
- export { x as default };
59
+ export { b as default };
61
60
 
62
61
  //# sourceMappingURL=Icon.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeClass","_unref","_createElementBlock","_createCommentVNode","_hoisted_1","_hoisted_2","Icon_vue_vue_type_script_setup_true_lang_default","props","__props","custom","useOptionalRegistry","markIconsMounted","fallbackName","computed","glyph","useGlyph","isIconAlias","iconAliasOverride","source","iconSource","iconAlias","component","icons","iconMap","resolveIcon","openBlock","createBlock","resolveDynamicComponent","normalizeClass","unref","cn","createElementBlock","createCommentVNode"],"sources":["../../src/lib/Icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { iconAlias, iconAliasOverride, iconSource, isIconAlias } from '@alfakit/core'\nimport { computed, onMounted, type Component, type HTMLAttributes } from 'vue'\nimport { useOptionalRegistry } from '../context'\nimport { iconMap, markIconsMounted, resolveIcon } from './icons'\nimport { cn } from './utils'\n\n/**\n * Renders an icon resolved by the server (`Icons::resolve()`): a Lucide name (`users`,\n * `shopping-cart`), an image URL or sanitised `<svg>` markup. `alfakit::` aliases use the\n * app's replacement (`Icons::register()`) or `fallback`. Unknown Lucide names render the\n * `fallback` icon (if any) or nothing. `fallback` may also be a statically imported glyph\n * (`:fallback=\"SearchIcon\"`): renderer chrome uses it so an unreplaced alias draws at once,\n * without loading anything.\n */\nconst props = defineProps<{\n name?: string | null\n fallback?: string | Component | null\n class?: HTMLAttributes['class']\n}>()\n\n// `createAlfakit({ components: { 'panel:icon': MyIcon } })` renders every named icon with\n// another icon set; it receives `name`, `fallback` and `class`.\nconst custom = useOptionalRegistry()?.resolve('panel:icon')\n// Named icons render once the page has hydrated (the server render shows none).\nonMounted(markIconsMounted)\n\nconst fallbackName = computed(() =>\n typeof props.fallback === 'string' ? props.fallback : undefined,\n)\nconst glyph = computed(() =>\n props.fallback && typeof props.fallback !== 'string' ? props.fallback : null,\n)\n\n// Chrome icons (`<Icon name=\"alfakit::…\" :fallback=\"SearchIcon\" />`) draw their bundled glyph\n// synchronously unless the app replaced the alias with `Icons::register()`.\nconst useGlyph = computed(\n () =>\n glyph.value !== null &&\n !!props.name &&\n isIconAlias(props.name) &&\n iconAliasOverride(props.name) === undefined,\n)\n\nconst source = computed(() =>\n props.name && !useGlyph.value ? iconSource(iconAlias(props.name, fallbackName.value)) : null,\n)\n\nconst component = computed(() => {\n if (source.value?.type !== 'name' || custom) return null\n\n const icons = iconMap()\n\n // Nothing until the icon map has loaded (and during the server render and hydration).\n if (!icons) return null\n\n return (\n resolveIcon(source.value.name, icons) ??\n glyph.value ??\n (fallbackName.value ? resolveIcon(fallbackName.value, icons) : null)\n )\n})\n</script>\n\n<template>\n <component :is=\"glyph\" v-if=\"useGlyph && glyph\" :class=\"cn('size-4 shrink-0', props.class)\" />\n <!-- Sanitised on the server (SvgSanitizer): drawing elements only. -->\n <!-- eslint-disable vue/no-v-html -->\n <span\n v-else-if=\"source?.type === 'svg'\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('inline-flex size-4 shrink-0 [&>svg]:size-full', props.class)\"\n v-html=\"source.svg\"\n />\n <!-- eslint-enable vue/no-v-html -->\n <img\n v-else-if=\"source?.type === 'url'\"\n :src=\"source.url\"\n alt=\"\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('size-4 shrink-0 object-contain', props.class)\"\n />\n <component\n :is=\"custom\"\n v-else-if=\"custom && source?.type === 'name'\"\n :name=\"source.name\"\n :fallback=\"fallbackName\"\n :class=\"cn('size-4 shrink-0', props.class)\"\n />\n <component :is=\"component\" v-else-if=\"component\" :class=\"cn('size-4 shrink-0', props.class)\" />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAeA,IAAMU,IAAQC,GAQRC,IAASC,EAAoB,CAAC,EAAE,QAAQ,YAAY;EAE1D,EAAUC,CAAgB;EAE1B,IAAMC,IAAeC,QACnB,OAAON,EAAM,YAAa,WAAWA,EAAM,WAAW,KAAA,CACxD,GACMO,IAAQD,QACZN,EAAM,YAAY,OAAOA,EAAM,YAAa,WAAWA,EAAM,WAAW,IAC1E,GAIMQ,IAAWF,QAEbC,EAAM,UAAU,QAChB,CAAC,CAACP,EAAM,QACRS,EAAYT,EAAM,IAAI,KACtBU,EAAkBV,EAAM,IAAI,MAAM,KAAA,CACtC,GAEMW,IAASL,QACbN,EAAM,QAAQ,CAACQ,EAAS,QAAQI,EAAWC,EAAUb,EAAM,MAAMK,EAAa,KAAK,CAAC,IAAI,IAC1F,GAEMS,IAAYR,QAAe;GAC/B,IAAIK,EAAO,OAAO,SAAS,UAAUT,GAAQ,OAAO;GAEpD,IAAMa,IAAQC,EAAQ;GAKtB,OAFKD,IAGHE,EAAYN,EAAO,MAAM,MAAMI,CAAK,KACpCR,EAAM,UACLF,EAAa,QAAQY,EAAYZ,EAAa,OAAOU,CAAK,IAAI,QAL9C;EAOrB,CAAC;mBAI8BP,EAAA,SAAYD,EAAA,SAAzCjB,EAAA,GAAAC,EAA8FC,EAA9Ee,EAAA,KAAK,GAAA;;GAA4B,OAAKd,EAAEC,EAAA6B,CAAA,CAAE,CAAA,mBAAoBvB,EAAM,KAAK,CAAA;EAI5E,GAAA,MAAA,GAAA,CAAA,OAAA,CAAA,KAAAW,EAAA,OAAQ,SAAI,SADzBrB,EAAA,GAAAK,EAME,QAAA;;GAJA,eAAY;GACZ,aAAU;GACT,OAAKF,EAAEC,EAAA6B,CAAA,CAAE,CAAA,iDAAkDvB,EAAM,KAAK,CAAA;GACvE,WAAQW,EAAA,MAAO;EAIJ,GAAA,MAAA,IAAAd,CAAA,KAAAc,EAAA,OAAQ,SAAI,SADzBrB,EAAA,GAAAK,EAOE,OAAA;;GALC,KAAKgB,EAAA,MAAO;GACb,KAAI;GACJ,eAAY;GACZ,aAAU;GACT,OAAKlB,EAAEC,EAAA6B,CAAA,CAAE,CAAA,kCAAmCvB,EAAM,KAAK,CAAA;EAI7CN,GAAAA,MAAAA,IAAAA,CAAAA,KAAAA,EAAAQ,CAAA,KAAUS,EAAA,OAAQ,SAAI,UAFnCrB,EAAA,GAAAC,EAMEC,EALKE,EAAAQ,CAAA,CAAM,GAAA;;GAEV,MAAMS,EAAA,MAAO;GACb,UAAUN,EAAA;GACV,OAAKZ,EAAEC,EAAA6B,CAAA,CAAE,CAAA,mBAAoBvB,EAAM,KAAK,CAAA;;;;;EAEL,CAAA,KAAAc,EAAA,SAAtCxB,EAAA,GAAAC,EAA+FC,EAA/EsB,EAAA,KAAS,GAAA;;GAAyB,OAAKrB,EAAEC,EAAA6B,CAAA,CAAE,CAAA,mBAAoBvB,EAAM,KAAK,CAAA"}
1
+ {"version":3,"file":"Icon.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeClass","_unref","_createElementBlock","_createCommentVNode","_hoisted_1","_hoisted_2","Icon_vue_vue_type_script_setup_true_lang_default","props","__props","custom","useOptionalRegistry","mounted","useAppMounted","fallbackName","computed","glyph","useGlyph","isIconAlias","iconAliasOverride","source","iconSource","iconAlias","component","icons","iconMap","resolveIcon","openBlock","createBlock","resolveDynamicComponent","normalizeClass","unref","cn","createElementBlock","createCommentVNode"],"sources":["../../src/lib/Icon.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { iconAlias, iconAliasOverride, iconSource, isIconAlias } from '@alfakit/core'\nimport { computed, type Component, type HTMLAttributes } from 'vue'\nimport { useOptionalRegistry } from '../context'\nimport { useAppMounted } from './hydration'\nimport { iconMap, resolveIcon } from './icons'\nimport { cn } from './utils'\n\n/**\n * Renders an icon resolved by the server (`Icons::resolve()`): a Lucide name (`users`,\n * `shopping-cart`), an image URL or sanitised `<svg>` markup. `alfakit::` aliases use the\n * app's replacement (`Icons::register()`) or `fallback`. Unknown Lucide names render the\n * `fallback` icon (if any) or nothing. `fallback` may also be a statically imported glyph\n * (`:fallback=\"SearchIcon\"`): renderer chrome uses it so an unreplaced alias draws at once,\n * without loading anything.\n */\nconst props = defineProps<{\n name?: string | null\n fallback?: string | Component | null\n class?: HTMLAttributes['class']\n}>()\n\n// `createAlfakit({ components: { 'panel:icon': MyIcon } })` renders every named icon with\n// another icon set; it receives `name`, `fallback` and `class`.\nconst custom = useOptionalRegistry()?.resolve('panel:icon')\n// Named icons render once this app has hydrated (the server render shows none).\nconst mounted = useAppMounted()\n\nconst fallbackName = computed(() =>\n typeof props.fallback === 'string' ? props.fallback : undefined,\n)\nconst glyph = computed(() =>\n props.fallback && typeof props.fallback !== 'string' ? props.fallback : null,\n)\n\n// Chrome icons (`<Icon name=\"alfakit::…\" :fallback=\"SearchIcon\" />`) draw their bundled glyph\n// synchronously unless the app replaced the alias with `Icons::register()`.\nconst useGlyph = computed(\n () =>\n glyph.value !== null &&\n !!props.name &&\n isIconAlias(props.name) &&\n iconAliasOverride(props.name) === undefined,\n)\n\nconst source = computed(() =>\n props.name && !useGlyph.value ? iconSource(iconAlias(props.name, fallbackName.value)) : null,\n)\n\nconst component = computed(() => {\n if (source.value?.type !== 'name' || custom) return null\n\n const icons = iconMap(mounted.value)\n\n // Nothing until the icon map has loaded (and during the server render and hydration).\n if (!icons) return null\n\n return (\n resolveIcon(source.value.name, icons) ??\n glyph.value ??\n (fallbackName.value ? resolveIcon(fallbackName.value, icons) : null)\n )\n})\n</script>\n\n<template>\n <component :is=\"glyph\" v-if=\"useGlyph && glyph\" :class=\"cn('size-4 shrink-0', props.class)\" />\n <!-- Sanitised on the server (SvgSanitizer): drawing elements only. -->\n <!-- eslint-disable vue/no-v-html -->\n <span\n v-else-if=\"source?.type === 'svg'\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('inline-flex size-4 shrink-0 [&>svg]:size-full', props.class)\"\n v-html=\"source.svg\"\n />\n <!-- eslint-enable vue/no-v-html -->\n <img\n v-else-if=\"source?.type === 'url'\"\n :src=\"source.url\"\n alt=\"\"\n aria-hidden=\"true\"\n data-slot=\"icon\"\n :class=\"cn('size-4 shrink-0 object-contain', props.class)\"\n />\n <component\n :is=\"custom\"\n v-else-if=\"custom && source?.type === 'name'\"\n :name=\"source.name\"\n :fallback=\"fallbackName\"\n :class=\"cn('size-4 shrink-0', props.class)\"\n />\n <component :is=\"component\" v-else-if=\"component\" :class=\"cn('size-4 shrink-0', props.class)\" />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAgBA,IAAMU,IAAQC,GAQRC,IAASC,EAAoB,CAAC,EAAE,QAAQ,YAAY,GAEpDC,IAAUC,EAAc,GAExBC,IAAeC,QACnB,OAAOP,EAAM,YAAa,WAAWA,EAAM,WAAW,KAAA,CACxD,GACMQ,IAAQD,QACZP,EAAM,YAAY,OAAOA,EAAM,YAAa,WAAWA,EAAM,WAAW,IAC1E,GAIMS,IAAWF,QAEbC,EAAM,UAAU,QAChB,CAAC,CAACR,EAAM,QACRU,EAAYV,EAAM,IAAI,KACtBW,EAAkBX,EAAM,IAAI,MAAM,KAAA,CACtC,GAEMY,IAASL,QACbP,EAAM,QAAQ,CAACS,EAAS,QAAQI,EAAWC,EAAUd,EAAM,MAAMM,EAAa,KAAK,CAAC,IAAI,IAC1F,GAEMS,IAAYR,QAAe;GAC/B,IAAIK,EAAO,OAAO,SAAS,UAAUV,GAAQ,OAAO;GAEpD,IAAMc,IAAQC,EAAQb,EAAQ,KAAK;GAKnC,OAFKY,IAGHE,EAAYN,EAAO,MAAM,MAAMI,CAAK,KACpCR,EAAM,UACLF,EAAa,QAAQY,EAAYZ,EAAa,OAAOU,CAAK,IAAI,QAL9C;EAOrB,CAAC;mBAI8BP,EAAA,SAAYD,EAAA,SAAzClB,EAAA,GAAAC,EAA8FC,EAA9EgB,EAAA,KAAK,GAAA;;GAA4B,OAAKf,EAAEC,EAAA8B,CAAA,CAAE,CAAA,mBAAoBxB,EAAM,KAAK,CAAA;EAI5E,GAAA,MAAA,GAAA,CAAA,OAAA,CAAA,KAAAY,EAAA,OAAQ,SAAI,SADzBtB,EAAA,GAAAK,EAME,QAAA;;GAJA,eAAY;GACZ,aAAU;GACT,OAAKF,EAAEC,EAAA8B,CAAA,CAAE,CAAA,iDAAkDxB,EAAM,KAAK,CAAA;GACvE,WAAQY,EAAA,MAAO;EAIJ,GAAA,MAAA,IAAAf,CAAA,KAAAe,EAAA,OAAQ,SAAI,SADzBtB,EAAA,GAAAK,EAOE,OAAA;;GALC,KAAKiB,EAAA,MAAO;GACb,KAAI;GACJ,eAAY;GACZ,aAAU;GACT,OAAKnB,EAAEC,EAAA8B,CAAA,CAAE,CAAA,kCAAmCxB,EAAM,KAAK,CAAA;EAI7CN,GAAAA,MAAAA,IAAAA,CAAAA,KAAAA,EAAAQ,CAAA,KAAUU,EAAA,OAAQ,SAAI,UAFnCtB,EAAA,GAAAC,EAMEC,EALKE,EAAAQ,CAAA,CAAM,GAAA;;GAEV,MAAMU,EAAA,MAAO;GACb,UAAUN,EAAA;GACV,OAAKb,EAAEC,EAAA8B,CAAA,CAAE,CAAA,mBAAoBxB,EAAM,KAAK,CAAA;;;;;EAEL,CAAA,KAAAe,EAAA,SAAtCzB,EAAA,GAAAC,EAA+FC,EAA/EuB,EAAA,KAAS,GAAA;;GAAyB,OAAKtB,EAAEC,EAAA8B,CAAA,CAAE,CAAA,mBAAoBxB,EAAM,KAAK,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { type Ref } from 'vue';
2
+ /**
3
+ * Call in a component's setup: `false` until the component's app has mounted (so during
4
+ * the server render and hydration), then `true` for every component in that app, so
5
+ * content rendered later draws at once (reactive). Lazily loaded parts (named icons, heavy
6
+ * fields) render their server markup until then, whatever has loaded already.
7
+ */
8
+ export declare function useAppMounted(): Ref<boolean>;
9
+ //# sourceMappingURL=hydration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydration.d.ts","sourceRoot":"","sources":["../../src/lib/hydration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AASnF;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,OAAO,CAAC,CAmB5C"}
@@ -0,0 +1,17 @@
1
+ import { getCurrentInstance as e, onMounted as t, ref as n } from "vue";
2
+ //#region src/lib/hydration.ts
3
+ var r = /* @__PURE__ */ new WeakMap();
4
+ function i() {
5
+ let i = e()?.appContext;
6
+ if (!i) return n(!0);
7
+ let a = r.get(i);
8
+ a || (a = n(!1), r.set(i, a));
9
+ let o = a;
10
+ return t(() => {
11
+ o.value = !0;
12
+ }), o;
13
+ }
14
+ //#endregion
15
+ export { i as useAppMounted };
16
+
17
+ //# sourceMappingURL=hydration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydration.js","names":["mountedApps","useAppMounted","context","getCurrentInstance","ref","mounted","flag","onMounted"],"sources":["../../src/lib/hydration.ts"],"sourcesContent":["import { getCurrentInstance, onMounted, ref, type AppContext, type Ref } from 'vue'\n\n/**\n * Whether each app has mounted (hydrated). Kept per app, not per module: loaded icon chunks\n * and lazy components outlive an app, so a second app hydrating in the same page would\n * otherwise draw content its server markup does not contain.\n */\nconst mountedApps = new WeakMap<AppContext, Ref<boolean>>()\n\n/**\n * Call in a component's setup: `false` until the component's app has mounted (so during\n * the server render and hydration), then `true` for every component in that app, so\n * content rendered later draws at once (reactive). Lazily loaded parts (named icons, heavy\n * fields) render their server markup until then, whatever has loaded already.\n */\nexport function useAppMounted(): Ref<boolean> {\n const context = getCurrentInstance()?.appContext\n\n // Outside a component there is no hydration to wait for.\n if (!context) return ref(true)\n\n let mounted = mountedApps.get(context)\n\n if (!mounted) {\n mounted = ref(false)\n mountedApps.set(context, mounted)\n }\n\n const flag = mounted\n onMounted(() => {\n flag.value = true\n })\n\n return flag\n}\n"],"mappings":";;AAOA,IAAMA,oBAAc,IAAI,QAAkC;AAQ1D,SAAgBC,IAA8B;CAC5C,IAAMC,IAAUC,EAAmB,CAAC,EAAE;CAGtC,IAAI,CAACD,GAAS,OAAOE,EAAI,EAAI;CAE7B,IAAIC,IAAUL,EAAY,IAAIE,CAAO;CAErC,AAAKG,MACH,IAAUD,EAAI,EAAK,GACnBJ,EAAY,IAAIE,GAASG,CAAO;CAGlC,IAAMC,IAAOD;CAKb,OAJAE,QAAgB;EACd,EAAK,QAAQ;CACf,CAAC,GAEMD;AACT"}
@@ -12,13 +12,11 @@ import type * as IconModules from './icon-modules';
12
12
  export type IconMap = typeof IconModules;
13
13
  /** Start loading the icon map ahead of the first named icon (browser only). */
14
14
  export declare function preloadIcons(): void;
15
- /** `<Icon>`s call this once mounted: from then on named icons render (after hydration). */
16
- export declare function markIconsMounted(): void;
17
15
  /**
18
- * The icon map once it has loaded in the browser and the page has hydrated, else `null`
19
- * (reactive). Starts loading it.
16
+ * The icon map once it has loaded in the browser and the `<Icon>`'s app has mounted
17
+ * (`useAppMounted()`), else `null` (reactive). Starts loading it.
20
18
  */
21
- export declare function iconMap(): IconMap | null;
19
+ export declare function iconMap(mounted: boolean): IconMap | null;
22
20
  /**
23
21
  * The icon component for `name`, or `null` for unknown names (and while the icon map
24
22
  * loads; the result is reactive).
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/lib/icons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,SAAS,EAAE,MAAM,KAAK,CAAA;AAC3E,OAAO,KAAK,KAAK,WAAW,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,WAAW,CAAA;AAsBxC,+EAA+E;AAC/E,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;GAGG;AACH,wBAAgB,OAAO,IAAI,OAAO,GAAG,IAAI,CAIxC;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAuBhF;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/lib/icons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,KAAK,CAAA;AACtE,OAAO,KAAK,KAAK,WAAW,MAAM,gBAAgB,CAAA;AAElD;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,WAAW,CAAA;AAsBxC,+EAA+E;AAC/E,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAIxD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAuBhF;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACxC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,YAAY,CAAA"}
package/dist/lib/icons.js CHANGED
@@ -1,35 +1,32 @@
1
1
  import { hasIcon as e } from "./icon-catalog.js";
2
2
  import t from "./Icon.js";
3
- import { defineAsyncComponent as n, ref as r, shallowRef as i } from "vue";
3
+ import { defineAsyncComponent as n, shallowRef as r } from "vue";
4
4
  //#region src/lib/icons.ts
5
- var a = i(null), o = r(!1), s, c = /* @__PURE__ */ new Map();
6
- function l() {
7
- typeof window < "u" && (s ??= import("./icon-modules.js").then((e) => a.value = e, (e) => {
8
- throw s = void 0, e;
9
- }), s.catch(() => void 0));
5
+ var i = r(null), a, o = /* @__PURE__ */ new Map();
6
+ function s() {
7
+ typeof window < "u" && (a ??= import("./icon-modules.js").then((e) => i.value = e, (e) => {
8
+ throw a = void 0, e;
9
+ }), a.catch(() => void 0));
10
10
  }
11
- function u() {
12
- l();
11
+ function c() {
12
+ s();
13
13
  }
14
- function d() {
15
- o.value = !0;
14
+ function l(e) {
15
+ return i.value || s(), e ? i.value : null;
16
16
  }
17
- function f() {
18
- return a.value || l(), o.value ? a.value : null;
19
- }
20
- function p(e, t) {
21
- t === void 0 && l();
22
- let r = t === void 0 ? a.value : t;
17
+ function u(e, t) {
18
+ t === void 0 && s();
19
+ let r = t === void 0 ? i.value : t;
23
20
  if (!r) return null;
24
- let i = c.get(e);
25
- if (i !== void 0) return i;
26
- let o = r.iconModules[r.iconPath(e, r.iconModules)], s = o ? n({
27
- loader: () => o().then((e) => e.default),
21
+ let a = o.get(e);
22
+ if (a !== void 0) return a;
23
+ let c = r.iconModules[r.iconPath(e, r.iconModules)], l = c ? n({
24
+ loader: () => c().then((e) => e.default),
28
25
  suspensible: !1
29
26
  }) : null;
30
- return c.set(e, s), s;
27
+ return o.set(e, l), l;
31
28
  }
32
29
  //#endregion
33
- export { t as Icon, e as hasIcon, f as iconMap, d as markIconsMounted, u as preloadIcons, p as resolveIcon };
30
+ export { t as Icon, e as hasIcon, l as iconMap, c as preloadIcons, u as resolveIcon };
34
31
 
35
32
  //# sourceMappingURL=icons.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"icons.js","names":["Icon_default","loadedMap","shallowRef","mounted","ref","pending","cache","loadIconMap","module","error","preloadIcons","markIconsMounted","iconMap","resolveIcon","map","icons","cached","name","loader","component","defineAsyncComponent","hasIcon"],"sources":["../../src/lib/icons.ts"],"sourcesContent":["import { defineAsyncComponent, ref, shallowRef, type Component } from 'vue'\nimport type * as IconModules from './icon-modules'\n\n/**\n * Lazily loaded Lucide icons keyed by kebab-case name (`users`, `shopping-cart`). Each icon\n * becomes its own chunk, like `lucide-react/dynamic`, so the main bundle stays small.\n *\n * The name → chunk map (~2,000 entries, `./icon-modules`) is not part of any entry chunk\n * either: panels (`createAlfakit()`, starter kit pages) start loading it while they boot,\n * and elsewhere (a host's sidebar) it loads with the first icon. As in the other renderers,\n * named icons are drawn in the browser only: the server render and hydration show none.\n */\nexport type IconMap = typeof IconModules\n\nconst loadedMap = shallowRef<IconMap | null>(null)\nconst mounted = ref(false)\nlet pending: Promise<IconMap> | undefined\n\nconst cache = new Map<string, Component | null>()\n\nfunction loadIconMap(): void {\n if (typeof window === 'undefined') return\n\n pending ??= import('./icon-modules').then(\n (module) => (loadedMap.value = module),\n (error: unknown) => {\n pending = undefined\n\n throw error\n },\n )\n pending.catch(() => undefined)\n}\n\n/** Start loading the icon map ahead of the first named icon (browser only). */\nexport function preloadIcons(): void {\n loadIconMap()\n}\n\n/** `<Icon>`s call this once mounted: from then on named icons render (after hydration). */\nexport function markIconsMounted(): void {\n mounted.value = true\n}\n\n/**\n * The icon map once it has loaded in the browser and the page has hydrated, else `null`\n * (reactive). Starts loading it.\n */\nexport function iconMap(): IconMap | null {\n if (!loadedMap.value) loadIconMap()\n\n return mounted.value ? loadedMap.value : null\n}\n\n/**\n * The icon component for `name`, or `null` for unknown names (and while the icon map\n * loads; the result is reactive).\n */\nexport function resolveIcon(name: string, map?: IconMap | null): Component | null {\n if (map === undefined) loadIconMap()\n\n const icons = map === undefined ? loadedMap.value : map\n\n if (!icons) return null\n\n const cached = cache.get(name)\n\n if (cached !== undefined) {\n return cached\n }\n\n const loader = icons.iconModules[icons.iconPath(name, icons.iconModules)]\n const component = loader\n ? defineAsyncComponent({\n loader: () => loader().then((module) => module.default),\n suspensible: false,\n })\n : null\n cache.set(name, component)\n\n return component\n}\n\nexport { hasIcon } from './icon-catalog'\nexport { default as Icon } from './Icon.vue'\n"],"mappings":";;;;AAcA,IAAMC,IAAYC,EAA2B,IAAI,GAC3CC,IAAUC,EAAI,EAAK,GACrBC,GAEEC,oBAAQ,IAAI,IAA8B;AAEhD,SAASC,IAAoB;CAC3B,AAAI,OAAO,SAAW,QAEtB,MAAY,OAAO,oBAAiB,CAAC,MAClC,MAAY,EAAU,QAAQC,IAC9B,MAAmB;EAGlB,MAFA,IAAU,KAAA,GAEJC;CACR,CACF,GACAJ,EAAQ,YAAY,KAAA,CAAS;AAC/B;AAGA,SAAgBK,IAAqB;CACnC,EAAY;AACd;AAGA,SAAgBC,IAAyB;CACvC,EAAQ,QAAQ;AAClB;AAMA,SAAgBC,IAA0B;CAGxC,OAFKX,EAAU,SAAOM,EAAY,GAE3BJ,EAAQ,QAAQF,EAAU,QAAQ;AAC3C;AAMA,SAAgBY,EAAY,GAAc,GAAwC;CAChF,AAAIC,MAAQ,KAAA,KAAWP,EAAY;CAEnC,IAAMQ,IAAQD,MAAQ,KAAA,IAAYb,EAAU,QAAQa;CAEpD,IAAI,CAACC,GAAO,OAAO;CAEnB,IAAMC,IAASV,EAAM,IAAIW,CAAI;CAE7B,IAAID,MAAW,KAAA,GACb,OAAOA;CAGT,IAAME,IAASH,EAAM,YAAYA,EAAM,SAASE,GAAMF,EAAM,WAAW,IACjEI,IAAYD,IACdE,EAAqB;EACnB,cAAcF,EAAO,CAAC,CAAC,MAAM,MAAWV,EAAO,OAAO;EACtD,aAAa;CACf,CAAC,IACD;CAGJ,OAFAF,EAAM,IAAIW,GAAME,CAAS,GAElBA;AACT"}
1
+ {"version":3,"file":"icons.js","names":["Icon_default","loadedMap","shallowRef","pending","cache","loadIconMap","module","error","preloadIcons","iconMap","mounted","resolveIcon","map","icons","cached","name","loader","component","defineAsyncComponent","hasIcon"],"sources":["../../src/lib/icons.ts"],"sourcesContent":["import { defineAsyncComponent, shallowRef, type Component } from 'vue'\nimport type * as IconModules from './icon-modules'\n\n/**\n * Lazily loaded Lucide icons keyed by kebab-case name (`users`, `shopping-cart`). Each icon\n * becomes its own chunk, like `lucide-react/dynamic`, so the main bundle stays small.\n *\n * The name → chunk map (~2,000 entries, `./icon-modules`) is not part of any entry chunk\n * either: panels (`createAlfakit()`, starter kit pages) start loading it while they boot,\n * and elsewhere (a host's sidebar) it loads with the first icon. As in the other renderers,\n * named icons are drawn in the browser only: the server render and hydration show none.\n */\nexport type IconMap = typeof IconModules\n\nconst loadedMap = shallowRef<IconMap | null>(null)\n\nlet pending: Promise<IconMap> | undefined\n\nconst cache = new Map<string, Component | null>()\n\nfunction loadIconMap(): void {\n if (typeof window === 'undefined') return\n\n pending ??= import('./icon-modules').then(\n (module) => (loadedMap.value = module),\n (error: unknown) => {\n pending = undefined\n\n throw error\n },\n )\n pending.catch(() => undefined)\n}\n\n/** Start loading the icon map ahead of the first named icon (browser only). */\nexport function preloadIcons(): void {\n loadIconMap()\n}\n\n/**\n * The icon map once it has loaded in the browser and the `<Icon>`'s app has mounted\n * (`useAppMounted()`), else `null` (reactive). Starts loading it.\n */\nexport function iconMap(mounted: boolean): IconMap | null {\n if (!loadedMap.value) loadIconMap()\n\n return mounted ? loadedMap.value : null\n}\n\n/**\n * The icon component for `name`, or `null` for unknown names (and while the icon map\n * loads; the result is reactive).\n */\nexport function resolveIcon(name: string, map?: IconMap | null): Component | null {\n if (map === undefined) loadIconMap()\n\n const icons = map === undefined ? loadedMap.value : map\n\n if (!icons) return null\n\n const cached = cache.get(name)\n\n if (cached !== undefined) {\n return cached\n }\n\n const loader = icons.iconModules[icons.iconPath(name, icons.iconModules)]\n const component = loader\n ? defineAsyncComponent({\n loader: () => loader().then((module) => module.default),\n suspensible: false,\n })\n : null\n cache.set(name, component)\n\n return component\n}\n\nexport { hasIcon } from './icon-catalog'\nexport { default as Icon } from './Icon.vue'\n"],"mappings":";;;;AAcA,IAAMC,IAAYC,EAA2B,IAAI,GAE7CC,GAEEC,oBAAQ,IAAI,IAA8B;AAEhD,SAASC,IAAoB;CAC3B,AAAI,OAAO,SAAW,QAEtB,MAAY,OAAO,oBAAiB,CAAC,MAClC,MAAY,EAAU,QAAQC,IAC9B,MAAmB;EAGlB,MAFA,IAAU,KAAA,GAEJC;CACR,CACF,GACAJ,EAAQ,YAAY,KAAA,CAAS;AAC/B;AAGA,SAAgBK,IAAqB;CACnC,EAAY;AACd;AAMA,SAAgBC,EAAQ,GAAkC;CAGxD,OAFKR,EAAU,SAAOI,EAAY,GAE3BK,IAAUT,EAAU,QAAQ;AACrC;AAMA,SAAgBU,EAAY,GAAc,GAAwC;CAChF,AAAIC,MAAQ,KAAA,KAAWP,EAAY;CAEnC,IAAMQ,IAAQD,MAAQ,KAAA,IAAYX,EAAU,QAAQW;CAEpD,IAAI,CAACC,GAAO,OAAO;CAEnB,IAAMC,IAASV,EAAM,IAAIW,CAAI;CAE7B,IAAID,MAAW,KAAA,GACb,OAAOA;CAGT,IAAME,IAASH,EAAM,YAAYA,EAAM,SAASE,GAAMF,EAAM,WAAW,IACjEI,IAAYD,IACdE,EAAqB;EACnB,cAAcF,EAAO,CAAC,CAAC,MAAM,MAAWV,EAAO,OAAO;EACtD,aAAa;CACf,CAAC,IACD;CAGJ,OAFAF,EAAM,IAAIW,GAAME,CAAS,GAElBA;AACT"}
@@ -2,7 +2,7 @@ import { type Component } from 'vue';
2
2
  /**
3
3
  * A component whose code (and heavy dependencies such as Tiptap or Chart.js) loads on
4
4
  * first use. The server render and hydration show `fallback` and never start the import;
5
- * once loaded, later renders show the component straight away.
5
+ * once the app has mounted, a loaded component renders straight away.
6
6
  */
7
7
  export declare function lazyComponent(name: string, load: () => Promise<Component>, fallback: Component): Component;
8
8
  //# sourceMappingURL=lazy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../../src/lib/lazy.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,SAAS,EAAE,MAAM,KAAK,CAAA;AAE9F;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,EAC9B,QAAQ,EAAE,SAAS,GAClB,SAAS,CAyBX"}
1
+ {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../../src/lib/lazy.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,KAAK,CAAA;AAG9E;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,EAC9B,QAAQ,EAAE,SAAS,GAClB,SAAS,CAuBX"}
package/dist/lib/lazy.js CHANGED
@@ -1,22 +1,23 @@
1
- import { defineAsyncComponent as e, defineComponent as t, h as n, onMounted as r, ref as i } from "vue";
1
+ import { useAppMounted as e } from "./hydration.js";
2
+ import { defineAsyncComponent as t, defineComponent as n, h as r } from "vue";
2
3
  //#region src/lib/lazy.ts
3
- function a(a, o, s) {
4
- let c = null, l = e({
5
- loader: () => o().then((e) => (c = e, e)),
6
- loadingComponent: s,
4
+ function i(i, a, o) {
5
+ let s = null, c = t({
6
+ loader: () => a().then((e) => (s = e, e)),
7
+ loadingComponent: o,
7
8
  delay: 0,
8
9
  suspensible: !1
9
10
  });
10
- return t({
11
- name: a,
11
+ return n({
12
+ name: i,
12
13
  inheritAttrs: !1,
13
- setup(e, { attrs: t }) {
14
- let a = i(!1);
15
- return r(() => a.value = !0), () => n(c ?? (a.value ? l : s), t);
14
+ setup(t, { attrs: n }) {
15
+ let i = e();
16
+ return () => r(i.value ? s ?? c : o, n);
16
17
  }
17
18
  });
18
19
  }
19
20
  //#endregion
20
- export { a as lazyComponent };
21
+ export { i as lazyComponent };
21
22
 
22
23
  //# sourceMappingURL=lazy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.js","names":["lazyComponent","loaded","Async","defineAsyncComponent","load","component","fallback","defineComponent","mounted","ref","onMounted","h","attrs"],"sources":["../../src/lib/lazy.ts"],"sourcesContent":["import { defineAsyncComponent, defineComponent, h, onMounted, ref, type Component } from 'vue'\n\n/**\n * A component whose code (and heavy dependencies such as Tiptap or Chart.js) loads on\n * first use. The server render and hydration show `fallback` and never start the import;\n * once loaded, later renders show the component straight away.\n */\nexport function lazyComponent(\n name: string,\n load: () => Promise<Component>,\n fallback: Component,\n): Component {\n let loaded: Component | null = null\n const Async = defineAsyncComponent({\n loader: () =>\n load().then((component) => {\n loaded = component\n\n return component\n }),\n loadingComponent: fallback,\n delay: 0,\n suspensible: false,\n })\n\n return defineComponent({\n name,\n inheritAttrs: false,\n setup(_, { attrs }) {\n const mounted = ref(false)\n\n onMounted(() => (mounted.value = true))\n\n return () => h(loaded ?? (mounted.value ? Async : fallback), attrs)\n },\n })\n}\n"],"mappings":";;AAOA,SAAgBA,EACd,GACA,GACA,GACW;CACX,IAAIC,IAA2B,MACzBC,IAAQC,EAAqB;EACjC,cACEC,EAAK,CAAC,CAAC,MAAM,OACX,IAASC,GAEFA,EACR;EACH,kBAAkBC;EAClB,OAAO;EACP,aAAa;CACf,CAAC;CAED,OAAOC,EAAgB;EACrB;EACA,cAAc;EACd,MAAM,GAAG,EAAE,YAAS;GAClB,IAAMC,IAAUC,EAAI,EAAK;GAIzB,OAFAC,QAAiB,EAAQ,QAAQ,EAAK,SAEzBC,EAAEV,MAAWO,EAAQ,QAAQN,IAAQI,IAAWM,CAAK;EACpE;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"lazy.js","names":["lazyComponent","loaded","Async","defineAsyncComponent","load","component","fallback","defineComponent","mounted","useAppMounted","h","attrs"],"sources":["../../src/lib/lazy.ts"],"sourcesContent":["import { defineAsyncComponent, defineComponent, h, type Component } from 'vue'\nimport { useAppMounted } from './hydration'\n\n/**\n * A component whose code (and heavy dependencies such as Tiptap or Chart.js) loads on\n * first use. The server render and hydration show `fallback` and never start the import;\n * once the app has mounted, a loaded component renders straight away.\n */\nexport function lazyComponent(\n name: string,\n load: () => Promise<Component>,\n fallback: Component,\n): Component {\n let loaded: Component | null = null\n const Async = defineAsyncComponent({\n loader: () =>\n load().then((component) => {\n loaded = component\n\n return component\n }),\n loadingComponent: fallback,\n delay: 0,\n suspensible: false,\n })\n\n return defineComponent({\n name,\n inheritAttrs: false,\n setup(_, { attrs }) {\n const mounted = useAppMounted()\n\n return () => h(mounted.value ? (loaded ?? Async) : fallback, attrs)\n },\n })\n}\n"],"mappings":";;;AAQA,SAAgBA,EACd,GACA,GACA,GACW;CACX,IAAIC,IAA2B,MACzBC,IAAQC,EAAqB;EACjC,cACEC,EAAK,CAAC,CAAC,MAAM,OACX,IAASC,GAEFA,EACR;EACH,kBAAkBC;EAClB,OAAO;EACP,aAAa;CACf,CAAC;CAED,OAAOC,EAAgB;EACrB;EACA,cAAc;EACd,MAAM,GAAG,EAAE,YAAS;GAClB,IAAMC,IAAUC,EAAc;GAE9B,aAAaC,EAAEF,EAAQ,QAASP,KAAUC,IAASI,GAAUK,CAAK;EACpE;CACF,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"AlfakitToaster.js","names":["_sfc_main","AlfakitToaster_vue_vue_type_script_setup_true_lang_default","AlfakitToaster_default"],"sources":["../../src/standalone/AlfakitToaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { resolveToastPosition, type ToastPosition } from '@alfakit/core'\nimport { onMounted, onUnmounted } from 'vue'\nimport Toaster from '../components/ui/Toaster.vue'\nimport { useOptionalAlfakit } from '../context'\nimport { claimToaster, createStandaloneContext, ensureFlashToasts } from './runtime'\n\n/**\n * Shows notifications flashed by standalone components (`Notification::make()->send()`\n * from `submit()` or an action) as toasts. Place it once in your app layout; a page whose\n * layout has none gets one from its first `<AlfakitComponent>`.\n *\n * Flash data comes from the `flash` Inertia event after each visit and from the initial\n * page (already fired before the app mounted), so it works in any layout.\n */\nconst props = withDefaults(\n defineProps<{\n /** Where toasts appear; `start`/`end` follow the reading direction. */\n position?: ToastPosition\n dir?: 'ltr' | 'rtl'\n /**\n * Render vue-sonner's `<Toaster>` too (default). Pass `false` when your layout already\n * mounts one: flashed Alfakit notifications are then shown through it.\n */\n toaster?: boolean\n /** @internal Set by `<AlfakitComponent>` when it takes the toaster role. */\n claimed?: boolean\n }>(),\n { dir: 'ltr', toaster: true, claimed: false },\n)\n\n// Outside <AlfakitComponent> the flash reader needs a registry for custom toast views.\nconst context =\n useOptionalAlfakit() ?? createStandaloneContext({ action: '', modal: '' }, undefined, undefined)\n\nlet release: (() => void) | null = null\n\nonMounted(() => {\n if (!props.claimed) release = claimToaster()\n\n ensureFlashToasts(context.registry)\n})\n\nonUnmounted(() => release?.())\n</script>\n\n<template>\n <Toaster\n v-if=\"props.toaster\"\n :position=\"resolveToastPosition(props.position, props.dir)\"\n :dir=\"props.dir\"\n rich-colors\n close-button\n />\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"AlfakitToaster.js","names":["_sfc_main","AlfakitToaster_vue_vue_type_script_setup_true_lang_default","AlfakitToaster_default"],"sources":["../../src/standalone/AlfakitToaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { resolveToastPosition, STARTER_KIT_TOASTER_ID, type ToastPosition } from '@alfakit/core'\nimport { onMounted, onUnmounted } from 'vue'\nimport { setToasterId } from '../components/notifications/flash-toasts'\nimport Toaster from '../components/ui/Toaster.vue'\nimport { useOptionalAlfakit } from '../context'\nimport { claimToaster, createStandaloneContext, ensureFlashToasts } from './runtime'\n\n/**\n * Shows notifications flashed by standalone components (`Notification::make()->send()`\n * from `submit()` or an action) as toasts. Place it once in your app layout; a page whose\n * layout has none gets one from its first `<AlfakitComponent>`.\n *\n * Flash data comes from the `flash` Inertia event after each visit and from the initial\n * page (already fired before the app mounted), so it works in any layout.\n */\nconst props = withDefaults(\n defineProps<{\n /** Where toasts appear; `start`/`end` follow the reading direction. */\n position?: ToastPosition\n dir?: 'ltr' | 'rtl'\n /**\n * Render vue-sonner's `<Toaster>` too (default). Pass `false` when your layout already\n * mounts one: flashed Alfakit notifications are then shown through it.\n */\n toaster?: boolean\n /** @internal Set by `<AlfakitComponent>` when it takes the toaster role. */\n claimed?: boolean\n }>(),\n { dir: 'ltr', toaster: true, claimed: false },\n)\n\n// Outside <AlfakitComponent> the flash reader needs a registry for custom toast views.\nconst context =\n useOptionalAlfakit() ?? createStandaloneContext({ action: '', modal: '' }, undefined, undefined)\n\nlet release: (() => void) | null = null\n\nonMounted(() => {\n if (!props.claimed) release = claimToaster()\n\n // Our own toaster gets an id, so a `<Toaster />` the app's layout already mounts (the\n // starter kits have one) doesn't show every Alfakit toast a second time.\n if (props.toaster) setToasterId(STARTER_KIT_TOASTER_ID)\n\n ensureFlashToasts(context.registry)\n})\n\nonUnmounted(() => {\n release?.()\n\n if (props.toaster) setToasterId(undefined)\n})\n</script>\n\n<template>\n <Toaster\n v-if=\"props.toaster\"\n :id=\"STARTER_KIT_TOASTER_ID\"\n :position=\"resolveToastPosition(props.position, props.dir)\"\n :dir=\"props.dir\"\n rich-colors\n close-button\n />\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"AlfakitToaster.vue.d.ts","sourceRoot":"","sources":["../../src/standalone/AlfakitToaster.vue"],"names":[],"mappings":"AAyDA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAMxE;;;;;;;GAOG;AACH,KAAK,WAAW,GAAG;IACf,uEAAuE;IACvE,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAC;;SARM,KAAK,GAAG,KAAK;aAKT,OAAO;aAEP,OAAO;;AAsErB,wBAOG"}
1
+ {"version":3,"file":"AlfakitToaster.vue.d.ts","sourceRoot":"","sources":["../../src/standalone/AlfakitToaster.vue"],"names":[],"mappings":"AAmEA,OAAO,EAAgD,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAOhG;;;;;;;GAOG;AACH,KAAK,WAAW,GAAG;IACf,uEAAuE;IACvE,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAC;;SARM,KAAK,GAAG,KAAK;aAKT,OAAO;aAEP,OAAO;;AAiFrB,wBAOG"}
@@ -1,10 +1,11 @@
1
1
  import { useOptionalAlfakit as e } from "../context.js";
2
- import { claimToaster as t, createStandaloneContext as n, ensureFlashToasts as r } from "./runtime.js";
3
- import i from "../components/ui/Toaster.js";
4
- import { resolveToastPosition as a } from "@alfakit/core";
5
- import { createBlock as o, createCommentVNode as s, defineComponent as c, onMounted as l, onUnmounted as u, openBlock as d, unref as f } from "vue";
2
+ import { setToasterId as t } from "../components/notifications/flash-toasts.js";
3
+ import { claimToaster as n, createStandaloneContext as r, ensureFlashToasts as i } from "./runtime.js";
4
+ import a from "../components/ui/Toaster.js";
5
+ import { STARTER_KIT_TOASTER_ID as o, resolveToastPosition as s } from "@alfakit/core";
6
+ import { createBlock as c, createCommentVNode as l, defineComponent as u, onMounted as d, onUnmounted as f, openBlock as p, unref as m } from "vue";
6
7
  //#region src/standalone/AlfakitToaster.vue?vue&type=script&setup=true&lang.ts
7
- var p = /*@__PURE__*/ c({
8
+ var h = /*@__PURE__*/ u({
8
9
  __name: "AlfakitToaster",
9
10
  props: {
10
11
  position: {},
@@ -18,23 +19,30 @@ var p = /*@__PURE__*/ c({
18
19
  default: !1
19
20
  }
20
21
  },
21
- setup(c) {
22
- let p = c, m = e() ?? n({
22
+ setup(u) {
23
+ let h = u, g = e() ?? r({
23
24
  action: "",
24
25
  modal: ""
25
- }, void 0, void 0), h = null;
26
- return l(() => {
27
- p.claimed || (h = t()), r(m.registry);
28
- }), u(() => h?.()), (e, t) => p.toaster ? (d(), o(i, {
26
+ }, void 0, void 0), _ = null;
27
+ return d(() => {
28
+ h.claimed || (_ = n()), h.toaster && t(o), i(g.registry);
29
+ }), f(() => {
30
+ _?.(), h.toaster && t(void 0);
31
+ }), (e, t) => h.toaster ? (p(), c(a, {
29
32
  key: 0,
30
- position: f(a)(p.position, p.dir),
31
- dir: p.dir,
33
+ id: m(o),
34
+ position: m(s)(h.position, h.dir),
35
+ dir: h.dir,
32
36
  "rich-colors": "",
33
37
  "close-button": ""
34
- }, null, 8, ["position", "dir"])) : s("", !0);
38
+ }, null, 8, [
39
+ "id",
40
+ "position",
41
+ "dir"
42
+ ])) : l("", !0);
35
43
  }
36
44
  });
37
45
  //#endregion
38
- export { p as default };
46
+ export { h as default };
39
47
 
40
48
  //# sourceMappingURL=AlfakitToaster.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AlfakitToaster.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","Toaster","_unref","_createCommentVNode","Toaster_default","AlfakitToaster_vue_vue_type_script_setup_true_lang_default","props","__props","context","useOptionalAlfakit","createStandaloneContext","release","onMounted","claimToaster","ensureFlashToasts","onUnmounted","openBlock","createBlock","unref","resolveToastPosition","createCommentVNode"],"sources":["../../src/standalone/AlfakitToaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { resolveToastPosition, type ToastPosition } from '@alfakit/core'\nimport { onMounted, onUnmounted } from 'vue'\nimport Toaster from '../components/ui/Toaster.vue'\nimport { useOptionalAlfakit } from '../context'\nimport { claimToaster, createStandaloneContext, ensureFlashToasts } from './runtime'\n\n/**\n * Shows notifications flashed by standalone components (`Notification::make()->send()`\n * from `submit()` or an action) as toasts. Place it once in your app layout; a page whose\n * layout has none gets one from its first `<AlfakitComponent>`.\n *\n * Flash data comes from the `flash` Inertia event after each visit and from the initial\n * page (already fired before the app mounted), so it works in any layout.\n */\nconst props = withDefaults(\n defineProps<{\n /** Where toasts appear; `start`/`end` follow the reading direction. */\n position?: ToastPosition\n dir?: 'ltr' | 'rtl'\n /**\n * Render vue-sonner's `<Toaster>` too (default). Pass `false` when your layout already\n * mounts one: flashed Alfakit notifications are then shown through it.\n */\n toaster?: boolean\n /** @internal Set by `<AlfakitComponent>` when it takes the toaster role. */\n claimed?: boolean\n }>(),\n { dir: 'ltr', toaster: true, claimed: false },\n)\n\n// Outside <AlfakitComponent> the flash reader needs a registry for custom toast views.\nconst context =\n useOptionalAlfakit() ?? createStandaloneContext({ action: '', modal: '' }, undefined, undefined)\n\nlet release: (() => void) | null = null\n\nonMounted(() => {\n if (!props.claimed) release = claimToaster()\n\n ensureFlashToasts(context.registry)\n})\n\nonUnmounted(() => release?.())\n</script>\n\n<template>\n <Toaster\n v-if=\"props.toaster\"\n :position=\"resolveToastPosition(props.position, props.dir)\"\n :dir=\"props.dir\"\n rich-colors\n close-button\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAeA,IAAMO,IAAQC,GAiBRC,IACJC,EAAmB,KAAKC,EAAwB;GAAE,QAAQ;GAAI,OAAO;EAAG,GAAG,KAAA,GAAW,KAAA,CAAS,GAE7FC,IAA+B;SAEnCC,QAAgB;GAGd,AAFKN,EAAM,YAAS,IAAUO,EAAa,IAE3CC,EAAkBN,EAAQ,QAAQ;EACpC,CAAC,GAEDO,QAAkBJ,IAAU,CAAC,aAKnBL,EAAM,WADdP,EAAA,GAAAC,EAMEC,GAAA;;GAJC,UAAUC,EAAAiB,CAAA,CAAoB,CAACb,EAAM,UAAUA,EAAM,GAAG;GACxD,KAAKA,EAAM;GACZ,eAAA;GACA,gBAAA"}
1
+ {"version":3,"file":"AlfakitToaster.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","Toaster","_unref","_createCommentVNode","Toaster_default","AlfakitToaster_vue_vue_type_script_setup_true_lang_default","props","__props","context","useOptionalAlfakit","createStandaloneContext","release","onMounted","claimToaster","setToasterId","STARTER_KIT_TOASTER_ID","ensureFlashToasts","onUnmounted","openBlock","createBlock","unref","resolveToastPosition","createCommentVNode"],"sources":["../../src/standalone/AlfakitToaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { resolveToastPosition, STARTER_KIT_TOASTER_ID, type ToastPosition } from '@alfakit/core'\nimport { onMounted, onUnmounted } from 'vue'\nimport { setToasterId } from '../components/notifications/flash-toasts'\nimport Toaster from '../components/ui/Toaster.vue'\nimport { useOptionalAlfakit } from '../context'\nimport { claimToaster, createStandaloneContext, ensureFlashToasts } from './runtime'\n\n/**\n * Shows notifications flashed by standalone components (`Notification::make()->send()`\n * from `submit()` or an action) as toasts. Place it once in your app layout; a page whose\n * layout has none gets one from its first `<AlfakitComponent>`.\n *\n * Flash data comes from the `flash` Inertia event after each visit and from the initial\n * page (already fired before the app mounted), so it works in any layout.\n */\nconst props = withDefaults(\n defineProps<{\n /** Where toasts appear; `start`/`end` follow the reading direction. */\n position?: ToastPosition\n dir?: 'ltr' | 'rtl'\n /**\n * Render vue-sonner's `<Toaster>` too (default). Pass `false` when your layout already\n * mounts one: flashed Alfakit notifications are then shown through it.\n */\n toaster?: boolean\n /** @internal Set by `<AlfakitComponent>` when it takes the toaster role. */\n claimed?: boolean\n }>(),\n { dir: 'ltr', toaster: true, claimed: false },\n)\n\n// Outside <AlfakitComponent> the flash reader needs a registry for custom toast views.\nconst context =\n useOptionalAlfakit() ?? createStandaloneContext({ action: '', modal: '' }, undefined, undefined)\n\nlet release: (() => void) | null = null\n\nonMounted(() => {\n if (!props.claimed) release = claimToaster()\n\n // Our own toaster gets an id, so a `<Toaster />` the app's layout already mounts (the\n // starter kits have one) doesn't show every Alfakit toast a second time.\n if (props.toaster) setToasterId(STARTER_KIT_TOASTER_ID)\n\n ensureFlashToasts(context.registry)\n})\n\nonUnmounted(() => {\n release?.()\n\n if (props.toaster) setToasterId(undefined)\n})\n</script>\n\n<template>\n <Toaster\n v-if=\"props.toaster\"\n :id=\"STARTER_KIT_TOASTER_ID\"\n :position=\"resolveToastPosition(props.position, props.dir)\"\n :dir=\"props.dir\"\n rich-colors\n close-button\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;EAgBA,IAAMO,IAAQC,GAiBRC,IACJC,EAAmB,KAAKC,EAAwB;GAAE,QAAQ;GAAI,OAAO;EAAG,GAAG,KAAA,GAAW,KAAA,CAAS,GAE7FC,IAA+B;SAEnCC,QAAgB;GAOd,AANKN,EAAM,YAAS,IAAUO,EAAa,IAIvCP,EAAM,WAASQ,EAAaC,CAAsB,GAEtDC,EAAkBR,EAAQ,QAAQ;EACpC,CAAC,GAEDS,QAAkB;GAGhB,AAFAN,IAAU,GAENL,EAAM,WAASQ,EAAa,KAAA,CAAS;EAC3C,CAAC,aAKSR,EAAM,WADdP,EAAA,GAAAC,EAOEC,GAAA;;GALC,IAAIC,EAAAa,CAAA;GACJ,UAAUb,EAAAmB,CAAA,CAAoB,CAACf,EAAM,UAAUA,EAAM,GAAG;GACxD,KAAKA,EAAM;GACZ,eAAA;GACA,gBAAA"}
@@ -13,6 +13,8 @@
13
13
  * your own `:root`. Shared by the React, Vue and Svelte renderers (copied into each dist).
14
14
  */
15
15
 
16
+ @import './components.css';
17
+
16
18
  @custom-variant dark (&:is(.dark *));
17
19
 
18
20
  /*
@@ -148,3 +150,48 @@
148
150
  content: attr(data-placeholder);
149
151
  @apply text-muted-foreground pointer-events-none float-left;
150
152
  }
153
+
154
+ /*
155
+ * "Developed by Alfa Six" (`[data-slot='credit']`) in the footer of panel pages. Starter-kit
156
+ * panels load this stylesheet instead of `themes.css`, so its rules are repeated here
157
+ * (keep them in step with the Credit section of themes.css).
158
+ */
159
+ [data-slot='credit'] {
160
+ display: flex;
161
+ justify-content: center;
162
+ padding: 0.75rem 1rem 1rem;
163
+ font-size: 0.75rem;
164
+ line-height: 1rem;
165
+ color: var(--muted-foreground);
166
+ }
167
+
168
+ [data-slot='credit'] a {
169
+ display: inline-flex;
170
+ align-items: center;
171
+ gap: 0.375rem;
172
+ color: inherit;
173
+ text-decoration: none;
174
+ transition: color 150ms;
175
+ }
176
+
177
+ [data-slot='credit'] svg {
178
+ width: auto;
179
+ height: 1.125rem;
180
+ flex-shrink: 0;
181
+ color: #073b78;
182
+ }
183
+
184
+ .dark [data-slot='credit'] svg {
185
+ color: #ffffff;
186
+ }
187
+
188
+ [data-slot='credit'] a:hover,
189
+ [data-slot='credit'] a:focus-visible {
190
+ color: var(--foreground);
191
+ text-decoration: underline;
192
+ text-underline-offset: 4px;
193
+ }
194
+
195
+ [data-slot='credit'] strong {
196
+ font-weight: 600;
197
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"SearchTrigger.js","names":["_sfc_main","SearchTrigger_vue_vue_type_script_setup_true_lang_default","SearchTrigger_default"],"sources":["../../../src/starter-kit/widgets/SearchTrigger.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n formatKeyBinding,\n registerStarterKitSearchShortcut,\n requestStarterKitSearch,\n type StarterKitWidgets,\n} from '@alfakit/core'\nimport { SearchIcon } from '@lucide/vue'\nimport { computed, watch } from 'vue'\nimport { useHydrated } from '../../composables/use-hydrated'\n\n/**\n * The search field until the palette has loaded: the same look, from the shared prop\n * alone. Its key bindings and a click are remembered and open the palette once loaded.\n */\nconst props = defineProps<{ source: StarterKitWidgets; onLoad?: () => void }>()\n\nconst hydrated = useHydrated()\nconst search = computed(() => props.source.widgets.search)\nconst placeholder = computed(() => search.value?.placeholder ?? '')\nconst binding = computed(() => search.value?.keyBindings[0])\n\nif (typeof window !== 'undefined') {\n watch(\n () => [JSON.stringify(search.value?.keyBindings ?? ['mod+k']), placeholder.value] as const,\n ([keys, label], _old, onCleanup) =>\n onCleanup(\n registerStarterKitSearchShortcut(JSON.parse(keys) as string[], label, () =>\n props.onLoad?.(),\n ),\n ),\n { immediate: true },\n )\n}\n\nfunction request() {\n requestStarterKitSearch()\n props.onLoad?.()\n}\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"border-input bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 focus-visible:ring-ring/50 text-muted-foreground inline-flex size-8 h-8 shrink-0 items-center justify-center gap-2 rounded-md border px-0 text-sm font-normal shadow-xs outline-none focus-visible:ring-[3px] sm:w-56 sm:justify-start sm:px-2.5\"\n @pointerenter=\"props.onLoad?.()\"\n @click=\"request\"\n >\n <SearchIcon class=\"size-4\" aria-hidden=\"true\" />\n <span class=\"sr-only sm:not-sr-only sm:flex-1 sm:text-start\">{{ placeholder }}</span>\n <kbd\n v-if=\"hydrated && binding\"\n class=\"bg-muted hidden rounded px-1 font-mono text-[10px] sm:inline\"\n >{{ formatKeyBinding(binding) }}</kbd\n >\n </button>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"SearchTrigger.js","names":["_sfc_main","SearchTrigger_vue_vue_type_script_setup_true_lang_default","SearchTrigger_default"],"sources":["../../../src/starter-kit/widgets/SearchTrigger.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n formatKeyBinding,\n registerStarterKitSearchShortcut,\n requestStarterKitSearch,\n type StarterKitWidgets,\n} from '@alfakit/core'\nimport { SearchIcon } from '@lucide/vue'\nimport { computed, watch } from 'vue'\nimport { useHydrated } from '../../composables/use-hydrated'\n\n/**\n * The search field until the palette has loaded: the same look, from the shared prop\n * alone. Its key bindings and a click are remembered and open the palette once loaded.\n */\nconst props = defineProps<{ source: StarterKitWidgets; onLoad?: () => void }>()\n\nconst hydrated = useHydrated()\nconst search = computed(() => props.source.widgets.search)\nconst placeholder = computed(() => search.value?.placeholder ?? '')\nconst binding = computed(() => search.value?.keyBindings[0])\n\nif (typeof window !== 'undefined') {\n watch(\n () => [JSON.stringify(search.value?.keyBindings ?? ['mod+k']), placeholder.value] as const,\n ([keys, label], _old, onCleanup) =>\n onCleanup(\n registerStarterKitSearchShortcut(JSON.parse(keys) as string[], label, () =>\n props.onLoad?.(),\n ),\n ),\n { immediate: true },\n )\n}\n\nfunction request() {\n requestStarterKitSearch()\n props.onLoad?.()\n}\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"border-input bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 focus-visible:ring-ring/50 text-muted-foreground inline-flex size-8 h-8 shrink-0 items-center justify-center gap-2 rounded-md border px-0 text-sm font-normal shadow-xs outline-none focus-visible:ring-[3px] sm:w-56 sm:justify-start sm:px-2.5\"\n @pointerenter=\"props.onLoad?.()\"\n @click=\"request\"\n >\n <SearchIcon class=\"size-4\" aria-hidden=\"true\" />\n <span class=\"sr-only sm:not-sr-only sm:flex-1 sm:text-start\">{{ placeholder }}</span>\n <kbd\n v-if=\"hydrated && binding\"\n dir=\"ltr\"\n class=\"bg-muted hidden rounded px-1 font-mono text-[10px] sm:inline\"\n >{{ formatKeyBinding(binding) }}</kbd\n >\n </button>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"SearchTrigger.vue.d.ts","sourceRoot":"","sources":["../../../src/starter-kit/widgets/SearchTrigger.vue"],"names":[],"mappings":"AA2DA,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAA;AAKtB;;;GAGG;AACH,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;;AA+HtE,wBAMG"}
1
+ {"version":3,"file":"SearchTrigger.vue.d.ts","sourceRoot":"","sources":["../../../src/starter-kit/widgets/SearchTrigger.vue"],"names":[],"mappings":"AA4DA,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAA;AAKtB;;;GAGG;AACH,KAAK,WAAW,GAAG;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;;AAgItE,wBAMG"}
@@ -5,6 +5,7 @@ import { SearchIcon as m } from "@lucide/vue";
5
5
  //#region src/starter-kit/widgets/SearchTrigger.vue?vue&type=script&setup=true&lang.ts
6
6
  var h = { class: "sr-only sm:not-sr-only sm:flex-1 sm:text-start" }, g = {
7
7
  key: 0,
8
+ dir: "ltr",
8
9
  class: "bg-muted hidden rounded px-1 font-mono text-[10px] sm:inline"
9
10
  }, _ = /*@__PURE__*/ l({
10
11
  __name: "SearchTrigger",
@@ -1 +1 @@
1
- {"version":3,"file":"SearchTrigger.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","_hoisted_1","_hoisted_2","SearchTrigger_vue_vue_type_script_setup_true_lang_default","props","__props","hydrated","useHydrated","search","computed","placeholder","binding","watch","keys","label","onCleanup","registerStarterKitSearchShortcut","request","requestStarterKitSearch","openBlock","createElementBlock","_cache","createVNode","unref","SearchIcon","createElementVNode","toDisplayString","formatKeyBinding","createCommentVNode"],"sources":["../../../src/starter-kit/widgets/SearchTrigger.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n formatKeyBinding,\n registerStarterKitSearchShortcut,\n requestStarterKitSearch,\n type StarterKitWidgets,\n} from '@alfakit/core'\nimport { SearchIcon } from '@lucide/vue'\nimport { computed, watch } from 'vue'\nimport { useHydrated } from '../../composables/use-hydrated'\n\n/**\n * The search field until the palette has loaded: the same look, from the shared prop\n * alone. Its key bindings and a click are remembered and open the palette once loaded.\n */\nconst props = defineProps<{ source: StarterKitWidgets; onLoad?: () => void }>()\n\nconst hydrated = useHydrated()\nconst search = computed(() => props.source.widgets.search)\nconst placeholder = computed(() => search.value?.placeholder ?? '')\nconst binding = computed(() => search.value?.keyBindings[0])\n\nif (typeof window !== 'undefined') {\n watch(\n () => [JSON.stringify(search.value?.keyBindings ?? ['mod+k']), placeholder.value] as const,\n ([keys, label], _old, onCleanup) =>\n onCleanup(\n registerStarterKitSearchShortcut(JSON.parse(keys) as string[], label, () =>\n props.onLoad?.(),\n ),\n ),\n { immediate: true },\n )\n}\n\nfunction request() {\n requestStarterKitSearch()\n props.onLoad?.()\n}\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"border-input bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 focus-visible:ring-ring/50 text-muted-foreground inline-flex size-8 h-8 shrink-0 items-center justify-center gap-2 rounded-md border px-0 text-sm font-normal shadow-xs outline-none focus-visible:ring-[3px] sm:w-56 sm:justify-start sm:px-2.5\"\n @pointerenter=\"props.onLoad?.()\"\n @click=\"request\"\n >\n <SearchIcon class=\"size-4\" aria-hidden=\"true\" />\n <span class=\"sr-only sm:not-sr-only sm:flex-1 sm:text-start\">{{ placeholder }}</span>\n <kbd\n v-if=\"hydrated && binding\"\n class=\"bg-muted hidden rounded px-1 font-mono text-[10px] sm:inline\"\n >{{ formatKeyBinding(binding) }}</kbd\n >\n </button>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;EAeA,IAAMU,IAAQC,GAERC,IAAWC,EAAY,GACvBC,IAASC,QAAeL,EAAM,OAAO,QAAQ,MAAM,GACnDM,IAAcD,QAAeD,EAAO,OAAO,eAAe,EAAE,GAC5DG,IAAUF,QAAeD,EAAO,OAAO,YAAY,EAAE;EAE3D,AAAI,OAAO,SAAW,OACpBI,QACQ,CAAC,KAAK,UAAUJ,EAAO,OAAO,eAAe,CAAC,OAAO,CAAC,GAAGE,EAAY,KAAK,IAC/E,CAACG,GAAMC,IAAQ,GAAM,MACpBC,EACEC,EAAiC,KAAK,MAAMH,CAAI,GAAeC,SAC7DV,EAAM,SAAS,CACjB,CACF,GACF,EAAE,WAAW,GAAK,CACpB;EAGF,SAASa,IAAU;GAEjB,AADAC,EAAwB,GACxBd,EAAM,SAAS;EACjB;oBAIEV,EAAA,GAAAC,EAaS,UAAA;GAZP,MAAK;GACL,OAAM;GACL,gBAAY,AAAA0B,EAAA,QAAA,MAAEjB,EAAM,SAAM;GAC1B,SAAOa;;GAERrB,EAAgDC,EAAA2B,CAAA,GAAA;IAApC,OAAM;IAAS,eAAY;;GACvC1B,EAAqF,QAArFG,GAAqFF,EAArBW,EAAA,KAAW,GAAA,CAAA;GAEnEb,EAAAS,CAAA,KAAYK,EAAA,SADpBjB,EAAA,GAAAC,EAIC,OAJDO,GAICH,EADKF,EAAA8B,CAAA,CAAgB,CAAChB,EAAA,KAAO,CAAA,GAAA,CAAA,KAAAiB,EAAA,IAAA,EAAA"}
1
+ {"version":3,"file":"SearchTrigger.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","_hoisted_1","_hoisted_2","SearchTrigger_vue_vue_type_script_setup_true_lang_default","props","__props","hydrated","useHydrated","search","computed","placeholder","binding","watch","keys","label","onCleanup","registerStarterKitSearchShortcut","request","requestStarterKitSearch","openBlock","createElementBlock","_cache","createVNode","unref","SearchIcon","createElementVNode","toDisplayString","formatKeyBinding","createCommentVNode"],"sources":["../../../src/starter-kit/widgets/SearchTrigger.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n formatKeyBinding,\n registerStarterKitSearchShortcut,\n requestStarterKitSearch,\n type StarterKitWidgets,\n} from '@alfakit/core'\nimport { SearchIcon } from '@lucide/vue'\nimport { computed, watch } from 'vue'\nimport { useHydrated } from '../../composables/use-hydrated'\n\n/**\n * The search field until the palette has loaded: the same look, from the shared prop\n * alone. Its key bindings and a click are remembered and open the palette once loaded.\n */\nconst props = defineProps<{ source: StarterKitWidgets; onLoad?: () => void }>()\n\nconst hydrated = useHydrated()\nconst search = computed(() => props.source.widgets.search)\nconst placeholder = computed(() => search.value?.placeholder ?? '')\nconst binding = computed(() => search.value?.keyBindings[0])\n\nif (typeof window !== 'undefined') {\n watch(\n () => [JSON.stringify(search.value?.keyBindings ?? ['mod+k']), placeholder.value] as const,\n ([keys, label], _old, onCleanup) =>\n onCleanup(\n registerStarterKitSearchShortcut(JSON.parse(keys) as string[], label, () =>\n props.onLoad?.(),\n ),\n ),\n { immediate: true },\n )\n}\n\nfunction request() {\n requestStarterKitSearch()\n props.onLoad?.()\n}\n</script>\n\n<template>\n <button\n type=\"button\"\n class=\"border-input bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 focus-visible:ring-ring/50 text-muted-foreground inline-flex size-8 h-8 shrink-0 items-center justify-center gap-2 rounded-md border px-0 text-sm font-normal shadow-xs outline-none focus-visible:ring-[3px] sm:w-56 sm:justify-start sm:px-2.5\"\n @pointerenter=\"props.onLoad?.()\"\n @click=\"request\"\n >\n <SearchIcon class=\"size-4\" aria-hidden=\"true\" />\n <span class=\"sr-only sm:not-sr-only sm:flex-1 sm:text-start\">{{ placeholder }}</span>\n <kbd\n v-if=\"hydrated && binding\"\n dir=\"ltr\"\n class=\"bg-muted hidden rounded px-1 font-mono text-[10px] sm:inline\"\n >{{ formatKeyBinding(binding) }}</kbd\n >\n </button>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;EAeA,IAAMU,IAAQC,GAERC,IAAWC,EAAY,GACvBC,IAASC,QAAeL,EAAM,OAAO,QAAQ,MAAM,GACnDM,IAAcD,QAAeD,EAAO,OAAO,eAAe,EAAE,GAC5DG,IAAUF,QAAeD,EAAO,OAAO,YAAY,EAAE;EAE3D,AAAI,OAAO,SAAW,OACpBI,QACQ,CAAC,KAAK,UAAUJ,EAAO,OAAO,eAAe,CAAC,OAAO,CAAC,GAAGE,EAAY,KAAK,IAC/E,CAACG,GAAMC,IAAQ,GAAM,MACpBC,EACEC,EAAiC,KAAK,MAAMH,CAAI,GAAeC,SAC7DV,EAAM,SAAS,CACjB,CACF,GACF,EAAE,WAAW,GAAK,CACpB;EAGF,SAASa,IAAU;GAEjB,AADAC,EAAwB,GACxBd,EAAM,SAAS;EACjB;oBAIEV,EAAA,GAAAC,EAcS,UAAA;GAbP,MAAK;GACL,OAAM;GACL,gBAAY,AAAA0B,EAAA,QAAA,MAAEjB,EAAM,SAAM;GAC1B,SAAOa;;GAERrB,EAAgDC,EAAA2B,CAAA,GAAA;IAApC,OAAM;IAAS,eAAY;;GACvC1B,EAAqF,QAArFG,GAAqFF,EAArBW,EAAA,KAAW,GAAA,CAAA;GAEnEb,EAAAS,CAAA,KAAYK,EAAA,SADpBjB,EAAA,GAAAC,EAKC,OALDO,GAKCH,EADKF,EAAA8B,CAAA,CAAgB,CAAChB,EAAA,KAAO,CAAA,GAAA,CAAA,KAAAiB,EAAA,IAAA,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"TenantChooser.js","names":["_sfc_main","TenantChooser_vue_vue_type_script_setup_true_lang_default","TenantChooser_default"],"sources":["../../../src/starter-kit/widgets/TenantChooser.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { initials, tenantNameText } from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { ChevronsUpDownIcon, PlusIcon } from '@lucide/vue'\nimport { computed } from 'vue'\nimport NavLabel from '../../components/panel/NavLabel.vue'\nimport Avatar from '../../components/ui/Avatar.vue'\nimport AvatarFallback from '../../components/ui/AvatarFallback.vue'\nimport AvatarImage from '../../components/ui/AvatarImage.vue'\nimport DropdownMenu from '../../components/ui/DropdownMenu.vue'\nimport DropdownMenuContent from '../../components/ui/DropdownMenuContent.vue'\nimport DropdownMenuItem from '../../components/ui/DropdownMenuItem.vue'\nimport DropdownMenuLabel from '../../components/ui/DropdownMenuLabel.vue'\nimport DropdownMenuSeparator from '../../components/ui/DropdownMenuSeparator.vue'\nimport DropdownMenuTrigger from '../../components/ui/DropdownMenuTrigger.vue'\nimport { usePanel, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\n\n/** The user's tenants on a page outside the panel (no current tenant). */\nconst t = useT()\nconst panel = usePanel()\nconst tenancy = computed(() => panel.value.tenancy)\nconst label = computed(() => t('starter_kit.choose_tenant', {}, 'Choose a tenant'))\nconst visible = computed(\n () => !!tenancy.value && (tenancy.value.tenants.length > 0 || !!tenancy.value.registrationUrl),\n)\n</script>\n\n<template>\n <DropdownMenu v-if=\"tenancy && visible\">\n <DropdownMenuTrigger as-child>\n <button\n type=\"button\"\n data-slot=\"tenant-menu\"\n class=\"hover:bg-accent data-[state=open]:bg-accent inline-flex h-9 max-w-60 shrink-0 items-center gap-2 rounded-md px-2 text-sm font-medium\"\n >\n <span class=\"sr-only lg:not-sr-only lg:truncate\">{{ label }}</span>\n <Icon\n name=\"alfakit::panels.tenant-menu.toggle-button\"\n :fallback=\"ChevronsUpDownIcon\"\n class=\"text-muted-foreground size-4 shrink-0\"\n />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"min-w-56 rounded-lg\" side=\"bottom\" align=\"end\" :side-offset=\"4\">\n <DropdownMenuLabel v-if=\"tenancy.tenants.length > 0\" class=\"text-muted-foreground text-xs\">{{\n label\n }}</DropdownMenuLabel>\n <DropdownMenuItem\n v-for=\"tenant in tenancy.tenants\"\n :key=\"String(tenant.id)\"\n @select=\"router.visit(tenant.url)\"\n >\n <Avatar class=\"size-6 rounded-sm\">\n <AvatarImage v-if=\"tenant.avatar\" :src=\"tenant.avatar\" alt=\"\" />\n <AvatarFallback class=\"rounded-sm text-[10px]\">{{\n initials(tenantNameText(tenant))\n }}</AvatarFallback>\n </Avatar>\n <NavLabel class=\"flex-1 truncate\" :text=\"tenant.name\" :html=\"tenant.nameHtml\" />\n </DropdownMenuItem>\n <template v-if=\"tenancy.registrationUrl\">\n <DropdownMenuSeparator v-if=\"tenancy.tenants.length > 0\" />\n <DropdownMenuItem @select=\"router.visit(tenancy.registrationUrl!)\">\n <Icon name=\"alfakit::panels.tenant-menu.registration-button\" :fallback=\"PlusIcon\" />\n {{ t('tenancy.register', {}, 'New') }}\n </DropdownMenuItem>\n </template>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"TenantChooser.js","names":["_sfc_main","TenantChooser_vue_vue_type_script_setup_true_lang_default","TenantChooser_default"],"sources":["../../../src/starter-kit/widgets/TenantChooser.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { initials, tenantNameText } from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { ChevronsUpDownIcon, PlusIcon } from '@lucide/vue'\nimport { computed } from 'vue'\nimport NavLabel from '../../components/panel/NavLabel.vue'\nimport Avatar from '../../components/ui/Avatar.vue'\nimport AvatarFallback from '../../components/ui/AvatarFallback.vue'\nimport AvatarImage from '../../components/ui/AvatarImage.vue'\nimport DropdownMenu from '../../components/ui/DropdownMenu.vue'\nimport DropdownMenuContent from '../../components/ui/DropdownMenuContent.vue'\nimport DropdownMenuItem from '../../components/ui/DropdownMenuItem.vue'\nimport DropdownMenuLabel from '../../components/ui/DropdownMenuLabel.vue'\nimport DropdownMenuSeparator from '../../components/ui/DropdownMenuSeparator.vue'\nimport DropdownMenuTrigger from '../../components/ui/DropdownMenuTrigger.vue'\nimport { usePanel, useT } from '../../context'\nimport { Icon } from '../../lib/icons'\n\n/** The user's tenants on a page outside the panel (no current tenant). */\nconst t = useT()\nconst panel = usePanel()\nconst tenancy = computed(() => panel.value.tenancy)\nconst label = computed(() => t('starter_kit.choose_tenant', {}, 'Choose a tenant'))\nconst visible = computed(\n () => !!tenancy.value && (tenancy.value.tenants.length > 0 || !!tenancy.value.registrationUrl),\n)\n</script>\n\n<template>\n <DropdownMenu v-if=\"tenancy && visible\">\n <DropdownMenuTrigger as-child>\n <button\n type=\"button\"\n data-slot=\"tenant-menu\"\n class=\"hover:bg-accent data-[state=open]:bg-accent inline-flex h-9 max-w-60 shrink-0 items-center gap-2 rounded-md px-2 text-sm font-medium\"\n >\n <span class=\"sr-only lg:not-sr-only lg:truncate\">{{ label }}</span>\n <Icon\n name=\"alfakit::panels.tenant-menu.toggle-button\"\n :fallback=\"ChevronsUpDownIcon\"\n class=\"text-muted-foreground size-4 shrink-0\"\n />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent class=\"min-w-56 rounded-lg\" side=\"bottom\" align=\"end\" :side-offset=\"4\">\n <DropdownMenuLabel v-if=\"tenancy.tenants.length > 0\" class=\"text-muted-foreground text-xs\">{{\n label\n }}</DropdownMenuLabel>\n <DropdownMenuItem\n v-for=\"tenant in tenancy.tenants\"\n :key=\"String(tenant.id)\"\n @select=\"router.visit(tenant.url)\"\n >\n <Avatar class=\"size-6 rounded-sm\">\n <AvatarImage v-if=\"tenant.avatar\" :src=\"tenant.avatar\" alt=\"\" />\n <AvatarFallback class=\"rounded-sm text-[10px]\">{{\n initials(tenantNameText(tenant))\n }}</AvatarFallback>\n </Avatar>\n <NavLabel class=\"flex-1 truncate\" :text=\"tenant.name\" :html=\"tenant.nameHtml\" />\n </DropdownMenuItem>\n <template v-if=\"tenancy.registrationUrl\">\n <DropdownMenuSeparator v-if=\"tenancy.tenants.length > 0\" />\n <DropdownMenuItem @select=\"router.visit(tenancy.registrationUrl!)\">\n <Icon name=\"alfakit::panels.tenant-menu.registration-button\" :fallback=\"PlusIcon\" />\n {{ tenancy.registrationLabel ?? t('tenancy.register', {}, 'New') }}\n </DropdownMenuItem>\n </template>\n </DropdownMenuContent>\n </DropdownMenu>\n</template>\n"],"mappings":""}