@designbasekorea/ui-wc 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/README.md +322 -29
  2. package/dist/esm/components/animation-background/canvas-controller.js +1 -0
  3. package/dist/esm/components/animation-background/controls.js +1 -0
  4. package/dist/esm/components/animation-background/graphite-controller.js +1 -0
  5. package/dist/esm/components/animation-background/graphite-presets.js +1 -0
  6. package/dist/esm/components/animation-background/graphite-shader.js +1 -0
  7. package/dist/esm/components/animation-background/layers.js +1 -0
  8. package/dist/esm/components/animation-background/lumina-presets.js +1 -0
  9. package/dist/esm/components/animation-background/lumina-shaders.js +1 -0
  10. package/dist/esm/components/animation-background/lumina-utils.js +1 -0
  11. package/dist/esm/components/animation-background/particle-defaults.js +1 -0
  12. package/dist/esm/components/animation-background/renderers.js +1 -0
  13. package/dist/esm/components/animation-background/shader-controller.js +1 -0
  14. package/dist/esm/components/color-picker-utils.js +1 -0
  15. package/dist/esm/components/date-picker-utils.js +1 -0
  16. package/dist/esm/components/db-accordion.d.ts +40 -0
  17. package/dist/esm/components/db-accordion.js +1 -0
  18. package/dist/esm/components/db-ad-banner.d.ts +66 -0
  19. package/dist/esm/components/db-ad-banner.js +1 -0
  20. package/dist/esm/components/db-alert.d.ts +24 -0
  21. package/dist/esm/components/db-alert.js +1 -0
  22. package/dist/esm/components/db-animation-background.d.ts +41 -0
  23. package/dist/esm/components/db-animation-background.js +1 -0
  24. package/dist/esm/components/db-animation-text.d.ts +43 -0
  25. package/dist/esm/components/db-animation-text.js +1 -0
  26. package/dist/esm/components/db-app-badge.d.ts +20 -0
  27. package/dist/esm/components/db-app-badge.js +1 -0
  28. package/dist/esm/components/db-audio-player.d.ts +82 -0
  29. package/dist/esm/components/db-audio-player.js +1 -0
  30. package/dist/esm/components/db-avatar.d.ts +18 -0
  31. package/dist/esm/components/db-avatar.js +1 -0
  32. package/dist/esm/components/db-backdrop.d.ts +24 -0
  33. package/dist/esm/components/db-backdrop.js +1 -0
  34. package/dist/esm/components/db-badge.d.ts +27 -0
  35. package/dist/esm/components/db-badge.js +1 -0
  36. package/dist/esm/components/db-banner.d.ts +28 -0
  37. package/dist/esm/components/db-banner.js +1 -0
  38. package/dist/esm/components/db-bottom-navigation.d.ts +29 -0
  39. package/dist/esm/components/db-bottom-navigation.js +1 -0
  40. package/dist/esm/components/db-bottom-sheet.d.ts +49 -0
  41. package/dist/esm/components/db-bottom-sheet.js +1 -0
  42. package/dist/esm/components/db-breadcrumbs.d.ts +24 -0
  43. package/dist/esm/components/db-breadcrumbs.js +1 -0
  44. package/dist/esm/components/db-button.d.ts +57 -0
  45. package/dist/esm/components/db-button.js +1 -0
  46. package/dist/esm/components/db-calendar.d.ts +78 -0
  47. package/dist/esm/components/db-calendar.js +1 -0
  48. package/dist/esm/components/db-card.d.ts +42 -0
  49. package/dist/esm/components/db-card.js +1 -0
  50. package/dist/esm/components/db-carousel.d.ts +35 -0
  51. package/dist/esm/components/db-carousel.js +1 -0
  52. package/dist/esm/components/db-checkbox.d.ts +35 -0
  53. package/dist/esm/components/db-checkbox.js +1 -0
  54. package/dist/esm/components/db-chip.d.ts +14 -0
  55. package/dist/esm/components/db-chip.js +1 -0
  56. package/dist/esm/components/db-code-block.d.ts +28 -0
  57. package/dist/esm/components/db-code-block.js +1 -0
  58. package/dist/esm/components/db-color-picker.d.ts +83 -0
  59. package/dist/esm/components/db-color-picker.js +1 -0
  60. package/dist/esm/components/db-confirm.d.ts +23 -0
  61. package/dist/esm/components/db-confirm.js +1 -0
  62. package/dist/esm/components/db-container.d.ts +13 -0
  63. package/dist/esm/components/db-container.js +1 -0
  64. package/dist/esm/components/db-context-menu.d.ts +46 -0
  65. package/dist/esm/components/db-context-menu.js +1 -0
  66. package/dist/esm/components/db-countdown.d.ts +23 -0
  67. package/dist/esm/components/db-countdown.js +1 -0
  68. package/dist/esm/components/db-cursor-follower.d.ts +31 -0
  69. package/dist/esm/components/db-cursor-follower.js +1 -0
  70. package/dist/esm/components/db-date-picker.d.ts +84 -0
  71. package/dist/esm/components/db-date-picker.js +1 -0
  72. package/dist/esm/components/db-divider.d.ts +13 -0
  73. package/dist/esm/components/db-divider.js +1 -0
  74. package/dist/esm/components/db-drawer.d.ts +32 -0
  75. package/dist/esm/components/db-drawer.js +1 -0
  76. package/dist/esm/components/db-dropdown.d.ts +70 -0
  77. package/dist/esm/components/db-dropdown.js +1 -0
  78. package/dist/esm/components/db-dropzone.d.ts +29 -0
  79. package/dist/esm/components/db-dropzone.js +1 -0
  80. package/dist/esm/components/db-empty-state.d.ts +14 -0
  81. package/dist/esm/components/db-empty-state.js +1 -0
  82. package/dist/esm/components/db-file-uploader.d.ts +27 -0
  83. package/dist/esm/components/db-file-uploader.js +1 -0
  84. package/dist/esm/components/db-floating-action-button.d.ts +24 -0
  85. package/dist/esm/components/db-floating-action-button.js +1 -0
  86. package/dist/esm/components/db-footer.d.ts +74 -0
  87. package/dist/esm/components/db-footer.js +1 -0
  88. package/dist/esm/components/db-form.d.ts +94 -0
  89. package/dist/esm/components/db-form.js +1 -0
  90. package/dist/esm/components/db-gradient.d.ts +26 -0
  91. package/dist/esm/components/db-gradient.js +1 -0
  92. package/dist/esm/components/db-grid-background.d.ts +93 -0
  93. package/dist/esm/components/db-grid-background.js +1 -0
  94. package/dist/esm/components/db-grid.d.ts +20 -0
  95. package/dist/esm/components/db-grid.js +1 -0
  96. package/dist/esm/components/db-icons.js +1 -0
  97. package/dist/esm/components/db-image-list.d.ts +35 -0
  98. package/dist/esm/components/db-image-list.js +1 -0
  99. package/dist/esm/components/db-image-placeholder.d.ts +16 -0
  100. package/dist/esm/components/db-image-placeholder.js +1 -0
  101. package/dist/esm/components/db-image.d.ts +34 -0
  102. package/dist/esm/components/db-image.js +1 -0
  103. package/dist/esm/components/db-indicator.d.ts +58 -0
  104. package/dist/esm/components/db-indicator.js +1 -0
  105. package/dist/esm/components/db-input.d.ts +51 -0
  106. package/dist/esm/components/db-input.js +1 -0
  107. package/dist/esm/components/db-label.d.ts +13 -0
  108. package/dist/esm/components/db-label.js +1 -0
  109. package/dist/esm/components/db-lightbox.d.ts +53 -0
  110. package/dist/esm/components/db-lightbox.js +1 -0
  111. package/dist/esm/components/db-list.d.ts +46 -0
  112. package/dist/esm/components/db-list.js +1 -0
  113. package/dist/esm/components/db-logo-svg.js +1 -0
  114. package/dist/esm/components/db-logo.d.ts +15 -0
  115. package/dist/esm/components/db-logo.js +1 -0
  116. package/dist/esm/components/db-lottie.d.ts +20 -0
  117. package/dist/esm/components/db-lottie.js +1 -0
  118. package/dist/esm/components/db-markdown-editor.d.ts +53 -0
  119. package/dist/esm/components/db-markdown-editor.js +1 -0
  120. package/dist/esm/components/db-marquee.d.ts +56 -0
  121. package/dist/esm/components/db-marquee.js +1 -0
  122. package/dist/esm/components/db-masonry.d.ts +24 -0
  123. package/dist/esm/components/db-masonry.js +1 -0
  124. package/dist/esm/components/db-menu-item.d.ts +30 -0
  125. package/dist/esm/components/db-menu-item.js +1 -0
  126. package/dist/esm/components/db-modal.d.ts +63 -0
  127. package/dist/esm/components/db-modal.js +1 -0
  128. package/dist/esm/components/db-navbar.d.ts +88 -0
  129. package/dist/esm/components/db-navbar.js +1 -0
  130. package/dist/esm/components/db-onboarding-modal.d.ts +57 -0
  131. package/dist/esm/components/db-onboarding-modal.js +1 -0
  132. package/dist/esm/components/db-page-header.d.ts +33 -0
  133. package/dist/esm/components/db-page-header.js +1 -0
  134. package/dist/esm/components/db-pagination.d.ts +25 -0
  135. package/dist/esm/components/db-pagination.js +1 -0
  136. package/dist/esm/components/db-popover.d.ts +62 -0
  137. package/dist/esm/components/db-popover.js +1 -0
  138. package/dist/esm/components/db-progress-step.d.ts +28 -0
  139. package/dist/esm/components/db-progress-step.js +1 -0
  140. package/dist/esm/components/db-progress.d.ts +25 -0
  141. package/dist/esm/components/db-progress.js +1 -0
  142. package/dist/esm/components/db-progressbar.d.ts +13 -0
  143. package/dist/esm/components/db-progressbar.js +1 -0
  144. package/dist/esm/components/db-radio.d.ts +34 -0
  145. package/dist/esm/components/db-radio.js +1 -0
  146. package/dist/esm/components/db-random-gradient.d.ts +24 -0
  147. package/dist/esm/components/db-random-gradient.js +1 -0
  148. package/dist/esm/components/db-range-slider.d.ts +71 -0
  149. package/dist/esm/components/db-range-slider.js +1 -0
  150. package/dist/esm/components/db-rating.d.ts +31 -0
  151. package/dist/esm/components/db-rating.js +1 -0
  152. package/dist/esm/components/db-reorder.d.ts +38 -0
  153. package/dist/esm/components/db-reorder.js +1 -0
  154. package/dist/esm/components/db-resizable-panels.d.ts +42 -0
  155. package/dist/esm/components/db-resizable-panels.js +1 -0
  156. package/dist/esm/components/db-scroll-area.d.ts +23 -0
  157. package/dist/esm/components/db-scroll-area.js +1 -0
  158. package/dist/esm/components/db-search-bar.d.ts +53 -0
  159. package/dist/esm/components/db-search-bar.js +1 -0
  160. package/dist/esm/components/db-section-app-download.d.ts +32 -0
  161. package/dist/esm/components/db-section-app-download.js +1 -0
  162. package/dist/esm/components/db-section-contact.d.ts +22 -0
  163. package/dist/esm/components/db-section-contact.js +1 -0
  164. package/dist/esm/components/db-section-feature.d.ts +34 -0
  165. package/dist/esm/components/db-section-feature.js +1 -0
  166. package/dist/esm/components/db-section-hero.d.ts +34 -0
  167. package/dist/esm/components/db-section-hero.js +1 -0
  168. package/dist/esm/components/db-section.d.ts +44 -0
  169. package/dist/esm/components/db-section.js +1 -0
  170. package/dist/esm/components/db-segment-control.d.ts +41 -0
  171. package/dist/esm/components/db-segment-control.js +1 -0
  172. package/dist/esm/components/db-select.d.ts +66 -0
  173. package/dist/esm/components/db-select.js +1 -0
  174. package/dist/esm/components/db-share-icons.js +1 -0
  175. package/dist/esm/components/db-share.d.ts +48 -0
  176. package/dist/esm/components/db-share.js +1 -0
  177. package/dist/esm/components/db-sidebar.d.ts +59 -0
  178. package/dist/esm/components/db-sidebar.js +1 -0
  179. package/dist/esm/components/db-skeleton.d.ts +13 -0
  180. package/dist/esm/components/db-skeleton.js +1 -0
  181. package/dist/esm/components/db-spinner.d.ts +27 -0
  182. package/dist/esm/components/db-spinner.js +1 -0
  183. package/dist/esm/components/db-split-view.d.ts +33 -0
  184. package/dist/esm/components/db-split-view.js +1 -0
  185. package/dist/esm/components/db-stack.d.ts +13 -0
  186. package/dist/esm/components/db-stack.js +1 -0
  187. package/dist/esm/components/db-stat.d.ts +26 -0
  188. package/dist/esm/components/db-stat.js +1 -0
  189. package/dist/esm/components/db-stepper.d.ts +49 -0
  190. package/dist/esm/components/db-stepper.js +1 -0
  191. package/dist/esm/components/db-table.d.ts +39 -0
  192. package/dist/esm/components/db-table.js +1 -0
  193. package/dist/esm/components/db-tabs.d.ts +48 -0
  194. package/dist/esm/components/db-tabs.js +1 -0
  195. package/dist/esm/components/db-testimonial.d.ts +27 -0
  196. package/dist/esm/components/db-testimonial.js +1 -0
  197. package/dist/esm/components/db-textarea.d.ts +33 -0
  198. package/dist/esm/components/db-textarea.js +1 -0
  199. package/dist/esm/components/db-time-picker.d.ts +62 -0
  200. package/dist/esm/components/db-time-picker.js +1 -0
  201. package/dist/esm/components/db-timeline.d.ts +29 -0
  202. package/dist/esm/components/db-timeline.js +1 -0
  203. package/dist/esm/components/db-toast.d.ts +23 -0
  204. package/dist/esm/components/db-toast.js +1 -0
  205. package/dist/esm/components/db-toggle.d.ts +35 -0
  206. package/dist/esm/components/db-toggle.js +1 -0
  207. package/dist/esm/components/db-toolbar.d.ts +25 -0
  208. package/dist/esm/components/db-toolbar.js +1 -0
  209. package/dist/esm/components/db-tooltip.d.ts +58 -0
  210. package/dist/esm/components/db-tooltip.js +1 -0
  211. package/dist/esm/components/db-top-banner.d.ts +17 -0
  212. package/dist/esm/components/db-top-banner.js +1 -0
  213. package/dist/esm/components/db-tutorial.d.ts +54 -0
  214. package/dist/esm/components/db-tutorial.js +1 -0
  215. package/dist/esm/components/db-video-player.d.ts +67 -0
  216. package/dist/esm/components/db-video-player.js +1 -0
  217. package/dist/esm/components/db-youtube-player.d.ts +22 -0
  218. package/dist/esm/components/db-youtube-player.js +1 -0
  219. package/dist/esm/components/highlight-code.js +1 -0
  220. package/dist/esm/components/input-validation.js +1 -0
  221. package/dist/esm/components/number-scrub.js +1 -0
  222. package/dist/esm/components/random-gradient-palettes.js +1 -0
  223. package/dist/esm/helpers/confirm.d.ts +30 -0
  224. package/dist/esm/helpers/confirm.js +1 -0
  225. package/dist/esm/helpers/toast.d.ts +56 -0
  226. package/dist/esm/helpers/toast.js +1 -0
  227. package/dist/esm/index.d.ts +102 -0
  228. package/dist/esm/index.js +1 -0
  229. package/dist/esm/node_modules/prismjs/components/prism-bash.js +1 -0
  230. package/dist/esm/node_modules/prismjs/components/prism-clike.js +1 -0
  231. package/dist/esm/node_modules/prismjs/components/prism-css.js +1 -0
  232. package/dist/esm/node_modules/prismjs/components/prism-javascript.js +1 -0
  233. package/dist/esm/node_modules/prismjs/components/prism-json.js +1 -0
  234. package/dist/esm/node_modules/prismjs/components/prism-jsx.js +1 -0
  235. package/dist/esm/node_modules/prismjs/components/prism-markup.js +1 -0
  236. package/dist/esm/node_modules/prismjs/components/prism-scss.js +1 -0
  237. package/dist/esm/node_modules/prismjs/components/prism-tsx.js +1 -0
  238. package/dist/esm/node_modules/prismjs/components/prism-typescript.js +1 -0
  239. package/dist/index.cjs +1 -1
  240. package/dist/index.css +1 -1
  241. package/dist/index.d.ts +475 -12
  242. package/dist/index.esm.js +1 -1
  243. package/dist/react/chunks/lottie-14e7addb.js +1 -0
  244. package/dist/react/index.cjs +1 -1
  245. package/dist/react/index.d.ts +604 -64
  246. package/dist/react/index.esm.js +1 -1
  247. package/package.json +10 -2
  248. package/dist/react/chunks/lottie-eed75107.js +0 -1
  249. /package/dist/chunks/{lottie-2c3b8673.js → lottie-1e5700ad.js} +0 -0
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @designbasekorea/ui-wc
2
2
 
