@designbasekorea/ui-wc 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/esm/components/animation-background/canvas-controller.js +1 -1
  2. package/dist/esm/components/animation-background/controls.js +1 -0
  3. package/dist/esm/components/animation-background/graphite-controller.js +1 -0
  4. package/dist/esm/components/animation-background/graphite-presets.js +1 -0
  5. package/dist/esm/components/animation-background/graphite-shader.js +1 -0
  6. package/dist/esm/components/animation-background/layers.js +1 -1
  7. package/dist/esm/components/animation-background/lumina-shaders.js +1 -1
  8. package/dist/esm/components/animation-background/lumina-utils.js +1 -1
  9. package/dist/esm/components/animation-background/renderers.js +1 -1
  10. package/dist/esm/components/animation-background/shader-controller.js +1 -1
  11. package/dist/esm/components/db-accordion.d.ts +2 -0
  12. package/dist/esm/components/db-accordion.js +1 -1
  13. package/dist/esm/components/db-ad-banner.d.ts +26 -1
  14. package/dist/esm/components/db-ad-banner.js +1 -1
  15. package/dist/esm/components/db-animation-background.d.ts +23 -2
  16. package/dist/esm/components/db-animation-background.js +1 -1
  17. package/dist/esm/components/db-animation-text.d.ts +11 -0
  18. package/dist/esm/components/db-animation-text.js +1 -1
  19. package/dist/esm/components/db-breadcrumbs.d.ts +29 -0
  20. package/dist/esm/components/db-breadcrumbs.js +1 -1
  21. package/dist/esm/components/db-calendar.js +1 -1
  22. package/dist/esm/components/db-context-menu.js +1 -1
  23. package/dist/esm/components/db-cursor-follower.d.ts +1 -2
  24. package/dist/esm/components/db-cursor-follower.js +1 -1
  25. package/dist/esm/components/db-dropdown.js +1 -1
  26. package/dist/esm/components/db-footer.d.ts +74 -0
  27. package/dist/esm/components/db-footer.js +1 -0
  28. package/dist/esm/components/db-gantt.d.ts +96 -0
  29. package/dist/esm/components/db-gantt.js +1 -0
  30. package/dist/esm/components/db-grid-background.d.ts +93 -0
  31. package/dist/esm/components/db-grid-background.js +1 -0
  32. package/dist/esm/components/db-icons.js +1 -1
  33. package/dist/esm/components/db-indicator.d.ts +12 -0
  34. package/dist/esm/components/db-indicator.js +1 -1
  35. package/dist/esm/components/db-kanban.d.ts +70 -0
  36. package/dist/esm/components/db-kanban.js +1 -0
  37. package/dist/esm/components/db-lightbox.d.ts +1 -0
  38. package/dist/esm/components/db-lightbox.js +1 -1
  39. package/dist/esm/components/db-marquee.d.ts +26 -4
  40. package/dist/esm/components/db-marquee.js +1 -1
  41. package/dist/esm/components/db-masonry.js +1 -1
  42. package/dist/esm/components/db-navbar.d.ts +32 -1
  43. package/dist/esm/components/db-navbar.js +1 -1
  44. package/dist/esm/components/db-popover.js +1 -1
  45. package/dist/esm/components/db-progress.d.ts +10 -0
  46. package/dist/esm/components/db-progress.js +1 -1
  47. package/dist/esm/components/db-range-slider.d.ts +7 -0
  48. package/dist/esm/components/db-range-slider.js +1 -1
  49. package/dist/esm/components/db-section-app-download.d.ts +0 -2
  50. package/dist/esm/components/db-section-app-download.js +1 -1
  51. package/dist/esm/components/db-section-contact.d.ts +1 -3
  52. package/dist/esm/components/db-section-contact.js +1 -1
  53. package/dist/esm/components/db-section-cta.d.ts +24 -0
  54. package/dist/esm/components/db-section-cta.js +1 -0
  55. package/dist/esm/components/db-section-faq.d.ts +20 -0
  56. package/dist/esm/components/db-section-faq.js +1 -0
  57. package/dist/esm/components/db-section-feature-grid.d.ts +20 -0
  58. package/dist/esm/components/db-section-feature-grid.js +1 -0
  59. package/dist/esm/components/db-section-feature.d.ts +2 -2
  60. package/dist/esm/components/db-section-feature.js +1 -1
  61. package/dist/esm/components/db-section-logo-cloud.d.ts +20 -0
  62. package/dist/esm/components/db-section-logo-cloud.js +1 -0
  63. package/dist/esm/components/db-section-pricing.d.ts +20 -0
  64. package/dist/esm/components/db-section-pricing.js +1 -0
  65. package/dist/esm/components/db-section-stats.d.ts +20 -0
  66. package/dist/esm/components/db-section-stats.js +1 -0
  67. package/dist/esm/components/db-section-testimonials.d.ts +34 -0
  68. package/dist/esm/components/db-section-testimonials.js +1 -0
  69. package/dist/esm/components/db-share-icons.js +1 -1
  70. package/dist/esm/components/db-tooltip.d.ts +3 -0
  71. package/dist/esm/components/db-tooltip.js +1 -1
  72. package/dist/esm/components/marketing-block-host-utils.js +1 -0
  73. package/dist/esm/components/section-block-header-utils.js +1 -0
  74. package/dist/esm/index.d.ts +11 -0
  75. package/dist/esm/index.js +1 -1
  76. package/dist/index.cjs +1 -1
  77. package/dist/index.css +1 -1
  78. package/dist/index.d.ts +664 -18
  79. package/dist/index.esm.js +1 -1
  80. package/dist/react/chunks/lottie-14e7addb.js +1 -0
  81. package/dist/react/index.cjs +1 -1
  82. package/dist/react/index.d.ts +1165 -27
  83. package/dist/react/index.esm.js +1 -1
  84. package/package.json +1 -1
  85. package/dist/react/chunks/lottie-eed75107.js +0 -1
  86. /package/dist/chunks/{lottie-e741cdda.js → lottie-3b3dac01.js} +0 -0
