@designbasekorea/ui-wc 0.5.5 → 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 (155) 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.esm.js +39373 -1
  153. package/package.json +1 -1
  154. package/dist/chunks/lottie-2637aa0f.js +0 -1
  155. package/dist/react/chunks/lottie-14e7addb.js +0 -1
@@ -1 +1,139 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e=["s","m","l"],i=["primary","secondary","tertiary"],s={s:12,m:16,l:20},n={s:"xs",m:"s",l:"m"};class DbFloatingActionButton extends HTMLElement{constructor(){super(...arguments),this.handleClick=t=>{if(this.disabled||this.loading)return t.preventDefault(),void t.stopPropagation();this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))}}static get observedAttributes(){return["size","variant","icon","loading","disabled","aria-label"]}get size(){const t=this.getAttribute("size")||"m";return e.includes(t)?t:"m"}set size(t){this.setAttribute("size",t)}get variant(){const t=this.getAttribute("variant")||"primary";return i.includes(t)?t:"primary"}set variant(t){this.setAttribute("variant",t)}get loading(){return this.hasAttribute("loading")}set loading(t){this.toggleAttribute("loading",Boolean(t))}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",Boolean(t))}connectedCallback(){"button"!==this.getAttribute("role")&&this.setAttribute("role","button"),this.hasAttribute("type")||this.setAttribute("type","button"),this.addEventListener("click",this.handleClick),this.sync()}disconnectedCallback(){this.removeEventListener("click",this.handleClick)}attributeChangedCallback(){this.isConnected&&this.sync()}resolveIconName(t){if(!t)return;return t in{plus:1,search:1,settings:1,edit:1,close:1}?t:void 0}sync(){this.className=["designbase-wc-fab",`designbase-wc-fab--${this.size}`,`designbase-wc-fab--${this.variant}`,this.disabled&&"designbase-wc-fab--disabled",this.loading&&"designbase-wc-fab--loading"].filter(Boolean).join(" ");const e=this.getAttribute("aria-label")||"Floating action button";this.getAttribute("aria-label")!==e&&this.setAttribute("aria-label",e);const i=String(this.loading);this.getAttribute("aria-busy")!==i&&this.setAttribute("aria-busy",i);const a=String(this.disabled||this.loading);this.getAttribute("aria-disabled")!==a&&this.setAttribute("aria-disabled",a);let r=this.querySelector(":scope > .designbase-wc-fab__icon");if(r||(r=document.createElement("div"),r.className="designbase-wc-fab__icon",this.append(r)),r.replaceChildren(),this.loading){const t=document.createElement("span");return t.className=`designbase-wc-spinner designbase-wc-spinner--circular designbase-wc-spinner--${n[this.size]}`,t.setAttribute("aria-hidden","true"),t.innerHTML='<svg class="designbase-wc-spinner__circular" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><circle class="designbase-wc-spinner__circular-track" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"></circle><circle class="designbase-wc-spinner__circular-indicator" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"></circle></svg>',void r.append(t)}const c=this.getAttribute("icon"),o=this.resolveIconName(c);if(o)return void r.append(t(o,s[this.size]));const l=Array.from(this.children).find(t=>t!==r&&!t.hasAttribute("data-wc-internal"));l&&!l.isConnected&&r.append(l)}}customElements.get("db-floating-action-button")||customElements.define("db-floating-action-button",DbFloatingActionButton);export{DbFloatingActionButton};
1
+ import { createDbIcon } from './db-icons.js';
2
+
3
+ const SIZES = ['s', 'm', 'l'];
4
+ const VARIANTS = ['primary', 'secondary', 'tertiary'];
5
+ const CIRCULAR_SPINNER_HTML = '<svg class="designbase-wc-spinner__circular" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><circle class="designbase-wc-spinner__circular-track" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"></circle><circle class="designbase-wc-spinner__circular-indicator" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"></circle></svg>';
6
+ const ICON_SIZE = {
7
+ s: 12,
8
+ m: 16,
9
+ l: 20,
10
+ };
11
+ const SPINNER_SIZE = {
12
+ s: 'xs',
13
+ m: 's',
14
+ l: 'm',
15
+ };
16
+ class DbFloatingActionButton extends HTMLElement {
17
+ constructor() {
18
+ super(...arguments);
19
+ this.handleClick = (event) => {
20
+ if (this.disabled || this.loading) {
21
+ event.preventDefault();
22
+ event.stopPropagation();
23
+ return;
24
+ }
25
+ this.dispatchEvent(new CustomEvent('db-click', { bubbles: true, composed: true }));
26
+ };
27
+ }
28
+ static get observedAttributes() {
29
+ return ['size', 'variant', 'icon', 'loading', 'disabled', 'aria-label'];
30
+ }
31
+ get size() {
32
+ const raw = this.getAttribute('size') || 'm';
33
+ return SIZES.includes(raw) ? raw : 'm';
34
+ }
35
+ set size(value) {
36
+ this.setAttribute('size', value);
37
+ }
38
+ get variant() {
39
+ const raw = this.getAttribute('variant') || 'primary';
40
+ return VARIANTS.includes(raw) ? raw : 'primary';
41
+ }
42
+ set variant(value) {
43
+ this.setAttribute('variant', value);
44
+ }
45
+ get loading() {
46
+ return this.hasAttribute('loading');
47
+ }
48
+ set loading(value) {
49
+ this.toggleAttribute('loading', Boolean(value));
50
+ }
51
+ get disabled() {
52
+ return this.hasAttribute('disabled');
53
+ }
54
+ set disabled(value) {
55
+ this.toggleAttribute('disabled', Boolean(value));
56
+ }
57
+ connectedCallback() {
58
+ if (this.getAttribute('role') !== 'button') {
59
+ this.setAttribute('role', 'button');
60
+ }
61
+ if (!this.hasAttribute('type')) {
62
+ this.setAttribute('type', 'button');
63
+ }
64
+ this.addEventListener('click', this.handleClick);
65
+ this.sync();
66
+ }
67
+ disconnectedCallback() {
68
+ this.removeEventListener('click', this.handleClick);
69
+ }
70
+ attributeChangedCallback() {
71
+ if (this.isConnected)
72
+ this.sync();
73
+ }
74
+ resolveIconName(icon) {
75
+ if (!icon)
76
+ return undefined;
77
+ const known = {
78
+ plus: 1,
79
+ search: 1,
80
+ settings: 1,
81
+ edit: 1,
82
+ close: 1,
83
+ };
84
+ return icon in known ? icon : undefined;
85
+ }
86
+ sync() {
87
+ this.className = [
88
+ 'designbase-wc-fab',
89
+ `designbase-wc-fab--${this.size}`,
90
+ `designbase-wc-fab--${this.variant}`,
91
+ this.disabled && 'designbase-wc-fab--disabled',
92
+ this.loading && 'designbase-wc-fab--loading',
93
+ ]
94
+ .filter(Boolean)
95
+ .join(' ');
96
+ const label = this.getAttribute('aria-label') || 'Floating action button';
97
+ if (this.getAttribute('aria-label') !== label) {
98
+ this.setAttribute('aria-label', label);
99
+ }
100
+ const busy = String(this.loading);
101
+ if (this.getAttribute('aria-busy') !== busy) {
102
+ this.setAttribute('aria-busy', busy);
103
+ }
104
+ const ariaDisabled = String(this.disabled || this.loading);
105
+ if (this.getAttribute('aria-disabled') !== ariaDisabled) {
106
+ this.setAttribute('aria-disabled', ariaDisabled);
107
+ }
108
+ let iconHost = this.querySelector(':scope > .designbase-wc-fab__icon');
109
+ if (!iconHost) {
110
+ iconHost = document.createElement('div');
111
+ iconHost.className = 'designbase-wc-fab__icon';
112
+ this.append(iconHost);
113
+ }
114
+ iconHost.replaceChildren();
115
+ if (this.loading) {
116
+ const spinner = document.createElement('span');
117
+ spinner.className = `designbase-wc-spinner designbase-wc-spinner--circular designbase-wc-spinner--${SPINNER_SIZE[this.size]}`;
118
+ spinner.setAttribute('aria-hidden', 'true');
119
+ spinner.innerHTML = CIRCULAR_SPINNER_HTML;
120
+ iconHost.append(spinner);
121
+ return;
122
+ }
123
+ const iconAttr = this.getAttribute('icon');
124
+ const iconName = this.resolveIconName(iconAttr);
125
+ if (iconName) {
126
+ iconHost.append(createDbIcon(iconName, ICON_SIZE[this.size]));
127
+ return;
128
+ }
129
+ const slottedIcon = Array.from(this.children).find((child) => child !== iconHost && !child.hasAttribute('data-wc-internal'));
130
+ if (slottedIcon && !slottedIcon.isConnected) {
131
+ iconHost.append(slottedIcon);
132
+ }
133
+ }
134
+ }
135
+ if (!customElements.get('db-floating-action-button')) {
136
+ customElements.define('db-floating-action-button', DbFloatingActionButton);
137
+ }
138
+
139
+ export { DbFloatingActionButton };
@@ -1 +1,385 @@
1
- import{createShareIcon as e}from"./db-share-icons.js";const t=["default","compact","minimal"],s=["s","m","l"],n={youtube:"youtube",instagram:"instagram",x:"x",linkedin:"linkedin",facebook:"facebook",email:"mail"};function parseJson(e,t){if(!e)return t;try{return JSON.parse(e)??t}catch{return t}}class DbFooter extends HTMLElement{static get observedAttributes(){return["columns","legal-links","social-links","company-info","family-sites","tagline","copyright","logo-type","variant","size","full-width","show-logo","show-social","family-site-label"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}get columns(){return parseJson(this.getAttribute("columns"),[])}set columns(e){this.setAttribute("columns","string"==typeof e?e:JSON.stringify(e))}get legalLinks(){return parseJson(this.getAttribute("legal-links"),[])}set legalLinks(e){this.setAttribute("legal-links","string"==typeof e?e:JSON.stringify(e))}get socialLinks(){return parseJson(this.getAttribute("social-links"),[])}set socialLinks(e){this.setAttribute("social-links","string"==typeof e?e:JSON.stringify(e))}get companyInfo(){return parseJson(this.getAttribute("company-info"),{})}set companyInfo(e){this.setAttribute("company-info","string"==typeof e?e:JSON.stringify(e))}get familySites(){return parseJson(this.getAttribute("family-sites"),[])}set familySites(e){this.setAttribute("family-sites","string"==typeof e?e:JSON.stringify(e))}syncHostClasses(){const e=this.getAttribute("size")||"m",n=this.getAttribute("variant")||"default",a=s.includes(e)?e:"m",i=t.includes(n)?n:"default";this.className=["designbase-wc-footer",`designbase-wc-footer--${a}`,`designbase-wc-footer--${i}`,this.hasAttribute("full-width")&&"designbase-wc-footer--full-width"].filter(Boolean).join(" ")}dispatchLinkClick(e,t){this.dispatchEvent(new CustomEvent("db-link-click",{bubbles:!0,composed:!0,detail:{link:e,source:t}}))}createLink(e,t,s){const n=document.createElement("a");return n.href=e.href||"#",n.className=[t,e.emphasize&&`${t}--emphasize`].filter(Boolean).join(" "),n.textContent=e.label,e.external&&(n.target="_blank",n.rel="noopener noreferrer"),n.addEventListener("click",t=>{t.preventDefault(),this.dispatchLinkClick(e,s)}),n}createSocialLink(t,s){const a=document.createElement("a");a.href=t.href,a.className="designbase-wc-footer__social-link",a.target="_blank",a.rel="noopener noreferrer",a.setAttribute("aria-label",t.label||t.platform);const i=n[t.platform]||"share-alt";return a.append(e(i,s)),a.addEventListener("click",e=>{e.preventDefault(),this.dispatchEvent(new CustomEvent("db-social-click",{bubbles:!0,composed:!0,detail:{link:t}}))}),a}createCompanyInfoRows(e){const t=[],s=[];e.companyName&&s.push(e.companyName),e.representative&&s.push(`대표: ${e.representative}`),e.businessNumber&&s.push(`사업자등록번호: ${e.businessNumber}`),s.length&&t.push(s.join(" | "));const n=[];e.address&&n.push(e.address),e.phone&&n.push(`대표전화: ${e.phone}`),e.customerCenter&&n.push(`고객센터: ${e.customerCenter}`),n.length&&t.push(n.join(" | "));const a=[];return e.email&&a.push(`이메일: ${e.email}`),e.mailOrderNumber&&a.push(`통신판매업신고: ${e.mailOrderNumber}`),e.hostingProvider&&a.push(`호스팅: ${e.hostingProvider}`),a.length&&t.push(a.join(" | ")),t}showLogo(){return!this.hasAttribute("show-logo")||"false"!==this.getAttribute("show-logo")}createLogo(){const e=document.createElement("div");e.className="designbase-wc-footer__logo";const t=document.createElement("db-logo");return t.setAttribute("type",this.getAttribute("logo-type")||"designbase"),t.setAttribute("size","s"),t.setAttribute("clickable",""),t.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),e.append(t),e}renderBrand(e,t={}){const{showTagline:s=!0}=t,n=document.createElement("div");n.className="designbase-wc-footer__brand",this.showLogo()&&n.append(this.createLogo());const a=this.getAttribute("tagline");if(s&&a){const e=document.createElement("p");e.className="designbase-wc-footer__tagline",e.textContent=a,n.append(e)}const i=this.socialLinks;if(i.length&&(!this.hasAttribute("show-social")||"false"!==this.getAttribute("show-social"))){const t=document.createElement("div");t.className="designbase-wc-footer__social",i.forEach(s=>t.append(this.createSocialLink(s,e))),n.append(t)}return n}renderColumns(e){if(!e.length)return null;const t=document.createElement("div");return t.className="designbase-wc-footer__columns",t.style.setProperty("--db-footer-columns",String(Math.min(e.length,4))),e.forEach(e=>{const s=document.createElement("div");s.className="designbase-wc-footer__column";const n=document.createElement("h3");n.className="designbase-wc-footer__column-title",n.textContent=e.title,s.append(n);const a=document.createElement("ul");a.className="designbase-wc-footer__column-list",e.items.forEach(e=>{const t=document.createElement("li");t.append(this.createLink(e,"designbase-wc-footer__column-link","column")),a.append(t)}),s.append(a),t.append(s)}),t}createLegalNav(e){const t=document.createElement("nav");t.className="designbase-wc-footer__legal-nav",t.setAttribute("aria-label","법적 고지");const s=document.createElement("ul");return s.className="designbase-wc-footer__legal-list",e.forEach((t,n)=>{const a=document.createElement("li");if(a.append(this.createLink(t,"designbase-wc-footer__legal-link","legal")),s.append(a),n<e.length-1){const e=document.createElement("span");e.className="designbase-wc-footer__legal-divider",e.setAttribute("aria-hidden","true"),e.textContent="|",a.append(e)}}),t.append(s),t}renderLegalBar(e,t){if(!e.length&&!t.length)return null;const s=document.createElement("div");if(s.className="designbase-wc-footer__legal-bar",e.length&&s.append(this.createLegalNav(e)),t.length){const e=document.createElement("div");e.className="designbase-wc-footer__family-site";const n=document.createElement("select");n.className="designbase-wc-footer__family-select",n.setAttribute("aria-label",this.getAttribute("family-site-label")||"패밀리 사이트");const a=document.createElement("option");a.value="",a.textContent=this.getAttribute("family-site-label")||"패밀리 사이트",a.disabled=!0,a.selected=!0,n.append(a),t.forEach(e=>{const t=document.createElement("option");t.value=e.href,t.textContent=e.label,t.dataset.id=e.id,n.append(t)}),n.addEventListener("change",()=>{const e=t.find(e=>e.href===n.value);e&&(n.selectedIndex=0,this.dispatchEvent(new CustomEvent("db-family-site-change",{bubbles:!0,composed:!0,detail:{site:e}})))}),e.append(n),s.append(e)}return s}renderCompanyInfo(e){const t=this.createCompanyInfoRows(e);if(!t.length)return null;const s=document.createElement("div");return s.className="designbase-wc-footer__company",t.forEach(e=>{const t=document.createElement("p");t.className="designbase-wc-footer__company-line",t.textContent=e,s.append(t)}),s}createCopyright(e){const t=document.createElement("div");t.className="designbase-wc-footer__bottom";const s=document.createElement("p");return s.className="designbase-wc-footer__copyright",s.textContent=e,t.append(s),t}renderMinimal(e,t,s){const n=document.createElement("div");n.className="designbase-wc-footer__minimal-bar";const a=document.createElement("div");if(a.className="designbase-wc-footer__minimal-start",this.showLogo()&&a.append(this.createLogo()),n.append(a),t.length){const e=document.createElement("div");e.className="designbase-wc-footer__minimal-legal",e.append(this.createLegalNav(t)),n.append(e)}e.append(n),e.append(this.createCopyright(s))}render(){this.syncHostClasses(),this.setAttribute("role","contentinfo");const e=this.getAttribute("variant")||"default",t=this.getAttribute("size")||"m",s="s"===t?18:"l"===t?22:20,n="default"===e?this.columns:[],a=this.legalLinks,i=this.companyInfo,o=this.familySites,r=this.getAttribute("copyright")||`© ${(new Date).getFullYear()} Designbase. All rights reserved.`;this.replaceChildren();const l=document.createElement("div");if(l.className=["designbase-wc-footer__container",this.hasAttribute("full-width")&&"designbase-wc-footer__container--full-width"].filter(Boolean).join(" "),"minimal"===e)return this.renderMinimal(l,a,r),void this.append(l);const c=document.createElement("div");c.className="designbase-wc-footer__top",c.append(this.renderBrand(s,{showTagline:"compact"!==e}));const d=this.renderColumns(n);d&&c.append(d),l.append(c);const m=this.renderLegalBar(a,o);m&&l.append(m);const u=this.renderCompanyInfo(i);u&&l.append(u),l.append(this.createCopyright(r)),this.append(l)}}customElements.get("db-footer")||customElements.define("db-footer",DbFooter);export{DbFooter};
1
+ import { createShareIcon } from './db-share-icons.js';
2
+
3
+ const VARIANTS = ['default', 'compact', 'minimal'];
4
+ const SIZES = ['s', 'm', 'l'];
5
+ const SOCIAL_ICON_MAP = {
6
+ youtube: 'youtube',
7
+ instagram: 'instagram',
8
+ x: 'x',
9
+ linkedin: 'linkedin',
10
+ facebook: 'facebook',
11
+ email: 'mail',
12
+ };
13
+ function parseJson(raw, fallback) {
14
+ if (!raw)
15
+ return fallback;
16
+ try {
17
+ const parsed = JSON.parse(raw);
18
+ return parsed ?? fallback;
19
+ }
20
+ catch {
21
+ return fallback;
22
+ }
23
+ }
24
+ class DbFooter extends HTMLElement {
25
+ static get observedAttributes() {
26
+ return [
27
+ 'columns',
28
+ 'legal-links',
29
+ 'social-links',
30
+ 'company-info',
31
+ 'family-sites',
32
+ 'tagline',
33
+ 'copyright',
34
+ 'logo-type',
35
+ 'variant',
36
+ 'size',
37
+ 'full-width',
38
+ 'show-logo',
39
+ 'show-social',
40
+ 'family-site-label',
41
+ ];
42
+ }
43
+ connectedCallback() {
44
+ this.render();
45
+ }
46
+ attributeChangedCallback() {
47
+ if (!this.isConnected)
48
+ return;
49
+ this.render();
50
+ }
51
+ get columns() {
52
+ return parseJson(this.getAttribute('columns'), []);
53
+ }
54
+ set columns(value) {
55
+ this.setAttribute('columns', typeof value === 'string' ? value : JSON.stringify(value));
56
+ }
57
+ get legalLinks() {
58
+ return parseJson(this.getAttribute('legal-links'), []);
59
+ }
60
+ set legalLinks(value) {
61
+ this.setAttribute('legal-links', typeof value === 'string' ? value : JSON.stringify(value));
62
+ }
63
+ get socialLinks() {
64
+ return parseJson(this.getAttribute('social-links'), []);
65
+ }
66
+ set socialLinks(value) {
67
+ this.setAttribute('social-links', typeof value === 'string' ? value : JSON.stringify(value));
68
+ }
69
+ get companyInfo() {
70
+ return parseJson(this.getAttribute('company-info'), {});
71
+ }
72
+ set companyInfo(value) {
73
+ this.setAttribute('company-info', typeof value === 'string' ? value : JSON.stringify(value));
74
+ }
75
+ get familySites() {
76
+ return parseJson(this.getAttribute('family-sites'), []);
77
+ }
78
+ set familySites(value) {
79
+ this.setAttribute('family-sites', typeof value === 'string' ? value : JSON.stringify(value));
80
+ }
81
+ syncHostClasses() {
82
+ const size = this.getAttribute('size') || 'm';
83
+ const variant = this.getAttribute('variant') || 'default';
84
+ const safeSize = SIZES.includes(size) ? size : 'm';
85
+ const safeVariant = VARIANTS.includes(variant) ? variant : 'default';
86
+ this.className = [
87
+ 'designbase-wc-footer',
88
+ `designbase-wc-footer--${safeSize}`,
89
+ `designbase-wc-footer--${safeVariant}`,
90
+ this.hasAttribute('full-width') && 'designbase-wc-footer--full-width',
91
+ ]
92
+ .filter(Boolean)
93
+ .join(' ');
94
+ }
95
+ dispatchLinkClick(link, source) {
96
+ this.dispatchEvent(new CustomEvent('db-link-click', {
97
+ bubbles: true,
98
+ composed: true,
99
+ detail: { link, source },
100
+ }));
101
+ }
102
+ createLink(link, className, source) {
103
+ const anchor = document.createElement('a');
104
+ anchor.href = link.href || '#';
105
+ anchor.className = [
106
+ className,
107
+ link.emphasize && `${className}--emphasize`,
108
+ ]
109
+ .filter(Boolean)
110
+ .join(' ');
111
+ anchor.textContent = link.label;
112
+ if (link.external) {
113
+ anchor.target = '_blank';
114
+ anchor.rel = 'noopener noreferrer';
115
+ }
116
+ anchor.addEventListener('click', (event) => {
117
+ event.preventDefault();
118
+ this.dispatchLinkClick(link, source);
119
+ });
120
+ return anchor;
121
+ }
122
+ createSocialLink(link, iconPx) {
123
+ const anchor = document.createElement('a');
124
+ anchor.href = link.href;
125
+ anchor.className = 'designbase-wc-footer__social-link';
126
+ anchor.target = '_blank';
127
+ anchor.rel = 'noopener noreferrer';
128
+ anchor.setAttribute('aria-label', link.label || link.platform);
129
+ const iconName = SOCIAL_ICON_MAP[link.platform] || 'share-alt';
130
+ anchor.append(createShareIcon(iconName, iconPx));
131
+ anchor.addEventListener('click', (event) => {
132
+ event.preventDefault();
133
+ this.dispatchEvent(new CustomEvent('db-social-click', {
134
+ bubbles: true,
135
+ composed: true,
136
+ detail: { link },
137
+ }));
138
+ });
139
+ return anchor;
140
+ }
141
+ createCompanyInfoRows(info) {
142
+ const rows = [];
143
+ const line1 = [];
144
+ if (info.companyName)
145
+ line1.push(info.companyName);
146
+ if (info.representative)
147
+ line1.push(`대표: ${info.representative}`);
148
+ if (info.businessNumber)
149
+ line1.push(`사업자등록번호: ${info.businessNumber}`);
150
+ if (line1.length)
151
+ rows.push(line1.join(' | '));
152
+ const line2 = [];
153
+ if (info.address)
154
+ line2.push(info.address);
155
+ if (info.phone)
156
+ line2.push(`대표전화: ${info.phone}`);
157
+ if (info.customerCenter)
158
+ line2.push(`고객센터: ${info.customerCenter}`);
159
+ if (line2.length)
160
+ rows.push(line2.join(' | '));
161
+ const line3 = [];
162
+ if (info.email)
163
+ line3.push(`이메일: ${info.email}`);
164
+ if (info.mailOrderNumber)
165
+ line3.push(`통신판매업신고: ${info.mailOrderNumber}`);
166
+ if (info.hostingProvider)
167
+ line3.push(`호스팅: ${info.hostingProvider}`);
168
+ if (line3.length)
169
+ rows.push(line3.join(' | '));
170
+ return rows;
171
+ }
172
+ showLogo() {
173
+ return !this.hasAttribute('show-logo') || this.getAttribute('show-logo') !== 'false';
174
+ }
175
+ createLogo() {
176
+ const logoWrap = document.createElement('div');
177
+ logoWrap.className = 'designbase-wc-footer__logo';
178
+ const logo = document.createElement('db-logo');
179
+ logo.setAttribute('type', this.getAttribute('logo-type') || 'designbase');
180
+ logo.setAttribute('size', 's');
181
+ logo.setAttribute('clickable', '');
182
+ logo.addEventListener('db-click', () => {
183
+ this.dispatchEvent(new CustomEvent('db-logo-click', { bubbles: true, composed: true }));
184
+ });
185
+ logoWrap.append(logo);
186
+ return logoWrap;
187
+ }
188
+ renderBrand(iconPx, options = {}) {
189
+ const { showTagline = true } = options;
190
+ const brand = document.createElement('div');
191
+ brand.className = 'designbase-wc-footer__brand';
192
+ if (this.showLogo()) {
193
+ brand.append(this.createLogo());
194
+ }
195
+ const tagline = this.getAttribute('tagline');
196
+ if (showTagline && tagline) {
197
+ const taglineEl = document.createElement('p');
198
+ taglineEl.className = 'designbase-wc-footer__tagline';
199
+ taglineEl.textContent = tagline;
200
+ brand.append(taglineEl);
201
+ }
202
+ const socialLinks = this.socialLinks;
203
+ if (socialLinks.length && (!this.hasAttribute('show-social') || this.getAttribute('show-social') !== 'false')) {
204
+ const social = document.createElement('div');
205
+ social.className = 'designbase-wc-footer__social';
206
+ socialLinks.forEach((link) => social.append(this.createSocialLink(link, iconPx)));
207
+ brand.append(social);
208
+ }
209
+ return brand;
210
+ }
211
+ renderColumns(columns) {
212
+ if (!columns.length)
213
+ return null;
214
+ const wrap = document.createElement('div');
215
+ wrap.className = 'designbase-wc-footer__columns';
216
+ wrap.style.setProperty('--db-footer-columns', String(Math.min(columns.length, 4)));
217
+ columns.forEach((column) => {
218
+ const col = document.createElement('div');
219
+ col.className = 'designbase-wc-footer__column';
220
+ const title = document.createElement('h3');
221
+ title.className = 'designbase-wc-footer__column-title';
222
+ title.textContent = column.title;
223
+ col.append(title);
224
+ const list = document.createElement('ul');
225
+ list.className = 'designbase-wc-footer__column-list';
226
+ column.items.forEach((item) => {
227
+ const li = document.createElement('li');
228
+ li.append(this.createLink(item, 'designbase-wc-footer__column-link', 'column'));
229
+ list.append(li);
230
+ });
231
+ col.append(list);
232
+ wrap.append(col);
233
+ });
234
+ return wrap;
235
+ }
236
+ createLegalNav(legalLinks) {
237
+ const nav = document.createElement('nav');
238
+ nav.className = 'designbase-wc-footer__legal-nav';
239
+ nav.setAttribute('aria-label', '법적 고지');
240
+ const list = document.createElement('ul');
241
+ list.className = 'designbase-wc-footer__legal-list';
242
+ legalLinks.forEach((link, index) => {
243
+ const li = document.createElement('li');
244
+ li.append(this.createLink(link, 'designbase-wc-footer__legal-link', 'legal'));
245
+ list.append(li);
246
+ if (index < legalLinks.length - 1) {
247
+ const divider = document.createElement('span');
248
+ divider.className = 'designbase-wc-footer__legal-divider';
249
+ divider.setAttribute('aria-hidden', 'true');
250
+ divider.textContent = '|';
251
+ li.append(divider);
252
+ }
253
+ });
254
+ nav.append(list);
255
+ return nav;
256
+ }
257
+ renderLegalBar(legalLinks, familySites) {
258
+ if (!legalLinks.length && !familySites.length)
259
+ return null;
260
+ const bar = document.createElement('div');
261
+ bar.className = 'designbase-wc-footer__legal-bar';
262
+ if (legalLinks.length) {
263
+ bar.append(this.createLegalNav(legalLinks));
264
+ }
265
+ if (familySites.length) {
266
+ const familyWrap = document.createElement('div');
267
+ familyWrap.className = 'designbase-wc-footer__family-site';
268
+ const select = document.createElement('select');
269
+ select.className = 'designbase-wc-footer__family-select';
270
+ select.setAttribute('aria-label', this.getAttribute('family-site-label') || '패밀리 사이트');
271
+ const placeholder = document.createElement('option');
272
+ placeholder.value = '';
273
+ placeholder.textContent = this.getAttribute('family-site-label') || '패밀리 사이트';
274
+ placeholder.disabled = true;
275
+ placeholder.selected = true;
276
+ select.append(placeholder);
277
+ familySites.forEach((site) => {
278
+ const option = document.createElement('option');
279
+ option.value = site.href;
280
+ option.textContent = site.label;
281
+ option.dataset.id = site.id;
282
+ select.append(option);
283
+ });
284
+ select.addEventListener('change', () => {
285
+ const selected = familySites.find((site) => site.href === select.value);
286
+ if (!selected)
287
+ return;
288
+ select.selectedIndex = 0;
289
+ this.dispatchEvent(new CustomEvent('db-family-site-change', {
290
+ bubbles: true,
291
+ composed: true,
292
+ detail: { site: selected },
293
+ }));
294
+ });
295
+ familyWrap.append(select);
296
+ bar.append(familyWrap);
297
+ }
298
+ return bar;
299
+ }
300
+ renderCompanyInfo(info) {
301
+ const rows = this.createCompanyInfoRows(info);
302
+ if (!rows.length)
303
+ return null;
304
+ const wrap = document.createElement('div');
305
+ wrap.className = 'designbase-wc-footer__company';
306
+ rows.forEach((row) => {
307
+ const line = document.createElement('p');
308
+ line.className = 'designbase-wc-footer__company-line';
309
+ line.textContent = row;
310
+ wrap.append(line);
311
+ });
312
+ return wrap;
313
+ }
314
+ createCopyright(copyright) {
315
+ const bottom = document.createElement('div');
316
+ bottom.className = 'designbase-wc-footer__bottom';
317
+ const copyrightEl = document.createElement('p');
318
+ copyrightEl.className = 'designbase-wc-footer__copyright';
319
+ copyrightEl.textContent = copyright;
320
+ bottom.append(copyrightEl);
321
+ return bottom;
322
+ }
323
+ renderMinimal(container, legalLinks, copyright) {
324
+ const bar = document.createElement('div');
325
+ bar.className = 'designbase-wc-footer__minimal-bar';
326
+ const start = document.createElement('div');
327
+ start.className = 'designbase-wc-footer__minimal-start';
328
+ if (this.showLogo())
329
+ start.append(this.createLogo());
330
+ bar.append(start);
331
+ if (legalLinks.length) {
332
+ const legalWrap = document.createElement('div');
333
+ legalWrap.className = 'designbase-wc-footer__minimal-legal';
334
+ legalWrap.append(this.createLegalNav(legalLinks));
335
+ bar.append(legalWrap);
336
+ }
337
+ container.append(bar);
338
+ container.append(this.createCopyright(copyright));
339
+ }
340
+ render() {
341
+ this.syncHostClasses();
342
+ this.setAttribute('role', 'contentinfo');
343
+ const variant = this.getAttribute('variant') || 'default';
344
+ const size = this.getAttribute('size') || 'm';
345
+ const iconPx = size === 's' ? 18 : size === 'l' ? 22 : 20;
346
+ const columns = variant === 'default' ? this.columns : [];
347
+ const legalLinks = this.legalLinks;
348
+ const companyInfo = this.companyInfo;
349
+ const familySites = this.familySites;
350
+ const copyright = this.getAttribute('copyright') || `© ${new Date().getFullYear()} Designbase. All rights reserved.`;
351
+ this.replaceChildren();
352
+ const container = document.createElement('div');
353
+ container.className = [
354
+ 'designbase-wc-footer__container',
355
+ this.hasAttribute('full-width') && 'designbase-wc-footer__container--full-width',
356
+ ]
357
+ .filter(Boolean)
358
+ .join(' ');
359
+ if (variant === 'minimal') {
360
+ this.renderMinimal(container, legalLinks, copyright);
361
+ this.append(container);
362
+ return;
363
+ }
364
+ const top = document.createElement('div');
365
+ top.className = 'designbase-wc-footer__top';
366
+ top.append(this.renderBrand(iconPx, { showTagline: variant !== 'compact' }));
367
+ const columnsEl = this.renderColumns(columns);
368
+ if (columnsEl)
369
+ top.append(columnsEl);
370
+ container.append(top);
371
+ const legalBar = this.renderLegalBar(legalLinks, familySites);
372
+ if (legalBar)
373
+ container.append(legalBar);
374
+ const companyEl = this.renderCompanyInfo(companyInfo);
375
+ if (companyEl)
376
+ container.append(companyEl);
377
+ container.append(this.createCopyright(copyright));
378
+ this.append(container);
379
+ }
380
+ }
381
+ if (!customElements.get('db-footer')) {
382
+ customElements.define('db-footer', DbFooter);
383
+ }
384
+
385
+ export { DbFooter };