layerchart 2.0.0-next.37 → 2.0.0-next.39

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.
Files changed (115) hide show
  1. package/dist/components/AnnotationLine.svelte +15 -2
  2. package/dist/components/AnnotationPoint.svelte +13 -2
  3. package/dist/components/AnnotationRange.svelte +16 -2
  4. package/dist/components/Arc.svelte +3 -3
  5. package/dist/components/Area.svelte +10 -2
  6. package/dist/components/Axis.svelte +43 -26
  7. package/dist/components/Axis.svelte.d.ts +10 -3
  8. package/dist/components/Bar.svelte +6 -5
  9. package/dist/components/Bar.svelte.d.ts +2 -2
  10. package/dist/components/Bars.svelte +3 -3
  11. package/dist/components/Blur.svelte +2 -3
  12. package/dist/components/BrushContext.svelte +44 -44
  13. package/dist/components/Calendar.svelte +21 -4
  14. package/dist/components/Chart.svelte +1 -2
  15. package/dist/components/Chart.svelte.d.ts +10 -3
  16. package/dist/components/ChartClipPath.svelte +1 -1
  17. package/dist/components/Circle.svelte +44 -3
  18. package/dist/components/CircleClipPath.svelte +8 -1
  19. package/dist/components/ClipPath.svelte +1 -2
  20. package/dist/components/ColorRamp.svelte +1 -1
  21. package/dist/components/ComputedStyles.svelte +9 -2
  22. package/dist/components/Connector.svelte +1 -1
  23. package/dist/components/Ellipse.svelte +44 -3
  24. package/dist/components/ForceSimulation.svelte.d.ts +10 -3
  25. package/dist/components/Frame.svelte +1 -1
  26. package/dist/components/GeoCircle.svelte +1 -1
  27. package/dist/components/GeoEdgeFade.svelte +1 -1
  28. package/dist/components/GeoPath.svelte +18 -3
  29. package/dist/components/GeoPoint.svelte +3 -3
  30. package/dist/components/GeoSpline.svelte +1 -1
  31. package/dist/components/GeoTile.svelte +1 -1
  32. package/dist/components/Graticule.svelte +5 -5
  33. package/dist/components/Grid.svelte +57 -60
  34. package/dist/components/Group.svelte +11 -6
  35. package/dist/components/Group.svelte.d.ts +10 -3
  36. package/dist/components/Highlight.svelte +46 -22
  37. package/dist/components/Highlight.svelte.d.ts +4 -0
  38. package/dist/components/Hull.svelte +11 -4
  39. package/dist/components/Labels.svelte +21 -11
  40. package/dist/components/Labels.svelte.d.ts +10 -3
  41. package/dist/components/Legend.svelte +133 -67
  42. package/dist/components/Legend.svelte.d.ts +7 -3
  43. package/dist/components/Line.svelte +40 -3
  44. package/dist/components/LinearGradient.svelte +35 -4
  45. package/dist/components/Link.svelte +1 -1
  46. package/dist/components/Marker.svelte +37 -26
  47. package/dist/components/MonthPath.svelte +14 -3
  48. package/dist/components/MotionPath.svelte +1 -1
  49. package/dist/components/Pack.svelte.d.ts +10 -3
  50. package/dist/components/Partition.svelte.d.ts +10 -3
  51. package/dist/components/Pattern.svelte +5 -5
  52. package/dist/components/Pie.svelte +1 -2
  53. package/dist/components/Points.svelte +1 -3
  54. package/dist/components/Polygon.svelte +27 -3
  55. package/dist/components/RadialGradient.svelte +3 -3
  56. package/dist/components/Rect.svelte +55 -5
  57. package/dist/components/Rect.svelte.d.ts +2 -2
  58. package/dist/components/RectClipPath.svelte +4 -3
  59. package/dist/components/RectClipPath.svelte.d.ts +2 -2
  60. package/dist/components/Rule.svelte +30 -23
  61. package/dist/components/Spline.svelte +29 -10
  62. package/dist/components/Text.svelte +59 -13
  63. package/dist/components/TileImage.svelte +19 -4
  64. package/dist/components/TransformContext.svelte +9 -3
  65. package/dist/components/TransformControls.svelte +72 -17
  66. package/dist/components/Tree.svelte.d.ts +10 -3
  67. package/dist/components/Treemap.svelte.d.ts +10 -3
  68. package/dist/components/Voronoi.svelte +12 -13
  69. package/dist/components/charts/ArcChart.svelte +40 -69
  70. package/dist/components/charts/ArcChart.svelte.d.ts +10 -3
  71. package/dist/components/charts/AreaChart.svelte +19 -42
  72. package/dist/components/charts/AreaChart.svelte.d.ts +10 -3
  73. package/dist/components/charts/BarChart.svelte +7 -18
  74. package/dist/components/charts/BarChart.svelte.d.ts +10 -3
  75. package/dist/components/charts/DefaultTooltip.svelte +2 -2
  76. package/dist/components/charts/DefaultTooltip.svelte.d.ts +1 -1
  77. package/dist/components/charts/LineChart.svelte +61 -66
  78. package/dist/components/charts/LineChart.svelte.d.ts +21 -8
  79. package/dist/components/charts/PieChart.svelte +41 -69
  80. package/dist/components/charts/PieChart.svelte.d.ts +10 -3
  81. package/dist/components/charts/ScatterChart.svelte +8 -19
  82. package/dist/components/charts/ScatterChart.svelte.d.ts +10 -3
  83. package/dist/components/charts/utils.svelte.d.ts +1 -19
  84. package/dist/components/charts/utils.svelte.js +7 -39
  85. package/dist/components/layout/Canvas.svelte +29 -20
  86. package/dist/components/layout/Html.svelte +15 -9
  87. package/dist/components/layout/Svg.svelte +19 -11
  88. package/dist/components/layout/WebGL.svelte +26 -6
  89. package/dist/components/layout/WebGL.svelte.d.ts +5 -2
  90. package/dist/components/tooltip/Tooltip.svelte +60 -29
  91. package/dist/components/tooltip/Tooltip.svelte.d.ts +10 -3
  92. package/dist/components/tooltip/TooltipContext.svelte +73 -36
  93. package/dist/components/tooltip/TooltipContext.svelte.d.ts +17 -3
  94. package/dist/components/tooltip/TooltipHeader.svelte +27 -14
  95. package/dist/components/tooltip/TooltipItem.svelte +41 -33
  96. package/dist/components/tooltip/TooltipList.svelte +12 -10
  97. package/dist/components/tooltip/TooltipSeparator.svelte +18 -10
  98. package/dist/states/series.svelte.d.ts +30 -0
  99. package/dist/states/series.svelte.js +54 -0
  100. package/dist/styles/daisyui-5.css +6 -0
  101. package/dist/styles/shadcn-svelte.css +11 -0
  102. package/dist/styles/skeleton-3.css +15 -0
  103. package/dist/utils/attributes.d.ts +3 -13
  104. package/dist/utils/attributes.js +4 -18
  105. package/dist/utils/common.d.ts +9 -0
  106. package/dist/utils/common.js +18 -1
  107. package/dist/utils/common.test.js +26 -1
  108. package/dist/utils/graph/dagre.d.ts +4 -4
  109. package/dist/utils/graph/dagre.js +5 -7
  110. package/dist/utils/math.d.ts +17 -0
  111. package/dist/utils/math.js +17 -0
  112. package/dist/utils/scales.svelte.js +3 -3
  113. package/dist/utils/stack.js +1 -1
  114. package/dist/utils/types.d.ts +15 -2
  115. package/package.json +25 -22
