@k2b/ui 0.17.0 → 0.18.0

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 (88) hide show
  1. package/dist/browser/chat/ChatComposer.js +261 -274
  2. package/dist/browser/chat/ChatComposer.js.map +1 -1
  3. package/dist/browser/chat/ChatPrimitives.js +9 -6
  4. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  5. package/dist/browser/content/FileView.js +62 -36
  6. package/dist/browser/content/FileView.js.map +1 -1
  7. package/dist/browser/content/MarkdownView.js +9 -3
  8. package/dist/browser/content/MarkdownView.js.map +1 -1
  9. package/dist/browser/content/VideoPlayer.js +279 -0
  10. package/dist/browser/content/VideoPlayer.js.map +1 -0
  11. package/dist/browser/content/file-view-preview.js +2 -2
  12. package/dist/browser/content/file-view-preview.js.map +1 -1
  13. package/dist/browser/content/index.js +2 -0
  14. package/dist/browser/content/index.js.map +1 -1
  15. package/dist/browser/content/markdown-links.js +178 -0
  16. package/dist/browser/content/markdown-links.js.map +1 -0
  17. package/dist/browser/inputs/FileDropTarget.js +129 -0
  18. package/dist/browser/inputs/FileDropTarget.js.map +1 -0
  19. package/dist/browser/inputs/FileInputs.js +37 -11
  20. package/dist/browser/inputs/FileInputs.js.map +1 -1
  21. package/dist/browser/inputs/file-drop.js +338 -0
  22. package/dist/browser/inputs/file-drop.js.map +1 -0
  23. package/dist/browser/inputs/index.js +1 -0
  24. package/dist/browser/inputs/index.js.map +1 -1
  25. package/dist/browser/inputs/markdown/MarkdownEditor.js +72 -78
  26. package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
  27. package/dist/browser/intl/messages.js +97 -4
  28. package/dist/browser/intl/messages.js.map +1 -1
  29. package/dist/browser/layout/AppWorkspace.js +210 -44
  30. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  31. package/dist/browser/layout/Navigation.js +274 -197
  32. package/dist/browser/layout/Navigation.js.map +1 -1
  33. package/dist/browser/layout/index.js.map +1 -1
  34. package/dist/browser/layout/navigation-model.js +2 -0
  35. package/dist/browser/layout/navigation-model.js.map +1 -1
  36. package/dist/browser/surfaces/NoticeCard.js +47 -44
  37. package/dist/browser/surfaces/NoticeCard.js.map +1 -1
  38. package/dist/ssr/chat/ChatComposer.js +59 -48
  39. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  40. package/dist/ssr/chat/ChatPrimitives.js +9 -6
  41. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  42. package/dist/ssr/content/FileView.js +30 -6
  43. package/dist/ssr/content/FileView.js.map +1 -1
  44. package/dist/ssr/content/MarkdownView.js +9 -3
  45. package/dist/ssr/content/MarkdownView.js.map +1 -1
  46. package/dist/ssr/content/VideoPlayer.js +208 -0
  47. package/dist/ssr/content/VideoPlayer.js.map +1 -0
  48. package/dist/ssr/content/file-view-preview.js +2 -2
  49. package/dist/ssr/content/file-view-preview.js.map +1 -1
  50. package/dist/ssr/content/index.js +2 -0
  51. package/dist/ssr/content/index.js.map +1 -1
  52. package/dist/ssr/content/markdown-links.js +178 -0
  53. package/dist/ssr/content/markdown-links.js.map +1 -0
  54. package/dist/ssr/inputs/FileDropTarget.js +103 -0
  55. package/dist/ssr/inputs/FileDropTarget.js.map +1 -0
  56. package/dist/ssr/inputs/FileInputs.js +32 -10
  57. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  58. package/dist/ssr/inputs/file-drop.js +338 -0
  59. package/dist/ssr/inputs/file-drop.js.map +1 -0
  60. package/dist/ssr/inputs/index.js +1 -0
  61. package/dist/ssr/inputs/index.js.map +1 -1
  62. package/dist/ssr/inputs/markdown/MarkdownEditor.js +14 -2
  63. package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
  64. package/dist/ssr/intl/messages.js +97 -4
  65. package/dist/ssr/intl/messages.js.map +1 -1
  66. package/dist/ssr/layout/AppWorkspace.js +173 -27
  67. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  68. package/dist/ssr/layout/Navigation.js +169 -122
  69. package/dist/ssr/layout/Navigation.js.map +1 -1
  70. package/dist/ssr/layout/index.js.map +1 -1
  71. package/dist/ssr/layout/navigation-model.js +2 -0
  72. package/dist/ssr/layout/navigation-model.js.map +1 -1
  73. package/dist/ssr/surfaces/NoticeCard.js +17 -12
  74. package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
  75. package/dist/styles.css +1 -1
  76. package/dist/types/chat/ChatPrimitives.d.ts +1 -1
  77. package/dist/types/content/VideoPlayer.d.ts +41 -0
  78. package/dist/types/content/index.d.ts +2 -0
  79. package/dist/types/content/markdown-links.d.ts +66 -0
  80. package/dist/types/inputs/FileDropTarget.d.ts +23 -0
  81. package/dist/types/inputs/FileInputs.d.ts +2 -0
  82. package/dist/types/inputs/file-drop.d.ts +80 -0
  83. package/dist/types/inputs/index.d.ts +2 -0
  84. package/dist/types/intl/messages.d.ts +47 -0
  85. package/dist/types/layout/AppWorkspace.d.ts +21 -0
  86. package/dist/types/layout/index.d.ts +2 -2
  87. package/dist/types/layout/navigation-model.d.ts +18 -0
  88. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["inputs/FileInputs.tsx"],"sourcesContent":["import { dropzone } from \"@k2b/stdlib/solid\";\nimport { createEffect, createSignal, For, type JSX, onCleanup, Show } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { Tooltip } from \"../feedback/Tooltip\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../internal/field\";\nimport { useUiMessages } from \"../intl/messages\";\nimport type { FieldProps, ValueFieldProps } from \"./field-contract\";\nimport { commitFieldValue, resolveMaybeAccessor } from \"./field-contract\";\nimport {\n clampImageCropRect,\n getInitialImageCropRect,\n type ImageCropAspect,\n type ImageCropRect,\n type ImageCropResizeHandle,\n type ImageCropRotation,\n type ImageCropSource,\n type ImageCropState,\n resizeImageCropFromCorner,\n rotateImageCropRight,\n} from \"./image-crop\";\n\nexport type FileDropzoneProps = FieldProps & {\n accept?: string;\n multiple?: boolean;\n busy?: boolean;\n /** Full icon class list, for example `\"ti ti-photo-plus\"`. Defaults to `\"ti ti-cloud-upload\"`. */\n icon?: string;\n title?: JSX.Element;\n subtitle?: JSX.Element;\n hint?: JSX.Element;\n onDrop: (files: File[]) => void | Promise<void>;\n};\n\nexport function FileDropzone(props: FileDropzoneProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const disabled = () => Boolean(props.disabled || props.busy);\n const error = () => resolveMaybeAccessor(props.error);\n let input: HTMLInputElement | undefined;\n const emit = (files: File[]) => {\n if (disabled() || files.length === 0) return;\n void props.onDrop(props.multiple === false ? files.slice(0, 1) : files);\n };\n const zone = dropzone.create({\n get accept() {\n return props.accept;\n },\n onDrop: emit,\n });\n const title = () =>\n props.busy\n ? messages().uploading\n : zone.invalidDrag()\n ? messages().fileTypeNotAccepted\n : zone.isDragging()\n ? messages().dropToUpload\n : (props.title ?? messages().dropFiles);\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <button\n id={meta.controlId}\n type=\"button\"\n class=\"k2b-dropzone\"\n data-dragging={zone.isDragging() ? \"true\" : undefined}\n data-invalid={zone.invalidDrag() || error() ? \"true\" : undefined}\n disabled={disabled()}\n {...fieldControlAria(meta, props)}\n onClick={() => input?.click()}\n {...zone.handlers}\n >\n <span class=\"k2b-dropzone__icon\" aria-hidden=\"true\">\n <i class={props.busy ? \"ti ti-loader-2 k2b-spin\" : (props.icon ?? \"ti ti-cloud-upload\")} />\n </span>\n <span class=\"k2b-dropzone__copy\">\n <strong>{title()}</strong>\n <Show\n when={zone.invalidDrag()}\n fallback={\n <Show when={props.subtitle}>\n <span class=\"k2b-dropzone__subtitle\">{props.subtitle}</span>\n </Show>\n }\n >\n <span class=\"k2b-dropzone__subtitle\">{messages().chooseMatchingFile}</span>\n </Show>\n <Show when={props.hint}>\n <span class=\"k2b-dropzone__hint\">{props.hint}</span>\n </Show>\n </span>\n </button>\n <input\n ref={input}\n class=\"k2b-sr-only\"\n type=\"file\"\n aria-label={\n props[\"aria-label\"] ??\n (typeof props.label === \"string\" ? props.label : props.multiple === false ? messages().chooseFile : messages().chooseFiles)\n }\n accept={props.accept}\n multiple={props.multiple ?? true}\n disabled={disabled()}\n tabIndex={-1}\n onChange={(event) => {\n const files = Array.from(event.currentTarget.files ?? []);\n // Reset before emitting so re-picking the same file still fires change,\n // even when onDrop throws.\n event.currentTarget.value = \"\";\n emit(files);\n }}\n />\n </Field>\n );\n}\n\nexport type ImageInputProps = ValueFieldProps<string | null> & {\n round?: boolean;\n variant?: \"default\" | \"small\";\n transform?: (file: File) => Promise<string>;\n accept?: string;\n fallbackMarker?: string;\n};\n\nconst DEFAULT_IMAGE_ACCEPT = \"image/jpeg,image/png,image/gif,image/webp,image/svg+xml,.jpg,.jpeg,.png,.gif,.webp,.svg\";\n\nconst defaultImageTransform = async (file: File): Promise<string> => {\n const { img } = await import(\"@k2b/stdlib/browser\");\n return img.presets.avatar(file);\n};\n\nexport function ImageInput(props: ImageInputProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const [busy, setBusy] = createSignal(false);\n const [localError, setLocalError] = createSignal<string>();\n let input: HTMLInputElement | undefined;\n const disabled = () => Boolean(props.disabled || busy() || !props.onValueChange);\n const error = () => resolveMaybeAccessor(props.error) ?? localError();\n const value = () => {\n const current = resolveMaybeAccessor(props.value);\n return current && !current.includes(props.fallbackMarker ?? \"?fallback\") ? current : null;\n };\n const compact = () => props.variant === \"small\";\n const changeLabel = () => (value() ? messages().changeImage : messages().addImage);\n const changeIcon = () => (value() ? \"ti ti-pencil\" : \"ti ti-photo-plus\");\n const select = async (file: File | undefined) => {\n if (!file || disabled()) return;\n setBusy(true);\n setLocalError();\n try {\n const transformed = await (props.transform ?? defaultImageTransform)(file);\n commitFieldValue(props, transformed);\n } catch (error) {\n setLocalError(error instanceof Error ? error.message : messages().imageProcessingFailed);\n } finally {\n setBusy(false);\n if (input) input.value = \"\";\n }\n };\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <div\n class=\"k2b-image-input\"\n data-round={props.round ? \"true\" : undefined}\n data-variant={props.variant ?? \"default\"}\n role=\"group\"\n aria-labelledby={props.label ? meta.labelId : undefined}\n aria-label={!props.label ? props[\"aria-label\"] : undefined}\n aria-describedby={fieldControlAria(meta, { ...props, error })[\"aria-describedby\"]}\n >\n <div class=\"k2b-image-input__preview\">\n <Show when={value()} fallback={<i class=\"ti ti-photo-off\" aria-hidden=\"true\" />}>\n {(source) => <img src={source()} alt={typeof props.label === \"string\" ? props.label : messages().selectedImage} />}\n </Show>\n </div>\n <div class=\"k2b-image-input__actions\">\n <Show\n when={compact()}\n fallback={\n <Button\n variant=\"secondary\"\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n {value() ? messages().change : messages().add}\n </Button>\n }\n >\n <IconButton\n label={changeLabel()}\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n </IconButton>\n </Show>\n <Show when={value()}>\n <Show\n when={compact()}\n fallback={\n <Button variant=\"ghost\" disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" /> Remove\n </Button>\n }\n >\n <IconButton label={messages().removeImage} disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </Show>\n </div>\n <input\n ref={input}\n id={meta.controlId}\n class=\"k2b-sr-only\"\n type=\"file\"\n accept={props.accept ?? DEFAULT_IMAGE_ACCEPT}\n disabled={disabled()}\n required={props.required && !value()}\n {...fieldControlAria(meta, { ...props, error })}\n onChange={(event) => void select(event.currentTarget.files?.[0])}\n />\n </div>\n </Field>\n );\n}\n\ntype PreviewState = {\n url: string;\n objectUrl: boolean;\n sourceWidth: number;\n sourceHeight: number;\n};\n\ntype DragHandle = \"move\" | ImageCropResizeHandle;\ntype DragState = {\n handle: DragHandle;\n pointerId: number;\n startX: number;\n startY: number;\n startCrop: ImageCropRect;\n};\n\nexport type ImageCropperProps = {\n source: ImageCropSource;\n aspect?: ImageCropAspect;\n previewShape?: \"rect\" | \"circle\";\n disabled?: boolean;\n onValueChange?: (state: ImageCropState | null) => void;\n class?: string;\n};\n\nconst clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(max, value));\n\nconst imageElementReady = async (image: HTMLImageElement): Promise<void> => {\n if (image.complete && image.naturalWidth > 0) return;\n await new Promise<void>((resolve, reject) => {\n image.addEventListener(\"load\", () => resolve(), { once: true });\n image.addEventListener(\"error\", () => reject(new Error(\"Failed to load image.\")), { once: true });\n });\n};\n\nconst loadPreviewState = async (source: ImageCropSource): Promise<PreviewState> => {\n const sourceImage =\n source instanceof HTMLImageElement\n ? source\n : Object.assign(new Image(), {\n crossOrigin: source instanceof Blob ? undefined : \"anonymous\",\n src:\n source instanceof HTMLCanvasElement\n ? source.toDataURL(\"image/png\")\n : source instanceof Blob\n ? URL.createObjectURL(source)\n : source,\n });\n\n try {\n await imageElementReady(sourceImage);\n return {\n url: source instanceof HTMLImageElement ? source.currentSrc || source.src : sourceImage.src,\n objectUrl: source instanceof Blob,\n sourceWidth: sourceImage.naturalWidth || sourceImage.width,\n sourceHeight: sourceImage.naturalHeight || sourceImage.height,\n };\n } catch (error) {\n if (source instanceof Blob) URL.revokeObjectURL(sourceImage.src);\n throw error;\n }\n};\n\nexport function ImageCropper(props: ImageCropperProps): JSX.Element {\n const messages = useUiMessages();\n let frame: HTMLDivElement | undefined;\n let activePreview: PreviewState | null = null;\n const aspect = () => props.aspect ?? \"free\";\n const previewShape = () => props.previewShape ?? \"rect\";\n const disabled = () => props.disabled ?? false;\n const [preview, setPreview] = createSignal<PreviewState | null>(null);\n const [crop, setCrop] = createSignal<ImageCropRect | null>(null);\n const [rotation, setRotation] = createSignal<ImageCropRotation>(0);\n const [loading, setLoading] = createSignal(true);\n const [error, setError] = createSignal<string | null>(null);\n const [drag, setDrag] = createSignal<DragState | null>(null);\n\n const previewSize = (): { width: number; height: number } | null => {\n const currentPreview = preview();\n if (!currentPreview) return null;\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n width: swapsDimensions ? currentPreview.sourceHeight : currentPreview.sourceWidth,\n height: swapsDimensions ? currentPreview.sourceWidth : currentPreview.sourceHeight,\n };\n };\n\n const replacePreview = (next: PreviewState | null) => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n activePreview = next;\n setPreview(next);\n };\n\n onCleanup(() => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n });\n\n createEffect(() => {\n props.source;\n setRotation(0);\n setCrop(null);\n });\n\n createEffect(() => {\n const source = props.source;\n let disposed = false;\n replacePreview(null);\n setLoading(true);\n setError(null);\n\n void (async () => {\n try {\n const nextPreview = await loadPreviewState(source);\n if (disposed) {\n if (nextPreview.objectUrl) URL.revokeObjectURL(nextPreview.url);\n return;\n }\n replacePreview(nextPreview);\n } catch {\n if (disposed) return;\n replacePreview(null);\n setCrop(null);\n setError(messages().failedLoadImage);\n } finally {\n if (!disposed) setLoading(false);\n }\n })();\n\n onCleanup(() => {\n disposed = true;\n });\n });\n\n createEffect(() => {\n const currentSize = previewSize();\n const currentAspect = aspect();\n if (!currentSize) return;\n setCrop((current) => clampImageCropRect(current ?? getInitialImageCropRect(currentSize, currentAspect), currentSize, currentAspect));\n });\n\n createEffect(() => {\n const currentCrop = crop();\n const currentPreview = preview();\n props.onValueChange?.(currentCrop && currentPreview ? { crop: currentCrop, rotation: rotation() } : null);\n });\n\n const readPointerPosition = (event: PointerEvent) => {\n if (!frame) return { x: 0, y: 0 };\n const rect = frame.getBoundingClientRect();\n return {\n x: (event.clientX - rect.left) / Math.max(1, rect.width),\n y: (event.clientY - rect.top) / Math.max(1, rect.height),\n };\n };\n\n const moveCrop = (event: PointerEvent) => {\n const state = drag();\n const currentSize = previewSize();\n if (!state || !currentSize || state.pointerId !== event.pointerId) return;\n event.preventDefault();\n const point = readPointerPosition(event);\n const dx = point.x - state.startX;\n const dy = point.y - state.startY;\n const start = state.startCrop;\n\n if (state.handle === \"move\") {\n setCrop(\n clampImageCropRect(\n {\n ...start,\n x: start.x + dx,\n y: start.y + dy,\n },\n currentSize,\n aspect(),\n ),\n );\n return;\n }\n\n setCrop(resizeImageCropFromCorner(start, currentSize, aspect(), state.handle, dx, dy));\n };\n\n const endDrag = (event: PointerEvent) => {\n const state = drag();\n if (!state || state.pointerId !== event.pointerId) return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n setDrag(null);\n };\n\n const startDrag = (handle: DragHandle, event: PointerEvent) => {\n const currentCrop = crop();\n if (!currentCrop || disabled()) return;\n event.preventDefault();\n event.stopPropagation();\n (event.currentTarget as Element).setPointerCapture?.(event.pointerId);\n const point = readPointerPosition(event);\n setDrag({\n handle,\n pointerId: event.pointerId,\n startX: point.x,\n startY: point.y,\n startCrop: currentCrop,\n });\n window.addEventListener(\"pointermove\", moveCrop);\n window.addEventListener(\"pointerup\", endDrag);\n window.addEventListener(\"pointercancel\", endDrag);\n };\n\n onCleanup(() => {\n if (typeof window === \"undefined\") return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n });\n\n const rotateRight = () => {\n if (disabled()) return;\n setRotation((current) => rotateImageCropRight(current));\n };\n\n const nudgeCrop = (handle: DragHandle, event: KeyboardEvent) => {\n if (disabled() || ![\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\"].includes(event.key)) return;\n const current = crop();\n const currentSize = previewSize();\n if (!current || !currentSize) return;\n event.preventDefault();\n const step = event.shiftKey ? 0.05 : 0.01;\n const dx = event.key === \"ArrowLeft\" ? -step : event.key === \"ArrowRight\" ? step : 0;\n const dy = event.key === \"ArrowUp\" ? -step : event.key === \"ArrowDown\" ? step : 0;\n setCrop(\n handle === \"move\"\n ? clampImageCropRect({ ...current, x: current.x + dx, y: current.y + dy }, currentSize, aspect())\n : resizeImageCropFromCorner(current, currentSize, aspect(), handle, dx, dy),\n );\n };\n\n const previewFrameStyle = (): JSX.CSSProperties => {\n const currentSize = previewSize();\n if (!currentSize) return {};\n return {\n \"aspect-ratio\": `${currentSize.width} / ${currentSize.height}`,\n \"max-width\": `min(100%, calc(min(58vh, 24rem) * ${currentSize.width} / ${currentSize.height}))`,\n };\n };\n\n const previewImageStyle = (): JSX.CSSProperties => {\n const currentPreview = preview();\n const currentSize = previewSize();\n if (!currentPreview || !currentSize) return {};\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n left: \"50%\",\n top: \"50%\",\n width: swapsDimensions ? `${(currentPreview.sourceWidth / currentSize.width) * 100}%` : \"100%\",\n height: swapsDimensions ? `${(currentPreview.sourceHeight / currentSize.height) * 100}%` : \"100%\",\n \"max-width\": \"none\",\n \"object-fit\": \"fill\",\n transform: `translate(-50%, -50%) rotate(${rotation()}deg)`,\n };\n };\n\n const cropStyle = (): JSX.CSSProperties => {\n const currentCrop = crop();\n if (!currentCrop) return {};\n return {\n left: `${currentCrop.x * 100}%`,\n top: `${currentCrop.y * 100}%`,\n width: `${currentCrop.width * 100}%`,\n height: `${currentCrop.height * 100}%`,\n \"box-shadow\": \"0 0 0 9999px rgba(0,0,0,.42)\",\n };\n };\n\n const showResizeHandles = () => previewShape() !== \"circle\";\n\n return (\n <div class={`k2b-image-cropper ${props.class ?? \"\"}`}>\n <div class=\"k2b-image-cropper__stage\">\n <Show when={!loading()} fallback={<small>{messages().preparingImage}</small>}>\n <Show when={!error()} fallback={<small class=\"k2b-image-cropper__error\">{error()}</small>}>\n <Show when={preview() && crop()}>\n <div ref={frame} class=\"k2b-image-cropper__frame\" style={previewFrameStyle()}>\n <img src={preview()!.url} alt={messages().cropPreview} draggable={false} style={previewImageStyle()} />\n <div\n class=\"k2b-image-cropper__selection\"\n data-shape={previewShape()}\n style={cropStyle()}\n role=\"group\"\n tabIndex={disabled() ? undefined : 0}\n aria-label={messages().cropArea}\n onPointerDown={(event) => startDrag(\"move\", event)}\n onKeyDown={(event) => nudgeCrop(\"move\", event)}\n >\n <Show when={showResizeHandles()}>\n <For each={[\"nw\", \"ne\", \"sw\", \"se\"] as const}>\n {(handle) => (\n <button\n type=\"button\"\n class=\"k2b-image-cropper__handle\"\n data-handle={handle}\n aria-label={messages().resizeCrop({ handle })}\n disabled={disabled()}\n onPointerDown={(event) => startDrag(handle, event)}\n onKeyDown={(event) => nudgeCrop(handle, event)}\n />\n )}\n </For>\n </Show>\n </div>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-image-cropper__rotate\"\n content={messages().rotateRight}\n aria-label={messages().rotateRight}\n disabled={disabled() || !crop() || Boolean(error())}\n onClick={rotateRight}\n >\n <i class=\"ti ti-rotate-clockwise\" aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </div>\n </Show>\n </Show>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["inputs/FileInputs.tsx"],"sourcesContent":["import { createEffect, createMemo, createSignal, For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { Tooltip } from \"../feedback/Tooltip\";\nimport { createFieldMeta, Field, fieldControlAria } from \"../internal/field\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { fileDropTarget } from \"./FileDropTarget\";\nimport type { FieldProps, ValueFieldProps } from \"./field-contract\";\nimport { commitFieldValue, resolveMaybeAccessor } from \"./field-contract\";\nimport { fileDropEngine, liveDocument } from \"./file-drop\";\nimport {\n clampImageCropRect,\n getInitialImageCropRect,\n type ImageCropAspect,\n type ImageCropRect,\n type ImageCropResizeHandle,\n type ImageCropRotation,\n type ImageCropSource,\n type ImageCropState,\n resizeImageCropFromCorner,\n rotateImageCropRight,\n} from \"./image-crop\";\n\nexport type FileDropzoneProps = FieldProps & {\n accept?: string;\n multiple?: boolean;\n busy?: boolean;\n /** Full icon class list, for example `\"ti ti-photo-plus\"`. Defaults to `\"ti ti-cloud-upload\"`. */\n icon?: string;\n title?: JSX.Element;\n subtitle?: JSX.Element;\n hint?: JSX.Element;\n /** One sentence that says what dropping does, shown while files are over the zone. Defaults to \"Drop to upload\". */\n dropLabel?: string;\n onDrop: (files: File[]) => void | Promise<void>;\n};\n\nexport function FileDropzone(props: FileDropzoneProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const disabled = () => Boolean(props.disabled || props.busy);\n const error = () => resolveMaybeAccessor(props.error);\n let input: HTMLInputElement | undefined;\n const [button, setButton] = createSignal<HTMLButtonElement>();\n const emit = (files: File[]) => {\n if (disabled() || files.length === 0) return;\n void props.onDrop(props.multiple === false ? files.slice(0, 1) : files);\n };\n // Drops take the same path as every other file drop target: files only, the most specific target wins, and files\n // that do not fit `accept` are left out with a message.\n const dropLabel = () => props.dropLabel ?? messages().dropToUpload;\n const dropRef = fileDropTarget({\n get label() {\n return dropLabel();\n },\n get accept() {\n return props.accept;\n },\n get multiple() {\n return props.multiple;\n },\n get disabled() {\n return disabled();\n },\n onDrop: emit,\n });\n const [engine, setEngine] = createSignal<ReturnType<typeof fileDropEngine>>();\n onMount(() => {\n const element = button();\n if (element) setEngine(fileDropEngine(liveDocument(element)));\n });\n const dragState = createMemo(() => {\n const element = button();\n const hover = engine()?.session()?.hover;\n if (!hover || hover.element !== element) return undefined;\n return hover.invalid ? \"invalid\" : \"over\";\n });\n const title = () =>\n props.busy\n ? messages().uploading\n : dragState() === \"invalid\"\n ? messages().fileTypeNotAccepted\n : dragState() === \"over\"\n ? dropLabel()\n : (props.title ?? messages().dropFiles);\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <button\n id={meta.controlId}\n type=\"button\"\n ref={(element) => {\n setButton(element);\n dropRef(element);\n }}\n class=\"k2b-dropzone\"\n data-invalid={error() ? \"true\" : undefined}\n disabled={disabled()}\n {...fieldControlAria(meta, props)}\n onClick={() => input?.click()}\n >\n <span class=\"k2b-dropzone__icon\" aria-hidden=\"true\">\n <i class={props.busy ? \"ti ti-loader-2 k2b-spin\" : (props.icon ?? \"ti ti-cloud-upload\")} />\n </span>\n <span class=\"k2b-dropzone__copy\">\n <strong>{title()}</strong>\n <Show\n when={dragState() === \"invalid\"}\n fallback={\n <Show when={props.subtitle}>\n <span class=\"k2b-dropzone__subtitle\">{props.subtitle}</span>\n </Show>\n }\n >\n <span class=\"k2b-dropzone__subtitle\">{messages().chooseMatchingFile}</span>\n </Show>\n <Show when={props.hint}>\n <span class=\"k2b-dropzone__hint\">{props.hint}</span>\n </Show>\n </span>\n </button>\n <input\n ref={input}\n class=\"k2b-sr-only\"\n type=\"file\"\n aria-label={\n props[\"aria-label\"] ??\n (typeof props.label === \"string\" ? props.label : props.multiple === false ? messages().chooseFile : messages().chooseFiles)\n }\n accept={props.accept}\n multiple={props.multiple ?? true}\n disabled={disabled()}\n tabIndex={-1}\n onChange={(event) => {\n const files = Array.from(event.currentTarget.files ?? []);\n // Reset before emitting so re-picking the same file still fires change,\n // even when onDrop throws.\n event.currentTarget.value = \"\";\n emit(files);\n }}\n />\n </Field>\n );\n}\n\nexport type ImageInputProps = ValueFieldProps<string | null> & {\n round?: boolean;\n variant?: \"default\" | \"small\";\n transform?: (file: File) => Promise<string>;\n accept?: string;\n fallbackMarker?: string;\n};\n\nconst DEFAULT_IMAGE_ACCEPT = \"image/jpeg,image/png,image/gif,image/webp,image/svg+xml,.jpg,.jpeg,.png,.gif,.webp,.svg\";\n\nconst defaultImageTransform = async (file: File): Promise<string> => {\n const { img } = await import(\"@k2b/stdlib/browser\");\n return img.presets.avatar(file);\n};\n\nexport function ImageInput(props: ImageInputProps): JSX.Element {\n const messages = useUiMessages();\n const meta = createFieldMeta(props.id);\n const [busy, setBusy] = createSignal(false);\n const [localError, setLocalError] = createSignal<string>();\n let input: HTMLInputElement | undefined;\n const disabled = () => Boolean(props.disabled || busy() || !props.onValueChange);\n const error = () => resolveMaybeAccessor(props.error) ?? localError();\n const value = () => {\n const current = resolveMaybeAccessor(props.value);\n return current && !current.includes(props.fallbackMarker ?? \"?fallback\") ? current : null;\n };\n const compact = () => props.variant === \"small\";\n const changeLabel = () => (value() ? messages().changeImage : messages().addImage);\n const changeIcon = () => (value() ? \"ti ti-pencil\" : \"ti ti-photo-plus\");\n const select = async (file: File | undefined) => {\n if (!file || disabled()) return;\n setBusy(true);\n setLocalError();\n try {\n const transformed = await (props.transform ?? defaultImageTransform)(file);\n commitFieldValue(props, transformed);\n } catch (error) {\n setLocalError(error instanceof Error ? error.message : messages().imageProcessingFailed);\n } finally {\n setBusy(false);\n if (input) input.value = \"\";\n }\n };\n\n return (\n <Field\n class={props.class}\n label={props.label}\n description={props.description}\n error={error()}\n meta={meta}\n required={props.required}\n disabled={disabled()}\n >\n <div\n class=\"k2b-image-input\"\n data-round={props.round ? \"true\" : undefined}\n data-variant={props.variant ?? \"default\"}\n role=\"group\"\n aria-labelledby={props.label ? meta.labelId : undefined}\n aria-label={!props.label ? props[\"aria-label\"] : undefined}\n aria-describedby={fieldControlAria(meta, { ...props, error })[\"aria-describedby\"]}\n >\n <div class=\"k2b-image-input__preview\">\n <Show when={value()} fallback={<i class=\"ti ti-photo-off\" aria-hidden=\"true\" />}>\n {(source) => <img src={source()} alt={typeof props.label === \"string\" ? props.label : messages().selectedImage} />}\n </Show>\n </div>\n <div class=\"k2b-image-input__actions\">\n <Show\n when={compact()}\n fallback={\n <Button\n variant=\"secondary\"\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n {value() ? messages().change : messages().add}\n </Button>\n }\n >\n <IconButton\n label={changeLabel()}\n loading={busy()}\n loadingLabel={messages().processingImage}\n disabled={disabled()}\n onClick={() => input?.click()}\n >\n <i class={changeIcon()} aria-hidden=\"true\" />\n </IconButton>\n </Show>\n <Show when={value()}>\n <Show\n when={compact()}\n fallback={\n <Button variant=\"ghost\" disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" /> Remove\n </Button>\n }\n >\n <IconButton label={messages().removeImage} disabled={disabled()} onClick={() => commitFieldValue(props, null)}>\n <i class=\"ti ti-trash\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </Show>\n </div>\n <input\n ref={input}\n id={meta.controlId}\n class=\"k2b-sr-only\"\n type=\"file\"\n accept={props.accept ?? DEFAULT_IMAGE_ACCEPT}\n disabled={disabled()}\n required={props.required && !value()}\n {...fieldControlAria(meta, { ...props, error })}\n onChange={(event) => void select(event.currentTarget.files?.[0])}\n />\n </div>\n </Field>\n );\n}\n\ntype PreviewState = {\n url: string;\n objectUrl: boolean;\n sourceWidth: number;\n sourceHeight: number;\n};\n\ntype DragHandle = \"move\" | ImageCropResizeHandle;\ntype DragState = {\n handle: DragHandle;\n pointerId: number;\n startX: number;\n startY: number;\n startCrop: ImageCropRect;\n};\n\nexport type ImageCropperProps = {\n source: ImageCropSource;\n aspect?: ImageCropAspect;\n previewShape?: \"rect\" | \"circle\";\n disabled?: boolean;\n onValueChange?: (state: ImageCropState | null) => void;\n class?: string;\n};\n\nconst clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(max, value));\n\nconst imageElementReady = async (image: HTMLImageElement): Promise<void> => {\n if (image.complete && image.naturalWidth > 0) return;\n await new Promise<void>((resolve, reject) => {\n image.addEventListener(\"load\", () => resolve(), { once: true });\n image.addEventListener(\"error\", () => reject(new Error(\"Failed to load image.\")), { once: true });\n });\n};\n\nconst loadPreviewState = async (source: ImageCropSource): Promise<PreviewState> => {\n const sourceImage =\n source instanceof HTMLImageElement\n ? source\n : Object.assign(new Image(), {\n crossOrigin: source instanceof Blob ? undefined : \"anonymous\",\n src:\n source instanceof HTMLCanvasElement\n ? source.toDataURL(\"image/png\")\n : source instanceof Blob\n ? URL.createObjectURL(source)\n : source,\n });\n\n try {\n await imageElementReady(sourceImage);\n return {\n url: source instanceof HTMLImageElement ? source.currentSrc || source.src : sourceImage.src,\n objectUrl: source instanceof Blob,\n sourceWidth: sourceImage.naturalWidth || sourceImage.width,\n sourceHeight: sourceImage.naturalHeight || sourceImage.height,\n };\n } catch (error) {\n if (source instanceof Blob) URL.revokeObjectURL(sourceImage.src);\n throw error;\n }\n};\n\nexport function ImageCropper(props: ImageCropperProps): JSX.Element {\n const messages = useUiMessages();\n let frame: HTMLDivElement | undefined;\n let activePreview: PreviewState | null = null;\n const aspect = () => props.aspect ?? \"free\";\n const previewShape = () => props.previewShape ?? \"rect\";\n const disabled = () => props.disabled ?? false;\n const [preview, setPreview] = createSignal<PreviewState | null>(null);\n const [crop, setCrop] = createSignal<ImageCropRect | null>(null);\n const [rotation, setRotation] = createSignal<ImageCropRotation>(0);\n const [loading, setLoading] = createSignal(true);\n const [error, setError] = createSignal<string | null>(null);\n const [drag, setDrag] = createSignal<DragState | null>(null);\n\n const previewSize = (): { width: number; height: number } | null => {\n const currentPreview = preview();\n if (!currentPreview) return null;\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n width: swapsDimensions ? currentPreview.sourceHeight : currentPreview.sourceWidth,\n height: swapsDimensions ? currentPreview.sourceWidth : currentPreview.sourceHeight,\n };\n };\n\n const replacePreview = (next: PreviewState | null) => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n activePreview = next;\n setPreview(next);\n };\n\n onCleanup(() => {\n if (activePreview?.objectUrl) URL.revokeObjectURL(activePreview.url);\n });\n\n createEffect(() => {\n props.source;\n setRotation(0);\n setCrop(null);\n });\n\n createEffect(() => {\n const source = props.source;\n let disposed = false;\n replacePreview(null);\n setLoading(true);\n setError(null);\n\n void (async () => {\n try {\n const nextPreview = await loadPreviewState(source);\n if (disposed) {\n if (nextPreview.objectUrl) URL.revokeObjectURL(nextPreview.url);\n return;\n }\n replacePreview(nextPreview);\n } catch {\n if (disposed) return;\n replacePreview(null);\n setCrop(null);\n setError(messages().failedLoadImage);\n } finally {\n if (!disposed) setLoading(false);\n }\n })();\n\n onCleanup(() => {\n disposed = true;\n });\n });\n\n createEffect(() => {\n const currentSize = previewSize();\n const currentAspect = aspect();\n if (!currentSize) return;\n setCrop((current) => clampImageCropRect(current ?? getInitialImageCropRect(currentSize, currentAspect), currentSize, currentAspect));\n });\n\n createEffect(() => {\n const currentCrop = crop();\n const currentPreview = preview();\n props.onValueChange?.(currentCrop && currentPreview ? { crop: currentCrop, rotation: rotation() } : null);\n });\n\n const readPointerPosition = (event: PointerEvent) => {\n if (!frame) return { x: 0, y: 0 };\n const rect = frame.getBoundingClientRect();\n return {\n x: (event.clientX - rect.left) / Math.max(1, rect.width),\n y: (event.clientY - rect.top) / Math.max(1, rect.height),\n };\n };\n\n const moveCrop = (event: PointerEvent) => {\n const state = drag();\n const currentSize = previewSize();\n if (!state || !currentSize || state.pointerId !== event.pointerId) return;\n event.preventDefault();\n const point = readPointerPosition(event);\n const dx = point.x - state.startX;\n const dy = point.y - state.startY;\n const start = state.startCrop;\n\n if (state.handle === \"move\") {\n setCrop(\n clampImageCropRect(\n {\n ...start,\n x: start.x + dx,\n y: start.y + dy,\n },\n currentSize,\n aspect(),\n ),\n );\n return;\n }\n\n setCrop(resizeImageCropFromCorner(start, currentSize, aspect(), state.handle, dx, dy));\n };\n\n const endDrag = (event: PointerEvent) => {\n const state = drag();\n if (!state || state.pointerId !== event.pointerId) return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n setDrag(null);\n };\n\n const startDrag = (handle: DragHandle, event: PointerEvent) => {\n const currentCrop = crop();\n if (!currentCrop || disabled()) return;\n event.preventDefault();\n event.stopPropagation();\n (event.currentTarget as Element).setPointerCapture?.(event.pointerId);\n const point = readPointerPosition(event);\n setDrag({\n handle,\n pointerId: event.pointerId,\n startX: point.x,\n startY: point.y,\n startCrop: currentCrop,\n });\n window.addEventListener(\"pointermove\", moveCrop);\n window.addEventListener(\"pointerup\", endDrag);\n window.addEventListener(\"pointercancel\", endDrag);\n };\n\n onCleanup(() => {\n if (typeof window === \"undefined\") return;\n window.removeEventListener(\"pointermove\", moveCrop);\n window.removeEventListener(\"pointerup\", endDrag);\n window.removeEventListener(\"pointercancel\", endDrag);\n });\n\n const rotateRight = () => {\n if (disabled()) return;\n setRotation((current) => rotateImageCropRight(current));\n };\n\n const nudgeCrop = (handle: DragHandle, event: KeyboardEvent) => {\n if (disabled() || ![\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\"].includes(event.key)) return;\n const current = crop();\n const currentSize = previewSize();\n if (!current || !currentSize) return;\n event.preventDefault();\n const step = event.shiftKey ? 0.05 : 0.01;\n const dx = event.key === \"ArrowLeft\" ? -step : event.key === \"ArrowRight\" ? step : 0;\n const dy = event.key === \"ArrowUp\" ? -step : event.key === \"ArrowDown\" ? step : 0;\n setCrop(\n handle === \"move\"\n ? clampImageCropRect({ ...current, x: current.x + dx, y: current.y + dy }, currentSize, aspect())\n : resizeImageCropFromCorner(current, currentSize, aspect(), handle, dx, dy),\n );\n };\n\n const previewFrameStyle = (): JSX.CSSProperties => {\n const currentSize = previewSize();\n if (!currentSize) return {};\n return {\n \"aspect-ratio\": `${currentSize.width} / ${currentSize.height}`,\n \"max-width\": `min(100%, calc(min(58vh, 24rem) * ${currentSize.width} / ${currentSize.height}))`,\n };\n };\n\n const previewImageStyle = (): JSX.CSSProperties => {\n const currentPreview = preview();\n const currentSize = previewSize();\n if (!currentPreview || !currentSize) return {};\n const swapsDimensions = rotation() === 90 || rotation() === 270;\n return {\n left: \"50%\",\n top: \"50%\",\n width: swapsDimensions ? `${(currentPreview.sourceWidth / currentSize.width) * 100}%` : \"100%\",\n height: swapsDimensions ? `${(currentPreview.sourceHeight / currentSize.height) * 100}%` : \"100%\",\n \"max-width\": \"none\",\n \"object-fit\": \"fill\",\n transform: `translate(-50%, -50%) rotate(${rotation()}deg)`,\n };\n };\n\n const cropStyle = (): JSX.CSSProperties => {\n const currentCrop = crop();\n if (!currentCrop) return {};\n return {\n left: `${currentCrop.x * 100}%`,\n top: `${currentCrop.y * 100}%`,\n width: `${currentCrop.width * 100}%`,\n height: `${currentCrop.height * 100}%`,\n \"box-shadow\": \"0 0 0 9999px rgba(0,0,0,.42)\",\n };\n };\n\n const showResizeHandles = () => previewShape() !== \"circle\";\n\n return (\n <div class={`k2b-image-cropper ${props.class ?? \"\"}`}>\n <div class=\"k2b-image-cropper__stage\">\n <Show when={!loading()} fallback={<small>{messages().preparingImage}</small>}>\n <Show when={!error()} fallback={<small class=\"k2b-image-cropper__error\">{error()}</small>}>\n <Show when={preview() && crop()}>\n <div ref={frame} class=\"k2b-image-cropper__frame\" style={previewFrameStyle()}>\n <img src={preview()!.url} alt={messages().cropPreview} draggable={false} style={previewImageStyle()} />\n <div\n class=\"k2b-image-cropper__selection\"\n data-shape={previewShape()}\n style={cropStyle()}\n role=\"group\"\n tabIndex={disabled() ? undefined : 0}\n aria-label={messages().cropArea}\n onPointerDown={(event) => startDrag(\"move\", event)}\n onKeyDown={(event) => nudgeCrop(\"move\", event)}\n >\n <Show when={showResizeHandles()}>\n <For each={[\"nw\", \"ne\", \"sw\", \"se\"] as const}>\n {(handle) => (\n <button\n type=\"button\"\n class=\"k2b-image-cropper__handle\"\n data-handle={handle}\n aria-label={messages().resizeCrop({ handle })}\n disabled={disabled()}\n onPointerDown={(event) => startDrag(handle, event)}\n onKeyDown={(event) => nudgeCrop(handle, event)}\n />\n )}\n </For>\n </Show>\n </div>\n <Tooltip.Trigger\n type=\"button\"\n class=\"k2b-image-cropper__rotate\"\n content={messages().rotateRight}\n aria-label={messages().rotateRight}\n disabled={disabled() || !crop() || Boolean(error())}\n onClick={rotateRight}\n >\n <i class=\"ti ti-rotate-clockwise\" aria-hidden=\"true\" />\n </Tooltip.Trigger>\n </div>\n </Show>\n </Show>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,338 @@
