@lifeonlars/prime-yggdrasil 0.2.0 → 0.2.2

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.
@@ -388,6 +388,22 @@
388
388
  .p-splitbutton {
389
389
  border-radius: var(--radius-md);
390
390
  }
391
+
392
+ /* SplitButton border radius overrides for grouped buttons */
393
+ .p-splitbutton > .p-button {
394
+ border-radius: 0;
395
+ }
396
+
397
+ .p-splitbutton > .p-button:first-child {
398
+ border-top-left-radius: var(--radius-md);
399
+ border-bottom-left-radius: var(--radius-md);
400
+ }
401
+
402
+ .p-splitbutton > .p-button:last-child {
403
+ border-top-right-radius: var(--radius-md);
404
+ border-bottom-right-radius: var(--radius-md);
405
+ }
406
+
391
407
  .p-splitbutton.p-button-outlined > .p-button {
392
408
  background-color: transparent;
393
409
  color: var(--text-state-interactive);
@@ -195,16 +195,30 @@
195
195
  display: inline-flex;
196
196
  user-select: none;
197
197
  vertical-align: bottom;
198
- }
199
- .p-checkbox {
200
198
  width: 22px;
201
199
  height: 22px;
202
200
  }
201
+
203
202
  .p-checkbox .p-checkbox-input {
203
+ appearance: none;
204
+ position: absolute;
205
+ top: 0;
206
+ left: 0;
207
+ width: 100%;
208
+ height: 100%;
209
+ padding: 0;
210
+ margin: 0;
211
+ opacity: 0;
212
+ z-index: 1;
213
+ outline: 0 none;
204
214
  border: 2px solid var(--border-neutral-default);
205
215
  border-radius: var(--radius-md);
206
216
  }
217
+
207
218
  .p-checkbox .p-checkbox-box {
219
+ display: flex;
220
+ justify-content: center;
221
+ align-items: center;
208
222
  border: 2px solid var(--border-neutral-default);
209
223
  background: var(--surface-neutral-primary);
210
224
  width: 22px;
@@ -214,30 +228,13 @@
214
228
  transition: background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
215
229
  outline-color: transparent;
216
230
  }
231
+
217
232
  .p-checkbox .p-checkbox-box .p-checkbox-icon {
218
233
  transition-duration: 0.2s;
219
234
  color: var(--text-onsurface-onbrand);
220
235
  font-size: 14px;
221
236
  }
222
- .p-checkbox .p-checkbox-box .p-checkbox-icon.p-icon {
223
- width: 14px;
224
- height: 14px;
225
- }
226
- .p-checkbox .p-checkbox-box {
227
- border: 2px solid var(--border-neutral-default);
228
- background: var(--surface-neutral-primary);
229
- width: 22px;
230
- height: 22px;
231
- color: var(--text-neutral-default);
232
- border-radius: var(--radius-md);
233
- transition: background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
234
- outline-color: transparent;
235
- }
236
- .p-checkbox .p-checkbox-box .p-checkbox-icon {
237
- transition-duration: 0.2s;
238
- color: var(--text-onsurface-onbrand);
239
- font-size: 14px;
240
- }
237
+
241
238
  .p-checkbox .p-checkbox-box .p-checkbox-icon.p-icon {
242
239
  width: 14px;
243
240
  height: 14px;
@@ -275,23 +272,13 @@
275
272
  .p-checkbox.p-variant-filled:not(.p-disabled):has(.p-checkbox-input:hover).p-highlight .p-checkbox-box {
276
273
  background: var(--surface-brand-secondary);
277
274
  }
278
- .p-checkbox {
279
- position: relative;
280
- display: inline-flex;
281
- user-select: none;
282
- vertical-align: bottom;
283
- }
275
+
276
+ /* Radio Button */
284
277
  .p-radiobutton {
285
278
  position: relative;
286
279
  display: inline-flex;
287
280
  user-select: none;
288
281
  vertical-align: bottom;
289
- }
290
- .p-radiobutton.p-highlight .p-radiobutton-icon {
291
- transform: translateZ(0) scale(1, 1);
292
- visibility: visible;
293
- }
294
- .p-radiobutton {
295
282
  width: 22px;
296
283
  height: 22px;
297
284
  }
@@ -311,6 +298,9 @@
311
298
  border-radius: var(--radius-full);
312
299
  }
