@designbasekorea/ui-wc 0.8.1 → 0.8.2
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 +19 -0
- package/README.md +18 -0
- package/dist/esm/components/animation-background/controls.js +1 -1
- package/dist/esm/components/animation-background/layers.js +1 -1
- package/dist/esm/components/db-activity-heatmap.d.ts +38 -0
- package/dist/esm/components/db-activity-heatmap.js +1 -0
- package/dist/esm/components/db-animation-background.d.ts +2 -0
- package/dist/esm/components/db-animation-background.js +1 -1
- package/dist/esm/components/db-app-badge.d.ts +2 -0
- package/dist/esm/components/db-app-badge.js +1 -1
- package/dist/esm/components/db-audio-player.d.ts +4 -0
- package/dist/esm/components/db-audio-player.js +1 -1
- package/dist/esm/components/db-avatar.js +1 -1
- package/dist/esm/components/db-backdrop.d.ts +4 -0
- package/dist/esm/components/db-backdrop.js +1 -1
- package/dist/esm/components/db-badge.d.ts +2 -2
- package/dist/esm/components/db-badge.js +1 -1
- package/dist/esm/components/db-bottom-navigation.js +1 -1
- package/dist/esm/components/db-bottom-sheet.d.ts +5 -0
- package/dist/esm/components/db-bottom-sheet.js +1 -1
- package/dist/esm/components/db-button.d.ts +13 -0
- package/dist/esm/components/db-button.js +1 -1
- package/dist/esm/components/db-calendar.js +1 -1
- package/dist/esm/components/db-card.js +1 -1
- package/dist/esm/components/db-carousel.js +1 -1
- package/dist/esm/components/db-chat-composer.d.ts +14 -0
- package/dist/esm/components/db-chat-composer.js +1 -1
- package/dist/esm/components/db-chat-message.d.ts +15 -2
- package/dist/esm/components/db-chat-message.js +1 -1
- package/dist/esm/components/db-chat-orb.d.ts +6 -8
- package/dist/esm/components/db-chat-orb.js +1 -1
- package/dist/esm/components/db-chat-room.d.ts +12 -1
- package/dist/esm/components/db-chat-room.js +1 -1
- package/dist/esm/components/db-chat-welcome.js +1 -1
- package/dist/esm/components/db-chat-widget.d.ts +43 -10
- package/dist/esm/components/db-chat-widget.js +1 -1
- package/dist/esm/components/db-checkbox.d.ts +11 -0
- package/dist/esm/components/db-checkbox.js +1 -1
- package/dist/esm/components/db-chip.js +1 -1
- package/dist/esm/components/db-color-picker.js +1 -1
- package/dist/esm/components/db-confirm.d.ts +5 -0
- package/dist/esm/components/db-confirm.js +1 -1
- package/dist/esm/components/db-container.js +1 -1
- package/dist/esm/components/db-cookie-banner.js +1 -1
- package/dist/esm/components/db-date-picker.d.ts +3 -0
- package/dist/esm/components/db-date-picker.js +1 -1
- package/dist/esm/components/db-divider.js +1 -1
- package/dist/esm/components/db-download-progress.d.ts +3 -4
- package/dist/esm/components/db-download-progress.js +1 -1
- package/dist/esm/components/db-drawer.d.ts +5 -1
- package/dist/esm/components/db-drawer.js +1 -1
- package/dist/esm/components/db-dropdown.js +1 -1
- package/dist/esm/components/db-dropzone.js +1 -1
- package/dist/esm/components/db-email-verify.d.ts +2 -2
- package/dist/esm/components/db-email-verify.js +1 -1
- package/dist/esm/components/db-file-uploader.js +1 -1
- package/dist/esm/components/db-floating-action-button.d.ts +1 -0
- package/dist/esm/components/db-floating-action-button.js +1 -1
- package/dist/esm/components/db-footer.js +1 -1
- package/dist/esm/components/db-gantt.js +1 -1
- package/dist/esm/components/db-indicator.js +1 -1
- package/dist/esm/components/db-input.d.ts +7 -0
- package/dist/esm/components/db-input.js +1 -1
- package/dist/esm/components/db-kanban.js +1 -1
- package/dist/esm/components/db-lightbox.d.ts +4 -0
- package/dist/esm/components/db-lightbox.js +1 -1
- package/dist/esm/components/db-list.js +1 -1
- package/dist/esm/components/db-masonry.js +1 -1
- package/dist/esm/components/db-menu-item.js +1 -1
- package/dist/esm/components/db-modal.d.ts +10 -0
- package/dist/esm/components/db-modal.js +1 -1
- package/dist/esm/components/db-navbar.d.ts +4 -2
- package/dist/esm/components/db-navbar.js +1 -1
- package/dist/esm/components/db-onboarding-modal.d.ts +3 -0
- package/dist/esm/components/db-onboarding-modal.js +1 -1
- package/dist/esm/components/db-otp-input.d.ts +3 -2
- package/dist/esm/components/db-otp-input.js +1 -1
- package/dist/esm/components/db-page-header.js +1 -1
- package/dist/esm/components/db-phone-verify.d.ts +2 -2
- package/dist/esm/components/db-phone-verify.js +1 -1
- package/dist/esm/components/db-popover.js +1 -1
- package/dist/esm/components/db-progress-step.js +1 -1
- package/dist/esm/components/db-progress.js +1 -1
- package/dist/esm/components/db-progressbar.js +1 -1
- package/dist/esm/components/db-radio.d.ts +1 -0
- package/dist/esm/components/db-radio.js +1 -1
- package/dist/esm/components/db-range-slider.d.ts +9 -4
- package/dist/esm/components/db-range-slider.js +1 -1
- package/dist/esm/components/db-rating.js +1 -1
- package/dist/esm/components/db-resizable-panels.d.ts +14 -0
- package/dist/esm/components/db-resizable-panels.js +1 -1
- package/dist/esm/components/db-search-bar.js +1 -1
- package/dist/esm/components/db-section-cta.js +1 -1
- package/dist/esm/components/db-section-feature.js +1 -1
- package/dist/esm/components/db-section-pricing.js +1 -1
- package/dist/esm/components/db-section.js +1 -1
- package/dist/esm/components/db-segment-control.js +1 -1
- package/dist/esm/components/db-select.d.ts +8 -0
- package/dist/esm/components/db-select.js +1 -1
- package/dist/esm/components/db-sidebar.d.ts +41 -6
- package/dist/esm/components/db-sidebar.js +1 -1
- package/dist/esm/components/db-skeleton.js +1 -1
- package/dist/esm/components/db-spinner.d.ts +4 -0
- package/dist/esm/components/db-spinner.js +1 -1
- package/dist/esm/components/db-split-view.js +1 -1
- package/dist/esm/components/db-stat.js +1 -1
- package/dist/esm/components/db-stepper.js +1 -1
- package/dist/esm/components/db-table.js +1 -1
- package/dist/esm/components/db-tabs.js +1 -1
- package/dist/esm/components/db-testimonial.js +1 -1
- package/dist/esm/components/db-textarea.js +1 -1
- package/dist/esm/components/db-time-picker.d.ts +5 -2
- package/dist/esm/components/db-time-picker.js +1 -1
- package/dist/esm/components/db-timeline.js +1 -1
- package/dist/esm/components/db-toast.d.ts +8 -1
- package/dist/esm/components/db-toast.js +1 -1
- package/dist/esm/components/db-toggle.d.ts +2 -0
- package/dist/esm/components/db-toggle.js +1 -1
- package/dist/esm/components/db-tooltip.js +1 -1
- package/dist/esm/components/db-top-banner.js +1 -1
- package/dist/esm/components/db-tutorial.d.ts +1 -0
- package/dist/esm/components/db-tutorial.js +1 -1
- package/dist/esm/components/db-two-factor.d.ts +2 -2
- package/dist/esm/components/db-two-factor.js +1 -1
- package/dist/esm/components/db-video-player.d.ts +3 -0
- package/dist/esm/components/db-video-player.js +1 -1
- package/dist/esm/components/section-block-header-utils.js +1 -1
- package/dist/esm/core/a11y.d.ts +40 -0
- package/dist/esm/core/a11y.js +1 -0
- package/dist/esm/core/base-element.d.ts +41 -0
- package/dist/esm/core/base-element.js +1 -0
- package/dist/esm/core/dom.d.ts +35 -0
- package/dist/esm/core/dom.js +1 -0
- package/dist/esm/core/focus-trap.d.ts +41 -0
- package/dist/esm/core/focus-trap.js +1 -0
- package/dist/esm/core/i18n.d.ts +82 -0
- package/dist/esm/core/i18n.js +1 -0
- package/dist/esm/core/scroll-lock.d.ts +19 -0
- package/dist/esm/core/scroll-lock.js +1 -0
- package/dist/esm/core/uid.d.ts +23 -0
- package/dist/esm/core/uid.js +1 -0
- package/dist/esm/helpers/toast.d.ts +10 -10
- package/dist/esm/helpers/toast.js +1 -1
- package/dist/esm/index.d.ts +12 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -0
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/primitives.js +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +583 -59
- package/dist/index.esm.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +433 -55
- package/dist/react/index.esm.js +1 -1
- package/package.json +12 -3
- /package/dist/chunks/{lottie-26a5e98f.js → lottie-3f885725.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getDbComponentIconSize as e,createDbIcon as t}from"./db-icons.js";import"./db-checkbox.js";const s=["s","m","l"];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()}connectedCallback(){this.built||this.build(),this.syncState(),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}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())}formDisabledCallback(e){this.toggleAttribute("disabled",e)}attributeChangedCallback(e){if(this.built){if("open"!==e)return"value"===e?(this.syncTrigger(),void this.syncOptions()):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")}getIconSize(){const t=this.getAttribute("size")||"m";return e(s.includes(t)?t:"m")}syncIndicatorIcons(){const e=this.getIconSize();this.clearButton?.replaceChildren(t("close",e)),this.chevronEl&&this.chevronEl.replaceChildren(t(this.open?"chevron-up":"chevron-down",e))}build(){const e=this.getAttribute("id")||`db-select-${Math.random().toString(36).slice(2)}`,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","모든 값 지우기"),this.clearButton.hidden=!0,this.clearButton.appendChild(t("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="옵션 검색",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){const s=new FormData;return e.forEach(e=>s.append(this.name||"select",e)),this.internals.setFormValue(e.length?s:null),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.internals.setFormValue(s||null),this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:s,label:i},bubbles:!0,composed:!0}))}syncState(){if(!this.trigger||!this.dropdown||!this.optionsEl)return;const e=s.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",t="top"===this.getAttribute("position")?"top":"bottom",i="full"===this.getAttribute("dropdown-width")?"full":"auto",n=Number(this.getAttribute("max-height")||200),a=this.getAttribute("label")||"",r=this.getAttribute("helper-text")||"",l=this.getAttribute("error-message")||"",h=this.hasAttribute("error"),c=this.getAttribute("id")||"";this.className=["designbase-wc-select",`designbase-wc-select--${e}`,this.open&&"designbase-wc-select--open",h&&"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"].filter(Boolean).join(" ");const o=this.parseSelectedValues();if(this.classList.toggle("designbase-wc-select--has-value",o.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.dropdown.className=["designbase-wc-select__dropdown",`designbase-wc-select__dropdown--${i}`,`designbase-wc-select__dropdown--${t}`,this.open&&"designbase-wc-select__dropdown--open"].filter(Boolean).join(" "),this.optionsEl.style.maxHeight=`${n}px`,this.searchWrap&&(this.searchWrap.hidden=!this.searchable);const d=`${c}-helper`,u=`${c}-error`;h&&l?(this.errorEl.id=u,this.errorEl.textContent=l,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.trigger.setAttribute("aria-describedby",u),this.trigger.setAttribute("aria-invalid","true")):r?(this.helperEl.id=d,this.helperEl.textContent=r,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.trigger.setAttribute("aria-describedby",d),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.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(),s=this.parseSelectedValues(),i=this.getAttribute("placeholder")||"선택하세요",n=s.length>0,a=n&&this.showClearButton&&!this.hasAttribute("disabled")&&!this.hasAttribute("readonly");if(this.valueEl.replaceChildren(),this.multiple)if(0===s.length){const e=document.createElement("span");e.className="designbase-wc-select__placeholder",e.textContent=i,this.valueEl.appendChild(e)}else{const i=document.createElement("div");i.className="designbase-wc-select__tags",s.forEach(n=>{const a=e.find(e=>e.value===n),r=document.createElement("span");r.className="designbase-wc-select__tag";const l=document.createElement("span");l.className="designbase-wc-select__tag-label",l.textContent=a?.label||n;const h=document.createElement("button");h.type="button",h.className="designbase-wc-select__tag-remove",h.setAttribute("aria-label",`${a?.label||n} 제거`),h.appendChild(t("close",12)),h.addEventListener("click",e=>{e.stopPropagation();const t=s.filter(e=>e!==n);this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t)}),r.append(l,h),i.appendChild(r)}),this.valueEl.appendChild(i)}else{const t=document.createElement("span");t.className="designbase-wc-select__single-value";const a=e.find(e=>e.value===s[0]);t.textContent=n?a?.label||s[0]:i,n||t.classList.add("designbase-wc-select__placeholder"),this.valueEl.appendChild(t)}this.clearButton.hidden=!a,this.clearButton.setAttribute("aria-hidden",a?"false":"true"),this.classList.toggle("designbase-wc-select--has-value",n)}syncOptions(){if(!this.optionsEl)return;const e=this.getFilteredOptions(),t=this.parseSelectedValues(),s=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?"검색 결과가 없습니다.":"옵션이 없습니다.",void this.optionsEl.appendChild(e)}e.forEach((e,i)=>{const n=t.includes(e.value),a=i===this.focusedIndex,r=document.createElement("div");if(r.className=["designbase-wc-select__option",n&&"designbase-wc-select__option--selected",a&&"designbase-wc-select__option--focused",e.disabled&&"designbase-wc-select__option--disabled"].filter(Boolean).join(" "),r.id=`${s}-option-${i}`,r.setAttribute("role","option"),r.setAttribute("aria-selected",String(n)),r.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"),n&&s.setAttribute("checked",""),e.disabled&&s.setAttribute("disabled",""),t.appendChild(s),r.appendChild(t)}const l=document.createElement("span");l.className="designbase-wc-select__option-label",l.textContent=e.label,r.appendChild(l),this.optionsEl.appendChild(r)}),this.focusedIndex>=0?this.trigger?.setAttribute("aria-activedescendant",`${s}-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{getDbComponentIconSize as e,createDbIcon as t}from"./db-icons.js";import"./db-checkbox.js";import{dbUid as s}from"../core/uid.js";import{labelFrom as i,t as n}from"../core/i18n.js";import{SELECT_SIZES as r,SELECT_POSITIONS as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as l}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()}connectedCallback(){this.built||this.build(),this.syncState(),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}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())}formDisabledCallback(e){this.toggleAttribute("disabled",e)}attributeChangedCallback(e){if(this.built){if("open"!==e)return"value"===e?(this.syncTrigger(),void this.syncOptions()):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")}getIconSize(){const t=this.getAttribute("size")||"m";return e(r.includes(t)?t:"m")}syncIndicatorIcons(){const e=this.getIconSize();this.clearButton?.replaceChildren(t("close",e)),this.chevronEl&&this.chevronEl.replaceChildren(t(this.open?"chevron-up":"chevron-down",e))}build(){const e=this.getAttribute("id")||s("db-select"),n=`${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",n),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",i(this,"label-clear","clearAll")),this.clearButton.hidden=!0,this.clearButton.appendChild(t("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=i(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=n,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){const s=new FormData;return e.forEach(e=>s.append(this.name||"select",e)),this.internals.setFormValue(e.length?s:null),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.internals.setFormValue(s||null),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=s("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")||n("select.placeholder");this.trigger.setAttribute("aria-label",t)}syncState(){if(!this.trigger||!this.dropdown||!this.optionsEl)return;const e=l(this.getAttribute("size"),r,"m"),t=l(this.getAttribute("position"),a,"bottom"),s="full"===this.getAttribute("dropdown-width")?"full":"auto",i=Number(this.getAttribute("max-height")||200),n=this.getAttribute("label")||"",h=this.getAttribute("helper-text")||"",c=this.getAttribute("error-message")||"",o=this.hasAttribute("error"),d=this.getAttribute("id")||"";this.className=["designbase-wc-select",`designbase-wc-select--${e}`,this.open&&"designbase-wc-select--open",o&&"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"].filter(Boolean).join(" ");const u=this.parseSelectedValues();if(this.classList.toggle("designbase-wc-select--has-value",u.length>0),this.labelEl){const e=this.hasAttribute("required")?'<span class="designbase-wc-select__required" aria-hidden="true">*</span>':"";this.labelEl.innerHTML=n?`${this.escape(n)}${e}`:"",this.labelEl.hidden=!n}this.syncAccessibleName(n),this.dropdown.className=["designbase-wc-select__dropdown",`designbase-wc-select__dropdown--${s}`,`designbase-wc-select__dropdown--${t}`,this.open&&"designbase-wc-select__dropdown--open"].filter(Boolean).join(" "),this.optionsEl.style.maxHeight=`${i}px`,this.searchWrap&&(this.searchWrap.hidden=!this.searchable);const p=`${d}-helper`,b=`${d}-error`;o&&c?(this.errorEl.id=b,this.errorEl.textContent=c,this.errorEl.hidden=!1,this.helperEl.hidden=!0,this.trigger.setAttribute("aria-describedby",b),this.trigger.setAttribute("aria-invalid","true")):h?(this.helperEl.id=p,this.helperEl.textContent=h,this.helperEl.hidden=!1,this.errorEl.hidden=!0,this.trigger.setAttribute("aria-describedby",p),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.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(),s=this.parseSelectedValues(),i=this.getAttribute("placeholder")||n("select.placeholder"),r=s.length>0,a=r&&this.showClearButton&&!this.hasAttribute("disabled")&&!this.hasAttribute("readonly");if(this.valueEl.replaceChildren(),this.multiple)if(0===s.length){const e=document.createElement("span");e.className="designbase-wc-select__placeholder",e.textContent=i,this.valueEl.appendChild(e)}else{const i=document.createElement("div");i.className="designbase-wc-select__tags",s.forEach(n=>{const r=e.find(e=>e.value===n),a=document.createElement("span");a.className="designbase-wc-select__tag";const l=document.createElement("span");l.className="designbase-wc-select__tag-label",l.textContent=r?.label||n;const h=document.createElement("button");h.type="button",h.className="designbase-wc-select__tag-remove",h.setAttribute("aria-label",`${r?.label||n} 제거`),h.appendChild(t("close",12)),h.addEventListener("click",e=>{e.stopPropagation();const t=s.filter(e=>e!==n);this.setSelectedValues(t),this.syncTrigger(),this.syncOptions(),this.dispatchChange(t)}),a.append(l,h),i.appendChild(a)}),this.valueEl.appendChild(i)}else{const t=document.createElement("span");t.className="designbase-wc-select__single-value";const n=e.find(e=>e.value===s[0]);t.textContent=r?n?.label||s[0]:i,r||t.classList.add("designbase-wc-select__placeholder"),this.valueEl.appendChild(t)}this.clearButton.hidden=!a,this.clearButton.setAttribute("aria-hidden",a?"false":"true"),this.classList.toggle("designbase-wc-select--has-value",r)}syncOptions(){if(!this.optionsEl)return;const e=this.getFilteredOptions(),t=this.parseSelectedValues(),s=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?i(this,"label-no-results","select.noResults"):i(this,"label-empty","select.noResults"),void this.optionsEl.appendChild(e)}e.forEach((e,i)=>{const n=t.includes(e.value),r=i===this.focusedIndex,a=document.createElement("div");if(a.className=["designbase-wc-select__option",n&&"designbase-wc-select__option--selected",r&&"designbase-wc-select__option--focused",e.disabled&&"designbase-wc-select__option--disabled"].filter(Boolean).join(" "),a.id=`${s}-option-${i}`,a.setAttribute("role","option"),a.setAttribute("aria-selected",String(n)),a.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"),n&&s.setAttribute("checked",""),e.disabled&&s.setAttribute("disabled",""),t.appendChild(s),a.appendChild(t)}const l=document.createElement("span");l.className="designbase-wc-select__option-label",l.textContent=e.label,a.appendChild(l),this.optionsEl.appendChild(a)}),this.focusedIndex>=0?this.trigger?.setAttribute("aria-activedescendant",`${s}-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};
|
|
@@ -13,7 +13,7 @@ interface DbSidebarItem {
|
|
|
13
13
|
selected?: boolean;
|
|
14
14
|
/** 프로필 메뉴에서 이 항목 앞에 구분선을 표시합니다. */
|
|
15
15
|
dividerBefore?: boolean;
|
|
16
|
-
/** 클릭 시 이동할 사이드바 패널 id (예: settings) */
|
|
16
|
+
/** 클릭 시 이동할 사이드바 패널 id (예: authentication, settings) */
|
|
17
17
|
openPanel?: string;
|
|
18
18
|
children?: DbSidebarItem[];
|
|
19
19
|
}
|
|
@@ -24,6 +24,20 @@ interface DbSidebarSection {
|
|
|
24
24
|
gap?: 'none' | 's' | 'm' | 'l';
|
|
25
25
|
items: DbSidebarItem[];
|
|
26
26
|
}
|
|
27
|
+
type DbSidebarPanelMode = 'auto' | 'adjacent' | 'replace';
|
|
28
|
+
interface DbSidebarPanel {
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
ariaLabel?: string;
|
|
33
|
+
backLabel?: string;
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated 레이아웃 폭은 전역 `panel-width`만 사용합니다.
|
|
36
|
+
* 패널마다 다른 폭을 주면 adjacent에서 폭이 흔들립니다.
|
|
37
|
+
*/
|
|
38
|
+
width?: number | string;
|
|
39
|
+
sections: DbSidebarSection[];
|
|
40
|
+
}
|
|
27
41
|
interface DbSidebarUserProfile {
|
|
28
42
|
name: string;
|
|
29
43
|
email?: string;
|
|
@@ -65,6 +79,9 @@ declare class DbSidebar extends HTMLElement {
|
|
|
65
79
|
private flyoutCloseTimer;
|
|
66
80
|
private userFlyoutCloseTimer;
|
|
67
81
|
private outsideHandler;
|
|
82
|
+
private panelMediaQuery;
|
|
83
|
+
private panelMediaHandler;
|
|
84
|
+
private resolvedPanelMode;
|
|
68
85
|
/**
|
|
69
86
|
* db-sidebar는 Light DOM으로 렌더링하므로 이름 있는 자식 요소를 직접 보존하고
|
|
70
87
|
* 해당 내비게이션 영역으로 이동해 슬롯처럼 투영합니다.
|
|
@@ -75,7 +92,9 @@ declare class DbSidebar extends HTMLElement {
|
|
|
75
92
|
static get observedAttributes(): string[];
|
|
76
93
|
connectedCallback(): void;
|
|
77
94
|
disconnectedCallback(): void;
|
|
78
|
-
attributeChangedCallback(name: string): void;
|
|
95
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
96
|
+
private bindPanelMediaQuery;
|
|
97
|
+
private unbindPanelMediaQuery;
|
|
79
98
|
private seedExpanded;
|
|
80
99
|
get items(): DbSidebarItem[];
|
|
81
100
|
set items(value: DbSidebarItem[] | string);
|
|
@@ -113,12 +132,27 @@ declare class DbSidebar extends HTMLElement {
|
|
|
113
132
|
set backLabel(value: string);
|
|
114
133
|
get backHref(): string;
|
|
115
134
|
set backHref(value: string);
|
|
135
|
+
get panels(): DbSidebarPanel[];
|
|
136
|
+
set panels(value: DbSidebarPanel[] | string);
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated panels를 사용하세요. 기존 settings-sections는 settings 패널로 자동 변환됩니다.
|
|
139
|
+
*/
|
|
116
140
|
get settingsSections(): DbSidebarSection[];
|
|
117
141
|
set settingsSections(value: DbSidebarSection[] | string);
|
|
118
142
|
get activePanel(): string;
|
|
119
143
|
set activePanel(value: string);
|
|
144
|
+
get panelMode(): DbSidebarPanelMode;
|
|
145
|
+
set panelMode(value: DbSidebarPanelMode);
|
|
146
|
+
get panelWidth(): string;
|
|
147
|
+
set panelWidth(value: string | number);
|
|
148
|
+
get panelBreakpoint(): number;
|
|
149
|
+
set panelBreakpoint(value: number);
|
|
150
|
+
private normalizeCssLength;
|
|
120
151
|
private parseSettingsSections;
|
|
121
|
-
private
|
|
152
|
+
private parsePanels;
|
|
153
|
+
private hasPanels;
|
|
154
|
+
private findPanel;
|
|
155
|
+
private getActivePanelConfig;
|
|
122
156
|
private parseSections;
|
|
123
157
|
private parseUserMenuItems;
|
|
124
158
|
private parseUserProfile;
|
|
@@ -139,7 +173,6 @@ declare class DbSidebar extends HTMLElement {
|
|
|
139
173
|
private setUserFlyout;
|
|
140
174
|
private scheduleUserFlyoutClose;
|
|
141
175
|
private syncHostClasses;
|
|
142
|
-
private syncActivePanelTrack;
|
|
143
176
|
private navigateToPanel;
|
|
144
177
|
private dispatchItemClick;
|
|
145
178
|
private dispatchUserMenuItemClick;
|
|
@@ -160,8 +193,10 @@ declare class DbSidebar extends HTMLElement {
|
|
|
160
193
|
private createUserDropdown;
|
|
161
194
|
private createUpdateBanner;
|
|
162
195
|
private createPromoBanner;
|
|
163
|
-
private
|
|
196
|
+
private createMainHeader;
|
|
197
|
+
private createPanelHeader;
|
|
164
198
|
private createNavWrapper;
|
|
199
|
+
private createFooter;
|
|
165
200
|
private render;
|
|
166
201
|
}
|
|
167
202
|
declare global {
|
|
@@ -171,4 +206,4 @@ declare global {
|
|
|
171
206
|
}
|
|
172
207
|
|
|
173
208
|
export { DbSidebar };
|
|
174
|
-
export type { DbSidebarItem, DbSidebarProject, DbSidebarPromoBanner, DbSidebarSection, DbSidebarUpdateBanner, DbSidebarUserProfile };
|
|
209
|
+
export type { DbSidebarItem, DbSidebarPanel, DbSidebarPanelMode, DbSidebarProject, DbSidebarPromoBanner, DbSidebarSection, DbSidebarUpdateBanner, DbSidebarUserProfile };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as e,isDbIconName as t}from"./db-icons.js";const s=["s","m","l"],a=["default","dark","light"],i=["default","wrapper"],n=["left","right"],r=["nav-top","nav","nav-bottom"];class DbSidebar extends HTMLElement{constructor(){super(...arguments),this.expandedItems=new Set,this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.flyoutCloseTimer=null,this.userFlyoutCloseTimer=null,this.outsideHandler=null}collectCustomNavSlots(){const e=new Map;return r.forEach(t=>{const s=Array.from(this.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t),a=Array.from(this.querySelectorAll(`[data-sidebar-slot="${t}"]`)).flatMap(e=>Array.from(e.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t));e.set(t,[...new Set([...s,...a])])}),e}createCustomNavSlot(e){const t=document.createElement("div");return t.className=["designbase-wc-sidebar__custom-slot",`designbase-wc-sidebar__custom-slot--${e}`].join(" "),t.dataset.sidebarSlot=e,t}projectCustomNavSlots(e){r.forEach(t=>{const s=this.querySelector(`[data-sidebar-slot="${t}"]`),a=e.get(t)??[];s&&0!==a.length?s.append(...a):s?.remove()})}static get observedAttributes(){return["items","sections","user-menu-items","user-profile","default-expanded-ids","projects","selected-project-id","project-manage-label","project-manage-href","project-section-label","project-empty-label","project-empty-trigger-label","bottom-items","bottom-sections","promo-banner","update-banner","header-type","back-label","back-href","settings-sections","active-panel","size","theme","variant","position","collapsed","collapsible","show-logo","full-height","shadow"]}connectedCallback(){this.seedExpanded(),this.render(),this.bindOutsideClick()}disconnectedCallback(){this.unbindOutsideClick(),this.cancelFlyoutClose(),this.cancelUserFlyoutClose()}attributeChangedCallback(e){if(this.isConnected){if("default-expanded-ids"===e&&this.seedExpanded(),"collapsed"===e&&this.hasAttribute("collapsed")&&(this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.cancelFlyoutClose(),this.cancelUserFlyoutClose()),"active-panel"===e&&this.querySelector(".designbase-wc-sidebar__panel-track"))return this.syncActivePanelTrack(),void this.dispatchEvent(new CustomEvent("db-panel-change",{bubbles:!0,composed:!0,detail:{panel:this.activePanel}}));this.render()}}seedExpanded(){try{const e=JSON.parse(this.getAttribute("default-expanded-ids")||"[]");Array.isArray(e)&&(this.expandedItems=new Set(e))}catch{this.expandedItems=new Set}}get items(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get sections(){return this.parseSections()}set sections(e){this.setAttribute("sections","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseUserMenuItems()}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}get projects(){return this.parseProjects()}set projects(e){this.setAttribute("projects","string"==typeof e?e:JSON.stringify(e))}get selectedProjectId(){return this.getAttribute("selected-project-id")||""}set selectedProjectId(e){e?this.setAttribute("selected-project-id",e):this.removeAttribute("selected-project-id")}get projectManageLabel(){return this.getAttribute("project-manage-label")||"프로젝트 관리"}set projectManageLabel(e){this.setAttribute("project-manage-label",e)}get projectManageHref(){return this.getAttribute("project-manage-href")||""}set projectManageHref(e){e?this.setAttribute("project-manage-href",e):this.removeAttribute("project-manage-href")}get projectSectionLabel(){return this.getAttribute("project-section-label")||"프로젝트"}set projectSectionLabel(e){this.setAttribute("project-section-label",e)}get projectEmptyLabel(){return this.getAttribute("project-empty-label")||"프로젝트를 추가해 주세요"}set projectEmptyLabel(e){this.setAttribute("project-empty-label",e)}get projectEmptyTriggerLabel(){return this.getAttribute("project-empty-trigger-label")||"프로젝트 추가"}set projectEmptyTriggerLabel(e){this.setAttribute("project-empty-trigger-label",e)}get bottomItems(){return this.parseBottomItems()}set bottomItems(e){this.setAttribute("bottom-items","string"==typeof e?e:JSON.stringify(e))}get bottomSections(){return this.parseBottomSections()}set bottomSections(e){this.setAttribute("bottom-sections","string"==typeof e?e:JSON.stringify(e))}get promoBanner(){return this.parsePromoBanner()}set promoBanner(e){null==e?this.removeAttribute("promo-banner"):this.setAttribute("promo-banner","string"==typeof e?e:JSON.stringify(e))}get updateBanner(){return this.parseUpdateBanner()}set updateBanner(e){null==e?this.removeAttribute("update-banner"):this.setAttribute("update-banner","string"==typeof e?e:JSON.stringify(e))}get headerType(){return"back"===this.getAttribute("header-type")?"back":"default"}set headerType(e){this.setAttribute("header-type",e)}get backLabel(){return this.getAttribute("back-label")||"뒤로가기"}set backLabel(e){this.setAttribute("back-label",e)}get backHref(){return this.getAttribute("back-href")||""}set backHref(e){e?this.setAttribute("back-href",e):this.removeAttribute("back-href")}get settingsSections(){return this.parseSettingsSections()}set settingsSections(e){this.setAttribute("settings-sections","string"==typeof e?e:JSON.stringify(e))}get activePanel(){return this.getAttribute("active-panel")||"main"}set activePanel(e){this.setAttribute("active-panel",e||"main")}parseSettingsSections(){try{const e=JSON.parse(this.getAttribute("settings-sections")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}hasSettingsPanel(){return this.parseSettingsSections().length>0}parseSections(){const e=this.getAttribute("sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}try{const e=JSON.parse(this.getAttribute("items")||"[]");return[{id:"main",items:Array.isArray(e)?e:[]}]}catch{return[{id:"main",items:[]}]}}parseUserMenuItems(){try{const e=JSON.parse(this.getAttribute("user-menu-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseProjects(){try{const e=JSON.parse(this.getAttribute("projects")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomItems(){try{const e=JSON.parse(this.getAttribute("bottom-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomSections(){const e=this.getAttribute("bottom-sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}const t=this.parseBottomItems();return t.length?[{id:"bottom",items:t}]:[]}parsePromoBanner(){const e=this.getAttribute("promo-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseUpdateBanner(){const e=this.getAttribute("update-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}getSelectedProject(){const e=this.parseProjects();if(!e.length)return null;const t=this.selectedProjectId;return e.find(e=>e.id===t)||e[0]}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{const t=e.target;if(this.contains(t))return;let s=!1;this.userMenuOpen&&(this.userMenuOpen=!1,this.userFlyoutItemId=null,s=!0),this.projectMenuOpen&&(this.projectMenuOpen=!1,s=!0),s&&this.render()},document.addEventListener("mousedown",this.outsideHandler))}closeOverlayMenus(){const e=this.projectMenuOpen,t=this.userMenuOpen;if(!e&&!t)return!1;this.projectMenuOpen=!1,this.userMenuOpen=!1,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.classList.remove("designbase-wc-sidebar--user-menu-open"),this.querySelector(".designbase-wc-sidebar__project-dropdown")?.remove(),this.querySelector(".designbase-wc-sidebar__project-selector")?.classList.remove("designbase-wc-sidebar__project-selector--open");const s=this.querySelector(".designbase-wc-sidebar__project-trigger");s?.setAttribute("aria-expanded","false");const a=this.querySelector(".designbase-wc-sidebar__user-dropdown");return a&&(a.hidden=!0),this.querySelector(".designbase-wc-sidebar__user-info")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.classList.remove("designbase-wc-sidebar__user-collapsed--open"),!0}syncExclusiveAccordion(e){[...Array.from(this.querySelectorAll(".designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item")),...Array.from(this.querySelectorAll(".designbase-wc-sidebar__bottom-nav .designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item"))].forEach(t=>{const s=t.getAttribute("data-item-id");s&&(e&&s===e?t.setAttribute("expanded",""):t.removeAttribute("expanded"))})}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}cancelFlyoutClose(){this.flyoutCloseTimer&&(clearTimeout(this.flyoutCloseTimer),this.flyoutCloseTimer=null)}showFlyout(e){this.cancelFlyoutClose(),this.flyoutItemId!==e&&(this.flyoutItemId=e,this.renderNav(),this.renderBottomNav())}scheduleFlyoutClose(){this.cancelFlyoutClose(),this.flyoutCloseTimer=setTimeout(()=>{this.flyoutCloseTimer=null,this.flyoutItemId=null,this.renderNav(),this.renderBottomNav()},120)}cancelUserFlyoutClose(){this.userFlyoutCloseTimer&&(clearTimeout(this.userFlyoutCloseTimer),this.userFlyoutCloseTimer=null)}setUserFlyout(e){this.cancelUserFlyoutClose(),this.userFlyoutItemId=e,this.querySelectorAll(".designbase-wc-sidebar__user-menu-item").forEach(t=>{const s=Boolean(e&&t.dataset.itemId===e);t.classList.toggle("designbase-wc-sidebar__user-menu-item--flyout-active",s),t.querySelector(".designbase-wc-sidebar__user-menu-trigger")?.setAttribute("aria-expanded",String(s));const a=t.querySelector(".designbase-wc-sidebar__user-flyout");a&&(a.hidden=!s)})}scheduleUserFlyoutClose(){this.cancelUserFlyoutClose(),this.userFlyoutCloseTimer=setTimeout(()=>{this.userFlyoutCloseTimer=null,this.setUserFlyout(null)},120)}syncHostClasses(){const e=this.getAttribute("size")||"m",t=this.getAttribute("theme")||"default",r=this.getAttribute("variant")||"default",c=this.getAttribute("position")||"left";this.className=["designbase-wc-sidebar",`designbase-wc-sidebar--${s.includes(e)?e:"m"}`,`designbase-wc-sidebar--${a.includes(t)?t:"default"}`,`designbase-wc-sidebar--${n.includes(c)?c:"left"}`,i.includes(r)&&"wrapper"===r&&"designbase-wc-sidebar--wrapper",this.hasAttribute("collapsed")&&"designbase-wc-sidebar--collapsed",this.hasAttribute("full-height")&&"designbase-wc-sidebar--full-height",this.hasAttribute("shadow")&&"designbase-wc-sidebar--shadow",this.userMenuOpen&&"designbase-wc-sidebar--user-menu-open",("back"===this.headerType||"main"!==this.activePanel)&&"designbase-wc-sidebar--header-back","main"!==this.activePanel&&"designbase-wc-sidebar--panel-settings",this.hasSettingsPanel()&&"designbase-wc-sidebar--has-panels"].filter(Boolean).join(" ")}syncActivePanelTrack(){const e=this.querySelector(".designbase-wc-sidebar__panel-track");if(!e)return;const t=this.activePanel;e.setAttribute("data-active",t),this.syncHostClasses(),this.querySelectorAll(".designbase-wc-sidebar__panel-slide").forEach(e=>{const s=e.dataset.panel===t;e.toggleAttribute("inert",!s),e.setAttribute("aria-hidden",String(!s))})}navigateToPanel(e){const t=e||"main";if(this.activePanel!==t)return this.hasAttribute("collapsed")?(this.setAttribute("active-panel",t),void this.removeAttribute("collapsed")):void this.setAttribute("active-panel",t)}dispatchItemClick(e){this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchUserMenuItemClick(e){this.dispatchEvent(new CustomEvent("db-user-menu-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchBackClick(){this.hasSettingsPanel()&&"main"!==this.activePanel&&this.navigateToPanel("main");const e=new CustomEvent("db-back-click",{bubbles:!0,composed:!0,cancelable:!0,detail:{label:this.backLabel,href:this.backHref}});this.dispatchEvent(e),!e.defaultPrevented&&this.backHref&&"main"===this.activePanel&&"back"===this.headerType&&window.location.assign(this.backHref)}dispatchProjectChange(e){this.dispatchEvent(new CustomEvent("db-project-change",{bubbles:!0,composed:!0,detail:{project:e}}))}dispatchProjectManage(){this.dispatchEvent(new CustomEvent("db-project-manage",{bubbles:!0,composed:!0,detail:{}}))}dispatchPromoCtaClick(e){this.dispatchEvent(new CustomEvent("db-promo-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}dispatchUpdateCtaClick(e){this.dispatchEvent(new CustomEvent("db-update-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}createProjectAvatar(e,t="s"){const s=document.createElement("db-avatar");if(s.className="designbase-wc-sidebar__project-avatar",s.setAttribute("size",t),s.setAttribute("initials",(e.label||"?").trim()),s.setAttribute("alt",e.label),e.color){const applyColor=()=>{const t=s.querySelector(".designbase-wc-avatar__initials");return!!t&&(t.style.backgroundColor=e.color,t.style.color="#fff",!0)},t=new MutationObserver(()=>{applyColor()&&t.disconnect()});t.observe(s,{childList:!0,subtree:!0}),queueMicrotask(()=>{applyColor()&&t.disconnect()})}return s}createProjectEmptyMark(t="s"){const s=document.createElement("span");return s.className=["designbase-wc-sidebar__project-mark",`designbase-wc-sidebar__project-mark--${t}`,"designbase-wc-sidebar__project-mark--empty"].join(" "),s.setAttribute("aria-hidden","true"),s.append(e("plus","m"===t?16:14)),s}createProjectBadge(e){if(!e.badge)return null;const t=document.createElement("db-badge");return t.className="designbase-wc-sidebar__project-badge",t.setAttribute("size","s"),t.setAttribute("variant",e.badgeColor||"warning"),t.setAttribute("badge-style","text"),t.textContent=e.badge,t}createProjectSelector(t){if(!this.hasAttribute("projects"))return null;const s=this.parseProjects(),a=0===s.length,i=this.getSelectedProject(),n=document.createElement("div");n.className=["designbase-wc-sidebar__project-selector",t&&"designbase-wc-sidebar__project-selector--collapsed",this.projectMenuOpen&&"designbase-wc-sidebar__project-selector--open",a&&"designbase-wc-sidebar__project-selector--empty"].filter(Boolean).join(" ");const r=this.getAttribute("project-section-label");if(!t&&r&&r.trim()){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-section-label",e.textContent=r.trim(),n.append(e)}const c=document.createElement("button");if(c.type="button",c.className="designbase-wc-sidebar__project-trigger",c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded",String(this.projectMenuOpen)),a||!i){if(c.setAttribute("aria-label",this.projectEmptyTriggerLabel),c.append(this.createProjectEmptyMark(t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=this.projectEmptyTriggerLabel,c.append(e)}}else if(c.setAttribute("aria-label",i.label),c.append(this.createProjectAvatar(i,t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=i.label,c.append(e)}const o=document.createElement("span");if(o.className="designbase-wc-sidebar__project-chevron",o.setAttribute("aria-hidden","true"),o.append(e("chevron-down",14)),c.append(o),c.addEventListener("click",()=>{this.projectMenuOpen=!this.projectMenuOpen,this.userMenuOpen=!1,this.render()}),n.append(c),this.projectMenuOpen){const t=document.createElement("div");if(t.className="designbase-wc-sidebar__project-dropdown",t.setAttribute("role","menu"),t.setAttribute("aria-label",this.projectSectionLabel),a){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-empty",e.setAttribute("role","presentation");const s=document.createElement("p");s.className="designbase-wc-sidebar__project-empty-text",s.textContent=this.projectEmptyLabel,e.append(s),t.append(e)}else{const e=document.createElement("ul");e.className="designbase-wc-sidebar__project-list",s.forEach(t=>{const s=document.createElement("li");s.className="designbase-wc-sidebar__project-option";const a=document.createElement("button");a.type="button",a.className=["designbase-wc-sidebar__project-option-btn",i&&t.id===i.id&&"designbase-wc-sidebar__project-option-btn--active"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a.append(this.createProjectAvatar(t,"s"));const n=document.createElement("span");n.className="designbase-wc-sidebar__project-option-label",n.textContent=t.label,a.append(n);const r=this.createProjectBadge(t);r&&a.append(r),a.addEventListener("click",()=>{this.projectMenuOpen=!1,this.setAttribute("selected-project-id",t.id),this.dispatchProjectChange(t),this.render()}),s.append(a),e.append(s)}),t.append(e)}const r=document.createElement("button");r.type="button",r.className="designbase-wc-sidebar__project-manage",r.setAttribute("role","menuitem"),r.append(e("plus",14));const c=document.createElement("span");c.textContent=this.projectManageLabel,r.append(c),r.addEventListener("click",()=>{this.projectMenuOpen=!1;const e=this.projectManageHref;e&&window.location.assign(e),this.dispatchProjectManage(),this.render()}),t.append(r),n.append(t)}return n}createFlyout(e,t){const s=this.getAttribute("position")||"left",a=document.createElement("div");a.className=["designbase-wc-sidebar__flyout","right"===s&&"designbase-wc-sidebar__flyout--align-left"].filter(Boolean).join(" "),a.setAttribute("role","menu"),a.setAttribute("aria-label",`${e.label} 하위 메뉴`),a.addEventListener("mouseenter",()=>this.cancelFlyoutClose()),a.addEventListener("mouseleave",()=>this.scheduleFlyoutClose());const i=document.createElement("div");i.className="designbase-wc-sidebar__flyout-title",i.textContent=e.label,a.append(i);const n=document.createElement("ul");return n.className="designbase-wc-sidebar__flyout-list",(e.children||[]).forEach(e=>{const s=document.createElement("li");s.className="designbase-wc-sidebar__flyout-item";const a=document.createElement("db-menu-item");a.setAttribute("label",e.label),a.setAttribute("type","block"),a.setAttribute("menu-style","dropdown"),a.setAttribute("size",t),e.href&&a.setAttribute("href",e.href),e.active&&a.setAttribute("active",""),e.disabled&&a.setAttribute("disabled",""),void 0!==e.badge&&a.setAttribute("badge",String(e.badge)),e.badgeColor&&a.setAttribute("badge-color",e.badgeColor),a.addEventListener("db-click",()=>{e.disabled||(this.flyoutItemId=null,this.dispatchItemClick(e),this.renderNav(),this.renderBottomNav())}),s.append(a),n.append(s)}),a.append(n),a}createSidebarMenuItem(e,t,s=0){const a=Boolean(e.children?.length),i=this.expandedItems.has(e.id),n=this.hasAttribute("collapsed"),r=n&&a,c=document.createElement("li");c.className=["designbase-wc-sidebar__item",r&&this.flyoutItemId===e.id&&"designbase-wc-sidebar__item--flyout-active"].filter(Boolean).join(" "),r&&(c.addEventListener("mouseenter",()=>this.showFlyout(e.id)),c.addEventListener("mouseleave",()=>this.scheduleFlyoutClose()));const o=document.createElement("db-menu-item");if(o.setAttribute("data-item-id",e.id),o.setAttribute("label",e.label),o.setAttribute("type","block"),o.setAttribute("menu-style","accordion"),o.setAttribute("size",t),o.setAttribute("depth",String(s)),e.href&&o.setAttribute("href",e.href),e.icon&&o.setAttribute("icon",e.icon),e.active&&o.setAttribute("active",""),e.disabled&&o.setAttribute("disabled",""),void 0!==e.badge&&o.setAttribute("badge",String(e.badge)),e.badgeColor&&o.setAttribute("badge-color",e.badgeColor),a&&!r&&(o.setAttribute("expandable",""),o.subItems=(e.children||[]).map(e=>({id:e.id,label:e.label,href:e.href,active:e.active,disabled:e.disabled,badge:e.badge,badgeColor:e.badgeColor})),i&&!n&&o.setAttribute("expanded","")),o.addEventListener("db-click",t=>{if(!e.disabled){if(a&&!n){const s=t.detail?.expanded??!this.expandedItems.has(e.id);return this.closeOverlayMenus(),void(s?(this.expandedItems.clear(),this.expandedItems.add(e.id),this.syncExclusiveAccordion(e.id)):(this.expandedItems.delete(e.id),this.syncExclusiveAccordion(null)))}if(r)return this.closeOverlayMenus(),void this.showFlyout(e.id);if(this.closeOverlayMenus(),e.openPanel&&this.hasSettingsPanel())return this.dispatchItemClick(e),void this.navigateToPanel(e.openPanel);this.dispatchItemClick(e)}}),o.addEventListener("db-child-click",e=>{const t=e.detail;this.dispatchItemClick(t.child)}),c.append(o),n&&void 0!==e.badge&&null!==e.badge&&""!==e.badge){const t=e.badgeColor||"primary",s=document.createElement("span");s.className=["designbase-wc-sidebar__collapsed-badge-dot",`designbase-wc-sidebar__collapsed-badge-dot--${t}`].join(" "),s.setAttribute("aria-hidden","true"),c.append(s)}if(n&&!a){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=e.label,t.setAttribute("role","tooltip"),c.append(t)}return r&&this.flyoutItemId===e.id&&c.append(this.createFlyout(e,t)),c}renderSectionList(e,t,s){const a=document.createDocumentFragment();return e.forEach(e=>{const i=document.createElement("div");if(i.className=["designbase-wc-sidebar__section",e.gap&&`designbase-wc-sidebar__section--gap-${e.gap}`].filter(Boolean).join(" "),!s&&e.title){const t=document.createElement("div");t.className="designbase-wc-sidebar__section-title",t.textContent=e.title,i.append(t)}const n=document.createElement("ul");n.className="designbase-wc-sidebar__nav-list",e.items.forEach(e=>n.append(this.createSidebarMenuItem(e,t))),i.append(n),a.append(i)}),a}renderNav(){const e=this.getAttribute("size")||"m",t=this.hasAttribute("collapsed"),s=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="main"]')||(this.hasSettingsPanel()?null:this.querySelector(".designbase-wc-sidebar__nav"));s&&s.replaceChildren(this.renderSectionList(this.parseSections(),e,t),this.createCustomNavSlot("nav"));const a=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="settings"]');a&&a.replaceChildren(this.renderSectionList(this.parseSettingsSections(),e,!1))}renderBottomNav(){const e=this.querySelector(".designbase-wc-sidebar__bottom-nav");if(!e)return;const t=this.getAttribute("size")||"m",s=this.hasAttribute("collapsed");e.replaceChildren(this.renderSectionList(this.parseBottomSections(),t,s))}createUserDropdown(s,a=!1){if(!s.length)return null;const i=this.getAttribute("position")||"left",n=document.createElement("div");n.className=["designbase-wc-sidebar__user-dropdown",a&&"designbase-wc-sidebar__user-dropdown--collapsed"].filter(Boolean).join(" "),n.setAttribute("role","menu"),n.setAttribute("aria-label","사용자 메뉴"),n.hidden=!this.userMenuOpen,n.addEventListener("keydown",e=>{"Escape"===e.key&&(e.stopPropagation(),this.userFlyoutItemId?this.setUserFlyout(null):(this.userMenuOpen=!1,this.render()))});const r=document.createElement("ul");return r.className="designbase-wc-sidebar__user-menu",s.forEach(s=>{const a=Boolean(s.children?.length),n=document.createElement("li");n.dataset.itemId=s.id,n.className=["designbase-wc-sidebar__user-menu-item",s.dividerBefore&&"designbase-wc-sidebar__user-menu-item--divider",s.disabled&&"designbase-wc-sidebar__user-menu-item--disabled",a&&"designbase-wc-sidebar__user-menu-item--has-children"].filter(Boolean).join(" ");const c=document.createElement("button");if(c.type="button",c.className="designbase-wc-sidebar__user-menu-trigger",c.setAttribute("role","menuitem"),c.disabled=Boolean(s.disabled),s.icon&&t(s.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(s.icon,16)),c.append(t)}const o=document.createElement("span");if(o.className="designbase-wc-sidebar__user-menu-label",o.textContent=s.label,c.append(o),s.value){const e=document.createElement("span");e.className="designbase-wc-sidebar__user-menu-value",e.textContent=s.value,c.append(e)}if(a){const a=document.createElement("span");a.className="designbase-wc-sidebar__user-menu-chevron",a.setAttribute("aria-hidden","true"),a.append(e("right"===i?"chevron-left":"chevron-right",16)),c.append(a),c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded",String(this.userFlyoutItemId===s.id));const openFlyout=()=>this.setUserFlyout(s.id);n.addEventListener("mouseenter",openFlyout),n.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose()),n.addEventListener("focusin",openFlyout),n.addEventListener("focusout",e=>{const t=e.relatedTarget;t&&n.contains(t)||this.scheduleUserFlyoutClose()}),c.addEventListener("click",openFlyout);const r=document.createElement("div");r.className=["designbase-wc-sidebar__user-flyout","right"===i&&"designbase-wc-sidebar__user-flyout--align-left"].filter(Boolean).join(" "),r.setAttribute("role","menu"),r.setAttribute("aria-label",`${s.label} 하위 메뉴`),r.hidden=this.userFlyoutItemId!==s.id,r.addEventListener("mouseenter",()=>this.cancelUserFlyoutClose()),r.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose());const o=document.createElement("ul");o.className="designbase-wc-sidebar__user-flyout-list",(s.children||[]).forEach(s=>{const a=document.createElement("li");a.className="designbase-wc-sidebar__user-flyout-item";const i=document.createElement("button");if(i.type="button",i.className=["designbase-wc-sidebar__user-menu-trigger","designbase-wc-sidebar__user-flyout-trigger",s.selected&&"designbase-wc-sidebar__user-flyout-trigger--selected"].filter(Boolean).join(" "),i.setAttribute("role","menuitemradio"),i.setAttribute("aria-checked",String(Boolean(s.selected))),i.disabled=Boolean(s.disabled),s.icon&&t(s.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(s.icon,16)),i.append(t)}const n=document.createElement("span");if(n.className="designbase-wc-sidebar__user-menu-label",n.textContent=s.label,i.append(n),s.selected){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-check",t.setAttribute("aria-hidden","true"),t.append(e("done",16)),i.append(t)}i.addEventListener("click",()=>{s.disabled||(this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(s),s.href&&window.location.assign(s.href),this.render())}),a.append(i),o.append(a)}),r.append(o),n.append(c,r)}else c.addEventListener("click",()=>{s.disabled||(this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(s),s.href&&window.location.assign(s.href),this.render())}),n.append(c);r.append(n)}),n.append(r),n}createUpdateBanner(e){if("back"===this.headerType)return null;const t=this.parseUpdateBanner();if(!t)return null;if(e)return null;const s=document.createElement("div");s.className="designbase-wc-sidebar__update";const a=document.createElement("db-banner");return a.className="designbase-wc-sidebar__update-banner",a.setAttribute("size","s"),a.setAttribute("variant",t.variant||"outline"),a.setAttribute("title",t.title),t.description&&a.setAttribute("description",t.description),t.icon&&a.setAttribute("icon",t.icon),a.setAttribute("clickable",""),a.setAttribute("aria-label",t.ctaLabel||t.title),a.addEventListener("db-click",()=>{t.ctaHref&&window.location.assign(t.ctaHref),this.dispatchUpdateCtaClick(t)}),s.append(a),s}createPromoBanner(s){if("back"===this.headerType)return null;const a=this.parsePromoBanner();if(!a)return null;if(s){const s=document.createElement("button");s.type="button",s.className="designbase-wc-sidebar__promo-collapsed",s.setAttribute("aria-label",a.ctaLabel||a.title);const i=document.createElement("db-animation-background");i.className="designbase-wc-sidebar__promo-bg",i.setAttribute("type","aurora"),i.setAttribute("theme","light"),i.setAttribute("intensity","subtle"),i.setAttribute("blur","40"),i.setAttribute("speed","4000"),i.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8"])),s.append(i),s.append(e(a.icon&&t(a.icon)?a.icon:"sparkle",18)),s.addEventListener("click",()=>this.dispatchPromoCtaClick(a));const n=document.createElement("span");n.className="designbase-wc-sidebar__item-tooltip",n.textContent=a.title,n.setAttribute("role","tooltip");const r=document.createElement("div");return r.className="designbase-wc-sidebar__promo-collapsed-wrap",r.append(s,n),r}const i=document.createElement("div");i.className="designbase-wc-sidebar__promo";const n=document.createElement("db-animation-background");n.className="designbase-wc-sidebar__promo-bg",n.setAttribute("type","aurora"),n.setAttribute("theme","light"),n.setAttribute("intensity","subtle"),n.setAttribute("blur","60"),n.setAttribute("speed","5000"),n.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8","#bfdbfe"])),i.append(n);const r=document.createElement("div");r.className="designbase-wc-sidebar__promo-content";const c=document.createElement("div");c.className="designbase-wc-sidebar__promo-title-row";const o=document.createElement("span");o.className="designbase-wc-sidebar__promo-icon",o.setAttribute("aria-hidden","true"),o.append(e(a.icon&&t(a.icon)?a.icon:"sparkle",16));const d=document.createElement("div");if(d.className="designbase-wc-sidebar__promo-title",d.textContent=a.title,c.append(o,d),r.append(c),a.description){const e=document.createElement("div");e.className="designbase-wc-sidebar__promo-desc",e.textContent=a.description,r.append(e)}if(a.ctaLabel){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__promo-action",e.setAttribute("variant","secondary"),e.setAttribute("size","s"),e.setAttribute("full-width",""),e.textContent=a.ctaLabel,e.addEventListener("db-click",()=>{a.ctaHref&&window.location.assign(a.ctaHref),this.dispatchPromoCtaClick(a)}),r.append(e)}return i.append(r),i}createHeader(t){const{mode:s,size:a,collapsible:i,showLogo:n,collapsed:r}=t,c="settings"===s||"back"===this.headerType,o="l"===a?"m":"s"===a?"xs":"s";if(!c&&!i&&(!n||r))return null;const d=document.createElement("div");if(d.className=["designbase-wc-sidebar__header",(r||!n)&&!c&&"designbase-wc-sidebar__header--collapsed-only",c&&"designbase-wc-sidebar__header--back"].filter(Boolean).join(" "),c){const t=document.createElement("button");if(t.type="button",t.className=["designbase-wc-sidebar__back",r&&"designbase-wc-sidebar__back--collapsed"].filter(Boolean).join(" "),t.setAttribute("aria-label",this.backLabel),t.append(e("chevron-left",18)),!r){const e=document.createElement("span");e.textContent=this.backLabel,t.append(e)}t.addEventListener("click",()=>this.dispatchBackClick()),d.append(t)}else if(!r&&n){const e=document.createElement("div");e.className="designbase-wc-sidebar__logo";const t=document.createElement("db-logo");t.setAttribute("type","designbase"),t.setAttribute("size",o),e.append(t),e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),d.append(e)}if(i&&"main"===s){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__toggle",e.setAttribute("variant","tertiary"),e.setAttribute("size","s"),e.setAttribute("icon-only",""),e.setAttribute("start-icon",r?"arrow-bar-right":"arrow-bar-left"),e.setAttribute("aria-label",r?"사이드바 펼치기":"사이드바 접기"),e.addEventListener("db-click",()=>{const e=!this.hasAttribute("collapsed");e?this.setAttribute("collapsed",""):this.removeAttribute("collapsed"),this.dispatchEvent(new CustomEvent("db-toggle",{bubbles:!0,composed:!0,detail:{collapsed:e}}))}),d.append(e)}return d}createNavWrapper(e){const{mode:t,collapsed:s,includeProjects:a,includeBottom:i}=e,n=document.createElement("div");if(n.className="designbase-wc-sidebar__nav-wrapper",a){const e=this.createProjectSelector(s);e&&n.append(e)}"main"===t&&n.append(this.createCustomNavSlot("nav-top"));const r=document.createElement("nav");if(r.className="designbase-wc-sidebar__nav",r.setAttribute("data-panel-nav",t),r.setAttribute("aria-label","settings"===t?"설정 메뉴":"주 메뉴"),n.append(r),"main"===t&&n.append(this.createCustomNavSlot("nav-bottom")),i){const e=document.createElement("nav");e.className="designbase-wc-sidebar__bottom-nav",e.setAttribute("aria-label","하단 메뉴"),n.append(e)}return n}render(){this.syncHostClasses(),this.setAttribute("role","complementary"),this.setAttribute("aria-label","사이드바 네비게이션");const t=this.getAttribute("size")||"m",s="false"!==this.getAttribute("collapsible"),a="false"!==this.getAttribute("show-logo"),i=this.hasAttribute("collapsed"),n=this.parseUserProfile(),r=this.parseUserMenuItems(),c=this.parseBottomSections(),o=this.hasSettingsPanel(),d=this.activePanel,l=this.collectCustomNavSlots();this.replaceChildren();const u=document.createElement("div");if(u.className="designbase-wc-sidebar__container",o){const e=document.createElement("div");e.className="designbase-wc-sidebar__panel-viewport";const n=document.createElement("div");n.className="designbase-wc-sidebar__panel-track",n.setAttribute("data-active",d);const r=document.createElement("div");r.className="designbase-wc-sidebar__panel-slide",r.dataset.panel="main",r.toggleAttribute("inert","main"!==d),r.setAttribute("aria-hidden",String("main"!==d));const o=this.createHeader({mode:"main",size:t,collapsible:s,showLogo:a,collapsed:i});o&&r.append(o),r.append(this.createNavWrapper({mode:"main",collapsed:i,includeProjects:!0,includeBottom:c.length>0}));const l=this.createUpdateBanner(i);l&&r.append(l);const b=this.createPromoBanner(i);b&&r.append(b);const p=document.createElement("div");p.className="designbase-wc-sidebar__panel-slide",p.dataset.panel="settings",p.toggleAttribute("inert","settings"!==d),p.setAttribute("aria-hidden",String("settings"!==d));const m=this.createHeader({mode:"settings",size:t,collapsible:!1,showLogo:!1,collapsed:!1});m&&p.append(m),p.append(this.createNavWrapper({mode:"settings",collapsed:!1,includeProjects:!1,includeBottom:!1})),n.append(r,p),e.append(n),u.append(e)}else{const e=this.createHeader({mode:"back"===this.headerType?"settings":"main",size:t,collapsible:"back"!==this.headerType&&s,showLogo:"back"!==this.headerType&&a,collapsed:i});e&&u.append(e),u.append(this.createNavWrapper({mode:"main",collapsed:i,includeProjects:"back"!==this.headerType,includeBottom:c.length>0}))}const b=document.createElement("div");if(b.className="designbase-wc-sidebar__footer",!o){const e=this.createUpdateBanner(i);e&&b.append(e);const t=this.createPromoBanner(i);t&&b.append(t)}if(n&&!i){const t=document.createElement("div");t.className="designbase-wc-sidebar__user";const s=this.createUserDropdown(r);s&&t.append(s);const a=document.createElement("div");a.className="designbase-wc-sidebar__user-info",a.setAttribute("role","button"),a.setAttribute("tabindex","0"),a.setAttribute("aria-expanded",String(this.userMenuOpen));const i=document.createElement("db-avatar");i.className="designbase-wc-sidebar__user-avatar",i.setAttribute("size","s"),i.setAttribute("initials",n.name),i.setAttribute("alt",n.name),n.avatar&&i.setAttribute("src",n.avatar);const c=document.createElement("div");c.className="designbase-wc-sidebar__user-details";const o=document.createElement("div");if(o.className="designbase-wc-sidebar__user-name",o.textContent=n.name,c.append(o),n.email){const e=document.createElement("div");e.className="designbase-wc-sidebar__user-email",e.textContent=n.email,c.append(e)}if(a.append(i,c),r.length){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-more",t.setAttribute("aria-hidden","true"),t.append(e("more-vertical",16)),a.append(t),a.setAttribute("aria-haspopup","menu")}a.addEventListener("click",()=>{r.length&&(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render())}),a.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),a.click())}),t.append(a),b.append(t)}else if(n&&i){const e=document.createElement("div");e.className=["designbase-wc-sidebar__user-collapsed",this.userMenuOpen&&"designbase-wc-sidebar__user-collapsed--open"].filter(Boolean).join(" "),e.setAttribute("role","button"),e.setAttribute("tabindex","0"),e.setAttribute("aria-label",n.name),e.setAttribute("aria-expanded",String(this.userMenuOpen)),r.length&&e.setAttribute("aria-haspopup","menu");const t=document.createElement("db-avatar");if(t.className="designbase-wc-sidebar__user-avatar-collapsed",t.setAttribute("size","s"),t.setAttribute("initials",n.name),t.setAttribute("alt",n.name),n.avatar&&t.setAttribute("src",n.avatar),e.append(t),!this.userMenuOpen){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=n.name,t.setAttribute("role","tooltip"),e.append(t)}const s=this.createUserDropdown(r,!0);s&&e.append(s),e.addEventListener("click",e=>{r.length&&(e.target.closest(".designbase-wc-sidebar__user-dropdown")||(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render()))}),e.addEventListener("keydown",t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),e.click())}),b.append(e)}u.append(b),this.append(u),this.renderNav(),this.renderBottomNav(),this.projectCustomNavSlots(l)}}customElements.get("db-sidebar")||customElements.define("db-sidebar",DbSidebar);export{DbSidebar};
|
|
1
|
+
import{createDbIcon as e,isDbIconName as t}from"./db-icons.js";import{SIDEBAR_CUSTOM_NAV_SLOTS as s,SIDEBAR_PANEL_MODES as a,SIDEBAR_SIZES as i,SIDEBAR_THEMES as n,SIDEBAR_POSITIONS as r,SIDEBAR_VARIANTS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c="240px";class DbSidebar extends HTMLElement{constructor(){super(...arguments),this.expandedItems=new Set,this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.flyoutCloseTimer=null,this.userFlyoutCloseTimer=null,this.outsideHandler=null,this.panelMediaQuery=null,this.panelMediaHandler=null,this.resolvedPanelMode="adjacent"}collectCustomNavSlots(){const e=new Map;return s.forEach(t=>{const s=Array.from(this.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t),a=Array.from(this.querySelectorAll(`[data-sidebar-slot="${t}"]`)).flatMap(e=>Array.from(e.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t));e.set(t,[...new Set([...s,...a])])}),e}createCustomNavSlot(e){const t=document.createElement("div");return t.className=["designbase-wc-sidebar__custom-slot",`designbase-wc-sidebar__custom-slot--${e}`].join(" "),t.dataset.sidebarSlot=e,t}projectCustomNavSlots(e){s.forEach(t=>{const s=this.querySelector(`[data-sidebar-slot="${t}"]`),a=e.get(t)??[];s&&0!==a.length?s.append(...a):s?.remove()})}static get observedAttributes(){return["items","sections","user-menu-items","user-profile","default-expanded-ids","projects","selected-project-id","project-manage-label","project-manage-href","project-section-label","project-empty-label","project-empty-trigger-label","bottom-items","bottom-sections","promo-banner","update-banner","header-type","back-label","back-href","panels","settings-sections","active-panel","panel-mode","panel-width","panel-breakpoint","size","theme","variant","position","collapsed","collapsible","show-logo","full-height","shadow"]}connectedCallback(){this.seedExpanded(),this.bindPanelMediaQuery(),this.render(),this.bindOutsideClick()}disconnectedCallback(){this.unbindOutsideClick(),this.unbindPanelMediaQuery(),this.cancelFlyoutClose(),this.cancelUserFlyoutClose()}attributeChangedCallback(e,t,s){if(this.isConnected&&t!==s&&("default-expanded-ids"===e&&this.seedExpanded(),"collapsed"===e&&this.hasAttribute("collapsed")&&(this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.cancelFlyoutClose(),this.cancelUserFlyoutClose()),"panel-mode"!==e&&"panel-breakpoint"!==e||this.bindPanelMediaQuery(),this.render(),"active-panel"===e)){const e=this.getActivePanelConfig();this.dispatchEvent(new CustomEvent("db-panel-change",{bubbles:!0,composed:!0,detail:{panel:e?.id??"main",panelConfig:e,mode:this.resolvedPanelMode}}))}}bindPanelMediaQuery(){this.unbindPanelMediaQuery();const e=this.panelMode;if("auto"!==e)return void(this.resolvedPanelMode=e);if("undefined"==typeof window||"function"!=typeof window.matchMedia)return void(this.resolvedPanelMode="adjacent");const t=window.matchMedia(`(min-width: ${this.panelBreakpoint}px)`);this.panelMediaQuery=t,this.resolvedPanelMode=t.matches?"adjacent":"replace",this.panelMediaHandler=e=>{const t=e.matches?"adjacent":"replace";t!==this.resolvedPanelMode&&(this.resolvedPanelMode=t,this.render(),this.dispatchEvent(new CustomEvent("db-panel-mode-change",{bubbles:!0,composed:!0,detail:{mode:t}})))},t.addEventListener("change",this.panelMediaHandler)}unbindPanelMediaQuery(){this.panelMediaQuery&&this.panelMediaHandler&&this.panelMediaQuery.removeEventListener("change",this.panelMediaHandler),this.panelMediaQuery=null,this.panelMediaHandler=null}seedExpanded(){try{const e=JSON.parse(this.getAttribute("default-expanded-ids")||"[]");Array.isArray(e)&&(this.expandedItems=new Set(e))}catch{this.expandedItems=new Set}}get items(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get sections(){return this.parseSections()}set sections(e){this.setAttribute("sections","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseUserMenuItems()}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}get projects(){return this.parseProjects()}set projects(e){this.setAttribute("projects","string"==typeof e?e:JSON.stringify(e))}get selectedProjectId(){return this.getAttribute("selected-project-id")||""}set selectedProjectId(e){e?this.setAttribute("selected-project-id",e):this.removeAttribute("selected-project-id")}get projectManageLabel(){return this.getAttribute("project-manage-label")||"프로젝트 관리"}set projectManageLabel(e){this.setAttribute("project-manage-label",e)}get projectManageHref(){return this.getAttribute("project-manage-href")||""}set projectManageHref(e){e?this.setAttribute("project-manage-href",e):this.removeAttribute("project-manage-href")}get projectSectionLabel(){return this.getAttribute("project-section-label")||"프로젝트"}set projectSectionLabel(e){this.setAttribute("project-section-label",e)}get projectEmptyLabel(){return this.getAttribute("project-empty-label")||"프로젝트를 추가해 주세요"}set projectEmptyLabel(e){this.setAttribute("project-empty-label",e)}get projectEmptyTriggerLabel(){return this.getAttribute("project-empty-trigger-label")||"프로젝트 추가"}set projectEmptyTriggerLabel(e){this.setAttribute("project-empty-trigger-label",e)}get bottomItems(){return this.parseBottomItems()}set bottomItems(e){this.setAttribute("bottom-items","string"==typeof e?e:JSON.stringify(e))}get bottomSections(){return this.parseBottomSections()}set bottomSections(e){this.setAttribute("bottom-sections","string"==typeof e?e:JSON.stringify(e))}get promoBanner(){return this.parsePromoBanner()}set promoBanner(e){null==e?this.removeAttribute("promo-banner"):this.setAttribute("promo-banner","string"==typeof e?e:JSON.stringify(e))}get updateBanner(){return this.parseUpdateBanner()}set updateBanner(e){null==e?this.removeAttribute("update-banner"):this.setAttribute("update-banner","string"==typeof e?e:JSON.stringify(e))}get headerType(){return"back"===this.getAttribute("header-type")?"back":"default"}set headerType(e){this.setAttribute("header-type",e)}get backLabel(){return this.getAttribute("back-label")||"뒤로가기"}set backLabel(e){this.setAttribute("back-label",e)}get backHref(){return this.getAttribute("back-href")||""}set backHref(e){e?this.setAttribute("back-href",e):this.removeAttribute("back-href")}get panels(){return this.parsePanels()}set panels(e){this.setAttribute("panels","string"==typeof e?e:JSON.stringify(e))}get settingsSections(){return this.parseSettingsSections()}set settingsSections(e){this.setAttribute("settings-sections","string"==typeof e?e:JSON.stringify(e))}get activePanel(){const e=this.getAttribute("active-panel")||"main";return"main"===e?"main":this.findPanel(e)?e:"main"}set activePanel(e){const t=e&&"main"!==e&&this.findPanel(e)?e:"main";this.setAttribute("active-panel",t)}get panelMode(){const e=this.getAttribute("panel-mode")||"auto";return a.includes(e)?e:"auto"}set panelMode(e){this.setAttribute("panel-mode",a.includes(e)?e:"auto")}get panelWidth(){return this.normalizeCssLength(this.getAttribute("panel-width")||c)}set panelWidth(e){this.setAttribute("panel-width",this.normalizeCssLength(e))}get panelBreakpoint(){const e=Number(this.getAttribute("panel-breakpoint"));return Number.isFinite(e)&&e>0?e:1024}set panelBreakpoint(e){const t=Number.isFinite(e)&&e>0?Math.round(e):1024;this.setAttribute("panel-breakpoint",String(t))}normalizeCssLength(e){if("number"==typeof e)return`${Math.max(0,e)}px`;const t=String(e??"").trim();return t?/^-?\d+(?:\.\d+)?$/.test(t)?`${Math.max(0,Number(t))}px`:t:c}parseSettingsSections(){try{const e=JSON.parse(this.getAttribute("settings-sections")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parsePanels(){let e=[];const t=this.getAttribute("panels");if(t)try{const s=JSON.parse(t);Array.isArray(s)&&(e=s.filter(e=>Boolean(e&&"string"==typeof e.id&&e.id.trim())).map(e=>({...e,id:e.id.trim(),title:String(e.title||e.id).trim(),sections:Array.isArray(e.sections)?e.sections:[]})))}catch{e=[]}const s=this.parseSettingsSections();return s.length&&!e.some(e=>"settings"===e.id)&&e.push({id:"settings",title:"Settings",backLabel:this.backLabel,sections:s}),e}hasPanels(){return this.parsePanels().length>0}findPanel(e){return e&&"main"!==e?this.parsePanels().find(t=>t.id===e)??null:null}getActivePanelConfig(){return this.findPanel(this.getAttribute("active-panel")||"main")}parseSections(){const e=this.getAttribute("sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}try{const e=JSON.parse(this.getAttribute("items")||"[]");return[{id:"main",items:Array.isArray(e)?e:[]}]}catch{return[{id:"main",items:[]}]}}parseUserMenuItems(){try{const e=JSON.parse(this.getAttribute("user-menu-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseProjects(){try{const e=JSON.parse(this.getAttribute("projects")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomItems(){try{const e=JSON.parse(this.getAttribute("bottom-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomSections(){const e=this.getAttribute("bottom-sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}const t=this.parseBottomItems();return t.length?[{id:"bottom",items:t}]:[]}parsePromoBanner(){const e=this.getAttribute("promo-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseUpdateBanner(){const e=this.getAttribute("update-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}getSelectedProject(){const e=this.parseProjects();if(!e.length)return null;const t=this.selectedProjectId;return e.find(e=>e.id===t)||e[0]}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{const t=e.target;if(this.contains(t))return;let s=!1;this.userMenuOpen&&(this.userMenuOpen=!1,this.userFlyoutItemId=null,s=!0),this.projectMenuOpen&&(this.projectMenuOpen=!1,s=!0),s&&this.render()},document.addEventListener("mousedown",this.outsideHandler))}closeOverlayMenus(){const e=this.projectMenuOpen,t=this.userMenuOpen;if(!e&&!t)return!1;this.projectMenuOpen=!1,this.userMenuOpen=!1,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.classList.remove("designbase-wc-sidebar--user-menu-open"),this.querySelector(".designbase-wc-sidebar__project-dropdown")?.remove(),this.querySelector(".designbase-wc-sidebar__project-selector")?.classList.remove("designbase-wc-sidebar__project-selector--open");const s=this.querySelector(".designbase-wc-sidebar__project-trigger");s?.setAttribute("aria-expanded","false");const a=this.querySelector(".designbase-wc-sidebar__user-dropdown");return a&&(a.hidden=!0),this.querySelector(".designbase-wc-sidebar__user-info")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.classList.remove("designbase-wc-sidebar__user-collapsed--open"),!0}syncExclusiveAccordion(e){[...Array.from(this.querySelectorAll(".designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item")),...Array.from(this.querySelectorAll(".designbase-wc-sidebar__bottom-nav .designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item"))].forEach(t=>{const s=t.getAttribute("data-item-id");s&&(e&&s===e?t.setAttribute("expanded",""):t.removeAttribute("expanded"))})}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}cancelFlyoutClose(){this.flyoutCloseTimer&&(clearTimeout(this.flyoutCloseTimer),this.flyoutCloseTimer=null)}showFlyout(e){this.cancelFlyoutClose(),this.flyoutItemId!==e&&(this.flyoutItemId=e,this.renderNav(),this.renderBottomNav())}scheduleFlyoutClose(){this.cancelFlyoutClose(),this.flyoutCloseTimer=setTimeout(()=>{this.flyoutCloseTimer=null,this.flyoutItemId=null,this.renderNav(),this.renderBottomNav()},120)}cancelUserFlyoutClose(){this.userFlyoutCloseTimer&&(clearTimeout(this.userFlyoutCloseTimer),this.userFlyoutCloseTimer=null)}setUserFlyout(e){this.cancelUserFlyoutClose(),this.userFlyoutItemId=e,this.querySelectorAll(".designbase-wc-sidebar__user-menu-item").forEach(t=>{const s=Boolean(e&&t.dataset.itemId===e);t.classList.toggle("designbase-wc-sidebar__user-menu-item--flyout-active",s),t.querySelector(".designbase-wc-sidebar__user-menu-trigger")?.setAttribute("aria-expanded",String(s));const a=t.querySelector(".designbase-wc-sidebar__user-flyout");a&&(a.hidden=!s)})}scheduleUserFlyoutClose(){this.cancelUserFlyoutClose(),this.userFlyoutCloseTimer=setTimeout(()=>{this.userFlyoutCloseTimer=null,this.setUserFlyout(null)},120)}syncHostClasses(){const e=this.getAttribute("size")||"m",t=this.getAttribute("theme")||"default",s=this.getAttribute("variant")||"default",a=this.getAttribute("position")||"left",c=this.getActivePanelConfig(),d=Boolean(c),l=this.panelWidth;this.style.setProperty("--db-sidebar-panel-width",l),this.className=["designbase-wc-sidebar",`designbase-wc-sidebar--${i.includes(e)?e:"m"}`,`designbase-wc-sidebar--${n.includes(t)?t:"default"}`,`designbase-wc-sidebar--${r.includes(a)?a:"left"}`,`designbase-wc-sidebar--panel-${this.resolvedPanelMode}`,o.includes(s)&&"wrapper"===s&&"designbase-wc-sidebar--wrapper",this.hasAttribute("collapsed")&&"designbase-wc-sidebar--collapsed",this.hasAttribute("full-height")&&"designbase-wc-sidebar--full-height",this.hasAttribute("shadow")&&"designbase-wc-sidebar--shadow",this.userMenuOpen&&"designbase-wc-sidebar--user-menu-open",("back"===this.headerType||d&&"replace"===this.resolvedPanelMode)&&"designbase-wc-sidebar--header-back",d&&"designbase-wc-sidebar--panel-open",this.hasPanels()&&"designbase-wc-sidebar--has-panels"].filter(Boolean).join(" ")}navigateToPanel(e){const t="main"!==e&&e?this.findPanel(e)?.id:"main";t&&this.activePanel!==t&&("main"!==t&&"replace"===this.resolvedPanelMode&&this.hasAttribute("collapsed")&&this.removeAttribute("collapsed"),this.setAttribute("active-panel",t))}dispatchItemClick(e){this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchUserMenuItemClick(e){this.dispatchEvent(new CustomEvent("db-user-menu-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchBackClick(){const e=this.getActivePanelConfig();e&&this.navigateToPanel("main");const t=new CustomEvent("db-back-click",{bubbles:!0,composed:!0,cancelable:!0,detail:{label:e?.backLabel||this.backLabel,href:this.backHref,panel:e}});this.dispatchEvent(t),t.defaultPrevented||e||!this.backHref||"back"!==this.headerType||window.location.assign(this.backHref)}dispatchProjectChange(e){this.dispatchEvent(new CustomEvent("db-project-change",{bubbles:!0,composed:!0,detail:{project:e}}))}dispatchProjectManage(){this.dispatchEvent(new CustomEvent("db-project-manage",{bubbles:!0,composed:!0,detail:{}}))}dispatchPromoCtaClick(e){this.dispatchEvent(new CustomEvent("db-promo-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}dispatchUpdateCtaClick(e){this.dispatchEvent(new CustomEvent("db-update-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}createProjectAvatar(e,t="s"){const s=document.createElement("db-avatar");if(s.className="designbase-wc-sidebar__project-avatar",s.setAttribute("size",t),s.setAttribute("initials",(e.label||"?").trim()),s.setAttribute("alt",e.label),e.color){const applyColor=()=>{const t=s.querySelector(".designbase-wc-avatar__initials");return!!t&&(t.style.backgroundColor=e.color,t.style.color="#fff",!0)},t=new MutationObserver(()=>{applyColor()&&t.disconnect()});t.observe(s,{childList:!0,subtree:!0}),queueMicrotask(()=>{applyColor()&&t.disconnect()})}return s}createProjectEmptyMark(t="s"){const s=document.createElement("span");return s.className=["designbase-wc-sidebar__project-mark",`designbase-wc-sidebar__project-mark--${t}`,"designbase-wc-sidebar__project-mark--empty"].join(" "),s.setAttribute("aria-hidden","true"),s.append(e("plus","m"===t?16:14)),s}createProjectBadge(e){if(!e.badge)return null;const t=document.createElement("db-badge");return t.className="designbase-wc-sidebar__project-badge",t.setAttribute("size","s"),t.setAttribute("variant",e.badgeColor||"warning"),t.setAttribute("type","text"),t.textContent=e.badge,t}createProjectSelector(t){if(!this.hasAttribute("projects"))return null;const s=this.parseProjects(),a=0===s.length,i=this.getSelectedProject(),n=document.createElement("div");n.className=["designbase-wc-sidebar__project-selector",t&&"designbase-wc-sidebar__project-selector--collapsed",this.projectMenuOpen&&"designbase-wc-sidebar__project-selector--open",a&&"designbase-wc-sidebar__project-selector--empty"].filter(Boolean).join(" ");const r=this.getAttribute("project-section-label");if(!t&&r&&r.trim()){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-section-label",e.textContent=r.trim(),n.append(e)}const o=document.createElement("button");if(o.type="button",o.className="designbase-wc-sidebar__project-trigger",o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-expanded",String(this.projectMenuOpen)),a||!i){if(o.setAttribute("aria-label",this.projectEmptyTriggerLabel),o.append(this.createProjectEmptyMark(t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=this.projectEmptyTriggerLabel,o.append(e)}}else if(o.setAttribute("aria-label",i.label),o.append(this.createProjectAvatar(i,t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=i.label,o.append(e)}const c=document.createElement("span");if(c.className="designbase-wc-sidebar__project-chevron",c.setAttribute("aria-hidden","true"),c.append(e("chevron-down",14)),o.append(c),o.addEventListener("click",()=>{this.projectMenuOpen=!this.projectMenuOpen,this.userMenuOpen=!1,this.render()}),n.append(o),this.projectMenuOpen){const t=document.createElement("div");if(t.className="designbase-wc-sidebar__project-dropdown",t.setAttribute("role","menu"),t.setAttribute("aria-label",this.projectSectionLabel),a){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-empty",e.setAttribute("role","presentation");const s=document.createElement("p");s.className="designbase-wc-sidebar__project-empty-text",s.textContent=this.projectEmptyLabel,e.append(s),t.append(e)}else{const e=document.createElement("ul");e.className="designbase-wc-sidebar__project-list",s.forEach(t=>{const s=document.createElement("li");s.className="designbase-wc-sidebar__project-option";const a=document.createElement("button");a.type="button",a.className=["designbase-wc-sidebar__project-option-btn",i&&t.id===i.id&&"designbase-wc-sidebar__project-option-btn--active"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a.append(this.createProjectAvatar(t,"s"));const n=document.createElement("span");n.className="designbase-wc-sidebar__project-option-label",n.textContent=t.label,a.append(n);const r=this.createProjectBadge(t);r&&a.append(r),a.addEventListener("click",()=>{this.projectMenuOpen=!1,this.setAttribute("selected-project-id",t.id),this.dispatchProjectChange(t),this.render()}),s.append(a),e.append(s)}),t.append(e)}const r=document.createElement("button");r.type="button",r.className="designbase-wc-sidebar__project-manage",r.setAttribute("role","menuitem"),r.append(e("plus",14));const o=document.createElement("span");o.textContent=this.projectManageLabel,r.append(o),r.addEventListener("click",()=>{this.projectMenuOpen=!1;const e=this.projectManageHref;e&&window.location.assign(e),this.dispatchProjectManage(),this.render()}),t.append(r),n.append(t)}return n}createFlyout(e,t){const s=this.getAttribute("position")||"left",a=document.createElement("div");a.className=["designbase-wc-sidebar__flyout","right"===s&&"designbase-wc-sidebar__flyout--align-left"].filter(Boolean).join(" "),a.setAttribute("role","menu"),a.setAttribute("aria-label",`${e.label} 하위 메뉴`),a.addEventListener("mouseenter",()=>this.cancelFlyoutClose()),a.addEventListener("mouseleave",()=>this.scheduleFlyoutClose());const i=document.createElement("div");i.className="designbase-wc-sidebar__flyout-title",i.textContent=e.label,a.append(i);const n=document.createElement("ul");return n.className="designbase-wc-sidebar__flyout-list",(e.children||[]).forEach(e=>{const s=document.createElement("li");s.className="designbase-wc-sidebar__flyout-item";const a=document.createElement("db-menu-item");a.setAttribute("label",e.label),a.setAttribute("type","block"),a.setAttribute("menu-style","dropdown"),a.setAttribute("size",t),e.href&&a.setAttribute("href",e.href),e.active&&a.setAttribute("active",""),e.disabled&&a.setAttribute("disabled",""),void 0!==e.badge&&a.setAttribute("badge",String(e.badge)),e.badgeColor&&a.setAttribute("badge-color",e.badgeColor),a.addEventListener("db-click",()=>{e.disabled||(this.flyoutItemId=null,this.dispatchItemClick(e),this.renderNav(),this.renderBottomNav())}),s.append(a),n.append(s)}),a.append(n),a}createSidebarMenuItem(e,t,s=0){const a=Boolean(e.children?.length),i=this.expandedItems.has(e.id),n=this.hasAttribute("collapsed"),r=n&&a,o=document.createElement("li");o.className=["designbase-wc-sidebar__item",r&&this.flyoutItemId===e.id&&"designbase-wc-sidebar__item--flyout-active"].filter(Boolean).join(" "),r&&(o.addEventListener("mouseenter",()=>this.showFlyout(e.id)),o.addEventListener("mouseleave",()=>this.scheduleFlyoutClose()));const c=document.createElement("db-menu-item");if(c.setAttribute("data-item-id",e.id),c.setAttribute("label",e.label),c.setAttribute("type","block"),c.setAttribute("menu-style","accordion"),c.setAttribute("size",t),c.setAttribute("depth",String(s)),e.href&&c.setAttribute("href",e.href),e.icon&&c.setAttribute("icon",e.icon),(e.active||e.openPanel&&e.openPanel===this.activePanel)&&c.setAttribute("active",""),e.disabled&&c.setAttribute("disabled",""),void 0!==e.badge&&c.setAttribute("badge",String(e.badge)),e.badgeColor&&c.setAttribute("badge-color",e.badgeColor),a&&!r&&(c.setAttribute("expandable",""),c.subItems=(e.children||[]).map(e=>({id:e.id,label:e.label,href:e.href,active:e.active,disabled:e.disabled,badge:e.badge,badgeColor:e.badgeColor})),i&&!n&&c.setAttribute("expanded","")),c.addEventListener("db-click",t=>{if(!e.disabled){if(a&&!n){const s=t.detail?.expanded??!this.expandedItems.has(e.id);return this.closeOverlayMenus(),void(s?(this.expandedItems.clear(),this.expandedItems.add(e.id),this.syncExclusiveAccordion(e.id)):(this.expandedItems.delete(e.id),this.syncExclusiveAccordion(null)))}if(r)return this.closeOverlayMenus(),void this.showFlyout(e.id);if(this.closeOverlayMenus(),e.openPanel&&this.findPanel(e.openPanel))return this.dispatchItemClick(e),void this.navigateToPanel(e.openPanel);this.dispatchItemClick(e)}}),c.addEventListener("db-child-click",e=>{const t=e.detail;this.dispatchItemClick(t.child)}),o.append(c),n&&void 0!==e.badge&&null!==e.badge&&""!==e.badge){const t=e.badgeColor||"primary",s=document.createElement("span");s.className=["designbase-wc-sidebar__collapsed-badge-dot",`designbase-wc-sidebar__collapsed-badge-dot--${t}`].join(" "),s.setAttribute("aria-hidden","true"),o.append(s)}if(n&&!a){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=e.label,t.setAttribute("role","tooltip"),o.append(t)}return r&&this.flyoutItemId===e.id&&o.append(this.createFlyout(e,t)),o}renderSectionList(e,t,s){const a=document.createDocumentFragment();return e.forEach(e=>{const i=document.createElement("div");if(i.className=["designbase-wc-sidebar__section",e.gap&&`designbase-wc-sidebar__section--gap-${e.gap}`].filter(Boolean).join(" "),!s&&e.title){const t=document.createElement("div");t.className="designbase-wc-sidebar__section-title",t.textContent=e.title,i.append(t)}const n=document.createElement("ul");n.className="designbase-wc-sidebar__nav-list",e.items.forEach(e=>n.append(this.createSidebarMenuItem(e,t))),i.append(n),a.append(i)}),a}renderNav(){const e=this.getAttribute("size")||"m",t=this.hasAttribute("collapsed"),s=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="main"]');s&&s.replaceChildren(this.renderSectionList(this.parseSections(),e,t),this.createCustomNavSlot("nav"));const a=this.getActivePanelConfig(),i=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="panel"]');i&&a&&i.replaceChildren(this.renderSectionList(a.sections,e,!1))}renderBottomNav(){const e=this.querySelector(".designbase-wc-sidebar__bottom-nav");if(!e)return;const t=this.getAttribute("size")||"m",s=this.hasAttribute("collapsed");e.replaceChildren(this.renderSectionList(this.parseBottomSections(),t,s))}createUserDropdown(s,a=!1){if(!s.length)return null;const i=this.getAttribute("position")||"left",n=document.createElement("div");n.className=["designbase-wc-sidebar__user-dropdown",a&&"designbase-wc-sidebar__user-dropdown--collapsed"].filter(Boolean).join(" "),n.setAttribute("role","menu"),n.setAttribute("aria-label","사용자 메뉴"),n.hidden=!this.userMenuOpen,n.addEventListener("keydown",e=>{"Escape"===e.key&&(e.stopPropagation(),this.userFlyoutItemId?this.setUserFlyout(null):(this.userMenuOpen=!1,this.render()))});const r=document.createElement("ul");return r.className="designbase-wc-sidebar__user-menu",s.forEach(s=>{const a=Boolean(s.children?.length),n=document.createElement("li");n.dataset.itemId=s.id,n.className=["designbase-wc-sidebar__user-menu-item",s.dividerBefore&&"designbase-wc-sidebar__user-menu-item--divider",s.disabled&&"designbase-wc-sidebar__user-menu-item--disabled",a&&"designbase-wc-sidebar__user-menu-item--has-children"].filter(Boolean).join(" ");const o=document.createElement("button");if(o.type="button",o.className="designbase-wc-sidebar__user-menu-trigger",o.setAttribute("role","menuitem"),o.disabled=Boolean(s.disabled),s.icon&&t(s.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(s.icon,16)),o.append(t)}const c=document.createElement("span");if(c.className="designbase-wc-sidebar__user-menu-label",c.textContent=s.label,o.append(c),s.value){const e=document.createElement("span");e.className="designbase-wc-sidebar__user-menu-value",e.textContent=s.value,o.append(e)}if(a){const a=document.createElement("span");a.className="designbase-wc-sidebar__user-menu-chevron",a.setAttribute("aria-hidden","true"),a.append(e("right"===i?"chevron-left":"chevron-right",16)),o.append(a),o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-expanded",String(this.userFlyoutItemId===s.id));const openFlyout=()=>this.setUserFlyout(s.id);n.addEventListener("mouseenter",openFlyout),n.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose()),n.addEventListener("focusin",openFlyout),n.addEventListener("focusout",e=>{const t=e.relatedTarget;t&&n.contains(t)||this.scheduleUserFlyoutClose()}),o.addEventListener("click",openFlyout);const r=document.createElement("div");r.className=["designbase-wc-sidebar__user-flyout","right"===i&&"designbase-wc-sidebar__user-flyout--align-left"].filter(Boolean).join(" "),r.setAttribute("role","menu"),r.setAttribute("aria-label",`${s.label} 하위 메뉴`),r.hidden=this.userFlyoutItemId!==s.id,r.addEventListener("mouseenter",()=>this.cancelUserFlyoutClose()),r.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose());const c=document.createElement("ul");c.className="designbase-wc-sidebar__user-flyout-list",(s.children||[]).forEach(s=>{const a=document.createElement("li");a.className="designbase-wc-sidebar__user-flyout-item";const i=document.createElement("button");if(i.type="button",i.className=["designbase-wc-sidebar__user-menu-trigger","designbase-wc-sidebar__user-flyout-trigger",s.selected&&"designbase-wc-sidebar__user-flyout-trigger--selected"].filter(Boolean).join(" "),i.setAttribute("role","menuitemradio"),i.setAttribute("aria-checked",String(Boolean(s.selected))),i.disabled=Boolean(s.disabled),s.icon&&t(s.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(s.icon,16)),i.append(t)}const n=document.createElement("span");if(n.className="designbase-wc-sidebar__user-menu-label",n.textContent=s.label,i.append(n),s.selected){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-check",t.setAttribute("aria-hidden","true"),t.append(e("done",16)),i.append(t)}i.addEventListener("click",()=>{s.disabled||(this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(s),s.href&&window.location.assign(s.href),this.render())}),a.append(i),c.append(a)}),r.append(c),n.append(o,r)}else o.addEventListener("click",()=>{s.disabled||(this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(s),s.href&&window.location.assign(s.href),this.render())}),n.append(o);r.append(n)}),n.append(r),n}createUpdateBanner(e){if("back"===this.headerType)return null;const t=this.parseUpdateBanner();if(!t)return null;if(e)return null;const s=document.createElement("div");s.className="designbase-wc-sidebar__update";const a=document.createElement("db-banner");return a.className="designbase-wc-sidebar__update-banner",a.setAttribute("size","s"),a.setAttribute("variant",t.variant||"outline"),a.setAttribute("title",t.title),t.description&&a.setAttribute("description",t.description),t.icon&&a.setAttribute("icon",t.icon),a.setAttribute("clickable",""),a.setAttribute("aria-label",t.ctaLabel||t.title),a.addEventListener("db-click",()=>{t.ctaHref&&window.location.assign(t.ctaHref),this.dispatchUpdateCtaClick(t)}),s.append(a),s}createPromoBanner(s){if("back"===this.headerType)return null;const a=this.parsePromoBanner();if(!a)return null;if(s){const s=document.createElement("button");s.type="button",s.className="designbase-wc-sidebar__promo-collapsed",s.setAttribute("aria-label",a.ctaLabel||a.title);const i=document.createElement("db-animation-background");i.className="designbase-wc-sidebar__promo-bg",i.setAttribute("type","aurora"),i.setAttribute("theme","light"),i.setAttribute("intensity","subtle"),i.setAttribute("blur","40"),i.setAttribute("speed","4000"),i.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8"])),s.append(i),s.append(e(a.icon&&t(a.icon)?a.icon:"sparkle",18)),s.addEventListener("click",()=>this.dispatchPromoCtaClick(a));const n=document.createElement("span");n.className="designbase-wc-sidebar__item-tooltip",n.textContent=a.title,n.setAttribute("role","tooltip");const r=document.createElement("div");return r.className="designbase-wc-sidebar__promo-collapsed-wrap",r.append(s,n),r}const i=document.createElement("div");i.className="designbase-wc-sidebar__promo";const n=document.createElement("db-animation-background");n.className="designbase-wc-sidebar__promo-bg",n.setAttribute("type","aurora"),n.setAttribute("theme","light"),n.setAttribute("intensity","subtle"),n.setAttribute("blur","60"),n.setAttribute("speed","5000"),n.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8","#bfdbfe"])),i.append(n);const r=document.createElement("div");r.className="designbase-wc-sidebar__promo-content";const o=document.createElement("div");o.className="designbase-wc-sidebar__promo-title-row";const c=document.createElement("span");c.className="designbase-wc-sidebar__promo-icon",c.setAttribute("aria-hidden","true"),c.append(e(a.icon&&t(a.icon)?a.icon:"sparkle",16));const d=document.createElement("div");if(d.className="designbase-wc-sidebar__promo-title",d.textContent=a.title,o.append(c,d),r.append(o),a.description){const e=document.createElement("div");e.className="designbase-wc-sidebar__promo-desc",e.textContent=a.description,r.append(e)}if(a.ctaLabel){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__promo-action",e.setAttribute("variant","secondary"),e.setAttribute("size","s"),e.setAttribute("full-width",""),e.textContent=a.ctaLabel,e.addEventListener("db-click",()=>{a.ctaHref&&window.location.assign(a.ctaHref),this.dispatchPromoCtaClick(a)}),r.append(e)}return i.append(r),i}createMainHeader(t){const{size:s,collapsible:a,showLogo:i,collapsed:n}=t,r="back"===this.headerType,o="l"===s?"m":"s"===s?"xs":"s";if(!r&&!a&&(!i||n))return null;const c=document.createElement("div");if(c.className=["designbase-wc-sidebar__header",(n||!i)&&!r&&"designbase-wc-sidebar__header--collapsed-only",r&&"designbase-wc-sidebar__header--back"].filter(Boolean).join(" "),r){const t=document.createElement("button");if(t.type="button",t.className=["designbase-wc-sidebar__back",n&&"designbase-wc-sidebar__back--collapsed"].filter(Boolean).join(" "),t.setAttribute("aria-label",this.backLabel),t.append(e("chevron-left",18)),!n){const e=document.createElement("span");e.textContent=this.backLabel,t.append(e)}t.addEventListener("click",()=>this.dispatchBackClick()),c.append(t)}else if(!n&&i){const e=document.createElement("div");e.className="designbase-wc-sidebar__logo";const t=document.createElement("db-logo");t.setAttribute("type","designbase"),t.setAttribute("size",o),e.append(t),e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),c.append(e)}if(a&&!r){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__toggle",e.setAttribute("variant","tertiary"),e.setAttribute("size","s"),e.setAttribute("icon-only",""),e.setAttribute("start-icon",n?"arrow-bar-right":"arrow-bar-left"),e.setAttribute("aria-label",n?"사이드바 펼치기":"사이드바 접기"),e.addEventListener("db-click",()=>{const e=!this.hasAttribute("collapsed");e?this.setAttribute("collapsed",""):this.removeAttribute("collapsed"),this.dispatchEvent(new CustomEvent("db-toggle",{bubbles:!0,composed:!0,detail:{collapsed:e}}))}),c.append(e)}return c}createPanelHeader(t){const s="replace"===this.resolvedPanelMode,a=document.createElement("div");if(a.className=["designbase-wc-sidebar__panel-header",s&&"designbase-wc-sidebar__panel-header--replace"].filter(Boolean).join(" "),s){const s=document.createElement("button");s.type="button",s.className="designbase-wc-sidebar__panel-back",s.setAttribute("aria-label",t.backLabel||this.backLabel),s.append(e("chevron-left",18)),s.addEventListener("click",()=>this.dispatchBackClick()),a.append(s)}const i=document.createElement("div");i.className="designbase-wc-sidebar__panel-heading";const n=document.createElement("div");if(n.className="designbase-wc-sidebar__panel-title",n.textContent=t.title,i.append(n),t.description){const e=document.createElement("div");e.className="designbase-wc-sidebar__panel-description",e.textContent=t.description,i.append(e)}return a.append(i),a}createNavWrapper(e){const{mode:t,collapsed:s,includeProjects:a,includeBottom:i,panel:n}=e,r=document.createElement("div");if(r.className="designbase-wc-sidebar__nav-wrapper",a){const e=this.createProjectSelector(s);e&&r.append(e)}"main"===t&&r.append(this.createCustomNavSlot("nav-top"));const o=document.createElement("nav");if(o.className="designbase-wc-sidebar__nav",o.setAttribute("data-panel-nav",t),n&&(o.dataset.panelId=n.id),o.setAttribute("aria-label",n?.ariaLabel||n?.title||"주 메뉴"),r.append(o),"main"===t&&r.append(this.createCustomNavSlot("nav-bottom")),i){const e=document.createElement("nav");e.className="designbase-wc-sidebar__bottom-nav",e.setAttribute("aria-label","하단 메뉴"),r.append(e)}return r}createFooter(t){const{collapsed:s,userProfile:a,userMenuItems:i}=t,n=document.createElement("div");n.className="designbase-wc-sidebar__footer";const r=this.createUpdateBanner(s);r&&n.append(r);const o=this.createPromoBanner(s);if(o&&n.append(o),a&&!s){const t=document.createElement("div");t.className="designbase-wc-sidebar__user";const s=this.createUserDropdown(i);s&&t.append(s);const r=document.createElement("div");r.className="designbase-wc-sidebar__user-info",r.setAttribute("role","button"),r.setAttribute("tabindex","0"),r.setAttribute("aria-expanded",String(this.userMenuOpen));const o=document.createElement("db-avatar");o.className="designbase-wc-sidebar__user-avatar",o.setAttribute("size","s"),o.setAttribute("initials",a.name),o.setAttribute("alt",a.name),a.avatar&&o.setAttribute("src",a.avatar);const c=document.createElement("div");c.className="designbase-wc-sidebar__user-details";const d=document.createElement("div");if(d.className="designbase-wc-sidebar__user-name",d.textContent=a.name,c.append(d),a.email){const e=document.createElement("div");e.className="designbase-wc-sidebar__user-email",e.textContent=a.email,c.append(e)}if(r.append(o,c),i.length){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-more",t.setAttribute("aria-hidden","true"),t.append(e("more-vertical",16)),r.append(t),r.setAttribute("aria-haspopup","menu")}r.addEventListener("click",()=>{i.length&&(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render())}),r.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),r.click())}),t.append(r),n.append(t)}else if(a&&s){const e=document.createElement("div");e.className=["designbase-wc-sidebar__user-collapsed",this.userMenuOpen&&"designbase-wc-sidebar__user-collapsed--open"].filter(Boolean).join(" "),e.setAttribute("role","button"),e.setAttribute("tabindex","0"),e.setAttribute("aria-label",a.name),e.setAttribute("aria-expanded",String(this.userMenuOpen)),i.length&&e.setAttribute("aria-haspopup","menu");const t=document.createElement("db-avatar");if(t.className="designbase-wc-sidebar__user-avatar-collapsed",t.setAttribute("size","s"),t.setAttribute("initials",a.name),t.setAttribute("alt",a.name),a.avatar&&t.setAttribute("src",a.avatar),e.append(t),!this.userMenuOpen){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=a.name,t.setAttribute("role","tooltip"),e.append(t)}const s=this.createUserDropdown(i,!0);s&&e.append(s),e.addEventListener("click",e=>{i.length&&(e.target.closest(".designbase-wc-sidebar__user-dropdown")||(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render()))}),e.addEventListener("keydown",t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),e.click())}),n.append(e)}return n}render(){const e=this.getActivePanelConfig();this.syncHostClasses(),this.setAttribute("role","complementary"),this.setAttribute("aria-label","사이드바 네비게이션");const t=this.getAttribute("size")||"m",s="false"!==this.getAttribute("collapsible"),a="false"!==this.getAttribute("show-logo"),i=this.hasAttribute("collapsed"),n=this.parseUserProfile(),r=this.parseUserMenuItems(),o=this.parseBottomSections(),c=this.collectCustomNavSlots(),d=Boolean(e),l="replace"===this.resolvedPanelMode;this.replaceChildren();const u=document.createElement("div");u.className="designbase-wc-sidebar__container";const b=document.createElement("div");b.className="designbase-wc-sidebar__panel-viewport";const p=document.createElement("div");p.className="designbase-wc-sidebar__panel-track",p.dataset.active=d&&l?"main":d?"panel":"main";const m=document.createElement("div");m.className=["designbase-wc-sidebar__panel-slide","designbase-wc-sidebar__panel-slide--main"].join(" "),m.dataset.panel="main";const h=d&&l;m.toggleAttribute("inert",h),m.setAttribute("aria-hidden",String(h));const g=this.createMainHeader({size:t,collapsible:s,showLogo:a,collapsed:i});if(g&&m.append(g),m.append(this.createNavWrapper({mode:"main",collapsed:i,includeProjects:"back"!==this.headerType,includeBottom:o.length>0})),m.append(this.createFooter({collapsed:i,userProfile:n,userMenuItems:r})),p.append(m),e){const t=document.createElement("div");t.className=["designbase-wc-sidebar__panel-slide","designbase-wc-sidebar__panel-slide--secondary"].join(" "),t.dataset.panel=e.id,t.setAttribute("aria-hidden","false"),t.append(this.createPanelHeader(e)),t.append(this.createNavWrapper({mode:"panel",collapsed:!1,includeProjects:!1,includeBottom:!1,panel:e})),p.append(t)}b.append(p),u.append(b),this.append(u),this.renderNav(),this.renderBottomNav(),this.projectCustomNavSlots(c),d&&l&&requestAnimationFrame(()=>{this.isConnected&&this.activePanel===e?.id&&(p.dataset.active="panel")})}}customElements.get("db-sidebar")||customElements.define("db-sidebar",DbSidebar);export{DbSidebar};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{SKELETON_VARIANTS as e,SKELETON_SIZES as t}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function getDefaultSize(e,t){if("circular"===e)switch(t){case"xs":return"16px";case"s":return"24px";case"l":return"48px";case"xl":return"64px";default:return"32px"}switch(t){case"xs":return"12px";case"s":return"16px";case"l":return"24px";case"xl":return"32px";default:return"20px"}}function toCssSize(e){return/^\d+$/.test(e)?`${e}px`:e}class DbSkeleton extends HTMLElement{static get observedAttributes(){return["variant","size","width","height","animation","lines","line-spacing","last-line-width","aria-label"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}render(){const s=this.getAttribute("variant")||"text",i=this.getAttribute("size")||"m",n=this.getAttribute("animation")||"pulse",r=Number(this.getAttribute("lines")||1),a=this.getAttribute("width"),l=this.getAttribute("height"),c=this.getAttribute("line-spacing")||"8px",u=this.getAttribute("last-line-width")||"60%",o=e.includes(s)?s:"text",h=t.includes(i)?i:"m",d=["designbase-wc-skeleton",`designbase-wc-skeleton--${o}`,`designbase-wc-skeleton--${h}`,`designbase-wc-skeleton--${n}`,(a||l)&&"designbase-wc-skeleton--custom-size"].filter(Boolean).join(" ");this.className!==d&&(this.className=d);const b=this.getAttribute("aria-label")??`${o} 스켈레톤 로딩 중`;if(this.getAttribute("aria-label")!==b&&this.setAttribute("aria-label",b),this.setAttribute("role","status"),this.setAttribute("aria-live","polite"),this.replaceChildren(),this.style.width=a?toCssSize(a):"circular"===o?getDefaultSize(o,h):"100%",this.style.height=l?toCssSize(l):"circular"===o?getDefaultSize(o,h):function getTextLineHeight(e){switch(e){case"xs":return"12px";case"s":return"16px";case"l":return"24px";case"xl":return"32px";default:return"20px"}}(h),"text"===o&&r>1)for(let e=1;e<r;e+=1){const t=document.createElement("div");t.className="designbase-wc-skeleton__line",t.style.marginTop=toCssSize(c),e===r-1&&(t.style.width=toCssSize(u)),this.append(t)}}}customElements.get("db-skeleton")||customElements.define("db-skeleton",DbSkeleton);export{DbSkeleton};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{SPINNER_TYPES as e,SPINNER_SIZES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbSpinner extends HTMLElement{static get observedAttributes(){return["type","size","color","speed","label","show-label"]}get type(){return this.getAttribute("type")||"circular"}set type(e){this.setAttribute("type",e)}get size(){return this.getAttribute("size")||"m"}set size(e){this.setAttribute("size",e)}get color(){return this.getAttribute("color")||""}set color(e){e?this.setAttribute("color",e):this.removeAttribute("color")}get speed(){return Number(this.getAttribute("speed")||1)}set speed(e){this.setAttribute("speed",String(e))}get label(){return this.getAttribute("label")||"로딩 중..."}set label(e){this.setAttribute("label",e)}get showLabel(){return this.hasAttribute("show-label")}set showLabel(e){this.toggleAttribute("show-label",e)}connectedCallback(){this.render()}attributeChangedCallback(){this.render()}render(){this.className=Array.from(this.classList).filter(e=>!e.startsWith("designbase-wc-spinner")).join(" "),this.classList.add("designbase-wc-spinner"),this.classList.add(`designbase-wc-spinner--${e.includes(this.type)?this.type:"circular"}`),this.classList.add(`designbase-wc-spinner--${s.includes(this.size)?this.size:"m"}`),this.setAttribute("role","status"),this.setAttribute("aria-live","polite"),this.setAttribute("aria-busy","true"),this.showLabel&&this.setAttribute("aria-label",this.label),this.style.setProperty("--spinner-speed",`${this.speed}s`),this.color?this.style.setProperty("--spinner-color",this.color):this.style.removeProperty("--spinner-color");const t=e.includes(this.type)?this.type:"circular";if(this.renderedType!==t||!this.graphicEl?.isConnected){const e=document.createElement("template");e.innerHTML=this.renderSpinner(),this.graphicEl=e.content.firstElementChild,this.renderedType=t,this.labelEl=void 0,this.replaceChildren(this.graphicEl)}Boolean(this.showLabel&&this.label)?(this.labelEl?.isConnected||(this.labelEl=document.createElement("span"),this.labelEl.className="designbase-wc-spinner__label",this.labelEl.setAttribute("aria-hidden","true"),this.append(this.labelEl)),this.labelEl.textContent=this.label):(this.labelEl?.remove(),this.labelEl=void 0)}renderSpinner(){switch(this.type){case"dots":return'<span class="designbase-wc-spinner__dots" aria-hidden="true"><span class="designbase-wc-spinner__dot"></span><span class="designbase-wc-spinner__dot"></span><span class="designbase-wc-spinner__dot"></span></span>';case"bars":return'<span class="designbase-wc-spinner__bars" aria-hidden="true"><span class="designbase-wc-spinner__bar"></span><span class="designbase-wc-spinner__bar"></span><span class="designbase-wc-spinner__bar"></span><span class="designbase-wc-spinner__bar"></span><span class="designbase-wc-spinner__bar"></span></span>';case"pulse":return'<span class="designbase-wc-spinner__pulse" aria-hidden="true"></span>';case"ripple":return'<span class="designbase-wc-spinner__ripple" aria-hidden="true"><span class="designbase-wc-spinner__ripple-circle"></span><span class="designbase-wc-spinner__ripple-circle"></span></span>';default:return'<svg class="designbase-wc-spinner__circular" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><circle class="designbase-wc-spinner__circular-track" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"></circle><circle class="designbase-wc-spinner__circular-indicator" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"></circle></svg>'}}escape(e){return e.replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[e]||e))}}customElements.get("db-spinner")||customElements.define("db-spinner",DbSpinner);export{DbSpinner};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class DbSplitView extends HTMLElement{constructor(){super(...arguments),this.panelSizes=[],this.draggingIndex=null,this.panelSources=[],this.isSyncing=!1,this.isObserving=!1,this.handleMouseDown=e=>t=>{t.preventDefault(),this.draggingIndex=e,document.body.style.cursor="horizontal"===this.getDirection()?"col-resize":"row-resize",document.body.style.userSelect="none"},this.handleMouseMove=e=>{if(null===this.draggingIndex)return;if(!this.panelSources.length)return;const t=this.getDirection(),i=this.getMode(),s=this.getSplitterSize(),n=this.getBoundingClientRect(),l=this.panelSources[this.draggingIndex];if(!l)return;const r=this.readPanelConfig(l,this.draggingIndex,this.panelSources.length);let o=this.panelSizes[this.draggingIndex];if("horizontal"===t){const t=n.width,l=e.clientX-n.left;let a=0;for(let e=0;e<this.draggingIndex;e++){const n=this.panelSizes[e];a+="fixed"===i?n:n*t,a+=s}const h=l-a;if("fixed"===i)o=Math.max(r.minSize||0,Math.min(r.maxSize||t,h));else{o=h/t;const e=r.minSize?r.minSize/t:0,i=r.maxSize?r.maxSize/t:1;o=Math.max(e,Math.min(i,o))}}else{const t=n.height,l=e.clientY-n.top;let a=0;for(let e=0;e<this.draggingIndex;e++){const n=this.panelSizes[e];a+="fixed"===i?n:n*t,a+=s}const h=l-a;if("fixed"===i)o=Math.max(r.minSize||0,Math.min(r.maxSize||t,h));else{o=h/t;const e=r.minSize?r.minSize/t:0,i=r.maxSize?r.maxSize/t:1;o=Math.max(e,Math.min(i,o))}}this.panelSizes[this.draggingIndex]=o,this.applyPanelSizes(),this.classList.toggle("designbase-wc-split-view--dragging",!0)},this.handleMouseUp=()=>{null!==this.draggingIndex&&(this.draggingIndex=null,document.body.style.cursor="",document.body.style.userSelect="",this.classList.toggle("designbase-wc-split-view--dragging",!1))}}static get observedAttributes(){return["direction","mode","splitter-size","splitter-color","splitter-hover-color","gap","full-width","full-height"]}connectedCallback(){this.style.display="flex",this.style.boxSizing="border-box",this.collectPanelSources(),this.initPanelSizes(),this.sync(),this.observer=new MutationObserver(()=>{this.isSyncing||(this.collectPanelSources(),this.initPanelSizes(),this.sync())}),this.startObserving(),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp)}disconnectedCallback(){this.stopObserving(),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),this.draggingIndex=null,document.body.style.cursor="",document.body.style.userSelect=""}startObserving(){this.observer&&!this.isObserving&&(this.observer.observe(this,{childList:!0}),this.isObserving=!0)}stopObserving(){this.observer&&this.isObserving&&(this.observer.disconnect(),this.isObserving=!1)}attributeChangedCallback(){this.isConnected&&this.sync()}collectPanelSources(){this.panelSources=[];const e=Array.from(this.querySelectorAll('[slot="panel"]'));if(e.length)return void(this.panelSources=e);const t=Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__panel > .designbase-wc-split-view__panel-body"));t.length&&(this.panelSources=t.map(e=>e.firstElementChild).filter(e=>e instanceof HTMLElement))}readPanelConfig(e,t,i){const s=e.getAttribute("data-size"),n=e.getAttribute("data-min-size"),l=e.getAttribute("data-max-size"),r=this.getMode();let o;return null!=s&&""!==s&&(o=Number(s)),{size:void 0!==o&&Number.isFinite(o)?o:"ratio"===r?1/i:200,minSize:n?Number(n):void 0,maxSize:l?Number(l):void 0,resizable:"false"!==e.getAttribute("data-resizable"),flexible:e.hasAttribute("data-flexible")||"false"!==e.getAttribute("data-flexible")&&t===i-1}}initPanelSizes(){const e=this.panelSources.length;if(!e)return;if(this.panelSizes.length===e)return;const t=this.getMode();this.panelSizes=this.panelSources.map((i,s)=>this.readPanelConfig(i,s,e).size??("ratio"===t?1/e:200))}getDirection(){return"vertical"===(this.getAttribute("direction")||"horizontal")?"vertical":"horizontal"}getMode(){return"fixed"===(this.getAttribute("mode")||"ratio")?"fixed":"ratio"}getSplitterSize(){return Number(this.getAttribute("splitter-size")||4)}getGap(){return Number(this.getAttribute("gap")||0)}applyPanelSizes(){if(!this.panelSources.length)return;const e=this.getDirection(),t=this.getMode();Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__panel")).forEach((i,s)=>{const n=this.panelSources[s];if(!n)return;const l=this.readPanelConfig(n,s,this.panelSources.length),r=this.panelSizes[s],o=l.flexible;if(i.style.width="",i.style.height="",i.style.flexBasis="",i.style.flexGrow="",i.style.flexShrink="",i.style.minHeight="",i.style.minWidth="",o)i.style.flex="1 1 0","vertical"===e?i.style.minHeight="0":i.style.minWidth="0";else{const e="fixed"===t?`${r}px`:100*r+"%";i.style.flex=`0 0 ${e}`}i.classList.toggle("designbase-wc-split-view__panel--flexible",Boolean(o)),i.classList.toggle("designbase-wc-split-view__panel--fixed",!o)})}sync(){if(this.isSyncing=!0,this.stopObserving(),this.collectPanelSources(),this.initPanelSizes(),!this.panelSources.length)return this.isSyncing=!1,void this.startObserving();const e=this.getDirection(),t=this.getMode(),i=this.getGap(),s=this.getSplitterSize(),n=this.getAttribute("splitter-color"),l=this.getAttribute("splitter-hover-color");this.className=["designbase-wc-split-view",`designbase-wc-split-view--direction-${e}`,`designbase-wc-split-view--mode-${t}`,this.hasAttribute("full-width")&&"designbase-wc-split-view--full-width",this.hasAttribute("full-height")&&"designbase-wc-split-view--full-height",null!==this.draggingIndex&&"designbase-wc-split-view--dragging"].filter(Boolean).join(" "),this.style.setProperty("--splitter-size",`${s}px`),n?this.style.setProperty("--splitter-color",n):this.style.removeProperty("--splitter-color"),l?this.style.setProperty("--splitter-hover-color",l):this.style.removeProperty("--splitter-hover-color"),this.style.gap=i>0?`${i}px`:"";const r=Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__panel")),o=Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__splitter"));r.forEach(e=>e.remove()),o.forEach(e=>e.remove()),this.panelSources.forEach((t,s)=>{const n=this.readPanelConfig(t,s,this.panelSources.length),l=s===this.panelSources.length-1,r=!1!==n.resizable&&!l,o=document.createElement("div");o.className="designbase-wc-split-view__panel";const a=document.createElement("div");if(a.className="designbase-wc-split-view__panel-body",t.parentElement!==a&&a.append(t),o.append(a),this.append(o),!l&&r&&0===i){const t=document.createElement("div");t.className=`designbase-wc-split-view__splitter designbase-wc-split-view__splitter--direction-${e}`,t.style.cursor="horizontal"===e?"col-resize":"row-resize",t.addEventListener("mousedown",this.handleMouseDown(s)),this.append(t)}}),this.applyPanelSizes(),this.isSyncing=!1,this.startObserving()}}customElements.get("db-split-view")||customElements.define("db-split-view",DbSplitView);export{DbSplitView};
|
|
1
|
+
import{rafThrottle as e}from"../core/dom.js";class DbSplitView extends HTMLElement{constructor(){super(...arguments),this.panelSizes=[],this.draggingIndex=null,this.panelSources=[],this.isSyncing=!1,this.isObserving=!1,this.handleMouseDown=e=>t=>{t.preventDefault(),this.draggingIndex=e,document.body.style.cursor="horizontal"===this.getDirection()?"col-resize":"row-resize",document.body.style.userSelect="none"},this.handleMouseMove=e(e=>{if(null===this.draggingIndex)return;if(!this.panelSources.length)return;const t=this.getDirection(),i=this.getMode(),s=this.getSplitterSize(),n=this.getBoundingClientRect(),l=this.panelSources[this.draggingIndex];if(!l)return;const r=this.readPanelConfig(l,this.draggingIndex,this.panelSources.length);let o=this.panelSizes[this.draggingIndex];if("horizontal"===t){const t=n.width,l=e.clientX-n.left;let a=0;for(let e=0;e<this.draggingIndex;e++){const n=this.panelSizes[e];a+="fixed"===i?n:n*t,a+=s}const h=l-a;if("fixed"===i)o=Math.max(r.minSize||0,Math.min(r.maxSize||t,h));else{o=h/t;const e=r.minSize?r.minSize/t:0,i=r.maxSize?r.maxSize/t:1;o=Math.max(e,Math.min(i,o))}}else{const t=n.height,l=e.clientY-n.top;let a=0;for(let e=0;e<this.draggingIndex;e++){const n=this.panelSizes[e];a+="fixed"===i?n:n*t,a+=s}const h=l-a;if("fixed"===i)o=Math.max(r.minSize||0,Math.min(r.maxSize||t,h));else{o=h/t;const e=r.minSize?r.minSize/t:0,i=r.maxSize?r.maxSize/t:1;o=Math.max(e,Math.min(i,o))}}this.panelSizes[this.draggingIndex]=o,this.applyPanelSizes(),this.classList.toggle("designbase-wc-split-view--dragging",!0)}),this.handleMouseUp=()=>{null!==this.draggingIndex&&(this.draggingIndex=null,document.body.style.cursor="",document.body.style.userSelect="",this.classList.toggle("designbase-wc-split-view--dragging",!1))}}static get observedAttributes(){return["direction","mode","splitter-size","splitter-color","splitter-hover-color","gap","full-width","full-height"]}connectedCallback(){this.style.display="flex",this.style.boxSizing="border-box",this.collectPanelSources(),this.initPanelSizes(),this.sync(),this.observer=new MutationObserver(()=>{this.isSyncing||(this.collectPanelSources(),this.initPanelSizes(),this.sync())}),this.startObserving(),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp)}disconnectedCallback(){this.stopObserving(),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),this.draggingIndex=null,document.body.style.cursor="",document.body.style.userSelect=""}startObserving(){this.observer&&!this.isObserving&&(this.observer.observe(this,{childList:!0}),this.isObserving=!0)}stopObserving(){this.observer&&this.isObserving&&(this.observer.disconnect(),this.isObserving=!1)}attributeChangedCallback(){this.isConnected&&this.sync()}collectPanelSources(){this.panelSources=[];const e=Array.from(this.querySelectorAll('[slot="panel"]'));if(e.length)return void(this.panelSources=e);const t=Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__panel > .designbase-wc-split-view__panel-body"));t.length&&(this.panelSources=t.map(e=>e.firstElementChild).filter(e=>e instanceof HTMLElement))}readPanelConfig(e,t,i){const s=e.getAttribute("data-size"),n=e.getAttribute("data-min-size"),l=e.getAttribute("data-max-size"),r=this.getMode();let o;return null!=s&&""!==s&&(o=Number(s)),{size:void 0!==o&&Number.isFinite(o)?o:"ratio"===r?1/i:200,minSize:n?Number(n):void 0,maxSize:l?Number(l):void 0,resizable:"false"!==e.getAttribute("data-resizable"),flexible:e.hasAttribute("data-flexible")||"false"!==e.getAttribute("data-flexible")&&t===i-1}}initPanelSizes(){const e=this.panelSources.length;if(!e)return;if(this.panelSizes.length===e)return;const t=this.getMode();this.panelSizes=this.panelSources.map((i,s)=>this.readPanelConfig(i,s,e).size??("ratio"===t?1/e:200))}getDirection(){return"vertical"===(this.getAttribute("direction")||"horizontal")?"vertical":"horizontal"}getMode(){return"fixed"===(this.getAttribute("mode")||"ratio")?"fixed":"ratio"}getSplitterSize(){return Number(this.getAttribute("splitter-size")||4)}getGap(){return Number(this.getAttribute("gap")||0)}applyPanelSizes(){if(!this.panelSources.length)return;const e=this.getDirection(),t=this.getMode();Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__panel")).forEach((i,s)=>{const n=this.panelSources[s];if(!n)return;const l=this.readPanelConfig(n,s,this.panelSources.length),r=this.panelSizes[s],o=l.flexible;if(i.style.width="",i.style.height="",i.style.flexBasis="",i.style.flexGrow="",i.style.flexShrink="",i.style.minHeight="",i.style.minWidth="",o)i.style.flex="1 1 0","vertical"===e?i.style.minHeight="0":i.style.minWidth="0";else{const e="fixed"===t?`${r}px`:100*r+"%";i.style.flex=`0 0 ${e}`}i.classList.toggle("designbase-wc-split-view__panel--flexible",Boolean(o)),i.classList.toggle("designbase-wc-split-view__panel--fixed",!o)})}sync(){if(this.isSyncing=!0,this.stopObserving(),this.collectPanelSources(),this.initPanelSizes(),!this.panelSources.length)return this.isSyncing=!1,void this.startObserving();const e=this.getDirection(),t=this.getMode(),i=this.getGap(),s=this.getSplitterSize(),n=this.getAttribute("splitter-color"),l=this.getAttribute("splitter-hover-color");this.className=["designbase-wc-split-view",`designbase-wc-split-view--direction-${e}`,`designbase-wc-split-view--mode-${t}`,this.hasAttribute("full-width")&&"designbase-wc-split-view--full-width",this.hasAttribute("full-height")&&"designbase-wc-split-view--full-height",null!==this.draggingIndex&&"designbase-wc-split-view--dragging"].filter(Boolean).join(" "),this.style.setProperty("--splitter-size",`${s}px`),n?this.style.setProperty("--splitter-color",n):this.style.removeProperty("--splitter-color"),l?this.style.setProperty("--splitter-hover-color",l):this.style.removeProperty("--splitter-hover-color"),this.style.gap=i>0?`${i}px`:"";const r=Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__panel")),o=Array.from(this.querySelectorAll(":scope > .designbase-wc-split-view__splitter"));r.forEach(e=>e.remove()),o.forEach(e=>e.remove()),this.panelSources.forEach((t,s)=>{const n=this.readPanelConfig(t,s,this.panelSources.length),l=s===this.panelSources.length-1,r=!1!==n.resizable&&!l,o=document.createElement("div");o.className="designbase-wc-split-view__panel";const a=document.createElement("div");if(a.className="designbase-wc-split-view__panel-body",t.parentElement!==a&&a.append(t),o.append(a),this.append(o),!l&&r&&0===i){const t=document.createElement("div");t.className=`designbase-wc-split-view__splitter designbase-wc-split-view__splitter--direction-${e}`,t.style.cursor="horizontal"===e?"col-resize":"row-resize",t.addEventListener("mousedown",this.handleMouseDown(s)),this.append(t)}}),this.applyPanelSizes(),this.isSyncing=!1,this.startObserving()}}customElements.get("db-split-view")||customElements.define("db-split-view",DbSplitView);export{DbSplitView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as t}from"./db-icons.js";
|
|
1
|
+
import{createDbIcon as t}from"./db-icons.js";import{STAT_SIZES as e,STAT_VARIANTS as s,STAT_LAYOUTS as i,STAT_COLORS as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const n={s:16,m:20,l:24};class DbStat extends HTMLElement{constructor(){super(...arguments),this.handleClick=()=>{!this.hasAttribute("disabled")&&this.hasAttribute("clickable")&&this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))},this.handleKeyDown=t=>{this.hasAttribute("clickable")&&!this.hasAttribute("disabled")&&("Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.handleClick()))}}static get observedAttributes(){return["value","label","icon","icon-position","size","variant","layout","color","custom-color","progress","show-progress","change","show-change","description","show-description","clickable","disabled","animated"]}connectedCallback(){this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeyDown),this.render()}disconnectedCallback(){this.removeEventListener("click",this.handleClick),this.removeEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(){this.render()}parseChange(){const t=this.getAttribute("change");if(!t)return null;try{const e=JSON.parse(t);if(e&&"number"==typeof e.value&&e.type)return e}catch{}return null}getChangeText(t){const e="increase"===t.type?"+":"-",s=t.period?` ${t.period}`:"";return`${e}${Math.abs(t.value)}%${s}`}resolveIconName(t){if(!t)return;return t in{user:1,sparkle:1,award:1,bulb:1,edit:1,search:1}?t:void 0}getProgressVariant(t){return"primary"===t?"primary":"success"===t?"success":"warning"===t?"warning":"error"===t?"danger":"default"}render(){const r=this.getAttribute("value")??"",c=this.getAttribute("label")||"",o=this.getAttribute("icon")||"",d=this.getAttribute("icon-position")||"left",l=this.getAttribute("size")||"m",h=e.includes(l)?l:"m",b=this.getAttribute("variant")||"default",u=s.includes(b)?b:"default",g=this.getAttribute("layout")||"horizontal",m=i.includes(g)?g:"horizontal",p=this.getAttribute("color")||"primary",w=a.includes(p)?p:"primary",v=this.getAttribute("custom-color")||"",A=this.getAttribute("progress"),_=null!==A?Number(A):NaN,y=this.hasAttribute("show-progress"),k=this.parseChange(),E=this.hasAttribute("show-change"),N=this.getAttribute("description")||"",f=this.hasAttribute("show-description"),C=this.hasAttribute("clickable"),x=this.hasAttribute("disabled"),$=this.hasAttribute("animated");this.className=["designbase-wc-stat",`designbase-wc-stat--size-${h}`,`designbase-wc-stat--variant-${u}`,`designbase-wc-stat--layout-${m}`,`designbase-wc-stat--color-${w}`,C&&"designbase-wc-stat--clickable",x&&"designbase-wc-stat--disabled",$&&"designbase-wc-stat--animated",y&&"designbase-wc-stat--with-progress",E&&k&&"designbase-wc-stat--with-change",f&&N&&"designbase-wc-stat--with-description"].filter(Boolean).join(" "),v?this.style.setProperty("--stat-color",v):this.style.removeProperty("--stat-color"),C?(this.setAttribute("role","button"),this.setAttribute("aria-disabled",String(x)),x?this.removeAttribute("tabindex"):this.setAttribute("tabindex","0")):(this.removeAttribute("aria-disabled"),this.removeAttribute("role"),this.removeAttribute("tabindex")),this.replaceChildren();const D=document.createElement("div");D.className="designbase-wc-stat__body";const S=this.resolveIconName(o);if(S){const e=document.createElement("div");e.className=`designbase-wc-stat__icon designbase-wc-stat__icon--${d}`;const s="iconBox"===u?n[h]:20;e.append(t(S,s)),D.append(e)}const z=document.createElement("div");z.className="designbase-wc-stat__content";const L=document.createElement("div");L.className="designbase-wc-stat__main";const j=document.createElement("div");j.className="designbase-wc-stat__label",j.textContent=c;const M=document.createElement("div");if(M.className="designbase-wc-stat__value",M.textContent=String(r),L.append(j,M),z.append(L),E&&k){const t=document.createElement("div");t.className=["designbase-wc-stat__change","increase"===k.type?"designbase-wc-stat__change--increase":"designbase-wc-stat__change--decrease"].join(" "),t.textContent=this.getChangeText(k),z.append(t)}if(f&&N){const t=document.createElement("div");t.className="designbase-wc-stat__description",t.textContent=N,z.append(t)}if(D.append(z),this.append(D),y&&!Number.isNaN(_)){const t=Math.min(Math.max(_,0),100),e=document.createElement("div");e.className="designbase-wc-stat__progress";const s=document.createElement("db-progressbar");s.setAttribute("value",String(t)),s.setAttribute("size","s"),s.setAttribute("variant",this.getProgressVariant(w)),s.setAttribute("full-width",""),e.append(s),this.append(e)}}}customElements.get("db-stat")||customElements.define("db-stat",DbStat);export{DbStat};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const t="designbase-wc-stepper",e=["s","m","l"],i={display:"block",width:"100%",minWidth:"0",height:"auto",padding:"0",margin:"0",border:"0",background:"transparent",color:"inherit",fontFamily:"inherit",fontWeight:"600",lineHeight:"1",textAlign:"center",outline:"none",boxShadow:"none",boxSizing:"border-box",appearance:"none"};class DbStepper extends HTMLElement{constructor(){super(...arguments),this.decrementBtn=null,this.incrementBtn=null,this.valueWrapEl=null,this.valueTextEl=null,this.valueInputEl=null,this.descriptionEl=null,this.boundInputKeyDown=t=>this.handleInputKeyDown(t),this.boundInputInput=()=>this.handleInputInput(),this.boundInputPaste=t=>this.handleInputPaste(t),this.boundInputBlur=()=>this.commitInputValue()}static get observedAttributes(){return["value","min","max","step","size","editable","full-width","disabled","readonly"]}connectedCallback(){this.querySelector(`.${t}__button`)||this.build(),this.syncFromAttributes()}attributeChangedCallback(t){this.decrementBtn&&this.syncFromAttributes()}get value(){return Number(this.getAttribute("value")||0)}set value(t){this.setAttribute("value",String(t))}build(){this.decrementBtn=document.createElement("button"),this.decrementBtn.type="button",this.decrementBtn.className=`${t}__button ${t}__button--decrement`,this.decrementBtn.setAttribute("aria-label","감소"),this.decrementBtn.innerHTML='<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="5" y1="12" x2="19" y2="12"/></svg>',this.valueWrapEl=document.createElement("div"),this.valueWrapEl.className=`${t}__value`,this.valueTextEl=document.createElement("span"),this.valueTextEl.className=`${t}__value-text`,this.valueWrapEl.appendChild(this.valueTextEl),this.incrementBtn=document.createElement("button"),this.incrementBtn.type="button",this.incrementBtn.className=`${t}__button ${t}__button--increment`,this.incrementBtn.setAttribute("aria-label","증가"),this.incrementBtn.innerHTML='<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>',this.descriptionEl=document.createElement("div"),this.descriptionEl.id="stepper-description",this.descriptionEl.className="sr-only",this.decrementBtn.addEventListener("click",()=>this.change(this.value-this.getStep())),this.incrementBtn.addEventListener("click",()=>this.change(this.value+this.getStep())),this.append(this.decrementBtn,this.valueWrapEl,this.incrementBtn,this.descriptionEl)}isEditable(){return!this.hasAttribute("disabled")&&!this.hasAttribute("readonly")&&"false"!==this.getAttribute("editable")}syncFromAttributes(){const i=this.getAttribute("size")||"m",n=this.hasAttribute("disabled"),s=this.hasAttribute("readonly"),l=this.getMin(),u=this.getMax(),a=this.getStep(),r=this.clamp(this.snapToStep(this.value));if(this.getAttribute("value")!==String(r)&&this.setAttribute("value",String(r)),this.className=[t,`${t}--${e.includes(i)?i:"m"}`,this.hasAttribute("full-width")&&`${t}--full-width`,this.isEditable()&&`${t}--editable`,n&&`${t}--disabled`,s&&`${t}--readonly`].filter(Boolean).join(" "),this.syncValueField(r),this.descriptionEl){const t=this.isEditable()?"값을 직접 입력할 수 있습니다. ":"";this.descriptionEl.textContent=`${t}숫자 조정기. +/- 버튼으로 값을 조정할 수 있습니다. 현재 값: ${r}, 최소값: ${l}, 최대값: ${u}, 단계: ${a}`}this.decrementBtn?.setAttribute("aria-describedby","stepper-description"),this.incrementBtn?.setAttribute("aria-describedby","stepper-description"),this.updateButtons()}applyValueInputAppearance(){this.valueInputEl&&(Object.assign(this.valueInputEl.style,i),this.valueInputEl.style.setProperty("-webkit-appearance","none"),this.valueInputEl.style.setProperty("-moz-appearance","textfield"))}syncValueField(e){if(this.valueWrapEl){if(this.isEditable())return this.valueInputEl||(this.valueInputEl=document.createElement("input"),this.valueInputEl.className=`${t}__value-input`,this.valueInputEl.type="text",this.valueInputEl.setAttribute("inputmode",this.allowsDecimal()?"decimal":"numeric"),this.valueInputEl.setAttribute("pattern",this.buildInputPattern()),this.valueInputEl.setAttribute("aria-label","값 입력"),this.valueInputEl.autocomplete="off",this.valueInputEl.spellcheck=!1,this.valueInputEl.addEventListener("keydown",this.boundInputKeyDown),this.valueInputEl.addEventListener("input",this.boundInputInput),this.valueInputEl.addEventListener("paste",this.boundInputPaste),this.valueInputEl.addEventListener("blur",this.boundInputBlur),this.applyValueInputAppearance()),this.applyValueInputAppearance(),this.valueInputEl.setAttribute("inputmode",this.allowsDecimal()?"decimal":"numeric"),this.valueInputEl.setAttribute("pattern",this.buildInputPattern()),this.valueInputEl.setAttribute("aria-valuemin",String(this.getMin())),this.valueInputEl.setAttribute("aria-valuemax",String(this.getMax())),this.valueInputEl.disabled=!1,document.activeElement!==this.valueInputEl&&(this.valueInputEl.value=String(e)),this.valueTextEl?.remove(),void(this.valueWrapEl.contains(this.valueInputEl)||this.valueWrapEl.appendChild(this.valueInputEl));this.valueInputEl&&(this.valueInputEl.removeEventListener("keydown",this.boundInputKeyDown),this.valueInputEl.removeEventListener("input",this.boundInputInput),this.valueInputEl.removeEventListener("paste",this.boundInputPaste),this.valueInputEl.removeEventListener("blur",this.boundInputBlur),this.valueInputEl.remove(),this.valueInputEl=null),this.valueTextEl||(this.valueTextEl=document.createElement("span"),this.valueTextEl.className=`${t}__value-text`),this.valueTextEl.textContent=String(e),this.valueWrapEl.contains(this.valueTextEl)||this.valueWrapEl.appendChild(this.valueTextEl)}}allowsNegative(){return this.getMin()<0}allowsDecimal(){const t=this.getStep();return!Number.isInteger(t)}buildInputPattern(){return`^${this.allowsNegative()?"-?":""}\\d*${this.allowsDecimal()?"(\\.\\d*)?":""}$`}sanitizeInputString(t){let e="",i=!1,n=!1;for(let s=0;s<t.length;s++){const l=t[s];"-"!==l||!this.allowsNegative()||0!==e.length||i?"."!==l||!this.allowsDecimal()||n?/\d/.test(l)&&(e+=l):(e+=l,n=!0):(e+=l,i=!0)}return e}parseInputValue(t){const e=t.trim();if(""===e||"-"===e||"."===e)return null;const i=Number(e);return Number.isFinite(i)?i:null}enforceInputBounds(t,e={}){const i=this.sanitizeInputString(t),n=this.parseInputValue(i);if(null===n)return i;const s=this.getMin(),l=this.getMax();return n>l?String(l):e.clampMin&&n<s?String(s):i}handleInputKeyDown(t){if(!["Backspace","Delete","Tab","Escape","ArrowLeft","ArrowRight","Home","End"].includes(t.key)){if("Enter"===t.key)return t.preventDefault(),this.commitInputValue(),void this.valueInputEl?.blur();if("-"===t.key&&this.allowsNegative()){const t=this.valueInputEl;if(t&&0===t.selectionStart&&0===t.selectionEnd&&!t.value.includes("-"))return}"."===t.key&&this.allowsDecimal()&&!this.valueInputEl?.value.includes(".")||/^\d$/.test(t.key)||t.preventDefault()}}handleInputInput(){if(!this.valueInputEl)return;const t=this.enforceInputBounds(this.valueInputEl.value);this.valueInputEl.value!==t&&(this.valueInputEl.value=t)}handleInputPaste(t){if(t.preventDefault(),!this.valueInputEl)return;const e=t.clipboardData?.getData("text")??"",i=this.enforceInputBounds(this.sanitizeInputString(this.valueInputEl.value+e));this.valueInputEl.value=i,this.handleInputInput()}commitInputValue(){if(!this.valueInputEl||!this.isEditable())return;const t=this.valueInputEl.value.trim();if(""===t||"-"===t||"."===t)return void(this.valueInputEl.value=String(this.value));const e=this.parseInputValue(t);if(null===e)return void(this.valueInputEl.value=String(this.value));const i=this.snapToStep(e);this.valueInputEl.value=String(i),this.change(i)}getMin(){return Number(this.getAttribute("min")??0)}getMax(){return Number(this.getAttribute("max")??100)}getStep(){return Number(this.getAttribute("step")??1)}snapToStep(t){const e=this.getStep(),i=Math.round(t/e)*e;return this.clamp(i)}clamp(t){return Math.max(this.getMin(),Math.min(this.getMax(),t))}updateButtons(){const e=this.getMin(),i=this.getMax(),n=this.hasAttribute("disabled"),s=this.hasAttribute("readonly"),l=this.value,u=l<=e,a=l>=i;if(this.decrementBtn){const e=n||s||u;this.decrementBtn.disabled=e,this.decrementBtn.classList.toggle(`${t}__button--disabled`,e)}if(this.incrementBtn){const e=n||s||a;this.incrementBtn.disabled=e,this.incrementBtn.classList.toggle(`${t}__button--disabled`,e)}}change(t){if(this.hasAttribute("disabled")||this.hasAttribute("readonly"))return;const e=this.getMin(),i=this.getMax(),n=this.clamp(this.snapToStep(t)),s=this.value;if(n!==s){if(this.setAttribute("value",String(n)),this.valueTextEl&&(this.valueTextEl.textContent=String(n)),this.valueInputEl&&(this.valueInputEl.value=String(n)),this.updateButtons(),this.descriptionEl){const t=this.getStep(),s=this.isEditable()?"값을 직접 입력할 수 있습니다. ":"";this.descriptionEl.textContent=`${s}숫자 조정기. +/- 버튼으로 값을 조정할 수 있습니다. 현재 값: ${n}, 최소값: ${e}, 최대값: ${i}, 단계: ${t}`}this.dispatchEvent(new CustomEvent("db-change",{detail:{value:n,minReached:n<=e,maxReached:n>=i},bubbles:!0,composed:!0})),n<=e&&s>e&&this.dispatchEvent(new CustomEvent("db-min-reached",{bubbles:!0,composed:!0,detail:{value:n}})),n>=i&&s<i&&this.dispatchEvent(new CustomEvent("db-max-reached",{bubbles:!0,composed:!0,detail:{value:n}}))}else this.valueInputEl&&(this.valueInputEl.value=String(n))}}customElements.get("db-stepper")||customElements.define("db-stepper",DbStepper);export{DbStepper};
|
|
1
|
+
const t="designbase-wc-stepper",e=["s","m","l"],i={display:"block",width:"100%",minWidth:"0",height:"auto",padding:"0",margin:"0",border:"0",background:"transparent",color:"inherit",fontFamily:"inherit",fontWeight:"600",lineHeight:"1",textAlign:"center",outline:"none",boxShadow:"none",boxSizing:"border-box",appearance:"none"};class DbStepper extends HTMLElement{constructor(){super(...arguments),this.decrementBtn=null,this.incrementBtn=null,this.valueWrapEl=null,this.valueTextEl=null,this.valueInputEl=null,this.descriptionEl=null,this.boundInputKeyDown=t=>this.handleInputKeyDown(t),this.boundInputInput=()=>this.handleInputInput(),this.boundInputPaste=t=>this.handleInputPaste(t),this.boundInputBlur=()=>this.commitInputValue()}static get observedAttributes(){return["value","min","max","step","size","editable","full-width","disabled","readonly"]}connectedCallback(){this.querySelector(`.${t}__button`)||this.build(),this.syncFromAttributes()}attributeChangedCallback(t){this.decrementBtn&&this.syncFromAttributes()}get value(){return Number(this.getAttribute("value")||0)}set value(t){this.setAttribute("value",String(t))}build(){this.decrementBtn=document.createElement("button"),this.decrementBtn.type="button",this.decrementBtn.className=`${t}__button ${t}__button--decrement`,this.decrementBtn.setAttribute("aria-label","감소"),this.decrementBtn.innerHTML='<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="5" y1="12" x2="19" y2="12"/></svg>',this.valueWrapEl=document.createElement("div"),this.valueWrapEl.className=`${t}__value`,this.valueTextEl=document.createElement("span"),this.valueTextEl.className=`${t}__value-text`,this.valueWrapEl.appendChild(this.valueTextEl),this.incrementBtn=document.createElement("button"),this.incrementBtn.type="button",this.incrementBtn.className=`${t}__button ${t}__button--increment`,this.incrementBtn.setAttribute("aria-label","증가"),this.incrementBtn.innerHTML='<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>',this.descriptionEl=document.createElement("div"),this.descriptionEl.id="stepper-description",this.descriptionEl.className="sr-only",this.decrementBtn.addEventListener("click",()=>this.change(this.value-this.getStep())),this.incrementBtn.addEventListener("click",()=>this.change(this.value+this.getStep())),this.append(this.decrementBtn,this.valueWrapEl,this.incrementBtn,this.descriptionEl)}isEditable(){return!this.hasAttribute("disabled")&&!this.hasAttribute("readonly")&&"false"!==this.getAttribute("editable")}syncFromAttributes(){const i=this.getAttribute("size")||"m",n=this.hasAttribute("disabled"),s=this.hasAttribute("readonly"),l=this.getMin(),u=this.getMax(),a=this.getStep(),r=this.clamp(this.snapToStep(this.value));if(this.getAttribute("value")!==String(r)&&this.setAttribute("value",String(r)),this.className=[t,`${t}--${e.includes(i)?i:"m"}`,this.hasAttribute("full-width")&&`${t}--full-width`,this.isEditable()&&`${t}--editable`,n&&`${t}--disabled`,s&&`${t}--readonly`].filter(Boolean).join(" "),this.syncValueField(r),this.descriptionEl){const t=this.isEditable()?"값을 직접 입력할 수 있습니다. ":"";this.descriptionEl.textContent=`${t}숫자 조정기. +/- 버튼으로 값을 조정할 수 있습니다. 현재 값: ${r}, 최소값: ${l}, 최대값: ${u}, 단계: ${a}`}this.decrementBtn?.setAttribute("aria-describedby","stepper-description"),this.incrementBtn?.setAttribute("aria-describedby","stepper-description"),this.updateButtons()}applyValueInputAppearance(){this.valueInputEl&&(Object.assign(this.valueInputEl.style,i),this.valueInputEl.style.setProperty("-webkit-appearance","none"),this.valueInputEl.style.setProperty("-moz-appearance","textfield"))}syncValueField(e){if(this.valueWrapEl){if(this.isEditable())return this.valueInputEl||(this.valueInputEl=document.createElement("input"),this.valueInputEl.className=`${t}__value-input`,this.valueInputEl.type="text",this.valueInputEl.setAttribute("inputmode",this.allowsDecimal()?"decimal":"numeric"),this.valueInputEl.setAttribute("pattern",this.buildInputPattern()),this.valueInputEl.setAttribute("aria-label","값 입력"),this.valueInputEl.autocomplete="off",this.valueInputEl.spellcheck=!1,this.valueInputEl.addEventListener("keydown",this.boundInputKeyDown),this.valueInputEl.addEventListener("input",this.boundInputInput),this.valueInputEl.addEventListener("paste",this.boundInputPaste),this.valueInputEl.addEventListener("blur",this.boundInputBlur),this.applyValueInputAppearance()),this.applyValueInputAppearance(),this.valueInputEl.setAttribute("inputmode",this.allowsDecimal()?"decimal":"numeric"),this.valueInputEl.setAttribute("pattern",this.buildInputPattern()),this.valueInputEl.setAttribute("aria-valuemin",String(this.getMin())),this.valueInputEl.setAttribute("aria-valuemax",String(this.getMax())),this.valueInputEl.disabled=!1,document.activeElement!==this.valueInputEl&&(this.valueInputEl.value=String(e)),this.valueTextEl?.remove(),void(this.valueWrapEl.contains(this.valueInputEl)||this.valueWrapEl.appendChild(this.valueInputEl));this.valueInputEl&&(this.valueInputEl.removeEventListener("keydown",this.boundInputKeyDown),this.valueInputEl.removeEventListener("input",this.boundInputInput),this.valueInputEl.removeEventListener("paste",this.boundInputPaste),this.valueInputEl.removeEventListener("blur",this.boundInputBlur),this.valueInputEl.remove(),this.valueInputEl=null),this.valueTextEl||(this.valueTextEl=document.createElement("span"),this.valueTextEl.className=`${t}__value-text`),this.valueTextEl.textContent=String(e),this.valueWrapEl.contains(this.valueTextEl)||this.valueWrapEl.appendChild(this.valueTextEl)}}allowsNegative(){return this.getMin()<0}allowsDecimal(){const t=this.getStep();return!Number.isInteger(t)}buildInputPattern(){return`^${this.allowsNegative()?"-?":""}\\d*${this.allowsDecimal()?"(\\.\\d*)?":""}$`}sanitizeInputString(t){let e="",i=!1,n=!1;for(let s=0;s<t.length;s++){const l=t[s];"-"!==l||!this.allowsNegative()||0!==e.length||i?"."!==l||!this.allowsDecimal()||n?/\d/.test(l)&&(e+=l):(e+=l,n=!0):(e+=l,i=!0)}return e}parseInputValue(t){const e=t.trim();if(""===e||"-"===e||"."===e)return null;const i=Number(e);return Number.isFinite(i)?i:null}enforceInputBounds(t,e={}){const i=this.sanitizeInputString(t),n=this.parseInputValue(i);if(null===n)return i;const s=this.getMin(),l=this.getMax();return n>l?String(l):e.clampMin&&n<s?String(s):i}handleInputKeyDown(t){if(!["Backspace","Delete","Tab","Escape","ArrowLeft","ArrowRight","Home","End"].includes(t.key)){if("Enter"===t.key)return t.preventDefault(),this.commitInputValue(),void this.valueInputEl?.blur();if("-"===t.key&&this.allowsNegative()){const t=this.valueInputEl;if(t&&0===t.selectionStart&&0===t.selectionEnd&&!t.value.includes("-"))return}"."===t.key&&this.allowsDecimal()&&!this.valueInputEl?.value.includes(".")||/^\d$/.test(t.key)||t.preventDefault()}}handleInputInput(){if(!this.valueInputEl)return;const t=this.enforceInputBounds(this.valueInputEl.value);this.valueInputEl.value!==t&&(this.valueInputEl.value=t)}handleInputPaste(t){if(t.preventDefault(),!this.valueInputEl)return;const e=t.clipboardData?.getData("text")??"",i=this.enforceInputBounds(this.sanitizeInputString(this.valueInputEl.value+e));this.valueInputEl.value=i,this.handleInputInput()}commitInputValue(){if(!this.valueInputEl||!this.isEditable())return;const t=this.valueInputEl.value.trim();if(""===t||"-"===t||"."===t)return void(this.valueInputEl.value=String(this.value));const e=this.parseInputValue(t);if(null===e)return void(this.valueInputEl.value=String(this.value));const i=this.snapToStep(e);this.valueInputEl.value=String(i),this.change(i)}getMin(){return Number(this.getAttribute("min")??0)}getMax(){return Number(this.getAttribute("max")??100)}getStep(){return Number(this.getAttribute("step")??1)}snapToStep(t){const e=this.getStep(),i=Math.round(t/e)*e;return this.clamp(i)}clamp(t){return Math.max(this.getMin(),Math.min(this.getMax(),t))}updateButtons(){const e=this.getMin(),i=this.getMax(),n=this.hasAttribute("disabled"),s=this.hasAttribute("readonly"),l=this.value,u=l<=e,a=l>=i;if(this.decrementBtn){const e=n||s||u;this.decrementBtn.disabled=e,this.decrementBtn.classList.toggle(`${t}__button--disabled`,e)}if(this.incrementBtn){const e=n||s||a;this.incrementBtn.disabled=e,this.incrementBtn.classList.toggle(`${t}__button--disabled`,e)}}change(t){if(this.hasAttribute("disabled")||this.hasAttribute("readonly"))return;const e=this.getMin(),i=this.getMax(),n=this.clamp(this.snapToStep(t)),s=this.value;if(n!==s){if(this.setAttribute("value",String(n)),this.valueTextEl&&(this.valueTextEl.textContent=String(n)),this.valueInputEl&&(this.valueInputEl.value=String(n)),this.updateButtons(),this.descriptionEl){const t=this.getStep(),s=this.isEditable()?"값을 직접 입력할 수 있습니다. ":"";this.descriptionEl.textContent=`${s}숫자 조정기. +/- 버튼으로 값을 조정할 수 있습니다. 현재 값: ${n}, 최소값: ${e}, 최대값: ${i}, 단계: ${t}`}this.dispatchEvent(new CustomEvent("db-change",{detail:{value:n,minReached:n<=e,maxReached:n>=i},bubbles:!0,composed:!0})),n<=e&&s>e&&this.dispatchEvent(new CustomEvent("db-min-reached",{bubbles:!0,composed:!0,detail:{value:n}})),n>=i&&s<i&&this.dispatchEvent(new CustomEvent("db-max-reached",{bubbles:!0,composed:!0,detail:{value:n}}))}else this.valueInputEl&&(this.valueInputEl.value=String(n))}}customElements.get("db-stepper")||customElements.define("db-stepper",DbStepper);export{DbStepper};
|