svelteplot 0.3.3 → 0.3.4
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/helpers/getBaseStyles.d.ts +2 -0
- package/dist/helpers/getBaseStyles.js +8 -0
- package/dist/marks/Text.svelte +10 -102
- package/dist/marks/Text.svelte.d.ts +5 -0
- package/dist/marks/helpers/MultilineText.svelte +158 -0
- package/dist/marks/helpers/MultilineText.svelte.d.ts +12 -0
- package/package.json +10 -10
|
@@ -5,3 +5,5 @@ export declare function getBaseStylesObject(datum: DataRow, props: Partial<Chann
|
|
|
5
5
|
};
|
|
6
6
|
export default function (datum: DataRow, props: Partial<Channels>): string;
|
|
7
7
|
export declare function maybeToPixel(cssKey: string, value: string | number): string | number;
|
|
8
|
+
export declare function maybeFromPixel(value: string | number): string | number;
|
|
9
|
+
export declare function maybeFromRem(value: string | number, rootFontSize?: number): string | number;
|
|
@@ -41,3 +41,11 @@ export function maybeToPixel(cssKey, value) {
|
|
|
41
41
|
}
|
|
42
42
|
return value;
|
|
43
43
|
}
|
|
44
|
+
export function maybeFromPixel(value) {
|
|
45
|
+
return typeof value === 'string' && value.endsWith('px') ? +value.slice(0, -2) : value;
|
|
46
|
+
}
|
|
47
|
+
export function maybeFromRem(value, rootFontSize = 16) {
|
|
48
|
+
return typeof value === 'string' && value.endsWith('rem')
|
|
49
|
+
? +value.slice(0, -3) * rootFontSize
|
|
50
|
+
: value;
|
|
51
|
+
}
|
package/dist/marks/Text.svelte
CHANGED
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
* the line anchor for vertical position; top, bottom, or middle
|
|
19
19
|
*/
|
|
20
20
|
lineAnchor?: ConstantAccessor<'bottom' | 'top' | 'middle'>;
|
|
21
|
+
/**
|
|
22
|
+
* line height as multiplier of font size
|
|
23
|
+
* @default 1.2
|
|
24
|
+
*/
|
|
25
|
+
lineHeight?: ConstantAccessor<number>;
|
|
21
26
|
frameAnchor?: ConstantAccessor<
|
|
22
27
|
| 'bottom'
|
|
23
28
|
| 'top'
|
|
@@ -35,7 +40,6 @@
|
|
|
35
40
|
import { getContext, type Snippet } from 'svelte';
|
|
36
41
|
import GroupMultiple from './helpers/GroupMultiple.svelte';
|
|
37
42
|
import type {
|
|
38
|
-
PlotContext,
|
|
39
43
|
DataRecord,
|
|
40
44
|
BaseMarkProps,
|
|
41
45
|
ConstantAccessor,
|
|
@@ -46,11 +50,14 @@
|
|
|
46
50
|
import Mark from '../Mark.svelte';
|
|
47
51
|
import { sort } from '../index.js';
|
|
48
52
|
|
|
53
|
+
import MultilineText from './helpers/MultilineText.svelte';
|
|
54
|
+
|
|
49
55
|
const DEFAULTS = {
|
|
50
56
|
fontSize: 12,
|
|
51
57
|
fontWeight: 500,
|
|
52
58
|
strokeWidth: 1.6,
|
|
53
59
|
frameAnchor: 'center',
|
|
60
|
+
lineHeight: 1.1,
|
|
54
61
|
...getContext<PlotDefaults>('svelteplot/_defaults').text
|
|
55
62
|
};
|
|
56
63
|
|
|
@@ -65,21 +72,12 @@
|
|
|
65
72
|
...markProps
|
|
66
73
|
});
|
|
67
74
|
|
|
68
|
-
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
69
|
-
let plot = $derived(getPlotState());
|
|
70
|
-
|
|
71
|
-
const LINE_ANCHOR = {
|
|
72
|
-
bottom: 'auto',
|
|
73
|
-
middle: 'central',
|
|
74
|
-
top: 'hanging'
|
|
75
|
-
} as const;
|
|
76
|
-
|
|
77
75
|
const args = $derived(
|
|
78
76
|
sort({
|
|
79
77
|
data,
|
|
80
78
|
...options
|
|
81
79
|
})
|
|
82
|
-
);
|
|
80
|
+
) as TextMarkProps;
|
|
83
81
|
</script>
|
|
84
82
|
|
|
85
83
|
<Mark
|
|
@@ -101,99 +99,9 @@
|
|
|
101
99
|
<GroupMultiple class="text {className}" length={className ? 2 : args.data.length}>
|
|
102
100
|
{#each scaledData as d, i (i)}
|
|
103
101
|
{#if d.valid}
|
|
104
|
-
{@const title = resolveProp(args.title, d.datum, '')}
|
|
105
|
-
{@const frameAnchor = resolveProp(args.frameAnchor, d.datum)}
|
|
106
|
-
{@const isLeft =
|
|
107
|
-
frameAnchor === 'left' ||
|
|
108
|
-
frameAnchor === 'top-left' ||
|
|
109
|
-
frameAnchor === 'bottom-left'}
|
|
110
|
-
{@const isRight =
|
|
111
|
-
frameAnchor === 'right' ||
|
|
112
|
-
frameAnchor === 'top-right' ||
|
|
113
|
-
frameAnchor === 'bottom-right'}
|
|
114
|
-
{@const isTop =
|
|
115
|
-
frameAnchor === 'top' ||
|
|
116
|
-
frameAnchor === 'top-left' ||
|
|
117
|
-
frameAnchor === 'top-right'}
|
|
118
|
-
{@const isBottom =
|
|
119
|
-
frameAnchor === 'bottom' ||
|
|
120
|
-
frameAnchor === 'bottom-left' ||
|
|
121
|
-
frameAnchor === 'bottom-right'}
|
|
122
|
-
{@const [x, y] =
|
|
123
|
-
args.x != null && args.y != null
|
|
124
|
-
? [d.x, d.y]
|
|
125
|
-
: [
|
|
126
|
-
args.x != null
|
|
127
|
-
? d.x
|
|
128
|
-
: isLeft
|
|
129
|
-
? plot.options.marginLeft
|
|
130
|
-
: isRight
|
|
131
|
-
? plot.options.marginLeft + plot.facetWidth
|
|
132
|
-
: plot.options.marginLeft + plot.facetWidth * 0.5,
|
|
133
|
-
args.y != null
|
|
134
|
-
? d.y
|
|
135
|
-
: isTop
|
|
136
|
-
? plot.options.marginTop
|
|
137
|
-
: isBottom
|
|
138
|
-
? plot.options.marginTop + plot.facetHeight
|
|
139
|
-
: plot.options.marginTop + plot.facetHeight * 0.5
|
|
140
|
-
]}
|
|
141
|
-
|
|
142
|
-
{@const dx = +resolveProp(args.dx, d.datum, 0)}
|
|
143
|
-
{@const dy = +resolveProp(args.dy, d.datum, 0)}
|
|
144
102
|
{@const textLines = String(resolveProp(args.text, d.datum, '')).split('\n')}
|
|
145
|
-
{@const lineAnchor = resolveProp(
|
|
146
|
-
args.lineAnchor,
|
|
147
|
-
d.datum,
|
|
148
|
-
args.y != null ? 'middle' : isTop ? 'top' : isBottom ? 'bottom' : 'middle'
|
|
149
|
-
)}
|
|
150
|
-
{@const textClassName = resolveProp(args.textClass, d.datum, null)}
|
|
151
|
-
|
|
152
|
-
{@const [style, styleClass] = resolveStyles(
|
|
153
|
-
plot,
|
|
154
|
-
{ ...d, __tspanIndex: 0 },
|
|
155
|
-
{
|
|
156
|
-
fontSize: 12,
|
|
157
|
-
fontWeight: 500,
|
|
158
|
-
strokeWidth: 1.6,
|
|
159
|
-
textAnchor: isLeft ? 'start' : isRight ? 'end' : 'middle',
|
|
160
|
-
...args
|
|
161
|
-
},
|
|
162
|
-
'fill',
|
|
163
|
-
usedScales
|
|
164
|
-
)}
|
|
165
103
|
|
|
166
|
-
{
|
|
167
|
-
<!-- multiline text-->
|
|
168
|
-
{@const fontSize = resolveProp(args.fontSize, d.datum) || 12}
|
|
169
|
-
<text
|
|
170
|
-
class={[textClassName]}
|
|
171
|
-
dominant-baseline={LINE_ANCHOR[lineAnchor]}
|
|
172
|
-
transform="translate({Math.round(x + dx)},{Math.round(
|
|
173
|
-
y +
|
|
174
|
-
dy -
|
|
175
|
-
(lineAnchor === 'bottom'
|
|
176
|
-
? textLines.length - 1
|
|
177
|
-
: lineAnchor === 'middle'
|
|
178
|
-
? (textLines.length - 1) * 0.5
|
|
179
|
-
: 0) *
|
|
180
|
-
fontSize
|
|
181
|
-
)})"
|
|
182
|
-
>{#each textLines as line, l (l)}<tspan
|
|
183
|
-
x="0"
|
|
184
|
-
dy={l ? fontSize : 0}
|
|
185
|
-
class={styleClass}
|
|
186
|
-
{style}>{line}</tspan
|
|
187
|
-
>{/each}{#if title}<title>{title}</title>{/if}</text>
|
|
188
|
-
{:else}
|
|
189
|
-
<!-- singleline text-->
|
|
190
|
-
<text
|
|
191
|
-
class={[textClassName, styleClass]}
|
|
192
|
-
dominant-baseline={LINE_ANCHOR[lineAnchor]}
|
|
193
|
-
transform="translate({Math.round(x + dx)},{Math.round(y + dy)})"
|
|
194
|
-
{style}
|
|
195
|
-
>{textLines[0]}{#if title}<title>{title}</title>{/if}</text>
|
|
196
|
-
{/if}
|
|
104
|
+
<MultilineText {textLines} {d} {args} {usedScales} />
|
|
197
105
|
{/if}
|
|
198
106
|
{/each}
|
|
199
107
|
</GroupMultiple>
|
|
@@ -13,6 +13,11 @@ export type TextMarkProps = BaseMarkProps & {
|
|
|
13
13
|
* the line anchor for vertical position; top, bottom, or middle
|
|
14
14
|
*/
|
|
15
15
|
lineAnchor?: ConstantAccessor<'bottom' | 'top' | 'middle'>;
|
|
16
|
+
/**
|
|
17
|
+
* line height as multiplier of font size
|
|
18
|
+
* @default 1.2
|
|
19
|
+
*/
|
|
20
|
+
lineHeight?: ConstantAccessor<number>;
|
|
16
21
|
frameAnchor?: ConstantAccessor<'bottom' | 'top' | 'left' | 'right' | 'top-left' | 'bottom-left' | 'top-right' | 'bottom-right'>;
|
|
17
22
|
};
|
|
18
23
|
import { type Snippet } from 'svelte';
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { resolveProp, resolveStyles } from '../../helpers/resolve';
|
|
3
|
+
import { getContext, type ComponentProps } from 'svelte';
|
|
4
|
+
import type { PlotContext, ScaledDataRecord, UsedScales } from '../../types';
|
|
5
|
+
import type Text from '../Text.svelte';
|
|
6
|
+
import { CSS_VAR } from '../../constants';
|
|
7
|
+
import { maybeFromPixel, maybeFromRem } from '../../helpers/getBaseStyles';
|
|
8
|
+
|
|
9
|
+
const LINE_ANCHOR = {
|
|
10
|
+
bottom: 'auto',
|
|
11
|
+
middle: 'central',
|
|
12
|
+
top: 'hanging'
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
16
|
+
const plot = $derived(getPlotState());
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
textLines,
|
|
20
|
+
d,
|
|
21
|
+
args,
|
|
22
|
+
usedScales
|
|
23
|
+
}: {
|
|
24
|
+
textLines: string[];
|
|
25
|
+
d: ScaledDataRecord;
|
|
26
|
+
args: ComponentProps<typeof Text>;
|
|
27
|
+
usedScales: UsedScales;
|
|
28
|
+
} = $props();
|
|
29
|
+
|
|
30
|
+
const title = $derived(resolveProp(args.title, d.datum, ''));
|
|
31
|
+
const frameAnchor = $derived(resolveProp(args.frameAnchor, d.datum));
|
|
32
|
+
const isLeft = $derived(
|
|
33
|
+
frameAnchor === 'left' || frameAnchor === 'top-left' || frameAnchor === 'bottom-left'
|
|
34
|
+
);
|
|
35
|
+
const isRight = $derived(
|
|
36
|
+
frameAnchor === 'right' || frameAnchor === 'top-right' || frameAnchor === 'bottom-right'
|
|
37
|
+
);
|
|
38
|
+
const isTop = $derived(
|
|
39
|
+
frameAnchor === 'top' || frameAnchor === 'top-left' || frameAnchor === 'top-right'
|
|
40
|
+
);
|
|
41
|
+
const isBottom = $derived(
|
|
42
|
+
frameAnchor === 'bottom' || frameAnchor === 'bottom-left' || frameAnchor === 'bottom-right'
|
|
43
|
+
);
|
|
44
|
+
const lineAnchor = $derived(
|
|
45
|
+
resolveProp(
|
|
46
|
+
args.lineAnchor,
|
|
47
|
+
d.datum,
|
|
48
|
+
args.y != null ? 'middle' : isTop ? 'top' : isBottom ? 'bottom' : 'middle'
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
const textClassName = $derived(resolveProp(args.textClass, d.datum, null));
|
|
52
|
+
const [x, y] = $derived(
|
|
53
|
+
args.x != null && args.y != null
|
|
54
|
+
? [d.x, d.y]
|
|
55
|
+
: [
|
|
56
|
+
args.x != null
|
|
57
|
+
? d.x
|
|
58
|
+
: isLeft
|
|
59
|
+
? plot.options.marginLeft
|
|
60
|
+
: isRight
|
|
61
|
+
? plot.options.marginLeft + plot.facetWidth
|
|
62
|
+
: plot.options.marginLeft + plot.facetWidth * 0.5,
|
|
63
|
+
args.y != null
|
|
64
|
+
? d.y
|
|
65
|
+
: isTop
|
|
66
|
+
? plot.options.marginTop
|
|
67
|
+
: isBottom
|
|
68
|
+
? plot.options.marginTop + plot.facetHeight
|
|
69
|
+
: plot.options.marginTop + plot.facetHeight * 0.5
|
|
70
|
+
]
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const dx = $derived(+resolveProp(args.dx, d.datum, 0));
|
|
74
|
+
const dy = $derived(+resolveProp(args.dy, d.datum, 0));
|
|
75
|
+
|
|
76
|
+
const [style, styleClass] = $derived(
|
|
77
|
+
resolveStyles(
|
|
78
|
+
plot,
|
|
79
|
+
{ ...d, __tspanIndex: 0 },
|
|
80
|
+
{
|
|
81
|
+
fontSize: 12,
|
|
82
|
+
fontWeight: 500,
|
|
83
|
+
strokeWidth: 1.6,
|
|
84
|
+
textAnchor: isLeft ? 'start' : isRight ? 'end' : 'middle',
|
|
85
|
+
...args
|
|
86
|
+
},
|
|
87
|
+
'fill',
|
|
88
|
+
usedScales
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const fontSize = $derived(
|
|
93
|
+
textLines.length > 1 ? (resolveProp(args.fontSize, d.datum) ?? 12) : 0
|
|
94
|
+
);
|
|
95
|
+
let textElement: SVGTextElement | null = $state(null);
|
|
96
|
+
|
|
97
|
+
const rootFontSize = $derived(
|
|
98
|
+
textElement?.ownerDocument?.documentElement && textLines.length > 1
|
|
99
|
+
? maybeFromPixel(getComputedStyle(textElement.ownerDocument.documentElement).fontSize)
|
|
100
|
+
: 14
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const computedFontSize = $derived(
|
|
104
|
+
textElement && textLines.length > 1 && CSS_VAR.test(fontSize)
|
|
105
|
+
? maybeFromRem(
|
|
106
|
+
maybeFromPixel(
|
|
107
|
+
getComputedStyle(textElement).getPropertyValue(
|
|
108
|
+
`--${fontSize.match(CSS_VAR)[1]}`
|
|
109
|
+
)
|
|
110
|
+
),
|
|
111
|
+
rootFontSize
|
|
112
|
+
)
|
|
113
|
+
: fontSize
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const lineHeight = $derived(
|
|
117
|
+
textLines.length > 1 ? (resolveProp(args.lineHeight, d.datum) ?? 1.2) : 0
|
|
118
|
+
);
|
|
119
|
+
</script>
|
|
120
|
+
|
|
121
|
+
{#if textLines.length > 1}
|
|
122
|
+
<!-- multiline text-->
|
|
123
|
+
<text
|
|
124
|
+
bind:this={textElement}
|
|
125
|
+
class={[textClassName]}
|
|
126
|
+
dominant-baseline={LINE_ANCHOR[lineAnchor]}
|
|
127
|
+
transform="translate({Math.round(x + dx)},{Math.round(
|
|
128
|
+
y +
|
|
129
|
+
dy -
|
|
130
|
+
(lineAnchor === 'bottom'
|
|
131
|
+
? textLines.length - 1
|
|
132
|
+
: lineAnchor === 'middle'
|
|
133
|
+
? (textLines.length - 1) * 0.5
|
|
134
|
+
: 0) *
|
|
135
|
+
computedFontSize *
|
|
136
|
+
lineHeight
|
|
137
|
+
)})"
|
|
138
|
+
>{#each textLines as line, l (l)}<tspan
|
|
139
|
+
x="0"
|
|
140
|
+
dy={l ? computedFontSize * lineHeight : 0}
|
|
141
|
+
class={styleClass}
|
|
142
|
+
{style}>{line}</tspan
|
|
143
|
+
>{/each}{#if title}<title>{title}</title>{/if}</text>
|
|
144
|
+
{:else}
|
|
145
|
+
<!-- singleline text-->
|
|
146
|
+
<text
|
|
147
|
+
class={[textClassName, styleClass]}
|
|
148
|
+
dominant-baseline={LINE_ANCHOR[lineAnchor]}
|
|
149
|
+
transform="translate({Math.round(x + dx)},{Math.round(y + dy)})"
|
|
150
|
+
{style}
|
|
151
|
+
>{textLines[0]}{#if title}<title>{title}</title>{/if}</text>
|
|
152
|
+
{/if}
|
|
153
|
+
|
|
154
|
+
<style>
|
|
155
|
+
text {
|
|
156
|
+
paint-order: stroke fill;
|
|
157
|
+
}
|
|
158
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ComponentProps } from 'svelte';
|
|
2
|
+
import type { ScaledDataRecord, UsedScales } from '../../types';
|
|
3
|
+
import type Text from '../Text.svelte';
|
|
4
|
+
type $$ComponentProps = {
|
|
5
|
+
textLines: string[];
|
|
6
|
+
d: ScaledDataRecord;
|
|
7
|
+
args: ComponentProps<typeof Text>;
|
|
8
|
+
usedScales: UsedScales;
|
|
9
|
+
};
|
|
10
|
+
declare const MultilineText: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type MultilineText = ReturnType<typeof MultilineText>;
|
|
12
|
+
export default MultilineText;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelteplot",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Gregor Aisch",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@sveltejs/adapter-auto": "^6.0.1",
|
|
40
40
|
"@sveltejs/adapter-static": "^3.0.8",
|
|
41
41
|
"@sveltejs/eslint-config": "^8.2.0",
|
|
42
|
-
"@sveltejs/kit": "^2.21.
|
|
42
|
+
"@sveltejs/kit": "^2.21.4",
|
|
43
43
|
"@sveltejs/package": "^2.3.11",
|
|
44
44
|
"@sveltejs/vite-plugin-svelte": "5.1.0",
|
|
45
45
|
"@sveltepress/theme-default": "^6.0.3",
|
|
@@ -57,15 +57,15 @@
|
|
|
57
57
|
"@types/d3-scale": "^4.0.9",
|
|
58
58
|
"@types/d3-scale-chromatic": "^3.1.0",
|
|
59
59
|
"@types/d3-shape": "^3.1.7",
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
61
|
-
"@typescript-eslint/parser": "^8.
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^8.34.0",
|
|
61
|
+
"@typescript-eslint/parser": "^8.34.0",
|
|
62
62
|
"csstype": "^3.1.3",
|
|
63
63
|
"d3-dsv": "^3.0.1",
|
|
64
64
|
"d3-fetch": "^3.0.1",
|
|
65
65
|
"d3-force": "^3.0.0",
|
|
66
66
|
"eslint": "^9.28.0",
|
|
67
67
|
"eslint-config-prettier": "^10.1.5",
|
|
68
|
-
"eslint-plugin-svelte": "3.9.
|
|
68
|
+
"eslint-plugin-svelte": "3.9.2",
|
|
69
69
|
"jsdom": "^26.1.0",
|
|
70
70
|
"prettier": "^3.5.3",
|
|
71
71
|
"prettier-plugin-svelte": "^3.4.0",
|
|
@@ -73,19 +73,19 @@
|
|
|
73
73
|
"remark-code-extra": "^1.0.1",
|
|
74
74
|
"remark-code-frontmatter": "^1.0.0",
|
|
75
75
|
"resize-observer-polyfill": "^1.5.1",
|
|
76
|
-
"sass": "^1.89.
|
|
76
|
+
"sass": "^1.89.2",
|
|
77
77
|
"svelte-check": "^4.2.1",
|
|
78
78
|
"svelte-eslint-parser": "1.2.0",
|
|
79
79
|
"svelte-highlight": "^7.8.3",
|
|
80
80
|
"svg-path-parser": "^1.1.0",
|
|
81
81
|
"topojson-client": "^3.1.0",
|
|
82
|
-
"ts-essentials": "^10.0
|
|
82
|
+
"ts-essentials": "^10.1.0",
|
|
83
83
|
"tslib": "^2.8.1",
|
|
84
84
|
"typedoc": "^0.28.5",
|
|
85
85
|
"typedoc-plugin-markdown": "^4.6.4",
|
|
86
86
|
"typescript": "^5.8.3",
|
|
87
87
|
"vite": "^6.3.5",
|
|
88
|
-
"vitest": "^3.2.
|
|
88
|
+
"vitest": "^3.2.3",
|
|
89
89
|
"vitest-matchmedia-mock": "^2.0.3"
|
|
90
90
|
},
|
|
91
91
|
"types": "./dist/index.d.ts",
|
|
@@ -104,10 +104,10 @@
|
|
|
104
104
|
"d3-scale-chromatic": "^3.1.0",
|
|
105
105
|
"d3-shape": "^3.2.0",
|
|
106
106
|
"d3-time": "^3.1.0",
|
|
107
|
-
"es-toolkit": "^1.39.
|
|
107
|
+
"es-toolkit": "^1.39.3",
|
|
108
108
|
"fast-equals": "^5.2.2",
|
|
109
109
|
"merge-deep": "^3.0.3",
|
|
110
|
-
"svelte": "5.33.
|
|
110
|
+
"svelte": "5.33.19"
|
|
111
111
|
},
|
|
112
112
|
"scripts": {
|
|
113
113
|
"dev": "vite dev",
|