@alfakit/vue 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/components/actions/ActionButton.js.map +1 -1
  3. package/dist/components/actions/ActionButton.vue.d.ts.map +1 -1
  4. package/dist/components/actions/ActionButton.vue_vue_type_script_setup_true_lang.js +160 -159
  5. package/dist/components/actions/ActionButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/actions/ActionModal.js.map +1 -1
  7. package/dist/components/actions/ActionModal.vue.d.ts.map +1 -1
  8. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js +214 -214
  9. package/dist/components/actions/ActionModal.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/cms/CmsLinkButton.vue.d.ts +1 -1
  11. package/dist/components/fields/ColorPickerField.js.map +1 -1
  12. package/dist/components/fields/ColorPickerField.vue.d.ts.map +1 -1
  13. package/dist/components/fields/ColorPickerField.vue_vue_type_script_setup_true_lang.js +1 -0
  14. package/dist/components/fields/ColorPickerField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/fields/ComboboxSelect.js.map +1 -1
  16. package/dist/components/fields/ComboboxSelect.vue.d.ts.map +1 -1
  17. package/dist/components/fields/ComboboxSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  18. package/dist/components/fields/ComboboxSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/fields/FileUploadField.js.map +1 -1
  20. package/dist/components/fields/FileUploadField.vue.d.ts.map +1 -1
  21. package/dist/components/fields/FileUploadField.vue_vue_type_script_setup_true_lang.js +183 -183
  22. package/dist/components/fields/FileUploadField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/fields/OneTimeCodeInputField.js.map +1 -1
  24. package/dist/components/fields/OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js +1 -2
  25. package/dist/components/fields/OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/fields/SelectField.js.map +1 -1
  27. package/dist/components/fields/SelectField.vue.d.ts.map +1 -1
  28. package/dist/components/fields/SelectField.vue_vue_type_script_setup_true_lang.js +2 -2
  29. package/dist/components/fields/SelectField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/fields/TableColumnHeaders.js.map +1 -1
  31. package/dist/components/fields/TableColumnHeaders.vue.d.ts.map +1 -1
  32. package/dist/components/fields/TableColumnHeaders.vue_vue_type_script_setup_true_lang.js +6 -3
  33. package/dist/components/fields/TableColumnHeaders.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/file-manager/FileManagerView.js.map +1 -1
  35. package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js +1 -1
  36. package/dist/components/file-manager/FileManagerView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/form/FormBlock.js.map +1 -1
  38. package/dist/components/form/FormBlock.vue.d.ts.map +1 -1
  39. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js +81 -77
  40. package/dist/components/form/FormBlock.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/form/form-context.js +25 -25
  42. package/dist/components/form/form-context.js.map +1 -1
  43. package/dist/components/layout/FusedGroupComponent.js.map +1 -1
  44. package/dist/components/layout/FusedGroupComponent.vue.d.ts.map +1 -1
  45. package/dist/components/layout/FusedGroupComponent.vue_vue_type_script_setup_true_lang.js +1 -0
  46. package/dist/components/layout/FusedGroupComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  47. package/dist/components/layout/TabsComponent.js.map +1 -1
  48. package/dist/components/layout/TabsComponent.vue.d.ts.map +1 -1
  49. package/dist/components/layout/TabsComponent.vue_vue_type_script_setup_true_lang.js +76 -55
  50. package/dist/components/layout/TabsComponent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/notifications/NotificationsMenu.js.map +1 -1
  52. package/dist/components/notifications/NotificationsMenu.vue.d.ts.map +1 -1
  53. package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js +44 -42
  54. package/dist/components/notifications/NotificationsMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/components/panel/GlobalSearch.js.map +1 -1
  56. package/dist/components/panel/GlobalSearch.vue.d.ts.map +1 -1
  57. package/dist/components/panel/GlobalSearch.vue_vue_type_script_setup_true_lang.js +1 -0
  58. package/dist/components/panel/GlobalSearch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  59. package/dist/components/panel/ShortcutKeys.js.map +1 -1
  60. package/dist/components/panel/ShortcutKeys.vue.d.ts.map +1 -1
  61. package/dist/components/panel/ShortcutKeys.vue_vue_type_script_setup_true_lang.js +4 -1
  62. package/dist/components/panel/ShortcutKeys.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/panel/TenantMenu.js.map +1 -1
  64. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js +2 -2
  65. package/dist/components/panel/TenantMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/components/table/GroupHeaderRow.js.map +1 -1
  67. package/dist/components/table/GroupHeaderRow.vue.d.ts.map +1 -1
  68. package/dist/components/table/GroupHeaderRow.vue_vue_type_script_setup_true_lang.js +55 -34
  69. package/dist/components/table/GroupHeaderRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/table/SelectCell.js.map +1 -1
  71. package/dist/components/table/SelectCell.vue.d.ts.map +1 -1
  72. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js +24 -19
  73. package/dist/components/table/SelectCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/table/TextInputCell.js.map +1 -1
  75. package/dist/components/table/TextInputCell.vue.d.ts.map +1 -1
  76. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js +38 -33
  77. package/dist/components/table/TextInputCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components.css +347 -0
  79. package/dist/eject-manifest.json +2 -2
  80. package/dist/lib/Icon.js.map +1 -1
  81. package/dist/lib/Icon.vue.d.ts.map +1 -1
  82. package/dist/lib/Icon.vue_vue_type_script_setup_true_lang.js +18 -19
  83. package/dist/lib/Icon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/lib/hydration.d.ts +9 -0
  85. package/dist/lib/hydration.d.ts.map +1 -0
  86. package/dist/lib/hydration.js +17 -0
  87. package/dist/lib/hydration.js.map +1 -0
  88. package/dist/lib/icons.d.ts +3 -5
  89. package/dist/lib/icons.d.ts.map +1 -1
  90. package/dist/lib/icons.js +19 -22
  91. package/dist/lib/icons.js.map +1 -1
  92. package/dist/lib/lazy.d.ts +1 -1
  93. package/dist/lib/lazy.d.ts.map +1 -1
  94. package/dist/lib/lazy.js +12 -11
  95. package/dist/lib/lazy.js.map +1 -1
  96. package/dist/standalone/AlfakitToaster.js.map +1 -1
  97. package/dist/standalone/AlfakitToaster.vue.d.ts.map +1 -1
  98. package/dist/standalone/AlfakitToaster.vue_vue_type_script_setup_true_lang.js +23 -15
  99. package/dist/standalone/AlfakitToaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/standalone.css +47 -0
  101. package/dist/starter-kit/widgets/SearchTrigger.js.map +1 -1
  102. package/dist/starter-kit/widgets/SearchTrigger.vue.d.ts.map +1 -1
  103. package/dist/starter-kit/widgets/SearchTrigger.vue_vue_type_script_setup_true_lang.js +1 -0
  104. package/dist/starter-kit/widgets/SearchTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/starter-kit/widgets/TenantChooser.js.map +1 -1
  106. package/dist/starter-kit/widgets/TenantChooser.vue_vue_type_script_setup_true_lang.js +1 -1
  107. package/dist/starter-kit/widgets/TenantChooser.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/themes.css +2 -334
  109. package/package.json +3 -3
  110. package/src/components/actions/ActionButton.vue +14 -6
  111. package/src/components/actions/ActionModal.vue +3 -1
  112. package/src/components/fields/ColorPickerField.vue +1 -0
  113. package/src/components/fields/ComboboxSelect.vue +1 -1
  114. package/src/components/fields/FileUploadField.vue +14 -11
  115. package/src/components/fields/OneTimeCodeInputField.vue +1 -1
  116. package/src/components/fields/SelectField.vue +4 -2
  117. package/src/components/fields/TableColumnHeaders.vue +6 -1
  118. package/src/components/file-manager/FileManagerView.vue +1 -1
  119. package/src/components/form/FormBlock.vue +24 -0
  120. package/src/components/form/form-context.ts +2 -2
  121. package/src/components/layout/FusedGroupComponent.vue +1 -0
  122. package/src/components/layout/TabsComponent.vue +61 -5
  123. package/src/components/notifications/NotificationsMenu.vue +11 -0
  124. package/src/components/panel/GlobalSearch.vue +1 -0
  125. package/src/components/panel/ShortcutKeys.vue +1 -0
  126. package/src/components/panel/TenantMenu.vue +2 -2
  127. package/src/components/table/GroupHeaderRow.vue +27 -0
  128. package/src/components/table/SelectCell.vue +5 -2
  129. package/src/components/table/TextInputCell.vue +11 -5
  130. package/src/lib/Icon.vue +6 -5
  131. package/src/lib/hydration.ts +35 -0
  132. package/src/lib/icons.ts +6 -11
  133. package/src/lib/lazy.ts +5 -6
  134. package/src/standalone/AlfakitToaster.vue +12 -2
  135. package/src/starter-kit/widgets/SearchTrigger.vue +1 -0
  136. package/src/starter-kit/widgets/TenantChooser.vue +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"FileUploadField.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createElementVNode","_normalizeClass","_createElementBlock","_Fragment","_renderList","Button","_createVNode","_createCommentVNode","Spinner","_normalizeStyle","_toDisplayString","_withKeys","_withModifiers","Button_default","Spinner_default","FieldWrapper_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","ImageEditorDialog","lazyComponent","module","defineComponent","FileUploadField_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","choice","useChoice","panel","usePanel","fieldDisabled","useField","disabled","computed","readOnly","store","useFormStore","uploadingStore","fieldMemory","uploadedStore","uploadingState","useStore","uploadedState","uploading","next","uploaded","dragging","ref","inputRef","dragPath","editing","shallowRef","editorRequested","request","editImage","resolve","edited","objectUrls","releasePreview","url","paths","fileUploadPaths","value","files","file","path","maxFiles","canAddMore","circle","integrated","removeAtStart","progressAtStart","uploadAlign","commit","setValue","upload","endpoint","accepted","list","limit","concurrencyLimiter","queued","position","picked","original","edit","canEditImage","prepare","local","pendingFile","send","transformImage","canEditExisting","index","editableImageName","editExisting","existing","name","source","fetchEditableImage","response","uploadTemporaryFile","panelUploadOptions","item","current","replacing","discard","insertUploadedFile","uploadError","message","remove","requestJson","removeEntry","onDrop","event","onPaste","pasted","filesFromClipboard","onPick","input","move","moveRepeaterItem","from","to","reorderable","onItemDrop","hints","formatBytes","isImage","brokenPreviews","cssLength","openBlock","createBlock","unref","id","error","withCtx","createElementVNode","normalizeClass","cn","createElementBlock","Fragment","renderList","_cache","$event","createVNode","XIcon","createCommentVNode","normalizeStyle","FileIcon","toDisplayString","ChevronUpIcon","ChevronDownIcon","PencilIcon","uploadedFileLinks","ExternalLinkIcon","DownloadIcon","cssAspectRatio","aria","withKeys","withModifiers","UploadCloudIcon","fileUploadAccept"],"sources":["../../../src/components/fields/FileUploadField.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { defineComponent } from 'vue'\nimport { lazyComponent } from '../../lib/lazy'\n\n// The image editor's code loads with the first image to edit, not with the form.\nconst ImageEditorDialog = lazyComponent(\n 'ImageEditorDialog',\n () => import('./ImageEditorDialog.vue').then((module) => module.default),\n defineComponent({ name: 'ImageEditorDialogLoading', render: () => null }),\n)\n</script>\n\n<script setup lang=\"ts\">\nimport type { FileUploadSchema, UploadedFile } from '@alfakit/core'\nimport {\n canEditImage,\n concurrencyLimiter,\n cssAspectRatio,\n editableImageName,\n fetchEditableImage,\n fieldMemory,\n fileUploadAccept,\n filesFromClipboard,\n fileUploadPaths,\n formatBytes,\n insertUploadedFile,\n moveRepeaterItem,\n requestJson,\n transformImage,\n uploadedFileLinks,\n panelUploadOptions,\n uploadTemporaryFile,\n} from '@alfakit/core'\nimport {\n ChevronDownIcon,\n ChevronUpIcon,\n DownloadIcon,\n ExternalLinkIcon,\n FileIcon,\n PencilIcon,\n UploadCloudIcon,\n XIcon,\n} from '@lucide/vue'\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useChoice, usePanel, useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport { useField, useFormStore } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Button from '../ui/Button.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport type { ImageEditRequest } from './ImageEditorDialog.vue'\n\ninterface LocalFile extends UploadedFile {\n progress?: number\n error?: string\n preview?: string\n}\n\nconst props = defineProps<{ component: FileUploadSchema }>()\nconst t = useT()\nconst choice = useChoice()\nconst panel = usePanel()\nconst {\n value,\n setValue,\n error,\n id,\n disabled: fieldDisabled,\n readOnly,\n aria,\n} = useField<string | string[] | null>(() => props.component)\n// Read-only keeps open/download links but hides upload and remove controls.\nconst disabled = computed(() => fieldDisabled.value || readOnly.value)\nconst store = useFormStore()\n// In-flight uploads and the metadata of files uploaded in this session (the server schema\n// only knows about saved files) live in the form's field memory, not in component state:\n// a virtualised Repeater item unmounts when scrolled out of view and finds them again,\n// local image previews included, when it mounts back.\nconst uploadingStore = fieldMemory<LocalFile[]>(\n store,\n `${props.component.statePath}:uploading`,\n () => [],\n)\nconst uploadedStore = fieldMemory<FileUploadSchema['files']>(\n store,\n `${props.component.statePath}:uploaded`,\n () => [],\n)\nconst uploadingState = useStore(uploadingStore)\nconst uploadedState = useStore(uploadedStore)\nconst uploading = computed({\n get: () => uploadingState.value,\n set: (next: LocalFile[]) => uploadingStore.set(next),\n})\nconst uploaded = computed({\n get: () => uploadedState.value,\n set: (next: FileUploadSchema['files']) => uploadedStore.set(next),\n})\nconst dragging = ref(false)\nconst inputRef = ref<HTMLInputElement | null>(null)\nconst dragPath = ref<string | null>(null)\n// The image open in the editor (`imageEditor()`), one at a time.\nconst editing = shallowRef<ImageEditRequest | null>(null)\nconst editorRequested = ref(false)\n\nwatch(editing, (request) => {\n if (request) editorRequested.value = true\n})\nconst editImage = (file: File) =>\n new Promise<File | null>((resolve) => {\n editing.value = {\n file,\n resolve: (edited) => {\n editing.value = null\n resolve(edited)\n },\n }\n })\n// Object URLs made for local image previews; released when the file is removed.\nconst objectUrls = fieldMemory<Set<string>>(\n store,\n `${props.component.statePath}:previews`,\n () => new Set(),\n).get()\n\nconst releasePreview = (url: string | undefined) => {\n if (url && objectUrls.delete(url)) URL.revokeObjectURL(url)\n}\n\nconst paths = computed(() => fileUploadPaths(value.value))\nconst files = computed<LocalFile[]>(() =>\n paths.value.map(\n (path) =>\n [...props.component.files, ...uploaded.value].find((file) => file.path === path) ?? {\n path,\n name: path.replace(/^tmp:/, ''),\n },\n ),\n)\nconst maxFiles = computed(() =>\n props.component.multiple ? (props.component.maxFiles ?? Infinity) : 1,\n)\nconst canAddMore = computed(() => files.value.length + uploading.value.length < maxFiles.value)\nconst circle = computed(() => props.component.panelLayout === 'circle' || props.component.avatar)\nconst integrated = computed(() => props.component.panelLayout === 'integrated' && !circle.value)\nconst removeAtStart = computed(() => props.component.positions?.removeButton === 'start')\nconst progressAtStart = computed(() => props.component.positions?.progressIndicator === 'start')\nconst uploadAlign = computed(() => props.component.positions?.uploadButton ?? 'center')\n\nconst commit = (next: string[]) => setValue(props.component.multiple ? next : (next[0] ?? null))\n\nconst upload = async (list: FileList | File[]) => {\n const endpoint = panel.value.endpoints.upload\n\n if (!endpoint) {\n return\n }\n\n const accepted = Array.from(list).slice(\n 0,\n Math.max(0, maxFiles.value - files.value.length - uploading.value.length),\n )\n\n // `maxParallelUploads()`: files are prepared (edited, resized) one by one and then\n // queued, so at most that many upload at once.\n const limit = concurrencyLimiter(props.component.maxParallelUploads ?? 1)\n const queued: Promise<void>[] = []\n\n for (const [position, picked] of accepted.entries()) {\n let original = picked\n const edit = Boolean(props.component.imageEditor && canEditImage(picked))\n\n if (edit) {\n const edited = await editImage(picked)\n\n // Cancelled: the file is not uploaded.\n if (!edited) continue\n\n original = edited\n }\n\n const file = await prepare(original, edit)\n\n if (!file) continue\n\n const local = pendingFile(file, position)\n uploading.value = [...uploading.value, local]\n\n queued.push(limit(() => send(endpoint, file, local)))\n }\n\n await Promise.all(queued)\n}\n\n/** Resize and orient a picked (or edited) file, and check its size. Null when rejected. */\nconst prepare = async (original: File, edited: boolean): Promise<File | null> => {\n const file =\n props.component.imageCropAspectRatio ||\n props.component.imageResizeTargetWidth ||\n props.component.imageResizeTargetHeight ||\n props.component.orientImagesFromExif\n ? await transformImage(original, {\n // The editor already cropped the image.\n aspectRatio: edited ? null : props.component.imageCropAspectRatio,\n mode: props.component.imageResizeMode,\n width: props.component.imageResizeTargetWidth,\n height: props.component.imageResizeTargetHeight,\n orient: props.component.orientImagesFromExif,\n })\n : original\n\n if (props.component.minSize && file.size < props.component.minSize * 1024) {\n uploading.value = [\n ...uploading.value,\n {\n path: file.name,\n name: file.name,\n size: file.size,\n error: t('form.file_too_small', {}, 'This file is too small.'),\n },\n ]\n\n return null\n }\n\n if (props.component.maxSize && file.size > props.component.maxSize * 1024) {\n uploading.value = [\n ...uploading.value,\n {\n path: file.name,\n name: file.name,\n size: file.size,\n error: t('form.file_too_large', {}, 'This file is too large.'),\n },\n ]\n\n return null\n }\n\n return file\n}\n\n/** The in-progress entry shown while `file` uploads. */\nconst pendingFile = (file: File, position: number | string): LocalFile => {\n const local: LocalFile = {\n // Unique within the batch and across re-picks of a changed file.\n path: `pending:${position}:${file.lastModified}:${file.size}:${file.name}`,\n name: file.name,\n size: file.size,\n progress: 0,\n preview: file.type.startsWith('image/') ? URL.createObjectURL(file) : undefined,\n }\n if (local.preview) objectUrls.add(local.preview)\n\n return local\n}\n\n// `imageEditor()`: uploaded JPEG, PNG and WebP images can be edited again.\nconst canEditExisting = (file: LocalFile, index: number) =>\n Boolean(props.component.imageEditor) &&\n !disabled.value &&\n index < files.value.length &&\n !file.missing &&\n Boolean(file.url ?? file.preview) &&\n editableImageName(file) !== null\n\n/**\n * The \"Edit\" button on an uploaded image: open it in the editor and upload the result\n * in its place (the old file goes like any removed one: a temporary upload is deleted\n * now, a stored file when the form is saved with `deleteRemovedFiles()`).\n */\nconst editExisting = async (existing: LocalFile) => {\n const endpoint = panel.value.endpoints.upload\n const url = existing.url ?? existing.preview\n const name = editableImageName(existing)\n\n if (!endpoint || !url || !name) return\n\n const source = await fetchEditableImage(url, name)\n\n if (!source) {\n uploading.value = [\n ...uploading.value,\n {\n path: `failed:${existing.path}`,\n name: existing.name,\n error: t('image_editor.load_failed', {}, 'The image could not be opened.'),\n },\n ]\n\n return\n }\n\n const edited = await editImage(source)\n\n // Cancelled, or the editor couldn't decode it: keep the file as it is.\n if (!edited || edited === source) return\n\n const file = await prepare(edited, true)\n\n if (!file) return\n\n const local = pendingFile(file, `edit:${existing.path}`)\n uploading.value = [...uploading.value, local]\n await send(endpoint, file, local, existing.path)\n}\n\nconst send = async (endpoint: string, file: File, local: LocalFile, replacing?: string) => {\n try {\n // Large files go in resumable chunks; progress covers the whole file.\n const response = await uploadTemporaryFile(endpoint, file, {\n ...panelUploadOptions(panel.value, props.component.uploadPolicy),\n onProgress: (progress) => {\n uploading.value = uploading.value.map((item) =>\n item.path === local.path ? { ...item, progress } : item,\n )\n },\n })\n\n uploaded.value = [\n ...uploaded.value,\n {\n path: response.key,\n name: response.name,\n size: response.size,\n temporary: true,\n url: local.preview,\n },\n ]\n uploading.value = uploading.value.filter((item) => item.path !== local.path)\n // Read the store, not `value`: it may lag behind within a batch.\n const current = fileUploadPaths(\n store.getValue<string | string[] | null>(props.component.statePath, null),\n )\n\n if (replacing !== undefined && current.includes(replacing)) {\n // An edited image takes the old one's place.\n commit(current.map((path) => (path === replacing ? response.key : path)))\n discard(replacing)\n } else {\n commit(insertUploadedFile(current, response.key, props.component, maxFiles.value))\n }\n } catch (uploadError) {\n const message =\n (uploadError as { errors?: Record<string, string[]> }).errors?.file?.[0] ??\n (uploadError as Error).message\n uploading.value = uploading.value.map((item) =>\n item.path === local.path ? { ...item, error: message, progress: undefined } : item,\n )\n }\n}\n\nconst remove = (path: string) => {\n commit(paths.value.filter((item) => item !== path))\n discard(path)\n}\n\n/** Release a file that left the field: its preview, and a temporary upload's file. */\nconst discard = (path: string) => {\n releasePreview(uploadedStore.get().find((file) => file.path === path)?.url)\n\n if (path.startsWith('tmp:') && panel.value.endpoints.uploadDestroy) {\n void requestJson(panel.value.endpoints.uploadDestroy, {\n method: 'DELETE',\n body: { key: path },\n }).catch(() => undefined)\n }\n}\n\nconst removeEntry = (file: LocalFile) => {\n if (file.error || file.progress !== undefined) {\n releasePreview(file.preview)\n uploading.value = uploading.value.filter((item) => item.path !== file.path)\n } else {\n remove(file.path)\n }\n}\n\nconst onDrop = (event: DragEvent) => {\n event.preventDefault()\n dragging.value = false\n\n if (!disabled.value && event.dataTransfer && event.dataTransfer.files.length > 0) {\n void upload(event.dataTransfer.files)\n }\n}\n\n// `pasteable()`: images and files pasted while the drop zone has focus.\nconst onPaste = (event: ClipboardEvent) => {\n if (disabled.value || props.component.pasteable === false) return\n\n const pasted = filesFromClipboard(event.clipboardData)\n\n if (pasted.length > 0) {\n event.preventDefault()\n void upload(pasted)\n }\n}\n\nconst onPick = (event: Event) => {\n const input = event.target as HTMLInputElement\n // Copy the list: clearing the input empties it while the editor is open.\n const picked = input.files ? Array.from(input.files) : []\n input.value = ''\n void upload(picked)\n}\n\nconst move = (from: number, to: number) =>\n commit(moveRepeaterItem(paths.value, from, to) as string[])\nconst reorderable = computed(() =>\n Boolean(props.component.reorderable && props.component.multiple && !disabled.value),\n)\n\nconst onItemDrop = (event: DragEvent, index: number) => {\n if (!reorderable.value || dragPath.value === null) return\n event.preventDefault()\n event.stopPropagation()\n const from = paths.value.indexOf(dragPath.value)\n if (from !== -1 && index < files.value.length) move(from, index)\n dragPath.value = null\n}\n\nconst hints = computed(() =>\n [\n props.component.acceptedFileTypes?.join(', '),\n props.component.maxSize ? `≤ ${formatBytes(props.component.maxSize * 1024, 0)}` : null,\n props.component.minFiles\n ? choice(\n 'form.min_files',\n props.component.minFiles,\n {},\n 'At least :count file|At least :count files',\n )\n : null,\n ]\n .filter(Boolean)\n .join(' · '),\n)\n\n// `previewable(false)` shows every file as a name and icon, without the image.\nconst isImage = (file: LocalFile) =>\n props.component.previewable !== false &&\n (props.component.image || /\\.(png|jpe?g|gif|webp|svg|avif)$/i.test(file.name))\n\n// Previews whose image failed to load (missing or unreachable file) show the file icon.\nconst brokenPreviews = ref<ReadonlySet<string>>(new Set())\n\n/** `imagePreviewHeight()`: numbers are pixels, strings are CSS lengths (`'250px'`, `'10rem'`). */\nfunction cssLength(value: number | string): string {\n return typeof value === 'number' || /^\\d+(\\.\\d+)?$/.test(value) ? `${value}px` : value\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <div\n data-slot=\"file-upload\"\n :data-layout=\"props.component.panelLayout\"\n :class=\"cn('flex flex-col gap-3', integrated && 'rounded-md border p-2')\"\n >\n <ul\n v-if=\"files.length > 0 || uploading.length > 0\"\n :class=\"\n cn(\n 'grid gap-2',\n props.component.panelLayout === 'grid' && 'grid-cols-2 sm:grid-cols-3 md:grid-cols-4',\n circle && 'justify-items-center',\n )\n \"\n >\n <li\n v-for=\"(file, index) in [...files, ...uploading]\"\n :key=\"file.path\"\n :draggable=\"reorderable && index < files.length\"\n :class=\"\n cn(\n dragPath === file.path && 'opacity-50',\n 'bg-muted/30 relative flex min-w-0 items-center gap-3 overflow-hidden rounded-md border p-2 text-sm',\n circle && 'size-28 justify-center rounded-full border-0 p-0',\n file.error && 'border-destructive',\n )\n \"\n @dragstart=\"dragPath = file.path\"\n @dragover=\"reorderable && $event.preventDefault()\"\n @drop=\"onItemDrop($event, index)\"\n @dragend=\"dragPath = null\"\n >\n <Button\n v-if=\"!circle && removeAtStart && props.component.deletable && !disabled\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('remove', {}, 'Remove')\"\n @click=\"removeEntry(file)\"\n ><XIcon\n /></Button>\n <Spinner\n v-if=\"!circle && progressAtStart && file.progress !== undefined && !file.error\"\n />\n <img\n v-if=\"isImage(file) && (file.url || file.preview) && !brokenPreviews.has(file.path)\"\n :src=\"file.url ?? file.preview\"\n alt=\"\"\n :class=\"cn('size-12 shrink-0 rounded object-cover', circle && 'size-28 rounded-full')\"\n :style=\"\n !circle && props.component.imagePreviewHeight\n ? {\n height: cssLength(props.component.imagePreviewHeight),\n width: 'auto',\n maxWidth: '50%',\n }\n : undefined\n \"\n @error=\"brokenPreviews = new Set(brokenPreviews).add(file.path)\"\n />\n <FileIcon v-else-if=\"!circle\" class=\"text-muted-foreground size-6 shrink-0\" />\n <div v-if=\"!circle\" class=\"min-w-0 flex-1\">\n <p class=\"truncate font-medium\">{{ file.name }}</p>\n <p :class=\"cn('text-muted-foreground text-xs', file.missing && 'text-destructive')\">\n {{\n file.error ??\n (file.missing\n ? t('form.file_missing', {}, 'This file no longer exists.')\n : file.progress !== undefined && !file.error\n ? (props.component.uploadingMessage ?? t('form.uploading', {}, 'Uploading…'))\n : file.size\n ? formatBytes(file.size)\n : file.temporary\n ? t('form.uploading', {}, 'Pending')\n : '')\n }}\n </p>\n </div>\n <div :class=\"cn('flex items-center gap-1', circle && 'absolute -end-1 -bottom-1')\">\n <Spinner\n v-if=\"(circle || !progressAtStart) && file.progress !== undefined && !file.error\"\n />\n <template v-if=\"reorderable && index < files.length\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('form.move_up', {}, 'Move up')\"\n :disabled=\"index === 0\"\n @click=\"move(index, index - 1)\"\n ><ChevronUpIcon\n /></Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('form.move_down', {}, 'Move down')\"\n :disabled=\"index === files.length - 1\"\n @click=\"move(index, index + 1)\"\n ><ChevronDownIcon\n /></Button>\n </template>\n <Button\n v-if=\"canEditExisting(file, index)\"\n type=\"button\"\n :variant=\"circle ? 'secondary' : 'ghost'\"\n size=\"icon-xs\"\n :class=\"cn(circle && 'rounded-full shadow')\"\n :aria-label=\"t('image_editor.title', {}, 'Edit image')\"\n :title=\"t('image_editor.title', {}, 'Edit image')\"\n data-action=\"edit-image\"\n @click=\"void editExisting(file)\"\n ><PencilIcon\n /></Button>\n <Button\n v-if=\"props.component.openable && uploadedFileLinks(file).open\"\n as-child\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n >\n <a\n :href=\"uploadedFileLinks(file).open\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :aria-label=\"`${t('open', {}, 'Open')} ${t('opens_in_new_tab', {}, '(opens in a new tab)')}`\"\n ><ExternalLinkIcon\n /></a>\n </Button>\n <Button\n v-if=\"props.component.downloadable && uploadedFileLinks(file).download\"\n as-child\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n >\n <a\n :href=\"uploadedFileLinks(file).download\"\n download\n :aria-label=\"t('download', {}, 'Download')\"\n ><DownloadIcon\n /></a>\n </Button>\n <Button\n v-if=\"props.component.deletable && !disabled && (circle || !removeAtStart)\"\n type=\"button\"\n :variant=\"circle ? 'secondary' : 'ghost'\"\n size=\"icon-xs\"\n :class=\"cn(circle && 'rounded-full shadow')\"\n :aria-label=\"t('remove', {}, 'Remove')\"\n @click=\"removeEntry(file)\"\n ><XIcon\n /></Button>\n </div>\n </li>\n </ul>\n <div\n v-if=\"canAddMore && !disabled\"\n role=\"button\"\n tabindex=\"0\"\n :data-align=\"uploadAlign\"\n :style=\"\n !circle && props.component.panelAspectRatio\n ? { aspectRatio: cssAspectRatio(props.component.panelAspectRatio) }\n : undefined\n \"\n :class=\"\n cn(\n 'text-muted-foreground hover:border-ring flex cursor-pointer flex-col justify-center gap-1 rounded-md border border-dashed px-4 py-6 text-sm transition-colors',\n uploadAlign === 'start'\n ? 'items-start text-start'\n : uploadAlign === 'end'\n ? 'items-end text-end'\n : 'items-center text-center',\n integrated && 'border-transparent',\n dragging && 'border-ring bg-accent',\n circle && 'size-28 items-center rounded-full py-0',\n )\n \"\n :aria-describedby=\"aria['aria-describedby']\"\n @click=\"inputRef?.click()\"\n @keydown.enter.prevent=\"inputRef?.click()\"\n @keydown.space.prevent=\"inputRef?.click()\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop=\"onDrop\"\n @paste=\"onPaste\"\n >\n <UploadCloudIcon class=\"size-5\" />\n <span v-if=\"!circle\">{{\n props.component.placeholder ??\n t('form.drop_files', {}, 'Drop files here or click to browse')\n }}</span>\n <span v-if=\"!circle && hints\" class=\"text-muted-foreground text-xs\">{{ hints }}</span>\n </div>\n <input\n :id=\"id\"\n ref=\"inputRef\"\n type=\"file\"\n class=\"sr-only\"\n tabindex=\"-1\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :multiple=\"props.component.multiple\"\n :accept=\"fileUploadAccept(props.component)\"\n :disabled=\"disabled\"\n @change=\"onPick\"\n />\n <!-- Mounted from the first edit on (it stays for its closing animation). -->\n <ImageEditorDialog\n v-if=\"props.component.imageEditor && (editing || editorRequested)\"\n :request=\"editing\"\n :options=\"props.component.imageEditor\"\n />\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"FileUploadField.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createElementVNode","_normalizeClass","_createElementBlock","_Fragment","_renderList","Button","_createVNode","_createCommentVNode","Spinner","_normalizeStyle","_toDisplayString","_withKeys","_withModifiers","Button_default","Spinner_default","FieldWrapper_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","ImageEditorDialog","lazyComponent","module","defineComponent","FileUploadField_vue_vue_type_script_setup_true_lang_default","props","__props","t","useT","formatter","useFormatter","choice","useChoice","panel","usePanel","fieldDisabled","useField","disabled","computed","readOnly","store","useFormStore","uploadingStore","fieldMemory","uploadedStore","uploadingState","useStore","uploadedState","uploading","next","uploaded","dragging","ref","inputRef","dragPath","editing","shallowRef","editorRequested","request","editImage","resolve","edited","objectUrls","releasePreview","url","paths","fileUploadPaths","value","files","file","path","maxFiles","canAddMore","circle","integrated","removeAtStart","progressAtStart","uploadAlign","commit","setValue","upload","endpoint","accepted","list","limit","concurrencyLimiter","queued","position","picked","original","edit","canEditImage","prepare","local","pendingFile","send","transformImage","canEditExisting","index","editableImageName","editExisting","existing","name","source","fetchEditableImage","response","uploadTemporaryFile","panelUploadOptions","item","current","replacing","discard","insertUploadedFile","uploadError","message","remove","requestJson","removeEntry","onDrop","event","onPaste","pasted","filesFromClipboard","onPick","input","move","moveRepeaterItem","from","to","reorderable","onItemDrop","hints","fileManagerSize","isImage","brokenPreviews","cssLength","openBlock","createBlock","unref","id","error","withCtx","createElementVNode","normalizeClass","cn","createElementBlock","Fragment","renderList","_cache","$event","createVNode","XIcon","createCommentVNode","normalizeStyle","FileIcon","toDisplayString","ChevronUpIcon","ChevronDownIcon","PencilIcon","uploadedFileLinks","ExternalLinkIcon","DownloadIcon","cssAspectRatio","aria","withKeys","withModifiers","UploadCloudIcon","fileUploadAccept"],"sources":["../../../src/components/fields/FileUploadField.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { defineComponent } from 'vue'\nimport { lazyComponent } from '../../lib/lazy'\n\n// The image editor's code loads with the first image to edit, not with the form.\nconst ImageEditorDialog = lazyComponent(\n 'ImageEditorDialog',\n () => import('./ImageEditorDialog.vue').then((module) => module.default),\n defineComponent({ name: 'ImageEditorDialogLoading', render: () => null }),\n)\n</script>\n\n<script setup lang=\"ts\">\nimport type { FileUploadSchema, UploadedFile } from '@alfakit/core'\nimport {\n canEditImage,\n concurrencyLimiter,\n cssAspectRatio,\n editableImageName,\n fetchEditableImage,\n fieldMemory,\n fileUploadAccept,\n filesFromClipboard,\n fileUploadPaths,\n fileManagerSize,\n insertUploadedFile,\n moveRepeaterItem,\n requestJson,\n transformImage,\n uploadedFileLinks,\n panelUploadOptions,\n uploadTemporaryFile,\n} from '@alfakit/core'\nimport {\n ChevronDownIcon,\n ChevronUpIcon,\n DownloadIcon,\n ExternalLinkIcon,\n FileIcon,\n PencilIcon,\n UploadCloudIcon,\n XIcon,\n} from '@lucide/vue'\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport { useStore } from '../../composables/use-store'\nimport { useChoice, useFormatter, usePanel, useT } from '../../context'\nimport { cn } from '../../lib/utils'\nimport { useField, useFormStore } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Button from '../ui/Button.vue'\nimport Spinner from '../ui/Spinner.vue'\nimport type { ImageEditRequest } from './ImageEditorDialog.vue'\n\ninterface LocalFile extends UploadedFile {\n progress?: number\n error?: string\n preview?: string\n}\n\nconst props = defineProps<{ component: FileUploadSchema }>()\nconst t = useT()\nconst formatter = useFormatter()\nconst choice = useChoice()\nconst panel = usePanel()\nconst {\n value,\n setValue,\n error,\n id,\n disabled: fieldDisabled,\n readOnly,\n aria,\n} = useField<string | string[] | null>(() => props.component)\n// Read-only keeps open/download links but hides upload and remove controls.\nconst disabled = computed(() => fieldDisabled.value || readOnly.value)\nconst store = useFormStore()\n// In-flight uploads and the metadata of files uploaded in this session (the server schema\n// only knows about saved files) live in the form's field memory, not in component state:\n// a virtualised Repeater item unmounts when scrolled out of view and finds them again,\n// local image previews included, when it mounts back.\nconst uploadingStore = fieldMemory<LocalFile[]>(\n store,\n `${props.component.statePath}:uploading`,\n () => [],\n)\nconst uploadedStore = fieldMemory<FileUploadSchema['files']>(\n store,\n `${props.component.statePath}:uploaded`,\n () => [],\n)\nconst uploadingState = useStore(uploadingStore)\nconst uploadedState = useStore(uploadedStore)\nconst uploading = computed({\n get: () => uploadingState.value,\n set: (next: LocalFile[]) => uploadingStore.set(next),\n})\nconst uploaded = computed({\n get: () => uploadedState.value,\n set: (next: FileUploadSchema['files']) => uploadedStore.set(next),\n})\nconst dragging = ref(false)\nconst inputRef = ref<HTMLInputElement | null>(null)\nconst dragPath = ref<string | null>(null)\n// The image open in the editor (`imageEditor()`), one at a time.\nconst editing = shallowRef<ImageEditRequest | null>(null)\nconst editorRequested = ref(false)\n\nwatch(editing, (request) => {\n if (request) editorRequested.value = true\n})\nconst editImage = (file: File) =>\n new Promise<File | null>((resolve) => {\n editing.value = {\n file,\n resolve: (edited) => {\n editing.value = null\n resolve(edited)\n },\n }\n })\n// Object URLs made for local image previews; released when the file is removed.\nconst objectUrls = fieldMemory<Set<string>>(\n store,\n `${props.component.statePath}:previews`,\n () => new Set(),\n).get()\n\nconst releasePreview = (url: string | undefined) => {\n if (url && objectUrls.delete(url)) URL.revokeObjectURL(url)\n}\n\nconst paths = computed(() => fileUploadPaths(value.value))\nconst files = computed<LocalFile[]>(() =>\n paths.value.map(\n (path) =>\n [...props.component.files, ...uploaded.value].find((file) => file.path === path) ?? {\n path,\n name: path.replace(/^tmp:/, ''),\n },\n ),\n)\nconst maxFiles = computed(() =>\n props.component.multiple ? (props.component.maxFiles ?? Infinity) : 1,\n)\nconst canAddMore = computed(() => files.value.length + uploading.value.length < maxFiles.value)\nconst circle = computed(() => props.component.panelLayout === 'circle' || props.component.avatar)\nconst integrated = computed(() => props.component.panelLayout === 'integrated' && !circle.value)\nconst removeAtStart = computed(() => props.component.positions?.removeButton === 'start')\nconst progressAtStart = computed(() => props.component.positions?.progressIndicator === 'start')\nconst uploadAlign = computed(() => props.component.positions?.uploadButton ?? 'center')\n\nconst commit = (next: string[]) => setValue(props.component.multiple ? next : (next[0] ?? null))\n\nconst upload = async (list: FileList | File[]) => {\n const endpoint = panel.value.endpoints.upload\n\n if (!endpoint) {\n return\n }\n\n const accepted = Array.from(list).slice(\n 0,\n Math.max(0, maxFiles.value - files.value.length - uploading.value.length),\n )\n\n // `maxParallelUploads()`: files are prepared (edited, resized) one by one and then\n // queued, so at most that many upload at once.\n const limit = concurrencyLimiter(props.component.maxParallelUploads ?? 1)\n const queued: Promise<void>[] = []\n\n for (const [position, picked] of accepted.entries()) {\n let original = picked\n const edit = Boolean(props.component.imageEditor && canEditImage(picked))\n\n if (edit) {\n const edited = await editImage(picked)\n\n // Cancelled: the file is not uploaded.\n if (!edited) continue\n\n original = edited\n }\n\n const file = await prepare(original, edit)\n\n if (!file) continue\n\n const local = pendingFile(file, position)\n uploading.value = [...uploading.value, local]\n\n queued.push(limit(() => send(endpoint, file, local)))\n }\n\n await Promise.all(queued)\n}\n\n/** Resize and orient a picked (or edited) file, and check its size. Null when rejected. */\nconst prepare = async (original: File, edited: boolean): Promise<File | null> => {\n const file =\n props.component.imageCropAspectRatio ||\n props.component.imageResizeTargetWidth ||\n props.component.imageResizeTargetHeight ||\n props.component.orientImagesFromExif\n ? await transformImage(original, {\n // The editor already cropped the image.\n aspectRatio: edited ? null : props.component.imageCropAspectRatio,\n mode: props.component.imageResizeMode,\n width: props.component.imageResizeTargetWidth,\n height: props.component.imageResizeTargetHeight,\n orient: props.component.orientImagesFromExif,\n })\n : original\n\n if (props.component.minSize && file.size < props.component.minSize * 1024) {\n uploading.value = [\n ...uploading.value,\n {\n path: file.name,\n name: file.name,\n size: file.size,\n error: t('form.file_too_small', {}, 'This file is too small.'),\n },\n ]\n\n return null\n }\n\n if (props.component.maxSize && file.size > props.component.maxSize * 1024) {\n uploading.value = [\n ...uploading.value,\n {\n path: file.name,\n name: file.name,\n size: file.size,\n error: t('form.file_too_large', {}, 'This file is too large.'),\n },\n ]\n\n return null\n }\n\n return file\n}\n\n/** The in-progress entry shown while `file` uploads. */\nconst pendingFile = (file: File, position: number | string): LocalFile => {\n const local: LocalFile = {\n // Unique within the batch and across re-picks of a changed file.\n path: `pending:${position}:${file.lastModified}:${file.size}:${file.name}`,\n name: file.name,\n size: file.size,\n progress: 0,\n preview: file.type.startsWith('image/') ? URL.createObjectURL(file) : undefined,\n }\n if (local.preview) objectUrls.add(local.preview)\n\n return local\n}\n\n// `imageEditor()`: uploaded JPEG, PNG and WebP images can be edited again.\nconst canEditExisting = (file: LocalFile, index: number) =>\n Boolean(props.component.imageEditor) &&\n !disabled.value &&\n index < files.value.length &&\n !file.missing &&\n Boolean(file.url ?? file.preview) &&\n editableImageName(file) !== null\n\n/**\n * The \"Edit\" button on an uploaded image: open it in the editor and upload the result\n * in its place (the old file goes like any removed one: a temporary upload is deleted\n * now, a stored file when the form is saved with `deleteRemovedFiles()`).\n */\nconst editExisting = async (existing: LocalFile) => {\n const endpoint = panel.value.endpoints.upload\n const url = existing.url ?? existing.preview\n const name = editableImageName(existing)\n\n if (!endpoint || !url || !name) return\n\n const source = await fetchEditableImage(url, name)\n\n if (!source) {\n uploading.value = [\n ...uploading.value,\n {\n path: `failed:${existing.path}`,\n name: existing.name,\n error: t('image_editor.load_failed', {}, 'The image could not be opened.'),\n },\n ]\n\n return\n }\n\n const edited = await editImage(source)\n\n // Cancelled, or the editor couldn't decode it: keep the file as it is.\n if (!edited || edited === source) return\n\n const file = await prepare(edited, true)\n\n if (!file) return\n\n const local = pendingFile(file, `edit:${existing.path}`)\n uploading.value = [...uploading.value, local]\n await send(endpoint, file, local, existing.path)\n}\n\nconst send = async (endpoint: string, file: File, local: LocalFile, replacing?: string) => {\n try {\n // Large files go in resumable chunks; progress covers the whole file.\n const response = await uploadTemporaryFile(endpoint, file, {\n ...panelUploadOptions(panel.value, props.component.uploadPolicy),\n onProgress: (progress) => {\n uploading.value = uploading.value.map((item) =>\n item.path === local.path ? { ...item, progress } : item,\n )\n },\n })\n\n uploaded.value = [\n ...uploaded.value,\n {\n path: response.key,\n name: response.name,\n size: response.size,\n temporary: true,\n url: local.preview,\n },\n ]\n uploading.value = uploading.value.filter((item) => item.path !== local.path)\n // Read the store, not `value`: it may lag behind within a batch.\n const current = fileUploadPaths(\n store.getValue<string | string[] | null>(props.component.statePath, null),\n )\n\n if (replacing !== undefined && current.includes(replacing)) {\n // An edited image takes the old one's place.\n commit(current.map((path) => (path === replacing ? response.key : path)))\n discard(replacing)\n } else {\n commit(insertUploadedFile(current, response.key, props.component, maxFiles.value))\n }\n } catch (uploadError) {\n const message =\n (uploadError as { errors?: Record<string, string[]> }).errors?.file?.[0] ??\n (uploadError as Error).message\n uploading.value = uploading.value.map((item) =>\n item.path === local.path ? { ...item, error: message, progress: undefined } : item,\n )\n }\n}\n\nconst remove = (path: string) => {\n commit(paths.value.filter((item) => item !== path))\n discard(path)\n}\n\n/** Release a file that left the field: its preview, and a temporary upload's file. */\nconst discard = (path: string) => {\n releasePreview(uploadedStore.get().find((file) => file.path === path)?.url)\n\n if (path.startsWith('tmp:') && panel.value.endpoints.uploadDestroy) {\n void requestJson(panel.value.endpoints.uploadDestroy, {\n method: 'DELETE',\n body: { key: path },\n }).catch(() => undefined)\n }\n}\n\nconst removeEntry = (file: LocalFile) => {\n if (file.error || file.progress !== undefined) {\n releasePreview(file.preview)\n uploading.value = uploading.value.filter((item) => item.path !== file.path)\n } else {\n remove(file.path)\n }\n}\n\nconst onDrop = (event: DragEvent) => {\n event.preventDefault()\n dragging.value = false\n\n if (!disabled.value && event.dataTransfer && event.dataTransfer.files.length > 0) {\n void upload(event.dataTransfer.files)\n }\n}\n\n// `pasteable()`: images and files pasted while the drop zone has focus.\nconst onPaste = (event: ClipboardEvent) => {\n if (disabled.value || props.component.pasteable === false) return\n\n const pasted = filesFromClipboard(event.clipboardData)\n\n if (pasted.length > 0) {\n event.preventDefault()\n void upload(pasted)\n }\n}\n\nconst onPick = (event: Event) => {\n const input = event.target as HTMLInputElement\n // Copy the list: clearing the input empties it while the editor is open.\n const picked = input.files ? Array.from(input.files) : []\n input.value = ''\n void upload(picked)\n}\n\nconst move = (from: number, to: number) =>\n commit(moveRepeaterItem(paths.value, from, to) as string[])\nconst reorderable = computed(() =>\n Boolean(props.component.reorderable && props.component.multiple && !disabled.value),\n)\n\nconst onItemDrop = (event: DragEvent, index: number) => {\n if (!reorderable.value || dragPath.value === null) return\n event.preventDefault()\n event.stopPropagation()\n const from = paths.value.indexOf(dragPath.value)\n if (from !== -1 && index < files.value.length) move(from, index)\n dragPath.value = null\n}\n\nconst hints = computed(() =>\n [\n props.component.acceptedFileTypes?.join(', '),\n props.component.maxSize\n ? `≤ ${fileManagerSize(props.component.maxSize * 1024, formatter.value)}`\n : null,\n props.component.minFiles\n ? choice(\n 'form.min_files',\n props.component.minFiles,\n {},\n 'At least :count file|At least :count files',\n )\n : null,\n ]\n .filter(Boolean)\n .join(' · '),\n)\n\n// `previewable(false)` shows every file as a name and icon, without the image.\nconst isImage = (file: LocalFile) =>\n props.component.previewable !== false &&\n (props.component.image || /\\.(png|jpe?g|gif|webp|svg|avif)$/i.test(file.name))\n\n// Previews whose image failed to load (missing or unreachable file) show the file icon.\nconst brokenPreviews = ref<ReadonlySet<string>>(new Set())\n\n/** `imagePreviewHeight()`: numbers are pixels, strings are CSS lengths (`'250px'`, `'10rem'`). */\nfunction cssLength(value: number | string): string {\n return typeof value === 'number' || /^\\d+(\\.\\d+)?$/.test(value) ? `${value}px` : value\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <div\n data-slot=\"file-upload\"\n :data-layout=\"props.component.panelLayout\"\n :class=\"cn('flex flex-col gap-3', integrated && 'rounded-md border p-2')\"\n >\n <ul\n v-if=\"files.length > 0 || uploading.length > 0\"\n :class=\"\n cn(\n 'grid gap-2',\n props.component.panelLayout === 'grid' && 'grid-cols-2 sm:grid-cols-3 md:grid-cols-4',\n circle && 'justify-items-center',\n )\n \"\n >\n <li\n v-for=\"(file, index) in [...files, ...uploading]\"\n :key=\"file.path\"\n :draggable=\"reorderable && index < files.length\"\n :class=\"\n cn(\n dragPath === file.path && 'opacity-50',\n 'bg-muted/30 relative flex min-w-0 items-center gap-3 overflow-hidden rounded-md border p-2 text-sm',\n circle && 'size-28 justify-center rounded-full border-0 p-0',\n file.error && 'border-destructive',\n )\n \"\n @dragstart=\"dragPath = file.path\"\n @dragover=\"reorderable && $event.preventDefault()\"\n @drop=\"onItemDrop($event, index)\"\n @dragend=\"dragPath = null\"\n >\n <Button\n v-if=\"!circle && removeAtStart && props.component.deletable && !disabled\"\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('file_upload.remove', { name: file.name }, 'Remove :name')\"\n @click=\"removeEntry(file)\"\n ><XIcon\n /></Button>\n <Spinner\n v-if=\"!circle && progressAtStart && file.progress !== undefined && !file.error\"\n />\n <img\n v-if=\"isImage(file) && (file.url || file.preview) && !brokenPreviews.has(file.path)\"\n :src=\"file.url ?? file.preview\"\n alt=\"\"\n :class=\"cn('size-12 shrink-0 rounded object-cover', circle && 'size-28 rounded-full')\"\n :style=\"\n !circle && props.component.imagePreviewHeight\n ? {\n height: cssLength(props.component.imagePreviewHeight),\n width: 'auto',\n maxWidth: '50%',\n }\n : undefined\n \"\n @error=\"brokenPreviews = new Set(brokenPreviews).add(file.path)\"\n />\n <FileIcon v-else-if=\"!circle\" class=\"text-muted-foreground size-6 shrink-0\" />\n <div v-if=\"!circle\" class=\"min-w-0 flex-1\">\n <p class=\"truncate font-medium\">{{ file.name }}</p>\n <p :class=\"cn('text-muted-foreground text-xs', file.missing && 'text-destructive')\">\n {{\n file.error ??\n (file.missing\n ? t('form.file_missing', {}, 'This file no longer exists.')\n : file.progress !== undefined && !file.error\n ? (props.component.uploadingMessage ?? t('form.uploading', {}, 'Uploading…'))\n : file.size\n ? fileManagerSize(file.size, formatter)\n : file.temporary\n ? t('form.uploading', {}, 'Pending')\n : '')\n }}\n </p>\n </div>\n <div :class=\"cn('flex items-center gap-1', circle && 'absolute -end-1 -bottom-1')\">\n <Spinner\n v-if=\"(circle || !progressAtStart) && file.progress !== undefined && !file.error\"\n />\n <template v-if=\"reorderable && index < files.length\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('file_upload.move_up', { name: file.name }, 'Move :name up')\"\n :disabled=\"index === 0\"\n @click=\"move(index, index - 1)\"\n ><ChevronUpIcon\n /></Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n :aria-label=\"t('file_upload.move_down', { name: file.name }, 'Move :name down')\"\n :disabled=\"index === files.length - 1\"\n @click=\"move(index, index + 1)\"\n ><ChevronDownIcon\n /></Button>\n </template>\n <Button\n v-if=\"canEditExisting(file, index)\"\n type=\"button\"\n :variant=\"circle ? 'secondary' : 'ghost'\"\n size=\"icon-xs\"\n :class=\"cn(circle && 'rounded-full shadow')\"\n :aria-label=\"t('file_upload.edit', { name: file.name }, 'Edit :name')\"\n :title=\"t('image_editor.title', {}, 'Edit image')\"\n data-action=\"edit-image\"\n @click=\"void editExisting(file)\"\n ><PencilIcon\n /></Button>\n <Button\n v-if=\"props.component.openable && uploadedFileLinks(file).open\"\n as-child\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n >\n <a\n :href=\"uploadedFileLinks(file).open\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :aria-label=\"`${t('file_upload.open', { name: file.name }, 'Open :name')} ${t('opens_in_new_tab', {}, '(opens in a new tab)')}`\"\n ><ExternalLinkIcon\n /></a>\n </Button>\n <Button\n v-if=\"props.component.downloadable && uploadedFileLinks(file).download\"\n as-child\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n >\n <a\n :href=\"uploadedFileLinks(file).download\"\n download\n :aria-label=\"t('file_upload.download', { name: file.name }, 'Download :name')\"\n ><DownloadIcon\n /></a>\n </Button>\n <Button\n v-if=\"props.component.deletable && !disabled && (circle || !removeAtStart)\"\n type=\"button\"\n :variant=\"circle ? 'secondary' : 'ghost'\"\n size=\"icon-xs\"\n :class=\"cn(circle && 'rounded-full shadow')\"\n :aria-label=\"t('file_upload.remove', { name: file.name }, 'Remove :name')\"\n @click=\"removeEntry(file)\"\n ><XIcon\n /></Button>\n </div>\n </li>\n </ul>\n <div\n v-if=\"canAddMore && !disabled\"\n role=\"button\"\n tabindex=\"0\"\n :data-align=\"uploadAlign\"\n :style=\"\n !circle && props.component.panelAspectRatio\n ? { aspectRatio: cssAspectRatio(props.component.panelAspectRatio) }\n : undefined\n \"\n :class=\"\n cn(\n 'text-muted-foreground hover:border-ring flex cursor-pointer flex-col justify-center gap-1 rounded-md border border-dashed px-4 py-6 text-sm transition-colors',\n uploadAlign === 'start'\n ? 'items-start text-start'\n : uploadAlign === 'end'\n ? 'items-end text-end'\n : 'items-center text-center',\n integrated && 'border-transparent',\n dragging && 'border-ring bg-accent',\n circle && 'size-28 items-center rounded-full py-0',\n )\n \"\n :aria-describedby=\"aria['aria-describedby']\"\n @click=\"inputRef?.click()\"\n @keydown.enter.prevent=\"inputRef?.click()\"\n @keydown.space.prevent=\"inputRef?.click()\"\n @dragover.prevent=\"dragging = true\"\n @dragleave=\"dragging = false\"\n @drop=\"onDrop\"\n @paste=\"onPaste\"\n >\n <UploadCloudIcon class=\"size-5\" />\n <span v-if=\"!circle\">{{\n props.component.placeholder ??\n t('form.drop_files', {}, 'Drop files here or click to browse')\n }}</span>\n <span v-if=\"!circle && hints\" class=\"text-muted-foreground text-xs\">{{ hints }}</span>\n </div>\n <input\n :id=\"id\"\n ref=\"inputRef\"\n type=\"file\"\n class=\"sr-only\"\n tabindex=\"-1\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :multiple=\"props.component.multiple\"\n :accept=\"fileUploadAccept(props.component)\"\n :disabled=\"disabled\"\n @change=\"onPick\"\n />\n <!-- Mounted from the first edit on (it stays for its closing animation). -->\n <ImageEditorDialog\n v-if=\"props.component.imageEditor && (editing || editorRequested)\"\n :request=\"editing\"\n :options=\"props.component.imageEditor\"\n />\n </div>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"OneTimeCodeInputField.js","names":["_sfc_main","OneTimeCodeInputField_vue_vue_type_script_setup_true_lang_default","OneTimeCodeInputField_default"],"sources":["../../../src/components/fields/OneTimeCodeInputField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { OneTimeCodeSubmitter, oneTimeCodeDigits, type OneTimeCodeInputSchema } from '@alfakit/core'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Input from '../ui/Input.vue'\n\n/**\n * `OneTimeCodeInput`: one numeric input with `autocomplete=\"one-time-code\"` (browsers and\n * password managers fill it from an SMS or email), digits only, left to right in every\n * language. `submitOnCompletion()` submits the form once the last digit is in.\n */\nconst props = defineProps<{ component: OneTimeCodeInputSchema }>()\nconst { value, setValue, blur, error, id, disabled, aria } = useField<string | null>(\n () => props.component,\n)\nconst submitter = new OneTimeCodeSubmitter()\n\nconst onInput = (event: Event) => {\n const input = event.target as HTMLInputElement\n const code = oneTimeCodeDigits(input.value, props.component.length)\n\n // A rejected character leaves the model value unchanged: correct the DOM too.\n if (code !== input.value) input.value = code\n\n setValue(code === '' ? null : code)\n\n // After the state reached the form store, so the submitted values include it.\n if (props.component.submitOnCompletion) {\n const form = input.form\n\n queueMicrotask(() => submitter.update(code, props.component.length, form))\n }\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <Input\n :id=\"id\"\n :name=\"props.component.name\"\n type=\"text\"\n dir=\"ltr\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n pattern=\"[0-9]*\"\n :maxlength=\"props.component.length\"\n :model-value=\"value ?? ''\"\n :placeholder=\"props.component.placeholder\"\n :disabled=\"disabled\"\n :readonly=\"props.component.readOnly\"\n :required=\"props.component.required\"\n :autofocus=\"props.component.autofocus\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n data-slot=\"one-time-code-input\"\n class=\"max-w-56 text-center font-mono text-lg tracking-[0.5em] tabular-nums\"\n v-bind=\"props.component.extraInputAttributes\"\n @input=\"onInput\"\n @blur=\"blur\"\n />\n </FieldWrapper>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"OneTimeCodeInputField.js","names":["_sfc_main","OneTimeCodeInputField_vue_vue_type_script_setup_true_lang_default","OneTimeCodeInputField_default"],"sources":["../../../src/components/fields/OneTimeCodeInputField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { OneTimeCodeSubmitter, oneTimeCodeDigits, type OneTimeCodeInputSchema } from '@alfakit/core'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Input from '../ui/Input.vue'\n\n/**\n * `OneTimeCodeInput`: one numeric input with `autocomplete=\"one-time-code\"` (browsers and\n * password managers fill it from an SMS or email), digits only, left to right in every\n * language. `submitOnCompletion()` submits the form once the last digit is in.\n */\nconst props = defineProps<{ component: OneTimeCodeInputSchema }>()\nconst { value, setValue, blur, error, id, disabled, aria } = useField<string | null>(\n () => props.component,\n)\nconst submitter = new OneTimeCodeSubmitter()\n\nconst onInput = (event: Event) => {\n const input = event.target as HTMLInputElement\n const code = oneTimeCodeDigits(input.value, props.component.length)\n\n // A rejected character leaves the model value unchanged: correct the DOM too.\n if (code !== input.value) input.value = code\n\n setValue(code === '' ? null : code)\n\n // After the state reached the form store, so the submitted values include it.\n if (props.component.submitOnCompletion) {\n const form = input.form\n\n queueMicrotask(() => submitter.update(code, props.component.length, form))\n }\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <Input\n :id=\"id\"\n :name=\"props.component.name\"\n type=\"text\"\n dir=\"ltr\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n pattern=\"[0-9]*\"\n :model-value=\"value ?? ''\"\n :placeholder=\"props.component.placeholder\"\n :disabled=\"disabled\"\n :readonly=\"props.component.readOnly\"\n :required=\"props.component.required\"\n :autofocus=\"props.component.autofocus\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n data-slot=\"one-time-code-input\"\n data-input=\"\"\n class=\"max-w-56 text-center font-mono text-lg tracking-[0.5em] tabular-nums\"\n v-bind=\"props.component.extraInputAttributes\"\n @input=\"onInput\"\n @blur=\"blur\"\n />\n </FieldWrapper>\n</template>\n"],"mappings":""}
@@ -28,7 +28,6 @@ var f = /*@__PURE__*/ s({
28
28
  inputmode: "numeric",
29
29
  autocomplete: "one-time-code",
30
30
  pattern: "[0-9]*",
31
- maxlength: f.component.length,
32
31
  "model-value": u(p) ?? "",
33
32
  placeholder: f.component.placeholder,
34
33
  disabled: u(v),
@@ -39,6 +38,7 @@ var f = /*@__PURE__*/ s({
39
38
  "aria-describedby": u(y)["aria-describedby"],
40
39
  "aria-required": u(y)["aria-required"],
41
40
  "data-slot": "one-time-code-input",
41
+ "data-input": "",
42
42
  class: "max-w-56 text-center font-mono text-lg tracking-[0.5em] tabular-nums"
43
43
  }, f.component.extraInputAttributes, {
44
44
  onInput: x,
@@ -46,7 +46,6 @@ var f = /*@__PURE__*/ s({
46
46
  }), null, 16, [
47
47
  "id",
48
48
  "name",
49
- "maxlength",
50
49
  "model-value",
51
50
  "placeholder",
52
51
  "disabled",
@@ -1 +1 @@
1
- {"version":3,"file":"OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createVNode","Input","_mergeProps","Input_default","FieldWrapper_default","OneTimeCodeInputField_vue_vue_type_script_setup_true_lang_default","props","__props","useField","submitter","OneTimeCodeSubmitter","onInput","input","event","code","oneTimeCodeDigits","setValue","form","openBlock","createBlock","unref","id","error","withCtx","createVNode","mergeProps","value","disabled","aria","blur"],"sources":["../../../src/components/fields/OneTimeCodeInputField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { OneTimeCodeSubmitter, oneTimeCodeDigits, type OneTimeCodeInputSchema } from '@alfakit/core'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Input from '../ui/Input.vue'\n\n/**\n * `OneTimeCodeInput`: one numeric input with `autocomplete=\"one-time-code\"` (browsers and\n * password managers fill it from an SMS or email), digits only, left to right in every\n * language. `submitOnCompletion()` submits the form once the last digit is in.\n */\nconst props = defineProps<{ component: OneTimeCodeInputSchema }>()\nconst { value, setValue, blur, error, id, disabled, aria } = useField<string | null>(\n () => props.component,\n)\nconst submitter = new OneTimeCodeSubmitter()\n\nconst onInput = (event: Event) => {\n const input = event.target as HTMLInputElement\n const code = oneTimeCodeDigits(input.value, props.component.length)\n\n // A rejected character leaves the model value unchanged: correct the DOM too.\n if (code !== input.value) input.value = code\n\n setValue(code === '' ? null : code)\n\n // After the state reached the form store, so the submitted values include it.\n if (props.component.submitOnCompletion) {\n const form = input.form\n\n queueMicrotask(() => submitter.update(code, props.component.length, form))\n }\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <Input\n :id=\"id\"\n :name=\"props.component.name\"\n type=\"text\"\n dir=\"ltr\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n pattern=\"[0-9]*\"\n :maxlength=\"props.component.length\"\n :model-value=\"value ?? ''\"\n :placeholder=\"props.component.placeholder\"\n :disabled=\"disabled\"\n :readonly=\"props.component.readOnly\"\n :required=\"props.component.required\"\n :autofocus=\"props.component.autofocus\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n data-slot=\"one-time-code-input\"\n class=\"max-w-56 text-center font-mono text-lg tracking-[0.5em] tabular-nums\"\n v-bind=\"props.component.extraInputAttributes\"\n @input=\"onInput\"\n @blur=\"blur\"\n />\n </FieldWrapper>\n</template>\n"],"mappings":";;;;;;;;;;EAWA,IAAMW,IAAQC,GACR,EAAE,UAAO,aAAU,SAAM,UAAO,OAAI,aAAU,YAASC,QACrDF,EAAM,SACd,GACMG,IAAY,IAAIC,EAAqB,GAErCC,KAAW,MAAiB;GAChC,IAAMC,IAAQC,EAAM,QACdC,IAAOC,EAAkBH,EAAM,OAAON,EAAM,UAAU,MAAM;GAQlE,IALIQ,MAASF,EAAM,UAAO,EAAM,QAAQE,IAExCE,EAASF,MAAS,KAAK,OAAOA,CAAI,GAG9BR,EAAM,UAAU,oBAAoB;IACtC,IAAMW,IAAOL,EAAM;IAEnB,qBAAqBH,EAAU,OAAOK,GAAMR,EAAM,UAAU,QAAQW,CAAI,CAAC;GAC3E;EACF;oBAIEtB,EAAA,GAAAC,EAyBeC,GAAA;GAzBA,OAAOS,EAAM;GAAY,YAAUR,EAAAuB,CAAA;GAAK,OAAOvB,EAAAwB,CAAA;;GAC5D,SAAAvB,QAuBE,CAvBFC,EAuBEC,GAvBFC,EAuBE;IAtBC,IAAIJ,EAAAuB,CAAA;IACJ,MAAMf,EAAM,UAAU;IACvB,MAAK;IACL,KAAI;IACJ,WAAU;IACV,cAAa;IACb,SAAQ;IACP,WAAWA,EAAM,UAAU;IAC3B,eAAaR,EAAA4B,CAAA,KAAK;IAClB,aAAapB,EAAM,UAAU;IAC7B,UAAUR,EAAA6B,CAAA;IACV,UAAUrB,EAAM,UAAU;IAC1B,UAAUA,EAAM,UAAU;IAC1B,WAAWA,EAAM,UAAU;IAC3B,gBAAcR,EAAA8B,CAAA,CAAI,CAAA;IAClB,oBAAkB9B,EAAA8B,CAAA,CAAI,CAAA;IACtB,iBAAe9B,EAAA8B,CAAA,CAAI,CAAA;IACpB,aAAU;IACV,OAAM;GACE,GAAAtB,EAAM,UAAU,sBAAoB;IACpC;IACP,QAAMR,EAAA+B,CAAA"}
1
+ {"version":3,"file":"OneTimeCodeInputField.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createVNode","Input","_mergeProps","Input_default","FieldWrapper_default","OneTimeCodeInputField_vue_vue_type_script_setup_true_lang_default","props","__props","useField","submitter","OneTimeCodeSubmitter","onInput","input","event","code","oneTimeCodeDigits","setValue","form","openBlock","createBlock","unref","id","error","withCtx","createVNode","mergeProps","value","disabled","aria","blur"],"sources":["../../../src/components/fields/OneTimeCodeInputField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { OneTimeCodeSubmitter, oneTimeCodeDigits, type OneTimeCodeInputSchema } from '@alfakit/core'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Input from '../ui/Input.vue'\n\n/**\n * `OneTimeCodeInput`: one numeric input with `autocomplete=\"one-time-code\"` (browsers and\n * password managers fill it from an SMS or email), digits only, left to right in every\n * language. `submitOnCompletion()` submits the form once the last digit is in.\n */\nconst props = defineProps<{ component: OneTimeCodeInputSchema }>()\nconst { value, setValue, blur, error, id, disabled, aria } = useField<string | null>(\n () => props.component,\n)\nconst submitter = new OneTimeCodeSubmitter()\n\nconst onInput = (event: Event) => {\n const input = event.target as HTMLInputElement\n const code = oneTimeCodeDigits(input.value, props.component.length)\n\n // A rejected character leaves the model value unchanged: correct the DOM too.\n if (code !== input.value) input.value = code\n\n setValue(code === '' ? null : code)\n\n // After the state reached the form store, so the submitted values include it.\n if (props.component.submitOnCompletion) {\n const form = input.form\n\n queueMicrotask(() => submitter.update(code, props.component.length, form))\n }\n}\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <Input\n :id=\"id\"\n :name=\"props.component.name\"\n type=\"text\"\n dir=\"ltr\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n pattern=\"[0-9]*\"\n :model-value=\"value ?? ''\"\n :placeholder=\"props.component.placeholder\"\n :disabled=\"disabled\"\n :readonly=\"props.component.readOnly\"\n :required=\"props.component.required\"\n :autofocus=\"props.component.autofocus\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n data-slot=\"one-time-code-input\"\n data-input=\"\"\n class=\"max-w-56 text-center font-mono text-lg tracking-[0.5em] tabular-nums\"\n v-bind=\"props.component.extraInputAttributes\"\n @input=\"onInput\"\n @blur=\"blur\"\n />\n </FieldWrapper>\n</template>\n"],"mappings":";;;;;;;;;;EAWA,IAAMW,IAAQC,GACR,EAAE,UAAO,aAAU,SAAM,UAAO,OAAI,aAAU,YAASC,QACrDF,EAAM,SACd,GACMG,IAAY,IAAIC,EAAqB,GAErCC,KAAW,MAAiB;GAChC,IAAMC,IAAQC,EAAM,QACdC,IAAOC,EAAkBH,EAAM,OAAON,EAAM,UAAU,MAAM;GAQlE,IALIQ,MAASF,EAAM,UAAO,EAAM,QAAQE,IAExCE,EAASF,MAAS,KAAK,OAAOA,CAAI,GAG9BR,EAAM,UAAU,oBAAoB;IACtC,IAAMW,IAAOL,EAAM;IAEnB,qBAAqBH,EAAU,OAAOK,GAAMR,EAAM,UAAU,QAAQW,CAAI,CAAC;GAC3E;EACF;oBAIEtB,EAAA,GAAAC,EAyBeC,GAAA;GAzBA,OAAOS,EAAM;GAAY,YAAUR,EAAAuB,CAAA;GAAK,OAAOvB,EAAAwB,CAAA;;GAC5D,SAAAvB,QAuBE,CAvBFC,EAuBEC,GAvBFC,EAuBE;IAtBC,IAAIJ,EAAAuB,CAAA;IACJ,MAAMf,EAAM,UAAU;IACvB,MAAK;IACL,KAAI;IACJ,WAAU;IACV,cAAa;IACb,SAAQ;IACP,eAAaR,EAAA4B,CAAA,KAAK;IAClB,aAAapB,EAAM,UAAU;IAC7B,UAAUR,EAAA6B,CAAA;IACV,UAAUrB,EAAM,UAAU;IAC1B,UAAUA,EAAM,UAAU;IAC1B,WAAWA,EAAM,UAAU;IAC3B,gBAAcR,EAAA8B,CAAA,CAAI,CAAA;IAClB,oBAAkB9B,EAAA8B,CAAA,CAAI,CAAA;IACtB,iBAAe9B,EAAA8B,CAAA,CAAI,CAAA;IACpB,aAAU;IACV,cAAW;IACX,OAAM;GACE,GAAAtB,EAAM,UAAU,sBAAoB;IACpC;IACP,QAAMR,EAAA+B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectField.js","names":["_sfc_main","SelectField_vue_vue_type_script_setup_true_lang_default","SelectField_default"],"sources":["../../../src/components/fields/SelectField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { SelectSchema } from '@alfakit/core'\nimport { htmlLabelToText, isOptionGroup } from '@alfakit/core'\nimport { computed } from 'vue'\nimport { useT } from '../../context'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Select from '../ui/Select.vue'\nimport SelectContent from '../ui/SelectContent.vue'\nimport SelectGroup from '../ui/SelectGroup.vue'\nimport SelectItem from '../ui/SelectItem.vue'\nimport SelectLabel from '../ui/SelectLabel.vue'\nimport SelectTrigger from '../ui/SelectTrigger.vue'\nimport SelectValue from '../ui/SelectValue.vue'\nimport ComboboxSelect from './ComboboxSelect.vue'\nimport OptionLabel from './OptionLabel.vue'\nimport SelectAffixes from './SelectAffixes.vue'\n\nconst props = defineProps<{ component: SelectSchema }>()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<\n string | number | Array<string | number> | null\n>(() => props.component)\n\nconst isNative = computed(\n () => props.component.native && !props.component.multiple && !props.component.searchable,\n)\nconst isSimple = computed(() => !props.component.multiple && !props.component.searchable)\nconst current = computed(() =>\n value.value === null || value.value === undefined ? '' : String(value.value),\n)\nconst hasValue = computed(\n () => value.value !== null && value.value !== undefined && value.value !== '',\n)\nconst t = useT()\n/** Text of an option label for native `<option>`s (`allowHtml()` labels are HTML). */\nconst plainLabel = (label: string): string =>\n props.component.allowHtml ? htmlLabelToText(label) : label\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <SelectAffixes :component=\"props.component\" :error=\"error\">\n <select\n v-if=\"isNative\"\n :id=\"id\"\n :name=\"props.component.name\"\n :value=\"current\"\n :disabled=\"disabled || readOnly\"\n :required=\"props.component.required\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]\"\n @change=\"\n setValue(\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : ($event.target as HTMLSelectElement).value,\n )\n \"\n @blur=\"blur\"\n >\n <option v-if=\"props.component.selectablePlaceholder\" value=\"\">\n {{ props.component.placeholder ?? '' }}\n </option>\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <optgroup v-if=\"isOptionGroup(option)\" :label=\"option.label\">\n <option\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n {{ plainLabel(item.label) }}\n </option>\n </optgroup>\n <option v-else :value=\"option.value\" :disabled=\"option.disabled\">\n {{ plainLabel(option.label) }}\n </option>\n </template>\n </select>\n <Select\n v-else-if=\"isSimple\"\n :model-value=\"current\"\n :disabled=\"disabled || readOnly\"\n @update:model-value=\"setValue($event === '__none__' ? null : ($event as string))\"\n >\n <SelectTrigger\n :id=\"id\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"w-full\"\n >\n <SelectValue :placeholder=\"props.component.placeholder ?? ''\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem\n v-if=\"props.component.selectablePlaceholder && hasValue\"\n value=\"__none__\"\n class=\"text-muted-foreground\"\n >{{ props.component.placeholder ?? '—' }}</SelectItem\n >\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <SelectGroup v-if=\"isOptionGroup(option)\">\n <SelectLabel>{{ option.label }}</SelectLabel>\n <SelectItem\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n <OptionLabel\n :option=\"item\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </SelectGroup>\n <SelectItem v-else :value=\"option.value\" :disabled=\"option.disabled\">\n <OptionLabel\n :option=\"option\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </template>\n <div\n v-if=\"props.component.options.length === 0\"\n data-slot=\"select-empty\"\n class=\"text-muted-foreground px-2 py-1.5 text-sm\"\n >\n {{\n props.component.noOptionsMessage ?? t('form.no_options', {}, 'No options available.')\n }}\n </div>\n </SelectContent>\n </Select>\n <ComboboxSelect\n v-else\n :id=\"id\"\n :component=\"props.component\"\n :value=\"value\"\n :set-value=\"setValue\"\n :disabled=\"disabled\"\n :read-only=\"readOnly\"\n :error=\"error\"\n :aria=\"aria\"\n />\n </SelectAffixes>\n </FieldWrapper>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"SelectField.js","names":["_sfc_main","SelectField_vue_vue_type_script_setup_true_lang_default","SelectField_default"],"sources":["../../../src/components/fields/SelectField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { SelectSchema } from '@alfakit/core'\nimport { htmlLabelToText, isOptionGroup } from '@alfakit/core'\nimport { computed } from 'vue'\nimport { useT } from '../../context'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Select from '../ui/Select.vue'\nimport SelectContent from '../ui/SelectContent.vue'\nimport SelectGroup from '../ui/SelectGroup.vue'\nimport SelectItem from '../ui/SelectItem.vue'\nimport SelectLabel from '../ui/SelectLabel.vue'\nimport SelectTrigger from '../ui/SelectTrigger.vue'\nimport SelectValue from '../ui/SelectValue.vue'\nimport ComboboxSelect from './ComboboxSelect.vue'\nimport OptionLabel from './OptionLabel.vue'\nimport SelectAffixes from './SelectAffixes.vue'\n\nconst props = defineProps<{ component: SelectSchema }>()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<\n string | number | Array<string | number> | null\n>(() => props.component)\n\nconst isNative = computed(\n () => props.component.native && !props.component.multiple && !props.component.searchable,\n)\nconst isSimple = computed(() => !props.component.multiple && !props.component.searchable)\nconst current = computed(() =>\n value.value === null || value.value === undefined ? '' : String(value.value),\n)\nconst hasValue = computed(\n () => value.value !== null && value.value !== undefined && value.value !== '',\n)\nconst t = useT()\n/** Text of an option label for native `<option>`s (`allowHtml()` labels are HTML). */\nconst plainLabel = (label: string): string =>\n props.component.allowHtml ? htmlLabelToText(label) : label\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <SelectAffixes :component=\"props.component\" :error=\"error\">\n <select\n v-if=\"isNative\"\n :id=\"id\"\n :name=\"props.component.name\"\n :value=\"current\"\n :disabled=\"disabled || readOnly\"\n :required=\"props.component.required\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]\"\n @change=\"\n setValue(\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : ($event.target as HTMLSelectElement).value,\n )\n \"\n @blur=\"blur\"\n >\n <option v-if=\"props.component.selectablePlaceholder\" value=\"\">\n {{ props.component.placeholder ?? t('select_option', {}, 'Select an option') }}\n </option>\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <optgroup v-if=\"isOptionGroup(option)\" :label=\"option.label\">\n <option\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n {{ plainLabel(item.label) }}\n </option>\n </optgroup>\n <option v-else :value=\"option.value\" :disabled=\"option.disabled\">\n {{ plainLabel(option.label) }}\n </option>\n </template>\n </select>\n <Select\n v-else-if=\"isSimple\"\n :model-value=\"current\"\n :disabled=\"disabled || readOnly\"\n @update:model-value=\"setValue($event === '__none__' ? null : ($event as string))\"\n >\n <SelectTrigger\n :id=\"id\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"w-full\"\n >\n <SelectValue\n :placeholder=\"props.component.placeholder ?? t('select_option', {}, 'Select an option')\"\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem\n v-if=\"props.component.selectablePlaceholder && hasValue\"\n value=\"__none__\"\n class=\"text-muted-foreground\"\n >{{ props.component.placeholder ?? '—' }}</SelectItem\n >\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <SelectGroup v-if=\"isOptionGroup(option)\">\n <SelectLabel>{{ option.label }}</SelectLabel>\n <SelectItem\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n <OptionLabel\n :option=\"item\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </SelectGroup>\n <SelectItem v-else :value=\"option.value\" :disabled=\"option.disabled\">\n <OptionLabel\n :option=\"option\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </template>\n <div\n v-if=\"props.component.options.length === 0\"\n data-slot=\"select-empty\"\n class=\"text-muted-foreground px-2 py-1.5 text-sm\"\n >\n {{\n props.component.noOptionsMessage ?? t('form.no_options', {}, 'No options available.')\n }}\n </div>\n </SelectContent>\n </Select>\n <ComboboxSelect\n v-else\n :id=\"id\"\n :component=\"props.component\"\n :value=\"value\"\n :set-value=\"setValue\"\n :disabled=\"disabled\"\n :read-only=\"readOnly\"\n :error=\"error\"\n :aria=\"aria\"\n />\n </SelectAffixes>\n </FieldWrapper>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectField.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SelectField.vue"],"names":[],"mappings":"AAkKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAiBjD,KAAK,WAAW,GAAG;IAAE,SAAS,EAAE,YAAY,CAAA;CAAE,CAAC;;AAuW/C,wBAMG"}
1
+ {"version":3,"file":"SelectField.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fields/SelectField.vue"],"names":[],"mappings":"AAoKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAiBjD,KAAK,WAAW,GAAG;IAAE,SAAS,EAAE,YAAY,CAAA;CAAE,CAAC;;AAuW/C,wBAMG"}
@@ -59,7 +59,7 @@ var O = [
59
59
  class: "border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]",
60
60
  onChange: t[0] ||= (e) => E(I)(e.target.value === "" ? null : e.target.value),
61
61
  onBlur: t[1] ||= (...e) => E(L) && E(L)(...e)
62
- }, [P.component.selectablePlaceholder ? (C(), y("option", k, T(P.component.placeholder ?? ""), 1)) : v("", !0), (C(!0), y(h, null, w(P.component.options, (e) => (C(), y(h, { key: E(m)(e) ? e.label : e.value }, [E(m)(e) ? (C(), y("optgroup", {
62
+ }, [P.component.selectablePlaceholder ? (C(), y("option", k, T(P.component.placeholder ?? E(q)("select_option", {}, "Select an option")), 1)) : v("", !0), (C(!0), y(h, null, w(P.component.options, (e) => (C(), y(h, { key: E(m)(e) ? e.label : e.value }, [E(m)(e) ? (C(), y("optgroup", {
63
63
  key: 0,
64
64
  label: e.label
65
65
  }, [(C(!0), y(h, null, w(e.options, (e) => (C(), y("option", {
@@ -84,7 +84,7 @@ var O = [
84
84
  "aria-readonly": E(V) || void 0,
85
85
  class: "w-full"
86
86
  }, {
87
- default: D(() => [x(u, { placeholder: P.component.placeholder ?? "" }, null, 8, ["placeholder"])]),
87
+ default: D(() => [x(u, { placeholder: P.component.placeholder ?? E(q)("select_option", {}, "Select an option") }, null, 8, ["placeholder"])]),
88
88
  _: 1
89
89
  }, 8, [
90
90
  "id",
@@ -1 +1 @@
1
- {"version":3,"file":"SelectField.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createVNode","SelectAffixes","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","_createTextVNode","SelectGroup","SelectLabel","OptionLabel","ComboboxSelect","FieldWrapper_default","SelectAffixes_default","Select_default","SelectContent_default","SelectGroup_default","SelectItem_default","SelectLabel_default","SelectTrigger_default","SelectValue_default","OptionLabel_default","ComboboxSelect_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","SelectField_vue_vue_type_script_setup_true_lang_default","props","__props","useField","isNative","computed","isSimple","current","value","hasValue","t","useT","plainLabel","htmlLabelToText","label","openBlock","createBlock","unref","id","error","withCtx","createVNode","createElementBlock","disabled","readOnly","aria","_cache","setValue","$event","args","blur","toDisplayString","createCommentVNode","Fragment","renderList","isOptionGroup","option","item","createTextVNode"],"sources":["../../../src/components/fields/SelectField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { SelectSchema } from '@alfakit/core'\nimport { htmlLabelToText, isOptionGroup } from '@alfakit/core'\nimport { computed } from 'vue'\nimport { useT } from '../../context'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Select from '../ui/Select.vue'\nimport SelectContent from '../ui/SelectContent.vue'\nimport SelectGroup from '../ui/SelectGroup.vue'\nimport SelectItem from '../ui/SelectItem.vue'\nimport SelectLabel from '../ui/SelectLabel.vue'\nimport SelectTrigger from '../ui/SelectTrigger.vue'\nimport SelectValue from '../ui/SelectValue.vue'\nimport ComboboxSelect from './ComboboxSelect.vue'\nimport OptionLabel from './OptionLabel.vue'\nimport SelectAffixes from './SelectAffixes.vue'\n\nconst props = defineProps<{ component: SelectSchema }>()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<\n string | number | Array<string | number> | null\n>(() => props.component)\n\nconst isNative = computed(\n () => props.component.native && !props.component.multiple && !props.component.searchable,\n)\nconst isSimple = computed(() => !props.component.multiple && !props.component.searchable)\nconst current = computed(() =>\n value.value === null || value.value === undefined ? '' : String(value.value),\n)\nconst hasValue = computed(\n () => value.value !== null && value.value !== undefined && value.value !== '',\n)\nconst t = useT()\n/** Text of an option label for native `<option>`s (`allowHtml()` labels are HTML). */\nconst plainLabel = (label: string): string =>\n props.component.allowHtml ? htmlLabelToText(label) : label\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <SelectAffixes :component=\"props.component\" :error=\"error\">\n <select\n v-if=\"isNative\"\n :id=\"id\"\n :name=\"props.component.name\"\n :value=\"current\"\n :disabled=\"disabled || readOnly\"\n :required=\"props.component.required\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]\"\n @change=\"\n setValue(\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : ($event.target as HTMLSelectElement).value,\n )\n \"\n @blur=\"blur\"\n >\n <option v-if=\"props.component.selectablePlaceholder\" value=\"\">\n {{ props.component.placeholder ?? '' }}\n </option>\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <optgroup v-if=\"isOptionGroup(option)\" :label=\"option.label\">\n <option\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n {{ plainLabel(item.label) }}\n </option>\n </optgroup>\n <option v-else :value=\"option.value\" :disabled=\"option.disabled\">\n {{ plainLabel(option.label) }}\n </option>\n </template>\n </select>\n <Select\n v-else-if=\"isSimple\"\n :model-value=\"current\"\n :disabled=\"disabled || readOnly\"\n @update:model-value=\"setValue($event === '__none__' ? null : ($event as string))\"\n >\n <SelectTrigger\n :id=\"id\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"w-full\"\n >\n <SelectValue :placeholder=\"props.component.placeholder ?? ''\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem\n v-if=\"props.component.selectablePlaceholder && hasValue\"\n value=\"__none__\"\n class=\"text-muted-foreground\"\n >{{ props.component.placeholder ?? '—' }}</SelectItem\n >\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <SelectGroup v-if=\"isOptionGroup(option)\">\n <SelectLabel>{{ option.label }}</SelectLabel>\n <SelectItem\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n <OptionLabel\n :option=\"item\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </SelectGroup>\n <SelectItem v-else :value=\"option.value\" :disabled=\"option.disabled\">\n <OptionLabel\n :option=\"option\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </template>\n <div\n v-if=\"props.component.options.length === 0\"\n data-slot=\"select-empty\"\n class=\"text-muted-foreground px-2 py-1.5 text-sm\"\n >\n {{\n props.component.noOptionsMessage ?? t('form.no_options', {}, 'No options available.')\n }}\n </div>\n </SelectContent>\n </Select>\n <ComboboxSelect\n v-else\n :id=\"id\"\n :component=\"props.component\"\n :value=\"value\"\n :set-value=\"setValue\"\n :disabled=\"disabled\"\n :read-only=\"readOnly\"\n :error=\"error\"\n :aria=\"aria\"\n />\n </SelectAffixes>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"SelectField.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","FieldWrapper","_unref","_withCtx","_createVNode","SelectAffixes","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","_createTextVNode","SelectGroup","SelectLabel","OptionLabel","ComboboxSelect","FieldWrapper_default","SelectAffixes_default","Select_default","SelectContent_default","SelectGroup_default","SelectItem_default","SelectLabel_default","SelectTrigger_default","SelectValue_default","OptionLabel_default","ComboboxSelect_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","SelectField_vue_vue_type_script_setup_true_lang_default","props","__props","useField","isNative","computed","isSimple","current","value","hasValue","t","useT","plainLabel","htmlLabelToText","label","openBlock","createBlock","unref","id","error","withCtx","createVNode","createElementBlock","disabled","readOnly","aria","_cache","setValue","$event","args","blur","toDisplayString","createCommentVNode","Fragment","renderList","isOptionGroup","option","item","createTextVNode"],"sources":["../../../src/components/fields/SelectField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { SelectSchema } from '@alfakit/core'\nimport { htmlLabelToText, isOptionGroup } from '@alfakit/core'\nimport { computed } from 'vue'\nimport { useT } from '../../context'\nimport { useField } from '../form/form-context'\nimport FieldWrapper from '../schema/FieldWrapper.vue'\nimport Select from '../ui/Select.vue'\nimport SelectContent from '../ui/SelectContent.vue'\nimport SelectGroup from '../ui/SelectGroup.vue'\nimport SelectItem from '../ui/SelectItem.vue'\nimport SelectLabel from '../ui/SelectLabel.vue'\nimport SelectTrigger from '../ui/SelectTrigger.vue'\nimport SelectValue from '../ui/SelectValue.vue'\nimport ComboboxSelect from './ComboboxSelect.vue'\nimport OptionLabel from './OptionLabel.vue'\nimport SelectAffixes from './SelectAffixes.vue'\n\nconst props = defineProps<{ component: SelectSchema }>()\nconst { value, setValue, blur, error, id, disabled, readOnly, aria } = useField<\n string | number | Array<string | number> | null\n>(() => props.component)\n\nconst isNative = computed(\n () => props.component.native && !props.component.multiple && !props.component.searchable,\n)\nconst isSimple = computed(() => !props.component.multiple && !props.component.searchable)\nconst current = computed(() =>\n value.value === null || value.value === undefined ? '' : String(value.value),\n)\nconst hasValue = computed(\n () => value.value !== null && value.value !== undefined && value.value !== '',\n)\nconst t = useT()\n/** Text of an option label for native `<option>`s (`allowHtml()` labels are HTML). */\nconst plainLabel = (label: string): string =>\n props.component.allowHtml ? htmlLabelToText(label) : label\n</script>\n\n<template>\n <FieldWrapper :field=\"props.component\" :html-for=\"id\" :error=\"error\">\n <SelectAffixes :component=\"props.component\" :error=\"error\">\n <select\n v-if=\"isNative\"\n :id=\"id\"\n :name=\"props.component.name\"\n :value=\"current\"\n :disabled=\"disabled || readOnly\"\n :required=\"props.component.required\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"border-input dark:bg-input/30 focus-visible:ring-ring/50 h-9 w-full rounded-md border bg-transparent px-3 text-sm shadow-xs outline-none focus-visible:ring-[3px]\"\n @change=\"\n setValue(\n ($event.target as HTMLSelectElement).value === ''\n ? null\n : ($event.target as HTMLSelectElement).value,\n )\n \"\n @blur=\"blur\"\n >\n <option v-if=\"props.component.selectablePlaceholder\" value=\"\">\n {{ props.component.placeholder ?? t('select_option', {}, 'Select an option') }}\n </option>\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <optgroup v-if=\"isOptionGroup(option)\" :label=\"option.label\">\n <option\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n {{ plainLabel(item.label) }}\n </option>\n </optgroup>\n <option v-else :value=\"option.value\" :disabled=\"option.disabled\">\n {{ plainLabel(option.label) }}\n </option>\n </template>\n </select>\n <Select\n v-else-if=\"isSimple\"\n :model-value=\"current\"\n :disabled=\"disabled || readOnly\"\n @update:model-value=\"setValue($event === '__none__' ? null : ($event as string))\"\n >\n <SelectTrigger\n :id=\"id\"\n :aria-invalid=\"aria['aria-invalid']\"\n :aria-describedby=\"aria['aria-describedby']\"\n :aria-required=\"aria['aria-required']\"\n :aria-readonly=\"readOnly || undefined\"\n class=\"w-full\"\n >\n <SelectValue\n :placeholder=\"props.component.placeholder ?? t('select_option', {}, 'Select an option')\"\n />\n </SelectTrigger>\n <SelectContent>\n <SelectItem\n v-if=\"props.component.selectablePlaceholder && hasValue\"\n value=\"__none__\"\n class=\"text-muted-foreground\"\n >{{ props.component.placeholder ?? '—' }}</SelectItem\n >\n <template\n v-for=\"option in props.component.options\"\n :key=\"isOptionGroup(option) ? option.label : option.value\"\n >\n <SelectGroup v-if=\"isOptionGroup(option)\">\n <SelectLabel>{{ option.label }}</SelectLabel>\n <SelectItem\n v-for=\"item in option.options\"\n :key=\"item.value\"\n :value=\"item.value\"\n :disabled=\"item.disabled\"\n >\n <OptionLabel\n :option=\"item\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </SelectGroup>\n <SelectItem v-else :value=\"option.value\" :disabled=\"option.disabled\">\n <OptionLabel\n :option=\"option\"\n :allow-html=\"props.component.allowHtml\"\n :wrap=\"props.component.wrapOptionLabels !== false\"\n />\n </SelectItem>\n </template>\n <div\n v-if=\"props.component.options.length === 0\"\n data-slot=\"select-empty\"\n class=\"text-muted-foreground px-2 py-1.5 text-sm\"\n >\n {{\n props.component.noOptionsMessage ?? t('form.no_options', {}, 'No options available.')\n }}\n </div>\n </SelectContent>\n </Select>\n <ComboboxSelect\n v-else\n :id=\"id\"\n :component=\"props.component\"\n :value=\"value\"\n :set-value=\"setValue\"\n :disabled=\"disabled\"\n :read-only=\"readOnly\"\n :error=\"error\"\n :aria=\"aria\"\n />\n </SelectAffixes>\n </FieldWrapper>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TableColumnHeaders.js","names":["_sfc_main","TableColumnHeaders_vue_vue_type_script_setup_true_lang_default","TableColumnHeaders_default"],"sources":["../../../src/components/fields/TableColumnHeaders.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { TableColumnSchema } from '@alfakit/core'\nimport { tableColumnAlignmentClass } from '@alfakit/core'\nimport { cn } from '../../lib/utils'\n\n/** Header cells shared by the Repeater and RepeatableEntry tables. */\nconst props = defineProps<{ columns: TableColumnSchema[] }>()\n</script>\n\n<template>\n <th\n v-for=\"(column, index) in props.columns\"\n :key=\"`${column.name ?? 'column'}-${index}`\"\n scope=\"col\"\n :style=\"column.width ? { width: column.width } : undefined\"\n :class=\"\n cn(\n 'text-muted-foreground px-3 py-2 text-xs font-medium',\n tableColumnAlignmentClass(column),\n !column.wrapHeader && 'whitespace-nowrap',\n )\n \"\n >\n <span :class=\"cn(column.hiddenLabel && 'sr-only')\">{{ column.label }}</span\n ><span v-if=\"column.required\" class=\"text-destructive ms-0.5\" aria-hidden=\"true\">*</span>\n </th>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"TableColumnHeaders.js","names":["_sfc_main","TableColumnHeaders_vue_vue_type_script_setup_true_lang_default","TableColumnHeaders_default"],"sources":["../../../src/components/fields/TableColumnHeaders.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { TableColumnSchema } from '@alfakit/core'\nimport { tableColumnAlignmentClass } from '@alfakit/core'\nimport { cn } from '../../lib/utils'\n\n/** Header cells shared by the Repeater and RepeatableEntry tables. */\nconst props = defineProps<{ columns: TableColumnSchema[] }>()\n\n// A fixed `width()` (`9rem`, `120px`) is also the column's minimum, so the table scrolls\n// sideways instead of squeezing its fields; percentages stay flexible.\nconst widthStyle = (width?: string | null) =>\n !width ? undefined : width.trim().endsWith('%') ? { width } : { width, minWidth: width }\n</script>\n\n<template>\n <th\n v-for=\"(column, index) in props.columns\"\n :key=\"`${column.name ?? 'column'}-${index}`\"\n scope=\"col\"\n :style=\"widthStyle(column.width)\"\n :class=\"\n cn(\n 'text-muted-foreground px-3 py-2 text-xs font-medium',\n tableColumnAlignmentClass(column),\n !column.wrapHeader && 'whitespace-nowrap',\n )\n \"\n >\n <span :class=\"cn(column.hiddenLabel && 'sr-only')\">{{ column.label }}</span\n ><span v-if=\"column.required\" class=\"text-destructive ms-0.5\" aria-hidden=\"true\">*</span>\n </th>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"TableColumnHeaders.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fields/TableColumnHeaders.vue"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAItD,sEAAsE;AACtE,KAAK,WAAW,GAAG;IAAE,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAAE,CAAC;;AAyDpD,wBAMG"}
1
+ {"version":3,"file":"TableColumnHeaders.vue.d.ts","sourceRoot":"","sources":["../../../src/components/fields/TableColumnHeaders.vue"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAItD,sEAAsE;AACtE,KAAK,WAAW,GAAG;IAAE,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAAE,CAAC;;AA+DpD,wBAMG"}
@@ -10,11 +10,14 @@ var p = {
10
10
  __name: "TableColumnHeaders",
11
11
  props: { columns: {} },
12
12
  setup(o) {
13
- let m = o;
14
- return (o, h) => (l(!0), i(n, null, u(m.columns, (n, o) => (l(), i("th", {
13
+ let m = o, h = (e) => e ? e.trim().endsWith("%") ? { width: e } : {
14
+ width: e,
15
+ minWidth: e
16
+ } : void 0;
17
+ return (o, g) => (l(!0), i(n, null, u(m.columns, (n, o) => (l(), i("th", {
15
18
  key: `${n.name ?? "column"}-${o}`,
16
19
  scope: "col",
17
- style: c(n.width ? { width: n.width } : void 0),
20
+ style: c(h(n.width)),
18
21
  class: s(f(e)("text-muted-foreground px-3 py-2 text-xs font-medium", f(t)(n), !n.wrapHeader && "whitespace-nowrap"))
19
22
  }, [a("span", { class: s(f(e)(n.hiddenLabel && "sr-only")) }, d(n.label), 3), n.required ? (l(), i("span", p, "*")) : r("", !0)], 6))), 128));
20
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TableColumnHeaders.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_renderList","_normalizeStyle","_normalizeClass","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","_hoisted_1","TableColumnHeaders_vue_vue_type_script_setup_true_lang_default","props","__props","openBlock","createElementBlock","Fragment","renderList","column","index","normalizeStyle","normalizeClass","unref","cn","tableColumnAlignmentClass","createElementVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/fields/TableColumnHeaders.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { TableColumnSchema } from '@alfakit/core'\nimport { tableColumnAlignmentClass } from '@alfakit/core'\nimport { cn } from '../../lib/utils'\n\n/** Header cells shared by the Repeater and RepeatableEntry tables. */\nconst props = defineProps<{ columns: TableColumnSchema[] }>()\n</script>\n\n<template>\n <th\n v-for=\"(column, index) in props.columns\"\n :key=\"`${column.name ?? 'column'}-${index}`\"\n scope=\"col\"\n :style=\"column.width ? { width: column.width } : undefined\"\n :class=\"\n cn(\n 'text-muted-foreground px-3 py-2 text-xs font-medium',\n tableColumnAlignmentClass(column),\n !column.wrapHeader && 'whitespace-nowrap',\n )\n \"\n >\n <span :class=\"cn(column.hiddenLabel && 'sr-only')\">{{ column.label }}</span\n ><span v-if=\"column.required\" class=\"text-destructive ms-0.5\" aria-hidden=\"true\">*</span>\n </th>\n</template>\n"],"mappings":";;;;;;;;;;;;EAMA,IAAMY,IAAQC;oBAIZb,EAAA,EAAA,GAAAC,EAeKC,GAAA,MAAAC,EAduBS,EAAM,UAAxB,GAAQ,OADlBZ,EAAA,GAAAC,EAeK,MAAA;GAbF,KAAG,GAAKiB,EAAO,QAAI,SAAA,GAAgBC;GACpC,OAAM;GACL,OAAKf,EAAEc,EAAO,QAAK,EAAA,OAAYA,EAAO,MAAK,IAAK,KAAA,CAAS;GACzD,OAAKb,EAASC,EAAAiB,CAAA,CAAE,CAAA,uDAAyEjB,EAAAkB,CAAA,CAAyB,CAACN,CAAM,GAAY,CAAAA,EAAO,cAAU,mBAAA,CAAA;EAQvJX,GAAAA,CAAAA,EACC,QAAA,EADM,OAAKF,EAAEC,EAAAiB,CAAA,CAAE,CAACL,EAAO,eAAW,SAAA,CAAA,EAAmB,GAAAV,EAAAU,EAAO,KAAK,GAAA,CAAA,GACrDA,EAAO,YAAnBlB,EAAA,GAAAC,EAAwF,QAAxFS,GAAgF,GAAC,KAAAiB,EAAA,IAAA,EAAA,CAAA,GAAA,CAAA"}
1
+ {"version":3,"file":"TableColumnHeaders.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_renderList","_normalizeStyle","_normalizeClass","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","_hoisted_1","TableColumnHeaders_vue_vue_type_script_setup_true_lang_default","props","__props","widthStyle","width","openBlock","createElementBlock","Fragment","renderList","column","index","normalizeStyle","normalizeClass","unref","cn","tableColumnAlignmentClass","createElementVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/fields/TableColumnHeaders.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { TableColumnSchema } from '@alfakit/core'\nimport { tableColumnAlignmentClass } from '@alfakit/core'\nimport { cn } from '../../lib/utils'\n\n/** Header cells shared by the Repeater and RepeatableEntry tables. */\nconst props = defineProps<{ columns: TableColumnSchema[] }>()\n\n// A fixed `width()` (`9rem`, `120px`) is also the column's minimum, so the table scrolls\n// sideways instead of squeezing its fields; percentages stay flexible.\nconst widthStyle = (width?: string | null) =>\n !width ? undefined : width.trim().endsWith('%') ? { width } : { width, minWidth: width }\n</script>\n\n<template>\n <th\n v-for=\"(column, index) in props.columns\"\n :key=\"`${column.name ?? 'column'}-${index}`\"\n scope=\"col\"\n :style=\"widthStyle(column.width)\"\n :class=\"\n cn(\n 'text-muted-foreground px-3 py-2 text-xs font-medium',\n tableColumnAlignmentClass(column),\n !column.wrapHeader && 'whitespace-nowrap',\n )\n \"\n >\n <span :class=\"cn(column.hiddenLabel && 'sr-only')\">{{ column.label }}</span\n ><span v-if=\"column.required\" class=\"text-destructive ms-0.5\" aria-hidden=\"true\">*</span>\n </th>\n</template>\n"],"mappings":";;;;;;;;;;;;EAMA,IAAMY,IAAQC,GAIRC,KAAc,MACjBC,IAAoBA,EAAM,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,EAAE,SAAM,IAAI;GAAE;GAAO,UAAUA;EAAM,IAA9E,KAAA;oBAITf,EAAA,EAAA,GAAAC,EAeKC,GAAA,MAAAC,EAduBS,EAAM,UAAxB,GAAQ,OADlBZ,EAAA,GAAAC,EAeK,MAAA;GAbF,KAAG,GAAKmB,EAAO,QAAI,SAAA,GAAgBC;GACpC,OAAM;GACL,OAAKjB,EAAEU,EAAWM,EAAO,KAAK,CAAA;GAC9B,OAAKf,EAASC,EAAAmB,CAAA,CAAE,CAAA,uDAAyEnB,EAAAoB,CAAA,CAAyB,CAACN,CAAM,GAAY,CAAAA,EAAO,cAAU,mBAAA,CAAA;EAQvJb,GAAAA,CAAAA,EACC,QAAA,EADM,OAAKF,EAAEC,EAAAmB,CAAA,CAAE,CAACL,EAAO,eAAW,SAAA,CAAA,EAAmB,GAAAZ,EAAAY,EAAO,KAAK,GAAA,CAAA,GACrDA,EAAO,YAAnBpB,EAAA,GAAAC,EAAwF,QAAxFS,GAAgF,GAAC,KAAAmB,EAAA,IAAA,EAAA,CAAA,GAAA,CAAA"}