@designbasekorea/ui-wc 0.9.4 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +2 -0
- package/dist/esm/components/db-accordion.d.ts +22 -10
- package/dist/esm/components/db-accordion.js +1 -1
- package/dist/esm/components/db-avatar.js +1 -1
- package/dist/esm/components/db-button.d.ts +33 -1
- package/dist/esm/components/db-button.js +1 -1
- package/dist/esm/components/db-chat-orb.d.ts +13 -0
- package/dist/esm/components/db-chat-orb.js +1 -1
- package/dist/esm/components/db-chat-room.js +1 -1
- package/dist/esm/components/db-chat-widget.js +1 -1
- package/dist/esm/components/db-checkbox.d.ts +3 -0
- package/dist/esm/components/db-checkbox.js +1 -1
- package/dist/esm/components/db-confetti.d.ts +11 -5
- package/dist/esm/components/db-confetti.js +1 -1
- package/dist/esm/components/db-email-verify.d.ts +36 -7
- package/dist/esm/components/db-email-verify.js +1 -1
- package/dist/esm/components/db-floating-action-button.d.ts +1 -1
- package/dist/esm/components/db-floating-action-button.js +1 -1
- package/dist/esm/components/db-input.d.ts +8 -1
- package/dist/esm/components/db-input.js +1 -1
- package/dist/esm/components/db-navbar.d.ts +3 -0
- package/dist/esm/components/db-navbar.js +1 -1
- package/dist/esm/components/db-otp-input.js +1 -1
- package/dist/esm/components/db-page-header.d.ts +11 -0
- package/dist/esm/components/db-page-header.js +1 -1
- package/dist/esm/components/db-phone-verify.d.ts +33 -11
- package/dist/esm/components/db-phone-verify.js +1 -1
- package/dist/esm/components/db-radio.d.ts +3 -0
- package/dist/esm/components/db-radio.js +1 -1
- package/dist/esm/components/db-range-slider.d.ts +35 -7
- package/dist/esm/components/db-range-slider.js +1 -1
- package/dist/esm/components/db-select.d.ts +35 -6
- package/dist/esm/components/db-select.js +1 -1
- package/dist/esm/components/db-tabs.d.ts +36 -13
- package/dist/esm/components/db-tabs.js +1 -1
- package/dist/esm/components/db-textarea.d.ts +13 -1
- package/dist/esm/components/db-textarea.js +1 -1
- package/dist/esm/components/db-toggle.d.ts +33 -4
- package/dist/esm/components/db-toggle.js +1 -1
- package/dist/esm/components/db-two-factor.d.ts +35 -12
- package/dist/esm/components/db-two-factor.js +1 -1
- package/dist/esm/core/control-label.js +1 -0
- package/dist/esm/core/i18n-copy.js +1 -1
- package/dist/esm/core/range-values.js +1 -0
- package/dist/esm/core/text-field-state.js +1 -0
- package/dist/esm/node_modules/@designbasekorea/ui-contracts/dist/components.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +362 -77
- package/dist/index.esm.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +5431 -634
- package/dist/react/index.esm.js +1 -1
- package/package.json +7 -3
|
@@ -4,11 +4,14 @@ declare class DbCheckbox extends HTMLElement {
|
|
|
4
4
|
private input?;
|
|
5
5
|
private visual?;
|
|
6
6
|
private labelEl?;
|
|
7
|
+
private readonly labelContent;
|
|
7
8
|
private built;
|
|
8
9
|
private userInteracted;
|
|
9
10
|
private resetChecked?;
|
|
10
11
|
private readonly cleanups;
|
|
11
12
|
focus(options?: FocusOptions): void;
|
|
13
|
+
get label(): string;
|
|
14
|
+
set label(value: string);
|
|
12
15
|
get name(): string;
|
|
13
16
|
set name(value: string);
|
|
14
17
|
get value(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ControlLabel as e}from"../core/control-label.js";import{createDbIcon as t}from"./db-icons.js";import{CleanupBag as s}from"../core/dom.js";import{coerceToContract as i}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{CHECKBOX_SIZES as h}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";class DbCheckbox extends HTMLElement{constructor(){super(...arguments),this.labelContent=new e(this),this.built=!1,this.userInteracted=!1,this.cleanups=new s,this.handleChange=()=>{if(!this.input||this.disabled||this.readOnly)return;this.userInteracted=!0;const e=this.input.checked;this.removeAttribute("selected"),this.toggleAttribute("checked",e),this.indeterminate&&(this.removeAttribute("indeterminate"),this.input.indeterminate=!1),this.syncVisual(),this.syncClasses(),this.syncValidity(),this.dispatchEvent(new CustomEvent("db-change",{detail:{checked:e,selected:e},bubbles:!0,composed:!0}))}}static get observedAttributes(){return["checked","selected","default-checked","default-selected","indeterminate","size","disabled","readonly","required","name","value","label","has-label","aria-label","aria-labelledby","aria-describedby"]}focus(e){this.input?.focus(e)}get label(){return this.labelContent.value}set label(e){this.setAttribute("label",e)}get name(){return this.getAttribute("name")||""}set name(e){this.setAttribute("name",e)}get value(){return this.getAttribute("value")??"on"}set value(e){this.setAttribute("value",e)}get defaultChecked(){return this.hasAttribute("default-checked")||this.hasAttribute("default-selected")}set defaultChecked(e){this.removeAttribute("default-selected"),this.toggleAttribute("default-checked",e)}get defaultSelected(){return this.defaultChecked}set defaultSelected(e){this.defaultChecked=e}upgradeProperties(){for(const e of["checked","selected","defaultChecked","defaultSelected","name","value","label","disabled","readOnly","required","hasLabel","size","indeterminate"]){if(!Object.prototype.hasOwnProperty.call(this,e))continue;const t=this,s=t[e];delete t[e],t[e]=s}}get checked(){return this.input?.checked??(this.hasAttribute("checked")||this.hasAttribute("selected"))}set checked(e){this.userInteracted=!0,this.removeAttribute("selected"),this.toggleAttribute("checked",e),this.input&&(this.input.checked=e,this.syncVisual(),this.syncClasses())}get selected(){return this.checked}set selected(e){this.checked=e}get indeterminate(){return this.hasAttribute("indeterminate")}set indeterminate(e){this.toggleAttribute("indeterminate",e),this.input&&(this.input.indeterminate=e,this.syncVisual(),this.syncClasses())}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",e),this.input&&(this.input.disabled=e),this.syncClasses()}get readOnly(){return this.hasAttribute("readonly")}set readOnly(e){this.toggleAttribute("readonly",e),this.input&&(this.input.readOnly=e),this.syncClasses()}get required(){return this.hasAttribute("required")}set required(e){this.toggleAttribute("required",e),this.input&&(this.input.required=e)}get size(){return i(this.getAttribute("size"),h,"m")}set size(e){this.setAttribute("size",e)}connectedCallback(){this.upgradeProperties(),this.style.display="contents",this.built||this.build(),this.labelContent.connect(this.labelEl,()=>this.syncClasses()),this.syncState();const e=this.input?.form;e&&this.cleanups.listen(e,"reset",()=>{window.setTimeout(()=>this.syncAfterReset(),0)})}disconnectedCallback(){this.cleanups.run(),this.labelContent.disconnect()}syncAfterReset(){this.input&&(this.toggleAttribute("checked",this.input.checked),this.removeAttribute("selected"),this.syncVisual(),this.syncClasses())}attributeChangedCallback(e){if(this.built){if("default-checked"!==e&&"default-selected"!==e||(this.resetChecked=this.hasAttribute("default-checked")||this.hasAttribute("default-selected")),"checked"===e||"selected"===e)return this.userInteracted=!0,this.input&&(this.input.checked=this.hasAttribute("checked")||this.hasAttribute("selected")),this.syncVisual(),void this.syncClasses();this.syncState()}}get hasLabel(){return!this.hasAttribute("has-label")||"false"!==this.getAttribute("has-label")}set hasLabel(e){this.setAttribute("has-label",String(e))}build(){for(this.root=document.createElement("label"),this.root.className="designbase-wc-checkbox",this.input=document.createElement("input"),this.input.type="checkbox",this.input.className="designbase-wc-checkbox__input",this.visual=document.createElement("span"),this.visual.className="designbase-wc-checkbox__visual",this.visual.setAttribute("aria-hidden","true"),this.labelEl=document.createElement("span"),this.labelEl.className="designbase-wc-checkbox__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",e=>{this.readOnly&&e.preventDefault()}),this.input.addEventListener("change",this.handleChange),this.built=!0}syncValidity(){if(!this.input)return;const e=!this.input.checkValidity();this.input.setAttribute("aria-invalid",String(e)),this.classList.toggle("designbase-wc-checkbox--invalid",e)}syncState(){if(!this.root||!this.input||!this.visual)return;this.labelContent.sync();const e=this.hasAttribute("checked")||this.hasAttribute("selected")||!this.userInteracted&&(this.hasAttribute("default-checked")||this.hasAttribute("default-selected")),t=this.hasAttribute("indeterminate");this.input.checked=e,this.resetChecked??(this.resetChecked=e),this.input.defaultChecked=this.resetChecked,this.input.indeterminate=t,this.input.disabled=this.disabled,this.input.readOnly=this.readOnly,this.input.setAttribute("aria-readonly",String(this.readOnly)),this.input.required=this.required,this.input.name=this.getAttribute("name")||"",this.input.value=this.getAttribute("value")??"on";for(const e of["aria-label","aria-labelledby","aria-describedby"]){const t=this.getAttribute(e);t?this.input.setAttribute(e,t):this.input.removeAttribute(e)}this.hasLabel?this.labelEl?.removeAttribute("hidden"):this.labelEl?.setAttribute("hidden",""),this.syncVisual(),this.syncClasses()}syncVisual(){if(this.visual&&this.input){if(this.visual.replaceChildren(),this.input.indeterminate){const e=document.createElement("span");return e.className="designbase-wc-checkbox__indeterminate-icon",e.appendChild(t("minus",16)),void this.visual.appendChild(e)}if(this.input.checked){const e=document.createElement("span");e.className="designbase-wc-checkbox__check-icon",e.appendChild(t("done",16)),this.visual.appendChild(e)}}}syncClasses(){if(!this.root||!this.input)return;const e=h.includes(this.size)?this.size:"m",t=this.hasLabel&&Boolean(this.label.trim());this.root.className=["designbase-wc-checkbox",`designbase-wc-checkbox--${e}`,this.input.checked&&"designbase-wc-checkbox--selected",this.input.indeterminate&&"designbase-wc-checkbox--indeterminate",this.disabled&&"designbase-wc-checkbox--disabled",this.readOnly&&"designbase-wc-checkbox--readonly",!t&&"designbase-wc-checkbox--no-label"].filter(Boolean).join(" ")}}customElements.get("db-checkbox")||customElements.define("db-checkbox",DbCheckbox);export{DbCheckbox};
|
|
@@ -14,6 +14,8 @@ interface ConfettiParticleOptions {
|
|
|
14
14
|
y: number;
|
|
15
15
|
};
|
|
16
16
|
colors?: string[];
|
|
17
|
+
/** 색상 프리셋 이름(CONFETTI_PALETTES). colors 가 있으면 colors 가 우선합니다. */
|
|
18
|
+
palette?: string;
|
|
17
19
|
shapes?: ConfettiShape[];
|
|
18
20
|
scalar?: number;
|
|
19
21
|
zIndex?: number;
|
|
@@ -24,6 +26,7 @@ interface ConfettiFireworkOptions {
|
|
|
24
26
|
interval?: number;
|
|
25
27
|
particleCount?: number;
|
|
26
28
|
colors?: string[];
|
|
29
|
+
palette?: string;
|
|
27
30
|
}
|
|
28
31
|
declare class DbConfetti extends HTMLElement {
|
|
29
32
|
static get observedAttributes(): string[];
|
|
@@ -49,6 +52,9 @@ declare class DbConfetti extends HTMLElement {
|
|
|
49
52
|
set originY(value: number);
|
|
50
53
|
get colors(): string[];
|
|
51
54
|
set colors(value: string[]);
|
|
55
|
+
/** 색상 프리셋 이름. `colors` 속성이 있으면 colors 가 우선합니다. */
|
|
56
|
+
get palette(): string;
|
|
57
|
+
set palette(value: string);
|
|
52
58
|
get shapes(): ConfettiShape[];
|
|
53
59
|
set shapes(value: ConfettiShape[]);
|
|
54
60
|
get duration(): number;
|
|
@@ -63,9 +69,9 @@ declare class DbConfetti extends HTMLElement {
|
|
|
63
69
|
private sync;
|
|
64
70
|
fire(opts?: ConfettiParticleOptions): void;
|
|
65
71
|
fireworks(options?: ConfettiFireworkOptions): void;
|
|
66
|
-
cannon(): void;
|
|
67
|
-
stars(): void;
|
|
68
|
-
pride(): void;
|
|
72
|
+
cannon(options?: ConfettiParticleOptions): void;
|
|
73
|
+
stars(options?: ConfettiParticleOptions): void;
|
|
74
|
+
pride(options?: ConfettiParticleOptions): void;
|
|
69
75
|
snow(): void;
|
|
70
76
|
fireByMode(): void;
|
|
71
77
|
private drawStar;
|
|
@@ -80,8 +86,8 @@ interface ConfettiFunction {
|
|
|
80
86
|
(options?: ConfettiParticleOptions): void;
|
|
81
87
|
fireworks(options?: ConfettiFireworkOptions): void;
|
|
82
88
|
cannon(options?: ConfettiParticleOptions): void;
|
|
83
|
-
stars(): void;
|
|
84
|
-
pride(): void;
|
|
89
|
+
stars(options?: ConfettiParticleOptions): void;
|
|
90
|
+
pride(options?: ConfettiParticleOptions): void;
|
|
85
91
|
snow(): void;
|
|
86
92
|
}
|
|
87
93
|
declare const confetti: ConfettiFunction;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{coerceToContract as t}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{CONFETTI_MODES as e,CONFETTI_TRIGGERS as i,CONFETTI_SHAPES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const r="designbase-wc-confetti",n=["#26ccff","#a25afd","#ff5e7e","#88ff5a","#fcff42","#ffa62d","#ff36ff"];function randomRange(t,e){return Math.random()*(e-t)+t}function hexToRgb(t){let e=t.replace("#","");3===e.length&&(e=e.split("").map(t=>t+t).join(""));const i=parseInt(e,16);return{r:i>>16&255,g:i>>8&255,b:255&i}}class DbConfetti extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.particles=[],this.animationId=null,this.fireworkTimer=null,this.clickHandler=()=>this.fire(),this.loop=()=>{if(!this.ctx||!this.canvas)return void(this.animationId=null);const t=this.ctx,e=this.canvas.width/(window.devicePixelRatio||1),i=this.canvas.height/(window.devicePixelRatio||1);t.clearRect(0,0,e,i);const s=[],r=this.particles.length;for(let n=0;n<r;n++){const r=this.particles[n];r.tick++,r.vx*=r.drag,r.vy<r.maxFallSpeed?r.vy=r.vy*r.drag+r.gravity:(r.vy=.98*r.vy+.05*r.gravity,r.vy>r.maxFallSpeed&&(r.vy=r.maxFallSpeed)),r.wobble+=r.wobbleSpeed;const a=Math.sin(r.wobble)*r.flutterStrength;r.x+=r.vx+r.drift+a,r.y+=r.vy,r.angle+=r.rotationSpeed;const o=r.tick/r.totalTicks;if(r.opacity=o<.72?1:Math.max(0,1-(o-.72)/.28),r.opacity<=0||r.tick>=r.totalTicks||r.y>i+50||r.x<-80||r.x>e+80)continue;s.push(r),t.save(),t.translate(r.x,r.y),t.rotate(r.angle*Math.PI/180),t.scale(Math.cos(r.wobble),1);const l=hexToRgb(r.color);t.fillStyle=`rgba(${l.r}, ${l.g}, ${l.b}, ${r.opacity.toFixed(3)})`,"circle"===r.shape?(t.beginPath(),t.arc(0,0,r.w/2,0,2*Math.PI),t.fill()):"star"===r.shape?this.drawStar(t,0,0,5,r.w,r.w/2):t.fillRect(-r.w/2,-r.h/2,r.w,r.h),t.restore()}this.particles=s,this.particles.length>0?this.animationId=requestAnimationFrame(this.loop):this.animationId=null}}static get observedAttributes(){return["mode","trigger","particle-count","spread","origin-x","origin-y","colors","shapes","duration","fullscreen"]}get mode(){return t(this.getAttribute("mode"),e,"cannon")}set mode(t){this.setAttribute("mode",t)}get trigger(){return t(this.getAttribute("trigger"),i,"manual")}set trigger(t){this.setAttribute("trigger",t)}get particleCount(){const t=parseInt(this.getAttribute("particle-count")||"60",10);return Number.isFinite(t)&&t>0?t:60}set particleCount(t){this.setAttribute("particle-count",String(t))}get spread(){const t=parseFloat(this.getAttribute("spread")||"70");return Number.isFinite(t)?t:70}set spread(t){this.setAttribute("spread",String(t))}get originX(){const t=parseFloat(this.getAttribute("origin-x")||"0.5");return Number.isFinite(t)?t:.5}set originX(t){this.setAttribute("origin-x",String(t))}get originY(){const t=parseFloat(this.getAttribute("origin-y")||"0.7");return Number.isFinite(t)?t:.7}set originY(t){this.setAttribute("origin-y",String(t))}get colors(){const t=this.getAttribute("colors");if(!t)return n;const e=t.split(",").map(t=>t.trim()).filter(Boolean);return e.length?e:n}set colors(t){this.setAttribute("colors",t.join(","))}get shapes(){const t=this.getAttribute("shapes");if(!t)return["square","circle"];if("mix"===t)return["square","circle","star"];const e=t.split(",").map(t=>t.trim()).filter(t=>s.includes(t));return e.length?e:["square","circle"]}set shapes(t){this.setAttribute("shapes",t.join(","))}get duration(){const t=parseFloat(this.getAttribute("duration")||"3000");return Number.isFinite(t)&&t>0?t:3e3}set duration(t){this.setAttribute("duration",String(t))}get fullscreen(){return this.hasAttribute("fullscreen")}set fullscreen(t){t?this.setAttribute("fullscreen",""):this.removeAttribute("fullscreen")}connectedCallback(){this.setAttribute("aria-hidden","true"),this.built||(this.build(),this.built=!0),this.sync(),"auto"===this.trigger?requestAnimationFrame(()=>this.fireByMode()):"click"===this.trigger&&this.parentElement&&this.parentElement.addEventListener("click",this.clickHandler)}disconnectedCallback(){null!==this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=void 0),this.parentElement&&this.parentElement.removeEventListener("click",this.clickHandler)}attributeChangedCallback(t,e,i){this.built&&("trigger"===t&&this.parentElement&&(this.parentElement.removeEventListener("click",this.clickHandler),"click"===this.trigger&&this.parentElement.addEventListener("click",this.clickHandler)),this.sync())}build(){this.classList.add(r);const t=document.createElement("canvas");t.className=`${r}__canvas`,this.canvas=t,this.ctx=t.getContext("2d"),this.replaceChildren(t),this.updateCanvasSize(),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateCanvasSize()),this.resizeObserver.observe(this.fullscreen?document.body:this.parentElement||this))}updateCanvasSize(){if(!this.canvas)return;const t=window.devicePixelRatio||1;let e=this.clientWidth,i=this.clientHeight;if(this.fullscreen||0===e||0===i){const t=this.parentElement;t&&!this.fullscreen?(e=t.clientWidth,i=t.clientHeight):(e=window.innerWidth,i=window.innerHeight)}0===e&&(e=300),0===i&&(i=300),this.canvas.width=e*t,this.canvas.height=i*t,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${i}px`,this.ctx&&(this.ctx.resetTransform?.(),this.ctx.scale(t,t))}sync(){this.fullscreen?this.classList.add(`${r}--fullscreen`):this.classList.remove(`${r}--fullscreen`),e.forEach(t=>this.classList.remove(`${r}--${t}`)),this.classList.add(`${r}--${this.mode}`)}fire(t){if(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches&&!1!==t?.disableForReducedMotion)return;this.updateCanvasSize();const e=this.canvas?this.canvas.width/(window.devicePixelRatio||1):400,i=this.canvas?this.canvas.height/(window.devicePixelRatio||1):400,s=this.fullscreen||this.parentElement===document.body||this.parentElement===document.documentElement||e>=window.innerWidth-30&&i>=window.innerHeight-30,r=s?1:Math.min(1,Math.max(.18,i/750)),n=s?1:Math.min(1,Math.max(.22,e/900)),a=Math.min(r,n),o=s?1:Math.max(.18,Math.min(1,.62*r+.04)),l=s?1:Math.max(.26,Math.min(1,.7*r+.15)),c=s?1:Math.max(.35,Math.min(1,.6*r+.25)),h=s?1:Math.max(.7,Math.min(1,.68+.32*a)),d=t?.particleCount??this.particleCount,u=t?.angle??90,f=t?.spread??this.spread,g=(t?.startVelocity??58)*o,m=t?.decay??(s?.925:Math.max(.91,.925-.015*(1-r))),p=(t?.gravity??.42)*l,b=(t?.drift??0)*(s?1:n),v=t?.ticks??380,w=s?v:Math.round(v*(.65+.35*a)),y=t?.colors??this.colors,k=t?.shapes??this.shapes,x=(t?.scalar??1)*h,M=(t?.origin?.x??this.originX)*e,C=(t?.origin?.y??this.originY)*i,R=u*Math.PI/180,A=f*Math.PI/180;for(let t=0;t<d;t++){const t=R+(Math.random()-.5)*A,e=g*randomRange(.65,1.35),i=y[Math.floor(Math.random()*y.length)],r=k[Math.floor(Math.random()*k.length)],n=m*randomRange(.99,1.01),o=p*randomRange(.85,1.15),l=randomRange(2.2,4.2)*x*c,h=randomRange(.8,2.2)*(s?1:Math.max(.5,1.2*a)),d=Math.floor(w*randomRange(.85,1.25));this.particles.push({x:M,y:C,vx:Math.cos(t)*e,vy:-Math.sin(t)*e,w:randomRange(7,12)*x,h:("circle"===r?randomRange(7,12):randomRange(10,18))*x,color:i,shape:r,angle:360*Math.random(),rotationSpeed:randomRange(-4.5,4.5),wobble:10*Math.random(),wobbleSpeed:randomRange(.06,.14),opacity:1,gravity:o,drag:n,drift:b,maxFallSpeed:l,flutterStrength:h,tick:0,totalTicks:d,scalar:x})}null===this.animationId&&this.loop()}fireworks(t){const e=t?.duration??(this.duration||3500),i=t?.interval??320,s=Date.now()+e;null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null);const runBurst=()=>{if(Date.now()>s)return void(null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null));const e=t?.particleCount??Math.floor(randomRange(30,50));this.fire({particleCount:e,startVelocity:42,spread:360,ticks:280,origin:{x:randomRange(.15,.85),y:randomRange(.12,.45)},colors:t?.colors??this.colors})};runBurst(),this.fireworkTimer=window.setInterval(runBurst,i)}cannon(){this.fire({particleCount:this.particleCount,angle:90,spread:75,startVelocity:58,ticks:380,origin:{x:.5,y:.85}})}stars(){this.fire({particleCount:45,spread:360,ticks:260,gravity:.25,decay:.94,startVelocity:38,shapes:["star"],colors:["#ffe600","#ffd700","#ffffff","#ffaa00","#f59e0b"],scalar:1.2})}pride(){const t=["#e40303","#ff8c00","#ffed00","#008026","#004dff","#750787"];this.fire({particleCount:48,angle:60,spread:60,startVelocity:56,ticks:380,origin:{x:0,y:.85},colors:t}),this.fire({particleCount:48,angle:120,spread:60,startVelocity:56,ticks:380,origin:{x:1,y:.85},colors:t})}snow(){this.fire({particleCount:50,angle:270,spread:180,startVelocity:14,gravity:.18,drift:randomRange(-.3,.3),ticks:450,shapes:["circle"],colors:["#ffffff","#e2e8f0","#93c5fd"],origin:{x:randomRange(.1,.9),y:-.05},scalar:.8})}fireByMode(){switch(this.mode){case"fireworks":this.fireworks();break;case"stars":this.stars();break;case"pride":this.pride();break;case"snow":this.snow();break;default:this.cannon()}}drawStar(t,e,i,s,r,n){let a=Math.PI/2*3,o=e,l=i;const c=Math.PI/s;t.beginPath(),t.moveTo(e,i-r);for(let h=0;h<s;h++)o=e+Math.cos(a)*r,l=i+Math.sin(a)*r,t.lineTo(o,l),a+=c,o=e+Math.cos(a)*n,l=i+Math.sin(a)*n,t.lineTo(o,l),a+=c;t.lineTo(e,i-r),t.closePath(),t.fill()}}customElements.get("db-confetti")||customElements.define("db-confetti",DbConfetti);let a=null;function getGlobalConfetti(){return a&&a.isConnected||(a=document.createElement("db-confetti"),a.setAttribute("fullscreen",""),document.body.appendChild(a)),a}const o=Object.assign(t=>{getGlobalConfetti().fire(t)},{fireworks:t=>{getGlobalConfetti().fireworks(t)},cannon:t=>{t?getGlobalConfetti().fire(t):getGlobalConfetti().cannon()},stars:()=>{getGlobalConfetti().stars()},pride:()=>{getGlobalConfetti().pride()},snow:()=>{getGlobalConfetti().snow()}});export{DbConfetti,o as confetti};
|
|
1
|
+
import{coerceToContract as t}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{CONFETTI_MODES as e,CONFETTI_TRIGGERS as i,CONFETTI_SHAPES as s}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const r="designbase-wc-confetti",a={soft:["#7c8cf8","#f08fb0","#f6b26b","#79c9b0","#b79cf0","#f2d675"],pastel:["#ffd1dc","#c7e4ff","#d6f5d6","#fff1b8","#e3d4ff","#ffd9b8"],sunset:["#ff9a6b","#ff6f91","#ffc75f","#f9a8d4","#c44d78","#ffe0a3"],ocean:["#38bdf8","#2dd4bf","#818cf8","#a5f3fc","#0e7490","#bae6fd"],forest:["#4d8b6a","#9bc59d","#d9c98b","#7aa78a","#c9dfb4","#2f6b52"],candy:["#ff8fcf","#8fd3ff","#ffe08f","#b9a4ff","#9ff0c8","#ffb4a2"],gold:["#e8c15a","#f6e3a1","#c99a2e","#fff6d6","#b8860b","#f3d27a"],mono:["#111827","#4b5563","#9ca3af","#d1d5db","#f3f4f6","#6b7280"],classic:["#26ccff","#a25afd","#ff5e7e","#88ff5a","#fcff42","#ffa62d","#ff36ff"]},n="soft",o=a[n];function paletteColors(t){return t&&a[t]?a[t]:null}function randomRange(t,e){return Math.random()*(e-t)+t}function hexToRgb(t){let e=t.replace("#","");3===e.length&&(e=e.split("").map(t=>t+t).join(""));const i=parseInt(e,16);return{r:i>>16&255,g:i>>8&255,b:255&i}}class DbConfetti extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.particles=[],this.animationId=null,this.fireworkTimer=null,this.clickHandler=()=>this.fire(),this.loop=()=>{if(!this.ctx||!this.canvas)return void(this.animationId=null);const t=this.ctx,e=this.canvas.width/(window.devicePixelRatio||1),i=this.canvas.height/(window.devicePixelRatio||1);t.clearRect(0,0,e,i);const s=[],r=this.particles.length;for(let a=0;a<r;a++){const r=this.particles[a];r.tick++,r.vx*=r.drag,r.vy<r.maxFallSpeed?r.vy=r.vy*r.drag+r.gravity:(r.vy=.98*r.vy+.05*r.gravity,r.vy>r.maxFallSpeed&&(r.vy=r.maxFallSpeed)),r.wobble+=r.wobbleSpeed;const n=Math.sin(r.wobble)*r.flutterStrength;r.x+=r.vx+r.drift+n,r.y+=r.vy,r.angle+=r.rotationSpeed;const o=r.tick/r.totalTicks;if(r.opacity=o<.72?1:Math.max(0,1-(o-.72)/.28),r.opacity<=0||r.tick>=r.totalTicks||r.y>i+50||r.x<-80||r.x>e+80)continue;s.push(r),t.save(),t.translate(r.x,r.y),t.rotate(r.angle*Math.PI/180),t.scale(Math.cos(r.wobble),1);const l=hexToRgb(r.color);if(t.fillStyle=`rgba(${l.r}, ${l.g}, ${l.b}, ${r.opacity.toFixed(3)})`,"circle"===r.shape)t.beginPath(),t.arc(0,0,r.w/2,0,2*Math.PI),t.fill();else if("star"===r.shape)this.drawStar(t,0,0,5,r.w,r.w/2);else{const e=.22*Math.min(r.w,r.h);t.beginPath(),t.roundRect(-r.w/2,-r.h/2,r.w,r.h,e),t.fill()}t.restore()}this.particles=s,this.particles.length>0?this.animationId=requestAnimationFrame(this.loop):this.animationId=null}}static get observedAttributes(){return["mode","trigger","particle-count","spread","origin-x","origin-y","colors","palette","shapes","duration","fullscreen"]}get mode(){return t(this.getAttribute("mode"),e,"cannon")}set mode(t){this.setAttribute("mode",t)}get trigger(){return t(this.getAttribute("trigger"),i,"manual")}set trigger(t){this.setAttribute("trigger",t)}get particleCount(){const t=parseInt(this.getAttribute("particle-count")||"60",10);return Number.isFinite(t)&&t>0?t:60}set particleCount(t){this.setAttribute("particle-count",String(t))}get spread(){const t=parseFloat(this.getAttribute("spread")||"70");return Number.isFinite(t)?t:70}set spread(t){this.setAttribute("spread",String(t))}get originX(){const t=parseFloat(this.getAttribute("origin-x")||"0.5");return Number.isFinite(t)?t:.5}set originX(t){this.setAttribute("origin-x",String(t))}get originY(){const t=parseFloat(this.getAttribute("origin-y")||"0.7");return Number.isFinite(t)?t:.7}set originY(t){this.setAttribute("origin-y",String(t))}get colors(){const t=this.getAttribute("colors"),e=paletteColors(this.getAttribute("palette"))??o;if(!t)return e;const i=t.split(",").map(t=>t.trim()).filter(Boolean);return i.length?i:e}set colors(t){this.setAttribute("colors",t.join(","))}get palette(){const t=this.getAttribute("palette");return t&&a[t]?t:n}set palette(t){this.setAttribute("palette",t)}get shapes(){const t=this.getAttribute("shapes");if(!t)return["square","circle"];if("mix"===t)return["square","circle","star"];const e=t.split(",").map(t=>t.trim()).filter(t=>s.includes(t));return e.length?e:["square","circle"]}set shapes(t){this.setAttribute("shapes",t.join(","))}get duration(){const t=parseFloat(this.getAttribute("duration")||"3000");return Number.isFinite(t)&&t>0?t:3e3}set duration(t){this.setAttribute("duration",String(t))}get fullscreen(){return this.hasAttribute("fullscreen")}set fullscreen(t){t?this.setAttribute("fullscreen",""):this.removeAttribute("fullscreen")}connectedCallback(){this.setAttribute("aria-hidden","true"),this.built||(this.build(),this.built=!0),this.sync(),"auto"===this.trigger?requestAnimationFrame(()=>this.fireByMode()):"click"===this.trigger&&this.parentElement&&this.parentElement.addEventListener("click",this.clickHandler)}disconnectedCallback(){null!==this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=void 0),this.parentElement&&this.parentElement.removeEventListener("click",this.clickHandler)}attributeChangedCallback(t,e,i){this.built&&("trigger"===t&&this.parentElement&&(this.parentElement.removeEventListener("click",this.clickHandler),"click"===this.trigger&&this.parentElement.addEventListener("click",this.clickHandler)),this.sync())}build(){this.classList.add(r);const t=document.createElement("canvas");t.className=`${r}__canvas`,this.canvas=t,this.ctx=t.getContext("2d"),this.replaceChildren(t),this.updateCanvasSize(),"undefined"!=typeof ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateCanvasSize()),this.resizeObserver.observe(this.fullscreen?document.body:this.parentElement||this))}updateCanvasSize(){if(!this.canvas)return;const t=window.devicePixelRatio||1;let e=this.clientWidth,i=this.clientHeight;if(this.fullscreen||0===e||0===i){const t=this.parentElement;t&&!this.fullscreen?(e=t.clientWidth,i=t.clientHeight):(e=window.innerWidth,i=window.innerHeight)}0===e&&(e=300),0===i&&(i=300),this.canvas.width=e*t,this.canvas.height=i*t,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${i}px`,this.ctx&&(this.ctx.resetTransform?.(),this.ctx.scale(t,t))}sync(){this.fullscreen?this.classList.add(`${r}--fullscreen`):this.classList.remove(`${r}--fullscreen`),e.forEach(t=>this.classList.remove(`${r}--${t}`)),this.classList.add(`${r}--${this.mode}`)}fire(t){if(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches&&!1!==t?.disableForReducedMotion)return;this.updateCanvasSize();const e=this.canvas?this.canvas.width/(window.devicePixelRatio||1):400,i=this.canvas?this.canvas.height/(window.devicePixelRatio||1):400,s=this.fullscreen||this.parentElement===document.body||this.parentElement===document.documentElement||e>=window.innerWidth-30&&i>=window.innerHeight-30,r=s?1:Math.min(1,Math.max(.18,i/750)),a=s?1:Math.min(1,Math.max(.22,e/900)),n=Math.min(r,a),o=s?1:Math.max(.18,Math.min(1,.62*r+.04)),l=s?1:Math.max(.26,Math.min(1,.7*r+.15)),c=s?1:Math.max(.35,Math.min(1,.6*r+.25)),h=s?1:Math.max(.7,Math.min(1,.68+.32*n)),d=t?.particleCount??this.particleCount,f=t?.angle??90,u=t?.spread??this.spread,g=(t?.startVelocity??58)*o,m=t?.decay??(s?.925:Math.max(.91,.925-.015*(1-r))),p=(t?.gravity??.42)*l,b=(t?.drift??0)*(s?1:a),v=t?.ticks??380,w=s?v:Math.round(v*(.65+.35*n)),y=t?.colors??paletteColors(t?.palette)??this.colors,k=t?.shapes??this.shapes,x=(t?.scalar??1)*h,M=(t?.origin?.x??this.originX)*e,C=(t?.origin?.y??this.originY)*i,A=f*Math.PI/180,R=u*Math.PI/180;for(let t=0;t<d;t++){const t=A+(Math.random()-.5)*R,e=g*randomRange(.65,1.35),i=y[Math.floor(Math.random()*y.length)],r=k[Math.floor(Math.random()*k.length)],a=m*randomRange(.99,1.01),o=p*randomRange(.85,1.15),l=randomRange(2.2,4.2)*x*c,h=randomRange(.8,2.2)*(s?1:Math.max(.5,1.2*n)),d=Math.floor(w*randomRange(.85,1.25));this.particles.push({x:M,y:C,vx:Math.cos(t)*e,vy:-Math.sin(t)*e,w:randomRange(5,9)*x,h:("circle"===r?randomRange(5,9):randomRange(9,15))*x,color:i,shape:r,angle:360*Math.random(),rotationSpeed:randomRange(-4.5,4.5),wobble:10*Math.random(),wobbleSpeed:randomRange(.06,.14),opacity:1,gravity:o,drag:a,drift:b,maxFallSpeed:l,flutterStrength:h,tick:0,totalTicks:d,scalar:x})}null===this.animationId&&this.loop()}fireworks(t){const e=t?.duration??(this.duration||3500),i=t?.interval??320,s=Date.now()+e;null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null);const runBurst=()=>{if(Date.now()>s)return void(null!==this.fireworkTimer&&(clearInterval(this.fireworkTimer),this.fireworkTimer=null));const e=t?.particleCount??Math.floor(randomRange(30,50));this.fire({particleCount:e,startVelocity:42,spread:360,ticks:280,origin:{x:randomRange(.15,.85),y:randomRange(.12,.45)},colors:t?.colors??paletteColors(t?.palette)??this.colors})};runBurst(),this.fireworkTimer=window.setInterval(runBurst,i)}cannon(t){this.fire({particleCount:this.particleCount,angle:90,spread:75,startVelocity:58,ticks:380,origin:{x:.5,y:.85},...t})}stars(t){this.fire({particleCount:45,spread:360,ticks:260,gravity:.25,decay:.94,startVelocity:38,shapes:["star"],colors:t?.colors??paletteColors(t?.palette)??a.gold,scalar:1.2})}pride(t){const e=t?.colors??paletteColors(t?.palette)??["#e45757","#f0a04b","#f0d35a","#4fae7b","#5b82e6","#8a63c9"];this.fire({particleCount:48,angle:60,spread:60,startVelocity:56,ticks:380,origin:{x:0,y:.85},colors:e}),this.fire({particleCount:48,angle:120,spread:60,startVelocity:56,ticks:380,origin:{x:1,y:.85},colors:e})}snow(){this.fire({particleCount:50,angle:270,spread:180,startVelocity:14,gravity:.18,drift:randomRange(-.3,.3),ticks:450,shapes:["circle"],colors:["#ffffff","#e2e8f0","#93c5fd"],origin:{x:randomRange(.1,.9),y:-.05},scalar:.8})}fireByMode(){switch(this.mode){case"fireworks":this.fireworks();break;case"stars":this.stars();break;case"pride":this.pride();break;case"snow":this.snow();break;default:this.cannon()}}drawStar(t,e,i,s,r,a){let n=Math.PI/2*3,o=e,l=i;const c=Math.PI/s;t.beginPath(),t.moveTo(e,i-r);for(let h=0;h<s;h++)o=e+Math.cos(n)*r,l=i+Math.sin(n)*r,t.lineTo(o,l),n+=c,o=e+Math.cos(n)*a,l=i+Math.sin(n)*a,t.lineTo(o,l),n+=c;t.lineTo(e,i-r),t.closePath(),t.fill()}}customElements.get("db-confetti")||customElements.define("db-confetti",DbConfetti);let l=null;function getGlobalConfetti(){return l&&l.isConnected||(l=document.createElement("db-confetti"),l.setAttribute("fullscreen",""),document.body.appendChild(l)),l}const c=Object.assign(t=>{getGlobalConfetti().fire(t)},{fireworks:t=>{getGlobalConfetti().fireworks(t)},cannon:t=>{getGlobalConfetti().cannon(t)},stars:t=>{getGlobalConfetti().stars(t)},pride:t=>{getGlobalConfetti().pride(t)},snow:()=>{getGlobalConfetti().snow()}});export{a as CONFETTI_PALETTES,DbConfetti,c as confetti};
|
|
@@ -4,34 +4,53 @@ import './db-otp-input.js';
|
|
|
4
4
|
import { EMAIL_VERIFY_SIZES } from '../ui-contracts/dist/components.d.js';
|
|
5
5
|
|
|
6
6
|
type Size = (typeof EMAIL_VERIFY_SIZES)[number];
|
|
7
|
+
type Step = 'email' | 'code' | 'sent' | 'verified';
|
|
7
8
|
declare class DbEmailVerify extends HTMLElement {
|
|
8
9
|
static get observedAttributes(): string[];
|
|
9
10
|
private built;
|
|
10
11
|
private timerId;
|
|
12
|
+
/** 인증번호 유효 시간(초) — code 모드에서만 쓴다 */
|
|
11
13
|
private remaining;
|
|
14
|
+
/** 재전송 버튼이 다시 열리기까지 남은 시간(초) */
|
|
15
|
+
private cooldownLeft;
|
|
16
|
+
private expired;
|
|
17
|
+
private eyebrowEl;
|
|
18
|
+
private headerEl;
|
|
19
|
+
private titleEl;
|
|
20
|
+
private descEl;
|
|
12
21
|
private emailInput;
|
|
13
22
|
private sendBtn;
|
|
14
23
|
private otpInput;
|
|
15
24
|
private timerEl;
|
|
16
|
-
private
|
|
25
|
+
private expiredEl;
|
|
26
|
+
private codeResendBtn;
|
|
27
|
+
private codeChangeBtn;
|
|
17
28
|
private verifyBtn;
|
|
18
29
|
private confirmBtn;
|
|
30
|
+
private doneBtn;
|
|
31
|
+
private sentResendBtn;
|
|
32
|
+
private sentChangeBtn;
|
|
33
|
+
private sentDescEl;
|
|
34
|
+
private verifiedDescEl;
|
|
19
35
|
private codeBlock;
|
|
20
|
-
private
|
|
36
|
+
private sentBlock;
|
|
21
37
|
private verifiedBlock;
|
|
22
38
|
private emailRow;
|
|
23
39
|
private errorEl;
|
|
24
|
-
private closeBtn
|
|
40
|
+
private closeBtn;
|
|
25
41
|
get mode(): 'code' | 'confirm';
|
|
26
42
|
set mode(v: 'code' | 'confirm');
|
|
27
43
|
get size(): Size;
|
|
28
44
|
set size(v: Size);
|
|
29
|
-
get step():
|
|
30
|
-
set step(v:
|
|
45
|
+
get step(): Step;
|
|
46
|
+
set step(v: Step);
|
|
31
47
|
get email(): string;
|
|
32
48
|
set email(v: string);
|
|
33
49
|
get countdown(): number;
|
|
34
50
|
set countdown(v: number);
|
|
51
|
+
/** 재전송을 다시 누를 수 있기까지 기다리는 시간(초). 기본 30초. 0이면 바로 누를 수 있다. */
|
|
52
|
+
get resendCooldown(): number;
|
|
53
|
+
set resendCooldown(v: number);
|
|
35
54
|
connectedCallback(): void;
|
|
36
55
|
disconnectedCallback(): void;
|
|
37
56
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
@@ -40,14 +59,24 @@ declare class DbEmailVerify extends HTMLElement {
|
|
|
40
59
|
restartCountdown(): void;
|
|
41
60
|
markSent(): void;
|
|
42
61
|
markVerified(): void;
|
|
62
|
+
/** 이메일 입력 단계로 돌아갑니다 (입력한 코드는 지웁니다). */
|
|
63
|
+
editEmail(): void;
|
|
64
|
+
private startTimersForStep;
|
|
43
65
|
private clearTimer;
|
|
44
|
-
private
|
|
66
|
+
private startTimers;
|
|
45
67
|
private renderTimer;
|
|
68
|
+
private syncVerifyDisabled;
|
|
69
|
+
private emit;
|
|
70
|
+
private handleResend;
|
|
71
|
+
private handleChangeEmail;
|
|
46
72
|
private build;
|
|
73
|
+
private buildFooter;
|
|
47
74
|
private sync;
|
|
48
75
|
private isEmailValid;
|
|
76
|
+
private requestSend;
|
|
49
77
|
private requestVerify;
|
|
50
|
-
|
|
78
|
+
/** 번역 문장 안의 {0} 자리에 이메일을 굵게 넣는다 — 언어마다 어순이 달라 조각내 번역하지 않는다. */
|
|
79
|
+
private setTextWithEmail;
|
|
51
80
|
}
|
|
52
81
|
declare global {
|
|
53
82
|
interface HTMLElementTagNameMap {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbFormat as t,dbText as e}from"../core/i18n.js";import{createDbIcon as i}from"./db-icons.js";import"./db-button.js";import"./db-input.js";import"./db-otp-input.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{EMAIL_VERIFY_SIZES as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}class DbEmailVerify extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.timerId=null,this.remaining=0}static get observedAttributes(){return["mode","email","code","step","size","disabled","error","error-message","countdown","title","description","send-label","resend-label","verify-label","confirm-label","code-length","closable","manual","sending","verifying","auto-submit"]}get mode(){return"confirm"===this.getAttribute("mode")?"confirm":"code"}set mode(t){this.setAttribute("mode",t)}get size(){return s(this.getAttribute("size"),n,"m")}set size(t){this.setAttribute("size",t)}get step(){const t=this.getAttribute("step");return"code"===t||"sent"===t||"verified"===t?t:"email"}set step(t){this.setAttribute("step",t)}get email(){return this.getAttribute("email")||""}set email(t){this.setAttribute("email",t)}get countdown(){const t=Number(this.getAttribute("countdown")||180);return Number.isFinite(t)&&t>0?t:180}set countdown(t){this.setAttribute("countdown",String(t))}connectedCallback(){this.build(),this.sync(),"code"===this.mode&&"code"===this.step&&this.startTimer(this.countdown)}disconnectedCallback(){this.clearTimer()}attributeChangedCallback(t,e,i){this.built&&(this.sync(),"step"!==t&&"mode"!==t||e===i||("code"===this.mode&&"code"===this.step?this.startTimer(this.countdown):this.clearTimer()))}startCodeStep(){"code"!==this.mode&&(this.mode="code"),"code"===this.step?this.startTimer(this.countdown):this.step="code",requestAnimationFrame(()=>this.otpInput?.focus?.())}restartCountdown(){"code"===this.mode&&"code"===this.step&&this.startTimer(this.countdown)}markSent(){this.step="sent",this.clearTimer()}markVerified(){this.step="verified",this.clearTimer()}clearTimer(){this.timerId&&clearInterval(this.timerId),this.timerId=null,this.remaining=0}startTimer(t){this.clearTimer(),this.remaining=t,this.renderTimer(),this.timerId=setInterval(()=>{this.remaining-=1,this.renderTimer(),this.remaining<=0&&(this.clearTimer(),this.resendBtn.disabled=!1,this.dispatchEvent(new CustomEvent("db-countdown-complete",{bubbles:!0,composed:!0})))},1e3)}renderTimer(){const e=Math.max(0,Math.floor(this.remaining/60)),i=Math.max(0,this.remaining%60);this.timerEl.textContent=`${String(e).padStart(2,"0")}:${String(i).padStart(2,"0")}`,this.timerEl.setAttribute("aria-label",t("남은 시간 {0}분 {1}초",[e,i])),this.resendBtn.disabled=this.remaining>0||this.hasAttribute("disabled")}build(){if(this.built)return;this.built=!0;const t="designbase-wc-email-verify";this.replaceChildren();const s=el("div",`${t}__shell`),n=el("div",`${t}__top`),r=el("span",`${t}__eyebrow`);r.dataset.role="eyebrow",this.closeBtn=el("button",`${t}__close`),this.closeBtn.type="button",this.closeBtn.setAttribute("aria-label",e("닫기")),this.closeBtn.append(i("close",18)),this.closeBtn.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-close",{bubbles:!0,composed:!0}))}),n.append(r,this.closeBtn);const o=el("div",`${t}__header`),d=el("h3",`${t}__title`);d.dataset.role="title";const a=el("p",`${t}__description`);a.dataset.role="description",o.append(d,a),this.emailRow=el("div",`${t}__email-row`),this.emailInput=document.createElement("db-input"),this.emailInput.setAttribute("type","email"),this.emailInput.setAttribute("label","이메일"),this.emailInput.setAttribute("placeholder","name@example.com"),this.emailInput.setAttribute("full-width",""),this.emailInput.setAttribute("start-icon","mail"),this.emailInput.addEventListener("db-input",t=>{t.stopPropagation();const e=String(t.detail?.value??this.emailInput.value??"");this.setAttribute("email",e),this.dispatchEvent(new CustomEvent("db-email-change",{detail:{email:e},bubbles:!0,composed:!0}))}),this.sendBtn=document.createElement("db-button"),this.sendBtn.setAttribute("variant","primary"),this.sendBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.isEmailValid()&&(this.dispatchEvent(new CustomEvent("db-send-code",{detail:{email:this.email,mode:this.mode},bubbles:!0,composed:!0})),this.hasAttribute("manual")||("confirm"===this.mode?this.markSent():this.startCodeStep()))}),this.emailRow.append(this.emailInput,this.sendBtn),this.codeBlock=el("div",`${t}__code`);const l=el("div",`${t}__code-head`),h=el("span",`${t}__code-label`);h.textContent=e("인증 코드"),this.timerEl=el("span",`${t}__timer`),l.append(h,this.timerEl),this.otpInput=document.createElement("db-otp-input"),this.otpInput.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.setAttribute("code",e),this.dispatchEvent(new CustomEvent("db-code-change",{detail:{code:e},bubbles:!0,composed:!0}))}),this.otpInput.addEventListener("db-complete",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.dispatchEvent(new CustomEvent("db-code-complete",{detail:{code:e,email:this.email},bubbles:!0,composed:!0})),this.hasAttribute("auto-submit")&&this.requestVerify()});const c=el("div",`${t}__code-actions`);this.resendBtn=el("button",`${t}__resend`),this.resendBtn.type="button",this.resendBtn.addEventListener("click",()=>{this.resendBtn.disabled||(this.dispatchEvent(new CustomEvent("db-resend",{detail:{email:this.email},bubbles:!0,composed:!0})),this.hasAttribute("manual")||this.startTimer(this.countdown))}),this.verifyBtn=document.createElement("db-button"),this.verifyBtn.setAttribute("variant","primary"),this.verifyBtn.setAttribute("full-width",""),this.verifyBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.requestVerify()}),c.append(this.resendBtn,this.verifyBtn),this.codeBlock.append(l,this.otpInput,c),this.confirmBlock=el("div",`${t}__confirm`);const m=el("div",`${t}__confirm-icon`);m.append(i("mail",40));const u=el("span",`${t}__confirm-badge`);u.append(i("circle-checked",16)),m.append(u);const b=el("h4",`${t}__confirm-title`);b.dataset.role="confirm-title";const p=el("p",`${t}__confirm-desc`);p.dataset.role="confirm-desc",this.confirmBtn=document.createElement("db-button"),this.confirmBtn.setAttribute("variant","primary"),this.confirmBtn.setAttribute("full-width",""),this.confirmBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.dispatchEvent(new CustomEvent("db-confirm",{detail:{email:this.email},bubbles:!0,composed:!0}))});const f=el("button",`${t}__resend`);f.type="button",f.dataset.role="confirm-resend",f.addEventListener("click",()=>{this.dispatchEvent(new CustomEvent("db-resend",{detail:{email:this.email},bubbles:!0,composed:!0}))}),this.confirmBlock.append(m,b,p,this.confirmBtn,f),this.verifiedBlock=el("div",`${t}__confirm`);const v=el("div",`${t}__confirm-icon`);v.append(i("circle-checked",40));const g=el("h4",`${t}__confirm-title`);g.textContent=e("이메일 인증 완료");const A=el("p",`${t}__confirm-desc`);A.dataset.role="verified-desc",this.verifiedBlock.append(v,g,A),this.errorEl=el("p",`${t}__error`),this.errorEl.hidden=!0,s.append(n,o,this.emailRow,this.codeBlock,this.confirmBlock,this.verifiedBlock,this.errorEl),this.append(s)}sync(){const t="designbase-wc-email-verify",i=this.size,s=this.mode,n=this.step,r=this.hasAttribute("disabled"),o=this.getAttribute("code-length")||"6",d=this.email;this.className=[t,`${t}--${i}`,`${t}--mode-${s}`,`${t}--step-${n}`,r&&`${t}--disabled`,this.hasAttribute("error")&&`${t}--error`].filter(Boolean).join(" "),this.emailInput?.toggleAttribute("error",this.hasAttribute("error"));this.querySelector('[data-role="eyebrow"]').textContent="confirm"===s?"회원가입":"이메일 인증";const a=this.querySelector('[data-role="title"]'),l=this.querySelector('[data-role="description"]');a.textContent=this.getAttribute("title")||("confirm"===s?"이메일을 확인해 주세요":"이메일 인증");const h=this.getAttribute("description");h?l.textContent=h:"confirm"===s?this.setEmphasizedText(l,"",d||"your@email.com"," 으로 인증 링크를 보냈어요."):this.setEmphasizedText(l,"인증 코드를 ",d||"이메일"," 로 보내 드릴게요."),this.closeBtn&&(this.closeBtn.hidden=!this.hasAttribute("closable")),this.emailInput.value=d,this.emailInput.setAttribute("size",i),this.emailInput.toggleAttribute("disabled",r||"code"===n||"sent"===n||"verified"===n),this.sendBtn.setAttribute("size",i),this.sendBtn.textContent=this.getAttribute("send-label")||("confirm"===s?"인증 메일 보내기":"인증번호 받기"),this.sendBtn.toggleAttribute("disabled",r||!this.isEmailValid()||"email"!==n),this.sendBtn.toggleAttribute("loading",this.hasAttribute("sending")),this.otpInput.setAttribute("length",o),this.otpInput.setAttribute("size",i),this.otpInput.setAttribute("value",this.getAttribute("code")||""),this.otpInput.toggleAttribute("disabled",r||"code"!==n),this.resendBtn.textContent=this.getAttribute("resend-label")||"재전송",this.verifyBtn.setAttribute("size",i),this.verifyBtn.textContent=this.getAttribute("verify-label")||"인증하기",this.verifyBtn.toggleAttribute("disabled",r||"code"!==n||(this.getAttribute("code")||"").length!==Number(o)),this.verifyBtn.toggleAttribute("loading",this.hasAttribute("verifying"));const c=this.querySelector('[data-role="confirm-title"]'),m=this.querySelector('[data-role="confirm-desc"]');c.textContent=e("메일함을 확인해 주세요!"),this.setEmphasizedText(m,"",d||"your@email.com"," 으로 보낸 링크를 클릭하면 인증이 완료됩니다."),this.confirmBtn.setAttribute("size",i),this.confirmBtn.textContent=this.getAttribute("confirm-label")||"확인";const u=this.querySelector('[data-role="confirm-resend"]');u&&(u.textContent=e("메일 다시 보내기"));const b=this.querySelector('[data-role="verified-desc"]');this.setEmphasizedText(b,"",d||"your@email.com"," 주소가 인증되었습니다."),this.emailRow.hidden="confirm"===s&&("sent"===n||"verified"===n)||"code"===s&&"verified"===n,this.codeBlock.hidden=!("code"===s&&"code"===n),this.confirmBlock.hidden=!("confirm"===s&&("sent"===n||"verified"===n)),this.verifiedBlock.hidden=!("code"===s&&"verified"===n);const p=this.getAttribute("error-message")||"";this.errorEl.textContent=p,this.errorEl.hidden=!this.hasAttribute("error")||!p}isEmailValid(){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email.trim())}requestVerify(){const t=(this.getAttribute("code")||this.otpInput.value).replace(/\D/g,""),e=Number(this.getAttribute("code-length")||6);"code"!==this.step||t.length!==e||this.hasAttribute("disabled")||this.dispatchEvent(new CustomEvent("db-verify",{detail:{email:this.email,code:t},bubbles:!0,composed:!0}))}setEmphasizedText(t,e,i,s){const n=document.createElement("strong");n.textContent=i,t.replaceChildren(document.createTextNode(e),n,document.createTextNode(s))}}customElements.get("db-email-verify")||customElements.define("db-email-verify",DbEmailVerify);export{DbEmailVerify};
|
|
1
|
+
import{dbFormat as t,dbText as e}from"../core/i18n.js";import{createDbIcon as i}from"./db-icons.js";import"./db-button.js";import"./db-input.js";import"./db-otp-input.js";import{coerceToContract as s}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{EMAIL_VERIFY_SIZES as n}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function el(t,e){const i=document.createElement(t);return e&&(i.className=e),i}function textButton(t,e){const i=el("button",t);return i.type="button",i.addEventListener("click",()=>{i.disabled||e()}),i}class DbEmailVerify extends HTMLElement{constructor(){super(...arguments),this.built=!1,this.timerId=null,this.remaining=0,this.cooldownLeft=0,this.expired=!1}static get observedAttributes(){return["mode","email","code","step","size","disabled","error","error-message","countdown","resend-cooldown","eyebrow","title","description","send-label","resend-label","verify-label","confirm-label","done-label","code-length","closable","manual","sending","verifying","auto-submit"]}get mode(){return"confirm"===this.getAttribute("mode")?"confirm":"code"}set mode(t){this.setAttribute("mode",t)}get size(){return s(this.getAttribute("size"),n,"m")}set size(t){this.setAttribute("size",t)}get step(){const t=this.getAttribute("step");return"code"===t||"sent"===t||"verified"===t?t:"email"}set step(t){this.setAttribute("step",t)}get email(){return this.getAttribute("email")||""}set email(t){this.setAttribute("email",t)}get countdown(){const t=Number(this.getAttribute("countdown")||180);return Number.isFinite(t)&&t>0?t:180}set countdown(t){this.setAttribute("countdown",String(t))}get resendCooldown(){const t=this.getAttribute("resend-cooldown"),e=Number(t??30);return Number.isFinite(e)&&e>=0?e:30}set resendCooldown(t){this.setAttribute("resend-cooldown",String(t))}connectedCallback(){this.build(),this.sync(),this.startTimersForStep()}disconnectedCallback(){this.clearTimer()}attributeChangedCallback(t,e,i){this.built&&("step"!==t&&"mode"!==t||e===i||this.startTimersForStep(),this.sync())}startCodeStep(){"code"!==this.mode&&(this.mode="code"),"code"===this.step?this.startTimers():this.step="code",requestAnimationFrame(()=>this.otpInput?.focus?.())}restartCountdown(){"code"!==this.step&&"sent"!==this.step||this.startTimers()}markSent(){this.step="sent"}markVerified(){this.step="verified"}editEmail(){this.removeAttribute("code"),this.step="email",requestAnimationFrame(()=>this.emailInput?.focus?.())}startTimersForStep(){const t=this.step;"code"===this.mode&&"code"===t||"confirm"===this.mode&&"sent"===t?this.startTimers():this.clearTimer()}clearTimer(){this.timerId&&clearInterval(this.timerId),this.timerId=null,this.remaining=0,this.cooldownLeft=0,this.expired=!1}startTimers(){this.clearTimer();const t="code"===this.mode;this.remaining=t?this.countdown:0,this.cooldownLeft=t?Math.min(this.resendCooldown,this.countdown):this.resendCooldown,this.renderTimer(),this.remaining<=0&&this.cooldownLeft<=0||(this.timerId=setInterval(()=>{this.cooldownLeft>0&&(this.cooldownLeft-=1),this.remaining>0&&(this.remaining-=1,this.remaining<=0&&(this.expired=!0,this.cooldownLeft=0,this.dispatchEvent(new CustomEvent("db-countdown-complete",{bubbles:!0,composed:!0})))),this.renderTimer(),this.remaining<=0&&this.cooldownLeft<=0&&this.timerId&&(clearInterval(this.timerId),this.timerId=null)},1e3))}renderTimer(){if(!this.built)return;const i=Math.max(0,Math.floor(this.remaining/60)),s=Math.max(0,this.remaining%60);this.timerEl.textContent=`${String(i).padStart(2,"0")}:${String(s).padStart(2,"0")}`,this.timerEl.setAttribute("aria-label",t("남은 시간 {0}분 {1}초",[i,s])),this.timerEl.classList.toggle("designbase-wc-email-verify__timer--expired",this.expired),this.expiredEl.hidden=!this.expired;const n=this.hasAttribute("disabled"),r=this.cooldownLeft>0,o=this.getAttribute("resend-label")||e("재전송"),l=r?t("재전송 ({0}초)",[this.cooldownLeft]):o;for(const t of[this.codeResendBtn,this.sentResendBtn])t.textContent=l,t.disabled=r||n;this.syncVerifyDisabled()}syncVerifyDisabled(){const t=Number(this.getAttribute("code-length")||6);this.verifyBtn.toggleAttribute("disabled",this.hasAttribute("disabled")||"code"!==this.step||this.expired||(this.getAttribute("code")||"").length!==t)}emit(t,e={}){this.dispatchEvent(new CustomEvent(t,{detail:e,bubbles:!0,composed:!0}))}handleResend(){this.emit("db-resend",{email:this.email,mode:this.mode}),this.hasAttribute("manual")||(this.removeAttribute("code"),this.startTimers())}handleChangeEmail(){this.emit("db-change-email",{email:this.email}),this.hasAttribute("manual")||this.editEmail()}build(){if(this.built)return;this.built=!0;const t="designbase-wc-email-verify";this.replaceChildren();const s=el("div",`${t}__shell`);this.closeBtn=el("button",`${t}__close`),this.closeBtn.type="button",this.closeBtn.setAttribute("aria-label",e("닫기")),this.closeBtn.append(i("close",18)),this.closeBtn.addEventListener("click",()=>this.emit("db-close")),this.headerEl=el("div",`${t}__header`),this.eyebrowEl=el("span",`${t}__eyebrow`),this.titleEl=el("h3",`${t}__title`),this.descEl=el("p",`${t}__description`),this.headerEl.append(this.eyebrowEl,this.titleEl,this.descEl),this.emailRow=el("div",`${t}__email-row`),this.emailInput=document.createElement("db-input"),this.emailInput.setAttribute("type","email"),this.emailInput.setAttribute("placeholder","name@example.com"),this.emailInput.setAttribute("autocomplete","email"),this.emailInput.setAttribute("full-width",""),this.emailInput.setAttribute("start-icon","mail"),this.emailInput.addEventListener("db-input",t=>{t.stopPropagation();const e=String(t.detail?.value??this.emailInput.value??"");this.setAttribute("email",e),this.emit("db-email-change",{email:e})}),this.emailInput.addEventListener("keydown",t=>{"Enter"===t.key&&this.requestSend()}),this.sendBtn=document.createElement("db-button"),this.sendBtn.setAttribute("variant","primary"),this.sendBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.requestSend()}),this.emailRow.append(this.emailInput,this.sendBtn),this.codeBlock=el("div",`${t}__code`);const n=el("div",`${t}__code-head`),r=el("span",`${t}__code-label`);r.dataset.role="code-label",this.timerEl=el("span",`${t}__timer`),this.timerEl.setAttribute("role","timer"),n.append(r,this.timerEl),this.otpInput=document.createElement("db-otp-input"),this.otpInput.setAttribute("full-width",""),this.otpInput.addEventListener("db-change",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.setAttribute("code",e),this.emit("db-code-change",{code:e})}),this.otpInput.addEventListener("db-complete",t=>{t.stopPropagation();const e=String(t.detail?.value||"");this.emit("db-code-complete",{code:e,email:this.email}),this.hasAttribute("auto-submit")&&this.requestVerify()}),this.expiredEl=el("p",`${t}__expired`),this.expiredEl.setAttribute("role","alert"),this.expiredEl.hidden=!0,this.verifyBtn=document.createElement("db-button"),this.verifyBtn.setAttribute("variant","primary"),this.verifyBtn.setAttribute("full-width",""),this.verifyBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.requestVerify()}),this.codeResendBtn=textButton(`${t}__link`,()=>this.handleResend()),this.codeChangeBtn=textButton(`${t}__link ${t}__link--muted`,()=>this.handleChangeEmail());const o=this.buildFooter(this.codeResendBtn,this.codeChangeBtn);this.codeBlock.append(n,this.otpInput,this.expiredEl,this.verifyBtn,o),this.sentBlock=el("div",`${t}__result`);const l=el("div",`${t}__result-icon`);l.append(i("mail",36));const d=el("h3",`${t}__result-title`);d.dataset.role="sent-title",this.sentDescEl=el("p",`${t}__result-desc`),this.confirmBtn=document.createElement("db-button"),this.confirmBtn.setAttribute("variant","primary"),this.confirmBtn.setAttribute("full-width",""),this.confirmBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.emit("db-confirm",{email:this.email})}),this.sentResendBtn=textButton(`${t}__link`,()=>this.handleResend()),this.sentChangeBtn=textButton(`${t}__link ${t}__link--muted`,()=>this.handleChangeEmail());const h=this.buildFooter(this.sentResendBtn,this.sentChangeBtn);this.sentBlock.append(l,d,this.sentDescEl,this.confirmBtn,h),this.verifiedBlock=el("div",`${t}__result ${t}__result--success`);const a=el("div",`${t}__result-icon`);a.append(i("circle-checked",36));const c=el("h3",`${t}__result-title`);c.dataset.role="verified-title",this.verifiedDescEl=el("p",`${t}__result-desc`),this.doneBtn=document.createElement("db-button"),this.doneBtn.setAttribute("variant","primary"),this.doneBtn.setAttribute("full-width",""),this.doneBtn.addEventListener("db-click",t=>{t.stopPropagation(),this.emit("db-done",{email:this.email})}),this.verifiedBlock.append(a,c,this.verifiedDescEl,this.doneBtn),this.errorEl=el("p",`${t}__error`),this.errorEl.setAttribute("role","alert"),this.errorEl.hidden=!0,s.append(this.closeBtn,this.headerEl,this.emailRow,this.errorEl,this.codeBlock,this.sentBlock,this.verifiedBlock),this.append(s)}buildFooter(t,e){const i="designbase-wc-email-verify",s=el("div",`${i}__footer`),n=el("span",`${i}__footer-resend`),r=el("span",`${i}__footer-hint`);return r.dataset.role="resend-hint",n.append(r,t),s.append(n,e),s}sync(){const t="designbase-wc-email-verify",i=this.size,s=this.mode,n=this.step,r=this.hasAttribute("disabled"),o=this.getAttribute("code-length")||"6",l=this.email,d=l||"your@email.com",h="confirm"===s&&"code"===n?"email":"code"===s&&"sent"===n?"code":n,a="sent"===h||"verified"===h;this.className=[t,`${t}--${i}`,`${t}--mode-${s}`,`${t}--step-${h}`,this.hasAttribute("closable")&&`${t}--closable`,r&&`${t}--disabled`,this.hasAttribute("error")&&`${t}--error`].filter(Boolean).join(" "),this.emailInput.toggleAttribute("error",this.hasAttribute("error")&&"email"===h),this.closeBtn.hidden=!this.hasAttribute("closable"),this.headerEl.hidden=a;const c=this.getAttribute("eyebrow")||"";this.eyebrowEl.textContent=c,this.eyebrowEl.hidden=!c,"code"===h?(this.titleEl.textContent=e("인증번호를 입력해 주세요"),this.setTextWithEmail(this.descEl,"{0} 주소로 {1}자리 인증번호를 보냈어요.",d,[o])):(this.titleEl.textContent=this.getAttribute("title")||e("이메일 인증"),this.descEl.textContent=this.getAttribute("description")||e("confirm"===s?"인증받을 이메일 주소를 입력해 주세요. 입력한 주소로 인증 링크를 보내 드려요.":"인증받을 이메일 주소를 입력해 주세요. 입력한 주소로 인증번호를 보내 드려요.")),this.emailRow.hidden="email"!==h,this.emailInput.setAttribute("label",e("이메일 주소")),this.emailInput.value=l,this.emailInput.setAttribute("size",i),this.emailInput.toggleAttribute("disabled",r),this.sendBtn.setAttribute("size",i),this.sendBtn.textContent=this.getAttribute("send-label")||e("confirm"===s?"인증 메일 보내기":"인증번호 받기"),this.sendBtn.toggleAttribute("disabled",r||!this.isEmailValid()),this.sendBtn.toggleAttribute("loading",this.hasAttribute("sending")),this.codeBlock.hidden="code"!==h;this.querySelector('[data-role="code-label"]').textContent=e("인증번호"),this.otpInput.setAttribute("length",o),this.otpInput.setAttribute("size",i),this.otpInput.setAttribute("value",this.getAttribute("code")||""),this.otpInput.toggleAttribute("disabled",r||"code"!==h||this.expired),this.otpInput.toggleAttribute("error",this.hasAttribute("error")&&"code"===h),this.expiredEl.textContent=e("인증 시간이 만료되었어요. 인증번호를 다시 받아 주세요."),this.verifyBtn.setAttribute("size",i),this.verifyBtn.textContent=this.getAttribute("verify-label")||e("인증하기"),this.verifyBtn.toggleAttribute("loading",this.hasAttribute("verifying")),this.sentBlock.hidden="sent"!==h,this.querySelector('[data-role="sent-title"]').textContent=e("메일함을 확인해 주세요"),this.setTextWithEmail(this.sentDescEl,"{0} 주소로 인증 링크를 보냈어요. 메일의 링크를 누르면 인증이 완료돼요.",d),this.confirmBtn.setAttribute("size",i),this.confirmBtn.textContent=this.getAttribute("confirm-label")||e("확인"),this.verifiedBlock.hidden="verified"!==h,this.querySelector('[data-role="verified-title"]').textContent=e("이메일 인증 완료"),this.setTextWithEmail(this.verifiedDescEl,"{0} 주소가 인증되었어요.",d),this.doneBtn.setAttribute("size",i),this.doneBtn.textContent=this.getAttribute("done-label")||e("확인"),this.querySelectorAll('[data-role="resend-hint"]').forEach(t=>{t.textContent=e("메일을 받지 못하셨나요?")});for(const t of[this.codeChangeBtn,this.sentChangeBtn])t.textContent=e("이메일 변경"),t.disabled=r;const m=this.getAttribute("error-message")||"";this.errorEl.textContent=m,this.errorEl.hidden=!this.hasAttribute("error")||!m||a;const u="code"===h?this.otpInput:this.emailRow;this.errorEl.previousElementSibling!==u&&u.after(this.errorEl),this.renderTimer()}isEmailValid(){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email.trim())}requestSend(){("email"===this.step||"confirm"===this.mode&&"code"===this.step)&&(this.hasAttribute("disabled")||this.hasAttribute("sending")||!this.isEmailValid()||(this.emit("db-send-code",{email:this.email,mode:this.mode}),this.hasAttribute("manual")||("confirm"===this.mode?this.markSent():this.startCodeStep())))}requestVerify(){const t=(this.getAttribute("code")||this.otpInput.value).replace(/\D/g,""),e=Number(this.getAttribute("code-length")||6);"code"!==this.step||this.expired||t.length!==e||this.hasAttribute("disabled")||this.emit("db-verify",{email:this.email,code:t})}setTextWithEmail(t,i,s,n=[]){const r=e(i).replace(/\{(\d+)\}/g,(t,e)=>"0"===e?t:String(n[Number(e)-1]??"")),[o,l=""]=r.split("{0}"),d=document.createElement("strong");d.textContent=s,t.replaceChildren(document.createTextNode(o),d,document.createTextNode(l))}}customElements.get("db-email-verify")||customElements.define("db-email-verify",DbEmailVerify);export{DbEmailVerify};
|
|
@@ -18,7 +18,7 @@ declare class DbFloatingActionButton extends DbButton {
|
|
|
18
18
|
set collapseThreshold(value: number);
|
|
19
19
|
connectedCallback(): void;
|
|
20
20
|
disconnectedCallback(): void;
|
|
21
|
-
attributeChangedCallback(name?: string): void;
|
|
21
|
+
attributeChangedCallback(name?: string, oldValue?: string | null, value?: string | null): void;
|
|
22
22
|
private syncFab;
|
|
23
23
|
private measureLabel;
|
|
24
24
|
private unbindScroll;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DbButton as t}from"./db-button.js";class DbFloatingActionButton extends t{constructor(){super(...arguments),this.scrollRoot=null,this.lastScroll=0,this.scrollCollapsed=!1,this.measureLabel=()=>{const t=this.querySelector(".designbase-wc-fab__label-text");this.style.setProperty("--db-fab-label-width",`${t?.scrollWidth||0}px`)},this.onScroll=()=>{const t=this.scrollPosition(),e=t-this.lastScroll;if(t<=this.collapseThreshold)this.scrollCollapsed=!1;else if(e>4)this.scrollCollapsed=!0;else{if(!(e<-4))return;this.scrollCollapsed=!1}this.lastScroll=t,this.classList.toggle("designbase-wc-fab--collapsed",this.collapsed||this.scrollCollapsed)}}static get observedAttributes(){return[...super.observedAttributes,"icon","label","collapsed","collapse-on-scroll","scroll-target","collapse-threshold"]}get label(){return this.getAttribute("label")||""}set label(t){this.setAttribute("label",t)}get collapsed(){return this.hasAttribute("collapsed")}set collapsed(t){this.toggleAttribute("collapsed",t)}get collapseOnScroll(){return this.hasAttribute("collapse-on-scroll")}set collapseOnScroll(t){this.toggleAttribute("collapse-on-scroll",t)}get collapseThreshold(){const t=Number(this.getAttribute("collapse-threshold")??24);return Number.isFinite(t)?Math.max(0,t):24}set collapseThreshold(t){this.setAttribute("collapse-threshold",String(t))}connectedCallback(){this.hasAttribute("radius")||(this.radius="pill"),this.syncFab(),super.connectedCallback(),this.labelObserver=new ResizeObserver(this.measureLabel);const t=this.querySelector(".designbase-wc-fab__label-text");t&&this.labelObserver.observe(t),this.bindScroll()}disconnectedCallback(){super.disconnectedCallback(),this.unbindScroll(),this.labelObserver?.disconnect(),this.labelObserver=void 0}attributeChangedCallback(t){super.attributeChangedCallback(),this.syncFab(),this.isConnected&&["collapse-on-scroll","scroll-target","collapse-threshold"].includes(t||"")&&this.bindScroll()}syncFab(){this.classList.add("designbase-wc-fab");const t=this.getAttribute("icon");if(t)this.mappedIcon=t,this.getAttribute("start-icon")!==t&&this.setAttribute("start-icon",t);else if(this.mappedIcon){const t=this.mappedIcon;this.mappedIcon=void 0,this.getAttribute("start-icon")===t&&this.removeAttribute("start-icon")}let e=this.querySelector(":scope > .designbase-wc-fab__label");if(!e){e=document.createElement("span"),e.className="designbase-wc-fab__label",e.setAttribute("aria-hidden","true");const t=document.createElement("span");t.className="designbase-wc-fab__label-text",e.append(t),this.append(e)}const l=e.firstElementChild;l.textContent!==this.label&&(l.textContent=this.label),!this.label||this.hasAttribute("aria-label")&&this.getAttribute("data-fab-auto-label")!==this.getAttribute("aria-label")||(this.setAttribute("aria-label",this.label),this.setAttribute("data-fab-auto-label",this.label)),this.hasAttribute("aria-label")||(this.setAttribute("aria-label","Floating action button"),this.setAttribute("data-fab-auto-label","Floating action button")),this.classList.toggle("designbase-wc-fab--extended",Boolean(this.label)),this.classList.toggle("designbase-wc-fab--collapsed",this.collapsed||this.scrollCollapsed),this.measureLabel()}unbindScroll(){this.scrollRoot?.removeEventListener("scroll",this.onScroll),this.scrollRoot=null}bindScroll(){if(this.unbindScroll(),this.scrollCollapsed=!1,this.collapseOnScroll){let t=null;const e=this.getAttribute("scroll-target");if(e)try{t=document.querySelector(e)}catch{}else for(let e=this.parentElement;e;e=e.parentElement)if(/(auto|scroll)/.test(getComputedStyle(e).overflowY)){t=e;break}this.scrollRoot=t||window,this.lastScroll=this.scrollPosition(),this.scrollCollapsed=this.lastScroll>this.collapseThreshold,this.scrollRoot.addEventListener("scroll",this.onScroll,{passive:!0})}this.syncFab()}scrollPosition(){return Math.max(0,this.scrollRoot instanceof HTMLElement?this.scrollRoot.scrollTop:window.scrollY)}}customElements.get("db-floating-action-button")||customElements.define("db-floating-action-button",DbFloatingActionButton);export{DbFloatingActionButton};
|
|
1
|
+
import{DbButton as t}from"./db-button.js";class DbFloatingActionButton extends t{constructor(){super(...arguments),this.scrollRoot=null,this.lastScroll=0,this.scrollCollapsed=!1,this.measureLabel=()=>{const t=this.querySelector(".designbase-wc-fab__label-text");this.style.setProperty("--db-fab-label-width",`${t?.scrollWidth||0}px`)},this.onScroll=()=>{const t=this.scrollPosition(),e=t-this.lastScroll;if(t<=this.collapseThreshold)this.scrollCollapsed=!1;else if(e>4)this.scrollCollapsed=!0;else{if(!(e<-4))return;this.scrollCollapsed=!1}this.lastScroll=t,this.classList.toggle("designbase-wc-fab--collapsed",this.collapsed||this.scrollCollapsed)}}static get observedAttributes(){return[...super.observedAttributes,"icon","label","collapsed","collapse-on-scroll","scroll-target","collapse-threshold"]}get label(){return this.getAttribute("label")||""}set label(t){this.setAttribute("label",t)}get collapsed(){return this.hasAttribute("collapsed")}set collapsed(t){this.toggleAttribute("collapsed",t)}get collapseOnScroll(){return this.hasAttribute("collapse-on-scroll")}set collapseOnScroll(t){this.toggleAttribute("collapse-on-scroll",t)}get collapseThreshold(){const t=Number(this.getAttribute("collapse-threshold")??24);return Number.isFinite(t)?Math.max(0,t):24}set collapseThreshold(t){this.setAttribute("collapse-threshold",String(t))}connectedCallback(){this.hasAttribute("radius")||(this.radius="pill"),this.syncFab(),super.connectedCallback(),this.labelObserver=new ResizeObserver(this.measureLabel);const t=this.querySelector(".designbase-wc-fab__label-text");t&&this.labelObserver.observe(t),this.bindScroll()}disconnectedCallback(){super.disconnectedCallback(),this.unbindScroll(),this.labelObserver?.disconnect(),this.labelObserver=void 0}attributeChangedCallback(t,e,l){t&&e===l||(super.attributeChangedCallback(t,e,l),this.syncFab(),this.isConnected&&["collapse-on-scroll","scroll-target","collapse-threshold"].includes(t||"")&&this.bindScroll())}syncFab(){this.classList.add("designbase-wc-fab");const t=this.getAttribute("icon");if(t)this.mappedIcon=t,this.getAttribute("start-icon")!==t&&this.setAttribute("start-icon",t);else if(this.mappedIcon){const t=this.mappedIcon;this.mappedIcon=void 0,this.getAttribute("start-icon")===t&&this.removeAttribute("start-icon")}let e=this.querySelector(":scope > .designbase-wc-fab__label");if(!e){e=document.createElement("span"),e.className="designbase-wc-fab__label",e.setAttribute("aria-hidden","true");const t=document.createElement("span");t.className="designbase-wc-fab__label-text",e.append(t),this.append(e)}const l=e.firstElementChild;l.textContent!==this.label&&(l.textContent=this.label),!this.label||this.hasAttribute("aria-label")&&this.getAttribute("data-fab-auto-label")!==this.getAttribute("aria-label")||(this.setAttribute("aria-label",this.label),this.setAttribute("data-fab-auto-label",this.label)),this.hasAttribute("aria-label")||(this.setAttribute("aria-label","Floating action button"),this.setAttribute("data-fab-auto-label","Floating action button")),this.classList.toggle("designbase-wc-fab--extended",Boolean(this.label)),this.classList.toggle("designbase-wc-fab--collapsed",this.collapsed||this.scrollCollapsed),this.measureLabel()}unbindScroll(){this.scrollRoot?.removeEventListener("scroll",this.onScroll),this.scrollRoot=null}bindScroll(){if(this.unbindScroll(),this.scrollCollapsed=!1,this.collapseOnScroll){let t=null;const e=this.getAttribute("scroll-target");if(e)try{t=document.querySelector(e)}catch{}else for(let e=this.parentElement;e;e=e.parentElement)if(/(auto|scroll)/.test(getComputedStyle(e).overflowY)){t=e;break}this.scrollRoot=t||window,this.lastScroll=this.scrollPosition(),this.scrollCollapsed=this.lastScroll>this.collapseThreshold,this.scrollRoot.addEventListener("scroll",this.onScroll,{passive:!0})}this.syncFab()}scrollPosition(){return Math.max(0,this.scrollRoot instanceof HTMLElement?this.scrollRoot.scrollTop:window.scrollY)}}customElements.get("db-floating-action-button")||customElements.define("db-floating-action-button",DbFloatingActionButton);export{DbFloatingActionButton};
|
|
@@ -3,6 +3,7 @@ declare class DbInput extends HTMLElement {
|
|
|
3
3
|
private shapeKey;
|
|
4
4
|
static get observedAttributes(): string[];
|
|
5
5
|
private input?;
|
|
6
|
+
private formState;
|
|
6
7
|
private passwordVisible;
|
|
7
8
|
private isFocused;
|
|
8
9
|
private touched;
|
|
@@ -10,6 +11,12 @@ declare class DbInput extends HTMLElement {
|
|
|
10
11
|
private detachScrub?;
|
|
11
12
|
get value(): string;
|
|
12
13
|
set value(value: string);
|
|
14
|
+
get defaultValue(): string;
|
|
15
|
+
set defaultValue(value: string);
|
|
16
|
+
get name(): string;
|
|
17
|
+
set name(value: string);
|
|
18
|
+
get required(): boolean;
|
|
19
|
+
set required(value: boolean);
|
|
13
20
|
get type(): string;
|
|
14
21
|
set type(value: string);
|
|
15
22
|
get size(): string;
|
|
@@ -21,7 +28,7 @@ declare class DbInput extends HTMLElement {
|
|
|
21
28
|
connectedCallback(): void;
|
|
22
29
|
disconnectedCallback(): void;
|
|
23
30
|
attributeChangedCallback(name: string): void;
|
|
24
|
-
focus(): void;
|
|
31
|
+
focus(options?: FocusOptions): void;
|
|
25
32
|
private get passwordMinLength();
|
|
26
33
|
private get validationVisibility();
|
|
27
34
|
private get validateOnBlur();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t,dbText as e}from"../core/i18n.js";import{getDbComponentIconSize as s,createDbIcon as i}from"./db-icons.js";import{getPasswordValidation as n}from"./input-validation.js";import{attachNumberScrub as a,readNumericAttribute as r}from"./number-scrub.js";import{dbUid as d}from"../core/uid.js";import{INPUT_TYPES as l,INPUT_SIZES as u}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const o=new Set(["arrow-bar-left","arrow-bar-right","caret-down-filled","chevron-down","chevron-left","chevron-right","circle-checked","close","error-filled","edit","hide","info-filled","lock","mail","plus","search","share-alt","show","sparkle","trash","user","warning-filled"]);class DbInput extends HTMLElement{constructor(){super(...arguments),this.shapeKey="",this.passwordVisible=!1,this.isFocused=!1,this.touched=!1,this.isScrubbing=!1,this.handleInput=t=>{t.stopPropagation();const e=t.target;this.updateDynamicUI(),this.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:e.value,nativeEvent:t},bubbles:!0,composed:!0}))},this.handleChange=t=>{t.stopPropagation();const e=t.target;this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e.value,nativeEvent:t},bubbles:!0,composed:!0}))},this.handleFocus=t=>{this.isFocused=!0,this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-focus",{detail:{nativeEvent:t},bubbles:!0,composed:!0}))},this.handleBlur=t=>{this.isFocused=!1,this.touched=!0,this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-blur",{detail:{nativeEvent:t},bubbles:!0,composed:!0}))},this.handlePasswordToggle=()=>{this.passwordVisible=!this.passwordVisible,this.render()},this.handleSearchClear=()=>{this.input&&(this.input.value="",this.setAttribute("value",""),this.input.focus(),this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:"",nativeEvent:null},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-clear",{bubbles:!0,composed:!0})))}}static get observedAttributes(){return["type","label","placeholder","value","default-value","size","disabled","readonly","required","error","error-message","helper-text","full-width","name","start-icon","end-icon","validate","validation-visibility","validate-on-blur","password-min-length","scrubbable","scrub-step","scrub-sensitivity","min","max","step"]}get value(){return this.input?.value??this.getAttribute("value")??""}set value(t){this.setAttribute("value",t),this.input&&(this.input.value=t),this.updateDynamicUI()}get type(){return this.getAttribute("type")||"text"}set type(t){this.setAttribute("type",t)}get size(){return this.getAttribute("size")||"m"}set size(t){this.setAttribute("size",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t)}connectedCallback(){this.render()}disconnectedCallback(){this.detachScrub?.(),this.detachScrub=void 0}attributeChangedCallback(t){if("value"!==t||!this.isScrubbing){if("value"===t&&this.input){const t=this.getAttribute("value")??"";return this.input.value!==t&&(this.input.value=t),void this.updateDynamicUI()}this.render()}}focus(){this.input?.focus()}get passwordMinLength(){return Number(this.getAttribute("password-min-length")||8)}get validationVisibility(){return this.getAttribute("validation-visibility")||"focus"}get validateOnBlur(){return!this.hasAttribute("validate-on-blur")||"false"!==this.getAttribute("validate-on-blur")}get isValidationEnabled(){return this.hasAttribute("validate")}getIconSize(){return s(this.size)}resolveIconName(t){const e=this.getAttribute(t);if(e&&o.has(e))return e}resolveStartIcon(){const t=this.resolveIconName("start-icon");return t||("search"===this.type?"search":void 0)}getCurrentValue(){return this.input?.value??this.getAttribute("value")??this.getAttribute("default-value")??""}buildStructure(t){const make=(t,e)=>{const s=document.createElement(t);return s.className=e,s},e=[];if(t.label){const s=document.createElement("label");s.className="designbase-wc-input__label",s.htmlFor=t.fieldId,e.push(s)}const s=make("span","designbase-wc-input__wrapper");if(t.startIcon){const t=make("span","designbase-wc-input__start-icon");t.setAttribute("aria-hidden","true"),s.append(t)}const i=document.createElement("input");if(i.className="designbase-wc-input__field",i.id=t.fieldId,s.append(i),t.isPassword){const t=document.createElement("button");t.type="button",t.className="designbase-wc-input__password-toggle",s.append(t)}if(t.isSearch){const t=document.createElement("button");t.type="button",t.className="designbase-wc-input__clear-button",t.hidden=!0,s.append(t)}if(t.endIcon&&!t.isPassword&&!t.isSearch){const t=make("span","designbase-wc-input__end-icon");t.setAttribute("aria-hidden","true"),s.append(t)}if(e.push(s),this.isValidationEnabled&&t.isPassword){const s=make("div","designbase-wc-input__validation-slot");s.id=t.validationId,e.push(s)}const n=make("p","designbase-wc-input__helper-text");n.id=t.helperId;const a=make("p","designbase-wc-input__error-message");a.id=t.errorId,e.push(n,a),this.replaceChildren(...e)}render(){const e=this.getCurrentValue(),s=l.includes(this.type)?this.type:"text",i="search"===s,n="password"===s,o=n&&this.passwordVisible||i?"text":s,c=this.getAttribute("label")||"",h=this.getAttribute("helper-text")||"",b=this.getAttribute("error-message")||"",p=this.hasAttribute("error"),g=this.resolveStartIcon(),w=this.resolveIconName("end-icon");this.classList.add("designbase-wc-input"),u.forEach(t=>this.classList.remove(`designbase-wc-input--${t}`)),this.classList.add(`designbase-wc-input--${u.includes(this.size)?this.size:"m"}`),this.classList.toggle("designbase-wc-input--error",p),this.classList.toggle("designbase-wc-input--disabled",this.disabled),this.classList.toggle("designbase-wc-input--readonly",this.readOnly),this.classList.toggle("designbase-wc-input--full-width",this.hasAttribute("full-width")),this.classList.toggle("designbase-wc-input--with-start-icon",Boolean(g));const v=i&&e.length>0&&!this.disabled&&!this.readOnly;this.classList.toggle("designbase-wc-input--with-end-icon",Boolean(w&&!n&&!i)||n||v),this.classList.toggle("designbase-wc-input--with-password-toggle",n),this.classList.toggle("designbase-wc-input--with-search-clear",v);const m=this.hasAttribute("scrubbable")&&"number"===s&&!this.disabled&&!this.readOnly;this.classList.toggle("designbase-wc-input--scrubbable",m),this.classList.toggle("designbase-wc-input--scrubbing",this.isScrubbing);const _=this.getAttribute("id")||d("db-input");this.hasAttribute("id")||this.setAttribute("id",_);const y=`${_}-field`,A=`${_}-helper`,f=`${_}-error`,S=`${_}-validation`,E=this.getAttribute("min"),I=this.getAttribute("max"),C=this.getAttribute("step"),q=[c?"L":"",g?"S":"",!w||n||i?"":"E",n?"P":"",i?"C":"",this.isValidationEnabled&&n?"V":""].join("");this.shapeKey===q&&this.input?.isConnected||(this.buildStructure({label:c,fieldId:y,helperId:A,errorId:f,validationId:S,startIcon:g,endIcon:w,isPassword:n,isSearch:i}),this.shapeKey=q);const L=this.querySelector(".designbase-wc-input__label");if(L&&(L.htmlFor=y,L.textContent=c,this.hasAttribute("required"))){const t=document.createElement("span");t.setAttribute("aria-hidden","true"),t.textContent=" *",L.append(t)}const V=this.querySelector("input.designbase-wc-input__field");if(V){V.id=y,V.type!==o&&(V.type=o),V.placeholder=this.getAttribute("placeholder")||"",V.disabled=this.disabled,V.readOnly=this.readOnly,V.required=this.hasAttribute("required"),V.name=this.getAttribute("name")||"",V.setAttribute("aria-invalid",String(p)),i?V.setAttribute("role","searchbox"):V.removeAttribute("role");for(const[t,e]of[["min",E],["max",I],["step",C]])null!==e?V.setAttribute(t,e):V.removeAttribute(t)}const x=this.querySelector(".designbase-wc-input__password-toggle");x&&(x.disabled=this.disabled,x.setAttribute("aria-label",t(this.passwordVisible?"input.hidePassword":"input.showPassword"))),this.querySelector(".designbase-wc-input__clear-button")?.setAttribute("aria-label",t("input.clearSearch"));const $=this.querySelector(".designbase-wc-input__helper-text");$&&($.id=A,$.textContent=h,$.hidden=!h||p);const P=this.querySelector(".designbase-wc-input__error-message");P&&(P.id=f,P.textContent=b,P.hidden=!p||!b),this.querySelector(".designbase-wc-input__validation-slot")?.setAttribute("id",S),this.mountIcons(g,!w||n||i?void 0:w,n);const k=this.querySelector("input.designbase-wc-input__field")||void 0;k&&(k.value!==e&&(k.value=e),k!==this.input&&(k.addEventListener("input",this.handleInput),k.addEventListener("change",this.handleChange),k.addEventListener("focus",this.handleFocus),k.addEventListener("blur",this.handleBlur))),this.input=k;const D=this.querySelector(".designbase-wc-input__password-toggle");D&&!D.dataset.wcBound&&(D.dataset.wcBound="true",D.addEventListener("click",this.handlePasswordToggle));const z=this.querySelector(".designbase-wc-input__clear-button");z&&!z.dataset.wcBound&&(z.dataset.wcBound="true",z.addEventListener("click",this.handleSearchClear)),this.detachScrub?.(),this.detachScrub=void 0,m&&this.input&&(this.detachScrub=a(this.input,{isEnabled:()=>this.hasAttribute("scrubbable")&&"number"===this.type,isInteractive:()=>!this.disabled&&!this.readOnly,getValue:()=>this.getCurrentValue(),getStep:()=>r(this,"scrub-step")??r(this,"step")??1,getMin:()=>r(this,"min"),getMax:()=>r(this,"max"),getSensitivity:()=>r(this,"scrub-sensitivity")??4,onValueChange:t=>this.applyScrubValue(t),onScrubStateChange:t=>{this.isScrubbing=t,this.classList.toggle("designbase-wc-input--scrubbing",t),!t&&this.input&&this.dispatchEvent(new CustomEvent("db-change",{detail:{value:this.input.value,nativeEvent:null},bubbles:!0,composed:!0}))}})),this.updateDynamicUI()}mountIcons(t,e,s=!1){const n=this.getIconSize();if(t){const e=this.querySelector(".designbase-wc-input__start-icon");e?.replaceChildren(i(t,n))}if(e){const t=this.querySelector(".designbase-wc-input__end-icon");t?.replaceChildren(i(e,n))}if(s){const t=this.querySelector(".designbase-wc-input__password-toggle");t?.replaceChildren(i(this.passwordVisible?"hide":"show",n))}const a=this.querySelector(".designbase-wc-input__clear-button");a?.replaceChildren(i("close",n))}shouldShowPasswordValidation(t){return!(!this.isValidationEnabled||"password"!==this.type)&&("never"!==this.validationVisibility&&("always"===this.validationVisibility||(this.isFocused||t.length>0)))}renderValidationMarkup(t){const s=n(t,this.passwordMinLength),i=Array.from({length:4},(t,e)=>`<span class="designbase-wc-input__password-strength-segment${e<s.score?` designbase-wc-input__password-strength-segment--${s.level}`:""}"></span>`).join(""),a=s.requirements.map(t=>`<li class="designbase-wc-input__password-requirement${t.met?" designbase-wc-input__password-requirement--met":""}">${t.met?'<span class="designbase-wc-input__password-requirement-icon" aria-hidden="true"></span>':'<span class="designbase-wc-input__password-requirement-icon" aria-hidden="true"><span class="designbase-wc-input__password-requirement-dot"></span></span>'}<span class="designbase-wc-input__password-requirement-label">${this.escape(t.label)}</span></li>`).join("");return`\n <div class="designbase-wc-input__validation" aria-live="polite">\n <div class="designbase-wc-input__password-strength">\n <div class="designbase-wc-input__password-strength-bar" role="progressbar" aria-valuemin="0" aria-valuemax="4" aria-valuenow="${s.score}" aria-label="${e("비밀번호 강도")}">${i}</div>\n <span class="designbase-wc-input__password-strength-label designbase-wc-input__password-strength-label--${s.level}">${s.levelLabel}</span>\n </div>\n <ul class="designbase-wc-input__password-requirements">${a}</ul>\n </div>\n `}updateDynamicUI(){const t=this.getCurrentValue(),e="search"===this.type&&t.length>0&&!this.disabled&&!this.readOnly;this.classList.toggle("designbase-wc-input--with-search-clear",e);const s=this.querySelector(".designbase-wc-input__clear-button");s&&(s.hidden=!e,s.replaceChildren(i("close",this.getIconSize())));const n=this.querySelector(".designbase-wc-input__validation-slot");if(n&&(this.shouldShowPasswordValidation(t)?(n.innerHTML=this.renderValidationMarkup(t),n.querySelectorAll(".designbase-wc-input__password-requirement--met .designbase-wc-input__password-requirement-icon").forEach(t=>{t.replaceChildren(i("circle-checked",12))})):n.innerHTML=""),this.input){const e=`${this.getAttribute("id")}-helper`,s=`${this.getAttribute("id")}-error`,i=`${this.getAttribute("id")}-validation`,n=this.getAttribute("helper-text")||"",a=this.getAttribute("error-message")||"",r=this.hasAttribute("error"),d=[n&&!r?e:"",this.shouldShowPasswordValidation(t)?i:"",r&&a?s:""].filter(Boolean).join(" ")||void 0;d?this.input.setAttribute("aria-describedby",d):this.input.removeAttribute("aria-describedby")}}applyScrubValue(t){this.input&&(this.input.value=t,this.setAttribute("value",t),this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:t,nativeEvent:null},bubbles:!0,composed:!0})))}escape(t){return t.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t]||t))}}customElements.get("db-input")||customElements.define("db-input",DbInput);export{DbInput};
|
|
1
|
+
import{TextFieldState as t,TEXT_FIELD_ATTRIBUTES as e,upgradeTextProperties as s,textFieldDescription as i}from"../core/text-field-state.js";import{t as n,dbText as a}from"../core/i18n.js";import{getDbComponentIconSize as r,createDbIcon as d}from"./db-icons.js";import{getPasswordValidation as u}from"./input-validation.js";import{attachNumberScrub as l,readNumericAttribute as o}from"./number-scrub.js";import{dbUid as h}from"../core/uid.js";import{coerceToContract as c}from"../node_modules/@designbasekorea/ui-contracts/dist/primitives.js";import{INPUT_TYPES as b,INPUT_SIZES as p}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";const g=new Set(["arrow-bar-left","arrow-bar-right","caret-down-filled","chevron-down","chevron-left","chevron-right","circle-checked","close","error-filled","edit","hide","info-filled","lock","mail","mobile","plus","search","share-alt","show","sparkle","trash","user","warning-filled"]);class DbInput extends HTMLElement{constructor(){super(...arguments),this.shapeKey="",this.formState=new t(this,()=>{this.touched=!1,this.updateDynamicUI()}),this.passwordVisible=!1,this.isFocused=!1,this.touched=!1,this.isScrubbing=!1,this.handleInput=t=>{t.stopPropagation();const e=t.target;this.updateDynamicUI(),this.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:e.value,nativeEvent:t},bubbles:!0,composed:!0}))},this.handleChange=t=>{t.stopPropagation();const e=t.target;this.dispatchEvent(new Event("change",{bubbles:!0})),this.dispatchEvent(new CustomEvent("db-change",{detail:{value:e.value,nativeEvent:t},bubbles:!0,composed:!0}))},this.handleFocus=t=>{this.isFocused=!0,this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-focus",{detail:{nativeEvent:t},bubbles:!0,composed:!0}))},this.handleBlur=t=>{this.isFocused=!1,this.touched=!0,this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-blur",{detail:{nativeEvent:t},bubbles:!0,composed:!0}))},this.handlePasswordToggle=()=>{this.passwordVisible=!this.passwordVisible,this.render()},this.handleSearchClear=()=>{this.input&&(this.input.value="",this.setAttribute("value",""),this.input.focus(),this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:"",nativeEvent:null},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("db-clear",{bubbles:!0,composed:!0})))}}static get observedAttributes(){return["type","label","placeholder","value","default-value","size","disabled","readonly","required","error","error-message","helper-text","full-width","name","start-icon","end-icon","validate","validation-visibility","validate-on-blur","password-min-length","scrubbable","scrub-step","scrub-sensitivity","min","max","step",...e]}get value(){return this.input?.value??this.getAttribute("value")??""}set value(t){this.setAttribute("value",t),this.input&&(this.input.value=t),this.updateDynamicUI()}get defaultValue(){return this.formState.defaultValue}set defaultValue(t){this.setAttribute("default-value",t)}get name(){return this.getAttribute("name")||""}set name(t){this.setAttribute("name",t)}get required(){return this.hasAttribute("required")}set required(t){this.toggleAttribute("required",t)}get type(){return c(this.getAttribute("type"),b,"text")}set type(t){this.setAttribute("type",t)}get size(){return c(this.getAttribute("size"),p,"m")}set size(t){this.setAttribute("size",t)}get disabled(){return this.hasAttribute("disabled")}set disabled(t){this.toggleAttribute("disabled",t)}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){this.toggleAttribute("readonly",t)}connectedCallback(){s(this,["value","defaultValue","name","required","type","size","disabled","readOnly"]),this.render()}disconnectedCallback(){this.formState.disconnect(),this.detachScrub?.(),this.detachScrub=void 0}attributeChangedCallback(t){if("value"!==t||!this.isScrubbing){if("value"===t&&this.input){const t=this.getAttribute("value")??"";return this.input.value!==t&&(this.input.value=t),this.formState.syncValue(this.input),void this.updateDynamicUI()}this.isConnected&&this.render()}}focus(t){this.input?.focus(t)}get passwordMinLength(){return Number(this.getAttribute("password-min-length")||8)}get validationVisibility(){return this.getAttribute("validation-visibility")||"focus"}get validateOnBlur(){return!this.hasAttribute("validate-on-blur")||"false"!==this.getAttribute("validate-on-blur")}get isValidationEnabled(){return this.hasAttribute("validate")}getIconSize(){return r(this.size)}resolveIconName(t){const e=this.getAttribute(t);if(e&&g.has(e))return e}resolveStartIcon(){const t=this.resolveIconName("start-icon");return t||("search"===this.type?"search":void 0)}getCurrentValue(){return this.input?.value??this.getAttribute("value")??this.getAttribute("default-value")??""}buildStructure(t){const make=(t,e)=>{const s=document.createElement(t);return s.className=e,s},e=[];if(t.label){const s=document.createElement("label");s.className="designbase-wc-input__label",s.htmlFor=t.fieldId,e.push(s)}const s=make("span","designbase-wc-input__wrapper");if(t.startIcon){const t=make("span","designbase-wc-input__start-icon");t.setAttribute("aria-hidden","true"),s.append(t)}const i=document.createElement("input");if(i.className="designbase-wc-input__field",i.id=t.fieldId,s.append(i),t.isPassword){const t=document.createElement("button");t.type="button",t.className="designbase-wc-input__password-toggle",s.append(t)}if(t.isSearch){const t=document.createElement("button");t.type="button",t.className="designbase-wc-input__clear-button",t.hidden=!0,s.append(t)}if(t.endIcon&&!t.isPassword&&!t.isSearch){const t=make("span","designbase-wc-input__end-icon");t.setAttribute("aria-hidden","true"),s.append(t)}if(e.push(s),this.isValidationEnabled&&t.isPassword){const s=make("div","designbase-wc-input__validation-slot");s.id=t.validationId,e.push(s)}const n=make("p","designbase-wc-input__helper-text");n.id=t.helperId;const a=make("p","designbase-wc-input__error-message");a.id=t.errorId,e.push(n,a),this.replaceChildren(...e)}render(){const t=this.getCurrentValue(),e=b.includes(this.type)?this.type:"text",s="search"===e,i="password"===e,a=i&&this.passwordVisible||s?"text":e,r=this.getAttribute("label")||"",d=this.getAttribute("helper-text")||"",u=this.getAttribute("error-message")||"",c=this.hasAttribute("error"),g=this.resolveStartIcon(),w=this.resolveIconName("end-icon");this.classList.add("designbase-wc-input"),p.forEach(t=>this.classList.remove(`designbase-wc-input--${t}`)),this.classList.add(`designbase-wc-input--${p.includes(this.size)?this.size:"m"}`),this.classList.toggle("designbase-wc-input--error",c),this.classList.toggle("designbase-wc-input--disabled",this.disabled),this.classList.toggle("designbase-wc-input--readonly",this.readOnly),this.classList.toggle("designbase-wc-input--full-width",this.hasAttribute("full-width")),this.classList.toggle("designbase-wc-input--with-start-icon",Boolean(g));const m=s&&t.length>0&&!this.disabled&&!this.readOnly;this.classList.toggle("designbase-wc-input--with-end-icon",Boolean(w&&!i&&!s)||i||m),this.classList.toggle("designbase-wc-input--with-password-toggle",i),this.classList.toggle("designbase-wc-input--with-search-clear",m);const v=this.hasAttribute("scrubbable")&&"number"===e&&!this.disabled&&!this.readOnly;this.classList.toggle("designbase-wc-input--scrubbable",v),this.classList.toggle("designbase-wc-input--scrubbing",this.isScrubbing);const _=this.getAttribute("id")||h("db-input");this.hasAttribute("id")||this.setAttribute("id",_);const y=`${_}-field`,f=`${_}-helper`,A=`${_}-error`,S=`${_}-validation`,E=this.getAttribute("min"),I=this.getAttribute("max"),q=this.getAttribute("step"),C=[r?"L":"",g?"S":"",!w||i||s?"":"E",i?"P":"",s?"C":"",this.isValidationEnabled&&i?"V":""].join("");this.shapeKey===C&&this.input?.isConnected||(this.buildStructure({label:r,fieldId:y,helperId:f,errorId:A,validationId:S,startIcon:g,endIcon:w,isPassword:i,isSearch:s}),this.shapeKey=C);const V=this.querySelector(".designbase-wc-input__label");if(V&&(V.htmlFor=y,V.textContent=r,this.hasAttribute("required"))){const t=document.createElement("span");t.setAttribute("aria-hidden","true"),t.textContent=" *",V.append(t)}const L=this.querySelector("input.designbase-wc-input__field");if(L){L.id=y,L.type!==a&&(L.type=a),L.placeholder=this.getAttribute("placeholder")||"",L.disabled=this.disabled,L.readOnly=this.readOnly,L.required=this.hasAttribute("required"),L.name=this.getAttribute("name")||"",L.setAttribute("aria-invalid",String(c)),s?L.setAttribute("role","searchbox"):L.removeAttribute("role");for(const[t,e]of[["min",E],["max",I],["step",q]])null!==e?L.setAttribute(t,e):L.removeAttribute(t)}const x=this.querySelector(".designbase-wc-input__password-toggle");x&&(x.disabled=this.disabled,x.setAttribute("aria-label",n(this.passwordVisible?"input.hidePassword":"input.showPassword"))),this.querySelector(".designbase-wc-input__clear-button")?.setAttribute("aria-label",n("input.clearSearch"));const $=this.querySelector(".designbase-wc-input__helper-text");$&&($.id=f,$.textContent=d,$.hidden=!d||c);const P=this.querySelector(".designbase-wc-input__error-message");P&&(P.id=A,P.textContent=u,P.hidden=!c||!u),this.querySelector(".designbase-wc-input__validation-slot")?.setAttribute("id",S),this.mountIcons(g,!w||i||s?void 0:w,i);const k=this.querySelector("input.designbase-wc-input__field")||void 0;k&&(k.value!==t&&(k.value=t),k!==this.input&&(k.addEventListener("input",this.handleInput),k.addEventListener("change",this.handleChange),k.addEventListener("focus",this.handleFocus),k.addEventListener("blur",this.handleBlur))),this.input=k,k&&this.formState.sync(k);const D=this.querySelector(".designbase-wc-input__password-toggle");D&&!D.dataset.wcBound&&(D.dataset.wcBound="true",D.addEventListener("click",this.handlePasswordToggle));const z=this.querySelector(".designbase-wc-input__clear-button");z&&!z.dataset.wcBound&&(z.dataset.wcBound="true",z.addEventListener("click",this.handleSearchClear)),this.detachScrub?.(),this.detachScrub=void 0,v&&this.input&&(this.detachScrub=l(this.input,{isEnabled:()=>this.hasAttribute("scrubbable")&&"number"===this.type,isInteractive:()=>!this.disabled&&!this.readOnly,getValue:()=>this.getCurrentValue(),getStep:()=>o(this,"scrub-step")??o(this,"step")??1,getMin:()=>o(this,"min"),getMax:()=>o(this,"max"),getSensitivity:()=>o(this,"scrub-sensitivity")??4,onValueChange:t=>this.applyScrubValue(t),onScrubStateChange:t=>{this.isScrubbing=t,this.classList.toggle("designbase-wc-input--scrubbing",t),!t&&this.input&&this.dispatchEvent(new CustomEvent("db-change",{detail:{value:this.input.value,nativeEvent:null},bubbles:!0,composed:!0}))}})),this.updateDynamicUI()}mountIcons(t,e,s=!1){const i=this.getIconSize();if(t){const e=this.querySelector(".designbase-wc-input__start-icon");e?.replaceChildren(d(t,i))}if(e){const t=this.querySelector(".designbase-wc-input__end-icon");t?.replaceChildren(d(e,i))}if(s){const t=this.querySelector(".designbase-wc-input__password-toggle");t?.replaceChildren(d(this.passwordVisible?"hide":"show",i))}const n=this.querySelector(".designbase-wc-input__clear-button");n?.replaceChildren(d("close",i))}shouldShowPasswordValidation(t){return!(!this.isValidationEnabled||"password"!==this.type)&&("never"!==this.validationVisibility&&("always"===this.validationVisibility||(this.isFocused||t.length>0)))}renderValidationMarkup(t){const e=u(t,this.passwordMinLength),s=Array.from({length:4},(t,s)=>`<span class="designbase-wc-input__password-strength-segment${s<e.score?` designbase-wc-input__password-strength-segment--${e.level}`:""}"></span>`).join(""),i=e.requirements.map(t=>`<li class="designbase-wc-input__password-requirement${t.met?" designbase-wc-input__password-requirement--met":""}">${t.met?'<span class="designbase-wc-input__password-requirement-icon" aria-hidden="true"></span>':'<span class="designbase-wc-input__password-requirement-icon" aria-hidden="true"><span class="designbase-wc-input__password-requirement-dot"></span></span>'}<span class="designbase-wc-input__password-requirement-label">${this.escape(t.label)}</span></li>`).join("");return`\n <div class="designbase-wc-input__validation" aria-live="polite">\n <div class="designbase-wc-input__password-strength">\n <div class="designbase-wc-input__password-strength-bar" role="progressbar" aria-valuemin="0" aria-valuemax="4" aria-valuenow="${e.score}" aria-label="${a("비밀번호 강도")}">${s}</div>\n <span class="designbase-wc-input__password-strength-label designbase-wc-input__password-strength-label--${e.level}">${e.levelLabel}</span>\n </div>\n <ul class="designbase-wc-input__password-requirements">${i}</ul>\n </div>\n `}updateDynamicUI(){const t=this.getCurrentValue(),e="search"===this.type&&t.length>0&&!this.disabled&&!this.readOnly;this.classList.toggle("designbase-wc-input--with-search-clear",e);const s=this.querySelector(".designbase-wc-input__clear-button");s&&(s.hidden=!e,s.replaceChildren(d("close",this.getIconSize())));const n=this.querySelector(".designbase-wc-input__validation-slot");if(n&&(this.shouldShowPasswordValidation(t)?(n.innerHTML=this.renderValidationMarkup(t),n.querySelectorAll(".designbase-wc-input__password-requirement--met .designbase-wc-input__password-requirement-icon").forEach(t=>{t.replaceChildren(d("circle-checked",12))})):n.innerHTML=""),this.input){const e=`${this.getAttribute("id")}-helper`,s=`${this.getAttribute("id")}-error`,n=`${this.getAttribute("id")}-validation`,a=this.getAttribute("helper-text")||"",r=this.getAttribute("error-message")||"",d=this.hasAttribute("error"),u=i(this,a&&!d?e:"",this.shouldShowPasswordValidation(t)?n:"",d&&r?s:"")||void 0;u?this.input.setAttribute("aria-describedby",u):this.input.removeAttribute("aria-describedby")}}applyScrubValue(t){this.input&&(this.input.value=t,this.setAttribute("value",t),this.updateDynamicUI(),this.dispatchEvent(new CustomEvent("db-input",{detail:{value:t,nativeEvent:null},bubbles:!0,composed:!0})))}escape(t){return t.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t]||t))}}customElements.get("db-input")||customElements.define("db-input",DbInput);export{DbInput};
|
|
@@ -47,6 +47,9 @@ declare class DbNavbar extends HTMLElement {
|
|
|
47
47
|
private static nextId;
|
|
48
48
|
private readonly mobileMenuId;
|
|
49
49
|
private mobileOpen;
|
|
50
|
+
private slotObserver?;
|
|
51
|
+
private containerObserver?;
|
|
52
|
+
private escapeMenu;
|
|
50
53
|
private userMenuOpen;
|
|
51
54
|
private expandedMobile;
|
|
52
55
|
private outsideHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dbText as e}from"../core/i18n.js";import{createDbIcon as t}from"./db-icons.js";import{sanitizeHref as a}from"../core/safe-url.js";import{NAVBAR_SIZES as n,NAVBAR_VARIANTS as s,NAVBAR_POSITIONS as i}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function resolveIcon(e){if(e)return e}class DbNavbar extends HTMLElement{constructor(){super(...arguments),this.mobileMenuId="db-navbar-menu-"+ ++DbNavbar.nextId,this.mobileOpen=!1,this.userMenuOpen=!1,this.expandedMobile={},this.outsideHandler=null}static get observedAttributes(){return["logo-src","logo-alt","items","user-menu-items","user-profile","size","variant","position","is-authenticated","show-search","search-placeholder","full-width","shadow"]}connectedCallback(){this.render(),this.bindOutsideClick()}disconnectedCallback(){this.unbindOutsideClick()}attributeChangedCallback(){this.isConnected&&this.render()}get items(){return this.parseItems("items")}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseItems("user-menu-items")}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}parseItems(e="items"){try{const t=JSON.parse(this.getAttribute(e)||"[]");return Array.isArray(t)?t:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}iconSize(e){return"s"===e?16:"l"===e?24:20}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{this.contains(e.target)||(this.userMenuOpen=!1,this.updateUserMenuVisibility())},document.addEventListener("mousedown",this.outsideHandler))}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}dispatchItemClick(e,t){this.dispatchEvent(new CustomEvent("user"===t?"db-user-menu-item-click":"db-item-click",{bubbles:!0,composed:!0,detail:{item:e,source:t}}))}syncHostClasses(){const e=this.getAttribute("size")||"m",t=this.getAttribute("variant")||"default",a=this.getAttribute("position")||"static";this.className=["designbase-wc-navbar",`designbase-wc-navbar--${n.includes(e)?e:"m"}`,`designbase-wc-navbar--${s.includes(t)?t:"default"}`,`designbase-wc-navbar--${i.includes(a)?a:"static"}`,this.hasAttribute("full-width")&&"designbase-wc-navbar--full-width",this.hasAttribute("shadow")&&"designbase-wc-navbar--shadow",this.mobileOpen&&"designbase-wc-navbar--mobile-open"].filter(Boolean).join(" ")}isMegaMenu(e){return Boolean(e.megaMenu&&e.columns?.length)}createNavToggleButton(e,a){const n=document.createElement("button");n.type="button",n.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",e.active&&"designbase-wc-navbar__nav-link--active",e.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),n.disabled=Boolean(e.disabled);const s=resolveIcon(e.icon);s&&n.append(t(s,a)),n.append(document.createTextNode(e.label));const i=t("chevron-down",12);return i.classList.add("designbase-wc-navbar__chevron"),n.append(i),n}createMegaLink(e,n){const s=document.createElement("a");s.href=a(e.href,"#"),s.className=["designbase-wc-navbar__mega-link",e.active&&"designbase-wc-navbar__mega-link--active",e.disabled&&"designbase-wc-navbar__mega-link--disabled"].filter(Boolean).join(" ");const i=resolveIcon(e.icon);if(i){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-link-icon",e.append(t(i,n)),s.append(e)}const r=document.createElement("span");r.className="designbase-wc-navbar__mega-link-body";const c=document.createElement("span");if(c.className="designbase-wc-navbar__mega-link-label",c.textContent=e.label,r.append(c),e.description){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-link-desc",t.textContent=e.description,r.append(t)}return s.append(r),s.addEventListener("click",t=>{t.preventDefault(),e.disabled||this.dispatchItemClick(e,"nav")}),s}createMegaMenu(e,t){const a=document.createElement("li");a.className="designbase-wc-navbar__nav-item designbase-wc-navbar__nav-item--mega";const n=this.createNavToggleButton(e,t),s=document.createElement("div");s.className="designbase-wc-navbar__mega";const i=document.createElement("div");i.className="designbase-wc-navbar__mega-inner";const r=document.createElement("div");return r.className="designbase-wc-navbar__mega-columns",r.style.setProperty("--db-navbar-mega-columns",String(e.columns.length)),e.columns.forEach(e=>{const a=document.createElement("div");if(a.className="designbase-wc-navbar__mega-column",e.title){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-column-title",t.textContent=e.title,a.append(t)}const n=document.createElement("ul");n.className="designbase-wc-navbar__mega-list",e.items.forEach(e=>{const a=document.createElement("li");a.append(this.createMegaLink(e,t)),n.append(a)}),a.append(n),r.append(a)}),i.append(r),e.featured&&i.append(this.createMegaFeatured(e.featured,t)),s.append(i),a.append(n,s),a}createMegaFeatured(e,n){const s=document.createElement("a");s.href=a(e.href,"#"),s.className="designbase-wc-navbar__mega-featured",e.image&&(s.style.setProperty("--db-navbar-mega-featured-image",`url("${e.image}")`),s.classList.add("designbase-wc-navbar__mega-featured--image"));const i=resolveIcon(e.icon);if(i){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-featured-icon",e.append(t(i,n+4)),s.append(e)}if(e.title){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-featured-title",t.textContent=e.title,s.append(t)}if(e.description){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-featured-desc",t.textContent=e.description,s.append(t)}if(e.ctaLabel){const a=document.createElement("span");a.className="designbase-wc-navbar__mega-featured-cta",a.append(document.createTextNode(e.ctaLabel)),a.append(t("chevron-right",14)),s.append(a)}return s.addEventListener("click",t=>{t.preventDefault(),this.dispatchItemClick({id:`${e.href||"featured"}`,label:e.title||"featured",href:e.href},"nav")}),s}createDesktopNavItem(e,n){if(this.isMegaMenu(e))return this.createMegaMenu(e,n);const s=document.createElement("li");s.className="designbase-wc-navbar__nav-item";if(Boolean(e.children?.length)){const i=document.createElement("div");i.className="designbase-wc-navbar__dropdown";const r=document.createElement("button");r.type="button",r.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",e.active&&"designbase-wc-navbar__nav-link--active",e.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),r.disabled=Boolean(e.disabled);const c=resolveIcon(e.icon);c&&r.append(t(c,n)),r.append(document.createTextNode(e.label));const d=t("chevron-down",12);d.classList.add("designbase-wc-navbar__chevron"),r.append(d);const l=document.createElement("ul");return l.className="designbase-wc-navbar__dropdown-menu",e.children.forEach(e=>{const s=document.createElement("li"),i=document.createElement("a");i.href=a(e.href,"#"),i.className=["designbase-wc-navbar__dropdown-item",e.active&&"designbase-wc-navbar__dropdown-item--active",e.disabled&&"designbase-wc-navbar__dropdown-item--disabled"].filter(Boolean).join(" ");const r=resolveIcon(e.icon);r&&i.append(t(r,n)),i.append(document.createTextNode(e.label)),i.addEventListener("click",t=>{e.disabled?t.preventDefault():(t.preventDefault(),this.dispatchItemClick(e,"nav"))}),s.append(i),l.append(s)}),i.append(r,l),s.append(i),s}const i=document.createElement("a");i.href=a(e.href,"#"),i.className=["designbase-wc-navbar__nav-link",e.active&&"designbase-wc-navbar__nav-link--active",e.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" ");const r=resolveIcon(e.icon);return r&&i.append(t(r,n)),i.append(document.createTextNode(e.label)),i.addEventListener("click",t=>{e.disabled?t.preventDefault():(t.preventDefault(),this.dispatchItemClick(e,"nav"))}),s.append(i),s}createUserMenuItemElement(e,t,n){const s=document.createElement("db-menu-item");s.setAttribute("label",e.label),s.setAttribute("type","block"),s.setAttribute("menu-style","dropdown"),s.setAttribute("size",t);const i=a(e.href,"");return i&&s.setAttribute("href",i),e.icon&&s.setAttribute("icon",e.icon),e.disabled&&s.setAttribute("disabled",""),s.addEventListener("db-click",()=>{e.disabled||(n(),this.dispatchItemClick(e,"user"))}),s}bindSearchEvents(e){e.addEventListener("db-search",e=>{const t=e.detail,a=t.query??t.value??"";this.dispatchEvent(new CustomEvent("db-search",{bubbles:!0,composed:!0,detail:{query:a,value:a}}))})}applyAvatarProfile(e,t,a){e.setAttribute("size","s"===a?"s":"l"===a?"l":"m"),e.setAttribute("initials",t.name),e.setAttribute("alt",t.name),t.avatar&&e.setAttribute("src",t.avatar),void 0!==t.badge&&e.setAttribute("badge",String(t.badge)),t.badgeVariant&&e.setAttribute("badge-variant",t.badgeVariant),t.badgeType&&e.setAttribute("badge-type",t.badgeType),t.badgeText&&e.setAttribute("badge-text",t.badgeText)}getMobileChildren(e){if(this.isMegaMenu(e)){const t=(e.columns||[]).flatMap(e=>e.items);return e.featured?.href&&t.push({id:`${e.id}-featured`,label:e.featured.title||e.featured.ctaLabel||e.label,href:e.featured.href,icon:e.featured.icon}),t}return e.children||[]}createMobileMenuItem(e,t){const n=this.getMobileChildren(e),s=n.length>0,i=Boolean(this.expandedMobile[e.id]),r=document.createElement("db-menu-item");r.setAttribute("label",e.label),r.setAttribute("type","block"),r.setAttribute("menu-style","accordion"),r.setAttribute("size",t);const c=a(e.href,"");return c&&r.setAttribute("href",c),e.icon&&r.setAttribute("icon",e.icon),e.active&&r.setAttribute("active",""),e.disabled&&r.setAttribute("disabled",""),s&&(r.setAttribute("expandable",""),r.subItems=n.map(e=>({id:e.id,label:e.label,href:e.href,icon:e.icon,active:e.active,disabled:e.disabled})),i&&r.setAttribute("expanded","")),r.addEventListener("db-click",()=>{e.disabled||(s?this.expandedMobile[e.id]=r.hasAttribute("expanded"):(this.mobileOpen=!1,this.dispatchItemClick(e,"mobile"),this.render()))}),r.addEventListener("db-child-click",e=>{const t=e.detail;this.mobileOpen=!1,this.dispatchItemClick(t.child,"mobile"),this.render()}),r}updateUserMenuVisibility(){const e=this.querySelector(".designbase-wc-navbar__user-dropdown-menu");e&&(e.hidden=!this.userMenuOpen)}renderMobileMenu(){const e=this.querySelector(".designbase-wc-navbar__mobile-nav-list");if(!e)return;const t=this.getAttribute("size")||"m",a=this.parseItems();e.replaceChildren(...a.map(e=>this.createMobileMenuItem(e,t)))}render(){this.syncHostClasses(),this.setAttribute("role","navigation"),this.setAttribute("aria-label",e("메인 네비게이션"));const a=this.getAttribute("size")||"m",n=this.iconSize(a),s=this.parseItems(),i=this.parseItems("user-menu-items"),r=this.parseUserProfile(),c=this.hasAttribute("is-authenticated"),d=this.hasAttribute("show-search");this.replaceChildren();const l=document.createElement("div");l.className=["designbase-wc-navbar__container",this.hasAttribute("full-width")&&"designbase-wc-navbar__container--full-width"].filter(Boolean).join(" ");const o=document.createElement("div");o.className="designbase-wc-navbar__left";const b=document.createElement("div");b.className="designbase-wc-navbar__brand";const u=document.createElement("div");u.className="designbase-wc-navbar__logo";const m=document.createElement("db-logo"),p=this.getAttribute("logo-src");m.setAttribute("type",p?"custom":"designbase"),p&&m.setAttribute("src",p),m.setAttribute("alt",this.getAttribute("logo-alt")||"홈"),m.setAttribute("size","s"),m.setAttribute("clickable",""),m.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),u.append(m),b.append(u),o.append(b);const h=document.createElement("div");h.className="designbase-wc-navbar__right";const v=document.createElement("div");v.className="designbase-wc-navbar__nav designbase-wc-navbar__nav--desktop";const g=document.createElement("ul");if(g.className="designbase-wc-navbar__nav-list",s.forEach(e=>g.append(this.createDesktopNavItem(e,n))),v.append(g),h.append(v),d){const e=document.createElement("div");e.className="designbase-wc-navbar__search";const t=document.createElement("db-search-bar");t.setAttribute("variant","outlined"),t.setAttribute("size","s"===a?"s":"l"===a?"l":"m"),t.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(t),e.append(t),h.append(e)}const _=document.createElement("div");if(_.className="designbase-wc-navbar__user-menu",c&&r){const e=document.createElement("div");e.className="designbase-wc-navbar__user-dropdown";const n=document.createElement("button");n.type="button",n.className="designbase-wc-navbar__user-toggle",n.setAttribute("aria-expanded",String(this.userMenuOpen));const s=document.createElement("db-avatar");this.applyAvatarProfile(s,r,a);const c=document.createElement("span");c.className="designbase-wc-navbar__user-name",c.textContent=r.name,n.append(s,c,t("chevron-down",12)),n.addEventListener("click",()=>{this.userMenuOpen=!this.userMenuOpen,n.setAttribute("aria-expanded",String(this.userMenuOpen)),this.updateUserMenuVisibility()});const d=document.createElement("ul");if(d.className="designbase-wc-navbar__user-dropdown-menu",d.hidden=!this.userMenuOpen,r.email){const e=document.createElement("li");e.className="designbase-wc-navbar__user-info";const t=document.createElement("span");t.className="designbase-wc-navbar__user-email",t.textContent=r.email,e.append(t),d.append(e)}i.forEach(e=>{const t=document.createElement("li");t.append(this.createUserMenuItemElement(e,a,()=>{this.userMenuOpen=!1,this.updateUserMenuVisibility()})),d.append(t)}),e.append(n,d),_.append(e)}else{const t=document.createElement("db-button");t.setAttribute("variant","primary"),t.setAttribute("size","s"===a?"s":"l"===a?"l":"m"),t.textContent=e("로그인"),t.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),_.append(t)}h.append(_);const f=document.createElement("button");f.type="button",f.className="designbase-wc-navbar__mobile-toggle",f.setAttribute("aria-expanded",String(this.mobileOpen)),this.mobileOpen&&f.setAttribute("aria-controls",this.mobileMenuId),f.setAttribute("aria-label",this.mobileOpen?"메뉴 닫기":"메뉴 열기");for(let e=0;e<3;e+=1){const e=document.createElement("span");e.className="designbase-wc-navbar__mobile-toggle-line",f.append(e)}if(f.addEventListener("click",()=>{this.mobileOpen=!this.mobileOpen,this.render(),this.querySelector(".designbase-wc-navbar__mobile-toggle")?.focus()}),l.append(o,h,f),this.append(l),this.mobileOpen){const t=document.createElement("div");if(t.className="designbase-wc-navbar__mobile-menu",t.id=this.mobileMenuId,t.addEventListener("keydown",e=>{"Escape"===e.key&&(this.mobileOpen=!1,this.render(),this.querySelector(".designbase-wc-navbar__mobile-toggle")?.focus())}),d){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-search";const a=document.createElement("db-search-bar");a.setAttribute("variant","outlined"),a.setAttribute("size","s"),a.setAttribute("full-width",""),a.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(a),e.append(a),t.append(e)}const a=document.createElement("div");a.className="designbase-wc-navbar__mobile-nav-list",t.append(a);const n=document.createElement("div");if(n.className="designbase-wc-navbar__mobile-user",c&&r){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-info";const t=document.createElement("db-avatar");this.applyAvatarProfile(t,r,"m");const a=document.createElement("div"),s=document.createElement("div");if(s.className="designbase-wc-navbar__mobile-user-name",s.textContent=r.name,a.append(s),r.email){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-email",e.textContent=r.email,a.append(e)}if(e.append(t,a),n.append(e),i.length){const e=document.createElement("ul");e.className="designbase-wc-navbar__mobile-user-menu",i.forEach(t=>{const a=document.createElement("li");a.append(this.createUserMenuItemElement(t,"m",()=>{this.mobileOpen=!1,this.render()})),e.append(a)}),n.append(e)}}else{const t=document.createElement("db-button");t.setAttribute("variant","primary"),t.setAttribute("size","m"),t.setAttribute("full-width",""),t.textContent=e("로그인"),t.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),n.append(t)}t.append(n),this.append(t),this.renderMobileMenu()}}}DbNavbar.nextId=0,customElements.get("db-navbar")||customElements.define("db-navbar",DbNavbar);export{DbNavbar};
|
|
1
|
+
import{setHostClasses as e}from"../core/host-class.js";import{dbText as t}from"../core/i18n.js";import{createDbIcon as a}from"./db-icons.js";import{sanitizeHref as n}from"../core/safe-url.js";import{NAVBAR_SIZES as s,NAVBAR_VARIANTS as i,NAVBAR_POSITIONS as r}from"../node_modules/@designbasekorea/ui-contracts/dist/components.js";function resolveIcon(e){if(e)return e}class DbNavbar extends HTMLElement{constructor(){super(...arguments),this.mobileMenuId="db-navbar-menu-"+ ++DbNavbar.nextId,this.mobileOpen=!1,this.escapeMenu=e=>{"Escape"===e.key&&this.mobileOpen&&(e.preventDefault(),this.mobileOpen=!1,this.render(),this.querySelector(".designbase-wc-navbar__mobile-toggle")?.focus())},this.userMenuOpen=!1,this.expandedMobile={},this.outsideHandler=null}static get observedAttributes(){return["logo-src","logo-alt","items","user-menu-items","user-profile","size","variant","position","is-authenticated","show-search","search-placeholder","full-width","shadow"]}connectedCallback(){this.render(),this.bindOutsideClick(),this.addEventListener("keydown",this.escapeMenu),this.containerObserver=new ResizeObserver(([e])=>{e.contentRect.width>=1024&&this.mobileOpen&&(this.mobileOpen=!1,this.render())}),this.containerObserver.observe(this),this.slotObserver=new MutationObserver(()=>{Array.from(this.children).some(e=>["brand","actions"].includes(e.getAttribute("slot")||""))&&this.render()}),this.slotObserver.observe(this,{childList:!0})}disconnectedCallback(){this.unbindOutsideClick(),this.slotObserver?.disconnect(),this.containerObserver?.disconnect(),this.removeEventListener("keydown",this.escapeMenu)}attributeChangedCallback(){this.isConnected&&this.render()}get items(){return this.parseItems("items")}set items(e){this.setAttribute("items","string"==typeof e?e:JSON.stringify(e))}get userMenuItems(){return this.parseItems("user-menu-items")}set userMenuItems(e){this.setAttribute("user-menu-items","string"==typeof e?e:JSON.stringify(e))}get userProfile(){return this.parseUserProfile()}set userProfile(e){null==e?this.removeAttribute("user-profile"):this.setAttribute("user-profile","string"==typeof e?e:JSON.stringify(e))}parseItems(e="items"){try{const t=JSON.parse(this.getAttribute(e)||"[]");return Array.isArray(t)?t:[]}catch{return[]}}parseUserProfile(){const e=this.getAttribute("user-profile");if(!e)return null;try{return JSON.parse(e)}catch{return null}}iconSize(e){return"s"===e?16:"l"===e?24:20}bindOutsideClick(){this.outsideHandler||(this.outsideHandler=e=>{this.contains(e.target)||(this.userMenuOpen=!1,this.updateUserMenuVisibility(),this.mobileOpen&&(this.mobileOpen=!1,this.render()))},document.addEventListener("mousedown",this.outsideHandler))}unbindOutsideClick(){this.outsideHandler&&(document.removeEventListener("mousedown",this.outsideHandler),this.outsideHandler=null)}dispatchItemClick(e,t){this.dispatchEvent(new CustomEvent("user"===t?"db-user-menu-item-click":"db-item-click",{bubbles:!0,composed:!0,detail:{item:e,source:t}}))}syncHostClasses(){const t=this.getAttribute("size")||"m",a=this.getAttribute("variant")||"default",n=this.getAttribute("position")||"static";e(this,["designbase-wc-navbar",`designbase-wc-navbar--${s.includes(t)?t:"m"}`,`designbase-wc-navbar--${i.includes(a)?a:"default"}`,`designbase-wc-navbar--${r.includes(n)?n:"static"}`,this.hasAttribute("full-width")&&"designbase-wc-navbar--full-width",this.hasAttribute("shadow")&&"designbase-wc-navbar--shadow",this.mobileOpen&&"designbase-wc-navbar--mobile-open"])}isMegaMenu(e){return Boolean(e.megaMenu&&e.columns?.length)}createNavToggleButton(e,t){const n=document.createElement("button");n.type="button",n.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",e.active&&"designbase-wc-navbar__nav-link--active",e.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),n.disabled=Boolean(e.disabled);const s=resolveIcon(e.icon);s&&n.append(a(s,t)),n.append(document.createTextNode(e.label));const i=a("chevron-down",12);return i.classList.add("designbase-wc-navbar__chevron"),n.append(i),n}createMegaLink(e,t){const s=document.createElement("a");s.href=n(e.href,"#"),s.className=["designbase-wc-navbar__mega-link",e.active&&"designbase-wc-navbar__mega-link--active",e.disabled&&"designbase-wc-navbar__mega-link--disabled"].filter(Boolean).join(" ");const i=resolveIcon(e.icon);if(i){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-link-icon",e.append(a(i,t)),s.append(e)}const r=document.createElement("span");r.className="designbase-wc-navbar__mega-link-body";const c=document.createElement("span");if(c.className="designbase-wc-navbar__mega-link-label",c.textContent=e.label,r.append(c),e.description){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-link-desc",t.textContent=e.description,r.append(t)}return s.append(r),s.addEventListener("click",t=>{t.preventDefault(),e.disabled||this.dispatchItemClick(e,"nav")}),s}createMegaMenu(e,t){const a=document.createElement("li");a.className="designbase-wc-navbar__nav-item designbase-wc-navbar__nav-item--mega";const n=this.createNavToggleButton(e,t),s=document.createElement("div");s.className="designbase-wc-navbar__mega";const i=document.createElement("div");i.className="designbase-wc-navbar__mega-inner";const r=document.createElement("div");return r.className="designbase-wc-navbar__mega-columns",e.columns.forEach(e=>{const a=document.createElement("div");if(a.className="designbase-wc-navbar__mega-column",e.title){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-column-title",t.textContent=e.title,a.append(t)}const n=document.createElement("ul");n.className="designbase-wc-navbar__mega-list",e.items.forEach(e=>{const a=document.createElement("li");a.append(this.createMegaLink(e,t)),n.append(a)}),a.append(n),r.append(a)}),i.append(r),e.featured&&i.append(this.createMegaFeatured(e.featured,t)),s.append(i),a.append(n,s),a}createMegaFeatured(e,t){const s=document.createElement("a");s.href=n(e.href,"#"),s.className="designbase-wc-navbar__mega-featured",e.image&&(s.style.setProperty("--db-navbar-mega-featured-image",`url("${e.image}")`),s.classList.add("designbase-wc-navbar__mega-featured--image"));const i=resolveIcon(e.icon);if(i){const e=document.createElement("span");e.className="designbase-wc-navbar__mega-featured-icon",e.append(a(i,t+4)),s.append(e)}if(e.title){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-featured-title",t.textContent=e.title,s.append(t)}if(e.description){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-featured-desc",t.textContent=e.description,s.append(t)}if(e.ctaLabel){const t=document.createElement("span");t.className="designbase-wc-navbar__mega-featured-cta",t.append(document.createTextNode(e.ctaLabel)),t.append(a("chevron-right",14)),s.append(t)}return s.addEventListener("click",t=>{t.preventDefault(),this.dispatchItemClick({id:`${e.href||"featured"}`,label:e.title||"featured",href:e.href},"nav")}),s}createDesktopNavItem(e,t){if(this.isMegaMenu(e))return this.createMegaMenu(e,t);const s=document.createElement("li");s.className="designbase-wc-navbar__nav-item";if(Boolean(e.children?.length)){const i=document.createElement("div");i.className="designbase-wc-navbar__dropdown";const r=document.createElement("button");r.type="button",r.className=["designbase-wc-navbar__nav-link","designbase-wc-navbar__nav-link--has-children",e.active&&"designbase-wc-navbar__nav-link--active",e.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" "),r.disabled=Boolean(e.disabled);const c=resolveIcon(e.icon);c&&r.append(a(c,t)),r.append(document.createTextNode(e.label));const d=a("chevron-down",12);d.classList.add("designbase-wc-navbar__chevron"),r.append(d);const l=document.createElement("ul");return l.className="designbase-wc-navbar__dropdown-menu",e.children.forEach(e=>{const s=document.createElement("li"),i=document.createElement("a");i.href=n(e.href,"#"),i.className=["designbase-wc-navbar__dropdown-item",e.active&&"designbase-wc-navbar__dropdown-item--active",e.disabled&&"designbase-wc-navbar__dropdown-item--disabled"].filter(Boolean).join(" ");const r=resolveIcon(e.icon);r&&i.append(a(r,t)),i.append(document.createTextNode(e.label)),i.addEventListener("click",t=>{e.disabled?t.preventDefault():(t.preventDefault(),this.dispatchItemClick(e,"nav"))}),s.append(i),l.append(s)}),i.append(r,l),s.append(i),s}const i=document.createElement("a");i.href=n(e.href,"#"),i.className=["designbase-wc-navbar__nav-link",e.active&&"designbase-wc-navbar__nav-link--active",e.disabled&&"designbase-wc-navbar__nav-link--disabled"].filter(Boolean).join(" ");const r=resolveIcon(e.icon);return r&&i.append(a(r,t)),i.append(document.createTextNode(e.label)),i.addEventListener("click",t=>{e.disabled?t.preventDefault():(t.preventDefault(),this.dispatchItemClick(e,"nav"))}),s.append(i),s}createUserMenuItemElement(e,t,a){const s=document.createElement("db-menu-item");s.setAttribute("label",e.label),s.setAttribute("type","block"),s.setAttribute("menu-style","dropdown"),s.setAttribute("size",t);const i=n(e.href,"");return i&&s.setAttribute("href",i),e.icon&&s.setAttribute("icon",e.icon),e.disabled&&s.setAttribute("disabled",""),s.addEventListener("db-click",()=>{e.disabled||(a(),this.dispatchItemClick(e,"user"))}),s}bindSearchEvents(e){e.addEventListener("db-search",e=>{const t=e.detail,a=t.query??t.value??"";this.dispatchEvent(new CustomEvent("db-search",{bubbles:!0,composed:!0,detail:{query:a,value:a}}))})}applyAvatarProfile(e,t,a){e.setAttribute("size","s"===a?"s":"l"===a?"l":"m"),e.setAttribute("initials",t.name),e.setAttribute("alt",t.name),t.avatar&&e.setAttribute("src",t.avatar),void 0!==t.badge&&e.setAttribute("badge",String(t.badge)),t.badgeVariant&&e.setAttribute("badge-variant",t.badgeVariant),t.badgeType&&e.setAttribute("badge-type",t.badgeType),t.badgeText&&e.setAttribute("badge-text",t.badgeText)}getMobileChildren(e){if(this.isMegaMenu(e)){const t=(e.columns||[]).flatMap(e=>e.items);return e.featured?.href&&t.push({id:`${e.id}-featured`,label:e.featured.title||e.featured.ctaLabel||e.label,href:e.featured.href,icon:e.featured.icon}),t}return e.children||[]}createMobileMenuItem(e,t){const a=this.getMobileChildren(e),s=a.length>0,i=Boolean(this.expandedMobile[e.id]),r=document.createElement("db-menu-item");r.setAttribute("label",e.label),r.setAttribute("type","block"),r.setAttribute("menu-style","accordion"),r.setAttribute("size",t);const c=n(e.href,"");return c&&r.setAttribute("href",c),e.icon&&r.setAttribute("icon",e.icon),e.active&&r.setAttribute("active",""),e.disabled&&r.setAttribute("disabled",""),s&&(r.setAttribute("expandable",""),r.subItems=a.map(e=>({id:e.id,label:e.label,href:e.href,icon:e.icon,active:e.active,disabled:e.disabled})),i&&r.setAttribute("expanded","")),r.addEventListener("db-click",()=>{e.disabled||(s?this.expandedMobile[e.id]=r.hasAttribute("expanded"):(this.mobileOpen=!1,this.dispatchItemClick(e,"mobile"),this.render()))}),r.addEventListener("db-child-click",e=>{const t=e.detail;this.mobileOpen=!1,this.dispatchItemClick(t.child,"mobile"),this.render()}),r}updateUserMenuVisibility(){const e=this.querySelector(".designbase-wc-navbar__user-dropdown-menu");e&&(e.hidden=!this.userMenuOpen)}renderMobileMenu(){const e=this.querySelector(".designbase-wc-navbar__mobile-nav-list");if(!e)return;const t=this.getAttribute("size")||"m",a=this.parseItems();e.replaceChildren(...a.map(e=>this.createMobileMenuItem(e,t)))}render(){this.syncHostClasses(),this.setAttribute("role","navigation"),this.hasAttribute("aria-label")||this.setAttribute("aria-label",t("메인 네비게이션"));const e=this.getAttribute("size")||"m",n=this.iconSize(e),s=this.parseItems(),i=this.parseItems("user-menu-items"),r=this.parseUserProfile(),c=this.hasAttribute("is-authenticated"),d=this.hasAttribute("show-search"),l=this.querySelector('[slot="brand"]'),o=this.querySelector('[slot="actions"]');this.replaceChildren();const b=document.createElement("div");b.className=["designbase-wc-navbar__container",this.hasAttribute("full-width")&&"designbase-wc-navbar__container--full-width"].filter(Boolean).join(" ");const u=document.createElement("div");u.className="designbase-wc-navbar__left";const m=document.createElement("div");m.className="designbase-wc-navbar__brand";const p=document.createElement("div");p.className="designbase-wc-navbar__logo";const h=document.createElement("db-logo"),v=this.getAttribute("logo-src");h.setAttribute("type",v?"custom":"designbase"),v&&h.setAttribute("src",v),h.setAttribute("alt",this.getAttribute("logo-alt")||"홈"),h.setAttribute("size","s"),h.setAttribute("clickable",""),h.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-logo-click",{bubbles:!0,composed:!0}))}),p.append(h),m.append(l||p),u.append(m);const g=document.createElement("div");g.className="designbase-wc-navbar__right";const _=document.createElement("div");_.className="designbase-wc-navbar__nav designbase-wc-navbar__nav--desktop";const f=document.createElement("ul");if(f.className="designbase-wc-navbar__nav-list",s.forEach(e=>f.append(this.createDesktopNavItem(e,n))),_.append(f),g.append(_),d){const t=document.createElement("div");t.className="designbase-wc-navbar__search";const a=document.createElement("db-search-bar");a.setAttribute("variant","outlined"),a.setAttribute("size","s"===e?"s":"l"===e?"l":"m"),a.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(a),t.append(a),g.append(t)}const w=document.createElement("div");if(w.className="designbase-wc-navbar__user-menu",c&&r){const t=document.createElement("div");t.className="designbase-wc-navbar__user-dropdown";const n=document.createElement("button");n.type="button",n.className="designbase-wc-navbar__user-toggle",n.setAttribute("aria-expanded",String(this.userMenuOpen));const s=document.createElement("db-avatar");this.applyAvatarProfile(s,r,e);const c=document.createElement("span");c.className="designbase-wc-navbar__user-name",c.textContent=r.name,n.append(s,c,a("chevron-down",12)),n.addEventListener("click",()=>{this.userMenuOpen=!this.userMenuOpen,n.setAttribute("aria-expanded",String(this.userMenuOpen)),this.updateUserMenuVisibility()});const d=document.createElement("ul");if(d.className="designbase-wc-navbar__user-dropdown-menu",d.hidden=!this.userMenuOpen,r.email){const e=document.createElement("li");e.className="designbase-wc-navbar__user-info";const t=document.createElement("span");t.className="designbase-wc-navbar__user-email",t.textContent=r.email,e.append(t),d.append(e)}i.forEach(t=>{const a=document.createElement("li");a.append(this.createUserMenuItemElement(t,e,()=>{this.userMenuOpen=!1,this.updateUserMenuVisibility()})),d.append(a)}),t.append(n,d),w.append(t)}else{const a=document.createElement("db-button");a.setAttribute("variant","primary"),a.setAttribute("size","s"===e?"s":"l"===e?"l":"m"),a.textContent=t("로그인"),a.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),w.append(a)}g.append(o||w);const E=document.createElement("button");E.type="button",E.className="designbase-wc-navbar__mobile-toggle",E.setAttribute("aria-expanded",String(this.mobileOpen)),this.mobileOpen&&E.setAttribute("aria-controls",this.mobileMenuId),E.setAttribute("aria-label",t(this.mobileOpen?"메뉴 닫기":"메뉴 열기"));for(let e=0;e<3;e+=1){const e=document.createElement("span");e.className="designbase-wc-navbar__mobile-toggle-line",E.append(e)}if(E.addEventListener("click",()=>{this.mobileOpen=!this.mobileOpen,this.render(),this.querySelector(".designbase-wc-navbar__mobile-toggle")?.focus()}),b.append(u,g,E),this.append(b),this.mobileOpen){const e=document.createElement("div");if(e.className="designbase-wc-navbar__mobile-menu",e.id=this.mobileMenuId,e.addEventListener("keydown",e=>{"Escape"===e.key&&(this.mobileOpen=!1,this.render(),this.querySelector(".designbase-wc-navbar__mobile-toggle")?.focus())}),d){const t=document.createElement("div");t.className="designbase-wc-navbar__mobile-search";const a=document.createElement("db-search-bar");a.setAttribute("variant","outlined"),a.setAttribute("size","s"),a.setAttribute("full-width",""),a.setAttribute("placeholder",this.getAttribute("search-placeholder")||"검색..."),this.bindSearchEvents(a),t.append(a),e.append(t)}const a=document.createElement("div");a.className="designbase-wc-navbar__mobile-nav-list",e.append(a);const n=document.createElement("div");if(n.className="designbase-wc-navbar__mobile-user",c&&r){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-info";const t=document.createElement("db-avatar");this.applyAvatarProfile(t,r,"m");const a=document.createElement("div"),s=document.createElement("div");if(s.className="designbase-wc-navbar__mobile-user-name",s.textContent=r.name,a.append(s),r.email){const e=document.createElement("div");e.className="designbase-wc-navbar__mobile-user-email",e.textContent=r.email,a.append(e)}if(e.append(t,a),n.append(e),i.length){const e=document.createElement("ul");e.className="designbase-wc-navbar__mobile-user-menu",i.forEach(t=>{const a=document.createElement("li");a.append(this.createUserMenuItemElement(t,"m",()=>{this.mobileOpen=!1,this.render()})),e.append(a)}),n.append(e)}}else{const e=document.createElement("db-button");e.setAttribute("variant","primary"),e.setAttribute("size","m"),e.setAttribute("full-width",""),e.textContent=t("로그인"),e.addEventListener("db-click",()=>{this.dispatchEvent(new CustomEvent("db-login-click",{bubbles:!0,composed:!0}))}),n.append(e)}o||e.append(n),this.append(e),this.renderMobileMenu()}}}DbNavbar.nextId=0,customElements.get("db-navbar")||customElements.define("db-navbar",DbNavbar);export{DbNavbar};
|