@designbasekorea/ui-wc 0.5.3 → 0.5.6

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 (156) hide show
  1. package/dist/chunks/lottie-e273b936.js +17032 -0
  2. package/dist/esm/components/animation-background/canvas-controller.js +121 -1
  3. package/dist/esm/components/animation-background/controls.js +180 -1
  4. package/dist/esm/components/animation-background/graphite-controller.js +196 -1
  5. package/dist/esm/components/animation-background/graphite-presets.js +42 -1
  6. package/dist/esm/components/animation-background/graphite-shader.js +111 -1
  7. package/dist/esm/components/animation-background/layers.js +369 -1
  8. package/dist/esm/components/animation-background/lumina-presets.js +53 -1
  9. package/dist/esm/components/animation-background/lumina-shaders.js +181 -1
  10. package/dist/esm/components/animation-background/lumina-utils.js +60 -1
  11. package/dist/esm/components/animation-background/particle-defaults.js +36 -1
  12. package/dist/esm/components/animation-background/renderers.js +167 -1
  13. package/dist/esm/components/animation-background/shader-controller.js +154 -1
  14. package/dist/esm/components/color-picker-utils.js +134 -1
  15. package/dist/esm/components/date-picker-utils.js +140 -1
  16. package/dist/esm/components/db-accordion.js +304 -1
  17. package/dist/esm/components/db-ad-banner.js +455 -1
  18. package/dist/esm/components/db-alert.js +149 -1
  19. package/dist/esm/components/db-animation-background.js +486 -1
  20. package/dist/esm/components/db-animation-text.js +601 -1
  21. package/dist/esm/components/db-app-badge.js +88 -1
  22. package/dist/esm/components/db-audio-player.js +752 -1
  23. package/dist/esm/components/db-avatar.js +188 -1
  24. package/dist/esm/components/db-backdrop.js +139 -1
  25. package/dist/esm/components/db-badge.js +91 -1
  26. package/dist/esm/components/db-banner.js +188 -1
  27. package/dist/esm/components/db-bottom-navigation.js +146 -1
  28. package/dist/esm/components/db-bottom-sheet.js +481 -1
  29. package/dist/esm/components/db-breadcrumbs.js +329 -1
  30. package/dist/esm/components/db-button.js +316 -1
  31. package/dist/esm/components/db-calendar.js +675 -1
  32. package/dist/esm/components/db-card.js +265 -1
  33. package/dist/esm/components/db-carousel.js +264 -1
  34. package/dist/esm/components/db-checkbox.js +202 -1
  35. package/dist/esm/components/db-chip.js +104 -1
  36. package/dist/esm/components/db-code-block.js +304 -1
  37. package/dist/esm/components/db-color-picker.js +746 -1
  38. package/dist/esm/components/db-confirm.js +191 -1
  39. package/dist/esm/components/db-container.js +39 -1
  40. package/dist/esm/components/db-context-menu.js +265 -1
  41. package/dist/esm/components/db-countdown.js +146 -1
  42. package/dist/esm/components/db-cursor-follower.js +173 -1
  43. package/dist/esm/components/db-date-picker.js +837 -1
  44. package/dist/esm/components/db-divider.js +66 -1
  45. package/dist/esm/components/db-drawer.js +245 -1
  46. package/dist/esm/components/db-dropdown.js +493 -1
  47. package/dist/esm/components/db-dropzone.js +266 -1
  48. package/dist/esm/components/db-empty-state.js +97 -1
  49. package/dist/esm/components/db-file-uploader.js +256 -1
  50. package/dist/esm/components/db-floating-action-button.js +139 -1
  51. package/dist/esm/components/db-footer.js +385 -1
  52. package/dist/esm/components/db-form.js +566 -1
  53. package/dist/esm/components/db-gantt.js +882 -1
  54. package/dist/esm/components/db-gradient.js +133 -1
  55. package/dist/esm/components/db-grid-background.js +909 -1
  56. package/dist/esm/components/db-grid.js +73 -1
  57. package/dist/esm/components/db-icons.js +82 -1
  58. package/dist/esm/components/db-image-list.js +214 -1
  59. package/dist/esm/components/db-image-placeholder.js +96 -1
  60. package/dist/esm/components/db-image.js +289 -1
  61. package/dist/esm/components/db-indicator.js +517 -1
  62. package/dist/esm/components/db-input.js +420 -1
  63. package/dist/esm/components/db-kanban.js +538 -1
  64. package/dist/esm/components/db-label.js +66 -1
  65. package/dist/esm/components/db-lightbox.js +372 -1
  66. package/dist/esm/components/db-list.js +340 -1
  67. package/dist/esm/components/db-logo-svg.js +72 -1
  68. package/dist/esm/components/db-logo.js +106 -1
  69. package/dist/esm/components/db-lottie.js +109 -1
  70. package/dist/esm/components/db-markdown-editor.js +458 -1
  71. package/dist/esm/components/db-marquee.js +402 -1
  72. package/dist/esm/components/db-masonry.js +94 -1
  73. package/dist/esm/components/db-menu-item.js +211 -1
  74. package/dist/esm/components/db-modal.js +522 -1
  75. package/dist/esm/components/db-navbar.js +680 -1
  76. package/dist/esm/components/db-onboarding-modal.js +322 -1
  77. package/dist/esm/components/db-page-header.js +312 -1
  78. package/dist/esm/components/db-pagination.js +271 -1
  79. package/dist/esm/components/db-popover.js +580 -1
  80. package/dist/esm/components/db-progress-step.js +166 -1
  81. package/dist/esm/components/db-progress.js +171 -1
  82. package/dist/esm/components/db-progressbar.js +72 -1
  83. package/dist/esm/components/db-radio.js +172 -1
  84. package/dist/esm/components/db-random-gradient.js +121 -1
  85. package/dist/esm/components/db-range-slider.js +811 -1
  86. package/dist/esm/components/db-rating.js +325 -1
  87. package/dist/esm/components/db-reorder.js +286 -1
  88. package/dist/esm/components/db-resizable-panels.js +282 -1
  89. package/dist/esm/components/db-scroll-area.js +126 -1
  90. package/dist/esm/components/db-search-bar.js +668 -1
  91. package/dist/esm/components/db-section-app-download.js +101 -1
  92. package/dist/esm/components/db-section-contact.js +102 -1
  93. package/dist/esm/components/db-section-cta.js +150 -1
  94. package/dist/esm/components/db-section-faq.js +120 -1
  95. package/dist/esm/components/db-section-feature-grid.js +137 -1
  96. package/dist/esm/components/db-section-feature.js +179 -1
  97. package/dist/esm/components/db-section-hero.js +243 -1
  98. package/dist/esm/components/db-section-logo-cloud.js +138 -1
  99. package/dist/esm/components/db-section-pricing.js +166 -1
  100. package/dist/esm/components/db-section-stats.js +129 -1
  101. package/dist/esm/components/db-section-testimonials.js +252 -1
  102. package/dist/esm/components/db-section.js +385 -1
  103. package/dist/esm/components/db-segment-control.js +231 -1
  104. package/dist/esm/components/db-select.js +571 -1
  105. package/dist/esm/components/db-share-icons.js +40 -1
  106. package/dist/esm/components/db-share.js +489 -1
  107. package/dist/esm/components/db-sidebar.js +1068 -1
  108. package/dist/esm/components/db-skeleton.js +94 -1
  109. package/dist/esm/components/db-spinner.js +102 -1
  110. package/dist/esm/components/db-split-view.js +297 -1
  111. package/dist/esm/components/db-stack.js +46 -1
  112. package/dist/esm/components/db-stat.js +218 -1
  113. package/dist/esm/components/db-stepper.js +398 -1
  114. package/dist/esm/components/db-table.js +412 -1
  115. package/dist/esm/components/db-tabs.js +335 -1
  116. package/dist/esm/components/db-testimonial.js +162 -1
  117. package/dist/esm/components/db-textarea.js +233 -1
  118. package/dist/esm/components/db-time-picker.js +523 -1
  119. package/dist/esm/components/db-timeline.js +174 -1
  120. package/dist/esm/components/db-toast.js +158 -1
  121. package/dist/esm/components/db-toggle.js +162 -1
  122. package/dist/esm/components/db-toolbar.js +94 -1
  123. package/dist/esm/components/db-tooltip.js +440 -1
  124. package/dist/esm/components/db-top-banner.js +121 -1
  125. package/dist/esm/components/db-tutorial.js +324 -1
  126. package/dist/esm/components/db-video-player.js +503 -1
  127. package/dist/esm/components/db-youtube-player.js +194 -1
  128. package/dist/esm/components/highlight-code.js +65 -1
  129. package/dist/esm/components/input-validation.js +50 -1
  130. package/dist/esm/components/marketing-block-host-utils.js +9 -1
  131. package/dist/esm/components/number-scrub.js +117 -1
  132. package/dist/esm/components/random-gradient-palettes.js +67 -1
  133. package/dist/esm/components/section-block-header-utils.js +48 -1
  134. package/dist/esm/helpers/confirm.js +52 -1
  135. package/dist/esm/helpers/toast.js +73 -1
  136. package/dist/esm/index.js +111 -1
  137. package/dist/esm/node_modules/prismjs/components/prism-bash.js +235 -1
  138. package/dist/esm/node_modules/prismjs/components/prism-clike.js +31 -1
  139. package/dist/esm/node_modules/prismjs/components/prism-css.js +64 -1
  140. package/dist/esm/node_modules/prismjs/components/prism-javascript.js +172 -1
  141. package/dist/esm/node_modules/prismjs/components/prism-json.js +27 -1
  142. package/dist/esm/node_modules/prismjs/components/prism-jsx.js +143 -1
  143. package/dist/esm/node_modules/prismjs/components/prism-markup.js +186 -1
  144. package/dist/esm/node_modules/prismjs/components/prism-scss.js +81 -1
  145. package/dist/esm/node_modules/prismjs/components/prism-tsx.js +15 -1
  146. package/dist/esm/node_modules/prismjs/components/prism-typescript.js +60 -1
  147. package/dist/index.cjs +55414 -1
  148. package/dist/index.css +1 -1
  149. package/dist/index.esm.js +38284 -1
  150. package/dist/react/chunks/lottie-72a4c6d4.js +17032 -0
  151. package/dist/react/index.cjs +56503 -1
  152. package/dist/react/index.d.ts +1 -1
  153. package/dist/react/index.esm.js +39373 -1
  154. package/package.json +1 -1
  155. package/dist/chunks/lottie-2d1f6278.js +0 -1
  156. package/dist/react/chunks/lottie-14e7addb.js +0 -1