3
- Designbase **Web Components** — Vue 3, Angular, React, vanilla HTML에서 공통으로 사용하는 웹 컴포넌트 원본입니다.
3
+ Designbase **Web Components** — Vue 3, Angular, React, vanilla HTML에서 공통으로 사용하는 웹 컴포넌트 라이브러리입니다.
4
4
 
5
- React 사용자는 `@designbasekorea/ui-wc/react`의 `Button`, `Input`, `Tabs` wrapper를 사용할 수 있습니다. vanilla/Vue/Angular는 `<db-button>` 같은 Custom Elements를 직접 사용할 수 있습니다. 기존 `@designbasekorea/ui` React 패키지는 별도 레거시/완성형 패키지로 유지합니다.
5
+ 100여 개의 커스텀 엘리먼트를 제공하며, React 전용 wrapper(`@designbasekorea/ui-wc/react`)도 포함합니다.
6
6
 
7
7
  ## 설치
8
8
 
@@ -10,75 +10,368 @@ React 사용자는 `@designbasekorea/ui-wc/react`의 `Button`, `Input`, `Tabs` w
10
10
  npm install @designbasekorea/ui-wc @designbasekorea/tokens @designbasekorea/theme
11
11
  ```
12
12
 
13
- ## 사용법
13
+ ## 기본 사용법
14
14
 
15
15
  ```ts
16
+ // CSS (필수 — 순서 중요)
16
17
  import '@designbasekorea/tokens/dist/css/tokens.css';
17
18
  import '@designbasekorea/theme/dist/css/theme.css';
18
19
  import '@designbasekorea/ui-wc/dist/index.css';
20
+
21
+ // 전체 등록 (모든 컴포넌트를 한 번에)
19
22
  import '@designbasekorea/ui-wc';
20
23
  ```
21
24
 
22
25
  ```html
23
26
  <db-button variant="primary">저장</db-button>
24
27
  <db-input label="이메일" placeholder="you@example.com"></db-input>
25
- <db-tabs labels="홈,탐색,알림" active-index="0"></db-tabs>
28
+ <db-tabs items='[{"id":"a","label":"홈"},{"id":"b","label":"탐색"}]'></db-tabs>
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 트리셰이킹 / 개별 import
34
+
35
+ 빌드 번들 크기를 줄이려면 `./components/*` 경로로 개별 임포트합니다. 사용한 컴포넌트만 번들에 포함됩니다.
36
+
37
+ ```ts
38
+ import '@designbasekorea/tokens/dist/css/tokens.css';
39
+ import '@designbasekorea/theme/dist/css/theme.css';
40
+ import '@designbasekorea/ui-wc/dist/index.css';
41
+
42
+ // 필요한 컴포넌트만 임포트
43
+ import '@designbasekorea/ui-wc/components/db-button';
44
+ import '@designbasekorea/ui-wc/components/db-input';
45
+ ```
46
+
47
+ TypeScript에서 클래스를 직접 임포트할 수도 있습니다.
48
+
49
+ ```ts
50
+ import { DbButton } from '@designbasekorea/ui-wc/components/db-button';
26
51
  ```
27
52
 
53
+ ---
54
+
28
55
  ## React wrapper
29
56
 
30
57
  ```tsx
31
58
  import '@designbasekorea/tokens/dist/css/tokens.css';
32
59
  import '@designbasekorea/theme/dist/css/theme.css';
33
60
  import '@designbasekorea/ui-wc/dist/index.css';
34
- import { Button } from '@designbasekorea/ui-wc/react';
61
+ import { Button, Input, Toggle } from '@designbasekorea/ui-wc/react';
62
+
63
+ <Button variant="primary" onDbClick={() => save()}>저장</Button>
64
+ <Input label="이메일" onChange={e => setValue(e.detail.value)} />
65
+ <Toggle checked={agreed} onDbChange={e => setAgreed(e.detail.checked)} />
66
+ ```
67
+
68
+ ---
69
+
70
+ ## 명령형 헬퍼
71
+
72
+ DOM 없이 JavaScript로 토스트·확인 다이얼로그를 직접 제어합니다.
73
+
74
+ ### toast
75
+
76
+ ```ts
77
+ import { toast } from '@designbasekorea/ui-wc';
78
+
79
+ // 단축 메서드
80
+ toast.success('저장되었습니다');
81
+ toast.error('오류가 발생했습니다', { description: '잠시 후 다시 시도하세요' });
82
+ toast.warning('용량이 거의 찼습니다');
83
+ toast.info('업데이트가 준비됐습니다');
84
+
85
+ // 전체 옵션
86
+ toast({
87
+ title: '처리 중…',
88
+ status: 'info',
89
+ duration: 0, // 0이면 수동으로 닫을 때까지 유지
90
+ position: 'bottom-center',
91
+ showProgress: true,
92
+ });
35
93
 
36
- <Button variant="primary" onPress={() => save()}>
37
- 저장
38
- </Button>
94
+ // 수동 제어
95
+ const handle = toast.success('파일 업로드 완료');
96
+ handle.close(); // 프로그래밍으로 닫기
97
+
98
+ // 전체 닫기
99
+ toast.dismissAll();
100
+ toast.dismissAll('top-right'); // 특정 위치만
101
+ ```
102
+
103
+ **position 옵션:** `top-right` (기본) · `top-left` · `top-center` · `bottom-right` · `bottom-left` · `bottom-center`
104
+
105
+ ### confirm
106
+
107
+ ```ts
108
+ import { confirm } from '@designbasekorea/ui-wc';
109
+ // 전역 confirm과 충돌을 피하려면:
110
+ import { dbConfirm } from '@designbasekorea/ui-wc';
111
+
112
+ const ok = await confirm({
113
+ title: '정말 삭제하시겠습니까?',
114
+ message: '이 작업은 되돌릴 수 없습니다.',
115
+ variant: 'danger',
116
+ confirmText: '삭제',
117
+ cancelText: '취소',
118
+ });
119
+ if (ok) deleteItem();
120
+ ```
121
+
122
+ ---
123
+
124
+ ## property 설정 (복합 데이터)
125
+
126
+ JSON 문자열 속성 대신 JavaScript 배열·객체를 직접 할당할 수 있습니다.
127
+
128
+ ```ts
129
+ const tabs = document.querySelector('db-tabs');
130
+
131
+ // 이전 방식 (여전히 동작)
132
+ tabs.setAttribute('items', JSON.stringify([{ id: 'a', label: '홈' }]));
133
+
134
+ // 권장 방식 — property setter
135
+ tabs.items = [
136
+ { id: 'home', label: '홈' },
137
+ { id: 'search', label: '탐색' },
138
+ ];
139
+
140
+ const navbar = document.querySelector('db-navbar');
141
+ navbar.items = [{ label: '소개', href: '/about' }];
142
+ navbar.userProfile = { name: '홍길동', avatar: '/avatar.png' };
143
+ navbar.userProfile = null; // 프로필 영역 제거
39
144
  ```
40
145
 
