@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.
- package/CHANGELOG.md +14 -0
- package/dist/app/components.d.ts.map +1 -1
- package/dist/app/components.js +1 -0
- package/dist/app/components.js.map +1 -1
- package/dist/components/actions/ActionModal.js.map +1 -1
- package/dist/components/actions/ActionModal.vue.d.ts.map +1 -1
- package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/dev-tools/DevToolsInspector.js.map +1 -1
- package/dist/components/dev-tools/DevToolsInspector.vue.d.ts.map +1 -1
- package/dist/components/dev-tools/DevToolsInspector.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/dev-tools/DevToolsInspector.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/CheckboxListField.js.map +1 -1
- package/dist/components/fields/CheckboxListField.vue.d.ts.map +1 -1
- package/dist/components/fields/CheckboxListField.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/fields/CheckboxListField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/DatePickerField.js.map +1 -1
- package/dist/components/fields/DatePickerField.vue.d.ts.map +1 -1
- package/dist/components/fields/DatePickerField.vue_vue_type_script_setup_true_lang.js +34 -32
- package/dist/components/fields/DatePickerField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/RichEditorSuggestions.js.map +1 -1
- package/dist/components/fields/RichEditorSuggestions.vue.d.ts +1 -1
- package/dist/components/fields/RichEditorSuggestions.vue.d.ts.map +1 -1
- package/dist/components/fields/RichEditorSuggestions.vue_vue_type_script_setup_true_lang.js +29 -23
- package/dist/components/fields/RichEditorSuggestions.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/RichEditorToolbarGroup.js.map +1 -1
- package/dist/components/fields/RichEditorToolbarGroup.vue.d.ts.map +1 -1
- package/dist/components/fields/RichEditorToolbarGroup.vue_vue_type_script_setup_true_lang.js +9 -4
- package/dist/components/fields/RichEditorToolbarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/file-manager/FileManagerView.js.map +1 -1
- package/dist/components/file-manager/FileManagerView.vue.d.ts.map +1 -1
- package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form/FormBlock.js.map +1 -1
- package/dist/components/form/FormBlock.vue.d.ts.map +1 -1
- package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js +79 -78
- package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/CalloutComponent.js.map +1 -1
- package/dist/components/layout/CalloutComponent.vue.d.ts.map +1 -1
- package/dist/components/layout/CalloutComponent.vue_vue_type_script_setup_true_lang.js +43 -39
- package/dist/components/layout/CalloutComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/EmptyStateComponent.js.map +1 -1
- package/dist/components/layout/EmptyStateComponent.vue.d.ts.map +1 -1
- package/dist/components/layout/EmptyStateComponent.vue_vue_type_script_setup_true_lang.js +29 -26
- package/dist/components/layout/EmptyStateComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/MixedContent.js.map +1 -1
- package/dist/components/layout/MixedContent.vue.d.ts +5 -3
- package/dist/components/layout/MixedContent.vue.d.ts.map +1 -1
- package/dist/components/layout/MixedContent.vue_vue_type_script_setup_true_lang.js +5 -4
- package/dist/components/layout/MixedContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/SectionComponent.js.map +1 -1
- package/dist/components/layout/SectionComponent.vue.d.ts.map +1 -1
- package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js +12 -8
- package/dist/components/layout/SectionComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/notifications/NotificationsMenu.js.map +1 -1
- package/dist/components/notifications/NotificationsMenu.vue.d.ts.map +1 -1
- package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js +133 -104
- package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/BottomNav.js.map +1 -1
- package/dist/components/panel/BottomNav.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/panel/BottomNav.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/KeyboardShortcuts.js.map +1 -1
- package/dist/components/panel/KeyboardShortcuts.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/panel/KeyboardShortcuts.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/NavGroup.js.map +1 -1
- package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/panel/NavGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/NavItem.js.map +1 -1
- package/dist/components/panel/NavItem.vue.d.ts.map +1 -1
- package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/panel/NavItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/NavSubItem.js.map +1 -1
- package/dist/components/panel/NavSubItem.vue.d.ts.map +1 -1
- package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/panel/NavSubItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/ShortcutsOverlay.js.map +1 -1
- package/dist/components/panel/ShortcutsOverlay.vue.d.ts.map +1 -1
- package/dist/components/panel/ShortcutsOverlay.vue_vue_type_script_setup_true_lang.js +20 -19
- package/dist/components/panel/ShortcutsOverlay.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/ColumnManager.js.map +1 -1
- package/dist/components/table/ColumnManager.vue.d.ts.map +1 -1
- package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/components/table/ColumnManager.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/Spreadsheet.js.map +1 -1
- package/dist/components/table/Spreadsheet.vue.d.ts.map +1 -1
- package/dist/components/table/Spreadsheet.vue_vue_type_script_setup_true_lang.js +37 -33
- package/dist/components/table/Spreadsheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/translation-manager/TranslationManagerView.js.map +1 -1
- package/dist/components/translation-manager/TranslationManagerView.vue.d.ts.map +1 -1
- package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/translation-manager/TranslationManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/ui/SidebarMenuButton.js.map +1 -1
- package/dist/components/ui/SidebarMenuButton.vue.d.ts.map +1 -1
- package/dist/components/ui/SidebarMenuButton.vue_vue_type_script_setup_true_lang.js +12 -12
- package/dist/components/ui/SidebarMenuButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/ui/TooltipTrigger.js.map +1 -1
- package/dist/components/ui/TooltipTrigger.vue.d.ts +2 -2
- package/dist/components/ui/TooltipTrigger.vue.d.ts.map +1 -1
- package/dist/components/ui/TooltipTrigger.vue_vue_type_script_setup_true_lang.js +10 -7
- package/dist/components/ui/TooltipTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/widgets/StatCard.js.map +1 -1
- package/dist/components/widgets/StatCard.vue.d.ts.map +1 -1
- package/dist/components/widgets/StatCard.vue_vue_type_script_setup_true_lang.js +30 -30
- package/dist/components/widgets/StatCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/eject-manifest.json +2 -2
- package/dist/layouts/TopNavLayout.js.map +1 -1
- package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/layouts/TopNavLayout.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/layouts/TopNavMenu.js.map +1 -1
- package/dist/layouts/TopNavMenu.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/layouts/TopNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/pages/AlfakitPage.js.map +1 -1
- package/dist/pages/AlfakitPage.vue.d.ts.map +1 -1
- package/dist/pages/AlfakitPage.vue_vue_type_script_setup_true_lang.js +16 -19
- package/dist/pages/AlfakitPage.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/standalone/AlfakitComponent.js.map +1 -1
- package/dist/standalone/AlfakitComponent.vue.d.ts.map +1 -1
- package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js +29 -24
- package/dist/standalone/AlfakitComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/standalone/runtime.d.ts.map +1 -1
- package/dist/standalone/runtime.js +25 -25
- package/dist/standalone/runtime.js.map +1 -1
- package/dist/standalone.css +12 -7
- package/dist/starter-kit/AlfakitStarterKitRoot.js.map +1 -1
- package/dist/starter-kit/AlfakitStarterKitRoot.vue.d.ts.map +1 -1
- package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js +25 -21
- package/dist/starter-kit/AlfakitStarterKitRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/starter-kit/navigation.d.ts +6 -1
- package/dist/starter-kit/navigation.d.ts.map +1 -1
- package/dist/starter-kit/navigation.js +11 -10
- package/dist/starter-kit/navigation.js.map +1 -1
- package/dist/styles.css +2 -1
- package/dist/themes.css +4 -0
- package/package.json +2 -2
- package/src/app/components.ts +3 -0
- package/src/components/actions/ActionModal.vue +2 -0
- package/src/components/dev-tools/DevToolsInspector.vue +1 -1
- package/src/components/fields/CheckboxListField.vue +2 -2
- package/src/components/fields/DatePickerField.vue +1 -0
- package/src/components/fields/RichEditorSuggestions.vue +13 -6
- package/src/components/fields/RichEditorToolbarGroup.vue +16 -1
- package/src/components/file-manager/FileManagerView.vue +3 -1
- package/src/components/form/FormBlock.vue +15 -2
- package/src/components/layout/CalloutComponent.vue +15 -2
- package/src/components/layout/EmptyStateComponent.vue +10 -1
- package/src/components/layout/MixedContent.vue +12 -4
- package/src/components/layout/SectionComponent.vue +20 -4
- package/src/components/notifications/NotificationsMenu.vue +45 -1
- package/src/components/panel/BottomNav.vue +2 -2
- package/src/components/panel/KeyboardShortcuts.vue +1 -1
- package/src/components/panel/NavGroup.vue +3 -3
- package/src/components/panel/NavItem.vue +5 -1
- package/src/components/panel/NavSubItem.vue +5 -1
- package/src/components/panel/ShortcutsOverlay.vue +27 -22
- package/src/components/table/ColumnManager.vue +6 -4
- package/src/components/table/Spreadsheet.vue +9 -4
- package/src/components/translation-manager/TranslationManagerView.vue +1 -1
- package/src/components/ui/SidebarMenuButton.vue +6 -0
- package/src/components/ui/TooltipTrigger.vue +4 -1
- package/src/components/widgets/StatCard.vue +6 -3
- package/src/layouts/TopNavLayout.vue +2 -2
- package/src/layouts/TopNavMenu.vue +1 -1
- package/src/pages/AlfakitPage.vue +13 -3
- package/src/standalone/AlfakitComponent.vue +16 -5
- package/src/standalone/runtime.ts +3 -0
- package/src/starter-kit/AlfakitStarterKitRoot.vue +7 -0
- package/src/starter-kit/navigation.ts +12 -1
- package/src/styles.css +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @alfakit/vue
|
|
2
2
|
|
|
3
|
+
## 0.1.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Back after a save shows fresh data; parent navigation items expand; custom page components render once with live props; no extraneous-attribute warning on `AppPage`; `useAlfakitNavigation().userMenuItems` for starter kits; push toggle in `<AlfakitNotifications />`; rich editor focus, form-context actions and column manager Reset fixes.
|
|
8
|
+
|
|
9
|
+
## 0.1.9
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Row action modals work on every list tab; starter kits: the debug panel, "G then D" to the app dashboard and badge contrast; two standalone forms on a page get their own field ids; an `<AlfakitComponent>` in a panel page posts to its own endpoint; tooltips keep the button's `data-slot`; navigation items keyed by URL; modal headers leave room for the close button.
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @alfakit/core@0.1.9
|
|
16
|
+
|
|
3
17
|
## 0.1.8
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/app/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAA;AAEzF,OAAO,EAAgC,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAA;AAOnF;;;;GAIG;AAEH,0DAA0D;AAC1D,wBAAgB,UAAU,IAAI,WAAW,CAAC,UAAU,GAAG,SAAS,CAAC,CAOhE;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC,YAAY,GAAG,SAAS,CAAC,CAI/E;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO;;
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/app/components.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAA;AAEzF,OAAO,EAAgC,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAA;AAOnF;;;;GAIG;AAEH,0DAA0D;AAC1D,wBAAgB,UAAU,IAAI,WAAW,CAAC,UAAU,GAAG,SAAS,CAAC,CAOhE;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC,YAAY,GAAG,SAAS,CAAC,CAI/E;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO;;yPAyBlB,CAAA;AAEF,yFAAyF;AACzF,eAAO,MAAM,SAAS;IAGlB,yFAAyF;;;;;;cAE/C,QAAQ,CAAC,OAAO,CAAC;;;;;;;;IAF3D,yFAAyF;;;;;;cAE/C,QAAQ,CAAC,OAAO,CAAC;;;;;4EAmB7D,CAAA;AAoBF,8FAA8F;AAC9F,eAAO,MAAM,QAAQ;;;;;;cAd2B,QAAQ,CAAC,OAAO,CAAC;;;;;;;;;;;cAAjB,QAAQ,CAAC,OAAO,CAAC;;;;;;4EAcH,CAAA;AAE9D,+FAA+F;AAC/F,eAAO,MAAM,SAAS;;;;;;cAjB0B,QAAQ,CAAC,OAAO,CAAC;;;;;;;;;;;cAAjB,QAAQ,CAAC,OAAO,CAAC;;;;;;4EAiBC,CAAA;AAElE,4FAA4F;AAC5F,eAAO,MAAM,YAAY;;;;;;cApBuB,QAAQ,CAAC,OAAO,CAAC;;;;;;;;;;;cAAjB,QAAQ,CAAC,OAAO,CAAC;;;;;;4EAoBa,CAAA;AAE9E,qDAAqD;AACrD,eAAO,MAAM,WAAW;;cAGQ,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;;;;cACf,QAAQ,CAAC,OAAO,CAAC;;;;;;;cAD/B,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;;;;cACf,QAAQ,CAAC,OAAO,CAAC;;;;;;4EAa7D,CAAA"}
|
package/dist/app/components.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","names":["PageShell","ContentBlockRenderer","ContentBlockRenderer_default","PageShell_default","useAppPage","props","useAlfakitProps","page","usePageSchema","computed","resolveLazyComponents","usePageBlock","block","key","AppPage","defineComponent","panel","usePanel","providePageActionContext","h","Head","slots","PageBlock","item","cn","namedBlock","prefix","fallbackKey","PageForm","PageTable","PageInfolist","PageWidgets"],"sources":["../../src/app/components.ts"],"sourcesContent":["import { resolveLazyComponents, type ContentBlock, type PageSchema } from '@alfakit/core'\nimport { Head } from '@inertiajs/vue3'\nimport { computed, defineComponent, h, type ComputedRef, type PropType } from 'vue'\nimport { providePageActionContext } from '../components/actions/action-context'\nimport { useAlfakitProps, usePageSchema, usePanel } from '../context'\nimport { cn } from '../lib/utils'\nimport ContentBlockRenderer from '../pages/ContentBlockRenderer.vue'\nimport PageShell from '../pages/PageShell.vue'\n\n/**\n * Building blocks for custom page components: the page shell with the panel layout, and the\n * page's PHP-defined pieces rendered by name, with live fields, actions, uploads and polling\n * working exactly as on schema-driven pages.\n */\n\n/** The current page with its lazy components resolved. */\nexport function useAppPage(): ComputedRef<PageSchema | undefined> {\n const props = useAlfakitProps()\n const page = usePageSchema()\n\n return computed(() =>\n page.value ? resolveLazyComponents(page.value, props.value.alfakitLazy) : undefined,\n )\n}\n\n/** A content block of the page by key (`form:customer`, `table`, `headerWidgets`…). */\nexport function usePageBlock(key: string): ComputedRef<ContentBlock | undefined> {\n const page = useAppPage()\n\n return computed(() => page.value?.content.find((block) => block.key === key))\n}\n\n/**\n * The page's layout (sidebar and topbar, `fullscreen`…), heading, header actions and\n * document title around a custom component: `<AppPage>…</AppPage>`.\n */\nexport const AppPage = defineComponent({\n name: 'AppPage',\n setup(_, { slots }) {\n const page = useAppPage()\n const panel = usePanel()\n\n providePageActionContext({\n get token() {\n return page.value?.token ?? ''\n },\n component: 'page',\n })\n\n return () => {\n if (!page.value) return slots.default?.()\n\n return [\n h(Head, { title: `${page.value.title} - ${panel.value.brandName}` }),\n h(PageShell, { page: page.value }, { default: () => slots.default?.() }),\n ]\n }\n },\n})\n\n/** Render any content block of the page by key; the `fallback` slot when it has none. */\nexport const PageBlock = defineComponent({\n name: 'PageBlock',\n props: {\n /** `form:customer`, `table:products`, `infolist:summary`, `form`, `table`, `content`… */\n name: { type: String, required: true },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { slots }) {\n const page = useAppPage()\n const block = computed(() => page.value?.content.find((item) => item.key === props.name))\n\n return () =>\n block.value\n ? h(\n 'div',\n {\n 'data-slot': 'page-block',\n 'data-block': props.name,\n class: cn('min-w-0', props.class as string | undefined),\n },\n [h(ContentBlockRenderer, { block: block.value })],\n )\n : slots.fallback?.()\n },\n})\n\nfunction namedBlock(name: string, prefix: string, fallbackKey: string) {\n return defineComponent({\n name,\n props: {\n name: { type: String, default: undefined },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { slots }) {\n return () =>\n h(\n PageBlock,\n { name: props.name ? `${prefix}:${props.name}` : fallbackKey, class: props.class },\n slots,\n )\n },\n })\n}\n\n/** A form defined by `{name}Form(Schema $schema)` (or the page's `form()` without a name). */\nexport const PageForm = namedBlock('PageForm', 'form', 'form')\n\n/** A table defined by `{name}Table(Table $table)` (or the page's `table()` without a name). */\nexport const PageTable = namedBlock('PageTable', 'table', 'table')\n\n/** An infolist defined by `{name}Infolist(Schema $schema)` (or the page's `infolist()`). */\nexport const PageInfolist = namedBlock('PageInfolist', 'infolist', 'infolist')\n\n/** The page's header (default) or footer widgets. */\nexport const PageWidgets = defineComponent({\n name: 'PageWidgets',\n props: {\n position: { type: String as PropType<'header' | 'footer'>, default: 'header' },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { slots }) {\n return () =>\n h(\n PageBlock,\n {\n name: props.position === 'footer' ? 'footerWidgets' : 'headerWidgets',\n class: props.class,\n },\n slots,\n )\n },\n})\n"],"mappings":";;;;;;;;;AAgBA,SAAgBI,IAAkD;CAChE,IAAMC,IAAQC,EAAgB,GACxBC,IAAOC,EAAc;CAE3B,OAAOC,QACLF,EAAK,QAAQG,EAAsBH,EAAK,OAAOF,EAAM,MAAM,WAAW,IAAI,KAAA,CAC5E;AACF;AAGA,SAAgBM,EAAa,GAAoD;CAC/E,IAAMJ,IAAOH,EAAW;CAExB,OAAOK,QAAeF,EAAK,OAAO,QAAQ,MAAM,MAAUK,EAAM,QAAQC,CAAG,CAAC;AAC9E;AAMA,IAAaC,IAAUC,EAAgB;CACrC,MAAM;
|
|
1
|
+
{"version":3,"file":"components.js","names":["PageShell","ContentBlockRenderer","ContentBlockRenderer_default","PageShell_default","useAppPage","props","useAlfakitProps","page","usePageSchema","computed","resolveLazyComponents","usePageBlock","block","key","AppPage","defineComponent","panel","usePanel","providePageActionContext","h","Head","slots","PageBlock","item","cn","namedBlock","prefix","fallbackKey","PageForm","PageTable","PageInfolist","PageWidgets"],"sources":["../../src/app/components.ts"],"sourcesContent":["import { resolveLazyComponents, type ContentBlock, type PageSchema } from '@alfakit/core'\nimport { Head } from '@inertiajs/vue3'\nimport { computed, defineComponent, h, type ComputedRef, type PropType } from 'vue'\nimport { providePageActionContext } from '../components/actions/action-context'\nimport { useAlfakitProps, usePageSchema, usePanel } from '../context'\nimport { cn } from '../lib/utils'\nimport ContentBlockRenderer from '../pages/ContentBlockRenderer.vue'\nimport PageShell from '../pages/PageShell.vue'\n\n/**\n * Building blocks for custom page components: the page shell with the panel layout, and the\n * page's PHP-defined pieces rendered by name, with live fields, actions, uploads and polling\n * working exactly as on schema-driven pages.\n */\n\n/** The current page with its lazy components resolved. */\nexport function useAppPage(): ComputedRef<PageSchema | undefined> {\n const props = useAlfakitProps()\n const page = usePageSchema()\n\n return computed(() =>\n page.value ? resolveLazyComponents(page.value, props.value.alfakitLazy) : undefined,\n )\n}\n\n/** A content block of the page by key (`form:customer`, `table`, `headerWidgets`…). */\nexport function usePageBlock(key: string): ComputedRef<ContentBlock | undefined> {\n const page = useAppPage()\n\n return computed(() => page.value?.content.find((block) => block.key === key))\n}\n\n/**\n * The page's layout (sidebar and topbar, `fullscreen`…), heading, header actions and\n * document title around a custom component: `<AppPage>…</AppPage>`.\n */\nexport const AppPage = defineComponent({\n name: 'AppPage',\n // The page component's undeclared Inertia props fall through to here; AppPage takes no\n // HTML attributes and renders several root nodes.\n inheritAttrs: false,\n setup(_, { slots }) {\n const page = useAppPage()\n const panel = usePanel()\n\n providePageActionContext({\n get token() {\n return page.value?.token ?? ''\n },\n component: 'page',\n })\n\n return () => {\n if (!page.value) return slots.default?.()\n\n return [\n h(Head, { title: `${page.value.title} - ${panel.value.brandName}` }),\n h(PageShell, { page: page.value }, { default: () => slots.default?.() }),\n ]\n }\n },\n})\n\n/** Render any content block of the page by key; the `fallback` slot when it has none. */\nexport const PageBlock = defineComponent({\n name: 'PageBlock',\n props: {\n /** `form:customer`, `table:products`, `infolist:summary`, `form`, `table`, `content`… */\n name: { type: String, required: true },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { slots }) {\n const page = useAppPage()\n const block = computed(() => page.value?.content.find((item) => item.key === props.name))\n\n return () =>\n block.value\n ? h(\n 'div',\n {\n 'data-slot': 'page-block',\n 'data-block': props.name,\n class: cn('min-w-0', props.class as string | undefined),\n },\n [h(ContentBlockRenderer, { block: block.value })],\n )\n : slots.fallback?.()\n },\n})\n\nfunction namedBlock(name: string, prefix: string, fallbackKey: string) {\n return defineComponent({\n name,\n props: {\n name: { type: String, default: undefined },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { slots }) {\n return () =>\n h(\n PageBlock,\n { name: props.name ? `${prefix}:${props.name}` : fallbackKey, class: props.class },\n slots,\n )\n },\n })\n}\n\n/** A form defined by `{name}Form(Schema $schema)` (or the page's `form()` without a name). */\nexport const PageForm = namedBlock('PageForm', 'form', 'form')\n\n/** A table defined by `{name}Table(Table $table)` (or the page's `table()` without a name). */\nexport const PageTable = namedBlock('PageTable', 'table', 'table')\n\n/** An infolist defined by `{name}Infolist(Schema $schema)` (or the page's `infolist()`). */\nexport const PageInfolist = namedBlock('PageInfolist', 'infolist', 'infolist')\n\n/** The page's header (default) or footer widgets. */\nexport const PageWidgets = defineComponent({\n name: 'PageWidgets',\n props: {\n position: { type: String as PropType<'header' | 'footer'>, default: 'header' },\n class: { type: [String, Array, Object] as PropType<unknown>, default: undefined },\n },\n setup(props, { slots }) {\n return () =>\n h(\n PageBlock,\n {\n name: props.position === 'footer' ? 'footerWidgets' : 'headerWidgets',\n class: props.class,\n },\n slots,\n )\n },\n})\n"],"mappings":";;;;;;;;;AAgBA,SAAgBI,IAAkD;CAChE,IAAMC,IAAQC,EAAgB,GACxBC,IAAOC,EAAc;CAE3B,OAAOC,QACLF,EAAK,QAAQG,EAAsBH,EAAK,OAAOF,EAAM,MAAM,WAAW,IAAI,KAAA,CAC5E;AACF;AAGA,SAAgBM,EAAa,GAAoD;CAC/E,IAAMJ,IAAOH,EAAW;CAExB,OAAOK,QAAeF,EAAK,OAAO,QAAQ,MAAM,MAAUK,EAAM,QAAQC,CAAG,CAAC;AAC9E;AAMA,IAAaC,IAAUC,EAAgB;CACrC,MAAM;CAGN,cAAc;CACd,MAAM,GAAG,EAAE,YAAS;EAClB,IAAMR,IAAOH,EAAW,GAClBY,IAAQC,EAAS;EASvB,OAPAC,EAAyB;GACvB,IAAI,QAAQ;IACV,OAAOX,EAAK,OAAO,SAAS;GAC9B;GACA,WAAW;EACb,CAAC,SAGMA,EAAK,QAEH,CACLY,EAAEC,GAAM,EAAE,OAAO,GAAGb,EAAK,MAAM,MAAM,KAAKS,EAAM,MAAM,YAAY,CAAC,GACnEG,EAAEnB,GAAW,EAAE,MAAMO,EAAK,MAAM,GAAG,EAAE,eAAec,EAAM,UAAU,EAAE,CAAC,CACzE,IALwBA,EAAM,UAAU;CAO5C;AACF,CAAC,GAGYC,IAAYP,EAAgB;CACvC,MAAM;CACN,OAAO;EAEL,MAAM;GAAE,MAAM;GAAQ,UAAU;EAAK;EACrC,OAAO;GAAE,MAAM;IAAC;IAAQ;IAAO;GAAM;GAAwB,SAAS,KAAA;EAAU;CAClF;CACA,MAAM,GAAO,EAAE,YAAS;EACtB,IAAMR,IAAOH,EAAW,GAClBQ,IAAQH,QAAeF,EAAK,OAAO,QAAQ,MAAM,MAASgB,EAAK,QAAQlB,EAAM,IAAI,CAAC;EAExF,aACEO,EAAM,QACFO,EACE,OACA;GACE,aAAa;GACb,cAAcd,EAAM;GACpB,OAAOmB,EAAG,WAAWnB,EAAM,KAA2B;EACxD,GACA,CAACc,EAAElB,GAAsB,EAAE,OAAOW,EAAM,MAAM,CAAC,CAAC,CAClD,IACAS,EAAM,WAAW;CACzB;AACF,CAAC;AAED,SAASI,EAAW,GAAc,GAAgB,GAAqB;CACrE,OAAOV,EAAgB;EACrB;EACA,OAAO;GACL,MAAM;IAAE,MAAM;IAAQ,SAAS,KAAA;GAAU;GACzC,OAAO;IAAE,MAAM;KAAC;KAAQ;KAAO;IAAM;IAAwB,SAAS,KAAA;GAAU;EAClF;EACA,MAAM,GAAO,EAAE,YAAS;GACtB,aACEI,EACEG,GACA;IAAE,MAAMjB,EAAM,OAAO,GAAGqB,EAAO,GAAGrB,EAAM,SAASsB;IAAa,OAAOtB,EAAM;GAAM,GACjFgB,CACF;EACJ;CACF,CAAC;AACH;AAGA,IAAaO,IAAWH,EAAW,YAAY,QAAQ,MAAM,GAGhDI,IAAYJ,EAAW,aAAa,SAAS,OAAO,GAGpDK,IAAeL,EAAW,gBAAgB,YAAY,UAAU,GAGhEM,IAAchB,EAAgB;CACzC,MAAM;CACN,OAAO;EACL,UAAU;GAAE,MAAM;GAAyC,SAAS;EAAS;EAC7E,OAAO;GAAE,MAAM;IAAC;IAAQ;IAAO;GAAM;GAAwB,SAAS,KAAA;EAAU;CAClF;CACA,MAAM,GAAO,EAAE,YAAS;EACtB,aACEI,EACEG,GACA;GACE,MAAMjB,EAAM,aAAa,WAAW,kBAAkB;GACtD,OAAOA,EAAM;EACf,GACAgB,CACF;CACJ;AACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionModal.js","names":["_sfc_main","ActionModal_vue_vue_type_script_setup_true_lang_default","ActionModal_default"],"sources":["../../../src/components/actions/ActionModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { OpenModal } from '@alfakit/core'\nimport {\n actionFormComponent,\n formIdPrefix,\n actionFormParams,\n confirmModalClose,\n FormStore,\n guardModalUnload,\n isModalSubmitVisible,\n modalFooterAlignment,\n nestedActionContext,\n PASSWORD_CONFIRMATION_INPUT,\n scheduleAutofocus,\n slideOverSide,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { computed, nextTick, onMounted, onScopeDispose, ref, useId, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useDirection, usePanel, useT } from '../../context'\nimport {\n colorClass,\n iconBackgroundColorClasses,\n outlineButtonColorClasses,\n solidButtonColorClasses,\n} from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { provideForm } from '../form/form-context'\nimport Slot from '../panel/Slot.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport Button from '../ui/Button.vue'\nimport Dialog from '../ui/Dialog.vue'\nimport DialogContent from '../ui/DialogContent.vue'\nimport DialogDescription from '../ui/DialogDescription.vue'\nimport DialogFooter from '../ui/DialogFooter.vue'\nimport DialogHeader from '../ui/DialogHeader.vue'\nimport DialogTitle from '../ui/DialogTitle.vue'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetDescription from '../ui/SheetDescription.vue'\nimport SheetFooter from '../ui/SheetFooter.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport ActionList from './ActionList.vue'\nimport ActionModalPassword from './ActionModalPassword.vue'\nimport { showToast } from '../notifications/flash-toasts'\n\nconst WIDTHS: Record<string, string> = {\n '3xs': 'sm:max-w-3xs',\n '2xs': 'sm:max-w-2xs',\n xs: 'sm:max-w-xs',\n sm: 'sm:max-w-sm',\n md: 'sm:max-w-md',\n lg: 'sm:max-w-lg',\n xl: 'sm:max-w-xl',\n '2xl': 'sm:max-w-2xl',\n '3xl': 'sm:max-w-3xl',\n '4xl': 'sm:max-w-4xl',\n '5xl': 'sm:max-w-5xl',\n '6xl': 'sm:max-w-6xl',\n '7xl': 'sm:max-w-7xl',\n none: 'sm:max-w-none',\n min: 'sm:max-w-min',\n max: 'sm:max-w-max',\n fit: 'sm:max-w-fit',\n prose: 'sm:max-w-prose',\n container: 'sm:container',\n 'screen-sm': 'sm:max-w-(--breakpoint-sm)',\n 'screen-md': 'sm:max-w-(--breakpoint-md)',\n 'screen-lg': 'sm:max-w-(--breakpoint-lg)',\n 'screen-xl': 'sm:max-w-(--breakpoint-xl)',\n 'screen-2xl': 'sm:max-w-(--breakpoint-2xl)',\n full: 'sm:max-w-[calc(100%-2rem)]',\n screen: 'sm:max-w-[calc(100%-2rem)] h-[calc(100%-2rem)]',\n}\n\nconst FOOTER_JUSTIFY: Record<string, string> = {\n start: 'sm:justify-start',\n center: 'sm:justify-center',\n end: 'sm:justify-end',\n between: 'sm:justify-between',\n}\n\nconst props = withDefaults(defineProps<{ modal: OpenModal; hidden?: boolean }>(), {\n hidden: false,\n})\n\nconst runner = useActionRunner()\nconst panel = usePanel()\nconst direction = useDirection()\nconst t = useT()\n\nconst action = props.modal.action\nconst context = props.modal.context\nconst schema = computed(() => props.modal.modal)\n\nconst form = (() => {\n if (!schema.value.form) {\n return null\n }\n\n return new FormStore(schema.value.form, {\n token: context.token,\n component: actionFormComponent(action, context),\n // Own field ids: the modal opens over a form whose fields may share names.\n idPrefix: formIdPrefix(actionFormComponent(action, context)),\n record: context.record ?? null,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n params: actionFormParams(context),\n })\n})()\n\nif (form) {\n provideForm(form)\n}\n\nconst formState = form ? useStore(form.store) : null\n\nwatch(\n () => props.modal.errors,\n (errors) => form?.setErrors(errors),\n { immediate: true },\n)\n\nonScopeDispose(() => form?.destroy())\n\n// Nested actions read this form (`$mountedActions`, `getRawData()`) and write into it\n// (`fillData()`).\nif (form) {\n onScopeDispose(runner.registerModalForm(action, context, form))\n}\n\n// `extraModalWindowAttributes()`: `class` joins the window's classes.\nconst windowClass = computed(() => schema.value.windowAttributes?.class as string | undefined)\nconst windowAttributes = computed(() => {\n const { class: _class, ...rest } = schema.value.windowAttributes ?? {}\n\n return rest\n})\n\n// `extraModalOverlayAttributes()`: the backdrop is the content's previous sibling.\nconst modalId = useId()\n\n// A marker inside the content finds the window and its backdrop (the dialog primitives\n// render through a portal and don't pass other attributes on).\nconst setAttributes = (element: Element, attributes: Record<string, unknown>) => {\n for (const [name, value] of Object.entries(attributes)) {\n if (value === null || value === undefined || value === false) continue\n\n if (name === 'class') {\n element.classList.add(...String(value).split(/\\s+/).filter(Boolean))\n } else {\n element.setAttribute(name, value === true ? '' : String(value))\n }\n }\n}\n\nconst applyOverlayAttributes = () => {\n if (props.hidden || typeof document === 'undefined') return\n\n const element = document\n .querySelector(`[data-alfakit-modal=\"${modalId}\"]`)\n ?.closest('[role=\"dialog\"]')\n const overlay = element?.previousElementSibling\n\n if (element) setAttributes(element, windowAttributes.value)\n\n if (overlay?.getAttribute('data-slot')?.endsWith('-overlay') && schema.value.overlayAttributes) {\n setAttributes(overlay, schema.value.overlayAttributes)\n }\n}\n\nonMounted(() => void nextTick(applyOverlayAttributes))\nwatch(\n () => props.hidden,\n () => void nextTick(applyOverlayAttributes),\n { flush: 'post' },\n)\n\nconst footerJustify = computed(() => FOOTER_JUSTIFY[modalFooterAlignment(schema.value)])\nconst footerActionsClass = computed(() =>\n modalFooterAlignment(schema.value) === 'end' ? 'sm:me-auto' : undefined,\n)\nconst side = computed(() => slideOverSide(schema.value.slideOverPosition, direction.value))\n\n// A wizard form reports its step, so the submit button waits for the last one.\nconst progress = form ? useStore(wizardProgressStore(form)) : null\nconst submitVisible = computed(() => isModalSubmitVisible(schema.value, progress?.value))\n\nconst password = ref('')\nconst passwordError = computed(() => props.modal.errors[PASSWORD_CONFIRMATION_INPUT]?.[0])\nconst footerContext = nestedActionContext(context, action)\n\nconst run = (createAnother: boolean) => {\n // A click that blurred a live field started a refresh: send the state it returns.\n if (form) {\n form.whenSettled(() => execute(createAnother))\n } else {\n execute(createAnother)\n }\n}\n\nconst execute = (createAnother: boolean) => {\n const values = form?.state.values ?? {}\n const options = {\n ...(schema.value.passwordConfirmation ? { password: password.value } : {}),\n ...(createAnother ? { createAnother: true } : {}),\n }\n\n if (Object.keys(options).length > 0) {\n runner.execute(action, context, values, options)\n } else {\n runner.execute(action, context, values)\n }\n}\nconst submit = () => run(false)\n// \"Create & create another\": the runner reloads the modal, and its fresh form fills this one.\nconst submitAnother = () => run(true)\n\nwatch(\n () => schema.value.form,\n (payload, previous) => {\n if (payload && payload !== previous) form?.fill(payload)\n },\n)\n\n// \"Create & create another\": back to the `autofocus()` field of the fresh form.\nwatch(\n () => props.modal.refocus,\n (refocus, _previous, onCleanup) => {\n const components = schema.value.form?.components\n\n if (!refocus || !components) return\n\n onCleanup(\n scheduleAutofocus(() => document.getElementById(`action-form-${action.name}`), components),\n )\n },\n)\n\n// Dismissing the modal (not submitting it): `cancelParentActionsOnClose()` applies.\nconst close = () => runner.cancelModal(action.name)\nconst unsavedMessage = t('unsaved_changes_close', {}, 'You have unsaved changes. Close anyway?')\n// Cancel, Escape, clicking away and the close button ask first when the form changed.\nconst requestClose = () => {\n if (confirmModalClose(schema.value, form, unsavedMessage)) close()\n}\nonScopeDispose(guardModalUnload(schema.value, form, unsavedMessage))\nconst cancelClass = computed(() =>\n schema.value.cancelColor ? colorClass(outlineButtonColorClasses, schema.value.cancelColor) : '',\n)\n// `createAnotherAction()`: the \"Create & create another\" button's colour.\nconst createAnotherClass = computed(() =>\n schema.value.createAnotherColor\n ? colorClass(outlineButtonColorClasses, schema.value.createAnotherColor)\n : '',\n)\n// Every dialog needs an accessible name: without a heading it stays visually hidden.\nconst title = computed(() => schema.value.heading ?? action.label ?? t('actions', {}, 'Actions'))\n\nconst onOpenChange = (open: boolean) => {\n if (!open && !props.modal.processing) {\n requestClose()\n }\n}\n\nconst hasFooter = computed(() =>\n Boolean(\n schema.value.submitLabel || schema.value.cancelLabel || schema.value.extraFooterActions?.length,\n ),\n)\nconst hasBody = computed(() =>\n Boolean(\n schema.value.content || form || schema.value.contentFooter || schema.value.passwordConfirmation,\n ),\n)\n</script>\n\n<template>\n <Sheet\n v-if=\"schema.slideOver\"\n :open=\"!props.hidden\"\n :modal=\"!schema.clickThrough\"\n @update:open=\"onOpenChange\"\n >\n <SheetContent\n :side=\"side\"\n :class=\"\n cn('flex w-full flex-col gap-0 p-0', WIDTHS[schema.width] ?? 'sm:max-w-md', windowClass)\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <SheetHeader class=\"border-b\">\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <SheetTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</SheetTitle>\n <SheetDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></SheetDescription>\n <SheetDescription v-else class=\"sr-only\">{{ title }}</SheetDescription>\n </div>\n </div>\n </SheetHeader>\n <div class=\"flex-1 overflow-y-auto p-4\">\n <div class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.before\"\n :data=\"{ action: action.name }\"\n />\n <form\n v-if=\"form && formState\"\n :id=\"`action-form-${action.name}`\"\n @submit.prevent=\"submit\"\n >\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.after\"\n :data=\"{ action: action.name }\"\n />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n </div>\n <SheetFooter\n v-if=\"hasFooter\"\n :class=\"cn('border-t', schema.stickyFooter && 'bg-background sticky bottom-0')\"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n <Dialog v-else :open=\"!props.hidden\" :modal=\"!schema.clickThrough\" @update:open=\"onOpenChange\">\n <DialogContent\n :class=\"\n cn(\n 'max-h-[calc(100vh-2rem)] overflow-y-auto',\n WIDTHS[schema.width] ?? 'sm:max-w-lg',\n windowClass,\n )\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <!-- A sticky header stays pinned to the top of the scrolling dialog, edge to edge. -->\n <DialogHeader\n :class=\"\n cn(\n schema.stickyHeader &&\n 'bg-background sticky -top-6 z-10 -mx-6 -mt-6 rounded-t-lg border-b px-6 pt-6 pb-4',\n )\n \"\n >\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <DialogTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</DialogTitle>\n <DialogDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></DialogDescription>\n <DialogDescription v-else class=\"sr-only\">{{ title }}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n <div v-if=\"hasBody\" class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot v-if=\"form && formState\" name=\"modal.schema.before\" :data=\"{ action: action.name }\" />\n <form v-if=\"form && formState\" :id=\"`action-form-${action.name}`\" @submit.prevent=\"submit\">\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot v-if=\"form && formState\" name=\"modal.schema.after\" :data=\"{ action: action.name }\" />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n <!-- A sticky footer stays pinned to the bottom of the scrolling dialog, edge to edge. -->\n <DialogFooter\n v-if=\"hasFooter\"\n :class=\"\n cn(\n schema.stickyFooter &&\n 'bg-background sticky bottom-0 -mx-6 -mb-6 rounded-b-lg border-t px-6 py-4',\n )\n \"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ActionModal.js","names":["_sfc_main","ActionModal_vue_vue_type_script_setup_true_lang_default","ActionModal_default"],"sources":["../../../src/components/actions/ActionModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { OpenModal } from '@alfakit/core'\nimport {\n actionFormComponent,\n formIdPrefix,\n actionFormParams,\n confirmModalClose,\n FormStore,\n guardModalUnload,\n isModalSubmitVisible,\n modalFooterAlignment,\n nestedActionContext,\n PASSWORD_CONFIRMATION_INPUT,\n scheduleAutofocus,\n slideOverSide,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { computed, nextTick, onMounted, onScopeDispose, ref, useId, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useDirection, usePanel, useT } from '../../context'\nimport {\n colorClass,\n iconBackgroundColorClasses,\n outlineButtonColorClasses,\n solidButtonColorClasses,\n} from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { provideForm } from '../form/form-context'\nimport Slot from '../panel/Slot.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport Button from '../ui/Button.vue'\nimport Dialog from '../ui/Dialog.vue'\nimport DialogContent from '../ui/DialogContent.vue'\nimport DialogDescription from '../ui/DialogDescription.vue'\nimport DialogFooter from '../ui/DialogFooter.vue'\nimport DialogHeader from '../ui/DialogHeader.vue'\nimport DialogTitle from '../ui/DialogTitle.vue'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetDescription from '../ui/SheetDescription.vue'\nimport SheetFooter from '../ui/SheetFooter.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport ActionList from './ActionList.vue'\nimport ActionModalPassword from './ActionModalPassword.vue'\nimport { showToast } from '../notifications/flash-toasts'\n\nconst WIDTHS: Record<string, string> = {\n '3xs': 'sm:max-w-3xs',\n '2xs': 'sm:max-w-2xs',\n xs: 'sm:max-w-xs',\n sm: 'sm:max-w-sm',\n md: 'sm:max-w-md',\n lg: 'sm:max-w-lg',\n xl: 'sm:max-w-xl',\n '2xl': 'sm:max-w-2xl',\n '3xl': 'sm:max-w-3xl',\n '4xl': 'sm:max-w-4xl',\n '5xl': 'sm:max-w-5xl',\n '6xl': 'sm:max-w-6xl',\n '7xl': 'sm:max-w-7xl',\n none: 'sm:max-w-none',\n min: 'sm:max-w-min',\n max: 'sm:max-w-max',\n fit: 'sm:max-w-fit',\n prose: 'sm:max-w-prose',\n container: 'sm:container',\n 'screen-sm': 'sm:max-w-(--breakpoint-sm)',\n 'screen-md': 'sm:max-w-(--breakpoint-md)',\n 'screen-lg': 'sm:max-w-(--breakpoint-lg)',\n 'screen-xl': 'sm:max-w-(--breakpoint-xl)',\n 'screen-2xl': 'sm:max-w-(--breakpoint-2xl)',\n full: 'sm:max-w-[calc(100%-2rem)]',\n screen: 'sm:max-w-[calc(100%-2rem)] h-[calc(100%-2rem)]',\n}\n\nconst FOOTER_JUSTIFY: Record<string, string> = {\n start: 'sm:justify-start',\n center: 'sm:justify-center',\n end: 'sm:justify-end',\n between: 'sm:justify-between',\n}\n\nconst props = withDefaults(defineProps<{ modal: OpenModal; hidden?: boolean }>(), {\n hidden: false,\n})\n\nconst runner = useActionRunner()\nconst panel = usePanel()\nconst direction = useDirection()\nconst t = useT()\n\nconst action = props.modal.action\nconst context = props.modal.context\nconst schema = computed(() => props.modal.modal)\n\nconst form = (() => {\n if (!schema.value.form) {\n return null\n }\n\n return new FormStore(schema.value.form, {\n token: context.token,\n component: actionFormComponent(action, context),\n // Own field ids: the modal opens over a form whose fields may share names.\n idPrefix: formIdPrefix(actionFormComponent(action, context)),\n record: context.record ?? null,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n params: actionFormParams(context),\n })\n})()\n\nif (form) {\n provideForm(form)\n}\n\nconst formState = form ? useStore(form.store) : null\n\nwatch(\n () => props.modal.errors,\n (errors) => form?.setErrors(errors),\n { immediate: true },\n)\n\nonScopeDispose(() => form?.destroy())\n\n// Nested actions read this form (`$mountedActions`, `getRawData()`) and write into it\n// (`fillData()`).\nif (form) {\n onScopeDispose(runner.registerModalForm(action, context, form))\n}\n\n// `extraModalWindowAttributes()`: `class` joins the window's classes.\nconst windowClass = computed(() => schema.value.windowAttributes?.class as string | undefined)\nconst windowAttributes = computed(() => {\n const { class: _class, ...rest } = schema.value.windowAttributes ?? {}\n\n return rest\n})\n\n// `extraModalOverlayAttributes()`: the backdrop is the content's previous sibling.\nconst modalId = useId()\n\n// A marker inside the content finds the window and its backdrop (the dialog primitives\n// render through a portal and don't pass other attributes on).\nconst setAttributes = (element: Element, attributes: Record<string, unknown>) => {\n for (const [name, value] of Object.entries(attributes)) {\n if (value === null || value === undefined || value === false) continue\n\n if (name === 'class') {\n element.classList.add(...String(value).split(/\\s+/).filter(Boolean))\n } else {\n element.setAttribute(name, value === true ? '' : String(value))\n }\n }\n}\n\nconst applyOverlayAttributes = () => {\n if (props.hidden || typeof document === 'undefined') return\n\n const element = document\n .querySelector(`[data-alfakit-modal=\"${modalId}\"]`)\n ?.closest('[role=\"dialog\"]')\n const overlay = element?.previousElementSibling\n\n if (element) setAttributes(element, windowAttributes.value)\n\n if (overlay?.getAttribute('data-slot')?.endsWith('-overlay') && schema.value.overlayAttributes) {\n setAttributes(overlay, schema.value.overlayAttributes)\n }\n}\n\nonMounted(() => void nextTick(applyOverlayAttributes))\nwatch(\n () => props.hidden,\n () => void nextTick(applyOverlayAttributes),\n { flush: 'post' },\n)\n\nconst footerJustify = computed(() => FOOTER_JUSTIFY[modalFooterAlignment(schema.value)])\nconst footerActionsClass = computed(() =>\n modalFooterAlignment(schema.value) === 'end' ? 'sm:me-auto' : undefined,\n)\nconst side = computed(() => slideOverSide(schema.value.slideOverPosition, direction.value))\n\n// A wizard form reports its step, so the submit button waits for the last one.\nconst progress = form ? useStore(wizardProgressStore(form)) : null\nconst submitVisible = computed(() => isModalSubmitVisible(schema.value, progress?.value))\n\nconst password = ref('')\nconst passwordError = computed(() => props.modal.errors[PASSWORD_CONFIRMATION_INPUT]?.[0])\nconst footerContext = nestedActionContext(context, action)\n\nconst run = (createAnother: boolean) => {\n // A click that blurred a live field started a refresh: send the state it returns.\n if (form) {\n form.whenSettled(() => execute(createAnother))\n } else {\n execute(createAnother)\n }\n}\n\nconst execute = (createAnother: boolean) => {\n const values = form?.state.values ?? {}\n const options = {\n ...(schema.value.passwordConfirmation ? { password: password.value } : {}),\n ...(createAnother ? { createAnother: true } : {}),\n }\n\n if (Object.keys(options).length > 0) {\n runner.execute(action, context, values, options)\n } else {\n runner.execute(action, context, values)\n }\n}\nconst submit = () => run(false)\n// \"Create & create another\": the runner reloads the modal, and its fresh form fills this one.\nconst submitAnother = () => run(true)\n\nwatch(\n () => schema.value.form,\n (payload, previous) => {\n if (payload && payload !== previous) form?.fill(payload)\n },\n)\n\n// \"Create & create another\": back to the `autofocus()` field of the fresh form.\nwatch(\n () => props.modal.refocus,\n (refocus, _previous, onCleanup) => {\n const components = schema.value.form?.components\n\n if (!refocus || !components) return\n\n onCleanup(\n scheduleAutofocus(() => document.getElementById(`action-form-${action.name}`), components),\n )\n },\n)\n\n// Dismissing the modal (not submitting it): `cancelParentActionsOnClose()` applies.\nconst close = () => runner.cancelModal(action.name)\nconst unsavedMessage = t('unsaved_changes_close', {}, 'You have unsaved changes. Close anyway?')\n// Cancel, Escape, clicking away and the close button ask first when the form changed.\nconst requestClose = () => {\n if (confirmModalClose(schema.value, form, unsavedMessage)) close()\n}\nonScopeDispose(guardModalUnload(schema.value, form, unsavedMessage))\nconst cancelClass = computed(() =>\n schema.value.cancelColor ? colorClass(outlineButtonColorClasses, schema.value.cancelColor) : '',\n)\n// `createAnotherAction()`: the \"Create & create another\" button's colour.\nconst createAnotherClass = computed(() =>\n schema.value.createAnotherColor\n ? colorClass(outlineButtonColorClasses, schema.value.createAnotherColor)\n : '',\n)\n// Every dialog needs an accessible name: without a heading it stays visually hidden.\nconst title = computed(() => schema.value.heading ?? action.label ?? t('actions', {}, 'Actions'))\n\nconst onOpenChange = (open: boolean) => {\n if (!open && !props.modal.processing) {\n requestClose()\n }\n}\n\nconst hasFooter = computed(() =>\n Boolean(\n schema.value.submitLabel || schema.value.cancelLabel || schema.value.extraFooterActions?.length,\n ),\n)\nconst hasBody = computed(() =>\n Boolean(\n schema.value.content || form || schema.value.contentFooter || schema.value.passwordConfirmation,\n ),\n)\n</script>\n\n<template>\n <Sheet\n v-if=\"schema.slideOver\"\n :open=\"!props.hidden\"\n :modal=\"!schema.clickThrough\"\n @update:open=\"onOpenChange\"\n >\n <SheetContent\n :side=\"side\"\n :class=\"\n cn('flex w-full flex-col gap-0 p-0', WIDTHS[schema.width] ?? 'sm:max-w-md', windowClass)\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <SheetHeader class=\"border-b\">\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <SheetTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</SheetTitle>\n <SheetDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></SheetDescription>\n <SheetDescription v-else class=\"sr-only\">{{ title }}</SheetDescription>\n </div>\n </div>\n </SheetHeader>\n <div class=\"flex-1 overflow-y-auto p-4\">\n <div class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.before\"\n :data=\"{ action: action.name }\"\n />\n <form\n v-if=\"form && formState\"\n :id=\"`action-form-${action.name}`\"\n @submit.prevent=\"submit\"\n >\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.after\"\n :data=\"{ action: action.name }\"\n />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n </div>\n <SheetFooter\n v-if=\"hasFooter\"\n :class=\"cn('border-t', schema.stickyFooter && 'bg-background sticky bottom-0')\"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n <Dialog v-else :open=\"!props.hidden\" :modal=\"!schema.clickThrough\" @update:open=\"onOpenChange\">\n <DialogContent\n :class=\"\n cn(\n 'max-h-[calc(100vh-2rem)] overflow-y-auto',\n WIDTHS[schema.width] ?? 'sm:max-w-lg',\n windowClass,\n )\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <!-- A sticky header stays pinned to the top of the scrolling dialog, edge to edge. -->\n <DialogHeader\n :class=\"\n cn(\n schema.stickyHeader &&\n 'bg-background sticky -top-6 z-10 -mx-6 -mt-6 rounded-t-lg border-b px-6 pt-6 pb-4',\n // Room for the close button (X): a long heading would run under it.\n schema.closeButton !== false && (schema.stickyHeader ? 'pe-12' : 'pe-6'),\n )\n \"\n >\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <DialogTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</DialogTitle>\n <DialogDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></DialogDescription>\n <DialogDescription v-else class=\"sr-only\">{{ title }}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n <div v-if=\"hasBody\" class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot v-if=\"form && formState\" name=\"modal.schema.before\" :data=\"{ action: action.name }\" />\n <form v-if=\"form && formState\" :id=\"`action-form-${action.name}`\" @submit.prevent=\"submit\">\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot v-if=\"form && formState\" name=\"modal.schema.after\" :data=\"{ action: action.name }\" />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n <!-- A sticky footer stays pinned to the bottom of the scrolling dialog, edge to edge. -->\n <DialogFooter\n v-if=\"hasFooter\"\n :class=\"\n cn(\n schema.stickyFooter &&\n 'bg-background sticky bottom-0 -mx-6 -mb-6 rounded-b-lg border-t px-6 py-4',\n )\n \"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionModal.vue.d.ts","sourceRoot":"","sources":["../../../src/components/actions/ActionModal.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ActionModal.vue.d.ts","sourceRoot":"","sources":["../../../src/components/actions/ActionModal.vue"],"names":[],"mappings":"AAshBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAoF9C,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;;YAAV,OAAO;;AAshCvD,wBAOG"}
|
|
@@ -280,7 +280,7 @@ var ke = ["data-alfakit-modal"], Ae = { class: "flex flex-col gap-1.5" }, je = [
|
|
|
280
280
|
"data-alfakit-modal": j(K),
|
|
281
281
|
hidden: ""
|
|
282
282
|
}, null, 8, Fe),
|
|
283
|
-
w(ae, { class: D(j(i)(H.value.stickyHeader && "bg-background sticky -top-6 z-10 -mx-6 -mt-6 rounded-t-lg border-b px-6 pt-6 pb-4")) }, {
|
|
283
|
+
w(ae, { class: D(j(i)(H.value.stickyHeader && "bg-background sticky -top-6 z-10 -mx-6 -mt-6 rounded-t-lg border-b px-6 pt-6 pb-4", H.value.closeButton !== !1 && (H.value.stickyHeader ? "pe-12" : "pe-6"))) }, {
|
|
284
284
|
default: N(() => [S("div", { class: D(j(i)("flex gap-4", H.value.alignment === "center" && "flex-col items-center text-center")) }, [H.value.icon ? (k(), x("div", {
|
|
285
285
|
key: 0,
|
|
286
286
|
class: D(j(i)("flex size-10 shrink-0 items-center justify-center rounded-full", j(a)(j(o), H.value.iconColor, "primary")))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionModal.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","Sheet","_withCtx","_createVNode","SheetContent","_normalizeClass","_unref","_createElementVNode","SheetHeader","_createElementBlock","Icon","_createCommentVNode","SheetTitle","_createTextVNode","_toDisplayString","SheetDescription","SchemaRenderer","Slot","_withModifiers","ActionModalPassword","SheetFooter","ActionList","Button","Spinner","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter","Icon_default","Button_default","Spinner_default","ActionList_default","SchemaRenderer_default","Slot_default","Dialog_default","DialogContent_default","DialogDescription_default","DialogHeader_default","DialogTitle_default","Sheet_default","SheetContent_default","SheetDescription_default","SheetHeader_default","SheetTitle_default","DialogFooter_default","SheetFooter_default","ActionModalPassword_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","ActionModal_vue_vue_type_script_setup_true_lang_default","WIDTHS","FOOTER_JUSTIFY","props","__props","runner","useActionRunner","panel","usePanel","direction","useDirection","t","useT","action","context","schema","computed","form","FormStore","actionFormComponent","formIdPrefix","notifications","showToast","n","actionFormParams","provideForm","formState","useStore","watch","errors","onScopeDispose","windowClass","windowAttributes","_class","rest","modalId","useId","setAttributes","name","value","attributes","element","applyOverlayAttributes","overlay","onMounted","nextTick","footerJustify","modalFooterAlignment","footerActionsClass","side","slideOverSide","progress","wizardProgressStore","submitVisible","isModalSubmitVisible","password","ref","passwordError","PASSWORD_CONFIRMATION_INPUT","footerContext","nestedActionContext","run","execute","createAnother","values","options","submit","submitAnother","payload","previous","components","refocus","onCleanup","scheduleAutofocus","close","unsavedMessage","requestClose","confirmModalClose","guardModalUnload","cancelClass","colorClass","outlineButtonColorClasses","createAnotherClass","title","onOpenChange","open","hasFooter","hasBody","openBlock","createBlock","withCtx","createVNode","normalizeClass","unref","cn","_cache","event","createElementVNode","createElementBlock","iconBackgroundColorClasses","createCommentVNode","createTextVNode","toDisplayString","withModifiers","$event","solidButtonColorClasses"],"sources":["../../../src/components/actions/ActionModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { OpenModal } from '@alfakit/core'\nimport {\n actionFormComponent,\n formIdPrefix,\n actionFormParams,\n confirmModalClose,\n FormStore,\n guardModalUnload,\n isModalSubmitVisible,\n modalFooterAlignment,\n nestedActionContext,\n PASSWORD_CONFIRMATION_INPUT,\n scheduleAutofocus,\n slideOverSide,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { computed, nextTick, onMounted, onScopeDispose, ref, useId, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useDirection, usePanel, useT } from '../../context'\nimport {\n colorClass,\n iconBackgroundColorClasses,\n outlineButtonColorClasses,\n solidButtonColorClasses,\n} from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { provideForm } from '../form/form-context'\nimport Slot from '../panel/Slot.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport Button from '../ui/Button.vue'\nimport Dialog from '../ui/Dialog.vue'\nimport DialogContent from '../ui/DialogContent.vue'\nimport DialogDescription from '../ui/DialogDescription.vue'\nimport DialogFooter from '../ui/DialogFooter.vue'\nimport DialogHeader from '../ui/DialogHeader.vue'\nimport DialogTitle from '../ui/DialogTitle.vue'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetDescription from '../ui/SheetDescription.vue'\nimport SheetFooter from '../ui/SheetFooter.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport ActionList from './ActionList.vue'\nimport ActionModalPassword from './ActionModalPassword.vue'\nimport { showToast } from '../notifications/flash-toasts'\n\nconst WIDTHS: Record<string, string> = {\n '3xs': 'sm:max-w-3xs',\n '2xs': 'sm:max-w-2xs',\n xs: 'sm:max-w-xs',\n sm: 'sm:max-w-sm',\n md: 'sm:max-w-md',\n lg: 'sm:max-w-lg',\n xl: 'sm:max-w-xl',\n '2xl': 'sm:max-w-2xl',\n '3xl': 'sm:max-w-3xl',\n '4xl': 'sm:max-w-4xl',\n '5xl': 'sm:max-w-5xl',\n '6xl': 'sm:max-w-6xl',\n '7xl': 'sm:max-w-7xl',\n none: 'sm:max-w-none',\n min: 'sm:max-w-min',\n max: 'sm:max-w-max',\n fit: 'sm:max-w-fit',\n prose: 'sm:max-w-prose',\n container: 'sm:container',\n 'screen-sm': 'sm:max-w-(--breakpoint-sm)',\n 'screen-md': 'sm:max-w-(--breakpoint-md)',\n 'screen-lg': 'sm:max-w-(--breakpoint-lg)',\n 'screen-xl': 'sm:max-w-(--breakpoint-xl)',\n 'screen-2xl': 'sm:max-w-(--breakpoint-2xl)',\n full: 'sm:max-w-[calc(100%-2rem)]',\n screen: 'sm:max-w-[calc(100%-2rem)] h-[calc(100%-2rem)]',\n}\n\nconst FOOTER_JUSTIFY: Record<string, string> = {\n start: 'sm:justify-start',\n center: 'sm:justify-center',\n end: 'sm:justify-end',\n between: 'sm:justify-between',\n}\n\nconst props = withDefaults(defineProps<{ modal: OpenModal; hidden?: boolean }>(), {\n hidden: false,\n})\n\nconst runner = useActionRunner()\nconst panel = usePanel()\nconst direction = useDirection()\nconst t = useT()\n\nconst action = props.modal.action\nconst context = props.modal.context\nconst schema = computed(() => props.modal.modal)\n\nconst form = (() => {\n if (!schema.value.form) {\n return null\n }\n\n return new FormStore(schema.value.form, {\n token: context.token,\n component: actionFormComponent(action, context),\n // Own field ids: the modal opens over a form whose fields may share names.\n idPrefix: formIdPrefix(actionFormComponent(action, context)),\n record: context.record ?? null,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n params: actionFormParams(context),\n })\n})()\n\nif (form) {\n provideForm(form)\n}\n\nconst formState = form ? useStore(form.store) : null\n\nwatch(\n () => props.modal.errors,\n (errors) => form?.setErrors(errors),\n { immediate: true },\n)\n\nonScopeDispose(() => form?.destroy())\n\n// Nested actions read this form (`$mountedActions`, `getRawData()`) and write into it\n// (`fillData()`).\nif (form) {\n onScopeDispose(runner.registerModalForm(action, context, form))\n}\n\n// `extraModalWindowAttributes()`: `class` joins the window's classes.\nconst windowClass = computed(() => schema.value.windowAttributes?.class as string | undefined)\nconst windowAttributes = computed(() => {\n const { class: _class, ...rest } = schema.value.windowAttributes ?? {}\n\n return rest\n})\n\n// `extraModalOverlayAttributes()`: the backdrop is the content's previous sibling.\nconst modalId = useId()\n\n// A marker inside the content finds the window and its backdrop (the dialog primitives\n// render through a portal and don't pass other attributes on).\nconst setAttributes = (element: Element, attributes: Record<string, unknown>) => {\n for (const [name, value] of Object.entries(attributes)) {\n if (value === null || value === undefined || value === false) continue\n\n if (name === 'class') {\n element.classList.add(...String(value).split(/\\s+/).filter(Boolean))\n } else {\n element.setAttribute(name, value === true ? '' : String(value))\n }\n }\n}\n\nconst applyOverlayAttributes = () => {\n if (props.hidden || typeof document === 'undefined') return\n\n const element = document\n .querySelector(`[data-alfakit-modal=\"${modalId}\"]`)\n ?.closest('[role=\"dialog\"]')\n const overlay = element?.previousElementSibling\n\n if (element) setAttributes(element, windowAttributes.value)\n\n if (overlay?.getAttribute('data-slot')?.endsWith('-overlay') && schema.value.overlayAttributes) {\n setAttributes(overlay, schema.value.overlayAttributes)\n }\n}\n\nonMounted(() => void nextTick(applyOverlayAttributes))\nwatch(\n () => props.hidden,\n () => void nextTick(applyOverlayAttributes),\n { flush: 'post' },\n)\n\nconst footerJustify = computed(() => FOOTER_JUSTIFY[modalFooterAlignment(schema.value)])\nconst footerActionsClass = computed(() =>\n modalFooterAlignment(schema.value) === 'end' ? 'sm:me-auto' : undefined,\n)\nconst side = computed(() => slideOverSide(schema.value.slideOverPosition, direction.value))\n\n// A wizard form reports its step, so the submit button waits for the last one.\nconst progress = form ? useStore(wizardProgressStore(form)) : null\nconst submitVisible = computed(() => isModalSubmitVisible(schema.value, progress?.value))\n\nconst password = ref('')\nconst passwordError = computed(() => props.modal.errors[PASSWORD_CONFIRMATION_INPUT]?.[0])\nconst footerContext = nestedActionContext(context, action)\n\nconst run = (createAnother: boolean) => {\n // A click that blurred a live field started a refresh: send the state it returns.\n if (form) {\n form.whenSettled(() => execute(createAnother))\n } else {\n execute(createAnother)\n }\n}\n\nconst execute = (createAnother: boolean) => {\n const values = form?.state.values ?? {}\n const options = {\n ...(schema.value.passwordConfirmation ? { password: password.value } : {}),\n ...(createAnother ? { createAnother: true } : {}),\n }\n\n if (Object.keys(options).length > 0) {\n runner.execute(action, context, values, options)\n } else {\n runner.execute(action, context, values)\n }\n}\nconst submit = () => run(false)\n// \"Create & create another\": the runner reloads the modal, and its fresh form fills this one.\nconst submitAnother = () => run(true)\n\nwatch(\n () => schema.value.form,\n (payload, previous) => {\n if (payload && payload !== previous) form?.fill(payload)\n },\n)\n\n// \"Create & create another\": back to the `autofocus()` field of the fresh form.\nwatch(\n () => props.modal.refocus,\n (refocus, _previous, onCleanup) => {\n const components = schema.value.form?.components\n\n if (!refocus || !components) return\n\n onCleanup(\n scheduleAutofocus(() => document.getElementById(`action-form-${action.name}`), components),\n )\n },\n)\n\n// Dismissing the modal (not submitting it): `cancelParentActionsOnClose()` applies.\nconst close = () => runner.cancelModal(action.name)\nconst unsavedMessage = t('unsaved_changes_close', {}, 'You have unsaved changes. Close anyway?')\n// Cancel, Escape, clicking away and the close button ask first when the form changed.\nconst requestClose = () => {\n if (confirmModalClose(schema.value, form, unsavedMessage)) close()\n}\nonScopeDispose(guardModalUnload(schema.value, form, unsavedMessage))\nconst cancelClass = computed(() =>\n schema.value.cancelColor ? colorClass(outlineButtonColorClasses, schema.value.cancelColor) : '',\n)\n// `createAnotherAction()`: the \"Create & create another\" button's colour.\nconst createAnotherClass = computed(() =>\n schema.value.createAnotherColor\n ? colorClass(outlineButtonColorClasses, schema.value.createAnotherColor)\n : '',\n)\n// Every dialog needs an accessible name: without a heading it stays visually hidden.\nconst title = computed(() => schema.value.heading ?? action.label ?? t('actions', {}, 'Actions'))\n\nconst onOpenChange = (open: boolean) => {\n if (!open && !props.modal.processing) {\n requestClose()\n }\n}\n\nconst hasFooter = computed(() =>\n Boolean(\n schema.value.submitLabel || schema.value.cancelLabel || schema.value.extraFooterActions?.length,\n ),\n)\nconst hasBody = computed(() =>\n Boolean(\n schema.value.content || form || schema.value.contentFooter || schema.value.passwordConfirmation,\n ),\n)\n</script>\n\n<template>\n <Sheet\n v-if=\"schema.slideOver\"\n :open=\"!props.hidden\"\n :modal=\"!schema.clickThrough\"\n @update:open=\"onOpenChange\"\n >\n <SheetContent\n :side=\"side\"\n :class=\"\n cn('flex w-full flex-col gap-0 p-0', WIDTHS[schema.width] ?? 'sm:max-w-md', windowClass)\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <SheetHeader class=\"border-b\">\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <SheetTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</SheetTitle>\n <SheetDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></SheetDescription>\n <SheetDescription v-else class=\"sr-only\">{{ title }}</SheetDescription>\n </div>\n </div>\n </SheetHeader>\n <div class=\"flex-1 overflow-y-auto p-4\">\n <div class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.before\"\n :data=\"{ action: action.name }\"\n />\n <form\n v-if=\"form && formState\"\n :id=\"`action-form-${action.name}`\"\n @submit.prevent=\"submit\"\n >\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.after\"\n :data=\"{ action: action.name }\"\n />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n </div>\n <SheetFooter\n v-if=\"hasFooter\"\n :class=\"cn('border-t', schema.stickyFooter && 'bg-background sticky bottom-0')\"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n <Dialog v-else :open=\"!props.hidden\" :modal=\"!schema.clickThrough\" @update:open=\"onOpenChange\">\n <DialogContent\n :class=\"\n cn(\n 'max-h-[calc(100vh-2rem)] overflow-y-auto',\n WIDTHS[schema.width] ?? 'sm:max-w-lg',\n windowClass,\n )\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <!-- A sticky header stays pinned to the top of the scrolling dialog, edge to edge. -->\n <DialogHeader\n :class=\"\n cn(\n schema.stickyHeader &&\n 'bg-background sticky -top-6 z-10 -mx-6 -mt-6 rounded-t-lg border-b px-6 pt-6 pb-4',\n )\n \"\n >\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <DialogTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</DialogTitle>\n <DialogDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></DialogDescription>\n <DialogDescription v-else class=\"sr-only\">{{ title }}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n <div v-if=\"hasBody\" class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot v-if=\"form && formState\" name=\"modal.schema.before\" :data=\"{ action: action.name }\" />\n <form v-if=\"form && formState\" :id=\"`action-form-${action.name}`\" @submit.prevent=\"submit\">\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot v-if=\"form && formState\" name=\"modal.schema.after\" :data=\"{ action: action.name }\" />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n <!-- A sticky footer stays pinned to the bottom of the scrolling dialog, edge to edge. -->\n <DialogFooter\n v-if=\"hasFooter\"\n :class=\"\n cn(\n schema.stickyFooter &&\n 'bg-background sticky bottom-0 -mx-6 -mb-6 rounded-b-lg border-t px-6 py-4',\n )\n \"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActionModal.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","Sheet","_withCtx","_createVNode","SheetContent","_normalizeClass","_unref","_createElementVNode","SheetHeader","_createElementBlock","Icon","_createCommentVNode","SheetTitle","_createTextVNode","_toDisplayString","SheetDescription","SchemaRenderer","Slot","_withModifiers","ActionModalPassword","SheetFooter","ActionList","Button","Spinner","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter","Icon_default","Button_default","Spinner_default","ActionList_default","SchemaRenderer_default","Slot_default","Dialog_default","DialogContent_default","DialogDescription_default","DialogHeader_default","DialogTitle_default","Sheet_default","SheetContent_default","SheetDescription_default","SheetHeader_default","SheetTitle_default","DialogFooter_default","SheetFooter_default","ActionModalPassword_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","ActionModal_vue_vue_type_script_setup_true_lang_default","WIDTHS","FOOTER_JUSTIFY","props","__props","runner","useActionRunner","panel","usePanel","direction","useDirection","t","useT","action","context","schema","computed","form","FormStore","actionFormComponent","formIdPrefix","notifications","showToast","n","actionFormParams","provideForm","formState","useStore","watch","errors","onScopeDispose","windowClass","windowAttributes","_class","rest","modalId","useId","setAttributes","name","value","attributes","element","applyOverlayAttributes","overlay","onMounted","nextTick","footerJustify","modalFooterAlignment","footerActionsClass","side","slideOverSide","progress","wizardProgressStore","submitVisible","isModalSubmitVisible","password","ref","passwordError","PASSWORD_CONFIRMATION_INPUT","footerContext","nestedActionContext","run","execute","createAnother","values","options","submit","submitAnother","payload","previous","components","refocus","onCleanup","scheduleAutofocus","close","unsavedMessage","requestClose","confirmModalClose","guardModalUnload","cancelClass","colorClass","outlineButtonColorClasses","createAnotherClass","title","onOpenChange","open","hasFooter","hasBody","openBlock","createBlock","withCtx","createVNode","normalizeClass","unref","cn","_cache","event","createElementVNode","createElementBlock","iconBackgroundColorClasses","createCommentVNode","createTextVNode","toDisplayString","withModifiers","$event","solidButtonColorClasses"],"sources":["../../../src/components/actions/ActionModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { OpenModal } from '@alfakit/core'\nimport {\n actionFormComponent,\n formIdPrefix,\n actionFormParams,\n confirmModalClose,\n FormStore,\n guardModalUnload,\n isModalSubmitVisible,\n modalFooterAlignment,\n nestedActionContext,\n PASSWORD_CONFIRMATION_INPUT,\n scheduleAutofocus,\n slideOverSide,\n wizardProgressStore,\n} from '@alfakit/core'\nimport { computed, nextTick, onMounted, onScopeDispose, ref, useId, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useActionRunner, useDirection, usePanel, useT } from '../../context'\nimport {\n colorClass,\n iconBackgroundColorClasses,\n outlineButtonColorClasses,\n solidButtonColorClasses,\n} from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport { provideForm } from '../form/form-context'\nimport Slot from '../panel/Slot.vue'\nimport SchemaRenderer from '../schema/SchemaRenderer.vue'\nimport Button from '../ui/Button.vue'\nimport Dialog from '../ui/Dialog.vue'\nimport DialogContent from '../ui/DialogContent.vue'\nimport DialogDescription from '../ui/DialogDescription.vue'\nimport DialogFooter from '../ui/DialogFooter.vue'\nimport DialogHeader from '../ui/DialogHeader.vue'\nimport DialogTitle from '../ui/DialogTitle.vue'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetDescription from '../ui/SheetDescription.vue'\nimport SheetFooter from '../ui/SheetFooter.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport ActionList from './ActionList.vue'\nimport ActionModalPassword from './ActionModalPassword.vue'\nimport { showToast } from '../notifications/flash-toasts'\n\nconst WIDTHS: Record<string, string> = {\n '3xs': 'sm:max-w-3xs',\n '2xs': 'sm:max-w-2xs',\n xs: 'sm:max-w-xs',\n sm: 'sm:max-w-sm',\n md: 'sm:max-w-md',\n lg: 'sm:max-w-lg',\n xl: 'sm:max-w-xl',\n '2xl': 'sm:max-w-2xl',\n '3xl': 'sm:max-w-3xl',\n '4xl': 'sm:max-w-4xl',\n '5xl': 'sm:max-w-5xl',\n '6xl': 'sm:max-w-6xl',\n '7xl': 'sm:max-w-7xl',\n none: 'sm:max-w-none',\n min: 'sm:max-w-min',\n max: 'sm:max-w-max',\n fit: 'sm:max-w-fit',\n prose: 'sm:max-w-prose',\n container: 'sm:container',\n 'screen-sm': 'sm:max-w-(--breakpoint-sm)',\n 'screen-md': 'sm:max-w-(--breakpoint-md)',\n 'screen-lg': 'sm:max-w-(--breakpoint-lg)',\n 'screen-xl': 'sm:max-w-(--breakpoint-xl)',\n 'screen-2xl': 'sm:max-w-(--breakpoint-2xl)',\n full: 'sm:max-w-[calc(100%-2rem)]',\n screen: 'sm:max-w-[calc(100%-2rem)] h-[calc(100%-2rem)]',\n}\n\nconst FOOTER_JUSTIFY: Record<string, string> = {\n start: 'sm:justify-start',\n center: 'sm:justify-center',\n end: 'sm:justify-end',\n between: 'sm:justify-between',\n}\n\nconst props = withDefaults(defineProps<{ modal: OpenModal; hidden?: boolean }>(), {\n hidden: false,\n})\n\nconst runner = useActionRunner()\nconst panel = usePanel()\nconst direction = useDirection()\nconst t = useT()\n\nconst action = props.modal.action\nconst context = props.modal.context\nconst schema = computed(() => props.modal.modal)\n\nconst form = (() => {\n if (!schema.value.form) {\n return null\n }\n\n return new FormStore(schema.value.form, {\n token: context.token,\n component: actionFormComponent(action, context),\n // Own field ids: the modal opens over a form whose fields may share names.\n idPrefix: formIdPrefix(actionFormComponent(action, context)),\n record: context.record ?? null,\n refreshUrl: panel.value.endpoints.schemaRefresh,\n optionsUrl: panel.value.endpoints.schemaOptions,\n validateUrl: panel.value.endpoints.schemaValidate,\n // A halted wizard step shows what its hook sent.\n onNotifications: (notifications) => notifications.forEach((n) => showToast(n)),\n params: actionFormParams(context),\n })\n})()\n\nif (form) {\n provideForm(form)\n}\n\nconst formState = form ? useStore(form.store) : null\n\nwatch(\n () => props.modal.errors,\n (errors) => form?.setErrors(errors),\n { immediate: true },\n)\n\nonScopeDispose(() => form?.destroy())\n\n// Nested actions read this form (`$mountedActions`, `getRawData()`) and write into it\n// (`fillData()`).\nif (form) {\n onScopeDispose(runner.registerModalForm(action, context, form))\n}\n\n// `extraModalWindowAttributes()`: `class` joins the window's classes.\nconst windowClass = computed(() => schema.value.windowAttributes?.class as string | undefined)\nconst windowAttributes = computed(() => {\n const { class: _class, ...rest } = schema.value.windowAttributes ?? {}\n\n return rest\n})\n\n// `extraModalOverlayAttributes()`: the backdrop is the content's previous sibling.\nconst modalId = useId()\n\n// A marker inside the content finds the window and its backdrop (the dialog primitives\n// render through a portal and don't pass other attributes on).\nconst setAttributes = (element: Element, attributes: Record<string, unknown>) => {\n for (const [name, value] of Object.entries(attributes)) {\n if (value === null || value === undefined || value === false) continue\n\n if (name === 'class') {\n element.classList.add(...String(value).split(/\\s+/).filter(Boolean))\n } else {\n element.setAttribute(name, value === true ? '' : String(value))\n }\n }\n}\n\nconst applyOverlayAttributes = () => {\n if (props.hidden || typeof document === 'undefined') return\n\n const element = document\n .querySelector(`[data-alfakit-modal=\"${modalId}\"]`)\n ?.closest('[role=\"dialog\"]')\n const overlay = element?.previousElementSibling\n\n if (element) setAttributes(element, windowAttributes.value)\n\n if (overlay?.getAttribute('data-slot')?.endsWith('-overlay') && schema.value.overlayAttributes) {\n setAttributes(overlay, schema.value.overlayAttributes)\n }\n}\n\nonMounted(() => void nextTick(applyOverlayAttributes))\nwatch(\n () => props.hidden,\n () => void nextTick(applyOverlayAttributes),\n { flush: 'post' },\n)\n\nconst footerJustify = computed(() => FOOTER_JUSTIFY[modalFooterAlignment(schema.value)])\nconst footerActionsClass = computed(() =>\n modalFooterAlignment(schema.value) === 'end' ? 'sm:me-auto' : undefined,\n)\nconst side = computed(() => slideOverSide(schema.value.slideOverPosition, direction.value))\n\n// A wizard form reports its step, so the submit button waits for the last one.\nconst progress = form ? useStore(wizardProgressStore(form)) : null\nconst submitVisible = computed(() => isModalSubmitVisible(schema.value, progress?.value))\n\nconst password = ref('')\nconst passwordError = computed(() => props.modal.errors[PASSWORD_CONFIRMATION_INPUT]?.[0])\nconst footerContext = nestedActionContext(context, action)\n\nconst run = (createAnother: boolean) => {\n // A click that blurred a live field started a refresh: send the state it returns.\n if (form) {\n form.whenSettled(() => execute(createAnother))\n } else {\n execute(createAnother)\n }\n}\n\nconst execute = (createAnother: boolean) => {\n const values = form?.state.values ?? {}\n const options = {\n ...(schema.value.passwordConfirmation ? { password: password.value } : {}),\n ...(createAnother ? { createAnother: true } : {}),\n }\n\n if (Object.keys(options).length > 0) {\n runner.execute(action, context, values, options)\n } else {\n runner.execute(action, context, values)\n }\n}\nconst submit = () => run(false)\n// \"Create & create another\": the runner reloads the modal, and its fresh form fills this one.\nconst submitAnother = () => run(true)\n\nwatch(\n () => schema.value.form,\n (payload, previous) => {\n if (payload && payload !== previous) form?.fill(payload)\n },\n)\n\n// \"Create & create another\": back to the `autofocus()` field of the fresh form.\nwatch(\n () => props.modal.refocus,\n (refocus, _previous, onCleanup) => {\n const components = schema.value.form?.components\n\n if (!refocus || !components) return\n\n onCleanup(\n scheduleAutofocus(() => document.getElementById(`action-form-${action.name}`), components),\n )\n },\n)\n\n// Dismissing the modal (not submitting it): `cancelParentActionsOnClose()` applies.\nconst close = () => runner.cancelModal(action.name)\nconst unsavedMessage = t('unsaved_changes_close', {}, 'You have unsaved changes. Close anyway?')\n// Cancel, Escape, clicking away and the close button ask first when the form changed.\nconst requestClose = () => {\n if (confirmModalClose(schema.value, form, unsavedMessage)) close()\n}\nonScopeDispose(guardModalUnload(schema.value, form, unsavedMessage))\nconst cancelClass = computed(() =>\n schema.value.cancelColor ? colorClass(outlineButtonColorClasses, schema.value.cancelColor) : '',\n)\n// `createAnotherAction()`: the \"Create & create another\" button's colour.\nconst createAnotherClass = computed(() =>\n schema.value.createAnotherColor\n ? colorClass(outlineButtonColorClasses, schema.value.createAnotherColor)\n : '',\n)\n// Every dialog needs an accessible name: without a heading it stays visually hidden.\nconst title = computed(() => schema.value.heading ?? action.label ?? t('actions', {}, 'Actions'))\n\nconst onOpenChange = (open: boolean) => {\n if (!open && !props.modal.processing) {\n requestClose()\n }\n}\n\nconst hasFooter = computed(() =>\n Boolean(\n schema.value.submitLabel || schema.value.cancelLabel || schema.value.extraFooterActions?.length,\n ),\n)\nconst hasBody = computed(() =>\n Boolean(\n schema.value.content || form || schema.value.contentFooter || schema.value.passwordConfirmation,\n ),\n)\n</script>\n\n<template>\n <Sheet\n v-if=\"schema.slideOver\"\n :open=\"!props.hidden\"\n :modal=\"!schema.clickThrough\"\n @update:open=\"onOpenChange\"\n >\n <SheetContent\n :side=\"side\"\n :class=\"\n cn('flex w-full flex-col gap-0 p-0', WIDTHS[schema.width] ?? 'sm:max-w-md', windowClass)\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <SheetHeader class=\"border-b\">\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <SheetTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</SheetTitle>\n <SheetDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></SheetDescription>\n <SheetDescription v-else class=\"sr-only\">{{ title }}</SheetDescription>\n </div>\n </div>\n </SheetHeader>\n <div class=\"flex-1 overflow-y-auto p-4\">\n <div class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.before\"\n :data=\"{ action: action.name }\"\n />\n <form\n v-if=\"form && formState\"\n :id=\"`action-form-${action.name}`\"\n @submit.prevent=\"submit\"\n >\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot\n v-if=\"form && formState\"\n name=\"modal.schema.after\"\n :data=\"{ action: action.name }\"\n />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n </div>\n <SheetFooter\n v-if=\"hasFooter\"\n :class=\"cn('border-t', schema.stickyFooter && 'bg-background sticky bottom-0')\"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n <Dialog v-else :open=\"!props.hidden\" :modal=\"!schema.clickThrough\" @update:open=\"onOpenChange\">\n <DialogContent\n :class=\"\n cn(\n 'max-h-[calc(100vh-2rem)] overflow-y-auto',\n WIDTHS[schema.width] ?? 'sm:max-w-lg',\n windowClass,\n )\n \"\n :show-close-button=\"schema.closeButton\"\n @interact-outside=\"(event) => !schema.closeByClickingAway && event.preventDefault()\"\n @escape-key-down=\"(event) => !schema.closeByEscaping && event.preventDefault()\"\n >\n <span :data-alfakit-modal=\"modalId\" hidden />\n <!-- A sticky header stays pinned to the top of the scrolling dialog, edge to edge. -->\n <DialogHeader\n :class=\"\n cn(\n schema.stickyHeader &&\n 'bg-background sticky -top-6 z-10 -mx-6 -mt-6 rounded-t-lg border-b px-6 pt-6 pb-4',\n // Room for the close button (X): a long heading would run under it.\n schema.closeButton !== false && (schema.stickyHeader ? 'pe-12' : 'pe-6'),\n )\n \"\n >\n <div\n :class=\"\n cn('flex gap-4', schema.alignment === 'center' && 'flex-col items-center text-center')\n \"\n >\n <div\n v-if=\"schema.icon\"\n :class=\"\n cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-full',\n colorClass(iconBackgroundColorClasses, schema.iconColor, 'primary'),\n )\n \"\n >\n <Icon :name=\"schema.icon\" class=\"size-5\" />\n </div>\n <div class=\"flex flex-col gap-1.5\">\n <DialogTitle :class=\"cn(!schema.heading && 'sr-only')\">{{ title }}</DialogTitle>\n <DialogDescription v-if=\"schema.description\"\n ><span v-html=\"schema.description\"\n /></DialogDescription>\n <DialogDescription v-else class=\"sr-only\">{{ title }}</DialogDescription>\n </div>\n </div>\n </DialogHeader>\n <div v-if=\"hasBody\" class=\"flex flex-col gap-6\">\n <SchemaRenderer v-if=\"schema.content\" :components=\"schema.content\" />\n <Slot v-if=\"form && formState\" name=\"modal.schema.before\" :data=\"{ action: action.name }\" />\n <form v-if=\"form && formState\" :id=\"`action-form-${action.name}`\" @submit.prevent=\"submit\">\n <SchemaRenderer :components=\"formState.components\" :columns=\"formState.columns\" />\n </form>\n <Slot v-if=\"form && formState\" name=\"modal.schema.after\" :data=\"{ action: action.name }\" />\n <SchemaRenderer v-if=\"schema.contentFooter\" :components=\"schema.contentFooter\" />\n <ActionModalPassword\n v-if=\"schema.passwordConfirmation\"\n v-model=\"password\"\n :error=\"passwordError\"\n @submit=\"submit\"\n />\n </div>\n <!-- A sticky footer stays pinned to the bottom of the scrolling dialog, edge to edge. -->\n <DialogFooter\n v-if=\"hasFooter\"\n :class=\"\n cn(\n schema.stickyFooter &&\n 'bg-background sticky bottom-0 -mx-6 -mb-6 rounded-b-lg border-t px-6 py-4',\n )\n \"\n >\n <div\n :class=\"\n cn('flex w-full flex-col-reverse gap-2 sm:flex-row sm:items-center', footerJustify)\n \"\n >\n <ActionList\n v-if=\"schema.extraFooterActions\"\n :actions=\"schema.extraFooterActions\"\n :context=\"footerContext\"\n :class=\"footerActionsClass\"\n />\n <Button\n v-if=\"schema.cancelLabel\"\n type=\"button\"\n variant=\"outline\"\n :class=\"cancelClass\"\n :disabled=\"props.modal.processing\"\n @click=\"requestClose\"\n >{{ schema.cancelLabel }}</Button\n >\n <Button\n v-if=\"schema.createAnotherLabel && schema.submitLabel && submitVisible\"\n type=\"button\"\n variant=\"outline\"\n data-slot=\"create-another\"\n :class=\"createAnotherClass\"\n :disabled=\"props.modal.processing\"\n @click=\"submitAnother\"\n ><Icon v-if=\"schema.createAnotherIcon\" :name=\"schema.createAnotherIcon\" />{{\n schema.createAnotherLabel\n }}</Button\n >\n <Button\n v-if=\"schema.submitLabel && submitVisible\"\n type=\"button\"\n :class=\"colorClass(solidButtonColorClasses, schema.submitColor, 'primary')\"\n :disabled=\"props.modal.processing\"\n :autofocus=\"schema.autofocus && !form\"\n @click=\"submit\"\n >\n <Spinner v-if=\"props.modal.processing\" />\n <Icon v-else-if=\"schema.submitIcon\" :name=\"schema.submitIcon\" />\n {{ schema.submitLabel }}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DevToolsInspector.js","names":["_sfc_main","DevToolsInspector_vue_vue_type_script_setup_true_lang_default","DevToolsInspector_default"],"sources":["../../../src/components/dev-tools/DevToolsInspector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n byteLength,\n formatBytes,\n inspectableProps,\n jsonEntries,\n jsonScalar,\n latestServerTiming,\n prettyJson,\n searchJson,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { BracesIcon, CheckIcon, CopyIcon, ExternalLinkIcon } from '@lucide/vue'\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { useAlfakitProps, useDirection, useFormatter, useT } from '../../context'\nimport Button from '../ui/Button.vue'\nimport Input from '../ui/Input.vue'\nimport ScrollArea from '../ui/ScrollArea.vue'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetDescription from '../ui/SheetDescription.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\nimport SheetTrigger from '../ui/SheetTrigger.vue'\nimport DevToolsJsonNode from './DevToolsJsonNode.vue'\n\n/**\n * The schema inspector: a floating developer button that opens a drawer with the page's\n * props as a searchable JSON tree (with a copy button), what the context token identifies,\n * the server time reported in `Server-Timing`, the payload size and editor links for the\n * PHP classes behind the page. Rendered only for pages that carry `alfakitDevTools`.\n */\nconst t = useT()\nconst formatter = useFormatter()\nconst direction = useDirection()\nconst props = useAlfakitProps()\nconst tools = computed(() => props.value.alfakitDevTools)\nconst data = computed(() => inspectableProps(props.value as unknown as Record<string, unknown>))\nconst payload = computed(() => byteLength(props.value))\nconst query = ref('')\nconst copied = ref(false)\nconst serverTime = ref<number | null>(null)\nconst search = computed(() => searchJson(data.value, query.value))\nconst roots = computed(() => jsonEntries(data.value))\nconst parameters = computed(() => Object.entries(tools.value?.context.parameters ?? {}))\n\nlet stop: (() => void) | undefined\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nonMounted(() => {\n serverTime.value = latestServerTiming()\n // Re-read after every visit: the latest response carries the newest header.\n stop = router.on('finish', () => {\n serverTime.value = latestServerTiming()\n })\n})\n\nonBeforeUnmount(() => {\n stop?.()\n clearTimeout(timer)\n})\n\nconst copy = () => {\n void navigator.clipboard?.writeText(prettyJson(data.value)).then(() => {\n copied.value = true\n clearTimeout(timer)\n timer = setTimeout(() => (copied.value = false), 2000)\n })\n}\n\nconst time = (value: number | null) =>\n value === null ? t('dev_tools.never', {}, 'Never') : formatter.value.dateTime(value * 1000)\n</script>\n\n<template>\n <Sheet v-if=\"tools\">\n <SheetTrigger as-child>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n :aria-label=\"t('dev_tools.open', {}, 'Open schema inspector')\"\n data-slot=\"dev-tools-toggle\"\n class=\"fixed end-4 bottom-4 z-40 rounded-full shadow-md\"\n >\n <BracesIcon />\n </Button>\n </SheetTrigger>\n <SheetContent\n :side=\"direction === 'rtl' ? 'left' : 'right'\"\n class=\"flex w-full flex-col gap-0 p-0 sm:max-w-xl\"\n >\n <div data-slot=\"dev-tools\" class=\"flex min-h-0 flex-1 flex-col\">\n <SheetHeader class=\"border-b\">\n <SheetTitle class=\"flex items-center gap-2\">\n <BracesIcon class=\"size-4\" />\n {{ t('dev_tools.title', {}, 'Schema inspector') }}\n </SheetTitle>\n <SheetDescription class=\"truncate font-mono text-xs\" :title=\"tools.context.page\">\n {{ tools.context.page }}\n </SheetDescription>\n </SheetHeader>\n <ScrollArea class=\"min-h-0 flex-1\">\n <div class=\"space-y-5 p-4 text-sm\">\n <dl class=\"grid grid-cols-2 gap-3\">\n <div class=\"rounded-md border p-3\">\n <dt class=\"text-muted-foreground text-xs\">\n {{ t('dev_tools.server_time', {}, 'Server time') }}\n </dt>\n <dd class=\"font-mono text-sm font-semibold tabular-nums\">\n {{\n serverTime === null\n ? t('dev_tools.not_measured', {}, 'Not measured')\n : t(\n 'dev_tools.milliseconds',\n { value: formatter.number(serverTime) },\n ':value ms',\n )\n }}\n </dd>\n </div>\n <div class=\"rounded-md border p-3\">\n <dt class=\"text-muted-foreground text-xs\">\n {{ t('dev_tools.payload', {}, 'Payload size') }}\n </dt>\n <dd class=\"font-mono text-sm font-semibold tabular-nums\">\n {{ formatBytes(payload) }}\n </dd>\n </div>\n </dl>\n\n <section data-slot=\"dev-tools-context\">\n <h3 class=\"mb-2 text-sm font-medium\">\n {{ t('dev_tools.context', {}, 'Context token') }}\n </h3>\n <dl class=\"grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-xs\">\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.panel', {}, 'Panel') }}</dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ tools.context.panel }}</dd>\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.page', {}, 'Page') }}</dt>\n <dd class=\"min-w-0 truncate font-mono\" :title=\"tools.context.page\">\n {{ tools.context.page }}\n </dd>\n <template v-if=\"tools.context.component\">\n <dt class=\"text-muted-foreground\">\n {{ t('dev_tools.component', {}, 'Component') }}\n </dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ tools.context.component }}</dd>\n </template>\n <template v-if=\"tools.tenant !== null\">\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.tenant', {}, 'Tenant') }}</dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ tools.tenant }}</dd>\n </template>\n <template v-for=\"[key, value] in parameters\" :key=\"key\">\n <dt class=\"text-muted-foreground\">{{ key }}</dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ jsonScalar(value) }}</dd>\n </template>\n <dt class=\"text-muted-foreground\">\n {{ t('dev_tools.bound_to_user', {}, 'Bound to the user') }}\n </dt>\n <dd>\n {{\n tools.context.boundToUser\n ? t('dev_tools.yes', {}, 'Yes')\n : t('dev_tools.no', {}, 'No')\n }}\n </dd>\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.issued_at', {}, 'Issued') }}</dt>\n <dd>{{ time(tools.context.issuedAt) }}</dd>\n <dt class=\"text-muted-foreground\">\n {{ t('dev_tools.expires_at', {}, 'Expires') }}\n </dt>\n <dd>{{ time(tools.context.expiresAt) }}</dd>\n </dl>\n </section>\n\n <section data-slot=\"dev-tools-classes\">\n <h3 class=\"mb-2 text-sm font-medium\">{{ t('dev_tools.classes', {}, 'Classes') }}</h3>\n <ul class=\"divide-y rounded-md border text-xs\">\n <li\n v-for=\"item in tools.classes\"\n :key=\"item.role\"\n class=\"flex items-center gap-2 px-3 py-1.5\"\n >\n <span class=\"text-muted-foreground w-16 shrink-0\">\n {{ t(`dev_tools.roles.${item.role}`, {}, item.role) }}\n </span>\n <span\n class=\"min-w-0 flex-1 truncate font-mono\"\n :title=\"item.file ? `${item.file}:${item.line ?? 1}` : item.class\"\n >\n {{ item.class }}\n </span>\n <a\n v-if=\"item.url\"\n :href=\"item.url\"\n class=\"text-primary inline-flex shrink-0 items-center gap-1 hover:underline\"\n :aria-label=\"\n t(\n 'dev_tools.open_in_editor',\n { class: item.class, editor: tools.editor ?? '' },\n 'Open :class in :editor',\n )\n \"\n >\n <ExternalLinkIcon class=\"size-3.5\" />\n </a>\n </li>\n </ul>\n <p v-if=\"tools.editor === null\" class=\"text-muted-foreground mt-2 text-xs\">\n {{\n t(\n 'dev_tools.no_editor',\n {},\n 'Set APP_EDITOR (config app.editor) to open these classes in your editor.',\n )\n }}\n </p>\n </section>\n\n <section data-slot=\"dev-tools-schema\">\n <div class=\"mb-2 flex items-center gap-2\">\n <h3 class=\"me-auto text-sm font-medium\">\n {{ t('dev_tools.schema', {}, 'Schema') }}\n </h3>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" @click=\"copy\">\n <CheckIcon v-if=\"copied\" />\n <CopyIcon v-else />\n {{\n copied\n ? t('dev_tools.copied', {}, 'Copied')\n : t('dev_tools.copy', {}, 'Copy JSON')\n }}\n </Button>\n </div>\n <Input\n v-model=\"query\"\n type=\"search\"\n :placeholder=\"t('dev_tools.search', {}, 'Search keys and values')\"\n :aria-label=\"t('dev_tools.search', {}, 'Search keys and values')\"\n class=\"mb-2 h-8\"\n />\n <p\n v-if=\"query.trim() !== '' && search.matches.size === 0\"\n class=\"text-muted-foreground text-sm\"\n >\n {{\n t('dev_tools.no_matches', { query: query.trim() }, 'Nothing matches “:query”.')\n }}\n </p>\n <ul\n v-else\n dir=\"ltr\"\n role=\"tree\"\n :aria-label=\"t('dev_tools.schema', {}, 'Schema')\"\n class=\"bg-muted/40 overflow-x-auto rounded-md p-2 text-start font-mono text-xs leading-relaxed\"\n >\n <DevToolsJsonNode\n v-for=\"entry in roots\"\n :key=\"entry.path\"\n :entry=\"entry\"\n :depth=\"0\"\n :search=\"search\"\n :query=\"query\"\n />\n </ul>\n </section>\n </div>\n </ScrollArea>\n </div>\n </SheetContent>\n </Sheet>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"DevToolsInspector.js","names":["_sfc_main","DevToolsInspector_vue_vue_type_script_setup_true_lang_default","DevToolsInspector_default"],"sources":["../../../src/components/dev-tools/DevToolsInspector.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n byteLength,\n formatBytes,\n inspectableProps,\n jsonEntries,\n jsonScalar,\n latestServerTiming,\n prettyJson,\n searchJson,\n} from '@alfakit/core'\nimport { router } from '@inertiajs/vue3'\nimport { BracesIcon, CheckIcon, CopyIcon, ExternalLinkIcon } from '@lucide/vue'\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { useAlfakitProps, useDirection, useFormatter, useT } from '../../context'\nimport Button from '../ui/Button.vue'\nimport Input from '../ui/Input.vue'\nimport ScrollArea from '../ui/ScrollArea.vue'\nimport Sheet from '../ui/Sheet.vue'\nimport SheetContent from '../ui/SheetContent.vue'\nimport SheetDescription from '../ui/SheetDescription.vue'\nimport SheetHeader from '../ui/SheetHeader.vue'\nimport SheetTitle from '../ui/SheetTitle.vue'\nimport SheetTrigger from '../ui/SheetTrigger.vue'\nimport DevToolsJsonNode from './DevToolsJsonNode.vue'\n\n/**\n * The schema inspector: a floating developer button that opens a drawer with the page's\n * props as a searchable JSON tree (with a copy button), what the context token identifies,\n * the server time reported in `Server-Timing`, the payload size and editor links for the\n * PHP classes behind the page. Rendered only for pages that carry `alfakitDevTools`.\n */\nconst t = useT()\nconst formatter = useFormatter()\nconst direction = useDirection()\nconst props = useAlfakitProps()\nconst tools = computed(() => props.value.alfakitDevTools)\nconst data = computed(() => inspectableProps(props.value as unknown as Record<string, unknown>))\nconst payload = computed(() => byteLength(props.value))\nconst query = ref('')\nconst copied = ref(false)\nconst serverTime = ref<number | null>(null)\nconst search = computed(() => searchJson(data.value, query.value))\nconst roots = computed(() => jsonEntries(data.value))\nconst parameters = computed(() => Object.entries(tools.value?.context.parameters ?? {}))\n\nlet stop: (() => void) | undefined\nlet timer: ReturnType<typeof setTimeout> | undefined\n\nonMounted(() => {\n serverTime.value = latestServerTiming()\n // Re-read after every visit: the latest response carries the newest header.\n stop = router.on('finish', () => {\n serverTime.value = latestServerTiming()\n })\n})\n\nonBeforeUnmount(() => {\n stop?.()\n clearTimeout(timer)\n})\n\nconst copy = () => {\n void navigator.clipboard?.writeText(prettyJson(data.value)).then(() => {\n copied.value = true\n clearTimeout(timer)\n timer = setTimeout(() => (copied.value = false), 2000)\n })\n}\n\nconst time = (value: number | null) =>\n value === null ? t('dev_tools.never', {}, 'Never') : formatter.value.dateTime(value * 1000)\n</script>\n\n<template>\n <Sheet v-if=\"tools\">\n <SheetTrigger as-child>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n :aria-label=\"t('dev_tools.open', {}, 'Open schema inspector')\"\n data-slot=\"dev-tools-toggle\"\n class=\"fixed end-4 bottom-16 z-40 rounded-full shadow-md [[data-slot=starter-kit-root]_&]:end-auto [[data-slot=starter-kit-root]_&]:right-4\"\n >\n <BracesIcon />\n </Button>\n </SheetTrigger>\n <SheetContent\n :side=\"direction === 'rtl' ? 'left' : 'right'\"\n class=\"flex w-full flex-col gap-0 p-0 sm:max-w-xl\"\n >\n <div data-slot=\"dev-tools\" class=\"flex min-h-0 flex-1 flex-col\">\n <SheetHeader class=\"border-b\">\n <SheetTitle class=\"flex items-center gap-2\">\n <BracesIcon class=\"size-4\" />\n {{ t('dev_tools.title', {}, 'Schema inspector') }}\n </SheetTitle>\n <SheetDescription class=\"truncate font-mono text-xs\" :title=\"tools.context.page\">\n {{ tools.context.page }}\n </SheetDescription>\n </SheetHeader>\n <ScrollArea class=\"min-h-0 flex-1\">\n <div class=\"space-y-5 p-4 text-sm\">\n <dl class=\"grid grid-cols-2 gap-3\">\n <div class=\"rounded-md border p-3\">\n <dt class=\"text-muted-foreground text-xs\">\n {{ t('dev_tools.server_time', {}, 'Server time') }}\n </dt>\n <dd class=\"font-mono text-sm font-semibold tabular-nums\">\n {{\n serverTime === null\n ? t('dev_tools.not_measured', {}, 'Not measured')\n : t(\n 'dev_tools.milliseconds',\n { value: formatter.number(serverTime) },\n ':value ms',\n )\n }}\n </dd>\n </div>\n <div class=\"rounded-md border p-3\">\n <dt class=\"text-muted-foreground text-xs\">\n {{ t('dev_tools.payload', {}, 'Payload size') }}\n </dt>\n <dd class=\"font-mono text-sm font-semibold tabular-nums\">\n {{ formatBytes(payload) }}\n </dd>\n </div>\n </dl>\n\n <section data-slot=\"dev-tools-context\">\n <h3 class=\"mb-2 text-sm font-medium\">\n {{ t('dev_tools.context', {}, 'Context token') }}\n </h3>\n <dl class=\"grid grid-cols-[auto_1fr] gap-x-4 gap-y-1 text-xs\">\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.panel', {}, 'Panel') }}</dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ tools.context.panel }}</dd>\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.page', {}, 'Page') }}</dt>\n <dd class=\"min-w-0 truncate font-mono\" :title=\"tools.context.page\">\n {{ tools.context.page }}\n </dd>\n <template v-if=\"tools.context.component\">\n <dt class=\"text-muted-foreground\">\n {{ t('dev_tools.component', {}, 'Component') }}\n </dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ tools.context.component }}</dd>\n </template>\n <template v-if=\"tools.tenant !== null\">\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.tenant', {}, 'Tenant') }}</dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ tools.tenant }}</dd>\n </template>\n <template v-for=\"[key, value] in parameters\" :key=\"key\">\n <dt class=\"text-muted-foreground\">{{ key }}</dt>\n <dd class=\"min-w-0 truncate font-mono\">{{ jsonScalar(value) }}</dd>\n </template>\n <dt class=\"text-muted-foreground\">\n {{ t('dev_tools.bound_to_user', {}, 'Bound to the user') }}\n </dt>\n <dd>\n {{\n tools.context.boundToUser\n ? t('dev_tools.yes', {}, 'Yes')\n : t('dev_tools.no', {}, 'No')\n }}\n </dd>\n <dt class=\"text-muted-foreground\">{{ t('dev_tools.issued_at', {}, 'Issued') }}</dt>\n <dd>{{ time(tools.context.issuedAt) }}</dd>\n <dt class=\"text-muted-foreground\">\n {{ t('dev_tools.expires_at', {}, 'Expires') }}\n </dt>\n <dd>{{ time(tools.context.expiresAt) }}</dd>\n </dl>\n </section>\n\n <section data-slot=\"dev-tools-classes\">\n <h3 class=\"mb-2 text-sm font-medium\">{{ t('dev_tools.classes', {}, 'Classes') }}</h3>\n <ul class=\"divide-y rounded-md border text-xs\">\n <li\n v-for=\"item in tools.classes\"\n :key=\"item.role\"\n class=\"flex items-center gap-2 px-3 py-1.5\"\n >\n <span class=\"text-muted-foreground w-16 shrink-0\">\n {{ t(`dev_tools.roles.${item.role}`, {}, item.role) }}\n </span>\n <span\n class=\"min-w-0 flex-1 truncate font-mono\"\n :title=\"item.file ? `${item.file}:${item.line ?? 1}` : item.class\"\n >\n {{ item.class }}\n </span>\n <a\n v-if=\"item.url\"\n :href=\"item.url\"\n class=\"text-primary inline-flex shrink-0 items-center gap-1 hover:underline\"\n :aria-label=\"\n t(\n 'dev_tools.open_in_editor',\n { class: item.class, editor: tools.editor ?? '' },\n 'Open :class in :editor',\n )\n \"\n >\n <ExternalLinkIcon class=\"size-3.5\" />\n </a>\n </li>\n </ul>\n <p v-if=\"tools.editor === null\" class=\"text-muted-foreground mt-2 text-xs\">\n {{\n t(\n 'dev_tools.no_editor',\n {},\n 'Set APP_EDITOR (config app.editor) to open these classes in your editor.',\n )\n }}\n </p>\n </section>\n\n <section data-slot=\"dev-tools-schema\">\n <div class=\"mb-2 flex items-center gap-2\">\n <h3 class=\"me-auto text-sm font-medium\">\n {{ t('dev_tools.schema', {}, 'Schema') }}\n </h3>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" @click=\"copy\">\n <CheckIcon v-if=\"copied\" />\n <CopyIcon v-else />\n {{\n copied\n ? t('dev_tools.copied', {}, 'Copied')\n : t('dev_tools.copy', {}, 'Copy JSON')\n }}\n </Button>\n </div>\n <Input\n v-model=\"query\"\n type=\"search\"\n :placeholder=\"t('dev_tools.search', {}, 'Search keys and values')\"\n :aria-label=\"t('dev_tools.search', {}, 'Search keys and values')\"\n class=\"mb-2 h-8\"\n />\n <p\n v-if=\"query.trim() !== '' && search.matches.size === 0\"\n class=\"text-muted-foreground text-sm\"\n >\n {{\n t('dev_tools.no_matches', { query: query.trim() }, 'Nothing matches “:query”.')\n }}\n </p>\n <ul\n v-else\n dir=\"ltr\"\n role=\"tree\"\n :aria-label=\"t('dev_tools.schema', {}, 'Schema')\"\n class=\"bg-muted/40 overflow-x-auto rounded-md p-2 text-start font-mono text-xs leading-relaxed\"\n >\n <DevToolsJsonNode\n v-for=\"entry in roots\"\n :key=\"entry.path\"\n :entry=\"entry\"\n :depth=\"0\"\n :search=\"search\"\n :query=\"query\"\n />\n </ul>\n </section>\n </div>\n </ScrollArea>\n </div>\n </SheetContent>\n </Sheet>\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DevToolsInspector.vue.d.ts","sourceRoot":"","sources":["../../../src/components/dev-tools/DevToolsInspector.vue"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"DevToolsInspector.vue.d.ts","sourceRoot":"","sources":["../../../src/components/dev-tools/DevToolsInspector.vue"],"names":[],"mappings":";AAm6BA,wBAKG"}
|
|
@@ -47,7 +47,7 @@ var A = {
|
|
|
47
47
|
size: "icon",
|
|
48
48
|
"aria-label": w(H)("dev_tools.open", {}, "Open schema inspector"),
|
|
49
49
|
"data-slot": "dev-tools-toggle",
|
|
50
|
-
class: "fixed end-4 bottom-
|
|
50
|
+
class: "fixed end-4 bottom-16 z-40 rounded-full shadow-md [[data-slot=starter-kit-root]_&]:end-auto [[data-slot=starter-kit-root]_&]:right-4"
|
|
51
51
|
}, {
|
|
52
52
|
default: T(() => [v(w(E))]),
|
|
53
53
|
_: 1
|