@designbasekorea/ui-wc 0.8.7 → 0.8.9

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 (98) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -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.js +1 -1
  6. package/dist/esm/components/db-activity-heatmap.js +1 -1
  7. package/dist/esm/components/db-ad-banner.js +1 -1
  8. package/dist/esm/components/db-ai-chat.d.ts +2 -1
  9. package/dist/esm/components/db-ai-chat.js +1 -1
  10. package/dist/esm/components/db-alert.js +1 -1
  11. package/dist/esm/components/db-animation-background.js +1 -1
  12. package/dist/esm/components/db-animation-text.js +1 -1
  13. package/dist/esm/components/db-app-badge.js +1 -1
  14. package/dist/esm/components/db-audio-player.js +1 -1
  15. package/dist/esm/components/db-badge.js +1 -1
  16. package/dist/esm/components/db-banner.js +1 -1
  17. package/dist/esm/components/db-breadcrumbs.js +1 -1
  18. package/dist/esm/components/db-button.d.ts +2 -0
  19. package/dist/esm/components/db-button.js +1 -1
  20. package/dist/esm/components/db-carousel.js +1 -1
  21. package/dist/esm/components/db-chat-message.js +1 -1
  22. package/dist/esm/components/db-chat-orb.js +1 -1
  23. package/dist/esm/components/db-chat-room.d.ts +1 -0
  24. package/dist/esm/components/db-chat-room.js +1 -1
  25. package/dist/esm/components/db-checkbox.js +1 -1
  26. package/dist/esm/components/db-color-picker.js +1 -1
  27. package/dist/esm/components/db-color-swatch.js +1 -1
  28. package/dist/esm/components/db-confirm.js +1 -1
  29. package/dist/esm/components/db-cookie-banner.js +1 -1
  30. package/dist/esm/components/db-countdown.js +1 -1
  31. package/dist/esm/components/db-dropzone.js +1 -1
  32. package/dist/esm/components/db-email-verify.js +1 -1
  33. package/dist/esm/components/db-empty-state.js +1 -1
  34. package/dist/esm/components/db-footer.js +1 -1
  35. package/dist/esm/components/db-gradient.js +1 -1
  36. package/dist/esm/components/db-icons.d.ts +1 -1
  37. package/dist/esm/components/db-icons.js +1 -1
  38. package/dist/esm/components/db-kanban.d.ts +0 -1
  39. package/dist/esm/components/db-kanban.js +1 -1
  40. package/dist/esm/components/db-label.js +1 -1
  41. package/dist/esm/components/db-list.js +1 -1
  42. package/dist/esm/components/db-logo-svg.js +1 -1
  43. package/dist/esm/components/db-logo.js +1 -1
  44. package/dist/esm/components/db-markdown-editor.js +1 -1
  45. package/dist/esm/components/db-marquee.js +1 -1
  46. package/dist/esm/components/db-menu-item.js +1 -1
  47. package/dist/esm/components/db-navbar.js +1 -1
  48. package/dist/esm/components/db-otp-input.js +1 -1
  49. package/dist/esm/components/db-page-header.d.ts +1 -0
  50. package/dist/esm/components/db-page-header.js +1 -1
  51. package/dist/esm/components/db-pagination.js +1 -1
  52. package/dist/esm/components/db-phone-verify.js +1 -1
  53. package/dist/esm/components/db-progress-step.js +1 -1
  54. package/dist/esm/components/db-random-gradient.js +1 -1
  55. package/dist/esm/components/db-range-slider.d.ts +0 -1
  56. package/dist/esm/components/db-range-slider.js +1 -1
  57. package/dist/esm/components/db-rating.js +1 -1
  58. package/dist/esm/components/db-reorder.js +1 -1
  59. package/dist/esm/components/db-section-app-download.js +1 -1
  60. package/dist/esm/components/db-section-contact.js +1 -1
  61. package/dist/esm/components/db-section-cta.js +1 -1
  62. package/dist/esm/components/db-section-faq.js +1 -1
  63. package/dist/esm/components/db-section-feature-grid.js +1 -1
  64. package/dist/esm/components/db-section-feature.js +1 -1
  65. package/dist/esm/components/db-section-hero.js +1 -1
  66. package/dist/esm/components/db-section-logo-cloud.js +1 -1
  67. package/dist/esm/components/db-section-pricing.js +1 -1
  68. package/dist/esm/components/db-section-stats.js +1 -1
  69. package/dist/esm/components/db-section-testimonials.js +1 -1
  70. package/dist/esm/components/db-section.js +1 -1
  71. package/dist/esm/components/db-share-icons.js +1 -1
  72. package/dist/esm/components/db-share.d.ts +3 -0
  73. package/dist/esm/components/db-share.js +1 -1
  74. package/dist/esm/components/db-sidebar.js +1 -1
  75. package/dist/esm/components/db-signature.js +1 -1
  76. package/dist/esm/components/db-tabs.js +1 -1
  77. package/dist/esm/components/db-timeline.js +1 -1
  78. package/dist/esm/components/db-toast.js +1 -1
  79. package/dist/esm/components/db-toolbar.js +1 -1
  80. package/dist/esm/components/db-two-factor.js +1 -1
  81. package/dist/esm/components/db-video-player.js +1 -1
  82. package/dist/esm/components/db-youtube-player.js +1 -1
  83. package/dist/esm/components/section-block-header-utils.js +1 -1
  84. package/dist/esm/core/safe-html.d.ts +4 -0
  85. package/dist/esm/core/safe-html.js +1 -0
  86. package/dist/esm/core/safe-url.d.ts +3 -0
  87. package/dist/esm/core/safe-url.js +1 -0
  88. package/dist/esm/index.d.ts +2 -0
  89. package/dist/esm/index.js +1 -1
  90. package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
  91. package/dist/index.cjs +1 -1
  92. package/dist/index.css +1 -1
  93. package/dist/index.d.ts +16 -5
  94. package/dist/index.esm.js +1 -1
  95. package/dist/react/index.cjs +1 -1
  96. package/dist/react/index.d.ts +10 -4
  97. package/dist/react/index.esm.js +1 -1
  98. package/package.json +4 -4