41
- ## 컴포넌트 (11개)
146
+ property setter를 지원하는 컴포넌트: `db-tabs`, `db-navbar`, `db-sidebar`, `db-bottom-navigation`, `db-tutorial`, `db-gradient`, `db-section-feature`, `db-section-hero`, `db-section-app-download`, `db-table`
147
+
148
+ ---
149
+
150
+ ## 폼 통합
151
+
152
+ `db-toggle`과 `db-select`는 `formAssociated = true`를 지원해 네이티브 `<form>` 제출에 참여합니다.
153
+
154
+ ```html
155
+ <form id="settings-form">
156
+ <db-toggle name="notify" value="yes"></db-toggle>
157
+ <db-select name="lang" options='[{"value":"ko","label":"한국어"},{"value":"en","label":"English"}]'></db-select>
158
+ <button type="submit">저장</button>
159
+ </form>
160
+ ```
161
+
162
+ ```ts
163
+ document.getElementById('settings-form').addEventListener('submit', e => {
164
+ const data = new FormData(e.target);
165
+ // data.get('notify') → 'yes' (토글이 켜진 경우)
166
+ // data.get('lang') → 'ko'
167
+ });
168
+
169
+ // form.reset() 시 자동 초기화
170
+ // form disabled 시 자동 비활성화
171
+ ```
172
+
173
+ `db-input`과 `db-textarea`는 내부 `<input>`/`<textarea>`가 Light DOM에 있어 기존에도 form 제출에 참여하며, 이번 업데이트로 host 엘리먼트에서 네이티브 `input`/`change` 이벤트도 발행합니다.
174
+
175
+ ```ts
176
+ // host 엘리먼트에서 네이티브 이벤트 수신 가능
177
+ document.querySelector('db-input').addEventListener('change', e => {
178
+ console.log(e.target.value); // e.target === <db-input>
179
+ });
180
+ document.querySelector('db-input').addEventListener('input', handler);
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 컴포넌트 목록
186
+
187
+ > 현재 100개 이상의 컴포넌트를 제공합니다. 전체 목록은 [Storybook](#storybook)을 참고하세요.
188
+
189
+ ### 폼 / 입력
42
190
 
43
191
  | 태그 | 설명 |
44
192
  |------|------|
45
- | `db-button` | 버튼 |
46
- | `db-input` | 텍스트 입력 |
193
+ | `db-button` | 버튼 (variant, size, loading, icon 지원) |
194
+ | `db-input` | 텍스트 입력 (password, search, number scrub 지원) |
195
+ | `db-textarea` | 여러 줄 텍스트 입력 |
196
+ | `db-select` | 드롭다운 선택 (단일/다중, 검색 지원) |
47
197
  | `db-checkbox` | 체크박스 |
48
- | `db-toggle` | 토글 |
49
- | `db-badge` | 뱃지 |
198
+ | `db-toggle` | 토글 스위치 |
199
+ | `db-radio` | 라디오 버튼 |
200
+ | `db-range-slider` | 범위 슬라이더 |
201
+ | `db-rating` | 별점 입력 |
202
+ | `db-color-picker` | 색상 선택기 |
203
+ | `db-date-picker` | 날짜 선택 |
204
+ | `db-time-picker` | 시간 선택 |
205
+ | `db-search-bar` | 검색 바 |
206
+ | `db-form` | 폼 컨테이너 |
207
+
208
+ ### 피드백 / 오버레이
209
+
210
+ | 태그 | 설명 |
211
+ |------|------|
212
+ | `db-modal` | 모달 다이얼로그 |
213
+ | `db-confirm` | 확인 다이얼로그 |
214
+ | `db-toast` | 토스트 알림 |
215
+ | `db-tooltip` | 툴팁 |
216
+ | `db-popover` | 팝오버 |
217
+ | `db-drawer` | 사이드 드로어 |
218
+ | `db-bottom-sheet` | 하단 시트 |
219
+ | `db-alert` | 인라인 알림 |
220
+ | `db-banner` | 배너 |
221
+ | `db-backdrop` | 배경 오버레이 |
50
222
  | `db-spinner` | 로딩 스피너 |
51
- | `db-card` | 카드 |
223
+ | `db-skeleton` | 스켈레톤 로더 |
224
+
225
+ ### 탐색
226
+
227
+ | 태그 | 설명 |
228
+ |------|------|
52
229
  | `db-tabs` | 탭 |
53
- | `db-modal` | 모달 (`<dialog>`) |
54
- | `db-dropdown` | 드롭다운 |
55
- | `db-tooltip` | 툴팁 |
230
+ | `db-navbar` | 상단 네비게이션 |
231
+ | `db-sidebar` | 사이드바 |
232
+ | `db-bottom-navigation` | 하단 탭 네비게이션 |
233
+ | `db-breadcrumbs` | 브레드크럼 |
234
+ | `db-pagination` | 페이지네이션 |
235
+ | `db-page-header` | 페이지 헤더 |
236
+ | `db-segment-control` | 세그먼트 컨트롤 |
237
+ | `db-stepper` | 단계 진행 |
238
+ | `db-progress-step` | 프로그레스 스텝 |
56
239
 
57
- ## 이벤트
240
+ ### 데이터 표시
58
241
 
59
- 커스텀 이벤트는 `db-` 접두사를 사용합니다.
242
+ | 태그 | 설명 |
243
+ |------|------|
244
+ | `db-table` | 테이블 |
245
+ | `db-card` | 카드 |
246
+ | `db-badge` | 뱃지 |
247
+ | `db-chip` | 칩 |
248
+ | `db-avatar` | 아바타 |
249
+ | `db-stat` | 통계 수치 |
250
+ | `db-timeline` | 타임라인 |
251
+ | `db-list` | 리스트 |
252
+ | `db-empty-state` | 빈 상태 |
253
+ | `db-progress` | 진행률 바 |
254
+ | `db-progressbar` | 게이지형 진행바 |
255
+ | `db-indicator` | 단계 표시기 |
256
+ | `db-countdown` | 카운트다운 |
60
257
 
61
- - `db-click` — Button
62
- - `db-input` — Input (`detail.value`)
63
- - `db-change` — Checkbox, Toggle, Tabs, Dropdown
64
- - `db-close` — Modal
258
+ ### 레이아웃
65
259
 
66
- ## 스타일
260
+ | 태그 | 설명 |
261
+ |------|------|
262
+ | `db-container` | 콘텐츠 컨테이너 |
263
+ | `db-stack` | 수직/수평 스택 |
264
+ | `db-grid` · `db-grid-item` | 그리드 레이아웃 |
265
+ | `db-divider` | 구분선 |
266
+ | `db-scroll-area` | 스크롤 영역 |
267
+ | `db-split-view` | 분할 뷰 |
268
+ | `db-resizable-panels` | 크기 조절 패널 |
269
+ | `db-masonry` | 메이슨리 레이아웃 |
270
+ | `db-toolbar` | 툴바 |
271
+ | `db-section` | 섹션 래퍼 |
67
272
 
68
- Light DOM + 글로벌 `--db-*` CSS 변수. 자세한 내용은 [docs/STYLING.md](./docs/STYLING.md).
273
+ ### 미디어
274
+
275
+ | 태그 | 설명 |
276
+ |------|------|
277
+ | `db-image` | 이미지 (lazy load, fallback) |
278
+ | `db-image-list` | 이미지 목록 |
279
+ | `db-lightbox` | 라이트박스 |
280
+ | `db-carousel` | 캐러셀 슬라이더 |
281
+ | `db-video-player` | 비디오 플레이어 |
282
+ | `db-youtube-player` | 유튜브 플레이어 |
283
+ | `db-audio-player` | 오디오 플레이어 |
284
+ | `db-lottie` | Lottie 애니메이션 |
285
+
286
+ ### 기타
287
+
288
+ | 태그 | 설명 |
289
+ |------|------|
290
+ | `db-accordion` | 아코디언 |
291
+ | `db-dropdown` | 드롭다운 메뉴 |
292
+ | `db-context-menu` | 컨텍스트 메뉴 |
293
+ | `db-menu-item` | 메뉴 아이템 |
294
+ | `db-reorder` | 드래그 정렬 |
295
+ | `db-dropzone` | 파일 드롭존 |
296
+ | `db-file-uploader` | 파일 업로더 |
297
+ | `db-code-block` | 코드 블록 |
298
+ | `db-markdown-editor` | 마크다운 에디터 |
299
+ | `db-tutorial` | 온보딩 튜토리얼 |
300
+ | `db-calendar` | 달력 |
301
+ | `db-share` | 공유 버튼 |
302
+ | `db-floating-action-button` | FAB |
303
+ | `db-top-banner` | 최상단 배너 |
304
+ | `db-onboarding-modal` | 온보딩 모달 |
305
+ | `db-label` | 레이블 |
306
+ | `db-logo` | 로고 |
307
+ | `db-gradient` | 그라디언트 배경 |
308
+ | `db-marquee` | 마르키 스크롤 |
309
+ | `db-animation-text` | 텍스트 애니메이션 |
310
+ | `db-animation-background` | 배경 애니메이션 |
311
+ | `db-cursor-follower` | 커서 팔로워 |
312
+ | `db-section-hero` | 히어로 섹션 |
313
+ | `db-section-feature` | 피처 섹션 |
314
+ | `db-section-contact` | 문의 섹션 |
315
+ | `db-section-app-download` | 앱 다운로드 섹션 |
316
+ | `db-app-badge` | 앱스토어/구글플레이 뱃지 |
317
+ | `db-ad-banner` | 광고 배너 |
318
+ | `db-testimonial` | 추천사 |
319
+
320
+ ---
321
+
322
+ ## 주요 이벤트
323
+
324
+ 모든 커스텀 이벤트는 `db-` 접두사를 사용하며 `bubbles: true, composed: true`로 발행됩니다.
325
+
326
+ | 이벤트 | 발행 컴포넌트 | `detail` |
327
+ |--------|-------------|---------|
328
+ | `db-click` | `db-button` | — |
329
+ | `db-input` | `db-input`, `db-textarea` | `{ value: string }` |
330
+ | `db-change` | `db-input`, `db-textarea`, `db-select`, `db-checkbox`, `db-toggle`, `db-radio`, `db-range-slider`, `db-rating`, `db-tabs`, … | `{ value }` 또는 `{ checked }` |
331
+ | `db-focus` / `db-blur` | `db-input`, `db-textarea` | — |
332
+ | `db-open` / `db-close` | `db-modal`, `db-drawer`, `db-bottom-sheet`, `db-toast`, … | — |
333
+ | `db-confirm` / `db-cancel` | `db-confirm` | — |
334
+ | `db-step-change` | `db-tutorial` | `{ step: number }` |
335
+ | `db-page-change` | `db-pagination` | `{ page: number }` |
336
+ | `db-sort` | `db-table` | `{ column, direction }` |
337
+ | `db-select` | `db-table` | `{ selectedRows }` |
338
+
339
+ `db-input`, `db-textarea`는 네이티브 `input` / `change` 이벤트도 host에서 함께 발행합니다.
340
+
341
+ ---
342
+
343
+ ## 스타일 커스터마이징
344
+
345
+ Light DOM 기반으로 렌더링되므로 CSS 선택자로 직접 스타일링할 수 있습니다.
346
+
347
+ ```css
348
+ /* 글로벌 CSS 변수로 테마 조정 */
349
+ :root {
350
+ --db-color-primary: #6366f1;
351
+ --db-radius-m: 8px;
352
+ }
353
+
354
+ /* 또는 컴포넌트 내부 클래스 직접 스타일링 */
355
+ db-button .designbase-wc-button {
356
+ font-weight: 700;
357
+ }
358
+ ```
359
+
360
+ 자세한 내용은 [docs/STYLING.md](./docs/STYLING.md).
361
+
362
+ ---
69
363
 
70
364
  ## 프레임워크별 가이드
71
365
 
72
366
  - [멀티플랫폼 가이드](../../docs/MULTI-PLATFORM-GUIDE.md)
73
- - [WordPress 관리자 연동](../../docs/WORDPRESS-INTEGRATION.md)
74
- - [크로스플랫폼 컴포넌트 전략](../../docs/CROSS_PLATFORM_COMPONENT_STRATEGY.md)
75
367
  - [React 통합](../../docs/REACT-WC-INTEGRATION.md)
76
368
  - [Vue / Angular 통합](../../docs/VUE-ANGULAR-INTEGRATION.md)
369
+ - [WordPress 관리자 연동](../../docs/WORDPRESS-INTEGRATION.md)
370
+ - [크로스플랫폼 컴포넌트 전략](../../docs/CROSS_PLATFORM_COMPONENT_STRATEGY.md)
77
371
 
78
372
  ## Storybook
79
373
 
80
374
  ```bash
81
375
  npm run storybook