@@ -172,11 +172,11 @@
172
172
  </script>
173
173
 
174
174
  <script lang="ts" generics="TData">
175
- import { onMount, type ComponentProps, type Snippet } from 'svelte';
175
+ import { onMount, type ComponentProps } from 'svelte';
176
176
  import { format } from '@layerstack/utils';
177
- import { cls } from '@layerstack/tailwind';
178
- import { SelectionState } from '@layerstack/svelte-state';
179
177
  import type { PieArcDatum } from 'd3-shape';
178
+ import { schemeObservable10 } from 'd3-scale-chromatic';
179
+ import { getObjectOrNull } from '../../utils/common.js';
180
180
 
181
181
  import Arc from '../Arc.svelte';
182
182
  import Chart from '../Chart.svelte';
@@ -194,7 +194,8 @@
194
194
  SimplifiedChartPropsObject,
195
195
  SimplifiedChartSnippet,
196
196
  } from './types.js';
197
- import { HighlightKey } from './utils.svelte.js';
197
+ import { SeriesState } from '../../states/series.svelte.js';
198
+ import { createLegendProps } from './utils.svelte.js';
198
199
  import { setTooltipMetaContext } from '../tooltip/tooltipMetaContext.js';
199
200
 
200
201
  let {
@@ -237,67 +238,37 @@
237
238
  const series = $derived(
238
239
  seriesProp === undefined ? [{ key: 'default', value: value }] : seriesProp
239
240
  );
241
+ const seriesState = new SeriesState(() => series);
240
242
 
241
243
  const keyAccessor = $derived(accessor(key));
242
244
  const labelAccessor = $derived(accessor(label));
243
245
  const valueAccessor = $derived(accessor(value));
244
246
  const cAccessor = $derived(accessor(c));
245
247
 
246
- const allSeriesData = $derived(
247
- series
248
- .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d })))
249
- .filter((d) => d) as Array<TData>
250
- );
251
-
252
248
  const chartData = $derived(
253
- allSeriesData.length ? allSeriesData : chartDataArray(data)
249
+ seriesState.allSeriesData.length ? seriesState.allSeriesData : chartDataArray(data)
254
250
  ) as Array<TData>;