313
300
  .p-radiobutton .p-radiobutton-box {
301
+ display: flex;
302
+ justify-content: center;
303
+ align-items: center;
314
304
  border: 2px solid var(--border-neutral-default);
315
305
  background: var(--surface-neutral-primary);
316
306
  width: 22px;
@@ -323,6 +313,7 @@
323
313
  .p-radiobutton .p-radiobutton-box .p-radiobutton-icon {
324
314
  width: 12px;
325
315
  height: 12px;
316
+ border-radius: 50%;
326
317
  transition-duration: 0.2s;
327
318
  background-color: var(--surface-neutral-primary);
328
319
  }
@@ -475,6 +466,22 @@
475
466
  .p-selectbutton.p-invalid > .p-button {
476
467
  border-color: var(--severity-danger-text);
477
468
  }
469
+
470
+ /* SelectButton border radius overrides for grouped buttons */
471
+ .p-selectbutton .p-button {
472
+ border-radius: 0;
473
+ }
474
+
475
+ .p-selectbutton .p-button:first-child {
476
+ border-top-left-radius: var(--radius-md);
477
+ border-bottom-left-radius: var(--radius-md);
478
+ }
479
+
480
+ .p-selectbutton .p-button:last-child {
481
+ border-top-right-radius: var(--radius-md);
482
+ border-bottom-right-radius: var(--radius-md);
483
+ }
484
+
478
485
  .p-selectbutton > .p-button,
479
486
  .p-dropdown {
480
487
  display: inline-flex;
@@ -747,6 +754,116 @@
747
754
  .p-multiselect.p-invalid.p-component {
748
755
  border-color: var(--severity-danger-text);
749
756
  }
757
+
758
+ /* MultiSelect Panel */
759
+ .p-multiselect-panel {
760
+ background: var(--surface-neutral-primary);
761
+ color: var(--text-neutral-default);
762
+ border: 0 none;
763
+ border-radius: var(--radius-md);
764
+ box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
765
+ }
766
+
767
+ .p-multiselect-panel .p-multiselect-header {
768
+ padding: 0.75rem 1.25rem;
769
+ border-bottom: 1px solid var(--border-neutral-subdued);
770
+ color: var(--text-neutral-loud);
771
+ background: var(--surface-neutral-secondary);
772
+ margin: 0;
773
+ border-top-right-radius: var(--radius-md);
774
+ border-top-left-radius: var(--radius-md);
775
+ }
776
+
777
+ .p-multiselect-panel .p-multiselect-header .p-multiselect-filter-container .p-inputtext {
778
+ padding-right: 1.75rem;
779
+ }
780
+
781
+ .p-multiselect-panel .p-multiselect-header .p-multiselect-filter-container .p-multiselect-filter-icon {
782
+ right: 0.75rem;
783
+ color: var(--text-neutral-subdued);
784
+ }
785
+
786
+ .p-multiselect-panel .p-multiselect-header .p-checkbox {
787
+ margin-right: 0.5rem;
788
+ }
789
+
790
+ .p-multiselect-panel .p-multiselect-header .p-multiselect-close {
791
+ margin-left: 0.5rem;
792
+ width: 2rem;
793
+ height: 2rem;
794
+ color: var(--text-neutral-subdued);
795
+ border: 0 none;
796
+ background: transparent;
797
+ border-radius: var(--radius-full);
798
+ transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
799
+ }
800
+
801
+ .p-multiselect-panel .p-multiselect-header .p-multiselect-close:enabled:hover {
802
+ color: var(--text-neutral-loud);
803
+ border-color: transparent;
804
+ background: var(--surface-state-hover);
805
+ }
806
+
807
+ .p-multiselect-panel .p-multiselect-header .p-multiselect-close:focus-visible {
808
+ outline: 0 none;
809
+ outline-offset: 0;
810
+ box-shadow: 0 0 0 0.2rem var(--surface-brand-overlay);
811
+ }
812
+
813
+ .p-multiselect-panel .p-multiselect-items {
814
+ padding: 0.75rem 0;
815
+ }
816
+
817
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item {
818
+ margin: 0;
819
+ padding: 0.75rem 1.25rem;
820
+ border: 0 none;
821
+ color: var(--text-neutral-default);
822
+ background: transparent;
823
+ transition: box-shadow 0.2s;
824
+ border-radius: 0;
825
+ }
826
+
827
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item:first-child {
828
+ margin-top: 0;
829
+ }
830
+
831
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item:last-child {
832
+ margin-bottom: 0;
833
+ }
834
+
835
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item.p-highlight {
836
+ color: var(--text-state-interactive);
837
+ background: var(--surface-state-selected);
838
+ }
839
+
840
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item.p-highlight.p-focus {
841
+ background: color-mix(in srgb, var(--surface-brand-primary) 24%, transparent);
842
+ }
843
+
844
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item:not(.p-highlight, .p-disabled).p-focus {
845
+ color: var(--text-neutral-default);
846
+ background: var(--surface-state-hover);
847
+ }
848
+
849
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item .p-checkbox {
850
+ margin-right: 0.5rem;
851
+ }
852
+
853
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-item-group {
854
+ margin: 0;
855
+ padding: 0.75rem 1.25rem;
856
+ color: var(--text-neutral-loud);
857
+ background: var(--surface-neutral-primary);
858
+ font-weight: 700;
859
+ }
860
+
861
+ .p-multiselect-panel .p-multiselect-items .p-multiselect-empty-message {
862
+ padding: 0.75rem 1.25rem;
863
+ color: var(--text-neutral-default);
864
+ background: transparent;
865
+ }
866
+
750
867
  .p-treeselect {
751
868
  background: var(--text-onsurface-onbrand);
752
869
  border: 1px solid var(--border-neutral-subdued);
package/dist/index.cjs CHANGED
@@ -1 +1,6 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e="0.1.0",o={name:"Yggdrasil",version:"0.1.0",tokens:727,coverage:"96%",modes:["light","dark"]};exports.theme=o;exports.version=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const K=require("react"),ee=require("primereact/api");var b={exports:{}},_={};var $;function re(){if($)return _;$=1;var u=Symbol.for("react.transitional.element"),i=Symbol.for("react.fragment");function l(c,o,s){var d=null;if(s!==void 0&&(d=""+s),o.key!==void 0&&(d=""+o.key),"key"in o){s={};for(var m in o)m!=="key"&&(s[m]=o[m])}else s=o;return o=s.ref,{$$typeof:u,type:c,key:d,ref:o!==void 0?o:null,props:s}}return _.Fragment=i,_.jsx=l,_.jsxs=l,_}var E={};var I;function te(){return I||(I=1,process.env.NODE_ENV!=="production"&&(function(){function u(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===H?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case p:return"Fragment";case q:return"Profiler";case W:return"StrictMode";case z:return"Suspense";case G:return"SuspenseList";case B:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case L:return"Portal";case J:return e.displayName||"Context";case U:return(e._context.displayName||"Context")+".Consumer";case V:var r=e.render;return e=e.displayName,e||(e=r.displayName||r.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case X:return r=e.displayName||null,r!==null?r:u(e.type)||"Memo";case T:r=e._payload,e=e._init;try{return u(e(r))}catch{}}return null}function i(e){return""+e}function l(e){try{i(e);var r=!1}catch{r=!0}if(r){r=console;var t=r.error,n=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return t.call(r,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",n),i(e)}}function c(e){if(e===p)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===T)return"<...>";try{var r=u(e);return r?"<"+r+">":"<...>"}catch{return"<...>"}}function o(){var e=k.A;return e===null?null:e.getOwner()}function s(){return Error("react-stack-top-frame")}function d(e){if(w.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return e.key!==void 0}function m(e,r){function t(){h||(h=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",r))}t.isReactWarning=!0,Object.defineProperty(e,"key",{get:t,configurable:!0})}function D(){var e=u(this.type);return x[e]||(x[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function M(e,r,t,n,R,O){var a=t.ref;return e={$$typeof:j,type:e,key:r,props:t,_owner:n},(a!==void 0?a:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:D}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:R}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:O}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function S(e,r,t,n,R,O){var a=r.children;if(a!==void 0)if(n)if(Z(a)){for(n=0;n<a.length;n++)A(a[n]);Object.freeze&&Object.freeze(a)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else A(a);if(w.call(r,"key")){a=u(e);var f=Object.keys(r).filter(function(Q){return Q!=="key"});n=0<f.length?"{key: someKey, "+f.join(": ..., ")+": ...}":"{key: someKey}",Y[a+n]||(f=0<f.length?"{"+f.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
2
+ let props = %s;
3
+ <%s {...props} />
4
+ React keys must be passed directly to JSX without using spread:
5
+ let props = %s;
6
+ <%s key={someKey} {...props} />`,n,a,f,a),Y[a+n]=!0)}if(a=null,t!==void 0&&(l(t),a=""+t),d(r)&&(l(r.key),a=""+r.key),"key"in r){t={};for(var P in r)P!=="key"&&(t[P]=r[P])}else t=r;return a&&m(t,typeof e=="function"?e.displayName||e.name||"Unknown":e),M(e,a,t,o(),R,O)}function A(e){y(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===T&&(e._payload.status==="fulfilled"?y(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function y(e){return typeof e=="object"&&e!==null&&e.$$typeof===j}var v=K,j=Symbol.for("react.transitional.element"),L=Symbol.for("react.portal"),p=Symbol.for("react.fragment"),W=Symbol.for("react.strict_mode"),q=Symbol.for("react.profiler"),U=Symbol.for("react.consumer"),J=Symbol.for("react.context"),V=Symbol.for("react.forward_ref"),z=Symbol.for("react.suspense"),G=Symbol.for("react.suspense_list"),X=Symbol.for("react.memo"),T=Symbol.for("react.lazy"),B=Symbol.for("react.activity"),H=Symbol.for("react.client.reference"),k=v.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,w=Object.prototype.hasOwnProperty,Z=Array.isArray,g=console.createTask?console.createTask:function(){return null};v={react_stack_bottom_frame:function(e){return e()}};var h,x={},N=v.react_stack_bottom_frame.bind(v,s)(),C=g(c(s)),Y={};E.Fragment=p,E.jsx=function(e,r,t){var n=1e4>k.recentlyCreatedOwnerStacks++;return S(e,r,t,!1,n?Error("react-stack-top-frame"):N,n?g(c(e)):C)},E.jsxs=function(e,r,t){var n=1e4>k.recentlyCreatedOwnerStacks++;return S(e,r,t,!0,n?Error("react-stack-top-frame"):N,n?g(c(e)):C)}})()),E}var F;function ne(){return F||(F=1,process.env.NODE_ENV==="production"?b.exports=re():b.exports=te()),b.exports}var ae=ne();function oe({children:u,ripple:i=!0,primeConfig:l={}}){const c={ripple:i,inputStyle:"outlined",...l};return ae.jsx(ee.PrimeReactProvider,{value:c,children:u})}const se="0.2.1",ue={name:"Yggdrasil",version:"0.2.1",tokens:727,coverage:"100%",modes:["light","dark"]};exports.YggdrasilProvider=oe;exports.theme=ue;exports.version=se;
package/dist/index.js CHANGED
@@ -1,11 +1,286 @@
1
- const e = "0.1.0", o = {
1
+ import K from "react";
2
+ import { PrimeReactProvider as ee } from "primereact/api";
3
+ var b = { exports: {} }, _ = {};
4
+ var $;
5
+ function re() {
6
+ if ($) return _;
7
+ $ = 1;
8
+ var u = /* @__PURE__ */ Symbol.for("react.transitional.element"), i = /* @__PURE__ */ Symbol.for("react.fragment");
9
+ function l(c, o, s) {
10
+ var d = null;
11
+ if (s !== void 0 && (d = "" + s), o.key !== void 0 && (d = "" + o.key), "key" in o) {
12
+ s = {};
13
+ for (var m in o)
14
+ m !== "key" && (s[m] = o[m]);
15
+ } else s = o;
16
+ return o = s.ref, {
17
+ $$typeof: u,
18
+ type: c,
19
+ key: d,
20
+ ref: o !== void 0 ? o : null,
21
+ props: s
22
+ };
23
+ }
24
+ return _.Fragment = i, _.jsx = l, _.jsxs = l, _;
25
+ }
26
+ var E = {};
27
+ var I;
28
+ function te() {
29
+ return I || (I = 1, process.env.NODE_ENV !== "production" && (function() {
30
+ function u(e) {
31
+ if (e == null) return null;
32
+ if (typeof e == "function")
33
+ return e.$$typeof === H ? null : e.displayName || e.name || null;
34
+ if (typeof e == "string") return e;
35
+ switch (e) {
36
+ case p:
37
+ return "Fragment";
38
+ case U:
39
+ return "Profiler";
40
+ case W:
41
+ return "StrictMode";
42
+ case z:
43
+ return "Suspense";
44
+ case G:
45
+ return "SuspenseList";
46
+ case B:
47
+ return "Activity";
48
+ }
49
+ if (typeof e == "object")
50
+ switch (typeof e.tag == "number" && console.error(
51
+ "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
52
+ ), e.$$typeof) {
53
+ case M:
54
+ return "Portal";
55
+ case J:
56
+ return e.displayName || "Context";
57
+ case q:
58
+ return (e._context.displayName || "Context") + ".Consumer";
59
+ case V:
60
+ var r = e.render;
61
+ return e = e.displayName, e || (e = r.displayName || r.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
62
+ case X:
63
+ return r = e.displayName || null, r !== null ? r : u(e.type) || "Memo";
64
+ case T:
65
+ r = e._payload, e = e._init;
66
+ try {
67
+ return u(e(r));
68
+ } catch {
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ function i(e) {
74
+ return "" + e;
75
+ }
76
+ function l(e) {
77
+ try {
78
+ i(e);
79
+ var r = !1;
80
+ } catch {
81
+ r = !0;
82
+ }
83
+ if (r) {
84
+ r = console;
85
+ var t = r.error, n = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
86
+ return t.call(
87
+ r,
88
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
89
+ n
90
+ ), i(e);
91
+ }
92
+ }
93
+ function c(e) {
94
+ if (e === p) return "<>";
95
+ if (typeof e == "object" && e !== null && e.$$typeof === T)
96
+ return "<...>";
97
+ try {
98
+ var r = u(e);
99
+ return r ? "<" + r + ">" : "<...>";
100
+ } catch {
101
+ return "<...>";
102
+ }
103
+ }
104
+ function o() {
105
+ var e = k.A;
106
+ return e === null ? null : e.getOwner();
107
+ }
108
+ function s() {
109
+ return Error("react-stack-top-frame");
110
+ }
111
+ function d(e) {
112
+ if (x.call(e, "key")) {
113
+ var r = Object.getOwnPropertyDescriptor(e, "key").get;
114
+ if (r && r.isReactWarning) return !1;
115
+ }
116
+ return e.key !== void 0;
117
+ }
118
+ function m(e, r) {
119
+ function t() {
120
+ j || (j = !0, console.error(
121
+ "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
122
+ r
123
+ ));
124
+ }
125
+ t.isReactWarning = !0, Object.defineProperty(e, "key", {
126
+ get: t,
127
+ configurable: !0
128
+ });
129
+ }
130
+ function D() {
131
+ var e = u(this.type);
132
+ return h[e] || (h[e] = !0, console.error(
133
+ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
134
+ )), e = this.props.ref, e !== void 0 ? e : null;
135
+ }
136
+ function L(e, r, t, n, R, P) {
137
+ var a = t.ref;
138
+ return e = {
139
+ $$typeof: w,
140
+ type: e,
141
+ key: r,
142
+ props: t,
143
+ _owner: n
144
+ }, (a !== void 0 ? a : null) !== null ? Object.defineProperty(e, "ref", {
145
+ enumerable: !1,
146
+ get: D
147
+ }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
148
+ configurable: !1,
149
+ enumerable: !1,
150
+ writable: !0,
151
+ value: 0
152
+ }), Object.defineProperty(e, "_debugInfo", {
153
+ configurable: !1,
154
+ enumerable: !1,
155
+ writable: !0,
156
+ value: null
157
+ }), Object.defineProperty(e, "_debugStack", {
158
+ configurable: !1,
159
+ enumerable: !1,
160
+ writable: !0,
161
+ value: R
162
+ }), Object.defineProperty(e, "_debugTask", {
163
+ configurable: !1,
164
+ enumerable: !1,
165
+ writable: !0,
166
+ value: P
167
+ }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
168
+ }
169
+ function S(e, r, t, n, R, P) {
170
+ var a = r.children;
171
+ if (a !== void 0)
172
+ if (n)
173
+ if (Z(a)) {
174
+ for (n = 0; n < a.length; n++)
175
+ g(a[n]);
176
+ Object.freeze && Object.freeze(a);
177
+ } else
178
+ console.error(
179
+ "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
180
+ );
181
+ else g(a);
182
+ if (x.call(r, "key")) {
183
+ a = u(e);
184
+ var f = Object.keys(r).filter(function(Q) {
185
+ return Q !== "key";
186
+ });
187
+ n = 0 < f.length ? "{key: someKey, " + f.join(": ..., ") + ": ...}" : "{key: someKey}", Y[a + n] || (f = 0 < f.length ? "{" + f.join(": ..., ") + ": ...}" : "{}", console.error(
188
+ `A props object containing a "key" prop is being spread into JSX:
189
+ let props = %s;
190
+ <%s {...props} />
191
+ React keys must be passed directly to JSX without using spread:
192
+ let props = %s;
193
+ <%s key={someKey} {...props} />`,
194
+ n,
195
+ a,
196
+ f,
197
+ a
198
+ ), Y[a + n] = !0);
199
+ }
200
+ if (a = null, t !== void 0 && (l(t), a = "" + t), d(r) && (l(r.key), a = "" + r.key), "key" in r) {
201
+ t = {};
202
+ for (var A in r)
203
+ A !== "key" && (t[A] = r[A]);
204
+ } else t = r;
205
+ return a && m(
206
+ t,
207
+ typeof e == "function" ? e.displayName || e.name || "Unknown" : e
208
+ ), L(
209
+ e,
210
+ a,
211
+ t,
212
+ o(),
213
+ R,
214
+ P
215
+ );
216
+ }
217
+ function g(e) {
218
+ y(e) ? e._store && (e._store.validated = 1) : typeof e == "object" && e !== null && e.$$typeof === T && (e._payload.status === "fulfilled" ? y(e._payload.value) && e._payload.value._store && (e._payload.value._store.validated = 1) : e._store && (e._store.validated = 1));
219
+ }
220
+ function y(e) {
221
+ return typeof e == "object" && e !== null && e.$$typeof === w;
222
+ }
223
+ var v = K, w = /* @__PURE__ */ Symbol.for("react.transitional.element"), M = /* @__PURE__ */ Symbol.for("react.portal"), p = /* @__PURE__ */ Symbol.for("react.fragment"), W = /* @__PURE__ */ Symbol.for("react.strict_mode"), U = /* @__PURE__ */ Symbol.for("react.profiler"), q = /* @__PURE__ */ Symbol.for("react.consumer"), J = /* @__PURE__ */ Symbol.for("react.context"), V = /* @__PURE__ */ Symbol.for("react.forward_ref"), z = /* @__PURE__ */ Symbol.for("react.suspense"), G = /* @__PURE__ */ Symbol.for("react.suspense_list"), X = /* @__PURE__ */ Symbol.for("react.memo"), T = /* @__PURE__ */ Symbol.for("react.lazy"), B = /* @__PURE__ */ Symbol.for("react.activity"), H = /* @__PURE__ */ Symbol.for("react.client.reference"), k = v.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, x = Object.prototype.hasOwnProperty, Z = Array.isArray, O = console.createTask ? console.createTask : function() {
224
+ return null;
225
+ };
226
+ v = {
227
+ react_stack_bottom_frame: function(e) {
228
+ return e();
229
+ }
230
+ };
231
+ var j, h = {}, N = v.react_stack_bottom_frame.bind(
232
+ v,
233
+ s
234
+ )(), C = O(c(s)), Y = {};
235
+ E.Fragment = p, E.jsx = function(e, r, t) {
236
+ var n = 1e4 > k.recentlyCreatedOwnerStacks++;
237
+ return S(
238
+ e,
239
+ r,
240
+ t,
241
+ !1,
242
+ n ? Error("react-stack-top-frame") : N,
243
+ n ? O(c(e)) : C
244
+ );
245
+ }, E.jsxs = function(e, r, t) {
246
+ var n = 1e4 > k.recentlyCreatedOwnerStacks++;
247
+ return S(
248
+ e,
249
+ r,
250
+ t,
251
+ !0,
252
+ n ? Error("react-stack-top-frame") : N,
253
+ n ? O(c(e)) : C
254
+ );
255
+ };
256
+ })()), E;
257
+ }
258
+ var F;
259
+ function ne() {
260
+ return F || (F = 1, process.env.NODE_ENV === "production" ? b.exports = re() : b.exports = te()), b.exports;
261
+ }
262
+ var ae = ne();
263
+ function ue({
264
+ children: u,
265
+ ripple: i = !0,
266
+ primeConfig: l = {}
267
+ }) {
268
+ const c = {
269
+ ripple: i,
270
+ inputStyle: "outlined",
271
+ ...l
272
+ };
273
+ return /* @__PURE__ */ ae.jsx(ee, { value: c, children: u });
274
+ }
275
+ const le = "0.2.1", ce = {
2
276
  name: "Yggdrasil",
3
- version: "0.1.0",
277
+ version: "0.2.1",
4
278
  tokens: 727,
5
- coverage: "96%",
279
+ coverage: "100%",
6
280
  modes: ["light", "dark"]
7
281
  };
8
282
  export {
9
- o as theme,
10
- e as version
283
+ ue as YggdrasilProvider,
284
+ ce as theme,
285
+ le as version
11
286
  };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Typography Utilities (Optional)
3
+ *
4
+ * This file provides optional typography variables based on Yggdrasil design tokens.
5
+ * PrimeReact components use hardcoded sizing and don't consume these variables.
6
+ *
7
+ * Use these variables in your application code for consistent typography:
8
+ * - Body text: var(--Body-medium-font-size), var(--Body-medium-line-height)
9
+ * - Headings: var(--Heading-large-font-size), var(--Heading-large-line-height)
10
+ * - Titles: var(--Title-medium-font-size), var(--Title-medium-line-height)
11
+ *
12
+ * Font weights available:
13
+ * - 400 (Regular)
14
+ * - 500 (Medium)
15
+ * - 700 (Bold)
16
+ */
17
+
18
+ :root {
19
+ /* Body Text */
20
+ --Body-family: 'Roboto', arial, sans-serif;
21
+ --Body-large-font-size: 16px;
22
+ --Body-large-line-height: 28px;
23
+ --Body-medium-font-size: 14px;
24
+ --Body-medium-line-height: 24px;
25
+ --Body-small-font-size: 12px;
26
+ --Body-small-line-height: 20px;
27
+ --Body-weight-regular: 400;
28
+ --Body-weight-medium: 500;
29
+ --Body-weight-bold: 700;
30
+
31
+ /* Button Text */
32
+ --Button-family: 'Roboto', arial, sans-serif;
33
+ --Button-large-font-size: 18px;
34
+ --Button-large-line-height: 24px;
35
+ --Button-medium-font-size: 14px;
36
+ --Button-medium-line-height: 16px;
37
+ --Button-small-font-size: 12px;
38
+ --Button-small-line-height: 16px;
39
+ --Button-weight: 500;
40
+
41
+ /* Headings */
42
+ --Heading-family: 'Roboto', arial, sans-serif;
43
+ --Heading-large-font-size: 24px;
44
+ --Heading-large-line-height: 32px;
45
+ --Heading-medium-font-size: 20px;
46
+ --Heading-medium-line-height: 28px;
47
+ --Heading-small-font-size: 18px;
48
+ --Heading-small-line-height: 24px;
49
+ --Heading-weight: 500;
50
+
51
+ /* Titles */
52
+ --Title-family: 'Roboto', arial, sans-serif;
53
+ --Title-large-font-size: 36px;
54
+ --Title-large-line-height: 40px;
55
+ --Title-medium-font-size: 28px;
56
+ --Title-medium-line-height: 36px;
57
+ --Title-small-font-size: 22px;
58
+ --Title-small-line-height: 30px;
59
+ --Title-weight: 700;
60
+
61
+ /* Labels */
62
+ --Label-family: 'Roboto', arial, sans-serif;
63
+ --Label-large-font-size: 16px;
64
+ --Label-large-line-height: 24px;
65
+ --Label-medium-font-size: 14px;
66
+ --Label-medium-line-height: 20px;
67
+ --Label-small-font-size: 12px;
68
+ --Label-small-line-height: 16px;
69
+ --Label-x-small-font-size: 10px;
70
+ --Label-x-small-line-height: 12px;
71
+ --Label-weight-regular: 400;
72
+ --Label-weight-bold: 700;
73
+ }
@@ -5,7 +5,7 @@
5
5
  * For runtime switching, use yggdrasil-adaptive.css
6
6
  */
7
7
 
8
- @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
8
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
9
9
  @import "./foundations.css";
10
10
  @import "./radius.css";
11
11
  @import "./semantic-dark.css";
@@ -5,7 +5,7 @@
5
5
  * For runtime switching, use yggdrasil-adaptive.css
6
6
  */
7
7
 
8
- @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
8
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
9
9
  @import "./foundations.css";
10
10
  @import "./radius.css";
11
11
  @import "./semantic-light.css";
@@ -45,7 +45,7 @@ cp -r path/to/prime-yggdrasil/src/theme ./src/design-system
45
45
 
46
46
  ## 🚀 Integration
47
47
 
48
- ### 1. Import Theme in Your App
48
+ ### 1. Import Theme and Provider in Your App
49
49
 
50
50
  ```tsx
51
51
  // src/main.tsx or src/App.tsx
@@ -54,15 +54,73 @@ import 'prime-yggdrasil/yggdrasil-light.css'; // Light theme
54
54
  import 'prime-yggdrasil/yggdrasil-dark.css'; // Dark theme
55
55
 
56
56
  import 'primeicons/primeicons.css';
57
+ import { YggdrasilProvider } from 'prime-yggdrasil';
57
58
 
58
59
  // Your app code
59
60
  import { Button } from 'primereact/button';
60
61
 
61
62
  function App() {
62
- return <Button label="Hello Yggdrasil" />;
63
+ return (
64
+ <YggdrasilProvider ripple={true}>
65
+ <Button label="Hello Yggdrasil" />
66
+ </YggdrasilProvider>
67
+ );
68
+ }
69
+ ```
70
+
71
+ **YggdrasilProvider Configuration:**
72
+ - `ripple` (default: `true`) - Enable ripple effect on interactive components (buttons, checkboxes, etc.)
73
+ - `primeConfig` - Additional PrimeReact configuration options
74
+
75
+ ```tsx
76
+ <YggdrasilProvider
77
+ ripple={true}
78
+ primeConfig={{
79
+ inputStyle: 'outlined', // or 'filled'
80
+ // other PrimeReact config...
81
+ }}
82
+ >
83
+ <App />
84
+ </YggdrasilProvider>
85
+ ```
86
+
87
+ ### Typography (Optional)
88
+
89
+ Prime Yggdrasil loads Roboto font family by default. If you want to use the Yggdrasil typography system in your custom components:
90
+
91
+ ```tsx
92
+ // Import optional typography utilities
93
+ import '@lifeonlars/prime-yggdrasil/typography.css';
94
+
95
+ // Use in your custom components
96
+ function MyComponent() {
97
+ return (
98
+ <div style={{
99
+ fontFamily: 'var(--Body-family)',
100
+ fontSize: 'var(--Body-medium-font-size)',
101
+ lineHeight: 'var(--Body-medium-line-height)',
102
+ fontWeight: 'var(--Body-weight-regular)'
103
+ }}>
104
+ Custom content with Yggdrasil typography
105
+ </div>
106
+ );
63
107
  }
64
108
  ```
65
109
 
110
+ **Note:** PrimeReact components have their own typography sizing and don't consume these variables. Use these tokens only for custom application code outside of PrimeReact components.
111
+
112
+ **Available font weights:**
113
+ - 400 (Regular)
114
+ - 500 (Medium)
115
+ - 700 (Bold)
116
+
117
+ **Available typography categories:**
118
+ - `--Body-*` - Body text styles (small, medium, large)
119
+ - `--Heading-*` - Heading styles (small, medium, large)
120
+ - `--Title-*` - Title styles (small, medium, large)
121
+ - `--Button-*` - Button text styles (small, medium, large)
122
+ - `--Label-*` - Label styles (x-small, small, medium, large)
123
+
66
124
  ### 2. Configure Your Build Tool
67
125
 
68
126
  #### Vite (Recommended)
@@ -0,0 +1,352 @@
1
+ # Storybook Testing Guide
2
+
3
+ This guide explains how to test components in Prime Yggdrasil using Storybook's Vitest addon.
4
+
5
+ ## Overview
6
+
7
+ Prime Yggdrasil uses `@storybook/addon-vitest` for component testing. This allows you to:
8
+ - Write tests alongside your stories
9
+ - Test components in a real browser environment
10
+ - Use Vitest's familiar testing API
11
+ - Run tests in watch mode for development
12
+
13
+ ## Setup
14
+
15
+ The testing infrastructure is already configured:
16
+
17
+ ### Files
18
+ - `.storybook/vitest.config.ts` - Vitest configuration for Storybook
19
+ - `.storybook/vitest.setup.ts` - Test setup and Storybook project annotations
20
+ - `package.json` - Test scripts
21
+
22
+ ### Scripts
23
+ ```bash
24
+ # Run all Storybook tests once
25
+ npm run test:storybook
26
+
27
+ # Run tests in watch mode (auto-rerun on changes)
28
+ npm run test:storybook:watch
29
+ ```
30
+
31
+ ## Writing Tests
32
+
33
+ ### Basic Test Structure
34
+
35
+ Tests are written using Vitest's `expect` API inside your story files:
36
+
37
+ ```tsx
38
+ import { test, expect } from '@storybook/test';
39
+ import type { Meta, StoryObj } from '@storybook/react-vite';
40
+ import { Button } from 'primereact/button';
41
+
42
+ const meta = {
43
+ title: 'Button/Button',
44
+ component: Button,
45
+ } satisfies Meta<typeof Button>;
46
+
47
+ export default meta;
48
+ type Story = StoryObj<typeof meta>;
49
+
50
+ export const Primary: Story = {
51
+ args: {
52
+ label: 'Click me',
53
+ },
54
+ };
55
+
56
+ // Test the Primary story
57
+ test('Primary button renders correctly', async ({ mount }) => {
58
+ const component = await mount(<Primary.component {...Primary.args} />);
59
+ const button = await component.getByRole('button');
60
+
61
+ await expect(button).toBeInTheDocument();
62
+ await expect(button).toHaveTextContent('Click me');
63
+ });
64
+ ```
65
+
66
+ ### Testing Interactive Components
67
+
68
+ For components with state (like Checkbox, RadioButton, etc.):
69
+
70
+ ```tsx
71
+ import { test, expect } from '@storybook/test';
72
+ import { userEvent } from '@storybook/test';
73
+
74
+ export const Default: Story = {
75
+ render: () => {
76
+ const [checked, setChecked] = useState(false);
77
+ return (
78
+ <Checkbox checked={checked} onChange={(e) => setChecked(e.checked)} />
79
+ );
80
+ },
81
+ };
82
+
83
+ test('Checkbox toggles on click', async ({ mount, page }) => {
84
+ await mount(<Default.component />);
85
+
86
+ const checkbox = page.getByRole('checkbox');
87
+
88
+ // Initially unchecked
89
+ await expect(checkbox).not.toBeChecked();
90
+
91
+ // Click to check
92
+ await userEvent.click(checkbox);
93
+ await expect(checkbox).toBeChecked();
94
+
95
+ // Click again to uncheck
96
+ await userEvent.click(checkbox);
97
+ await expect(checkbox).not.toBeChecked();
98
+ });
99
+ ```
100
+
101
+ ### Testing Theme Switching
102
+
103
+ Test components in both light and dark modes:
104
+
105
+ ```tsx
106
+ test('Button renders in dark mode', async ({ mount, page }) => {
107
+ // Set dark mode
108
+ await page.evaluate(() => {
109
+ document.documentElement.setAttribute('data-theme', 'dark');
110
+ });
111
+
112
+ await mount(<Primary.component {...Primary.args} />);
113
+
114
+ const button = page.getByRole('button');
115
+ const bgColor = await button.evaluate((el) =>
116
+ getComputedStyle(el).backgroundColor
117
+ );
118
+
119
+ // Dark mode should have darker background
120
+ await expect(bgColor).toBeTruthy();
121
+ });
122
+ ```
123
+
124
+ ### Testing Accessibility
125
+
126
+ Use built-in a11y assertions:
127
+
128
+ ```tsx
129
+ import { test, expect } from '@storybook/test';
130
+
131
+ test('Button is accessible', async ({ mount, page }) => {
132
+ await mount(<Primary.component {...Primary.args} />);
133
+
134
+ const button = page.getByRole('button');
135
+
136
+ // Check ARIA attributes
137
+ await expect(button).toBeEnabled();
138
+ await expect(button).toBeVisible();
139
+ await expect(button).toHaveAccessibleName('Click me');
140
+ });
141
+ ```
142
+
143
+ ## Best Practices
144
+
145
+ ### 1. Test One Concern Per Test
146
+ ```tsx
147
+ // Good
148
+ test('renders with label', async ({ mount }) => { /* ... */ });
149
+ test('responds to click', async ({ mount }) => { /* ... */ });
150
+
151
+ // Avoid
152
+ test('renders and clicks', async ({ mount }) => { /* ... */ });
153
+ ```
154
+
155
+ ### 2. Use Semantic Queries
156
+ ```tsx
157
+ // Good - semantic and accessible
158
+ const button = page.getByRole('button', { name: 'Submit' });
159
+ const heading = page.getByRole('heading', { level: 1 });
160
+
161
+ // Avoid - fragile
162
+ const button = page.locator('.p-button');
163
+ ```
164
+
165
+ ### 3. Test User Behavior, Not Implementation
166
+ ```tsx
167
+ // Good - tests what user sees/does
168
+ test('shows error message on invalid input', async ({ mount, page }) => {
169
+ await mount(<Form />);
170
+ await page.getByRole('button', { name: 'Submit' }).click();
171
+ await expect(page.getByText('Required field')).toBeVisible();
172
+ });
173
+
174
+ // Avoid - tests implementation details
175
+ test('sets error state to true', async ({ mount }) => {
176
+ const { rerender } = await mount(<Form />);
177
+ // Don't test internal state
178
+ });
179
+ ```
180
+
181
+ ### 4. Keep Tests Fast
182
+ - Use `mount` instead of full page loads
183
+ - Mock external API calls
184
+ - Avoid unnecessary `waitFor` delays
185
+
186
+ ### 5. Test Across Themes
187
+ ```tsx
188
+ test.each(['light', 'dark'])('renders in %s mode', async (theme, { mount, page }) => {
189
+ await page.evaluate((t) => {
190
+ document.documentElement.setAttribute('data-theme', t);
191
+ }, theme);
192
+
193
+ await mount(<Component />);
194
+ // Test rendering...
195
+ });
196
+ ```
197
+
198
+ ## Common Patterns
199
+
200
+ ### Testing Forms
201
+
202
+ ```tsx
203
+ test('form submission', async ({ mount, page }) => {
204
+ await mount(<FormStory />);
205
+
206
+ // Fill in fields
207
+ await page.getByLabel('Email').fill('user@example.com');
208
+ await page.getByLabel('Password').fill('password123');
209
+
210
+ // Submit
211
+ await page.getByRole('button', { name: 'Sign In' }).click();
212
+
213
+ // Verify result
214
+ await expect(page.getByText('Welcome!')).toBeVisible();
215
+ });
216
+ ```
217
+
218
+ ### Testing Dropdowns
219
+
220
+ ```tsx
221
+ test('dropdown selection', async ({ mount, page }) => {
222
+ await mount(<DropdownStory />);
223
+
224
+ const dropdown = page.getByRole('combobox');
225
+ await dropdown.click();
226
+
227
+ // Select option
228
+ await page.getByRole('option', { name: 'New York' }).click();
229
+
230
+ // Verify selection
231
+ await expect(dropdown).toHaveValue('NY');
232
+ });
233
+ ```
234
+
235
+ ### Testing Modals/Dialogs
236
+
237
+ ```tsx
238
+ test('dialog opens and closes', async ({ mount, page }) => {
239
+ await mount(<DialogStory />);
240
+
241
+ // Open dialog
242
+ await page.getByRole('button', { name: 'Open' }).click();
243
+
244
+ const dialog = page.getByRole('dialog');
245
+ await expect(dialog).toBeVisible();
246
+
247
+ // Close dialog
248
+ await dialog.getByRole('button', { name: 'Close' }).click();
249
+ await expect(dialog).not.toBeVisible();
250
+ });
251
+ ```
252
+
253
+ ## Debugging Tests
254
+
255
+ ### Run in headed mode
256
+ ```bash
257
+ # See the browser while tests run
258
+ npm run test:storybook:watch
259
+ # Then in the Vitest UI, enable "headed" mode
260
+ ```
261
+
262
+ ### Use page.pause()
263
+ ```tsx
264
+ test('debug test', async ({ mount, page }) => {
265
+ await mount(<Component />);
266
+
267
+ await page.pause(); // Opens Playwright Inspector
268
+
269
+ // Test continues...
270
+ });
271
+ ```
272
+
273
+ ### Screenshot on failure
274
+ ```tsx
275
+ test('visual test', async ({ mount, page }) => {
276
+ await mount(<Component />);
277
+
278
+ try {
279
+ await expect(page.getByRole('button')).toBeVisible();
280
+ } catch (error) {
281
+ await page.screenshot({ path: 'test-failure.png' });
282
+ throw error;
283
+ }
284
+ });
285
+ ```
286
+
287
+ ## Continuous Integration
288
+
289
+ For CI/CD pipelines:
290
+
291
+ ```yaml
292
+ # .github/workflows/test.yml
293
+ - name: Install dependencies
294
+ run: npm ci
295
+
296
+ - name: Install Playwright browsers
297
+ run: npx playwright install --with-deps chromium
298
+
299
+ - name: Run Storybook tests
300
+ run: npm run test:storybook
301
+ ```
302
+
303
+ ## Troubleshooting
304
+
305
+ ### "Failed to start test runner process"
306
+
307
+ This usually means:
308
+ 1. Playwright browsers aren't installed: `npx playwright install chromium`
309
+ 2. Port conflict: Close other Storybook instances
310
+ 3. Timeout: Increase timeout in vitest.config.ts
311
+
312
+ ### Tests timing out
313
+
314
+ Increase test timeout:
315
+ ```ts
316
+ // .storybook/vitest.config.ts
317
+ export default defineConfig({
318
+ test: {
319
+ testTimeout: 30000, // 30 seconds
320
+ },
321
+ });
322
+ ```
323
+
324
+ ### Theme styles not applying
325
+
326
+ Ensure YggdrasilProvider is wrapping your component:
327
+ ```tsx
328
+ // In your story
329
+ export const Default: Story = {
330
+ decorators: [
331
+ (Story) => (
332
+ <YggdrasilProvider ripple={true}>
333
+ <Story />
334
+ </YggdrasilProvider>
335
+ ),
336
+ ],
337
+ };
338
+ ```
339
+
340
+ ## Resources
341
+
342
+ - [Storybook Test Addon Docs](https://storybook.js.org/docs/writing-tests/test-addon)
343
+ - [Vitest API](https://vitest.dev/api/)
344
+ - [Playwright Test API](https://playwright.dev/docs/api/class-test)
345
+ - [Testing Library Queries](https://testing-library.com/docs/queries/about)
346
+
347
+ ## Next Steps
348
+
349
+ 1. Add tests to existing stories
350
+ 2. Set up CI pipeline to run tests
351
+ 3. Add visual regression testing with Chromatic
352
+ 4. Configure test coverage reporting
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeonlars/prime-yggdrasil",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "AI-agent-friendly PrimeReact design system for component-driven development with semantic tokens and dark mode support",
6
6
  "keywords": [
@@ -36,6 +36,7 @@
36
36
  "./yggdrasil-dark.css": "./dist/yggdrasil-dark.css",
37
37
  "./theme.css": "./dist/prime-yggdrasil.css",
38
38
  "./foundations.css": "./dist/foundations.css",
39
+ "./typography.css": "./dist/typography.css",
39
40
  "./docs/*": "./docs/*"
40
41
  },
41
42
  "files": [
@@ -53,6 +54,8 @@
53
54
  "preview": "vite preview",
54
55
  "test": "vitest run",
55
56
  "test:watch": "vitest",
57
+ "test:storybook": "test-storybook",
58
+ "test:storybook:watch": "test-storybook --watch",
56
59
  "test:contrast": "node scripts/test-contrast.js",
57
60
  "test:contrast:vitest": "vitest run tests/contrast.test.ts",
58
61
  "test:contrast:watch": "vitest tests/contrast.test.ts",
@@ -75,11 +78,15 @@
75
78
  "devDependencies": {
76
79
  "@chromatic-com/storybook": "^4.1.3",
77
80
  "@eslint/js": "^9.39.1",
78
- "@storybook/addon-a11y": "^10.1.9",
79
- "@storybook/addon-docs": "^10.1.9",
80
- "@storybook/addon-onboarding": "^10.1.9",
81
- "@storybook/addon-vitest": "^10.1.9",
82
- "@storybook/react-vite": "^10.1.9",
81
+ "@storybook/addon-a11y": "^10.1.11",
82
+ "@storybook/addon-docs": "^10.1.11",
83
+ "@storybook/addon-onboarding": "^10.1.11",
84
+ "@storybook/addon-vitest": "^10.1.11",
85
+ "@storybook/react-vite": "^10.1.11",
86
+ "@storybook/test-runner": "^0.24.2",
87
+ "@testing-library/jest-dom": "^6.9.1",
88
+ "@testing-library/react": "^16.3.1",
89
+ "@testing-library/user-event": "^14.6.1",
83
90
  "@types/node": "^24.10.1",
84
91
  "@types/react": "^19.2.5",
85
92
  "@types/react-dom": "^19.2.3",
@@ -93,8 +100,9 @@
93
100
  "eslint": "^9.39.1",
94
101
  "eslint-plugin-react-hooks": "^7.0.1",
95
102
  "eslint-plugin-react-refresh": "^0.4.24",
96
- "eslint-plugin-storybook": "^10.1.9",
103
+ "eslint-plugin-storybook": "^10.1.11",
97
104
  "globals": "^16.5.0",
105
+ "jsdom": "^27.4.0",
98
106
  "playwright": "^1.57.0",
99
107
  "primeflex": "^4.0.0",
100
108
  "primeicons": "^7.0.0",
@@ -102,7 +110,7 @@
102
110
  "react": "^19.2.0",
103
111
  "react-dom": "^19.2.0",
104
112
  "sass": "^1.97.0",
105
- "storybook": "^10.1.9",
113
+ "storybook": "^10.1.11",
106
114
  "stylelint": "^16.26.1",
107
115
  "stylelint-config-standard": "^39.0.1",
108
116
  "typescript": "~5.9.3",