376
+ # http://localhost:6007
82
377
  ```
83
-
84
- 포트: `6007`
@@ -0,0 +1 @@
1
+ import{drawFallingParticles as e,drawStars as t,drawParticles as s}from"./renderers.js";import{toSpeedRate as i}from"./lumina-utils.js";const n=["snow","flowers","confetti"];class CanvasAnimationController{constructor(o,a){this.raf=0,this.frameCount=0,this.mouse={x:-9999,y:-9999},this.particlesRef={current:[]},this.starsRef={current:[]},this.fallingRef={current:[]},this.tick=()=>{const o=this.canvas.getContext("2d");if(!o)return void(this.raf=requestAnimationFrame(this.tick));const a=window.devicePixelRatio||1,r=this.canvas.width/a,c=this.canvas.height/a,{type:h,colors:l,speed:u,particleCount:v,particleSize:m,starCount:d,starSize:p,clickable:f,wind:w,layerOpacity:R}=this.options;o.clearRect(0,0,r,c);const g=i(u),y=this.frameCount*g;switch(this.frameCount+=1,h){case"particles":s(o,r,c,this.particlesRef,{count:v,colors:l,size:m,speed:u,mouse:this.mouse,clickable:f,layerOpacity:R});break;case"stars":t(o,r,c,this.starsRef,{count:d,colors:l,size:p,time:y,layerOpacity:R,speedRate:g});break;case"snow":case"flowers":case"confetti":(function isFallingType(e){return n.includes(e)})(h)&&e(o,r,c,this.fallingRef,h,{count:v,colors:l,size:m,speed:u,wind:w,layerOpacity:R})}this.raf=requestAnimationFrame(this.tick)},this.container=o,this.options=a,this.canvas=document.createElement("canvas"),this.canvas.className="designbase-wc-animation-background__canvas",o.appendChild(this.canvas),this.onResize=()=>this.resize(),this.onMouseMove=e=>{if("particles"!==this.options.type)return;const t=this.container.getBoundingClientRect();this.mouse={x:e.clientX-t.left,y:e.clientY-t.top}},this.onMouseLeave=()=>{this.mouse={x:-9999,y:-9999}},o.addEventListener("mousemove",this.onMouseMove),o.addEventListener("mouseleave",this.onMouseLeave),window.addEventListener("resize",this.onResize),this.particlesRef.current=[],this.starsRef.current=[],this.fallingRef.current=[],this.frameCount=0,this.resize(),this.tick()}updateOptions(e){this.options={...this.options,...e}}destroy(){cancelAnimationFrame(this.raf),this.container.removeEventListener("mousemove",this.onMouseMove),this.container.removeEventListener("mouseleave",this.onMouseLeave),window.removeEventListener("resize",this.onResize),this.canvas.remove()}resize(){const e=window.devicePixelRatio||1,t=this.container.getBoundingClientRect();this.canvas.width=t.width*e,this.canvas.height=t.height*e,this.canvas.style.width=`${t.width}px`,this.canvas.style.height=`${t.height}px`;const s=this.canvas.getContext("2d");s&&s.setTransform(e,0,0,e,0,0)}}export{CanvasAnimationController};
@@ -0,0 +1 @@
1
+ import{GRAPHITE_PRESET_IDS as e}from"./graphite-presets.js";const t=3e3,r={speed:{attr:"speed",label:"Speed (×)",kind:"range",min:500,max:12e3,step:100,default:t,display:{min:.2,max:4,step:.1,fixed:1,fromAttr:e=>{const r=Math.min(12e3,Math.max(500,e));return Math.round(r/t*10)/10},toAttr:e=>{const r=Math.min(4,Math.max(.2,e));return Math.round(r*t)}}},blur:{attr:"blur",label:"Blur",kind:"range",min:0,max:200,step:2,default:80},opacity:{attr:"opacity",label:"Opacity",kind:"range",min:0,max:1,step:.05,default:1,fixed:2},noise:{attr:"noise",label:"Noise",kind:"range",min:0,max:.4,step:.01,default:.05,fixed:2},zoom:{attr:"zoom",label:"Zoom",kind:"range",min:.5,max:3,step:.1,default:1,fixed:1},particleCount:{attr:"particle-count",label:"Particle Count",kind:"range",min:10,max:250,step:5,default:50},particleCountParticles:{attr:"particle-count",label:"Particle Count",kind:"range",min:10,max:250,step:5,default:15},particleSize:{attr:"particle-size",label:"Particle Size",kind:"range",min:1,max:10,step:.5,default:2,fixed:1},starCount:{attr:"star-count",label:"Star Count",kind:"range",min:20,max:500,step:10,default:100},starSize:{attr:"star-size",label:"Star Size",kind:"range",min:.5,max:6,step:.5,default:1.5,fixed:1},wind:{attr:"wind",label:"Wind",kind:"range",min:0,max:3,step:.1,default:.5,fixed:1},direction:{attr:"direction",label:"Direction",kind:"select",options:["left","right","up","down","diagonal","radial"],default:"left"},intensity:{attr:"intensity",label:"Intensity",kind:"select",options:["subtle","medium","vivid"],default:"subtle"},theme:{attr:"theme",label:"Theme",kind:"select",options:["dark","light"],default:"dark"},preset:{attr:"preset",label:"Preset",kind:"select",options:["(none)","neon_dream","sunset_bliss","deep_ocean","forest_mist","northern_lights","monochrome_fog","cotton_candy","cyber_glitch","golden_hour"],default:"(none)"},showVignette:{attr:"show-vignette",label:"Vignette",kind:"toggle",default:!0},shaderSpeed:{attr:"shader-speed",label:"Speed",kind:"range",min:0,max:3,step:.01,default:.4,fixed:2},shaderIntensity:{attr:"shader-intensity",label:"Intensity",kind:"range",min:.1,max:3,step:.01,default:1.2,fixed:2},grain:{attr:"noise",label:"Grain",kind:"range",min:0,max:.5,step:.01,default:.1,fixed:2},scale:{attr:"zoom",label:"Scale",kind:"range",min:.5,max:5,step:.1,default:1,fixed:1},warp:{attr:"warp",label:"Warp",kind:"range",min:0,max:2,step:.05,default:1.4,fixed:2},graphiteTheme:{attr:"preset",label:"Theme",kind:"select",options:[...e],default:"graphite"}};function colors(e){return{attr:"colors",label:"Colors",kind:"colors",default:e}}const a={particles:[r.particleCountParticles,r.particleSize,r.speed,r.opacity,colors(["#60a5fa","#a78bfa","#f472b6"])],stars:[r.starCount,r.starSize,r.speed,r.opacity,colors(["#ffffff","#e0e7ff","#c7d2fe"])],snow:[r.particleCount,r.particleSize,r.speed,r.wind,colors(["#ffffff","#f0f9ff","#e0f2fe"])],flowers:[r.particleCount,r.particleSize,r.speed,r.wind,colors(["#ffb7c5","#ff91a4","#f8c8dc","#ffc0cb"])],confetti:[r.particleCount,r.particleSize,r.speed,r.wind,colors(["#f44336","#e91e63","#9c27b0","#2196f3","#4caf50","#ffeb3b"])],aurora:[r.intensity,r.blur,r.speed,r.theme,colors(["#4f46e5","#ec4899","#06b6d4","#8b5cf6"])],plasma:[r.speed,r.blur,r.noise,r.showVignette,r.preset,colors(["#7000FF","#FF00AA","#3300FF","#FFCC00","#00FFFF"])],"mesh-flow":[r.speed,r.blur,r.noise,r.zoom,colors(["#4f46e5","#ec4899","#06b6d4","#8b5cf6","#22d3ee"])],fluid:[r.speed,r.blur,r.noise,r.zoom,colors(["#001133","#0044FF","#00DDFF","#00FFAA","#000066"])],radiant:[r.speed,r.blur,r.noise,r.zoom,colors(["#FF4E50","#FC913A","#F9D423","#EDE574","#E1F5C4"])],ethereal:[r.speed,r.blur,r.noise,r.zoom,colors(["#7000FF","#FF00AA","#00FFFF","#FFFFFF","#3300FF"])],graphite:[r.shaderSpeed,r.shaderIntensity,r.grain,r.scale,r.warp,r.graphiteTheme,colors(["#000000","#333333","#b3b3b3"])]};function getControlsForType(e){return a[e]??a.graphite}function getControlSliderBounds(e){return e.display?{min:e.display.min,max:e.display.max,step:e.display.step,fixed:e.display.fixed}:{min:e.min??0,max:e.max??100,step:e.step??1,fixed:e.fixed}}function controlAttrToSlider(e,t){return e.display?e.display.fromAttr(t):t}function controlSliderToAttr(e,t){return e.display?e.display.toAttr(t):t}function readControlValue(e,t){const r=e.getAttribute(t.attr);if("colors"===t.kind){if(!r)return[...t.default];try{const e=JSON.parse(r);return Array.isArray(e)&&e.length?[...e]:[...t.default]}catch{const e=r.split(",").map(e=>e.trim()).filter(Boolean);return e.length?e:[...t.default]}}if("toggle"===t.kind)return null===r?t.default:"false"!==r;if("select"===t.kind)return r||t.default;if(null===r||""===r)return t.default;const a=Number(r);return Number.isFinite(a)?a:t.default}function writeControlAttribute(e,t,r){"colors"!==t.kind?"toggle"!==t.kind?"select"!==t.kind?e.setAttribute(t.attr,String(r)):"(none)"===r?e.removeAttribute(t.attr):e.setAttribute(t.attr,String(r)):e.setAttribute(t.attr,r?"true":"false"):e.setAttribute(t.attr,JSON.stringify(r))}function resetControlsToDefaults(e,t){t.forEach(t=>{const r=t.default;"select"!==t.kind||r!==t.default?writeControlAttribute(e,t,Array.isArray(r)?[...r]:r):"(none)"===r?e.removeAttribute(t.attr):writeControlAttribute(e,t,r)})}export{controlAttrToSlider,controlSliderToAttr,getControlSliderBounds,getControlsForType,readControlValue,resetControlsToDefaults,writeControlAttribute};
@@ -0,0 +1 @@
1
+ import{hexToRgb as r}from"./lumina-utils.js";import{GRAPHITE_VS_SOURCE as e,GRAPHITE_FS_SOURCE as t}from"./graphite-shader.js";const i=.05;function loadShader(r,e,t){const i=r.createShader(e);return i?(r.shaderSource(i,t),r.compileShader(i),r.getShaderParameter(i,r.COMPILE_STATUS)?i:(r.deleteShader(i),null)):null}function lerp(r,e,t){return r+(e-r)*t}function lerpRgb(r,e,t){return[lerp(r[0],e[0],t),lerp(r[1],e[1],t),lerp(r[2],e[2],t)]}class GraphiteShaderController{constructor(r,e){this.raf=0,this.startTime=performance.now(),this.current={shaderSpeed:0,shaderIntensity:0,grain:0,scale:0,warp:0,color1:[0,0,0],color2:[0,0,0],color3:[0,0,0]},this.render=()=>{const r=this.gl,e=this.program,t=this.positionBuffer;if(!r||!e||!t)return;this.tickLerp();const{width:i,height:n}=this.resizeCanvas();if(0===i||0===n)return void(this.raf=requestAnimationFrame(this.render));r.viewport(0,0,i,n),r.useProgram(e);const s=r.getAttribLocation(e,"aVertexPosition"),o=r.getUniformLocation(e,"uResolution"),a=r.getUniformLocation(e,"uTime"),h=r.getUniformLocation(e,"uSpeed"),c=r.getUniformLocation(e,"uIntensity"),u=r.getUniformLocation(e,"uGrain"),l=r.getUniformLocation(e,"uScale"),d=r.getUniformLocation(e,"uWarp"),f=r.getUniformLocation(e,"uColor1"),m=r.getUniformLocation(e,"uColor2"),p=r.getUniformLocation(e,"uColor3");r.enableVertexAttribArray(s),r.bindBuffer(r.ARRAY_BUFFER,t),r.vertexAttribPointer(s,2,r.FLOAT,!1,0,0);const g=(performance.now()-this.startTime)/1e3;o&&r.uniform2f(o,i,n),a&&r.uniform1f(a,g),h&&r.uniform1f(h,this.current.shaderSpeed),c&&r.uniform1f(c,this.current.shaderIntensity),u&&r.uniform1f(u,this.current.grain),l&&r.uniform1f(l,this.current.scale),d&&r.uniform1f(d,this.current.warp),f&&r.uniform3fv(f,this.current.color1),m&&r.uniform3fv(m,this.current.color2),p&&r.uniform3fv(p,this.current.color3),r.drawArrays(r.TRIANGLE_STRIP,0,4),this.raf=requestAnimationFrame(this.render)},this.container=r,this.options=e,this.canvas=document.createElement("canvas"),this.canvas.className="designbase-wc-animation-background__shader-canvas",r.appendChild(this.canvas),this.syncCurrentImmediate(e),this.init()}updateOptions(r){this.options={...this.options,...r}}syncCurrentImmediate(e){const[t,i,n]=this.resolveColors(e.colors);this.current={shaderSpeed:e.shaderSpeed,shaderIntensity:e.shaderIntensity,grain:e.grain,scale:e.scale,warp:e.warp,color1:r(t),color2:r(i),color3:r(n)}}resolveColors(r){return[r[0]??"#000000",r[1]??"#333333",r[2]??"#b3b3b3"]}resizeCanvas(){const r=this.container.getBoundingClientRect(),e=window.devicePixelRatio||1;return this.canvas.width=Math.max(1,r.width*e),this.canvas.height=Math.max(1,r.height*e),this.canvas.style.width=`${r.width}px`,this.canvas.style.height=`${r.height}px`,{width:this.canvas.width,height:this.canvas.height}}init(){const r=this.canvas.getContext("webgl");if(!r)return;this.gl=r;const i=r.createProgram();if(!i)return;const n=loadShader(r,r.VERTEX_SHADER,e),s=loadShader(r,r.FRAGMENT_SHADER,t);if(!n||!s)return;if(r.attachShader(i,n),r.attachShader(i,s),r.linkProgram(i),!r.getProgramParameter(i,r.LINK_STATUS))return;this.program=i,this.vertexShader=n,this.fragmentShader=s;const o=r.createBuffer();o&&(this.positionBuffer=o,r.bindBuffer(r.ARRAY_BUFFER,o),r.bufferData(r.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),r.STATIC_DRAW),this.observer=new ResizeObserver(()=>this.resizeCanvas()),this.observer.observe(this.container),this.startTime=performance.now(),this.render())}tickLerp(){const{colors:e,shaderSpeed:t,shaderIntensity:n,grain:s,scale:o,warp:a}=this.options,[h,c,u]=this.resolveColors(e),l=r(h),d=r(c),f=r(u);this.current.shaderSpeed=lerp(this.current.shaderSpeed,t,i),this.current.shaderIntensity=lerp(this.current.shaderIntensity,n,i),this.current.grain=lerp(this.current.grain,s,i),this.current.scale=lerp(this.current.scale,o,i),this.current.warp=lerp(this.current.warp,a,i),this.current.color1=lerpRgb(this.current.color1,l,i),this.current.color2=lerpRgb(this.current.color2,d,i),this.current.color3=lerpRgb(this.current.color3,f,i)}destroy(){cancelAnimationFrame(this.raf),this.observer?.disconnect();const r=this.gl;r&&this.program&&(this.vertexShader&&r.deleteShader(this.vertexShader),this.fragmentShader&&r.deleteShader(this.fragmentShader),this.positionBuffer&&r.deleteBuffer(this.positionBuffer),r.deleteProgram(this.program)),this.canvas.remove()}}export{GraphiteShaderController};
@@ -0,0 +1 @@
1
+ const e={graphite:{id:"graphite",colors:["#000000","#333333","#b3b3b3"],scale:1},abyss:{id:"abyss",colors:["#020617","#0f172a","#3b82f6"],scale:2.2},cherry:{id:"cherry",colors:["#1a0505","#4a0b1c","#e11d48"],scale:2.8},forest:{id:"forest",colors:["#021207","#064e3b","#10b981"],scale:2},sunset:{id:"sunset",colors:["#170500","#7c2d12","#f97316"],scale:3},amethyst:{id:"amethyst",colors:["#0f051a","#3b0764","#a855f7"],scale:2.4}},s=e.graphite.colors,r=Object.keys(e);function isGraphitePresetId(s){return Boolean(s&&s in e)}function getGraphitePreset(s){return e[s]}export{s as GRAPHITE_DEFAULT_COLORS,e as GRAPHITE_PRESETS,r as GRAPHITE_PRESET_IDS,getGraphitePreset,isGraphitePresetId};
@@ -0,0 +1 @@
1
+ const n="\n attribute vec4 aVertexPosition;\n void main() {\n gl_Position = aVertexPosition;\n }\n",e="\n precision highp float;\n uniform vec2 uResolution;\n uniform float uTime;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uGrain;\n uniform float uScale;\n uniform float uWarp;\n uniform vec3 uColor1;\n uniform vec3 uColor2;\n uniform vec3 uColor3;\n\n vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}\n vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}\n vec3 fade(vec3 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);}\n\n float cnoise(vec3 P){\n vec3 Pi0 = floor(P);\n vec3 Pi1 = Pi0 + vec3(1.0);\n Pi0 = mod(Pi0, 289.0);\n Pi1 = mod(Pi1, 289.0);\n vec3 Pf0 = fract(P);\n vec3 Pf1 = Pf0 - vec3(1.0);\n vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);\n vec4 iy = vec4(Pi0.yy, Pi1.yy);\n vec4 iz0 = Pi0.zzzz;\n vec4 iz1 = Pi1.zzzz;\n\n vec4 ixy = permute(permute(ix) + iy);\n vec4 ixy0 = permute(ixy + iz0);\n vec4 ixy1 = permute(ixy + iz1);\n\n vec4 gx0 = ixy0 / 7.0;\n vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5;\n gx0 = fract(gx0);\n vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);\n vec4 sz0 = step(gz0, vec4(0.0));\n gx0 -= sz0 * (step(0.0, gx0) - 0.5);\n gy0 -= sz0 * (step(0.0, gy0) - 0.5);\n\n vec4 gx1 = ixy1 / 7.0;\n vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5;\n gx1 = fract(gx1);\n vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);\n vec4 sz1 = step(gz1, vec4(0.0));\n gx1 -= sz1 * (step(0.0, gx1) - 0.5);\n gy1 -= sz1 * (step(0.0, gy1) - 0.5);\n\n vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);\n vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);\n vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);\n vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);\n vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);\n vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);\n vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);\n vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);\n\n vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));\n g000 *= norm0.x;\n g010 *= norm0.y;\n g100 *= norm0.z;\n g110 *= norm0.w;\n vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));\n g001 *= norm1.x;\n g011 *= norm1.y;\n g101 *= norm1.z;\n g111 *= norm1.w;\n\n float n000 = dot(g000, Pf0);\n float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));\n float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));\n float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));\n float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));\n float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));\n float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));\n float n111 = dot(g111, Pf1);\n\n vec3 fade_xyz = fade(Pf0);\n vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);\n vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);\n float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);\n return 2.2 * n_xyz;\n }\n\n void main() {\n vec2 p = gl_FragCoord.xy / uResolution.xy;\n float base = p.x * 0.5 + p.y * 0.5;\n\n float n = cnoise(vec3(p * uScale, uTime * uSpeed)) * 0.5 + 0.5;\n float n2 = cnoise(vec3(p * (uScale * 1.5) - (n * uWarp), uTime * (uSpeed * 1.2))) * 0.5 + 0.5;\n\n float mask = (base * 0.2 + n * 0.5 + n2 * 0.3) * uIntensity;\n\n vec3 color = mix(uColor1, uColor2, smoothstep(0.1, 0.6, mask));\n color = mix(color, uColor3, smoothstep(0.5, 0.9, mask));\n\n float grain = fract(sin(dot(p + fract(uTime), vec2(12.9898, 78.233))) * 43758.5453);\n color += (grain - 0.5) * uGrain;\n\n gl_FragColor = vec4(color, 1.0);\n }\n";export{e as GRAPHITE_FS_SOURCE,n as GRAPHITE_VS_SOURCE};
@@ -0,0 +1 @@
1
+ import{LUMINA_NOISE_SVG as e,isLuminaType as t,FLUID_DEFAULT_COLORS as a,padColors as r,toAnimationDurationSec as n,LUMINA_ANIMATION_DURATION_SEC as s,toLuminaSpeed as i}from"./lumina-utils.js";import{getLuminaPresetColors as o}from"./lumina-presets.js";import{getGraphitePreset as l,GRAPHITE_DEFAULT_COLORS as d,isGraphitePresetId as m}from"./graphite-presets.js";import{getFallingParticleDefaults as u}from"./particle-defaults.js";import{CanvasAnimationController as p}from"./canvas-controller.js";import{ShaderAnimationController as g}from"./shader-controller.js";import{GraphiteShaderController as b}from"./graphite-controller.js";const f="designbase-wc-animation-background",h="graphite",y=new Set(["particles","stars","snow","flowers","confetti","aurora","plasma","mesh-flow","fluid","radiant","ethereal","graphite"]);function parseColors(e,t){if(!e)return t;try{const a=JSON.parse(e);return Array.isArray(a)&&a.length?a:t}catch{return e.split(",").map(e=>e.trim()).filter(Boolean)}}function parseAnimationBackgroundConfig(e){const t=function normalizeAnimationType(e){return e&&"gradient"!==e&&y.has(e)?e:h}(e.getAttribute("type")),a="light"===e.getAttribute("theme")?"light":"dark",r=e.getAttribute("intensity")||"subtle",n=e.getAttribute("preset")||void 0,s=e.getAttribute("zoom"),i="graphite"===t;let o=Number(s||1);if(i&&null===s){const e=m(n)?n:"graphite";o=l(e).scale}return{type:t,theme:a,intensity:r,blur:Number(e.getAttribute("blur")||80),speed:Number(e.getAttribute("speed")||3e3),direction:e.getAttribute("direction")||"left",colors:parseColors(e.getAttribute("colors"),i?[...d]:["#667eea","#764ba2","#f093fb"]),opacity:Number(e.getAttribute("opacity")||1),particleCount:Number(e.getAttribute("particle-count")||("particles"===t?15:50)),particleSize:Number(e.getAttribute("particle-size")||2),starCount:Number(e.getAttribute("star-count")||100),starSize:Number(e.getAttribute("star-size")||1.5),clickable:e.hasAttribute("clickable")&&"false"!==e.getAttribute("clickable"),wind:Number(e.getAttribute("wind")||.5),noise:Number(e.getAttribute("noise")??(i?.1:.05)),showVignette:!e.hasAttribute("show-vignette")||"false"!==e.getAttribute("show-vignette"),preset:n||(i?"graphite":void 0),zoom:o,shaderSpeed:Number(e.getAttribute("shader-speed")||.4),shaderIntensity:Number(e.getAttribute("shader-intensity")||1.2),warp:Number(e.getAttribute("warp")||1.4),disabled:e.hasAttribute("disabled")&&"false"!==e.getAttribute("disabled")}}function resolveColors(e){const{type:t,preset:r,colors:n}=e;if("graphite"===t)return r&&m(r)?[...l(r).colors]:n.length>=3?n.slice(0,3):[...d];if(r&&!m(r))return o(r);if("fluid"===t&&n.length<5)return a;if("snow"===t||"flowers"===t||"confetti"===t){const e=u(t);return 3===n.length&&"#667eea"===n[0]&&"#764ba2"===n[1]?e:n}return n}function createLuminaOverlays(t,a){const r=document.createDocumentFragment();if(t>0){const a=document.createElement("div");a.className=`${f}__lumina-noise`,a.style.backgroundImage=`url("${e}")`,a.style.opacity=String(t),r.appendChild(a)}if(a){const e=document.createElement("div");e.className=`${f}__lumina-vignette`,r.appendChild(e)}return r}function syncLuminaOverlays(t,a,r){let n=t.querySelector(`.${f}__lumina-noise`),s=t.querySelector(`.${f}__lumina-vignette`);a>0?(n||(n=document.createElement("div"),n.className=`${f}__lumina-noise`,n.style.backgroundImage=`url("${e}")`,n.style.mixBlendMode="overlay",t.appendChild(n)),n.style.opacity=String(a)):n?.remove(),r?s||(s=document.createElement("div"),s.className=`${f}__lumina-vignette`,t.appendChild(s)):s?.remove()}function mountAnimationLayers(e,t){const a=resolveColors(t);let o={};if(t.disabled)return o;switch(t.type){case"particles":case"stars":case"snow":case"flowers":case"confetti":{const r=document.createElement("div");r.className=`${f}__canvas-layer`,e.appendChild(r);const n=new p(r,{type:t.type,colors:a,speed:t.speed,particleCount:t.particleCount,particleSize:t.particleSize,starCount:t.starCount,starSize:t.starSize,clickable:t.clickable,wind:t.wind,layerOpacity:t.opacity});o={destroy:()=>n.destroy(),update:e=>{const t=resolveColors(e);n.updateOptions({colors:t,speed:e.speed,particleCount:e.particleCount,particleSize:e.particleSize,starCount:e.starCount,starSize:e.starSize,clickable:e.clickable,wind:e.wind,layerOpacity:e.opacity})}};break}case"aurora":e.appendChild(function createMeshAuroraLayer(e,t,a,r,s){const i=document.createElement("div");i.className=`${f}__aurora-mesh`;const o="subtle"===r?.3:"medium"===r?.6:.8,l=n(t,5,1.25),d=e.length>=3?e:["#4f46e5","#ec4899","#06b6d4","#8b5cf6"],m="dark"===s?"screen":"multiply",u=`blur(${a}px)`,p=`${f}__aurora-blob`,g=[{backgroundColor:d[0],top:"-10%",left:"-10%",animationDuration:`${l}s`,animationDelay:"0s"},{backgroundColor:d[1],top:"-10%",right:"-10%",animationDuration:1.2*l+"s",animationDelay:"2s"},{backgroundColor:d[2],bottom:"-20%",left:"20%",animationDuration:1.5*l+"s",animationDelay:"4s"}];d[3]&&g.push({backgroundColor:d[3],bottom:"-10%",right:"-10%",animationDuration:1.1*l+"s",animationDelay:"1s"}),g.forEach(e=>{const t=document.createElement("div");t.className=p,Object.assign(t.style,{filter:u,opacity:String(o),mixBlendMode:m,...e}),i.appendChild(t)});const b=document.createElement("div");return b.className=`${f}__aurora-noise`,b.style.opacity="dark"===s?"0.03":"0.05",b.style.backgroundImage="url(\"data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E\")",i.appendChild(b),i}(a,t.speed,t.blur,t.intensity,t.theme));break;case"plasma":e.appendChild(function createPlasmaLayer(e,t,a){const n=document.createElement("div");n.className=`${f}__plasma`;const o=Math.random().toString(36).slice(2,11),l=r(e),c=e=>l[e%l.length],d=i(t),m=s/d,u=document.createElement("style");u.textContent=`\n @keyframes designbase-wc-plasma-move-1-${o} {\n 0% { transform: translate(0, 0) rotate(0deg) scale(1); }\n 25% { transform: translate(10%, 10%) rotate(90deg) scale(1.2); }\n 50% { transform: translate(0, 20%) rotate(180deg) scale(1); }\n 75% { transform: translate(-10%, 10%) rotate(270deg) scale(0.9); }\n 100% { transform: translate(0, 0) rotate(360deg) scale(1); }\n }\n @keyframes designbase-wc-plasma-move-2-${o} {\n 0% { transform: translate(0, 0) rotate(0deg) scale(1.2); }\n 33% { transform: translate(-20%, 0) rotate(120deg) scale(1); }\n 66% { transform: translate(20%, -10%) rotate(240deg) scale(0.8); }\n 100% { transform: translate(0, 0) rotate(360deg) scale(1.2); }\n }\n @keyframes designbase-wc-plasma-move-3-${o} {\n 0% { transform: translate(0, 0) scale(0.8); }\n 50% { transform: translate(15%, -15%) scale(1.4); }\n 100% { transform: translate(0, 0) scale(0.8); }\n }\n @keyframes designbase-wc-plasma-rotate-${o} {\n 0% { transform: rotate(0deg) scale(1.5); }\n 50% { transform: rotate(180deg) scale(2.0); }\n 100% { transform: rotate(360deg) scale(1.5); }\n }`,n.appendChild(u);const p=document.createElement("div");return p.className=`${f}__plasma-base`,p.style.backgroundColor=c(0),n.appendChild(p),[{top:"-10%",left:"-10%",width:"70%",height:"70%",background:`radial-gradient(circle, ${c(1)} 0%, transparent 70%)`,animation:`designbase-wc-plasma-move-1-${o} ${m}s infinite linear`},{bottom:"-20%",right:"-10%",width:"80%",height:"80%",background:`radial-gradient(circle, ${c(2)} 0%, transparent 70%)`,animation:`designbase-wc-plasma-move-2-${o} ${m}s infinite linear`},{top:"20%",left:"20%",width:"60%",height:"60%",background:`radial-gradient(circle, ${c(3)} 0%, transparent 70%)`,animation:`designbase-wc-plasma-rotate-${o} ${m}s infinite linear`,extraClass:`${f}__plasma-blob--exclusion`},{top:"40%",right:"20%",width:"40%",height:"40%",background:c(4),animation:`designbase-wc-plasma-move-3-${o} ${m}s infinite ease-in-out`,extraClass:`${f}__plasma-blob--accent`,filter:`blur(${a}px)`,opacity:"0.6"}].forEach(e=>{const t=document.createElement("div");t.className=`${f}__plasma-blob${e.extraClass?` ${e.extraClass}`:""}`,Object.assign(t.style,{filter:e.filter||`blur(${a}px)`,opacity:e.opacity||"0.9",...e}),n.appendChild(t)}),n}(a,t.speed,t.blur)),e.appendChild(createLuminaOverlays(t.noise,t.showVignette));break;case"mesh-flow":case"fluid":case"radiant":case"ethereal":{const r=document.createElement("div");r.className=`${f}__shader-layer`,e.appendChild(r);const n=new g(r,{variant:t.type,colors:a,speed:t.speed,blur:t.blur,noise:t.noise,zoom:t.zoom});e.appendChild(createLuminaOverlays(t.noise,t.showVignette)),o={destroy:()=>n.destroy(),update:e=>{const t=resolveColors(e);n.updateOptions({colors:t,speed:e.speed,blur:e.blur,noise:e.noise,zoom:e.zoom})}};break}case"graphite":{const r=document.createElement("div");r.className=`${f}__shader-layer`,e.appendChild(r);const n=new b(r,{colors:a,shaderSpeed:t.shaderSpeed,shaderIntensity:t.shaderIntensity,grain:t.noise,scale:t.zoom,warp:t.warp});o={destroy:()=>n.destroy(),update:e=>{const t=resolveColors(e);n.updateOptions({colors:t,shaderSpeed:e.shaderSpeed,shaderIntensity:e.shaderIntensity,grain:e.noise,scale:e.zoom,warp:e.warp})}};break}}return o}function applyContainerStyles(e,a){const r=t(a.type),n="graphite"===a.type,s=r||n?"#000000":"dark"===a.theme?"var(--db-surface-base, #0f172a)":"var(--db-surface-base, #ffffff)";e.style.position="relative",e.style.overflow="hidden",e.style.backgroundColor=s}export{f as ANIMATION_BACKGROUND_CLASS,applyContainerStyles,mountAnimationLayers,parseAnimationBackgroundConfig,syncLuminaOverlays};
@@ -0,0 +1 @@
1
+ const F=[{id:"neon_dream",name:"Neon Dream",colors:["#7000FF","#FF00AA","#3300FF","#FFCC00","#00FFFF"]},{id:"sunset_bliss",name:"Sunset Bliss",colors:["#FF9900","#FF00CC","#6600FF","#FF5500","#220055"]},{id:"deep_ocean",name:"Deep Ocean",colors:["#001133","#0044FF","#00DDFF","#00FFAA","#000066"]},{id:"forest_mist",name:"Forest Mist",colors:["#002200","#00FF44","#AAFF00","#006622","#CCFFCC"]},{id:"northern_lights",name:"Northern Lights",colors:["#000000","#00FF99","#AA00FF","#0044FF","#FFFFFF"]},{id:"monochrome_fog",name:"Monochrome Fog",colors:["#000000","#333333","#888888","#CCCCCC","#FFFFFF"]},{id:"cotton_candy",name:"Cotton Candy",colors:["#FFC0CB","#87CEFA","#E0FFFF","#DDA0DD","#FF69B4"]},{id:"cyber_glitch",name:"Cyber Glitch",colors:["#1A1A1D","#C3073F","#6F2232","#950740","#4E4E50"]},{id:"golden_hour",name:"Golden Hour",colors:["#FF4E50","#FC913A","#F9D423","#EDE574","#E1F5C4"]}];function getLuminaPresetColors(o){const e=F.find(F=>F.id===o);return e?.colors??F[0].colors}export{F as LUMINA_COLOR_PRESETS,getLuminaPresetColors};
@@ -0,0 +1 @@
1
+ const o="\n attribute vec4 aVertexPosition;\n void main() {\n gl_Position = aVertexPosition;\n }\n";function getLuminaFragmentShader(o){switch(o){case"mesh-flow":return"\n precision highp float;\n uniform vec2 uResolution;\n uniform float uTime;\n uniform vec3 uColors[5];\n uniform float uSpeed;\n uniform float uSoftness;\n uniform float uZoom;\n void main() {\n vec2 uv = gl_FragCoord.xy / uResolution.xy;\n float aspect = uResolution.x / uResolution.y;\n vec2 p = (uv - 0.5) / max(0.25, uZoom) + 0.5;\n p.x *= aspect;\n float t = uTime * uSpeed * 0.1;\n vec3 col = mix(uColors[0], uColors[4], uv.y * 0.6 + 0.2);\n for(int i = 1; i < 4; i++) {\n float fi = float(i);\n float offset = fi * 4.0;\n vec2 q = p;\n q.x += sin(q.y * 1.5 + t + offset) * 0.2;\n q.y += cos(q.x * 0.8 - t + offset) * 0.1;\n float waveCenterY = 0.5 + 0.3 * sin(q.x * 1.0 + t * 0.8 + offset);\n float thickness = 0.15 + 0.15 * sin(q.x * 2.5 + t * 1.2 + offset);\n float w = thickness * (1.0 + uSoftness * 3.0);\n float dist = abs(q.y - waveCenterY);\n float blurAmount = 0.1 + uSoftness * 0.4;\n float intensity = smoothstep(w + blurAmount, w - blurAmount, dist);\n intensity *= 0.7;\n vec3 bandColor = uColors[i];\n bandColor = mix(bandColor, uColors[i+1], sin(p.x + t)*0.2 + 0.2);\n col = mix(col, bandColor, intensity);\n }\n float noise = fract(sin(dot(gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453);\n col += (noise - 0.5) * 0.03;\n gl_FragColor = vec4(col, 1.0);\n }\n";case"radiant":return"\n precision highp float;\n uniform vec2 uResolution;\n uniform float uTime;\n uniform vec3 uColors[5];\n uniform float uNoiseStrength;\n uniform float uSoftness;\n uniform float uZoom;\n float random(vec2 st) {\n return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);\n }\n void main() {\n vec2 uv = gl_FragCoord.xy / uResolution.xy;\n float aspect = uResolution.x / uResolution.y;\n uv = (uv - 0.5) / max(0.25, uZoom) + 0.5;\n uv.x *= aspect;\n float t = uTime * 0.15;\n vec3 col = uColors[0];\n for(int i = 1; i < 5; i++) {\n float fi = float(i);\n vec2 pos = vec2(\n 0.5 * aspect + 0.4 * sin(t * (0.5 + fi * 0.2) + fi * 1.5),\n 0.5 + 0.4 * cos(t * (0.4 + fi * 0.15) + fi)\n );\n float d = length(uv - pos);\n float radius = 0.6 + uSoftness * 1.0;\n float intensity = smoothstep(radius, 0.0, d);\n col = mix(col, uColors[i], intensity * 0.7);\n }\n float grain = random(gl_FragCoord.xy + uTime);\n col += (grain - 0.5) * uNoiseStrength;\n gl_FragColor = vec4(col, 1.0);\n }\n";case"ethereal":return"\n precision highp float;\n uniform vec2 uResolution;\n uniform float uTime;\n uniform vec3 uColors[5];\n uniform float uNoiseStrength;\n uniform float uSoftness;\n uniform float uZoom;\n float random (in vec2 st) {\n return fract(sin(dot(st.xy, vec2(12.9898,78.233)))*43758.5453123);\n }\n float noise (in vec2 st) {\n vec2 i = floor(st);\n vec2 f = fract(st);\n vec2 u = f*f*(3.0-2.0*f);\n return mix( mix( random( i + vec2(0.0,0.0) ),\n random( i + vec2(1.0,0.0) ), u.x),\n mix( random( i + vec2(0.0,1.0) ),\n random( i + vec2(1.0,1.0) ), u.x), u.y);\n }\n #define OCTAVES 5\n float fbm (in vec2 st) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVES; i++) {\n value += amplitude * noise(st);\n st *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n void main() {\n vec2 uv = gl_FragCoord.xy/uResolution.xy;\n float aspect = uResolution.x/uResolution.y;\n uv = (uv - 0.5) / max(0.25, uZoom) + 0.5;\n uv.x *= aspect;\n float t = uTime * 0.8;\n float scale = 5.0 - uSoftness * 3.0;\n vec2 st = uv * scale;\n vec2 q = vec2(0.);\n q.x = fbm( st + 0.12*t );\n q.y = fbm( st + vec2(1.0) + 0.10*t );\n vec2 r = vec2(0.);\n r.x = fbm( st + 1.0*q + vec2(1.7,9.2)+ 0.30*t );\n r.y = fbm( st + 1.0*q + vec2(8.3,2.8)+ 0.26*t );\n float f = fbm(st + r);\n vec3 color = mix(uColors[0], uColors[1], clamp((f*f)*4.0,0.0,1.0));\n color = mix(color, uColors[2], clamp(length(q),0.0,1.0));\n color = mix(color, uColors[3], clamp(length(r.x),0.0,1.0));\n color = mix(color, uColors[4], clamp(r.y*r.y, 0.0, 1.0));\n float grain = random(gl_FragCoord.xy + uTime);\n color += (grain - 0.5) * uNoiseStrength;\n gl_FragColor = vec4(color,1.0);\n }\n";default:return"\n precision highp float;\n uniform vec2 uResolution;\n uniform float uTime;\n uniform vec3 uColors[5];\n uniform float uNoiseStrength;\n uniform float uSoftness;\n uniform float uZoom;\n float random(vec2 st) {\n return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);\n }\n void main() {\n vec2 uv = (gl_FragCoord.xy - 0.5 * uResolution.xy) / min(uResolution.y, uResolution.x);\n float t = uTime * 0.2;\n float scale = mix(1.8, 0.45, uSoftness) / max(0.25, uZoom);\n vec2 p = uv * scale;\n for(float i = 1.0; i <= 4.0; i++){\n p.x += 0.6 / i * sin(i * 3.0 * p.y + t);\n p.y += 0.6 / i * cos(i * 3.0 * p.x + t);\n }\n float w1 = 0.5 + 0.5 * sin(p.x + t);\n float w2 = 0.5 + 0.5 * sin(p.y + t * 0.8);\n float w3 = 0.5 + 0.5 * sin(p.x + p.y);\n vec3 col = uColors[0];\n col = mix(col, uColors[1], smoothstep(0.1, 0.9, w1));\n col = mix(col, uColors[2], smoothstep(0.1, 0.9, w2));\n col = mix(col, uColors[3], smoothstep(0.1, 0.9, w3));\n float w4 = w1 * w2 * w3;\n col = mix(col, uColors[4], w4);\n float grain = random(gl_FragCoord.xy + uTime);\n col += (grain - 0.5) * uNoiseStrength;\n gl_FragColor = vec4(col, 1.0);\n }\n"}}export{o as VS_SOURCE,getLuminaFragmentShader};
@@ -0,0 +1 @@
1
+ const t=60,e=["plasma","mesh-flow","fluid","radiant","ethereal"];function isLuminaType(t){return e.includes(t)}function toLuminaSpeed(t){return Math.max(.1,t/3e3)}function toSpeedRate(t){return Math.max(.1,t/3e3)}function toAnimationDurationSec(t,e=3,n=.75){const a=3e3*e/Math.max(500,t);return Math.max(n,a)}function toLuminaSoftness(t){return Math.min(1,t/200)}function clampZoom(t){return Math.min(4,Math.max(.25,t))}function hexToRgb(t){const e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?[parseInt(e[1],16)/255,parseInt(e[2],16)/255,parseInt(e[3],16)/255]:[0,0,0]}function padColors(t,e=5){return 0===t.length?["#7000FF","#FF00AA","#3300FF","#FFCC00","#00FFFF"]:Array.from({length:e},(e,n)=>t[n%t.length])}const n=["#0d0221","#5b21b6","#db2777","#38bdf8","#e9d5ff"],a="data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='1'/%3E%3C/svg%3E";export{n as FLUID_DEFAULT_COLORS,t as LUMINA_ANIMATION_DURATION_SEC,e as LUMINA_ANIMATION_TYPES,a as LUMINA_NOISE_SVG,clampZoom,hexToRgb,isLuminaType,padColors,toAnimationDurationSec,toLuminaSoftness,toLuminaSpeed,toSpeedRate};
@@ -0,0 +1 @@
1
+ const f=["#ffffff","#f0f9ff","#e0f2fe"],e=["#ffb7c5","#ff91a4","#f8c8dc","#ffc0cb","#fda4af"],c=["#f44336","#e91e63","#9c27b0","#673ab7","#3f51b5","#2196f3","#03a9f4","#00bcd4","#4caf50","#ffeb3b","#ffc107","#ff9800"];function getFallingParticleDefaults(a){switch(a){case"snow":default:return f;case"flowers":return e;case"confetti":return c}}export{c as CONFETTI_DEFAULT_COLORS,e as FLOWERS_DEFAULT_COLORS,f as SNOW_DEFAULT_COLORS,getFallingParticleDefaults};
@@ -0,0 +1 @@
1
+ import{toSpeedRate as a}from"./lumina-utils.js";function createFallingParticle(a,e,t,o=!1){return{x:Math.random()*a,y:o?Math.random()*e:-20,size:Math.random()*(t.maxSize-t.minSize)+t.minSize,speedX:(Math.random()-.5)*t.wind,speedY:Math.random()*(t.maxSpeedY-t.minSpeedY)+t.minSpeedY,opacity:.5*Math.random()+.3,rotation:Math.random()*Math.PI*2,rotationSpeed:.05*(Math.random()-.5),color:t.colors[Math.floor(Math.random()*t.colors.length)]}}const drawFallingParticles=(e,t,o,r,n,l)=>{const i=a(l.speed),c=Math.max(1,.5*l.size),s={minSize:c,maxSize:Math.max(c+.5,1.5*l.size),minSpeedY:.4*i,maxSpeedY:1.2*i,wind:l.wind*i,colors:l.colors},h=`${l.count}:${l.size}:${l.speed}:${l.wind}`;r.current.length===l.count&&r.spawnKey===h||(r.current=Array.from({length:l.count},()=>createFallingParticle(t,o,s,!0)),r.spawnKey=h),r.current.forEach(a=>{a.y+=a.speedY,a.x+=a.speedX+.5*Math.sin(a.y/50)*i,a.rotation+=a.rotationSpeed,a.y>o+20&&Object.assign(a,createFallingParticle(t,o,s)),a.x>t+20&&(a.x=-20),a.x<-20&&(a.x=t+20),e.save(),e.translate(a.x,a.y),e.rotate(a.rotation),e.fillStyle=a.color,e.globalAlpha=a.opacity*l.layerOpacity,function drawFallingParticleShape(a,e,t){return"snow"===e?(a.beginPath(),a.arc(0,0,t,0,2*Math.PI),void a.fill()):"flowers"===e?(a.beginPath(),a.moveTo(0,0),a.bezierCurveTo(t,-t,2*t,t,0,2*t),a.bezierCurveTo(2*-t,t,-t,-t,0,0),void a.fill()):void a.fillRect(-t/2,-t/2,t,t)}(e,n,a.size),e.restore()}),e.globalAlpha=1},drawParticles=(e,t,o,r,n)=>{const l=`${n.count}:${n.size}`;r.current.length===n.count&&r.spawnKey===l||(r.current=Array.from({length:n.count}).map(()=>({x:Math.random()*t,y:Math.random()*o,vx:1.5*(Math.random()-.5),vy:1.5*(Math.random()-.5),size:Math.random()*n.size+1,color:n.colors[Math.floor(Math.random()*n.colors.length)]})),r.spawnKey=l);const i=r.current,c=a(n.speed);i.forEach((a,r)=>{if(a.x+=a.vx*c,a.y+=a.vy*c,(a.x<0||a.x>t)&&(a.vx*=-1),(a.y<0||a.y>o)&&(a.vy*=-1),n.clickable){const e=n.mouse.x-a.x,t=n.mouse.y-a.y,o=Math.sqrt(e*e+t*t);if(o<150){const r=(150-o)/150;a.vx+=e/o*r*.5,a.vy+=t/o*r*.5}const r=3,l=Math.sqrt(a.vx*a.vx+a.vy*a.vy);l>r&&(a.vx=a.vx/l*r,a.vy=a.vy/l*r)}e.save(),e.globalAlpha=n.layerOpacity,e.beginPath(),e.arc(a.x,a.y,a.size,0,2*Math.PI),e.fillStyle=a.color,e.fill(),e.restore();for(let t=r+1;t<i.length;t++){const o=i[t],r=a.x-o.x,l=a.y-o.y,c=Math.sqrt(r*r+l*l);c<100&&(e.beginPath(),e.strokeStyle=a.color,e.globalAlpha=(1-c/100)*n.layerOpacity,e.lineWidth=.5,e.moveTo(a.x,a.y),e.lineTo(o.x,o.y),e.stroke(),e.globalAlpha=1)}})},drawStars=(a,e,t,o,r)=>{const n=`${r.count}:${r.size}`;o.current.length===r.count&&o.spawnKey===n||(o.current=Array.from({length:r.count}).map(()=>({x:Math.random()*e,y:Math.random()*t,size:Math.random()*r.size,blinkSpeed:.05*Math.random()+.01,color:r.colors[Math.floor(Math.random()*r.colors.length)]})),o.spawnKey=n),o.current.forEach(e=>{e.y-=.05*r.speedRate,e.y<0&&(e.y=t);const o=(.5+.5*Math.sin(r.time*e.blinkSpeed))*r.layerOpacity;a.beginPath(),a.arc(e.x,e.y,e.size,0,2*Math.PI),a.fillStyle=e.color,a.globalAlpha=o,a.fill(),a.globalAlpha=1})};export{drawFallingParticles,drawParticles,drawStars};
@@ -0,0 +1 @@
1
+ import{padColors as t,hexToRgb as e,toLuminaSpeed as r,toLuminaSoftness as i,clampZoom as a}from"./lumina-utils.js";import{VS_SOURCE as n,getLuminaFragmentShader as o}from"./lumina-shaders.js";function loadShader(t,e,r){const i=t.createShader(e);return i?(t.shaderSource(i,r),t.compileShader(i),t.getShaderParameter(i,t.COMPILE_STATUS)?i:(t.deleteShader(i),null)):null}class ShaderAnimationController{constructor(n,o){this.raf=0,this.startTime=performance.now(),this.render=()=>{const n=this.gl,o=this.program,s=this.positionBuffer;if(!n||!o||!s)return;const{colors:h,speed:f,blur:c,noise:m,zoom:d,variant:u}=this.options,{width:l,height:g}=this.resizeCanvas();if(0===l||0===g)return void(this.raf=requestAnimationFrame(this.render));n.viewport(0,0,l,g),n.useProgram(o);const v=n.getAttribLocation(o,"aVertexPosition"),S=n.getUniformLocation(o,"uResolution"),p=n.getUniformLocation(o,"uTime"),A=n.getUniformLocation(o,"uColors"),w=n.getUniformLocation(o,"uSpeed"),R=n.getUniformLocation(o,"uSoftness"),b=n.getUniformLocation(o,"uNoiseStrength"),T=n.getUniformLocation(o,"uZoom");n.enableVertexAttribArray(v),n.bindBuffer(n.ARRAY_BUFFER,s),n.vertexAttribPointer(v,2,n.FLOAT,!1,0,0),n.uniform2f(S,l,g);const x=t(h),F=r(f),B=i(c),L=.6*F,P=a(d),U=(performance.now()-this.startTime)/1e3;"mesh-flow"===u?(p&&n.uniform1f(p,U),w&&n.uniform1f(w,L),R&&n.uniform1f(R,B),T&&n.uniform1f(T,P)):(p&&n.uniform1f(p,U*F),R&&n.uniform1f(R,B),b&&n.uniform1f(b,m),T&&n.uniform1f(T,P));const C=new Float32Array(15);for(let t=0;t<5;t++){const r=e(x[t]);C[3*t]=r[0],C[3*t+1]=r[1],C[3*t+2]=r[2]}A&&n.uniform3fv(A,C),n.drawArrays(n.TRIANGLE_STRIP,0,4),this.raf=requestAnimationFrame(this.render)},this.container=n,this.options=o,this.canvas=document.createElement("canvas"),this.canvas.className="designbase-wc-animation-background__shader-canvas",n.appendChild(this.canvas),this.init()}updateOptions(t){this.options={...this.options,...t}}resizeCanvas(){const t=this.container.getBoundingClientRect(),e=window.devicePixelRatio||1;return this.canvas.width=Math.max(1,t.width*e),this.canvas.height=Math.max(1,t.height*e),this.canvas.style.width=`${t.width}px`,this.canvas.style.height=`${t.height}px`,{width:this.canvas.width,height:this.canvas.height}}init(){const t=this.canvas.getContext("webgl");if(!t)return;this.gl=t;const{variant:e}=this.options,r=o(e),i=t.createProgram();if(!i)return;const a=loadShader(t,t.VERTEX_SHADER,n),s=loadShader(t,t.FRAGMENT_SHADER,r);if(!a||!s)return;if(t.attachShader(i,a),t.attachShader(i,s),t.linkProgram(i),!t.getProgramParameter(i,t.LINK_STATUS))return;this.program=i,this.vertexShader=a,this.fragmentShader=s;const h=t.createBuffer();h&&(this.positionBuffer=h,t.bindBuffer(t.ARRAY_BUFFER,h),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),t.STATIC_DRAW),this.observer=new ResizeObserver(()=>this.resizeCanvas()),this.observer.observe(this.container),this.startTime=performance.now(),this.render())}destroy(){cancelAnimationFrame(this.raf),this.observer?.disconnect();const t=this.gl;t&&this.program&&(this.vertexShader&&t.deleteShader(this.vertexShader),this.fragmentShader&&t.deleteShader(this.fragmentShader),this.positionBuffer&&t.deleteBuffer(this.positionBuffer),t.deleteProgram(this.program)),this.canvas.remove()}}export{ShaderAnimationController};
@@ -0,0 +1 @@
1
+ const clamp=(t,r,a)=>Math.max(r,Math.min(a,t)),normalizeHex=t=>{const r=(t||"").trim().toUpperCase();return r?r.startsWith("#")?r:`#${r}`:""},isHex=t=>/^#?[0-9A-Fa-f]{6}$/.test(t||""),hexToRgb=t=>{const r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t.trim());return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:null},toHex=(t,r,a)=>{const h=t=>clamp(Math.round(t),0,255).toString(16).padStart(2,"0");return`#${h(t)}${h(r)}${h(a)}`.toUpperCase()},rgbToHsv=(t,r,a)=>{t/=255,r/=255,a/=255;const e=Math.max(t,r,a),s=e-Math.min(t,r,a);let n=0;if(0!==s){switch(e){case t:n=(r-a)/s+(r<a?6:0);break;case r:n=(a-t)/s+2;break;case a:n=(t-r)/s+4}n*=60}return{h:n,s:100*(0===e?0:s/e),v:100*e}},hsvToRgb=(t,r,a)=>{const e=(a/=100)*(r/=100),s=e*(1-Math.abs(t/60%2-1)),n=a-e;let o=0,c=0,u=0;return t>=0&&t<60?(o=e,c=s,u=0):t<120?(o=s,c=e,u=0):t<180?(o=0,c=e,u=s):t<240?(o=0,c=s,u=e):t<300?(o=s,c=0,u=e):(o=e,c=0,u=s),{r:Math.round(255*(o+n)),g:Math.round(255*(c+n)),b:Math.round(255*(u+n))}},rgbToHsl=(t,r,a)=>{t/=255,r/=255,a/=255;const e=Math.max(t,r,a),s=Math.min(t,r,a);let n=0,o=0;const c=(e+s)/2;if(e!==s){const u=e-s;switch(o=c>.5?u/(2-e-s):u/(e+s),e){case t:n=(r-a)/u+(r<a?6:0);break;case r:n=(a-t)/u+2;break;case a:n=(t-r)/u+4}n*=60}return{h:n,s:100*o,l:100*c}},formatColor=(t,r,a,e,s)=>{const n=s/100;switch(t){case"hex":default:return a;case"rgb":return`rgb(${r.r}, ${r.g}, ${r.b})`;case"rgba":return`rgba(${r.r}, ${r.g}, ${r.b}, ${n.toFixed(2)})`;case"hsl":return`hsl(${Math.round(e.h)}, ${Math.round(e.s)}%, ${Math.round(e.l)}%)`;case"hsla":return`hsla(${Math.round(e.h)}, ${Math.round(e.s)}%, ${Math.round(e.l)}%, ${n.toFixed(2)})`}};export{clamp,formatColor,hexToRgb,hsvToRgb,isHex,normalizeHex,rgbToHsl,rgbToHsv,toHex};
@@ -0,0 +1 @@
1
+ const startOfDay=t=>{const e=new Date(t);return e.setHours(0,0,0,0),e},endOfDay=t=>{const e=new Date(t);return e.setHours(23,59,59,999),e},addDays=(t,e)=>{const n=new Date(t);return n.setDate(n.getDate()+e),startOfDay(n)},getMonthEnd=t=>endOfDay(new Date(t.getFullYear(),t.getMonth()+1,0)),getYearEnd=t=>endOfDay(new Date(t.getFullYear(),11,31)),clampRange=(t,e,n)=>{let{start:a,end:r}=t;return e&&a<e&&(a=startOfDay(e)),n&&r>n&&(r=endOfDay(n)),a>r?{start:r,end:a}:{start:a,end:r}},t=[{id:"today",label:"오늘",getRange:({today:t})=>clampRange({start:startOfDay(t),end:endOfDay(t)})},{id:"yesterday",label:"어제",getRange:({today:t})=>{const e=addDays(t,-1);return clampRange({start:e,end:endOfDay(e)})}},{id:"this-week",label:"이번 주",getRange:({today:t,startOfWeek:e,minDate:n,maxDate:a})=>{const r=((t,e)=>{const n=t.getDay();return addDays(t,-("monday"===e?(n+6)%7:n))})(t,e);return clampRange({start:r,end:(o=r,endOfDay(addDays(o,6)))},n,a);var o}},{id:"this-month",label:"이번 달",getRange:({today:t,minDate:e,maxDate:n})=>{return clampRange({start:(a=t,startOfDay(new Date(a.getFullYear(),a.getMonth(),1))),end:getMonthEnd(t)},e,n);var a}},{id:"this-year",label:"올해",getRange:({today:t,minDate:e,maxDate:n})=>{return clampRange({start:(a=t,startOfDay(new Date(a.getFullYear(),0,1))),end:getYearEnd(t)},e,n);var a}},{id:"custom",label:"사용자 지정",getRange:()=>null}],addMonths=(t,e)=>{const n=new Date(t);return n.setDate(1),n.setMonth(n.getMonth()+e),n},toISODate=t=>`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")}`,parseISODate=t=>{if(!t)return null;const e=t.trim().match(/^(\d{4})-(\d{2})-(\d{2})$/);if(!e)return null;const n=new Date(Number(e[1]),Number(e[2])-1,Number(e[3]));return Number.isNaN(n.getTime())?null:startOfDay(n)},formatDisplayDate=(t,e="ko-KR")=>t.toLocaleDateString(e),generateWeekdays=t=>{const e=["일","월","화","수","목","금","토"];return"monday"===t&&e.push(e.shift()),e},generateCalendarGrid=(t,e,n=!1)=>{const a=t.getFullYear(),r=t.getMonth(),o=new Date(a,r,1),s="monday"===e?(o.getDay()+6)%7:o.getDay();if(n){const t=[];for(let e=0;e<s;e+=1)t.push(null);const e=new Date(a,r+1,0).getDate();for(let n=1;n<=e;n+=1)t.push(new Date(a,r,n));return t}const u=new Date(o);return u.setDate(u.getDate()-s),Array.from({length:42},(t,e)=>{const n=new Date(u);return n.setDate(u.getDate()+e),n})},detectActivePresetId=(t,e,n)=>{if(!t)return"custom";const a=t.start.toDateString(),r=t.end.toDateString();for(const t of e){if("custom"===t.id)continue;const e=t.getRange(n);if(e&&(e.start.toDateString()===a&&e.end.toDateString()===r))return t.id}return"custom"},formatPanelInputDate=(t,e)=>t?t.toLocaleDateString(e,{year:"numeric",month:"short",day:"numeric"}):"";export{t as DEFAULT_DATE_PICKER_PRESETS,addMonths,detectActivePresetId,endOfDay,formatDisplayDate,formatPanelInputDate,generateCalendarGrid,generateWeekdays,parseISODate,startOfDay,toISODate};
@@ -0,0 +1,40 @@
1
+ interface AccordionItemConfig {
2
+ id?: string;
3
+ title: string;
4
+ disabled?: boolean;
5
+ itemType?: 'icon' | 'number' | 'question' | 'none';
6
+ icon?: string;
7
+ }
8
+ declare class DbAccordion extends HTMLElement {
9
+ static get observedAttributes(): string[];
10
+ private expanded;
11
+ private isRendering;
12
+ private suppressExpandedAttrCallback;
13
+ private childObserver?;
14
+ get items(): AccordionItemConfig[];
15
+ set items(value: AccordionItemConfig[] | string);
16
+ get allowMultiple(): boolean;
17
+ set allowMultiple(value: boolean);
18
+ get expandedItems(): string[] | string;
19
+ set expandedItems(value: string[] | string);
20
+ connectedCallback(): void;
21
+ disconnectedCallback(): void;
22
+ attributeChangedCallback(name: string): void;
23
+ /** id와 index 문자열 충돌 방지 — 항목당 단일 키만 사용 */
24
+ private resolveItemKey;
25
+ private getExpandMode;
26
+ private syncExpandedFromAttributes;
27
+ private iconSize;
28
+ private collectPanelContent;
29
+ private isItemExpanded;
30
+ private syncExpandedState;
31
+ private render;
32
+ private toggle;
33
+ }
34
+ declare global {
35
+ interface HTMLElementTagNameMap {
36
+ 'db-accordion': DbAccordion;
37
+ }
38
+ }
39
+
40
+ export { DbAccordion };
@@ -0,0 +1 @@
1
+ import{createDbIcon as e}from"./db-icons.js";class DbAccordion extends HTMLElement{constructor(){super(...arguments),this.expanded=new Set,this.isRendering=!1,this.suppressExpandedAttrCallback=!1}static get observedAttributes(){return["items","variant","size","allow-multiple","expand-mode","expanded-items","default-item-type"]}get items(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get allowMultiple(){return this.hasAttribute("allow-multiple")}set allowMultiple(e){this.toggleAttribute("allow-multiple",e)}get expandedItems(){const e=(this.getAttribute("expanded-items")||"").trim();if(!e)return[];if("all"===e)return this.items.map((e,t)=>this.resolveItemKey(e,t));try{const t=JSON.parse(e);if(Array.isArray(t))return t.map(e=>String(e).trim()).filter(Boolean)}catch{}return e.split(",").map(e=>e.trim()).filter(Boolean)}set expandedItems(e){Array.isArray(e)?this.setAttribute("expanded-items",e.join(",")):this.setAttribute("expanded-items",e)}connectedCallback(){this.syncExpandedFromAttributes(),this.render(),this.childObserver=new MutationObserver(e=>{if(this.isRendering)return;e.some(e=>Array.from(e.addedNodes).some(e=>e instanceof HTMLElement&&e.hasAttribute("slot")))&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.childObserver?.disconnect()}attributeChangedCallback(e){if(this.isConnected){if("expanded-items"===e){if(this.suppressExpandedAttrCallback)return;return this.syncExpandedFromAttributes(),void this.syncExpandedState()}return"expand-mode"===e||"allow-multiple"===e?(this.syncExpandedFromAttributes(),void this.syncExpandedState()):"items"===e?(this.syncExpandedFromAttributes(),void this.render()):void this.render()}}resolveItemKey(e,t){return e.id??String(t)}getExpandMode(){const e=this.getAttribute("expand-mode");return"single"===e||"multiple"===e||"all"===e?e:(this.hasAttribute("allow-multiple"),"multiple")}syncExpandedFromAttributes(){const e=this.items.map((e,t)=>this.resolveItemKey(e,t)),t=this.expandedItems,s=this.getExpandMode();t.length>0?this.expanded=new Set(t.filter(t=>e.includes(t))):this.expanded="all"!==s?new Set:new Set(e)}iconSize(e){return"s"===e?16:"l"===e?24:20}collectPanelContent(){const e=new Map,register=(t,s)=>{if(!(t instanceof HTMLElement)||"SLOT"===t.tagName)return;e.has(s)||e.set(s,[]);const i=e.get(s);i.includes(t)||i.push(t)};return Array.from(this.children).forEach(e=>{const t=e.getAttribute("slot")?.match(/^content-(\d+)$/);t&&register(e,Number(t[1]))}),this.querySelectorAll(":scope > .designbase-wc-accordion__item").forEach((e,t)=>{const s=e.querySelector(":scope > .designbase-wc-accordion__content > .designbase-wc-accordion__content-inner");s&&Array.from(s.children).forEach(e=>register(e,t))}),e}isItemExpanded(e,t){return this.expanded.has(this.resolveItemKey(e,t))}syncExpandedState(){const e=this.items;this.querySelectorAll(":scope > .designbase-wc-accordion__item").forEach((t,s)=>{const i=e[s];if(!i)return;const n=this.isItemExpanded(i,s);t.classList.toggle("designbase-wc-accordion__item--expanded",n),t.classList.toggle("designbase-wc-accordion__item--disabled",Boolean(i.disabled));const a=t.querySelector(".designbase-wc-accordion__trigger"),d=t.querySelector(".designbase-wc-accordion__content");a?.setAttribute("aria-expanded",String(n)),d?.setAttribute("aria-hidden",String(!n))})}render(){this.isRendering=!0;const t=this.collectPanelContent(),s=this.getAttribute("variant")||"default",i=this.getAttribute("size")||"m",n=this.getExpandMode(),a=this.getAttribute("default-item-type")||"none",d=this.items,r=this.iconSize(i);this.className=["designbase-wc-accordion",`designbase-wc-accordion--${s}`,`designbase-wc-accordion--${i}`,"multiple"===n&&"designbase-wc-accordion--multiple","single"===n&&"designbase-wc-accordion--single","all"===n&&"designbase-wc-accordion--all"].filter(Boolean).join(" "),this.setAttribute("role","region"),this.setAttribute("aria-label","아코디언"),this.querySelectorAll(":scope > .designbase-wc-accordion__item").forEach(e=>e.remove()),d.forEach((i,n)=>{const d=this.resolveItemKey(i,n),c=this.isItemExpanded(i,n),o=document.createElement("div");o.className=["designbase-wc-accordion__item",`designbase-wc-accordion__item--${s}`,c&&"designbase-wc-accordion__item--expanded",i.disabled&&"designbase-wc-accordion__item--disabled"].filter(Boolean).join(" "),o.dataset.itemKey=d;const l=document.createElement("button");l.type="button",l.className="designbase-wc-accordion__trigger",l.disabled=Boolean(i.disabled),l.setAttribute("aria-expanded",String(c)),l.setAttribute("aria-controls",`accordion-content-${d}`),l.addEventListener("click",()=>{i.disabled||this.toggle(d)});const m=i.itemType||a;if("number"===m){const e=document.createElement("div");e.className="designbase-wc-accordion__number",e.textContent=`${n+1}.`,l.append(e)}else if("question"===m){const e=document.createElement("div");e.className="designbase-wc-accordion__question",e.textContent="Q.",l.append(e)}else if("icon"===m&&i.icon){const t=document.createElement("div");t.className="designbase-wc-accordion__icon",t.append(e(i.icon,r)),l.append(t)}const p=document.createElement("span");p.className="designbase-wc-accordion__title",p.textContent=i.title;const h=document.createElement("div");h.className="designbase-wc-accordion__chevron",h.append(e("chevron-down",r)),l.append(p,h);const u=document.createElement("div");u.id=`accordion-content-${d}`,u.className="designbase-wc-accordion__content",u.setAttribute("aria-hidden",String(!c));const b=document.createElement("div");b.className="designbase-wc-accordion__content-inner",(t.get(n)||[]).forEach(e=>{e.removeAttribute("slot"),b.append(e)}),u.append(b),o.append(l,u),this.append(o)}),this.isRendering=!1}toggle(e){const t=this.getExpandMode();this.expanded.has(e)?this.expanded.delete(e):"single"===t?this.expanded=new Set([e]):this.expanded.add(e);const s=Array.from(this.expanded);this.syncExpandedState(),this.suppressExpandedAttrCallback=!0,this.expandedItems=s,this.suppressExpandedAttrCallback=!1,this.dispatchEvent(new CustomEvent("db-change",{detail:{expandedItems:s},bubbles:!0,composed:!0}))}}customElements.get("db-accordion")||customElements.define("db-accordion",DbAccordion);export{DbAccordion};