@diniz/webcomponents 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +959 -959
- package/dist/README.md +959 -0
- package/dist/style.css +1256 -0
- package/dist/webcomponents.es.js +1721 -0
- package/dist/webcomponents.umd.js +326 -0
- package/package.json +1 -1
- package/dist/assets/checkbox-demo-page-C-tPBGML.js +0 -152
- package/dist/assets/dashboard-page-DG9XqSlN.js +0 -34
- package/dist/assets/date-picker-demo-BFqT8vXb.js +0 -146
- package/dist/assets/index-BiVNQ5Fp.js +0 -343
- package/dist/assets/index-DFxj0POj.css +0 -1
- package/dist/assets/input-demo-C8SDvXHc.js +0 -113
- package/dist/assets/modal-demo-page-DdQtx_aK.js +0 -164
- package/dist/assets/modal-h8khzJNk.js +0 -36
- package/dist/assets/select-demo-page-yyBh86Yw.js +0 -186
- package/dist/assets/table-DAobVRE7.js +0 -12
- package/dist/assets/table-demo-Dv1cyM0s.js +0 -74
- package/dist/assets/tabs-demo-BZZ6mTYB.js +0 -68
- package/dist/assets/vendor-BvJLUv9i.js +0 -5
- package/dist/index.html +0 -35
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
var f=Object.defineProperty;var y=(s,a,t)=>a in s?f(s,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[a]=t;var n=(s,a,t)=>y(s,typeof a!="symbol"?a+"":a,t);import{B as v,t as E}from"./index-BiVNQ5Fp.js";import"./vendor-BvJLUv9i.js";class x extends v{constructor(){super();n(this,"inputEl",null);n(this,"customValidator",null);n(this,"validationRule",null);this.state={value:"",valid:!0,touched:!1,error:""}}static get observedAttributes(){return["type","label","placeholder","required","pattern","minlength","maxlength","min","max","error-message","custom-error","disabled","name","validate"]}connectedCallback(){this.setAttribute("data-ui","input"),super.connectedCallback()}attributeChangedCallback(t,e,i){e!==i&&t!=="value"&&this.render()}setCustomValidator(t){this.customValidator=t,this.validate()}get value(){return this.state.value}set value(t){this.state.value=t,this.inputEl&&this.inputEl.value!==t&&(this.inputEl.value=t),this.validate()}get isValid(){return this.state.valid}checkValidity(){return this.state.touched=!0,this.validate()}reportValidity(){this.state.touched=!0;const t=this.validate();return this.updateErrorDisplay(),!t&&this.inputEl&&this.inputEl.focus(),t}getType(){const t=this.getAttribute("type");return["text","email","password","number","tel","url"].includes(t||"")?t:"text"}getLabel(){return this.getAttribute("label")||""}getPlaceholder(){return this.getAttribute("placeholder")||""}getName(){return this.getAttribute("name")||""}getErrorMessage(){return this.state.error?this.state.error:this.getAttribute("error-message")||this.getAttribute("custom-error")||""}getCustomError(){return this.getAttribute("custom-error")||""}parseValidationRule(t){return t.startsWith("email:")?{type:"emailDomain",domain:t.slice(6)}:t.startsWith("match:")?{type:"match",selector:t.slice(6)}:t.startsWith("min:")?{type:"minLength",length:parseInt(t.slice(4),10)}:t.startsWith("max:")?{type:"maxLength",length:parseInt(t.slice(4),10)}:t.startsWith("regex:")?{type:"regex",pattern:t.slice(6)}:null}applyValidationRule(t){const e=this.state.value;switch(t.type){case"emailDomain":if(!e.endsWith(`@${t.domain}`))return{valid:!1,message:`Must end with @${t.domain}`};break;case"match":const i=document.querySelector(t.selector);if(i&&e!==i.value)return{valid:!1,message:"Values do not match"};break;case"minLength":if(e.length<t.length)return{valid:!1,message:`Must be at least ${t.length} characters`};break;case"maxLength":if(e.length>t.length)return{valid:!1,message:`Must be no more than ${t.length} characters`};break;case"regex":try{if(!new RegExp(t.pattern).test(e))return{valid:!1,message:"Invalid format"}}catch{return{valid:!1,message:"Invalid validation pattern"}}break}return{valid:!0}}validate(){if(!this.inputEl)return!0;const t=this.getAttribute("validate");if(t&&(this.validationRule||(this.validationRule=this.parseValidationRule(t)),this.validationRule)){const e=this.applyValidationRule(this.validationRule);return this.state.valid=e.valid,!e.valid&&e.message&&(this.state.error=e.message),this.state.valid}if(this.customValidator){const e=this.customValidator(this.state.value,this.inputEl);this.state.valid=e.valid,!e.valid&&e.message&&(this.state.error=e.message)}else{const e=this.inputEl.checkValidity();this.state.valid=e,!e&&this.state.touched&&(this.state.error=this.inputEl.validationMessage||this.getErrorMessage()),e&&(this.state.error="")}return this.state.valid}handleInput(t){const e=t.target;this.state.value=e.value,this.state.touched=!0,this.validate(),this.updateErrorDisplay()}handleBlur(){this.state.touched=!0,this.validate(),this.updateErrorDisplay()}updateErrorDisplay(){if(!this.inputEl)return;const t=this.shadowRoot.querySelector(".input-error"),e=this.shadowRoot.querySelector(".input-wrapper"),i=this.getName();e&&e.classList.toggle("invalid",!this.state.valid&&this.state.touched),t&&(!this.state.valid&&this.state.touched&&this.state.error?(t.textContent=this.state.error,t.classList.remove("hidden")):t.classList.add("hidden")),this.inputEl.setAttribute("aria-invalid",String(!this.state.valid&&this.state.touched)),i&&this.inputEl.setAttribute("aria-describedby",`${i}-error`)}needsRender(){return this.hasAttribute("type")||this.hasAttribute("label")||this.hasAttribute("placeholder")||this.hasAttribute("required")||this.hasAttribute("pattern")||this.hasAttribute("disabled")||this.hasAttribute("name")||this.hasAttribute("minlength")||this.hasAttribute("maxlength")||this.hasAttribute("min")||this.hasAttribute("max")||this.hasAttribute("error-message")||this.hasAttribute("custom-error")||this.hasAttribute("validate")}render(){const t=this.getType(),e=this.getLabel(),i=this.getPlaceholder(),r=this.getName(),l=this.getErrorMessage(),u=this.hasAttribute("required"),d=this.getAttribute("pattern"),h=this.getAttribute("minlength"),m=this.getAttribute("maxlength"),c=this.getAttribute("min"),p=this.getAttribute("max"),g=this.hasAttribute("disabled"),o=!this.state.valid&&this.state.touched,b=e!=="";this.shadowRoot.innerHTML=`
|
|
2
|
-
<style>${E}</style>
|
|
3
|
-
<div class="input-wrapper${o?" invalid":""}${g?" disabled":""}">
|
|
4
|
-
${b?`<label class="input-label">${e}${u?" *":""}</label>`:""}
|
|
5
|
-
<input
|
|
6
|
-
part="input"
|
|
7
|
-
class="input-field"
|
|
8
|
-
type="${t}"
|
|
9
|
-
placeholder="${i}"
|
|
10
|
-
name="${r}"
|
|
11
|
-
.value="${this.state.value}"
|
|
12
|
-
${u?"required":""}
|
|
13
|
-
${d?`pattern="${d}"`:""}
|
|
14
|
-
${h?`minlength="${h}"`:""}
|
|
15
|
-
${m?`maxlength="${m}"`:""}
|
|
16
|
-
${c?`min="${c}"`:""}
|
|
17
|
-
${p?`max="${p}"`:""}
|
|
18
|
-
${g?"disabled":""}
|
|
19
|
-
aria-invalid="${o}"
|
|
20
|
-
aria-describedby="${r}-error"
|
|
21
|
-
/>
|
|
22
|
-
<span class="input-error${o&&l?"":" hidden"}" id="${r}-error" role="alert">${l}</span>
|
|
23
|
-
</div>
|
|
24
|
-
`,this.inputEl=this.shadowRoot.querySelector(".input-field"),this.inputEl&&(this.inputEl.addEventListener("input",this.handleInput.bind(this)),this.inputEl.addEventListener("blur",this.handleBlur.bind(this)))}}customElements.define("ui-input",x);const A=`<div class="demo-container">
|
|
25
|
-
<h1>Input Component Demo</h1>
|
|
26
|
-
<p class="demo-description">
|
|
27
|
-
Explore the <code><ui-input></code> component with various validation scenarios.
|
|
28
|
-
</p>
|
|
29
|
-
|
|
30
|
-
<section class="demo-section">
|
|
31
|
-
<h2>Basic Inputs</h2>
|
|
32
|
-
<div class="form-grid">
|
|
33
|
-
<ui-input
|
|
34
|
-
label="Username"
|
|
35
|
-
placeholder="Enter your username"
|
|
36
|
-
name="username"
|
|
37
|
-
required
|
|
38
|
-
minlength="3"
|
|
39
|
-
maxlength="20"
|
|
40
|
-
></ui-input>
|
|
41
|
-
|
|
42
|
-
<ui-input
|
|
43
|
-
label="Email"
|
|
44
|
-
type="email"
|
|
45
|
-
placeholder="you@example.com"
|
|
46
|
-
name="email"
|
|
47
|
-
required
|
|
48
|
-
></ui-input>
|
|
49
|
-
|
|
50
|
-
<ui-input
|
|
51
|
-
label="Password"
|
|
52
|
-
type="password"
|
|
53
|
-
placeholder="Enter password"
|
|
54
|
-
name="password"
|
|
55
|
-
required
|
|
56
|
-
minlength="8"
|
|
57
|
-
></ui-input>
|
|
58
|
-
|
|
59
|
-
<ui-input
|
|
60
|
-
label="Phone"
|
|
61
|
-
type="tel"
|
|
62
|
-
placeholder="(555) 123-4567"
|
|
63
|
-
name="phone"
|
|
64
|
-
pattern="[0-9\\-\\(\\)\\s]+"
|
|
65
|
-
></ui-input>
|
|
66
|
-
</div>
|
|
67
|
-
</section>
|
|
68
|
-
|
|
69
|
-
<section class="demo-section">
|
|
70
|
-
<h2>Custom Validation</h2>
|
|
71
|
-
<p>Email must end with <code>@company.com</code></p>
|
|
72
|
-
<div class="form-grid">
|
|
73
|
-
<ui-input
|
|
74
|
-
label="Corporate Email"
|
|
75
|
-
type="email"
|
|
76
|
-
placeholder="you@company.com"
|
|
77
|
-
name="corp-email"
|
|
78
|
-
required
|
|
79
|
-
validate="email:company.com"
|
|
80
|
-
custom-error="Must be a company.com email"
|
|
81
|
-
id="corp-email"
|
|
82
|
-
></ui-input>
|
|
83
|
-
|
|
84
|
-
<ui-input
|
|
85
|
-
label="Confirm Email"
|
|
86
|
-
type="email"
|
|
87
|
-
placeholder="Confirm your email"
|
|
88
|
-
name="confirm-email"
|
|
89
|
-
required
|
|
90
|
-
validate="match:#corp-email"
|
|
91
|
-
custom-error="Emails must match"
|
|
92
|
-
id="confirm-email"
|
|
93
|
-
></ui-input>
|
|
94
|
-
</div>
|
|
95
|
-
</section>
|
|
96
|
-
|
|
97
|
-
<section class="demo-section">
|
|
98
|
-
<h2>Disabled State</h2>
|
|
99
|
-
<div class="form-grid">
|
|
100
|
-
<ui-input
|
|
101
|
-
label="Disabled Input"
|
|
102
|
-
placeholder="Cannot edit"
|
|
103
|
-
name="disabled"
|
|
104
|
-
value="This is disabled"
|
|
105
|
-
disabled
|
|
106
|
-
></ui-input>
|
|
107
|
-
</div>
|
|
108
|
-
</section>
|
|
109
|
-
</div>
|
|
110
|
-
`,$=".demo-container{padding:2rem;max-width:800px}.demo-container h1{margin:0 0 .5rem;color:var(--color-ink)}.demo-description{color:#64748b;margin-bottom:2rem}.demo-description code{background:var(--color-muted);padding:.15rem .4rem;border-radius:4px;font-size:.9em}.demo-section{margin-bottom:2.5rem;padding:1.5rem;background:var(--color-page-bg);border:1px solid var(--color-border);border-radius:var(--radius-md)}.demo-section h2{margin:0 0 1rem;font-size:1.25rem;color:var(--color-ink)}.demo-section>p{margin:0 0 1rem;color:#64748b}.form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:1.25rem}.form-actions{margin-top:1.5rem;display:flex;gap:.75rem}.demo-form{margin-bottom:1rem}.form-result{margin-top:1rem;padding:.75rem 1rem;background:var(--color-muted);border-radius:6px;display:flex;gap:.5rem}.result-label{font-weight:600;color:var(--color-ink)}.result-value{color:#64748b}.result-value.valid{color:#24ec71}.result-value.invalid{color:#ef4444}";class w extends v{constructor(){super(...arguments);n(this,"formResult",null);n(this,"statusSpan",null)}render(){this.shadowRoot.innerHTML=`
|
|
111
|
-
<style>${$}</style>
|
|
112
|
-
${A}
|
|
113
|
-
`,this.formResult=this.shadowRoot.querySelector("#form-result"),this.statusSpan=this.shadowRoot.querySelector("#result-status");const t=this.shadowRoot.querySelector("#demo-form"),e=this.shadowRoot.querySelector("#reset-btn");t&&t.addEventListener("submit",this.handleSubmit.bind(this)),e&&e.addEventListener("click",this.handleReset.bind(this))}async handleSubmit(t){t.preventDefault();const e=Array.from(this.shadowRoot.querySelectorAll("ui-input"));let i=!0;for(const r of e)r.reportValidity()||(i=!1);this.statusSpan&&(this.statusSpan.textContent=i?"Valid":"Invalid",this.statusSpan.className=`result-value ${i?"valid":"invalid"}`)}handleReset(){this.shadowRoot.querySelectorAll("ui-input").forEach(e=>{e.value=""}),this.statusSpan&&(this.statusSpan.textContent="Not validated",this.statusSpan.className="result-value")}}customElements.define("input-demo",w);export{w as InputDemo};
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import{B as w}from"./index-BiVNQ5Fp.js";import"./modal-h8khzJNk.js";import"./vendor-BvJLUv9i.js";const B=`
|
|
2
|
-
<div class="demo-container">
|
|
3
|
-
<h1>Modal Component Demo</h1>
|
|
4
|
-
<p>Interactive modals with various sizes and configurations.</p>
|
|
5
|
-
|
|
6
|
-
<div class="demo-section">
|
|
7
|
-
<h2>Basic Modals</h2>
|
|
8
|
-
<div class="demo-controls">
|
|
9
|
-
<ui-button id="openBasicModal" variant="primary" icon="maximize-2">
|
|
10
|
-
Open Basic Modal
|
|
11
|
-
</ui-button>
|
|
12
|
-
<ui-button id="openSmallModal" variant="secondary">
|
|
13
|
-
Small Modal
|
|
14
|
-
</ui-button>
|
|
15
|
-
<ui-button id="openLargeModal" variant="secondary">
|
|
16
|
-
Large Modal
|
|
17
|
-
</ui-button>
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
<div class="demo-section">
|
|
22
|
-
<h2>Modal Behaviors</h2>
|
|
23
|
-
<div class="demo-controls">
|
|
24
|
-
<ui-button id="openNoEscapeModal" variant="ghost">
|
|
25
|
-
No Close on Escape
|
|
26
|
-
</ui-button>
|
|
27
|
-
<ui-button id="openNoBackdropModal" variant="ghost">
|
|
28
|
-
No Close on Backdrop
|
|
29
|
-
</ui-button>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
<div class="demo-section">
|
|
34
|
-
<h2>Confirmation Modal</h2>
|
|
35
|
-
<div class="demo-controls">
|
|
36
|
-
<ui-button id="openConfirmModal" variant="primary" icon="alert-circle">
|
|
37
|
-
Delete Item
|
|
38
|
-
</ui-button>
|
|
39
|
-
</div>
|
|
40
|
-
<div id="confirmResult" class="result-display" style="display: none;">
|
|
41
|
-
<strong>Result:</strong> <span id="confirmText"></span>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<!-- Modals -->
|
|
46
|
-
<ui-modal id="basicModal" title="Welcome!" size="md">
|
|
47
|
-
<p>This is a basic modal with a title and content.</p>
|
|
48
|
-
<p>You can close it by:</p>
|
|
49
|
-
<ul>
|
|
50
|
-
<li>Clicking the X button</li>
|
|
51
|
-
<li>Pressing the Escape key</li>
|
|
52
|
-
<li>Clicking outside the modal</li>
|
|
53
|
-
</ul>
|
|
54
|
-
<div slot="footer">
|
|
55
|
-
<ui-button id="basicModalClose" variant="secondary">Close</ui-button>
|
|
56
|
-
<ui-button id="basicModalOk" variant="primary">Got it!</ui-button>
|
|
57
|
-
</div>
|
|
58
|
-
</ui-modal>
|
|
59
|
-
|
|
60
|
-
<ui-modal id="smallModal" title="Small Modal" size="sm">
|
|
61
|
-
<p>This is a small modal perfect for quick messages or confirmations.</p>
|
|
62
|
-
<div slot="footer">
|
|
63
|
-
<ui-button id="smallModalClose" variant="primary">Close</ui-button>
|
|
64
|
-
</div>
|
|
65
|
-
</ui-modal>
|
|
66
|
-
|
|
67
|
-
<ui-modal id="largeModal" title="Large Modal" size="lg">
|
|
68
|
-
<p>This is a large modal that can contain more content.</p>
|
|
69
|
-
<div style="height: 400px; background: #f1f5f9; border-radius: 8px; padding: 1rem; margin: 1rem 0;">
|
|
70
|
-
<p><strong>Scrollable Content Area</strong></p>
|
|
71
|
-
<p>When content exceeds the modal height, it automatically becomes scrollable.</p>
|
|
72
|
-
${Array(20).fill("<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>").join("")}
|
|
73
|
-
</div>
|
|
74
|
-
<div slot="footer">
|
|
75
|
-
<ui-button id="largeModalClose" variant="primary">Close</ui-button>
|
|
76
|
-
</div>
|
|
77
|
-
</ui-modal>
|
|
78
|
-
|
|
79
|
-
<ui-modal id="noEscapeModal" title="No Escape Close" size="md" no-close-on-escape>
|
|
80
|
-
<p>This modal cannot be closed by pressing the Escape key.</p>
|
|
81
|
-
<p>You must click the close button or click outside.</p>
|
|
82
|
-
<div slot="footer">
|
|
83
|
-
<ui-button id="noEscapeClose" variant="primary">Close</ui-button>
|
|
84
|
-
</div>
|
|
85
|
-
</ui-modal>
|
|
86
|
-
|
|
87
|
-
<ui-modal id="noBackdropModal" title="No Backdrop Close" size="md" no-close-on-backdrop>
|
|
88
|
-
<p>This modal cannot be closed by clicking the backdrop.</p>
|
|
89
|
-
<p>You must use the close button or press Escape.</p>
|
|
90
|
-
<div slot="footer">
|
|
91
|
-
<ui-button id="noBackdropClose" variant="primary">Close</ui-button>
|
|
92
|
-
</div>
|
|
93
|
-
</ui-modal>
|
|
94
|
-
|
|
95
|
-
<ui-modal id="confirmModal" title="Confirm Delete" size="sm">
|
|
96
|
-
<p>Are you sure you want to delete this item?</p>
|
|
97
|
-
<p style="color: #ef4444; font-size: 0.875rem;">This action cannot be undone.</p>
|
|
98
|
-
<div slot="footer">
|
|
99
|
-
<ui-button id="confirmCancel" variant="ghost">Cancel</ui-button>
|
|
100
|
-
<ui-button id="confirmDelete" variant="primary" icon="trash-2">Delete</ui-button>
|
|
101
|
-
</div>
|
|
102
|
-
</ui-modal>
|
|
103
|
-
</div>
|
|
104
|
-
`,C=`
|
|
105
|
-
.demo-container {
|
|
106
|
-
padding: 2rem;
|
|
107
|
-
max-width: 1200px;
|
|
108
|
-
margin: 0 auto;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.demo-container h1 {
|
|
112
|
-
font-size: 2rem;
|
|
113
|
-
margin-bottom: 0.5rem;
|
|
114
|
-
color: var(--color-ink);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.demo-container > p {
|
|
118
|
-
color: var(--color-text-muted);
|
|
119
|
-
margin-bottom: 2rem;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
.demo-section {
|
|
123
|
-
margin-bottom: 3rem;
|
|
124
|
-
padding-bottom: 2rem;
|
|
125
|
-
border-bottom: 1px solid var(--color-border);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.demo-section:last-child {
|
|
129
|
-
border-bottom: none;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.demo-section h2 {
|
|
133
|
-
font-size: 1.5rem;
|
|
134
|
-
margin-bottom: 1rem;
|
|
135
|
-
color: var(--color-ink);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.demo-controls {
|
|
139
|
-
display: flex;
|
|
140
|
-
gap: 1rem;
|
|
141
|
-
flex-wrap: wrap;
|
|
142
|
-
margin-top: 1rem;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.result-display {
|
|
146
|
-
margin-top: 1rem;
|
|
147
|
-
padding: 1rem;
|
|
148
|
-
background: var(--color-muted);
|
|
149
|
-
border-radius: var(--radius-md);
|
|
150
|
-
border-left: 4px solid var(--color-primary);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
ul {
|
|
154
|
-
margin: 1rem 0;
|
|
155
|
-
padding-left: 1.5rem;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
li {
|
|
159
|
-
margin: 0.5rem 0;
|
|
160
|
-
}
|
|
161
|
-
`;class R extends w{async connectedCallback(){super.connectedCallback(),await Promise.all([customElements.whenDefined("ui-modal"),customElements.whenDefined("ui-button")]),await new Promise(a=>setTimeout(a,10)),this.setupEventListeners()}setupEventListeners(){const a=this.shadowRoot.getElementById("openBasicModal"),o=this.shadowRoot.getElementById("basicModal"),r=this.shadowRoot.getElementById("basicModalClose"),c=this.shadowRoot.getElementById("basicModalOk");a==null||a.addEventListener("click",()=>o==null?void 0:o.open()),r==null||r.addEventListener("click",()=>o==null?void 0:o.close()),c==null||c.addEventListener("click",()=>o==null?void 0:o.close());const m=this.shadowRoot.getElementById("openSmallModal"),e=this.shadowRoot.getElementById("smallModal"),u=this.shadowRoot.getElementById("smallModalClose");m==null||m.addEventListener("click",()=>e==null?void 0:e.open()),u==null||u.addEventListener("click",()=>e==null?void 0:e.close());const p=this.shadowRoot.getElementById("openLargeModal"),i=this.shadowRoot.getElementById("largeModal"),h=this.shadowRoot.getElementById("largeModalClose");p==null||p.addEventListener("click",()=>i==null?void 0:i.open()),h==null||h.addEventListener("click",()=>i==null?void 0:i.close());const v=this.shadowRoot.getElementById("openNoEscapeModal"),n=this.shadowRoot.getElementById("noEscapeModal"),g=this.shadowRoot.getElementById("noEscapeClose");v==null||v.addEventListener("click",()=>n==null?void 0:n.open()),g==null||g.addEventListener("click",()=>n==null?void 0:n.close());const b=this.shadowRoot.getElementById("openNoBackdropModal"),s=this.shadowRoot.getElementById("noBackdropModal"),y=this.shadowRoot.getElementById("noBackdropClose");b==null||b.addEventListener("click",()=>s==null?void 0:s.open()),y==null||y.addEventListener("click",()=>s==null?void 0:s.close());const E=this.shadowRoot.getElementById("openConfirmModal"),t=this.shadowRoot.getElementById("confirmModal"),f=this.shadowRoot.getElementById("confirmCancel"),k=this.shadowRoot.getElementById("confirmDelete"),l=this.shadowRoot.getElementById("confirmResult"),d=this.shadowRoot.getElementById("confirmText");E==null||E.addEventListener("click",()=>t==null?void 0:t.open()),f==null||f.addEventListener("click",()=>{t==null||t.close(),l&&d&&(l.style.display="block",d.textContent="Cancelled",d.style.color="#64748b")}),k==null||k.addEventListener("click",()=>{t==null||t.close(),l&&d&&(l.style.display="block",d.textContent="Item deleted!",d.style.color="#ef4444")})}render(){this.shadowRoot.innerHTML=`
|
|
162
|
-
<style>${C}</style>
|
|
163
|
-
${B}
|
|
164
|
-
`}}customElements.define("modal-demo-page",R);
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
var c=Object.defineProperty;var r=(s,e,t)=>e in s?c(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var d=(s,e,t)=>r(s,typeof e!="symbol"?e+"":e,t);import{B as h,t as p}from"./index-BiVNQ5Fp.js";class u extends h{constructor(){super(...arguments);d(this,"isOpen",this.useSignal(!1))}connectedCallback(){this.setAttribute("data-ui","modal"),super.connectedCallback(),this.setupEventListeners()}static get observedAttributes(){return["open"]}attributeChangedCallback(t,o,i){t==="open"&&o!==i&&this.isOpen.set(i!==null)}setupEventListeners(){document.addEventListener("keydown",t=>{t.key==="Escape"&&this.isOpen.get()&&!this.hasAttribute("no-close-on-escape")&&this.close()})}open(){this.isOpen.set(!0),this.setAttribute("open",""),this.dispatchEvent(new CustomEvent("modal-open",{bubbles:!0,composed:!0})),document.body.style.overflow="hidden"}close(){this.isOpen.set(!1),this.removeAttribute("open"),this.dispatchEvent(new CustomEvent("modal-close",{bubbles:!0,composed:!0})),document.body.style.overflow=""}handleBackdropClick(t){t.target.classList.contains("modal-backdrop")&&!this.hasAttribute("no-close-on-backdrop")&&this.close()}render(){const t=this.isOpen.get(),o=this.getAttribute("title")||"",i=this.getAttribute("size")||"md";this.shadowRoot.innerHTML=`
|
|
2
|
-
<style>
|
|
3
|
-
${p}
|
|
4
|
-
|
|
5
|
-
::slotted([slot="footer"]) {
|
|
6
|
-
display: flex;
|
|
7
|
-
gap: 0.75rem;
|
|
8
|
-
width: 100%;
|
|
9
|
-
justify-content: flex-end;
|
|
10
|
-
}
|
|
11
|
-
</style>
|
|
12
|
-
|
|
13
|
-
<div class="modal-backdrop ${t?"open":""}" part="backdrop">
|
|
14
|
-
<div class="modal-content ${i}" part="content" @click="${a=>a.stopPropagation()}">
|
|
15
|
-
${o?`
|
|
16
|
-
<div class="modal-header" part="header">
|
|
17
|
-
<h2 class="modal-title">${o}</h2>
|
|
18
|
-
<button class="modal-close" part="close" aria-label="Close modal">
|
|
19
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
20
|
-
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
21
|
-
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
22
|
-
</svg>
|
|
23
|
-
</button>
|
|
24
|
-
</div>
|
|
25
|
-
`:""}
|
|
26
|
-
|
|
27
|
-
<div class="modal-body" part="body">
|
|
28
|
-
<slot></slot>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<div class="modal-footer" part="footer">
|
|
32
|
-
<slot name="footer"></slot>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
`;const l=this.shadowRoot.querySelector(".modal-backdrop"),n=this.shadowRoot.querySelector(".modal-close");l==null||l.addEventListener("click",a=>this.handleBackdropClick(a)),n==null||n.addEventListener("click",()=>this.close())}}customElements.define("ui-modal",u);
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
var w=Object.defineProperty;var E=(c,l,e)=>l in c?w(c,l,{enumerable:!0,configurable:!0,writable:!0,value:e}):c[l]=e;var m=(c,l,e)=>E(c,typeof l!="symbol"?l+"":l,e);import{B as y,t as R}from"./index-BiVNQ5Fp.js";import"./vendor-BvJLUv9i.js";const k=`
|
|
2
|
-
<div class="demo-container">
|
|
3
|
-
<h1>Select Component Demo</h1>
|
|
4
|
-
<p>Customizable dropdown select with search and multi-configuration options.</p>
|
|
5
|
-
|
|
6
|
-
<div class="demo-section">
|
|
7
|
-
<h2>Basic Select</h2>
|
|
8
|
-
<div class="demo-grid">
|
|
9
|
-
<ui-select
|
|
10
|
-
id="basicSelect"
|
|
11
|
-
label="Choose a Fruit"
|
|
12
|
-
placeholder="Select a fruit..."
|
|
13
|
-
></ui-select>
|
|
14
|
-
|
|
15
|
-
<ui-select
|
|
16
|
-
id="disabledSelect"
|
|
17
|
-
label="Disabled Select"
|
|
18
|
-
placeholder="Not available"
|
|
19
|
-
disabled
|
|
20
|
-
></ui-select>
|
|
21
|
-
</div>
|
|
22
|
-
<div id="basicResult" class="result-display" style="display: none;">
|
|
23
|
-
<strong>Selected:</strong> <span id="basicValue"></span>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
<div class="demo-section">
|
|
28
|
-
<h2>Searchable Select</h2>
|
|
29
|
-
<div class="demo-grid">
|
|
30
|
-
<ui-select
|
|
31
|
-
id="searchableSelect"
|
|
32
|
-
label="Choose a Country"
|
|
33
|
-
placeholder="Search countries..."
|
|
34
|
-
searchable
|
|
35
|
-
></ui-select>
|
|
36
|
-
</div>
|
|
37
|
-
<div id="searchResult" class="result-display" style="display: none;">
|
|
38
|
-
<strong>Selected Country:</strong> <span id="searchValue"></span>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
|
|
42
|
-
<div class="demo-section">
|
|
43
|
-
<h2>Select Sizes & Preselected</h2>
|
|
44
|
-
<div class="demo-grid">
|
|
45
|
-
<ui-select
|
|
46
|
-
id="preselectedSelect"
|
|
47
|
-
label="Choose a Programming Language"
|
|
48
|
-
placeholder="Select language..."
|
|
49
|
-
value="javascript"
|
|
50
|
-
></ui-select>
|
|
51
|
-
</div>
|
|
52
|
-
<div id="preselectedResult" class="result-display" style="display: none;">
|
|
53
|
-
<strong>Selected:</strong> <span id="preselectedValue"></span>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<div class="demo-section">
|
|
58
|
-
<h2>Form Example</h2>
|
|
59
|
-
<form id="userForm" style="max-width: 600px;">
|
|
60
|
-
<ui-select
|
|
61
|
-
id="roleSelect"
|
|
62
|
-
label="User Role"
|
|
63
|
-
placeholder="Select role..."
|
|
64
|
-
></ui-select>
|
|
65
|
-
|
|
66
|
-
<ui-select
|
|
67
|
-
id="departmentSelect"
|
|
68
|
-
label="Department"
|
|
69
|
-
placeholder="Select department..."
|
|
70
|
-
></ui-select>
|
|
71
|
-
|
|
72
|
-
<div style="margin-top: 0.5rem; display: flex; gap: 1rem;">
|
|
73
|
-
<ui-button type="submit" variant="primary" icon="check">Submit</ui-button>
|
|
74
|
-
<ui-button type="button" id="resetForm" variant="ghost">Reset</ui-button>
|
|
75
|
-
</div>
|
|
76
|
-
</form>
|
|
77
|
-
<div id="formResult" class="result-display" style="display: none; margin-top: 1rem;">
|
|
78
|
-
<strong>Form Data:</strong><br>
|
|
79
|
-
<span id="formValue"></span>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
`,C=`
|
|
84
|
-
.demo-container {
|
|
85
|
-
padding: 2rem;
|
|
86
|
-
max-width: 1200px;
|
|
87
|
-
margin: 0 auto;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.demo-container h1 {
|
|
91
|
-
font-size: 2rem;
|
|
92
|
-
margin-bottom: 0.5rem;
|
|
93
|
-
color: var(--color-ink);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.demo-container > p {
|
|
97
|
-
color: var(--color-text-muted);
|
|
98
|
-
margin-bottom: 2rem;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.demo-section {
|
|
102
|
-
margin-bottom: 3rem;
|
|
103
|
-
padding-bottom: 2rem;
|
|
104
|
-
border-bottom: 1px solid var(--color-border);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.demo-section:last-child {
|
|
108
|
-
border-bottom: none;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.demo-section h2 {
|
|
112
|
-
font-size: 1.5rem;
|
|
113
|
-
margin-bottom: 1rem;
|
|
114
|
-
color: var(--color-ink);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.demo-grid {
|
|
118
|
-
display: grid;
|
|
119
|
-
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
120
|
-
gap: 1.5rem;
|
|
121
|
-
margin-top: 1rem;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.demo-grid > * {
|
|
125
|
-
min-width: 0;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.result-display {
|
|
129
|
-
margin-top: 1rem;
|
|
130
|
-
padding: 1rem;
|
|
131
|
-
background: var(--color-muted);
|
|
132
|
-
border-radius: var(--radius-md);
|
|
133
|
-
border-left: 4px solid var(--color-primary);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
form {
|
|
137
|
-
background: white;
|
|
138
|
-
padding: 1.5rem;
|
|
139
|
-
border-radius: var(--radius-lg);
|
|
140
|
-
border: 1px solid var(--color-border);
|
|
141
|
-
display: flex;
|
|
142
|
-
flex-direction: column;
|
|
143
|
-
gap: 1rem;
|
|
144
|
-
}
|
|
145
|
-
`;class O extends y{constructor(){super(...arguments);m(this,"isOpen",this.useSignal(!1));m(this,"selectedValue",this.useSignal(""));m(this,"searchTerm",this.useSignal(""));m(this,"options",[])}connectedCallback(){this.setAttribute("data-ui","select"),super.connectedCallback(),this.parseOptions(),this.setupClickOutside()}static get observedAttributes(){return["value","disabled","placeholder","options"]}attributeChangedCallback(e,t,a){e==="value"&&t!==a&&this.selectedValue.set(a||""),e==="options"&&t!==a&&this.parseOptions(),this.render()}parseOptions(){const e=this.getAttribute("options");if(e)try{this.options=JSON.parse(e)}catch(t){console.error("Invalid options JSON",t),this.options=[]}}setupClickOutside(){document.addEventListener("click",e=>{!e.composedPath().includes(this)&&this.isOpen.get()&&this.isOpen.set(!1)})}toggleDropdown(){this.hasAttribute("disabled")||(this.isOpen.set(!this.isOpen.get()),this.isOpen.get()||this.searchTerm.set(""))}selectOption(e){this.selectedValue.set(e),this.setAttribute("value",e),this.isOpen.set(!1),this.searchTerm.set(""),this.dispatchEvent(new CustomEvent("select-change",{bubbles:!0,composed:!0,detail:{value:e,option:this.options.find(t=>t.value===e)}}))}handleSearch(e){this.searchTerm.set(e.toLowerCase())}getFilteredOptions(){const e=this.searchTerm.get();return e?this.options.filter(t=>t.label.toLowerCase().includes(e)||t.value.toLowerCase().includes(e)):this.options}getSelectedLabel(){const e=this.selectedValue.get(),t=this.options.find(a=>a.value===e);return(t==null?void 0:t.label)||this.getAttribute("placeholder")||"Select an option"}render(){const e=this.isOpen.get(),t=this.hasAttribute("disabled"),a=this.hasAttribute("searchable"),u=this.getAttribute("label")||"",h=this.getSelectedLabel(),d=this.getFilteredOptions(),p=this.selectedValue.get()!=="";this.shadowRoot.innerHTML=`
|
|
146
|
-
<style>${R}</style>
|
|
147
|
-
|
|
148
|
-
<div class="select-container">
|
|
149
|
-
${u?`<label class="select-label">${u}</label>`:""}
|
|
150
|
-
|
|
151
|
-
<div class="select-trigger ${e?"open":""}" part="trigger" tabindex="0" ${t?"disabled":""}>
|
|
152
|
-
<span class="select-placeholder ${p?"has-selection":""}">${h}</span>
|
|
153
|
-
<span class="select-arrow ${e?"open":""}">
|
|
154
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
155
|
-
<polyline points="6 9 12 15 18 9"></polyline>
|
|
156
|
-
</svg>
|
|
157
|
-
</span>
|
|
158
|
-
</div>
|
|
159
|
-
|
|
160
|
-
<div class="select-dropdown ${e?"open":""}" part="dropdown">
|
|
161
|
-
${a?`
|
|
162
|
-
<input
|
|
163
|
-
type="text"
|
|
164
|
-
class="select-search"
|
|
165
|
-
placeholder="Search..."
|
|
166
|
-
part="search"
|
|
167
|
-
>
|
|
168
|
-
`:""}
|
|
169
|
-
|
|
170
|
-
${d.length>0?d.map(s=>`
|
|
171
|
-
<div
|
|
172
|
-
class="select-option ${s.value===this.selectedValue.get()?"selected":""} ${s.disabled?"disabled":""}"
|
|
173
|
-
data-value="${s.value}"
|
|
174
|
-
part="option"
|
|
175
|
-
>
|
|
176
|
-
${s.label}
|
|
177
|
-
</div>
|
|
178
|
-
`).join(""):`
|
|
179
|
-
<div class="select-empty">No options found</div>
|
|
180
|
-
`}
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
`;const o=this.shadowRoot.querySelector(".select-trigger"),i=this.shadowRoot.querySelector(".select-search"),n=this.shadowRoot.querySelectorAll(".select-option:not(.disabled)");o==null||o.addEventListener("click",()=>this.toggleDropdown()),o==null||o.addEventListener("keydown",s=>{(s.key==="Enter"||s.key===" ")&&(s.preventDefault(),this.toggleDropdown())}),i==null||i.addEventListener("input",s=>{this.handleSearch(s.target.value)}),i==null||i.addEventListener("click",s=>s.stopPropagation()),n.forEach(s=>{s.addEventListener("click",()=>{const b=s.getAttribute("data-value");b&&this.selectOption(b)})})}}customElements.define("ui-select",O);class B extends y{async connectedCallback(){super.connectedCallback(),await customElements.whenDefined("ui-select"),await new Promise(l=>setTimeout(l,10)),this.setupSelects(),this.setupEventListeners()}setupSelects(){const l=this.shadowRoot.getElementById("basicSelect"),e=this.shadowRoot.getElementById("disabledSelect"),t=[{value:"apple",label:"🍎 Apple"},{value:"banana",label:"🍌 Banana"},{value:"orange",label:"🍊 Orange"},{value:"grape",label:"🍇 Grape"},{value:"strawberry",label:"🍓 Strawberry"},{value:"watermelon",label:"🍉 Watermelon"}];l&&l.setAttribute("options",JSON.stringify(t)),e&&e.setAttribute("options",JSON.stringify(t));const a=this.shadowRoot.getElementById("searchableSelect"),u=[{value:"us",label:"United States"},{value:"uk",label:"United Kingdom"},{value:"ca",label:"Canada"},{value:"au",label:"Australia"},{value:"de",label:"Germany"},{value:"fr",label:"France"},{value:"jp",label:"Japan"},{value:"br",label:"Brazil"},{value:"in",label:"India"},{value:"cn",label:"China"}];a&&a.setAttribute("options",JSON.stringify(u));const h=this.shadowRoot.getElementById("preselectedSelect"),d=[{value:"javascript",label:"JavaScript"},{value:"typescript",label:"TypeScript"},{value:"python",label:"Python"},{value:"java",label:"Java"},{value:"csharp",label:"C#"},{value:"go",label:"Go"},{value:"rust",label:"Rust"}];h&&h.setAttribute("options",JSON.stringify(d));const p=this.shadowRoot.getElementById("roleSelect"),o=[{value:"admin",label:"Administrator"},{value:"manager",label:"Manager"},{value:"developer",label:"Developer"},{value:"designer",label:"Designer"},{value:"user",label:"User"}];p&&p.setAttribute("options",JSON.stringify(o));const i=this.shadowRoot.getElementById("departmentSelect"),n=[{value:"engineering",label:"Engineering"},{value:"design",label:"Design"},{value:"marketing",label:"Marketing"},{value:"sales",label:"Sales"},{value:"hr",label:"Human Resources"}];i&&i.setAttribute("options",JSON.stringify(n))}setupEventListeners(){const l=this.shadowRoot.getElementById("basicSelect"),e=this.shadowRoot.getElementById("basicResult"),t=this.shadowRoot.getElementById("basicValue");l==null||l.addEventListener("select-change",r=>{e&&t&&(e.style.display="block",t.textContent=`${r.detail.option.label} (${r.detail.value})`)});const a=this.shadowRoot.getElementById("searchableSelect"),u=this.shadowRoot.getElementById("searchResult"),h=this.shadowRoot.getElementById("searchValue");a==null||a.addEventListener("select-change",r=>{u&&h&&(u.style.display="block",h.textContent=`${r.detail.option.label} (${r.detail.value})`)});const d=this.shadowRoot.getElementById("preselectedSelect"),p=this.shadowRoot.getElementById("preselectedResult"),o=this.shadowRoot.getElementById("preselectedValue");d==null||d.addEventListener("select-change",r=>{p&&o&&(p.style.display="block",o.textContent=`${r.detail.option.label} (${r.detail.value})`)});const i=this.shadowRoot.getElementById("userForm"),n=this.shadowRoot.getElementById("roleSelect"),s=this.shadowRoot.getElementById("departmentSelect"),b=this.shadowRoot.getElementById("formResult"),v=this.shadowRoot.getElementById("formValue"),g=this.shadowRoot.getElementById("resetForm");i==null||i.addEventListener("submit",r=>{r.preventDefault();const f=(n==null?void 0:n.getAttribute("value"))||"Not selected",S=(s==null?void 0:s.getAttribute("value"))||"Not selected";b&&v&&(b.style.display="block",v.innerHTML=`Role: <strong>${f}</strong><br>Department: <strong>${S}</strong>`)}),g==null||g.addEventListener("click",()=>{n==null||n.removeAttribute("value"),s==null||s.removeAttribute("value"),b&&(b.style.display="none")})}render(){this.shadowRoot.innerHTML=`
|
|
184
|
-
<style>${C}</style>
|
|
185
|
-
${k}
|
|
186
|
-
`}}customElements.define("select-demo-page",B);
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
var h=Object.defineProperty;var u=(i,e,t)=>e in i?h(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var o=(i,e,t)=>u(i,typeof e!="symbol"?e+"":e,t);import{B as m,t as w}from"./index-BiVNQ5Fp.js";class $ extends m{constructor(){super(...arguments);o(this,"columns",[]);o(this,"rows",[])}connectedCallback(){this.setAttribute("data-ui","table"),super.connectedCallback()}set data(t){this.columns=t.columns,this.rows=t.rows,this.render()}get data(){return{columns:this.columns,rows:this.rows}}render(){const t=this.columns.filter(a=>a.visible!==!1),d=t.map(a=>`<th class="align-${a.align??"left"}">${a.label}</th>`).join(""),l=this.rows.map((a,n)=>`<tr data-row-index="${n}">${t.map(s=>s.actions?`<td class="align-center actions-cell">
|
|
2
|
-
${s.actions.edit?`<ui-button variant="primary" class='action-btn' icon='edit' size="sm" data-action="edit" data-row-index="${n}">Edit</ui-button>`:""}
|
|
3
|
-
${s.actions.delete?`<ui-button variant="danger" class='action-btn' icon='trash' size="sm" data-action="delete" data-row-index="${n}">Delete</ui-button>`:""}
|
|
4
|
-
</td>`:`<td class="align-${s.align??"left"}">${String(a[s.key]??"")}</td>`).join("")}</tr>`).join("");this.shadowRoot.innerHTML=`
|
|
5
|
-
<style>${w}</style>
|
|
6
|
-
<div class="table-wrap">
|
|
7
|
-
<table>
|
|
8
|
-
<thead><tr>${d}</tr></thead>
|
|
9
|
-
<tbody>${l}</tbody>
|
|
10
|
-
</table>
|
|
11
|
-
</div>
|
|
12
|
-
`,this.shadowRoot.querySelectorAll(".action-btn").forEach(a=>{a.addEventListener("click",n=>{const s=n.currentTarget,c=s.dataset.action,r=parseInt(s.dataset.rowIndex||"0",10),b=c==="edit"?"edit-action":"delete-action";this.dispatchEvent(new CustomEvent(b,{bubbles:!0,composed:!0,detail:{row:this.rows[r],rowIndex:r}}))})})}}customElements.define("ui-table",$);
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
var m=Object.defineProperty;var b=(c,r,t)=>r in c?m(c,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):c[r]=t;var n=(c,r,t)=>b(c,typeof r!="symbol"?r+"":r,t);import{B as p,t as f}from"./index-BiVNQ5Fp.js";import"./table-DAobVRE7.js";import"./modal-h8khzJNk.js";import"./vendor-BvJLUv9i.js";class k extends p{constructor(){super(...arguments);n(this,"_total",0);n(this,"_currentPage",1);n(this,"_pageSize",10)}connectedCallback(){this.setAttribute("data-ui","pagination"),super.connectedCallback()}static get observedAttributes(){return["total","current-page","page-size"]}attributeChangedCallback(t,e,a){switch(t){case"total":this._total=parseInt(a,10)||0;break;case"current-page":this._currentPage=parseInt(a,10)||1;break;case"page-size":this._pageSize=parseInt(a,10)||10;break}this.render()}get total(){return this._total}set total(t){this._total=t,this.setAttribute("total",String(t))}get currentPage(){return this._currentPage}set currentPage(t){this._currentPage=t,this.setAttribute("current-page",String(t))}get pageSize(){return this._pageSize}set pageSize(t){this._pageSize=t,this.setAttribute("page-size",String(t))}get totalPages(){return Math.ceil(this._total/this._pageSize)}handlePageChange(t){t<1||t>this.totalPages||t===this._currentPage||(this.currentPage=t,this.dispatchEvent(new CustomEvent("page-change",{detail:{page:t,pageSize:this._pageSize,total:this._total,totalPages:this.totalPages},bubbles:!0,composed:!0})))}getPageNumbers(){const t=this.totalPages,e=this._currentPage;if(t<=7)return Array.from({length:t},(s,o)=>o+1);const a=[];return e<=3?a.push(1,2,3,4,"...",t):e>=t-2?a.push(1,"...",t-3,t-2,t-1,t):a.push(1,"...",e-1,e,e+1,"...",t),a}render(){const t=this.totalPages,e=this._currentPage,a=this.getPageNumbers(),s=(e-1)*this._pageSize+1,o=Math.min(e*this._pageSize,this._total);this.shadowRoot.innerHTML=`
|
|
2
|
-
<style>${f}</style>
|
|
3
|
-
<div class="pagination-container">
|
|
4
|
-
<div class="pagination-info">
|
|
5
|
-
${this._total>0?`Showing ${s} to ${o} of ${this._total}`:"No results"}
|
|
6
|
-
</div>
|
|
7
|
-
${t>1?`
|
|
8
|
-
<nav class="pagination" role="navigation" aria-label="Pagination">
|
|
9
|
-
<button
|
|
10
|
-
class="page-btn nav-btn"
|
|
11
|
-
${e===1?"disabled":""}
|
|
12
|
-
data-page="prev"
|
|
13
|
-
aria-label="Previous page"
|
|
14
|
-
>
|
|
15
|
-
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
16
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
|
|
17
|
-
</svg>
|
|
18
|
-
</button>
|
|
19
|
-
${a.map(i=>i==="..."?'<button class="page-btn ellipsis" disabled>...</button>':`
|
|
20
|
-
<button
|
|
21
|
-
class="page-btn ${i===e?"active":""}"
|
|
22
|
-
data-page="${i}"
|
|
23
|
-
aria-label="Page ${i}"
|
|
24
|
-
${i===e?'aria-current="page"':""}
|
|
25
|
-
>
|
|
26
|
-
${i}
|
|
27
|
-
</button>
|
|
28
|
-
`).join("")}
|
|
29
|
-
<button
|
|
30
|
-
class="page-btn nav-btn"
|
|
31
|
-
${e===t?"disabled":""}
|
|
32
|
-
data-page="next"
|
|
33
|
-
aria-label="Next page"
|
|
34
|
-
>
|
|
35
|
-
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
36
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
|
37
|
-
</svg>
|
|
38
|
-
</button>
|
|
39
|
-
</nav>
|
|
40
|
-
`:""}
|
|
41
|
-
</div>
|
|
42
|
-
`,this.attachEventListeners()}attachEventListeners(){this.shadowRoot&&this.shadowRoot.addEventListener("click",t=>{const a=t.target.closest(".page-btn");if(!a||a.disabled)return;const s=a.dataset.page;if(s==="prev")this.handlePageChange(this._currentPage-1);else if(s==="next")this.handlePageChange(this._currentPage+1);else if(s){const o=parseInt(s,10);isNaN(o)||this.handlePageChange(o)}})}}customElements.define("ui-pagination",k);const v=`<h1>Table Demo</h1>\r
|
|
43
|
-
<p class="intro">Example of loading JSON data and rendering a table.</p>\r
|
|
44
|
-
\r
|
|
45
|
-
<div class="demo-section">\r
|
|
46
|
-
<div class="section-header">\r
|
|
47
|
-
<h2>Data Source</h2>\r
|
|
48
|
-
<span class="status" id="data-status">Loading...</span>\r
|
|
49
|
-
</div>\r
|
|
50
|
-
<div class="code-block">\r
|
|
51
|
-
<code>fetch('https://dummyjson.com/products')</code>\r
|
|
52
|
-
</div>\r
|
|
53
|
-
</div>\r
|
|
54
|
-
\r
|
|
55
|
-
<div class="demo-section">\r
|
|
56
|
-
<h2>Table</h2>\r
|
|
57
|
-
<div class="action-message" id="action-message" style="display: none;"></div>\r
|
|
58
|
-
<ui-table id="demo-table"></ui-table>\r
|
|
59
|
-
<div class="meta" id="data-meta"></div>\r
|
|
60
|
-
<ui-pagination></ui-pagination>\r
|
|
61
|
-
</div>\r
|
|
62
|
-
\r
|
|
63
|
-
\r
|
|
64
|
-
<ui-modal id="confirmModal" title="Confirm Delete" size="sm">\r
|
|
65
|
-
<p>Are you sure you want to delete this item?</p>\r
|
|
66
|
-
<p style="color: #ef4444; font-size: 0.875rem;">This action cannot be undone.</p>\r
|
|
67
|
-
<div slot="footer">\r
|
|
68
|
-
<ui-button id="confirmCancel" variant="ghost">Cancel</ui-button>\r
|
|
69
|
-
<ui-button id="confirmDelete" variant="primary" icon="trash-2">Delete</ui-button>\r
|
|
70
|
-
</div>\r
|
|
71
|
-
</ui-modal>`,y=":host{display:block;padding:2rem;max-width:1200px;margin:0 auto}.intro{color:var(--color-ink, #0f172a);opacity:.8;margin-bottom:1.5rem}h1{font-size:2rem;margin-bottom:.5rem;color:var(--color-ink, #0f172a)}h2{font-size:1.4rem;margin-top:0;margin-bottom:.75rem;color:var(--color-ink, #0f172a)}.demo-section{margin-bottom:2rem;padding:1.5rem;border:1px solid #e2e8f0;border-radius:12px;background:#fff}.section-header{display:flex;align-items:center;justify-content:space-between;gap:1rem}.status{font-size:.85rem;font-weight:600;padding:.25rem .6rem;border-radius:999px;background:#e2e8f0;color:#334155}.status.loading{background:#fde68a;color:#92400e}.status.success{background:#bbf7d0;color:#166534}.status.error{background:#fecaca;color:#b91c1c}.code-block{background:#f1f5f9;padding:1rem;border-radius:8px;overflow-x:auto}code{font-family:Courier New,monospace;font-size:.9rem;color:#334155}.meta{margin-top:.75rem;margin-bottom:.75rem;font-size:.85rem;color:#64748b}ui-pagination{margin-top:1rem}.json-output{margin:0;background:#0f172a;color:#e2e8f0;padding:1rem;border-radius:8px;overflow-x:auto;font-size:.85rem}";class w extends p{constructor(){super(...arguments);n(this,"hasLoaded",!1);n(this,"loading",!1);n(this,"error",null);n(this,"data",null);n(this,"currentPage",1);n(this,"pageSize",10)}connectedCallback(){super.connectedCallback(),this.hasLoaded||(this.hasLoaded=!0,this.loadData())}async loadData(){this.loading=!0,this.error=null,this.render();try{const t=(this.currentPage-1)*this.pageSize,e=await fetch(`https://dummyjson.com/products?limit=${this.pageSize}&skip=${t}`);if(!e.ok)throw new Error(`Request failed: ${e.status}`);const a=await e.json(),s=[{key:"id",label:"ID",align:"right",visible:!1},{key:"title",label:"Title"},{key:"brand",label:"Brand"},{key:"category",label:"Category"},{key:"price",label:"Price",align:"right"},{key:"rating",label:"Rating",align:"right"},{key:"stock",label:"Stock",align:"right"},{key:"actions",label:"Actions",align:"center",actions:{edit:!0,delete:!0}}],o=a.products.map(i=>({id:i.id,title:i.title,brand:i.brand,category:i.category,price:`$${i.price.toFixed(2)}`,rating:i.rating.toFixed(1),stock:i.stock}));this.data={columns:s,rows:o,meta:{total:a.total,limit:a.limit,skip:a.skip}},this.loading=!1,this.render()}catch(t){this.loading=!1,this.error=t instanceof Error?t.message:"Unknown error",this.render()}}showActionMessage(t){const e=this.shadowRoot.querySelector("#action-message");e&&(e.textContent=t,e.style.display="block",setTimeout(()=>{const a=this.shadowRoot.querySelector("#action-message");a&&(a.style.display="none")},5e3))}render(){var h,u;this.shadowRoot.innerHTML=`
|
|
72
|
-
<style>${y}</style>
|
|
73
|
-
${v}
|
|
74
|
-
`;const t=this.shadowRoot.querySelector("#data-status"),e=this.shadowRoot.getElementById("confirmModal"),a=this.shadowRoot.getElementById("confirmDelete"),s=this.shadowRoot.getElementById("confirmCancel");s==null||s.addEventListener("click",()=>{e==null||e.close()}),t&&(t.textContent=this.loading?"Loading...":this.error?"Error":"Loaded",t.className=`status ${this.loading?"loading":this.error?"error":"success"}`);const o=this.shadowRoot.querySelector("#demo-table");o&&this.data&&(o.data={columns:this.data.columns,rows:this.data.rows});const i=this.shadowRoot.querySelector("ui-pagination");if(i&&((h=this.data)!=null&&h.meta)){i.total=this.data.meta.total,i.currentPage=this.currentPage,i.pageSize=this.pageSize;const d=i.cloneNode(!0);(u=i.parentNode)==null||u.replaceChild(d,i),d.addEventListener("page-change",l=>{this.currentPage=l.detail.page,this.loadData()})}const g=this.shadowRoot.querySelector("#demo-table");g&&(g.addEventListener("edit-action",d=>{const{row:l}=d.detail;this.showActionMessage(`EDIT clicked for "${l.id}: ${l.title}"`)}),g.addEventListener("delete-action",d=>{const{row:l}=d.detail;console.log(`DELETE clicked for "${l.id}: ${l.title}"`),e==null||e.open(),a==null||a.addEventListener("click",()=>{e==null||e.close(),this.showActionMessage(`DELETE confirmed for "${l.id}: ${l.title}"`)})}))}}customElements.define("table-demo",w);export{w as TableDemo};
|