@designbasekorea/ui-wc 0.9.3 → 0.10.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/CHANGELOG.md +17 -0
- package/README.md +2 -0
- package/dist/esm/components/date-picker-utils.js +1 -1
- package/dist/esm/components/db-accordion.d.ts +22 -10
- package/dist/esm/components/db-accordion.js +1 -1
- package/dist/esm/components/db-activity-heatmap.js +1 -1
- package/dist/esm/components/db-ai-file-tree.js +1 -1
- package/dist/esm/components/db-avatar.js +1 -1
- package/dist/esm/components/db-button.d.ts +33 -1
- package/dist/esm/components/db-button.js +1 -1
- package/dist/esm/components/db-calendar.d.ts +2 -1
- package/dist/esm/components/db-calendar.js +1 -1
- package/dist/esm/components/db-carousel.d.ts +2 -0
- package/dist/esm/components/db-carousel.js +1 -1
- package/dist/esm/components/db-chat-orb.d.ts +13 -0
- package/dist/esm/components/db-chat-orb.js +1 -1
- package/dist/esm/components/db-chat-room.js +1 -1
- package/dist/esm/components/db-chat-widget.js +1 -1
- package/dist/esm/components/db-checkbox.d.ts +18 -1
- package/dist/esm/components/db-checkbox.js +1 -1
- package/dist/esm/components/db-confetti.d.ts +11 -5
- package/dist/esm/components/db-confetti.js +1 -1
- package/dist/esm/components/db-confirm.d.ts +2 -0
- package/dist/esm/components/db-confirm.js +1 -1
- package/dist/esm/components/db-credit-card.d.ts +3 -4
- package/dist/esm/components/db-credit-card.js +1 -1
- package/dist/esm/components/db-date-picker.d.ts +2 -1
- package/dist/esm/components/db-date-picker.js +1 -1
- package/dist/esm/components/db-design-toolbar.js +1 -1
- package/dist/esm/components/db-device-mockup.js +1 -1
- package/dist/esm/components/db-email-verify.d.ts +36 -7
- package/dist/esm/components/db-email-verify.js +1 -1
- package/dist/esm/components/db-flight-status.d.ts +2 -2
- package/dist/esm/components/db-flight-status.js +1 -1
- package/dist/esm/components/db-floating-action-button.d.ts +1 -1
- package/dist/esm/components/db-floating-action-button.js +1 -1
- package/dist/esm/components/db-gantt.js +1 -1
- package/dist/esm/components/db-indicator.d.ts +1 -0
- package/dist/esm/components/db-indicator.js +1 -1
- package/dist/esm/components/db-input.d.ts +8 -1
- package/dist/esm/components/db-input.js +1 -1
- package/dist/esm/components/db-kanban.js +1 -1
- package/dist/esm/components/db-navbar.d.ts +3 -0
- package/dist/esm/components/db-navbar.js +1 -1
- package/dist/esm/components/db-node.d.ts +1 -3
- package/dist/esm/components/db-node.js +1 -1
- package/dist/esm/components/db-otp-input.js +1 -1
- package/dist/esm/components/db-page-header.d.ts +11 -0
- package/dist/esm/components/db-page-header.js +1 -1
- package/dist/esm/components/db-phone-verify.d.ts +33 -11
- package/dist/esm/components/db-phone-verify.js +1 -1
- package/dist/esm/components/db-radio.d.ts +22 -1
- package/dist/esm/components/db-radio.js +1 -1
- package/dist/esm/components/db-range-slider.d.ts +35 -7
- package/dist/esm/components/db-range-slider.js +1 -1
- package/dist/esm/components/db-receipt.js +1 -1
- package/dist/esm/components/db-select.d.ts +35 -6
- package/dist/esm/components/db-select.js +1 -1
- package/dist/esm/components/db-tabs.d.ts +36 -13
- package/dist/esm/components/db-tabs.js +1 -1
- package/dist/esm/components/db-textarea.d.ts +13 -1
- package/dist/esm/components/db-textarea.js +1 -1
- package/dist/esm/components/db-toggle.d.ts +33 -4
- package/dist/esm/components/db-toggle.js +1 -1
- package/dist/esm/components/db-tool-button.js +1 -1
- package/dist/esm/components/db-two-factor.d.ts +35 -12
- package/dist/esm/components/db-two-factor.js +1 -1
- package/dist/esm/components/db-voice-control.js +1 -1
- package/dist/esm/core/ai-element.d.ts +2 -1
- package/dist/esm/core/ai-element.js +1 -1
- package/dist/esm/core/control-label.js +1 -0
- package/dist/esm/core/i18n-copy.js +1 -1
- package/dist/esm/core/i18n-en.js +1 -1
- package/dist/esm/core/i18n.d.ts +4 -0
- package/dist/esm/core/i18n.js +1 -1
- package/dist/esm/core/range-values.js +1 -0
- package/dist/esm/core/text-field-state.js +1 -0
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
- package/dist/esm/ui-contracts/dist/components.d.d.ts +9 -2
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +420 -90
- package/dist/index.esm.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +5455 -636
- package/dist/react/index.esm.js +1 -1
- package/package.json +7 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
import{setHostClasses as e}from"../core/host-class.js";import{labelFrom as t,t as s,dbFormat as i}from"../core/i18n.js";import{getDbComponentIconSize as r,createDbIcon as a}from"./db-icons.js";import"./db-checkbox.js";import{dbUid as n}from"../core/uid.js";import{SELECT_SIZES as l,SELECT_POSITIONS as h}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as c}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";class DbSelect extends HTMLElement{constructor(){super(...arguments),this.internals=this.attachInternals(),this.built=!1,this.searchTerm="",this.focusedIndex=-1,this.handleTriggerClick=()=>{this.hasAttribute("disabled")||this.hasAttribute("readonly")||(this.open=!this.open,this.open&&this.searchable&&setTimeout(()=>this.searchInput?.focus(),0))},this.handleTriggerFocus=()=>{this.trigger?.classList.add("designbase-wc-select__trigger--focused")},this.handleTriggerBlur=()=>{this.trigger?.classList.remove("designbase-wc-select__trigger--focused")},this.handleClear=e=>{e.stopPropagation();const t=[];this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t)},this.handleSearchInput=()=>{this.searchTerm=this.searchInput?.value||"",this.focusedIndex=-1,this.syncOptions()},this.handleDocumentMouseDown=e=>{this.contains(e.target)||(this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1,this.syncOptions())},this.handleDocumentKeyDown=e=>{if(!this.contains(document.activeElement))return;if(!this.open)return void("Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.open=!0));const t=this.getFilteredOptions();switch(e.key){case"Escape":e.preventDefault(),this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1,this.syncOptions();break;case"ArrowDown":e.preventDefault(),this.focusedIndex=Math.min(this.focusedIndex+1,t.length-1),this.syncOptions();break;case"ArrowUp":e.preventDefault(),this.focusedIndex=Math.max(this.focusedIndex-1,0),this.syncOptions();break;case"Enter":e.preventDefault(),this.focusedIndex>=0&&t[this.focusedIndex]&&this.selectOption(t[this.focusedIndex])}}}static get observedAttributes(){return["options","value","placeholder","label","size","full-width","disabled","readonly","required","error","error-message","helper-text","multiple","searchable","show-clear-button","open","max-height","position","dropdown-width","name"]}get name(){return this.getAttribute("name")??""}set name(e){this.setAttribute("name",e)}get open(){return this.hasAttribute("open")}set open(e){this.toggleAttribute("open",e),this.syncOpenState()}get value(){return this.getAttribute("value")||""}set value(e){e?this.setAttribute("value",e):this.removeAttribute("value"),this.syncTrigger(),this.syncOptions(),this.syncFormValue()}connectedCallback(){this.built||this.build(),this.syncState(),queueMicrotask(()=>{this.isConnected&&this.syncFormValue()}),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}formAssociatedCallback(){this.syncFormValue()}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown)}formResetCallback(){this.removeAttribute("value"),this.internals.setFormValue(null),this.built&&(this.syncTrigger(),this.syncOptions(),this.syncFormValue())}formDisabledCallback(e){this.toggleAttribute("disabled",e)}attributeChangedCallback(e){if(this.built){if("open"!==e)return"value"===e?(this.syncTrigger(),this.syncOptions(),void this.syncFormValue()):void this.syncState();this.syncOpenState()}}get multiple(){return this.hasAttribute("multiple")}set multiple(e){this.toggleAttribute("multiple",Boolean(e))}get searchable(){return this.hasAttribute("searchable")}set searchable(e){this.toggleAttribute("searchable",Boolean(e))}get showClearButton(){return!this.hasAttribute("show-clear-button")||"false"!==this.getAttribute("show-clear-button")}parseOptions(){const e=this.getAttribute("options")||"[]";try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return e.split(",").map(e=>e.trim()).filter(Boolean).map(e=>({value:e,label:e}))}}parseSelectedValues(){const e=this.getAttribute("value")||"";if(!e)return[];if(this.multiple)try{const t=JSON.parse(e);return Array.isArray(t)?t.map(String):[]}catch{return e.split(",").map(e=>e.trim()).filter(Boolean)}return e?[e]:[]}setSelectedValues(e){this.multiple?e.length?this.setAttribute("value",JSON.stringify(e)):this.removeAttribute("value"):e[0]?this.setAttribute("value",e[0]):this.removeAttribute("value")}syncFormValue(){const e=this.parseSelectedValues();if(this.multiple){const t=new FormData;return e.forEach(e=>t.append(this.name||"select",e)),void this.internals.setFormValue(e.length?t:null)}this.internals.setFormValue(e[0]||null)}getIconSize(){const e=this.getAttribute("size")||"m";return r(l.includes(e)?e:"m")}syncIndicatorIcons(){const e=this.getIconSize();this.clearButton?.replaceChildren(a("close",e)),this.chevronEl&&this.chevronEl.replaceChildren(a(this.open?"chevron-up":"chevron-down",e))}build(){const e=this.getAttribute("id")||n("db-select"),s=`${e}-listbox`;this.hasAttribute("id")||this.setAttribute("id",e),this.labelEl=document.createElement("label"),this.labelEl.className="designbase-wc-select__label",this.trigger=document.createElement("div"),this.trigger.className="designbase-wc-select__trigger",this.trigger.tabIndex=0,this.trigger.setAttribute("role","combobox"),this.trigger.setAttribute("aria-haspopup","listbox"),this.trigger.setAttribute("aria-controls",s),this.trigger.addEventListener("click",this.handleTriggerClick),this.trigger.addEventListener("focus",this.handleTriggerFocus),this.trigger.addEventListener("blur",this.handleTriggerBlur),this.valueEl=document.createElement("div"),this.valueEl.className="designbase-wc-select__value",this.indicatorsEl=document.createElement("div"),this.indicatorsEl.className="designbase-wc-select__indicators",this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="designbase-wc-select__clear-button",this.clearButton.setAttribute("aria-label",t(this,"label-clear","clearAll")),this.clearButton.hidden=!0,this.clearButton.appendChild(a("close",this.getIconSize())),this.clearButton.addEventListener("click",this.handleClear),this.chevronEl=document.createElement("div"),this.chevronEl.className="designbase-wc-select__chevron",this.indicatorsEl.append(this.clearButton,this.chevronEl),this.trigger.append(this.valueEl,this.indicatorsEl),this.dropdown=document.createElement("div"),this.dropdown.className="designbase-wc-select__dropdown",this.searchWrap=document.createElement("div"),this.searchWrap.className="designbase-wc-select__search",this.searchWrap.hidden=!0,this.searchInput=document.createElement("input"),this.searchInput.type="text",this.searchInput.className="designbase-wc-select__search-input",this.searchInput.placeholder=t(this,"label-search","search.label"),this.searchInput.addEventListener("input",this.handleSearchInput),this.searchInput.addEventListener("mousedown",e=>e.stopPropagation()),this.searchInput.addEventListener("click",e=>e.stopPropagation()),this.searchWrap.appendChild(this.searchInput),this.optionsEl=document.createElement("div"),this.optionsEl.className="designbase-wc-select__options",this.optionsEl.id=s,this.optionsEl.setAttribute("role","listbox"),this.dropdown.append(this.searchWrap,this.optionsEl),this.helperEl=document.createElement("p"),this.helperEl.className="designbase-wc-select__helper-text",this.errorEl=document.createElement("p"),this.errorEl.className="designbase-wc-select__error-message",this.append(this.labelEl,this.trigger,this.dropdown,this.helperEl,this.errorEl),this.built=!0}getFilteredOptions(){const e=this.parseOptions();if(!this.searchable||!this.searchTerm)return e;const t=this.searchTerm.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(t))}selectOption(e){if(e.disabled)return;const t=this.parseSelectedValues();let s;this.multiple?s=t.includes(e.value)?t.filter(t=>t!==e.value):[...t,e.value]:(s=[e.value],this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1),this.setSelectedValues(s),this.syncTrigger(),this.syncOptions(),this.dispatchChange(s)}dispatchChange(e){const t=this.parseOptions();if(this.multiple)return this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),void this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,labels:e.map(e=>t.find(t=>t.value===e)?.label||e)},bubbles:!0,composed:!0}));const s=e[0]||"",i=t.find(e=>e.value===s)?.label||"";this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:s,label:i},bubbles:!0,composed:!0}))}syncAccessibleName(e){if(!this.trigger)return;if(e&&this.labelEl)return this.labelEl.id||(this.labelEl.id=n("db-select-label")),this.trigger.setAttribute("aria-labelledby",this.labelEl.id),void this.trigger.removeAttribute("aria-label");this.trigger.removeAttribute("aria-labelledby");const t=this.getAttribute("aria-label")||this.getAttribute("placeholder")||s("select.placeholder");this.trigger.setAttribute("aria-label",t)}syncState(){if(!this.trigger||!this.dropdown||!this.optionsEl)return;const t=c(this.getAttribute("size"),l,"m"),s=c(this.getAttribute("position"),h,"bottom"),i="full"===this.getAttribute("dropdown-width")?"full":"auto",r=Number(this.getAttribute("max-height")||200),a=this.getAttribute("label")||"",n=this.getAttribute("helper-text")||"",o=this.getAttribute("error-message")||"",d=this.hasAttribute("error"),u=this.getAttribute("id")||"";e(this,["designbase-wc-select",`designbase-wc-select--${t}`,this.open&&"designbase-wc-select--open",d&&"designbase-wc-select--error",this.hasAttribute("disabled")&&"designbase-wc-select--disabled",this.hasAttribute("readonly")&&"designbase-wc-select--readonly",this.hasAttribute("full-width")&&"designbase-wc-select--full-width",this.multiple&&"designbase-wc-select--multiple",this.searchable&&"designbase-wc-select--searchable"]);const p=this.parseSelectedValues();if(this.classList.toggle("designbase-wc-select--has-value",p.length>0),this.labelEl){const e=this.hasAttribute("required")?'<span class="designbase-wc-select__required" aria-hidden="true">*</span>':"";this.labelEl.innerHTML=a?`${this.escape(a)}${e}`:"",this.labelEl.hidden=!a}this.syncAccessibleName(a),this.dropdown.className=["designbase-wc-select__dropdown",`designbase-wc-select__dropdown--${i}`,`designbase-wc-select__dropdown--${s}`,this.open&&"designbase-wc-select__dropdown--open"].filter(Boolean).join(" "),this.optionsEl.style.maxHeight=`${r}px`,this.searchWrap&&(this.searchWrap.hidden=!this.searchable);const b=`${u}-helper`,g=`${u}-error`;d&&o?(this.errorEl.id=g,this.errorEl.textContent=o,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.trigger.setAttribute("aria-describedby",g),this.trigger.setAttribute("aria-invalid","true")):n?(this.helperEl.id=b,this.helperEl.textContent=n,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.trigger.setAttribute("aria-describedby",b),this.trigger.removeAttribute("aria-invalid")):(this.helperEl.hidden=!0,this.errorEl.hidden=!0,this.trigger.removeAttribute("aria-describedby"),this.trigger.removeAttribute("aria-invalid")),this.hasAttribute("disabled")||this.hasAttribute("readonly")?this.trigger.tabIndex=-1:this.trigger.tabIndex=0,this.syncOpenState(),this.syncTrigger(),this.syncOptions(),this.syncFormValue(),this.syncIndicatorIcons()}syncOpenState(){this.trigger&&this.dropdown&&this.chevronEl&&(this.trigger.setAttribute("aria-expanded",String(this.open)),this.classList.toggle("designbase-wc-select--open",this.open),this.dropdown.classList.toggle("designbase-wc-select__dropdown--open",this.open),this.syncIndicatorIcons())}syncTrigger(){if(!this.valueEl||!this.clearButton)return;const e=this.parseOptions(),t=this.parseSelectedValues(),r=this.getAttribute("placeholder")||s("select.placeholder"),n=t.length>0,l=n&&this.showClearButton&&!this.hasAttribute("disabled")&&!this.hasAttribute("readonly");if(this.valueEl.replaceChildren(),this.multiple)if(0===t.length){const e=document.createElement("span");e.className="designbase-wc-select__placeholder",e.textContent=r,this.valueEl.appendChild(e)}else{const s=document.createElement("div");s.className="designbase-wc-select__tags",t.forEach(r=>{const n=e.find(e=>e.value===r),l=document.createElement("span");l.className="designbase-wc-select__tag";const h=document.createElement("span");h.className="designbase-wc-select__tag-label",h.textContent=n?.label||r;const c=document.createElement("button");c.type="button",c.className="designbase-wc-select__tag-remove",c.setAttribute("aria-label",i("{0} 제거",[n?.label||r])),c.appendChild(a("close",12)),c.addEventListener("click",e=>{e.stopPropagation();const s=t.filter(e=>e!==r);this.setSelectedValues(s),this.syncTrigger(),this.syncOptions(),this.dispatchChange(s)}),l.append(h,c),s.appendChild(l)}),this.valueEl.appendChild(s)}else{const s=document.createElement("span");s.className="designbase-wc-select__single-value";const i=e.find(e=>e.value===t[0]);s.textContent=n?i?.label||t[0]:r,n||s.classList.add("designbase-wc-select__placeholder"),this.valueEl.appendChild(s)}this.clearButton.hidden=!l,this.clearButton.setAttribute("aria-hidden",l?"false":"true"),this.classList.toggle("designbase-wc-select--has-value",n)}syncOptions(){if(!this.optionsEl)return;const e=this.getFilteredOptions(),s=this.parseSelectedValues(),i=this.getAttribute("id")||"db-select";if(this.optionsEl.replaceChildren(),0===e.length){const e=document.createElement("div");return e.className="designbase-wc-select__no-options",e.textContent=this.searchTerm?t(this,"label-no-results","select.noResults"):t(this,"label-empty","select.noResults"),void this.optionsEl.appendChild(e)}e.forEach((e,t)=>{const r=s.includes(e.value),a=t===this.focusedIndex,n=document.createElement("div");if(n.className=["designbase-wc-select__option",r&&"designbase-wc-select__option--selected",a&&"designbase-wc-select__option--focused",e.disabled&&"designbase-wc-select__option--disabled"].filter(Boolean).join(" "),n.id=`${i}-option-${t}`,n.setAttribute("role","option"),n.setAttribute("aria-selected",String(r)),n.setAttribute("aria-disabled",String(Boolean(e.disabled))),n.addEventListener("click",()=>this.selectOption(e)),this.multiple){const t=document.createElement("div");t.className="designbase-wc-select__checkbox";const s=document.createElement("db-checkbox");s.setAttribute("size","s"),s.setAttribute("has-label","false"),r&&s.setAttribute("checked",""),e.disabled&&s.setAttribute("disabled",""),t.appendChild(s),n.appendChild(t)}const l=document.createElement("span");l.className="designbase-wc-select__option-label",l.textContent=e.label,n.appendChild(l),this.optionsEl.appendChild(n)}),this.focusedIndex>=0?this.trigger?.setAttribute("aria-activedescendant",`${i}-option-${this.focusedIndex}`):this.trigger?.removeAttribute("aria-activedescendant")}escape(e){return e.replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[e]||e))}}DbSelect.formAssociated=!0,customElements.get("db-select")||customElements.define("db-select",DbSelect);export{DbSelect};
|
|
1
|
+
import{setHostClasses as e}from"../core/host-class.js";import{t,labelFrom as s,dbFormat as i}from"../core/i18n.js";import{getDbComponentIconSize as a,createDbIcon as r}from"./db-icons.js";import{dbUid as l}from"../core/uid.js";import{SELECT_SIZES as n,SELECT_POSITIONS as h}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as o}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";class DbSelect extends HTMLElement{constructor(){super(...arguments),this.internals=this.attachInternals(),this.built=!1,this.searchTerm="",this.focusedIndex=-1,this.awaitingValue=!0,this.userInteracted=!1,this.formDisabled=!1,this.wasOpen=!1,this.typeahead="",this.typeaheadAt=0,this.handleTriggerClick=()=>{this.locked||(this.open=!this.open)},this.handleTriggerFocus=()=>{this.trigger?.classList.add("designbase-wc-select__trigger--focused")},this.handleTriggerBlur=()=>{this.trigger?.classList.remove("designbase-wc-select__trigger--focused")},this.handleClear=e=>{if(e.stopPropagation(),this.locked)return;this.userInteracted=!0,this.awaitingValue=!1;const t=[];this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t),this.focus()},this.handleSearchInput=()=>{this.searchTerm=this.searchInput?.value||"",this.focusedIndex=-1,this.syncOptions()},this.handleDocumentMouseDown=e=>{!e.composedPath().includes(this)&&this.open&&(this.open=!1)},this.handleFocusOut=()=>{queueMicrotask(()=>{const e=this.getRootNode();this.isConnected&&!this.contains(e.activeElement)&&(this.open=!1)})},this.handleDocumentKeyDown=e=>{if(!(this.locked||e.target!==this.trigger&&e.target!==this.searchInput))if("Tab"!==e.key){if(!this.open&&["Enter"," ","ArrowDown","ArrowUp"].includes(e.key))return e.preventDefault(),this.open=!0,void("ArrowDown"!==e.key&&"ArrowUp"!==e.key||this.moveFocus("ArrowDown"===e.key?"first":"last"));switch(e.key){case"Escape":if(!this.open)return;e.preventDefault(),e.stopPropagation(),this.open=!1,this.focus();break;case"ArrowDown":case"ArrowUp":if(!this.open)return;e.preventDefault(),this.moveFocus("ArrowDown"===e.key?"next":"previous");break;case"Home":case"End":if(e.target===this.searchInput||!this.open)return;e.preventDefault(),this.moveFocus("Home"===e.key?"first":"last");break;case"Enter":case" ":if(!this.open||" "===e.key&&e.target===this.searchInput)return;e.preventDefault();const t=this.getFilteredOptions()[this.focusedIndex];t&&this.selectOption(t);break;default:if(e.target===this.searchInput||1!==e.key.length||e.ctrlKey||e.metaKey||e.altKey)return;const s=performance.now();this.typeahead=s-this.typeaheadAt>700?e.key:this.typeahead+e.key,this.typeaheadAt=s,this.open=!0,this.focusedIndex=this.getFilteredOptions().findIndex(e=>!e.disabled&&e.label.toLocaleLowerCase().startsWith(this.typeahead.toLocaleLowerCase())),this.syncOptions()}}else this.open=!1}}static get observedAttributes(){return["options","value","placeholder","label","size","full-width","disabled","readonly","required","error","error-message","helper-text","multiple","searchable","show-clear-button","open","max-height","position","dropdown-width","name","default-value","aria-label","aria-labelledby","aria-describedby","label-search","label-clear","label-no-results","label-empty"]}get defaultValue(){return this.getAttribute("default-value")??this.initialValue??this.value}set defaultValue(e){this.setAttribute("default-value",Array.isArray(e)?JSON.stringify(e):e)}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",Boolean(e))}get readOnly(){return this.hasAttribute("readonly")}set readOnly(e){this.toggleAttribute("readonly",Boolean(e))}get required(){return this.hasAttribute("required")}set required(e){this.toggleAttribute("required",Boolean(e))}get form(){return this.internals.form}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}checkValidity(){return this.internals.checkValidity()}reportValidity(){return this.internals.reportValidity()}focus(e){this.trigger?.focus(e)}get unavailable(){return this.disabled||this.formDisabled}get locked(){return this.unavailable||this.readOnly}captureDefault(){void 0===this.initialValue&&(this.initialValue=this.getAttribute("default-value")??this.value,this.awaitingValue=!this.hasAttribute("value")&&!this.hasAttribute("default-value"),!this.hasAttribute("value")&&this.initialValue&&this.setAttribute("value",this.initialValue))}get name(){return this.getAttribute("name")??""}set name(e){this.setAttribute("name",e)}get open(){return this.hasAttribute("open")}set open(e){const t=Boolean(e)&&!this.locked;this.open!==t&&this.toggleAttribute("open",t)}get value(){return this.getAttribute("value")||""}set value(e){const t=Array.isArray(e)?JSON.stringify(e):e;t?this.setAttribute("value",t):this.removeAttribute("value"),this.syncTrigger(),this.syncOptions(),this.syncFormValue()}connectedCallback(){for(const e of["name","value","defaultValue","disabled","readOnly","required","multiple","searchable","open"]){if(!Object.prototype.hasOwnProperty.call(this,e))continue;const t=this,s=t[e];delete t[e],t[e]=s}this.captureDefault(),this.built||this.build(),this.syncState(),queueMicrotask(()=>{this.isConnected&&this.syncFormValue()}),document.addEventListener("mousedown",this.handleDocumentMouseDown),this.addEventListener("keydown",this.handleDocumentKeyDown),this.addEventListener("focusout",this.handleFocusOut)}formAssociatedCallback(){this.syncFormValue()}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),this.removeEventListener("keydown",this.handleDocumentKeyDown),this.removeEventListener("focusout",this.handleFocusOut),this.open=!1,this.cancelSearchFocus()}formResetCallback(){this.value=this.defaultValue,this.userInteracted=!1,this.open=!1,this.syncState()}formStateRestoreCallback(e){"string"==typeof e&&(this.value=e)}formDisabledCallback(e){this.formDisabled=e,this.built&&this.syncState()}attributeChangedCallback(e,t){if("value"===e&&void 0!==this.initialValue&&this.awaitingValue&&!this.userInteracted&&(this.initialValue=this.value,this.awaitingValue=!1),this.built){if("multiple"===e){let e=[];if(null!==t)try{const t=JSON.parse(this.value);e=Array.isArray(t)?t.map(String):[this.value]}catch{e=this.value.split(",").filter(Boolean)}else e=this.value?[this.value]:[];this.setSelectedValues(this.multiple?e:e.slice(0,1))}if("default-value"!==e||this.userInteracted||(this.value=this.defaultValue),"open"!==e)return"value"===e?(this.syncTrigger(),this.syncOptions(),void this.syncFormValue()):void this.syncState();this.syncOpenState()}}get multiple(){return this.hasAttribute("multiple")}set multiple(e){this.toggleAttribute("multiple",Boolean(e))}get searchable(){return this.hasAttribute("searchable")}set searchable(e){this.toggleAttribute("searchable",Boolean(e))}get showClearButton(){return!this.hasAttribute("show-clear-button")||"false"!==this.getAttribute("show-clear-button")}parseOptions(){const e=this.getAttribute("options")||"[]";try{const t=JSON.parse(e);if(!Array.isArray(t))return[];const s=new Set;return t.flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if(!["string","number"].includes(typeof t.value)||!["string","number"].includes(typeof t.label))return[];const i=String(t.value);return s.has(i)?[]:(s.add(i),[{value:i,label:String(t.label),disabled:!0===t.disabled}])})}catch{return e.split(",").map(e=>e.trim()).filter(Boolean).map(e=>({value:e,label:e}))}}parseSelectedValues(){const e=this.getAttribute("value")||"";if(!e)return[];if(this.multiple)try{const t=JSON.parse(e);return Array.isArray(t)?[...new Set(t.filter(e=>"string"==typeof e||"number"==typeof e).map(String))]:[]}catch{return e.split(",").map(e=>e.trim()).filter(Boolean)}return e?[e]:[]}setSelectedValues(e){this.multiple?e.length?this.setAttribute("value",JSON.stringify(e)):this.removeAttribute("value"):e[0]?this.setAttribute("value",e[0]):this.removeAttribute("value")}syncFormValue(){const e=this.parseSelectedValues(),s=this.value;if(this.unavailable||!this.name)this.internals.setFormValue(null,s);else if(this.multiple){const t=new FormData;e.forEach(e=>t.append(this.name,e)),this.internals.setFormValue(e.length?t:null,s)}else this.internals.setFormValue(e[0]||null,s);const i=this.required&&!this.locked&&0===e.length;this.internals.setValidity(i?{valueMissing:!0}:{},i?t("required"):"",this.trigger)}getIconSize(){const e=this.getAttribute("size")||"m";return a(n.includes(e)?e:"m")}syncIndicatorIcons(){const e=this.getIconSize(),update=(t,s)=>{if(!t)return;const i=t.querySelector(":scope > svg[data-designbase-icon]");i?.getAttribute("data-designbase-icon")===s&&i.getAttribute("width")===String(e)||t.replaceChildren(r(s,e))};update(this.clearButton,"close"),update(this.chevronEl,this.open?"chevron-up":"chevron-down")}build(){const e=this.getAttribute("id")||l("db-select"),t=`${e}-listbox`;this.hasAttribute("id")||this.setAttribute("id",e),this.labelEl=document.createElement("label"),this.labelEl.className="designbase-wc-select__label",this.labelEl.addEventListener("click",()=>this.focus()),this.trigger=document.createElement("div"),this.trigger.className="designbase-wc-select__trigger",this.trigger.tabIndex=0,this.trigger.setAttribute("role","combobox"),this.trigger.setAttribute("aria-haspopup","listbox"),this.trigger.setAttribute("aria-controls",t),this.trigger.addEventListener("click",this.handleTriggerClick),this.trigger.addEventListener("focus",this.handleTriggerFocus),this.trigger.addEventListener("blur",this.handleTriggerBlur),this.valueEl=document.createElement("div"),this.valueEl.className="designbase-wc-select__value",this.indicatorsEl=document.createElement("div"),this.indicatorsEl.className="designbase-wc-select__indicators",this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="designbase-wc-select__clear-button",this.clearButton.setAttribute("aria-label",s(this,"label-clear","clearAll")),this.clearButton.hidden=!0,this.clearButton.appendChild(r("close",this.getIconSize())),this.clearButton.addEventListener("click",this.handleClear),this.chevronEl=document.createElement("div"),this.chevronEl.className="designbase-wc-select__chevron",this.indicatorsEl.append(this.clearButton,this.chevronEl),this.trigger.append(this.valueEl,this.indicatorsEl),this.dropdown=document.createElement("div"),this.dropdown.className="designbase-wc-select__dropdown",this.searchWrap=document.createElement("div"),this.searchWrap.className="designbase-wc-select__search",this.searchWrap.hidden=!0,this.searchInput=document.createElement("input"),this.searchInput.type="text",this.searchInput.className="designbase-wc-select__search-input",this.searchInput.placeholder=s(this,"label-search","search.label"),this.searchInput.setAttribute("role","combobox"),this.searchInput.setAttribute("aria-autocomplete","list"),this.searchInput.setAttribute("aria-controls",t),this.searchInput.addEventListener("input",this.handleSearchInput),this.searchInput.addEventListener("mousedown",e=>e.stopPropagation()),this.searchInput.addEventListener("click",e=>e.stopPropagation()),this.searchWrap.appendChild(this.searchInput),this.optionsEl=document.createElement("div"),this.optionsEl.className="designbase-wc-select__options",this.optionsEl.id=t,this.optionsEl.setAttribute("role","listbox"),this.dropdown.append(this.searchWrap,this.optionsEl),this.helperEl=document.createElement("p"),this.helperEl.className="designbase-wc-select__helper-text",this.errorEl=document.createElement("p"),this.errorEl.className="designbase-wc-select__error-message",this.append(this.labelEl,this.trigger,this.dropdown,this.helperEl,this.errorEl),this.built=!0}moveFocus(e){const t=this.getFilteredOptions().map((e,t)=>e.disabled?-1:t).filter(e=>e>=0);t.length?this.focusedIndex="first"===e?t[0]:"last"===e?t[t.length-1]:"next"===e?t.find(e=>e>this.focusedIndex)??t[t.length-1]:[...t].reverse().find(e=>e<this.focusedIndex)??t[0]:this.focusedIndex=-1,this.syncOptions()}getFilteredOptions(){const e=this.parseOptions();if(!this.searchable||!this.searchTerm)return e;const t=this.searchTerm.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(t))}selectOption(e){if(this.locked||e.disabled)return;this.userInteracted=!0,this.awaitingValue=!1;const t=this.parseSelectedValues();let s;this.multiple?s=t.includes(e.value)?t.filter(t=>t!==e.value):[...t,e.value]:(s=[e.value],this.open=!1,this.searchTerm="",this.searchInput&&(this.searchInput.value=""),this.focusedIndex=-1),this.setSelectedValues(s),this.syncTrigger(),this.syncOptions(),this.dispatchChange(s),this.multiple||this.focus()}dispatchChange(e){const t=this.parseOptions();if(this.multiple)return this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),void this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,labels:e.map(e=>t.find(t=>t.value===e)?.label||e)},bubbles:!0,composed:!0}));const s=e[0]||"",i=t.find(e=>e.value===s)?.label||"";this.syncFormValue(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:s,label:i},bubbles:!0,composed:!0}))}syncAccessibleName(e){var s;if(!this.trigger)return;const i=this.getAttribute("aria-label");let a=this.getAttribute("aria-labelledby");!a&&!i&&e&&this.labelEl&&((s=this.labelEl).id||(s.id=l("db-select-label")),a=this.labelEl.id);for(const s of[this.trigger,this.searchInput,this.optionsEl])s&&(a?(s.setAttribute("aria-labelledby",a),s.removeAttribute("aria-label")):(s.removeAttribute("aria-labelledby"),s.setAttribute("aria-label",i||e||this.getAttribute("placeholder")||t("select.placeholder"))))}syncState(){if(!this.trigger||!this.dropdown||!this.optionsEl)return;const t=o(this.getAttribute("size"),n,"m"),i=o(this.getAttribute("position"),h,"bottom"),a="full"===this.getAttribute("dropdown-width")?"full":"auto",r=Number(this.getAttribute("max-height")||200),l=Number.isFinite(r)&&r>0?r:200,c=this.getAttribute("label")||"",d=this.getAttribute("helper-text")||"",u=this.getAttribute("error-message")||"",p=this.hasAttribute("error"),b=this.getAttribute("id")||"";e(this,["designbase-wc-select",`designbase-wc-select--${t}`,this.open&&"designbase-wc-select--open",p&&"designbase-wc-select--error",this.unavailable&&"designbase-wc-select--disabled",this.hasAttribute("readonly")&&"designbase-wc-select--readonly",this.hasAttribute("full-width")&&"designbase-wc-select--full-width",this.multiple&&"designbase-wc-select--multiple",this.searchable&&"designbase-wc-select--searchable"]);const g=this.parseSelectedValues();if(this.classList.toggle("designbase-wc-select--has-value",g.length>0),this.labelEl){const e=this.hasAttribute("required")?'<span class="designbase-wc-select__required" aria-hidden="true">*</span>':"";this.labelEl.innerHTML=c?`${this.escape(c)}${e}`:"",this.labelEl.hidden=!c}this.syncAccessibleName(c),this.dropdown.className=["designbase-wc-select__dropdown",`designbase-wc-select__dropdown--${a}`,`designbase-wc-select__dropdown--${i}`,this.open&&"designbase-wc-select__dropdown--open"].filter(Boolean).join(" "),this.optionsEl.style.maxHeight=`${l}px`,this.searchWrap&&(this.searchWrap.hidden=!this.searchable);const m=`${b}-helper`,v=`${b}-error`;this.trigger.setAttribute("aria-required",String(this.required)),this.trigger.setAttribute("aria-disabled",String(this.unavailable)),this.trigger.setAttribute("aria-readonly",String(this.readOnly)),this.searchInput.disabled=this.locked,this.searchInput.placeholder=s(this,"label-search","search.label"),this.clearButton.setAttribute("aria-label",s(this,"label-clear","clearAll")),this.optionsEl.setAttribute("aria-multiselectable",String(this.multiple)),p&&u?(this.errorEl.id=v,this.errorEl.textContent=u,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.trigger.setAttribute("aria-describedby",v),this.trigger.setAttribute("aria-invalid","true")):d?(this.helperEl.id=m,this.helperEl.textContent=d,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.trigger.setAttribute("aria-describedby",m),this.trigger.removeAttribute("aria-invalid")):(this.helperEl.hidden=!0,this.errorEl.hidden=!0,this.trigger.removeAttribute("aria-describedby"),this.trigger.removeAttribute("aria-invalid")),p&&this.trigger.setAttribute("aria-invalid","true");const f=[this.getAttribute("aria-describedby"),this.trigger.getAttribute("aria-describedby")].filter(Boolean).join(" ");f&&this.trigger.setAttribute("aria-describedby",[...new Set(f.split(/\s+/))].join(" "));for(const e of["aria-describedby","aria-required","aria-invalid"]){const t=this.trigger.getAttribute(e);null===t?this.searchInput.removeAttribute(e):this.searchInput.setAttribute(e,t)}this.unavailable?this.trigger.tabIndex=-1:this.trigger.tabIndex=0,this.syncOpenState(),this.syncTrigger(),this.syncOptions(),this.syncFormValue(),this.syncIndicatorIcons()}syncOpenState(){if(!this.trigger||!this.dropdown||!this.chevronEl)return;if(this.locked&&this.open)return void this.removeAttribute("open");const e=this.open&&!this.wasOpen;this.wasOpen=this.open,this.trigger.setAttribute("aria-expanded",String(this.open)),this.searchInput?.setAttribute("aria-expanded",String(this.open)),this.classList.toggle("designbase-wc-select--open",this.open),this.dropdown.classList.toggle("designbase-wc-select__dropdown--open",this.open),this.dropdown.inert=!this.open,this.open?e&&this.searchable&&this.scheduleSearchFocus():(this.cancelSearchFocus(),this.searchTerm="",this.focusedIndex=-1,this.searchInput&&(this.searchInput.value=""),this.syncOptions()),this.syncIndicatorIcons()}cancelSearchFocus(){void 0!==this.searchFocusFrame&&cancelAnimationFrame(this.searchFocusFrame),this.searchFocusFrame=void 0}scheduleSearchFocus(){this.cancelSearchFocus();const attempt=()=>{this.searchFocusFrame=void 0;const e=this.getRootNode();this.isConnected&&this.open&&this.searchable&&!this.locked&&this.searchInput&&this.contains(e.activeElement)&&("visible"===getComputedStyle(this.searchInput).visibility&&this.searchInput.getClientRects().length?this.searchInput.focus():this.dropdown?.getClientRects().length&&(this.searchFocusFrame=requestAnimationFrame(attempt)))};this.searchFocusFrame=requestAnimationFrame(attempt)}syncTrigger(){if(!this.valueEl||!this.clearButton)return;const e=this.parseOptions(),s=this.parseSelectedValues(),a=this.getAttribute("placeholder")||t("select.placeholder"),l=s.length>0,n=l&&this.showClearButton&&!this.locked;if(this.valueEl.replaceChildren(),this.multiple)if(0===s.length){const e=document.createElement("span");e.className="designbase-wc-select__placeholder",e.textContent=a,this.valueEl.appendChild(e)}else{const t=document.createElement("div");t.className="designbase-wc-select__tags",s.forEach(a=>{const l=e.find(e=>e.value===a),n=document.createElement("span");n.className="designbase-wc-select__tag";const h=document.createElement("span");h.className="designbase-wc-select__tag-label",h.textContent=l?.label||a;const o=document.createElement("button");o.type="button",o.disabled=this.locked,o.hidden=this.locked,o.className="designbase-wc-select__tag-remove",o.setAttribute("aria-label",i("{0} 제거",[l?.label||a])),o.appendChild(r("close",12)),o.addEventListener("click",e=>{if(e.stopPropagation(),this.locked)return;this.userInteracted=!0,this.awaitingValue=!1;const t=s.filter(e=>e!==a);this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t),this.focus()}),n.append(h,o),t.appendChild(n)}),this.valueEl.appendChild(t)}else{const t=document.createElement("span");t.className="designbase-wc-select__single-value";const i=e.find(e=>e.value===s[0]);t.textContent=l?i?.label||s[0]:a,l||t.classList.add("designbase-wc-select__placeholder"),this.valueEl.appendChild(t)}this.clearButton.hidden=!n,this.clearButton.setAttribute("aria-hidden",n?"false":"true"),this.classList.toggle("designbase-wc-select--has-value",l)}syncOptions(){if(!this.optionsEl)return;const e=this.getFilteredOptions(),t=this.parseSelectedValues(),i=this.getAttribute("id")||"db-select";if(this.optionsEl.replaceChildren(),this.trigger?.removeAttribute("aria-activedescendant"),this.searchInput?.removeAttribute("aria-activedescendant"),0===e.length){const e=document.createElement("div");return e.className="designbase-wc-select__no-options",e.textContent=this.searchTerm?s(this,"label-no-results","select.noResults"):s(this,"label-empty","select.noResults"),void this.optionsEl.appendChild(e)}if(e.forEach((e,s)=>{const a=t.includes(e.value),l=s===this.focusedIndex,n=document.createElement("div");if(n.className=["designbase-wc-select__option",a&&"designbase-wc-select__option--selected",l&&"designbase-wc-select__option--focused",e.disabled&&"designbase-wc-select__option--disabled"].filter(Boolean).join(" "),n.id=`${i}-option-${s}`,n.setAttribute("role","option"),n.setAttribute("aria-selected",String(a)),n.setAttribute("aria-disabled",String(Boolean(e.disabled))),n.addEventListener("mousedown",e=>e.preventDefault()),n.addEventListener("click",()=>this.selectOption(e)),this.multiple){const e=document.createElement("div");e.className="designbase-wc-select__checkbox",e.setAttribute("aria-hidden","true"),e.appendChild(r("done",16)),e.classList.toggle("designbase-wc-select__checkbox--checked",a),n.appendChild(e)}const h=document.createElement("span");h.className="designbase-wc-select__option-label",h.textContent=e.label,n.appendChild(h),this.optionsEl.appendChild(n)}),this.open&&this.focusedIndex>=0&&e[this.focusedIndex]&&!e[this.focusedIndex].disabled){const e=`${i}-option-${this.focusedIndex}`;this.trigger?.setAttribute("aria-activedescendant",e),this.searchInput?.setAttribute("aria-activedescendant",e);const t=this.optionsEl.children[this.focusedIndex];t.offsetTop<this.optionsEl.scrollTop?this.optionsEl.scrollTop=t.offsetTop:t.offsetTop+t.offsetHeight>this.optionsEl.scrollTop+this.optionsEl.clientHeight&&(this.optionsEl.scrollTop=t.offsetTop+t.offsetHeight-this.optionsEl.clientHeight)}else this.trigger?.removeAttribute("aria-activedescendant")}escape(e){return e.replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[e]||e))}}DbSelect.formAssociated=!0,customElements.get("db-select")||customElements.define("db-select",DbSelect);export{DbSelect};
|
|
@@ -6,23 +6,32 @@ interface TabItemConfig {
|
|
|
6
6
|
}
|
|
7
7
|
declare class DbTabs extends HTMLElement {
|
|
8
8
|
static get observedAttributes(): string[];
|
|
9
|
+
private readonly uid;
|
|
10
|
+
private readonly records;
|
|
11
|
+
private readonly slotNodes;
|
|
9
12
|
private list?;
|
|
10
13
|
private indicator?;
|
|
11
|
-
private
|
|
12
|
-
private
|
|
13
|
-
private
|
|
14
|
-
private
|
|
14
|
+
private stash?;
|
|
15
|
+
private rendering;
|
|
16
|
+
private reflecting;
|
|
17
|
+
private focusedKey?;
|
|
15
18
|
private childObserver?;
|
|
16
19
|
private resizeObserver?;
|
|
17
20
|
private resizeRaf?;
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
private drag?;
|
|
22
|
+
private suppressClick;
|
|
23
|
+
private clickTimer?;
|
|
20
24
|
get tabItems(): TabItemConfig[];
|
|
21
|
-
get items(): TabItemConfig[];
|
|
22
|
-
set items(value: TabItemConfig[] | string);
|
|
23
25
|
set tabItems(value: TabItemConfig[] | string);
|
|
26
|
+
get items(): TabItemConfig[] | string;
|
|
27
|
+
set items(value: TabItemConfig[] | string);
|
|
28
|
+
get labels(): string[];
|
|
29
|
+
set labels(value: string[] | string);
|
|
30
|
+
private entries;
|
|
24
31
|
get activeIndex(): number;
|
|
25
32
|
set activeIndex(value: number);
|
|
33
|
+
get selectedId(): string;
|
|
34
|
+
set selectedId(value: string);
|
|
26
35
|
get orientation(): string;
|
|
27
36
|
set orientation(value: string);
|
|
28
37
|
get size(): string;
|
|
@@ -33,13 +42,26 @@ declare class DbTabs extends HTMLElement {
|
|
|
33
42
|
set fullWidth(value: boolean);
|
|
34
43
|
connectedCallback(): void;
|
|
35
44
|
disconnectedCallback(): void;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
private
|
|
45
|
+
attributeChangedCallback(name: string, oldValue: string | null, value: string | null): void;
|
|
46
|
+
refresh(): void;
|
|
47
|
+
focus(options?: FocusOptions): void;
|
|
48
|
+
private slotIndex;
|
|
49
|
+
private collectSlots;
|
|
50
|
+
private createRecord;
|
|
51
|
+
private hideUnassigned;
|
|
40
52
|
private render;
|
|
53
|
+
private syncRoving;
|
|
41
54
|
private select;
|
|
42
|
-
private
|
|
55
|
+
private navigate;
|
|
56
|
+
private ensureVisible;
|
|
57
|
+
private beginDrag;
|
|
58
|
+
private moveDrag;
|
|
59
|
+
private finishDrag;
|
|
60
|
+
private cancelDrag;
|
|
61
|
+
private endDrag;
|
|
62
|
+
private captureClick;
|
|
63
|
+
private handleResize;
|
|
64
|
+
private handleListScroll;
|
|
43
65
|
private updateIndicator;
|
|
44
66
|
}
|
|
45
67
|
declare global {
|
|
@@ -49,3 +71,4 @@ declare global {
|
|
|
49
71
|
}
|
|
50
72
|
|
|
51
73
|
export { DbTabs };
|
|
74
|
+
export type { TabItemConfig };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as t}from"./db-icons.js";import{labelFrom as e}from"../core/i18n.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TABS_ORIENTATIONS as i,TABS_SIZES as a,TABS_VARIANTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTabs extends HTMLElement{constructor(){super(...arguments),this.tabButtons=[],this.inactivePanels=document.createDocumentFragment(),this.isRendering=!1,this.handleResize=()=>{this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.resizeRaf=requestAnimationFrame(()=>{this.isRendering||(this.handleListScroll(),this.updateIndicator(!1))})},this.handleListScroll=()=>{if(!this.list)return;const t=this.list.scrollWidth>this.list.clientWidth,e=this.list.scrollLeft+this.list.clientWidth>=this.list.scrollWidth-5;this.list.classList.toggle("designbase-wc-tabs__list--show-gradient",t&&!e&&"horizontal"===this.orientation)}}static get observedAttributes(){return["labels","items","active-index","selected-id","orientation","size","variant","full-width"]}get labels(){const t=this.tabItems.map(t=>t.label);return t.length?t:(this.getAttribute("labels")||"").split(",").map(t=>t.trim()).filter(Boolean)}set labels(t){this.setAttribute("labels",Array.isArray(t)?t.join(","):t)}get tabItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}get items(){return this.tabItems}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}set tabItems(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}get activeIndex(){const t=this.getAttribute("selected-id");if(t){const e=this.tabItems.findIndex((e,s)=>(e.id||String(s))===t);if(e>=0)return e}return Number(this.getAttribute("active-index")||0)}set activeIndex(t){this.setAttribute("active-index",String(t))}get orientation(){return s(this.getAttribute("orientation"),i,"horizontal")}set orientation(t){this.setAttribute("orientation",t)}get size(){return s(this.getAttribute("size"),a,"m")}set size(t){this.setAttribute("size",t)}get variant(){return s(this.getAttribute("variant"),n,"default")}set variant(t){this.setAttribute("variant",t)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(t){this.toggleAttribute("full-width",Boolean(t))}connectedCallback(){this.render(),this.list?.addEventListener("scroll",this.handleListScroll,{passive:!0}),window.addEventListener("resize",this.handleResize),this.resizeObserver=new ResizeObserver(()=>this.handleResize()),this.resizeObserver.observe(this),this.childObserver=new MutationObserver(t=>{if(this.isRendering)return;t.some(t=>Array.from(t.addedNodes).some(t=>t instanceof HTMLElement&&(t.hasAttribute("slot")||void 0!==t.dataset.panelIndex)))&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.list?.removeEventListener("scroll",this.handleListScroll),window.removeEventListener("resize",this.handleResize),this.resizeObserver?.disconnect(),this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.childObserver?.disconnect()}attributeChangedCallback(){this.isConnected&&this.render()}collectPanelContent(){const t=new Map,register=(e,s)=>{if(!(e instanceof HTMLElement)||"SLOT"===e.tagName)return;t.has(s)||t.set(s,[]);const i=t.get(s);i.includes(e)||i.push(e)};return Array.from(this.children).forEach(t=>{const e=t.getAttribute("slot")?.match(/^panel-(\d+)$/);if(e)return void register(t,Number(e[1]));const s=t.dataset.panelIndex;void 0!==s&®ister(t,Number(s))}),this.panel?.querySelectorAll(":scope > .designbase-wc-tabs__panel-inner > [data-panel-index]").forEach(t=>{t instanceof HTMLElement&®ister(t,Number(t.dataset.panelIndex))}),Array.from(this.inactivePanels.children).forEach(t=>{t instanceof HTMLElement&&void 0!==t.dataset.panelIndex&®ister(t,Number(t.dataset.panelIndex))}),t}render(){this.isRendering=!0;const s=this.collectPanelContent(),i=this.labels,a=this.tabItems,n=Math.min(Math.max(this.activeIndex,0),Math.max(i.length-1,0)),r=this.size,l=this.orientation,o=this.variant,d="default"===o;this.className=["designbase-wc-tabs",`designbase-wc-tabs--${l}`,`designbase-wc-tabs--${r}`,`designbase-wc-tabs--${o}`,this.fullWidth&&"designbase-wc-tabs--full-width"].filter(Boolean).join(" "),this.querySelectorAll(":scope > .designbase-wc-tabs__list, :scope > .designbase-wc-tabs__panel").forEach(t=>t.remove()),this.list=document.createElement("div"),this.list.className=["designbase-wc-tabs__list",`designbase-wc-tabs__list--${l}`,this.fullWidth&&"designbase-wc-tabs__list--full-width"].filter(Boolean).join(" "),this.list.setAttribute("role","tablist"),this.list.setAttribute("aria-orientation",l),this.list.setAttribute("aria-label",e(this,"label-tablist","tabs.label")),this.tabButtons=[],i.forEach((e,s)=>{const i=a[s],l=Boolean(i?.disabled),o=s===n,d=document.createElement("button");if(d.type="button",d.className=["designbase-wc-tabs__tab",o&&"designbase-wc-tabs__tab--selected",l&&"designbase-wc-tabs__tab--disabled"].filter(Boolean).join(" "),d.setAttribute("role","tab"),d.setAttribute("aria-selected",String(o)),d.setAttribute("aria-controls",`panel-${s}`),d.id=`tab-${s}`,d.tabIndex=o?0:-1,d.disabled=l,i?.icon){const e=document.createElement("span");e.className="designbase-wc-tabs__tab-icon";const s="s"===r?16:"l"===r?20:18;e.setAttribute("aria-hidden","true"),e.append(t(i.icon,s)),d.append(e)}const c=document.createElement("span");c.className="designbase-wc-tabs__tab-label",c.textContent=e,d.append(c),d.addEventListener("click",()=>this.select(s)),d.addEventListener("keydown",t=>this.handleKeyDown(t,s)),this.list?.append(d),this.tabButtons.push(d)}),d?(this.indicator=document.createElement("span"),this.indicator.className="designbase-wc-tabs__indicator designbase-wc-tabs__indicator--no-transition",this.list.append(this.indicator),requestAnimationFrame(()=>this.updateIndicator(!1))):this.indicator=void 0,this.panel=document.createElement("div"),this.panel.className="designbase-wc-tabs__panel",this.panel.setAttribute("role","tabpanel"),this.panel.id=`panel-${n}`,this.panel.setAttribute("aria-labelledby",`tab-${n}`),this.panel.tabIndex=0;const c=document.createElement("div");c.className="designbase-wc-tabs__panel-inner",s.forEach((t,e)=>{t.forEach(t=>{t.removeAttribute("slot"),t.dataset.panelIndex=String(e),e===n?c.append(t):this.inactivePanels.append(t)})}),this.panel.append(c),this.append(this.list,this.panel),requestAnimationFrame(()=>{this.handleListScroll(),d&&this.updateIndicator(!1)}),this.isRendering=!1}select(t){const e=this.labels,s=this.tabItems;if(!e[t]||s[t]?.disabled)return;this.activeIndex=t;const i=s[t]?.id||String(t);this.setAttribute("selected-id",i),this.dispatchEvent(new CustomEvent("db-change",{detail:{index:t,label:e[t],id:i},bubbles:!0,composed:!0})),this.render()}handleKeyDown(t,e){const s=this.labels,i=this.tabItems;let a=e;if("ArrowRight"===t.key||"ArrowDown"===t.key)a=(e+1)%s.length;else if("ArrowLeft"===t.key||"ArrowUp"===t.key)a=(e-1+s.length)%s.length;else if("Home"===t.key)a=0;else{if("End"!==t.key)return"Enter"===t.key||" "===t.key?(t.preventDefault(),void this.select(e)):void 0;a=s.length-1}t.preventDefault();let n=0;for(;i[a]?.disabled&&n<s.length;)a="ArrowLeft"===t.key||"ArrowUp"===t.key?(a-1+s.length)%s.length:(a+1)%s.length,n+=1;this.tabButtons[a]?.focus()}updateIndicator(t=!1){const e=this.list?.querySelector(".designbase-wc-tabs__tab--selected");if(!e||!this.indicator)return;const s="vertical"===this.orientation;this.indicator.classList.toggle("designbase-wc-tabs__indicator--no-transition",!t),this.indicator.classList.add(s?"designbase-wc-tabs__indicator--vertical":"designbase-wc-tabs__indicator--horizontal"),this.indicator.classList.add("designbase-wc-tabs__indicator--ready"),s?(this.indicator.style.width="2px",this.indicator.style.height=`${e.offsetHeight}px`,this.indicator.style.transform=`translate3d(0, ${e.offsetTop}px, 0)`):(this.indicator.style.width=`${e.offsetWidth}px`,this.indicator.style.height="2px",this.indicator.style.transform=`translate3d(${e.offsetLeft}px, 0, 0)`)}}customElements.get("db-tabs")||customElements.define("db-tabs",DbTabs);export{DbTabs};
|
|
1
|
+
import{isDbIconName as t,createDbIcon as e}from"./db-icons.js";import{labelFrom as i}from"../core/i18n.js";import{dbUid as s}from"../core/uid.js";import{setHostClasses as n}from"../core/host-class.js";import{coerceToContract as r}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TABS_ORIENTATIONS as a,TABS_SIZES as o,TABS_VARIANTS as l}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTabs extends HTMLElement{constructor(){super(...arguments),this.uid=s("db-tabs"),this.records=new Map,this.slotNodes=new Set,this.rendering=!1,this.reflecting=!1,this.suppressClick=!1,this.beginDrag=t=>{if(!this.list||"touch"===t.pointerType||!t.isPrimary||0!==t.button||this.drag)return;if(!("horizontal"===this.orientation?this.list.scrollWidth>this.list.clientWidth+1:this.list.scrollHeight>this.list.clientHeight+1))return;const e=t.target instanceof Element&&t.target.closest("button")||this.list;this.drag={id:t.pointerId,target:e,x:t.clientX,y:t.clientY,left:this.list.scrollLeft,top:this.list.scrollTop,moved:!1};try{e.setPointerCapture(t.pointerId)}catch{}},this.moveDrag=t=>{const e=this.drag;if(!e||!this.list||e.id!==t.pointerId)return;const i="horizontal"===this.orientation?t.clientX-e.x:t.clientY-e.y;!e.moved&&Math.abs(i)<6||(e.moved=!0,this.list.classList.add("designbase-wc-tabs__list--dragging"),t.cancelable&&t.preventDefault(),"horizontal"===this.orientation?this.list.scrollLeft=e.left-i:this.list.scrollTop=e.top-i)},this.finishDrag=t=>{t.pointerId===this.drag?.id&&(this.moveDrag(t),this.endDrag(!1))},this.cancelDrag=t=>{t.pointerId===this.drag?.id&&this.endDrag(!0)},this.captureClick=t=>{this.suppressClick&&(t.preventDefault(),t.stopImmediatePropagation())},this.handleResize=()=>{this.isConnected&&(void 0!==this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.resizeRaf=requestAnimationFrame(()=>{this.resizeRaf=void 0,this.handleListScroll(),this.updateIndicator()}))},this.handleListScroll=()=>{if(!this.list)return;const t="rtl"===getComputedStyle(this).direction,e=[...this.records.values()],i=e[e.length-1]?.button.getBoundingClientRect(),s=this.list.getBoundingClientRect(),n="horizontal"===this.orientation&&!!i&&(t?i.left<s.left-1:i.right>s.right+1);this.list.classList.toggle("designbase-wc-tabs__list--show-gradient",n)}}static get observedAttributes(){return["labels","items","active-index","selected-id","orientation","size","variant","full-width","aria-label","aria-labelledby","aria-describedby","label-tablist","dir"]}get tabItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t.filter(t=>!!t&&"object"==typeof t&&"string"==typeof t.label&&t.label.trim().length>0):[]}catch{return[]}}set tabItems(t){this.items=t}get items(){return this.tabItems}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}get labels(){const t=this.tabItems;if(t.length)return t.map(t=>t.label);const e=this.getAttribute("labels")||"";try{const t=JSON.parse(e);if(Array.isArray(t))return t.filter(t=>"string"==typeof t&&!!t.trim())}catch{}return e.split(",").map(t=>t.trim()).filter(Boolean)}set labels(t){this.setAttribute("labels",Array.isArray(t)?JSON.stringify(t):t)}entries(){const t=this.tabItems,e=new Set;return this.labels.map((i,s)=>{const n=t[s]||{label:i},r="string"==typeof n.id&&n.id?n.id:String(s);let a=r,o=1;for(;e.has(a);)a=`${r}#${++o}`;return e.add(a),{key:a,item:n,index:s}})}get activeIndex(){const t=this.entries(),e=this.getAttribute("selected-id");let i=e?t.findIndex(t=>t.key===e):-1;if(i<0){const t=Number(this.getAttribute("active-index")||0);i=Number.isFinite(t)?Math.trunc(t):0}if(i=Math.max(0,Math.min(i,t.length-1)),t[i]&&!t[i].item.disabled)return i;const s=t.find(t=>t.index>=i&&!t.item.disabled);return s?.index??t.find(t=>!t.item.disabled)?.index??-1}set activeIndex(t){this.reflecting=!0;try{this.removeAttribute("selected-id"),this.setAttribute("active-index",String(t))}finally{this.reflecting=!1}this.isConnected&&this.render()}get selectedId(){return this.entries()[this.activeIndex]?.key||""}set selectedId(t){this.setAttribute("selected-id",t)}get orientation(){return r(this.getAttribute("orientation"),a,"horizontal")}set orientation(t){this.setAttribute("orientation",t)}get size(){return r(this.getAttribute("size"),o,"m")}set size(t){this.setAttribute("size",t)}get variant(){return r(this.getAttribute("variant"),l,"default")}set variant(t){this.setAttribute("variant",t)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(t){this.toggleAttribute("full-width",t)}connectedCallback(){for(const t of["items","tabItems","labels","activeIndex","selectedId","orientation","size","variant","fullWidth"])if(Object.prototype.hasOwnProperty.call(this,t)){const e=this[t];delete this[t],this[t]=e}this.resizeObserver??(this.resizeObserver=new ResizeObserver(this.handleResize)),this.resizeObserver.observe(this),this.render(),this.resizeObserver.observe(this.list);for(const t of this.records.values())this.resizeObserver.observe(t.button);window.addEventListener("resize",this.handleResize),document.fonts?.addEventListener("loadingdone",this.handleResize),this.childObserver??(this.childObserver=new MutationObserver(t=>{if(this.rendering)return;t.some(t=>"attributes"===t.type||Array.from(t.addedNodes).some(t=>t instanceof HTMLElement&&t.parentElement===this&&void 0!==this.slotIndex(t))||Array.from(t.removedNodes).some(t=>t instanceof HTMLElement&&(this.slotNodes.has(t)&&!this.contains(t)||[...this.records.values()].some(e=>e.panel===t)&&t.parentElement!==this)))&&this.render()})),this.childObserver.observe(this,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["slot","data-panel-index"]})}disconnectedCallback(){this.endDrag(!0),void 0!==this.clickTimer&&clearTimeout(this.clickTimer),this.suppressClick=!1,this.clickTimer=void 0,window.removeEventListener("resize",this.handleResize),document.fonts?.removeEventListener("loadingdone",this.handleResize),this.resizeObserver?.disconnect(),this.childObserver?.disconnect(),void 0!==this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.resizeRaf=void 0}attributeChangedCallback(t,e,i){if(!this.reflecting&&e!==i){if("active-index"===t&&this.isConnected){this.reflecting=!0;try{this.removeAttribute("selected-id")}finally{this.reflecting=!1}}this.isConnected&&this.render()}}refresh(){this.isConnected&&this.render()}focus(t){this.records.get(this.selectedId)?.button.focus(t)}slotIndex(t){const e=t.getAttribute("slot")?.match(/^panel-(\d+)$/),i=e?.[1]??t.dataset.panelIndex;if(void 0===i||""===i.trim())return;const s=Number(i);return Number.isInteger(s)&&s>=0?s:void 0}collectSlots(){for(const t of Array.from(this.children))t instanceof HTMLElement&&void 0!==this.slotIndex(t)&&this.slotNodes.add(t);const t=new Map;for(const e of this.slotNodes){if(!this.contains(e)){this.slotNodes.delete(e);continue}const i=this.slotIndex(e);if(void 0===i)continue;const s=t.get(i)||[];s.push(e),t.set(i,s)}return t}createRecord(t){const e=document.createElement("button");e.type="button",e.setAttribute("role","tab");const i=s(this.uid);e.id=`${i}-tab`;const n=document.createElement("span");n.className="designbase-wc-tabs__tab-icon",n.setAttribute("aria-hidden","true");const r=document.createElement("span");r.className="designbase-wc-tabs__tab-label",e.append(n,r);const a=document.createElement("div");a.id=`${i}-panel`,a.className="designbase-wc-tabs__panel",a.setAttribute("role","tabpanel"),a.setAttribute("aria-labelledby",e.id),a.tabIndex=0;const o=document.createElement("div");return o.id=`${i}-inner`,o.className="designbase-wc-tabs__panel-inner",a.append(o),e.addEventListener("click",()=>this.select(t)),e.addEventListener("focus",()=>{this.focusedKey=t,this.syncRoving()}),e.addEventListener("keydown",e=>this.navigate(e,t)),this.resizeObserver?.observe(e),{button:e,icon:n,label:r,panel:a,inner:o}}hideUnassigned(t){this.stash??(this.stash=Object.assign(document.createElement("div"),{hidden:!0,inert:!0})),this.stash.parentElement||this.append(this.stash),t.parentElement!==this.stash&&this.stash.append(t)}render(){if(!this.rendering){this.drag&&this.endDrag(!0),this.rendering=!0;try{const s=this.entries(),r=this.activeIndex,a=s[r]?.key||"",o=document.activeElement,l=[...this.records.values()].findIndex(t=>t.button===o||t.panel.contains(o)),d=this.collectSlots(),h=new Set;this.list??(this.list=document.createElement("div")),this.list.parentElement||(this.list.addEventListener("scroll",this.handleListScroll,{passive:!0}),this.list.addEventListener("pointerdown",this.beginDrag),this.list.addEventListener("pointermove",this.moveDrag),this.list.addEventListener("pointerup",this.finishDrag),this.list.addEventListener("pointercancel",this.cancelDrag),this.list.addEventListener("lostpointercapture",this.cancelDrag),this.list.addEventListener("click",this.captureClick,!0),this.prepend(this.list)),this.list.className=`designbase-wc-tabs__list designbase-wc-tabs__list--${this.orientation}${this.fullWidth?" designbase-wc-tabs__list--full-width":""}`,this.list.setAttribute("role","tablist"),this.list.setAttribute("aria-orientation",this.orientation),this.list.setAttribute("aria-label",this.getAttribute("aria-label")||i(this,"label-tablist","tabs.label"));for(const t of["aria-labelledby","aria-describedby"])this.hasAttribute(t)?this.list.setAttribute(t,this.getAttribute(t)):this.list.removeAttribute(t);const c=[];let b=null,u=this.list;for(const{key:i,item:n,index:a}of s){const s=this.records.get(i)||this.createRecord(i);c.push([i,s]),s.button.className=`designbase-wc-tabs__tab${a===r?" designbase-wc-tabs__tab--selected":""}${n.disabled?" designbase-wc-tabs__tab--disabled":""}`,s.button.disabled=Boolean(n.disabled),s.button.setAttribute("aria-selected",String(a===r)),s.label.textContent=n.label;const o=`${n.icon}:${this.size}`;if(s.iconSignature!==o){s.icon.replaceChildren();const i=n.icon,r="string"==typeof i&&t(i);s.icon.hidden=!r,r&&s.icon.append(e(i,"s"===this.size?16:"l"===this.size?20:18)),s.iconSignature=o}if(s.inner.dataset.dbTabsContentIndex=String(a),!s.inner.hasAttribute("data-db-react-content")){const t=d.get(a)||[];for(const e of Array.from(s.inner.children))t.includes(e)||this.hideUnassigned(e);for(const e of t)h.add(e),e.parentElement!==s.inner&&s.inner.append(e)}const l=b?b.nextElementSibling:this.list.firstElementChild;l!==s.button&&this.list.insertBefore(s.button,l),b=s.button;const g=u.nextElementSibling;g!==s.panel&&this.insertBefore(s.panel,g),u=s.panel}const g=new Set(s.map(t=>t.key));for(const[t,e]of this.records)if(!g.has(t)){for(const t of this.slotNodes)e.panel.contains(t)&&!h.has(t)&&this.hideUnassigned(t);this.resizeObserver?.unobserve(e.button),e.button.remove(),e.panel.remove()}for(const t of this.slotNodes)h.has(t)||this.hideUnassigned(t);this.records.clear();for(const[t,e]of c)this.records.set(t,e);const f=c.some(([,t])=>t.inner.childNodes.length>0||t.inner.hasAttribute("data-db-react-content"));n(this,["designbase-wc-tabs",`designbase-wc-tabs--${this.orientation}`,`designbase-wc-tabs--${this.size}`,`designbase-wc-tabs--${this.variant}`,this.fullWidth&&"designbase-wc-tabs--full-width",!f&&"designbase-wc-tabs--nav-only"]);for(const[t,e]of c){const i=f&&t===a;e.panel.hidden=!i,e.panel.inert=!i,e.panel.setAttribute("aria-hidden",String(!i)),f?e.button.setAttribute("aria-controls",e.panel.id):e.button.removeAttribute("aria-controls")}this.focusedKey&&this.records.has(this.focusedKey)&&!this.records.get(this.focusedKey)?.button.disabled||(this.focusedKey=a),this.list.contains(o)||(this.focusedKey=a),this.syncRoving(),this.reflecting=!0;try{this.setAttribute("active-index",String(r)),a?this.setAttribute("selected-id",a):this.removeAttribute("selected-id")}finally{this.reflecting=!1}"default"===this.variant&&a?(this.indicator??(this.indicator=document.createElement("span")),this.indicator.className="designbase-wc-tabs__indicator designbase-wc-tabs__indicator--no-transition",this.indicator.setAttribute("aria-hidden","true"),this.indicator.parentElement!==this.list&&this.list.append(this.indicator)):this.indicator?.remove(),o instanceof HTMLElement&&l>=0&&(document.activeElement!==o||o.closest("[inert]")||o instanceof HTMLButtonElement&&o.disabled)&&(!o.isConnected||o.closest("[inert]")||o instanceof HTMLButtonElement&&o.disabled?this.records.get(a)?.button.focus({preventScroll:!0}):o.focus({preventScroll:!0})),this.handleResize()}finally{this.rendering=!1}this.dispatchEvent(new Event("db-content-targets-change"))}}syncRoving(){for(const[t,e]of this.records)e.button.tabIndex=e.button.disabled||t!==this.focusedKey?-1:0}select(t){if(this.suppressClick)return;const e=this.entries().find(e=>e.key===t);e&&!e.item.disabled&&(this.focusedKey=t,this.syncRoving(),t!==this.selectedId&&(this.selectedId=t,this.dispatchEvent(new CustomEvent("db-change",{detail:{index:e.index,label:e.item.label,id:t},bubbles:!0,composed:!0})),this.ensureVisible(this.records.get(t).button)))}navigate(t,e){if(t.altKey||t.ctrlKey||t.metaKey)return;const i=this.entries().filter(t=>!t.item.disabled),s=i.findIndex(t=>t.key===e);if(s<0)return;let n=s;const r="vertical"===this.orientation,a="rtl"===getComputedStyle(this).direction;if("Home"===t.key)n=0;else if("End"===t.key)n=i.length-1;else if(!r||"ArrowDown"!==t.key&&"ArrowUp"!==t.key){if(r||"ArrowRight"!==t.key&&"ArrowLeft"!==t.key)return;n=(s+("ArrowRight"===t.key!==a?1:-1)+i.length)%i.length}else n=(s+("ArrowDown"===t.key?1:-1)+i.length)%i.length;t.preventDefault();const o=this.records.get(i[n].key).button;o.focus({preventScroll:!0}),this.ensureVisible(o)}ensureVisible(t){if(!this.list)return;const e=t.getBoundingClientRect(),i=this.list.getBoundingClientRect();"horizontal"===this.orientation?this.list.scrollBy({left:e.left<i.left?e.left-i.left:e.right>i.right?e.right-i.right:0,behavior:"auto"}):this.list.scrollBy({top:e.top<i.top?e.top-i.top:e.bottom>i.bottom?e.bottom-i.bottom:0,behavior:"auto"})}endDrag(t){const e=this.drag;if(this.drag=void 0,e){this.list?.classList.remove("designbase-wc-tabs__list--dragging"),e.moved&&(this.suppressClick=!0,void 0!==this.clickTimer&&clearTimeout(this.clickTimer),this.clickTimer=window.setTimeout(()=>{this.suppressClick=!1,this.clickTimer=void 0},0));try{e.target.hasPointerCapture(e.id)&&e.target.releasePointerCapture(e.id)}catch{}t&&this.handleListScroll()}}updateIndicator(){const t=this.records.get(this.selectedId)?.button;if(!t||!this.indicator?.isConnected)return;const e="vertical"===this.orientation;this.indicator.classList.toggle("designbase-wc-tabs__indicator--vertical",e),this.indicator.classList.toggle("designbase-wc-tabs__indicator--horizontal",!e),this.indicator.classList.add("designbase-wc-tabs__indicator--ready"),this.indicator.style.width=e?"2px":`${t.offsetWidth}px`,this.indicator.style.height=e?`${t.offsetHeight}px`:"2px",this.indicator.style.transform=e?`translate3d(0, ${t.offsetTop}px, 0)`:`translate3d(${t.offsetLeft}px, 0, 0)`}}customElements.get("db-tabs")||customElements.define("db-tabs",DbTabs);export{DbTabs};
|
|
@@ -8,13 +8,25 @@ declare class DbTextarea extends HTMLElement {
|
|
|
8
8
|
private errorEl?;
|
|
9
9
|
private footerEl?;
|
|
10
10
|
private built;
|
|
11
|
+
private formState;
|
|
11
12
|
get value(): string;
|
|
12
13
|
set value(value: string);
|
|
14
|
+
get defaultValue(): string;
|
|
15
|
+
set defaultValue(value: string);
|
|
16
|
+
get name(): string;
|
|
17
|
+
set name(value: string);
|
|
18
|
+
get required(): boolean;
|
|
19
|
+
set required(value: boolean);
|
|
20
|
+
get disabled(): boolean;
|
|
21
|
+
set disabled(value: boolean);
|
|
22
|
+
get readOnly(): boolean;
|
|
23
|
+
set readOnly(value: boolean);
|
|
13
24
|
get size(): string;
|
|
14
25
|
set size(value: string);
|
|
15
26
|
connectedCallback(): void;
|
|
27
|
+
disconnectedCallback(): void;
|
|
16
28
|
attributeChangedCallback(name: string): void;
|
|
17
|
-
focus(): void;
|
|
29
|
+
focus(options?: FocusOptions): void;
|
|
18
30
|
private get showCharacterCount();
|
|
19
31
|
private get characterCountPosition();
|
|
20
32
|
private build;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{TextFieldState as t,TEXT_FIELD_ATTRIBUTES as e,upgradeTextProperties as i,textFieldDescription as s}from"../core/text-field-state.js";import{setHostClasses as a}from"../core/host-class.js";import{dbUid as r}from"../core/uid.js";import{coerceToContract as h}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TEXTAREA_SIZES as l}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTextarea extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.formState=new t(this,()=>this.updateCharacterCount()),this.handleInput=t=>{t.stopPropagation(),this.field&&(this.getAttribute("value")!==this.field.value&&this.setAttribute("value",this.field.value),this.updateCharacterCount(),this.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:this.field.value,nativeEvent:t},bubbles:!0,composed:!0})))},this.handleChange=t=>{if(t.stopPropagation(),!this.field)return;const e=this.field.value;this.getAttribute("value")!==e&&this.setAttribute("value",e),this.updateCharacterCount(),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e,nativeEvent:t},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["label","placeholder","value","default-value","name","size","rows","max-length","show-character-count","character-count-position","disabled","readonly","required","error","error-message","helper-text","full-width","resizable",...e]}get value(){return this.field?.value??this.getAttribute("value")??""}set value(t){this.setAttribute("value",t),this.field&&(this.field.value=t,this.updateCharacterCount())}get defaultValue(){return this.formState.defaultValue}set defaultValue(t){this.setAttribute("default-value",t)}get name(){return this.getAttribute("name")||""}set name(t){this.setAttribute("name",t)}get required(){return this.hasAttribute("required")}set required(t){this.toggleAttribute("required",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t)}get size(){return h(this.getAttribute("size"),l,"m")}set size(t){this.setAttribute("size",t)}connectedCallback(){i(this,["value","defaultValue","name","required","size","disabled","readOnly"]),this.built||this.build(),this.syncState()}disconnectedCallback(){this.formState.disconnect()}attributeChangedCallback(t){if(this.built){if("value"===t&&this.field){const t=this.getAttribute("value")||"";return this.field.value!==t&&(this.field.value=t),this.formState.syncValue(this.field),void this.updateCharacterCount()}this.syncState()}}focus(t){this.field?.focus(t)}get showCharacterCount(){return this.hasAttribute("show-character-count")}get characterCountPosition(){return this.getAttribute("character-count-position")||"bottom"}build(){const t=this.getAttribute("id")||r("db-textarea");this.hasAttribute("id")||this.setAttribute("id",t),this.labelEl=document.createElement("label"),this.labelEl.className="designbase-wc-textarea__label",this.labelEl.htmlFor=`${t}-field`,this.countTop=document.createElement("div"),this.countTop.className="designbase-wc-textarea__character-count designbase-wc-textarea__character-count--top",this.countTop.hidden=!0;const e=document.createElement("div");e.className="designbase-wc-textarea__wrapper",this.field=document.createElement("textarea"),this.field.id=`${t}-field`,this.field.className="designbase-wc-textarea__field",this.field.addEventListener("input",this.handleInput),this.field.addEventListener("change",this.handleChange),e.appendChild(this.field),this.footerEl=document.createElement("div"),this.footerEl.className="designbase-wc-textarea__footer",this.errorEl=document.createElement("div"),this.errorEl.className="designbase-wc-textarea__error-message",this.errorEl.setAttribute("role","alert"),this.helperEl=document.createElement("div"),this.helperEl.className="designbase-wc-textarea__helper-text",this.countBottom=document.createElement("div"),this.countBottom.className="designbase-wc-textarea__character-count designbase-wc-textarea__character-count--bottom",this.countBottom.hidden=!0,this.footerEl.append(this.errorEl,this.helperEl,this.countBottom),this.append(this.labelEl,this.countTop,e,this.footerEl),this.built=!0}syncState(){if(!this.field)return;const t=l.includes(this.size)?this.size:"m",e=this.getAttribute("label")||"",i=this.getAttribute("helper-text")||"",r=this.getAttribute("error-message")||"",h=this.hasAttribute("error"),d=this.getAttribute("value")??this.getAttribute("default-value")??"";if(a(this,["designbase-wc-textarea",`designbase-wc-textarea--${t}`,h&&"designbase-wc-textarea--error",this.hasAttribute("disabled")&&"designbase-wc-textarea--disabled",this.hasAttribute("readonly")&&"designbase-wc-textarea--readonly",this.hasAttribute("full-width")&&"designbase-wc-textarea--full-width",this.hasAttribute("rows")&&"designbase-wc-textarea--rows",this.hasAttribute("resizable")?"":"designbase-wc-textarea--not-resizable"]),this.labelEl){const t=this.hasAttribute("required")?'<span aria-hidden="true"> *</span>':"";this.labelEl.innerHTML=e?`${this.escape(e)}${t}`:"",this.labelEl.hidden=!e}this.field.placeholder=this.getAttribute("placeholder")||"",this.field.name=this.getAttribute("name")||"",this.field.value!==d&&(this.field.value=d);const n=Number(this.getAttribute("rows")||4);this.field.rows=Number.isInteger(n)&&n>0?n:4,this.field.disabled=this.hasAttribute("disabled"),this.field.readOnly=this.hasAttribute("readonly"),this.field.required=this.hasAttribute("required"),this.field.setAttribute("aria-invalid",String(h));const o=`${this.getAttribute("id")}-helper`,u=`${this.getAttribute("id")}-error`;h&&r?(this.errorEl.id=u,this.errorEl.textContent=r,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.field.setAttribute("aria-describedby",u)):i?(this.helperEl.id=o,this.helperEl.textContent=i,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.field.setAttribute("aria-describedby",o)):(this.helperEl.hidden=!0,this.errorEl.hidden=!0,this.field.removeAttribute("aria-describedby"));const c=s(this,this.field.getAttribute("aria-describedby")||"");c&&this.field.setAttribute("aria-describedby",c),this.formState.sync(this.field),this.updateCharacterCount()}updateCharacterCount(){if(!this.field||!this.countTop||!this.countBottom)return;const t=this.field.value.length,e=this.field.maxLength>=0?this.field.maxLength:null,i=null!==e&&t>e,s=`${t}${null!==e?` / ${e}`:""}`,renderCount=t=>{let e=t.querySelector(".designbase-wc-textarea__character-count-text");e||(e=document.createElement("span"),t.replaceChildren(e)),e.className="designbase-wc-textarea__character-count-text",e.classList.toggle("designbase-wc-textarea__character-count-text--error",i),e.textContent=s};this.showCharacterCount&&"top"===this.characterCountPosition?(renderCount(this.countTop),this.countTop.hidden=!1,this.countBottom.hidden=!0):this.showCharacterCount?(renderCount(this.countBottom),this.countBottom.hidden=!1,this.countTop.hidden=!0):(this.countTop.hidden=!0,this.countBottom.hidden=!0),this.footerEl&&(this.footerEl.hidden=Boolean(this.errorEl?.hidden&&this.helperEl?.hidden&&this.countBottom.hidden))}escape(t){return t.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t]||t))}}customElements.get("db-textarea")||customElements.define("db-textarea",DbTextarea);export{DbTextarea};
|
|
@@ -4,26 +4,55 @@ declare class DbToggle extends HTMLElement {
|
|
|
4
4
|
private readonly internals;
|
|
5
5
|
private root?;
|
|
6
6
|
private labelEl?;
|
|
7
|
+
private readonly labelContent;
|
|
7
8
|
private built;
|
|
8
|
-
|
|
9
|
-
private
|
|
9
|
+
private dirty;
|
|
10
|
+
private resetChecked?;
|
|
11
|
+
private awaitingInitial;
|
|
12
|
+
private formDisabled;
|
|
10
13
|
get checked(): boolean;
|
|
11
14
|
set checked(value: boolean);
|
|
15
|
+
get selected(): boolean;
|
|
16
|
+
set selected(value: boolean);
|
|
17
|
+
get defaultChecked(): boolean;
|
|
18
|
+
set defaultChecked(value: boolean);
|
|
19
|
+
get defaultSelected(): boolean;
|
|
20
|
+
set defaultSelected(value: boolean);
|
|
12
21
|
get name(): string;
|
|
13
22
|
set name(value: string);
|
|
23
|
+
get label(): string;
|
|
24
|
+
set label(value: string);
|
|
25
|
+
get value(): string;
|
|
26
|
+
set value(value: string);
|
|
14
27
|
get disabled(): boolean;
|
|
15
28
|
set disabled(value: boolean);
|
|
16
29
|
get readOnly(): boolean;
|
|
17
30
|
set readOnly(value: boolean);
|
|
31
|
+
get required(): boolean;
|
|
32
|
+
set required(value: boolean);
|
|
33
|
+
get hasLabel(): boolean;
|
|
34
|
+
set hasLabel(value: boolean);
|
|
18
35
|
get size(): string;
|
|
19
36
|
set size(value: string);
|
|
20
37
|
get variant(): string;
|
|
21
38
|
set variant(value: string);
|
|
39
|
+
get form(): HTMLFormElement | null;
|
|
40
|
+
get validity(): ValidityState;
|
|
41
|
+
get validationMessage(): string;
|
|
42
|
+
get willValidate(): boolean;
|
|
43
|
+
checkValidity(): boolean;
|
|
44
|
+
reportValidity(): boolean;
|
|
45
|
+
focus(options?: FocusOptions): void;
|
|
46
|
+
private get unavailable();
|
|
47
|
+
private captureFirstChecked;
|
|
48
|
+
private setPristineChecked;
|
|
22
49
|
connectedCallback(): void;
|
|
23
|
-
|
|
50
|
+
disconnectedCallback(): void;
|
|
51
|
+
attributeChangedCallback(name: string): void;
|
|
52
|
+
formAssociatedCallback(): void;
|
|
24
53
|
formResetCallback(): void;
|
|
54
|
+
formStateRestoreCallback(state: string | File | FormData | null): void;
|
|
25
55
|
formDisabledCallback(disabled: boolean): void;
|
|
26
|
-
private get hasLabel();
|
|
27
56
|
private syncFormValue;
|
|
28
57
|
private build;
|
|
29
58
|
private handleClick;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ControlLabel as t}from"../core/control-label.js";import{t as e}from"../core/i18n.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TOGGLE_SIZES as s,TOGGLE_VARIANTS as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbToggle extends HTMLElement{constructor(){super(...arguments),this.internals=this.attachInternals(),this.labelContent=new t(this),this.built=!1,this.dirty=!1,this.awaitingInitial=!1,this.formDisabled=!1,this.handleClick=()=>{if(this.unavailable||this.readOnly)return;const t=!this.checked;this.awaitingInitial=!1,this.checked=t,this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{checked:t,selected:t},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["checked","selected","default-checked","default-selected","size","variant","disabled","readonly","has-label","name","value","label","required","aria-label","aria-labelledby","aria-describedby","aria-description","aria-invalid","tabindex"]}get checked(){return this.hasAttribute("checked")||this.hasAttribute("selected")||!this.dirty&&this.defaultChecked}set checked(t){this.captureFirstChecked(Boolean(t)),this.dirty=!0,this.removeAttribute("selected"),this.toggleAttribute("checked",Boolean(t)),this.syncState()}get selected(){return this.checked}set selected(t){this.checked=t}get defaultChecked(){return this.hasAttribute("default-checked")||this.hasAttribute("default-selected")||(this.resetChecked??!1)}set defaultChecked(t){this.awaitingInitial=!1,this.resetChecked=Boolean(t),this.removeAttribute("default-selected"),this.toggleAttribute("default-checked",Boolean(t)),this.dirty||this.setPristineChecked(Boolean(t)),this.syncState()}get defaultSelected(){return this.defaultChecked}set defaultSelected(t){this.defaultChecked=t}get name(){return this.getAttribute("name")??""}set name(t){this.setAttribute("name",t)}get label(){return this.labelContent.value}set label(t){this.setAttribute("label",t)}get value(){return this.getAttribute("value")??"on"}set value(t){this.setAttribute("value",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",Boolean(t))}get required(){return this.hasAttribute("required")}set required(t){this.toggleAttribute("required",Boolean(t))}get hasLabel(){return"false"!==this.getAttribute("has-label")}set hasLabel(t){this.setAttribute("has-label",String(Boolean(t)))}get size(){return i(this.getAttribute("size"),s,"m")}set size(t){this.setAttribute("size",t)}get variant(){return i(this.getAttribute("variant"),a,"default")}set variant(t){this.setAttribute("variant",t)}get form(){return this.internals.form}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}checkValidity(){return this.internals.checkValidity()}reportValidity(){return this.internals.reportValidity()}focus(t){this.root?.focus(t)}get unavailable(){return this.disabled||this.formDisabled}captureFirstChecked(t){this.awaitingInitial&&(this.awaitingInitial=!1,this.hasAttribute("default-checked")||this.hasAttribute("default-selected")||(this.resetChecked=t))}setPristineChecked(t){this.removeAttribute("selected"),this.toggleAttribute("checked",t),this.dirty=!1}connectedCallback(){for(const t of["defaultChecked","defaultSelected","checked","selected","name","value","label","disabled","readOnly","required","hasLabel","size","variant"]){if(!Object.prototype.hasOwnProperty.call(this,t))continue;const e=this,i=e[t];delete e[t],e[t]=i}void 0===this.resetChecked&&(this.resetChecked=this.hasAttribute("default-checked")||this.hasAttribute("default-selected")||this.hasAttribute("checked")||this.hasAttribute("selected"),this.awaitingInitial=!["checked","selected","default-checked","default-selected"].some(t=>this.hasAttribute(t))),this.style.display||(this.style.display="contents"),this.built||this.build(),this.labelContent.connect(this.labelEl,()=>this.syncState()),this.syncState()}disconnectedCallback(){this.labelContent.disconnect()}attributeChangedCallback(t){"checked"!==t&&"selected"!==t||(this.captureFirstChecked(this.hasAttribute("checked")||this.hasAttribute("selected")),this.built&&(this.dirty=!0)),"default-checked"!==t&&"default-selected"!==t||(this.resetChecked=this.hasAttribute("default-checked")||this.hasAttribute("default-selected"),this.awaitingInitial=!1,this.built&&!this.dirty&&this.setPristineChecked(this.resetChecked)),this.built&&this.syncState()}formAssociatedCallback(){this.syncFormValue()}formResetCallback(){this.awaitingInitial=!1,this.setPristineChecked(this.defaultChecked),this.syncState()}formStateRestoreCallback(t){"string"==typeof t&&(this.awaitingInitial=!1,this.checked="true"===t)}formDisabledCallback(t){this.formDisabled=t,this.syncState()}syncFormValue(){const t=this.checked;this.internals.setFormValue(t&&!this.unavailable&&this.name?this.value:null,String(t));const i=this.required&&!this.unavailable&&!this.readOnly&&!t;this.internals.setValidity(i?{valueMissing:!0}:{},i?e("required"):"",this.root)}build(){this.root=document.createElement("button"),this.root.type="button",this.root.className="designbase-wc-toggle";const t=document.createElement("span");t.className="designbase-wc-toggle__track",t.setAttribute("aria-hidden","true");const e=document.createElement("span");for(e.className="designbase-wc-toggle__thumb",t.appendChild(e),this.labelEl=document.createElement("span"),this.labelEl.className="designbase-wc-toggle__label";this.firstChild;)this.labelEl.appendChild(this.firstChild);this.root.append(t,this.labelEl),this.appendChild(this.root),this.root.addEventListener("click",this.handleClick),this.built=!0}syncState(){if(!this.root)return;this.labelContent.sync(),this.root.disabled=this.unavailable;const t=this.getAttribute("tabindex");this.root.tabIndex=this.unavailable?-1:null!==t&&/^-?\d+$/.test(t)?Number(t):0,this.root.setAttribute("role","switch"),this.root.setAttribute("aria-checked",String(this.checked)),this.readOnly?this.root.setAttribute("aria-readonly","true"):this.root.removeAttribute("aria-readonly");for(const t of["aria-label","aria-labelledby","aria-describedby","aria-description","aria-invalid"]){const e=this.getAttribute(t);null!==e?this.root.setAttribute(t,e):this.root.removeAttribute(t)}this.hasLabel||this.hasAttribute("aria-label")||this.hasAttribute("aria-labelledby")||!this.label.trim()||this.root.setAttribute("aria-label",this.label.trim()),this.required?this.root.setAttribute("aria-required","true"):this.root.removeAttribute("aria-required"),this.syncFormValue(),this.hasLabel?this.labelEl?.removeAttribute("hidden"):this.labelEl?.setAttribute("hidden",""),this.syncClasses()}syncClasses(){if(!this.root)return;const t=s.includes(this.size)?this.size:"m",e=this.hasLabel&&Boolean(this.label.trim()),i=this.checked;this.root.className=["designbase-wc-toggle",`designbase-wc-toggle--${t}`,`designbase-wc-toggle--${this.variant}`,i&&"designbase-wc-toggle--selected",this.unavailable&&"designbase-wc-toggle--disabled",this.readOnly&&"designbase-wc-toggle--readonly",!e&&"designbase-wc-toggle--no-label"].filter(Boolean).join(" "),this.root.removeAttribute("aria-pressed")}}DbToggle.formAssociated=!0,customElements.get("db-toggle")||customElements.define("db-toggle",DbToggle);export{DbToggle};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./db-button.js";import"./db-tooltip.js";import"./db-popover.js";import{isDbIconName as t,createDbIcon as e}from"./db-icons.js";import{dbUid as i}from"../core/uid.js";class DbToolButton extends HTMLElement{constructor(){super(...arguments),this.held=!1,this.menuSignature="",this.outsidePress=t=>{const e=t.composedPath();e.includes(this)||this.menu&&e.includes(this.menu)||this.closeMenu(!1)},this.menuKey=t=>{const e=Array.from(this.menu?.querySelectorAll("button:not(:disabled)")||[]),i=e.indexOf(document.activeElement);if(["ArrowDown","ArrowUp","Home","End","Escape","Tab"].includes(t.key)){if(t.stopPropagation(),"Escape"===t.key)return t.preventDefault(),void this.closeMenu();if("Tab"===t.key)return void this.closeMenu();t.preventDefault();const s="Home"===t.key?0:"End"===t.key?e.length-1:(i+("ArrowDown"===t.key?1:-1)+e.length)%e.length;e[s]?.focus()}},this.pressStart=t=>{0===t.button&&!this.disabled&&this.options.length&&(this.clearPress(),this.held=!1,this.pointer={x:t.clientX,y:t.clientY,id:t.pointerId},this.timer=setTimeout(()=>{this.held=!0,this.openMenu()},450))},this.pressEnd=()=>{this.clearPress()}}static get observedAttributes(){return["tool-id","label","icon","text","shortcut","active","toggle","disabled","options","value","menu-trigger","size","tone","placement"]}get options(){try{const t=JSON.parse(this.getAttribute("options")||"[]");return Array.isArray(t)?t.filter(t=>t&&"string"==typeof t.id&&"string"==typeof t.label):[]}catch{return[]}}set options(t){this.setAttribute("options","string"==typeof t?t:JSON.stringify(t))}get value(){return this.getAttribute("value")||""}set value(t){this.setAttribute("value",t)}get disabled(){return this.hasAttribute("disabled")}connectedCallback(){this.ensure(),this.sync()}disconnectedCallback(){this.clearPress(),this.closeMenu(!1)}attributeChangedCallback(){this.isConnected&&(this.ensure(),this.sync())}ensure(){this.button||(this.classList.add("designbase-wc-tool-button"),this.tooltip=document.createElement("db-tooltip"),this.tooltip.setAttribute("position","bottom"),this.tooltip.setAttribute("focus-target","child"),this.tooltip.setAttribute("delay","350"),this.tooltip.setAttribute("size","s"),this.button=document.createElement("db-button"),this.button.id=i("design-tool"),this.button.setAttribute("variant","ghost"),this.button.setAttribute("type","button"),this.tooltip.append(this.button),this.menuPopover=document.createElement("db-popover"),this.menuPopover.setAttribute("trigger","manual"),this.menuPopover.setAttribute("open","false"),this.menuPopover.setAttribute("trigger-id",this.button.id),this.menuPopover.setAttribute("show-arrow","false"),this.menuPopover.setAttribute("size","s"),this.menuPopover.setAttribute("close-on-escape","false"),this.menuPopover.setAttribute("max-width","280"),this.menu=document.createElement("div"),this.menu.className="designbase-wc-tool-button__menu",this.menu.setAttribute("slot","content"),this.menu.setAttribute("role","menu"),this.menu.addEventListener("keydown",this.menuKey),this.menuPopover.append(this.menu),this.menuPopover.addEventListener("db-open-change",t=>{if(t.target!==this.menuPopover)return;const e=t.detail.open;this.button.setAttribute("aria-expanded",String(e)),this.tooltip.toggleAttribute("disabled",e),e||this.releaseMenuOwner()}),this.button.addEventListener("db-click",t=>{t.stopPropagation(),this.disabled||(this.held?this.held=!1:this.options.length&&"long-press"!==this.getAttribute("menu-trigger")?this.menuPopover?.open?this.closeMenu():this.openMenu():this.activate(this.options.find(t=>t.id===this.value)||this.options[0]))}),this.button.addEventListener("pointerdown",this.pressStart),this.button.addEventListener("pointerup",this.pressEnd),this.button.addEventListener("pointerleave",()=>this.clearPress()),this.button.addEventListener("pointercancel",()=>{this.held=!0,this.clearPress()}),this.button.addEventListener("pointermove",t=>{this.pointer&&Math.hypot(t.clientX-this.pointer.x,t.clientY-this.pointer.y)>8&&this.clearPress()}),this.button.addEventListener("contextmenu",t=>{this.options.length&&(t.preventDefault(),this.openMenu())}),this.button.addEventListener("keydown",t=>{const e="vertical"===this.closest("db-design-toolbar,db-context-bar")?.getAttribute("orientation");(t.key===(e?"ArrowRight":"ArrowDown")||t.altKey&&"Enter"===t.key)&&this.options.length&&(t.preventDefault(),t.stopPropagation(),this.openMenu())}),this.append(this.tooltip,this.menuPopover))}sync(){if(!this.button||!this.menu)return;const i=this.options,
|
|
1
|
+
import"./db-button.js";import"./db-tooltip.js";import"./db-popover.js";import{isDbIconName as t,createDbIcon as e}from"./db-icons.js";import{dbUid as i}from"../core/uid.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{DESIGN_TOOL_SIZES as o,POPOVER_PLACEMENTS as n,DESIGN_TOOL_TONES as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbToolButton extends HTMLElement{constructor(){super(...arguments),this.held=!1,this.menuSignature="",this.outsidePress=t=>{const e=t.composedPath();e.includes(this)||this.menu&&e.includes(this.menu)||this.closeMenu(!1)},this.menuKey=t=>{const e=Array.from(this.menu?.querySelectorAll("button:not(:disabled)")||[]),i=e.indexOf(document.activeElement);if(["ArrowDown","ArrowUp","Home","End","Escape","Tab"].includes(t.key)){if(t.stopPropagation(),"Escape"===t.key)return t.preventDefault(),void this.closeMenu();if("Tab"===t.key)return void this.closeMenu();t.preventDefault();const s="Home"===t.key?0:"End"===t.key?e.length-1:(i+("ArrowDown"===t.key?1:-1)+e.length)%e.length;e[s]?.focus()}},this.pressStart=t=>{0===t.button&&!this.disabled&&this.options.length&&(this.clearPress(),this.held=!1,this.pointer={x:t.clientX,y:t.clientY,id:t.pointerId},this.timer=setTimeout(()=>{this.held=!0,this.openMenu()},450))},this.pressEnd=()=>{this.clearPress()}}static get observedAttributes(){return["tool-id","label","icon","text","shortcut","active","toggle","disabled","options","value","menu-trigger","size","tone","placement"]}get options(){try{const t=JSON.parse(this.getAttribute("options")||"[]");return Array.isArray(t)?t.filter(t=>t&&"string"==typeof t.id&&"string"==typeof t.label):[]}catch{return[]}}set options(t){this.setAttribute("options","string"==typeof t?t:JSON.stringify(t))}get value(){return this.getAttribute("value")||""}set value(t){this.setAttribute("value",t)}get disabled(){return this.hasAttribute("disabled")}connectedCallback(){this.ensure(),this.sync()}disconnectedCallback(){this.clearPress(),this.closeMenu(!1)}attributeChangedCallback(){this.isConnected&&(this.ensure(),this.sync())}ensure(){this.button||(this.classList.add("designbase-wc-tool-button"),this.tooltip=document.createElement("db-tooltip"),this.tooltip.setAttribute("position","bottom"),this.tooltip.setAttribute("focus-target","child"),this.tooltip.setAttribute("delay","350"),this.tooltip.setAttribute("size","s"),this.button=document.createElement("db-button"),this.button.id=i("design-tool"),this.button.setAttribute("variant","ghost"),this.button.setAttribute("type","button"),this.tooltip.append(this.button),this.menuPopover=document.createElement("db-popover"),this.menuPopover.setAttribute("trigger","manual"),this.menuPopover.setAttribute("open","false"),this.menuPopover.setAttribute("trigger-id",this.button.id),this.menuPopover.setAttribute("show-arrow","false"),this.menuPopover.setAttribute("size","s"),this.menuPopover.setAttribute("close-on-escape","false"),this.menuPopover.setAttribute("max-width","280"),this.menu=document.createElement("div"),this.menu.className="designbase-wc-tool-button__menu",this.menu.setAttribute("slot","content"),this.menu.setAttribute("role","menu"),this.menu.addEventListener("keydown",this.menuKey),this.menuPopover.append(this.menu),this.menuPopover.addEventListener("db-open-change",t=>{if(t.target!==this.menuPopover)return;const e=t.detail.open;this.button.setAttribute("aria-expanded",String(e)),this.tooltip.toggleAttribute("disabled",e),e||this.releaseMenuOwner()}),this.button.addEventListener("db-click",t=>{t.stopPropagation(),this.disabled||(this.held?this.held=!1:this.options.length&&"long-press"!==this.getAttribute("menu-trigger")?this.menuPopover?.open?this.closeMenu():this.openMenu():this.activate(this.options.find(t=>t.id===this.value)||this.options[0]))}),this.button.addEventListener("pointerdown",this.pressStart),this.button.addEventListener("pointerup",this.pressEnd),this.button.addEventListener("pointerleave",()=>this.clearPress()),this.button.addEventListener("pointercancel",()=>{this.held=!0,this.clearPress()}),this.button.addEventListener("pointermove",t=>{this.pointer&&Math.hypot(t.clientX-this.pointer.x,t.clientY-this.pointer.y)>8&&this.clearPress()}),this.button.addEventListener("contextmenu",t=>{this.options.length&&(t.preventDefault(),this.openMenu())}),this.button.addEventListener("keydown",t=>{const e="vertical"===this.closest("db-design-toolbar,db-context-bar")?.getAttribute("orientation");(t.key===(e?"ArrowRight":"ArrowDown")||t.altKey&&"Enter"===t.key)&&this.options.length&&(t.preventDefault(),t.stopPropagation(),this.openMenu())}),this.append(this.tooltip,this.menuPopover))}sync(){if(!this.button||!this.menu)return;const i=this.options,u=i.find(t=>t.id===this.value),a=(this.hasAttribute("text")?this.getAttribute("label"):u?.label)||this.getAttribute("label")||"도구",h=u?.icon||this.getAttribute("icon")||"",l=u?.shortcut||this.getAttribute("shortcut"),d=`${a}${l?` · ${l}`:""}${i.length&&"long-press"===this.getAttribute("menu-trigger")?" · 길게 눌러 도구 더 보기":""}`;this.button.setAttribute("aria-label",a),this.button.setAttribute("size",s(this.getAttribute("size"),o,"m")),this.button.toggleAttribute("disabled",this.disabled),this.button.toggleAttribute("icon-only",!this.hasAttribute("text")),this.hasAttribute("toggle")||this.hasAttribute("active")?this.button.setAttribute("aria-pressed",String(this.hasAttribute("active"))):this.button.removeAttribute("aria-pressed"),this.button.dataset.toolId=this.getAttribute("tool-id")||"",i.length?(this.button.setAttribute("aria-haspopup","menu"),this.button.setAttribute("aria-expanded",String(!!this.menuPopover?.open))):(this.button.removeAttribute("aria-haspopup"),this.button.removeAttribute("aria-expanded")),this.tooltip.content=d,this.menuPopover.setAttribute("placement",s((this.getAttribute("placement")||"bottom-start").replace(/^(top|bottom)-left$/,"$1-start").replace(/^(top|bottom)-right$/,"$1-end"),n,"bottom-start")),this.menu.setAttribute("aria-label",this.getAttribute("label")||a),this.menu.dataset.tone=s(this.getAttribute("tone"),r,"default");const b=`${h}|${this.getAttribute("text")||""}|${i.length>0}`;if(this.button.dataset.signature!==b){this.button.dataset.signature=b;const s=[];if(h&&t(h)&&s.push(e(h,20)),this.hasAttribute("text")){const t=document.createElement("span");t.textContent=this.getAttribute("text"),s.push(t)}if(i.length){const t=document.createElement("span");t.className="designbase-wc-tool-button__indicator",t.setAttribute("aria-hidden","true"),s.push(t)}this.button.replaceChildren(...s)}this.disabled&&this.menuPopover?.open&&this.closeMenu(!1);const p="long-press"===this.getAttribute("menu-trigger")||!!this.value,c=JSON.stringify([i,this.value,p]);this.menuSignature!==c&&(this.menuSignature=c,this.menu.replaceChildren(),i.forEach(i=>{const s=document.createElement("button");s.type="button",s.disabled=!!i.disabled,s.setAttribute("role",p?"menuitemradio":"menuitem"),p&&s.setAttribute("aria-checked",String(i.id===this.value)),s.tabIndex=-1,i.icon&&t(i.icon)&&s.append(e(i.icon,20));const o=document.createElement("span");if(o.textContent=i.label,s.append(o),i.shortcut){const t=document.createElement("kbd");t.textContent=i.shortcut,s.append(t)}i.id===this.value&&s.append(e("done",14)),s.addEventListener("click",()=>{p&&(this.value=i.id),this.closeMenu(!0),this.activate(i)}),this.menu.append(s)}))}activate(t){this.disabled||t?.disabled||this.dispatchEvent(new CustomEvent("db-tool-action",{detail:{id:this.getAttribute("tool-id")||"",optionId:t?.id,option:t},bubbles:!0,composed:!0}))}openMenu(){if(this.disabled||!this.options.length||!this.menuPopover)return;this.clearPress();const t=DbToolButton.openMenus.get(this.ownerDocument);t&&t!==this&&t.closeMenu(!1),DbToolButton.openMenus.set(this.ownerDocument,this),this.ownerDocument.addEventListener("pointerdown",this.outsidePress,!0),this.menuPopover.open=!0,this.button?.setAttribute("aria-expanded","true"),this.tooltip?.setAttribute("disabled",""),this.focusFrame&&cancelAnimationFrame(this.focusFrame),this.focusFrame=requestAnimationFrame(()=>{this.menu?.closest('[role="dialog"]')?.setAttribute("aria-label",this.getAttribute("label")||"도구 메뉴");const t=Array.from(this.menu?.querySelectorAll("button:not(:disabled)")||[]);(t.find(t=>"true"===t.getAttribute("aria-checked"))||t[0])?.focus()})}releaseMenuOwner(){DbToolButton.openMenus.get(this.ownerDocument)===this&&DbToolButton.openMenus.delete(this.ownerDocument),this.ownerDocument.removeEventListener("pointerdown",this.outsidePress,!0)}closeMenu(t=!0){this.releaseMenuOwner(),this.focusFrame&&cancelAnimationFrame(this.focusFrame),this.menuPopover?.setAttribute("open","false"),this.button?.setAttribute("aria-expanded","false"),this.tooltip?.removeAttribute("disabled"),t&&this.button?.focus()}clearPress(){this.timer&&clearTimeout(this.timer),this.timer=void 0,this.pointer=void 0}}DbToolButton.openMenus=new WeakMap,customElements.get("db-tool-button")||customElements.define("db-tool-button",DbToolButton);export{DbToolButton};
|
|
@@ -20,41 +20,64 @@ declare class DbTwoFactor extends HTMLElement {
|
|
|
20
20
|
static get observedAttributes(): string[];
|
|
21
21
|
private built;
|
|
22
22
|
private timerId;
|
|
23
|
+
/** 코드 유효 시간(초) — SMS·이메일에서만 쓴다 */
|
|
23
24
|
private remaining;
|
|
25
|
+
/** 재전송 버튼이 다시 열리기까지 남은 시간(초) */
|
|
26
|
+
private cooldownLeft;
|
|
27
|
+
private expired;
|
|
28
|
+
private backupMode;
|
|
29
|
+
private resendCount;
|
|
30
|
+
private closeBtn;
|
|
31
|
+
private headerEl;
|
|
32
|
+
private eyebrowEl;
|
|
33
|
+
private titleEl;
|
|
34
|
+
private descEl;
|
|
24
35
|
private segment;
|
|
25
|
-
private
|
|
26
|
-
private
|
|
36
|
+
private codeBlock;
|
|
37
|
+
private codeLabelEl;
|
|
27
38
|
private timerEl;
|
|
28
|
-
private
|
|
29
|
-
private
|
|
39
|
+
private otpInput;
|
|
40
|
+
private expiredEl;
|
|
41
|
+
private backupInput;
|
|
30
42
|
private verifyBtn;
|
|
43
|
+
private resendGroup;
|
|
44
|
+
private resendHintEl;
|
|
45
|
+
private resendBtn;
|
|
31
46
|
private backupBtn;
|
|
32
|
-
private errorEl;
|
|
33
|
-
private channelActions;
|
|
34
|
-
private resendStatus;
|
|
35
|
-
private backupBlock;
|
|
36
|
-
private backupInput;
|
|
37
47
|
private backupCancelBtn;
|
|
38
|
-
private
|
|
39
|
-
private
|
|
48
|
+
private verifiedBlock;
|
|
49
|
+
private verifiedTitleEl;
|
|
50
|
+
private verifiedDescEl;
|
|
51
|
+
private doneBtn;
|
|
52
|
+
private errorEl;
|
|
40
53
|
get method(): Method;
|
|
41
54
|
set method(v: Method);
|
|
42
55
|
get size(): Size;
|
|
43
56
|
set size(v: Size);
|
|
44
57
|
get countdown(): number;
|
|
45
58
|
set countdown(v: number);
|
|
59
|
+
/** 재전송을 다시 누를 수 있기까지 기다리는 시간(초). 기본 30초. 0이면 바로 누를 수 있다. */
|
|
60
|
+
get resendCooldown(): number;
|
|
61
|
+
set resendCooldown(v: number);
|
|
46
62
|
get maxResends(): number;
|
|
63
|
+
private get usesTimer();
|
|
47
64
|
connectedCallback(): void;
|
|
48
65
|
disconnectedCallback(): void;
|
|
49
66
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
50
67
|
/** 수동 제어 모드에서 코드 발송 성공 후 카운트다운을 시작합니다. */
|
|
51
68
|
restartCountdown(): void;
|
|
69
|
+
/** 인증 완료 화면으로 전환합니다. */
|
|
70
|
+
markVerified(): void;
|
|
52
71
|
private clearTimer;
|
|
53
|
-
private
|
|
72
|
+
private startTimers;
|
|
54
73
|
private renderTimer;
|
|
74
|
+
private syncVerifyDisabled;
|
|
75
|
+
private emit;
|
|
55
76
|
private build;
|
|
56
77
|
private sync;
|
|
57
78
|
private requestVerify;
|
|
79
|
+
/** 번역 문장 안의 {0} 자리에 값을 굵게 넣는다 — 언어마다 어순이 달라 조각내 번역하지 않는다. */
|
|
80
|
+
private setTextWithValue;
|
|
58
81
|
}
|
|
59
82
|
declare global {
|
|
60
83
|
interface HTMLElementTagNameMap {
|