255
251
 
256
- const seriesColors = $derived(series.map((s) => s.color).filter((d) => d != null));
257
-
258
- const highlightKey = new HighlightKey<TData, typeof Arc>();
259
- const selectedKeys = new SelectionState();
260
- const selectedSeries = new SelectionState();
261
-
262
252
  const visibleData = $derived(
263
253
  chartData.filter((d) => {
264
254
  const dataKey = keyAccessor(d);
265
- return selectedKeys.isEmpty() || selectedKeys.isSelected(dataKey);
255
+ return seriesState.selectedKeys.isEmpty() || seriesState.selectedKeys.isSelected(dataKey);
266
256
  })
267
257
  );
268
258
 
269
- // TODO: note, I added this because it wasn't consistent with all the other charts
270
- // unsure if it is correct but will validate with Sean
271
- const visibleSeries = $derived(
272
- series.filter((s) => selectedSeries.isEmpty() || selectedSeries.isSelected(s.key))
273
- );
274
-
275
259
  function getLegendProps(): ComponentProps<typeof Legend> {
276
- return {
277
- tickFormat: (tick) => {
278
- const item = chartData.find((d) => keyAccessor(d) === tick);
279
- return item ? (labelAccessor(item) ?? tick) : tick;
280
- },
281
- placement: 'bottom',
282
- variant: 'swatches',
283
- onclick: (e, item) => {
284
- selectedKeys.toggle(item.value);
285
- // TODO: investigate
286
- // selectedSeries.toggle(item.value);
287
- },
288
- onpointerenter: (e, item) => (highlightKey.current = item.value),
289
- onpointerleave: (e) => (highlightKey.current = null),
290
- ...props.legend,
291
- ...(typeof legend === 'object' ? legend : null),
292
- classes: {
293
- item: (item) =>
294
- visibleData.length && !visibleData.some((d) => keyAccessor(d) === item.value)
295
- ? 'opacity-50'
296
- : '',
297
- ...props.legend?.classes,
298
- ...(typeof legend === 'object' ? legend.classes : null),
260
+ return createLegendProps({
261
+ seriesState,
262
+ props: {
263
+ tickFormat: (tick) => {
264
+ // Use data label instead of series label
265
+ const item = chartData.find((d) => keyAccessor(d) === tick);
266
+ return item ? (labelAccessor(item) ?? tick) : tick;
267
+ },
268
+ ...props.legend,
269
+ ...getObjectOrNull(legend),
299
270
  },
300
- };
271
+ });
301
272
  }
302
273
 
303
274
  function getGroupProps(): ComponentProps<typeof Group> {
@@ -338,7 +309,8 @@
338
309
  return {
339
310
  startAngle: arc.startAngle,
340
311
  endAngle: arc.endAngle,
341
- outerRadius: visibleSeries.length > 1 ? seriesIndex * (outerRadius ?? 0) : outerRadius,
312
+ outerRadius:
313
+ seriesState.visibleSeries.length > 1 ? seriesIndex * (outerRadius ?? 0) : outerRadius,
342
314
  innerRadius,
343
315
  cornerRadius,
344
316
  padAngle,
@@ -350,10 +322,7 @@
350
322
  // Workaround for `tooltip={{ mode: 'manual' }}
351
323
  onTooltipClick(e, { data: arc.data });
352
324
  },
353
- class: cls(
354
- 'transition-opacity',
355
- highlightKey.current && highlightKey.current !== keyAccessor(arc.data) && 'opacity-50'
356
- ),
325
+ opacity: seriesState.isHighlighted(keyAccessor(arc.data), true) ? 1 : 0.5,
357
326
  ...props.arc,
358
327
  ...s.props,
359
328
  ...arcDataProps,
@@ -382,7 +351,7 @@
382
351
  return key;
383
352
  },
384
353
  get visibleSeries() {
385
- return visibleSeries;
354
+ return seriesState.visibleSeries;
386
355
  },
387
356
  });
