entasis 0.9.3 → 0.10.1
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/components/ButtonGroup/ButtonGroup.svelte +10 -4
- package/dist/components/ButtonGroup/buttonGroup.mcp.d.ts +1 -1
- package/dist/components/ButtonGroup/buttonGroup.mcp.js +23 -3
- package/dist/components/ButtonGroup/buttonGroup.props.d.ts +19 -5
- package/dist/components/Chart/Chart.svelte +1 -1
- package/dist/components/Chart/chart.cartesian.js +3 -2
- package/dist/components/Chart/chart.fit.d.ts +53 -0
- package/dist/components/Chart/chart.fit.js +81 -0
- package/dist/components/Chart/chart.mcp.d.ts +1 -1
- package/dist/components/Chart/chart.mcp.js +2 -1
- package/dist/components/Chart/chart.polar.js +137 -18
- package/dist/components/Chart/chart.polar.props.d.ts +5 -0
- package/dist/components/Chart/chart.proportion.js +12 -6
- package/dist/components/Chart/chart.relation.network.js +32 -4
- package/dist/components/Chart/chart.relation.sankey.js +53 -6
- package/dist/components/Chart/chart.relation.tree.js +84 -24
- package/dist/components/Chart/chart.series.props.d.ts +6 -0
- package/dist/components/Chart/chart.state.svelte.d.ts +1 -0
- package/dist/components/Chart/chart.state.svelte.js +9 -6
- package/dist/components/Chart/chart.viewport.svelte.d.ts +1 -0
- package/dist/components/Chart/chart.viewport.svelte.js +25 -7
- package/dist/components/DataTable/DataTable.svelte +25 -8
- package/dist/components/DataTable/DataTableRow.svelte +33 -10
- package/dist/components/DataTable/dataTable.mcp.d.ts +1 -1
- package/dist/components/DataTable/dataTable.mcp.js +12 -1
- package/dist/components/DataTable/dataTable.model.svelte.js +4 -3
- package/dist/components/DataTable/dataTable.props.d.ts +17 -0
- package/dist/components/DataTable/dataTable.theme.d.ts +12 -0
- package/dist/components/DataTable/dataTable.theme.js +3 -2
- package/dist/components/DataTable/index.d.ts +1 -1
- package/dist/components/Dialog/Dialog.svelte +12 -7
- package/dist/components/Dialog/dialog.state.svelte.d.ts +2 -1
- package/dist/components/Dialog/dialog.state.svelte.js +7 -7
- package/dist/components/Dialog/dialog.theme.js +1 -1
- package/dist/components/FloatingWindow/floatingWindow.theme.js +1 -1
- package/dist/components/Form/Select/Select.svelte +3 -1
- package/dist/components/Form/Select/select.align.d.ts +3 -2
- package/dist/components/Form/Select/select.align.js +11 -4
- package/dist/components/PageShell/pageShell.state.svelte.d.ts +1 -1
- package/dist/components/PageShell/pageShell.state.svelte.js +6 -13
- package/dist/components/Popover/Popover.svelte +5 -5
- package/dist/components/Popover/index.d.ts +1 -1
- package/dist/components/Popover/popover.mcp.d.ts +1 -1
- package/dist/components/Popover/popover.mcp.js +33 -6
- package/dist/components/Popover/popover.state.svelte.d.ts +9 -1
- package/dist/components/Popover/popover.state.svelte.js +61 -8
- package/dist/components/Popover/popover.theme.js +1 -1
- package/dist/components/Sidebar/SidebarDesktopShell.svelte +26 -6
- package/dist/components/Sidebar/sidebar.theme.js +1 -1
- package/dist/components/Theme/index.d.ts +1 -1
- package/dist/components/Theme/index.js +1 -1
- package/dist/components/Theme/theme.mcp.d.ts +1 -1
- package/dist/components/Theme/theme.mcp.js +3 -0
- package/dist/components/Theme/theme.state.svelte.d.ts +4 -0
- package/dist/components/Theme/theme.state.svelte.js +4 -0
- package/dist/components/Tooltip/Tooltip.svelte +2 -4
- package/dist/components/Tooltip/tooltip.attachment.svelte.js +5 -0
- package/dist/components/Tooltip/tooltip.mcp.d.ts +1 -1
- package/dist/components/Tooltip/tooltip.mcp.js +4 -2
- package/dist/generated/componentAliases.d.ts +1 -0
- package/dist/generated/componentAliases.js +1 -0
- package/dist/generated/componentContract.d.ts +13 -3
- package/dist/generated/componentContract.js +15 -1
- package/dist/generated/componentMcpRegistry.d.ts +7 -6
- package/dist/generated/componentMcpRegistry.js +2 -0
- package/dist/i18n/ar.js +1 -1
- package/dist/i18n/de.js +1 -1
- package/dist/i18n/en.js +1 -1
- package/dist/i18n/es.js +1 -1
- package/dist/i18n/fr.js +1 -1
- package/dist/i18n/pt.js +1 -1
- package/dist/i18n/zh.js +1 -1
- package/dist/tailwind/colors.d.ts +10 -3
- package/dist/tailwind/colors.js +6 -0
- package/dist/tailwind/palette.d.ts +5 -0
- package/dist/tailwind/palette.js +4 -0
- package/dist/tailwind/palette.mcp.d.ts +1 -0
- package/dist/tailwind/palette.mcp.js +34 -0
- package/dist/utils/layers.svelte.js +9 -8
- package/dist/utils/registry.svelte.d.ts +21 -0
- package/dist/utils/registry.svelte.js +49 -0
- package/package.json +8 -1
|
@@ -130,6 +130,7 @@ import { themeDescription } from '../components/Theme/theme.mcp.js';
|
|
|
130
130
|
import { i18nDescription } from '../i18n/i18n.mcp.js';
|
|
131
131
|
import { tailwindPluginDescription } from '../tailwind/index.mcp.js';
|
|
132
132
|
import { themePluginDescription } from '../tailwind/theme.mcp.js';
|
|
133
|
+
import { colorPaletteDescription } from '../tailwind/palette.mcp.js';
|
|
133
134
|
import { typesDescription } from '../types/types.mcp.js';
|
|
134
135
|
import { cvaDescription } from '../utils/cva/cva.mcp.js';
|
|
135
136
|
import { schedulingDescription } from '../utils/scheduling/scheduling.mcp.js';
|
|
@@ -269,6 +270,7 @@ export const componentMcpRegistry = {
|
|
|
269
270
|
i18n: i18nDescription,
|
|
270
271
|
'tailwind-plugin': tailwindPluginDescription,
|
|
271
272
|
'theme-tailwind-plugin': themePluginDescription,
|
|
273
|
+
'color-palette': colorPaletteDescription,
|
|
272
274
|
types: typesDescription,
|
|
273
275
|
cva: cvaDescription,
|
|
274
276
|
scheduling: schedulingDescription,
|
package/dist/i18n/ar.js
CHANGED
|
@@ -134,7 +134,7 @@ export const ar = {
|
|
|
134
134
|
mapMarker: (label) => `علامة الخريطة ${label}`,
|
|
135
135
|
linkTo: (url) => `رابط إلى ${url}`,
|
|
136
136
|
pageRenderError: (pageNumber) => `تعذّر عرض الصفحة ${pageNumber}`,
|
|
137
|
-
paginationSummary: (startItem, endItem, totalItems) => `${startItem}
|
|
137
|
+
paginationSummary: (startItem, endItem, totalItems) => `${startItem}–${endItem} من ${totalItems}`,
|
|
138
138
|
currentPage: (page) => `صفحة ${page}، الصفحة الحالية`,
|
|
139
139
|
goToPage: (page) => `الانتقال إلى صفحة ${page}`,
|
|
140
140
|
expandPanel: (index) => `توسيع اللوحة ${index}`,
|
package/dist/i18n/de.js
CHANGED
|
@@ -134,7 +134,7 @@ export const de = {
|
|
|
134
134
|
mapMarker: (label) => `Kartenmarkierung ${label}`,
|
|
135
135
|
linkTo: (url) => `Link zu ${url}`,
|
|
136
136
|
pageRenderError: (pageNumber) => `Seite ${pageNumber} konnte nicht gerendert werden`,
|
|
137
|
-
paginationSummary: (startItem, endItem, totalItems) => `${startItem}
|
|
137
|
+
paginationSummary: (startItem, endItem, totalItems) => `${startItem}–${endItem} von ${totalItems}`,
|
|
138
138
|
currentPage: (page) => `Seite ${page}, aktuelle Seite`,
|
|
139
139
|
goToPage: (page) => `Gehe zu Seite ${page}`,
|
|
140
140
|
expandPanel: (index) => `Bereich ${index} erweitern`,
|
package/dist/i18n/en.js
CHANGED
|
@@ -142,7 +142,7 @@ export const en = {
|
|
|
142
142
|
mapMarker: (label) => `Map marker ${label}`,
|
|
143
143
|
linkTo: (url) => `Link to ${url}`,
|
|
144
144
|
pageRenderError: (pageNumber) => `Could not render page ${pageNumber}`,
|
|
145
|
-
paginationSummary: (startItem, endItem, totalItems) => `${startItem}
|
|
145
|
+
paginationSummary: (startItem, endItem, totalItems) => `${startItem}–${endItem} of ${totalItems}`,
|
|
146
146
|
currentPage: (page) => `Page ${page}, current page`,
|
|
147
147
|
goToPage: (page) => `Go to page ${page}`,
|
|
148
148
|
expandPanel: (index) => `Expand panel ${index}`,
|
package/dist/i18n/es.js
CHANGED
|
@@ -134,7 +134,7 @@ export const es = {
|
|
|
134
134
|
mapMarker: (label) => `Marcador del mapa ${label}`,
|
|
135
135
|
linkTo: (url) => `Enlace a ${url}`,
|
|
136
136
|
pageRenderError: (pageNumber) => `No se ha podido representar la página ${pageNumber}`,
|
|
137
|
-
paginationSummary: (startItem, endItem, totalItems) => `${startItem}
|
|
137
|
+
paginationSummary: (startItem, endItem, totalItems) => `${startItem}–${endItem} de ${totalItems}`,
|
|
138
138
|
currentPage: (page) => `Página ${page}, página actual`,
|
|
139
139
|
goToPage: (page) => `Ir a la página ${page}`,
|
|
140
140
|
expandPanel: (index) => `Expandir panel ${index}`,
|
package/dist/i18n/fr.js
CHANGED
|
@@ -134,7 +134,7 @@ export const fr = {
|
|
|
134
134
|
mapMarker: (label) => `Marqueur de carte ${label}`,
|
|
135
135
|
linkTo: (url) => `Lien vers ${url}`,
|
|
136
136
|
pageRenderError: (pageNumber) => `Impossible d'afficher la page ${pageNumber}`,
|
|
137
|
-
paginationSummary: (startItem, endItem, totalItems) => `${startItem}
|
|
137
|
+
paginationSummary: (startItem, endItem, totalItems) => `${startItem}–${endItem} sur ${totalItems}`,
|
|
138
138
|
currentPage: (page) => `Page ${page}, page actuelle`,
|
|
139
139
|
goToPage: (page) => `Aller à la page ${page}`,
|
|
140
140
|
expandPanel: (index) => `Développer le panneau ${index}`,
|
package/dist/i18n/pt.js
CHANGED
|
@@ -134,7 +134,7 @@ export const pt = {
|
|
|
134
134
|
mapMarker: (label) => `Marcador do mapa ${label}`,
|
|
135
135
|
linkTo: (url) => `Link para ${url}`,
|
|
136
136
|
pageRenderError: (pageNumber) => `Não foi possível renderizar a página ${pageNumber}`,
|
|
137
|
-
paginationSummary: (startItem, endItem, totalItems) => `${startItem}
|
|
137
|
+
paginationSummary: (startItem, endItem, totalItems) => `${startItem}–${endItem} de ${totalItems}`,
|
|
138
138
|
currentPage: (page) => `Página ${page}, página atual`,
|
|
139
139
|
goToPage: (page) => `Ir para a página ${page}`,
|
|
140
140
|
expandPanel: (index) => `Expandir painel ${index}`,
|
package/dist/i18n/zh.js
CHANGED
|
@@ -134,7 +134,7 @@ export const zh = {
|
|
|
134
134
|
mapMarker: (label) => `地图标记 ${label}`,
|
|
135
135
|
linkTo: (url) => `链接到 ${url}`,
|
|
136
136
|
pageRenderError: (pageNumber) => `无法渲染第 ${pageNumber} 页`,
|
|
137
|
-
paginationSummary: (startItem, endItem, totalItems) => `${startItem}
|
|
137
|
+
paginationSummary: (startItem, endItem, totalItems) => `${startItem}–${endItem},共 ${totalItems}`,
|
|
138
138
|
currentPage: (page) => `第 ${page} 页,当前页`,
|
|
139
139
|
goToPage: (page) => `前往第 ${page} 页`,
|
|
140
140
|
expandPanel: (index) => `展开面板 ${index}`,
|
|
@@ -326,7 +326,8 @@ type Colors = {
|
|
|
326
326
|
};
|
|
327
327
|
export declare const variants: readonly ["Light", "Lighter", "Dark", "Muted", "Contrast"];
|
|
328
328
|
export declare const colors: readonly ["primary", "secondary", "danger", "success", "warning", "info", "neutral"];
|
|
329
|
-
|
|
329
|
+
/** Inputs of {@link generateColorPalette}: the seed colours plus mode and tuning options. */
|
|
330
|
+
export type ColorPaletteOptions = {
|
|
330
331
|
saturation?: number;
|
|
331
332
|
luminance?: number;
|
|
332
333
|
colorscheme?: 'dark' | 'light';
|
|
@@ -334,7 +335,7 @@ type ColorThemeOption = {
|
|
|
334
335
|
'state-pressed-opacity'?: number;
|
|
335
336
|
'state-selected-opacity'?: number;
|
|
336
337
|
} & ColorTheme;
|
|
337
|
-
export declare const generateBaseColors: (theme:
|
|
338
|
+
export declare const generateBaseColors: (theme: ColorPaletteOptions) => {
|
|
338
339
|
colors: Colors;
|
|
339
340
|
surface: {
|
|
340
341
|
DEFAULT: string;
|
|
@@ -344,7 +345,13 @@ export declare const generateBaseColors: (theme: ColorThemeOption) => {
|
|
|
344
345
|
floating: string | null;
|
|
345
346
|
};
|
|
346
347
|
};
|
|
347
|
-
|
|
348
|
+
/**
|
|
349
|
+
* The palette the theme plugin writes for one theme, computed at runtime: every semantic role with
|
|
350
|
+
* its generated variants, the surface ladder, and the state-layer opacities. `cssVariables` maps
|
|
351
|
+
* `--color-*` and `--state-*` custom properties to values, ready to set on an element to theme its
|
|
352
|
+
* subtree (a brand colour chosen at runtime, a preview of a palette).
|
|
353
|
+
*/
|
|
354
|
+
export declare const generateColorPalette: (opts: ColorPaletteOptions) => {
|
|
348
355
|
colorsPalette: {
|
|
349
356
|
primary: {
|
|
350
357
|
DEFAULT: string;
|
package/dist/tailwind/colors.js
CHANGED
|
@@ -386,6 +386,12 @@ export const generateBaseColors = (theme) => {
|
|
|
386
386
|
});
|
|
387
387
|
return { colors: baseColors, surface };
|
|
388
388
|
};
|
|
389
|
+
/**
|
|
390
|
+
* The palette the theme plugin writes for one theme, computed at runtime: every semantic role with
|
|
391
|
+
* its generated variants, the surface ladder, and the state-layer opacities. `cssVariables` maps
|
|
392
|
+
* `--color-*` and `--state-*` custom properties to values, ready to set on an element to theme its
|
|
393
|
+
* subtree (a brand colour chosen at runtime, a preview of a palette).
|
|
394
|
+
*/
|
|
389
395
|
export const generateColorPalette = (opts) => {
|
|
390
396
|
const { luminance, saturation, colorscheme } = opts;
|
|
391
397
|
const { colors, surface } = generateBaseColors(opts);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { generateColorPalette } from './colors.js';
|
|
2
|
+
export { generateColorPalette };
|
|
3
|
+
export type { ColorPaletteOptions, ColorTheme } from './colors.js';
|
|
4
|
+
/** What {@link generateColorPalette} returns. */
|
|
5
|
+
export type ColorPalette = ReturnType<typeof generateColorPalette>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const colorPaletteDescription = "\n# Color palette\n\n`generateColorPalette` from `entasis/color-palette` computes, at runtime, the palette the theme\nplugin writes for one theme. It takes the same inputs as a `@plugin 'entasis/tailwind-plugin/theme'`\ndeclaration (`primary`, `secondary`, `danger`, `success`, `warning`, `info`, `neutral`,\n`surface`, their `-light`/`-muted`/\u2026 overrides, `colorscheme`, `luminance`, `saturation`\nand the `state-*-opacity` values) and does not import Tailwind.\n\n```svelte\n<script lang=\"ts\">\n\timport { generateColorPalette } from 'entasis/color-palette';\n\n\tlet brand = $state('#0f766e');\n\tconst palette = $derived(\n\t\tgenerateColorPalette({ colorscheme: 'light', primary: brand, surface: '#fafafa', neutral: '#18181b' })\n\t);\n\tconst style = $derived(\n\t\tObject.entries(palette.cssVariables)\n\t\t\t.map(([name, value]) => `${name}: ${value}`)\n\t\t\t.join('; ')\n\t);\n</script>\n\n<div {style}>\n\t<!-- Components in here use the generated palette. -->\n</div>\n```\n\n- `cssVariables` maps `--color-*` and `--state-*` custom properties to values. Setting them on an\n element themes its subtree, since every utility reads those variables.\n- `colorsPalette` holds the resolved hex colours for each role and variant.\n- Spacing, radius, typography and the state roles stay on `Theme`'s `designTokens`.\n";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const colorPaletteDescription = `
|
|
2
|
+
# Color palette
|
|
3
|
+
|
|
4
|
+
\`generateColorPalette\` from \`entasis/color-palette\` computes, at runtime, the palette the theme
|
|
5
|
+
plugin writes for one theme. It takes the same inputs as a \`@plugin 'entasis/tailwind-plugin/theme'\`
|
|
6
|
+
declaration (\`primary\`, \`secondary\`, \`danger\`, \`success\`, \`warning\`, \`info\`, \`neutral\`,
|
|
7
|
+
\`surface\`, their \`-light\`/\`-muted\`/… overrides, \`colorscheme\`, \`luminance\`, \`saturation\`
|
|
8
|
+
and the \`state-*-opacity\` values) and does not import Tailwind.
|
|
9
|
+
|
|
10
|
+
\`\`\`svelte
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
import { generateColorPalette } from './palette.ts';
|
|
13
|
+
|
|
14
|
+
let brand = $state('#0f766e');
|
|
15
|
+
const palette = $derived(
|
|
16
|
+
generateColorPalette({ colorscheme: 'light', primary: brand, surface: '#fafafa', neutral: '#18181b' })
|
|
17
|
+
);
|
|
18
|
+
const style = $derived(
|
|
19
|
+
Object.entries(palette.cssVariables)
|
|
20
|
+
.map(([name, value]) => \`\${name}: \${value}\`)
|
|
21
|
+
.join('; ')
|
|
22
|
+
);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div {style}>
|
|
26
|
+
<!-- Components in here use the generated palette. -->
|
|
27
|
+
</div>
|
|
28
|
+
\`\`\`
|
|
29
|
+
|
|
30
|
+
- \`cssVariables\` maps \`--color-*\` and \`--state-*\` custom properties to values. Setting them on an
|
|
31
|
+
element themes its subtree, since every utility reads those variables.
|
|
32
|
+
- \`colorsPalette\` holds the resolved hex colours for each role and variant.
|
|
33
|
+
- Spacing, radius, typography and the state roles stay on \`Theme\`'s \`designTokens\`.
|
|
34
|
+
`;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { on } from 'svelte/events';
|
|
6
6
|
import { getContext, hasContext, setContext, untrack } from 'svelte';
|
|
7
7
|
import { SvelteSet } from 'svelte/reactivity';
|
|
8
|
+
import { Registry } from './registry.svelte.js';
|
|
8
9
|
import { LAYER_Z_BASE, LAYER_Z_STEP } from '../components/Theme/theme.layers.js';
|
|
9
10
|
const LAYER_CONTEXT = Symbol('entasis:layer');
|
|
10
11
|
export class LayerHandle {
|
|
@@ -66,14 +67,14 @@ export class LayerHandle {
|
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
export class LayerStack {
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
#layers =
|
|
70
|
+
// A plain registry rather than reactive state read, filtered and written back: see
|
|
71
|
+
// `Registry`. A teardown in another async batch used to restore an old list and drop every
|
|
72
|
+
// layer registered meanwhile (after a docs tab switch, dialogs opened with no backdrop and
|
|
73
|
+
// ignored Escape).
|
|
74
|
+
#layers = new Registry();
|
|
74
75
|
#seq = 0;
|
|
75
76
|
/** Open layers sorted bottom → top. */
|
|
76
|
-
open = $derived(this.#layers.filter((layer) => layer.isOpen).sort((a, b) => a.openOrder - b.openOrder));
|
|
77
|
+
open = $derived(this.#layers.items.filter((layer) => layer.isOpen).sort((a, b) => a.openOrder - b.openOrder));
|
|
77
78
|
topModal = $derived([...this.open].reverse().find((layer) => layer.isModal));
|
|
78
79
|
ofKind(kind) {
|
|
79
80
|
return this.open.filter((layer) => layer.kind === kind);
|
|
@@ -99,7 +100,7 @@ export class LayerStack {
|
|
|
99
100
|
register(options) {
|
|
100
101
|
const handle = new LayerHandle(this, options);
|
|
101
102
|
setContext(LAYER_CONTEXT, handle);
|
|
102
|
-
this.#layers
|
|
103
|
+
this.#layers.add(handle);
|
|
103
104
|
$effect(() => {
|
|
104
105
|
if (options.isOpen()) {
|
|
105
106
|
untrack(() => {
|
|
@@ -111,7 +112,7 @@ export class LayerStack {
|
|
|
111
112
|
return handle;
|
|
112
113
|
}
|
|
113
114
|
remove(handle) {
|
|
114
|
-
this.#layers
|
|
115
|
+
this.#layers.delete(handle);
|
|
115
116
|
}
|
|
116
117
|
#onKeyDown = (event) => {
|
|
117
118
|
if (event.key !== 'Escape' || event.defaultPrevented)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A list that components join while they initialise and leave when they are torn down: open
|
|
3
|
+
* layers, a dialog's nested dialogs, a page's shell overrides.
|
|
4
|
+
*
|
|
5
|
+
* The entries live in a plain array mutated in place. Reading a reactive array, filtering it and
|
|
6
|
+
* writing it back is not safe for this: under Svelte's async mode a component torn down in one
|
|
7
|
+
* batch can read state another batch has written as it was before, so a teardown's
|
|
8
|
+
* `list = list.filter(...)` restores the old list and drops every entry added meanwhile. A deep
|
|
9
|
+
* `$state` proxy has its own trouble: it wraps stored objects, so identity checks against the
|
|
10
|
+
* original miss. Each change writes a fresh token instead, which no stale read can equal, and
|
|
11
|
+
* `items` re-reads the array whenever the token moves.
|
|
12
|
+
*/
|
|
13
|
+
export declare class Registry<T> {
|
|
14
|
+
#private;
|
|
15
|
+
/** The entries in the order they joined. Reading it subscribes to every change. */
|
|
16
|
+
get items(): readonly T[];
|
|
17
|
+
/** Adds an entry and returns the function that removes it, safe to call more than once. */
|
|
18
|
+
add(entry: T): () => void;
|
|
19
|
+
delete(entry: T): void;
|
|
20
|
+
clear(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A list that components join while they initialise and leave when they are torn down: open
|
|
3
|
+
* layers, a dialog's nested dialogs, a page's shell overrides.
|
|
4
|
+
*
|
|
5
|
+
* The entries live in a plain array mutated in place. Reading a reactive array, filtering it and
|
|
6
|
+
* writing it back is not safe for this: under Svelte's async mode a component torn down in one
|
|
7
|
+
* batch can read state another batch has written as it was before, so a teardown's
|
|
8
|
+
* `list = list.filter(...)` restores the old list and drops every entry added meanwhile. A deep
|
|
9
|
+
* `$state` proxy has its own trouble: it wraps stored objects, so identity checks against the
|
|
10
|
+
* original miss. Each change writes a fresh token instead, which no stale read can equal, and
|
|
11
|
+
* `items` re-reads the array whenever the token moves.
|
|
12
|
+
*/
|
|
13
|
+
export class Registry {
|
|
14
|
+
#entries = [];
|
|
15
|
+
#changed = $state.raw({});
|
|
16
|
+
#items = $derived.by(() => {
|
|
17
|
+
void this.#changed;
|
|
18
|
+
return [...this.#entries];
|
|
19
|
+
});
|
|
20
|
+
/** The entries in the order they joined. Reading it subscribes to every change. */
|
|
21
|
+
get items() {
|
|
22
|
+
return this.#items;
|
|
23
|
+
}
|
|
24
|
+
/** Adds an entry and returns the function that removes it, safe to call more than once. */
|
|
25
|
+
add(entry) {
|
|
26
|
+
this.#entries.push(entry);
|
|
27
|
+
this.#changed = {};
|
|
28
|
+
let present = true;
|
|
29
|
+
return () => {
|
|
30
|
+
if (!present)
|
|
31
|
+
return;
|
|
32
|
+
present = false;
|
|
33
|
+
this.delete(entry);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
delete(entry) {
|
|
37
|
+
const index = this.#entries.indexOf(entry);
|
|
38
|
+
if (index < 0)
|
|
39
|
+
return;
|
|
40
|
+
this.#entries.splice(index, 1);
|
|
41
|
+
this.#changed = {};
|
|
42
|
+
}
|
|
43
|
+
clear() {
|
|
44
|
+
if (this.#entries.length === 0)
|
|
45
|
+
return;
|
|
46
|
+
this.#entries.length = 0;
|
|
47
|
+
this.#changed = {};
|
|
48
|
+
}
|
|
49
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "entasis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
@@ -804,6 +804,10 @@
|
|
|
804
804
|
"types": "./dist/tailwind/theme.d.ts",
|
|
805
805
|
"default": "./dist/tailwind/theme.js"
|
|
806
806
|
},
|
|
807
|
+
"./color-palette": {
|
|
808
|
+
"types": "./dist/tailwind/palette.d.ts",
|
|
809
|
+
"default": "./dist/tailwind/palette.js"
|
|
810
|
+
},
|
|
807
811
|
"./types": {
|
|
808
812
|
"types": "./dist/types/index.d.ts",
|
|
809
813
|
"default": "./dist/types/index.js"
|
|
@@ -1225,6 +1229,9 @@
|
|
|
1225
1229
|
"tailwind-plugin/theme": [
|
|
1226
1230
|
"dist/tailwind/theme.d.ts"
|
|
1227
1231
|
],
|
|
1232
|
+
"color-palette": [
|
|
1233
|
+
"dist/tailwind/palette.d.ts"
|
|
1234
|
+
],
|
|
1228
1235
|
"types": [
|
|
1229
1236
|
"dist/types/index.d.ts"
|
|
1230
1237
|
],
|