@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,134 @@
1
- const clamp=(t,r,a)=>Math.max(r,Math.min(a,t)),normalizeHex=t=>{const r=(t||"").trim().toUpperCase();return r?r.startsWith("#")?r:`#${r}`:""},isHex=t=>/^#?[0-9A-Fa-f]{6}$/.test(t||""),hexToRgb=t=>{const r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t.trim());return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:null},toHex=(t,r,a)=>{const h=t=>clamp(Math.round(t),0,255).toString(16).padStart(2,"0");return`#${h(t)}${h(r)}${h(a)}`.toUpperCase()},rgbToHsv=(t,r,a)=>{t/=255,r/=255,a/=255;const e=Math.max(t,r,a),s=e-Math.min(t,r,a);let n=0;if(0!==s){switch(e){case t:n=(r-a)/s+(r<a?6:0);break;case r:n=(a-t)/s+2;break;case a:n=(t-r)/s+4}n*=60}return{h:n,s:100*(0===e?0:s/e),v:100*e}},hsvToRgb=(t,r,a)=>{const e=(a/=100)*(r/=100),s=e*(1-Math.abs(t/60%2-1)),n=a-e;let o=0,c=0,u=0;return t>=0&&t<60?(o=e,c=s,u=0):t<120?(o=s,c=e,u=0):t<180?(o=0,c=e,u=s):t<240?(o=0,c=s,u=e):t<300?(o=s,c=0,u=e):(o=e,c=0,u=s),{r:Math.round(255*(o+n)),g:Math.round(255*(c+n)),b:Math.round(255*(u+n))}},rgbToHsl=(t,r,a)=>{t/=255,r/=255,a/=255;const e=Math.max(t,r,a),s=Math.min(t,r,a);let n=0,o=0;const c=(e+s)/2;if(e!==s){const u=e-s;switch(o=c>.5?u/(2-e-s):u/(e+s),e){case t:n=(r-a)/u+(r<a?6:0);break;case r:n=(a-t)/u+2;break;case a:n=(t-r)/u+4}n*=60}return{h:n,s:100*o,l:100*c}},formatColor=(t,r,a,e,s)=>{const n=s/100;switch(t){case"hex":default:return a;case"rgb":return`rgb(${r.r}, ${r.g}, ${r.b})`;case"rgba":return`rgba(${r.r}, ${r.g}, ${r.b}, ${n.toFixed(2)})`;case"hsl":return`hsl(${Math.round(e.h)}, ${Math.round(e.s)}%, ${Math.round(e.l)}%)`;case"hsla":return`hsla(${Math.round(e.h)}, ${Math.round(e.s)}%, ${Math.round(e.l)}%, ${n.toFixed(2)})`}};export{clamp,formatColor,hexToRgb,hsvToRgb,isHex,normalizeHex,rgbToHsl,rgbToHsv,toHex};
1
+ const clamp = (n, min, max) => Math.max(min, Math.min(max, n));
2
+ const normalizeHex = (s) => {
3
+ const trimmed = (s || '').trim().toUpperCase();
4
+ if (!trimmed)
5
+ return '';
6
+ return trimmed.startsWith('#') ? trimmed : `#${trimmed}`;
7
+ };
8
+ const isHex = (s) => /^#?[0-9A-Fa-f]{6}$/.test(s || '');
9
+ const hexToRgb = (hex) => {
10
+ const m = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex.trim());
11
+ if (!m)
12
+ return null;
13
+ return { r: parseInt(m[1], 16), g: parseInt(m[2], 16), b: parseInt(m[3], 16) };
14
+ };
15
+ const toHex = (r, g, b) => {
16
+ const h = (x) => clamp(Math.round(x), 0, 255).toString(16).padStart(2, '0');
17
+ return `#${h(r)}${h(g)}${h(b)}`.toUpperCase();
18
+ };
19
+ const rgbToHsv = (r, g, b) => {
20
+ r /= 255;
21
+ g /= 255;
22
+ b /= 255;
23
+ const max = Math.max(r, g, b);
24
+ const min = Math.min(r, g, b);
25
+ const d = max - min;
26
+ let h = 0;
27
+ if (d !== 0) {
28
+ switch (max) {
29
+ case r:
30
+ h = (g - b) / d + (g < b ? 6 : 0);
31
+ break;
32
+ case g:
33
+ h = (b - r) / d + 2;
34
+ break;
35
+ case b:
36
+ h = (r - g) / d + 4;
37
+ break;
38
+ }
39
+ h *= 60;
40
+ }
41
+ const s = max === 0 ? 0 : d / max;
42
+ return { h, s: s * 100, v: max * 100 };
43
+ };
44
+ const hsvToRgb = (h, s, v) => {
45
+ s /= 100;
46
+ v /= 100;
47
+ const c = v * s;
48
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
49
+ const m = v - c;
50
+ let rp = 0;
51
+ let gp = 0;
52
+ let bp = 0;
53
+ if (h >= 0 && h < 60) {
54
+ rp = c;
55
+ gp = x;
56
+ bp = 0;
57
+ }
58
+ else if (h < 120) {
59
+ rp = x;
60
+ gp = c;
61
+ bp = 0;
62
+ }
63
+ else if (h < 180) {
64
+ rp = 0;
65
+ gp = c;
66
+ bp = x;
67
+ }
68
+ else if (h < 240) {
69
+ rp = 0;
70
+ gp = x;
71
+ bp = c;
72
+ }
73
+ else if (h < 300) {
74
+ rp = x;
75
+ gp = 0;
76
+ bp = c;
77
+ }
78
+ else {
79
+ rp = c;
80
+ gp = 0;
81
+ bp = x;
82
+ }
83
+ return {
84
+ r: Math.round((rp + m) * 255),
85
+ g: Math.round((gp + m) * 255),
86
+ b: Math.round((bp + m) * 255),
87
+ };
88
+ };
89
+ const rgbToHsl = (r, g, b) => {
90
+ r /= 255;
91
+ g /= 255;
92
+ b /= 255;
93
+ const max = Math.max(r, g, b);
94
+ const min = Math.min(r, g, b);
95
+ let h = 0;
96
+ let s = 0;
97
+ const l = (max + min) / 2;
98
+ if (max !== min) {
99
+ const d = max - min;
100
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
101
+ switch (max) {
102
+ case r:
103
+ h = (g - b) / d + (g < b ? 6 : 0);
104
+ break;
105
+ case g:
106
+ h = (b - r) / d + 2;
107
+ break;
108
+ case b:
109
+ h = (r - g) / d + 4;
110
+ break;
111
+ }
112
+ h *= 60;
113
+ }
114
+ return { h, s: s * 100, l: l * 100 };
115
+ };
116
+ const formatColor = (format, rgb, hex, hsl, alphaPercent) => {
117
+ const alpha = alphaPercent / 100;
118
+ switch (format) {
119
+ case 'hex':
120
+ return hex;
121
+ case 'rgb':
122
+ return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
123
+ case 'rgba':
124
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha.toFixed(2)})`;
125
+ case 'hsl':
126
+ return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
127
+ case 'hsla':
128
+ return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${alpha.toFixed(2)})`;
129
+ default:
130
+ return hex;
131
+ }
132
+ };
133
+
134
+ export { clamp, formatColor, hexToRgb, hsvToRgb, isHex, normalizeHex, rgbToHsl, rgbToHsv, toHex };
@@ -1 +1,140 @@
1
- const startOfDay=t=>{const e=new Date(t);return e.setHours(0,0,0,0),e},endOfDay=t=>{const e=new Date(t);return e.setHours(23,59,59,999),e},addDays=(t,e)=>{const n=new Date(t);return n.setDate(n.getDate()+e),startOfDay(n)},getMonthEnd=t=>endOfDay(new Date(t.getFullYear(),t.getMonth()+1,0)),getYearEnd=t=>endOfDay(new Date(t.getFullYear(),11,31)),clampRange=(t,e,n)=>{let{start:a,end:r}=t;return e&&a<e&&(a=startOfDay(e)),n&&r>n&&(r=endOfDay(n)),a>r?{start:r,end:a}:{start:a,end:r}},t=[{id:"today",label:"오늘",getRange:({today:t})=>clampRange({start:startOfDay(t),end:endOfDay(t)})},{id:"yesterday",label:"어제",getRange:({today:t})=>{const e=addDays(t,-1);return clampRange({start:e,end:endOfDay(e)})}},{id:"this-week",label:"이번 주",getRange:({today:t,startOfWeek:e,minDate:n,maxDate:a})=>{const r=((t,e)=>{const n=t.getDay();return addDays(t,-("monday"===e?(n+6)%7:n))})(t,e);return clampRange({start:r,end:(o=r,endOfDay(addDays(o,6)))},n,a);var o}},{id:"this-month",label:"이번 달",getRange:({today:t,minDate:e,maxDate:n})=>{return clampRange({start:(a=t,startOfDay(new Date(a.getFullYear(),a.getMonth(),1))),end:getMonthEnd(t)},e,n);var a}},{id:"this-year",label:"올해",getRange:({today:t,minDate:e,maxDate:n})=>{return clampRange({start:(a=t,startOfDay(new Date(a.getFullYear(),0,1))),end:getYearEnd(t)},e,n);var a}},{id:"custom",label:"사용자 지정",getRange:()=>null}],addMonths=(t,e)=>{const n=new Date(t);return n.setDate(1),n.setMonth(n.getMonth()+e),n},toISODate=t=>`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`,parseISODate=t=>{if(!t)return null;const e=t.trim().match(/^(\d{4})-(\d{2})-(\d{2})$/);if(!e)return null;const n=new Date(Number(e[1]),Number(e[2])-1,Number(e[3]));return Number.isNaN(n.getTime())?null:startOfDay(n)},formatDisplayDate=(t,e="ko-KR")=>t.toLocaleDateString(e),generateWeekdays=t=>{const e=["일","월","화","수","목","금","토"];return"monday"===t&&e.push(e.shift()),e},generateCalendarGrid=(t,e,n=!1)=>{const a=t.getFullYear(),r=t.getMonth(),o=new Date(a,r,1),s="monday"===e?(o.getDay()+6)%7:o.getDay();if(n){const t=[];for(let e=0;e<s;e+=1)t.push(null);const e=new Date(a,r+1,0).getDate();for(let n=1;n<=e;n+=1)t.push(new Date(a,r,n));return t}const u=new Date(o);return u.setDate(u.getDate()-s),Array.from({length:42},(t,e)=>{const n=new Date(u);return n.setDate(u.getDate()+e),n})},detectActivePresetId=(t,e,n)=>{if(!t)return"custom";const a=t.start.toDateString(),r=t.end.toDateString();for(const t of e){if("custom"===t.id)continue;const e=t.getRange(n);if(e&&(e.start.toDateString()===a&&e.end.toDateString()===r))return t.id}return"custom"},formatPanelInputDate=(t,e)=>t?t.toLocaleDateString(e,{year:"numeric",month:"short",day:"numeric"}):"";export{t as DEFAULT_DATE_PICKER_PRESETS,addMonths,detectActivePresetId,endOfDay,formatDisplayDate,formatPanelInputDate,generateCalendarGrid,generateWeekdays,parseISODate,startOfDay,toISODate};
1
+ const startOfDay = (date) => {
2
+ const next = new Date(date);
3
+ next.setHours(0, 0, 0, 0);
4
+ return next;
5
+ };
6
+ const endOfDay = (date) => {
7
+ const next = new Date(date);
8
+ next.setHours(23, 59, 59, 999);
9
+ return next;
10
+ };
11
+ const addDays = (date, days) => {
12
+ const next = new Date(date);
13
+ next.setDate(next.getDate() + days);
14
+ return startOfDay(next);
15
+ };
16
+ const getWeekStart = (date, startOfWeek) => {
17
+ const day = date.getDay();
18
+ const offset = startOfWeek === 'monday' ? (day + 6) % 7 : day;
19
+ return addDays(date, -offset);
20
+ };
21
+ const getWeekEnd = (weekStart) => endOfDay(addDays(weekStart, 6));
22
+ const getMonthStart = (date) => startOfDay(new Date(date.getFullYear(), date.getMonth(), 1));
23
+ const getMonthEnd = (date) => endOfDay(new Date(date.getFullYear(), date.getMonth() + 1, 0));
24
+ const getYearStart = (date) => startOfDay(new Date(date.getFullYear(), 0, 1));
25
+ const getYearEnd = (date) => endOfDay(new Date(date.getFullYear(), 11, 31));
26
+ const clampRange = (range, minDate, maxDate) => {
27
+ let { start, end } = range;
28
+ if (minDate && start < minDate)
29
+ start = startOfDay(minDate);
30
+ if (maxDate && end > maxDate)
31
+ end = endOfDay(maxDate);
32
+ if (start > end)
33
+ return { start: end, end: start };
34
+ return { start, end };
35
+ };
36
+ const DEFAULT_DATE_PICKER_PRESETS = [
37
+ { id: 'today', label: '오늘', getRange: ({ today }) => clampRange({ start: startOfDay(today), end: endOfDay(today) }) },
38
+ {
39
+ id: 'yesterday',
40
+ label: '어제',
41
+ getRange: ({ today }) => {
42
+ const day = addDays(today, -1);
43
+ return clampRange({ start: day, end: endOfDay(day) });
44
+ },
45
+ },
46
+ {
47
+ id: 'this-week',
48
+ label: '이번 주',
49
+ getRange: ({ today, startOfWeek, minDate, maxDate }) => {
50
+ const start = getWeekStart(today, startOfWeek);
51
+ return clampRange({ start, end: getWeekEnd(start) }, minDate, maxDate);
52
+ },
53
+ },
54
+ {
55
+ id: 'this-month',
56
+ label: '이번 달',
57
+ getRange: ({ today, minDate, maxDate }) => clampRange({ start: getMonthStart(today), end: getMonthEnd(today) }, minDate, maxDate),
58
+ },
59
+ {
60
+ id: 'this-year',
61
+ label: '올해',
62
+ getRange: ({ today, minDate, maxDate }) => clampRange({ start: getYearStart(today), end: getYearEnd(today) }, minDate, maxDate),
63
+ },
64
+ { id: 'custom', label: '사용자 지정', getRange: () => null },
65
+ ];
66
+ const addMonths = (date, months) => {
67
+ const next = new Date(date);
68
+ next.setDate(1);
69
+ next.setMonth(next.getMonth() + months);
70
+ return next;
71
+ };
72
+ const toISODate = (date) => {
73
+ const y = date.getFullYear();
74
+ const m = String(date.getMonth() + 1).padStart(2, '0');
75
+ const d = String(date.getDate()).padStart(2, '0');
76
+ return `${y}-${m}-${d}`;
77
+ };
78
+ const parseISODate = (value) => {
79
+ if (!value)
80
+ return null;
81
+ const match = value.trim().match(/^(\d{4})-(\d{2})-(\d{2})$/);
82
+ if (!match)
83
+ return null;
84
+ const date = new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
85
+ return Number.isNaN(date.getTime()) ? null : startOfDay(date);
86
+ };
87
+ const formatDisplayDate = (date, locale = 'ko-KR') => date.toLocaleDateString(locale);
88
+ const generateWeekdays = (startOfWeek) => {
89
+ const weekdays = ['일', '월', '화', '수', '목', '금', '토'];
90
+ if (startOfWeek === 'monday')
91
+ weekdays.push(weekdays.shift());
92
+ return weekdays;
93
+ };
94
+ const generateCalendarGrid = (baseDate, startOfWeek, monthOnly = false) => {
95
+ const year = baseDate.getFullYear();
96
+ const month = baseDate.getMonth();
97
+ const firstDay = new Date(year, month, 1);
98
+ const leadingBlankCount = startOfWeek === 'monday' ? (firstDay.getDay() + 6) % 7 : firstDay.getDay();
99
+ if (monthOnly) {
100
+ const grid = [];
101
+ for (let i = 0; i < leadingBlankCount; i += 1) {
102
+ grid.push(null);
103
+ }
104
+ const lastDayOfMonth = new Date(year, month + 1, 0).getDate();
105
+ for (let day = 1; day <= lastDayOfMonth; day += 1) {
106
+ grid.push(new Date(year, month, day));
107
+ }
108
+ return grid;
109
+ }
110
+ const startDate = new Date(firstDay);
111
+ startDate.setDate(startDate.getDate() - leadingBlankCount);
112
+ return Array.from({ length: 42 }, (_, index) => {
113
+ const date = new Date(startDate);
114
+ date.setDate(startDate.getDate() + index);
115
+ return date;
116
+ });
117
+ };
118
+ const detectActivePresetId = (value, presets, context) => {
119
+ if (!value)
120
+ return 'custom';
121
+ const valueStart = value.start.toDateString();
122
+ const valueEnd = value.end.toDateString();
123
+ for (const preset of presets) {
124
+ if (preset.id === 'custom')
125
+ continue;
126
+ const range = preset.getRange(context);
127
+ if (!range)
128
+ continue;
129
+ if (range.start.toDateString() === valueStart && range.end.toDateString() === valueEnd)
130
+ return preset.id;
131
+ }
132
+ return 'custom';
133
+ };
134
+ const formatPanelInputDate = (date, locale) => {
135
+ if (!date)
136
+ return '';
137
+ return date.toLocaleDateString(locale, { year: 'numeric', month: 'short', day: 'numeric' });
138
+ };
139
+
140
+ export { DEFAULT_DATE_PICKER_PRESETS, addMonths, detectActivePresetId, endOfDay, formatDisplayDate, formatPanelInputDate, generateCalendarGrid, generateWeekdays, parseISODate, startOfDay, toISODate };
@@ -1 +1,304 @@
1
- import{createDbIcon as e}from"./db-icons.js";class DbAccordion extends HTMLElement{constructor(){super(...arguments),this.expanded=new Set,this.isRendering=!1,this.suppressExpandedAttrCallback=!1}static get observedAttributes(){return["items","variant","size","allow-multiple","expand-mode","expanded-items","default-item-type"]}get items(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get allowMultiple(){return this.hasAttribute("allow-multiple")}set allowMultiple(e){this.toggleAttribute("allow-multiple",e)}get expandedItems(){const e=(this.getAttribute("expanded-items")||"").trim();if(!e)return[];if("all"===e)return this.items.map((e,t)=>this.resolveItemKey(e,t));try{const t=JSON.parse(e);if(Array.isArray(t))return t.map(e=>String(e).trim()).filter(Boolean)}catch{}return e.split(",").map(e=>e.trim()).filter(Boolean)}set expandedItems(e){Array.isArray(e)?this.setAttribute("expanded-items",e.join(",")):this.setAttribute("expanded-items",e)}connectedCallback(){this.syncExpandedFromAttributes(),this.render(),this.childObserver=new MutationObserver(e=>{if(this.isRendering)return;e.some(e=>Array.from(e.addedNodes).some(e=>e instanceof HTMLElement&&e.hasAttribute("slot")))&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.childObserver?.disconnect()}attributeChangedCallback(e){if(this.isConnected){if("expanded-items"===e){if(this.suppressExpandedAttrCallback)return;return this.syncExpandedFromAttributes(),void this.syncExpandedState()}return"expand-mode"===e||"allow-multiple"===e?(this.syncExpandedFromAttributes(),void this.syncExpandedState()):"items"===e?(this.syncExpandedFromAttributes(),void this.render()):void this.render()}}resolveItemKey(e,t){return e.id??String(t)}getExpandMode(){const e=this.getAttribute("expand-mode");return"single"===e||"multiple"===e||"all"===e?e:(this.hasAttribute("allow-multiple"),"multiple")}syncExpandedFromAttributes(){const e=this.items.map((e,t)=>this.resolveItemKey(e,t)),t=this.expandedItems,n=this.getExpandMode();t.length>0?this.expanded=new Set(t.filter(t=>e.includes(t))):this.expanded="all"!==n?new Set:new Set(e)}iconSize(e){return"s"===e?16:"l"===e?24:20}collectPanelContent(){const e=new Map,register=(t,n)=>{if(!(t instanceof HTMLElement)||"SLOT"===t.tagName)return;e.has(n)||e.set(n,[]);const s=e.get(n);s.includes(t)||s.push(t)};return Array.from(this.children).forEach(e=>{const t=e.getAttribute("slot")?.match(/^content-(\d+)$/);t&&register(e,Number(t[1]))}),this.querySelectorAll(":scope > .designbase-wc-accordion__item").forEach((e,t)=>{const n=e.querySelector(":scope > .designbase-wc-accordion__content > .designbase-wc-accordion__content-inner");n&&Array.from(n.children).forEach(e=>register(e,t))}),e}isItemExpanded(e,t){return this.expanded.has(this.resolveItemKey(e,t))}syncExpandedState(){const e=this.items;this.querySelectorAll(":scope > .designbase-wc-accordion__item").forEach((t,n)=>{const s=e[n];if(!s)return;const i=this.isItemExpanded(s,n);t.classList.toggle("designbase-wc-accordion__item--expanded",i),t.classList.toggle("designbase-wc-accordion__item--disabled",Boolean(s.disabled));const a=t.querySelector(".designbase-wc-accordion__trigger"),d=t.querySelector(".designbase-wc-accordion__content");a?.setAttribute("aria-expanded",String(i)),d?.setAttribute("aria-hidden",String(!i))})}render(){this.isRendering=!0;const t=this.collectPanelContent(),n=this.getAttribute("variant")||"default",s=this.getAttribute("size")||"m",i=this.getExpandMode(),a=this.getAttribute("default-item-type")||"none",d=this.items,c=this.iconSize(s);this.className=["designbase-wc-accordion",`designbase-wc-accordion--${n}`,`designbase-wc-accordion--${s}`,"multiple"===i&&"designbase-wc-accordion--multiple","single"===i&&"designbase-wc-accordion--single","all"===i&&"designbase-wc-accordion--all"].filter(Boolean).join(" "),this.setAttribute("role","region"),this.setAttribute("aria-label","아코디언"),this.querySelectorAll(":scope > .designbase-wc-accordion__item").forEach(e=>e.remove()),d.forEach((s,i)=>{const d=this.resolveItemKey(s,i),r=this.isItemExpanded(s,i),o=document.createElement("div");o.className=["designbase-wc-accordion__item",`designbase-wc-accordion__item--${n}`,r&&"designbase-wc-accordion__item--expanded",s.disabled&&"designbase-wc-accordion__item--disabled"].filter(Boolean).join(" "),o.dataset.itemKey=d;const l=document.createElement("button");l.type="button",l.className="designbase-wc-accordion__trigger",l.disabled=Boolean(s.disabled),l.setAttribute("aria-expanded",String(r)),l.setAttribute("aria-controls",`accordion-content-${d}`),l.addEventListener("click",()=>{s.disabled||this.toggle(d)});const m=s.itemType||a;if("number"===m){const e=document.createElement("div");e.className="designbase-wc-accordion__number",e.textContent=`${i+1}.`,l.append(e)}else if("question"===m){const e=document.createElement("div");e.className="designbase-wc-accordion__question",e.textContent="Q.",l.append(e)}else if("icon"===m&&s.icon){const t=document.createElement("div");t.className="designbase-wc-accordion__icon",t.append(e(s.icon,c)),l.append(t)}const p=document.createElement("span");p.className="designbase-wc-accordion__title",p.textContent=s.title;const h=document.createElement("div");h.className="designbase-wc-accordion__chevron",h.append(e("chevron-down",c)),l.append(p,h);const u=document.createElement("div");u.id=`accordion-content-${d}`,u.className="designbase-wc-accordion__content",u.setAttribute("aria-hidden",String(!r));const b=document.createElement("div");b.className="designbase-wc-accordion__content-inner";const g=t.get(i)||[];if(g.length>0)g.forEach(e=>{e.removeAttribute("slot"),b.append(e)});else if(s.content){const e=document.createElement("p");e.className="designbase-wc-accordion__content-text",e.textContent=s.content,b.append(e)}u.append(b),o.append(l,u),this.append(o)}),this.isRendering=!1}toggle(e){const t=this.getExpandMode();this.expanded.has(e)?this.expanded.delete(e):"single"===t?this.expanded=new Set([e]):this.expanded.add(e);const n=Array.from(this.expanded);this.syncExpandedState(),this.suppressExpandedAttrCallback=!0,this.expandedItems=n,this.suppressExpandedAttrCallback=!1,this.dispatchEvent(new CustomEvent("db-change",{detail:{expandedItems:n},bubbles:!0,composed:!0}))}}customElements.get("db-accordion")||customElements.define("db-accordion",DbAccordion);export{DbAccordion};
1
+ import { createDbIcon } from './db-icons.js';
2
+
3
+ class DbAccordion extends HTMLElement {
4
+ constructor() {
5
+ super(...arguments);
6
+ this.expanded = new Set();
7
+ this.isRendering = false;
8
+ this.suppressExpandedAttrCallback = false;
9
+ }
10
+ static get observedAttributes() {
11
+ return [
12
+ 'items',
13
+ 'variant',
14
+ 'size',
15
+ 'allow-multiple',
16
+ 'expand-mode',
17
+ 'expanded-items',
18
+ 'default-item-type',
19
+ ];
20
+ }
21
+ get items() {
22
+ try {
23
+ const parsed = JSON.parse(this.getAttribute('items') || '[]');
24
+ return Array.isArray(parsed) ? parsed : [];
25
+ }
26
+ catch {
27
+ return [];
28
+ }
29
+ }
30
+ set items(value) {
31
+ this.setAttribute('items', typeof value === 'string' ? value : JSON.stringify(value));
32
+ }
33
+ get allowMultiple() {
34
+ return this.hasAttribute('allow-multiple');
35
+ }
36
+ set allowMultiple(value) {
37
+ this.toggleAttribute('allow-multiple', value);
38
+ }
39
+ get expandedItems() {
40
+ const raw = (this.getAttribute('expanded-items') || '').trim();
41
+ if (!raw)
42
+ return [];
43
+ if (raw === 'all') {
44
+ return this.items.map((item, index) => this.resolveItemKey(item, index));
45
+ }
46
+ try {
47
+ const parsed = JSON.parse(raw);
48
+ if (Array.isArray(parsed)) {
49
+ return parsed.map((item) => String(item).trim()).filter(Boolean);
50
+ }
51
+ }
52
+ catch {
53
+ // comma-separated fallback
54
+ }
55
+ return raw
56
+ .split(',')
57
+ .map((item) => item.trim())
58
+ .filter(Boolean);
59
+ }
60
+ set expandedItems(value) {
61
+ if (Array.isArray(value)) {
62
+ this.setAttribute('expanded-items', value.join(','));
63
+ return;
64
+ }
65
+ this.setAttribute('expanded-items', value);
66
+ }
67
+ connectedCallback() {
68
+ this.syncExpandedFromAttributes();
69
+ this.render();
70
+ this.childObserver = new MutationObserver((mutations) => {
71
+ if (this.isRendering)
72
+ return;
73
+ const hasSlottedChange = mutations.some((mutation) => Array.from(mutation.addedNodes).some((node) => node instanceof HTMLElement && node.hasAttribute('slot')));
74
+ if (hasSlottedChange)
75
+ this.render();
76
+ });
77
+ this.childObserver.observe(this, { childList: true });
78
+ }
79
+ disconnectedCallback() {
80
+ this.childObserver?.disconnect();
81
+ }
82
+ attributeChangedCallback(name) {
83
+ if (!this.isConnected)
84
+ return;
85
+ if (name === 'expanded-items') {
86
+ if (this.suppressExpandedAttrCallback)
87
+ return;
88
+ this.syncExpandedFromAttributes();
89
+ this.syncExpandedState();
90
+ return;
91
+ }
92
+ if (name === 'expand-mode' || name === 'allow-multiple') {
93
+ this.syncExpandedFromAttributes();
94
+ this.syncExpandedState();
95
+ return;
96
+ }
97
+ if (name === 'items') {
98
+ this.syncExpandedFromAttributes();
99
+ this.render();
100
+ return;
101
+ }
102
+ this.render();
103
+ }
104
+ /** id와 index 문자열 충돌 방지 — 항목당 단일 키만 사용 */
105
+ resolveItemKey(item, index) {
106
+ return item.id ?? String(index);
107
+ }
108
+ getExpandMode() {
109
+ const mode = this.getAttribute('expand-mode');
110
+ if (mode === 'single' || mode === 'multiple' || mode === 'all') {
111
+ return mode;
112
+ }
113
+ if (this.hasAttribute('allow-multiple')) {
114
+ return 'multiple';
115
+ }
116
+ return 'multiple';
117
+ }
118
+ syncExpandedFromAttributes() {
119
+ const keys = this.items.map((item, index) => this.resolveItemKey(item, index));
120
+ const fromAttr = this.expandedItems;
121
+ const mode = this.getExpandMode();
122
+ if (fromAttr.length > 0) {
123
+ this.expanded = new Set(fromAttr.filter((key) => keys.includes(key)));
124
+ return;
125
+ }
126
+ if (mode === 'all') {
127
+ this.expanded = new Set(keys);
128
+ return;
129
+ }
130
+ this.expanded = new Set();
131
+ }
132
+ iconSize(size) {
133
+ if (size === 's')
134
+ return 16;
135
+ if (size === 'l')
136
+ return 24;
137
+ return 20;
138
+ }
139
+ collectPanelContent() {
140
+ const map = new Map();
141
+ const register = (node, index) => {
142
+ if (!(node instanceof HTMLElement) || node.tagName === 'SLOT')
143
+ return;
144
+ if (!map.has(index))
145
+ map.set(index, []);
146
+ const list = map.get(index);
147
+ if (!list.includes(node))
148
+ list.push(node);
149
+ };
150
+ Array.from(this.children).forEach((child) => {
151
+ const match = child.getAttribute('slot')?.match(/^content-(\d+)$/);
152
+ if (match)
153
+ register(child, Number(match[1]));
154
+ });
155
+ this.querySelectorAll(':scope > .designbase-wc-accordion__item').forEach((item, index) => {
156
+ const inner = item.querySelector(':scope > .designbase-wc-accordion__content > .designbase-wc-accordion__content-inner');
157
+ if (!inner)
158
+ return;
159
+ Array.from(inner.children).forEach((child) => register(child, index));
160
+ });
161
+ return map;
162
+ }
163
+ isItemExpanded(item, index) {
164
+ return this.expanded.has(this.resolveItemKey(item, index));
165
+ }
166
+ syncExpandedState() {
167
+ const items = this.items;
168
+ this.querySelectorAll(':scope > .designbase-wc-accordion__item').forEach((wrapper, index) => {
169
+ const item = items[index];
170
+ if (!item)
171
+ return;
172
+ const expanded = this.isItemExpanded(item, index);
173
+ wrapper.classList.toggle('designbase-wc-accordion__item--expanded', expanded);
174
+ wrapper.classList.toggle('designbase-wc-accordion__item--disabled', Boolean(item.disabled));
175
+ const trigger = wrapper.querySelector('.designbase-wc-accordion__trigger');
176
+ const content = wrapper.querySelector('.designbase-wc-accordion__content');
177
+ trigger?.setAttribute('aria-expanded', String(expanded));
178
+ content?.setAttribute('aria-hidden', String(!expanded));
179
+ });
180
+ }
181
+ render() {
182
+ this.isRendering = true;
183
+ const panelContent = this.collectPanelContent();
184
+ const variant = this.getAttribute('variant') || 'default';
185
+ const size = this.getAttribute('size') || 'm';
186
+ const expandMode = this.getExpandMode();
187
+ const defaultItemType = this.getAttribute('default-item-type') || 'none';
188
+ const items = this.items;
189
+ const iconPx = this.iconSize(size);
190
+ this.className = [
191
+ 'designbase-wc-accordion',
192
+ `designbase-wc-accordion--${variant}`,
193
+ `designbase-wc-accordion--${size}`,
194
+ expandMode === 'multiple' && 'designbase-wc-accordion--multiple',
195
+ expandMode === 'single' && 'designbase-wc-accordion--single',
196
+ expandMode === 'all' && 'designbase-wc-accordion--all',
197
+ ]
198
+ .filter(Boolean)
199
+ .join(' ');
200
+ this.setAttribute('role', 'region');
201
+ this.setAttribute('aria-label', '아코디언');
202
+ this.querySelectorAll(':scope > .designbase-wc-accordion__item').forEach((node) => node.remove());
203
+ items.forEach((item, index) => {
204
+ const key = this.resolveItemKey(item, index);
205
+ const expanded = this.isItemExpanded(item, index);
206
+ const wrapper = document.createElement('div');
207
+ wrapper.className = [
208
+ 'designbase-wc-accordion__item',
209
+ `designbase-wc-accordion__item--${variant}`,
210
+ expanded && 'designbase-wc-accordion__item--expanded',
211
+ item.disabled && 'designbase-wc-accordion__item--disabled',
212
+ ]
213
+ .filter(Boolean)
214
+ .join(' ');
215
+ wrapper.dataset.itemKey = key;
216
+ const trigger = document.createElement('button');
217
+ trigger.type = 'button';
218
+ trigger.className = 'designbase-wc-accordion__trigger';
219
+ trigger.disabled = Boolean(item.disabled);
220
+ trigger.setAttribute('aria-expanded', String(expanded));
221
+ trigger.setAttribute('aria-controls', `accordion-content-${key}`);
222
+ trigger.addEventListener('click', () => {
223
+ if (!item.disabled)
224
+ this.toggle(key);
225
+ });
226
+ const itemType = item.itemType || defaultItemType;
227
+ if (itemType === 'number') {
228
+ const prefix = document.createElement('div');
229
+ prefix.className = 'designbase-wc-accordion__number';
230
+ prefix.textContent = `${index + 1}.`;
231
+ trigger.append(prefix);
232
+ }
233
+ else if (itemType === 'question') {
234
+ const prefix = document.createElement('div');
235
+ prefix.className = 'designbase-wc-accordion__question';
236
+ prefix.textContent = 'Q.';
237
+ trigger.append(prefix);
238
+ }
239
+ else if (itemType === 'icon' && item.icon) {
240
+ const prefix = document.createElement('div');
241
+ prefix.className = 'designbase-wc-accordion__icon';
242
+ prefix.append(createDbIcon(item.icon, iconPx));
243
+ trigger.append(prefix);
244
+ }
245
+ const title = document.createElement('span');
246
+ title.className = 'designbase-wc-accordion__title';
247
+ title.textContent = item.title;
248
+ const chevron = document.createElement('div');
249
+ chevron.className = 'designbase-wc-accordion__chevron';
250
+ chevron.append(createDbIcon('chevron-down', iconPx));
251
+ trigger.append(title, chevron);
252
+ const content = document.createElement('div');
253
+ content.id = `accordion-content-${key}`;
254
+ content.className = 'designbase-wc-accordion__content';
255
+ content.setAttribute('aria-hidden', String(!expanded));
256
+ const inner = document.createElement('div');
257
+ inner.className = 'designbase-wc-accordion__content-inner';
258
+ const slottedNodes = panelContent.get(index) || [];
259
+ if (slottedNodes.length > 0) {
260
+ slottedNodes.forEach((node) => {
261
+ node.removeAttribute('slot');
262
+ inner.append(node);
263
+ });
264
+ }
265
+ else if (item.content) {
266
+ const answer = document.createElement('p');
267
+ answer.className = 'designbase-wc-accordion__content-text';
268
+ answer.textContent = item.content;
269
+ inner.append(answer);
270
+ }
271
+ content.append(inner);
272
+ wrapper.append(trigger, content);
273
+ this.append(wrapper);
274
+ });
275
+ this.isRendering = false;
276
+ }
277
+ toggle(key) {
278
+ const mode = this.getExpandMode();
279
+ if (this.expanded.has(key)) {
280
+ this.expanded.delete(key);
281
+ }
282
+ else if (mode === 'single') {
283
+ this.expanded = new Set([key]);
284
+ }
285
+ else {
286
+ this.expanded.add(key);
287
+ }
288
+ const expandedItems = Array.from(this.expanded);
289
+ this.syncExpandedState();
290
+ this.suppressExpandedAttrCallback = true;
291
+ this.expandedItems = expandedItems;
292
+ this.suppressExpandedAttrCallback = false;
293
+ this.dispatchEvent(new CustomEvent('db-change', {
294
+ detail: { expandedItems },
295
+ bubbles: true,
296
+ composed: true,
297
+ }));
298
+ }
299
+ }
300
+ if (!customElements.get('db-accordion')) {
301
+ customElements.define('db-accordion', DbAccordion);
302
+ }
303
+
304
+ export { DbAccordion };