@alfakit/vue 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/components/actions/ActionButton.js.map +1 -1
- package/dist/components/actions/ActionButton.vue.d.ts.map +1 -1
- package/dist/components/actions/ActionButton.vue_vue_type_script_setup_true_lang.js +160 -159
- package/dist/components/actions/ActionButton.vue_vue_type_script_setup_true_lang.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 +214 -214
- package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/ColorPickerField.js.map +1 -1
- package/dist/components/fields/ColorPickerField.vue.d.ts.map +1 -1
- package/dist/components/fields/ColorPickerField.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/fields/ColorPickerField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/ComboboxSelect.js.map +1 -1
- package/dist/components/fields/ComboboxSelect.vue.d.ts.map +1 -1
- package/dist/components/fields/ComboboxSelect.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/fields/ComboboxSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/FileUploadField.js.map +1 -1
- package/dist/components/fields/FileUploadField.vue.d.ts.map +1 -1
- package/dist/components/fields/FileUploadField.vue_vue_type_script_setup_true_lang.js +183 -183
- package/dist/components/fields/FileUploadField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/OneTimeCodeInputField.js.map +1 -1
- package/dist/components/fields/OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js +1 -2
- package/dist/components/fields/OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/SelectField.js.map +1 -1
- package/dist/components/fields/SelectField.vue.d.ts.map +1 -1
- package/dist/components/fields/SelectField.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/fields/SelectField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/fields/TableColumnHeaders.js.map +1 -1
- package/dist/components/fields/TableColumnHeaders.vue.d.ts.map +1 -1
- package/dist/components/fields/TableColumnHeaders.vue_vue_type_script_setup_true_lang.js +6 -3
- package/dist/components/fields/TableColumnHeaders.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_vue_type_script_setup_true_lang.js +1 -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 +81 -77
- package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/form/form-context.js +25 -25
- package/dist/components/form/form-context.js.map +1 -1
- package/dist/components/layout/FusedGroupComponent.js.map +1 -1
- package/dist/components/layout/FusedGroupComponent.vue.d.ts.map +1 -1
- package/dist/components/layout/FusedGroupComponent.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/layout/FusedGroupComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/layout/TabsComponent.js.map +1 -1
- package/dist/components/layout/TabsComponent.vue.d.ts.map +1 -1
- package/dist/components/layout/TabsComponent.vue_vue_type_script_setup_true_lang.js +76 -55
- package/dist/components/layout/TabsComponent.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 +44 -42
- package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/GlobalSearch.js.map +1 -1
- package/dist/components/panel/GlobalSearch.vue.d.ts.map +1 -1
- package/dist/components/panel/GlobalSearch.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/components/panel/GlobalSearch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/ShortcutKeys.js.map +1 -1
- package/dist/components/panel/ShortcutKeys.vue.d.ts.map +1 -1
- package/dist/components/panel/ShortcutKeys.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/components/panel/ShortcutKeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/panel/TenantMenu.js.map +1 -1
- package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/GroupHeaderRow.js.map +1 -1
- package/dist/components/table/GroupHeaderRow.vue.d.ts.map +1 -1
- package/dist/components/table/GroupHeaderRow.vue_vue_type_script_setup_true_lang.js +55 -34
- package/dist/components/table/GroupHeaderRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/SelectCell.js.map +1 -1
- package/dist/components/table/SelectCell.vue.d.ts.map +1 -1
- package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js +24 -19
- package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/TextInputCell.js.map +1 -1
- package/dist/components/table/TextInputCell.vue.d.ts.map +1 -1
- package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js +38 -33
- package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components.css +347 -0
- package/dist/eject-manifest.json +2 -2
- package/dist/standalone/AlfakitToaster.js.map +1 -1
- package/dist/standalone/AlfakitToaster.vue.d.ts.map +1 -1
- package/dist/standalone/AlfakitToaster.vue_vue_type_script_setup_true_lang.js +23 -15
- package/dist/standalone/AlfakitToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/standalone.css +47 -0
- package/dist/starter-kit/widgets/SearchTrigger.js.map +1 -1
- package/dist/starter-kit/widgets/SearchTrigger.vue.d.ts.map +1 -1
- package/dist/starter-kit/widgets/SearchTrigger.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/starter-kit/widgets/SearchTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/starter-kit/widgets/TenantChooser.js.map +1 -1
- package/dist/starter-kit/widgets/TenantChooser.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/starter-kit/widgets/TenantChooser.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/themes.css +2 -334
- package/package.json +3 -3
- package/src/components/actions/ActionButton.vue +14 -6
- package/src/components/actions/ActionModal.vue +3 -1
- package/src/components/fields/ColorPickerField.vue +1 -0
- package/src/components/fields/ComboboxSelect.vue +1 -1
- package/src/components/fields/FileUploadField.vue +14 -11
- package/src/components/fields/OneTimeCodeInputField.vue +1 -1
- package/src/components/fields/SelectField.vue +4 -2
- package/src/components/fields/TableColumnHeaders.vue +6 -1
- package/src/components/file-manager/FileManagerView.vue +1 -1
- package/src/components/form/FormBlock.vue +24 -0
- package/src/components/form/form-context.ts +2 -2
- package/src/components/layout/FusedGroupComponent.vue +1 -0
- package/src/components/layout/TabsComponent.vue +61 -5
- package/src/components/notifications/NotificationsMenu.vue +11 -0
- package/src/components/panel/GlobalSearch.vue +1 -0
- package/src/components/panel/ShortcutKeys.vue +1 -0
- package/src/components/panel/TenantMenu.vue +2 -2
- package/src/components/table/GroupHeaderRow.vue +27 -0
- package/src/components/table/SelectCell.vue +5 -2
- package/src/components/table/TextInputCell.vue +11 -5
- package/src/standalone/AlfakitToaster.vue +12 -2
- package/src/starter-kit/widgets/SearchTrigger.vue +1 -0
- package/src/starter-kit/widgets/TenantChooser.vue +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionButton.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","Tooltip","_withCtx","_createVNode","TooltipTrigger","_normalizeClass","Button","_mergeProps","_createElementVNode","Spinner","_unref","Icon","_createCommentVNode","_createElementBlock","_toDisplayString","Badge","_createTextVNode","TooltipContent","_Fragment","Icon_default","Badge_default","Button_default","Spinner_default","Tooltip_default","TooltipContent_default","TooltipTrigger_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","BADGE_TRIGGER_CLASSES","ActionButton_vue_vue_type_script_setup_true_lang_default","props","__props","runner","useActionRunner","loading","useStoreSelector","state","processing","modal","variant","computed","isIconOnly","busy","isPlainLink","bindsKeys","bindsKeyBindings","buttonClasses","color","action","kind","cn","colorClass","outlineButtonColorClasses","ghostButtonColorClasses","textColorClasses","badgeColorClasses","solidButtonColorClasses","run","onCleanup","registerKeyBindings","onClick","event","sizeProp","size","resolveActionSize","iconButtonSize","LABEL_FROM","ICON_ONLY_BELOW","labeledFrom","labelClass","classes","t","useT","newTabHint","ariaLabel","name","tooltip","shortcut","disabledTooltip","openBlock","createBlock","withCtx","createVNode","normalizeClass","mergeProps","createElementVNode","unref","createCommentVNode","createElementBlock","toDisplayString","createTextVNode","Link","formatKeyBinding","Fragment"],"sources":["../../../src/components/actions/ActionButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ActionContext, ActionSchema } from '@alfakit/core'\nimport {\n bindsKeyBindings,\n formatKeyBinding,\n iconButtonSize,\n registerKeyBindings,\n resolveActionSize,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/vue3'\nimport { computed, watchEffect, type HTMLAttributes } from 'vue'\nimport { useStoreSelector } from '../../composables/use-store'\nimport { useActionRunner, useT } from '../../context'\nimport {\n badgeColorClasses,\n colorClass,\n ghostButtonColorClasses,\n outlineButtonColorClasses,\n solidButtonColorClasses,\n textColorClasses,\n} from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport Badge from '../ui/Badge.vue'\nimport Button from '../ui/Button.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport Tooltip from '../ui/Tooltip.vue'\nimport TooltipContent from '../ui/TooltipContent.vue'\nimport TooltipTrigger from '../ui/TooltipTrigger.vue'\n\nexport interface ActionButtonProps {\n action: ActionSchema\n context: ActionContext\n size?: 'xs' | 'sm' | 'default' | 'lg'\n class?: HTMLAttributes['class']\n /** Force a variant (e.g. menu items render as plain rows). */\n variant?: ActionSchema['variant']\n /** Bind the action's key bindings globally while mounted. */\n withKeyBindings?: boolean\n /** Override how the action runs (e.g. a form submits its values). */\n onTrigger?: (action: ActionSchema, context: ActionContext) => void | Promise<void>\n}\n\nconst props = withDefaults(defineProps<ActionButtonProps>(), {\n size: 'default',\n withKeyBindings: true,\n})\n\nconst runner = useActionRunner()\nconst loading = useStoreSelector(runner.store, (state) => state.loading === props.action.name)\nconst processing = useStoreSelector(runner.store, (state) =>\n state.modals.some((modal) => modal.action.name === props.action.name && modal.processing),\n)\n\nconst variant = computed(\n () =>\n props.variant ??\n (props.action.outlined\n ? 'outline'\n : (props.action.variant ??\n (props.action.hasAction || props.action.hasModal || props.action.url ? 'link' : 'button'))),\n)\nconst isIconOnly = computed(() => variant.value === 'icon-button' || !props.action.label)\nconst busy = computed(() => loading.value || processing.value)\n// A disabled link renders as a disabled button so it cannot navigate.\nconst isPlainLink = computed(() =>\n Boolean(\n props.action.url && !props.action.hasAction && !props.action.hasModal && !props.action.disabled,\n ),\n)\n// Record actions repeat per row: a global shortcut would run them for every record.\nconst bindsKeys = computed(\n () => props.withKeyBindings && bindsKeyBindings(props.action, props.context),\n)\n\n/** The badge trigger style (`badge()` without an argument). */\nconst BADGE_TRIGGER_CLASSES =\n \"h-auto min-h-6 gap-1 rounded-md border px-2 py-0.5 text-xs font-medium [&_svg:not([class*='size-'])]:size-3.5\"\n\nfunction buttonClasses(action: ActionSchema, kind: ActionSchema['variant']): string {\n const color = action.color ?? 'primary'\n\n switch (kind) {\n case 'outline':\n return cn('bg-background border', colorClass(outlineButtonColorClasses, color, 'gray'))\n case 'ghost':\n return colorClass(ghostButtonColorClasses, color, 'gray')\n case 'link':\n return cn(\n 'h-auto p-0 underline-offset-4 hover:underline',\n colorClass(textColorClasses, color, 'primary'),\n )\n case 'icon-button':\n return colorClass(ghostButtonColorClasses, color, 'gray')\n case 'badge':\n // `badge()`: a tinted pill in the action's colour.\n return cn(BADGE_TRIGGER_CLASSES, colorClass(badgeColorClasses, color, 'primary'))\n default:\n return colorClass(solidButtonColorClasses, color, 'primary')\n }\n}\n\nconst run = () =>\n void (props.onTrigger\n ? props.onTrigger(props.action, props.context)\n : runner.trigger(props.action, props.context))\n\nwatchEffect((onCleanup) => {\n if (!bindsKeys.value || !props.action.keyBindings) {\n return\n }\n\n onCleanup(registerKeyBindings([{ keys: props.action.keyBindings, handler: run }]))\n})\n\nconst onClick = (event: MouseEvent) => {\n if (isPlainLink.value) {\n return // Plain link: let Inertia Link / anchor handle it.\n }\n\n event.preventDefault()\n run()\n}\n\nconst sizeProp = computed(() => {\n const size = variant.value === 'badge' ? 'xs' : resolveActionSize(props.action.size, props.size)\n\n return isIconOnly.value ? iconButtonSize(size) : size\n})\n// `labeledFrom()`: icon only below the breakpoint; the label stays the accessible name.\nconst LABEL_FROM: Record<string, string> = {\n sm: 'hidden sm:inline',\n md: 'hidden md:inline',\n lg: 'hidden lg:inline',\n xl: 'hidden xl:inline',\n '2xl': 'hidden 2xl:inline',\n}\nconst ICON_ONLY_BELOW: Record<string, string> = {\n sm: 'max-sm:aspect-square max-sm:px-0',\n md: 'max-md:aspect-square max-md:px-0',\n lg: 'max-lg:aspect-square max-lg:px-0',\n xl: 'max-xl:aspect-square max-xl:px-0',\n '2xl': 'max-2xl:aspect-square max-2xl:px-0',\n}\nconst labeledFrom = computed(() =>\n !isIconOnly.value && props.action.icon && props.action.labeledFrom\n ? props.action.labeledFrom\n : null,\n)\nconst labelClass = computed(() => (labeledFrom.value ? LABEL_FROM[labeledFrom.value] : undefined))\nconst classes = computed(() =>\n cn(\n buttonClasses(props.action, variant.value),\n labeledFrom.value && ICON_ONLY_BELOW[labeledFrom.value],\n props.class,\n ),\n)\nconst t = useT()\nconst newTabHint = computed(() => t('opens_in_new_tab', {}, '(opens in a new tab)'))\nconst ariaLabel = computed(() => {\n if (!isIconOnly.value && !labeledFrom.value) return undefined\n\n const name = props.action.label ?? props.action.tooltip ?? props.action.name\n\n return isPlainLink.value && props.action.openUrlInNewTab ? `${name} ${newTabHint.value}` : name\n})\nconst tooltip = computed(\n () => props.action.tooltip ?? (isIconOnly.value ? props.action.label : undefined),\n)\nconst shortcut = computed(() => (bindsKeys.value ? props.action.keyBindings?.[0] : undefined))\nconst disabledTooltip = computed(() => Boolean(props.action.disabled && tooltip.value))\n</script>\n\n<template>\n <Tooltip v-if=\"tooltip || shortcut\">\n <!-- A disabled button gets no pointer or focus events: a focusable span carries the\n tooltip (e.g. the reason from `authorizationTooltip()`). -->\n <TooltipTrigger\n :as-child=\"!disabledTooltip\"\n :as=\"disabledTooltip ? 'span' : undefined\"\n :tabindex=\"disabledTooltip ? 0 : undefined\"\n :class=\"disabledTooltip ? 'inline-flex' : undefined\"\n :data-disabled-tooltip=\"disabledTooltip ? '' : undefined\"\n >\n <Button\n v-if=\"isPlainLink && props.action.openUrlInNewTab\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <a :href=\"props.action.url\" target=\"_blank\" rel=\"noopener noreferrer\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <span v-if=\"!isIconOnly\" class=\"sr-only\"> {{ newTabHint }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </a>\n </Button>\n <Button\n v-else-if=\"isPlainLink\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <Link :href=\"props.action.url ?? '#'\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Link>\n </Button>\n <Button\n v-else\n type=\"button\"\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled || busy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n @click=\"onClick\"\n >\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {{ tooltip }}\n <kbd v-if=\"shortcut\" class=\"ms-2 rounded border border-white/20 px-1 font-mono text-[10px]\">{{\n formatKeyBinding(shortcut)\n }}</kbd>\n </TooltipContent>\n </Tooltip>\n <template v-else>\n <Button\n v-if=\"isPlainLink && props.action.openUrlInNewTab\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <a :href=\"props.action.url\" target=\"_blank\" rel=\"noopener noreferrer\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <span v-if=\"!isIconOnly\" class=\"sr-only\"> {{ newTabHint }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </a>\n </Button>\n <Button\n v-else-if=\"isPlainLink\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <Link :href=\"props.action.url ?? '#'\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Link>\n </Button>\n <Button\n v-else\n type=\"button\"\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled || busy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n @click=\"onClick\"\n >\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Button>\n </template>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActionButton.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","Tooltip","_withCtx","_createVNode","TooltipTrigger","_normalizeClass","Button","_mergeProps","_createElementVNode","Spinner","_unref","Icon","_createCommentVNode","_createElementBlock","_toDisplayString","Badge","_createTextVNode","TooltipContent","_Fragment","Icon_default","Badge_default","Button_default","Spinner_default","Tooltip_default","TooltipContent_default","TooltipTrigger_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","BADGE_TRIGGER_CLASSES","ActionButton_vue_vue_type_script_setup_true_lang_default","props","__props","runner","useActionRunner","loading","useStoreSelector","isActionLoading","state","processing","isActionProcessing","variant","computed","isIconOnly","busy","isPlainLink","bindsKeys","bindsKeyBindings","buttonClasses","color","action","kind","cn","colorClass","outlineButtonColorClasses","ghostButtonColorClasses","textColorClasses","badgeColorClasses","solidButtonColorClasses","run","onCleanup","registerKeyBindings","onClick","event","sizeProp","size","resolveActionSize","iconButtonSize","LABEL_FROM","ICON_ONLY_BELOW","labeledFrom","labelClass","classes","t","useT","newTabHint","ariaLabel","name","tooltip","shortcut","disabledTooltip","openBlock","createBlock","withCtx","createVNode","normalizeClass","mergeProps","createElementVNode","unref","createCommentVNode","createElementBlock","toDisplayString","createTextVNode","Link","formatKeyBinding","Fragment"],"sources":["../../../src/components/actions/ActionButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ActionContext, ActionSchema } from '@alfakit/core'\nimport {\n bindsKeyBindings,\n formatKeyBinding,\n iconButtonSize,\n isActionLoading,\n isActionProcessing,\n registerKeyBindings,\n resolveActionSize,\n} from '@alfakit/core'\nimport { Link } from '@inertiajs/vue3'\nimport { computed, watchEffect, type HTMLAttributes } from 'vue'\nimport { useStoreSelector } from '../../composables/use-store'\nimport { useActionRunner, useT } from '../../context'\nimport {\n badgeColorClasses,\n colorClass,\n ghostButtonColorClasses,\n outlineButtonColorClasses,\n solidButtonColorClasses,\n textColorClasses,\n} from '../../lib/colors'\nimport { Icon } from '../../lib/icons'\nimport { cn } from '../../lib/utils'\nimport Badge from '../ui/Badge.vue'\nimport Button from '../ui/Button.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport Tooltip from '../ui/Tooltip.vue'\nimport TooltipContent from '../ui/TooltipContent.vue'\nimport TooltipTrigger from '../ui/TooltipTrigger.vue'\n\nexport interface ActionButtonProps {\n action: ActionSchema\n context: ActionContext\n size?: 'xs' | 'sm' | 'default' | 'lg'\n class?: HTMLAttributes['class']\n /** Force a variant (e.g. menu items render as plain rows). */\n variant?: ActionSchema['variant']\n /** Bind the action's key bindings globally while mounted. */\n withKeyBindings?: boolean\n /** Override how the action runs (e.g. a form submits its values). */\n onTrigger?: (action: ActionSchema, context: ActionContext) => void | Promise<void>\n}\n\nconst props = withDefaults(defineProps<ActionButtonProps>(), {\n size: 'default',\n withKeyBindings: true,\n})\n\nconst runner = useActionRunner()\n// Only this run (this record's button), not the same action in every table row.\nconst loading = useStoreSelector(runner.store, (state) =>\n isActionLoading(state, props.action, props.context),\n)\nconst processing = useStoreSelector(runner.store, (state) =>\n isActionProcessing(state, props.action, props.context),\n)\n\nconst variant = computed(\n () =>\n props.variant ??\n (props.action.outlined\n ? 'outline'\n : (props.action.variant ??\n (props.action.hasAction || props.action.hasModal || props.action.url ? 'link' : 'button'))),\n)\nconst isIconOnly = computed(() => variant.value === 'icon-button' || !props.action.label)\nconst busy = computed(() => loading.value || processing.value)\n// A disabled link renders as a disabled button so it cannot navigate.\nconst isPlainLink = computed(() =>\n Boolean(\n props.action.url && !props.action.hasAction && !props.action.hasModal && !props.action.disabled,\n ),\n)\n// Record actions repeat per row: a global shortcut would run them for every record.\nconst bindsKeys = computed(\n () => props.withKeyBindings && bindsKeyBindings(props.action, props.context),\n)\n\n/** The badge trigger style (`badge()` without an argument). */\nconst BADGE_TRIGGER_CLASSES =\n \"h-auto min-h-6 gap-1 rounded-md border px-2 py-0.5 text-xs font-medium [&_svg:not([class*='size-'])]:size-3.5\"\n\nfunction buttonClasses(action: ActionSchema, kind: ActionSchema['variant']): string {\n const color = action.color ?? 'primary'\n\n switch (kind) {\n case 'outline':\n return cn('bg-background border', colorClass(outlineButtonColorClasses, color, 'gray'))\n case 'ghost':\n return colorClass(ghostButtonColorClasses, color, 'gray')\n case 'link':\n return cn(\n 'h-auto p-0 underline-offset-4 hover:underline has-[>svg]:px-0',\n colorClass(textColorClasses, color, 'primary'),\n )\n case 'icon-button':\n return colorClass(ghostButtonColorClasses, color, 'gray')\n case 'badge':\n // `badge()`: a tinted pill in the action's colour.\n return cn(BADGE_TRIGGER_CLASSES, colorClass(badgeColorClasses, color, 'primary'))\n default:\n return colorClass(solidButtonColorClasses, color, 'primary')\n }\n}\n\nconst run = () =>\n void (props.onTrigger\n ? props.onTrigger(props.action, props.context)\n : runner.trigger(props.action, props.context))\n\nwatchEffect((onCleanup) => {\n if (!bindsKeys.value || !props.action.keyBindings) {\n return\n }\n\n onCleanup(registerKeyBindings([{ keys: props.action.keyBindings, handler: run }]))\n})\n\nconst onClick = (event: MouseEvent) => {\n if (isPlainLink.value) {\n return // Plain link: let Inertia Link / anchor handle it.\n }\n\n event.preventDefault()\n run()\n}\n\nconst sizeProp = computed(() => {\n const size = variant.value === 'badge' ? 'xs' : resolveActionSize(props.action.size, props.size)\n\n return isIconOnly.value ? iconButtonSize(size) : size\n})\n// `labeledFrom()`: icon only below the breakpoint; the label stays the accessible name.\nconst LABEL_FROM: Record<string, string> = {\n sm: 'hidden sm:inline',\n md: 'hidden md:inline',\n lg: 'hidden lg:inline',\n xl: 'hidden xl:inline',\n '2xl': 'hidden 2xl:inline',\n}\nconst ICON_ONLY_BELOW: Record<string, string> = {\n sm: 'max-sm:aspect-square max-sm:px-0',\n md: 'max-md:aspect-square max-md:px-0',\n lg: 'max-lg:aspect-square max-lg:px-0',\n xl: 'max-xl:aspect-square max-xl:px-0',\n '2xl': 'max-2xl:aspect-square max-2xl:px-0',\n}\nconst labeledFrom = computed(() =>\n !isIconOnly.value && props.action.icon && props.action.labeledFrom\n ? props.action.labeledFrom\n : null,\n)\nconst labelClass = computed(() => (labeledFrom.value ? LABEL_FROM[labeledFrom.value] : undefined))\nconst classes = computed(() =>\n cn(\n buttonClasses(props.action, variant.value),\n labeledFrom.value && ICON_ONLY_BELOW[labeledFrom.value],\n props.class,\n ),\n)\nconst t = useT()\nconst newTabHint = computed(() => t('opens_in_new_tab', {}, '(opens in a new tab)'))\nconst ariaLabel = computed(() => {\n if (!isIconOnly.value && !labeledFrom.value) return undefined\n\n const name = props.action.label ?? props.action.tooltip ?? props.action.name\n\n return isPlainLink.value && props.action.openUrlInNewTab ? `${name} ${newTabHint.value}` : name\n})\nconst tooltip = computed(\n () => props.action.tooltip ?? (isIconOnly.value ? props.action.label : undefined),\n)\nconst shortcut = computed(() => (bindsKeys.value ? props.action.keyBindings?.[0] : undefined))\nconst disabledTooltip = computed(() => Boolean(props.action.disabled && tooltip.value))\n</script>\n\n<template>\n <Tooltip v-if=\"tooltip || shortcut\">\n <!-- A disabled button gets no pointer or focus events: a focusable span carries the\n tooltip (e.g. the reason from `authorizationTooltip()`). -->\n <TooltipTrigger\n :as-child=\"!disabledTooltip\"\n :as=\"disabledTooltip ? 'span' : undefined\"\n :tabindex=\"disabledTooltip ? 0 : undefined\"\n :class=\"disabledTooltip ? 'inline-flex' : undefined\"\n :data-disabled-tooltip=\"disabledTooltip ? '' : undefined\"\n >\n <Button\n v-if=\"isPlainLink && props.action.openUrlInNewTab\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <a :href=\"props.action.url\" target=\"_blank\" rel=\"noopener noreferrer\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <span v-if=\"!isIconOnly\" class=\"sr-only\"> {{ newTabHint }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </a>\n </Button>\n <Button\n v-else-if=\"isPlainLink\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <Link :href=\"props.action.url ?? '#'\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Link>\n </Button>\n <Button\n v-else\n type=\"button\"\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled || busy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n @click=\"onClick\"\n >\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Button>\n </TooltipTrigger>\n <TooltipContent>\n {{ tooltip }}\n <kbd\n v-if=\"shortcut\"\n dir=\"ltr\"\n class=\"ms-2 rounded border border-white/20 px-1 font-mono text-[10px]\"\n >{{ formatKeyBinding(shortcut) }}</kbd\n >\n </TooltipContent>\n </Tooltip>\n <template v-else>\n <Button\n v-if=\"isPlainLink && props.action.openUrlInNewTab\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <a :href=\"props.action.url\" target=\"_blank\" rel=\"noopener noreferrer\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <span v-if=\"!isIconOnly\" class=\"sr-only\"> {{ newTabHint }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </a>\n </Button>\n <Button\n v-else-if=\"isPlainLink\"\n as-child\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n >\n <Link :href=\"props.action.url ?? '#'\">\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Link>\n </Button>\n <Button\n v-else\n type=\"button\"\n variant=\"plain\"\n :size=\"sizeProp\"\n :class=\"classes\"\n :disabled=\"props.action.disabled || busy\"\n :aria-label=\"ariaLabel\"\n v-bind=\"props.action.extraAttributes\"\n @click=\"onClick\"\n >\n <Spinner v-if=\"busy\" />\n <Icon\n v-else-if=\"props.action.icon && props.action.iconPosition !== 'after'\"\n :name=\"props.action.icon\"\n />\n <span v-if=\"!isIconOnly\" :class=\"labelClass\">{{ props.action.label }}</span>\n <Icon\n v-if=\"props.action.icon && props.action.iconPosition === 'after' && !busy\"\n :name=\"props.action.icon\"\n />\n <Badge\n v-if=\"props.action.badge !== undefined && props.action.badge !== null\"\n variant=\"outline\"\n :class=\"\n cn('ms-1 px-1.5 py-0', colorClass(badgeColorClasses, props.action.badgeColor, 'gray'))\n \"\n >{{ props.action.badge }}</Badge\n >\n </Button>\n </template>\n</template>\n"],"mappings":"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"}
|
|
@@ -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 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 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 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 <span class=\"sr-only\">{{ t('close', {}, 'Close') }}</span>\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 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 +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":"AA2gBA,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;;AAygCvD,wBAOG"}
|