@designbasekorea/ui-wc 0.5.6 → 0.6.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.
- package/dist/chunks/lottie-0e23d630.js +1 -0
- package/dist/esm/components/animation-background/canvas-controller.js +1 -121
- package/dist/esm/components/animation-background/controls.js +1 -180
- package/dist/esm/components/animation-background/graphite-controller.js +1 -196
- package/dist/esm/components/animation-background/graphite-presets.js +1 -42
- package/dist/esm/components/animation-background/graphite-shader.js +1 -111
- package/dist/esm/components/animation-background/layers.js +1 -369
- package/dist/esm/components/animation-background/lumina-presets.js +1 -53
- package/dist/esm/components/animation-background/lumina-shaders.js +1 -181
- package/dist/esm/components/animation-background/lumina-utils.js +1 -60
- package/dist/esm/components/animation-background/particle-defaults.js +1 -36
- package/dist/esm/components/animation-background/renderers.js +1 -167
- package/dist/esm/components/animation-background/shader-controller.js +1 -154
- package/dist/esm/components/color-picker-utils.js +1 -134
- package/dist/esm/components/date-picker-utils.js +1 -140
- package/dist/esm/components/db-accordion.js +1 -304
- package/dist/esm/components/db-ad-banner.js +1 -455
- package/dist/esm/components/db-ai-chat-list.d.ts +43 -0
- package/dist/esm/components/db-ai-chat-list.js +1 -0
- package/dist/esm/components/db-ai-chat.d.ts +159 -0
- package/dist/esm/components/db-ai-chat.js +1 -0
- package/dist/esm/components/db-alert.js +1 -149
- package/dist/esm/components/db-animation-background.js +1 -486
- package/dist/esm/components/db-animation-text.js +1 -601
- package/dist/esm/components/db-app-badge.js +1 -88
- package/dist/esm/components/db-audio-player.js +1 -752
- package/dist/esm/components/db-avatar.js +1 -188
- package/dist/esm/components/db-backdrop.js +1 -139
- package/dist/esm/components/db-badge.js +1 -91
- package/dist/esm/components/db-banner.js +1 -188
- package/dist/esm/components/db-bottom-navigation.js +1 -146
- package/dist/esm/components/db-bottom-sheet.js +1 -481
- package/dist/esm/components/db-breadcrumbs.js +1 -329
- package/dist/esm/components/db-button.js +1 -316
- package/dist/esm/components/db-calendar.js +1 -675
- package/dist/esm/components/db-card.js +1 -265
- package/dist/esm/components/db-carousel.js +1 -264
- package/dist/esm/components/db-chat-composer.d.ts +134 -0
- package/dist/esm/components/db-chat-composer.js +1 -0
- package/dist/esm/components/db-chat-list.d.ts +47 -0
- package/dist/esm/components/db-chat-list.js +1 -0
- package/dist/esm/components/db-chat-message.d.ts +39 -0
- package/dist/esm/components/db-chat-message.js +1 -0
- package/dist/esm/components/db-chat-orb.d.ts +99 -0
- package/dist/esm/components/db-chat-orb.js +1 -0
- package/dist/esm/components/db-chat-room.d.ts +71 -0
- package/dist/esm/components/db-chat-room.js +1 -0
- package/dist/esm/components/db-chat-suggestions.d.ts +44 -0
- package/dist/esm/components/db-chat-suggestions.js +1 -0
- package/dist/esm/components/db-chat-typing.d.ts +22 -0
- package/dist/esm/components/db-chat-typing.js +1 -0
- package/dist/esm/components/db-chat-welcome.d.ts +32 -0
- package/dist/esm/components/db-chat-welcome.js +1 -0
- package/dist/esm/components/db-chat-widget.d.ts +146 -0
- package/dist/esm/components/db-chat-widget.js +1 -0
- package/dist/esm/components/db-checkbox.js +1 -202
- package/dist/esm/components/db-chip.js +1 -104
- package/dist/esm/components/db-code-block.js +1 -304
- package/dist/esm/components/db-color-picker.js +1 -746
- package/dist/esm/components/db-confirm.js +1 -191
- package/dist/esm/components/db-container.js +1 -39
- package/dist/esm/components/db-context-menu.js +1 -265
- package/dist/esm/components/db-countdown.js +1 -146
- package/dist/esm/components/db-cursor-follower.js +1 -173
- package/dist/esm/components/db-date-picker.js +1 -837
- package/dist/esm/components/db-divider.js +1 -66
- package/dist/esm/components/db-download-progress.d.ts +89 -0
- package/dist/esm/components/db-download-progress.js +1 -0
- package/dist/esm/components/db-drawer.js +1 -245
- package/dist/esm/components/db-dropdown.js +1 -493
- package/dist/esm/components/db-dropzone.js +1 -266
- package/dist/esm/components/db-email-verify.d.ts +62 -0
- package/dist/esm/components/db-email-verify.js +1 -0
- package/dist/esm/components/db-empty-state.js +1 -97
- package/dist/esm/components/db-file-uploader.js +1 -256
- package/dist/esm/components/db-floating-action-button.js +1 -139
- package/dist/esm/components/db-footer.js +1 -385
- package/dist/esm/components/db-form.js +1 -566
- package/dist/esm/components/db-gantt.js +1 -882
- package/dist/esm/components/db-gradient.js +1 -133
- package/dist/esm/components/db-grid-background.js +1 -909
- package/dist/esm/components/db-grid.js +1 -73
- package/dist/esm/components/db-icons.d.ts +3 -0
- package/dist/esm/components/db-icons.js +1 -82
- package/dist/esm/components/db-image-list.js +1 -214
- package/dist/esm/components/db-image-placeholder.js +1 -96
- package/dist/esm/components/db-image.js +1 -289
- package/dist/esm/components/db-indicator.js +1 -517
- package/dist/esm/components/db-input.js +1 -420
- package/dist/esm/components/db-kanban.js +1 -538
- package/dist/esm/components/db-label.js +1 -66
- package/dist/esm/components/db-lightbox.js +1 -372
- package/dist/esm/components/db-list.js +1 -340
- package/dist/esm/components/db-logo-svg.js +1 -72
- package/dist/esm/components/db-logo.js +1 -106
- package/dist/esm/components/db-lottie.js +1 -109
- package/dist/esm/components/db-markdown-editor.js +1 -458
- package/dist/esm/components/db-marquee.js +1 -402
- package/dist/esm/components/db-masonry.js +1 -94
- package/dist/esm/components/db-menu-item.js +1 -211
- package/dist/esm/components/db-modal.js +1 -522
- package/dist/esm/components/db-navbar.js +1 -680
- package/dist/esm/components/db-onboarding-modal.js +1 -322
- package/dist/esm/components/db-otp-input.d.ts +53 -0
- package/dist/esm/components/db-otp-input.js +1 -0
- package/dist/esm/components/db-page-header.js +1 -312
- package/dist/esm/components/db-pagination.js +1 -271
- package/dist/esm/components/db-phone-verify.d.ts +61 -0
- package/dist/esm/components/db-phone-verify.js +1 -0
- package/dist/esm/components/db-popover.js +1 -580
- package/dist/esm/components/db-progress-step.js +1 -166
- package/dist/esm/components/db-progress.js +1 -171
- package/dist/esm/components/db-progressbar.js +1 -72
- package/dist/esm/components/db-radio.js +1 -172
- package/dist/esm/components/db-random-gradient.js +1 -121
- package/dist/esm/components/db-range-slider.js +1 -811
- package/dist/esm/components/db-rating.js +1 -325
- package/dist/esm/components/db-reorder.js +1 -286
- package/dist/esm/components/db-resizable-panels.js +1 -282
- package/dist/esm/components/db-scroll-area.js +1 -126
- package/dist/esm/components/db-search-bar.js +1 -668
- package/dist/esm/components/db-section-app-download.js +1 -101
- package/dist/esm/components/db-section-contact.js +1 -102
- package/dist/esm/components/db-section-cta.js +1 -150
- package/dist/esm/components/db-section-faq.js +1 -120
- package/dist/esm/components/db-section-feature-grid.js +1 -137
- package/dist/esm/components/db-section-feature.js +1 -179
- package/dist/esm/components/db-section-hero.js +1 -243
- package/dist/esm/components/db-section-logo-cloud.js +1 -138
- package/dist/esm/components/db-section-pricing.js +1 -166
- package/dist/esm/components/db-section-stats.js +1 -129
- package/dist/esm/components/db-section-testimonials.js +1 -252
- package/dist/esm/components/db-section.js +1 -385
- package/dist/esm/components/db-segment-control.js +1 -231
- package/dist/esm/components/db-select.js +1 -571
- package/dist/esm/components/db-share-icons.js +1 -40
- package/dist/esm/components/db-share.js +1 -489
- package/dist/esm/components/db-sidebar.js +1 -1068
- package/dist/esm/components/db-skeleton.js +1 -94
- package/dist/esm/components/db-spinner.js +1 -102
- package/dist/esm/components/db-split-view.js +1 -297
- package/dist/esm/components/db-stack.js +1 -46
- package/dist/esm/components/db-stat.js +1 -218
- package/dist/esm/components/db-stepper.js +1 -398
- package/dist/esm/components/db-table.js +1 -412
- package/dist/esm/components/db-tabs.js +1 -335
- package/dist/esm/components/db-testimonial.d.ts +2 -0
- package/dist/esm/components/db-testimonial.js +1 -162
- package/dist/esm/components/db-textarea.js +1 -233
- package/dist/esm/components/db-time-picker.js +1 -523
- package/dist/esm/components/db-timeline.js +1 -174
- package/dist/esm/components/db-toast.js +1 -158
- package/dist/esm/components/db-toggle.js +1 -162
- package/dist/esm/components/db-toolbar.js +1 -94
- package/dist/esm/components/db-tooltip.js +1 -440
- package/dist/esm/components/db-top-banner.js +1 -121
- package/dist/esm/components/db-tutorial.js +1 -324
- package/dist/esm/components/db-two-factor.d.ts +60 -0
- package/dist/esm/components/db-two-factor.js +1 -0
- package/dist/esm/components/db-video-player.js +1 -503
- package/dist/esm/components/db-youtube-player.js +1 -194
- package/dist/esm/components/highlight-code.js +1 -65
- package/dist/esm/components/input-validation.js +1 -50
- package/dist/esm/components/marketing-block-host-utils.js +1 -9
- package/dist/esm/components/number-scrub.js +1 -117
- package/dist/esm/components/random-gradient-palettes.js +1 -67
- package/dist/esm/components/section-block-header-utils.js +1 -48
- package/dist/esm/helpers/confirm.js +1 -52
- package/dist/esm/helpers/toast.js +1 -73
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.js +1 -111
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-bash.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-clike.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-css.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-javascript.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-json.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-jsx.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-markup.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-scss.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-tsx.js +1 -0
- package/dist/esm/node_modules/.pnpm/prismjs@1.30.0/node_modules/prismjs/components/prism-typescript.js +1 -0
- package/dist/index.cjs +1 -55414
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1091 -2
- package/dist/index.esm.js +1 -38284
- package/dist/react/chunks/lottie-14e7addb.js +1 -0
- package/dist/react/index.cjs +1 -56503
- package/dist/react/index.d.ts +1620 -54
- package/dist/react/index.esm.js +1 -39373
- package/package.json +1 -1
- package/dist/chunks/lottie-e273b936.js +0 -17032
- package/dist/esm/node_modules/prismjs/components/prism-bash.js +0 -235
- package/dist/esm/node_modules/prismjs/components/prism-clike.js +0 -31
- package/dist/esm/node_modules/prismjs/components/prism-css.js +0 -64
- package/dist/esm/node_modules/prismjs/components/prism-javascript.js +0 -172
- package/dist/esm/node_modules/prismjs/components/prism-json.js +0 -27
- package/dist/esm/node_modules/prismjs/components/prism-jsx.js +0 -143
- package/dist/esm/node_modules/prismjs/components/prism-markup.js +0 -186
- package/dist/esm/node_modules/prismjs/components/prism-scss.js +0 -81
- package/dist/esm/node_modules/prismjs/components/prism-tsx.js +0 -15
- package/dist/esm/node_modules/prismjs/components/prism-typescript.js +0 -60
- package/dist/react/chunks/lottie-72a4c6d4.js +0 -17032
|
@@ -1,134 +1 @@
|
|
|
1
|
-
const clamp = (
|
|
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
|
+
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,140 +1 @@
|
|
|
1
|
-
const startOfDay = (
|
|
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
|
+
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,304 +1 @@
|
|
|
1
|
-
import
|
|
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 };
|
|
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&®ister(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};
|