@vielzeug/refine 1.5.4 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordion.cjs +1 -1
- package/dist/accordion.cjs.map +1 -1
- package/dist/accordion.js +30 -28
- package/dist/accordion.js.map +1 -1
- package/dist/async.cjs +11 -11
- package/dist/async.cjs.map +1 -1
- package/dist/async.js +1 -2
- package/dist/async.js.map +1 -1
- package/dist/button-group.cjs.map +1 -1
- package/dist/button-group.js.map +1 -1
- package/dist/button.cjs +1 -1
- package/dist/button.cjs.map +1 -1
- package/dist/button.js +1 -0
- package/dist/button.js.map +1 -1
- package/dist/calendar.cjs +26 -26
- package/dist/calendar.cjs.map +1 -1
- package/dist/calendar.js +4 -5
- package/dist/calendar.js.map +1 -1
- package/dist/checkbox-group.cjs +9 -9
- package/dist/checkbox-group.cjs.map +1 -1
- package/dist/checkbox-group.js +50 -58
- package/dist/checkbox-group.js.map +1 -1
- package/dist/code-window.cjs +4 -4
- package/dist/code-window.cjs.map +1 -1
- package/dist/code-window.js +1 -2
- package/dist/code-window.js.map +1 -1
- package/dist/combobox.cjs +29 -28
- package/dist/combobox.cjs.map +1 -1
- package/dist/combobox.js +201 -195
- package/dist/combobox.js.map +1 -1
- package/dist/command-palette.cjs +6 -6
- package/dist/command-palette.cjs.map +1 -1
- package/dist/command-palette.js +46 -47
- package/dist/command-palette.js.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/chat-message/chat-message.css.cjs +1 -1
- package/dist/content/chat-message/chat-message.css.cjs.map +1 -1
- package/dist/content/chat-message/chat-message.css.js +1 -1
- package/dist/content/chat-message/chat-message.css.js.map +1 -1
- package/dist/content/code-window/code-window.d.ts.map +1 -1
- package/dist/content/icon/icon.d.ts.map +1 -1
- package/dist/content/index.d.ts +4 -0
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/list/_list-item-reveal.cjs +2 -0
- package/dist/content/list/_list-item-reveal.cjs.map +1 -0
- package/dist/content/list/_list-item-reveal.d.ts +25 -0
- package/dist/content/list/_list-item-reveal.d.ts.map +1 -0
- package/dist/content/list/_list-item-reveal.js +33 -0
- package/dist/content/list/_list-item-reveal.js.map +1 -0
- package/dist/content/list/list-item.css.cjs +2 -0
- package/dist/content/list/list-item.css.cjs.map +1 -0
- package/dist/content/list/list-item.css.js +6 -0
- package/dist/content/list/list-item.css.js.map +1 -0
- package/dist/content/list/list-item.d.ts +111 -0
- package/dist/content/list/list-item.d.ts.map +1 -0
- package/dist/content/list/list.css.cjs +2 -0
- package/dist/content/list/list.css.cjs.map +1 -0
- package/dist/content/list/list.css.js +6 -0
- package/dist/content/list/list.css.js.map +1 -0
- package/dist/content/list/list.d.ts +93 -0
- package/dist/content/list/list.d.ts.map +1 -0
- package/dist/custom-elements.json +5693 -5090
- package/dist/datagrid.cjs +2 -2
- package/dist/datagrid.js +206 -206
- package/dist/datagrid.js.map +1 -1
- package/dist/date-picker.cjs +2 -1
- package/dist/date-picker.cjs.map +1 -1
- package/dist/date-picker.js +2 -0
- package/dist/date-picker.js.map +1 -1
- package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
- package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
- package/dist/drawer.cjs +1 -1
- package/dist/drawer.cjs.map +1 -1
- package/dist/drawer.js +47 -48
- package/dist/drawer.js.map +1 -1
- package/dist/feedback/async/async.d.ts.map +1 -1
- package/dist/feedback/progress/progress.d.ts.map +1 -1
- package/dist/file-input.cjs +108 -42
- package/dist/file-input.cjs.map +1 -1
- package/dist/file-input.js +215 -156
- package/dist/file-input.js.map +1 -1
- package/dist/headless/aria-reflection.cjs +2 -0
- package/dist/headless/aria-reflection.cjs.map +1 -0
- package/dist/headless/aria-reflection.d.ts +27 -0
- package/dist/headless/aria-reflection.d.ts.map +1 -0
- package/dist/headless/aria-reflection.js +18 -0
- package/dist/headless/aria-reflection.js.map +1 -0
- package/dist/headless/checkable.cjs +1 -1
- package/dist/headless/checkable.cjs.map +1 -1
- package/dist/headless/checkable.d.ts +2 -10
- package/dist/headless/checkable.d.ts.map +1 -1
- package/dist/headless/checkable.js +29 -29
- package/dist/headless/checkable.js.map +1 -1
- package/dist/headless/choice-field.cjs +1 -1
- package/dist/headless/choice-field.cjs.map +1 -1
- package/dist/headless/choice-field.d.ts +2 -7
- package/dist/headless/choice-field.d.ts.map +1 -1
- package/dist/headless/choice-field.js +37 -37
- package/dist/headless/choice-field.js.map +1 -1
- package/dist/headless/field-base.cjs +1 -1
- package/dist/headless/field-base.cjs.map +1 -1
- package/dist/headless/field-base.d.ts +17 -0
- package/dist/headless/field-base.d.ts.map +1 -1
- package/dist/headless/field-base.js +21 -6
- package/dist/headless/field-base.js.map +1 -1
- package/dist/headless/focus.cjs +1 -1
- package/dist/headless/focus.cjs.map +1 -1
- package/dist/headless/focus.d.ts +7 -0
- package/dist/headless/focus.d.ts.map +1 -1
- package/dist/headless/focus.js +6 -6
- package/dist/headless/focus.js.map +1 -1
- package/dist/headless/index.d.ts +4 -2
- package/dist/headless/index.d.ts.map +1 -1
- package/dist/headless/nav.cjs +1 -1
- package/dist/headless/nav.cjs.map +1 -1
- package/dist/headless/nav.d.ts +12 -0
- package/dist/headless/nav.d.ts.map +1 -1
- package/dist/headless/nav.js +68 -50
- package/dist/headless/nav.js.map +1 -1
- package/dist/headless/overlay.cjs +1 -1
- package/dist/headless/overlay.cjs.map +1 -1
- package/dist/headless/overlay.d.ts +2 -0
- package/dist/headless/overlay.d.ts.map +1 -1
- package/dist/headless/overlay.js +8 -5
- package/dist/headless/overlay.js.map +1 -1
- package/dist/headless/ref-callback.cjs +2 -0
- package/dist/headless/ref-callback.cjs.map +1 -0
- package/dist/headless/ref-callback.d.ts +26 -0
- package/dist/headless/ref-callback.d.ts.map +1 -0
- package/dist/headless/ref-callback.js +13 -0
- package/dist/headless/ref-callback.js.map +1 -0
- package/dist/headless/swipe.cjs +1 -1
- package/dist/headless/swipe.cjs.map +1 -1
- package/dist/headless/swipe.d.ts +2 -0
- package/dist/headless/swipe.d.ts.map +1 -1
- package/dist/headless/swipe.js +26 -21
- package/dist/headless/swipe.js.map +1 -1
- package/dist/headless.cjs +1 -1
- package/dist/headless.js +28 -26
- package/dist/icon.cjs +1 -1
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +35 -38
- package/dist/icon.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +63 -61
- package/dist/input.cjs +29 -26
- package/dist/input.cjs.map +1 -1
- package/dist/input.js +91 -79
- package/dist/input.js.map +1 -1
- package/dist/inputs/button/button.css.cjs +1 -1
- package/dist/inputs/button/button.css.cjs.map +1 -1
- package/dist/inputs/button/button.css.js +1 -1
- package/dist/inputs/button/button.css.js.map +1 -1
- package/dist/inputs/button/button.d.ts +8 -0
- package/dist/inputs/button/button.d.ts.map +1 -1
- package/dist/inputs/calendar/calendar.d.ts.map +1 -1
- package/dist/inputs/checkbox/checkbox.css.cjs +1 -1
- package/dist/inputs/checkbox/checkbox.css.cjs.map +1 -1
- package/dist/inputs/checkbox/checkbox.css.js +1 -1
- package/dist/inputs/checkbox/checkbox.css.js.map +1 -1
- package/dist/inputs/combobox/combobox.d.ts +1 -0
- package/dist/inputs/combobox/combobox.d.ts.map +1 -1
- package/dist/inputs/date-picker/date-picker.css.cjs +1 -1
- package/dist/inputs/date-picker/date-picker.css.cjs.map +1 -1
- package/dist/inputs/date-picker/date-picker.css.js +1 -1
- package/dist/inputs/date-picker/date-picker.css.js.map +1 -1
- package/dist/inputs/date-picker/date-picker.d.ts +6 -0
- package/dist/inputs/date-picker/date-picker.d.ts.map +1 -1
- package/dist/inputs/file-input/file-input-upload.cjs +2 -0
- package/dist/inputs/file-input/file-input-upload.cjs.map +1 -0
- package/dist/inputs/file-input/file-input-upload.d.ts +76 -0
- package/dist/inputs/file-input/file-input-upload.d.ts.map +1 -0
- package/dist/inputs/file-input/file-input-upload.js +145 -0
- package/dist/inputs/file-input/file-input-upload.js.map +1 -0
- package/dist/inputs/file-input/file-input.css.cjs +1 -1
- package/dist/inputs/file-input/file-input.css.cjs.map +1 -1
- package/dist/inputs/file-input/file-input.css.js +1 -1
- package/dist/inputs/file-input/file-input.css.js.map +1 -1
- package/dist/inputs/file-input/file-input.d.ts +54 -1
- package/dist/inputs/file-input/file-input.d.ts.map +1 -1
- package/dist/inputs/input/input.css.cjs +1 -1
- package/dist/inputs/input/input.css.cjs.map +1 -1
- package/dist/inputs/input/input.css.js +1 -1
- package/dist/inputs/input/input.css.js.map +1 -1
- package/dist/inputs/input/input.d.ts +13 -0
- package/dist/inputs/input/input.d.ts.map +1 -1
- package/dist/inputs/message-composer/message-composer.css.cjs +1 -1
- package/dist/inputs/message-composer/message-composer.css.cjs.map +1 -1
- package/dist/inputs/message-composer/message-composer.css.js +1 -1
- package/dist/inputs/message-composer/message-composer.css.js.map +1 -1
- package/dist/inputs/message-composer/message-composer.d.ts +7 -0
- package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
- package/dist/inputs/number-input/number-input.css.cjs +1 -1
- package/dist/inputs/number-input/number-input.css.cjs.map +1 -1
- package/dist/inputs/number-input/number-input.css.js +1 -1
- package/dist/inputs/number-input/number-input.css.js.map +1 -1
- package/dist/inputs/number-input/number-input.d.ts +15 -0
- package/dist/inputs/number-input/number-input.d.ts.map +1 -1
- package/dist/inputs/otp-input/otp-input.css.cjs +1 -1
- package/dist/inputs/otp-input/otp-input.css.cjs.map +1 -1
- package/dist/inputs/otp-input/otp-input.css.js +1 -1
- package/dist/inputs/otp-input/otp-input.css.js.map +1 -1
- package/dist/inputs/radio/radio.d.ts.map +1 -1
- package/dist/inputs/select/select.d.ts +1 -0
- package/dist/inputs/select/select.d.ts.map +1 -1
- package/dist/inputs/shared/index.d.ts +1 -1
- package/dist/inputs/shared/index.d.ts.map +1 -1
- package/dist/inputs/shared/templates.cjs +26 -3
- package/dist/inputs/shared/templates.cjs.map +1 -1
- package/dist/inputs/shared/templates.d.ts +20 -0
- package/dist/inputs/shared/templates.d.ts.map +1 -1
- package/dist/inputs/shared/templates.js +29 -5
- package/dist/inputs/shared/templates.js.map +1 -1
- package/dist/inputs/switch/switch.css.cjs +1 -1
- package/dist/inputs/switch/switch.css.cjs.map +1 -1
- package/dist/inputs/switch/switch.css.js +1 -1
- package/dist/inputs/switch/switch.css.js.map +1 -1
- package/dist/inputs/switch/switch.d.ts.map +1 -1
- package/dist/inputs/textarea/textarea.css.cjs +1 -1
- package/dist/inputs/textarea/textarea.css.cjs.map +1 -1
- package/dist/inputs/textarea/textarea.css.js +1 -1
- package/dist/inputs/textarea/textarea.css.js.map +1 -1
- package/dist/inputs/textarea/textarea.d.ts +14 -0
- package/dist/inputs/textarea/textarea.d.ts.map +1 -1
- package/dist/inputs/time-picker/time-picker.css.cjs +1 -1
- package/dist/inputs/time-picker/time-picker.css.cjs.map +1 -1
- package/dist/inputs/time-picker/time-picker.css.js +1 -1
- package/dist/inputs/time-picker/time-picker.css.js.map +1 -1
- package/dist/inputs/time-picker/time-picker.d.ts +6 -0
- package/dist/inputs/time-picker/time-picker.d.ts.map +1 -1
- package/dist/list-item.cjs +22 -0
- package/dist/list-item.cjs.map +1 -0
- package/dist/list-item.js +91 -0
- package/dist/list-item.js.map +1 -0
- package/dist/list.cjs +2 -0
- package/dist/list.cjs.map +1 -0
- package/dist/list.js +64 -0
- package/dist/list.js.map +1 -0
- package/dist/menu.cjs +4 -4
- package/dist/menu.cjs.map +1 -1
- package/dist/menu.js +60 -59
- package/dist/menu.js.map +1 -1
- package/dist/message-composer.cjs +14 -20
- package/dist/message-composer.cjs.map +1 -1
- package/dist/message-composer.js +63 -64
- package/dist/message-composer.js.map +1 -1
- package/dist/number-input.cjs +5 -3
- package/dist/number-input.cjs.map +1 -1
- package/dist/number-input.js +8 -4
- package/dist/number-input.js.map +1 -1
- package/dist/otp-input.cjs +9 -9
- package/dist/otp-input.cjs.map +1 -1
- package/dist/otp-input.js +70 -62
- package/dist/otp-input.js.map +1 -1
- package/dist/overlay/menu/menu-item.css.cjs +1 -1
- package/dist/overlay/menu/menu-item.css.cjs.map +1 -1
- package/dist/overlay/menu/menu-item.css.js +1 -1
- package/dist/overlay/menu/menu-item.css.js.map +1 -1
- package/dist/overlay/menu/menu-separator.css.cjs +1 -1
- package/dist/overlay/menu/menu-separator.css.cjs.map +1 -1
- package/dist/overlay/menu/menu-separator.css.js +1 -1
- package/dist/overlay/menu/menu-separator.css.js.map +1 -1
- package/dist/overlay/menu/menu.css.cjs +1 -1
- package/dist/overlay/menu/menu.css.cjs.map +1 -1
- package/dist/overlay/menu/menu.css.js +1 -1
- package/dist/overlay/menu/menu.css.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.map +1 -1
- package/dist/overlay/shared/use-dialog.js +7 -6
- package/dist/overlay/shared/use-dialog.js.map +1 -1
- package/dist/progress.cjs +13 -13
- package/dist/progress.cjs.map +1 -1
- package/dist/progress.js +3 -4
- package/dist/progress.js.map +1 -1
- package/dist/radio-group.cjs +11 -11
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.js +63 -70
- 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 +58 -58
- package/dist/radio.js.map +1 -1
- package/dist/rating.cjs.map +1 -1
- package/dist/rating.js.map +1 -1
- package/dist/refine.cjs +502 -309
- package/dist/refine.cjs.map +1 -1
- package/dist/refine.iife.js +562 -369
- package/dist/refine.iife.js.map +1 -1
- package/dist/refine.js +558 -365
- package/dist/refine.js.map +1 -1
- package/dist/select.cjs +21 -21
- package/dist/select.cjs.map +1 -1
- package/dist/select.js +135 -127
- package/dist/select.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 +74 -0
- package/dist/shared/size-presets.d.ts.map +1 -1
- package/dist/shared/size-presets.js +48 -1
- package/dist/shared/size-presets.js.map +1 -1
- package/dist/shared/types.d.ts +5 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/styles/index.cjs +1 -1
- package/dist/styles/index.cjs.map +1 -1
- package/dist/styles/index.d.ts +1 -0
- package/dist/styles/index.d.ts.map +1 -1
- package/dist/styles/index.js +5 -4
- package/dist/styles/index.js.map +1 -1
- package/dist/styles/mixins/field-variants.css.cjs +85 -0
- package/dist/styles/mixins/field-variants.css.cjs.map +1 -0
- package/dist/styles/mixins/field-variants.css.d.ts +66 -0
- package/dist/styles/mixins/field-variants.css.d.ts.map +1 -0
- package/dist/styles/mixins/field-variants.css.js +90 -0
- package/dist/styles/mixins/field-variants.css.js.map +1 -0
- package/dist/switch.cjs +3 -3
- package/dist/switch.cjs.map +1 -1
- package/dist/switch.js +38 -36
- package/dist/switch.js.map +1 -1
- package/dist/tab-item.cjs +8 -8
- package/dist/tab-item.cjs.map +1 -1
- package/dist/tab-item.js +38 -28
- package/dist/tab-item.js.map +1 -1
- package/dist/tab-panel.cjs +7 -7
- package/dist/tab-panel.cjs.map +1 -1
- package/dist/tab-panel.js +33 -26
- package/dist/tab-panel.js.map +1 -1
- package/dist/tabs.cjs +4 -4
- package/dist/tabs.cjs.map +1 -1
- package/dist/tabs.js +64 -60
- package/dist/tabs.js.map +1 -1
- package/dist/testing/index.d.ts +15 -60
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.js +7 -24
- package/dist/testing.js.map +1 -1
- package/dist/textarea.cjs +15 -18
- package/dist/textarea.cjs.map +1 -1
- package/dist/textarea.js +83 -74
- package/dist/textarea.js.map +1 -1
- package/dist/time-picker.cjs +34 -31
- package/dist/time-picker.cjs.map +1 -1
- package/dist/time-picker.js +121 -109
- package/dist/time-picker.js.map +1 -1
- package/package.json +22 -9
- package/dist/headless/dialog-focus.cjs +0 -2
- package/dist/headless/dialog-focus.cjs.map +0 -1
- package/dist/headless/dialog-focus.d.ts +0 -40
- package/dist/headless/dialog-focus.d.ts.map +0 -1
- package/dist/headless/dialog-focus.js +0 -22
- package/dist/headless/dialog-focus.js.map +0 -1
- package/dist/headless/focus-trap.cjs +0 -2
- package/dist/headless/focus-trap.cjs.map +0 -1
- package/dist/headless/focus-trap.d.ts +0 -45
- package/dist/headless/focus-trap.d.ts.map +0 -1
- package/dist/headless/focus-trap.js +0 -51
- package/dist/headless/focus-trap.js.map +0 -1
- package/dist/keymap/dist/_dev.cjs +0 -2
- package/dist/keymap/dist/_dev.cjs.map +0 -1
- package/dist/keymap/dist/_dev.js +0 -4
- package/dist/keymap/dist/_dev.js.map +0 -1
- package/dist/keymap/dist/format.cjs +0 -1
- package/dist/keymap/dist/format.js +0 -1
- package/dist/keymap/dist/index.cjs +0 -1
- package/dist/keymap/dist/index.js +0 -4
- package/dist/keymap/dist/keymap.cjs +0 -2
- package/dist/keymap/dist/keymap.cjs.map +0 -1
- package/dist/keymap/dist/keymap.js +0 -221
- package/dist/keymap/dist/keymap.js.map +0 -1
- package/dist/keymap/dist/layer.cjs +0 -1
- package/dist/keymap/dist/layer.js +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=`@layer refine.base{:host{--_menu-panel-bg:var(--menu-panel-bg,var(--color-canvas));--_menu-panel-border-color:var(--menu-panel-border-color,var(--color-divider));--_menu-panel-blur:var(--menu-panel-blur,var(--blur-md));--_menu-panel-shadow:var(--menu-panel-shadow,var(--shadow-xl));display:inline-block;position:relative}.menu-panel{z-index:calc(var(--z-popover) + 1);box-sizing:border-box;min-width:var(--menu-panel-min-width,10rem);max-height:var(--menu-panel-max-height,min(70vh, 32rem));padding:var(--size-1);pointer-events:none;background:var(--_menu-panel-bg);border:var(--border) solid var(--_menu-panel-border-color);border-radius:var(--menu-panel-radius,var(--rounded-lg));box-shadow:var(--_menu-panel-shadow);opacity:0;-webkit-backdrop-filter:blur(var(--_menu-panel-blur));backdrop-filter:blur(var(--_menu-panel-blur));transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));transform-origin:0 0;transition:opacity .1s var(--ease-spring), transform .1s var(--ease-spring), display .1s allow-discrete, overlay .1s allow-discrete;margin:0;position:fixed;top:0;overflow-y:auto}.menu-panel:not(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.menu-panel:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){right:0}.menu-panel[data-placement=top-start],.menu-panel[data-placement=top],.menu-panel[data-placement=top-end]{transform-origin:0 100%}.menu-panel[data-placement=bottom-end],.menu-panel[data-placement=right-start],.menu-panel[data-placement=right]{transform-origin:100% 0}.menu-panel[data-open]{pointer-events:auto;opacity:1;transition:opacity .15s var(--ease-spring), transform .15s var(--ease-spring), display .15s allow-discrete, overlay .15s allow-discrete;transform:translateY(0)scale(1)}@starting-style{.menu-panel[data-open]{opacity:0;transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale))}}::slotted(ore-menu-item),::slotted(ore-menu-separator){display:block}}`;exports.default=e;
|
|
1
|
+
var e=`@layer refine.base{:host{--_menu-panel-bg:var(--menu-panel-bg,var(--color-canvas));--_menu-panel-border-color:var(--menu-panel-border-color,var(--color-divider));--_menu-panel-blur:var(--menu-panel-blur,var(--blur-md));--_menu-panel-shadow:var(--menu-panel-shadow,var(--shadow-xl));display:inline-block;position:relative}.menu-panel{z-index:calc(var(--z-popover) + 1);box-sizing:border-box;min-width:var(--menu-panel-min-width,10rem);max-height:var(--menu-panel-max-height,min(70vh, 32rem));padding:var(--_panel-padding,var(--size-1));pointer-events:none;background:var(--_menu-panel-bg);border:var(--border) solid var(--_menu-panel-border-color);border-radius:var(--menu-panel-radius,var(--rounded-lg));box-shadow:var(--_menu-panel-shadow);opacity:0;-webkit-backdrop-filter:blur(var(--_menu-panel-blur));backdrop-filter:blur(var(--_menu-panel-blur));transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));transform-origin:0 0;transition:opacity .1s var(--ease-spring), transform .1s var(--ease-spring), display .1s allow-discrete, overlay .1s allow-discrete;margin:0;position:fixed;top:0;overflow-y:auto}.menu-panel:not(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.menu-panel:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){right:0}.menu-panel[data-placement=top-start],.menu-panel[data-placement=top],.menu-panel[data-placement=top-end]{transform-origin:0 100%}.menu-panel[data-placement=bottom-end],.menu-panel[data-placement=right-start],.menu-panel[data-placement=right]{transform-origin:100% 0}.menu-panel[data-open]{pointer-events:auto;opacity:1;transition:opacity .15s var(--ease-spring), transform .15s var(--ease-spring), display .15s allow-discrete, overlay .15s allow-discrete;transform:translateY(0)scale(1)}@starting-style{.menu-panel[data-open]{opacity:0;transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale))}}::slotted(ore-menu-item),::slotted(ore-menu-separator){display:block}}`;exports.default=e;
|
|
2
2
|
//# sourceMappingURL=menu.css.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.css.cjs","names":[],"sources":["../../../src/overlay/menu/menu.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n --_menu-panel-bg: var(--menu-panel-bg, var(--color-canvas));\n --_menu-panel-border-color: var(--menu-panel-border-color, var(--color-divider));\n --_menu-panel-blur: var(--menu-panel-blur, var(--blur-md));\n --_menu-panel-shadow: var(--menu-panel-shadow, var(--shadow-xl));\n\n position: relative;\n display: inline-block;\n }\n\n /* ========================================\n Menu Panel\n ======================================== */\n\n .menu-panel {\n position: fixed;\n inset-inline-start: 0;\n top: 0;\n z-index: calc(var(--z-popover) + 1);\n box-sizing: border-box;\n min-width: var(--menu-panel-min-width, 10rem);\n max-height: var(--menu-panel-max-height, min(70vh, 32rem));\n padding: var(--size-1);\n margin: 0;\n overflow-y: auto;\n pointer-events: none;\n background: var(--_menu-panel-bg);\n border: var(--border) solid var(--_menu-panel-border-color);\n border-radius: var(--menu-panel-radius, var(--rounded-lg));\n box-shadow: var(--_menu-panel-shadow);\n opacity: 0;\n backdrop-filter: blur(var(--_menu-panel-blur));\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n transform-origin: top left;\n transition:\n opacity 100ms var(--ease-spring),\n transform 100ms var(--ease-spring),\n display 100ms allow-discrete,\n overlay 100ms allow-discrete;\n }\n\n .menu-panel[data-placement='top-start'],\n .menu-panel[data-placement='top'],\n .menu-panel[data-placement='top-end'] {\n transform-origin: bottom left;\n }\n\n .menu-panel[data-placement='bottom-end'],\n .menu-panel[data-placement='right-start'],\n .menu-panel[data-placement='right'] {\n transform-origin: top right;\n }\n\n .menu-panel[data-open] {\n pointer-events: auto;\n opacity: 1;\n transform: translateY(0) scale(1);\n transition:\n opacity 150ms var(--ease-spring),\n transform 150ms var(--ease-spring),\n display 150ms allow-discrete,\n overlay 150ms allow-discrete;\n\n @starting-style {\n opacity: 0;\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n }\n }\n\n /* ========================================\n Menu Items (slotted ore-menu-item)\n ======================================== */\n\n ::slotted(ore-menu-item) {\n display: block;\n }\n\n ::slotted(ore-menu-separator) {\n display: block;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"menu.css.cjs","names":[],"sources":["../../../src/overlay/menu/menu.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n --_menu-panel-bg: var(--menu-panel-bg, var(--color-canvas));\n --_menu-panel-border-color: var(--menu-panel-border-color, var(--color-divider));\n --_menu-panel-blur: var(--menu-panel-blur, var(--blur-md));\n --_menu-panel-shadow: var(--menu-panel-shadow, var(--shadow-xl));\n\n position: relative;\n display: inline-block;\n }\n\n /* ========================================\n Menu Panel\n ======================================== */\n\n .menu-panel {\n position: fixed;\n inset-inline-start: 0;\n top: 0;\n z-index: calc(var(--z-popover) + 1);\n box-sizing: border-box;\n min-width: var(--menu-panel-min-width, 10rem);\n max-height: var(--menu-panel-max-height, min(70vh, 32rem));\n padding: var(--_panel-padding, var(--size-1));\n margin: 0;\n overflow-y: auto;\n pointer-events: none;\n background: var(--_menu-panel-bg);\n border: var(--border) solid var(--_menu-panel-border-color);\n border-radius: var(--menu-panel-radius, var(--rounded-lg));\n box-shadow: var(--_menu-panel-shadow);\n opacity: 0;\n backdrop-filter: blur(var(--_menu-panel-blur));\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n transform-origin: top left;\n transition:\n opacity 100ms var(--ease-spring),\n transform 100ms var(--ease-spring),\n display 100ms allow-discrete,\n overlay 100ms allow-discrete;\n }\n\n .menu-panel[data-placement='top-start'],\n .menu-panel[data-placement='top'],\n .menu-panel[data-placement='top-end'] {\n transform-origin: bottom left;\n }\n\n .menu-panel[data-placement='bottom-end'],\n .menu-panel[data-placement='right-start'],\n .menu-panel[data-placement='right'] {\n transform-origin: top right;\n }\n\n .menu-panel[data-open] {\n pointer-events: auto;\n opacity: 1;\n transform: translateY(0) scale(1);\n transition:\n opacity 150ms var(--ease-spring),\n transform 150ms var(--ease-spring),\n display 150ms allow-discrete,\n overlay 150ms allow-discrete;\n\n @starting-style {\n opacity: 0;\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n }\n }\n\n /* ========================================\n Menu Items (slotted ore-menu-item)\n ======================================== */\n\n ::slotted(ore-menu-item) {\n display: block;\n }\n\n ::slotted(ore-menu-separator) {\n display: block;\n }\n}\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/overlay/menu/menu.css?inline
|
|
2
|
-
var e = "@layer refine.base{:host{--_menu-panel-bg:var(--menu-panel-bg,var(--color-canvas));--_menu-panel-border-color:var(--menu-panel-border-color,var(--color-divider));--_menu-panel-blur:var(--menu-panel-blur,var(--blur-md));--_menu-panel-shadow:var(--menu-panel-shadow,var(--shadow-xl));display:inline-block;position:relative}.menu-panel{z-index:calc(var(--z-popover) + 1);box-sizing:border-box;min-width:var(--menu-panel-min-width,10rem);max-height:var(--menu-panel-max-height,min(70vh, 32rem));padding:var(--size-1);pointer-events:none;background:var(--_menu-panel-bg);border:var(--border) solid var(--_menu-panel-border-color);border-radius:var(--menu-panel-radius,var(--rounded-lg));box-shadow:var(--_menu-panel-shadow);opacity:0;-webkit-backdrop-filter:blur(var(--_menu-panel-blur));backdrop-filter:blur(var(--_menu-panel-blur));transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));transform-origin:0 0;transition:opacity .1s var(--ease-spring), transform .1s var(--ease-spring), display .1s allow-discrete, overlay .1s allow-discrete;margin:0;position:fixed;top:0;overflow-y:auto}.menu-panel:not(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.menu-panel:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){right:0}.menu-panel[data-placement=top-start],.menu-panel[data-placement=top],.menu-panel[data-placement=top-end]{transform-origin:0 100%}.menu-panel[data-placement=bottom-end],.menu-panel[data-placement=right-start],.menu-panel[data-placement=right]{transform-origin:100% 0}.menu-panel[data-open]{pointer-events:auto;opacity:1;transition:opacity .15s var(--ease-spring), transform .15s var(--ease-spring), display .15s allow-discrete, overlay .15s allow-discrete;transform:translateY(0)scale(1)}@starting-style{.menu-panel[data-open]{opacity:0;transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale))}}::slotted(ore-menu-item),::slotted(ore-menu-separator){display:block}}";
|
|
2
|
+
var e = "@layer refine.base{:host{--_menu-panel-bg:var(--menu-panel-bg,var(--color-canvas));--_menu-panel-border-color:var(--menu-panel-border-color,var(--color-divider));--_menu-panel-blur:var(--menu-panel-blur,var(--blur-md));--_menu-panel-shadow:var(--menu-panel-shadow,var(--shadow-xl));display:inline-block;position:relative}.menu-panel{z-index:calc(var(--z-popover) + 1);box-sizing:border-box;min-width:var(--menu-panel-min-width,10rem);max-height:var(--menu-panel-max-height,min(70vh, 32rem));padding:var(--_panel-padding,var(--size-1));pointer-events:none;background:var(--_menu-panel-bg);border:var(--border) solid var(--_menu-panel-border-color);border-radius:var(--menu-panel-radius,var(--rounded-lg));box-shadow:var(--_menu-panel-shadow);opacity:0;-webkit-backdrop-filter:blur(var(--_menu-panel-blur));backdrop-filter:blur(var(--_menu-panel-blur));transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));transform-origin:0 0;transition:opacity .1s var(--ease-spring), transform .1s var(--ease-spring), display .1s allow-discrete, overlay .1s allow-discrete;margin:0;position:fixed;top:0;overflow-y:auto}.menu-panel:not(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){left:0}.menu-panel:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){right:0}.menu-panel[data-placement=top-start],.menu-panel[data-placement=top],.menu-panel[data-placement=top-end]{transform-origin:0 100%}.menu-panel[data-placement=bottom-end],.menu-panel[data-placement=right-start],.menu-panel[data-placement=right]{transform-origin:100% 0}.menu-panel[data-open]{pointer-events:auto;opacity:1;transition:opacity .15s var(--ease-spring), transform .15s var(--ease-spring), display .15s allow-discrete, overlay .15s allow-discrete;transform:translateY(0)scale(1)}@starting-style{.menu-panel[data-open]{opacity:0;transform:translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale))}}::slotted(ore-menu-item),::slotted(ore-menu-separator){display:block}}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.css.js","names":[],"sources":["../../../src/overlay/menu/menu.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n --_menu-panel-bg: var(--menu-panel-bg, var(--color-canvas));\n --_menu-panel-border-color: var(--menu-panel-border-color, var(--color-divider));\n --_menu-panel-blur: var(--menu-panel-blur, var(--blur-md));\n --_menu-panel-shadow: var(--menu-panel-shadow, var(--shadow-xl));\n\n position: relative;\n display: inline-block;\n }\n\n /* ========================================\n Menu Panel\n ======================================== */\n\n .menu-panel {\n position: fixed;\n inset-inline-start: 0;\n top: 0;\n z-index: calc(var(--z-popover) + 1);\n box-sizing: border-box;\n min-width: var(--menu-panel-min-width, 10rem);\n max-height: var(--menu-panel-max-height, min(70vh, 32rem));\n padding: var(--size-1);\n margin: 0;\n overflow-y: auto;\n pointer-events: none;\n background: var(--_menu-panel-bg);\n border: var(--border) solid var(--_menu-panel-border-color);\n border-radius: var(--menu-panel-radius, var(--rounded-lg));\n box-shadow: var(--_menu-panel-shadow);\n opacity: 0;\n backdrop-filter: blur(var(--_menu-panel-blur));\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n transform-origin: top left;\n transition:\n opacity 100ms var(--ease-spring),\n transform 100ms var(--ease-spring),\n display 100ms allow-discrete,\n overlay 100ms allow-discrete;\n }\n\n .menu-panel[data-placement='top-start'],\n .menu-panel[data-placement='top'],\n .menu-panel[data-placement='top-end'] {\n transform-origin: bottom left;\n }\n\n .menu-panel[data-placement='bottom-end'],\n .menu-panel[data-placement='right-start'],\n .menu-panel[data-placement='right'] {\n transform-origin: top right;\n }\n\n .menu-panel[data-open] {\n pointer-events: auto;\n opacity: 1;\n transform: translateY(0) scale(1);\n transition:\n opacity 150ms var(--ease-spring),\n transform 150ms var(--ease-spring),\n display 150ms allow-discrete,\n overlay 150ms allow-discrete;\n\n @starting-style {\n opacity: 0;\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n }\n }\n\n /* ========================================\n Menu Items (slotted ore-menu-item)\n ======================================== */\n\n ::slotted(ore-menu-item) {\n display: block;\n }\n\n ::slotted(ore-menu-separator) {\n display: block;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"menu.css.js","names":[],"sources":["../../../src/overlay/menu/menu.css?inline"],"sourcesContent":["@layer refine.base {\n :host {\n --_menu-panel-bg: var(--menu-panel-bg, var(--color-canvas));\n --_menu-panel-border-color: var(--menu-panel-border-color, var(--color-divider));\n --_menu-panel-blur: var(--menu-panel-blur, var(--blur-md));\n --_menu-panel-shadow: var(--menu-panel-shadow, var(--shadow-xl));\n\n position: relative;\n display: inline-block;\n }\n\n /* ========================================\n Menu Panel\n ======================================== */\n\n .menu-panel {\n position: fixed;\n inset-inline-start: 0;\n top: 0;\n z-index: calc(var(--z-popover) + 1);\n box-sizing: border-box;\n min-width: var(--menu-panel-min-width, 10rem);\n max-height: var(--menu-panel-max-height, min(70vh, 32rem));\n padding: var(--_panel-padding, var(--size-1));\n margin: 0;\n overflow-y: auto;\n pointer-events: none;\n background: var(--_menu-panel-bg);\n border: var(--border) solid var(--_menu-panel-border-color);\n border-radius: var(--menu-panel-radius, var(--rounded-lg));\n box-shadow: var(--_menu-panel-shadow);\n opacity: 0;\n backdrop-filter: blur(var(--_menu-panel-blur));\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n transform-origin: top left;\n transition:\n opacity 100ms var(--ease-spring),\n transform 100ms var(--ease-spring),\n display 100ms allow-discrete,\n overlay 100ms allow-discrete;\n }\n\n .menu-panel[data-placement='top-start'],\n .menu-panel[data-placement='top'],\n .menu-panel[data-placement='top-end'] {\n transform-origin: bottom left;\n }\n\n .menu-panel[data-placement='bottom-end'],\n .menu-panel[data-placement='right-start'],\n .menu-panel[data-placement='right'] {\n transform-origin: top right;\n }\n\n .menu-panel[data-open] {\n pointer-events: auto;\n opacity: 1;\n transform: translateY(0) scale(1);\n transition:\n opacity 150ms var(--ease-spring),\n transform 150ms var(--ease-spring),\n display 150ms allow-discrete,\n overlay 150ms allow-discrete;\n\n @starting-style {\n opacity: 0;\n transform: translateY(var(--overlay-enter-translate-y)) scale(var(--overlay-enter-scale));\n }\n }\n\n /* ========================================\n Menu Items (slotted ore-menu-item)\n ======================================== */\n\n ::slotted(ore-menu-item) {\n display: block;\n }\n\n ::slotted(ore-menu-separator) {\n display: block;\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../headless/ore.cjs"),t=require("../../headless/overlay.cjs"),n=require("
|
|
1
|
+
const e=require("../../headless/ore.cjs"),t=require("../../headless/overlay.cjs"),n=require("./await-exit.cjs"),r=require("../../headless/focus.cjs"),i=require("./background-lock.cjs");let a=require("@vielzeug/ripple");function o(o){let s=e.lifecycleSignal(o.onCleanup),c=(0,a.signal)(!1),l=`programmatic`,u=i.createBackgroundLock(),d=!1,f=r.createFocusManager({getInitialFocusSelector:()=>o.initialFocus.value,getReturnFocus:()=>o.returnFocus.value,host:o.host,signal:s}),p=()=>{let e=o.dialogRef.value;if(!e?.open||d)return;d=!0,e.classList.add(`closing`);let t=()=>{e.close(),d=!1},r=o.getPanelEl();r?n.awaitExit(r,t,`transition`):t()},m=e=>o.host.dispatchEvent(new CustomEvent(`close-request`,{bubbles:!0,cancelable:!0,composed:!0,detail:{reason:e,...o.closeRequestDetail?.(e)}})),h=t.createOverlayControl({getBoundary:()=>o.host,getPanel:()=>{let e=o.getPanelEl();return e instanceof HTMLElement?e:null},isOpen:()=>c.value,onOpen:o.onOpen,setOpen:(e,t)=>{let n=o.dialogRef.value;if(n){if(e){if(n.open)return;n.classList.remove(`closing`),f.captureReturnFocus(),o.beforeOpen?.(n),n.showModal(),u.lock(o.host),f.applyInitialFocus(),c.value=!0;return}if(n.open){l=t,(o.performClose??(e=>e.close()))(n,t);return}c.value=!1}},signal:s}),g=e=>{m(e)&&h.close(e,!1)};o.host.addEventListener(`command`,e=>{let t=e.command;t===`show-modal`?h.open(`trigger`):(t===`close`||t===`request-close`)&&g(`trigger`)},{signal:s});let _=e=>{e.target===o.dialogRef.value&&(e.preventDefault(),!o.isPersistent()&&g(`escape`))},v=e=>{o.isPersistent()||e.target===o.dialogRef.value&&g(`outsideClick`)},y=e=>{if(e&&e.target!==o.dialogRef.value)return;u.unlock(),o.host.removeAttribute(`open`),c.value=!1,f.restoreFocus();let t=l;l=`programmatic`,o.onNativeClose?.(t)},b=()=>{let e=o.dialogRef.value;e&&o.onEvent(e,`close`,y),(0,a.watch)(o.openProp,e=>{e?h.open(`programmatic`):h.close(`programmatic`,!1)},{immediate:!0})};return{closeWithAnimation:p,dispatchCloseRequest:m,handleBackdropClick:v,handleCancel:_,isOpen:c,overlay:h,requestClose:g,setupNativeListeners:()=>{let e=o.dialogRef.value;e&&(b(),o.onEvent(e,`click`,v),o.onEvent(e,`cancel`,_))},watchOpenProp:b}}exports.useDialogControl=o;
|
|
2
2
|
//# sourceMappingURL=use-dialog.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-dialog.cjs","names":[],"sources":["../../../src/overlay/shared/use-dialog.ts"],"sourcesContent":["import { type Readable, type Signal, signal, watch } from '@vielzeug/ripple';\n\nimport {\n lifecycleSignal,\n createOverlayControl,\n type DialogCloseReason,\n type OverlayControl,\n type OverlayOpenReason,\n} from '../../headless';\nimport { createFocusManager } from '../../headless/focus';\nimport { awaitExit } from './await-exit';\nimport { createBackgroundLock } from './background-lock';\n\n// Invoker Commands API — not yet in lib.dom.d.ts\ninterface CommandEvent extends Event {\n command: string;\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type UseDialogOptions = {\n /** Called after showModal() but before isOpen = true. Use to clear drag styles etc. */\n beforeOpen?: (dialog: HTMLDialogElement) => void;\n /** Extra properties merged into the `close-request` custom event detail. */\n closeRequestDetail?: (reason: Exclude<DialogCloseReason, 'programmatic'>) => Record<string, unknown>;\n dialogRef: { value: HTMLDialogElement | null | undefined };\n getPanelEl: () => HTMLElement | null | undefined;\n host: HTMLElement;\n initialFocus: Readable<string | undefined>;\n isPersistent: () => boolean;\n /** Cleanup registrar from the component setup ctx. Automatically called on disconnect. */\n onCleanup: (fn: () => void) => void;\n /**\n * Scoped event listener registrar from the component setup ctx.\n * Automatically removed on component disconnect.\n */\n onEvent: <K extends keyof HTMLElementEventMap>(\n target: EventTarget | null | undefined,\n event: K,\n listener: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n ) => void;\n /**\n * Called after the native `close` event fires — after background unlock,\n * isOpen reset, and focus restore. Use to emit component events.\n */\n onNativeClose?: (reason: DialogCloseReason) => void;\n /** Called by the overlay on open. Use to emit events. */\n onOpen?: (reason: OverlayOpenReason) => void;\n /** Open prop from the component — drives programmatic open/close via watch. */\n openProp: Readable<boolean | undefined>;\n /**\n * Called by the overlay when closing. Orchestrates the close animation.\n * Default: `dialog.close()`. Override in dialog.ts to add the CSS exit animation.\n */\n performClose?: (dialog: HTMLDialogElement, reason: DialogCloseReason) => void;\n returnFocus: Readable<boolean | undefined>;\n};\n\nexport type UseDialogHandle = {\n closeWithAnimation: () => void;\n /**\n * Dispatch a cancelable `close-request` event on the host. Returns true when\n * the close is allowed (event not prevented), false when it was cancelled.\n */\n dispatchCloseRequest: (reason: Exclude<DialogCloseReason, 'programmatic'>) => boolean;\n handleBackdropClick: (e: MouseEvent) => void;\n handleCancel: (e: Event) => void;\n isOpen: Signal<boolean>;\n /** The overlay control — open/close/toggle/dispose. */\n overlay: OverlayControl;\n /**\n * Dispatch `close-request`; if allowed, call `overlay.close()`.\n */\n requestClose: (reason: Exclude<DialogCloseReason, 'programmatic'>) => void;\n /**\n * Registers the open-prop watcher AND standard click/cancel event listeners on\n * the dialog element (backdrop click-to-close, Escape via the native `cancel`\n * event). Use for components that need standard dialog behavior.\n * Call inside `onMounted()`.\n */\n setupNativeListeners: () => void;\n /**\n * Registers only the open-prop watcher (without adding click/cancel listeners).\n * Use for components like drawer that register their own event handlers.\n * Call inside `onMounted()`.\n */\n watchOpenProp: () => void;\n};\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Shared dialog-control composable for `ore-dialog` and `ore-drawer`.\n *\n * Owns: `isOpen`, close-reason tracking, focus management, `overlay`,\n * `requestClose`, background lock/unlock, and the `close` event handler.\n * Components supply only their unique behavior via callbacks and `onNativeClose`.\n */\nexport function useDialogControl(options: UseDialogOptions): UseDialogHandle {\n const abortSignal = lifecycleSignal(options.onCleanup);\n const isOpen = signal(false);\n // Internal close-reason: set atomically before dialog.close() fires.\n let pendingCloseReason: DialogCloseReason = 'programmatic';\n const bgLock = createBackgroundLock();\n let isClosing = false;\n\n // ── Focus management ──────────────────────────────────────────────────────\n const focus = createFocusManager({\n getInitialFocusSelector: () => options.initialFocus.value,\n getReturnFocus: () => options.returnFocus.value,\n host: options.host,\n });\n // ─────────────────────────────────────────────────────────────────────────\n\n const closeWithAnimation = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog?.open || isClosing) return;\n\n isClosing = true;\n dialog.classList.add('closing');\n\n const finish = () => {\n dialog.close();\n // Do NOT remove 'closing' here — removing it while the native ::backdrop is\n // still held in the top layer by the 'overlay allow-discrete' transition\n // would revert its opacity to 1 and cause a visible flash. The class is\n // cleaned up at the start of the next open cycle (see setOpen below).\n isClosing = false;\n };\n\n const panel = options.getPanelEl();\n\n if (panel) {\n awaitExit(panel, finish, 'transition');\n } else {\n finish();\n }\n };\n\n const dispatchCloseRequest = (reason: Exclude<DialogCloseReason, 'programmatic'>): boolean => {\n return options.host.dispatchEvent(\n new CustomEvent('close-request', {\n bubbles: true,\n cancelable: true,\n composed: true,\n detail: { reason, ...options.closeRequestDetail?.(reason) },\n }),\n );\n };\n\n const overlay = createOverlayControl({\n getBoundary: () => options.host,\n getPanel: () => {\n const panel = options.getPanelEl();\n\n return panel instanceof HTMLElement ? panel : null;\n },\n isOpen: () => isOpen.value,\n onOpen: options.onOpen,\n setOpen: (next, reason) => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n if (next) {\n if (dialog.open) return;\n\n // Clean up any leftover 'closing' class from the previous close animation\n // before opening so the entry @starting-style and transition work correctly.\n dialog.classList.remove('closing');\n focus.captureReturnFocus();\n options.beforeOpen?.(dialog);\n dialog.showModal();\n bgLock.lock(options.host);\n focus.applyInitialFocus();\n isOpen.value = true;\n\n return;\n }\n\n if (dialog.open) {\n // Capture reason before calling performClose so handleNativeClose can read it.\n pendingCloseReason = reason as DialogCloseReason;\n\n const performClose = options.performClose ?? ((d) => d.close());\n\n performClose(dialog, reason as DialogCloseReason);\n\n return;\n }\n\n isOpen.value = false;\n },\n signal: abortSignal,\n });\n\n const requestClose = (reason: Exclude<DialogCloseReason, 'programmatic'>): void => {\n const allowed = dispatchCloseRequest(reason);\n\n if (!allowed) return;\n\n overlay.close(reason, false);\n };\n\n // Invoker Commands API — allows declarative open/close from outside the component:\n // <button commandfor=\"ore-dialog-id\" command=\"show-modal\">Open</button>\n // <button commandfor=\"ore-dialog-id\" command=\"close\">Close</button>\n options.host.addEventListener(\n 'command',\n (e: Event) => {\n const cmd = (e as CommandEvent).command;\n\n if (cmd === 'show-modal') overlay.open('trigger');\n else if (cmd === 'close' || cmd === 'request-close') requestClose('trigger');\n },\n { signal: abortSignal },\n );\n\n // The native `<dialog>` element auto-closes on Escape via its own close-watcher, which\n // dispatches a cancelable `cancel` event before `close`. Suppressing/redirecting that is the\n // spec-correct hook — relying on `keydown`'s `preventDefault()` to stop the close-watcher is\n // implementation-specific, not guaranteed across browsers.\n const handleCancel = (e: Event): void => {\n // See `handleNativeClose`'s comment: guard against a same-named bubbling event from a\n // descendant field being misread as this dialog's own native event.\n if (e.target !== options.dialogRef.value) return;\n\n e.preventDefault();\n\n if (options.isPersistent()) return;\n\n requestClose('escape');\n };\n\n const handleBackdropClick = (e: MouseEvent): void => {\n if (options.isPersistent()) return;\n\n if (e.target === options.dialogRef.value) requestClose('outsideClick');\n };\n\n // ── Internal native close handler ─────────────────────────────────────────\n // `e.target` must be checked against the native `<dialog>` itself, the same way\n // `handleBackdropClick` already does: a bubbling `close`-named event fired by *any* descendant\n // component reaches this listener too — regardless of that event's own `composed` flag, since\n // slot-assignment-based event-path computation (a slotted descendant's \"parent\" is the `<slot>`\n // projecting it) isn't gated by `composed` the way crossing back out of a shadow root is. Some\n // fields nested here (`ore-select`, `ore-combobox`, …) emit their own public `close` event when\n // *their* dropdown closes — without this check, selecting an option in one of those closes this\n // dialog too, misreading the field's own event as this dialog's native close.\n const handleNativeClose = (e?: Event): void => {\n if (e && e.target !== options.dialogRef.value) return;\n\n bgLock.unlock();\n options.host.removeAttribute('open');\n isOpen.value = false;\n focus.restoreFocus();\n\n const reason = pendingCloseReason;\n\n pendingCloseReason = 'programmatic';\n options.onNativeClose?.(reason);\n };\n\n const watchOpenProp = (): void => {\n const dialog = options.dialogRef.value;\n\n if (dialog) options.onEvent(dialog, 'close', handleNativeClose);\n\n watch(\n options.openProp,\n (open) => {\n if (open) {\n overlay.open('programmatic');\n } else {\n overlay.close('programmatic', false);\n }\n },\n { immediate: true },\n );\n };\n\n const setupNativeListeners = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n watchOpenProp();\n options.onEvent(dialog, 'click', handleBackdropClick);\n options.onEvent(dialog, 'cancel', handleCancel);\n };\n\n return {\n closeWithAnimation,\n dispatchCloseRequest,\n handleBackdropClick,\n handleCancel,\n isOpen,\n overlay,\n requestClose,\n setupNativeListeners,\n watchOpenProp,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-dialog.cjs","names":[],"sources":["../../../src/overlay/shared/use-dialog.ts"],"sourcesContent":["import { type Readable, type Signal, signal, watch } from '@vielzeug/ripple';\n\nimport {\n lifecycleSignal,\n createOverlayControl,\n type DialogCloseReason,\n type OverlayControl,\n type OverlayOpenReason,\n} from '../../headless';\nimport { createFocusManager } from '../../headless/focus';\nimport { awaitExit } from './await-exit';\nimport { createBackgroundLock } from './background-lock';\n\n// Invoker Commands API — not yet in lib.dom.d.ts\ninterface CommandEvent extends Event {\n command: string;\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type UseDialogOptions = {\n /** Called after showModal() but before isOpen = true. Use to clear drag styles etc. */\n beforeOpen?: (dialog: HTMLDialogElement) => void;\n /** Extra properties merged into the `close-request` custom event detail. */\n closeRequestDetail?: (reason: Exclude<DialogCloseReason, 'programmatic'>) => Record<string, unknown>;\n dialogRef: { value: HTMLDialogElement | null | undefined };\n getPanelEl: () => HTMLElement | null | undefined;\n host: HTMLElement;\n initialFocus: Readable<string | undefined>;\n isPersistent: () => boolean;\n /** Cleanup registrar from the component setup ctx. Automatically called on disconnect. */\n onCleanup: (fn: () => void) => void;\n /**\n * Scoped event listener registrar from the component setup ctx.\n * Automatically removed on component disconnect.\n */\n onEvent: <K extends keyof HTMLElementEventMap>(\n target: EventTarget | null | undefined,\n event: K,\n listener: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n ) => void;\n /**\n * Called after the native `close` event fires — after background unlock,\n * isOpen reset, and focus restore. Use to emit component events.\n */\n onNativeClose?: (reason: DialogCloseReason) => void;\n /** Called by the overlay on open. Use to emit events. */\n onOpen?: (reason: OverlayOpenReason) => void;\n /** Open prop from the component — drives programmatic open/close via watch. */\n openProp: Readable<boolean | undefined>;\n /**\n * Called by the overlay when closing. Orchestrates the close animation.\n * Default: `dialog.close()`. Override in dialog.ts to add the CSS exit animation.\n */\n performClose?: (dialog: HTMLDialogElement, reason: DialogCloseReason) => void;\n returnFocus: Readable<boolean | undefined>;\n};\n\nexport type UseDialogHandle = {\n closeWithAnimation: () => void;\n /**\n * Dispatch a cancelable `close-request` event on the host. Returns true when\n * the close is allowed (event not prevented), false when it was cancelled.\n */\n dispatchCloseRequest: (reason: Exclude<DialogCloseReason, 'programmatic'>) => boolean;\n handleBackdropClick: (e: MouseEvent) => void;\n handleCancel: (e: Event) => void;\n isOpen: Signal<boolean>;\n /** The overlay control — open/close/toggle/dispose. */\n overlay: OverlayControl;\n /**\n * Dispatch `close-request`; if allowed, call `overlay.close()`.\n */\n requestClose: (reason: Exclude<DialogCloseReason, 'programmatic'>) => void;\n /**\n * Registers the open-prop watcher AND standard click/cancel event listeners on\n * the dialog element (backdrop click-to-close, Escape via the native `cancel`\n * event). Use for components that need standard dialog behavior.\n * Call inside `onMounted()`.\n */\n setupNativeListeners: () => void;\n /**\n * Registers only the open-prop watcher (without adding click/cancel listeners).\n * Use for components like drawer that register their own event handlers.\n * Call inside `onMounted()`.\n */\n watchOpenProp: () => void;\n};\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Shared dialog-control composable for `ore-dialog` and `ore-drawer`.\n *\n * Owns: `isOpen`, close-reason tracking, focus management, `overlay`,\n * `requestClose`, background lock/unlock, and the `close` event handler.\n * Components supply only their unique behavior via callbacks and `onNativeClose`.\n */\nexport function useDialogControl(options: UseDialogOptions): UseDialogHandle {\n const abortSignal = lifecycleSignal(options.onCleanup);\n const isOpen = signal(false);\n // Internal close-reason: set atomically before dialog.close() fires.\n let pendingCloseReason: DialogCloseReason = 'programmatic';\n const bgLock = createBackgroundLock();\n let isClosing = false;\n\n // ── Focus management ──────────────────────────────────────────────────────\n const focus = createFocusManager({\n getInitialFocusSelector: () => options.initialFocus.value,\n getReturnFocus: () => options.returnFocus.value,\n host: options.host,\n signal: abortSignal,\n });\n // ─────────────────────────────────────────────────────────────────────────\n\n const closeWithAnimation = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog?.open || isClosing) return;\n\n isClosing = true;\n dialog.classList.add('closing');\n\n const finish = () => {\n dialog.close();\n // Do NOT remove 'closing' here — removing it while the native ::backdrop is\n // still held in the top layer by the 'overlay allow-discrete' transition\n // would revert its opacity to 1 and cause a visible flash. The class is\n // cleaned up at the start of the next open cycle (see setOpen below).\n isClosing = false;\n };\n\n const panel = options.getPanelEl();\n\n if (panel) {\n awaitExit(panel, finish, 'transition');\n } else {\n finish();\n }\n };\n\n const dispatchCloseRequest = (reason: Exclude<DialogCloseReason, 'programmatic'>): boolean => {\n return options.host.dispatchEvent(\n new CustomEvent('close-request', {\n bubbles: true,\n cancelable: true,\n composed: true,\n detail: { reason, ...options.closeRequestDetail?.(reason) },\n }),\n );\n };\n\n const overlay = createOverlayControl({\n getBoundary: () => options.host,\n getPanel: () => {\n const panel = options.getPanelEl();\n\n return panel instanceof HTMLElement ? panel : null;\n },\n isOpen: () => isOpen.value,\n onOpen: options.onOpen,\n setOpen: (next, reason) => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n if (next) {\n if (dialog.open) return;\n\n // Clean up any leftover 'closing' class from the previous close animation\n // before opening so the entry @starting-style and transition work correctly.\n dialog.classList.remove('closing');\n focus.captureReturnFocus();\n options.beforeOpen?.(dialog);\n dialog.showModal();\n bgLock.lock(options.host);\n focus.applyInitialFocus();\n isOpen.value = true;\n\n return;\n }\n\n if (dialog.open) {\n // Capture reason before calling performClose so handleNativeClose can read it.\n pendingCloseReason = reason as DialogCloseReason;\n\n const performClose = options.performClose ?? ((d) => d.close());\n\n performClose(dialog, reason as DialogCloseReason);\n\n return;\n }\n\n isOpen.value = false;\n },\n signal: abortSignal,\n });\n\n const requestClose = (reason: Exclude<DialogCloseReason, 'programmatic'>): void => {\n const allowed = dispatchCloseRequest(reason);\n\n if (!allowed) return;\n\n overlay.close(reason, false);\n };\n\n // Invoker Commands API — allows declarative open/close from outside the component:\n // <button commandfor=\"ore-dialog-id\" command=\"show-modal\">Open</button>\n // <button commandfor=\"ore-dialog-id\" command=\"close\">Close</button>\n options.host.addEventListener(\n 'command',\n (e: Event) => {\n const cmd = (e as CommandEvent).command;\n\n if (cmd === 'show-modal') overlay.open('trigger');\n else if (cmd === 'close' || cmd === 'request-close') requestClose('trigger');\n },\n { signal: abortSignal },\n );\n\n // The native `<dialog>` element auto-closes on Escape via its own close-watcher, which\n // dispatches a cancelable `cancel` event before `close`. Suppressing/redirecting that is the\n // spec-correct hook — relying on `keydown`'s `preventDefault()` to stop the close-watcher is\n // implementation-specific, not guaranteed across browsers.\n const handleCancel = (e: Event): void => {\n // See `handleNativeClose`'s comment: guard against a same-named bubbling event from a\n // descendant field being misread as this dialog's own native event.\n if (e.target !== options.dialogRef.value) return;\n\n e.preventDefault();\n\n if (options.isPersistent()) return;\n\n requestClose('escape');\n };\n\n const handleBackdropClick = (e: MouseEvent): void => {\n if (options.isPersistent()) return;\n\n if (e.target === options.dialogRef.value) requestClose('outsideClick');\n };\n\n // ── Internal native close handler ─────────────────────────────────────────\n // `e.target` must be checked against the native `<dialog>` itself, the same way\n // `handleBackdropClick` already does: a bubbling `close`-named event fired by *any* descendant\n // component reaches this listener too — regardless of that event's own `composed` flag, since\n // slot-assignment-based event-path computation (a slotted descendant's \"parent\" is the `<slot>`\n // projecting it) isn't gated by `composed` the way crossing back out of a shadow root is. Some\n // fields nested here (`ore-select`, `ore-combobox`, …) emit their own public `close` event when\n // *their* dropdown closes — without this check, selecting an option in one of those closes this\n // dialog too, misreading the field's own event as this dialog's native close.\n const handleNativeClose = (e?: Event): void => {\n if (e && e.target !== options.dialogRef.value) return;\n\n bgLock.unlock();\n options.host.removeAttribute('open');\n isOpen.value = false;\n focus.restoreFocus();\n\n const reason = pendingCloseReason;\n\n pendingCloseReason = 'programmatic';\n options.onNativeClose?.(reason);\n };\n\n const watchOpenProp = (): void => {\n const dialog = options.dialogRef.value;\n\n if (dialog) options.onEvent(dialog, 'close', handleNativeClose);\n\n watch(\n options.openProp,\n (open) => {\n if (open) {\n overlay.open('programmatic');\n } else {\n overlay.close('programmatic', false);\n }\n },\n { immediate: true },\n );\n };\n\n const setupNativeListeners = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n watchOpenProp();\n options.onEvent(dialog, 'click', handleBackdropClick);\n options.onEvent(dialog, 'cancel', handleCancel);\n };\n\n return {\n closeWithAnimation,\n dispatchCloseRequest,\n handleBackdropClick,\n handleCancel,\n isOpen,\n overlay,\n requestClose,\n setupNativeListeners,\n watchOpenProp,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-dialog.d.ts","sourceRoot":"","sources":["../../../src/overlay/shared/use-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAYxB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uFAAuF;IACvF,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrG,SAAS,EAAE;QAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3D,UAAU,EAAE,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,YAAY,EAAE,MAAM,OAAO,CAAC;IAC5B,0FAA0F;IAC1F,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpC;;;OAGG;IACH,OAAO,EAAE,CAAC,CAAC,SAAS,MAAM,mBAAmB,EAC3C,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EACtC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,IAAI,EAC7C,OAAO,CAAC,EAAE,uBAAuB,KAC9B,IAAI,CAAC;IACV;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACpD,yDAAyD;IACzD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,+EAA+E;IAC/E,QAAQ,EAAE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACxC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9E,WAAW,EAAE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B;;;OAGG;IACH,oBAAoB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,KAAK,OAAO,CAAC;IACtF,mBAAmB,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACxB,uDAAuD;IACvD,OAAO,EAAE,cAAc,CAAC;IACxB;;OAEG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,KAAK,IAAI,CAAC;IAC3E;;;;;OAKG;IACH,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC;;;;OAIG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAIF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"use-dialog.d.ts","sourceRoot":"","sources":["../../../src/overlay/shared/use-dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAYxB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,uFAAuF;IACvF,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrG,SAAS,EAAE;QAAE,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3D,UAAU,EAAE,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3C,YAAY,EAAE,MAAM,OAAO,CAAC;IAC5B,0FAA0F;IAC1F,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpC;;;OAGG;IACH,OAAO,EAAE,CAAC,CAAC,SAAS,MAAM,mBAAmB,EAC3C,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EACtC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,IAAI,EAC7C,OAAO,CAAC,EAAE,uBAAuB,KAC9B,IAAI,CAAC;IACV;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACpD,yDAAyD;IACzD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,+EAA+E;IAC/E,QAAQ,EAAE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACxC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9E,WAAW,EAAE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B;;;OAGG;IACH,oBAAoB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,KAAK,OAAO,CAAC;IACtF,mBAAmB,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACxB,uDAAuD;IACvD,OAAO,EAAE,cAAc,CAAC;IACxB;;OAEG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,KAAK,IAAI,CAAC;IAC3E;;;;;OAKG;IACH,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC;;;;OAIG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAIF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CA8M3E"}
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { lifecycleSignal as e } from "../../headless/ore.js";
|
|
2
2
|
import { createOverlayControl as t } from "../../headless/overlay.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { awaitExit as n } from "./await-exit.js";
|
|
4
|
+
import { createFocusManager as r } from "../../headless/focus.js";
|
|
5
5
|
import { createBackgroundLock as i } from "./background-lock.js";
|
|
6
6
|
import { signal as a, watch as o } from "@vielzeug/ripple";
|
|
7
7
|
//#region src/overlay/shared/use-dialog.ts
|
|
8
8
|
function s(s) {
|
|
9
|
-
let c = e(s.onCleanup), l = a(!1), u = "programmatic", d = i(), f = !1, p =
|
|
9
|
+
let c = e(s.onCleanup), l = a(!1), u = "programmatic", d = i(), f = !1, p = r({
|
|
10
10
|
getInitialFocusSelector: () => s.initialFocus.value,
|
|
11
11
|
getReturnFocus: () => s.returnFocus.value,
|
|
12
|
-
host: s.host
|
|
12
|
+
host: s.host,
|
|
13
|
+
signal: c
|
|
13
14
|
}), m = () => {
|
|
14
15
|
let e = s.dialogRef.value;
|
|
15
16
|
if (!e?.open || f) return;
|
|
16
17
|
f = !0, e.classList.add("closing");
|
|
17
18
|
let t = () => {
|
|
18
19
|
e.close(), f = !1;
|
|
19
|
-
},
|
|
20
|
-
|
|
20
|
+
}, r = s.getPanelEl();
|
|
21
|
+
r ? n(r, t, "transition") : t();
|
|
21
22
|
}, h = (e) => s.host.dispatchEvent(new CustomEvent("close-request", {
|
|
22
23
|
bubbles: !0,
|
|
23
24
|
cancelable: !0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-dialog.js","names":[],"sources":["../../../src/overlay/shared/use-dialog.ts"],"sourcesContent":["import { type Readable, type Signal, signal, watch } from '@vielzeug/ripple';\n\nimport {\n lifecycleSignal,\n createOverlayControl,\n type DialogCloseReason,\n type OverlayControl,\n type OverlayOpenReason,\n} from '../../headless';\nimport { createFocusManager } from '../../headless/focus';\nimport { awaitExit } from './await-exit';\nimport { createBackgroundLock } from './background-lock';\n\n// Invoker Commands API — not yet in lib.dom.d.ts\ninterface CommandEvent extends Event {\n command: string;\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type UseDialogOptions = {\n /** Called after showModal() but before isOpen = true. Use to clear drag styles etc. */\n beforeOpen?: (dialog: HTMLDialogElement) => void;\n /** Extra properties merged into the `close-request` custom event detail. */\n closeRequestDetail?: (reason: Exclude<DialogCloseReason, 'programmatic'>) => Record<string, unknown>;\n dialogRef: { value: HTMLDialogElement | null | undefined };\n getPanelEl: () => HTMLElement | null | undefined;\n host: HTMLElement;\n initialFocus: Readable<string | undefined>;\n isPersistent: () => boolean;\n /** Cleanup registrar from the component setup ctx. Automatically called on disconnect. */\n onCleanup: (fn: () => void) => void;\n /**\n * Scoped event listener registrar from the component setup ctx.\n * Automatically removed on component disconnect.\n */\n onEvent: <K extends keyof HTMLElementEventMap>(\n target: EventTarget | null | undefined,\n event: K,\n listener: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n ) => void;\n /**\n * Called after the native `close` event fires — after background unlock,\n * isOpen reset, and focus restore. Use to emit component events.\n */\n onNativeClose?: (reason: DialogCloseReason) => void;\n /** Called by the overlay on open. Use to emit events. */\n onOpen?: (reason: OverlayOpenReason) => void;\n /** Open prop from the component — drives programmatic open/close via watch. */\n openProp: Readable<boolean | undefined>;\n /**\n * Called by the overlay when closing. Orchestrates the close animation.\n * Default: `dialog.close()`. Override in dialog.ts to add the CSS exit animation.\n */\n performClose?: (dialog: HTMLDialogElement, reason: DialogCloseReason) => void;\n returnFocus: Readable<boolean | undefined>;\n};\n\nexport type UseDialogHandle = {\n closeWithAnimation: () => void;\n /**\n * Dispatch a cancelable `close-request` event on the host. Returns true when\n * the close is allowed (event not prevented), false when it was cancelled.\n */\n dispatchCloseRequest: (reason: Exclude<DialogCloseReason, 'programmatic'>) => boolean;\n handleBackdropClick: (e: MouseEvent) => void;\n handleCancel: (e: Event) => void;\n isOpen: Signal<boolean>;\n /** The overlay control — open/close/toggle/dispose. */\n overlay: OverlayControl;\n /**\n * Dispatch `close-request`; if allowed, call `overlay.close()`.\n */\n requestClose: (reason: Exclude<DialogCloseReason, 'programmatic'>) => void;\n /**\n * Registers the open-prop watcher AND standard click/cancel event listeners on\n * the dialog element (backdrop click-to-close, Escape via the native `cancel`\n * event). Use for components that need standard dialog behavior.\n * Call inside `onMounted()`.\n */\n setupNativeListeners: () => void;\n /**\n * Registers only the open-prop watcher (without adding click/cancel listeners).\n * Use for components like drawer that register their own event handlers.\n * Call inside `onMounted()`.\n */\n watchOpenProp: () => void;\n};\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Shared dialog-control composable for `ore-dialog` and `ore-drawer`.\n *\n * Owns: `isOpen`, close-reason tracking, focus management, `overlay`,\n * `requestClose`, background lock/unlock, and the `close` event handler.\n * Components supply only their unique behavior via callbacks and `onNativeClose`.\n */\nexport function useDialogControl(options: UseDialogOptions): UseDialogHandle {\n const abortSignal = lifecycleSignal(options.onCleanup);\n const isOpen = signal(false);\n // Internal close-reason: set atomically before dialog.close() fires.\n let pendingCloseReason: DialogCloseReason = 'programmatic';\n const bgLock = createBackgroundLock();\n let isClosing = false;\n\n // ── Focus management ──────────────────────────────────────────────────────\n const focus = createFocusManager({\n getInitialFocusSelector: () => options.initialFocus.value,\n getReturnFocus: () => options.returnFocus.value,\n host: options.host,\n });\n // ─────────────────────────────────────────────────────────────────────────\n\n const closeWithAnimation = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog?.open || isClosing) return;\n\n isClosing = true;\n dialog.classList.add('closing');\n\n const finish = () => {\n dialog.close();\n // Do NOT remove 'closing' here — removing it while the native ::backdrop is\n // still held in the top layer by the 'overlay allow-discrete' transition\n // would revert its opacity to 1 and cause a visible flash. The class is\n // cleaned up at the start of the next open cycle (see setOpen below).\n isClosing = false;\n };\n\n const panel = options.getPanelEl();\n\n if (panel) {\n awaitExit(panel, finish, 'transition');\n } else {\n finish();\n }\n };\n\n const dispatchCloseRequest = (reason: Exclude<DialogCloseReason, 'programmatic'>): boolean => {\n return options.host.dispatchEvent(\n new CustomEvent('close-request', {\n bubbles: true,\n cancelable: true,\n composed: true,\n detail: { reason, ...options.closeRequestDetail?.(reason) },\n }),\n );\n };\n\n const overlay = createOverlayControl({\n getBoundary: () => options.host,\n getPanel: () => {\n const panel = options.getPanelEl();\n\n return panel instanceof HTMLElement ? panel : null;\n },\n isOpen: () => isOpen.value,\n onOpen: options.onOpen,\n setOpen: (next, reason) => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n if (next) {\n if (dialog.open) return;\n\n // Clean up any leftover 'closing' class from the previous close animation\n // before opening so the entry @starting-style and transition work correctly.\n dialog.classList.remove('closing');\n focus.captureReturnFocus();\n options.beforeOpen?.(dialog);\n dialog.showModal();\n bgLock.lock(options.host);\n focus.applyInitialFocus();\n isOpen.value = true;\n\n return;\n }\n\n if (dialog.open) {\n // Capture reason before calling performClose so handleNativeClose can read it.\n pendingCloseReason = reason as DialogCloseReason;\n\n const performClose = options.performClose ?? ((d) => d.close());\n\n performClose(dialog, reason as DialogCloseReason);\n\n return;\n }\n\n isOpen.value = false;\n },\n signal: abortSignal,\n });\n\n const requestClose = (reason: Exclude<DialogCloseReason, 'programmatic'>): void => {\n const allowed = dispatchCloseRequest(reason);\n\n if (!allowed) return;\n\n overlay.close(reason, false);\n };\n\n // Invoker Commands API — allows declarative open/close from outside the component:\n // <button commandfor=\"ore-dialog-id\" command=\"show-modal\">Open</button>\n // <button commandfor=\"ore-dialog-id\" command=\"close\">Close</button>\n options.host.addEventListener(\n 'command',\n (e: Event) => {\n const cmd = (e as CommandEvent).command;\n\n if (cmd === 'show-modal') overlay.open('trigger');\n else if (cmd === 'close' || cmd === 'request-close') requestClose('trigger');\n },\n { signal: abortSignal },\n );\n\n // The native `<dialog>` element auto-closes on Escape via its own close-watcher, which\n // dispatches a cancelable `cancel` event before `close`. Suppressing/redirecting that is the\n // spec-correct hook — relying on `keydown`'s `preventDefault()` to stop the close-watcher is\n // implementation-specific, not guaranteed across browsers.\n const handleCancel = (e: Event): void => {\n // See `handleNativeClose`'s comment: guard against a same-named bubbling event from a\n // descendant field being misread as this dialog's own native event.\n if (e.target !== options.dialogRef.value) return;\n\n e.preventDefault();\n\n if (options.isPersistent()) return;\n\n requestClose('escape');\n };\n\n const handleBackdropClick = (e: MouseEvent): void => {\n if (options.isPersistent()) return;\n\n if (e.target === options.dialogRef.value) requestClose('outsideClick');\n };\n\n // ── Internal native close handler ─────────────────────────────────────────\n // `e.target` must be checked against the native `<dialog>` itself, the same way\n // `handleBackdropClick` already does: a bubbling `close`-named event fired by *any* descendant\n // component reaches this listener too — regardless of that event's own `composed` flag, since\n // slot-assignment-based event-path computation (a slotted descendant's \"parent\" is the `<slot>`\n // projecting it) isn't gated by `composed` the way crossing back out of a shadow root is. Some\n // fields nested here (`ore-select`, `ore-combobox`, …) emit their own public `close` event when\n // *their* dropdown closes — without this check, selecting an option in one of those closes this\n // dialog too, misreading the field's own event as this dialog's native close.\n const handleNativeClose = (e?: Event): void => {\n if (e && e.target !== options.dialogRef.value) return;\n\n bgLock.unlock();\n options.host.removeAttribute('open');\n isOpen.value = false;\n focus.restoreFocus();\n\n const reason = pendingCloseReason;\n\n pendingCloseReason = 'programmatic';\n options.onNativeClose?.(reason);\n };\n\n const watchOpenProp = (): void => {\n const dialog = options.dialogRef.value;\n\n if (dialog) options.onEvent(dialog, 'close', handleNativeClose);\n\n watch(\n options.openProp,\n (open) => {\n if (open) {\n overlay.open('programmatic');\n } else {\n overlay.close('programmatic', false);\n }\n },\n { immediate: true },\n );\n };\n\n const setupNativeListeners = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n watchOpenProp();\n options.onEvent(dialog, 'click', handleBackdropClick);\n options.onEvent(dialog, 'cancel', handleCancel);\n };\n\n return {\n closeWithAnimation,\n dispatchCloseRequest,\n handleBackdropClick,\n handleCancel,\n isOpen,\n overlay,\n requestClose,\n setupNativeListeners,\n watchOpenProp,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-dialog.js","names":[],"sources":["../../../src/overlay/shared/use-dialog.ts"],"sourcesContent":["import { type Readable, type Signal, signal, watch } from '@vielzeug/ripple';\n\nimport {\n lifecycleSignal,\n createOverlayControl,\n type DialogCloseReason,\n type OverlayControl,\n type OverlayOpenReason,\n} from '../../headless';\nimport { createFocusManager } from '../../headless/focus';\nimport { awaitExit } from './await-exit';\nimport { createBackgroundLock } from './background-lock';\n\n// Invoker Commands API — not yet in lib.dom.d.ts\ninterface CommandEvent extends Event {\n command: string;\n}\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type UseDialogOptions = {\n /** Called after showModal() but before isOpen = true. Use to clear drag styles etc. */\n beforeOpen?: (dialog: HTMLDialogElement) => void;\n /** Extra properties merged into the `close-request` custom event detail. */\n closeRequestDetail?: (reason: Exclude<DialogCloseReason, 'programmatic'>) => Record<string, unknown>;\n dialogRef: { value: HTMLDialogElement | null | undefined };\n getPanelEl: () => HTMLElement | null | undefined;\n host: HTMLElement;\n initialFocus: Readable<string | undefined>;\n isPersistent: () => boolean;\n /** Cleanup registrar from the component setup ctx. Automatically called on disconnect. */\n onCleanup: (fn: () => void) => void;\n /**\n * Scoped event listener registrar from the component setup ctx.\n * Automatically removed on component disconnect.\n */\n onEvent: <K extends keyof HTMLElementEventMap>(\n target: EventTarget | null | undefined,\n event: K,\n listener: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n ) => void;\n /**\n * Called after the native `close` event fires — after background unlock,\n * isOpen reset, and focus restore. Use to emit component events.\n */\n onNativeClose?: (reason: DialogCloseReason) => void;\n /** Called by the overlay on open. Use to emit events. */\n onOpen?: (reason: OverlayOpenReason) => void;\n /** Open prop from the component — drives programmatic open/close via watch. */\n openProp: Readable<boolean | undefined>;\n /**\n * Called by the overlay when closing. Orchestrates the close animation.\n * Default: `dialog.close()`. Override in dialog.ts to add the CSS exit animation.\n */\n performClose?: (dialog: HTMLDialogElement, reason: DialogCloseReason) => void;\n returnFocus: Readable<boolean | undefined>;\n};\n\nexport type UseDialogHandle = {\n closeWithAnimation: () => void;\n /**\n * Dispatch a cancelable `close-request` event on the host. Returns true when\n * the close is allowed (event not prevented), false when it was cancelled.\n */\n dispatchCloseRequest: (reason: Exclude<DialogCloseReason, 'programmatic'>) => boolean;\n handleBackdropClick: (e: MouseEvent) => void;\n handleCancel: (e: Event) => void;\n isOpen: Signal<boolean>;\n /** The overlay control — open/close/toggle/dispose. */\n overlay: OverlayControl;\n /**\n * Dispatch `close-request`; if allowed, call `overlay.close()`.\n */\n requestClose: (reason: Exclude<DialogCloseReason, 'programmatic'>) => void;\n /**\n * Registers the open-prop watcher AND standard click/cancel event listeners on\n * the dialog element (backdrop click-to-close, Escape via the native `cancel`\n * event). Use for components that need standard dialog behavior.\n * Call inside `onMounted()`.\n */\n setupNativeListeners: () => void;\n /**\n * Registers only the open-prop watcher (without adding click/cancel listeners).\n * Use for components like drawer that register their own event handlers.\n * Call inside `onMounted()`.\n */\n watchOpenProp: () => void;\n};\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\n/**\n * Shared dialog-control composable for `ore-dialog` and `ore-drawer`.\n *\n * Owns: `isOpen`, close-reason tracking, focus management, `overlay`,\n * `requestClose`, background lock/unlock, and the `close` event handler.\n * Components supply only their unique behavior via callbacks and `onNativeClose`.\n */\nexport function useDialogControl(options: UseDialogOptions): UseDialogHandle {\n const abortSignal = lifecycleSignal(options.onCleanup);\n const isOpen = signal(false);\n // Internal close-reason: set atomically before dialog.close() fires.\n let pendingCloseReason: DialogCloseReason = 'programmatic';\n const bgLock = createBackgroundLock();\n let isClosing = false;\n\n // ── Focus management ──────────────────────────────────────────────────────\n const focus = createFocusManager({\n getInitialFocusSelector: () => options.initialFocus.value,\n getReturnFocus: () => options.returnFocus.value,\n host: options.host,\n signal: abortSignal,\n });\n // ─────────────────────────────────────────────────────────────────────────\n\n const closeWithAnimation = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog?.open || isClosing) return;\n\n isClosing = true;\n dialog.classList.add('closing');\n\n const finish = () => {\n dialog.close();\n // Do NOT remove 'closing' here — removing it while the native ::backdrop is\n // still held in the top layer by the 'overlay allow-discrete' transition\n // would revert its opacity to 1 and cause a visible flash. The class is\n // cleaned up at the start of the next open cycle (see setOpen below).\n isClosing = false;\n };\n\n const panel = options.getPanelEl();\n\n if (panel) {\n awaitExit(panel, finish, 'transition');\n } else {\n finish();\n }\n };\n\n const dispatchCloseRequest = (reason: Exclude<DialogCloseReason, 'programmatic'>): boolean => {\n return options.host.dispatchEvent(\n new CustomEvent('close-request', {\n bubbles: true,\n cancelable: true,\n composed: true,\n detail: { reason, ...options.closeRequestDetail?.(reason) },\n }),\n );\n };\n\n const overlay = createOverlayControl({\n getBoundary: () => options.host,\n getPanel: () => {\n const panel = options.getPanelEl();\n\n return panel instanceof HTMLElement ? panel : null;\n },\n isOpen: () => isOpen.value,\n onOpen: options.onOpen,\n setOpen: (next, reason) => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n if (next) {\n if (dialog.open) return;\n\n // Clean up any leftover 'closing' class from the previous close animation\n // before opening so the entry @starting-style and transition work correctly.\n dialog.classList.remove('closing');\n focus.captureReturnFocus();\n options.beforeOpen?.(dialog);\n dialog.showModal();\n bgLock.lock(options.host);\n focus.applyInitialFocus();\n isOpen.value = true;\n\n return;\n }\n\n if (dialog.open) {\n // Capture reason before calling performClose so handleNativeClose can read it.\n pendingCloseReason = reason as DialogCloseReason;\n\n const performClose = options.performClose ?? ((d) => d.close());\n\n performClose(dialog, reason as DialogCloseReason);\n\n return;\n }\n\n isOpen.value = false;\n },\n signal: abortSignal,\n });\n\n const requestClose = (reason: Exclude<DialogCloseReason, 'programmatic'>): void => {\n const allowed = dispatchCloseRequest(reason);\n\n if (!allowed) return;\n\n overlay.close(reason, false);\n };\n\n // Invoker Commands API — allows declarative open/close from outside the component:\n // <button commandfor=\"ore-dialog-id\" command=\"show-modal\">Open</button>\n // <button commandfor=\"ore-dialog-id\" command=\"close\">Close</button>\n options.host.addEventListener(\n 'command',\n (e: Event) => {\n const cmd = (e as CommandEvent).command;\n\n if (cmd === 'show-modal') overlay.open('trigger');\n else if (cmd === 'close' || cmd === 'request-close') requestClose('trigger');\n },\n { signal: abortSignal },\n );\n\n // The native `<dialog>` element auto-closes on Escape via its own close-watcher, which\n // dispatches a cancelable `cancel` event before `close`. Suppressing/redirecting that is the\n // spec-correct hook — relying on `keydown`'s `preventDefault()` to stop the close-watcher is\n // implementation-specific, not guaranteed across browsers.\n const handleCancel = (e: Event): void => {\n // See `handleNativeClose`'s comment: guard against a same-named bubbling event from a\n // descendant field being misread as this dialog's own native event.\n if (e.target !== options.dialogRef.value) return;\n\n e.preventDefault();\n\n if (options.isPersistent()) return;\n\n requestClose('escape');\n };\n\n const handleBackdropClick = (e: MouseEvent): void => {\n if (options.isPersistent()) return;\n\n if (e.target === options.dialogRef.value) requestClose('outsideClick');\n };\n\n // ── Internal native close handler ─────────────────────────────────────────\n // `e.target` must be checked against the native `<dialog>` itself, the same way\n // `handleBackdropClick` already does: a bubbling `close`-named event fired by *any* descendant\n // component reaches this listener too — regardless of that event's own `composed` flag, since\n // slot-assignment-based event-path computation (a slotted descendant's \"parent\" is the `<slot>`\n // projecting it) isn't gated by `composed` the way crossing back out of a shadow root is. Some\n // fields nested here (`ore-select`, `ore-combobox`, …) emit their own public `close` event when\n // *their* dropdown closes — without this check, selecting an option in one of those closes this\n // dialog too, misreading the field's own event as this dialog's native close.\n const handleNativeClose = (e?: Event): void => {\n if (e && e.target !== options.dialogRef.value) return;\n\n bgLock.unlock();\n options.host.removeAttribute('open');\n isOpen.value = false;\n focus.restoreFocus();\n\n const reason = pendingCloseReason;\n\n pendingCloseReason = 'programmatic';\n options.onNativeClose?.(reason);\n };\n\n const watchOpenProp = (): void => {\n const dialog = options.dialogRef.value;\n\n if (dialog) options.onEvent(dialog, 'close', handleNativeClose);\n\n watch(\n options.openProp,\n (open) => {\n if (open) {\n overlay.open('programmatic');\n } else {\n overlay.close('programmatic', false);\n }\n },\n { immediate: true },\n );\n };\n\n const setupNativeListeners = (): void => {\n const dialog = options.dialogRef.value;\n\n if (!dialog) return;\n\n watchOpenProp();\n options.onEvent(dialog, 'click', handleBackdropClick);\n options.onEvent(dialog, 'cancel', handleCancel);\n };\n\n return {\n closeWithAnimation,\n dispatchCloseRequest,\n handleBackdropClick,\n handleCancel,\n isOpen,\n overlay,\n requestClose,\n setupNativeListeners,\n watchOpenProp,\n };\n}\n"],"mappings":"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"}
|
package/dist/progress.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./shared/prop-bundles.cjs"),r=require("./feedback/progress/progress.css.cjs");let i=require("@vielzeug/ore"),a=require("@vielzeug/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/accessibility.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./shared/prop-bundles.cjs"),r=require("./feedback/progress/progress.css.cjs");let i=require("@vielzeug/ore"),a=require("@vielzeug/ripple");var o=`ore-progress`;(0,i.define)(o,{props:{...n.themableBundle,...n.sizableBundle,"floating-label":i.prop.string(),indeterminate:i.prop.bool(!1),label:i.prop.string(),max:i.prop.number(100),title:i.prop.string(),type:i.prop.oneOf([`linear`,`circular`,`vertical`],`linear`),value:i.prop.number(0),"value-text":i.prop.string()},setup(e){let t=(0,i.getHost)(),n=i.watchEffect,r=2*Math.PI*45,o=(0,a.computed)(()=>`${Math.max(0,Math.min(Number(e.value.value),Number(e.max.value)))/Math.max(1,Number(e.max.value))*100}%`),s=(0,a.computed)(()=>{let t=Math.max(0,Math.min(Number(e.value.value),Number(e.max.value))),n=Math.max(1,Number(e.max.value));return r-t/n*r}),c=()=>e.indeterminate.value?null:String(e.value.value),l=()=>e.label.value??e.title.value??`Progress`,u=(0,i.styleMap)({"--_circ":`${r}px`}),d=()=>e.indeterminate.value?void 0:`${r}px`,f=()=>e.indeterminate.value?void 0:`${s.value}px`,p=(0,a.computed)(()=>e.type.value===`vertical`),m=(0,i.styleMap)({height:()=>!e.indeterminate.value&&p.value?o.value:null,width:()=>!e.indeterminate.value&&!p.value?o.value:null});n(()=>{t.style.setProperty(`--_percent`,e.indeterminate.value?`0%`:o.value)});let h=()=>i.html` <div
|
|
2
2
|
class="circular-track"
|
|
3
3
|
role="progressbar"
|
|
4
|
-
:aria-valuenow="${
|
|
4
|
+
:aria-valuenow="${c}"
|
|
5
5
|
aria-valuemin="0"
|
|
6
6
|
:aria-valuemax="${e.max}"
|
|
7
|
-
:aria-label="${
|
|
7
|
+
:aria-label="${l}"
|
|
8
8
|
:aria-valuetext="${e[`value-text`]}"
|
|
9
|
-
:style="${
|
|
9
|
+
:style="${u}">
|
|
10
10
|
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
|
11
11
|
<circle class="circle-bg" cx="50" cy="50" r="${45}"></circle>
|
|
12
12
|
<circle
|
|
@@ -14,33 +14,33 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
14
14
|
cx="50"
|
|
15
15
|
cy="50"
|
|
16
16
|
r="${45}"
|
|
17
|
-
:stroke-dasharray="${
|
|
18
|
-
:stroke-dashoffset="${
|
|
17
|
+
:stroke-dasharray="${d}"
|
|
18
|
+
:stroke-dashoffset="${f}"></circle>
|
|
19
19
|
</svg>
|
|
20
20
|
<div class="circular-inner">
|
|
21
21
|
<span class="circular-label">${()=>e.label.value??``}</span>
|
|
22
22
|
<span class="circular-title">${()=>e.title.value??``}</span>
|
|
23
23
|
</div>
|
|
24
|
-
</div>`,
|
|
24
|
+
</div>`,g=()=>i.html` <div class="wrapper">
|
|
25
25
|
<div class="header">
|
|
26
26
|
<span class="progress-title">${()=>e.title.value??``}</span>
|
|
27
27
|
<span class="end-label header-label">${()=>e.label.value??``}</span>
|
|
28
28
|
</div>
|
|
29
|
-
<div :class=${()=>`bar-row${
|
|
29
|
+
<div :class=${()=>`bar-row${p.value?` bar-row-vertical`:``}`}>
|
|
30
30
|
<div class="track-outer">
|
|
31
31
|
<div
|
|
32
32
|
class="track"
|
|
33
33
|
role="progressbar"
|
|
34
|
-
:aria-valuenow="${
|
|
34
|
+
:aria-valuenow="${c}"
|
|
35
35
|
aria-valuemin="0"
|
|
36
36
|
:aria-valuemax="${e.max}"
|
|
37
|
-
:aria-label="${
|
|
37
|
+
:aria-label="${l}"
|
|
38
38
|
:aria-valuetext="${e[`value-text`]}">
|
|
39
|
-
<div class="fill" part="fill" :style="${
|
|
39
|
+
<div class="fill" part="fill" :style="${m}"></div>
|
|
40
40
|
</div>
|
|
41
|
-
${()=>
|
|
41
|
+
${()=>p.value?null:i.html`<span class="floating-label">${e[`floating-label`]}</span>`}
|
|
42
42
|
</div>
|
|
43
43
|
<span class="end-label row-label">${()=>e.label.value??``}</span>
|
|
44
44
|
</div>
|
|
45
|
-
</div>`;return i.html` ${()=>e.type.value===`circular`?
|
|
45
|
+
</div>`;return i.html` ${()=>e.type.value===`circular`?h():g()} `},styles:[t.colorThemeMixin,t.forcedColorsMixin,e.reducedMotionMixin,r.default]}),exports.PROGRESS_TAG=o;
|
|
46
46
|
//# sourceMappingURL=progress.cjs.map
|
package/dist/progress.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.cjs","names":[],"sources":["../src/feedback/progress/progress.ts"],"sourcesContent":["import { define, html, prop, getHost, watchEffect } from '@vielzeug/ore';\nimport { styleMap } from '@vielzeug/ore/directives';\nimport { computed } from '@vielzeug/ripple';\n\nimport type { ComponentSize, ThemeColor } from '../../types';\n\nimport { sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport componentStyles from './progress.css?inline';\n\n/** Progress bar component properties */\nexport type OreProgressProps = {\n /** Theme color for the fill bar */\n color?: ThemeColor;\n /** Floating chip centered above the fill endpoint (linear only). Hidden in indeterminate mode. Position formula: left = fill% − half chip width (CSS: left:X%; transform:translateX(−50%)). */\n 'floating-label'?: string;\n /** When true, shows an infinite animation — use when progress is unknown. */\n indeterminate?: boolean;\n /** Accessible name AND visible text label.\n * - Linear without `title`: rendered at the end of the bar.\n * - Linear with `title`: moved into the header row above the bar.\n * - Circular: large text centered inside the ring. */\n label?: string;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /** Size variant controlling bar height */\n size?: ComponentSize;\n /** Title text.\n * - Linear: displayed as a header above the bar; moves `label` into the header row.\n * - Circular: smaller text displayed below the `label` inside the ring. */\n title?: string;\n /** 'linear' (default), 'circular', or 'vertical' */\n type?: 'linear' | 'circular' | 'vertical';\n /** Current progress value (0 to `max`). Ignored when `indeterminate`. */\n value?: number;\n /** Human-readable value text for screen readers (e.g. \"Step 2 of 5\", \"75%\"). Overrides the raw aria-valuenow when set. */\n 'value-text'?: string;\n};\n\n/**\n * A linear progress bar for conveying operation progress.\n * Supports determinate (known value) and indeterminate (unknown duration) modes.\n *\n * @element ore-progress\n *\n * @attr {number} value - Current value (0–max). Defaults to 0.\n * @attr {number} max - Maximum value. Defaults to 100.\n * @attr {boolean} indeterminate - Show infinite animation (ignores value/max).\n * @attr {string} color - Theme color: 'primary' | 'success' | 'warning' | 'error' | …\n * @attr {string} size - Bar height/width: 'sm' | 'md' | 'lg'\n * @attr {string} type - 'linear' (default) | 'circular' | 'vertical'\n *\n * @cssprop --progress-width - Bar width override (vertical only)\n * @attr {string} label - Visible text label + accessible name. Linear: at bar end (or header row with title). Circular: large text centered inside the ring.\n * @attr {string} title - Title text. Linear: header above the bar (moves label to header row). Circular: smaller text below the label inside the ring.\n * @attr {string} floating-label - Floating chip centered above the fill endpoint (linear only); hidden when indeterminate.\n *\n * @cssprop --progress-height - Bar height override\n * @cssprop --progress-track-bg - Track background color\n * @cssprop --progress-fill - Fill bar color\n * @cssprop --progress-radius - Border radius\n * @cssprop --progress-label-gap - Gap between header/bar row and between bar and trailing label (default 0.25 rem)\n * @cssprop --progress-title-color - Title text color (defaults to currentColor)\n * @cssprop --progress-label-color - Label text color (defaults to currentColor)\n * @cssprop --progress-circle-size - Circular indicator diameter (default 6rem)\n * @cssprop --progress-circular-label-size - Font size of the label inside the ring (default --text-xl)\n * @cssprop --progress-circular-title-size - Font size of the title inside the ring (default --text-xs)\n *\n * @part fill - Progress fill element.\n * @example\n * ```html\n * <ore-progress value=\"45\"></ore-progress>\n * <ore-progress value=\"75\" max=\"100\" color=\"success\" size=\"lg\"></ore-progress>\n * <ore-progress indeterminate color=\"primary\" label=\"Loading…\"></ore-progress>\n * ```\n */\nexport const PROGRESS_TAG = 'ore-progress' as const;\ndefine<OreProgressProps>(PROGRESS_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n 'floating-label': prop.string(),\n indeterminate: prop.bool(false),\n label: prop.string(),\n max: prop.number(100),\n title: prop.string(),\n type: prop.oneOf(['linear', 'circular', 'vertical'] as const, 'linear'),\n value: prop.number(0),\n 'value-text': prop.string(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n // The SVG circle circumference for a radius of 45 (viewBox 0 0 100 100)\n const RADIUS = 45;\n const CIRC = 2 * Math.PI * RADIUS; // ~282.7\n\n const percent = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return `${(v / m) * 100}%`;\n });\n\n const dashoffset = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return CIRC - (v / m) * CIRC;\n });\n\n const ariaValueNow = () => (props.indeterminate.value ? null : String(props.value.value));\n const ariaLabel = () => props.label.value ?? props.title.value ?? 'Progress';\n const circularStyle = styleMap({ '--_circ': `${CIRC}px` });\n const strokeDasharray = () => (props.indeterminate.value ? undefined : `${CIRC}px`);\n const strokeDashoffset = () => (props.indeterminate.value ? undefined : `${dashoffset.value}px`);\n const isVertical = computed(() => props.type.value === 'vertical');\n const linearFillStyle = styleMap({\n height: () => (!props.indeterminate.value && isVertical.value ? percent.value : null),\n width: () => (!props.indeterminate.value && !isVertical.value ? percent.value : null),\n });\n\n watch(() => {\n el.style.setProperty('--_percent', props.indeterminate.value ? '0%' : percent.value);\n });\n\n const circularTemplate = () =>\n html` <div\n class=\"circular-track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\"\n :style=\"${circularStyle}\">\n <svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle class=\"circle-bg\" cx=\"50\" cy=\"50\" r=\"${RADIUS}\"></circle>\n <circle\n class=\"circle-fill\"\n cx=\"50\"\n cy=\"50\"\n r=\"${RADIUS}\"\n :stroke-dasharray=\"${strokeDasharray}\"\n :stroke-dashoffset=\"${strokeDashoffset}\"></circle>\n </svg>\n <div class=\"circular-inner\">\n <span class=\"circular-label\">${() => props.label.value ?? ''}</span>\n <span class=\"circular-title\">${() => props.title.value ?? ''}</span>\n </div>\n </div>`;\n\n const barTemplate = () =>\n html` <div class=\"wrapper\">\n <div class=\"header\">\n <span class=\"progress-title\">${() => props.title.value ?? ''}</span>\n <span class=\"end-label header-label\">${() => props.label.value ?? ''}</span>\n </div>\n <div :class=${() => `bar-row${isVertical.value ? ' bar-row-vertical' : ''}`}>\n <div class=\"track-outer\">\n <div\n class=\"track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\">\n <div class=\"fill\" part=\"fill\" :style=\"${linearFillStyle}\"></div>\n </div>\n ${() => (!isVertical.value ? html`<span class=\"floating-label\">${props['floating-label']}</span>` : null)}\n </div>\n <span class=\"end-label row-label\">${() => props.label.value ?? ''}</span>\n </div>\n </div>`;\n\n return html` ${() => (props.type.value === 'circular' ? circularTemplate() : barTemplate())} `;\n },\n\n styles: [colorThemeMixin, forcedColorsMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":"mWA4EA,IAAa,EAAe,4BACH,EAAc,CACrC,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,iBAAkB,EAAA,KAAK,OAAO,EAC9B,cAAe,EAAA,KAAK,KAAK,EAAK,EAC9B,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,OAAO,GAAG,EACpB,MAAO,EAAA,KAAK,OAAO,EACnB,KAAM,EAAA,KAAK,MAAM,CAAC,SAAU,WAAY,UAAU,EAAY,QAAQ,EACtE,MAAO,EAAA,KAAK,OAAO,CAAC,EACpB,aAAc,EAAA,KAAK,OAAO,CAC5B,EAEA,MAAM,EAAO,CACX,IAAM,GAAA,EAAA,EAAA,QAAA,CAAa,EACb,EAAQ,EAAA,YAIR,EAAO,EAAI,KAAK,GAAK,GAErB,GAAA,EAAA,EAAA,SAAA,KAIG,GAHG,KAAK,IAAI,EAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,EAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAGtE,EAFD,KAAK,IAAI,EAAG,OAAO,EAAM,IAAI,KAAK,CAE7B,EAAK,IAAI,EACzB,EAEK,GAAA,EAAA,EAAA,SAAA,KAA4B,CAChC,IAAM,EAAI,KAAK,IAAI,EAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,EAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAAC,EAC5E,EAAI,KAAK,IAAI,EAAG,OAAO,EAAM,IAAI,KAAK,CAAC,EAE7C,OAAO,EAAQ,EAAI,EAAK,CAC1B,CAAC,EAEK,MAAsB,EAAM,cAAc,MAAQ,KAAO,OAAO,EAAM,MAAM,KAAK,EACjF,MAAkB,EAAM,MAAM,OAAS,EAAM,MAAM,OAAS,WAC5D,GAAA,EAAA,EAAA,SAAA,CAAyB,CAAE,UAAW,GAAG,EAAK,GAAI,CAAC,EACnD,MAAyB,EAAM,cAAc,MAAQ,IAAA,GAAY,GAAG,EAAK,IACzE,MAA0B,EAAM,cAAc,MAAQ,IAAA,GAAY,GAAG,EAAW,MAAM,IACtF,GAAA,EAAA,EAAA,SAAA,KAA4B,EAAM,KAAK,QAAU,UAAU,EAC3D,GAAA,EAAA,EAAA,SAAA,CAA2B,CAC/B,WAAe,CAAC,EAAM,cAAc,OAAS,EAAW,MAAQ,EAAQ,MAAQ,KAChF,UAAc,CAAC,EAAM,cAAc,OAAS,CAAC,EAAW,MAAQ,EAAQ,MAAQ,IAClF,CAAC,EAED,MAAY,CACV,EAAG,MAAM,YAAY,aAAc,EAAM,cAAc,MAAQ,KAAO,EAAQ,KAAK,CACrF,CAAC,EAED,IAAM,MACJ,EAAA,IAAI;;;0BAGgB,EAAa;;0BAEb,EAAM,IAAI;uBACb,EAAU;2BACN,EAAM,cAAc;kBAC7B,EAAc;;yDAEyB,GAAO;;;;;iBAK/C,GAAO;iCACS,EAAgB;kCACf,EAAiB;;;6CAGJ,EAAM,MAAM,OAAS,GAAG;6CACxB,EAAM,MAAM,OAAS,GAAG;;cAI7D,MACJ,EAAA,IAAI;;6CAEqC,EAAM,MAAM,OAAS,GAAG;qDAChB,EAAM,MAAM,OAAS,GAAG;;0BAEnD,UAAU,EAAW,MAAQ,oBAAsB,KAAK;;;;;gCAKpD,EAAa;;gCAEb,EAAM,IAAI;6BACb,EAAU;iCACN,EAAM,cAAc;sDACC,EAAgB;;kBAEhD,EAAW,MAA+E,KAAvE,EAAA,IAAI,gCAAgC,EAAM,kBAAkB,SAAiB;;kDAElE,EAAM,MAAM,OAAS,GAAG;;cAIxE,MAAO,GAAA,IAAI,QAAW,EAAM,KAAK,QAAU,WAAa,EAAiB,EAAI,EAAY,EAAG,EAC9F,EAEA,OAAQ,CAAC,EAAA,gBAAiB,EAAA,kBAAmB,EAAA,mBAAoB,EAAA,OAAe,CAClF,CAAC"}
|
|
1
|
+
{"version":3,"file":"progress.cjs","names":[],"sources":["../src/feedback/progress/progress.ts"],"sourcesContent":["import { define, html, prop, getHost, watchEffect, styleMap } from '@vielzeug/ore';\nimport { computed } from '@vielzeug/ripple';\n\nimport type { ComponentSize, ThemeColor } from '../../types';\n\nimport { sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport componentStyles from './progress.css?inline';\n\n/** Progress bar component properties */\nexport type OreProgressProps = {\n /** Theme color for the fill bar */\n color?: ThemeColor;\n /** Floating chip centered above the fill endpoint (linear only). Hidden in indeterminate mode. Position formula: left = fill% − half chip width (CSS: left:X%; transform:translateX(−50%)). */\n 'floating-label'?: string;\n /** When true, shows an infinite animation — use when progress is unknown. */\n indeterminate?: boolean;\n /** Accessible name AND visible text label.\n * - Linear without `title`: rendered at the end of the bar.\n * - Linear with `title`: moved into the header row above the bar.\n * - Circular: large text centered inside the ring. */\n label?: string;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /** Size variant controlling bar height */\n size?: ComponentSize;\n /** Title text.\n * - Linear: displayed as a header above the bar; moves `label` into the header row.\n * - Circular: smaller text displayed below the `label` inside the ring. */\n title?: string;\n /** 'linear' (default), 'circular', or 'vertical' */\n type?: 'linear' | 'circular' | 'vertical';\n /** Current progress value (0 to `max`). Ignored when `indeterminate`. */\n value?: number;\n /** Human-readable value text for screen readers (e.g. \"Step 2 of 5\", \"75%\"). Overrides the raw aria-valuenow when set. */\n 'value-text'?: string;\n};\n\n/**\n * A linear progress bar for conveying operation progress.\n * Supports determinate (known value) and indeterminate (unknown duration) modes.\n *\n * @element ore-progress\n *\n * @attr {number} value - Current value (0–max). Defaults to 0.\n * @attr {number} max - Maximum value. Defaults to 100.\n * @attr {boolean} indeterminate - Show infinite animation (ignores value/max).\n * @attr {string} color - Theme color: 'primary' | 'success' | 'warning' | 'error' | …\n * @attr {string} size - Bar height/width: 'sm' | 'md' | 'lg'\n * @attr {string} type - 'linear' (default) | 'circular' | 'vertical'\n *\n * @cssprop --progress-width - Bar width override (vertical only)\n * @attr {string} label - Visible text label + accessible name. Linear: at bar end (or header row with title). Circular: large text centered inside the ring.\n * @attr {string} title - Title text. Linear: header above the bar (moves label to header row). Circular: smaller text below the label inside the ring.\n * @attr {string} floating-label - Floating chip centered above the fill endpoint (linear only); hidden when indeterminate.\n *\n * @cssprop --progress-height - Bar height override\n * @cssprop --progress-track-bg - Track background color\n * @cssprop --progress-fill - Fill bar color\n * @cssprop --progress-radius - Border radius\n * @cssprop --progress-label-gap - Gap between header/bar row and between bar and trailing label (default 0.25 rem)\n * @cssprop --progress-title-color - Title text color (defaults to currentColor)\n * @cssprop --progress-label-color - Label text color (defaults to currentColor)\n * @cssprop --progress-circle-size - Circular indicator diameter (default 6rem)\n * @cssprop --progress-circular-label-size - Font size of the label inside the ring (default --text-xl)\n * @cssprop --progress-circular-title-size - Font size of the title inside the ring (default --text-xs)\n *\n * @part fill - Progress fill element.\n * @example\n * ```html\n * <ore-progress value=\"45\"></ore-progress>\n * <ore-progress value=\"75\" max=\"100\" color=\"success\" size=\"lg\"></ore-progress>\n * <ore-progress indeterminate color=\"primary\" label=\"Loading…\"></ore-progress>\n * ```\n */\nexport const PROGRESS_TAG = 'ore-progress' as const;\ndefine<OreProgressProps>(PROGRESS_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n 'floating-label': prop.string(),\n indeterminate: prop.bool(false),\n label: prop.string(),\n max: prop.number(100),\n title: prop.string(),\n type: prop.oneOf(['linear', 'circular', 'vertical'] as const, 'linear'),\n value: prop.number(0),\n 'value-text': prop.string(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n // The SVG circle circumference for a radius of 45 (viewBox 0 0 100 100)\n const RADIUS = 45;\n const CIRC = 2 * Math.PI * RADIUS; // ~282.7\n\n const percent = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return `${(v / m) * 100}%`;\n });\n\n const dashoffset = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return CIRC - (v / m) * CIRC;\n });\n\n const ariaValueNow = () => (props.indeterminate.value ? null : String(props.value.value));\n const ariaLabel = () => props.label.value ?? props.title.value ?? 'Progress';\n const circularStyle = styleMap({ '--_circ': `${CIRC}px` });\n const strokeDasharray = () => (props.indeterminate.value ? undefined : `${CIRC}px`);\n const strokeDashoffset = () => (props.indeterminate.value ? undefined : `${dashoffset.value}px`);\n const isVertical = computed(() => props.type.value === 'vertical');\n const linearFillStyle = styleMap({\n height: () => (!props.indeterminate.value && isVertical.value ? percent.value : null),\n width: () => (!props.indeterminate.value && !isVertical.value ? percent.value : null),\n });\n\n watch(() => {\n el.style.setProperty('--_percent', props.indeterminate.value ? '0%' : percent.value);\n });\n\n const circularTemplate = () =>\n html` <div\n class=\"circular-track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\"\n :style=\"${circularStyle}\">\n <svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle class=\"circle-bg\" cx=\"50\" cy=\"50\" r=\"${RADIUS}\"></circle>\n <circle\n class=\"circle-fill\"\n cx=\"50\"\n cy=\"50\"\n r=\"${RADIUS}\"\n :stroke-dasharray=\"${strokeDasharray}\"\n :stroke-dashoffset=\"${strokeDashoffset}\"></circle>\n </svg>\n <div class=\"circular-inner\">\n <span class=\"circular-label\">${() => props.label.value ?? ''}</span>\n <span class=\"circular-title\">${() => props.title.value ?? ''}</span>\n </div>\n </div>`;\n\n const barTemplate = () =>\n html` <div class=\"wrapper\">\n <div class=\"header\">\n <span class=\"progress-title\">${() => props.title.value ?? ''}</span>\n <span class=\"end-label header-label\">${() => props.label.value ?? ''}</span>\n </div>\n <div :class=${() => `bar-row${isVertical.value ? ' bar-row-vertical' : ''}`}>\n <div class=\"track-outer\">\n <div\n class=\"track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\">\n <div class=\"fill\" part=\"fill\" :style=\"${linearFillStyle}\"></div>\n </div>\n ${() => (!isVertical.value ? html`<span class=\"floating-label\">${props['floating-label']}</span>` : null)}\n </div>\n <span class=\"end-label row-label\">${() => props.label.value ?? ''}</span>\n </div>\n </div>`;\n\n return html` ${() => (props.type.value === 'circular' ? circularTemplate() : barTemplate())} `;\n },\n\n styles: [colorThemeMixin, forcedColorsMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":"6TA2EA,IAAa,EAAe,4BACH,EAAc,CACrC,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,iBAAkB,EAAA,KAAK,OAAO,EAC9B,cAAe,EAAA,KAAK,KAAK,EAAK,EAC9B,MAAO,EAAA,KAAK,OAAO,EACnB,IAAK,EAAA,KAAK,OAAO,GAAG,EACpB,MAAO,EAAA,KAAK,OAAO,EACnB,KAAM,EAAA,KAAK,MAAM,CAAC,SAAU,WAAY,UAAU,EAAY,QAAQ,EACtE,MAAO,EAAA,KAAK,OAAO,CAAC,EACpB,aAAc,EAAA,KAAK,OAAO,CAC5B,EAEA,MAAM,EAAO,CACX,IAAM,GAAA,EAAA,EAAA,QAAA,CAAa,EACb,EAAQ,EAAA,YAIR,EAAO,EAAI,KAAK,GAAK,GAErB,GAAA,EAAA,EAAA,SAAA,KAIG,GAHG,KAAK,IAAI,EAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,EAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAGtE,EAFD,KAAK,IAAI,EAAG,OAAO,EAAM,IAAI,KAAK,CAE7B,EAAK,IAAI,EACzB,EAEK,GAAA,EAAA,EAAA,SAAA,KAA4B,CAChC,IAAM,EAAI,KAAK,IAAI,EAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,EAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAAC,EAC5E,EAAI,KAAK,IAAI,EAAG,OAAO,EAAM,IAAI,KAAK,CAAC,EAE7C,OAAO,EAAQ,EAAI,EAAK,CAC1B,CAAC,EAEK,MAAsB,EAAM,cAAc,MAAQ,KAAO,OAAO,EAAM,MAAM,KAAK,EACjF,MAAkB,EAAM,MAAM,OAAS,EAAM,MAAM,OAAS,WAC5D,GAAA,EAAA,EAAA,SAAA,CAAyB,CAAE,UAAW,GAAG,EAAK,GAAI,CAAC,EACnD,MAAyB,EAAM,cAAc,MAAQ,IAAA,GAAY,GAAG,EAAK,IACzE,MAA0B,EAAM,cAAc,MAAQ,IAAA,GAAY,GAAG,EAAW,MAAM,IACtF,GAAA,EAAA,EAAA,SAAA,KAA4B,EAAM,KAAK,QAAU,UAAU,EAC3D,GAAA,EAAA,EAAA,SAAA,CAA2B,CAC/B,WAAe,CAAC,EAAM,cAAc,OAAS,EAAW,MAAQ,EAAQ,MAAQ,KAChF,UAAc,CAAC,EAAM,cAAc,OAAS,CAAC,EAAW,MAAQ,EAAQ,MAAQ,IAClF,CAAC,EAED,MAAY,CACV,EAAG,MAAM,YAAY,aAAc,EAAM,cAAc,MAAQ,KAAO,EAAQ,KAAK,CACrF,CAAC,EAED,IAAM,MACJ,EAAA,IAAI;;;0BAGgB,EAAa;;0BAEb,EAAM,IAAI;uBACb,EAAU;2BACN,EAAM,cAAc;kBAC7B,EAAc;;yDAEyB,GAAO;;;;;iBAK/C,GAAO;iCACS,EAAgB;kCACf,EAAiB;;;6CAGJ,EAAM,MAAM,OAAS,GAAG;6CACxB,EAAM,MAAM,OAAS,GAAG;;cAI7D,MACJ,EAAA,IAAI;;6CAEqC,EAAM,MAAM,OAAS,GAAG;qDAChB,EAAM,MAAM,OAAS,GAAG;;0BAEnD,UAAU,EAAW,MAAQ,oBAAsB,KAAK;;;;;gCAKpD,EAAa;;gCAEb,EAAM,IAAI;6BACb,EAAU;iCACN,EAAM,cAAc;sDACC,EAAgB;;kBAEhD,EAAW,MAA+E,KAAvE,EAAA,IAAI,gCAAgC,EAAM,kBAAkB,SAAiB;;kDAElE,EAAM,MAAM,OAAS,GAAG;;cAIxE,MAAO,GAAA,IAAI,QAAW,EAAM,KAAK,QAAU,WAAa,EAAiB,EAAI,EAAY,EAAG,EAC9F,EAEA,OAAQ,CAAC,EAAA,gBAAiB,EAAA,kBAAmB,EAAA,mBAAoB,EAAA,OAAe,CAClF,CAAC"}
|
package/dist/progress.js
CHANGED
|
@@ -2,8 +2,7 @@ import { reducedMotionMixin as e } from "./styles/mixins/accessibility.css.js";
|
|
|
2
2
|
import { colorThemeMixin as t, forcedColorsMixin as n } from "./styles/mixins/theme.css.js";
|
|
3
3
|
import { sizableBundle as r, themableBundle as i } from "./shared/prop-bundles.js";
|
|
4
4
|
import a from "./feedback/progress/progress.css.js";
|
|
5
|
-
import { define as o, getHost as s, html as c, prop as l,
|
|
6
|
-
import { styleMap as d } from "@vielzeug/ore/directives";
|
|
5
|
+
import { define as o, getHost as s, html as c, prop as l, styleMap as u, watchEffect as d } from "@vielzeug/ore";
|
|
7
6
|
import { computed as f } from "@vielzeug/ripple";
|
|
8
7
|
//#region src/feedback/progress/progress.ts
|
|
9
8
|
var p = "ore-progress";
|
|
@@ -25,10 +24,10 @@ o(p, {
|
|
|
25
24
|
"value-text": l.string()
|
|
26
25
|
},
|
|
27
26
|
setup(e) {
|
|
28
|
-
let t = s(), n =
|
|
27
|
+
let t = s(), n = d, r = 2 * Math.PI * 45, i = f(() => `${Math.max(0, Math.min(Number(e.value.value), Number(e.max.value))) / Math.max(1, Number(e.max.value)) * 100}%`), a = f(() => {
|
|
29
28
|
let t = Math.max(0, Math.min(Number(e.value.value), Number(e.max.value))), n = Math.max(1, Number(e.max.value));
|
|
30
29
|
return r - t / n * r;
|
|
31
|
-
}), o = () => e.indeterminate.value ? null : String(e.value.value), l = () => e.label.value ?? e.title.value ?? "Progress", p =
|
|
30
|
+
}), o = () => e.indeterminate.value ? null : String(e.value.value), l = () => e.label.value ?? e.title.value ?? "Progress", p = u({ "--_circ": `${r}px` }), m = () => e.indeterminate.value ? void 0 : `${r}px`, h = () => e.indeterminate.value ? void 0 : `${a.value}px`, g = f(() => e.type.value === "vertical"), _ = u({
|
|
32
31
|
height: () => !e.indeterminate.value && g.value ? i.value : null,
|
|
33
32
|
width: () => !e.indeterminate.value && !g.value ? i.value : null
|
|
34
33
|
});
|
package/dist/progress.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","names":[],"sources":["../src/feedback/progress/progress.ts"],"sourcesContent":["import { define, html, prop, getHost, watchEffect } from '@vielzeug/ore';\nimport { styleMap } from '@vielzeug/ore/directives';\nimport { computed } from '@vielzeug/ripple';\n\nimport type { ComponentSize, ThemeColor } from '../../types';\n\nimport { sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport componentStyles from './progress.css?inline';\n\n/** Progress bar component properties */\nexport type OreProgressProps = {\n /** Theme color for the fill bar */\n color?: ThemeColor;\n /** Floating chip centered above the fill endpoint (linear only). Hidden in indeterminate mode. Position formula: left = fill% − half chip width (CSS: left:X%; transform:translateX(−50%)). */\n 'floating-label'?: string;\n /** When true, shows an infinite animation — use when progress is unknown. */\n indeterminate?: boolean;\n /** Accessible name AND visible text label.\n * - Linear without `title`: rendered at the end of the bar.\n * - Linear with `title`: moved into the header row above the bar.\n * - Circular: large text centered inside the ring. */\n label?: string;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /** Size variant controlling bar height */\n size?: ComponentSize;\n /** Title text.\n * - Linear: displayed as a header above the bar; moves `label` into the header row.\n * - Circular: smaller text displayed below the `label` inside the ring. */\n title?: string;\n /** 'linear' (default), 'circular', or 'vertical' */\n type?: 'linear' | 'circular' | 'vertical';\n /** Current progress value (0 to `max`). Ignored when `indeterminate`. */\n value?: number;\n /** Human-readable value text for screen readers (e.g. \"Step 2 of 5\", \"75%\"). Overrides the raw aria-valuenow when set. */\n 'value-text'?: string;\n};\n\n/**\n * A linear progress bar for conveying operation progress.\n * Supports determinate (known value) and indeterminate (unknown duration) modes.\n *\n * @element ore-progress\n *\n * @attr {number} value - Current value (0–max). Defaults to 0.\n * @attr {number} max - Maximum value. Defaults to 100.\n * @attr {boolean} indeterminate - Show infinite animation (ignores value/max).\n * @attr {string} color - Theme color: 'primary' | 'success' | 'warning' | 'error' | …\n * @attr {string} size - Bar height/width: 'sm' | 'md' | 'lg'\n * @attr {string} type - 'linear' (default) | 'circular' | 'vertical'\n *\n * @cssprop --progress-width - Bar width override (vertical only)\n * @attr {string} label - Visible text label + accessible name. Linear: at bar end (or header row with title). Circular: large text centered inside the ring.\n * @attr {string} title - Title text. Linear: header above the bar (moves label to header row). Circular: smaller text below the label inside the ring.\n * @attr {string} floating-label - Floating chip centered above the fill endpoint (linear only); hidden when indeterminate.\n *\n * @cssprop --progress-height - Bar height override\n * @cssprop --progress-track-bg - Track background color\n * @cssprop --progress-fill - Fill bar color\n * @cssprop --progress-radius - Border radius\n * @cssprop --progress-label-gap - Gap between header/bar row and between bar and trailing label (default 0.25 rem)\n * @cssprop --progress-title-color - Title text color (defaults to currentColor)\n * @cssprop --progress-label-color - Label text color (defaults to currentColor)\n * @cssprop --progress-circle-size - Circular indicator diameter (default 6rem)\n * @cssprop --progress-circular-label-size - Font size of the label inside the ring (default --text-xl)\n * @cssprop --progress-circular-title-size - Font size of the title inside the ring (default --text-xs)\n *\n * @part fill - Progress fill element.\n * @example\n * ```html\n * <ore-progress value=\"45\"></ore-progress>\n * <ore-progress value=\"75\" max=\"100\" color=\"success\" size=\"lg\"></ore-progress>\n * <ore-progress indeterminate color=\"primary\" label=\"Loading…\"></ore-progress>\n * ```\n */\nexport const PROGRESS_TAG = 'ore-progress' as const;\ndefine<OreProgressProps>(PROGRESS_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n 'floating-label': prop.string(),\n indeterminate: prop.bool(false),\n label: prop.string(),\n max: prop.number(100),\n title: prop.string(),\n type: prop.oneOf(['linear', 'circular', 'vertical'] as const, 'linear'),\n value: prop.number(0),\n 'value-text': prop.string(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n // The SVG circle circumference for a radius of 45 (viewBox 0 0 100 100)\n const RADIUS = 45;\n const CIRC = 2 * Math.PI * RADIUS; // ~282.7\n\n const percent = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return `${(v / m) * 100}%`;\n });\n\n const dashoffset = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return CIRC - (v / m) * CIRC;\n });\n\n const ariaValueNow = () => (props.indeterminate.value ? null : String(props.value.value));\n const ariaLabel = () => props.label.value ?? props.title.value ?? 'Progress';\n const circularStyle = styleMap({ '--_circ': `${CIRC}px` });\n const strokeDasharray = () => (props.indeterminate.value ? undefined : `${CIRC}px`);\n const strokeDashoffset = () => (props.indeterminate.value ? undefined : `${dashoffset.value}px`);\n const isVertical = computed(() => props.type.value === 'vertical');\n const linearFillStyle = styleMap({\n height: () => (!props.indeterminate.value && isVertical.value ? percent.value : null),\n width: () => (!props.indeterminate.value && !isVertical.value ? percent.value : null),\n });\n\n watch(() => {\n el.style.setProperty('--_percent', props.indeterminate.value ? '0%' : percent.value);\n });\n\n const circularTemplate = () =>\n html` <div\n class=\"circular-track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\"\n :style=\"${circularStyle}\">\n <svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle class=\"circle-bg\" cx=\"50\" cy=\"50\" r=\"${RADIUS}\"></circle>\n <circle\n class=\"circle-fill\"\n cx=\"50\"\n cy=\"50\"\n r=\"${RADIUS}\"\n :stroke-dasharray=\"${strokeDasharray}\"\n :stroke-dashoffset=\"${strokeDashoffset}\"></circle>\n </svg>\n <div class=\"circular-inner\">\n <span class=\"circular-label\">${() => props.label.value ?? ''}</span>\n <span class=\"circular-title\">${() => props.title.value ?? ''}</span>\n </div>\n </div>`;\n\n const barTemplate = () =>\n html` <div class=\"wrapper\">\n <div class=\"header\">\n <span class=\"progress-title\">${() => props.title.value ?? ''}</span>\n <span class=\"end-label header-label\">${() => props.label.value ?? ''}</span>\n </div>\n <div :class=${() => `bar-row${isVertical.value ? ' bar-row-vertical' : ''}`}>\n <div class=\"track-outer\">\n <div\n class=\"track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\">\n <div class=\"fill\" part=\"fill\" :style=\"${linearFillStyle}\"></div>\n </div>\n ${() => (!isVertical.value ? html`<span class=\"floating-label\">${props['floating-label']}</span>` : null)}\n </div>\n <span class=\"end-label row-label\">${() => props.label.value ?? ''}</span>\n </div>\n </div>`;\n\n return html` ${() => (props.type.value === 'circular' ? circularTemplate() : barTemplate())} `;\n },\n\n styles: [colorThemeMixin, forcedColorsMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":";;;;;;;;AA4EA,IAAa,IAAe;AAC5B,EAAyB,GAAc;CACrC,OAAO;EACL,GAAG;EACH,GAAG;EACH,kBAAkB,EAAK,OAAO;EAC9B,eAAe,EAAK,KAAK,EAAK;EAC9B,OAAO,EAAK,OAAO;EACnB,KAAK,EAAK,OAAO,GAAG;EACpB,OAAO,EAAK,OAAO;EACnB,MAAM,EAAK,MAAM;GAAC;GAAU;GAAY;EAAU,GAAY,QAAQ;EACtE,OAAO,EAAK,OAAO,CAAC;EACpB,cAAc,EAAK,OAAO;CAC5B;CAEA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACb,IAAQ,GAIR,IAAO,IAAI,KAAK,KAAK,IAErB,IAAU,QAIP,GAHG,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,GAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAGtE,IAFD,KAAK,IAAI,GAAG,OAAO,EAAM,IAAI,KAAK,CAE7B,IAAK,IAAI,EACzB,GAEK,IAAa,QAAe;GAChC,IAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,GAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAAC,GAC5E,IAAI,KAAK,IAAI,GAAG,OAAO,EAAM,IAAI,KAAK,CAAC;GAE7C,OAAO,IAAQ,IAAI,IAAK;EAC1B,CAAC,GAEK,UAAsB,EAAM,cAAc,QAAQ,OAAO,OAAO,EAAM,MAAM,KAAK,GACjF,UAAkB,EAAM,MAAM,SAAS,EAAM,MAAM,SAAS,YAC5D,IAAgB,EAAS,EAAE,WAAW,GAAG,EAAK,IAAI,CAAC,GACnD,UAAyB,EAAM,cAAc,QAAQ,KAAA,IAAY,GAAG,EAAK,KACzE,UAA0B,EAAM,cAAc,QAAQ,KAAA,IAAY,GAAG,EAAW,MAAM,KACtF,IAAa,QAAe,EAAM,KAAK,UAAU,UAAU,GAC3D,IAAkB,EAAS;GAC/B,cAAe,CAAC,EAAM,cAAc,SAAS,EAAW,QAAQ,EAAQ,QAAQ;GAChF,aAAc,CAAC,EAAM,cAAc,SAAS,CAAC,EAAW,QAAQ,EAAQ,QAAQ;EAClF,CAAC;EAED,QAAY;GACV,EAAG,MAAM,YAAY,cAAc,EAAM,cAAc,QAAQ,OAAO,EAAQ,KAAK;EACrF,CAAC;EAED,IAAM,UACJ,CAAI;;;0BAGgB,EAAa;;0BAEb,EAAM,IAAI;uBACb,EAAU;2BACN,EAAM,cAAc;kBAC7B,EAAc;;yDAEyB,GAAO;;;;;iBAK/C,GAAO;iCACS,EAAgB;kCACf,EAAiB;;;+CAGJ,EAAM,MAAM,SAAS,GAAG;+CACxB,EAAM,MAAM,SAAS,GAAG;;eAI7D,UACJ,CAAI;;+CAEqC,EAAM,MAAM,SAAS,GAAG;uDAChB,EAAM,MAAM,SAAS,GAAG;;4BAEnD,UAAU,EAAW,QAAQ,sBAAsB,KAAK;;;;;gCAKpD,EAAa;;gCAEb,EAAM,IAAI;6BACb,EAAU;iCACN,EAAM,cAAc;sDACC,EAAgB;;oBAEhD,EAAW,QAA+E,OAAvE,CAAI,gCAAgC,EAAM,kBAAkB,SAAiB;;oDAElE,EAAM,MAAM,SAAS,GAAG;;;EAIxE,OAAO,CAAI,UAAW,EAAM,KAAK,UAAU,aAAa,EAAiB,IAAI,EAAY,EAAG;CAC9F;CAEA,QAAQ;EAAC;EAAiB;EAAmB;EAAoB;CAAe;AAClF,CAAC"}
|
|
1
|
+
{"version":3,"file":"progress.js","names":[],"sources":["../src/feedback/progress/progress.ts"],"sourcesContent":["import { define, html, prop, getHost, watchEffect, styleMap } from '@vielzeug/ore';\nimport { computed } from '@vielzeug/ripple';\n\nimport type { ComponentSize, ThemeColor } from '../../types';\n\nimport { sizableBundle, themableBundle } from '../../shared';\nimport { colorThemeMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport componentStyles from './progress.css?inline';\n\n/** Progress bar component properties */\nexport type OreProgressProps = {\n /** Theme color for the fill bar */\n color?: ThemeColor;\n /** Floating chip centered above the fill endpoint (linear only). Hidden in indeterminate mode. Position formula: left = fill% − half chip width (CSS: left:X%; transform:translateX(−50%)). */\n 'floating-label'?: string;\n /** When true, shows an infinite animation — use when progress is unknown. */\n indeterminate?: boolean;\n /** Accessible name AND visible text label.\n * - Linear without `title`: rendered at the end of the bar.\n * - Linear with `title`: moved into the header row above the bar.\n * - Circular: large text centered inside the ring. */\n label?: string;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /** Size variant controlling bar height */\n size?: ComponentSize;\n /** Title text.\n * - Linear: displayed as a header above the bar; moves `label` into the header row.\n * - Circular: smaller text displayed below the `label` inside the ring. */\n title?: string;\n /** 'linear' (default), 'circular', or 'vertical' */\n type?: 'linear' | 'circular' | 'vertical';\n /** Current progress value (0 to `max`). Ignored when `indeterminate`. */\n value?: number;\n /** Human-readable value text for screen readers (e.g. \"Step 2 of 5\", \"75%\"). Overrides the raw aria-valuenow when set. */\n 'value-text'?: string;\n};\n\n/**\n * A linear progress bar for conveying operation progress.\n * Supports determinate (known value) and indeterminate (unknown duration) modes.\n *\n * @element ore-progress\n *\n * @attr {number} value - Current value (0–max). Defaults to 0.\n * @attr {number} max - Maximum value. Defaults to 100.\n * @attr {boolean} indeterminate - Show infinite animation (ignores value/max).\n * @attr {string} color - Theme color: 'primary' | 'success' | 'warning' | 'error' | …\n * @attr {string} size - Bar height/width: 'sm' | 'md' | 'lg'\n * @attr {string} type - 'linear' (default) | 'circular' | 'vertical'\n *\n * @cssprop --progress-width - Bar width override (vertical only)\n * @attr {string} label - Visible text label + accessible name. Linear: at bar end (or header row with title). Circular: large text centered inside the ring.\n * @attr {string} title - Title text. Linear: header above the bar (moves label to header row). Circular: smaller text below the label inside the ring.\n * @attr {string} floating-label - Floating chip centered above the fill endpoint (linear only); hidden when indeterminate.\n *\n * @cssprop --progress-height - Bar height override\n * @cssprop --progress-track-bg - Track background color\n * @cssprop --progress-fill - Fill bar color\n * @cssprop --progress-radius - Border radius\n * @cssprop --progress-label-gap - Gap between header/bar row and between bar and trailing label (default 0.25 rem)\n * @cssprop --progress-title-color - Title text color (defaults to currentColor)\n * @cssprop --progress-label-color - Label text color (defaults to currentColor)\n * @cssprop --progress-circle-size - Circular indicator diameter (default 6rem)\n * @cssprop --progress-circular-label-size - Font size of the label inside the ring (default --text-xl)\n * @cssprop --progress-circular-title-size - Font size of the title inside the ring (default --text-xs)\n *\n * @part fill - Progress fill element.\n * @example\n * ```html\n * <ore-progress value=\"45\"></ore-progress>\n * <ore-progress value=\"75\" max=\"100\" color=\"success\" size=\"lg\"></ore-progress>\n * <ore-progress indeterminate color=\"primary\" label=\"Loading…\"></ore-progress>\n * ```\n */\nexport const PROGRESS_TAG = 'ore-progress' as const;\ndefine<OreProgressProps>(PROGRESS_TAG, {\n props: {\n ...themableBundle,\n ...sizableBundle,\n 'floating-label': prop.string(),\n indeterminate: prop.bool(false),\n label: prop.string(),\n max: prop.number(100),\n title: prop.string(),\n type: prop.oneOf(['linear', 'circular', 'vertical'] as const, 'linear'),\n value: prop.number(0),\n 'value-text': prop.string(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n // The SVG circle circumference for a radius of 45 (viewBox 0 0 100 100)\n const RADIUS = 45;\n const CIRC = 2 * Math.PI * RADIUS; // ~282.7\n\n const percent = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return `${(v / m) * 100}%`;\n });\n\n const dashoffset = computed(() => {\n const v = Math.max(0, Math.min(Number(props.value.value), Number(props.max.value)));\n const m = Math.max(1, Number(props.max.value));\n\n return CIRC - (v / m) * CIRC;\n });\n\n const ariaValueNow = () => (props.indeterminate.value ? null : String(props.value.value));\n const ariaLabel = () => props.label.value ?? props.title.value ?? 'Progress';\n const circularStyle = styleMap({ '--_circ': `${CIRC}px` });\n const strokeDasharray = () => (props.indeterminate.value ? undefined : `${CIRC}px`);\n const strokeDashoffset = () => (props.indeterminate.value ? undefined : `${dashoffset.value}px`);\n const isVertical = computed(() => props.type.value === 'vertical');\n const linearFillStyle = styleMap({\n height: () => (!props.indeterminate.value && isVertical.value ? percent.value : null),\n width: () => (!props.indeterminate.value && !isVertical.value ? percent.value : null),\n });\n\n watch(() => {\n el.style.setProperty('--_percent', props.indeterminate.value ? '0%' : percent.value);\n });\n\n const circularTemplate = () =>\n html` <div\n class=\"circular-track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\"\n :style=\"${circularStyle}\">\n <svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle class=\"circle-bg\" cx=\"50\" cy=\"50\" r=\"${RADIUS}\"></circle>\n <circle\n class=\"circle-fill\"\n cx=\"50\"\n cy=\"50\"\n r=\"${RADIUS}\"\n :stroke-dasharray=\"${strokeDasharray}\"\n :stroke-dashoffset=\"${strokeDashoffset}\"></circle>\n </svg>\n <div class=\"circular-inner\">\n <span class=\"circular-label\">${() => props.label.value ?? ''}</span>\n <span class=\"circular-title\">${() => props.title.value ?? ''}</span>\n </div>\n </div>`;\n\n const barTemplate = () =>\n html` <div class=\"wrapper\">\n <div class=\"header\">\n <span class=\"progress-title\">${() => props.title.value ?? ''}</span>\n <span class=\"end-label header-label\">${() => props.label.value ?? ''}</span>\n </div>\n <div :class=${() => `bar-row${isVertical.value ? ' bar-row-vertical' : ''}`}>\n <div class=\"track-outer\">\n <div\n class=\"track\"\n role=\"progressbar\"\n :aria-valuenow=\"${ariaValueNow}\"\n aria-valuemin=\"0\"\n :aria-valuemax=\"${props.max}\"\n :aria-label=\"${ariaLabel}\"\n :aria-valuetext=\"${props['value-text']}\">\n <div class=\"fill\" part=\"fill\" :style=\"${linearFillStyle}\"></div>\n </div>\n ${() => (!isVertical.value ? html`<span class=\"floating-label\">${props['floating-label']}</span>` : null)}\n </div>\n <span class=\"end-label row-label\">${() => props.label.value ?? ''}</span>\n </div>\n </div>`;\n\n return html` ${() => (props.type.value === 'circular' ? circularTemplate() : barTemplate())} `;\n },\n\n styles: [colorThemeMixin, forcedColorsMixin, reducedMotionMixin, componentStyles],\n});\n"],"mappings":";;;;;;;AA2EA,IAAa,IAAe;AAC5B,EAAyB,GAAc;CACrC,OAAO;EACL,GAAG;EACH,GAAG;EACH,kBAAkB,EAAK,OAAO;EAC9B,eAAe,EAAK,KAAK,EAAK;EAC9B,OAAO,EAAK,OAAO;EACnB,KAAK,EAAK,OAAO,GAAG;EACpB,OAAO,EAAK,OAAO;EACnB,MAAM,EAAK,MAAM;GAAC;GAAU;GAAY;EAAU,GAAY,QAAQ;EACtE,OAAO,EAAK,OAAO,CAAC;EACpB,cAAc,EAAK,OAAO;CAC5B;CAEA,MAAM,GAAO;EACX,IAAM,IAAK,EAAQ,GACb,IAAQ,GAIR,IAAO,IAAI,KAAK,KAAK,IAErB,IAAU,QAIP,GAHG,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,GAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAGtE,IAFD,KAAK,IAAI,GAAG,OAAO,EAAM,IAAI,KAAK,CAE7B,IAAK,IAAI,EACzB,GAEK,IAAa,QAAe;GAChC,IAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,EAAM,MAAM,KAAK,GAAG,OAAO,EAAM,IAAI,KAAK,CAAC,CAAC,GAC5E,IAAI,KAAK,IAAI,GAAG,OAAO,EAAM,IAAI,KAAK,CAAC;GAE7C,OAAO,IAAQ,IAAI,IAAK;EAC1B,CAAC,GAEK,UAAsB,EAAM,cAAc,QAAQ,OAAO,OAAO,EAAM,MAAM,KAAK,GACjF,UAAkB,EAAM,MAAM,SAAS,EAAM,MAAM,SAAS,YAC5D,IAAgB,EAAS,EAAE,WAAW,GAAG,EAAK,IAAI,CAAC,GACnD,UAAyB,EAAM,cAAc,QAAQ,KAAA,IAAY,GAAG,EAAK,KACzE,UAA0B,EAAM,cAAc,QAAQ,KAAA,IAAY,GAAG,EAAW,MAAM,KACtF,IAAa,QAAe,EAAM,KAAK,UAAU,UAAU,GAC3D,IAAkB,EAAS;GAC/B,cAAe,CAAC,EAAM,cAAc,SAAS,EAAW,QAAQ,EAAQ,QAAQ;GAChF,aAAc,CAAC,EAAM,cAAc,SAAS,CAAC,EAAW,QAAQ,EAAQ,QAAQ;EAClF,CAAC;EAED,QAAY;GACV,EAAG,MAAM,YAAY,cAAc,EAAM,cAAc,QAAQ,OAAO,EAAQ,KAAK;EACrF,CAAC;EAED,IAAM,UACJ,CAAI;;;0BAGgB,EAAa;;0BAEb,EAAM,IAAI;uBACb,EAAU;2BACN,EAAM,cAAc;kBAC7B,EAAc;;yDAEyB,GAAO;;;;;iBAK/C,GAAO;iCACS,EAAgB;kCACf,EAAiB;;;+CAGJ,EAAM,MAAM,SAAS,GAAG;+CACxB,EAAM,MAAM,SAAS,GAAG;;eAI7D,UACJ,CAAI;;+CAEqC,EAAM,MAAM,SAAS,GAAG;uDAChB,EAAM,MAAM,SAAS,GAAG;;4BAEnD,UAAU,EAAW,QAAQ,sBAAsB,KAAK;;;;;gCAKpD,EAAa;;gCAEb,EAAM,IAAI;6BACb,EAAU;iCACN,EAAM,cAAc;sDACC,EAAgB;;oBAEhD,EAAW,QAA+E,OAAvE,CAAI,gCAAgC,EAAM,kBAAkB,SAAiB;;oDAElE,EAAM,MAAM,SAAS,GAAG;;;EAIxE,OAAO,CAAI,UAAW,EAAM,KAAK,UAAU,aAAa,EAAiB,IAAI,EAAY,EAAG;CAC9F;CAEA,QAAQ;EAAC;EAAiB;EAAmB;EAAoB;CAAe;AAClF,CAAC"}
|
package/dist/radio-group.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/states.css.cjs"),t=require("./shared/prop-bundles.cjs"),n=require("./headless/ore.cjs"),r=require("./headless/choice-field.cjs"),i=require("./headless/nav.cjs"),a=require("./headless/light-dom.cjs"),o=require("./inputs/shared/form-context.cjs"),s=require("./inputs/radio-group/radio-group.css.cjs");let c=require("@vielzeug/ore");require("@vielzeug/ripple");let l=require("@vielzeug/ore/forms");var u=(0,c.createContext)(`OreRadioGroup`),d=`ore-radio-group`;(0,c.define)(d,{formAssociated:!0,props:{...t.themableBundle,...t.sizableBundle,...t.disablableBundle,error:c.prop.string(),helper:c.prop.string(),label:c.prop.string(),name:c.prop.string(),orientation:c.prop.oneOf([`horizontal`,`vertical`],`vertical`),required:c.prop.bool(!1),value:{...c.prop.string(),reflect:!1}},setup(e){let t=(0,c.getHost)(),s=(0,c.useEmit)(),d=(0,c.useSlots)(),f=c.watchEffect,p=(0,c.inject)(o.FORM_CTX),m=o.useFormContext(e,p),h=r.createChoiceField({disabled:m.disabled,error:e.error,helper:e.helper,label:e.label,prefix:`radio-group`,required:e.required,signal:n.lifecycleSignal(c.onCleanup),validateOn:p?.validateOn,value:e.value});h.attachFormField((0,l.useField)({disabled:h.disabled,onReset:h.reset,toFormValue:e=>e,validationMessage:h.validationMessage,validity:h.validity,value:h.formValue}));let g=h.selectedValue,_=m.disabled;(0,c.bind)({attr:{size:m.size,value:()=>g.value||null}});let v=()=>a.getLightChildrenByTag(t,`ore-radio`),y=()=>_.value?[]:v().filter(e=>!e.hasAttribute(`disabled`)),b=e=>a.getChoiceLabel(v(),e),x=(e,t)=>{h.setValues(e?[e]:[]);let n=e?[b(e)]:[];s(`change`,{labels:n,originalEvent:t,values:e?[e]:[]}),h.triggerValidation(`blur`)};(0,c.provide)(u,{color:e.color,disabled:_,name:e.name,select:x,size:e.size,value:g}),f(()=>{d.elements().value,g.value;let t=v();for(let n of t){let t=n.getAttribute(`value`)??``;n.toggleAttribute(`checked`,t===g.value),e.name.value?n.setAttribute(`name`,e.name.value):n.removeAttribute(`name`),e.color.value?n.setAttribute(`color`,e.color.value):n.removeAttribute(`color`),e.size.value?n.setAttribute(`size`,e.size.value):n.removeAttribute(`size`),n.toggleAttribute(`disabled`,_.value)}}),f(()=>{d.elements().value;let e=v(),t=!1;for(let n of e){let e=n.getAttribute(`value`)===g.value;n.setAttribute(`tabindex`,e&&!_.value?`0`:`-1`),e&&!_.value&&(t=!0)}if(!t&&e.length>0){let t=e.find(e=>!e.hasAttribute(`disabled`));t&&t.setAttribute(`tabindex`,`0`)}});let S=i.createListControl({getItems:y,keys:{next:[`ArrowDown`,`ArrowRight`],prev:[`ArrowUp`,`ArrowLeft`]},loop:!0,onNavigate:(e,t,n)=>{let r=y()[t];r&&(r.focus(),r.tagName===`ORE-RADIO`&&x(r.getAttribute(`value`)??``,n))},signal:n.lifecycleSignal(c.onCleanup)});(0,c.bind)({on:{change:e=>{e.target!==t&&(e.stopPropagation(),x(e.target.getAttribute(`value`)??``,e))},keydown:e=>{let t=y();if(!t.length)return;let n=t.indexOf(document.activeElement);n!==-1&&(S.set(n),S.handleKeydown(e))}}});let C=(0,c.createStableId)(`radio-group-legend`);return c.html`
|
|
2
2
|
<fieldset
|
|
3
3
|
role="radiogroup"
|
|
4
4
|
aria-required="${()=>String(!!e.required.value)}"
|
|
5
|
-
:aria-invalid="${
|
|
6
|
-
:aria-errormessage="${
|
|
7
|
-
:aria-describedby="${
|
|
8
|
-
<legend id="${
|
|
9
|
-
${e.label}${(0,
|
|
5
|
+
:aria-invalid="${h.ariaInvalid}"
|
|
6
|
+
:aria-errormessage="${h.ariaErrorMessage}"
|
|
7
|
+
:aria-describedby="${h.ariaDescribedBy}">
|
|
8
|
+
<legend id="${C}" ?hidden=${()=>!e.label.value}>
|
|
9
|
+
${e.label}${(0,c.when)(()=>!!e.required.value,()=>c.html`<span aria-hidden="true"> *</span>`)}
|
|
10
10
|
</legend>
|
|
11
11
|
<div class="radio-group-items" part="items">
|
|
12
12
|
<slot></slot>
|
|
@@ -14,12 +14,12 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
14
14
|
<div
|
|
15
15
|
class="helper-text"
|
|
16
16
|
part="helper"
|
|
17
|
-
id="${
|
|
18
|
-
:role="${()=>
|
|
17
|
+
id="${h.assistiveId}"
|
|
18
|
+
:role="${()=>h.errorText.value?`alert`:null}"
|
|
19
19
|
aria-live="polite"
|
|
20
|
-
?hidden="${()=>!
|
|
21
|
-
${()=>
|
|
20
|
+
?hidden="${()=>!h.errorText.value&&!h.helperText.value}">
|
|
21
|
+
${()=>h.errorText.value||h.helperText.value}
|
|
22
22
|
</div>
|
|
23
23
|
</fieldset>
|
|
24
|
-
`},styles:[
|
|
24
|
+
`},styles:[e.disabledStateMixin,s.default]}),exports.RADIO_GROUP_CTX=u,exports.RADIO_GROUP_TAG=d;
|
|
25
25
|
//# sourceMappingURL=radio-group.cjs.map
|