@designbasekorea/ui-wc 0.8.1 → 0.8.3

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 (162) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +18 -1
  3. package/dist/esm/components/animation-background/controls.js +1 -1
  4. package/dist/esm/components/animation-background/layers.js +1 -1
  5. package/dist/esm/components/db-accordion.d.ts +1 -1
  6. package/dist/esm/components/db-activity-heatmap.d.ts +38 -0
  7. package/dist/esm/components/db-activity-heatmap.js +1 -0
  8. package/dist/esm/components/db-animation-background.d.ts +2 -0
  9. package/dist/esm/components/db-animation-background.js +1 -1
  10. package/dist/esm/components/db-app-badge.d.ts +2 -0
  11. package/dist/esm/components/db-app-badge.js +1 -1
  12. package/dist/esm/components/db-audio-player.d.ts +4 -0
  13. package/dist/esm/components/db-audio-player.js +1 -1
  14. package/dist/esm/components/db-avatar.js +1 -1
  15. package/dist/esm/components/db-backdrop.d.ts +4 -0
  16. package/dist/esm/components/db-backdrop.js +1 -1
  17. package/dist/esm/components/db-badge.d.ts +2 -2
  18. package/dist/esm/components/db-badge.js +1 -1
  19. package/dist/esm/components/db-bottom-navigation.js +1 -1
  20. package/dist/esm/components/db-bottom-sheet.d.ts +5 -0
  21. package/dist/esm/components/db-bottom-sheet.js +1 -1
  22. package/dist/esm/components/db-breadcrumbs.d.ts +1 -1
  23. package/dist/esm/components/db-button.d.ts +13 -0
  24. package/dist/esm/components/db-button.js +1 -1
  25. package/dist/esm/components/db-calendar.js +1 -1
  26. package/dist/esm/components/db-card.js +1 -1
  27. package/dist/esm/components/db-carousel.js +1 -1
  28. package/dist/esm/components/db-chat-composer.d.ts +14 -0
  29. package/dist/esm/components/db-chat-composer.js +1 -1
  30. package/dist/esm/components/db-chat-message.d.ts +15 -2
  31. package/dist/esm/components/db-chat-message.js +1 -1
  32. package/dist/esm/components/db-chat-orb.d.ts +6 -8
  33. package/dist/esm/components/db-chat-orb.js +1 -1
  34. package/dist/esm/components/db-chat-room.d.ts +12 -1
  35. package/dist/esm/components/db-chat-room.js +1 -1
  36. package/dist/esm/components/db-chat-welcome.js +1 -1
  37. package/dist/esm/components/db-chat-widget.d.ts +43 -10
  38. package/dist/esm/components/db-chat-widget.js +1 -1
  39. package/dist/esm/components/db-checkbox.d.ts +11 -0
  40. package/dist/esm/components/db-checkbox.js +1 -1
  41. package/dist/esm/components/db-chip.js +1 -1
  42. package/dist/esm/components/db-color-picker.js +1 -1
  43. package/dist/esm/components/db-confirm.d.ts +5 -0
  44. package/dist/esm/components/db-confirm.js +1 -1
  45. package/dist/esm/components/db-container.js +1 -1
  46. package/dist/esm/components/db-cookie-banner.js +1 -1
  47. package/dist/esm/components/db-date-picker.d.ts +4 -1
  48. package/dist/esm/components/db-date-picker.js +1 -1
  49. package/dist/esm/components/db-divider.js +1 -1
  50. package/dist/esm/components/db-download-progress.d.ts +3 -4
  51. package/dist/esm/components/db-download-progress.js +1 -1
  52. package/dist/esm/components/db-drawer.d.ts +5 -1
  53. package/dist/esm/components/db-drawer.js +1 -1
  54. package/dist/esm/components/db-dropdown.js +1 -1
  55. package/dist/esm/components/db-dropzone.js +1 -1
  56. package/dist/esm/components/db-email-verify.d.ts +2 -2
  57. package/dist/esm/components/db-email-verify.js +1 -1
  58. package/dist/esm/components/db-file-uploader.js +1 -1
  59. package/dist/esm/components/db-floating-action-button.d.ts +1 -0
  60. package/dist/esm/components/db-floating-action-button.js +1 -1
  61. package/dist/esm/components/db-footer.js +1 -1
  62. package/dist/esm/components/db-gantt.js +1 -1
  63. package/dist/esm/components/db-indicator.js +1 -1
  64. package/dist/esm/components/db-input.d.ts +7 -0
  65. package/dist/esm/components/db-input.js +1 -1
  66. package/dist/esm/components/db-kanban.js +1 -1
  67. package/dist/esm/components/db-lightbox.d.ts +4 -0
  68. package/dist/esm/components/db-lightbox.js +1 -1
  69. package/dist/esm/components/db-list.js +1 -1
  70. package/dist/esm/components/db-masonry.js +1 -1
  71. package/dist/esm/components/db-menu-item.js +1 -1
  72. package/dist/esm/components/db-modal.d.ts +10 -0
  73. package/dist/esm/components/db-modal.js +1 -1
  74. package/dist/esm/components/db-navbar.d.ts +4 -2
  75. package/dist/esm/components/db-navbar.js +1 -1
  76. package/dist/esm/components/db-onboarding-modal.d.ts +3 -0
  77. package/dist/esm/components/db-onboarding-modal.js +1 -1
  78. package/dist/esm/components/db-otp-input.d.ts +3 -2
  79. package/dist/esm/components/db-otp-input.js +1 -1
  80. package/dist/esm/components/db-page-header.js +1 -1
  81. package/dist/esm/components/db-phone-verify.d.ts +2 -2
  82. package/dist/esm/components/db-phone-verify.js +1 -1
  83. package/dist/esm/components/db-popover.js +1 -1
  84. package/dist/esm/components/db-progress-step.js +1 -1
  85. package/dist/esm/components/db-progress.js +1 -1
  86. package/dist/esm/components/db-progressbar.js +1 -1
  87. package/dist/esm/components/db-radio.d.ts +1 -0
  88. package/dist/esm/components/db-radio.js +1 -1
  89. package/dist/esm/components/db-range-slider.d.ts +9 -4
  90. package/dist/esm/components/db-range-slider.js +1 -1
  91. package/dist/esm/components/db-rating.js +1 -1
  92. package/dist/esm/components/db-resizable-panels.d.ts +14 -0
  93. package/dist/esm/components/db-resizable-panels.js +1 -1
  94. package/dist/esm/components/db-search-bar.js +1 -1
  95. package/dist/esm/components/db-section-cta.js +1 -1
  96. package/dist/esm/components/db-section-feature.js +1 -1
  97. package/dist/esm/components/db-section-pricing.js +1 -1
  98. package/dist/esm/components/db-section.js +1 -1
  99. package/dist/esm/components/db-segment-control.js +1 -1
  100. package/dist/esm/components/db-select.d.ts +8 -0
  101. package/dist/esm/components/db-select.js +1 -1
  102. package/dist/esm/components/db-sidebar.d.ts +41 -6
  103. package/dist/esm/components/db-sidebar.js +1 -1
  104. package/dist/esm/components/db-skeleton.js +1 -1
  105. package/dist/esm/components/db-spinner.d.ts +4 -0
  106. package/dist/esm/components/db-spinner.js +1 -1
  107. package/dist/esm/components/db-split-view.js +1 -1
  108. package/dist/esm/components/db-stat.js +1 -1
  109. package/dist/esm/components/db-stepper.js +1 -1
  110. package/dist/esm/components/db-table.js +1 -1
  111. package/dist/esm/components/db-tabs.d.ts +1 -1
  112. package/dist/esm/components/db-tabs.js +1 -1
  113. package/dist/esm/components/db-testimonial.js +1 -1
  114. package/dist/esm/components/db-textarea.js +1 -1
  115. package/dist/esm/components/db-time-picker.d.ts +5 -2
  116. package/dist/esm/components/db-time-picker.js +1 -1
  117. package/dist/esm/components/db-timeline.js +1 -1
  118. package/dist/esm/components/db-toast.d.ts +8 -1
  119. package/dist/esm/components/db-toast.js +1 -1
  120. package/dist/esm/components/db-toggle.d.ts +2 -0
  121. package/dist/esm/components/db-toggle.js +1 -1
  122. package/dist/esm/components/db-tooltip.js +1 -1
  123. package/dist/esm/components/db-top-banner.js +1 -1
  124. package/dist/esm/components/db-tutorial.d.ts +1 -0
  125. package/dist/esm/components/db-tutorial.js +1 -1
  126. package/dist/esm/components/db-two-factor.d.ts +2 -2
  127. package/dist/esm/components/db-two-factor.js +1 -1
  128. package/dist/esm/components/db-video-player.d.ts +3 -0
  129. package/dist/esm/components/db-video-player.js +1 -1
  130. package/dist/esm/components/section-block-header-utils.js +1 -1
  131. package/dist/esm/core/a11y.d.ts +40 -0
  132. package/dist/esm/core/a11y.js +1 -0
  133. package/dist/esm/core/base-element.d.ts +41 -0
  134. package/dist/esm/core/base-element.js +1 -0
  135. package/dist/esm/core/dom.d.ts +35 -0
  136. package/dist/esm/core/dom.js +1 -0
  137. package/dist/esm/core/focus-trap.d.ts +41 -0
  138. package/dist/esm/core/focus-trap.js +1 -0
  139. package/dist/esm/core/i18n.d.ts +82 -0
  140. package/dist/esm/core/i18n.js +1 -0
  141. package/dist/esm/core/scroll-lock.d.ts +19 -0
  142. package/dist/esm/core/scroll-lock.js +1 -0
  143. package/dist/esm/core/uid.d.ts +23 -0
  144. package/dist/esm/core/uid.js +1 -0
  145. package/dist/esm/helpers/toast.d.ts +10 -10
  146. package/dist/esm/helpers/toast.js +1 -1
  147. package/dist/esm/index.d.ts +12 -4
  148. package/dist/esm/index.js +1 -1
  149. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -0
  150. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/primitives.js +1 -0
  151. package/dist/index.cjs +1 -1
  152. package/dist/index.css +1 -1
  153. package/dist/index.d.ts +587 -82
  154. package/dist/index.esm.js +1 -1
  155. package/dist/react/index.cjs +1 -1
  156. package/dist/react/index.d.ts +470 -122
  157. package/dist/react/index.esm.js +1 -1
  158. package/package.json +37 -10
  159. package/dist/chunks/lottie-26a5e98f.js +0 -1
  160. package/dist/esm/components/db-lottie.d.ts +0 -20
  161. package/dist/esm/components/db-lottie.js +0 -1
  162. package/dist/react/chunks/lottie-14e7addb.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # 변경 이력
2
2
 
3
+ ## 0.8.2 - 2026-07-21
4
+
5
+ ### 추가
6
+
7
+ - Activity Heatmap 컴포넌트 (`db-activity-heatmap` / React `ActivityHeatmap`): GitHub 기여 그래프형 활동 히트맵, 월·요일 라벨, 범례, `db-cell-click`
8
+ - Sidebar Secondary Panel API: `panels`, 메뉴 `openPanel`, `activePanel`, `panelMode`(auto · adjacent · replace), `panelWidth`, `panelBreakpoint`
9
+ - Sidebar 패널 이벤트 `db-panel-change`, `db-panel-mode-change`
10
+ - React `Sidebar`에 `panels`·`panelMode`·`panelWidth` 등 Secondary Panel 프롭 및 타입 추가
11
+
12
+ ### 개선
13
+
14
+ - Activity Heatmap: 주 열이 2칸 미만인 달 라벨 숨김(차트 앞단 잘림 시 월 라벨 겹침 방지)
15
+ - Sidebar 접힌 폭을 48px로 조정(default), wrapper는 패딩 포함 64px
16
+ - Sidebar 선택 메뉴 스타일: 배경 `layer-1`, 파란색 강조 제거
17
+ - Secondary Panel adjacent 레이아웃: `panelWidth` 전역 기준 통일, flex 축소·폭 점프 방지
18
+ - `settings-sections`는 deprecated — `panels`로 자동 변환
19
+ - design-examples Sidebar 가이드·기본 사용 예시를 `sections` + `panels` 구조로 최신화
20
+ - 문서 코드 블록 긴 예시 세로 스크롤(`overflow="scroll-both"`)
21
+
3
22
  ## 0.8.1 - 2026-07-19
4
23
 
5
24
  ### 추가
package/README.md CHANGED
@@ -4,6 +4,24 @@ Designbase **Web Components** — Vue 3, Angular, React, vanilla HTML에서 공
4
4
 
5
5
  100여 개의 커스텀 엘리먼트를 제공하며, React 전용 wrapper(`@designbasekorea/ui-wc/react`)도 포함합니다.
6
6
 
7
+ ### 품질 규격
8
+
9
+ 이 라이브러리의 컴포넌트는 접근성·웹표준·성능·DX·UX 규격을 기준으로 개발·평가됩니다.
10
+
11
+ | 문서 | 용도 |
12
+ |---|---|
13
+ | [품질 규격](./docs/QUALITY-GUIDELINES.md) | 규칙 정의 (P0/P1/P2, 규칙 ID) |
14
+ | [컴포넌트 체크리스트](./docs/COMPONENT-CHECKLIST.md) | 컴포넌트 작업 시 복사해 쓰는 체크리스트 |
15
+ | [스코어카드](./docs/quality/SCORECARD.md) | 전체 컴포넌트 자동 채점 결과 |
16
+ | [런타임 접근성 리포트](./docs/quality/AXE-REPORT.md) | axe-core · 키보드 시나리오 검증 결과 |
17
+ | [스타일 전략](./docs/STYLING.md) | Light DOM 결정과 CSS 규약 |
18
+
19
+ ```bash
20
+ npm run audit:quality # 정적 규격 감사 → docs/quality/SCORECARD.md
21
+ npm run audit:axe # axe-core 런타임 접근성 검증 (build 선행 필요)
22
+ npm run verify:docs # 문서 ↔ 구현 정합성
23
+ ```
24
+
7
25
  ## v0.7.3 업데이트
8
26
 
9
27
  - Sidebar 프롭 정리: `variant`(외형 `default`·`wrapper`) / `theme`(색상 `default`·`dark`·`light`), 외형별 접힌 폭
@@ -339,7 +357,6 @@ document.querySelector('db-input').addEventListener('input', handler);
339
357
  | `db-video-player` | 비디오 플레이어 |
340
358
  | `db-youtube-player` | 유튜브 플레이어 |
341
359
  | `db-audio-player` | 오디오 플레이어 |
342
- | `db-lottie` | Lottie 애니메이션 |
343
360
 
344
361
  ### 기타
345
362
 
