@fusion.dev/helix 0.182.2 → 0.184.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/custom-elements.json +477 -116
- package/dist/bar-chart/root/bar-chart-root.css.js +1 -1
- package/dist/code-block/index.d.ts +1 -0
- package/dist/code-block/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/menu/filter/index.d.ts +1 -0
- package/dist/menu/filter/index.js +5 -0
- package/dist/menu/filter/menu-filter.css.d.ts +1 -0
- package/dist/menu/filter/menu-filter.css.js +2 -0
- package/dist/menu/root/menu-root.css.js +1 -1
- package/dist/sandbox/compile.d.ts +63 -0
- package/dist/sandbox/compile.js +52 -0
- package/dist/sandbox/preview/sandbox-preview.d.ts +29 -1
- package/dist/sandbox/preview/sandbox-preview.js +45 -7
- package/dist/sandbox/root/sandbox-root.d.ts +4 -0
- package/dist/sandbox/root/sandbox-root.js +1 -1
- package/lint.json +1 -1
- package/package.json +6 -6
- package/types/jsx.d.ts +144 -16
- package/types/vue.d.ts +36 -6
- package/types/words.d.ts +7 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createSheet } from '@fusion.dev/helix-core';
|
|
2
|
-
export const styles = createSheet(`:host {display: grid;position: relative;gap: var(--bar-chart-gap, var(--helix-space-2xs))}[part="plot"] {position: relative;block-size: var(--bar-chart-block-size, 12em)}[part="plot"] svg {block-size: 100%;inline-size: 100%;overflow: visible}[part="baseline"] {stroke: var(--helix-color-border);stroke-width: var(--helix-border-thin);vector-effect: non-scaling-stroke}[part~="bar"] {--_bar-chart-corners: var(--bar-chart-bar-radius, 2px) var(--bar-chart-bar-radius, 2px) 0 0;--_bar-chart-base: 0 0 calc(var(--bar-chart-bar-stroke, var(--helix-border-thick)) / 2) 0;clip-path: inset(var(--_bar-chart-foot, 0) round var(--_bar-chart-corners));fill: var(--_bar-chart-series)}:host([orientation="horizontal"]) [part~="bar"] {--_bar-chart-corners: 0 var(--bar-chart-bar-radius, 2px) var(--bar-chart-bar-radius, 2px) 0;--_bar-chart-base: 0 0 0 calc(var(--bar-chart-bar-stroke, var(--helix-border-thick)) / 2)}:host([stacked]) [part~="bar"]:not([part~="bar-end"]) {--_bar-chart-corners: 0}[part~="bar-end-negative"] {--_bar-chart-corners: 0 0 var(--bar-chart-bar-radius, 2px) var(--bar-chart-bar-radius, 2px)}:host([orientation="horizontal"]) [part~="bar-end-negative"] {--_bar-chart-corners: var(--bar-chart-bar-radius, 2px) 0 0 var(--bar-chart-bar-radius, 2px)}[part="labels"] {display: grid;grid-auto-columns: 1fr;grid-auto-flow: column}[part="label"] {color: var(--helix-color-foreground-muted);font-size: var(--helix-text-xs);overflow: hidden;text-align: center;text-overflow: ellipsis;white-space: nowrap}:host([orientation="horizontal"]) {grid-template-columns: auto 1fr}:host([orientation="horizontal"]) [part="labels"] {grid-column: 1;grid-row: 1}:host([orientation="horizontal"]) [part="plot"] {grid-column: 2;grid-row: 1}:host([orientation="horizontal"]) [part="labels"] {grid-auto-columns: auto;grid-auto-flow: row;grid-auto-rows: 1fr;align-self: start;block-size: var(--bar-chart-block-size, 12em)}:host([orientation="horizontal"]) [part="label"] {align-self: center;text-align: end}[part~="bar"], [part="line"] {--_bar-chart-series: var(--chart-series)}:host {--bar-chart-tone-accent: var(--helix-color-accent);--bar-chart-tone-danger: var(--helix-color-danger);--bar-chart-tone-info: var(--helix-color-info);--bar-chart-tone-muted: var(--helix-color-foreground-subtle);--bar-chart-tone-primary: var(--helix-color-primary);--bar-chart-tone-success: var(--helix-color-success);--bar-chart-tone-warning: var(--helix-color-warning)}[part="plot"]:has([data-active]) [part~="group"]:not([data-active]) {opacity: 0.45}[part~="group"] {transition: opacity var(--helix-duration-fast) var(--helix-easing-decelerate)}[part~="bar"] {transition: height var(--helix-duration-normal) var(--helix-easing-decelerate), width var(--helix-duration-normal) var(--helix-easing-decelerate), x var(--helix-duration-normal) var(--helix-easing-decelerate), y var(--helix-duration-normal) var(--helix-easing-decelerate)}@starting-style {:host(:not([orientation="horizontal"])) [part~="bar"] {height: 0;y: 100}:host([orientation="horizontal"]) [part~="bar"] {width: 0}}[part="plot"] {cursor: crosshair}[part="gridline"] {stroke: var(--bar-chart-gridline-color, var(--helix-color-border));stroke-width: var(--helix-border-thin);vector-effect: non-scaling-stroke}[part="band"] {fill: var(--bar-chart-band-color, var(--helix-color-surface-sunken))}[part="line"] {fill: none;stroke: var(--bar-chart-line-color, var(--_bar-chart-series, var(--helix-color-series-1)));stroke-linecap: round;stroke-linejoin: round;stroke-width: var(--bar-chart-line-width, var(--_chart-stroke));vector-effect: non-scaling-stroke}:host([secondary]) {grid-template-columns: auto 1fr auto}:host([secondary]) [part="axis"][data-axis="primary"] {grid-column: 1;grid-row: 1}:host([secondary]) [part="plot"] {grid-column: 2;grid-row: 1}[part="axis"][data-axis="secondary"] {--_bar-chart-axis-ink: color-mix(in oklab, var(--bar-chart-secondary) 45%, var(--helix-color-foreground));color: var(--_bar-chart-axis-ink, var(--helix-color-foreground-subtle))}:host([secondary]) [part="axis"][data-axis="secondary"] {grid-column: 3;grid-row: 1}:host([secondary]) [part="labels"] {grid-column: 2;grid-row: 2}:host([orientation="horizontal"][secondary]) {grid-template-columns: auto 1fr;grid-template-rows: auto 1fr auto}:host([orientation="horizontal"][secondary]) [part="axis"][data-axis="secondary"] {grid-column: 2;grid-row: 1}:host([orientation="horizontal"][secondary]) [part="labels"] {grid-column: 1;grid-row: 2}:host([orientation="horizontal"][secondary]) [part="plot"] {grid-column: 2;grid-row: 2}:host([orientation="horizontal"][secondary]) [part="axis"][data-axis="primary"] {grid-column: 2;grid-row: 3}:host([value-axis]:not([secondary]):not([orientation="horizontal"])) {grid-template-columns: auto 1fr}:host([value-axis]:not([secondary]):not([orientation="horizontal"])) [part="axis"][data-axis="primary"] {grid-column: 1;grid-row: 1}:host([value-axis]:not([secondary]):not([orientation="horizontal"])) [part="plot"], :host([value-axis]:not([secondary]):not([orientation="horizontal"])) [part="labels"] {grid-column: 2}:host([value-axis][orientation="horizontal"]:not([secondary])) {grid-template-rows: 1fr auto}:host([value-axis][orientation="horizontal"]:not([secondary])) [part="axis"][data-axis="primary"] {grid-column: 2;grid-row: 2}[part="axis"] {color: var(--helix-color-foreground-subtle);font-size: var(--helix-text-xs);font-variant-numeric: tabular-nums;pointer-events: none;position: relative}:host(:not([orientation="horizontal"])) [part="axis"] {inline-size: var(--bar-chart-axis, 3ch)}:host([orientation="horizontal"]) [part="axis"] {block-size: 1lh}[part="tick"] {position: absolute}:host(:not([orientation="horizontal"])) [part="tick"] {inset-inline-end: 0;translate: 0 -50%}:host([orientation="horizontal"]) [part="tick"] {translate: -50% 0}:host([orientation="horizontal"]:dir(rtl)) [part="tick"] {translate: 50% 0}:host(:not([orientation="horizontal"])) [part="axis"][data-axis="secondary"] [part="tick"] {inset-inline-end: auto;inset-inline-start: 0}[part~="bar"] {fill-opacity: calc(var(--_bar-chart-area, 1) * var(--_bar-chart-through, 1));stroke-opacity: var(--_bar-chart-through, 1)}[part~="bar"][data-emphasis="outlined"], :host([emphasis="outlined"]) [part~="bar"]:not([data-emphasis]) {--_bar-chart-foot: var(--_bar-chart-base);fill: var(--_bar-chart-shade);stroke: var(--_bar-chart-series);stroke-width: var(--bar-chart-bar-stroke, var(--helix-border-thick));vector-effect: non-scaling-stroke}[part~="bar"][data-emphasis="subtle"], :host([emphasis="subtle"]) [part~="bar"]:not([data-emphasis]) {--_bar-chart-area: 0.2;--_bar-chart-foot: var(--_bar-chart-base);stroke: var(--_bar-chart-series);stroke-width: var(--bar-chart-bar-stroke, var(--helix-border-thick));vector-effect: non-scaling-stroke}[part~="bar"] {--_bar-chart-shade: color-mix(in oklab, var(--_bar-chart-series) 60%, var(--helix-color-background))}[part~="bar"][data-material="glass"], :host([material="glass"]) [part~="bar"]:not([data-material]) {--_bar-chart-through: calc(0.62 * var(--helix-material-opacity))}:host([material="frosted"]) [part~="bar"]:not([data-material]) {--_bar-chart-through: calc(0.88 * var(--helix-material-opacity))}:host([wash="gradient"]) [part~="bar"] {fill: var(--chart-bar-wash)}[part="bar-wash-start"] {stop-color: var(--chart-series);stop-opacity: calc(1 * var(--helix-material-opacity))}[part="bar-wash-end"] {stop-color: var(--chart-series);stop-opacity: calc(0.35 * var(--helix-material-opacity))}@media print {:host {print-color-adjust: exact}}[part="summary"] {block-size: 1px;clip-path: inset(50%);inline-size: 1px;margin: var(--helix-space-none);overflow: hidden;position: absolute;white-space: nowrap}`);
|
|
2
|
+
export const styles = createSheet(`:host {display: grid;position: relative;gap: var(--bar-chart-gap, var(--helix-space-2xs))}[part="plot"] {position: relative;block-size: var(--bar-chart-block-size, 12em)}[part="plot"] svg {block-size: 100%;inline-size: 100%;overflow: visible}[part="baseline"] {stroke: var(--helix-color-border);stroke-width: var(--helix-border-thin);vector-effect: non-scaling-stroke}[part~="bar"] {--_bar-chart-corners: var(--bar-chart-bar-radius, 2px) var(--bar-chart-bar-radius, 2px) 0 0;--_bar-chart-base: 0 0 calc(var(--bar-chart-bar-stroke, var(--helix-border-thick)) / 2) 0;clip-path: inset(var(--_bar-chart-foot, 0) round var(--_bar-chart-corners));fill: var(--_bar-chart-series)}:host([orientation="horizontal"]) [part~="bar"] {--_bar-chart-corners: 0 var(--bar-chart-bar-radius, 2px) var(--bar-chart-bar-radius, 2px) 0;--_bar-chart-base: 0 0 0 calc(var(--bar-chart-bar-stroke, var(--helix-border-thick)) / 2)}:host([stacked]) [part~="bar"]:not([part~="bar-end"]) {--_bar-chart-corners: 0}[part~="bar-end-negative"] {--_bar-chart-corners: 0 0 var(--bar-chart-bar-radius, 2px) var(--bar-chart-bar-radius, 2px)}:host([orientation="horizontal"]) [part~="bar-end-negative"] {--_bar-chart-corners: var(--bar-chart-bar-radius, 2px) 0 0 var(--bar-chart-bar-radius, 2px)}[part~="bar-negative"] {--_bar-chart-base: calc(var(--bar-chart-bar-stroke, var(--helix-border-thick)) / 2) 0 0 0}:host([orientation="horizontal"]) [part~="bar-negative"] {--_bar-chart-base: 0 calc(var(--bar-chart-bar-stroke, var(--helix-border-thick)) / 2) 0 0}[part="labels"] {display: grid;grid-auto-columns: 1fr;grid-auto-flow: column}[part="label"] {color: var(--helix-color-foreground-muted);font-size: var(--helix-text-xs);overflow: hidden;text-align: center;text-overflow: ellipsis;white-space: nowrap}:host([orientation="horizontal"]) {grid-template-columns: auto 1fr}:host([orientation="horizontal"]) [part="labels"] {grid-column: 1;grid-row: 1}:host([orientation="horizontal"]) [part="plot"] {grid-column: 2;grid-row: 1}:host([orientation="horizontal"]) [part="labels"] {grid-auto-columns: auto;grid-auto-flow: row;grid-auto-rows: 1fr;align-self: start;block-size: var(--bar-chart-block-size, 12em)}:host([orientation="horizontal"]) [part="label"] {align-self: center;text-align: end}[part~="bar"], [part="line"] {--_bar-chart-series: var(--chart-series)}:host {--bar-chart-tone-accent: var(--helix-color-accent);--bar-chart-tone-danger: var(--helix-color-danger);--bar-chart-tone-info: var(--helix-color-info);--bar-chart-tone-muted: var(--helix-color-foreground-subtle);--bar-chart-tone-primary: var(--helix-color-primary);--bar-chart-tone-success: var(--helix-color-success);--bar-chart-tone-warning: var(--helix-color-warning)}[part="plot"]:has([data-active]) [part~="group"]:not([data-active]) {opacity: 0.45}[part~="group"] {transition: opacity var(--helix-duration-fast) var(--helix-easing-decelerate)}[part~="bar"] {transition: height var(--helix-duration-normal) var(--helix-easing-decelerate), width var(--helix-duration-normal) var(--helix-easing-decelerate), x var(--helix-duration-normal) var(--helix-easing-decelerate), y var(--helix-duration-normal) var(--helix-easing-decelerate)}@starting-style {:host(:not([orientation="horizontal"])) [part~="bar"] {height: 0;y: 100}:host([orientation="horizontal"]) [part~="bar"] {width: 0}}[part="plot"] {cursor: crosshair}[part="gridline"] {stroke: var(--bar-chart-gridline-color, var(--helix-color-border));stroke-width: var(--helix-border-thin);vector-effect: non-scaling-stroke}[part="band"] {fill: var(--bar-chart-band-color, var(--helix-color-surface-sunken))}[part="line"] {fill: none;stroke: var(--bar-chart-line-color, var(--_bar-chart-series, var(--helix-color-series-1)));stroke-linecap: round;stroke-linejoin: round;stroke-width: var(--bar-chart-line-width, var(--_chart-stroke));vector-effect: non-scaling-stroke}:host([secondary]) {grid-template-columns: auto 1fr auto}:host([secondary]) [part="axis"][data-axis="primary"] {grid-column: 1;grid-row: 1}:host([secondary]) [part="plot"] {grid-column: 2;grid-row: 1}[part="axis"][data-axis="secondary"] {--_bar-chart-axis-ink: color-mix(in oklab, var(--bar-chart-secondary) 45%, var(--helix-color-foreground));color: var(--_bar-chart-axis-ink, var(--helix-color-foreground-subtle))}:host([secondary]) [part="axis"][data-axis="secondary"] {grid-column: 3;grid-row: 1}:host([secondary]) [part="labels"] {grid-column: 2;grid-row: 2}:host([orientation="horizontal"][secondary]) {grid-template-columns: auto 1fr;grid-template-rows: auto 1fr auto}:host([orientation="horizontal"][secondary]) [part="axis"][data-axis="secondary"] {grid-column: 2;grid-row: 1}:host([orientation="horizontal"][secondary]) [part="labels"] {grid-column: 1;grid-row: 2}:host([orientation="horizontal"][secondary]) [part="plot"] {grid-column: 2;grid-row: 2}:host([orientation="horizontal"][secondary]) [part="axis"][data-axis="primary"] {grid-column: 2;grid-row: 3}:host([value-axis]:not([secondary]):not([orientation="horizontal"])) {grid-template-columns: auto 1fr}:host([value-axis]:not([secondary]):not([orientation="horizontal"])) [part="axis"][data-axis="primary"] {grid-column: 1;grid-row: 1}:host([value-axis]:not([secondary]):not([orientation="horizontal"])) [part="plot"], :host([value-axis]:not([secondary]):not([orientation="horizontal"])) [part="labels"] {grid-column: 2}:host([value-axis][orientation="horizontal"]:not([secondary])) {grid-template-rows: 1fr auto}:host([value-axis][orientation="horizontal"]:not([secondary])) [part="axis"][data-axis="primary"] {grid-column: 2;grid-row: 2}[part="axis"] {color: var(--helix-color-foreground-subtle);font-size: var(--helix-text-xs);font-variant-numeric: tabular-nums;pointer-events: none;position: relative}:host(:not([orientation="horizontal"])) [part="axis"] {inline-size: var(--bar-chart-axis, 3ch)}:host([orientation="horizontal"]) [part="axis"] {block-size: 1lh}[part="tick"] {position: absolute}:host(:not([orientation="horizontal"])) [part="tick"] {inset-inline-end: 0;translate: 0 -50%}:host([orientation="horizontal"]) [part="tick"] {translate: -50% 0}:host([orientation="horizontal"]:dir(rtl)) [part="tick"] {translate: 50% 0}:host(:not([orientation="horizontal"])) [part="axis"][data-axis="secondary"] [part="tick"] {inset-inline-end: auto;inset-inline-start: 0}[part~="bar"] {fill-opacity: calc(var(--_bar-chart-area, 1) * var(--_bar-chart-through, 1));stroke-opacity: var(--_bar-chart-through, 1)}[part~="bar"][data-emphasis="outlined"], :host([emphasis="outlined"]) [part~="bar"]:not([data-emphasis]) {--_bar-chart-foot: var(--_bar-chart-base);fill: var(--_bar-chart-shade);stroke: var(--_bar-chart-series);stroke-width: var(--bar-chart-bar-stroke, var(--helix-border-thick));vector-effect: non-scaling-stroke}[part~="bar"][data-emphasis="subtle"], :host([emphasis="subtle"]) [part~="bar"]:not([data-emphasis]) {--_bar-chart-area: 0.2;--_bar-chart-foot: var(--_bar-chart-base);stroke: var(--_bar-chart-series);stroke-width: var(--bar-chart-bar-stroke, var(--helix-border-thick));vector-effect: non-scaling-stroke}[part~="bar"] {--_bar-chart-shade: color-mix(in oklab, var(--_bar-chart-series) 60%, var(--helix-color-background))}[part~="bar"][data-material="glass"], :host([material="glass"]) [part~="bar"]:not([data-material]) {--_bar-chart-through: calc(0.62 * var(--helix-material-opacity))}:host([material="frosted"]) [part~="bar"]:not([data-material]) {--_bar-chart-through: calc(0.88 * var(--helix-material-opacity))}:host([wash="gradient"]) [part~="bar"] {fill: var(--chart-bar-wash)}[part="bar-wash-start"] {stop-color: var(--chart-series);stop-opacity: calc(1 * var(--helix-material-opacity))}[part="bar-wash-end"] {stop-color: var(--chart-series);stop-opacity: calc(0.35 * var(--helix-material-opacity))}@media print {:host {print-color-adjust: exact}}[part="summary"] {block-size: 1px;clip-path: inset(50%);inline-size: 1px;margin: var(--helix-space-none);overflow: hidden;position: absolute;white-space: nowrap}`);
|
package/dist/code-block/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export * from './listbox/index.js';
|
|
|
62
62
|
export * from './loader/index.js';
|
|
63
63
|
export * from './map/index.js';
|
|
64
64
|
export * from './megamenu/index.js';
|
|
65
|
+
export * from './menu/filter/index.js';
|
|
65
66
|
export * from './menu/index.js';
|
|
66
67
|
export * from './meter/index.js';
|
|
67
68
|
export * from './navigation/index.js';
|
package/dist/index.js
CHANGED
|
@@ -57,6 +57,7 @@ export * from './listbox/index.js';
|
|
|
57
57
|
export * from './loader/index.js';
|
|
58
58
|
export * from './map/index.js';
|
|
59
59
|
export * from './megamenu/index.js';
|
|
60
|
+
export * from './menu/filter/index.js';
|
|
60
61
|
export * from './menu/index.js';
|
|
61
62
|
export * from './meter/index.js';
|
|
62
63
|
export * from './navigation/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { filterMenu, MenuFilterController } from '@fusion.dev/helix-headless/menu/filter';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { filterMenu } from '@fusion.dev/helix-headless/menu/filter';
|
|
2
|
+
import { HelixMenu } from '../root/menu-root.js';
|
|
3
|
+
import { styles } from './menu-filter.css.js';
|
|
4
|
+
filterMenu(HelixMenu, styles);
|
|
5
|
+
export { filterMenu, MenuFilterController } from '@fusion.dev/helix-headless/menu/filter';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { createSheet } from '@fusion.dev/helix-core';
|
|
2
|
+
export const styles = createSheet(`input {appearance: none;background-color: var(--menu-background-color, var(--helix-color-surface-overlay));border: none;border-block-end: var(--helix-border-thin) solid var(--helix-color-border);box-sizing: border-box;color: var(--helix-color-foreground);display: block;font-family: var(--helix-font-sans);font-size: var(--helix-text-xs);font-weight: var(--helix-weight-medium);inline-size: 100%;inset-block-start: calc(var(--helix-space-xs) * -1);margin-block: calc(var(--helix-space-xs) * -1) var(--helix-space-xs);min-block-size: var(--helix-size-control);padding-inline: var(--helix-space-sm);position: sticky;z-index: 1}input:focus-visible {outline: none}[data-filtered] slot::slotted(helix-divider) {display: none}`);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createSheet } from '@fusion.dev/helix-core';
|
|
2
|
-
export const styles = createSheet(`:host {display: contents}[part="surface"] {--helix-size-control: var(--helix-size-control-sm);--helix-size-control-loose: calc(var(--helix-size-control) * 1.2);--helix-size-control-tight: calc(var(--helix-size-control) * 0.8);--helix-size-icon: var(--helix-size-icon-sm);--helix-size-icon-loose: calc(var(--helix-size-icon) * 1.2);--helix-size-icon-tight: calc(var(--helix-size-icon) * 0.8);--menu-item-start: 0px;--menu-item-end: 0px;max-block-size: var(--menu-max-block-size, var(--floating-available-block-size, none));overflow-y: auto;--_floating-background-color: var(--menu-background-color, var(--helix-color-surface-overlay));--_floating-border-color: var(--menu-border-color, var(--helix-color-border));--_floating-border-width: var(--menu-border-width, var(--helix-border-floating));--_floating-shadow: var(--menu-shadow, var(--helix-shadow-floating));min-inline-size: var(--menu-min-inline-size, 12rem);padding-block: var(--helix-space-xs);padding-inline: var(--helix-space-none)}:host(:state(start)) [part="surface"] {--menu-item-start: calc(var(--helix-size-icon) + var(--helix-space-xs))}:host(:state(mark)) [part="surface"] {--menu-item-end: calc(var(--helix-size-icon) + var(--helix-space-xs))}[part="surface"][data-placement^="left"] {transform-origin: 100% var(--floating-arrow-y, 50%)}[part="surface"][data-placement^="right"] {transform-origin: 0 var(--floating-arrow-y, 50%)}[part="header"] {align-items: center;border-block-end: var(--helix-border-thin) solid var(--helix-color-border);display: flex;gap: var(--helix-space-2xs);margin-block-end: var(--helix-space-2xs);padding: var(--helix-space-2xs) var(--helix-space-xs) var(--helix-space-xs)}[part="back"] {align-items: center;background: none;border: none;border-radius: var(--helix-radii-sm);color: var(--helix-color-foreground-muted);cursor: pointer;display: inline-flex;justify-content: center;block-size: calc(var(--helix-size-icon) + var(--helix-space-xs));inline-size: calc(var(--helix-size-icon) + var(--helix-space-xs));padding: var(--helix-space-none)}[part="back"] svg {block-size: var(--helix-size-icon);inline-size: var(--helix-size-icon)}[part="back"]:hover {background-color: color-mix(in oklab, var(--helix-color-foreground) 8%, transparent);color: var(--helix-color-foreground)}[part="back"]:focus-visible {outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);outline-offset: calc(var(--helix-size-focus-offset) * -1)}[part="title"] {color: var(--helix-color-foreground);font-size: var(--helix-text-xs);font-weight: var(--helix-weight-medium)}::slotted(helix-divider) {margin-block: var(--helix-space-2xs)}[part="surface"][data-drilled] slot::slotted(:not(helix-menu-item)) {display: none}
|
|
2
|
+
export const styles = createSheet(`:host {display: contents}[part="surface"] {--helix-size-control: var(--helix-size-control-sm);--helix-size-control-loose: calc(var(--helix-size-control) * 1.2);--helix-size-control-tight: calc(var(--helix-size-control) * 0.8);--helix-size-icon: var(--helix-size-icon-sm);--helix-size-icon-loose: calc(var(--helix-size-icon) * 1.2);--helix-size-icon-tight: calc(var(--helix-size-icon) * 0.8);--menu-item-start: 0px;--menu-item-end: 0px;max-block-size: var(--menu-max-block-size, var(--floating-available-block-size, none));overflow-y: auto;--_floating-background-color: var(--menu-background-color, var(--helix-color-surface-overlay));--_floating-border-color: var(--menu-border-color, var(--helix-color-border));--_floating-border-width: var(--menu-border-width, var(--helix-border-floating));--_floating-shadow: var(--menu-shadow, var(--helix-shadow-floating));min-inline-size: var(--menu-min-inline-size, 12rem);padding-block: var(--helix-space-xs);padding-inline: var(--helix-space-none)}:host(:state(start)) [part="surface"] {--menu-item-start: calc(var(--helix-size-icon) + var(--helix-space-xs))}:host(:state(mark)) [part="surface"] {--menu-item-end: calc(var(--helix-size-icon) + var(--helix-space-xs))}[part="surface"][data-placement^="left"] {transform-origin: 100% var(--floating-arrow-y, 50%)}[part="surface"][data-placement^="right"] {transform-origin: 0 var(--floating-arrow-y, 50%)}[part="header"] {align-items: center;border-block-end: var(--helix-border-thin) solid var(--helix-color-border);display: flex;gap: var(--helix-space-2xs);margin-block-end: var(--helix-space-2xs);padding: var(--helix-space-2xs) var(--helix-space-xs) var(--helix-space-xs)}[part="back"] {align-items: center;background: none;border: none;border-radius: var(--helix-radii-sm);color: var(--helix-color-foreground-muted);cursor: pointer;display: inline-flex;justify-content: center;block-size: calc(var(--helix-size-icon) + var(--helix-space-xs));inline-size: calc(var(--helix-size-icon) + var(--helix-space-xs));padding: var(--helix-space-none)}[part="back"] svg {block-size: var(--helix-size-icon);inline-size: var(--helix-size-icon)}[part="back"]:hover {background-color: color-mix(in oklab, var(--helix-color-foreground) 8%, transparent);color: var(--helix-color-foreground)}[part="back"]:focus-visible {outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);outline-offset: calc(var(--helix-size-focus-offset) * -1)}[part="title"] {color: var(--helix-color-foreground);font-size: var(--helix-text-xs);font-weight: var(--helix-weight-medium)}::slotted(helix-divider) {margin-block: var(--helix-space-2xs)}[part="surface"][data-drilled] slot::slotted(:not(helix-menu-item)) {display: none}:host([loading]) [part="surface"] {opacity: 0.5}@media print {:host {display: none}}`);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compiler a module file in TypeScript or JSX runs through before the
|
|
3
|
+
* frame loads it, by its npm name and its pinned version.
|
|
4
|
+
*
|
|
5
|
+
* **Sucrase, measured against esbuild-wasm on October 8, 2026**, on a TSX
|
|
6
|
+
* module of 241 lines with the automatic JSX runtime:
|
|
7
|
+
*
|
|
8
|
+
* | | Sucrase 3.35 | esbuild-wasm 0.28 |
|
|
9
|
+
* | --- | --- | --- |
|
|
10
|
+
* | Download, gzip | 48 KB, and 9 KB of `buffer` esm.sh adds | 3.2 MB of WebAssembly, and 19 KB |
|
|
11
|
+
* | First compile | 14 ms | 188 ms, the WebAssembly starting |
|
|
12
|
+
* | Each after | 0.8 ms | 4.6 ms |
|
|
13
|
+
* | Automatic JSX runtime | yes | yes |
|
|
14
|
+
* | Source map | yes | yes |
|
|
15
|
+
*
|
|
16
|
+
* Both compile what a sandbox holds, and neither checks types. esbuild-wasm
|
|
17
|
+
* downloads 56 times as much before the first module runs, which a reader
|
|
18
|
+
* waits through on the first edit of every page. Sucrase also keeps every line
|
|
19
|
+
* where it was, so a line number in an error in the frame is the line in the
|
|
20
|
+
* pane even where a browser ignores the source map.
|
|
21
|
+
*
|
|
22
|
+
* **Loaded the first time a module needs it**, from the preview's `cdn` as a
|
|
23
|
+
* package in `dependencies` is, so the published package carries no compiler
|
|
24
|
+
* and a sandbox with no TypeScript loads none.
|
|
25
|
+
*
|
|
26
|
+
* **In a worker of its own**, which has no access to the page and keeps a
|
|
27
|
+
* long compile off the page's thread. The worker's script is text, so the
|
|
28
|
+
* `import()` of an address known only at run time is one no bundler reads:
|
|
29
|
+
* written in this module, Turbopack refused to build a page that imported
|
|
30
|
+
* it, the TypeScript build having dropped the comments that tell bundlers to
|
|
31
|
+
* leave it alone. The compiler reads the source as text, and the example
|
|
32
|
+
* itself still runs only in the frame.
|
|
33
|
+
*/
|
|
34
|
+
export declare const COMPILER = "sucrase@3.35.1";
|
|
35
|
+
/** Whether a module file is TypeScript or JSX, which a browser cannot run as written. */
|
|
36
|
+
export declare const COMPILED: RegExp;
|
|
37
|
+
/** Sucrase's `transform`, as the worker runs it: rejects with what failed. */
|
|
38
|
+
type Transform = (source: string, options: Record<string, unknown>) => Promise<{
|
|
39
|
+
code: string;
|
|
40
|
+
sourceMap?: Record<string, unknown>;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* The compiler for each `cdn`, so each is set up once a page. A spec puts a
|
|
44
|
+
* stand-in here, for an address of its own.
|
|
45
|
+
*/
|
|
46
|
+
export declare const compilers: Map<string, Transform>;
|
|
47
|
+
/**
|
|
48
|
+
* A module file compiled to JavaScript, with its source map inline, for the
|
|
49
|
+
* frame to load as its other modules.
|
|
50
|
+
*
|
|
51
|
+
* `.ts` is read as TypeScript, `.tsx` as TypeScript with JSX, and `.jsx` as
|
|
52
|
+
* JSX. JSX compiles to the automatic runtime, `react/jsx-runtime`, which an
|
|
53
|
+
* example lists in `dependencies`, or to the runtime a
|
|
54
|
+
* `@jsxImportSource preact` comment in the file names.
|
|
55
|
+
*
|
|
56
|
+
* **What fails to compile still runs, as a module that throws** what the
|
|
57
|
+
* compiler said, such as `Error transforming app.tsx: Unexpected token (2:1)`.
|
|
58
|
+
* The frame reports it as it reports any error an example does not catch, so
|
|
59
|
+
* it shows over the example in the preview's `error` part and in the
|
|
60
|
+
* terminal, and only where the example imports the file.
|
|
61
|
+
*/
|
|
62
|
+
export declare const compile: (cdn: string, path: string, source: string) => Promise<string>;
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const COMPILER = 'sucrase@3.35.1';
|
|
2
|
+
export const COMPILED = /\.(?:[cm]?ts|[jt]sx)$/;
|
|
3
|
+
const WORKER = 'const l={};onmessage=async({data:[i,a,s,o]})=>{let c;try{c=await(l[a]??=import(a))}catch(e){delete l[a];return postMessage([i,,o.filePath+" needs "+a+", which did not load: "+e])}try{postMessage([i,c.transform(s,o)])}catch(e){postMessage([i,,String(e?.message)])}}';
|
|
4
|
+
let worker;
|
|
5
|
+
let sent = 0;
|
|
6
|
+
const owed = new Map();
|
|
7
|
+
const inWorker = (address) => (source, options) => {
|
|
8
|
+
if (!worker) {
|
|
9
|
+
worker = new Worker(URL.createObjectURL(new Blob([WORKER], { type: 'text/javascript' })), {
|
|
10
|
+
type: 'module',
|
|
11
|
+
});
|
|
12
|
+
worker.onmessage = ({ data }) => {
|
|
13
|
+
owed.get(data[0])?.(data);
|
|
14
|
+
owed.delete(data[0]);
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
sent += 1;
|
|
18
|
+
const id = sent;
|
|
19
|
+
worker.postMessage([id, address, source, options]);
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
owed.set(id, ([, result, error]) => (result ? resolve(result) : reject(new Error(error))));
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
export const compilers = new Map();
|
|
25
|
+
const compilerAt = (cdn) => {
|
|
26
|
+
let compiler = compilers.get(cdn);
|
|
27
|
+
if (!compiler) {
|
|
28
|
+
compiler = inWorker(`${cdn}${COMPILER}`);
|
|
29
|
+
compilers.set(cdn, compiler);
|
|
30
|
+
}
|
|
31
|
+
return compiler;
|
|
32
|
+
};
|
|
33
|
+
export const compile = async (cdn, path, source) => {
|
|
34
|
+
try {
|
|
35
|
+
const { code, sourceMap } = await compilerAt(cdn)(source, {
|
|
36
|
+
filePath: path,
|
|
37
|
+
jsxImportSource: /@jsxImportSource\s+(\S+)/.exec(source)?.[1],
|
|
38
|
+
jsxRuntime: 'automatic',
|
|
39
|
+
production: true,
|
|
40
|
+
sourceMapOptions: { compiledFilename: path },
|
|
41
|
+
transforms: [
|
|
42
|
+
...(/tsx?$/.test(path) ? ['typescript'] : []),
|
|
43
|
+
...(/x$/.test(path) ? ['jsx'] : []),
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
const map = JSON.stringify({ ...sourceMap, sourcesContent: [source] });
|
|
47
|
+
return `${code}\n
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return `throw new SyntaxError(${JSON.stringify(error.message)})`;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -73,6 +73,15 @@ export type PreviewMessage = PreviewConsole | PreviewPress | PreviewReady | Prev
|
|
|
73
73
|
* in the `js` pane or in another module loads it. A sandbox writes each pane
|
|
74
74
|
* named for a module file here.
|
|
75
75
|
*
|
|
76
|
+
* **A module in TypeScript or JSX runs too**: a path ending in `.ts`, `.tsx`
|
|
77
|
+
* or `.jsx` is compiled to JavaScript first, and imported by its path or by
|
|
78
|
+
* its path without the extension. The compiler, Sucrase, loads from `cdn` the
|
|
79
|
+
* first time a module needs it, so the package carries none and a preview
|
|
80
|
+
* with no such module loads none. JSX compiles to the automatic runtime,
|
|
81
|
+
* `react/jsx-runtime`, from `dependencies`, or to the one a
|
|
82
|
+
* `@jsxImportSource` comment names. What fails to compile shows in the
|
|
83
|
+
* `error` part as an error the example threw, when the example imports it.
|
|
84
|
+
*
|
|
76
85
|
* **Examples render in a frame**, so an example's styles and scripts do not
|
|
77
86
|
* affect the page around the sandbox, and `position: fixed` stays inside the
|
|
78
87
|
* pane. The frame starts empty, with its own stylesheets and its own custom
|
|
@@ -233,6 +242,16 @@ export declare class HelixSandboxPreview extends HelixElement {
|
|
|
233
242
|
private failedSource;
|
|
234
243
|
/** What the example threw and did not catch, while the preview is `failed`. */
|
|
235
244
|
private failure;
|
|
245
|
+
/** Each module file compiled to JavaScript, by its path and source. */
|
|
246
|
+
private compiled;
|
|
247
|
+
/** The module files being compiled, by their path and source. */
|
|
248
|
+
private readonly compiling;
|
|
249
|
+
/**
|
|
250
|
+
* The import map the built-in document loads with: the last one with every
|
|
251
|
+
* module file compiled, so a frame never loads without one an example
|
|
252
|
+
* imports.
|
|
253
|
+
*/
|
|
254
|
+
private map;
|
|
236
255
|
/** Says the preview failed with `text`, or, with none, that it has not. */
|
|
237
256
|
private fail;
|
|
238
257
|
/** What the frame is sent as its source: the markup, and the script after it. */
|
|
@@ -244,6 +263,11 @@ export declare class HelixSandboxPreview extends HelixElement {
|
|
|
244
263
|
* `dependencies` and the paths under it, and `imports` over all of them.
|
|
245
264
|
*/
|
|
246
265
|
private get importMap();
|
|
266
|
+
/**
|
|
267
|
+
* Compiles a module file, once, then draws again with it. Not on a server,
|
|
268
|
+
* which loads no frame.
|
|
269
|
+
*/
|
|
270
|
+
private compileModule;
|
|
247
271
|
/**
|
|
248
272
|
* The frame's document has finished loading, so its listener exists, the
|
|
249
273
|
* example is sent and the preview is no longer `loading`. The frame saying
|
|
@@ -322,7 +346,10 @@ export declare class HelixSandboxPreview extends HelixElement {
|
|
|
322
346
|
private scheduleSend;
|
|
323
347
|
/** What the frame is sent: the source, its stylesheet and its settings. */
|
|
324
348
|
private get message();
|
|
325
|
-
/**
|
|
349
|
+
/**
|
|
350
|
+
* Sends the current source to the frame, once it is listening and no
|
|
351
|
+
* module it may import is still compiling.
|
|
352
|
+
*/
|
|
326
353
|
private send;
|
|
327
354
|
/**
|
|
328
355
|
* Opens the example in a new tab, and returns the tab's window, or `null`
|
|
@@ -362,6 +389,7 @@ export declare class HelixSandboxPreview extends HelixElement {
|
|
|
362
389
|
* nothing has failed in it. The built-in document loads too.
|
|
363
390
|
*/
|
|
364
391
|
private unready;
|
|
392
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
365
393
|
protected updated(changed: PropertyValues): void;
|
|
366
394
|
/** The reload and open buttons, under `controls`. */
|
|
367
395
|
private renderControls;
|
|
@@ -4,6 +4,7 @@ import { customElement, DelayController, HelixConsoleEvent, HelixElement, HelixR
|
|
|
4
4
|
const SETTLE = 120;
|
|
5
5
|
import { html, nothing } from 'lit';
|
|
6
6
|
import { property, state } from 'lit/decorators.js';
|
|
7
|
+
import { COMPILED, compile } from '../compile.js';
|
|
7
8
|
import { defaultFrame, withScript } from '../frame.js';
|
|
8
9
|
import { styles as sheet } from './sandbox-preview.css.js';
|
|
9
10
|
const SANDBOX = 'allow-scripts allow-forms';
|
|
@@ -22,6 +23,9 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
22
23
|
this.src = '';
|
|
23
24
|
this.styles = '';
|
|
24
25
|
this.ready = false;
|
|
26
|
+
this.compiled = new Map();
|
|
27
|
+
this.compiling = new Set();
|
|
28
|
+
this.map = {};
|
|
25
29
|
this.handleFrameLoad = () => {
|
|
26
30
|
this.ready = true;
|
|
27
31
|
this.toggleState('loading', false);
|
|
@@ -72,11 +76,39 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
72
76
|
map[name] = address;
|
|
73
77
|
map[`${name}/`] = `${address}/`;
|
|
74
78
|
}
|
|
79
|
+
const compiled = new Map();
|
|
75
80
|
for (const [given, source] of Object.entries(this.modules ?? {})) {
|
|
76
81
|
const path = given.replace(/^\.?\//, '');
|
|
77
|
-
|
|
82
|
+
if (!COMPILED.test(path)) {
|
|
83
|
+
map[`./${path}`] = map[`sandbox:/${path}`] = moduleText(path, source);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const key = `${path}\u0000${source}`;
|
|
87
|
+
const code = this.compiled.get(key);
|
|
88
|
+
if (code === undefined) {
|
|
89
|
+
this.compileModule(key, path, source);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
compiled.set(key, code);
|
|
93
|
+
const text = moduleText(path, code);
|
|
94
|
+
const bare = path.replace(COMPILED, '');
|
|
95
|
+
map[`./${path}`] = map[`sandbox:/${path}`] = text;
|
|
96
|
+
map[`./${bare}`] ??= map[`sandbox:/${bare}`] ??= text;
|
|
78
97
|
}
|
|
79
|
-
|
|
98
|
+
this.compiled = compiled;
|
|
99
|
+
return this.compiling.size > 0 ? undefined : { ...map, ...this.imports };
|
|
100
|
+
}
|
|
101
|
+
compileModule(key, path, source) {
|
|
102
|
+
if (this.compiling.has(key) || typeof document === 'undefined') {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.compiling.add(key);
|
|
106
|
+
void compile(this.cdn, path, source).then((code) => {
|
|
107
|
+
this.compiling.delete(key);
|
|
108
|
+
this.compiled.set(key, code);
|
|
109
|
+
this.requestUpdate();
|
|
110
|
+
void this.updateComplete.then(() => this.send());
|
|
111
|
+
});
|
|
80
112
|
}
|
|
81
113
|
static { this.target = '*'; }
|
|
82
114
|
scheduleSend() {
|
|
@@ -98,7 +130,7 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
98
130
|
};
|
|
99
131
|
}
|
|
100
132
|
send() {
|
|
101
|
-
if (!this.ready) {
|
|
133
|
+
if (!this.ready || this.compiling.size > 0) {
|
|
102
134
|
return;
|
|
103
135
|
}
|
|
104
136
|
this.frame?.contentWindow?.postMessage(this.message, HelixSandboxPreview_1.target);
|
|
@@ -118,7 +150,7 @@ let HelixSandboxPreview = class HelixSandboxPreview extends HelixElement {
|
|
|
118
150
|
frame.title = this.label;
|
|
119
151
|
frame.style.cssText = 'block-size: 100vh; border: none; display: block; inline-size: 100vw';
|
|
120
152
|
if (this.src === '') {
|
|
121
|
-
frame.srcdoc = defaultFrame(this.
|
|
153
|
+
frame.srcdoc = defaultFrame(this.map);
|
|
122
154
|
}
|
|
123
155
|
else {
|
|
124
156
|
frame.src = this.frame?.src || this.src;
|
|
@@ -144,7 +176,7 @@ frame.onload = () => frame.contentWindow.postMessage(${JSON.stringify(this.messa
|
|
|
144
176
|
}
|
|
145
177
|
this.unready();
|
|
146
178
|
if (this.src === '') {
|
|
147
|
-
frame.srcdoc = defaultFrame(this.
|
|
179
|
+
frame.srcdoc = defaultFrame(this.map);
|
|
148
180
|
return;
|
|
149
181
|
}
|
|
150
182
|
frame.src = this.src;
|
|
@@ -156,9 +188,15 @@ frame.onload = () => frame.contentWindow.postMessage(${JSON.stringify(this.messa
|
|
|
156
188
|
this.fail();
|
|
157
189
|
this.toggleState('loading', true);
|
|
158
190
|
}
|
|
191
|
+
willUpdate(changed) {
|
|
192
|
+
super.willUpdate(changed);
|
|
193
|
+
if (this.src === '') {
|
|
194
|
+
this.map = this.importMap ?? this.map;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
159
197
|
updated(changed) {
|
|
160
198
|
super.updated(changed);
|
|
161
|
-
const map = this.src === '' ? JSON.stringify(this.
|
|
199
|
+
const map = this.src === '' ? JSON.stringify(this.map) : '';
|
|
162
200
|
const remapped = map !== this.loadedMap;
|
|
163
201
|
this.loadedMap = map;
|
|
164
202
|
if (changed.has('src') || remapped) {
|
|
@@ -189,7 +227,7 @@ frame.onload = () => frame.contentWindow.postMessage(${JSON.stringify(this.messa
|
|
|
189
227
|
part="frame"
|
|
190
228
|
@load=${this.handleFrameLoad}
|
|
191
229
|
src=${this.src || nothing}
|
|
192
|
-
srcdoc=${this.src === '' ? defaultFrame(this.
|
|
230
|
+
srcdoc=${this.src === '' ? defaultFrame(this.map) : nothing}
|
|
193
231
|
title=${this.label}
|
|
194
232
|
aria-describedby=${this.failure === undefined ? nothing : 'error'}
|
|
195
233
|
allow="clipboard-write *; fullscreen *"
|
|
@@ -21,6 +21,10 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
|
21
21
|
* - `js` sets a script that runs as a module after the markup.
|
|
22
22
|
* - A module file name ending in `.js` or `.mjs`, such as `utils.js`, is a
|
|
23
23
|
* module the other scripts import by its path, `./utils.js`.
|
|
24
|
+
* - A module file name ending in `.ts`, `.tsx` or `.jsx`, such as `app.tsx`,
|
|
25
|
+
* is one too, which the preview compiles to JavaScript first. The `js` pane
|
|
26
|
+
* runs it with `import './app.tsx'`. A file that does not compile shows
|
|
27
|
+
* why over the preview, as an error the example threw.
|
|
24
28
|
* - `package.json` sets the npm packages the scripts import by name, from its
|
|
25
29
|
* `dependencies`, which load from the preview's `cdn`.
|
|
26
30
|
*
|
|
@@ -8,7 +8,7 @@ const DEFAULT_SPLIT = 50;
|
|
|
8
8
|
const DEFAULT_PANEL = 160;
|
|
9
9
|
const PANEL_MAX = 0.8;
|
|
10
10
|
const PANE_KEYS = { css: 'styles', html: 'source', js: 'script' };
|
|
11
|
-
const MODULE = /\.m?js$/;
|
|
11
|
+
const MODULE = /\.(?:m?js|[cm]?ts|[jt]sx)$/;
|
|
12
12
|
const MANIFEST = 'package.json';
|
|
13
13
|
const isPaneName = (name) => typeof name === 'string' &&
|
|
14
14
|
(Object.hasOwn(PANE_KEYS, name) || MODULE.test(name) || name === MANIFEST);
|