@ecopages/radiant-ui 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -0
- package/dist/components/ui/alert/alert.css +27 -0
- package/dist/components/ui/alert/alert.d.ts +4 -0
- package/dist/components/ui/alert/alert.script.d.ts +25 -0
- package/dist/components/ui/alert/index.d.ts +2 -0
- package/dist/components/ui/alert/index.js +2 -0
- package/dist/components/ui/alert/index.js.map +7 -0
- package/dist/components/ui/breadcrumb/breadcrumb.css +41 -0
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +59 -0
- package/dist/components/ui/breadcrumb/breadcrumb.script.d.ts +40 -0
- package/dist/components/ui/breadcrumb/index.d.ts +2 -0
- package/dist/components/ui/breadcrumb/index.js +2 -0
- package/dist/components/ui/breadcrumb/index.js.map +7 -0
- package/dist/components/ui/button/button.d.ts +37 -0
- package/dist/components/ui/button/index.d.ts +1 -0
- package/dist/components/ui/button/index.js +2 -0
- package/dist/components/ui/button/index.js.map +7 -0
- package/dist/components/ui/carousel/carousel.css +170 -0
- package/dist/components/ui/carousel/carousel.d.ts +39 -0
- package/dist/components/ui/carousel/carousel.script.d.ts +113 -0
- package/dist/components/ui/carousel/index.d.ts +2 -0
- package/dist/components/ui/carousel/index.js +2 -0
- package/dist/components/ui/carousel/index.js.map +7 -0
- package/dist/components/ui/checkbox/checkbox.css +55 -0
- package/dist/components/ui/checkbox/checkbox.d.ts +4 -0
- package/dist/components/ui/checkbox/checkbox.script.d.ts +58 -0
- package/dist/components/ui/checkbox/index.d.ts +2 -0
- package/dist/components/ui/checkbox/index.js +2 -0
- package/dist/components/ui/checkbox/index.js.map +7 -0
- package/dist/components/ui/combobox/combobox.css +65 -0
- package/dist/components/ui/combobox/combobox.d.ts +53 -0
- package/dist/components/ui/combobox/combobox.script.d.ts +89 -0
- package/dist/components/ui/combobox/index.d.ts +2 -0
- package/dist/components/ui/combobox/index.js +2 -0
- package/dist/components/ui/combobox/index.js.map +7 -0
- package/dist/components/ui/dialog/dialog-registry.d.ts +34 -0
- package/dist/components/ui/dialog/dialog-registry.test.d.ts +1 -0
- package/dist/components/ui/dialog/dialog-types.d.ts +55 -0
- package/dist/components/ui/dialog/dialog.css +53 -0
- package/dist/components/ui/dialog/dialog.d.ts +36 -0
- package/dist/components/ui/dialog/dialog.script.d.ts +61 -0
- package/dist/components/ui/dialog/index.d.ts +4 -0
- package/dist/components/ui/dialog/index.js +2 -0
- package/dist/components/ui/dialog/index.js.map +7 -0
- package/dist/components/ui/disclosure/disclosure-group.script.d.ts +31 -0
- package/dist/components/ui/disclosure/disclosure.css +105 -0
- package/dist/components/ui/disclosure/disclosure.d.ts +35 -0
- package/dist/components/ui/disclosure/disclosure.script.d.ts +38 -0
- package/dist/components/ui/disclosure/index.d.ts +3 -0
- package/dist/components/ui/disclosure/index.js +2 -0
- package/dist/components/ui/disclosure/index.js.map +7 -0
- package/dist/components/ui/feed/feed.css +14 -0
- package/dist/components/ui/feed/feed.d.ts +12 -0
- package/dist/components/ui/feed/feed.script.d.ts +22 -0
- package/dist/components/ui/feed/index.d.ts +2 -0
- package/dist/components/ui/feed/index.js +2 -0
- package/dist/components/ui/feed/index.js.map +7 -0
- package/dist/components/ui/field/field-context.d.ts +20 -0
- package/dist/components/ui/field/field-description.d.ts +8 -0
- package/dist/components/ui/field/field-error.d.ts +9 -0
- package/dist/components/ui/field/field-ssr-hydration.test.d.ts +1 -0
- package/dist/components/ui/field/field.css +26 -0
- package/dist/components/ui/field/field.d.ts +4 -0
- package/dist/components/ui/field/field.script.d.ts +68 -0
- package/dist/components/ui/field/index.d.ts +5 -0
- package/dist/components/ui/field/index.js +2 -0
- package/dist/components/ui/field/index.js.map +7 -0
- package/dist/components/ui/form/control-protocol.d.ts +19 -0
- package/dist/components/ui/form/form-context.d.ts +27 -0
- package/dist/components/ui/form/form-field.test.d.ts +3 -0
- package/dist/components/ui/form/form-store.d.ts +53 -0
- package/dist/components/ui/form/form-store.test.d.ts +1 -0
- package/dist/components/ui/form/form.css +12 -0
- package/dist/components/ui/form/form.d.ts +5 -0
- package/dist/components/ui/form/form.script.d.ts +67 -0
- package/dist/components/ui/form/index.d.ts +7 -0
- package/dist/components/ui/form/index.js +2 -0
- package/dist/components/ui/form/index.js.map +7 -0
- package/dist/components/ui/form/resolvers.d.ts +3 -0
- package/dist/components/ui/form/types.d.ts +72 -0
- package/dist/components/ui/grid/grid.css +47 -0
- package/dist/components/ui/grid/grid.d.ts +7 -0
- package/dist/components/ui/grid/grid.script.d.ts +26 -0
- package/dist/components/ui/grid/index.d.ts +2 -0
- package/dist/components/ui/grid/index.js +2 -0
- package/dist/components/ui/grid/index.js.map +7 -0
- package/dist/components/ui/input/index.d.ts +1 -0
- package/dist/components/ui/input/index.js +2 -0
- package/dist/components/ui/input/index.js.map +7 -0
- package/dist/components/ui/input/input.css +32 -0
- package/dist/components/ui/input/input.d.ts +23 -0
- package/dist/components/ui/label/index.d.ts +1 -0
- package/dist/components/ui/label/index.js +2 -0
- package/dist/components/ui/label/index.js.map +7 -0
- package/dist/components/ui/label/label.css +8 -0
- package/dist/components/ui/label/label.d.ts +9 -0
- package/dist/components/ui/listbox/index.d.ts +2 -0
- package/dist/components/ui/listbox/index.js +2 -0
- package/dist/components/ui/listbox/index.js.map +7 -0
- package/dist/components/ui/listbox/listbox.css +23 -0
- package/dist/components/ui/listbox/listbox.d.ts +12 -0
- package/dist/components/ui/listbox/listbox.script.d.ts +40 -0
- package/dist/components/ui/menu-button/index.d.ts +2 -0
- package/dist/components/ui/menu-button/index.js +2 -0
- package/dist/components/ui/menu-button/index.js.map +7 -0
- package/dist/components/ui/menu-button/menu-button.css +43 -0
- package/dist/components/ui/menu-button/menu-button.d.ts +13 -0
- package/dist/components/ui/menu-button/menu-button.script.d.ts +64 -0
- package/dist/components/ui/menubar/index.d.ts +2 -0
- package/dist/components/ui/menubar/index.js +2 -0
- package/dist/components/ui/menubar/index.js.map +7 -0
- package/dist/components/ui/menubar/menubar.css +45 -0
- package/dist/components/ui/menubar/menubar.d.ts +16 -0
- package/dist/components/ui/menubar/menubar.script.d.ts +52 -0
- package/dist/components/ui/meter/index.d.ts +2 -0
- package/dist/components/ui/meter/index.js +2 -0
- package/dist/components/ui/meter/index.js.map +7 -0
- package/dist/components/ui/meter/meter.css +17 -0
- package/dist/components/ui/meter/meter.d.ts +4 -0
- package/dist/components/ui/meter/meter.script.d.ts +33 -0
- package/dist/components/ui/navigation-menu/index.d.ts +2 -0
- package/dist/components/ui/navigation-menu/index.js +2 -0
- package/dist/components/ui/navigation-menu/index.js.map +7 -0
- package/dist/components/ui/navigation-menu/navigation-menu.css +90 -0
- package/dist/components/ui/navigation-menu/navigation-menu.d.ts +28 -0
- package/dist/components/ui/navigation-menu/navigation-menu.script.d.ts +49 -0
- package/dist/components/ui/radio-group/index.d.ts +2 -0
- package/dist/components/ui/radio-group/index.js +2 -0
- package/dist/components/ui/radio-group/index.js.map +7 -0
- package/dist/components/ui/radio-group/radio-group.css +44 -0
- package/dist/components/ui/radio-group/radio-group.d.ts +12 -0
- package/dist/components/ui/radio-group/radio-group.script.d.ts +52 -0
- package/dist/components/ui/sidebar/index.d.ts +3 -0
- package/dist/components/ui/sidebar/index.js +2 -0
- package/dist/components/ui/sidebar/index.js.map +7 -0
- package/dist/components/ui/sidebar/sidebar-trigger.script.d.ts +53 -0
- package/dist/components/ui/sidebar/sidebar.css +362 -0
- package/dist/components/ui/sidebar/sidebar.d.ts +141 -0
- package/dist/components/ui/sidebar/sidebar.script.d.ts +140 -0
- package/dist/components/ui/sidebar/sidebar.test.d.ts +1 -0
- package/dist/components/ui/slider/index.d.ts +2 -0
- package/dist/components/ui/slider/index.js +2 -0
- package/dist/components/ui/slider/index.js.map +7 -0
- package/dist/components/ui/slider/slider.css +51 -0
- package/dist/components/ui/slider/slider.d.ts +7 -0
- package/dist/components/ui/slider/slider.script.d.ts +102 -0
- package/dist/components/ui/spinbutton/index.d.ts +2 -0
- package/dist/components/ui/spinbutton/index.js +2 -0
- package/dist/components/ui/spinbutton/index.js.map +7 -0
- package/dist/components/ui/spinbutton/spinbutton.css +19 -0
- package/dist/components/ui/spinbutton/spinbutton.d.ts +4 -0
- package/dist/components/ui/spinbutton/spinbutton.script.d.ts +64 -0
- package/dist/components/ui/switch/index.d.ts +2 -0
- package/dist/components/ui/switch/index.js +2 -0
- package/dist/components/ui/switch/index.js.map +7 -0
- package/dist/components/ui/switch/switch.css +47 -0
- package/dist/components/ui/switch/switch.d.ts +4 -0
- package/dist/components/ui/switch/switch.script.d.ts +51 -0
- package/dist/components/ui/tabs/index.d.ts +2 -0
- package/dist/components/ui/tabs/index.js +2 -0
- package/dist/components/ui/tabs/index.js.map +7 -0
- package/dist/components/ui/tabs/tabs.css +28 -0
- package/dist/components/ui/tabs/tabs.d.ts +12 -0
- package/dist/components/ui/tabs/tabs.script.d.ts +54 -0
- package/dist/components/ui/textarea/index.d.ts +1 -0
- package/dist/components/ui/textarea/index.js +2 -0
- package/dist/components/ui/textarea/index.js.map +7 -0
- package/dist/components/ui/textarea/textarea.css +33 -0
- package/dist/components/ui/textarea/textarea.d.ts +23 -0
- package/dist/components/ui/toast/index.d.ts +5 -0
- package/dist/components/ui/toast/index.js +2 -0
- package/dist/components/ui/toast/index.js.map +7 -0
- package/dist/components/ui/toast/toast-api.d.ts +29 -0
- package/dist/components/ui/toast/toast-context.d.ts +59 -0
- package/dist/components/ui/toast/toast-state.d.ts +25 -0
- package/dist/components/ui/toast/toast.css +315 -0
- package/dist/components/ui/toast/toast.d.ts +8 -0
- package/dist/components/ui/toast/toast.script.d.ts +91 -0
- package/dist/components/ui/toast/toast.test.d.ts +2 -0
- package/dist/components/ui/toast/toaster.script.d.ts +79 -0
- package/dist/components/ui/toolbar/index.d.ts +2 -0
- package/dist/components/ui/toolbar/index.js +2 -0
- package/dist/components/ui/toolbar/index.js.map +7 -0
- package/dist/components/ui/toolbar/toolbar.css +16 -0
- package/dist/components/ui/toolbar/toolbar.d.ts +4 -0
- package/dist/components/ui/toolbar/toolbar.script.d.ts +30 -0
- package/dist/components/ui/tooltip/index.d.ts +2 -0
- package/dist/components/ui/tooltip/index.js +2 -0
- package/dist/components/ui/tooltip/index.js.map +7 -0
- package/dist/components/ui/tooltip/tooltip.css +25 -0
- package/dist/components/ui/tooltip/tooltip.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip.script.d.ts +70 -0
- package/dist/components/ui/tree/index.d.ts +2 -0
- package/dist/components/ui/tree/index.js +2 -0
- package/dist/components/ui/tree/index.js.map +7 -0
- package/dist/components/ui/tree/tree.css +54 -0
- package/dist/components/ui/tree/tree.d.ts +13 -0
- package/dist/components/ui/tree/tree.script.d.ts +45 -0
- package/dist/components/ui/treegrid/index.d.ts +2 -0
- package/dist/components/ui/treegrid/index.js +2 -0
- package/dist/components/ui/treegrid/index.js.map +7 -0
- package/dist/components/ui/treegrid/treegrid.css +77 -0
- package/dist/components/ui/treegrid/treegrid.d.ts +14 -0
- package/dist/components/ui/treegrid/treegrid.script.d.ts +49 -0
- package/dist/components/ui/window-splitter/index.d.ts +2 -0
- package/dist/components/ui/window-splitter/index.js +2 -0
- package/dist/components/ui/window-splitter/index.js.map +7 -0
- package/dist/components/ui/window-splitter/window-splitter.css +35 -0
- package/dist/components/ui/window-splitter/window-splitter.d.ts +8 -0
- package/dist/components/ui/window-splitter/window-splitter.script.d.ts +49 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/lib/focusable-elements.d.ts +2 -0
- package/dist/lib/radiant-view.d.ts +17 -0
- package/dist/lib/roving-tabindex.d.ts +27 -0
- package/dist/styles/components/button.css +115 -0
- package/dist/styles/radiant-ui-core.css +7 -0
- package/dist/styles/radiant-ui.css +10 -0
- package/dist/styles/styles.css +36 -0
- package/dist/styles/tailwind.css +41 -0
- package/dist/styles/themes/aurora.css +19 -0
- package/dist/styles/themes/default-compact-soft.css +19 -0
- package/dist/styles/themes/default.css +2 -0
- package/dist/styles/themes/glacier.css +19 -0
- package/dist/styles/tokens/colors/aurora.css +73 -0
- package/dist/styles/tokens/colors/basalt.css +36 -0
- package/dist/styles/tokens/colors/glacier.css +45 -0
- package/dist/styles/tokens/colors/palettes.css +3 -0
- package/dist/styles/tokens/elevation/default.css +22 -0
- package/dist/styles/tokens/elevation/flat.css +22 -0
- package/dist/styles/tokens/motion/default.css +19 -0
- package/dist/styles/tokens/motion/snappy.css +19 -0
- package/dist/styles/tokens/presets/colors/aurora.css +126 -0
- package/dist/styles/tokens/presets/colors/basalt.css +126 -0
- package/dist/styles/tokens/presets/colors/ember.css +134 -0
- package/dist/styles/tokens/presets/colors/glacier.css +130 -0
- package/dist/styles/tokens/presets/colors/index.css +4 -0
- package/dist/styles/tokens/presets/radius.css +45 -0
- package/dist/styles/tokens/presets/spacing.css +57 -0
- package/dist/styles/tokens/radius/default.css +34 -0
- package/dist/styles/tokens/radius/edgy.css +35 -0
- package/dist/styles/tokens/radius/sharp.css +2 -0
- package/dist/styles/tokens/radius/soft.css +34 -0
- package/dist/styles/tokens/semantic.css +80 -0
- package/dist/styles/tokens/spacing/compact.css +23 -0
- package/dist/styles/tokens/spacing/default.css +23 -0
- package/dist/styles/tokens/spacing/scale-bridge.css +17 -0
- package/dist/styles/tokens/spacing/wide.css +23 -0
- package/dist/styles/tokens/system.css +36 -0
- package/dist/styles/tokens/typography/default.css +37 -0
- package/dist/styles/utilities/sheen.css +7 -0
- package/dist/types.d.ts +14 -0
- package/package.json +371 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { RuiCombobox as RuiComboboxElement, type RuiComboboxProps, type RuiComboboxChangeDetail, } from './combobox.script';
|
|
2
|
+
export { RuiCombobox, RuiComboboxControl, RuiComboboxInput, RuiComboboxListbox, RuiComboboxOption, RuiComboboxTrigger, type RuiComboboxOptionData, } from './combobox';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{RadiantElement as R,customElement as A,event as y,onEvent as n,onUpdated as C,prop as l}from"@ecopages/radiant";var u=@A("rui-combobox")class extends R{@l({type:String,reflect:!0,defaultValue:""})value;@l({type:String,defaultValue:""})label;@l({type:String,defaultValue:""})placeholder;@l({type:Boolean,reflect:!0,defaultValue:!1})disabled;@l({type:Boolean,reflect:!0,defaultValue:!1})openOnFocus;@y({name:"rui-change",bubbles:!0,composed:!0})changeEvent;open=!1;listboxHasVisualFocus=!1;activeIndex=-1;skipNextFocusOpen=!1;uid=Math.random().toString(36).slice(2,9);get listboxId(){return`rui-combobox-list-${this.uid}`}get inputId(){return`rui-combobox-input-${this.uid}`}getInput(){return this.querySelector("[data-combobox-input]")}getTrigger(){return this.querySelector("[data-combobox-trigger]")}getListbox(){return this.querySelector("[data-combobox-listbox]")}getOptions(){let t=this.getListbox();return t?Array.from(t.querySelectorAll("[data-combobox-option]")):[]}getVisibleOptions(){return this.getOptions().filter(t=>!t.hidden&&t.getAttribute("aria-disabled")!=="true")}getOptionLabel(t){return t.getAttribute("data-label")||t.textContent?.trim()||""}ensureOptionIds(){this.getOptions().forEach((t,e)=>{t.id||(t.id=`rui-combobox-option-${this.uid}-${e}`)})}getAccessibleName(){return this.findAssociatedLabel()?.textContent?.trim()||this.label||"Suggestions"}isComboboxInput(t){return t instanceof HTMLInputElement&&t.hasAttribute("data-combobox-input")}findAssociatedLabel(){let t=this.previousElementSibling;if(t instanceof HTMLLabelElement)return t;let e=this.parentElement;if(e){let i=e.querySelector("[data-rui-field-label], label.rui-label");if(i)return i}return null}syncLabel(){let t=this.getInput();if(!t||t.hasAttribute("data-rui-field-managed"))return;let e=this.findAssociatedLabel();if(e){e.id||(e.id=`rui-combobox-label-${this.uid}`),e.htmlFor||(e.htmlFor=this.inputId),t.setAttribute("aria-labelledby",e.id),t.removeAttribute("aria-label");return}if(this.label){t.setAttribute("aria-label",this.label),t.removeAttribute("aria-labelledby");return}t.removeAttribute("aria-label"),t.removeAttribute("aria-labelledby")}syncTrigger(){let t=this.getTrigger(),e=this.getListbox();!t||!e||(t.setAttribute("aria-expanded",String(this.open)),t.setAttribute("aria-controls",e.id||this.listboxId),t.tabIndex=-1,this.disabled&&(t.disabled=!0))}syncInput(){let t=this.getInput(),e=this.getListbox();!t||!e||(t.id||(t.id=this.inputId),e.id||(e.id=this.listboxId),t.setAttribute("role","combobox"),t.setAttribute("aria-haspopup","listbox"),t.setAttribute("aria-autocomplete","list"),t.setAttribute("aria-expanded",String(this.open)),t.setAttribute("aria-controls",this.listboxId),e.setAttribute("role","listbox"),e.setAttribute("aria-label",this.getAccessibleName()),this.placeholder&&!t.placeholder&&(t.placeholder=this.placeholder),this.disabled&&(t.disabled=!0),this.syncTrigger())}clearActiveOption(){this.activeIndex=-1,this.listboxHasVisualFocus=!1,this.getInput()?.removeAttribute("aria-activedescendant");for(let e of this.getOptions())e.removeAttribute("data-active"),e.removeAttribute("aria-selected")}setActiveOption(t){let e=this.getVisibleOptions();if(t<0||t>=e.length){this.clearActiveOption();return}this.activeIndex=t,this.listboxHasVisualFocus=!0;for(let r of this.getOptions())r.removeAttribute("data-active"),r.removeAttribute("aria-selected");let i=e[t],o=this.getInput();!i||!o||(i.id||(i.id=`rui-combobox-option-${this.uid}-${t}`),i.setAttribute("data-active","true"),i.setAttribute("aria-selected","true"),o.setAttribute("aria-activedescendant",i.id),i.scrollIntoView({block:"nearest"}))}setVisualFocusCombobox(){this.clearActiveOption()}setOpen(t,e={}){let i=e.activate??"none";this.open=t;let o=this.getInput(),r=this.getListbox();if(!(!o||!r)){if(o.setAttribute("aria-expanded",String(t)),r.hidden=!t,this.syncTrigger(),!t){this.clearActiveOption();return}if(this.ensureOptionIds(),i==="first"){let a=this.getVisibleOptions();this.setActiveOption(a.length?0:-1);return}if(i==="last"){let a=this.getVisibleOptions();this.setActiveOption(a.length?a.length-1:-1);return}this.clearActiveOption()}}filterOptions(t){let e=t.trim().toLowerCase();for(let i of this.getOptions()){let o=this.getOptionLabel(i).toLowerCase();i.hidden=e!==""&&!o.startsWith(e)}}select(t){if(t.getAttribute("aria-disabled")==="true")return;let e=t.getAttribute("data-value")||this.getOptionLabel(t),i=this.getOptionLabel(t)||e;this.value=e;let o=this.getInput();o&&(o.value=i),this.changeEvent.emit({value:e}),this.skipNextFocusOpen=!0,this.setOpen(!1),o?.focus()}syncFromValue(){let t=this.getInput();if(!t)return;let e=this.getOptions().find(o=>o.getAttribute("data-value")===this.value),i=e?this.getOptionLabel(e):this.value||"";t.value=i}initialize(){this.ensureOptionIds(),this.syncLabel(),this.syncInput(),this.syncFromValue(),this.setOpen(!1)}connectedCallback(){super.connectedCallback(),queueMicrotask(()=>this.initialize())}@C(["value","label","placeholder","disabled","openOnFocus"])onPropsUpdated(){this.syncLabel(),this.syncInput(),this.syncFromValue()}@n({ref:"root",type:"focusin"})onRootFocusIn(t){if(this.isComboboxInput(t.target)){if(this.skipNextFocusOpen){this.skipNextFocusOpen=!1;return}this.openOnFocus&&(this.filterOptions(this.getInput()?.value??""),this.setOpen(!0),this.setVisualFocusCombobox())}}@n({ref:"root",type:"input"})onRootInput(t){if(!this.isComboboxInput(t.target))return;let e=t.target;this.filterOptions(e.value),e.value.trim()!==""&&this.getVisibleOptions().length?this.setOpen(!0):e.value.trim()===""&&this.openOnFocus?this.setOpen(!0):(e.value.trim()===""||!this.getVisibleOptions().length)&&this.setOpen(!1),this.setVisualFocusCombobox()}@n({ref:"root",type:"keydown",options:{capture:!0}})onRootKeydown(t){this.isComboboxInput(t.target)&&this.handleInputKeydown(t)}moveActive(t){this.filterOptions(this.getInput()?.value??""),this.getVisibleOptions().length||this.filterOptions("");let e=this.getVisibleOptions();if(e.length){if(!this.open){this.setOpen(!0,{activate:t===1?"first":"last"});return}if(this.listboxHasVisualFocus){let i=t===1?this.activeIndex>=e.length-1?0:this.activeIndex+1:this.activeIndex<=0?e.length-1:this.activeIndex-1;this.setActiveOption(i);return}this.setActiveOption(t===1?0:e.length-1)}}handleInputKeydown(t){if(t.ctrlKey||t.shiftKey||t.metaKey)return;let e=t.altKey;if(t.key==="ArrowDown"){if(t.preventDefault(),t.stopPropagation(),e){this.open||(this.filterOptions(this.getInput()?.value??""),this.setOpen(!0));return}this.moveActive(1);return}if(t.key==="ArrowUp"){if(t.preventDefault(),t.stopPropagation(),e){this.open&&this.setOpen(!1);return}this.moveActive(-1);return}if(t.key==="Home"){let i=this.getInput();if(!i)return;t.preventDefault(),i.setSelectionRange(0,0),this.setVisualFocusCombobox();return}if(t.key==="End"){let i=this.getInput();if(!i)return;t.preventDefault();let o=i.value.length;i.setSelectionRange(o,o),this.setVisualFocusCombobox();return}if(t.key==="Escape"){if(t.preventDefault(),this.open){this.setOpen(!1);return}let i=this.getInput();i&&i.value&&(i.value="",this.value="",this.changeEvent.emit({value:""}),this.filterOptions(""));return}if(t.key==="Enter"){let i=this.getVisibleOptions();if(this.open&&this.listboxHasVisualFocus&&i[this.activeIndex]){t.preventDefault(),this.select(i[this.activeIndex]);return}this.open&&(t.preventDefault(),this.setOpen(!1));return}if(t.key==="Tab"&&this.open){let i=this.getVisibleOptions();if(this.listboxHasVisualFocus&&i[this.activeIndex]){this.select(i[this.activeIndex]);return}this.setOpen(!1)}}@n({selector:"[data-combobox-trigger]",type:"click"})onTriggerClick(t){t.preventDefault();let e=this.getInput();!e||e.disabled||(this.open?(this.skipNextFocusOpen=!0,this.setOpen(!1)):(this.filterOptions(e.value),this.setOpen(!0),this.setVisualFocusCombobox()),e.focus())}@n({selector:"[data-combobox-option]",type:"pointerover"})onOptionPointerOver(t){if(!this.open)return;let e=t.target.closest("[data-combobox-option]");if(!e||e.getAttribute("aria-disabled")==="true"||e.hidden)return;let o=this.getVisibleOptions().indexOf(e);o>=0&&this.setActiveOption(o)}@n({selector:"[data-combobox-option]",type:"mousedown"})onOptionMouseDown(t){t.preventDefault()}@n({selector:"[data-combobox-option]",type:"click"})onOptionClick(t){let e=t.target.closest("[data-combobox-option]");e&&this.select(e)}@n({ref:"root",type:"focusout"})onFocusOut(t){let e=t.relatedTarget;e instanceof Node&&this.contains(e)||this.setOpen(!1)}@n({document:!0,type:"click"})onDocumentClick(t){this.contains(t.target)||this.setOpen(!1)}render(){return React.createElement("div",{class:"rui-combobox","data-ref":"root"},React.createElement("slot",{name:"control"}),React.createElement("slot",{name:"listbox"}))}};var I=Symbol.for("@ecopages/storybook-radiant.viewElement"),c=Symbol.for("@ecopages/storybook-radiant.scriptModule"),d=Symbol.for("@ecopages/storybook-radiant.scriptExport");function E(s,t){s[I]=t;let e=t[c];e&&(s[c]=e,s[d]=t[d]??t.name)}function h(s,t){let e=(i=>t(i));return E(e,s),e}import"./combobox.css";function b(...s){return s.filter(Boolean).join(" ")}function m({slot:s="control",children:t,class:e}){return React.createElement("div",{slot:s,class:b("rui-combobox__control",e)},t)}function g({placeholder:s,disabled:t,class:e}){return React.createElement("input",{type:"text","data-combobox-input":!0,"data-rui-control":!0,"data-rui-control-type":"text",class:b("rui-combobox__input",e),placeholder:s,disabled:t,autocomplete:"off"})}function f({children:s,class:t,"aria-label":e="Show suggestions",disabled:i}){return React.createElement("button",{type:"button","data-combobox-trigger":!0,class:b("rui-combobox__trigger",t),"aria-label":e,disabled:i,tabIndex:-1},s??React.createElement("span",{"aria-hidden":"true"},"\u25BE"))}function x({slot:s="listbox",children:t,class:e}){return React.createElement("div",{slot:s,"data-combobox-listbox":!0,class:b("rui-combobox__listbox",e),hidden:!0},t)}function v({value:s,label:t,children:e,class:i,disabled:o}){return React.createElement("div",{role:"option","data-combobox-option":!0,"data-value":s,"data-label":t,class:b("rui-combobox__option",i),"aria-disabled":o?"true":void 0},e)}var T=h(u,({slot:s,value:t,label:e,placeholder:i,disabled:o,openOnFocus:r,options:a,children:O})=>a!=null?React.createElement("rui-combobox",{slot:s,value:t,label:e,placeholder:i,disabled:o,openOnFocus:r},React.createElement(m,null,React.createElement(g,{placeholder:i,disabled:o}),React.createElement(f,null)),React.createElement(x,null,a.map(p=>React.createElement(v,{value:p.value,label:typeof p.label=="string"?p.label:void 0},p.label)))):React.createElement("rui-combobox",{slot:s,value:t,label:e,placeholder:i,disabled:o,openOnFocus:r},O));export{T as RuiCombobox,m as RuiComboboxControl,u as RuiComboboxElement,g as RuiComboboxInput,x as RuiComboboxListbox,v as RuiComboboxOption,f as RuiComboboxTrigger};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/components/ui/combobox/combobox.script.tsx", "../../../../src/lib/radiant-view.ts", "../../../../src/components/ui/combobox/combobox.tsx"],
|
|
4
|
+
"sourcesContent": ["import { RadiantElement, customElement, event, onEvent, onUpdated, prop } from '@ecopages/radiant';\nimport type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';\n\nexport type RuiComboboxProps = {\n\tvalue?: string;\n\t/** Accessible name when there is no visible `RuiLabel` associated with the input. */\n\tlabel?: string;\n\tplaceholder?: string;\n\tdisabled?: boolean;\n\t/**\n\t * When true, focusing the input opens the listbox (visual focus stays on the\n\t * input until ArrowDown / ArrowUp). Defaults to false \u2014 APG list autocomplete\n\t * opens on ArrowDown, typing, or the trigger button.\n\t */\n\topenOnFocus?: boolean;\n};\n\nexport type RuiComboboxChangeDetail = { value: string };\n\n/**\n * `<rui-combobox>` \u2014 a composition-first combobox with a listbox popup.\n *\n * Implements the APG Combobox pattern (list autocomplete, manual selection).\n * DOM focus stays on the combobox input; visual focus moves into the popup via\n * `aria-activedescendant` when the user presses ArrowDown / ArrowUp.\n *\n * Pair with `RuiLabel` (sibling, or via `RuiField`) for the visible name.\n * Compose with `data-combobox-input`, optional `data-combobox-trigger`,\n * `data-combobox-listbox`, and `data-combobox-option` (see view helpers).\n *\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-autocomplete-list/\n * @element rui-combobox\n * @slot control - Input row (`RuiComboboxControl` with input and trigger).\n * @slot listbox - Popup listbox (`RuiComboboxListbox`).\n * @fires rui-change\n */\n@customElement('rui-combobox')\nexport class RuiCombobox extends RadiantElement {\n\t@prop({ type: String, reflect: true, defaultValue: '' }) value: string;\n\t@prop({ type: String, defaultValue: '' }) label: string;\n\t@prop({ type: String, defaultValue: '' }) placeholder: string;\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) disabled: boolean;\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) openOnFocus: boolean;\n\n\t@event({ name: 'rui-change', bubbles: true, composed: true })\n\tchangeEvent: EventEmitter<RuiComboboxChangeDetail>;\n\n\tprivate open = false;\n\t/** True when visual focus is in the listbox (aria-activedescendant is set). */\n\tprivate listboxHasVisualFocus = false;\n\tprivate activeIndex = -1;\n\tprivate skipNextFocusOpen = false;\n\tprivate readonly uid = Math.random().toString(36).slice(2, 9);\n\n\tprivate get listboxId(): string {\n\t\treturn `rui-combobox-list-${this.uid}`;\n\t}\n\n\tprivate get inputId(): string {\n\t\treturn `rui-combobox-input-${this.uid}`;\n\t}\n\n\tprivate getInput(): HTMLInputElement | null {\n\t\treturn this.querySelector<HTMLInputElement>('[data-combobox-input]');\n\t}\n\n\tprivate getTrigger(): HTMLButtonElement | null {\n\t\treturn this.querySelector<HTMLButtonElement>('[data-combobox-trigger]');\n\t}\n\n\tprivate getListbox(): HTMLElement | null {\n\t\treturn this.querySelector<HTMLElement>('[data-combobox-listbox]');\n\t}\n\n\tprivate getOptions(): HTMLElement[] {\n\t\tconst listbox = this.getListbox();\n\t\tif (!listbox) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn Array.from(listbox.querySelectorAll<HTMLElement>('[data-combobox-option]'));\n\t}\n\n\tprivate getVisibleOptions(): HTMLElement[] {\n\t\treturn this.getOptions().filter((option) => !option.hidden && option.getAttribute('aria-disabled') !== 'true');\n\t}\n\n\tprivate getOptionLabel(option: HTMLElement): string {\n\t\treturn option.getAttribute('data-label') || option.textContent?.trim() || '';\n\t}\n\n\tprivate ensureOptionIds(): void {\n\t\tthis.getOptions().forEach((option, index) => {\n\t\t\tif (!option.id) {\n\t\t\t\toption.id = `rui-combobox-option-${this.uid}-${index}`;\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate getAccessibleName(): string {\n\t\tconst labelElement = this.findAssociatedLabel();\n\t\treturn labelElement?.textContent?.trim() || this.label || 'Suggestions';\n\t}\n\n\tprivate isComboboxInput(target: EventTarget | null): target is HTMLInputElement {\n\t\treturn target instanceof HTMLInputElement && target.hasAttribute('data-combobox-input');\n\t}\n\n\t/** Prefer `RuiLabel` as a previous sibling or Field-managed label. */\n\tprivate findAssociatedLabel(): HTMLLabelElement | null {\n\t\tconst previous = this.previousElementSibling;\n\t\tif (previous instanceof HTMLLabelElement) {\n\t\t\treturn previous;\n\t\t}\n\n\t\tconst parent = this.parentElement;\n\t\tif (parent) {\n\t\t\tconst fieldLabel = parent.querySelector<HTMLLabelElement>('[data-rui-field-label], label.rui-label');\n\t\t\tif (fieldLabel) {\n\t\t\t\treturn fieldLabel;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate syncLabel(): void {\n\t\tconst input = this.getInput();\n\t\tif (!input) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (input.hasAttribute('data-rui-field-managed')) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst labelElement = this.findAssociatedLabel();\n\t\tif (labelElement) {\n\t\t\tif (!labelElement.id) {\n\t\t\t\tlabelElement.id = `rui-combobox-label-${this.uid}`;\n\t\t\t}\n\n\t\t\tif (!labelElement.htmlFor) {\n\t\t\t\tlabelElement.htmlFor = this.inputId;\n\t\t\t}\n\n\t\t\tinput.setAttribute('aria-labelledby', labelElement.id);\n\t\t\tinput.removeAttribute('aria-label');\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.label) {\n\t\t\tinput.setAttribute('aria-label', this.label);\n\t\t\tinput.removeAttribute('aria-labelledby');\n\t\t\treturn;\n\t\t}\n\n\t\tinput.removeAttribute('aria-label');\n\t\tinput.removeAttribute('aria-labelledby');\n\t}\n\n\tprivate syncTrigger(): void {\n\t\tconst trigger = this.getTrigger();\n\t\tconst listbox = this.getListbox();\n\t\tif (!trigger || !listbox) {\n\t\t\treturn;\n\t\t}\n\n\t\ttrigger.setAttribute('aria-expanded', String(this.open));\n\t\ttrigger.setAttribute('aria-controls', listbox.id || this.listboxId);\n\t\ttrigger.tabIndex = -1;\n\n\t\tif (this.disabled) {\n\t\t\ttrigger.disabled = true;\n\t\t}\n\t}\n\n\tprivate syncInput(): void {\n\t\tconst input = this.getInput();\n\t\tconst listbox = this.getListbox();\n\t\tif (!input || !listbox) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!input.id) {\n\t\t\tinput.id = this.inputId;\n\t\t}\n\n\t\tif (!listbox.id) {\n\t\t\tlistbox.id = this.listboxId;\n\t\t}\n\n\t\tinput.setAttribute('role', 'combobox');\n\t\tinput.setAttribute('aria-haspopup', 'listbox');\n\t\tinput.setAttribute('aria-autocomplete', 'list');\n\t\tinput.setAttribute('aria-expanded', String(this.open));\n\t\tinput.setAttribute('aria-controls', this.listboxId);\n\t\tlistbox.setAttribute('role', 'listbox');\n\t\tlistbox.setAttribute('aria-label', this.getAccessibleName());\n\n\t\tif (this.placeholder && !input.placeholder) {\n\t\t\tinput.placeholder = this.placeholder;\n\t\t}\n\n\t\tif (this.disabled) {\n\t\t\tinput.disabled = true;\n\t\t}\n\n\t\tthis.syncTrigger();\n\t}\n\n\tprivate clearActiveOption(): void {\n\t\tthis.activeIndex = -1;\n\t\tthis.listboxHasVisualFocus = false;\n\n\t\tconst input = this.getInput();\n\t\tinput?.removeAttribute('aria-activedescendant');\n\n\t\tfor (const option of this.getOptions()) {\n\t\t\toption.removeAttribute('data-active');\n\t\t\toption.removeAttribute('aria-selected');\n\t\t}\n\t}\n\n\tprivate setActiveOption(index: number): void {\n\t\tconst visible = this.getVisibleOptions();\n\t\tif (index < 0 || index >= visible.length) {\n\t\t\tthis.clearActiveOption();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.activeIndex = index;\n\t\tthis.listboxHasVisualFocus = true;\n\n\t\tfor (const option of this.getOptions()) {\n\t\t\toption.removeAttribute('data-active');\n\t\t\toption.removeAttribute('aria-selected');\n\t\t}\n\n\t\tconst active = visible[index];\n\t\tconst input = this.getInput();\n\t\tif (!active || !input) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!active.id) {\n\t\t\tactive.id = `rui-combobox-option-${this.uid}-${index}`;\n\t\t}\n\n\t\tactive.setAttribute('data-active', 'true');\n\t\tactive.setAttribute('aria-selected', 'true');\n\t\tinput.setAttribute('aria-activedescendant', active.id);\n\t\tactive.scrollIntoView({ block: 'nearest' });\n\t}\n\n\tprivate setVisualFocusCombobox(): void {\n\t\tthis.clearActiveOption();\n\t}\n\n\tprivate setOpen(next: boolean, options: { activate?: 'first' | 'last' | 'none' } = {}): void {\n\t\tconst activate = options.activate ?? 'none';\n\t\tthis.open = next;\n\t\tconst input = this.getInput();\n\t\tconst listbox = this.getListbox();\n\t\tif (!input || !listbox) {\n\t\t\treturn;\n\t\t}\n\n\t\tinput.setAttribute('aria-expanded', String(next));\n\t\tlistbox.hidden = !next;\n\t\tthis.syncTrigger();\n\n\t\tif (!next) {\n\t\t\tthis.clearActiveOption();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ensureOptionIds();\n\n\t\tif (activate === 'first') {\n\t\t\tconst visible = this.getVisibleOptions();\n\t\t\tthis.setActiveOption(visible.length ? 0 : -1);\n\t\t\treturn;\n\t\t}\n\n\t\tif (activate === 'last') {\n\t\t\tconst visible = this.getVisibleOptions();\n\t\t\tthis.setActiveOption(visible.length ? visible.length - 1 : -1);\n\t\t\treturn;\n\t\t}\n\n\t\t// Manual selection: popup can open without moving visual focus into it.\n\t\tthis.clearActiveOption();\n\t}\n\n\tprivate filterOptions(query: string): void {\n\t\tconst q = query.trim().toLowerCase();\n\t\tfor (const option of this.getOptions()) {\n\t\t\tconst text = this.getOptionLabel(option).toLowerCase();\n\t\t\toption.hidden = q !== '' && !text.startsWith(q);\n\t\t}\n\t}\n\n\tprivate select(option: HTMLElement): void {\n\t\tif (option.getAttribute('aria-disabled') === 'true') {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = option.getAttribute('data-value') || this.getOptionLabel(option);\n\t\tconst label = this.getOptionLabel(option) || value;\n\t\tthis.value = value;\n\n\t\tconst input = this.getInput();\n\t\tif (input) {\n\t\t\tinput.value = label;\n\t\t}\n\n\t\tthis.changeEvent.emit({ value });\n\t\tthis.skipNextFocusOpen = true;\n\t\tthis.setOpen(false);\n\t\tinput?.focus();\n\t}\n\n\tprivate syncFromValue(): void {\n\t\tconst input = this.getInput();\n\t\tif (!input) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst match = this.getOptions().find((option) => option.getAttribute('data-value') === this.value);\n\t\tconst label = match ? this.getOptionLabel(match) : this.value || '';\n\t\tinput.value = label;\n\t}\n\n\tprivate initialize(): void {\n\t\tthis.ensureOptionIds();\n\t\tthis.syncLabel();\n\t\tthis.syncInput();\n\t\tthis.syncFromValue();\n\t\tthis.setOpen(false);\n\t}\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback();\n\t\tqueueMicrotask(() => this.initialize());\n\t}\n\n\t@onUpdated(['value', 'label', 'placeholder', 'disabled', 'openOnFocus'])\n\tonPropsUpdated(): void {\n\t\tthis.syncLabel();\n\t\tthis.syncInput();\n\t\tthis.syncFromValue();\n\t}\n\n\t@onEvent({ ref: 'root', type: 'focusin' })\n\tonRootFocusIn(event: FocusEvent): void {\n\t\tif (!this.isComboboxInput(event.target)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.skipNextFocusOpen) {\n\t\t\tthis.skipNextFocusOpen = false;\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.openOnFocus) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.filterOptions(this.getInput()?.value ?? '');\n\t\tthis.setOpen(true);\n\t\tthis.setVisualFocusCombobox();\n\t}\n\n\t@onEvent({ ref: 'root', type: 'input' })\n\tonRootInput(event: Event): void {\n\t\tif (!this.isComboboxInput(event.target)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst input = event.target;\n\t\tthis.filterOptions(input.value);\n\t\tif (input.value.trim() !== '' && this.getVisibleOptions().length) {\n\t\t\tthis.setOpen(true);\n\t\t} else if (input.value.trim() === '' && this.openOnFocus) {\n\t\t\tthis.setOpen(true);\n\t\t} else if (input.value.trim() === '' || !this.getVisibleOptions().length) {\n\t\t\tthis.setOpen(false);\n\t\t}\n\n\t\t// Typing returns visual focus to the textbox.\n\t\tthis.setVisualFocusCombobox();\n\t}\n\n\t@onEvent({ ref: 'root', type: 'keydown', options: { capture: true } })\n\tonRootKeydown(event: KeyboardEvent): void {\n\t\tif (!this.isComboboxInput(event.target)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.handleInputKeydown(event);\n\t}\n\n\t/** Filter, open, and move the active option by one step (wrapping) toward `direction`. */\n\tprivate moveActive(direction: 1 | -1): void {\n\t\tthis.filterOptions(this.getInput()?.value ?? '');\n\t\tif (!this.getVisibleOptions().length) {\n\t\t\t// Show all options when the current filter has no matches.\n\t\t\tthis.filterOptions('');\n\t\t}\n\t\tconst visible = this.getVisibleOptions();\n\t\tif (!visible.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.open) {\n\t\t\tthis.setOpen(true, { activate: direction === 1 ? 'first' : 'last' });\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.listboxHasVisualFocus) {\n\t\t\tconst next =\n\t\t\t\tdirection === 1\n\t\t\t\t\t? this.activeIndex >= visible.length - 1\n\t\t\t\t\t\t? 0\n\t\t\t\t\t\t: this.activeIndex + 1\n\t\t\t\t\t: this.activeIndex <= 0\n\t\t\t\t\t\t? visible.length - 1\n\t\t\t\t\t\t: this.activeIndex - 1;\n\t\t\tthis.setActiveOption(next);\n\t\t\treturn;\n\t\t}\n\n\t\t// First arrow key while open: jump visual focus into the listbox.\n\t\tthis.setActiveOption(direction === 1 ? 0 : visible.length - 1);\n\t}\n\n\tprivate handleInputKeydown(event: KeyboardEvent): void {\n\t\tif (event.ctrlKey || event.shiftKey || event.metaKey) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst altKey = event.altKey;\n\n\t\tif (event.key === 'ArrowDown') {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tif (altKey) {\n\t\t\t\tif (!this.open) {\n\t\t\t\t\tthis.filterOptions(this.getInput()?.value ?? '');\n\t\t\t\t\tthis.setOpen(true);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.moveActive(1);\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'ArrowUp') {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tif (altKey) {\n\t\t\t\tif (this.open) {\n\t\t\t\t\tthis.setOpen(false);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.moveActive(-1);\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'Home') {\n\t\t\tconst input = this.getInput();\n\t\t\tif (!input) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tinput.setSelectionRange(0, 0);\n\t\t\tthis.setVisualFocusCombobox();\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'End') {\n\t\t\tconst input = this.getInput();\n\t\t\tif (!input) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tevent.preventDefault();\n\t\t\tconst length = input.value.length;\n\t\t\tinput.setSelectionRange(length, length);\n\t\t\tthis.setVisualFocusCombobox();\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'Escape') {\n\t\t\tevent.preventDefault();\n\t\t\tif (this.open) {\n\t\t\t\tthis.setOpen(false);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst input = this.getInput();\n\t\t\tif (input && input.value) {\n\t\t\t\tinput.value = '';\n\t\t\t\tthis.value = '';\n\t\t\t\tthis.changeEvent.emit({ value: '' });\n\t\t\t\tthis.filterOptions('');\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'Enter') {\n\t\t\tconst visible = this.getVisibleOptions();\n\t\t\tif (this.open && this.listboxHasVisualFocus && visible[this.activeIndex]) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.select(visible[this.activeIndex]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.open) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.setOpen(false);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'Tab' && this.open) {\n\t\t\tconst visible = this.getVisibleOptions();\n\t\t\tif (this.listboxHasVisualFocus && visible[this.activeIndex]) {\n\t\t\t\tthis.select(visible[this.activeIndex]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.setOpen(false);\n\t\t}\n\t}\n\n\t@onEvent({ selector: '[data-combobox-trigger]', type: 'click' })\n\tonTriggerClick(event: Event): void {\n\t\tevent.preventDefault();\n\t\tconst input = this.getInput();\n\t\tif (!input || input.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.open) {\n\t\t\tthis.skipNextFocusOpen = true;\n\t\t\tthis.setOpen(false);\n\t\t} else {\n\t\t\tthis.filterOptions(input.value);\n\t\t\tthis.setOpen(true);\n\t\t\tthis.setVisualFocusCombobox();\n\t\t}\n\n\t\tinput.focus();\n\t}\n\n\t@onEvent({ selector: '[data-combobox-option]', type: 'pointerover' })\n\tonOptionPointerOver(event: Event): void {\n\t\tif (!this.open) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst option = (event.target as HTMLElement).closest<HTMLElement>('[data-combobox-option]');\n\t\tif (!option || option.getAttribute('aria-disabled') === 'true' || option.hidden) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst visible = this.getVisibleOptions();\n\t\tconst index = visible.indexOf(option);\n\t\tif (index >= 0) {\n\t\t\tthis.setActiveOption(index);\n\t\t}\n\t}\n\n\t@onEvent({ selector: '[data-combobox-option]', type: 'mousedown' })\n\tonOptionMouseDown(event: Event): void {\n\t\tevent.preventDefault();\n\t}\n\n\t@onEvent({ selector: '[data-combobox-option]', type: 'click' })\n\tonOptionClick(event: Event): void {\n\t\tconst option = (event.target as HTMLElement).closest<HTMLElement>('[data-combobox-option]');\n\t\tif (option) {\n\t\t\tthis.select(option);\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'root', type: 'focusout' })\n\tonFocusOut(event: FocusEvent): void {\n\t\tconst next = event.relatedTarget;\n\t\tif (next instanceof Node && this.contains(next)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setOpen(false);\n\t}\n\n\t@onEvent({ document: true, type: 'click' })\n\tonDocumentClick(event: Event): void {\n\t\tif (!this.contains(event.target as Node)) {\n\t\t\tthis.setOpen(false);\n\t\t}\n\t}\n\n\toverride render() {\n\t\treturn (\n\t\t\t<div class=\"rui-combobox\" data-ref=\"root\">\n\t\t\t\t<slot name=\"control\"></slot>\n\t\t\t\t<slot name=\"listbox\"></slot>\n\t\t\t</div>\n\t\t);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\n\nconst RADIANT_VIEW_ELEMENT = Symbol.for('@ecopages/storybook-radiant.viewElement');\nconst RADIANT_SCRIPT_MODULE = Symbol.for('@ecopages/storybook-radiant.scriptModule');\nconst RADIANT_SCRIPT_EXPORT = Symbol.for('@ecopages/storybook-radiant.scriptExport');\n\nexport type RadiantViewComponent<TArgs = unknown> = ((args: TArgs) => JsxRenderable) & {\n\t[RADIANT_VIEW_ELEMENT]?: CustomElementConstructor;\n\t[RADIANT_SCRIPT_MODULE]?: string;\n\t[RADIANT_SCRIPT_EXPORT]?: string;\n};\n\nfunction linkViewToElement<TArgs>(\n\tview: RadiantViewComponent<TArgs>,\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n): void {\n\tview[RADIANT_VIEW_ELEMENT] = element;\n\n\tconst ssrModule = element[RADIANT_SCRIPT_MODULE];\n\tif (ssrModule) {\n\t\tview[RADIANT_SCRIPT_MODULE] = ssrModule;\n\t\tview[RADIANT_SCRIPT_EXPORT] = element[RADIANT_SCRIPT_EXPORT] ?? element.name;\n\t}\n}\n\n/** Link a JSX view export to its RadiantElement class (same symbols as the Storybook framework). */\nexport function defineRadiantView<TArgs>(\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n\trender: (args: TArgs) => JsxRenderable,\n): RadiantViewComponent<TArgs> {\n\tconst view = ((args: TArgs) => render(args)) as RadiantViewComponent<TArgs>;\n\tlinkViewToElement(view, element);\n\treturn view;\n}\n\n/** Re-copy SSR metadata from the linked element (e.g. after HMR). */\nexport function syncRadiantViewMetadata(view: RadiantViewComponent): void {\n\tconst element = view[RADIANT_VIEW_ELEMENT];\n\tif (element) {\n\t\tlinkViewToElement(view, element);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\nimport type { RadiantSlotProps } from '../../../types';\nimport { defineRadiantView } from '../../../lib/radiant-view';\nimport type { RuiComboboxProps } from './combobox.script';\nimport { RuiCombobox as RuiComboboxElement } from './combobox.script';\nimport './combobox.css';\n\nfunction cx(...parts: Array<string | false | null | undefined>): string {\n\treturn parts.filter(Boolean).join(' ');\n}\n\nexport type RuiComboboxControlProps = RadiantSlotProps & {\n\tchildren: JsxRenderable;\n\tclass?: string;\n};\n\n/** Input row wrapper for the combobox input and optional trigger icon. */\nexport function RuiComboboxControl({ slot = 'control', children, class: className }: RuiComboboxControlProps) {\n\treturn (\n\t\t<div slot={slot} class={cx('rui-combobox__control', className)}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport type RuiComboboxInputProps = {\n\tplaceholder?: string;\n\tdisabled?: boolean;\n\tclass?: string;\n};\n\n/** Text input with `role=\"combobox\"`. Place inside `RuiComboboxControl`. */\nexport function RuiComboboxInput({ placeholder, disabled, class: className }: RuiComboboxInputProps) {\n\treturn (\n\t\t<input\n\t\t\ttype=\"text\"\n\t\t\tdata-combobox-input\n\t\t\tdata-rui-control\n\t\t\tdata-rui-control-type=\"text\"\n\t\t\tclass={cx('rui-combobox__input', className)}\n\t\t\tplaceholder={placeholder}\n\t\t\tdisabled={disabled}\n\t\t\tautocomplete=\"off\"\n\t\t/>\n\t);\n}\n\nexport type RuiComboboxTriggerProps = {\n\tchildren?: JsxRenderable;\n\tclass?: string;\n\t'aria-label'?: string;\n\tdisabled?: boolean;\n};\n\n/** Optional open button placed inside `RuiComboboxControl`. */\nexport function RuiComboboxTrigger({\n\tchildren,\n\tclass: className,\n\t'aria-label': ariaLabel = 'Show suggestions',\n\tdisabled,\n}: RuiComboboxTriggerProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdata-combobox-trigger\n\t\t\tclass={cx('rui-combobox__trigger', className)}\n\t\t\taria-label={ariaLabel}\n\t\t\tdisabled={disabled}\n\t\t\ttabIndex={-1}\n\t\t>\n\t\t\t{children ?? <span aria-hidden=\"true\">\u25BE</span>}\n\t\t</button>\n\t);\n}\n\nexport type RuiComboboxListboxProps = RadiantSlotProps & {\n\tchildren: JsxRenderable;\n\tclass?: string;\n};\n\n/** Popup listbox slotted into `listbox` by default. */\nexport function RuiComboboxListbox({ slot = 'listbox', children, class: className }: RuiComboboxListboxProps) {\n\treturn (\n\t\t<div slot={slot} data-combobox-listbox class={cx('rui-combobox__listbox', className)} hidden>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport type RuiComboboxOptionProps = {\n\tvalue: string;\n\t/** Display text committed to the input when selected. Defaults to `children` text. */\n\tlabel?: string;\n\tchildren: JsxRenderable;\n\tclass?: string;\n\tdisabled?: boolean;\n};\n\n/** Listbox option placed inside `RuiComboboxListbox`. */\nexport function RuiComboboxOption({ value, label, children, class: className, disabled }: RuiComboboxOptionProps) {\n\treturn (\n\t\t<div\n\t\t\trole=\"option\"\n\t\t\tdata-combobox-option\n\t\t\tdata-value={value}\n\t\t\tdata-label={label}\n\t\t\tclass={cx('rui-combobox__option', className)}\n\t\t\taria-disabled={disabled ? 'true' : undefined}\n\t\t>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport type RuiComboboxOptionData = { value: string; label: JsxRenderable };\n\n/**\n * Combobox view. Pair with `RuiLabel` (sibling or via `RuiField`) for the visible name \u2014\n * do not nest a combobox-specific label.\n */\nexport const RuiCombobox = defineRadiantView(\n\tRuiComboboxElement,\n\t({\n\t\tslot,\n\t\tvalue,\n\t\tlabel,\n\t\tplaceholder,\n\t\tdisabled,\n\t\topenOnFocus,\n\t\toptions,\n\t\tchildren,\n\t}: RuiComboboxProps &\n\t\tRadiantSlotProps & {\n\t\t\toptions?: RuiComboboxOptionData[];\n\t\t\tchildren?: JsxRenderable;\n\t\t}) => {\n\t\tif (options != null) {\n\t\t\treturn (\n\t\t\t\t<rui-combobox\n\t\t\t\t\tslot={slot}\n\t\t\t\t\tvalue={value}\n\t\t\t\t\tlabel={label}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\topenOnFocus={openOnFocus}\n\t\t\t\t>\n\t\t\t\t\t<RuiComboboxControl>\n\t\t\t\t\t\t<RuiComboboxInput placeholder={placeholder} disabled={disabled} />\n\t\t\t\t\t\t<RuiComboboxTrigger />\n\t\t\t\t\t</RuiComboboxControl>\n\t\t\t\t\t<RuiComboboxListbox>\n\t\t\t\t\t\t{options.map((option) => (\n\t\t\t\t\t\t\t<RuiComboboxOption\n\t\t\t\t\t\t\t\tvalue={option.value}\n\t\t\t\t\t\t\t\tlabel={typeof option.label === 'string' ? option.label : undefined}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t</RuiComboboxOption>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</RuiComboboxListbox>\n\t\t\t\t</rui-combobox>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<rui-combobox\n\t\t\t\tslot={slot}\n\t\t\t\tvalue={value}\n\t\t\t\tlabel={label}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tdisabled={disabled}\n\t\t\t\topenOnFocus={openOnFocus}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</rui-combobox>\n\t\t);\n\t},\n);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RadiantElement", "customElement", "event", "onEvent", "onUpdated", "prop", "RuiCombobox", "listbox", "option", "index", "target", "previous", "parent", "fieldLabel", "input", "labelElement", "trigger", "visible", "active", "next", "options", "activate", "query", "q", "text", "value", "label", "match", "direction", "altKey", "length", "RADIANT_VIEW_ELEMENT", "RADIANT_SCRIPT_MODULE", "RADIANT_SCRIPT_EXPORT", "linkViewToElement", "view", "element", "ssrModule", "defineRadiantView", "render", "args", "cx", "parts", "RuiComboboxControl", "slot", "children", "className", "RuiComboboxInput", "placeholder", "disabled", "RuiComboboxTrigger", "ariaLabel", "RuiComboboxListbox", "RuiComboboxOption", "value", "label", "RuiCombobox", "defineRadiantView", "openOnFocus", "options", "option"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import './dialog.script';
|
|
2
|
+
import { type DialogHandle, type DialogOpenOptions } from './dialog-types';
|
|
3
|
+
export type InstallDialogsOptions = {
|
|
4
|
+
/** Parent node for the imperative host mount. Default: `document.body`. */
|
|
5
|
+
mount?: ParentNode;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Install document listeners for dialog events and `data-dialog-*` attributes.
|
|
9
|
+
* Idempotent — safe to call from app boot and Storybook decorators.
|
|
10
|
+
* Returns an uninstall function for tests / HMR.
|
|
11
|
+
*/
|
|
12
|
+
export declare function installDialogs(options?: InstallDialogsOptions): () => void;
|
|
13
|
+
/** Tear down listeners and the host dialog (mainly for tests). */
|
|
14
|
+
export declare function uninstallDialogs(): void;
|
|
15
|
+
/** Currently open dialog id, or `null`. */
|
|
16
|
+
export declare function getOpenDialogId(): string | null;
|
|
17
|
+
/** Open a named dialog by id, or fill/open the imperative host dialog. */
|
|
18
|
+
export declare function openDialog(idOrOptions: string | DialogOpenOptions): void;
|
|
19
|
+
/** Close the current dialog, or a specific id. */
|
|
20
|
+
export declare function closeDialog(id?: string): void;
|
|
21
|
+
/** Toggle a named dialog by id. */
|
|
22
|
+
export declare function toggleDialog(id: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Bound handle for a named dialog id, or the imperative host when `id` is omitted.
|
|
25
|
+
* A bound handle's `open()` always targets that id; pass options only on unbound handles.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const confirm = createDialogHandle();
|
|
29
|
+
* confirm.open({ title: 'Delete?', body: '…', actions: […] });
|
|
30
|
+
*
|
|
31
|
+
* const profile = createDialogHandle('edit-profile');
|
|
32
|
+
* profile.open();
|
|
33
|
+
*/
|
|
34
|
+
export declare function createDialogHandle(id?: string): DialogHandle;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './dialog.script';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** Reserved id for the registry-owned imperative host dialog. */
|
|
2
|
+
export declare const RUI_DIALOG_HOST_ID = "__rui-dialog-host";
|
|
3
|
+
export declare const RUI_DIALOG_OPEN_EVENT = "rui-dialog-open";
|
|
4
|
+
export declare const RUI_DIALOG_CLOSE_EVENT = "rui-dialog-close";
|
|
5
|
+
export declare const RUI_DIALOG_TOGGLE_EVENT = "rui-dialog-toggle";
|
|
6
|
+
export declare const RUI_DIALOG_ACTION_EVENT = "rui-dialog-action";
|
|
7
|
+
export type DialogActionVariant = 'primary' | 'ghost' | 'error' | 'outline' | 'filled';
|
|
8
|
+
export type DialogActionSize = 'sm' | 'md' | 'lg';
|
|
9
|
+
export type DialogAction = {
|
|
10
|
+
label: string;
|
|
11
|
+
variant?: DialogActionVariant;
|
|
12
|
+
size?: DialogActionSize;
|
|
13
|
+
/** Emitted on `rui-dialog-action` as `detail.value`. */
|
|
14
|
+
value?: string;
|
|
15
|
+
/** Default `true` — dismiss after click. */
|
|
16
|
+
closeOnClick?: boolean;
|
|
17
|
+
};
|
|
18
|
+
/** Content for the registry-owned imperative host dialog (no `id`). */
|
|
19
|
+
export type DialogHostContent = {
|
|
20
|
+
title?: string;
|
|
21
|
+
/** Body copy (plain text). */
|
|
22
|
+
body?: string;
|
|
23
|
+
alert?: boolean;
|
|
24
|
+
/** Accessible name when there is no title. */
|
|
25
|
+
label?: string;
|
|
26
|
+
actions?: DialogAction[];
|
|
27
|
+
};
|
|
28
|
+
/** Open a named dialog by id, or fill the imperative host — never both. */
|
|
29
|
+
export type DialogOpenOptions = {
|
|
30
|
+
id: string;
|
|
31
|
+
} | DialogHostContent;
|
|
32
|
+
export type DialogOpenDetail = DialogOpenOptions | string;
|
|
33
|
+
export type DialogCloseDetail = {
|
|
34
|
+
id?: string;
|
|
35
|
+
};
|
|
36
|
+
export type DialogToggleDetail = {
|
|
37
|
+
id: string;
|
|
38
|
+
};
|
|
39
|
+
export type DialogActionDetail = {
|
|
40
|
+
value?: string;
|
|
41
|
+
};
|
|
42
|
+
export type DialogHandle = {
|
|
43
|
+
open: {
|
|
44
|
+
(): void;
|
|
45
|
+
(id: string): void;
|
|
46
|
+
(options: DialogHostContent): void;
|
|
47
|
+
};
|
|
48
|
+
/** Omit `id` to close the currently open dialog. */
|
|
49
|
+
close: (id?: string) => void;
|
|
50
|
+
toggle: (id?: string) => void;
|
|
51
|
+
readonly openId: string | null;
|
|
52
|
+
};
|
|
53
|
+
export declare function isNamedDialogOpen(detail: DialogOpenOptions): detail is {
|
|
54
|
+
id: string;
|
|
55
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
@reference '../../../styles/radiant-ui.css';
|
|
2
|
+
|
|
3
|
+
rui-dialog {
|
|
4
|
+
@apply contents;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@layer components {
|
|
8
|
+
.rui-dialog {
|
|
9
|
+
@apply fixed inset-0 z-modal flex items-center justify-center;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.rui-dialog[hidden] {
|
|
13
|
+
@apply hidden;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.rui-dialog__backdrop {
|
|
17
|
+
@apply absolute inset-0 bg-overlay;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.rui-dialog__surface {
|
|
21
|
+
@apply relative z-modal w-full max-w-md rounded-container bg-background p-inset text-on-background shadow-lg;
|
|
22
|
+
@apply outline-none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.rui-dialog__close {
|
|
26
|
+
@apply absolute right-3 top-3 inline-flex size-8 items-center justify-center;
|
|
27
|
+
@apply cursor-pointer rounded-button border-0 bg-transparent text-xl text-on-surface;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.rui-dialog__close:focus-visible {
|
|
31
|
+
@apply ring-2 ring-focus-ring;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.rui-dialog__title {
|
|
35
|
+
@apply pr-8 text-lg font-semibold;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.rui-dialog__title:empty {
|
|
39
|
+
@apply hidden;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.rui-dialog__body {
|
|
43
|
+
@apply mt-3 text-sm;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.rui-dialog__actions {
|
|
47
|
+
@apply mt-6 flex justify-end gap-inline;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.rui-dialog__actions:empty {
|
|
51
|
+
@apply hidden;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { JsxRenderable } from '@ecopages/jsx';
|
|
2
|
+
import type { RadiantSlotProps } from '../../../types';
|
|
3
|
+
import type { RuiDialogProps } from './dialog.script';
|
|
4
|
+
import './dialog.css';
|
|
5
|
+
export type RuiDialogTitleProps = RadiantSlotProps & {
|
|
6
|
+
children: JsxRenderable;
|
|
7
|
+
class?: string;
|
|
8
|
+
};
|
|
9
|
+
/** Dialog title slotted into `title` by default. */
|
|
10
|
+
export declare function RuiDialogTitle({ slot, children, class: className }: RuiDialogTitleProps): JsxRenderable;
|
|
11
|
+
export type RuiDialogBodyProps = {
|
|
12
|
+
children: JsxRenderable;
|
|
13
|
+
class?: string;
|
|
14
|
+
};
|
|
15
|
+
/** Dialog body in the default slot. */
|
|
16
|
+
export declare function RuiDialogBody({ children, class: className }: RuiDialogBodyProps): JsxRenderable;
|
|
17
|
+
export type RuiDialogActionsProps = RadiantSlotProps & {
|
|
18
|
+
children: JsxRenderable;
|
|
19
|
+
class?: string;
|
|
20
|
+
};
|
|
21
|
+
/** Action row slotted into `actions` by default. */
|
|
22
|
+
export declare function RuiDialogActions({ slot, children, class: className }: RuiDialogActionsProps): JsxRenderable;
|
|
23
|
+
export type RuiDialogCloseProps = RadiantSlotProps & {
|
|
24
|
+
children?: JsxRenderable;
|
|
25
|
+
class?: string;
|
|
26
|
+
'aria-label'?: string;
|
|
27
|
+
};
|
|
28
|
+
/** Close control slotted into `close` by default. */
|
|
29
|
+
export declare function RuiDialogClose({ slot, children, class: className, 'aria-label': ariaLabel, }: RuiDialogCloseProps): JsxRenderable;
|
|
30
|
+
export type RuiDialogViewProps = RuiDialogProps & RadiantSlotProps & {
|
|
31
|
+
id?: string;
|
|
32
|
+
title?: JsxRenderable;
|
|
33
|
+
actions?: JsxRenderable;
|
|
34
|
+
children?: JsxRenderable;
|
|
35
|
+
};
|
|
36
|
+
export declare const RuiDialog: import("../../../lib/radiant-view").RadiantViewComponent<RuiDialogViewProps>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { RadiantElement } from '@ecopages/radiant';
|
|
2
|
+
import type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';
|
|
3
|
+
export type RuiDialogProps = {
|
|
4
|
+
/** Whether the dialog is open. Default: `false`. */
|
|
5
|
+
open?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* When `true`, uses `role="alertdialog"` for workflow-interrupting
|
|
8
|
+
* confirmations. Default: `false` (`role="dialog"`).
|
|
9
|
+
*/
|
|
10
|
+
alert?: boolean;
|
|
11
|
+
/** Accessible name when there is no visible title. */
|
|
12
|
+
label?: string;
|
|
13
|
+
};
|
|
14
|
+
export type RuiDialogCloseDetail = {
|
|
15
|
+
reason: 'escape' | 'backdrop' | 'dismiss';
|
|
16
|
+
};
|
|
17
|
+
type RuiDialogBindings = {
|
|
18
|
+
open: boolean;
|
|
19
|
+
alert: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* `<rui-dialog>` — a composition-first modal dialog shell.
|
|
23
|
+
*
|
|
24
|
+
* Implements the WAI-ARIA APG Dialog (Modal) pattern, and the Alert and Message
|
|
25
|
+
* Dialogs pattern when `alert` is set. Compose title, body, actions, and close
|
|
26
|
+
* controls with the view helpers.
|
|
27
|
+
*
|
|
28
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
|
|
29
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/
|
|
30
|
+
*
|
|
31
|
+
* @element rui-dialog
|
|
32
|
+
* @slot close - Optional close control (`RuiDialogClose`).
|
|
33
|
+
* @slot title - Optional visible dialog title (`RuiDialogTitle`).
|
|
34
|
+
* @slot - Dialog body (`RuiDialogBody`).
|
|
35
|
+
* @slot actions - Optional action buttons (`RuiDialogActions`).
|
|
36
|
+
* @fires rui-close - Emitted when the dialog is dismissed.
|
|
37
|
+
*/
|
|
38
|
+
export declare class RuiDialog extends RadiantElement<RuiDialogBindings> {
|
|
39
|
+
open: boolean;
|
|
40
|
+
alert: boolean;
|
|
41
|
+
label: string;
|
|
42
|
+
dialogTarget: HTMLElement;
|
|
43
|
+
titleTarget: HTMLElement;
|
|
44
|
+
descriptionTarget: HTMLElement;
|
|
45
|
+
closeEvent: EventEmitter<RuiDialogCloseDetail>;
|
|
46
|
+
private readonly dialogHidden;
|
|
47
|
+
private readonly resolvedRole;
|
|
48
|
+
private previouslyFocused;
|
|
49
|
+
private titleId;
|
|
50
|
+
private descriptionId;
|
|
51
|
+
connectedCallback(): void;
|
|
52
|
+
syncOpenState(): void;
|
|
53
|
+
private focusInitial;
|
|
54
|
+
private getFocusable;
|
|
55
|
+
private dismiss;
|
|
56
|
+
onDocumentKeydown(event: KeyboardEvent): void;
|
|
57
|
+
onBackdropClick(): void;
|
|
58
|
+
onCloseClick(): void;
|
|
59
|
+
render(): import("@ecopages/jsx").JsxRenderable;
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { RuiDialog as RuiDialogElement, type RuiDialogProps, type RuiDialogCloseDetail } from './dialog.script';
|
|
2
|
+
export { RuiDialog, RuiDialogActions, RuiDialogBody, RuiDialogClose, RuiDialogTitle, type RuiDialogViewProps, type RuiDialogTitleProps, type RuiDialogBodyProps, type RuiDialogActionsProps, type RuiDialogCloseProps, } from './dialog';
|
|
3
|
+
export { installDialogs, uninstallDialogs, openDialog, closeDialog, toggleDialog, createDialogHandle, getOpenDialogId, type InstallDialogsOptions, } from './dialog-registry';
|
|
4
|
+
export { RUI_DIALOG_HOST_ID, RUI_DIALOG_OPEN_EVENT, RUI_DIALOG_CLOSE_EVENT, RUI_DIALOG_TOGGLE_EVENT, RUI_DIALOG_ACTION_EVENT, type DialogAction, type DialogActionVariant, type DialogActionSize, type DialogOpenOptions, type DialogHostContent, type DialogOpenDetail, type DialogCloseDetail, type DialogToggleDetail, type DialogActionDetail, type DialogHandle, } from './dialog-types';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{RadiantElement as z,bound as j,customElement as q,event as K,onEvent as A,onUpdated as X,prop as _,query as I}from"@ecopages/radiant";var W='a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])',c=@q("rui-dialog")class extends z{@_({type:Boolean,reflect:!0,defaultValue:!1})open;@_({type:Boolean,reflect:!0,defaultValue:!1})alert;@_({type:String,defaultValue:""})label;@I({ref:"dialog"})dialogTarget;@I({selector:"[data-dialog-title]"})titleTarget;@I({selector:"[data-dialog-body]"})descriptionTarget;@K({name:"rui-close",bubbles:!0,composed:!0})closeEvent;dialogHidden=this.$.open.map(t=>!t);resolvedRole=this.$.alert.map(t=>t?"alertdialog":"dialog");previouslyFocused=null;titleId=`rui-dialog-title-${Math.random().toString(36).slice(2,9)}`;descriptionId=`rui-dialog-desc-${Math.random().toString(36).slice(2,9)}`;connectedCallback(){super.connectedCallback(),queueMicrotask(()=>this.syncOpenState())}@j@X(["open","label"])syncOpenState(){this.dialogTarget&&(this.titleTarget?.textContent?.trim()?(this.titleTarget.id=this.titleId,this.dialogTarget.setAttribute("aria-labelledby",this.titleId),this.dialogTarget.removeAttribute("aria-label")):this.label&&(this.dialogTarget.setAttribute("aria-label",this.label),this.dialogTarget.removeAttribute("aria-labelledby")),this.descriptionTarget?(this.descriptionTarget.id=this.descriptionId,this.dialogTarget.setAttribute("aria-describedby",this.descriptionId)):this.dialogTarget.removeAttribute("aria-describedby"),this.open?(this.previouslyFocused=document.activeElement,queueMicrotask(()=>this.focusInitial())):(this.previouslyFocused?.focus?.(),this.previouslyFocused=null))}focusInitial(){(this.getFocusable()[0]??this.dialogTarget)?.focus()}getFocusable(){return Array.from(this.dialogTarget?.querySelectorAll(W)??[]).filter(t=>!t.hasAttribute("disabled")&&t.tabIndex!==-1)}dismiss(t){this.open&&(this.open=!1,this.closeEvent.emit({reason:t}))}@A({document:!0,type:"keydown"})onDocumentKeydown(t){if(!this.open)return;if(t.key==="Escape"){t.preventDefault(),this.dismiss("escape");return}if(t.key!=="Tab")return;let o=this.getFocusable();if(!o.length){t.preventDefault(),this.dialogTarget.focus();return}let i=o[0],n=o[o.length-1],a=document.activeElement;t.shiftKey&&a===i?(t.preventDefault(),n.focus()):!t.shiftKey&&a===n&&(t.preventDefault(),i.focus())}@A({ref:"backdrop",type:"click"})onBackdropClick(){this.dismiss("backdrop")}@A({selector:"[data-dialog-close]",type:"click"})onCloseClick(){this.dismiss("dismiss")}render(){return React.createElement("div",{class:"rui-dialog",hidden:this.dialogHidden},React.createElement("div",{"data-ref":"backdrop",class:"rui-dialog__backdrop"}),React.createElement("div",{"data-ref":"dialog",class:"rui-dialog__surface",tabindex:-1,role:this.resolvedRole,"aria-modal":"true"},React.createElement("slot",{name:"close"}),React.createElement("slot",{name:"title"}),React.createElement("slot",null),React.createElement("slot",{name:"actions"})))}};var Q=Symbol.for("@ecopages/storybook-radiant.viewElement"),L=Symbol.for("@ecopages/storybook-radiant.scriptModule"),P=Symbol.for("@ecopages/storybook-radiant.scriptExport");function Y(e,t){e[Q]=t;let o=t[L];o&&(e[L]=o,e[P]=t[P]??t.name)}function N(e,t){let o=(i=>t(i));return Y(o,e),o}import"./dialog.css";function m(...e){return e.filter(Boolean).join(" ")}function H({slot:e="title",children:t,class:o}){return React.createElement("div",{slot:e,"data-dialog-title":!0,"data-ref":"title",class:m("rui-dialog__title",o)},t)}function S({children:e,class:t}){return React.createElement("div",{"data-dialog-body":!0,"data-ref":"description",class:m("rui-dialog__body",t)},e)}function V({slot:e="actions",children:t,class:o}){return React.createElement("div",{slot:e,class:m("rui-dialog__actions",o)},t)}function k({slot:e="close",children:t,class:o,"aria-label":i="Close"}){return React.createElement("button",{slot:e,type:"button","data-dialog-close":!0,"data-ref":"close",class:m("rui-dialog__close",o),"aria-label":i},t??"\xD7")}var Z=N(c,({slot:e,open:t,alert:o,label:i,id:n,title:a,actions:g,children:T})=>a!=null||g!=null?React.createElement("rui-dialog",{slot:e,id:n,open:t,alert:o,label:i},React.createElement(k,null),a!=null?React.createElement(H,null,a):null,T!=null?React.createElement(S,null,T):null,g!=null?React.createElement(V,null,g):null):React.createElement("rui-dialog",{slot:e,id:n,open:t,alert:o,label:i},T));var r="__rui-dialog-host",b="rui-dialog-open",E="rui-dialog-close",y="rui-dialog-toggle",x="rui-dialog-action";function M(e){return"id"in e&&e.id!=null&&e.id!==""}var p=!1,R=null,D=null,l=null;function h(e){let t=e.trim();if(!t)return null;let o=document.getElementById(t);return o?.localName==="rui-dialog"?o:null}function tt(){let e=document.createElement("button");return e.slot="close",e.type="button",e.setAttribute("data-dialog-close",""),e.setAttribute("data-ref","close"),e.className="rui-dialog__close",e.setAttribute("aria-label","Close"),e.textContent="\xD7",e}function et(e){let t=document.createElement("div");return t.slot="title",t.setAttribute("data-dialog-title",""),t.setAttribute("data-ref","title"),t.className="rui-dialog__title",t.textContent=e,t}function ot(e){let t=document.createElement("div");t.setAttribute("data-dialog-body",""),t.setAttribute("data-ref","description"),t.className="rui-dialog__body";let o=document.createElement("p");return o.textContent=e,t.append(o),t}function it(e){let t=document.createElement("div");t.slot="actions",t.className="rui-dialog__actions";for(let o of e){let i=document.createElement("button");i.type="button",i.className=`rui-button rui-button--${o.variant??"filled"} rui-button--${o.size??"md"}`,i.setAttribute("data-dialog-action",o.value??""),o.closeOnClick===!1&&i.setAttribute("data-dialog-action-close","false"),i.textContent=o.label,t.append(i)}return t}function f(){D?.remove(),D=null}function lt(e){f();let t=document.createElement("rui-dialog");return t.id=r,t.alert=!!e.alert,t.label=e.label??"",t.append(tt()),e.title&&t.append(et(e.title)),e.body&&t.append(ot(e.body)),e.actions?.length&&t.append(it(e.actions)),(R??document.body).appendChild(t),D=t,t}function G(e){if(!(!l||l===e))if(l===r)f();else{let t=h(l);t&&(t.open=!1)}}function d(e){s();let t=h(e);t&&(G(e),t.open=!0,l=e)}function nt(e){s(),G(r);let t=lt(e);t.open=!0,l=r}function v(e){if(typeof e=="string"){d(e);return}if(M(e)){d(e.id);return}nt(e)}function u(e){s();let t=e??l;if(t){if(t===r)f();else{let o=h(t);o&&(o.open=!1)}l===t&&(l=null)}}function O(e){if(s(),l===e){u(e);return}d(e)}function U(e){let t=e.detail;if(typeof t=="string"){v(t);return}t&&typeof t=="object"&&v(t)}function B(e){let t=e.detail;u(t?.id)}function w(e){let t=e.detail;t?.id&&O(t.id)}function J(e){let t=e.target;if(!t?.closest)return;let o=t.closest("[data-dialog-action]");if(o&&D?.contains(o)){e.preventDefault();let g={value:o.getAttribute("data-dialog-action")||void 0||void 0};D.dispatchEvent(new CustomEvent(x,{detail:g,bubbles:!0,composed:!0})),o.getAttribute("data-dialog-action-close")!=="false"&&u(r);return}let i=t.closest("[data-dialog-open]");if(i){let a=i.getAttribute("data-dialog-open")?.trim();a&&(e.preventDefault(),d(a));return}let n=t.closest("[data-dialog-close]");if(n){if(n.closest("rui-dialog")?.hasAttribute("open"))return;e.preventDefault(),u()}}function F(e){let t=e.target?.closest?.("rui-dialog");if(!t)return;let o=t.id||null;o&&l===o&&(o===r&&f(),l=null)}function $(e={}){return p?(e.mount&&(R=e.mount),C):(p=!0,R=e.mount??document.body,document.addEventListener(b,U),document.addEventListener(E,B),document.addEventListener(y,w),document.addEventListener("click",J),document.addEventListener("rui-close",F),C)}function s(){p||$()}function C(){p&&(document.removeEventListener(b,U),document.removeEventListener(E,B),document.removeEventListener(y,w),document.removeEventListener("click",J),document.removeEventListener("rui-close",F),f(),R=null,l=null,p=!1)}function at(){return l}function rt(e){s(),v(e)}function st(e){s(),u(e)}function dt(e){s(),O(e)}function ut(e){s();let t=e?.trim()||void 0;return{open:(i=>{if(t){d(t);return}if(i!=null){if(typeof i=="string"){d(i);return}v(i)}}),close:i=>{u(i??t)},toggle:i=>{let n=i??t;n&&O(n)},get openId(){return l}}}export{x as RUI_DIALOG_ACTION_EVENT,E as RUI_DIALOG_CLOSE_EVENT,r as RUI_DIALOG_HOST_ID,b as RUI_DIALOG_OPEN_EVENT,y as RUI_DIALOG_TOGGLE_EVENT,Z as RuiDialog,V as RuiDialogActions,S as RuiDialogBody,k as RuiDialogClose,c as RuiDialogElement,H as RuiDialogTitle,st as closeDialog,ut as createDialogHandle,at as getOpenDialogId,$ as installDialogs,rt as openDialog,dt as toggleDialog,C as uninstallDialogs};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/components/ui/dialog/dialog.script.tsx", "../../../../src/lib/radiant-view.ts", "../../../../src/components/ui/dialog/dialog.tsx", "../../../../src/components/ui/dialog/dialog-types.ts", "../../../../src/components/ui/dialog/dialog-registry.ts"],
|
|
4
|
+
"sourcesContent": ["import { RadiantElement, bound, customElement, event, onEvent, onUpdated, prop, query } from '@ecopages/radiant';\nimport type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';\n\nexport type RuiDialogProps = {\n\t/** Whether the dialog is open. Default: `false`. */\n\topen?: boolean;\n\t/**\n\t * When `true`, uses `role=\"alertdialog\"` for workflow-interrupting\n\t * confirmations. Default: `false` (`role=\"dialog\"`).\n\t */\n\talert?: boolean;\n\t/** Accessible name when there is no visible title. */\n\tlabel?: string;\n};\n\nexport type RuiDialogCloseDetail = {\n\treason: 'escape' | 'backdrop' | 'dismiss';\n};\n\ntype RuiDialogBindings = {\n\topen: boolean;\n\talert: boolean;\n};\n\nconst FOCUSABLE =\n\t'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * `<rui-dialog>` \u2014 a composition-first modal dialog shell.\n *\n * Implements the WAI-ARIA APG Dialog (Modal) pattern, and the Alert and Message\n * Dialogs pattern when `alert` is set. Compose title, body, actions, and close\n * controls with the view helpers.\n *\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/\n *\n * @element rui-dialog\n * @slot close - Optional close control (`RuiDialogClose`).\n * @slot title - Optional visible dialog title (`RuiDialogTitle`).\n * @slot - Dialog body (`RuiDialogBody`).\n * @slot actions - Optional action buttons (`RuiDialogActions`).\n * @fires rui-close - Emitted when the dialog is dismissed.\n */\n@customElement('rui-dialog')\nexport class RuiDialog extends RadiantElement<RuiDialogBindings> {\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) open: boolean;\n\t@prop({ type: Boolean, reflect: true, defaultValue: false }) alert: boolean;\n\t@prop({ type: String, defaultValue: '' }) label: string;\n\n\t@query({ ref: 'dialog' }) dialogTarget: HTMLElement;\n\t@query({ selector: '[data-dialog-title]' }) titleTarget: HTMLElement;\n\t@query({ selector: '[data-dialog-body]' }) descriptionTarget: HTMLElement;\n\n\t@event({ name: 'rui-close', bubbles: true, composed: true })\n\tcloseEvent: EventEmitter<RuiDialogCloseDetail>;\n\n\tprivate readonly dialogHidden = this.$.open.map((open) => !open);\n\tprivate readonly resolvedRole = this.$.alert.map((alert) => (alert ? 'alertdialog' : 'dialog'));\n\n\tprivate previouslyFocused: HTMLElement | null = null;\n\tprivate titleId = `rui-dialog-title-${Math.random().toString(36).slice(2, 9)}`;\n\tprivate descriptionId = `rui-dialog-desc-${Math.random().toString(36).slice(2, 9)}`;\n\n\toverride connectedCallback(): void {\n\t\tsuper.connectedCallback();\n\t\tqueueMicrotask(() => this.syncOpenState());\n\t}\n\n\t@bound\n\t@onUpdated(['open', 'label'])\n\tsyncOpenState(): void {\n\t\tif (!this.dialogTarget) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.titleTarget?.textContent?.trim()) {\n\t\t\tthis.titleTarget.id = this.titleId;\n\t\t\tthis.dialogTarget.setAttribute('aria-labelledby', this.titleId);\n\t\t\tthis.dialogTarget.removeAttribute('aria-label');\n\t\t} else if (this.label) {\n\t\t\tthis.dialogTarget.setAttribute('aria-label', this.label);\n\t\t\tthis.dialogTarget.removeAttribute('aria-labelledby');\n\t\t}\n\n\t\tif (this.descriptionTarget) {\n\t\t\tthis.descriptionTarget.id = this.descriptionId;\n\t\t\tthis.dialogTarget.setAttribute('aria-describedby', this.descriptionId);\n\t\t} else {\n\t\t\tthis.dialogTarget.removeAttribute('aria-describedby');\n\t\t}\n\n\t\tif (this.open) {\n\t\t\tthis.previouslyFocused = document.activeElement as HTMLElement | null;\n\t\t\tqueueMicrotask(() => this.focusInitial());\n\t\t} else {\n\t\t\tthis.previouslyFocused?.focus?.();\n\t\t\tthis.previouslyFocused = null;\n\t\t}\n\t}\n\n\tprivate focusInitial(): void {\n\t\tconst focusable = this.getFocusable();\n\t\t(focusable[0] ?? this.dialogTarget)?.focus();\n\t}\n\n\tprivate getFocusable(): HTMLElement[] {\n\t\treturn Array.from(this.dialogTarget?.querySelectorAll<HTMLElement>(FOCUSABLE) ?? []).filter(\n\t\t\t(el) => !el.hasAttribute('disabled') && el.tabIndex !== -1,\n\t\t);\n\t}\n\n\tprivate dismiss(reason: RuiDialogCloseDetail['reason']): void {\n\t\tif (!this.open) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.open = false;\n\t\tthis.closeEvent.emit({ reason });\n\t}\n\n\t@onEvent({ document: true, type: 'keydown' })\n\tonDocumentKeydown(event: KeyboardEvent): void {\n\t\tif (!this.open) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key === 'Escape') {\n\t\t\tevent.preventDefault();\n\t\t\tthis.dismiss('escape');\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.key !== 'Tab') {\n\t\t\treturn;\n\t\t}\n\n\t\tconst focusable = this.getFocusable();\n\t\tif (!focusable.length) {\n\t\t\tevent.preventDefault();\n\t\t\tthis.dialogTarget.focus();\n\t\t\treturn;\n\t\t}\n\n\t\tconst first = focusable[0];\n\t\tconst last = focusable[focusable.length - 1];\n\t\tconst active = document.activeElement as HTMLElement | null;\n\n\t\tif (event.shiftKey && active === first) {\n\t\t\tevent.preventDefault();\n\t\t\tlast.focus();\n\t\t} else if (!event.shiftKey && active === last) {\n\t\t\tevent.preventDefault();\n\t\t\tfirst.focus();\n\t\t}\n\t}\n\n\t@onEvent({ ref: 'backdrop', type: 'click' })\n\tonBackdropClick(): void {\n\t\tthis.dismiss('backdrop');\n\t}\n\n\t@onEvent({ selector: '[data-dialog-close]', type: 'click' })\n\tonCloseClick(): void {\n\t\tthis.dismiss('dismiss');\n\t}\n\n\toverride render() {\n\t\treturn (\n\t\t\t<div class=\"rui-dialog\" hidden={this.dialogHidden}>\n\t\t\t\t<div data-ref=\"backdrop\" class=\"rui-dialog__backdrop\"></div>\n\t\t\t\t<div\n\t\t\t\t\tdata-ref=\"dialog\"\n\t\t\t\t\tclass=\"rui-dialog__surface\"\n\t\t\t\t\ttabindex={-1}\n\t\t\t\t\trole={this.resolvedRole}\n\t\t\t\t\taria-modal=\"true\"\n\t\t\t\t>\n\t\t\t\t\t<slot name=\"close\"></slot>\n\t\t\t\t\t<slot name=\"title\"></slot>\n\t\t\t\t\t<slot></slot>\n\t\t\t\t\t<slot name=\"actions\"></slot>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\n\nconst RADIANT_VIEW_ELEMENT = Symbol.for('@ecopages/storybook-radiant.viewElement');\nconst RADIANT_SCRIPT_MODULE = Symbol.for('@ecopages/storybook-radiant.scriptModule');\nconst RADIANT_SCRIPT_EXPORT = Symbol.for('@ecopages/storybook-radiant.scriptExport');\n\nexport type RadiantViewComponent<TArgs = unknown> = ((args: TArgs) => JsxRenderable) & {\n\t[RADIANT_VIEW_ELEMENT]?: CustomElementConstructor;\n\t[RADIANT_SCRIPT_MODULE]?: string;\n\t[RADIANT_SCRIPT_EXPORT]?: string;\n};\n\nfunction linkViewToElement<TArgs>(\n\tview: RadiantViewComponent<TArgs>,\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n): void {\n\tview[RADIANT_VIEW_ELEMENT] = element;\n\n\tconst ssrModule = element[RADIANT_SCRIPT_MODULE];\n\tif (ssrModule) {\n\t\tview[RADIANT_SCRIPT_MODULE] = ssrModule;\n\t\tview[RADIANT_SCRIPT_EXPORT] = element[RADIANT_SCRIPT_EXPORT] ?? element.name;\n\t}\n}\n\n/** Link a JSX view export to its RadiantElement class (same symbols as the Storybook framework). */\nexport function defineRadiantView<TArgs>(\n\telement: CustomElementConstructor & {\n\t\t[RADIANT_SCRIPT_MODULE]?: string;\n\t\t[RADIANT_SCRIPT_EXPORT]?: string;\n\t},\n\trender: (args: TArgs) => JsxRenderable,\n): RadiantViewComponent<TArgs> {\n\tconst view = ((args: TArgs) => render(args)) as RadiantViewComponent<TArgs>;\n\tlinkViewToElement(view, element);\n\treturn view;\n}\n\n/** Re-copy SSR metadata from the linked element (e.g. after HMR). */\nexport function syncRadiantViewMetadata(view: RadiantViewComponent): void {\n\tconst element = view[RADIANT_VIEW_ELEMENT];\n\tif (element) {\n\t\tlinkViewToElement(view, element);\n\t}\n}\n", "import type { JsxRenderable } from '@ecopages/jsx';\nimport type { RadiantSlotProps } from '../../../types';\nimport { defineRadiantView } from '../../../lib/radiant-view';\nimport type { RuiDialogProps } from './dialog.script';\nimport { RuiDialog as RuiDialogElement } from './dialog.script';\nimport './dialog.css';\n\nfunction cx(...parts: Array<string | false | null | undefined>): string {\n\treturn parts.filter(Boolean).join(' ');\n}\n\nexport type RuiDialogTitleProps = RadiantSlotProps & {\n\tchildren: JsxRenderable;\n\tclass?: string;\n};\n\n/** Dialog title slotted into `title` by default. */\nexport function RuiDialogTitle({ slot = 'title', children, class: className }: RuiDialogTitleProps) {\n\treturn (\n\t\t<div slot={slot} data-dialog-title data-ref=\"title\" class={cx('rui-dialog__title', className)}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport type RuiDialogBodyProps = {\n\tchildren: JsxRenderable;\n\tclass?: string;\n};\n\n/** Dialog body in the default slot. */\nexport function RuiDialogBody({ children, class: className }: RuiDialogBodyProps) {\n\treturn (\n\t\t<div data-dialog-body data-ref=\"description\" class={cx('rui-dialog__body', className)}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport type RuiDialogActionsProps = RadiantSlotProps & {\n\tchildren: JsxRenderable;\n\tclass?: string;\n};\n\n/** Action row slotted into `actions` by default. */\nexport function RuiDialogActions({ slot = 'actions', children, class: className }: RuiDialogActionsProps) {\n\treturn (\n\t\t<div slot={slot} class={cx('rui-dialog__actions', className)}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport type RuiDialogCloseProps = RadiantSlotProps & {\n\tchildren?: JsxRenderable;\n\tclass?: string;\n\t'aria-label'?: string;\n};\n\n/** Close control slotted into `close` by default. */\nexport function RuiDialogClose({\n\tslot = 'close',\n\tchildren,\n\tclass: className,\n\t'aria-label': ariaLabel = 'Close',\n}: RuiDialogCloseProps) {\n\treturn (\n\t\t<button\n\t\t\tslot={slot}\n\t\t\ttype=\"button\"\n\t\t\tdata-dialog-close\n\t\t\tdata-ref=\"close\"\n\t\t\tclass={cx('rui-dialog__close', className)}\n\t\t\taria-label={ariaLabel}\n\t\t>\n\t\t\t{children ?? '\u00D7'}\n\t\t</button>\n\t);\n}\n\nexport type RuiDialogViewProps = RuiDialogProps &\n\tRadiantSlotProps & {\n\t\tid?: string;\n\t\ttitle?: JsxRenderable;\n\t\tactions?: JsxRenderable;\n\t\tchildren?: JsxRenderable;\n\t};\n\nexport const RuiDialog = defineRadiantView(\n\tRuiDialogElement,\n\t({ slot, open, alert, label, id, title, actions, children }: RuiDialogViewProps) => {\n\t\tif (title != null || actions != null) {\n\t\t\treturn (\n\t\t\t\t<rui-dialog slot={slot} id={id} open={open} alert={alert} label={label}>\n\t\t\t\t\t<RuiDialogClose />\n\t\t\t\t\t{title != null ? <RuiDialogTitle>{title}</RuiDialogTitle> : null}\n\t\t\t\t\t{children != null ? <RuiDialogBody>{children}</RuiDialogBody> : null}\n\t\t\t\t\t{actions != null ? <RuiDialogActions>{actions}</RuiDialogActions> : null}\n\t\t\t\t</rui-dialog>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<rui-dialog slot={slot} id={id} open={open} alert={alert} label={label}>\n\t\t\t\t{children}\n\t\t\t</rui-dialog>\n\t\t);\n\t},\n);\n", "/** Reserved id for the registry-owned imperative host dialog. */\nexport const RUI_DIALOG_HOST_ID = '__rui-dialog-host';\n\nexport const RUI_DIALOG_OPEN_EVENT = 'rui-dialog-open';\nexport const RUI_DIALOG_CLOSE_EVENT = 'rui-dialog-close';\nexport const RUI_DIALOG_TOGGLE_EVENT = 'rui-dialog-toggle';\nexport const RUI_DIALOG_ACTION_EVENT = 'rui-dialog-action';\n\nexport type DialogActionVariant = 'primary' | 'ghost' | 'error' | 'outline' | 'filled';\nexport type DialogActionSize = 'sm' | 'md' | 'lg';\n\nexport type DialogAction = {\n\tlabel: string;\n\tvariant?: DialogActionVariant;\n\tsize?: DialogActionSize;\n\t/** Emitted on `rui-dialog-action` as `detail.value`. */\n\tvalue?: string;\n\t/** Default `true` \u2014 dismiss after click. */\n\tcloseOnClick?: boolean;\n};\n\n/** Content for the registry-owned imperative host dialog (no `id`). */\nexport type DialogHostContent = {\n\ttitle?: string;\n\t/** Body copy (plain text). */\n\tbody?: string;\n\talert?: boolean;\n\t/** Accessible name when there is no title. */\n\tlabel?: string;\n\tactions?: DialogAction[];\n};\n\n/** Open a named dialog by id, or fill the imperative host \u2014 never both. */\nexport type DialogOpenOptions = { id: string } | DialogHostContent;\n\nexport type DialogOpenDetail = DialogOpenOptions | string;\nexport type DialogCloseDetail = { id?: string };\nexport type DialogToggleDetail = { id: string };\nexport type DialogActionDetail = { value?: string };\n\nexport type DialogHandle = {\n\topen: {\n\t\t(): void;\n\t\t(id: string): void;\n\t\t(options: DialogHostContent): void;\n\t};\n\t/** Omit `id` to close the currently open dialog. */\n\tclose: (id?: string) => void;\n\ttoggle: (id?: string) => void;\n\treadonly openId: string | null;\n};\n\nexport function isNamedDialogOpen(detail: DialogOpenOptions): detail is { id: string } {\n\treturn 'id' in detail && detail.id != null && detail.id !== '';\n}\n", "import type { RuiDialog } from './dialog.script';\nimport './dialog.script';\nimport {\n\tRUI_DIALOG_ACTION_EVENT,\n\tRUI_DIALOG_CLOSE_EVENT,\n\tRUI_DIALOG_HOST_ID,\n\tRUI_DIALOG_OPEN_EVENT,\n\tRUI_DIALOG_TOGGLE_EVENT,\n\ttype DialogAction,\n\ttype DialogActionDetail,\n\ttype DialogCloseDetail,\n\ttype DialogHandle,\n\ttype DialogHostContent,\n\ttype DialogOpenOptions,\n\ttype DialogToggleDetail,\n\tisNamedDialogOpen,\n} from './dialog-types';\n\nexport type InstallDialogsOptions = {\n\t/** Parent node for the imperative host mount. Default: `document.body`. */\n\tmount?: ParentNode;\n};\n\nlet installed = false;\nlet mountParent: ParentNode | null = null;\nlet hostDialog: RuiDialog | null = null;\nlet openId: string | null = null;\n\nfunction resolveDialog(id: string): RuiDialog | null {\n\tconst trimmed = id.trim();\n\tif (!trimmed) {\n\t\treturn null;\n\t}\n\n\tconst byId = document.getElementById(trimmed);\n\tif (byId?.localName === 'rui-dialog') {\n\t\treturn byId as RuiDialog;\n\t}\n\n\treturn null;\n}\n\nfunction createCloseButton(): HTMLButtonElement {\n\tconst close = document.createElement('button');\n\tclose.slot = 'close';\n\tclose.type = 'button';\n\tclose.setAttribute('data-dialog-close', '');\n\tclose.setAttribute('data-ref', 'close');\n\tclose.className = 'rui-dialog__close';\n\tclose.setAttribute('aria-label', 'Close');\n\tclose.textContent = '\u00D7';\n\treturn close;\n}\n\nfunction createTitle(title: string): HTMLElement {\n\tconst el = document.createElement('div');\n\tel.slot = 'title';\n\tel.setAttribute('data-dialog-title', '');\n\tel.setAttribute('data-ref', 'title');\n\tel.className = 'rui-dialog__title';\n\tel.textContent = title;\n\treturn el;\n}\n\nfunction createBody(body: string): HTMLElement {\n\tconst el = document.createElement('div');\n\tel.setAttribute('data-dialog-body', '');\n\tel.setAttribute('data-ref', 'description');\n\tel.className = 'rui-dialog__body';\n\tconst paragraph = document.createElement('p');\n\tparagraph.textContent = body;\n\tel.append(paragraph);\n\treturn el;\n}\n\nfunction createActions(actions: DialogAction[]): HTMLElement {\n\tconst row = document.createElement('div');\n\trow.slot = 'actions';\n\trow.className = 'rui-dialog__actions';\n\n\tfor (const action of actions) {\n\t\tconst button = document.createElement('button');\n\t\tbutton.type = 'button';\n\t\tbutton.className = `rui-button rui-button--${action.variant ?? 'filled'} rui-button--${action.size ?? 'md'}`;\n\t\tbutton.setAttribute('data-dialog-action', action.value ?? '');\n\t\tif (action.closeOnClick === false) {\n\t\t\tbutton.setAttribute('data-dialog-action-close', 'false');\n\t\t}\n\t\tbutton.textContent = action.label;\n\t\trow.append(button);\n\t}\n\n\treturn row;\n}\n\nfunction destroyHostDialog(): void {\n\thostDialog?.remove();\n\thostDialog = null;\n}\n\nfunction mountHostDialog(options: DialogHostContent): RuiDialog {\n\tdestroyHostDialog();\n\n\tconst dialog = document.createElement('rui-dialog') as RuiDialog;\n\tdialog.id = RUI_DIALOG_HOST_ID;\n\tdialog.alert = Boolean(options.alert);\n\tdialog.label = options.label ?? '';\n\n\tdialog.append(createCloseButton());\n\tif (options.title) {\n\t\tdialog.append(createTitle(options.title));\n\t}\n\tif (options.body) {\n\t\tdialog.append(createBody(options.body));\n\t}\n\tif (options.actions?.length) {\n\t\tdialog.append(createActions(options.actions));\n\t}\n\n\t(mountParent ?? document.body).appendChild(dialog);\n\thostDialog = dialog;\n\treturn dialog;\n}\n\nfunction closeCurrentExcept(nextId: string): void {\n\tif (!openId || openId === nextId) {\n\t\treturn;\n\t}\n\n\tif (openId === RUI_DIALOG_HOST_ID) {\n\t\tdestroyHostDialog();\n\t} else {\n\t\tconst dialog = resolveDialog(openId);\n\t\tif (dialog) {\n\t\t\tdialog.open = false;\n\t\t}\n\t}\n}\n\nfunction openNamed(id: string): void {\n\tensureInstalled();\n\tconst dialog = resolveDialog(id);\n\tif (!dialog) {\n\t\treturn;\n\t}\n\n\tcloseCurrentExcept(id);\n\tdialog.open = true;\n\topenId = id;\n}\n\nfunction openHost(options: DialogHostContent): void {\n\tensureInstalled();\n\tcloseCurrentExcept(RUI_DIALOG_HOST_ID);\n\tconst dialog = mountHostDialog(options);\n\tdialog.open = true;\n\topenId = RUI_DIALOG_HOST_ID;\n}\n\n/**\n * Resolve open intent: string/`id` opens a named dialog; otherwise fill the host.\n * Named dialogs own their markup \u2014 when `id` is set, host content fields are ignored.\n */\nfunction open(idOrOptions: string | DialogOpenOptions): void {\n\tif (typeof idOrOptions === 'string') {\n\t\topenNamed(idOrOptions);\n\t\treturn;\n\t}\n\n\tif (isNamedDialogOpen(idOrOptions)) {\n\t\topenNamed(idOrOptions.id);\n\t\treturn;\n\t}\n\n\topenHost(idOrOptions);\n}\n\nfunction close(id?: string): void {\n\tensureInstalled();\n\tconst targetId = id ?? openId;\n\tif (!targetId) {\n\t\treturn;\n\t}\n\n\tif (targetId === RUI_DIALOG_HOST_ID) {\n\t\tdestroyHostDialog();\n\t} else {\n\t\tconst dialog = resolveDialog(targetId);\n\t\tif (dialog) {\n\t\t\tdialog.open = false;\n\t\t}\n\t}\n\n\tif (openId === targetId) {\n\t\topenId = null;\n\t}\n}\n\nfunction toggle(id: string): void {\n\tensureInstalled();\n\tif (openId === id) {\n\t\tclose(id);\n\t\treturn;\n\t}\n\topenNamed(id);\n}\n\nfunction onOpenEvent(event: Event): void {\n\tconst detail = (event as CustomEvent<DialogOpenOptions | string>).detail;\n\tif (typeof detail === 'string') {\n\t\topen(detail);\n\t\treturn;\n\t}\n\tif (detail && typeof detail === 'object') {\n\t\topen(detail);\n\t}\n}\n\nfunction onCloseEvent(event: Event): void {\n\tconst detail = (event as CustomEvent<DialogCloseDetail>).detail;\n\tclose(detail?.id);\n}\n\nfunction onToggleEvent(event: Event): void {\n\tconst detail = (event as CustomEvent<DialogToggleDetail>).detail;\n\tif (detail?.id) {\n\t\ttoggle(detail.id);\n\t}\n}\n\nfunction onDocumentClick(event: Event): void {\n\tconst target = event.target as Element | null;\n\tif (!target?.closest) {\n\t\treturn;\n\t}\n\n\tconst action = target.closest('[data-dialog-action]') as HTMLElement | null;\n\tif (action && hostDialog?.contains(action)) {\n\t\tevent.preventDefault();\n\t\tconst value = action.getAttribute('data-dialog-action') || undefined;\n\t\tconst detail: DialogActionDetail = { value: value || undefined };\n\t\thostDialog.dispatchEvent(\n\t\t\tnew CustomEvent(RUI_DIALOG_ACTION_EVENT, {\n\t\t\t\tdetail,\n\t\t\t\tbubbles: true,\n\t\t\t\tcomposed: true,\n\t\t\t}),\n\t\t);\n\t\tif (action.getAttribute('data-dialog-action-close') !== 'false') {\n\t\t\tclose(RUI_DIALOG_HOST_ID);\n\t\t}\n\t\treturn;\n\t}\n\n\tconst openTrigger = target.closest('[data-dialog-open]');\n\tif (openTrigger) {\n\t\tconst id = openTrigger.getAttribute('data-dialog-open')?.trim();\n\t\tif (id) {\n\t\t\tevent.preventDefault();\n\t\t\topenNamed(id);\n\t\t}\n\t\treturn;\n\t}\n\n\tconst closeTrigger = target.closest('[data-dialog-close]');\n\tif (closeTrigger) {\n\t\tconst insideDialog = closeTrigger.closest('rui-dialog');\n\t\tif (insideDialog?.hasAttribute('open')) {\n\t\t\treturn;\n\t\t}\n\t\tevent.preventDefault();\n\t\tclose();\n\t}\n}\n\nfunction onRuiClose(event: Event): void {\n\tconst dialog = (event.target as Element | null)?.closest?.('rui-dialog');\n\tif (!dialog) {\n\t\treturn;\n\t}\n\n\tconst id = dialog.id || null;\n\tif (id && openId === id) {\n\t\tif (id === RUI_DIALOG_HOST_ID) {\n\t\t\tdestroyHostDialog();\n\t\t}\n\t\topenId = null;\n\t}\n}\n\n/**\n * Install document listeners for dialog events and `data-dialog-*` attributes.\n * Idempotent \u2014 safe to call from app boot and Storybook decorators.\n * Returns an uninstall function for tests / HMR.\n */\nexport function installDialogs(options: InstallDialogsOptions = {}): () => void {\n\tif (installed) {\n\t\tif (options.mount) {\n\t\t\tmountParent = options.mount;\n\t\t}\n\t\treturn uninstallDialogs;\n\t}\n\n\tinstalled = true;\n\tmountParent = options.mount ?? document.body;\n\n\tdocument.addEventListener(RUI_DIALOG_OPEN_EVENT, onOpenEvent);\n\tdocument.addEventListener(RUI_DIALOG_CLOSE_EVENT, onCloseEvent);\n\tdocument.addEventListener(RUI_DIALOG_TOGGLE_EVENT, onToggleEvent);\n\tdocument.addEventListener('click', onDocumentClick);\n\tdocument.addEventListener('rui-close', onRuiClose);\n\n\treturn uninstallDialogs;\n}\n\nfunction ensureInstalled(): void {\n\tif (!installed) {\n\t\tinstallDialogs();\n\t}\n}\n\n/** Tear down listeners and the host dialog (mainly for tests). */\nexport function uninstallDialogs(): void {\n\tif (!installed) {\n\t\treturn;\n\t}\n\n\tdocument.removeEventListener(RUI_DIALOG_OPEN_EVENT, onOpenEvent);\n\tdocument.removeEventListener(RUI_DIALOG_CLOSE_EVENT, onCloseEvent);\n\tdocument.removeEventListener(RUI_DIALOG_TOGGLE_EVENT, onToggleEvent);\n\tdocument.removeEventListener('click', onDocumentClick);\n\tdocument.removeEventListener('rui-close', onRuiClose);\n\n\tdestroyHostDialog();\n\tmountParent = null;\n\topenId = null;\n\tinstalled = false;\n}\n\n/** Currently open dialog id, or `null`. */\nexport function getOpenDialogId(): string | null {\n\treturn openId;\n}\n\n/** Open a named dialog by id, or fill/open the imperative host dialog. */\nexport function openDialog(idOrOptions: string | DialogOpenOptions): void {\n\tensureInstalled();\n\topen(idOrOptions);\n}\n\n/** Close the current dialog, or a specific id. */\nexport function closeDialog(id?: string): void {\n\tensureInstalled();\n\tclose(id);\n}\n\n/** Toggle a named dialog by id. */\nexport function toggleDialog(id: string): void {\n\tensureInstalled();\n\ttoggle(id);\n}\n\n/**\n * Bound handle for a named dialog id, or the imperative host when `id` is omitted.\n * A bound handle's `open()` always targets that id; pass options only on unbound handles.\n *\n * @example\n * const confirm = createDialogHandle();\n * confirm.open({ title: 'Delete?', body: '\u2026', actions: [\u2026] });\n *\n * const profile = createDialogHandle('edit-profile');\n * profile.open();\n */\nexport function createDialogHandle(id?: string): DialogHandle {\n\tensureInstalled();\n\n\tconst boundId = id?.trim() || undefined;\n\n\tconst handleOpen = ((idOrOptions?: string | DialogHostContent) => {\n\t\tif (boundId) {\n\t\t\topenNamed(boundId);\n\t\t\treturn;\n\t\t}\n\n\t\tif (idOrOptions == null) {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof idOrOptions === 'string') {\n\t\t\topenNamed(idOrOptions);\n\t\t\treturn;\n\t\t}\n\t\topen(idOrOptions);\n\t}) as DialogHandle['open'];\n\n\treturn {\n\t\topen: handleOpen,\n\t\tclose: (closeId) => {\n\t\t\tclose(closeId ?? boundId);\n\t\t},\n\t\ttoggle: (toggleId) => {\n\t\t\tconst target = toggleId ?? boundId;\n\t\t\tif (target) {\n\t\t\t\ttoggle(target);\n\t\t\t}\n\t\t},\n\t\tget openId() {\n\t\t\treturn openId;\n\t\t},\n\t};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RadiantElement", "bound", "customElement", "event", "onEvent", "onUpdated", "prop", "query", "FOCUSABLE", "RuiDialog", "open", "alert", "el", "reason", "focusable", "first", "last", "active", "RADIANT_VIEW_ELEMENT", "RADIANT_SCRIPT_MODULE", "RADIANT_SCRIPT_EXPORT", "linkViewToElement", "view", "element", "ssrModule", "defineRadiantView", "render", "args", "cx", "parts", "RuiDialogTitle", "slot", "children", "className", "RuiDialogBody", "RuiDialogActions", "RuiDialogClose", "ariaLabel", "RuiDialog", "defineRadiantView", "open", "alert", "label", "id", "title", "actions", "RUI_DIALOG_HOST_ID", "RUI_DIALOG_OPEN_EVENT", "RUI_DIALOG_CLOSE_EVENT", "RUI_DIALOG_TOGGLE_EVENT", "RUI_DIALOG_ACTION_EVENT", "isNamedDialogOpen", "detail", "installed", "mountParent", "hostDialog", "openId", "resolveDialog", "id", "trimmed", "byId", "createCloseButton", "close", "createTitle", "title", "el", "createBody", "body", "paragraph", "createActions", "actions", "row", "action", "button", "destroyHostDialog", "mountHostDialog", "options", "dialog", "RUI_DIALOG_HOST_ID", "closeCurrentExcept", "nextId", "openNamed", "ensureInstalled", "openHost", "open", "idOrOptions", "isNamedDialogOpen", "targetId", "toggle", "onOpenEvent", "event", "detail", "onCloseEvent", "onToggleEvent", "onDocumentClick", "target", "RUI_DIALOG_ACTION_EVENT", "openTrigger", "closeTrigger", "onRuiClose", "installDialogs", "uninstallDialogs", "RUI_DIALOG_OPEN_EVENT", "RUI_DIALOG_CLOSE_EVENT", "RUI_DIALOG_TOGGLE_EVENT", "getOpenDialogId", "openDialog", "closeDialog", "toggleDialog", "createDialogHandle", "boundId", "closeId", "toggleId"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RadiantElement } from '@ecopages/radiant';
|
|
2
|
+
export type RuiDisclosureGroupProps = {
|
|
3
|
+
/** Allow more than one disclosure to stay open. Default: `false` (exclusive). */
|
|
4
|
+
multiple?: boolean;
|
|
5
|
+
/** Animate panel height for child disclosures. Default: `false`. */
|
|
6
|
+
animated?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* `<rui-disclosure-group>` — coordinates stacked disclosures (accordion-style).
|
|
10
|
+
*
|
|
11
|
+
* When `multiple` is `false` (default), opening one disclosure closes the others.
|
|
12
|
+
* Supports APG accordion keyboard navigation between triggers (ArrowUp/Down, Home/End)
|
|
13
|
+
* and optional ArrowLeft/Right to collapse/expand the focused section.
|
|
14
|
+
*
|
|
15
|
+
* @see https://www.w3.org/WAI/ARIA/apg/patterns/accordion/
|
|
16
|
+
* @element rui-disclosure-group
|
|
17
|
+
* @slot - `rui-disclosure` children.
|
|
18
|
+
*/
|
|
19
|
+
export declare class RuiDisclosureGroup extends RadiantElement {
|
|
20
|
+
multiple: boolean;
|
|
21
|
+
animated: boolean;
|
|
22
|
+
connectedCallback(): void;
|
|
23
|
+
private getTriggers;
|
|
24
|
+
private getDisclosureForTrigger;
|
|
25
|
+
private syncTriggers;
|
|
26
|
+
private syncChildrenAnimated;
|
|
27
|
+
onAnimatedUpdated(): void;
|
|
28
|
+
onDisclosureToggle(event: Event): void;
|
|
29
|
+
onTriggerKeydown(event: KeyboardEvent): void;
|
|
30
|
+
render(): import("@ecopages/jsx").JsxRenderable;
|
|
31
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
@reference '../../../styles/radiant-ui.css';
|
|
2
|
+
|
|
3
|
+
rui-disclosure {
|
|
4
|
+
@apply block w-full;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@layer components {
|
|
8
|
+
.rui-disclosure__trigger {
|
|
9
|
+
@apply inline-flex w-full items-center gap-3 rounded-container border-0 bg-transparent px-control-x py-3;
|
|
10
|
+
@apply cursor-pointer text-left text-sm font-medium text-on-background;
|
|
11
|
+
@apply transition-colors duration-fast;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.rui-disclosure__trigger--icon-end {
|
|
15
|
+
@apply justify-between;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.rui-disclosure__trigger:hover {
|
|
19
|
+
@apply bg-surface;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.rui-disclosure__trigger:focus-visible {
|
|
23
|
+
@apply bg-surface ring-2 ring-focus-ring ring-inset outline-hidden;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.rui-disclosure__icon {
|
|
27
|
+
@apply inline-flex shrink-0 items-center justify-center text-on-surface;
|
|
28
|
+
pointer-events: none;
|
|
29
|
+
transition:
|
|
30
|
+
transform 150ms ease,
|
|
31
|
+
color 150ms ease;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.rui-disclosure__icon--chevron {
|
|
35
|
+
width: 0;
|
|
36
|
+
height: 0;
|
|
37
|
+
border-top: 4px solid transparent;
|
|
38
|
+
border-bottom: 4px solid transparent;
|
|
39
|
+
border-left: 6px solid currentColor;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.rui-disclosure__trigger[aria-expanded='true'] .rui-disclosure__icon--chevron {
|
|
43
|
+
transform: rotate(90deg);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.rui-disclosure__icon--plus {
|
|
47
|
+
@apply size-5 text-lg leading-none;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.rui-disclosure__icon--plus::before {
|
|
51
|
+
content: '+';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.rui-disclosure__trigger[aria-expanded='true'] .rui-disclosure__icon--plus::before {
|
|
55
|
+
content: '×';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.rui-disclosure__label {
|
|
59
|
+
@apply min-w-0 flex-1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.rui-disclosure__panel {
|
|
63
|
+
@apply text-sm leading-relaxed text-on-surface;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.rui-disclosure__panel-inner {
|
|
67
|
+
@apply p-inset;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.rui-disclosure__panel[hidden] {
|
|
71
|
+
display: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.rui-disclosure__panel:not([hidden]) {
|
|
75
|
+
display: block;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
rui-disclosure[data-animated] .rui-disclosure__panel {
|
|
79
|
+
display: grid;
|
|
80
|
+
grid-template-rows: 0fr;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
transition: grid-template-rows 200ms ease;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
rui-disclosure[data-animated] .rui-disclosure__panel[data-state='open'] {
|
|
86
|
+
grid-template-rows: 1fr;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
rui-disclosure[data-animated] .rui-disclosure__panel-inner {
|
|
90
|
+
min-height: 0;
|
|
91
|
+
overflow: hidden;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
rui-disclosure[data-animated] .rui-disclosure__panel[aria-hidden='true'] .rui-disclosure__panel-inner {
|
|
95
|
+
visibility: hidden;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.rui-disclosure__panel-inner > :first-child {
|
|
99
|
+
@apply mt-0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.rui-disclosure__panel-inner > :last-child {
|
|
103
|
+
@apply mb-0;
|
|
104
|
+
}
|
|
105
|
+
}
|