1
+ import { text } from "@k2b/stdlib";
2
+ import { checkMimeType } from "@k2b/stdlib/browser";
3
+ import { createSignal } from "solid-js";
4
+ import { announce } from "../feedback/announce";
5
+ import { toast } from "../feedback/toast";
6
+ /** The marker a hovered specific target carries for its ring; regions show their own overlay instead. */
7
+ export const FILE_DROP_ATTRIBUTE = "data-file-drop";
8
+
9
+ /** Where a region without `for` looks for its area: the nearest dialog, workspace detail, or workspace main area. */
10
+ export const FILE_DROP_DEFAULT_REGION = "dialog, .k2b-app-workspace__detail, .k2b-app-workspace__main";
11
+
12
+ /**
13
+ * The type every drag that starts in a page carries. Such a drag holds page content, never files from outside, even
14
+ * an image that carries one. Marking the drag itself leaves nothing behind when it never reports its end, as when its
15
+ * start is cancelled or its source is removed.
16
+ */
17
+ const PAGE_DRAG_TYPE = "application/x-k2b-page-drag";
18
+
19
+ /** How long after the last drag event a pointer move means the drag ended; a drag over the page repeats them sooner. */
20
+ const DRAG_SILENCE_MS = 600;
21
+ const engines = new WeakMap();
22
+ const isFileDrag = event => {
23
+ const types = Array.from(event.dataTransfer?.types ?? []);
24
+ return types.includes("Files") && !types.includes(PAGE_DRAG_TYPE);
25
+ };
26
+ const elementOf = target => target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
27
+ const isModal = dialog => {
28
+ try {
29
+ return dialog.matches(":modal");
30
+ } catch {
31
+ // An engine without `:modal` has no modal dialogs to defer to.
32
+ return false;
33
+ }
34
+ };
35
+
36
+ /**
37
+ * The topmost modal dialog. Everything outside of it is inert, so a drag over the page lands inside it; only a drag
38
+ * over other top-layer content falls back to the last modal dialog in the document.
39
+ */
40
+ const topModal = (doc, target) => {
41
+ for (let dialog = elementOf(target)?.closest("dialog"); dialog; dialog = dialog.parentElement?.closest("dialog")) if (isModal(dialog)) return dialog;
42
+ return Array.from(doc.querySelectorAll("dialog[open]")).filter(isModal).at(-1) ?? null;
43
+ };
44
+
45
+ /** Sorts dropped files into the ones a target takes and the ones it leaves out, in drop order. */
46
+ export const partitionDroppedFiles = (files, options) => {
47
+ const limit = options.multiple === false ? 1 : options.maxFiles ?? Number.POSITIVE_INFINITY;
48
+ const accepted = [];
49
+ const rejected = [];
50
+ for (const file of files) {
51
+ if (options.accept && !checkMimeType(file, options.accept)) rejected.push({
52
+ file,
53
+ reason: "type"
54
+ });else if (options.maxSize !== undefined && file.size > options.maxSize) rejected.push({
55
+ file,
56
+ reason: "size"
57
+ });else if (accepted.length >= limit) rejected.push({
58
+ file,
59
+ reason: "count"
60
+ });else accepted.push(file);
61
+ }
62
+ return {
63
+ accepted,
64
+ rejected
65
+ };
66
+ };
67
+
68
+ /**
69
+ * During a drag only the types are readable, and only in some engines. A drag is refused when none of them can fit.
70
+ * An extension in `accept` matches by file name, and systems report differing types for one extension (a `.csv` may be
71
+ * `application/vnd.ms-excel`), so with one the drop decides.
72
+ */
73
+ export const refusesDraggedTypes = (types, accept) => {
74
+ if (!accept || accept.split(",").some(entry => entry.trim().startsWith("."))) return false;
75
+ return types.length > 0 && types.every(type => type !== "" && !checkMimeType(type, accept));
76
+ };
77
+ const invalidDrag = (event, options) => refusesDraggedTypes(Array.from(event.dataTransfer?.items ?? []).filter(item => item.kind === "file").map(item => item.type), options.accept);
78
+ const MAX_NAMES = 3;
79
+ const nameList = (files, messages) => {
80
+ const names = files.slice(0, MAX_NAMES).map(file => file.name);
81
+ return files.length > MAX_NAMES ? `${names.join(", ")} ${messages.fileDropMore({
82
+ count: files.length - MAX_NAMES
83
+ })}` : names.join(", ");
84
+ };
85
+ export const fileDropRejectionMessage = (rejected, options, messages, locale) => {
86
+ const lines = [];
87
+ const of = reason => rejected.filter(entry => entry.reason === reason).map(entry => entry.file);
88
+ const type = of("type");
89
+ const size = of("size");
90
+ const count = of("count");
91
+ if (type.length) lines.push(messages.fileDropRejectedType({
92
+ names: nameList(type, messages)
93
+ }));
94
+ if (size.length) lines.push(messages.fileDropRejectedSize({
95
+ names: nameList(size, messages),
96
+ limit: text.pprintBytes(options.maxSize ?? 0, {
97
+ locale
98
+ })
99
+ }));
100
+ if (count.length) lines.push(messages.fileDropRejectedCount({
101
+ names: nameList(count, messages),
102
+ max: options.multiple === false ? 1 : options.maxFiles ?? 1
103
+ }));
104
+ return lines.join("\n");
105
+ };
106
+ const createEngine = doc => {
107
+ const view = doc.defaultView;
108
+ const regions = new Set();
109
+ const targets = new WeakMap();
110
+ const [session, setSession] = createSignal(null);
111
+ const [frame, setFrame] = createSignal(0);
112
+ /** Elements the drag has entered and not yet left; the drag is over the window while any remains. */
113
+ const entered = new Set();
114
+ let lastDragEvent = 0;
115
+ let marked = null;
116
+ let frameRequest = 0;
117
+ const mark = hover => {
118
+ if (marked && marked !== hover?.element) marked.removeAttribute(FILE_DROP_ATTRIBUTE);
119
+ marked = null;
120
+ if (!hover || hover.entry.region) return;
121
+ marked = hover.element;
122
+ marked.setAttribute(FILE_DROP_ATTRIBUTE, hover.invalid ? "invalid" : "over");
123
+ };
124
+ const regionElement = entry => {
125
+ const element = entry.region?.();
126
+ return element?.isConnected ? element : undefined;
127
+ };
128
+
129
+ /** Whether nothing between the target's host and its area hides it, as a dialog stack hides its lower levels. */
130
+ const displayed = (host, area) => {
131
+ for (let element = host; element && element !== area; element = element.parentElement) if (view?.getComputedStyle(element).display === "none") return false;
132
+ return true;
133
+ };
134
+
135
+ /** A region takes part when it is enabled, displayed, and not behind a modal dialog it is not inside of. */
136
+ const eligible = (entry, modal) => {
137
+ const element = regionElement(entry);
138
+ if (!element || entry.options.disabled) return false;
139
+ return (!modal || modal.contains(element)) && displayed(entry.host?.(), element);
140
+ };
141
+ const rendered = element => element === doc.documentElement || element.getClientRects().length > 0;
142
+ const begin = target => {
143
+ const modal = topModal(doc, target);
144
+ const candidates = [...regions].filter(entry => eligible(entry, modal) && rendered(regionElement(entry)));
145
+ // The latest region on an element replaces earlier ones; a region inside another shown one acts as a specific target.
146
+ const byElement = new Map();
147
+ for (const entry of candidates) byElement.set(regionElement(entry), entry);
148
+ const shown = [...byElement].filter(([element]) => ![...byElement.keys()].some(other => other !== element && other.contains(element)));
149
+ setSession({
150
+ shown: shown.map(([, entry]) => entry),
151
+ hover: null
152
+ });
153
+ const first = shown[0]?.[1];
154
+ if (first) announce(first.options.label);
155
+ };
156
+ const end = () => {
157
+ entered.clear();
158
+ mark(null);
159
+ if (session()) setSession(null);
160
+ };
161
+ const resolve = target => {
162
+ const modal = topModal(doc, target);
163
+ for (let element = elementOf(target); element; element = element.parentElement) {
164
+ const specific = targets.get(element);
165
+ if (specific && !specific.options.disabled) return {
166
+ entry: specific,
167
+ element
168
+ };
169
+ let region;
170
+ for (const entry of regions) if (regionElement(entry) === element && eligible(entry, modal)) region = entry;
171
+ if (region) return {
172
+ entry: region,
173
+ element
174
+ };
175
+ }
176
+ return null;
177
+ };
178
+ const hoverFrom = event => {
179
+ const current = session();
180
+ if (!current) return null;
181
+ const found = resolve(event.target);
182
+ const hover = found ? {
183
+ ...found,
184
+ invalid: invalidDrag(event, found.entry.options)
185
+ } : null;
186
+ const previous = current.hover;
187
+ if (previous?.entry !== hover?.entry || previous?.element !== hover?.element || previous?.invalid !== hover?.invalid) {
188
+ mark(hover);
189
+ setSession({
190
+ ...current,
191
+ hover
192
+ });
193
+ }
194
+ return hover;
195
+ };
196
+
197
+ /** Over a page with a region, a file never falls through to the browser, which would open it and leave the page. */
198
+ const guarding = () => [...regions].some(entry => regionElement(entry));
199
+ const accept = (event, hover) => {
200
+ if (!hover && !guarding()) return;
201
+ event.preventDefault();
202
+ if (event.dataTransfer) event.dataTransfer.dropEffect = hover && !hover.invalid ? "copy" : "none";
203
+ };
204
+ const requestFrame = () => {
205
+ if (frameRequest || !view) return;
206
+ frameRequest = view.requestAnimationFrame(() => {
207
+ frameRequest = 0;
208
+ setFrame(value => value + 1);
209
+ });
210
+ };
211
+ const deliver = (entry, dataTransfer) => {
212
+ const {
213
+ options
214
+ } = entry;
215
+ const files = Array.from(dataTransfer.files);
216
+ const {
217
+ accepted,
218
+ rejected
219
+ } = partitionDroppedFiles(files, options);
220
+ const messages = entry.messages();
221
+ if (rejected.length) toast.error(fileDropRejectionMessage(rejected, options, messages, entry.locale()));
222
+ if (!accepted.length && files.length) return;
223
+ if (accepted.length) announce(accepted.length === 1 ? messages.fileDropDroppedOne({
224
+ name: accepted[0].name
225
+ }) : messages.fileDropDropped({
226
+ count: accepted.length
227
+ }));
228
+ void options.onDrop(accepted, {
229
+ dataTransfer,
230
+ rejected
231
+ });
232
+ };
233
+ const listeners = {
234
+ dragstart: event => {
235
+ event.dataTransfer?.setData(PAGE_DRAG_TYPE, "");
236
+ },
237
+ dragenter: event => {
238
+ const drag = event;
239
+ if (!isFileDrag(drag)) return;
240
+ lastDragEvent = event.timeStamp;
241
+ if (event.target) entered.add(event.target);
242
+ if (!session()) begin(event.target);
243
+ accept(drag, hoverFrom(drag));
244
+ },
245
+ dragover: event => {
246
+ const drag = event;
247
+ if (!isFileDrag(drag)) return;
248
+ lastDragEvent = event.timeStamp;
249
+ // An engine may skip the first dragenter; the drag still counts as over the window.
250
+ if (!session()) {
251
+ if (event.target) entered.add(event.target);
252
+ begin(event.target);
253
+ }
254
+ accept(drag, hoverFrom(drag));
255
+ requestFrame();
256
+ },
257
+ dragleave: event => {
258
+ if (!session()) return;
259
+ if (event.target) entered.delete(event.target);
260
+ // An element removed during the drag never reports leaving.
261
+ for (const target of entered) if (target instanceof Node && !target.isConnected) entered.delete(target);
262
+ if (entered.size === 0) end();
263
+ },
264
+ drop: event => {
265
+ const drag = event;
266
+ if (!isFileDrag(drag)) return;
267
+ const found = resolve(event.target);
268
+ end();
269
+ if (!found) {
270
+ if (guarding()) event.preventDefault();
271
+ return;
272
+ }
273
+ // The most specific target owns the drop; editors and other handlers below it never see the files.
274
+ event.preventDefault();
275
+ event.stopPropagation();
276
+ if (drag.dataTransfer) deliver(found.entry, drag.dataTransfer);
277
+ },
278
+ keydown: event => {
279
+ if (event.key === "Escape" && session()) end();
280
+ },
281
+ // Engines send no pointer moves during a drag: one long after the last drag event means the drag ended somewhere the
282
+ // page did not see. One right after it belongs to another pointer, such as a second finger on a touch screen.
283
+ pointermove: event => {
284
+ if (session() && event.timeStamp - lastDragEvent > DRAG_SILENCE_MS) end();
285
+ },
286
+ visibilitychange: () => {
287
+ if (doc.visibilityState === "hidden") end();
288
+ }
289
+ };
290
+ let installed = false;
291
+ const install = () => {
292
+ if (installed || !view) return;
293
+ installed = true;
294
+ for (const [type, listener] of Object.entries(listeners)) (type === "visibilitychange" ? doc : view).addEventListener(type, listener, {
295
+ capture: true
296
+ });
297
+ };
298
+ return {
299
+ session,
300
+ frame,
301
+ addRegion: entry => {
302
+ install();
303
+ regions.add(entry);
304
+ return () => {
305
+ regions.delete(entry);
306
+ const current = session();
307
+ if (current?.hover?.entry === entry) {
308
+ mark(null);
309
+ setSession({
310
+ ...current,
311
+ hover: null
312
+ });
313
+ }
314
+ };
315
+ },
316
+ setTarget: (element, entry) => {
317
+ install();
318
+ targets.set(element, entry);
319
+ }
320
+ };
321
+ };
322
+
323
+ /**
324
+ * The document an element lives in. A freshly rendered element still belongs to the inert document of the template it
325
+ * was cloned from; until it is inserted, that is the page's document.
326
+ */
327
+ export const liveDocument = element => element.ownerDocument.defaultView ? element.ownerDocument : document;
328
+
329
+ /** The one drag tracker of a document, shared by every drop target in it. */
330
+ export const fileDropEngine = doc => {
331
+ let engine = engines.get(doc);
332
+ if (!engine) {
333
+ engine = createEngine(doc);
334
+ engines.set(doc, engine);
335
+ }
336
+ return engine;
337
+ };
338
+ //# sourceMappingURL=file-drop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["inputs/file-drop.ts"],"sourcesContent":["import { text } from \"@k2b/stdlib\";\nimport { checkMimeType } from \"@k2b/stdlib/browser\";\nimport { type Accessor, createSignal } from \"solid-js\";\nimport { announce } from \"../feedback/announce\";\nimport { toast } from \"../feedback/toast\";\nimport type { UiMessages } from \"../intl/messages\";\n\nexport type FileDropRejection = {\n file: File;\n /** `type` misses `accept`, `size` exceeds `maxSize`, `count` is past `maxFiles` or the single file of `multiple={false}`. */\n reason: \"type\" | \"size\" | \"count\";\n};\n\nexport type FileDropDetails = {\n /** The drop's data, readable only while `onDrop` runs synchronously; read folder entries before the first `await`. */\n dataTransfer: DataTransfer;\n /** Files left out by `accept`, `maxSize`, or the file count; the user has already been told. */\n rejected: readonly FileDropRejection[];\n};\n\nexport type FileDropOptions = {\n /** One sentence that says what dropping does here, such as \"Drop to attach to the message\". */\n label: string;\n /** `<input accept>` syntax, such as `\"image/*,.pdf\"`. */\n accept?: string;\n /** Defaults to `true`; `false` takes the first fitting file. */\n multiple?: boolean;\n /** The most files one drop hands over. */\n maxFiles?: number;\n /** The largest file in bytes. */\n maxSize?: number;\n disabled?: boolean;\n /**\n * Called synchronously in the drop with the files that fit. `files` is empty only when the drop carried no file\n * objects at all, as some engines hand over dropped folders; `details.dataTransfer.items` still has their entries.\n */\n onDrop: (files: File[], details: FileDropDetails) => void | Promise<void>;\n};\n\nexport type FileDropTargetEntry = {\n options: FileDropOptions;\n messages: () => UiMessages;\n locale: () => string;\n /** Set for regions: the area the overlay covers. Specific targets are keyed by their element. */\n region?: () => Element | undefined;\n /** Set for regions: where the target itself is rendered; a region whose host is hidden takes no drops. */\n host?: () => Element | undefined;\n};\n\nexport type FileDropHover = { entry: FileDropTargetEntry; element: Element; invalid: boolean };\n\nexport type FileDropSession = {\n /** Regions that show their overlay during this drag: eligible, visible, and not inside another shown region. */\n shown: readonly FileDropTargetEntry[];\n hover: FileDropHover | null;\n};\n\nexport type FileDropEngine = {\n session: Accessor<FileDropSession | null>;\n /** Changes on every drag movement, so overlays can follow a region that moved or resized. */\n frame: Accessor<number>;\n addRegion: (entry: FileDropTargetEntry) => () => void;\n setTarget: (element: Element, entry: FileDropTargetEntry) => void;\n};\n\n/** The marker a hovered specific target carries for its ring; regions show their own overlay instead. */\nexport const FILE_DROP_ATTRIBUTE = \"data-file-drop\";\n\n/** Where a region without `for` looks for its area: the nearest dialog, workspace detail, or workspace main area. */\nexport const FILE_DROP_DEFAULT_REGION = \"dialog, .k2b-app-workspace__detail, .k2b-app-workspace__main\";\n\n/**\n * The type every drag that starts in a page carries. Such a drag holds page content, never files from outside, even\n * an image that carries one. Marking the drag itself leaves nothing behind when it never reports its end, as when its\n * start is cancelled or its source is removed.\n */\nconst PAGE_DRAG_TYPE = \"application/x-k2b-page-drag\";\n\n/** How long after the last drag event a pointer move means the drag ended; a drag over the page repeats them sooner. */\nconst DRAG_SILENCE_MS = 600;\n\nconst engines = new WeakMap<Document, FileDropEngine>();\n\nconst isFileDrag = (event: DragEvent) => {\n const types = Array.from(event.dataTransfer?.types ?? []);\n return types.includes(\"Files\") && !types.includes(PAGE_DRAG_TYPE);\n};\n\nconst elementOf = (target: EventTarget | null): Element | null =>\n target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n\nconst isModal = (dialog: Element) => {\n try {\n return dialog.matches(\":modal\");\n } catch {\n // An engine without `:modal` has no modal dialogs to defer to.\n return false;\n }\n};\n\n/**\n * The topmost modal dialog. Everything outside of it is inert, so a drag over the page lands inside it; only a drag\n * over other top-layer content falls back to the last modal dialog in the document.\n */\nconst topModal = (doc: Document, target: EventTarget | null): Element | null => {\n for (let dialog = elementOf(target)?.closest(\"dialog\"); dialog; dialog = dialog.parentElement?.closest(\"dialog\"))\n if (isModal(dialog)) return dialog;\n return Array.from(doc.querySelectorAll(\"dialog[open]\")).filter(isModal).at(-1) ?? null;\n};\n\n/** Sorts dropped files into the ones a target takes and the ones it leaves out, in drop order. */\nexport const partitionDroppedFiles = (\n files: readonly File[],\n options: Pick<FileDropOptions, \"accept\" | \"multiple\" | \"maxFiles\" | \"maxSize\">,\n): { accepted: File[]; rejected: FileDropRejection[] } => {\n const limit = options.multiple === false ? 1 : (options.maxFiles ?? Number.POSITIVE_INFINITY);\n const accepted: File[] = [];\n const rejected: FileDropRejection[] = [];\n for (const file of files) {\n if (options.accept && !checkMimeType(file, options.accept)) rejected.push({ file, reason: \"type\" });\n else if (options.maxSize !== undefined && file.size > options.maxSize) rejected.push({ file, reason: \"size\" });\n else if (accepted.length >= limit) rejected.push({ file, reason: \"count\" });\n else accepted.push(file);\n }\n return { accepted, rejected };\n};\n\n/**\n * During a drag only the types are readable, and only in some engines. A drag is refused when none of them can fit.\n * An extension in `accept` matches by file name, and systems report differing types for one extension (a `.csv` may be\n * `application/vnd.ms-excel`), so with one the drop decides.\n */\nexport const refusesDraggedTypes = (types: readonly string[], accept: string | undefined): boolean => {\n if (!accept || accept.split(\",\").some((entry) => entry.trim().startsWith(\".\"))) return false;\n return types.length > 0 && types.every((type) => type !== \"\" && !checkMimeType(type, accept));\n};\n\nconst invalidDrag = (event: DragEvent, options: FileDropOptions) =>\n refusesDraggedTypes(\n Array.from(event.dataTransfer?.items ?? [])\n .filter((item) => item.kind === \"file\")\n .map((item) => item.type),\n options.accept,\n );\n\nconst MAX_NAMES = 3;\nconst nameList = (files: readonly File[], messages: UiMessages) => {\n const names = files.slice(0, MAX_NAMES).map((file) => file.name);\n return files.length > MAX_NAMES ? `${names.join(\", \")} ${messages.fileDropMore({ count: files.length - MAX_NAMES })}` : names.join(\", \");\n};\n\nexport const fileDropRejectionMessage = (\n rejected: readonly FileDropRejection[],\n options: Pick<FileDropOptions, \"multiple\" | \"maxFiles\" | \"maxSize\">,\n messages: UiMessages,\n locale: string,\n): string => {\n const lines: string[] = [];\n const of = (reason: FileDropRejection[\"reason\"]) => rejected.filter((entry) => entry.reason === reason).map((entry) => entry.file);\n const type = of(\"type\");\n const size = of(\"size\");\n const count = of(\"count\");\n if (type.length) lines.push(messages.fileDropRejectedType({ names: nameList(type, messages) }));\n if (size.length)\n lines.push(\n messages.fileDropRejectedSize({ names: nameList(size, messages), limit: text.pprintBytes(options.maxSize ?? 0, { locale }) }),\n );\n if (count.length)\n lines.push(\n messages.fileDropRejectedCount({ names: nameList(count, messages), max: options.multiple === false ? 1 : (options.maxFiles ?? 1) }),\n );\n return lines.join(\"\\n\");\n};\n\nconst createEngine = (doc: Document): FileDropEngine => {\n const view = doc.defaultView;\n const regions = new Set<FileDropTargetEntry>();\n const targets = new WeakMap<Element, FileDropTargetEntry>();\n const [session, setSession] = createSignal<FileDropSession | null>(null);\n const [frame, setFrame] = createSignal(0);\n /** Elements the drag has entered and not yet left; the drag is over the window while any remains. */\n const entered = new Set<EventTarget>();\n let lastDragEvent = 0;\n let marked: Element | null = null;\n let frameRequest = 0;\n\n const mark = (hover: FileDropHover | null) => {\n if (marked && marked !== hover?.element) marked.removeAttribute(FILE_DROP_ATTRIBUTE);\n marked = null;\n if (!hover || hover.entry.region) return;\n marked = hover.element;\n marked.setAttribute(FILE_DROP_ATTRIBUTE, hover.invalid ? \"invalid\" : \"over\");\n };\n\n const regionElement = (entry: FileDropTargetEntry) => {\n const element = entry.region?.();\n return element?.isConnected ? element : undefined;\n };\n\n /** Whether nothing between the target's host and its area hides it, as a dialog stack hides its lower levels. */\n const displayed = (host: Element | undefined, area: Element) => {\n for (let element: Element | null | undefined = host; element && element !== area; element = element.parentElement)\n if (view?.getComputedStyle(element).display === \"none\") return false;\n return true;\n };\n\n /** A region takes part when it is enabled, displayed, and not behind a modal dialog it is not inside of. */\n const eligible = (entry: FileDropTargetEntry, modal: Element | null) => {\n const element = regionElement(entry);\n if (!element || entry.options.disabled) return false;\n return (!modal || modal.contains(element)) && displayed(entry.host?.(), element);\n };\n const rendered = (element: Element) => element === doc.documentElement || element.getClientRects().length > 0;\n\n const begin = (target: EventTarget | null) => {\n const modal = topModal(doc, target);\n const candidates = [...regions].filter((entry) => eligible(entry, modal) && rendered(regionElement(entry)!));\n // The latest region on an element replaces earlier ones; a region inside another shown one acts as a specific target.\n const byElement = new Map<Element, FileDropTargetEntry>();\n for (const entry of candidates) byElement.set(regionElement(entry)!, entry);\n const shown = [...byElement].filter(\n ([element]) => ![...byElement.keys()].some((other) => other !== element && other.contains(element)),\n );\n setSession({ shown: shown.map(([, entry]) => entry), hover: null });\n const first = shown[0]?.[1];\n if (first) announce(first.options.label);\n };\n\n const end = () => {\n entered.clear();\n mark(null);\n if (session()) setSession(null);\n };\n\n const resolve = (target: EventTarget | null): { entry: FileDropTargetEntry; element: Element } | null => {\n const modal = topModal(doc, target);\n for (let element = elementOf(target); element; element = element.parentElement) {\n const specific = targets.get(element);\n if (specific && !specific.options.disabled) return { entry: specific, element };\n let region: FileDropTargetEntry | undefined;\n for (const entry of regions) if (regionElement(entry) === element && eligible(entry, modal)) region = entry;\n if (region) return { entry: region, element };\n }\n return null;\n };\n\n const hoverFrom = (event: DragEvent) => {\n const current = session();\n if (!current) return null;\n const found = resolve(event.target);\n const hover = found ? { ...found, invalid: invalidDrag(event, found.entry.options) } : null;\n const previous = current.hover;\n if (previous?.entry !== hover?.entry || previous?.element !== hover?.element || previous?.invalid !== hover?.invalid) {\n mark(hover);\n setSession({ ...current, hover });\n }\n return hover;\n };\n\n /** Over a page with a region, a file never falls through to the browser, which would open it and leave the page. */\n const guarding = () => [...regions].some((entry) => regionElement(entry));\n\n const accept = (event: DragEvent, hover: FileDropHover | null) => {\n if (!hover && !guarding()) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = hover && !hover.invalid ? \"copy\" : \"none\";\n };\n\n const requestFrame = () => {\n if (frameRequest || !view) return;\n frameRequest = view.requestAnimationFrame(() => {\n frameRequest = 0;\n setFrame((value) => value + 1);\n });\n };\n\n const deliver = (entry: FileDropTargetEntry, dataTransfer: DataTransfer) => {\n const { options } = entry;\n const files = Array.from(dataTransfer.files);\n const { accepted, rejected } = partitionDroppedFiles(files, options);\n const messages = entry.messages();\n if (rejected.length) toast.error(fileDropRejectionMessage(rejected, options, messages, entry.locale()));\n if (!accepted.length && files.length) return;\n if (accepted.length)\n announce(\n accepted.length === 1\n ? messages.fileDropDroppedOne({ name: accepted[0]!.name })\n : messages.fileDropDropped({ count: accepted.length }),\n );\n void options.onDrop(accepted, { dataTransfer, rejected });\n };\n\n const listeners: Record<string, (event: Event) => void> = {\n dragstart: (event) => {\n (event as DragEvent).dataTransfer?.setData(PAGE_DRAG_TYPE, \"\");\n },\n dragenter: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n if (event.target) entered.add(event.target);\n if (!session()) begin(event.target);\n accept(drag, hoverFrom(drag));\n },\n dragover: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n lastDragEvent = event.timeStamp;\n // An engine may skip the first dragenter; the drag still counts as over the window.\n if (!session()) {\n if (event.target) entered.add(event.target);\n begin(event.target);\n }\n accept(drag, hoverFrom(drag));\n requestFrame();\n },\n dragleave: (event) => {\n if (!session()) return;\n if (event.target) entered.delete(event.target);\n // An element removed during the drag never reports leaving.\n for (const target of entered) if (target instanceof Node && !target.isConnected) entered.delete(target);\n if (entered.size === 0) end();\n },\n drop: (event) => {\n const drag = event as DragEvent;\n if (!isFileDrag(drag)) return;\n const found = resolve(event.target);\n end();\n if (!found) {\n if (guarding()) event.preventDefault();\n return;\n }\n // The most specific target owns the drop; editors and other handlers below it never see the files.\n event.preventDefault();\n event.stopPropagation();\n if (drag.dataTransfer) deliver(found.entry, drag.dataTransfer);\n },\n keydown: (event) => {\n if ((event as KeyboardEvent).key === \"Escape\" && session()) end();\n },\n // Engines send no pointer moves during a drag: one long after the last drag event means the drag ended somewhere the\n // page did not see. One right after it belongs to another pointer, such as a second finger on a touch screen.\n pointermove: (event) => {\n if (session() && event.timeStamp - lastDragEvent > DRAG_SILENCE_MS) end();\n },\n visibilitychange: () => {\n if (doc.visibilityState === \"hidden\") end();\n },\n };\n\n let installed = false;\n const install = () => {\n if (installed || !view) return;\n installed = true;\n for (const [type, listener] of Object.entries(listeners))\n (type === \"visibilitychange\" ? doc : view).addEventListener(type, listener, { capture: true });\n };\n\n return {\n session,\n frame,\n addRegion: (entry) => {\n install();\n regions.add(entry);\n return () => {\n regions.delete(entry);\n const current = session();\n if (current?.hover?.entry === entry) {\n mark(null);\n setSession({ ...current, hover: null });\n }\n };\n },\n setTarget: (element, entry) => {\n install();\n targets.set(element, entry);\n },\n };\n};\n\n/**\n * The document an element lives in. A freshly rendered element still belongs to the inert document of the template it\n * was cloned from; until it is inserted, that is the page's document.\n */\nexport const liveDocument = (element: Element): Document => (element.ownerDocument.defaultView ? element.ownerDocument : document);\n\n/** The one drag tracker of a document, shared by every drop target in it. */\nexport const fileDropEngine = (doc: Document): FileDropEngine => {\n let engine = engines.get(doc);\n if (!engine) {\n engine = createEngine(doc);\n engines.set(doc, engine);\n }\n return engine;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -6,6 +6,7 @@ export { ColorInput, PinInput, Slider } from "./ChoiceInputs";
6
6
  export { Combobox } from "./Combobox";
