@designbasekorea/ui-wc 0.8.1 → 0.8.2
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.
- package/CHANGELOG.md +19 -0
- package/README.md +18 -0
- package/dist/esm/components/animation-background/controls.js +1 -1
- package/dist/esm/components/animation-background/layers.js +1 -1
- package/dist/esm/components/db-activity-heatmap.d.ts +38 -0
- package/dist/esm/components/db-activity-heatmap.js +1 -0
- package/dist/esm/components/db-animation-background.d.ts +2 -0
- package/dist/esm/components/db-animation-background.js +1 -1
- package/dist/esm/components/db-app-badge.d.ts +2 -0
- package/dist/esm/components/db-app-badge.js +1 -1
- package/dist/esm/components/db-audio-player.d.ts +4 -0
- package/dist/esm/components/db-audio-player.js +1 -1
- package/dist/esm/components/db-avatar.js +1 -1
- package/dist/esm/components/db-backdrop.d.ts +4 -0
- package/dist/esm/components/db-backdrop.js +1 -1
- package/dist/esm/components/db-badge.d.ts +2 -2
- package/dist/esm/components/db-badge.js +1 -1
- package/dist/esm/components/db-bottom-navigation.js +1 -1
- package/dist/esm/components/db-bottom-sheet.d.ts +5 -0
- package/dist/esm/components/db-bottom-sheet.js +1 -1
- package/dist/esm/components/db-button.d.ts +13 -0
- package/dist/esm/components/db-button.js +1 -1
- package/dist/esm/components/db-calendar.js +1 -1
- package/dist/esm/components/db-card.js +1 -1
- package/dist/esm/components/db-carousel.js +1 -1
- package/dist/esm/components/db-chat-composer.d.ts +14 -0
- package/dist/esm/components/db-chat-composer.js +1 -1
- package/dist/esm/components/db-chat-message.d.ts +15 -2
- package/dist/esm/components/db-chat-message.js +1 -1
- package/dist/esm/components/db-chat-orb.d.ts +6 -8
- package/dist/esm/components/db-chat-orb.js +1 -1
- package/dist/esm/components/db-chat-room.d.ts +12 -1
- package/dist/esm/components/db-chat-room.js +1 -1
- package/dist/esm/components/db-chat-welcome.js +1 -1
- package/dist/esm/components/db-chat-widget.d.ts +43 -10
- package/dist/esm/components/db-chat-widget.js +1 -1
- package/dist/esm/components/db-checkbox.d.ts +11 -0
- package/dist/esm/components/db-checkbox.js +1 -1
- package/dist/esm/components/db-chip.js +1 -1
- package/dist/esm/components/db-color-picker.js +1 -1
- package/dist/esm/components/db-confirm.d.ts +5 -0
- package/dist/esm/components/db-confirm.js +1 -1
- package/dist/esm/components/db-container.js +1 -1
- package/dist/esm/components/db-cookie-banner.js +1 -1
- package/dist/esm/components/db-date-picker.d.ts +3 -0
- package/dist/esm/components/db-date-picker.js +1 -1
- package/dist/esm/components/db-divider.js +1 -1
- package/dist/esm/components/db-download-progress.d.ts +3 -4
- package/dist/esm/components/db-download-progress.js +1 -1
- package/dist/esm/components/db-drawer.d.ts +5 -1
- package/dist/esm/components/db-drawer.js +1 -1
- package/dist/esm/components/db-dropdown.js +1 -1
- package/dist/esm/components/db-dropzone.js +1 -1
- package/dist/esm/components/db-email-verify.d.ts +2 -2
- package/dist/esm/components/db-email-verify.js +1 -1
- package/dist/esm/components/db-file-uploader.js +1 -1
- package/dist/esm/components/db-floating-action-button.d.ts +1 -0
- package/dist/esm/components/db-floating-action-button.js +1 -1
- package/dist/esm/components/db-footer.js +1 -1
- package/dist/esm/components/db-gantt.js +1 -1
- package/dist/esm/components/db-indicator.js +1 -1
- package/dist/esm/components/db-input.d.ts +7 -0
- package/dist/esm/components/db-input.js +1 -1
- package/dist/esm/components/db-kanban.js +1 -1
- package/dist/esm/components/db-lightbox.d.ts +4 -0
- package/dist/esm/components/db-lightbox.js +1 -1
- package/dist/esm/components/db-list.js +1 -1
- package/dist/esm/components/db-masonry.js +1 -1
- package/dist/esm/components/db-menu-item.js +1 -1
- package/dist/esm/components/db-modal.d.ts +10 -0
- package/dist/esm/components/db-modal.js +1 -1
- package/dist/esm/components/db-navbar.d.ts +4 -2
- package/dist/esm/components/db-navbar.js +1 -1
- package/dist/esm/components/db-onboarding-modal.d.ts +3 -0
- package/dist/esm/components/db-onboarding-modal.js +1 -1
- package/dist/esm/components/db-otp-input.d.ts +3 -2
- package/dist/esm/components/db-otp-input.js +1 -1
- package/dist/esm/components/db-page-header.js +1 -1
- package/dist/esm/components/db-phone-verify.d.ts +2 -2
- package/dist/esm/components/db-phone-verify.js +1 -1
- package/dist/esm/components/db-popover.js +1 -1
- package/dist/esm/components/db-progress-step.js +1 -1
- package/dist/esm/components/db-progress.js +1 -1
- package/dist/esm/components/db-progressbar.js +1 -1
- package/dist/esm/components/db-radio.d.ts +1 -0
- package/dist/esm/components/db-radio.js +1 -1
- package/dist/esm/components/db-range-slider.d.ts +9 -4
- package/dist/esm/components/db-range-slider.js +1 -1
- package/dist/esm/components/db-rating.js +1 -1
- package/dist/esm/components/db-resizable-panels.d.ts +14 -0
- package/dist/esm/components/db-resizable-panels.js +1 -1
- package/dist/esm/components/db-search-bar.js +1 -1
- package/dist/esm/components/db-section-cta.js +1 -1
- package/dist/esm/components/db-section-feature.js +1 -1
- package/dist/esm/components/db-section-pricing.js +1 -1
- package/dist/esm/components/db-section.js +1 -1
- package/dist/esm/components/db-segment-control.js +1 -1
- package/dist/esm/components/db-select.d.ts +8 -0
- package/dist/esm/components/db-select.js +1 -1
- package/dist/esm/components/db-sidebar.d.ts +41 -6
- package/dist/esm/components/db-sidebar.js +1 -1
- package/dist/esm/components/db-skeleton.js +1 -1
- package/dist/esm/components/db-spinner.d.ts +4 -0
- package/dist/esm/components/db-spinner.js +1 -1
- package/dist/esm/components/db-split-view.js +1 -1
- package/dist/esm/components/db-stat.js +1 -1
- package/dist/esm/components/db-stepper.js +1 -1
- package/dist/esm/components/db-table.js +1 -1
- package/dist/esm/components/db-tabs.js +1 -1
- package/dist/esm/components/db-testimonial.js +1 -1
- package/dist/esm/components/db-textarea.js +1 -1
- package/dist/esm/components/db-time-picker.d.ts +5 -2
- package/dist/esm/components/db-time-picker.js +1 -1
- package/dist/esm/components/db-timeline.js +1 -1
- package/dist/esm/components/db-toast.d.ts +8 -1
- package/dist/esm/components/db-toast.js +1 -1
- package/dist/esm/components/db-toggle.d.ts +2 -0
- package/dist/esm/components/db-toggle.js +1 -1
- package/dist/esm/components/db-tooltip.js +1 -1
- package/dist/esm/components/db-top-banner.js +1 -1
- package/dist/esm/components/db-tutorial.d.ts +1 -0
- package/dist/esm/components/db-tutorial.js +1 -1
- package/dist/esm/components/db-two-factor.d.ts +2 -2
- package/dist/esm/components/db-two-factor.js +1 -1
- package/dist/esm/components/db-video-player.d.ts +3 -0
- package/dist/esm/components/db-video-player.js +1 -1
- package/dist/esm/components/section-block-header-utils.js +1 -1
- package/dist/esm/core/a11y.d.ts +40 -0
- package/dist/esm/core/a11y.js +1 -0
- package/dist/esm/core/base-element.d.ts +41 -0
- package/dist/esm/core/base-element.js +1 -0
- package/dist/esm/core/dom.d.ts +35 -0
- package/dist/esm/core/dom.js +1 -0
- package/dist/esm/core/focus-trap.d.ts +41 -0
- package/dist/esm/core/focus-trap.js +1 -0
- package/dist/esm/core/i18n.d.ts +82 -0
- package/dist/esm/core/i18n.js +1 -0
- package/dist/esm/core/scroll-lock.d.ts +19 -0
- package/dist/esm/core/scroll-lock.js +1 -0
- package/dist/esm/core/uid.d.ts +23 -0
- package/dist/esm/core/uid.js +1 -0
- package/dist/esm/helpers/toast.d.ts +10 -10
- package/dist/esm/helpers/toast.js +1 -1
- package/dist/esm/index.d.ts +12 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -0
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/primitives.js +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +583 -59
- package/dist/index.esm.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +433 -55
- package/dist/react/index.esm.js +1 -1
- package/package.json +12 -3
- /package/dist/chunks/{lottie-26a5e98f.js → lottie-3f885725.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as t}from"./db-icons.js";const e={s:40,m:60,l:80,full:100},s=["default","persistent","temporary","fullscreen"],i=["slide","fade","scale","none"];function resolveHeightPercent(t){if(!t)return e.m;const s=e[t];if(s)return Math.min(100,Math.max(20,s));const i=Number(t);return Number.isFinite(i)?Math.min(100,Math.max(20,i)):e.m}class DbBottomSheet extends HTMLElement{constructor(){super(...arguments),this.sheetHeightPercent=e.m,this.isDragging=!1,this.isVisible=!1,this.isMounted=!1,this.keyHandler=null,this.dragState={active:!1,pointerId:-1,startY:0,startHeight:e.m,lastY:0,lastTime:0},this.handlePointerDown=t=>{"true"!==this.getAttribute("disable-drag")&&0===t.button&&(t.preventDefault(),t.currentTarget.setPointerCapture(t.pointerId),this.dragState={active:!0,pointerId:t.pointerId,startY:t.clientY,startHeight:this.sheetHeightPercent,lastY:t.clientY,lastTime:Date.now()},this.isDragging=!0,this.syncActiveClasses())},this.handlePointerMove=t=>{const e=this.dragState;if(!e.active||t.pointerId!==e.pointerId)return;t.preventDefault(),e.lastY=t.clientY,e.lastTime=Date.now();const s=window.innerHeight||1,i=(e.startY-t.clientY)/s*100,r=this.getMaxHeightLimit(resolveHeightPercent(this.getAttribute("height")));this.sheetHeightPercent=Math.min(r,Math.max(20,e.startHeight+i)),this.applySheetDimensions()},this.handlePointerUp=t=>{const e=this.dragState;if(!e.active||t.pointerId!==e.pointerId)return;const s=t.currentTarget;s.hasPointerCapture(t.pointerId)&&s.releasePointerCapture(t.pointerId),this.finishDrag()}}static get observedAttributes(){return["open","title","subtitle","height","max-height","variant","disable-backdrop-click","disable-escape-key-down","disable-drag","show-close-button","animation","animation-duration","z-index","show-backdrop","backdrop-blur","backdrop-opacity","sticky-header","sticky-footer"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}shouldMountPortal(){return this.isOpenRequested()||this.isMounted}connectedCallback(){this.style.display="contents",this.childObserver=new MutationObserver(()=>{this.isOpenRequested()&&this.render()}),this.childObserver.observe(this,{childList:!0}),this.syncOpenState()}disconnectedCallback(){this.childObserver?.disconnect(),this.childObserver=void 0,this.clearTimers(),this.detachEscape(),this.root?.remove(),this.root=void 0,document.body.style.overflow=""}attributeChangedCallback(t){this.isConnected&&("open"!==t?("height"===t&&this.isOpenRequested()&&(this.sheetHeightPercent=resolveHeightPercent(this.getAttribute("height"))),this.shouldMountPortal()&&(this.render(),this.isMounted&&this.syncActiveClasses())):this.syncOpenState())}isOpenRequested(){return this.open}clearTimers(){this.enterFrame&&(cancelAnimationFrame(this.enterFrame),this.enterFrame=void 0),this.exitTimer&&(clearTimeout(this.exitTimer),this.exitTimer=void 0)}scheduleEnterAnimation(){this.enterFrame&&cancelAnimationFrame(this.enterFrame),this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=void 0,this.isOpenRequested()&&this.sheet&&(this.sheet.offsetHeight,this.isVisible=!0,this.syncActiveClasses())})})}getMaxHeightLimit(t){const e=Number(this.getAttribute("max-height")||0),s=t>=100;return Math.min(100,Math.max(t,e||(s?100:90)))}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}attachEscape(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"true"!==this.getAttribute("disable-escape-key-down")&&this.close()},document.addEventListener("keydown",this.keyHandler))}detachEscape(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}collectSlotted(t){const e=Array.from(this.querySelectorAll(`:scope > [slot="${t}"]`));if(e.length)return e;if("header"===t){const t=this.sheet?.querySelector(".designbase-wc-bottom-sheet__header-main");return t?Array.from(t.children):[]}if("footer"===t){const t=this.sheet?.querySelector(".designbase-wc-bottom-sheet__footer");return t?Array.from(t.children):[]}return[]}collectContentNodes(){const t=Array.from(this.children).filter(t=>{const e=t.getAttribute("slot");return!e||"default"===e});return t.length?t:this.contentEl?Array.from(this.contentEl.children):[]}finishDrag(){const t=this.dragState;if(!t.active)return;t.active=!1,this.isDragging=!1;const e=t.lastY-t.startY,s=e/Math.max(1,Date.now()-t.lastTime),i=window.innerHeight||1,r=(t.startY-t.lastY)/i*100,n=this.getMaxHeightLimit(resolveHeightPercent(this.getAttribute("height"))),o=Math.min(n,Math.max(20,t.startHeight+r));o<=22||e>72||s>.6?this.close():(this.sheetHeightPercent=o,this.applySheetDimensions(),this.syncActiveClasses())}syncOpenState(){const t=this.isOpenRequested(),e=Number(this.getAttribute("animation-duration")||400);if(this.clearTimers(),t)return this.sheetHeightPercent=resolveHeightPercent(this.getAttribute("height")),this.render(),this.isMounted=!0,this.isVisible=!1,this.syncActiveClasses(),this.root&&!this.root.isConnected&&document.body.append(this.root),this.scheduleEnterAnimation(),document.body.style.overflow="hidden",void this.attachEscape();this.isVisible=!1,this.syncActiveClasses(),this.exitTimer=setTimeout(()=>{this.exitTimer=void 0,this.detachContentToHost(),this.isMounted=!1,this.syncActiveClasses(),this.root?.remove(),document.body.style.overflow="",this.detachEscape()},e),this.detachEscape()}syncActiveClasses(){if(!this.sheet)return;const t=resolveHeightPercent(this.getAttribute("height")),e=this.getAttribute("variant")||"default",r=this.getAttribute("animation")||"slide",n=s.includes(e)?e:"default",o=i.includes(r)?r:"slide",a="false"!==this.getAttribute("show-backdrop"),h=this.hasAttribute("sticky-header"),c=this.hasAttribute("sticky-footer");this.sheet.className=["designbase-wc-bottom-sheet",`designbase-wc-bottom-sheet--${n}`,`designbase-wc-bottom-sheet--${o}`,this.isMounted&&this.isVisible&&"designbase-wc-bottom-sheet--open",this.isDragging&&"designbase-wc-bottom-sheet--dragging",h&&"designbase-wc-bottom-sheet--sticky-header",c&&"designbase-wc-bottom-sheet--sticky-footer",!a&&"designbase-wc-bottom-sheet--no-backdrop",(t>=100||this.sheetHeightPercent>=100)&&"designbase-wc-bottom-sheet--full"].filter(Boolean).join(" "),this.backdrop?.classList.toggle("designbase-wc-backdrop--open",this.isMounted&&this.isVisible)}applySheetDimensions(){if(!this.sheet)return;const t=this.getMaxHeightLimit(resolveHeightPercent(this.getAttribute("height")));this.sheet.style.height=`${this.sheetHeightPercent}vh`,this.sheet.style.maxHeight=`${t}vh`}detachContentToHost(){this.contentEl&&Array.from(this.contentEl.children).forEach(t=>this.append(t));const t=this.sheet?.querySelector(".designbase-wc-bottom-sheet__header-main");t&&Array.from(t.children).forEach(t=>{"bottom-sheet-title"!==t.id&&"bottom-sheet-subtitle"!==t.id&&this.append(t)});const e=this.sheet?.querySelector(".designbase-wc-bottom-sheet__footer");e&&Array.from(e.children).forEach(t=>this.append(t))}render(){if(!this.shouldMountPortal())return;const e=this.getAttribute("title"),s=this.getAttribute("subtitle"),i="false"!==this.getAttribute("show-close-button"),r="false"!==this.getAttribute("show-backdrop"),n=this.hasAttribute("backdrop-blur"),o=this.getAttribute("backdrop-opacity")||"0.5",a=this.getAttribute("animation-duration")||"400",h=this.getAttribute("z-index")||"1000",c=this.hasAttribute("sticky-header"),d=this.hasAttribute("sticky-footer"),l=this.collectSlotted("header"),b=this.collectSlotted("footer"),m=this.collectContentNodes();if(this.root||(this.root=document.createElement("div"),this.root.setAttribute("data-wc-internal",""),this.backdrop=document.createElement("div"),this.backdrop.className="designbase-wc-backdrop designbase-wc-backdrop--bottom-sheet",this.backdrop.setAttribute("role","presentation"),this.backdrop.addEventListener("click",t=>{t.target===this.backdrop&&"true"!==this.getAttribute("disable-backdrop-click")&&this.close()}),this.sheet=document.createElement("div"),this.sheet.setAttribute("role","dialog"),this.sheet.setAttribute("aria-modal","true"),this.grabBar=document.createElement("div"),this.grabBar.className="designbase-wc-bottom-sheet__grab-bar",this.grabBar.addEventListener("pointerdown",this.handlePointerDown),this.grabBar.addEventListener("pointermove",this.handlePointerMove),this.grabBar.addEventListener("pointerup",this.handlePointerUp),this.grabBar.addEventListener("pointercancel",this.handlePointerUp),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-bottom-sheet__content"),this.root.replaceChildren(),r&&this.backdrop&&(this.backdrop.className=["designbase-wc-backdrop","designbase-wc-backdrop--bottom-sheet",n&&"designbase-wc-backdrop--blur"].filter(Boolean).join(" "),this.backdrop.style.setProperty("--backdrop-opacity",o),this.backdrop.style.setProperty("--bottom-sheet-animation-duration",`${a}ms`),this.backdrop.style.zIndex=h,this.backdrop.setAttribute("aria-hidden",String(!this.isOpenRequested())),this.root.append(this.backdrop)),!this.sheet||!this.grabBar||!this.contentEl)return;this.sheet.style.zIndex=String(Number(h)+1),this.sheet.style.setProperty("--bottom-sheet-animation-duration",`${a}ms`),this.applySheetDimensions(),e?this.sheet.setAttribute("aria-labelledby","bottom-sheet-title"):this.sheet.removeAttribute("aria-labelledby"),s?this.sheet.setAttribute("aria-describedby","bottom-sheet-subtitle"):this.sheet.removeAttribute("aria-describedby"),this.sheet.replaceChildren();const u="true"===this.getAttribute("disable-drag");if(this.grabBar.className=["designbase-wc-bottom-sheet__grab-bar",!u&&"designbase-wc-bottom-sheet__grab-bar--draggable"].filter(Boolean).join(" "),this.grabBar.replaceChildren(),!u){const t=document.createElement("div");t.className="designbase-wc-bottom-sheet__handle",t.setAttribute("aria-hidden","true"),this.grabBar.append(t)}this.sheet.append(this.grabBar);if(Boolean(e||s||l.length||i)){const r=document.createElement("div");r.className=["designbase-wc-bottom-sheet__header",c&&"designbase-wc-bottom-sheet__header--sticky"].filter(Boolean).join(" ");const n=document.createElement("div");if(n.className="designbase-wc-bottom-sheet__header-main",l.length)l.forEach(t=>n.append(t));else{if(e){const t=document.createElement("h2");t.id="bottom-sheet-title",t.className="designbase-wc-bottom-sheet__title",t.textContent=e,n.append(t)}if(s){const t=document.createElement("p");t.id="bottom-sheet-subtitle",t.className="designbase-wc-bottom-sheet__subtitle",t.textContent=s,n.append(t)}}if(r.append(n),i){const e=document.createElement("button");e.type="button",e.className="designbase-wc-bottom-sheet__close-button",e.setAttribute("aria-label","닫기"),e.append(t("close",20)),e.addEventListener("click",()=>this.close()),r.append(e)}this.sheet.append(r)}if(this.contentEl.replaceChildren(...m),this.sheet.append(this.contentEl),b.length){const t=document.createElement("div");t.className=["designbase-wc-bottom-sheet__footer",d&&"designbase-wc-bottom-sheet__footer--sticky"].filter(Boolean).join(" "),b.forEach(e=>t.append(e)),this.sheet.append(t)}this.root.append(this.sheet),this.isMounted&&!this.root.isConnected&&document.body.append(this.root),this.syncActiveClasses()}}customElements.get("db-bottom-sheet")||customElements.define("db-bottom-sheet",DbBottomSheet);export{DbBottomSheet};
|
|
1
|
+
import{createDbIcon as t}from"./db-icons.js";import{createFocusTrap as e}from"../core/focus-trap.js";import{unlockScroll as s,lockScroll as i}from"../core/scroll-lock.js";import{BOTTOM_SHEET_VARIANTS as r,BOTTOM_SHEET_ANIMATIONS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const n={s:40,m:60,l:80,full:100};function resolveHeightPercent(t){if(!t)return n.m;const e=n[t];if(e)return Math.min(100,Math.max(20,e));const s=Number(t);return Number.isFinite(s)?Math.min(100,Math.max(20,s)):n.m}class DbBottomSheet extends HTMLElement{constructor(){super(...arguments),this.sheetHeightPercent=n.m,this.scrollLocked=!1,this.isDragging=!1,this.isVisible=!1,this.isMounted=!1,this.keyHandler=null,this.dragState={active:!1,pointerId:-1,startY:0,startHeight:n.m,lastY:0,lastTime:0},this.handlePointerDown=t=>{"true"!==this.getAttribute("disable-drag")&&0===t.button&&(t.preventDefault(),t.currentTarget.setPointerCapture(t.pointerId),this.dragState={active:!0,pointerId:t.pointerId,startY:t.clientY,startHeight:this.sheetHeightPercent,lastY:t.clientY,lastTime:Date.now()},this.isDragging=!0,this.syncActiveClasses())},this.handlePointerMove=t=>{const e=this.dragState;if(!e.active||t.pointerId!==e.pointerId)return;t.preventDefault(),e.lastY=t.clientY,e.lastTime=Date.now();const s=window.innerHeight||1,i=(e.startY-t.clientY)/s*100,r=this.getMaxHeightLimit(resolveHeightPercent(this.getAttribute("height")));this.sheetHeightPercent=Math.min(r,Math.max(20,e.startHeight+i)),this.applySheetDimensions()},this.handlePointerUp=t=>{const e=this.dragState;if(!e.active||t.pointerId!==e.pointerId)return;const s=t.currentTarget;s.hasPointerCapture(t.pointerId)&&s.releasePointerCapture(t.pointerId),this.finishDrag()}}static get observedAttributes(){return["open","title","subtitle","height","max-height","variant","disable-backdrop-click","disable-escape-key-down","disable-drag","show-close-button","animation","animation-duration","z-index","show-backdrop","backdrop-blur","backdrop-opacity","sticky-header","sticky-footer"]}get open(){return this.hasAttribute("open")&&"false"!==this.getAttribute("open")}set open(t){t?this.setAttribute("open",""):this.removeAttribute("open")}shouldMountPortal(){return this.isOpenRequested()||this.isMounted}connectedCallback(){this.style.display="contents",this.childObserver=new MutationObserver(()=>{this.isOpenRequested()&&this.render()}),this.childObserver.observe(this,{childList:!0}),this.syncOpenState()}disconnectedCallback(){this.childObserver?.disconnect(),this.childObserver=void 0,this.clearTimers(),this.detachEscape(),this.root?.remove(),this.root=void 0,this.teardownOverlay()}teardownOverlay(){this.focusTrap?.deactivate(),this.focusTrap=void 0,this.scrollLocked&&(this.scrollLocked=!1,s())}attributeChangedCallback(t){this.isConnected&&("open"!==t?("height"===t&&this.isOpenRequested()&&(this.sheetHeightPercent=resolveHeightPercent(this.getAttribute("height"))),this.shouldMountPortal()&&(this.render(),this.isMounted&&this.syncActiveClasses())):this.syncOpenState())}isOpenRequested(){return this.open}clearTimers(){this.enterFrame&&(cancelAnimationFrame(this.enterFrame),this.enterFrame=void 0),this.exitTimer&&(clearTimeout(this.exitTimer),this.exitTimer=void 0)}scheduleEnterAnimation(){this.enterFrame&&cancelAnimationFrame(this.enterFrame),this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=requestAnimationFrame(()=>{this.enterFrame=void 0,this.isOpenRequested()&&this.sheet&&(this.sheet.offsetHeight,this.isVisible=!0,this.syncActiveClasses())})})}getMaxHeightLimit(t){const e=Number(this.getAttribute("max-height")||0),s=t>=100;return Math.min(100,Math.max(t,e||(s?100:90)))}close(){this.open=!1,this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}attachEscape(){this.keyHandler||(this.keyHandler=t=>{"Escape"===t.key&&"true"!==this.getAttribute("disable-escape-key-down")&&this.close()},document.addEventListener("keydown",this.keyHandler))}detachEscape(){this.keyHandler&&(document.removeEventListener("keydown",this.keyHandler),this.keyHandler=null)}collectSlotted(t){const e=Array.from(this.querySelectorAll(`:scope > [slot="${t}"]`));if(e.length)return e;if("header"===t){const t=this.sheet?.querySelector(".designbase-wc-bottom-sheet__header-main");return t?Array.from(t.children):[]}if("footer"===t){const t=this.sheet?.querySelector(".designbase-wc-bottom-sheet__footer");return t?Array.from(t.children):[]}return[]}collectContentNodes(){const t=Array.from(this.children).filter(t=>{const e=t.getAttribute("slot");return!e||"default"===e});return t.length?t:this.contentEl?Array.from(this.contentEl.children):[]}finishDrag(){const t=this.dragState;if(!t.active)return;t.active=!1,this.isDragging=!1;const e=t.lastY-t.startY,s=e/Math.max(1,Date.now()-t.lastTime),i=window.innerHeight||1,r=(t.startY-t.lastY)/i*100,o=this.getMaxHeightLimit(resolveHeightPercent(this.getAttribute("height"))),n=Math.min(o,Math.max(20,t.startHeight+r));n<=22||e>72||s>.6?this.close():(this.sheetHeightPercent=n,this.applySheetDimensions(),this.syncActiveClasses())}syncOpenState(){const t=this.isOpenRequested(),s=Number(this.getAttribute("animation-duration")||400);if(this.clearTimers(),t)return this.sheetHeightPercent=resolveHeightPercent(this.getAttribute("height")),this.render(),this.isMounted=!0,this.isVisible=!1,this.syncActiveClasses(),this.root&&!this.root.isConnected&&document.body.append(this.root),this.scheduleEnterAnimation(),this.scrollLocked||(i(),this.scrollLocked=!0),this.sheet&&!this.focusTrap&&(this.focusTrap=e(this.sheet),requestAnimationFrame(()=>this.focusTrap?.activate())),void this.attachEscape();this.isVisible=!1,this.syncActiveClasses(),this.exitTimer=setTimeout(()=>{this.exitTimer=void 0,this.detachContentToHost(),this.isMounted=!1,this.syncActiveClasses(),this.root?.remove(),this.teardownOverlay(),this.detachEscape()},s),this.detachEscape()}syncActiveClasses(){if(!this.sheet)return;const t=resolveHeightPercent(this.getAttribute("height")),e=this.getAttribute("variant")||"default",s=this.getAttribute("animation")||"slide",i=r.includes(e)?e:"default",n=o.includes(s)?s:"slide",a="false"!==this.getAttribute("show-backdrop"),h=this.hasAttribute("sticky-header"),c=this.hasAttribute("sticky-footer");this.sheet.className=["designbase-wc-bottom-sheet",`designbase-wc-bottom-sheet--${i}`,`designbase-wc-bottom-sheet--${n}`,this.isMounted&&this.isVisible&&"designbase-wc-bottom-sheet--open",this.isDragging&&"designbase-wc-bottom-sheet--dragging",h&&"designbase-wc-bottom-sheet--sticky-header",c&&"designbase-wc-bottom-sheet--sticky-footer",!a&&"designbase-wc-bottom-sheet--no-backdrop",(t>=100||this.sheetHeightPercent>=100)&&"designbase-wc-bottom-sheet--full"].filter(Boolean).join(" "),this.backdrop?.classList.toggle("designbase-wc-backdrop--open",this.isMounted&&this.isVisible)}applySheetDimensions(){if(!this.sheet)return;const t=this.getMaxHeightLimit(resolveHeightPercent(this.getAttribute("height")));this.sheet.style.height=`${this.sheetHeightPercent}vh`,this.sheet.style.maxHeight=`${t}vh`}detachContentToHost(){this.contentEl&&Array.from(this.contentEl.children).forEach(t=>this.append(t));const t=this.sheet?.querySelector(".designbase-wc-bottom-sheet__header-main");t&&Array.from(t.children).forEach(t=>{"bottom-sheet-title"!==t.id&&"bottom-sheet-subtitle"!==t.id&&this.append(t)});const e=this.sheet?.querySelector(".designbase-wc-bottom-sheet__footer");e&&Array.from(e.children).forEach(t=>this.append(t))}render(){if(!this.shouldMountPortal())return;const e=this.getAttribute("title"),s=this.getAttribute("subtitle"),i="false"!==this.getAttribute("show-close-button"),r="false"!==this.getAttribute("show-backdrop"),o=this.hasAttribute("backdrop-blur"),n=this.getAttribute("backdrop-opacity")||"0.5",a=this.getAttribute("animation-duration")||"400",h=this.getAttribute("z-index")||"1000",c=this.hasAttribute("sticky-header"),d=this.hasAttribute("sticky-footer"),l=this.collectSlotted("header"),b=this.collectSlotted("footer"),m=this.collectContentNodes();if(this.root||(this.root=document.createElement("div"),this.root.setAttribute("data-wc-internal",""),this.backdrop=document.createElement("div"),this.backdrop.className="designbase-wc-backdrop designbase-wc-backdrop--bottom-sheet",this.backdrop.setAttribute("role","presentation"),this.backdrop.addEventListener("click",t=>{t.target===this.backdrop&&"true"!==this.getAttribute("disable-backdrop-click")&&this.close()}),this.sheet=document.createElement("div"),this.sheet.setAttribute("role","dialog"),this.sheet.setAttribute("aria-modal","true"),this.grabBar=document.createElement("div"),this.grabBar.className="designbase-wc-bottom-sheet__grab-bar",this.grabBar.addEventListener("pointerdown",this.handlePointerDown),this.grabBar.addEventListener("pointermove",this.handlePointerMove),this.grabBar.addEventListener("pointerup",this.handlePointerUp),this.grabBar.addEventListener("pointercancel",this.handlePointerUp),this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-bottom-sheet__content"),this.root.replaceChildren(),r&&this.backdrop&&(this.backdrop.className=["designbase-wc-backdrop","designbase-wc-backdrop--bottom-sheet",o&&"designbase-wc-backdrop--blur"].filter(Boolean).join(" "),this.backdrop.style.setProperty("--backdrop-opacity",n),this.backdrop.style.setProperty("--bottom-sheet-animation-duration",`${a}ms`),this.backdrop.style.zIndex=h,this.backdrop.setAttribute("aria-hidden",String(!this.isOpenRequested())),this.root.append(this.backdrop)),!this.sheet||!this.grabBar||!this.contentEl)return;this.sheet.style.zIndex=String(Number(h)+1),this.sheet.style.setProperty("--bottom-sheet-animation-duration",`${a}ms`),this.applySheetDimensions(),e?this.sheet.setAttribute("aria-labelledby","bottom-sheet-title"):this.sheet.removeAttribute("aria-labelledby"),s?this.sheet.setAttribute("aria-describedby","bottom-sheet-subtitle"):this.sheet.removeAttribute("aria-describedby"),this.sheet.replaceChildren();const u="true"===this.getAttribute("disable-drag");if(this.grabBar.className=["designbase-wc-bottom-sheet__grab-bar",!u&&"designbase-wc-bottom-sheet__grab-bar--draggable"].filter(Boolean).join(" "),this.grabBar.replaceChildren(),!u){const t=document.createElement("div");t.className="designbase-wc-bottom-sheet__handle",t.setAttribute("aria-hidden","true"),this.grabBar.append(t)}this.sheet.append(this.grabBar);if(Boolean(e||s||l.length||i)){const r=document.createElement("div");r.className=["designbase-wc-bottom-sheet__header",c&&"designbase-wc-bottom-sheet__header--sticky"].filter(Boolean).join(" ");const o=document.createElement("div");if(o.className="designbase-wc-bottom-sheet__header-main",l.length)l.forEach(t=>o.append(t));else{if(e){const t=document.createElement("h2");t.id="bottom-sheet-title",t.className="designbase-wc-bottom-sheet__title",t.textContent=e,o.append(t)}if(s){const t=document.createElement("p");t.id="bottom-sheet-subtitle",t.className="designbase-wc-bottom-sheet__subtitle",t.textContent=s,o.append(t)}}if(r.append(o),i){const e=document.createElement("button");e.type="button",e.className="designbase-wc-bottom-sheet__close-button",e.setAttribute("aria-label","닫기"),e.append(t("close",20)),e.addEventListener("click",()=>this.close()),r.append(e)}this.sheet.append(r)}if(this.contentEl.replaceChildren(...m),this.sheet.append(this.contentEl),b.length){const t=document.createElement("div");t.className=["designbase-wc-bottom-sheet__footer",d&&"designbase-wc-bottom-sheet__footer--sticky"].filter(Boolean).join(" "),b.forEach(e=>t.append(e)),this.sheet.append(t)}this.root.append(this.sheet),this.isMounted&&!this.root.isConnected&&document.body.append(this.root),this.syncActiveClasses()}}customElements.get("db-bottom-sheet")||customElements.define("db-bottom-sheet",DbBottomSheet);export{DbBottomSheet};
|
|
@@ -6,10 +6,15 @@
|
|
|
6
6
|
*/
|
|
7
7
|
declare class DbButton extends HTMLElement {
|
|
8
8
|
static get observedAttributes(): string[];
|
|
9
|
+
/**
|
|
10
|
+
* 계약에 없는 값이 attribute 로 들어오면 기본값으로 되돌린다 — throw 하지 않는다.
|
|
11
|
+
* 커스텀 엘리먼트의 attribute 는 임의 문자열을 받으므로 타입으로 막을 수 없다. (STD-COERCE)
|
|
12
|
+
*/
|
|
9
13
|
get variant(): string;
|
|
10
14
|
set variant(value: string);
|
|
11
15
|
get size(): string;
|
|
12
16
|
set size(value: string);
|
|
17
|
+
/** 빈 값은 "사이즈에 따라 자동" 을 뜻하므로 계약값에 포함되지 않아도 유효하다 */
|
|
13
18
|
get radius(): string;
|
|
14
19
|
set radius(value: string);
|
|
15
20
|
get accentStyle(): string;
|
|
@@ -42,6 +47,14 @@ declare class DbButton extends HTMLElement {
|
|
|
42
47
|
private getDefaultRadiusClass;
|
|
43
48
|
private syncRadius;
|
|
44
49
|
private syncAccentStyle;
|
|
50
|
+
/**
|
|
51
|
+
* outline 스타일의 회전하는 테두리 글로우.
|
|
52
|
+
*
|
|
53
|
+
* conic-gradient 의 각도를 직접 애니메이션하려면 `@property` 가 필요해 기준선이 올라간다.
|
|
54
|
+
* 대신 넘치는 정사각형을 `overflow: hidden` 컨테이너 안에서 회전시키고,
|
|
55
|
+
* 컨테이너의 `::after` 가 안쪽을 덮어 1.5px 테두리만 남기는 방식을 쓴다.
|
|
56
|
+
*/
|
|
57
|
+
private syncAccentRing;
|
|
45
58
|
private syncAccentField;
|
|
46
59
|
private syncModifier;
|
|
47
60
|
private syncBooleanModifier;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isDbIconName as t,createDbIcon as e}from"./db-icons.js";
|
|
1
|
+
import{isDbIconName as t,createDbIcon as e}from"./db-icons.js";import{coerceWithAliases as s,coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{BUTTON_RADII as n,BUTTON_SIZES as a,BUTTON_ACCENT_STYLES as r,BUTTON_VARIANT_ALIASES as c,BUTTON_VARIANTS as o}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const d=["disabled","loading","icon-only","full-width"];class DbButton extends HTMLElement{constructor(){super(...arguments),this.handleClick=t=>{if(this.disabled||this.loading)return t.preventDefault(),void t.stopPropagation();this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))},this.handleKeyDown=t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.disabled||this.loading||this.classList.add("designbase-wc-button--pressed"),this.click())},this.handleKeyUp=t=>{"Enter"!==t.key&&" "!==t.key||this.classList.remove("designbase-wc-button--pressed")},this.handlePointerDown=()=>{this.disabled||this.loading||this.classList.add("designbase-wc-button--pressed")},this.handlePointerUp=()=>{this.classList.remove("designbase-wc-button--pressed")}}static get observedAttributes(){return["variant","size","radius","accent-style","type","loading-text","start-icon","end-icon",...d]}get variant(){return s(this.getAttribute("variant"),o,c,"primary")}set variant(t){this.setAttribute("variant",t)}get size(){return i(this.getAttribute("size"),a,"m")}set size(t){this.setAttribute("size",t)}get radius(){const t=this.getAttribute("radius");return t?i(t,n,n[0]):""}set radius(t){t?this.setAttribute("radius",t):this.removeAttribute("radius")}get accentStyle(){return i(this.getAttribute("accent-style"),r,"solid")}set accentStyle(t){t?this.setAttribute("accent-style",t):this.removeAttribute("accent-style")}get type(){return this.getAttribute("type")||"button"}set type(t){this.setAttribute("type",t)}get loadingText(){return this.getAttribute("loading-text")||""}set loadingText(t){t?this.setAttribute("loading-text",t):this.removeAttribute("loading-text")}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get loading(){return this.hasAttribute("loading")}set loading(t){this.toggleAttribute("loading",t)}get iconOnly(){return this.hasAttribute("icon-only")}set iconOnly(t){this.toggleAttribute("icon-only",t)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(t){this.toggleAttribute("full-width",t)}connectedCallback(){this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeyDown),this.addEventListener("keyup",this.handleKeyUp),this.addEventListener("pointerdown",this.handlePointerDown),this.addEventListener("pointerup",this.handlePointerUp),this.addEventListener("pointerleave",this.handlePointerUp),this.addEventListener("pointercancel",this.handlePointerUp),this.syncAttributes()}disconnectedCallback(){this.removeEventListener("click",this.handleClick),this.removeEventListener("keydown",this.handleKeyDown),this.removeEventListener("keyup",this.handleKeyUp),this.removeEventListener("pointerdown",this.handlePointerDown),this.removeEventListener("pointerup",this.handlePointerUp),this.removeEventListener("pointerleave",this.handlePointerUp),this.removeEventListener("pointercancel",this.handlePointerUp)}attributeChangedCallback(){this.syncAttributes()}syncAttributes(){this.classList.add("designbase-wc-button"),this.setAttribute("role","button"),this.setAttribute("aria-disabled",String(this.disabled||this.loading)),this.loading?this.setAttribute("aria-busy","true"):this.removeAttribute("aria-busy"),this.disabled||this.loading?this.removeAttribute("tabindex"):this.hasAttribute("tabindex")||this.setAttribute("tabindex","0"),this.syncModifier("variant",this.variant),this.syncModifier("size",this.size),this.syncRadius(),this.syncAccentStyle(),this.syncAccentField(),this.syncAccentRing(),this.syncBooleanModifier("disabled"),this.syncBooleanModifier("icon-only"),this.syncBooleanModifier("full-width"),this.syncLoadingVisual(),this.loading?(this.querySelector(":scope > .designbase-wc-button__start-icon")?.remove(),this.querySelector(":scope > .designbase-wc-button__end-icon")?.remove()):this.syncIcons()}getIconSize(){return"s"===this.size?16:"l"===this.size?24:20}resolveIconName(e){if(e&&t(e))return e}isManagedIconNode(t){return t instanceof HTMLElement&&(t.classList.contains("designbase-wc-button__start-icon")||t.classList.contains("designbase-wc-button__end-icon")||t.classList.contains("designbase-wc-button__spinner")||t.classList.contains("designbase-wc-button__accent-field")||t.classList.contains("designbase-wc-button__accent-glass")||t.classList.contains("designbase-wc-button__accent-orb")||t.classList.contains("designbase-wc-button__accent-ring"))}syncIcons(){const t=this.resolveIconName(this.getAttribute("start-icon")),s=this.resolveIconName(this.getAttribute("end-icon")),i=this.getIconSize();let n=this.querySelector(":scope > .designbase-wc-button__start-icon");if(t){if(!n){n=document.createElement("span"),n.className="designbase-wc-button__start-icon",n.setAttribute("aria-hidden","true");const t=Array.from(this.childNodes).find(t=>!this.isManagedIconNode(t));t?this.insertBefore(n,t):this.append(n)}n.replaceChildren(e(t,i))}else n?.remove();let a=this.querySelector(":scope > .designbase-wc-button__end-icon");s?(a||(a=document.createElement("span"),a.className="designbase-wc-button__end-icon",a.setAttribute("aria-hidden","true")),a.replaceChildren(e(s,i)),this.append(a)):a?.remove()}getDefaultRadiusClass(){if(n.includes(this.radius))return`designbase-wc-button--radius-${this.radius}`;const t=a.includes(this.size)?this.size:"m";return`designbase-wc-button--radius-${"s"===t||"l"===t?t:"m"}`}syncRadius(){n.forEach(t=>this.classList.remove(`designbase-wc-button--radius-${t}`)),this.classList.add(this.getDefaultRadiusClass())}syncAccentStyle(){if(r.forEach(t=>this.classList.remove(`designbase-wc-button--accent-${t}`)),"accent"!==this.variant)return;const t=this.accentStyle,e=r.includes(t)?t:"solid";this.classList.add(`designbase-wc-button--accent-${e}`)}syncAccentRing(){const t="accent"===this.variant&&"outline"===this.accentStyle,e=this.querySelector(":scope > .designbase-wc-button__accent-ring");if(!t)return void e?.remove();if(e)return;const s=document.createElement("span");s.className="designbase-wc-button__accent-ring",s.setAttribute("aria-hidden","true");const i=document.createElement("span");i.className="designbase-wc-button__accent-ring-spin",s.appendChild(i),this.insertBefore(s,this.firstChild)}syncAccentField(){const t="accent"===this.variant&&"gradient"===this.accentStyle,e=this.querySelector(":scope > .designbase-wc-button__accent-field"),s=this.querySelector(":scope > .designbase-wc-button__accent-glass");if(!t)return e?.remove(),void s?.remove();let i=e;if(!i){i=document.createElement("span"),i.className="designbase-wc-button__accent-field",i.setAttribute("aria-hidden","true");for(let t=1;t<=5;t+=1){const e=document.createElement("span");e.className=`designbase-wc-button__accent-orb designbase-wc-button__accent-orb--${t}`,i.appendChild(e)}this.insertBefore(i,this.firstChild)}if(!s){const t=document.createElement("span");t.className="designbase-wc-button__accent-glass",t.setAttribute("aria-hidden","true"),i.insertAdjacentElement("afterend",t)}}syncModifier(t,e){if(Array.from(this.classList).filter(e=>e.startsWith(`designbase-wc-button--${t}-`)).forEach(t=>this.classList.remove(t)),"variant"===t||"size"===t){("variant"===t?o:a).forEach(t=>this.classList.remove(`designbase-wc-button--${t}`)),this.classList.add(`designbase-wc-button--${e}`)}}syncBooleanModifier(t){const e=`designbase-wc-button--${t}`;this.classList.toggle(e,this.hasAttribute(t))}getSpinnerSize(){return a.includes(this.size)?this.size:"m"}syncLoadingVisual(){this.classList.toggle("designbase-wc-button--loading",this.loading);const t=this.querySelector(":scope > .designbase-wc-button__spinner");if(!this.loading)return void t?.remove();const e=`designbase-wc-button__spinner designbase-wc-spinner designbase-wc-spinner--circular designbase-wc-spinner--${this.getSpinnerSize()}`;if(t)return t.className=e,void t.setAttribute("aria-hidden","true");const s=document.createElement("span");s.className=e,s.setAttribute("aria-hidden","true"),s.innerHTML='<svg class="designbase-wc-spinner__circular" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><circle class="designbase-wc-spinner__circular-track" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none"></circle><circle class="designbase-wc-spinner__circular-indicator" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"></circle></svg>',this.insertBefore(s,this.firstChild)}}customElements.get("db-button")||customElements.define("db-button",DbButton);export{DbButton};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as e,getDbComponentIconSize as t}from"./db-icons.js";import{parseISODate as a,toISODate as n}from"./date-picker-utils.js";import"./db-modal.js";import"./db-input.js";import"./db-select.js";import"./db-date-picker.js";import"./db-time-picker.js";import"./db-button.js";const s="designbase-wc-calendar",i=[{value:"meeting",label:"회의"},{value:"task",label:"업무"},{value:"reminder",label:"알림"},{value:"birthday",label:"생일"},{value:"holiday",label:"휴일"},{value:"custom",label:"기타"}],d=[{value:"#17a2b8",label:"청록"},{value:"#0d6efd",label:"파랑"},{value:"#198754",label:"초록"},{value:"#ffc107",label:"노랑"},{value:"#dc3545",label:"빨강"},{value:"#6f42c1",label:"보라"}];class DbCalendar extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.currentView="month",this.selectedDate=new Date,this._events=[],this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.draggedEvent=null,this.dragOverDate=null,this.selectedDateRange={start:null,end:null},this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""}}static get observedAttributes(){return["view","current-date","events","locale","show-weekends","highlight-today","show-outside-days"]}connectedCallback(){this.built||this.build(),this.readAttributes(),this.render()}attributeChangedCallback(){this.built&&(this.readAttributes(),this.render())}get locale(){return this.getAttribute("locale")||"ko-KR"}get showWeekends(){return"false"!==this.getAttribute("show-weekends")}get highlightToday(){return"false"!==this.getAttribute("highlight-today")}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get events(){return this._events}set events(e){"string"!=typeof e?(this._events=Array.isArray(e)?e:[],this.setAttribute("events",JSON.stringify(this._events))):this.setAttribute("events",e)}build(){this.built=!0,this.headerEl=document.createElement("div"),this.headerEl.className=`${s}__header`,this.bodyEl=document.createElement("div"),this.bodyEl.className=`${s}__body`,this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","m"),this.modalEl.addEventListener("db-close",()=>this.closeModal())}readAttributes(){this.currentView="month";const e=a(this.getAttribute("current-date"));e&&(this.selectedDate=e);const t=this.getAttribute("events");if(t)try{const e=JSON.parse(t);this._events=Array.isArray(e)?e:[]}catch{this._events=[]}else this._events=[]}isSameDate(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}eventsForDate(e){return this._events.filter(t=>{const n=a(t.date);return!!n&&this.isSameDate(n,e)})}emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}handleViewChange(e){this.currentView="month",this.emit("db-view-change",{view:e}),this.render()}shiftMonth(e){const t=new Date(this.selectedDate);t.setMonth(t.getMonth()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}shiftYear(e){const t=new Date(this.selectedDate);t.setFullYear(t.getFullYear()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}handleDateClick(e){this.selectedDate=e,this.emit("db-date-click",{date:n(e)}),!this.selectedDateRange.start||this.selectedDateRange.start&&this.selectedDateRange.end?this.selectedDateRange={start:e,end:null}:this.selectedDateRange.start&&!this.selectedDateRange.end&&(e<this.selectedDateRange.start?this.selectedDateRange={start:e,end:this.selectedDateRange.start}:this.selectedDateRange={start:this.selectedDateRange.start,end:e}),this.openAddModal(e)}handleDragStart(e,t){this.draggedEvent=e,t.dataTransfer?.setData("text/plain",e.id),t.dataTransfer?.setData("application/json",JSON.stringify(e)),t.dataTransfer&&(t.dataTransfer.effectAllowed="move")}handleDragOver(e,t){t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="move"),this.dragOverDate=e,this.render()}handleDragLeave(e){const t=e.relatedTarget,a=e.currentTarget;a&&t&&a.contains(t)||(this.dragOverDate=null,this.render())}handleDrop(e,t){if(t.preventDefault(),!this.draggedEvent)return;const a={...this.draggedEvent,date:n(e)};this.emit("db-event-edit",{event:a}),this.draggedEvent=null,this.dragOverDate=null,this.render()}handleDragEnd(){this.draggedEvent=null,this.dragOverDate=null,this.render()}handleEventClick(e,t){t.stopPropagation(),this.selectedEvent=e,this.isEditing=!0;const n=a(e.date);n&&(this.selectedDate=n),this.eventForm={title:e.title,description:e.description||"",startTime:e.startTime||"09:00",endTime:e.endTime||"10:00",type:e.type,color:e.color||"#17a2b8",isAllDay:e.isAllDay||!1,location:e.location||""},this.emit("db-event-click",{event:e}),this.showEventModal=!0,this.render()}openAddModal(e){this.selectedDate=e,this.selectedEvent=null,this.isEditing=!1,this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""},this.showEventModal=!0,this.render()}closeModal(){this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.render()}saveEvent(){if(!this.eventForm.title.trim())return void window.alert("제목을 입력해주세요.");const e={title:this.eventForm.title.trim(),description:this.eventForm.description,date:n(this.selectedDate),startTime:this.eventForm.startTime,endTime:this.eventForm.endTime,type:this.eventForm.type,color:this.eventForm.color,isAllDay:this.eventForm.isAllDay,location:this.eventForm.location};if(this.isEditing&&this.selectedEvent){const t={...this.selectedEvent,...e};this.emit("db-event-edit",{event:t})}else this.emit("db-event-add",{event:e});this.closeModal()}deleteEvent(){this.selectedEvent&&window.confirm("정말로 이 일정을 삭제하시겠습니까?")&&(this.emit("db-event-delete",{eventId:this.selectedEvent.id}),this.closeModal())}renderHeader(){if(!this.headerEl)return;this.headerEl.replaceChildren();const a=document.createElement("div");a.className=`${s}__navigation`;const n=t("m"),i=document.createElement("button");i.type="button",i.className=`${s}__nav-button`,i.setAttribute("aria-label","이전"),i.appendChild(e("chevron-left",n)),i.addEventListener("click",()=>{this.shiftMonth(-1)});const d=document.createElement("div");d.className=`${s}__title`,d.textContent=this.selectedDate.toLocaleDateString(this.locale,{year:"numeric",month:"long"});const l=document.createElement("button");l.type="button",l.className=`${s}__nav-button`,l.setAttribute("aria-label","다음"),l.appendChild(e("chevron-right",n)),l.addEventListener("click",()=>{this.shiftMonth(1)}),a.append(i,d,l),this.headerEl.appendChild(a)}renderMonthView(){const e=document.createElement("div");e.className=`${s}__month-view`;const t=document.createElement("div");t.className=`${s}__weekdays`,["일","월","화","수","목","금","토"].forEach(e=>{const a=document.createElement("div");a.className=`${s}__weekday`,a.textContent=e,t.appendChild(a)}),e.appendChild(t);const a=document.createElement("div");a.className=`${s}__days`;const n=this.selectedDate.getFullYear(),i=this.selectedDate.getMonth(),d=new Date(n,i,1),l=new Date(d);l.setDate(l.getDate()-d.getDay());const r=new Date;for(let e=0;e<42;e+=1){const t=new Date(l);t.setDate(l.getDate()+e);const n=t.getMonth()===i;if(!this.showOutsideDays&&!n)continue;const d=0===t.getDay()||6===t.getDay();if(!this.showWeekends&&d)continue;const o=document.createElement("div"),c=this.selectedDateRange.start&&this.selectedDateRange.end&&t>=this.selectedDateRange.start&&t<=this.selectedDateRange.end,h=this.selectedDateRange.start&&t.toDateString()===this.selectedDateRange.start.toDateString(),m=this.selectedDateRange.end&&t.toDateString()===this.selectedDateRange.end.toDateString(),u=Boolean(c&&!h&&!m);o.className=[`${s}__day`,n&&`${s}__day--current-month`,this.highlightToday&&t.toDateString()===r.toDateString()&&`${s}__day--today`,this.isSameDate(t,this.selectedDate)&&`${s}__day--selected`,h&&`${s}__day--selected--start`,m&&`${s}__day--selected--end`,u&&`${s}__day--selected--middle`,!this.showWeekends&&d&&`${s}__day--weekend`].filter(Boolean).join(" "),o.addEventListener("click",()=>this.handleDateClick(t));const v=document.createElement("span");v.className=`${s}__day-number`,v.textContent=String(t.getDate()),o.appendChild(v);const p=this.eventsForDate(t);if(p.length){const e=document.createElement("div");if(e.className=`${s}__day-events`,p.slice(0,2).forEach(t=>{const a=document.createElement("div");a.className=[`${s}__event-bar`,`${s}__event-bar--${t.type}`].filter(Boolean).join(" "),t.color&&(a.style.backgroundColor=t.color),this.draggedEvent?.id===t.id&&a.classList.add(`${s}__event-bar--dragging`),a.title=t.title,a.draggable=!0;const n=document.createElement("span");n.className=`${s}__event-title`,n.textContent=t.title,a.appendChild(n),a.addEventListener("click",e=>this.handleEventClick(t,e)),a.addEventListener("dragstart",e=>this.handleDragStart(t,e)),a.addEventListener("dragend",()=>this.handleDragEnd()),e.appendChild(a)}),p.length>2){const t=document.createElement("div");t.className=`${s}__more-events`,t.textContent=`+${p.length-2} more`,e.appendChild(t)}o.appendChild(e)}const g=document.createElement("div");g.className=[`${s}__drop-zone`,this.dragOverDate&&this.isSameDate(this.dragOverDate,t)&&`${s}__drop-zone--active`].filter(Boolean).join(" "),g.addEventListener("dragover",e=>this.handleDragOver(t,e)),g.addEventListener("dragleave",e=>this.handleDragLeave(e)),g.addEventListener("drop",e=>this.handleDrop(t,e)),o.appendChild(g),a.appendChild(o)}return e.appendChild(a),e}renderYearView(){const e=document.createElement("div");e.className=`${s}__year-view`;const t=this.selectedDate.getFullYear();for(let n=0;n<12;n+=1){const i=new Date(t,n,1),d=this._events.filter(e=>{const s=a(e.date);return s&&s.getFullYear()===t&&s.getMonth()===n}),l=document.createElement("div");l.className=`${s}__year-month`,l.addEventListener("click",()=>{this.selectedDate=i,this.handleViewChange("month")});const r=document.createElement("h3");if(r.className=`${s}__year-month-title`,r.textContent=i.toLocaleDateString(this.locale,{month:"long"}),l.appendChild(r),d.length){const e=document.createElement("div");if(e.className=`${s}__year-month-events`,d.slice(0,4).forEach(t=>{const a=document.createElement("span");a.className=[`${s}__year-event`,`${s}__year-event--${t.type}`].join(" "),t.color&&(a.style.backgroundColor=t.color),e.appendChild(a)}),d.length>4){const t=document.createElement("span");t.className=`${s}__year-more-events`,t.textContent=`+${d.length-4} more`,e.appendChild(t)}l.appendChild(e)}e.appendChild(l)}return e}renderWeekView(){const e=document.createElement("div");e.className=`${s}__week-view`;const t=new Date,a=new Date(this.selectedDate);a.setDate(this.selectedDate.getDate()-this.selectedDate.getDay());const n=document.createElement("div");n.className=`${s}__week-header`;const i=document.createElement("div");i.className=`${s}__time-column-header`,n.appendChild(i);for(let e=0;e<7;e+=1){const i=new Date(a);i.setDate(a.getDate()+e);const d=document.createElement("div");d.className=[`${s}__week-day-header`,i.toDateString()===t.toDateString()&&`${s}__week-day-header--today`].filter(Boolean).join(" ");const l=document.createElement("span");l.className=`${s}__week-day-name`,l.textContent=i.toLocaleDateString(this.locale,{weekday:"short"});const r=document.createElement("span");r.className=`${s}__week-day-number`,r.textContent=String(i.getDate()),d.append(l,r),n.appendChild(d)}e.appendChild(n);const d=document.createElement("div");d.className=`${s}__week-grid`;const l=document.createElement("div");l.className=`${s}__week-time-column`;for(let e=6;e<=22;e+=1){const t=document.createElement("div");t.className=`${s}__time-slot`;const a=document.createElement("span");a.className=`${s}__time-label`,a.textContent=`${String(e).padStart(2,"0")}:00`,t.appendChild(a),l.appendChild(t)}d.appendChild(l);const r=document.createElement("div");r.className=`${s}__week-columns`;for(let e=0;e<7;e+=1){const t=new Date(a);t.setDate(a.getDate()+e);const n=document.createElement("div");n.className=`${s}__week-column`;for(let e=6;e<=22;e+=1){const a=document.createElement("div");a.className=`${s}__week-cell`,a.title=`${t.toLocaleDateString()} ${String(e).padStart(2,"0")}:00`,a.addEventListener("click",()=>{this.selectedDate=new Date(t),this.eventForm.startTime=`${String(e).padStart(2,"0")}:00`,this.eventForm.endTime=`${String(e+1).padStart(2,"0")}:00`,this.openAddModal(this.selectedDate)}),n.appendChild(a)}this.eventsForDate(t).forEach(e=>{if(!e.startTime)return;const[t,a]=e.startTime.split(":").map(Number),i=.8*(60*(t-6)+(a||0)),d=(e.endTime||e.startTime).split(":").map(Number),l=60*(d[0]||t)+(d[1]||0),r=60*t+(a||0),o=Math.max(20,48*(l-r)/60),c=document.createElement("div");c.className=[`${s}__week-event`,`${s}__week-event--${e.type}`].filter(Boolean).join(" "),c.textContent=e.title,c.title=e.title,c.style.backgroundColor=e.color||"#17a2b8",c.style.top=`${i}px`,c.style.height=`${o}px`,c.addEventListener("click",t=>this.handleEventClick(e,t)),n.appendChild(c)}),r.appendChild(n)}return d.appendChild(r),e.appendChild(d),e}renderModal(){if(!this.modalEl)return;if(this.modalEl.replaceChildren(),!this.showEventModal)return void this.modalEl.removeAttribute("open");this.modalEl.setAttribute("open","true"),this.modalEl.setAttribute("title",this.isEditing?"일정 편집":"새 일정 추가");const e=document.createElement("div");e.className=`${s}__event-form`;const t=document.createElement("db-input");t.setAttribute("label","제목 *"),t.setAttribute("placeholder","일정 제목을 입력하세요"),t.setAttribute("full-width",""),t.setAttribute("value",this.eventForm.title),t.addEventListener("db-input",e=>{this.eventForm.title=e.detail.value});const l=document.createElement("db-input");l.setAttribute("label","설명"),l.setAttribute("placeholder","일정 설명을 입력하세요"),l.setAttribute("full-width",""),l.setAttribute("value",this.eventForm.description),l.addEventListener("db-input",e=>{this.eventForm.description=e.detail.value});const r=document.createElement("db-date-picker");r.setAttribute("label","날짜"),r.setAttribute("full-width",""),r.setAttribute("value",n(this.selectedDate)),r.addEventListener("db-change",e=>{const t=a(e.detail.value);t&&(this.selectedDate=t)});const o=document.createElement("db-select");o.setAttribute("label","일정 타입"),o.setAttribute("full-width",""),o.setAttribute("options",JSON.stringify(i)),o.setAttribute("value",this.eventForm.type),o.addEventListener("db-change",e=>{this.eventForm.type=e.detail.value});const c=document.createElement("db-select");c.setAttribute("label","색상"),c.setAttribute("full-width",""),c.setAttribute("options",JSON.stringify(d)),c.setAttribute("value",this.eventForm.color),c.addEventListener("db-change",e=>{this.eventForm.color=e.detail.value});const h=document.createElement("db-time-picker");h.setAttribute("label","시작 시간"),h.setAttribute("full-width",""),h.setAttribute("value",this.eventForm.startTime),h.addEventListener("db-change",e=>{this.eventForm.startTime=e.detail.value});const m=document.createElement("db-time-picker");m.setAttribute("label","종료 시간"),m.setAttribute("full-width",""),m.setAttribute("value",this.eventForm.endTime),m.addEventListener("db-change",e=>{this.eventForm.endTime=e.detail.value}),e.append(t,l,r,o,c,h,m);const u=document.createElement("div");u.className="designbase-wc-modal__body",u.setAttribute("data-modal-part","body"),u.appendChild(e);const v=document.createElement("div");v.className="designbase-wc-modal__footer",v.setAttribute("data-modal-part","footer");const p=document.createElement("div");if(p.className=`${s}__modal-actions`,this.isEditing){const e=document.createElement("db-button");e.setAttribute("variant","danger"),e.textContent="삭제",e.addEventListener("click",()=>this.deleteEvent()),p.appendChild(e)}const g=document.createElement("div");g.className=`${s}__modal-buttons`;const b=document.createElement("db-button");b.setAttribute("variant","secondary"),b.textContent="취소",b.addEventListener("click",()=>this.closeModal());const E=document.createElement("db-button");E.setAttribute("variant","primary"),E.textContent=this.isEditing?"수정":"저장",E.addEventListener("click",()=>this.saveEvent()),g.append(b,E),p.appendChild(g),v.appendChild(p),this.modalEl.append(u,v)}render(){this.className=s,this.replaceChildren(),this.headerEl&&this.bodyEl&&(this.renderHeader(),this.bodyEl.replaceChildren(),this.bodyEl.appendChild(this.renderMonthView()),this.append(this.headerEl,this.bodyEl),this.renderModal(),this.showEventModal&&this.modalEl&&this.appendChild(this.modalEl))}}customElements.get("db-calendar")||customElements.define("db-calendar",DbCalendar);export{DbCalendar};
|
|
1
|
+
import{createDbIcon as e,getDbComponentIconSize as t}from"./db-icons.js";import{parseISODate as a,toISODate as n}from"./date-picker-utils.js";import"./db-modal.js";import"./db-input.js";import"./db-select.js";import"./db-date-picker.js";import"./db-time-picker.js";import"./db-button.js";const s="designbase-wc-calendar",i=[{value:"meeting",label:"회의"},{value:"task",label:"업무"},{value:"reminder",label:"알림"},{value:"birthday",label:"생일"},{value:"holiday",label:"휴일"},{value:"custom",label:"기타"}],d=[{value:"#17a2b8",label:"청록"},{value:"#0d6efd",label:"파랑"},{value:"#198754",label:"초록"},{value:"#ffc107",label:"노랑"},{value:"#dc3545",label:"빨강"},{value:"#6f42c1",label:"보라"}];class DbCalendar extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.currentView="month",this.selectedDate=new Date,this._events=[],this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.draggedEvent=null,this.dragOverDate=null,this.selectedDateRange={start:null,end:null},this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""}}static get observedAttributes(){return["view","current-date","events","locale","show-weekends","highlight-today","show-outside-days"]}connectedCallback(){this.built||this.build(),this.readAttributes(),this.render()}attributeChangedCallback(){this.built&&(this.readAttributes(),this.render())}get locale(){return this.getAttribute("locale")||"ko-KR"}get showWeekends(){return"false"!==this.getAttribute("show-weekends")}get highlightToday(){return"false"!==this.getAttribute("highlight-today")}get showOutsideDays(){return"false"!==this.getAttribute("show-outside-days")}get events(){return this._events}set events(e){"string"!=typeof e?(this._events=Array.isArray(e)?e:[],this.setAttribute("events",JSON.stringify(this._events))):this.setAttribute("events",e)}build(){this.built=!0,this.headerEl=document.createElement("div"),this.headerEl.className=`${s}__header`,this.bodyEl=document.createElement("div"),this.bodyEl.className=`${s}__body`,this.modalEl=document.createElement("db-modal"),this.modalEl.setAttribute("size","m"),this.modalEl.addEventListener("db-close",()=>this.closeModal())}readAttributes(){this.currentView="month";const e=a(this.getAttribute("current-date"));e&&(this.selectedDate=e);const t=this.getAttribute("events");if(t)try{const e=JSON.parse(t);this._events=Array.isArray(e)?e:[]}catch{this._events=[]}else this._events=[]}isSameDate(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()}eventsForDate(e){return this._events.filter(t=>{const n=a(t.date);return!!n&&this.isSameDate(n,e)})}emit(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}handleViewChange(e){this.currentView="month",this.emit("db-view-change",{view:e}),this.render()}shiftMonth(e){const t=new Date(this.selectedDate);t.setMonth(t.getMonth()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}shiftYear(e){const t=new Date(this.selectedDate);t.setFullYear(t.getFullYear()+e),this.selectedDate=t,this.emit("db-month-change",{date:n(t)}),this.render()}handleDateClick(e){this.selectedDate=e,this.emit("db-date-click",{date:n(e)}),!this.selectedDateRange.start||this.selectedDateRange.start&&this.selectedDateRange.end?this.selectedDateRange={start:e,end:null}:this.selectedDateRange.start&&!this.selectedDateRange.end&&(e<this.selectedDateRange.start?this.selectedDateRange={start:e,end:this.selectedDateRange.start}:this.selectedDateRange={start:this.selectedDateRange.start,end:e}),this.openAddModal(e)}handleDragStart(e,t){this.draggedEvent=e,t.dataTransfer?.setData("text/plain",e.id),t.dataTransfer?.setData("application/json",JSON.stringify(e)),t.dataTransfer&&(t.dataTransfer.effectAllowed="move")}handleDragOver(e,t){t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="move"),this.dragOverDate=e,this.render()}handleDragLeave(e){const t=e.relatedTarget,a=e.currentTarget;a&&t&&a.contains(t)||(this.dragOverDate=null,this.render())}handleDrop(e,t){if(t.preventDefault(),!this.draggedEvent)return;const a={...this.draggedEvent,date:n(e)};this.emit("db-event-edit",{event:a}),this.draggedEvent=null,this.dragOverDate=null,this.render()}handleDragEnd(){this.draggedEvent=null,this.dragOverDate=null,this.render()}handleEventClick(e,t){t.stopPropagation(),this.selectedEvent=e,this.isEditing=!0;const n=a(e.date);n&&(this.selectedDate=n),this.eventForm={title:e.title,description:e.description||"",startTime:e.startTime||"09:00",endTime:e.endTime||"10:00",type:e.type,color:e.color||"#17a2b8",isAllDay:e.isAllDay||!1,location:e.location||""},this.emit("db-event-click",{event:e}),this.showEventModal=!0,this.render()}openAddModal(e){this.selectedDate=e,this.selectedEvent=null,this.isEditing=!1,this.eventForm={title:"",description:"",startTime:"09:00",endTime:"10:00",type:"meeting",color:"#17a2b8",isAllDay:!1,location:""},this.showEventModal=!0,this.render()}closeModal(){this.showEventModal=!1,this.selectedEvent=null,this.isEditing=!1,this.render()}saveEvent(){if(!this.eventForm.title.trim())return void window.alert("제목을 입력해주세요.");const e={title:this.eventForm.title.trim(),description:this.eventForm.description,date:n(this.selectedDate),startTime:this.eventForm.startTime,endTime:this.eventForm.endTime,type:this.eventForm.type,color:this.eventForm.color,isAllDay:this.eventForm.isAllDay,location:this.eventForm.location};if(this.isEditing&&this.selectedEvent){const t={...this.selectedEvent,...e};this.emit("db-event-edit",{event:t})}else this.emit("db-event-add",{event:e});this.closeModal()}deleteEvent(){this.selectedEvent&&window.confirm("정말로 이 일정을 삭제하시겠습니까?")&&(this.emit("db-event-delete",{eventId:this.selectedEvent.id}),this.closeModal())}renderHeader(){if(!this.headerEl)return;this.headerEl.replaceChildren();const a=document.createElement("div");a.className=`${s}__navigation`;const n=t("m"),i=document.createElement("button");i.type="button",i.className=`${s}__nav-button`,i.setAttribute("aria-label","이전"),i.appendChild(e("chevron-left",n)),i.addEventListener("click",()=>{this.shiftMonth(-1)});const d=document.createElement("div");d.className=`${s}__title`,d.textContent=this.selectedDate.toLocaleDateString(this.locale,{year:"numeric",month:"long"});const l=document.createElement("button");l.type="button",l.className=`${s}__nav-button`,l.setAttribute("aria-label","다음"),l.appendChild(e("chevron-right",n)),l.addEventListener("click",()=>{this.shiftMonth(1)}),a.append(i,d,l),this.headerEl.appendChild(a)}renderMonthView(){const e=document.createElement("div");e.className=`${s}__month-view`;const t=document.createElement("div");t.className=`${s}__weekdays`,["일","월","화","수","목","금","토"].forEach(e=>{const a=document.createElement("div");a.className=`${s}__weekday`,a.textContent=e,t.appendChild(a)}),e.appendChild(t);const a=document.createElement("div");a.className=`${s}__days`;const n=this.selectedDate.getFullYear(),i=this.selectedDate.getMonth(),d=new Date(n,i,1),l=new Date(d);l.setDate(l.getDate()-d.getDay());const r=new Date;for(let e=0;e<42;e+=1){const t=new Date(l);t.setDate(l.getDate()+e);const n=t.getMonth()===i;if(!this.showOutsideDays&&!n)continue;const d=0===t.getDay()||6===t.getDay();if(!this.showWeekends&&d)continue;const o=document.createElement("div"),c=this.selectedDateRange.start&&this.selectedDateRange.end&&t>=this.selectedDateRange.start&&t<=this.selectedDateRange.end,h=this.selectedDateRange.start&&t.toDateString()===this.selectedDateRange.start.toDateString(),m=this.selectedDateRange.end&&t.toDateString()===this.selectedDateRange.end.toDateString(),u=Boolean(c&&!h&&!m);o.className=[`${s}__day`,n&&`${s}__day--current-month`,this.highlightToday&&t.toDateString()===r.toDateString()&&`${s}__day--today`,this.isSameDate(t,this.selectedDate)&&`${s}__day--selected`,h&&`${s}__day--selected--start`,m&&`${s}__day--selected--end`,u&&`${s}__day--selected--middle`,!this.showWeekends&&d&&`${s}__day--weekend`].filter(Boolean).join(" "),o.addEventListener("click",()=>this.handleDateClick(t));const v=document.createElement("span");v.className=`${s}__day-number`,v.textContent=String(t.getDate()),o.appendChild(v);const p=this.eventsForDate(t);if(p.length){const e=document.createElement("div");if(e.className=`${s}__day-events`,p.slice(0,2).forEach(t=>{const a=document.createElement("div");a.className=[`${s}__event-bar`,`${s}__event-bar--${t.type}`].filter(Boolean).join(" "),t.color&&(a.style.backgroundColor=t.color),this.draggedEvent?.id===t.id&&a.classList.add(`${s}__event-bar--dragging`),a.title=t.title,a.draggable=!0;const n=document.createElement("span");n.className=`${s}__event-title`,n.textContent=t.title,a.appendChild(n),a.addEventListener("click",e=>this.handleEventClick(t,e)),a.addEventListener("dragstart",e=>this.handleDragStart(t,e)),a.addEventListener("dragend",()=>this.handleDragEnd()),e.appendChild(a)}),p.length>2){const t=document.createElement("div");t.className=`${s}__more-events`,t.textContent=`+${p.length-2} more`,e.appendChild(t)}o.appendChild(e)}const g=document.createElement("div");g.className=[`${s}__drop-zone`,this.dragOverDate&&this.isSameDate(this.dragOverDate,t)&&`${s}__drop-zone--active`].filter(Boolean).join(" "),g.addEventListener("dragover",e=>this.handleDragOver(t,e)),g.addEventListener("dragleave",e=>this.handleDragLeave(e)),g.addEventListener("drop",e=>this.handleDrop(t,e)),o.appendChild(g),a.appendChild(o)}return e.appendChild(a),e}renderYearView(){const e=document.createElement("div");e.className=`${s}__year-view`;const t=this.selectedDate.getFullYear();for(let n=0;n<12;n+=1){const i=new Date(t,n,1),d=this._events.filter(e=>{const s=a(e.date);return s&&s.getFullYear()===t&&s.getMonth()===n}),l=document.createElement("div");l.className=`${s}__year-month`,l.addEventListener("click",()=>{this.selectedDate=i,this.handleViewChange("month")});const r=document.createElement("h3");if(r.className=`${s}__year-month-title`,r.textContent=i.toLocaleDateString(this.locale,{month:"long"}),l.appendChild(r),d.length){const e=document.createElement("div");if(e.className=`${s}__year-month-events`,d.slice(0,4).forEach(t=>{const a=document.createElement("span");a.className=[`${s}__year-event`,`${s}__year-event--${t.type}`].join(" "),t.color&&(a.style.backgroundColor=t.color),e.appendChild(a)}),d.length>4){const t=document.createElement("span");t.className=`${s}__year-more-events`,t.textContent=`+${d.length-4} more`,e.appendChild(t)}l.appendChild(e)}e.appendChild(l)}return e}renderWeekView(){const e=document.createElement("div");e.className=`${s}__week-view`;const t=new Date,a=new Date(this.selectedDate);a.setDate(this.selectedDate.getDate()-this.selectedDate.getDay());const n=document.createElement("div");n.className=`${s}__week-header`;const i=document.createElement("div");i.className=`${s}__time-column-header`,n.appendChild(i);for(let e=0;e<7;e+=1){const i=new Date(a);i.setDate(a.getDate()+e);const d=document.createElement("div");d.className=[`${s}__week-day-header`,i.toDateString()===t.toDateString()&&`${s}__week-day-header--today`].filter(Boolean).join(" ");const l=document.createElement("span");l.className=`${s}__week-day-name`,l.textContent=i.toLocaleDateString(this.locale,{weekday:"short"});const r=document.createElement("span");r.className=`${s}__week-day-number`,r.textContent=String(i.getDate()),d.append(l,r),n.appendChild(d)}e.appendChild(n);const d=document.createElement("div");d.className=`${s}__week-grid`;const l=document.createElement("div");l.className=`${s}__week-time-column`;for(let e=6;e<=22;e+=1){const t=document.createElement("div");t.className=`${s}__time-slot`;const a=document.createElement("span");a.className=`${s}__time-label`,a.textContent=`${String(e).padStart(2,"0")}:00`,t.appendChild(a),l.appendChild(t)}d.appendChild(l);const r=document.createElement("div");r.className=`${s}__week-columns`;for(let e=0;e<7;e+=1){const t=new Date(a);t.setDate(a.getDate()+e);const n=document.createElement("div");n.className=`${s}__week-column`;for(let e=6;e<=22;e+=1){const a=document.createElement("div");a.className=`${s}__week-cell`,a.title=`${t.toLocaleDateString()} ${String(e).padStart(2,"0")}:00`,a.addEventListener("click",()=>{this.selectedDate=new Date(t),this.eventForm.startTime=`${String(e).padStart(2,"0")}:00`,this.eventForm.endTime=`${String(e+1).padStart(2,"0")}:00`,this.openAddModal(this.selectedDate)}),n.appendChild(a)}this.eventsForDate(t).forEach(e=>{if(!e.startTime)return;const[t,a]=e.startTime.split(":").map(Number),i=.8*(60*(t-6)+(a||0)),d=(e.endTime||e.startTime).split(":").map(Number),l=60*(d[0]||t)+(d[1]||0),r=60*t+(a||0),o=Math.max(20,48*(l-r)/60),c=document.createElement("div");c.className=[`${s}__week-event`,`${s}__week-event--${e.type}`].filter(Boolean).join(" "),c.textContent=e.title,c.title=e.title,c.style.backgroundColor=e.color||"#17a2b8",c.style.top=`${i}px`,c.style.height=`${o}px`,c.addEventListener("click",t=>this.handleEventClick(e,t)),n.appendChild(c)}),r.appendChild(n)}return d.appendChild(r),e.appendChild(d),e}renderModal(){if(!this.modalEl)return;if(this.modalEl.replaceChildren(),!this.showEventModal)return void this.modalEl.removeAttribute("open");this.modalEl.setAttribute("open","true"),this.modalEl.setAttribute("title",this.isEditing?"일정 편집":"새 일정 추가");const e=document.createElement("div");e.className=`${s}__event-form`;const t=document.createElement("db-input");t.setAttribute("label","제목 *"),t.setAttribute("placeholder","일정 제목을 입력하세요"),t.setAttribute("full-width",""),t.setAttribute("value",this.eventForm.title),t.addEventListener("db-input",e=>{this.eventForm.title=e.detail.value});const l=document.createElement("db-input");l.setAttribute("label","설명"),l.setAttribute("placeholder","일정 설명을 입력하세요"),l.setAttribute("full-width",""),l.setAttribute("value",this.eventForm.description),l.addEventListener("db-input",e=>{this.eventForm.description=e.detail.value});const r=document.createElement("db-date-picker");r.setAttribute("label","날짜"),r.setAttribute("full-width",""),r.setAttribute("value",n(this.selectedDate)),r.addEventListener("db-change",e=>{const t=a(e.detail.value);t&&(this.selectedDate=t)});const o=document.createElement("db-select");o.setAttribute("label","일정 타입"),o.setAttribute("full-width",""),o.setAttribute("options",JSON.stringify(i)),o.setAttribute("value",this.eventForm.type),o.addEventListener("db-change",e=>{this.eventForm.type=e.detail.value});const c=document.createElement("db-select");c.setAttribute("label","색상"),c.setAttribute("full-width",""),c.setAttribute("options",JSON.stringify(d)),c.setAttribute("value",this.eventForm.color),c.addEventListener("db-change",e=>{this.eventForm.color=e.detail.value});const h=document.createElement("db-time-picker");h.setAttribute("label","시작 시간"),h.setAttribute("full-width",""),h.setAttribute("value",this.eventForm.startTime),h.addEventListener("db-change",e=>{this.eventForm.startTime=e.detail.value});const m=document.createElement("db-time-picker");m.setAttribute("label","종료 시간"),m.setAttribute("full-width",""),m.setAttribute("value",this.eventForm.endTime),m.addEventListener("db-change",e=>{this.eventForm.endTime=e.detail.value}),e.append(t,l,r,o,c,h,m);const u=document.createElement("div");u.className="designbase-wc-modal__body",u.setAttribute("data-modal-part","body"),u.appendChild(e);const v=document.createElement("div");v.className="designbase-wc-modal__footer",v.setAttribute("data-modal-part","footer");const p=document.createElement("div");if(p.className=`${s}__modal-actions`,this.isEditing){const e=document.createElement("db-button");e.setAttribute("variant","destructive"),e.textContent="삭제",e.addEventListener("click",()=>this.deleteEvent()),p.appendChild(e)}const g=document.createElement("div");g.className=`${s}__modal-buttons`;const b=document.createElement("db-button");b.setAttribute("variant","secondary"),b.textContent="취소",b.addEventListener("click",()=>this.closeModal());const E=document.createElement("db-button");E.setAttribute("variant","primary"),E.textContent=this.isEditing?"수정":"저장",E.addEventListener("click",()=>this.saveEvent()),g.append(b,E),p.appendChild(g),v.appendChild(p),this.modalEl.append(u,v)}render(){this.className=s,this.replaceChildren(),this.headerEl&&this.bodyEl&&(this.renderHeader(),this.bodyEl.replaceChildren(),this.bodyEl.appendChild(this.renderMonthView()),this.append(this.headerEl,this.bodyEl),this.renderModal(),this.showEventModal&&this.modalEl&&this.appendChild(this.modalEl))}}customElements.get("db-calendar")||customElements.define("db-calendar",DbCalendar);export{DbCalendar};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{CARD_VARIANTS as e,CARD_SIZES as t}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbCard extends HTMLElement{constructor(){super(...arguments),this.selectCheckbox=null,this.imageNode=null,this.handleClick=e=>{if(this.disabled||this.loading)return e.preventDefault(),void e.stopPropagation();this.clickable&&this.dispatchEvent(new CustomEvent("db-click",{bubbles:!0,composed:!0}))},this.handleKeyDown=e=>{!this.clickable||"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.click())},this.handleSelect=e=>{if(e?.stopPropagation(),this.disabled||this.loading||!this.selectable)return;const t=!this.selected;this.toggleAttribute("selected",t),this.selectCheckbox&&(t?this.selectCheckbox.setAttribute("checked",""):this.selectCheckbox.removeAttribute("checked")),this.dispatchEvent(new CustomEvent("db-select",{bubbles:!0,composed:!0,detail:{selected:t}}))}}static get observedAttributes(){return["variant","size","prism","full-width","clickable","hoverable","selectable","selected","disabled","loading","image","image-alt"]}get variant(){return this.getAttribute("variant")||"default"}set variant(e){this.setAttribute("variant",e)}get size(){return this.getAttribute("size")||"m"}set size(e){this.setAttribute("size",e)}get clickable(){return this.hasAttribute("clickable")}set clickable(e){this.toggleAttribute("clickable",e)}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e)}get loading(){return this.hasAttribute("loading")}set loading(e){this.toggleAttribute("loading",e)}get fullWidth(){return this.hasAttribute("full-width")}set fullWidth(e){this.toggleAttribute("full-width",e)}get hoverable(){return this.hasAttribute("hoverable")}set hoverable(e){this.toggleAttribute("hoverable",e)}get selectable(){return this.hasAttribute("selectable")}set selectable(e){this.toggleAttribute("selectable",e)}get selected(){return this.hasAttribute("selected")}set selected(e){this.toggleAttribute("selected",e)}connectedCallback(){this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeyDown),this.sync()}disconnectedCallback(){this.removeEventListener("click",this.handleClick),this.removeEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(e){this.isConnected&&(this.sync(),"selected"===e&&this.selectCheckbox&&(this.selected?this.selectCheckbox.setAttribute("checked",""):this.selectCheckbox.removeAttribute("checked")))}hasMediaSection(){return!!this.getAttribute("image")||null!==this.querySelector(':scope > .designbase-wc-card__thumbnail, :scope > .designbase-wc-card__media, :scope > [slot="media"], :scope > [slot="thumbnail"]')}hasFooterSection(){return null!==this.querySelector(':scope > .designbase-wc-card__footer, :scope > [slot="footer"]')}syncImageMedia(){const e=this.getAttribute("image"),t=this.querySelector(':scope > .designbase-wc-card__thumbnail, :scope > .designbase-wc-card__media, :scope > [slot="media"], :scope > [slot="thumbnail"]');if(!e)return void(this.imageNode&&(this.imageNode.remove(),this.imageNode=null));if(t&&t!==this.imageNode)return void(this.imageNode&&(this.imageNode.remove(),this.imageNode=null));if(!this.imageNode){this.imageNode=document.createElement("div"),this.imageNode.className="designbase-wc-card__media designbase-wc-card__thumbnail",this.imageNode.setAttribute("slot","media");const e=document.createElement("img");e.className="designbase-wc-card__thumbnail-image",this.imageNode.append(e);const t=this.querySelector(':scope > .designbase-wc-card__body, :scope > [slot="body"], :scope > .designbase-wc-card__footer, :scope > [slot="footer"]');t?this.insertBefore(this.imageNode,t):this.insertBefore(this.imageNode,this.firstChild)}const s=this.imageNode.querySelector("img");s&&(s.src=e,s.alt=this.getAttribute("image-alt")||"")}sync(){this.syncImageMedia(),this.syncAttributes(),this.syncOverlays()}syncOverlays(){const e=this.querySelector(":scope > .designbase-wc-card__loading-overlay"),t=this.querySelector(":scope > .designbase-wc-card__select-overlay");if(this.loading){if(!e){const e=document.createElement("div");e.className="designbase-wc-card__loading-overlay",e.setAttribute("aria-live","polite"),e.setAttribute("aria-busy","true");const t=document.createElement("div");t.className="designbase-wc-card__loading-spinner",e.append(t),this.append(e)}}else e?.remove();if(this.selectable)if(t)this.selectCheckbox&&(this.selected?this.selectCheckbox.setAttribute("checked",""):this.selectCheckbox.removeAttribute("checked"));else{const e=document.createElement("div");e.className="designbase-wc-card__select-overlay",e.addEventListener("click",e=>this.handleSelect(e));const t=document.createElement("db-checkbox");t.className="designbase-wc-card__select-checkbox",t.setAttribute("size","s"),t.setAttribute("has-label","false"),t.setAttribute("aria-label","카드 선택"),this.selected&&t.setAttribute("checked",""),t.addEventListener("click",e=>e.stopPropagation()),t.addEventListener("db-change",e=>{e.stopPropagation(),this.handleSelect()}),e.append(t),this.append(e),this.selectCheckbox=t}else t?.remove(),this.selectCheckbox=null}syncAttributes(){this.classList.add("designbase-wc-card"),this.setAttribute("aria-disabled",String(this.disabled||this.loading)),!this.clickable||this.disabled||this.loading?(this.removeAttribute("role"),this.removeAttribute("tabindex"),this.removeAttribute("aria-pressed")):(this.setAttribute("role","button"),this.hasAttribute("tabindex")||this.setAttribute("tabindex","0"),this.setAttribute("aria-pressed",String(this.hasAttribute("selected")))),e.forEach(e=>this.classList.remove(`designbase-wc-card--${e}`)),t.forEach(e=>this.classList.remove(`designbase-wc-card--${e}`)),this.classList.add(`designbase-wc-card--${e.includes(this.variant)?this.variant:"default"}`),this.classList.add(`designbase-wc-card--${t.includes(this.size)?this.size:"m"}`),this.classList.toggle("designbase-wc-card--prism",this.hasAttribute("prism")),this.classList.toggle("designbase-wc-card--full-width",this.hasAttribute("full-width")),this.classList.toggle("designbase-wc-card--clickable",this.clickable),this.classList.toggle("designbase-wc-card--hoverable",this.hasAttribute("hoverable")),this.classList.toggle("designbase-wc-card--selectable",this.hasAttribute("selectable")),this.classList.toggle("designbase-wc-card--selected",this.hasAttribute("selected")),this.classList.toggle("designbase-wc-card--disabled",this.disabled),this.classList.toggle("designbase-wc-card--loading",this.loading),this.classList.toggle("designbase-wc-card--with-media",this.hasMediaSection()),this.classList.toggle("designbase-wc-card--with-thumbnail",this.hasMediaSection()),this.classList.toggle("designbase-wc-card--with-footer",this.hasFooterSection())}}customElements.get("db-card")||customElements.define("db-card",DbCard);export{DbCard};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as t}from"./db-icons.js";class DbCarousel extends HTMLElement{constructor(){super(...arguments),this.currentIndex=0,this.timer=null,this.isAutoPlaying=!1}static get observedAttributes(){return["items","size","variant","theme","transition","auto-play","auto-play-interval","infinite","show-navigation","show-indicators","indicator-style","show-auto-play-control","show-title","show-description","disabled","readonly"]}get items(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}connectedCallback(){this.style.display="block",this.clampCurrentIndex(),this.isAutoPlaying=this.getBool("auto-play"),this.startAutoPlay(),this.render()}disconnectedCallback(){this.stopAutoPlay()}attributeChangedCallback(t){"items"===t&&this.clampCurrentIndex(),"auto-play"!==t&&"auto-play-interval"!==t||(this.isAutoPlaying=this.getBool("auto-play"),this.startAutoPlay()),this.render()}getBool(t,e=!1){if(!this.hasAttribute(t))return e;const s=this.getAttribute(t);return""===s||"true"===s}clampCurrentIndex(){this.currentIndex>=this.items.length&&(this.currentIndex=0)}stopAutoPlay(){this.timer&&(window.clearInterval(this.timer),this.timer=null)}startAutoPlay(){if(this.stopAutoPlay(),!this.isAutoPlaying||this.items.length<=1)return;const t=Math.max(1e3,Number(this.getAttribute("auto-play-interval")||5e3));this.timer=window.setInterval(()=>this.goToNext(),t)}getIndicatorType(){if(this.getBool("show-auto-play-control",!0)&&this.getBool("show-indicators",!0)&&this.items.length>1)return"combined";const t=this.getAttribute("indicator-style")||"dots";return"lines"===t?"line":"numbers"===t?"numbers":"dots"}getIndicatorSize(){const t=this.getAttribute("size")||"m";return"l"===t||"xl"===t?"m":"s"}goTo(t){t<0||t>=this.items.length||(this.currentIndex=t,this.dispatchEvent(new CustomEvent("db-slide-change",{detail:{index:t},bubbles:!0,composed:!0})),this.render())}goToPrev(){if(0===this.items.length)return;const t=this.getBool("infinite",!0),e=this.currentIndex-1;e<0?this.goTo(t?this.items.length-1:0):this.goTo(e)}goToNext(){if(0===this.items.length)return;const t=this.getBool("infinite",!0),e=this.currentIndex+1;e>=this.items.length?this.goTo(t?0:this.items.length-1):this.goTo(e)}render(){const
|
|
1
|
+
import{createDbIcon as t}from"./db-icons.js";import{t as e}from"../core/i18n.js";class DbCarousel extends HTMLElement{constructor(){super(...arguments),this.currentIndex=0,this.timer=null,this.isAutoPlaying=!1}static get observedAttributes(){return["items","size","variant","theme","transition","auto-play","auto-play-interval","infinite","show-navigation","show-indicators","indicator-style","show-auto-play-control","show-title","show-description","disabled","readonly"]}get items(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t:[]}catch{return[]}}set items(t){this.setAttribute("items","string"==typeof t?t:JSON.stringify(t))}connectedCallback(){this.style.display="block",this.clampCurrentIndex(),this.isAutoPlaying=this.getBool("auto-play"),this.startAutoPlay(),this.render()}disconnectedCallback(){this.stopAutoPlay()}attributeChangedCallback(t){"items"===t&&this.clampCurrentIndex(),"auto-play"!==t&&"auto-play-interval"!==t||(this.isAutoPlaying=this.getBool("auto-play"),this.startAutoPlay()),this.render()}getBool(t,e=!1){if(!this.hasAttribute(t))return e;const s=this.getAttribute(t);return""===s||"true"===s}clampCurrentIndex(){this.currentIndex>=this.items.length&&(this.currentIndex=0)}stopAutoPlay(){this.timer&&(window.clearInterval(this.timer),this.timer=null)}startAutoPlay(){if(this.stopAutoPlay(),!this.isAutoPlaying||this.items.length<=1)return;const t=Math.max(1e3,Number(this.getAttribute("auto-play-interval")||5e3));this.timer=window.setInterval(()=>this.goToNext(),t)}getIndicatorType(){if(this.getBool("show-auto-play-control",!0)&&this.getBool("show-indicators",!0)&&this.items.length>1)return"combined";const t=this.getAttribute("indicator-style")||"dots";return"lines"===t?"line":"numbers"===t?"numbers":"dots"}getIndicatorSize(){const t=this.getAttribute("size")||"m";return"l"===t||"xl"===t?"m":"s"}goTo(t){t<0||t>=this.items.length||(this.currentIndex=t,this.dispatchEvent(new CustomEvent("db-slide-change",{detail:{index:t},bubbles:!0,composed:!0})),this.render())}goToPrev(){if(0===this.items.length)return;const t=this.getBool("infinite",!0),e=this.currentIndex-1;e<0?this.goTo(t?this.items.length-1:0):this.goTo(e)}goToNext(){if(0===this.items.length)return;const t=this.getBool("infinite",!0),e=this.currentIndex+1;e>=this.items.length?this.goTo(t?0:this.items.length-1):this.goTo(e)}render(){const s=this.getAttribute("size")||"m",i=this.getAttribute("variant")||"default",n=this.getAttribute("theme")||"light",a=this.getAttribute("transition")||"slide",o=this.getBool("show-navigation",!0),r=this.getBool("show-indicators",!0),l=this.getBool("show-auto-play-control",!0),c=this.getBool("show-title",!0),d=this.getBool("show-description",!0),u=this.getBool("disabled"),h=this.getBool("readonly"),g=this.getAttribute("indicator-style")||"dots",m=l&&r&&this.items.length>1;this.className=["designbase-wc-carousel",`designbase-wc-carousel--size-${s}`,`designbase-wc-carousel--variant-${i}`,`designbase-wc-carousel--theme-${n}`,`designbase-wc-carousel--transition-${a}`,`designbase-wc-carousel--indicator-${g}`,u&&"designbase-wc-carousel--disabled",h&&"designbase-wc-carousel--readonly"].filter(Boolean).join(" ");const b=document.createElement("div");b.className="designbase-wc-carousel__container";const p=document.createElement("div");if(p.className="designbase-wc-carousel__track",p.style.transform=`translateX(-${100*this.currentIndex}%)`,this.items.forEach((t,e)=>{const s=document.createElement("div");s.className="designbase-wc-carousel__slide"+(e===this.currentIndex?" designbase-wc-carousel__slide--active":""),s.style.flex="0 0 100%",s.style.width="100%",s.style.height="100%",s.style.minWidth="0";const i=t.image?"#ffffff":"";if(i&&(s.style.color=i),t.image){const i=document.createElement("div");i.className="designbase-wc-carousel__slide-image";const n=document.createElement("img");n.className="designbase-wc-carousel__slide-img",n.src=t.image,n.alt=t.alt||t.title||`Slide ${e+1}`,i.append(n),s.append(i)}if(c&&t.title||d&&t.description){const e=document.createElement("div");if(e.className="designbase-wc-carousel__slide-info",i&&(e.style.color=i),c&&t.title){const s=document.createElement("h3");s.className="designbase-wc-carousel__slide-title",s.textContent=t.title,i&&(s.style.color=i),e.append(s)}if(d&&t.description){const s=document.createElement("p");s.className="designbase-wc-carousel__slide-description",s.textContent=t.description,i&&(s.style.color=i),e.append(s)}s.append(e)}s.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-item-click",{detail:{item:t,index:e},bubbles:!0,composed:!0}))}),p.append(s)}),b.append(p),o&&this.items.length>1){const s=document.createElement("button");s.className="designbase-wc-carousel__nav-button designbase-wc-carousel__nav-button--prev",s.type="button",s.setAttribute("aria-label",e("carousel.previous")),s.append(t("chevron-left",20)),s.disabled=u||h,s.addEventListener("click",()=>this.goToPrev());const i=document.createElement("button");i.className="designbase-wc-carousel__nav-button designbase-wc-carousel__nav-button--next",i.type="button",i.setAttribute("aria-label",e("carousel.next")),i.append(t("chevron-right",20)),i.disabled=u||h,i.addEventListener("click",()=>this.goToNext()),b.append(s,i)}const y=[b];if(r&&this.items.length>1){const t=document.createElement("div");t.className="designbase-wc-carousel__controls";const e=document.createElement("div");e.className="designbase-wc-carousel__indicators";const s=document.createElement("db-indicator");s.setAttribute("current",String(this.currentIndex)),s.setAttribute("total",String(this.items.length)),s.setAttribute("type",this.getIndicatorType()),s.setAttribute("size",this.getIndicatorSize()),s.setAttribute("clickable",""),m&&(s.setAttribute("timer",""),s.setAttribute("timer-duration",String(Math.max(1e3,Number(this.getAttribute("auto-play-interval")||5e3)))),s.setAttribute("auto-roll","false"),this.isAutoPlaying?s.setAttribute("playing",""):s.removeAttribute("playing"),(u||h)&&s.setAttribute("playback-disabled","")),s.addEventListener("db-step-click",t=>{const e=t;this.goTo(e.detail.index)}),s.addEventListener("db-playing-change",t=>{const e=t;this.isAutoPlaying=e.detail.playing,this.startAutoPlay(),this.render()}),e.append(s),t.append(e),y.push(t)}this.replaceChildren(...y)}}customElements.get("db-carousel")||customElements.define("db-carousel",DbCarousel);export{DbCarousel};
|
|
@@ -73,6 +73,8 @@ declare class DbChatComposer extends HTMLElement {
|
|
|
73
73
|
private fileInput;
|
|
74
74
|
private micBtn;
|
|
75
75
|
private sendBtn;
|
|
76
|
+
private dropOverlay;
|
|
77
|
+
private dragDepth;
|
|
76
78
|
get value(): string;
|
|
77
79
|
set value(v: string);
|
|
78
80
|
get streaming(): boolean;
|
|
@@ -105,12 +107,24 @@ declare class DbChatComposer extends HTMLElement {
|
|
|
105
107
|
private handleOutsideClick;
|
|
106
108
|
private chooseAttachOption;
|
|
107
109
|
private handleFilePicked;
|
|
110
|
+
private hasDragFiles;
|
|
111
|
+
private handleDragEnter;
|
|
112
|
+
private handleDragOver;
|
|
113
|
+
private handleDragLeave;
|
|
114
|
+
private handleDrop;
|
|
115
|
+
private showDropOverlay;
|
|
108
116
|
private addFile;
|
|
117
|
+
/** 동일 파일을 두 번 끌어놓거나 다시 선택해도 첨부 목록에는 한 번만 표시한다. */
|
|
118
|
+
private hasAttachment;
|
|
109
119
|
private attachmentMeta;
|
|
110
120
|
private handleInput;
|
|
111
121
|
private handleKeyDown;
|
|
112
122
|
private handleSendClick;
|
|
113
123
|
private submit;
|
|
124
|
+
/** 여러 파일을 첨부합니다. */
|
|
125
|
+
addFiles(files: File[], type?: string): void;
|
|
126
|
+
/** 현재 입력·첨부를 전송합니다. */
|
|
127
|
+
send(): void;
|
|
114
128
|
/** 입력 필드를 비웁니다. */
|
|
115
129
|
clear(): void;
|
|
116
130
|
/** 첨부를 하나 제거합니다. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isDbIconName as t,createDbIcon as e}from"./db-icons.js";import"./db-button.js";import"./db-chip.js";const s=[{id:"image",label:"사진·이미지",icon:"gallery",accept:"image/*",multiple:!0},{id:"video",label:"동영상",icon:"video",accept:"video/*",multiple:!0},{id:"file",label:"문서·파일",icon:"file-new",accept:"",multiple:!0},{id:"camera",label:"카메라 촬영",icon:"camera",accept:"image/*",capture:"environment"}];function kindFromMime(t){return t.startsWith("image/")?"image":t.startsWith("video/")?"video":"file"}const i={image:"gallery",video:"video",file:"file-new"};let a=0;class DbChatComposer extends HTMLElement{constructor(){super(...arguments),this.built=!1,this._tools=[],this._attachOptions=s,this._attachments=[],this.attachMenuOpen=!1,this.handleAttachClick=()=>{this.disabled||(this.attachMenuOpen?this.closeAttachMenu():this.openAttachMenu())},this.handleOutsideClick=t=>{this.attachMenuOpen&&(this.attachWrap.contains(t.target)||this.closeAttachMenu())},this.handleFilePicked=()=>{const t=Array.from(this.fileInput.files||[]);if(!t.length)return;const e=this.fileInput.dataset.type||"file";t.forEach(t=>this.addFile(t)),this.dispatchEvent(new CustomEvent("db-attach-files",{detail:{type:e,files:t},bubbles:!0,composed:!0}))},this.handleInput=()=>{this.autoGrow(),this.syncSendState(),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:this.field.value},bubbles:!0,composed:!0}))},this.handleKeyDown=t=>{if("Escape"===t.key&&this.attachMenuOpen)return t.preventDefault(),void this.closeAttachMenu();"Enter"!==t.key||t.shiftKey||t.isComposing||(t.preventDefault(),this.submit())},this.handleSendClick=()=>{this.disabled||(this.streaming?this.dispatchEvent(new CustomEvent("db-stop",{bubbles:!0,composed:!0})):this.submit())}}static get observedAttributes(){return["placeholder","value","disabled","streaming","voice","attach","max-length","send-label"]}get value(){return this.field?.value??this.getAttribute("value")??""}set value(t){this.field&&(this.field.value=t,this.autoGrow(),this.syncSendState()),t?this.setAttribute("value",t):this.removeAttribute("value")}get streaming(){return this.hasAttribute("streaming")}set streaming(t){this.toggleAttribute("streaming",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get tools(){return this._tools}set tools(t){this._tools=Array.isArray(t)?t:[],this.built&&this.renderTools()}get attachOptions(){return this._attachOptions}set attachOptions(t){this._attachOptions=Array.isArray(t)&&t.length?t:s,this.built&&this.renderAttachMenu()}get attachments(){return this._attachments.map(t=>({...t}))}connectedCallback(){this.built||this.build(),this.sync(),requestAnimationFrame(()=>this.autoGrow()),document.addEventListener("click",this.handleOutsideClick,!0)}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick,!0),this._attachments.forEach(t=>t.preview&&URL.revokeObjectURL(t.preview))}attributeChangedCallback(t){if(this.built){if("value"===t){const t=this.getAttribute("value")||"";return this.field.value!==t&&(this.field.value=t,this.autoGrow()),void this.syncSendState()}"streaming"!==t?this.sync():this.renderSendButton()}}build(){this.built=!0,this.className="designbase-wc-chat-composer",this.replaceChildren();const t=document.createElement("div");t.className="designbase-wc-chat-composer__surface",this.attachmentsEl=document.createElement("div"),this.attachmentsEl.className="designbase-wc-chat-composer__attachments",this.attachmentsEl.hidden=!0;const e=document.createElement("div");e.className="designbase-wc-chat-composer__field-row",this.field=document.createElement("textarea"),this.field.className="designbase-wc-chat-composer__field",this.field.rows=1,this.field.addEventListener("input",this.handleInput),this.field.addEventListener("keydown",this.handleKeyDown),e.append(this.field);const s=document.createElement("div");s.className="designbase-wc-chat-composer__toolbar";const i=document.createElement("div");i.className="designbase-wc-chat-composer__leading",this.attachWrap=document.createElement("div"),this.attachWrap.className="designbase-wc-chat-composer__attach-wrap",this.attachBtn=document.createElement("db-button"),this.attachBtn.className="designbase-wc-chat-composer__attach",this.attachBtn.setAttribute("variant","ghost"),this.attachBtn.setAttribute("icon-only",""),this.attachBtn.setAttribute("radius","pill"),this.attachBtn.setAttribute("size","m"),this.attachBtn.setAttribute("start-icon","paperclip"),this.attachBtn.setAttribute("aria-label","첨부"),this.attachBtn.setAttribute("aria-haspopup","menu"),this.attachBtn.addEventListener("db-click",this.handleAttachClick),this.attachMenu=document.createElement("div"),this.attachMenu.className="designbase-wc-chat-composer__attach-menu",this.attachMenu.setAttribute("role","menu"),this.attachMenu.hidden=!0,this.attachWrap.append(this.attachBtn,this.attachMenu),this.fileInput=document.createElement("input"),this.fileInput.type="file",this.fileInput.className="designbase-wc-chat-composer__file-input",this.fileInput.hidden=!0,this.fileInput.addEventListener("change",this.handleFilePicked),this.toolsEl=document.createElement("div"),this.toolsEl.className="designbase-wc-chat-composer__tools",i.append(this.attachWrap,this.toolsEl);const a=document.createElement("div");a.className="designbase-wc-chat-composer__trailing",this.micBtn=this.makeIconButton("microphone","음성 입력","db-voice"),this.micBtn.classList.add("designbase-wc-chat-composer__mic"),this.sendBtn=document.createElement("db-button"),this.sendBtn.className="designbase-wc-chat-composer__send",this.sendBtn.setAttribute("icon-only",""),this.sendBtn.setAttribute("radius","pill"),this.sendBtn.setAttribute("size","m"),this.sendBtn.addEventListener("db-click",this.handleSendClick),a.append(this.micBtn,this.sendBtn),s.append(i,a),t.append(this.attachmentsEl,e,s),this.append(t,this.fileInput),this.renderTools(),this.renderAttachMenu(),this.renderSendButton()}makeIconButton(t,e,s){const i=document.createElement("db-button");return i.setAttribute("variant","ghost"),i.setAttribute("icon-only",""),i.setAttribute("radius","pill"),i.setAttribute("size","m"),i.setAttribute("start-icon",t),i.setAttribute("aria-label",e),i.addEventListener("db-click",()=>{this.disabled||this.dispatchEvent(new CustomEvent(s,{bubbles:!0,composed:!0}))}),i}sync(){this.classList.toggle("designbase-wc-chat-composer--disabled",this.disabled),this.classList.toggle("designbase-wc-chat-composer--streaming",this.streaming),this.field.placeholder=this.getAttribute("placeholder")||"메시지를 입력하세요…",this.field.disabled=this.disabled;const t=this.getAttribute("max-length");t?this.field.maxLength=Number(t):this.field.removeAttribute("maxlength"),this.attachWrap.hidden=!this.hasAttribute("attach"),this.micBtn.hidden=!this.hasAttribute("voice"),this.hasAttribute("attach")||this.closeAttachMenu(),this.autoGrow(),this.syncSendState()}renderTools(){this.toolsEl.replaceChildren();for(const e of this._tools){const s=document.createElement("db-chip");s.setAttribute("label",e.label),s.setAttribute("size","s"),s.setAttribute("clickable",""),s.setAttribute("variant",e.active?"primary":"default"),e.icon&&t(e.icon)&&s.setAttribute("start-icon",e.icon),s.setAttribute("aria-pressed",String(!!e.active)),s.addEventListener("db-click",()=>{this.disabled||(e.active=!e.active,s.setAttribute("variant",e.active?"primary":"default"),s.setAttribute("aria-pressed",String(!!e.active)),this.dispatchEvent(new CustomEvent("db-tool-toggle",{detail:{id:e.id,active:!!e.active},bubbles:!0,composed:!0})))}),this.toolsEl.append(s)}}renderAttachMenu(){this.attachMenu.replaceChildren();for(const s of this._attachOptions){const i=document.createElement("button");i.type="button",i.className="designbase-wc-chat-composer__attach-item",i.setAttribute("role","menuitem");const a=document.createElement("span");a.className="designbase-wc-chat-composer__attach-item-icon",s.icon&&t(s.icon)&&a.append(e(s.icon,18));const n=document.createElement("span");n.className="designbase-wc-chat-composer__attach-item-text";const c=document.createElement("span");if(c.className="designbase-wc-chat-composer__attach-item-label",c.textContent=s.label,n.append(c),s.description){const t=document.createElement("span");t.className="designbase-wc-chat-composer__attach-item-desc",t.textContent=s.description,n.append(t)}i.append(a,n),i.addEventListener("click",()=>this.chooseAttachOption(s)),this.attachMenu.append(i)}}renderAttachments(){this.attachmentsEl.replaceChildren(),this.attachmentsEl.hidden=0===this._attachments.length;for(const t of this._attachments){const e=document.createElement("db-chip");e.setAttribute("label",t.name),e.setAttribute("size","s"),e.setAttribute("variant","neutral"),e.setAttribute("deletable",""),e.setAttribute("start-icon",i[t.kind]),e.addEventListener("db-delete",()=>this.removeAttachment(t.id)),this.attachmentsEl.append(e)}this.syncSendState()}renderSendButton(){const t=this.streaming;this.sendBtn.setAttribute("variant",t?"secondary":"primary"),this.sendBtn.setAttribute("start-icon",t?"stop":"send"),this.sendBtn.setAttribute("aria-label",t?"생성 중지":"전송"),this.syncSendState()}syncSendState(){if(!this.sendBtn)return;const t=0===this.value.trim().length&&0===this._attachments.length,e=this.disabled||!this.streaming&&t;this.sendBtn.toggleAttribute("disabled",e)}autoGrow(){this.field&&0!==this.field.clientWidth&&(this.field.style.height="auto",this.field.style.height=`${Math.min(this.field.scrollHeight,200)}px`)}openAttachMenu(){this.attachMenuOpen=!0,this.attachMenu.hidden=!1,this.attachBtn.setAttribute("aria-expanded","true"),this.classList.add("designbase-wc-chat-composer--attach-open"),requestAnimationFrame(()=>this.attachMenu.classList.add("designbase-wc-chat-composer__attach-menu--visible"))}closeAttachMenu(){this.attachMenuOpen&&(this.attachMenuOpen=!1,this.attachMenu.hidden=!0,this.attachMenu.classList.remove("designbase-wc-chat-composer__attach-menu--visible"),this.attachBtn.setAttribute("aria-expanded","false"),this.classList.remove("designbase-wc-chat-composer--attach-open"))}chooseAttachOption(t){this.closeAttachMenu(),this.dispatchEvent(new CustomEvent("db-attach",{detail:{type:t.id},bubbles:!0,composed:!0})),void 0!==t.accept&&(this.fileInput.value="",this.fileInput.accept=t.accept,this.fileInput.multiple=!!t.multiple,t.capture?this.fileInput.setAttribute("capture",t.capture):this.fileInput.removeAttribute("capture"),this.fileInput.dataset.type=t.id,this.fileInput.click())}addFile(t){const e=kindFromMime(t.type),s={id:`att-${a+=1}`,name:t.name,size:t.size,mime:t.type,kind:e,file:t,preview:"image"===e?URL.createObjectURL(t):void 0};this._attachments.push(s),this.renderAttachments(),this.dispatchEvent(new CustomEvent("db-attachment-add",{detail:{attachment:this.attachmentMeta(s)},bubbles:!0,composed:!0}))}attachmentMeta(t){return{id:t.id,name:t.name,size:t.size,mime:t.mime,kind:t.kind,file:t.file}}submit(){const t=this.field.value.trim();if(!t&&0===this._attachments.length||this.disabled||this.streaming)return;const e=new CustomEvent("db-send",{detail:{value:t,attachments:this._attachments.map(t=>this.attachmentMeta(t))},bubbles:!0,composed:!0,cancelable:!0});this.dispatchEvent(e)&&(this.clear(),this.clearAttachments())}clear(){this.value=""}removeAttachment(t){const e=this._attachments.find(e=>e.id===t);e&&(e.preview&&URL.revokeObjectURL(e.preview),this._attachments=this._attachments.filter(e=>e.id!==t),this.renderAttachments(),this.dispatchEvent(new CustomEvent("db-attachment-remove",{detail:{id:t},bubbles:!0,composed:!0})))}clearAttachments(){this._attachments.forEach(t=>t.preview&&URL.revokeObjectURL(t.preview)),this._attachments=[],this.renderAttachments()}addAttachment(t){if(t instanceof File)return void this.addFile(t);const e=kindFromMime(t.mime);this._attachments.push({id:`att-${a+=1}`,kind:e,...t}),this.renderAttachments()}focusInput(){this.field?.focus()}setStreaming(t){this.streaming=t}}customElements.get("db-chat-composer")||customElements.define("db-chat-composer",DbChatComposer);export{DbChatComposer};
|
|
1
|
+
import{isDbIconName as t,createDbIcon as e}from"./db-icons.js";import"./db-button.js";import"./db-chip.js";const s=[{id:"image",label:"사진·이미지",icon:"gallery",accept:"image/*",multiple:!0},{id:"video",label:"동영상",icon:"video",accept:"video/*",multiple:!0},{id:"file",label:"문서·파일",icon:"file-new",accept:"",multiple:!0},{id:"camera",label:"카메라 촬영",icon:"camera",accept:"image/*",capture:"environment"}];function kindFromMime(t){return t.startsWith("image/")?"image":t.startsWith("video/")?"video":"file"}const i={image:"gallery",video:"video",file:"file-new"};let a=0;class DbChatComposer extends HTMLElement{constructor(){super(...arguments),this.built=!1,this._tools=[],this._attachOptions=s,this._attachments=[],this.attachMenuOpen=!1,this.dragDepth=0,this.handleAttachClick=()=>{this.disabled||(this.attachMenuOpen?this.closeAttachMenu():this.openAttachMenu())},this.handleOutsideClick=t=>{this.attachMenuOpen&&(this.attachWrap.contains(t.target)||this.closeAttachMenu())},this.handleFilePicked=()=>{const t=Array.from(this.fileInput.files||[]);if(!t.length)return;const e=this.fileInput.dataset.type||"file";this.addFiles(t,e)},this.handleDragEnter=t=>{this.hasAttribute("attach")&&!this.disabled&&this.hasDragFiles(t)&&(t.preventDefault(),this.dragDepth+=1,this.showDropOverlay(!0))},this.handleDragOver=t=>{this.hasAttribute("attach")&&!this.disabled&&this.hasDragFiles(t)&&(t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="copy"))},this.handleDragLeave=t=>{this.hasAttribute("attach")&&this.hasDragFiles(t)&&(this.dragDepth=Math.max(0,this.dragDepth-1),0===this.dragDepth&&this.showDropOverlay(!1))},this.handleDrop=t=>{if(!this.hasAttribute("attach")||this.disabled)return;if(!this.hasDragFiles(t))return;t.preventDefault(),t.stopPropagation(),this.dragDepth=0,this.showDropOverlay(!1);const e=Array.from(t.dataTransfer?.files||[]);e.length&&(this.addFiles(e,"drop"),this.focusInput())},this.handleInput=()=>{this.autoGrow(),this.syncSendState(),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:this.field.value},bubbles:!0,composed:!0}))},this.handleKeyDown=t=>{if("Escape"===t.key&&this.attachMenuOpen)return t.preventDefault(),void this.closeAttachMenu();"Enter"!==t.key||t.shiftKey||t.isComposing||(t.preventDefault(),this.submit())},this.handleSendClick=()=>{this.disabled||(this.streaming?this.dispatchEvent(new CustomEvent("db-stop",{bubbles:!0,composed:!0})):this.submit())}}static get observedAttributes(){return["placeholder","value","disabled","streaming","voice","attach","max-length","send-label"]}get value(){return this.field?.value??this.getAttribute("value")??""}set value(t){this.field&&(this.field.value=t,this.autoGrow(),this.syncSendState()),t?this.setAttribute("value",t):this.removeAttribute("value")}get streaming(){return this.hasAttribute("streaming")}set streaming(t){this.toggleAttribute("streaming",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get tools(){return this._tools}set tools(t){this._tools=Array.isArray(t)?t:[],this.built&&this.renderTools()}get attachOptions(){return this._attachOptions}set attachOptions(t){this._attachOptions=Array.isArray(t)&&t.length?t:s,this.built&&this.renderAttachMenu()}get attachments(){return this._attachments.map(t=>({...t}))}connectedCallback(){this.built||this.build(),this.sync(),requestAnimationFrame(()=>this.autoGrow()),document.addEventListener("click",this.handleOutsideClick,!0),this.addEventListener("dragenter",this.handleDragEnter),this.addEventListener("dragover",this.handleDragOver),this.addEventListener("dragleave",this.handleDragLeave),this.addEventListener("drop",this.handleDrop)}disconnectedCallback(){document.removeEventListener("click",this.handleOutsideClick,!0),this.removeEventListener("dragenter",this.handleDragEnter),this.removeEventListener("dragover",this.handleDragOver),this.removeEventListener("dragleave",this.handleDragLeave),this.removeEventListener("drop",this.handleDrop),this._attachments.forEach(t=>t.preview&&URL.revokeObjectURL(t.preview))}attributeChangedCallback(t){if(this.built){if("value"===t){const t=this.getAttribute("value")||"";return this.field.value!==t&&(this.field.value=t,this.autoGrow()),void this.syncSendState()}"streaming"!==t?this.sync():this.renderSendButton()}}build(){this.built=!0,this.className="designbase-wc-chat-composer",this.replaceChildren();const t=document.createElement("div");t.className="designbase-wc-chat-composer__surface",this.attachmentsEl=document.createElement("div"),this.attachmentsEl.className="designbase-wc-chat-composer__attachments",this.attachmentsEl.hidden=!0;const e=document.createElement("div");e.className="designbase-wc-chat-composer__field-row",this.field=document.createElement("textarea"),this.field.className="designbase-wc-chat-composer__field",this.field.rows=1,this.field.addEventListener("input",this.handleInput),this.field.addEventListener("keydown",this.handleKeyDown),e.append(this.field);const s=document.createElement("div");s.className="designbase-wc-chat-composer__toolbar";const i=document.createElement("div");i.className="designbase-wc-chat-composer__leading",this.attachWrap=document.createElement("div"),this.attachWrap.className="designbase-wc-chat-composer__attach-wrap",this.attachBtn=document.createElement("db-button"),this.attachBtn.className="designbase-wc-chat-composer__attach",this.attachBtn.setAttribute("variant","ghost"),this.attachBtn.setAttribute("icon-only",""),this.attachBtn.setAttribute("radius","pill"),this.attachBtn.setAttribute("size","m"),this.attachBtn.setAttribute("start-icon","paperclip"),this.attachBtn.setAttribute("aria-label","첨부"),this.attachBtn.setAttribute("aria-haspopup","menu"),this.attachBtn.addEventListener("db-click",this.handleAttachClick),this.attachMenu=document.createElement("div"),this.attachMenu.className="designbase-wc-chat-composer__attach-menu",this.attachMenu.setAttribute("role","menu"),this.attachMenu.hidden=!0,this.attachWrap.append(this.attachBtn,this.attachMenu),this.fileInput=document.createElement("input"),this.fileInput.type="file",this.fileInput.className="designbase-wc-chat-composer__file-input",this.fileInput.hidden=!0,this.fileInput.addEventListener("change",this.handleFilePicked),this.toolsEl=document.createElement("div"),this.toolsEl.className="designbase-wc-chat-composer__tools",i.append(this.attachWrap,this.toolsEl);const a=document.createElement("div");a.className="designbase-wc-chat-composer__trailing",this.micBtn=this.makeIconButton("microphone","음성 입력","db-voice"),this.micBtn.classList.add("designbase-wc-chat-composer__mic"),this.sendBtn=document.createElement("db-button"),this.sendBtn.className="designbase-wc-chat-composer__send",this.sendBtn.setAttribute("icon-only",""),this.sendBtn.setAttribute("radius","pill"),this.sendBtn.setAttribute("size","m"),this.sendBtn.addEventListener("db-click",this.handleSendClick),a.append(this.micBtn,this.sendBtn),s.append(i,a),t.append(this.attachmentsEl,e,s),this.dropOverlay=document.createElement("div"),this.dropOverlay.className="designbase-wc-chat-composer__drop-overlay",this.dropOverlay.hidden=!0,this.dropOverlay.setAttribute("aria-hidden","true"),this.dropOverlay.innerHTML='<span class="designbase-wc-chat-composer__drop-label">파일을 놓으면 첨부됩니다</span>',this.append(t,this.dropOverlay,this.fileInput),this.renderTools(),this.renderAttachMenu(),this.renderSendButton()}makeIconButton(t,e,s){const i=document.createElement("db-button");return i.setAttribute("variant","ghost"),i.setAttribute("icon-only",""),i.setAttribute("radius","pill"),i.setAttribute("size","m"),i.setAttribute("start-icon",t),i.setAttribute("aria-label",e),i.addEventListener("db-click",()=>{this.disabled||this.dispatchEvent(new CustomEvent(s,{bubbles:!0,composed:!0}))}),i}sync(){this.classList.toggle("designbase-wc-chat-composer--disabled",this.disabled),this.classList.toggle("designbase-wc-chat-composer--streaming",this.streaming),this.field.placeholder=this.getAttribute("placeholder")||"메시지를 입력하세요…",this.field.disabled=this.disabled;const t=this.getAttribute("max-length");t?this.field.maxLength=Number(t):this.field.removeAttribute("maxlength"),this.attachWrap.hidden=!this.hasAttribute("attach"),this.micBtn.hidden=!this.hasAttribute("voice"),this.hasAttribute("attach")||this.closeAttachMenu(),this.autoGrow(),this.syncSendState()}renderTools(){this.toolsEl.replaceChildren();for(const e of this._tools){const s=document.createElement("db-chip");s.setAttribute("label",e.label),s.setAttribute("size","s"),s.setAttribute("clickable",""),s.setAttribute("variant",e.active?"primary":"default"),e.icon&&t(e.icon)&&s.setAttribute("start-icon",e.icon),s.setAttribute("aria-pressed",String(!!e.active)),s.addEventListener("db-click",()=>{this.disabled||(e.active=!e.active,s.setAttribute("variant",e.active?"primary":"default"),s.setAttribute("aria-pressed",String(!!e.active)),this.dispatchEvent(new CustomEvent("db-tool-toggle",{detail:{id:e.id,active:!!e.active},bubbles:!0,composed:!0})))}),this.toolsEl.append(s)}}renderAttachMenu(){this.attachMenu.replaceChildren();for(const s of this._attachOptions){const i=document.createElement("button");i.type="button",i.className="designbase-wc-chat-composer__attach-item",i.setAttribute("role","menuitem");const a=document.createElement("span");a.className="designbase-wc-chat-composer__attach-item-icon",s.icon&&t(s.icon)&&a.append(e(s.icon,18));const n=document.createElement("span");n.className="designbase-wc-chat-composer__attach-item-text";const h=document.createElement("span");if(h.className="designbase-wc-chat-composer__attach-item-label",h.textContent=s.label,n.append(h),s.description){const t=document.createElement("span");t.className="designbase-wc-chat-composer__attach-item-desc",t.textContent=s.description,n.append(t)}i.append(a,n),i.addEventListener("click",()=>this.chooseAttachOption(s)),this.attachMenu.append(i)}}renderAttachments(){this.attachmentsEl.replaceChildren(),this.attachmentsEl.hidden=0===this._attachments.length;for(const t of this._attachments){if("image"===t.kind&&t.preview){const s=document.createElement("div");s.className="designbase-wc-chat-composer__thumb";const i=document.createElement("img");i.src=t.preview,i.alt=t.name;const a=document.createElement("button");a.type="button",a.className="designbase-wc-chat-composer__thumb-remove",a.setAttribute("aria-label",`${t.name} 제거`),a.append(e("close",12)),a.addEventListener("click",()=>this.removeAttachment(t.id)),s.append(i,a),this.attachmentsEl.append(s);continue}const s=document.createElement("db-chip");s.setAttribute("label",t.name),s.setAttribute("size","s"),s.setAttribute("variant","neutral"),s.setAttribute("deletable",""),s.setAttribute("start-icon",i[t.kind]),s.addEventListener("db-delete",()=>this.removeAttachment(t.id)),this.attachmentsEl.append(s)}this.syncSendState()}renderSendButton(){const t=this.streaming;this.sendBtn.setAttribute("variant",t?"secondary":"primary"),this.sendBtn.setAttribute("start-icon",t?"stop":"send"),this.sendBtn.setAttribute("aria-label",t?"생성 중지":"전송"),this.syncSendState()}syncSendState(){if(!this.sendBtn)return;const t=0===this.value.trim().length&&0===this._attachments.length,e=this.disabled||!this.streaming&&t;this.sendBtn.toggleAttribute("disabled",e)}autoGrow(){this.field&&0!==this.field.clientWidth&&(this.field.style.height="auto",this.field.style.height=`${Math.min(this.field.scrollHeight,200)}px`)}openAttachMenu(){this.attachMenuOpen=!0,this.attachMenu.hidden=!1,this.attachBtn.setAttribute("aria-expanded","true"),this.classList.add("designbase-wc-chat-composer--attach-open"),requestAnimationFrame(()=>this.attachMenu.classList.add("designbase-wc-chat-composer__attach-menu--visible"))}closeAttachMenu(){this.attachMenuOpen&&(this.attachMenuOpen=!1,this.attachMenu.hidden=!0,this.attachMenu.classList.remove("designbase-wc-chat-composer__attach-menu--visible"),this.attachBtn.setAttribute("aria-expanded","false"),this.classList.remove("designbase-wc-chat-composer--attach-open"))}chooseAttachOption(t){this.closeAttachMenu(),this.dispatchEvent(new CustomEvent("db-attach",{detail:{type:t.id},bubbles:!0,composed:!0})),void 0!==t.accept&&(this.fileInput.value="",this.fileInput.accept=t.accept,this.fileInput.multiple=!!t.multiple,t.capture?this.fileInput.setAttribute("capture",t.capture):this.fileInput.removeAttribute("capture"),this.fileInput.dataset.type=t.id,this.fileInput.click())}hasDragFiles(t){return Array.from(t.dataTransfer?.types||[]).includes("Files")}showDropOverlay(t){this.dropOverlay&&(this.dropOverlay.hidden=!t,this.classList.toggle("designbase-wc-chat-composer--drop-active",t))}addFile(t){if(this.hasAttachment(t))return!1;const e=kindFromMime(t.type),s={id:`att-${a+=1}`,name:t.name,size:t.size,mime:t.type,kind:e,file:t,preview:"image"===e?URL.createObjectURL(t):void 0};return this._attachments.push(s),this.renderAttachments(),this.dispatchEvent(new CustomEvent("db-attachment-add",{detail:{attachment:this.attachmentMeta(s)},bubbles:!0,composed:!0})),!0}hasAttachment(t){return this._attachments.some(e=>e.file&&e.file.name===t.name&&e.file.size===t.size&&e.file.type===t.type&&e.file.lastModified===t.lastModified)}attachmentMeta(t){return{id:t.id,name:t.name,size:t.size,mime:t.mime,kind:t.kind,file:t.file,preview:t.preview}}submit(){const t=this.field.value.trim();if(!t&&0===this._attachments.length||this.disabled||this.streaming)return;const e=new CustomEvent("db-send",{detail:{value:t,attachments:this._attachments.map(t=>this.attachmentMeta(t))},bubbles:!0,composed:!0,cancelable:!0});this.dispatchEvent(e)&&(this.clear(),this.clearAttachments())}addFiles(t,e="file"){const s=Array.from(t||[]).filter(Boolean);if(!s.length)return;const i=s.filter(t=>this.addFile(t));i.length&&this.dispatchEvent(new CustomEvent("db-attach-files",{detail:{type:e,files:i},bubbles:!0,composed:!0}))}send(){this.submit()}clear(){this.value=""}removeAttachment(t){const e=this._attachments.find(e=>e.id===t);e&&(e.preview&&URL.revokeObjectURL(e.preview),this._attachments=this._attachments.filter(e=>e.id!==t),this.renderAttachments(),this.dispatchEvent(new CustomEvent("db-attachment-remove",{detail:{id:t},bubbles:!0,composed:!0})))}clearAttachments(){this._attachments.forEach(t=>t.preview&&URL.revokeObjectURL(t.preview)),this._attachments=[],this.renderAttachments()}addAttachment(t){if(t instanceof File)return void this.addFile(t);if(t.file&&this.hasAttachment(t.file))return;const e=kindFromMime(t.mime);this._attachments.push({id:`att-${a+=1}`,kind:e,...t}),this.renderAttachments()}focusInput(){this.field?.focus()}setStreaming(t){this.streaming=t}}customElements.get("db-chat-composer")||customElements.define("db-chat-composer",DbChatComposer);export{DbChatComposer};
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import './db-avatar.js';
|
|
2
|
+
import { CHAT_MESSAGE_ROLES } from '@designbasekorea/ui-contracts';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
type Role = (typeof CHAT_MESSAGE_ROLES)[number];
|
|
5
|
+
interface DbChatMessageAttachment {
|
|
6
|
+
name: string;
|
|
7
|
+
kind?: 'image' | 'video' | 'file';
|
|
8
|
+
/** 미리보기/다운로드 URL (blob: 또는 https:) */
|
|
9
|
+
url?: string;
|
|
10
|
+
mime?: string;
|
|
11
|
+
}
|
|
5
12
|
/**
|
|
6
13
|
* 채팅 메시지 한 줄. 본문은 라이트 DOM 자식으로 전달하며 컴포넌트가 감쌉니다.
|
|
7
14
|
* 아바타는 `db-avatar` 를 재사용합니다.
|
|
@@ -15,17 +22,22 @@ declare class DbChatMessage extends HTMLElement {
|
|
|
15
22
|
static get observedAttributes(): string[];
|
|
16
23
|
private built;
|
|
17
24
|
private contentEl;
|
|
25
|
+
private mediaEl;
|
|
18
26
|
private avatarWrap;
|
|
19
27
|
private headerEl;
|
|
20
28
|
private nameEl;
|
|
21
29
|
private timeEl;
|
|
22
30
|
private actionsEl;
|
|
31
|
+
private _attachments;
|
|
23
32
|
get role(): Role;
|
|
24
33
|
set role(v: Role);
|
|
34
|
+
get attachments(): DbChatMessageAttachment[];
|
|
35
|
+
set attachments(list: DbChatMessageAttachment[]);
|
|
25
36
|
connectedCallback(): void;
|
|
26
37
|
attributeChangedCallback(name: string): void;
|
|
27
38
|
private build;
|
|
28
39
|
private sync;
|
|
40
|
+
private renderAttachments;
|
|
29
41
|
private renderAvatar;
|
|
30
42
|
private renderActions;
|
|
31
43
|
private handleAction;
|
|
@@ -37,3 +49,4 @@ declare global {
|
|
|
37
49
|
}
|
|
38
50
|
|
|
39
51
|
export { DbChatMessage };
|
|
52
|
+
export type { DbChatMessageAttachment };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createDbIcon as t,isDbIconName as e}from"./db-icons.js";import"./db-avatar.js";
|
|
1
|
+
import{createDbIcon as t,isDbIconName as e}from"./db-icons.js";import"./db-avatar.js";import{CHAT_MESSAGE_ROLES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const a={copy:"copy",regenerate:"refresh",like:"thumb-up",dislike:"thumb-down",edit:"edit"},i={copy:"복사",regenerate:"다시 생성",like:"좋아요",dislike:"싫어요",edit:"편집"};class DbChatMessage extends HTMLElement{constructor(){super(...arguments),this.built=!1,this._attachments=[]}static get observedAttributes(){return["role","name","avatar-src","avatar-initials","timestamp","status","actions","variant"]}get role(){return s.includes(this.getAttribute("role"))?this.getAttribute("role"):"assistant"}set role(t){this.setAttribute("role",t)}get attachments(){return this._attachments.map(t=>({...t}))}set attachments(t){this._attachments=Array.isArray(t)?t:[],this.built&&this.renderAttachments()}connectedCallback(){this.built||this.build(),this.sync()}attributeChangedCallback(t){this.built&&("actions"===t&&this.renderActions(),this.sync())}build(){for(this.built=!0,this.contentEl=document.createElement("div"),this.contentEl.className="designbase-wc-chat-message__content";this.firstChild;)this.contentEl.append(this.firstChild);this.mediaEl=document.createElement("div"),this.mediaEl.className="designbase-wc-chat-message__media",this.mediaEl.hidden=!0,this.avatarWrap=document.createElement("div"),this.avatarWrap.className="designbase-wc-chat-message__avatar";const t=document.createElement("div");t.className="designbase-wc-chat-message__bubble",this.headerEl=document.createElement("div"),this.headerEl.className="designbase-wc-chat-message__header",this.nameEl=document.createElement("span"),this.nameEl.className="designbase-wc-chat-message__name",this.timeEl=document.createElement("span"),this.timeEl.className="designbase-wc-chat-message__time",this.headerEl.append(this.nameEl,this.timeEl),this.actionsEl=document.createElement("div"),this.actionsEl.className="designbase-wc-chat-message__actions",t.append(this.headerEl,this.mediaEl,this.contentEl,this.actionsEl),this.append(this.avatarWrap,t),this.renderAvatar(),this.renderActions(),this.renderAttachments()}sync(){this.className=["designbase-wc-chat-message",`designbase-wc-chat-message--${this.role}`,`designbase-wc-chat-message--${this.getAttribute("variant")||"bubble"}`,this.getAttribute("status")&&`designbase-wc-chat-message--${this.getAttribute("status")}`].filter(Boolean).join(" ");const t=this.getAttribute("name")||"";this.nameEl.textContent=t,this.nameEl.hidden=!t;const e=this.getAttribute("timestamp")||"";this.timeEl.textContent=e,this.timeEl.hidden=!e,this.headerEl.hidden=!t&&!e;const s=Boolean(this.contentEl.textContent?.trim()||this.contentEl.children.length);this.contentEl.hidden=!s&&this._attachments.length>0,this.renderAvatar()}renderAttachments(){if(!this.mediaEl)return;this.mediaEl.replaceChildren(),this.mediaEl.hidden=0===this._attachments.length;for(const e of this._attachments){const s=e.kind||(e.mime?.startsWith("image/")?"image":e.mime?.startsWith("video/")?"video":"file");if("image"===s&&e.url){const t=document.createElement("a");t.className="designbase-wc-chat-message__image",t.href=e.url,t.target="_blank",t.rel="noopener noreferrer";const s=document.createElement("img");s.src=e.url,s.alt=e.name,s.loading="lazy",t.append(s),this.mediaEl.append(t);continue}const a=document.createElement(e.url?"a":"div");a.className="designbase-wc-chat-message__file",e.url&&a instanceof HTMLAnchorElement&&(a.href=e.url,a.target="_blank",a.rel="noopener noreferrer",a.download=e.name);const i=document.createElement("span");i.textContent=e.name,a.append(t("video"===s?"video":"file-new",16),i),this.mediaEl.append(a)}const e=Boolean(this.contentEl.textContent?.trim()||this.contentEl.children.length);this.contentEl.hidden=!e&&this._attachments.length>0}renderAvatar(){const t=this.getAttribute("avatar-src"),e=this.getAttribute("avatar-initials"),s="assistant"===this.role||Boolean(t||e);if(this.avatarWrap.hidden=!s,!s)return void this.avatarWrap.replaceChildren();let a=this.avatarWrap.querySelector("db-avatar");a||(a=document.createElement("db-avatar"),this.avatarWrap.append(a)),a.setAttribute("size","s"),t?a.setAttribute("src",t):a.removeAttribute("src"),e?a.setAttribute("initials",e):a.removeAttribute("initials"),"assistant"!==this.role||t||e||a.setAttribute("variant","primary")}renderActions(){this.actionsEl.replaceChildren();const s=(this.getAttribute("actions")||"").split(",").map(t=>t.trim()).filter(Boolean);for(const n of s){const s=document.createElement("button");s.type="button",s.className="designbase-wc-chat-message__action",s.setAttribute("aria-label",i[n]||n);const r=a[n];s.append(t(r&&e(r)?r:"sparkle",16)),s.addEventListener("click",()=>this.handleAction(n,s)),this.actionsEl.append(s)}this.actionsEl.hidden=0===s.length}handleAction(t,e){if("copy"===t){const t=this.contentEl.textContent||"";navigator.clipboard?.writeText(t).catch(()=>{})}"like"!==t&&"dislike"!==t||e.classList.toggle("designbase-wc-chat-message__action--active"),this.dispatchEvent(new CustomEvent("db-action",{detail:{action:t,text:this.contentEl.textContent||""},bubbles:!0,composed:!0}))}}customElements.get("db-chat-message")||customElements.define("db-chat-message",DbChatMessage);export{DbChatMessage};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type
|
|
6
|
-
type
|
|
7
|
-
type OrbState = (typeof STATES)[number];
|
|
8
|
-
type OrbTheme = (typeof THEMES)[number];
|
|
1
|
+
import { CHAT_ORB_SIZES, CHAT_ORB_VARIANTS, CHAT_ORB_STATES, CHAT_ORB_THEMES } from '@designbasekorea/ui-contracts';
|
|
2
|
+
|
|
3
|
+
type OrbSize = (typeof CHAT_ORB_SIZES)[number];
|
|
4
|
+
type OrbVariant = (typeof CHAT_ORB_VARIANTS)[number];
|
|
5
|
+
type OrbState = (typeof CHAT_ORB_STATES)[number];
|
|
6
|
+
type OrbTheme = (typeof CHAT_ORB_THEMES)[number];
|
|
9
7
|
/**
|
|
10
8
|
* AI 어시스턴트를 상징하는 캔버스 기반 애니메이션 오브(구체).
|
|
11
9
|
* 광택 있는 3D 구체 위에 유체처럼 흐르는 내부 광원 + 프레넬 림 라이트 + 스페큘러 하이라이트로
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=["xs","s","m","l","xl"],e=["aurora","ocean","emerald","violet","mono"],i=["idle","thinking","listening"],s=["auto","light","dark"];function pick(t,e,i){return t.includes(e)?e:i}const a={aurora:{core:[22,20,52],lights:[[236,92,220],[70,140,250],[42,208,158]],rim:[199,210,254],glow:[120,110,240]},ocean:{core:[10,32,62],lights:[[56,189,248],[34,211,238],[96,165,250]],rim:[165,243,252],glow:[59,130,246]},emerald:{core:[6,42,38],lights:[[52,211,153],[74,222,128],[163,230,53]],rim:[187,247,208],glow:[34,197,94]},violet:{core:[40,12,82],lights:[[192,132,252],[168,85,247],[240,171,252]],rim:[245,208,254],glow:[139,92,246]},mono:{core:[30,34,44],lights:[[229,231,235],[156,163,175],[249,250,251]],rim:[255,255,255],glow:[156,163,175]}},r={aurora:{core:[240,240,250],lights:[[235,96,224],[74,144,246],[26,196,150]],rim:[150,130,210],glow:[138,128,244]},ocean:{core:[226,248,255],lights:[[14,165,233],[34,211,238],[96,165,250]],rim:[64,150,181],glow:[56,189,248]},emerald:{core:[228,250,240],lights:[[16,185,129],[74,222,128],[163,230,53]],rim:[57,145,111],glow:[52,211,153]},violet:{core:[246,233,255],lights:[[168,85,247],[217,70,239],[240,171,252]],rim:[143,91,183],glow:[192,132,252]},mono:{core:[243,246,250],lights:[[148,163,184],[203,213,225],[255,255,255]],rim:[100,116,139],glow:[148,163,184]}},n={idle:{speed:1.55,amp:.38,turb:.95,glow:1.15,breatheSpeed:1.9,breatheAmt:.055,lightAlpha:.95,autoRipple:0},thinking:{speed:3.2,amp:.5,turb:1.45,glow:1.85,breatheSpeed:4.2,breatheAmt:.075,lightAlpha:1.35,autoRipple:0},listening:{speed:1.45,amp:.32,turb:.9,glow:1.2,breatheSpeed:2.1,breatheAmt:.035,lightAlpha:.95,autoRipple:1.7}};function rgba(t,e){return`rgba(${t[0]},${t[1]},${t[2]},${e})`}function mix(t,e,i){return[t[0]+(e[0]-t[0])*i,t[1]+(e[1]-t[1])*i,t[2]+(e[2]-t[2])*i]}function clamp(t,e,i){return Math.min(i,Math.max(e,t))}function numberAttribute(t,e,i,s,a){const r=t.getAttribute(e);if(null===r||""===r.trim())return i;const n=Number(r);return Number.isFinite(n)?clamp(n,s,a):i}const h=2*Math.PI,o="undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches,l=new Set;let c=0;function tick(t){l.forEach(e=>e.frame(t)),c=l.size?requestAnimationFrame(tick):0}class DbChatOrb extends HTMLElement{constructor(){super(...arguments),this.dpr=1,this.cssW=0,this.cssH=0,this.t0=0,this.lastFrame=0,this.resizeObs=null,this.io=null,this.themeObserver=null,this.themeMedia=null,this.visible=!1,this.hover={x:0,y:0,tx:0,ty:0},this.ripples=[],this.lastAutoRipple=0,this.lastVoiceRipple=0,this.previousVoiceLevel=0,this.displayedVoiceLevel=0,this.inputStream=null,this.audioContext=null,this.audioSource=null,this.analyser=null,this.analyserData=null,this.onPointerMove=t=>{const e=this.getBoundingClientRect();e.width&&(this.hover.tx=Math.max(-1,Math.min(1,2*((t.clientX-e.left)/e.width-.5))),this.hover.ty=Math.max(-1,Math.min(1,2*((t.clientY-e.top)/e.height-.5))))},this.onPointerLeave=()=>{this.hover.tx=0,this.hover.ty=0},this.onPointerDown=()=>{this.addRipple(performance.now(),1)},this.onThemeChange=()=>{o&&this.frame(performance.now())}}static get observedAttributes(){return["size","variant","state","theme","voice-level","min-scale","max-scale"]}get size(){return pick(t,this.getAttribute("size"),"l")}set size(t){this.setAttribute("size",t)}get variant(){return pick(e,this.getAttribute("variant"),"aurora")}set variant(t){this.setAttribute("variant",t)}get state(){return pick(i,this.getAttribute("state"),"idle")}set state(t){this.setAttribute("state",t)}get theme(){return pick(s,this.getAttribute("theme"),"auto")}set theme(t){this.setAttribute("theme",t)}get voiceLevel(){return numberAttribute(this,"voice-level",0,0,1)}set voiceLevel(t){const e=Number(t);this.setAttribute("voice-level",String(clamp(Number.isFinite(e)?e:0,0,1)))}get minScale(){return numberAttribute(this,"min-scale",.88,.5,1.5)}set minScale(t){const e=Number(t);this.setAttribute("min-scale",String(clamp(Number.isFinite(e)?e:.88,.5,1.5)))}get maxScale(){return Math.max(this.minScale,numberAttribute(this,"max-scale",1.18,.5,1.7))}set maxScale(t){const e=Number(t);this.setAttribute("max-scale",String(clamp(Number.isFinite(e)?e:1.18,.5,1.7)))}get audioStream(){return this.inputStream}set audioStream(t){(t!==this.inputStream||null!==t&&!this.analyser)&&(this.stopAudioAnalysis(),this.inputStream=t&&"function"==typeof t.getAudioTracks?t:null,this.isConnected&&this.inputStream&&this.startAudioAnalysis(this.inputStream))}connectedCallback(){this.syncClasses(),this.setAttribute("aria-hidden","true"),this.canvas||this.build(),this.t0=performance.now(),this.lastFrame=0,this.observeTheme(),this.inputStream&&this.startAudioAnalysis(this.inputStream),"undefined"!=typeof ResizeObserver&&(this.resizeObs=new ResizeObserver(()=>this.resize()),this.resizeObs.observe(this)),this.resize(),o?this.frame(this.t0+1600):"undefined"!=typeof IntersectionObserver?(this.io=new IntersectionObserver(t=>{for(const e of t)this.setVisible(e.isIntersecting)},{threshold:.01}),this.io.observe(this)):this.setVisible(!0)}disconnectedCallback(){this.setVisible(!1),this.resizeObs?.disconnect(),this.resizeObs=null,this.io?.disconnect(),this.io=null,this.themeObserver?.disconnect(),this.themeObserver=null,this.themeMedia?.removeEventListener("change",this.onThemeChange),this.themeMedia=null,this.stopAudioAnalysis()}attributeChangedCallback(t){this.canvas&&("size"!==t&&"variant"!==t&&"state"!==t||this.syncClasses(),o&&this.frame(performance.now()))}setVisible(t){t!==this.visible&&(this.visible=t,t?(l.add(this),function ensureTicking(){c||!l.size||o||(c=requestAnimationFrame(tick))}()):l.delete(this))}syncClasses(){this.className=["designbase-wc-chat-orb",`designbase-wc-chat-orb--${this.size}`,`designbase-wc-chat-orb--${this.variant}`,`designbase-wc-chat-orb--${this.state}`].join(" ")}build(){this.replaceChildren(),this.canvas=document.createElement("canvas"),this.canvas.className="designbase-wc-chat-orb__canvas",this.ctx=this.canvas.getContext("2d"),this.append(this.canvas),this.addEventListener("pointermove",this.onPointerMove),this.addEventListener("pointerleave",this.onPointerLeave),this.addEventListener("pointerdown",this.onPointerDown)}addRipple(t,e){this.ripples.push({start:t,strength:clamp(e,.2,1)})}observeTheme(){"undefined"==typeof MutationObserver||this.themeObserver||(this.themeObserver=new MutationObserver(this.onThemeChange),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme","data-color-mode","class"]})),"function"!=typeof window.matchMedia||this.themeMedia||(this.themeMedia=window.matchMedia("(prefers-color-scheme: dark)"),this.themeMedia.addEventListener("change",this.onThemeChange))}isDarkContext(){if("dark"===this.theme)return!0;if("light"===this.theme)return!1;const t=this.parentElement?.closest("[data-theme], [data-color-mode]"),e=t?.getAttribute("data-color-mode");if("dark"===e)return!0;if("light"===e)return!1;const i=t?.getAttribute("data-theme");if("dark"===i)return!0;if("light"===i)return!1;const s=document.documentElement,a=s.getAttribute("data-color-mode");if("dark"===a)return!0;if("light"===a)return!1;const r=s.getAttribute("data-theme");return"dark"===r||"light"!==r&&(this.themeMedia?.matches??!1)}startAudioAnalysis(t){if(this.analyser)return;const e=window.AudioContext??window.webkitAudioContext;if(e)try{const i=new e,s=i.createAnalyser();s.fftSize=512,s.smoothingTimeConstant=.58;const a=i.createMediaStreamSource(t);a.connect(s),this.audioContext=i,this.audioSource=a,this.analyser=s,this.analyserData=new Float32Array(s.fftSize),"suspended"===i.state&&i.resume().catch(()=>{})}catch{this.stopAudioAnalysis()}}stopAudioAnalysis(){try{this.audioSource?.disconnect(),this.analyser?.disconnect()}catch{}this.audioContext&&this.audioContext.close().catch(()=>{}),this.audioContext=null,this.audioSource=null,this.analyser=null,this.analyserData=null}sampleVoiceLevel(t){if(this.analyser&&this.analyserData){this.analyser.getFloatTimeDomainData(this.analyserData);let t=0;for(const e of this.analyserData)t+=e*e;return{level:clamp((Math.sqrt(t/this.analyserData.length)-.01)/.11,0,1),hasInput:!0}}if(this.hasAttribute("voice-level"))return{level:this.voiceLevel,hasInput:!0};return{level:clamp(.16+.12*(Math.sin(2.05*t)+1)+.42*Math.pow(Math.max(0,Math.sin(.86*t+.7)),5),0,1),hasInput:!1}}resize(){this.canvas&&(this.dpr=Math.min(2,window.devicePixelRatio||1),this.cssW=this.clientWidth||72,this.cssH=this.clientHeight||this.cssW,this.canvas.width=Math.round(this.cssW*this.dpr),this.canvas.height=Math.round(this.cssH*this.dpr),o&&this.frame(this.t0+1600))}frame(t){const e=this.ctx;if(!e||!this.cssW)return;const i=this.lastFrame?Math.min((t-this.lastFrame)/1e3,.1):1/60;this.lastFrame=t;const s=(t-this.t0)/1e3,o=this.cssW,l=this.cssH,c=o/2,d=l/2,m=Math.min(o,l)/2,u=this.isDarkContext(),p=u?a[this.variant]:r[this.variant],g=n[this.state];this.hover.x+=.08*(this.hover.tx-this.hover.x),this.hover.y+=.08*(this.hover.ty-this.hover.y);const b="listening"===this.state?this.sampleVoiceLevel(s):{level:0,hasInput:!1},v=b.level>this.displayedVoiceLevel?19:7;this.displayedVoiceLevel+=(b.level-this.displayedVoiceLevel)*(1-Math.exp(-v*i)),"listening"!==this.state&&this.displayedVoiceLevel<.001&&(this.displayedVoiceLevel=0);const f=Math.pow(clamp(this.displayedVoiceLevel,0,1),.72),y="listening"===this.state?this.minScale+(this.maxScale-this.minScale)*f:1,w=g.breatheAmt*("listening"===this.state?.55:1),A=1+Math.sin(s*g.breatheSpeed)*w,S="listening"===this.state?f:"thinking"===this.state?1:.55,M="thinking"===this.state?1.38:1,C=.68*m*A*y*("thinking"===this.state?1.1:1),x=.99*m;e.setTransform(this.dpr,0,0,this.dpr,0,0),e.clearRect(0,0,o,l),e.globalCompositeOperation="source-over",e.filter="none";const k="thinking"===this.state?u?.42:.22:u?.28:.5,O=u?mix(p.core,p.lights[0],k):"thinking"===this.state?mix(p.core,p.lights[0],.35):mix(p.core,[255,255,255],.5),z=mix(p.core,p.lights[1],u?"thinking"===this.state?.35:0:"thinking"===this.state?.28:.12),L=e.createRadialGradient(c,d-.12*C,.1*C,c,d,C);L.addColorStop(0,rgba(O,u?1:.96)),L.addColorStop(.72,rgba(z,u?1:.9)),L.addColorStop(.93,rgba(z,u?.72:.5)),L.addColorStop(1,rgba(z,0)),e.fillStyle=L,e.beginPath(),e.arc(c,d,C,0,h),e.fill(),e.globalCompositeOperation=u?"lighter":"source-over";const R=p.lights.length;for(let t=0;t<R;t+=1){const i=2.1*t,a=g.turb*(.85+.55*S),r=Math.sin(s*g.speed+i)*g.amp+Math.sin(s*g.speed*1.7+1.4*i)*g.amp*a*.75+Math.sin(s*g.speed*.45+.7*i)*g.amp*.35,n=Math.cos(s*g.speed*.9+1.3*i)*g.amp+Math.cos(s*g.speed*2+i)*g.amp*a*.75+Math.cos(s*g.speed*.55+.9*i)*g.amp*.35,o="thinking"===this.state?.42:.28,l=t/R*h-.5*Math.PI+s*g.speed*o,m=C*("thinking"===this.state?.52:.44),b=c+Math.cos(l)*m+r*C+this.hover.x*C*.12,v=d+Math.sin(l)*m+n*C+this.hover.y*C*.12,f=C*M*(.92+.28*S+.12*Math.sin(s*g.speed*1.3+i)),y="thinking"===this.state?mix(p.lights[t],u?[255,255,255]:p.core,u?.1:.18):p.lights[t],w=(u?.62:.78)*g.lightAlpha*(.85+.28*S)*("thinking"===this.state?1.22:1);e.save(),e.filter=`blur(${C*(u?.15:.18)*("thinking"===this.state?.92:1)}px)`;const A=e.createRadialGradient(b,v,0,b,v,f);A.addColorStop(0,rgba(y,Math.min(1,w))),A.addColorStop(.48,rgba(y,Math.min(1,.5*w))),A.addColorStop(1,rgba(y,0)),e.fillStyle=A,e.beginPath(),e.arc(b,v,f,0,h),e.fill(),e.restore()}e.filter="none",e.globalCompositeOperation="destination-in";const D=e.createRadialGradient(c,d,.6*C,c,d,C);D.addColorStop(0,"rgba(0,0,0,1)"),D.addColorStop(.86,"rgba(0,0,0,1)"),D.addColorStop(1,"rgba(0,0,0,0)"),e.fillStyle=D,e.beginPath(),e.arc(c,d,C,0,h),e.fill(),e.globalCompositeOperation="source-atop";const V=c-.22*C+this.hover.x*C*.1,F=d-.28*C+this.hover.y*C*.1,E=e.createRadialGradient(V,F,0,V,F,.95*C);E.addColorStop(0,`rgba(255,255,255,${u?.12:.2})`),E.addColorStop(1,"rgba(255,255,255,0)"),e.fillStyle=E,e.fillRect(c-C,d-C,2*C,2*C),e.globalCompositeOperation="destination-over";const P=e.createRadialGradient(c,d,.7*C,c,d,x),T=(u?.32:.14)*g.glow*(.85+.28*S);P.addColorStop(0,rgba(p.glow,T)),P.addColorStop(1,rgba(p.glow,0)),e.fillStyle=P,e.beginPath(),e.arc(c,d,x,0,h),e.fill(),e.globalCompositeOperation="source-over",e.filter="none"}}customElements.get("db-chat-orb")||customElements.define("db-chat-orb",DbChatOrb);export{DbChatOrb};
|
|
1
|
+
import{CHAT_ORB_SIZES as t,CHAT_ORB_VARIANTS as e,CHAT_ORB_STATES as i,CHAT_ORB_THEMES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function pick(t,e,i){return t.includes(e)?e:i}const a={aurora:{core:[22,20,52],lights:[[236,92,220],[70,140,250],[42,208,158]],rim:[199,210,254],glow:[120,110,240]},ocean:{core:[10,32,62],lights:[[56,189,248],[34,211,238],[96,165,250]],rim:[165,243,252],glow:[59,130,246]},emerald:{core:[6,42,38],lights:[[52,211,153],[74,222,128],[163,230,53]],rim:[187,247,208],glow:[34,197,94]},violet:{core:[40,12,82],lights:[[192,132,252],[168,85,247],[240,171,252]],rim:[245,208,254],glow:[139,92,246]},mono:{core:[30,34,44],lights:[[229,231,235],[156,163,175],[249,250,251]],rim:[255,255,255],glow:[156,163,175]}},r={aurora:{core:[240,240,250],lights:[[235,96,224],[74,144,246],[26,196,150]],rim:[150,130,210],glow:[138,128,244]},ocean:{core:[226,248,255],lights:[[14,165,233],[34,211,238],[96,165,250]],rim:[64,150,181],glow:[56,189,248]},emerald:{core:[228,250,240],lights:[[16,185,129],[74,222,128],[163,230,53]],rim:[57,145,111],glow:[52,211,153]},violet:{core:[246,233,255],lights:[[168,85,247],[217,70,239],[240,171,252]],rim:[143,91,183],glow:[192,132,252]},mono:{core:[243,246,250],lights:[[148,163,184],[203,213,225],[255,255,255]],rim:[100,116,139],glow:[148,163,184]}},n={idle:{speed:1.55,amp:.38,turb:.95,glow:1.15,breatheSpeed:1.9,breatheAmt:.055,lightAlpha:.95,autoRipple:0},thinking:{speed:3.2,amp:.5,turb:1.45,glow:1.85,breatheSpeed:4.2,breatheAmt:.075,lightAlpha:1.35,autoRipple:0},listening:{speed:1.45,amp:.32,turb:.9,glow:1.2,breatheSpeed:2.1,breatheAmt:.035,lightAlpha:.95,autoRipple:1.7}};function rgba(t,e){return`rgba(${t[0]},${t[1]},${t[2]},${e})`}function mix(t,e,i){return[t[0]+(e[0]-t[0])*i,t[1]+(e[1]-t[1])*i,t[2]+(e[2]-t[2])*i]}function clamp(t,e,i){return Math.min(i,Math.max(e,t))}function numberAttribute(t,e,i,s,a){const r=t.getAttribute(e);if(null===r||""===r.trim())return i;const n=Number(r);return Number.isFinite(n)?clamp(n,s,a):i}const h=2*Math.PI;function prefersReducedMotion(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}const o=new Set;let l=0;function tick(t){o.forEach(e=>e.frame(t)),l=o.size?requestAnimationFrame(tick):0}class DbChatOrb extends HTMLElement{constructor(){super(...arguments),this.dpr=1,this.cssW=0,this.cssH=0,this.t0=0,this.lastFrame=0,this.resizeObs=null,this.io=null,this.themeObserver=null,this.themeMedia=null,this.visible=!1,this.hover={x:0,y:0,tx:0,ty:0},this.ripples=[],this.lastAutoRipple=0,this.lastVoiceRipple=0,this.previousVoiceLevel=0,this.displayedVoiceLevel=0,this.inputStream=null,this.audioContext=null,this.audioSource=null,this.analyser=null,this.analyserData=null,this.onPointerMove=t=>{const e=this.getBoundingClientRect();e.width&&(this.hover.tx=Math.max(-1,Math.min(1,2*((t.clientX-e.left)/e.width-.5))),this.hover.ty=Math.max(-1,Math.min(1,2*((t.clientY-e.top)/e.height-.5))))},this.onPointerLeave=()=>{this.hover.tx=0,this.hover.ty=0},this.onPointerDown=()=>{this.addRipple(performance.now(),1)},this.onThemeChange=()=>{prefersReducedMotion()&&this.frame(performance.now())}}static get observedAttributes(){return["size","variant","state","theme","voice-level","min-scale","max-scale"]}get size(){return pick(t,this.getAttribute("size"),"l")}set size(t){this.setAttribute("size",t)}get variant(){return pick(e,this.getAttribute("variant"),"aurora")}set variant(t){this.setAttribute("variant",t)}get state(){return pick(i,this.getAttribute("state"),"idle")}set state(t){this.setAttribute("state",t)}get theme(){return pick(s,this.getAttribute("theme"),"auto")}set theme(t){this.setAttribute("theme",t)}get voiceLevel(){return numberAttribute(this,"voice-level",0,0,1)}set voiceLevel(t){const e=Number(t);this.setAttribute("voice-level",String(clamp(Number.isFinite(e)?e:0,0,1)))}get minScale(){return numberAttribute(this,"min-scale",.88,.5,1.5)}set minScale(t){const e=Number(t);this.setAttribute("min-scale",String(clamp(Number.isFinite(e)?e:.88,.5,1.5)))}get maxScale(){return Math.max(this.minScale,numberAttribute(this,"max-scale",1.18,.5,1.7))}set maxScale(t){const e=Number(t);this.setAttribute("max-scale",String(clamp(Number.isFinite(e)?e:1.18,.5,1.7)))}get audioStream(){return this.inputStream}set audioStream(t){(t!==this.inputStream||null!==t&&!this.analyser)&&(this.stopAudioAnalysis(),this.inputStream=t&&"function"==typeof t.getAudioTracks?t:null,this.isConnected&&this.inputStream&&this.startAudioAnalysis(this.inputStream))}connectedCallback(){this.syncClasses(),this.setAttribute("aria-hidden","true"),this.canvas||this.build(),this.t0=performance.now(),this.lastFrame=0,this.observeTheme(),this.inputStream&&this.startAudioAnalysis(this.inputStream),"undefined"!=typeof ResizeObserver&&(this.resizeObs=new ResizeObserver(()=>this.resize()),this.resizeObs.observe(this)),this.resize(),prefersReducedMotion()?this.frame(this.t0+1600):"undefined"!=typeof IntersectionObserver?(this.io=new IntersectionObserver(t=>{for(const e of t)this.setVisible(e.isIntersecting)},{threshold:.01}),this.io.observe(this)):this.setVisible(!0)}disconnectedCallback(){this.setVisible(!1),this.resizeObs?.disconnect(),this.resizeObs=null,this.io?.disconnect(),this.io=null,this.themeObserver?.disconnect(),this.themeObserver=null,this.themeMedia?.removeEventListener("change",this.onThemeChange),this.themeMedia=null,this.stopAudioAnalysis()}attributeChangedCallback(t){this.canvas&&("size"!==t&&"variant"!==t&&"state"!==t||this.syncClasses(),prefersReducedMotion()&&this.frame(performance.now()))}setVisible(t){t!==this.visible&&(this.visible=t,t?(o.add(this),function ensureTicking(){l||!o.size||prefersReducedMotion()||(l=requestAnimationFrame(tick))}()):o.delete(this))}syncClasses(){this.className=["designbase-wc-chat-orb",`designbase-wc-chat-orb--${this.size}`,`designbase-wc-chat-orb--${this.variant}`,`designbase-wc-chat-orb--${this.state}`].join(" ")}build(){this.replaceChildren(),this.canvas=document.createElement("canvas"),this.canvas.className="designbase-wc-chat-orb__canvas",this.ctx=this.canvas.getContext("2d"),this.append(this.canvas),this.addEventListener("pointermove",this.onPointerMove),this.addEventListener("pointerleave",this.onPointerLeave),this.addEventListener("pointerdown",this.onPointerDown)}addRipple(t,e){this.ripples.push({start:t,strength:clamp(e,.2,1)})}observeTheme(){"undefined"==typeof MutationObserver||this.themeObserver||(this.themeObserver=new MutationObserver(this.onThemeChange),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme","data-color-mode","class"]})),"function"!=typeof window.matchMedia||this.themeMedia||(this.themeMedia=window.matchMedia("(prefers-color-scheme: dark)"),this.themeMedia.addEventListener("change",this.onThemeChange))}isDarkContext(){if("dark"===this.theme)return!0;if("light"===this.theme)return!1;const t=this.parentElement?.closest("[data-theme], [data-color-mode]"),e=t?.getAttribute("data-color-mode");if("dark"===e)return!0;if("light"===e)return!1;const i=t?.getAttribute("data-theme");if("dark"===i)return!0;if("light"===i)return!1;const s=document.documentElement,a=s.getAttribute("data-color-mode");if("dark"===a)return!0;if("light"===a)return!1;const r=s.getAttribute("data-theme");return"dark"===r||"light"!==r&&(this.themeMedia?.matches??!1)}startAudioAnalysis(t){if(this.analyser)return;const e=window.AudioContext??window.webkitAudioContext;if(e)try{const i=new e,s=i.createAnalyser();s.fftSize=512,s.smoothingTimeConstant=.58;const a=i.createMediaStreamSource(t);a.connect(s),this.audioContext=i,this.audioSource=a,this.analyser=s,this.analyserData=new Float32Array(s.fftSize),"suspended"===i.state&&i.resume().catch(()=>{})}catch{this.stopAudioAnalysis()}}stopAudioAnalysis(){try{this.audioSource?.disconnect(),this.analyser?.disconnect()}catch{}this.audioContext&&this.audioContext.close().catch(()=>{}),this.audioContext=null,this.audioSource=null,this.analyser=null,this.analyserData=null}sampleVoiceLevel(t){if(this.analyser&&this.analyserData){this.analyser.getFloatTimeDomainData(this.analyserData);let t=0;for(const e of this.analyserData)t+=e*e;return{level:clamp((Math.sqrt(t/this.analyserData.length)-.01)/.11,0,1),hasInput:!0}}if(this.hasAttribute("voice-level"))return{level:this.voiceLevel,hasInput:!0};return{level:clamp(.16+.12*(Math.sin(2.05*t)+1)+.42*Math.pow(Math.max(0,Math.sin(.86*t+.7)),5),0,1),hasInput:!1}}resize(){this.canvas&&(this.dpr=Math.min(2,window.devicePixelRatio||1),this.cssW=this.clientWidth||72,this.cssH=this.clientHeight||this.cssW,this.canvas.width=Math.round(this.cssW*this.dpr),this.canvas.height=Math.round(this.cssH*this.dpr),prefersReducedMotion()&&this.frame(this.t0+1600))}frame(t){const e=this.ctx;if(!e||!this.cssW)return;const i=this.lastFrame?Math.min((t-this.lastFrame)/1e3,.1):1/60;this.lastFrame=t;const s=(t-this.t0)/1e3,o=this.cssW,l=this.cssH,c=o/2,d=l/2,u=Math.min(o,l)/2,m=this.isDarkContext(),p=m?a[this.variant]:r[this.variant],g=n[this.state];this.hover.x+=.08*(this.hover.tx-this.hover.x),this.hover.y+=.08*(this.hover.ty-this.hover.y);const b="listening"===this.state?this.sampleVoiceLevel(s):{level:0,hasInput:!1},v=b.level>this.displayedVoiceLevel?19:7;this.displayedVoiceLevel+=(b.level-this.displayedVoiceLevel)*(1-Math.exp(-v*i)),"listening"!==this.state&&this.displayedVoiceLevel<.001&&(this.displayedVoiceLevel=0);const f=Math.pow(clamp(this.displayedVoiceLevel,0,1),.72),y="listening"===this.state?this.minScale+(this.maxScale-this.minScale)*f:1,w=g.breatheAmt*("listening"===this.state?.55:1),M=1+Math.sin(s*g.breatheSpeed)*w,A="listening"===this.state?f:"thinking"===this.state?1:.55,S="thinking"===this.state?1.38:1,C=.68*u*M*y*("thinking"===this.state?1.1:1),x=.99*u;e.setTransform(this.dpr,0,0,this.dpr,0,0),e.clearRect(0,0,o,l),e.globalCompositeOperation="source-over",e.filter="none";const k="thinking"===this.state?m?.42:.22:m?.28:.5,O=m?mix(p.core,p.lights[0],k):"thinking"===this.state?mix(p.core,p.lights[0],.35):mix(p.core,[255,255,255],.5),R=mix(p.core,p.lights[1],m?"thinking"===this.state?.35:0:"thinking"===this.state?.28:.12),z=e.createRadialGradient(c,d-.12*C,.1*C,c,d,C);z.addColorStop(0,rgba(O,m?1:.96)),z.addColorStop(.72,rgba(R,m?1:.9)),z.addColorStop(.93,rgba(R,m?.72:.5)),z.addColorStop(1,rgba(R,0)),e.fillStyle=z,e.beginPath(),e.arc(c,d,C,0,h),e.fill(),e.globalCompositeOperation=m?"lighter":"source-over";const L=p.lights.length;for(let t=0;t<L;t+=1){const i=2.1*t,a=g.turb*(.85+.55*A),r=Math.sin(s*g.speed+i)*g.amp+Math.sin(s*g.speed*1.7+1.4*i)*g.amp*a*.75+Math.sin(s*g.speed*.45+.7*i)*g.amp*.35,n=Math.cos(s*g.speed*.9+1.3*i)*g.amp+Math.cos(s*g.speed*2+i)*g.amp*a*.75+Math.cos(s*g.speed*.55+.9*i)*g.amp*.35,o="thinking"===this.state?.42:.28,l=t/L*h-.5*Math.PI+s*g.speed*o,u=C*("thinking"===this.state?.52:.44),b=c+Math.cos(l)*u+r*C+this.hover.x*C*.12,v=d+Math.sin(l)*u+n*C+this.hover.y*C*.12,f=C*S*(.92+.28*A+.12*Math.sin(s*g.speed*1.3+i)),y="thinking"===this.state?mix(p.lights[t],m?[255,255,255]:p.core,m?.1:.18):p.lights[t],w=(m?.62:.78)*g.lightAlpha*(.85+.28*A)*("thinking"===this.state?1.22:1);e.save(),e.filter=`blur(${C*(m?.15:.18)*("thinking"===this.state?.92:1)}px)`;const M=e.createRadialGradient(b,v,0,b,v,f);M.addColorStop(0,rgba(y,Math.min(1,w))),M.addColorStop(.48,rgba(y,Math.min(1,.5*w))),M.addColorStop(1,rgba(y,0)),e.fillStyle=M,e.beginPath(),e.arc(b,v,f,0,h),e.fill(),e.restore()}e.filter="none",e.globalCompositeOperation="destination-in";const D=e.createRadialGradient(c,d,.6*C,c,d,C);D.addColorStop(0,"rgba(0,0,0,1)"),D.addColorStop(.86,"rgba(0,0,0,1)"),D.addColorStop(1,"rgba(0,0,0,0)"),e.fillStyle=D,e.beginPath(),e.arc(c,d,C,0,h),e.fill(),e.globalCompositeOperation="source-atop";const V=c-.22*C+this.hover.x*C*.1,F=d-.28*C+this.hover.y*C*.1,E=e.createRadialGradient(V,F,0,V,F,.95*C);E.addColorStop(0,`rgba(255,255,255,${m?.12:.2})`),E.addColorStop(1,"rgba(255,255,255,0)"),e.fillStyle=E,e.fillRect(c-C,d-C,2*C,2*C),e.globalCompositeOperation="destination-over";const P=e.createRadialGradient(c,d,.7*C,c,d,x),T=(m?.32:.14)*g.glow*(.85+.28*A);P.addColorStop(0,rgba(p.glow,T)),P.addColorStop(1,rgba(p.glow,0)),e.fillStyle=P,e.beginPath(),e.arc(c,d,x,0,h),e.fill(),e.globalCompositeOperation="source-over",e.filter="none"}}customElements.get("db-chat-orb")||customElements.define("db-chat-orb",DbChatOrb);export{DbChatOrb};
|