@fusion.dev/helix 0.143.0 → 0.145.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 +19817 -1238
- package/dist/accordion/item/accordion-item.css.js +14 -3
- package/dist/accordion/item/accordion-item.d.ts +2 -0
- package/dist/aura/palette.d.ts +38 -0
- package/dist/aura/palette.js +22 -0
- package/dist/aura/root/aura-root.css.js +24 -3
- package/dist/aura/root/aura-root.d.ts +42 -7
- package/dist/aura/root/aura-root.js +31 -25
- package/dist/badge/root/badge-root.css.js +35 -0
- package/dist/badge/root/badge-root.d.ts +16 -0
- package/dist/badge/root/badge-root.js +3 -0
- package/dist/blockquote/root/blockquote-root.css.js +5 -5
- package/dist/blockquote/root/blockquote-root.d.ts +5 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.css.js +7 -7
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +5 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.css.js +1 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +3 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +2 -0
- package/dist/button/root/button-root.css.js +38 -1
- package/dist/button/root/button-root.d.ts +5 -0
- package/dist/button/root/button-root.js +2 -1
- package/dist/button-group/root/button-group-root.d.ts +3 -0
- package/dist/callout/root/callout-root.css.js +69 -11
- package/dist/callout/root/callout-root.d.ts +25 -2
- package/dist/callout/root/callout-root.js +4 -0
- package/dist/canvas/root/canvas-root.css.js +1 -0
- package/dist/card/root/card-root.css.js +26 -1
- package/dist/card/root/card-root.d.ts +11 -0
- package/dist/carousel/root/carousel-root.css.js +17 -1
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +2 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +2 -0
- package/dist/code-block/root/code-block-root.css.js +23 -0
- package/dist/code-block/root/code-block-root.d.ts +15 -0
- package/dist/code-block/root/code-block-root.js +8 -0
- package/dist/color-picker/root/color-picker-root.css.js +64 -0
- package/dist/color-picker/root/color-picker-root.d.ts +2 -0
- package/dist/copy-button/root/copy-button-root.css.js +5 -0
- package/dist/data-table/root/data-table-root.css.js +63 -0
- package/dist/data-table/root/data-table-root.d.ts +1 -0
- package/dist/date-input/root/date-input-root.css.js +19 -0
- package/dist/date-input/root/date-input-root.d.ts +8 -0
- package/dist/date-input/root/date-input-root.js +2 -0
- package/dist/date-picker/root/date-picker-root.css.js +68 -0
- package/dist/date-picker/root/date-picker-root.d.ts +1 -0
- package/dist/description-list/item/description-list-item.css.js +11 -0
- package/dist/dialog/root/dialog-root.css.js +47 -0
- package/dist/divider/root/divider-root.css.js +8 -3
- package/dist/divider/root/divider-root.d.ts +17 -1
- package/dist/divider/root/divider-root.js +4 -0
- package/dist/drawer/root/drawer-root.css.js +28 -1
- package/dist/drilldown/item/drilldown-item.css.js +2 -1
- package/dist/drilldown/root/drilldown-root.css.js +2 -1
- package/dist/element-events.generated.js +66 -14
- package/dist/empty/root/empty-root.css.js +9 -9
- package/dist/empty/root/empty-root.d.ts +9 -0
- package/dist/file-input/root/file-input-root.js +2 -0
- package/dist/filter-input/root/filter-input-root.js +2 -0
- package/dist/flex/root/flex-root.css.js +134 -9
- package/dist/flex/root/flex-root.d.ts +51 -5
- package/dist/flex/root/flex-root.js +17 -1
- package/dist/grid/root/grid-root.css.js +114 -11
- package/dist/grid/root/grid-root.d.ts +37 -0
- package/dist/grid/root/grid-root.js +13 -1
- package/dist/heatmap/root/heatmap-root.css.js +33 -5
- package/dist/heatmap/root/heatmap-root.d.ts +4 -1
- package/dist/icon/index.d.ts +1 -0
- package/dist/icon/index.js +1 -0
- package/dist/icon/root/icon-root.d.ts +1 -1
- package/dist/icon/root/icon-root.js +1 -1
- package/dist/icon/root/index.d.ts +2 -0
- package/dist/icon/root/index.js +2 -0
- package/dist/icon-button/root/icon-button-root.css.js +37 -0
- package/dist/icon-button/root/icon-button-root.d.ts +4 -0
- package/dist/icon-button/root/icon-button-root.js +2 -1
- package/dist/input/root/input-root.css.js +3 -3
- package/dist/input/root/input-root.d.ts +3 -0
- package/dist/legend/root/legend-root.css.js +40 -13
- package/dist/legend/root/legend-root.d.ts +6 -0
- package/dist/legend/root/legend-root.js +1 -1
- package/dist/lightbox/root/lightbox-root.css.js +84 -0
- package/dist/lightbox/root/lightbox-root.d.ts +1 -0
- package/dist/list/item/list-item.css.js +21 -1
- package/dist/list/item/list-item.d.ts +3 -0
- package/dist/list/root/list-root.css.js +13 -1
- package/dist/loader/root/loader-root.css.js +10 -0
- package/dist/loader/root/loader-root.d.ts +3 -0
- package/dist/menu/index.d.ts +1 -0
- package/dist/menu/index.js +1 -0
- package/dist/menu/item/menu-item.css.js +15 -1
- package/dist/menu/item/menu-item.d.ts +3 -0
- package/dist/menu/item/menu-item.js +2 -0
- package/dist/menu/section/menu-section.css.d.ts +1 -0
- package/dist/menu/section/menu-section.css.js +14 -0
- package/dist/menu/section/menu-section.d.ts +24 -0
- package/dist/menu/section/menu-section.js +16 -0
- package/dist/meter/root/meter-root.css.js +23 -1
- package/dist/meter/root/meter-root.d.ts +5 -0
- package/dist/navigation/root/navigation-root.css.js +3 -2
- package/dist/navigation/root/navigation-root.d.ts +6 -0
- package/dist/notifications/notification/notification.css.js +5 -0
- package/dist/notifications/root/notifications-root.css.js +24 -1
- package/dist/notifications/root/notifications-root.d.ts +1 -0
- package/dist/number-input/root/number-input-root.css.js +3 -3
- package/dist/number-input/root/number-input-root.d.ts +3 -0
- package/dist/object-inspector/root/object-inspector-root.css.js +36 -1
- package/dist/object-inspector/root/object-inspector-root.d.ts +4 -1
- package/dist/object-inspector/root/object-inspector-root.js +2 -1
- package/dist/orb/index.d.ts +1 -1
- package/dist/orb/index.js +1 -1
- package/dist/orb/root/orb-root.d.ts +31 -5
- package/dist/orb/root/orb-root.js +33 -4
- package/dist/outline/root/outline-root.css.js +10 -0
- package/dist/outline/root/outline-root.d.ts +7 -0
- package/dist/pin-input/root/pin-input-root.css.js +12 -5
- package/dist/pin-input/root/pin-input-root.d.ts +5 -0
- package/dist/popover/root/popover-root.css.js +36 -0
- package/dist/popover/root/popover-root.d.ts +1 -0
- package/dist/progress/root/progress-root.css.js +22 -1
- package/dist/progress/root/progress-root.d.ts +5 -0
- package/dist/quote/root/quote-root.css.js +1 -1
- package/dist/quote/root/quote-root.d.ts +1 -0
- package/dist/sandbox/frame.d.ts +63 -0
- package/dist/sandbox/frame.js +132 -0
- package/dist/sandbox/index.d.ts +1 -0
- package/dist/sandbox/index.js +1 -0
- package/dist/sandbox/levels.d.ts +10 -0
- package/dist/sandbox/levels.js +5 -0
- package/dist/sandbox/root/sandbox-root.d.ts +3 -0
- package/dist/sandbox/root/sandbox-root.js +13 -3
- package/dist/sandbox/source/sandbox-source.d.ts +1 -0
- package/dist/sandbox/source/sandbox-source.js +7 -3
- package/dist/sandbox/terminal/sandbox-terminal.css.js +39 -0
- package/dist/sandbox/terminal/sandbox-terminal.d.ts +42 -1
- package/dist/sandbox/terminal/sandbox-terminal.js +47 -3
- package/dist/scroll-area/root/scroll-area-root.css.js +83 -1
- package/dist/scroll-area/root/scroll-area-root.d.ts +6 -0
- package/dist/shared/chart/tooltip.css.js +25 -2
- package/dist/shared/field/field-segments.css.d.ts +1 -0
- package/dist/shared/field/field-segments.css.js +40 -0
- package/dist/skeleton/root/skeleton-root.css.js +56 -5
- package/dist/skeleton/root/skeleton-root.d.ts +17 -1
- package/dist/skeleton/root/skeleton-root.js +3 -0
- package/dist/skip-link/root/skip-link-root.css.js +8 -8
- package/dist/skip-link/root/skip-link-root.d.ts +9 -0
- package/dist/speed-dial/item/speed-dial-item.css.js +11 -4
- package/dist/speed-dial/item/speed-dial-item.d.ts +4 -0
- package/dist/speed-dial/root/speed-dial-root.css.js +7 -3
- package/dist/speed-dial/root/speed-dial-root.d.ts +9 -0
- package/dist/speed-dial/root/speed-dial-root.js +4 -0
- package/dist/stat/root/stat-root.css.js +7 -7
- package/dist/stat/root/stat-root.d.ts +8 -0
- package/dist/steps/step/step.js +2 -1
- package/dist/switch/root/switch-root.css.js +13 -5
- package/dist/switch/root/switch-root.d.ts +25 -1
- package/dist/switch/root/switch-root.js +7 -0
- package/dist/table/root/table-root.css.js +18 -0
- package/dist/table/root/table-root.d.ts +6 -0
- package/dist/table/root/table-root.js +2 -0
- package/dist/table/row/table-row.css.js +18 -0
- package/dist/table/row/table-row.d.ts +2 -0
- package/dist/table/row/table-row.js +2 -0
- package/dist/tabs/panel/tab-panel.css.js +5 -1
- package/dist/tabs/root/tabs-root.css.js +56 -1
- package/dist/tabs/tab/tab.css.js +5 -1
- package/dist/tag/group/tag-group.css.d.ts +1 -0
- package/dist/tag/group/tag-group.css.js +6 -0
- package/dist/tag/group/tag-group.d.ts +25 -0
- package/dist/tag/group/tag-group.js +16 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.css.js +50 -0
- package/dist/tag/root/tag-root.d.ts +4 -0
- package/dist/text/clamp.d.ts +8 -0
- package/dist/text/clamp.js +1 -0
- package/dist/text/root/text-root.css.js +85 -45
- package/dist/text/root/text-root.d.ts +48 -7
- package/dist/text/root/text-root.js +17 -11
- package/dist/textarea/root/textarea-root.css.js +12 -4
- package/dist/textarea/root/textarea-root.d.ts +4 -0
- package/dist/time-input/root/time-input-root.css.js +19 -0
- package/dist/time-input/root/time-input-root.d.ts +8 -0
- package/dist/time-input/root/time-input-root.js +2 -0
- package/dist/timeline/group/timeline-group.css.d.ts +1 -0
- package/dist/timeline/group/timeline-group.css.js +32 -0
- package/dist/timeline/group/timeline-group.d.ts +25 -0
- package/dist/timeline/group/timeline-group.js +16 -0
- package/dist/timeline/index.d.ts +1 -0
- package/dist/timeline/index.js +1 -0
- package/dist/timeline/item/timeline-item.css.js +43 -16
- package/dist/timeline/root/timeline-root.css.js +56 -0
- package/dist/timeline/root/timeline-root.d.ts +26 -0
- package/dist/timeline/root/timeline-root.js +7 -0
- package/dist/toast/item/toast-item.css.js +16 -0
- package/dist/toggle/group/toggle-group.css.js +16 -0
- package/dist/toolbar/root/toolbar-root.css.js +3 -0
- package/dist/toolbar/root/toolbar-root.d.ts +3 -0
- package/dist/tour/root/tour-root.css.js +8 -0
- package/dist/tour/stop/tour-stop.css.js +32 -0
- package/dist/tree/item/tree-item.css.js +72 -0
- package/dist/tree/item/tree-item.d.ts +10 -0
- package/dist/trend/root/trend-root.css.js +12 -5
- package/dist/trend/root/trend-root.d.ts +6 -1
- package/dist/video/root/video-root.css.js +6 -0
- package/dist/video/root/video-root.d.ts +3 -0
- package/dist/virtual-list/root/virtual-list-root.css.js +5 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +4 -3
- package/lint.json +1 -1
- package/package.json +6 -6
- package/types/jsx.d.ts +8620 -813
- package/types/svelte.d.ts +3 -0
- package/types/vue.d.ts +2372 -213
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { PreviewRender } from './preview/sandbox-preview.js';
|
|
2
|
+
/** How `servePreview` serves a frame document. */
|
|
3
|
+
export interface ServePreviewOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The element each example is written into. Defaults to `#preview-root`,
|
|
6
|
+
* and to the body where there is none.
|
|
7
|
+
*/
|
|
8
|
+
root?: HTMLElement;
|
|
9
|
+
/**
|
|
10
|
+
* Whether the frame adds the rules for the four `layout` values, `padded`,
|
|
11
|
+
* `centered`, `hug` and `fullscreen`, to its own head. Defaults to `true`.
|
|
12
|
+
* Set `false` where your frame's stylesheet places the root itself.
|
|
13
|
+
*/
|
|
14
|
+
layouts?: boolean;
|
|
15
|
+
/** Called before new markup replaces the old, to take down what it mounted. */
|
|
16
|
+
onReplace?: (root: HTMLElement) => void;
|
|
17
|
+
/** Called after each render, with whether the markup was new or only restyled. */
|
|
18
|
+
onRender?: (root: HTMLElement, fresh: boolean) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The rules that place the root for each `layout` a preview sends.
|
|
22
|
+
*
|
|
23
|
+
* `centered` gives the example a measure and centers that box, and `hug`
|
|
24
|
+
* shrinks each top-level child to its own content and centers it, which is
|
|
25
|
+
* the difference for a component whose root is a full-width block. They
|
|
26
|
+
* select the root by its `data-preview-root` attribute, so they reach nothing
|
|
27
|
+
* an example draws inside it.
|
|
28
|
+
*/
|
|
29
|
+
export declare const LAYOUT_RULES = "\n:root { --preview-measure: 48rem; }\n[data-preview-root][data-layout=\"padded\"] { padding: var(--helix-space-lg, 1.5rem); }\n[data-preview-root][data-layout=\"centered\"], [data-preview-root][data-layout=\"hug\"] {\n align-content: center; display: block; inline-size: min(100%, var(--preview-measure));\n margin-inline: auto; min-block-size: 100dvh; padding: var(--helix-space-lg, 1.5rem);\n}\n[data-preview-root][data-layout=\"centered\"] { text-align: center; }\n[data-preview-root][data-layout=\"centered\"] > * { margin-inline: auto; text-align: start; }\n[data-preview-root][data-layout=\"hug\"] > * {\n inline-size: fit-content; margin-inline: auto; max-inline-size: 100%;\n}\n[data-preview-root][data-layout=\"fullscreen\"] { min-block-size: 100dvh; padding: 0; }\n";
|
|
30
|
+
/** Whether `data` is a render message, as the preview sends one. */
|
|
31
|
+
export declare const isRender: (data: unknown) => data is PreviewRender;
|
|
32
|
+
/**
|
|
33
|
+
* The markup an example renders, without the stylesheet links it carries.
|
|
34
|
+
*
|
|
35
|
+
* An example that needs CSS says so the way a consumer would, with a `<link>`
|
|
36
|
+
* beside it, and the stylesheet arrives in the render message already read.
|
|
37
|
+
* The frame is on an opaque origin, so a request for the link would fail and
|
|
38
|
+
* log an error into the reader's console on every render.
|
|
39
|
+
*/
|
|
40
|
+
export declare const withoutStylesheets: (source: string) => string;
|
|
41
|
+
/** A logged value as text, without throwing on a cycle. */
|
|
42
|
+
export declare const loggedText: (value: unknown) => string;
|
|
43
|
+
/**
|
|
44
|
+
* Serves the frame side of a sandbox preview, in the document its `src` loads.
|
|
45
|
+
*
|
|
46
|
+
* Call it once from that document, after the elements your examples use are
|
|
47
|
+
* defined. It does what the preview's protocol asks of a frame:
|
|
48
|
+
*
|
|
49
|
+
* - Posts `helix-preview-ready` once it listens.
|
|
50
|
+
* - Writes each `helix-preview-render` into the root: the markup, the
|
|
51
|
+
* stylesheet, the direction, the layout and the color mode. Scripts in the
|
|
52
|
+
* markup run.
|
|
53
|
+
* - Posts every console call and uncaught error as `helix-preview-console`.
|
|
54
|
+
* - Posts `helix-preview-size` whenever what was drawn changes height.
|
|
55
|
+
* - Posts `helix-preview-press` on every press, so menus outside close.
|
|
56
|
+
*
|
|
57
|
+
* Only a message from the parent window is rendered. Answers go to `*`, which
|
|
58
|
+
* is the only target a sandboxed frame can name, and carry only what the
|
|
59
|
+
* example itself wrote.
|
|
60
|
+
*
|
|
61
|
+
* @returns A function that stops serving and puts the console back.
|
|
62
|
+
*/
|
|
63
|
+
export declare const servePreview: (options?: ServePreviewOptions) => (() => void);
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export const LAYOUT_RULES = `
|
|
2
|
+
:root { --preview-measure: 48rem; }
|
|
3
|
+
[data-preview-root][data-layout="padded"] { padding: var(--helix-space-lg, 1.5rem); }
|
|
4
|
+
[data-preview-root][data-layout="centered"], [data-preview-root][data-layout="hug"] {
|
|
5
|
+
align-content: center; display: block; inline-size: min(100%, var(--preview-measure));
|
|
6
|
+
margin-inline: auto; min-block-size: 100dvh; padding: var(--helix-space-lg, 1.5rem);
|
|
7
|
+
}
|
|
8
|
+
[data-preview-root][data-layout="centered"] { text-align: center; }
|
|
9
|
+
[data-preview-root][data-layout="centered"] > * { margin-inline: auto; text-align: start; }
|
|
10
|
+
[data-preview-root][data-layout="hug"] > * {
|
|
11
|
+
inline-size: fit-content; margin-inline: auto; max-inline-size: 100%;
|
|
12
|
+
}
|
|
13
|
+
[data-preview-root][data-layout="fullscreen"] { min-block-size: 100dvh; padding: 0; }
|
|
14
|
+
`;
|
|
15
|
+
export const isRender = (data) => typeof data === 'object' &&
|
|
16
|
+
data !== null &&
|
|
17
|
+
data.type === 'helix-preview-render';
|
|
18
|
+
export const withoutStylesheets = (source) => source.replace(/<link\b[^>]*\brel=(["'])stylesheet\1[^>]*>\s*/gi, '');
|
|
19
|
+
export const loggedText = (value) => {
|
|
20
|
+
if (typeof value === 'string') {
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
return JSON.stringify(value) ?? String(value);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return String(value);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const runScripts = (root) => {
|
|
31
|
+
for (const original of [...root.querySelectorAll('script')]) {
|
|
32
|
+
const script = document.createElement('script');
|
|
33
|
+
for (const { name, value } of original.attributes) {
|
|
34
|
+
script.setAttribute(name, value);
|
|
35
|
+
}
|
|
36
|
+
if (!script.type) {
|
|
37
|
+
script.type = 'module';
|
|
38
|
+
}
|
|
39
|
+
script.text = original.text;
|
|
40
|
+
original.replaceWith(script);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const drawn = (child) => {
|
|
44
|
+
const own = child.getBoundingClientRect();
|
|
45
|
+
if (own.width > 0 || own.height > 0) {
|
|
46
|
+
return [own];
|
|
47
|
+
}
|
|
48
|
+
return [...child.querySelectorAll('*')]
|
|
49
|
+
.filter((node) => getComputedStyle(node).position !== 'fixed')
|
|
50
|
+
.map((node) => node.getBoundingClientRect())
|
|
51
|
+
.filter((box) => box.width > 0 || box.height > 0);
|
|
52
|
+
};
|
|
53
|
+
export const servePreview = (options = {}) => {
|
|
54
|
+
const root = options.root ?? document.getElementById('preview-root') ?? document.body;
|
|
55
|
+
root.toggleAttribute('data-preview-root', true);
|
|
56
|
+
root.dataset.layout ??= 'padded';
|
|
57
|
+
if (options.layouts !== false) {
|
|
58
|
+
const rules = document.createElement('style');
|
|
59
|
+
rules.textContent = LAYOUT_RULES;
|
|
60
|
+
document.head.prepend(rules);
|
|
61
|
+
}
|
|
62
|
+
const post = (message) => window.parent?.postMessage(message, '*');
|
|
63
|
+
const levels = ['log', 'info', 'warn', 'error'];
|
|
64
|
+
const originals = levels.map((level) => console[level]);
|
|
65
|
+
for (const level of levels) {
|
|
66
|
+
const original = console[level];
|
|
67
|
+
console[level] = (...args) => {
|
|
68
|
+
original(...args);
|
|
69
|
+
post({ level, text: args.map(loggedText).join(' '), type: 'helix-preview-console' });
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const failed = (event) => {
|
|
73
|
+
post({ level: 'error', text: event.message, type: 'helix-preview-console' });
|
|
74
|
+
};
|
|
75
|
+
const measure = () => {
|
|
76
|
+
const boxes = [...root.children].flatMap(drawn);
|
|
77
|
+
if (boxes.length === 0) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const top = Math.min(...boxes.map((box) => box.top));
|
|
81
|
+
const bottom = Math.max(...boxes.map((box) => box.bottom));
|
|
82
|
+
const style = getComputedStyle(root);
|
|
83
|
+
const padding = (Number.parseFloat(style.paddingBlockStart) || 0) +
|
|
84
|
+
(Number.parseFloat(style.paddingBlockEnd) || 0);
|
|
85
|
+
post({ size: Math.ceil(bottom - top + padding), type: 'helix-preview-size' });
|
|
86
|
+
};
|
|
87
|
+
let rendered;
|
|
88
|
+
const render = (event) => {
|
|
89
|
+
if (!isRender(event.data) || event.source !== window.parent) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const { colorMode, direction = 'ltr', layout = 'padded', source = '', styles = '' } = event.data;
|
|
93
|
+
document.documentElement.dir = direction;
|
|
94
|
+
root.dataset.layout = layout;
|
|
95
|
+
if (colorMode) {
|
|
96
|
+
document.documentElement.dataset.colorMode = colorMode;
|
|
97
|
+
document.documentElement.style.colorScheme = colorMode;
|
|
98
|
+
}
|
|
99
|
+
const fresh = source !== rendered;
|
|
100
|
+
if (fresh) {
|
|
101
|
+
options.onReplace?.(root);
|
|
102
|
+
root.innerHTML = withoutStylesheets(source);
|
|
103
|
+
runScripts(root);
|
|
104
|
+
rendered = source;
|
|
105
|
+
}
|
|
106
|
+
let sheet = document.getElementById('preview-styles');
|
|
107
|
+
if (!sheet) {
|
|
108
|
+
sheet = document.createElement('style');
|
|
109
|
+
sheet.id = 'preview-styles';
|
|
110
|
+
document.head.append(sheet);
|
|
111
|
+
}
|
|
112
|
+
sheet.textContent = styles;
|
|
113
|
+
options.onRender?.(root, fresh);
|
|
114
|
+
measure();
|
|
115
|
+
};
|
|
116
|
+
const press = () => post({ type: 'helix-preview-press' });
|
|
117
|
+
const watcher = new ResizeObserver(measure);
|
|
118
|
+
watcher.observe(root);
|
|
119
|
+
window.addEventListener('error', failed);
|
|
120
|
+
window.addEventListener('message', render);
|
|
121
|
+
document.addEventListener('pointerdown', press, { capture: true, passive: true });
|
|
122
|
+
post({ type: 'helix-preview-ready' });
|
|
123
|
+
return () => {
|
|
124
|
+
levels.forEach((level, index) => {
|
|
125
|
+
console[level] = originals[index];
|
|
126
|
+
});
|
|
127
|
+
watcher.disconnect();
|
|
128
|
+
window.removeEventListener('error', failed);
|
|
129
|
+
window.removeEventListener('message', render);
|
|
130
|
+
document.removeEventListener('pointerdown', press, { capture: true });
|
|
131
|
+
};
|
|
132
|
+
};
|
package/dist/sandbox/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* hardcodes `sandbox="allow-scripts allow-forms"` on its frame and never
|
|
13
13
|
* `allow-same-origin`, which is the pairing that would undo it.
|
|
14
14
|
*/
|
|
15
|
+
export { isRender, LAYOUT_RULES, loggedText, type ServePreviewOptions, servePreview, withoutStylesheets, } from './frame.js';
|
|
15
16
|
export * from './preview/sandbox-preview.js';
|
|
16
17
|
export * from './root/sandbox-root.js';
|
|
17
18
|
export * from './source/sandbox-source.js';
|
package/dist/sandbox/index.js
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ConsoleDetail } from '@fusion.dev/helix-core';
|
|
2
|
+
/** A console level, from the quietest to the loudest. */
|
|
3
|
+
export type ConsoleLevel = ConsoleDetail['level'];
|
|
4
|
+
/** The four levels in order, the quietest first. */
|
|
5
|
+
export declare const LEVELS: readonly ConsoleLevel[];
|
|
6
|
+
/**
|
|
7
|
+
* Whether a line at `level` shows under a terminal's `level`, which is the
|
|
8
|
+
* quietest it shows. No floor, or one that names no level, shows every line.
|
|
9
|
+
*/
|
|
10
|
+
export declare const shows: (level: ConsoleLevel, floor: string | undefined) => boolean;
|
|
@@ -36,7 +36,10 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
|
|
|
36
36
|
* @event {HelixBeforeSplitEvent} helix-before-split - Fired before the panes' divider is released, with the lead pane's share. Cancelable: cancel it to keep the current split.
|
|
37
37
|
* @event {HelixCaretEvent} helix-caret - Fired when the cursor moves in the source. The source pane dispatches it, and you can listen for it on the sandbox.
|
|
38
38
|
* @event {HelixConsoleEvent} helix-console - Fired once per console call in the preview frame. The preview pane dispatches it.
|
|
39
|
+
* @event {HelixEditEvent} helix-edit - Fired after the source was edited, with the new source. The source pane dispatches it, and you can listen for it on the sandbox.
|
|
40
|
+
* @event {HelixPanelResizeEvent} helix-panel-resize - Fired after the panel's divider settled at a new height, with the height in pixels.
|
|
39
41
|
* @event {HelixResizeEvent} helix-resize - Fired by the preview pane when the height of the frame's content changes, with the new height.
|
|
42
|
+
* @event {HelixSplitEvent} helix-split - Fired after the panes' divider settled somewhere new, with the lead pane's share.
|
|
40
43
|
*
|
|
41
44
|
* @csspart body - The splitter holding the panes above the panel.
|
|
42
45
|
* @csspart corner - The handle where the two dividers cross.
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixBeforePanelResizeEvent, HelixBeforeSplitEvent, HelixElement, requestChange, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixBeforePanelResizeEvent, HelixBeforeSplitEvent, HelixElement, HelixPanelResizeEvent, HelixSplitEvent, requestChange, } from '@fusion.dev/helix-core';
|
|
8
8
|
import '../../splitter/index.js';
|
|
9
9
|
import { html } from 'lit';
|
|
10
10
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -164,7 +164,8 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
|
|
|
164
164
|
return this.orientation ?? 'horizontal';
|
|
165
165
|
}
|
|
166
166
|
requestSplit(next) {
|
|
167
|
-
|
|
167
|
+
const was = this.split;
|
|
168
|
+
const accepted = requestChange({
|
|
168
169
|
apply: (value) => {
|
|
169
170
|
this.split = value;
|
|
170
171
|
},
|
|
@@ -172,9 +173,14 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
|
|
|
172
173
|
host: this,
|
|
173
174
|
next,
|
|
174
175
|
});
|
|
176
|
+
if (accepted && this.split !== was) {
|
|
177
|
+
this.dispatchEvent(new HelixSplitEvent({ value: String(this.split) }));
|
|
178
|
+
}
|
|
179
|
+
return accepted;
|
|
175
180
|
}
|
|
176
181
|
requestPanelSize(next) {
|
|
177
|
-
|
|
182
|
+
const was = this.panelSize;
|
|
183
|
+
const accepted = requestChange({
|
|
178
184
|
apply: (value) => {
|
|
179
185
|
this.panelSize = value;
|
|
180
186
|
},
|
|
@@ -182,6 +188,10 @@ let HelixSandbox = class HelixSandbox extends HelixElement {
|
|
|
182
188
|
host: this,
|
|
183
189
|
next,
|
|
184
190
|
});
|
|
191
|
+
if (accepted && this.panelSize !== was) {
|
|
192
|
+
this.dispatchEvent(new HelixPanelResizeEvent({ value: String(this.panelSize) }));
|
|
193
|
+
}
|
|
194
|
+
return accepted;
|
|
185
195
|
}
|
|
186
196
|
answer(divider, position) {
|
|
187
197
|
const target = divider;
|
|
@@ -18,6 +18,7 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
|
18
18
|
*
|
|
19
19
|
* @event {HelixBeforeEditEvent} helix-before-edit - Fired before the source is edited. Cancelable: cancel it to keep the source unchanged.
|
|
20
20
|
* @event {HelixCaretEvent} helix-caret - Fired when the cursor moves.
|
|
21
|
+
* @event {HelixEditEvent} helix-edit - Fired after the source was edited, with the new source.
|
|
21
22
|
*
|
|
22
23
|
* @csspart source - The editable region.
|
|
23
24
|
*
|
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { customElement, HelixBeforeEditEvent, HelixCaretEvent, HelixElement, onUnlessFalse, restoreValue, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, HelixBeforeEditEvent, HelixCaretEvent, HelixEditEvent, HelixElement, onUnlessFalse, restoreValue, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { styles } from './sandbox-source.css.js';
|
|
@@ -13,7 +13,7 @@ let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
|
|
|
13
13
|
constructor() {
|
|
14
14
|
super(...arguments);
|
|
15
15
|
this.fieldLabel = 'Example source';
|
|
16
|
-
this.keysDescription = 'Tab inserts two spaces. To leave, press Escape and then Tab.';
|
|
16
|
+
this.keysDescription = 'Tab inserts two spaces. To leave, press Escape and then Tab, or press Shift+Tab to go back.';
|
|
17
17
|
this.name = 'html';
|
|
18
18
|
this.tabIndents = true;
|
|
19
19
|
this.value = '';
|
|
@@ -55,10 +55,14 @@ let HelixSandboxSource = class HelixSandboxSource extends HelixElement {
|
|
|
55
55
|
}
|
|
56
56
|
edit(field, next) {
|
|
57
57
|
const request = new HelixBeforeEditEvent({ value: next });
|
|
58
|
-
|
|
58
|
+
const accepted = this.dispatchEvent(request);
|
|
59
|
+
if (accepted) {
|
|
59
60
|
this.value = next;
|
|
60
61
|
}
|
|
61
62
|
restoreValue(field, this.value);
|
|
63
|
+
if (accepted) {
|
|
64
|
+
this.dispatchEvent(new HelixEditEvent({ value: next }));
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
render() {
|
|
64
68
|
return html `<textarea
|
|
@@ -7,6 +7,45 @@ grid-template-rows: minmax(0, 1fr);
|
|
|
7
7
|
min-block-size: 0;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
:host([controls]) {
|
|
11
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
[part="controls"] {
|
|
15
|
+
align-items: center;
|
|
16
|
+
border-block-end: var(--helix-border-thin) solid var(--helix-color-border);
|
|
17
|
+
display: flex;
|
|
18
|
+
font-family: var(--helix-font-sans);
|
|
19
|
+
font-size: var(--helix-text-xs);
|
|
20
|
+
gap: var(--helix-space-xs);
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
padding: var(--helix-space-2xs) var(--helix-space-sm);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[part="filter"],
|
|
26
|
+
[part="clear"] {
|
|
27
|
+
background-color: transparent;
|
|
28
|
+
border: var(--helix-border-thin) solid var(--helix-color-border);
|
|
29
|
+
border-radius: var(--helix-radii-sm);
|
|
30
|
+
color: var(--helix-color-foreground);
|
|
31
|
+
font: inherit;
|
|
32
|
+
padding: var(--helix-space-2xs) var(--helix-space-xs);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
[part="clear"] {
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[part="clear"]:hover {
|
|
40
|
+
background-color: var(--helix-color-surface-sunken);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[part="filter"]:focus-visible,
|
|
44
|
+
[part="clear"]:focus-visible {
|
|
45
|
+
outline: var(--helix-size-focus-ring) solid var(--helix-color-focus-ring);
|
|
46
|
+
outline-offset: var(--helix-size-focus-offset);
|
|
47
|
+
}
|
|
48
|
+
|
|
10
49
|
[part="log"] {
|
|
11
50
|
font-family: var(--helix-font-mono);
|
|
12
51
|
font-size: var(--helix-text-xs);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ConsoleDetail, HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
3
|
+
import { type ConsoleLevel } from '../levels.js';
|
|
3
4
|
/**
|
|
4
5
|
* @summary A panel that shows what the previewed example wrote to the console.
|
|
5
6
|
*
|
|
@@ -17,14 +18,21 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
|
17
18
|
* level is read before it, except a plain `log`, so an error does not sound
|
|
18
19
|
* like any other line.
|
|
19
20
|
*
|
|
21
|
+
* **`controls` adds a clear button and a level filter** above the log. Both
|
|
22
|
+
* are also yours to drive without them: `clear()` empties the log, and
|
|
23
|
+
* `level` hides the quieter lines.
|
|
24
|
+
*
|
|
20
25
|
* @since 0.1.0
|
|
21
26
|
* @status stable
|
|
22
27
|
* @aliases Console, Output
|
|
23
28
|
* @documentation https://fusion.dev/helix/components/sandbox
|
|
24
29
|
*
|
|
30
|
+
* @csspart clear - The button that empties the log, under `controls`.
|
|
31
|
+
* @csspart controls - The row holding the clear button and the level filter, under `controls`.
|
|
25
32
|
* @csspart count - How many times a repeated line was written.
|
|
26
|
-
* @csspart empty - Shown while nothing has been written.
|
|
33
|
+
* @csspart empty - Shown while nothing has been written, or while the level filter hides every line.
|
|
27
34
|
* @csspart entry - One line.
|
|
35
|
+
* @csspart filter - The level filter, a native select, under `controls`.
|
|
28
36
|
* @csspart level - The console level a line was written at.
|
|
29
37
|
* @csspart log - The scrolling region.
|
|
30
38
|
* @csspart message - The text of a line.
|
|
@@ -32,6 +40,17 @@ import type { CSSResultGroup, TemplateResult } from 'lit';
|
|
|
32
40
|
* @cssproperty --sandbox-terminal-size - Height of the scrolling region.
|
|
33
41
|
*/
|
|
34
42
|
export declare class HelixSandboxTerminal extends HelixElement {
|
|
43
|
+
/**
|
|
44
|
+
* The clear button's text, under `controls`.
|
|
45
|
+
*/
|
|
46
|
+
clearLabel: string;
|
|
47
|
+
/**
|
|
48
|
+
* Shows a clear button and a level filter above the log.
|
|
49
|
+
*
|
|
50
|
+
* Off by default, because a sandbox that puts the terminal in a panel often
|
|
51
|
+
* has a toolbar of its own for them.
|
|
52
|
+
*/
|
|
53
|
+
controls: boolean;
|
|
35
54
|
/**
|
|
36
55
|
* Text shown before anything has been written.
|
|
37
56
|
*/
|
|
@@ -40,6 +59,24 @@ export declare class HelixSandboxTerminal extends HelixElement {
|
|
|
40
59
|
* The log's name, read by screen readers.
|
|
41
60
|
*/
|
|
42
61
|
label: string;
|
|
62
|
+
/**
|
|
63
|
+
* The quietest level shown: `info` hides plain logs, `warn` shows warnings
|
|
64
|
+
* and errors, and `error` shows errors only. Absent shows every line.
|
|
65
|
+
*
|
|
66
|
+
* Lines it hides are kept, so lowering it shows them again. The filter under
|
|
67
|
+
* `controls` sets it.
|
|
68
|
+
*/
|
|
69
|
+
level?: ConsoleLevel | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* The level filter's name, read by screen readers, under `controls`.
|
|
72
|
+
*/
|
|
73
|
+
levelLabel: string;
|
|
74
|
+
/**
|
|
75
|
+
* What each choice of the level filter reads, for a page in another
|
|
76
|
+
* language, keyed by level, such as `{ warn: '…' }`. A level left out keeps
|
|
77
|
+
* its English words. As an attribute it is that object as JSON.
|
|
78
|
+
*/
|
|
79
|
+
levelWords: Partial<Record<ConsoleLevel, string>>;
|
|
43
80
|
private entries;
|
|
44
81
|
/**
|
|
45
82
|
* Whether the reader is at the bottom, and so wants to follow new output.
|
|
@@ -61,6 +98,10 @@ export declare class HelixSandboxTerminal extends HelixElement {
|
|
|
61
98
|
/** Empties the log. */
|
|
62
99
|
clear(): void;
|
|
63
100
|
protected updated(): void;
|
|
101
|
+
/** Takes the level the reader chose in the filter. */
|
|
102
|
+
private readonly handleLevel;
|
|
103
|
+
/** The clear button and the level filter, under `controls`. */
|
|
104
|
+
private renderControls;
|
|
64
105
|
protected render(): TemplateResult;
|
|
65
106
|
static styles: CSSResultGroup;
|
|
66
107
|
}
|
|
@@ -7,15 +7,30 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { customElement, HelixElement } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
|
+
import { LEVELS, shows } from '../levels.js';
|
|
10
11
|
import { styles } from './sandbox-terminal.css.js';
|
|
12
|
+
const LEVEL_WORDS = {
|
|
13
|
+
error: 'Errors',
|
|
14
|
+
info: 'Info and above',
|
|
15
|
+
log: 'All levels',
|
|
16
|
+
warn: 'Warnings and errors',
|
|
17
|
+
};
|
|
11
18
|
const LIMIT = 200;
|
|
12
19
|
let HelixSandboxTerminal = class HelixSandboxTerminal extends HelixElement {
|
|
13
20
|
constructor() {
|
|
14
21
|
super(...arguments);
|
|
22
|
+
this.clearLabel = 'Clear';
|
|
23
|
+
this.controls = false;
|
|
15
24
|
this.emptyLabel = 'Nothing written to the console yet.';
|
|
16
25
|
this.label = 'Console output';
|
|
26
|
+
this.levelLabel = 'Levels shown';
|
|
27
|
+
this.levelWords = {};
|
|
17
28
|
this.entries = [];
|
|
18
29
|
this.following = true;
|
|
30
|
+
this.handleLevel = (event) => {
|
|
31
|
+
const chosen = event.target.value;
|
|
32
|
+
this.level = chosen === 'log' ? undefined : chosen;
|
|
33
|
+
};
|
|
19
34
|
}
|
|
20
35
|
get log() {
|
|
21
36
|
return this.renderRoot.querySelector('[part="log"]');
|
|
@@ -44,11 +59,25 @@ let HelixSandboxTerminal = class HelixSandboxTerminal extends HelixElement {
|
|
|
44
59
|
}
|
|
45
60
|
}
|
|
46
61
|
}
|
|
62
|
+
renderControls() {
|
|
63
|
+
if (!this.controls) {
|
|
64
|
+
return nothing;
|
|
65
|
+
}
|
|
66
|
+
return html `<div part="controls">
|
|
67
|
+
<select part="filter" aria-label=${this.levelLabel} @change=${this.handleLevel}>
|
|
68
|
+
${LEVELS.map((one) => html `<option value=${one} ?selected=${(this.level ?? 'log') === one}>
|
|
69
|
+
${this.levelWords[one] ?? LEVEL_WORDS[one]}
|
|
70
|
+
</option>`)}
|
|
71
|
+
</select>
|
|
72
|
+
<button part="clear" type="button" @click=${() => this.clear()}>${this.clearLabel}</button>
|
|
73
|
+
</div>`;
|
|
74
|
+
}
|
|
47
75
|
render() {
|
|
48
|
-
|
|
49
|
-
|
|
76
|
+
const shown = this.entries.filter((entry) => shows(entry.level, this.level));
|
|
77
|
+
return html `${this.renderControls()}<div part="log" role="log" aria-label=${this.label} tabindex="0">
|
|
78
|
+
${shown.length === 0
|
|
50
79
|
? html `<p part="empty">${this.emptyLabel}</p>`
|
|
51
|
-
:
|
|
80
|
+
: shown.map((entry) => html `<div part="entry" data-level=${entry.level}>
|
|
52
81
|
<span part="level" aria-hidden=${entry.level === 'log' ? 'true' : nothing}
|
|
53
82
|
>${entry.level}</span
|
|
54
83
|
>
|
|
@@ -63,12 +92,27 @@ let HelixSandboxTerminal = class HelixSandboxTerminal extends HelixElement {
|
|
|
63
92
|
}
|
|
64
93
|
static { this.styles = styles; }
|
|
65
94
|
};
|
|
95
|
+
__decorate([
|
|
96
|
+
property({ attribute: 'clear-label' })
|
|
97
|
+
], HelixSandboxTerminal.prototype, "clearLabel", void 0);
|
|
98
|
+
__decorate([
|
|
99
|
+
property({ reflect: true, type: Boolean })
|
|
100
|
+
], HelixSandboxTerminal.prototype, "controls", void 0);
|
|
66
101
|
__decorate([
|
|
67
102
|
property({ attribute: 'empty-label' })
|
|
68
103
|
], HelixSandboxTerminal.prototype, "emptyLabel", void 0);
|
|
69
104
|
__decorate([
|
|
70
105
|
property()
|
|
71
106
|
], HelixSandboxTerminal.prototype, "label", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
property()
|
|
109
|
+
], HelixSandboxTerminal.prototype, "level", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
property({ attribute: 'level-label' })
|
|
112
|
+
], HelixSandboxTerminal.prototype, "levelLabel", void 0);
|
|
113
|
+
__decorate([
|
|
114
|
+
property({ attribute: 'level-words', type: Object })
|
|
115
|
+
], HelixSandboxTerminal.prototype, "levelWords", void 0);
|
|
72
116
|
__decorate([
|
|
73
117
|
state()
|
|
74
118
|
], HelixSandboxTerminal.prototype, "entries", void 0);
|
|
@@ -21,6 +21,87 @@ var(--scroll-area-track-color, transparent);
|
|
|
21
21
|
scrollbar-width: var(--scroll-area-scrollbar, thin);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
:host([scrollbars]) [part="viewport"] {
|
|
25
|
+
scrollbar-width: none;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[part~="scrollbar"] {
|
|
29
|
+
--_scroll-area-thumb: max(
|
|
30
|
+
var(--scroll-area-thumb-min-size, var(--helix-space-lg)),
|
|
31
|
+
var(--scroll-area-thumb-fraction, 1) *
|
|
32
|
+
100%
|
|
33
|
+
);
|
|
34
|
+
background-color: var(--scroll-area-track-color, transparent);
|
|
35
|
+
opacity: 0;
|
|
36
|
+
position: absolute;
|
|
37
|
+
touch-action: none;
|
|
38
|
+
transition: opacity var(--helix-duration-fast) var(--helix-easing-standard);
|
|
39
|
+
user-select: none;
|
|
40
|
+
|
|
41
|
+
z-index: calc(var(--helix-layer-raised) + 1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[part~="scrollbar-visible"] {
|
|
45
|
+
opacity: 1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[part~="scrollbar-vertical"] {
|
|
49
|
+
inline-size: var(--scroll-area-scrollbar-size, var(--helix-space-sm));
|
|
50
|
+
inset-block: 0;
|
|
51
|
+
inset-inline-end: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
[part~="scrollbar-horizontal"] {
|
|
55
|
+
block-size: var(--scroll-area-scrollbar-size, var(--helix-space-sm));
|
|
56
|
+
inset-block-end: 0;
|
|
57
|
+
inset-inline: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:host(:state(scrollbar-horizontal)) [part~="scrollbar-vertical"] {
|
|
61
|
+
inset-block-end: var(--scroll-area-scrollbar-size, var(--helix-space-sm));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
:host(:state(scrollbar-vertical)) [part~="scrollbar-horizontal"] {
|
|
65
|
+
inset-inline-end: var(--scroll-area-scrollbar-size, var(--helix-space-sm));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
[part~="thumb"] {
|
|
69
|
+
background-color: var(--scroll-area-thumb-color, var(--helix-color-border));
|
|
70
|
+
border-radius: var(--helix-radii-full);
|
|
71
|
+
position: absolute;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
[part~="thumb"]:hover {
|
|
75
|
+
background-color: var(--scroll-area-thumb-hover-color, var(--helix-color-foreground-subtle));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[part~="thumb-vertical"] {
|
|
79
|
+
block-size: var(--_scroll-area-thumb);
|
|
80
|
+
inset-block-start: calc(
|
|
81
|
+
var(--scroll-area-scroll-fraction, 0) *
|
|
82
|
+
(100% - var(--_scroll-area-thumb))
|
|
83
|
+
);
|
|
84
|
+
inset-inline: var(--helix-border-thick);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[part~="thumb-horizontal"] {
|
|
88
|
+
inline-size: var(--_scroll-area-thumb);
|
|
89
|
+
inset-block: var(--helix-border-thick);
|
|
90
|
+
inset-inline-start: calc(
|
|
91
|
+
var(--scroll-area-scroll-fraction, 0) *
|
|
92
|
+
(100% - var(--_scroll-area-thumb))
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
[part="corner"] {
|
|
97
|
+
background-color: var(--scroll-area-track-color, transparent);
|
|
98
|
+
block-size: var(--scroll-area-scrollbar-size, var(--helix-space-sm));
|
|
99
|
+
inline-size: var(--scroll-area-scrollbar-size, var(--helix-space-sm));
|
|
100
|
+
inset-block-end: 0;
|
|
101
|
+
inset-inline-end: 0;
|
|
102
|
+
position: absolute;
|
|
103
|
+
}
|
|
104
|
+
|
|
24
105
|
:host::before,
|
|
25
106
|
:host::after {
|
|
26
107
|
content: "";
|
|
@@ -110,7 +191,8 @@ opacity: 1;
|
|
|
110
191
|
:host::before,
|
|
111
192
|
:host::after,
|
|
112
193
|
[part="edges"]::before,
|
|
113
|
-
[part="edges"]::after
|
|
194
|
+
[part="edges"]::after,
|
|
195
|
+
[part~="scrollbar"] {
|
|
114
196
|
transition: none;
|
|
115
197
|
}
|
|
116
198
|
}
|
|
@@ -8,6 +8,9 @@ import type { CSSResultGroup } from 'lit';
|
|
|
8
8
|
* styled to match the design system. The base class measures which edges have
|
|
9
9
|
* content past them.
|
|
10
10
|
*
|
|
11
|
+
* Under `scrollbars`, the browser's scrollbar is hidden and the component's own
|
|
12
|
+
* are drawn over the content at the edge, in the same colors.
|
|
13
|
+
*
|
|
11
14
|
* @since 0.1.0
|
|
12
15
|
* @status stable
|
|
13
16
|
* @category layout
|
|
@@ -21,7 +24,10 @@ import type { CSSResultGroup } from 'lit';
|
|
|
21
24
|
* @cssproperty --scroll-area-fade-inline-end - The depth of the fade at the inline end, or `0` to remove it.
|
|
22
25
|
* @cssproperty --scroll-area-fade-inline-start - The depth of the fade at the inline start, or `0` to remove it.
|
|
23
26
|
* @cssproperty --scroll-area-scrollbar - The scrollbar width, as a `scrollbar-width` keyword.
|
|
27
|
+
* @cssproperty --scroll-area-scrollbar-size - The thickness of each scrollbar drawn under `scrollbars`, and the size of the corner.
|
|
24
28
|
* @cssproperty --scroll-area-thumb-color - The color of the scrollbar's thumb.
|
|
29
|
+
* @cssproperty --scroll-area-thumb-hover-color - The color of a thumb drawn under `scrollbars` while the pointer is over it.
|
|
30
|
+
* @cssproperty --scroll-area-thumb-min-size - The shortest a thumb drawn under `scrollbars` gets, however long the content.
|
|
25
31
|
* @cssproperty --scroll-area-track-color - The color of the scrollbar's track.
|
|
26
32
|
*/
|
|
27
33
|
export declare class HelixScrollArea extends HelixHeadlessScrollArea {
|