@@ -1 +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};
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"])],prism:[r.speed,r.blur,r.noise,r.showVignette,colors([])],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};
@@ -1 +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,e.style.border="none"}export{f as ANIMATION_BACKGROUND_CLASS,applyContainerStyles,mountAnimationLayers,parseAnimationBackgroundConfig,syncLuminaOverlays};
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 p}from"./particle-defaults.js";import{CanvasAnimationController as u}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","prism"]);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"),"prism"===t?[]: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("prism"===t)return n;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=p(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 u(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",p=`blur(${a}px)`,u=`${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=u,Object.assign(t.style,{filter:p,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,p=document.createElement("style");p.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(p);const u=document.createElement("div");return u.className=`${f}__plasma-base`,u.style.backgroundColor=c(0),n.appendChild(u),[{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"prism":e.appendChild(function createPrismLayer(e,t,a,r){const n=document.createElement("div");n.className=`${f}__prism`;const o=Math.random().toString(36).slice(2,11),l=e.length?`conic-gradient(from 0deg at 50% 50%, ${e.map((t,a)=>`${t} ${Math.round(360/e.length*a)}deg`).join(", ")}, ${e[0]} 360deg)`:"var(--db-prism-gradient)",d=i(t),m=s/d,p=Math.min(56,Math.max(14,.4*a)),u=document.createElement("style");u.textContent=`\n @keyframes designbase-wc-prism-drift-1-${o} {\n 0% { transform: rotate(0deg) translate(0, 0) scale(1); }\n 50% { transform: rotate(180deg) translate(6%, 4%) scale(1.12); }\n 100% { transform: rotate(360deg) translate(0, 0) scale(1); }\n }\n @keyframes designbase-wc-prism-drift-2-${o} {\n 0% { transform: rotate(360deg) translate(0, 0) scale(1.05); }\n 50% { transform: rotate(180deg) translate(-8%, 5%) scale(0.92); }\n 100% { transform: rotate(0deg) translate(0, 0) scale(1.05); }\n }\n @keyframes designbase-wc-prism-drift-3-${o} {\n 0% { transform: rotate(0deg) translate(0, 0) scale(1.1); }\n 50% { transform: rotate(-180deg) translate(4%, -6%) scale(1.28); }\n 100% { transform: rotate(-360deg) translate(0, 0) scale(1.1); }\n }`,n.appendChild(u);const g=document.createElement("div");g.className=`${f}__prism-base`,g.style.background="var(--db-prism-dome)",n.appendChild(g);const b=[{size:"95%",top:"-34%",left:"-14%",opacity:.4,blur:p,anim:`designbase-wc-prism-drift-1-${o} ${m}s linear infinite`},{size:"80%",top:"38%",left:"58%",opacity:.3,blur:1.35*p,anim:`designbase-wc-prism-drift-2-${o} ${1.6*m}s linear infinite`},{size:"110%",top:"18%",left:"20%",opacity:.2,blur:1.9*p,anim:`designbase-wc-prism-drift-3-${o} ${2.4*m}s linear infinite`}];for(const e of b){const t=document.createElement("div");t.className=`${f}__prism-disc`,t.style.width=e.size,t.style.top=e.top,t.style.left=e.left,t.style.background=l,t.style.filter=`blur(${Math.round(e.blur)}px)`,t.style.opacity=String(e.opacity),t.style.animation=e.anim,n.appendChild(t)}return n}(a,t.speed,t.blur,t.theme)),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,e.style.border="none"}export{f as ANIMATION_BACKGROUND_CLASS,applyContainerStyles,mountAnimationLayers,parseAnimationBackgroundConfig,syncLuminaOverlays};
@@ -17,7 +17,7 @@ declare class DbAccordion extends HTMLElement {
17
17
  set items(value: AccordionItemConfig[] | string);
18
18
  get allowMultiple(): boolean;
19
19
  set allowMultiple(value: boolean);
20
- get expandedItems(): string[] | string;
20
+ get expandedItems(): string[];
21
21
  set expandedItems(value: string[] | string);
22
22
  connectedCallback(): void;
23
23
  disconnectedCallback(): void;
@@ -0,0 +1,38 @@
1
+ type DbActivityHeatmapItem = {
2
+ date: string;
3
+ value: number;
4
+ };
5
+ type DbActivityHeatmapCellDetail = {
6
+ date: string;
7
+ value: number;
8
+ level: number;
9
+ };
10
+ declare class DbActivityHeatmap extends HTMLElement {
11
+ static get observedAttributes(): string[];
12
+ connectedCallback(): void;
13
+ disconnectedCallback(): void;
14
+ attributeChangedCallback(): void;
15
+ private handleClick;
16
+ private parseData;
17
+ private parseEndDate;
18
+ private parseISODate;
19
+ private formatISODate;
20
+ private addDays;
21
+ private startOfWeek;
22
+ private isAfter;
23
+ private buildWeeks;
24
+ private resolveLevel;
25
+ private formatMonthLabel;
26
+ private formatTooltip;
27
+ private getDayLabels;
28
+ private getMonthLabels;
29
+ private render;
30
+ }
31
+ declare global {
32
+ interface HTMLElementTagNameMap {
33
+ 'db-activity-heatmap': DbActivityHeatmap;
34
+ }
35
+ }
36
+
37
+ export { DbActivityHeatmap };
38
+ export type { DbActivityHeatmapCellDetail, DbActivityHeatmapItem };
@@ -0,0 +1 @@
1
+ import{ACTIVITY_HEATMAP_SIZES as e,ACTIVITY_HEATMAP_COLOR_SCHEMES as t}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const a="designbase-wc-activity-heatmap";class DbActivityHeatmap extends HTMLElement{constructor(){super(...arguments),this.handleClick=e=>{const t=e.target,n=t?.closest(`.${a}__cell`);if(!n||n.disabled)return;const s=n.dataset.date;if(!s)return;const r=Number(n.dataset.value??"0"),l=Number(n.dataset.level??"0");this.dispatchEvent(new CustomEvent("db-cell-click",{detail:{date:s,value:r,level:l},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["data","end-date","weeks","week-starts-on","size","locale","color-scheme","show-legend","show-month-labels","show-day-labels","legend-less-label","legend-more-label","value-label","max-value","footer-text","footer-href"]}connectedCallback(){this.addEventListener("click",this.handleClick),this.render()}disconnectedCallback(){this.removeEventListener("click",this.handleClick)}attributeChangedCallback(){this.render()}parseData(){const e=this.getAttribute("data");if(!e)return[];try{const t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>e&&"string"==typeof e.date&&"number"==typeof e.value):[]}catch{return[]}}parseEndDate(){const e=this.getAttribute("end-date");if(e){const t=this.parseISODate(e);if(t)return t}const t=new Date;return new Date(t.getFullYear(),t.getMonth(),t.getDate())}parseISODate(e){const t=/^(\d{4})-(\d{2})-(\d{2})/.exec(e.trim());if(!t)return null;const a=Number(t[1]),n=Number(t[2]),s=Number(t[3]);return a&&n&&s?new Date(a,n-1,s):null}formatISODate(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}addDays(e,t){const a=new Date(e);return a.setDate(a.getDate()+t),a}startOfWeek(e,t){const a=(e.getDay()-t+7)%7;return this.addDays(e,-a)}isAfter(e,t){return e.getTime()>t.getTime()}buildWeeks(e,t,a){const n=this.startOfWeek(e,a),s=this.addDays(n,7*-(t-1)),r=[];for(let e=0;e<t;e+=1){const t=[];for(let a=0;a<7;a+=1)t.push(this.addDays(s,7*e+a));r.push(t)}return r}resolveLevel(e,t,a){if(e<=0||t<=0)return 0;const n=e/t;return Math.min(a,Math.max(1,Math.ceil(n*a)))}formatMonthLabel(e,t){return new Intl.DateTimeFormat(t,{month:"short"}).format(e)}formatTooltip(e,t,a,n){const s=new Intl.DateTimeFormat(a,{year:"numeric",month:"long",day:"numeric"}).format(e);return t<=0?`${s}: 활동 없음`:`${s}: ${t.toLocaleString(a)}${n}`}getDayLabels(e,t){const a=Array.from({length:7},(a,n)=>{const s=new Date(2024,0,7+(e+n)%7);return new Intl.DateTimeFormat(t,{weekday:"short"}).format(s)}),n=1===e?[0,2,4,6]:[1,3,5,0];return a.map((e,t)=>n.includes(t)?e:"")}getMonthLabels(e,t){const a=e.map(e=>{const t=e.find(e=>e.getDate()<=7)??e[0];return t.getMonth()+12*t.getFullYear()}),n=e.map(()=>"");let s=0;for(;s<e.length;){const r=a[s];let l=s+1;for(;l<e.length&&a[l]===r;)l+=1;if(l-s>=2){const a=e[s],r=a.find(e=>e.getDate()<=7)??a[0];n[s]=this.formatMonthLabel(r,t)}s=l}return n}render(){const n=this.parseData(),s=new Map(n.map(e=>[e.date,e.value])),r=this.parseEndDate(),l=Math.max(1,Number(this.getAttribute("weeks")??"53")||53),o="0"===this.getAttribute("week-starts-on")?0:1,i=this.getAttribute("size")||"m",c=e.includes(i)?i:"m",d=this.getAttribute("locale")||"ko-KR",m=this.getAttribute("color-scheme")||"green",u=t.includes(m)?m:"green",h="false"!==this.getAttribute("show-legend"),p="false"!==this.getAttribute("show-month-labels"),b="false"!==this.getAttribute("show-day-labels"),g=this.getAttribute("legend-less-label")||"적음",f=this.getAttribute("legend-more-label")||"많음",_=this.getAttribute("value-label")||"회",v=this.getAttribute("footer-text")||"",$=this.getAttribute("footer-href")||"",E=this.getAttribute("max-value"),A=n.map(e=>e.value).filter(e=>e>0),D=A.length?Math.max(...A):0,y=E?Math.max(Number(E)||0,D):D,N=this.buildWeeks(r,l,o),w=this.getMonthLabels(N,d),k=this.getDayLabels(o,d);this.className=[a,`${a}--size-${c}`,`${a}--color-${u}`,h&&`${a}--with-legend`].filter(Boolean).join(" "),this.replaceChildren();const x=document.createElement("div");x.className=`${a}__viewport`;const C=document.createElement("div");if(C.className=`${a}__scroll-inner`,b){const e=document.createElement("div");e.className=`${a}__sticky-rail`;const t=document.createElement("div");t.className=`${a}__sticky-spacer`,p||t.classList.add(`${a}__sticky-spacer--hidden`);const n=document.createElement("div");n.className=`${a}__days`,n.setAttribute("aria-hidden","true"),k.forEach(e=>{const t=document.createElement("span");t.className=`${a}__day`,t.textContent=e,n.append(t)}),e.append(t,n),C.append(e)}const M=document.createElement("div");if(M.className=`${a}__grid-area`,p){const e=document.createElement("div");e.className=`${a}__months`,e.setAttribute("aria-hidden","true"),w.forEach(t=>{const n=document.createElement("span");n.className=`${a}__month`,n.textContent=t,e.append(n)}),M.append(e)}const L=document.createElement("div");if(L.className=`${a}__weeks`,L.setAttribute("role","grid"),L.setAttribute("aria-label","활동 히트맵"),N.forEach(e=>{const t=document.createElement("div");t.className=`${a}__week`,t.setAttribute("role","row"),e.forEach(e=>{const n=this.formatISODate(e),l=this.isAfter(e,r),o=l?0:s.get(n)??0,i=l?0:this.resolveLevel(o,y,4),c=document.createElement("button");c.type="button",c.className=[`${a}__cell`,`${a}__cell--level-${i}`,l&&`${a}__cell--future`].filter(Boolean).join(" "),c.dataset.date=n,c.dataset.value=String(o),c.dataset.level=String(i),c.title=this.formatTooltip(e,o,d,_),c.setAttribute("aria-label",this.formatTooltip(e,o,d,_)),c.disabled=l,t.append(c)}),L.append(t)}),M.append(L),C.append(M),x.append(C),this.append(x),h||v){const e=document.createElement("div");if(e.className=`${a}__footer`,v)if($){const t=document.createElement("a");t.className=`${a}__footer-link`,t.href=$,t.textContent=v,e.append(t)}else{const t=document.createElement("span");t.className=`${a}__footer-text`,t.textContent=v,e.append(t)}else e.append(document.createElement("span"));if(h){const t=document.createElement("div");t.className=`${a}__legend`,t.setAttribute("aria-hidden","true");const n=document.createElement("span");n.className=`${a}__legend-label`,n.textContent=g;const s=document.createElement("div");s.className=`${a}__legend-scale`;for(let e=0;e<=4;e+=1){const t=document.createElement("span");t.className=`${a}__legend-cell ${a}__legend-cell--level-${e}`,s.append(t)}const r=document.createElement("span");r.className=`${a}__legend-label`,r.textContent=f,t.append(n,s,r),e.append(t)}this.append(e)}}}customElements.get("db-activity-heatmap")||customElements.define("db-activity-heatmap",DbActivityHeatmap);export{DbActivityHeatmap};
@@ -11,6 +11,8 @@ declare class DbAnimationBackground extends HTMLElement {
11
11
  private syncingControls;
12
12
  static get observedAttributes(): string[];
13
13
  connectedCallback(): void;
14
+ /** 열린 설정 패널은 Escape 로 닫힌다 (A11Y-ESCAPE) */
15
+ private handleDocumentKeyDown;
14
16
  disconnectedCallback(): void;
15
17
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
16
18
  private getBool;
@@ -1 +1 @@
1
- import{parseAnimationBackgroundConfig as t,mountAnimationLayers as e,applyContainerStyles as s,syncLuminaOverlays as n,ANIMATION_BACKGROUND_CLASS as i}from"./animation-background/layers.js";import{getControlsForType as o,resetControlsToDefaults as l,getControlSliderBounds as r,controlSliderToAttr as a,writeControlAttribute as c,readControlValue as d,controlAttrToSlider as h}from"./animation-background/controls.js";import{isGraphitePresetId as u,getGraphitePreset as p}from"./animation-background/graphite-presets.js";import{createDbIcon as m}from"./db-icons.js";const b=i,g=["particles","stars","snow","flowers","confetti","mesh-flow","fluid","radiant","ethereal","graphite"],y=["mesh-flow","fluid","radiant","ethereal"];class DbAnimationBackground extends HTMLElement{constructor(){super(...arguments),this.panelOpen=!1,this.controlInputs=new Map,this.syncingControls=!1}static get observedAttributes(){return["type","theme","intensity","blur","speed","direction","colors","width","height","border-radius","opacity","blend-mode","particle-count","particle-size","star-count","star-size","wind","clickable","disabled","noise","show-vignette","preset","zoom","show-controls","shader-speed","shader-intensity","warp"]}connectedCallback(){this.style.display="block",this.render()}disconnectedCallback(){this.teardownLayers(),this.clickHandler&&(this.removeEventListener("click",this.clickHandler),this.clickHandler=void 0)}attributeChangedCallback(t,e,s){this.isConnected&&e!==s&&("show-controls"!==t?this.syncingControls||("type"===t&&this.getBool("show-controls",!1)&&this.rebuildControlInputs(),this.applyConfig(),this.getBool("show-controls",!1)&&this.syncControlInputs()):this.syncControlsVisibility())}getBool(t,e=!1){return this.hasAttribute(t)?"false"!==this.getAttribute(t):e}getSizeStyle(t){if(!t)return;const e=Number(t);return Number.isFinite(e)?`${e}px`:t}getConfig(){return t(this)}teardownLayers(){this.layerHandle?.destroy?.(),this.layerHandle=void 0,this.mountedType=void 0,this.layersEl&&this.layersEl.replaceChildren()}remountLayers(t){this.layersEl&&(this.teardownLayers(),this.layerHandle=e(this.layersEl,t),this.mountedType=t.type)}canLiveUpdate(t){return this.mountedType===t.type&&g.includes(t.type)&&"function"==typeof this.layerHandle?.update}applyConfig(){const t=this.getConfig();this.className=[b,`${b}--${t.type}`,t.clickable&&!t.disabled&&`${b}--clickable`,t.disabled&&`${b}--disabled`,this.getBool("show-controls",!1)&&`${b}--show-controls`].filter(Boolean).join(" "),s(this,t);const e=this.getSizeStyle(this.getAttribute("width")),i=this.getSizeStyle(this.getAttribute("height")),o=this.getSizeStyle(this.getAttribute("border-radius"));e&&(this.style.width=e),i&&(this.style.height=i),this.style.borderRadius=o||"0",this.style.border="none",this.style.opacity="",this.layersEl&&(this.layersEl.style.opacity=String(t.opacity));const l=this.getAttribute("blend-mode");if(l&&(this.style.mixBlendMode=l),t.disabled)return this.teardownLayers(),void this.syncClickable(t);this.canLiveUpdate(t)?(this.layerHandle?.update?.(t),this.layersEl&&y.includes(t.type)&&n(this.layersEl,t.noise,t.showVignette)):this.remountLayers(t),this.syncClickable(t)}syncClickable(t){this.clickHandler&&(this.removeEventListener("click",this.clickHandler),this.clickHandler=void 0),t.clickable&&!t.disabled&&(this.clickHandler=()=>{this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))},this.addEventListener("click",this.clickHandler))}render(){if(!this.layersEl){this.layersEl=document.createElement("div"),this.layersEl.className=`${b}__layers`,Object.assign(this.layersEl.style,{position:"absolute",inset:"0",width:"100%",height:"100%",zIndex:"0"}),this.contentEl=document.createElement("div"),this.contentEl.className=`${b}__content`,Object.assign(this.contentEl.style,{position:"relative",zIndex:"10",width:"100%",height:"100%"});const t=document.createElement("slot");this.contentEl.appendChild(t),this.append(this.layersEl,this.contentEl)}this.ensureControlsShell(),this.applyConfig(),this.syncControlsVisibility()}ensureControlsShell(){if(this.controlsRootEl)return;const t=document.createElement("div");t.className=`${b}__controls-root`,t.hidden=!0;const e=this.createIconButton("settings","컨트롤 열기",()=>{this.panelOpen=!this.panelOpen,this.syncPanelState()});e.setAttribute("variant","secondary"),e.className=`${b}__controls-gear`;const s=document.createElement("div");s.className=`${b}__controls-panel`,s.setAttribute("role","dialog"),s.hidden=!0,s.addEventListener("click",t=>t.stopPropagation());const n=document.createElement("div");n.className=`${b}__controls-head`;const i=document.createElement("span");i.className=`${b}__controls-title`,i.append(m("settings",14),document.createTextNode(" Controls"));const r=this.createIconButton("refresh","기본값으로 초기화",()=>{const t=this.getConfig(),e=o(t.type);if(this.syncingControls=!0,l(this,e),"graphite"===t.type){const t=p("graphite");this.setAttribute("zoom",String(t.scale)),this.setAttribute("colors",JSON.stringify(t.colors))}this.syncingControls=!1,this.applyConfig(),this.syncControlInputs()});r.className=`${b}__controls-icon-btn`,n.append(i,r),s.append(n),t.append(e,s),this.appendChild(t),this.controlsRootEl=t,this.panelEl=s}syncControlsVisibility(){if(!this.controlsRootEl)return;const t=this.getBool("show-controls",!1);this.controlsRootEl.hidden=!t,t?this.rebuildControlInputs():(this.panelOpen=!1,this.syncPanelState())}syncPanelState(){if(!this.controlsRootEl||!this.panelEl)return;const t=this.controlsRootEl.querySelector(`.${b}__controls-gear`);t&&(t.dataset.open=this.panelOpen?"true":"false",t.setAttribute("aria-expanded",this.panelOpen?"true":"false")),this.panelEl.hidden=!this.panelOpen}createIconButton(t,e,s){const n=document.createElement("db-button");return n.setAttribute("variant","tertiary"),n.setAttribute("size","s"),n.setAttribute("icon-only",""),n.setAttribute("start-icon",t),n.setAttribute("aria-label",e),n.addEventListener("click",t=>{t.stopPropagation(),s()}),n}rebuildControlInputs(){if(!this.panelEl)return;this.panelEl.querySelectorAll(`.${b}__controls-field`).forEach(t=>t.remove()),this.controlInputs.clear();const t=this.getConfig(),e=o(t.type),s=this.panelEl.querySelector(`.${b}__controls-title`);s&&(s.lastChild?.remove(),s.append(document.createTextNode(` ${t.type}`))),e.forEach(t=>{const e=this.createControlField(t);this.panelEl?.appendChild(e)}),this.syncControlInputs()}createControlField(t){const e=document.createElement("div");if(e.className=`${b}__controls-field`,e.dataset.attr=t.attr,"range"===t.kind){const s=r(t),n=document.createElement("db-range-slider");return n.className=`${b}__controls-range`,n.setAttribute("size","s"),n.setAttribute("full-width",""),n.setAttribute("show-label",""),n.setAttribute("label",t.label),n.setAttribute("show-value",""),n.setAttribute("value-position","top"),n.setAttribute("show-thumb-tooltip",""),n.setAttribute("min",String(s.min)),n.setAttribute("max",String(s.max)),n.setAttribute("step",String(s.step)),null!=s.fixed&&n.setAttribute("value-fixed",String(s.fixed)),n.addEventListener("db-change",e=>{const s=e.detail;null!=s.value&&this.commitControlValue(t,a(t,s.value))}),e.appendChild(n),this.controlInputs.set(t.attr,n),e}if("select"===t.kind){const s=document.createElement("div");s.className=`${b}__controls-label`,s.textContent=t.label;const n=t.options??[];if(n.length>4){const i=document.createElement("db-select");i.className=`${b}__controls-select`,i.setAttribute("size","s"),i.setAttribute("full-width",""),i.setAttribute("options",JSON.stringify(n.map(t=>({value:t,label:t})))),i.addEventListener("db-change",e=>{const s=e.detail;null!=s.value&&this.commitControlValue(t,s.value)}),e.append(s,i),this.controlInputs.set(t.attr,i)}else{const i=document.createElement("db-segment-control");i.className=`${b}__controls-seg`,i.setAttribute("size","s"),i.setAttribute("full-width",""),i.setAttribute("options",JSON.stringify(n.map(t=>({value:t,label:t})))),i.addEventListener("db-change",e=>{const s=e.detail;null!=s.value&&this.commitControlValue(t,s.value)}),e.append(s,i),this.controlInputs.set(t.attr,i)}return e}if("toggle"===t.kind){const s=document.createElement("div");s.className=`${b}__controls-toggle`;const n=document.createElement("span");n.textContent=t.label;const i=document.createElement("db-toggle");return i.setAttribute("size","s"),i.addEventListener("db-change",e=>{const s=e.detail;this.commitControlValue(t,Boolean(s.checked))}),s.append(n,i),e.appendChild(s),this.controlInputs.set(t.attr,i),e}const s=document.createElement("div");s.className=`${b}__controls-label`,s.textContent=t.label;const n=document.createElement("div");return n.className=`${b}__controls-colors`,e.append(s,n),this.controlInputs.set(t.attr,n),e}commitControlValue(t,e){if(this.syncingControls=!0,c(this,t,e),"preset"===t.attr&&"graphite"===this.getConfig().type&&"string"==typeof e&&u(e)){const t=p(e);this.setAttribute("zoom",String(t.scale)),this.setAttribute("colors",JSON.stringify(t.colors))}this.syncingControls=!1,this.applyConfig()}syncControlInputs(){o(this.getConfig().type).forEach(t=>{const e=d(this,t),s=this.controlInputs.get(t.attr);if(s)if("range"===t.kind&&function isRangeSlider(t){return"DB-RANGE-SLIDER"===t.tagName}(s)){const n=Number(e);s.setAttribute("value",String(h(t,n)))}else if("select"===t.kind)s.setAttribute("value",String(e));else if("toggle"===t.kind){Boolean(e)?s.setAttribute("checked",""):s.removeAttribute("checked")}else"colors"===t.kind&&this.renderColorInputs(s,t,e)})}renderColorInputs(t,e,s){const n=[...s];t.replaceChildren();const commitStructuralChange=s=>{this.commitControlValue(e,s),this.renderColorInputs(t,e,s)};if(n.forEach((s,i)=>{const o=document.createElement("div");o.className=`${b}__controls-color`;const l=document.createElement("db-color-picker");if(l.className=`${b}__controls-color-picker`,l.setAttribute("size","s"),l.setAttribute("full-width",""),l.setAttribute("show-alpha","false"),l.setAttribute("show-eyedropper","false"),l.setAttribute("value",s),l.addEventListener("db-change",t=>{const s=t.detail,o=s?.value;"string"==typeof o&&o&&(n[i]=o,this.commitControlValue(e,[...n]))}),o.appendChild(l),n.length>1){const t=this.createIconButton("trash","색상 제거",()=>{commitStructuralChange(n.filter((t,e)=>e!==i))});t.className=`${b}__controls-color-remove`,o.appendChild(t)}t.appendChild(o)}),n.length<8){const e=this.createIconButton("plus","색상 추가",()=>{commitStructuralChange([...n,n[n.length-1]??"#ffffff"])});e.className=`${b}__controls-color-add`,t.appendChild(e)}}}customElements.get("db-animation-background")||customElements.define("db-animation-background",DbAnimationBackground);export{DbAnimationBackground};
1
+ import{parseAnimationBackgroundConfig as t,mountAnimationLayers as e,applyContainerStyles as s,syncLuminaOverlays as n,ANIMATION_BACKGROUND_CLASS as i}from"./animation-background/layers.js";import{getControlsForType as o,resetControlsToDefaults as l,getControlSliderBounds as r,controlSliderToAttr as a,writeControlAttribute as c,readControlValue as d,controlAttrToSlider as h}from"./animation-background/controls.js";import{isGraphitePresetId as u,getGraphitePreset as p}from"./animation-background/graphite-presets.js";import{createDbIcon as m}from"./db-icons.js";const b=i,y=["particles","stars","snow","flowers","confetti","mesh-flow","fluid","radiant","ethereal","graphite"],g=["mesh-flow","fluid","radiant","ethereal"];class DbAnimationBackground extends HTMLElement{constructor(){super(...arguments),this.panelOpen=!1,this.controlInputs=new Map,this.syncingControls=!1,this.handleDocumentKeyDown=t=>{"Escape"===t.key&&this.panelOpen&&(t.preventDefault(),this.panelOpen=!1,this.syncPanelState())}}static get observedAttributes(){return["type","theme","intensity","blur","speed","direction","colors","width","height","border-radius","opacity","blend-mode","particle-count","particle-size","star-count","star-size","wind","clickable","disabled","noise","show-vignette","preset","zoom","show-controls","shader-speed","shader-intensity","warp"]}connectedCallback(){this.style.display="block",this.render(),document.addEventListener("keydown",this.handleDocumentKeyDown)}disconnectedCallback(){document.removeEventListener("keydown",this.handleDocumentKeyDown),this.teardownLayers(),this.clickHandler&&(this.removeEventListener("click",this.clickHandler),this.clickHandler=void 0)}attributeChangedCallback(t,e,s){this.isConnected&&e!==s&&("show-controls"!==t?this.syncingControls||("type"===t&&this.getBool("show-controls",!1)&&this.rebuildControlInputs(),this.applyConfig(),this.getBool("show-controls",!1)&&this.syncControlInputs()):this.syncControlsVisibility())}getBool(t,e=!1){return this.hasAttribute(t)?"false"!==this.getAttribute(t):e}getSizeStyle(t){if(!t)return;const e=Number(t);return Number.isFinite(e)?`${e}px`:t}getConfig(){return t(this)}teardownLayers(){this.layerHandle?.destroy?.(),this.layerHandle=void 0,this.mountedType=void 0,this.layersEl&&this.layersEl.replaceChildren()}remountLayers(t){this.layersEl&&(this.teardownLayers(),this.layerHandle=e(this.layersEl,t),this.mountedType=t.type)}canLiveUpdate(t){return this.mountedType===t.type&&y.includes(t.type)&&"function"==typeof this.layerHandle?.update}applyConfig(){const t=this.getConfig();this.className=[b,`${b}--${t.type}`,t.clickable&&!t.disabled&&`${b}--clickable`,t.disabled&&`${b}--disabled`,this.getBool("show-controls",!1)&&`${b}--show-controls`].filter(Boolean).join(" "),s(this,t);const e=this.getSizeStyle(this.getAttribute("width")),i=this.getSizeStyle(this.getAttribute("height")),o=this.getSizeStyle(this.getAttribute("border-radius"));e&&(this.style.width=e),i&&(this.style.height=i),this.style.borderRadius=o||"0",this.style.border="none",this.style.opacity="",this.layersEl&&(this.layersEl.style.opacity=String(t.opacity));const l=this.getAttribute("blend-mode");if(l&&(this.style.mixBlendMode=l),t.disabled)return this.teardownLayers(),void this.syncClickable(t);this.canLiveUpdate(t)?(this.layerHandle?.update?.(t),this.layersEl&&g.includes(t.type)&&n(this.layersEl,t.noise,t.showVignette)):this.remountLayers(t),this.syncClickable(t)}syncClickable(t){this.clickHandler&&(this.removeEventListener("click",this.clickHandler),this.clickHandler=void 0),t.clickable&&!t.disabled&&(this.clickHandler=()=>{this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))},this.addEventListener("click",this.clickHandler))}render(){if(!this.layersEl){this.layersEl=document.createElement("div"),this.layersEl.className=`${b}__layers`,Object.assign(this.layersEl.style,{position:"absolute",inset:"0",width:"100%",height:"100%",zIndex:"0"}),this.contentEl=document.createElement("div"),this.contentEl.className=`${b}__content`,Object.assign(this.contentEl.style,{position:"relative",zIndex:"10",width:"100%",height:"100%"});const t=document.createElement("slot");this.contentEl.appendChild(t),this.append(this.layersEl,this.contentEl)}this.ensureControlsShell(),this.applyConfig(),this.syncControlsVisibility()}ensureControlsShell(){if(this.controlsRootEl)return;const t=document.createElement("div");t.className=`${b}__controls-root`,t.hidden=!0;const e=this.createIconButton("settings","컨트롤 열기",()=>{this.panelOpen=!this.panelOpen,this.syncPanelState()});e.setAttribute("variant","secondary"),e.className=`${b}__controls-gear`;const s=document.createElement("div");s.className=`${b}__controls-panel`,s.setAttribute("role","dialog"),s.setAttribute("aria-modal","false"),s.hidden=!0,s.addEventListener("click",t=>t.stopPropagation());const n=document.createElement("div");n.className=`${b}__controls-head`;const i=document.createElement("span");i.className=`${b}__controls-title`,i.append(m("settings",14),document.createTextNode(" Controls"));const r=this.createIconButton("refresh","기본값으로 초기화",()=>{const t=this.getConfig(),e=o(t.type);if(this.syncingControls=!0,l(this,e),"graphite"===t.type){const t=p("graphite");this.setAttribute("zoom",String(t.scale)),this.setAttribute("colors",JSON.stringify(t.colors))}this.syncingControls=!1,this.applyConfig(),this.syncControlInputs()});r.className=`${b}__controls-icon-btn`,n.append(i,r),s.append(n),t.append(e,s),this.appendChild(t),this.controlsRootEl=t,this.panelEl=s}syncControlsVisibility(){if(!this.controlsRootEl)return;const t=this.getBool("show-controls",!1);this.controlsRootEl.hidden=!t,t?this.rebuildControlInputs():(this.panelOpen=!1,this.syncPanelState())}syncPanelState(){if(!this.controlsRootEl||!this.panelEl)return;const t=this.controlsRootEl.querySelector(`.${b}__controls-gear`);t&&(t.dataset.open=this.panelOpen?"true":"false",t.setAttribute("aria-expanded",this.panelOpen?"true":"false")),this.panelEl.hidden=!this.panelOpen}createIconButton(t,e,s){const n=document.createElement("db-button");return n.setAttribute("variant","tertiary"),n.setAttribute("size","s"),n.setAttribute("icon-only",""),n.setAttribute("start-icon",t),n.setAttribute("aria-label",e),n.addEventListener("click",t=>{t.stopPropagation(),s()}),n}rebuildControlInputs(){if(!this.panelEl)return;this.panelEl.querySelectorAll(`.${b}__controls-field`).forEach(t=>t.remove()),this.controlInputs.clear();const t=this.getConfig(),e=o(t.type),s=this.panelEl.querySelector(`.${b}__controls-title`);s&&(s.lastChild?.remove(),s.append(document.createTextNode(` ${t.type}`))),e.forEach(t=>{const e=this.createControlField(t);this.panelEl?.appendChild(e)}),this.syncControlInputs()}createControlField(t){const e=document.createElement("div");if(e.className=`${b}__controls-field`,e.dataset.attr=t.attr,"range"===t.kind){const s=r(t),n=document.createElement("db-range-slider");return n.className=`${b}__controls-range`,n.setAttribute("size","s"),n.setAttribute("full-width",""),n.setAttribute("show-label",""),n.setAttribute("label",t.label),n.setAttribute("show-value",""),n.setAttribute("value-position","top"),n.setAttribute("show-thumb-tooltip",""),n.setAttribute("min",String(s.min)),n.setAttribute("max",String(s.max)),n.setAttribute("step",String(s.step)),null!=s.fixed&&n.setAttribute("value-fixed",String(s.fixed)),n.addEventListener("db-change",e=>{const s=e.detail;null!=s.value&&this.commitControlValue(t,a(t,s.value))}),e.appendChild(n),this.controlInputs.set(t.attr,n),e}if("select"===t.kind){const s=document.createElement("div");s.className=`${b}__controls-label`,s.textContent=t.label;const n=t.options??[];if(n.length>4){const i=document.createElement("db-select");i.className=`${b}__controls-select`,i.setAttribute("size","s"),i.setAttribute("full-width",""),i.setAttribute("options",JSON.stringify(n.map(t=>({value:t,label:t})))),i.addEventListener("db-change",e=>{const s=e.detail;null!=s.value&&this.commitControlValue(t,s.value)}),e.append(s,i),this.controlInputs.set(t.attr,i)}else{const i=document.createElement("db-segment-control");i.className=`${b}__controls-seg`,i.setAttribute("size","s"),i.setAttribute("full-width",""),i.setAttribute("options",JSON.stringify(n.map(t=>({value:t,label:t})))),i.addEventListener("db-change",e=>{const s=e.detail;null!=s.value&&this.commitControlValue(t,s.value)}),e.append(s,i),this.controlInputs.set(t.attr,i)}return e}if("toggle"===t.kind){const s=document.createElement("div");s.className=`${b}__controls-toggle`;const n=document.createElement("span");n.textContent=t.label;const i=document.createElement("db-toggle");return i.setAttribute("size","s"),i.addEventListener("db-change",e=>{const s=e.detail;this.commitControlValue(t,Boolean(s.checked))}),s.append(n,i),e.appendChild(s),this.controlInputs.set(t.attr,i),e}const s=document.createElement("div");s.className=`${b}__controls-label`,s.textContent=t.label;const n=document.createElement("div");return n.className=`${b}__controls-colors`,e.append(s,n),this.controlInputs.set(t.attr,n),e}commitControlValue(t,e){if(this.syncingControls=!0,c(this,t,e),"preset"===t.attr&&"graphite"===this.getConfig().type&&"string"==typeof e&&u(e)){const t=p(e);this.setAttribute("zoom",String(t.scale)),this.setAttribute("colors",JSON.stringify(t.colors))}this.syncingControls=!1,this.applyConfig()}syncControlInputs(){o(this.getConfig().type).forEach(t=>{const e=d(this,t),s=this.controlInputs.get(t.attr);if(s)if("range"===t.kind&&function isRangeSlider(t){return"DB-RANGE-SLIDER"===t.tagName}(s)){const n=Number(e);s.setAttribute("value",String(h(t,n)))}else if("select"===t.kind)s.setAttribute("value",String(e));else if("toggle"===t.kind){Boolean(e)?s.setAttribute("checked",""):s.removeAttribute("checked")}else"colors"===t.kind&&this.renderColorInputs(s,t,e)})}renderColorInputs(t,e,s){const n=[...s];t.replaceChildren();const commitStructuralChange=s=>{this.commitControlValue(e,s),this.renderColorInputs(t,e,s)};if(n.forEach((s,i)=>{const o=document.createElement("div");o.className=`${b}__controls-color`;const l=document.createElement("db-color-picker");if(l.className=`${b}__controls-color-picker`,l.setAttribute("size","s"),l.setAttribute("full-width",""),l.setAttribute("show-alpha","false"),l.setAttribute("show-eyedropper","false"),l.setAttribute("value",s),l.addEventListener("db-change",t=>{const s=t.detail,o=s?.value;"string"==typeof o&&o&&(n[i]=o,this.commitControlValue(e,[...n]))}),o.appendChild(l),n.length>1){const t=this.createIconButton("trash","색상 제거",()=>{commitStructuralChange(n.filter((t,e)=>e!==i))});t.className=`${b}__controls-color-remove`,o.appendChild(t)}t.appendChild(o)}),n.length<8){const e=this.createIconButton("plus","색상 추가",()=>{commitStructuralChange([...n,n[n.length-1]??"#ffffff"])});e.className=`${b}__controls-color-add`,t.appendChild(e)}}}customElements.get("db-animation-background")||customElements.define("db-animation-background",DbAnimationBackground);export{DbAnimationBackground};
@@ -1,4 +1,5 @@
1
1
  declare class DbAppBadge extends HTMLElement {
2
+ private detachKeyActivation?;
2
3
  static get observedAttributes(): string[];
3
4
  private built;
4
5
  private labelEl?;
@@ -9,6 +10,7 @@ declare class DbAppBadge extends HTMLElement {
9
10
  private getStore;
10
11
  private getIconSize;
11
12
  private build;
13
+ disconnectedCallback(): void;
12
14
  private updateUI;
13
15
  }
14
16
  declare global {
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e="designbase-wc-app-badge",s={"app-store":{label:"다운로드",storeName:"App Store"},"google-play":{label:"다운로드",storeName:"Google Play"}};class DbAppBadge extends HTMLElement{constructor(){super(...arguments),this.built=!1}static get observedAttributes(){return["store","href","label","store-name","size","theme"]}connectedCallback(){this.built||(this.built=!0,this.build()),this.updateUI()}attributeChangedCallback(){this.built&&this.updateUI()}getStore(){return"google-play"===(this.getAttribute("store")||"app-store")?"google-play":"app-store"}getIconSize(){const t=this.getAttribute("size")||"m";return"s"===t?18:"l"===t?24:20}build(){this.iconWrapEl=document.createElement("span"),this.iconWrapEl.className=`${e}__icon`,this.iconWrapEl.setAttribute("aria-hidden","true");const t=document.createElement("span");t.className=`${e}__text`,this.labelEl=document.createElement("span"),this.labelEl.className=`${e}__label`,this.storeEl=document.createElement("span"),this.storeEl.className=`${e}__store`,t.append(this.labelEl,this.storeEl),this.append(this.iconWrapEl,t),this.addEventListener("click",t=>{this.getAttribute("href")||this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0,detail:{event:t}}))})}updateUI(){const i=this.getStore(),a=s[i],l=this.getAttribute("size")||"m",r=this.getAttribute("theme")||"dark",o=this.getAttribute("label")||a.label,n=this.getAttribute("store-name")||a.storeName,p=this.getAttribute("href");this.className=[e,`${e}--${l}`,`${e}--${r}`,`${e}--${i}`].join(" "),p?(this.setAttribute("role","link"),this.tabIndex=0,this.onclick=()=>window.open(p,"_blank","noopener,noreferrer")):(this.setAttribute("role","button"),this.tabIndex=0),this.iconWrapEl&&this.iconWrapEl.replaceChildren(t("app-store"===i?"apple":"play-store",this.getIconSize())),this.labelEl&&(this.labelEl.textContent=o),this.storeEl&&(this.storeEl.textContent=n)}}customElements.get("db-app-badge")||customElements.define("db-app-badge",DbAppBadge);export{DbAppBadge};
1
+ import{createDbIcon as t}from"./db-icons.js";import{activateOnKey as e}from"../core/a11y.js";const s="designbase-wc-app-badge",i={"app-store":{label:"다운로드",storeName:"App Store"},"google-play":{label:"다운로드",storeName:"Google Play"}};class DbAppBadge extends HTMLElement{constructor(){super(...arguments),this.built=!1}static get observedAttributes(){return["store","href","label","store-name","size","theme"]}connectedCallback(){this.built||(this.built=!0,this.build()),this.updateUI()}attributeChangedCallback(){this.built&&this.updateUI()}getStore(){return"google-play"===(this.getAttribute("store")||"app-store")?"google-play":"app-store"}getIconSize(){const t=this.getAttribute("size")||"m";return"s"===t?18:"l"===t?24:20}build(){this.iconWrapEl=document.createElement("span"),this.iconWrapEl.className=`${s}__icon`,this.iconWrapEl.setAttribute("aria-hidden","true");const t=document.createElement("span");t.className=`${s}__text`,this.labelEl=document.createElement("span"),this.labelEl.className=`${s}__label`,this.storeEl=document.createElement("span"),this.storeEl.className=`${s}__store`,t.append(this.labelEl,this.storeEl),this.append(this.iconWrapEl,t),this.addEventListener("click",t=>{this.getAttribute("href")||this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0,detail:{event:t}}))}),this.detachKeyActivation=e(this)}disconnectedCallback(){this.detachKeyActivation?.(),this.detachKeyActivation=void 0}updateUI(){const e=this.getStore(),a=i[e],l=this.getAttribute("size")||"m",o=this.getAttribute("theme")||"dark",r=this.getAttribute("label")||a.label,n=this.getAttribute("store-name")||a.storeName,h=this.getAttribute("href");this.className=[s,`${s}--${l}`,`${s}--${o}`,`${s}--${e}`].join(" "),h?(this.setAttribute("role","link"),this.tabIndex=0,this.onclick=()=>window.open(h,"_blank","noopener,noreferrer")):(this.setAttribute("role","button"),this.tabIndex=0),this.iconWrapEl&&this.iconWrapEl.replaceChildren(t("app-store"===e?"apple":"play-store",this.getIconSize())),this.labelEl&&(this.labelEl.textContent=r),this.storeEl&&(this.storeEl.textContent=n)}}customElements.get("db-app-badge")||customElements.define("db-app-badge",DbAppBadge);export{DbAppBadge};
@@ -51,6 +51,10 @@ declare class DbAudioPlayer extends HTMLElement {
51
51
  private toggleShuffle;
52
52
  private handlePlaybackRateChange;
53
53
  private handleKeyDown;
54
+ /**
55
+ * 아이콘만 있는 컨트롤 버튼. `label` 은 선택이 아니라 필수다 —
56
+ * 아이콘은 aria-hidden 이므로 이것이 유일한 접근 가능한 이름이 된다. (A11Y-NAME)
57
+ */
54
58
  private iconButton;
55
59
  private build;
56
60
  private get leftControls();
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e="designbase-wc-audio-player";class DbAudioPlayer extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isPlaying=!1,this.isMuted=!1,this.volume=1,this.currentTime=0,this.duration=0,this.showSettingsMenu=!1,this.playbackRate=1,this.currentRepeatMode="none",this.isShuffle=!1,this.isLoading=!1,this.error=null,this.playlistIndex=0,this.shuffledPlaylist=[],this.boundKeyDown=t=>this.handleKeyDown(t)}static get observedAttributes(){return["src","title","artist","album","album-art","size","variant","theme","auto-play","loop","muted","show-controls","enable-keyboard","show-progress","show-time","show-volume","show-settings","playlist","current-index","playback-rates","default-playback-rate","repeat-mode","shuffle"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build(),this.bindAudioEvents()),this.syncFromAttributes(),this.updateUI(),this.getBool("enable-keyboard",!0)&&document.addEventListener("keydown",this.boundKeyDown)}disconnectedCallback(){document.removeEventListener("keydown",this.boundKeyDown)}attributeChangedCallback(t){if(this.built){if("current-index"===t)return this.playlistIndex=Number(this.getAttribute("current-index")||0),void this.loadCurrentTrack();"repeat-mode"===t&&(this.currentRepeatMode=this.getAttribute("repeat-mode")||"none"),"shuffle"===t&&(this.isShuffle=this.getBool("shuffle"),this.refreshShuffledPlaylist()),"default-playback-rate"===t&&(this.playbackRate=Number(this.getAttribute("default-playback-rate")||1),this.audioEl&&(this.audioEl.playbackRate=this.playbackRate)),this.updateUI()}}getBool(t,e=!1){if(!this.hasAttribute(t))return e;const s=this.getAttribute(t);return""===s||"true"===s}getPlaylist(){try{const t=this.getAttribute("playlist"),e=t?JSON.parse(t):[];return Array.isArray(e)?e:[]}catch{return[]}}getPlaybackRates(){try{const t=this.getAttribute("playback-rates"),e=t?JSON.parse(t):[.5,.75,1,1.25,1.5,2];return Array.isArray(e)&&e.length>0?e:[.5,.75,1,1.25,1.5,2]}catch{return[.5,.75,1,1.25,1.5,2]}}getIconSize(){const t=this.getAttribute("size")||"m";return"s"===t?16:"l"===t?24:"xl"===t?32:20}getCurrentTrack(){const t=this.getPlaylist();if(t.length>0){return t[this.isShuffle&&this.shuffledPlaylist.length>0?this.shuffledPlaylist[this.playlistIndex]??this.playlistIndex:this.playlistIndex]||t[0]}return{src:this.getAttribute("src")||"",title:this.getAttribute("title")||void 0,artist:this.getAttribute("artist")||void 0,album:this.getAttribute("album")||void 0,albumArt:this.getAttribute("album-art")||void 0}}refreshShuffledPlaylist(){const t=this.getPlaylist();if(t.length>0&&this.isShuffle){const e=Array.from({length:t.length},(t,e)=>e);this.shuffledPlaylist=[...e].sort(()=>Math.random()-.5)}else this.shuffledPlaylist=[]}formatTime(t){return`${Math.floor(t/60)}:${Math.floor(t%60).toString().padStart(2,"0")}`}syncFromAttributes(){this.playlistIndex=Number(this.getAttribute("current-index")||0),this.currentRepeatMode=this.getAttribute("repeat-mode")||"none",this.isShuffle=this.getBool("shuffle"),this.playbackRate=Number(this.getAttribute("default-playback-rate")||1),this.isMuted=this.getBool("muted"),this.volume=this.isMuted?0:1,this.refreshShuffledPlaylist(),this.loadCurrentTrack()}loadCurrentTrack(){if(!this.audioEl)return;const t=this.getCurrentTrack(),e=t?.src||this.getAttribute("src")||"";this.audioEl.src!==e&&e&&(this.audioEl.src=e,this.audioEl.load()),this.updateTrackInfo(),this.updatePlaylistActive()}bindAudioEvents(){const t=this.audioEl;t&&(t.addEventListener("play",()=>{this.isPlaying=!0,this.dispatchEvent(new CustomEvent("db-play",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("pause",()=>{this.isPlaying=!1,this.dispatchEvent(new CustomEvent("db-pause",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("timeupdate",()=>{this.currentTime=t.currentTime,this.duration=t.duration||0,this.dispatchEvent(new CustomEvent("db-time-update",{detail:{currentTime:this.currentTime,duration:this.duration},bubbles:!0,composed:!0})),this.updateProgress(),this.updateTime()}),t.addEventListener("volumechange",()=>{this.volume=t.volume,this.isMuted=t.muted,this.dispatchEvent(new CustomEvent("db-volume-change",{detail:{volume:this.volume},bubbles:!0,composed:!0})),this.updateVolumeUI()}),t.addEventListener("ended",()=>this.handleEnded()),t.addEventListener("error",()=>{this.error="오디오를 재생할 수 없습니다.",this.dispatchEvent(new CustomEvent("db-error",{detail:{error:this.error},bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("loadstart",()=>{this.isLoading=!0,this.error=null,this.updateUI()}),t.addEventListener("canplay",()=>{this.isLoading=!1,this.updateUI()}))}handleEnded(){this.isPlaying=!1,this.dispatchEvent(new CustomEvent("db-ended",{bubbles:!0,composed:!0}));const t=this.getPlaylist();if(t.length>0){if("one"===this.currentRepeatMode)this.audioEl&&(this.audioEl.currentTime=0,this.audioEl.play());else if("all"===this.currentRepeatMode||this.playlistIndex<t.length-1){const e=this.playlistIndex+1;e<t.length?this.setPlaylistIndex(e):"all"===this.currentRepeatMode&&this.setPlaylistIndex(0)}}else this.getBool("loop")&&this.audioEl&&(this.audioEl.currentTime=0,this.audioEl.play());this.updateUI()}setPlaylistIndex(t){this.playlistIndex=t,this.dispatchEvent(new CustomEvent("db-playlist-change",{detail:{index:t},bubbles:!0,composed:!0})),this.loadCurrentTrack(),this.audioEl&&this.audioEl.play()}togglePlay(){this.audioEl&&(this.isPlaying?this.audioEl.pause():this.audioEl.play())}toggleMute(){this.audioEl&&(this.audioEl.muted=!this.isMuted)}toggleRepeatMode(){const t=["none","one","all"],e=t[(t.indexOf(this.currentRepeatMode)+1)%t.length];this.currentRepeatMode=e,this.dispatchEvent(new CustomEvent("db-repeat-mode-change",{detail:{mode:e},bubbles:!0,composed:!0})),this.updateUI()}toggleShuffle(){this.isShuffle=!this.isShuffle,this.refreshShuffledPlaylist(),this.dispatchEvent(new CustomEvent("db-shuffle-change",{detail:{shuffle:this.isShuffle},bubbles:!0,composed:!0})),this.updateUI()}handlePlaybackRateChange(t){this.audioEl&&(this.audioEl.playbackRate=t,this.playbackRate=t,this.dispatchEvent(new CustomEvent("db-playback-rate-change",{detail:{rate:t},bubbles:!0,composed:!0})))}handleKeyDown(t){if(this.audioEl&&this.getBool("enable-keyboard",!0))switch(t.code){case"Space":t.preventDefault(),this.togglePlay();break;case"ArrowLeft":t.preventDefault(),this.audioEl.currentTime=Math.max(0,this.currentTime-10);break;case"ArrowRight":t.preventDefault(),this.audioEl.currentTime=Math.min(this.duration,this.currentTime+10);break;case"ArrowUp":t.preventDefault(),this.audioEl.volume=Math.min(1,this.volume+.1),this.audioEl.muted=!1;break;case"ArrowDown":t.preventDefault(),this.audioEl.volume=Math.max(0,this.volume-.1),this.audioEl.muted=0===this.audioEl.volume;break;case"KeyM":t.preventDefault(),this.toggleMute();break;case"KeyR":t.preventDefault(),this.toggleRepeatMode();break;case"KeyS":t.preventDefault(),this.toggleShuffle()}}iconButton(s,i,l){const a=document.createElement("button");return a.type="button",a.className=`${e}__control-button`,a.append(t(s,this.getIconSize())),l?.disabled&&(a.disabled=!0),l?.data&&Object.entries(l.data).forEach(([t,e])=>a.setAttribute(`data-${t}`,e)),a.addEventListener("click",i),a}build(){const t=this.getAttribute("size")||"m",s=this.getAttribute("variant")||"default",i=this.getAttribute("theme")||"auto";this.className=[e,`${e}--size-${t}`,`${e}--variant-${s}`,`${e}--theme-${i}`].join(" "),this.audioEl=document.createElement("audio"),this.audioEl.preload="metadata",this.audioEl.hidden=!0;const l=document.createElement("div");l.className=`${e}__loading`;const a=document.createElement("div");a.className=`${e}__spinner`,l.append(a);const n=document.createElement("div");n.className=`${e}__error`;const o=document.createElement("p");o.textContent="오디오를 재생할 수 없습니다.";const r=document.createElement("button");r.type="button",r.textContent="다시 시도",r.addEventListener("click",()=>window.location.reload()),n.append(o,r);const h=document.createElement("div");h.className=`${e}__album-art`,this.albumImgEl=document.createElement("img"),this.albumImgEl.addEventListener("error",()=>{this.albumImgEl&&(this.albumImgEl.style.display="none"),this.albumPlaceholderEl?.classList.remove("album-placeholder")}),this.albumPlaceholderEl=document.createElement("div"),this.albumPlaceholderEl.className="album-placeholder",this.albumPlaceholderEl.textContent="🎵",h.append(this.albumImgEl,this.albumPlaceholderEl);const u=document.createElement("div");u.className=`${e}__main`;const d=document.createElement("div");d.className=`${e}__info`,this.titleEl=document.createElement("div"),this.titleEl.className=`${e}__title`,this.artistEl=document.createElement("div"),this.artistEl.className=`${e}__artist`,this.albumEl=document.createElement("div"),this.albumEl.className=`${e}__album`,d.append(this.titleEl,this.artistEl,this.albumEl),this.progressEl=document.createElement("div"),this.progressEl.className=`${e}__progress`,this.progressBarEl=document.createElement("div"),this.progressBarEl.className=`${e}__progress-bar`,this.progressHandleEl=document.createElement("div"),this.progressHandleEl.className=`${e}__progress-handle`,this.progressEl.append(this.progressBarEl,this.progressHandleEl),this.progressEl.addEventListener("click",t=>{if(!this.audioEl||!this.progressEl)return;const e=this.progressEl.getBoundingClientRect(),s=(t.clientX-e.left)/e.width;this.audioEl.currentTime=s*(this.duration||0)});const c=document.createElement("div");c.className=`${e}__controls`;const m=document.createElement("div");m.className=`${e}__left-controls`;const p=document.createElement("div");p.className=`${e}__center-controls`;const E=document.createElement("div");E.className=`${e}__right-controls`,this.playButtonEl=document.createElement("button"),this.playButtonEl.type="button",this.playButtonEl.className=`${e}__play-button`,this.playButtonEl.addEventListener("click",()=>this.togglePlay()),p.append(this.playButtonEl),c.append(m,p,E);const g=document.createElement("div");g.className=`${e}__bottom-controls`;const b=document.createElement("div");b.className=`${e}__left-bottom`;const y=document.createElement("div");y.className=`${e}__right-bottom`;const v=document.createElement("div");v.className=`${e}__time`,this.timeCurrentEl=document.createElement("span");const f=document.createElement("span");f.textContent="/",this.timeDurationEl=document.createElement("span"),v.append(this.timeCurrentEl,f,this.timeDurationEl),b.append(v);const _=document.createElement("div");_.className=`${e}__volume`;const k=this.iconButton(this.isMuted||0===this.volume?"mute-filled":"volume-up",()=>this.toggleMute());k.title=this.isMuted||0===this.volume?"음소거 해제":"음소거";const C=document.createElement("div");C.className=`${e}__volume-slider`;const I=document.createElement("div");I.className="volume-label";const $=document.createElement("span");$.textContent="🔊";const P=document.createElement("span");I.append($,P),this.volumeInputEl=document.createElement("input"),this.volumeInputEl.type="range",this.volumeInputEl.min="0",this.volumeInputEl.max="1",this.volumeInputEl.step="0.1",this.volumeInputEl.addEventListener("input",()=>{if(!this.audioEl||!this.volumeInputEl)return;const t=parseFloat(this.volumeInputEl.value);this.audioEl.volume=t,this.audioEl.muted=0===t}),C.append(I,this.volumeInputEl),_.append(k,C);const A=document.createElement("div");A.className=`${e}__settings`;const x=this.iconButton("settings",()=>{this.showSettingsMenu=!this.showSettingsMenu,this.updateSettingsMenu()});this.settingsMenuEl=document.createElement("div"),this.settingsMenuEl.className=`${e}__settings-menu`,this.settingsMenuEl.hidden=!0;const M=document.createElement("div");M.className=`${e}__setting-group`;const w=document.createElement("label");w.textContent="재생 속도";const B=document.createElement("select");B.addEventListener("change",()=>this.handlePlaybackRateChange(parseFloat(B.value))),M.append(w,B),this.settingsMenuEl.append(M),A.append(x,this.settingsMenuEl),y.append(_,A),g.append(b,y),u.append(d,this.progressEl,c,g);const N=document.createElement("div");N.className=`${e}__playlist`,N.hidden=!0;const T=document.createElement("h4");T.textContent="플레이리스트",this.playlistTracksEl=document.createElement("div"),this.playlistTracksEl.className=`${e}__playlist-tracks`,N.append(T,this.playlistTracksEl),this.append(this.audioEl,l,n,h,u,N),this._leftControls=m,this._rightControls=E,this._controls=c,this._time=v,this._volumeWrap=_,this._settings=A,this._playlist=N,this._rateSelect=B,this._volumePercent=P,this._muteButton=k}get leftControls(){return this._leftControls}get rightControls(){return this._rightControls}get controlsEl(){return this._controls}get timeEl(){return this._time}get volumeWrap(){return this._volumeWrap}get settingsEl(){return this._settings}get playlistEl(){return this._playlist}get rateSelect(){return this._rateSelect}get volumePercent(){return this._volumePercent}get muteButton(){return this._muteButton}updateTrackInfo(){const t=this.getCurrentTrack();this.titleEl&&(this.titleEl.textContent=t?.title||"Unknown Track"),this.artistEl&&(this.artistEl.textContent=t?.artist||"Unknown Artist"),this.albumEl&&(t?.album?(this.albumEl.textContent=t.album,this.albumEl.hidden=!1):this.albumEl.hidden=!0),this.albumImgEl&&this.albumPlaceholderEl&&(t?.albumArt?(this.albumImgEl.src=t.albumArt,this.albumImgEl.alt=t.title||"Album Art",this.albumImgEl.style.display=""):(this.albumImgEl.removeAttribute("src"),this.albumImgEl.style.display="none"),this.albumPlaceholderEl.className="album-placeholder")}updateProgress(){const t=this.duration>0?this.currentTime/this.duration*100:0;this.progressBarEl&&(this.progressBarEl.style.width=`${t}%`),this.progressHandleEl&&(this.progressHandleEl.style.left=`${t}%`,this.progressHandleEl.style.transform=t<=0?"translate(0, -50%)":t>=100?"translate(-100%, -50%)":"translate(-50%, -50%)")}updateTime(){this.timeCurrentEl&&(this.timeCurrentEl.textContent=this.formatTime(this.currentTime)),this.timeDurationEl&&(this.timeDurationEl.textContent=this.formatTime(this.duration))}updateVolumeUI(){this.volumeInputEl&&(this.volumeInputEl.value=String(this.volume)),this.volumePercent&&(this.volumePercent.textContent=`${Math.round(100*this.volume)}%`),this.muteButton&&(this.muteButton.replaceChildren(t(this.isMuted||0===this.volume?"mute-filled":"volume-up",this.getIconSize())),this.muteButton.title=this.isMuted||0===this.volume?"음소거 해제":"음소거")}updateSettingsMenu(){this.settingsMenuEl&&(this.settingsMenuEl.hidden=!this.showSettingsMenu)}rebuildControlButtons(){const e=this.getPlaylist(),s=1.2*this.getIconSize();this.leftControls.replaceChildren(),this.rightControls.replaceChildren(),e.length>0&&this.leftControls.append(this.iconButton("refresh",()=>this.toggleShuffle(),{data:{shuffle:"true"}})),this.leftControls.append(this.iconButton("chevron-left",()=>{if(e.length>0){const t=this.playlistIndex-1;t>=0&&this.setPlaylistIndex(t)}else this.audioEl&&(this.audioEl.currentTime=0)},{disabled:e.length>0&&0===this.playlistIndex})),this.playButtonEl&&this.playButtonEl.replaceChildren(t(this.isPlaying?"pause":"play",s)),this.rightControls.append(this.iconButton("chevron-right",()=>{if(e.length>0){const t=this.playlistIndex+1;t<e.length&&this.setPlaylistIndex(t)}},{disabled:e.length>0&&this.playlistIndex===e.length-1})),e.length>0&&this.rightControls.append(this.iconButton("repeat",()=>this.toggleRepeatMode(),{data:{repeat:"true"}}))}rebuildPlaylist(){if(!this.playlistTracksEl)return;const t=this.getPlaylist(),s=this.getAttribute("variant")||"default";this.playlistEl.hidden=!("full"===s&&t.length>0),this.playlistTracksEl.replaceChildren(),t.forEach((t,s)=>{const i=document.createElement("div");if(i.className=`${e}__playlist-track${s===this.playlistIndex?` ${e}__playlist-track--active`:""}`,i.addEventListener("click",()=>this.setPlaylistIndex(s)),t.albumArt){const e=document.createElement("img");e.src=t.albumArt,e.alt=t.title||"Album Art",i.append(e)}const l=document.createElement("div");l.className=`${e}__playlist-track-info`;const a=document.createElement("div");a.className=`${e}__playlist-track-title`,a.textContent=t.title||"Unknown Track";const n=document.createElement("div");n.className=`${e}__playlist-track-artist`,n.textContent=t.artist||"Unknown Artist",l.append(a,n),i.append(l),this.playlistTracksEl?.append(i)})}updatePlaylistActive(){this.playlistTracksEl&&Array.from(this.playlistTracksEl.children).forEach((t,s)=>{t.classList.toggle(`${e}__playlist-track--active`,s===this.playlistIndex)})}updateUI(){const t=this.getAttribute("size")||"m",s=this.getAttribute("variant")||"default",i=this.getAttribute("theme")||"auto",l=this.getBool("show-controls",!0),a=this.getBool("show-progress",!0),n=this.getBool("show-time",!0),o=this.getBool("show-volume",!0),r=this.getBool("show-settings",!1);this.className=[e,`${e}--size-${t}`,`${e}--variant-${s}`,`${e}--theme-${i}`,this.isPlaying&&`${e}--playing`,!this.isPlaying&&`${e}--paused`,this.isMuted&&`${e}--muted`,this.isLoading&&`${e}--loading`,this.error&&`${e}--error`,this.isShuffle&&`${e}--shuffle`,`${e}--repeat-${this.currentRepeatMode}`].filter(Boolean).join(" "),this.audioEl&&(this.audioEl.autoplay=this.getBool("auto-play"),this.audioEl.loop=this.getBool("loop"),this.audioEl.muted=this.getBool("muted"),this.audioEl.playbackRate=this.playbackRate),this.progressEl&&(this.progressEl.hidden=!a),this.controlsEl&&(this.controlsEl.hidden=!l),this.timeEl&&(this.timeEl.hidden=!n),this.volumeWrap&&(this.volumeWrap.hidden=!o),this.settingsEl&&(this.settingsEl.hidden=!r),this.rateSelect.replaceChildren(...this.getPlaybackRates().map(t=>{const e=document.createElement("option");return e.value=String(t),e.textContent=`${t}x`,t===this.playbackRate&&(e.selected=!0),e})),this.rebuildControlButtons(),this.updateTrackInfo(),this.updateProgress(),this.updateTime(),this.updateVolumeUI(),this.updateSettingsMenu(),this.rebuildPlaylist()}}customElements.get("db-audio-player")||customElements.define("db-audio-player",DbAudioPlayer);export{DbAudioPlayer};
1
+ import{createDbIcon as t}from"./db-icons.js";import{t as e}from"../core/i18n.js";const s="designbase-wc-audio-player";class DbAudioPlayer extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.isPlaying=!1,this.isMuted=!1,this.volume=1,this.currentTime=0,this.duration=0,this.showSettingsMenu=!1,this.playbackRate=1,this.currentRepeatMode="none",this.isShuffle=!1,this.isLoading=!1,this.error=null,this.playlistIndex=0,this.shuffledPlaylist=[],this.boundKeyDown=t=>this.handleKeyDown(t)}static get observedAttributes(){return["src","title","artist","album","album-art","size","variant","theme","auto-play","loop","muted","show-controls","enable-keyboard","show-progress","show-time","show-volume","show-settings","playlist","current-index","playback-rates","default-playback-rate","repeat-mode","shuffle"]}connectedCallback(){this.style.display="block",this.built||(this.built=!0,this.build(),this.bindAudioEvents()),this.syncFromAttributes(),this.updateUI(),this.getBool("enable-keyboard",!0)&&document.addEventListener("keydown",this.boundKeyDown)}disconnectedCallback(){document.removeEventListener("keydown",this.boundKeyDown)}attributeChangedCallback(t){if(this.built){if("current-index"===t)return this.playlistIndex=Number(this.getAttribute("current-index")||0),void this.loadCurrentTrack();"repeat-mode"===t&&(this.currentRepeatMode=this.getAttribute("repeat-mode")||"none"),"shuffle"===t&&(this.isShuffle=this.getBool("shuffle"),this.refreshShuffledPlaylist()),"default-playback-rate"===t&&(this.playbackRate=Number(this.getAttribute("default-playback-rate")||1),this.audioEl&&(this.audioEl.playbackRate=this.playbackRate)),this.updateUI()}}getBool(t,e=!1){if(!this.hasAttribute(t))return e;const s=this.getAttribute(t);return""===s||"true"===s}getPlaylist(){try{const t=this.getAttribute("playlist"),e=t?JSON.parse(t):[];return Array.isArray(e)?e:[]}catch{return[]}}getPlaybackRates(){try{const t=this.getAttribute("playback-rates"),e=t?JSON.parse(t):[.5,.75,1,1.25,1.5,2];return Array.isArray(e)&&e.length>0?e:[.5,.75,1,1.25,1.5,2]}catch{return[.5,.75,1,1.25,1.5,2]}}getIconSize(){const t=this.getAttribute("size")||"m";return"s"===t?16:"l"===t?24:"xl"===t?32:20}getCurrentTrack(){const t=this.getPlaylist();if(t.length>0){return t[this.isShuffle&&this.shuffledPlaylist.length>0?this.shuffledPlaylist[this.playlistIndex]??this.playlistIndex:this.playlistIndex]||t[0]}return{src:this.getAttribute("src")||"",title:this.getAttribute("title")||void 0,artist:this.getAttribute("artist")||void 0,album:this.getAttribute("album")||void 0,albumArt:this.getAttribute("album-art")||void 0}}refreshShuffledPlaylist(){const t=this.getPlaylist();if(t.length>0&&this.isShuffle){const e=Array.from({length:t.length},(t,e)=>e);this.shuffledPlaylist=[...e].sort(()=>Math.random()-.5)}else this.shuffledPlaylist=[]}formatTime(t){return`${Math.floor(t/60)}:${Math.floor(t%60).toString().padStart(2,"0")}`}syncFromAttributes(){this.playlistIndex=Number(this.getAttribute("current-index")||0),this.currentRepeatMode=this.getAttribute("repeat-mode")||"none",this.isShuffle=this.getBool("shuffle"),this.playbackRate=Number(this.getAttribute("default-playback-rate")||1),this.isMuted=this.getBool("muted"),this.volume=this.isMuted?0:1,this.refreshShuffledPlaylist(),this.loadCurrentTrack()}loadCurrentTrack(){if(!this.audioEl)return;const t=this.getCurrentTrack(),e=t?.src||this.getAttribute("src")||"";this.audioEl.src!==e&&e&&(this.audioEl.src=e,this.audioEl.load()),this.updateTrackInfo(),this.updatePlaylistActive()}bindAudioEvents(){const t=this.audioEl;t&&(t.addEventListener("play",()=>{this.isPlaying=!0,this.dispatchEvent(new CustomEvent("db-play",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("pause",()=>{this.isPlaying=!1,this.dispatchEvent(new CustomEvent("db-pause",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("timeupdate",()=>{this.currentTime=t.currentTime,this.duration=t.duration||0,this.dispatchEvent(new CustomEvent("db-time-update",{detail:{currentTime:this.currentTime,duration:this.duration},bubbles:!0,composed:!0})),this.updateProgress(),this.updateTime()}),t.addEventListener("volumechange",()=>{this.volume=t.volume,this.isMuted=t.muted,this.dispatchEvent(new CustomEvent("db-volume-change",{detail:{volume:this.volume},bubbles:!0,composed:!0})),this.updateVolumeUI()}),t.addEventListener("ended",()=>this.handleEnded()),t.addEventListener("error",()=>{this.error="오디오를 재생할 수 없습니다.",this.dispatchEvent(new CustomEvent("db-error",{detail:{error:this.error},bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("loadstart",()=>{this.isLoading=!0,this.error=null,this.updateUI()}),t.addEventListener("canplay",()=>{this.isLoading=!1,this.updateUI()}))}handleEnded(){this.isPlaying=!1,this.dispatchEvent(new CustomEvent("db-ended",{bubbles:!0,composed:!0}));const t=this.getPlaylist();if(t.length>0){if("one"===this.currentRepeatMode)this.audioEl&&(this.audioEl.currentTime=0,this.audioEl.play());else if("all"===this.currentRepeatMode||this.playlistIndex<t.length-1){const e=this.playlistIndex+1;e<t.length?this.setPlaylistIndex(e):"all"===this.currentRepeatMode&&this.setPlaylistIndex(0)}}else this.getBool("loop")&&this.audioEl&&(this.audioEl.currentTime=0,this.audioEl.play());this.updateUI()}setPlaylistIndex(t){this.playlistIndex=t,this.dispatchEvent(new CustomEvent("db-playlist-change",{detail:{index:t},bubbles:!0,composed:!0})),this.loadCurrentTrack(),this.audioEl&&this.audioEl.play()}togglePlay(){this.audioEl&&(this.isPlaying?this.audioEl.pause():this.audioEl.play())}toggleMute(){this.audioEl&&(this.audioEl.muted=!this.isMuted)}toggleRepeatMode(){const t=["none","one","all"],e=t[(t.indexOf(this.currentRepeatMode)+1)%t.length];this.currentRepeatMode=e,this.dispatchEvent(new CustomEvent("db-repeat-mode-change",{detail:{mode:e},bubbles:!0,composed:!0})),this.updateUI()}toggleShuffle(){this.isShuffle=!this.isShuffle,this.refreshShuffledPlaylist(),this.dispatchEvent(new CustomEvent("db-shuffle-change",{detail:{shuffle:this.isShuffle},bubbles:!0,composed:!0})),this.updateUI()}handlePlaybackRateChange(t){this.audioEl&&(this.audioEl.playbackRate=t,this.playbackRate=t,this.dispatchEvent(new CustomEvent("db-playback-rate-change",{detail:{rate:t},bubbles:!0,composed:!0})))}handleKeyDown(t){if(this.audioEl&&this.getBool("enable-keyboard",!0))switch(t.code){case"Space":t.preventDefault(),this.togglePlay();break;case"ArrowLeft":t.preventDefault(),this.audioEl.currentTime=Math.max(0,this.currentTime-10);break;case"ArrowRight":t.preventDefault(),this.audioEl.currentTime=Math.min(this.duration,this.currentTime+10);break;case"ArrowUp":t.preventDefault(),this.audioEl.volume=Math.min(1,this.volume+.1),this.audioEl.muted=!1;break;case"ArrowDown":t.preventDefault(),this.audioEl.volume=Math.max(0,this.volume-.1),this.audioEl.muted=0===this.audioEl.volume;break;case"KeyM":t.preventDefault(),this.toggleMute();break;case"KeyR":t.preventDefault(),this.toggleRepeatMode();break;case"KeyS":t.preventDefault(),this.toggleShuffle()}}iconButton(e,i,l,a){const n=document.createElement("button");return n.type="button",n.className=`${s}__control-button`,n.setAttribute("aria-label",i),n.append(t(e,this.getIconSize())),a?.disabled&&(n.disabled=!0),a?.data&&Object.entries(a.data).forEach(([t,e])=>n.setAttribute(`data-${t}`,e)),n.addEventListener("click",l),n}build(){const t=this.getAttribute("size")||"m",i=this.getAttribute("variant")||"default",l=this.getAttribute("theme")||"auto";this.className=[s,`${s}--size-${t}`,`${s}--variant-${i}`,`${s}--theme-${l}`].join(" "),this.audioEl=document.createElement("audio"),this.audioEl.preload="metadata",this.audioEl.hidden=!0;const a=document.createElement("div");a.className=`${s}__loading`;const n=document.createElement("div");n.className=`${s}__spinner`,a.append(n);const o=document.createElement("div");o.className=`${s}__error`;const r=document.createElement("p");r.textContent="오디오를 재생할 수 없습니다.";const h=document.createElement("button");h.type="button",h.textContent="다시 시도",h.addEventListener("click",()=>window.location.reload()),o.append(r,h);const u=document.createElement("div");u.className=`${s}__album-art`,this.albumImgEl=document.createElement("img"),this.albumImgEl.addEventListener("error",()=>{this.albumImgEl&&(this.albumImgEl.style.display="none"),this.albumPlaceholderEl?.classList.remove("album-placeholder")}),this.albumPlaceholderEl=document.createElement("div"),this.albumPlaceholderEl.className="album-placeholder",this.albumPlaceholderEl.textContent="🎵",u.append(this.albumImgEl,this.albumPlaceholderEl);const d=document.createElement("div");d.className=`${s}__main`;const c=document.createElement("div");c.className=`${s}__info`,this.titleEl=document.createElement("div"),this.titleEl.className=`${s}__title`,this.artistEl=document.createElement("div"),this.artistEl.className=`${s}__artist`,this.albumEl=document.createElement("div"),this.albumEl.className=`${s}__album`,c.append(this.titleEl,this.artistEl,this.albumEl),this.progressEl=document.createElement("div"),this.progressEl.className=`${s}__progress`,this.progressBarEl=document.createElement("div"),this.progressBarEl.className=`${s}__progress-bar`,this.progressHandleEl=document.createElement("div"),this.progressHandleEl.className=`${s}__progress-handle`,this.progressEl.append(this.progressBarEl,this.progressHandleEl),this.progressEl.addEventListener("click",t=>{if(!this.audioEl||!this.progressEl)return;const e=this.progressEl.getBoundingClientRect(),s=(t.clientX-e.left)/e.width;this.audioEl.currentTime=s*(this.duration||0)});const m=document.createElement("div");m.className=`${s}__controls`;const p=document.createElement("div");p.className=`${s}__left-controls`;const E=document.createElement("div");E.className=`${s}__center-controls`;const g=document.createElement("div");g.className=`${s}__right-controls`,this.playButtonEl=document.createElement("button"),this.playButtonEl.type="button",this.playButtonEl.className=`${s}__play-button`,this.playButtonEl.addEventListener("click",()=>this.togglePlay()),E.append(this.playButtonEl),m.append(p,E,g);const b=document.createElement("div");b.className=`${s}__bottom-controls`;const y=document.createElement("div");y.className=`${s}__left-bottom`;const v=document.createElement("div");v.className=`${s}__right-bottom`;const f=document.createElement("div");f.className=`${s}__time`,this.timeCurrentEl=document.createElement("span");const _=document.createElement("span");_.textContent="/",this.timeDurationEl=document.createElement("span"),f.append(this.timeCurrentEl,_,this.timeDurationEl),y.append(f);const k=document.createElement("div");k.className=`${s}__volume`;const C=this.iconButton(this.isMuted||0===this.volume?"mute-filled":"volume-up",this.isMuted||0===this.volume?e("media.unmute"):e("media.mute"),()=>this.toggleMute());C.title=this.isMuted||0===this.volume?"음소거 해제":"음소거";const I=document.createElement("div");I.className=`${s}__volume-slider`;const $=document.createElement("div");$.className="volume-label";const A=document.createElement("span");A.textContent="🔊";const P=document.createElement("span");$.append(A,P),this.volumeInputEl=document.createElement("input"),this.volumeInputEl.type="range",this.volumeInputEl.min="0",this.volumeInputEl.max="1",this.volumeInputEl.step="0.1",this.volumeInputEl.addEventListener("input",()=>{if(!this.audioEl||!this.volumeInputEl)return;const t=parseFloat(this.volumeInputEl.value);this.audioEl.volume=t,this.audioEl.muted=0===t}),I.append($,this.volumeInputEl),k.append(C,I);const x=document.createElement("div");x.className=`${s}__settings`;const M=this.iconButton("settings",e("media.settings"),()=>{this.showSettingsMenu=!this.showSettingsMenu,this.updateSettingsMenu()});this.settingsMenuEl=document.createElement("div"),this.settingsMenuEl.className=`${s}__settings-menu`,this.settingsMenuEl.hidden=!0;const w=document.createElement("div");w.className=`${s}__setting-group`;const B=document.createElement("label");B.textContent="재생 속도";const N=document.createElement("select");N.addEventListener("change",()=>this.handlePlaybackRateChange(parseFloat(N.value))),w.append(B,N),this.settingsMenuEl.append(w),x.append(M,this.settingsMenuEl),v.append(k,x),b.append(y,v),d.append(c,this.progressEl,m,b);const T=document.createElement("div");T.className=`${s}__playlist`,T.hidden=!0;const S=document.createElement("h4");S.textContent="플레이리스트",this.playlistTracksEl=document.createElement("div"),this.playlistTracksEl.className=`${s}__playlist-tracks`,T.append(S,this.playlistTracksEl),this.append(this.audioEl,a,o,u,d,T),this._leftControls=p,this._rightControls=g,this._controls=m,this._time=f,this._volumeWrap=k,this._settings=x,this._playlist=T,this._rateSelect=N,this._volumePercent=P,this._muteButton=C}get leftControls(){return this._leftControls}get rightControls(){return this._rightControls}get controlsEl(){return this._controls}get timeEl(){return this._time}get volumeWrap(){return this._volumeWrap}get settingsEl(){return this._settings}get playlistEl(){return this._playlist}get rateSelect(){return this._rateSelect}get volumePercent(){return this._volumePercent}get muteButton(){return this._muteButton}updateTrackInfo(){const t=this.getCurrentTrack();this.titleEl&&(this.titleEl.textContent=t?.title||"Unknown Track"),this.artistEl&&(this.artistEl.textContent=t?.artist||"Unknown Artist"),this.albumEl&&(t?.album?(this.albumEl.textContent=t.album,this.albumEl.hidden=!1):this.albumEl.hidden=!0),this.albumImgEl&&this.albumPlaceholderEl&&(t?.albumArt?(this.albumImgEl.src=t.albumArt,this.albumImgEl.alt=t.title||"Album Art",this.albumImgEl.style.display=""):(this.albumImgEl.removeAttribute("src"),this.albumImgEl.style.display="none"),this.albumPlaceholderEl.className="album-placeholder")}updateProgress(){const t=this.duration>0?this.currentTime/this.duration*100:0;this.progressBarEl&&(this.progressBarEl.style.width=`${t}%`),this.progressHandleEl&&(this.progressHandleEl.style.left=`${t}%`,this.progressHandleEl.style.transform=t<=0?"translate(0, -50%)":t>=100?"translate(-100%, -50%)":"translate(-50%, -50%)")}updateTime(){this.timeCurrentEl&&(this.timeCurrentEl.textContent=this.formatTime(this.currentTime)),this.timeDurationEl&&(this.timeDurationEl.textContent=this.formatTime(this.duration))}updateVolumeUI(){this.volumeInputEl&&(this.volumeInputEl.value=String(this.volume)),this.volumePercent&&(this.volumePercent.textContent=`${Math.round(100*this.volume)}%`),this.muteButton&&(this.muteButton.replaceChildren(t(this.isMuted||0===this.volume?"mute-filled":"volume-up",this.getIconSize())),this.muteButton.title=this.isMuted||0===this.volume?"음소거 해제":"음소거")}updateSettingsMenu(){this.settingsMenuEl&&(this.settingsMenuEl.hidden=!this.showSettingsMenu)}rebuildControlButtons(){const s=this.getPlaylist(),i=1.2*this.getIconSize();this.leftControls.replaceChildren(),this.rightControls.replaceChildren(),s.length>0&&this.leftControls.append(this.iconButton("refresh",e("media.shuffle"),()=>this.toggleShuffle(),{data:{shuffle:"true"}})),this.leftControls.append(this.iconButton("chevron-left",e("media.previous"),()=>{if(s.length>0){const t=this.playlistIndex-1;t>=0&&this.setPlaylistIndex(t)}else this.audioEl&&(this.audioEl.currentTime=0)},{disabled:s.length>0&&0===this.playlistIndex})),this.playButtonEl&&this.playButtonEl.replaceChildren(t(this.isPlaying?"pause":"play",i)),this.rightControls.append(this.iconButton("chevron-right",e("media.next"),()=>{if(s.length>0){const t=this.playlistIndex+1;t<s.length&&this.setPlaylistIndex(t)}},{disabled:s.length>0&&this.playlistIndex===s.length-1})),s.length>0&&this.rightControls.append(this.iconButton("repeat",e("media.repeat"),()=>this.toggleRepeatMode(),{data:{repeat:"true"}}))}rebuildPlaylist(){if(!this.playlistTracksEl)return;const t=this.getPlaylist(),e=this.getAttribute("variant")||"default";this.playlistEl.hidden=!("full"===e&&t.length>0),this.playlistTracksEl.replaceChildren(),t.forEach((t,e)=>{const i=document.createElement("div");if(i.className=`${s}__playlist-track${e===this.playlistIndex?` ${s}__playlist-track--active`:""}`,i.addEventListener("click",()=>this.setPlaylistIndex(e)),t.albumArt){const e=document.createElement("img");e.src=t.albumArt,e.alt=t.title||"Album Art",i.append(e)}const l=document.createElement("div");l.className=`${s}__playlist-track-info`;const a=document.createElement("div");a.className=`${s}__playlist-track-title`,a.textContent=t.title||"Unknown Track";const n=document.createElement("div");n.className=`${s}__playlist-track-artist`,n.textContent=t.artist||"Unknown Artist",l.append(a,n),i.append(l),this.playlistTracksEl?.append(i)})}updatePlaylistActive(){this.playlistTracksEl&&Array.from(this.playlistTracksEl.children).forEach((t,e)=>{t.classList.toggle(`${s}__playlist-track--active`,e===this.playlistIndex)})}updateUI(){const t=this.getAttribute("size")||"m",e=this.getAttribute("variant")||"default",i=this.getAttribute("theme")||"auto",l=this.getBool("show-controls",!0),a=this.getBool("show-progress",!0),n=this.getBool("show-time",!0),o=this.getBool("show-volume",!0),r=this.getBool("show-settings",!1);this.className=[s,`${s}--size-${t}`,`${s}--variant-${e}`,`${s}--theme-${i}`,this.isPlaying&&`${s}--playing`,!this.isPlaying&&`${s}--paused`,this.isMuted&&`${s}--muted`,this.isLoading&&`${s}--loading`,this.error&&`${s}--error`,this.isShuffle&&`${s}--shuffle`,`${s}--repeat-${this.currentRepeatMode}`].filter(Boolean).join(" "),this.audioEl&&(this.audioEl.autoplay=this.getBool("auto-play"),this.audioEl.loop=this.getBool("loop"),this.audioEl.muted=this.getBool("muted"),this.audioEl.playbackRate=this.playbackRate),this.progressEl&&(this.progressEl.hidden=!a),this.controlsEl&&(this.controlsEl.hidden=!l),this.timeEl&&(this.timeEl.hidden=!n),this.volumeWrap&&(this.volumeWrap.hidden=!o),this.settingsEl&&(this.settingsEl.hidden=!r),this.rateSelect.replaceChildren(...this.getPlaybackRates().map(t=>{const e=document.createElement("option");return e.value=String(t),e.textContent=`${t}x`,t===this.playbackRate&&(e.selected=!0),e})),this.rebuildControlButtons(),this.updateTrackInfo(),this.updateProgress(),this.updateTime(),this.updateVolumeUI(),this.updateSettingsMenu(),this.rebuildPlaylist()}}customElements.get("db-audio-player")||customElements.define("db-audio-player",DbAudioPlayer);export{DbAudioPlayer};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e=["xs","s","m","l","xl","2xl"],a=["default","primary","success","warning","danger","info"],s=["online","offline","away","busy"],i=["#E3F2FD","#F3E5F5","#E8F5E8","#FFF3E0","#FCE4EC","#E0F2F1","#FFF8E1","#F1F8E9","#E8EAF6","#FFEBEE"],n=["#1976D2","#7B1FA2","#388E3C","#F57C00","#C2185B","#00796B","#F9A825","#689F38","#3F51B5","#D32F2F"];class DbAvatar extends HTMLElement{constructor(){super(...arguments),this.imageFailed=!1,this.imageLoaded=!1,this.handleClick=()=>{!this.hasAttribute("disabled")&&this.hasAttribute("clickable")&&this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))},this.handleKeyDown=t=>{this.hasAttribute("clickable")&&!this.hasAttribute("disabled")&&("Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.handleClick()))}}static get observedAttributes(){return["src","alt","initials","size","variant","status","disabled","clickable","badge","badge-max-count","badge-variant","badge-style","badge-text"]}connectedCallback(){this.render(),this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeyDown)}disconnectedCallback(){this.removeEventListener("click",this.handleClick),this.removeEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(t){"src"===t&&(this.imageFailed=!1,this.imageLoaded=!1),this.render()}render(){const r=e.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",d=a.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",l=this.hasAttribute("disabled"),c=this.hasAttribute("clickable"),o=this.getAttribute("src"),b=this.getAttribute("initials")||"",h=Boolean(o&&!this.imageFailed),u=h&&!this.imageLoaded;if(this.className=["designbase-wc-avatar",`designbase-wc-avatar--${r}`,`designbase-wc-avatar--${d}`,c&&"designbase-wc-avatar--clickable",l&&"designbase-wc-avatar--disabled",u&&"designbase-wc-avatar--loading"].filter(Boolean).join(" "),c&&!l?(this.setAttribute("role","button"),this.tabIndex=0):(this.removeAttribute("role"),this.removeAttribute("tabindex")),this.toggleAttribute("aria-disabled",l),this.replaceChildren(),u){const t=document.createElement("div");t.className="designbase-wc-avatar__loading";const e=document.createElement("div");e.className="designbase-wc-avatar__skeleton",t.append(e),this.append(t)}if(h){const t=document.createElement("img");t.className="designbase-wc-avatar__image",t.src=o,t.alt=this.getAttribute("alt")||"아바타 이미지",t.loading="lazy",t.addEventListener("load",()=>{this.imageLoaded=!0,this.classList.remove("designbase-wc-avatar--loading"),this.querySelector(".designbase-wc-avatar__loading")?.remove()}),t.addEventListener("error",()=>{this.imageFailed=!0,this.imageLoaded=!1,this.render()}),this.append(t)}else if(b){const t=document.createElement("div");if(t.className="designbase-wc-avatar__initials","default"===d){const e=function initialsColor(t){let e=0;for(let a=0;a<t.length;a++)e=t.charCodeAt(a)+((e<<5)-e);const a=Math.abs(e)%i.length;return{backgroundColor:i[a],color:n[a]}}(b);t.style.backgroundColor=e.backgroundColor,t.style.color=e.color}t.textContent=b.charAt(0).toUpperCase(),this.append(t)}else{const e=document.createElement("div");e.className="designbase-wc-avatar__icon",e.append(t("user",function iconSize(t){return"xs"===t?12:"s"===t?16:"m"===t?20:"l"===t?24:"xl"===t?32:40}(r))),this.append(e)}const g=this.getAttribute("status")||"";if(s.includes(g)){const t=document.createElement("span");t.className=`designbase-wc-avatar__status designbase-wc-avatar__status--${g}`,this.append(t)}if(this.hasAttribute("badge")){const t=document.createElement("div");t.className="designbase-wc-avatar__badge";const e=document.createElement("db-badge");e.setAttribute("count",this.getAttribute("badge")||"0");const a=this.getAttribute("badge-style")||"number";e.setAttribute("badge-style",a),this.hasAttribute("badge-max-count")&&e.setAttribute("max-count",this.getAttribute("badge-max-count")),e.setAttribute("variant",this.getAttribute("badge-variant")||"danger"),this.hasAttribute("badge-text")&&(e.textContent=this.getAttribute("badge-text"));const s="xl"===r||"2xl"===r?"m":"s";e.setAttribute("size",s),t.append(e),this.append(t)}}}customElements.get("db-avatar")||customElements.define("db-avatar",DbAvatar);export{DbAvatar};
1
+ import{createDbIcon as t}from"./db-icons.js";import{AVATAR_SIZES as e,AVATAR_VARIANTS as a,AVATAR_STATUSES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const i=["#E3F2FD","#F3E5F5","#E8F5E8","#FFF3E0","#FCE4EC","#E0F2F1","#FFF8E1","#F1F8E9","#E8EAF6","#FFEBEE"],n=["#1976D2","#7B1FA2","#388E3C","#F57C00","#C2185B","#00796B","#F9A825","#689F38","#3F51B5","#D32F2F"];class DbAvatar extends HTMLElement{constructor(){super(...arguments),this.imageFailed=!1,this.imageLoaded=!1,this.handleClick=()=>{!this.hasAttribute("disabled")&&this.hasAttribute("clickable")&&this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))},this.handleKeyDown=t=>{this.hasAttribute("clickable")&&!this.hasAttribute("disabled")&&("Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.handleClick()))}}static get observedAttributes(){return["src","alt","initials","size","variant","status","disabled","clickable","badge","badge-max-count","badge-variant","badge-type","badge-text"]}connectedCallback(){this.render(),this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeyDown)}disconnectedCallback(){this.removeEventListener("click",this.handleClick),this.removeEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(t){"src"===t&&(this.imageFailed=!1,this.imageLoaded=!1),this.render()}render(){const r=e.includes(this.getAttribute("size")||"m")&&this.getAttribute("size")||"m",d=a.includes(this.getAttribute("variant")||"default")&&this.getAttribute("variant")||"default",c=this.hasAttribute("disabled"),l=this.hasAttribute("clickable"),o=this.getAttribute("src"),b=this.getAttribute("initials")||"",h=Boolean(o&&!this.imageFailed),u=h&&!this.imageLoaded;if(this.className=["designbase-wc-avatar",`designbase-wc-avatar--${r}`,`designbase-wc-avatar--${d}`,l&&"designbase-wc-avatar--clickable",c&&"designbase-wc-avatar--disabled",u&&"designbase-wc-avatar--loading"].filter(Boolean).join(" "),l&&!c?(this.setAttribute("role","button"),this.tabIndex=0):(this.removeAttribute("role"),this.removeAttribute("tabindex")),this.toggleAttribute("aria-disabled",c),this.replaceChildren(),u){const t=document.createElement("div");t.className="designbase-wc-avatar__loading";const e=document.createElement("div");e.className="designbase-wc-avatar__skeleton",t.append(e),this.append(t)}if(h){const t=document.createElement("img");t.className="designbase-wc-avatar__image",t.src=o,t.alt=this.getAttribute("alt")||"아바타 이미지",t.loading="lazy",t.addEventListener("load",()=>{this.imageLoaded=!0,this.classList.remove("designbase-wc-avatar--loading"),this.querySelector(".designbase-wc-avatar__loading")?.remove()}),t.addEventListener("error",()=>{this.imageFailed=!0,this.imageLoaded=!1,this.render()}),this.append(t)}else if(b){const t=document.createElement("div");if(t.className="designbase-wc-avatar__initials","default"===d){const e=function initialsColor(t){let e=0;for(let a=0;a<t.length;a++)e=t.charCodeAt(a)+((e<<5)-e);const a=Math.abs(e)%i.length;return{backgroundColor:i[a],color:n[a]}}(b);t.style.backgroundColor=e.backgroundColor,t.style.color=e.color}t.textContent=b.charAt(0).toUpperCase(),this.append(t)}else{const e=document.createElement("div");e.className="designbase-wc-avatar__icon",e.append(t("user",function iconSize(t){return"xs"===t?12:"s"===t?16:"m"===t?20:"l"===t?24:"xl"===t?32:40}(r))),this.append(e)}const g=this.getAttribute("status")||"";if(s.includes(g)){const t=document.createElement("span");t.className=`designbase-wc-avatar__status designbase-wc-avatar__status--${g}`,this.append(t)}if(this.hasAttribute("badge")){const t=document.createElement("div");t.className="designbase-wc-avatar__badge";const e=document.createElement("db-badge");e.setAttribute("count",this.getAttribute("badge")||"0");const a=this.getAttribute("badge-type")||"number";e.setAttribute("type",a),this.hasAttribute("badge-max-count")&&e.setAttribute("max-count",this.getAttribute("badge-max-count")),e.setAttribute("variant",this.getAttribute("badge-variant")||"danger"),this.hasAttribute("badge-text")&&(e.textContent=this.getAttribute("badge-text"));const s="xl"===r||"2xl"===r?"m":"s";e.setAttribute("size",s),t.append(e),this.append(t)}}}customElements.get("db-avatar")||customElements.define("db-avatar",DbAvatar);export{DbAvatar};
@@ -1,6 +1,8 @@
1
1
  declare class DbBackdrop extends HTMLElement {
2
2
  static get observedAttributes(): string[];
3
3
  private portal?;
4
+ /** 참조 카운트 스크롤락을 이 인스턴스가 잡고 있는지 (PERF-GLOBAL-STATE) */
5
+ private scrollLocked;
4
6
  private keyHandler;
5
7
  get open(): boolean;
6
8
  set open(value: boolean);
@@ -14,6 +16,8 @@ declare class DbBackdrop extends HTMLElement {
14
16
  private detachListeners;
15
17
  private handlePortalClick;
16
18
  private render;
19
+ /** 잠근 적이 있을 때만 푼다 — 참조 카운트가 음수로 새지 않도록 */
20
+ private releaseScrollLock;
17
21
  }
18
22
  declare global {
19
23
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- const t=["fade","slide","zoom","none"];class DbBackdrop extends HTMLElement{constructor(){super(...arguments),this.keyHandler=null,this.handlePortalClick=t=>{t.target===this.portal&&"true"!==this.getAttribute("disable-backdrop-click")&&(this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0})))}}static get observedAttributes(){return["open","blur","opacity","blur-amount","animation","animation-duration","z-index","background-color","disable-backdrop-click","disable-escape-key-down"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}connectedCallback(){this.style.display="contents",this.syncOpenState()}disconnectedCallback(){this.detachListeners(),this.portal?.remove(),this.portal=void 0,document.body.style.overflow=""}attributeChangedCallback(){this.isConnected&&this.syncOpenState()}isOpen(){return this.open}syncOpenState(){this.isOpen()?this.render():(document.body.style.overflow="",this.detachListeners(),this.portal?.remove())}collectChildren(){return Array.from(this.children).filter(t=>!t.hasAttribute("data-wc-internal"))}attachListeners(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"true"!==this.getAttribute("disable-escape-key-down")&&(this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0})))},document.addEventListener("keydown",this.keyHandler))}detachListeners(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}render(){if(!this.isOpen())return void this.syncOpenState();const e=this.hasAttribute("blur"),s=this.getAttribute("opacity")||"0.5",i=this.getAttribute("blur-amount")||"4",r=t.includes(this.getAttribute("animation")||"fade")&&this.getAttribute("animation")||"fade",o=this.getAttribute("animation-duration")||"300",n=this.getAttribute("z-index")||"1000",a=this.getAttribute("background-color"),d=this.collectChildren();document.body.style.overflow="hidden",this.attachListeners(),this.portal||(this.portal=document.createElement("div"),this.portal.setAttribute("data-wc-internal",""),this.portal.addEventListener("click",this.handlePortalClick)),this.portal.className=["designbase-wc-backdrop",`designbase-wc-backdrop--${r}`,"designbase-wc-backdrop--open",e?"designbase-wc-backdrop--blur":""].filter(Boolean).join(" "),this.portal.setAttribute("role","presentation"),this.portal.setAttribute("aria-hidden","false"),this.portal.style.setProperty("--backdrop-opacity",s),this.portal.style.setProperty("--backdrop-blur-amount",`${i}px`),this.portal.style.setProperty("--backdrop-animation-duration",`${o}ms`),this.portal.style.setProperty("--backdrop-z-index",n),a?this.portal.style.backgroundColor=a:this.portal.style.removeProperty("background-color"),this.portal.replaceChildren(...d),this.portal.isConnected||document.body.append(this.portal)}}customElements.get("db-backdrop")||customElements.define("db-backdrop",DbBackdrop);export{DbBackdrop};
1
+ import{lockScroll as t,unlockScroll as e}from"../core/scroll-lock.js";const s=["fade","slide","zoom","none"];class DbBackdrop extends HTMLElement{constructor(){super(...arguments),this.scrollLocked=!1,this.keyHandler=null,this.handlePortalClick=t=>{t.target===this.portal&&"true"!==this.getAttribute("disable-backdrop-click")&&(this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0})))}}static get observedAttributes(){return["open","blur","opacity","blur-amount","animation","animation-duration","z-index","background-color","disable-backdrop-click","disable-escape-key-down"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}connectedCallback(){this.style.display="contents",this.syncOpenState()}disconnectedCallback(){this.detachListeners(),this.portal?.remove(),this.portal=void 0,this.releaseScrollLock()}attributeChangedCallback(){this.isConnected&&this.syncOpenState()}isOpen(){return this.open}syncOpenState(){this.isOpen()?this.render():(this.releaseScrollLock(),this.detachListeners(),this.portal?.remove())}collectChildren(){return Array.from(this.children).filter(t=>!t.hasAttribute("data-wc-internal"))}attachListeners(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"true"!==this.getAttribute("disable-escape-key-down")&&(this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0})))},document.addEventListener("keydown",this.keyHandler))}detachListeners(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}render(){if(!this.isOpen())return void this.syncOpenState();const e=this.hasAttribute("blur"),i=this.getAttribute("opacity")||"0.5",r=this.getAttribute("blur-amount")||"4",o=s.includes(this.getAttribute("animation")||"fade")&&this.getAttribute("animation")||"fade",a=this.getAttribute("animation-duration")||"300",n=this.getAttribute("z-index")||"1000",l=this.getAttribute("background-color"),c=this.collectChildren();this.scrollLocked||(t(),this.scrollLocked=!0),this.attachListeners(),this.portal||(this.portal=document.createElement("div"),this.portal.setAttribute("data-wc-internal",""),this.portal.addEventListener("click",this.handlePortalClick)),this.portal.className=["designbase-wc-backdrop",`designbase-wc-backdrop--${o}`,"designbase-wc-backdrop--open",e?"designbase-wc-backdrop--blur":""].filter(Boolean).join(" "),this.portal.setAttribute("role","presentation"),this.portal.setAttribute("aria-hidden","false"),this.portal.style.setProperty("--backdrop-opacity",i),this.portal.style.setProperty("--backdrop-blur-amount",`${r}px`),this.portal.style.setProperty("--backdrop-animation-duration",`${a}ms`),this.portal.style.setProperty("--backdrop-z-index",n),l?this.portal.style.backgroundColor=l:this.portal.style.removeProperty("background-color"),this.portal.replaceChildren(...c),this.portal.isConnected||document.body.append(this.portal)}releaseScrollLock(){this.scrollLocked&&(this.scrollLocked=!1,e())}}customElements.get("db-backdrop")||customElements.define("db-backdrop",DbBackdrop);export{DbBackdrop};
@@ -4,8 +4,8 @@ declare class DbBadge extends HTMLElement {
4
4
  set variant(value: string);
5
5
  get size(): string;
6
6
  set size(value: string);
7
- get badgeStyle(): string;
8
- set badgeStyle(value: string);
7
+ get type(): string;
8
+ set type(value: string);
9
9
  get count(): number | undefined;
10
10
  set count(value: number | undefined);
11
11
  get maxCount(): number;
@@ -1 +1 @@
1
- const t="designbase-wc-badge",e=["primary","secondary","info","success","warning","danger"],s=["s","m","l"],i=["dot","number","text","outlined"];class DbBadge extends HTMLElement{static get observedAttributes(){return["variant","size","badge-style","count","max-count","disabled"]}get variant(){return this.getAttribute("variant")||"primary"}set variant(t){this.setAttribute("variant",t)}get size(){return this.getAttribute("size")||"m"}set size(t){this.setAttribute("size",t)}get badgeStyle(){return this.getAttribute("badge-style")||"text"}set badgeStyle(t){this.setAttribute("badge-style",t)}get count(){const t=this.getAttribute("count");return null===t?void 0:Number(t)}set count(t){void 0===t?this.removeAttribute("count"):this.setAttribute("count",String(t))}get maxCount(){return Number(this.getAttribute("max-count")||99)}set maxCount(t){this.setAttribute("max-count",String(t))}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}connectedCallback(){this.syncAttributes()}attributeChangedCallback(t,e,s){"count"!==t&&"max-count"!==t&&"badge-style"!==t||this.syncContent(),this.syncAttributes()}syncAttributes(){this.classList.add(t),this.setAttribute("aria-disabled",String(this.disabled)),this.syncEnum("variant",this.variant,e),this.syncEnum("size",this.size,s),this.syncEnum("style",this.badgeStyle,i),this.classList.toggle(`${t}--disabled`,this.disabled),this.syncContent()}syncContent(){"number"!==this.badgeStyle||void 0===this.count?"dot"===this.badgeStyle&&(this.textContent=""):this.textContent=this.count>this.maxCount?`${this.maxCount}+`:String(this.count)}syncEnum(e,s,i){i.forEach(e=>this.classList.remove(`${t}--${e}`)),i.includes(s)?this.classList.add(`${t}--${s}`):"style"===e&&this.classList.add(`${t}--text`)}}customElements.get("db-badge")||customElements.define("db-badge",DbBadge);export{DbBadge};
1
+ import{BADGE_VARIANTS as t,BADGE_SIZES as e,BADGE_TYPES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const i="designbase-wc-badge";class DbBadge extends HTMLElement{static get observedAttributes(){return["variant","size","type","count","max-count","disabled"]}get variant(){return this.getAttribute("variant")||"primary"}set variant(t){this.setAttribute("variant",t)}get size(){return this.getAttribute("size")||"m"}set size(t){this.setAttribute("size",t)}get type(){return this.getAttribute("type")||"text"}set type(t){this.setAttribute("type",t)}get count(){const t=this.getAttribute("count");return null===t?void 0:Number(t)}set count(t){void 0===t?this.removeAttribute("count"):this.setAttribute("count",String(t))}get maxCount(){return Number(this.getAttribute("max-count")||99)}set maxCount(t){this.setAttribute("max-count",String(t))}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}connectedCallback(){this.syncAttributes()}attributeChangedCallback(t,e,s){"count"!==t&&"max-count"!==t&&"type"!==t||this.syncContent(),this.syncAttributes()}syncAttributes(){this.classList.add(i),this.setAttribute("aria-disabled",String(this.disabled)),this.syncEnum("variant",this.variant,t),this.syncEnum("size",this.size,e),this.syncEnum("type",this.type,s),this.classList.toggle(`${i}--disabled`,this.disabled),this.syncContent()}syncContent(){"number"!==this.type||void 0===this.count?"dot"===this.type&&(this.textContent=""):this.textContent=this.count>this.maxCount?`${this.maxCount}+`:String(this.count)}syncEnum(t,e,s){s.forEach(t=>this.classList.remove(`${i}--${t}`)),s.includes(e)?this.classList.add(`${i}--${e}`):"type"===t&&this.classList.add(`${i}--text`)}}customElements.get("db-badge")||customElements.define("db-badge",DbBadge);export{DbBadge};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e=["s","m","l"],i=["default","glass","transparent"];class DbBottomNavigation extends HTMLElement{static get observedAttributes(){return["items","active-item-id","size","background-color","fixed"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}get items(){return this.parseItems()}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}parseItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}iconSize(t){return"s"===t?20:"l"===t?28:24}syncHostClasses(){const t=this.getAttribute("size")||"m",a=e.includes(t)?t:"m",n=this.getAttribute("background-color")||"default",s=i.includes(n)?n:"default";this.className=["designbase-wc-bottom-navigation",`designbase-wc-bottom-navigation--${a}`,`designbase-wc-bottom-navigation--${s}`,"false"!==this.getAttribute("fixed")&&"designbase-wc-bottom-navigation--fixed"].filter(Boolean).join(" ")}render(){this.syncHostClasses(),this.setAttribute("role","navigation"),this.setAttribute("aria-label","하단 네비게이션");const e=this.parseItems(),i=this.getAttribute("active-item-id")||"",a=this.getAttribute("size")||"m",n=this.iconSize(a);let s=this.querySelector(".designbase-wc-bottom-navigation__container");s?s.replaceChildren():(s=document.createElement("div"),s.className="designbase-wc-bottom-navigation__container",this.replaceChildren(s)),e.forEach(e=>{const a=i===e.id||Boolean(e.isActive),o=function resolveIcon(t){if(t)return t}(a&&e.activeIcon?e.activeIcon:e.icon),r=document.createElement("button");r.type="button",r.className=["designbase-wc-bottom-navigation__item",a&&"designbase-wc-bottom-navigation__item--active",e.disabled&&"designbase-wc-bottom-navigation__item--disabled"].filter(Boolean).join(" "),r.disabled=Boolean(e.disabled),r.setAttribute("aria-label",e.label),a&&r.setAttribute("aria-current","page");const c=document.createElement("div");c.className="designbase-wc-bottom-navigation__item-content";const d=document.createElement("div");if(d.className="designbase-wc-bottom-navigation__icon-wrapper",o){const e=t(o,n);e.classList.add("designbase-wc-bottom-navigation__icon"),d.append(e)}if(void 0!==e.badge&&""!==e.badge){const t=document.createElement("db-badge");t.className="designbase-wc-bottom-navigation__badge",t.setAttribute("size","s"),t.setAttribute("variant",function mapBadgeVariant(t){return"error"===t?"danger":"warning"===t?"warning":"success"===t?"success":"info"===t?"info":"primary"===t?"primary":"secondary"}(e.badgeColor)),t.setAttribute("badge-style","number"),t.setAttribute("count",String(e.badge)),d.append(t)}const b=document.createElement("span");b.className="designbase-wc-bottom-navigation__label",b.textContent=e.label,c.append(d,b),r.append(c),r.addEventListener("click",()=>{e.disabled||this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}),s.append(r)})}}customElements.get("db-bottom-navigation")||customElements.define("db-bottom-navigation",DbBottomNavigation);export{DbBottomNavigation};
1
+ import{createDbIcon as t}from"./db-icons.js";import{BOTTOM_NAV_SIZES as e,BOTTOM_NAV_BACKGROUNDS as i}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbBottomNavigation extends HTMLElement{static get observedAttributes(){return["items","active-item-id","size","background-color","fixed"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}get items(){return this.parseItems()}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}parseItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}iconSize(t){return"s"===t?20:"l"===t?28:24}syncHostClasses(){const t=this.getAttribute("size")||"m",n=e.includes(t)?t:"m",a=this.getAttribute("background-color")||"default",s=i.includes(a)?a:"default";this.className=["designbase-wc-bottom-navigation",`designbase-wc-bottom-navigation--${n}`,`designbase-wc-bottom-navigation--${s}`,"false"!==this.getAttribute("fixed")&&"designbase-wc-bottom-navigation--fixed"].filter(Boolean).join(" ")}render(){this.syncHostClasses(),this.setAttribute("role","navigation"),this.setAttribute("aria-label","하단 네비게이션");const e=this.parseItems(),i=this.getAttribute("active-item-id")||"",n=this.getAttribute("size")||"m",a=this.iconSize(n);let s=this.querySelector(".designbase-wc-bottom-navigation__container");s?s.replaceChildren():(s=document.createElement("div"),s.className="designbase-wc-bottom-navigation__container",this.replaceChildren(s)),e.forEach(e=>{const n=i===e.id||Boolean(e.isActive),o=function resolveIcon(t){if(t)return t}(n&&e.activeIcon?e.activeIcon:e.icon),r=document.createElement("button");r.type="button",r.className=["designbase-wc-bottom-navigation__item",n&&"designbase-wc-bottom-navigation__item--active",e.disabled&&"designbase-wc-bottom-navigation__item--disabled"].filter(Boolean).join(" "),r.disabled=Boolean(e.disabled),r.setAttribute("aria-label",e.label),n&&r.setAttribute("aria-current","page");const c=document.createElement("div");c.className="designbase-wc-bottom-navigation__item-content";const d=document.createElement("div");if(d.className="designbase-wc-bottom-navigation__icon-wrapper",o){const e=t(o,a);e.classList.add("designbase-wc-bottom-navigation__icon"),d.append(e)}if(void 0!==e.badge&&""!==e.badge){const t=document.createElement("db-badge");t.className="designbase-wc-bottom-navigation__badge",t.setAttribute("size","s"),t.setAttribute("variant",function mapBadgeVariant(t){return"error"===t?"danger":"warning"===t?"warning":"success"===t?"success":"info"===t?"info":"primary"===t?"primary":"secondary"}(e.badgeColor)),t.setAttribute("type","number"),t.setAttribute("count",String(e.badge)),d.append(t)}const b=document.createElement("span");b.className="designbase-wc-bottom-navigation__label",b.textContent=e.label,c.append(d,b),r.append(c),r.addEventListener("click",()=>{e.disabled||this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}),s.append(r)})}}customElements.get("db-bottom-navigation")||customElements.define("db-bottom-navigation",DbBottomNavigation);export{DbBottomNavigation};
@@ -6,6 +6,9 @@ declare class DbBottomSheet extends HTMLElement {
6
6
  private grabBar?;
7
7
  private contentEl?;
8
8
  private sheetHeightPercent;
9
+ private focusTrap?;
10
+ /** 참조 카운트 스크롤락을 이 인스턴스가 잡고 있는지 (PERF-GLOBAL-STATE) */
11
+ private scrollLocked;
9
12
  private isDragging;
10
13
  private isVisible;
11
14
  private isMounted;
@@ -19,6 +22,8 @@ declare class DbBottomSheet extends HTMLElement {
19
22
  private shouldMountPortal;
20
23
  connectedCallback(): void;
21
24
  disconnectedCallback(): void;
25
+ /** 트랩 해제(=포커스 복원)와 스크롤락 반환 */
26
+ private teardownOverlay;
22
27
  attributeChangedCallback(name: string): void;
23
28
  private isOpenRequested;
24
29
  private clearTimers;