@@ -1 +1 @@
1
- import{createDbIcon as e}from"./db-icons.js";class DbBreadcrumbs extends HTMLElement{static get observedAttributes(){return["items","size","variant","breadcrumb-style","max-items"]}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.render()}attributeChangedCallback(){this.isConnected&&this.render()}visibleItems(){const e=this.items,t=Number(this.getAttribute("max-items")||0);if(!t||e.length<=t)return e;const s=e[0],a=e[e.length-1],i=e.slice(1,-1),n=t-2;if(n<=0)return[s,a];const r=Math.floor(i.length/2)-Math.floor(n/2);return[s,...i.slice(r,r+n),a]}render(){const t=this.getAttribute("size")||"m",s=this.getAttribute("breadcrumb-style")||this.getAttribute("variant")||"default",a=this.visibleItems(),i=a.length<this.items.length;this.className=["designbase-wc-breadcrumbs",`designbase-wc-breadcrumbs--${t}`,`designbase-wc-breadcrumbs--${s}`,i&&"designbase-wc-breadcrumbs--collapsed"].filter(Boolean).join(" "),this.setAttribute("role","navigation"),this.setAttribute("aria-label","브레드크럼 네비게이션"),this.replaceChildren();const n=document.createElement("ol");n.className="designbase-wc-breadcrumbs__list",a.forEach((t,s)=>{const i=s===a.length-1,r=document.createElement("li");r.className="designbase-wc-breadcrumbs__item";const c=!t.href||i||t.disabled?document.createElement("span"):document.createElement("a");if(c.className=c instanceof HTMLAnchorElement?["designbase-wc-breadcrumbs__link",t.active&&"designbase-wc-breadcrumbs__link--active",t.disabled&&"designbase-wc-breadcrumbs__link--disabled"].filter(Boolean).join(" "):["designbase-wc-breadcrumbs__text",i&&"designbase-wc-breadcrumbs__text--active",t.disabled&&"designbase-wc-breadcrumbs__text--disabled"].filter(Boolean).join(" "),t.icon){const s=document.createElement("span");s.className="designbase-wc-breadcrumbs__icon",s.append(e(t.icon,16)),c.append(s)}const b=document.createElement("span");if(b.className="designbase-wc-breadcrumbs__label",b.textContent=t.label,c.append(b),c instanceof HTMLAnchorElement&&(c.href=t.href||"#"),c.addEventListener("click",e=>{(t.disabled||t.active||i)&&e.preventDefault(),this.dispatchEvent(new CustomEvent("db-click",{detail:{item:t},bubbles:!0,composed:!0}))}),r.append(c),!i){const t=document.createElement("span");t.className="designbase-wc-breadcrumbs__separator",t.setAttribute("aria-hidden","true"),t.append(e("chevron-right",16)),r.append(t)}n.append(r)}),this.append(n)}}customElements.get("db-breadcrumbs")||customElements.define("db-breadcrumbs",DbBreadcrumbs);export{DbBreadcrumbs};
1
+ import{createDbIcon as e}from"./db-icons.js";const t={s:12,m:14,l:16};class DbBreadcrumbs extends HTMLElement{constructor(){super(...arguments),this.openMenuId=null,this.onDocumentMouseDown=null,this.onDocumentKeyDown=null}static get observedAttributes(){return["items","size","variant","breadcrumb-style","max-items","menu-dropdown","max-label-length"]}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.render()}disconnectedCallback(){this.removeGlobalListeners()}attributeChangedCallback(){this.isConnected&&(this.openMenuId=null,this.render())}get menuDropdown(){return this.hasAttribute("menu-dropdown")}get maxLabelLength(){const e=Number(this.getAttribute("max-label-length"));return Number.isFinite(e)&&e>0?e:12}get resolvedVariant(){return this.getAttribute("variant")||this.getAttribute("breadcrumb-style")||"default"}itemId(e,t){return e.id||`item-${t}`}menuItemId(e,t){return e.id||`menu-${t}`}visibleItems(){const e=this.items,t=Number(this.getAttribute("max-items")||0);if(!t||e.length<=t)return e;const n=e[0],s=e[e.length-1],a=e.slice(1,-1),r=t-2;if(r<=0)return[n,s];const i=Math.floor(a.length/2)-Math.floor(r/2);return[n,...a.slice(i,i+r),s]}shouldUseDropdown(e){return this.menuDropdown&&Boolean(e.menu?.length)}closeMenu(){this.openMenuId&&(this.openMenuId=null,this.removeGlobalListeners(),this.updateDropdownStates())}openMenu(e){this.openMenuId=e,this.addGlobalListeners(),this.updateDropdownStates()}toggleMenu(e){this.openMenuId===e?this.closeMenu():this.openMenu(e)}addGlobalListeners(){this.onDocumentMouseDown||(this.onDocumentMouseDown=e=>{this.contains(e.target)||this.closeMenu()},this.onDocumentKeyDown=e=>{"Escape"===e.key&&this.closeMenu()},document.addEventListener("mousedown",this.onDocumentMouseDown),document.addEventListener("keydown",this.onDocumentKeyDown))}removeGlobalListeners(){this.onDocumentMouseDown&&(document.removeEventListener("mousedown",this.onDocumentMouseDown),this.onDocumentMouseDown=null),this.onDocumentKeyDown&&(document.removeEventListener("keydown",this.onDocumentKeyDown),this.onDocumentKeyDown=null)}updateDropdownStates(){this.querySelectorAll("[data-breadcrumb-dropdown]").forEach(e=>{const t=e.dataset.breadcrumbDropdown||"",n=this.openMenuId===t;e.classList.toggle("designbase-wc-breadcrumbs__dropdown--open",n);const s=e.querySelector(".designbase-wc-breadcrumbs__trigger");s&&s.setAttribute("aria-expanded",String(n))})}createLabel(e){const t=function formatBreadcrumbLabel(e,t){return!t||e.length<=t?{text:e,full:e,truncated:!1}:{text:`${e.slice(0,t)}...`,full:e,truncated:!0}}(e,this.maxLabelLength),n=document.createElement("span");return n.className="designbase-wc-breadcrumbs__label",n.textContent=t.text,t.truncated&&n.setAttribute("title",t.full),n}createMenuItem(t,n,s){const a=t.href&&!t.disabled?document.createElement("a"):document.createElement("button");if(a.className=["designbase-wc-breadcrumbs__menu-item",t.active&&"designbase-wc-breadcrumbs__menu-item--active",t.disabled&&"designbase-wc-breadcrumbs__menu-item--disabled"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a instanceof HTMLButtonElement?(a.type="button",a.disabled=Boolean(t.disabled)):a.href=t.href||"#",t.icon){const n=document.createElement("span");n.className="designbase-wc-breadcrumbs__icon",n.append(e(t.icon,16)),a.append(n)}return a.append(this.createLabel(t.label)),a.addEventListener("click",e=>{t.disabled?e.preventDefault():(this.closeMenu(),this.dispatchEvent(new CustomEvent("db-menu-click",{detail:{menuItem:{...t,id:this.menuItemId(t,n)},parentItem:s},bubbles:!0,composed:!0})))}),a}createDropdownItem(t,n,s,a){const r=this.itemId(t,n),i=this.openMenuId===r,d=document.createElement("div");d.className=["designbase-wc-breadcrumbs__dropdown",i&&"designbase-wc-breadcrumbs__dropdown--open"].filter(Boolean).join(" "),d.dataset.breadcrumbDropdown=r;const o=document.createElement("button");if(o.type="button",o.className=["designbase-wc-breadcrumbs__trigger",(s||t.active)&&"designbase-wc-breadcrumbs__trigger--active",t.disabled&&"designbase-wc-breadcrumbs__trigger--disabled"].filter(Boolean).join(" "),o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-expanded",String(i)),o.disabled=Boolean(t.disabled),t.icon){const n=document.createElement("span");n.className="designbase-wc-breadcrumbs__icon",n.append(e(t.icon,16)),o.append(n)}o.append(this.createLabel(t.label));const c=document.createElement("span");c.className="designbase-wc-breadcrumbs__chevron",c.setAttribute("aria-hidden","true"),c.append(e("chevron-down",a)),o.append(c),o.addEventListener("click",e=>{e.stopPropagation(),t.disabled||this.toggleMenu(r)}),d.append(o);const u=document.createElement("div");return u.className="designbase-wc-breadcrumbs__menu",u.setAttribute("role","menu"),t.menu?.forEach((e,n)=>{u.append(this.createMenuItem(e,n,t))}),d.append(u),d}createStandardItem(t,n,s){const a=!t.href||s||t.disabled?document.createElement("span"):document.createElement("a");if(a.className=a instanceof HTMLAnchorElement?["designbase-wc-breadcrumbs__link",t.active&&"designbase-wc-breadcrumbs__link--active",t.disabled&&"designbase-wc-breadcrumbs__link--disabled"].filter(Boolean).join(" "):["designbase-wc-breadcrumbs__text",s&&"designbase-wc-breadcrumbs__text--active",t.disabled&&"designbase-wc-breadcrumbs__text--disabled"].filter(Boolean).join(" "),t.icon){const n=document.createElement("span");n.className="designbase-wc-breadcrumbs__icon",n.append(e(t.icon,16)),a.append(n)}return a.append(this.createLabel(t.label)),a instanceof HTMLAnchorElement&&(a.href=t.href||"#"),a.addEventListener("click",e=>{(t.disabled||t.active||s)&&e.preventDefault(),this.dispatchEvent(new CustomEvent("db-click",{detail:{item:t},bubbles:!0,composed:!0}))}),a}render(){const n=this.getAttribute("size")||"m",s=this.resolvedVariant,a=this.visibleItems(),r=a.length<this.items.length,i=t[n]||14;this.className=["designbase-wc-breadcrumbs",`designbase-wc-breadcrumbs--${n}`,`designbase-wc-breadcrumbs--${s}`,r&&"designbase-wc-breadcrumbs--collapsed"].filter(Boolean).join(" "),this.setAttribute("role","navigation"),this.setAttribute("aria-label","브레드크럼 네비게이션"),this.replaceChildren();const d=document.createElement("ol");d.className="designbase-wc-breadcrumbs__list",a.forEach((t,n)=>{const s=n===a.length-1,r=document.createElement("li");if(r.className="designbase-wc-breadcrumbs__item",this.shouldUseDropdown(t)?r.append(this.createDropdownItem(t,n,s,i)):r.append(this.createStandardItem(t,n,s)),!s){const t=document.createElement("span");t.className="designbase-wc-breadcrumbs__separator",t.setAttribute("aria-hidden","true"),t.append(e("chevron-right",16)),r.append(t)}d.append(r)}),this.append(d)}}customElements.get("db-breadcrumbs")||customElements.define("db-breadcrumbs",DbBreadcrumbs);export{DbBreadcrumbs};
@@ -1 +1 @@
1
- import{createDbIcon as e,getDbComponentIconSize as t}from"./db-icons.js";import{parseISODate as a,toISODate as n}from"./date-picker-utils.js";import"./db-modal.js";import"./db-input.js";import"./db-select.js";import"./db-date-picker.js";import"./db-time-picker.js";import"./db-button.js";const s="designbase-wc-calendar",i=[{value:"meeting",label:"회의"},{value:"task",label:"업무"},{value:"reminder",label:"알림"},{value:"birthday",label:"생일"},{value:"holiday",label:"휴일"},{value:"custom",label:"기타"}],d=[{value:"#17a2b8",label:"청록"},{value:"#0d6efd",label:"파랑"},{value:"#198754",label:"초록"},{value:"#ffc107",label:"노랑"},{value:"#dc3545",label:"빨강"},{value:"#6f42c1",label:"보라"}];class DbCalendar extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.currentView="month",this.selectedDate=new Date,this._events=[],this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.draggedEvent=null,this.dragOverDate=null,this.selectedDateRange={start:null,end:null},this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""}}static get observedAttributes(){return["view","current-date","events","locale","show-weekends","highlight-today","show-outside-days"]}connectedCallback(){this.built||this.build(),this.readAttributes(),this.render()}attributeChangedCallback(){this.built&&(this.readAttributes(),this.render())}get locale(){return this.getAttribute("locale")||"ko-KR"}get showWeekends(){return"false"!==this.getAttribute("show-weekends")}get highlightToday(){return"false"!==this.getAttribute("highlight-today")}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get events(){return this._events}set events(e){"string"!=typeof e?(this._events=Array.isArray(e)?e:[],this.setAttribute("events",JSON.stringify(this._events))):this.setAttribute("events",e)}build(){this.built=!0,this.headerEl=document.createElement("div"),this.headerEl.className=`${s}__header`,this.bodyEl=document.createElement("div"),this.bodyEl.className=`${s}__body`,this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","m"),this.modalEl.addEventListener("db-close",()=>this.closeModal())}readAttributes(){this.currentView="month";const e=a(this.getAttribute("current-date"));e&&(this.selectedDate=e);const t=this.getAttribute("events");if(t)try{const e=JSON.parse(t);this._events=Array.isArray(e)?e:[]}catch{this._events=[]}else this._events=[]}isSameDate(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}eventsForDate(e){return this._events.filter(t=>{const n=a(t.date);return!!n&&this.isSameDate(n,e)})}emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}handleViewChange(e){this.currentView="month",this.emit("db-view-change",{view:e}),this.render()}shiftMonth(e){const t=new Date(this.selectedDate);t.setMonth(t.getMonth()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}shiftYear(e){const t=new Date(this.selectedDate);t.setFullYear(t.getFullYear()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}handleDateClick(e){this.selectedDate=e,this.emit("db-date-click",{date:n(e)}),!this.selectedDateRange.start||this.selectedDateRange.start&&this.selectedDateRange.end?this.selectedDateRange={start:e,end:null}:this.selectedDateRange.start&&!this.selectedDateRange.end&&(e<this.selectedDateRange.start?this.selectedDateRange={start:e,end:this.selectedDateRange.start}:this.selectedDateRange={start:this.selectedDateRange.start,end:e}),this.openAddModal(e)}handleDragStart(e,t){this.draggedEvent=e,t.dataTransfer?.setData("text/plain",e.id),t.dataTransfer?.setData("application/json",JSON.stringify(e)),t.dataTransfer&&(t.dataTransfer.effectAllowed="move")}handleDragOver(e,t){t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="move"),this.dragOverDate=e,this.render()}handleDragLeave(e){const t=e.relatedTarget,a=e.currentTarget;a&&t&&a.contains(t)||(this.dragOverDate=null,this.render())}handleDrop(e,t){if(t.preventDefault(),!this.draggedEvent)return;const a={...this.draggedEvent,date:n(e)};this.emit("db-event-edit",{event:a}),this.draggedEvent=null,this.dragOverDate=null,this.render()}handleDragEnd(){this.draggedEvent=null,this.dragOverDate=null,this.render()}handleEventClick(e,t){t.stopPropagation(),this.selectedEvent=e,this.isEditing=!0;const n=a(e.date);n&&(this.selectedDate=n),this.eventForm={title:e.title,description:e.description||"",startTime:e.startTime||"09:00",endTime:e.endTime||"10:00",type:e.type,color:e.color||"#17a2b8",isAllDay:e.isAllDay||!1,location:e.location||""},this.emit("db-event-click",{event:e}),this.showEventModal=!0,this.render()}openAddModal(e){this.selectedDate=e,this.selectedEvent=null,this.isEditing=!1,this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""},this.showEventModal=!0,this.render()}closeModal(){this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.render()}saveEvent(){if(!this.eventForm.title.trim())return void window.alert("제목을 입력해주세요.");const e={title:this.eventForm.title.trim(),description:this.eventForm.description,date:n(this.selectedDate),startTime:this.eventForm.startTime,endTime:this.eventForm.endTime,type:this.eventForm.type,color:this.eventForm.color,isAllDay:this.eventForm.isAllDay,location:this.eventForm.location};if(this.isEditing&&this.selectedEvent){const t={...this.selectedEvent,...e};this.emit("db-event-edit",{event:t})}else this.emit("db-event-add",{event:e});this.closeModal()}deleteEvent(){this.selectedEvent&&window.confirm("정말로 이 일정을 삭제하시겠습니까?")&&(this.emit("db-event-delete",{eventId:this.selectedEvent.id}),this.closeModal())}renderHeader(){if(!this.headerEl)return;this.headerEl.replaceChildren();const a=document.createElement("div");a.className=`${s}__navigation`;const n=t("m"),i=document.createElement("button");i.type="button",i.className=`${s}__nav-button`,i.setAttribute("aria-label","이전"),i.appendChild(e("chevron-left",n)),i.addEventListener("click",()=>{this.shiftMonth(-1)});const d=document.createElement("div");d.className=`${s}__title`,d.textContent=this.selectedDate.toLocaleDateString(this.locale,{year:"numeric",month:"long"});const l=document.createElement("button");l.type="button",l.className=`${s}__nav-button`,l.setAttribute("aria-label","다음"),l.appendChild(e("chevron-right",n)),l.addEventListener("click",()=>{this.shiftMonth(1)}),a.append(i,d,l),this.headerEl.appendChild(a)}renderMonthView(){const e=document.createElement("div");e.className=`${s}__month-view`;const t=document.createElement("div");t.className=`${s}__weekdays`,["일","월","화","수","목","금","토"].forEach(e=>{const a=document.createElement("div");a.className=`${s}__weekday`,a.textContent=e,t.appendChild(a)}),e.appendChild(t);const a=document.createElement("div");a.className=`${s}__days`;const n=this.selectedDate.getFullYear(),i=this.selectedDate.getMonth(),d=new Date(n,i,1),l=new Date(d);l.setDate(l.getDate()-d.getDay());const r=new Date;for(let e=0;e<42;e+=1){const t=new Date(l);t.setDate(l.getDate()+e);const n=t.getMonth()===i;if(!this.showOutsideDays&&!n)continue;const d=0===t.getDay()||6===t.getDay();if(!this.showWeekends&&d)continue;const o=document.createElement("div"),c=this.selectedDateRange.start&&this.selectedDateRange.end&&t>=this.selectedDateRange.start&&t<=this.selectedDateRange.end,h=this.selectedDateRange.start&&t.toDateString()===this.selectedDateRange.start.toDateString(),m=this.selectedDateRange.end&&t.toDateString()===this.selectedDateRange.end.toDateString(),u=Boolean(c&&!h&&!m);o.className=[`${s}__day`,n&&`${s}__day--current-month`,this.highlightToday&&t.toDateString()===r.toDateString()&&`${s}__day--today`,this.isSameDate(t,this.selectedDate)&&`${s}__day--selected`,h&&`${s}__day--selected--start`,m&&`${s}__day--selected--end`,u&&`${s}__day--selected--middle`,!this.showWeekends&&d&&`${s}__day--weekend`].filter(Boolean).join(" "),o.addEventListener("click",()=>this.handleDateClick(t));const v=document.createElement("span");v.className=`${s}__day-number`,v.textContent=String(t.getDate()),o.appendChild(v);const p=this.eventsForDate(t);if(p.length){const e=document.createElement("div");if(e.className=`${s}__day-events`,p.slice(0,2).forEach(t=>{const a=document.createElement("div");a.className=[`${s}__event-bar`,`${s}__event-bar--${t.type}`].filter(Boolean).join(" "),t.color&&(a.style.backgroundColor=t.color),this.draggedEvent?.id===t.id&&a.classList.add(`${s}__event-bar--dragging`),a.title=t.title,a.draggable=!0;const n=document.createElement("span");n.className=`${s}__event-title`,n.textContent=t.title,a.appendChild(n),a.addEventListener("click",e=>this.handleEventClick(t,e)),a.addEventListener("dragstart",e=>this.handleDragStart(t,e)),a.addEventListener("dragend",()=>this.handleDragEnd()),e.appendChild(a)}),p.length>2){const t=document.createElement("div");t.className=`${s}__more-events`,t.textContent=`+${p.length-2} more`,e.appendChild(t)}o.appendChild(e)}const g=document.createElement("div");g.className=[`${s}__drop-zone`,this.dragOverDate&&this.isSameDate(this.dragOverDate,t)&&`${s}__drop-zone--active`].filter(Boolean).join(" "),g.addEventListener("dragover",e=>this.handleDragOver(t,e)),g.addEventListener("dragleave",e=>this.handleDragLeave(e)),g.addEventListener("drop",e=>this.handleDrop(t,e)),o.appendChild(g),a.appendChild(o)}return e.appendChild(a),e}renderYearView(){const e=document.createElement("div");e.className=`${s}__year-view`;const t=this.selectedDate.getFullYear();for(let n=0;n<12;n+=1){const i=new Date(t,n,1),d=this._events.filter(e=>{const s=a(e.date);return s&&s.getFullYear()===t&&s.getMonth()===n}),l=document.createElement("div");l.className=`${s}__year-month`,l.addEventListener("click",()=>{this.selectedDate=i,this.handleViewChange("month")});const r=document.createElement("h3");if(r.className=`${s}__year-month-title`,r.textContent=i.toLocaleDateString(this.locale,{month:"long"}),l.appendChild(r),d.length){const e=document.createElement("div");if(e.className=`${s}__year-month-events`,d.slice(0,4).forEach(t=>{const a=document.createElement("span");a.className=[`${s}__year-event`,`${s}__year-event--${t.type}`].join(" "),t.color&&(a.style.backgroundColor=t.color),e.appendChild(a)}),d.length>4){const t=document.createElement("span");t.className=`${s}__year-more-events`,t.textContent=`+${d.length-4} more`,e.appendChild(t)}l.appendChild(e)}e.appendChild(l)}return e}renderWeekView(){const e=document.createElement("div");e.className=`${s}__week-view`;const t=new Date,a=new Date(this.selectedDate);a.setDate(this.selectedDate.getDate()-this.selectedDate.getDay());const n=document.createElement("div");n.className=`${s}__week-header`;const i=document.createElement("div");i.className=`${s}__time-column-header`,n.appendChild(i);for(let e=0;e<7;e+=1){const i=new Date(a);i.setDate(a.getDate()+e);const d=document.createElement("div");d.className=[`${s}__week-day-header`,i.toDateString()===t.toDateString()&&`${s}__week-day-header--today`].filter(Boolean).join(" ");const l=document.createElement("span");l.className=`${s}__week-day-name`,l.textContent=i.toLocaleDateString(this.locale,{weekday:"short"});const r=document.createElement("span");r.className=`${s}__week-day-number`,r.textContent=String(i.getDate()),d.append(l,r),n.appendChild(d)}e.appendChild(n);const d=document.createElement("div");d.className=`${s}__week-grid`;const l=document.createElement("div");l.className=`${s}__week-time-column`;for(let e=6;e<=22;e+=1){const t=document.createElement("div");t.className=`${s}__time-slot`;const a=document.createElement("span");a.className=`${s}__time-label`,a.textContent=`${String(e).padStart(2,"0")}:00`,t.appendChild(a),l.appendChild(t)}d.appendChild(l);const r=document.createElement("div");r.className=`${s}__week-columns`;for(let e=0;e<7;e+=1){const t=new Date(a);t.setDate(a.getDate()+e);const n=document.createElement("div");n.className=`${s}__week-column`;for(let e=6;e<=22;e+=1){const a=document.createElement("div");a.className=`${s}__week-cell`,a.title=`${t.toLocaleDateString()} ${String(e).padStart(2,"0")}:00`,a.addEventListener("click",()=>{this.selectedDate=new Date(t),this.eventForm.startTime=`${String(e).padStart(2,"0")}:00`,this.eventForm.endTime=`${String(e+1).padStart(2,"0")}:00`,this.openAddModal(this.selectedDate)}),n.appendChild(a)}this.eventsForDate(t).forEach(e=>{if(!e.startTime)return;const[t,a]=e.startTime.split(":").map(Number),i=.8*(60*(t-6)+(a||0)),d=(e.endTime||e.startTime).split(":").map(Number),l=60*(d[0]||t)+(d[1]||0),r=60*t+(a||0),o=Math.max(20,48*(l-r)/60),c=document.createElement("div");c.className=[`${s}__week-event`,`${s}__week-event--${e.type}`].filter(Boolean).join(" "),c.textContent=e.title,c.title=e.title,c.style.backgroundColor=e.color||"#17a2b8",c.style.top=`${i}px`,c.style.height=`${o}px`,c.addEventListener("click",t=>this.handleEventClick(e,t)),n.appendChild(c)}),r.appendChild(n)}return d.appendChild(r),e.appendChild(d),e}renderModal(){if(!this.modalEl)return;if(this.modalEl.replaceChildren(),!this.showEventModal)return void this.modalEl.removeAttribute("open");this.modalEl.setAttribute("open","true"),this.modalEl.setAttribute("title",this.isEditing?"일정 편집":"새 일정 추가");const e=document.createElement("div");e.className=`${s}__event-form`;const t=document.createElement("db-input");t.setAttribute("label","제목 *"),t.setAttribute("placeholder","일정 제목을 입력하세요"),t.setAttribute("full-width",""),t.setAttribute("value",this.eventForm.title),t.addEventListener("db-input",e=>{this.eventForm.title=e.detail.value});const l=document.createElement("db-input");l.setAttribute("label","설명"),l.setAttribute("placeholder","일정 설명을 입력하세요"),l.setAttribute("full-width",""),l.setAttribute("value",this.eventForm.description),l.addEventListener("db-input",e=>{this.eventForm.description=e.detail.value});const r=document.createElement("db-date-picker");r.setAttribute("label","날짜"),r.setAttribute("full-width",""),r.setAttribute("value",n(this.selectedDate)),r.addEventListener("db-change",e=>{const t=a(e.detail.value);t&&(this.selectedDate=t)});const o=document.createElement("db-select");o.setAttribute("label","일정 타입"),o.setAttribute("full-width",""),o.setAttribute("options",JSON.stringify(i)),o.setAttribute("value",this.eventForm.type),o.addEventListener("db-change",e=>{this.eventForm.type=e.detail.value});const c=document.createElement("db-select");c.setAttribute("label","색상"),c.setAttribute("full-width",""),c.setAttribute("options",JSON.stringify(d)),c.setAttribute("value",this.eventForm.color),c.addEventListener("db-change",e=>{this.eventForm.color=e.detail.value});const h=document.createElement("db-time-picker");h.setAttribute("label","시작 시간"),h.setAttribute("full-width",""),h.setAttribute("value",this.eventForm.startTime),h.addEventListener("db-change",e=>{this.eventForm.startTime=e.detail.value});const m=document.createElement("db-time-picker");m.setAttribute("label","종료 시간"),m.setAttribute("full-width",""),m.setAttribute("value",this.eventForm.endTime),m.addEventListener("db-change",e=>{this.eventForm.endTime=e.detail.value}),e.append(t,l,r,o,c,h,m);const u=document.createElement("div");if(u.className=`${s}__event-form-footer`,u.style.display="flex",u.style.gap="8px",u.style.justifyContent="flex-end",u.style.marginTop="16px",this.isEditing){const e=document.createElement("db-button");e.setAttribute("variant","danger"),e.textContent="삭제",e.addEventListener("click",()=>this.deleteEvent()),u.appendChild(e)}const v=document.createElement("db-button");v.setAttribute("variant","secondary"),v.textContent="취소",v.addEventListener("click",()=>this.closeModal());const p=document.createElement("db-button");p.setAttribute("variant","primary"),p.textContent="저장",p.addEventListener("click",()=>this.saveEvent()),u.append(v,p),e.appendChild(u),this.modalEl.appendChild(e)}render(){this.className=s,this.replaceChildren(),this.headerEl&&this.bodyEl&&(this.renderHeader(),this.bodyEl.replaceChildren(),this.bodyEl.appendChild(this.renderMonthView()),this.append(this.headerEl,this.bodyEl),this.renderModal(),this.showEventModal&&this.modalEl&&this.appendChild(this.modalEl))}}customElements.get("db-calendar")||customElements.define("db-calendar",DbCalendar);export{DbCalendar};
1
+ import{createDbIcon as e,getDbComponentIconSize as t}from"./db-icons.js";import{parseISODate as a,toISODate as n}from"./date-picker-utils.js";import"./db-modal.js";import"./db-input.js";import"./db-select.js";import"./db-date-picker.js";import"./db-time-picker.js";import"./db-button.js";const s="designbase-wc-calendar",i=[{value:"meeting",label:"회의"},{value:"task",label:"업무"},{value:"reminder",label:"알림"},{value:"birthday",label:"생일"},{value:"holiday",label:"휴일"},{value:"custom",label:"기타"}],d=[{value:"#17a2b8",label:"청록"},{value:"#0d6efd",label:"파랑"},{value:"#198754",label:"초록"},{value:"#ffc107",label:"노랑"},{value:"#dc3545",label:"빨강"},{value:"#6f42c1",label:"보라"}];class DbCalendar extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.currentView="month",this.selectedDate=new Date,this._events=[],this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.draggedEvent=null,this.dragOverDate=null,this.selectedDateRange={start:null,end:null},this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""}}static get observedAttributes(){return["view","current-date","events","locale","show-weekends","highlight-today","show-outside-days"]}connectedCallback(){this.built||this.build(),this.readAttributes(),this.render()}attributeChangedCallback(){this.built&&(this.readAttributes(),this.render())}get locale(){return this.getAttribute("locale")||"ko-KR"}get showWeekends(){return"false"!==this.getAttribute("show-weekends")}get highlightToday(){return"false"!==this.getAttribute("highlight-today")}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get events(){return this._events}set events(e){"string"!=typeof e?(this._events=Array.isArray(e)?e:[],this.setAttribute("events",JSON.stringify(this._events))):this.setAttribute("events",e)}build(){this.built=!0,this.headerEl=document.createElement("div"),this.headerEl.className=`${s}__header`,this.bodyEl=document.createElement("div"),this.bodyEl.className=`${s}__body`,this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","m"),this.modalEl.addEventListener("db-close",()=>this.closeModal())}readAttributes(){this.currentView="month";const e=a(this.getAttribute("current-date"));e&&(this.selectedDate=e);const t=this.getAttribute("events");if(t)try{const e=JSON.parse(t);this._events=Array.isArray(e)?e:[]}catch{this._events=[]}else this._events=[]}isSameDate(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}eventsForDate(e){return this._events.filter(t=>{const n=a(t.date);return!!n&&this.isSameDate(n,e)})}emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}handleViewChange(e){this.currentView="month",this.emit("db-view-change",{view:e}),this.render()}shiftMonth(e){const t=new Date(this.selectedDate);t.setMonth(t.getMonth()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}shiftYear(e){const t=new Date(this.selectedDate);t.setFullYear(t.getFullYear()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}handleDateClick(e){this.selectedDate=e,this.emit("db-date-click",{date:n(e)}),!this.selectedDateRange.start||this.selectedDateRange.start&&this.selectedDateRange.end?this.selectedDateRange={start:e,end:null}:this.selectedDateRange.start&&!this.selectedDateRange.end&&(e<this.selectedDateRange.start?this.selectedDateRange={start:e,end:this.selectedDateRange.start}:this.selectedDateRange={start:this.selectedDateRange.start,end:e}),this.openAddModal(e)}handleDragStart(e,t){this.draggedEvent=e,t.dataTransfer?.setData("text/plain",e.id),t.dataTransfer?.setData("application/json",JSON.stringify(e)),t.dataTransfer&&(t.dataTransfer.effectAllowed="move")}handleDragOver(e,t){t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="move"),this.dragOverDate=e,this.render()}handleDragLeave(e){const t=e.relatedTarget,a=e.currentTarget;a&&t&&a.contains(t)||(this.dragOverDate=null,this.render())}handleDrop(e,t){if(t.preventDefault(),!this.draggedEvent)return;const a={...this.draggedEvent,date:n(e)};this.emit("db-event-edit",{event:a}),this.draggedEvent=null,this.dragOverDate=null,this.render()}handleDragEnd(){this.draggedEvent=null,this.dragOverDate=null,this.render()}handleEventClick(e,t){t.stopPropagation(),this.selectedEvent=e,this.isEditing=!0;const n=a(e.date);n&&(this.selectedDate=n),this.eventForm={title:e.title,description:e.description||"",startTime:e.startTime||"09:00",endTime:e.endTime||"10:00",type:e.type,color:e.color||"#17a2b8",isAllDay:e.isAllDay||!1,location:e.location||""},this.emit("db-event-click",{event:e}),this.showEventModal=!0,this.render()}openAddModal(e){this.selectedDate=e,this.selectedEvent=null,this.isEditing=!1,this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""},this.showEventModal=!0,this.render()}closeModal(){this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.render()}saveEvent(){if(!this.eventForm.title.trim())return void window.alert("제목을 입력해주세요.");const e={title:this.eventForm.title.trim(),description:this.eventForm.description,date:n(this.selectedDate),startTime:this.eventForm.startTime,endTime:this.eventForm.endTime,type:this.eventForm.type,color:this.eventForm.color,isAllDay:this.eventForm.isAllDay,location:this.eventForm.location};if(this.isEditing&&this.selectedEvent){const t={...this.selectedEvent,...e};this.emit("db-event-edit",{event:t})}else this.emit("db-event-add",{event:e});this.closeModal()}deleteEvent(){this.selectedEvent&&window.confirm("정말로 이 일정을 삭제하시겠습니까?")&&(this.emit("db-event-delete",{eventId:this.selectedEvent.id}),this.closeModal())}renderHeader(){if(!this.headerEl)return;this.headerEl.replaceChildren();const a=document.createElement("div");a.className=`${s}__navigation`;const n=t("m"),i=document.createElement("button");i.type="button",i.className=`${s}__nav-button`,i.setAttribute("aria-label","이전"),i.appendChild(e("chevron-left",n)),i.addEventListener("click",()=>{this.shiftMonth(-1)});const d=document.createElement("div");d.className=`${s}__title`,d.textContent=this.selectedDate.toLocaleDateString(this.locale,{year:"numeric",month:"long"});const l=document.createElement("button");l.type="button",l.className=`${s}__nav-button`,l.setAttribute("aria-label","다음"),l.appendChild(e("chevron-right",n)),l.addEventListener("click",()=>{this.shiftMonth(1)}),a.append(i,d,l),this.headerEl.appendChild(a)}renderMonthView(){const e=document.createElement("div");e.className=`${s}__month-view`;const t=document.createElement("div");t.className=`${s}__weekdays`,["일","월","화","수","목","금","토"].forEach(e=>{const a=document.createElement("div");a.className=`${s}__weekday`,a.textContent=e,t.appendChild(a)}),e.appendChild(t);const a=document.createElement("div");a.className=`${s}__days`;const n=this.selectedDate.getFullYear(),i=this.selectedDate.getMonth(),d=new Date(n,i,1),l=new Date(d);l.setDate(l.getDate()-d.getDay());const r=new Date;for(let e=0;e<42;e+=1){const t=new Date(l);t.setDate(l.getDate()+e);const n=t.getMonth()===i;if(!this.showOutsideDays&&!n)continue;const d=0===t.getDay()||6===t.getDay();if(!this.showWeekends&&d)continue;const o=document.createElement("div"),c=this.selectedDateRange.start&&this.selectedDateRange.end&&t>=this.selectedDateRange.start&&t<=this.selectedDateRange.end,h=this.selectedDateRange.start&&t.toDateString()===this.selectedDateRange.start.toDateString(),m=this.selectedDateRange.end&&t.toDateString()===this.selectedDateRange.end.toDateString(),u=Boolean(c&&!h&&!m);o.className=[`${s}__day`,n&&`${s}__day--current-month`,this.highlightToday&&t.toDateString()===r.toDateString()&&`${s}__day--today`,this.isSameDate(t,this.selectedDate)&&`${s}__day--selected`,h&&`${s}__day--selected--start`,m&&`${s}__day--selected--end`,u&&`${s}__day--selected--middle`,!this.showWeekends&&d&&`${s}__day--weekend`].filter(Boolean).join(" "),o.addEventListener("click",()=>this.handleDateClick(t));const v=document.createElement("span");v.className=`${s}__day-number`,v.textContent=String(t.getDate()),o.appendChild(v);const p=this.eventsForDate(t);if(p.length){const e=document.createElement("div");if(e.className=`${s}__day-events`,p.slice(0,2).forEach(t=>{const a=document.createElement("div");a.className=[`${s}__event-bar`,`${s}__event-bar--${t.type}`].filter(Boolean).join(" "),t.color&&(a.style.backgroundColor=t.color),this.draggedEvent?.id===t.id&&a.classList.add(`${s}__event-bar--dragging`),a.title=t.title,a.draggable=!0;const n=document.createElement("span");n.className=`${s}__event-title`,n.textContent=t.title,a.appendChild(n),a.addEventListener("click",e=>this.handleEventClick(t,e)),a.addEventListener("dragstart",e=>this.handleDragStart(t,e)),a.addEventListener("dragend",()=>this.handleDragEnd()),e.appendChild(a)}),p.length>2){const t=document.createElement("div");t.className=`${s}__more-events`,t.textContent=`+${p.length-2} more`,e.appendChild(t)}o.appendChild(e)}const g=document.createElement("div");g.className=[`${s}__drop-zone`,this.dragOverDate&&this.isSameDate(this.dragOverDate,t)&&`${s}__drop-zone--active`].filter(Boolean).join(" "),g.addEventListener("dragover",e=>this.handleDragOver(t,e)),g.addEventListener("dragleave",e=>this.handleDragLeave(e)),g.addEventListener("drop",e=>this.handleDrop(t,e)),o.appendChild(g),a.appendChild(o)}return e.appendChild(a),e}renderYearView(){const e=document.createElement("div");e.className=`${s}__year-view`;const t=this.selectedDate.getFullYear();for(let n=0;n<12;n+=1){const i=new Date(t,n,1),d=this._events.filter(e=>{const s=a(e.date);return s&&s.getFullYear()===t&&s.getMonth()===n}),l=document.createElement("div");l.className=`${s}__year-month`,l.addEventListener("click",()=>{this.selectedDate=i,this.handleViewChange("month")});const r=document.createElement("h3");if(r.className=`${s}__year-month-title`,r.textContent=i.toLocaleDateString(this.locale,{month:"long"}),l.appendChild(r),d.length){const e=document.createElement("div");if(e.className=`${s}__year-month-events`,d.slice(0,4).forEach(t=>{const a=document.createElement("span");a.className=[`${s}__year-event`,`${s}__year-event--${t.type}`].join(" "),t.color&&(a.style.backgroundColor=t.color),e.appendChild(a)}),d.length>4){const t=document.createElement("span");t.className=`${s}__year-more-events`,t.textContent=`+${d.length-4} more`,e.appendChild(t)}l.appendChild(e)}e.appendChild(l)}return e}renderWeekView(){const e=document.createElement("div");e.className=`${s}__week-view`;const t=new Date,a=new Date(this.selectedDate);a.setDate(this.selectedDate.getDate()-this.selectedDate.getDay());const n=document.createElement("div");n.className=`${s}__week-header`;const i=document.createElement("div");i.className=`${s}__time-column-header`,n.appendChild(i);for(let e=0;e<7;e+=1){const i=new Date(a);i.setDate(a.getDate()+e);const d=document.createElement("div");d.className=[`${s}__week-day-header`,i.toDateString()===t.toDateString()&&`${s}__week-day-header--today`].filter(Boolean).join(" ");const l=document.createElement("span");l.className=`${s}__week-day-name`,l.textContent=i.toLocaleDateString(this.locale,{weekday:"short"});const r=document.createElement("span");r.className=`${s}__week-day-number`,r.textContent=String(i.getDate()),d.append(l,r),n.appendChild(d)}e.appendChild(n);const d=document.createElement("div");d.className=`${s}__week-grid`;const l=document.createElement("div");l.className=`${s}__week-time-column`;for(let e=6;e<=22;e+=1){const t=document.createElement("div");t.className=`${s}__time-slot`;const a=document.createElement("span");a.className=`${s}__time-label`,a.textContent=`${String(e).padStart(2,"0")}:00`,t.appendChild(a),l.appendChild(t)}d.appendChild(l);const r=document.createElement("div");r.className=`${s}__week-columns`;for(let e=0;e<7;e+=1){const t=new Date(a);t.setDate(a.getDate()+e);const n=document.createElement("div");n.className=`${s}__week-column`;for(let e=6;e<=22;e+=1){const a=document.createElement("div");a.className=`${s}__week-cell`,a.title=`${t.toLocaleDateString()} ${String(e).padStart(2,"0")}:00`,a.addEventListener("click",()=>{this.selectedDate=new Date(t),this.eventForm.startTime=`${String(e).padStart(2,"0")}:00`,this.eventForm.endTime=`${String(e+1).padStart(2,"0")}:00`,this.openAddModal(this.selectedDate)}),n.appendChild(a)}this.eventsForDate(t).forEach(e=>{if(!e.startTime)return;const[t,a]=e.startTime.split(":").map(Number),i=.8*(60*(t-6)+(a||0)),d=(e.endTime||e.startTime).split(":").map(Number),l=60*(d[0]||t)+(d[1]||0),r=60*t+(a||0),o=Math.max(20,48*(l-r)/60),c=document.createElement("div");c.className=[`${s}__week-event`,`${s}__week-event--${e.type}`].filter(Boolean).join(" "),c.textContent=e.title,c.title=e.title,c.style.backgroundColor=e.color||"#17a2b8",c.style.top=`${i}px`,c.style.height=`${o}px`,c.addEventListener("click",t=>this.handleEventClick(e,t)),n.appendChild(c)}),r.appendChild(n)}return d.appendChild(r),e.appendChild(d),e}renderModal(){if(!this.modalEl)return;if(this.modalEl.replaceChildren(),!this.showEventModal)return void this.modalEl.removeAttribute("open");this.modalEl.setAttribute("open","true"),this.modalEl.setAttribute("title",this.isEditing?"일정 편집":"새 일정 추가");const e=document.createElement("div");e.className=`${s}__event-form`;const t=document.createElement("db-input");t.setAttribute("label","제목 *"),t.setAttribute("placeholder","일정 제목을 입력하세요"),t.setAttribute("full-width",""),t.setAttribute("value",this.eventForm.title),t.addEventListener("db-input",e=>{this.eventForm.title=e.detail.value});const l=document.createElement("db-input");l.setAttribute("label","설명"),l.setAttribute("placeholder","일정 설명을 입력하세요"),l.setAttribute("full-width",""),l.setAttribute("value",this.eventForm.description),l.addEventListener("db-input",e=>{this.eventForm.description=e.detail.value});const r=document.createElement("db-date-picker");r.setAttribute("label","날짜"),r.setAttribute("full-width",""),r.setAttribute("value",n(this.selectedDate)),r.addEventListener("db-change",e=>{const t=a(e.detail.value);t&&(this.selectedDate=t)});const o=document.createElement("db-select");o.setAttribute("label","일정 타입"),o.setAttribute("full-width",""),o.setAttribute("options",JSON.stringify(i)),o.setAttribute("value",this.eventForm.type),o.addEventListener("db-change",e=>{this.eventForm.type=e.detail.value});const c=document.createElement("db-select");c.setAttribute("label","색상"),c.setAttribute("full-width",""),c.setAttribute("options",JSON.stringify(d)),c.setAttribute("value",this.eventForm.color),c.addEventListener("db-change",e=>{this.eventForm.color=e.detail.value});const h=document.createElement("db-time-picker");h.setAttribute("label","시작 시간"),h.setAttribute("full-width",""),h.setAttribute("value",this.eventForm.startTime),h.addEventListener("db-change",e=>{this.eventForm.startTime=e.detail.value});const m=document.createElement("db-time-picker");m.setAttribute("label","종료 시간"),m.setAttribute("full-width",""),m.setAttribute("value",this.eventForm.endTime),m.addEventListener("db-change",e=>{this.eventForm.endTime=e.detail.value}),e.append(t,l,r,o,c,h,m);const u=document.createElement("div");u.className="designbase-wc-modal__body",u.setAttribute("data-modal-part","body"),u.appendChild(e);const v=document.createElement("div");v.className="designbase-wc-modal__footer",v.setAttribute("data-modal-part","footer");const p=document.createElement("div");if(p.className=`${s}__modal-actions`,this.isEditing){const e=document.createElement("db-button");e.setAttribute("variant","danger"),e.textContent="삭제",e.addEventListener("click",()=>this.deleteEvent()),p.appendChild(e)}const g=document.createElement("div");g.className=`${s}__modal-buttons`;const b=document.createElement("db-button");b.setAttribute("variant","secondary"),b.textContent="취소",b.addEventListener("click",()=>this.closeModal());const E=document.createElement("db-button");E.setAttribute("variant","primary"),E.textContent=this.isEditing?"수정":"저장",E.addEventListener("click",()=>this.saveEvent()),g.append(b,E),p.appendChild(g),v.appendChild(p),this.modalEl.append(u,v)}render(){this.className=s,this.replaceChildren(),this.headerEl&&this.bodyEl&&(this.renderHeader(),this.bodyEl.replaceChildren(),this.bodyEl.appendChild(this.renderMonthView()),this.append(this.headerEl,this.bodyEl),this.renderModal(),this.showEventModal&&this.modalEl&&this.appendChild(this.modalEl))}}customElements.get("db-calendar")||customElements.define("db-calendar",DbCalendar);export{DbCalendar};
@@ -1 +1 @@
1
- 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)||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 e=Number(this.getAttribute("x")||0),t=Number(this.getAttribute("y")||0),n=this.items,i=document.createElement("div");i.className="designbase-wc-context-menu",i.setAttribute("data-wc-internal",""),i.style.position="fixed",i.style.left=`${e}px`,i.style.top=`${t}px`,i.style.zIndex="1000",i.setAttribute("role","menu"),i.setAttribute("aria-orientation","vertical"),n.forEach((e,t)=>{const n=this.renderItem(e,t);n&&i.append(n)}),document.body.append(i),this.menuEl=i,requestAnimationFrame(()=>this.adjustPosition())}}customElements.get("db-context-menu")||customElements.define("db-context-menu",DbContextMenu);export{DbContextMenu};
1
+ class DbContextMenu extends HTMLElement{constructor(){super(...arguments),this.externalTarget=null,this.activeSubMenu=null,this.onExternalContextMenu=null,this.handleDocumentMouseDown=t=>{if(!this.open)return;const e=t.target;this.menuEl?.contains(e)||2===t.button&&(this.targetWrap?.contains(e)||this.externalTarget?.contains(e))||this.close()},this.handleKeyDown=t=>{this.open&&"Escape"===t.key&&this.close()},this.handleContextMenu=t=>{this.hasAttribute("disabled")||(t.preventDefault(),t.stopPropagation(),this.openAt(t.clientX,t.clientY))}}static get observedAttributes(){return["open","x","y","items","target-id","disabled"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open","true"):this.removeAttribute("open")}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}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(t){if(this.isConnected)return"target-id"===t?(this.unbindExternalTarget(),void this.bindExternalTarget()):void("open"!==t&&"x"!==t&&"y"!==t&&"items"!==t||this.syncMenu())}openAt(t,e){this.setAttribute("x",String(t)),this.setAttribute("y",String(e)),this.setAttribute("open","true"),this.dispatchEvent(new CustomEvent("db-open",{bubbles:!0,composed:!0,detail:{x:t,y:e}})),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 t=Array.from(this.children).filter(t=>!t.hasAttribute("data-wc-internal")&&t!==this.targetWrap);return t.length>0?t:Array.from(this.targetWrap?.children||[])}bindExternalTarget(){const t=this.getAttribute("target-id");t&&(this.externalTarget=document.getElementById(t),this.externalTarget&&(this.onExternalContextMenu=t=>this.handleContextMenu(t),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 t=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(),t.forEach(t=>this.targetWrap.append(t)),t.length>0&&this.append(this.targetWrap))}adjustPosition(){if(!this.menuEl)return;const t=Number(this.getAttribute("x")||0),e=Number(this.getAttribute("y")||0),n=this.menuEl.getBoundingClientRect();let i=t,s=e;t+n.width>window.innerWidth&&(i=t-n.width),e+n.height>window.innerHeight&&(s=e-n.height),this.menuEl.style.left=`${Math.max(0,i)}px`,this.menuEl.style.top=`${Math.max(0,s)}px`}createMenuItem(t){const e=document.createElement("db-menu-item");return e.setAttribute("label",t.label||t.id),e.setAttribute("type","block"),e.setAttribute("menu-style","dropdown"),t.icon&&e.setAttribute("icon",t.icon),t.disabled&&e.setAttribute("disabled",""),t.variant&&e.setAttribute("variant",t.variant),t.subItems?.length&&(e.setAttribute("sub-items",JSON.stringify(t.subItems)),e.setAttribute("expandable","")),e.addEventListener("db-click",()=>{t.disabled||t.subItems?.length||(this.dispatchEvent(new CustomEvent("db-select",{detail:{item:t},bubbles:!0,composed:!0})),this.close())}),e.addEventListener("db-child-click",t=>{const e=t.detail?.child;this.dispatchEvent(new CustomEvent("db-select",{detail:{item:e},bubbles:!0,composed:!0})),this.close()}),e}renderItem(t,e){if(t.divider||t.isDivider){const t=document.createElement("db-divider");return t.className="designbase-wc-divider",t}const n=document.createElement("div");n.className="designbase-wc-context-menu__item-wrapper",n.append(this.createMenuItem(t));if(Boolean(t.subItems?.length)){const e=document.createElement("div");e.className=["designbase-wc-context-menu__submenu",this.activeSubMenu===t.id&&"designbase-wc-context-menu__submenu--open"].filter(Boolean).join(" "),t.subItems?.forEach((t,n)=>{const i=this.renderItem(t,n);i&&e.append(i)}),n.addEventListener("mouseenter",()=>{this.activeSubMenu=t.id,e.classList.add("designbase-wc-context-menu__submenu--open")}),n.addEventListener("mouseleave",()=>{this.activeSubMenu=null,e.classList.remove("designbase-wc-context-menu__submenu--open")}),n.append(e)}return n}syncMenu(){if(this.menuEl?.remove(),this.menuEl=void 0,!this.open)return;const t=Number(this.getAttribute("x")||0),e=Number(this.getAttribute("y")||0),n=this.items,i=document.createElement("div");i.className="designbase-wc-context-menu",i.setAttribute("data-wc-internal",""),i.style.position="fixed",i.style.left=`${t}px`,i.style.top=`${e}px`,i.style.zIndex="1000",i.setAttribute("role","menu"),i.setAttribute("aria-orientation","vertical"),n.forEach((t,e)=>{const n=this.renderItem(t,e);n&&i.append(n)}),document.body.append(i),this.menuEl=i,requestAnimationFrame(()=>this.adjustPosition())}}customElements.get("db-context-menu")||customElements.define("db-context-menu",DbContextMenu);export{DbContextMenu};
@@ -1,5 +1,4 @@
1
1
  declare class DbCursorFollower extends HTMLElement {
2
- private scopeEl?;
3
2
  private portalRoot?;
4
3
  private pillEl?;
5
4
  private labelEl?;
@@ -17,7 +16,7 @@ declare class DbCursorFollower extends HTMLElement {
17
16
  disconnectedCallback(): void;
18
17
  attributeChangedCallback(): void;
19
18
  private setupDesktopGate;
20
- private ensureScope;
19
+ private updateScope;
21
20
  private isInScope;
22
21
  private mountLayer;
23
22
  private teardownLayer;
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e="designbase-wc-cursor-follower",s="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.ensureScope(),this.mountLayer()):this.teardownLayer())},this.onDesktopChange(),this.desktopMq.addEventListener("change",this.onDesktopChange))}ensureScope(){if(this.scopeEl)return;if(this.childElementCount>0||this.textContent?.trim()){this.isScoped=!0,this.scopeEl=document.createElement("div"),this.scopeEl.className="designbase-wc-cursor-follower-scope";const t=document.createElement("slot");this.scopeEl.appendChild(t),this.appendChild(this.scopeEl)}}isInScope(t){return!!t&&(!this.isScoped||!this.scopeEl||this.scopeEl.contains(t))}mountLayer(){this.teardownLayer(),this.ensureScope();const i=this.getAttribute("default-label")||"See the project",o=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"]',n=Math.min(1,Math.max(.05,Number(this.getAttribute("smoothness")||.14))),r=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"),a=!this.hasAttribute("show-icon")||"false"!==this.getAttribute("show-icon");l&&document.documentElement.classList.add(s),this.portalRoot=document.createElement("div"),this.portalRoot.className=e,this.portalRoot.setAttribute("aria-hidden","true"),this.pillEl=document.createElement("div"),this.pillEl.className=`${e}__pill`,this.labelEl=document.createElement("span"),this.labelEl.textContent=i,this.pillEl.appendChild(this.labelEl),a&&(this.iconEl=document.createElement("span"),this.iconEl.className=`${e}__icon`,this.iconEl.appendChild(t("arrow-right",14)),this.pillEl.appendChild(this.iconEl)),this.portalRoot.appendChild(this.pillEl),document.body.appendChild(this.portalRoot),this.onMouseMove=t=>{this.target={x:t.clientX+r.x,y:t.clientY+r.y};const s=document.elementFromPoint(t.clientX,t.clientY),n=s?.closest(o)??null;this.isInScope(n)&&n?(this.labelEl&&(this.labelEl.textContent=function getLabelFromElement(t,e){return t.getAttribute("data-cursor-label")||t.getAttribute("data-cursor")||t.getAttribute("aria-label")||e}(n,i)),this.pillEl?.classList.add(`${e}__pill--visible`)):this.pillEl?.classList.remove(`${e}__pill--visible`)},window.addEventListener("mousemove",this.onMouseMove,{passive:!0});const tick=()=>{this.current.x+=(this.target.x-this.current.x)*n,this.current.y+=(this.target.y-this.current.y)*n,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(s),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.scopeEl?.remove(),this.scopeEl=void 0,this.isScoped=!1,this.enabled=!1}}customElements.get("db-cursor-follower")||customElements.define("db-cursor-follower",DbCursorFollower);export{DbCursorFollower};
1
+ import{createDbIcon as t}from"./db-icons.js";const e="designbase-wc-cursor-follower",s="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 i=this.getAttribute("default-label")||"See the project",o=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"]',n=Math.min(1,Math.max(.05,Number(this.getAttribute("smoothness")||.14))),r=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")),a=this.hasAttribute("hide-native-cursor")&&"false"!==this.getAttribute("hide-native-cursor"),l=!this.hasAttribute("show-icon")||"false"!==this.getAttribute("show-icon");a&&document.documentElement.classList.add(s),this.portalRoot=document.createElement("div"),this.portalRoot.className=e,this.portalRoot.setAttribute("aria-hidden","true"),this.pillEl=document.createElement("div"),this.pillEl.className=`${e}__pill`,this.labelEl=document.createElement("span"),this.labelEl.textContent=i,this.pillEl.appendChild(this.labelEl),l&&(this.iconEl=document.createElement("span"),this.iconEl.className=`${e}__icon`,this.iconEl.appendChild(t("arrow-right",14)),this.pillEl.appendChild(this.iconEl)),this.portalRoot.appendChild(this.pillEl),document.body.appendChild(this.portalRoot),this.onMouseMove=t=>{this.target={x:t.clientX+r.x,y:t.clientY+r.y};const s=document.elementFromPoint(t.clientX,t.clientY),n=s?.closest(o)??null;this.isInScope(n)&&n?(this.labelEl&&(this.labelEl.textContent=function getLabelFromElement(t,e){return t.getAttribute("data-cursor-label")||t.getAttribute("data-cursor")||t.getAttribute("aria-label")||e}(n,i)),this.pillEl?.classList.add(`${e}__pill--visible`)):this.pillEl?.classList.remove(`${e}__pill--visible`)},window.addEventListener("mousemove",this.onMouseMove,{passive:!0});const tick=()=>{this.current.x+=(this.target.x-this.current.x)*n,this.current.y+=(this.target.y-this.current.y)*n,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(s),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};
@@ -1 +1 @@
1
- import{isDbIconName as e,createDbIcon as t}from"./db-icons.js";const i=["s","m","l"],r=["bottom-left","bottom-right","top-left","top-right"],s=["primary","secondary","tertiary","danger","ghost"];class DbDropdown extends HTMLElement{constructor(){super(...arguments),this.focusedIndex=-1,this.onTriggerActivate=null,this.lastTriggerSignature="",this.handleTriggerKeyDown=e=>{if(("Enter"===e.key||" "===e.key||"ArrowDown"===e.key)&&!this.open)return e.preventDefault(),this.open=!0,requestAnimationFrame(()=>this.focusItem(0)),void this.render();"Escape"===e.key&&this.open&&(e.preventDefault(),this.open=!1,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();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"]}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=>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||(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"].join("|")}renderDefaultTrigger(){const t=this.resolvedSize(),i=this.getAttribute("trigger-variant")||"tertiary",r=s.includes(i)?i:"tertiary",n=this.hasAttribute("icon-only"),a=this.getAttribute("trigger-icon"),o=document.createElement("db-button");if(o.setAttribute("type","button"),o.setAttribute("variant",r),o.setAttribute("size",t),o.className="designbase-wc-dropdown__trigger",o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-label",this.triggerLabel()),this.fullWidth&&o.setAttribute("full-width",""),n)o.setAttribute("icon-only",""),o.setAttribute("start-icon",a&&e(a)?a:"edit"),o.removeAttribute("end-icon");else{o.removeAttribute("icon-only"),a&&e(a)?o.setAttribute("start-icon",a):o.removeAttribute("start-icon");const t=document.createElement("span");t.className="designbase-wc-dropdown__trigger-label",t.textContent=this.triggerLabel(),o.append(t),o.setAttribute("end-icon","chevron-down")}return o}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")),this.contains(this.triggerWrap)||this.append(this.triggerWrap),this.triggerWrap.contains(this.menu)||this.triggerWrap.append(this.menu),Array.from(this.children).forEach(e=>{e===this.triggerWrap||e.hasAttribute("data-wc-internal")||this.triggerWrap.insertBefore(e,this.menu)})}renderTrigger(){const e=this.collectTriggerChildren();if(e.length>0){this.defaultTrigger?.remove(),this.defaultTrigger=void 0;Array.from(this.triggerWrap.children).filter(e=>e!==this.menu&&e!==this.defaultTrigger).forEach(e=>e.remove()),e.forEach(e=>{e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",String(this.open)),e.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),this.triggerWrap.insertBefore(e,this.menu||null)})}else{Array.from(this.triggerWrap.children).filter(e=>e!==this.menu&&e!==this.defaultTrigger).forEach(e=>e.remove()),this.defaultTrigger&&this.triggerSignature()===this.lastTriggerSignature?this.syncDefaultTriggerState(this.defaultTrigger):(this.defaultTrigger?.remove(),this.defaultTrigger=this.renderDefaultTrigger(),this.lastTriggerSignature=this.triggerSignature(),this.triggerWrap.insertBefore(this.defaultTrigger,this.menu||null))}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()),this.menu.replaceChildren();const i=this.menuItemIconSize();this.parsedItems.forEach((e,r)=>{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(r);const s=e.label||e.id,n=Boolean(e.disabled||this.disabled),a=this.focusedIndex===r,o=document.createElement("button");if(o.type="button",o.className=["designbase-wc-dropdown__item",n&&"designbase-wc-dropdown__item--disabled",a&&"designbase-wc-dropdown__item--focused"].filter(Boolean).join(" "),o.setAttribute("role","menuitem"),o.disabled=n,o.tabIndex=a?0:-1,o.dataset.index=String(r),e.icon){const r=t(e.icon,i);r.classList.add("designbase-wc-dropdown__item-icon"),o.append(r)}const d=document.createElement("span");d.className="designbase-wc-dropdown__item-label",d.textContent=s,o.append(d),o.addEventListener("click",t=>{t.stopPropagation(),this.selectItem(e)}),this.menu?.append(o)})}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){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{isDbIconName as e,createDbIcon as t}from"./db-icons.js";const i=["s","m","l"],r=["bottom-left","bottom-right","top-left","top-right"],s=["primary","secondary","tertiary","danger","ghost"];class DbDropdown extends HTMLElement{constructor(){super(...arguments),this.focusedIndex=-1,this.onTriggerActivate=null,this.lastTriggerSignature="",this.handleTriggerKeyDown=e=>{if(("Enter"===e.key||" "===e.key||"ArrowDown"===e.key)&&!this.open)return e.preventDefault(),this.open=!0,requestAnimationFrame(()=>this.focusItem(0)),void this.render();"Escape"===e.key&&this.open&&(e.preventDefault(),this.open=!1,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();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"]}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=>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||(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"].join("|")}renderDefaultTrigger(){const t=this.resolvedSize(),i=this.getAttribute("trigger-variant")||"tertiary",r=s.includes(i)?i:"tertiary",n=this.hasAttribute("icon-only"),a=this.getAttribute("trigger-icon"),o=document.createElement("db-button");if(o.setAttribute("type","button"),o.setAttribute("variant",r),o.setAttribute("size",t),o.className="designbase-wc-dropdown__trigger",o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-label",this.triggerLabel()),this.fullWidth&&o.setAttribute("full-width",""),n)o.setAttribute("icon-only",""),o.setAttribute("start-icon",a&&e(a)?a:"edit"),o.removeAttribute("end-icon");else{o.removeAttribute("icon-only"),a&&e(a)?o.setAttribute("start-icon",a):o.removeAttribute("start-icon");const t=document.createElement("span");t.className="designbase-wc-dropdown__trigger-label",t.textContent=this.triggerLabel(),o.append(t),o.setAttribute("end-icon","chevron-down")}return o}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")),this.contains(this.triggerWrap)||this.append(this.triggerWrap),this.triggerWrap.contains(this.menu)||this.triggerWrap.append(this.menu),Array.from(this.children).forEach(e=>{e===this.triggerWrap||e.hasAttribute("data-wc-internal")||this.triggerWrap.insertBefore(e,this.menu)})}renderTrigger(){const e=this.collectTriggerChildren();if(e.length>0){this.defaultTrigger?.remove(),this.defaultTrigger=void 0;Array.from(this.triggerWrap.children).filter(e=>e!==this.menu&&e!==this.defaultTrigger).forEach(e=>e.remove()),e.forEach(e=>{e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",String(this.open)),e.classList.toggle("designbase-wc-dropdown__trigger--open",this.open),this.triggerWrap.insertBefore(e,this.menu||null)})}else{Array.from(this.triggerWrap.children).filter(e=>e!==this.menu&&e!==this.defaultTrigger).forEach(e=>e.remove()),this.defaultTrigger&&this.triggerSignature()===this.lastTriggerSignature||(this.defaultTrigger?.remove(),this.defaultTrigger=this.renderDefaultTrigger(),this.lastTriggerSignature=this.triggerSignature(),this.triggerWrap.insertBefore(this.defaultTrigger,this.menu||null)),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()),this.menu.replaceChildren();const i=this.menuItemIconSize();this.parsedItems.forEach((e,r)=>{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(r);const s=e.label||e.id,n=Boolean(e.disabled||this.disabled),a=this.focusedIndex===r,o=document.createElement("button");if(o.type="button",o.className=["designbase-wc-dropdown__item",n&&"designbase-wc-dropdown__item--disabled",a&&"designbase-wc-dropdown__item--focused"].filter(Boolean).join(" "),o.setAttribute("role","menuitem"),o.disabled=n,o.tabIndex=a?0:-1,o.dataset.index=String(r),e.icon){const r=t(e.icon,i);r.classList.add("designbase-wc-dropdown__item-icon"),o.append(r)}const d=document.createElement("span");d.className="designbase-wc-dropdown__item-label",d.textContent=s,o.append(d),o.addEventListener("click",t=>{t.stopPropagation(),this.selectItem(e)}),this.menu?.append(o)})}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){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};
@@ -0,0 +1,74 @@
1
+ type DbFooterSocialPlatform = 'youtube' | 'instagram' | 'x' | 'linkedin' | 'facebook' | 'email';
2
+ interface DbFooterLink {
3
+ id: string;
4
+ label: string;
5
+ href?: string;
6
+ external?: boolean;
7
+ /** 개인정보처리방침 등 강조 링크 */
8
+ emphasize?: boolean;
9
+ }
10
+ interface DbFooterLinkColumn {
11
+ id: string;
12
+ title: string;
13
+ items: DbFooterLink[];
14
+ }
15
+ interface DbFooterSocialLink {
16
+ id: string;
17
+ platform: DbFooterSocialPlatform;
18
+ href: string;
19
+ label?: string;
20
+ }
21
+ interface DbFooterCompanyInfo {
22
+ companyName?: string;
23
+ representative?: string;
24
+ businessNumber?: string;
25
+ mailOrderNumber?: string;
26
+ address?: string;
27
+ phone?: string;
28
+ customerCenter?: string;
29
+ email?: string;
30
+ hostingProvider?: string;
31
+ }
32
+ interface DbFooterFamilySite {
33
+ id: string;
34
+ label: string;
35
+ href: string;
36
+ }
37
+ declare class DbFooter extends HTMLElement {
38
+ static get observedAttributes(): string[];
39
+ connectedCallback(): void;
40
+ attributeChangedCallback(): void;
41
+ get columns(): DbFooterLinkColumn[];
42
+ set columns(value: DbFooterLinkColumn[] | string);
43
+ get legalLinks(): DbFooterLink[];
44
+ set legalLinks(value: DbFooterLink[] | string);
45
+ get socialLinks(): DbFooterSocialLink[];
46
+ set socialLinks(value: DbFooterSocialLink[] | string);
47
+ get companyInfo(): DbFooterCompanyInfo;
48
+ set companyInfo(value: DbFooterCompanyInfo | string);
49
+ get familySites(): DbFooterFamilySite[];
50
+ set familySites(value: DbFooterFamilySite[] | string);
51
+ private syncHostClasses;
52
+ private dispatchLinkClick;
53
+ private createLink;
54
+ private createSocialLink;
55
+ private createCompanyInfoRows;
56
+ private showLogo;
57
+ private createLogo;
58
+ private renderBrand;
59
+ private renderColumns;
60
+ private createLegalNav;
61
+ private renderLegalBar;
62
+ private renderCompanyInfo;
63
+ private createCopyright;
64
+ private renderMinimal;
65
+ private render;
66
+ }
67
+ declare global {
68
+ interface HTMLElementTagNameMap {
69
+ 'db-footer': DbFooter;
70
+ }
71
+ }
72
+
73
+ export { DbFooter };
74
+ export type { DbFooterCompanyInfo, DbFooterFamilySite, DbFooterLink, DbFooterLinkColumn, DbFooterSocialLink, DbFooterSocialPlatform };
@@ -0,0 +1 @@
1
+ import{createShareIcon as e}from"./db-share-icons.js";const t=["default","compact","minimal"],s=["s","m","l"],n={youtube:"youtube",instagram:"instagram",x:"x",linkedin:"linkedin",facebook:"facebook",email:"mail"};function parseJson(e,t){if(!e)return t;try{return JSON.parse(e)??t}catch{return t}}class DbFooter extends HTMLElement{static get observedAttributes(){return["columns","legal-links","social-links","company-info","family-sites","tagline","copyright","logo-type","variant","size","full-width","show-logo","show-social","family-site-label"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}get columns(){return parseJson(this.getAttribute("columns"),[])}set columns(e){this.setAttribute("columns","string"==typeof e?e:JSON.stringify(e))}get legalLinks(){return parseJson(this.getAttribute("legal-links"),[])}set legalLinks(e){this.setAttribute("legal-links","string"==typeof e?e:JSON.stringify(e))}get socialLinks(){return parseJson(this.getAttribute("social-links"),[])}set socialLinks(e){this.setAttribute("social-links","string"==typeof e?e:JSON.stringify(e))}get companyInfo(){return parseJson(this.getAttribute("company-info"),{})}set companyInfo(e){this.setAttribute("company-info","string"==typeof e?e:JSON.stringify(e))}get familySites(){return parseJson(this.getAttribute("family-sites"),[])}set familySites(e){this.setAttribute("family-sites","string"==typeof e?e:JSON.stringify(e))}syncHostClasses(){const e=this.getAttribute("size")||"m",n=this.getAttribute("variant")||"default",a=s.includes(e)?e:"m",i=t.includes(n)?n:"default";this.className=["designbase-wc-footer",`designbase-wc-footer--${a}`,`designbase-wc-footer--${i}`,this.hasAttribute("full-width")&&"designbase-wc-footer--full-width"].filter(Boolean).join(" ")}dispatchLinkClick(e,t){this.dispatchEvent(new CustomEvent("db-link-click",{bubbles:!0,composed:!0,detail:{link:e,source:t}}))}createLink(e,t,s){const n=document.createElement("a");return n.href=e.href||"#",n.className=[t,e.emphasize&&`${t}--emphasize`].filter(Boolean).join(" "),n.textContent=e.label,e.external&&(n.target="_blank",n.rel="noopener noreferrer"),n.addEventListener("click",t=>{t.preventDefault(),this.dispatchLinkClick(e,s)}),n}createSocialLink(t,s){const a=document.createElement("a");a.href=t.href,a.className="designbase-wc-footer__social-link",a.target="_blank",a.rel="noopener noreferrer",a.setAttribute("aria-label",t.label||t.platform);const i=n[t.platform]||"share-alt";return a.append(e(i,s)),a.addEventListener("click",e=>{e.preventDefault(),this.dispatchEvent(new CustomEvent("db-social-click",{bubbles:!0,composed:!0,detail:{link:t}}))}),a}createCompanyInfoRows(e){const t=[],s=[];e.companyName&&s.push(e.companyName),e.representative&&s.push(`대표: ${e.representative}`),e.businessNumber&&s.push(`사업자등록번호: ${e.businessNumber}`),s.length&&t.push(s.join(" | "));const n=[];e.address&&n.push(e.address),e.phone&&n.push(`대표전화: ${e.phone}`),e.customerCenter&&n.push(`고객센터: ${e.customerCenter}`),n.length&&t.push(n.join(" | "));const a=[];return e.email&&a.push(`이메일: ${e.email}`),e.mailOrderNumber&&a.push(`통신판매업신고: ${e.mailOrderNumber}`),e.hostingProvider&&a.push(`호스팅: ${e.hostingProvider}`),a.length&&t.push(a.join(" | ")),t}showLogo(){return!this.hasAttribute("show-logo")||"false"!==this.getAttribute("show-logo")}createLogo(){const e=document.createElement("div");e.className="designbase-wc-footer__logo";const t=document.createElement("db-logo");return t.setAttribute("type",this.getAttribute("logo-type")||"designbase"),t.setAttribute("size","s"),t.setAttribute("clickable",""),t.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),e.append(t),e}renderBrand(e,t={}){const{showTagline:s=!0}=t,n=document.createElement("div");n.className="designbase-wc-footer__brand",this.showLogo()&&n.append(this.createLogo());const a=this.getAttribute("tagline");if(s&&a){const e=document.createElement("p");e.className="designbase-wc-footer__tagline",e.textContent=a,n.append(e)}const i=this.socialLinks;if(i.length&&(!this.hasAttribute("show-social")||"false"!==this.getAttribute("show-social"))){const t=document.createElement("div");t.className="designbase-wc-footer__social",i.forEach(s=>t.append(this.createSocialLink(s,e))),n.append(t)}return n}renderColumns(e){if(!e.length)return null;const t=document.createElement("div");return t.className="designbase-wc-footer__columns",t.style.setProperty("--db-footer-columns",String(Math.min(e.length,4))),e.forEach(e=>{const s=document.createElement("div");s.className="designbase-wc-footer__column";const n=document.createElement("h3");n.className="designbase-wc-footer__column-title",n.textContent=e.title,s.append(n);const a=document.createElement("ul");a.className="designbase-wc-footer__column-list",e.items.forEach(e=>{const t=document.createElement("li");t.append(this.createLink(e,"designbase-wc-footer__column-link","column")),a.append(t)}),s.append(a),t.append(s)}),t}createLegalNav(e){const t=document.createElement("nav");t.className="designbase-wc-footer__legal-nav",t.setAttribute("aria-label","법적 고지");const s=document.createElement("ul");return s.className="designbase-wc-footer__legal-list",e.forEach((t,n)=>{const a=document.createElement("li");if(a.append(this.createLink(t,"designbase-wc-footer__legal-link","legal")),s.append(a),n<e.length-1){const e=document.createElement("span");e.className="designbase-wc-footer__legal-divider",e.setAttribute("aria-hidden","true"),e.textContent="|",a.append(e)}}),t.append(s),t}renderLegalBar(e,t){if(!e.length&&!t.length)return null;const s=document.createElement("div");if(s.className="designbase-wc-footer__legal-bar",e.length&&s.append(this.createLegalNav(e)),t.length){const e=document.createElement("div");e.className="designbase-wc-footer__family-site";const n=document.createElement("select");n.className="designbase-wc-footer__family-select",n.setAttribute("aria-label",this.getAttribute("family-site-label")||"패밀리 사이트");const a=document.createElement("option");a.value="",a.textContent=this.getAttribute("family-site-label")||"패밀리 사이트",a.disabled=!0,a.selected=!0,n.append(a),t.forEach(e=>{const t=document.createElement("option");t.value=e.href,t.textContent=e.label,t.dataset.id=e.id,n.append(t)}),n.addEventListener("change",()=>{const e=t.find(e=>e.href===n.value);e&&(n.selectedIndex=0,this.dispatchEvent(new CustomEvent("db-family-site-change",{bubbles:!0,composed:!0,detail:{site:e}})))}),e.append(n),s.append(e)}return s}renderCompanyInfo(e){const t=this.createCompanyInfoRows(e);if(!t.length)return null;const s=document.createElement("div");return s.className="designbase-wc-footer__company",t.forEach(e=>{const t=document.createElement("p");t.className="designbase-wc-footer__company-line",t.textContent=e,s.append(t)}),s}createCopyright(e){const t=document.createElement("div");t.className="designbase-wc-footer__bottom";const s=document.createElement("p");return s.className="designbase-wc-footer__copyright",s.textContent=e,t.append(s),t}renderMinimal(e,t,s){const n=document.createElement("div");n.className="designbase-wc-footer__minimal-bar";const a=document.createElement("div");if(a.className="designbase-wc-footer__minimal-start",this.showLogo()&&a.append(this.createLogo()),n.append(a),t.length){const e=document.createElement("div");e.className="designbase-wc-footer__minimal-legal",e.append(this.createLegalNav(t)),n.append(e)}e.append(n),e.append(this.createCopyright(s))}render(){this.syncHostClasses(),this.setAttribute("role","contentinfo");const e=this.getAttribute("variant")||"default",t=this.getAttribute("size")||"m",s="s"===t?18:"l"===t?22:20,n="default"===e?this.columns:[],a=this.legalLinks,i=this.companyInfo,o=this.familySites,r=this.getAttribute("copyright")||`© ${(new Date).getFullYear()} Designbase. All rights reserved.`;this.replaceChildren();const l=document.createElement("div");if(l.className=["designbase-wc-footer__container",this.hasAttribute("full-width")&&"designbase-wc-footer__container--full-width"].filter(Boolean).join(" "),"minimal"===e)return this.renderMinimal(l,a,r),void this.append(l);const c=document.createElement("div");c.className="designbase-wc-footer__top",c.append(this.renderBrand(s,{showTagline:"compact"!==e}));const d=this.renderColumns(n);d&&c.append(d),l.append(c);const m=this.renderLegalBar(a,o);m&&l.append(m);const u=this.renderCompanyInfo(i);u&&l.append(u),l.append(this.createCopyright(r)),this.append(l)}}customElements.get("db-footer")||customElements.define("db-footer",DbFooter);export{DbFooter};
@@ -0,0 +1,96 @@
1
+ type DbGanttAssignee = {
2
+ name: string;
3
+ initials?: string;
4
+ avatar?: string;
5
+ };
6
+ type DbGanttItemStatus = 'on-track' | 'at-risk' | 'delayed' | 'completed';
7
+ type DbGanttItem = {
8
+ id: string;
9
+ rowId: string;
10
+ title: string;
11
+ startDate: string;
12
+ endDate: string;
13
+ color?: string;
14
+ assignee?: DbGanttAssignee;
15
+ progress?: number;
16
+ status?: DbGanttItemStatus;
17
+ disabled?: boolean;
18
+ };
19
+ type DbGanttRow = {
20
+ id: string;
21
+ label: string;
22
+ groupId?: string;
23
+ };
24
+ type DbGanttGroup = {
25
+ id: string;
26
+ title: string;
27
+ color?: string;
28
+ };
29
+ declare class DbGantt extends HTMLElement {
30
+ private collapsedGroups;
31
+ private dragState;
32
+ private reorderState;
33
+ private reorderDropIndex;
34
+ private suppressRender;
35
+ private didDrag;
36
+ static get observedAttributes(): string[];
37
+ get groups(): DbGanttGroup[];
38
+ set groups(value: DbGanttGroup[] | string);
39
+ get rows(): DbGanttRow[];
40
+ set rows(value: DbGanttRow[] | string);
41
+ get items(): DbGanttItem[];
42
+ set items(value: DbGanttItem[] | string);
43
+ connectedCallback(): void;
44
+ disconnectedCallback(): void;
45
+ attributeChangedCallback(): void;
46
+ private parseJson;
47
+ private getBool;
48
+ private getNumber;
49
+ private getOption;
50
+ private getLocale;
51
+ private getWeekdays;
52
+ private getViewRange;
53
+ private getTodayDate;
54
+ private getDateColumns;
55
+ private getVisibleRows;
56
+ private getMonthSegments;
57
+ private getInitials;
58
+ private updateItem;
59
+ private emitItemsChange;
60
+ private applyBarGeometry;
61
+ private handlePointerMove;
62
+ private handlePointerUp;
63
+ private startBarDrag;
64
+ private canReorder;
65
+ private createDragHandle;
66
+ private getGroupIndex;
67
+ private getRowScope;
68
+ private getRowIndexInScope;
69
+ private getReorderTargets;
70
+ private startReorderDrag;
71
+ private updateReorderDropTarget;
72
+ private clearReorderIndicators;
73
+ private finishReorderDrag;
74
+ private emitStructureChange;
75
+ private reorderGroups;
76
+ private reorderRows;
77
+ private createGroupBadge;
78
+ private createGroupChevron;
79
+ private createAssignee;
80
+ private createStatusIcon;
81
+ private deriveSummaryColor;
82
+ private getGroupSummary;
83
+ private applyBarTone;
84
+ private createGroupSummaryBar;
85
+ private createBar;
86
+ private toggleGroup;
87
+ private render;
88
+ }
89
+ declare global {
90
+ interface HTMLElementTagNameMap {
91
+ 'db-gantt': DbGantt;
92
+ }
93
+ }
94
+
95
+ export { DbGantt };
96
+ export type { DbGanttAssignee, DbGanttGroup, DbGanttItem, DbGanttItemStatus, DbGanttRow };
@@ -0,0 +1 @@
1
+ import{createDbIcon as e}from"./db-icons.js";const t=["day","week"],a=["#86efac","#fde047","#93c5fd","#c4b5fd","#f9a8d4","#5eead4","#fdba74","#a5b4fc"],s=["일","월","화","수","목","금","토"],r=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];function parseDate(e){const[t,a,s]=e.split("-").map(Number);return new Date(t,a-1,s)}function toDateKey(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function addDays(e,t){const a=new Date(e);return a.setDate(a.getDate()+t),a}function daysBetween(e,t){const a=Date.UTC(e.getFullYear(),e.getMonth(),e.getDate()),s=Date.UTC(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((s-a)/864e5)}function clampDate(e,t,a){return e<t?new Date(t):e>a?new Date(a):e}class DbGantt extends HTMLElement{constructor(){super(...arguments),this.collapsedGroups=new Set,this.dragState=null,this.reorderState=null,this.reorderDropIndex=null,this.suppressRender=!1,this.didDrag=!1,this.handlePointerMove=e=>{if(this.reorderState&&e.pointerId===this.reorderState.pointerId)return void this.updateReorderDropTarget(e.clientY);if(!this.dragState||e.pointerId!==this.dragState.pointerId)return;const a=this.getOption("scale",t,"day"),s=this.getNumber("cell-width","week"===a?72:44),{start:r,end:n}=this.getViewRange(),i=Math.round((e.clientX-this.dragState.startX)/s);0!==i&&(this.didDrag=!0);let d=new Date(this.dragState.originalStart),o=new Date(this.dragState.originalEnd);if("move"===this.dragState.mode?(d=addDays(this.dragState.originalStart,i),o=addDays(this.dragState.originalEnd,i)):"resize-start"===this.dragState.mode?(d=addDays(this.dragState.originalStart,i),d>o&&(d=new Date(o))):(o=addDays(this.dragState.originalEnd,i),o<d&&(o=new Date(d))),d=clampDate(d,r,n),o=clampDate(o,r,n),d>o)return;const l=this.items.find(e=>e.id===this.dragState.itemId);l&&this.applyBarGeometry(this.dragState.barEl,{...l,startDate:toDateKey(d),endDate:toDateKey(o)},r,s)},this.handlePointerUp=e=>{if(this.reorderState&&e.pointerId===this.reorderState.pointerId)return void this.finishReorderDrag(e);if(!this.dragState||e.pointerId!==this.dragState.pointerId)return;const a=this.getOption("scale",t,"day"),s=this.getNumber("cell-width","week"===a?72:44),{start:r,end:n}=this.getViewRange(),i=Math.round((e.clientX-this.dragState.startX)/s);let d=new Date(this.dragState.originalStart),o=new Date(this.dragState.originalEnd);const l=this.dragState.mode,c=this.dragState.itemId;"move"===l?(d=addDays(this.dragState.originalStart,i),o=addDays(this.dragState.originalEnd,i)):"resize-start"===l?(d=addDays(this.dragState.originalStart,i),d>o&&(d=new Date(o))):(o=addDays(this.dragState.originalEnd,i),o<d&&(o=new Date(d))),d=clampDate(d,r,n),o=clampDate(o,r,n),this.dragState.barEl.releasePointerCapture(e.pointerId),this.dragState.barEl.classList.remove("designbase-wc-gantt__bar--dragging"),this.dragState=null;const g=this.items.find(e=>e.id===c);if(!g)return;const p=toDateKey(d),h=toDateKey(o);p===g.startDate&&h===g.endDate||(this.updateItem(c,{startDate:p,endDate:h},"move"===l?"move":"resize"),this.render())}}static get observedAttributes(){return["groups","rows","items","start-date","end-date","today","scale","cell-width","show-weekends","show-today","sidebar-label","full-width","disabled","draggable","reorderable","locale"]}get groups(){return this.parseJson("groups",[])}set groups(e){this.setAttribute("groups","string"==typeof e?e:JSON.stringify(e))}get rows(){return this.parseJson("rows",[])}set rows(e){this.setAttribute("rows","string"==typeof e?e:JSON.stringify(e))}get items(){return this.parseJson("items",[])}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.setAttribute("role","region"),this.setAttribute("aria-label","프로젝트 타임라인"),this.addEventListener("pointermove",this.handlePointerMove),this.addEventListener("pointerup",this.handlePointerUp),this.addEventListener("pointercancel",this.handlePointerUp),this.render()}disconnectedCallback(){this.removeEventListener("pointermove",this.handlePointerMove),this.removeEventListener("pointerup",this.handlePointerUp),this.removeEventListener("pointercancel",this.handlePointerUp)}attributeChangedCallback(){!this.isConnected||this.suppressRender||this.dragState||this.reorderState||this.render()}parseJson(e,t){try{return JSON.parse(this.getAttribute(e)||"null")??t}catch{return t}}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const a=this.getAttribute(e);return""===a||"true"===a}getNumber(e,t){const a=Number(this.getAttribute(e));return Number.isFinite(a)&&a>0?a:t}getOption(e,t,a){const s=this.getAttribute(e);return s&&t.includes(s)?s:a}getLocale(){return this.getAttribute("locale")||"ko-KR"}getWeekdays(){return this.getLocale().startsWith("ko")?s:r}getViewRange(){const e=this.getAttribute("start-date"),t=this.getAttribute("end-date");if(e&&t)return{start:parseDate(e),end:parseDate(t)};const a=this.items.flatMap(e=>[parseDate(e.startDate),parseDate(e.endDate)]);if(0===a.length){const e=new Date,t=new Date(e.getFullYear(),e.getMonth(),1);return{start:t,end:addDays(t,29)}}const s=new Date(Math.min(...a.map(e=>e.getTime()))),r=new Date(Math.max(...a.map(e=>e.getTime())));return{start:addDays(s,-2),end:addDays(r,2)}}getTodayDate(){const e=this.getAttribute("today");return e?parseDate(e):new Date}getDateColumns(e,t){const a=daysBetween(e,t)+1;return Array.from({length:a},(t,a)=>addDays(e,a))}getVisibleRows(){const e=this.groups,t=this.rows;if(0===e.length)return t.map(e=>({type:"row",row:e}));const a=[];for(const s of e)a.push({type:"group",group:s}),this.collapsedGroups.has(s.id)||t.filter(e=>e.groupId===s.id).forEach(e=>a.push({type:"row",row:e}));return t.filter(t=>!t.groupId||!e.some(e=>e.id===t.groupId)).forEach(e=>a.push({type:"row",row:e})),a}getMonthSegments(e){const t=[];let a="",s=0;for(const r of e){const e=`${r.getFullYear()}-${r.getMonth()}`;e!==a?(s>0&&t.push({label:a,span:s}),a=e,s=1):s+=1}return s>0&&t.push({label:a,span:s}),t.map(e=>{const[t,a]=e.label.split("-").map(Number);return{label:new Date(t,a,1).toLocaleDateString(this.getLocale(),{year:"numeric",month:"long"}),span:e.span}})}getInitials(e){return e.initials?e.initials:e.name.split(/\s+/).map(e=>e[0]).join("").slice(0,2).toUpperCase()}updateItem(e,t,a){const s=this.items.map(a=>a.id===e?{...a,...t}:a);this.emitItemsChange(s,a,e)}emitItemsChange(e,t,a){this.suppressRender=!0,this.items=e,this.suppressRender=!1;const s=e.find(e=>e.id===a);this.dispatchEvent(new CustomEvent("db-item-change",{detail:{item:s,items:e,action:t},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{groups:this.groups,rows:this.rows,items:e},bubbles:!0,composed:!0}))}applyBarGeometry(e,t,a,s){const r=parseDate(t.startDate),n=parseDate(t.endDate),i=daysBetween(a,r),d=daysBetween(r,n)+1;e.style.left=i*s+2+"px",e.style.width=`${Math.max(d*s-4,s-4)}px`}startBarDrag(e,t,a,s){!this.getBool("draggable",!0)||this.getBool("disabled")||t.disabled||(e.preventDefault(),e.stopPropagation(),this.didDrag=!1,s.setPointerCapture(e.pointerId),s.classList.add("designbase-wc-gantt__bar--dragging"),this.dragState={itemId:t.id,mode:a,pointerId:e.pointerId,startX:e.clientX,originalStart:parseDate(t.startDate),originalEnd:parseDate(t.endDate),barEl:s})}canReorder(){return this.getBool("reorderable",!0)&&!this.getBool("disabled")}createDragHandle(t,a,s){const r=document.createElement("span");return r.className="designbase-wc-gantt__drag-handle",r.setAttribute("role","button"),r.setAttribute("aria-label","group"===t?"그룹 순서 변경":"행 순서 변경"),r.append(e("grip-vertical",12)),this.canReorder()?(r.addEventListener("pointerdown",e=>{e.preventDefault(),e.stopPropagation(),this.startReorderDrag(e,t,a,s,r)}),r):r}getGroupIndex(e){return this.groups.findIndex(t=>t.id===e)}getRowScope(e){return this.rows.filter(t=>(t.groupId||"")===(e||""))}getRowIndexInScope(e,t){return this.getRowScope(t).findIndex(t=>t.id===e)}getReorderTargets(e,t){return Array.from(this.querySelectorAll("group"===e?".designbase-wc-gantt__label-cell--group":`.designbase-wc-gantt__label-cell--row[data-group-id="${t||""}"]`))}startReorderDrag(e,t,a,s,r){const n="group"===t?this.getGroupIndex(a):this.getRowIndexInScope(a,s);n<0||(r.setPointerCapture(e.pointerId),this.reorderState={kind:t,id:a,groupId:s,pointerId:e.pointerId,startY:e.clientY,fromIndex:n,captureEl:r},this.classList.add("designbase-wc-gantt--reordering"),this.updateReorderDropTarget(e.clientY))}updateReorderDropTarget(e){if(!this.reorderState)return;const t=this.getReorderTargets(this.reorderState.kind,this.reorderState.groupId);let a=null;t.forEach((t,s)=>{const r=t.getBoundingClientRect(),n=r.top+r.height/2,i=e>=r.top&&e<=r.bottom,d=e>n;t.classList.toggle("designbase-wc-gantt__label-cell--drag-over",i),t.classList.toggle("designbase-wc-gantt__label-cell--drag-over-before",i&&!d),t.classList.toggle("designbase-wc-gantt__label-cell--drag-over-after",i&&d),i&&(a=d?s+1:s)}),this.reorderDropIndex=a}clearReorderIndicators(){this.querySelectorAll(".designbase-wc-gantt__label-cell--drag-over").forEach(e=>{e.classList.remove("designbase-wc-gantt__label-cell--drag-over","designbase-wc-gantt__label-cell--drag-over-before","designbase-wc-gantt__label-cell--drag-over-after")})}finishReorderDrag(e){if(!this.reorderState)return;const{kind:t,id:a,groupId:s,fromIndex:r,captureEl:n}=this.reorderState;try{n.releasePointerCapture(this.reorderState.pointerId)}catch{}const i=this.reorderDropIndex;if(this.reorderState=null,this.reorderDropIndex=null,this.classList.remove("designbase-wc-gantt--reordering"),this.clearReorderIndicators(),null===i)return;const d=i>r?i-1:i;d<0||d===r||("group"===t?this.reorderGroups(r,d,a):this.reorderRows(r,d,a,s))}emitStructureChange(e,t,a,s){this.suppressRender=!0,this.groups=e,this.rows=t,this.suppressRender=!1,this.dispatchEvent(new CustomEvent(s,{detail:{...a,groups:e,rows:t},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{groups:e,rows:t,items:this.items},bubbles:!0,composed:!0})),this.render()}reorderGroups(e,t,a){const s=[...this.groups],[r]=s.splice(e,1);r&&(s.splice(t,0,r),this.emitStructureChange(s,this.rows,{groupId:a,fromIndex:e,toIndex:t},"db-group-reorder"))}reorderRows(e,t,a,s){const r=this.getRowScope(s),n=[...r],[i]=n.splice(e,1);if(!i)return;n.splice(t,0,i);const d=new Set(r.map(e=>e.id)),o=[];let l=!1;for(const e of this.rows)d.has(e.id)?l||(o.push(...n),l=!0):o.push(e);l||o.push(...n),this.emitStructureChange(this.groups,o,{rowId:a,groupId:s,fromIndex:e,toIndex:t},"db-row-reorder")}createGroupBadge(e){const t=document.createElement("db-badge");return t.className="designbase-wc-gantt__group-badge",t.setAttribute("badge-style","dot"),t.setAttribute("size","s"),t.setAttribute("variant","primary"),t.setAttribute("aria-hidden","true"),e&&t.style.setProperty("--db-gantt-badge-color",e),t}createGroupChevron(t){const a=document.createElement("span");return a.className=["designbase-wc-gantt__group-chevron",t?"designbase-wc-gantt__group-chevron--collapsed":""].filter(Boolean).join(" "),a.append(e("chevron-down",12)),a}createAssignee(e){const t=document.createElement("span");if(t.className="designbase-wc-gantt__assignee",t.title=e.name,e.avatar){const a=document.createElement("img");a.src=e.avatar,a.alt=e.name,t.appendChild(a)}else t.textContent=this.getInitials(e);return t}createStatusIcon(e){const t=document.createElement("span");return t.className=`designbase-wc-gantt__status designbase-wc-gantt__status--${e}`,t.setAttribute("aria-hidden","true"),t.textContent="completed"===e?"✓":"!",t}deriveSummaryColor(e,t){if(0===e.length)return t||a[0];const s=e.filter(e=>e.color);if(0===s.length)return t||a[0];return s.reduce((e,t)=>{const a=daysBetween(parseDate(e.startDate),parseDate(e.endDate));return daysBetween(parseDate(t.startDate),parseDate(t.endDate))>a?t:e}).color||t||a[0]}getGroupSummary(e,t){const a=this.rows.filter(t=>t.groupId===e),s=this.items.filter(e=>a.some(t=>t.id===e.rowId));if(0===s.length)return null;const r=s.map(e=>parseDate(e.startDate).getTime()),n=s.map(e=>parseDate(e.endDate).getTime()),i=s.map(e=>e.progress).filter(e=>"number"==typeof e);return{startDate:toDateKey(new Date(Math.min(...r))),endDate:toDateKey(new Date(Math.max(...n))),color:this.deriveSummaryColor(s,t),progress:i.length>0?i.reduce((e,t)=>e+t,0)/i.length:0,count:s.length}}applyBarTone(e,t){const a=function deriveBarTone(e){return{base:`color-mix(in srgb, ${e} 42%, white)`,progress:`color-mix(in srgb, ${e} 58%, white)`}}(t);e.style.setProperty("--db-gantt-bar-color",t),e.style.setProperty("--db-gantt-bar-bg",a.base),e.style.setProperty("--db-gantt-bar-progress-bg",a.progress)}createGroupSummaryBar(e,t,a,s){const r=clampDate(parseDate(e.startDate),t,a),n=clampDate(parseDate(e.endDate),t,a);if(n<t||r>a)return null;const i=daysBetween(t,r),d=daysBetween(r,n)+1,o=Math.min(100,Math.max(0,e.progress)),l=document.createElement("div");if(l.className="designbase-wc-gantt__group-summary",l.setAttribute("aria-hidden","true"),l.title=`${e.count}개 태스크`,this.applyBarTone(l,e.color),l.style.left=i*s+2+"px",l.style.width=`${Math.max(d*s-4,s-4)}px`,o>0){const e=document.createElement("span");e.className="designbase-wc-gantt__group-summary-progress",e.style.width=`${o}%`,l.appendChild(e)}return l}createBar(e,t,s,r){const n=e.color||a[r%a.length],i=document.createElement("div");i.className="designbase-wc-gantt__bar",i.setAttribute("role","button"),i.setAttribute("tabindex",e.disabled?"-1":"0"),i.setAttribute("aria-label",`${e.title}, ${e.startDate} – ${e.endDate}`),this.applyBarTone(i,n),e.disabled&&i.classList.add("designbase-wc-gantt__bar--disabled"),this.applyBarGeometry(i,e,t,s);const d="number"==typeof e.progress?Math.min(100,Math.max(0,e.progress)):0;if(d>0){const e=document.createElement("span");e.className="designbase-wc-gantt__bar-progress",e.style.width=`${d}%`,i.appendChild(e)}const o=document.createElement("div");o.className="designbase-wc-gantt__bar-body","delayed"!==e.status&&"at-risk"!==e.status||o.appendChild(this.createStatusIcon(e.status));const l=document.createElement("span");l.className="designbase-wc-gantt__bar-label",l.textContent=e.title,o.appendChild(l),e.assignee&&o.appendChild(this.createAssignee(e.assignee));const c=document.createElement("span");c.className="designbase-wc-gantt__bar-handle designbase-wc-gantt__bar-handle--start",c.setAttribute("aria-hidden","true");const g=document.createElement("span");return g.className="designbase-wc-gantt__bar-handle designbase-wc-gantt__bar-handle--end",g.setAttribute("aria-hidden","true"),i.append(c,o,g),e.disabled||!this.getBool("draggable",!0)||this.getBool("disabled")||(c.addEventListener("pointerdown",t=>this.startBarDrag(t,e,"resize-start",i)),g.addEventListener("pointerdown",t=>this.startBarDrag(t,e,"resize-end",i)),o.addEventListener("pointerdown",t=>{t.target.closest(".designbase-wc-gantt__bar-handle")||this.startBarDrag(t,e,"move",i)})),i.addEventListener("click",t=>{this.dragState||this.didDrag?this.didDrag=!1:(t.stopPropagation(),this.dispatchEvent(new CustomEvent("db-item-click",{detail:{item:e},bubbles:!0,composed:!0})))}),i}toggleGroup(e){this.collapsedGroups.has(e)?this.collapsedGroups.delete(e):this.collapsedGroups.add(e),this.dispatchEvent(new CustomEvent("db-group-toggle",{detail:{groupId:e,collapsed:this.collapsedGroups.has(e)},bubbles:!0,composed:!0})),this.render()}render(){const e=this.items,s=this.getOption("scale",t,"day"),r=this.getNumber("cell-width","week"===s?72:44),n=this.getBool("show-weekends",!0),i=this.getBool("show-today",!0),d=this.getAttribute("sidebar-label")||"할 일",o=this.getBool("disabled"),l=this.getBool("full-width",!0),c=this.getWeekdays(),{start:g,end:p}=this.getViewRange(),h=this.getDateColumns(g,p),u=toDateKey(this.getTodayDate()),m=h.findIndex(e=>toDateKey(e)===u),b=this.getVisibleRows(),w=h.length*r,D=document.createElement("div");D.className=["designbase-wc-gantt",l?"designbase-wc-gantt--full-width":"",o?"designbase-wc-gantt--disabled":"",this.getBool("draggable",!0)?"designbase-wc-gantt--draggable":""].filter(Boolean).join(" ");const y=document.createElement("div");y.className="designbase-wc-gantt__viewport";const _=document.createElement("div");_.className="designbase-wc-gantt__grid",_.style.setProperty("--db-gantt-chart-width",`${w}px`),_.style.setProperty("--db-gantt-cell-width",`${r}px`);const f=document.createElement("div");f.className="designbase-wc-gantt__corner",f.textContent=d,_.appendChild(f);const v=document.createElement("div");v.className="designbase-wc-gantt__date-header";const E=document.createElement("div");E.className="designbase-wc-gantt__month-row";for(const e of this.getMonthSegments(h)){const t=document.createElement("div");t.className="designbase-wc-gantt__month-cell",t.style.width=e.span*r+"px",t.textContent=e.label,E.appendChild(t)}v.appendChild(E);const S=document.createElement("div");S.className="designbase-wc-gantt__day-row";for(const e of h){const t=toDateKey(e)===u,a=0===e.getDay()||6===e.getDay(),s=document.createElement("div");s.className=["designbase-wc-gantt__day-cell",t&&i?"designbase-wc-gantt__day-cell--today":"",a&&n?"designbase-wc-gantt__day-cell--weekend":""].filter(Boolean).join(" "),s.style.width=`${r}px`;const d=document.createElement("span");d.className="designbase-wc-gantt__day-num",d.textContent=String(e.getDate());const o=document.createElement("span");o.className="designbase-wc-gantt__day-name",o.textContent=c[e.getDay()],s.append(d,o),S.appendChild(s)}v.appendChild(S),_.appendChild(v);const C=new Map;e.forEach((e,t)=>{const s=C.get(e.rowId)||[];s.push({...e,color:e.color||a[t%a.length]}),C.set(e.rowId,s)});let I=0;for(const e of b){if("group"===e.type){const{group:t}=e,a=this.collapsedGroups.has(t.id),s=document.createElement("button");s.type="button",s.className="designbase-wc-gantt__label-cell designbase-wc-gantt__label-cell--group",s.setAttribute("aria-expanded",String(!a)),s.dataset.groupId=t.id;const i=document.createElement("span");i.className="designbase-wc-gantt__group-title",i.textContent=t.title,s.append(this.createDragHandle("group",t.id),this.createGroupChevron(a),this.createGroupBadge(t.color),i),s.addEventListener("click",e=>{e.target.closest(".designbase-wc-gantt__drag-handle")||this.toggleGroup(t.id)}),_.appendChild(s);const d=document.createElement("div");if(d.className="designbase-wc-gantt__track-cell designbase-wc-gantt__track-cell--group",a){const e=this.getGroupSummary(t.id,t.color);if(e){const t=document.createElement("div");t.className="designbase-wc-gantt__grid-bg",h.forEach(e=>{const a=document.createElement("div"),s=0===e.getDay()||6===e.getDay();a.className=["designbase-wc-gantt__grid-cell",s&&n?"designbase-wc-gantt__grid-cell--weekend":""].filter(Boolean).join(" "),a.style.width=`${r}px`,t.appendChild(a)}),d.appendChild(t);const a=document.createElement("div");a.className="designbase-wc-gantt__group-summary-wrap";const s=this.createGroupSummaryBar(e,g,p,r);s&&a.appendChild(s),d.appendChild(a)}}_.appendChild(d);continue}const{row:t}=e,a=document.createElement("button");a.type="button",a.className="designbase-wc-gantt__label-cell designbase-wc-gantt__label-cell--row",a.dataset.groupId=t.groupId||"",a.dataset.rowId=t.id;const s=document.createElement("span");s.className="designbase-wc-gantt__row-title",s.textContent=t.label,a.append(this.createDragHandle("row",t.id,t.groupId),s),a.addEventListener("click",e=>{e.target.closest(".designbase-wc-gantt__drag-handle")||this.dispatchEvent(new CustomEvent("db-row-click",{detail:{row:t},bubbles:!0,composed:!0}))}),_.appendChild(a);const i=document.createElement("div");i.className="designbase-wc-gantt__track-cell";const d=document.createElement("div");d.className="designbase-wc-gantt__grid-bg",h.forEach(e=>{const t=document.createElement("div"),a=0===e.getDay()||6===e.getDay();t.className=["designbase-wc-gantt__grid-cell",a&&n?"designbase-wc-gantt__grid-cell--weekend":""].filter(Boolean).join(" "),t.style.width=`${r}px`,d.appendChild(t)}),i.appendChild(d);const o=document.createElement("div");o.className="designbase-wc-gantt__bars",(C.get(t.id)||[]).forEach(e=>{const t=clampDate(parseDate(e.startDate),g,p),a=clampDate(parseDate(e.endDate),g,p);a<g||t>p||o.appendChild(this.createBar({...e,startDate:toDateKey(t),endDate:toDateKey(a)},g,r,I++))}),i.appendChild(o),_.appendChild(i)}if(y.appendChild(_),i&&m>=0){const e=document.createElement("div");e.className="designbase-wc-gantt__today-line",e.style.left=`calc(var(--db-gantt-label-width) + ${m*r+r/2}px)`,_.appendChild(e)}D.appendChild(y),this.replaceChildren(D)}}customElements.get("db-gantt")||customElements.define("db-gantt",DbGantt);export{DbGantt};
@@ -0,0 +1,93 @@
1
+ /**
2
+ * db-grid-background — 캔버스 기반 그리드 배경.
3
+ *
4
+ * 패턴은 항상 중앙을 기준으로 대칭 배치되며(가장자리 라인 없음),
5
+ * 단독 배경으로도, 다른 배경 위 데코 레이어(overlay)로도 쓸 수 있다.
6
+ * interactive/animate 로 마우스 인터랙션과 앰비언트 애니메이션을 켤 수 있다.
7
+ *
8
+ * @example
9
+ * <db-grid-background type="lines" size="32" fade="all"
10
+ * interactive animate height="240"></db-grid-background>
11
+ */
12
+ declare class DbGridBackground extends HTMLElement {
13
+ private canvas?;
14
+ private ctx?;
15
+ private hlCanvas?;
16
+ private maskCanvas?;
17
+ private ro?;
18
+ private rafId?;
19
+ private lastTime;
20
+ private lastPointerMove;
21
+ private bandAngle;
22
+ private pointer;
23
+ private cssW;
24
+ private cssH;
25
+ private colorProbe?;
26
+ private themeObserver?;
27
+ private themeMedia?;
28
+ private tracePulses;
29
+ private traceSpawnAccumulator;
30
+ private onThemeMediaChange;
31
+ private onPointerMove;
32
+ static get observedAttributes(): string[];
33
+ connectedCallback(): void;
34
+ disconnectedCallback(): void;
35
+ attributeChangedCallback(): void;
36
+ private getBool;
37
+ private getNumber;
38
+ private getSizeStyle;
39
+ private getColorProbe;
40
+ private resolveCssColor;
41
+ private isDarkContext;
42
+ private resolveThemeColor;
43
+ private effectiveOpacity;
44
+ private effectiveColor;
45
+ private effectiveInterColor;
46
+ private traceDrawColor;
47
+ private traceDrawOpacity;
48
+ private parseColorRgb;
49
+ private crossArm;
50
+ private interactionMode;
51
+ private animationStyle;
52
+ private traceDirection;
53
+ private linesLayout;
54
+ private crossStyle;
55
+ private parseGuideEdges;
56
+ private guideFraction;
57
+ private isGridLines;
58
+ private isTraceableLines;
59
+ private get cfg();
60
+ private ensureCanvas;
61
+ private applyHostStyles;
62
+ private startObserving;
63
+ private observeDocumentTheme;
64
+ private bindPointer;
65
+ private handlePointerMove;
66
+ private measure;
67
+ /** 중앙을 기준으로 대칭 배치되며 (0, extent) 내부 좌표만 반환 → 가장자리 라인 없음 */
68
+ private axis;
69
+ private scheduleDraw;
70
+ private ensureLoop;
71
+ private drawFrame;
72
+ private easeInOutCubic;
73
+ private traceSegmentLength;
74
+ private pulseHead;
75
+ private updateTracePulses;
76
+ private traceLinePositions;
77
+ private spawnTracePulse;
78
+ private drawTracePulseSegment;
79
+ private drawTraceHighlight;
80
+ private drawPattern;
81
+ private drawGridLines;
82
+ private drawFrameGuides;
83
+ private drawCenterGuides;
84
+ private buildEnergyMask;
85
+ private applyFade;
86
+ }
87
+ declare global {
88
+ interface HTMLElementTagNameMap {
89
+ 'db-grid-background': DbGridBackground;
90
+ }
91
+ }
92
+
93
+ export { DbGridBackground };