@customerio/jist 0.1.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/dist/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Customer IO
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.
@@ -0,0 +1,32 @@
1
+ import JistRenderer from "./jist-renderer.js";
2
+ import type { JistTemplate, JistData, JistFormatDate, JistOnAction, JistActionEvent } from "./jist-renderer.js";
3
+ type JistMode = "auto" | "light" | "dark";
4
+ type ThemeValue = string | number | boolean | null | ThemeObject;
5
+ interface ThemeObject {
6
+ [key: string]: ThemeValue;
7
+ }
8
+ declare class JistTemplateElement extends HTMLElement {
9
+ #private;
10
+ static observedAttributes: string[];
11
+ get template(): string | null;
12
+ set template(val: string | null);
13
+ get data(): JistData | null;
14
+ set data(val: JistData | string | null);
15
+ get theme(): ThemeObject | null;
16
+ set theme(val: ThemeObject | string | null);
17
+ get mode(): JistMode;
18
+ set mode(val: JistMode | string);
19
+ get formatDate(): JistFormatDate | null;
20
+ set formatDate(fn: JistFormatDate | null);
21
+ get onAction(): JistOnAction | null;
22
+ set onAction(fn: JistOnAction | null);
23
+ get templates(): Record<string, JistTemplate>;
24
+ set templates(val: Record<string, JistTemplate[]> | string);
25
+ connectedCallback(): void;
26
+ disconnectedCallback(): void;
27
+ attributeChangedCallback(name: string, oldVal: string | null, newVal: string | null): void;
28
+ }
29
+ export default JistTemplateElement;
30
+ export { JistRenderer };
31
+ export type { JistTemplate, JistData, JistFormatDate, JistOnAction, JistActionEvent, JistMode, };
32
+ //# sourceMappingURL=jist-element.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jist-element.d.ts","sourceRoot":"","sources":["../src/jist-element.ts"],"names":[],"mappings":"AAKA,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAmE5B,KAAK,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,WAAW,CAAC;AACjE,UAAU,WAAW;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;CAC3B;AAED,cAAM,mBAAoB,SAAQ,WAAW;;IAC3C,MAAM,CAAC,kBAAkB,WAAyC;IAoBlE,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;IACD,IAAI,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAG9B;IAED,IAAI,IAAI,IAAI,QAAQ,GAAG,IAAI,CAE1B;IACD,IAAI,IAAI,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,EAGrC;IAED,IAAI,KAAK,IAAI,WAAW,GAAG,IAAI,CAE9B;IACD,IAAI,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,EAIzC;IAED,IAAI,IAAI,IAAI,QAAQ,CAEnB;IACD,IAAI,IAAI,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,EAG9B;IAED,IAAI,UAAU,IAAI,cAAc,GAAG,IAAI,CAEtC;IACD,IAAI,UAAU,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,EAGvC;IAED,IAAI,QAAQ,IAAI,YAAY,GAAG,IAAI,CAElC;IACD,IAAI,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,EAEnC;IAED,IAAI,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAE5C;IACD,IAAI,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,MAAM,EAYzD;IAID,iBAAiB,IAAI,IAAI;IAczB,oBAAoB,IAAI,IAAI;IAQ5B,wBAAwB,CACtB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,IAAI;CAiSR;AAID,eAAe,mBAAmB,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,eAAe,EACf,QAAQ,GACT,CAAC"}
@@ -0,0 +1,432 @@
1
+ /* ═══════════════════════════════════════════
2
+ <jist-template> Custom Element
3
+ Renders a Jist template tree into native DOM
4
+ ═══════════════════════════════════════════ */
5
+ var _a;
6
+ import JistRenderer from "./jist-renderer.js";
7
+ const SUPPORTED_VERSION = "1";
8
+ // Theme properties that are unitless numbers (not CSS lengths)
9
+ const UNITLESS_KEYS = new Set([
10
+ "fontWeight",
11
+ "maxLines",
12
+ "lineHeight",
13
+ "opacity",
14
+ ]);
15
+ // Numeric properties where 0 means "reset to platform default" (CSS `normal`),
16
+ // not a literal zero value. Setting these to 0 breaks the var() fallback chain
17
+ // so the variant doesn't inherit the base heading's value.
18
+ const ZERO_MEANS_NORMAL = new Set([
19
+ "lineHeight",
20
+ "letterSpacing",
21
+ ]);
22
+ // ── Variant CSS generation ─────────────────
23
+ // Maps a flattened theme path suffix to the CSS property it controls.
24
+ // Only leaf properties that appear in a variant's theme data generate CSS.
25
+ const PATH_TO_CSS = {
26
+ "text-font-size": "font-size",
27
+ "text-font-weight": "font-weight",
28
+ "text-font-family": "font-family",
29
+ "text-color": "color",
30
+ "text-line-height": "line-height",
31
+ "text-letter-spacing": "letter-spacing",
32
+ "text-max-lines": "-webkit-line-clamp",
33
+ "background-color": "background-color",
34
+ "border-width": "border-width",
35
+ "border-color": "border-color",
36
+ "border-radius": "border-radius",
37
+ "padding-top": "padding-top",
38
+ "padding-right": "padding-right",
39
+ "padding-bottom": "padding-bottom",
40
+ "padding-left": "padding-left",
41
+ "margin-top": "margin-top",
42
+ "margin-right": "margin-right",
43
+ "margin-bottom": "margin-bottom",
44
+ "margin-left": "margin-left",
45
+ "min-width": "min-width",
46
+ "min-height": "min-height",
47
+ };
48
+ const SHADOW_PARTS = ["shadow-offset-x", "shadow-offset-y", "shadow-blur", "shadow-color"];
49
+ const SHADOW_DEFAULTS = {
50
+ "shadow-offset-x": "0", "shadow-offset-y": "0", "shadow-blur": "0", "shadow-color": "transparent",
51
+ };
52
+ const BASE_KEYS = {
53
+ heading: new Set(["text", "padding", "margin"]),
54
+ text: new Set(["text", "padding", "margin"]),
55
+ date: new Set(["text", "padding", "margin"]),
56
+ button: new Set(["text", "background", "border", "shadow", "padding", "margin", "minWidth", "minHeight", "states"]),
57
+ image: new Set(["border", "padding", "margin"]),
58
+ };
59
+ const BUTTON_STATES = ["hover", "active", "disabled"];
60
+ const BUTTON_STATE_PROPS = [
61
+ ["background-color", "background-color"],
62
+ ["color", "text-color"],
63
+ ];
64
+ class JistTemplateElement extends HTMLElement {
65
+ static observedAttributes = ["template", "data", "theme", "mode"];
66
+ static #sharedStyle = null;
67
+ static #nextScopeId = 0;
68
+ // unscoped CSS → { scopeId, refCount }
69
+ static #scopes = new Map();
70
+ #scopeKey = null;
71
+ #template = null;
72
+ #data = null;
73
+ #theme = null;
74
+ #mode = "auto";
75
+ #formatDate = null;
76
+ #onAction = null;
77
+ #templates = {};
78
+ #mediaQuery = null;
79
+ #mediaHandler = null;
80
+ // ── Property API ──────────────────────────
81
+ get template() {
82
+ return this.#template;
83
+ }
84
+ set template(val) {
85
+ this.#template = val;
86
+ this.#render();
87
+ }
88
+ get data() {
89
+ return this.#data;
90
+ }
91
+ set data(val) {
92
+ this.#data = typeof val === "string" ? JSON.parse(val) : val;
93
+ this.#render();
94
+ }
95
+ get theme() {
96
+ return this.#theme;
97
+ }
98
+ set theme(val) {
99
+ this.#theme = typeof val === "string" ? JSON.parse(val) : val;
100
+ this.#applyTheme();
101
+ this.#render();
102
+ }
103
+ get mode() {
104
+ return this.#mode;
105
+ }
106
+ set mode(val) {
107
+ this.#mode = (val || "auto");
108
+ this.#applyTheme();
109
+ }
110
+ get formatDate() {
111
+ return this.#formatDate;
112
+ }
113
+ set formatDate(fn) {
114
+ this.#formatDate = fn;
115
+ this.#render();
116
+ }
117
+ get onAction() {
118
+ return this.#onAction;
119
+ }
120
+ set onAction(fn) {
121
+ this.#onAction = fn;
122
+ }
123
+ get templates() {
124
+ return this.#templates;
125
+ }
126
+ set templates(val) {
127
+ const raw = typeof val === "string" ? JSON.parse(val) : (val || {});
128
+ const resolved = {};
129
+ for (const [name, value] of Object.entries(raw)) {
130
+ if (name.startsWith("$"))
131
+ continue;
132
+ if (!Array.isArray(value))
133
+ continue;
134
+ const versions = value;
135
+ const match = versions.find((t) => t.version === SUPPORTED_VERSION);
136
+ if (match)
137
+ resolved[name] = match;
138
+ }
139
+ this.#templates = resolved;
140
+ this.#render();
141
+ }
142
+ // ── Lifecycle ─────────────────────────────
143
+ connectedCallback() {
144
+ this.#mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
145
+ this.#mediaHandler = () => {
146
+ if (this.#mode === "auto") {
147
+ this.#applyTheme();
148
+ this.#render();
149
+ }
150
+ };
151
+ this.#mediaQuery.addEventListener("change", this.#mediaHandler);
152
+ this.#applyTheme();
153
+ this.#render();
154
+ }
155
+ disconnectedCallback() {
156
+ if (this.#mediaQuery && this.#mediaHandler) {
157
+ this.#mediaQuery.removeEventListener("change", this.#mediaHandler);
158
+ }
159
+ this.#releaseScope();
160
+ _a.#syncSharedStyle();
161
+ }
162
+ attributeChangedCallback(name, oldVal, newVal) {
163
+ if (oldVal === newVal)
164
+ return;
165
+ switch (name) {
166
+ case "template":
167
+ this.#template = newVal || null;
168
+ this.#render();
169
+ break;
170
+ case "data":
171
+ this.#data = newVal ? JSON.parse(newVal) : null;
172
+ this.#render();
173
+ break;
174
+ case "theme":
175
+ this.#theme = newVal ? JSON.parse(newVal) : null;
176
+ this.#applyTheme();
177
+ this.#render();
178
+ break;
179
+ case "mode":
180
+ this.#mode = (newVal || "auto");
181
+ this.#applyTheme();
182
+ this.#render();
183
+ break;
184
+ }
185
+ }
186
+ // ── Theme → CSS Custom Properties ─────────
187
+ #isDark() {
188
+ if (this.#mode === "dark")
189
+ return true;
190
+ if (this.#mode === "light")
191
+ return false;
192
+ return this.#mediaQuery?.matches ?? false;
193
+ }
194
+ #applyTheme() {
195
+ if (!this.isConnected) {
196
+ if (!this.#theme) {
197
+ this.#releaseScope();
198
+ _a.#syncSharedStyle();
199
+ }
200
+ return;
201
+ }
202
+ if (this.#isDark()) {
203
+ this.setAttribute("data-jist-dark", "");
204
+ }
205
+ else {
206
+ this.removeAttribute("data-jist-dark");
207
+ }
208
+ if (!this.#theme) {
209
+ this.#releaseScope();
210
+ _a.#syncSharedStyle();
211
+ return;
212
+ }
213
+ // Clear existing jist custom properties
214
+ const toRemove = [];
215
+ for (let i = 0; i < this.style.length; i++) {
216
+ if (this.style[i].startsWith("--jist-"))
217
+ toRemove.push(this.style[i]);
218
+ }
219
+ toRemove.forEach((p) => this.style.removeProperty(p));
220
+ // Flatten base theme
221
+ this.#flatten(this.#theme, "--jist");
222
+ // Apply dark overrides if active
223
+ if (this.#isDark()) {
224
+ const darkOverrides = this.#theme.modes
225
+ ?.dark;
226
+ if (darkOverrides) {
227
+ this.#flatten(darkOverrides, "--jist");
228
+ }
229
+ }
230
+ // Generate variant CSS rules
231
+ this.#applyVariantCSS();
232
+ }
233
+ #flatten(obj, prefix) {
234
+ for (const [key, value] of Object.entries(obj)) {
235
+ if (key === "modes" || key.startsWith("$"))
236
+ continue;
237
+ const kebab = key.replace(/([A-Z])/g, "-$1").toLowerCase();
238
+ const prop = `${prefix}-${kebab}`;
239
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
240
+ this.#flatten(value, prop);
241
+ }
242
+ else if (value !== null && value !== undefined && value !== "") {
243
+ // Numeric 0 on reset-capable properties means "back to normal" — set the
244
+ // CSS keyword so the var() chain is broken rather than inheriting the base.
245
+ const cssValue = value === 0 && ZERO_MEANS_NORMAL.has(key)
246
+ ? "normal"
247
+ : typeof value === "number" && !UNITLESS_KEYS.has(key)
248
+ ? `${value}px`
249
+ : String(value);
250
+ this.style.setProperty(prop, cssValue);
251
+ }
252
+ }
253
+ }
254
+ // ── Variant CSS Generation ────────────────
255
+ #applyVariantCSS() {
256
+ const unscopedRules = [];
257
+ const theme = this.#theme;
258
+ if (!theme)
259
+ return;
260
+ const dark = theme.modes?.dark;
261
+ for (const type of Object.keys(BASE_KEYS)) {
262
+ const base = theme[type];
263
+ const darkBase = dark?.[type];
264
+ const baseKeys = BASE_KEYS[type];
265
+ const variantNames = new Set();
266
+ for (const src of [base, darkBase]) {
267
+ if (!src)
268
+ continue;
269
+ for (const key of Object.keys(src)) {
270
+ if (!baseKeys.has(key) && !key.startsWith("$"))
271
+ variantNames.add(key);
272
+ }
273
+ }
274
+ for (const variant of variantNames) {
275
+ const lightData = (base?.[variant] ?? {});
276
+ const darkData = (darkBase?.[variant] ?? {});
277
+ unscopedRules.push(this.#buildVariantRule(type, variant, lightData, darkData));
278
+ }
279
+ }
280
+ const unscopedCSS = unscopedRules.join("\n");
281
+ // Release previous scope before acquiring a new one
282
+ this.#releaseScope();
283
+ if (!unscopedCSS)
284
+ return;
285
+ let entry = _a.#scopes.get(unscopedCSS);
286
+ if (!entry) {
287
+ entry = { id: _a.#nextScopeId++, refs: 0 };
288
+ _a.#scopes.set(unscopedCSS, entry);
289
+ }
290
+ entry.refs++;
291
+ this.#scopeKey = unscopedCSS;
292
+ this.setAttribute("data-jist-v", String(entry.id));
293
+ _a.#syncSharedStyle();
294
+ }
295
+ #releaseScope() {
296
+ if (!this.#scopeKey)
297
+ return;
298
+ const entry = _a.#scopes.get(this.#scopeKey);
299
+ if (entry) {
300
+ entry.refs--;
301
+ if (entry.refs <= 0)
302
+ _a.#scopes.delete(this.#scopeKey);
303
+ }
304
+ this.#scopeKey = null;
305
+ this.removeAttribute("data-jist-v");
306
+ }
307
+ static #syncSharedStyle() {
308
+ if (_a.#scopes.size === 0) {
309
+ if (_a.#sharedStyle) {
310
+ _a.#sharedStyle.remove();
311
+ _a.#sharedStyle = null;
312
+ }
313
+ return;
314
+ }
315
+ if (!_a.#sharedStyle) {
316
+ _a.#sharedStyle = document.createElement("style");
317
+ _a.#sharedStyle.setAttribute("data-jist-variants", "");
318
+ document.head.appendChild(_a.#sharedStyle);
319
+ }
320
+ const parts = [];
321
+ for (const [unscopedCSS, { id }] of _a.#scopes) {
322
+ const scope = `[data-jist-v="${id}"]`;
323
+ parts.push(unscopedCSS.replace(/^(\.[a-z_-]+)/gm, `${scope} $1`));
324
+ }
325
+ _a.#sharedStyle.textContent = parts.join("\n");
326
+ }
327
+ #buildVariantRule(type, variant, lightData, darkData) {
328
+ const kebabVariant = variant.replace(/([A-Z])/g, "-$1").toLowerCase();
329
+ const cls = `.jist__${type}--${kebabVariant}`;
330
+ // Collect all leaf paths from the variant's theme data (union of light + dark)
331
+ const paths = new Set();
332
+ const collectPaths = (obj, prefix) => {
333
+ for (const [key, value] of Object.entries(obj)) {
334
+ if (key === "states" || key.startsWith("$"))
335
+ continue;
336
+ const kebab = key.replace(/([A-Z])/g, "-$1").toLowerCase();
337
+ const path = prefix ? `${prefix}-${kebab}` : kebab;
338
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
339
+ collectPaths(value, path);
340
+ }
341
+ else {
342
+ paths.add(path);
343
+ }
344
+ }
345
+ };
346
+ collectPaths(lightData, "");
347
+ collectPaths(darkData, "");
348
+ const lines = [];
349
+ for (const path of paths) {
350
+ const cssProp = PATH_TO_CSS[path];
351
+ if (!cssProp)
352
+ continue;
353
+ const variantVar = `--jist-${type}-${kebabVariant}-${path}`;
354
+ const baseVar = `--jist-${type}-${path}`;
355
+ lines.push(` ${cssProp}: var(${variantVar}, var(${baseVar}));`);
356
+ }
357
+ // box-shadow is composite — emit if any shadow sub-property is defined
358
+ if (type === "button" && [...paths].some((p) => p.startsWith("shadow-"))) {
359
+ const shadowParts = SHADOW_PARTS.map((part) => {
360
+ const variantVar = `--jist-button-${kebabVariant}-${part}`;
361
+ const baseVar = `--jist-button-${part}`;
362
+ return `var(${variantVar}, var(${baseVar}, ${SHADOW_DEFAULTS[part]}))`;
363
+ });
364
+ lines.push(` box-shadow: ${shadowParts.join(" ")};`);
365
+ }
366
+ let css = `${cls} {\n${lines.join("\n")}\n}`;
367
+ // Button state pseudo-classes
368
+ if (type === "button") {
369
+ const hasStates = lightData.states
370
+ || darkData.states;
371
+ if (hasStates) {
372
+ for (const state of BUTTON_STATES) {
373
+ const lightState = lightData.states?.[state];
374
+ const darkState = darkData.states?.[state];
375
+ if (!lightState && !darkState)
376
+ continue;
377
+ const stateLines = [];
378
+ for (const [cssProp, suffix] of BUTTON_STATE_PROPS) {
379
+ const vs = `--jist-button-${kebabVariant}-states-${state}-${suffix}`;
380
+ const bs = `--jist-button-states-${state}-${suffix}`;
381
+ const vb = `--jist-button-${kebabVariant}-${suffix}`;
382
+ const bb = `--jist-button-${suffix}`;
383
+ stateLines.push(` ${cssProp}: var(${vs}, var(${bs}, var(${vb}, var(${bb}))));`);
384
+ }
385
+ const pseudo = state === "disabled" ? ":disabled" : `:${state}`;
386
+ css += `\n${cls}${pseudo} {\n${stateLines.join("\n")}\n}`;
387
+ }
388
+ }
389
+ }
390
+ return css;
391
+ }
392
+ // ── Rendering ─────────────────────────────
393
+ #render() {
394
+ if (!this.#template || !this.#data)
395
+ return;
396
+ if (!this.isConnected)
397
+ return;
398
+ const tmpl = this.#templates[this.#template];
399
+ if (!tmpl) {
400
+ this.innerHTML = "";
401
+ return;
402
+ }
403
+ const renderer = new JistRenderer({
404
+ formatDate: this.#formatDate || undefined,
405
+ templates: this.#templates,
406
+ onAction: (detail) => {
407
+ // Property callback
408
+ if (this.#onAction)
409
+ this.#onAction(detail);
410
+ // CustomEvent (without DOM event in detail — not cloneable)
411
+ this.dispatchEvent(new CustomEvent("jist-action", {
412
+ bubbles: true,
413
+ detail: {
414
+ component: detail.component,
415
+ name: detail.name,
416
+ data: detail.data,
417
+ meta: detail.meta,
418
+ },
419
+ }));
420
+ },
421
+ });
422
+ this.innerHTML = "";
423
+ const dom = renderer.render(tmpl.root, this.#data);
424
+ if (dom)
425
+ this.appendChild(dom);
426
+ }
427
+ }
428
+ _a = JistTemplateElement;
429
+ customElements.define("jist-template", JistTemplateElement);
430
+ export default JistTemplateElement;
431
+ export { JistRenderer };
432
+ //# sourceMappingURL=jist-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jist-element.js","sourceRoot":"","sources":["../src/jist-element.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ export interface JistSpacing {
2
+ top?: number;
3
+ right?: number;
4
+ bottom?: number;
5
+ left?: number;
6
+ }
7
+ export interface JistLayoutNode {
8
+ type: "layout";
9
+ direction: "vertical" | "horizontal";
10
+ gap?: number;
11
+ align?: string;
12
+ justify?: string;
13
+ margin?: JistSpacing;
14
+ children: JistNode[];
15
+ }
16
+ export interface JistActionNode {
17
+ type: "action";
18
+ name: string;
19
+ meta?: Record<string, unknown>;
20
+ children: JistNode[];
21
+ }
22
+ export interface JistHeadingNode {
23
+ type: "heading";
24
+ name?: string;
25
+ variant?: "h2" | "h3" | "h4";
26
+ }
27
+ export interface JistTextNode {
28
+ type: "text";
29
+ name?: string;
30
+ variant?: string;
31
+ }
32
+ export interface JistDateNode {
33
+ type: "date";
34
+ name?: string;
35
+ variant?: string;
36
+ }
37
+ export interface JistButtonNode {
38
+ type: "button";
39
+ name: string;
40
+ variant?: string;
41
+ meta?: Record<string, unknown>;
42
+ }
43
+ export interface JistImageNode {
44
+ type: "image";
45
+ name: string;
46
+ variant?: string;
47
+ width?: number | "fill";
48
+ height?: number;
49
+ objectFit?: "contain" | "cover" | "fill";
50
+ borderRadius?: number;
51
+ }
52
+ export interface JistDynamicLayoutNode {
53
+ type: "dynamicLayout";
54
+ name: string;
55
+ direction?: "vertical" | "horizontal";
56
+ gap?: number;
57
+ align?: string;
58
+ justify?: string;
59
+ margin?: JistSpacing;
60
+ template: JistNode;
61
+ }
62
+ export interface JistTemplateNode {
63
+ type: "template";
64
+ name: string;
65
+ }
66
+ export type JistNode = JistLayoutNode | JistActionNode | JistHeadingNode | JistTextNode | JistDateNode | JistButtonNode | JistImageNode | JistDynamicLayoutNode | JistTemplateNode;
67
+ export interface JistTemplate {
68
+ version: string;
69
+ root: JistNode;
70
+ }
71
+ export interface JistButtonData {
72
+ label: string;
73
+ url: string;
74
+ disabled?: boolean;
75
+ }
76
+ export type JistData = Record<string, unknown>;
77
+ export interface JistActionEvent {
78
+ component: "button" | "action";
79
+ name: string;
80
+ data: unknown;
81
+ meta: Record<string, unknown> | null;
82
+ event?: Event;
83
+ }
84
+ export type JistFormatDate = (isoString: string, name: string) => string;
85
+ export type JistOnAction = (event: JistActionEvent) => void;
86
+ export interface JistRendererOptions {
87
+ formatDate?: JistFormatDate;
88
+ onAction?: JistOnAction;
89
+ templates?: Record<string, JistTemplate>;
90
+ }
91
+ export default class JistRenderer {
92
+ #private;
93
+ constructor({ formatDate, onAction, templates }?: JistRendererOptions);
94
+ /**
95
+ * Recursively builds a DOM tree from a JSON template node.
96
+ */
97
+ render(node: JistNode, data: JistData): HTMLElement | null;
98
+ }
99
+ //# sourceMappingURL=jist-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jist-renderer.d.ts","sourceRoot":"","sources":["../src/jist-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,278 @@
1
+ /* ═══════════════════════════════════════════
2
+ Jist Renderer
3
+ Converts JSON template trees into DOM nodes
4
+ ═══════════════════════════════════════════ */
5
+ // ── Constants ──────────────────────────────
6
+ const CLASS_PREFIX = "jist";
7
+ const ALIGN_MAP = {
8
+ start: "flex-start",
9
+ end: "flex-end",
10
+ center: "center",
11
+ stretch: "stretch",
12
+ baseline: "baseline",
13
+ };
14
+ const JUSTIFY_MAP = {
15
+ start: "flex-start",
16
+ end: "flex-end",
17
+ center: "center",
18
+ "space-between": "space-between",
19
+ "space-around": "space-around",
20
+ "space-evenly": "space-evenly",
21
+ };
22
+ function px(value) {
23
+ if (typeof value === "number")
24
+ return `${value}px`;
25
+ if (value === "fill")
26
+ return "100%";
27
+ return value;
28
+ }
29
+ function defaultFormatDate(iso) {
30
+ try {
31
+ return new Date(iso).toLocaleDateString(navigator.language);
32
+ }
33
+ catch {
34
+ return iso;
35
+ }
36
+ }
37
+ // ── Renderer ───────────────────────────────
38
+ const MAX_TEMPLATE_DEPTH = 10;
39
+ export default class JistRenderer {
40
+ #formatDate;
41
+ #onAction;
42
+ #templates;
43
+ #templateDepth = 0;
44
+ constructor({ formatDate, onAction, templates } = {}) {
45
+ this.#formatDate = formatDate || defaultFormatDate;
46
+ this.#onAction = onAction || null;
47
+ this.#templates = templates || {};
48
+ }
49
+ /**
50
+ * Recursively builds a DOM tree from a JSON template node.
51
+ */
52
+ render(node, data) {
53
+ if (!node)
54
+ return null;
55
+ switch (node.type) {
56
+ case "layout":
57
+ return this.#buildLayout(node, data);
58
+ case "action":
59
+ return this.#buildAction(node, data);
60
+ case "heading":
61
+ return this.#buildHeading(node, data);
62
+ case "text":
63
+ return this.#buildText("p", node, data);
64
+ case "date":
65
+ return this.#buildDate(node, data);
66
+ case "button":
67
+ return this.#buildButton(node, data);
68
+ case "image":
69
+ return this.#buildImage(node, data);
70
+ case "dynamicLayout":
71
+ return this.#buildDynamicLayout(node, data);
72
+ case "template":
73
+ return this.#buildTemplate(node, data);
74
+ default:
75
+ return null; // Unknown component — skip (forward compatibility)
76
+ }
77
+ }
78
+ // ── Layout ────────────────────────────────
79
+ #buildLayout(node, data) {
80
+ const el = document.createElement("div");
81
+ el.style.display = "flex";
82
+ el.style.flexDirection = node.direction === "horizontal" ? "row" : "column";
83
+ if (node.gap)
84
+ el.style.gap = px(node.gap);
85
+ if (node.align)
86
+ el.style.alignItems = ALIGN_MAP[node.align] || node.align;
87
+ if (node.justify)
88
+ el.style.justifyContent = JUSTIFY_MAP[node.justify] || node.justify;
89
+ if (node.margin) {
90
+ if (node.margin.top)
91
+ el.style.marginTop = px(node.margin.top);
92
+ if (node.margin.right)
93
+ el.style.marginRight = px(node.margin.right);
94
+ if (node.margin.bottom)
95
+ el.style.marginBottom = px(node.margin.bottom);
96
+ if (node.margin.left)
97
+ el.style.marginLeft = px(node.margin.left);
98
+ }
99
+ const isHorizontal = node.direction === "horizontal";
100
+ const needsFlex = isHorizontal && (!node.justify || node.justify === "start");
101
+ const textAlign = !isHorizontal && node.align === "center" ? "center"
102
+ : !isHorizontal && node.align === "end" ? "right"
103
+ : "";
104
+ for (const child of node.children || []) {
105
+ const childEl = this.render(child, data);
106
+ if (childEl) {
107
+ if (needsFlex && child.type === "layout") {
108
+ childEl.style.flex = "1";
109
+ childEl.style.minWidth = "0";
110
+ }
111
+ if (textAlign)
112
+ childEl.style.textAlign = textAlign;
113
+ el.appendChild(childEl);
114
+ }
115
+ }
116
+ return el;
117
+ }
118
+ // ── Action (clickable wrapper) ────────────
119
+ #buildAction(node, data) {
120
+ const name = node.name || "action";
121
+ const el = document.createElement("div");
122
+ this.#applyClasses(el, "action", name);
123
+ el.setAttribute("role", "button");
124
+ el.setAttribute("tabindex", "0");
125
+ for (const child of node.children || []) {
126
+ const childEl = this.render(child, data);
127
+ if (childEl)
128
+ el.appendChild(childEl);
129
+ }
130
+ const actionData = data[name];
131
+ const meta = node.meta || null;
132
+ if (this.#onAction) {
133
+ const onAction = this.#onAction;
134
+ const handler = (e) => {
135
+ e.stopPropagation();
136
+ onAction({
137
+ component: "action",
138
+ name,
139
+ data: actionData,
140
+ meta,
141
+ event: e,
142
+ });
143
+ };
144
+ el.addEventListener("click", handler);
145
+ el.addEventListener("keydown", (e) => {
146
+ if (e.key === "Enter" || e.key === " ") {
147
+ e.preventDefault();
148
+ handler(e);
149
+ }
150
+ });
151
+ }
152
+ return el;
153
+ }
154
+ // ── Heading ───────────────────────────────
155
+ #buildHeading(node, data) {
156
+ const variant = node.variant || "h3";
157
+ return this.#buildText(variant, node, data, variant);
158
+ }
159
+ // ── Text (heading, body) ──────────────────
160
+ #buildText(tag, node, data, variant) {
161
+ const name = node.name || node.type;
162
+ const el = document.createElement(tag);
163
+ this.#applyClasses(el, node.type, name, variant || node.variant);
164
+ el.textContent = data[name] || "";
165
+ return el;
166
+ }
167
+ // ── Date ──────────────────────────────────
168
+ #buildDate(node, data) {
169
+ const name = node.name || "date";
170
+ const el = document.createElement("time");
171
+ this.#applyClasses(el, "date", name, node.variant);
172
+ const value = data[name];
173
+ el.textContent = value ? this.#formatDate(value, name) : "";
174
+ return el;
175
+ }
176
+ // ── Button ────────────────────────────────
177
+ #buildButton(node, data) {
178
+ const name = node.name || "button";
179
+ const buttonData = data[name];
180
+ if (!buttonData)
181
+ return null;
182
+ const el = document.createElement("button");
183
+ this.#applyClasses(el, "button", name, node.variant);
184
+ el.textContent = buttonData.label;
185
+ if (buttonData.disabled)
186
+ el.disabled = true;
187
+ const meta = node.meta || null;
188
+ el.addEventListener("click", (e) => {
189
+ e.stopPropagation();
190
+ if (this.#onAction) {
191
+ this.#onAction({
192
+ component: "button",
193
+ name,
194
+ data: buttonData,
195
+ meta,
196
+ event: e,
197
+ });
198
+ }
199
+ });
200
+ return el;
201
+ }
202
+ // ── Image ─────────────────────────────────
203
+ #buildImage(node, data) {
204
+ const name = node.name || "image";
205
+ const src = data[name];
206
+ if (!src)
207
+ return null;
208
+ const wrapper = document.createElement("div");
209
+ this.#applyClasses(wrapper, "image", name, node.variant);
210
+ wrapper.style.overflow = "hidden";
211
+ const el = document.createElement("img");
212
+ el.src = src;
213
+ el.alt = data.title || "";
214
+ el.style.display = "block";
215
+ if (node.width)
216
+ el.style.width = px(node.width);
217
+ if (node.height)
218
+ el.style.height = px(node.height);
219
+ if (node.objectFit)
220
+ el.style.objectFit = node.objectFit;
221
+ if (node.borderRadius)
222
+ el.style.borderRadius = px(node.borderRadius);
223
+ wrapper.appendChild(el);
224
+ return wrapper;
225
+ }
226
+ // ── Dynamic Layout (repeating container) ───
227
+ #buildDynamicLayout(node, data) {
228
+ const items = data[node.name];
229
+ if (!Array.isArray(items))
230
+ return null;
231
+ const el = document.createElement("div");
232
+ const direction = node.direction || "vertical";
233
+ el.style.display = "flex";
234
+ el.style.flexDirection = direction === "horizontal" ? "row" : "column";
235
+ if (node.gap)
236
+ el.style.gap = px(node.gap);
237
+ if (node.align)
238
+ el.style.alignItems = ALIGN_MAP[node.align] || node.align;
239
+ if (node.justify)
240
+ el.style.justifyContent = JUSTIFY_MAP[node.justify] || node.justify;
241
+ if (node.margin) {
242
+ if (node.margin.top)
243
+ el.style.marginTop = px(node.margin.top);
244
+ if (node.margin.right)
245
+ el.style.marginRight = px(node.margin.right);
246
+ if (node.margin.bottom)
247
+ el.style.marginBottom = px(node.margin.bottom);
248
+ if (node.margin.left)
249
+ el.style.marginLeft = px(node.margin.left);
250
+ }
251
+ for (const item of items) {
252
+ const itemData = (typeof item === "object" && item !== null) ? item : {};
253
+ const childEl = this.render(node.template, itemData);
254
+ if (childEl)
255
+ el.appendChild(childEl);
256
+ }
257
+ return el;
258
+ }
259
+ // ── Ref (template reference) ───────────────
260
+ #buildTemplate(node, data) {
261
+ const template = this.#templates[node.name];
262
+ if (!template || this.#templateDepth >= MAX_TEMPLATE_DEPTH)
263
+ return null;
264
+ this.#templateDepth++;
265
+ const result = this.render(template.root, data);
266
+ this.#templateDepth--;
267
+ return result;
268
+ }
269
+ // ── Helpers ───────────────────────────────
270
+ #applyClasses(el, type, name, variant) {
271
+ el.classList.add(`${CLASS_PREFIX}__${type}`);
272
+ if (variant)
273
+ el.classList.add(`${CLASS_PREFIX}__${type}--${variant}`);
274
+ if (name !== type)
275
+ el.classList.add(`${CLASS_PREFIX}__${name}`);
276
+ }
277
+ }
278
+ //# sourceMappingURL=jist-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jist-renderer.js","sourceRoot":"","sources":["../src/jist-renderer.ts"],"names":[],"mappings":"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"}
package/dist/jist.css ADDED
@@ -0,0 +1,187 @@
1
+ /* ═══════════════════════════════════════════
2
+ Jist Template Styles
3
+ ═══════════════════════════════════════════ */
4
+
5
+ /* ── Host Element ───────────────────────── */
6
+
7
+ jist-template {
8
+ display: block;
9
+ }
10
+
11
+ /* ── Base Reset ─────────────────────────── */
12
+
13
+ .jist__heading,
14
+ .jist__text,
15
+ .jist__date {
16
+ margin: 0;
17
+ padding: 0;
18
+ }
19
+
20
+ /* ── Heading ────────────────────────────── */
21
+
22
+ .jist__heading {
23
+ font-size: var(--jist-heading-text-font-size, 16px);
24
+ font-weight: var(--jist-heading-text-font-weight, 600);
25
+ color: var(--jist-heading-text-color, #000000);
26
+ font-family: var(--jist-heading-text-font-family, inherit);
27
+ line-height: var(--jist-heading-text-line-height, 1.3);
28
+ letter-spacing: var(--jist-heading-text-letter-spacing, normal);
29
+ padding-top: var(--jist-heading-padding-top, 0);
30
+ padding-right: var(--jist-heading-padding-right, 0);
31
+ padding-bottom: var(--jist-heading-padding-bottom, 0);
32
+ padding-left: var(--jist-heading-padding-left, 0);
33
+ margin-top: var(--jist-heading-margin-top, 0);
34
+ margin-right: var(--jist-heading-margin-right, 0);
35
+ margin-bottom: var(--jist-heading-margin-bottom, 0);
36
+ margin-left: var(--jist-heading-margin-left, 0);
37
+ /* Line clamping — active when --jist-heading-text-max-lines is set */
38
+ display: -webkit-box;
39
+ -webkit-box-orient: vertical;
40
+ -webkit-line-clamp: var(--jist-heading-text-max-lines, none);
41
+ overflow: hidden;
42
+ }
43
+
44
+ /* ── Text ───────────────────────────────── */
45
+
46
+ .jist__text {
47
+ font-size: var(--jist-text-text-font-size, 14px);
48
+ font-weight: var(--jist-text-text-font-weight, 400);
49
+ color: var(--jist-text-text-color, #000000);
50
+ font-family: var(--jist-text-text-font-family, inherit);
51
+ line-height: var(--jist-text-text-line-height, 1.5);
52
+ letter-spacing: var(--jist-text-text-letter-spacing, normal);
53
+ padding-top: var(--jist-text-padding-top, 0);
54
+ padding-right: var(--jist-text-padding-right, 0);
55
+ padding-bottom: var(--jist-text-padding-bottom, 0);
56
+ padding-left: var(--jist-text-padding-left, 0);
57
+ margin-top: var(--jist-text-margin-top, 0);
58
+ margin-right: var(--jist-text-margin-right, 0);
59
+ margin-bottom: var(--jist-text-margin-bottom, 0);
60
+ margin-left: var(--jist-text-margin-left, 0);
61
+ /* Line clamping — active when --jist-text-text-max-lines is set */
62
+ display: -webkit-box;
63
+ -webkit-box-orient: vertical;
64
+ -webkit-line-clamp: var(--jist-text-text-max-lines, none);
65
+ overflow: hidden;
66
+ }
67
+
68
+ /* ── Date ───────────────────────────────── */
69
+
70
+ .jist__date {
71
+ font-size: var(--jist-date-text-font-size, 12px);
72
+ font-weight: var(--jist-date-text-font-weight, 400);
73
+ color: var(--jist-date-text-color, #000000);
74
+ font-family: var(--jist-date-text-font-family, inherit);
75
+ line-height: var(--jist-date-text-line-height, 1.4);
76
+ letter-spacing: var(--jist-date-text-letter-spacing, normal);
77
+ padding-top: var(--jist-date-padding-top, 0);
78
+ padding-right: var(--jist-date-padding-right, 0);
79
+ padding-bottom: var(--jist-date-padding-bottom, 0);
80
+ padding-left: var(--jist-date-padding-left, 0);
81
+ margin-top: var(--jist-date-margin-top, 0);
82
+ margin-right: var(--jist-date-margin-right, 0);
83
+ margin-bottom: var(--jist-date-margin-bottom, 0);
84
+ margin-left: var(--jist-date-margin-left, 0);
85
+ }
86
+
87
+ /* ── Button ─────────────────────────────── */
88
+
89
+ .jist__button {
90
+ appearance: none;
91
+ -webkit-appearance: none;
92
+ display: inline-flex;
93
+ align-items: center;
94
+ justify-content: center;
95
+ cursor: pointer;
96
+ border: none;
97
+ font-size: var(--jist-button-text-font-size, 14px);
98
+ font-weight: var(--jist-button-text-font-weight, 500);
99
+ color: var(--jist-button-text-color, #ffffff);
100
+ font-family: var(--jist-button-text-font-family, inherit);
101
+ line-height: var(--jist-button-text-line-height, 1);
102
+ background-color: var(--jist-button-background-color, #4f46e5);
103
+ border-width: var(--jist-button-border-width, 0);
104
+ border-style: solid;
105
+ border-color: var(--jist-button-border-color, transparent);
106
+ border-radius: var(--jist-button-border-radius, 6px);
107
+ box-shadow:
108
+ var(--jist-button-shadow-offset-x, 0)
109
+ var(--jist-button-shadow-offset-y, 0)
110
+ var(--jist-button-shadow-blur, 0)
111
+ var(--jist-button-shadow-color, transparent);
112
+ padding-top: var(--jist-button-padding-top, 8px);
113
+ padding-right: var(--jist-button-padding-right, 16px);
114
+ padding-bottom: var(--jist-button-padding-bottom, 8px);
115
+ padding-left: var(--jist-button-padding-left, 16px);
116
+ margin-top: var(--jist-button-margin-top, 0);
117
+ margin-right: var(--jist-button-margin-right, 0);
118
+ margin-bottom: var(--jist-button-margin-bottom, 0);
119
+ margin-left: var(--jist-button-margin-left, 0);
120
+ min-width: var(--jist-button-min-width, 0);
121
+ min-height: var(--jist-button-min-height, 0);
122
+ transition: background-color 0.15s ease, color 0.15s ease,
123
+ border-color 0.15s ease, box-shadow 0.15s ease;
124
+ }
125
+
126
+ .jist__button:hover {
127
+ background-color: var(--jist-button-states-hover-background-color,
128
+ var(--jist-button-background-color, #4338ca));
129
+ color: var(--jist-button-states-hover-text-color,
130
+ var(--jist-button-text-color, #ffffff));
131
+ }
132
+
133
+ .jist__button:active {
134
+ background-color: var(--jist-button-states-active-background-color,
135
+ var(--jist-button-background-color, #3730a3));
136
+ color: var(--jist-button-states-active-text-color,
137
+ var(--jist-button-text-color, #ffffff));
138
+ }
139
+
140
+ .jist__button:disabled {
141
+ background-color: var(--jist-button-states-disabled-background-color,
142
+ var(--jist-button-background-color, #c7d2fe));
143
+ color: var(--jist-button-states-disabled-text-color,
144
+ var(--jist-button-text-color, #a5b4fc));
145
+ cursor: not-allowed;
146
+ }
147
+
148
+ /* ── Image ──────────────────────────────── */
149
+
150
+ .jist__image {
151
+ display: block;
152
+ max-width: 100%;
153
+ overflow: hidden;
154
+ border-radius: var(--jist-image-border-radius, 0);
155
+ padding-top: var(--jist-image-padding-top, 0);
156
+ padding-right: var(--jist-image-padding-right, 0);
157
+ padding-bottom: var(--jist-image-padding-bottom, 0);
158
+ padding-left: var(--jist-image-padding-left, 0);
159
+ margin-top: var(--jist-image-margin-top, 0);
160
+ margin-right: var(--jist-image-margin-right, 0);
161
+ margin-bottom: var(--jist-image-margin-bottom, 0);
162
+ margin-left: var(--jist-image-margin-left, 0);
163
+ }
164
+
165
+ .jist__image img {
166
+ border-radius: inherit;
167
+ }
168
+
169
+ /* ── Dark Mode Defaults ────────────────── */
170
+
171
+ [data-jist-dark] .jist__heading { color: var(--jist-heading-text-color, #ffffff); }
172
+ [data-jist-dark] .jist__text { color: var(--jist-text-text-color, #ffffff); }
173
+ [data-jist-dark] .jist__date { color: var(--jist-date-text-color, #ffffff); }
174
+ [data-jist-dark] .jist__button { color: var(--jist-button-text-color, #ffffff); }
175
+
176
+ /* ── Action (clickable wrapper) ─────────── */
177
+
178
+ .jist__action {
179
+ cursor: pointer;
180
+ -webkit-tap-highlight-color: transparent;
181
+ }
182
+
183
+ .jist__action:focus-visible {
184
+ outline: 2px solid var(--jist-button-background-color, #4f46e5);
185
+ outline-offset: 2px;
186
+ border-radius: 4px;
187
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@customerio/jist",
3
+ "version": "0.1.0",
4
+ "description": "Cross-platform JSON template renderer — web custom element. Renders Jist template trees into native DOM.",
5
+ "type": "module",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "main": "./dist/jist-element.js",
10
+ "module": "./dist/jist-element.js",
11
+ "types": "./dist/jist-element.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/jist-element.d.ts",
15
+ "import": "./dist/jist-element.js"
16
+ },
17
+ "./renderer": {
18
+ "types": "./dist/jist-renderer.d.ts",
19
+ "import": "./dist/jist-renderer.js"
20
+ },
21
+ "./jist.css": "./dist/jist.css"
22
+ },
23
+ "sideEffects": [
24
+ "./dist/jist-element.js",
25
+ "./dist/jist.css"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsc && cp src/jist.css dist/jist.css && cp ../LICENSE dist/LICENSE",
29
+ "test": "playwright test",
30
+ "prepublishOnly": "npm run build"
31
+ },
32
+ "author": "Customer.io (https://customer.io)",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/customerio/jist.git",
37
+ "directory": "web"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/customerio/jist/issues"
41
+ },
42
+ "homepage": "https://github.com/customerio/jist/tree/main/web",
43
+ "keywords": [
44
+ "jist",
45
+ "templates",
46
+ "in-app",
47
+ "messages",
48
+ "web-components",
49
+ "custom-element",
50
+ "customerio"
51
+ ],
52
+ "devDependencies": {
53
+ "@playwright/test": "^1.52.0",
54
+ "serve": "^14.2.4",
55
+ "typescript": "^5.7.0"
56
+ }
57
+ }