@designbasekorea/ui-wc 0.9.3 → 0.9.4
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 +9 -0
- package/dist/esm/components/date-picker-utils.js +1 -1
- package/dist/esm/components/db-activity-heatmap.js +1 -1
- package/dist/esm/components/db-ai-file-tree.js +1 -1
- package/dist/esm/components/db-calendar.d.ts +2 -1
- package/dist/esm/components/db-calendar.js +1 -1
- package/dist/esm/components/db-carousel.d.ts +2 -0
- package/dist/esm/components/db-carousel.js +1 -1
- package/dist/esm/components/db-checkbox.d.ts +15 -1
- package/dist/esm/components/db-checkbox.js +1 -1
- package/dist/esm/components/db-confirm.d.ts +2 -0
- package/dist/esm/components/db-confirm.js +1 -1
- package/dist/esm/components/db-credit-card.d.ts +3 -4
- package/dist/esm/components/db-credit-card.js +1 -1
- package/dist/esm/components/db-date-picker.d.ts +2 -1
- package/dist/esm/components/db-date-picker.js +1 -1
- package/dist/esm/components/db-design-toolbar.js +1 -1
- package/dist/esm/components/db-device-mockup.js +1 -1
- package/dist/esm/components/db-flight-status.d.ts +2 -2
- package/dist/esm/components/db-flight-status.js +1 -1
- package/dist/esm/components/db-gantt.js +1 -1
- package/dist/esm/components/db-indicator.d.ts +1 -0
- package/dist/esm/components/db-indicator.js +1 -1
- package/dist/esm/components/db-kanban.js +1 -1
- package/dist/esm/components/db-node.d.ts +1 -3
- package/dist/esm/components/db-node.js +1 -1
- package/dist/esm/components/db-radio.d.ts +19 -1
- package/dist/esm/components/db-radio.js +1 -1
- package/dist/esm/components/db-receipt.js +1 -1
- package/dist/esm/components/db-tabs.js +1 -1
- package/dist/esm/components/db-textarea.js +1 -1
- package/dist/esm/components/db-tool-button.js +1 -1
- package/dist/esm/components/db-voice-control.js +1 -1
- package/dist/esm/core/ai-element.d.ts +2 -1
- package/dist/esm/core/ai-element.js +1 -1
- package/dist/esm/core/i18n-en.js +1 -1
- package/dist/esm/core/i18n.d.ts +4 -0
- package/dist/esm/core/i18n.js +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
- package/dist/esm/ui-contracts/dist/components.d.d.ts +9 -2
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +58 -13
- package/dist/index.esm.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +31 -9
- package/dist/react/index.esm.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbText as t}from"../core/i18n.js";import{DbToolButton as e}from"./db-tool-button.js";class DbDesignToolbar extends HTMLElement{constructor(){super(...arguments),this.tools=new Map,this.focusId="",this.connected=!1,this.location={x:12,y:12},this.focusIn=t=>{const e=t.target.closest("db-button");e&&(this.focusId=e.dataset.toolId||"",this.rove())},this.keyDown=t=>{if(!t.target.closest("db-tool-button"))return;const e="vertical"===this.getAttribute("orientation"),i=e?"ArrowDown":"ArrowRight";if(![e?"ArrowUp":"ArrowLeft",i,"Home","End"].includes(t.key))return;t.preventDefault();const o=this.buttons(),s=o.indexOf(document.activeElement),n="Home"===t.key?0:"End"===t.key?o.length-1:(s+(t.key===i?1:-1)+o.length)%o.length;o[n]?.focus()},this.dragStart=t=>{if(0!==t.button||!this.parentElement)return;t.preventDefault(),t.stopPropagation(),this.closeMenus();const e=this.parentElement.getBoundingClientRect();this.dragState={pointer:t.pointerId,clientX:t.clientX,clientY:t.clientY,...this.location,scaleX:e.width/Math.max(1,this.parentElement.offsetWidth),scaleY:e.height/Math.max(1,this.parentElement.offsetHeight)},this.grip?.querySelector("db-button")?.focus({preventScroll:!0}),this.setPointerCapture(t.pointerId),this.setAttribute("data-moving","")},this.dragMove=t=>{const e=this.dragState;e&&t.pointerId===e.pointer&&(t.preventDefault(),t.stopPropagation(),this.location={x:e.x+(t.clientX-e.clientX)/e.scaleX,y:e.y+(t.clientY-e.clientY)/e.scaleY},this.constrainPosition(!0))},this.dragEnd=t=>{this.dragState?.pointer===t.pointerId&&(this.dragState=void 0,this.removeAttribute("data-moving"),this.hasPointerCapture(t.pointerId)&&this.releasePointerCapture(t.pointerId),this.constrainPosition(!0))},this.dragCancel=t=>{this.dragState?.pointer===t.pointerId&&this.dragEnd(t)},this.gripKey=t=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home"].includes(t.key))return;if(t.preventDefault(),t.stopPropagation(),"Home"===t.key)return void this.resetPosition();const e=t.shiftKey?20:4;this.location.x+="ArrowRight"===t.key?e:"ArrowLeft"===t.key?-e:0,this.location.y+="ArrowDown"===t.key?e:"ArrowUp"===t.key?-e:0,this.constrainPosition(!0)}}static get observedAttributes(){return["items","size","tone","orientation","placement","movable","toolbar-position"]}get toolbarPosition(){return{...this.location}}set toolbarPosition(t){try{const e="string"==typeof t?JSON.parse(t):t;this.location={x:Number.isFinite(e.x)?e.x:12,y:Number.isFinite(e.y)?e.y:12},this.constrainPosition()}catch{}}get items(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t.filter(t=>t&&"string"==typeof t.id):[]}catch{return[]}}set items(t){const e="string"==typeof t?t:JSON.stringify(t);e!==this.getAttribute("items")&&this.setAttribute("items",e)}connectedCallback(){this.connected=!0,this.classList.add("designbase-wc-design-toolbar"),this.setAttribute("role","toolbar"),this.hasAttribute("aria-label")||this.setAttribute("aria-label",t("디자인 도구")),this.addEventListener("keydown",this.keyDown),this.addEventListener("focusin",this.focusIn),this.sync(),this.addEventListener("pointermove",this.dragMove),this.addEventListener("pointerup",this.dragEnd),this.addEventListener("pointercancel",this.dragCancel),this.addEventListener("lostpointercapture",this.dragCancel),this.boundaryObserver=new ResizeObserver(()=>this.constrainPosition()),this.parentElement&&this.boundaryObserver.observe(this.parentElement),this.boundaryObserver.observe(this),this.constrainPosition()}disconnectedCallback(){this.connected=!1,this.dragState=void 0,this.boundaryObserver?.disconnect(),this.removeEventListener("pointermove",this.dragMove),this.removeEventListener("pointerup",this.dragEnd),this.removeEventListener("pointercancel",this.dragCancel),this.removeEventListener("lostpointercapture",this.dragCancel),this.removeEventListener("keydown",this.keyDown),this.removeEventListener("focusin",this.focusIn)}attributeChangedCallback(t){"toolbar-position"===t&&(this.toolbarPosition=this.getAttribute("toolbar-position")||"{}"),this.connected&&this.sync()}sync(){const t=this.items,e=new Set,set=(t,e,i)=>{t.getAttribute(e)!==i&&t.setAttribute(e,i)},
|
|
1
|
+
import{dbText as t}from"../core/i18n.js";import{DbToolButton as e}from"./db-tool-button.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{DESIGN_TOOL_TONES as o,DESIGN_TOOL_SIZES as s,POPOVER_PLACEMENTS as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbDesignToolbar extends HTMLElement{constructor(){super(...arguments),this.tools=new Map,this.focusId="",this.connected=!1,this.location={x:12,y:12},this.focusIn=t=>{const e=t.target.closest("db-button");e&&(this.focusId=e.dataset.toolId||"",this.rove())},this.keyDown=t=>{if(!t.target.closest("db-tool-button"))return;const e="vertical"===this.getAttribute("orientation"),i=e?"ArrowDown":"ArrowRight";if(![e?"ArrowUp":"ArrowLeft",i,"Home","End"].includes(t.key))return;t.preventDefault();const o=this.buttons(),s=o.indexOf(document.activeElement),n="Home"===t.key?0:"End"===t.key?o.length-1:(s+(t.key===i?1:-1)+o.length)%o.length;o[n]?.focus()},this.dragStart=t=>{if(0!==t.button||!this.parentElement)return;t.preventDefault(),t.stopPropagation(),this.closeMenus();const e=this.parentElement.getBoundingClientRect();this.dragState={pointer:t.pointerId,clientX:t.clientX,clientY:t.clientY,...this.location,scaleX:e.width/Math.max(1,this.parentElement.offsetWidth),scaleY:e.height/Math.max(1,this.parentElement.offsetHeight)},this.grip?.querySelector("db-button")?.focus({preventScroll:!0}),this.setPointerCapture(t.pointerId),this.setAttribute("data-moving","")},this.dragMove=t=>{const e=this.dragState;e&&t.pointerId===e.pointer&&(t.preventDefault(),t.stopPropagation(),this.location={x:e.x+(t.clientX-e.clientX)/e.scaleX,y:e.y+(t.clientY-e.clientY)/e.scaleY},this.constrainPosition(!0))},this.dragEnd=t=>{this.dragState?.pointer===t.pointerId&&(this.dragState=void 0,this.removeAttribute("data-moving"),this.hasPointerCapture(t.pointerId)&&this.releasePointerCapture(t.pointerId),this.constrainPosition(!0))},this.dragCancel=t=>{this.dragState?.pointer===t.pointerId&&this.dragEnd(t)},this.gripKey=t=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home"].includes(t.key))return;if(t.preventDefault(),t.stopPropagation(),"Home"===t.key)return void this.resetPosition();const e=t.shiftKey?20:4;this.location.x+="ArrowRight"===t.key?e:"ArrowLeft"===t.key?-e:0,this.location.y+="ArrowDown"===t.key?e:"ArrowUp"===t.key?-e:0,this.constrainPosition(!0)}}static get observedAttributes(){return["items","size","tone","orientation","placement","movable","toolbar-position"]}get toolbarPosition(){return{...this.location}}set toolbarPosition(t){try{const e="string"==typeof t?JSON.parse(t):t;this.location={x:Number.isFinite(e.x)?e.x:12,y:Number.isFinite(e.y)?e.y:12},this.constrainPosition()}catch{}}get items(){try{const t=JSON.parse(this.getAttribute("items")||"[]");return Array.isArray(t)?t.filter(t=>t&&"string"==typeof t.id):[]}catch{return[]}}set items(t){const e="string"==typeof t?t:JSON.stringify(t);e!==this.getAttribute("items")&&this.setAttribute("items",e)}connectedCallback(){this.connected=!0,this.classList.add("designbase-wc-design-toolbar"),this.setAttribute("role","toolbar"),this.hasAttribute("aria-label")||this.setAttribute("aria-label",t("디자인 도구")),this.addEventListener("keydown",this.keyDown),this.addEventListener("focusin",this.focusIn),this.sync(),this.addEventListener("pointermove",this.dragMove),this.addEventListener("pointerup",this.dragEnd),this.addEventListener("pointercancel",this.dragCancel),this.addEventListener("lostpointercapture",this.dragCancel),this.boundaryObserver=new ResizeObserver(()=>this.constrainPosition()),this.parentElement&&this.boundaryObserver.observe(this.parentElement),this.boundaryObserver.observe(this),this.constrainPosition()}disconnectedCallback(){this.connected=!1,this.dragState=void 0,this.boundaryObserver?.disconnect(),this.removeEventListener("pointermove",this.dragMove),this.removeEventListener("pointerup",this.dragEnd),this.removeEventListener("pointercancel",this.dragCancel),this.removeEventListener("lostpointercapture",this.dragCancel),this.removeEventListener("keydown",this.keyDown),this.removeEventListener("focusin",this.focusIn)}attributeChangedCallback(t){"toolbar-position"===t&&(this.toolbarPosition=this.getAttribute("toolbar-position")||"{}"),this.connected&&this.sync()}sync(){const t=this.items,e=new Set,set=(t,e,i)=>{t.getAttribute(e)!==i&&t.setAttribute(e,i)},r=[];this.hasAttribute("movable")?(this.grip||(this.grip=document.createElement("db-tool-button"),this.grip.setAttribute("tool-id","move-toolbar"),this.grip.setAttribute("label","툴바 이동"),this.grip.setAttribute("shortcut","드래그 / 방향키"),this.grip.setAttribute("icon","grip-vertical"),this.grip.setAttribute("data-toolbar-grip",""),this.grip.addEventListener("db-tool-action",t=>t.stopPropagation()),this.grip.addEventListener("pointerdown",this.dragStart),this.grip.addEventListener("keydown",this.gripKey)),set(this.grip,"tone",i(this.getAttribute("tone"),o,"default")),set(this.grip,"size",i(this.getAttribute("size"),s,"m")),r.push(this.grip)):this.grip?.remove();for(const a of t){if(e.has(a.id))continue;e.add(a.id);let t=this.tools.get(a.id);const h="separator"===a.type;t&&"DB-TOOL-BUTTON"===t.tagName===h&&(t.remove(),this.tools.delete(a.id),t=void 0),t||(t=h?document.createElement("span"):document.createElement("db-tool-button"),this.tools.set(a.id,t)),h?(t.setAttribute("role","separator"),t.className="designbase-wc-design-toolbar__separator"):(set(t,"tool-id",a.id),set(t,"label",a.label||a.id),set(t,"icon",a.icon||""),void 0!==a.text?set(t,"text",a.text):t.removeAttribute("text"),set(t,"shortcut",a.shortcut||""),set(t,"options",JSON.stringify(a.options||[])),set(t,"value",a.value||""),set(t,"menu-trigger",a.menuTrigger||"click"),set(t,"size",i(this.getAttribute("size"),s,"m")),set(t,"tone",i(this.getAttribute("tone"),o,"default")),set(t,"placement",i(this.getAttribute("placement"),n,"bottom-start")),t.toggleAttribute("toggle","boolean"==typeof a.active),t.toggleAttribute("active",!!a.active),t.toggleAttribute("disabled",!!a.disabled)),r.push(t)}for(const[t,i]of this.tools)e.has(t)||(i.remove(),this.tools.delete(t));r.forEach((t,e)=>{this.children[e]!==t&&this.insertBefore(t,this.children[e]||null)}),this.setAttribute("aria-orientation","vertical"===this.getAttribute("orientation")?"vertical":"horizontal"),this.rove(),this.constrainPosition()}buttons(){return Array.from(this.querySelectorAll(":scope > db-tool-button:not([disabled]) db-button"))}rove(){const t=this.buttons(),e=t.find(t=>t.dataset.toolId===this.focusId)||t[0];t.forEach(t=>t.tabIndex=t===e?0:-1)}constrainPosition(t=!1){if(!this.hasAttribute("movable")||!this.parentElement)return;const e=Math.max(0,this.parentElement.clientWidth-this.offsetWidth),i=Math.max(0,this.parentElement.clientHeight-this.offsetHeight),o=Math.min(8,e/2),s=Math.min(8,i/2);this.location={x:Math.max(o,Math.min(e-o,this.location.x)),y:Math.max(s,Math.min(i-s,this.location.y))},this.style.left=`${this.location.x}px`,this.style.top=`${this.location.y}px`,t&&this.dispatchEvent(new CustomEvent("db-position-change",{detail:this.toolbarPosition,bubbles:!0,composed:!0}))}resetPosition(){this.location={x:12,y:12},this.constrainPosition(!0)}closeMenus(){for(const t of this.tools.values())t instanceof e&&t.closeMenu(!1)}}customElements.get("db-design-toolbar")||customElements.define("db-design-toolbar",DbDesignToolbar);export{DbDesignToolbar};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DbElement as e}from"../core/base-element.js";import{createDbIcon as t}from"./db-icons.js";import{deviceMockupStyle as o}from"./device-mockup-style.js";import{MOCKUP_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c={default:[1600,1e3],tablet:[3,4],ios:[1206,2622],android:[1080,2340],watch:[416,496],flip:[1080,2520],"flip-cover":[948,1048],fold:[1968,2184],"fold-cover":[1080,2520],duo:[14,10],"duo-cover":[7,10]};class DbDeviceMockup extends e{constructor(){super(...arguments),this.model="default",this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return["src","alt","url","orientation","variant","screen-title","notch","fold-state","cover-src"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}node(e,t,o){const s=document.createElement(e);return s.className=t,void 0!==o&&(s.textContent=o),s}decorative(e){const t=this.node("span",e);return t.setAttribute("aria-hidden","true"),t}tools(e,o){const s=this.decorative(`tools ${o}`);return e.forEach(e=>s.append(t(e,14))),s}watchBand(e){const t=document.createElementNS("http://www.w3.org/2000/svg","svg");
|
|
1
|
+
import{DbElement as e}from"../core/base-element.js";import{createDbIcon as t}from"./db-icons.js";import{deviceMockupStyle as o}from"./device-mockup-style.js";import{MOCKUP_VARIANTS as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const c={default:[1600,1e3],tablet:[3,4],ios:[1206,2622],android:[1080,2340],watch:[416,496],flip:[1080,2520],"flip-cover":[948,1048],fold:[1968,2184],"fold-cover":[1080,2520],duo:[14,10],"duo-cover":[7,10]};class DbDeviceMockup extends e{constructor(){super(...arguments),this.model="default",this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return["src","alt","url","orientation","variant","screen-title","notch","fold-state","cover-src"]}connectedCallback(){this.render()}attributeChangedCallback(){this.isConnected&&this.render()}node(e,t,o){const s=document.createElement(e);return s.className=t,void 0!==o&&(s.textContent=o),s}decorative(e){const t=this.node("span",e);return t.setAttribute("aria-hidden","true"),t}tools(e,o){const s=this.decorative(`tools ${o}`);return e.forEach(e=>s.append(t(e,14))),s}watchBand(e){const t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("class",`watch-band watch-band--${e}`),t.setAttribute("viewBox","0 0 160 100"),t.setAttribute("preserveAspectRatio","none"),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false");const make=(e,t)=>{const o=document.createElementNS("http://www.w3.org/2000/svg",e);for(const[e,s]of Object.entries(t))o.setAttribute(e,s);return o},o=make("defs",{}),s=make("linearGradient",{id:`band-${e}`,x1:"0",y1:"0",x2:"1",y2:"0"});for(const[e,t]of[["0","#232426"],[".12","#3c3d40"],[".38","#343538"],[".72","#323336"],[".91","#3b3c3f"],["1","#242527"]])s.append(make("stop",{offset:e,"stop-color":t}));const c=make("linearGradient",{id:`band-shade-${e}`,x1:"0",y1:"0",x2:"0",y2:"1"});for(const[e,t,o]of[["0","#fff",".04"],[".5","#fff","0"],["1","#000",".22"]])c.append(make("stop",{offset:e,"stop-color":t,"stop-opacity":o}));o.append(s,c);const i="M28 13 C35 3 125 3 132 13 C139 25 133 57 149 81 L160 100 H0 L11 81 C27 57 21 25 28 13Z";return t.append(o,make("path",{d:i,fill:`url(#band-${e})`}),make("path",{d:i,fill:`url(#band-shade-${e})`})),t}browserChrome(){const e=this.node("div","chrome"),o=this.node("div","tab-strip"),s=this.decorative("dots");for(let e=0;e<3;e++)s.append(document.createElement("i"));const c=this.node("div","tab");c.setAttribute("aria-hidden","true"),c.append(document.createElement("b"),this.node("span","",this.getAttribute("screen-title")||"Preview"),t("close",11)),o.append(s,c);const i=this.node("div","toolbar"),d=this.node("div","url");return d.append(t("lock",11),this.node("span","",this.getAttribute("url")||"example.com")),i.append(this.tools(["chevron-left","chevron-right","refresh"],"tools--left"),d,this.tools(["share-alt","plus","copy"],"tools--right")),e.append(o,i),e}render(){const e=document.createElement("style");e.textContent=o,this.dataset.device=this.device,this.dataset.model=this.model;const t="flip"===this.model||"fold"===this.model||"duo"===this.model,i=t&&"closed"===this.getAttribute("fold-state");this.dataset.foldState=i?"closed":"open",this.dataset.variant=s.find(e=>e===this.getAttribute("variant"))||"realistic";const d=this.getAttribute("notch"),n="ios"===this.model?"island":["android","flip","fold","duo"].includes(this.model)?"punch":"none";this.dataset.notch="watch"===this.device||"browser"===this.device||i&&"flip"===this.model?"none":"none"===d||"island"===d||"punch"===d?d:n;const r=this.node("div","frame");r.part.add("frame"),"browser"===this.device&&r.append(this.browserChrome());const a=this.node("div","screen");a.part.add("screen");const l="tablet"===this.device?"tablet":i?`${this.model}-cover`:this.model,[p,u]=c[l]||c.default,h="landscape"===this.getAttribute("orientation")&&"watch"!==this.device;a.style.aspectRatio=`var(--db-mockup-ratio, ${h?u:p} / ${h?p:u})`;const b=this.node("div","content");b.part.add("content");const m=i&&this.getAttribute("cover-src")||this.getAttribute("src");if(m){const e=document.createElement("img");e.src=m,e.alt=this.getAttribute("alt")||"",e.loading="lazy",b.append(e)}else{const e=document.createElement("slot");i&&this.querySelector('[slot="cover"]')&&(e.name="cover"),b.append(e)}a.append(b),r.append(a),"browser"!==this.device&&("none"!==this.dataset.notch&&r.append(this.decorative("camera")),t&&!i&&a.append(this.decorative("crease")),"flip"===this.model&&i&&a.append(this.decorative("cover-cameras")),"watch"===this.device&&(r.append(this.watchBand("top"),this.watchBand("bottom"),this.decorative("crown")),a.append(this.decorative("watch-glass"))),"duo"===this.model&&r.append(this.decorative("hinge")),r.append(this.decorative("side side--power"),this.decorative("side side--volume"),this.decorative("side side--action"))),this.root.replaceChildren(e,r)}}class DbBrowserMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="browser"}}class DbTabletMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="tablet"}}class DbMobileMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="mobile",this.model="ios"}}class DbIosMockup extends DbMobileMockup{}class DbAndroidMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="android"}}class DbAppleWatchMockup extends DbDeviceMockup{constructor(){super(...arguments),this.device="watch",this.model="watch"}}class DbFlipMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="flip"}}class DbFoldMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="fold"}}class DbDuoMockup extends DbMobileMockup{constructor(){super(...arguments),this.model="duo"}}customElements.get("db-browser-mockup")||customElements.define("db-browser-mockup",DbBrowserMockup),customElements.get("db-tablet-mockup")||customElements.define("db-tablet-mockup",DbTabletMockup),customElements.get("db-mobile-mockup")||customElements.define("db-mobile-mockup",DbMobileMockup),customElements.get("db-ios-mockup")||customElements.define("db-ios-mockup",DbIosMockup),customElements.get("db-android-mockup")||customElements.define("db-android-mockup",DbAndroidMockup),customElements.get("db-apple-watch-mockup")||customElements.define("db-apple-watch-mockup",DbAppleWatchMockup),customElements.get("db-flip-mockup")||customElements.define("db-flip-mockup",DbFlipMockup),customElements.get("db-fold-mockup")||customElements.define("db-fold-mockup",DbFoldMockup),customElements.get("db-duo-mockup")||customElements.define("db-duo-mockup",DbDuoMockup);export{c as DEVICE_MOCKUP_SCREENS,DbAndroidMockup,DbAppleWatchMockup,DbBrowserMockup,DbDuoMockup,DbFlipMockup,DbFoldMockup,DbIosMockup,DbMobileMockup,DbTabletMockup};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DbElement } from '../core/base-element.js';
|
|
2
|
+
import { FLIGHT_STATUSES } from '../ui-contracts/dist/components.d.js';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
type DbFlightStatusValue = typeof STATUSES[number];
|
|
4
|
+
type DbFlightStatusValue = typeof FLIGHT_STATUSES[number];
|
|
5
5
|
/** Display data supplied by the application; does not fetch or simulate live flights. */
|
|
6
6
|
declare class DbFlightStatus extends DbElement {
|
|
7
7
|
static get observedAttributes(): string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t}from"../core/i18n.js";import{DbElement as e}from"../core/base-element.js";import{createDbIcon as s}from"./db-icons.js";import{paperNode as i}from"./paper-card.js";import{flightRoutePosition as r}from"./flight-route.js";
|
|
1
|
+
import{t}from"../core/i18n.js";import{DbElement as e}from"../core/base-element.js";import{createDbIcon as s}from"./db-icons.js";import{paperNode as i}from"./paper-card.js";import{flightRoutePosition as r}from"./flight-route.js";import{FLIGHT_STATUSES as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const n={scheduled:"출발 예정",boarding:"탑승 중","in-flight":"운항 중",landed:"도착",delayed:"지연",cancelled:"취소"};class DbFlightStatus extends e{constructor(){super(...arguments),this.view=i("section","db-flight-status__view"),this.displayedProgress=null,this.animation=0,this.resizeObserver=null,this.motion=null,this.redraw=null,this.onMotionChange=()=>{this.motion?.matches&&(this.stopAnimation(),this.displayedProgress=this.targetProgress,this.redraw?.())}}static get observedAttributes(){return["airline","service-number","origin","origin-name","destination","destination-name","departure-time","arrival-time","terminal","gate","status","detail","progress","label"]}get targetProgress(){return"landed"===this.status?100:"scheduled"===this.status||"cancelled"===this.status?0:this.progress}stopAnimation(){this.animation&&cancelAnimationFrame(this.animation),this.animation=0}disconnectedCallback(){this.stopAnimation(),this.resizeObserver?.disconnect(),this.motion?.removeEventListener("change",this.onMotionChange),this.redraw=null,super.disconnectedCallback()}get progress(){const t=Number(this.getAttribute("progress")||0);return Number.isFinite(t)?Math.min(100,Math.max(0,t)):0}set progress(t){this.setAttribute("progress",String(t))}get status(){return a.find(t=>t===this.getAttribute("status"))||"scheduled"}set status(t){this.setAttribute("status",t)}connectedCallback(){this.classList.add("db-flight-status"),this.upgradeProperties(["progress","status"]),this.view.parentNode||this.prepend(this.view),this.motion=window.matchMedia?.("(prefers-reduced-motion: reduce)")||null,this.motion?.addEventListener("change",this.onMotionChange),this.render()}attributeChangedCallback(){this.isConnected&&this.render()}render(){const attr=t=>this.getAttribute(t)||"";this.dataset.status=this.status,this.view.setAttribute("aria-label",attr("label")||`${attr("origin")} → ${attr("destination")} · ${t("flight.title")}`);const e=i("header","db-flight-status__header");e.append(i("strong","",attr("airline")||attr("service-number")||t("flight.title")),i("span","db-flight-status__status",attr("detail")||t(`flight.${this.status}`,n[this.status])));const a=i("div","db-flight-status__route"),endpoint=t=>{const e=i("div","db-flight-status__endpoint");return e.append(i("strong","",attr(t)||"—")),attr(`${t}-name`)&&e.append(i("span","",attr(`${t}-name`))),e},o=i("div","db-flight-status__track"),d=this.targetProgress;this.stopAnimation(),this.resizeObserver?.disconnect(),o.setAttribute("role","progressbar"),o.setAttribute("aria-label",t("flight.progress")),o.setAttribute("aria-valuemin","0"),o.setAttribute("aria-valuemax","100"),o.setAttribute("aria-valuenow",String(d)),o.setAttribute("aria-valuetext",`${t(`flight.${this.status}`,n[this.status])} · ${d}%`);const l="http://www.w3.org/2000/svg",h=document.createElementNS(l,"svg");h.setAttribute("viewBox","0 0 240 64"),h.setAttribute("preserveAspectRatio","none"),h.setAttribute("aria-hidden","true");for(const t of["db-flight-status__path","db-flight-status__travelled"]){const e=document.createElementNS(l,"path");e.setAttribute("d","M12 46 Q120 -8 228 46"),e.setAttribute("pathLength","100"),e.setAttribute("class",t),t.endsWith("travelled")&&(e.style.strokeDasharray=`${d} 100`),h.append(e)}const u=i("span","db-flight-status__plane");u.setAttribute("aria-hidden","true"),u.append(s("plane",20)),o.append(h,u),a.append(endpoint("origin"),o,endpoint("destination"));const g=i("div","db-flight-status__footer");g.append(i("span","",[attr("service-number"),attr("departure-time")&&`${t("boardingPass.departure")} ${attr("departure-time")}`].filter(Boolean).join(" · ")),i("span","",[attr("arrival-time")&&`${t("boardingPass.arrival")} ${attr("arrival-time")}`,attr("terminal")&&`${t("boardingPass.terminal")} ${attr("terminal")}`,attr("gate")&&`${t("boardingPass.gate")} ${attr("gate")}`].filter(Boolean).join(" · "))),this.view.replaceChildren(e,a,g);const c=h.querySelector(".db-flight-status__travelled");let p=o.clientWidth||240,m=o.clientHeight||58;this.redraw=()=>{const t=this.displayedProgress??d,e=r(t,p,m);u.style.left=`${e.x}px`,u.style.top=`${e.y}px`,u.style.transform=`translate(-50%, -50%) rotate(${e.angle}deg)`,c.style.strokeDasharray=`${t} 100`},"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>{p=o.clientWidth||240,m=o.clientHeight||58,this.redraw?.()}),this.resizeObserver.observe(o));const b=this.displayedProgress;if(null===b||b===d||this.motion?.matches)return this.displayedProgress=d,void this.redraw();this.redraw();let v=null;const animate=t=>{v??(v=t);const e=Math.min(1,(t-v)/1e3);this.displayedProgress=b+(d-b)*(1-Math.pow(1-e,3)),this.redraw?.(),this.animation=e<1?requestAnimationFrame(animate):0};this.animation=requestAnimationFrame(animate)}}customElements.get("db-flight-status")||customElements.define("db-flight-status",DbFlightStatus);export{DbFlightStatus};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbText as e,dbFormat as t,getDbLocale as a}from"../core/i18n.js";import{createDbIcon as s}from"./db-icons.js";import{rafThrottle as r}from"../core/dom.js";const n=["day","week"],i=["#86efac","#fde047","#93c5fd","#c4b5fd","#f9a8d4","#5eead4","#fdba74","#a5b4fc"],d=["일","월","화","수","목","금","토"],o=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];function parseDate(e){const[t,a,s]=e.split("-").map(Number);return new Date(t,a-1,s)}function toDateKey(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function addDays(e,t){const a=new Date(e);return a.setDate(a.getDate()+t),a}function daysBetween(e,t){const a=Date.UTC(e.getFullYear(),e.getMonth(),e.getDate()),s=Date.UTC(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((s-a)/864e5)}function clampDate(e,t,a){return e<t?new Date(t):e>a?new Date(a):e}class DbGantt extends HTMLElement{constructor(){super(...arguments),this.collapsedGroups=new Set,this.dragState=null,this.reorderState=null,this.reorderDropIndex=null,this.suppressRender=!1,this.didDrag=!1,this.handlePointerMove=r(e=>{if(this.reorderState&&e.pointerId===this.reorderState.pointerId)return void this.updateReorderDropTarget(e.clientY);if(!this.dragState||e.pointerId!==this.dragState.pointerId)return;const t=this.getOption("scale",n,"day"),a=this.getNumber("cell-width","week"===t?72:44),{start:s,end:r}=this.getViewRange(),i=Math.round((e.clientX-this.dragState.startX)/a);0!==i&&(this.didDrag=!0);let d=new Date(this.dragState.originalStart),o=new Date(this.dragState.originalEnd);if("move"===this.dragState.mode?(d=addDays(this.dragState.originalStart,i),o=addDays(this.dragState.originalEnd,i)):"resize-start"===this.dragState.mode?(d=addDays(this.dragState.originalStart,i),d>o&&(d=new Date(o))):(o=addDays(this.dragState.originalEnd,i),o<d&&(o=new Date(d))),d=clampDate(d,s,r),o=clampDate(o,s,r),d>o)return;const l=this.items.find(e=>e.id===this.dragState.itemId);l&&this.applyBarGeometry(this.dragState.barEl,{...l,startDate:toDateKey(d),endDate:toDateKey(o)},s,a)}),this.handlePointerUp=e=>{if(this.reorderState&&e.pointerId===this.reorderState.pointerId)return void this.finishReorderDrag(e);if(!this.dragState||e.pointerId!==this.dragState.pointerId)return;const t=this.getOption("scale",n,"day"),a=this.getNumber("cell-width","week"===t?72:44),{start:s,end:r}=this.getViewRange(),i=Math.round((e.clientX-this.dragState.startX)/a);let d=new Date(this.dragState.originalStart),o=new Date(this.dragState.originalEnd);const l=this.dragState.mode,c=this.dragState.itemId;"move"===l?(d=addDays(this.dragState.originalStart,i),o=addDays(this.dragState.originalEnd,i)):"resize-start"===l?(d=addDays(this.dragState.originalStart,i),d>o&&(d=new Date(o))):(o=addDays(this.dragState.originalEnd,i),o<d&&(o=new Date(d))),d=clampDate(d,s,r),o=clampDate(o,s,r),this.dragState.barEl.releasePointerCapture(e.pointerId),this.dragState.barEl.classList.remove("designbase-wc-gantt__bar--dragging"),this.dragState=null;const g=this.items.find(e=>e.id===c);if(!g)return;const p=toDateKey(d),h=toDateKey(o);p===g.startDate&&h===g.endDate||(this.updateItem(c,{startDate:p,endDate:h},"move"===l?"move":"resize"),this.render())}}static get observedAttributes(){return["groups","rows","items","start-date","end-date","today","scale","cell-width","show-weekends","show-today","sidebar-label","full-width","disabled","draggable","reorderable","locale"]}get groups(){return this.parseJson("groups",[])}set groups(e){this.setAttribute("groups","string"==typeof e?e:JSON.stringify(e))}get rows(){return this.parseJson("rows",[])}set rows(e){this.setAttribute("rows","string"==typeof e?e:JSON.stringify(e))}get items(){return this.parseJson("items",[])}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.setAttribute("role","region"),this.setAttribute("aria-label",e("프로젝트 타임라인")),this.addEventListener("pointermove",this.handlePointerMove),this.addEventListener("pointerup",this.handlePointerUp),this.addEventListener("pointercancel",this.handlePointerUp),this.render()}disconnectedCallback(){this.removeEventListener("pointermove",this.handlePointerMove),this.removeEventListener("pointerup",this.handlePointerUp),this.removeEventListener("pointercancel",this.handlePointerUp)}attributeChangedCallback(){!this.isConnected||this.suppressRender||this.dragState||this.reorderState||this.render()}parseJson(e,t){try{return JSON.parse(this.getAttribute(e)||"null")??t}catch{return t}}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const a=this.getAttribute(e);return""===a||"true"===a}getNumber(e,t){const a=Number(this.getAttribute(e));return Number.isFinite(a)&&a>0?a:t}getOption(e,t,a){const s=this.getAttribute(e);return s&&t.includes(s)?s:a}getLocale(){return this.getAttribute("locale")||("ko"===a()?"ko-KR":"en-US")}getWeekdays(){return this.getLocale().startsWith("ko")?d:o}getViewRange(){const e=this.getAttribute("start-date"),t=this.getAttribute("end-date");if(e&&t)return{start:parseDate(e),end:parseDate(t)};const a=this.items.flatMap(e=>[parseDate(e.startDate),parseDate(e.endDate)]);if(0===a.length){const e=new Date,t=new Date(e.getFullYear(),e.getMonth(),1);return{start:t,end:addDays(t,29)}}const s=new Date(Math.min(...a.map(e=>e.getTime()))),r=new Date(Math.max(...a.map(e=>e.getTime())));return{start:addDays(s,-2),end:addDays(r,2)}}getTodayDate(){const e=this.getAttribute("today");return e?parseDate(e):new Date}getDateColumns(e,t){const a=daysBetween(e,t)+1;return Array.from({length:a},(t,a)=>addDays(e,a))}getVisibleRows(){const e=this.groups,t=this.rows;if(0===e.length)return t.map(e=>({type:"row",row:e}));const a=[];for(const s of e)a.push({type:"group",group:s}),this.collapsedGroups.has(s.id)||t.filter(e=>e.groupId===s.id).forEach(e=>a.push({type:"row",row:e}));return t.filter(t=>!t.groupId||!e.some(e=>e.id===t.groupId)).forEach(e=>a.push({type:"row",row:e})),a}getMonthSegments(e){const t=[];let a="",s=0;for(const r of e){const e=`${r.getFullYear()}-${r.getMonth()}`;e!==a?(s>0&&t.push({label:a,span:s}),a=e,s=1):s+=1}return s>0&&t.push({label:a,span:s}),t.map(e=>{const[t,a]=e.label.split("-").map(Number);return{label:new Date(t,a,1).toLocaleDateString(this.getLocale(),{year:"numeric",month:"long"}),span:e.span}})}getInitials(e){return e.initials?e.initials:e.name.split(/\s+/).map(e=>e[0]).join("").slice(0,2).toUpperCase()}updateItem(e,t,a){const s=this.items.map(a=>a.id===e?{...a,...t}:a);this.emitItemsChange(s,a,e)}emitItemsChange(e,t,a){this.suppressRender=!0,this.items=e,this.suppressRender=!1;const s=e.find(e=>e.id===a);this.dispatchEvent(new CustomEvent("db-item-change",{detail:{item:s,items:e,action:t},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{groups:this.groups,rows:this.rows,items:e},bubbles:!0,composed:!0}))}applyBarGeometry(e,t,a,s){const r=parseDate(t.startDate),n=parseDate(t.endDate),i=daysBetween(a,r),d=daysBetween(r,n)+1;e.style.left=i*s+2+"px",e.style.width=`${Math.max(d*s-4,s-4)}px`}startBarDrag(e,t,a,s){!this.getBool("draggable",!0)||this.getBool("disabled")||t.disabled||(e.preventDefault(),e.stopPropagation(),this.didDrag=!1,s.setPointerCapture(e.pointerId),s.classList.add("designbase-wc-gantt__bar--dragging"),this.dragState={itemId:t.id,mode:a,pointerId:e.pointerId,startX:e.clientX,originalStart:parseDate(t.startDate),originalEnd:parseDate(t.endDate),barEl:s})}canReorder(){return this.getBool("reorderable",!0)&&!this.getBool("disabled")}createDragHandle(e,t,a){const r=document.createElement("span");return r.className="designbase-wc-gantt__drag-handle",r.setAttribute("role","button"),r.setAttribute("aria-label","group"===e?"그룹 순서 변경":"행 순서 변경"),r.append(s("grip-vertical",12)),this.canReorder()?(r.addEventListener("pointerdown",s=>{s.preventDefault(),s.stopPropagation(),this.startReorderDrag(s,e,t,a,r)}),r):r}getGroupIndex(e){return this.groups.findIndex(t=>t.id===e)}getRowScope(e){return this.rows.filter(t=>(t.groupId||"")===(e||""))}getRowIndexInScope(e,t){return this.getRowScope(t).findIndex(t=>t.id===e)}getReorderTargets(e,t){return Array.from(this.querySelectorAll("group"===e?".designbase-wc-gantt__label-cell--group":`.designbase-wc-gantt__label-cell--row[data-group-id="${t||""}"]`))}startReorderDrag(e,t,a,s,r){const n="group"===t?this.getGroupIndex(a):this.getRowIndexInScope(a,s);n<0||(r.setPointerCapture(e.pointerId),this.reorderState={kind:t,id:a,groupId:s,pointerId:e.pointerId,startY:e.clientY,fromIndex:n,captureEl:r},this.classList.add("designbase-wc-gantt--reordering"),this.updateReorderDropTarget(e.clientY))}updateReorderDropTarget(e){if(!this.reorderState)return;const t=this.getReorderTargets(this.reorderState.kind,this.reorderState.groupId);let a=null;t.forEach((t,s)=>{const r=t.getBoundingClientRect(),n=r.top+r.height/2,i=e>=r.top&&e<=r.bottom,d=e>n;t.classList.toggle("designbase-wc-gantt__label-cell--drag-over",i),t.classList.toggle("designbase-wc-gantt__label-cell--drag-over-before",i&&!d),t.classList.toggle("designbase-wc-gantt__label-cell--drag-over-after",i&&d),i&&(a=d?s+1:s)}),this.reorderDropIndex=a}clearReorderIndicators(){this.querySelectorAll(".designbase-wc-gantt__label-cell--drag-over").forEach(e=>{e.classList.remove("designbase-wc-gantt__label-cell--drag-over","designbase-wc-gantt__label-cell--drag-over-before","designbase-wc-gantt__label-cell--drag-over-after")})}finishReorderDrag(e){if(!this.reorderState)return;const{kind:t,id:a,groupId:s,fromIndex:r,captureEl:n}=this.reorderState;try{n.releasePointerCapture(this.reorderState.pointerId)}catch{}const i=this.reorderDropIndex;if(this.reorderState=null,this.reorderDropIndex=null,this.classList.remove("designbase-wc-gantt--reordering"),this.clearReorderIndicators(),null===i)return;const d=i>r?i-1:i;d<0||d===r||("group"===t?this.reorderGroups(r,d,a):this.reorderRows(r,d,a,s))}emitStructureChange(e,t,a,s){this.suppressRender=!0,this.groups=e,this.rows=t,this.suppressRender=!1,this.dispatchEvent(new CustomEvent(s,{detail:{...a,groups:e,rows:t},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{groups:e,rows:t,items:this.items},bubbles:!0,composed:!0})),this.render()}reorderGroups(e,t,a){const s=[...this.groups],[r]=s.splice(e,1);r&&(s.splice(t,0,r),this.emitStructureChange(s,this.rows,{groupId:a,fromIndex:e,toIndex:t},"db-group-reorder"))}reorderRows(e,t,a,s){const r=this.getRowScope(s),n=[...r],[i]=n.splice(e,1);if(!i)return;n.splice(t,0,i);const d=new Set(r.map(e=>e.id)),o=[];let l=!1;for(const e of this.rows)d.has(e.id)?l||(o.push(...n),l=!0):o.push(e);l||o.push(...n),this.emitStructureChange(this.groups,o,{rowId:a,groupId:s,fromIndex:e,toIndex:t},"db-row-reorder")}createGroupBadge(e){const t=document.createElement("db-badge");return t.className="designbase-wc-gantt__group-badge",t.setAttribute("type","dot"),t.setAttribute("size","s"),t.setAttribute("variant","primary"),t.setAttribute("aria-hidden","true"),e&&t.style.setProperty("--db-gantt-badge-color",e),t}createGroupChevron(e){const t=document.createElement("span");return t.className=["designbase-wc-gantt__group-chevron",e?"designbase-wc-gantt__group-chevron--collapsed":""].filter(Boolean).join(" "),t.append(s("chevron-down",12)),t}createAssignee(e){const t=document.createElement("span");if(t.className="designbase-wc-gantt__assignee",t.title=e.name,e.avatar){const a=document.createElement("img");a.src=e.avatar,a.alt=e.name,t.appendChild(a)}else t.textContent=this.getInitials(e);return t}createStatusIcon(e){const t=document.createElement("span");return t.className=`designbase-wc-gantt__status designbase-wc-gantt__status--${e}`,t.setAttribute("aria-hidden","true"),t.textContent="completed"===e?"✓":"!",t}deriveSummaryColor(e,t){if(0===e.length)return t||i[0];const a=e.filter(e=>e.color);if(0===a.length)return t||i[0];return a.reduce((e,t)=>{const a=daysBetween(parseDate(e.startDate),parseDate(e.endDate));return daysBetween(parseDate(t.startDate),parseDate(t.endDate))>a?t:e}).color||t||i[0]}getGroupSummary(e,t){const a=this.rows.filter(t=>t.groupId===e),s=this.items.filter(e=>a.some(t=>t.id===e.rowId));if(0===s.length)return null;const r=s.map(e=>parseDate(e.startDate).getTime()),n=s.map(e=>parseDate(e.endDate).getTime()),i=s.map(e=>e.progress).filter(e=>"number"==typeof e);return{startDate:toDateKey(new Date(Math.min(...r))),endDate:toDateKey(new Date(Math.max(...n))),color:this.deriveSummaryColor(s,t),progress:i.length>0?i.reduce((e,t)=>e+t,0)/i.length:0,count:s.length}}applyBarTone(e,t){const a=function deriveBarTone(e){return{base:`color-mix(in srgb, ${e} 42%, white)`,progress:`color-mix(in srgb, ${e} 58%, white)`}}(t);e.style.setProperty("--db-gantt-bar-color",t),e.style.setProperty("--db-gantt-bar-bg",a.base),e.style.setProperty("--db-gantt-bar-progress-bg",a.progress)}createGroupSummaryBar(e,a,s,r){const n=clampDate(parseDate(e.startDate),a,s),i=clampDate(parseDate(e.endDate),a,s);if(i<a||n>s)return null;const d=daysBetween(a,n),o=daysBetween(n,i)+1,l=Math.min(100,Math.max(0,e.progress)),c=document.createElement("div");if(c.className="designbase-wc-gantt__group-summary",c.setAttribute("aria-hidden","true"),c.title=t("{0}개 태스크",[e.count]),this.applyBarTone(c,e.color),c.style.left=d*r+2+"px",c.style.width=`${Math.max(o*r-4,r-4)}px`,l>0){const e=document.createElement("span");e.className="designbase-wc-gantt__group-summary-progress",e.style.width=`${l}%`,c.appendChild(e)}return c}createBar(e,t,a,s){const r=e.color||i[s%i.length],n=document.createElement("div");n.className="designbase-wc-gantt__bar",n.setAttribute("role","button"),n.setAttribute("tabindex",e.disabled?"-1":"0"),n.setAttribute("aria-disabled",String(Boolean(e.disabled)||this.getBool("disabled"))),n.setAttribute("aria-label",`${e.title}, ${e.startDate} – ${e.endDate}`),this.applyBarTone(n,r),e.disabled&&n.classList.add("designbase-wc-gantt__bar--disabled"),this.applyBarGeometry(n,e,t,a);const d="number"==typeof e.progress?Math.min(100,Math.max(0,e.progress)):0;if(d>0){const e=document.createElement("span");e.className="designbase-wc-gantt__bar-progress",e.style.width=`${d}%`,n.appendChild(e)}const o=document.createElement("div");o.className="designbase-wc-gantt__bar-body","delayed"!==e.status&&"at-risk"!==e.status||o.appendChild(this.createStatusIcon(e.status));const l=document.createElement("span");l.className="designbase-wc-gantt__bar-label",l.textContent=e.title,o.appendChild(l),e.assignee&&o.appendChild(this.createAssignee(e.assignee));const c=document.createElement("span");c.className="designbase-wc-gantt__bar-handle designbase-wc-gantt__bar-handle--start",c.setAttribute("aria-hidden","true");const g=document.createElement("span");return g.className="designbase-wc-gantt__bar-handle designbase-wc-gantt__bar-handle--end",g.setAttribute("aria-hidden","true"),n.append(c,o,g),e.disabled||!this.getBool("draggable",!0)||this.getBool("disabled")||(c.addEventListener("pointerdown",t=>this.startBarDrag(t,e,"resize-start",n)),g.addEventListener("pointerdown",t=>this.startBarDrag(t,e,"resize-end",n)),o.addEventListener("pointerdown",t=>{t.target.closest(".designbase-wc-gantt__bar-handle")||this.startBarDrag(t,e,"move",n)})),n.addEventListener("click",t=>{this.dragState||this.didDrag?this.didDrag=!1:(t.stopPropagation(),this.dispatchEvent(new CustomEvent("db-item-click",{detail:{item:e},bubbles:!0,composed:!0})))}),n}toggleGroup(e){this.collapsedGroups.has(e)?this.collapsedGroups.delete(e):this.collapsedGroups.add(e),this.dispatchEvent(new CustomEvent("db-group-toggle",{detail:{groupId:e,collapsed:this.collapsedGroups.has(e)},bubbles:!0,composed:!0})),this.render()}render(){const e=this.items,t=this.getOption("scale",n,"day"),a=this.getNumber("cell-width","week"===t?72:44),s=this.getBool("show-weekends",!0),r=this.getBool("show-today",!0),d=this.getAttribute("sidebar-label")||"할 일",o=this.getBool("disabled"),l=this.getBool("full-width",!0),c=this.getWeekdays(),{start:g,end:p}=this.getViewRange(),h=this.getDateColumns(g,p),u=toDateKey(this.getTodayDate()),m=h.findIndex(e=>toDateKey(e)===u),b=this.getVisibleRows(),w=h.length*a,D=document.createElement("div");D.className=["designbase-wc-gantt",l?"designbase-wc-gantt--full-width":"",o?"designbase-wc-gantt--disabled":"",this.getBool("draggable",!0)?"designbase-wc-gantt--draggable":""].filter(Boolean).join(" ");const y=document.createElement("div");y.className="designbase-wc-gantt__viewport";const _=document.createElement("div");_.className="designbase-wc-gantt__grid",_.style.setProperty("--db-gantt-chart-width",`${w}px`),_.style.setProperty("--db-gantt-cell-width",`${a}px`);const f=document.createElement("div");f.className="designbase-wc-gantt__corner",f.textContent=d,_.appendChild(f);const v=document.createElement("div");v.className="designbase-wc-gantt__date-header";const E=document.createElement("div");E.className="designbase-wc-gantt__month-row";for(const e of this.getMonthSegments(h)){const t=document.createElement("div");t.className="designbase-wc-gantt__month-cell",t.style.width=e.span*a+"px",t.textContent=e.label,E.appendChild(t)}v.appendChild(E);const S=document.createElement("div");S.className="designbase-wc-gantt__day-row";for(const e of h){const t=toDateKey(e)===u,n=0===e.getDay()||6===e.getDay(),i=document.createElement("div");i.className=["designbase-wc-gantt__day-cell",t&&r?"designbase-wc-gantt__day-cell--today":"",n&&s?"designbase-wc-gantt__day-cell--weekend":""].filter(Boolean).join(" "),i.style.width=`${a}px`;const d=document.createElement("span");d.className="designbase-wc-gantt__day-num",d.textContent=String(e.getDate());const o=document.createElement("span");o.className="designbase-wc-gantt__day-name",o.textContent=c[e.getDay()],i.append(d,o),S.appendChild(i)}v.appendChild(S),_.appendChild(v);const C=new Map;e.forEach((e,t)=>{const a=C.get(e.rowId)||[];a.push({...e,color:e.color||i[t%i.length]}),C.set(e.rowId,a)});let I=0;for(const e of b){if("group"===e.type){const{group:t}=e,r=this.collapsedGroups.has(t.id),n=document.createElement("button");n.type="button",n.className="designbase-wc-gantt__label-cell designbase-wc-gantt__label-cell--group",n.setAttribute("aria-expanded",String(!r)),n.dataset.groupId=t.id;const i=document.createElement("span");i.className="designbase-wc-gantt__group-title",i.textContent=t.title,n.append(this.createDragHandle("group",t.id),this.createGroupChevron(r),this.createGroupBadge(t.color),i),n.addEventListener("click",e=>{e.target.closest(".designbase-wc-gantt__drag-handle")||this.toggleGroup(t.id)}),_.appendChild(n);const d=document.createElement("div");if(d.className="designbase-wc-gantt__track-cell designbase-wc-gantt__track-cell--group",r){const e=this.getGroupSummary(t.id,t.color);if(e){const t=document.createElement("div");t.className="designbase-wc-gantt__grid-bg",h.forEach(e=>{const r=document.createElement("div"),n=0===e.getDay()||6===e.getDay();r.className=["designbase-wc-gantt__grid-cell",n&&s?"designbase-wc-gantt__grid-cell--weekend":""].filter(Boolean).join(" "),r.style.width=`${a}px`,t.appendChild(r)}),d.appendChild(t);const r=document.createElement("div");r.className="designbase-wc-gantt__group-summary-wrap";const n=this.createGroupSummaryBar(e,g,p,a);n&&r.appendChild(n),d.appendChild(r)}}_.appendChild(d);continue}const{row:t}=e,r=document.createElement("button");r.type="button",r.className="designbase-wc-gantt__label-cell designbase-wc-gantt__label-cell--row",r.dataset.groupId=t.groupId||"",r.dataset.rowId=t.id;const n=document.createElement("span");n.className="designbase-wc-gantt__row-title",n.textContent=t.label,r.append(this.createDragHandle("row",t.id,t.groupId),n),r.addEventListener("click",e=>{e.target.closest(".designbase-wc-gantt__drag-handle")||this.dispatchEvent(new CustomEvent("db-row-click",{detail:{row:t},bubbles:!0,composed:!0}))}),_.appendChild(r);const i=document.createElement("div");i.className="designbase-wc-gantt__track-cell";const d=document.createElement("div");d.className="designbase-wc-gantt__grid-bg",h.forEach(e=>{const t=document.createElement("div"),r=0===e.getDay()||6===e.getDay();t.className=["designbase-wc-gantt__grid-cell",r&&s?"designbase-wc-gantt__grid-cell--weekend":""].filter(Boolean).join(" "),t.style.width=`${a}px`,d.appendChild(t)}),i.appendChild(d);const o=document.createElement("div");o.className="designbase-wc-gantt__bars",(C.get(t.id)||[]).forEach(e=>{const t=clampDate(parseDate(e.startDate),g,p),s=clampDate(parseDate(e.endDate),g,p);s<g||t>p||o.appendChild(this.createBar({...e,startDate:toDateKey(t),endDate:toDateKey(s)},g,a,I++))}),i.appendChild(o),_.appendChild(i)}if(y.appendChild(_),r&&m>=0){const e=document.createElement("div");e.className="designbase-wc-gantt__today-line",e.style.left=`calc(var(--db-gantt-label-width) + ${m*a+a/2}px)`,_.appendChild(e)}D.appendChild(y),this.replaceChildren(D)}}customElements.get("db-gantt")||customElements.define("db-gantt",DbGantt);export{DbGantt};
|
|
1
|
+
import{dbText as e,getDbLocale as t,dbFormat as a}from"../core/i18n.js";import{createDbIcon as s}from"./db-icons.js";import{rafThrottle as r}from"../core/dom.js";const n=["day","week"],i=["#86efac","#fde047","#93c5fd","#c4b5fd","#f9a8d4","#5eead4","#fdba74","#a5b4fc"],d=["일","월","화","수","목","금","토"],o=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];function parseDate(e){const[t,a,s]=e.split("-").map(Number);return new Date(t,a-1,s)}function toDateKey(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`}function addDays(e,t){const a=new Date(e);return a.setDate(a.getDate()+t),a}function daysBetween(e,t){const a=Date.UTC(e.getFullYear(),e.getMonth(),e.getDate()),s=Date.UTC(t.getFullYear(),t.getMonth(),t.getDate());return Math.round((s-a)/864e5)}function clampDate(e,t,a){return e<t?new Date(t):e>a?new Date(a):e}class DbGantt extends HTMLElement{constructor(){super(...arguments),this.collapsedGroups=new Set,this.dragState=null,this.reorderState=null,this.reorderDropIndex=null,this.suppressRender=!1,this.didDrag=!1,this.handlePointerMove=r(e=>{if(this.reorderState&&e.pointerId===this.reorderState.pointerId)return void this.updateReorderDropTarget(e.clientY);if(!this.dragState||e.pointerId!==this.dragState.pointerId)return;const t=this.getOption("scale",n,"day"),a=this.getNumber("cell-width","week"===t?72:44),{start:s,end:r}=this.getViewRange(),i=Math.round((e.clientX-this.dragState.startX)/a);0!==i&&(this.didDrag=!0);let d=new Date(this.dragState.originalStart),o=new Date(this.dragState.originalEnd);if("move"===this.dragState.mode?(d=addDays(this.dragState.originalStart,i),o=addDays(this.dragState.originalEnd,i)):"resize-start"===this.dragState.mode?(d=addDays(this.dragState.originalStart,i),d>o&&(d=new Date(o))):(o=addDays(this.dragState.originalEnd,i),o<d&&(o=new Date(d))),d=clampDate(d,s,r),o=clampDate(o,s,r),d>o)return;const l=this.items.find(e=>e.id===this.dragState.itemId);l&&this.applyBarGeometry(this.dragState.barEl,{...l,startDate:toDateKey(d),endDate:toDateKey(o)},s,a)}),this.handlePointerUp=e=>{if(this.reorderState&&e.pointerId===this.reorderState.pointerId)return void this.finishReorderDrag(e);if(!this.dragState||e.pointerId!==this.dragState.pointerId)return;const t=this.getOption("scale",n,"day"),a=this.getNumber("cell-width","week"===t?72:44),{start:s,end:r}=this.getViewRange(),i=Math.round((e.clientX-this.dragState.startX)/a);let d=new Date(this.dragState.originalStart),o=new Date(this.dragState.originalEnd);const l=this.dragState.mode,c=this.dragState.itemId;"move"===l?(d=addDays(this.dragState.originalStart,i),o=addDays(this.dragState.originalEnd,i)):"resize-start"===l?(d=addDays(this.dragState.originalStart,i),d>o&&(d=new Date(o))):(o=addDays(this.dragState.originalEnd,i),o<d&&(o=new Date(d))),d=clampDate(d,s,r),o=clampDate(o,s,r),this.dragState.barEl.releasePointerCapture(e.pointerId),this.dragState.barEl.classList.remove("designbase-wc-gantt__bar--dragging"),this.dragState=null;const g=this.items.find(e=>e.id===c);if(!g)return;const p=toDateKey(d),h=toDateKey(o);p===g.startDate&&h===g.endDate||(this.updateItem(c,{startDate:p,endDate:h},"move"===l?"move":"resize"),this.render())}}static get observedAttributes(){return["groups","rows","items","start-date","end-date","today","scale","cell-width","show-weekends","show-today","sidebar-label","full-width","disabled","draggable","reorderable","locale"]}get groups(){return this.parseJson("groups",[])}set groups(e){this.setAttribute("groups","string"==typeof e?e:JSON.stringify(e))}get rows(){return this.parseJson("rows",[])}set rows(e){this.setAttribute("rows","string"==typeof e?e:JSON.stringify(e))}get items(){return this.parseJson("items",[])}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.setAttribute("role","region"),this.setAttribute("aria-label",e("프로젝트 타임라인")),this.addEventListener("pointermove",this.handlePointerMove),this.addEventListener("pointerup",this.handlePointerUp),this.addEventListener("pointercancel",this.handlePointerUp),this.render()}disconnectedCallback(){this.removeEventListener("pointermove",this.handlePointerMove),this.removeEventListener("pointerup",this.handlePointerUp),this.removeEventListener("pointercancel",this.handlePointerUp)}attributeChangedCallback(){!this.isConnected||this.suppressRender||this.dragState||this.reorderState||this.render()}parseJson(e,t){try{return JSON.parse(this.getAttribute(e)||"null")??t}catch{return t}}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const a=this.getAttribute(e);return""===a||"true"===a}getNumber(e,t){const a=Number(this.getAttribute(e));return Number.isFinite(a)&&a>0?a:t}getOption(e,t,a){const s=this.getAttribute(e);return s&&t.includes(s)?s:a}getLocale(){return this.getAttribute("locale")||("ko"===t()?"ko-KR":"en-US")}getWeekdays(){return this.getLocale().startsWith("ko")?d:o}getViewRange(){const e=this.getAttribute("start-date"),t=this.getAttribute("end-date");if(e&&t)return{start:parseDate(e),end:parseDate(t)};const a=this.items.flatMap(e=>[parseDate(e.startDate),parseDate(e.endDate)]);if(0===a.length){const e=new Date,t=new Date(e.getFullYear(),e.getMonth(),1);return{start:t,end:addDays(t,29)}}const s=new Date(Math.min(...a.map(e=>e.getTime()))),r=new Date(Math.max(...a.map(e=>e.getTime())));return{start:addDays(s,-2),end:addDays(r,2)}}getTodayDate(){const e=this.getAttribute("today");return e?parseDate(e):new Date}getDateColumns(e,t){const a=daysBetween(e,t)+1;return Array.from({length:a},(t,a)=>addDays(e,a))}getVisibleRows(){const e=this.groups,t=this.rows;if(0===e.length)return t.map(e=>({type:"row",row:e}));const a=[];for(const s of e)a.push({type:"group",group:s}),this.collapsedGroups.has(s.id)||t.filter(e=>e.groupId===s.id).forEach(e=>a.push({type:"row",row:e}));return t.filter(t=>!t.groupId||!e.some(e=>e.id===t.groupId)).forEach(e=>a.push({type:"row",row:e})),a}getMonthSegments(e){const t=[];let a="",s=0;for(const r of e){const e=`${r.getFullYear()}-${r.getMonth()}`;e!==a?(s>0&&t.push({label:a,span:s}),a=e,s=1):s+=1}return s>0&&t.push({label:a,span:s}),t.map(e=>{const[t,a]=e.label.split("-").map(Number);return{label:new Date(t,a,1).toLocaleDateString(this.getLocale(),{year:"numeric",month:"long"}),span:e.span}})}getInitials(e){return e.initials?e.initials:e.name.split(/\s+/).map(e=>e[0]).join("").slice(0,2).toUpperCase()}updateItem(e,t,a){const s=this.items.map(a=>a.id===e?{...a,...t}:a);this.emitItemsChange(s,a,e)}emitItemsChange(e,t,a){this.suppressRender=!0,this.items=e,this.suppressRender=!1;const s=e.find(e=>e.id===a);this.dispatchEvent(new CustomEvent("db-item-change",{detail:{item:s,items:e,action:t},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{groups:this.groups,rows:this.rows,items:e},bubbles:!0,composed:!0}))}applyBarGeometry(e,t,a,s){const r=parseDate(t.startDate),n=parseDate(t.endDate),i=daysBetween(a,r),d=daysBetween(r,n)+1;e.style.left=i*s+2+"px",e.style.width=`${Math.max(d*s-4,s-4)}px`}startBarDrag(e,t,a,s){!this.getBool("draggable",!0)||this.getBool("disabled")||t.disabled||(e.preventDefault(),e.stopPropagation(),this.didDrag=!1,s.setPointerCapture(e.pointerId),s.classList.add("designbase-wc-gantt__bar--dragging"),this.dragState={itemId:t.id,mode:a,pointerId:e.pointerId,startX:e.clientX,originalStart:parseDate(t.startDate),originalEnd:parseDate(t.endDate),barEl:s})}canReorder(){return this.getBool("reorderable",!0)&&!this.getBool("disabled")}createDragHandle(e,t,a){const r=document.createElement("span");return r.className="designbase-wc-gantt__drag-handle",r.setAttribute("role","button"),r.setAttribute("aria-label","group"===e?"그룹 순서 변경":"행 순서 변경"),r.append(s("grip-vertical",12)),this.canReorder()?(r.addEventListener("pointerdown",s=>{s.preventDefault(),s.stopPropagation(),this.startReorderDrag(s,e,t,a,r)}),r):r}getGroupIndex(e){return this.groups.findIndex(t=>t.id===e)}getRowScope(e){return this.rows.filter(t=>(t.groupId||"")===(e||""))}getRowIndexInScope(e,t){return this.getRowScope(t).findIndex(t=>t.id===e)}getReorderTargets(e,t){return Array.from(this.querySelectorAll("group"===e?".designbase-wc-gantt__label-cell--group":`.designbase-wc-gantt__label-cell--row[data-group-id="${t||""}"]`))}startReorderDrag(e,t,a,s,r){const n="group"===t?this.getGroupIndex(a):this.getRowIndexInScope(a,s);n<0||(r.setPointerCapture(e.pointerId),this.reorderState={kind:t,id:a,groupId:s,pointerId:e.pointerId,startY:e.clientY,fromIndex:n,captureEl:r},this.classList.add("designbase-wc-gantt--reordering"),this.updateReorderDropTarget(e.clientY))}updateReorderDropTarget(e){if(!this.reorderState)return;const t=this.getReorderTargets(this.reorderState.kind,this.reorderState.groupId);let a=null;t.forEach((t,s)=>{const r=t.getBoundingClientRect(),n=r.top+r.height/2,i=e>=r.top&&e<=r.bottom,d=e>n;t.classList.toggle("designbase-wc-gantt__label-cell--drag-over",i),t.classList.toggle("designbase-wc-gantt__label-cell--drag-over-before",i&&!d),t.classList.toggle("designbase-wc-gantt__label-cell--drag-over-after",i&&d),i&&(a=d?s+1:s)}),this.reorderDropIndex=a}clearReorderIndicators(){this.querySelectorAll(".designbase-wc-gantt__label-cell--drag-over").forEach(e=>{e.classList.remove("designbase-wc-gantt__label-cell--drag-over","designbase-wc-gantt__label-cell--drag-over-before","designbase-wc-gantt__label-cell--drag-over-after")})}finishReorderDrag(e){if(!this.reorderState)return;const{kind:t,id:a,groupId:s,fromIndex:r,captureEl:n}=this.reorderState;try{n.releasePointerCapture(this.reorderState.pointerId)}catch{}const i=this.reorderDropIndex;if(this.reorderState=null,this.reorderDropIndex=null,this.classList.remove("designbase-wc-gantt--reordering"),this.clearReorderIndicators(),null===i)return;const d=i>r?i-1:i;d<0||d===r||("group"===t?this.reorderGroups(r,d,a):this.reorderRows(r,d,a,s))}emitStructureChange(e,t,a,s){this.suppressRender=!0,this.groups=e,this.rows=t,this.suppressRender=!1,this.dispatchEvent(new CustomEvent(s,{detail:{...a,groups:e,rows:t},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{groups:e,rows:t,items:this.items},bubbles:!0,composed:!0})),this.render()}reorderGroups(e,t,a){const s=[...this.groups],[r]=s.splice(e,1);r&&(s.splice(t,0,r),this.emitStructureChange(s,this.rows,{groupId:a,fromIndex:e,toIndex:t},"db-group-reorder"))}reorderRows(e,t,a,s){const r=this.getRowScope(s),n=[...r],[i]=n.splice(e,1);if(!i)return;n.splice(t,0,i);const d=new Set(r.map(e=>e.id)),o=[];let l=!1;for(const e of this.rows)d.has(e.id)?l||(o.push(...n),l=!0):o.push(e);l||o.push(...n),this.emitStructureChange(this.groups,o,{rowId:a,groupId:s,fromIndex:e,toIndex:t},"db-row-reorder")}createGroupBadge(e){const t=document.createElement("db-badge");return t.className="designbase-wc-gantt__group-badge",t.setAttribute("type","dot"),t.setAttribute("size","s"),t.setAttribute("variant","primary"),t.setAttribute("aria-hidden","true"),e&&t.style.setProperty("--db-gantt-badge-color",e),t}createGroupChevron(e){const t=document.createElement("span");return t.className=["designbase-wc-gantt__group-chevron",e?"designbase-wc-gantt__group-chevron--collapsed":""].filter(Boolean).join(" "),t.append(s("chevron-down",12)),t}createAssignee(e){const t=document.createElement("span");if(t.className="designbase-wc-gantt__assignee",t.title=e.name,e.avatar){const a=document.createElement("img");a.src=e.avatar,a.alt=e.name,t.appendChild(a)}else t.textContent=this.getInitials(e);return t}createStatusIcon(e){const t=document.createElement("span");return t.className=`designbase-wc-gantt__status designbase-wc-gantt__status--${e}`,t.setAttribute("aria-hidden","true"),t.textContent="completed"===e?"✓":"!",t}deriveSummaryColor(e,t){if(0===e.length)return t||i[0];const a=e.filter(e=>e.color);if(0===a.length)return t||i[0];return a.reduce((e,t)=>{const a=daysBetween(parseDate(e.startDate),parseDate(e.endDate));return daysBetween(parseDate(t.startDate),parseDate(t.endDate))>a?t:e}).color||t||i[0]}getGroupSummary(e,t){const a=this.rows.filter(t=>t.groupId===e),s=this.items.filter(e=>a.some(t=>t.id===e.rowId));if(0===s.length)return null;const r=s.map(e=>parseDate(e.startDate).getTime()),n=s.map(e=>parseDate(e.endDate).getTime()),i=s.map(e=>e.progress).filter(e=>"number"==typeof e);return{startDate:toDateKey(new Date(Math.min(...r))),endDate:toDateKey(new Date(Math.max(...n))),color:this.deriveSummaryColor(s,t),progress:i.length>0?i.reduce((e,t)=>e+t,0)/i.length:0,count:s.length}}applyBarTone(e,t){const a=function deriveBarTone(e){return{base:`color-mix(in srgb, ${e} 42%, white)`,progress:`color-mix(in srgb, ${e} 58%, white)`}}(t);e.style.setProperty("--db-gantt-bar-color",t),e.style.setProperty("--db-gantt-bar-bg",a.base),e.style.setProperty("--db-gantt-bar-progress-bg",a.progress)}createGroupSummaryBar(e,t,s,r){const n=clampDate(parseDate(e.startDate),t,s),i=clampDate(parseDate(e.endDate),t,s);if(i<t||n>s)return null;const d=daysBetween(t,n),o=daysBetween(n,i)+1,l=Math.min(100,Math.max(0,e.progress)),c=document.createElement("div");if(c.className="designbase-wc-gantt__group-summary",c.setAttribute("aria-hidden","true"),c.title=a("{0}개 태스크",[e.count]),this.applyBarTone(c,e.color),c.style.left=d*r+2+"px",c.style.width=`${Math.max(o*r-4,r-4)}px`,l>0){const e=document.createElement("span");e.className="designbase-wc-gantt__group-summary-progress",e.style.width=`${l}%`,c.appendChild(e)}return c}createBar(e,t,a,s){const r=e.color||i[s%i.length],n=document.createElement("div");n.className="designbase-wc-gantt__bar",n.setAttribute("role","button"),n.setAttribute("tabindex",e.disabled?"-1":"0"),n.setAttribute("aria-disabled",String(Boolean(e.disabled)||this.getBool("disabled"))),n.setAttribute("aria-label",`${e.title}, ${e.startDate} – ${e.endDate}`),this.applyBarTone(n,r),e.disabled&&n.classList.add("designbase-wc-gantt__bar--disabled"),this.applyBarGeometry(n,e,t,a);const d="number"==typeof e.progress?Math.min(100,Math.max(0,e.progress)):0;if(d>0){const e=document.createElement("span");e.className="designbase-wc-gantt__bar-progress",e.style.width=`${d}%`,n.appendChild(e)}const o=document.createElement("div");o.className="designbase-wc-gantt__bar-body","delayed"!==e.status&&"at-risk"!==e.status||o.appendChild(this.createStatusIcon(e.status));const l=document.createElement("span");l.className="designbase-wc-gantt__bar-label",l.textContent=e.title,o.appendChild(l),e.assignee&&o.appendChild(this.createAssignee(e.assignee));const c=document.createElement("span");c.className="designbase-wc-gantt__bar-handle designbase-wc-gantt__bar-handle--start",c.setAttribute("aria-hidden","true");const g=document.createElement("span");return g.className="designbase-wc-gantt__bar-handle designbase-wc-gantt__bar-handle--end",g.setAttribute("aria-hidden","true"),n.append(c,o,g),e.disabled||!this.getBool("draggable",!0)||this.getBool("disabled")||(c.addEventListener("pointerdown",t=>this.startBarDrag(t,e,"resize-start",n)),g.addEventListener("pointerdown",t=>this.startBarDrag(t,e,"resize-end",n)),o.addEventListener("pointerdown",t=>{t.target.closest(".designbase-wc-gantt__bar-handle")||this.startBarDrag(t,e,"move",n)})),n.addEventListener("click",t=>{this.dragState||this.didDrag?this.didDrag=!1:(t.stopPropagation(),this.dispatchEvent(new CustomEvent("db-item-click",{detail:{item:e},bubbles:!0,composed:!0})))}),n}toggleGroup(e){this.collapsedGroups.has(e)?this.collapsedGroups.delete(e):this.collapsedGroups.add(e),this.dispatchEvent(new CustomEvent("db-group-toggle",{detail:{groupId:e,collapsed:this.collapsedGroups.has(e)},bubbles:!0,composed:!0})),this.render()}render(){const e=this.items,t=this.getOption("scale",n,"day"),a=this.getNumber("cell-width","week"===t?72:44),s=this.getBool("show-weekends",!0),r=this.getBool("show-today",!0),d=this.getAttribute("sidebar-label")||"할 일",o=this.getBool("disabled"),l=this.getBool("full-width",!0),c=this.getWeekdays(),{start:g,end:p}=this.getViewRange(),h=this.getDateColumns(g,p),u=toDateKey(this.getTodayDate()),m=h.findIndex(e=>toDateKey(e)===u),b=this.getVisibleRows(),w=h.length*a,D=document.createElement("div");D.className=["designbase-wc-gantt",l?"designbase-wc-gantt--full-width":"",o?"designbase-wc-gantt--disabled":"",this.getBool("draggable",!0)?"designbase-wc-gantt--draggable":""].filter(Boolean).join(" ");const y=document.createElement("div");y.className="designbase-wc-gantt__viewport";const _=document.createElement("div");_.className="designbase-wc-gantt__grid",_.style.setProperty("--db-gantt-chart-width",`${w}px`),_.style.setProperty("--db-gantt-cell-width",`${a}px`);const f=document.createElement("div");f.className="designbase-wc-gantt__corner",f.textContent=d,_.appendChild(f);const v=document.createElement("div");v.className="designbase-wc-gantt__date-header";const E=document.createElement("div");E.className="designbase-wc-gantt__month-row";for(const e of this.getMonthSegments(h)){const t=document.createElement("div");t.className="designbase-wc-gantt__month-cell",t.style.width=e.span*a+"px",t.textContent=e.label,E.appendChild(t)}v.appendChild(E);const S=document.createElement("div");S.className="designbase-wc-gantt__day-row";for(const e of h){const t=toDateKey(e)===u,n=0===e.getDay()||6===e.getDay(),i=document.createElement("div");i.className=["designbase-wc-gantt__day-cell",t&&r?"designbase-wc-gantt__day-cell--today":"",n&&s?"designbase-wc-gantt__day-cell--weekend":""].filter(Boolean).join(" "),i.style.width=`${a}px`;const d=document.createElement("span");d.className="designbase-wc-gantt__day-num",d.textContent=String(e.getDate());const o=document.createElement("span");o.className="designbase-wc-gantt__day-name",o.textContent=c[e.getDay()],i.append(d,o),S.appendChild(i)}v.appendChild(S),_.appendChild(v);const C=new Map;e.forEach((e,t)=>{const a=C.get(e.rowId)||[];a.push({...e,color:e.color||i[t%i.length]}),C.set(e.rowId,a)});let I=0;for(const e of b){if("group"===e.type){const{group:t}=e,r=this.collapsedGroups.has(t.id),n=document.createElement("button");n.type="button",n.className="designbase-wc-gantt__label-cell designbase-wc-gantt__label-cell--group",n.setAttribute("aria-expanded",String(!r)),n.dataset.groupId=t.id;const i=document.createElement("span");i.className="designbase-wc-gantt__group-title",i.textContent=t.title,n.append(this.createDragHandle("group",t.id),this.createGroupChevron(r),this.createGroupBadge(t.color),i),n.addEventListener("click",e=>{e.target.closest(".designbase-wc-gantt__drag-handle")||this.toggleGroup(t.id)}),_.appendChild(n);const d=document.createElement("div");if(d.className="designbase-wc-gantt__track-cell designbase-wc-gantt__track-cell--group",r){const e=this.getGroupSummary(t.id,t.color);if(e){const t=document.createElement("div");t.className="designbase-wc-gantt__grid-bg",h.forEach(e=>{const r=document.createElement("div"),n=0===e.getDay()||6===e.getDay();r.className=["designbase-wc-gantt__grid-cell",n&&s?"designbase-wc-gantt__grid-cell--weekend":""].filter(Boolean).join(" "),r.style.width=`${a}px`,t.appendChild(r)}),d.appendChild(t);const r=document.createElement("div");r.className="designbase-wc-gantt__group-summary-wrap";const n=this.createGroupSummaryBar(e,g,p,a);n&&r.appendChild(n),d.appendChild(r)}}_.appendChild(d);continue}const{row:t}=e,r=document.createElement("button");r.type="button",r.className="designbase-wc-gantt__label-cell designbase-wc-gantt__label-cell--row",r.dataset.groupId=t.groupId||"",r.dataset.rowId=t.id;const n=document.createElement("span");n.className="designbase-wc-gantt__row-title",n.textContent=t.label,r.append(this.createDragHandle("row",t.id,t.groupId),n),r.addEventListener("click",e=>{e.target.closest(".designbase-wc-gantt__drag-handle")||this.dispatchEvent(new CustomEvent("db-row-click",{detail:{row:t},bubbles:!0,composed:!0}))}),_.appendChild(r);const i=document.createElement("div");i.className="designbase-wc-gantt__track-cell";const d=document.createElement("div");d.className="designbase-wc-gantt__grid-bg",h.forEach(e=>{const t=document.createElement("div"),r=0===e.getDay()||6===e.getDay();t.className=["designbase-wc-gantt__grid-cell",r&&s?"designbase-wc-gantt__grid-cell--weekend":""].filter(Boolean).join(" "),t.style.width=`${a}px`,d.appendChild(t)}),i.appendChild(d);const o=document.createElement("div");o.className="designbase-wc-gantt__bars",(C.get(t.id)||[]).forEach(e=>{const t=clampDate(parseDate(e.startDate),g,p),s=clampDate(parseDate(e.endDate),g,p);s<g||t>p||o.appendChild(this.createBar({...e,startDate:toDateKey(t),endDate:toDateKey(s)},g,a,I++))}),i.appendChild(o),_.appendChild(i)}if(y.appendChild(_),r&&m>=0){const e=document.createElement("div");e.className="designbase-wc-gantt__today-line",e.style.left=`calc(var(--db-gantt-label-width) + ${m*a+a/2}px)`,_.appendChild(e)}D.appendChild(y),this.replaceChildren(D)}}customElements.get("db-gantt")||customElements.define("db-gantt",DbGantt);export{DbGantt};
|
|
@@ -25,6 +25,7 @@ declare class DbIndicator extends HTMLElement {
|
|
|
25
25
|
set clickable(value: boolean);
|
|
26
26
|
get timer(): boolean;
|
|
27
27
|
set timer(value: boolean);
|
|
28
|
+
private unsubscribeLocale?;
|
|
28
29
|
connectedCallback(): void;
|
|
29
30
|
disconnectedCallback(): void;
|
|
30
31
|
attributeChangedCallback(name: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbFormat as t}from"../core/i18n.js";import{createDbIcon as e}from"./db-icons.js";import{INDICATOR_TYPES as i,INDICATOR_SIZES as s,INDICATOR_DIRECTIONS as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbIndicator extends HTMLElement{constructor(){super(...arguments),this.timerFrame=0,this.progress=0,this.pausedProgress=0,this.activeStep=0,this.isPlayingInternal=!1}static get observedAttributes(){return["total","current","default-current","indicator-type","type","size","direction","number-background","playback","clickable","timer","timer-duration","progress","auto-roll","playing","default-playing","playback-disabled"]}get total(){return Math.max(1,Number(this.getAttribute("total")||1))}set total(t){this.setAttribute("total",String(t))}normalizeStep(t){const e=this.total;return(t%e+e)%e}get isCurrentControlled(){return this.hasAttribute("current")}get isPlayingControlled(){return this.hasAttribute("playing")}get resolvedCurrent(){return this.isCurrentControlled?this.normalizeStep(Number(this.getAttribute("current")||0)):this.activeStep}get resolvedPlaying(){return!!this.isPlayingControlled||this.isPlayingInternal}get indicatorType(){const t=this.getAttribute("indicator-type")||this.getAttribute("type")||"dots";return i.includes(t)?t:"dots"}get size(){const t=this.getAttribute("size")||"m";return s.includes(t)?t:"m"}set size(t){this.setAttribute("size",t)}get direction(){const t=this.getAttribute("direction")||"horizontal";return r.includes(t)?t:"horizontal"}set direction(t){this.setAttribute("direction",t)}get numberBackground(){return this.hasAttribute("number-background")}set numberBackground(t){this.toggleAttribute("number-background",Boolean(t))}get playback(){return this.hasAttribute("playback")}set playback(t){this.toggleAttribute("playback",Boolean(t))}get clickable(){return this.hasAttribute("clickable")}set clickable(t){this.toggleAttribute("clickable",Boolean(t))}get timer(){return this.hasAttribute("timer")}set timer(t){this.toggleAttribute("timer",Boolean(t))}connectedCallback(){this.activeStep=this.normalizeStep(Number(this.getAttribute("default-current")||0)),this.isPlayingInternal=this.hasAttribute("default-playing"),this.resetProgress(),this.render(),this.startTimer()}disconnectedCallback(){cancelAnimationFrame(this.timerFrame)}attributeChangedCallback(t){if(this.isConnected){if("progress"===t)return this.resetProgress(),this.updateTimerVisuals(),void this.startTimer();if("current"===t&&this.isCurrentControlled)return this.resetProgress(),this.render(),void this.startTimer();if("playing"===t)return this.resolvedPlaying||(this.pausedProgress=this.progress),this.syncRootClasses(),this.syncPlaybackButton(),void this.startTimer();if("default-current"===t&&!this.isCurrentControlled)return this.activeStep=this.normalizeStep(Number(this.getAttribute("default-current")||0)),this.resetProgress(),this.render(),void this.startTimer();if("default-playing"===t&&!this.isPlayingControlled)return this.isPlayingInternal=this.hasAttribute("default-playing"),this.syncRootClasses(),this.syncPlaybackButton(),void this.startTimer();if("timer"===t||"timer-duration"===t||"auto-roll"===t)return this.resetProgress(),this.render(),void this.startTimer();this.render(),this.startTimer()}}resetProgress(){this.pausedProgress=0;const t=Number(this.getAttribute("progress")||0);this.progress=Number.isFinite(t)?Math.max(0,Math.min(1,t)):0}emitChange(t){const e={current:t,index:t};this.dispatchEvent(new CustomEvent("db-change",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-current-change",{detail:e,bubbles:!0,composed:!0}))}goToStep(t){const e=this.normalizeStep(t);this.isCurrentControlled||(this.activeStep=e,this.resetProgress(),this.render(),this.startTimer()),this.emitChange(e)}startTimer(){if(cancelAnimationFrame(this.timerFrame),this.hasAttribute("progress")||!this.timer||!this.resolvedPlaying||!this.isConnected)return;const t=Number(this.getAttribute("timer-duration")||3e3),e=Date.now()-this.pausedProgress*t,tick=()=>{const i=Date.now()-e,s=Math.min(i/t,1);this.progress=s,this.pausedProgress=s,this.updateTimerVisuals(),s<1?this.timerFrame=requestAnimationFrame(tick):(this.dispatchEvent(new CustomEvent("db-timer-complete",{detail:{step:this.resolvedCurrent},bubbles:!0,composed:!0})),this.resetProgress(),"false"===this.getAttribute("auto-roll")?this.render():this.goToStep(this.resolvedCurrent+1))};this.timerFrame=requestAnimationFrame(tick)}updateTimerVisuals(){this.querySelectorAll(".designbase-wc-indicator__line-fill, .designbase-wc-indicator__track-fill, .designbase-wc-indicator__dot-line-fill").forEach(t=>{t.style.transform="vertical"===this.direction?`scaleY(${this.progress})`:`scaleX(${this.progress})`});const t=this.querySelector(".designbase-wc-indicator__track-progress");if(t){const e=100*this.fillRatio()+"%";"vertical"===this.direction?t.style.height=e:t.style.width=e}const e=this.querySelector(".designbase-wc-indicator__dot-ring-progress");if(e){const t=15.9155,i=2*Math.PI*t;e.setAttribute("stroke-dashoffset",String(i*(1-this.progress)))}}syncRootClasses(){const t=this.indicatorType;this.className=["designbase-wc-indicator",`designbase-wc-indicator--${t}`,"combined"===t&&"designbase-wc-indicator--dots",`designbase-wc-indicator--${this.size}`,`designbase-wc-indicator--${this.direction}`,this.clickable&&"designbase-wc-indicator--clickable",this.timer&&!this.resolvedPlaying&&"designbase-wc-indicator--paused"].filter(Boolean).join(" ")}syncPlaybackButton(){const t=this.querySelector(".designbase-wc-indicator__playback-button");t&&(t.disabled=this.hasAttribute("playback-disabled"),t.setAttribute("aria-label",this.resolvedPlaying?"일시정지":"재생"),t.replaceChildren(e(this.resolvedPlaying?"pause":"play")))}renderDotRing(){const t=15.9155,e=2*Math.PI*t,i=document.createElement("span");i.className="designbase-wc-indicator__dot-ring",i.setAttribute("aria-hidden","true");const s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("class","designbase-wc-indicator__dot-ring-svg"),s.setAttribute("viewBox","0 0 36 36");const r=document.createElementNS("http://www.w3.org/2000/svg","circle");r.setAttribute("class","designbase-wc-indicator__dot-ring-bg"),r.setAttribute("cx","18"),r.setAttribute("cy","18"),r.setAttribute("r",String(t)),r.setAttribute("fill","none");const n=document.createElementNS("http://www.w3.org/2000/svg","circle");return n.setAttribute("class","designbase-wc-indicator__dot-ring-progress"),n.setAttribute("cx","18"),n.setAttribute("cy","18"),n.setAttribute("r",String(t)),n.setAttribute("fill","none"),n.setAttribute("stroke-dasharray",String(e)),n.setAttribute("stroke-dashoffset",String(e*(1-this.progress))),n.setAttribute("stroke-linecap","round"),s.append(r,n),i.append(s),i}renderStep(e,i,s){const r=e===this.resolvedCurrent,n=this.clickable?document.createElement("button"):document.createElement("span");return n.className=i,this.clickable&&n instanceof HTMLButtonElement?(n.type="button",n.setAttribute("aria-label",t("{0}단계",[e+1])),r&&n.setAttribute("aria-current","step"),n.addEventListener("click",()=>{this.goToStep(e),this.dispatchEvent(new CustomEvent("db-step-click",{detail:{current:e,index:e},bubbles:!0,composed:!0}))})):r||n.setAttribute("aria-hidden","true"),s&&n.append(s),n}renderDots(){const t=document.createDocumentFragment(),e=this.indicatorType,i="combined"===e?"dots":e,s=this.timer,r=this.resolvedPlaying,n=this.resolvedCurrent;this.direction;const a=this.total;if("dots"!==i)return t;for(let e=0;e<a;e+=1){const i=e===n,a=s&&i&&r,o=document.createElement("span");o.className="designbase-wc-indicator__dot-core";const c=document.createDocumentFragment();c.append(o),s&&i&&(a||this.progress>0)&&c.append(this.renderDotRing()),t.append(this.renderStep(e,["designbase-wc-indicator__dot",i&&"designbase-wc-indicator__dot--active"].filter(Boolean).join(" "),c))}return t}renderPlaybackButton(){const t=document.createElement("button");return t.type="button",t.className="designbase-wc-indicator__playback-button",t.disabled=this.hasAttribute("playback-disabled"),t.setAttribute("aria-label",this.resolvedPlaying?"일시정지":"재생"),t.append(e(this.resolvedPlaying?"pause":"play")),t.addEventListener("click",()=>{if(this.hasAttribute("playback-disabled"))return;const t=!this.resolvedPlaying;this.isPlayingControlled?t?this.setAttribute("playing",""):(this.removeAttribute("playing"),this.pausedProgress=this.progress):(this.isPlayingInternal=t,t||(this.pausedProgress=this.progress)),this.syncRootClasses(),this.syncPlaybackButton(),this.startTimer(),this.dispatchEvent(new CustomEvent("db-playing-change",{detail:{playing:t},bubbles:!0,composed:!0}))}),t}renderNumbers(){const t=document.createElement("div");t.className=["designbase-wc-indicator__numbers",this.numberBackground&&"designbase-wc-indicator__numbers--bg"].filter(Boolean).join(" ");const e=document.createElement("span");e.className="designbase-wc-indicator__current",e.textContent=String(this.resolvedCurrent+1);const i=document.createElement("span");i.className="designbase-wc-indicator__separator",i.textContent="/";const s=document.createElement("span");return s.className="designbase-wc-indicator__total",s.textContent=String(this.total),t.append(e,i,s),t}renderSlide(){const t=this.direction,e=this.resolvedCurrent,i=document.createElement("div");i.className="designbase-wc-indicator__track";const s=document.createElement("div");s.className="designbase-wc-indicator__track-thumb";const r=100/this.total;if("vertical"===t?(s.style.height=`${r}%`,s.style.transform=`translateY(${100*e}%)`):(s.style.width=`${r}%`,s.style.transform=`translateX(${100*e}%)`),this.timer&&this.resolvedPlaying){const e=document.createElement("div");e.className="designbase-wc-indicator__track-fill",e.style.transform="vertical"===t?`scaleY(${this.progress})`:`scaleX(${this.progress})`,s.append(e)}return i.append(s),i}renderScaleFill(t){const e=document.createElement("span");return e.className=t,e.style.transform="vertical"===this.direction?`scaleY(${this.progress})`:`scaleX(${this.progress})`,e}renderLine(){const t=document.createDocumentFragment(),e=this.timer,i=this.resolvedPlaying,s=this.resolvedCurrent;for(let r=0;r<this.total;r+=1){const n=r===s,a=e&&n&&i?this.renderScaleFill("designbase-wc-indicator__line-fill"):void 0;t.append(this.renderStep(r,["designbase-wc-indicator__line-segment",n&&!e&&"designbase-wc-indicator__line-segment--active",n&&e&&"designbase-wc-indicator__line-segment--current"].filter(Boolean).join(" "),a))}return t}renderDotLine(){const t=document.createDocumentFragment(),e=this.timer,i=this.resolvedPlaying,s=this.resolvedCurrent;for(let r=0;r<this.total;r+=1){const n=r===s,a=e&&n&&i?this.renderScaleFill("designbase-wc-indicator__dot-line-fill"):void 0;t.append(this.renderStep(r,["designbase-wc-indicator__dot-line-item",n&&!e&&"designbase-wc-indicator__dot-line-item--active",n&&e&&"designbase-wc-indicator__dot-line-item--current"].filter(Boolean).join(" "),a))}return t}fillRatio(){const t=this.resolvedCurrent,e=t/this.total,i=1/this.total;return this.timer&&this.resolvedPlaying?Math.min(e+i*this.progress,1):(t+1)/this.total}renderFill(){const t=document.createElement("div");t.className="designbase-wc-indicator__track";const e=document.createElement("div");e.className="designbase-wc-indicator__track-progress";const i=100*this.fillRatio()+"%";return"vertical"===this.direction?e.style.height=i:e.style.width=i,t.append(e),t}renderContent(){const t="combined"===this.indicatorType?"dots":this.indicatorType;return"numbers"===t?this.renderNumbers():"slide"===t?this.renderSlide():"fill"===t?this.renderFill():"line"===t?this.renderLine():"dot-line"===t?this.renderDotLine():this.renderDots()}render(){const t=this.indicatorType,e=this.resolvedCurrent,i=this.total;this.syncRootClasses(),this.setAttribute("role","progressbar"),this.setAttribute("aria-valuemin","1"),this.setAttribute("aria-valuemax",String(i)),this.setAttribute("aria-valuenow",String(e+1)),this.replaceChildren();if("combined"===t||this.playback){const t=document.createElement("div");return t.className="designbase-wc-indicator__steps",t.append(this.renderContent()),this.append(t,this.renderPlaybackButton()),void this.updateTimerVisuals()}this.append(this.renderContent()),this.updateTimerVisuals()}}customElements.get("db-indicator")||customElements.define("db-indicator",DbIndicator);export{DbIndicator};
|
|
1
|
+
import{subscribeDbLocale as t,t as e,dbFormat as i}from"../core/i18n.js";import{createDbIcon as s}from"./db-icons.js";import{INDICATOR_TYPES as r,INDICATOR_SIZES as n,INDICATOR_DIRECTIONS as a}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbIndicator extends HTMLElement{constructor(){super(...arguments),this.timerFrame=0,this.progress=0,this.pausedProgress=0,this.activeStep=0,this.isPlayingInternal=!1}static get observedAttributes(){return["total","current","default-current","indicator-type","type","size","direction","number-background","playback","clickable","timer","timer-duration","progress","auto-roll","playing","default-playing","playback-disabled"]}get total(){return Math.max(1,Number(this.getAttribute("total")||1))}set total(t){this.setAttribute("total",String(t))}normalizeStep(t){const e=this.total;return(t%e+e)%e}get isCurrentControlled(){return this.hasAttribute("current")}get isPlayingControlled(){return this.hasAttribute("playing")}get resolvedCurrent(){return this.isCurrentControlled?this.normalizeStep(Number(this.getAttribute("current")||0)):this.activeStep}get resolvedPlaying(){return!!this.isPlayingControlled||this.isPlayingInternal}get indicatorType(){const t=this.getAttribute("indicator-type")||this.getAttribute("type")||"dots";return r.includes(t)?t:"dots"}get size(){const t=this.getAttribute("size")||"m";return n.includes(t)?t:"m"}set size(t){this.setAttribute("size",t)}get direction(){const t=this.getAttribute("direction")||"horizontal";return a.includes(t)?t:"horizontal"}set direction(t){this.setAttribute("direction",t)}get numberBackground(){return this.hasAttribute("number-background")}set numberBackground(t){this.toggleAttribute("number-background",Boolean(t))}get playback(){return this.hasAttribute("playback")}set playback(t){this.toggleAttribute("playback",Boolean(t))}get clickable(){return this.hasAttribute("clickable")}set clickable(t){this.toggleAttribute("clickable",Boolean(t))}get timer(){return this.hasAttribute("timer")}set timer(t){this.toggleAttribute("timer",Boolean(t))}connectedCallback(){this.unsubscribeLocale=t(()=>this.syncPlaybackButton()),this.activeStep=this.normalizeStep(Number(this.getAttribute("default-current")||0)),this.isPlayingInternal=this.hasAttribute("default-playing"),this.resetProgress(),this.render(),this.startTimer()}disconnectedCallback(){this.unsubscribeLocale?.(),this.unsubscribeLocale=void 0,cancelAnimationFrame(this.timerFrame)}attributeChangedCallback(t){if(this.isConnected){if("progress"===t)return this.resetProgress(),this.updateTimerVisuals(),void this.startTimer();if("current"===t&&this.isCurrentControlled)return this.resetProgress(),this.render(),void this.startTimer();if("playing"===t)return this.resolvedPlaying||(this.pausedProgress=this.progress),this.syncRootClasses(),this.syncPlaybackButton(),void this.startTimer();if("default-current"===t&&!this.isCurrentControlled)return this.activeStep=this.normalizeStep(Number(this.getAttribute("default-current")||0)),this.resetProgress(),this.render(),void this.startTimer();if("default-playing"===t&&!this.isPlayingControlled)return this.isPlayingInternal=this.hasAttribute("default-playing"),this.syncRootClasses(),this.syncPlaybackButton(),void this.startTimer();if("timer"===t||"timer-duration"===t||"auto-roll"===t)return this.resetProgress(),this.render(),void this.startTimer();this.render(),this.startTimer()}}resetProgress(){this.pausedProgress=0;const t=Number(this.getAttribute("progress")||0);this.progress=Number.isFinite(t)?Math.max(0,Math.min(1,t)):0}emitChange(t){const e={current:t,index:t};this.dispatchEvent(new CustomEvent("db-change",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-current-change",{detail:e,bubbles:!0,composed:!0}))}goToStep(t){const e=this.normalizeStep(t);this.isCurrentControlled||(this.activeStep=e,this.resetProgress(),this.render(),this.startTimer()),this.emitChange(e)}startTimer(){if(cancelAnimationFrame(this.timerFrame),this.hasAttribute("progress")||!this.timer||!this.resolvedPlaying||!this.isConnected)return;const t=Number(this.getAttribute("timer-duration")||3e3),e=Date.now()-this.pausedProgress*t,tick=()=>{const i=Date.now()-e,s=Math.min(i/t,1);this.progress=s,this.pausedProgress=s,this.updateTimerVisuals(),s<1?this.timerFrame=requestAnimationFrame(tick):(this.dispatchEvent(new CustomEvent("db-timer-complete",{detail:{step:this.resolvedCurrent},bubbles:!0,composed:!0})),this.resetProgress(),"false"===this.getAttribute("auto-roll")?this.render():this.goToStep(this.resolvedCurrent+1))};this.timerFrame=requestAnimationFrame(tick)}updateTimerVisuals(){this.querySelectorAll(".designbase-wc-indicator__line-fill, .designbase-wc-indicator__track-fill, .designbase-wc-indicator__dot-line-fill").forEach(t=>{t.style.transform="vertical"===this.direction?`scaleY(${this.progress})`:`scaleX(${this.progress})`});const t=this.querySelector(".designbase-wc-indicator__track-progress");if(t){const e=100*this.fillRatio()+"%";"vertical"===this.direction?t.style.height=e:t.style.width=e}const e=this.querySelector(".designbase-wc-indicator__dot-ring-progress");if(e){const t=15.9155,i=2*Math.PI*t;e.setAttribute("stroke-dashoffset",String(i*(1-this.progress)))}}syncRootClasses(){const t=this.indicatorType;this.className=["designbase-wc-indicator",`designbase-wc-indicator--${t}`,"combined"===t&&"designbase-wc-indicator--dots",`designbase-wc-indicator--${this.size}`,`designbase-wc-indicator--${this.direction}`,this.clickable&&"designbase-wc-indicator--clickable",this.timer&&!this.resolvedPlaying&&"designbase-wc-indicator--paused"].filter(Boolean).join(" ")}syncPlaybackButton(){const t=this.querySelector(".designbase-wc-indicator__playback-button");t&&(t.disabled=this.hasAttribute("playback-disabled"),t.setAttribute("aria-label",e(this.resolvedPlaying?"media.pause":"media.play")),t.replaceChildren(s(this.resolvedPlaying?"pause":"play")))}renderDotRing(){const t=15.9155,e=2*Math.PI*t,i=document.createElement("span");i.className="designbase-wc-indicator__dot-ring",i.setAttribute("aria-hidden","true");const s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("class","designbase-wc-indicator__dot-ring-svg"),s.setAttribute("viewBox","0 0 36 36");const r=document.createElementNS("http://www.w3.org/2000/svg","circle");r.setAttribute("class","designbase-wc-indicator__dot-ring-bg"),r.setAttribute("cx","18"),r.setAttribute("cy","18"),r.setAttribute("r",String(t)),r.setAttribute("fill","none");const n=document.createElementNS("http://www.w3.org/2000/svg","circle");return n.setAttribute("class","designbase-wc-indicator__dot-ring-progress"),n.setAttribute("cx","18"),n.setAttribute("cy","18"),n.setAttribute("r",String(t)),n.setAttribute("fill","none"),n.setAttribute("stroke-dasharray",String(e)),n.setAttribute("stroke-dashoffset",String(e*(1-this.progress))),n.setAttribute("stroke-linecap","round"),s.append(r,n),i.append(s),i}renderStep(t,e,s){const r=t===this.resolvedCurrent,n=this.clickable?document.createElement("button"):document.createElement("span");return n.className=e,this.clickable&&n instanceof HTMLButtonElement?(n.type="button",n.setAttribute("aria-label",i("{0}단계",[t+1])),r&&n.setAttribute("aria-current","step"),n.addEventListener("click",()=>{this.goToStep(t),this.dispatchEvent(new CustomEvent("db-step-click",{detail:{current:t,index:t},bubbles:!0,composed:!0}))})):r||n.setAttribute("aria-hidden","true"),s&&n.append(s),n}renderDots(){const t=document.createDocumentFragment(),e=this.indicatorType,i="combined"===e?"dots":e,s=this.timer,r=this.resolvedPlaying,n=this.resolvedCurrent;this.direction;const a=this.total;if("dots"!==i)return t;for(let e=0;e<a;e+=1){const i=e===n,a=s&&i&&r,o=document.createElement("span");o.className="designbase-wc-indicator__dot-core";const c=document.createDocumentFragment();c.append(o),s&&i&&(a||this.progress>0)&&c.append(this.renderDotRing()),t.append(this.renderStep(e,["designbase-wc-indicator__dot",i&&"designbase-wc-indicator__dot--active"].filter(Boolean).join(" "),c))}return t}renderPlaybackButton(){const t=document.createElement("button");return t.type="button",t.className="designbase-wc-indicator__playback-button",t.disabled=this.hasAttribute("playback-disabled"),t.setAttribute("aria-label",e(this.resolvedPlaying?"media.pause":"media.play")),t.append(s(this.resolvedPlaying?"pause":"play")),t.addEventListener("click",()=>{if(this.hasAttribute("playback-disabled"))return;const t=!this.resolvedPlaying;this.isPlayingControlled?t?this.setAttribute("playing",""):(this.removeAttribute("playing"),this.pausedProgress=this.progress):(this.isPlayingInternal=t,t||(this.pausedProgress=this.progress)),this.syncRootClasses(),this.syncPlaybackButton(),this.startTimer(),this.dispatchEvent(new CustomEvent("db-playing-change",{detail:{playing:t},bubbles:!0,composed:!0}))}),t}renderNumbers(){const t=document.createElement("div");t.className=["designbase-wc-indicator__numbers",this.numberBackground&&"designbase-wc-indicator__numbers--bg"].filter(Boolean).join(" ");const e=document.createElement("span");e.className="designbase-wc-indicator__current",e.textContent=String(this.resolvedCurrent+1);const i=document.createElement("span");i.className="designbase-wc-indicator__separator",i.textContent="/";const s=document.createElement("span");return s.className="designbase-wc-indicator__total",s.textContent=String(this.total),t.append(e,i,s),t}renderSlide(){const t=this.direction,e=this.resolvedCurrent,i=document.createElement("div");i.className="designbase-wc-indicator__track";const s=document.createElement("div");s.className="designbase-wc-indicator__track-thumb";const r=100/this.total;if("vertical"===t?(s.style.height=`${r}%`,s.style.transform=`translateY(${100*e}%)`):(s.style.width=`${r}%`,s.style.transform=`translateX(${100*e}%)`),this.timer&&this.resolvedPlaying){const e=document.createElement("div");e.className="designbase-wc-indicator__track-fill",e.style.transform="vertical"===t?`scaleY(${this.progress})`:`scaleX(${this.progress})`,s.append(e)}return i.append(s),i}renderScaleFill(t){const e=document.createElement("span");return e.className=t,e.style.transform="vertical"===this.direction?`scaleY(${this.progress})`:`scaleX(${this.progress})`,e}renderLine(){const t=document.createDocumentFragment(),e=this.timer,i=this.resolvedPlaying,s=this.resolvedCurrent;for(let r=0;r<this.total;r+=1){const n=r===s,a=e&&n&&i?this.renderScaleFill("designbase-wc-indicator__line-fill"):void 0;t.append(this.renderStep(r,["designbase-wc-indicator__line-segment",n&&!e&&"designbase-wc-indicator__line-segment--active",n&&e&&"designbase-wc-indicator__line-segment--current"].filter(Boolean).join(" "),a))}return t}renderDotLine(){const t=document.createDocumentFragment(),e=this.timer,i=this.resolvedPlaying,s=this.resolvedCurrent;for(let r=0;r<this.total;r+=1){const n=r===s,a=e&&n&&i?this.renderScaleFill("designbase-wc-indicator__dot-line-fill"):void 0;t.append(this.renderStep(r,["designbase-wc-indicator__dot-line-item",n&&!e&&"designbase-wc-indicator__dot-line-item--active",n&&e&&"designbase-wc-indicator__dot-line-item--current"].filter(Boolean).join(" "),a))}return t}fillRatio(){const t=this.resolvedCurrent,e=t/this.total,i=1/this.total;return this.timer&&this.resolvedPlaying?Math.min(e+i*this.progress,1):(t+1)/this.total}renderFill(){const t=document.createElement("div");t.className="designbase-wc-indicator__track";const e=document.createElement("div");e.className="designbase-wc-indicator__track-progress";const i=100*this.fillRatio()+"%";return"vertical"===this.direction?e.style.height=i:e.style.width=i,t.append(e),t}renderContent(){const t="combined"===this.indicatorType?"dots":this.indicatorType;return"numbers"===t?this.renderNumbers():"slide"===t?this.renderSlide():"fill"===t?this.renderFill():"line"===t?this.renderLine():"dot-line"===t?this.renderDotLine():this.renderDots()}render(){const t=this.indicatorType,e=this.resolvedCurrent,i=this.total;this.syncRootClasses(),this.setAttribute("role","progressbar"),this.setAttribute("aria-valuemin","1"),this.setAttribute("aria-valuemax",String(i)),this.setAttribute("aria-valuenow",String(e+1)),this.replaceChildren();if("combined"===t||this.playback){const t=document.createElement("div");return t.className="designbase-wc-indicator__steps",t.append(this.renderContent()),this.append(t,this.renderPlaybackButton()),void this.updateTimerVisuals()}this.append(this.renderContent()),this.updateTimerVisuals()}}customElements.get("db-indicator")||customElements.define("db-indicator",DbIndicator);export{DbIndicator};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbText as e,dbFormat as t,getDbLocale as a}from"../core/i18n.js";import{createDbIcon as n}from"./db-icons.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{KANBAN_SIZES as d}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const r=d,i=["low","medium","high","urgent"],o={low:"낮음",medium:"보통",high:"높음",urgent:"긴급"};class DbKanban extends HTMLElement{constructor(){super(...arguments),this.dragState=null,this.dropTarget=null,this.handleBoardDragOver=e=>{if(!this.dragState)return;const t=e.target;t instanceof Element&&(t.closest(".designbase-wc-kanban__card")||t.closest(".designbase-wc-kanban__column-body"))||(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"))},this.handleBoardDrop=e=>{if(!this.dragState)return;const t=e.target;t instanceof Element&&(t.closest(".designbase-wc-kanban__card")||t.closest(".designbase-wc-kanban__column-body"))||(e.preventDefault(),this.commitDrop())}}static get observedAttributes(){return["columns","size","disabled","draggable","show-column-count","show-add-card","allow-cross-column","full-width","empty-column-text"]}get columns(){try{const e=JSON.parse(this.getAttribute("columns")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set columns(e){this.setAttribute("columns","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.setAttribute("role","region"),this.setAttribute("aria-label",e("칸반 보드")),this.addEventListener("dragover",this.handleBoardDragOver),this.addEventListener("drop",this.handleBoardDrop),this.render()}disconnectedCallback(){this.removeEventListener("dragover",this.handleBoardDragOver),this.removeEventListener("drop",this.handleBoardDrop)}attributeChangedCallback(){this.isConnected&&this.render()}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const a=this.getAttribute(e);return""===a||"true"===a}emitChange(e){this.columns=e,this.dispatchEvent(new CustomEvent("db-change",{detail:{columns:e},bubbles:!0,composed:!0}))}emitCardMove(e,t){this.columns=e,this.dispatchEvent(new CustomEvent("db-card-move",{detail:{...t,columns:e},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{columns:e},bubbles:!0,composed:!0}))}findCardLocation(e){for(const t of this.columns){const a=t.cards.findIndex(t=>t.id===e);if(a>=0)return{columnId:t.id,index:a}}return null}getAdjustedDropIndex(e,t){if(!this.dragState)return-1;const{columnId:a,cardIndex:n}=this.dragState;return a===e&&t>n?t-1:t}isValidDropTarget(e=this.dropTarget){if(!this.dragState||!e)return!1;const t=this.getAdjustedDropIndex(e.columnId,e.index);return!(t<0)&&(this.dragState.columnId!==e.columnId||t!==this.dragState.cardIndex)}moveCard(e,t,a){const n=this.findCardLocation(e);if(!n)return;const s=this.columns.map(e=>({...e,cards:[...e.cards]})),d=s.find(e=>e.id===n.columnId),r=s.find(e=>e.id===t);if(!d||!r)return;const[i]=d.cards.splice(n.index,1);if(!i)return;const o=this.getAdjustedDropIndex(t,a);r.cards.splice(Math.max(0,o),0,i),this.emitCardMove(s,{cardId:e,fromColumnId:n.columnId,toColumnId:t,fromIndex:n.index,toIndex:Math.max(0,o)})}setDropTarget(e){const t=e&&this.isValidDropTarget(e)?e:null;(this.dropTarget?`${this.dropTarget.columnId}:${this.dropTarget.index}`:"")!==(t?`${t.columnId}:${t.index}`:"")&&(this.dropTarget=t,this.updateDragClasses())}resetDragState(){this.dragState=null,this.dropTarget=null,this.classList.remove("designbase-wc-kanban--dragging"),this.updateDragClasses()}updateDragClasses(){const e=!!this.dragState;this.classList.toggle("designbase-wc-kanban--dragging",e),this.querySelectorAll(".designbase-wc-kanban__card").forEach(t=>{const a=t.dataset.cardId||"",n=e&&this.dragState?.cardId===a;t.classList.toggle("designbase-wc-kanban__card--dragged",n)}),this.querySelectorAll(".designbase-wc-kanban__column-body").forEach(e=>{const t=e.dataset.columnId||"",a=!!this.dropTarget&&this.dropTarget.columnId===t;e.classList.toggle("designbase-wc-kanban__column-body--drag-over",a)}),this.querySelectorAll(".designbase-wc-kanban__card").forEach(e=>{const t=e.dataset.columnId||"",a=Number(e.dataset.cardIndex||-1),n=!!this.dropTarget&&this.dropTarget.columnId===t&&this.dropTarget.index===a,s=this.columns.find(e=>e.id===t),d=!!this.dropTarget&&this.dropTarget.columnId===t&&s&&this.dropTarget.index===s.cards.length&&a===s.cards.length-1;e.classList.toggle("designbase-wc-kanban__card--drop-before",n),e.classList.toggle("designbase-wc-kanban__card--drop-after",d)})}getDropIndexFromPointer(e,t,a){const n=t.getBoundingClientRect();return e.clientY-n.top<n.height/2?a:a+1}getDropIndexFromColumnPointer(e,t){const a=Array.from(this.querySelectorAll(`.designbase-wc-kanban__column-body[data-column-id="${t}"] > .designbase-wc-kanban__card`));if(0===a.length)return 0;for(let t=0;t<a.length;t+=1){const n=a[t].getBoundingClientRect();if(e.clientY<n.top+n.height/2)return t}return a.length}commitDrop(){if(!this.dragState||!this.dropTarget||!this.isValidDropTarget())return void this.resetDragState();const{cardId:e}=this.dragState,{columnId:t,index:a}=this.dropTarget;this.resetDragState(),this.moveCard(e,t,a),this.render()}formatDueDate(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString("ko"===a()?"ko-KR":"en-US",{month:"short",day:"numeric"})}getInitials(e){return e.initials?e.initials:e.name.split(/\s+/).map(e=>e.charAt(0)).join("").slice(0,2).toUpperCase()}createTag(e){const t=document.createElement("span");return t.className=["designbase-wc-kanban__tag",e.variant&&`designbase-wc-kanban__tag--${e.variant}`].filter(Boolean).join(" "),t.textContent=e.label,t}createPriorityBadge(e){const a=document.createElement("span");return a.className=`designbase-wc-kanban__priority designbase-wc-kanban__priority--${e}`,a.textContent=o[e],a.setAttribute("aria-label",t("우선순위 {0}",[o[e]])),a}createAssignee(e){const t=document.createElement("div");if(t.className="designbase-wc-kanban__assignee",t.title=e.name,e.avatar){const a=document.createElement("img");a.className="designbase-wc-kanban__assignee-avatar",a.src=e.avatar,a.alt=e.name,t.append(a)}else{const a=document.createElement("span");a.className="designbase-wc-kanban__assignee-initials",a.textContent=this.getInitials(e),t.append(a)}const a=document.createElement("span");return a.className="designbase-wc-kanban__assignee-name",a.textContent=e.name,t.append(a),t}bindCardDrag(e,t,a,n,s,d){e.draggable=s&&!d&&!t.disabled,e.addEventListener("dragstart",e=>{!s||d||t.disabled||(this.dragState={cardId:t.id,columnId:a,cardIndex:n},this.dropTarget=null,e.dataTransfer&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",t.id)),this.classList.add("designbase-wc-kanban--dragging"),this.updateDragClasses())}),e.addEventListener("dragover",t=>{if(!this.dragState)return;t.preventDefault(),t.stopPropagation(),t.dataTransfer&&(t.dataTransfer.dropEffect="move");if(!this.getBool("allow-cross-column",!0)&&this.dragState.columnId!==a)return;const s=this.getDropIndexFromPointer(t,e,n);this.setDropTarget({columnId:a,index:s})}),e.addEventListener("dragleave",t=>{const a=e.getBoundingClientRect(),n=t.clientX-a.left,s=t.clientY-a.top;(n<0||n>a.width||s<0||s>a.height)&&this.setDropTarget(null)}),e.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.commitDrop()}),e.addEventListener("dragend",()=>{this.resetDragState(),this.render()})}createCard(e,t,a,s){const d=document.createElement("article");d.className=["designbase-wc-kanban__card",e.disabled&&"designbase-wc-kanban__card--disabled",e.priority&&`designbase-wc-kanban__card--priority-${e.priority}`].filter(Boolean).join(" "),d.dataset.cardId=e.id,d.dataset.columnId=t,d.dataset.cardIndex=String(a),d.setAttribute("role","listitem"),d.tabIndex=e.disabled?-1:0;const r=document.createElement("div");r.className="designbase-wc-kanban__card-title-row";const o=document.createElement("h4");if(o.className="designbase-wc-kanban__card-title",o.textContent=e.title,r.append(o),e.priority&&i.includes(e.priority)&&r.append(this.createPriorityBadge(e.priority)),d.append(r),e.description){const t=document.createElement("p");t.className="designbase-wc-kanban__card-description",t.textContent=e.description,d.append(t)}if(e.tags?.length){const t=document.createElement("div");t.className="designbase-wc-kanban__card-tags",e.tags.forEach(e=>t.append(this.createTag(e))),d.append(t)}const c=document.createElement("div");if(c.className="designbase-wc-kanban__card-footer",e.assignee&&c.append(this.createAssignee(e.assignee)),e.dueDate){const t=document.createElement("span");t.className="designbase-wc-kanban__due-date",t.append(n("calendar","l"===s.size?12:"m"===s.size?11:10));const a=document.createElement("span");a.textContent=this.formatDueDate(e.dueDate),t.append(a),c.append(t)}return c.childNodes.length>0&&d.append(c),d.addEventListener("click",a=>{s.disabled||this.dispatchEvent(new CustomEvent("db-card-click",{detail:{card:e,columnId:t},bubbles:!0,composed:!0}))}),d.addEventListener("keydown",a=>{"Enter"!==a.key&&" "!==a.key||(a.preventDefault(),this.dispatchEvent(new CustomEvent("db-card-click",{detail:{card:e,columnId:t},bubbles:!0,composed:!0})))}),this.bindCardDrag(d,e,t,a,s.draggable,s.disabled),d}createColumn(t,a){const s=document.createElement("section"),d=void 0!==t.limit&&t.cards.length>t.limit;s.className=["designbase-wc-kanban__column",d&&"designbase-wc-kanban__column--over-limit"].filter(Boolean).join(" "),s.dataset.columnId=t.id,s.setAttribute("role","group"),s.setAttribute("aria-label",t.title);const r=document.createElement("header");r.className="designbase-wc-kanban__column-header";const i=document.createElement("div");if(i.className="designbase-wc-kanban__column-title-wrap",t.color){const e=document.createElement("span");e.className="designbase-wc-kanban__column-color",e.style.backgroundColor=t.color,e.setAttribute("aria-hidden","true"),i.append(e)}const o=document.createElement("h3");if(o.className="designbase-wc-kanban__column-title",o.textContent=t.title,i.append(o),r.append(i),a.showColumnCount){const e=document.createElement("span");e.className="designbase-wc-kanban__column-count",e.textContent=void 0!==t.limit?`${t.cards.length}/${t.limit}`:String(t.cards.length),r.append(e)}s.append(r);const c=document.createElement("div");if(c.className="designbase-wc-kanban__column-body",c.dataset.columnId=t.id,c.setAttribute("role","list"),c.addEventListener("dragover",e=>{if(!this.dragState)return;e.preventDefault(),e.stopPropagation(),e.dataTransfer&&(e.dataTransfer.dropEffect="move");if(!this.getBool("allow-cross-column",!0)&&this.dragState.columnId!==t.id)return;const a=this.getDropIndexFromColumnPointer(e,t.id);this.setDropTarget({columnId:t.id,index:a})}),c.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.commitDrop()}),0===t.cards.length){const e=document.createElement("div");e.className="designbase-wc-kanban__column-empty",e.textContent=a.emptyColumnText,c.append(e)}else t.cards.forEach((e,n)=>{c.append(this.createCard(e,t.id,n,{size:a.size,draggable:a.draggable,disabled:a.disabled}))});if(s.append(c),a.showAddCard&&!a.disabled){const d=document.createElement("button");d.type="button",d.className="designbase-wc-kanban__add-card",d.append(n("plus","l"===a.size?14:"m"===a.size?12:10));const r=document.createElement("span");r.textContent=e("카드 추가"),d.append(r),d.disabled=this.getBool("disabled"),d.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-add-card",{detail:{columnId:t.id},bubbles:!0,composed:!0}))}),s.append(d)}return s}render(){const e=s(this.getAttribute("size"),r,"s"),t=this.getBool("disabled"),a=this.getBool("draggable",!0),n=this.getBool("show-column-count",!0),d=this.getBool("show-add-card"),i=this.getAttribute("empty-column-text")||"카드가 없습니다";this.className=["designbase-wc-kanban",`designbase-wc-kanban--${e}`,this.getBool("full-width")&&"designbase-wc-kanban--full-width",t&&"designbase-wc-kanban--disabled",this.classList.contains("designbase-wc-kanban--dragging")&&"designbase-wc-kanban--dragging"].filter(Boolean).join(" ");const o=document.createElement("div");o.className="designbase-wc-kanban__board";const c=document.createDocumentFragment();this.columns.forEach(s=>{c.append(this.createColumn(s,{size:e,draggable:a,showColumnCount:n,showAddCard:d,emptyColumnText:i,disabled:t}))}),o.append(c),this.replaceChildren(o),this.updateDragClasses()}}customElements.get("db-kanban")||customElements.define("db-kanban",DbKanban);export{DbKanban};
|
|
1
|
+
import{dbText as e,getDbLocale as t,dbFormat as a}from"../core/i18n.js";import{createDbIcon as n}from"./db-icons.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{KANBAN_SIZES as d}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const r=d,i=["low","medium","high","urgent"],o={low:"낮음",medium:"보통",high:"높음",urgent:"긴급"};class DbKanban extends HTMLElement{constructor(){super(...arguments),this.dragState=null,this.dropTarget=null,this.handleBoardDragOver=e=>{if(!this.dragState)return;const t=e.target;t instanceof Element&&(t.closest(".designbase-wc-kanban__card")||t.closest(".designbase-wc-kanban__column-body"))||(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move"))},this.handleBoardDrop=e=>{if(!this.dragState)return;const t=e.target;t instanceof Element&&(t.closest(".designbase-wc-kanban__card")||t.closest(".designbase-wc-kanban__column-body"))||(e.preventDefault(),this.commitDrop())}}static get observedAttributes(){return["columns","size","disabled","draggable","show-column-count","show-add-card","allow-cross-column","full-width","empty-column-text"]}get columns(){try{const e=JSON.parse(this.getAttribute("columns")||"[]");return Array.isArray(e)?e:[]}catch{return[]}}set columns(e){this.setAttribute("columns","string"==typeof e?e:JSON.stringify(e))}connectedCallback(){this.setAttribute("role","region"),this.setAttribute("aria-label",e("칸반 보드")),this.addEventListener("dragover",this.handleBoardDragOver),this.addEventListener("drop",this.handleBoardDrop),this.render()}disconnectedCallback(){this.removeEventListener("dragover",this.handleBoardDragOver),this.removeEventListener("drop",this.handleBoardDrop)}attributeChangedCallback(){this.isConnected&&this.render()}getBool(e,t=!1){if(!this.hasAttribute(e))return t;const a=this.getAttribute(e);return""===a||"true"===a}emitChange(e){this.columns=e,this.dispatchEvent(new CustomEvent("db-change",{detail:{columns:e},bubbles:!0,composed:!0}))}emitCardMove(e,t){this.columns=e,this.dispatchEvent(new CustomEvent("db-card-move",{detail:{...t,columns:e},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{columns:e},bubbles:!0,composed:!0}))}findCardLocation(e){for(const t of this.columns){const a=t.cards.findIndex(t=>t.id===e);if(a>=0)return{columnId:t.id,index:a}}return null}getAdjustedDropIndex(e,t){if(!this.dragState)return-1;const{columnId:a,cardIndex:n}=this.dragState;return a===e&&t>n?t-1:t}isValidDropTarget(e=this.dropTarget){if(!this.dragState||!e)return!1;const t=this.getAdjustedDropIndex(e.columnId,e.index);return!(t<0)&&(this.dragState.columnId!==e.columnId||t!==this.dragState.cardIndex)}moveCard(e,t,a){const n=this.findCardLocation(e);if(!n)return;const s=this.columns.map(e=>({...e,cards:[...e.cards]})),d=s.find(e=>e.id===n.columnId),r=s.find(e=>e.id===t);if(!d||!r)return;const[i]=d.cards.splice(n.index,1);if(!i)return;const o=this.getAdjustedDropIndex(t,a);r.cards.splice(Math.max(0,o),0,i),this.emitCardMove(s,{cardId:e,fromColumnId:n.columnId,toColumnId:t,fromIndex:n.index,toIndex:Math.max(0,o)})}setDropTarget(e){const t=e&&this.isValidDropTarget(e)?e:null;(this.dropTarget?`${this.dropTarget.columnId}:${this.dropTarget.index}`:"")!==(t?`${t.columnId}:${t.index}`:"")&&(this.dropTarget=t,this.updateDragClasses())}resetDragState(){this.dragState=null,this.dropTarget=null,this.classList.remove("designbase-wc-kanban--dragging"),this.updateDragClasses()}updateDragClasses(){const e=!!this.dragState;this.classList.toggle("designbase-wc-kanban--dragging",e),this.querySelectorAll(".designbase-wc-kanban__card").forEach(t=>{const a=t.dataset.cardId||"",n=e&&this.dragState?.cardId===a;t.classList.toggle("designbase-wc-kanban__card--dragged",n)}),this.querySelectorAll(".designbase-wc-kanban__column-body").forEach(e=>{const t=e.dataset.columnId||"",a=!!this.dropTarget&&this.dropTarget.columnId===t;e.classList.toggle("designbase-wc-kanban__column-body--drag-over",a)}),this.querySelectorAll(".designbase-wc-kanban__card").forEach(e=>{const t=e.dataset.columnId||"",a=Number(e.dataset.cardIndex||-1),n=!!this.dropTarget&&this.dropTarget.columnId===t&&this.dropTarget.index===a,s=this.columns.find(e=>e.id===t),d=!!this.dropTarget&&this.dropTarget.columnId===t&&s&&this.dropTarget.index===s.cards.length&&a===s.cards.length-1;e.classList.toggle("designbase-wc-kanban__card--drop-before",n),e.classList.toggle("designbase-wc-kanban__card--drop-after",d)})}getDropIndexFromPointer(e,t,a){const n=t.getBoundingClientRect();return e.clientY-n.top<n.height/2?a:a+1}getDropIndexFromColumnPointer(e,t){const a=Array.from(this.querySelectorAll(`.designbase-wc-kanban__column-body[data-column-id="${t}"] > .designbase-wc-kanban__card`));if(0===a.length)return 0;for(let t=0;t<a.length;t+=1){const n=a[t].getBoundingClientRect();if(e.clientY<n.top+n.height/2)return t}return a.length}commitDrop(){if(!this.dragState||!this.dropTarget||!this.isValidDropTarget())return void this.resetDragState();const{cardId:e}=this.dragState,{columnId:t,index:a}=this.dropTarget;this.resetDragState(),this.moveCard(e,t,a),this.render()}formatDueDate(e){const a=new Date(e);return Number.isNaN(a.getTime())?e:a.toLocaleDateString("ko"===t()?"ko-KR":"en-US",{month:"short",day:"numeric"})}getInitials(e){return e.initials?e.initials:e.name.split(/\s+/).map(e=>e.charAt(0)).join("").slice(0,2).toUpperCase()}createTag(e){const t=document.createElement("span");return t.className=["designbase-wc-kanban__tag",e.variant&&`designbase-wc-kanban__tag--${e.variant}`].filter(Boolean).join(" "),t.textContent=e.label,t}createPriorityBadge(e){const t=document.createElement("span");return t.className=`designbase-wc-kanban__priority designbase-wc-kanban__priority--${e}`,t.textContent=o[e],t.setAttribute("aria-label",a("우선순위 {0}",[o[e]])),t}createAssignee(e){const t=document.createElement("div");if(t.className="designbase-wc-kanban__assignee",t.title=e.name,e.avatar){const a=document.createElement("img");a.className="designbase-wc-kanban__assignee-avatar",a.src=e.avatar,a.alt=e.name,t.append(a)}else{const a=document.createElement("span");a.className="designbase-wc-kanban__assignee-initials",a.textContent=this.getInitials(e),t.append(a)}const a=document.createElement("span");return a.className="designbase-wc-kanban__assignee-name",a.textContent=e.name,t.append(a),t}bindCardDrag(e,t,a,n,s,d){e.draggable=s&&!d&&!t.disabled,e.addEventListener("dragstart",e=>{!s||d||t.disabled||(this.dragState={cardId:t.id,columnId:a,cardIndex:n},this.dropTarget=null,e.dataTransfer&&(e.dataTransfer.effectAllowed="move",e.dataTransfer.setData("text/plain",t.id)),this.classList.add("designbase-wc-kanban--dragging"),this.updateDragClasses())}),e.addEventListener("dragover",t=>{if(!this.dragState)return;t.preventDefault(),t.stopPropagation(),t.dataTransfer&&(t.dataTransfer.dropEffect="move");if(!this.getBool("allow-cross-column",!0)&&this.dragState.columnId!==a)return;const s=this.getDropIndexFromPointer(t,e,n);this.setDropTarget({columnId:a,index:s})}),e.addEventListener("dragleave",t=>{const a=e.getBoundingClientRect(),n=t.clientX-a.left,s=t.clientY-a.top;(n<0||n>a.width||s<0||s>a.height)&&this.setDropTarget(null)}),e.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.commitDrop()}),e.addEventListener("dragend",()=>{this.resetDragState(),this.render()})}createCard(e,t,a,s){const d=document.createElement("article");d.className=["designbase-wc-kanban__card",e.disabled&&"designbase-wc-kanban__card--disabled",e.priority&&`designbase-wc-kanban__card--priority-${e.priority}`].filter(Boolean).join(" "),d.dataset.cardId=e.id,d.dataset.columnId=t,d.dataset.cardIndex=String(a),d.setAttribute("role","listitem"),d.tabIndex=e.disabled?-1:0;const r=document.createElement("div");r.className="designbase-wc-kanban__card-title-row";const o=document.createElement("h4");if(o.className="designbase-wc-kanban__card-title",o.textContent=e.title,r.append(o),e.priority&&i.includes(e.priority)&&r.append(this.createPriorityBadge(e.priority)),d.append(r),e.description){const t=document.createElement("p");t.className="designbase-wc-kanban__card-description",t.textContent=e.description,d.append(t)}if(e.tags?.length){const t=document.createElement("div");t.className="designbase-wc-kanban__card-tags",e.tags.forEach(e=>t.append(this.createTag(e))),d.append(t)}const c=document.createElement("div");if(c.className="designbase-wc-kanban__card-footer",e.assignee&&c.append(this.createAssignee(e.assignee)),e.dueDate){const t=document.createElement("span");t.className="designbase-wc-kanban__due-date",t.append(n("calendar","l"===s.size?12:"m"===s.size?11:10));const a=document.createElement("span");a.textContent=this.formatDueDate(e.dueDate),t.append(a),c.append(t)}return c.childNodes.length>0&&d.append(c),d.addEventListener("click",a=>{s.disabled||this.dispatchEvent(new CustomEvent("db-card-click",{detail:{card:e,columnId:t},bubbles:!0,composed:!0}))}),d.addEventListener("keydown",a=>{"Enter"!==a.key&&" "!==a.key||(a.preventDefault(),this.dispatchEvent(new CustomEvent("db-card-click",{detail:{card:e,columnId:t},bubbles:!0,composed:!0})))}),this.bindCardDrag(d,e,t,a,s.draggable,s.disabled),d}createColumn(t,a){const s=document.createElement("section"),d=void 0!==t.limit&&t.cards.length>t.limit;s.className=["designbase-wc-kanban__column",d&&"designbase-wc-kanban__column--over-limit"].filter(Boolean).join(" "),s.dataset.columnId=t.id,s.setAttribute("role","group"),s.setAttribute("aria-label",t.title);const r=document.createElement("header");r.className="designbase-wc-kanban__column-header";const i=document.createElement("div");if(i.className="designbase-wc-kanban__column-title-wrap",t.color){const e=document.createElement("span");e.className="designbase-wc-kanban__column-color",e.style.backgroundColor=t.color,e.setAttribute("aria-hidden","true"),i.append(e)}const o=document.createElement("h3");if(o.className="designbase-wc-kanban__column-title",o.textContent=t.title,i.append(o),r.append(i),a.showColumnCount){const e=document.createElement("span");e.className="designbase-wc-kanban__column-count",e.textContent=void 0!==t.limit?`${t.cards.length}/${t.limit}`:String(t.cards.length),r.append(e)}s.append(r);const c=document.createElement("div");if(c.className="designbase-wc-kanban__column-body",c.dataset.columnId=t.id,c.setAttribute("role","list"),c.addEventListener("dragover",e=>{if(!this.dragState)return;e.preventDefault(),e.stopPropagation(),e.dataTransfer&&(e.dataTransfer.dropEffect="move");if(!this.getBool("allow-cross-column",!0)&&this.dragState.columnId!==t.id)return;const a=this.getDropIndexFromColumnPointer(e,t.id);this.setDropTarget({columnId:t.id,index:a})}),c.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.commitDrop()}),0===t.cards.length){const e=document.createElement("div");e.className="designbase-wc-kanban__column-empty",e.textContent=a.emptyColumnText,c.append(e)}else t.cards.forEach((e,n)=>{c.append(this.createCard(e,t.id,n,{size:a.size,draggable:a.draggable,disabled:a.disabled}))});if(s.append(c),a.showAddCard&&!a.disabled){const d=document.createElement("button");d.type="button",d.className="designbase-wc-kanban__add-card",d.append(n("plus","l"===a.size?14:"m"===a.size?12:10));const r=document.createElement("span");r.textContent=e("카드 추가"),d.append(r),d.disabled=this.getBool("disabled"),d.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-add-card",{detail:{columnId:t.id},bubbles:!0,composed:!0}))}),s.append(d)}return s}render(){const e=s(this.getAttribute("size"),r,"s"),t=this.getBool("disabled"),a=this.getBool("draggable",!0),n=this.getBool("show-column-count",!0),d=this.getBool("show-add-card"),i=this.getAttribute("empty-column-text")||"카드가 없습니다";this.className=["designbase-wc-kanban",`designbase-wc-kanban--${e}`,this.getBool("full-width")&&"designbase-wc-kanban--full-width",t&&"designbase-wc-kanban--disabled",this.classList.contains("designbase-wc-kanban--dragging")&&"designbase-wc-kanban--dragging"].filter(Boolean).join(" ");const o=document.createElement("div");o.className="designbase-wc-kanban__board";const c=document.createDocumentFragment();this.columns.forEach(s=>{c.append(this.createColumn(s,{size:e,draggable:a,showColumnCount:n,showAddCard:d,emptyColumnText:i,disabled:t}))}),o.append(c),this.replaceChildren(o),this.updateDragClasses()}}customElements.get("db-kanban")||customElements.define("db-kanban",DbKanban);export{DbKanban};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { DbElement } from '../core/base-element.js';
|
|
2
2
|
import './db-badge.js';
|
|
3
3
|
|
|
4
|
-
declare const NODE_VARIANTS: readonly ["default", "compact"];
|
|
5
|
-
declare const NODE_STATUSES: readonly ["idle", "running", "success", "error"];
|
|
6
4
|
type DbNodePortType = 'any' | 'text' | 'image' | 'number' | 'boolean';
|
|
7
5
|
type DbNodePort = {
|
|
8
6
|
id: string;
|
|
@@ -79,5 +77,5 @@ declare global {
|
|
|
79
77
|
}
|
|
80
78
|
}
|
|
81
79
|
|
|
82
|
-
export { DbNode
|
|
80
|
+
export { DbNode };
|
|
83
81
|
export type { DbNodeMove, DbNodePort, DbNodePortDrag, DbNodePortSelect, DbNodePortType };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbFormat as t,dbText as e}from"../core/i18n.js";import{DbElement as i}from"../core/base-element.js";import{createDbIcon as s}from"./db-icons.js";import"./db-badge.js";import{nodeStyle as n}from"./node-style.js";const o=["default","compact"],r=["idle","running","success","error"],a=new Set(["any","text","image","number","boolean"]),typeLabels=()=>({any:e("일반"),text:e("텍스트"),image:e("이미지"),number:e("숫자"),boolean:e("조건")}),d={idle:"대기",running:"실행 중",success:"완료",error:"오류"};class DbNode extends i{constructor(){super(...arguments),this.root=this.attachShadow({mode:"open"}),this.inputPorts=[],this.outputPorts=[],this.portsDirty=!0,this.drag=null,this.portDrag=null,this.suppressPortClick=!1}static get observedAttributes(){return["node-id","heading","description","icon","variant","status","selected","collapsed","disabled","movable","runnable","collapsible","inputs","outputs","detail","deletable"]}get inputs(){return this.inputPorts.map(t=>({...t}))}set inputs(t){const e=this.normalizePorts(t);JSON.stringify(e)!==JSON.stringify(this.inputPorts)&&(this.inputPorts=e,this.portsDirty=!0,this.sync())}get outputs(){return this.outputPorts.map(t=>({...t}))}set outputs(t){const e=this.normalizePorts(t);JSON.stringify(e)!==JSON.stringify(this.outputPorts)&&(this.outputPorts=e,this.portsDirty=!0,this.sync())}getPortElement(t,e){const i="input"===e?this.inputList:this.outputList;return[...i?.querySelectorAll("button")||[]].find(e=>e.dataset.portId===t)||null}connectedCallback(){this.root.childElementCount||this.build(),this.upgradeProperties(["inputs","outputs"]);for(const t of["inputs","outputs"])this.hasAttribute(t)&&this.readPorts(t);this.sync()}disconnectedCallback(){this.finishDrag("end"),this.cancelPortDrag(),super.disconnectedCallback()}attributeChangedCallback(t){"inputs"!==t&&"outputs"!==t||this.readPorts(t),"disabled"===t&&this.hasAttribute("disabled")&&(this.finishDrag("end"),this.cancelPortDrag()),this.sync()}normalizePorts(t){if(!Array.isArray(t))return[];const e=new Set;return t.filter(t=>t&&"string"==typeof t.id&&t.id&&"string"==typeof t.label&&!e.has(t.id)&&e.add(t.id)).map(t=>({id:t.id,label:t.label,type:a.has(t.type)?t.type:"any",connected:!!t.connected,disabled:!!t.disabled}))}readPorts(t){let e=[];try{e=JSON.parse(this.getAttribute(t)||"[]")}catch{}"inputs"===t?this.inputPorts=this.normalizePorts(e):this.outputPorts=this.normalizePorts(e),this.portsDirty=!0}nodeId(){return this.getAttribute("node-id")||this.id}el(t,e){const i=document.createElement(t);return i.className=e,i}action(t,e){const i=this.el("button","action");return i.type="button",i.setAttribute("aria-label",t),i.title=t,i.append(s(e,16)),i}build(){const t=document.createElement("style");t.textContent=n;const e=this.el("article","frame");e.part.add("frame");const i=this.el("header","header");i.part.add("header"),this.headingButton=this.el("button","heading"),this.headingButton.type="button",this.iconBox=this.el("span","icon"),this.iconBox.setAttribute("aria-hidden","true"),this.titleEl=this.el("span","title"),this.headingButton.append(this.iconBox,this.titleEl),this.statusEl=this.el("span","status"),this.statusEl.setAttribute("role","status"),this.statusBadge=document.createElement("db-badge"),this.statusBadge.setAttribute("size","s"),this.statusBadge.setAttribute("type","outlined"),this.statusEl.append(this.statusBadge);const s=this.el("div","actions"),o=document.createElement("slot");o.name="actions",this.runButton=this.action("노드 실행","play-outline"),this.runButton.classList.add("action--run"),this.collapseButton=this.action("노드 접기","chevron-up"),this.deleteButton=this.action("노드 삭제","close"),this.deleteButton.addEventListener("click",()=>this.dbEmit("delete",{nodeId:this.nodeId()},{cancelable:!0})),s.append(o,this.runButton,this.collapseButton,this.deleteButton),i.append(this.headingButton,this.statusEl,s),this.descriptionEl=this.el("p","description"),this.inputList=this.el("div","ports ports--input"),this.inputList.part.add("inputs"),this.outputList=this.el("div","ports ports--output"),this.outputList.part.add("outputs"),this.body=this.el("div","body"),this.body.part.add("body"),this.body.append(document.createElement("slot")),this.footer=this.el("footer","footer");const r=document.createElement("slot");r.name="footer",this.footer.append(r);this.root.addEventListener("slotchange",()=>{this.body.hidden=this.hasAttribute("collapsed")||!this.body.querySelector("slot").assignedNodes({flatten:!0}).some(t=>1===t.nodeType||!!t.textContent?.trim()),this.footer.hidden=this.hasAttribute("collapsed")||!r.assignedNodes({flatten:!0}).length}),e.append(i,this.descriptionEl,this.inputList,this.body,this.outputList,this.footer),this.root.append(t,e);const isEditor=t=>t.composedPath().some(t=>t instanceof HTMLElement&&(t.isContentEditable||t.matches("input, textarea, db-input, db-textarea, db-markdown-editor")));this.addEventListener("selectstart",t=>{isEditor(t)||t.preventDefault()}),this.addEventListener("dragstart",t=>{isEditor(t)||t.preventDefault()}),this.headingButton.addEventListener("click",()=>{this.hasAttribute("disabled")||this.dbEmit("select",{nodeId:this.nodeId()})}),this.collapseButton.addEventListener("click",()=>{const t=!this.hasAttribute("collapsed");this.toggleAttribute("collapsed",t),this.dbEmit("collapse",{nodeId:this.nodeId(),collapsed:t})}),this.runButton.addEventListener("click",()=>this.dbEmit("run",{nodeId:this.nodeId()},{cancelable:!0})),this.headingButton.addEventListener("pointerdown",t=>{this.hasAttribute("movable")&&!this.hasAttribute("disabled")&&0===t.button&&(this.drag={id:t.pointerId,x:t.clientX,y:t.clientY,lastX:t.clientX,lastY:t.clientY},this.headingButton.setPointerCapture(t.pointerId),this.emitMove("start",0,0))}),this.headingButton.addEventListener("pointermove",t=>{this.drag?.id===t.pointerId&&(this.drag.lastX=t.clientX,this.drag.lastY=t.clientY,this.emitMove("move",t.clientX-this.drag.x,t.clientY-this.drag.y))}),this.headingButton.addEventListener("pointerup",t=>{this.drag?.id===t.pointerId&&(this.drag.lastX=t.clientX,this.drag.lastY=t.clientY,this.finishDrag("end"))}),this.headingButton.addEventListener("pointercancel",()=>this.finishDrag("end")),this.headingButton.addEventListener("lostpointercapture",()=>this.finishDrag("end")),this.headingButton.addEventListener("keydown",t=>{if("Escape"===t.key&&this.drag)return void this.finishDrag("cancel");if(!this.hasAttribute("movable")||this.hasAttribute("disabled"))return;const e={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]};if(e[t.key]){t.preventDefault();const[i,s]=e[t.key],n=t.shiftKey?4:16;this.emitMove("keyboard",i*n,s*n)}})}emitMove(t,e,i){this.dbEmit("move",{nodeId:this.nodeId(),deltaX:e,deltaY:i,phase:t})}finishDrag(t){const e=this.drag;e&&(this.drag=null,this.emitMove(t,"cancel"===t?0:e.lastX-e.x,"cancel"===t?0:e.lastY-e.y),this.headingButton.hasPointerCapture(e.id)&&this.headingButton.releasePointerCapture(e.id))}renderPorts(i,s,n){const o=this.root.activeElement,r=o&&i.contains(o)?o.dataset.portId:void 0;this.cancelPortDrag(),i.replaceChildren(),i.hidden=!s.length;for(const o of s){const s=this.el("div","port-row");s.dataset.type=o.type||"any";const r=this.el("button","port");r.type="button",r.part.add("port"),r.dataset.portId=o.id,r.dataset.direction=n,r.disabled=this.hasAttribute("disabled")||!!o.disabled,r.dataset.connected=String(!!o.connected),r.setAttribute("aria-label",t("{0} · {1} · {2}",[e("input"===n?"입력":"출력"),o.label,typeLabels()[o.type||"any"]])),r.setAttribute("aria-pressed",String(!!o.connected));const a=this.el("span","port-dot");r.append(a);const d=this.el("span","port-label");d.textContent=o.label;const h=this.el("span","port-type");h.textContent=typeLabels()[o.type||"any"];const l={nodeId:this.nodeId(),portId:o.id,direction:n,type:o.type||"any"};r.addEventListener("click",()=>{this.suppressPortClick||this.dbEmit("port-select",l)}),r.addEventListener("pointerdown",t=>{0!==t.button||r.disabled||(this.portDrag={id:t.pointerId,button:r,port:l,x:t.clientX,y:t.clientY,moved:!1},this.suppressPortClick=!1,r.setPointerCapture(t.pointerId))}),r.addEventListener("pointermove",t=>{const e=this.portDrag;e&&e.id===t.pointerId&&(!e.moved&&Math.hypot(t.clientX-e.x,t.clientY-e.y)>=4&&(e.moved=!0,this.suppressPortClick=!0,this.emitPortDrag("start",e.x,e.y)),e.moved&&this.emitPortDrag("move",t.clientX,t.clientY))}),r.addEventListener("pointerup",t=>{this.portDrag?.id===t.pointerId&&(this.portDrag.moved&&this.emitPortDrag("end",t.clientX,t.clientY),this.portDrag=null,r.hasPointerCapture(t.pointerId)&&r.releasePointerCapture(t.pointerId),setTimeout(()=>{this.suppressPortClick=!1},0))}),r.addEventListener("pointercancel",()=>this.cancelPortDrag()),r.addEventListener("lostpointercapture",()=>this.cancelPortDrag()),r.addEventListener("keydown",t=>{"Escape"===t.key&&this.cancelPortDrag()}),s.append(r,d,h),i.append(s)}r&&this.getPortElement(r,n)?.focus({preventScroll:!0})}emitPortDrag(t,e,i){this.portDrag&&this.dbEmit("port-drag",{...this.portDrag.port,phase:t,clientX:e,clientY:i})}cancelPortDrag(){const t=this.portDrag;t&&(t.moved&&this.emitPortDrag("cancel",t.x,t.y),this.portDrag=null,t.button.hasPointerCapture(t.id)&&t.button.releasePointerCapture(t.id))}sync(){if(!this.headingButton)return;const t=this.hasAttribute("disabled"),e=this.hasAttribute("collapsed");this.setAttribute("aria-disabled",String(t)),this.root.querySelector(".frame").inert=t,this.dataset.variant=o.includes(this.getAttribute("variant"))?this.getAttribute("variant"):"default";const i=r.find(t=>t===this.getAttribute("status"))||"idle";this.dataset.status=i,this.titleEl.textContent=this.getAttribute("heading")||"새 노드",this.headingButton.disabled=t,this.headingButton.setAttribute("aria-pressed",String(this.hasAttribute("selected"))),this.headingButton.title=this.hasAttribute("movable")?"드래그 또는 방향키로 이동":"노드 선택";const n=this.getAttribute("icon");if(this.iconBox.hidden=!n,n?this.iconBox.replaceChildren(s(n,16)):this.iconBox.replaceChildren(),this.descriptionEl.textContent=this.getAttribute("description")||"",this.descriptionEl.hidden=e||!this.descriptionEl.textContent,this.statusBadge.textContent=d[i],this.statusBadge.setAttribute("variant","error"===i?"danger":"success"===i?"success":"info"),this.statusEl.hidden="idle"===i,this.collapseButton.hidden=!this.hasAttribute("collapsible"),this.collapseButton.disabled=t,this.collapseButton.setAttribute("aria-expanded",String(!e)),this.collapseButton.setAttribute("aria-label",e?"노드 펼치기":"노드 접기"),this.collapseButton.title=e?"노드 펼치기":"노드 접기",this.collapseButton.replaceChildren(s(e?"chevron-down":"chevron-up",16)),this.deleteButton.hidden=!this.hasAttribute("deletable"),this.deleteButton.disabled=t,this.runButton.hidden=!this.hasAttribute("runnable"),this.runButton.disabled=t||"running"===i,this.body.hidden=e||!this.body.querySelector("slot").assignedNodes({flatten:!0}).some(t=>1===t.nodeType||!!t.textContent?.trim()),this.footer.hidden=e||!this.footer.querySelector("slot").assignedNodes({flatten:!0}).length,this.portsDirty)this.renderPorts(this.inputList,this.inputPorts,"input"),this.renderPorts(this.outputList,this.outputPorts,"output"),this.portsDirty=!1;else for(const e of[this.inputList,this.outputList])for(const i of e.querySelectorAll("button")){const s=e===this.inputList?this.inputPorts:this.outputPorts;i.disabled=t||!!s.find(t=>t.id===i.dataset.portId)?.disabled}}}customElements.get("db-node")||customElements.define("db-node",DbNode);export{DbNode,r as NODE_STATUSES,o as NODE_VARIANTS};
|
|
1
|
+
import{dbFormat as t,dbText as e}from"../core/i18n.js";import{DbElement as i}from"../core/base-element.js";import{createDbIcon as s}from"./db-icons.js";import"./db-badge.js";import{nodeStyle as n}from"./node-style.js";import{NODE_VARIANTS as o,NODE_STATUSES as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const a=new Set(["any","text","image","number","boolean"]),typeLabels=()=>({any:e("일반"),text:e("텍스트"),image:e("이미지"),number:e("숫자"),boolean:e("조건")}),d={idle:"대기",running:"실행 중",success:"완료",error:"오류"};class DbNode extends i{constructor(){super(...arguments),this.root=this.attachShadow({mode:"open"}),this.inputPorts=[],this.outputPorts=[],this.portsDirty=!0,this.drag=null,this.portDrag=null,this.suppressPortClick=!1}static get observedAttributes(){return["node-id","heading","description","icon","variant","status","selected","collapsed","disabled","movable","runnable","collapsible","inputs","outputs","detail","deletable"]}get inputs(){return this.inputPorts.map(t=>({...t}))}set inputs(t){const e=this.normalizePorts(t);JSON.stringify(e)!==JSON.stringify(this.inputPorts)&&(this.inputPorts=e,this.portsDirty=!0,this.sync())}get outputs(){return this.outputPorts.map(t=>({...t}))}set outputs(t){const e=this.normalizePorts(t);JSON.stringify(e)!==JSON.stringify(this.outputPorts)&&(this.outputPorts=e,this.portsDirty=!0,this.sync())}getPortElement(t,e){const i="input"===e?this.inputList:this.outputList;return[...i?.querySelectorAll("button")||[]].find(e=>e.dataset.portId===t)||null}connectedCallback(){this.root.childElementCount||this.build(),this.upgradeProperties(["inputs","outputs"]);for(const t of["inputs","outputs"])this.hasAttribute(t)&&this.readPorts(t);this.sync()}disconnectedCallback(){this.finishDrag("end"),this.cancelPortDrag(),super.disconnectedCallback()}attributeChangedCallback(t){"inputs"!==t&&"outputs"!==t||this.readPorts(t),"disabled"===t&&this.hasAttribute("disabled")&&(this.finishDrag("end"),this.cancelPortDrag()),this.sync()}normalizePorts(t){if(!Array.isArray(t))return[];const e=new Set;return t.filter(t=>t&&"string"==typeof t.id&&t.id&&"string"==typeof t.label&&!e.has(t.id)&&e.add(t.id)).map(t=>({id:t.id,label:t.label,type:a.has(t.type)?t.type:"any",connected:!!t.connected,disabled:!!t.disabled}))}readPorts(t){let e=[];try{e=JSON.parse(this.getAttribute(t)||"[]")}catch{}"inputs"===t?this.inputPorts=this.normalizePorts(e):this.outputPorts=this.normalizePorts(e),this.portsDirty=!0}nodeId(){return this.getAttribute("node-id")||this.id}el(t,e){const i=document.createElement(t);return i.className=e,i}action(t,e){const i=this.el("button","action");return i.type="button",i.setAttribute("aria-label",t),i.title=t,i.append(s(e,16)),i}build(){const t=document.createElement("style");t.textContent=n;const e=this.el("article","frame");e.part.add("frame");const i=this.el("header","header");i.part.add("header"),this.headingButton=this.el("button","heading"),this.headingButton.type="button",this.iconBox=this.el("span","icon"),this.iconBox.setAttribute("aria-hidden","true"),this.titleEl=this.el("span","title"),this.headingButton.append(this.iconBox,this.titleEl),this.statusEl=this.el("span","status"),this.statusEl.setAttribute("role","status"),this.statusBadge=document.createElement("db-badge"),this.statusBadge.setAttribute("size","s"),this.statusBadge.setAttribute("type","outlined"),this.statusEl.append(this.statusBadge);const s=this.el("div","actions"),o=document.createElement("slot");o.name="actions",this.runButton=this.action("노드 실행","play-outline"),this.runButton.classList.add("action--run"),this.collapseButton=this.action("노드 접기","chevron-up"),this.deleteButton=this.action("노드 삭제","close"),this.deleteButton.addEventListener("click",()=>this.dbEmit("delete",{nodeId:this.nodeId()},{cancelable:!0})),s.append(o,this.runButton,this.collapseButton,this.deleteButton),i.append(this.headingButton,this.statusEl,s),this.descriptionEl=this.el("p","description"),this.inputList=this.el("div","ports ports--input"),this.inputList.part.add("inputs"),this.outputList=this.el("div","ports ports--output"),this.outputList.part.add("outputs"),this.body=this.el("div","body"),this.body.part.add("body"),this.body.append(document.createElement("slot")),this.footer=this.el("footer","footer");const r=document.createElement("slot");r.name="footer",this.footer.append(r);this.root.addEventListener("slotchange",()=>{this.body.hidden=this.hasAttribute("collapsed")||!this.body.querySelector("slot").assignedNodes({flatten:!0}).some(t=>1===t.nodeType||!!t.textContent?.trim()),this.footer.hidden=this.hasAttribute("collapsed")||!r.assignedNodes({flatten:!0}).length}),e.append(i,this.descriptionEl,this.inputList,this.body,this.outputList,this.footer),this.root.append(t,e);const isEditor=t=>t.composedPath().some(t=>t instanceof HTMLElement&&(t.isContentEditable||t.matches("input, textarea, db-input, db-textarea, db-markdown-editor")));this.addEventListener("selectstart",t=>{isEditor(t)||t.preventDefault()}),this.addEventListener("dragstart",t=>{isEditor(t)||t.preventDefault()}),this.headingButton.addEventListener("click",()=>{this.hasAttribute("disabled")||this.dbEmit("select",{nodeId:this.nodeId()})}),this.collapseButton.addEventListener("click",()=>{const t=!this.hasAttribute("collapsed");this.toggleAttribute("collapsed",t),this.dbEmit("collapse",{nodeId:this.nodeId(),collapsed:t})}),this.runButton.addEventListener("click",()=>this.dbEmit("run",{nodeId:this.nodeId()},{cancelable:!0})),this.headingButton.addEventListener("pointerdown",t=>{this.hasAttribute("movable")&&!this.hasAttribute("disabled")&&0===t.button&&(this.drag={id:t.pointerId,x:t.clientX,y:t.clientY,lastX:t.clientX,lastY:t.clientY},this.headingButton.setPointerCapture(t.pointerId),this.emitMove("start",0,0))}),this.headingButton.addEventListener("pointermove",t=>{this.drag?.id===t.pointerId&&(this.drag.lastX=t.clientX,this.drag.lastY=t.clientY,this.emitMove("move",t.clientX-this.drag.x,t.clientY-this.drag.y))}),this.headingButton.addEventListener("pointerup",t=>{this.drag?.id===t.pointerId&&(this.drag.lastX=t.clientX,this.drag.lastY=t.clientY,this.finishDrag("end"))}),this.headingButton.addEventListener("pointercancel",()=>this.finishDrag("end")),this.headingButton.addEventListener("lostpointercapture",()=>this.finishDrag("end")),this.headingButton.addEventListener("keydown",t=>{if("Escape"===t.key&&this.drag)return void this.finishDrag("cancel");if(!this.hasAttribute("movable")||this.hasAttribute("disabled"))return;const e={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]};if(e[t.key]){t.preventDefault();const[i,s]=e[t.key],n=t.shiftKey?4:16;this.emitMove("keyboard",i*n,s*n)}})}emitMove(t,e,i){this.dbEmit("move",{nodeId:this.nodeId(),deltaX:e,deltaY:i,phase:t})}finishDrag(t){const e=this.drag;e&&(this.drag=null,this.emitMove(t,"cancel"===t?0:e.lastX-e.x,"cancel"===t?0:e.lastY-e.y),this.headingButton.hasPointerCapture(e.id)&&this.headingButton.releasePointerCapture(e.id))}renderPorts(i,s,n){const o=this.root.activeElement,r=o&&i.contains(o)?o.dataset.portId:void 0;this.cancelPortDrag(),i.replaceChildren(),i.hidden=!s.length;for(const o of s){const s=this.el("div","port-row");s.dataset.type=o.type||"any";const r=this.el("button","port");r.type="button",r.part.add("port"),r.dataset.portId=o.id,r.dataset.direction=n,r.disabled=this.hasAttribute("disabled")||!!o.disabled,r.dataset.connected=String(!!o.connected),r.setAttribute("aria-label",t("{0} · {1} · {2}",[e("input"===n?"입력":"출력"),o.label,typeLabels()[o.type||"any"]])),r.setAttribute("aria-pressed",String(!!o.connected));const a=this.el("span","port-dot");r.append(a);const d=this.el("span","port-label");d.textContent=o.label;const h=this.el("span","port-type");h.textContent=typeLabels()[o.type||"any"];const l={nodeId:this.nodeId(),portId:o.id,direction:n,type:o.type||"any"};r.addEventListener("click",()=>{this.suppressPortClick||this.dbEmit("port-select",l)}),r.addEventListener("pointerdown",t=>{0!==t.button||r.disabled||(this.portDrag={id:t.pointerId,button:r,port:l,x:t.clientX,y:t.clientY,moved:!1},this.suppressPortClick=!1,r.setPointerCapture(t.pointerId))}),r.addEventListener("pointermove",t=>{const e=this.portDrag;e&&e.id===t.pointerId&&(!e.moved&&Math.hypot(t.clientX-e.x,t.clientY-e.y)>=4&&(e.moved=!0,this.suppressPortClick=!0,this.emitPortDrag("start",e.x,e.y)),e.moved&&this.emitPortDrag("move",t.clientX,t.clientY))}),r.addEventListener("pointerup",t=>{this.portDrag?.id===t.pointerId&&(this.portDrag.moved&&this.emitPortDrag("end",t.clientX,t.clientY),this.portDrag=null,r.hasPointerCapture(t.pointerId)&&r.releasePointerCapture(t.pointerId),setTimeout(()=>{this.suppressPortClick=!1},0))}),r.addEventListener("pointercancel",()=>this.cancelPortDrag()),r.addEventListener("lostpointercapture",()=>this.cancelPortDrag()),r.addEventListener("keydown",t=>{"Escape"===t.key&&this.cancelPortDrag()}),s.append(r,d,h),i.append(s)}r&&this.getPortElement(r,n)?.focus({preventScroll:!0})}emitPortDrag(t,e,i){this.portDrag&&this.dbEmit("port-drag",{...this.portDrag.port,phase:t,clientX:e,clientY:i})}cancelPortDrag(){const t=this.portDrag;t&&(t.moved&&this.emitPortDrag("cancel",t.x,t.y),this.portDrag=null,t.button.hasPointerCapture(t.id)&&t.button.releasePointerCapture(t.id))}sync(){if(!this.headingButton)return;const t=this.hasAttribute("disabled"),e=this.hasAttribute("collapsed");this.setAttribute("aria-disabled",String(t)),this.root.querySelector(".frame").inert=t,this.dataset.variant=o.includes(this.getAttribute("variant"))?this.getAttribute("variant"):"default";const i=r.find(t=>t===this.getAttribute("status"))||"idle";this.dataset.status=i,this.titleEl.textContent=this.getAttribute("heading")||"새 노드",this.headingButton.disabled=t,this.headingButton.setAttribute("aria-pressed",String(this.hasAttribute("selected"))),this.headingButton.title=this.hasAttribute("movable")?"드래그 또는 방향키로 이동":"노드 선택";const n=this.getAttribute("icon");if(this.iconBox.hidden=!n,n?this.iconBox.replaceChildren(s(n,16)):this.iconBox.replaceChildren(),this.descriptionEl.textContent=this.getAttribute("description")||"",this.descriptionEl.hidden=e||!this.descriptionEl.textContent,this.statusBadge.textContent=d[i],this.statusBadge.setAttribute("variant","error"===i?"danger":"success"===i?"success":"info"),this.statusEl.hidden="idle"===i,this.collapseButton.hidden=!this.hasAttribute("collapsible"),this.collapseButton.disabled=t,this.collapseButton.setAttribute("aria-expanded",String(!e)),this.collapseButton.setAttribute("aria-label",e?"노드 펼치기":"노드 접기"),this.collapseButton.title=e?"노드 펼치기":"노드 접기",this.collapseButton.replaceChildren(s(e?"chevron-down":"chevron-up",16)),this.deleteButton.hidden=!this.hasAttribute("deletable"),this.deleteButton.disabled=t,this.runButton.hidden=!this.hasAttribute("runnable"),this.runButton.disabled=t||"running"===i,this.body.hidden=e||!this.body.querySelector("slot").assignedNodes({flatten:!0}).some(t=>1===t.nodeType||!!t.textContent?.trim()),this.footer.hidden=e||!this.footer.querySelector("slot").assignedNodes({flatten:!0}).length,this.portsDirty)this.renderPorts(this.inputList,this.inputPorts,"input"),this.renderPorts(this.outputList,this.outputPorts,"output"),this.portsDirty=!1;else for(const e of[this.inputList,this.outputList])for(const i of e.querySelectorAll("button")){const s=e===this.inputList?this.inputPorts:this.outputPorts;i.disabled=t||!!s.find(t=>t.id===i.dataset.portId)?.disabled}}}customElements.get("db-node")||customElements.define("db-node",DbNode);export{DbNode,r as NODE_STATUSES,o as NODE_VARIANTS};
|
|
@@ -7,8 +7,22 @@ declare class DbRadio extends HTMLElement {
|
|
|
7
7
|
private labelEl?;
|
|
8
8
|
private built;
|
|
9
9
|
private userInteracted;
|
|
10
|
+
private resetChecked?;
|
|
11
|
+
private readonly cleanups;
|
|
12
|
+
focus(options?: FocusOptions): void;
|
|
13
|
+
get name(): string;
|
|
14
|
+
set name(value: string);
|
|
15
|
+
get value(): string;
|
|
16
|
+
set value(value: string);
|
|
17
|
+
get defaultChecked(): boolean;
|
|
18
|
+
set defaultChecked(value: boolean);
|
|
19
|
+
get defaultSelected(): boolean;
|
|
20
|
+
set defaultSelected(value: boolean);
|
|
21
|
+
private upgradeProperties;
|
|
10
22
|
get checked(): boolean;
|
|
11
23
|
set checked(value: boolean);
|
|
24
|
+
get selected(): boolean;
|
|
25
|
+
set selected(value: boolean);
|
|
12
26
|
get disabled(): boolean;
|
|
13
27
|
set disabled(value: boolean);
|
|
14
28
|
get readOnly(): boolean;
|
|
@@ -18,10 +32,14 @@ declare class DbRadio extends HTMLElement {
|
|
|
18
32
|
get size(): string;
|
|
19
33
|
set size(value: string);
|
|
20
34
|
connectedCallback(): void;
|
|
35
|
+
disconnectedCallback(): void;
|
|
21
36
|
attributeChangedCallback(name: string): void;
|
|
22
|
-
|
|
37
|
+
get hasLabel(): boolean;
|
|
38
|
+
set hasLabel(value: boolean);
|
|
23
39
|
private build;
|
|
24
40
|
private handleChange;
|
|
41
|
+
private groupPeers;
|
|
42
|
+
private syncGroup;
|
|
25
43
|
private syncState;
|
|
26
44
|
private syncVisual;
|
|
27
45
|
private syncClasses;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{CleanupBag as t}from"../core/dom.js";import{coerceToContract as e}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{RADIO_SIZES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbRadio extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.userInteracted=!1,this.cleanups=new t,this.handleChange=()=>{if(!this.input||this.disabled||this.readOnly)return;this.userInteracted=!0;const t=this.input.checked;this.removeAttribute("selected"),this.toggleAttribute("checked",t),this.syncGroup(),this.syncVisual(),this.syncClasses(),this.dispatchEvent(new CustomEvent("db-change",{detail:{checked:t,selected:t,value:this.input.value},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["checked","selected","default-checked","default-selected","size","disabled","readonly","required","name","value","has-label","aria-label","aria-labelledby","aria-describedby"]}focus(t){this.input?.focus(t)}get name(){return this.getAttribute("name")||""}set name(t){this.setAttribute("name",t)}get value(){return this.getAttribute("value")??"on"}set value(t){this.setAttribute("value",t)}get defaultChecked(){return this.hasAttribute("default-checked")||this.hasAttribute("default-selected")}set defaultChecked(t){this.removeAttribute("default-selected"),this.toggleAttribute("default-checked",t)}get defaultSelected(){return this.defaultChecked}set defaultSelected(t){this.defaultChecked=t}upgradeProperties(){for(const t of["checked","selected","defaultChecked","defaultSelected","name","value","disabled","readOnly","required","hasLabel","size"]){if(!Object.prototype.hasOwnProperty.call(this,t))continue;const e=this,s=e[t];delete e[t],e[t]=s}}get checked(){return this.input?.checked??(this.hasAttribute("checked")||this.hasAttribute("selected"))}set checked(t){this.userInteracted=!0,this.removeAttribute("selected"),this.toggleAttribute("checked",t),this.input&&(this.input.checked=t,this.syncVisual(),this.syncClasses(),this.syncGroup())}get selected(){return this.checked}set selected(t){this.checked=t}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t),this.input&&(this.input.disabled=t),this.syncClasses()}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t),this.input&&(this.input.readOnly=t),this.syncClasses()}get required(){return this.hasAttribute("required")}set required(t){this.toggleAttribute("required",t),this.input&&(this.input.required=t)}get size(){return e(this.getAttribute("size"),s,"m")}set size(t){this.setAttribute("size",t)}connectedCallback(){this.upgradeProperties(),this.style.display="contents",this.built||this.build(),this.syncState(),this.input?.form&&this.cleanups.listen(this.input.form,"reset",()=>{window.setTimeout(()=>{this.input&&this.isConnected&&(this.toggleAttribute("checked",this.input.checked),this.removeAttribute("selected"),this.syncClasses())},0)})}disconnectedCallback(){this.cleanups.run()}attributeChangedCallback(t){if(this.built){if("default-checked"!==t&&"default-selected"!==t||(this.resetChecked=this.hasAttribute("default-checked")||this.hasAttribute("default-selected")),"checked"===t||"selected"===t)return this.userInteracted=!0,this.input&&(this.input.checked=this.hasAttribute("checked")||this.hasAttribute("selected")),this.syncVisual(),this.syncClasses(),void this.syncGroup();this.syncState()}}get hasLabel(){return!this.hasAttribute("has-label")||"false"!==this.getAttribute("has-label")}set hasLabel(t){this.setAttribute("has-label",String(t))}build(){for(this.root=document.createElement("label"),this.root.className="designbase-wc-radio",this.input=document.createElement("input"),this.input.type="radio",this.input.className="designbase-wc-radio__input",this.visual=document.createElement("span"),this.visual.className="designbase-wc-radio__visual",this.visual.setAttribute("aria-hidden","true"),this.dot=document.createElement("span"),this.dot.className="designbase-wc-radio__dot",this.visual.appendChild(this.dot),this.labelEl=document.createElement("span"),this.labelEl.className="designbase-wc-radio__label";this.firstChild;)this.labelEl.appendChild(this.firstChild);this.root.append(this.input,this.visual,this.labelEl),this.appendChild(this.root),this.input.addEventListener("click",t=>{this.readOnly&&t.preventDefault()}),this.input.addEventListener("keydown",t=>{const e=["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"];if(this.readOnly&&(" "===t.key||e.includes(t.key)))return void t.preventDefault();const s=this.groupPeers();if(!e.includes(t.key)||!s.some(t=>t.readOnly))return;const i=s.filter(t=>!t.disabled&&!t.readOnly);if(!i.length)return;t.preventDefault();const r="rtl"===getComputedStyle(this).direction,a="ArrowDown"===t.key||t.key===(r?"ArrowLeft":"ArrowRight"),h=i[(i.indexOf(this)+(a?1:-1)+i.length)%i.length];h.input?.focus(),h.input?.click()}),this.input.addEventListener("change",this.handleChange),this.built=!0}groupPeers(){if(!this.input?.name)return[this];const t=this.getRootNode();return Array.from(t.querySelectorAll("db-radio")).filter(t=>t.input?.name===this.input.name&&t.input?.form===this.input.form)}syncGroup(){if(this.input?.checked&&this.input.name){const t=this.getRootNode();for(const e of t.querySelectorAll("db-radio"))e!==this&&e.input&&e.input.name===this.input.name&&e.input.form===this.input.form&&(e.userInteracted=!0,e.removeAttribute("checked"),e.removeAttribute("selected"),e.syncClasses())}}syncState(){if(!this.root||!this.input||!this.visual)return;const t=this.hasAttribute("checked")||this.hasAttribute("selected")||!this.userInteracted&&(this.hasAttribute("default-checked")||this.hasAttribute("default-selected"));this.resetChecked??(this.resetChecked=t),this.input.defaultChecked=this.resetChecked,this.input.checked=t,this.input.disabled=this.disabled,this.input.readOnly=this.readOnly,this.input.setAttribute("aria-disabled",String(this.disabled||this.readOnly)),this.input.required=this.required,this.input.name=this.getAttribute("name")||"",this.input.value=this.getAttribute("value")??"on";for(const t of["aria-label","aria-labelledby","aria-describedby"]){const e=this.getAttribute(t);e?this.input.setAttribute(t,e):this.input.removeAttribute(t)}this.hasLabel?this.labelEl?.removeAttribute("hidden"):this.labelEl?.setAttribute("hidden",""),this.syncVisual(),this.syncClasses()}syncVisual(){}syncClasses(){if(!this.root||!this.input)return;const t=s.includes(this.size)?this.size:"m",e=this.hasLabel&&Boolean(this.labelEl?.textContent?.trim());this.root.className=["designbase-wc-radio",`designbase-wc-radio--${t}`,this.input.checked&&"designbase-wc-radio--selected",this.disabled&&"designbase-wc-radio--disabled",this.readOnly&&"designbase-wc-radio--readonly",!e&&"designbase-wc-radio--no-label"].filter(Boolean).join(" ")}}customElements.get("db-radio")||customElements.define("db-radio",DbRadio);export{DbRadio};
|