@@ -1 +1,538 @@
1
- import{createDbIcon as e}from"./db-icons.js";const t=["s","m","l"],a=["low","medium","high","urgent"],n={low:"낮음",medium:"보통",high:"높음",urgent:"긴급"};class DbKanban extends HTMLElement{constructor(){super(...arguments),this.dragState=null,this.dropTarget=null,this.handleBoardDragOver=e=>{if(!this.dragState)return;const t=e.target;t instanceof Element&&(t.closest(".designbase-wc-kanban__card")||t.closest(".designbase-wc-kanban__column-body"))||(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"))},this.handleBoardDrop=e=>{if(!this.dragState)return;const t=e.target;t instanceof Element&&(t.closest(".designbase-wc-kanban__card")||t.closest(".designbase-wc-kanban__column-body"))||(e.preventDefault(),this.commitDrop())}}static get observedAttributes(){return["columns","size","disabled","draggable","show-column-count","show-add-card","allow-cross-column","full-width","empty-column-text"]}get columns(){try{const e=JSON.parse(this.getAttribute("columns")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set columns(e){this.setAttribute("columns","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.setAttribute("role","region"),this.setAttribute("aria-label","칸반 보드"),this.addEventListener("dragover",this.handleBoardDragOver),this.addEventListener("drop",this.handleBoardDrop),this.render()}disconnectedCallback(){this.removeEventListener("dragover",this.handleBoardDragOver),this.removeEventListener("drop",this.handleBoardDrop)}attributeChangedCallback(){this.isConnected&&this.render()}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const a=this.getAttribute(e);return""===a||"true"===a}getOption(e,t,a){const n=this.getAttribute(e);return n&&t.includes(n)?n:a}emitChange(e){this.columns=e,this.dispatchEvent(new CustomEvent("db-change",{detail:{columns:e},bubbles:!0,composed:!0}))}emitCardMove(e,t){this.columns=e,this.dispatchEvent(new CustomEvent("db-card-move",{detail:{...t,columns:e},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{columns:e},bubbles:!0,composed:!0}))}findCardLocation(e){for(const t of this.columns){const a=t.cards.findIndex(t=>t.id===e);if(a>=0)return{columnId:t.id,index:a}}return null}getAdjustedDropIndex(e,t){if(!this.dragState)return-1;const{columnId:a,cardIndex:n}=this.dragState;return a===e&&t>n?t-1:t}isValidDropTarget(e=this.dropTarget){if(!this.dragState||!e)return!1;const t=this.getAdjustedDropIndex(e.columnId,e.index);return!(t<0)&&(this.dragState.columnId!==e.columnId||t!==this.dragState.cardIndex)}moveCard(e,t,a){const n=this.findCardLocation(e);if(!n)return;const s=this.columns.map(e=>({...e,cards:[...e.cards]})),d=s.find(e=>e.id===n.columnId),r=s.find(e=>e.id===t);if(!d||!r)return;const[i]=d.cards.splice(n.index,1);if(!i)return;const o=this.getAdjustedDropIndex(t,a);r.cards.splice(Math.max(0,o),0,i),this.emitCardMove(s,{cardId:e,fromColumnId:n.columnId,toColumnId:t,fromIndex:n.index,toIndex:Math.max(0,o)})}setDropTarget(e){const t=e&&this.isValidDropTarget(e)?e:null;(this.dropTarget?`${this.dropTarget.columnId}:${this.dropTarget.index}`:"")!==(t?`${t.columnId}:${t.index}`:"")&&(this.dropTarget=t,this.updateDragClasses())}resetDragState(){this.dragState=null,this.dropTarget=null,this.classList.remove("designbase-wc-kanban--dragging"),this.updateDragClasses()}updateDragClasses(){const e=!!this.dragState;this.classList.toggle("designbase-wc-kanban--dragging",e),this.querySelectorAll(".designbase-wc-kanban__card").forEach(t=>{const a=t.dataset.cardId||"",n=e&&this.dragState?.cardId===a;t.classList.toggle("designbase-wc-kanban__card--dragged",n)}),this.querySelectorAll(".designbase-wc-kanban__column-body").forEach(e=>{const t=e.dataset.columnId||"",a=!!this.dropTarget&&this.dropTarget.columnId===t;e.classList.toggle("designbase-wc-kanban__column-body--drag-over",a)}),this.querySelectorAll(".designbase-wc-kanban__card").forEach(e=>{const t=e.dataset.columnId||"",a=Number(e.dataset.cardIndex||-1),n=!!this.dropTarget&&this.dropTarget.columnId===t&&this.dropTarget.index===a,s=this.columns.find(e=>e.id===t),d=!!this.dropTarget&&this.dropTarget.columnId===t&&s&&this.dropTarget.index===s.cards.length&&a===s.cards.length-1;e.classList.toggle("designbase-wc-kanban__card--drop-before",n),e.classList.toggle("designbase-wc-kanban__card--drop-after",d)})}getDropIndexFromPointer(e,t,a){const n=t.getBoundingClientRect();return e.clientY-n.top<n.height/2?a:a+1}getDropIndexFromColumnPointer(e,t){const a=Array.from(this.querySelectorAll(`.designbase-wc-kanban__column-body[data-column-id="${t}"] > .designbase-wc-kanban__card`));if(0===a.length)return 0;for(let t=0;t<a.length;t+=1){const n=a[t].getBoundingClientRect();if(e.clientY<n.top+n.height/2)return t}return a.length}commitDrop(){if(!this.dragState||!this.dropTarget||!this.isValidDropTarget())return void this.resetDragState();const{cardId:e}=this.dragState,{columnId:t,index:a}=this.dropTarget;this.resetDragState(),this.moveCard(e,t,a),this.render()}formatDueDate(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString("ko-KR",{month:"short",day:"numeric"})}getInitials(e){return e.initials?e.initials:e.name.split(/\s+/).map(e=>e.charAt(0)).join("").slice(0,2).toUpperCase()}createTag(e){const t=document.createElement("span");return t.className=["designbase-wc-kanban__tag",e.variant&&`designbase-wc-kanban__tag--${e.variant}`].filter(Boolean).join(" "),t.textContent=e.label,t}createPriorityBadge(e){const t=document.createElement("span");return t.className=`designbase-wc-kanban__priority designbase-wc-kanban__priority--${e}`,t.textContent=n[e],t.setAttribute("aria-label",`우선순위 ${n[e]}`),t}createAssignee(e){const t=document.createElement("div");if(t.className="designbase-wc-kanban__assignee",t.title=e.name,e.avatar){const a=document.createElement("img");a.className="designbase-wc-kanban__assignee-avatar",a.src=e.avatar,a.alt=e.name,t.append(a)}else{const a=document.createElement("span");a.className="designbase-wc-kanban__assignee-initials",a.textContent=this.getInitials(e),t.append(a)}const a=document.createElement("span");return a.className="designbase-wc-kanban__assignee-name",a.textContent=e.name,t.append(a),t}bindCardDrag(e,t,a,n,s,d){e.draggable=s&&!d&&!t.disabled,e.addEventListener("dragstart",e=>{!s||d||t.disabled||(this.dragState={cardId:t.id,columnId:a,cardIndex:n},this.dropTarget=null,e.dataTransfer&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",t.id)),this.classList.add("designbase-wc-kanban--dragging"),this.updateDragClasses())}),e.addEventListener("dragover",t=>{if(!this.dragState)return;t.preventDefault(),t.stopPropagation(),t.dataTransfer&&(t.dataTransfer.dropEffect="move");if(!this.getBool("allow-cross-column",!0)&&this.dragState.columnId!==a)return;const s=this.getDropIndexFromPointer(t,e,n);this.setDropTarget({columnId:a,index:s})}),e.addEventListener("dragleave",t=>{const a=e.getBoundingClientRect(),n=t.clientX-a.left,s=t.clientY-a.top;(n<0||n>a.width||s<0||s>a.height)&&this.setDropTarget(null)}),e.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.commitDrop()}),e.addEventListener("dragend",()=>{this.resetDragState(),this.render()})}createCard(t,n,s,d){const r=document.createElement("article");r.className=["designbase-wc-kanban__card",t.disabled&&"designbase-wc-kanban__card--disabled",t.priority&&`designbase-wc-kanban__card--priority-${t.priority}`].filter(Boolean).join(" "),r.dataset.cardId=t.id,r.dataset.columnId=n,r.dataset.cardIndex=String(s),r.setAttribute("role","listitem"),r.tabIndex=t.disabled?-1:0;const i=document.createElement("div");i.className="designbase-wc-kanban__card-title-row";const o=document.createElement("h4");if(o.className="designbase-wc-kanban__card-title",o.textContent=t.title,i.append(o),t.priority&&a.includes(t.priority)&&i.append(this.createPriorityBadge(t.priority)),r.append(i),t.description){const e=document.createElement("p");e.className="designbase-wc-kanban__card-description",e.textContent=t.description,r.append(e)}if(t.tags?.length){const e=document.createElement("div");e.className="designbase-wc-kanban__card-tags",t.tags.forEach(t=>e.append(this.createTag(t))),r.append(e)}const c=document.createElement("div");if(c.className="designbase-wc-kanban__card-footer",t.assignee&&c.append(this.createAssignee(t.assignee)),t.dueDate){const a=document.createElement("span");a.className="designbase-wc-kanban__due-date",a.append(e("calendar","l"===d.size?12:"m"===d.size?11:10));const n=document.createElement("span");n.textContent=this.formatDueDate(t.dueDate),a.append(n),c.append(a)}return c.childNodes.length>0&&r.append(c),r.addEventListener("click",e=>{d.disabled||this.dispatchEvent(new CustomEvent("db-card-click",{detail:{card:t,columnId:n},bubbles:!0,composed:!0}))}),r.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.dispatchEvent(new CustomEvent("db-card-click",{detail:{card:t,columnId:n},bubbles:!0,composed:!0})))}),this.bindCardDrag(r,t,n,s,d.draggable,d.disabled),r}createColumn(t,a){const n=document.createElement("section"),s=void 0!==t.limit&&t.cards.length>t.limit;n.className=["designbase-wc-kanban__column",s&&"designbase-wc-kanban__column--over-limit"].filter(Boolean).join(" "),n.dataset.columnId=t.id,n.setAttribute("role","group"),n.setAttribute("aria-label",t.title);const d=document.createElement("header");d.className="designbase-wc-kanban__column-header";const r=document.createElement("div");if(r.className="designbase-wc-kanban__column-title-wrap",t.color){const e=document.createElement("span");e.className="designbase-wc-kanban__column-color",e.style.backgroundColor=t.color,e.setAttribute("aria-hidden","true"),r.append(e)}const i=document.createElement("h3");if(i.className="designbase-wc-kanban__column-title",i.textContent=t.title,r.append(i),d.append(r),a.showColumnCount){const e=document.createElement("span");e.className="designbase-wc-kanban__column-count",e.textContent=void 0!==t.limit?`${t.cards.length}/${t.limit}`:String(t.cards.length),d.append(e)}n.append(d);const o=document.createElement("div");if(o.className="designbase-wc-kanban__column-body",o.dataset.columnId=t.id,o.setAttribute("role","list"),o.addEventListener("dragover",e=>{if(!this.dragState)return;e.preventDefault(),e.stopPropagation(),e.dataTransfer&&(e.dataTransfer.dropEffect="move");if(!this.getBool("allow-cross-column",!0)&&this.dragState.columnId!==t.id)return;const a=this.getDropIndexFromColumnPointer(e,t.id);this.setDropTarget({columnId:t.id,index:a})}),o.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.commitDrop()}),0===t.cards.length){const e=document.createElement("div");e.className="designbase-wc-kanban__column-empty",e.textContent=a.emptyColumnText,o.append(e)}else t.cards.forEach((e,n)=>{o.append(this.createCard(e,t.id,n,{size:a.size,draggable:a.draggable,disabled:a.disabled}))});if(n.append(o),a.showAddCard&&!a.disabled){const s=document.createElement("button");s.type="button",s.className="designbase-wc-kanban__add-card",s.append(e("plus","l"===a.size?14:"m"===a.size?12:10));const d=document.createElement("span");d.textContent="카드 추가",s.append(d),s.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-add-card",{detail:{columnId:t.id},bubbles:!0,composed:!0}))}),n.append(s)}return n}render(){const e=this.getOption("size",t,"s"),a=this.getBool("disabled"),n=this.getBool("draggable",!0),s=this.getBool("show-column-count",!0),d=this.getBool("show-add-card"),r=this.getAttribute("empty-column-text")||"카드가 없습니다";this.className=["designbase-wc-kanban",`designbase-wc-kanban--${e}`,this.getBool("full-width")&&"designbase-wc-kanban--full-width",a&&"designbase-wc-kanban--disabled",this.classList.contains("designbase-wc-kanban--dragging")&&"designbase-wc-kanban--dragging"].filter(Boolean).join(" ");const i=document.createElement("div");i.className="designbase-wc-kanban__board";const o=document.createDocumentFragment();this.columns.forEach(t=>{o.append(this.createColumn(t,{size:e,draggable:n,showColumnCount:s,showAddCard:d,emptyColumnText:r,disabled:a}))}),i.append(o),this.replaceChildren(i),this.updateDragClasses()}}customElements.get("db-kanban")||customElements.define("db-kanban",DbKanban);export{DbKanban};
1
+ import { createDbIcon } from './db-icons.js';
2
+
3
+ const SIZES = ['s', 'm', 'l'];
4
+ const PRIORITIES = ['low', 'medium', 'high', 'urgent'];
5
+ const PRIORITY_LABELS = {
6
+ low: '낮음',
7
+ medium: '보통',
8
+ high: '높음',
9
+ urgent: '긴급',
10
+ };
11
+ class DbKanban extends HTMLElement {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.dragState = null;
15
+ this.dropTarget = null;
16
+ this.handleBoardDragOver = (event) => {
17
+ if (!this.dragState)
18
+ return;
19
+ const target = event.target;
20
+ if (target instanceof Element &&
21
+ (target.closest('.designbase-wc-kanban__card') ||
22
+ target.closest('.designbase-wc-kanban__column-body'))) {
23
+ return;
24
+ }
25
+ event.preventDefault();
26
+ if (event.dataTransfer)
27
+ event.dataTransfer.dropEffect = 'move';
28
+ };
29
+ this.handleBoardDrop = (event) => {
30
+ if (!this.dragState)
31
+ return;
32
+ const target = event.target;
33
+ if (target instanceof Element &&
34
+ (target.closest('.designbase-wc-kanban__card') ||
35
+ target.closest('.designbase-wc-kanban__column-body'))) {
36
+ return;
37
+ }
38
+ event.preventDefault();
39
+ this.commitDrop();
40
+ };
41
+ }
42
+ static get observedAttributes() {
43
+ return [
44
+ 'columns',
45
+ 'size',
46
+ 'disabled',
47
+ 'draggable',
48
+ 'show-column-count',
49
+ 'show-add-card',
50
+ 'allow-cross-column',
51
+ 'full-width',
52
+ 'empty-column-text',
53
+ ];
54
+ }
55
+ get columns() {
56
+ try {
57
+ const parsed = JSON.parse(this.getAttribute('columns') || '[]');
58
+ return Array.isArray(parsed) ? parsed : [];
59
+ }
60
+ catch {
61
+ return [];
62
+ }
63
+ }
64
+ set columns(value) {
65
+ this.setAttribute('columns', typeof value === 'string' ? value : JSON.stringify(value));
66
+ }
67
+ connectedCallback() {
68
+ this.setAttribute('role', 'region');
69
+ this.setAttribute('aria-label', '칸반 보드');
70
+ this.addEventListener('dragover', this.handleBoardDragOver);
71
+ this.addEventListener('drop', this.handleBoardDrop);
72
+ this.render();
73
+ }
74
+ disconnectedCallback() {
75
+ this.removeEventListener('dragover', this.handleBoardDragOver);
76
+ this.removeEventListener('drop', this.handleBoardDrop);
77
+ }
78
+ attributeChangedCallback() {
79
+ if (this.isConnected)
80
+ this.render();
81
+ }
82
+ getBool(name, fallback = false) {
83
+ if (!this.hasAttribute(name))
84
+ return fallback;
85
+ const value = this.getAttribute(name);
86
+ return value === '' || value === 'true';
87
+ }
88
+ getOption(name, values, fallback) {
89
+ const value = this.getAttribute(name);
90
+ return value && values.includes(value) ? value : fallback;
91
+ }
92
+ emitChange(columns) {
93
+ this.columns = columns;
94
+ this.dispatchEvent(new CustomEvent('db-change', { detail: { columns }, bubbles: true, composed: true }));
95
+ }
96
+ emitCardMove(columns, detail) {
97
+ this.columns = columns;
98
+ this.dispatchEvent(new CustomEvent('db-card-move', {
99
+ detail: { ...detail, columns },
100
+ bubbles: true,
101
+ composed: true,
102
+ }));
103
+ this.dispatchEvent(new CustomEvent('db-change', { detail: { columns }, bubbles: true, composed: true }));
104
+ }
105
+ findCardLocation(cardId) {
106
+ for (const column of this.columns) {
107
+ const index = column.cards.findIndex((card) => card.id === cardId);
108
+ if (index >= 0)
109
+ return { columnId: column.id, index };
110
+ }
111
+ return null;
112
+ }
113
+ getAdjustedDropIndex(columnId, dropIndex) {
114
+ if (!this.dragState)
115
+ return -1;
116
+ const { columnId: fromColumnId, cardIndex: fromIndex } = this.dragState;
117
+ if (fromColumnId === columnId && dropIndex > fromIndex) {
118
+ return dropIndex - 1;
119
+ }
120
+ return dropIndex;
121
+ }
122
+ isValidDropTarget(target = this.dropTarget) {
123
+ if (!this.dragState || !target)
124
+ return false;
125
+ const adjusted = this.getAdjustedDropIndex(target.columnId, target.index);
126
+ if (adjusted < 0)
127
+ return false;
128
+ if (this.dragState.columnId === target.columnId && adjusted === this.dragState.cardIndex) {
129
+ return false;
130
+ }
131
+ return true;
132
+ }
133
+ moveCard(cardId, toColumnId, toIndex) {
134
+ const location = this.findCardLocation(cardId);
135
+ if (!location)
136
+ return;
137
+ const next = this.columns.map((column) => ({
138
+ ...column,
139
+ cards: [...column.cards],
140
+ }));
141
+ const fromColumn = next.find((column) => column.id === location.columnId);
142
+ const toColumn = next.find((column) => column.id === toColumnId);
143
+ if (!fromColumn || !toColumn)
144
+ return;
145
+ const [moved] = fromColumn.cards.splice(location.index, 1);
146
+ if (!moved)
147
+ return;
148
+ const adjustedIndex = this.getAdjustedDropIndex(toColumnId, toIndex);
149
+ toColumn.cards.splice(Math.max(0, adjustedIndex), 0, moved);
150
+ this.emitCardMove(next, {
151
+ cardId,
152
+ fromColumnId: location.columnId,
153
+ toColumnId,
154
+ fromIndex: location.index,
155
+ toIndex: Math.max(0, adjustedIndex),
156
+ });
157
+ }
158
+ setDropTarget(target) {
159
+ const next = target && this.isValidDropTarget(target) ? target : null;
160
+ const prevKey = this.dropTarget ? `${this.dropTarget.columnId}:${this.dropTarget.index}` : '';
161
+ const nextKey = next ? `${next.columnId}:${next.index}` : '';
162
+ if (prevKey === nextKey)
163
+ return;
164
+ this.dropTarget = next;
165
+ this.updateDragClasses();
166
+ }
167
+ resetDragState() {
168
+ this.dragState = null;
169
+ this.dropTarget = null;
170
+ this.classList.remove('designbase-wc-kanban--dragging');
171
+ this.updateDragClasses();
172
+ }
173
+ updateDragClasses() {
174
+ const hasDrag = !!this.dragState;
175
+ this.classList.toggle('designbase-wc-kanban--dragging', hasDrag);
176
+ this.querySelectorAll('.designbase-wc-kanban__card').forEach((cardEl) => {
177
+ const cardId = cardEl.dataset.cardId || '';
178
+ const isDragged = hasDrag && this.dragState?.cardId === cardId;
179
+ cardEl.classList.toggle('designbase-wc-kanban__card--dragged', isDragged);
180
+ });
181
+ this.querySelectorAll('.designbase-wc-kanban__column-body').forEach((bodyEl) => {
182
+ const columnId = bodyEl.dataset.columnId || '';
183
+ const isDropColumn = !!this.dropTarget && this.dropTarget.columnId === columnId;
184
+ bodyEl.classList.toggle('designbase-wc-kanban__column-body--drag-over', isDropColumn);
185
+ });
186
+ this.querySelectorAll('.designbase-wc-kanban__card').forEach((cardEl) => {
187
+ const columnId = cardEl.dataset.columnId || '';
188
+ const cardIndex = Number(cardEl.dataset.cardIndex || -1);
189
+ const showBefore = !!this.dropTarget &&
190
+ this.dropTarget.columnId === columnId &&
191
+ this.dropTarget.index === cardIndex;
192
+ const column = this.columns.find((entry) => entry.id === columnId);
193
+ const showAfterLast = !!this.dropTarget &&
194
+ this.dropTarget.columnId === columnId &&
195
+ column &&
196
+ this.dropTarget.index === column.cards.length &&
197
+ cardIndex === column.cards.length - 1;
198
+ cardEl.classList.toggle('designbase-wc-kanban__card--drop-before', showBefore);
199
+ cardEl.classList.toggle('designbase-wc-kanban__card--drop-after', showAfterLast);
200
+ });
201
+ }
202
+ getDropIndexFromPointer(event, cardEl, index) {
203
+ const rect = cardEl.getBoundingClientRect();
204
+ const offset = event.clientY - rect.top;
205
+ return offset < rect.height / 2 ? index : index + 1;
206
+ }
207
+ getDropIndexFromColumnPointer(event, columnId) {
208
+ const cards = Array.from(this.querySelectorAll(`.designbase-wc-kanban__column-body[data-column-id="${columnId}"] > .designbase-wc-kanban__card`));
209
+ if (cards.length === 0)
210
+ return 0;
211
+ for (let index = 0; index < cards.length; index += 1) {
212
+ const rect = cards[index].getBoundingClientRect();
213
+ if (event.clientY < rect.top + rect.height / 2)
214
+ return index;
215
+ }
216
+ return cards.length;
217
+ }
218
+ commitDrop() {
219
+ if (!this.dragState || !this.dropTarget || !this.isValidDropTarget()) {
220
+ this.resetDragState();
221
+ return;
222
+ }
223
+ const { cardId } = this.dragState;
224
+ const { columnId, index } = this.dropTarget;
225
+ this.resetDragState();
226
+ this.moveCard(cardId, columnId, index);
227
+ this.render();
228
+ }
229
+ formatDueDate(value) {
230
+ const date = new Date(value);
231
+ if (Number.isNaN(date.getTime()))
232
+ return value;
233
+ return date.toLocaleDateString('ko-KR', { month: 'short', day: 'numeric' });
234
+ }
235
+ getInitials(assignee) {
236
+ if (assignee.initials)
237
+ return assignee.initials;
238
+ return assignee.name
239
+ .split(/\s+/)
240
+ .map((part) => part.charAt(0))
241
+ .join('')
242
+ .slice(0, 2)
243
+ .toUpperCase();
244
+ }
245
+ createTag(tag) {
246
+ const el = document.createElement('span');
247
+ el.className = [
248
+ 'designbase-wc-kanban__tag',
249
+ tag.variant && `designbase-wc-kanban__tag--${tag.variant}`,
250
+ ]
251
+ .filter(Boolean)
252
+ .join(' ');
253
+ el.textContent = tag.label;
254
+ return el;
255
+ }
256
+ createPriorityBadge(priority) {
257
+ const el = document.createElement('span');
258
+ el.className = `designbase-wc-kanban__priority designbase-wc-kanban__priority--${priority}`;
259
+ el.textContent = PRIORITY_LABELS[priority];
260
+ el.setAttribute('aria-label', `우선순위 ${PRIORITY_LABELS[priority]}`);
261
+ return el;
262
+ }
263
+ createAssignee(assignee) {
264
+ const el = document.createElement('div');
265
+ el.className = 'designbase-wc-kanban__assignee';
266
+ el.title = assignee.name;
267
+ if (assignee.avatar) {
268
+ const img = document.createElement('img');
269
+ img.className = 'designbase-wc-kanban__assignee-avatar';
270
+ img.src = assignee.avatar;
271
+ img.alt = assignee.name;
272
+ el.append(img);
273
+ }
274
+ else {
275
+ const initials = document.createElement('span');
276
+ initials.className = 'designbase-wc-kanban__assignee-initials';
277
+ initials.textContent = this.getInitials(assignee);
278
+ el.append(initials);
279
+ }
280
+ const name = document.createElement('span');
281
+ name.className = 'designbase-wc-kanban__assignee-name';
282
+ name.textContent = assignee.name;
283
+ el.append(name);
284
+ return el;
285
+ }
286
+ bindCardDrag(cardEl, card, columnId, cardIndex, draggable, disabled) {
287
+ cardEl.draggable = draggable && !disabled && !card.disabled;
288
+ cardEl.addEventListener('dragstart', (event) => {
289
+ if (!draggable || disabled || card.disabled)
290
+ return;
291
+ this.dragState = { cardId: card.id, columnId, cardIndex };
292
+ this.dropTarget = null;
293
+ if (event.dataTransfer) {
294
+ event.dataTransfer.effectAllowed = 'move';
295
+ event.dataTransfer.setData('text/plain', card.id);
296
+ }
297
+ this.classList.add('designbase-wc-kanban--dragging');
298
+ this.updateDragClasses();
299
+ });
300
+ cardEl.addEventListener('dragover', (event) => {
301
+ if (!this.dragState)
302
+ return;
303
+ event.preventDefault();
304
+ event.stopPropagation();
305
+ if (event.dataTransfer)
306
+ event.dataTransfer.dropEffect = 'move';
307
+ const allowCrossColumn = this.getBool('allow-cross-column', true);
308
+ if (!allowCrossColumn && this.dragState.columnId !== columnId)
309
+ return;
310
+ const nextIndex = this.getDropIndexFromPointer(event, cardEl, cardIndex);
311
+ this.setDropTarget({ columnId, index: nextIndex });
312
+ });
313
+ cardEl.addEventListener('dragleave', (event) => {
314
+ const rect = cardEl.getBoundingClientRect();
315
+ const x = event.clientX - rect.left;
316
+ const y = event.clientY - rect.top;
317
+ if (x < 0 || x > rect.width || y < 0 || y > rect.height) {
318
+ this.setDropTarget(null);
319
+ }
320
+ });
321
+ cardEl.addEventListener('drop', (event) => {
322
+ event.preventDefault();
323
+ event.stopPropagation();
324
+ this.commitDrop();
325
+ });
326
+ cardEl.addEventListener('dragend', () => {
327
+ this.resetDragState();
328
+ this.render();
329
+ });
330
+ }
331
+ createCard(card, columnId, cardIndex, options) {
332
+ const cardEl = document.createElement('article');
333
+ cardEl.className = [
334
+ 'designbase-wc-kanban__card',
335
+ card.disabled && 'designbase-wc-kanban__card--disabled',
336
+ card.priority && `designbase-wc-kanban__card--priority-${card.priority}`,
337
+ ]
338
+ .filter(Boolean)
339
+ .join(' ');
340
+ cardEl.dataset.cardId = card.id;
341
+ cardEl.dataset.columnId = columnId;
342
+ cardEl.dataset.cardIndex = String(cardIndex);
343
+ cardEl.setAttribute('role', 'listitem');
344
+ cardEl.tabIndex = card.disabled ? -1 : 0;
345
+ const titleRow = document.createElement('div');
346
+ titleRow.className = 'designbase-wc-kanban__card-title-row';
347
+ const title = document.createElement('h4');
348
+ title.className = 'designbase-wc-kanban__card-title';
349
+ title.textContent = card.title;
350
+ titleRow.append(title);
351
+ if (card.priority && PRIORITIES.includes(card.priority)) {
352
+ titleRow.append(this.createPriorityBadge(card.priority));
353
+ }
354
+ cardEl.append(titleRow);
355
+ if (card.description) {
356
+ const description = document.createElement('p');
357
+ description.className = 'designbase-wc-kanban__card-description';
358
+ description.textContent = card.description;
359
+ cardEl.append(description);
360
+ }
361
+ if (card.tags?.length) {
362
+ const tags = document.createElement('div');
363
+ tags.className = 'designbase-wc-kanban__card-tags';
364
+ card.tags.forEach((tag) => tags.append(this.createTag(tag)));
365
+ cardEl.append(tags);
366
+ }
367
+ const footer = document.createElement('div');
368
+ footer.className = 'designbase-wc-kanban__card-footer';
369
+ if (card.assignee) {
370
+ footer.append(this.createAssignee(card.assignee));
371
+ }
372
+ if (card.dueDate) {
373
+ const due = document.createElement('span');
374
+ due.className = 'designbase-wc-kanban__due-date';
375
+ due.append(createDbIcon('calendar', options.size === 'l' ? 12 : options.size === 'm' ? 11 : 10));
376
+ const dueText = document.createElement('span');
377
+ dueText.textContent = this.formatDueDate(card.dueDate);
378
+ due.append(dueText);
379
+ footer.append(due);
380
+ }
381
+ if (footer.childNodes.length > 0)
382
+ cardEl.append(footer);
383
+ cardEl.addEventListener('click', (event) => {
384
+ if (options.disabled)
385
+ return;
386
+ this.dispatchEvent(new CustomEvent('db-card-click', {
387
+ detail: { card, columnId },
388
+ bubbles: true,
389
+ composed: true,
390
+ }));
391
+ });
392
+ cardEl.addEventListener('keydown', (event) => {
393
+ if (event.key === 'Enter' || event.key === ' ') {
394
+ event.preventDefault();
395
+ this.dispatchEvent(new CustomEvent('db-card-click', {
396
+ detail: { card, columnId },
397
+ bubbles: true,
398
+ composed: true,
399
+ }));
400
+ }
401
+ });
402
+ this.bindCardDrag(cardEl, card, columnId, cardIndex, options.draggable, options.disabled);
403
+ return cardEl;
404
+ }
405
+ createColumn(column, options) {
406
+ const columnEl = document.createElement('section');
407
+ const isOverLimit = column.limit !== undefined && column.cards.length > column.limit;
408
+ columnEl.className = [
409
+ 'designbase-wc-kanban__column',
410
+ isOverLimit && 'designbase-wc-kanban__column--over-limit',
411
+ ]
412
+ .filter(Boolean)
413
+ .join(' ');
414
+ columnEl.dataset.columnId = column.id;
415
+ columnEl.setAttribute('role', 'group');
416
+ columnEl.setAttribute('aria-label', column.title);
417
+ const header = document.createElement('header');
418
+ header.className = 'designbase-wc-kanban__column-header';
419
+ const titleWrap = document.createElement('div');
420
+ titleWrap.className = 'designbase-wc-kanban__column-title-wrap';
421
+ if (column.color) {
422
+ const color = document.createElement('span');
423
+ color.className = 'designbase-wc-kanban__column-color';
424
+ color.style.backgroundColor = column.color;
425
+ color.setAttribute('aria-hidden', 'true');
426
+ titleWrap.append(color);
427
+ }
428
+ const title = document.createElement('h3');
429
+ title.className = 'designbase-wc-kanban__column-title';
430
+ title.textContent = column.title;
431
+ titleWrap.append(title);
432
+ header.append(titleWrap);
433
+ if (options.showColumnCount) {
434
+ const count = document.createElement('span');
435
+ count.className = 'designbase-wc-kanban__column-count';
436
+ count.textContent =
437
+ column.limit !== undefined
438
+ ? `${column.cards.length}/${column.limit}`
439
+ : String(column.cards.length);
440
+ header.append(count);
441
+ }
442
+ columnEl.append(header);
443
+ const body = document.createElement('div');
444
+ body.className = 'designbase-wc-kanban__column-body';
445
+ body.dataset.columnId = column.id;
446
+ body.setAttribute('role', 'list');
447
+ body.addEventListener('dragover', (event) => {
448
+ if (!this.dragState)
449
+ return;
450
+ event.preventDefault();
451
+ event.stopPropagation();
452
+ if (event.dataTransfer)
453
+ event.dataTransfer.dropEffect = 'move';
454
+ const allowCrossColumn = this.getBool('allow-cross-column', true);
455
+ if (!allowCrossColumn && this.dragState.columnId !== column.id)
456
+ return;
457
+ const nextIndex = this.getDropIndexFromColumnPointer(event, column.id);
458
+ this.setDropTarget({ columnId: column.id, index: nextIndex });
459
+ });
460
+ body.addEventListener('drop', (event) => {
461
+ event.preventDefault();
462
+ event.stopPropagation();
463
+ this.commitDrop();
464
+ });
465
+ if (column.cards.length === 0) {
466
+ const empty = document.createElement('div');
467
+ empty.className = 'designbase-wc-kanban__column-empty';
468
+ empty.textContent = options.emptyColumnText;
469
+ body.append(empty);
470
+ }
471
+ else {
472
+ column.cards.forEach((card, index) => {
473
+ body.append(this.createCard(card, column.id, index, {
474
+ size: options.size,
475
+ draggable: options.draggable,
476
+ disabled: options.disabled,
477
+ }));
478
+ });
479
+ }
480
+ columnEl.append(body);
481
+ if (options.showAddCard && !options.disabled) {
482
+ const addButton = document.createElement('button');
483
+ addButton.type = 'button';
484
+ addButton.className = 'designbase-wc-kanban__add-card';
485
+ addButton.append(createDbIcon('plus', options.size === 'l' ? 14 : options.size === 'm' ? 12 : 10));
486
+ const addLabel = document.createElement('span');
487
+ addLabel.textContent = '카드 추가';
488
+ addButton.append(addLabel);
489
+ addButton.addEventListener('click', () => {
490
+ this.dispatchEvent(new CustomEvent('db-add-card', {
491
+ detail: { columnId: column.id },
492
+ bubbles: true,
493
+ composed: true,
494
+ }));
495
+ });
496
+ columnEl.append(addButton);
497
+ }
498
+ return columnEl;
499
+ }
500
+ render() {
501
+ const size = this.getOption('size', SIZES, 's');
502
+ const disabled = this.getBool('disabled');
503
+ const draggable = this.getBool('draggable', true);
504
+ const showColumnCount = this.getBool('show-column-count', true);
505
+ const showAddCard = this.getBool('show-add-card');
506
+ const emptyColumnText = this.getAttribute('empty-column-text') || '카드가 없습니다';
507
+ this.className = [
508
+ 'designbase-wc-kanban',
509
+ `designbase-wc-kanban--${size}`,
510
+ this.getBool('full-width') && 'designbase-wc-kanban--full-width',
511
+ disabled && 'designbase-wc-kanban--disabled',
512
+ this.classList.contains('designbase-wc-kanban--dragging') &&
513
+ 'designbase-wc-kanban--dragging',
514
+ ]
515
+ .filter(Boolean)
516
+ .join(' ');
517
+ const board = document.createElement('div');
518
+ board.className = 'designbase-wc-kanban__board';
519
+ const fragment = document.createDocumentFragment();
520
+ this.columns.forEach((column) => {
521
+ fragment.append(this.createColumn(column, {
522
+ size,
523
+ draggable,
524
+ showColumnCount,
525
+ showAddCard,
526
+ emptyColumnText,
527
+ disabled,
528
+ }));
529
+ });
530
+ board.append(fragment);
531
+ this.replaceChildren(board);
532
+ this.updateDragClasses();
533
+ }
534
+ }
535
+ if (!customElements.get('db-kanban'))
536
+ customElements.define('db-kanban', DbKanban);
537
+
538
+ export { DbKanban };
@@ -1 +1,66 @@
1
- class DbLabel extends HTMLElement{static get observedAttributes(){return["label","html-for","id","size","required","disabled","error"]}connectedCallback(){this.sync()}attributeChangedCallback(){this.sync()}sync(){const e=this.getAttribute("size")||"s",t=this.hasAttribute("required"),s=this.hasAttribute("disabled"),l=this.hasAttribute("error"),a=this.getAttribute("html-for"),i=this.getAttribute("id"),r=this.getAttribute("label");this.className=["designbase-wc-label",`designbase-wc-label--${e}`,s&&"designbase-wc-label--disabled",l&&"designbase-wc-label--error"].filter(Boolean).join(" ");let b=this.querySelector(":scope > label.designbase-wc-label__text");if(null!==r&&""!==r)b||(this.replaceChildren(),b=document.createElement("label"),b.className="designbase-wc-label__text",this.append(b)),b.textContent=r;else if(!b&&this.childNodes.length>0){b=document.createElement("label"),b.className="designbase-wc-label__text";Array.from(this.childNodes).forEach(e=>b.append(e)),this.append(b)}if(b&&(a?b.htmlFor=a:b.removeAttribute("for"),i?b.id=i:b.removeAttribute("id"),b.querySelector(".designbase-wc-label__required")?.remove(),t)){const e=document.createElement("span");e.className="designbase-wc-label__required",e.textContent="*",b.append(e)}}}customElements.get("db-label")||customElements.define("db-label",DbLabel);export{DbLabel};
1
+ class DbLabel extends HTMLElement {
2
+ static get observedAttributes() {
3
+ return ['label', 'html-for', 'id', 'size', 'required', 'disabled', 'error'];
4
+ }
5
+ connectedCallback() {
6
+ this.sync();
7
+ }
8
+ attributeChangedCallback() {
9
+ this.sync();
10
+ }
11
+ sync() {
12
+ const size = this.getAttribute('size') || 's';
13
+ const required = this.hasAttribute('required');
14
+ const disabled = this.hasAttribute('disabled');
15
+ const error = this.hasAttribute('error');
16
+ const htmlFor = this.getAttribute('html-for');
17
+ const id = this.getAttribute('id');
18
+ const explicit = this.getAttribute('label');
19
+ this.className = [
20
+ 'designbase-wc-label',
21
+ `designbase-wc-label--${size}`,
22
+ disabled && 'designbase-wc-label--disabled',
23
+ error && 'designbase-wc-label--error',
24
+ ]
25
+ .filter(Boolean)
26
+ .join(' ');
27
+ let labelEl = this.querySelector(':scope > label.designbase-wc-label__text');
28
+ if (explicit !== null && explicit !== '') {
29
+ if (!labelEl) {
30
+ this.replaceChildren();
31
+ labelEl = document.createElement('label');
32
+ labelEl.className = 'designbase-wc-label__text';
33
+ this.append(labelEl);
34
+ }
35
+ labelEl.textContent = explicit;
36
+ }
37
+ else if (!labelEl && this.childNodes.length > 0) {
38
+ labelEl = document.createElement('label');
39
+ labelEl.className = 'designbase-wc-label__text';
40
+ const nodes = Array.from(this.childNodes);
41
+ nodes.forEach((node) => labelEl.append(node));
42
+ this.append(labelEl);
43
+ }
44
+ if (!labelEl)
45
+ return;
46
+ if (htmlFor)
47
+ labelEl.htmlFor = htmlFor;
48
+ else
49
+ labelEl.removeAttribute('for');
50
+ if (id)
51
+ labelEl.id = id;
52
+ else
53
+ labelEl.removeAttribute('id');
54
+ labelEl.querySelector('.designbase-wc-label__required')?.remove();
55
+ if (required) {
56
+ const mark = document.createElement('span');
57
+ mark.className = 'designbase-wc-label__required';
58
+ mark.textContent = '*';
59
+ labelEl.append(mark);
60
+ }
61
+ }
62
+ }
63
+ if (!customElements.get('db-label'))
64
+ customElements.define('db-label', DbLabel);
65
+
66
+ export { DbLabel };