@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,324 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e="designbase-wc-tutorial";class DbTutorial extends HTMLElement{constructor(){super(...arguments),this.internalStep=0,this.targetElement=null,this.keyHandler=null,this.resizeHandler=null,this.isMounted=!1}static get observedAttributes(){return["open","steps","current-step","indicator-type","indicator-size"]}connectedCallback(){this.style.display="contents",this.syncStepFromAttribute(),this.syncOpenState()}disconnectedCallback(){this.detachListeners(),this.clearTargetHighlight(),this.unmount()}attributeChangedCallback(t){this.isConnected&&("open"!==t?("current-step"===t&&this.syncStepFromAttribute(),this.isMounted&&this.render()):this.syncOpenState())}get steps(){return this.parseSteps()}set steps(t){this.setAttribute("steps","string"==typeof t?t:JSON.stringify(t))}parseSteps(){try{const t=JSON.parse(this.getAttribute("steps")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}syncStepFromAttribute(){if(!this.hasAttribute("current-step"))return;const t=Number(this.getAttribute("current-step")||0);Number.isFinite(t)&&(this.internalStep=Math.max(0,t))}isOpenRequested(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}getCurrentStepData(){const t=this.parseSteps();if(!t.length)return;const e=Math.min(Math.max(this.internalStep,0),t.length-1);return{step:t[e],index:e,steps:t}}syncOpenState(){if(this.isOpenRequested())return this.mount(),void this.attachListeners();this.detachListeners(),this.clearTargetHighlight(),this.unmount()}mount(){this.root||(this.root=document.createElement("div"),this.root.className=e,this.root.setAttribute("role","dialog"),this.root.setAttribute("aria-modal","true"),this.root.tabIndex=-1,this.ensureStructure()),this.root.isConnected||document.body.append(this.root),this.isMounted=!0,this.render()}unmount(){this.isMounted=!1,this.root?.remove()}ensureStructure(){if(!this.root||this.popoverEl)return;this.overlayEl=document.createElement("div"),this.overlayEl.className=`${e}__overlay`,this.overlayEl.addEventListener("click",()=>this.handleEnd()),this.popoverEl=document.createElement("div"),this.popoverEl.className=`${e}__popover`,this.closeButtonEl=document.createElement("button"),this.closeButtonEl.type="button",this.closeButtonEl.className=`${e}__close-button`,this.closeButtonEl.setAttribute("aria-label","튜토리얼 종료"),this.closeButtonEl.append(t("close",16)),this.closeButtonEl.addEventListener("click",()=>this.handleEnd());const i=document.createElement("div");i.className=`${e}__content`;const s=document.createElement("div");s.className=`${e}__text`,this.titleEl=document.createElement("h3"),this.titleEl.id="tutorial-title",this.titleEl.className=`${e}__title`,this.descriptionEl=document.createElement("p"),this.descriptionEl.id="tutorial-content",this.descriptionEl.className=`${e}__description`,s.append(this.titleEl,this.descriptionEl);const n=document.createElement("div");n.className=`${e}__navigation`,this.prevButtonEl=document.createElement("db-button"),this.prevButtonEl.setAttribute("variant","secondary"),this.prevButtonEl.setAttribute("size","s"),this.prevButtonEl.setAttribute("start-icon","chevron-left"),this.prevButtonEl.textContent="이전",this.prevButtonEl.addEventListener("db-click",()=>this.handlePrev()),this.indicatorEl=document.createElement("db-indicator"),this.indicatorEl.addEventListener("db-step-click",t=>{const e=t.detail;"number"==typeof e.index&&this.goToStep(e.index)}),this.nextButtonEl=document.createElement("db-button"),this.nextButtonEl.setAttribute("variant","primary"),this.nextButtonEl.setAttribute("size","s"),this.nextButtonEl.addEventListener("db-click",()=>this.handleNext()),n.append(this.prevButtonEl,this.indicatorEl,this.nextButtonEl),i.append(s,n),this.popoverEl.append(this.closeButtonEl,i),this.root.append(this.overlayEl,this.popoverEl)}attachListeners(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key?this.handleEnd():"ArrowLeft"===t.key?this.handlePrev():"ArrowRight"===t.key&&this.handleNext()},document.addEventListener("keydown",this.keyHandler)),this.resizeHandler||(this.resizeHandler=()=>this.updateTargetElement(),window.addEventListener("resize",this.resizeHandler))}detachListeners(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null),this.resizeHandler&&(window.removeEventListener("resize",this.resizeHandler),this.resizeHandler=null)}clearTargetHighlight(){this.targetElement&&(this.targetElement.classList.remove(`${e}__target`),this.targetElement.style.position="",this.targetElement.style.zIndex="",this.targetElement=null)}updateTargetElement(){const t=this.getCurrentStepData();if(!t?.step.target||!this.popoverEl)return;this.clearTargetHighlight();const i=document.querySelector(t.step.target);if(!i)return;this.targetElement=i,i.style.position="relative",i.style.zIndex="1000",i.classList.add(`${e}__target`);const s=i.getBoundingClientRect(),n=window.innerWidth,r=window.innerHeight,o=300,l=200,h=16;let a="auto"!==t.step.placement&&t.step.placement?t.step.placement:"bottom",d=s.bottom+h,c=s.left+s.width/2-150;if("auto"===t.step.placement)s.top-l-h>0?(a="top",d=s.top-l-h):s.bottom+l+h<r?(a="bottom",d=s.bottom+h):s.left-o-h>0?(a="left",d=s.top+s.height/2-100,c=s.left-o-h):(a="right",d=s.top+s.height/2-100,c=s.right+h);else switch(a){case"top":d=s.top-l-h;break;case"bottom":d=s.bottom+h;break;case"left":d=s.top+s.height/2-100,c=s.left-o-h;break;case"right":d=s.top+s.height/2-100,c=s.right+h}c=Math.max(h,Math.min(c,n-o-h)),d=Math.max(h,Math.min(d,r-l-h)),this.popoverEl.className=[`${e}__popover`,`${e}__popover--${a}`].join(" "),this.popoverEl.style.top=`${d}px`,this.popoverEl.style.left=`${c}px`}emitStepChange(t){this.dispatchEvent(new CustomEvent("db-step-change",{bubbles:!0,composed:!0,detail:{step:t}}))}goToStep(t){const e=this.parseSteps();e.length&&(this.clearTargetHighlight(),this.internalStep=Math.min(Math.max(t,0),e.length-1),this.setAttribute("current-step",String(this.internalStep)),this.emitStepChange(this.internalStep),this.render())}handlePrev(){const t=this.getCurrentStepData();!t||t.index<=0||(this.dispatchEvent(new CustomEvent("db-prev",{bubbles:!0,composed:!0})),this.goToStep(t.index-1))}handleNext(){const t=this.getCurrentStepData();t&&(t.index>=t.steps.length-1?this.handleEnd():(this.dispatchEvent(new CustomEvent("db-next",{bubbles:!0,composed:!0})),this.goToStep(t.index+1)))}handleEnd(){this.dispatchEvent(new CustomEvent("db-end",{bubbles:!0,composed:!0})),this.setAttribute("open","false")}render(){const t=this.getCurrentStepData();if(!t||!this.root)return;const{step:e,index:i,steps:s}=t,n=0===i,r=i===s.length-1;this.titleEl&&(this.titleEl.textContent=e.title||"",this.titleEl.hidden=!e.title),this.descriptionEl&&(this.descriptionEl.textContent=e.content||"",this.descriptionEl.hidden=!e.content),this.prevButtonEl&&(this.prevButtonEl.hidden=n),this.nextButtonEl&&(this.nextButtonEl.textContent=r?"완료":"다음",r?this.nextButtonEl.removeAttribute("end-icon"):this.nextButtonEl.setAttribute("end-icon","chevron-right")),this.indicatorEl&&(this.indicatorEl.setAttribute("current",String(i)),this.indicatorEl.setAttribute("total",String(s.length)),this.indicatorEl.setAttribute("type",this.getAttribute("indicator-type")||"numbers"),this.indicatorEl.setAttribute("size",this.getAttribute("indicator-size")||"m")),this.updateTargetElement()}}customElements.get("db-tutorial")||customElements.define("db-tutorial",DbTutorial);export{DbTutorial};
1
+ import { createDbIcon } from './db-icons.js';
2
+
3
+ const CLASS = 'designbase-wc-tutorial';
4
+ class DbTutorial extends HTMLElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.internalStep = 0;
8
+ this.targetElement = null;
9
+ this.keyHandler = null;
10
+ this.resizeHandler = null;
11
+ this.isMounted = false;
12
+ }
13
+ static get observedAttributes() {
14
+ return ['open', 'steps', 'current-step', 'indicator-type', 'indicator-size'];
15
+ }
16
+ connectedCallback() {
17
+ this.style.display = 'contents';
18
+ this.syncStepFromAttribute();
19
+ this.syncOpenState();
20
+ }
21
+ disconnectedCallback() {
22
+ this.detachListeners();
23
+ this.clearTargetHighlight();
24
+ this.unmount();
25
+ }
26
+ attributeChangedCallback(name) {
27
+ if (!this.isConnected)
28
+ return;
29
+ if (name === 'open') {
30
+ this.syncOpenState();
31
+ return;
32
+ }
33
+ if (name === 'current-step')
34
+ this.syncStepFromAttribute();
35
+ if (this.isMounted)
36
+ this.render();
37
+ }
38
+ get steps() {
39
+ return this.parseSteps();
40
+ }
41
+ set steps(value) {
42
+ this.setAttribute('steps', typeof value === 'string' ? value : JSON.stringify(value));
43
+ }
44
+ parseSteps() {
45
+ try {
46
+ const parsed = JSON.parse(this.getAttribute('steps') || '[]');
47
+ return Array.isArray(parsed) ? parsed : [];
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ }
53
+ syncStepFromAttribute() {
54
+ if (!this.hasAttribute('current-step'))
55
+ return;
56
+ const next = Number(this.getAttribute('current-step') || 0);
57
+ if (Number.isFinite(next))
58
+ this.internalStep = Math.max(0, next);
59
+ }
60
+ isOpenRequested() {
61
+ return this.hasAttribute('open') && this.getAttribute('open') !== 'false';
62
+ }
63
+ getCurrentStepData() {
64
+ const steps = this.parseSteps();
65
+ if (!steps.length)
66
+ return undefined;
67
+ const index = Math.min(Math.max(this.internalStep, 0), steps.length - 1);
68
+ return { step: steps[index], index, steps };
69
+ }
70
+ syncOpenState() {
71
+ if (this.isOpenRequested()) {
72
+ this.mount();
73
+ this.attachListeners();
74
+ return;
75
+ }
76
+ this.detachListeners();
77
+ this.clearTargetHighlight();
78
+ this.unmount();
79
+ }
80
+ mount() {
81
+ if (!this.root) {
82
+ this.root = document.createElement('div');
83
+ this.root.className = CLASS;
84
+ this.root.setAttribute('role', 'dialog');
85
+ this.root.setAttribute('aria-modal', 'true');
86
+ this.root.tabIndex = -1;
87
+ this.ensureStructure();
88
+ }
89
+ if (!this.root.isConnected)
90
+ document.body.append(this.root);
91
+ this.isMounted = true;
92
+ this.render();
93
+ }
94
+ unmount() {
95
+ this.isMounted = false;
96
+ this.root?.remove();
97
+ }
98
+ ensureStructure() {
99
+ if (!this.root || this.popoverEl)
100
+ return;
101
+ this.overlayEl = document.createElement('div');
102
+ this.overlayEl.className = `${CLASS}__overlay`;
103
+ this.overlayEl.addEventListener('click', () => this.handleEnd());
104
+ this.popoverEl = document.createElement('div');
105
+ this.popoverEl.className = `${CLASS}__popover`;
106
+ this.closeButtonEl = document.createElement('button');
107
+ this.closeButtonEl.type = 'button';
108
+ this.closeButtonEl.className = `${CLASS}__close-button`;
109
+ this.closeButtonEl.setAttribute('aria-label', '튜토리얼 종료');
110
+ this.closeButtonEl.append(createDbIcon('close', 16));
111
+ this.closeButtonEl.addEventListener('click', () => this.handleEnd());
112
+ const content = document.createElement('div');
113
+ content.className = `${CLASS}__content`;
114
+ const text = document.createElement('div');
115
+ text.className = `${CLASS}__text`;
116
+ this.titleEl = document.createElement('h3');
117
+ this.titleEl.id = 'tutorial-title';
118
+ this.titleEl.className = `${CLASS}__title`;
119
+ this.descriptionEl = document.createElement('p');
120
+ this.descriptionEl.id = 'tutorial-content';
121
+ this.descriptionEl.className = `${CLASS}__description`;
122
+ text.append(this.titleEl, this.descriptionEl);
123
+ const navigation = document.createElement('div');
124
+ navigation.className = `${CLASS}__navigation`;
125
+ this.prevButtonEl = document.createElement('db-button');
126
+ this.prevButtonEl.setAttribute('variant', 'secondary');
127
+ this.prevButtonEl.setAttribute('size', 's');
128
+ this.prevButtonEl.setAttribute('start-icon', 'chevron-left');
129
+ this.prevButtonEl.textContent = '이전';
130
+ this.prevButtonEl.addEventListener('db-click', () => this.handlePrev());
131
+ this.indicatorEl = document.createElement('db-indicator');
132
+ this.indicatorEl.addEventListener('db-step-click', (event) => {
133
+ const detail = event.detail;
134
+ if (typeof detail.index === 'number')
135
+ this.goToStep(detail.index);
136
+ });
137
+ this.nextButtonEl = document.createElement('db-button');
138
+ this.nextButtonEl.setAttribute('variant', 'primary');
139
+ this.nextButtonEl.setAttribute('size', 's');
140
+ this.nextButtonEl.addEventListener('db-click', () => this.handleNext());
141
+ navigation.append(this.prevButtonEl, this.indicatorEl, this.nextButtonEl);
142
+ content.append(text, navigation);
143
+ this.popoverEl.append(this.closeButtonEl, content);
144
+ this.root.append(this.overlayEl, this.popoverEl);
145
+ }
146
+ attachListeners() {
147
+ if (!this.keyHandler) {
148
+ this.keyHandler = (event) => {
149
+ if (event.key === 'Escape')
150
+ this.handleEnd();
151
+ else if (event.key === 'ArrowLeft')
152
+ this.handlePrev();
153
+ else if (event.key === 'ArrowRight')
154
+ this.handleNext();
155
+ };
156
+ document.addEventListener('keydown', this.keyHandler);
157
+ }
158
+ if (!this.resizeHandler) {
159
+ this.resizeHandler = () => this.updateTargetElement();
160
+ window.addEventListener('resize', this.resizeHandler);
161
+ }
162
+ }
163
+ detachListeners() {
164
+ if (this.keyHandler) {
165
+ document.removeEventListener('keydown', this.keyHandler);
166
+ this.keyHandler = null;
167
+ }
168
+ if (this.resizeHandler) {
169
+ window.removeEventListener('resize', this.resizeHandler);
170
+ this.resizeHandler = null;
171
+ }
172
+ }
173
+ clearTargetHighlight() {
174
+ if (!this.targetElement)
175
+ return;
176
+ this.targetElement.classList.remove(`${CLASS}__target`);
177
+ this.targetElement.style.position = '';
178
+ this.targetElement.style.zIndex = '';
179
+ this.targetElement = null;
180
+ }
181
+ updateTargetElement() {
182
+ const current = this.getCurrentStepData();
183
+ if (!current?.step.target || !this.popoverEl)
184
+ return;
185
+ this.clearTargetHighlight();
186
+ const element = document.querySelector(current.step.target);
187
+ if (!element)
188
+ return;
189
+ this.targetElement = element;
190
+ element.style.position = 'relative';
191
+ element.style.zIndex = '1000';
192
+ element.classList.add(`${CLASS}__target`);
193
+ const rect = element.getBoundingClientRect();
194
+ const viewportWidth = window.innerWidth;
195
+ const viewportHeight = window.innerHeight;
196
+ const popoverWidth = 300;
197
+ const popoverHeight = 200;
198
+ const margin = 16;
199
+ let placement = current.step.placement === 'auto' || !current.step.placement
200
+ ? 'bottom'
201
+ : current.step.placement;
202
+ let top = rect.bottom + margin;
203
+ let left = rect.left + rect.width / 2 - popoverWidth / 2;
204
+ if (current.step.placement === 'auto') {
205
+ if (rect.top - popoverHeight - margin > 0) {
206
+ placement = 'top';
207
+ top = rect.top - popoverHeight - margin;
208
+ }
209
+ else if (rect.bottom + popoverHeight + margin < viewportHeight) {
210
+ placement = 'bottom';
211
+ top = rect.bottom + margin;
212
+ }
213
+ else if (rect.left - popoverWidth - margin > 0) {
214
+ placement = 'left';
215
+ top = rect.top + rect.height / 2 - popoverHeight / 2;
216
+ left = rect.left - popoverWidth - margin;
217
+ }
218
+ else {
219
+ placement = 'right';
220
+ top = rect.top + rect.height / 2 - popoverHeight / 2;
221
+ left = rect.right + margin;
222
+ }
223
+ }
224
+ else {
225
+ switch (placement) {
226
+ case 'top':
227
+ top = rect.top - popoverHeight - margin;
228
+ break;
229
+ case 'bottom':
230
+ top = rect.bottom + margin;
231
+ break;
232
+ case 'left':
233
+ top = rect.top + rect.height / 2 - popoverHeight / 2;
234
+ left = rect.left - popoverWidth - margin;
235
+ break;
236
+ case 'right':
237
+ top = rect.top + rect.height / 2 - popoverHeight / 2;
238
+ left = rect.right + margin;
239
+ break;
240
+ }
241
+ }
242
+ left = Math.max(margin, Math.min(left, viewportWidth - popoverWidth - margin));
243
+ top = Math.max(margin, Math.min(top, viewportHeight - popoverHeight - margin));
244
+ this.popoverEl.className = [`${CLASS}__popover`, `${CLASS}__popover--${placement}`].join(' ');
245
+ this.popoverEl.style.top = `${top}px`;
246
+ this.popoverEl.style.left = `${left}px`;
247
+ }
248
+ emitStepChange(step) {
249
+ this.dispatchEvent(new CustomEvent('db-step-change', {
250
+ bubbles: true,
251
+ composed: true,
252
+ detail: { step },
253
+ }));
254
+ }
255
+ goToStep(step) {
256
+ const steps = this.parseSteps();
257
+ if (!steps.length)
258
+ return;
259
+ this.clearTargetHighlight();
260
+ this.internalStep = Math.min(Math.max(step, 0), steps.length - 1);
261
+ this.setAttribute('current-step', String(this.internalStep));
262
+ this.emitStepChange(this.internalStep);
263
+ this.render();
264
+ }
265
+ handlePrev() {
266
+ const current = this.getCurrentStepData();
267
+ if (!current || current.index <= 0)
268
+ return;
269
+ this.dispatchEvent(new CustomEvent('db-prev', { bubbles: true, composed: true }));
270
+ this.goToStep(current.index - 1);
271
+ }
272
+ handleNext() {
273
+ const current = this.getCurrentStepData();
274
+ if (!current)
275
+ return;
276
+ if (current.index >= current.steps.length - 1) {
277
+ this.handleEnd();
278
+ return;
279
+ }
280
+ this.dispatchEvent(new CustomEvent('db-next', { bubbles: true, composed: true }));
281
+ this.goToStep(current.index + 1);
282
+ }
283
+ handleEnd() {
284
+ this.dispatchEvent(new CustomEvent('db-end', { bubbles: true, composed: true }));
285
+ this.setAttribute('open', 'false');
286
+ }
287
+ render() {
288
+ const current = this.getCurrentStepData();
289
+ if (!current || !this.root)
290
+ return;
291
+ const { step, index, steps } = current;
292
+ const isFirst = index === 0;
293
+ const isLast = index === steps.length - 1;
294
+ if (this.titleEl) {
295
+ this.titleEl.textContent = step.title || '';
296
+ this.titleEl.hidden = !step.title;
297
+ }
298
+ if (this.descriptionEl) {
299
+ this.descriptionEl.textContent = step.content || '';
300
+ this.descriptionEl.hidden = !step.content;
301
+ }
302
+ if (this.prevButtonEl)
303
+ this.prevButtonEl.hidden = isFirst;
304
+ if (this.nextButtonEl) {
305
+ this.nextButtonEl.textContent = isLast ? '완료' : '다음';
306
+ if (isLast)
307
+ this.nextButtonEl.removeAttribute('end-icon');
308
+ else
309
+ this.nextButtonEl.setAttribute('end-icon', 'chevron-right');
310
+ }
311
+ if (this.indicatorEl) {
312
+ this.indicatorEl.setAttribute('current', String(index));
313
+ this.indicatorEl.setAttribute('total', String(steps.length));
314
+ this.indicatorEl.setAttribute('type', this.getAttribute('indicator-type') || 'numbers');
315
+ this.indicatorEl.setAttribute('size', this.getAttribute('indicator-size') || 'm');
316
+ }
317
+ this.updateTargetElement();
318
+ }
319
+ }
320
+ if (!customElements.get('db-tutorial')) {
321
+ customElements.define('db-tutorial', DbTutorial);
322
+ }
323
+
324
+ export { DbTutorial };