@designbasekorea/ui-wc 0.9.2 → 0.9.4
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 +22 -0
- package/dist/esm/components/date-picker-utils.js +1 -1
- package/dist/esm/components/db-activity-heatmap.js +1 -1
- package/dist/esm/components/db-ai-chat-list.js +1 -1
- package/dist/esm/components/db-ai-file-tree.js +1 -1
- package/dist/esm/components/db-alert.d.ts +12 -0
- package/dist/esm/components/db-alert.js +1 -1
- package/dist/esm/components/db-backdrop.js +1 -1
- package/dist/esm/components/db-bottom-sheet.js +1 -1
- package/dist/esm/components/db-calendar.d.ts +2 -1
- package/dist/esm/components/db-calendar.js +1 -1
- package/dist/esm/components/db-carousel.d.ts +2 -0
- package/dist/esm/components/db-carousel.js +1 -1
- package/dist/esm/components/db-chat-composer.js +1 -1
- package/dist/esm/components/db-checkbox.d.ts +15 -1
- package/dist/esm/components/db-checkbox.js +1 -1
- package/dist/esm/components/db-code-block.js +1 -1
- package/dist/esm/components/db-confirm.d.ts +2 -0
- package/dist/esm/components/db-confirm.js +1 -1
- package/dist/esm/components/db-context-menu.js +1 -1
- package/dist/esm/components/db-credit-card.d.ts +3 -4
- package/dist/esm/components/db-credit-card.js +1 -1
- package/dist/esm/components/db-cursor-follower.js +1 -1
- package/dist/esm/components/db-date-picker.d.ts +2 -1
- package/dist/esm/components/db-date-picker.js +1 -1
- package/dist/esm/components/db-design-toolbar.js +1 -1
- package/dist/esm/components/db-device-mockup.js +1 -1
- package/dist/esm/components/db-drawer.d.ts +1 -0
- package/dist/esm/components/db-drawer.js +1 -1
- package/dist/esm/components/db-dropdown.js +1 -1
- package/dist/esm/components/db-flight-status.d.ts +2 -2
- package/dist/esm/components/db-flight-status.js +1 -1
- package/dist/esm/components/db-gantt.js +1 -1
- package/dist/esm/components/db-indicator.d.ts +1 -0
- package/dist/esm/components/db-indicator.js +1 -1
- package/dist/esm/components/db-kanban.js +1 -1
- package/dist/esm/components/db-lightbox.js +1 -1
- package/dist/esm/components/db-modal.js +1 -1
- package/dist/esm/components/db-node.d.ts +1 -3
- package/dist/esm/components/db-node.js +1 -1
- package/dist/esm/components/db-onboarding-modal.js +1 -1
- package/dist/esm/components/db-popover.js +1 -1
- package/dist/esm/components/db-radio.d.ts +19 -1
- package/dist/esm/components/db-radio.js +1 -1
- package/dist/esm/components/db-receipt.js +1 -1
- package/dist/esm/components/db-search-bar.js +1 -1
- package/dist/esm/components/db-select.js +1 -1
- package/dist/esm/components/db-tabs.js +1 -1
- package/dist/esm/components/db-textarea.js +1 -1
- package/dist/esm/components/db-time-picker.js +1 -1
- package/dist/esm/components/db-tool-button.js +1 -1
- package/dist/esm/components/db-tooltip.js +1 -1
- package/dist/esm/components/db-tutorial.js +1 -1
- package/dist/esm/components/db-voice-control.js +1 -1
- package/dist/esm/core/ai-element.d.ts +2 -1
- package/dist/esm/core/ai-element.js +1 -1
- package/dist/esm/core/focus-trap.js +1 -1
- package/dist/esm/core/host-class.js +1 -0
- package/dist/esm/core/i18n-copy.js +1 -1
- package/dist/esm/core/i18n-en.js +1 -1
- package/dist/esm/core/i18n.d.ts +16 -0
- package/dist/esm/core/i18n.js +1 -1
- package/dist/esm/core/theme-scope.js +1 -0
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
- package/dist/esm/ui-contracts/dist/components.d.d.ts +9 -2
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +83 -13
- package/dist/index.esm.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +35 -9
- package/dist/react/index.esm.js +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as
|
|
1
|
+
import{createDbIcon as e}from"./db-icons.js";import{CleanupBag as t}from"../core/dom.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{CHECKBOX_SIZES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbCheckbox extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.userInteracted=!1,this.cleanups=new t,this.handleChange=()=>{if(!this.input||this.disabled||this.readOnly)return;this.userInteracted=!0;const e=this.input.checked;this.removeAttribute("selected"),this.toggleAttribute("checked",e),this.indeterminate&&(this.removeAttribute("indeterminate"),this.input.indeterminate=!1),this.syncVisual(),this.syncClasses(),this.syncValidity(),this.dispatchEvent(new CustomEvent("db-change",{detail:{checked:e,selected:e},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["checked","selected","default-checked","default-selected","indeterminate","size","disabled","readonly","required","name","value","has-label","aria-label","aria-labelledby","aria-describedby"]}focus(e){this.input?.focus(e)}get name(){return this.getAttribute("name")||""}set name(e){this.setAttribute("name",e)}get value(){return this.getAttribute("value")??"on"}set value(e){this.setAttribute("value",e)}get defaultChecked(){return this.hasAttribute("default-checked")||this.hasAttribute("default-selected")}set defaultChecked(e){this.removeAttribute("default-selected"),this.toggleAttribute("default-checked",e)}get defaultSelected(){return this.defaultChecked}set defaultSelected(e){this.defaultChecked=e}upgradeProperties(){for(const e of["checked","selected","defaultChecked","defaultSelected","name","value","disabled","readOnly","required","hasLabel","size","indeterminate"]){if(!Object.prototype.hasOwnProperty.call(this,e))continue;const t=this,i=t[e];delete t[e],t[e]=i}}get checked(){return this.input?.checked??(this.hasAttribute("checked")||this.hasAttribute("selected"))}set checked(e){this.userInteracted=!0,this.removeAttribute("selected"),this.toggleAttribute("checked",e),this.input&&(this.input.checked=e,this.syncVisual(),this.syncClasses())}get selected(){return this.checked}set selected(e){this.checked=e}get indeterminate(){return this.hasAttribute("indeterminate")}set indeterminate(e){this.toggleAttribute("indeterminate",e),this.input&&(this.input.indeterminate=e,this.syncVisual(),this.syncClasses())}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e),this.input&&(this.input.disabled=e),this.syncClasses()}get readOnly(){return this.hasAttribute("readonly")}set readOnly(e){this.toggleAttribute("readonly",e),this.input&&(this.input.readOnly=e),this.syncClasses()}get required(){return this.hasAttribute("required")}set required(e){this.toggleAttribute("required",e),this.input&&(this.input.required=e)}get size(){return i(this.getAttribute("size"),s,"m")}set size(e){this.setAttribute("size",e)}connectedCallback(){this.upgradeProperties(),this.style.display="contents",this.built||this.build(),this.syncState();const e=this.input?.form;e&&this.cleanups.listen(e,"reset",()=>{window.setTimeout(()=>this.syncAfterReset(),0)})}disconnectedCallback(){this.cleanups.run()}syncAfterReset(){this.input&&(this.toggleAttribute("checked",this.input.checked),this.removeAttribute("selected"),this.syncVisual(),this.syncClasses())}attributeChangedCallback(e){if(this.built){if("default-checked"!==e&&"default-selected"!==e||(this.resetChecked=this.hasAttribute("default-checked")||this.hasAttribute("default-selected")),"checked"===e||"selected"===e)return this.userInteracted=!0,this.input&&(this.input.checked=this.hasAttribute("checked")||this.hasAttribute("selected")),this.syncVisual(),void this.syncClasses();this.syncState()}}get hasLabel(){return!this.hasAttribute("has-label")||"false"!==this.getAttribute("has-label")}set hasLabel(e){this.setAttribute("has-label",String(e))}build(){for(this.root=document.createElement("label"),this.root.className="designbase-wc-checkbox",this.input=document.createElement("input"),this.input.type="checkbox",this.input.className="designbase-wc-checkbox__input",this.visual=document.createElement("span"),this.visual.className="designbase-wc-checkbox__visual",this.visual.setAttribute("aria-hidden","true"),this.labelEl=document.createElement("span"),this.labelEl.className="designbase-wc-checkbox__label";this.firstChild;)this.labelEl.appendChild(this.firstChild);this.root.append(this.input,this.visual,this.labelEl),this.appendChild(this.root),this.input.addEventListener("click",e=>{this.readOnly&&e.preventDefault()}),this.input.addEventListener("change",this.handleChange),this.built=!0}syncValidity(){if(!this.input)return;const e=!this.input.checkValidity();this.input.setAttribute("aria-invalid",String(e)),this.classList.toggle("designbase-wc-checkbox--invalid",e)}syncState(){if(!this.root||!this.input||!this.visual)return;const e=this.hasAttribute("checked")||this.hasAttribute("selected")||!this.userInteracted&&(this.hasAttribute("default-checked")||this.hasAttribute("default-selected")),t=this.hasAttribute("indeterminate");this.input.checked=e,this.resetChecked??(this.resetChecked=e),this.input.defaultChecked=this.resetChecked,this.input.indeterminate=t,this.input.disabled=this.disabled,this.input.readOnly=this.readOnly,this.input.setAttribute("aria-readonly",String(this.readOnly)),this.input.required=this.required,this.input.name=this.getAttribute("name")||"",this.input.value=this.getAttribute("value")??"on";for(const e of["aria-label","aria-labelledby","aria-describedby"]){const t=this.getAttribute(e);t?this.input.setAttribute(e,t):this.input.removeAttribute(e)}this.hasLabel?this.labelEl?.removeAttribute("hidden"):this.labelEl?.setAttribute("hidden",""),this.syncVisual(),this.syncClasses()}syncVisual(){if(this.visual&&this.input){if(this.visual.replaceChildren(),this.input.indeterminate){const t=document.createElement("span");return t.className="designbase-wc-checkbox__indeterminate-icon",t.appendChild(e("minus",16)),void this.visual.appendChild(t)}if(this.input.checked){const t=document.createElement("span");t.className="designbase-wc-checkbox__check-icon",t.appendChild(e("done",16)),this.visual.appendChild(t)}}}syncClasses(){if(!this.root||!this.input)return;const e=s.includes(this.size)?this.size:"m",t=this.hasLabel&&Boolean(this.labelEl?.textContent?.trim());this.root.className=["designbase-wc-checkbox",`designbase-wc-checkbox--${e}`,this.input.checked&&"designbase-wc-checkbox--selected",this.input.indeterminate&&"designbase-wc-checkbox--indeterminate",this.disabled&&"designbase-wc-checkbox--disabled",this.readOnly&&"designbase-wc-checkbox--readonly",!t&&"designbase-wc-checkbox--no-label"].filter(Boolean).join(" ")}}customElements.get("db-checkbox")||customElements.define("db-checkbox",DbCheckbox);export{DbCheckbox};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{setHostClasses as e}from"../core/host-class.js";import{dbFormat as t}from"../core/i18n.js";import{ensureHighlightReady as i,highlightCodeSync as s,formatLanguageLabel as o}from"./highlight-code.js";const n="designbase-wc-code-block";class DbCodeBlock extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.renderToken=0,this.internalActiveId="",this.copied=!1,this.editedCodes={},this.handleSegmentChange=e=>{const t=e,i=t.detail?.value;i&&(this.hasAttribute("active-id")||(this.internalActiveId=i),this.dispatchEvent(new CustomEvent("db-active-id-change",{detail:{activeId:i},bubbles:!0,composed:!0})),this.render())}}static get observedAttributes(){return["items","code","language","default-active-id","active-id","show-language","highlight","theme","show-copy","copied-label","copy-label","min-height","max-height","overflow","editable"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.internalActiveId=this.getAttribute("default-active-id")||this.getResolvedItems()[0]?.id||""),this.render(),i().then(()=>{this.isConnected&&this.built&&this.render()}),this.addEventListener("db-change",this.handleSegmentChange)}disconnectedCallback(){this.removeEventListener("db-change",this.handleSegmentChange),this.copyTimeout&&window.clearTimeout(this.copyTimeout)}attributeChangedCallback(e){if(this.built)if("active-id"!==e){if("items"===e||"code"===e||"language"===e){const e=this.getResolvedItems();e.find(e=>e.id===this.getActiveId())||(this.internalActiveId=e[0]?.id||"")}this.render()}else this.render()}getBool(e,t=!0){if(!this.hasAttribute(e))return t;const i=this.getAttribute(e);return""===i||"true"===i}getResolvedItems(){const e=this.getAttribute("items");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length>0)return t}catch{}const t=this.getAttribute("code");if(t){const e=this.getAttribute("language")||"tsx";return[{id:"default",label:e,code:t,language:e}]}return[]}getActiveId(){return this.getAttribute("active-id")||this.internalActiveId}getActiveItem(){const e=this.getResolvedItems();return e.find(e=>e.id===this.getActiveId())||e[0]}toCssSize(e){if(e)return/^\d+$/.test(e)?`${e}px`:e}async handleCopy(){const e=this.getActiveItem(),t=this.getBool("editable",!1),i=(t?this.editedCodes[e?.id??""]??e?.code:e?.code)?.trim();if(i){try{await navigator.clipboard.writeText(i)}catch{const e=document.createElement("textarea");e.value=i,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select(),document.execCommand("copy"),e.remove()}this.copied=!0,this.render(),this.copyTimeout&&window.clearTimeout(this.copyTimeout),this.copyTimeout=window.setTimeout(()=>{this.copied=!1,this.render()},1600)}}render(){const e=++this.renderToken;this.renderNow(e)}renderNow(i){const d=this.getActiveItem();if(!d)return void this.replaceChildren();const c=this.getResolvedItems(),a=c.length>1,r=this.getAttribute("language")||"tsx",l=d.language??r,h=this.getBool("show-language",!0),u=this.getBool("highlight",!0),m=this.getAttribute("theme")||"auto",b=this.getBool("show-copy",!0),g=this.getAttribute("copied-label")||"복사됨",p=this.getAttribute("copy-label")||"복사",v=this.getAttribute("overflow")||"scroll-x",A=this.getBool("editable",!1),y=A?this.editedCodes[d.id]??d.code:d.code,f=y.trim();let C=null;if(u&&y)try{C=s(y,l)}catch{C=null}if(i!==this.renderToken)return;const E=this.toCssSize(this.getAttribute("min-height")),_=this.toCssSize(this.getAttribute("max-height"));E?this.style.setProperty("--db-code-block-min-height",E):this.style.removeProperty("--db-code-block-min-height"),_?this.style.setProperty("--db-code-block-max-height",_):this.style.removeProperty("--db-code-block-max-height"),e(this,[n,`${n}--overflow-${v}`,"auto"!==m&&`${n}--theme-${m}`,A&&`${n}--editable`]);const x=document.createElement("div");x.className=`${n}__toolbar`;const $=document.createElement("div");if($.className=`${n}__toolbar-left`,a){const e=document.createElement("db-segment-control");e.setAttribute("size","s"),e.setAttribute("options",JSON.stringify(c.map(e=>({value:e.id,label:e.label})))),e.setAttribute("value",this.getActiveId()),$.append(e)}if(h){const e=document.createElement("span");e.className=`${n}__language`,e.textContent=o(l),$.append(e)}if(x.append($),b){const e=document.createElement("db-button");e.setAttribute("type","button"),e.setAttribute("variant","tertiary"),e.setAttribute("size","s"),e.setAttribute("start-icon",this.copied?"done":"copy"),e.textContent=this.copied?g:p,e.addEventListener("db-click",()=>this.handleCopy()),x.append(e)}const w=document.createElement("div");if(w.className=`${n}__body`,a&&d.description){const e=document.createElement("p");e.className=`${n}__caption`,e.textContent=d.description,w.append(e)}if(A){void 0===this.editedCodes[d.id]&&(this.editedCodes[d.id]=d.code);const e=document.createElement("div");e.className=`${n}__editor`;const i=document.createElement("pre");i.className=`${n}__pre ${n}__pre--mirror`,i.setAttribute("aria-hidden","true");const c=document.createElement("code");c.className=`${n}__code language-${l}`,C?c.innerHTML=C:c.textContent=y,i.append(c);const a=document.createElement("textarea");a.className=`${n}__textarea`,a.value=y,a.spellcheck=!1,a.setAttribute("autocapitalize","off"),a.setAttribute("autocorrect","off"),a.setAttribute("aria-label",t("{0} 코드 편집",[o(l)])),a.addEventListener("input",()=>{this.editedCodes[d.id]=a.value;const e=u&&a.value?s(a.value,l):null;e?c.innerHTML=e:c.textContent=a.value,this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:a.value,itemId:d.id},bubbles:!0,composed:!0}))}),e.append(i,a),w.append(e)}else{const e=document.createElement("pre");e.className=`${n}__pre`;const t=document.createElement("code");t.className=`${n}__code language-${l}`,C?t.innerHTML=C:t.textContent=f,e.append(t),w.append(e)}this.replaceChildren(x,w)}}customElements.get("db-code-block")||customElements.define("db-code-block",DbCodeBlock);export{DbCodeBlock};
|
|
@@ -5,6 +5,8 @@ declare class DbConfirm extends HTMLElement {
|
|
|
5
5
|
private focusTrap?;
|
|
6
6
|
/** 참조 카운트 스크롤락을 이 인스턴스가 잡고 있는지 (PERF-GLOBAL-STATE) */
|
|
7
7
|
private scrollLocked;
|
|
8
|
+
private unsubscribeLocale?;
|
|
9
|
+
private syncLocale;
|
|
8
10
|
connectedCallback(): void;
|
|
9
11
|
disconnectedCallback(): void;
|
|
10
12
|
/** 트랩 해제(=포커스 복원)와 스크롤락 반환을 한 곳에서 처리한다 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t,subscribeDbLocale as e}from"../core/i18n.js";import{inheritThemeScope as i}from"../core/theme-scope.js";import{createDbIcon as s}from"./db-icons.js";import{createFocusTrap as n}from"../core/focus-trap.js";import{unlockScroll as o,lockScroll as c}from"../core/scroll-lock.js";import{coerceToContract as r}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{CONFIRM_VARIANTS as a,CONFIRM_SIZES as d}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbConfirm extends HTMLElement{constructor(){super(...arguments),this.root=null,this.keyHandler=null,this.scrollLocked=!1,this.syncLocale=()=>{const e=this.root?.querySelectorAll(".designbase-wc-confirm__footer > db-button");e?.[0]&&(e[0].textContent=this.getAttribute("cancel-text")||t("confirm.cancel")),e?.[1]&&(e[1].textContent=this.getAttribute("confirm-text")||t("confirm.ok"))}}static get observedAttributes(){return["open","title","message","confirm-text","cancel-text","confirm-variant","variant","size","show-icon","initial-focus","confirm-disabled","cancel-disabled","close-on-escape","close-on-backdrop"]}connectedCallback(){this.unsubscribeLocale=e(this.syncLocale),this.render()}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,this.detachEscape(),this.teardownOverlay(),this.root?.remove(),this.root=null}teardownOverlay(){this.focusTrap?.deactivate(),this.focusTrap=void 0,this.scrollLocked&&(this.scrollLocked=!1,o())}attributeChangedCallback(){this.render()}isOpen(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}attachEscape(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"false"!==this.getAttribute("close-on-escape")&&this.dispatchCancel()},document.addEventListener("keydown",this.keyHandler))}detachEscape(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}dispatchCancel(){this.setAttribute("open","false"),this.dispatchEvent(new CustomEvent("db-cancel",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}dispatchConfirm(){this.setAttribute("open","false"),this.dispatchEvent(new CustomEvent("db-confirm",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}iconForVariant(t){return"success"===t?"award":"warning"===t?"bell-active":"danger"===t?"cloud-close":"bulb"}iconSize(t){return"s"===t?20:"l"===t?32:24}render(){if(this.root?.remove(),this.root=null,this.detachEscape(),this.teardownOverlay(),!this.isOpen())return void this.replaceChildren();this.scrollLocked||(c(),this.scrollLocked=!0),this.attachEscape();const e=this.getAttribute("title")||"",o=this.getAttribute("message")||this.textContent?.trim()||"",l=this.getAttribute("confirm-text")||t("confirm.ok"),m=this.getAttribute("cancel-text")||t("confirm.cancel"),b=this.getAttribute("confirm-variant")||"primary",u=r(this.getAttribute("variant"),a,"info"),h=r(this.getAttribute("size"),d,"s"),p="false"!==this.getAttribute("show-icon"),f=this.getAttribute("initial-focus")||"confirm",v="true"===this.getAttribute("confirm-disabled"),g="true"===this.getAttribute("cancel-disabled"),A=document.createElement("div");A.className="designbase-wc-confirm__overlay",A.setAttribute("role","dialog"),A.setAttribute("aria-modal","true"),e&&A.setAttribute("aria-labelledby","confirm-title"),A.setAttribute("aria-describedby","confirm-content"),A.addEventListener("click",t=>{t.target===A&&"false"!==this.getAttribute("close-on-backdrop")&&this.dispatchCancel()});const E=document.createElement("div");E.className=["designbase-wc-confirm__modal",`designbase-wc-confirm__modal--${u}`,`designbase-wc-confirm__modal--${h}`,!p&&"designbase-wc-confirm__modal--no-icon"].filter(Boolean).join(" ");const k=document.createElement("div");if(k.className=["designbase-wc-confirm__header",!p&&"designbase-wc-confirm__header--no-icon"].filter(Boolean).join(" "),p){const t=document.createElement("div");t.className="designbase-wc-confirm__icon",t.append(s(this.iconForVariant(u),this.iconSize(h))),k.append(t)}const w=document.createElement("div");if(w.className="designbase-wc-confirm__title-area",e){const t=document.createElement("h2");t.id="confirm-title",t.className="designbase-wc-confirm__title",t.textContent=e,w.append(t)}k.append(w),E.append(k);const _=document.createElement("div");_.id="confirm-content",_.className="designbase-wc-confirm__content",_.textContent=o,E.append(_);const C=document.createElement("div");C.className="designbase-wc-confirm__footer";const y=document.createElement("db-button");y.setAttribute("variant","tertiary"),y.setAttribute("full-width",""),y.textContent=m,g&&y.setAttribute("disabled",""),y.addEventListener("db-click",()=>this.dispatchCancel());const L=document.createElement("db-button");L.setAttribute("variant",b),L.setAttribute("full-width",""),L.textContent=l,v&&L.setAttribute("disabled",""),L.addEventListener("db-click",()=>this.dispatchConfirm()),C.append(y,L),E.append(C),A.append(E),i(this,A),document.body.append(A),this.root=A,this.focusTrap=n(E,{initialFocus:()=>"cancel"===f?y:L}),requestAnimationFrame(()=>this.focusTrap?.activate())}}customElements.get("db-confirm")||customElements.define("db-confirm",DbConfirm);export{DbConfirm};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class DbContextMenu extends HTMLElement{constructor(){super(...arguments),this.externalTarget=null,this.activeSubMenu=null,this.onExternalContextMenu=null,this.handleDocumentMouseDown=
|
|
1
|
+
import{inheritThemeScope as e}from"../core/theme-scope.js";class DbContextMenu extends HTMLElement{constructor(){super(...arguments),this.externalTarget=null,this.activeSubMenu=null,this.onExternalContextMenu=null,this.handleDocumentMouseDown=e=>{if(!this.open)return;const t=e.target;this.menuEl?.contains(t)||2===e.button&&(this.targetWrap?.contains(t)||this.externalTarget?.contains(t))||this.close()},this.handleKeyDown=e=>{this.open&&"Escape"===e.key&&this.close()},this.handleContextMenu=e=>{this.hasAttribute("disabled")||(e.preventDefault(),e.stopPropagation(),this.openAt(e.clientX,e.clientY))}}static get observedAttributes(){return["open","x","y","items","target-id","disabled"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(e){e?this.setAttribute("open","true"):this.removeAttribute("open")}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.style.display="contents",requestAnimationFrame(()=>{this.renderTarget(),this.syncMenu()}),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleKeyDown),this.unbindExternalTarget(),this.menuEl?.remove(),this.menuEl=void 0}attributeChangedCallback(e){if(this.isConnected)return"target-id"===e?(this.unbindExternalTarget(),void this.bindExternalTarget()):void("open"!==e&&"x"!==e&&"y"!==e&&"items"!==e||this.syncMenu())}openAt(e,t){this.setAttribute("x",String(e)),this.setAttribute("y",String(t)),this.setAttribute("open","true"),this.dispatchEvent(new CustomEvent("db-open",{bubbles:!0,composed:!0,detail:{x:e,y:t}})),this.syncMenu()}close(){this.activeSubMenu=null,this.removeAttribute("open"),this.menuEl?.remove(),this.menuEl=void 0,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}collectTargetChildren(){const e=Array.from(this.children).filter(e=>!e.hasAttribute("data-wc-internal")&&e!==this.targetWrap);return e.length>0?e:Array.from(this.targetWrap?.children||[])}bindExternalTarget(){const e=this.getAttribute("target-id");e&&(this.externalTarget=document.getElementById(e),this.externalTarget&&(this.onExternalContextMenu=e=>this.handleContextMenu(e),this.externalTarget.addEventListener("contextmenu",this.onExternalContextMenu)))}unbindExternalTarget(){this.externalTarget&&this.onExternalContextMenu&&this.externalTarget.removeEventListener("contextmenu",this.onExternalContextMenu),this.externalTarget=null,this.onExternalContextMenu=null}renderTarget(){const e=this.collectTargetChildren();this.getAttribute("target-id")?(this.replaceChildren(),this.bindExternalTarget()):(this.targetWrap||(this.targetWrap=document.createElement("div"),this.targetWrap.className="designbase-wc-context-menu__target",this.targetWrap.addEventListener("contextmenu",this.handleContextMenu)),this.replaceChildren(),e.forEach(e=>this.targetWrap.append(e)),e.length>0&&this.append(this.targetWrap))}adjustPosition(){if(!this.menuEl)return;const e=Number(this.getAttribute("x")||0),t=Number(this.getAttribute("y")||0),n=this.menuEl.getBoundingClientRect();let i=e,s=t;e+n.width>window.innerWidth&&(i=e-n.width),t+n.height>window.innerHeight&&(s=t-n.height),this.menuEl.style.left=`${Math.max(0,i)}px`,this.menuEl.style.top=`${Math.max(0,s)}px`}createMenuItem(e){const t=document.createElement("db-menu-item");return t.setAttribute("label",e.label||e.id),t.setAttribute("type","block"),t.setAttribute("menu-style","dropdown"),e.icon&&t.setAttribute("icon",e.icon),e.disabled&&t.setAttribute("disabled",""),e.variant&&t.setAttribute("variant",e.variant),e.subItems?.length&&(t.setAttribute("sub-items",JSON.stringify(e.subItems)),t.setAttribute("expandable","")),t.addEventListener("db-click",()=>{e.disabled||e.subItems?.length||(this.dispatchEvent(new CustomEvent("db-select",{detail:{item:e},bubbles:!0,composed:!0})),this.close())}),t.addEventListener("db-child-click",e=>{const t=e.detail?.child;this.dispatchEvent(new CustomEvent("db-select",{detail:{item:t},bubbles:!0,composed:!0})),this.close()}),t}renderItem(e,t){if(e.divider||e.isDivider){const e=document.createElement("db-divider");return e.className="designbase-wc-divider",e}const n=document.createElement("div");n.className="designbase-wc-context-menu__item-wrapper",n.append(this.createMenuItem(e));if(Boolean(e.subItems?.length)){const t=document.createElement("div");t.className=["designbase-wc-context-menu__submenu",this.activeSubMenu===e.id&&"designbase-wc-context-menu__submenu--open"].filter(Boolean).join(" "),e.subItems?.forEach((e,n)=>{const i=this.renderItem(e,n);i&&t.append(i)}),n.addEventListener("mouseenter",()=>{this.activeSubMenu=e.id,t.classList.add("designbase-wc-context-menu__submenu--open")}),n.addEventListener("mouseleave",()=>{this.activeSubMenu=null,t.classList.remove("designbase-wc-context-menu__submenu--open")}),n.append(t)}return n}syncMenu(){if(this.menuEl?.remove(),this.menuEl=void 0,!this.open)return;const t=Number(this.getAttribute("x")||0),n=Number(this.getAttribute("y")||0),i=this.items,s=document.createElement("div");s.className="designbase-wc-context-menu",s.setAttribute("data-wc-internal",""),s.style.position="fixed",s.style.left=`${t}px`,s.style.top=`${n}px`,s.style.zIndex="1000",s.setAttribute("role","menu"),s.setAttribute("aria-orientation","vertical"),i.forEach((e,t)=>{const n=this.renderItem(e,t);n&&s.append(n)}),e(this,s),document.body.append(s),this.menuEl=s,requestAnimationFrame(()=>this.adjustPosition())}}customElements.get("db-context-menu")||customElements.define("db-context-menu",DbContextMenu);export{DbContextMenu};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { DbElement } from '../core/base-element.js';
|
|
2
|
+
import { CREDIT_CARD_ORIENTATIONS, CREDIT_CARD_VARIANTS } from '../ui-contracts/dist/components.d.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type DbCreditCardOrientation = typeof ORIENTATIONS[number];
|
|
6
|
-
type DbCreditCardVariant = typeof VARIANTS[number];
|
|
4
|
+
type DbCreditCardOrientation = typeof CREDIT_CARD_ORIENTATIONS[number];
|
|
5
|
+
type DbCreditCardVariant = typeof CREDIT_CARD_VARIANTS[number];
|
|
7
6
|
interface DbCreditCardFlip {
|
|
8
7
|
flipped: boolean;
|
|
9
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t}from"../core/i18n.js";import{getPaymentBrand as e}from"../helpers/payment-brands.js";import{DbElement as i}from"../core/base-element.js";
|
|
1
|
+
import{t}from"../core/i18n.js";import{getPaymentBrand as e}from"../helpers/payment-brands.js";import{DbElement as i}from"../core/base-element.js";import{CREDIT_CARD_VARIANTS as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const node=(t,e,i="")=>{const r=document.createElement(t);return r.className=e,r.textContent=i,r};class DbCreditCard extends i{static get observedAttributes(){return["issuer","holder","last-four","expiry","network","security-code","back-note","orientation","variant","flipped","disabled","label"]}get flipped(){return this.hasAttribute("flipped")}set flipped(t){this.toggleAttribute("flipped",Boolean(t))}get orientation(){return"vertical"===this.getAttribute("orientation")?"vertical":"horizontal"}set orientation(t){this.setAttribute("orientation",t)}get variant(){const t=this.getAttribute("variant");return r.find(e=>e===t)||"default"}set variant(t){this.setAttribute("variant",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}connectedCallback(){this.classList.add("db-credit-card"),this.upgradeProperties(["flipped","orientation","variant","disabled"]),this.button||this.build(),this.cleanups.listen(this.button,"click",()=>{this.disabled||(this.flipped=!this.flipped,this.dbEmit("flip",{flipped:this.flipped}))}),this.cleanups.listen(this.button,"pointermove",t=>{const e=t;if(this.disabled||"mouse"!==e.pointerType||!matchMedia("(hover: hover) and (pointer: fine)").matches||matchMedia("(prefers-reduced-motion: reduce)").matches)return;const i=this.button.getBoundingClientRect(),r=Math.max(0,Math.min(1,(e.clientX-i.left)/i.width)),s=Math.max(0,Math.min(1,(e.clientY-i.top)/i.height));this.dataset.pointerActive="",this.style.setProperty("--db-cc-rotate-x",7*(.5-s)+"deg"),this.style.setProperty("--db-cc-rotate-y",7*(r-.5)+"deg"),this.style.setProperty("--db-cc-pointer-x",100*r+"%"),this.style.setProperty("--db-cc-pointer-y",100*s+"%"),this.style.setProperty("--db-cc-glare","1")}),this.cleanups.listen(this.button,"pointerleave",()=>this.releaseSurface());for(const t of["pointercancel","blur"])this.cleanups.listen(this.button,t,()=>this.releaseSurface());this.cleanups.listen(matchMedia("(prefers-reduced-motion: reduce)"),"change",()=>this.resetSurface()),this.sync()}disconnectedCallback(){this.resetSurface(),super.disconnectedCallback()}releaseSurface(){if(this.hasAttribute("data-pointer-active"))for(const t of["x","y"]){const e=`--db-cc-pointer-${t}`,i=parseFloat(this.style.getPropertyValue(e));Number.isFinite(i)&&this.style.setProperty(e,`${Math.max(-20,Math.min(120,i+.6*(i-50)))}%`)}delete this.dataset.pointerActive;for(const t of["rotate-x","rotate-y","glare"])this.style.removeProperty(`--db-cc-${t}`)}resetSurface(){delete this.dataset.pointerActive;for(const t of["rotate-x","rotate-y","pointer-x","pointer-y","glare"])this.style.removeProperty(`--db-cc-${t}`)}syncNetwork(t,i){const r=e(i);if(t.dataset.network===i)return;if(t.dataset.network=i,!r)return delete t.dataset.brand,t.style.removeProperty("--db-cc-network-mask"),void(t.textContent=i);const s=document.createElement("img");t.dataset.brand=r.id;const a="cardSrc"in r?r.cardSrc:r.src;s.src=a,t.style.setProperty("--db-cc-network-mask",`url("${a}")`),s.alt=r.label,s.width=120,s.height=80,s.draggable=!1,t.replaceChildren(s)}attributeChangedCallback(){this.button&&this.sync()}build(){const t=document.createElement("button");t.type="button",t.className="db-credit-card__button";const e=node("span","db-credit-card__frame");this.front=node("span","db-credit-card__face db-credit-card__face--front");const i=node("span","db-credit-card__head");this.issuerFront=node("span","db-credit-card__issuer"),this.networkFront=node("span","db-credit-card__network"),i.append(this.issuerFront,this.networkFront);const r=node("span","db-credit-card__middle"),s=node("span","db-credit-card__chip");s.setAttribute("aria-hidden","true"),s.append(node("span","")),r.append(s),this.number=node("span","db-credit-card__number");const a=node("span","db-credit-card__foot");this.holderFront=node("span","db-credit-card__holder"),this.expiryFront=node("span","db-credit-card__expiry"),a.append(this.holderFront,this.expiryFront),this.front.append(i,r,this.number,a),this.back=node("span","db-credit-card__face db-credit-card__face--back"),this.issuerBack=node("span","db-credit-card__issuer");const n=node("span","db-credit-card__stripe");n.setAttribute("aria-hidden","true");const d=node("span","db-credit-card__signature");this.holderBack=node("span","db-credit-card__signature-name"),this.security=node("span","db-credit-card__security"),d.append(this.holderBack,this.security),this.note=node("span","db-credit-card__note");const c=node("span","db-credit-card__foot");this.networkBack=node("span","db-credit-card__network"),this.expiryBack=node("span","db-credit-card__expiry"),c.append(this.networkBack,this.expiryBack),this.back.append(this.issuerBack,n,d,this.note,c),e.append(this.front,this.back);const o=node("span","db-credit-card__tilt");o.append(e),t.append(o),this.button=t,this.prepend(t)}sync(){const e=this.getAttribute("issuer")||"Studio",i=this.getAttribute("holder")||"",r=this.getAttribute("last-four")||"",s=/^\d{4}$/.test(r)?r:"••••",a=this.getAttribute("network")||"",n=this.getAttribute("expiry")||"";this.dataset.orientation=this.orientation,this.dataset.variant=this.variant,this.issuerFront.textContent=e,this.issuerBack.textContent=e,this.syncNetwork(this.networkFront,a),this.syncNetwork(this.networkBack,a),this.number.textContent=`•••• •••• •••• ${s}`,this.holderFront.textContent=i,this.holderFront.title=i,this.holderBack.textContent=i,this.expiryFront.textContent=n,this.expiryBack.textContent=n,this.security.textContent=this.getAttribute("security-code")||"•••",this.security.setAttribute("aria-label",t("creditCard.security").replace("{code}",this.security.textContent||"")),this.note.textContent=this.getAttribute("back-note")||"",this.button.disabled=this.disabled,this.disabled&&this.resetSurface(),this.button.setAttribute("aria-label",this.getAttribute("label")||t("creditCard.label").replace("{issuer}",e).replace("{lastFour}","••••"===s?"":t("creditCard.ending").replace("{digits}",s))),this.button.setAttribute("aria-pressed",String(this.flipped)),this.button.setAttribute("aria-description",[t("creditCard.showing").replace("{side}",t(this.flipped?"creditCard.back":"creditCard.front")),i,a,n?t("creditCard.expiry").replace("{expiry}",n):"",this.flipped?t("creditCard.security").replace("{code}",this.security.textContent||""):"",t("creditCard.show").replace("{side}",t(this.flipped?"creditCard.front":"creditCard.back"))].filter(Boolean).join(". ")),this.front.setAttribute("aria-hidden",String(this.flipped)),this.back.setAttribute("aria-hidden",String(!this.flipped)),this.front.inert=this.flipped,this.back.inert=!this.flipped}}customElements.get("db-credit-card")||customElements.define("db-credit-card",DbCreditCard);export{DbCreditCard};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{inheritThemeScope as t}from"../core/theme-scope.js";import{createDbIcon as e}from"./db-icons.js";const s="designbase-wc-cursor-follower",i="designbase-wc-cursor-follower--hide-native";class DbCursorFollower extends HTMLElement{constructor(){super(...arguments),this.target={x:-9999,y:-9999},this.current={x:-9999,y:-9999},this.raf=0,this.enabled=!1,this.isScoped=!1}static get observedAttributes(){return["default-label","selector","smoothness","offset","hide-native-cursor","show-icon"]}connectedCallback(){this.style.display="contents",this.setupDesktopGate()}disconnectedCallback(){this.teardown()}attributeChangedCallback(){this.isConnected&&this.enabled&&this.mountLayer()}setupDesktopGate(){"undefined"!=typeof window&&(this.desktopMq=window.matchMedia("(pointer: fine) and (hover: hover) and (min-width: 769px)"),this.onDesktopChange=()=>{const t=this.desktopMq?.matches??!1;t!==this.enabled&&(this.enabled=t,t?this.mountLayer():this.teardownLayer())},this.onDesktopChange(),this.desktopMq.addEventListener("change",this.onDesktopChange))}updateScope(){this.isScoped=this.childElementCount>0||!!this.textContent?.trim()}isInScope(t){return!!t&&(!this.isScoped||this.contains(t))}mountLayer(){this.teardownLayer(),this.updateScope();const o=this.getAttribute("default-label")||"See the project",n=this.getAttribute("selector")||'a[href], button:not(:disabled), [role="button"]:not([aria-disabled="true"]), [data-cursor], [data-cursor-label], input[type="submit"], input[type="button"]',r=Math.min(1,Math.max(.05,Number(this.getAttribute("smoothness")||.14))),a=function parseOffset(t){if(!t)return{x:18,y:18};try{const e=JSON.parse(t);return{x:Number(e.x??18),y:Number(e.y??18)}}catch{const[e,s]=t.split(",").map(t=>Number(t.trim()));return{x:Number.isFinite(e)?e:18,y:Number.isFinite(s)?s:18}}}(this.getAttribute("offset")),l=this.hasAttribute("hide-native-cursor")&&"false"!==this.getAttribute("hide-native-cursor"),h=!this.hasAttribute("show-icon")||"false"!==this.getAttribute("show-icon");l&&document.documentElement.classList.add(i),this.portalRoot=document.createElement("div"),this.portalRoot.className=s,this.portalRoot.setAttribute("aria-hidden","true"),this.pillEl=document.createElement("div"),this.pillEl.className=`${s}__pill`,this.labelEl=document.createElement("span"),this.labelEl.textContent=o,this.pillEl.appendChild(this.labelEl),h&&(this.iconEl=document.createElement("span"),this.iconEl.className=`${s}__icon`,this.iconEl.appendChild(e("arrow-right",14)),this.pillEl.appendChild(this.iconEl)),this.portalRoot.appendChild(this.pillEl),t(this,this.portalRoot),document.body.appendChild(this.portalRoot),this.onMouseMove=t=>{this.target={x:t.clientX+a.x,y:t.clientY+a.y};const e=document.elementFromPoint(t.clientX,t.clientY),i=e?.closest(n)??null;this.isInScope(i)&&i?(this.labelEl&&(this.labelEl.textContent=function getLabelFromElement(t,e){return t.getAttribute("data-cursor-label")||t.getAttribute("data-cursor")||t.getAttribute("aria-label")||e}(i,o)),this.pillEl?.classList.add(`${s}__pill--visible`)):this.pillEl?.classList.remove(`${s}__pill--visible`)},window.addEventListener("mousemove",this.onMouseMove,{passive:!0});const tick=()=>{this.current.x+=(this.target.x-this.current.x)*r,this.current.y+=(this.target.y-this.current.y)*r,this.portalRoot&&(this.portalRoot.style.transform=`translate3d(${this.current.x}px, ${this.current.y}px, 0)`),this.raf=requestAnimationFrame(tick)};this.raf=requestAnimationFrame(tick)}teardownLayer(){cancelAnimationFrame(this.raf),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=void 0),document.documentElement.classList.remove(i),this.portalRoot?.remove(),this.portalRoot=void 0,this.pillEl=void 0,this.labelEl=void 0,this.iconEl=void 0}teardown(){this.teardownLayer(),this.desktopMq&&this.onDesktopChange&&this.desktopMq.removeEventListener("change",this.onDesktopChange),this.isScoped=!1,this.enabled=!1}}customElements.get("db-cursor-follower")||customElements.define("db-cursor-follower",DbCursorFollower);export{DbCursorFollower};
|
|
@@ -35,7 +35,8 @@ declare class DbDatePicker extends HTMLElement {
|
|
|
35
35
|
get inline(): boolean;
|
|
36
36
|
set inline(value: boolean);
|
|
37
37
|
private get type();
|
|
38
|
-
|
|
38
|
+
get locale(): string;
|
|
39
|
+
set locale(value: string);
|
|
39
40
|
private get startOfWeek();
|
|
40
41
|
private get showOutsideDays();
|
|
41
42
|
private get usesPendingValue();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbText as t,getDbLocale as e}from"../core/i18n.js";import{createDbIcon as i,getDbComponentIconSize as s}from"./db-icons.js";import"./db-button.js";import"./db-modal.js";import{startOfDay as n,parseISODate as a,DEFAULT_DATE_PICKER_PRESETS as r,formatDisplayDate as l,toISODate as d,detectActivePresetId as o,addMonths as h,generateWeekdays as u,generateCalendarGrid as c,formatPanelInputDate as p}from"./date-picker-utils.js";import{DATE_PICKER_SIZES as m,DATE_PICKER_VARIANTS as g}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const b="designbase-wc-date-picker",isRangeValue=t=>Boolean(t)&&"object"==typeof t&&!Array.isArray(t)&&"start"in t&&"end"in t;class DbDatePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.currentMonth=new Date,this.viewStartMonth=new Date,this.rangeStart=null,this.hoveredDate=null,this.activePresetId="custom",this.inputText="",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["mode","layout","type","inline","value","default-value","min-date","max-date","size","variant","disabled","readonly","label","full-width","error","locale","start-of-week","show-outside-days","dropdown-position","open","events"]}connectedCallback(){this.built||this.build(),this.readInitialValue(),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown)}attributeChangedCallback(t){if(this.built){if("value"===t&&(this.readAttributeValue(),this.syncInputText()),"open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get mode(){const t=this.getAttribute("mode")||"single";return"range"===t?"range":"multiple"===t?"multiple":"single"}set mode(t){this.setAttribute("mode",t)}get isPanelLayout(){return"panel"===this.getAttribute("layout")}get effectiveMode(){return this.isPanelLayout?"range":this.mode}get inline(){return this.hasAttribute("inline")}set inline(t){this.toggleAttribute("inline",Boolean(t))}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get locale(){return this.getAttribute("locale")||("ko"===e()?"ko-KR":"en-US")}get startOfWeek(){return"monday"===this.getAttribute("start-of-week")?"monday":"sunday"}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get usesPendingValue(){return this.isPanelLayout||"modal"===this.type}get today(){return n(new Date)}get minDate(){return a(this.getAttribute("min-date"))}get maxDate(){return a(this.getAttribute("max-date"))}get presets(){return this.isPanelLayout?r.map(e=>({...e,label:t(e.label)})):[]}get events(){const t=this.getAttribute("events");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${b}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${b}__trigger`;const e=document.createElement("button");e.type="button",e.className=`${b}__icon-display`,e.setAttribute("aria-label",t("날짜 선택 열기")),e.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${b}__input`,this.inputEl.setAttribute("aria-label",t("날짜 입력")),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const i=document.createElement("button");i.type="button",i.className=`${b}__toggle`,i.setAttribute("aria-label",t("날짜 선택 열기")),i.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(e,this.inputEl,i),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${b}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false"),this.calendarHost=document.createElement("div"),this.dropdownEl.appendChild(this.calendarHost)}readInitialValue(){const t=this.getAttribute("value")??this.getAttribute("default-value");if(t&&(this.selectedValue=this.parseValue(t)),this.tempValue=this.selectedValue,this.syncInputText(),isRangeValue(this.selectedValue)){const t=a(this.selectedValue.start);t&&(this.viewStartMonth=new Date(t))}else if("string"==typeof this.selectedValue){const t=a(this.selectedValue);t&&(this.currentMonth=new Date(t))}}readAttributeValue(){const t=this.getAttribute("value");if(!t)return this.selectedValue=void 0,void(this.tempValue=void 0);this.selectedValue=this.parseValue(t),this.isOpen&&this.usesPendingValue||(this.tempValue=this.selectedValue)}parseValue(t){if(t){if("multiple"===this.effectiveMode||t.trim().startsWith("["))try{const e=JSON.parse(t);if(Array.isArray(e))return e.filter(t=>Boolean(a(t)))}catch{return}if("range"===this.effectiveMode||t.trim().startsWith("{"))try{const e=JSON.parse(t);if(e?.start&&e?.end)return{start:e.start,end:e.end}}catch{return}return a(t)?t:void 0}}serializeValue(t){return t?"string"==typeof t?t:JSON.stringify(t):""}formatDisplay(t){if(!t)return"";if("string"==typeof t){const e=a(t);return e?l(e,this.locale):""}if(Array.isArray(t))return t.map(t=>a(t)).filter(Boolean).map(t=>l(t,this.locale)).join(", ");const e=a(t.start),i=a(t.end);return e&&i?t.start===t.end?l(e,this.locale):`${l(e,this.locale)} ~ ${l(i,this.locale)}`:""}syncInputText(){this.inputText=this.formatDisplay(this.selectedValue),this.inputEl&&(this.inputEl.value=this.inputText)}getWorkingValue(){return"range"===this.effectiveMode&&this.rangeStart?this.tempValue??this.selectedValue:this.usesPendingValue&&(this.isOpen||this.inline)?this.tempValue:this.selectedValue}presetContext(){return{today:this.today,startOfWeek:this.startOfWeek,minDate:this.minDate??void 0,maxDate:this.maxDate??void 0}}isDateValid(t){return!(this.minDate&&t<this.minDate)&&!(this.maxDate&&t>this.maxDate)}emitChange(t){const e=this.serializeValue(t);e?this.setAttribute("value",e):this.removeAttribute("value"),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t??null},bubbles:!0,composed:!0}))}applyValue(t,e=!this.usesPendingValue){if(e)return this.selectedValue=t,this.tempValue=t,this.syncInputText(),void this.emitChange(t);this.tempValue=t,this.renderCalendar()}handleDateClick(t){if(this.disabled||this.readonly||!this.isDateValid(t))return;this.isPanelLayout&&(this.activePresetId="custom");const e=this.getWorkingValue();if("single"===this.effectiveMode){const e=d(t);return this.applyValue(e,!this.usesPendingValue),this.inline||this.isPanelLayout||this.closePicker(),void this.render()}if("multiple"===this.effectiveMode){const i=d(t),s=Array.isArray(e)?e:[],n=s.includes(i)?s.filter(t=>t!==i):[...s,i];return this.applyValue(n,!this.usesPendingValue),void this.render()}if(!this.rangeStart)return this.rangeStart=t,this.applyValue({start:d(t),end:d(t)},!1),void this.renderCalendar();const i=this.rangeStart,s=t,n=i>s?{start:d(s),end:d(i)}:{start:d(i),end:d(s)};this.rangeStart=null,this.applyValue(n,!0),this.inline||this.isPanelLayout||this.closePicker(),this.render()}handlePresetSelect(t){if(this.activePresetId=t.id,this.rangeStart=null,"custom"===t.id)return void this.renderCalendar();const e=t.getRange(this.presetContext());if(!e)return;const i={start:d(e.start),end:d(e.end)};this.viewStartMonth=new Date(e.start),this.applyValue(i,!this.usesPendingValue),this.render()}handlePendingApply(){this.selectedValue=this.tempValue,this.syncInputText(),this.emitChange(this.tempValue),this.rangeStart=null,this.closePicker(),this.render()}handlePendingCancel(){this.tempValue=this.selectedValue,this.rangeStart=null,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext()),this.closePicker(),this.render()}handleInputBlur(){if(!this.inputEl)return;const t=this.inputEl.value.trim();if(t.match(/^(\d{4})-(\d{2})-(\d{2})$/)){const e=a(t);if(e&&this.isDateValid(e)){const t=d(e);return this.applyValue(t,!0),void this.render()}}this.syncInputText()}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}get readonly(){return this.hasAttribute("readonly")}set readonly(t){this.toggleAttribute("readonly",Boolean(t))}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,this.usesPendingValue&&(this.tempValue=this.selectedValue,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext())),this.render())}closePicker(){this.isOpen=!1,this.rangeStart=null,this.hoveredDate=null,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){this.isOpen&&!this.inline&&(this.contains(t.target)||(this.usesPendingValue&&(this.tempValue=this.selectedValue),this.closePicker()))}isDateSelected(t){const e=d(t),i=this.getWorkingValue();return"single"===this.effectiveMode?"string"==typeof i&&i===e:"multiple"===this.effectiveMode?Array.isArray(i)&&i.includes(e):!(!this.rangeStart||d(this.rangeStart)!==e)||!!isRangeValue(i)&&(i.start===e||i.end===e)}isInRange(t){if("range"!==this.effectiveMode)return!1;let e=null,i=null;if(this.rangeStart)e=this.rangeStart,i=this.hoveredDate;else{const t=this.getWorkingValue();isRangeValue(t)&&(e=a(t.start),i=a(t.end))}if(!e)return!1;const s=d(t),n=d(e),r=i?d(i):n;return s>=n&&s<=r}renderDateCell(t,e){const i=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear(),s=t.toDateString()===this.today.toDateString(),n=this.isDateSelected(t),r=this.isInRange(t),l=0===t.getDay()||6===t.getDay(),d=this.events.filter(e=>{const i=a(e.date);return!!i&&i.toDateString()===t.toDateString()}),o=this.getWorkingValue(),h=isRangeValue(o)?a(o.end)?.toDateString():void 0,u=isRangeValue(o)?a(o.start)?.toDateString():void 0,c=document.createElement("button");c.type="button",c.className=[`${b}__date`,!i&&this.showOutsideDays&&`${b}__date--outside`,s&&`${b}__date--today`,n&&`${b}__date--selected`,r&&!n&&`${b}__date--in-range`,"range"===this.effectiveMode&&(this.rangeStart?.toDateString()===t.toDateString()||u===t.toDateString())&&`${b}__date--range-start`,"range"===this.effectiveMode&&h===t.toDateString()&&`${b}__date--range-end`,l&&`${b}__date--weekend`,!this.isDateValid(t)&&`${b}__date--disabled`,d.length>0&&`${b}__date--has-events`].filter(Boolean).join(" "),c.disabled=!this.isDateValid(t)||this.disabled||this.readonly,c.addEventListener("click",()=>this.handleDateClick(t));const p=document.createElement("span");if(p.className=`${b}__date-number`,p.textContent=String(t.getDate()),c.appendChild(p),d.length>0){const t=document.createElement("div");t.className=`${b}__events`,d.slice(0,3).forEach(e=>{const i=document.createElement("div");i.className=`${b}__event ${b}__event--${e.type||"dot"}`,e.color&&(i.style.backgroundColor=e.color),e.label&&(i.title=e.label),t.appendChild(i)}),c.appendChild(t)}return c}renderSingleMonth(e,n={}){const{showPrev:a=!1,showNext:r=!1}=n,l=this.getAttribute("size")||"m",d=s(l),o=document.createElement("div");o.className=`${b}__month`;const p=document.createElement("div");if(p.className=`${b}__header`,a){const e=document.createElement("button");e.type="button",e.className=`${b}__nav-button`,e.setAttribute("aria-label",t("이전 달")),e.disabled=this.disabled||this.readonly,e.appendChild(i("chevron-left",d)),e.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,-1):this.currentMonth=h(this.currentMonth,-1),this.renderCalendar()}),p.appendChild(e)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}const m=document.createElement("div");if(m.className=`${b}__current-month`,m.textContent=e.toLocaleDateString(this.locale,{year:"numeric",month:"long"}),p.appendChild(m),r){const e=document.createElement("button");e.type="button",e.className=`${b}__nav-button`,e.setAttribute("aria-label",t("다음 달")),e.disabled=this.disabled||this.readonly,e.appendChild(i("chevron-right",d)),e.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,1):this.currentMonth=h(this.currentMonth,1),this.renderCalendar()}),p.appendChild(e)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}o.appendChild(p);const g=document.createElement("div");g.className=`${b}__weekdays`,u(this.startOfWeek,this.locale).forEach(t=>{const e=document.createElement("div");e.className=`${b}__weekday`,e.textContent=t,g.appendChild(e)}),o.appendChild(g);const v=document.createElement("div");v.className=`${b}__grid`;const y=this.isPanelLayout;return c(e,this.startOfWeek,y).forEach((t,i)=>{if(!t){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(i),void v.appendChild(t)}const s=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear();if(!this.showOutsideDays&&!s){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(i),void v.appendChild(t)}v.appendChild(this.renderDateCell(t,e))}),o.appendChild(v),o}renderDefaultCalendar(){const e=document.createElement("div");e.className=`${b}__selector`;const i=this.isPanelLayout?this.viewStartMonth:this.currentMonth;if(e.appendChild(this.renderSingleMonth(i,{showPrev:!0,showNext:!0})),!this.isPanelLayout){const i=document.createElement("div");i.className=`${b}__footer`;const s=document.createElement("button");s.type="button",s.className=`${b}__today-button`,s.textContent=t("오늘"),s.disabled=this.disabled||this.readonly,s.addEventListener("click",()=>{const t=new Date;this.isPanelLayout?this.viewStartMonth=t:this.currentMonth=t,this.renderCalendar()}),i.appendChild(s),e.appendChild(i)}return e}renderPanelCalendar(){const e=document.createElement("div");e.className=`${b}__panel`;const i=document.createElement("div");i.className=`${b}__presets`,i.setAttribute("role","listbox"),i.setAttribute("aria-label",t("기간 프리셋")),this.presets.forEach(t=>{const e=document.createElement("button");e.type="button",e.className=[`${b}__preset`,this.activePresetId===t.id&&`${b}__preset--active`].filter(Boolean).join(" "),e.setAttribute("role","option"),e.setAttribute("aria-selected",String(this.activePresetId===t.id)),e.textContent=t.label,e.addEventListener("click",()=>this.handlePresetSelect(t)),i.appendChild(e)}),e.appendChild(i);const s=document.createElement("div");s.className=`${b}__panel-main`;const n=document.createElement("div");n.className=`${b}__months ${b}__months--count-2`,[0,1].forEach(t=>{const e=h(this.viewStartMonth,t);n.appendChild(this.renderSingleMonth(e,{showPrev:0===t,showNext:1===t}))}),s.appendChild(n);const r=document.createElement("div");r.className=`${b}__panel-footer`;const l=isRangeValue(this.tempValue)?this.tempValue:void 0,d=document.createElement("div");d.className=`${b}__range-display`;const o=document.createElement("span");o.className=`${b}__range-text`,o.textContent=l?.start&&a(l.start)?p(a(l.start),this.locale):"시작일";const u=document.createElement("span");u.className=`${b}__range-separator`,u.textContent="–";const c=document.createElement("span");c.className=`${b}__range-text`,c.textContent=l?.end&&a(l.end)?p(a(l.end),this.locale):"종료일",d.append(o,u,c),r.appendChild(d);const m=document.createElement("div");m.className=`${b}__panel-actions`;const g=document.createElement("db-button");g.setAttribute("variant","secondary"),g.setAttribute("size","m"),g.textContent=t("취소"),g.addEventListener("click",()=>this.handlePendingCancel());const v=document.createElement("db-button");return v.setAttribute("variant","primary"),v.setAttribute("size","m"),v.textContent=t("적용"),v.addEventListener("click",()=>this.handlePendingApply()),m.append(g,v),r.appendChild(m),s.appendChild(r),e.appendChild(s),e}renderCalendar(){this.calendarHost&&(this.calendarHost.replaceChildren(),this.calendarHost.appendChild(this.isPanelLayout?this.renderPanelCalendar():this.renderDefaultCalendar()))}render(){const e=m.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",n=g.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",a=this.getAttribute("dropdown-position")||"bottom-start",r=s(e);if(this.className=[b,this.inline?`${b}--size-${e}`:`${b}--${e}`,`${b}--variant-${n}`,this.hasAttribute("full-width")&&`${b}--full-width`,this.disabled&&`${b}--disabled`,this.readonly&&`${b}--readonly`,this.isOpen&&`${b}--open`,this.hasAttribute("error")&&`${b}--error`,this.isPanelLayout&&`${b}--panel`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.replaceChildren(),this.inline)return this.calendarHost=document.createElement("div"),this.appendChild(this.calendarHost),void this.renderCalendar();if(!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const l=this.getAttribute("label")||"";this.labelEl.textContent=l,this.labelEl.hidden=!l,this.inputEl.value=this.inputText,this.inputEl.placeholder=this.isPanelLayout?"기간을 선택하세요":"날짜를 선택하세요",this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const d=this.triggerEl.querySelector(`.${b}__icon-display`);d&&(d.innerHTML="",d.appendChild(i("calendar",r)),d.disabled=this.disabled);const o=this.triggerEl.querySelector(`.${b}__toggle`);if(o&&(o.innerHTML="",o.appendChild(i("chevron-down",r)),o.disabled=this.disabled),this.dropdownEl.className=[`${b}__dropdown`,`${b}__dropdown--${a}`,this.isPanelLayout&&`${b}__dropdown--panel`].filter(Boolean).join(" "),this.dropdownEl.hidden=!this.isOpen||"modal"===this.type,this.calendarHost=document.createElement("div"),this.dropdownEl.replaceChildren(this.calendarHost),this.renderCalendar(),this.append(this.labelEl,this.triggerEl),this.isOpen&&"dropdown"===this.type&&this.appendChild(this.dropdownEl),this.isOpen&&"modal"===this.type){const e=document.createElement("db-modal");e.setAttribute("open","true"),e.setAttribute("title",this.isPanelLayout?"기간 선택":"날짜 선택"),e.setAttribute("size",this.isPanelLayout?"l":"s"),e.addEventListener("db-close",()=>this.handlePendingCancel());const i=document.createElement("div");if(this.calendarHost=i,this.renderCalendar(),e.append(i),this.usesPendingValue){const i=document.createElement("div");i.className=`${b}__modal-footer`;const s=document.createElement("db-button");s.setAttribute("variant","secondary"),s.setAttribute("size","m"),s.textContent=t("취소"),s.addEventListener("click",()=>this.handlePendingCancel());const n=document.createElement("db-button");n.setAttribute("variant","primary"),n.setAttribute("size","m"),n.textContent=t("적용"),n.addEventListener("click",()=>this.handlePendingApply()),i.append(s,n),e.append(i)}this.appendChild(e)}}}customElements.get("db-date-picker")||customElements.define("db-date-picker",DbDatePicker);export{DbDatePicker};
|
|
1
|
+
import{dbText as t}from"../core/i18n.js";import{createDbIcon as e,getDbComponentIconSize as i}from"./db-icons.js";import"./db-button.js";import"./db-modal.js";import{resolveDateLocale as s,startOfDay as n,parseISODate as a,DEFAULT_DATE_PICKER_PRESETS as r,formatDisplayDate as l,toISODate as d,detectActivePresetId as o,addMonths as h,generateWeekdays as u,generateCalendarGrid as c,formatPanelInputDate as p}from"./date-picker-utils.js";import{DATE_PICKER_SIZES as m,DATE_PICKER_VARIANTS as g}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const b="designbase-wc-date-picker",isRangeValue=t=>Boolean(t)&&"object"==typeof t&&!Array.isArray(t)&&"start"in t&&"end"in t;class DbDatePicker extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isOpen=!1,this.currentMonth=new Date,this.viewStartMonth=new Date,this.rangeStart=null,this.hoveredDate=null,this.activePresetId="custom",this.inputText="",this.boundDocumentMouseDown=t=>this.handleDocumentMouseDown(t),this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.isOpen&&(t.preventDefault(),this.closePicker(),this.inputEl?.focus())},this.boundDocumentKeyDown=t=>this.handleDocumentKeyDown(t)}static get observedAttributes(){return["mode","layout","type","inline","value","default-value","min-date","max-date","size","variant","disabled","readonly","label","full-width","error","locale","start-of-week","show-outside-days","dropdown-position","open","events"]}connectedCallback(){this.built||this.build(),this.readInitialValue(),this.render(),document.addEventListener("mousedown",this.boundDocumentMouseDown),document.addEventListener("keydown",this.boundDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.boundDocumentMouseDown),document.removeEventListener("keydown",this.boundDocumentKeyDown)}attributeChangedCallback(t){if(this.built){if("value"===t&&(this.readAttributeValue(),this.syncInputText()),"open"===t)return this.isOpen=this.hasAttribute("open"),void this.render();this.render()}}get value(){return this.getAttribute("value")||""}set value(t){t?this.setAttribute("value",t):this.removeAttribute("value")}get mode(){const t=this.getAttribute("mode")||"single";return"range"===t?"range":"multiple"===t?"multiple":"single"}set mode(t){this.setAttribute("mode",t)}get isPanelLayout(){return"panel"===this.getAttribute("layout")}get effectiveMode(){return this.isPanelLayout?"range":this.mode}get inline(){return this.hasAttribute("inline")}set inline(t){this.toggleAttribute("inline",Boolean(t))}get type(){return"modal"===this.getAttribute("type")?"modal":"dropdown"}get locale(){return s(this.getAttribute("locale"))}set locale(t){this.setAttribute("locale",t||"")}get startOfWeek(){return"monday"===this.getAttribute("start-of-week")?"monday":"sunday"}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get usesPendingValue(){return this.isPanelLayout||"modal"===this.type}get today(){return n(new Date)}get minDate(){return a(this.getAttribute("min-date"))}get maxDate(){return a(this.getAttribute("max-date"))}get presets(){return this.isPanelLayout?r.map(e=>({...e,label:t(e.label)})):[]}get events(){const t=this.getAttribute("events");if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e:[]}catch{return[]}}build(){this.built=!0,this.labelEl=document.createElement("label"),this.labelEl.className=`${b}__label`,this.triggerEl=document.createElement("div"),this.triggerEl.className=`${b}__trigger`;const e=document.createElement("button");e.type="button",e.className=`${b}__icon-display`,e.setAttribute("aria-label",t("날짜 선택 열기")),e.addEventListener("click",()=>this.toggleOpen()),this.inputEl=document.createElement("input"),this.inputEl.type="text",this.inputEl.className=`${b}__input`,this.inputEl.setAttribute("aria-label",t("날짜 입력")),this.inputEl.addEventListener("click",()=>this.openPicker()),this.inputEl.addEventListener("blur",()=>this.handleInputBlur()),this.inputEl.addEventListener("input",()=>{this.inputText=this.inputEl?.value||""});const i=document.createElement("button");i.type="button",i.className=`${b}__toggle`,i.setAttribute("aria-label",t("날짜 선택 열기")),i.addEventListener("click",()=>this.toggleOpen()),this.triggerEl.append(e,this.inputEl,i),this.dropdownEl=document.createElement("div"),this.dropdownEl.className=`${b}__dropdown`,this.dropdownEl.setAttribute("role","dialog"),this.dropdownEl.setAttribute("aria-modal","false"),this.calendarHost=document.createElement("div"),this.dropdownEl.appendChild(this.calendarHost)}readInitialValue(){const t=this.getAttribute("value")??this.getAttribute("default-value");if(t&&(this.selectedValue=this.parseValue(t)),this.tempValue=this.selectedValue,this.syncInputText(),isRangeValue(this.selectedValue)){const t=a(this.selectedValue.start);t&&(this.viewStartMonth=new Date(t))}else if("string"==typeof this.selectedValue){const t=a(this.selectedValue);t&&(this.currentMonth=new Date(t))}}readAttributeValue(){const t=this.getAttribute("value");if(!t)return this.selectedValue=void 0,void(this.tempValue=void 0);this.selectedValue=this.parseValue(t),this.isOpen&&this.usesPendingValue||(this.tempValue=this.selectedValue)}parseValue(t){if(t){if("multiple"===this.effectiveMode||t.trim().startsWith("["))try{const e=JSON.parse(t);if(Array.isArray(e))return e.filter(t=>Boolean(a(t)))}catch{return}if("range"===this.effectiveMode||t.trim().startsWith("{"))try{const e=JSON.parse(t);if(e?.start&&e?.end)return{start:e.start,end:e.end}}catch{return}return a(t)?t:void 0}}serializeValue(t){return t?"string"==typeof t?t:JSON.stringify(t):""}formatDisplay(t){if(!t)return"";if("string"==typeof t){const e=a(t);return e?l(e,this.locale):""}if(Array.isArray(t))return t.map(t=>a(t)).filter(Boolean).map(t=>l(t,this.locale)).join(", ");const e=a(t.start),i=a(t.end);return e&&i?t.start===t.end?l(e,this.locale):`${l(e,this.locale)} ~ ${l(i,this.locale)}`:""}syncInputText(){this.inputText=this.formatDisplay(this.selectedValue),this.inputEl&&(this.inputEl.value=this.inputText)}getWorkingValue(){return"range"===this.effectiveMode&&this.rangeStart?this.tempValue??this.selectedValue:this.usesPendingValue&&(this.isOpen||this.inline)?this.tempValue:this.selectedValue}presetContext(){return{today:this.today,startOfWeek:this.startOfWeek,minDate:this.minDate??void 0,maxDate:this.maxDate??void 0}}isDateValid(t){return!(this.minDate&&t<this.minDate)&&!(this.maxDate&&t>this.maxDate)}emitChange(t){const e=this.serializeValue(t);e?this.setAttribute("value",e):this.removeAttribute("value"),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:t??null},bubbles:!0,composed:!0}))}applyValue(t,e=!this.usesPendingValue){if(e)return this.selectedValue=t,this.tempValue=t,this.syncInputText(),void this.emitChange(t);this.tempValue=t,this.renderCalendar()}handleDateClick(t){if(this.disabled||this.readonly||!this.isDateValid(t))return;this.isPanelLayout&&(this.activePresetId="custom");const e=this.getWorkingValue();if("single"===this.effectiveMode){const e=d(t);return this.applyValue(e,!this.usesPendingValue),this.inline||this.isPanelLayout||this.closePicker(),void this.render()}if("multiple"===this.effectiveMode){const i=d(t),s=Array.isArray(e)?e:[],n=s.includes(i)?s.filter(t=>t!==i):[...s,i];return this.applyValue(n,!this.usesPendingValue),void this.render()}if(!this.rangeStart)return this.rangeStart=t,this.applyValue({start:d(t),end:d(t)},!1),void this.renderCalendar();const i=this.rangeStart,s=t,n=i>s?{start:d(s),end:d(i)}:{start:d(i),end:d(s)};this.rangeStart=null,this.applyValue(n,!0),this.inline||this.isPanelLayout||this.closePicker(),this.render()}handlePresetSelect(t){if(this.activePresetId=t.id,this.rangeStart=null,"custom"===t.id)return void this.renderCalendar();const e=t.getRange(this.presetContext());if(!e)return;const i={start:d(e.start),end:d(e.end)};this.viewStartMonth=new Date(e.start),this.applyValue(i,!this.usesPendingValue),this.render()}handlePendingApply(){this.selectedValue=this.tempValue,this.syncInputText(),this.emitChange(this.tempValue),this.rangeStart=null,this.closePicker(),this.render()}handlePendingCancel(){this.tempValue=this.selectedValue,this.rangeStart=null,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext()),this.closePicker(),this.render()}handleInputBlur(){if(!this.inputEl)return;const t=this.inputEl.value.trim();if(t.match(/^(\d{4})-(\d{2})-(\d{2})$/)){const e=a(t);if(e&&this.isDateValid(e)){const t=d(e);return this.applyValue(t,!0),void this.render()}}this.syncInputText()}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}get readonly(){return this.hasAttribute("readonly")}set readonly(t){this.toggleAttribute("readonly",Boolean(t))}openPicker(){this.disabled||this.readonly||(this.isOpen=!0,this.usesPendingValue&&(this.tempValue=this.selectedValue,this.activePresetId=o(isRangeValue(this.selectedValue)?{start:a(this.selectedValue.start),end:a(this.selectedValue.end)}:void 0,this.presets,this.presetContext())),this.render())}closePicker(){this.isOpen=!1,this.rangeStart=null,this.hoveredDate=null,this.render()}toggleOpen(){this.isOpen?this.closePicker():this.openPicker()}handleDocumentMouseDown(t){this.isOpen&&!this.inline&&(this.contains(t.target)||(this.usesPendingValue&&(this.tempValue=this.selectedValue),this.closePicker()))}isDateSelected(t){const e=d(t),i=this.getWorkingValue();return"single"===this.effectiveMode?"string"==typeof i&&i===e:"multiple"===this.effectiveMode?Array.isArray(i)&&i.includes(e):!(!this.rangeStart||d(this.rangeStart)!==e)||!!isRangeValue(i)&&(i.start===e||i.end===e)}isInRange(t){if("range"!==this.effectiveMode)return!1;let e=null,i=null;if(this.rangeStart)e=this.rangeStart,i=this.hoveredDate;else{const t=this.getWorkingValue();isRangeValue(t)&&(e=a(t.start),i=a(t.end))}if(!e)return!1;const s=d(t),n=d(e),r=i?d(i):n;return s>=n&&s<=r}renderDateCell(t,e){const i=t.getMonth()===e.getMonth()&&t.getFullYear()===e.getFullYear(),s=t.toDateString()===this.today.toDateString(),n=this.isDateSelected(t),r=this.isInRange(t),l=0===t.getDay()||6===t.getDay(),d=this.events.filter(e=>{const i=a(e.date);return!!i&&i.toDateString()===t.toDateString()}),o=this.getWorkingValue(),h=isRangeValue(o)?a(o.end)?.toDateString():void 0,u=isRangeValue(o)?a(o.start)?.toDateString():void 0,c=document.createElement("button");c.type="button",c.className=[`${b}__date`,!i&&this.showOutsideDays&&`${b}__date--outside`,s&&`${b}__date--today`,n&&`${b}__date--selected`,r&&!n&&`${b}__date--in-range`,"range"===this.effectiveMode&&(this.rangeStart?.toDateString()===t.toDateString()||u===t.toDateString())&&`${b}__date--range-start`,"range"===this.effectiveMode&&h===t.toDateString()&&`${b}__date--range-end`,l&&`${b}__date--weekend`,!this.isDateValid(t)&&`${b}__date--disabled`,d.length>0&&`${b}__date--has-events`].filter(Boolean).join(" "),c.disabled=!this.isDateValid(t)||this.disabled||this.readonly,c.addEventListener("click",()=>this.handleDateClick(t));const p=document.createElement("span");if(p.className=`${b}__date-number`,p.textContent=String(t.getDate()),c.appendChild(p),d.length>0){const t=document.createElement("div");t.className=`${b}__events`,d.slice(0,3).forEach(e=>{const i=document.createElement("div");i.className=`${b}__event ${b}__event--${e.type||"dot"}`,e.color&&(i.style.backgroundColor=e.color),e.label&&(i.title=e.label),t.appendChild(i)}),c.appendChild(t)}return c}renderSingleMonth(s,n={}){const{showPrev:a=!1,showNext:r=!1}=n,l=this.getAttribute("size")||"m",d=i(l),o=document.createElement("div");o.className=`${b}__month`;const p=document.createElement("div");if(p.className=`${b}__header`,a){const i=document.createElement("button");i.type="button",i.className=`${b}__nav-button`,i.setAttribute("aria-label",t("이전 달")),i.disabled=this.disabled||this.readonly,i.appendChild(e("chevron-left",d)),i.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,-1):this.currentMonth=h(this.currentMonth,-1),this.renderCalendar()}),p.appendChild(i)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}const m=document.createElement("div");if(m.className=`${b}__current-month`,m.textContent=s.toLocaleDateString(this.locale,{year:"numeric",month:"long"}),p.appendChild(m),r){const i=document.createElement("button");i.type="button",i.className=`${b}__nav-button`,i.setAttribute("aria-label",t("다음 달")),i.disabled=this.disabled||this.readonly,i.appendChild(e("chevron-right",d)),i.addEventListener("click",()=>{this.isPanelLayout?this.viewStartMonth=h(this.viewStartMonth,1):this.currentMonth=h(this.currentMonth,1),this.renderCalendar()}),p.appendChild(i)}else{const t=document.createElement("span");t.className=`${b}__nav-spacer`,t.setAttribute("aria-hidden","true"),p.appendChild(t)}o.appendChild(p);const g=document.createElement("div");g.className=`${b}__weekdays`,u(this.startOfWeek,this.locale).forEach(t=>{const e=document.createElement("div");e.className=`${b}__weekday`,e.textContent=t,g.appendChild(e)}),o.appendChild(g);const v=document.createElement("div");v.className=`${b}__grid`;const y=this.isPanelLayout;return c(s,this.startOfWeek,y).forEach((t,e)=>{if(!t){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(e),void v.appendChild(t)}const i=t.getMonth()===s.getMonth()&&t.getFullYear()===s.getFullYear();if(!this.showOutsideDays&&!i){const t=document.createElement("span");return t.className=`${b}__date ${b}__date--empty`,t.setAttribute("aria-hidden","true"),t.dataset.index=String(e),void v.appendChild(t)}v.appendChild(this.renderDateCell(t,s))}),o.appendChild(v),o}renderDefaultCalendar(){const e=document.createElement("div");e.className=`${b}__selector`;const i=this.isPanelLayout?this.viewStartMonth:this.currentMonth;if(e.appendChild(this.renderSingleMonth(i,{showPrev:!0,showNext:!0})),!this.isPanelLayout){const i=document.createElement("div");i.className=`${b}__footer`;const s=document.createElement("button");s.type="button",s.className=`${b}__today-button`,s.textContent=t("오늘"),s.disabled=this.disabled||this.readonly,s.addEventListener("click",()=>{const t=new Date;this.isPanelLayout?this.viewStartMonth=t:this.currentMonth=t,this.renderCalendar()}),i.appendChild(s),e.appendChild(i)}return e}renderPanelCalendar(){const e=document.createElement("div");e.className=`${b}__panel`;const i=document.createElement("div");i.className=`${b}__presets`,i.setAttribute("role","listbox"),i.setAttribute("aria-label",t("기간 프리셋")),this.presets.forEach(t=>{const e=document.createElement("button");e.type="button",e.className=[`${b}__preset`,this.activePresetId===t.id&&`${b}__preset--active`].filter(Boolean).join(" "),e.setAttribute("role","option"),e.setAttribute("aria-selected",String(this.activePresetId===t.id)),e.textContent=t.label,e.addEventListener("click",()=>this.handlePresetSelect(t)),i.appendChild(e)}),e.appendChild(i);const s=document.createElement("div");s.className=`${b}__panel-main`;const n=document.createElement("div");n.className=`${b}__months ${b}__months--count-2`,[0,1].forEach(t=>{const e=h(this.viewStartMonth,t);n.appendChild(this.renderSingleMonth(e,{showPrev:0===t,showNext:1===t}))}),s.appendChild(n);const r=document.createElement("div");r.className=`${b}__panel-footer`;const l=isRangeValue(this.tempValue)?this.tempValue:void 0,d=document.createElement("div");d.className=`${b}__range-display`;const o=document.createElement("span");o.className=`${b}__range-text`,o.textContent=l?.start&&a(l.start)?p(a(l.start),this.locale):"시작일";const u=document.createElement("span");u.className=`${b}__range-separator`,u.textContent="–";const c=document.createElement("span");c.className=`${b}__range-text`,c.textContent=l?.end&&a(l.end)?p(a(l.end),this.locale):"종료일",d.append(o,u,c),r.appendChild(d);const m=document.createElement("div");m.className=`${b}__panel-actions`;const g=document.createElement("db-button");g.setAttribute("variant","secondary"),g.setAttribute("size","m"),g.textContent=t("취소"),g.addEventListener("click",()=>this.handlePendingCancel());const v=document.createElement("db-button");return v.setAttribute("variant","primary"),v.setAttribute("size","m"),v.textContent=t("적용"),v.addEventListener("click",()=>this.handlePendingApply()),m.append(g,v),r.appendChild(m),s.appendChild(r),e.appendChild(s),e}renderCalendar(){this.calendarHost&&(this.calendarHost.replaceChildren(),this.calendarHost.appendChild(this.isPanelLayout?this.renderPanelCalendar():this.renderDefaultCalendar()))}render(){const s=m.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",n=g.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",a=this.getAttribute("dropdown-position")||"bottom-start",r=i(s);if(this.className=[b,this.inline?`${b}--size-${s}`:`${b}--${s}`,`${b}--variant-${n}`,this.hasAttribute("full-width")&&`${b}--full-width`,this.disabled&&`${b}--disabled`,this.readonly&&`${b}--readonly`,this.isOpen&&`${b}--open`,this.hasAttribute("error")&&`${b}--error`,this.isPanelLayout&&`${b}--panel`].filter(Boolean).join(" "),this.inputEl?.setAttribute("aria-invalid",String(this.hasAttribute("error"))),this.replaceChildren(),this.inline)return this.calendarHost=document.createElement("div"),this.appendChild(this.calendarHost),void this.renderCalendar();if(!(this.labelEl&&this.triggerEl&&this.inputEl&&this.dropdownEl))return;const l=this.getAttribute("label")||"";this.labelEl.textContent=l,this.labelEl.hidden=!l,this.inputEl.value=this.inputText,this.inputEl.placeholder=this.isPanelLayout?"기간을 선택하세요":"날짜를 선택하세요",this.inputEl.disabled=this.disabled,this.inputEl.readOnly=this.readonly;const d=this.triggerEl.querySelector(`.${b}__icon-display`);d&&(d.innerHTML="",d.appendChild(e("calendar",r)),d.disabled=this.disabled);const o=this.triggerEl.querySelector(`.${b}__toggle`);if(o&&(o.innerHTML="",o.appendChild(e("chevron-down",r)),o.disabled=this.disabled),this.dropdownEl.className=[`${b}__dropdown`,`${b}__dropdown--${a}`,this.isPanelLayout&&`${b}__dropdown--panel`].filter(Boolean).join(" "),this.dropdownEl.hidden=!this.isOpen||"modal"===this.type,this.calendarHost=document.createElement("div"),this.dropdownEl.replaceChildren(this.calendarHost),this.renderCalendar(),this.append(this.labelEl,this.triggerEl),this.isOpen&&"dropdown"===this.type&&this.appendChild(this.dropdownEl),this.isOpen&&"modal"===this.type){const e=document.createElement("db-modal");e.setAttribute("open","true"),e.setAttribute("title",this.isPanelLayout?"기간 선택":"날짜 선택"),e.setAttribute("size",this.isPanelLayout?"l":"s"),e.addEventListener("db-close",()=>this.handlePendingCancel());const i=document.createElement("div");if(this.calendarHost=i,this.renderCalendar(),e.append(i),this.usesPendingValue){const i=document.createElement("div");i.className=`${b}__modal-footer`;const s=document.createElement("db-button");s.setAttribute("variant","secondary"),s.setAttribute("size","m"),s.textContent=t("취소"),s.addEventListener("click",()=>this.handlePendingCancel());const n=document.createElement("db-button");n.setAttribute("variant","primary"),n.setAttribute("size","m"),n.textContent=t("적용"),n.addEventListener("click",()=>this.handlePendingApply()),i.append(s,n),e.append(i)}this.appendChild(e)}}}customElements.get("db-date-picker")||customElements.define("db-date-picker",DbDatePicker);export{DbDatePicker};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbText as t}from"../core/i18n.js";import{DbToolButton as e}from"./db-tool-button.js";class DbDesignToolbar extends HTMLElement{constructor(){super(...arguments),this.tools=new Map,this.focusId="",this.connected=!1,this.location={x:12,y:12},this.focusIn=t=>{const e=t.target.closest("db-button");e&&(this.focusId=e.dataset.toolId||"",this.rove())},this.keyDown=t=>{if(!t.target.closest("db-tool-button"))return;const e="vertical"===this.getAttribute("orientation"),i=e?"ArrowDown":"ArrowRight";if(![e?"ArrowUp":"ArrowLeft",i,"Home","End"].includes(t.key))return;t.preventDefault();const o=this.buttons(),s=o.indexOf(document.activeElement),n="Home"===t.key?0:"End"===t.key?o.length-1:(s+(t.key===i?1:-1)+o.length)%o.length;o[n]?.focus()},this.dragStart=t=>{if(0!==t.button||!this.parentElement)return;t.preventDefault(),t.stopPropagation(),this.closeMenus();const e=this.parentElement.getBoundingClientRect();this.dragState={pointer:t.pointerId,clientX:t.clientX,clientY:t.clientY,...this.location,scaleX:e.width/Math.max(1,this.parentElement.offsetWidth),scaleY:e.height/Math.max(1,this.parentElement.offsetHeight)},this.grip?.querySelector("db-button")?.focus({preventScroll:!0}),this.setPointerCapture(t.pointerId),this.setAttribute("data-moving","")},this.dragMove=t=>{const e=this.dragState;e&&t.pointerId===e.pointer&&(t.preventDefault(),t.stopPropagation(),this.location={x:e.x+(t.clientX-e.clientX)/e.scaleX,y:e.y+(t.clientY-e.clientY)/e.scaleY},this.constrainPosition(!0))},this.dragEnd=t=>{this.dragState?.pointer===t.pointerId&&(this.dragState=void 0,this.removeAttribute("data-moving"),this.hasPointerCapture(t.pointerId)&&this.releasePointerCapture(t.pointerId),this.constrainPosition(!0))},this.dragCancel=t=>{this.dragState?.pointer===t.pointerId&&this.dragEnd(t)},this.gripKey=t=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home"].includes(t.key))return;if(t.preventDefault(),t.stopPropagation(),"Home"===t.key)return void this.resetPosition();const e=t.shiftKey?20:4;this.location.x+="ArrowRight"===t.key?e:"ArrowLeft"===t.key?-e:0,this.location.y+="ArrowDown"===t.key?e:"ArrowUp"===t.key?-e:0,this.constrainPosition(!0)}}static get observedAttributes(){return["items","size","tone","orientation","placement","movable","toolbar-position"]}get toolbarPosition(){return{...this.location}}set toolbarPosition(t){try{const e="string"==typeof t?JSON.parse(t):t;this.location={x:Number.isFinite(e.x)?e.x:12,y:Number.isFinite(e.y)?e.y:12},this.constrainPosition()}catch{}}get items(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t.filter(t=>t&&"string"==typeof t.id):[]}catch{return[]}}set items(t){const e="string"==typeof t?t:JSON.stringify(t);e!==this.getAttribute("items")&&this.setAttribute("items",e)}connectedCallback(){this.connected=!0,this.classList.add("designbase-wc-design-toolbar"),this.setAttribute("role","toolbar"),this.hasAttribute("aria-label")||this.setAttribute("aria-label",t("디자인 도구")),this.addEventListener("keydown",this.keyDown),this.addEventListener("focusin",this.focusIn),this.sync(),this.addEventListener("pointermove",this.dragMove),this.addEventListener("pointerup",this.dragEnd),this.addEventListener("pointercancel",this.dragCancel),this.addEventListener("lostpointercapture",this.dragCancel),this.boundaryObserver=new ResizeObserver(()=>this.constrainPosition()),this.parentElement&&this.boundaryObserver.observe(this.parentElement),this.boundaryObserver.observe(this),this.constrainPosition()}disconnectedCallback(){this.connected=!1,this.dragState=void 0,this.boundaryObserver?.disconnect(),this.removeEventListener("pointermove",this.dragMove),this.removeEventListener("pointerup",this.dragEnd),this.removeEventListener("pointercancel",this.dragCancel),this.removeEventListener("lostpointercapture",this.dragCancel),this.removeEventListener("keydown",this.keyDown),this.removeEventListener("focusin",this.focusIn)}attributeChangedCallback(t){"toolbar-position"===t&&(this.toolbarPosition=this.getAttribute("toolbar-position")||"{}"),this.connected&&this.sync()}sync(){const t=this.items,e=new Set,set=(t,e,i)=>{t.getAttribute(e)!==i&&t.setAttribute(e,i)},
|
|
1
|
+
import{dbText as t}from"../core/i18n.js";import{DbToolButton as e}from"./db-tool-button.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{DESIGN_TOOL_TONES as o,DESIGN_TOOL_SIZES as s,POPOVER_PLACEMENTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDesignToolbar extends HTMLElement{constructor(){super(...arguments),this.tools=new Map,this.focusId="",this.connected=!1,this.location={x:12,y:12},this.focusIn=t=>{const e=t.target.closest("db-button");e&&(this.focusId=e.dataset.toolId||"",this.rove())},this.keyDown=t=>{if(!t.target.closest("db-tool-button"))return;const e="vertical"===this.getAttribute("orientation"),i=e?"ArrowDown":"ArrowRight";if(![e?"ArrowUp":"ArrowLeft",i,"Home","End"].includes(t.key))return;t.preventDefault();const o=this.buttons(),s=o.indexOf(document.activeElement),n="Home"===t.key?0:"End"===t.key?o.length-1:(s+(t.key===i?1:-1)+o.length)%o.length;o[n]?.focus()},this.dragStart=t=>{if(0!==t.button||!this.parentElement)return;t.preventDefault(),t.stopPropagation(),this.closeMenus();const e=this.parentElement.getBoundingClientRect();this.dragState={pointer:t.pointerId,clientX:t.clientX,clientY:t.clientY,...this.location,scaleX:e.width/Math.max(1,this.parentElement.offsetWidth),scaleY:e.height/Math.max(1,this.parentElement.offsetHeight)},this.grip?.querySelector("db-button")?.focus({preventScroll:!0}),this.setPointerCapture(t.pointerId),this.setAttribute("data-moving","")},this.dragMove=t=>{const e=this.dragState;e&&t.pointerId===e.pointer&&(t.preventDefault(),t.stopPropagation(),this.location={x:e.x+(t.clientX-e.clientX)/e.scaleX,y:e.y+(t.clientY-e.clientY)/e.scaleY},this.constrainPosition(!0))},this.dragEnd=t=>{this.dragState?.pointer===t.pointerId&&(this.dragState=void 0,this.removeAttribute("data-moving"),this.hasPointerCapture(t.pointerId)&&this.releasePointerCapture(t.pointerId),this.constrainPosition(!0))},this.dragCancel=t=>{this.dragState?.pointer===t.pointerId&&this.dragEnd(t)},this.gripKey=t=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home"].includes(t.key))return;if(t.preventDefault(),t.stopPropagation(),"Home"===t.key)return void this.resetPosition();const e=t.shiftKey?20:4;this.location.x+="ArrowRight"===t.key?e:"ArrowLeft"===t.key?-e:0,this.location.y+="ArrowDown"===t.key?e:"ArrowUp"===t.key?-e:0,this.constrainPosition(!0)}}static get observedAttributes(){return["items","size","tone","orientation","placement","movable","toolbar-position"]}get toolbarPosition(){return{...this.location}}set toolbarPosition(t){try{const e="string"==typeof t?JSON.parse(t):t;this.location={x:Number.isFinite(e.x)?e.x:12,y:Number.isFinite(e.y)?e.y:12},this.constrainPosition()}catch{}}get items(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t.filter(t=>t&&"string"==typeof t.id):[]}catch{return[]}}set items(t){const e="string"==typeof t?t:JSON.stringify(t);e!==this.getAttribute("items")&&this.setAttribute("items",e)}connectedCallback(){this.connected=!0,this.classList.add("designbase-wc-design-toolbar"),this.setAttribute("role","toolbar"),this.hasAttribute("aria-label")||this.setAttribute("aria-label",t("디자인 도구")),this.addEventListener("keydown",this.keyDown),this.addEventListener("focusin",this.focusIn),this.sync(),this.addEventListener("pointermove",this.dragMove),this.addEventListener("pointerup",this.dragEnd),this.addEventListener("pointercancel",this.dragCancel),this.addEventListener("lostpointercapture",this.dragCancel),this.boundaryObserver=new ResizeObserver(()=>this.constrainPosition()),this.parentElement&&this.boundaryObserver.observe(this.parentElement),this.boundaryObserver.observe(this),this.constrainPosition()}disconnectedCallback(){this.connected=!1,this.dragState=void 0,this.boundaryObserver?.disconnect(),this.removeEventListener("pointermove",this.dragMove),this.removeEventListener("pointerup",this.dragEnd),this.removeEventListener("pointercancel",this.dragCancel),this.removeEventListener("lostpointercapture",this.dragCancel),this.removeEventListener("keydown",this.keyDown),this.removeEventListener("focusin",this.focusIn)}attributeChangedCallback(t){"toolbar-position"===t&&(this.toolbarPosition=this.getAttribute("toolbar-position")||"{}"),this.connected&&this.sync()}sync(){const t=this.items,e=new Set,set=(t,e,i)=>{t.getAttribute(e)!==i&&t.setAttribute(e,i)},r=[];this.hasAttribute("movable")?(this.grip||(this.grip=document.createElement("db-tool-button"),this.grip.setAttribute("tool-id","move-toolbar"),this.grip.setAttribute("label","툴바 이동"),this.grip.setAttribute("shortcut","드래그 / 방향키"),this.grip.setAttribute("icon","grip-vertical"),this.grip.setAttribute("data-toolbar-grip",""),this.grip.addEventListener("db-tool-action",t=>t.stopPropagation()),this.grip.addEventListener("pointerdown",this.dragStart),this.grip.addEventListener("keydown",this.gripKey)),set(this.grip,"tone",i(this.getAttribute("tone"),o,"default")),set(this.grip,"size",i(this.getAttribute("size"),s,"m")),r.push(this.grip)):this.grip?.remove();for(const a of t){if(e.has(a.id))continue;e.add(a.id);let t=this.tools.get(a.id);const h="separator"===a.type;t&&"DB-TOOL-BUTTON"===t.tagName===h&&(t.remove(),this.tools.delete(a.id),t=void 0),t||(t=h?document.createElement("span"):document.createElement("db-tool-button"),this.tools.set(a.id,t)),h?(t.setAttribute("role","separator"),t.className="designbase-wc-design-toolbar__separator"):(set(t,"tool-id",a.id),set(t,"label",a.label||a.id),set(t,"icon",a.icon||""),void 0!==a.text?set(t,"text",a.text):t.removeAttribute("text"),set(t,"shortcut",a.shortcut||""),set(t,"options",JSON.stringify(a.options||[])),set(t,"value",a.value||""),set(t,"menu-trigger",a.menuTrigger||"click"),set(t,"size",i(this.getAttribute("size"),s,"m")),set(t,"tone",i(this.getAttribute("tone"),o,"default")),set(t,"placement",i(this.getAttribute("placement"),n,"bottom-start")),t.toggleAttribute("toggle","boolean"==typeof a.active),t.toggleAttribute("active",!!a.active),t.toggleAttribute("disabled",!!a.disabled)),r.push(t)}for(const[t,i]of this.tools)e.has(t)||(i.remove(),this.tools.delete(t));r.forEach((t,e)=>{this.children[e]!==t&&this.insertBefore(t,this.children[e]||null)}),this.setAttribute("aria-orientation","vertical"===this.getAttribute("orientation")?"vertical":"horizontal"),this.rove(),this.constrainPosition()}buttons(){return Array.from(this.querySelectorAll(":scope > db-tool-button:not([disabled]) db-button"))}rove(){const t=this.buttons(),e=t.find(t=>t.dataset.toolId===this.focusId)||t[0];t.forEach(t=>t.tabIndex=t===e?0:-1)}constrainPosition(t=!1){if(!this.hasAttribute("movable")||!this.parentElement)return;const e=Math.max(0,this.parentElement.clientWidth-this.offsetWidth),i=Math.max(0,this.parentElement.clientHeight-this.offsetHeight),o=Math.min(8,e/2),s=Math.min(8,i/2);this.location={x:Math.max(o,Math.min(e-o,this.location.x)),y:Math.max(s,Math.min(i-s,this.location.y))},this.style.left=`${this.location.x}px`,this.style.top=`${this.location.y}px`,t&&this.dispatchEvent(new CustomEvent("db-position-change",{detail:this.toolbarPosition,bubbles:!0,composed:!0}))}resetPosition(){this.location={x:12,y:12},this.constrainPosition(!0)}closeMenus(){for(const t of this.tools.values())t instanceof e&&t.closeMenu(!1)}}customElements.get("db-design-toolbar")||customElements.define("db-design-toolbar",DbDesignToolbar);export{DbDesignToolbar};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DbElement as e}from"../core/base-element.js";import{createDbIcon as t}from"./db-icons.js";import{deviceMockupStyle as o}from"./device-mockup-style.js";import{MOCKUP_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c={default:[1600,1e3],tablet:[3,4],ios:[1206,2622],android:[1080,2340],watch:[416,496],flip:[1080,2520],"flip-cover":[948,1048],fold:[1968,2184],"fold-cover":[1080,2520],duo:[14,10],"duo-cover":[7,10]};class DbDeviceMockup extends e{constructor(){super(...arguments),this.model="default",this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return["src","alt","url","orientation","variant","screen-title","notch","fold-state","cover-src"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}node(e,t,o){const s=document.createElement(e);return s.className=t,void 0!==o&&(s.textContent=o),s}decorative(e){const t=this.node("span",e);return t.setAttribute("aria-hidden","true"),t}tools(e,o){const s=this.decorative(`tools ${o}`);return e.forEach(e=>s.append(t(e,14))),s}watchBand(e){const t=document.createElementNS("http://www.w3.org/2000/svg","svg");
|
|
1
|
+
import{DbElement as e}from"../core/base-element.js";import{createDbIcon as t}from"./db-icons.js";import{deviceMockupStyle as o}from"./device-mockup-style.js";import{MOCKUP_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c={default:[1600,1e3],tablet:[3,4],ios:[1206,2622],android:[1080,2340],watch:[416,496],flip:[1080,2520],"flip-cover":[948,1048],fold:[1968,2184],"fold-cover":[1080,2520],duo:[14,10],"duo-cover":[7,10]};class DbDeviceMockup extends e{constructor(){super(...arguments),this.model="default",this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return["src","alt","url","orientation","variant","screen-title","notch","fold-state","cover-src"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}node(e,t,o){const s=document.createElement(e);return s.className=t,void 0!==o&&(s.textContent=o),s}decorative(e){const t=this.node("span",e);return t.setAttribute("aria-hidden","true"),t}tools(e,o){const s=this.decorative(`tools ${o}`);return e.forEach(e=>s.append(t(e,14))),s}watchBand(e){const t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("class",`watch-band watch-band--${e}`),t.setAttribute("viewBox","0 0 160 100"),t.setAttribute("preserveAspectRatio","none"),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false");const make=(e,t)=>{const o=document.createElementNS("http://www.w3.org/2000/svg",e);for(const[e,s]of Object.entries(t))o.setAttribute(e,s);return o},o=make("defs",{}),s=make("linearGradient",{id:`band-${e}`,x1:"0",y1:"0",x2:"1",y2:"0"});for(const[e,t]of[["0","#232426"],[".12","#3c3d40"],[".38","#343538"],[".72","#323336"],[".91","#3b3c3f"],["1","#242527"]])s.append(make("stop",{offset:e,"stop-color":t}));const c=make("linearGradient",{id:`band-shade-${e}`,x1:"0",y1:"0",x2:"0",y2:"1"});for(const[e,t,o]of[["0","#fff",".04"],[".5","#fff","0"],["1","#000",".22"]])c.append(make("stop",{offset:e,"stop-color":t,"stop-opacity":o}));o.append(s,c);const i="M28 13 C35 3 125 3 132 13 C139 25 133 57 149 81 L160 100 H0 L11 81 C27 57 21 25 28 13Z";return t.append(o,make("path",{d:i,fill:`url(#band-${e})`}),make("path",{d:i,fill:`url(#band-shade-${e})`})),t}browserChrome(){const e=this.node("div","chrome"),o=this.node("div","tab-strip"),s=this.decorative("dots");for(let e=0;e<3;e++)s.append(document.createElement("i"));const c=this.node("div","tab");c.setAttribute("aria-hidden","true"),c.append(document.createElement("b"),this.node("span","",this.getAttribute("screen-title")||"Preview"),t("close",11)),o.append(s,c);const i=this.node("div","toolbar"),d=this.node("div","url");return d.append(t("lock",11),this.node("span","",this.getAttribute("url")||"example.com")),i.append(this.tools(["chevron-left","chevron-right","refresh"],"tools--left"),d,this.tools(["share-alt","plus","copy"],"tools--right")),e.append(o,i),e}render(){const e=document.createElement("style");e.textContent=o,this.dataset.device=this.device,this.dataset.model=this.model;const t="flip"===this.model||"fold"===this.model||"duo"===this.model,i=t&&"closed"===this.getAttribute("fold-state");this.dataset.foldState=i?"closed":"open",this.dataset.variant=s.find(e=>e===this.getAttribute("variant"))||"realistic";const d=this.getAttribute("notch"),n="ios"===this.model?"island":["android","flip","fold","duo"].includes(this.model)?"punch":"none";this.dataset.notch="watch"===this.device||"browser"===this.device||i&&"flip"===this.model?"none":"none"===d||"island"===d||"punch"===d?d:n;const r=this.node("div","frame");r.part.add("frame"),"browser"===this.device&&r.append(this.browserChrome());const a=this.node("div","screen");a.part.add("screen");const l="tablet"===this.device?"tablet":i?`${this.model}-cover`:this.model,[p,u]=c[l]||c.default,h="landscape"===this.getAttribute("orientation")&&"watch"!==this.device;a.style.aspectRatio=`var(--db-mockup-ratio, ${h?u:p} / ${h?p:u})`;const b=this.node("div","content");b.part.add("content");const m=i&&this.getAttribute("cover-src")||this.getAttribute("src");if(m){const e=document.createElement("img");e.src=m,e.alt=this.getAttribute("alt")||"",e.loading="lazy",b.append(e)}else{const e=document.createElement("slot");i&&this.querySelector('[slot="cover"]')&&(e.name="cover"),b.append(e)}a.append(b),r.append(a),"browser"!==this.device&&("none"!==this.dataset.notch&&r.append(this.decorative("camera")),t&&!i&&a.append(this.decorative("crease")),"flip"===this.model&&i&&a.append(this.decorative("cover-cameras")),"watch"===this.device&&(r.append(this.watchBand("top"),this.watchBand("bottom"),this.decorative("crown")),a.append(this.decorative("watch-glass"))),"duo"===this.model&&r.append(this.decorative("hinge")),r.append(this.decorative("side side--power"),this.decorative("side side--volume"),this.decorative("side side--action"))),this.root.replaceChildren(e,r)}}class DbBrowserMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="browser"}}class DbTabletMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="tablet"}}class DbMobileMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="mobile",this.model="ios"}}class DbIosMockup extends DbMobileMockup{}class DbAndroidMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="android"}}class DbAppleWatchMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="watch",this.model="watch"}}class DbFlipMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="flip"}}class DbFoldMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="fold"}}class DbDuoMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="duo"}}customElements.get("db-browser-mockup")||customElements.define("db-browser-mockup",DbBrowserMockup),customElements.get("db-tablet-mockup")||customElements.define("db-tablet-mockup",DbTabletMockup),customElements.get("db-mobile-mockup")||customElements.define("db-mobile-mockup",DbMobileMockup),customElements.get("db-ios-mockup")||customElements.define("db-ios-mockup",DbIosMockup),customElements.get("db-android-mockup")||customElements.define("db-android-mockup",DbAndroidMockup),customElements.get("db-apple-watch-mockup")||customElements.define("db-apple-watch-mockup",DbAppleWatchMockup),customElements.get("db-flip-mockup")||customElements.define("db-flip-mockup",DbFlipMockup),customElements.get("db-fold-mockup")||customElements.define("db-fold-mockup",DbFoldMockup),customElements.get("db-duo-mockup")||customElements.define("db-duo-mockup",DbDuoMockup);export{c as DEVICE_MOCKUP_SCREENS,DbAndroidMockup,DbAppleWatchMockup,DbBrowserMockup,DbDuoMockup,DbFlipMockup,DbFoldMockup,DbIosMockup,DbMobileMockup,DbTabletMockup};
|
|
@@ -17,6 +17,7 @@ declare class DbDrawer extends HTMLElement {
|
|
|
17
17
|
/** 잠근 적이 있을 때만 푼다 — 카운트가 음수로 새지 않도록 */
|
|
18
18
|
private releaseScrollLock;
|
|
19
19
|
attributeChangedCallback(name: string): void;
|
|
20
|
+
private syncInteraction;
|
|
20
21
|
private isOpenRequested;
|
|
21
22
|
private clearTimers;
|
|
22
23
|
private attachEscape;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{inheritThemeScope as t}from"../core/theme-scope.js";import{dbText as e}from"../core/i18n.js";import{createFocusTrap as s}from"../core/focus-trap.js";import{unlockScroll as i,lockScroll as r}from"../core/scroll-lock.js";import{DRAWER_POSITIONS as o,DRAWER_SIZES as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDrawer extends HTMLElement{constructor(){super(...arguments),this.isMounted=!1,this.isActive=!1,this.scrollLocked=!1,this.keyHandler=null}static get observedAttributes(){return["open","title","position","size","show-close-button","close-on-backdrop-click","close-on-escape","animation-duration","show-overlay","overlay-closable","z-index","trap-focus","drawer-id"]}connectedCallback(){this.style.display="contents",this.render(),this.syncOpenState()}disconnectedCallback(){this.clearTimers(),this.detachEscape(),this.focusTrap?.deactivate(),this.focusTrap=void 0,this.root?.remove(),this.root=void 0,this.releaseScrollLock()}releaseScrollLock(){this.scrollLocked&&(this.scrollLocked=!1,i())}attributeChangedCallback(t){this.isConnected&&("open"!==t?(this.render(),this.isMounted&&(this.syncActiveClasses(),this.syncInteraction())):this.syncOpenState())}syncInteraction(){"false"===this.getAttribute("show-overlay")?this.releaseScrollLock():this.scrollLocked||(r(),this.scrollLocked=!0);"false"!==this.getAttribute("trap-focus")?this.isActive&&this.container&&!this.focusTrap&&(this.focusTrap=s(this.container),this.focusTrap.activate()):(this.focusTrap?.deactivate(),this.focusTrap=void 0)}isOpenRequested(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}clearTimers(){null!=this.enterFrame&&(cancelAnimationFrame(this.enterFrame),this.enterFrame=void 0),this.exitTimer&&(clearTimeout(this.exitTimer),this.exitTimer=void 0)}attachEscape(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"false"!==this.getAttribute("close-on-escape")&&this.close()},document.addEventListener("keydown",this.keyHandler))}detachEscape(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}close(){this.setAttribute("open","false"),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}collectChildren(){return[...new Set([...Array.from(this.contentEl?.children||[]),...Array.from(this.children)])].filter(t=>!t.hasAttribute("data-wc-internal"))}syncOpenState(){const e=this.isOpenRequested(),s=Number(this.getAttribute("animation-duration")||300);if(this.clearTimers(),e)return this.render(),this.isMounted=!0,this.isActive=!1,this.syncActiveClasses(),this.root&&!this.root.isConnected&&(t(this,this.root),document.body.append(this.root)),this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=void 0,this.isActive=!0,this.syncActiveClasses(),this.syncInteraction()})}),this.syncInteraction(),void this.attachEscape();this.isActive=!1,this.syncActiveClasses(),this.exitTimer=setTimeout(()=>{this.exitTimer=void 0,this.isMounted=!1,this.syncActiveClasses(),this.root?.remove(),this.releaseScrollLock(),this.detachEscape(),this.focusTrap?.deactivate(),this.focusTrap=void 0},s),this.detachEscape()}syncActiveClasses(){this.root&&(this.root.classList.toggle("designbase-wc-drawer--open",this.isActive),this.root.classList.toggle("designbase-wc-drawer--closing",this.isMounted&&!this.isActive),this.overlay?.classList.toggle("designbase-wc-drawer__overlay--open",this.isActive),this.container?.classList.toggle("designbase-wc-drawer__container--open",this.isActive))}render(){const s=o.includes(this.getAttribute("position")||"right")&&this.getAttribute("position")||"right",i=n.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",r=this.getAttribute("title"),a="false"!==this.getAttribute("show-close-button"),c="false"!==this.getAttribute("show-overlay"),h=this.getAttribute("animation-duration")||"300",l=this.getAttribute("z-index")||"1000",d=this.getAttribute("drawer-id")||"drawer",u=this.collectChildren();this.root||(this.root=document.createElement("div"),this.root.setAttribute("data-wc-internal",""),this.overlay=document.createElement("div"),this.overlay.className="designbase-wc-drawer__overlay",this.overlay.setAttribute("aria-hidden","true"),this.overlay.addEventListener("click",t=>{if(t.target!==this.overlay)return;const e="false"!==this.getAttribute("overlay-closable"),s="false"!==this.getAttribute("close-on-backdrop-click");e&&s&&this.close()}),this.container=document.createElement("div"),this.container.className=`designbase-wc-drawer__container designbase-wc-drawer__container--${s}`,this.container.setAttribute("role","dialog"),this.container.setAttribute("aria-modal","true"),this.container.tabIndex=-1,this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-drawer__content",this.container.append(this.contentEl)),this.root.className=["designbase-wc-drawer",`designbase-wc-drawer--${s}`,`designbase-wc-drawer--${i}`].join(" "),this.root.style.setProperty("--drawer-animation-duration",`${h}ms`),this.root.style.setProperty("--drawer-z-index",l),this.container.className=`designbase-wc-drawer__container designbase-wc-drawer__container--${s}`,this.container.id=d,this.container.setAttribute("aria-modal",String(c)),r?this.container.setAttribute("aria-labelledby",`${d}-title`):this.container.removeAttribute("aria-labelledby"),this.contentEl.id=`${d}-content`,c&&this.overlay?this.overlay.parentElement!==this.root&&this.root.prepend(this.overlay):this.overlay?.remove(),this.container.querySelector(":scope > .designbase-wc-drawer__header")?.remove();if(Boolean(r)||a){const t=document.createElement("div");if(t.className="designbase-wc-drawer__header",r){const e=document.createElement("h2");e.className="designbase-wc-drawer__title",e.id=`${d}-title`,e.textContent=r,t.append(e)}if(a){const s=document.createElement("db-button");s.className="designbase-wc-drawer__close-button",s.setAttribute("variant","ghost"),s.setAttribute("size","s"),s.setAttribute("icon-only",""),s.setAttribute("start-icon","close"),s.setAttribute("aria-label",e("닫기")),s.addEventListener("db-click",t=>{t.stopPropagation(),this.close()}),t.append(s)}this.container.insertBefore(t,this.contentEl)}const m=Array.from(this.contentEl.children);(m.length!==u.length||m.some((t,e)=>t!==u[e]))&&this.contentEl.replaceChildren(...u),this.container.parentElement!==this.root&&this.root.append(this.container),this.isMounted&&!this.root.isConnected&&(t(this,this.root),document.body.append(this.root))}}customElements.get("db-drawer")||customElements.define("db-drawer",DbDrawer);export{DbDrawer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isDbIconName as e,createDbIcon as t}from"./db-icons.js";import{DROPDOWN_SIZES as i,DROPDOWN_PLACEMENTS as r,DROPDOWN_TRIGGER_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDropdown extends HTMLElement{constructor(){super(...arguments),this.focusedIndex=-1,this.onTriggerActivate=null,this.lastTriggerSignature="",this.handleTriggerKeyDown=e=>{if(!this.menu?.contains(e.target))return"Enter"!==e.key&&" "!==e.key&&"ArrowDown"!==e.key||this.open?void("Escape"===e.key&&this.open&&(e.preventDefault(),this.open=!1,this.render())):(e.preventDefault(),this.open=!0,requestAnimationFrame(()=>this.focusItem(0)),void this.render())},this.handleDocumentKeyDown=e=>{if(!this.open)return;if("Escape"===e.key)return e.preventDefault(),this.open=!1,this.render(),void this.triggerWrap?.querySelector("[aria-haspopup]")?.focus();if(this.menu?.querySelector(':scope > [slot="content"]'))return;const t=this.enabledItems();if(!t.length)return;const i=t.findIndex(e=>this.parsedItems.indexOf(e)===this.focusedIndex);switch(e.key){case"ArrowDown":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i+1)%t.length]));break;case"ArrowUp":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i-1+t.length)%t.length]));break;case"Home":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[0]));break;case"End":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[t.length-1]));break;case"Enter":case" ":{e.preventDefault();const t=this.parsedItems[this.focusedIndex];!t||t.divider||t.disabled||this.selectItem(t);break}}},this.handleDocumentMouseDown=e=>{this.open&&(this.contains(e.target)||(this.open=!1,this.render()))}}static get observedAttributes(){return["options","items","placeholder","label","value","size","placement","full-width","disabled","open","trigger-variant","trigger-icon","icon-only","show-chevron"]}get showChevron(){return"false"!==this.getAttribute("show-chevron")}set showChevron(e){this.setAttribute("show-chevron",String(e))}get parsedItems(){const e=this.getAttribute("items");if(e)try{const t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return(this.getAttribute("options")||"").split(",").map(e=>e.trim()).filter(Boolean).map((e,t)=>({id:`option-${t}`,label:e}))}get options(){return this.parsedItems.map(e=>e.label||e.id)}set options(e){this.setAttribute("options",Array.isArray(e)?e.join(","):e)}get items(){return this.parsedItems}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get value(){return this.getAttribute("value")||""}set value(e){e?this.setAttribute("value",e):this.removeAttribute("value")}get open(){return this.hasAttribute("open")}set open(e){const t=this.open;this.toggleAttribute("open",e),t!==e&&this.dispatchEvent(new CustomEvent("db-open",{detail:{open:e},bubbles:!0,composed:!0}))}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e)}get size(){return this.getAttribute("size")||"m"}set size(e){this.setAttribute("size",e)}get placement(){return this.getAttribute("placement")||"bottom-left"}set placement(e){this.setAttribute("placement",e)}get placeholder(){return this.getAttribute("placeholder")||""}set placeholder(e){e?this.setAttribute("placeholder",e):this.removeAttribute("placeholder")}get label(){return this.getAttribute("label")||""}set label(e){e?this.setAttribute("label",e):this.removeAttribute("label")}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(e){this.toggleAttribute("full-width",e)}connectedCallback(){requestAnimationFrame(()=>this.render()),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown),this.unbindTrigger()}attributeChangedCallback(e){this.isConnected&&("open"!==e||this.open||(this.focusedIndex=-1),this.render())}resolvedSize(){return i.includes(this.size)?this.size:"m"}resolvedPlacement(){return r.includes(this.placement)?this.placement:"bottom-left"}menuItemIconSize(){const e=this.resolvedSize();return"s"===e?14:"l"===e?18:16}triggerLabel(){return this.label?this.label:this.placeholder?this.placeholder:this.value?this.value:"메뉴"}enabledItems(){return this.parsedItems.filter(e=>!e.disabled&&!e.divider)}collectTriggerChildren(){const isInternalNode=e=>"content"===e.getAttribute("slot")||e.hasAttribute("data-wc-internal")||e===this.triggerWrap||e===this.menu||e===this.defaultTrigger,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[]).filter(e=>!isInternalNode(e))}hasCustomTrigger(){return this.collectTriggerChildren().length>0}bindTrigger(){this.triggerWrap&&(this.unbindTrigger(),this.onTriggerActivate=e=>{this.disabled||this.menu?.contains(e.target)||(e.preventDefault(),e.stopPropagation(),this.toggleOpen())},this.triggerWrap.addEventListener("click",this.onTriggerActivate),this.triggerWrap.addEventListener("keydown",this.handleTriggerKeyDown))}unbindTrigger(){this.triggerWrap&&this.onTriggerActivate&&this.triggerWrap.removeEventListener("click",this.onTriggerActivate),this.triggerWrap&&this.triggerWrap.removeEventListener("keydown",this.handleTriggerKeyDown),this.onTriggerActivate=null}toggleOpen(){this.disabled||(this.open=!this.open,this.open&&requestAnimationFrame(()=>this.focusItem(0)),this.render())}triggerSignature(){return[this.resolvedSize(),this.getAttribute("trigger-variant")||"tertiary",this.hasAttribute("icon-only")?"1":"0",this.getAttribute("trigger-icon")||"",this.fullWidth?"1":"0",this.showChevron?"1":"0"].join("|")}renderDefaultTrigger(){const t=this.resolvedSize(),i=this.getAttribute("trigger-variant")||"tertiary",r=s.includes(i)?i:"tertiary",n=this.hasAttribute("icon-only"),o=this.getAttribute("trigger-icon"),a=document.createElement("db-button");if(a.setAttribute("type","button"),a.setAttribute("variant",r),a.setAttribute("size",t),a.className="designbase-wc-dropdown__trigger",a.setAttribute("aria-haspopup","menu"),a.setAttribute("aria-label",this.triggerLabel()),this.fullWidth&&a.setAttribute("full-width",""),n)a.setAttribute("icon-only",""),a.setAttribute("start-icon",o&&e(o)?o:"edit"),a.removeAttribute("end-icon");else{a.removeAttribute("icon-only"),o&&e(o)?a.setAttribute("start-icon",o):a.removeAttribute("start-icon");const t=document.createElement("span");t.className="designbase-wc-dropdown__trigger-label",t.textContent=this.triggerLabel(),a.append(t),this.showChevron&&a.setAttribute("end-icon","chevron-down")}return a}syncDefaultTriggerState(e){e.setAttribute("aria-expanded",String(this.open)),e.setAttribute("aria-label",this.triggerLabel()),e.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),this.disabled?e.setAttribute("disabled",""):e.removeAttribute("disabled");const t=e.querySelector(".designbase-wc-dropdown__trigger-label");t&&(t.textContent=this.triggerLabel())}ensureStructure(){this.triggerWrap||(this.triggerWrap=document.createElement("div"),this.triggerWrap.className="designbase-wc-dropdown__trigger-wrap",this.triggerWrap.setAttribute("data-wc-internal","")),this.menu||(this.menu=document.createElement("div"),this.menu.className="designbase-wc-dropdown__menu",this.menu.setAttribute("data-wc-internal",""),this.menu.setAttribute("role","menu"));const e=this.triggerWrap,t=this.menu;e&&t&&(this.contains(e)||this.append(e),e.contains(t)||e.append(t),Array.from(this.children).forEach(i=>{i===e||i.hasAttribute("data-wc-internal")||("content"===i.getAttribute("slot")?t.append(i):e.insertBefore(i,t))}))}renderTrigger(){const e=this.triggerWrap,t=this.menu;if(!e||!t)return;const i=this.collectTriggerChildren();if(i.length>0){this.defaultTrigger?.remove(),this.defaultTrigger=void 0;Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),i.forEach(i=>{i.setAttribute("aria-haspopup","menu"),i.setAttribute("aria-expanded",String(this.open)),i.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),e.insertBefore(i,t)})}else{Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),this.defaultTrigger&&this.triggerSignature()===this.lastTriggerSignature||(this.defaultTrigger?.remove(),this.defaultTrigger=this.renderDefaultTrigger(),this.lastTriggerSignature=this.triggerSignature(),e.insertBefore(this.defaultTrigger,t)),this.defaultTrigger&&this.syncDefaultTriggerState(this.defaultTrigger)}this.bindTrigger()}renderMenu(){const e=this.resolvedPlacement();this.menu.className=`designbase-wc-dropdown__menu designbase-wc-dropdown__menu--${e}${this.open?" designbase-wc-dropdown__menu--open":""}`,this.menu.setAttribute("aria-hidden",String(!this.open)),this.menu.setAttribute("aria-label",this.triggerLabel());const i=this.menu.querySelector(':scope > [slot="content"]');if(this.menu.setAttribute("role",i?"dialog":"menu"),i)return this.menu.inert=!this.open,this.menu.setAttribute("aria-modal","false"),this.menu.classList.add("designbase-wc-dropdown__menu--custom"),void this.triggerWrap?.querySelector("[aria-haspopup]")?.setAttribute("aria-haspopup","dialog");this.menu.inert=!1,this.menu.removeAttribute("aria-modal"),this.menu.replaceChildren();const r=this.menuItemIconSize();this.parsedItems.forEach((e,i)=>{if(e.divider){const e=document.createElement("div");return e.className="designbase-wc-dropdown__divider",e.setAttribute("role","separator"),void this.menu?.append(e)}e.id||e.label||String(i);const s=e.label||e.id,n=Boolean(e.disabled||this.disabled),o=this.focusedIndex===i,a=document.createElement("button");if(a.type="button",a.className=["designbase-wc-dropdown__item",n&&"designbase-wc-dropdown__item--disabled",o&&"designbase-wc-dropdown__item--focused"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a.disabled=n,a.tabIndex=o?0:-1,a.dataset.index=String(i),e.icon){const i=t(e.icon,r);i.classList.add("designbase-wc-dropdown__item-icon"),a.append(i)}const d=document.createElement("span");d.className="designbase-wc-dropdown__item-label",d.textContent=s,a.append(d),a.addEventListener("click",t=>{t.stopPropagation(),this.selectItem(e)}),this.menu?.append(a)})}render(){const e=this.resolvedSize();this.className=["designbase-wc-dropdown",`designbase-wc-dropdown--${e}`,this.open&&"designbase-wc-dropdown--open",this.fullWidth&&"designbase-wc-dropdown--full-width",this.disabled&&"designbase-wc-dropdown--disabled"].filter(Boolean).join(" "),this.ensureStructure(),this.renderTrigger(),this.renderMenu()}selectItem(e){e.disabled||e.divider||(this.open=!1,this.focusedIndex=-1,this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e.label||e.id,id:e.id,item:e},bubbles:!0,composed:!0})),this.render(),this.triggerWrap?.querySelector("[aria-haspopup]")?.focus())}focusItem(e){if(this.menu?.querySelector(':scope > [slot="content"]'))return void this.menu.querySelector('input:not([disabled]), button:not([disabled]), [tabindex="0"]')?.focus();const t=this.enabledItems();if(!t.length)return;const i=t[Math.max(0,Math.min(e,t.length-1))],r=this.parsedItems.indexOf(i);this.focusedIndex=r;Array.from(this.menu?.querySelectorAll(".designbase-wc-dropdown__item")||[]).forEach(e=>{const t=Number(e.dataset.index)===r;e.classList.toggle("designbase-wc-dropdown__item--focused",t),e.tabIndex=t?0:-1,t&&e.focus()})}}customElements.get("db-dropdown")||customElements.define("db-dropdown",DbDropdown);export{DbDropdown};
|
|
1
|
+
import{setHostClasses as e}from"../core/host-class.js";import{isDbIconName as t,createDbIcon as i}from"./db-icons.js";import{DROPDOWN_SIZES as r,DROPDOWN_PLACEMENTS as s,DROPDOWN_TRIGGER_VARIANTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDropdown extends HTMLElement{constructor(){super(...arguments),this.focusedIndex=-1,this.onTriggerActivate=null,this.lastTriggerSignature="",this.handleTriggerKeyDown=e=>{if(!this.menu?.contains(e.target))return"Enter"!==e.key&&" "!==e.key&&"ArrowDown"!==e.key||this.open?void("Escape"===e.key&&this.open&&(e.preventDefault(),this.open=!1,this.render())):(e.preventDefault(),this.open=!0,requestAnimationFrame(()=>this.focusItem(0)),void this.render())},this.handleDocumentKeyDown=e=>{if(!this.open)return;if("Escape"===e.key)return e.preventDefault(),this.open=!1,this.render(),void this.triggerWrap?.querySelector("[aria-haspopup]")?.focus();if(this.menu?.querySelector(':scope > [slot="content"]'))return;const t=this.enabledItems();if(!t.length)return;const i=t.findIndex(e=>this.parsedItems.indexOf(e)===this.focusedIndex);switch(e.key){case"ArrowDown":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i+1)%t.length]));break;case"ArrowUp":e.preventDefault(),this.focusItem(i<0?0:this.parsedItems.indexOf(t[(i-1+t.length)%t.length]));break;case"Home":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[0]));break;case"End":e.preventDefault(),this.focusItem(this.parsedItems.indexOf(t[t.length-1]));break;case"Enter":case" ":{e.preventDefault();const t=this.parsedItems[this.focusedIndex];!t||t.divider||t.disabled||this.selectItem(t);break}}},this.handleDocumentMouseDown=e=>{this.open&&(this.contains(e.target)||(this.open=!1,this.render()))}}static get observedAttributes(){return["options","items","placeholder","label","value","size","placement","full-width","disabled","open","trigger-variant","trigger-icon","icon-only","show-chevron"]}get showChevron(){return"false"!==this.getAttribute("show-chevron")}set showChevron(e){this.setAttribute("show-chevron",String(e))}get parsedItems(){const e=this.getAttribute("items");if(e)try{const t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return(this.getAttribute("options")||"").split(",").map(e=>e.trim()).filter(Boolean).map((e,t)=>({id:`option-${t}`,label:e}))}get options(){return this.parsedItems.map(e=>e.label||e.id)}set options(e){this.setAttribute("options",Array.isArray(e)?e.join(","):e)}get items(){return this.parsedItems}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get value(){return this.getAttribute("value")||""}set value(e){e?this.setAttribute("value",e):this.removeAttribute("value")}get open(){return this.hasAttribute("open")}set open(e){const t=this.open;this.toggleAttribute("open",e),t!==e&&this.dispatchEvent(new CustomEvent("db-open",{detail:{open:e},bubbles:!0,composed:!0}))}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e)}get size(){return this.getAttribute("size")||"m"}set size(e){this.setAttribute("size",e)}get placement(){return this.getAttribute("placement")||"bottom-left"}set placement(e){this.setAttribute("placement",e)}get placeholder(){return this.getAttribute("placeholder")||""}set placeholder(e){e?this.setAttribute("placeholder",e):this.removeAttribute("placeholder")}get label(){return this.getAttribute("label")||""}set label(e){e?this.setAttribute("label",e):this.removeAttribute("label")}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(e){this.toggleAttribute("full-width",e)}connectedCallback(){requestAnimationFrame(()=>this.render()),document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown),this.unbindTrigger()}attributeChangedCallback(e){this.isConnected&&("open"!==e||this.open||(this.focusedIndex=-1),this.render())}resolvedSize(){return r.includes(this.size)?this.size:"m"}resolvedPlacement(){return s.includes(this.placement)?this.placement:"bottom-left"}menuItemIconSize(){const e=this.resolvedSize();return"s"===e?14:"l"===e?18:16}triggerLabel(){return this.label?this.label:this.placeholder?this.placeholder:this.value?this.value:"메뉴"}enabledItems(){return this.parsedItems.filter(e=>!e.disabled&&!e.divider)}collectTriggerChildren(){const isInternalNode=e=>"content"===e.getAttribute("slot")||e.hasAttribute("data-wc-internal")||e===this.triggerWrap||e===this.menu||e===this.defaultTrigger,e=Array.from(this.children).filter(e=>!isInternalNode(e));return e.length>0?e:Array.from(this.triggerWrap?.children||[]).filter(e=>!isInternalNode(e))}hasCustomTrigger(){return this.collectTriggerChildren().length>0}bindTrigger(){this.triggerWrap&&(this.unbindTrigger(),this.onTriggerActivate=e=>{this.disabled||this.menu?.contains(e.target)||(e.preventDefault(),e.stopPropagation(),this.toggleOpen())},this.triggerWrap.addEventListener("click",this.onTriggerActivate),this.triggerWrap.addEventListener("keydown",this.handleTriggerKeyDown))}unbindTrigger(){this.triggerWrap&&this.onTriggerActivate&&this.triggerWrap.removeEventListener("click",this.onTriggerActivate),this.triggerWrap&&this.triggerWrap.removeEventListener("keydown",this.handleTriggerKeyDown),this.onTriggerActivate=null}toggleOpen(){this.disabled||(this.open=!this.open,this.open&&requestAnimationFrame(()=>this.focusItem(0)),this.render())}triggerSignature(){return[this.resolvedSize(),this.getAttribute("trigger-variant")||"tertiary",this.hasAttribute("icon-only")?"1":"0",this.getAttribute("trigger-icon")||"",this.fullWidth?"1":"0",this.showChevron?"1":"0"].join("|")}renderDefaultTrigger(){const e=this.resolvedSize(),i=this.getAttribute("trigger-variant")||"tertiary",r=n.includes(i)?i:"tertiary",s=this.hasAttribute("icon-only"),o=this.getAttribute("trigger-icon"),a=document.createElement("db-button");if(a.setAttribute("type","button"),a.setAttribute("variant",r),a.setAttribute("size",e),a.className="designbase-wc-dropdown__trigger",a.setAttribute("aria-haspopup","menu"),a.setAttribute("aria-label",this.triggerLabel()),this.fullWidth&&a.setAttribute("full-width",""),s)a.setAttribute("icon-only",""),a.setAttribute("start-icon",o&&t(o)?o:"edit"),a.removeAttribute("end-icon");else{a.removeAttribute("icon-only"),o&&t(o)?a.setAttribute("start-icon",o):a.removeAttribute("start-icon");const e=document.createElement("span");e.className="designbase-wc-dropdown__trigger-label",e.textContent=this.triggerLabel(),a.append(e),this.showChevron&&a.setAttribute("end-icon","chevron-down")}return a}syncDefaultTriggerState(e){e.setAttribute("aria-expanded",String(this.open)),e.setAttribute("aria-label",this.triggerLabel()),e.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),this.disabled?e.setAttribute("disabled",""):e.removeAttribute("disabled");const t=e.querySelector(".designbase-wc-dropdown__trigger-label");t&&(t.textContent=this.triggerLabel())}ensureStructure(){this.triggerWrap||(this.triggerWrap=document.createElement("div"),this.triggerWrap.className="designbase-wc-dropdown__trigger-wrap",this.triggerWrap.setAttribute("data-wc-internal","")),this.menu||(this.menu=document.createElement("div"),this.menu.className="designbase-wc-dropdown__menu",this.menu.setAttribute("data-wc-internal",""),this.menu.setAttribute("role","menu"));const e=this.triggerWrap,t=this.menu;e&&t&&(this.contains(e)||this.append(e),e.contains(t)||e.append(t),Array.from(this.children).forEach(i=>{i===e||i.hasAttribute("data-wc-internal")||("content"===i.getAttribute("slot")?t.append(i):e.insertBefore(i,t))}))}renderTrigger(){const e=this.triggerWrap,t=this.menu;if(!e||!t)return;const i=this.collectTriggerChildren();if(i.length>0){this.defaultTrigger?.remove(),this.defaultTrigger=void 0;Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),i.forEach(i=>{i.setAttribute("aria-haspopup","menu"),i.setAttribute("aria-expanded",String(this.open)),i.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),e.insertBefore(i,t)})}else{Array.from(e.children).filter(e=>e!==t&&e!==this.defaultTrigger).forEach(e=>e.remove()),this.defaultTrigger&&this.triggerSignature()===this.lastTriggerSignature||(this.defaultTrigger?.remove(),this.defaultTrigger=this.renderDefaultTrigger(),this.lastTriggerSignature=this.triggerSignature(),e.insertBefore(this.defaultTrigger,t)),this.defaultTrigger&&this.syncDefaultTriggerState(this.defaultTrigger)}this.bindTrigger()}renderMenu(){const e=this.resolvedPlacement();this.menu.className=`designbase-wc-dropdown__menu designbase-wc-dropdown__menu--${e}${this.open?" designbase-wc-dropdown__menu--open":""}`,this.menu.setAttribute("aria-hidden",String(!this.open)),this.menu.setAttribute("aria-label",this.triggerLabel());const t=this.menu.querySelector(':scope > [slot="content"]');if(this.menu.setAttribute("role",t?"dialog":"menu"),t)return this.menu.inert=!this.open,this.menu.setAttribute("aria-modal","false"),this.menu.classList.add("designbase-wc-dropdown__menu--custom"),void this.triggerWrap?.querySelector("[aria-haspopup]")?.setAttribute("aria-haspopup","dialog");this.menu.inert=!1,this.menu.removeAttribute("aria-modal"),this.menu.replaceChildren();const r=this.menuItemIconSize();this.parsedItems.forEach((e,t)=>{if(e.divider){const e=document.createElement("div");return e.className="designbase-wc-dropdown__divider",e.setAttribute("role","separator"),void this.menu?.append(e)}e.id||e.label||String(t);const s=e.label||e.id,n=Boolean(e.disabled||this.disabled),o=this.focusedIndex===t,a=document.createElement("button");if(a.type="button",a.className=["designbase-wc-dropdown__item",n&&"designbase-wc-dropdown__item--disabled",o&&"designbase-wc-dropdown__item--focused"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a.disabled=n,a.tabIndex=o?0:-1,a.dataset.index=String(t),e.icon){const t=i(e.icon,r);t.classList.add("designbase-wc-dropdown__item-icon"),a.append(t)}const d=document.createElement("span");d.className="designbase-wc-dropdown__item-label",d.textContent=s,a.append(d),a.addEventListener("click",t=>{t.stopPropagation(),this.selectItem(e)}),this.menu?.append(a)})}render(){const t=this.resolvedSize();e(this,["designbase-wc-dropdown",`designbase-wc-dropdown--${t}`,this.open&&"designbase-wc-dropdown--open",this.fullWidth&&"designbase-wc-dropdown--full-width",this.disabled&&"designbase-wc-dropdown--disabled"]),this.ensureStructure(),this.renderTrigger(),this.renderMenu()}selectItem(e){e.disabled||e.divider||(this.open=!1,this.focusedIndex=-1,this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e.label||e.id,id:e.id,item:e},bubbles:!0,composed:!0})),this.render(),this.triggerWrap?.querySelector("[aria-haspopup]")?.focus())}focusItem(e){if(this.menu?.querySelector(':scope > [slot="content"]'))return void this.menu.querySelector('input:not([disabled]), button:not([disabled]), [tabindex="0"]')?.focus();const t=this.enabledItems();if(!t.length)return;const i=t[Math.max(0,Math.min(e,t.length-1))],r=this.parsedItems.indexOf(i);this.focusedIndex=r;Array.from(this.menu?.querySelectorAll(".designbase-wc-dropdown__item")||[]).forEach(e=>{const t=Number(e.dataset.index)===r;e.classList.toggle("designbase-wc-dropdown__item--focused",t),e.tabIndex=t?0:-1,t&&e.focus()})}}customElements.get("db-dropdown")||customElements.define("db-dropdown",DbDropdown);export{DbDropdown};
|