@neuralfog/elemix-storybook 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +88 -13
- package/dist/index.js +1 -1
- package/dist/src/elemixStory.d.ts +1 -1
- package/package.json +18 -16
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 brownhounds
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,19 +1,94 @@
|
|
|
1
|
-
|
|
1
|
+
# ⚡ Elemix Storybook
|
|
2
|
+
|
|
3
|
+
Storybook integration for [Elemix](https://github.com/neuralfog/elemix). Renders elemix templates directly inside Storybook's web-components framework via a decorator, and provides typed helpers (`ElemixMeta`, `ElemixStory`) for writing stories with full TypeScript support.
|
|
4
|
+
|
|
5
|
+
## Why?
|
|
6
|
+
|
|
7
|
+
`@storybook/web-components-vite` ships with a lit-html based renderer. Elemix uses its own renderer (`@neuralfog/elemix-renderer`) and a custom-element lifecycle that lit-html can't drive. This package bridges the two — Storybook keeps managing the UI shell, args panel, addons, and HMR, while elemix owns what actually mounts into the story canvas.
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install --save-dev @neuralfog/elemix-storybook
|
|
4
13
|
```
|
|
5
|
-
|
|
14
|
+
|
|
15
|
+
## Setup
|
|
16
|
+
|
|
17
|
+
Register the decorator in `.storybook/preview.ts`:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import type { Preview } from '@storybook/web-components-vite';
|
|
21
|
+
import { elemixDecorator } from '@neuralfog/elemix-storybook';
|
|
22
|
+
|
|
23
|
+
const preview: Preview = {
|
|
24
|
+
decorators: [elemixDecorator],
|
|
25
|
+
parameters: {
|
|
26
|
+
controls: {
|
|
27
|
+
matchers: {
|
|
28
|
+
color: /(background|color)$/i,
|
|
29
|
+
date: /Date$/i,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default preview;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The decorator clears `#storybook-root`, mounts a fresh `<div data-elemix-root>` host, and pipes the story's returned template through `render()` from `@neuralfog/elemix-renderer`.
|
|
39
|
+
|
|
40
|
+
## Writing a Story
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { html } from '@neuralfog/elemix';
|
|
44
|
+
import type { ElemixMeta, ElemixStory } from '@neuralfog/elemix-storybook';
|
|
45
|
+
|
|
46
|
+
type HelloArgs = { text: string };
|
|
47
|
+
|
|
48
|
+
const meta: ElemixMeta<HelloArgs> = {
|
|
49
|
+
title: 'Test/Hello',
|
|
50
|
+
args: { text: 'There' },
|
|
51
|
+
argTypes: { text: { control: 'text' } },
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default meta;
|
|
55
|
+
|
|
56
|
+
export const Default: ElemixStory<HelloArgs> = {
|
|
57
|
+
render: (args) => html`<div>Hello ${args.text}</div>`,
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`ElemixStory.render` returns an elemix `HtmlTemplate` directly — no need to wrap or unwrap. The decorator picks it up and renders it via elemix-renderer.
|
|
62
|
+
|
|
63
|
+
## Per-Story Hooks
|
|
64
|
+
|
|
65
|
+
Stories can opt into setup / teardown / render hooks via `parameters.elemix`:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const meta: ElemixMeta<HelloArgs> = {
|
|
69
|
+
title: 'Test/Hello',
|
|
70
|
+
parameters: {
|
|
71
|
+
elemix: {
|
|
72
|
+
setup: (ctx) => {
|
|
73
|
+
return () => {};
|
|
74
|
+
},
|
|
75
|
+
beforeRender: (ctx) => {},
|
|
76
|
+
afterRender: (ctx) => {},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
};
|
|
6
80
|
```
|
|
7
81
|
|
|
8
|
-
|
|
82
|
+
| Hook | When it runs |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `setup` | Once per story id, before the first render. May return a teardown function. |
|
|
85
|
+
| `beforeRender` | Before every render (initial + every args change). |
|
|
86
|
+
| `afterRender` | After every render. |
|
|
9
87
|
|
|
10
|
-
##
|
|
88
|
+
## Notes
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx storybook@latest init --type web_components
|
|
92
|
+
```
|
|
11
93
|
|
|
12
|
-
|
|
13
|
-
- [] Cant have globals in stories it will mess up concurrent runs of stories:
|
|
14
|
-
- [] Application context is static class, needs changing
|
|
15
|
-
- [] Application context inject in stories somehow
|
|
16
|
-
- [] Signals are also global states that may be used by multiple components
|
|
17
|
-
- [] Need to find a way to stub signals per story, this is not easy, it is
|
|
18
|
-
but ergonomics matter, at moment signal are injected at the decorator stage :thinking:
|
|
19
|
-
- [] Write helpers in testing package to pierce shadow dom and wait for element
|
|
94
|
+
The Storybook wizard does not bootstrap TypeScript on its own, so create `tsconfig.json` before running init.
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var R={},d={},O;function se(){if(O)return d;O=1;const m="₥";var u=(o=>(o[o.EVENT=0]="EVENT",o[o.PROP=1]="PROP",o[o.MODEL=2]="MODEL",o[o.STD=3]="STD",o[o.REF=4]="REF",o[o.EMIT=5]="EMIT",o[o.BIND_ATTRS=6]="BIND_ATTRS",o[o.BIND_EVENTS=7]="BIND_EVENTS",o[o.DIRECT_CLASS=8]="DIRECT_CLASS",o))(u||{});const p=o=>{const f=new RegExp(`${m}(\\d+)`),g=o.match(f);if(!g)throw new Error("Unable to extract index from hole comment");return Number(g[1])},c=o=>`<!--${m}${o}-->`,l=o=>o.replace(/<([a-zA-Z][^\s/>]*)([\s\S]*?)\/>/g,(f,g,S)=>g.includes("-")?`<${g}${S}></${g}>`:f),T=o=>o.replace(/(\S+)=((<!--[\s\S]*?-->)|([^\s">]+))/g,'$1="$2"'),y=o=>o.replace(/([A-Z])/g,f=>"-"+f.toLowerCase()),N=(o,f)=>Array.from(new Set([...o.split(" "),...f.split(" ")].filter(Boolean))).join(" ").trim();return d.Attributes=u,d.TEMPLATE_MARKER_GLYPH=m,d.camelToKebab=y,d.fixAttributeQuotes=T,d.fixSelfClosingTags=l,d.getIndexFromComment=p,d.makeMarkerComment=c,d.mergeClasses=N,d}var $;function ie(){return $||($=1,(function(m){var u=Object.defineProperty,p=(r,e,s)=>e in r?u(r,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):r[e]=s,c=(r,e,s)=>p(r,typeof e!="symbol"?e+"":e,s);Object.defineProperty(m,Symbol.toStringTag,{value:"Module"});const l=se(),T=r=>{const e=r;return e.$cache||(e.$cache={template:new Map}),e.$cache};class y{constructor(e,s){c(this,"key",""),this.strings=e,this.values=s}}class N{constructor(e,s){c(this,"initialClass"),this.node=e,this.definition=s,this.initialClass=e.getAttribute("class")||""}setValue(e){if(e==null||typeof e!="object")return;const{node:s}=this,t=e;for(const[i,n]of Object.entries(t)){const a=l.camelToKebab(i);if(n==null||n===!1){s.removeAttribute(a),this.initialClass.length&&s.setAttribute("class",String(this.initialClass));continue}if(a==="class"){s.setAttribute("class",l.mergeClasses(this.initialClass,String(n)));continue}s.setAttribute(a,String(n))}}}class o{constructor(e,s){this.node=e,this.definition=s}setValue(e){if(e!=null&&typeof e=="object")for(const[s,t]of Object.entries(e))this.node[`on${s}`]=t}}class f{constructor(e,s){c(this,"initialClass"),this.node=e,this.definition=s,this.initialClass=e.getAttribute("class")||""}setValue(e){const{node:s}=this;if(e==null&&this.initialClass.length&&s.setAttribute("class",String(this.initialClass)),typeof e=="string"&&s.setAttribute("class",l.mergeClasses(this.initialClass,String(e))),typeof e=="object"){const t=Object.entries(e).filter(([,i])=>!!i).map(([i])=>i).join(" ");s.setAttribute("class",l.mergeClasses(this.initialClass,t))}}}class g{constructor(e,s){this.node=e,this.definition=s}setValue(e){if(e===void 0)return;const{name:s}=this.definition,t=this.node;t.$emits&&t.$emits.set(s.slice(s.indexOf(":")+1),e)}}class S{constructor(e,s){this.node=e,this.definition=s}setValue(e){if(e===void 0)return;const s=this.definition.name.slice(1);this.node[`on${s}`]=e}}class _{constructor(e,s){this.node=e,this.definition=s}setValue(e){if(e===void 0)return;const s=t=>{e.value=t.target.value};this.node.oninput||(this.node.value=e.value,this.node.oninput=s)}}class j{constructor(e,s){this.node=e,this.definition=s}setValue(e){const s=this.definition.name.slice(1),t=this.node;t.$props&&t.$props.set(s,e)}}class P{constructor(e,s){this.node=e,this.definition=s}setValue(e){e!==void 0&&(e.value=this.node)}}let x=class{constructor(r,e){this.node=r,this.definition=e}setValue(r){r!==void 0&&this.node.setAttribute(this.definition.name,String(r))}};const F=(r,e)=>{const s=/(\S+)(?==(?:["']?)$)/,t=r.match(s);if(t){const i={index:e,name:t[1],value:l.makeMarkerComment(e),virtual:!1,type:l.Attributes.STD};switch(t[1][0]){case"@":return t[1].startsWith("@emits:")?(i.type=l.Attributes.EMIT,i.virtual=!0,i):(i.type=l.Attributes.EVENT,i.virtual=!0,i);case":":return t[1].endsWith(":ref")?(i.type=l.Attributes.REF,i.virtual=!0,i):(i.type=l.Attributes.PROP,i.virtual=!0,i);case"~":return t[1].startsWith("~model")&&(i.type=l.Attributes.MODEL,i.virtual=!0),i;case".":return t[1].startsWith(".bind-attrs")?(i.type=l.Attributes.BIND_ATTRS,i.virtual=!0,i):t[1].startsWith(".bind-events")?(i.type=l.Attributes.BIND_EVENTS,i.virtual=!0,i):(t[1].startsWith(".class")&&(i.type=l.Attributes.DIRECT_CLASS,i.virtual=!0),i);default:return i}}},K=(r,e)=>{const s=r.querySelector(W(e.name,e.value));if(s)switch(e.virtual&&s.removeAttribute(e.name),e.type){case l.Attributes.EVENT:return new S(s,e);case l.Attributes.PROP:return new j(s,e);case l.Attributes.MODEL:return new _(s,e);case l.Attributes.REF:return new P(s,e);case l.Attributes.EMIT:return new g(s,e);case l.Attributes.BIND_ATTRS:return new N(s,e);case l.Attributes.DIRECT_CLASS:return new f(s,e);case l.Attributes.BIND_EVENTS:return new o(s,e);default:return new x(s,e)}},B=r=>{let e="";for(let s=0;s<r.length;s++){const t=r.charAt(s),i=t.charCodeAt(0);i>=48&&i<=57||i>=65&&i<=90||i>=97&&i<=122||t==="-"||t==="_"?e+=t:e+=`\\${t}`}return e},W=(r,e)=>`[${B(r)}='${e}']`,q=(r,e)=>{const s=r.length,t=e.length,i=Object.create(null);let n,a,h;for(n=0;n<s;n++)a=r[n].key,i[a]=n;const b=new Array(t),v=[],A=[],k=Object.create(null);for(n=0;n<t;n++){const E=e[n].key;k[E]=!0;const M=i[E];M===void 0?b[n]=-1:(b[n]=M,v.push(M),A.push(n))}const L=G(v),C=new Array(t);for(n=0;n<t;n++)C[n]=!1;const te=L.length;for(n=0;n<te;n++)C[A[L[n]]]=!0;const I=[],D=[],V=[];for(n=0;n<s;n++)h=r[n].key,k[h]!==!0&&I.push({key:h});for(n=0;n<t;n++){h=e[n].key;const E=n+1<t?e[n+1].key:void 0;b[n]===-1?D.push({key:h,value:e[n],beforeKey:E}):C[n]||V.push({key:h,beforeKey:E})}return{deletes:I,inserts:D,moves:V}},G=r=>{const e=r.length,s=new Array(e),t=[];let i,n,a,h;for(i=0;i<e;i++){for(n=0,a=t.length;n<a;)h=n+a>>>1,r[t[h]]<r[i]?n=h+1:a=h;n===t.length?t.push(i):t[n]=i,s[i]=n>0?t[n-1]:-1}const b=t.length,v=new Array(b);let A=t[b-1];for(i=b-1;i>=0;i--)v[i]=A,A=s[A];return v};class Q{constructor(e){c(this,"cache",{listTemplate:new Map,listNodes:new Map,listHtmlTemplate:[]}),this.commentNode=e}renderListElement(e,s){if(!this.commentNode)throw new Error("renderList method needs to accept instance of HTMLElement");if(!e.key)throw new Error("use repeat directive when rendering the lists");let t=this.cache.listTemplate.get(e.key);return t||(t=new w(e),this.cache.listTemplate.set(e.key,t),t.mountListElement(this.commentNode,e.key,e.values,this.cache,s)),t}renderAllItems(e){const s=e.length;for(let t=0;t<s;t++)this.renderListElement(e[t]).update(e[t].values)}emptyList(){for(const[,e]of this.cache.listNodes)e.remove();this.cache.listTemplate.clear(),this.cache.listNodes.clear()}deleteNodes(e){const s=e.length;for(let t=s-1;t>=0;t--){const i=this.cache.listNodes.get(e[t].key);i&&i.remove(),this.cache.listNodes.delete(e[t].key),this.cache.listTemplate.delete(e[t].key)}}moveNodes(e){const s=e.length;for(let t=s-1;t>=0;t--){const i=this.cache.listNodes.get(e[t].key),n=this.cache.listNodes.get(e[t].beforeKey);i&&n&&n?.before(i),!n&&i&&this.commentNode.before(i)}}insertNodes(e){const s=e.length;for(let t=s-1;t>=0;t--){const i=this.cache.listNodes.get(e[t].beforeKey);this.renderListElement(e[t].value,i)}}updateAllItems(e){const s=e.length;for(let t=0;t<s;t++){const i=this.cache.listTemplate.get(e[t].key);i?.update(e[t].values)}}render(e){if(!this.cache.listHtmlTemplate.length){this.renderAllItems(e),this.cache.listHtmlTemplate=e;return}if(!e.length){this.emptyList(),this.cache.listHtmlTemplate=e;return}const{deletes:s,inserts:t,moves:i}=q(this.cache.listHtmlTemplate,e);if(s.length===e.length||t.length===e.length){this.emptyList(),this.renderAllItems(e),this.cache.listHtmlTemplate=e;return}s.length&&this.deleteNodes(s),i.length&&this.moveNodes(i),t.length&&this.insertNodes(t),this.updateAllItems(e),this.cache.listHtmlTemplate=e}}class U{constructor(e){c(this,"renderer"),this.commentNode=e,this.renderer=new Q(e)}setValue(e){this.renderer.render(e)}}class Y{constructor(e){c(this,"node",document.createTextNode("")),this.commentNode=e,e.before(this.node)}setValue(e){const s=e!=null?String(e):"";this.node.textContent!==s&&(this.node.textContent=s)}}class z{constructor(e){c(this,"cache",{nodes:[]}),this.commentNode=e}removeNodes(){if(!this.cache.nodes.length)return;const e=this.cache.nodes.length;for(let s=0;s<e;s++)this.cache.nodes[s].remove();this.cache.nodes=[]}render(e){this.cache.strings!==e.strings&&(this.cache.fragment=void 0,this.removeNodes()),this.cache.fragment||(this.cache.fragment=new w(e),this.cache.strings=e.strings,this.cache.nodes=this.cache.fragment.mountTemplate(this.commentNode,e.values)),this.cache.fragment.update(e.values)}}class Z{constructor(e){c(this,"renderer"),this.commentNode=e,this.renderer=new z(e)}setValue(e){this.renderer.render(e)}}const J=(r,e)=>Array.isArray(r)?new U(e):r instanceof y?new Z(e):new Y(e);class w{constructor(e){c(this,"holes",new Map),c(this,"htmlString",""),c(this,"attributeMap",[]),this.parse(e.strings)}parse(e){const s=e.length;for(let t=0;t<s;t++)if(this.htmlString+=e[t],t<e.length-1){const i=F(this.htmlString,t);i&&this.attributeMap.push(i),this.htmlString+=l.makeMarkerComment(t)}this.htmlString=l.fixSelfClosingTags(this.htmlString),this.htmlString=l.fixAttributeQuotes(this.htmlString)}initFragment(){const e=document.createElement("template");return e.innerHTML=this.htmlString,e.content}hydrateAttributes(e){const s=this.attributeMap.length;for(let t=0;t<s;t++){const i=K(e,this.attributeMap[t]);i&&this.holes.set(this.attributeMap[t].index,i)}return e}hydrateTemplateHoles(e,s){var t;const i=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT,null);for(;i.nextNode();){const n=i.currentNode;if((t=n.nodeValue)!=null&&t.includes(l.TEMPLATE_MARKER_GLYPH)){const a=l.getIndexFromComment(n.nodeValue),h=J(s[a],n);this.holes.set(a,h)}}return e}mount(e,s){const t=this.initFragment();this.hydrateTemplateHoles(t,s),this.hydrateAttributes(t),e.appendChild(t)}mountTemplate(e,s){const t=this.initFragment();this.hydrateTemplateHoles(t,s),this.hydrateAttributes(t);const i=Array.from(t.childNodes);return e.before(t),i}mountListElement(e,s,t,i,n){const a=this.initFragment();this.hydrateTemplateHoles(a,t),this.hydrateAttributes(a),n?n.before(a):e.before(a);const h=n?n.previousSibling:e.previousSibling;h&&i&&i.listNodes.set(s,h)}update(e){for(const[s,t]of this.holes)t.setValue(e[s])}}const X=(r,...e)=>new y(r,e),ee=(r,e)=>{if(!e)throw new Error("render method needs to accept instance of HTMLElement");const s=T(e);let t=s.template.get(r.strings);t||(t=new w(r),s.template.set(r.strings,t),t.mount(e,r.values)),t.update(r.values)};m.html=X,m.render=ee})(R)),R}var ne=ie();const H=new Map,re=(m,u)=>{const p=u.parameters?.elemix??{};if(p.setup&&!H.has(u.id)){const y=p.setup(u);H.set(u.id,y)}const c=document.createElement("div");c.setAttribute("data-elemix-root","");const l=document.getElementById("storybook-root")??document.body;l.innerHTML="",l.appendChild(c),p.beforeRender?.(u);const T=m(u);return ne.render(T,c),p.afterRender?.(u),c};exports.elemixDecorator=re;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@neuralfog/elemix/render");var t=new Map,n=(n,r)=>{let i=r.parameters?.elemix??{};if(i.setup&&!t.has(r.id)){let e=i.setup(r);t.set(r.id,e)}let a=document.createElement(`div`);a.setAttribute(`data-elemix-root`,``);let o=document.getElementById(`storybook-root`)??document.body;return o.innerHTML=``,o.appendChild(a),i.beforeRender?.(r),(0,e.render)(n(r),a),i.afterRender?.(r),a};exports.elemixDecorator=n;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HtmlTemplate } from '@neuralfog/elemix
|
|
1
|
+
import type { HtmlTemplate } from '@neuralfog/elemix/render';
|
|
2
2
|
import type { StoryContext, Parameters, Meta } from '@storybook/web-components-vite';
|
|
3
3
|
export type ElemixTeardown = () => void;
|
|
4
4
|
export type ElemixParams<TArgs = Record<string, never>> = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuralfog/elemix-storybook",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "brownhounds",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,27 +18,29 @@
|
|
|
18
18
|
"build-storybook": "storybook build",
|
|
19
19
|
"lint": "tsc --noEmit && biome format && biome lint",
|
|
20
20
|
"lint:fix": "biome format --write . && biome lint --write . && tsc --noEmit",
|
|
21
|
-
"test": "vitest",
|
|
21
|
+
"test": "vitest run",
|
|
22
22
|
"test:watch": "vitest --watch",
|
|
23
23
|
"test:coverage": "vitest run --coverage",
|
|
24
24
|
"release": "npm run clean && npm run build && npm publish --access public"
|
|
25
25
|
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@neuralfog/elemix": "0.5.0"
|
|
28
|
+
},
|
|
26
29
|
"devDependencies": {
|
|
27
|
-
"@chromatic-com/storybook": "5.
|
|
30
|
+
"@chromatic-com/storybook": "5.2.1",
|
|
28
31
|
"@neuralfog/biome-config": "0.1.2",
|
|
29
|
-
"@neuralfog/elemix": "0.
|
|
30
|
-
"@neuralfog/elemix-renderer": "0.1.8",
|
|
32
|
+
"@neuralfog/elemix": "0.5.0",
|
|
31
33
|
"@neuralfog/ts-config": "0.1.2",
|
|
32
|
-
"@storybook/addon-a11y": "10.
|
|
33
|
-
"@storybook/addon-docs": "10.
|
|
34
|
-
"@storybook/addon-vitest": "10.
|
|
35
|
-
"@storybook/web-components-vite": "10.
|
|
36
|
-
"@types/node": "25.1
|
|
37
|
-
"@vitest/browser-playwright": "4.
|
|
38
|
-
"@vitest/coverage-v8": "4.
|
|
39
|
-
"playwright": "1.
|
|
40
|
-
"storybook": "10.
|
|
41
|
-
"typescript": "
|
|
42
|
-
"vitest": "4.
|
|
34
|
+
"@storybook/addon-a11y": "10.4.1",
|
|
35
|
+
"@storybook/addon-docs": "10.4.1",
|
|
36
|
+
"@storybook/addon-vitest": "10.4.1",
|
|
37
|
+
"@storybook/web-components-vite": "10.4.1",
|
|
38
|
+
"@types/node": "25.9.1",
|
|
39
|
+
"@vitest/browser-playwright": "4.1.8",
|
|
40
|
+
"@vitest/coverage-v8": "4.1.8",
|
|
41
|
+
"playwright": "1.60.0",
|
|
42
|
+
"storybook": "10.4.1",
|
|
43
|
+
"typescript": "6.0.3",
|
|
44
|
+
"vitest": "4.1.8"
|
|
43
45
|
}
|
|
44
46
|
}
|