@k3000/ce 0.2.0 → 0.2.1
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/ce.mjs +1 -1
- package/console/components/div-test.mjs +11 -0
- package/console/components/g-button.mjs +79 -0
- package/console/components/g-cell.mjs +129 -0
- package/console/components/g-col.mjs +38 -0
- package/console/components/g-field.mjs +162 -0
- package/console/components/g-form.mjs +11 -0
- package/console/components/g-icon.mjs +82 -0
- package/console/components/g-image.mjs +127 -0
- package/console/components/g-popup.mjs +130 -0
- package/console/components/g-row.mjs +120 -0
- package/console/components/g-space.mjs +21 -0
- package/console/components/g-toast.mjs +116 -0
- package/console/components/layout-header.mjs +0 -179
- package/console/components/layout-menu.mjs +98 -1
- package/console/index.html +1 -0
- package/console/index2.html +46 -0
- package/console/pages/demo-button.mjs +116 -0
- package/console/pages/demo-cell.mjs +59 -0
- package/console/pages/demo-field.mjs +67 -0
- package/console/pages/demo-icon.mjs +200 -0
- package/console/pages/demo-image.mjs +113 -0
- package/console/pages/demo-layout.mjs +141 -0
- package/console/pages/demo-popup.mjs +158 -0
- package/console/pages/demo-space.mjs +51 -0
- package/console/pages/demo-toast.mjs +66 -0
- package/index.mjs +7 -0
- package/package.json +1 -1
- package/test.html +15 -0
package/ce.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let dir="./comp",ext="mjs",getVariables=e=>{const t=e.match(/\{\{.+?}}/g);if(!t)return new Set;const o=new Set,n=new Set(["true","false","null","undefined","this","new","typeof","in","instanceof"]);return t.forEach((e=>{const t=e.slice(2,-2).match(/\b[a-zA-Z_$][\w$]*(?:\s*\.\s*[a-zA-Z_$][\w$]*)*(?!\s*\()/g);t&&t.forEach((e=>{n.has(e)||o.add(e)}))})),o},createTmpNode=(e="")=>document.createTextNode(""),literalsCode=e=>`with (scope) {\n\treturn \`${e.replace(/{{(.*?)}}/g,((e,t)=>`\${${t}}`))}\` \n}`,functionCode=e=>`with (scope) {\n\treturn ${e} \n}`,handleArray=(e,t)=>{const o=e.ownerElement;if(e.nodeMap||(e.nodeMap=[],e.mark=createTmpNode("数组结束标记"),o.parentNode.replaceChild(e.mark,o),e.ownerElement=o.cloneNode(!0)),!Array.isArray(t))return e;const n=e.mark.parentNode;let r=0;for(;r<t.length;r++)if(void 0!==e.nodeMap[r]){if(e.nodeMap[r][0]!==t[r]){const s=o.cloneNode(!0);try{t[r]._=e.scope}catch(e){}bindNode(t[r],s,!0),n.replaceChild(s,e.nodeMap[r][1]),e.nodeMap[r]=[t[r],s]}}else{const s=o.cloneNode(!0);try{t[r]._=e.scope}catch(e){}bindNode(t[r],s,!0),n.insertBefore(s,e.mark),e.nodeMap[r]=[t[r],s]}const s=r;for(;r<e.nodeMap.length;r++)n.removeChild(e.nodeMap[r][1]);return e.nodeMap.splice(s,e.nodeMap.length-s),e};export const config=e=>{e.dir&&(dir=e.dir),e.ext&&(ext=e.ext),"function"==typeof e.getVariables&&(getVariables=e.getVariables),"function"==typeof e.createTmpNode&&(createTmpNode=e.createTmpNode),"function"==typeof e.literalsCode&&(literalsCode=e.literalsCode),"function"==typeof e.functionCode&&(functionCode=e.functionCode),"function"==typeof e.handleArray&&(handleArray=e.handleArray)};const getCEName=e=>e.tagName.includes("-")?e.tagName.toLowerCase():e.hasAttribute("is")?e.getAttribute("is"):void 0;export const throttle=(e,t=41)=>{let o;return(...n)=>{clearTimeout(o),o=setTimeout((()=>e(...n)),t)}};const objectPool=new WeakMap,importPool=new WeakSet,addListener=(e,t,o)=>{getVariables(t).forEach((t=>{let n="",r=e,s=0,a=t.split(".");for([s,n]of a.entries()){if(s===a.length-1)break;if(null===r||"object"!=typeof r||!Reflect.has(r,n))return;if(Array.isArray(r[n])&&s===a.length-2)break;r=r[n]}if(null!==r&&"object"==typeof r&&(!Object.getOwnPropertyDescriptor(r,n)||Object.getOwnPropertyDescriptor(r,n).configurable))if(objectPool.has(r)){const e=objectPool.get(r);if(e.has(n))e.get(n).add(o);else{const t=new Set([o]);e.set(n,t);let s=r[n];Object.defineProperty(r,n,{get:()=>s,set:e=>{s!==e&&(s=e,t.forEach((e=>e())))}})}}else{const e=new Set([o]);objectPool.set(r,new Map([[n,e]]));let t=r[n];Object.defineProperty(r,n,{get:()=>t,set:o=>{t!==o&&(t=o,e.forEach((e=>e())))}})}}))},ceMap=Object.create(null),disposeCE=(e,t)=>{if(e.querySelectorAll("*:not(:defined)").forEach((e=>importCE(e))),ceMap[t].shadowRoot&&(e.attachShadow({mode:"open"}),e.shadowRoot.appendChild(ceMap[t].shadowRoot.create(e))),ceMap[t].innerHTML||ceMap[t].outerHTML){const o=(ceMap[t].innerHTML||ceMap[t].outerHTML).create(e);if(!ceMap[t].shadowRoot){const t=Array.from(o.querySelectorAll("slot")),n=t.reduce(((e,t)=>(e[t.getAttribute("name")||""]=t,e)),{}),r=Array.from(e.childNodes);for(const e of r){const t="function"==typeof e.getAttribute&&e.getAttribute("slot")||"";n[t]&&n[t].parentNode.insertBefore(e,n[t])}for(const e of t)e.parentNode.removeChild(e)}if(ceMap[t].outerHTML){for(;o.firstChild;)e.parentElement.insertBefore(o.firstChild,e);e.parentElement.removeChild(e)}else e.appendChild(o)}"function"==typeof e.ready&&e.ready()};let tmp=null;const importCE=(e,t=void 0)=>{if(t=t??getCEName(e),importPool.has(e))return;if(importPool.add(e),void 0!==customElements.get(t))return void disposeCE(e,t);const o=e.nodeName.includes("-");let n=dir;if(e.attributes.dir&&e.attributes.dir.nodeValue){const t=e.attributes.dir.nodeValue;e.removeAttribute("dir"),n=t.startsWith("/")||t.startsWith("./")?t:`${n}/${t}`}import(`${n}/${t}.${ext}`).then((n=>{void 0===customElements.get(t)&&(ceMap[t]=Object.create(null),"string"==typeof n.innerHTML&&(ceMap[t].innerHTML=bind(n.innerHTML)),"string"==typeof n.outerHTML&&(ceMap[t].outerHTML=bind(n.outerHTML)),"string"==typeof n.shadowRoot&&(ceMap[t].shadowRoot=bind(n.shadowRoot)),o?customElements.define(t,n.default):customElements.define(t,n.default,{extends:e.nodeName.toLowerCase()})),disposeCE(e,t)})).catch((e=>{console.error(e)}))},disposeNode=(e,t)=>{const o=t.nodeValue;if(null===o.match(/{{(.*?)}}/))return;const n=new Function("scope",literalsCode(o));addListener(e,o,throttle((()=>t.nodeValue=n.call(t,e)))),t.nodeValue=n.call(t,e)},disposeAttrValue=(e,t,o,n)=>{if(!n.startsWith("{{")||!n.endsWith("}}")||n.slice(2).includes("{{")){const r=new Function("scope",literalsCode(n));return()=>o.nodeValue=r.call(t,e)}const r=new Function("scope",functionCode(n.slice(2,-2)));return()=>{const n=r.call(t,e);switch(n){case!0:o.nodeValue="",t.attributes.setNamedItem(o);break;case!1:t.removeAttribute(o.nodeName);break;default:o.nodeValue=n,t.attributes.setNamedItem(o)}}},disposeSpecialAttr=(e,t,o,n)=>{const r=t.ownerElement;let s=t.nodeName;if(s.startsWith("on")){if(r.removeAttribute(s),!o.includes("(")){const t=o.split(".");let n="",a=e,i=0;for([i,n]of t.entries()){if(i===t.length-1)break;if(null===a||"object"!=typeof a||!Reflect.has(a,n)){a={};break}a=a[n]}if("function"==typeof a[n])return r[s]=e=>a[n](e),!0}const t=new Function("scope","event",functionCode(o));return r[s]=o=>t.call(r,e,o),!0}if("connect"===s){r.removeAttribute(s);const n=new Function("scope",functionCode(o)),a=createTmpNode("节点断开重连的标记"),i=()=>{n(e)?a.parentNode?.replaceChild(r,a):r.parentNode?.replaceChild(a,r)};return addListener(e,t.nodeValue,throttle((()=>i()))),i(),!0}if("each"===s){r.removeAttribute(s);let n={ownerElement:r,scope:e};if(Reflect.has(e,o)){const r=()=>n=handleArray(n,e[o]);return addListener(e,t.nodeValue,throttle((()=>r()))),r(),!0}const a=new Function("scope",functionCode(o));return handleArray(n,a(e)),!0}if(n){r.removeAttribute(s);const n=new Function("scope",functionCode(o));s.includes("-")&&(s=s.split("-").map(((e,t)=>e&&t?e[0].toUpperCase()+e.slice(1):e)).join(""));const a=()=>{const t=n(e);r[s]="function"==typeof t?t.bind(e):t};return addListener(e,t.nodeValue,throttle((()=>a()))),a(),!0}return!1},disposeAttr=(e,t,o)=>{const n=t.nodeValue;if(null===n.match(/{{(.*?)}}/))return;if(n.startsWith("{{")&&n.endsWith("}}")&&disposeSpecialAttr(e,t,n.slice(2,-2),o))return;const r=disposeAttrValue(e,t.ownerElement,t,n);addListener(e,n,throttle((()=>r()))),r()};export const bindNode=(e,t,o)=>{const n=o?[t]:Array.from(t.childNodes);for(const o of n){if(o.attributes)for(const n of Array.from(o.attributes))if(disposeAttr(e,n,getCEName(o)),"each"===n.nodeName&&n.nodeValue.startsWith("{{")&&n.nodeValue.endsWith("}}"))return t;if(o.childNodes&&bindNode(e,o),3===o.nodeType&&null!==o.nodeValue&&disposeNode(e,o),1===o.nodeType){const e=getCEName(o);e&&importCE(o,e)}}return t};export const bind=e=>{const t=document.createElement("template");return t.innerHTML=e,{create:e=>bindNode(e,document.importNode(t.content,!0))}};const style=document.createElement("style");style.innerHTML="\n*:not(:defined) {\n display: none\n}\n",document.head.appendChild(style),addEventListener("DOMContentLoaded",(()=>document.querySelectorAll("*:not(:defined)").forEach((e=>importCE(e)))));class EventBus{value=void 0;targets=new Map;add(e,t=Object.create(null)){this.targets.set(e,t),t.preValue&&void 0!==this.value&&e(...this.value)}remove(e){this.targets.delete(e)}dispatch(...e){return this.value=e,Promise.allSettled(this.targets.entries().map((([t,{once:o}])=>(o&&this.targets.delete(t),t(...e)))))}}const eventBusObj=Object.create(null),eventBus=Object.defineProperties(Object.create(null),{add:{value:(e,t,o)=>{Reflect.has(eventBusObj,e)||(eventBusObj[e]=new EventBus),eventBusObj[e].add(t,o)}},remove:{value:(e,t)=>{Reflect.has(eventBusObj,e)&&eventBusObj[e].remove(t)}},dispatch:{value:(e,...t)=>(Reflect.has(eventBusObj,e)||(eventBusObj[e]=new EventBus),eventBusObj[e].dispatch(...t))}});export const useEvent=()=>eventBus;export const useRef=e=>{const t=Object.create(null);for(const o of e.querySelectorAll("[ref]"))t[o.attributes.ref.nodeValue]=o;return t};export const useAttr=e=>{const t=Object.create(null);for(const o of e.attributes)t[o.nodeName]=o.nodeValue;return t};export const useWatch=e=>(t,o=!1)=>{for(const[n,r]of Object.entries(t)){if("function"!=typeof r)continue;let t=e[n];Object.defineProperty(e,n,{get:()=>t,set:e=>{if(!1!==r(e,t))return t=e}}),o&&r(t,t)}};
|
|
1
|
+
let dir="./comp",ext="mjs",getVariables=e=>{const t=e.match(/\{\{.+?}}/g);if(!t)return new Set;const o=new Set,n=new Set(["true","false","null","undefined","this","new","typeof","in","instanceof"]);return t.forEach((e=>{const t=e.slice(2,-2).match(/\b[a-zA-Z_$][\w$]*(?:\s*\.\s*[a-zA-Z_$][\w$]*)*(?!\s*\()/g);t&&t.forEach((e=>{n.has(e)||o.add(e)}))})),o},createTmpNode=(e="")=>document.createTextNode(""),literalsCode=e=>`with (scope) {\n\treturn \`${e.replace(/{{(.*?)}}/g,((e,t)=>`\${${t}}`))}\` \n}`,functionCode=e=>`with (scope) {\n\treturn ${e} \n}`,handleArray=(e,t)=>{const o=e.ownerElement;if(e.nodeMap||(e.nodeMap=[],e.mark=createTmpNode("数组结束标记"),o.parentNode.replaceChild(e.mark,o),e.ownerElement=o.cloneNode(!0)),!Array.isArray(t))return e;const n=e.mark.parentNode;let r=0;for(;r<t.length;r++)if(void 0!==e.nodeMap[r]){if(e.nodeMap[r][0]!==t[r]){const s=o.cloneNode(!0);try{t[r]._=e.scope}catch(e){}bindNode(t[r],s,!0),n.replaceChild(s,e.nodeMap[r][1]),e.nodeMap[r]=[t[r],s]}}else{const s=o.cloneNode(!0);try{t[r]._=e.scope}catch(e){}bindNode(t[r],s,!0),n.insertBefore(s,e.mark),e.nodeMap[r]=[t[r],s]}const s=r;for(;r<e.nodeMap.length;r++)n.removeChild(e.nodeMap[r][1]);return e.nodeMap.splice(s,e.nodeMap.length-s),e};export const config=e=>{e.dir&&(dir=e.dir),e.ext&&(ext=e.ext),"function"==typeof e.getVariables&&(getVariables=e.getVariables),"function"==typeof e.createTmpNode&&(createTmpNode=e.createTmpNode),"function"==typeof e.literalsCode&&(literalsCode=e.literalsCode),"function"==typeof e.functionCode&&(functionCode=e.functionCode),"function"==typeof e.handleArray&&(handleArray=e.handleArray)};const getCEName=e=>e.tagName.includes("-")?e.tagName.toLowerCase():e.hasAttribute("is")?e.getAttribute("is"):void 0;export const throttle=(e,t=41)=>{let o;return(...n)=>{clearTimeout(o),o=setTimeout((()=>e(...n)),t)}};const objectPool=new WeakMap,importPool=new WeakSet,addListener=(e,t,o)=>{getVariables(t).forEach((t=>{let n="",r=e,s=0,a=t.split(".");for([s,n]of a.entries()){if(s===a.length-1)break;if(null===r||"object"!=typeof r||!Reflect.has(r,n))return;if(Array.isArray(r[n])&&s===a.length-2)break;r=r[n]}if(null!==r&&"object"==typeof r&&(!Object.getOwnPropertyDescriptor(r,n)||Object.getOwnPropertyDescriptor(r,n).configurable))if(objectPool.has(r)){const e=objectPool.get(r);if(e.has(n))e.get(n).add(o);else{const t=new Set([o]);e.set(n,t);let s=r[n];Object.defineProperty(r,n,{get:()=>s,set:e=>{s!==e&&(s=e,t.forEach((e=>e())))}})}}else{const e=new Set([o]);objectPool.set(r,new Map([[n,e]]));let t=r[n];Object.defineProperty(r,n,{get:()=>t,set:o=>{t!==o&&(t=o,e.forEach((e=>e())))}})}}))},ceMap=Object.create(null),disposeCE=(e,t)=>{if(e.querySelectorAll("*:not(:defined)").forEach((e=>importCE(e))),ceMap[t].shadowRoot&&(e.attachShadow({mode:"open"}),e.shadowRoot.appendChild(ceMap[t].shadowRoot.create(e))),ceMap[t].innerHTML||ceMap[t].outerHTML){const o=(ceMap[t].innerHTML||ceMap[t].outerHTML).create(e);if(!ceMap[t].shadowRoot){const t=Array.from(o.querySelectorAll("slot")),n=t.reduce(((e,t)=>(e[t.getAttribute("name")||""]=t,e)),{}),r=Array.from(e.childNodes);for(const e of r){const t="function"==typeof e.getAttribute&&e.getAttribute("slot")||"";n[t]&&n[t].parentNode.insertBefore(e,n[t])}for(const e of t)e.parentNode.removeChild(e)}if(ceMap[t].outerHTML){for(;o.firstChild;)e.parentElement.insertBefore(o.firstChild,e);e.parentElement.removeChild(e)}else e.appendChild(o)}"function"==typeof e.ready&&e.ready()};let tmp=null;const importCE=(e,t=void 0)=>{if(t=t??getCEName(e),importPool.has(e))return;if(importPool.add(e),void 0!==customElements.get(t))return void disposeCE(e,t);const o=e.nodeName.includes("-");let n=dir;if(e.attributes.dir&&e.attributes.dir.nodeValue){const t=e.attributes.dir.nodeValue;e.removeAttribute("dir"),n=t.startsWith("/")||t.startsWith("./")?t:`${n}/${t}`}import(`${n}/${t}.${ext}`).then((n=>{void 0===customElements.get(t)&&(ceMap[t]=Object.create(null),"string"==typeof n.innerHTML&&(ceMap[t].innerHTML=bind(n.innerHTML)),"string"==typeof n.outerHTML&&(ceMap[t].outerHTML=bind(n.outerHTML)),"string"==typeof n.shadowRoot&&(ceMap[t].shadowRoot=bind(n.shadowRoot)),o?customElements.define(t,n.default):customElements.define(t,n.default,{extends:e.nodeName.toLowerCase()})),disposeCE(e,t)})).catch((e=>{console.error(e)}))},disposeNode=(e,t)=>{const o=t.nodeValue;if(null===o.match(/{{(.*?)}}/))return;const n=new Function("scope",literalsCode(o));addListener(e,o,throttle((()=>t.nodeValue=n.call(t,e)))),t.nodeValue=n.call(t,e)},disposeAttrValue=(e,t,o,n)=>{if(!n.startsWith("{{")||!n.endsWith("}}")||n.slice(2).includes("{{")){const r=new Function("scope",literalsCode(n));return()=>o.nodeValue=r.call(t,e)}const r=new Function("scope",functionCode(n.slice(2,-2)));return()=>{const n=r.call(t,e);switch(n){case!0:o.nodeValue="",t.attributes.setNamedItem(o);break;case!1:t.removeAttribute(o.nodeName);break;default:o.nodeValue=n,t.attributes.setNamedItem(o)}}},disposeSpecialAttr=(e,t,o,n)=>{const r=t.ownerElement;let s=t.nodeName;if(s.startsWith("on")){if(r.removeAttribute(s),!o.includes("(")){const t=o.split(".");let n="",a=e,i=0;for([i,n]of t.entries()){if(i===t.length-1)break;if(null===a||"object"!=typeof a||!Reflect.has(a,n)){a={};break}a=a[n]}if("function"==typeof a[n])return r[s]=e=>a[n](e),!0}const t=new Function("scope","event",functionCode(o));return r[s]=o=>t.call(r,e,o),!0}if("connect"===s){r.removeAttribute(s);const n=new Function("scope",functionCode(o)),a=createTmpNode("节点断开重连的标记"),i=()=>{n(e)?a.parentNode?.replaceChild(r,a):r.parentNode?.replaceChild(a,r)};return addListener(e,t.nodeValue,throttle((()=>i()))),i(),!0}if("each"===s){r.removeAttribute(s);let n={ownerElement:r,scope:e};if(Reflect.has(e,o)){const r=()=>n=handleArray(n,e[o]);return addListener(e,t.nodeValue,throttle((()=>r()))),r(),!0}const a=new Function("scope",functionCode(o));return handleArray(n,a(e)),!0}if(n){r.removeAttribute(s);const n=new Function("scope",functionCode(o));s.includes("-")&&(s=s.split("-").map(((e,t)=>e&&t?e[0].toUpperCase()+e.slice(1):e)).join(""));const a=()=>{const t=n(e);r[s]="function"==typeof t?t.bind(e):t};return addListener(e,t.nodeValue,throttle((()=>a()))),a(),!0}return!1},disposeAttr=(e,t,o)=>{const n=t.nodeValue;if(null===n.match(/{{(.*?)}}/))return;if(n.startsWith("{{")&&n.endsWith("}}")&&disposeSpecialAttr(e,t,n.slice(2,-2),o))return;const r=disposeAttrValue(e,t.ownerElement,t,n);addListener(e,n,throttle((()=>r()))),r()};export const bindNode=(e,t,o)=>{const n=o?[t]:Array.from(t.childNodes);for(const o of n){if(o.attributes)for(const n of Array.from(o.attributes))if(disposeAttr(e,n,getCEName(o)),"each"===n.nodeName&&n.nodeValue.startsWith("{{")&&n.nodeValue.endsWith("}}"))return t;if(o.childNodes&&bindNode(e,o),3===o.nodeType&&null!==o.nodeValue&&disposeNode(e,o),1===o.nodeType){const e=getCEName(o);e&&importCE(o,e)}}return t};export const bind=e=>{const t=document.createElement("template");return t.innerHTML=e,{create:e=>bindNode(e,document.importNode(t.content,!0))}};const style=document.createElement("style");style.innerHTML="\n*:not(:defined) {\n display: none\n}\n",document.head.appendChild(style),addEventListener("DOMContentLoaded",(()=>document.querySelectorAll("*:not(:defined)").forEach((e=>importCE(e)))));class EventBus{value=void 0;targets=new Map;add(e,t=Object.create(null)){this.targets.set(e,t),t.preValue&&void 0!==this.value&&e(...this.value)}remove(e){this.targets.delete(e)}dispatch(...e){return this.value=e,Promise.allSettled(this.targets.entries().map((([t,{once:o}])=>(o&&this.targets.delete(t),t(...e)))))}}const eventBusObj=Object.create(null),eventBus=Object.defineProperties(Object.create(null),{add:{value:(e,t,o)=>{Reflect.has(eventBusObj,e)||(eventBusObj[e]=new EventBus),eventBusObj[e].add(t,o)}},remove:{value:(e,t)=>{Reflect.has(eventBusObj,e)&&eventBusObj[e].remove(t)}},dispatch:{value:(e,...t)=>(Reflect.has(eventBusObj,e)||(eventBusObj[e]=new EventBus),eventBusObj[e].dispatch(...t))}});export const useEvent=()=>eventBus;export const useRef=e=>{const t=Object.create(null);for(const o of e.querySelectorAll("[ref]"))t[o.attributes.ref.nodeValue]=o;return t};export const useAttr=e=>{const t=Object.create(null);for(const o of e.attributes)o.nodeName.includes("-")&&(t[o.nodeName.split("-").map(((e,t)=>e&&t?e[0].toUpperCase()+e.slice(1):e)).join("")]=o.nodeValue),t[o.nodeName]=o.nodeValue;return t};export const useWatch=e=>(t,o=!1)=>{for(const[n,r]of Object.entries(t)){if("function"!=typeof r)continue;let t=e[n];Object.defineProperty(e,n,{get:()=>t,set:e=>{if(!1!==r(e,t))return t=e}}),o&&r(t,t)}};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useAttr, bind, useRef } from "../../ce.mjs";
|
|
2
|
+
|
|
3
|
+
export const innerHTML = `
|
|
4
|
+
<button disabled="{{!!(isDisabled || loading)}}" class="cursor-pointer relative inline-flex items-center justify-center {{sizeClass}} rounded-full backdrop-blur-2xl border shadow-[inset_0_1px_1px_rgba(255,255,255,0.8),0_4px_12px_rgba(0,0,0,0.05)] dark:shadow-[inset_0_1px_1px_rgba(255,255,255,0.1),0_4px_12px_rgba(0,0,0,0.2)] font-medium transition-all {{(isDisabled || loading) ? 'opacity-50 cursor-not-allowed' : 'hover:-translate-y-0.5 active:translate-y-0 active:shadow-inner group'}} overflow-hidden {{typeClass}} {{classStr}}">
|
|
5
|
+
<!-- Highlight overlay for glass effect -->
|
|
6
|
+
<div class="absolute inset-0 rounded-full bg-gradient-to-b from-white/40 to-transparent dark:from-white/5 opacity-0 {{(isDisabled || loading) ? '' : 'group-hover:opacity-100'}} transition-opacity pointer-events-none"></div>
|
|
7
|
+
<div class="relative z-10 flex items-center justify-center gap-2">
|
|
8
|
+
<svg class="animate-spin h-4 w-4 text-current {{loading ? '' : 'hidden'}}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
9
|
+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
10
|
+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
11
|
+
</svg>
|
|
12
|
+
<slot name="prefix"></slot>
|
|
13
|
+
<slot name="icon"></slot>
|
|
14
|
+
<div connect="{{loading && loadingText}}" style="display: contents">{{loadingText}}</div>
|
|
15
|
+
<div style="display: {{loading && loadingText ? 'none' : 'contents'}}">
|
|
16
|
+
<g-icon connect="{{icon && !isIconUrl}}" name="{{icon}}" class="w-4 h-4"></g-icon>
|
|
17
|
+
<img connect="{{isIconUrl}}" src="{{isIconUrl ? icon : false}}" class="w-4 h-4" />
|
|
18
|
+
<slot></slot>
|
|
19
|
+
</div>
|
|
20
|
+
<slot name="suffix"></slot>
|
|
21
|
+
</div>
|
|
22
|
+
</button>
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
const typeStyles = {
|
|
26
|
+
default: 'bg-white/40 dark:bg-gray-800/40 border-white/60 dark:border-white/10 text-gray-800 dark:text-gray-100 hover:bg-white/60 dark:hover:bg-gray-700/60',
|
|
27
|
+
primary: 'bg-blue-500/10 dark:bg-blue-500/20 border-blue-500/20 dark:border-blue-500/10 text-blue-600 dark:text-blue-400 hover:bg-blue-500/20 dark:hover:bg-blue-500/30',
|
|
28
|
+
success: 'bg-green-500/10 dark:bg-green-500/20 border-green-500/20 dark:border-green-500/10 text-green-600 dark:text-green-400 hover:bg-green-500/20 dark:hover:bg-green-500/30',
|
|
29
|
+
warning: 'bg-orange-500/10 dark:bg-orange-500/20 border-orange-500/20 dark:border-orange-500/10 text-orange-600 dark:text-orange-400 hover:bg-orange-500/20 dark:hover:bg-orange-500/30',
|
|
30
|
+
danger: 'bg-red-500/10 dark:bg-red-500/20 border-red-500/20 dark:border-red-500/10 text-red-600 dark:text-red-400 hover:bg-red-500/20 dark:hover:bg-red-500/30'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const plainTypeStyles = {
|
|
34
|
+
default: 'bg-transparent border-white/60 dark:border-white/10 text-gray-800 dark:text-gray-100 hover:bg-white/10 dark:hover:bg-gray-700/20',
|
|
35
|
+
primary: 'bg-transparent border-blue-500/20 dark:border-blue-500/10 text-blue-600 dark:text-blue-400 hover:bg-blue-500/10 dark:hover:bg-blue-500/20',
|
|
36
|
+
success: 'bg-transparent border-green-500/20 dark:border-green-500/10 text-green-600 dark:text-green-400 hover:bg-green-500/10 dark:hover:bg-green-500/20',
|
|
37
|
+
warning: 'bg-transparent border-orange-500/20 dark:border-orange-500/10 text-orange-600 dark:text-orange-400 hover:bg-orange-500/10 dark:hover:bg-orange-500/20',
|
|
38
|
+
danger: 'bg-transparent border-red-500/20 dark:border-red-500/10 text-red-600 dark:text-red-400 hover:bg-red-500/10 dark:hover:bg-red-500/20'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const sizeStyles = {
|
|
42
|
+
large: 'px-6 py-2.5 text-base',
|
|
43
|
+
normal: 'px-4 py-2 text-sm',
|
|
44
|
+
small: 'px-3 py-1.5 text-xs',
|
|
45
|
+
mini: 'px-2.5 py-1 text-[11px]'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default class extends HTMLElement {
|
|
49
|
+
text = ''
|
|
50
|
+
icon = ''
|
|
51
|
+
isIconUrl = false
|
|
52
|
+
classStr = ''
|
|
53
|
+
typeClass = ''
|
|
54
|
+
sizeClass = ''
|
|
55
|
+
isDisabled = false
|
|
56
|
+
loadingText = ''
|
|
57
|
+
|
|
58
|
+
constructor() {
|
|
59
|
+
super()
|
|
60
|
+
this.style.display = 'inline-block'
|
|
61
|
+
const attr = useAttr(this)
|
|
62
|
+
this.text = attr.text || ''
|
|
63
|
+
this.icon = attr.icon || ''
|
|
64
|
+
this.isIconUrl = this.icon.startsWith('http') || this.icon.startsWith('/') || this.icon.startsWith('data:')
|
|
65
|
+
this.classStr = attr.class || ''
|
|
66
|
+
this.isDisabled = attr.disabled !== undefined && attr.disabled !== 'false'
|
|
67
|
+
this.loadingText = attr.loadingText || ''
|
|
68
|
+
|
|
69
|
+
const type = attr.type || 'default'
|
|
70
|
+
const isPlain = attr.plain !== undefined && attr.plain !== 'false'
|
|
71
|
+
const size = attr.size || 'normal'
|
|
72
|
+
|
|
73
|
+
this.typeClass = isPlain
|
|
74
|
+
? (plainTypeStyles[type] || plainTypeStyles.default)
|
|
75
|
+
: (typeStyles[type] || typeStyles.default)
|
|
76
|
+
|
|
77
|
+
this.sizeClass = sizeStyles[size] || sizeStyles.normal
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { useAttr, bind, useRef } from "../../ce.mjs";
|
|
2
|
+
|
|
3
|
+
export const innerHTML = `
|
|
4
|
+
<!-- Main Cell Container -->
|
|
5
|
+
<div class="group relative flex items-center justify-between p-4 bg-white/40 dark:bg-gray-800/40 backdrop-blur-2xl border-b border-white/60 dark:border-white/10 shadow-[inset_0_1px_1px_rgba(255,255,255,0.8),0_4px_12px_rgba(0,0,0,0.02)] dark:shadow-[inset_0_1px_1px_rgba(255,255,255,0.1),0_4px_12px_rgba(0,0,0,0.1)] transition-all hover:bg-white/60 dark:hover:bg-gray-700/60 {{clickable ? 'cursor-pointer active:bg-white/30 dark:active:bg-gray-800/80 active:translate-y-[1px]' : ''}} {{classStr}}">
|
|
6
|
+
<!-- Highlight overlay for glass effect on hover -->
|
|
7
|
+
<div class="absolute inset-0 bg-gradient-to-b from-white/40 to-transparent dark:from-white/5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none {{isLast ? 'rounded-b-2xl' : ''}} {{isFirst ? 'rounded-t-2xl' : ''}}"></div>
|
|
8
|
+
|
|
9
|
+
<!-- Left Section: Icon + Title + Label -->
|
|
10
|
+
<div class="relative z-10 flex items-center gap-3 flex-1 min-w-0">
|
|
11
|
+
<!-- Icon Slot -->
|
|
12
|
+
<div class="flex-shrink-0 text-gray-500 dark:text-gray-400 {{icon ? '' : 'hidden'}}">
|
|
13
|
+
<span ref="iconMark"></span>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<!-- Text Content -->
|
|
17
|
+
<div class="flex flex-col flex-1 min-w-0">
|
|
18
|
+
<div class="text-[15px] font-medium text-gray-800 dark:text-gray-100 truncate">{{title}}</div>
|
|
19
|
+
<div class="text-xs text-gray-500 dark:text-gray-400 truncate mt-0.5 {{label ? '' : 'hidden'}}">{{label}}</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<!-- Right Section: Value + Arrow Slot -->
|
|
24
|
+
<div class="relative z-10 flex items-center gap-2 pl-4 flex-shrink-0">
|
|
25
|
+
<!-- Value Content -->
|
|
26
|
+
<div class="text-[14px] text-gray-500 dark:text-gray-400 text-right">{{value}}</div>
|
|
27
|
+
|
|
28
|
+
<!-- Arrow / Right Icon Slot -->
|
|
29
|
+
<div class="flex-shrink-0 text-gray-400 dark:text-gray-500 {{showArrow ? '' : 'hidden'}}">
|
|
30
|
+
<span ref="arrowMark"></span>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<slot name="right-icon"></slot>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
`
|
|
37
|
+
|
|
38
|
+
export default class extends HTMLElement {
|
|
39
|
+
title = ''
|
|
40
|
+
value = ''
|
|
41
|
+
label = ''
|
|
42
|
+
icon = ''
|
|
43
|
+
isIconUrl = false
|
|
44
|
+
arrowDirection = ''
|
|
45
|
+
showArrow = false
|
|
46
|
+
clickable = false
|
|
47
|
+
isClickableHover = false
|
|
48
|
+
classStr = ''
|
|
49
|
+
|
|
50
|
+
// For grouped rounded corners if we support cell-group later
|
|
51
|
+
isFirst = false
|
|
52
|
+
isLast = false
|
|
53
|
+
|
|
54
|
+
constructor() {
|
|
55
|
+
super()
|
|
56
|
+
this.style.display = 'block'
|
|
57
|
+
const attr = useAttr(this)
|
|
58
|
+
|
|
59
|
+
this.title = attr.title || ''
|
|
60
|
+
this.value = attr.value || ''
|
|
61
|
+
this.label = attr.label || ''
|
|
62
|
+
|
|
63
|
+
this.icon = attr.icon || ''
|
|
64
|
+
this.isIconUrl = this.icon.startsWith('http') || this.icon.startsWith('/') || this.icon.startsWith('data:')
|
|
65
|
+
|
|
66
|
+
// Arrow direction: 'right', 'down', 'up', 'left'. Default is empty (no arrow)
|
|
67
|
+
// If is-link is present, implicitly show right arrow unless specified
|
|
68
|
+
const isLink = attr['is-link'] !== undefined && attr['is-link'] !== 'false'
|
|
69
|
+
this.arrowDirection = attr['arrow-direction'] || (isLink ? 'right' : '')
|
|
70
|
+
this.showArrow = !!this.arrowDirection
|
|
71
|
+
|
|
72
|
+
// Clickable implies hover effect and pointer cursor
|
|
73
|
+
this.clickable = this.showArrow || (attr.clickable !== undefined && attr.clickable !== 'false')
|
|
74
|
+
|
|
75
|
+
this.classStr = attr.class || ''
|
|
76
|
+
|
|
77
|
+
// Helper classes for borderline and border-radius rounding (handled externally via cell-group usually, but allowing override)
|
|
78
|
+
this.isFirst = attr['round-top'] !== undefined && attr['round-top'] !== 'false'
|
|
79
|
+
this.isLast = attr['border'] === 'false' || (attr['round-bottom'] !== undefined && attr['round-bottom'] !== 'false')
|
|
80
|
+
|
|
81
|
+
// Adjust border logic
|
|
82
|
+
if (this.isLast || attr.border === 'false') {
|
|
83
|
+
this.classStr = this.classStr.replace('border-b', '') + ' border-transparent'
|
|
84
|
+
}
|
|
85
|
+
if (this.isFirst) {
|
|
86
|
+
this.classStr += ' rounded-t-2xl'
|
|
87
|
+
}
|
|
88
|
+
if (this.isLast) {
|
|
89
|
+
this.classStr += ' rounded-b-2xl'
|
|
90
|
+
}
|
|
91
|
+
if (!this.isFirst && !this.isLast && attr.round === 'true') {
|
|
92
|
+
this.classStr += ' rounded-2xl border-transparent'
|
|
93
|
+
this.isFirst = true
|
|
94
|
+
this.isLast = true
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
ready() {
|
|
99
|
+
const { iconMark, arrowMark } = useRef(this)
|
|
100
|
+
|
|
101
|
+
// Handle Left Icon
|
|
102
|
+
if (this.icon) {
|
|
103
|
+
const iconHtml = this.isIconUrl
|
|
104
|
+
? `<img src="${this.icon}" class="w-5 h-5" />`
|
|
105
|
+
: `<g-icon name="${this.icon}" class="w-5 h-5"></g-icon>`
|
|
106
|
+
const iconNode = bind(iconHtml).create(this)
|
|
107
|
+
iconMark.parentElement.insertBefore(iconNode, iconMark)
|
|
108
|
+
}
|
|
109
|
+
iconMark.parentElement.removeChild(iconMark)
|
|
110
|
+
|
|
111
|
+
// Handle Right Arrow
|
|
112
|
+
if (this.showArrow) {
|
|
113
|
+
// Map direction to standard icons if we had them or just use svg path directly
|
|
114
|
+
// M9 5l7 7-7 7 (right)
|
|
115
|
+
// M19 9l-7 7-7-7 (down)
|
|
116
|
+
// M5 15l7-7 7 7 (up)
|
|
117
|
+
// M15 19l-7-7 7-7 (left)
|
|
118
|
+
let pathD = 'M9 5l7 7-7 7' // default right
|
|
119
|
+
if (this.arrowDirection === 'down') pathD = 'M19 9l-7 7-7-7'
|
|
120
|
+
else if (this.arrowDirection === 'up') pathD = 'M5 15l7-7 7 7'
|
|
121
|
+
else if (this.arrowDirection === 'left') pathD = 'M15 19l-7-7 7-7'
|
|
122
|
+
|
|
123
|
+
const arrowHtml = `<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="${pathD}"></path></svg>`
|
|
124
|
+
const arrowNode = bind(arrowHtml).create(this)
|
|
125
|
+
arrowMark.parentElement.insertBefore(arrowNode, arrowMark)
|
|
126
|
+
}
|
|
127
|
+
arrowMark.parentElement.removeChild(arrowMark)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useAttr } from "../../ce.mjs";
|
|
2
|
+
|
|
3
|
+
export default class extends HTMLElement {
|
|
4
|
+
constructor() {
|
|
5
|
+
super()
|
|
6
|
+
this.style.display = 'block'
|
|
7
|
+
this.style.boxSizing = 'border-box'
|
|
8
|
+
|
|
9
|
+
const attr = useAttr(this)
|
|
10
|
+
|
|
11
|
+
const span = attr.span ? Number(attr.span) : 24
|
|
12
|
+
const offset = attr.offset ? Number(attr.offset) : 0
|
|
13
|
+
const classStr = attr.class || ''
|
|
14
|
+
|
|
15
|
+
// Convert span 1-24 to basis/% widths directly on host element
|
|
16
|
+
if (span) {
|
|
17
|
+
const percentage = (span / 24) * 100
|
|
18
|
+
this.style.width = `${percentage}%`
|
|
19
|
+
this.style.flex = `0 0 ${percentage}%`
|
|
20
|
+
this.style.maxWidth = `${percentage}%`
|
|
21
|
+
} else {
|
|
22
|
+
this.style.width = '0'
|
|
23
|
+
this.style.flex = '0 0 0'
|
|
24
|
+
this.style.maxWidth = '0'
|
|
25
|
+
this.style.overflow = 'hidden'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Convert offset 1-24 to margin-left natively
|
|
29
|
+
if (offset) {
|
|
30
|
+
const offsetPerc = (offset / 24) * 100
|
|
31
|
+
this.style.marginLeft = `${offsetPerc}%`
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (classStr) {
|
|
35
|
+
this.className = this.className ? this.className + ' ' + classStr : classStr
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { useAttr, useWatch } from "../../ce.mjs";
|
|
2
|
+
|
|
3
|
+
export const innerHTML = `
|
|
4
|
+
<div class="flex items-center w-full min-h-[44px] px-3 bg-white/60 dark:bg-gray-800/60 backdrop-blur-2xl rounded-xl border border-gray-200 dark:border-gray-700 transition-all duration-300 {{focusClass}} {{disabledClass}} {{readonlyClass}}">
|
|
5
|
+
<!-- Prefix Icon Option (e.g. search icon) -->
|
|
6
|
+
<div class="mr-2 text-gray-400 dark:text-gray-500 flex items-center justify-center {{leftIcon ? '' : 'hidden'}}">
|
|
7
|
+
<g-icon name="{{leftIcon}}" class="w-4 h-4"></g-icon>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<!-- Label Option -->
|
|
11
|
+
<div class="mr-4 text-sm whitespace-nowrap text-gray-700 dark:text-gray-300 font-medium select-none {{label ? '' : 'hidden'}}">
|
|
12
|
+
{{label}}
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<!-- Input Area -->
|
|
16
|
+
<div class="flex-1 relative flex items-center h-full">
|
|
17
|
+
<input
|
|
18
|
+
type="{{type}}"
|
|
19
|
+
class="w-full h-full bg-transparent border-none outline-none text-sm text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 {{disabled || readonly ? 'cursor-not-allowed text-gray-500 dark:text-gray-400' : ''}}"
|
|
20
|
+
placeholder="{{placeholder}}"
|
|
21
|
+
value="{{value}}"
|
|
22
|
+
{{disabled ? 'disabled' : ''}}
|
|
23
|
+
{{readonly ? 'readonly' : ''}}
|
|
24
|
+
oninput="{{handleInput}}"
|
|
25
|
+
onfocus="{{handleFocus}}"
|
|
26
|
+
onblur="{{handleBlur}}"
|
|
27
|
+
onchange="{{handleChange}}"
|
|
28
|
+
onkeydown="{{handleKeyDown}}"
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
<!-- Clear Icon -->
|
|
32
|
+
<div class="ml-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 cursor-pointer transition-colors flex items-center justify-center {{clearable && value && !disabled && !readonly ? '' : 'hidden'}}" onclick="{{clear}}">
|
|
33
|
+
<g-icon name="close" class="w-4 h-4 bg-gray-200/50 dark:bg-gray-700/50 rounded-full p-0.5 hover:bg-gray-300 dark:hover:bg-gray-600"></g-icon>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Right Icon Option -->
|
|
37
|
+
<div class="ml-2 text-gray-400 dark:text-gray-500 flex items-center justify-center cursor-pointer {{rightIcon ? '' : 'hidden'}}" onclick="{{onRightIconClick}}">
|
|
38
|
+
<g-icon name="{{rightIcon}}" class="w-4 h-4"></g-icon>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
`
|
|
43
|
+
|
|
44
|
+
export default class extends HTMLElement {
|
|
45
|
+
value = ''
|
|
46
|
+
type = 'text'
|
|
47
|
+
placeholder = '请输入内容'
|
|
48
|
+
label = ''
|
|
49
|
+
leftIcon = ''
|
|
50
|
+
rightIcon = ''
|
|
51
|
+
|
|
52
|
+
// Using string boolean values from attributes
|
|
53
|
+
disabled = false
|
|
54
|
+
readonly = false
|
|
55
|
+
clearable = false
|
|
56
|
+
|
|
57
|
+
focusClass = 'hover:border-gray-300 dark:hover:border-gray-600'
|
|
58
|
+
disabledClass = ''
|
|
59
|
+
readonlyClass = ''
|
|
60
|
+
form = null
|
|
61
|
+
name = ''
|
|
62
|
+
|
|
63
|
+
constructor() {
|
|
64
|
+
super()
|
|
65
|
+
this.style.display = 'block'
|
|
66
|
+
this.style.width = '100%'
|
|
67
|
+
|
|
68
|
+
const attr = useAttr(this)
|
|
69
|
+
|
|
70
|
+
this.value = attr.value || ''
|
|
71
|
+
this.type = attr.type || 'text'
|
|
72
|
+
this.placeholder = attr.placeholder || '请输入内容'
|
|
73
|
+
this.label = attr.label || ''
|
|
74
|
+
this.leftIcon = attr['left-icon'] || ''
|
|
75
|
+
this.rightIcon = attr['right-icon'] || ''
|
|
76
|
+
this.name = this.name || attr.name || ''
|
|
77
|
+
|
|
78
|
+
this.disabled = attr.disabled === 'true' || attr.disabled === ''
|
|
79
|
+
this.readonly = attr.readonly === 'true' || attr.readonly === ''
|
|
80
|
+
this.clearable = attr.clearable === 'true' || attr.clearable === ''
|
|
81
|
+
|
|
82
|
+
this._updateClasses()
|
|
83
|
+
|
|
84
|
+
const watch = useWatch(this)
|
|
85
|
+
// Ensure changing disabled/readonly state dynamically also acts
|
|
86
|
+
watch({
|
|
87
|
+
disabled: () => this._updateClasses(),
|
|
88
|
+
readonly: () => this._updateClasses()
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
this.form = this.closest('g-form')
|
|
92
|
+
|
|
93
|
+
this.updateFormValue()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
updateFormValue() {
|
|
97
|
+
|
|
98
|
+
if (this.form && this.name) {
|
|
99
|
+
|
|
100
|
+
this.form.data[this.name] = this.value
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
_updateClasses() {
|
|
105
|
+
if (this.disabled) {
|
|
106
|
+
this.disabledClass = 'opacity-60 bg-gray-50 dark:bg-gray-900/40 border-gray-100 dark:border-gray-800'
|
|
107
|
+
this.focusClass = ''
|
|
108
|
+
} else if (this.readonly) {
|
|
109
|
+
this.readonlyClass = 'bg-gray-50 dark:bg-gray-900/40'
|
|
110
|
+
this.focusClass = ''
|
|
111
|
+
} else {
|
|
112
|
+
this.disabledClass = ''
|
|
113
|
+
this.readonlyClass = ''
|
|
114
|
+
this.focusClass = 'hover:border-gray-300 dark:hover:border-gray-600 focus-within:border-blue-500 focus-within:ring-2 focus-within:ring-blue-500/20 dark:focus-within:border-blue-400'
|
|
115
|
+
}
|
|
116
|
+
if (this.update) this.update()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
handleInput(e) {
|
|
120
|
+
this.value = e.target.value
|
|
121
|
+
if (this.update) this.update()
|
|
122
|
+
if (this.oninput) this.oninput(e)
|
|
123
|
+
this.updateFormValue()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
handleChange(e) {
|
|
127
|
+
if (this.onchange) this.onchange(e)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
handleFocus(e) {
|
|
131
|
+
if (this.onfocus) this.onfocus(e)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
handleBlur(e) {
|
|
135
|
+
// Small delay so clear button click can register before focus is lost entirely if we base logic on focus
|
|
136
|
+
if (this.onblur) this.onblur(e)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
handleKeyDown(e) {
|
|
140
|
+
if (e.key === 'Enter' && this.onenter) {
|
|
141
|
+
this.onenter(e)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
clear() {
|
|
146
|
+
if (this.disabled || this.readonly) return
|
|
147
|
+
this.value = ''
|
|
148
|
+
const input = this.querySelector('input')
|
|
149
|
+
if (input) {
|
|
150
|
+
input.value = ''
|
|
151
|
+
input.focus()
|
|
152
|
+
// Dispatch input event artificially for watchers
|
|
153
|
+
input.dispatchEvent(new Event('input', { bubbles: true }))
|
|
154
|
+
}
|
|
155
|
+
if (this.update) this.update()
|
|
156
|
+
if (this.onclear) this.onclear()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
onRightIconClick(e) {
|
|
160
|
+
if (this.onrightclick) this.onrightclick(e)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useAttr, useRef } from "../../ce.mjs";
|
|
2
|
+
|
|
3
|
+
export const innerHTML = `
|
|
4
|
+
<svg ref="svg" class="{{classStr}}" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path ref="path" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path>
|
|
6
|
+
</svg>
|
|
7
|
+
<div class="{{hasDot ? '' : 'hidden'}} absolute top-0 right-0 transform translate-x-[20%] -translate-y-[20%] flex h-2.5 w-2.5">
|
|
8
|
+
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
|
|
9
|
+
<span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-red-500 border-[1.5px] border-white dark:border-gray-800"></span>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="{{badge ? '' : 'hidden'}} absolute top-0 right-0 transform translate-x-[30%] -translate-y-[30%] flex items-center justify-center z-10">
|
|
12
|
+
<span class="relative inline-flex rounded-full bg-red-500 text-white text-[10px] items-center justify-center px-1 min-w-[16px] h-[16px] border-[1.5px] border-white dark:border-gray-800 font-medium whitespace-nowrap leading-none shadow-sm">{{badge}}</span>
|
|
13
|
+
</div>
|
|
14
|
+
`
|
|
15
|
+
|
|
16
|
+
// Icon paths mapped by name
|
|
17
|
+
const icons = {
|
|
18
|
+
system: 'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z',
|
|
19
|
+
system_inner: 'M15 12a3 3 0 11-6 0 3 3 0 016 0z', // Need to add multiple paths if needed, here we simplify or append
|
|
20
|
+
user: 'M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z',
|
|
21
|
+
role: 'M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.956 11.956 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z',
|
|
22
|
+
menu: 'M4 6h16M4 12h16M4 18h16',
|
|
23
|
+
tools: 'M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z M15 12a3 3 0 11-6 0 3 3 0 016 0z', // Combining paths for simplicity for now
|
|
24
|
+
search: 'M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z',
|
|
25
|
+
button: 'M8 11V7a4 4 0 118 0m-4 8v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2z',
|
|
26
|
+
home: 'M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6',
|
|
27
|
+
edit: 'M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z',
|
|
28
|
+
delete: 'M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16',
|
|
29
|
+
add: 'M12 4v16m8-8H4',
|
|
30
|
+
check: 'M5 13l4 4L19 7',
|
|
31
|
+
close: 'M6 18L18 6M6 6l12 12',
|
|
32
|
+
info: 'M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
|
|
33
|
+
warning: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z',
|
|
34
|
+
view: 'M15 12a3 3 0 11-6 0 3 3 0 016 0zM2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z',
|
|
35
|
+
logout: 'M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1',
|
|
36
|
+
upload: 'M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12',
|
|
37
|
+
download: 'M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4',
|
|
38
|
+
refresh: 'M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default class extends HTMLElement {
|
|
42
|
+
// name = ''
|
|
43
|
+
classStr = ''
|
|
44
|
+
size = ''
|
|
45
|
+
color = ''
|
|
46
|
+
hasDot = false
|
|
47
|
+
badge = ''
|
|
48
|
+
|
|
49
|
+
constructor() {
|
|
50
|
+
super()
|
|
51
|
+
this.style.display = 'inline-flex'
|
|
52
|
+
this.style.alignItems = 'center'
|
|
53
|
+
this.style.justifyContent = 'center'
|
|
54
|
+
this.style.position = 'relative'
|
|
55
|
+
|
|
56
|
+
const attr = useAttr(this)
|
|
57
|
+
this.name = this.name || attr.name || ''
|
|
58
|
+
this.size = attr.size || ''
|
|
59
|
+
this.color = attr.color || ''
|
|
60
|
+
this.badge = attr.badge || ''
|
|
61
|
+
this.hasDot = !this.badge && attr.dot !== undefined && attr.dot !== 'false'
|
|
62
|
+
this.classStr = attr.class || (this.size ? '' : 'w-5 h-5')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
ready() {
|
|
66
|
+
const { path, svg } = useRef(this)
|
|
67
|
+
|
|
68
|
+
if (this.size) {
|
|
69
|
+
svg.style.width = this.size
|
|
70
|
+
svg.style.height = this.size
|
|
71
|
+
}
|
|
72
|
+
if (this.color) {
|
|
73
|
+
svg.style.color = this.color
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (this.name && icons[this.name]) {
|
|
77
|
+
path.setAttribute('d', icons[this.name])
|
|
78
|
+
} else {
|
|
79
|
+
path.setAttribute('d', 'M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z') // default info icon
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|