@vielzeug/refine 1.8.0 → 2.0.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 +5 -12
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +2 -5
- package/dist/_dev.js.map +1 -1
- package/dist/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/accordion-item.cjs +26 -24
- package/dist/accordion-item.cjs.map +1 -1
- package/dist/accordion-item.js +53 -51
- package/dist/accordion-item.js.map +1 -1
- package/dist/accordion.cjs +3 -1
- package/dist/accordion.cjs.map +1 -1
- package/dist/accordion.js +5 -3
- package/dist/accordion.js.map +1 -1
- package/dist/alert.cjs +1 -1
- package/dist/alert.cjs.map +1 -1
- package/dist/alert.js +1 -1
- package/dist/alert.js.map +1 -1
- package/dist/async.cjs +4 -2
- package/dist/async.cjs.map +1 -1
- package/dist/async.js +4 -2
- package/dist/async.js.map +1 -1
- package/dist/avatar-group.cjs +7 -0
- package/dist/avatar-group.cjs.map +1 -0
- package/dist/avatar-group.js +34 -0
- package/dist/avatar-group.js.map +1 -0
- package/dist/avatar.cjs +21 -16
- package/dist/avatar.cjs.map +1 -1
- package/dist/avatar.js +38 -54
- package/dist/avatar.js.map +1 -1
- package/dist/badge.cjs +4 -2
- package/dist/badge.cjs.map +1 -1
- package/dist/badge.js +6 -4
- package/dist/badge.js.map +1 -1
- package/dist/box.cjs +3 -1
- package/dist/box.cjs.map +1 -1
- package/dist/box.js +24 -18
- package/dist/box.js.map +1 -1
- package/dist/breadcrumb.cjs +4 -4
- package/dist/breadcrumb.cjs.map +1 -1
- package/dist/breadcrumb.js +4 -4
- package/dist/breadcrumb.js.map +1 -1
- package/dist/button-group.cjs +3 -3
- package/dist/button-group.cjs.map +1 -1
- package/dist/button-group.js +18 -16
- package/dist/button-group.js.map +1 -1
- package/dist/button.cjs +16 -12
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +31 -28
- package/dist/button.js.map +1 -1
- package/dist/calendar.cjs +94 -69
- package/dist/calendar.cjs.map +1 -1
- package/dist/calendar.js +131 -98
- package/dist/calendar.js.map +1 -1
- package/dist/card.cjs +7 -7
- package/dist/card.cjs.map +1 -1
- package/dist/card.js +53 -49
- package/dist/card.js.map +1 -1
- package/dist/carousel.cjs +65 -57
- package/dist/carousel.cjs.map +1 -1
- package/dist/carousel.js +157 -201
- package/dist/carousel.js.map +1 -1
- package/dist/chat-message.cjs +21 -19
- package/dist/chat-message.cjs.map +1 -1
- package/dist/chat-message.js +18 -15
- package/dist/chat-message.js.map +1 -1
- package/dist/checkbox-group.cjs +12 -10
- package/dist/checkbox-group.cjs.map +1 -1
- package/dist/checkbox-group.js +75 -76
- package/dist/checkbox-group.js.map +1 -1
- package/dist/checkbox.cjs +4 -4
- package/dist/checkbox.cjs.map +1 -1
- package/dist/checkbox.js +55 -55
- package/dist/checkbox.js.map +1 -1
- package/dist/chip.cjs +22 -20
- package/dist/chip.cjs.map +1 -1
- package/dist/chip.js +15 -12
- package/dist/chip.js.map +1 -1
- package/dist/code-window.cjs +8 -2
- package/dist/code-window.cjs.map +1 -1
- package/dist/code-window.js +8 -2
- package/dist/code-window.js.map +1 -1
- package/dist/combobox.cjs +63 -58
- package/dist/combobox.cjs.map +1 -1
- package/dist/combobox.js +199 -197
- package/dist/combobox.js.map +1 -1
- package/dist/command-palette.cjs +49 -29
- package/dist/command-palette.cjs.map +1 -1
- package/dist/command-palette.js +150 -118
- package/dist/command-palette.js.map +1 -1
- package/dist/content/avatar/avatar-group.d.ts +33 -0
- package/dist/content/avatar/avatar-group.d.ts.map +1 -0
- package/dist/content/avatar/avatar.d.ts +0 -32
- package/dist/content/avatar/avatar.d.ts.map +1 -1
- package/dist/content/card/card.css.cjs +1 -1
- package/dist/content/card/card.css.cjs.map +1 -1
- package/dist/content/card/card.css.js +1 -1
- package/dist/content/card/card.css.js.map +1 -1
- package/dist/content/card/card.d.ts.map +1 -1
- package/dist/content/carousel/carousel-slide.cjs +3 -1
- package/dist/content/carousel/carousel-slide.cjs.map +1 -1
- package/dist/content/carousel/carousel-slide.css.cjs +1 -1
- package/dist/content/carousel/carousel-slide.css.cjs.map +1 -1
- package/dist/content/carousel/carousel-slide.css.js +1 -1
- package/dist/content/carousel/carousel-slide.css.js.map +1 -1
- package/dist/content/carousel/carousel-slide.js +3 -1
- package/dist/content/carousel/carousel-slide.js.map +1 -1
- package/dist/content/carousel/carousel.css.cjs +1 -1
- package/dist/content/carousel/carousel.css.cjs.map +1 -1
- package/dist/content/carousel/carousel.css.js +1 -1
- package/dist/content/carousel/carousel.css.js.map +1 -1
- package/dist/content/carousel/carousel.d.ts +5 -19
- package/dist/content/carousel/carousel.d.ts.map +1 -1
- package/dist/content/chat-message/chat-message.d.ts.map +1 -1
- package/dist/content/index.d.ts +10 -2
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/list/_list-item-reveal.cjs +1 -1
- package/dist/content/list/_list-item-reveal.cjs.map +1 -1
- package/dist/content/list/_list-item-reveal.d.ts +2 -2
- package/dist/content/list/_list-item-reveal.d.ts.map +1 -1
- package/dist/content/list/_list-item-reveal.js +2 -2
- package/dist/content/list/_list-item-reveal.js.map +1 -1
- package/dist/content/list/list.d.ts.map +1 -1
- package/dist/content/marquee/index.d.ts +2 -0
- package/dist/content/marquee/index.d.ts.map +1 -0
- package/dist/content/marquee/marquee.css.cjs +2 -0
- package/dist/content/marquee/marquee.css.cjs.map +1 -0
- package/dist/content/marquee/marquee.css.js +6 -0
- package/dist/content/marquee/marquee.css.js.map +1 -0
- package/dist/content/marquee/marquee.d.ts +44 -0
- package/dist/content/marquee/marquee.d.ts.map +1 -0
- package/dist/content/stepper/_is-step-navigable.cjs +2 -0
- package/dist/content/stepper/_is-step-navigable.cjs.map +1 -0
- package/dist/content/stepper/_is-step-navigable.d.ts +14 -0
- package/dist/content/stepper/_is-step-navigable.d.ts.map +1 -0
- package/dist/content/stepper/_is-step-navigable.js +8 -0
- package/dist/content/stepper/_is-step-navigable.js.map +1 -0
- package/dist/content/stepper/step.css.cjs +2 -0
- package/dist/content/stepper/step.css.cjs.map +1 -0
- package/dist/content/stepper/step.css.js +6 -0
- package/dist/content/stepper/step.css.js.map +1 -0
- package/dist/content/stepper/step.d.ts +63 -0
- package/dist/content/stepper/step.d.ts.map +1 -0
- package/dist/content/stepper/stepper.css.cjs +2 -0
- package/dist/content/stepper/stepper.css.cjs.map +1 -0
- package/dist/content/stepper/stepper.css.js +6 -0
- package/dist/content/stepper/stepper.css.js.map +1 -0
- package/dist/content/stepper/stepper.d.ts +88 -0
- package/dist/content/stepper/stepper.d.ts.map +1 -0
- package/dist/copy-command.cjs +9 -3
- package/dist/copy-command.cjs.map +1 -1
- package/dist/copy-command.js +9 -3
- package/dist/copy-command.js.map +1 -1
- package/dist/{headless → core}/_internal.d.ts +3 -5
- package/dist/core/_internal.d.ts.map +1 -0
- package/dist/core/announcer.cjs.map +1 -0
- package/dist/core/announcer.d.ts.map +1 -0
- package/dist/{headless → core}/announcer.js +1 -1
- package/dist/core/announcer.js.map +1 -0
- package/dist/core/aria-reflection.cjs.map +1 -0
- package/dist/core/aria-reflection.d.ts.map +1 -0
- package/dist/{headless → core}/aria-reflection.js +1 -1
- package/dist/core/aria-reflection.js.map +1 -0
- package/dist/core/auto-resize.cjs.map +1 -0
- package/dist/core/auto-resize.d.ts.map +1 -0
- package/dist/{headless → core}/auto-resize.js +1 -1
- package/dist/core/auto-resize.js.map +1 -0
- package/dist/core/checkable.cjs.map +1 -0
- package/dist/core/checkable.d.ts.map +1 -0
- package/dist/{headless → core}/checkable.js +1 -1
- package/dist/core/checkable.js.map +1 -0
- package/dist/core/choice-field.cjs +2 -0
- package/dist/core/choice-field.cjs.map +1 -0
- package/dist/core/choice-field.d.ts.map +1 -0
- package/dist/{headless → core}/choice-field.js +3 -2
- package/dist/core/choice-field.js.map +1 -0
- package/dist/core/composer.cjs.map +1 -0
- package/dist/core/composer.d.ts.map +1 -0
- package/dist/{headless → core}/composer.js +1 -1
- package/dist/core/composer.js.map +1 -0
- package/dist/{headless → core}/date-picker.cjs +1 -1
- package/dist/core/date-picker.cjs.map +1 -0
- package/dist/core/date-picker.d.ts.map +1 -0
- package/dist/{headless → core}/date-picker.js +3 -3
- package/dist/core/date-picker.js.map +1 -0
- package/dist/core/direction.cjs.map +1 -0
- package/dist/core/direction.d.ts.map +1 -0
- package/dist/{headless → core}/direction.js +1 -1
- package/dist/core/direction.js.map +1 -0
- package/dist/core/field-base.cjs +2 -0
- package/dist/core/field-base.cjs.map +1 -0
- package/dist/{headless → core}/field-base.d.ts +3 -3
- package/dist/core/field-base.d.ts.map +1 -0
- package/dist/core/field-base.js +66 -0
- package/dist/core/field-base.js.map +1 -0
- package/dist/core/focus.cjs.map +1 -0
- package/dist/core/focus.d.ts.map +1 -0
- package/dist/{headless → core}/focus.js +1 -1
- package/dist/core/focus.js.map +1 -0
- package/dist/{headless → core}/index.d.ts +7 -6
- package/dist/core/index.d.ts.map +1 -0
- package/dist/{headless → core}/keyboard.cjs +1 -1
- package/dist/core/keyboard.cjs.map +1 -0
- package/dist/core/keyboard.d.ts.map +1 -0
- package/dist/{headless → core}/keyboard.js +2 -2
- package/dist/core/keyboard.js.map +1 -0
- package/dist/core/light-dom.cjs.map +1 -0
- package/dist/core/light-dom.d.ts.map +1 -0
- package/dist/{headless → core}/light-dom.js +1 -1
- package/dist/core/light-dom.js.map +1 -0
- package/dist/core/nav.cjs.map +1 -0
- package/dist/core/nav.d.ts.map +1 -0
- package/dist/{headless → core}/nav.js +1 -1
- package/dist/core/nav.js.map +1 -0
- package/dist/core/numbers.cjs.map +1 -0
- package/dist/core/numbers.d.ts.map +1 -0
- package/dist/{headless → core}/numbers.js +1 -1
- package/dist/core/numbers.js.map +1 -0
- package/dist/core/option-list.cjs +2 -0
- package/dist/core/option-list.cjs.map +1 -0
- package/dist/core/option-list.d.ts +49 -0
- package/dist/core/option-list.d.ts.map +1 -0
- package/dist/core/option-list.js +65 -0
- package/dist/core/option-list.js.map +1 -0
- package/dist/core/ore.cjs.map +1 -0
- package/dist/{headless → core}/ore.d.ts +2 -2
- package/dist/core/ore.d.ts.map +1 -0
- package/dist/{headless → core}/ore.js +1 -1
- package/dist/core/ore.js.map +1 -0
- package/dist/core/overlay.cjs +2 -0
- package/dist/core/overlay.cjs.map +1 -0
- package/dist/core/overlay.d.ts +41 -0
- package/dist/core/overlay.d.ts.map +1 -0
- package/dist/core/overlay.js +17 -0
- package/dist/core/overlay.js.map +1 -0
- package/dist/core/paginated-list.d.ts.map +1 -0
- package/dist/core/parse.cjs.map +1 -0
- package/dist/core/parse.d.ts.map +1 -0
- package/dist/{headless → core}/parse.js +1 -1
- package/dist/core/parse.js.map +1 -0
- package/dist/core/positioner.cjs +2 -0
- package/dist/core/positioner.cjs.map +1 -0
- package/dist/core/positioner.d.ts.map +1 -0
- package/dist/{headless → core}/positioner.js +7 -7
- package/dist/core/positioner.js.map +1 -0
- package/dist/core/ref-callback.cjs +2 -0
- package/dist/core/ref-callback.cjs.map +1 -0
- package/dist/core/ref-callback.d.ts.map +1 -0
- package/dist/{headless → core}/ref-callback.js +2 -2
- package/dist/core/ref-callback.js.map +1 -0
- package/dist/core/signals.cjs +2 -0
- package/dist/core/signals.cjs.map +1 -0
- package/dist/core/signals.d.ts.map +1 -0
- package/dist/{headless → core}/signals.js +3 -2
- package/dist/core/signals.js.map +1 -0
- package/dist/core/slider.cjs +2 -0
- package/dist/core/slider.cjs.map +1 -0
- package/dist/core/slider.d.ts.map +1 -0
- package/dist/{headless → core}/slider.js +3 -3
- package/dist/{headless/slider.cjs.map → core/slider.js.map} +1 -1
- package/dist/core/spinner.cjs +2 -0
- package/dist/core/spinner.cjs.map +1 -0
- package/dist/core/spinner.d.ts.map +1 -0
- package/dist/{headless → core}/spinner.js +3 -3
- package/dist/{headless/spinner.cjs.map → core/spinner.js.map} +1 -1
- package/dist/core/swipe.cjs.map +1 -0
- package/dist/core/swipe.d.ts.map +1 -0
- package/dist/{headless → core}/swipe.js +1 -1
- package/dist/core/swipe.js.map +1 -0
- package/dist/core/text-field.cjs.map +1 -0
- package/dist/core/text-field.d.ts.map +1 -0
- package/dist/{headless → core}/text-field.js +1 -1
- package/dist/core/text-field.js.map +1 -0
- package/dist/core/typeahead.cjs.map +1 -0
- package/dist/core/typeahead.d.ts.map +1 -0
- package/dist/{headless → core}/typeahead.js +1 -1
- package/dist/core/typeahead.js.map +1 -0
- package/dist/custom-elements.json +5079 -4595
- package/dist/datagrid.cjs +320 -271
- package/dist/datagrid.cjs.map +1 -1
- package/dist/datagrid.js +483 -429
- package/dist/datagrid.js.map +1 -1
- package/dist/date-picker.cjs +77 -62
- package/dist/date-picker.cjs.map +1 -1
- package/dist/date-picker.js +169 -146
- package/dist/date-picker.js.map +1 -1
- package/dist/dialog.cjs +3 -3
- package/dist/dialog.cjs.map +1 -1
- package/dist/dialog.js +18 -7
- package/dist/dialog.js.map +1 -1
- package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
- package/dist/drawer.cjs +5 -5
- package/dist/drawer.cjs.map +1 -1
- package/dist/drawer.js +52 -47
- package/dist/drawer.js.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/feedback/chip/chip.d.ts.map +1 -1
- package/dist/feedback/skeleton/skeleton.d.ts.map +1 -1
- package/dist/feedback/toast/index.d.ts +1 -1
- package/dist/feedback/toast/index.d.ts.map +1 -1
- package/dist/feedback/toast/toast.d.ts +16 -68
- package/dist/feedback/toast/toast.d.ts.map +1 -1
- package/dist/feedback/typing-indicator/typing-indicator.d.ts +1 -1
- package/dist/file-input.cjs +111 -78
- package/dist/file-input.cjs.map +1 -1
- package/dist/file-input.js +220 -183
- package/dist/file-input.js.map +1 -1
- package/dist/grid-item.cjs +3 -1
- package/dist/grid-item.cjs.map +1 -1
- package/dist/grid-item.js +3 -1
- package/dist/grid-item.js.map +1 -1
- package/dist/grid.cjs +3 -1
- package/dist/grid.cjs.map +1 -1
- package/dist/grid.js +6 -5
- package/dist/grid.js.map +1 -1
- package/dist/icon.cjs +5 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +50 -46
- package/dist/icon.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +7 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -67
- package/dist/input.cjs +44 -40
- package/dist/input.cjs.map +1 -1
- package/dist/input.js +132 -130
- package/dist/input.js.map +1 -1
- package/dist/inputs/button-group/button-group.css.cjs +1 -1
- package/dist/inputs/button-group/button-group.css.cjs.map +1 -1
- package/dist/inputs/button-group/button-group.css.js +1 -1
- package/dist/inputs/button-group/button-group.css.js.map +1 -1
- package/dist/inputs/button-group/button-group.d.ts +6 -3
- package/dist/inputs/button-group/button-group.d.ts.map +1 -1
- package/dist/inputs/checkbox/checkbox.d.ts +6 -5
- package/dist/inputs/checkbox/checkbox.d.ts.map +1 -1
- package/dist/inputs/checkbox-group/checkbox-group.d.ts +1 -1
- package/dist/inputs/checkbox-group/checkbox-group.d.ts.map +1 -1
- package/dist/inputs/combobox/combobox.d.ts +4 -2
- package/dist/inputs/combobox/combobox.d.ts.map +1 -1
- package/dist/inputs/combobox/combobox.types.d.ts +5 -7
- package/dist/inputs/combobox/combobox.types.d.ts.map +1 -1
- package/dist/inputs/datagrid/datagrid-column.cjs +1 -1
- package/dist/inputs/datagrid/datagrid-column.cjs.map +1 -1
- package/dist/inputs/datagrid/datagrid-column.d.ts +1 -1
- package/dist/inputs/datagrid/datagrid-column.d.ts.map +1 -1
- package/dist/inputs/datagrid/datagrid-column.js +5 -5
- package/dist/inputs/datagrid/datagrid-column.js.map +1 -1
- package/dist/inputs/datagrid/datagrid-model.cjs +2 -0
- package/dist/inputs/datagrid/datagrid-model.cjs.map +1 -0
- package/dist/inputs/datagrid/datagrid-model.d.ts +101 -0
- package/dist/inputs/datagrid/datagrid-model.d.ts.map +1 -0
- package/dist/inputs/datagrid/datagrid-model.js +202 -0
- package/dist/inputs/datagrid/datagrid-model.js.map +1 -0
- package/dist/inputs/datagrid/datagrid-nav.cjs.map +1 -1
- package/dist/inputs/datagrid/datagrid.d.ts +44 -45
- package/dist/inputs/datagrid/datagrid.d.ts.map +1 -1
- package/dist/inputs/date-picker/date-picker.d.ts +4 -4
- package/dist/inputs/date-picker/date-picker.d.ts.map +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs.map +1 -1
- package/dist/inputs/file-input/file-input-upload.d.ts.map +1 -1
- package/dist/inputs/file-input/file-input-upload.js +6 -3
- package/dist/inputs/file-input/file-input-upload.js.map +1 -1
- package/dist/inputs/file-input/file-input.d.ts.map +1 -1
- package/dist/inputs/index.d.ts +0 -4
- package/dist/inputs/index.d.ts.map +1 -1
- package/dist/inputs/input/input.d.ts +4 -10
- package/dist/inputs/input/input.d.ts.map +1 -1
- package/dist/inputs/message-composer/message-composer.d.ts +6 -10
- package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
- package/dist/inputs/number-input/number-input.d.ts +4 -10
- package/dist/inputs/number-input/number-input.d.ts.map +1 -1
- package/dist/inputs/otp-input/otp-input.d.ts +4 -6
- package/dist/inputs/otp-input/otp-input.d.ts.map +1 -1
- package/dist/inputs/radio/radio.d.ts +4 -3
- package/dist/inputs/radio/radio.d.ts.map +1 -1
- package/dist/inputs/radio-group/radio-group.d.ts +1 -1
- package/dist/inputs/radio-group/radio-group.d.ts.map +1 -1
- package/dist/inputs/rating/rating.d.ts +4 -5
- package/dist/inputs/rating/rating.d.ts.map +1 -1
- package/dist/inputs/select/select.d.ts +7 -9
- package/dist/inputs/select/select.d.ts.map +1 -1
- package/dist/inputs/shared/field-binding.cjs.map +1 -1
- package/dist/inputs/shared/field-binding.d.ts +1 -1
- package/dist/inputs/shared/field-binding.js.map +1 -1
- package/dist/inputs/shared/index.d.ts +0 -1
- package/dist/inputs/shared/index.d.ts.map +1 -1
- package/dist/inputs/shared/native-field-event.cjs +2 -0
- package/dist/inputs/shared/native-field-event.cjs.map +1 -0
- package/dist/inputs/shared/native-field-event.d.ts +6 -0
- package/dist/inputs/shared/native-field-event.d.ts.map +1 -0
- package/dist/inputs/shared/native-field-event.js +29 -0
- package/dist/inputs/shared/native-field-event.js.map +1 -0
- package/dist/inputs/shared/templates.cjs +18 -12
- package/dist/inputs/shared/templates.cjs.map +1 -1
- package/dist/inputs/shared/templates.d.ts +1 -1
- package/dist/inputs/shared/templates.d.ts.map +1 -1
- package/dist/inputs/shared/templates.js +19 -13
- package/dist/inputs/shared/templates.js.map +1 -1
- package/dist/inputs/slider/slider.css.cjs +1 -1
- package/dist/inputs/slider/slider.css.cjs.map +1 -1
- package/dist/inputs/slider/slider.css.js +1 -1
- package/dist/inputs/slider/slider.css.js.map +1 -1
- package/dist/inputs/slider/slider.d.ts +7 -10
- package/dist/inputs/slider/slider.d.ts.map +1 -1
- package/dist/inputs/switch/switch.d.ts +4 -3
- package/dist/inputs/switch/switch.d.ts.map +1 -1
- package/dist/inputs/textarea/textarea.d.ts +4 -10
- package/dist/inputs/textarea/textarea.d.ts.map +1 -1
- package/dist/inputs/time-picker/time-picker.d.ts +4 -4
- package/dist/inputs/time-picker/time-picker.d.ts.map +1 -1
- package/dist/layout/box/box.d.ts.map +1 -1
- package/dist/layout/navbar/navbar.css.cjs +1 -1
- package/dist/layout/navbar/navbar.css.cjs.map +1 -1
- package/dist/layout/navbar/navbar.css.js +1 -1
- package/dist/layout/navbar/navbar.css.js.map +1 -1
- package/dist/layout/navbar/navbar.d.ts +10 -0
- package/dist/layout/navbar/navbar.d.ts.map +1 -1
- package/dist/layout/sidebar/sidebar-item.css.cjs +1 -1
- package/dist/layout/sidebar/sidebar-item.css.cjs.map +1 -1
- package/dist/layout/sidebar/sidebar-item.css.js +1 -1
- package/dist/layout/sidebar/sidebar-item.css.js.map +1 -1
- package/dist/layout/sidebar/sidebar.css.cjs +1 -1
- package/dist/layout/sidebar/sidebar.css.cjs.map +1 -1
- package/dist/layout/sidebar/sidebar.css.js +1 -1
- package/dist/layout/sidebar/sidebar.css.js.map +1 -1
- package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
- package/dist/list-item.cjs +2 -2
- package/dist/list-item.cjs.map +1 -1
- package/dist/list-item.js +4 -4
- package/dist/list-item.js.map +1 -1
- package/dist/list.cjs +3 -1
- package/dist/list.cjs.map +1 -1
- package/dist/list.js +28 -25
- package/dist/list.js.map +1 -1
- package/dist/marquee.cjs +32 -0
- package/dist/marquee.cjs.map +1 -0
- package/dist/marquee.js +93 -0
- package/dist/marquee.js.map +1 -0
- package/dist/menu.cjs +7 -7
- package/dist/menu.cjs.map +1 -1
- package/dist/menu.js +135 -103
- package/dist/menu.js.map +1 -1
- package/dist/message-composer.cjs +33 -31
- package/dist/message-composer.cjs.map +1 -1
- package/dist/message-composer.js +123 -123
- package/dist/message-composer.js.map +1 -1
- package/dist/navbar.cjs +17 -15
- package/dist/navbar.cjs.map +1 -1
- package/dist/navbar.js +108 -89
- package/dist/navbar.js.map +1 -1
- package/dist/number-input.cjs +19 -19
- package/dist/number-input.cjs.map +1 -1
- package/dist/number-input.js +94 -97
- package/dist/number-input.js.map +1 -1
- package/dist/otp-input.cjs +15 -13
- package/dist/otp-input.cjs.map +1 -1
- package/dist/otp-input.js +83 -82
- package/dist/otp-input.js.map +1 -1
- package/dist/overlay/command-palette/command-palette.d.ts +2 -2
- package/dist/overlay/command-palette/command-palette.d.ts.map +1 -1
- package/dist/overlay/command-palette/command-palette.types.d.ts +4 -5
- package/dist/overlay/command-palette/command-palette.types.d.ts.map +1 -1
- package/dist/overlay/dialog/dialog.d.ts +7 -6
- package/dist/overlay/dialog/dialog.d.ts.map +1 -1
- package/dist/overlay/drawer/drawer.d.ts +7 -10
- package/dist/overlay/drawer/drawer.d.ts.map +1 -1
- package/dist/overlay/index.d.ts +1 -1
- package/dist/overlay/index.d.ts.map +1 -1
- package/dist/overlay/menu/menu.d.ts +9 -7
- package/dist/overlay/menu/menu.d.ts.map +1 -1
- package/dist/overlay/popover/popover.d.ts +6 -11
- package/dist/overlay/popover/popover.d.ts.map +1 -1
- package/dist/overlay/shared/await-exit.cjs +1 -1
- package/dist/overlay/shared/await-exit.cjs.map +1 -1
- package/dist/overlay/shared/await-exit.js +1 -1
- package/dist/overlay/shared/await-exit.js.map +1 -1
- package/dist/overlay/shared/use-dialog.cjs +1 -1
- package/dist/overlay/shared/use-dialog.cjs.map +1 -1
- package/dist/overlay/shared/use-dialog.d.ts +13 -3
- package/dist/overlay/shared/use-dialog.d.ts.map +1 -1
- package/dist/overlay/shared/use-dialog.js +80 -72
- package/dist/overlay/shared/use-dialog.js.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.cjs +1 -1
- package/dist/overlay/shared/use-floating-trigger.cjs.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.d.ts +3 -1
- package/dist/overlay/shared/use-floating-trigger.d.ts.map +1 -1
- package/dist/overlay/shared/use-floating-trigger.js +64 -70
- package/dist/overlay/shared/use-floating-trigger.js.map +1 -1
- package/dist/overlay/tooltip/tooltip.d.ts +9 -0
- package/dist/overlay/tooltip/tooltip.d.ts.map +1 -1
- package/dist/pagination.cjs +69 -55
- package/dist/pagination.cjs.map +1 -1
- package/dist/pagination.js +70 -56
- package/dist/pagination.js.map +1 -1
- package/dist/password-strength.cjs +6 -4
- package/dist/password-strength.cjs.map +1 -1
- package/dist/password-strength.js +6 -4
- package/dist/password-strength.js.map +1 -1
- package/dist/popover.cjs +4 -4
- package/dist/popover.cjs.map +1 -1
- package/dist/popover.js +28 -17
- package/dist/popover.js.map +1 -1
- package/dist/progress.cjs +25 -17
- package/dist/progress.cjs.map +1 -1
- package/dist/progress.js +26 -18
- package/dist/progress.js.map +1 -1
- package/dist/radio-group.cjs +14 -12
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.js +88 -89
- package/dist/radio-group.js.map +1 -1
- package/dist/radio.cjs +4 -4
- package/dist/radio.cjs.map +1 -1
- package/dist/radio.js +90 -90
- package/dist/radio.js.map +1 -1
- package/dist/rating.cjs +18 -16
- package/dist/rating.cjs.map +1 -1
- package/dist/rating.js +69 -69
- package/dist/rating.js.map +1 -1
- package/dist/refine.cjs +1669 -1324
- package/dist/refine.cjs.map +1 -1
- package/dist/refine.iife.js +1656 -1311
- package/dist/refine.iife.js.map +1 -1
- package/dist/refine.js +1759 -1414
- package/dist/refine.js.map +1 -1
- package/dist/register.d.ts +21 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/select.cjs +59 -51
- package/dist/select.cjs.map +1 -1
- package/dist/select.js +189 -182
- package/dist/select.js.map +1 -1
- package/dist/separator.cjs +9 -9
- package/dist/separator.cjs.map +1 -1
- package/dist/separator.js +9 -9
- package/dist/separator.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/prop-bundles.cjs +1 -1
- package/dist/shared/prop-bundles.cjs.map +1 -1
- package/dist/shared/prop-bundles.js +4 -2
- package/dist/shared/prop-bundles.js.map +1 -1
- package/dist/shared/size-presets.cjs +1 -1
- package/dist/shared/size-presets.cjs.map +1 -1
- package/dist/shared/size-presets.d.ts +3 -0
- package/dist/shared/size-presets.d.ts.map +1 -1
- package/dist/shared/size-presets.js +4 -1
- package/dist/shared/size-presets.js.map +1 -1
- package/dist/sidebar.cjs +8 -8
- package/dist/sidebar.cjs.map +1 -1
- package/dist/sidebar.js +25 -25
- package/dist/sidebar.js.map +1 -1
- package/dist/skeleton.cjs +4 -6
- package/dist/skeleton.cjs.map +1 -1
- package/dist/skeleton.js +21 -22
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.cjs +14 -14
- package/dist/slider.cjs.map +1 -1
- package/dist/slider.js +160 -168
- package/dist/slider.js.map +1 -1
- package/dist/step.cjs +47 -0
- package/dist/step.cjs.map +1 -0
- package/dist/step.js +127 -0
- package/dist/step.js.map +1 -0
- package/dist/stepper.cjs +8 -0
- package/dist/stepper.cjs.map +1 -0
- package/dist/stepper.js +101 -0
- package/dist/stepper.js.map +1 -0
- package/dist/styles/index.d.ts +0 -28
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/styles/mixins/shape.css.cjs +2 -2
- package/dist/styles/mixins/shape.css.cjs.map +1 -1
- package/dist/styles/mixins/shape.css.js +6 -6
- package/dist/styles/mixins/shape.css.js.map +1 -1
- package/dist/styles/tokens.css +4 -0
- package/dist/switch.cjs +4 -4
- package/dist/switch.cjs.map +1 -1
- package/dist/switch.js +44 -44
- package/dist/switch.js.map +1 -1
- package/dist/tab-item.cjs +3 -3
- package/dist/tab-item.cjs.map +1 -1
- package/dist/tab-item.js +24 -24
- package/dist/tab-item.js.map +1 -1
- package/dist/tab-panel.cjs +7 -5
- package/dist/tab-panel.cjs.map +1 -1
- package/dist/tab-panel.js +14 -12
- package/dist/tab-panel.js.map +1 -1
- package/dist/table.cjs +3 -1
- package/dist/table.cjs.map +1 -1
- package/dist/table.js +3 -1
- package/dist/table.js.map +1 -1
- package/dist/tabs.cjs +6 -6
- package/dist/tabs.cjs.map +1 -1
- package/dist/tabs.js +30 -29
- package/dist/tabs.js.map +1 -1
- package/dist/text.cjs +3 -1
- package/dist/text.cjs.map +1 -1
- package/dist/text.js +3 -1
- package/dist/text.js.map +1 -1
- package/dist/textarea.cjs +22 -22
- package/dist/textarea.cjs.map +1 -1
- package/dist/textarea.js +110 -112
- package/dist/textarea.js.map +1 -1
- package/dist/time-picker.cjs +69 -61
- package/dist/time-picker.cjs.map +1 -1
- package/dist/time-picker.js +146 -132
- package/dist/time-picker.js.map +1 -1
- package/dist/toast.cjs +22 -22
- package/dist/toast.cjs.map +1 -1
- package/dist/toast.js +280 -173
- package/dist/toast.js.map +1 -1
- package/dist/tooltip.cjs +5 -5
- package/dist/tooltip.cjs.map +1 -1
- package/dist/tooltip.js +61 -51
- package/dist/tooltip.js.map +1 -1
- package/dist/typing-indicator.cjs +1 -1
- package/dist/typing-indicator.cjs.map +1 -1
- package/dist/typing-indicator.js +5 -5
- package/dist/typing-indicator.js.map +1 -1
- package/dist/utils/link.cjs.map +1 -1
- package/dist/utils/link.d.ts +2 -2
- package/package.json +35 -117
- package/dist/form.cjs +0 -11
- package/dist/form.cjs.map +0 -1
- package/dist/form.js +0 -59
- package/dist/form.js.map +0 -1
- package/dist/headless/_internal.d.ts.map +0 -1
- package/dist/headless/announcer.cjs.map +0 -1
- package/dist/headless/announcer.d.ts.map +0 -1
- package/dist/headless/announcer.js.map +0 -1
- package/dist/headless/aria-reflection.cjs.map +0 -1
- package/dist/headless/aria-reflection.d.ts.map +0 -1
- package/dist/headless/aria-reflection.js.map +0 -1
- package/dist/headless/auto-resize.cjs.map +0 -1
- package/dist/headless/auto-resize.d.ts.map +0 -1
- package/dist/headless/auto-resize.js.map +0 -1
- package/dist/headless/checkable.cjs.map +0 -1
- package/dist/headless/checkable.d.ts.map +0 -1
- package/dist/headless/checkable.js.map +0 -1
- package/dist/headless/choice-field.cjs +0 -2
- package/dist/headless/choice-field.cjs.map +0 -1
- package/dist/headless/choice-field.d.ts.map +0 -1
- package/dist/headless/choice-field.js.map +0 -1
- package/dist/headless/composer.cjs.map +0 -1
- package/dist/headless/composer.d.ts.map +0 -1
- package/dist/headless/composer.js.map +0 -1
- package/dist/headless/datagrid.cjs +0 -2
- package/dist/headless/datagrid.cjs.map +0 -1
- package/dist/headless/datagrid.d.ts +0 -158
- package/dist/headless/datagrid.d.ts.map +0 -1
- package/dist/headless/datagrid.js +0 -55
- package/dist/headless/datagrid.js.map +0 -1
- package/dist/headless/date-picker.cjs.map +0 -1
- package/dist/headless/date-picker.d.ts.map +0 -1
- package/dist/headless/date-picker.js.map +0 -1
- package/dist/headless/direction.cjs.map +0 -1
- package/dist/headless/direction.d.ts.map +0 -1
- package/dist/headless/direction.js.map +0 -1
- package/dist/headless/field-base.cjs +0 -2
- package/dist/headless/field-base.cjs.map +0 -1
- package/dist/headless/field-base.d.ts.map +0 -1
- package/dist/headless/field-base.js +0 -72
- package/dist/headless/field-base.js.map +0 -1
- package/dist/headless/focus.cjs.map +0 -1
- package/dist/headless/focus.d.ts.map +0 -1
- package/dist/headless/focus.js.map +0 -1
- package/dist/headless/index.d.ts.map +0 -1
- package/dist/headless/keyboard.cjs.map +0 -1
- package/dist/headless/keyboard.d.ts.map +0 -1
- package/dist/headless/keyboard.js.map +0 -1
- package/dist/headless/light-dom.cjs.map +0 -1
- package/dist/headless/light-dom.d.ts.map +0 -1
- package/dist/headless/light-dom.js.map +0 -1
- package/dist/headless/nav.cjs.map +0 -1
- package/dist/headless/nav.d.ts.map +0 -1
- package/dist/headless/nav.js.map +0 -1
- package/dist/headless/numbers.cjs.map +0 -1
- package/dist/headless/numbers.d.ts.map +0 -1
- package/dist/headless/numbers.js.map +0 -1
- package/dist/headless/option-list.cjs +0 -2
- package/dist/headless/option-list.cjs.map +0 -1
- package/dist/headless/option-list.d.ts +0 -107
- package/dist/headless/option-list.d.ts.map +0 -1
- package/dist/headless/option-list.js +0 -66
- package/dist/headless/option-list.js.map +0 -1
- package/dist/headless/ore.cjs.map +0 -1
- package/dist/headless/ore.d.ts.map +0 -1
- package/dist/headless/ore.js.map +0 -1
- package/dist/headless/overlay.cjs +0 -2
- package/dist/headless/overlay.cjs.map +0 -1
- package/dist/headless/overlay.d.ts +0 -64
- package/dist/headless/overlay.d.ts.map +0 -1
- package/dist/headless/overlay.js +0 -32
- package/dist/headless/overlay.js.map +0 -1
- package/dist/headless/paginated-list.cjs +0 -2
- package/dist/headless/paginated-list.cjs.map +0 -1
- package/dist/headless/paginated-list.d.ts.map +0 -1
- package/dist/headless/paginated-list.js +0 -34
- package/dist/headless/paginated-list.js.map +0 -1
- package/dist/headless/parse.cjs.map +0 -1
- package/dist/headless/parse.d.ts.map +0 -1
- package/dist/headless/parse.js.map +0 -1
- package/dist/headless/positioner.cjs +0 -2
- package/dist/headless/positioner.cjs.map +0 -1
- package/dist/headless/positioner.d.ts.map +0 -1
- package/dist/headless/positioner.js.map +0 -1
- package/dist/headless/ref-callback.cjs +0 -2
- package/dist/headless/ref-callback.cjs.map +0 -1
- package/dist/headless/ref-callback.d.ts.map +0 -1
- package/dist/headless/ref-callback.js.map +0 -1
- package/dist/headless/selection-control.cjs +0 -2
- package/dist/headless/selection-control.cjs.map +0 -1
- package/dist/headless/selection-control.d.ts +0 -30
- package/dist/headless/selection-control.d.ts.map +0 -1
- package/dist/headless/selection-control.js +0 -44
- package/dist/headless/selection-control.js.map +0 -1
- package/dist/headless/signals.cjs +0 -2
- package/dist/headless/signals.cjs.map +0 -1
- package/dist/headless/signals.d.ts.map +0 -1
- package/dist/headless/signals.js.map +0 -1
- package/dist/headless/slider.cjs +0 -2
- package/dist/headless/slider.d.ts.map +0 -1
- package/dist/headless/slider.js.map +0 -1
- package/dist/headless/sort-control.cjs +0 -2
- package/dist/headless/sort-control.cjs.map +0 -1
- package/dist/headless/sort-control.d.ts +0 -22
- package/dist/headless/sort-control.d.ts.map +0 -1
- package/dist/headless/sort-control.js +0 -36
- package/dist/headless/sort-control.js.map +0 -1
- package/dist/headless/spinner.cjs +0 -2
- package/dist/headless/spinner.d.ts.map +0 -1
- package/dist/headless/spinner.js.map +0 -1
- package/dist/headless/swipe.cjs.map +0 -1
- package/dist/headless/swipe.d.ts.map +0 -1
- package/dist/headless/swipe.js.map +0 -1
- package/dist/headless/text-field.cjs.map +0 -1
- package/dist/headless/text-field.d.ts.map +0 -1
- package/dist/headless/text-field.js.map +0 -1
- package/dist/headless/typeahead.cjs.map +0 -1
- package/dist/headless/typeahead.d.ts.map +0 -1
- package/dist/headless/typeahead.js.map +0 -1
- package/dist/headless.cjs +0 -1
- package/dist/headless.js +0 -30
- package/dist/inputs/datagrid/datagrid-controls.cjs +0 -2
- package/dist/inputs/datagrid/datagrid-controls.cjs.map +0 -1
- package/dist/inputs/datagrid/datagrid-controls.d.ts +0 -98
- package/dist/inputs/datagrid/datagrid-controls.d.ts.map +0 -1
- package/dist/inputs/datagrid/datagrid-controls.js +0 -147
- package/dist/inputs/datagrid/datagrid-controls.js.map +0 -1
- package/dist/inputs/form/form.css.cjs +0 -2
- package/dist/inputs/form/form.css.cjs.map +0 -1
- package/dist/inputs/form/form.css.js +0 -6
- package/dist/inputs/form/form.css.js.map +0 -1
- package/dist/inputs/form/form.d.ts +0 -59
- package/dist/inputs/form/form.d.ts.map +0 -1
- package/dist/inputs/shared/form-context.cjs +0 -2
- package/dist/inputs/shared/form-context.cjs.map +0 -1
- package/dist/inputs/shared/form-context.d.ts +0 -55
- package/dist/inputs/shared/form-context.d.ts.map +0 -1
- package/dist/inputs/shared/form-context.js +0 -15
- package/dist/inputs/shared/form-context.js.map +0 -1
- package/dist/styles/index.cjs +0 -2
- package/dist/styles/index.cjs.map +0 -1
- package/dist/styles/index.js +0 -25
- package/dist/styles/index.js.map +0 -1
- package/dist/styles/styles.css +0 -5
- package/dist/testing/index.d.ts +0 -188
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing.cjs +0 -2
- package/dist/testing.cjs.map +0 -1
- package/dist/testing.js +0 -26
- package/dist/testing.js.map +0 -1
- /package/dist/{headless → core}/announcer.cjs +0 -0
- /package/dist/{headless → core}/announcer.d.ts +0 -0
- /package/dist/{headless → core}/aria-reflection.cjs +0 -0
- /package/dist/{headless → core}/aria-reflection.d.ts +0 -0
- /package/dist/{headless → core}/auto-resize.cjs +0 -0
- /package/dist/{headless → core}/auto-resize.d.ts +0 -0
- /package/dist/{headless → core}/checkable.cjs +0 -0
- /package/dist/{headless → core}/checkable.d.ts +0 -0
- /package/dist/{headless → core}/choice-field.d.ts +0 -0
- /package/dist/{headless → core}/composer.cjs +0 -0
- /package/dist/{headless → core}/composer.d.ts +0 -0
- /package/dist/{headless → core}/date-picker.d.ts +0 -0
- /package/dist/{headless → core}/direction.cjs +0 -0
- /package/dist/{headless → core}/direction.d.ts +0 -0
- /package/dist/{headless → core}/focus.cjs +0 -0
- /package/dist/{headless → core}/focus.d.ts +0 -0
- /package/dist/{headless → core}/keyboard.d.ts +0 -0
- /package/dist/{headless → core}/light-dom.cjs +0 -0
- /package/dist/{headless → core}/light-dom.d.ts +0 -0
- /package/dist/{headless → core}/nav.cjs +0 -0
- /package/dist/{headless → core}/nav.d.ts +0 -0
- /package/dist/{headless → core}/numbers.cjs +0 -0
- /package/dist/{headless → core}/numbers.d.ts +0 -0
- /package/dist/{headless → core}/ore.cjs +0 -0
- /package/dist/{headless → core}/paginated-list.d.ts +0 -0
- /package/dist/{headless → core}/parse.cjs +0 -0
- /package/dist/{headless → core}/parse.d.ts +0 -0
- /package/dist/{headless → core}/positioner.d.ts +0 -0
- /package/dist/{headless → core}/ref-callback.d.ts +0 -0
- /package/dist/{headless → core}/signals.d.ts +0 -0
- /package/dist/{headless → core}/slider.d.ts +0 -0
- /package/dist/{headless → core}/spinner.d.ts +0 -0
- /package/dist/{headless → core}/swipe.cjs +0 -0
- /package/dist/{headless → core}/swipe.d.ts +0 -0
- /package/dist/{headless → core}/text-field.cjs +0 -0
- /package/dist/{headless → core}/text-field.d.ts +0 -0
- /package/dist/{headless → core}/typeahead.cjs +0 -0
- /package/dist/{headless → core}/typeahead.d.ts +0 -0
|
@@ -4,14 +4,13 @@ import '../../inputs/checkbox/checkbox';
|
|
|
4
4
|
import '../../inputs/combobox/combobox';
|
|
5
5
|
import '../../inputs/select/select';
|
|
6
6
|
import '../../overlay/popover/popover';
|
|
7
|
-
import { type DataGridColumn, type SelectionMode, type SortDirection, type SortState } from '
|
|
8
|
-
import { type FilterOption, type DataGridView } from './datagrid-controls';
|
|
7
|
+
import { type DataGridColumn, type DataGridView, type FilterOption, type SelectionMode, type SortDirection, type SortState } from './datagrid-model';
|
|
9
8
|
type SortMode = 'client' | 'server';
|
|
10
9
|
export { COLUMN_TAG } from './datagrid-column';
|
|
11
|
-
export type { DataGridView, FilterOption, FilterOperator } from './datagrid-
|
|
10
|
+
export type { DataGridView, FilterOption, FilterOperator } from './datagrid-model';
|
|
12
11
|
/**
|
|
13
12
|
* Returns the Lucide icon name for a column's sort state.
|
|
14
|
-
* Pure function — no closure dependency on
|
|
13
|
+
* Pure function — no closure dependency on the grid model.
|
|
15
14
|
*/
|
|
16
15
|
export declare function sortIconName(state: SortState, key: string): string;
|
|
17
16
|
/**
|
|
@@ -80,10 +79,9 @@ export type OreDataGridProps<T = Record<string, unknown>> = {
|
|
|
80
79
|
* Enable row expansion. When set, each row gets a toggle button.
|
|
81
80
|
* Requires at least one column to have a `renderExpanded` function.
|
|
82
81
|
*
|
|
83
|
-
* @security The `renderExpanded` callback's returned HTML string is inserted
|
|
84
|
-
* `
|
|
85
|
-
*
|
|
86
|
-
* (e.g. with DOMPurify or your CSP-compliant sanitizer).
|
|
82
|
+
* @security The `renderExpanded` callback's returned HTML string is inserted through
|
|
83
|
+
* Ore's `unsafeHtml()` directive. If data originates from untrusted user input, sanitize
|
|
84
|
+
* it before returning (for example, with DOMPurify or your CSP-compliant sanitizer).
|
|
87
85
|
*/
|
|
88
86
|
expandable?: boolean;
|
|
89
87
|
/**
|
|
@@ -148,11 +146,11 @@ export type OreDataGridProps<T = Record<string, unknown>> = {
|
|
|
148
146
|
/**
|
|
149
147
|
* A reactive data source from `@vielzeug/sourcerer` (or any compatible object).
|
|
150
148
|
* When set, the source drives row data, pagination, and search — the `rows` prop is ignored.
|
|
151
|
-
* Client-side sort and filter are bypassed; wire `sort-change` to `source.
|
|
149
|
+
* Client-side sort and filter are bypassed; wire `sort-change` to `source.setQuery()` externally.
|
|
152
150
|
* @example
|
|
153
151
|
* ```js
|
|
154
|
-
* import {
|
|
155
|
-
* const source =
|
|
152
|
+
* import { createPageSource } from '@vielzeug/sourcerer';
|
|
153
|
+
* const source = createPageSource({ load: ({ query, signal }) => api.users(query, { signal }) });
|
|
156
154
|
* grid.source = source;
|
|
157
155
|
* ```
|
|
158
156
|
*/
|
|
@@ -245,26 +243,25 @@ export type OreDataGridProps<T = Record<string, unknown>> = {
|
|
|
245
243
|
/**
|
|
246
244
|
* Minimal structural interface for a reactive data source accepted by `ore-datagrid`.
|
|
247
245
|
*
|
|
248
|
-
* Any `@vielzeug/sourcerer` source
|
|
249
|
-
*
|
|
246
|
+
* Any page-shaped `@vielzeug/sourcerer` source satisfies this interface automatically — no direct
|
|
247
|
+
* sourcerer import is required in refine.
|
|
250
248
|
*
|
|
251
249
|
* When `source` is set on the grid:
|
|
252
|
-
* - `rows` prop is ignored; `source.
|
|
253
|
-
* - Pagination
|
|
254
|
-
* - Prev/next buttons call `source.
|
|
255
|
-
* -
|
|
256
|
-
* - `source.
|
|
257
|
-
* - Client-side sort and filter are bypassed; wire `sort-change` to `source.
|
|
250
|
+
* - `rows` prop is ignored; `source.snapshot.data` drives displayed items.
|
|
251
|
+
* - Pagination reads `source.snapshot.pagination`.
|
|
252
|
+
* - Prev/next buttons call `source.page.previous()` / `source.page.next()`.
|
|
253
|
+
* - Search calls `source.setQuery({ search })`.
|
|
254
|
+
* - `source.snapshot.isFetching` contributes to the grid's `aria-busy` state.
|
|
255
|
+
* - Client-side sort and filter are bypassed; wire `sort-change` to `source.setQuery()` externally.
|
|
258
256
|
*
|
|
259
257
|
* @example
|
|
260
258
|
* ```ts
|
|
261
|
-
* import {
|
|
259
|
+
* import { createPageSource } from '@vielzeug/sourcerer';
|
|
262
260
|
*
|
|
263
|
-
* const source =
|
|
264
|
-
*
|
|
265
|
-
* fetch(`/api/users?page=${
|
|
261
|
+
* const source = createPageSource({
|
|
262
|
+
* load: ({ query, signal }) =>
|
|
263
|
+
* fetch(`/api/users?page=${query.page}&limit=${query.pageSize}&search=${query.search}`, { signal })
|
|
266
264
|
* .then(r => r.json()),
|
|
267
|
-
* limit: 20,
|
|
268
265
|
* });
|
|
269
266
|
*
|
|
270
267
|
* const grid = document.querySelector('ore-datagrid');
|
|
@@ -272,31 +269,33 @@ export type OreDataGridProps<T = Record<string, unknown>> = {
|
|
|
272
269
|
* ```
|
|
273
270
|
*/
|
|
274
271
|
export type DataGridSource<T = Record<string, unknown>> = {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
272
|
+
readonly page?: {
|
|
273
|
+
next(): Promise<void> | void;
|
|
274
|
+
previous(): Promise<void> | void;
|
|
275
|
+
};
|
|
276
|
+
setQuery?(changes: {
|
|
277
|
+
search?: string;
|
|
278
|
+
}): Promise<void> | void;
|
|
279
|
+
readonly snapshot: {
|
|
280
|
+
readonly data: readonly T[];
|
|
281
281
|
readonly error: {
|
|
282
282
|
message: string;
|
|
283
283
|
} | null;
|
|
284
|
-
readonly
|
|
285
|
-
readonly
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
284
|
+
readonly isFetching: boolean;
|
|
285
|
+
readonly pagination: {
|
|
286
|
+
readonly count: number;
|
|
287
|
+
readonly hasNext: boolean;
|
|
288
|
+
readonly hasPrevious: boolean;
|
|
289
|
+
readonly index: number;
|
|
290
|
+
readonly kind: 'page';
|
|
291
|
+
readonly size: number;
|
|
292
|
+
readonly total: number;
|
|
293
|
+
};
|
|
294
|
+
readonly query: {
|
|
295
|
+
readonly search?: string;
|
|
296
|
+
};
|
|
289
297
|
};
|
|
290
|
-
|
|
291
|
-
next?(): Promise<void>;
|
|
292
|
-
/** Navigate to the previous page. No-op when on the first page. */
|
|
293
|
-
prev?(): Promise<void>;
|
|
294
|
-
/** Debounced text search. No-op when not implemented by the source. */
|
|
295
|
-
search?(query: string, opts?: {
|
|
296
|
-
immediate?: boolean;
|
|
297
|
-
}): Promise<void>;
|
|
298
|
-
/** Subscribe to source updates. Returns an unsubscribe function. */
|
|
299
|
-
subscribe(listener: () => void): () => void;
|
|
298
|
+
subscribe(listener: (snapshot: DataGridSource<T>['snapshot']) => void): () => void;
|
|
300
299
|
};
|
|
301
300
|
export declare const DATAGRID_TAG: "ore-datagrid";
|
|
302
301
|
//# sourceMappingURL=datagrid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datagrid.d.ts","sourceRoot":"","sources":["../../../src/inputs/datagrid/datagrid.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"datagrid.d.ts","sourceRoot":"","sources":["../../../src/inputs/datagrid/datagrid.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,8 @@ import type { ComponentSize, RoundedSize, ThemeColor, VisualVariant } from '../.
|
|
|
2
2
|
import '../../content/icon/icon';
|
|
3
3
|
import '../input/input';
|
|
4
4
|
export type OreDatePickerEvents = {
|
|
5
|
-
change:
|
|
6
|
-
|
|
7
|
-
};
|
|
5
|
+
change: Event;
|
|
6
|
+
input: Event;
|
|
8
7
|
};
|
|
9
8
|
export type OreDatePickerProps = {
|
|
10
9
|
/** Theme color */
|
|
@@ -84,7 +83,8 @@ export type OreDatePickerProps = {
|
|
|
84
83
|
* @attr {string} locale - BCP 47 locale string
|
|
85
84
|
* @attr {string} weekend-days - Comma-separated day indices to disable
|
|
86
85
|
*
|
|
87
|
-
* @fires
|
|
86
|
+
* @fires input - Fired when a date is selected.
|
|
87
|
+
* @fires change - Fired when a date is selected.
|
|
88
88
|
*
|
|
89
89
|
* @slot label - Custom label for the trigger field
|
|
90
90
|
* @slot prefix - Content before the trigger text (e.g. icon)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/inputs/date-picker/date-picker.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAU1F,OAAO,yBAAyB,CAAC;AACjC,OAAO,gBAAgB,CAAC;AAQxB,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/inputs/date-picker/date-picker.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAU1F,OAAO,yBAAyB,CAAC;AACjC,OAAO,gBAAgB,CAAC;AAQxB,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kBAAkB;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,iBAAiB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,qBAAqB;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IACnD;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,eAAO,MAAM,eAAe,EAAG,iBAA0B,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../
|
|
1
|
+
const e=require("../../core/announcer.cjs");let t=require("@vielzeug/ripple"),n=require("@vielzeug/ripple/watch"),r=require("@vielzeug/dnd");var i=e=>{if(e===0)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`,`TB`],r=Math.floor(Math.log(e)/Math.log(t));return`${parseFloat((e/t**r).toFixed(1))} ${n[r]}`},a=(e,t)=>!t||e.size<=t,o=e=>e>0?`${i(e)}/s`:``,s=e=>e?e.split(`,`).map(e=>e.trim()):[],c={error:null,loaded:0,speedBps:0,status:`idle`},l=e=>{if(e.speedBps<=0||e.status!==`uploading`)return``;let t=Math.max(0,Math.round((e.total-e.loaded)/e.speedBps));return t<60?`${t}s left`:`${Math.round(t/60)}m left`};function u(i){let u=(0,t.signal)([]),d=new Map,f=new Map;function p(e){let n=d.get(e);return n||(n=(0,t.signal)({...c,total:e.size}),d.set(e,n)),n}function m(e){return p(e).value}function h(e,t){let n=p(e);n.value={...n.value,...t}}function g(t,n=0){if(i.disabled.value)return;let r=i.upload.value;if(!r)return;f.get(t)?.abort();let a=new AbortController;f.set(t,a),h(t,{error:null,loaded:n,speedBps:0,status:`uploading`,total:t.size});let o=performance.now(),s=n;r(t,{onProgress:(e,n)=>{if(a.signal.aborted)return;let r=performance.now(),c=(r-o)/1e3,l=c>0?Math.max(0,(e-s)/c):0,u=m(t).speedBps,d=u>0?u*.7+l*.3:l;o=r,s=e,h(t,{loaded:e,speedBps:d,total:n||t.size}),i.onUploadProgress(t,e,n||t.size)},resumeFrom:n,signal:a.signal}).then(()=>{a.signal.aborted||(h(t,{loaded:t.size,speedBps:0,status:`success`}),e.announce(`${t.name} uploaded successfully.`),i.onUploadSuccess(t))}).catch(n=>{if(a.signal.aborted)return;let r=n instanceof Error?n.message:String(n);h(t,{error:r,speedBps:0,status:`error`}),e.announce(`${t.name} failed to upload: ${r}`,{politeness:`assertive`}),i.onUploadError(t,n)})}function _(e){i.disabled.value||g(e,m(e).loaded)}function v(e){let t=new Set(e);for(let e of d.keys())t.has(e)||(f.get(e)?.abort(),f.delete(e),d.delete(e))}let y=(0,n.watch)(u,v);function b(e,t){if(i.disabled.value)return;let n=i.multiple.value,o=Array.from(e);n||(o=o.slice(0,1));let c=s(i.accept.value),l=i.maxSize.value;o=o.filter(e=>(0,r.matchesAccept)(e,c)&&a(e,l));let d=n?[...u.value]:[],f=[];for(let e of o)d.includes(e)||(d.push(e),f.push(e));let p=i.maxFiles.value;p>0&&d.length>p&&(d=d.slice(0,p)),u.value=d,i.onChange(u.value,t);for(let e of f)u.value.includes(e)&&g(e)}function x(e,t){i.disabled.value||(u.value=u.value.filter(t=>t!==e),i.onRemove(e,u.value,t),i.onChange(u.value,t))}function S(e,t,n){if(i.disabled.value)return!1;let o=s(i.accept.value);return!(0,r.matchesAccept)(t,o)||!a(t,i.maxSize.value)?!1:(u.value=u.value.map(n=>n===e?t:n),i.onRemove(e,u.value,n),i.onChange(u.value,n),g(t),!0)}function C(e){let t=m(e);return t.total<=0?0:Math.min(100,Math.round(t.loaded/t.total*100))}function w(e){let t=m(e);return[o(t.speedBps),l(t)].filter(Boolean).join(` · `)}function T(e){let t=m(e).status;return t===`success`?`check`:t===`error`?`alert-circle`:`file`}function E(){y.dispose();for(let e of f.values())e.abort();f.clear(),d.clear()}return{addFiles:b,dispose:E,files:u,fileState:m,removeFile:x,replaceFile:S,retryUpload:_,statusIconName:T,uploadMetaText:w,uploadPercent:C}}exports.createFileQueue=u,exports.formatBytes=i;
|
|
2
2
|
//# sourceMappingURL=file-input-upload.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input-upload.cjs","names":[],"sources":["../../../src/inputs/file-input/file-input-upload.ts"],"sourcesContent":["import { matchesAccept } from '@vielzeug/dnd';\nimport { type Readable, signal, watch } from '@vielzeug/ripple';\n\nimport { announce } from '../../headless';\n\n// ── Byte/speed formatting ────────────────────────────────────────────────────\n\nexport const formatBytes = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n};\n\nconst isFileSizeAllowed = (file: File, maxSize: number): boolean => !maxSize || file.size <= maxSize;\n\nconst formatSpeed = (bytesPerSecond: number): string => (bytesPerSecond > 0 ? `${formatBytes(bytesPerSecond)}/s` : '');\n\nconst parseAccept = (accept: string | undefined): string[] => (accept ? accept.split(',').map((t) => t.trim()) : []);\n\n// ── Upload lifecycle types ───────────────────────────────────────────────────\n\n/** Upload lifecycle status for a single file. `idle` covers both \"no `upload` handler wired up\"\n * (picker-only mode, fully supported) and \"not started yet\". */\nexport type FileUploadStatus = 'error' | 'idle' | 'success' | 'uploading';\n\n/** Per-file upload snapshot. One reactive signal per file — see `createFileQueue` — not one\n * signal holding a map, so a progress tick for one file never invalidates another's bindings. */\nexport type FileUploadState = {\n error: string | null;\n loaded: number;\n speedBps: number;\n status: FileUploadStatus;\n total: number;\n};\n\nconst IDLE_UPLOAD_STATE: Omit<FileUploadState, 'total'> = { error: null, loaded: 0, speedBps: 0, status: 'idle' };\n\nconst formatEta = (state: FileUploadState): string => {\n if (state.speedBps <= 0 || state.status !== 'uploading') return '';\n\n const remainingSeconds = Math.max(0, Math.round((state.total - state.loaded) / state.speedBps));\n\n if (remainingSeconds < 60) return `${remainingSeconds}s left`;\n\n return `${Math.round(remainingSeconds / 60)}m left`;\n};\n\n/**\n * Consumer-supplied transport — this component has no built-in network layer (zero-dependency,\n * transport-agnostic by design, same reasoning as `courier`'s own fetch-wrapping-only stance).\n * This function is the seam between the UI's upload lifecycle (progress, retry, per-file\n * isolation) and however the app actually moves bytes (`fetch`, `XMLHttpRequest`, a presigned S3\n * PUT, `@vielzeug/courier`, …).\n *\n * `resumeFrom` is a *hint*, not a guarantee: it's the byte offset the component last observed\n * via `onProgress` before the previous attempt failed (0 on a fresh upload). A transport that\n * supports byte ranges (e.g. an HTTP `Range`/`Content-Range` header, S3 multipart, tus) can use\n * it to genuinely resume from that point; a plain `fetch(url, { body: file })` can ignore it and\n * simply re-send the whole file — the UI still shows a resumed-from-N-bytes experience either\n * way, since the file itself was never dropped from memory.\n */\nexport type FileUploadFn = (\n file: File,\n ctx: { onProgress: (loaded: number, total: number) => void; resumeFrom: number; signal: AbortSignal },\n) => Promise<void>;\n\n// ── Queue ─────────────────────────────────────────────────────────────────────\n\nexport type FileQueueOptions = {\n accept: Readable<string | undefined>;\n disabled: Readable<boolean>;\n maxFiles: Readable<number>;\n maxSize: Readable<number>;\n multiple: Readable<boolean>;\n onChange: (files: File[], originalEvent?: Event) => void;\n onRemove: (file: File, files: File[], originalEvent?: Event) => void;\n onUploadError: (file: File, error: unknown) => void;\n onUploadProgress: (file: File, loaded: number, total: number) => void;\n onUploadSuccess: (file: File) => void;\n upload: Readable<FileUploadFn | undefined>;\n};\n\nexport type FileQueue = {\n addFiles(newFiles: File[], originalEvent?: Event): void;\n dispose(): void;\n readonly files: Readable<File[]>;\n fileState(file: File): FileUploadState;\n removeFile(file: File, originalEvent?: Event): void;\n /** Validates `newFile` (accept/max-size) and, if accepted, swaps it in for `oldFile` in place\n * and starts its upload. Returns whether the replacement was accepted. Also fires `onRemove`\n * for `oldFile` — a replace is a removal-and-add that happen to land in the same slot, and a\n * consumer listening only for removal (e.g. to clean up a server-side record) still needs to\n * hear that the old file is gone. */\n replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean;\n retryUpload(file: File): void;\n statusIconName(file: File): string;\n uploadMetaText(file: File): string;\n uploadPercent(file: File): number;\n};\n\n/**\n * Owns file selection *and* the opt-in upload lifecycle together — they were never really\n * separable (adding a file starts its upload; removing one must abort it; replacing one is both\n * at once). Independent of `html`/rendering, following the same shape as `datagrid`'s\n * `createDataGridControls` and `combobox`'s `combobox-options.ts`: a factory `file-input.ts`\n * wires into drag/drop/native-input events and the template, directly unit-testable without\n * mounting a component.\n *\n * Every file-level rule (accept, max-size, max-files, disabled) and every upload-lifecycle rule\n * (progress, retry-from-offset, per-file isolation) lives here in one place.\n */\nexport function createFileQueue(options: FileQueueOptions): FileQueue {\n const files = signal<File[]>([]);\n const stateSignals = new Map<File, ReturnType<typeof signal<FileUploadState>>>();\n const controllers = new Map<File, AbortController>();\n\n function stateSignal(file: File): ReturnType<typeof signal<FileUploadState>> {\n let s = stateSignals.get(file);\n\n if (!s) {\n s = signal<FileUploadState>({ ...IDLE_UPLOAD_STATE, total: file.size });\n stateSignals.set(file, s);\n }\n\n return s;\n }\n\n function fileState(file: File): FileUploadState {\n return stateSignal(file).value;\n }\n\n function patchState(file: File, patch: Partial<FileUploadState>): void {\n const s = stateSignal(file);\n\n s.value = { ...s.value, ...patch };\n }\n\n // Each file gets its own `AbortController` and its own promise chain — nothing here `await`s\n // another file's upload, so one file's rejection can never block, freeze, or cancel the others.\n function startUpload(file: File, resumeFrom = 0): void {\n if (options.disabled.value) return;\n\n const uploadFn = options.upload.value;\n\n if (!uploadFn) return;\n\n controllers.get(file)?.abort();\n\n const controller = new AbortController();\n\n controllers.set(file, controller);\n patchState(file, { error: null, loaded: resumeFrom, speedBps: 0, status: 'uploading', total: file.size });\n\n // Rolling (exponential-moving-average) speed estimate rather than a naive\n // `loaded / elapsedSinceStart` average — the latter drags heavily behind the file's actual\n // *current* rate right after a slow start or a mid-transfer stall.\n let lastSampleAt = performance.now();\n let lastSampleLoaded = resumeFrom;\n\n uploadFn(file, {\n onProgress: (loaded, total) => {\n if (controller.signal.aborted) return;\n\n const now = performance.now();\n const elapsedSeconds = (now - lastSampleAt) / 1000;\n const instantBps = elapsedSeconds > 0 ? Math.max(0, (loaded - lastSampleLoaded) / elapsedSeconds) : 0;\n const previousBps = fileState(file).speedBps;\n const speedBps = previousBps > 0 ? previousBps * 0.7 + instantBps * 0.3 : instantBps;\n\n lastSampleAt = now;\n lastSampleLoaded = loaded;\n patchState(file, { loaded, speedBps, total: total || file.size });\n options.onUploadProgress(file, loaded, total || file.size);\n },\n resumeFrom,\n signal: controller.signal,\n })\n .then(() => {\n if (controller.signal.aborted) return;\n\n patchState(file, { loaded: file.size, speedBps: 0, status: 'success' });\n announce(`${file.name} uploaded successfully.`);\n options.onUploadSuccess(file);\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n\n const message = error instanceof Error ? error.message : String(error);\n\n patchState(file, { error: message, speedBps: 0, status: 'error' });\n announce(`${file.name} failed to upload: ${message}`, { politeness: 'assertive' });\n options.onUploadError(file, error);\n });\n }\n\n // Resumes from the last byte offset this file actually reached, not from 0 — see\n // `FileUploadFn`'s doc comment on what \"resume\" honestly means when the transport is\n // consumer-supplied.\n function retryUpload(file: File): void {\n if (options.disabled.value) return;\n\n startUpload(file, fileState(file).loaded);\n }\n\n // Aborts + drops upload state for any file no longer in `files` — covers plain removal, a\n // non-`multiple` selection replacing the previous file, and `replaceFile()` swapping one File\n // for another. One cleanup path instead of duplicating it at every call site that can shrink\n // `files`.\n function dropOrphanedState(activeFiles: File[]): void {\n const keep = new Set(activeFiles);\n\n for (const file of stateSignals.keys()) {\n if (keep.has(file)) continue;\n\n controllers.get(file)?.abort();\n controllers.delete(file);\n stateSignals.delete(file);\n }\n }\n\n const filesWatch = watch(files, dropOrphanedState);\n\n function addFiles(newFiles: File[], originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n const isMultiple = options.multiple.value;\n let incoming = Array.from(newFiles);\n\n if (!isMultiple) incoming = incoming.slice(0, 1);\n\n const acceptList = parseAccept(options.accept.value);\n const maxSize = options.maxSize.value;\n\n incoming = incoming.filter((f) => matchesAccept(f, acceptList) && isFileSizeAllowed(f, maxSize));\n\n let updated: File[] = isMultiple ? [...files.value] : [];\n const added: File[] = [];\n\n for (const f of incoming) {\n if (!updated.includes(f)) {\n updated.push(f);\n added.push(f);\n }\n }\n\n const maxFiles = options.maxFiles.value;\n\n if (maxFiles > 0 && updated.length > maxFiles) updated = updated.slice(0, maxFiles);\n\n files.value = updated;\n options.onChange(files.value, originalEvent);\n\n for (const f of added) {\n if (files.value.includes(f)) startUpload(f);\n }\n }\n\n function removeFile(file: File, originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n files.value = files.value.filter((f) => f !== file);\n options.onRemove(file, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n }\n\n function replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean {\n if (options.disabled.value) return false;\n\n const acceptList = parseAccept(options.accept.value);\n\n if (!matchesAccept(newFile, acceptList) || !isFileSizeAllowed(newFile, options.maxSize.value)) return false;\n\n files.value = files.value.map((f) => (f === oldFile ? newFile : f));\n options.onRemove(oldFile, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n startUpload(newFile);\n\n return true;\n }\n\n function uploadPercent(file: File): number {\n const state = fileState(file);\n\n if (state.total <= 0) return 0;\n\n return Math.min(100, Math.round((state.loaded / state.total) * 100));\n }\n\n // Speed + ETA on one line — percent itself is rendered separately (e.g. `<ore-progress>`'s\n // own `label`), so this only needs the two metrics that wouldn't otherwise fit there.\n function uploadMetaText(file: File): string {\n const state = fileState(file);\n\n return [formatSpeed(state.speedBps), formatEta(state)].filter(Boolean).join(' · ');\n }\n\n function statusIconName(file: File): string {\n const status = fileState(file).status;\n\n if (status === 'success') return 'check';\n\n if (status === 'error') return 'alert-circle';\n\n return 'file';\n }\n\n function dispose(): void {\n filesWatch.dispose();\n\n for (const controller of controllers.values()) controller.abort();\n\n controllers.clear();\n stateSignals.clear();\n }\n\n return {\n addFiles,\n dispose,\n files,\n fileState,\n removeFile,\n replaceFile,\n retryUpload,\n statusIconName,\n uploadMetaText,\n uploadPercent,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"file-input-upload.cjs","names":[],"sources":["../../../src/inputs/file-input/file-input-upload.ts"],"sourcesContent":["import { matchesAccept } from '@vielzeug/dnd';\nimport { type Readable, signal } from '@vielzeug/ripple';\nimport { watch } from '@vielzeug/ripple/watch';\n\nimport { announce } from '../../core';\n\n// ── Byte/speed formatting ────────────────────────────────────────────────────\n\nexport const formatBytes = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n};\n\nconst isFileSizeAllowed = (file: File, maxSize: number): boolean => !maxSize || file.size <= maxSize;\n\nconst formatSpeed = (bytesPerSecond: number): string => (bytesPerSecond > 0 ? `${formatBytes(bytesPerSecond)}/s` : '');\n\nconst parseAccept = (accept: string | undefined): string[] => (accept ? accept.split(',').map((t) => t.trim()) : []);\n\n// ── Upload lifecycle types ───────────────────────────────────────────────────\n\n/** Upload lifecycle status for a single file. `idle` covers both \"no `upload` handler wired up\"\n * (picker-only mode, fully supported) and \"not started yet\". */\nexport type FileUploadStatus = 'error' | 'idle' | 'success' | 'uploading';\n\n/** Per-file upload snapshot. One reactive signal per file — see `createFileQueue` — not one\n * signal holding a map, so a progress tick for one file never invalidates another's bindings. */\nexport type FileUploadState = {\n error: string | null;\n loaded: number;\n speedBps: number;\n status: FileUploadStatus;\n total: number;\n};\n\nconst IDLE_UPLOAD_STATE: Omit<FileUploadState, 'total'> = { error: null, loaded: 0, speedBps: 0, status: 'idle' };\n\nconst formatEta = (state: FileUploadState): string => {\n if (state.speedBps <= 0 || state.status !== 'uploading') return '';\n\n const remainingSeconds = Math.max(0, Math.round((state.total - state.loaded) / state.speedBps));\n\n if (remainingSeconds < 60) return `${remainingSeconds}s left`;\n\n return `${Math.round(remainingSeconds / 60)}m left`;\n};\n\n/**\n * Consumer-supplied transport — this component has no built-in network layer (zero-dependency,\n * transport-agnostic by design, same reasoning as `courier`'s own fetch-wrapping-only stance).\n * This function is the seam between the UI's upload lifecycle (progress, retry, per-file\n * isolation) and however the app actually moves bytes (`fetch`, `XMLHttpRequest`, a presigned S3\n * PUT, `@vielzeug/courier`, …).\n *\n * `resumeFrom` is a *hint*, not a guarantee: it's the byte offset the component last observed\n * via `onProgress` before the previous attempt failed (0 on a fresh upload). A transport that\n * supports byte ranges (e.g. an HTTP `Range`/`Content-Range` header, S3 multipart, tus) can use\n * it to genuinely resume from that point; a plain `fetch(url, { body: file })` can ignore it and\n * simply re-send the whole file — the UI still shows a resumed-from-N-bytes experience either\n * way, since the file itself was never dropped from memory.\n */\nexport type FileUploadFn = (\n file: File,\n ctx: { onProgress: (loaded: number, total: number) => void; resumeFrom: number; signal: AbortSignal },\n) => Promise<void>;\n\n// ── Queue ─────────────────────────────────────────────────────────────────────\n\nexport type FileQueueOptions = {\n accept: Readable<string | undefined>;\n disabled: Readable<boolean>;\n maxFiles: Readable<number>;\n maxSize: Readable<number>;\n multiple: Readable<boolean>;\n onChange: (files: File[], originalEvent?: Event) => void;\n onRemove: (file: File, files: File[], originalEvent?: Event) => void;\n onUploadError: (file: File, error: unknown) => void;\n onUploadProgress: (file: File, loaded: number, total: number) => void;\n onUploadSuccess: (file: File) => void;\n upload: Readable<FileUploadFn | undefined>;\n};\n\nexport type FileQueue = {\n addFiles(newFiles: File[], originalEvent?: Event): void;\n dispose(): void;\n readonly files: Readable<File[]>;\n fileState(file: File): FileUploadState;\n removeFile(file: File, originalEvent?: Event): void;\n /** Validates `newFile` (accept/max-size) and, if accepted, swaps it in for `oldFile` in place\n * and starts its upload. Returns whether the replacement was accepted. Also fires `onRemove`\n * for `oldFile` — a replace is a removal-and-add that happen to land in the same slot, and a\n * consumer listening only for removal (e.g. to clean up a server-side record) still needs to\n * hear that the old file is gone. */\n replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean;\n retryUpload(file: File): void;\n statusIconName(file: File): string;\n uploadMetaText(file: File): string;\n uploadPercent(file: File): number;\n};\n\n/**\n * Owns file selection *and* the opt-in upload lifecycle together — they were never really\n * separable (adding a file starts its upload; removing one must abort it; replacing one is both\n * at once). Independent of `html`/rendering, following the same shape as `datagrid`'s\n * `createDataGridControls` and `combobox`'s `combobox-options.ts`: a factory `file-input.ts`\n * wires into drag/drop/native-input events and the template, directly unit-testable without\n * mounting a component.\n *\n * Every file-level rule (accept, max-size, max-files, disabled) and every upload-lifecycle rule\n * (progress, retry-from-offset, per-file isolation) lives here in one place.\n */\nexport function createFileQueue(options: FileQueueOptions): FileQueue {\n const files = signal<File[]>([]);\n const stateSignals = new Map<File, ReturnType<typeof signal<FileUploadState>>>();\n const controllers = new Map<File, AbortController>();\n\n function stateSignal(file: File): ReturnType<typeof signal<FileUploadState>> {\n let s = stateSignals.get(file);\n\n if (!s) {\n s = signal<FileUploadState>({ ...IDLE_UPLOAD_STATE, total: file.size });\n stateSignals.set(file, s);\n }\n\n return s;\n }\n\n function fileState(file: File): FileUploadState {\n return stateSignal(file).value;\n }\n\n function patchState(file: File, patch: Partial<FileUploadState>): void {\n const s = stateSignal(file);\n\n s.value = { ...s.value, ...patch };\n }\n\n // Each file gets its own `AbortController` and its own promise chain — nothing here `await`s\n // another file's upload, so one file's rejection can never block, freeze, or cancel the others.\n function startUpload(file: File, resumeFrom = 0): void {\n if (options.disabled.value) return;\n\n const uploadFn = options.upload.value;\n\n if (!uploadFn) return;\n\n controllers.get(file)?.abort();\n\n const controller = new AbortController();\n\n controllers.set(file, controller);\n patchState(file, { error: null, loaded: resumeFrom, speedBps: 0, status: 'uploading', total: file.size });\n\n // Rolling (exponential-moving-average) speed estimate rather than a naive\n // `loaded / elapsedSinceStart` average — the latter drags heavily behind the file's actual\n // *current* rate right after a slow start or a mid-transfer stall.\n let lastSampleAt = performance.now();\n let lastSampleLoaded = resumeFrom;\n\n uploadFn(file, {\n onProgress: (loaded, total) => {\n if (controller.signal.aborted) return;\n\n const now = performance.now();\n const elapsedSeconds = (now - lastSampleAt) / 1000;\n const instantBps = elapsedSeconds > 0 ? Math.max(0, (loaded - lastSampleLoaded) / elapsedSeconds) : 0;\n const previousBps = fileState(file).speedBps;\n const speedBps = previousBps > 0 ? previousBps * 0.7 + instantBps * 0.3 : instantBps;\n\n lastSampleAt = now;\n lastSampleLoaded = loaded;\n patchState(file, { loaded, speedBps, total: total || file.size });\n options.onUploadProgress(file, loaded, total || file.size);\n },\n resumeFrom,\n signal: controller.signal,\n })\n .then(() => {\n if (controller.signal.aborted) return;\n\n patchState(file, { loaded: file.size, speedBps: 0, status: 'success' });\n announce(`${file.name} uploaded successfully.`);\n options.onUploadSuccess(file);\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n\n const message = error instanceof Error ? error.message : String(error);\n\n patchState(file, { error: message, speedBps: 0, status: 'error' });\n announce(`${file.name} failed to upload: ${message}`, { politeness: 'assertive' });\n options.onUploadError(file, error);\n });\n }\n\n // Resumes from the last byte offset this file actually reached, not from 0 — see\n // `FileUploadFn`'s doc comment on what \"resume\" honestly means when the transport is\n // consumer-supplied.\n function retryUpload(file: File): void {\n if (options.disabled.value) return;\n\n startUpload(file, fileState(file).loaded);\n }\n\n // Aborts + drops upload state for any file no longer in `files` — covers plain removal, a\n // non-`multiple` selection replacing the previous file, and `replaceFile()` swapping one File\n // for another. One cleanup path instead of duplicating it at every call site that can shrink\n // `files`.\n function dropOrphanedState(activeFiles: File[]): void {\n const keep = new Set(activeFiles);\n\n for (const file of stateSignals.keys()) {\n if (keep.has(file)) continue;\n\n controllers.get(file)?.abort();\n controllers.delete(file);\n stateSignals.delete(file);\n }\n }\n\n const filesWatch = watch(files, dropOrphanedState);\n\n function addFiles(newFiles: File[], originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n const isMultiple = options.multiple.value;\n let incoming = Array.from(newFiles);\n\n if (!isMultiple) incoming = incoming.slice(0, 1);\n\n const acceptList = parseAccept(options.accept.value);\n const maxSize = options.maxSize.value;\n\n incoming = incoming.filter((f) => matchesAccept(f, acceptList) && isFileSizeAllowed(f, maxSize));\n\n let updated: File[] = isMultiple ? [...files.value] : [];\n const added: File[] = [];\n\n for (const f of incoming) {\n if (!updated.includes(f)) {\n updated.push(f);\n added.push(f);\n }\n }\n\n const maxFiles = options.maxFiles.value;\n\n if (maxFiles > 0 && updated.length > maxFiles) updated = updated.slice(0, maxFiles);\n\n files.value = updated;\n options.onChange(files.value, originalEvent);\n\n for (const f of added) {\n if (files.value.includes(f)) startUpload(f);\n }\n }\n\n function removeFile(file: File, originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n files.value = files.value.filter((f) => f !== file);\n options.onRemove(file, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n }\n\n function replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean {\n if (options.disabled.value) return false;\n\n const acceptList = parseAccept(options.accept.value);\n\n if (!matchesAccept(newFile, acceptList) || !isFileSizeAllowed(newFile, options.maxSize.value)) return false;\n\n files.value = files.value.map((f) => (f === oldFile ? newFile : f));\n options.onRemove(oldFile, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n startUpload(newFile);\n\n return true;\n }\n\n function uploadPercent(file: File): number {\n const state = fileState(file);\n\n if (state.total <= 0) return 0;\n\n return Math.min(100, Math.round((state.loaded / state.total) * 100));\n }\n\n // Speed + ETA on one line — percent itself is rendered separately (e.g. `<ore-progress>`'s\n // own `label`), so this only needs the two metrics that wouldn't otherwise fit there.\n function uploadMetaText(file: File): string {\n const state = fileState(file);\n\n return [formatSpeed(state.speedBps), formatEta(state)].filter(Boolean).join(' · ');\n }\n\n function statusIconName(file: File): string {\n const status = fileState(file).status;\n\n if (status === 'success') return 'check';\n\n if (status === 'error') return 'alert-circle';\n\n return 'file';\n }\n\n function dispose(): void {\n filesWatch.dispose();\n\n for (const controller of controllers.values()) controller.abort();\n\n controllers.clear();\n stateSignals.clear();\n }\n\n return {\n addFiles,\n dispose,\n files,\n fileState,\n removeFile,\n replaceFile,\n retryUpload,\n statusIconName,\n uploadMetaText,\n uploadPercent,\n };\n}\n"],"mappings":"6IAQA,IAAa,EAAe,GAA0B,CACpD,GAAI,IAAU,EAAG,MAAO,MAExB,IAAM,EAAI,KACJ,EAAQ,CAAC,IAAK,KAAM,KAAM,KAAM,IAAI,EACpC,EAAI,KAAK,MAAM,KAAK,IAAI,CAAK,EAAI,KAAK,IAAI,CAAC,CAAC,EAElD,MAAO,GAAG,YAAY,EAAiB,GAAG,EAAC,CAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAM,IACrE,EAEM,GAAqB,EAAY,IAA6B,CAAC,GAAW,EAAK,MAAQ,EAEvF,EAAe,GAAoC,EAAiB,EAAI,GAAG,EAAY,CAAc,EAAE,IAAM,GAE7G,EAAe,GAA0C,EAAS,EAAO,MAAM,GAAG,CAAC,CAAC,IAAK,GAAM,EAAE,KAAK,CAAC,EAAI,CAAC,EAkB5G,EAAoD,CAAE,MAAO,KAAM,OAAQ,EAAG,SAAU,EAAG,OAAQ,MAAO,EAE1G,EAAa,GAAmC,CACpD,GAAI,EAAM,UAAY,GAAK,EAAM,SAAW,YAAa,MAAO,GAEhE,IAAM,EAAmB,KAAK,IAAI,EAAG,KAAK,OAAO,EAAM,MAAQ,EAAM,QAAU,EAAM,QAAQ,CAAC,EAI9F,OAFI,EAAmB,GAAW,GAAG,EAAiB,QAE/C,GAAG,KAAK,MAAM,EAAmB,EAAE,EAAE,OAC9C,EAkEA,SAAgB,EAAgB,EAAsC,CACpE,IAAM,GAAA,EAAQ,EAAA,OAAA,CAAe,CAAC,CAAC,EACzB,EAAe,IAAI,IACnB,EAAc,IAAI,IAExB,SAAS,EAAY,EAAwD,CAC3E,IAAI,EAAI,EAAa,IAAI,CAAI,EAO7B,OALK,IACH,GAAA,EAAI,EAAA,OAAA,CAAwB,CAAE,GAAG,EAAmB,MAAO,EAAK,IAAK,CAAC,EACtE,EAAa,IAAI,EAAM,CAAC,GAGnB,CACT,CAEA,SAAS,EAAU,EAA6B,CAC9C,OAAO,EAAY,CAAI,CAAC,CAAC,KAC3B,CAEA,SAAS,EAAW,EAAY,EAAuC,CACrE,IAAM,EAAI,EAAY,CAAI,EAE1B,EAAE,MAAQ,CAAE,GAAG,EAAE,MAAO,GAAG,CAAM,CACnC,CAIA,SAAS,EAAY,EAAY,EAAa,EAAS,CACrD,GAAI,EAAQ,SAAS,MAAO,OAE5B,IAAM,EAAW,EAAQ,OAAO,MAEhC,GAAI,CAAC,EAAU,OAEf,EAAY,IAAI,CAAI,CAAC,EAAE,MAAM,EAE7B,IAAM,EAAa,IAAI,gBAEvB,EAAY,IAAI,EAAM,CAAU,EAChC,EAAW,EAAM,CAAE,MAAO,KAAM,OAAQ,EAAY,SAAU,EAAG,OAAQ,YAAa,MAAO,EAAK,IAAK,CAAC,EAKxG,IAAI,EAAe,YAAY,IAAI,EAC/B,EAAmB,EAEvB,EAAS,EAAM,CACb,YAAa,EAAQ,IAAU,CAC7B,GAAI,EAAW,OAAO,QAAS,OAE/B,IAAM,EAAM,YAAY,IAAI,EACtB,GAAkB,EAAM,GAAgB,IACxC,EAAa,EAAiB,EAAI,KAAK,IAAI,GAAI,EAAS,GAAoB,CAAc,EAAI,EAC9F,EAAc,EAAU,CAAI,CAAC,CAAC,SAC9B,EAAW,EAAc,EAAI,EAAc,GAAM,EAAa,GAAM,EAE1E,EAAe,EACf,EAAmB,EACnB,EAAW,EAAM,CAAE,SAAQ,WAAU,MAAO,GAAS,EAAK,IAAK,CAAC,EAChE,EAAQ,iBAAiB,EAAM,EAAQ,GAAS,EAAK,IAAI,CAC3D,EACA,aACA,OAAQ,EAAW,MACrB,CAAC,CAAC,CACC,SAAW,CACN,EAAW,OAAO,UAEtB,EAAW,EAAM,CAAE,OAAQ,EAAK,KAAM,SAAU,EAAG,OAAQ,SAAU,CAAC,EACtE,EAAA,SAAS,GAAG,EAAK,KAAK,wBAAwB,EAC9C,EAAQ,gBAAgB,CAAI,EAC9B,CAAC,CAAC,CACD,MAAO,GAAmB,CACzB,GAAI,EAAW,OAAO,QAAS,OAE/B,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAErE,EAAW,EAAM,CAAE,MAAO,EAAS,SAAU,EAAG,OAAQ,OAAQ,CAAC,EACjE,EAAA,SAAS,GAAG,EAAK,KAAK,qBAAqB,IAAW,CAAE,WAAY,WAAY,CAAC,EACjF,EAAQ,cAAc,EAAM,CAAK,CACnC,CAAC,CACL,CAKA,SAAS,EAAY,EAAkB,CACjC,EAAQ,SAAS,OAErB,EAAY,EAAM,EAAU,CAAI,CAAC,CAAC,MAAM,CAC1C,CAMA,SAAS,EAAkB,EAA2B,CACpD,IAAM,EAAO,IAAI,IAAI,CAAW,EAEhC,IAAK,IAAM,KAAQ,EAAa,KAAK,EAC/B,EAAK,IAAI,CAAI,IAEjB,EAAY,IAAI,CAAI,CAAC,EAAE,MAAM,EAC7B,EAAY,OAAO,CAAI,EACvB,EAAa,OAAO,CAAI,EAE5B,CAEA,IAAM,GAAA,EAAa,EAAA,MAAA,CAAM,EAAO,CAAiB,EAEjD,SAAS,EAAS,EAAkB,EAA6B,CAC/D,GAAI,EAAQ,SAAS,MAAO,OAE5B,IAAM,EAAa,EAAQ,SAAS,MAChC,EAAW,MAAM,KAAK,CAAQ,EAE7B,IAAY,EAAW,EAAS,MAAM,EAAG,CAAC,GAE/C,IAAM,EAAa,EAAY,EAAQ,OAAO,KAAK,EAC7C,EAAU,EAAQ,QAAQ,MAEhC,EAAW,EAAS,OAAQ,IAAA,EAAM,EAAA,cAAA,CAAc,EAAG,CAAU,GAAK,EAAkB,EAAG,CAAO,CAAC,EAE/F,IAAI,EAAkB,EAAa,CAAC,GAAG,EAAM,KAAK,EAAI,CAAC,EACjD,EAAgB,CAAC,EAEvB,IAAK,IAAM,KAAK,EACT,EAAQ,SAAS,CAAC,IACrB,EAAQ,KAAK,CAAC,EACd,EAAM,KAAK,CAAC,GAIhB,IAAM,EAAW,EAAQ,SAAS,MAE9B,EAAW,GAAK,EAAQ,OAAS,IAAU,EAAU,EAAQ,MAAM,EAAG,CAAQ,GAElF,EAAM,MAAQ,EACd,EAAQ,SAAS,EAAM,MAAO,CAAa,EAE3C,IAAK,IAAM,KAAK,EACV,EAAM,MAAM,SAAS,CAAC,GAAG,EAAY,CAAC,CAE9C,CAEA,SAAS,EAAW,EAAY,EAA6B,CACvD,EAAQ,SAAS,QAErB,EAAM,MAAQ,EAAM,MAAM,OAAQ,GAAM,IAAM,CAAI,EAClD,EAAQ,SAAS,EAAM,EAAM,MAAO,CAAa,EACjD,EAAQ,SAAS,EAAM,MAAO,CAAa,EAC7C,CAEA,SAAS,EAAY,EAAe,EAAe,EAAgC,CACjF,GAAI,EAAQ,SAAS,MAAO,MAAO,GAEnC,IAAM,EAAa,EAAY,EAAQ,OAAO,KAAK,EASnD,MAPI,EAAA,EAAC,EAAA,cAAA,CAAc,EAAS,CAAU,GAAK,CAAC,EAAkB,EAAS,EAAQ,QAAQ,KAAK,EAAU,IAEtG,EAAM,MAAQ,EAAM,MAAM,IAAK,GAAO,IAAM,EAAU,EAAU,CAAE,EAClE,EAAQ,SAAS,EAAS,EAAM,MAAO,CAAa,EACpD,EAAQ,SAAS,EAAM,MAAO,CAAa,EAC3C,EAAY,CAAO,EAEZ,GACT,CAEA,SAAS,EAAc,EAAoB,CACzC,IAAM,EAAQ,EAAU,CAAI,EAI5B,OAFI,EAAM,OAAS,EAAU,EAEtB,KAAK,IAAI,IAAK,KAAK,MAAO,EAAM,OAAS,EAAM,MAAS,GAAG,CAAC,CACrE,CAIA,SAAS,EAAe,EAAoB,CAC1C,IAAM,EAAQ,EAAU,CAAI,EAE5B,MAAO,CAAC,EAAY,EAAM,QAAQ,EAAG,EAAU,CAAK,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,CACnF,CAEA,SAAS,EAAe,EAAoB,CAC1C,IAAM,EAAS,EAAU,CAAI,CAAC,CAAC,OAM/B,OAJI,IAAW,UAAkB,QAE7B,IAAW,QAAgB,eAExB,MACT,CAEA,SAAS,GAAgB,CACvB,EAAW,QAAQ,EAEnB,IAAK,IAAM,KAAc,EAAY,OAAO,EAAG,EAAW,MAAM,EAEhE,EAAY,MAAM,EAClB,EAAa,MAAM,CACrB,CAEA,MAAO,CACL,WACA,UACA,QACA,YACA,aACA,cACA,cACA,iBACA,iBACA,eACF,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input-upload.d.ts","sourceRoot":"","sources":["../../../src/inputs/file-input/file-input-upload.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"file-input-upload.d.ts","sourceRoot":"","sources":["../../../src/inputs/file-input/file-input-upload.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAOzD,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,MAQ3C,CAAC;AAUF;gEACgE;AAChE,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;AAE1E;iGACiG;AACjG,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAcF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE;IAAE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,KAClG,OAAO,CAAC,IAAI,CAAC,CAAC;AAInB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC5B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,aAAa,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACzD,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,aAAa,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACrE,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE,eAAe,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,QAAQ,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACxD,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,eAAe,CAAC;IACvC,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACpD;;;;yCAIqC;IACrC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IAC1E,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;IACnC,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;IACnC,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAwNpE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { announce as e } from "../../
|
|
2
|
-
import { signal as t
|
|
1
|
+
import { announce as e } from "../../core/announcer.js";
|
|
2
|
+
import { signal as t } from "@vielzeug/ripple";
|
|
3
|
+
import { watch as n } from "@vielzeug/ripple/watch";
|
|
3
4
|
import { matchesAccept as r } from "@vielzeug/dnd";
|
|
4
5
|
//#region src/inputs/file-input/file-input-upload.ts
|
|
5
6
|
var i = (e) => {
|
|
@@ -107,7 +108,9 @@ function u(i) {
|
|
|
107
108
|
i.disabled.value || (u.value = u.value.filter((t) => t !== e), i.onRemove(e, u.value, t), i.onChange(u.value, t));
|
|
108
109
|
}
|
|
109
110
|
function S(e, t, n) {
|
|
110
|
-
|
|
111
|
+
if (i.disabled.value) return !1;
|
|
112
|
+
let o = s(i.accept.value);
|
|
113
|
+
return !r(t, o) || !a(t, i.maxSize.value) ? !1 : (u.value = u.value.map((n) => n === e ? t : n), i.onRemove(e, u.value, n), i.onChange(u.value, n), g(t), !0);
|
|
111
114
|
}
|
|
112
115
|
function C(e) {
|
|
113
116
|
let t = m(e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input-upload.js","names":[],"sources":["../../../src/inputs/file-input/file-input-upload.ts"],"sourcesContent":["import { matchesAccept } from '@vielzeug/dnd';\nimport { type Readable, signal, watch } from '@vielzeug/ripple';\n\nimport { announce } from '../../headless';\n\n// ── Byte/speed formatting ────────────────────────────────────────────────────\n\nexport const formatBytes = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n};\n\nconst isFileSizeAllowed = (file: File, maxSize: number): boolean => !maxSize || file.size <= maxSize;\n\nconst formatSpeed = (bytesPerSecond: number): string => (bytesPerSecond > 0 ? `${formatBytes(bytesPerSecond)}/s` : '');\n\nconst parseAccept = (accept: string | undefined): string[] => (accept ? accept.split(',').map((t) => t.trim()) : []);\n\n// ── Upload lifecycle types ───────────────────────────────────────────────────\n\n/** Upload lifecycle status for a single file. `idle` covers both \"no `upload` handler wired up\"\n * (picker-only mode, fully supported) and \"not started yet\". */\nexport type FileUploadStatus = 'error' | 'idle' | 'success' | 'uploading';\n\n/** Per-file upload snapshot. One reactive signal per file — see `createFileQueue` — not one\n * signal holding a map, so a progress tick for one file never invalidates another's bindings. */\nexport type FileUploadState = {\n error: string | null;\n loaded: number;\n speedBps: number;\n status: FileUploadStatus;\n total: number;\n};\n\nconst IDLE_UPLOAD_STATE: Omit<FileUploadState, 'total'> = { error: null, loaded: 0, speedBps: 0, status: 'idle' };\n\nconst formatEta = (state: FileUploadState): string => {\n if (state.speedBps <= 0 || state.status !== 'uploading') return '';\n\n const remainingSeconds = Math.max(0, Math.round((state.total - state.loaded) / state.speedBps));\n\n if (remainingSeconds < 60) return `${remainingSeconds}s left`;\n\n return `${Math.round(remainingSeconds / 60)}m left`;\n};\n\n/**\n * Consumer-supplied transport — this component has no built-in network layer (zero-dependency,\n * transport-agnostic by design, same reasoning as `courier`'s own fetch-wrapping-only stance).\n * This function is the seam between the UI's upload lifecycle (progress, retry, per-file\n * isolation) and however the app actually moves bytes (`fetch`, `XMLHttpRequest`, a presigned S3\n * PUT, `@vielzeug/courier`, …).\n *\n * `resumeFrom` is a *hint*, not a guarantee: it's the byte offset the component last observed\n * via `onProgress` before the previous attempt failed (0 on a fresh upload). A transport that\n * supports byte ranges (e.g. an HTTP `Range`/`Content-Range` header, S3 multipart, tus) can use\n * it to genuinely resume from that point; a plain `fetch(url, { body: file })` can ignore it and\n * simply re-send the whole file — the UI still shows a resumed-from-N-bytes experience either\n * way, since the file itself was never dropped from memory.\n */\nexport type FileUploadFn = (\n file: File,\n ctx: { onProgress: (loaded: number, total: number) => void; resumeFrom: number; signal: AbortSignal },\n) => Promise<void>;\n\n// ── Queue ─────────────────────────────────────────────────────────────────────\n\nexport type FileQueueOptions = {\n accept: Readable<string | undefined>;\n disabled: Readable<boolean>;\n maxFiles: Readable<number>;\n maxSize: Readable<number>;\n multiple: Readable<boolean>;\n onChange: (files: File[], originalEvent?: Event) => void;\n onRemove: (file: File, files: File[], originalEvent?: Event) => void;\n onUploadError: (file: File, error: unknown) => void;\n onUploadProgress: (file: File, loaded: number, total: number) => void;\n onUploadSuccess: (file: File) => void;\n upload: Readable<FileUploadFn | undefined>;\n};\n\nexport type FileQueue = {\n addFiles(newFiles: File[], originalEvent?: Event): void;\n dispose(): void;\n readonly files: Readable<File[]>;\n fileState(file: File): FileUploadState;\n removeFile(file: File, originalEvent?: Event): void;\n /** Validates `newFile` (accept/max-size) and, if accepted, swaps it in for `oldFile` in place\n * and starts its upload. Returns whether the replacement was accepted. Also fires `onRemove`\n * for `oldFile` — a replace is a removal-and-add that happen to land in the same slot, and a\n * consumer listening only for removal (e.g. to clean up a server-side record) still needs to\n * hear that the old file is gone. */\n replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean;\n retryUpload(file: File): void;\n statusIconName(file: File): string;\n uploadMetaText(file: File): string;\n uploadPercent(file: File): number;\n};\n\n/**\n * Owns file selection *and* the opt-in upload lifecycle together — they were never really\n * separable (adding a file starts its upload; removing one must abort it; replacing one is both\n * at once). Independent of `html`/rendering, following the same shape as `datagrid`'s\n * `createDataGridControls` and `combobox`'s `combobox-options.ts`: a factory `file-input.ts`\n * wires into drag/drop/native-input events and the template, directly unit-testable without\n * mounting a component.\n *\n * Every file-level rule (accept, max-size, max-files, disabled) and every upload-lifecycle rule\n * (progress, retry-from-offset, per-file isolation) lives here in one place.\n */\nexport function createFileQueue(options: FileQueueOptions): FileQueue {\n const files = signal<File[]>([]);\n const stateSignals = new Map<File, ReturnType<typeof signal<FileUploadState>>>();\n const controllers = new Map<File, AbortController>();\n\n function stateSignal(file: File): ReturnType<typeof signal<FileUploadState>> {\n let s = stateSignals.get(file);\n\n if (!s) {\n s = signal<FileUploadState>({ ...IDLE_UPLOAD_STATE, total: file.size });\n stateSignals.set(file, s);\n }\n\n return s;\n }\n\n function fileState(file: File): FileUploadState {\n return stateSignal(file).value;\n }\n\n function patchState(file: File, patch: Partial<FileUploadState>): void {\n const s = stateSignal(file);\n\n s.value = { ...s.value, ...patch };\n }\n\n // Each file gets its own `AbortController` and its own promise chain — nothing here `await`s\n // another file's upload, so one file's rejection can never block, freeze, or cancel the others.\n function startUpload(file: File, resumeFrom = 0): void {\n if (options.disabled.value) return;\n\n const uploadFn = options.upload.value;\n\n if (!uploadFn) return;\n\n controllers.get(file)?.abort();\n\n const controller = new AbortController();\n\n controllers.set(file, controller);\n patchState(file, { error: null, loaded: resumeFrom, speedBps: 0, status: 'uploading', total: file.size });\n\n // Rolling (exponential-moving-average) speed estimate rather than a naive\n // `loaded / elapsedSinceStart` average — the latter drags heavily behind the file's actual\n // *current* rate right after a slow start or a mid-transfer stall.\n let lastSampleAt = performance.now();\n let lastSampleLoaded = resumeFrom;\n\n uploadFn(file, {\n onProgress: (loaded, total) => {\n if (controller.signal.aborted) return;\n\n const now = performance.now();\n const elapsedSeconds = (now - lastSampleAt) / 1000;\n const instantBps = elapsedSeconds > 0 ? Math.max(0, (loaded - lastSampleLoaded) / elapsedSeconds) : 0;\n const previousBps = fileState(file).speedBps;\n const speedBps = previousBps > 0 ? previousBps * 0.7 + instantBps * 0.3 : instantBps;\n\n lastSampleAt = now;\n lastSampleLoaded = loaded;\n patchState(file, { loaded, speedBps, total: total || file.size });\n options.onUploadProgress(file, loaded, total || file.size);\n },\n resumeFrom,\n signal: controller.signal,\n })\n .then(() => {\n if (controller.signal.aborted) return;\n\n patchState(file, { loaded: file.size, speedBps: 0, status: 'success' });\n announce(`${file.name} uploaded successfully.`);\n options.onUploadSuccess(file);\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n\n const message = error instanceof Error ? error.message : String(error);\n\n patchState(file, { error: message, speedBps: 0, status: 'error' });\n announce(`${file.name} failed to upload: ${message}`, { politeness: 'assertive' });\n options.onUploadError(file, error);\n });\n }\n\n // Resumes from the last byte offset this file actually reached, not from 0 — see\n // `FileUploadFn`'s doc comment on what \"resume\" honestly means when the transport is\n // consumer-supplied.\n function retryUpload(file: File): void {\n if (options.disabled.value) return;\n\n startUpload(file, fileState(file).loaded);\n }\n\n // Aborts + drops upload state for any file no longer in `files` — covers plain removal, a\n // non-`multiple` selection replacing the previous file, and `replaceFile()` swapping one File\n // for another. One cleanup path instead of duplicating it at every call site that can shrink\n // `files`.\n function dropOrphanedState(activeFiles: File[]): void {\n const keep = new Set(activeFiles);\n\n for (const file of stateSignals.keys()) {\n if (keep.has(file)) continue;\n\n controllers.get(file)?.abort();\n controllers.delete(file);\n stateSignals.delete(file);\n }\n }\n\n const filesWatch = watch(files, dropOrphanedState);\n\n function addFiles(newFiles: File[], originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n const isMultiple = options.multiple.value;\n let incoming = Array.from(newFiles);\n\n if (!isMultiple) incoming = incoming.slice(0, 1);\n\n const acceptList = parseAccept(options.accept.value);\n const maxSize = options.maxSize.value;\n\n incoming = incoming.filter((f) => matchesAccept(f, acceptList) && isFileSizeAllowed(f, maxSize));\n\n let updated: File[] = isMultiple ? [...files.value] : [];\n const added: File[] = [];\n\n for (const f of incoming) {\n if (!updated.includes(f)) {\n updated.push(f);\n added.push(f);\n }\n }\n\n const maxFiles = options.maxFiles.value;\n\n if (maxFiles > 0 && updated.length > maxFiles) updated = updated.slice(0, maxFiles);\n\n files.value = updated;\n options.onChange(files.value, originalEvent);\n\n for (const f of added) {\n if (files.value.includes(f)) startUpload(f);\n }\n }\n\n function removeFile(file: File, originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n files.value = files.value.filter((f) => f !== file);\n options.onRemove(file, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n }\n\n function replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean {\n if (options.disabled.value) return false;\n\n const acceptList = parseAccept(options.accept.value);\n\n if (!matchesAccept(newFile, acceptList) || !isFileSizeAllowed(newFile, options.maxSize.value)) return false;\n\n files.value = files.value.map((f) => (f === oldFile ? newFile : f));\n options.onRemove(oldFile, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n startUpload(newFile);\n\n return true;\n }\n\n function uploadPercent(file: File): number {\n const state = fileState(file);\n\n if (state.total <= 0) return 0;\n\n return Math.min(100, Math.round((state.loaded / state.total) * 100));\n }\n\n // Speed + ETA on one line — percent itself is rendered separately (e.g. `<ore-progress>`'s\n // own `label`), so this only needs the two metrics that wouldn't otherwise fit there.\n function uploadMetaText(file: File): string {\n const state = fileState(file);\n\n return [formatSpeed(state.speedBps), formatEta(state)].filter(Boolean).join(' · ');\n }\n\n function statusIconName(file: File): string {\n const status = fileState(file).status;\n\n if (status === 'success') return 'check';\n\n if (status === 'error') return 'alert-circle';\n\n return 'file';\n }\n\n function dispose(): void {\n filesWatch.dispose();\n\n for (const controller of controllers.values()) controller.abort();\n\n controllers.clear();\n stateSignals.clear();\n }\n\n return {\n addFiles,\n dispose,\n files,\n fileState,\n removeFile,\n replaceFile,\n retryUpload,\n statusIconName,\n uploadMetaText,\n uploadPercent,\n };\n}\n"],"mappings":";;;;AAOA,IAAa,KAAe,MAA0B;CACpD,IAAI,MAAU,GAAG,OAAO;CAExB,IAAM,IAAI,MACJ,IAAQ;EAAC;EAAK;EAAM;EAAM;EAAM;CAAI,GACpC,IAAI,KAAK,MAAM,KAAK,IAAI,CAAK,IAAI,KAAK,IAAI,CAAC,CAAC;CAElD,OAAO,GAAG,YAAY,IAAiB,KAAG,EAAC,CAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAM;AACrE,GAEM,KAAqB,GAAY,MAA6B,CAAC,KAAW,EAAK,QAAQ,GAEvF,KAAe,MAAoC,IAAiB,IAAI,GAAG,EAAY,CAAc,EAAE,MAAM,IAE7G,KAAe,MAA0C,IAAS,EAAO,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,GAkB5G,IAAoD;CAAE,OAAO;CAAM,QAAQ;CAAG,UAAU;CAAG,QAAQ;AAAO,GAE1G,KAAa,MAAmC;CACpD,IAAI,EAAM,YAAY,KAAK,EAAM,WAAW,aAAa,OAAO;CAEhE,IAAM,IAAmB,KAAK,IAAI,GAAG,KAAK,OAAO,EAAM,QAAQ,EAAM,UAAU,EAAM,QAAQ,CAAC;CAI9F,OAFI,IAAmB,KAAW,GAAG,EAAiB,UAE/C,GAAG,KAAK,MAAM,IAAmB,EAAE,EAAE;AAC9C;AAkEA,SAAgB,EAAgB,GAAsC;CACpE,IAAM,IAAQ,EAAe,CAAC,CAAC,GACzB,oBAAe,IAAI,IAAsD,GACzE,oBAAc,IAAI,IAA2B;CAEnD,SAAS,EAAY,GAAwD;EAC3E,IAAI,IAAI,EAAa,IAAI,CAAI;EAO7B,OALK,MACH,IAAI,EAAwB;GAAE,GAAG;GAAmB,OAAO,EAAK;EAAK,CAAC,GACtE,EAAa,IAAI,GAAM,CAAC,IAGnB;CACT;CAEA,SAAS,EAAU,GAA6B;EAC9C,OAAO,EAAY,CAAI,CAAC,CAAC;CAC3B;CAEA,SAAS,EAAW,GAAY,GAAuC;EACrE,IAAM,IAAI,EAAY,CAAI;EAE1B,EAAE,QAAQ;GAAE,GAAG,EAAE;GAAO,GAAG;EAAM;CACnC;CAIA,SAAS,EAAY,GAAY,IAAa,GAAS;EACrD,IAAI,EAAQ,SAAS,OAAO;EAE5B,IAAM,IAAW,EAAQ,OAAO;EAEhC,IAAI,CAAC,GAAU;EAEf,EAAY,IAAI,CAAI,CAAC,EAAE,MAAM;EAE7B,IAAM,IAAa,IAAI,gBAAgB;EAGvC,AADA,EAAY,IAAI,GAAM,CAAU,GAChC,EAAW,GAAM;GAAE,OAAO;GAAM,QAAQ;GAAY,UAAU;GAAG,QAAQ;GAAa,OAAO,EAAK;EAAK,CAAC;EAKxG,IAAI,IAAe,YAAY,IAAI,GAC/B,IAAmB;EAEvB,EAAS,GAAM;GACb,aAAa,GAAQ,MAAU;IAC7B,IAAI,EAAW,OAAO,SAAS;IAE/B,IAAM,IAAM,YAAY,IAAI,GACtB,KAAkB,IAAM,KAAgB,KACxC,IAAa,IAAiB,IAAI,KAAK,IAAI,IAAI,IAAS,KAAoB,CAAc,IAAI,GAC9F,IAAc,EAAU,CAAI,CAAC,CAAC,UAC9B,IAAW,IAAc,IAAI,IAAc,KAAM,IAAa,KAAM;IAK1E,AAHA,IAAe,GACf,IAAmB,GACnB,EAAW,GAAM;KAAE;KAAQ;KAAU,OAAO,KAAS,EAAK;IAAK,CAAC,GAChE,EAAQ,iBAAiB,GAAM,GAAQ,KAAS,EAAK,IAAI;GAC3D;GACA;GACA,QAAQ,EAAW;EACrB,CAAC,CAAC,CACC,WAAW;GACN,EAAW,OAAO,YAEtB,EAAW,GAAM;IAAE,QAAQ,EAAK;IAAM,UAAU;IAAG,QAAQ;GAAU,CAAC,GACtE,EAAS,GAAG,EAAK,KAAK,wBAAwB,GAC9C,EAAQ,gBAAgB,CAAI;EAC9B,CAAC,CAAC,CACD,OAAO,MAAmB;GACzB,IAAI,EAAW,OAAO,SAAS;GAE/B,IAAM,IAAU,aAAiB,QAAQ,EAAM,UAAU,OAAO,CAAK;GAIrE,AAFA,EAAW,GAAM;IAAE,OAAO;IAAS,UAAU;IAAG,QAAQ;GAAQ,CAAC,GACjE,EAAS,GAAG,EAAK,KAAK,qBAAqB,KAAW,EAAE,YAAY,YAAY,CAAC,GACjF,EAAQ,cAAc,GAAM,CAAK;EACnC,CAAC;CACL;CAKA,SAAS,EAAY,GAAkB;EACjC,EAAQ,SAAS,SAErB,EAAY,GAAM,EAAU,CAAI,CAAC,CAAC,MAAM;CAC1C;CAMA,SAAS,EAAkB,GAA2B;EACpD,IAAM,IAAO,IAAI,IAAI,CAAW;EAEhC,KAAK,IAAM,KAAQ,EAAa,KAAK,GAC/B,EAAK,IAAI,CAAI,MAEjB,EAAY,IAAI,CAAI,CAAC,EAAE,MAAM,GAC7B,EAAY,OAAO,CAAI,GACvB,EAAa,OAAO,CAAI;CAE5B;CAEA,IAAM,IAAa,EAAM,GAAO,CAAiB;CAEjD,SAAS,EAAS,GAAkB,GAA6B;EAC/D,IAAI,EAAQ,SAAS,OAAO;EAE5B,IAAM,IAAa,EAAQ,SAAS,OAChC,IAAW,MAAM,KAAK,CAAQ;EAElC,AAAK,MAAY,IAAW,EAAS,MAAM,GAAG,CAAC;EAE/C,IAAM,IAAa,EAAY,EAAQ,OAAO,KAAK,GAC7C,IAAU,EAAQ,QAAQ;EAEhC,IAAW,EAAS,QAAQ,MAAM,EAAc,GAAG,CAAU,KAAK,EAAkB,GAAG,CAAO,CAAC;EAE/F,IAAI,IAAkB,IAAa,CAAC,GAAG,EAAM,KAAK,IAAI,CAAC,GACjD,IAAgB,CAAC;EAEvB,KAAK,IAAM,KAAK,GACd,AAAK,EAAQ,SAAS,CAAC,MACrB,EAAQ,KAAK,CAAC,GACd,EAAM,KAAK,CAAC;EAIhB,IAAM,IAAW,EAAQ,SAAS;EAKlC,AAHI,IAAW,KAAK,EAAQ,SAAS,MAAU,IAAU,EAAQ,MAAM,GAAG,CAAQ,IAElF,EAAM,QAAQ,GACd,EAAQ,SAAS,EAAM,OAAO,CAAa;EAE3C,KAAK,IAAM,KAAK,GACd,AAAI,EAAM,MAAM,SAAS,CAAC,KAAG,EAAY,CAAC;CAE9C;CAEA,SAAS,EAAW,GAAY,GAA6B;EACvD,EAAQ,SAAS,UAErB,EAAM,QAAQ,EAAM,MAAM,QAAQ,MAAM,MAAM,CAAI,GAClD,EAAQ,SAAS,GAAM,EAAM,OAAO,CAAa,GACjD,EAAQ,SAAS,EAAM,OAAO,CAAa;CAC7C;CAEA,SAAS,EAAY,GAAe,GAAe,GAAgC;EAYjF,OAXI,EAAQ,SAAS,SAIjB,CAAC,EAAc,GAFA,EAAY,EAAQ,OAAO,KAElB,CAAU,KAAK,CAAC,EAAkB,GAAS,EAAQ,QAAQ,KAAK,IAAU,MAEtG,EAAM,QAAQ,EAAM,MAAM,KAAK,MAAO,MAAM,IAAU,IAAU,CAAE,GAClE,EAAQ,SAAS,GAAS,EAAM,OAAO,CAAa,GACpD,EAAQ,SAAS,EAAM,OAAO,CAAa,GAC3C,EAAY,CAAO,GAEZ;CACT;CAEA,SAAS,EAAc,GAAoB;EACzC,IAAM,IAAQ,EAAU,CAAI;EAI5B,OAFI,EAAM,SAAS,IAAU,IAEtB,KAAK,IAAI,KAAK,KAAK,MAAO,EAAM,SAAS,EAAM,QAAS,GAAG,CAAC;CACrE;CAIA,SAAS,EAAe,GAAoB;EAC1C,IAAM,IAAQ,EAAU,CAAI;EAE5B,OAAO,CAAC,EAAY,EAAM,QAAQ,GAAG,EAAU,CAAK,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK;CACnF;CAEA,SAAS,EAAe,GAAoB;EAC1C,IAAM,IAAS,EAAU,CAAI,CAAC,CAAC;EAM/B,OAJI,MAAW,YAAkB,UAE7B,MAAW,UAAgB,iBAExB;CACT;CAEA,SAAS,IAAgB;EACvB,EAAW,QAAQ;EAEnB,KAAK,IAAM,KAAc,EAAY,OAAO,GAAG,EAAW,MAAM;EAGhE,AADA,EAAY,MAAM,GAClB,EAAa,MAAM;CACrB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"file-input-upload.js","names":[],"sources":["../../../src/inputs/file-input/file-input-upload.ts"],"sourcesContent":["import { matchesAccept } from '@vielzeug/dnd';\nimport { type Readable, signal } from '@vielzeug/ripple';\nimport { watch } from '@vielzeug/ripple/watch';\n\nimport { announce } from '../../core';\n\n// ── Byte/speed formatting ────────────────────────────────────────────────────\n\nexport const formatBytes = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n};\n\nconst isFileSizeAllowed = (file: File, maxSize: number): boolean => !maxSize || file.size <= maxSize;\n\nconst formatSpeed = (bytesPerSecond: number): string => (bytesPerSecond > 0 ? `${formatBytes(bytesPerSecond)}/s` : '');\n\nconst parseAccept = (accept: string | undefined): string[] => (accept ? accept.split(',').map((t) => t.trim()) : []);\n\n// ── Upload lifecycle types ───────────────────────────────────────────────────\n\n/** Upload lifecycle status for a single file. `idle` covers both \"no `upload` handler wired up\"\n * (picker-only mode, fully supported) and \"not started yet\". */\nexport type FileUploadStatus = 'error' | 'idle' | 'success' | 'uploading';\n\n/** Per-file upload snapshot. One reactive signal per file — see `createFileQueue` — not one\n * signal holding a map, so a progress tick for one file never invalidates another's bindings. */\nexport type FileUploadState = {\n error: string | null;\n loaded: number;\n speedBps: number;\n status: FileUploadStatus;\n total: number;\n};\n\nconst IDLE_UPLOAD_STATE: Omit<FileUploadState, 'total'> = { error: null, loaded: 0, speedBps: 0, status: 'idle' };\n\nconst formatEta = (state: FileUploadState): string => {\n if (state.speedBps <= 0 || state.status !== 'uploading') return '';\n\n const remainingSeconds = Math.max(0, Math.round((state.total - state.loaded) / state.speedBps));\n\n if (remainingSeconds < 60) return `${remainingSeconds}s left`;\n\n return `${Math.round(remainingSeconds / 60)}m left`;\n};\n\n/**\n * Consumer-supplied transport — this component has no built-in network layer (zero-dependency,\n * transport-agnostic by design, same reasoning as `courier`'s own fetch-wrapping-only stance).\n * This function is the seam between the UI's upload lifecycle (progress, retry, per-file\n * isolation) and however the app actually moves bytes (`fetch`, `XMLHttpRequest`, a presigned S3\n * PUT, `@vielzeug/courier`, …).\n *\n * `resumeFrom` is a *hint*, not a guarantee: it's the byte offset the component last observed\n * via `onProgress` before the previous attempt failed (0 on a fresh upload). A transport that\n * supports byte ranges (e.g. an HTTP `Range`/`Content-Range` header, S3 multipart, tus) can use\n * it to genuinely resume from that point; a plain `fetch(url, { body: file })` can ignore it and\n * simply re-send the whole file — the UI still shows a resumed-from-N-bytes experience either\n * way, since the file itself was never dropped from memory.\n */\nexport type FileUploadFn = (\n file: File,\n ctx: { onProgress: (loaded: number, total: number) => void; resumeFrom: number; signal: AbortSignal },\n) => Promise<void>;\n\n// ── Queue ─────────────────────────────────────────────────────────────────────\n\nexport type FileQueueOptions = {\n accept: Readable<string | undefined>;\n disabled: Readable<boolean>;\n maxFiles: Readable<number>;\n maxSize: Readable<number>;\n multiple: Readable<boolean>;\n onChange: (files: File[], originalEvent?: Event) => void;\n onRemove: (file: File, files: File[], originalEvent?: Event) => void;\n onUploadError: (file: File, error: unknown) => void;\n onUploadProgress: (file: File, loaded: number, total: number) => void;\n onUploadSuccess: (file: File) => void;\n upload: Readable<FileUploadFn | undefined>;\n};\n\nexport type FileQueue = {\n addFiles(newFiles: File[], originalEvent?: Event): void;\n dispose(): void;\n readonly files: Readable<File[]>;\n fileState(file: File): FileUploadState;\n removeFile(file: File, originalEvent?: Event): void;\n /** Validates `newFile` (accept/max-size) and, if accepted, swaps it in for `oldFile` in place\n * and starts its upload. Returns whether the replacement was accepted. Also fires `onRemove`\n * for `oldFile` — a replace is a removal-and-add that happen to land in the same slot, and a\n * consumer listening only for removal (e.g. to clean up a server-side record) still needs to\n * hear that the old file is gone. */\n replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean;\n retryUpload(file: File): void;\n statusIconName(file: File): string;\n uploadMetaText(file: File): string;\n uploadPercent(file: File): number;\n};\n\n/**\n * Owns file selection *and* the opt-in upload lifecycle together — they were never really\n * separable (adding a file starts its upload; removing one must abort it; replacing one is both\n * at once). Independent of `html`/rendering, following the same shape as `datagrid`'s\n * `createDataGridControls` and `combobox`'s `combobox-options.ts`: a factory `file-input.ts`\n * wires into drag/drop/native-input events and the template, directly unit-testable without\n * mounting a component.\n *\n * Every file-level rule (accept, max-size, max-files, disabled) and every upload-lifecycle rule\n * (progress, retry-from-offset, per-file isolation) lives here in one place.\n */\nexport function createFileQueue(options: FileQueueOptions): FileQueue {\n const files = signal<File[]>([]);\n const stateSignals = new Map<File, ReturnType<typeof signal<FileUploadState>>>();\n const controllers = new Map<File, AbortController>();\n\n function stateSignal(file: File): ReturnType<typeof signal<FileUploadState>> {\n let s = stateSignals.get(file);\n\n if (!s) {\n s = signal<FileUploadState>({ ...IDLE_UPLOAD_STATE, total: file.size });\n stateSignals.set(file, s);\n }\n\n return s;\n }\n\n function fileState(file: File): FileUploadState {\n return stateSignal(file).value;\n }\n\n function patchState(file: File, patch: Partial<FileUploadState>): void {\n const s = stateSignal(file);\n\n s.value = { ...s.value, ...patch };\n }\n\n // Each file gets its own `AbortController` and its own promise chain — nothing here `await`s\n // another file's upload, so one file's rejection can never block, freeze, or cancel the others.\n function startUpload(file: File, resumeFrom = 0): void {\n if (options.disabled.value) return;\n\n const uploadFn = options.upload.value;\n\n if (!uploadFn) return;\n\n controllers.get(file)?.abort();\n\n const controller = new AbortController();\n\n controllers.set(file, controller);\n patchState(file, { error: null, loaded: resumeFrom, speedBps: 0, status: 'uploading', total: file.size });\n\n // Rolling (exponential-moving-average) speed estimate rather than a naive\n // `loaded / elapsedSinceStart` average — the latter drags heavily behind the file's actual\n // *current* rate right after a slow start or a mid-transfer stall.\n let lastSampleAt = performance.now();\n let lastSampleLoaded = resumeFrom;\n\n uploadFn(file, {\n onProgress: (loaded, total) => {\n if (controller.signal.aborted) return;\n\n const now = performance.now();\n const elapsedSeconds = (now - lastSampleAt) / 1000;\n const instantBps = elapsedSeconds > 0 ? Math.max(0, (loaded - lastSampleLoaded) / elapsedSeconds) : 0;\n const previousBps = fileState(file).speedBps;\n const speedBps = previousBps > 0 ? previousBps * 0.7 + instantBps * 0.3 : instantBps;\n\n lastSampleAt = now;\n lastSampleLoaded = loaded;\n patchState(file, { loaded, speedBps, total: total || file.size });\n options.onUploadProgress(file, loaded, total || file.size);\n },\n resumeFrom,\n signal: controller.signal,\n })\n .then(() => {\n if (controller.signal.aborted) return;\n\n patchState(file, { loaded: file.size, speedBps: 0, status: 'success' });\n announce(`${file.name} uploaded successfully.`);\n options.onUploadSuccess(file);\n })\n .catch((error: unknown) => {\n if (controller.signal.aborted) return;\n\n const message = error instanceof Error ? error.message : String(error);\n\n patchState(file, { error: message, speedBps: 0, status: 'error' });\n announce(`${file.name} failed to upload: ${message}`, { politeness: 'assertive' });\n options.onUploadError(file, error);\n });\n }\n\n // Resumes from the last byte offset this file actually reached, not from 0 — see\n // `FileUploadFn`'s doc comment on what \"resume\" honestly means when the transport is\n // consumer-supplied.\n function retryUpload(file: File): void {\n if (options.disabled.value) return;\n\n startUpload(file, fileState(file).loaded);\n }\n\n // Aborts + drops upload state for any file no longer in `files` — covers plain removal, a\n // non-`multiple` selection replacing the previous file, and `replaceFile()` swapping one File\n // for another. One cleanup path instead of duplicating it at every call site that can shrink\n // `files`.\n function dropOrphanedState(activeFiles: File[]): void {\n const keep = new Set(activeFiles);\n\n for (const file of stateSignals.keys()) {\n if (keep.has(file)) continue;\n\n controllers.get(file)?.abort();\n controllers.delete(file);\n stateSignals.delete(file);\n }\n }\n\n const filesWatch = watch(files, dropOrphanedState);\n\n function addFiles(newFiles: File[], originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n const isMultiple = options.multiple.value;\n let incoming = Array.from(newFiles);\n\n if (!isMultiple) incoming = incoming.slice(0, 1);\n\n const acceptList = parseAccept(options.accept.value);\n const maxSize = options.maxSize.value;\n\n incoming = incoming.filter((f) => matchesAccept(f, acceptList) && isFileSizeAllowed(f, maxSize));\n\n let updated: File[] = isMultiple ? [...files.value] : [];\n const added: File[] = [];\n\n for (const f of incoming) {\n if (!updated.includes(f)) {\n updated.push(f);\n added.push(f);\n }\n }\n\n const maxFiles = options.maxFiles.value;\n\n if (maxFiles > 0 && updated.length > maxFiles) updated = updated.slice(0, maxFiles);\n\n files.value = updated;\n options.onChange(files.value, originalEvent);\n\n for (const f of added) {\n if (files.value.includes(f)) startUpload(f);\n }\n }\n\n function removeFile(file: File, originalEvent?: Event): void {\n if (options.disabled.value) return;\n\n files.value = files.value.filter((f) => f !== file);\n options.onRemove(file, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n }\n\n function replaceFile(oldFile: File, newFile: File, originalEvent?: Event): boolean {\n if (options.disabled.value) return false;\n\n const acceptList = parseAccept(options.accept.value);\n\n if (!matchesAccept(newFile, acceptList) || !isFileSizeAllowed(newFile, options.maxSize.value)) return false;\n\n files.value = files.value.map((f) => (f === oldFile ? newFile : f));\n options.onRemove(oldFile, files.value, originalEvent);\n options.onChange(files.value, originalEvent);\n startUpload(newFile);\n\n return true;\n }\n\n function uploadPercent(file: File): number {\n const state = fileState(file);\n\n if (state.total <= 0) return 0;\n\n return Math.min(100, Math.round((state.loaded / state.total) * 100));\n }\n\n // Speed + ETA on one line — percent itself is rendered separately (e.g. `<ore-progress>`'s\n // own `label`), so this only needs the two metrics that wouldn't otherwise fit there.\n function uploadMetaText(file: File): string {\n const state = fileState(file);\n\n return [formatSpeed(state.speedBps), formatEta(state)].filter(Boolean).join(' · ');\n }\n\n function statusIconName(file: File): string {\n const status = fileState(file).status;\n\n if (status === 'success') return 'check';\n\n if (status === 'error') return 'alert-circle';\n\n return 'file';\n }\n\n function dispose(): void {\n filesWatch.dispose();\n\n for (const controller of controllers.values()) controller.abort();\n\n controllers.clear();\n stateSignals.clear();\n }\n\n return {\n addFiles,\n dispose,\n files,\n fileState,\n removeFile,\n replaceFile,\n retryUpload,\n statusIconName,\n uploadMetaText,\n uploadPercent,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input.d.ts","sourceRoot":"","sources":["../../../src/inputs/file-input/file-input.ts"],"names":[],"mappings":"AAmBA,OAAO,yBAAyB,CAAC;AACjC,OAAO,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"file-input.d.ts","sourceRoot":"","sources":["../../../src/inputs/file-input/file-input.ts"],"names":[],"mappings":"AAmBA,OAAO,yBAAyB,CAAC;AACjC,OAAO,kCAAkC,CAAC;AAY1C,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGtF,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAI3F,sCAAsC;AACtC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACrD,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,iDAAiD;AACjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,8CAA8C;IAC9C,MAAM,EAAE;QAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,IAAI,EAAE,CAAA;KAAE,CAAC;IAChE,8CAA8C;IAC9C,MAAM,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,IAAI,EAAE,CAAA;KAAE,CAAC;IAC5E,kFAAkF;IAClF,cAAc,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;IAC/C,4EAA4E;IAC5E,iBAAiB,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,gDAAgD;IAChD,gBAAgB,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,eAAO,MAAM,cAAc,EAAG,gBAAyB,CAAC"}
|
package/dist/inputs/index.d.ts
CHANGED
|
@@ -17,8 +17,6 @@ export type { OreComboboxEvents, OreComboboxProps } from './combobox/combobox';
|
|
|
17
17
|
export type { OreComboboxOptionProps } from './combobox/combobox.types';
|
|
18
18
|
export { FILE_INPUT_TAG } from './file-input/file-input';
|
|
19
19
|
export type { OreFileInputEvents, OreFileInputProps } from './file-input/file-input';
|
|
20
|
-
export { FORM_TAG } from './form/form';
|
|
21
|
-
export type { OreFormEvents, OreFormProps } from './form/form';
|
|
22
20
|
export { INPUT_TAG } from './input/input';
|
|
23
21
|
export type { OreInputEvents, OreInputProps } from './input/input';
|
|
24
22
|
export { MESSAGE_COMPOSER_TAG } from './message-composer/message-composer';
|
|
@@ -43,7 +41,5 @@ export { TEXTAREA_TAG } from './textarea/textarea';
|
|
|
43
41
|
export type { OreTextareaEvents, OreTextareaProps } from './textarea/textarea';
|
|
44
42
|
export { TIME_PICKER_TAG } from './time-picker/time-picker';
|
|
45
43
|
export type { OreTimePickerEvents, OreTimePickerProps } from './time-picker/time-picker';
|
|
46
|
-
export { FORM_CTX } from './shared/form-context';
|
|
47
|
-
export type { FormContext } from './shared/form-context';
|
|
48
44
|
export type { BaseFormProps, SelectableFieldProps, TextFieldProps } from '../shared';
|
|
49
45
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inputs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACjF,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACzF,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inputs/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,14 +3,8 @@ import type { InputType, VisualVariant } from '../../types';
|
|
|
3
3
|
import '../../content/icon/icon';
|
|
4
4
|
/** Input component properties */
|
|
5
5
|
export type OreInputEvents = {
|
|
6
|
-
change:
|
|
7
|
-
|
|
8
|
-
value: string;
|
|
9
|
-
};
|
|
10
|
-
input: {
|
|
11
|
-
originalEvent: Event;
|
|
12
|
-
value: string;
|
|
13
|
-
};
|
|
6
|
+
change: Event;
|
|
7
|
+
input: InputEvent;
|
|
14
8
|
};
|
|
15
9
|
export type OreInputProps = TextFieldProps<Exclude<VisualVariant, 'frost'>> & {
|
|
16
10
|
/** Autocomplete hint */
|
|
@@ -64,8 +58,8 @@ export type OreInputProps = TextFieldProps<Exclude<VisualVariant, 'frost'>> & {
|
|
|
64
58
|
* @attr {string} size - Input size: 'sm' | 'md' | 'lg'
|
|
65
59
|
* @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'
|
|
66
60
|
*
|
|
67
|
-
* @fires input - Emitted when input value changes (on every keystroke).
|
|
68
|
-
* @fires change - Emitted when input loses focus with changed value.
|
|
61
|
+
* @fires input - Emitted when input value changes (on every keystroke).
|
|
62
|
+
* @fires change - Emitted when input loses focus with changed value.
|
|
69
63
|
*
|
|
70
64
|
* @slot prefix - Content before the input (e.g., icons)
|
|
71
65
|
* @slot suffix - Content after the input (e.g., clear button, validation icon)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/inputs/input/input.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/inputs/input/input.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5D,OAAO,yBAAyB,CAAC;AAgBjC,iCAAiC;AAEjC,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,UAAU,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG;IAC5E,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IACzF;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACrD,sBAAsB;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC;AAiBF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,eAAO,MAAM,SAAS,EAAG,WAAoB,CAAC"}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import type { ComponentSize, ThemeColor, VisualVariant } from '../../types';
|
|
2
|
-
import { type SendShortcut } from '../../
|
|
2
|
+
import { type SendShortcut } from '../../core';
|
|
3
3
|
import '../../content/icon/icon';
|
|
4
4
|
import '../button/button';
|
|
5
|
-
export type { SendShortcut } from '../../
|
|
5
|
+
export type { SendShortcut } from '../../core';
|
|
6
6
|
/** Events emitted by the message composer */
|
|
7
7
|
export type OreMessageComposerEvents = {
|
|
8
|
-
|
|
9
|
-
input: {
|
|
10
|
-
originalEvent: Event;
|
|
11
|
-
value: string;
|
|
12
|
-
};
|
|
8
|
+
input: InputEvent;
|
|
13
9
|
/**
|
|
14
10
|
* Fired for a send attempt (the resolved `send-shortcut` or the send button) while the
|
|
15
11
|
* composer isn't blank/disabled/loading. Cancelable — call `preventDefault()` to keep the
|
|
@@ -51,7 +47,7 @@ export type OreMessageComposerProps = {
|
|
|
51
47
|
* `null` when it unmounts. Set as a JS property: `composer.ref = (el) => { ... }`.
|
|
52
48
|
*/
|
|
53
49
|
ref?: ((el: HTMLTextAreaElement | null) => void) | null;
|
|
54
|
-
/** Require a non-blank value for
|
|
50
|
+
/** Require a non-blank value for native form validation */
|
|
55
51
|
required?: boolean;
|
|
56
52
|
/** Number of visible rows before auto-resize grows the field */
|
|
57
53
|
rows?: number;
|
|
@@ -75,7 +71,7 @@ export type OreMessageComposerProps = {
|
|
|
75
71
|
};
|
|
76
72
|
/**
|
|
77
73
|
* A message/comment composer — a card with an auto-resizing field on top and a toolbar row
|
|
78
|
-
* below it, built directly on the same
|
|
74
|
+
* below it, built directly on the same core primitives as `ore-textarea` (`createTextField`,
|
|
79
75
|
* `createAutoResize`) rather than composing `ore-textarea` itself. Nesting a fully-styled sibling
|
|
80
76
|
* component and suppressing most of its chrome (as an earlier version of this component did) is
|
|
81
77
|
* a leaky composition — this owns its single `<textarea>` outright, so there's exactly one
|
|
@@ -95,7 +91,7 @@ export type OreMessageComposerProps = {
|
|
|
95
91
|
* @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)
|
|
96
92
|
* @attr {boolean} disabled - Disable the whole composer
|
|
97
93
|
* @attr {boolean} readonly - Read-only mode
|
|
98
|
-
* @attr {boolean} required - Require a non-blank value for
|
|
94
|
+
* @attr {boolean} required - Require a non-blank value for native form validation
|
|
99
95
|
* @attr {boolean} loading - Blocks further sends without disabling editing
|
|
100
96
|
* @attr {number} maxlength - Max character count; shows a counter
|
|
101
97
|
* @attr {number} rows - Visible rows before auto-resize grows the field (default 1)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-composer.d.ts","sourceRoot":"","sources":["../../../src/inputs/message-composer/message-composer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"message-composer.d.ts","sourceRoot":"","sources":["../../../src/inputs/message-composer/message-composer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAqBpB,OAAO,yBAAyB,CAAC;AACjC,OAAO,kBAAkB,CAAC;AAG1B,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,6CAA6C;AAC7C,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,IAAI,EAAE;QAAE,aAAa,EAAE,aAAa,GAAG,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACpE,CAAC;AAEF,kCAAkC;AAClC,MAAM,MAAM,uBAAuB,GAAG;IACpC,gFAAgF;IAChF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gEAAgE;IAChE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,mBAAmB,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8IAA8I;IAC9I,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,qBAAqB;IACrB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4FAA4F;IAC5F,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,eAAO,MAAM,oBAAoB,EAAG,sBAA+B,CAAC"}
|
|
@@ -2,14 +2,8 @@ import type { ComponentSize, ThemeColor, VisualVariant } from '../../types';
|
|
|
2
2
|
import '../../content/icon/icon';
|
|
3
3
|
import '../input/input';
|
|
4
4
|
export type OreNumberInputEvents = {
|
|
5
|
-
change:
|
|
6
|
-
|
|
7
|
-
value: number | null;
|
|
8
|
-
};
|
|
9
|
-
input: {
|
|
10
|
-
originalEvent?: Event;
|
|
11
|
-
value: number | null;
|
|
12
|
-
};
|
|
5
|
+
change: Event;
|
|
6
|
+
input: InputEvent;
|
|
13
7
|
};
|
|
14
8
|
/** Number Input props */
|
|
15
9
|
export type OreNumberInputProps = {
|
|
@@ -87,8 +81,8 @@ export type OreNumberInputProps = {
|
|
|
87
81
|
* @attr {string} size - 'sm' | 'md' | 'lg'
|
|
88
82
|
* @attr {string} placeholder - Input placeholder
|
|
89
83
|
*
|
|
90
|
-
* @fires
|
|
91
|
-
* @fires
|
|
84
|
+
* @fires input - On every keystroke.
|
|
85
|
+
* @fires change - On committed value change.
|
|
92
86
|
*
|
|
93
87
|
* @slot prefix - Content before the input (e.g. icon)
|
|
94
88
|
* @slot suffix - Content after the input (e.g. unit label)
|