@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,166 @@
1
- import{applySectionBlockHeader as e}from"./section-block-header-utils.js";import{syncMarketingBlockHost as t}from"./marketing-block-host-utils.js";const i="designbase-wc-section-pricing";class DbSectionPricing extends HTMLElement{constructor(){super(...arguments),this.built=!1}static get observedAttributes(){return["headline","subtitle","description","badge","plans","columns","align","content-padding","size","full-width","full-height","overflow-visible"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build()),this.updateUI()}attributeChangedCallback(){this.built&&this.updateUI()}parsePlans(){try{const e=JSON.parse(this.getAttribute("plans")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBadge(){try{const e=this.getAttribute("badge");return e?JSON.parse(e):null}catch{return null}}build(){this.innerEl=document.createElement("div"),this.innerEl.className=`${i}__inner`,this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-section-block-header",this.headerEl.innerHTML='\n <db-badge class="designbase-wc-section-block-header__badge" hidden></db-badge>\n <h2 class="designbase-wc-section-block-header__headline"></h2>\n <p class="designbase-wc-section-block-header__subtitle"></p>\n <p class="designbase-wc-section-block-header__description"></p>\n ',this.gridEl=document.createElement("div"),this.gridEl.className=`${i}__grid`,this.innerEl.append(this.headerEl,this.gridEl),this.append(this.innerEl)}updateUI(){const n=this.getAttribute("headline")||"요금제",s=this.getAttribute("subtitle")||"",a=this.getAttribute("description")||"",c=this.getAttribute("columns")||"3",r=this.getAttribute("content-padding")||"l",l=this.getAttribute("align")||"center",d=this.parseBadge(),o=this.parsePlans();this.className=[i,`${i}--cols-${c}`,`${i}--padding-${r}`].join(" "),t(this,i),this.headerEl&&e(this.headerEl,{headline:n,subtitle:s,description:a,badge:d,align:l}),this.gridEl&&(this.gridEl.replaceChildren(),o.forEach(e=>{const t=document.createElement("article");t.className=[`${i}__plan-card`,e.highlighted?`${i}__plan-card--highlighted`:""].filter(Boolean).join(" ");const n=document.createElement("div");if(n.className=`${i}__plan-body`,e.badge){const t=document.createElement("db-badge");t.setAttribute("variant","primary"),t.setAttribute("badge-style","filled"),t.setAttribute("size","s"),t.className=`${i}__plan-badge`,t.textContent=e.badge,n.append(t)}const s=document.createElement("h3");s.className=`${i}__plan-name`,s.textContent=e.name;const a=document.createElement("div");a.className=`${i}__price-row`;const c=document.createElement("span");if(c.className=`${i}__price`,c.textContent=e.price,a.append(c),e.period){const t=document.createElement("span");t.className=`${i}__period`,t.textContent=`/ ${e.period}`,a.append(t)}if(n.append(s,a),e.description){const t=document.createElement("p");t.className=`${i}__plan-description`,t.textContent=e.description,n.append(t)}const r=document.createElement("ul");r.className=`${i}__features`,e.features.forEach(e=>{const t=document.createElement("li");t.textContent=e,r.append(t)}),n.append(r);const l=document.createElement("div");l.className=`${i}__plan-footer`;const d=document.createElement("db-button");d.className=`${i}__cta`,d.setAttribute("variant",e.cta.variant||(e.highlighted?"primary":"tertiary")),d.setAttribute("size","m"),d.setAttribute("full-width",""),e.cta.href&&d.setAttribute("href",e.cta.href),d.textContent=e.cta.label,l.append(d),t.append(n,l),this.gridEl.append(t)}))}}customElements.get("db-section-pricing")||customElements.define("db-section-pricing",DbSectionPricing);export{DbSectionPricing};
1
+ import { applySectionBlockHeader } from './section-block-header-utils.js';
2
+ import { syncMarketingBlockHost } from './marketing-block-host-utils.js';
3
+
4
+ const CLASS = 'designbase-wc-section-pricing';
5
+ class DbSectionPricing extends HTMLElement {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.built = false;
9
+ }
10
+ static get observedAttributes() {
11
+ return [
12
+ 'headline',
13
+ 'subtitle',
14
+ 'description',
15
+ 'badge',
16
+ 'plans',
17
+ 'columns',
18
+ 'align',
19
+ 'content-padding',
20
+ 'size',
21
+ 'full-width',
22
+ 'full-height',
23
+ 'overflow-visible',
24
+ ];
25
+ }
26
+ connectedCallback() {
27
+ this.style.display = 'block';
28
+ if (!this.built) {
29
+ this.built = true;
30
+ this.build();
31
+ }
32
+ this.updateUI();
33
+ }
34
+ attributeChangedCallback() {
35
+ if (!this.built)
36
+ return;
37
+ this.updateUI();
38
+ }
39
+ parsePlans() {
40
+ try {
41
+ const parsed = JSON.parse(this.getAttribute('plans') || '[]');
42
+ return Array.isArray(parsed) ? parsed : [];
43
+ }
44
+ catch {
45
+ return [];
46
+ }
47
+ }
48
+ parseBadge() {
49
+ try {
50
+ const raw = this.getAttribute('badge');
51
+ if (!raw)
52
+ return null;
53
+ return JSON.parse(raw);
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ }
59
+ build() {
60
+ this.innerEl = document.createElement('div');
61
+ this.innerEl.className = `${CLASS}__inner`;
62
+ this.headerEl = document.createElement('div');
63
+ this.headerEl.className = 'designbase-wc-section-block-header';
64
+ this.headerEl.innerHTML = `
65
+ <db-badge class="designbase-wc-section-block-header__badge" hidden></db-badge>
66
+ <h2 class="designbase-wc-section-block-header__headline"></h2>
67
+ <p class="designbase-wc-section-block-header__subtitle"></p>
68
+ <p class="designbase-wc-section-block-header__description"></p>
69
+ `;
70
+ this.gridEl = document.createElement('div');
71
+ this.gridEl.className = `${CLASS}__grid`;
72
+ this.innerEl.append(this.headerEl, this.gridEl);
73
+ this.append(this.innerEl);
74
+ }
75
+ updateUI() {
76
+ const headline = this.getAttribute('headline') || '요금제';
77
+ const subtitle = this.getAttribute('subtitle') || '';
78
+ const description = this.getAttribute('description') || '';
79
+ const columns = this.getAttribute('columns') || '3';
80
+ const contentPadding = this.getAttribute('content-padding') || 'l';
81
+ const align = this.getAttribute('align') || 'center';
82
+ const badge = this.parseBadge();
83
+ const plans = this.parsePlans();
84
+ this.className = [CLASS, `${CLASS}--cols-${columns}`, `${CLASS}--padding-${contentPadding}`].join(' ');
85
+ syncMarketingBlockHost(this, CLASS);
86
+ if (this.headerEl) {
87
+ applySectionBlockHeader(this.headerEl, {
88
+ headline,
89
+ subtitle,
90
+ description,
91
+ badge,
92
+ align,
93
+ });
94
+ }
95
+ if (!this.gridEl)
96
+ return;
97
+ this.gridEl.replaceChildren();
98
+ plans.forEach((plan) => {
99
+ const card = document.createElement('article');
100
+ card.className = [
101
+ `${CLASS}__plan-card`,
102
+ plan.highlighted ? `${CLASS}__plan-card--highlighted` : '',
103
+ ]
104
+ .filter(Boolean)
105
+ .join(' ');
106
+ const body = document.createElement('div');
107
+ body.className = `${CLASS}__plan-body`;
108
+ if (plan.badge) {
109
+ const planBadge = document.createElement('db-badge');
110
+ planBadge.setAttribute('variant', 'primary');
111
+ planBadge.setAttribute('badge-style', 'filled');
112
+ planBadge.setAttribute('size', 's');
113
+ planBadge.className = `${CLASS}__plan-badge`;
114
+ planBadge.textContent = plan.badge;
115
+ body.append(planBadge);
116
+ }
117
+ const name = document.createElement('h3');
118
+ name.className = `${CLASS}__plan-name`;
119
+ name.textContent = plan.name;
120
+ const priceRow = document.createElement('div');
121
+ priceRow.className = `${CLASS}__price-row`;
122
+ const price = document.createElement('span');
123
+ price.className = `${CLASS}__price`;
124
+ price.textContent = plan.price;
125
+ priceRow.append(price);
126
+ if (plan.period) {
127
+ const period = document.createElement('span');
128
+ period.className = `${CLASS}__period`;
129
+ period.textContent = `/ ${plan.period}`;
130
+ priceRow.append(period);
131
+ }
132
+ body.append(name, priceRow);
133
+ if (plan.description) {
134
+ const planDesc = document.createElement('p');
135
+ planDesc.className = `${CLASS}__plan-description`;
136
+ planDesc.textContent = plan.description;
137
+ body.append(planDesc);
138
+ }
139
+ const features = document.createElement('ul');
140
+ features.className = `${CLASS}__features`;
141
+ plan.features.forEach((feature) => {
142
+ const li = document.createElement('li');
143
+ li.textContent = feature;
144
+ features.append(li);
145
+ });
146
+ body.append(features);
147
+ const footer = document.createElement('div');
148
+ footer.className = `${CLASS}__plan-footer`;
149
+ const cta = document.createElement('db-button');
150
+ cta.className = `${CLASS}__cta`;
151
+ cta.setAttribute('variant', plan.cta.variant || (plan.highlighted ? 'primary' : 'tertiary'));
152
+ cta.setAttribute('size', 'm');
153
+ cta.setAttribute('full-width', '');
154
+ if (plan.cta.href)
155
+ cta.setAttribute('href', plan.cta.href);
156
+ cta.textContent = plan.cta.label;
157
+ footer.append(cta);
158
+ card.append(body, footer);
159
+ this.gridEl.append(card);
160
+ });
161
+ }
162
+ }
163
+ if (!customElements.get('db-section-pricing'))
164
+ customElements.define('db-section-pricing', DbSectionPricing);
165
+
166
+ export { DbSectionPricing };
@@ -1 +1,129 @@
1
- import{applySectionBlockHeader as t}from"./section-block-header-utils.js";import{syncMarketingBlockHost as e}from"./marketing-block-host-utils.js";const i="designbase-wc-section-stats";class DbSectionStats extends HTMLElement{constructor(){super(...arguments),this.built=!1}static get observedAttributes(){return["headline","subtitle","description","badge","items","columns","tinted","align","content-padding","size","full-width","full-height","overflow-visible"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build()),this.updateUI()}attributeChangedCallback(){this.built&&this.updateUI()}parseItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}parseBadge(){try{const t=this.getAttribute("badge");return t?JSON.parse(t):null}catch{return null}}build(){this.innerEl=document.createElement("div"),this.innerEl.className=`${i}__inner`,this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-section-block-header",this.headerEl.innerHTML='\n <db-badge class="designbase-wc-section-block-header__badge" hidden></db-badge>\n <h2 class="designbase-wc-section-block-header__headline"></h2>\n <p class="designbase-wc-section-block-header__subtitle"></p>\n <p class="designbase-wc-section-block-header__description"></p>\n ',this.gridEl=document.createElement("div"),this.gridEl.className=`${i}__grid`,this.innerEl.append(this.headerEl,this.gridEl),this.append(this.innerEl)}updateUI(){const s=this.getAttribute("headline")||"",n=this.getAttribute("subtitle")||"",a=this.getAttribute("description")||"",r=this.getAttribute("columns")||"4",l=this.getAttribute("content-padding")||"l",d=this.getAttribute("align")||"center",c=this.hasAttribute("tinted"),h=this.parseBadge(),o=this.parseItems();if(this.className=[i,`${i}--cols-${r}`,`${i}--padding-${l}`,c&&`${i}--tinted`].filter(Boolean).join(" "),e(this,i),this.headerEl){const e=s||n||a||h?.text;this.headerEl.hidden=!e,t(this.headerEl,{headline:s,subtitle:n,description:a,badge:h,align:d})}this.gridEl&&(this.gridEl.replaceChildren(),o.forEach(t=>{const e=document.createElement("db-stat");e.setAttribute("value",String(t.value)),e.setAttribute("label",t.label),e.setAttribute("variant","minimal"),e.setAttribute("layout","vertical"),e.setAttribute("size","l"),t.description&&(e.setAttribute("description",t.description),e.setAttribute("show-description","")),e.className=`${i}__stat`,this.gridEl.append(e)}))}}customElements.get("db-section-stats")||customElements.define("db-section-stats",DbSectionStats);export{DbSectionStats};
1
+ import { applySectionBlockHeader } from './section-block-header-utils.js';
2
+ import { syncMarketingBlockHost } from './marketing-block-host-utils.js';
3
+
4
+ const CLASS = 'designbase-wc-section-stats';
5
+ class DbSectionStats extends HTMLElement {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.built = false;
9
+ }
10
+ static get observedAttributes() {
11
+ return [
12
+ 'headline',
13
+ 'subtitle',
14
+ 'description',
15
+ 'badge',
16
+ 'items',
17
+ 'columns',
18
+ 'tinted',
19
+ 'align',
20
+ 'content-padding',
21
+ 'size',
22
+ 'full-width',
23
+ 'full-height',
24
+ 'overflow-visible',
25
+ ];
26
+ }
27
+ connectedCallback() {
28
+ this.style.display = 'block';
29
+ if (!this.built) {
30
+ this.built = true;
31
+ this.build();
32
+ }
33
+ this.updateUI();
34
+ }
35
+ attributeChangedCallback() {
36
+ if (!this.built)
37
+ return;
38
+ this.updateUI();
39
+ }
40
+ parseItems() {
41
+ try {
42
+ const parsed = JSON.parse(this.getAttribute('items') || '[]');
43
+ return Array.isArray(parsed) ? parsed : [];
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ }
49
+ parseBadge() {
50
+ try {
51
+ const raw = this.getAttribute('badge');
52
+ if (!raw)
53
+ return null;
54
+ return JSON.parse(raw);
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ build() {
61
+ this.innerEl = document.createElement('div');
62
+ this.innerEl.className = `${CLASS}__inner`;
63
+ this.headerEl = document.createElement('div');
64
+ this.headerEl.className = 'designbase-wc-section-block-header';
65
+ this.headerEl.innerHTML = `
66
+ <db-badge class="designbase-wc-section-block-header__badge" hidden></db-badge>
67
+ <h2 class="designbase-wc-section-block-header__headline"></h2>
68
+ <p class="designbase-wc-section-block-header__subtitle"></p>
69
+ <p class="designbase-wc-section-block-header__description"></p>
70
+ `;
71
+ this.gridEl = document.createElement('div');
72
+ this.gridEl.className = `${CLASS}__grid`;
73
+ this.innerEl.append(this.headerEl, this.gridEl);
74
+ this.append(this.innerEl);
75
+ }
76
+ updateUI() {
77
+ const headline = this.getAttribute('headline') || '';
78
+ const subtitle = this.getAttribute('subtitle') || '';
79
+ const description = this.getAttribute('description') || '';
80
+ const columns = this.getAttribute('columns') || '4';
81
+ const contentPadding = this.getAttribute('content-padding') || 'l';
82
+ const align = this.getAttribute('align') || 'center';
83
+ const tinted = this.hasAttribute('tinted');
84
+ const badge = this.parseBadge();
85
+ const items = this.parseItems();
86
+ headline || subtitle || description || badge?.text;
87
+ this.className = [
88
+ CLASS,
89
+ `${CLASS}--cols-${columns}`,
90
+ `${CLASS}--padding-${contentPadding}`,
91
+ tinted && `${CLASS}--tinted`,
92
+ ]
93
+ .filter(Boolean)
94
+ .join(' ');
95
+ syncMarketingBlockHost(this, CLASS);
96
+ if (this.headerEl) {
97
+ const hasHeader = headline || subtitle || description || badge?.text;
98
+ this.headerEl.hidden = !hasHeader;
99
+ applySectionBlockHeader(this.headerEl, {
100
+ headline,
101
+ subtitle,
102
+ description,
103
+ badge,
104
+ align,
105
+ });
106
+ }
107
+ if (!this.gridEl)
108
+ return;
109
+ this.gridEl.replaceChildren();
110
+ items.forEach((item) => {
111
+ const stat = document.createElement('db-stat');
112
+ stat.setAttribute('value', String(item.value));
113
+ stat.setAttribute('label', item.label);
114
+ stat.setAttribute('variant', 'minimal');
115
+ stat.setAttribute('layout', 'vertical');
116
+ stat.setAttribute('size', 'l');
117
+ if (item.description) {
118
+ stat.setAttribute('description', item.description);
119
+ stat.setAttribute('show-description', '');
120
+ }
121
+ stat.className = `${CLASS}__stat`;
122
+ this.gridEl.append(stat);
123
+ });
124
+ }
125
+ }
126
+ if (!customElements.get('db-section-stats'))
127
+ customElements.define('db-section-stats', DbSectionStats);
128
+
129
+ export { DbSectionStats };
@@ -1 +1,252 @@
1
- import{createDbIcon as e}from"./db-icons.js";import{applySectionBlockHeader as t}from"./section-block-header-utils.js";import{syncMarketingBlockHost as s}from"./marketing-block-host-utils.js";const i="designbase-wc-section-testimonials";class DbSectionTestimonials extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.carouselIndex=0}static get observedAttributes(){return["headline","subtitle","description","badge","items","variant","columns","align","content-padding","size","full-width","full-height","overflow-visible"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build()),this.updateUI()}disconnectedCallback(){this.resizeObserver?.disconnect(),this.resizeObserver=void 0}attributeChangedCallback(){this.built&&(this.carouselIndex=0,this.updateUI())}parseItems(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBadge(){try{const e=this.getAttribute("badge");return e?JSON.parse(e):null}catch{return null}}buildHeader(e){this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-section-block-header";const t=document.createElement("db-badge");t.className="designbase-wc-section-block-header__badge",t.hidden=!0,t.dataset.role="badge";const s=document.createElement("h2");s.className="designbase-wc-section-block-header__headline",s.dataset.role="headline";const i=document.createElement("p");i.className="designbase-wc-section-block-header__subtitle",i.dataset.role="subtitle";const a=document.createElement("p");a.className="designbase-wc-section-block-header__description",a.dataset.role="description",this.headerEl.append(t,s,i,a),e.append(this.headerEl)}build(){this.innerEl=document.createElement("div"),this.innerEl.className=`${i}__inner`,this.buildHeader(this.innerEl),this.contentEl=document.createElement("div"),this.contentEl.className=`${i}__grid`,this.innerEl.append(this.contentEl),this.append(this.innerEl)}createTestimonialEl(e){const t=document.createElement("db-testimonial");return t.setAttribute("variant","card"),t.setAttribute("quote",e.quote),t.setAttribute("author",e.author),e.role&&t.setAttribute("role",e.role),e.company&&t.setAttribute("company",e.company),e.avatar&&t.setAttribute("avatar",e.avatar),null!=e.rating&&t.setAttribute("rating",String(e.rating)),t.setAttribute("align","center"),t}updateHeader(){this.headerEl&&t(this.headerEl,{headline:this.getAttribute("headline")||"고객 후기",subtitle:this.getAttribute("subtitle")||"",description:this.getAttribute("description")||"",badge:this.parseBadge(),align:this.getAttribute("align")||"center"})}clampCarouselIndex(e){e<=0?this.carouselIndex=0:(this.carouselIndex>=e&&(this.carouselIndex=0),this.carouselIndex<0&&(this.carouselIndex=0))}updateCarouselTransform(){if(!this.carouselViewport||!this.carouselTrack)return;const e=this.carouselViewport.clientWidth;this.carouselTrack.style.transform=`translate3d(-${this.carouselIndex*e}px, 0, 0)`,this.carouselIndicator&&this.carouselIndicator.setAttribute("current",String(this.carouselIndex))}goToCarouselSlide(e,t){t<=0||(this.carouselIndex=Math.max(0,Math.min(e,t-1)),this.updateCarouselTransform())}renderGrid(e){this.contentEl&&(this.resizeObserver?.disconnect(),this.resizeObserver=void 0,this.carouselViewport=void 0,this.carouselTrack=void 0,this.carouselIndicator=void 0,this.contentEl.className=`${i}__grid`,this.contentEl.replaceChildren(),e.forEach(e=>{this.contentEl.append(this.createTestimonialEl(e))}))}renderCarousel(t){if(!this.contentEl)return;if(this.contentEl.replaceChildren(),this.contentEl.className=`${i}__carousel`,this.clampCarouselIndex(t.length),0===t.length)return;const s=document.createElement("div");s.className=`${i}__carousel-viewport`;const a=document.createElement("div");if(a.className=`${i}__carousel-track`,t.forEach(e=>{const t=document.createElement("div");t.className=`${i}__carousel-slide`,t.append(this.createTestimonialEl(e)),a.append(t)}),s.append(a),this.carouselViewport=s,this.carouselTrack=a,t.length>1){const a=document.createElement("button");a.type="button",a.className=`${i}__carousel-nav ${i}__carousel-nav--prev`,a.setAttribute("aria-label","이전 후기"),a.append(e("chevron-left",20)),a.addEventListener("click",()=>{const e=this.carouselIndex-1;this.goToCarouselSlide(e<0?t.length-1:e,t.length)});const r=document.createElement("button");r.type="button",r.className=`${i}__carousel-nav ${i}__carousel-nav--next`,r.setAttribute("aria-label","다음 후기"),r.append(e("chevron-right",20)),r.addEventListener("click",()=>{const e=this.carouselIndex+1;this.goToCarouselSlide(e>=t.length?0:e,t.length)}),s.append(a,r);const n=document.createElement("div");n.className=`${i}__carousel-controls`;const l=document.createElement("db-indicator");l.className=`${i}__carousel-indicator`,l.setAttribute("current",String(this.carouselIndex)),l.setAttribute("total",String(t.length)),l.setAttribute("type","dots"),l.setAttribute("size","s"),l.setAttribute("clickable",""),l.addEventListener("db-step-click",e=>{const s=e;this.goToCarouselSlide(s.detail.index,t.length)}),this.carouselIndicator=l,n.append(l),this.contentEl.append(s,n)}else this.contentEl.append(s);this.resizeObserver?.disconnect(),this.resizeObserver=new ResizeObserver(()=>this.updateCarouselTransform()),this.resizeObserver.observe(s),requestAnimationFrame(()=>this.updateCarouselTransform())}updateUI(){const e=this.getAttribute("variant")||"grid",t=this.getAttribute("columns")||"3",a=this.getAttribute("content-padding")||"l",r=this.parseItems();this.className=[i,`${i}--${e}`,`${i}--cols-${t}`,`${i}--padding-${a}`].join(" "),s(this,i),this.updateHeader(),"carousel"===e?this.renderCarousel(r):this.renderGrid(r)}}customElements.get("db-section-testimonials")||customElements.define("db-section-testimonials",DbSectionTestimonials);export{DbSectionTestimonials};
1
+ import { createDbIcon } from './db-icons.js';
2
+ import { applySectionBlockHeader } from './section-block-header-utils.js';
3
+ import { syncMarketingBlockHost } from './marketing-block-host-utils.js';
4
+
5
+ const CLASS = 'designbase-wc-section-testimonials';
6
+ class DbSectionTestimonials extends HTMLElement {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.built = false;
10
+ this.carouselIndex = 0;
11
+ }
12
+ static get observedAttributes() {
13
+ return [
14
+ 'headline',
15
+ 'subtitle',
16
+ 'description',
17
+ 'badge',
18
+ 'items',
19
+ 'variant',
20
+ 'columns',
21
+ 'align',
22
+ 'content-padding',
23
+ 'size',
24
+ 'full-width',
25
+ 'full-height',
26
+ 'overflow-visible',
27
+ ];
28
+ }
29
+ connectedCallback() {
30
+ this.style.display = 'block';
31
+ if (!this.built) {
32
+ this.built = true;
33
+ this.build();
34
+ }
35
+ this.updateUI();
36
+ }
37
+ disconnectedCallback() {
38
+ this.resizeObserver?.disconnect();
39
+ this.resizeObserver = undefined;
40
+ }
41
+ attributeChangedCallback() {
42
+ if (!this.built)
43
+ return;
44
+ this.carouselIndex = 0;
45
+ this.updateUI();
46
+ }
47
+ parseItems() {
48
+ try {
49
+ const parsed = JSON.parse(this.getAttribute('items') || '[]');
50
+ return Array.isArray(parsed) ? parsed : [];
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ }
56
+ parseBadge() {
57
+ try {
58
+ const raw = this.getAttribute('badge');
59
+ if (!raw)
60
+ return null;
61
+ return JSON.parse(raw);
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ buildHeader(parent) {
68
+ this.headerEl = document.createElement('div');
69
+ this.headerEl.className = 'designbase-wc-section-block-header';
70
+ const badge = document.createElement('db-badge');
71
+ badge.className = 'designbase-wc-section-block-header__badge';
72
+ badge.hidden = true;
73
+ badge.dataset.role = 'badge';
74
+ const headline = document.createElement('h2');
75
+ headline.className = 'designbase-wc-section-block-header__headline';
76
+ headline.dataset.role = 'headline';
77
+ const subtitle = document.createElement('p');
78
+ subtitle.className = 'designbase-wc-section-block-header__subtitle';
79
+ subtitle.dataset.role = 'subtitle';
80
+ const description = document.createElement('p');
81
+ description.className = 'designbase-wc-section-block-header__description';
82
+ description.dataset.role = 'description';
83
+ this.headerEl.append(badge, headline, subtitle, description);
84
+ parent.append(this.headerEl);
85
+ }
86
+ build() {
87
+ this.innerEl = document.createElement('div');
88
+ this.innerEl.className = `${CLASS}__inner`;
89
+ this.buildHeader(this.innerEl);
90
+ this.contentEl = document.createElement('div');
91
+ this.contentEl.className = `${CLASS}__grid`;
92
+ this.innerEl.append(this.contentEl);
93
+ this.append(this.innerEl);
94
+ }
95
+ createTestimonialEl(item) {
96
+ const el = document.createElement('db-testimonial');
97
+ el.setAttribute('variant', 'card');
98
+ el.setAttribute('quote', item.quote);
99
+ el.setAttribute('author', item.author);
100
+ if (item.role)
101
+ el.setAttribute('role', item.role);
102
+ if (item.company)
103
+ el.setAttribute('company', item.company);
104
+ if (item.avatar)
105
+ el.setAttribute('avatar', item.avatar);
106
+ if (item.rating != null)
107
+ el.setAttribute('rating', String(item.rating));
108
+ el.setAttribute('align', 'center');
109
+ return el;
110
+ }
111
+ updateHeader() {
112
+ if (!this.headerEl)
113
+ return;
114
+ applySectionBlockHeader(this.headerEl, {
115
+ headline: this.getAttribute('headline') || '고객 후기',
116
+ subtitle: this.getAttribute('subtitle') || '',
117
+ description: this.getAttribute('description') || '',
118
+ badge: this.parseBadge(),
119
+ align: this.getAttribute('align') || 'center',
120
+ });
121
+ }
122
+ clampCarouselIndex(count) {
123
+ if (count <= 0) {
124
+ this.carouselIndex = 0;
125
+ return;
126
+ }
127
+ if (this.carouselIndex >= count)
128
+ this.carouselIndex = 0;
129
+ if (this.carouselIndex < 0)
130
+ this.carouselIndex = 0;
131
+ }
132
+ updateCarouselTransform() {
133
+ if (!this.carouselViewport || !this.carouselTrack)
134
+ return;
135
+ const width = this.carouselViewport.clientWidth;
136
+ this.carouselTrack.style.transform = `translate3d(-${this.carouselIndex * width}px, 0, 0)`;
137
+ if (this.carouselIndicator) {
138
+ this.carouselIndicator.setAttribute('current', String(this.carouselIndex));
139
+ }
140
+ }
141
+ goToCarouselSlide(index, count) {
142
+ if (count <= 0)
143
+ return;
144
+ this.carouselIndex = Math.max(0, Math.min(index, count - 1));
145
+ this.updateCarouselTransform();
146
+ }
147
+ renderGrid(items) {
148
+ if (!this.contentEl)
149
+ return;
150
+ this.resizeObserver?.disconnect();
151
+ this.resizeObserver = undefined;
152
+ this.carouselViewport = undefined;
153
+ this.carouselTrack = undefined;
154
+ this.carouselIndicator = undefined;
155
+ this.contentEl.className = `${CLASS}__grid`;
156
+ this.contentEl.replaceChildren();
157
+ items.forEach((item) => {
158
+ this.contentEl.append(this.createTestimonialEl(item));
159
+ });
160
+ }
161
+ renderCarousel(items) {
162
+ if (!this.contentEl)
163
+ return;
164
+ this.contentEl.replaceChildren();
165
+ this.contentEl.className = `${CLASS}__carousel`;
166
+ this.clampCarouselIndex(items.length);
167
+ if (items.length === 0)
168
+ return;
169
+ const viewport = document.createElement('div');
170
+ viewport.className = `${CLASS}__carousel-viewport`;
171
+ const track = document.createElement('div');
172
+ track.className = `${CLASS}__carousel-track`;
173
+ items.forEach((item) => {
174
+ const slide = document.createElement('div');
175
+ slide.className = `${CLASS}__carousel-slide`;
176
+ slide.append(this.createTestimonialEl(item));
177
+ track.append(slide);
178
+ });
179
+ viewport.append(track);
180
+ this.carouselViewport = viewport;
181
+ this.carouselTrack = track;
182
+ if (items.length > 1) {
183
+ const prev = document.createElement('button');
184
+ prev.type = 'button';
185
+ prev.className = `${CLASS}__carousel-nav ${CLASS}__carousel-nav--prev`;
186
+ prev.setAttribute('aria-label', '이전 후기');
187
+ prev.append(createDbIcon('chevron-left', 20));
188
+ prev.addEventListener('click', () => {
189
+ const next = this.carouselIndex - 1;
190
+ this.goToCarouselSlide(next < 0 ? items.length - 1 : next, items.length);
191
+ });
192
+ const next = document.createElement('button');
193
+ next.type = 'button';
194
+ next.className = `${CLASS}__carousel-nav ${CLASS}__carousel-nav--next`;
195
+ next.setAttribute('aria-label', '다음 후기');
196
+ next.append(createDbIcon('chevron-right', 20));
197
+ next.addEventListener('click', () => {
198
+ const nextIndex = this.carouselIndex + 1;
199
+ this.goToCarouselSlide(nextIndex >= items.length ? 0 : nextIndex, items.length);
200
+ });
201
+ viewport.append(prev, next);
202
+ const controls = document.createElement('div');
203
+ controls.className = `${CLASS}__carousel-controls`;
204
+ const indicator = document.createElement('db-indicator');
205
+ indicator.className = `${CLASS}__carousel-indicator`;
206
+ indicator.setAttribute('current', String(this.carouselIndex));
207
+ indicator.setAttribute('total', String(items.length));
208
+ indicator.setAttribute('type', 'dots');
209
+ indicator.setAttribute('size', 's');
210
+ indicator.setAttribute('clickable', '');
211
+ indicator.addEventListener('db-step-click', ((event) => {
212
+ const customEvent = event;
213
+ this.goToCarouselSlide(customEvent.detail.index, items.length);
214
+ }));
215
+ this.carouselIndicator = indicator;
216
+ controls.append(indicator);
217
+ this.contentEl.append(viewport, controls);
218
+ }
219
+ else {
220
+ this.contentEl.append(viewport);
221
+ }
222
+ this.resizeObserver?.disconnect();
223
+ this.resizeObserver = new ResizeObserver(() => this.updateCarouselTransform());
224
+ this.resizeObserver.observe(viewport);
225
+ requestAnimationFrame(() => this.updateCarouselTransform());
226
+ }
227
+ updateUI() {
228
+ const variant = this.getAttribute('variant') || 'grid';
229
+ const columns = this.getAttribute('columns') || '3';
230
+ const contentPadding = this.getAttribute('content-padding') || 'l';
231
+ const items = this.parseItems();
232
+ this.className = [
233
+ CLASS,
234
+ `${CLASS}--${variant}`,
235
+ `${CLASS}--cols-${columns}`,
236
+ `${CLASS}--padding-${contentPadding}`,
237
+ ].join(' ');
238
+ syncMarketingBlockHost(this, CLASS);
239
+ this.updateHeader();
240
+ if (variant === 'carousel') {
241
+ this.renderCarousel(items);
242
+ }
243
+ else {
244
+ this.renderGrid(items);
245
+ }
246
+ }
247
+ }
248
+ if (!customElements.get('db-section-testimonials')) {
249
+ customElements.define('db-section-testimonials', DbSectionTestimonials);
250
+ }
251
+
252
+ export { DbSectionTestimonials };