7
7
  export { abbreviations } from "./completion";
8
8
  export { DatePicker, DateRangePicker, DateTimePicker } from "./DatePicker";
9
+ export { FileDropTarget, fileDropTarget } from "./FileDropTarget";
9
10
  export { FileDropzone, ImageCropper, ImageInput } from "./FileInputs";
10
11
  export { DEFAULT_ICON_GROUPS, DEFAULT_ICON_OPTIONS } from "./icon-options";
11
12
  export { clampImageCropRect, createCroppedImageCanvas, createCroppedImageDataUrl, getInitialImageCropRect, imageCropRectToPixels, normalizeImageCropRotation, resizeImageCropAroundCenter, rotateImageCropRight } from "./image-crop";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["inputs/index.ts"],"sourcesContent":["export type { AutocompleteEditorProps } from \"./AutocompleteEditor\";\nexport { AutocompleteEditor } from \"./AutocompleteEditor\";\nexport type {\n AutocompleteSelectOption,\n AutocompleteSelectProps,\n AutocompleteSelectSearchResult,\n} from \"./AutocompleteSelect\";\nexport { AutocompleteSelect } from \"./AutocompleteSelect\";\nexport type { CheckboxProps } from \"./Checkbox\";\nexport { Checkbox } from \"./Checkbox\";\nexport type { CheckboxCardProps } from \"./CheckboxCard\";\nexport { CheckboxCard } from \"./CheckboxCard\";\nexport type {\n ColorInputProps,\n PinInputProps,\n SliderProps,\n} from \"./ChoiceInputs\";\nexport { ColorInput, PinInput, Slider } from \"./ChoiceInputs\";\nexport type { ComboboxOption, ComboboxProps } from \"./Combobox\";\nexport { Combobox } from \"./Combobox\";\nexport type { ChoiceOption, ChoiceOptionsLoader } from \"./choice\";\nexport type {\n Completion,\n QueryContext,\n SuggestContext,\n Suggestion,\n} from \"./completion\";\nexport { abbreviations } from \"./completion\";\nexport type {\n DatePickerBaseProps,\n DatePickerProps,\n DatePreset,\n DateRangePickerProps,\n DateRangeValue,\n DateTimePickerProps,\n DurationPreset,\n} from \"./DatePicker\";\nexport { DatePicker, DateRangePicker, DateTimePicker } from \"./DatePicker\";\nexport type { FileDropzoneProps, ImageCropperProps, ImageInputProps } from \"./FileInputs\";\nexport { FileDropzone, ImageCropper, ImageInput } from \"./FileInputs\";\nexport type { DateContext, FieldProps, MaybeAccessor, ValueFieldProps } from \"./field-contract\";\nexport { DEFAULT_ICON_GROUPS, DEFAULT_ICON_OPTIONS } from \"./icon-options\";\nexport type {\n ImageCropAspect,\n ImageCropOutput,\n ImageCropRect,\n ImageCropRotation,\n ImageCropSize,\n ImageCropSource,\n ImageCropState,\n} from \"./image-crop\";\nexport {\n clampImageCropRect,\n createCroppedImageCanvas,\n createCroppedImageDataUrl,\n getInitialImageCropRect,\n imageCropRectToPixels,\n normalizeImageCropRotation,\n resizeImageCropAroundCenter,\n rotateImageCropRight,\n} from \"./image-crop\";\nexport type {\n MultiSelectFetchDataFn,\n MultiSelectInputProps,\n MultiSelectOption,\n} from \"./MultiSelectInput\";\nexport { MultiSelectInput } from \"./MultiSelectInput\";\nexport type { MarkdownEditorProps } from \"./markdown/MarkdownEditor\";\nexport { MarkdownEditor } from \"./markdown/MarkdownEditor\";\nexport type { NumberInputProps } from \"./NumberInput\";\nexport { NumberInput } from \"./NumberInput\";\nexport type { QrScannerError, QrScannerProps } from \"./QrScanner\";\nexport { QrScanner } from \"./QrScanner\";\nexport type { ChoiceAppearance, SelectGridSize, SelectGroup, SelectOption, SelectProps, SelectSourceOption, SelectView } from \"./Select\";\nexport { Select } from \"./Select\";\nexport type { SelectChipOption, SelectChipProps } from \"./SelectChip\";\nexport { SelectChip } from \"./SelectChip\";\nexport type { IconInputProps, IconOption } from \"./SpecialInputs\";\nexport { IconInput } from \"./SpecialInputs\";\nexport type { SwitchProps } from \"./Switch\";\nexport { Switch } from \"./Switch\";\nexport type { TagEditorItem, TagEditorLabels, TagEditorProps, TagEditorValue } from \"./TagEditor\";\nexport { TagEditor } from \"./TagEditor\";\nexport type { TagsInputProps } from \"./TagsInput\";\nexport { TagsInput } from \"./TagsInput\";\nexport type {\n TemplateEditorLayout,\n TemplateEditorProps,\n TemplatePreviewProps,\n TemplateSampleDataProps,\n TemplateVariable,\n TemplateVariableKind,\n} from \"./TemplateEditor\";\nexport {\n createTemplateEditorPanesLayout,\n TemplateEditor,\n TemplatePreview,\n TemplateSampleData,\n} from \"./TemplateEditor\";\nexport type { TextInputProps } from \"./TextInput\";\nexport { TextInput } from \"./TextInput\";\n"],"mappings":"AACA,SAAS,kBAAkB,QAAQ,sBAAsB;AAMzD,SAAS,kBAAkB,QAAQ,sBAAsB;AAEzD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,YAAY,QAAQ,gBAAgB;AAM7C,SAAS,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,gBAAgB;AAE7D,SAAS,QAAQ,QAAQ,YAAY;AAQrC,SAAS,aAAa,QAAQ,cAAc;AAU5C,SAAS,UAAU,EAAE,eAAe,EAAE,cAAc,QAAQ,cAAc;AAE1E,SAAS,YAAY,EAAE,YAAY,EAAE,UAAU,QAAQ,cAAc;AAErE,SAAS,mBAAmB,EAAE,oBAAoB,QAAQ,gBAAgB;AAU1E,SACE,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,QACf,cAAc;AAMrB,SAAS,gBAAgB,QAAQ,oBAAoB;AAErD,SAAS,cAAc,QAAQ,2BAA2B;AAE1D,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,SAAS,QAAQ,aAAa;AAEvC,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,UAAU,QAAQ,cAAc;AAEzC,SAAS,SAAS,QAAQ,iBAAiB;AAE3C,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,SAAS,QAAQ,aAAa;AAEvC,SAAS,SAAS,QAAQ,aAAa;AASvC,SACE,+BAA+B,EAC/B,cAAc,EACd,eAAe,EACf,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,SAAS,QAAQ,aAAa","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["inputs/index.ts"],"sourcesContent":["export type { AutocompleteEditorProps } from \"./AutocompleteEditor\";\nexport { AutocompleteEditor } from \"./AutocompleteEditor\";\nexport type {\n AutocompleteSelectOption,\n AutocompleteSelectProps,\n AutocompleteSelectSearchResult,\n} from \"./AutocompleteSelect\";\nexport { AutocompleteSelect } from \"./AutocompleteSelect\";\nexport type { CheckboxProps } from \"./Checkbox\";\nexport { Checkbox } from \"./Checkbox\";\nexport type { CheckboxCardProps } from \"./CheckboxCard\";\nexport { CheckboxCard } from \"./CheckboxCard\";\nexport type {\n ColorInputProps,\n PinInputProps,\n SliderProps,\n} from \"./ChoiceInputs\";\nexport { ColorInput, PinInput, Slider } from \"./ChoiceInputs\";\nexport type { ComboboxOption, ComboboxProps } from \"./Combobox\";\nexport { Combobox } from \"./Combobox\";\nexport type { ChoiceOption, ChoiceOptionsLoader } from \"./choice\";\nexport type {\n Completion,\n QueryContext,\n SuggestContext,\n Suggestion,\n} from \"./completion\";\nexport { abbreviations } from \"./completion\";\nexport type {\n DatePickerBaseProps,\n DatePickerProps,\n DatePreset,\n DateRangePickerProps,\n DateRangeValue,\n DateTimePickerProps,\n DurationPreset,\n} from \"./DatePicker\";\nexport { DatePicker, DateRangePicker, DateTimePicker } from \"./DatePicker\";\nexport type { FileDropDetails, FileDropOptions, FileDropRejection, FileDropTargetProps } from \"./FileDropTarget\";\nexport { FileDropTarget, fileDropTarget } from \"./FileDropTarget\";\nexport type { FileDropzoneProps, ImageCropperProps, ImageInputProps } from \"./FileInputs\";\nexport { FileDropzone, ImageCropper, ImageInput } from \"./FileInputs\";\nexport type { DateContext, FieldProps, MaybeAccessor, ValueFieldProps } from \"./field-contract\";\nexport { DEFAULT_ICON_GROUPS, DEFAULT_ICON_OPTIONS } from \"./icon-options\";\nexport type {\n ImageCropAspect,\n ImageCropOutput,\n ImageCropRect,\n ImageCropRotation,\n ImageCropSize,\n ImageCropSource,\n ImageCropState,\n} from \"./image-crop\";\nexport {\n clampImageCropRect,\n createCroppedImageCanvas,\n createCroppedImageDataUrl,\n getInitialImageCropRect,\n imageCropRectToPixels,\n normalizeImageCropRotation,\n resizeImageCropAroundCenter,\n rotateImageCropRight,\n} from \"./image-crop\";\nexport type {\n MultiSelectFetchDataFn,\n MultiSelectInputProps,\n MultiSelectOption,\n} from \"./MultiSelectInput\";\nexport { MultiSelectInput } from \"./MultiSelectInput\";\nexport type { MarkdownEditorProps } from \"./markdown/MarkdownEditor\";\nexport { MarkdownEditor } from \"./markdown/MarkdownEditor\";\nexport type { NumberInputProps } from \"./NumberInput\";\nexport { NumberInput } from \"./NumberInput\";\nexport type { QrScannerError, QrScannerProps } from \"./QrScanner\";\nexport { QrScanner } from \"./QrScanner\";\nexport type { ChoiceAppearance, SelectGridSize, SelectGroup, SelectOption, SelectProps, SelectSourceOption, SelectView } from \"./Select\";\nexport { Select } from \"./Select\";\nexport type { SelectChipOption, SelectChipProps } from \"./SelectChip\";\nexport { SelectChip } from \"./SelectChip\";\nexport type { IconInputProps, IconOption } from \"./SpecialInputs\";\nexport { IconInput } from \"./SpecialInputs\";\nexport type { SwitchProps } from \"./Switch\";\nexport { Switch } from \"./Switch\";\nexport type { TagEditorItem, TagEditorLabels, TagEditorProps, TagEditorValue } from \"./TagEditor\";\nexport { TagEditor } from \"./TagEditor\";\nexport type { TagsInputProps } from \"./TagsInput\";\nexport { TagsInput } from \"./TagsInput\";\nexport type {\n TemplateEditorLayout,\n TemplateEditorProps,\n TemplatePreviewProps,\n TemplateSampleDataProps,\n TemplateVariable,\n TemplateVariableKind,\n} from \"./TemplateEditor\";\nexport {\n createTemplateEditorPanesLayout,\n TemplateEditor,\n TemplatePreview,\n TemplateSampleData,\n} from \"./TemplateEditor\";\nexport type { TextInputProps } from \"./TextInput\";\nexport { TextInput } from \"./TextInput\";\n"],"mappings":"AACA,SAAS,kBAAkB,QAAQ,sBAAsB;AAMzD,SAAS,kBAAkB,QAAQ,sBAAsB;AAEzD,SAAS,QAAQ,QAAQ,YAAY;AAErC,SAAS,YAAY,QAAQ,gBAAgB;AAM7C,SAAS,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,gBAAgB;AAE7D,SAAS,QAAQ,QAAQ,YAAY;AAQrC,SAAS,aAAa,QAAQ,cAAc;AAU5C,SAAS,UAAU,EAAE,eAAe,EAAE,cAAc,QAAQ,cAAc;AAE1E,SAAS,cAAc,EAAE,cAAc,QAAQ,kBAAkB;AAEjE,SAAS,YAAY,EAAE,YAAY,EAAE,UAAU,QAAQ,cAAc;AAErE,SAAS,mBAAmB,EAAE,oBAAoB,QAAQ,gBAAgB;AAU1E,SACE,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,QACf,cAAc;AAMrB,SAAS,gBAAgB,QAAQ,oBAAoB;AAErD,SAAS,cAAc,QAAQ,2BAA2B;AAE1D,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,SAAS,QAAQ,aAAa;AAEvC,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,UAAU,QAAQ,cAAc;AAEzC,SAAS,SAAS,QAAQ,iBAAiB;AAE3C,SAAS,MAAM,QAAQ,UAAU;AAEjC,SAAS,SAAS,QAAQ,aAAa;AAEvC,SAAS,SAAS,QAAQ,aAAa;AASvC,SACE,+BAA+B,EAC/B,cAAc,EACd,eAAe,EACf,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,SAAS,QAAQ,aAAa","ignoreList":[]}