mono-jsx 0.6.11 → 0.6.12
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 +41 -0
- package/jsx-runtime.mjs +69 -57
- package/package.json +1 -1
- package/types/html.d.ts +1 -0
- package/types/mono.d.ts +5 -1
package/README.md
CHANGED
|
@@ -543,6 +543,15 @@ function App(this: FC<{ value: string }>) {
|
|
|
543
543
|
}
|
|
544
544
|
```
|
|
545
545
|
|
|
546
|
+
You can also use the `$checked` attribute to bind a signal to the checked state of a checkbox or radio input element.
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
function App(this: FC<{ checked: boolean }>) {
|
|
550
|
+
this.checked = false;
|
|
551
|
+
return <input type="checkbox" $checked={this.checked} />;
|
|
552
|
+
}
|
|
553
|
+
```
|
|
554
|
+
|
|
546
555
|
### Limitation of Signals
|
|
547
556
|
|
|
548
557
|
1\. Arrow function are non-stateful components.
|
|
@@ -1063,6 +1072,38 @@ export default {
|
|
|
1063
1072
|
}
|
|
1064
1073
|
```
|
|
1065
1074
|
|
|
1075
|
+
## Using View Transition
|
|
1076
|
+
|
|
1077
|
+
mono-jsx supports [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API) to create smooth transitions between views. To use view transition, add `viewTransition` attribute to below components:
|
|
1078
|
+
|
|
1079
|
+
- `<toggle viewTransition="transition-name">`
|
|
1080
|
+
- `<switch viewTransition="transition-name">`
|
|
1081
|
+
- `<component viewTransition="transition-name">`
|
|
1082
|
+
- `<router viewTransition="transition-name">`
|
|
1083
|
+
|
|
1084
|
+
You can set custom transition animation by adding [`::view-transition-group`](https://developer.mozilla.org/en-US/docs/Web/CSS/::view-transition-group) and [`::view-transition-old`](https://developer.mozilla.org/en-US/docs/Web/CSS/::view-transition-old) and [`::view-transition-new`](https://developer.mozilla.org/en-US/docs/Web/CSS/::view-transition-new) pseudo-elements with your own CSS animation. For example,
|
|
1085
|
+
|
|
1086
|
+
```tsx
|
|
1087
|
+
function App(this: FC<{ show: boolean }>) {
|
|
1088
|
+
return (
|
|
1089
|
+
<div
|
|
1090
|
+
style={{
|
|
1091
|
+
"@keyframes fade-in": { from: { opacity: 0 }, to: { opacity: 1 } },
|
|
1092
|
+
"@keyframes fade-out": { from: { opacity: 1 }, to: { opacity: 0 } },
|
|
1093
|
+
"::view-transition-group(fade)": { animationDuration: "0.5s" },
|
|
1094
|
+
"::view-transition-old(fade)": { animation: "0.5s ease-in both fade-out" },
|
|
1095
|
+
"::view-transition-new(fade)": { animation: "0.5s ease-in both fade-in" },
|
|
1096
|
+
}}
|
|
1097
|
+
>
|
|
1098
|
+
<toggle show={this.show} viewTransition="fade">
|
|
1099
|
+
<h1>Hello world!</h1>
|
|
1100
|
+
</toggle>
|
|
1101
|
+
<button onClick={() => this.show = !this.show}>Toggle</button>
|
|
1102
|
+
</div>
|
|
1103
|
+
)
|
|
1104
|
+
}
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1066
1107
|
## Customizing html Response
|
|
1067
1108
|
|
|
1068
1109
|
You can add `status` or `headers` attributes to the root `<html>` element to customize the http response:
|
package/jsx-runtime.mjs
CHANGED
|
@@ -11,14 +11,14 @@ var LAZY = 256;
|
|
|
11
11
|
var ROUTER = 512;
|
|
12
12
|
var EVENT_JS = `{var w=window;w.$emit=(e,f,s)=>f.call(w.$signals?.(s)??e.target,e.type==="mount"?e.target:e);w.$onsubmit=(e,f,s)=>{e.preventDefault();f.call(w.$signals?.(s)??e.target,new FormData(e.target),e)};}`;
|
|
13
13
|
var CX_JS = `{var n=e=>typeof e=="string"?e:typeof e=="object"&&e!==null?Array.isArray(e)?e.map(n).filter(Boolean).join(" "):Object.entries(e).filter(([,t])=>!!t).map(([t])=>t).join(" "):"";window.$cx=n;}`;
|
|
14
|
-
var STYLE_JS = `{var
|
|
14
|
+
var STYLE_JS = `{var l=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;var u=e=>typeof e=="string",p=e=>typeof e=="object"&&e!==null,f=e=>e.replace(/[a-z][A-Z]/g,o=>o.charAt(0)+"-"+o.charAt(1).toLowerCase());var g=e=>{let o=[],n=[],r=new y;for(let[t,s]of Object.entries(e))switch(t.charCodeAt(0)){case 58:n.push(t.startsWith("::view-")?"":null,t+"{"+c(s)+"}");break;case 64:t.startsWith("@keyframes ")||t.startsWith("@view-")?p(s)&&n.push(t+"{"+Object.entries(s).map(([i,a])=>i+"{"+c(a)+"}").join("")+"}"):n.push(t+"{",null,"{"+c(s)+"}}");break;case 38:n.push(null,t.slice(1)+"{"+c(s)+"}");break;default:o.push([t,s])}return o.length>0&&(r.inline=c(o)),n.length>0&&(r.css=n),r},b=(e,o)=>{let{inline:n,css:r}=g(o);if(r){let t="data-css-",s="["+t+(Date.now()+Math.random()).toString(36).replace(".","")+"]";document.head.appendChild(document.createElement("style")).textContent=(n?s+"{"+n+"}":"")+r.map(i=>i===null?s:i).join(""),e.getAttributeNames().forEach(i=>i.startsWith(t)&&e.removeAttribute(i)),e.setAttribute(s.slice(1,-1),"")}else n&&e.setAttribute("style",n)},c=e=>{if(typeof e=="object"&&e!==null){let o="";for(let[n,r]of Array.isArray(e)?e:Object.entries(e))if(u(r)||typeof r=="number"){let t=f(n),s=typeof r=="number"?l.test(n)?""+r:r+"px":""+r;o+=(o?";":"")+t+":"+(t==="content"?JSON.stringify(s):s)}return o}return""},y=(()=>{function e(){}return e.prototype=Object.freeze(Object.create(null)),e})();window.$applyStyle=b;}`;
|
|
15
15
|
var RENDER_ATTR_JS = `{var s=(l,n,r)=>{let e=l.parentElement;return e.tagName==="M-GROUP"&&(e=e.previousElementSibling),()=>{let t=r();n==="value"?e.value=String(t):n==="checked"?e.checked=!!t:typeof t=="boolean"?e.toggleAttribute(n,t):t==null?e.removeAttribute(n):typeof t=="object"?n==="class"?e.setAttribute(n,$cx(t)):n==="style"?$applyStyle(e,t):e.setAttribute(n,JSON.stringify(t)):e.setAttribute(n,String(t))}};window.$renderAttr=s;}`;
|
|
16
|
-
var RENDER_TOGGLE_JS = `{var
|
|
17
|
-
var RENDER_SWITCH_JS = `{var
|
|
16
|
+
var RENDER_TOGGLE_JS = `{var i=(e,s)=>{let t,l=()=>e.replaceChildren(...s()?t:[]);return()=>{if(!t){let n=e.firstElementChild;n&&n.tagName==="TEMPLATE"&&n.hasAttribute("m-slot")?t=[...n.content.childNodes]:t=[...e.childNodes]}e.hasAttribute("vt")&&document.startViewTransition?document.startViewTransition(l):l()}};window.$renderToggle=i;}`;
|
|
17
|
+
var RENDER_SWITCH_JS = `{var a=(l,u)=>{let s,r=l.getAttribute("value"),t,i,o=e=>t.get(e)??t.set(e,[]).get(e),d=()=>l.replaceChildren(...t.has(s)?t.get(s):i);return()=>{if(!t){t=new Map,i=[];for(let e of l.childNodes)if(e.nodeType===1&&e.tagName==="TEMPLATE"&&e.hasAttribute("m-slot")){for(let n of e.content.childNodes)n.nodeType===1&&n.hasAttribute("slot")?o(n.getAttribute("slot")).push(n):i.push(n);e.remove()}else r?o(r).push(e):i.push(e)}s=""+u(),l.hasAttribute("vt")&&document.startViewTransition?document.startViewTransition(d):d()}};window.$renderSwitch=a;}`;
|
|
18
18
|
var SIGNALS_JS = `{let m;const h=window,b=new Map,k=new Map,l=n=>k.get(n)??k.set(n,M(n)).get(n),y=()=>Object.create(null),f=(n,e)=>n.getAttribute(e),M=n=>{const e=y(),t=(r,c)=>{e[r]=c},s=new Map,a=(r,c)=>{let o=s.get(r);return o||(o=new Set,s.set(r,o)),o.add(c),()=>{o.delete(c),o.size===0&&s.delete(r)}},i=new Proxy(y(),{get:(r,c)=>document.querySelector("[data-ref='"+n+":"+c+"']")});return new Proxy(e,{get:(r,c,o)=>{switch(c){case"$init":return t;case"$watch":return a;case"app":return l(0);case"refs":return i;default:return m?.(n,c),Reflect.get(r,c,o)}},set:(r,c,o,d)=>{if(o!==Reflect.get(r,c,d)){const u=s.get(c);return u&&queueMicrotask(()=>u.forEach(g=>g())),Reflect.set(r,c,o,d)}return!1}})},$=(n,e,t)=>{switch(e){case"toggle":return $renderToggle(n,t);case"switch":return $renderSwitch(n,t);case"html":return()=>n.innerHTML=""+t()}return e&&e.length>2&&e.startsWith("[")&&e.endsWith("]")?$renderAttr(n,e.slice(1,-1),t):()=>n.textContent=""+t()},E=n=>{const e=n.indexOf(":");return e>0?[Number(n.slice(0,e)),n.slice(e+1)]:null},p=async n=>{const e=n();return e!==void 0?e:(await new Promise(t=>setTimeout(t,0)),p(n))},S=n=>{typeof n=="function"&&n()},v=(n,e)=>customElements.define(n,class extends HTMLElement{disposes=[];connectedCallback(){e(this)}disconnectedCallback(){this.disposes.forEach(t=>t()),this.disposes.length=0}});v("m-signal",n=>{const e=Number(f(n,"scope")),t=l(e),s=f(n,"key");if(s)n.disposes.push(t.$watch(s,$(n,f(n,"mode"),()=>t[s])));else{const a=Number(f(n,"computed"));p(()=>b.get(e*1e9+a)).then(([i,r])=>{const c=$(n,f(n,"mode"),i.bind(t));r.forEach(o=>{const[d,u]=E(o);n.disposes.push(l(d).$watch(u,c))})})}}),v("m-effect",n=>{const{disposes:e}=n,t=Number(f(n,"scope")),s=Number(f(n,"n")),a=new Array(s);e.push(()=>{a.forEach(S),a.length=0});for(let i=0;i<s;i++){const r="$ME_"+t+"_"+i;p(()=>h[r]).then(c=>{const o=[],d=l(t),u=()=>{S(a[i]),a[i]=c.call(d)};m=(g,w)=>o.push([g,w]),u(),m=void 0;for(const[g,w]of o)e.push(l(g).$watch(w,u))},()=>{})}}),h.$MS=(n,e)=>{const[t,s]=E(n);l(t).$init(s,e)},h.$MC=(n,e,t,s)=>{b.set(n*1e9+e,[t,s])},h.$patch=(n,...e)=>{for(const[t,...s]of e){const a=s.pop();let i=n;for(const r of s)i=i[r];i[a]=t}return n},h.$signals=n=>n!==void 0?l(n):void 0;}`;
|
|
19
19
|
var SUSPENSE_JS = `{const i=new Map,o=e=>e.getAttribute("chunk-id"),l=(e,t)=>customElements.define(e,class extends HTMLElement{connectedCallback(){t(this)}});l("m-portal",e=>{i.set(o(e),e)}),l("m-chunk",e=>{setTimeout(()=>{const t=o(e),n=i.get(t),s=e.firstChild?.content.childNodes;n&&(e.hasAttribute("next")?s&&n.before(...s):(e.hasAttribute("done")?n.remove():s&&n.replaceWith(...s),i.delete(t)),e.remove())})});}`;
|
|
20
|
-
var LAZY_JS = `{const
|
|
21
|
-
var ROUTER_JS = `{const
|
|
20
|
+
var LAZY_JS = `{const e=document,a=(t,s)=>t.getAttribute(s);customElements.define("m-component",class extends HTMLElement{static observedAttributes=["name","props"];#t;#s;#r;#h;#i;#e=new Map;#a=!0;async#l(){if(!this.#t){this.#n("");return}const t=this.#s||"{}",s=this.#t+t,i={"x-component":this.#t,"x-props":t,"x-flags":$FLAGS},n=new AbortController;if(this.#h?.abort(),this.#h=n,this.#e.has(s)){this.#n(this.#e.get(s));return}this.#r?.length&&this.#n(this.#r);const r=await fetch(location.href,{headers:i,signal:n.signal});if(!r.ok)throw this.#n(""),new Error("Failed to fetch component '"+this.#t+"'");const[h,o]=await r.json();this.#e.set(s,h),this.#n(h),o&&(e.body.appendChild(e.createElement("script")).textContent=o)}#n(t){const s=()=>typeof t=="string"?this.innerHTML=t:this.replaceChildren(...t);this.hasAttribute("vt")&&e.startViewTransition&&!this.#a?e.startViewTransition(s):s(),this.#a=!1}get name(){return this.#t??null}set name(t){t&&t!==this.#t&&(this.#t=t,this.#o())}get props(){return this.#s?JSON.parse(this.#s):void 0}set props(t){const s=typeof t=="string"?t:JSON.stringify(t);s&&s!==this.#s&&(this.#s=s,this.#o())}attributeChangedCallback(t,s,i){this.#t&&i&&(t==="name"?this.name=i:t==="props"&&(this.props=i))}connectedCallback(){setTimeout(()=>{if(!this.#r){const t=a(this,"props");this.#t=a(this,"name"),this.#s=t?.startsWith("base64,")?atob(t.slice(7)):void 0,this.#r=[...this.childNodes]}this.#l()})}disconnectedCallback(){this.#e.clear(),this.#h?.abort(),this.#h=void 0,this.#i&&clearTimeout(this.#i),this.#i=void 0}#o(){this.#i&&clearTimeout(this.#i),this.#i=setTimeout(()=>{this.#i=void 0,this.#l()},50)}refresh(){this.#t&&this.#e.delete(this.#t+(this.#s||"{}")),this.#o()}});}`;
|
|
21
|
+
var ROUTER_JS = `{const n=document,a=location,l=t=>t.split("#",1)[0],c=t=>l(t)===l(a.href);customElements.define("m-router",class extends HTMLElement{#t;#e;#s;#i;#n=new Map;#r=!0;async#c(t){this.#n.has(t)&&this.#a(this.#n.get(t));const e=new AbortController,s={"x-route":"true","x-flags":$FLAGS};this.#i?.abort(),this.#i=e;const i=await fetch(t,{headers:s,signal:e.signal});if(i.status===404)return this.#a(this.#t??[]),404;if(!i.ok)throw this.replaceChildren(),new Error("Failed to fetch route: "+i.status+" "+i.statusText);const[r,o]=await i.json();this.#n.set(t,r),this.#a(r),o&&(n.body.appendChild(n.createElement("script")).textContent=o)}#a(t){const e=()=>typeof t=="string"?this.innerHTML=t:this.replaceChildren(...t);this.hasAttribute("vt")&&n.startViewTransition&&!this.#r?n.startViewTransition(e):e(),this.#r=!1}#o(){n.querySelectorAll("nav a").forEach(t=>{const{href:e,classList:s}=t,i=t.closest("nav")?.getAttribute("data-active-class")??"active";c(e)?s.add(i):s.remove(i)})}async#l(t,e){const s=await this.#c(t)===404;e?.replace?history.replaceState({},"",t):history.pushState({},"",t),s&&typeof $signals<"u"&&($signals(0).url=new URL(t)),this.#o(),window.scrollTo(0,0)}navigate(t,e){const s=new URL(t,a.href);if(s.origin!==a.origin){a.href=t;return}c(s.href)||this.#l(t,e)}connectedCallback(){setTimeout(()=>{if(!this.#t)if(this.getAttribute("status")==="404")this.#t=[...this.childNodes];else{this.#t=[];for(const t of this.childNodes)if(t.nodeType===1&&t.tagName==="TEMPLATE"&&t.hasAttribute("m-slot")){this.#t.push(...t.content.childNodes),t.remove();break}}}),this.#e=t=>{if(t.defaultPrevented||t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||!(t.target instanceof HTMLAnchorElement))return;const{download:e,href:s,rel:i,target:r}=t.target;e||i==="external"||r==="_blank"||!s.startsWith(a.origin)||(t.preventDefault(),this.navigate(s))},this.#s=()=>this.#l(a.href),addEventListener("popstate",this.#s),n.addEventListener("click",this.#e),setTimeout(()=>this.#o())}disconnectedCallback(){removeEventListener("popstate",this.#s),n.removeEventListener("click",this.#e),this.#i?.abort(),this.#i=void 0,this.#n.clear(),this.#e=void 0,this.#s=void 0}});}`;
|
|
22
22
|
|
|
23
23
|
// runtime/utils.ts
|
|
24
24
|
var regexpCssBareUnitProps = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
|
|
@@ -46,11 +46,17 @@ var styleToCSS = (style) => {
|
|
|
46
46
|
switch (k.charCodeAt(0)) {
|
|
47
47
|
case /* ':' */
|
|
48
48
|
58:
|
|
49
|
-
css.push(null, k + "{" + renderStyle(v) + "}");
|
|
49
|
+
css.push(k.startsWith("::view-") ? "" : null, k + "{" + renderStyle(v) + "}");
|
|
50
50
|
break;
|
|
51
51
|
case /* '@' */
|
|
52
52
|
64:
|
|
53
|
-
|
|
53
|
+
if (k.startsWith("@keyframes ") || k.startsWith("@view-")) {
|
|
54
|
+
if (isObject(v)) {
|
|
55
|
+
css.push(k + "{" + Object.entries(v).map(([k2, v2]) => k2 + "{" + renderStyle(v2) + "}").join("") + "}");
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
css.push(k + "{", null, "{" + renderStyle(v) + "}}");
|
|
59
|
+
}
|
|
54
60
|
break;
|
|
55
61
|
case /* '&' */
|
|
56
62
|
38:
|
|
@@ -135,7 +141,7 @@ var $signal = Symbol.for("mono.signal");
|
|
|
135
141
|
var $vnode = Symbol.for("jsx.vnode");
|
|
136
142
|
|
|
137
143
|
// version.ts
|
|
138
|
-
var VERSION = "0.6.
|
|
144
|
+
var VERSION = "0.6.11";
|
|
139
145
|
|
|
140
146
|
// render.ts
|
|
141
147
|
var cdn = "https://raw.esm.sh";
|
|
@@ -434,7 +440,7 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
434
440
|
case "object":
|
|
435
441
|
if (node === null) {
|
|
436
442
|
} else if (isSignal(node)) {
|
|
437
|
-
renderSignal(rc, node
|
|
443
|
+
rc.write(renderSignal(rc, node));
|
|
438
444
|
} else if (isVNode(node)) {
|
|
439
445
|
const [tag, props] = node;
|
|
440
446
|
switch (tag) {
|
|
@@ -450,7 +456,7 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
450
456
|
const { innerHTML } = props;
|
|
451
457
|
if (innerHTML) {
|
|
452
458
|
if (isSignal(innerHTML)) {
|
|
453
|
-
renderSignal(rc, innerHTML, "html"
|
|
459
|
+
rc.write(renderSignal(rc, innerHTML, "html"));
|
|
454
460
|
} else {
|
|
455
461
|
write(innerHTML);
|
|
456
462
|
}
|
|
@@ -476,7 +482,7 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
476
482
|
}
|
|
477
483
|
// `<toggle>` element
|
|
478
484
|
case "toggle": {
|
|
479
|
-
let { show, hidden, children } = props;
|
|
485
|
+
let { show, hidden, viewTransition, children } = props;
|
|
480
486
|
if (children !== void 0) {
|
|
481
487
|
if (show === void 0 && hidden !== void 0) {
|
|
482
488
|
if (isSignal(hidden)) {
|
|
@@ -498,13 +504,8 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
498
504
|
}
|
|
499
505
|
}
|
|
500
506
|
if (isSignal(show)) {
|
|
501
|
-
const {
|
|
502
|
-
let buf =
|
|
503
|
-
if (isString(key)) {
|
|
504
|
-
buf += "key=" + toAttrStringLit(key) + ">";
|
|
505
|
-
} else {
|
|
506
|
-
buf += 'computed="' + rc.mcs.gen(show, rc.fcCtx?.scopeId) + '">';
|
|
507
|
-
}
|
|
507
|
+
const { value } = show[$signal];
|
|
508
|
+
let buf = renderSignal(rc, show, "toggle", false).slice(0, -1) + renderViewTransitionAttr(viewTransition) + ">";
|
|
508
509
|
if (!value) {
|
|
509
510
|
buf += "<template m-slot>";
|
|
510
511
|
}
|
|
@@ -520,19 +521,14 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
520
521
|
}
|
|
521
522
|
// `<switch>` element
|
|
522
523
|
case "switch": {
|
|
523
|
-
const { value: valueProp, children } = props;
|
|
524
|
+
const { value: valueProp, viewTransition, children } = props;
|
|
524
525
|
if (children !== void 0) {
|
|
525
526
|
let slots = Array.isArray(children) ? isVNode(children) ? [children] : children : [children];
|
|
526
|
-
let
|
|
527
|
+
let signalHtml;
|
|
527
528
|
let toSlotName;
|
|
528
529
|
if (isSignal(valueProp)) {
|
|
529
|
-
const {
|
|
530
|
-
|
|
531
|
-
if (isString(key)) {
|
|
532
|
-
stateful += "key=" + toAttrStringLit(key) + ">";
|
|
533
|
-
} else {
|
|
534
|
-
stateful += 'computed="' + rc.mcs.gen(valueProp, rc.fcCtx?.scopeId) + '">';
|
|
535
|
-
}
|
|
530
|
+
const { value } = valueProp[$signal];
|
|
531
|
+
signalHtml = renderSignal(rc, valueProp, "switch", false).slice(0, -1) + renderViewTransitionAttr(viewTransition) + ">";
|
|
536
532
|
rc.flags.runtime |= RENDER_SWITCH;
|
|
537
533
|
toSlotName = String(value);
|
|
538
534
|
} else {
|
|
@@ -553,15 +549,15 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
553
549
|
namedSlots.push(slot);
|
|
554
550
|
}
|
|
555
551
|
}
|
|
556
|
-
if (
|
|
557
|
-
write(matchedSlot ?
|
|
552
|
+
if (signalHtml) {
|
|
553
|
+
write(matchedSlot ? signalHtml.slice(0, -1) + " match=" + toAttrStringLit(matchedSlot[0]) + ">" : signalHtml);
|
|
558
554
|
}
|
|
559
555
|
if (matchedSlot) {
|
|
560
556
|
await renderNode(rc, matchedSlot[1], true);
|
|
561
557
|
} else if (unnamedSlots.length > 0) {
|
|
562
558
|
await renderChildren(rc, unnamedSlots);
|
|
563
559
|
}
|
|
564
|
-
if (
|
|
560
|
+
if (signalHtml) {
|
|
565
561
|
if (namedSlots.length > 0 || matchedSlot && unnamedSlots.length > 0) {
|
|
566
562
|
write("<template m-slot>");
|
|
567
563
|
await renderChildren(rc, namedSlots);
|
|
@@ -577,22 +573,20 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
577
573
|
}
|
|
578
574
|
// `<component>` element
|
|
579
575
|
case "component": {
|
|
580
|
-
let { placeholder } = props;
|
|
576
|
+
let { placeholder, viewTransition } = props;
|
|
581
577
|
let attrs = "";
|
|
582
578
|
let attrModifiers = "";
|
|
583
579
|
for (const p of ["name", "props", "ref"]) {
|
|
584
580
|
let propValue = props[p];
|
|
585
581
|
let [attr, , attrSignal] = renderAttr(rc, p, propValue);
|
|
586
582
|
if (attrSignal) {
|
|
587
|
-
|
|
588
|
-
attrModifiers += chunk;
|
|
589
|
-
};
|
|
590
|
-
renderSignal({ ...rc, write: write2 }, attrSignal, [p]);
|
|
583
|
+
attrModifiers += renderSignal(rc, attrSignal, [p]);
|
|
591
584
|
rc.flags.runtime |= RENDER_ATTR;
|
|
592
585
|
propValue = attrSignal[$signal].value;
|
|
593
586
|
}
|
|
594
587
|
attrs += attr;
|
|
595
588
|
}
|
|
589
|
+
attrs += renderViewTransitionAttr(viewTransition);
|
|
596
590
|
let buf = "<m-component" + attrs + ">";
|
|
597
591
|
if (placeholder) {
|
|
598
592
|
const write2 = (chunk) => {
|
|
@@ -610,10 +604,9 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
610
604
|
}
|
|
611
605
|
// `<router>` element
|
|
612
606
|
case "router": {
|
|
607
|
+
const { children, viewTransition } = props;
|
|
613
608
|
const { routeFC } = rc;
|
|
614
|
-
|
|
615
|
-
const status = routeFC ? 200 : 404;
|
|
616
|
-
write('<m-router status="' + status + '">');
|
|
609
|
+
write('<m-router status="' + (routeFC ? 200 : 404) + '"' + renderViewTransitionAttr(viewTransition) + ">");
|
|
617
610
|
if (routeFC) {
|
|
618
611
|
await renderFC(rc, routeFC instanceof Promise ? (await routeFC).default : routeFC, {});
|
|
619
612
|
}
|
|
@@ -656,10 +649,7 @@ async function renderNode(rc, node, stripSlotProp) {
|
|
|
656
649
|
write(addonHtml);
|
|
657
650
|
}
|
|
658
651
|
if (signalValue) {
|
|
659
|
-
|
|
660
|
-
attrModifiers += chunk;
|
|
661
|
-
};
|
|
662
|
-
renderSignal({ ...rc, write: write2 }, signalValue, [binding ? propName.slice(1) : propName]);
|
|
652
|
+
attrModifiers += renderSignal(rc, signalValue, [binding ? propName.slice(1) : propName]);
|
|
663
653
|
rc.flags.runtime |= RENDER_ATTR;
|
|
664
654
|
}
|
|
665
655
|
buffer += attr;
|
|
@@ -826,6 +816,14 @@ function renderAttr(rc, attrName, attrValue, stripSlotProp) {
|
|
|
826
816
|
}
|
|
827
817
|
return [attr, addonHtml, signalValue, binding];
|
|
828
818
|
}
|
|
819
|
+
function renderViewTransitionAttr(viewTransition) {
|
|
820
|
+
if (viewTransition === true || viewTransition === "") {
|
|
821
|
+
return " vt";
|
|
822
|
+
} else if (isString(viewTransition)) {
|
|
823
|
+
return " style=" + toAttrStringLit("view-transition-name:" + viewTransition) + " vt";
|
|
824
|
+
}
|
|
825
|
+
return "";
|
|
826
|
+
}
|
|
829
827
|
async function renderFC(rc, fc, props, eager) {
|
|
830
828
|
const { write } = rc;
|
|
831
829
|
const { children } = props;
|
|
@@ -912,17 +910,14 @@ async function renderFC(rc, fc, props, eager) {
|
|
|
912
910
|
}
|
|
913
911
|
}
|
|
914
912
|
}
|
|
915
|
-
function renderSignal(rc, signal, mode,
|
|
916
|
-
const { scope, key } = signal[$signal];
|
|
913
|
+
function renderSignal(rc, signal, mode, close) {
|
|
914
|
+
const { scope, key, value } = signal[$signal];
|
|
917
915
|
let buffer = "<m-signal";
|
|
918
916
|
if (mode) {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
buffer += mode;
|
|
922
|
-
} else {
|
|
923
|
-
buffer += "[" + mode[0] + "]";
|
|
917
|
+
if (Array.isArray(mode)) {
|
|
918
|
+
mode = "[" + mode[0] + "]";
|
|
924
919
|
}
|
|
925
|
-
buffer += '"';
|
|
920
|
+
buffer += ' mode="' + mode + '"';
|
|
926
921
|
}
|
|
927
922
|
buffer += ' scope="' + scope + '"';
|
|
928
923
|
if (isString(key)) {
|
|
@@ -930,9 +925,26 @@ function renderSignal(rc, signal, mode, content, html2) {
|
|
|
930
925
|
} else {
|
|
931
926
|
buffer += ' computed="' + rc.mcs.gen(signal, rc.fcCtx?.scopeId) + '"';
|
|
932
927
|
}
|
|
933
|
-
|
|
928
|
+
buffer += ">";
|
|
929
|
+
if (!mode || mode === "html") {
|
|
930
|
+
let text;
|
|
931
|
+
switch (typeof value) {
|
|
932
|
+
case "string":
|
|
933
|
+
text = value;
|
|
934
|
+
break;
|
|
935
|
+
case "number":
|
|
936
|
+
case "bigint": {
|
|
937
|
+
text = String(value);
|
|
938
|
+
break;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
if (text) {
|
|
942
|
+
buffer += !mode ? escapeHTML(text) : text;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return buffer + (close !== false ? "</m-signal>" : "");
|
|
934
946
|
}
|
|
935
|
-
var
|
|
947
|
+
var collectDep;
|
|
936
948
|
function Signal(scope, key, value) {
|
|
937
949
|
const signal = { scope, key, value };
|
|
938
950
|
return new Proxy(new NullProtoObj(), {
|
|
@@ -971,9 +983,9 @@ function createSignals(scopeId, appSignals, context = new NullProtoObj(), reques
|
|
|
971
983
|
});
|
|
972
984
|
const computed = (compute) => {
|
|
973
985
|
const deps = /* @__PURE__ */ new Set();
|
|
974
|
-
|
|
986
|
+
collectDep = (scopeId2, key) => deps.add(scopeId2 + ":" + key);
|
|
975
987
|
const value = compute.call(thisProxy);
|
|
976
|
-
|
|
988
|
+
collectDep = void 0;
|
|
977
989
|
return Signal(scopeId, { compute, deps }, value);
|
|
978
990
|
};
|
|
979
991
|
const markEffect = (effect) => {
|
|
@@ -1017,7 +1029,7 @@ function createSignals(scopeId, appSignals, context = new NullProtoObj(), reques
|
|
|
1017
1029
|
return mark;
|
|
1018
1030
|
case "url":
|
|
1019
1031
|
if (scopeId === 0) {
|
|
1020
|
-
|
|
1032
|
+
collectDep?.(0, key);
|
|
1021
1033
|
return request ? request.URL ?? (request.URL = new URL(request.url)) : void 0;
|
|
1022
1034
|
}
|
|
1023
1035
|
// fallthrough
|
|
@@ -1029,8 +1041,8 @@ function createSignals(scopeId, appSignals, context = new NullProtoObj(), reques
|
|
|
1029
1041
|
if (value === void 0 && !Reflect.has(target, key)) {
|
|
1030
1042
|
Reflect.set(target, key, void 0, receiver);
|
|
1031
1043
|
}
|
|
1032
|
-
if (
|
|
1033
|
-
|
|
1044
|
+
if (collectDep) {
|
|
1045
|
+
collectDep(scopeId, key);
|
|
1034
1046
|
return value;
|
|
1035
1047
|
}
|
|
1036
1048
|
let signal = signals.get(key);
|
package/package.json
CHANGED
package/types/html.d.ts
CHANGED
package/types/mono.d.ts
CHANGED
|
@@ -24,10 +24,10 @@ export interface BaseCSSProperties extends CSS.Properties<string | number> {
|
|
|
24
24
|
export interface AtRuleCSSProperties {
|
|
25
25
|
[key: `@container${" " | "("}${string}`]: BaseCSSProperties;
|
|
26
26
|
[key: `@media${" " | "("}${string}`]: BaseCSSProperties;
|
|
27
|
+
[key: `@supports${" " | "("}${string}`]: BaseCSSProperties;
|
|
27
28
|
[key: `@keyframes ${string}`]: {
|
|
28
29
|
[key in "from" | "to" | `${D100}%`]?: BaseCSSProperties;
|
|
29
30
|
};
|
|
30
|
-
[key: `@supports${" " | "("}${string}`]: BaseCSSProperties;
|
|
31
31
|
"@view-transition"?: {
|
|
32
32
|
/**
|
|
33
33
|
* Specifies the effect this at-rule will have on the document's view transition behavior.
|
|
@@ -118,6 +118,7 @@ export interface Elements {
|
|
|
118
118
|
toggle: BaseAttributes & {
|
|
119
119
|
show?: any;
|
|
120
120
|
hidden?: any;
|
|
121
|
+
viewTransition?: string | boolean;
|
|
121
122
|
};
|
|
122
123
|
/**
|
|
123
124
|
* The `switch` element is a built-in element that chooses one of its children based on the `slot` attribute to display.
|
|
@@ -125,6 +126,7 @@ export interface Elements {
|
|
|
125
126
|
*/
|
|
126
127
|
switch: BaseAttributes & {
|
|
127
128
|
value?: string | number | boolean | null;
|
|
129
|
+
viewTransition?: string | boolean;
|
|
128
130
|
};
|
|
129
131
|
/**
|
|
130
132
|
* The `component` element is a built-in element that is used to load components lazily,
|
|
@@ -134,6 +136,7 @@ export interface Elements {
|
|
|
134
136
|
name?: string;
|
|
135
137
|
props?: Record<string, unknown>;
|
|
136
138
|
ref?: ComponentElement | ((el: ComponentElement) => void);
|
|
139
|
+
viewTransition?: string | boolean;
|
|
137
140
|
};
|
|
138
141
|
/**
|
|
139
142
|
* The `router` element is a built-in element that implements client-side routing.
|
|
@@ -144,6 +147,7 @@ export interface Elements {
|
|
|
144
147
|
*/
|
|
145
148
|
base?: string;
|
|
146
149
|
ref?: RouterElement | ((el: RouterElement) => void);
|
|
150
|
+
viewTransition?: string | boolean;
|
|
147
151
|
};
|
|
148
152
|
}
|
|
149
153
|
|