@@ -1 +1 @@
1
- import{createDbIcon as e,isDbIconName as t}from"./db-icons.js";import{SIDEBAR_CUSTOM_NAV_SLOTS as s,SIDEBAR_PANEL_MODES as a,SIDEBAR_SIZES as i,SIDEBAR_THEMES as n,SIDEBAR_POSITIONS as r,SIDEBAR_VARIANTS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c="240px";class DbSidebar extends HTMLElement{constructor(){super(...arguments),this.expandedItems=new Set,this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.flyoutCloseTimer=null,this.userFlyoutCloseTimer=null,this.outsideHandler=null,this.panelMediaQuery=null,this.panelMediaHandler=null,this.resolvedPanelMode="adjacent"}collectCustomNavSlots(){const e=new Map;return s.forEach(t=>{const s=Array.from(this.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t),a=Array.from(this.querySelectorAll(`[data-sidebar-slot="${t}"]`)).flatMap(e=>Array.from(e.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t));e.set(t,[...new Set([...s,...a])])}),e}createCustomNavSlot(e){const t=document.createElement("div");return t.className=["designbase-wc-sidebar__custom-slot",`designbase-wc-sidebar__custom-slot--${e}`].join(" "),t.dataset.sidebarSlot=e,t}projectCustomNavSlots(e){s.forEach(t=>{const s=this.querySelector(`[data-sidebar-slot="${t}"]`),a=e.get(t)??[];s&&0!==a.length?s.append(...a):s?.remove()})}static get observedAttributes(){return["items","sections","user-menu-items","user-profile","default-expanded-ids","projects","selected-project-id","project-manage-label","project-manage-href","project-section-label","project-empty-label","project-empty-trigger-label","bottom-items","bottom-sections","promo-banner","update-banner","header-type","back-label","back-href","panels","settings-sections","active-panel","panel-mode","panel-width","panel-breakpoint","size","theme","variant","position","collapsed","collapsible","show-logo","logo-type","logo-text","full-height","shadow"]}connectedCallback(){this.seedExpanded(),this.bindPanelMediaQuery(),this.render(),this.bindOutsideClick()}disconnectedCallback(){this.unbindOutsideClick(),this.unbindPanelMediaQuery(),this.cancelFlyoutClose(),this.cancelUserFlyoutClose()}attributeChangedCallback(e,t,s){if(this.isConnected&&t!==s&&("default-expanded-ids"===e&&this.seedExpanded(),"collapsed"===e&&this.hasAttribute("collapsed")&&(this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.cancelFlyoutClose(),this.cancelUserFlyoutClose()),"panel-mode"!==e&&"panel-breakpoint"!==e||this.bindPanelMediaQuery(),this.render(),"active-panel"===e)){const e=this.getActivePanelConfig();this.dispatchEvent(new CustomEvent("db-panel-change",{bubbles:!0,composed:!0,detail:{panel:e?.id??"main",panelConfig:e,mode:this.resolvedPanelMode}}))}}bindPanelMediaQuery(){this.unbindPanelMediaQuery();const e=this.panelMode;if("auto"!==e)return void(this.resolvedPanelMode=e);if("undefined"==typeof window||"function"!=typeof window.matchMedia)return void(this.resolvedPanelMode="adjacent");const t=window.matchMedia(`(min-width: ${this.panelBreakpoint}px)`);this.panelMediaQuery=t,this.resolvedPanelMode=t.matches?"adjacent":"replace",this.panelMediaHandler=e=>{const t=e.matches?"adjacent":"replace";t!==this.resolvedPanelMode&&(this.resolvedPanelMode=t,this.render(),this.dispatchEvent(new CustomEvent("db-panel-mode-change",{bubbles:!0,composed:!0,detail:{mode:t}})))},t.addEventListener("change",this.panelMediaHandler)}unbindPanelMediaQuery(){this.panelMediaQuery&&this.panelMediaHandler&&this.panelMediaQuery.removeEventListener("change",this.panelMediaHandler),this.panelMediaQuery=null,this.panelMediaHandler=null}seedExpanded(){try{const e=JSON.parse(this.getAttribute("default-expanded-ids")||"[]");Array.isArray(e)&&(this.expandedItems=new Set(e))}catch{this.expandedItems=new Set}}get items(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get sections(){return this.parseSections()}set sections(e){this.setAttribute("sections","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseUserMenuItems()}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}get projects(){return this.parseProjects()}set projects(e){this.setAttribute("projects","string"==typeof e?e:JSON.stringify(e))}get selectedProjectId(){return this.getAttribute("selected-project-id")||""}set selectedProjectId(e){e?this.setAttribute("selected-project-id",e):this.removeAttribute("selected-project-id")}get projectManageLabel(){return this.getAttribute("project-manage-label")||"프로젝트 관리"}set projectManageLabel(e){this.setAttribute("project-manage-label",e)}get projectManageHref(){return this.getAttribute("project-manage-href")||""}set projectManageHref(e){e?this.setAttribute("project-manage-href",e):this.removeAttribute("project-manage-href")}get projectSectionLabel(){return this.getAttribute("project-section-label")||"프로젝트"}set projectSectionLabel(e){this.setAttribute("project-section-label",e)}get projectEmptyLabel(){return this.getAttribute("project-empty-label")||"프로젝트를 추가해 주세요"}set projectEmptyLabel(e){this.setAttribute("project-empty-label",e)}get projectEmptyTriggerLabel(){return this.getAttribute("project-empty-trigger-label")||"프로젝트 추가"}set projectEmptyTriggerLabel(e){this.setAttribute("project-empty-trigger-label",e)}get bottomItems(){return this.parseBottomItems()}set bottomItems(e){this.setAttribute("bottom-items","string"==typeof e?e:JSON.stringify(e))}get bottomSections(){return this.parseBottomSections()}set bottomSections(e){this.setAttribute("bottom-sections","string"==typeof e?e:JSON.stringify(e))}get promoBanner(){return this.parsePromoBanner()}set promoBanner(e){null==e?this.removeAttribute("promo-banner"):this.setAttribute("promo-banner","string"==typeof e?e:JSON.stringify(e))}get updateBanner(){return this.parseUpdateBanner()}set updateBanner(e){null==e?this.removeAttribute("update-banner"):this.setAttribute("update-banner","string"==typeof e?e:JSON.stringify(e))}get headerType(){return"back"===this.getAttribute("header-type")?"back":"default"}set headerType(e){this.setAttribute("header-type",e)}get backLabel(){return this.getAttribute("back-label")||"뒤로가기"}set backLabel(e){this.setAttribute("back-label",e)}get backHref(){return this.getAttribute("back-href")||""}set backHref(e){e?this.setAttribute("back-href",e):this.removeAttribute("back-href")}get panels(){return this.parsePanels()}set panels(e){this.setAttribute("panels","string"==typeof e?e:JSON.stringify(e))}get settingsSections(){return this.parseSettingsSections()}set settingsSections(e){this.setAttribute("settings-sections","string"==typeof e?e:JSON.stringify(e))}get activePanel(){const e=this.getAttribute("active-panel")||"main";return"main"===e?"main":this.findPanel(e)?e:"main"}set activePanel(e){const t=e&&"main"!==e&&this.findPanel(e)?e:"main";this.setAttribute("active-panel",t)}get panelMode(){const e=this.getAttribute("panel-mode")||"auto";return a.includes(e)?e:"auto"}set panelMode(e){this.setAttribute("panel-mode",a.includes(e)?e:"auto")}get panelWidth(){return this.normalizeCssLength(this.getAttribute("panel-width")||c)}set panelWidth(e){this.setAttribute("panel-width",this.normalizeCssLength(e))}get panelBreakpoint(){const e=Number(this.getAttribute("panel-breakpoint"));return Number.isFinite(e)&&e>0?e:1024}set panelBreakpoint(e){const t=Number.isFinite(e)&&e>0?Math.round(e):1024;this.setAttribute("panel-breakpoint",String(t))}normalizeCssLength(e){if("number"==typeof e)return`${Math.max(0,e)}px`;const t=String(e??"").trim();return t?/^-?\d+(?:\.\d+)?$/.test(t)?`${Math.max(0,Number(t))}px`:t:c}parseSettingsSections(){try{const e=JSON.parse(this.getAttribute("settings-sections")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parsePanels(){let e=[];const t=this.getAttribute("panels");if(t)try{const s=JSON.parse(t);Array.isArray(s)&&(e=s.filter(e=>Boolean(e&&"string"==typeof e.id&&e.id.trim())).map(e=>({...e,id:e.id.trim(),title:String(e.title||e.id).trim(),sections:Array.isArray(e.sections)?e.sections:[]})))}catch{e=[]}const s=this.parseSettingsSections();return s.length&&!e.some(e=>"settings"===e.id)&&e.push({id:"settings",title:"Settings",backLabel:this.backLabel,sections:s}),e}hasPanels(){return this.parsePanels().length>0}findPanel(e){return e&&"main"!==e?this.parsePanels().find(t=>t.id===e)??null:null}getActivePanelConfig(){return this.findPanel(this.getAttribute("active-panel")||"main")}parseSections(){const e=this.getAttribute("sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}try{const e=JSON.parse(this.getAttribute("items")||"[]");return[{id:"main",items:Array.isArray(e)?e:[]}]}catch{return[{id:"main",items:[]}]}}parseUserMenuItems(){try{const e=JSON.parse(this.getAttribute("user-menu-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseProjects(){try{const e=JSON.parse(this.getAttribute("projects")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomItems(){try{const e=JSON.parse(this.getAttribute("bottom-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomSections(){const e=this.getAttribute("bottom-sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}const t=this.parseBottomItems();return t.length?[{id:"bottom",items:t}]:[]}parsePromoBanner(){const e=this.getAttribute("promo-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseUpdateBanner(){const e=this.getAttribute("update-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}getSelectedProject(){const e=this.parseProjects();if(!e.length)return null;const t=this.selectedProjectId;return e.find(e=>e.id===t)||e[0]}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{const t=e.target;if(this.contains(t))return;let s=!1;this.userMenuOpen&&(this.userMenuOpen=!1,this.userFlyoutItemId=null,s=!0),this.projectMenuOpen&&(this.projectMenuOpen=!1,s=!0),s&&this.render()},document.addEventListener("mousedown",this.outsideHandler))}closeOverlayMenus(){const e=this.projectMenuOpen,t=this.userMenuOpen;if(!e&&!t)return!1;this.projectMenuOpen=!1,this.userMenuOpen=!1,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.classList.remove("designbase-wc-sidebar--user-menu-open"),this.querySelector(".designbase-wc-sidebar__project-dropdown")?.remove(),this.querySelector(".designbase-wc-sidebar__project-selector")?.classList.remove("designbase-wc-sidebar__project-selector--open");const s=this.querySelector(".designbase-wc-sidebar__project-trigger");s?.setAttribute("aria-expanded","false");const a=this.querySelector(".designbase-wc-sidebar__user-dropdown");return a&&(a.hidden=!0),this.querySelector(".designbase-wc-sidebar__user-info")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.classList.remove("designbase-wc-sidebar__user-collapsed--open"),!0}syncExclusiveAccordion(e){[...Array.from(this.querySelectorAll(".designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item")),...Array.from(this.querySelectorAll(".designbase-wc-sidebar__bottom-nav .designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item"))].forEach(t=>{const s=t.getAttribute("data-item-id");s&&(e&&s===e?t.setAttribute("expanded",""):t.removeAttribute("expanded"))})}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}cancelFlyoutClose(){this.flyoutCloseTimer&&(clearTimeout(this.flyoutCloseTimer),this.flyoutCloseTimer=null)}showFlyout(e){this.cancelFlyoutClose(),this.flyoutItemId!==e&&(this.flyoutItemId=e,this.renderNav(),this.renderBottomNav())}scheduleFlyoutClose(){this.cancelFlyoutClose(),this.flyoutCloseTimer=setTimeout(()=>{this.flyoutCloseTimer=null,this.flyoutItemId=null,this.renderNav(),this.renderBottomNav()},120)}cancelUserFlyoutClose(){this.userFlyoutCloseTimer&&(clearTimeout(this.userFlyoutCloseTimer),this.userFlyoutCloseTimer=null)}setUserFlyout(e){this.cancelUserFlyoutClose(),this.userFlyoutItemId=e,this.querySelectorAll(".designbase-wc-sidebar__user-menu-item").forEach(t=>{const s=Boolean(e&&t.dataset.itemId===e);t.classList.toggle("designbase-wc-sidebar__user-menu-item--flyout-active",s),t.querySelector(".designbase-wc-sidebar__user-menu-trigger")?.setAttribute("aria-expanded",String(s));const a=t.querySelector(".designbase-wc-sidebar__user-flyout");a&&(a.hidden=!s)})}scheduleUserFlyoutClose(){this.cancelUserFlyoutClose(),this.userFlyoutCloseTimer=setTimeout(()=>{this.userFlyoutCloseTimer=null,this.setUserFlyout(null)},120)}syncHostClasses(){const e=this.getAttribute("size")||"m",t=this.getAttribute("theme")||"default",s=this.getAttribute("variant")||"default",a=this.getAttribute("position")||"left",c=this.getActivePanelConfig(),d=Boolean(c),l=this.panelWidth;this.style.setProperty("--db-sidebar-panel-width",l),this.className=["designbase-wc-sidebar",`designbase-wc-sidebar--${i.includes(e)?e:"m"}`,`designbase-wc-sidebar--${n.includes(t)?t:"default"}`,`designbase-wc-sidebar--${r.includes(a)?a:"left"}`,`designbase-wc-sidebar--panel-${this.resolvedPanelMode}`,o.includes(s)&&"wrapper"===s&&"designbase-wc-sidebar--wrapper",this.hasAttribute("collapsed")&&"designbase-wc-sidebar--collapsed",this.hasAttribute("full-height")&&"designbase-wc-sidebar--full-height",this.hasAttribute("shadow")&&"designbase-wc-sidebar--shadow",this.userMenuOpen&&"designbase-wc-sidebar--user-menu-open",("back"===this.headerType||d&&"replace"===this.resolvedPanelMode)&&"designbase-wc-sidebar--header-back",d&&"designbase-wc-sidebar--panel-open",this.hasPanels()&&"designbase-wc-sidebar--has-panels"].filter(Boolean).join(" ")}navigateToPanel(e){const t="main"!==e&&e?this.findPanel(e)?.id:"main";t&&this.activePanel!==t&&("main"!==t&&"replace"===this.resolvedPanelMode&&this.hasAttribute("collapsed")&&this.removeAttribute("collapsed"),this.setAttribute("active-panel",t))}dispatchItemClick(e){this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchUserMenuItemClick(e){this.dispatchEvent(new CustomEvent("db-user-menu-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchBackClick(){const e=this.getActivePanelConfig();e&&this.navigateToPanel("main");const t=new CustomEvent("db-back-click",{bubbles:!0,composed:!0,cancelable:!0,detail:{label:e?.backLabel||this.backLabel,href:this.backHref,panel:e}});this.dispatchEvent(t),t.defaultPrevented||e||!this.backHref||"back"!==this.headerType||window.location.assign(this.backHref)}dispatchProjectChange(e){this.dispatchEvent(new CustomEvent("db-project-change",{bubbles:!0,composed:!0,detail:{project:e}}))}dispatchProjectManage(){this.dispatchEvent(new CustomEvent("db-project-manage",{bubbles:!0,composed:!0,detail:{}}))}dispatchPromoCtaClick(e){this.dispatchEvent(new CustomEvent("db-promo-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}dispatchUpdateCtaClick(e){this.dispatchEvent(new CustomEvent("db-update-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}createProjectAvatar(e,t="s"){const s=document.createElement("db-avatar");if(s.className="designbase-wc-sidebar__project-avatar",s.setAttribute("size",t),s.setAttribute("initials",(e.label||"?").trim()),s.setAttribute("alt",e.label),e.color){const applyColor=()=>{const t=s.querySelector(".designbase-wc-avatar__initials");return!!t&&(t.style.backgroundColor=e.color,t.style.color="#fff",!0)},t=new MutationObserver(()=>{applyColor()&&t.disconnect()});t.observe(s,{childList:!0,subtree:!0}),queueMicrotask(()=>{applyColor()&&t.disconnect()})}return s}createProjectEmptyMark(t="s"){const s=document.createElement("span");return s.className=["designbase-wc-sidebar__project-mark",`designbase-wc-sidebar__project-mark--${t}`,"designbase-wc-sidebar__project-mark--empty"].join(" "),s.setAttribute("aria-hidden","true"),s.append(e("plus","m"===t?16:14)),s}createProjectBadge(e){if(!e.badge)return null;const t=document.createElement("db-badge");return t.className="designbase-wc-sidebar__project-badge",t.setAttribute("size","s"),t.setAttribute("variant",e.badgeColor||"warning"),t.setAttribute("type","text"),t.textContent=e.badge,t}createProjectSelector(t){if(!this.hasAttribute("projects"))return null;const s=this.parseProjects(),a=0===s.length,i=this.getSelectedProject(),n=document.createElement("div");n.className=["designbase-wc-sidebar__project-selector",t&&"designbase-wc-sidebar__project-selector--collapsed",this.projectMenuOpen&&"designbase-wc-sidebar__project-selector--open",a&&"designbase-wc-sidebar__project-selector--empty"].filter(Boolean).join(" ");const r=this.getAttribute("project-section-label");if(!t&&r&&r.trim()){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-section-label",e.textContent=r.trim(),n.append(e)}const o=document.createElement("button");if(o.type="button",o.className="designbase-wc-sidebar__project-trigger",o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-expanded",String(this.projectMenuOpen)),a||!i){if(o.setAttribute("aria-label",this.projectEmptyTriggerLabel),o.append(this.createProjectEmptyMark(t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=this.projectEmptyTriggerLabel,o.append(e)}}else if(o.setAttribute("aria-label",i.label),o.append(this.createProjectAvatar(i,t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=i.label,o.append(e)}const c=document.createElement("span");if(c.className="designbase-wc-sidebar__project-chevron",c.setAttribute("aria-hidden","true"),c.append(e("chevron-down",14)),o.append(c),o.addEventListener("click",()=>{this.projectMenuOpen=!this.projectMenuOpen,this.userMenuOpen=!1,this.render()}),n.append(o),this.projectMenuOpen){const t=document.createElement("div");if(t.className="designbase-wc-sidebar__project-dropdown",t.setAttribute("role","menu"),t.setAttribute("aria-label",this.projectSectionLabel),a){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-empty",e.setAttribute("role","presentation");const s=document.createElement("p");s.className="designbase-wc-sidebar__project-empty-text",s.textContent=this.projectEmptyLabel,e.append(s),t.append(e)}else{const e=document.createElement("ul");e.className="designbase-wc-sidebar__project-list",s.forEach(t=>{const s=document.createElement("li");s.className="designbase-wc-sidebar__project-option";const a=document.createElement("button");a.type="button",a.className=["designbase-wc-sidebar__project-option-btn",i&&t.id===i.id&&"designbase-wc-sidebar__project-option-btn--active"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a.append(this.createProjectAvatar(t,"s"));const n=document.createElement("span");n.className="designbase-wc-sidebar__project-option-label",n.textContent=t.label,a.append(n);const r=this.createProjectBadge(t);r&&a.append(r),a.addEventListener("click",()=>{this.projectMenuOpen=!1,this.setAttribute("selected-project-id",t.id),this.dispatchProjectChange(t),this.render()}),s.append(a),e.append(s)}),t.append(e)}const r=document.createElement("button");r.type="button",r.className="designbase-wc-sidebar__project-manage",r.setAttribute("role","menuitem"),r.append(e("plus",14));const o=document.createElement("span");o.textContent=this.projectManageLabel,r.append(o),r.addEventListener("click",()=>{this.projectMenuOpen=!1;const e=this.projectManageHref;e&&window.location.assign(e),this.dispatchProjectManage(),this.render()}),t.append(r),n.append(t)}return n}createFlyout(e,t){const s=this.getAttribute("position")||"left",a=document.createElement("div");a.className=["designbase-wc-sidebar__flyout","right"===s&&"designbase-wc-sidebar__flyout--align-left"].filter(Boolean).join(" "),a.setAttribute("role","menu"),a.setAttribute("aria-label",`${e.label} 하위 메뉴`),a.addEventListener("mouseenter",()=>this.cancelFlyoutClose()),a.addEventListener("mouseleave",()=>this.scheduleFlyoutClose());const i=document.createElement("div");i.className="designbase-wc-sidebar__flyout-title",i.textContent=e.label,a.append(i);const n=document.createElement("ul");return n.className="designbase-wc-sidebar__flyout-list",(e.children||[]).forEach(e=>{const s=document.createElement("li");s.className="designbase-wc-sidebar__flyout-item";const a=document.createElement("db-menu-item");a.setAttribute("label",e.label),a.setAttribute("type","block"),a.setAttribute("menu-style","dropdown"),a.setAttribute("size",t),e.href&&a.setAttribute("href",e.href),e.active&&a.setAttribute("active",""),e.disabled&&a.setAttribute("disabled",""),void 0!==e.badge&&a.setAttribute("badge",String(e.badge)),e.badgeColor&&a.setAttribute("badge-color",e.badgeColor),a.addEventListener("db-click",()=>{e.disabled||(this.flyoutItemId=null,this.dispatchItemClick(e),this.renderNav(),this.renderBottomNav())}),s.append(a),n.append(s)}),a.append(n),a}createSidebarMenuItem(e,t,s=0){const a=Boolean(e.children?.length),i=this.expandedItems.has(e.id),n=this.hasAttribute("collapsed"),r=n&&a,o=document.createElement("li");o.className=["designbase-wc-sidebar__item",r&&this.flyoutItemId===e.id&&"designbase-wc-sidebar__item--flyout-active"].filter(Boolean).join(" "),r&&(o.addEventListener("mouseenter",()=>this.showFlyout(e.id)),o.addEventListener("mouseleave",()=>this.scheduleFlyoutClose()));const c=document.createElement("db-menu-item");if(c.setAttribute("data-item-id",e.id),c.setAttribute("label",e.label),c.setAttribute("type","block"),c.setAttribute("menu-style","accordion"),c.setAttribute("size",t),c.setAttribute("depth",String(s)),e.href&&c.setAttribute("href",e.href),e.icon&&c.setAttribute("icon",e.icon),(e.active||e.openPanel&&e.openPanel===this.activePanel)&&c.setAttribute("active",""),e.disabled&&c.setAttribute("disabled",""),void 0!==e.badge&&c.setAttribute("badge",String(e.badge)),e.badgeColor&&c.setAttribute("badge-color",e.badgeColor),a&&!r&&(c.setAttribute("expandable",""),c.subItems=(e.children||[]).map(e=>({id:e.id,label:e.label,href:e.href,active:e.active,disabled:e.disabled,badge:e.badge,badgeColor:e.badgeColor})),i&&!n&&c.setAttribute("expanded","")),c.addEventListener("db-click",t=>{if(!e.disabled){if(a&&!n){const s=t.detail?.expanded??!this.expandedItems.has(e.id);return this.closeOverlayMenus(),void(s?(this.expandedItems.clear(),this.expandedItems.add(e.id),this.syncExclusiveAccordion(e.id)):(this.expandedItems.delete(e.id),this.syncExclusiveAccordion(null)))}if(r)return this.closeOverlayMenus(),void this.showFlyout(e.id);if(this.closeOverlayMenus(),e.openPanel&&this.findPanel(e.openPanel))return this.dispatchItemClick(e),void this.navigateToPanel(e.openPanel);this.dispatchItemClick(e)}}),c.addEventListener("db-child-click",e=>{const t=e.detail;this.dispatchItemClick(t.child)}),o.append(c),n&&void 0!==e.badge&&null!==e.badge&&""!==e.badge){const t=e.badgeColor||"primary",s=document.createElement("span");s.className=["designbase-wc-sidebar__collapsed-badge-dot",`designbase-wc-sidebar__collapsed-badge-dot--${t}`].join(" "),s.setAttribute("aria-hidden","true"),o.append(s)}if(n&&!a){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=e.label,t.setAttribute("role","tooltip"),o.append(t)}return r&&this.flyoutItemId===e.id&&o.append(this.createFlyout(e,t)),o}renderSectionList(e,t,s){const a=document.createDocumentFragment();return e.forEach(e=>{const i=document.createElement("div");if(i.className=["designbase-wc-sidebar__section",e.gap&&`designbase-wc-sidebar__section--gap-${e.gap}`].filter(Boolean).join(" "),!s&&e.title){const t=document.createElement("div");t.className="designbase-wc-sidebar__section-title",t.textContent=e.title,i.append(t)}const n=document.createElement("ul");n.className="designbase-wc-sidebar__nav-list",e.items.forEach(e=>n.append(this.createSidebarMenuItem(e,t))),i.append(n),a.append(i)}),a}renderNav(){const e=this.getAttribute("size")||"m",t=this.hasAttribute("collapsed"),s=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="main"]');s&&s.replaceChildren(this.renderSectionList(this.parseSections(),e,t),this.createCustomNavSlot("nav"));const a=this.getActivePanelConfig(),i=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="panel"]');i&&a&&i.replaceChildren(this.renderSectionList(a.sections,e,!1))}renderBottomNav(){const e=this.querySelector(".designbase-wc-sidebar__bottom-nav");if(!e)return;const t=this.getAttribute("size")||"m",s=this.hasAttribute("collapsed");e.replaceChildren(this.renderSectionList(this.parseBottomSections(),t,s))}createUserDropdown(s,a=!1){if(!s.length)return null;const i=this.getAttribute("position")||"left",n=document.createElement("div");n.className=["designbase-wc-sidebar__user-dropdown",a&&"designbase-wc-sidebar__user-dropdown--collapsed"].filter(Boolean).join(" "),n.setAttribute("role","menu"),n.setAttribute("aria-label","사용자 메뉴"),n.hidden=!this.userMenuOpen,n.addEventListener("keydown",e=>{"Escape"===e.key&&(e.stopPropagation(),this.userFlyoutItemId?this.setUserFlyout(null):(this.userMenuOpen=!1,this.render()))});const r=document.createElement("ul");return r.className="designbase-wc-sidebar__user-menu",s.forEach(s=>{const a=Boolean(s.children?.length),n=document.createElement("li");n.dataset.itemId=s.id,n.className=["designbase-wc-sidebar__user-menu-item",s.dividerBefore&&"designbase-wc-sidebar__user-menu-item--divider",s.disabled&&"designbase-wc-sidebar__user-menu-item--disabled",a&&"designbase-wc-sidebar__user-menu-item--has-children"].filter(Boolean).join(" ");const o=document.createElement("button");if(o.type="button",o.className="designbase-wc-sidebar__user-menu-trigger",o.setAttribute("role","menuitem"),o.disabled=Boolean(s.disabled),s.icon&&t(s.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(s.icon,16)),o.append(t)}const c=document.createElement("span");if(c.className="designbase-wc-sidebar__user-menu-label",c.textContent=s.label,o.append(c),s.value){const e=document.createElement("span");e.className="designbase-wc-sidebar__user-menu-value",e.textContent=s.value,o.append(e)}if(a){const a=document.createElement("span");a.className="designbase-wc-sidebar__user-menu-chevron",a.setAttribute("aria-hidden","true"),a.append(e("right"===i?"chevron-left":"chevron-right",16)),o.append(a),o.setAttribute("aria-haspopup","menu"),o.setAttribute("aria-expanded",String(this.userFlyoutItemId===s.id));const openFlyout=()=>this.setUserFlyout(s.id);n.addEventListener("mouseenter",openFlyout),n.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose()),n.addEventListener("focusin",openFlyout),n.addEventListener("focusout",e=>{const t=e.relatedTarget;t&&n.contains(t)||this.scheduleUserFlyoutClose()}),o.addEventListener("click",openFlyout);const r=document.createElement("div");r.className=["designbase-wc-sidebar__user-flyout","right"===i&&"designbase-wc-sidebar__user-flyout--align-left"].filter(Boolean).join(" "),r.setAttribute("role","menu"),r.setAttribute("aria-label",`${s.label} 하위 메뉴`),r.hidden=this.userFlyoutItemId!==s.id,r.addEventListener("mouseenter",()=>this.cancelUserFlyoutClose()),r.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose());const c=document.createElement("ul");c.className="designbase-wc-sidebar__user-flyout-list",(s.children||[]).forEach(s=>{const a=document.createElement("li");a.className="designbase-wc-sidebar__user-flyout-item";const i=document.createElement("button");if(i.type="button",i.className=["designbase-wc-sidebar__user-menu-trigger","designbase-wc-sidebar__user-flyout-trigger",s.selected&&"designbase-wc-sidebar__user-flyout-trigger--selected"].filter(Boolean).join(" "),i.setAttribute("role","menuitemradio"),i.setAttribute("aria-checked",String(Boolean(s.selected))),i.disabled=Boolean(s.disabled),s.icon&&t(s.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(s.icon,16)),i.append(t)}const n=document.createElement("span");if(n.className="designbase-wc-sidebar__user-menu-label",n.textContent=s.label,i.append(n),s.selected){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-check",t.setAttribute("aria-hidden","true"),t.append(e("done",16)),i.append(t)}i.addEventListener("click",()=>{s.disabled||(this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(s),s.href&&window.location.assign(s.href),this.render())}),a.append(i),c.append(a)}),r.append(c),n.append(o,r)}else o.addEventListener("click",()=>{s.disabled||(this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(s),s.href&&window.location.assign(s.href),this.render())}),n.append(o);r.append(n)}),n.append(r),n}createUpdateBanner(e){if("back"===this.headerType)return null;const t=this.parseUpdateBanner();if(!t)return null;if(e)return null;const s=document.createElement("div");s.className="designbase-wc-sidebar__update";const a=document.createElement("db-banner");return a.className="designbase-wc-sidebar__update-banner",a.setAttribute("size","s"),a.setAttribute("variant",t.variant||"outline"),a.setAttribute("title",t.title),t.description&&a.setAttribute("description",t.description),t.icon&&a.setAttribute("icon",t.icon),a.setAttribute("clickable",""),a.setAttribute("aria-label",t.ctaLabel||t.title),a.addEventListener("db-click",()=>{t.ctaHref&&window.location.assign(t.ctaHref),this.dispatchUpdateCtaClick(t)}),s.append(a),s}createPromoBanner(s){if("back"===this.headerType)return null;const a=this.parsePromoBanner();if(!a)return null;if(s){const s=document.createElement("button");s.type="button",s.className="designbase-wc-sidebar__promo-collapsed",s.setAttribute("aria-label",a.ctaLabel||a.title);const i=document.createElement("db-animation-background");i.className="designbase-wc-sidebar__promo-bg",i.setAttribute("type","aurora"),i.setAttribute("theme","light"),i.setAttribute("intensity","subtle"),i.setAttribute("blur","40"),i.setAttribute("speed","4000"),i.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8"])),s.append(i),s.append(e(a.icon&&t(a.icon)?a.icon:"sparkle",18)),s.addEventListener("click",()=>this.dispatchPromoCtaClick(a));const n=document.createElement("span");n.className="designbase-wc-sidebar__item-tooltip",n.textContent=a.title,n.setAttribute("role","tooltip");const r=document.createElement("div");return r.className="designbase-wc-sidebar__promo-collapsed-wrap",r.append(s,n),r}const i=document.createElement("div");i.className="designbase-wc-sidebar__promo";const n=document.createElement("db-animation-background");n.className="designbase-wc-sidebar__promo-bg",n.setAttribute("type","aurora"),n.setAttribute("theme","light"),n.setAttribute("intensity","subtle"),n.setAttribute("blur","60"),n.setAttribute("speed","5000"),n.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8","#bfdbfe"])),i.append(n);const r=document.createElement("div");r.className="designbase-wc-sidebar__promo-content";const o=document.createElement("div");o.className="designbase-wc-sidebar__promo-title-row";const c=document.createElement("span");c.className="designbase-wc-sidebar__promo-icon",c.setAttribute("aria-hidden","true"),c.append(e(a.icon&&t(a.icon)?a.icon:"sparkle",16));const d=document.createElement("div");if(d.className="designbase-wc-sidebar__promo-title",d.textContent=a.title,o.append(c,d),r.append(o),a.description){const e=document.createElement("div");e.className="designbase-wc-sidebar__promo-desc",e.textContent=a.description,r.append(e)}if(a.ctaLabel){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__promo-action",e.setAttribute("variant","secondary"),e.setAttribute("size","s"),e.setAttribute("full-width",""),e.textContent=a.ctaLabel,e.addEventListener("db-click",()=>{a.ctaHref&&window.location.assign(a.ctaHref),this.dispatchPromoCtaClick(a)}),r.append(e)}return i.append(r),i}createMainHeader(t){const{size:s,collapsible:a,showLogo:i,collapsed:n}=t,r="back"===this.headerType,o="l"===s?"m":"s"===s?"xs":"s";if(!r&&!a&&(!i||n))return null;const c=document.createElement("div");if(c.className=["designbase-wc-sidebar__header",(n||!i)&&!r&&"designbase-wc-sidebar__header--collapsed-only",r&&"designbase-wc-sidebar__header--back"].filter(Boolean).join(" "),r){const t=document.createElement("button");if(t.type="button",t.className=["designbase-wc-sidebar__back",n&&"designbase-wc-sidebar__back--collapsed"].filter(Boolean).join(" "),t.setAttribute("aria-label",this.backLabel),t.append(e("chevron-left",18)),!n){const e=document.createElement("span");e.textContent=this.backLabel,t.append(e)}t.addEventListener("click",()=>this.dispatchBackClick()),c.append(t)}else if(!n&&i){const e=document.createElement("div");e.className="designbase-wc-sidebar__logo";const t=this.getAttribute("logo-type")||"designbase",s=this.getAttribute("logo-text")||"";if("custom"===t&&s){const t=document.createElement("span");t.className="designbase-wc-sidebar__logo-text",t.textContent=s,e.append(t)}else{const a=document.createElement("db-logo");a.setAttribute("type",t),a.setAttribute("size",o),s&&a.setAttribute("text",s),e.append(a)}e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),c.append(e)}if(a&&!r){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__toggle",e.setAttribute("variant","tertiary"),e.setAttribute("size","s"),e.setAttribute("icon-only",""),e.setAttribute("start-icon",n?"arrow-bar-right":"arrow-bar-left"),e.setAttribute("aria-label",n?"사이드바 펼치기":"사이드바 접기"),e.addEventListener("db-click",()=>{const e=!this.hasAttribute("collapsed");e?this.setAttribute("collapsed",""):this.removeAttribute("collapsed"),this.dispatchEvent(new CustomEvent("db-toggle",{bubbles:!0,composed:!0,detail:{collapsed:e}}))}),c.append(e)}return c}createPanelHeader(t){const s="replace"===this.resolvedPanelMode,a=document.createElement("div");if(a.className=["designbase-wc-sidebar__panel-header",s&&"designbase-wc-sidebar__panel-header--replace"].filter(Boolean).join(" "),s){const s=document.createElement("button");s.type="button",s.className="designbase-wc-sidebar__panel-back",s.setAttribute("aria-label",t.backLabel||this.backLabel),s.append(e("chevron-left",18)),s.addEventListener("click",()=>this.dispatchBackClick()),a.append(s)}const i=document.createElement("div");i.className="designbase-wc-sidebar__panel-heading";const n=document.createElement("div");if(n.className="designbase-wc-sidebar__panel-title",n.textContent=t.title,i.append(n),t.description){const e=document.createElement("div");e.className="designbase-wc-sidebar__panel-description",e.textContent=t.description,i.append(e)}return a.append(i),a}createNavWrapper(e){const{mode:t,collapsed:s,includeProjects:a,includeBottom:i,panel:n}=e,r=document.createElement("div");if(r.className="designbase-wc-sidebar__nav-wrapper",a){const e=this.createProjectSelector(s);e&&r.append(e)}"main"===t&&r.append(this.createCustomNavSlot("nav-top"));const o=document.createElement("nav");if(o.className="designbase-wc-sidebar__nav",o.setAttribute("data-panel-nav",t),n&&(o.dataset.panelId=n.id),o.setAttribute("aria-label",n?.ariaLabel||n?.title||"주 메뉴"),r.append(o),"main"===t&&r.append(this.createCustomNavSlot("nav-bottom")),i){const e=document.createElement("nav");e.className="designbase-wc-sidebar__bottom-nav",e.setAttribute("aria-label","하단 메뉴"),r.append(e)}return r}createFooter(t){const{collapsed:s,userProfile:a,userMenuItems:i}=t,n=document.createElement("div");n.className="designbase-wc-sidebar__footer";const r=this.createUpdateBanner(s);r&&n.append(r);const o=this.createPromoBanner(s);if(o&&n.append(o),a&&!s){const t=document.createElement("div");t.className="designbase-wc-sidebar__user";const s=this.createUserDropdown(i);s&&t.append(s);const r=document.createElement("div");r.className="designbase-wc-sidebar__user-info",r.setAttribute("role","button"),r.setAttribute("tabindex","0"),r.setAttribute("aria-expanded",String(this.userMenuOpen));const o=document.createElement("db-avatar");o.className="designbase-wc-sidebar__user-avatar",o.setAttribute("size","s"),o.setAttribute("initials",a.name),o.setAttribute("alt",a.name),a.avatar&&o.setAttribute("src",a.avatar);const c=document.createElement("div");c.className="designbase-wc-sidebar__user-details";const d=document.createElement("div");if(d.className="designbase-wc-sidebar__user-name",d.textContent=a.name,c.append(d),a.email){const e=document.createElement("div");e.className="designbase-wc-sidebar__user-email",e.textContent=a.email,c.append(e)}if(r.append(o,c),i.length){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-more",t.setAttribute("aria-hidden","true"),t.append(e("more-vertical",16)),r.append(t),r.setAttribute("aria-haspopup","menu")}r.addEventListener("click",()=>{i.length&&(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render())}),r.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),r.click())}),t.append(r),n.append(t)}else if(a&&s){const e=document.createElement("div");e.className=["designbase-wc-sidebar__user-collapsed",this.userMenuOpen&&"designbase-wc-sidebar__user-collapsed--open"].filter(Boolean).join(" "),e.setAttribute("role","button"),e.setAttribute("tabindex","0"),e.setAttribute("aria-label",a.name),e.setAttribute("aria-expanded",String(this.userMenuOpen)),i.length&&e.setAttribute("aria-haspopup","menu");const t=document.createElement("db-avatar");if(t.className="designbase-wc-sidebar__user-avatar-collapsed",t.setAttribute("size","s"),t.setAttribute("initials",a.name),t.setAttribute("alt",a.name),a.avatar&&t.setAttribute("src",a.avatar),e.append(t),!this.userMenuOpen){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=a.name,t.setAttribute("role","tooltip"),e.append(t)}const s=this.createUserDropdown(i,!0);s&&e.append(s),e.addEventListener("click",e=>{i.length&&(e.target.closest(".designbase-wc-sidebar__user-dropdown")||(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render()))}),e.addEventListener("keydown",t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),e.click())}),n.append(e)}return n}render(){const e=this.getActivePanelConfig();this.syncHostClasses(),this.setAttribute("role","complementary"),this.setAttribute("aria-label","사이드바 네비게이션");const t=this.getAttribute("size")||"m",s="false"!==this.getAttribute("collapsible"),a="false"!==this.getAttribute("show-logo"),i=this.hasAttribute("collapsed"),n=this.parseUserProfile(),r=this.parseUserMenuItems(),o=this.parseBottomSections(),c=this.collectCustomNavSlots(),d=Boolean(e),l="replace"===this.resolvedPanelMode;this.replaceChildren();const u=document.createElement("div");u.className="designbase-wc-sidebar__container";const b=document.createElement("div");b.className="designbase-wc-sidebar__panel-viewport";const p=document.createElement("div");p.className="designbase-wc-sidebar__panel-track",p.dataset.active=d&&l?"main":d?"panel":"main";const m=document.createElement("div");m.className=["designbase-wc-sidebar__panel-slide","designbase-wc-sidebar__panel-slide--main"].join(" "),m.dataset.panel="main";const h=d&&l;m.toggleAttribute("inert",h),m.setAttribute("aria-hidden",String(h));const g=this.createMainHeader({size:t,collapsible:s,showLogo:a,collapsed:i});if(g&&m.append(g),m.append(this.createNavWrapper({mode:"main",collapsed:i,includeProjects:"back"!==this.headerType,includeBottom:o.length>0})),m.append(this.createFooter({collapsed:i,userProfile:n,userMenuItems:r})),p.append(m),e){const t=document.createElement("div");t.className=["designbase-wc-sidebar__panel-slide","designbase-wc-sidebar__panel-slide--secondary"].join(" "),t.dataset.panel=e.id,t.setAttribute("aria-hidden","false"),t.append(this.createPanelHeader(e)),t.append(this.createNavWrapper({mode:"panel",collapsed:!1,includeProjects:!1,includeBottom:!1,panel:e})),p.append(t)}b.append(p),u.append(b),this.append(u),this.renderNav(),this.renderBottomNav(),this.projectCustomNavSlots(c),d&&l&&requestAnimationFrame(()=>{this.isConnected&&this.activePanel===e?.id&&(p.dataset.active="panel")})}}customElements.get("db-sidebar")||customElements.define("db-sidebar",DbSidebar);export{DbSidebar};
1
+ import{createDbIcon as e,isDbIconName as t}from"./db-icons.js";import{sanitizeHref as s}from"../core/safe-url.js";import{SIDEBAR_CUSTOM_NAV_SLOTS as a,SIDEBAR_PANEL_MODES as i,SIDEBAR_SIZES as n,SIDEBAR_THEMES as r,SIDEBAR_POSITIONS as o,SIDEBAR_VARIANTS as c}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const d="240px";class DbSidebar extends HTMLElement{constructor(){super(...arguments),this.expandedItems=new Set,this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.flyoutCloseTimer=null,this.userFlyoutCloseTimer=null,this.outsideHandler=null,this.panelMediaQuery=null,this.panelMediaHandler=null,this.resolvedPanelMode="adjacent"}collectCustomNavSlots(){const e=new Map;return a.forEach(t=>{const s=Array.from(this.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t),a=Array.from(this.querySelectorAll(`[data-sidebar-slot="${t}"]`)).flatMap(e=>Array.from(e.children).filter(e=>e instanceof HTMLElement&&e.getAttribute("slot")===t));e.set(t,[...new Set([...s,...a])])}),e}createCustomNavSlot(e){const t=document.createElement("div");return t.className=["designbase-wc-sidebar__custom-slot",`designbase-wc-sidebar__custom-slot--${e}`].join(" "),t.dataset.sidebarSlot=e,t}projectCustomNavSlots(e){a.forEach(t=>{const s=this.querySelector(`[data-sidebar-slot="${t}"]`),a=e.get(t)??[];s&&0!==a.length?s.append(...a):s?.remove()})}static get observedAttributes(){return["items","sections","user-menu-items","user-profile","default-expanded-ids","projects","selected-project-id","project-manage-label","project-manage-href","project-section-label","project-empty-label","project-empty-trigger-label","bottom-items","bottom-sections","promo-banner","update-banner","header-type","back-label","back-href","panels","settings-sections","active-panel","panel-mode","panel-width","panel-breakpoint","size","theme","variant","position","collapsed","collapsible","show-logo","logo-type","logo-text","full-height","shadow"]}connectedCallback(){this.seedExpanded(),this.bindPanelMediaQuery(),this.render(),this.bindOutsideClick()}disconnectedCallback(){this.unbindOutsideClick(),this.unbindPanelMediaQuery(),this.cancelFlyoutClose(),this.cancelUserFlyoutClose()}attributeChangedCallback(e,t,s){if(this.isConnected&&t!==s&&("default-expanded-ids"===e&&this.seedExpanded(),"collapsed"===e&&this.hasAttribute("collapsed")&&(this.userMenuOpen=!1,this.projectMenuOpen=!1,this.flyoutItemId=null,this.userFlyoutItemId=null,this.cancelFlyoutClose(),this.cancelUserFlyoutClose()),"panel-mode"!==e&&"panel-breakpoint"!==e||this.bindPanelMediaQuery(),this.render(),"active-panel"===e)){const e=this.getActivePanelConfig();this.dispatchEvent(new CustomEvent("db-panel-change",{bubbles:!0,composed:!0,detail:{panel:e?.id??"main",panelConfig:e,mode:this.resolvedPanelMode}}))}}bindPanelMediaQuery(){this.unbindPanelMediaQuery();const e=this.panelMode;if("auto"!==e)return void(this.resolvedPanelMode=e);if("undefined"==typeof window||"function"!=typeof window.matchMedia)return void(this.resolvedPanelMode="adjacent");const t=window.matchMedia(`(min-width: ${this.panelBreakpoint}px)`);this.panelMediaQuery=t,this.resolvedPanelMode=t.matches?"adjacent":"replace",this.panelMediaHandler=e=>{const t=e.matches?"adjacent":"replace";t!==this.resolvedPanelMode&&(this.resolvedPanelMode=t,this.render(),this.dispatchEvent(new CustomEvent("db-panel-mode-change",{bubbles:!0,composed:!0,detail:{mode:t}})))},t.addEventListener("change",this.panelMediaHandler)}unbindPanelMediaQuery(){this.panelMediaQuery&&this.panelMediaHandler&&this.panelMediaQuery.removeEventListener("change",this.panelMediaHandler),this.panelMediaQuery=null,this.panelMediaHandler=null}seedExpanded(){try{const e=JSON.parse(this.getAttribute("default-expanded-ids")||"[]");Array.isArray(e)&&(this.expandedItems=new Set(e))}catch{this.expandedItems=new Set}}get items(){try{const e=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get sections(){return this.parseSections()}set sections(e){this.setAttribute("sections","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseUserMenuItems()}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}get projects(){return this.parseProjects()}set projects(e){this.setAttribute("projects","string"==typeof e?e:JSON.stringify(e))}get selectedProjectId(){return this.getAttribute("selected-project-id")||""}set selectedProjectId(e){e?this.setAttribute("selected-project-id",e):this.removeAttribute("selected-project-id")}get projectManageLabel(){return this.getAttribute("project-manage-label")||"프로젝트 관리"}set projectManageLabel(e){this.setAttribute("project-manage-label",e)}get projectManageHref(){return this.getAttribute("project-manage-href")||""}set projectManageHref(e){e?this.setAttribute("project-manage-href",e):this.removeAttribute("project-manage-href")}get projectSectionLabel(){return this.getAttribute("project-section-label")||"프로젝트"}set projectSectionLabel(e){this.setAttribute("project-section-label",e)}get projectEmptyLabel(){return this.getAttribute("project-empty-label")||"프로젝트를 추가해 주세요"}set projectEmptyLabel(e){this.setAttribute("project-empty-label",e)}get projectEmptyTriggerLabel(){return this.getAttribute("project-empty-trigger-label")||"프로젝트 추가"}set projectEmptyTriggerLabel(e){this.setAttribute("project-empty-trigger-label",e)}get bottomItems(){return this.parseBottomItems()}set bottomItems(e){this.setAttribute("bottom-items","string"==typeof e?e:JSON.stringify(e))}get bottomSections(){return this.parseBottomSections()}set bottomSections(e){this.setAttribute("bottom-sections","string"==typeof e?e:JSON.stringify(e))}get promoBanner(){return this.parsePromoBanner()}set promoBanner(e){null==e?this.removeAttribute("promo-banner"):this.setAttribute("promo-banner","string"==typeof e?e:JSON.stringify(e))}get updateBanner(){return this.parseUpdateBanner()}set updateBanner(e){null==e?this.removeAttribute("update-banner"):this.setAttribute("update-banner","string"==typeof e?e:JSON.stringify(e))}get headerType(){return"back"===this.getAttribute("header-type")?"back":"default"}set headerType(e){this.setAttribute("header-type",e)}get backLabel(){return this.getAttribute("back-label")||"뒤로가기"}set backLabel(e){this.setAttribute("back-label",e)}get backHref(){return this.getAttribute("back-href")||""}set backHref(e){e?this.setAttribute("back-href",e):this.removeAttribute("back-href")}get panels(){return this.parsePanels()}set panels(e){this.setAttribute("panels","string"==typeof e?e:JSON.stringify(e))}get settingsSections(){return this.parseSettingsSections()}set settingsSections(e){this.setAttribute("settings-sections","string"==typeof e?e:JSON.stringify(e))}get activePanel(){const e=this.getAttribute("active-panel")||"main";return"main"===e?"main":this.findPanel(e)?e:"main"}set activePanel(e){const t=e&&"main"!==e&&this.findPanel(e)?e:"main";this.setAttribute("active-panel",t)}get panelMode(){const e=this.getAttribute("panel-mode")||"auto";return i.includes(e)?e:"auto"}set panelMode(e){this.setAttribute("panel-mode",i.includes(e)?e:"auto")}get panelWidth(){return this.normalizeCssLength(this.getAttribute("panel-width")||d)}set panelWidth(e){this.setAttribute("panel-width",this.normalizeCssLength(e))}get panelBreakpoint(){const e=Number(this.getAttribute("panel-breakpoint"));return Number.isFinite(e)&&e>0?e:1024}set panelBreakpoint(e){const t=Number.isFinite(e)&&e>0?Math.round(e):1024;this.setAttribute("panel-breakpoint",String(t))}normalizeCssLength(e){if("number"==typeof e)return`${Math.max(0,e)}px`;const t=String(e??"").trim();return t?/^-?\d+(?:\.\d+)?$/.test(t)?`${Math.max(0,Number(t))}px`:t:d}parseSettingsSections(){try{const e=JSON.parse(this.getAttribute("settings-sections")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parsePanels(){let e=[];const t=this.getAttribute("panels");if(t)try{const s=JSON.parse(t);Array.isArray(s)&&(e=s.filter(e=>Boolean(e&&"string"==typeof e.id&&e.id.trim())).map(e=>({...e,id:e.id.trim(),title:String(e.title||e.id).trim(),sections:Array.isArray(e.sections)?e.sections:[]})))}catch{e=[]}const s=this.parseSettingsSections();return s.length&&!e.some(e=>"settings"===e.id)&&e.push({id:"settings",title:"Settings",backLabel:this.backLabel,sections:s}),e}hasPanels(){return this.parsePanels().length>0}findPanel(e){return e&&"main"!==e?this.parsePanels().find(t=>t.id===e)??null:null}getActivePanelConfig(){return this.findPanel(this.getAttribute("active-panel")||"main")}parseSections(){const e=this.getAttribute("sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}try{const e=JSON.parse(this.getAttribute("items")||"[]");return[{id:"main",items:Array.isArray(e)?e:[]}]}catch{return[{id:"main",items:[]}]}}parseUserMenuItems(){try{const e=JSON.parse(this.getAttribute("user-menu-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseProjects(){try{const e=JSON.parse(this.getAttribute("projects")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomItems(){try{const e=JSON.parse(this.getAttribute("bottom-items")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}parseBottomSections(){const e=this.getAttribute("bottom-sections");if(e)try{const t=JSON.parse(e);if(Array.isArray(t)&&t.length)return t}catch{}const t=this.parseBottomItems();return t.length?[{id:"bottom",items:t}]:[]}parsePromoBanner(){const e=this.getAttribute("promo-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}parseUpdateBanner(){const e=this.getAttribute("update-banner");if(!e)return null;try{return JSON.parse(e)}catch{return null}}getSelectedProject(){const e=this.parseProjects();if(!e.length)return null;const t=this.selectedProjectId;return e.find(e=>e.id===t)||e[0]}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{const t=e.target;if(this.contains(t))return;let s=!1;this.userMenuOpen&&(this.userMenuOpen=!1,this.userFlyoutItemId=null,s=!0),this.projectMenuOpen&&(this.projectMenuOpen=!1,s=!0),s&&this.render()},document.addEventListener("mousedown",this.outsideHandler))}closeOverlayMenus(){const e=this.projectMenuOpen,t=this.userMenuOpen;if(!e&&!t)return!1;this.projectMenuOpen=!1,this.userMenuOpen=!1,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.classList.remove("designbase-wc-sidebar--user-menu-open"),this.querySelector(".designbase-wc-sidebar__project-dropdown")?.remove(),this.querySelector(".designbase-wc-sidebar__project-selector")?.classList.remove("designbase-wc-sidebar__project-selector--open");const s=this.querySelector(".designbase-wc-sidebar__project-trigger");s?.setAttribute("aria-expanded","false");const a=this.querySelector(".designbase-wc-sidebar__user-dropdown");return a&&(a.hidden=!0),this.querySelector(".designbase-wc-sidebar__user-info")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.setAttribute("aria-expanded","false"),this.querySelector(".designbase-wc-sidebar__user-collapsed")?.classList.remove("designbase-wc-sidebar__user-collapsed--open"),!0}syncExclusiveAccordion(e){[...Array.from(this.querySelectorAll(".designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item")),...Array.from(this.querySelectorAll(".designbase-wc-sidebar__bottom-nav .designbase-wc-sidebar__nav-list > .designbase-wc-sidebar__item > db-menu-item"))].forEach(t=>{const s=t.getAttribute("data-item-id");s&&(e&&s===e?t.setAttribute("expanded",""):t.removeAttribute("expanded"))})}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}cancelFlyoutClose(){this.flyoutCloseTimer&&(clearTimeout(this.flyoutCloseTimer),this.flyoutCloseTimer=null)}showFlyout(e){this.cancelFlyoutClose(),this.flyoutItemId!==e&&(this.flyoutItemId=e,this.renderNav(),this.renderBottomNav())}scheduleFlyoutClose(){this.cancelFlyoutClose(),this.flyoutCloseTimer=setTimeout(()=>{this.flyoutCloseTimer=null,this.flyoutItemId=null,this.renderNav(),this.renderBottomNav()},120)}cancelUserFlyoutClose(){this.userFlyoutCloseTimer&&(clearTimeout(this.userFlyoutCloseTimer),this.userFlyoutCloseTimer=null)}setUserFlyout(e){this.cancelUserFlyoutClose(),this.userFlyoutItemId=e,this.querySelectorAll(".designbase-wc-sidebar__user-menu-item").forEach(t=>{const s=Boolean(e&&t.dataset.itemId===e);t.classList.toggle("designbase-wc-sidebar__user-menu-item--flyout-active",s),t.querySelector(".designbase-wc-sidebar__user-menu-trigger")?.setAttribute("aria-expanded",String(s));const a=t.querySelector(".designbase-wc-sidebar__user-flyout");a&&(a.hidden=!s)})}scheduleUserFlyoutClose(){this.cancelUserFlyoutClose(),this.userFlyoutCloseTimer=setTimeout(()=>{this.userFlyoutCloseTimer=null,this.setUserFlyout(null)},120)}syncHostClasses(){const e=this.getAttribute("size")||"m",t=this.getAttribute("theme")||"default",s=this.getAttribute("variant")||"default",a=this.getAttribute("position")||"left",i=this.getActivePanelConfig(),d=Boolean(i),l=this.panelWidth;this.style.setProperty("--db-sidebar-panel-width",l),this.className=["designbase-wc-sidebar",`designbase-wc-sidebar--${n.includes(e)?e:"m"}`,`designbase-wc-sidebar--${r.includes(t)?t:"default"}`,`designbase-wc-sidebar--${o.includes(a)?a:"left"}`,`designbase-wc-sidebar--panel-${this.resolvedPanelMode}`,c.includes(s)&&"wrapper"===s&&"designbase-wc-sidebar--wrapper",this.hasAttribute("collapsed")&&"designbase-wc-sidebar--collapsed",this.hasAttribute("full-height")&&"designbase-wc-sidebar--full-height",this.hasAttribute("shadow")&&"designbase-wc-sidebar--shadow",this.userMenuOpen&&"designbase-wc-sidebar--user-menu-open",("back"===this.headerType||d&&"replace"===this.resolvedPanelMode)&&"designbase-wc-sidebar--header-back",d&&"designbase-wc-sidebar--panel-open",this.hasPanels()&&"designbase-wc-sidebar--has-panels"].filter(Boolean).join(" ")}navigateToPanel(e){const t="main"!==e&&e?this.findPanel(e)?.id:"main";t&&this.activePanel!==t&&("main"!==t&&"replace"===this.resolvedPanelMode&&this.hasAttribute("collapsed")&&this.removeAttribute("collapsed"),this.setAttribute("active-panel",t))}dispatchItemClick(e){this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchUserMenuItemClick(e){this.dispatchEvent(new CustomEvent("db-user-menu-item-click",{bubbles:!0,composed:!0,detail:{item:e}}))}dispatchBackClick(){const e=this.getActivePanelConfig();e&&this.navigateToPanel("main");const t=new CustomEvent("db-back-click",{bubbles:!0,composed:!0,cancelable:!0,detail:{label:e?.backLabel||this.backLabel,href:this.backHref,panel:e}});this.dispatchEvent(t);const a=s(this.backHref,"");t.defaultPrevented||e||!a||"back"!==this.headerType||window.location.assign(a)}dispatchProjectChange(e){this.dispatchEvent(new CustomEvent("db-project-change",{bubbles:!0,composed:!0,detail:{project:e}}))}dispatchProjectManage(){this.dispatchEvent(new CustomEvent("db-project-manage",{bubbles:!0,composed:!0,detail:{}}))}dispatchPromoCtaClick(e){this.dispatchEvent(new CustomEvent("db-promo-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}dispatchUpdateCtaClick(e){this.dispatchEvent(new CustomEvent("db-update-cta-click",{bubbles:!0,composed:!0,detail:{banner:e}}))}createProjectAvatar(e,t="s"){const s=document.createElement("db-avatar");if(s.className="designbase-wc-sidebar__project-avatar",s.setAttribute("size",t),s.setAttribute("initials",(e.label||"?").trim()),s.setAttribute("alt",e.label),e.color){const applyColor=()=>{const t=s.querySelector(".designbase-wc-avatar__initials");return!!t&&(t.style.backgroundColor=e.color,t.style.color="#fff",!0)},t=new MutationObserver(()=>{applyColor()&&t.disconnect()});t.observe(s,{childList:!0,subtree:!0}),queueMicrotask(()=>{applyColor()&&t.disconnect()})}return s}createProjectEmptyMark(t="s"){const s=document.createElement("span");return s.className=["designbase-wc-sidebar__project-mark",`designbase-wc-sidebar__project-mark--${t}`,"designbase-wc-sidebar__project-mark--empty"].join(" "),s.setAttribute("aria-hidden","true"),s.append(e("plus","m"===t?16:14)),s}createProjectBadge(e){if(!e.badge)return null;const t=document.createElement("db-badge");return t.className="designbase-wc-sidebar__project-badge",t.setAttribute("size","s"),t.setAttribute("variant",e.badgeColor||"warning"),t.setAttribute("type","text"),t.textContent=e.badge,t}createProjectSelector(t){if(!this.hasAttribute("projects"))return null;const a=this.parseProjects(),i=0===a.length,n=this.getSelectedProject(),r=document.createElement("div");r.className=["designbase-wc-sidebar__project-selector",t&&"designbase-wc-sidebar__project-selector--collapsed",this.projectMenuOpen&&"designbase-wc-sidebar__project-selector--open",i&&"designbase-wc-sidebar__project-selector--empty"].filter(Boolean).join(" ");const o=this.getAttribute("project-section-label");if(!t&&o&&o.trim()){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-section-label",e.textContent=o.trim(),r.append(e)}const c=document.createElement("button");if(c.type="button",c.className="designbase-wc-sidebar__project-trigger",c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded",String(this.projectMenuOpen)),i||!n){if(c.setAttribute("aria-label",this.projectEmptyTriggerLabel),c.append(this.createProjectEmptyMark(t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=this.projectEmptyTriggerLabel,c.append(e)}}else if(c.setAttribute("aria-label",n.label),c.append(this.createProjectAvatar(n,t?"m":"s")),!t){const e=document.createElement("span");e.className="designbase-wc-sidebar__project-label",e.textContent=n.label,c.append(e)}const d=document.createElement("span");if(d.className="designbase-wc-sidebar__project-chevron",d.setAttribute("aria-hidden","true"),d.append(e("chevron-down",14)),c.append(d),c.addEventListener("click",()=>{this.projectMenuOpen=!this.projectMenuOpen,this.userMenuOpen=!1,this.render()}),r.append(c),this.projectMenuOpen){const t=document.createElement("div");if(t.className="designbase-wc-sidebar__project-dropdown",t.setAttribute("role","menu"),t.setAttribute("aria-label",this.projectSectionLabel),i){const e=document.createElement("div");e.className="designbase-wc-sidebar__project-empty",e.setAttribute("role","presentation");const s=document.createElement("p");s.className="designbase-wc-sidebar__project-empty-text",s.textContent=this.projectEmptyLabel,e.append(s),t.append(e)}else{const e=document.createElement("ul");e.className="designbase-wc-sidebar__project-list",a.forEach(t=>{const s=document.createElement("li");s.className="designbase-wc-sidebar__project-option";const a=document.createElement("button");a.type="button",a.className=["designbase-wc-sidebar__project-option-btn",n&&t.id===n.id&&"designbase-wc-sidebar__project-option-btn--active"].filter(Boolean).join(" "),a.setAttribute("role","menuitem"),a.append(this.createProjectAvatar(t,"s"));const i=document.createElement("span");i.className="designbase-wc-sidebar__project-option-label",i.textContent=t.label,a.append(i);const r=this.createProjectBadge(t);r&&a.append(r),a.addEventListener("click",()=>{this.projectMenuOpen=!1,this.setAttribute("selected-project-id",t.id),this.dispatchProjectChange(t),this.render()}),s.append(a),e.append(s)}),t.append(e)}const o=document.createElement("button");o.type="button",o.className="designbase-wc-sidebar__project-manage",o.setAttribute("role","menuitem"),o.append(e("plus",14));const c=document.createElement("span");c.textContent=this.projectManageLabel,o.append(c),o.addEventListener("click",()=>{this.projectMenuOpen=!1;const e=this.projectManageHref,t=s(e,"");t&&window.location.assign(t),this.dispatchProjectManage(),this.render()}),t.append(o),r.append(t)}return r}createFlyout(e,t){const a=this.getAttribute("position")||"left",i=document.createElement("div");i.className=["designbase-wc-sidebar__flyout","right"===a&&"designbase-wc-sidebar__flyout--align-left"].filter(Boolean).join(" "),i.setAttribute("role","menu"),i.setAttribute("aria-label",`${e.label} 하위 메뉴`),i.addEventListener("mouseenter",()=>this.cancelFlyoutClose()),i.addEventListener("mouseleave",()=>this.scheduleFlyoutClose());const n=document.createElement("div");n.className="designbase-wc-sidebar__flyout-title",n.textContent=e.label,i.append(n);const r=document.createElement("ul");return r.className="designbase-wc-sidebar__flyout-list",(e.children||[]).forEach(e=>{const a=document.createElement("li");a.className="designbase-wc-sidebar__flyout-item";const i=document.createElement("db-menu-item");i.setAttribute("label",e.label),i.setAttribute("type","block"),i.setAttribute("menu-style","dropdown"),i.setAttribute("size",t);const n=s(e.href,"");n&&i.setAttribute("href",n),e.active&&i.setAttribute("active",""),e.disabled&&i.setAttribute("disabled",""),void 0!==e.badge&&i.setAttribute("badge",String(e.badge)),e.badgeColor&&i.setAttribute("badge-color",e.badgeColor),i.addEventListener("db-click",()=>{e.disabled||(this.flyoutItemId=null,this.dispatchItemClick(e),this.renderNav(),this.renderBottomNav())}),a.append(i),r.append(a)}),i.append(r),i}createSidebarMenuItem(e,t,a=0){const i=Boolean(e.children?.length),n=this.expandedItems.has(e.id),r=this.hasAttribute("collapsed"),o=r&&i,c=document.createElement("li");c.className=["designbase-wc-sidebar__item",o&&this.flyoutItemId===e.id&&"designbase-wc-sidebar__item--flyout-active"].filter(Boolean).join(" "),o&&(c.addEventListener("mouseenter",()=>this.showFlyout(e.id)),c.addEventListener("mouseleave",()=>this.scheduleFlyoutClose()));const d=document.createElement("db-menu-item");d.setAttribute("data-item-id",e.id),d.setAttribute("label",e.label),d.setAttribute("type","block"),d.setAttribute("menu-style","accordion"),d.setAttribute("size",t),d.setAttribute("depth",String(a));const l=s(e.href,"");if(l&&d.setAttribute("href",l),e.icon&&d.setAttribute("icon",e.icon),(e.active||e.openPanel&&e.openPanel===this.activePanel)&&d.setAttribute("active",""),e.disabled&&d.setAttribute("disabled",""),void 0!==e.badge&&d.setAttribute("badge",String(e.badge)),e.badgeColor&&d.setAttribute("badge-color",e.badgeColor),i&&!o&&(d.setAttribute("expandable",""),d.subItems=(e.children||[]).map(e=>({id:e.id,label:e.label,href:e.href,active:e.active,disabled:e.disabled,badge:e.badge,badgeColor:e.badgeColor})),n&&!r&&d.setAttribute("expanded","")),d.addEventListener("db-click",t=>{if(!e.disabled){if(i&&!r){const s=t.detail?.expanded??!this.expandedItems.has(e.id);return this.closeOverlayMenus(),void(s?(this.expandedItems.clear(),this.expandedItems.add(e.id),this.syncExclusiveAccordion(e.id)):(this.expandedItems.delete(e.id),this.syncExclusiveAccordion(null)))}if(o)return this.closeOverlayMenus(),void this.showFlyout(e.id);if(this.closeOverlayMenus(),e.openPanel&&this.findPanel(e.openPanel))return this.dispatchItemClick(e),void this.navigateToPanel(e.openPanel);this.dispatchItemClick(e)}}),d.addEventListener("db-child-click",e=>{const t=e.detail;this.dispatchItemClick(t.child)}),c.append(d),r&&void 0!==e.badge&&null!==e.badge&&""!==e.badge){const t=e.badgeColor||"primary",s=document.createElement("span");s.className=["designbase-wc-sidebar__collapsed-badge-dot",`designbase-wc-sidebar__collapsed-badge-dot--${t}`].join(" "),s.setAttribute("aria-hidden","true"),c.append(s)}if(r&&!i){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=e.label,t.setAttribute("role","tooltip"),c.append(t)}return o&&this.flyoutItemId===e.id&&c.append(this.createFlyout(e,t)),c}renderSectionList(e,t,s){const a=document.createDocumentFragment();return e.forEach(e=>{const i=document.createElement("div");if(i.className=["designbase-wc-sidebar__section",e.gap&&`designbase-wc-sidebar__section--gap-${e.gap}`].filter(Boolean).join(" "),!s&&e.title){const t=document.createElement("div");t.className="designbase-wc-sidebar__section-title",t.textContent=e.title,i.append(t)}const n=document.createElement("ul");n.className="designbase-wc-sidebar__nav-list",e.items.forEach(e=>n.append(this.createSidebarMenuItem(e,t))),i.append(n),a.append(i)}),a}renderNav(){const e=this.getAttribute("size")||"m",t=this.hasAttribute("collapsed"),s=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="main"]');s&&s.replaceChildren(this.renderSectionList(this.parseSections(),e,t),this.createCustomNavSlot("nav"));const a=this.getActivePanelConfig(),i=this.querySelector('.designbase-wc-sidebar__nav[data-panel-nav="panel"]');i&&a&&i.replaceChildren(this.renderSectionList(a.sections,e,!1))}renderBottomNav(){const e=this.querySelector(".designbase-wc-sidebar__bottom-nav");if(!e)return;const t=this.getAttribute("size")||"m",s=this.hasAttribute("collapsed");e.replaceChildren(this.renderSectionList(this.parseBottomSections(),t,s))}createUserDropdown(a,i=!1){if(!a.length)return null;const n=this.getAttribute("position")||"left",r=document.createElement("div");r.className=["designbase-wc-sidebar__user-dropdown",i&&"designbase-wc-sidebar__user-dropdown--collapsed"].filter(Boolean).join(" "),r.setAttribute("role","menu"),r.setAttribute("aria-label","사용자 메뉴"),r.hidden=!this.userMenuOpen,r.addEventListener("keydown",e=>{"Escape"===e.key&&(e.stopPropagation(),this.userFlyoutItemId?this.setUserFlyout(null):(this.userMenuOpen=!1,this.render()))});const o=document.createElement("ul");return o.className="designbase-wc-sidebar__user-menu",a.forEach(a=>{const i=Boolean(a.children?.length),r=document.createElement("li");r.dataset.itemId=a.id,r.className=["designbase-wc-sidebar__user-menu-item",a.dividerBefore&&"designbase-wc-sidebar__user-menu-item--divider",a.disabled&&"designbase-wc-sidebar__user-menu-item--disabled",i&&"designbase-wc-sidebar__user-menu-item--has-children"].filter(Boolean).join(" ");const c=document.createElement("button");if(c.type="button",c.className="designbase-wc-sidebar__user-menu-trigger",c.setAttribute("role","menuitem"),c.disabled=Boolean(a.disabled),a.icon&&t(a.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(a.icon,16)),c.append(t)}const d=document.createElement("span");if(d.className="designbase-wc-sidebar__user-menu-label",d.textContent=a.label,c.append(d),a.value){const e=document.createElement("span");e.className="designbase-wc-sidebar__user-menu-value",e.textContent=a.value,c.append(e)}if(i){const i=document.createElement("span");i.className="designbase-wc-sidebar__user-menu-chevron",i.setAttribute("aria-hidden","true"),i.append(e("right"===n?"chevron-left":"chevron-right",16)),c.append(i),c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded",String(this.userFlyoutItemId===a.id));const openFlyout=()=>this.setUserFlyout(a.id);r.addEventListener("mouseenter",openFlyout),r.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose()),r.addEventListener("focusin",openFlyout),r.addEventListener("focusout",e=>{const t=e.relatedTarget;t&&r.contains(t)||this.scheduleUserFlyoutClose()}),c.addEventListener("click",openFlyout);const o=document.createElement("div");o.className=["designbase-wc-sidebar__user-flyout","right"===n&&"designbase-wc-sidebar__user-flyout--align-left"].filter(Boolean).join(" "),o.setAttribute("role","menu"),o.setAttribute("aria-label",`${a.label} 하위 메뉴`),o.hidden=this.userFlyoutItemId!==a.id,o.addEventListener("mouseenter",()=>this.cancelUserFlyoutClose()),o.addEventListener("mouseleave",()=>this.scheduleUserFlyoutClose());const d=document.createElement("ul");d.className="designbase-wc-sidebar__user-flyout-list",(a.children||[]).forEach(a=>{const i=document.createElement("li");i.className="designbase-wc-sidebar__user-flyout-item";const n=document.createElement("button");if(n.type="button",n.className=["designbase-wc-sidebar__user-menu-trigger","designbase-wc-sidebar__user-flyout-trigger",a.selected&&"designbase-wc-sidebar__user-flyout-trigger--selected"].filter(Boolean).join(" "),n.setAttribute("role","menuitemradio"),n.setAttribute("aria-checked",String(Boolean(a.selected))),n.disabled=Boolean(a.disabled),a.icon&&t(a.icon)){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-icon",t.setAttribute("aria-hidden","true"),t.append(e(a.icon,16)),n.append(t)}const r=document.createElement("span");if(r.className="designbase-wc-sidebar__user-menu-label",r.textContent=a.label,n.append(r),a.selected){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-menu-check",t.setAttribute("aria-hidden","true"),t.append(e("done",16)),n.append(t)}n.addEventListener("click",()=>{if(a.disabled)return;this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(a);const e=s(a.href,"");e&&window.location.assign(e),this.render()}),i.append(n),d.append(i)}),o.append(d),r.append(c,o)}else c.addEventListener("click",()=>{if(a.disabled)return;this.userFlyoutItemId=null,this.userMenuOpen=!1,this.dispatchUserMenuItemClick(a);const e=s(a.href,"");e&&window.location.assign(e),this.render()}),r.append(c);o.append(r)}),r.append(o),r}createUpdateBanner(e){if("back"===this.headerType)return null;const t=this.parseUpdateBanner();if(!t)return null;if(e)return null;const a=document.createElement("div");a.className="designbase-wc-sidebar__update";const i=document.createElement("db-banner");return i.className="designbase-wc-sidebar__update-banner",i.setAttribute("size","s"),i.setAttribute("variant",t.variant||"outline"),i.setAttribute("title",t.title),t.description&&i.setAttribute("description",t.description),t.icon&&i.setAttribute("icon",t.icon),i.setAttribute("clickable",""),i.setAttribute("aria-label",t.ctaLabel||t.title),i.addEventListener("db-click",()=>{const e=s(t.ctaHref,"");e&&window.location.assign(e),this.dispatchUpdateCtaClick(t)}),a.append(i),a}createPromoBanner(a){if("back"===this.headerType)return null;const i=this.parsePromoBanner();if(!i)return null;if(a){const s=document.createElement("button");s.type="button",s.className="designbase-wc-sidebar__promo-collapsed",s.setAttribute("aria-label",i.ctaLabel||i.title);const a=document.createElement("db-animation-background");a.className="designbase-wc-sidebar__promo-bg",a.setAttribute("type","aurora"),a.setAttribute("theme","light"),a.setAttribute("intensity","subtle"),a.setAttribute("blur","40"),a.setAttribute("speed","4000"),a.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8"])),s.append(a),s.append(e(i.icon&&t(i.icon)?i.icon:"sparkle",18)),s.addEventListener("click",()=>this.dispatchPromoCtaClick(i));const n=document.createElement("span");n.className="designbase-wc-sidebar__item-tooltip",n.textContent=i.title,n.setAttribute("role","tooltip");const r=document.createElement("div");return r.className="designbase-wc-sidebar__promo-collapsed-wrap",r.append(s,n),r}const n=document.createElement("div");n.className="designbase-wc-sidebar__promo";const r=document.createElement("db-animation-background");r.className="designbase-wc-sidebar__promo-bg",r.setAttribute("type","aurora"),r.setAttribute("theme","light"),r.setAttribute("intensity","subtle"),r.setAttribute("blur","60"),r.setAttribute("speed","5000"),r.setAttribute("colors",JSON.stringify(["#c7d2fe","#ddd6fe","#fbcfe8","#bfdbfe"])),n.append(r);const o=document.createElement("div");o.className="designbase-wc-sidebar__promo-content";const c=document.createElement("div");c.className="designbase-wc-sidebar__promo-title-row";const d=document.createElement("span");d.className="designbase-wc-sidebar__promo-icon",d.setAttribute("aria-hidden","true"),d.append(e(i.icon&&t(i.icon)?i.icon:"sparkle",16));const l=document.createElement("div");if(l.className="designbase-wc-sidebar__promo-title",l.textContent=i.title,c.append(d,l),o.append(c),i.description){const e=document.createElement("div");e.className="designbase-wc-sidebar__promo-desc",e.textContent=i.description,o.append(e)}if(i.ctaLabel){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__promo-action",e.setAttribute("variant","secondary"),e.setAttribute("size","s"),e.setAttribute("full-width",""),e.textContent=i.ctaLabel,e.addEventListener("db-click",()=>{const e=s(i.ctaHref,"");e&&window.location.assign(e),this.dispatchPromoCtaClick(i)}),o.append(e)}return n.append(o),n}createMainHeader(t){const{size:s,collapsible:a,showLogo:i,collapsed:n}=t,r="back"===this.headerType,o="l"===s?"m":"s"===s?"xs":"s";if(!r&&!a&&(!i||n))return null;const c=document.createElement("div");if(c.className=["designbase-wc-sidebar__header",(n||!i)&&!r&&"designbase-wc-sidebar__header--collapsed-only",r&&"designbase-wc-sidebar__header--back"].filter(Boolean).join(" "),r){const t=document.createElement("button");if(t.type="button",t.className=["designbase-wc-sidebar__back",n&&"designbase-wc-sidebar__back--collapsed"].filter(Boolean).join(" "),t.setAttribute("aria-label",this.backLabel),t.append(e("chevron-left",18)),!n){const e=document.createElement("span");e.textContent=this.backLabel,t.append(e)}t.addEventListener("click",()=>this.dispatchBackClick()),c.append(t)}else if(!n&&i){const e=document.createElement("div");e.className="designbase-wc-sidebar__logo";const t=this.getAttribute("logo-type")||"designbase",s=this.getAttribute("logo-text")||"";if("custom"===t&&s){const t=document.createElement("span");t.className="designbase-wc-sidebar__logo-text",t.textContent=s,e.append(t)}else{const a=document.createElement("db-logo");a.setAttribute("type",t),a.setAttribute("size",o),s&&a.setAttribute("text",s),e.append(a)}e.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),c.append(e)}if(a&&!r){const e=document.createElement("db-button");e.className="designbase-wc-sidebar__toggle",e.setAttribute("variant","tertiary"),e.setAttribute("size","s"),e.setAttribute("icon-only",""),e.setAttribute("start-icon",n?"arrow-bar-right":"arrow-bar-left"),e.setAttribute("aria-label",n?"사이드바 펼치기":"사이드바 접기"),e.addEventListener("db-click",()=>{const e=!this.hasAttribute("collapsed");e?this.setAttribute("collapsed",""):this.removeAttribute("collapsed"),this.dispatchEvent(new CustomEvent("db-toggle",{bubbles:!0,composed:!0,detail:{collapsed:e}}))}),c.append(e)}return c}createPanelHeader(t){const s="replace"===this.resolvedPanelMode,a=document.createElement("div");if(a.className=["designbase-wc-sidebar__panel-header",s&&"designbase-wc-sidebar__panel-header--replace"].filter(Boolean).join(" "),s){const s=document.createElement("button");s.type="button",s.className="designbase-wc-sidebar__panel-back",s.setAttribute("aria-label",t.backLabel||this.backLabel),s.append(e("chevron-left",18)),s.addEventListener("click",()=>this.dispatchBackClick()),a.append(s)}const i=document.createElement("div");i.className="designbase-wc-sidebar__panel-heading";const n=document.createElement("div");if(n.className="designbase-wc-sidebar__panel-title",n.textContent=t.title,i.append(n),t.description){const e=document.createElement("div");e.className="designbase-wc-sidebar__panel-description",e.textContent=t.description,i.append(e)}return a.append(i),a}createNavWrapper(e){const{mode:t,collapsed:s,includeProjects:a,includeBottom:i,panel:n}=e,r=document.createElement("div");if(r.className="designbase-wc-sidebar__nav-wrapper",a){const e=this.createProjectSelector(s);e&&r.append(e)}"main"===t&&r.append(this.createCustomNavSlot("nav-top"));const o=document.createElement("nav");if(o.className="designbase-wc-sidebar__nav",o.setAttribute("data-panel-nav",t),n&&(o.dataset.panelId=n.id),o.setAttribute("aria-label",n?.ariaLabel||n?.title||"주 메뉴"),r.append(o),"main"===t&&r.append(this.createCustomNavSlot("nav-bottom")),i){const e=document.createElement("nav");e.className="designbase-wc-sidebar__bottom-nav",e.setAttribute("aria-label","하단 메뉴"),r.append(e)}return r}createFooter(t){const{collapsed:s,userProfile:a,userMenuItems:i}=t,n=document.createElement("div");n.className="designbase-wc-sidebar__footer";const r=this.createUpdateBanner(s);r&&n.append(r);const o=this.createPromoBanner(s);if(o&&n.append(o),a&&!s){const t=document.createElement("div");t.className="designbase-wc-sidebar__user";const s=this.createUserDropdown(i);s&&t.append(s);const r=document.createElement("div");r.className="designbase-wc-sidebar__user-info",r.setAttribute("role","button"),r.setAttribute("tabindex","0"),r.setAttribute("aria-expanded",String(this.userMenuOpen));const o=document.createElement("db-avatar");o.className="designbase-wc-sidebar__user-avatar",o.setAttribute("size","s"),o.setAttribute("initials",a.name),o.setAttribute("alt",a.name),a.avatar&&o.setAttribute("src",a.avatar);const c=document.createElement("div");c.className="designbase-wc-sidebar__user-details";const d=document.createElement("div");if(d.className="designbase-wc-sidebar__user-name",d.textContent=a.name,c.append(d),a.email){const e=document.createElement("div");e.className="designbase-wc-sidebar__user-email",e.textContent=a.email,c.append(e)}if(r.append(o,c),i.length){const t=document.createElement("span");t.className="designbase-wc-sidebar__user-more",t.setAttribute("aria-hidden","true"),t.append(e("more-vertical",16)),r.append(t),r.setAttribute("aria-haspopup","menu")}r.addEventListener("click",()=>{i.length&&(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render())}),r.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),r.click())}),t.append(r),n.append(t)}else if(a&&s){const e=document.createElement("div");e.className=["designbase-wc-sidebar__user-collapsed",this.userMenuOpen&&"designbase-wc-sidebar__user-collapsed--open"].filter(Boolean).join(" "),e.setAttribute("role","button"),e.setAttribute("tabindex","0"),e.setAttribute("aria-label",a.name),e.setAttribute("aria-expanded",String(this.userMenuOpen)),i.length&&e.setAttribute("aria-haspopup","menu");const t=document.createElement("db-avatar");if(t.className="designbase-wc-sidebar__user-avatar-collapsed",t.setAttribute("size","s"),t.setAttribute("initials",a.name),t.setAttribute("alt",a.name),a.avatar&&t.setAttribute("src",a.avatar),e.append(t),!this.userMenuOpen){const t=document.createElement("span");t.className="designbase-wc-sidebar__item-tooltip",t.textContent=a.name,t.setAttribute("role","tooltip"),e.append(t)}const s=this.createUserDropdown(i,!0);s&&e.append(s),e.addEventListener("click",e=>{i.length&&(e.target.closest(".designbase-wc-sidebar__user-dropdown")||(this.userMenuOpen=!this.userMenuOpen,this.userFlyoutItemId=null,this.cancelUserFlyoutClose(),this.projectMenuOpen=!1,this.render()))}),e.addEventListener("keydown",t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),e.click())}),n.append(e)}return n}render(){const e=this.getActivePanelConfig();this.syncHostClasses(),this.setAttribute("role","complementary"),this.setAttribute("aria-label","사이드바 네비게이션");const t=this.getAttribute("size")||"m",s="false"!==this.getAttribute("collapsible"),a="false"!==this.getAttribute("show-logo"),i=this.hasAttribute("collapsed"),n=this.parseUserProfile(),r=this.parseUserMenuItems(),o=this.parseBottomSections(),c=this.collectCustomNavSlots(),d=Boolean(e),l="replace"===this.resolvedPanelMode;this.replaceChildren();const u=document.createElement("div");u.className="designbase-wc-sidebar__container";const b=document.createElement("div");b.className="designbase-wc-sidebar__panel-viewport";const p=document.createElement("div");p.className="designbase-wc-sidebar__panel-track",p.dataset.active=d&&l?"main":d?"panel":"main";const m=document.createElement("div");m.className=["designbase-wc-sidebar__panel-slide","designbase-wc-sidebar__panel-slide--main"].join(" "),m.dataset.panel="main";const h=d&&l;m.toggleAttribute("inert",h),m.setAttribute("aria-hidden",String(h));const g=this.createMainHeader({size:t,collapsible:s,showLogo:a,collapsed:i});if(g&&m.append(g),m.append(this.createNavWrapper({mode:"main",collapsed:i,includeProjects:"back"!==this.headerType,includeBottom:o.length>0})),m.append(this.createFooter({collapsed:i,userProfile:n,userMenuItems:r})),p.append(m),e){const t=document.createElement("div");t.className=["designbase-wc-sidebar__panel-slide","designbase-wc-sidebar__panel-slide--secondary"].join(" "),t.dataset.panel=e.id,t.setAttribute("aria-hidden","false"),t.append(this.createPanelHeader(e)),t.append(this.createNavWrapper({mode:"panel",collapsed:!1,includeProjects:!1,includeBottom:!1,panel:e})),p.append(t)}b.append(p),u.append(b),this.append(u),this.renderNav(),this.renderBottomNav(),this.projectCustomNavSlots(c),d&&l&&requestAnimationFrame(()=>{this.isConnected&&this.activePanel===e?.id&&(p.dataset.active="panel")})}}customElements.get("db-sidebar")||customElements.define("db-sidebar",DbSidebar);export{DbSidebar};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";const e=["dashed","outlined"];class DbSignature extends HTMLElement{constructor(){super(...arguments),this.canvas=null,this.placeholderEl=null,this.clearButton=null,this.resizeObserver=null,this.themeObserver=null,this.strokes=[],this.redoStack=[],this.currentStroke=null,this.lastMid=null,this.lastWidth=0,this.lastVelocity=0,this.backgroundImage=null,this.activePointerId=null,this.handlePointerDown=t=>{if(!this.interactive||0!==t.button)return;t.preventDefault(),this.focus({preventScroll:!0}),this.activePointerId=t.pointerId;try{this.canvas?.setPointerCapture(t.pointerId)}catch{}this.lastVelocity=0,this.lastWidth=(this.minWidth+this.maxWidth)/2;const e=this.getPoint(t);this.currentStroke=[e],this.lastMid=e,this.dispatchEvent(new CustomEvent("db-begin",{bubbles:!0,composed:!0}))},this.handlePointerMove=t=>{if(!this.currentStroke||this.activePointerId!==t.pointerId)return;t.preventDefault();const e="function"==typeof t.getCoalescedEvents?t.getCoalescedEvents():[t];for(const t of e){const e=this.canvas.getBoundingClientRect();this.appendPoint({x:t.clientX-e.left,y:t.clientY-e.top,t:t.timeStamp||Date.now()})}},this.handlePointerUp=t=>{const e=this.currentStroke;if(!e||this.activePointerId!==t.pointerId)return;this.activePointerId=null,this.currentStroke=null;const i=this.canvas?.getContext("2d");if(i)if(1===e.length)this.drawDot(i,e[0],this.getPenColor());else{const t=e[e.length-1],s=this.lastMid??t,n=this.lastWidth||(this.minWidth+this.maxWidth)/2;this.drawCurveSegment(i,s,t,t,this.getPenColor(),n)}this.lastMid=null,this.strokes.push(e),this.redoStack=[],this.updateState(),this.dispatchEvent(new CustomEvent("db-end",{bubbles:!0,composed:!0})),this.emitChange()},this.handleClearClick=()=>{this.interactive&&(this.clear(),this.dispatchEvent(new CustomEvent("db-clear",{bubbles:!0,composed:!0})),this.emitChange())},this.handleKeyDown=t=>{if(!this.interactive)return;if(!(t.metaKey||t.ctrlKey))return;const e=t.key.toLowerCase();return"z"===e&&t.shiftKey?(t.preventDefault(),void this.redo()):"z"===e?(t.preventDefault(),void this.undo()):void("y"===e&&(t.preventDefault(),this.redo()))}}static get observedAttributes(){return["height","variant","pen-color","background-color","min-width","max-width","placeholder","show-clear","clear-label","disabled","readonly","value"]}connectedCallback(){this.render(),this.syncCanvasSize(),this.addEventListener("keydown",this.handleKeyDown),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.syncCanvasSize()),this.resizeObserver.observe(this)),"undefined"!=typeof MutationObserver&&(this.themeObserver=new MutationObserver(()=>{this.getAttribute("pen-color")||this.redraw()}),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme","data-color-mode","class"]}));const t=this.getAttribute("value");t&&this.fromDataURL(t)}disconnectedCallback(){this.removeEventListener("keydown",this.handleKeyDown),this.resizeObserver?.disconnect(),this.resizeObserver=null,this.themeObserver?.disconnect(),this.themeObserver=null}attributeChangedCallback(t,e,i){this.isConnected&&e!==i&&("value"!==t?(this.render(),this.syncCanvasSize(),this.redraw()):i?this.fromDataURL(i):this.clear())}get value(){return this.toDataURL()}set value(t){t?this.fromDataURL(t):this.clear()}getNumberAttr(t,e){const i=this.getAttribute(t);if(null===i||""===i)return e;const s=Number(i);return Number.isFinite(s)?s:e}getBooleanAttr(t,e=!1){if(!this.hasAttribute(t))return e;const i=this.getAttribute(t);return""===i||"true"===i}getVariant(){const t=this.getAttribute("variant");return t&&e.includes(t)?t:"dashed"}get minWidth(){return this.getNumberAttr("min-width",1)}get maxWidth(){return this.getNumberAttr("max-width",3.2)}get interactive(){return!this.getBooleanAttr("disabled")&&!this.getBooleanAttr("readonly")}getPenColor(){const t=this.getAttribute("pen-color");if(t)return t;return getComputedStyle(this).getPropertyValue("--db-text-primary").trim()||"#2c3542"}render(){const e=this.getVariant(),i=this.getAttribute("placeholder")??"",s=this.getBooleanAttr("show-clear",!0);if(this.className=["designbase-wc-signature",`designbase-wc-signature--${e}`,this.getBooleanAttr("disabled")&&"designbase-wc-signature--disabled",this.getBooleanAttr("readonly")&&"designbase-wc-signature--readonly",this.isEmpty()&&"designbase-wc-signature--empty"].filter(Boolean).join(" "),this.style.height=`${this.getNumberAttr("height",220)}px`,this.interactive?this.tabIndex=0:this.removeAttribute("tabindex"),this.canvas||(this.canvas=document.createElement("canvas"),this.canvas.className="designbase-wc-signature__canvas",this.canvas.setAttribute("role","img"),this.canvas.addEventListener("pointerdown",this.handlePointerDown),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerup",this.handlePointerUp),this.canvas.addEventListener("pointercancel",this.handlePointerUp),this.append(this.canvas)),this.canvas.setAttribute("aria-label",i||"서명 입력 영역"),i?(this.placeholderEl||(this.placeholderEl=document.createElement("span"),this.placeholderEl.className="designbase-wc-signature__placeholder",this.append(this.placeholderEl)),this.placeholderEl.textContent=i,this.placeholderEl.hidden=!this.isEmpty()):(this.placeholderEl?.remove(),this.placeholderEl=null),s){this.clearButton||(this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="designbase-wc-signature__clear",this.clearButton.addEventListener("click",this.handleClearClick),this.clearButton.append(t("trash",20)),this.append(this.clearButton));const e=this.getAttribute("clear-label")||"서명 지우기";this.clearButton.setAttribute("aria-label",e),this.clearButton.title=e,this.clearButton.disabled=!this.interactive||this.isEmpty()}else this.clearButton?.remove(),this.clearButton=null}updateState(){const t=this.isEmpty();this.classList.toggle("designbase-wc-signature--empty",t),this.placeholderEl&&(this.placeholderEl.hidden=!t),this.clearButton&&(this.clearButton.disabled=!this.interactive||t)}syncCanvasSize(){const t=this.canvas;if(!t)return;const e=window.devicePixelRatio||1,i=t.getBoundingClientRect();if(0===i.width||0===i.height)return;const s=Math.round(i.width*e),n=Math.round(i.height*e);t.width===s&&t.height===n||(t.width=s,t.height=n,t.getContext("2d")?.scale(e,e),this.redraw())}resetCanvas(t,e,i){t.clearRect(0,0,e,i);const s=this.getAttribute("background-color");s&&"transparent"!==s&&(t.fillStyle=s,t.fillRect(0,0,e,i)),this.backgroundImage&&t.drawImage(this.backgroundImage,0,0,e,i)}resolveWidth(t,e){const i=e.x-t.x,s=e.y-t.y,n=.55*(Math.sqrt(i*i+s*s)/Math.max(e.t-t.t,1))+(1-.55)*this.lastVelocity;this.lastVelocity=n;const{minWidth:r,maxWidth:a}=this,h=Math.min(Math.max(a/(.85*n+1),r),a),o=(this.lastWidth+h)/2;return this.lastWidth=h,o}drawCurveSegment(t,e,i,s,n,r){t.strokeStyle=n,t.lineWidth=r,t.lineCap="round",t.lineJoin="round",t.beginPath(),t.moveTo(e.x,e.y),t.quadraticCurveTo(i.x,i.y,s.x,s.y),t.stroke()}drawDot(t,e,i){t.fillStyle=i,t.beginPath(),t.arc(e.x,e.y,(this.minWidth+this.maxWidth)/4,0,2*Math.PI),t.fill()}drawStroke(t,e,i){if(this.lastVelocity=0,this.lastWidth=(this.minWidth+this.maxWidth)/2,0===e.length)return;if(1===e.length)return void this.drawDot(t,e[0],i);if(2===e.length){const s=this.resolveWidth(e[0],e[1]);return void this.drawCurveSegment(t,e[0],e[0],e[1],i,s)}let s=e[0];for(let n=1;n<e.length-1;n+=1){const r=e[n],a=e[n+1],h={x:(r.x+a.x)/2,y:(r.y+a.y)/2,t:r.t},o=this.resolveWidth(e[n-1],r);this.drawCurveSegment(t,s,r,h,i,o),s=h}const n=e[e.length-1],r=e[e.length-2],a=this.resolveWidth(r,n);this.drawCurveSegment(t,s,n,n,i,a)}redraw(){const t=this.canvas,e=t?.getContext("2d");if(!t||!e)return;const i=window.devicePixelRatio||1;this.resetCanvas(e,t.width/i,t.height/i);const s=this.getPenColor();for(const t of this.strokes)this.drawStroke(e,t,s)}getPoint(t){const e=t.currentTarget.getBoundingClientRect();return{x:t.clientX-e.left,y:t.clientY-e.top,t:t.timeStamp||Date.now()}}appendPoint(t){const e=this.currentStroke,i=this.canvas?.getContext("2d");if(!e||!i)return;const s=e[e.length-1],n=t.x-s.x,r=t.y-s.y;if(Math.sqrt(n*n+r*r)<1.5)return;e.push(t);const a=this.getPenColor(),h=this.lastMid??s,o={x:(s.x+t.x)/2,y:(s.y+t.y)/2,t:t.t},l=this.resolveWidth(s,t);this.drawCurveSegment(i,h,s,o,a,l),this.lastMid=o}emitChange(){this.dispatchEvent(new CustomEvent("db-change",{bubbles:!0,composed:!0,detail:{value:this.toDataURL()}}))}isEmpty(){return 0===this.strokes.length&&!this.backgroundImage}clear(){this.strokes=[],this.redoStack=[],this.currentStroke=null,this.lastMid=null,this.backgroundImage=null,this.redraw(),this.updateState()}undo(){if(this.currentStroke)return;if(0===this.strokes.length)return;const t=this.strokes[this.strokes.length-1];this.strokes=this.strokes.slice(0,-1),this.redoStack=[...this.redoStack,t],this.redraw(),this.updateState(),this.emitChange()}redo(){if(this.currentStroke)return;if(0===this.redoStack.length)return;const t=this.redoStack[this.redoStack.length-1];this.redoStack=this.redoStack.slice(0,-1),this.strokes=[...this.strokes,t],this.redraw(),this.updateState(),this.emitChange()}toDataURL(t="image/png",e){return!this.canvas||this.isEmpty()?null:this.canvas.toDataURL(t,e)}fromDataURL(t){const e=new Image;e.crossOrigin="anonymous",e.onload=()=>{this.backgroundImage=e,this.strokes=[],this.redoStack=[],this.redraw(),this.updateState()},e.src=t}getCanvas(){return this.canvas}}customElements.get("db-signature")||customElements.define("db-signature",DbSignature);export{DbSignature};
1
+ import{createDbIcon as t}from"./db-icons.js";import{coerceToContract as e}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{SIGNATURE_VARIANTS as i}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const s=i;class DbSignature extends HTMLElement{constructor(){super(...arguments),this.canvas=null,this.placeholderEl=null,this.clearButton=null,this.resizeObserver=null,this.themeObserver=null,this.strokes=[],this.redoStack=[],this.currentStroke=null,this.lastMid=null,this.lastWidth=0,this.lastVelocity=0,this.backgroundImage=null,this.activePointerId=null,this.handlePointerDown=t=>{if(!this.interactive||0!==t.button)return;t.preventDefault(),this.focus({preventScroll:!0}),this.activePointerId=t.pointerId;try{this.canvas?.setPointerCapture(t.pointerId)}catch{}this.lastVelocity=0,this.lastWidth=(this.minWidth+this.maxWidth)/2;const e=this.getPoint(t);this.currentStroke=[e],this.lastMid=e,this.dispatchEvent(new CustomEvent("db-begin",{bubbles:!0,composed:!0}))},this.handlePointerMove=t=>{if(!this.currentStroke||this.activePointerId!==t.pointerId)return;t.preventDefault();const e="function"==typeof t.getCoalescedEvents?t.getCoalescedEvents():[t];for(const t of e){const e=this.canvas.getBoundingClientRect();this.appendPoint({x:t.clientX-e.left,y:t.clientY-e.top,t:t.timeStamp||Date.now()})}},this.handlePointerUp=t=>{const e=this.currentStroke;if(!e||this.activePointerId!==t.pointerId)return;this.activePointerId=null,this.currentStroke=null;const i=this.canvas?.getContext("2d");if(i)if(1===e.length)this.drawDot(i,e[0],this.getPenColor());else{const t=e[e.length-1],s=this.lastMid??t,n=this.lastWidth||(this.minWidth+this.maxWidth)/2;this.drawCurveSegment(i,s,t,t,this.getPenColor(),n)}this.lastMid=null,this.strokes.push(e),this.redoStack=[],this.updateState(),this.dispatchEvent(new CustomEvent("db-end",{bubbles:!0,composed:!0})),this.emitChange()},this.handleClearClick=()=>{this.interactive&&(this.clear(),this.dispatchEvent(new CustomEvent("db-clear",{bubbles:!0,composed:!0})),this.emitChange())},this.handleKeyDown=t=>{if(!this.interactive)return;if(!(t.metaKey||t.ctrlKey))return;const e=t.key.toLowerCase();return"z"===e&&t.shiftKey?(t.preventDefault(),void this.redo()):"z"===e?(t.preventDefault(),void this.undo()):void("y"===e&&(t.preventDefault(),this.redo()))}}static get observedAttributes(){return["height","variant","pen-color","background-color","min-width","max-width","placeholder","show-clear","clear-label","disabled","readonly","value"]}connectedCallback(){this.render(),this.syncCanvasSize(),this.addEventListener("keydown",this.handleKeyDown),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.syncCanvasSize()),this.resizeObserver.observe(this)),"undefined"!=typeof MutationObserver&&(this.themeObserver=new MutationObserver(()=>{this.getAttribute("pen-color")||this.redraw()}),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme","data-color-mode","class"]}));const t=this.getAttribute("value");t&&this.fromDataURL(t)}disconnectedCallback(){this.removeEventListener("keydown",this.handleKeyDown),this.resizeObserver?.disconnect(),this.resizeObserver=null,this.themeObserver?.disconnect(),this.themeObserver=null}attributeChangedCallback(t,e,i){this.isConnected&&e!==i&&("value"!==t?(this.render(),this.syncCanvasSize(),this.redraw()):i?this.fromDataURL(i):this.clear())}get value(){return this.toDataURL()}set value(t){t?this.fromDataURL(t):this.clear()}getNumberAttr(t,e){const i=this.getAttribute(t);if(null===i||""===i)return e;const s=Number(i);return Number.isFinite(s)?s:e}getBooleanAttr(t,e=!1){if(!this.hasAttribute(t))return e;const i=this.getAttribute(t);return""===i||"true"===i}getVariant(){return e(this.getAttribute("variant"),s,"dashed")}get minWidth(){return this.getNumberAttr("min-width",1)}get maxWidth(){return this.getNumberAttr("max-width",3.2)}get interactive(){return!this.getBooleanAttr("disabled")&&!this.getBooleanAttr("readonly")}getPenColor(){const t=this.getAttribute("pen-color");if(t)return t;return getComputedStyle(this).getPropertyValue("--db-text-primary").trim()||"#2c3542"}render(){const e=this.getVariant(),i=this.getAttribute("placeholder")??"",s=this.getBooleanAttr("show-clear",!0);if(this.className=["designbase-wc-signature",`designbase-wc-signature--${e}`,this.getBooleanAttr("disabled")&&"designbase-wc-signature--disabled",this.getBooleanAttr("readonly")&&"designbase-wc-signature--readonly",this.isEmpty()&&"designbase-wc-signature--empty"].filter(Boolean).join(" "),this.style.height=`${this.getNumberAttr("height",220)}px`,this.interactive?this.tabIndex=0:this.removeAttribute("tabindex"),this.canvas||(this.canvas=document.createElement("canvas"),this.canvas.className="designbase-wc-signature__canvas",this.canvas.setAttribute("role","img"),this.canvas.addEventListener("pointerdown",this.handlePointerDown),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerup",this.handlePointerUp),this.canvas.addEventListener("pointercancel",this.handlePointerUp),this.append(this.canvas)),this.canvas.setAttribute("aria-label",i||"서명 입력 영역"),i?(this.placeholderEl||(this.placeholderEl=document.createElement("span"),this.placeholderEl.className="designbase-wc-signature__placeholder",this.append(this.placeholderEl)),this.placeholderEl.textContent=i,this.placeholderEl.hidden=!this.isEmpty()):(this.placeholderEl?.remove(),this.placeholderEl=null),s){this.clearButton||(this.clearButton=document.createElement("button"),this.clearButton.type="button",this.clearButton.className="designbase-wc-signature__clear",this.clearButton.addEventListener("click",this.handleClearClick),this.clearButton.append(t("trash",20)),this.append(this.clearButton));const e=this.getAttribute("clear-label")||"서명 지우기";this.clearButton.setAttribute("aria-label",e),this.clearButton.title=e,this.clearButton.disabled=!this.interactive||this.isEmpty()}else this.clearButton?.remove(),this.clearButton=null}updateState(){const t=this.isEmpty();this.classList.toggle("designbase-wc-signature--empty",t),this.placeholderEl&&(this.placeholderEl.hidden=!t),this.clearButton&&(this.clearButton.disabled=!this.interactive||t)}syncCanvasSize(){const t=this.canvas;if(!t)return;const e=window.devicePixelRatio||1,i=t.getBoundingClientRect();if(0===i.width||0===i.height)return;const s=Math.round(i.width*e),n=Math.round(i.height*e);t.width===s&&t.height===n||(t.width=s,t.height=n,t.getContext("2d")?.scale(e,e),this.redraw())}resetCanvas(t,e,i){t.clearRect(0,0,e,i);const s=this.getAttribute("background-color");s&&"transparent"!==s&&(t.fillStyle=s,t.fillRect(0,0,e,i)),this.backgroundImage&&t.drawImage(this.backgroundImage,0,0,e,i)}resolveWidth(t,e){const i=e.x-t.x,s=e.y-t.y,n=.55*(Math.sqrt(i*i+s*s)/Math.max(e.t-t.t,1))+(1-.55)*this.lastVelocity;this.lastVelocity=n;const{minWidth:r,maxWidth:a}=this,h=Math.min(Math.max(a/(.85*n+1),r),a),o=(this.lastWidth+h)/2;return this.lastWidth=h,o}drawCurveSegment(t,e,i,s,n,r){t.strokeStyle=n,t.lineWidth=r,t.lineCap="round",t.lineJoin="round",t.beginPath(),t.moveTo(e.x,e.y),t.quadraticCurveTo(i.x,i.y,s.x,s.y),t.stroke()}drawDot(t,e,i){t.fillStyle=i,t.beginPath(),t.arc(e.x,e.y,(this.minWidth+this.maxWidth)/4,0,2*Math.PI),t.fill()}drawStroke(t,e,i){if(this.lastVelocity=0,this.lastWidth=(this.minWidth+this.maxWidth)/2,0===e.length)return;if(1===e.length)return void this.drawDot(t,e[0],i);if(2===e.length){const s=this.resolveWidth(e[0],e[1]);return void this.drawCurveSegment(t,e[0],e[0],e[1],i,s)}let s=e[0];for(let n=1;n<e.length-1;n+=1){const r=e[n],a=e[n+1],h={x:(r.x+a.x)/2,y:(r.y+a.y)/2,t:r.t},o=this.resolveWidth(e[n-1],r);this.drawCurveSegment(t,s,r,h,i,o),s=h}const n=e[e.length-1],r=e[e.length-2],a=this.resolveWidth(r,n);this.drawCurveSegment(t,s,n,n,i,a)}redraw(){const t=this.canvas,e=t?.getContext("2d");if(!t||!e)return;const i=window.devicePixelRatio||1;this.resetCanvas(e,t.width/i,t.height/i);const s=this.getPenColor();for(const t of this.strokes)this.drawStroke(e,t,s)}getPoint(t){const e=t.currentTarget.getBoundingClientRect();return{x:t.clientX-e.left,y:t.clientY-e.top,t:t.timeStamp||Date.now()}}appendPoint(t){const e=this.currentStroke,i=this.canvas?.getContext("2d");if(!e||!i)return;const s=e[e.length-1],n=t.x-s.x,r=t.y-s.y;if(Math.sqrt(n*n+r*r)<1.5)return;e.push(t);const a=this.getPenColor(),h=this.lastMid??s,o={x:(s.x+t.x)/2,y:(s.y+t.y)/2,t:t.t},l=this.resolveWidth(s,t);this.drawCurveSegment(i,h,s,o,a,l),this.lastMid=o}emitChange(){this.dispatchEvent(new CustomEvent("db-change",{bubbles:!0,composed:!0,detail:{value:this.toDataURL()}}))}isEmpty(){return 0===this.strokes.length&&!this.backgroundImage}clear(){this.strokes=[],this.redoStack=[],this.currentStroke=null,this.lastMid=null,this.backgroundImage=null,this.redraw(),this.updateState()}undo(){if(this.currentStroke)return;if(0===this.strokes.length)return;const t=this.strokes[this.strokes.length-1];this.strokes=this.strokes.slice(0,-1),this.redoStack=[...this.redoStack,t],this.redraw(),this.updateState(),this.emitChange()}redo(){if(this.currentStroke)return;if(0===this.redoStack.length)return;const t=this.redoStack[this.redoStack.length-1];this.redoStack=this.redoStack.slice(0,-1),this.strokes=[...this.strokes,t],this.redraw(),this.updateState(),this.emitChange()}toDataURL(t="image/png",e){return!this.canvas||this.isEmpty()?null:this.canvas.toDataURL(t,e)}fromDataURL(t){const e=new Image;e.crossOrigin="anonymous",e.onload=()=>{this.backgroundImage=e,this.strokes=[],this.redoStack=[],this.redraw(),this.updateState()},e.src=t}getCanvas(){return this.canvas}}customElements.get("db-signature")||customElements.define("db-signature",DbSignature);export{DbSignature};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";import{labelFrom as e}from"../core/i18n.js";import{TABS_ORIENTATIONS as s,TABS_SIZES as i,TABS_VARIANTS as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as n}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";class DbTabs extends HTMLElement{constructor(){super(...arguments),this.tabButtons=[],this.inactivePanels=document.createDocumentFragment(),this.isRendering=!1,this.handleResize=()=>{this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.resizeRaf=requestAnimationFrame(()=>{this.isRendering||(this.handleListScroll(),this.updateIndicator(!1))})},this.handleListScroll=()=>{if(!this.list)return;const t=this.list.scrollWidth>this.list.clientWidth,e=this.list.scrollLeft+this.list.clientWidth>=this.list.scrollWidth-5;this.list.classList.toggle("designbase-wc-tabs__list--show-gradient",t&&!e&&"horizontal"===this.orientation)}}static get observedAttributes(){return["labels","items","active-index","selected-id","orientation","size","variant","full-width"]}get labels(){const t=this.tabItems.map(t=>t.label);return t.length?t:(this.getAttribute("labels")||"").split(",").map(t=>t.trim()).filter(Boolean)}set labels(t){this.setAttribute("labels",Array.isArray(t)?t.join(","):t)}get tabItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}get items(){return this.tabItems}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}set tabItems(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}get activeIndex(){const t=this.getAttribute("selected-id");if(t){const e=this.tabItems.findIndex((e,s)=>(e.id||String(s))===t);if(e>=0)return e}return Number(this.getAttribute("active-index")||0)}set activeIndex(t){this.setAttribute("active-index",String(t))}get orientation(){return n(this.getAttribute("orientation"),s,"horizontal")}set orientation(t){this.setAttribute("orientation",t)}get size(){return n(this.getAttribute("size"),i,"m")}set size(t){this.setAttribute("size",t)}get variant(){return n(this.getAttribute("variant"),a,"default")}set variant(t){this.setAttribute("variant",t)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(t){this.toggleAttribute("full-width",Boolean(t))}connectedCallback(){this.render(),this.list?.addEventListener("scroll",this.handleListScroll,{passive:!0}),window.addEventListener("resize",this.handleResize),this.resizeObserver=new ResizeObserver(()=>this.handleResize()),this.resizeObserver.observe(this),this.childObserver=new MutationObserver(t=>{if(this.isRendering)return;t.some(t=>Array.from(t.addedNodes).some(t=>t instanceof HTMLElement&&(t.hasAttribute("slot")||void 0!==t.dataset.panelIndex)))&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.list?.removeEventListener("scroll",this.handleListScroll),window.removeEventListener("resize",this.handleResize),this.resizeObserver?.disconnect(),this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.childObserver?.disconnect()}attributeChangedCallback(){this.isConnected&&this.render()}collectPanelContent(){const t=new Map,register=(e,s)=>{if(!(e instanceof HTMLElement)||"SLOT"===e.tagName)return;t.has(s)||t.set(s,[]);const i=t.get(s);i.includes(e)||i.push(e)};return Array.from(this.children).forEach(t=>{const e=t.getAttribute("slot")?.match(/^panel-(\d+)$/);if(e)return void register(t,Number(e[1]));const s=t.dataset.panelIndex;void 0!==s&&register(t,Number(s))}),this.panel?.querySelectorAll(":scope > .designbase-wc-tabs__panel-inner > [data-panel-index]").forEach(t=>{t instanceof HTMLElement&&register(t,Number(t.dataset.panelIndex))}),Array.from(this.inactivePanels.children).forEach(t=>{t instanceof HTMLElement&&void 0!==t.dataset.panelIndex&&register(t,Number(t.dataset.panelIndex))}),t}render(){this.isRendering=!0;const s=this.collectPanelContent(),i=this.labels,a=this.tabItems,n=Math.min(Math.max(this.activeIndex,0),Math.max(i.length-1,0)),r=this.size,l=this.orientation,o=this.variant,d="default"===o;this.className=["designbase-wc-tabs",`designbase-wc-tabs--${l}`,`designbase-wc-tabs--${r}`,`designbase-wc-tabs--${o}`,this.fullWidth&&"designbase-wc-tabs--full-width"].filter(Boolean).join(" "),this.querySelectorAll(":scope > .designbase-wc-tabs__list, :scope > .designbase-wc-tabs__panel").forEach(t=>t.remove()),this.list=document.createElement("div"),this.list.className=["designbase-wc-tabs__list",`designbase-wc-tabs__list--${l}`,this.fullWidth&&"designbase-wc-tabs__list--full-width"].filter(Boolean).join(" "),this.list.setAttribute("role","tablist"),this.list.setAttribute("aria-orientation",l),this.list.setAttribute("aria-label",e(this,"label-tablist","tabs.label")),this.tabButtons=[],i.forEach((e,s)=>{const i=a[s],l=Boolean(i?.disabled),o=s===n,d=document.createElement("button");if(d.type="button",d.className=["designbase-wc-tabs__tab",o&&"designbase-wc-tabs__tab--selected",l&&"designbase-wc-tabs__tab--disabled"].filter(Boolean).join(" "),d.setAttribute("role","tab"),d.setAttribute("aria-selected",String(o)),d.setAttribute("aria-controls",`panel-${s}`),d.id=`tab-${s}`,d.tabIndex=o?0:-1,d.disabled=l,i?.icon){const e=document.createElement("span");e.className="designbase-wc-tabs__tab-icon";const s="s"===r?16:"l"===r?20:18;e.setAttribute("aria-hidden","true"),e.append(t(i.icon,s)),d.append(e)}const c=document.createElement("span");c.className="designbase-wc-tabs__tab-label",c.textContent=e,d.append(c),d.addEventListener("click",()=>this.select(s)),d.addEventListener("keydown",t=>this.handleKeyDown(t,s)),this.list?.append(d),this.tabButtons.push(d)}),d?(this.indicator=document.createElement("span"),this.indicator.className="designbase-wc-tabs__indicator designbase-wc-tabs__indicator--no-transition",this.list.append(this.indicator),requestAnimationFrame(()=>this.updateIndicator(!1))):this.indicator=void 0,this.panel=document.createElement("div"),this.panel.className="designbase-wc-tabs__panel",this.panel.setAttribute("role","tabpanel"),this.panel.id=`panel-${n}`,this.panel.setAttribute("aria-labelledby",`tab-${n}`),this.panel.tabIndex=0;const c=document.createElement("div");c.className="designbase-wc-tabs__panel-inner",s.forEach((t,e)=>{t.forEach(t=>{t.removeAttribute("slot"),t.dataset.panelIndex=String(e),e===n?c.append(t):this.inactivePanels.append(t)})}),this.panel.append(c),this.append(this.list,this.panel),requestAnimationFrame(()=>{this.handleListScroll(),d&&this.updateIndicator(!1)}),this.isRendering=!1}select(t){const e=this.labels,s=this.tabItems;if(!e[t]||s[t]?.disabled)return;this.activeIndex=t;const i=s[t]?.id||String(t);this.setAttribute("selected-id",i),this.dispatchEvent(new CustomEvent("db-change",{detail:{index:t,label:e[t],id:i},bubbles:!0,composed:!0})),this.render()}handleKeyDown(t,e){const s=this.labels,i=this.tabItems;let a=e;if("ArrowRight"===t.key||"ArrowDown"===t.key)a=(e+1)%s.length;else if("ArrowLeft"===t.key||"ArrowUp"===t.key)a=(e-1+s.length)%s.length;else if("Home"===t.key)a=0;else{if("End"!==t.key)return"Enter"===t.key||" "===t.key?(t.preventDefault(),void this.select(e)):void 0;a=s.length-1}t.preventDefault();let n=0;for(;i[a]?.disabled&&n<s.length;)a="ArrowLeft"===t.key||"ArrowUp"===t.key?(a-1+s.length)%s.length:(a+1)%s.length,n+=1;this.tabButtons[a]?.focus()}updateIndicator(t=!1){const e=this.list?.querySelector(".designbase-wc-tabs__tab--selected");if(!e||!this.indicator)return;const s="vertical"===this.orientation;this.indicator.classList.toggle("designbase-wc-tabs__indicator--no-transition",!t),this.indicator.classList.add(s?"designbase-wc-tabs__indicator--vertical":"designbase-wc-tabs__indicator--horizontal"),this.indicator.classList.add("designbase-wc-tabs__indicator--ready"),s?(this.indicator.style.width="2px",this.indicator.style.height=`${e.offsetHeight}px`,this.indicator.style.transform=`translate3d(0, ${e.offsetTop}px, 0)`):(this.indicator.style.width=`${e.offsetWidth}px`,this.indicator.style.height="2px",this.indicator.style.transform=`translate3d(${e.offsetLeft}px, 0, 0)`)}}customElements.get("db-tabs")||customElements.define("db-tabs",DbTabs);export{DbTabs};
1
+ import{createDbIcon as t}from"./db-icons.js";import{labelFrom as e}from"../core/i18n.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TABS_ORIENTATIONS as i,TABS_SIZES as a,TABS_VARIANTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbTabs extends HTMLElement{constructor(){super(...arguments),this.tabButtons=[],this.inactivePanels=document.createDocumentFragment(),this.isRendering=!1,this.handleResize=()=>{this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.resizeRaf=requestAnimationFrame(()=>{this.isRendering||(this.handleListScroll(),this.updateIndicator(!1))})},this.handleListScroll=()=>{if(!this.list)return;const t=this.list.scrollWidth>this.list.clientWidth,e=this.list.scrollLeft+this.list.clientWidth>=this.list.scrollWidth-5;this.list.classList.toggle("designbase-wc-tabs__list--show-gradient",t&&!e&&"horizontal"===this.orientation)}}static get observedAttributes(){return["labels","items","active-index","selected-id","orientation","size","variant","full-width"]}get labels(){const t=this.tabItems.map(t=>t.label);return t.length?t:(this.getAttribute("labels")||"").split(",").map(t=>t.trim()).filter(Boolean)}set labels(t){this.setAttribute("labels",Array.isArray(t)?t.join(","):t)}get tabItems(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}get items(){return this.tabItems}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}set tabItems(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}get activeIndex(){const t=this.getAttribute("selected-id");if(t){const e=this.tabItems.findIndex((e,s)=>(e.id||String(s))===t);if(e>=0)return e}return Number(this.getAttribute("active-index")||0)}set activeIndex(t){this.setAttribute("active-index",String(t))}get orientation(){return s(this.getAttribute("orientation"),i,"horizontal")}set orientation(t){this.setAttribute("orientation",t)}get size(){return s(this.getAttribute("size"),a,"m")}set size(t){this.setAttribute("size",t)}get variant(){return s(this.getAttribute("variant"),n,"default")}set variant(t){this.setAttribute("variant",t)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(t){this.toggleAttribute("full-width",Boolean(t))}connectedCallback(){this.render(),this.list?.addEventListener("scroll",this.handleListScroll,{passive:!0}),window.addEventListener("resize",this.handleResize),this.resizeObserver=new ResizeObserver(()=>this.handleResize()),this.resizeObserver.observe(this),this.childObserver=new MutationObserver(t=>{if(this.isRendering)return;t.some(t=>Array.from(t.addedNodes).some(t=>t instanceof HTMLElement&&(t.hasAttribute("slot")||void 0!==t.dataset.panelIndex)))&&this.render()}),this.childObserver.observe(this,{childList:!0})}disconnectedCallback(){this.list?.removeEventListener("scroll",this.handleListScroll),window.removeEventListener("resize",this.handleResize),this.resizeObserver?.disconnect(),this.resizeRaf&&cancelAnimationFrame(this.resizeRaf),this.childObserver?.disconnect()}attributeChangedCallback(){this.isConnected&&this.render()}collectPanelContent(){const t=new Map,register=(e,s)=>{if(!(e instanceof HTMLElement)||"SLOT"===e.tagName)return;t.has(s)||t.set(s,[]);const i=t.get(s);i.includes(e)||i.push(e)};return Array.from(this.children).forEach(t=>{const e=t.getAttribute("slot")?.match(/^panel-(\d+)$/);if(e)return void register(t,Number(e[1]));const s=t.dataset.panelIndex;void 0!==s&&register(t,Number(s))}),this.panel?.querySelectorAll(":scope > .designbase-wc-tabs__panel-inner > [data-panel-index]").forEach(t=>{t instanceof HTMLElement&&register(t,Number(t.dataset.panelIndex))}),Array.from(this.inactivePanels.children).forEach(t=>{t instanceof HTMLElement&&void 0!==t.dataset.panelIndex&&register(t,Number(t.dataset.panelIndex))}),t}render(){this.isRendering=!0;const s=this.collectPanelContent(),i=this.labels,a=this.tabItems,n=Math.min(Math.max(this.activeIndex,0),Math.max(i.length-1,0)),r=this.size,l=this.orientation,o=this.variant,d="default"===o;this.className=["designbase-wc-tabs",`designbase-wc-tabs--${l}`,`designbase-wc-tabs--${r}`,`designbase-wc-tabs--${o}`,this.fullWidth&&"designbase-wc-tabs--full-width"].filter(Boolean).join(" "),this.querySelectorAll(":scope > .designbase-wc-tabs__list, :scope > .designbase-wc-tabs__panel").forEach(t=>t.remove()),this.list=document.createElement("div"),this.list.className=["designbase-wc-tabs__list",`designbase-wc-tabs__list--${l}`,this.fullWidth&&"designbase-wc-tabs__list--full-width"].filter(Boolean).join(" "),this.list.setAttribute("role","tablist"),this.list.setAttribute("aria-orientation",l),this.list.setAttribute("aria-label",e(this,"label-tablist","tabs.label")),this.tabButtons=[],i.forEach((e,s)=>{const i=a[s],l=Boolean(i?.disabled),o=s===n,d=document.createElement("button");if(d.type="button",d.className=["designbase-wc-tabs__tab",o&&"designbase-wc-tabs__tab--selected",l&&"designbase-wc-tabs__tab--disabled"].filter(Boolean).join(" "),d.setAttribute("role","tab"),d.setAttribute("aria-selected",String(o)),d.setAttribute("aria-controls",`panel-${s}`),d.id=`tab-${s}`,d.tabIndex=o?0:-1,d.disabled=l,i?.icon){const e=document.createElement("span");e.className="designbase-wc-tabs__tab-icon";const s="s"===r?16:"l"===r?20:18;e.setAttribute("aria-hidden","true"),e.append(t(i.icon,s)),d.append(e)}const c=document.createElement("span");c.className="designbase-wc-tabs__tab-label",c.textContent=e,d.append(c),d.addEventListener("click",()=>this.select(s)),d.addEventListener("keydown",t=>this.handleKeyDown(t,s)),this.list?.append(d),this.tabButtons.push(d)}),d?(this.indicator=document.createElement("span"),this.indicator.className="designbase-wc-tabs__indicator designbase-wc-tabs__indicator--no-transition",this.list.append(this.indicator),requestAnimationFrame(()=>this.updateIndicator(!1))):this.indicator=void 0,this.panel=document.createElement("div"),this.panel.className="designbase-wc-tabs__panel",this.panel.setAttribute("role","tabpanel"),this.panel.id=`panel-${n}`,this.panel.setAttribute("aria-labelledby",`tab-${n}`),this.panel.tabIndex=0;const c=document.createElement("div");c.className="designbase-wc-tabs__panel-inner",s.forEach((t,e)=>{t.forEach(t=>{t.removeAttribute("slot"),t.dataset.panelIndex=String(e),e===n?c.append(t):this.inactivePanels.append(t)})}),this.panel.append(c),this.append(this.list,this.panel),requestAnimationFrame(()=>{this.handleListScroll(),d&&this.updateIndicator(!1)}),this.isRendering=!1}select(t){const e=this.labels,s=this.tabItems;if(!e[t]||s[t]?.disabled)return;this.activeIndex=t;const i=s[t]?.id||String(t);this.setAttribute("selected-id",i),this.dispatchEvent(new CustomEvent("db-change",{detail:{index:t,label:e[t],id:i},bubbles:!0,composed:!0})),this.render()}handleKeyDown(t,e){const s=this.labels,i=this.tabItems;let a=e;if("ArrowRight"===t.key||"ArrowDown"===t.key)a=(e+1)%s.length;else if("ArrowLeft"===t.key||"ArrowUp"===t.key)a=(e-1+s.length)%s.length;else if("Home"===t.key)a=0;else{if("End"!==t.key)return"Enter"===t.key||" "===t.key?(t.preventDefault(),void this.select(e)):void 0;a=s.length-1}t.preventDefault();let n=0;for(;i[a]?.disabled&&n<s.length;)a="ArrowLeft"===t.key||"ArrowUp"===t.key?(a-1+s.length)%s.length:(a+1)%s.length,n+=1;this.tabButtons[a]?.focus()}updateIndicator(t=!1){const e=this.list?.querySelector(".designbase-wc-tabs__tab--selected");if(!e||!this.indicator)return;const s="vertical"===this.orientation;this.indicator.classList.toggle("designbase-wc-tabs__indicator--no-transition",!t),this.indicator.classList.add(s?"designbase-wc-tabs__indicator--vertical":"designbase-wc-tabs__indicator--horizontal"),this.indicator.classList.add("designbase-wc-tabs__indicator--ready"),s?(this.indicator.style.width="2px",this.indicator.style.height=`${e.offsetHeight}px`,this.indicator.style.transform=`translate3d(0, ${e.offsetTop}px, 0)`):(this.indicator.style.width=`${e.offsetWidth}px`,this.indicator.style.height="2px",this.indicator.style.transform=`translate3d(${e.offsetLeft}px, 0, 0)`)}}customElements.get("db-tabs")||customElements.define("db-tabs",DbTabs);export{DbTabs};
@@ -1 +1 @@
1
- import{isDbIconName as e,createDbIcon as t}from"./db-icons.js";const i="designbase-wc-timeline";class DbTimeline extends HTMLElement{static get observedAttributes(){return["items","type","variant","size","color","clickable","full-width","disabled"]}connectedCallback(){this.style.display="block",this.render()}attributeChangedCallback(){this.isConnected&&this.render()}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}getItemPosition(e){return"left"===(this.getAttribute("type")||"alternate")||e%2==0?"left":"right"}handleItemClick(e,t){this.hasAttribute("disabled")||e.disabled||!this.hasAttribute("clickable")||this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e,index:t}}))}render(){const n=this.getAttribute("type")||"alternate",s=this.getAttribute("variant")||"default",a=this.getAttribute("size")||"m",l=this.getAttribute("color")||"primary",c=this.hasAttribute("clickable"),d=this.hasAttribute("disabled"),o=this.items;this.className=[i,`${i}--${n}`,`${i}--${s}`,`${i}--${a}`,c&&`${i}--clickable`,this.hasAttribute("full-width")&&`${i}--full-width`,d&&`${i}--disabled`].filter(Boolean).join(" "),this.replaceChildren();const r=document.createElement("div");r.className=`${i}__container`,o.forEach((n,m)=>{const b=this.getItemPosition(m),u=m===o.length-1,p=c&&!d&&!n.disabled,h=c&&(d||Boolean(n.disabled)),_=n.color||l,$=n.status||"pending",v=document.createElement("div");v.className=[`${i}__item`,`${i}__item--${b}`,`${i}__item--${_}`,p&&`${i}__item--clickable`,n.disabled&&`${i}__item--disabled`].filter(Boolean).join(" ");const E=document.createElement("div");if(E.className=`${i}__indicator-container`,"active"===$&&!n.icon&&void 0===n.number){const e=document.createElement("div");e.className=`${i}__pulse`,E.append(e)}const f=document.createElement("div");if(f.className=[`${i}__dot`,`${i}__dot--${_}`,`${i}__dot--${s}`,`${i}__dot--${$}`,p&&`${i}__dot--clickable`,n.icon&&`${i}__dot--with-icon`,void 0!==n.number&&!n.icon&&`${i}__dot--with-number`].filter(Boolean).join(" "),h&&(f.setAttribute("role","button"),f.setAttribute("aria-disabled","true")),p&&(f.tabIndex=0,f.setAttribute("role","button"),f.setAttribute("aria-label",n.title?`${n.title} 타임라인 점`:`타임라인 점 ${m+1}`),f.addEventListener("click",()=>this.handleItemClick(n,m)),f.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleItemClick(n,m))})),n.icon&&e(n.icon)){const e=document.createElement("div");e.className=`${i}__icon`,e.append(t(n.icon,"s"===a?14:"l"===a?20:16)),f.append(e)}else if(void 0!==n.number){const e=document.createElement("span");e.className=`${i}__number`,e.textContent=String(n.number),f.append(e)}if(E.append(f),!u){const e=document.createElement("div");e.className=`${i}__connector`,E.append(e)}const k=document.createElement("div");if(k.className=[`${i}__content`,`${i}__content--${b}`].join(" "),n.timestamp){const e=document.createElement("div");e.className=`${i}__timestamp`,e.textContent=n.timestamp,k.append(e)}const A=document.createElement("div");if(A.className=`${i}__content-inner`,h&&(A.setAttribute("role","button"),A.setAttribute("aria-disabled","true")),p&&(A.tabIndex=0,A.setAttribute("role","button"),A.setAttribute("aria-label",n.title?`${n.title} 타임라인 아이템`:`타임라인 아이템 ${m+1}`),A.addEventListener("click",()=>this.handleItemClick(n,m)),A.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleItemClick(n,m))})),n.title){const e=document.createElement("h3");e.className=`${i}__title`,e.textContent=n.title,A.append(e)}if(n.description){const e=document.createElement("p");e.className=`${i}__description`,e.textContent=n.description,A.append(e)}k.append(A),v.append(E,k),r.append(v)}),this.append(r)}}customElements.get("db-timeline")||customElements.define("db-timeline",DbTimeline);export{DbTimeline};
1
+ import{isDbIconName as e,createDbIcon as t}from"./db-icons.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TIMELINE_VARIANTS as n,TIMELINE_SIZES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const a="designbase-wc-timeline";class DbTimeline extends HTMLElement{static get observedAttributes(){return["items","type","variant","size","color","clickable","full-width","disabled"]}connectedCallback(){this.style.display="block",this.render()}attributeChangedCallback(){this.isConnected&&this.render()}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}getItemPosition(e){return"left"===(this.getAttribute("type")||"alternate")||e%2==0?"left":"right"}handleItemClick(e,t){this.hasAttribute("disabled")||e.disabled||!this.hasAttribute("clickable")||this.dispatchEvent(new CustomEvent("db-item-click",{bubbles:!0,composed:!0,detail:{item:e,index:t}}))}render(){const l=this.getAttribute("type")||"alternate",c=i(this.getAttribute("variant"),n,"default"),d=i(this.getAttribute("size"),s,"m"),o=this.getAttribute("color")||"primary",r=this.hasAttribute("clickable"),m=this.hasAttribute("disabled"),b=this.items;this.className=[a,`${a}--${l}`,`${a}--${c}`,`${a}--${d}`,r&&`${a}--clickable`,this.hasAttribute("full-width")&&`${a}--full-width`,m&&`${a}--disabled`].filter(Boolean).join(" "),this.replaceChildren();const u=document.createElement("div");u.className=`${a}__container`,b.forEach((i,n)=>{const s=this.getItemPosition(n),l=n===b.length-1,p=r&&!m&&!i.disabled,_=r&&(m||Boolean(i.disabled)),h=i.color||o,$=i.status||"pending",v=document.createElement("div");v.className=[`${a}__item`,`${a}__item--${s}`,`${a}__item--${h}`,p&&`${a}__item--clickable`,i.disabled&&`${a}__item--disabled`].filter(Boolean).join(" ");const f=document.createElement("div");if(f.className=`${a}__indicator-container`,"active"===$&&!i.icon&&void 0===i.number){const e=document.createElement("div");e.className=`${a}__pulse`,f.append(e)}const k=document.createElement("div");if(k.className=[`${a}__dot`,`${a}__dot--${h}`,`${a}__dot--${c}`,`${a}__dot--${$}`,p&&`${a}__dot--clickable`,i.icon&&`${a}__dot--with-icon`,void 0!==i.number&&!i.icon&&`${a}__dot--with-number`].filter(Boolean).join(" "),_&&(k.setAttribute("role","button"),k.setAttribute("aria-disabled","true")),p&&(k.tabIndex=0,k.setAttribute("role","button"),k.setAttribute("aria-label",i.title?`${i.title} 타임라인 점`:`타임라인 점 ${n+1}`),k.addEventListener("click",()=>this.handleItemClick(i,n)),k.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleItemClick(i,n))})),i.icon&&e(i.icon)){const e=document.createElement("div");e.className=`${a}__icon`,e.append(t(i.icon,"s"===d?14:"l"===d?20:16)),k.append(e)}else if(void 0!==i.number){const e=document.createElement("span");e.className=`${a}__number`,e.textContent=String(i.number),k.append(e)}if(f.append(k),!l){const e=document.createElement("div");e.className=`${a}__connector`,f.append(e)}const E=document.createElement("div");if(E.className=[`${a}__content`,`${a}__content--${s}`].join(" "),i.timestamp){const e=document.createElement("div");e.className=`${a}__timestamp`,e.textContent=i.timestamp,E.append(e)}const g=document.createElement("div");if(g.className=`${a}__content-inner`,_&&(g.setAttribute("role","button"),g.setAttribute("aria-disabled","true")),p&&(g.tabIndex=0,g.setAttribute("role","button"),g.setAttribute("aria-label",i.title?`${i.title} 타임라인 아이템`:`타임라인 아이템 ${n+1}`),g.addEventListener("click",()=>this.handleItemClick(i,n)),g.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.handleItemClick(i,n))})),i.title){const e=document.createElement("h3");e.className=`${a}__title`,e.textContent=i.title,g.append(e)}if(i.description){const e=document.createElement("p");e.className=`${a}__description`,e.textContent=i.description,g.append(e)}E.append(g),v.append(f,E),u.append(v)}),this.append(u)}}customElements.get("db-timeline")||customElements.define("db-timeline",DbTimeline);export{DbTimeline};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";import{politenessForTone as e}from"../core/a11y.js";import{labelFrom as s}from"../core/i18n.js";import{CleanupBag as i}from"../core/dom.js";import{TOAST_VARIANTS as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";import{coerceToContract as a}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";class DbToast extends HTMLElement{constructor(){super(...arguments),this.timeoutId=null,this.progressInterval=null,this.closeTimerId=null,this.closed=!1,this.cleanups=new i,this.elapsedBeforePause=0,this.runStartedAt=0,this.paused=!1,this.pauseTimers=()=>{this.paused||this.closed||(this.paused=!0,this.elapsedBeforePause+=Date.now()-this.runStartedAt,this.clearTimers())},this.resumeTimers=()=>{this.paused&&!this.closed&&(this.paused=!1,this.startTimers())}}static get observedAttributes(){return["toast-id","variant","title","description","duration","show-close","show-progress","auto-remove"]}connectedCallback(){this.closed=!1,this.elapsedBeforePause=0,this.render(),this.startTimers(),requestAnimationFrame(()=>this.classList.add("designbase-wc-toast--visible")),this.cleanups.listen(this,"pointerenter",this.pauseTimers),this.cleanups.listen(this,"pointerleave",this.resumeTimers),this.cleanups.listen(this,"focusin",this.pauseTimers),this.cleanups.listen(this,"focusout",this.resumeTimers)}disconnectedCallback(){this.cleanups.run(),this.clearTimers(),this.closeTimerId&&clearTimeout(this.closeTimerId),this.closeTimerId=null}attributeChangedCallback(t){if(!this.isConnected||this.closed)return;const e=this.classList.contains("designbase-wc-toast--visible");this.render(),e&&requestAnimationFrame(()=>this.classList.add("designbase-wc-toast--visible")),"duration"!==t&&"show-progress"!==t||(this.clearTimers(),this.startTimers())}clearTimers(){this.timeoutId&&clearTimeout(this.timeoutId),this.progressInterval&&clearInterval(this.progressInterval),this.timeoutId=null,this.progressInterval=null}startTimers(){const t=Number(this.getAttribute("duration")??"5000");if(!Number.isFinite(t)||t<=0)return;const e=Math.max(0,t-this.elapsedBeforePause);if(this.runStartedAt=Date.now(),0===e)return void this.close();if("false"!==this.getAttribute("show-progress")&&this.hasAttribute("show-progress")){const e=this.querySelector(".designbase-wc-toast__progress-bar");e&&(e.style.width="0%");const s=Date.now();return void(this.progressInterval=setInterval(()=>{const i=this.elapsedBeforePause+(Date.now()-s),r=Math.min(100,i/t*100);e&&(e.style.width=`${r}%`),r>=100&&this.close()},16))}this.timeoutId=setTimeout(()=>this.close(),e)}close(){this.closed||(this.closed=!0,this.clearTimers(),this.classList.remove("designbase-wc-toast--visible"),this.classList.add("designbase-wc-toast--closing"),this.closeTimerId&&clearTimeout(this.closeTimerId),this.closeTimerId=setTimeout(()=>{this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0,detail:{id:this.getAttribute("toast-id")||""}}));("true"===this.getAttribute("auto-remove")||this.hasAttribute("auto-remove")&&"false"!==this.getAttribute("auto-remove"))&&this.remove()},300))}iconForVariant(t){return"success"===t?"circle-checked":"warning"===t?"warning-filled":"danger"===t?"error-filled":"info-filled"}render(){const i=a(this.getAttribute("variant"),r,"info"),o=this.getAttribute("title")||"",n=this.getAttribute("description")||"",c="false"!==this.getAttribute("show-close"),l="false"!==this.getAttribute("show-progress")&&this.hasAttribute("show-progress");this.className=["designbase-wc-toast",`designbase-wc-toast--${i}`,this.closed&&"designbase-wc-toast--closing"].filter(Boolean).join(" ");const d=e(i);if(this.setAttribute("role","assertive"===d?"alert":"status"),this.setAttribute("aria-live",d),this.setAttribute("aria-atomic","true"),this.replaceChildren(),l){const t=document.createElement("div");t.className="designbase-wc-toast__progress";const e=document.createElement("div");e.className="designbase-wc-toast__progress-bar",e.style.width="0%",t.append(e),this.append(t)}const h=document.createElement("div");h.className=`designbase-wc-toast__icon designbase-wc-toast__icon--${i}`,h.setAttribute("aria-hidden","true"),h.append(t(this.iconForVariant(i),20));const u=document.createElement("div");u.className="designbase-wc-toast__content";const m=document.createElement("div");if(m.className="designbase-wc-toast__title",m.textContent=o,u.append(m),n){const t=document.createElement("div");t.className="designbase-wc-toast__description",t.textContent=n,u.append(t)}if(this.append(h,u),c){const e=document.createElement("button");e.type="button",e.className="designbase-wc-toast__close-button",e.setAttribute("aria-label",s(this,"label-close","toast.close"));const i=t("close",20);i.setAttribute("aria-hidden","true"),e.append(i),e.addEventListener("click",()=>this.close()),this.append(e)}}}customElements.get("db-toast")||customElements.define("db-toast",DbToast);export{DbToast};
1
+ import{createDbIcon as t}from"./db-icons.js";import{politenessForTone as e}from"../core/a11y.js";import{labelFrom as s}from"../core/i18n.js";import{CleanupBag as i}from"../core/dom.js";import{coerceToContract as r}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TOAST_VARIANTS as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbToast extends HTMLElement{constructor(){super(...arguments),this.timeoutId=null,this.progressInterval=null,this.closeTimerId=null,this.closed=!1,this.cleanups=new i,this.elapsedBeforePause=0,this.runStartedAt=0,this.paused=!1,this.pauseTimers=()=>{this.paused||this.closed||(this.paused=!0,this.elapsedBeforePause+=Date.now()-this.runStartedAt,this.clearTimers())},this.resumeTimers=()=>{this.paused&&!this.closed&&(this.paused=!1,this.startTimers())}}static get observedAttributes(){return["toast-id","variant","title","description","duration","show-close","show-progress","auto-remove"]}connectedCallback(){this.closed=!1,this.elapsedBeforePause=0,this.render(),this.startTimers(),requestAnimationFrame(()=>this.classList.add("designbase-wc-toast--visible")),this.cleanups.listen(this,"pointerenter",this.pauseTimers),this.cleanups.listen(this,"pointerleave",this.resumeTimers),this.cleanups.listen(this,"focusin",this.pauseTimers),this.cleanups.listen(this,"focusout",this.resumeTimers)}disconnectedCallback(){this.cleanups.run(),this.clearTimers(),this.closeTimerId&&clearTimeout(this.closeTimerId),this.closeTimerId=null}attributeChangedCallback(t){if(!this.isConnected||this.closed)return;const e=this.classList.contains("designbase-wc-toast--visible");this.render(),e&&requestAnimationFrame(()=>this.classList.add("designbase-wc-toast--visible")),"duration"!==t&&"show-progress"!==t||(this.clearTimers(),this.startTimers())}clearTimers(){this.timeoutId&&clearTimeout(this.timeoutId),this.progressInterval&&clearInterval(this.progressInterval),this.timeoutId=null,this.progressInterval=null}startTimers(){const t=Number(this.getAttribute("duration")??"5000");if(!Number.isFinite(t)||t<=0)return;const e=Math.max(0,t-this.elapsedBeforePause);if(this.runStartedAt=Date.now(),0===e)return void this.close();if("false"!==this.getAttribute("show-progress")&&this.hasAttribute("show-progress")){const e=this.querySelector(".designbase-wc-toast__progress-bar");e&&(e.style.width="0%");const s=Date.now();return void(this.progressInterval=setInterval(()=>{const i=this.elapsedBeforePause+(Date.now()-s),r=Math.min(100,i/t*100);e&&(e.style.width=`${r}%`),r>=100&&this.close()},16))}this.timeoutId=setTimeout(()=>this.close(),e)}close(){this.closed||(this.closed=!0,this.clearTimers(),this.classList.remove("designbase-wc-toast--visible"),this.classList.add("designbase-wc-toast--closing"),this.closeTimerId&&clearTimeout(this.closeTimerId),this.closeTimerId=setTimeout(()=>{this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0,detail:{id:this.getAttribute("toast-id")||""}}));("true"===this.getAttribute("auto-remove")||this.hasAttribute("auto-remove")&&"false"!==this.getAttribute("auto-remove"))&&this.remove()},300))}iconForVariant(t){return"success"===t?"circle-checked":"warning"===t?"warning-filled":"danger"===t?"error-filled":"info-filled"}render(){const i=r(this.getAttribute("variant"),a,"info"),o=this.getAttribute("title")||"",n=this.getAttribute("description")||"",c="false"!==this.getAttribute("show-close"),l="false"!==this.getAttribute("show-progress")&&this.hasAttribute("show-progress");this.className=["designbase-wc-toast",`designbase-wc-toast--${i}`,this.closed&&"designbase-wc-toast--closing"].filter(Boolean).join(" ");const d=e(i);if(this.setAttribute("role","assertive"===d?"alert":"status"),this.setAttribute("aria-live",d),this.setAttribute("aria-atomic","true"),this.replaceChildren(),l){const t=document.createElement("div");t.className="designbase-wc-toast__progress";const e=document.createElement("div");e.className="designbase-wc-toast__progress-bar",e.style.width="0%",t.append(e),this.append(t)}const h=document.createElement("div");h.className=`designbase-wc-toast__icon designbase-wc-toast__icon--${i}`,h.setAttribute("aria-hidden","true"),h.append(t(this.iconForVariant(i),20));const u=document.createElement("div");u.className="designbase-wc-toast__content";const m=document.createElement("div");if(m.className="designbase-wc-toast__title",m.textContent=o,u.append(m),n){const t=document.createElement("div");t.className="designbase-wc-toast__description",t.textContent=n,u.append(t)}if(this.append(h,u),c){const e=document.createElement("button");e.type="button",e.className="designbase-wc-toast__close-button",e.setAttribute("aria-label",s(this,"label-close","toast.close"));const i=t("close",20);i.setAttribute("aria-hidden","true"),e.append(i),e.addEventListener("click",()=>this.close()),this.append(e)}}}customElements.get("db-toast")||customElements.define("db-toast",DbToast);export{DbToast};
@@ -1 +1 @@
1
- class DbToolbar extends HTMLElement{static get observedAttributes(){return["items","size","variant","position","full-width","shadow","rounded","fixed"]}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}connectedCallback(){this.render()}attributeChangedCallback(t){"items"!==t?this.syncHostClasses():this.render()}syncHostClasses(){const t=this.getAttribute("size")||"m",e=this.getAttribute("variant")||"default",s=this.getAttribute("position")||"top";this.className=["designbase-wc-toolbar",`designbase-wc-toolbar--size-${t}`,`designbase-wc-toolbar--variant-${e}`,`designbase-wc-toolbar--position-${s}`,this.hasAttribute("full-width")&&"designbase-wc-toolbar--full-width",this.hasAttribute("fixed")&&"designbase-wc-toolbar--fixed",this.hasAttribute("shadow")&&"designbase-wc-toolbar--shadow",this.hasAttribute("rounded")&&"designbase-wc-toolbar--rounded"].filter(Boolean).join(" ")}render(){this.syncHostClasses(),this.setAttribute("role","toolbar");let t=this.querySelector(".designbase-wc-toolbar__content");t?t.replaceChildren():(t=document.createElement("div"),t.className="designbase-wc-toolbar__content",this.replaceChildren(t));const e=document.createElement("div");e.className="designbase-wc-toolbar__group",t.append(e),this.items.forEach(t=>{if("separator"===t.type){const t=document.createElement("div");return t.className="designbase-wc-toolbar__item designbase-wc-toolbar__item--separator",t.setAttribute("role","separator"),void e.append(t)}const s=document.createElement("button");s.type="button",s.className=["designbase-wc-toolbar__item","designbase-wc-toolbar__item--button",t.active&&"designbase-wc-toolbar__item--active",t.disabled&&"designbase-wc-toolbar__item--disabled"].filter(Boolean).join(" "),s.textContent=t.label||t.id,s.disabled=Boolean(t.disabled),t.tooltip&&(s.title=t.tooltip),s.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-item-click",{detail:{item:t},bubbles:!0,composed:!0}))}),e.append(s)})}}customElements.get("db-toolbar")||customElements.define("db-toolbar",DbToolbar);export{DbToolbar};
1
+ import{coerceToContract as t}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TOOLBAR_SIZES as e,TOOLBAR_VARIANTS as s,TOOLBAR_POSITIONS as i}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbToolbar extends HTMLElement{static get observedAttributes(){return["items","size","variant","position","full-width","shadow","rounded","fixed"]}get items(){try{return JSON.parse(this.getAttribute("items")||"[]")}catch{return[]}}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}connectedCallback(){this.render()}attributeChangedCallback(t){"items"!==t?this.syncHostClasses():this.render()}syncHostClasses(){const o=t(this.getAttribute("size"),e,"m"),a=t(this.getAttribute("variant"),s,"default"),r=t(this.getAttribute("position"),i,"top");this.className=["designbase-wc-toolbar",`designbase-wc-toolbar--size-${o}`,`designbase-wc-toolbar--variant-${a}`,`designbase-wc-toolbar--position-${r}`,this.hasAttribute("full-width")&&"designbase-wc-toolbar--full-width",this.hasAttribute("fixed")&&"designbase-wc-toolbar--fixed",this.hasAttribute("shadow")&&"designbase-wc-toolbar--shadow",this.hasAttribute("rounded")&&"designbase-wc-toolbar--rounded"].filter(Boolean).join(" ")}render(){this.syncHostClasses(),this.setAttribute("role","toolbar");let t=this.querySelector(".designbase-wc-toolbar__content");t?t.replaceChildren():(t=document.createElement("div"),t.className="designbase-wc-toolbar__content",this.replaceChildren(t));const e=document.createElement("div");e.className="designbase-wc-toolbar__group",t.append(e),this.items.forEach(t=>{if("separator"===t.type){const t=document.createElement("div");return t.className="designbase-wc-toolbar__item designbase-wc-toolbar__item--separator",t.setAttribute("role","separator"),void e.append(t)}const s=document.createElement("button");s.type="button",s.className=["designbase-wc-toolbar__item","designbase-wc-toolbar__item--button",t.active&&"designbase-wc-toolbar__item--active",t.disabled&&"designbase-wc-toolbar__item--disabled"].filter(Boolean).join(" "),s.textContent=t.label||t.id,s.disabled=Boolean(t.disabled),t.tooltip&&(s.title=t.tooltip),s.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-item-click",{detail:{item:t},bubbles:!0,composed:!0}))}),e.append(s)})}}customElements.get("db-toolbar")||customElements.define("db-toolbar",DbToolbar);export{DbToolbar};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";import"./db-button.js";import"./db-input.js";import"./db-otp-input.js";import"./db-segment-control.js";import{TWO_FACTOR_SIZES as e}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const i=[{value:"app",label:"인증 앱"},{value:"sms",label:"SMS"},{value:"email",label:"이메일"}];function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}class DbTwoFactor extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.timerId=null,this.remaining=0,this.backupMode=!1,this.resendCount=0}static get observedAttributes(){return["method","code","size","disabled","error","error-message","title","description","verify-label","code-length","show-backup","countdown","destination","manual","sending","verifying","auto-submit","resend-label","max-resends"]}get method(){const t=this.getAttribute("method");return"sms"===t||"email"===t||"app"===t?t:"app"}set method(t){this.setAttribute("method",t)}get size(){return function pick(t,e,i){return t.includes(e)?e:i}(e,this.getAttribute("size"),"m")}set size(t){this.setAttribute("size",t)}get countdown(){const t=Number(this.getAttribute("countdown")||180);return Number.isFinite(t)&&t>0?t:180}set countdown(t){this.setAttribute("countdown",String(t))}get maxResends(){const t=Number(this.getAttribute("max-resends")||3);return Number.isFinite(t)?Math.max(1,Math.min(5,Math.round(t))):3}connectedCallback(){this.build(),this.sync(),"app"===this.method||this.hasAttribute("manual")||this.startTimer(this.countdown)}disconnectedCallback(){this.clearTimer()}attributeChangedCallback(t,e,i){this.built&&(this.sync(),"method"!==t&&"manual"!==t||e===i||("method"===t&&(this.resendCount=0,this.backupMode=!1),"app"===this.method||this.hasAttribute("manual")?this.clearTimer():this.startTimer(this.countdown)))}restartCountdown(){"app"!==this.method&&this.startTimer(this.countdown)}clearTimer(){this.timerId&&clearInterval(this.timerId),this.timerId=null,this.remaining=0,this.timerEl&&(this.timerEl.textContent="")}startTimer(t){this.clearTimer(),this.remaining=t,this.renderTimer(),this.timerId=setInterval(()=>{this.remaining-=1,this.renderTimer(),this.remaining<=0&&(this.clearTimer(),this.resendBtn.disabled=!1,this.dispatchEvent(new CustomEvent("db-countdown-complete",{bubbles:!0,composed:!0})))},1e3)}renderTimer(){const t=Math.max(0,Math.floor(this.remaining/60)),e=Math.max(0,this.remaining%60);this.timerEl.textContent="app"===this.method?"":`${String(t).padStart(2,"0")}:${String(e).padStart(2,"0")}`,"app"!==this.method?this.timerEl.setAttribute("aria-label",`남은 시간 ${t}분 ${e}초`):this.timerEl.removeAttribute("aria-label");const i=this.resendCount>=this.maxResends;this.resendBtn.disabled="app"===this.method||this.remaining>0||i||this.hasAttribute("disabled"),"app"===this.method?this.resendStatus.textContent="":i?this.resendStatus.textContent="재전송 한도에 도달했습니다. 새 인증을 시작해 주세요.":this.remaining>0?this.resendStatus.textContent=`${String(t).padStart(2,"0")}:${String(e).padStart(2,"0")} 후 재전송 가능 · 남은 횟수 ${this.maxResends-this.resendCount}회`:this.resendStatus.textContent=`재전송 가능 · 남은 횟수 ${this.maxResends-this.resendCount}회`}build(){if(this.built)return;this.built=!0;const e="designbase-wc-two-factor";this.replaceChildren();const s=el("div",`${e}__header`),n=el("div",`${e}__icon`);n.append(t("lock",22));const r=el("div",`${e}__titles`),h=el("h3",`${e}__title`);h.dataset.role="title";const a=el("p",`${e}__description`);a.dataset.role="description",r.append(h,a),s.append(n,r),this.segment=document.createElement("db-segment-control"),this.segment.setAttribute("options",JSON.stringify(i.map(t=>({value:t.value,label:t.label})))),this.segment.setAttribute("full-width",""),this.segment.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"app");e!==this.method&&(this.setAttribute("code",""),this.method=e,this.dispatchEvent(new CustomEvent("db-method-change",{detail:{method:e},bubbles:!0,composed:!0})),"app"!==e&&this.dispatchEvent(new CustomEvent("db-send-code",{detail:{method:e,destination:this.getAttribute("destination")||""},bubbles:!0,composed:!0})))}),this.hintEl=el("p",`${e}__hint`),this.hintEl.dataset.role="hint",this.codeHead=el("div",`${e}__code-head`);const o=el("span",`${e}__code-label`);o.textContent="인증 코드",this.timerEl=el("span",`${e}__timer`),this.codeHead.append(o,this.timerEl),this.otpInput=document.createElement("db-otp-input"),this.otpInput.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.setAttribute("code",e),this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:e},bubbles:!0,composed:!0}))}),this.otpInput.addEventListener("db-complete",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.dispatchEvent(new CustomEvent("db-code-complete",{detail:{code:e,method:this.method},bubbles:!0,composed:!0})),this.hasAttribute("auto-submit")&&this.requestVerify()}),this.channelActions=el("div",`${e}__channel`),this.resendBtn=el("button",`${e}__resend`),this.resendBtn.type="button",this.resendBtn.textContent="코드 재전송",this.resendBtn.addEventListener("click",()=>{this.resendBtn.disabled||(this.resendCount+=1,this.dispatchEvent(new CustomEvent("db-resend",{detail:{method:this.method,destination:this.getAttribute("destination")||""},bubbles:!0,composed:!0})),this.hasAttribute("manual")?this.renderTimer():this.startTimer(this.countdown))}),this.resendStatus=el("p",`${e}__resend-status`),this.resendStatus.setAttribute("aria-live","polite"),this.channelActions.append(this.resendBtn,this.resendStatus),this.backupBlock=el("div",`${e}__backup-block`);const d=el("p",`${e}__hint`);d.textContent="계정 설정 시 저장한 8자리 백업 코드 중 사용하지 않은 코드를 입력하세요.",this.backupInput=document.createElement("db-input"),this.backupInput.setAttribute("label","백업 코드"),this.backupInput.setAttribute("placeholder","XXXX-XXXX"),this.backupInput.setAttribute("autocomplete","one-time-code"),this.backupInput.setAttribute("full-width",""),this.backupInput.addEventListener("db-input",t=>{t.stopPropagation();const e=String(t.detail?.value||"").toUpperCase().replace(/[^A-Z0-9]/g,"").slice(0,8),i=e.length>4?`${e.slice(0,4)}-${e.slice(4)}`:e;this.backupInput.value=i,this.sync()}),this.backupCancelBtn=el("button",`${e}__backup`),this.backupCancelBtn.type="button",this.backupCancelBtn.textContent="인증 코드로 돌아가기",this.backupCancelBtn.addEventListener("click",()=>{this.backupMode=!1,this.sync()}),this.backupBlock.append(d,this.backupInput,this.backupCancelBtn),this.verifyBtn=document.createElement("db-button"),this.verifyBtn.setAttribute("variant","primary"),this.verifyBtn.setAttribute("full-width",""),this.verifyBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.requestVerify()}),this.backupBtn=el("button",`${e}__backup`),this.backupBtn.type="button",this.backupBtn.textContent="백업 코드로 인증",this.backupBtn.addEventListener("click",()=>{this.backupMode=!0,this.sync(),requestAnimationFrame(()=>this.backupInput?.focus?.()),this.dispatchEvent(new CustomEvent("db-backup-request",{bubbles:!0,composed:!0}))}),this.errorEl=el("p",`${e}__error`),this.errorEl.hidden=!0,this.append(s,this.segment,this.hintEl,this.codeHead,this.otpInput,this.channelActions,this.backupBlock,this.verifyBtn,this.backupBtn,this.errorEl)}sync(){const t="designbase-wc-two-factor",e=this.size,i=this.method,s=this.hasAttribute("disabled"),n=this.getAttribute("code-length")||"6",r=this.getAttribute("destination")||"";this.className=[t,`${t}--${e}`,`${t}--${i}`,s&&`${t}--disabled`,this.hasAttribute("error")&&`${t}--error`].filter(Boolean).join(" ");const h=this.querySelector('[data-role="title"]'),a=this.querySelector('[data-role="description"]');h.textContent=this.getAttribute("title")||"2단계 인증",a.textContent=this.getAttribute("description")||"계속하려면 인증 코드를 입력해 주세요.",this.segment.setAttribute("value",i),this.segment.setAttribute("size",e),this.segment.toggleAttribute("disabled",s),this.segment.toggleAttribute("hidden",this.backupMode);const o=this.querySelector('[data-role="hint"]');o.textContent="app"===i?"인증 앱(Google Authenticator, 1Password 등)에 표시된 6자리 코드를 입력하세요.":"sms"===i?r?`${r} 으로 보낸 SMS 인증 코드를 입력하세요.`:"등록된 휴대폰으로 보낸 SMS 인증 코드를 입력하세요.":r?`${r} 으로 보낸 이메일 인증 코드를 입력하세요.`:"등록된 이메일로 보낸 인증 코드를 입력하세요.",this.otpInput.setAttribute("length",n),this.otpInput.setAttribute("size",e),this.otpInput.setAttribute("value",this.getAttribute("code")||""),this.otpInput.toggleAttribute("disabled",s),this.otpInput.toggleAttribute("error",this.hasAttribute("error")),this.getAttribute("error-message")?this.otpInput.setAttribute("error-message",this.getAttribute("error-message")||""):this.otpInput.removeAttribute("error-message"),this.hintEl.hidden=this.backupMode,this.codeHead.hidden=this.backupMode,this.otpInput.hidden=this.backupMode,this.channelActions.hidden="app"===i||this.backupMode,this.backupBlock.hidden=!this.backupMode,this.backupInput.setAttribute("size",e),this.backupInput.toggleAttribute("disabled",s),this.resendBtn.textContent=this.hasAttribute("sending")?"전송 중…":this.getAttribute("resend-label")||"코드 재전송",this.renderTimer(),this.hasAttribute("sending")&&(this.resendBtn.disabled=!0),this.verifyBtn.setAttribute("size",e),this.verifyBtn.textContent=this.backupMode?"백업 코드로 인증":this.getAttribute("verify-label")||"인증하기";const d=this.getAttribute("code")||"",u=String(this.backupInput.value||"").replace(/-/g,"");this.verifyBtn.toggleAttribute("disabled",s||(this.backupMode?8!==u.length:d.length<Number(n))),this.verifyBtn.toggleAttribute("loading",this.hasAttribute("verifying")),this.backupBtn.hidden=!this.hasAttribute("show-backup")||this.backupMode;const c=this.getAttribute("error-message")||"";this.errorEl.textContent=c,this.errorEl.hidden=!this.hasAttribute("error")||!c}requestVerify(){if(this.backupMode){const t=String(this.backupInput.value||"").replace(/-/g,"");if(8!==t.length||this.hasAttribute("disabled"))return;return void this.dispatchEvent(new CustomEvent("db-verify",{detail:{method:"backup",code:t},bubbles:!0,composed:!0}))}const t=(this.getAttribute("code")||this.otpInput.value).replace(/\D/g,""),e=Number(this.getAttribute("code-length")||6);t.length!==e||this.hasAttribute("disabled")||this.dispatchEvent(new CustomEvent("db-verify",{detail:{method:this.method,code:t},bubbles:!0,composed:!0}))}}customElements.get("db-two-factor")||customElements.define("db-two-factor",DbTwoFactor);export{DbTwoFactor};
1
+ import{createDbIcon as t}from"./db-icons.js";import"./db-button.js";import"./db-input.js";import"./db-otp-input.js";import"./db-segment-control.js";import{coerceToContract as e}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{TWO_FACTOR_SIZES as i}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const s=[{value:"app",label:"인증 앱"},{value:"sms",label:"SMS"},{value:"email",label:"이메일"}];function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}class DbTwoFactor extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.timerId=null,this.remaining=0,this.backupMode=!1,this.resendCount=0}static get observedAttributes(){return["method","code","size","disabled","error","error-message","title","description","verify-label","code-length","show-backup","countdown","destination","manual","sending","verifying","auto-submit","resend-label","max-resends"]}get method(){const t=this.getAttribute("method");return"sms"===t||"email"===t||"app"===t?t:"app"}set method(t){this.setAttribute("method",t)}get size(){return e(this.getAttribute("size"),i,"m")}set size(t){this.setAttribute("size",t)}get countdown(){const t=Number(this.getAttribute("countdown")||180);return Number.isFinite(t)&&t>0?t:180}set countdown(t){this.setAttribute("countdown",String(t))}get maxResends(){const t=Number(this.getAttribute("max-resends")||3);return Number.isFinite(t)?Math.max(1,Math.min(5,Math.round(t))):3}connectedCallback(){this.build(),this.sync(),"app"===this.method||this.hasAttribute("manual")||this.startTimer(this.countdown)}disconnectedCallback(){this.clearTimer()}attributeChangedCallback(t,e,i){this.built&&(this.sync(),"method"!==t&&"manual"!==t||e===i||("method"===t&&(this.resendCount=0,this.backupMode=!1),"app"===this.method||this.hasAttribute("manual")?this.clearTimer():this.startTimer(this.countdown)))}restartCountdown(){"app"!==this.method&&this.startTimer(this.countdown)}clearTimer(){this.timerId&&clearInterval(this.timerId),this.timerId=null,this.remaining=0,this.timerEl&&(this.timerEl.textContent="")}startTimer(t){this.clearTimer(),this.remaining=t,this.renderTimer(),this.timerId=setInterval(()=>{this.remaining-=1,this.renderTimer(),this.remaining<=0&&(this.clearTimer(),this.resendBtn.disabled=!1,this.dispatchEvent(new CustomEvent("db-countdown-complete",{bubbles:!0,composed:!0})))},1e3)}renderTimer(){const t=Math.max(0,Math.floor(this.remaining/60)),e=Math.max(0,this.remaining%60);this.timerEl.textContent="app"===this.method?"":`${String(t).padStart(2,"0")}:${String(e).padStart(2,"0")}`,"app"!==this.method?this.timerEl.setAttribute("aria-label",`남은 시간 ${t}분 ${e}초`):this.timerEl.removeAttribute("aria-label");const i=this.resendCount>=this.maxResends;this.resendBtn.disabled="app"===this.method||this.remaining>0||i||this.hasAttribute("disabled"),"app"===this.method?this.resendStatus.textContent="":i?this.resendStatus.textContent="재전송 한도에 도달했습니다. 새 인증을 시작해 주세요.":this.remaining>0?this.resendStatus.textContent=`${String(t).padStart(2,"0")}:${String(e).padStart(2,"0")} 후 재전송 가능 · 남은 횟수 ${this.maxResends-this.resendCount}회`:this.resendStatus.textContent=`재전송 가능 · 남은 횟수 ${this.maxResends-this.resendCount}회`}build(){if(this.built)return;this.built=!0;const e="designbase-wc-two-factor";this.replaceChildren();const i=el("div",`${e}__header`),n=el("div",`${e}__icon`);n.append(t("lock",22));const r=el("div",`${e}__titles`),o=el("h3",`${e}__title`);o.dataset.role="title";const a=el("p",`${e}__description`);a.dataset.role="description",r.append(o,a),i.append(n,r),this.segment=document.createElement("db-segment-control"),this.segment.setAttribute("options",JSON.stringify(s.map(t=>({value:t.value,label:t.label})))),this.segment.setAttribute("full-width",""),this.segment.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"app");e!==this.method&&(this.setAttribute("code",""),this.method=e,this.dispatchEvent(new CustomEvent("db-method-change",{detail:{method:e},bubbles:!0,composed:!0})),"app"!==e&&this.dispatchEvent(new CustomEvent("db-send-code",{detail:{method:e,destination:this.getAttribute("destination")||""},bubbles:!0,composed:!0})))}),this.hintEl=el("p",`${e}__hint`),this.hintEl.dataset.role="hint",this.codeHead=el("div",`${e}__code-head`);const h=el("span",`${e}__code-label`);h.textContent="인증 코드",this.timerEl=el("span",`${e}__timer`),this.codeHead.append(h,this.timerEl),this.otpInput=document.createElement("db-otp-input"),this.otpInput.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.setAttribute("code",e),this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:e},bubbles:!0,composed:!0}))}),this.otpInput.addEventListener("db-complete",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.dispatchEvent(new CustomEvent("db-code-complete",{detail:{code:e,method:this.method},bubbles:!0,composed:!0})),this.hasAttribute("auto-submit")&&this.requestVerify()}),this.channelActions=el("div",`${e}__channel`),this.resendBtn=el("button",`${e}__resend`),this.resendBtn.type="button",this.resendBtn.textContent="코드 재전송",this.resendBtn.addEventListener("click",()=>{this.resendBtn.disabled||(this.resendCount+=1,this.dispatchEvent(new CustomEvent("db-resend",{detail:{method:this.method,destination:this.getAttribute("destination")||""},bubbles:!0,composed:!0})),this.hasAttribute("manual")?this.renderTimer():this.startTimer(this.countdown))}),this.resendStatus=el("p",`${e}__resend-status`),this.resendStatus.setAttribute("aria-live","polite"),this.channelActions.append(this.resendBtn,this.resendStatus),this.backupBlock=el("div",`${e}__backup-block`);const d=el("p",`${e}__hint`);d.textContent="계정 설정 시 저장한 8자리 백업 코드 중 사용하지 않은 코드를 입력하세요.",this.backupInput=document.createElement("db-input"),this.backupInput.setAttribute("label","백업 코드"),this.backupInput.setAttribute("placeholder","XXXX-XXXX"),this.backupInput.setAttribute("autocomplete","one-time-code"),this.backupInput.setAttribute("full-width",""),this.backupInput.addEventListener("db-input",t=>{t.stopPropagation();const e=String(t.detail?.value||"").toUpperCase().replace(/[^A-Z0-9]/g,"").slice(0,8),i=e.length>4?`${e.slice(0,4)}-${e.slice(4)}`:e;this.backupInput.value=i,this.sync()}),this.backupCancelBtn=el("button",`${e}__backup`),this.backupCancelBtn.type="button",this.backupCancelBtn.textContent="인증 코드로 돌아가기",this.backupCancelBtn.addEventListener("click",()=>{this.backupMode=!1,this.sync()}),this.backupBlock.append(d,this.backupInput,this.backupCancelBtn),this.verifyBtn=document.createElement("db-button"),this.verifyBtn.setAttribute("variant","primary"),this.verifyBtn.setAttribute("full-width",""),this.verifyBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.requestVerify()}),this.backupBtn=el("button",`${e}__backup`),this.backupBtn.type="button",this.backupBtn.textContent="백업 코드로 인증",this.backupBtn.addEventListener("click",()=>{this.backupMode=!0,this.sync(),requestAnimationFrame(()=>this.backupInput?.focus?.()),this.dispatchEvent(new CustomEvent("db-backup-request",{bubbles:!0,composed:!0}))}),this.errorEl=el("p",`${e}__error`),this.errorEl.hidden=!0,this.append(i,this.segment,this.hintEl,this.codeHead,this.otpInput,this.channelActions,this.backupBlock,this.verifyBtn,this.backupBtn,this.errorEl)}sync(){const t="designbase-wc-two-factor",e=this.size,i=this.method,s=this.hasAttribute("disabled"),n=this.getAttribute("code-length")||"6",r=this.getAttribute("destination")||"";this.className=[t,`${t}--${e}`,`${t}--${i}`,s&&`${t}--disabled`,this.hasAttribute("error")&&`${t}--error`].filter(Boolean).join(" ");const o=this.querySelector('[data-role="title"]'),a=this.querySelector('[data-role="description"]');o.textContent=this.getAttribute("title")||"2단계 인증",a.textContent=this.getAttribute("description")||"계속하려면 인증 코드를 입력해 주세요.",this.segment.setAttribute("value",i),this.segment.setAttribute("size",e),this.segment.toggleAttribute("disabled",s),this.segment.toggleAttribute("hidden",this.backupMode);const h=this.querySelector('[data-role="hint"]');h.textContent="app"===i?"인증 앱(Google Authenticator, 1Password 등)에 표시된 6자리 코드를 입력하세요.":"sms"===i?r?`${r} 으로 보낸 SMS 인증 코드를 입력하세요.`:"등록된 휴대폰으로 보낸 SMS 인증 코드를 입력하세요.":r?`${r} 으로 보낸 이메일 인증 코드를 입력하세요.`:"등록된 이메일로 보낸 인증 코드를 입력하세요.",this.otpInput.setAttribute("length",n),this.otpInput.setAttribute("size",e),this.otpInput.setAttribute("value",this.getAttribute("code")||""),this.otpInput.toggleAttribute("disabled",s),this.otpInput.toggleAttribute("error",this.hasAttribute("error")),this.getAttribute("error-message")?this.otpInput.setAttribute("error-message",this.getAttribute("error-message")||""):this.otpInput.removeAttribute("error-message"),this.hintEl.hidden=this.backupMode,this.codeHead.hidden=this.backupMode,this.otpInput.hidden=this.backupMode,this.channelActions.hidden="app"===i||this.backupMode,this.backupBlock.hidden=!this.backupMode,this.backupInput.setAttribute("size",e),this.backupInput.toggleAttribute("disabled",s),this.resendBtn.textContent=this.hasAttribute("sending")?"전송 중…":this.getAttribute("resend-label")||"코드 재전송",this.renderTimer(),this.hasAttribute("sending")&&(this.resendBtn.disabled=!0),this.verifyBtn.setAttribute("size",e),this.verifyBtn.textContent=this.backupMode?"백업 코드로 인증":this.getAttribute("verify-label")||"인증하기";const d=this.getAttribute("code")||"",u=String(this.backupInput.value||"").replace(/-/g,"");this.verifyBtn.toggleAttribute("disabled",s||(this.backupMode?8!==u.length:d.length<Number(n))),this.verifyBtn.toggleAttribute("loading",this.hasAttribute("verifying")),this.backupBtn.hidden=!this.hasAttribute("show-backup")||this.backupMode;const c=this.getAttribute("error-message")||"";this.errorEl.textContent=c,this.errorEl.hidden=!this.hasAttribute("error")||!c}requestVerify(){if(this.backupMode){const t=String(this.backupInput.value||"").replace(/-/g,"");if(8!==t.length||this.hasAttribute("disabled"))return;return void this.dispatchEvent(new CustomEvent("db-verify",{detail:{method:"backup",code:t},bubbles:!0,composed:!0}))}const t=(this.getAttribute("code")||this.otpInput.value).replace(/\D/g,""),e=Number(this.getAttribute("code-length")||6);t.length!==e||this.hasAttribute("disabled")||this.dispatchEvent(new CustomEvent("db-verify",{detail:{method:this.method,code:t},bubbles:!0,composed:!0}))}}customElements.get("db-two-factor")||customElements.define("db-two-factor",DbTwoFactor);export{DbTwoFactor};
@@ -1 +1 @@
1
- import{createDbIcon as t}from"./db-icons.js";import{t as e}from"../core/i18n.js";const s="designbase-wc-video-player",i=20;class DbVideoPlayer extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.rafId=null,this.playlistIndex=0,this.isFullscreen=!1,this.showControlsOverlay=!1,this.isPlaying=!1,this.isMuted=!1,this.volume=1,this.lastVolumeBeforeMute=1,this.currentTime=0,this.duration=0,this.isLoading=!1,this.error=null,this.onFullscreenChange=()=>{this.isFullscreen=document.fullscreenElement===this,this.dispatchEvent(new CustomEvent("db-fullscreen-change",{detail:{isFullscreen:this.isFullscreen},bubbles:!0,composed:!0})),this.updateUI()},this.onMouseEnter=()=>{this.showControlsOverlay=!0,this.updateUI()},this.onMouseLeave=()=>{this.showControlsOverlay=!1,this.updateUI()}}static get observedAttributes(){return["src","poster","title","description","size","variant","theme","auto-play","loop","muted","show-controls","enable-fullscreen","show-progress","show-time","show-volume","playlist","current-index"]}connectedCallback(){this.built||(this.built=!0,this.build(),this.bindVideoEvents()),this.syncFromAttributes(),this.updateUI(),document.addEventListener("fullscreenchange",this.onFullscreenChange),this.addEventListener("mouseenter",this.onMouseEnter),this.addEventListener("mouseleave",this.onMouseLeave)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.removeEventListener("mouseenter",this.onMouseEnter),this.removeEventListener("mouseleave",this.onMouseLeave),this.stopProgressAnimation()}attributeChangedCallback(t){this.built&&("src"!==t&&"playlist"!==t&&"current-index"!==t?("muted"===t&&this.videoEl&&(this.videoEl.muted=this.getBool("muted")),this.updateUI()):this.loadVideoSource())}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[]}}getCurrentSrc(){const t=this.getPlaylist();if(t.length>0){const e=Number(this.getAttribute("current-index")||this.playlistIndex||0);return t[Math.max(0,Math.min(t.length-1,e))]}return this.getAttribute("src")||""}formatTime(t){if(!Number.isFinite(t)||t<0)return"0:00";return`${Math.floor(t/60)}:${Math.floor(t%60).toString().padStart(2,"0")}`}iconButton(e,i,l,n){const o=document.createElement("button");return o.type="button",o.className=`${s}__control-button`,o.setAttribute("aria-label",l),o.append(t(e,i)),o.addEventListener("click",t=>{t.stopPropagation(),n()}),o}skipButton(t,e){const i=document.createElement("button");return i.type="button",i.className=`${s}__skip-button`,i.textContent=t,i.setAttribute("aria-label",e<0?"10초 되감기":"10초 빨리감기"),i.addEventListener("click",t=>{t.stopPropagation(),this.seekBy(e)}),i}syncFromAttributes(){this.playlistIndex=Number(this.getAttribute("current-index")||0),this.isMuted=this.getBool("muted"),this.volume=this.isMuted?0:1,this.lastVolumeBeforeMute=this.volume>0?this.volume:1,this.loadVideoSource()}loadVideoSource(){if(!this.videoEl)return;const t=this.getCurrentSrc();if(!t)return;const e=new URL(t,window.location.href).href;this.videoEl.src!==e&&(this.videoEl.src=t,this.videoEl.load()),this.videoEl.poster=this.getAttribute("poster")||"",this.videoEl.autoplay=this.getBool("auto-play"),this.videoEl.loop=this.getBool("loop"),this.videoEl.muted=this.getBool("muted"),this.videoEl.playsInline=!0}bindVideoEvents(){const t=this.videoEl;t&&(t.addEventListener("play",()=>{this.isPlaying=!0,this.startProgressAnimation(),this.dispatchEvent(new CustomEvent("db-play",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("pause",()=>{this.isPlaying=!1,this.stopProgressAnimation(),this.dispatchEvent(new CustomEvent("db-pause",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("timeupdate",()=>{this.currentTime=t.currentTime,this.duration=Number.isFinite(t.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||0===t.volume,!this.isMuted&&this.volume>0&&(this.lastVolumeBeforeMute=this.volume),this.dispatchEvent(new CustomEvent("db-volume-change",{detail:{volume:this.volume},bubbles:!0,composed:!0})),this.updateVolumeUI()}),t.addEventListener("ended",()=>{this.isPlaying=!1,this.stopProgressAnimation(),this.dispatchEvent(new CustomEvent("db-ended",{bubbles:!0,composed:!0}));const e=this.getPlaylist(),s=this.playlistIndex+1;e.length>0&&s<e.length&&(this.playlistIndex=s,this.loadVideoSource(),t.play()),this.updateUI()}),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("loadedmetadata",()=>{this.duration=Number.isFinite(t.duration)?t.duration:0,this.updateTime()}),t.addEventListener("canplay",()=>{this.isLoading=!1,this.updateUI()}),t.addEventListener("click",()=>this.togglePlay()))}togglePlay(){this.videoEl&&(this.videoEl.paused?this.videoEl.play():this.videoEl.pause())}toggleMute(){if(this.videoEl){if(this.isMuted)return this.videoEl.muted=!1,void(this.videoEl.volume=this.lastVolumeBeforeMute>0?this.lastVolumeBeforeMute:1);this.videoEl.volume>0&&(this.lastVolumeBeforeMute=this.videoEl.volume),this.videoEl.muted=!0,this.videoEl.volume=0}}seekBy(t){if(!this.videoEl)return;const e=Number.isFinite(this.videoEl.duration)?this.videoEl.duration:0,s=e>0?e:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(s,this.videoEl.currentTime+t));this.videoEl.currentTime=i}toggleFullscreen(){this.getBool("enable-fullscreen",!0)&&(this.isFullscreen?document.exitFullscreen?.():this.requestFullscreen?.())}build(){this.videoEl=document.createElement("video"),this.videoEl.className=`${s}__video`;const t=document.createElement("div");t.className=`${s}__loading`;const l=document.createElement("div");l.className=`${s}__spinner`,t.append(l);const n=document.createElement("div");n.className=`${s}__error`;const o=document.createElement("p");o.textContent="비디오를 재생할 수 없습니다.";const r=document.createElement("button");r.type="button",r.textContent="다시 시도",r.addEventListener("click",()=>{this.error=null,this.loadVideoSource(),this.updateUI()}),n.append(o,r),this.dimOverlayEl=document.createElement("div"),this.dimOverlayEl.className=`${s}__dim-overlay`,this.overlayEl=document.createElement("div"),this.overlayEl.className=`${s}__overlay`;const a=document.createElement("div");a.className=`${s}__top-controls`;const h=document.createElement("div");h.className=`${s}__title`;const u=document.createElement("h3"),d=document.createElement("p");h.append(u,d),a.append(h),this._titleEl=u,this._descEl=d;const c=document.createElement("div");c.className=`${s}__center-controls`;const m=this.skipButton("-10",-10);this.centerPlayEl=document.createElement("button"),this.centerPlayEl.type="button",this.centerPlayEl.className=`${s}__play-button`,this.centerPlayEl.addEventListener("click",t=>{t.stopPropagation(),this.togglePlay()});const E=this.skipButton("+10",10);c.append(m,this.centerPlayEl,E);const p=document.createElement("div");p.className=`${s}__bottom-controls`,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.videoEl||!Number.isFinite(this.duration)||this.duration<=0)return;const e=this.progressEl.getBoundingClientRect(),s=(t.clientX-e.left)/e.width;this.videoEl.currentTime=s*this.duration});const v=document.createElement("div");v.className=`${s}__controls`;const g=document.createElement("div");g.className=`${s}__left-controls`,this.togglePlayEl=this.iconButton("play",i,e("media.play"),()=>this.togglePlay()),this.volumeWrapEl=document.createElement("div"),this.volumeWrapEl.className=`${s}__volume`,this.muteButtonEl=this.iconButton("volume-up",i,e("media.mute"),()=>this.toggleMute());const b=document.createElement("div");b.className=`${s}__volume-slider`,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.videoEl||!this.volumeInputEl)return;const t=parseFloat(this.volumeInputEl.value);t>0&&(this.lastVolumeBeforeMute=t),this.videoEl.volume=t,this.videoEl.muted=0===t}),b.append(this.volumeInputEl),this.volumeWrapEl.append(this.muteButtonEl,b),this.timeEl=document.createElement("div"),this.timeEl.className=`${s}__time`,this.timeCurrentEl=document.createElement("span");const y=document.createElement("span");y.textContent="/",this.timeDurationEl=document.createElement("span"),this.timeEl.append(this.timeCurrentEl,y,this.timeDurationEl),g.append(this.togglePlayEl,this.volumeWrapEl,this.timeEl);const f=document.createElement("div");f.className=`${s}__right-controls`,this.fullscreenButtonEl=this.iconButton("expand",i,e("media.fullscreen"),()=>this.toggleFullscreen()),f.append(this.fullscreenButtonEl),v.append(g,f),p.append(this.progressEl,v),this.overlayEl.append(a,c,p),this.append(this.videoEl,t,n,this.dimOverlayEl,this.overlayEl)}get titleEl(){return this._titleEl}get descEl(){return this._descEl}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}%`)}updateTime(){this.timeCurrentEl&&(this.timeCurrentEl.textContent=this.formatTime(this.currentTime)),this.timeDurationEl&&(this.timeDurationEl.textContent=this.formatTime(this.duration))}updateVolumeUI(){const e=this.isMuted?0:this.volume;this.volumeInputEl&&(this.volumeInputEl.value=String(e)),this.muteButtonEl&&this.muteButtonEl.replaceChildren(t(this.isMuted||0===e?"mute-filled":"volume-up",i))}startProgressAnimation(){this.stopProgressAnimation();const tick=()=>{!this.videoEl||this.videoEl.paused||this.videoEl.ended||(this.currentTime=this.videoEl.currentTime,this.duration=Number.isFinite(this.videoEl.duration)?this.videoEl.duration:0,this.updateProgress(),this.updateTime(),this.rafId=requestAnimationFrame(tick))};this.rafId=requestAnimationFrame(tick)}stopProgressAnimation(){null!==this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null)}updatePlayIcons(){const e=this.isPlaying?"pause":"play";this.centerPlayEl&&this.centerPlayEl.replaceChildren(t(e,48)),this.togglePlayEl&&this.togglePlayEl.replaceChildren(t(e,i))}updateUI(){const e=this.getAttribute("size")||"m",l=this.getAttribute("variant")||"default",n=this.getAttribute("theme")||"auto",o=this.getBool("show-controls",!0),r=this.getBool("show-progress",!0),a=this.getBool("show-time",!0),h=this.getBool("show-volume",!0),u=this.getBool("enable-fullscreen",!0);this.className=[s,`${s}--size-${e}`,`${s}--variant-${l}`,`${s}--theme-${n}`,this.isPlaying&&`${s}--playing`,!this.isPlaying&&`${s}--paused`,this.isMuted&&`${s}--muted`,this.isLoading&&`${s}--loading`,this.error&&`${s}--error`,o&&this.showControlsOverlay&&`${s}--show-controls`,this.isFullscreen&&`${s}--fullscreen`].filter(Boolean).join(" ");const d=this.getAttribute("title"),c=this.getAttribute("description");this.titleEl&&(d?(this.titleEl.textContent=d,this.titleEl.hidden=!1):this.titleEl.hidden=!0),this.descEl&&(c?(this.descEl.textContent=c,this.descEl.hidden=!1):this.descEl.hidden=!0),this.overlayEl&&(this.overlayEl.hidden=!o),this.dimOverlayEl&&(this.dimOverlayEl.hidden=!o),this.progressEl&&(this.progressEl.hidden=!r),this.timeEl&&(this.timeEl.hidden=!a),this.volumeWrapEl&&(this.volumeWrapEl.hidden=!h),this.fullscreenButtonEl&&(this.fullscreenButtonEl.hidden=!u),this.fullscreenButtonEl&&this.fullscreenButtonEl.replaceChildren(t(this.isFullscreen?"shrink":"expand",i)),this.updatePlayIcons(),this.updateProgress(),this.updateTime(),this.updateVolumeUI()}}customElements.get("db-video-player")||customElements.define("db-video-player",DbVideoPlayer);export{DbVideoPlayer};
1
+ import{createDbIcon as t}from"./db-icons.js";import{t as e}from"../core/i18n.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{VIDEO_PLAYER_SIZES as i,VIDEO_PLAYER_VARIANTS as l}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const o="designbase-wc-video-player",n=20;class DbVideoPlayer extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.rafId=null,this.playlistIndex=0,this.isFullscreen=!1,this.showControlsOverlay=!1,this.isPlaying=!1,this.isMuted=!1,this.volume=1,this.lastVolumeBeforeMute=1,this.currentTime=0,this.duration=0,this.isLoading=!1,this.error=null,this.onFullscreenChange=()=>{this.isFullscreen=document.fullscreenElement===this,this.dispatchEvent(new CustomEvent("db-fullscreen-change",{detail:{isFullscreen:this.isFullscreen},bubbles:!0,composed:!0})),this.updateUI()},this.onMouseEnter=()=>{this.showControlsOverlay=!0,this.updateUI()},this.onMouseLeave=()=>{this.showControlsOverlay=!1,this.updateUI()}}static get observedAttributes(){return["src","poster","title","description","size","variant","theme","auto-play","loop","muted","show-controls","enable-fullscreen","show-progress","show-time","show-volume","playlist","current-index"]}connectedCallback(){this.built||(this.built=!0,this.build(),this.bindVideoEvents()),this.syncFromAttributes(),this.updateUI(),document.addEventListener("fullscreenchange",this.onFullscreenChange),this.addEventListener("mouseenter",this.onMouseEnter),this.addEventListener("mouseleave",this.onMouseLeave)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.removeEventListener("mouseenter",this.onMouseEnter),this.removeEventListener("mouseleave",this.onMouseLeave),this.stopProgressAnimation()}attributeChangedCallback(t){this.built&&("src"!==t&&"playlist"!==t&&"current-index"!==t?("muted"===t&&this.videoEl&&(this.videoEl.muted=this.getBool("muted")),this.updateUI()):this.loadVideoSource())}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[]}}getCurrentSrc(){const t=this.getPlaylist();if(t.length>0){const e=Number(this.getAttribute("current-index")||this.playlistIndex||0);return t[Math.max(0,Math.min(t.length-1,e))]}return this.getAttribute("src")||""}formatTime(t){if(!Number.isFinite(t)||t<0)return"0:00";return`${Math.floor(t/60)}:${Math.floor(t%60).toString().padStart(2,"0")}`}iconButton(e,s,i,l){const n=document.createElement("button");return n.type="button",n.className=`${o}__control-button`,n.setAttribute("aria-label",i),n.append(t(e,s)),n.addEventListener("click",t=>{t.stopPropagation(),l()}),n}skipButton(t,e){const s=document.createElement("button");return s.type="button",s.className=`${o}__skip-button`,s.textContent=t,s.setAttribute("aria-label",e<0?"10초 되감기":"10초 빨리감기"),s.addEventListener("click",t=>{t.stopPropagation(),this.seekBy(e)}),s}syncFromAttributes(){this.playlistIndex=Number(this.getAttribute("current-index")||0),this.isMuted=this.getBool("muted"),this.volume=this.isMuted?0:1,this.lastVolumeBeforeMute=this.volume>0?this.volume:1,this.loadVideoSource()}loadVideoSource(){if(!this.videoEl)return;const t=this.getCurrentSrc();if(!t)return;const e=new URL(t,window.location.href).href;this.videoEl.src!==e&&(this.videoEl.src=t,this.videoEl.load()),this.videoEl.poster=this.getAttribute("poster")||"",this.videoEl.autoplay=this.getBool("auto-play"),this.videoEl.loop=this.getBool("loop"),this.videoEl.muted=this.getBool("muted"),this.videoEl.playsInline=!0}bindVideoEvents(){const t=this.videoEl;t&&(t.addEventListener("play",()=>{this.isPlaying=!0,this.startProgressAnimation(),this.dispatchEvent(new CustomEvent("db-play",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("pause",()=>{this.isPlaying=!1,this.stopProgressAnimation(),this.dispatchEvent(new CustomEvent("db-pause",{bubbles:!0,composed:!0})),this.updateUI()}),t.addEventListener("timeupdate",()=>{this.currentTime=t.currentTime,this.duration=Number.isFinite(t.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||0===t.volume,!this.isMuted&&this.volume>0&&(this.lastVolumeBeforeMute=this.volume),this.dispatchEvent(new CustomEvent("db-volume-change",{detail:{volume:this.volume},bubbles:!0,composed:!0})),this.updateVolumeUI()}),t.addEventListener("ended",()=>{this.isPlaying=!1,this.stopProgressAnimation(),this.dispatchEvent(new CustomEvent("db-ended",{bubbles:!0,composed:!0}));const e=this.getPlaylist(),s=this.playlistIndex+1;e.length>0&&s<e.length&&(this.playlistIndex=s,this.loadVideoSource(),t.play()),this.updateUI()}),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("loadedmetadata",()=>{this.duration=Number.isFinite(t.duration)?t.duration:0,this.updateTime()}),t.addEventListener("canplay",()=>{this.isLoading=!1,this.updateUI()}),t.addEventListener("click",()=>this.togglePlay()))}togglePlay(){this.videoEl&&(this.videoEl.paused?this.videoEl.play():this.videoEl.pause())}toggleMute(){if(this.videoEl){if(this.isMuted)return this.videoEl.muted=!1,void(this.videoEl.volume=this.lastVolumeBeforeMute>0?this.lastVolumeBeforeMute:1);this.videoEl.volume>0&&(this.lastVolumeBeforeMute=this.videoEl.volume),this.videoEl.muted=!0,this.videoEl.volume=0}}seekBy(t){if(!this.videoEl)return;const e=Number.isFinite(this.videoEl.duration)?this.videoEl.duration:0,s=e>0?e:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(s,this.videoEl.currentTime+t));this.videoEl.currentTime=i}toggleFullscreen(){this.getBool("enable-fullscreen",!0)&&(this.isFullscreen?document.exitFullscreen?.():this.requestFullscreen?.())}build(){this.videoEl=document.createElement("video"),this.videoEl.className=`${o}__video`;const t=document.createElement("div");t.className=`${o}__loading`;const s=document.createElement("div");s.className=`${o}__spinner`,t.append(s);const i=document.createElement("div");i.className=`${o}__error`;const l=document.createElement("p");l.textContent="비디오를 재생할 수 없습니다.";const r=document.createElement("button");r.type="button",r.textContent="다시 시도",r.addEventListener("click",()=>{this.error=null,this.loadVideoSource(),this.updateUI()}),i.append(l,r),this.dimOverlayEl=document.createElement("div"),this.dimOverlayEl.className=`${o}__dim-overlay`,this.overlayEl=document.createElement("div"),this.overlayEl.className=`${o}__overlay`;const a=document.createElement("div");a.className=`${o}__top-controls`;const u=document.createElement("div");u.className=`${o}__title`;const h=document.createElement("h3"),d=document.createElement("p");u.append(h,d),a.append(u),this._titleEl=h,this._descEl=d;const m=document.createElement("div");m.className=`${o}__center-controls`;const c=this.skipButton("-10",-10);this.centerPlayEl=document.createElement("button"),this.centerPlayEl.type="button",this.centerPlayEl.className=`${o}__play-button`,this.centerPlayEl.addEventListener("click",t=>{t.stopPropagation(),this.togglePlay()});const E=this.skipButton("+10",10);m.append(c,this.centerPlayEl,E);const p=document.createElement("div");p.className=`${o}__bottom-controls`,this.progressEl=document.createElement("div"),this.progressEl.className=`${o}__progress`,this.progressBarEl=document.createElement("div"),this.progressBarEl.className=`${o}__progress-bar`,this.progressHandleEl=document.createElement("div"),this.progressHandleEl.className=`${o}__progress-handle`,this.progressEl.append(this.progressBarEl,this.progressHandleEl),this.progressEl.addEventListener("click",t=>{if(!this.videoEl||!Number.isFinite(this.duration)||this.duration<=0)return;const e=this.progressEl.getBoundingClientRect(),s=(t.clientX-e.left)/e.width;this.videoEl.currentTime=s*this.duration});const v=document.createElement("div");v.className=`${o}__controls`;const g=document.createElement("div");g.className=`${o}__left-controls`,this.togglePlayEl=this.iconButton("play",n,e("media.play"),()=>this.togglePlay()),this.volumeWrapEl=document.createElement("div"),this.volumeWrapEl.className=`${o}__volume`,this.muteButtonEl=this.iconButton("volume-up",n,e("media.mute"),()=>this.toggleMute());const b=document.createElement("div");b.className=`${o}__volume-slider`,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.videoEl||!this.volumeInputEl)return;const t=parseFloat(this.volumeInputEl.value);t>0&&(this.lastVolumeBeforeMute=t),this.videoEl.volume=t,this.videoEl.muted=0===t}),b.append(this.volumeInputEl),this.volumeWrapEl.append(this.muteButtonEl,b),this.timeEl=document.createElement("div"),this.timeEl.className=`${o}__time`,this.timeCurrentEl=document.createElement("span");const y=document.createElement("span");y.textContent="/",this.timeDurationEl=document.createElement("span"),this.timeEl.append(this.timeCurrentEl,y,this.timeDurationEl),g.append(this.togglePlayEl,this.volumeWrapEl,this.timeEl);const f=document.createElement("div");f.className=`${o}__right-controls`,this.fullscreenButtonEl=this.iconButton("expand",n,e("media.fullscreen"),()=>this.toggleFullscreen()),f.append(this.fullscreenButtonEl),v.append(g,f),p.append(this.progressEl,v),this.overlayEl.append(a,m,p),this.append(this.videoEl,t,i,this.dimOverlayEl,this.overlayEl)}get titleEl(){return this._titleEl}get descEl(){return this._descEl}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}%`)}updateTime(){this.timeCurrentEl&&(this.timeCurrentEl.textContent=this.formatTime(this.currentTime)),this.timeDurationEl&&(this.timeDurationEl.textContent=this.formatTime(this.duration))}updateVolumeUI(){const e=this.isMuted?0:this.volume;this.volumeInputEl&&(this.volumeInputEl.value=String(e)),this.muteButtonEl&&this.muteButtonEl.replaceChildren(t(this.isMuted||0===e?"mute-filled":"volume-up",n))}startProgressAnimation(){this.stopProgressAnimation();const tick=()=>{!this.videoEl||this.videoEl.paused||this.videoEl.ended||(this.currentTime=this.videoEl.currentTime,this.duration=Number.isFinite(this.videoEl.duration)?this.videoEl.duration:0,this.updateProgress(),this.updateTime(),this.rafId=requestAnimationFrame(tick))};this.rafId=requestAnimationFrame(tick)}stopProgressAnimation(){null!==this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=null)}updatePlayIcons(){const e=this.isPlaying?"pause":"play";this.centerPlayEl&&this.centerPlayEl.replaceChildren(t(e,48)),this.togglePlayEl&&this.togglePlayEl.replaceChildren(t(e,n))}updateUI(){const e=s(this.getAttribute("size"),i,"m"),r=s(this.getAttribute("variant"),l,"default"),a=this.getAttribute("theme")||"auto",u=this.getBool("show-controls",!0),h=this.getBool("show-progress",!0),d=this.getBool("show-time",!0),m=this.getBool("show-volume",!0),c=this.getBool("enable-fullscreen",!0);this.className=[o,`${o}--size-${e}`,`${o}--variant-${r}`,`${o}--theme-${a}`,this.isPlaying&&`${o}--playing`,!this.isPlaying&&`${o}--paused`,this.isMuted&&`${o}--muted`,this.isLoading&&`${o}--loading`,this.error&&`${o}--error`,u&&this.showControlsOverlay&&`${o}--show-controls`,this.isFullscreen&&`${o}--fullscreen`].filter(Boolean).join(" ");const E=this.getAttribute("title"),p=this.getAttribute("description");this.titleEl&&(E?(this.titleEl.textContent=E,this.titleEl.hidden=!1):this.titleEl.hidden=!0),this.descEl&&(p?(this.descEl.textContent=p,this.descEl.hidden=!1):this.descEl.hidden=!0),this.overlayEl&&(this.overlayEl.hidden=!u),this.dimOverlayEl&&(this.dimOverlayEl.hidden=!u),this.progressEl&&(this.progressEl.hidden=!h),this.timeEl&&(this.timeEl.hidden=!d),this.volumeWrapEl&&(this.volumeWrapEl.hidden=!m),this.fullscreenButtonEl&&(this.fullscreenButtonEl.hidden=!c),this.fullscreenButtonEl&&this.fullscreenButtonEl.replaceChildren(t(this.isFullscreen?"shrink":"expand",n)),this.updatePlayIcons(),this.updateProgress(),this.updateTime(),this.updateVolumeUI()}}customElements.get("db-video-player")||customElements.define("db-video-player",DbVideoPlayer);export{DbVideoPlayer};
@@ -1 +1 @@
1
- class DbYouTubePlayer extends HTMLElement{constructor(){super(...arguments),this.isFullscreen=!1,this.playlistIndex=0,this.onFullscreenChange=()=>{this.isFullscreen=!!document.fullscreenElement,this.dispatchEvent(new CustomEvent("db-fullscreen-change",{detail:{isFullscreen:this.isFullscreen},bubbles:!0,composed:!0})),this.render()}}static get observedAttributes(){return["video-id","title","description","size","variant","theme","auto-play","loop","muted","show-controls","enable-fullscreen","enable-keyboard","enable-touch","show-subtitles","default-subtitle-lang","playback-rate","start-time","end-time","show-related-videos","show-info","show-channel-info","show-like-buttons","show-comments","playlist","current-index"]}connectedCallback(){this.style.display="block",this.playlistIndex=Number(this.getAttribute("current-index")||0),this.render(),document.addEventListener("fullscreenchange",this.onFullscreenChange)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.onFullscreenChange)}attributeChangedCallback(){this.render()}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const s=this.getAttribute(e);return""===s||"true"===s}extractVideoId(e){if(!e)return"";if(11===e.length&&/^[a-zA-Z0-9_-]{11}$/.test(e))return e;const t=[/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/|youtube\.com\/watch\?.*&v=)([^&\n?#]+)/,/youtube\.com\/watch\?.*v=([^&\n?#]+)/];for(const s of t){const t=e.match(s);if(t)return t[1]}return e}getPlaylist(){try{const e=this.getAttribute("playlist"),t=e?JSON.parse(e):[];return Array.isArray(t)?t:[]}catch{return[]}}getCurrentVideoId(){const e=this.getPlaylist();if(e.length>0){const t=Math.max(0,Math.min(e.length-1,this.playlistIndex));return this.extractVideoId(e[t])}return this.extractVideoId(this.getAttribute("video-id")||"")}generateEmbedUrl(e){const t=new URLSearchParams;if(this.getBool("auto-play")&&t.append("autoplay","1"),this.getBool("loop")&&t.append("loop","1"),this.getBool("muted")&&t.append("mute","1"),this.getBool("show-controls",!0)||t.append("controls","0"),this.getBool("enable-fullscreen",!0)||t.append("fs","0"),this.getBool("enable-keyboard",!0)||t.append("disablekb","1"),this.getBool("enable-touch",!0)||t.append("modestbranding","1"),this.getBool("show-subtitles")){t.append("cc_load_policy","1");const e=this.getAttribute("default-subtitle-lang")||"ko";e&&t.append("cc_lang_pref",e)}const s=this.getAttribute("playback-rate")||"1";"1"!==s&&t.append("vq",s);const n=Number(this.getAttribute("start-time")||0);n>0&&t.append("start",String(n));const o=Number(this.getAttribute("end-time")||0);o>0&&t.append("end",String(o)),this.getBool("show-related-videos",!0)||t.append("rel","0"),this.getBool("show-info",!0)||t.append("showinfo","0"),this.getBool("show-channel-info",!0)||t.append("modestbranding","1"),this.getBool("show-like-buttons",!0)||t.append("modestbranding","1"),this.getBool("show-comments",!1)||t.append("modestbranding","1");const i=this.getPlaylist().map(e=>this.extractVideoId(e)).filter(Boolean);i.length>0?t.append("playlist",i.join(",")):this.getBool("loop")&&t.append("playlist",e);const r=t.toString();return`https://www.youtube.com/embed/${e}${r?`?${r}`:""}`}render(){const e=this.getAttribute("size")||"m",t=this.getAttribute("variant")||"default",s=this.getAttribute("theme")||"auto";this.className=["designbase-wc-youtube-player",`designbase-wc-youtube-player--${e}`,`designbase-wc-youtube-player--${t}`,`designbase-wc-youtube-player--${s}`,this.isFullscreen&&"designbase-wc-youtube-player--fullscreen"].filter(Boolean).join(" ");const n=this.getCurrentVideoId();if(!n){const e=document.createElement("div");return e.className="designbase-wc-youtube-player__error",e.textContent="동영상을 불러올 수 없습니다.",void this.replaceChildren(e)}const o=document.createElement("div");o.className="designbase-wc-youtube-player__container";const i=document.createElement("iframe");i.className="designbase-wc-youtube-player__iframe",i.src=this.generateEmbedUrl(n),i.title=this.getAttribute("title")||`YouTube 동영상: ${n}`,i.setAttribute("frameborder","0"),i.setAttribute("allow","accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"),i.setAttribute("referrerpolicy","strict-origin-when-cross-origin"),i.referrerPolicy="strict-origin-when-cross-origin",i.allowFullscreen=!0,o.append(i);const r=this.getAttribute("description"),a=document.createDocumentFragment();if(a.append(o),r&&"minimal"!==t){const e=document.createElement("div");e.className="designbase-wc-youtube-player__description";const t=document.createElement("p");t.textContent=r,e.append(t),a.append(e)}this.replaceChildren(a)}}customElements.get("db-youtube-player")||customElements.define("db-youtube-player",DbYouTubePlayer);export{DbYouTubePlayer};
1
+ import{coerceToContract as e}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{YOUTUBE_PLAYER_SIZES as t,YOUTUBE_PLAYER_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbYouTubePlayer extends HTMLElement{constructor(){super(...arguments),this.isFullscreen=!1,this.playlistIndex=0,this.onFullscreenChange=()=>{this.isFullscreen=!!document.fullscreenElement,this.dispatchEvent(new CustomEvent("db-fullscreen-change",{detail:{isFullscreen:this.isFullscreen},bubbles:!0,composed:!0})),this.render()}}static get observedAttributes(){return["video-id","title","description","size","variant","theme","auto-play","loop","muted","show-controls","enable-fullscreen","enable-keyboard","enable-touch","show-subtitles","default-subtitle-lang","playback-rate","start-time","end-time","show-related-videos","show-info","show-channel-info","show-like-buttons","show-comments","playlist","current-index"]}connectedCallback(){this.style.display="block",this.playlistIndex=Number(this.getAttribute("current-index")||0),this.render(),document.addEventListener("fullscreenchange",this.onFullscreenChange)}disconnectedCallback(){document.removeEventListener("fullscreenchange",this.onFullscreenChange)}attributeChangedCallback(){this.render()}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const s=this.getAttribute(e);return""===s||"true"===s}extractVideoId(e){if(!e)return"";if(11===e.length&&/^[a-zA-Z0-9_-]{11}$/.test(e))return e;const t=[/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/|youtube\.com\/watch\?.*&v=)([^&\n?#]+)/,/youtube\.com\/watch\?.*v=([^&\n?#]+)/];for(const s of t){const t=e.match(s);if(t)return t[1]}return e}getPlaylist(){try{const e=this.getAttribute("playlist"),t=e?JSON.parse(e):[];return Array.isArray(t)?t:[]}catch{return[]}}getCurrentVideoId(){const e=this.getPlaylist();if(e.length>0){const t=Math.max(0,Math.min(e.length-1,this.playlistIndex));return this.extractVideoId(e[t])}return this.extractVideoId(this.getAttribute("video-id")||"")}generateEmbedUrl(e){const t=new URLSearchParams;if(this.getBool("auto-play")&&t.append("autoplay","1"),this.getBool("loop")&&t.append("loop","1"),this.getBool("muted")&&t.append("mute","1"),this.getBool("show-controls",!0)||t.append("controls","0"),this.getBool("enable-fullscreen",!0)||t.append("fs","0"),this.getBool("enable-keyboard",!0)||t.append("disablekb","1"),this.getBool("enable-touch",!0)||t.append("modestbranding","1"),this.getBool("show-subtitles")){t.append("cc_load_policy","1");const e=this.getAttribute("default-subtitle-lang")||"ko";t.append("cc_lang_pref",e)}const s=this.getAttribute("playback-rate")||"1";"1"!==s&&t.append("vq",s);const n=Number(this.getAttribute("start-time")||0);n>0&&t.append("start",String(n));const o=Number(this.getAttribute("end-time")||0);o>0&&t.append("end",String(o)),this.getBool("show-related-videos",!0)||t.append("rel","0"),this.getBool("show-info",!0)||t.append("showinfo","0"),this.getBool("show-channel-info",!0)||t.append("modestbranding","1"),this.getBool("show-like-buttons",!0)||t.append("modestbranding","1"),this.getBool("show-comments",!1)||t.append("modestbranding","1");const i=this.getPlaylist().map(e=>this.extractVideoId(e)).filter(Boolean);i.length>0?t.append("playlist",i.join(",")):this.getBool("loop")&&t.append("playlist",e);const r=t.toString();return`https://www.youtube.com/embed/${e}${r?`?${r}`:""}`}render(){const n=e(this.getAttribute("size"),t,"m"),o=e(this.getAttribute("variant"),s,"default"),i=this.getAttribute("theme")||"auto";this.className=["designbase-wc-youtube-player",`designbase-wc-youtube-player--${n}`,`designbase-wc-youtube-player--${o}`,`designbase-wc-youtube-player--${i}`,this.isFullscreen&&"designbase-wc-youtube-player--fullscreen"].filter(Boolean).join(" ");const r=this.getCurrentVideoId();if(!r){const e=document.createElement("div");return e.className="designbase-wc-youtube-player__error",e.textContent="동영상을 불러올 수 없습니다.",void this.replaceChildren(e)}const a=document.createElement("div");a.className="designbase-wc-youtube-player__container";const l=document.createElement("iframe");l.className="designbase-wc-youtube-player__iframe",l.src=this.generateEmbedUrl(r),l.title=this.getAttribute("title")||`YouTube 동영상: ${r}`,l.setAttribute("frameborder","0"),l.setAttribute("allow","accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"),l.setAttribute("referrerpolicy","strict-origin-when-cross-origin"),l.referrerPolicy="strict-origin-when-cross-origin",l.allowFullscreen=!0,a.append(l);const c=this.getAttribute("description"),u=document.createDocumentFragment();if(u.append(a),c&&"minimal"!==o){const e=document.createElement("div");e.className="designbase-wc-youtube-player__description";const t=document.createElement("p");t.textContent=c,e.append(t),u.append(e)}this.replaceChildren(u)}}customElements.get("db-youtube-player")||customElements.define("db-youtube-player",DbYouTubePlayer);export{DbYouTubePlayer};