388
357
  </script>
@@ -394,19 +363,21 @@
394
363
  x={value}
395
364
  c={key}
396
365
  cDomain={chartData.map(keyAccessor)}
397
- cRange={seriesColors.length
398
- ? seriesColors
366
+ cRange={seriesState.allSeriesColors.length
367
+ ? seriesState.allSeriesColors
399
368
  : c !== key
400
369
  ? chartData.map((d) => cAccessor(d))
401
370
  : [
402
- 'var(--color-primary)',
403
- 'var(--color-secondary)',
404
- 'var(--color-info)',
405
- 'var(--color-success)',
406
- 'var(--color-warning)',
407
- 'var(--color-danger)',
371
+ `var(--color-primary, ${schemeObservable10[0]})`,
372
+ `var(--color-secondary, ${schemeObservable10[1]})`,
373
+ `var(--color-info, ${schemeObservable10[2]})`,
374
+ `var(--color-success, ${schemeObservable10[3]})`,
375
+ `var(--color-warning, ${schemeObservable10[4]})`,
376
+ `var(--color-danger, ${schemeObservable10[5]})`,
408
377
  ]}
409
- padding={{ bottom: legend === true ? 32 : 0 }}
378
+ padding={{
379
+ bottom: legend === true || getObjectOrNull(legend)?.placement?.includes('bottom') ? 32 : 0,
380
+ }}
410
381
  {...restProps}
411
382
  tooltip={tooltip === false
412
383
  ? false
@@ -420,10 +391,10 @@
420
391
  color: cAccessor,
421
392
  context,
422
393
  series,
423
- visibleSeries,
394
+ visibleSeries: seriesState.visibleSeries,
424
395
  visibleData,
425
- highlightKey: highlightKey.current,
426
- setHighlightKey: highlightKey.set,
396
+ highlightKey: seriesState.highlightKey.current,
397
+ setHighlightKey: seriesState.highlightKey.set,
427
398
  getLegendProps,
428
399
  getGroupProps,
429
400
  }}
@@ -444,7 +415,8 @@
444
415
  {@render marks(snippetProps)}
445
416
  {:else}
446
417
  <Group {...getGroupProps()}>
