@ctrl-ui/react 0.8.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.
- package/README.md +70 -0
- package/dist/action-bar.d.ts +44 -0
- package/dist/action-bar.js +89 -0
- package/dist/activity.d.ts +53 -0
- package/dist/activity.js +188 -0
- package/dist/audio-recorder.d.ts +32 -0
- package/dist/audio-recorder.js +235 -0
- package/dist/audio-visualizer.d.ts +12 -0
- package/dist/audio-visualizer.js +58 -0
- package/dist/blocks/chat.d.ts +10 -0
- package/dist/blocks/chat.js +12 -0
- package/dist/blocks/coding-agent.d.ts +61 -0
- package/dist/blocks/coding-agent.js +255 -0
- package/dist/blocks/file-explorer-data.d.ts +57 -0
- package/dist/blocks/file-explorer-data.js +74 -0
- package/dist/blocks/file-explorer.d.ts +24 -0
- package/dist/blocks/file-explorer.js +427 -0
- package/dist/blocks/settings-data.d.ts +36 -0
- package/dist/blocks/settings-data.js +66 -0
- package/dist/blocks/settings.d.ts +19 -0
- package/dist/blocks/settings.js +282 -0
- package/dist/blocks/theme-toggle.d.ts +43 -0
- package/dist/blocks/theme-toggle.js +180 -0
- package/dist/chat-composer-attachment.d.ts +55 -0
- package/dist/chat-composer-attachment.js +267 -0
- package/dist/chat-composer-editor/extensions/mention.d.ts +14 -0
- package/dist/chat-composer-editor/extensions/mention.js +278 -0
- package/dist/chat-composer-editor/ghost.d.ts +5 -0
- package/dist/chat-composer-editor/ghost.js +55 -0
- package/dist/chat-composer-editor/schema.d.ts +6 -0
- package/dist/chat-composer-editor/schema.js +25 -0
- package/dist/chat-composer-editor/serialize.d.ts +6 -0
- package/dist/chat-composer-editor/serialize.js +16 -0
- package/dist/chat-composer-editor/types.d.ts +29 -0
- package/dist/chat-composer-editor/types.js +0 -0
- package/dist/chat-composer-editor.d.ts +9 -0
- package/dist/chat-composer-editor.js +154 -0
- package/dist/chat-composer.d.ts +60 -0
- package/dist/chat-composer.js +134 -0
- package/dist/chat-layout.d.ts +27 -0
- package/dist/chat-layout.js +114 -0
- package/dist/chat-message.d.ts +31 -0
- package/dist/chat-message.js +95 -0
- package/dist/code-block-editor.d.ts +59 -0
- package/dist/code-block-editor.js +250 -0
- package/dist/context-model.d.ts +33 -0
- package/dist/context-model.js +52 -0
- package/dist/context.d.ts +47 -0
- package/dist/context.js +335 -0
- package/dist/control-props.d.ts +28 -0
- package/dist/control-props.js +4 -0
- package/dist/control-variants.d.ts +8 -0
- package/dist/control-variants.js +14 -0
- package/dist/dynamic-notification-glass.d.ts +10 -0
- package/dist/dynamic-notification-glass.js +311 -0
- package/dist/dynamic-notification-liquid.d.ts +24 -0
- package/dist/dynamic-notification-liquid.js +682 -0
- package/dist/dynamic-notification-siri-wave.d.ts +4 -0
- package/dist/dynamic-notification-siri-wave.js +82 -0
- package/dist/dynamic-notification.d.ts +74 -0
- package/dist/dynamic-notification.js +342 -0
- package/dist/environment-variables.d.ts +124 -0
- package/dist/environment-variables.js +492 -0
- package/dist/extensions/create-track-highlight.d.ts +12 -0
- package/dist/extensions/create-track-highlight.js +147 -0
- package/dist/extensions/track-highlight.d.ts +22 -0
- package/dist/extensions/track-highlight.js +52 -0
- package/dist/hooks/use-audio-recorder.d.ts +107 -0
- package/dist/hooks/use-audio-recorder.js +577 -0
- package/dist/hooks/use-chat-composer.d.ts +56 -0
- package/dist/hooks/use-chat-composer.js +63 -0
- package/dist/hooks/use-chat-message.d.ts +28 -0
- package/dist/hooks/use-chat-message.js +24 -0
- package/dist/hooks/use-color-area.d.ts +18 -0
- package/dist/hooks/use-color-area.js +60 -0
- package/dist/hooks/use-copy-to-clipboard.d.ts +22 -0
- package/dist/hooks/use-copy-to-clipboard.js +90 -0
- package/dist/hooks/use-dropzone.d.ts +59 -0
- package/dist/hooks/use-dropzone.js +372 -0
- package/dist/hooks/use-dynamic-notification.d.ts +37 -0
- package/dist/hooks/use-dynamic-notification.js +87 -0
- package/dist/hooks/use-environment-variables.d.ts +51 -0
- package/dist/hooks/use-environment-variables.js +188 -0
- package/dist/hooks/use-mobile.d.ts +5 -0
- package/dist/hooks/use-mobile.js +29 -0
- package/dist/hooks/use-textarea-trigger-menu.d.ts +8 -0
- package/dist/hooks/use-textarea-trigger-menu.js +69 -0
- package/dist/hooks/use-trigger-menu.d.ts +49 -0
- package/dist/hooks/use-trigger-menu.js +102 -0
- package/dist/hooks/use-user-ask.d.ts +48 -0
- package/dist/hooks/use-user-ask.js +167 -0
- package/dist/inline-attachment.d.ts +37 -0
- package/dist/inline-attachment.js +192 -0
- package/dist/inline-citation.d.ts +56 -0
- package/dist/inline-citation.js +319 -0
- package/dist/knob-contracts/accordion-knobs.d.ts +5 -0
- package/dist/knob-contracts/accordion-knobs.js +9 -0
- package/dist/knob-contracts/action-bar-knobs.d.ts +5 -0
- package/dist/knob-contracts/action-bar-knobs.js +4 -0
- package/dist/knob-contracts/activity-knobs.d.ts +5 -0
- package/dist/knob-contracts/activity-knobs.js +9 -0
- package/dist/knob-contracts/alert-knobs.d.ts +5 -0
- package/dist/knob-contracts/alert-knobs.js +9 -0
- package/dist/knob-contracts/audio-recorder-knobs.d.ts +5 -0
- package/dist/knob-contracts/audio-recorder-knobs.js +9 -0
- package/dist/knob-contracts/audio-visualizer-knobs.d.ts +5 -0
- package/dist/knob-contracts/audio-visualizer-knobs.js +9 -0
- package/dist/knob-contracts/avatar-knobs.d.ts +5 -0
- package/dist/knob-contracts/avatar-knobs.js +9 -0
- package/dist/knob-contracts/badge-knobs.d.ts +5 -0
- package/dist/knob-contracts/badge-knobs.js +9 -0
- package/dist/knob-contracts/button-group-knobs.d.ts +5 -0
- package/dist/knob-contracts/button-group-knobs.js +9 -0
- package/dist/knob-contracts/button-knobs.d.ts +5 -0
- package/dist/knob-contracts/button-knobs.js +25 -0
- package/dist/knob-contracts/calendar-knobs.d.ts +5 -0
- package/dist/knob-contracts/calendar-knobs.js +10 -0
- package/dist/knob-contracts/card-knobs.d.ts +5 -0
- package/dist/knob-contracts/card-knobs.js +11 -0
- package/dist/knob-contracts/chat-composer-attachment-knobs.d.ts +5 -0
- package/dist/knob-contracts/chat-composer-attachment-knobs.js +11 -0
- package/dist/knob-contracts/chat-composer-knobs.d.ts +5 -0
- package/dist/knob-contracts/chat-composer-knobs.js +18 -0
- package/dist/knob-contracts/chat-layout-knobs.d.ts +5 -0
- package/dist/knob-contracts/chat-layout-knobs.js +11 -0
- package/dist/knob-contracts/chat-message-knobs.d.ts +5 -0
- package/dist/knob-contracts/chat-message-knobs.js +17 -0
- package/dist/knob-contracts/choice-knobs.d.ts +5 -0
- package/dist/knob-contracts/choice-knobs.js +9 -0
- package/dist/knob-contracts/code-block-editor-knobs.d.ts +5 -0
- package/dist/knob-contracts/code-block-editor-knobs.js +11 -0
- package/dist/knob-contracts/code-diff-knobs.d.ts +5 -0
- package/dist/knob-contracts/code-diff-knobs.js +18 -0
- package/dist/knob-contracts/code-knobs.d.ts +5 -0
- package/dist/knob-contracts/code-knobs.js +11 -0
- package/dist/knob-contracts/collapsible-knobs.d.ts +5 -0
- package/dist/knob-contracts/collapsible-knobs.js +4 -0
- package/dist/knob-contracts/color-picker-knobs.d.ts +5 -0
- package/dist/knob-contracts/color-picker-knobs.js +12 -0
- package/dist/knob-contracts/context-knobs.d.ts +5 -0
- package/dist/knob-contracts/context-knobs.js +13 -0
- package/dist/knob-contracts/dockable-panel-knobs.d.ts +5 -0
- package/dist/knob-contracts/dockable-panel-knobs.js +12 -0
- package/dist/knob-contracts/dropzone-knobs.d.ts +5 -0
- package/dist/knob-contracts/dropzone-knobs.js +11 -0
- package/dist/knob-contracts/dynamic-notification-knobs.d.ts +5 -0
- package/dist/knob-contracts/dynamic-notification-knobs.js +18 -0
- package/dist/knob-contracts/empty-knobs.d.ts +5 -0
- package/dist/knob-contracts/empty-knobs.js +12 -0
- package/dist/knob-contracts/environment-variables-knobs.d.ts +5 -0
- package/dist/knob-contracts/environment-variables-knobs.js +11 -0
- package/dist/knob-contracts/field-knobs.d.ts +5 -0
- package/dist/knob-contracts/field-knobs.js +16 -0
- package/dist/knob-contracts/gradient-editor-knobs.d.ts +5 -0
- package/dist/knob-contracts/gradient-editor-knobs.js +13 -0
- package/dist/knob-contracts/infinite-canvas-knobs.d.ts +5 -0
- package/dist/knob-contracts/infinite-canvas-knobs.js +13 -0
- package/dist/knob-contracts/inline-attachment-knobs.d.ts +5 -0
- package/dist/knob-contracts/inline-attachment-knobs.js +14 -0
- package/dist/knob-contracts/inline-citation-knobs.d.ts +5 -0
- package/dist/knob-contracts/inline-citation-knobs.js +14 -0
- package/dist/knob-contracts/item-knobs.d.ts +5 -0
- package/dist/knob-contracts/item-knobs.js +10 -0
- package/dist/knob-contracts/kbd-knobs.d.ts +5 -0
- package/dist/knob-contracts/kbd-knobs.js +10 -0
- package/dist/knob-contracts/markdown-block-knobs.d.ts +5 -0
- package/dist/knob-contracts/markdown-block-knobs.js +11 -0
- package/dist/knob-contracts/markdown-knobs.d.ts +5 -0
- package/dist/knob-contracts/markdown-knobs.js +14 -0
- package/dist/knob-contracts/morphing-panel-knobs.d.ts +5 -0
- package/dist/knob-contracts/morphing-panel-knobs.js +11 -0
- package/dist/knob-contracts/pagination-knobs.d.ts +5 -0
- package/dist/knob-contracts/pagination-knobs.js +10 -0
- package/dist/knob-contracts/phone-input-knobs.d.ts +5 -0
- package/dist/knob-contracts/phone-input-knobs.js +10 -0
- package/dist/knob-contracts/popup-knobs.d.ts +5 -0
- package/dist/knob-contracts/popup-knobs.js +21 -0
- package/dist/knob-contracts/range-knobs.d.ts +5 -0
- package/dist/knob-contracts/range-knobs.js +13 -0
- package/dist/knob-contracts/resizable-knobs.d.ts +5 -0
- package/dist/knob-contracts/resizable-knobs.js +14 -0
- package/dist/knob-contracts/rich-tooltip-knobs.d.ts +5 -0
- package/dist/knob-contracts/rich-tooltip-knobs.js +13 -0
- package/dist/knob-contracts/scroll-area-knobs.d.ts +5 -0
- package/dist/knob-contracts/scroll-area-knobs.js +8 -0
- package/dist/knob-contracts/separator-knobs.d.ts +5 -0
- package/dist/knob-contracts/separator-knobs.js +4 -0
- package/dist/knob-contracts/sidebar-knobs.d.ts +5 -0
- package/dist/knob-contracts/sidebar-knobs.js +26 -0
- package/dist/knob-contracts/skeleton-knobs.d.ts +5 -0
- package/dist/knob-contracts/skeleton-knobs.js +4 -0
- package/dist/knob-contracts/source-badge-knobs.d.ts +5 -0
- package/dist/knob-contracts/source-badge-knobs.js +11 -0
- package/dist/knob-contracts/spinner-knobs.d.ts +5 -0
- package/dist/knob-contracts/spinner-knobs.js +4 -0
- package/dist/knob-contracts/stepper-knobs.d.ts +5 -0
- package/dist/knob-contracts/stepper-knobs.js +11 -0
- package/dist/knob-contracts/switch-knobs.d.ts +5 -0
- package/dist/knob-contracts/switch-knobs.js +12 -0
- package/dist/knob-contracts/table-knobs.d.ts +5 -0
- package/dist/knob-contracts/table-knobs.js +12 -0
- package/dist/knob-contracts/table-of-contents-knobs.d.ts +5 -0
- package/dist/knob-contracts/table-of-contents-knobs.js +8 -0
- package/dist/knob-contracts/tabs-knobs.d.ts +5 -0
- package/dist/knob-contracts/tabs-knobs.js +16 -0
- package/dist/knob-contracts/task-list-knobs.d.ts +5 -0
- package/dist/knob-contracts/task-list-knobs.js +14 -0
- package/dist/knob-contracts/thread-rail-knobs.d.ts +5 -0
- package/dist/knob-contracts/thread-rail-knobs.js +14 -0
- package/dist/knob-contracts/timeline-knobs.d.ts +5 -0
- package/dist/knob-contracts/timeline-knobs.js +12 -0
- package/dist/knob-contracts/toolbar-knobs.d.ts +5 -0
- package/dist/knob-contracts/toolbar-knobs.js +20 -0
- package/dist/knob-contracts/track-highlight-knobs.d.ts +5 -0
- package/dist/knob-contracts/track-highlight-knobs.js +11 -0
- package/dist/knob-contracts/transcript-divider-knobs.d.ts +5 -0
- package/dist/knob-contracts/transcript-divider-knobs.js +10 -0
- package/dist/knob-contracts/tree-knobs.d.ts +5 -0
- package/dist/knob-contracts/tree-knobs.js +13 -0
- package/dist/knob-contracts/user-ask-knobs.d.ts +5 -0
- package/dist/knob-contracts/user-ask-knobs.js +17 -0
- package/dist/lib/cn.d.ts +5 -0
- package/dist/lib/cn.js +34 -0
- package/dist/lib/code-block-shiki.d.ts +9 -0
- package/dist/lib/code-block-shiki.js +6 -0
- package/dist/lib/code-tokens.d.ts +28 -0
- package/dist/lib/code-tokens.js +160 -0
- package/dist/lib/color.d.ts +72 -0
- package/dist/lib/color.js +490 -0
- package/dist/lib/contrast.d.ts +30 -0
- package/dist/lib/contrast.js +64 -0
- package/dist/lib/diff.d.ts +50 -0
- package/dist/lib/diff.js +315 -0
- package/dist/lib/dropzone-validation.d.ts +66 -0
- package/dist/lib/dropzone-validation.js +228 -0
- package/dist/lib/env-file.d.ts +28 -0
- package/dist/lib/env-file.js +218 -0
- package/dist/lib/format-audio-recorder-duration.d.ts +4 -0
- package/dist/lib/format-audio-recorder-duration.js +7 -0
- package/dist/lib/liquid-glass-optics.d.ts +4 -0
- package/dist/lib/liquid-glass-optics.js +96 -0
- package/dist/lib/phone-input-format.d.ts +6 -0
- package/dist/lib/phone-input-format.js +26 -0
- package/dist/lib/phone-number.d.ts +18 -0
- package/dist/lib/phone-number.js +28 -0
- package/dist/lib/trigger-detect.d.ts +15 -0
- package/dist/lib/trigger-detect.js +77 -0
- package/dist/markdown-block.d.ts +25 -0
- package/dist/markdown-block.js +77 -0
- package/dist/skin.config.d.ts +5 -0
- package/dist/skin.config.js +4 -0
- package/dist/skin.d.ts +69 -0
- package/dist/skin.js +62 -0
- package/dist/source-badge.d.ts +23 -0
- package/dist/source-badge.js +72 -0
- package/dist/styles/chat-composer-editor.css +44 -0
- package/dist/styles/code.css +57 -0
- package/dist/styles/effects.css +126 -0
- package/dist/styles/index.css +81 -0
- package/dist/styles/recipes/accordion.css +87 -0
- package/dist/styles/recipes/action-bar.css +19 -0
- package/dist/styles/recipes/activity.css +129 -0
- package/dist/styles/recipes/alert.css +75 -0
- package/dist/styles/recipes/audio-recorder.css +102 -0
- package/dist/styles/recipes/audio-visualizer.css +90 -0
- package/dist/styles/recipes/avatar.css +52 -0
- package/dist/styles/recipes/badge.css +110 -0
- package/dist/styles/recipes/button-group.css +64 -0
- package/dist/styles/recipes/button.css +305 -0
- package/dist/styles/recipes/calendar.css +152 -0
- package/dist/styles/recipes/card.css +93 -0
- package/dist/styles/recipes/chat-composer-attachment.css +177 -0
- package/dist/styles/recipes/chat-composer.css +195 -0
- package/dist/styles/recipes/chat-layout.css +108 -0
- package/dist/styles/recipes/chat-message.css +160 -0
- package/dist/styles/recipes/choice.css +108 -0
- package/dist/styles/recipes/code-block-editor.css +136 -0
- package/dist/styles/recipes/code-diff.css +256 -0
- package/dist/styles/recipes/code.css +136 -0
- package/dist/styles/recipes/collapsible.css +27 -0
- package/dist/styles/recipes/color-picker-details.css +61 -0
- package/dist/styles/recipes/color-picker-values.css +117 -0
- package/dist/styles/recipes/color-picker.css +158 -0
- package/dist/styles/recipes/context.css +237 -0
- package/dist/styles/recipes/dockable-panel.css +106 -0
- package/dist/styles/recipes/dropzone.css +149 -0
- package/dist/styles/recipes/dynamic-notification-input.css +29 -0
- package/dist/styles/recipes/dynamic-notification-motion.css +298 -0
- package/dist/styles/recipes/dynamic-notification.css +241 -0
- package/dist/styles/recipes/empty.css +96 -0
- package/dist/styles/recipes/environment-variables.css +173 -0
- package/dist/styles/recipes/field-parts.css +148 -0
- package/dist/styles/recipes/field.css +234 -0
- package/dist/styles/recipes/gradient-editor.css +109 -0
- package/dist/styles/recipes/infinite-canvas.css +78 -0
- package/dist/styles/recipes/inline-attachment.css +182 -0
- package/dist/styles/recipes/inline-citation.css +174 -0
- package/dist/styles/recipes/item.css +107 -0
- package/dist/styles/recipes/kbd.css +55 -0
- package/dist/styles/recipes/markdown-block.css +75 -0
- package/dist/styles/recipes/markdown.css +204 -0
- package/dist/styles/recipes/morphing-panel.css +123 -0
- package/dist/styles/recipes/pagination.css +86 -0
- package/dist/styles/recipes/phone-input.css +105 -0
- package/dist/styles/recipes/popup-controls.css +59 -0
- package/dist/styles/recipes/popup-drawer.css +162 -0
- package/dist/styles/recipes/popup-lists.css +198 -0
- package/dist/styles/recipes/popup-motion.css +94 -0
- package/dist/styles/recipes/popup-toast.css +126 -0
- package/dist/styles/recipes/popup.css +396 -0
- package/dist/styles/recipes/range.css +259 -0
- package/dist/styles/recipes/resizable.css +170 -0
- package/dist/styles/recipes/rich-tooltip.css +272 -0
- package/dist/styles/recipes/scroll-area.css +59 -0
- package/dist/styles/recipes/separator.css +12 -0
- package/dist/styles/recipes/sidebar.css +345 -0
- package/dist/styles/recipes/skeleton.css +23 -0
- package/dist/styles/recipes/source-badge.css +77 -0
- package/dist/styles/recipes/spinner.css +33 -0
- package/dist/styles/recipes/stepper.css +178 -0
- package/dist/styles/recipes/switch.css +149 -0
- package/dist/styles/recipes/table-of-contents.css +107 -0
- package/dist/styles/recipes/table.css +124 -0
- package/dist/styles/recipes/tabs.css +235 -0
- package/dist/styles/recipes/task-list.css +146 -0
- package/dist/styles/recipes/thread-rail.css +247 -0
- package/dist/styles/recipes/timeline.css +107 -0
- package/dist/styles/recipes/toolbar.css +260 -0
- package/dist/styles/recipes/track-highlight.css +73 -0
- package/dist/styles/recipes/transcript-divider.css +64 -0
- package/dist/styles/recipes/tree.css +137 -0
- package/dist/styles/recipes/user-ask-details.css +45 -0
- package/dist/styles/recipes/user-ask.css +204 -0
- package/dist/styles/skin-theme.css +137 -0
- package/dist/styles/skin.css +143 -0
- package/dist/styles/theme.css +628 -0
- package/dist/styles/type-scale.css +45 -0
- package/dist/surface-variants.d.ts +6 -0
- package/dist/surface-variants.js +16 -0
- package/dist/task-list.d.ts +34 -0
- package/dist/task-list.js +177 -0
- package/dist/thread-rail.d.ts +52 -0
- package/dist/thread-rail.js +190 -0
- package/dist/transcript-divider.d.ts +15 -0
- package/dist/transcript-divider.js +25 -0
- package/dist/ui/accordion.d.ts +31 -0
- package/dist/ui/accordion.js +60 -0
- package/dist/ui/alert-dialog.d.ts +36 -0
- package/dist/ui/alert-dialog.js +100 -0
- package/dist/ui/alert.d.ts +21 -0
- package/dist/ui/alert.js +36 -0
- package/dist/ui/aspect-ratio.d.ts +8 -0
- package/dist/ui/aspect-ratio.js +17 -0
- package/dist/ui/autocomplete.d.ts +70 -0
- package/dist/ui/autocomplete.js +150 -0
- package/dist/ui/avatar.d.ts +24 -0
- package/dist/ui/avatar.js +44 -0
- package/dist/ui/badge.d.ts +20 -0
- package/dist/ui/badge.js +36 -0
- package/dist/ui/button-group.d.ts +24 -0
- package/dist/ui/button-group.js +45 -0
- package/dist/ui/button.d.ts +36 -0
- package/dist/ui/button.js +104 -0
- package/dist/ui/calendar.d.ts +11 -0
- package/dist/ui/calendar.js +160 -0
- package/dist/ui/card.d.ts +36 -0
- package/dist/ui/card.js +70 -0
- package/dist/ui/checkbox-group.d.ts +11 -0
- package/dist/ui/checkbox-group.js +16 -0
- package/dist/ui/checkbox.d.ts +23 -0
- package/dist/ui/checkbox.js +58 -0
- package/dist/ui/code-diff.d.ts +28 -0
- package/dist/ui/code-diff.js +561 -0
- package/dist/ui/code.d.ts +62 -0
- package/dist/ui/code.js +292 -0
- package/dist/ui/collapsible.d.ts +31 -0
- package/dist/ui/collapsible.js +72 -0
- package/dist/ui/color-picker.d.ts +137 -0
- package/dist/ui/color-picker.js +797 -0
- package/dist/ui/combobox-disabled-selection.d.ts +5 -0
- package/dist/ui/combobox-disabled-selection.js +11 -0
- package/dist/ui/combobox.d.ts +70 -0
- package/dist/ui/combobox.js +194 -0
- package/dist/ui/command.d.ts +44 -0
- package/dist/ui/command.js +166 -0
- package/dist/ui/context-menu.d.ts +86 -0
- package/dist/ui/context-menu.js +202 -0
- package/dist/ui/dialog.d.ts +38 -0
- package/dist/ui/dialog.js +124 -0
- package/dist/ui/dockable-panel-geometry.d.ts +18 -0
- package/dist/ui/dockable-panel-geometry.js +17 -0
- package/dist/ui/dockable-panel.d.ts +58 -0
- package/dist/ui/dockable-panel.js +366 -0
- package/dist/ui/drawer.d.ts +42 -0
- package/dist/ui/drawer.js +182 -0
- package/dist/ui/dropdown-menu.d.ts +46 -0
- package/dist/ui/dropdown-menu.js +89 -0
- package/dist/ui/dropzone.d.ts +66 -0
- package/dist/ui/dropzone.js +311 -0
- package/dist/ui/empty.d.ts +28 -0
- package/dist/ui/empty.js +59 -0
- package/dist/ui/field.d.ts +64 -0
- package/dist/ui/field.js +166 -0
- package/dist/ui/form.d.ts +10 -0
- package/dist/ui/form.js +17 -0
- package/dist/ui/gradient-editor.d.ts +47 -0
- package/dist/ui/gradient-editor.js +301 -0
- package/dist/ui/hover-card.d.ts +25 -0
- package/dist/ui/hover-card.js +46 -0
- package/dist/ui/infinite-canvas.d.ts +40 -0
- package/dist/ui/infinite-canvas.js +278 -0
- package/dist/ui/input-group.d.ts +21 -0
- package/dist/ui/input-group.js +44 -0
- package/dist/ui/input-otp.d.ts +38 -0
- package/dist/ui/input-otp.js +45 -0
- package/dist/ui/input.d.ts +12 -0
- package/dist/ui/input.js +18 -0
- package/dist/ui/item.d.ts +46 -0
- package/dist/ui/item.js +110 -0
- package/dist/ui/kbd.d.ts +12 -0
- package/dist/ui/kbd.js +23 -0
- package/dist/ui/markdown-elements.d.ts +52 -0
- package/dist/ui/markdown-elements.js +211 -0
- package/dist/ui/markdown.d.ts +14 -0
- package/dist/ui/markdown.js +31 -0
- package/dist/ui/menubar.d.ts +74 -0
- package/dist/ui/menubar.js +162 -0
- package/dist/ui/meter.d.ts +34 -0
- package/dist/ui/meter.js +57 -0
- package/dist/ui/morphing-panel.d.ts +24 -0
- package/dist/ui/morphing-panel.js +87 -0
- package/dist/ui/native-select.d.ts +12 -0
- package/dist/ui/native-select.js +41 -0
- package/dist/ui/navigation-menu.d.ts +51 -0
- package/dist/ui/navigation-menu.js +135 -0
- package/dist/ui/number-field.d.ts +72 -0
- package/dist/ui/number-field.js +124 -0
- package/dist/ui/pagination.d.ts +26 -0
- package/dist/ui/pagination.js +77 -0
- package/dist/ui/phone-input.d.ts +30 -0
- package/dist/ui/phone-input.js +263 -0
- package/dist/ui/popover.d.ts +34 -0
- package/dist/ui/popover.js +87 -0
- package/dist/ui/progress.d.ts +34 -0
- package/dist/ui/progress.js +57 -0
- package/dist/ui/radio-group.d.ts +29 -0
- package/dist/ui/radio-group.js +37 -0
- package/dist/ui/resizable.d.ts +56 -0
- package/dist/ui/resizable.js +82 -0
- package/dist/ui/responsive-dialog.d.ts +18 -0
- package/dist/ui/responsive-dialog.js +121 -0
- package/dist/ui/rich-tooltip-tour.d.ts +12 -0
- package/dist/ui/rich-tooltip-tour.js +20 -0
- package/dist/ui/rich-tooltip.d.ts +83 -0
- package/dist/ui/rich-tooltip.js +331 -0
- package/dist/ui/scroll-area.d.ts +25 -0
- package/dist/ui/scroll-area.js +93 -0
- package/dist/ui/select.d.ts +44 -0
- package/dist/ui/select.js +124 -0
- package/dist/ui/separator.d.ts +9 -0
- package/dist/ui/separator.js +16 -0
- package/dist/ui/sheet.d.ts +25 -0
- package/dist/ui/sheet.js +76 -0
- package/dist/ui/sidebar.d.ts +88 -0
- package/dist/ui/sidebar.js +362 -0
- package/dist/ui/skeleton.d.ts +8 -0
- package/dist/ui/skeleton.js +13 -0
- package/dist/ui/slider.d.ts +24 -0
- package/dist/ui/slider.js +114 -0
- package/dist/ui/spinner.d.ts +12 -0
- package/dist/ui/spinner.js +26 -0
- package/dist/ui/stepper.d.ts +58 -0
- package/dist/ui/stepper.js +232 -0
- package/dist/ui/switch.d.ts +26 -0
- package/dist/ui/switch.js +71 -0
- package/dist/ui/table-of-contents.d.ts +22 -0
- package/dist/ui/table-of-contents.js +181 -0
- package/dist/ui/table.d.ts +37 -0
- package/dist/ui/table.js +83 -0
- package/dist/ui/tabs.d.ts +36 -0
- package/dist/ui/tabs.js +127 -0
- package/dist/ui/textarea.d.ts +9 -0
- package/dist/ui/textarea.js +16 -0
- package/dist/ui/timeline.d.ts +40 -0
- package/dist/ui/timeline.js +80 -0
- package/dist/ui/toast.d.ts +28 -0
- package/dist/ui/toast.js +132 -0
- package/dist/ui/toggle.d.ts +20 -0
- package/dist/ui/toggle.js +71 -0
- package/dist/ui/toolbar.d.ts +40 -0
- package/dist/ui/toolbar.js +72 -0
- package/dist/ui/tooltip.d.ts +27 -0
- package/dist/ui/tooltip.js +93 -0
- package/dist/ui/tree.d.ts +56 -0
- package/dist/ui/tree.js +438 -0
- package/dist/ui/trigger-menu.d.ts +46 -0
- package/dist/ui/trigger-menu.js +116 -0
- package/dist/user-ask.d.ts +50 -0
- package/dist/user-ask.js +398 -0
- package/package.json +115 -0
package/dist/lib/diff.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { diffChars, diffWordsWithSpace, parsePatch, structuredPatch } from "diff";
|
|
2
|
+
//#region src/lib/diff.ts
|
|
3
|
+
const DEFAULT_CONTEXT = 3;
|
|
4
|
+
const DEFAULT_MAX_LINE_DIFF_LENGTH = 2e3;
|
|
5
|
+
function splitLines(text) {
|
|
6
|
+
if (text.length === 0) return [];
|
|
7
|
+
const lines = text.split("\n");
|
|
8
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
9
|
+
return lines;
|
|
10
|
+
}
|
|
11
|
+
function stripGitPrefix(name) {
|
|
12
|
+
if (name === void 0) return void 0;
|
|
13
|
+
if (name === "/dev/null") return name;
|
|
14
|
+
return name.replace(/^[ab]\//, "");
|
|
15
|
+
}
|
|
16
|
+
function computeWordDiff(oldText, newText, kind, maxLength) {
|
|
17
|
+
if (kind === "none") return [void 0, void 0];
|
|
18
|
+
if (maxLength > 0 && oldText.length + newText.length > maxLength) return [void 0, void 0];
|
|
19
|
+
const changes = kind === "char" ? diffChars(oldText, newText) : diffWordsWithSpace(oldText, newText);
|
|
20
|
+
const oldSegments = [];
|
|
21
|
+
const newSegments = [];
|
|
22
|
+
for (const change of changes) {
|
|
23
|
+
if (change.value.length === 0) continue;
|
|
24
|
+
if (change.added) newSegments.push({
|
|
25
|
+
text: change.value,
|
|
26
|
+
emphasis: true
|
|
27
|
+
});
|
|
28
|
+
else if (change.removed) oldSegments.push({
|
|
29
|
+
text: change.value,
|
|
30
|
+
emphasis: true
|
|
31
|
+
});
|
|
32
|
+
else {
|
|
33
|
+
oldSegments.push({
|
|
34
|
+
text: change.value,
|
|
35
|
+
emphasis: false
|
|
36
|
+
});
|
|
37
|
+
newSegments.push({
|
|
38
|
+
text: change.value,
|
|
39
|
+
emphasis: false
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return [oldSegments, newSegments];
|
|
44
|
+
}
|
|
45
|
+
function diffRunEnd(lines, start, type) {
|
|
46
|
+
let end = start;
|
|
47
|
+
while (lines[end]?.type === type) end += 1;
|
|
48
|
+
return end;
|
|
49
|
+
}
|
|
50
|
+
function attachWordDiff(lines, kind, maxLength) {
|
|
51
|
+
if (kind === "none") return;
|
|
52
|
+
let index = 0;
|
|
53
|
+
while (index < lines.length) {
|
|
54
|
+
if (lines[index]?.type !== "del") {
|
|
55
|
+
index += 1;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const delEnd = diffRunEnd(lines, index, "del");
|
|
59
|
+
const addEnd = diffRunEnd(lines, delEnd, "add");
|
|
60
|
+
const pairCount = Math.min(delEnd - index, addEnd - delEnd);
|
|
61
|
+
for (let pair = 0; pair < pairCount; pair += 1) {
|
|
62
|
+
const delLine = lines[index + pair];
|
|
63
|
+
const addLine = lines[delEnd + pair];
|
|
64
|
+
if (!delLine || !addLine) continue;
|
|
65
|
+
const [oldSegments, newSegments] = computeWordDiff(delLine.text, addLine.text, kind, maxLength);
|
|
66
|
+
delLine.segments = oldSegments;
|
|
67
|
+
addLine.segments = newSegments;
|
|
68
|
+
}
|
|
69
|
+
index = addEnd;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function hunkLines(hunk) {
|
|
73
|
+
const lines = [];
|
|
74
|
+
let oldNo = hunk.oldStart;
|
|
75
|
+
let newNo = hunk.newStart;
|
|
76
|
+
for (const raw of hunk.lines) {
|
|
77
|
+
if (raw.length === 0) continue;
|
|
78
|
+
const marker = raw[0];
|
|
79
|
+
const text = raw.slice(1);
|
|
80
|
+
if (marker === "\\") continue;
|
|
81
|
+
if (marker === "-") {
|
|
82
|
+
lines.push({
|
|
83
|
+
type: "del",
|
|
84
|
+
oldNo,
|
|
85
|
+
text
|
|
86
|
+
});
|
|
87
|
+
oldNo += 1;
|
|
88
|
+
} else if (marker === "+") {
|
|
89
|
+
lines.push({
|
|
90
|
+
type: "add",
|
|
91
|
+
newNo,
|
|
92
|
+
text
|
|
93
|
+
});
|
|
94
|
+
newNo += 1;
|
|
95
|
+
} else {
|
|
96
|
+
lines.push({
|
|
97
|
+
type: "context",
|
|
98
|
+
oldNo,
|
|
99
|
+
newNo,
|
|
100
|
+
text
|
|
101
|
+
});
|
|
102
|
+
oldNo += 1;
|
|
103
|
+
newNo += 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return lines;
|
|
107
|
+
}
|
|
108
|
+
function hunkHeaderScope(hunk) {
|
|
109
|
+
const raw = hunkRawHeader.get(hunk);
|
|
110
|
+
if (!raw) return void 0;
|
|
111
|
+
const trimmed = raw.trim();
|
|
112
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
113
|
+
}
|
|
114
|
+
const hunkRawHeader = /* @__PURE__ */ new WeakMap();
|
|
115
|
+
function toDiffFile(patch, options, oldLines, newLines, isPartial) {
|
|
116
|
+
const kind = options.lineDiffType ?? "word";
|
|
117
|
+
const maxLength = options.maxLineDiffLength ?? DEFAULT_MAX_LINE_DIFF_LENGTH;
|
|
118
|
+
const summary = summarizeHunks(patch.hunks, kind, maxLength);
|
|
119
|
+
const oldName = stripGitPrefix(patch.oldFileName);
|
|
120
|
+
const newName = stripGitPrefix(patch.newFileName);
|
|
121
|
+
const name = resolveDiffFileName(options.name, oldName, newName);
|
|
122
|
+
const type = resolveDiffFileType(oldName, newName, oldLines, newLines, isPartial);
|
|
123
|
+
return {
|
|
124
|
+
name,
|
|
125
|
+
oldName: type === "rename" ? oldName : void 0,
|
|
126
|
+
type,
|
|
127
|
+
lang: options.lang,
|
|
128
|
+
hunks: summary.hunks,
|
|
129
|
+
oldLines,
|
|
130
|
+
newLines,
|
|
131
|
+
isPartial,
|
|
132
|
+
additions: summary.additions,
|
|
133
|
+
deletions: summary.deletions
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function countLineChanges(lines) {
|
|
137
|
+
let additions = 0;
|
|
138
|
+
let deletions = 0;
|
|
139
|
+
for (const line of lines) {
|
|
140
|
+
if (line.type === "add") additions += 1;
|
|
141
|
+
if (line.type === "del") deletions += 1;
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
additions,
|
|
145
|
+
deletions
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function summarizeHunks(rawHunks, kind, maxLength) {
|
|
149
|
+
const hunks = [];
|
|
150
|
+
let additions = 0;
|
|
151
|
+
let deletions = 0;
|
|
152
|
+
let previousOldEnd = 0;
|
|
153
|
+
for (const raw of rawHunks) {
|
|
154
|
+
const lines = hunkLines(raw);
|
|
155
|
+
attachWordDiff(lines, kind, maxLength);
|
|
156
|
+
const changes = countLineChanges(lines);
|
|
157
|
+
additions += changes.additions;
|
|
158
|
+
deletions += changes.deletions;
|
|
159
|
+
hunks.push({
|
|
160
|
+
header: hunkHeaderScope(raw),
|
|
161
|
+
oldStart: raw.oldStart,
|
|
162
|
+
oldCount: raw.oldLines,
|
|
163
|
+
newStart: raw.newStart,
|
|
164
|
+
newCount: raw.newLines,
|
|
165
|
+
lines,
|
|
166
|
+
collapsedBefore: Math.max(0, raw.oldStart - 1 - previousOldEnd)
|
|
167
|
+
});
|
|
168
|
+
previousOldEnd = raw.oldStart - 1 + raw.oldLines;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
hunks,
|
|
172
|
+
additions,
|
|
173
|
+
deletions
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function resolveDiffFileName(explicitName, oldName, newName) {
|
|
177
|
+
if (explicitName !== void 0) return explicitName;
|
|
178
|
+
if (newName && newName !== "/dev/null") return newName;
|
|
179
|
+
return oldName ?? "file";
|
|
180
|
+
}
|
|
181
|
+
function resolveDiffFileType(oldName, newName, oldLines, newLines, isPartial) {
|
|
182
|
+
if (oldName === "/dev/null" || !isPartial && oldLines.length === 0 && newLines.length > 0) return "new";
|
|
183
|
+
if (newName === "/dev/null" || !isPartial && newLines.length === 0 && oldLines.length > 0) return "deleted";
|
|
184
|
+
if (oldName !== void 0 && newName !== void 0 && oldName !== newName) return "rename";
|
|
185
|
+
return "change";
|
|
186
|
+
}
|
|
187
|
+
function buildDiffFromFiles(oldText, newText, options = {}) {
|
|
188
|
+
const name = options.name ?? "file";
|
|
189
|
+
const context = options.context ?? DEFAULT_CONTEXT;
|
|
190
|
+
return toDiffFile(structuredPatch(name, name, oldText, newText, "", "", { context }), options, splitLines(oldText), splitLines(newText), false);
|
|
191
|
+
}
|
|
192
|
+
function buildDiffFromPatch(patchText, options = {}) {
|
|
193
|
+
let patches;
|
|
194
|
+
try {
|
|
195
|
+
patches = parsePatch(patchText);
|
|
196
|
+
indexRawHunkHeaders(patchText, patches);
|
|
197
|
+
} catch {
|
|
198
|
+
patches = parsePatchLenient(patchText);
|
|
199
|
+
}
|
|
200
|
+
return patches.map((patch) => toDiffFile(patch, options, [], [], true));
|
|
201
|
+
}
|
|
202
|
+
function emptyStructuredPatch() {
|
|
203
|
+
return {
|
|
204
|
+
oldFileName: void 0,
|
|
205
|
+
newFileName: void 0,
|
|
206
|
+
oldHeader: void 0,
|
|
207
|
+
newHeader: void 0,
|
|
208
|
+
hunks: []
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function patchFileName(rest) {
|
|
212
|
+
return rest.split(" ", 1)[0]?.trim() ?? "";
|
|
213
|
+
}
|
|
214
|
+
function reconcileHunkCounts(hunk) {
|
|
215
|
+
let oldCount = 0;
|
|
216
|
+
let newCount = 0;
|
|
217
|
+
for (const line of hunk.lines) {
|
|
218
|
+
const marker = line[0];
|
|
219
|
+
if (marker === "+") newCount += 1;
|
|
220
|
+
else if (marker === "-") oldCount += 1;
|
|
221
|
+
else if (marker === "\\") continue;
|
|
222
|
+
else {
|
|
223
|
+
oldCount += 1;
|
|
224
|
+
newCount += 1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
hunk.oldLines = oldCount;
|
|
228
|
+
hunk.newLines = newCount;
|
|
229
|
+
}
|
|
230
|
+
function ensureCurrentFile(state) {
|
|
231
|
+
state.current ??= emptyStructuredPatch();
|
|
232
|
+
return state.current;
|
|
233
|
+
}
|
|
234
|
+
function closeLenientHunk(state) {
|
|
235
|
+
if (state.current && state.hunk) {
|
|
236
|
+
reconcileHunkCounts(state.hunk);
|
|
237
|
+
state.current.hunks.push(state.hunk);
|
|
238
|
+
}
|
|
239
|
+
state.hunk = void 0;
|
|
240
|
+
}
|
|
241
|
+
function closeLenientFile(state) {
|
|
242
|
+
closeLenientHunk(state);
|
|
243
|
+
if (state.current) state.files.push(state.current);
|
|
244
|
+
state.current = void 0;
|
|
245
|
+
}
|
|
246
|
+
function lenientHunkHeader(line) {
|
|
247
|
+
const match = line.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@(.*)$/);
|
|
248
|
+
if (!match) return void 0;
|
|
249
|
+
return {
|
|
250
|
+
oldStart: Number(match[1]),
|
|
251
|
+
newStart: Number(match[2]),
|
|
252
|
+
scope: match[3] ?? ""
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function isHunkBodyLine(line) {
|
|
256
|
+
const marker = line[0];
|
|
257
|
+
return marker === " " || marker === "+" || marker === "-" || marker === "\\";
|
|
258
|
+
}
|
|
259
|
+
function consumeLenientPatchLine(state, line) {
|
|
260
|
+
if (line.startsWith("diff --git")) {
|
|
261
|
+
closeLenientFile(state);
|
|
262
|
+
state.current = emptyStructuredPatch();
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (line.startsWith("--- ")) {
|
|
266
|
+
if (state.current) closeLenientHunk(state);
|
|
267
|
+
ensureCurrentFile(state).oldFileName = patchFileName(line.slice(4));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (line.startsWith("+++ ")) {
|
|
271
|
+
ensureCurrentFile(state).newFileName = patchFileName(line.slice(4));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const header = lenientHunkHeader(line);
|
|
275
|
+
if (header) {
|
|
276
|
+
closeLenientHunk(state);
|
|
277
|
+
ensureCurrentFile(state);
|
|
278
|
+
state.hunk = {
|
|
279
|
+
oldStart: header.oldStart,
|
|
280
|
+
oldLines: 0,
|
|
281
|
+
newStart: header.newStart,
|
|
282
|
+
newLines: 0,
|
|
283
|
+
lines: []
|
|
284
|
+
};
|
|
285
|
+
hunkRawHeader.set(state.hunk, header.scope);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (!state.hunk) return;
|
|
289
|
+
if (isHunkBodyLine(line)) {
|
|
290
|
+
state.hunk.lines.push(line);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
closeLenientHunk(state);
|
|
294
|
+
}
|
|
295
|
+
function parsePatchLenient(patchText) {
|
|
296
|
+
const state = { files: [] };
|
|
297
|
+
for (const line of patchText.split("\n")) consumeLenientPatchLine(state, line);
|
|
298
|
+
closeLenientFile(state);
|
|
299
|
+
return state.files;
|
|
300
|
+
}
|
|
301
|
+
function indexRawHunkHeaders(patchText, patches) {
|
|
302
|
+
const scopes = [];
|
|
303
|
+
for (const line of patchText.split("\n")) {
|
|
304
|
+
const scope = line.match(/^@@[^@]*@@(.*)$/)?.[1];
|
|
305
|
+
if (scope !== void 0) scopes.push(scope);
|
|
306
|
+
}
|
|
307
|
+
let hunkIndex = 0;
|
|
308
|
+
for (const patch of patches) for (const hunk of patch.hunks) {
|
|
309
|
+
const scope = scopes[hunkIndex];
|
|
310
|
+
if (scope !== void 0) hunkRawHeader.set(hunk, scope);
|
|
311
|
+
hunkIndex += 1;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
315
|
+
export { buildDiffFromFiles, buildDiffFromPatch, computeWordDiff, diffRunEnd };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { DropzoneVisualState } from "../hooks/use-dropzone.js";
|
|
2
|
+
//#region src/lib/dropzone-validation.d.ts
|
|
3
|
+
type DropzoneSelectionMode = "append" | "replace";
|
|
4
|
+
declare const DropzoneErrorCode: {
|
|
5
|
+
readonly FileInvalidType: "file-invalid-type";
|
|
6
|
+
readonly FileTooLarge: "file-too-large";
|
|
7
|
+
readonly FileTooSmall: "file-too-small";
|
|
8
|
+
readonly TooManyFiles: "too-many-files";
|
|
9
|
+
readonly FileAlreadySelected: "file-already-selected";
|
|
10
|
+
};
|
|
11
|
+
type DropzoneErrorCodeValue = (typeof DropzoneErrorCode)[keyof typeof DropzoneErrorCode];
|
|
12
|
+
type DropzoneAccept = Readonly<Record<string, readonly string[]>>;
|
|
13
|
+
type DropzoneFileError = {
|
|
14
|
+
code: DropzoneErrorCodeValue | string;
|
|
15
|
+
message: string;
|
|
16
|
+
};
|
|
17
|
+
type DropzoneFileRejection = {
|
|
18
|
+
file: File;
|
|
19
|
+
errors: readonly DropzoneFileError[];
|
|
20
|
+
};
|
|
21
|
+
type DropzoneValidatorResult = DropzoneFileError | readonly DropzoneFileError[] | null;
|
|
22
|
+
type DropzoneValidator = (file: File, signal: AbortSignal) => DropzoneValidatorResult | Promise<DropzoneValidatorResult>;
|
|
23
|
+
type DropzonePolicy = {
|
|
24
|
+
accept?: DropzoneAccept;
|
|
25
|
+
minSize?: number;
|
|
26
|
+
maxSize?: number;
|
|
27
|
+
maxFiles?: number;
|
|
28
|
+
multiple?: boolean;
|
|
29
|
+
selectionMode?: DropzoneSelectionMode;
|
|
30
|
+
allowDuplicates?: boolean;
|
|
31
|
+
validator?: DropzoneValidator;
|
|
32
|
+
};
|
|
33
|
+
type DropzoneFileMetadata = {
|
|
34
|
+
name?: string;
|
|
35
|
+
size?: number;
|
|
36
|
+
type?: string;
|
|
37
|
+
lastModified?: number;
|
|
38
|
+
webkitRelativePath?: string;
|
|
39
|
+
};
|
|
40
|
+
type DropzoneProcessResult = {
|
|
41
|
+
acceptedFiles: readonly File[];
|
|
42
|
+
fileRejections: readonly DropzoneFileRejection[];
|
|
43
|
+
value: readonly File[];
|
|
44
|
+
removedFiles: readonly File[];
|
|
45
|
+
};
|
|
46
|
+
type DropzoneDragVerdictOptions = {
|
|
47
|
+
customExtraction?: boolean;
|
|
48
|
+
};
|
|
49
|
+
type NormalizedAcceptEntry = {
|
|
50
|
+
mime: string;
|
|
51
|
+
extensions: readonly string[];
|
|
52
|
+
};
|
|
53
|
+
declare function normalizeDropzoneAccept(accept: DropzoneAccept | undefined): readonly NormalizedAcceptEntry[];
|
|
54
|
+
declare function compileDropzoneAccept(accept: DropzoneAccept | undefined): string | undefined;
|
|
55
|
+
declare function isDropzoneFileAccepted(file: Pick<File, "name" | "type">, accept: DropzoneAccept | undefined): boolean;
|
|
56
|
+
declare function normalizeDropzoneMaxFiles(maxFiles: number | undefined): number;
|
|
57
|
+
declare function getDropzoneSelectionMode(policy: DropzonePolicy | undefined): DropzoneSelectionMode;
|
|
58
|
+
declare function getDropzoneCapacity(policy: DropzonePolicy | undefined): number;
|
|
59
|
+
declare function getDropzoneFileIdentity(file: DropzoneFileMetadata): string;
|
|
60
|
+
declare function toDropzoneError(value: unknown): Error;
|
|
61
|
+
declare function validateDropzoneFile(file: File, policy: DropzonePolicy | undefined, signal: AbortSignal): Promise<readonly DropzoneFileError[]>;
|
|
62
|
+
declare function processDropzoneFiles(files: readonly File[], currentValue: readonly File[], policy: DropzonePolicy | undefined, signal: AbortSignal): Promise<DropzoneProcessResult>;
|
|
63
|
+
declare function getDropzoneDragVerdict(files: readonly DropzoneFileMetadata[] | null, currentValue: readonly File[], policy: DropzonePolicy | undefined, options?: DropzoneDragVerdictOptions): Exclude<DropzoneVisualState, "idle" | "processing">;
|
|
64
|
+
declare function formatDropzoneFileSize(size: number): string;
|
|
65
|
+
//#endregion
|
|
66
|
+
export { DropzoneAccept, DropzoneDragVerdictOptions, DropzoneErrorCode, DropzoneErrorCodeValue, DropzoneFileError, DropzoneFileMetadata, DropzoneFileRejection, DropzonePolicy, DropzoneProcessResult, DropzoneSelectionMode, DropzoneValidator, DropzoneValidatorResult, compileDropzoneAccept, formatDropzoneFileSize, getDropzoneCapacity, getDropzoneDragVerdict, getDropzoneFileIdentity, getDropzoneSelectionMode, isDropzoneFileAccepted, normalizeDropzoneAccept, normalizeDropzoneMaxFiles, processDropzoneFiles, toDropzoneError, validateDropzoneFile };
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
//#region src/lib/dropzone-validation.ts
|
|
2
|
+
const DropzoneErrorCode = {
|
|
3
|
+
FileInvalidType: "file-invalid-type",
|
|
4
|
+
FileTooLarge: "file-too-large",
|
|
5
|
+
FileTooSmall: "file-too-small",
|
|
6
|
+
TooManyFiles: "too-many-files",
|
|
7
|
+
FileAlreadySelected: "file-already-selected"
|
|
8
|
+
};
|
|
9
|
+
const DEFAULT_POLICY = {
|
|
10
|
+
minSize: 0,
|
|
11
|
+
maxSize: Number.POSITIVE_INFINITY,
|
|
12
|
+
maxFiles: 0,
|
|
13
|
+
multiple: true,
|
|
14
|
+
selectionMode: "append",
|
|
15
|
+
allowDuplicates: false
|
|
16
|
+
};
|
|
17
|
+
function normalizeDropzoneAccept(accept) {
|
|
18
|
+
if (!accept) return [];
|
|
19
|
+
return Object.entries(accept).flatMap(([rawMime, rawExtensions]) => {
|
|
20
|
+
const mime = rawMime.trim().toLowerCase();
|
|
21
|
+
const extensions = Array.from(new Set(rawExtensions.flatMap((rawExtension) => {
|
|
22
|
+
const extension = rawExtension.trim().toLowerCase();
|
|
23
|
+
if (!extension) return [];
|
|
24
|
+
return [extension.startsWith(".") ? extension : `.${extension}`];
|
|
25
|
+
})));
|
|
26
|
+
return mime || extensions.length > 0 ? [{
|
|
27
|
+
mime,
|
|
28
|
+
extensions
|
|
29
|
+
}] : [];
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function compileDropzoneAccept(accept) {
|
|
33
|
+
const values = normalizeDropzoneAccept(accept).flatMap(({ mime, extensions }) => {
|
|
34
|
+
if (extensions.length > 0) return extensions;
|
|
35
|
+
return mime ? [mime] : [];
|
|
36
|
+
});
|
|
37
|
+
return values.length > 0 ? values.join(",") : void 0;
|
|
38
|
+
}
|
|
39
|
+
function isDropzoneFileAccepted(file, accept) {
|
|
40
|
+
return getFileAcceptance(file, normalizeDropzoneAccept(accept)) === "accept";
|
|
41
|
+
}
|
|
42
|
+
function normalizeDropzoneMaxFiles(maxFiles) {
|
|
43
|
+
const value = maxFiles ?? DEFAULT_POLICY.maxFiles;
|
|
44
|
+
if (!Number.isFinite(value) || value <= 0) return Number.POSITIVE_INFINITY;
|
|
45
|
+
return Math.max(1, Math.floor(value));
|
|
46
|
+
}
|
|
47
|
+
function getDropzoneSelectionMode(policy) {
|
|
48
|
+
return policy?.multiple === false ? "replace" : policy?.selectionMode ?? DEFAULT_POLICY.selectionMode;
|
|
49
|
+
}
|
|
50
|
+
function getDropzoneCapacity(policy) {
|
|
51
|
+
return policy?.multiple === false ? 1 : normalizeDropzoneMaxFiles(policy?.maxFiles);
|
|
52
|
+
}
|
|
53
|
+
function getDropzoneFileIdentity(file) {
|
|
54
|
+
return `${file.webkitRelativePath || file.name || ""}\0${file.size ?? ""}\0${file.type?.toLowerCase() ?? ""}\0${file.lastModified ?? ""}`;
|
|
55
|
+
}
|
|
56
|
+
function toDropzoneError(value) {
|
|
57
|
+
return value instanceof Error ? value : new Error(String(value));
|
|
58
|
+
}
|
|
59
|
+
async function validateDropzoneFile(file, policy, signal) {
|
|
60
|
+
const errors = [];
|
|
61
|
+
const minSize = policy?.minSize ?? DEFAULT_POLICY.minSize;
|
|
62
|
+
const maxSize = policy?.maxSize ?? DEFAULT_POLICY.maxSize;
|
|
63
|
+
if (!isDropzoneFileAccepted(file, policy?.accept)) errors.push({
|
|
64
|
+
code: DropzoneErrorCode.FileInvalidType,
|
|
65
|
+
message: "File type is not accepted."
|
|
66
|
+
});
|
|
67
|
+
if (file.size < minSize) errors.push({
|
|
68
|
+
code: DropzoneErrorCode.FileTooSmall,
|
|
69
|
+
message: `File is smaller than the ${formatDropzoneFileSize(minSize)} minimum.`
|
|
70
|
+
});
|
|
71
|
+
if (file.size > maxSize) errors.push({
|
|
72
|
+
code: DropzoneErrorCode.FileTooLarge,
|
|
73
|
+
message: `File is larger than the ${formatDropzoneFileSize(maxSize)} limit.`
|
|
74
|
+
});
|
|
75
|
+
if (policy?.validator) {
|
|
76
|
+
signal.throwIfAborted();
|
|
77
|
+
const result = await policy.validator(file, signal);
|
|
78
|
+
signal.throwIfAborted();
|
|
79
|
+
if (result) errors.push(...normalizeValidatorErrors(result));
|
|
80
|
+
}
|
|
81
|
+
return errors;
|
|
82
|
+
}
|
|
83
|
+
async function processDropzoneFiles(files, currentValue, policy, signal) {
|
|
84
|
+
signal.throwIfAborted();
|
|
85
|
+
const validatedFiles = await Promise.all(files.map(async (file) => ({
|
|
86
|
+
file,
|
|
87
|
+
errors: await validateDropzoneFile(file, policy, signal)
|
|
88
|
+
})));
|
|
89
|
+
signal.throwIfAborted();
|
|
90
|
+
const acceptedFiles = [];
|
|
91
|
+
const fileRejections = [];
|
|
92
|
+
const selectionMode = getDropzoneSelectionMode(policy);
|
|
93
|
+
const capacity = getDropzoneCapacity(policy);
|
|
94
|
+
const selectedFiles = selectionMode === "append" ? [...currentValue] : [];
|
|
95
|
+
const selectedIdentities = new Set(policy?.allowDuplicates ? [] : (selectionMode === "append" ? currentValue : []).map(getDropzoneFileIdentity));
|
|
96
|
+
for (const { file, errors } of validatedFiles) {
|
|
97
|
+
if (errors.length > 0) {
|
|
98
|
+
fileRejections.push({
|
|
99
|
+
file,
|
|
100
|
+
errors
|
|
101
|
+
});
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const identity = getDropzoneFileIdentity(file);
|
|
105
|
+
if (!policy?.allowDuplicates && selectedIdentities.has(identity)) {
|
|
106
|
+
fileRejections.push({
|
|
107
|
+
file,
|
|
108
|
+
errors: [{
|
|
109
|
+
code: DropzoneErrorCode.FileAlreadySelected,
|
|
110
|
+
message: `File "${file.name}" is already selected.`
|
|
111
|
+
}]
|
|
112
|
+
});
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (selectedFiles.length >= capacity) {
|
|
116
|
+
fileRejections.push({
|
|
117
|
+
file,
|
|
118
|
+
errors: [{
|
|
119
|
+
code: DropzoneErrorCode.TooManyFiles,
|
|
120
|
+
message: "Too many files."
|
|
121
|
+
}]
|
|
122
|
+
});
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
acceptedFiles.push(file);
|
|
126
|
+
selectedFiles.push(file);
|
|
127
|
+
selectedIdentities.add(identity);
|
|
128
|
+
}
|
|
129
|
+
if (selectionMode === "replace" && acceptedFiles.length === 0) return {
|
|
130
|
+
acceptedFiles,
|
|
131
|
+
fileRejections,
|
|
132
|
+
value: currentValue,
|
|
133
|
+
removedFiles: []
|
|
134
|
+
};
|
|
135
|
+
return {
|
|
136
|
+
acceptedFiles,
|
|
137
|
+
fileRejections,
|
|
138
|
+
value: selectedFiles,
|
|
139
|
+
removedFiles: selectionMode === "replace" ? getRemovedFiles(currentValue, selectedFiles) : []
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function getDropzoneDragVerdict(files, currentValue, policy, options = {}) {
|
|
143
|
+
const selectionMode = getDropzoneSelectionMode(policy);
|
|
144
|
+
const capacity = getDropzoneCapacity(policy);
|
|
145
|
+
if (selectionMode === "append" && currentValue.length >= capacity) return "reject";
|
|
146
|
+
if (!files || files.length === 0) return "unknown";
|
|
147
|
+
const availableSlots = selectionMode === "append" ? capacity - currentValue.length : capacity;
|
|
148
|
+
if (files.length > availableSlots) return "reject";
|
|
149
|
+
const normalizedAccept = normalizeDropzoneAccept(policy?.accept);
|
|
150
|
+
const metadataVerdicts = files.map((file) => getDropzoneMetadataVerdict(file, normalizedAccept, policy));
|
|
151
|
+
if (metadataVerdicts.includes("reject")) return "reject";
|
|
152
|
+
const duplicateVerdict = getDropzoneDuplicateVerdict(files, currentValue, policy, selectionMode);
|
|
153
|
+
if (duplicateVerdict === "reject") return "reject";
|
|
154
|
+
if (policy?.validator || options.customExtraction || metadataVerdicts.includes("unknown") || duplicateVerdict === "unknown") return "unknown";
|
|
155
|
+
return "accept";
|
|
156
|
+
}
|
|
157
|
+
function formatDropzoneFileSize(size) {
|
|
158
|
+
const safeSize = Number.isFinite(size) && size >= 0 ? size : 0;
|
|
159
|
+
const units = [
|
|
160
|
+
"B",
|
|
161
|
+
"KB",
|
|
162
|
+
"MB",
|
|
163
|
+
"GB",
|
|
164
|
+
"TB"
|
|
165
|
+
];
|
|
166
|
+
if (safeSize === 0) return "0 B";
|
|
167
|
+
const unitIndex = Math.min(Math.floor(Math.log(safeSize) / Math.log(1024)), units.length - 1);
|
|
168
|
+
return `${Math.round(safeSize / 1024 ** unitIndex * 10) / 10} ${units[unitIndex]}`;
|
|
169
|
+
}
|
|
170
|
+
function getFileAcceptance(file, entries) {
|
|
171
|
+
if (entries.length === 0) return "accept";
|
|
172
|
+
const verdicts = entries.map((entry) => getAcceptEntryVerdict(file, entry));
|
|
173
|
+
if (verdicts.includes("accept")) return "accept";
|
|
174
|
+
return verdicts.includes("unknown") ? "unknown" : "reject";
|
|
175
|
+
}
|
|
176
|
+
function getAcceptEntryVerdict(file, { mime, extensions }) {
|
|
177
|
+
if (extensions.length > 0) {
|
|
178
|
+
if (!file.name) return "unknown";
|
|
179
|
+
const name = file.name.toLowerCase();
|
|
180
|
+
return extensions.some((extension) => name.endsWith(extension)) ? "accept" : "reject";
|
|
181
|
+
}
|
|
182
|
+
if (!file.type) return "unknown";
|
|
183
|
+
const type = file.type.toLowerCase();
|
|
184
|
+
return (mime.endsWith("/*") ? type.startsWith(mime.slice(0, -1)) : type === mime) ? "accept" : "reject";
|
|
185
|
+
}
|
|
186
|
+
function getDropzoneMetadataVerdict(file, normalizedAccept, policy) {
|
|
187
|
+
const acceptance = getFileAcceptance(file, normalizedAccept);
|
|
188
|
+
if (acceptance === "reject") return "reject";
|
|
189
|
+
if (file.size === void 0) return "unknown";
|
|
190
|
+
if (file.size < (policy?.minSize ?? DEFAULT_POLICY.minSize)) return "reject";
|
|
191
|
+
if (file.size > (policy?.maxSize ?? DEFAULT_POLICY.maxSize)) return "reject";
|
|
192
|
+
return acceptance;
|
|
193
|
+
}
|
|
194
|
+
function getDropzoneDuplicateVerdict(files, currentValue, policy, selectionMode) {
|
|
195
|
+
if (policy?.allowDuplicates) return "accept";
|
|
196
|
+
const selectedIdentities = new Set(selectionMode === "append" ? currentValue.map(getDropzoneFileIdentity) : []);
|
|
197
|
+
let hasUnknownIdentity = false;
|
|
198
|
+
for (const file of files) {
|
|
199
|
+
if (!hasCompleteIdentity(file)) {
|
|
200
|
+
hasUnknownIdentity = true;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const identity = getDropzoneFileIdentity(file);
|
|
204
|
+
if (selectedIdentities.has(identity)) return "reject";
|
|
205
|
+
selectedIdentities.add(identity);
|
|
206
|
+
}
|
|
207
|
+
return hasUnknownIdentity ? "unknown" : "accept";
|
|
208
|
+
}
|
|
209
|
+
function isDropzoneErrorList(result) {
|
|
210
|
+
return Array.isArray(result);
|
|
211
|
+
}
|
|
212
|
+
function normalizeValidatorErrors(result) {
|
|
213
|
+
return isDropzoneErrorList(result) ? result : [result];
|
|
214
|
+
}
|
|
215
|
+
function hasCompleteIdentity(file) {
|
|
216
|
+
return Boolean(file.webkitRelativePath || file.name) && file.size !== void 0 && file.type !== void 0 && file.lastModified !== void 0;
|
|
217
|
+
}
|
|
218
|
+
function getRemovedFiles(currentValue, nextValue) {
|
|
219
|
+
const unmatchedNext = [...nextValue];
|
|
220
|
+
return currentValue.filter((file) => {
|
|
221
|
+
const index = unmatchedNext.indexOf(file);
|
|
222
|
+
if (index < 0) return true;
|
|
223
|
+
unmatchedNext.splice(index, 1);
|
|
224
|
+
return false;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
//#endregion
|
|
228
|
+
export { DropzoneErrorCode, compileDropzoneAccept, formatDropzoneFileSize, getDropzoneCapacity, getDropzoneDragVerdict, getDropzoneFileIdentity, getDropzoneSelectionMode, isDropzoneFileAccepted, normalizeDropzoneAccept, normalizeDropzoneMaxFiles, processDropzoneFiles, toDropzoneError, validateDropzoneFile };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/lib/env-file.d.ts
|
|
2
|
+
interface EnvironmentVariableEntry {
|
|
3
|
+
key: string;
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
declare const ENV_FILE_MAX_SIZE: number;
|
|
7
|
+
declare const DUPLICATE_ENVIRONMENT_VARIABLE_MESSAGE = "Environment variable keys must be unique";
|
|
8
|
+
declare class DuplicateEnvironmentVariableKeyError extends Error {
|
|
9
|
+
readonly key: string;
|
|
10
|
+
constructor(key: string);
|
|
11
|
+
}
|
|
12
|
+
declare function createEmptyEnvironmentVariableEntry(): EnvironmentVariableEntry;
|
|
13
|
+
declare function rowsFromEnvironmentVariables(envVars: Record<string, unknown> | undefined): EnvironmentVariableEntry[];
|
|
14
|
+
declare function getDuplicateEnvironmentVariableKeys(rows: readonly EnvironmentVariableEntry[]): Set<string>;
|
|
15
|
+
declare function collectEnvironmentVariables(rows: readonly EnvironmentVariableEntry[]): Record<string, string>;
|
|
16
|
+
declare function parseEnvFileText(text: string): EnvironmentVariableEntry[];
|
|
17
|
+
declare function rowsToEnvFileText(rows: readonly EnvironmentVariableEntry[]): string;
|
|
18
|
+
declare function readEnvFile(file: File, options?: {
|
|
19
|
+
maxSize?: number;
|
|
20
|
+
}): Promise<{
|
|
21
|
+
ok: true;
|
|
22
|
+
entries: EnvironmentVariableEntry[];
|
|
23
|
+
} | {
|
|
24
|
+
ok: false;
|
|
25
|
+
error: string;
|
|
26
|
+
}>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { DUPLICATE_ENVIRONMENT_VARIABLE_MESSAGE, DuplicateEnvironmentVariableKeyError, ENV_FILE_MAX_SIZE, EnvironmentVariableEntry, collectEnvironmentVariables, createEmptyEnvironmentVariableEntry, getDuplicateEnvironmentVariableKeys, parseEnvFileText, readEnvFile, rowsFromEnvironmentVariables, rowsToEnvFileText };
|