447
- {#each visibleSeries as s, seriesIdx (s.key)}
418
+ <!-- Use `series` instead of `visibleSeries` since data is filtered (legend) instead of series -->
419
+ {#each series as s, seriesIdx (s.key)}
448
420
  {#if typeof pie === 'function'}
449
421
  {@render pie({
450
422
  ...snippetProps,
@@ -496,8 +468,8 @@
496
468
  value={valueAccessor(data)}
497
469
  color={context.cScale?.(context.c(data))}
498
470
  {format}
499
- onpointerenter={() => (highlightKey.current = keyAccessor(data))}
500
- onpointerleave={() => (highlightKey.current = null)}
471
+ onpointerenter={() => (seriesState.highlightKey.current = keyAccessor(data))}
472
+ onpointerleave={() => (seriesState.highlightKey.current = null)}
501
473
  {...props.tooltip?.item}
502
474
  />
503
475
  </Tooltip.List>
@@ -126,10 +126,17 @@ import Group from '../Group.svelte';
126
126
  import Pie from '../Pie.svelte';
127
127
  import { type Accessor } from '../../utils/common.js';
128
128
  import type { SeriesData, SimplifiedChartProps, SimplifiedChartPropsObject, SimplifiedChartSnippet } from './types.js';
129
+ declare function $$render<TData>(): {
130
+ props: PieChartProps<TData>;
131
+ exports: {};
132
+ bindings: "context";
133
+ slots: {};
134
+ events: {};
135
+ };
129
136
  declare class __sveltets_Render<TData> {
130
- props(): PieChartProps<TData>;
131
- events(): {};
132
- slots(): {};
137
+ props(): ReturnType<typeof $$render<TData>>['props'];
138
+ events(): ReturnType<typeof $$render<TData>>['events'];
139
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
133
140
  bindings(): "context";
134
141
  exports(): {};
135
142
  }
@@ -61,9 +61,10 @@
61
61
  import Rule from '../Rule.svelte';
62
62
  import * as Tooltip from '../tooltip/index.js';
63
63
 
64
- import { accessor, chartDataArray, defaultChartPadding } from '../../utils/common.js';
64
+ import { chartDataArray, defaultChartPadding } from '../../utils/common.js';
65
65
  import { asAny } from '../../utils/types.js';
66
- import { createLegendProps, SeriesState } from './utils.svelte.js';
66
+ import { SeriesState } from '../../states/series.svelte.js';
67
+ import { createLegendProps } from './utils.svelte.js';
67
68
 
68
69
  let {
69
70
  data = [],
@@ -117,16 +118,10 @@
117
118
  return {
118
119
  data: s.data,
119
120
  fill: s.color,
121
+ opacity: seriesState.isHighlighted(s.key, true) ? 1 : 0.1,
120
122
  ...props.points,
121
123
  ...s.props,
122
- class: cls(
123
- 'transition-opacity',
124
- seriesState.highlightKey.current &&
125
- seriesState.highlightKey.current !== s.key &&
126
- 'opacity-10',
127
- props.points?.class,
128
- s.props?.class
129
- ),
124
+ class: cls(props.points?.class, s.props?.class),
130
125
  };
131
126
  }
132
127
 
@@ -136,16 +131,10 @@
136
131
  ): ComponentProps<typeof Labels<TData>> {
137
132
  return {
138
133
  data: s.data,
134
+ opacity: seriesState.isHighlighted(s.key, true) ? 1 : 0.1,
139
135
  ...props.labels,
140
136
  ...(typeof labels === 'object' ? labels : null),
141
- class: cls(
142
- 'stroke-surface-200 transition-opacity',
143
- seriesState.highlightKey.current &&
144
- seriesState.highlightKey.current !== s.key &&
145
- 'opacity-10',
146
- props.labels?.class,
147
- typeof labels === 'object' && labels.class
148
- ),
137
+ class: cls(props.labels?.class, typeof labels === 'object' && labels.class),
149
138
  };
150
139
  }
151
140
 
@@ -230,7 +219,7 @@
230
219
  {yDomain}
231
220
  yNice
232
221
  c={yProp}
233
- cRange={['var(--color-primary)']}
222
+ cRange={['var(--color-primary, currentColor)']}
234
223
  padding={defaultChartPadding(axis, legend)}
235
224
  {...restProps}
236
225
  tooltip={tooltip === false
@@ -20,10 +20,17 @@ import Highlight from '../Highlight.svelte';
20
20
  import Labels from '../Labels.svelte';
21
21
  import Points from '../Points.svelte';
22
22
  import Rule from '../Rule.svelte';
23
+ declare function $$render<TData>(): {
24
+ props: ScatterChartProps<TData>;
25
+ exports: {};
26
+ bindings: "context";
27
+ slots: {};
28
+ events: {};
29
+ };
23
30
  declare class __sveltets_Render<TData> {
24
- props(): ScatterChartProps<TData>;
25
- events(): {};
26
- slots(): {};
31
+ props(): ReturnType<typeof $$render<TData>>['props'];
32
+ events(): ReturnType<typeof $$render<TData>>['events'];
33
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
27
34
  bindings(): "context";
28
35
  exports(): {};
29
36
  }
@@ -1,24 +1,6 @@
1
1
  import type { Component, ComponentProps } from 'svelte';
2
- import { SelectionState } from '@layerstack/svelte-state';
3
- import type { SeriesData } from './types.js';
4
2
  import type Legend from '../Legend.svelte';
5
- export declare class HighlightKey<TData, SeriesComponent extends Component> {
6
- current: string | null;
7
- set: (seriesKey: typeof this.current) => void;
8
- }
9
- export declare class SeriesState<TData, TComponent extends Component> {
10
- #private;
11
- selectedSeries: SelectionState<unknown, false>;
12
- selectedKeys: SelectionState<unknown, false>;
13
- highlightKey: HighlightKey<TData, TComponent>;
14
- constructor(getSeries: () => SeriesData<TData, TComponent>[]);
15
- get series(): SeriesData<TData, TComponent>[];
16
- get isDefaultSeries(): boolean;
17
- get allSeriesData(): Array<TData & {
18
- seriesKey: string;
19
- }>;
20
- get visibleSeries(): SeriesData<TData, TComponent>[];
21
- }
3
+ import type { SeriesState } from '../../states/series.svelte.js';
22
4
  type CreateLegendPropsOptions<TData, TComponent extends Component> = {
23
5
  seriesState: SeriesState<TData, TComponent>;
24
6
  props: Partial<ComponentProps<typeof Legend>>;
@@ -1,38 +1,6 @@
1
- import { SelectionState } from '@layerstack/svelte-state';
2
1
  import { scaleOrdinal } from 'd3-scale';
3
- export class HighlightKey {
4
- current = $state(null);
5
- set = (seriesKey) => {
6
- this.current = seriesKey;
7
- };
8
- }
9
- export class SeriesState {
10
- #series = $state.raw([]);
11
- selectedSeries = new SelectionState();
12
- selectedKeys = new SelectionState();
13
- highlightKey = new HighlightKey();
14
- constructor(getSeries) {
15
- this.#series = getSeries();
16
- $effect.pre(() => {
17
- // keep series state in sync with the prop
18
- this.#series = getSeries();
19
- });
20
- }
21
- get series() {
22
- return this.#series;
23
- }
24
- get isDefaultSeries() {
25
- return this.#series.length === 1 && this.#series[0].key === 'default';
26
- }
27
- get allSeriesData() {
28
- return this.#series
29
- .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d })))
30
- .filter((d) => d);
31
- }
32
- get visibleSeries() {
33
- return this.#series.filter((s) => this.selectedSeries.isEmpty() || this.selectedSeries.isSelected(s.key));
34
- }
35
- }
2
+ import { cls } from '@layerstack/tailwind';
3
+ import { resolveMaybeFn } from '../../utils/common.js';
36
4
  /**
37
5
  * A prop builder for the legend component shared between the simplified charts.
38
6
  */
@@ -44,15 +12,15 @@ export function createLegendProps(opts) {
44
12
  tickFormat: (key) => opts.seriesState.series.find((s) => s.key === key)?.label ?? key,
45
13
  placement: 'bottom',
46
14
  variant: 'swatches',
47
- onclick: (_, item) => opts.seriesState.selectedSeries.toggle(item.value),
15
+ selected: opts.seriesState.selectedKeys.current,
16
+ onclick: (_, item) => opts.seriesState.selectedKeys.toggle(item.value),
48
17
  onpointerenter: (_, item) => (opts.seriesState.highlightKey.current = item.value),
49
18
  onpointerleave: () => (opts.seriesState.highlightKey.current = null),
50
19
  ...opts.props,
51
20
  classes: {
52
- item: (item) => opts.seriesState.visibleSeries.length &&
53
- !opts.seriesState.visibleSeries.some((s) => s.key === item.value)
54
- ? 'opacity-50'
55
- : '',
21
+ item: (item) => {
22
+ return cls(resolveMaybeFn(opts.props?.classes?.item, item));
23
+ },
56
24
  ...opts.props?.classes,
57
25
  },
58
26
  };
@@ -149,7 +149,6 @@
149
149
 
150
150
  <script lang="ts">
151
151
  import { onMount, untrack, type Snippet } from 'svelte';
152
- import { cls } from '@layerstack/tailwind';
153
152
  import { Logger, localPoint } from '@layerstack/utils';
154
153
  import { MediaQueryPresets } from '@layerstack/svelte-state';
155
154
 
@@ -166,7 +165,6 @@
166
165
  } from 'svelte/elements';
167
166
  import type { Without } from '../../utils/types.js';
168
167
  import { getChartContext } from '../Chart.svelte';
169
- import { layerClass } from '../../utils/attributes.js';
170
168
 
171
169
  let {
172
170
  ref: refProp = $bindable(),
@@ -453,12 +451,8 @@
453
451
  <canvas
454
452
  bind:this={ref}
455
453
  style:z-index={zIndex}
456
- class={cls(
457
- layerClass('layout-canvas'),
458
- 'absolute top-0 left-0 w-full h-full',
459
- pointerEvents === false && 'pointer-events-none',
460
- className
461
- )}
454
+ class={['lc-layout-canvas', className]}
455
+ class:disablePointerEvents={pointerEvents === false}
462
456
  onclick={(e) => {
463
457
  const component = getPointerComponent(e);
464
458
  component?.events?.click?.(e);
@@ -507,17 +501,32 @@
507
501
  </canvas>
508
502
 
509
503
  <!-- Hit canvas used for hidden context -->
510
- <canvas
511
- bind:this={hitCanvasElement}
512
- class={cls(
513
- layerClass('hit-canvas'),
514
- 'layerchart-hitcanvas',
515
- 'absolute top-0 left-0 w-full h-full',
516
- 'pointer-events-none', // events all handled by main canvas
517
- // '[image-rendering:pixelated]', // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering
518
- 'border border-danger',
519
- !debug && 'opacity-0'
520
- )}
521
- ></canvas>
504
+ <canvas bind:this={hitCanvasElement} class="lc-hit-canvas" class:debug></canvas>
522
505
 
523
506
  {@render children?.({ ref, canvasContext: context })}
507
+
508
+ <style>
509
+ @layer base {
510
+ :where(.lc-layout-canvas) {
511
+ position: absolute;
512
+ inset: 0;
513
+
514
+ &.disablePointerEvents {
515
+ pointer-events: none;
516
+ }
517
+ }
518
+
519
+ :where(.lc-hit-canvas) {
520
+ position: absolute;
521
+ inset: 0;
522
+ pointer-events: none; /* events handled by main canvas */
523
+ image-rendering: pixelated; /* https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering */
524
+
525
+ opacity: 0;
526
+ &.debug {
527
+ border: 1px solid var(--color-danger, red);
528
+ opacity: 1;
529
+ }
530
+ }
531
+ }
532
+ </style>
@@ -46,11 +46,9 @@
46
46
  </script>
47
47
 
48
48
  <script lang="ts">
49
- import { cls } from '@layerstack/tailwind';
50
49
  import { getTransformContext } from '../TransformContext.svelte';
51
50
 
52
51
  import { getChartContext, setRenderContext } from '../Chart.svelte';
53
- import { layerClass } from '../../utils/attributes.js';
54
52
 
55
53
  let {
56
54
  ref: refProp = $bindable(),
@@ -90,16 +88,11 @@
90
88
 
91
89
  <div
92
90
  bind:this={ref}
93
- class={cls(
94
- layerClass('layout-html'),
95
- 'absolute top-0 left-0',
96
- pointerEvents === false && 'pointer-events-none',
97
- className
98
- )}
91
+ class={['lc-layout-html', className]}
92
+ class:disablePointerEvents={pointerEvents === false}
99
93
  style:transform
100
94
  style:transform-origin="top left"
101
95
  style:z-index={zIndex}
102
- style:pointer-events={pointerEvents === false ? 'none' : null}
103
96
  style:top="{ctx.padding.top}px"
104
97
  style:bottom="{ctx.padding.bottom}px"
105
98
  style:left="{ctx.padding.left}px"
@@ -112,3 +105,16 @@
112
105
  >
113
106
  {@render children?.({ ref })}
114
107
  </div>
108
+
109
+ <style>
110
+ @layer base {
111
+ :where(.lc-layout-html) {
112
+ position: absolute;
113
+ inset: 0;
114
+
115
+ &.disablePointerEvents {
116
+ pointer-events: none;
117
+ }
118
+ }
119
+ }
120
+ </style>
@@ -63,11 +63,9 @@
63
63
  </script>
64
64
 
65
65
  <script lang="ts">
66
- import { cls } from '@layerstack/tailwind';
67
66
  import { getTransformContext } from '../TransformContext.svelte';
68
67
 
69
68
  import { getChartContext, setRenderContext } from '../Chart.svelte';
70
- import { layerClass } from '../../utils/attributes.js';
71
69
 
72
70
  let {
73
71
  ref: refProp = $bindable(),
@@ -114,19 +112,15 @@
114
112
  width={ctx.containerWidth}
115
113
  height={ctx.containerHeight}
116
114
  style:z-index={zIndex}
117
- class={cls(
118
- layerClass('layout-svg'),
119
- 'absolute top-0 left-0 overflow-visible',
120
- pointerEvents === false && 'pointer-events-none',
121
- className
122
- )}
115
+ class={['lc-layout-svg', className]}
116
+ class:disablePointerEvents={pointerEvents === false}
123
117
  role="figure"
124
118
  {...restProps}
125
119
  >
126
120
  {#if typeof title === 'function'}
127
121
  {@render title()}
128
122
  {:else if title}
129
- <title class={layerClass('layout-svg-title')}>{title}</title>
123
+ <title class="lc-layout-svg-title">{title}</title>
130
124
  {/if}
131
125
 
132
126
  <defs>
@@ -135,11 +129,11 @@
135
129
 
136
130
  <g
137
131
  bind:this={innerRef}
138
- class={layerClass('layout-svg-g')}
132
+ class="lc-layout-svg-g"
139
133
  transform="translate({ctx.padding.left}, {ctx.padding.top})"
140
134
  >
141
135
  {#if transform}
142
- <g {transform} class={layerClass('layout-svg-g-transform')}>
136
+ <g {transform} class="lc-layout-svg-g-transform">
143
137
  {@render children?.({ ref })}
144
138
  </g>
145
139
  {:else}
@@ -147,3 +141,17 @@
147
141
  {/if}
148
142
  </g>
149
143
  </svg>
144
+
145
+ <style>
146
+ @layer base {
147
+ :where(.lc-layout-svg) {
148
+ position: absolute;
149
+ inset: 0;
150
+ overflow: visible; /* match html and allow viewing outside of bounds (useful for axis that leak and general debugging)*/
151
+
152
+ &.disablePointerEvents {
153
+ pointer-events: none;
154
+ }
155
+ }
156
+ }
157
+ </style>
@@ -1,5 +1,9 @@
1
1
  <script lang="ts" module>
2
- export type WebGLProps = {
2
+ import type { Snippet } from 'svelte';
3
+ import type { Without } from '../../utils/types.js';
4
+ import type { HTMLCanvasAttributes } from 'svelte/elements';
5
+
6
+ export type WebGLPropsWithoutHTML = {
3
7
  /**
4
8
  * A reference to the `<canvas>` element.
5
9
  *
@@ -44,6 +48,9 @@
44
48
  >;
45
49
  };
46
50
 
51
+ export type WebGLProps = WebGLPropsWithoutHTML &
52
+ Without<HTMLCanvasAttributes, WebGLPropsWithoutHTML>;
53
+
47
54
  export type WebGLContextValue = {
48
55
  gl: WebGLRenderingContext | null;
49
56
  };
@@ -61,10 +68,9 @@
61
68
  </script>
62
69
 
63
70
  <script lang="ts">
64
- import { onMount, type Snippet } from 'svelte';
71
+ import { onMount } from 'svelte';
65
72
  import { getChartContext } from '../Chart.svelte';
66
73
  import { Context } from 'runed';
67
- import { extractLayerProps } from '../../utils/attributes.js';
68
74
 
69
75
  let {
70
76
  context = $bindable(),
@@ -73,6 +79,7 @@
73
79
  fallback = '',
74
80
  pointerEvents = true,
75
81
  zIndex = 0,
82
+ class: className,
76
83
  children,
77
84
  ...restProps
78
85
  }: WebGLProps = $props();
@@ -116,14 +123,14 @@
116
123
 
117
124
  <canvas
118
125
  bind:this={ref}
126
+ class={['lc-layout-webgl', className]}
127
+ class:disablePointerEvents={pointerEvents === false}
119
128
  style:z-index={zIndex}
120
- style:pointer-events={pointerEvents === false ? 'none' : null}
121
129
  style:top={ctx.padding.top + 'px'}
122
130
  style:right={ctx.padding.right + 'px'}
123
131
  style:bottom={ctx.padding.bottom + 'px'}
124
132
  style:left={ctx.padding.left + 'px'}
125
- style="width:100%;height:100%;position:absolute;"
126
- {...extractLayerProps(restProps, 'layout-webgl')}
133
+ {...restProps}
127
134
  >
128
135
  {#if typeof fallback === 'function'}
129
136
  {@render fallback()}
@@ -133,3 +140,16 @@
133
140
  </canvas>
134
141
 
135
142
  {@render children?.({ ref, webGLContext: context })}
143
+
144
+ <style>
145
+ @layer base {
146
+ :where(.lc-layout-webgl) {
147
+ position: absolute;
148
+ inset: 0;
149
+
150
+ &.disablePointerEvents {
151
+ pointer-events: none;
152
+ }
153
+ }
154
+ }
155
+ </style>
@@ -1,4 +1,7 @@
1
- export type WebGLProps = {
1
+ import type { Snippet } from 'svelte';
2
+ import type { Without } from '../../utils/types.js';
3
+ import type { HTMLCanvasAttributes } from 'svelte/elements';
4
+ export type WebGLPropsWithoutHTML = {
2
5
  /**
3
6
  * A reference to the `<canvas>` element.
4
7
  *
@@ -39,12 +42,12 @@ export type WebGLProps = {
39
42
  }
40
43
  ]>;
41
44
  };
45
+ export type WebGLProps = WebGLPropsWithoutHTML & Without<HTMLCanvasAttributes, WebGLPropsWithoutHTML>;
42
46
  export type WebGLContextValue = {
43
47
  gl: WebGLRenderingContext | null;
44
48
  };
45
49
  export declare function setWebGLContext(context: WebGLContextValue): WebGLContextValue;
46
50
  export declare function getWebGLContext(): WebGLContextValue;
47
- import { type Snippet } from 'svelte';
48
51
  declare const WebGl: import("svelte").Component<WebGLProps, {}, "ref" | "context">;
49
52
  type WebGl = ReturnType<typeof WebGl>;
50
53
  export default WebGl;