layerchart 0.38.2 → 0.38.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.
@@ -4,10 +4,11 @@
4
4
  // See: https://github.com/carbon-design-system/sveld/issues/104
5
5
  import { LayerCake,
6
6
  // Canvas as _Canvas,
7
- Html as _Html,
7
+ // Html as _Html,
8
8
  // Svg as _Svg,
9
9
  WebGL as _WebGL, } from 'layercake';
10
10
  import _Canvas from './layout/Canvas.svelte';
11
+ import _Html from './layout/Html.svelte';
11
12
  import _Svg from './layout/Svg.svelte';
12
13
  export const Canvas = _Canvas;
13
14
  export const Html = _Html;
@@ -1,6 +1,7 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import { Html as _Html, WebGL as _WebGL } from 'layercake';
2
+ import { WebGL as _WebGL } from 'layercake';
3
3
  import _Canvas from './layout/Canvas.svelte';
4
+ import _Html from './layout/Html.svelte';
4
5
  import _Svg from './layout/Svg.svelte';
5
6
  export declare const Canvas: typeof _Canvas;
6
7
  export declare const Html: typeof _Html;
@@ -50,24 +51,15 @@ declare const __propDef: {
50
51
  projection: import("d3-geo").GeoProjection | import("d3-geo").GeoIdentityTransform;
51
52
  transform: {
52
53
  scale: number;
53
- setScale: ((new_value: number, opts?: import("svelte/motion").SpringUpdateOpts | undefined) => Promise<void>) | ((value: number, opts?: import("svelte/motion").TweenedOptions<number> | undefined) => Promise<void>) | ((this: void, value: number) => void);
54
+ setScale: (value: number, options?: import("../stores/motionStore").MotionOptions | undefined) => void;
54
55
  translate: {
55
56
  x: number;
56
57
  y: number;
57
58
  };
58
- setTranslate: ((new_value: {
59
+ setTranslate: (point: {
59
60
  x: number;
60
61
  y: number;
61
- }, opts?: import("svelte/motion").SpringUpdateOpts | undefined) => Promise<void>) | ((value: {
62
- x: number;
63
- y: number;
64
- }, opts?: import("svelte/motion").TweenedOptions<{
65
- x: number;
66
- y: number;
67
- }> | undefined) => Promise<void>) | ((this: void, value: {
68
- x: number;
69
- y: number;
70
- }) => void);
62
+ }, options?: import("../stores/motionStore").MotionOptions | undefined) => void;
71
63
  zoomTo: (center: {
72
64
  x: number;
73
65
  y: number;
@@ -80,7 +72,7 @@ declare const __propDef: {
80
72
  tooltip: {
81
73
  y: number;
82
74
  x: number;
83
- data: null; /** Props passed to TransformContext */
75
+ data: null;
84
76
  show: (e: PointerEvent, tooltipData?: any) => void;
85
77
  hide: () => void;
86
78
  };
@@ -24,6 +24,8 @@ export let tooltip = undefined;
24
24
  * @type {CurveFactory | CurveFactoryLineOnly | undefined}
25
25
  */
26
26
  export let curve = curveLinearClosed;
27
+ let className = undefined;
28
+ export { className as class };
27
29
  const dispatch = createEventDispatcher();
28
30
  const { width, height } = getContext('LayerCake');
29
31
  const canvas = getContext('canvas');
@@ -35,8 +37,8 @@ $: ctx = canvas?.ctx;
35
37
  $: if (renderContext === 'canvas' && $ctx) {
36
38
  let computedStyles = {};
37
39
  // Transfer classes defined on <GeoPath> to <canvas> to enable window.getComputedStyle() retrieval (Tailwind classes, etc)
38
- if ($$props.class) {
39
- $ctx.canvas.classList.add(...$$props.class.split(' '));
40
+ if (className) {
41
+ $ctx.canvas.classList.add(...className.split(' '));
40
42
  computedStyles = window.getComputedStyle($ctx.canvas);
41
43
  }
42
44
  // console.count('render');
@@ -79,7 +81,7 @@ $: if (renderContext === 'canvas' && $ctx) {
79
81
  on:pointerleave
80
82
  on:click={(event) => dispatch('click', { geoPath, event })}
81
83
  on:click
82
- class={cls($$props.fill == null && 'fill-transparent', $$props.class)}
84
+ class={cls(fill == null && 'fill-transparent', className)}
83
85
  />
84
86
  </slot>
85
87
  {/if}
@@ -12,6 +12,7 @@ declare const __propDef: {
12
12
  strokeWidth?: number | string | undefined;
13
13
  tooltip?: TooltipContextValue | undefined;
14
14
  curve?: CurveFactory | CurveFactoryLineOnly | undefined;
15
+ class?: string | undefined;
15
16
  };
16
17
  events: {
17
18
  pointerenter: PointerEvent;
@@ -32,7 +32,7 @@ function* rgbColorGenerator(step = 500) {
32
32
  }
33
33
  $: colorGenerator = rgbColorGenerator();
34
34
  // Reset color generator whenever updated (width/height) so always reusing same colors (and not exhausting)
35
- const { translate, scale } = transformContext();
35
+ const { translate, scale, dragging } = transformContext();
36
36
  $: {
37
37
  $width;
38
38
  $height;
@@ -89,4 +89,8 @@ function dispatchPointerMove(e) {
89
89
  }
90
90
  }}
91
91
  />
92
- <slot nextColor={() => colorGenerator.next().value} {setColorData}></slot>
92
+
93
+ <!-- Do not render while dragging to improve interaction performance -->
94
+ {#if !$dragging}
95
+ <slot nextColor={() => colorGenerator.next().value} {setColorData}></slot>
96
+ {/if}
@@ -1,10 +1,15 @@
1
1
  <script context="module">import { getContext, setContext } from 'svelte';
2
- import { writable } from 'svelte/store';
2
+ import { writable, derived } from 'svelte/store';
3
3
  export const transformContextKey = Symbol();
4
+ const defaultTranslate = writable({ x: 0, y: 0 });
5
+ const defaultScale = writable(1);
4
6
  const defaultContext = {
5
7
  mode: 'none',
6
- scale: writable(1),
7
- translate: writable({ x: 0, y: 0 }),
8
+ scale: defaultScale,
9
+ setScale: defaultScale.set,
10
+ translate: defaultTranslate,
11
+ setTranslate: defaultTranslate.set,
12
+ moving: writable(false),
8
13
  dragging: writable(false),
9
14
  reset: () => { },
10
15
  zoomIn: () => { },
@@ -21,7 +26,7 @@ function setTransformContext(transform) {
21
26
  </script>
22
27
 
23
28
  <script>import { createEventDispatcher } from 'svelte';
24
- import { motionStore } from '../stores/motionStore.js';
29
+ import { motionStore, motionFinishHandler } from '../stores/motionStore.js';
25
30
  const { width, height } = getContext('LayerCake');
26
31
  export let mode = 'none';
27
32
  export let translateOnScale = false;
@@ -76,17 +81,6 @@ export function zoomTo(center, rect) {
76
81
  $scale = $width < $height ? $width / rect.width : $height / rect.height;
77
82
  }
78
83
  }
79
- setTransformContext({
80
- mode,
81
- scale,
82
- translate,
83
- dragging,
84
- reset,
85
- zoomIn,
86
- zoomOut,
87
- translateCenter,
88
- zoomTo,
89
- });
90
84
  function onPointerDown(e) {
91
85
  if (mode === 'none' || disablePointer)
92
86
  return;
@@ -111,11 +105,12 @@ function onPointerMove(e) {
111
105
  if ($dragging) {
112
106
  e.stopPropagation(); // Stop tooltip from trigging (along with `capture: true`)
113
107
  e.currentTarget.setPointerCapture(e.pointerId);
114
- translate.set(processTranslate(startTranslate.x, startTranslate.y, deltaX, deltaY, $scale), spring ? { hard: true } : tweened ? { duration: 0 } : undefined);
108
+ setTranslate(processTranslate(startTranslate.x, startTranslate.y, deltaX, deltaY, $scale), spring ? { hard: true } : tweened ? { duration: 0 } : undefined);
115
109
  }
116
110
  }
117
111
  function onPointerUp(e) {
118
112
  pointerDown = false;
113
+ $dragging = false;
119
114
  dispatch('dragend');
120
115
  }
121
116
  function onClick(e) {
@@ -152,7 +147,7 @@ function onWheel(e) {
152
147
  function scaleTo(value, point, options = undefined) {
153
148
  const currentScale = $scale;
154
149
  const newScale = $scale * value;
155
- scale.set(newScale, options);
150
+ setScale(newScale, options);
156
151
  if (translateOnScale) {
157
152
  // Translate towards point (ex. mouse cursor/center) while zooming in/out
158
153
  const invertTransformPoint = {
@@ -163,9 +158,18 @@ function scaleTo(value, point, options = undefined) {
163
158
  x: point.x - invertTransformPoint.x * newScale,
164
159
  y: point.y - invertTransformPoint.y * newScale,
165
160
  };
166
- translate.set(newTranslate, options);
161
+ setTranslate(newTranslate, options);
167
162
  }
168
163
  }
164
+ const translating = motionFinishHandler();
165
+ const scaling = motionFinishHandler();
166
+ const moving = derived([dragging, translating, scaling], ([dragging, translating, scaling]) => dragging || translating || scaling);
167
+ export function setTranslate(point, options) {
168
+ translating.handle(translate.set(point, options));
169
+ }
170
+ export function setScale(value, options) {
171
+ scaling.handle(scale.set(value, options));
172
+ }
169
173
  function localPoint(e) {
170
174
  return {
171
175
  x: e.offsetX,
@@ -178,6 +182,20 @@ $: viewportCenter = {
178
182
  y: center.y - $translate.y,
179
183
  };
180
184
  $: dispatch('transform', { scale: $scale, translate: $translate });
185
+ setTransformContext({
186
+ mode,
187
+ scale,
188
+ setScale,
189
+ translate,
190
+ setTranslate,
191
+ dragging,
192
+ moving,
193
+ reset,
194
+ zoomIn,
195
+ zoomOut,
196
+ translateCenter,
197
+ zoomTo,
198
+ });
181
199
  </script>
182
200
 
183
201
  <div
@@ -202,9 +220,9 @@ $: dispatch('transform', { scale: $scale, translate: $translate });
202
220
  <slot
203
221
  transform={{
204
222
  scale: $scale,
205
- setScale: scale.set,
223
+ setScale,
206
224
  translate: $translate,
207
- setTranslate: translate.set,
225
+ setTranslate,
208
226
  zoomTo,
209
227
  reset,
210
228
  }}
@@ -4,10 +4,16 @@ export declare const transformContextKey: unique symbol;
4
4
  export type TransformContextValue = {
5
5
  mode: 'canvas' | 'manual' | 'none';
6
6
  scale: Writable<number>;
7
+ setScale(value: number, options?: MotionOptions): void;
7
8
  translate: Writable<{
8
9
  x: number;
9
10
  y: number;
10
11
  }>;
12
+ setTranslate(point: {
13
+ x: number;
14
+ y: number;
15
+ }, options?: MotionOptions): void;
16
+ moving: Readable<boolean>;
11
17
  dragging: Readable<boolean>;
12
18
  reset(): void;
13
19
  zoomIn(): void;
@@ -23,7 +29,7 @@ export type TransformContextValue = {
23
29
  };
24
30
  export type TransformContext = TransformContextValue;
25
31
  export declare function transformContext(): TransformContext;
26
- import { motionStore } from '../stores/motionStore.js';
32
+ import { motionStore, type MotionOptions } from '../stores/motionStore.js';
27
33
  declare const __propDef: {
28
34
  props: {
29
35
  mode?: "none" | "canvas" | "manual" | undefined;
@@ -64,6 +70,11 @@ declare const __propDef: {
64
70
  width: number;
65
71
  height: number;
66
72
  }) => void) | undefined;
73
+ setTranslate?: ((point: {
74
+ x: number;
75
+ y: number;
76
+ }, options?: MotionOptions) => void) | undefined;
77
+ setScale?: ((value: number, options?: MotionOptions) => void) | undefined;
67
78
  };
68
79
  events: {
69
80
  click: MouseEvent;
@@ -86,24 +97,15 @@ declare const __propDef: {
86
97
  default: {
87
98
  transform: {
88
99
  scale: number;
89
- setScale: ((new_value: number, opts?: import("svelte/motion").SpringUpdateOpts | undefined) => Promise<void>) | ((value: number, opts?: import("svelte/motion").TweenedOptions<number> | undefined) => Promise<void>) | ((this: void, value: number) => void);
100
+ setScale: (value: number, options?: MotionOptions) => void;
90
101
  translate: {
91
102
  x: number;
92
103
  y: number;
93
104
  };
94
- setTranslate: ((new_value: {
95
- x: number;
96
- y: number;
97
- }, opts?: import("svelte/motion").SpringUpdateOpts | undefined) => Promise<void>) | ((value: {
105
+ setTranslate: (point: {
98
106
  x: number;
99
107
  y: number;
100
- }, opts?: import("svelte/motion").TweenedOptions<{
101
- x: number;
102
- y: number;
103
- }> | undefined) => Promise<void>) | ((this: void, value: {
104
- x: number;
105
- y: number;
106
- }) => void);
108
+ }, options?: MotionOptions) => void;
107
109
  zoomTo: (center: {
108
110
  x: number;
109
111
  y: number;
@@ -142,5 +144,10 @@ export default class TransformContext extends SvelteComponentTyped<TransformCont
142
144
  width: number;
143
145
  height: number;
144
146
  } | undefined) => void;
147
+ get setTranslate(): (point: {
148
+ x: number;
149
+ y: number;
150
+ }, options?: MotionOptions | undefined) => void;
151
+ get setScale(): (value: number, options?: MotionOptions | undefined) => void;
145
152
  }
146
153
  export {};
@@ -58,7 +58,7 @@ setContext('canvas', { ctx });
58
58
  'layercake-layout-canvas',
59
59
  'absolute w-full h-full',
60
60
  pointerEvents === false && 'pointer-events-none',
61
- $$restProps.class
61
+ $$props.class
62
62
  )}
63
63
  aria-label={label}
64
64
  aria-labelledby={labelledBy}
@@ -0,0 +1,41 @@
1
+ <script>import { getContext } from 'svelte';
2
+ import { cls } from 'svelte-ux';
3
+ /** The layer's outermost `<div>` tag. Useful for bindings. */
4
+ export let element = undefined;
5
+ /** The layer's z-index. */
6
+ export let zIndex = undefined;
7
+ /** Set this to `false` to set `pointer-events: none;` on the entire layer. */
8
+ export let pointerEvents = undefined;
9
+ /** A string passed to the `aria-role` on the `<div>` tag. This is `undefined` by default but will be set by default to `'figure'` if `label`, `labelledby` or `describedby` is set. That default will be overridden by whatever is passed in. */
10
+ export let role = undefined;
11
+ /** A string passed to the `aria-label` property on the `<div>` tag. */
12
+ export let label = undefined;
13
+ /** A string passed to the `aria-labelledby property` on the `<div>` tag. */
14
+ export let labelledBy = undefined;
15
+ /** A string passed to the `aria-describedby` property on the `<div>` tag. */
16
+ export let describedBy = undefined;
17
+ const { padding } = getContext('LayerCake');
18
+ $: roleVal = role || (label || labelledBy || describedBy ? 'figure' : undefined);
19
+ </script>
20
+
21
+ <div
22
+ bind:this={element}
23
+ class={cls(
24
+ 'layercake-layout-html',
25
+ 'absolute top-0 left-0',
26
+ pointerEvents === false && 'pointer-events-none',
27
+ $$props.class
28
+ )}
29
+ style:z-index={zIndex}
30
+ style:pointer-events={pointerEvents === false ? 'none' : null}
31
+ style:top="{$padding.top}px"
32
+ style:bottom="{$padding.bottom}px"
33
+ style:left="{$padding.left}px"
34
+ style:right="{$padding.right}px"
35
+ role={roleVal}
36
+ aria-label={label}
37
+ aria-labelledby={labelledBy}
38
+ aria-describedby={describedBy}
39
+ >
40
+ <slot {element}></slot>
41
+ </div>
@@ -0,0 +1,27 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ [x: string]: any;
5
+ element?: HTMLDivElement | undefined;
6
+ zIndex?: undefined;
7
+ pointerEvents?: boolean | undefined;
8
+ role?: string | undefined;
9
+ label?: string | undefined;
10
+ labelledBy?: string | undefined;
11
+ describedBy?: string | undefined;
12
+ };
13
+ events: {
14
+ [evt: string]: CustomEvent<any>;
15
+ };
16
+ slots: {
17
+ default: {
18
+ element: HTMLDivElement | undefined;
19
+ };
20
+ };
21
+ };
22
+ export type HtmlProps = typeof __propDef.props;
23
+ export type HtmlEvents = typeof __propDef.events;
24
+ export type HtmlSlots = typeof __propDef.slots;
25
+ export default class Html extends SvelteComponentTyped<HtmlProps, HtmlEvents, HtmlSlots> {
26
+ }
27
+ export {};
@@ -41,7 +41,8 @@ $: if (mode === 'canvas') {
41
41
  class={cls(
42
42
  'layercake-layout-svg',
43
43
  'absolute top-0 left-0 overflow-visible',
44
- pointerEvents === false && 'pointer-events-none'
44
+ pointerEvents === false && 'pointer-events-none',
45
+ $$props.class
45
46
  )}
46
47
  aria-label={label}
47
48
  aria-labelledby={labelledBy}
@@ -1,15 +1,16 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
- /** The layer's `<svg>` tag. Useful for bindings. */ element?: SVGElement | undefined;
5
- /** The layer's `<g>` tag. Useful for bindings. */ innerElement?: SVGGElement | undefined;
6
- /** The layer's z-index. */ zIndex?: undefined;
7
- /** Set this to `false` to set `pointer-events: none;` on the entire layer. */ pointerEvents?: boolean | undefined;
8
- /** A string passed to the `viewBox` property on the `<svg>` tag. */ viewBox?: string | undefined;
9
- /** A string passed to the `aria-label` property on the `<svg>` tag. */ label?: string | undefined;
10
- /** A string passed to the `aria-labelledby property` on the `<svg>` tag. */ labelledBy?: string | undefined;
11
- /** A string passed to the `aria-describedby` property on the `<svg>` tag. */ describedBy?: string | undefined;
12
- /** Shorthand to set the contents of `<title></title>` for accessibility. You can also set arbitrary HTML via the "title" slot but this is a convenient shorthand. If you use the "title" slot, this prop is ignored. */ title?: string | undefined;
4
+ [x: string]: any;
5
+ element?: SVGElement | undefined;
6
+ innerElement?: SVGGElement | undefined;
7
+ zIndex?: undefined;
8
+ pointerEvents?: boolean | undefined;
9
+ viewBox?: string | undefined;
10
+ label?: string | undefined;
11
+ labelledBy?: string | undefined;
12
+ describedBy?: string | undefined;
13
+ title?: string | undefined;
13
14
  };
14
15
  events: {
15
16
  click: MouseEvent;
@@ -25,3 +25,7 @@ export declare function resolveOptions(prop: string, options: PropMotionOptions)
25
25
  spring: any;
26
26
  tweened: any;
27
27
  };
28
+ export declare function motionFinishHandler(): {
29
+ subscribe: (this: void, run: import("svelte/store").Subscriber<boolean>, invalidate?: import("svelte/store").Invalidator<boolean> | undefined) => import("svelte/store").Unsubscriber;
30
+ handle: (promise: Promise<void> | void) => void;
31
+ };
@@ -35,3 +35,26 @@ export function resolveOptions(prop, options) {
35
35
  : false,
36
36
  };
37
37
  }
38
+ export function motionFinishHandler() {
39
+ let latestIndex = 0;
40
+ const moving = writable(false);
41
+ const handle = function (promise) {
42
+ latestIndex += 1;
43
+ if (!promise) {
44
+ // The store returned nothing, which means that the motion store is immediate.
45
+ moving.set(false);
46
+ return;
47
+ }
48
+ let thisIndex = latestIndex;
49
+ moving.set(true);
50
+ promise.then(() => {
51
+ if (thisIndex === latestIndex) {
52
+ moving.set(false);
53
+ }
54
+ });
55
+ };
56
+ return {
57
+ subscribe: moving.subscribe,
58
+ handle,
59
+ };
60
+ }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "author": "Sean Lynch <techniq35@gmail.com>",
5
5
  "license": "MIT",
6
6
  "repository": "techniq/layerchart",
7
- "version": "0.38.2",
7
+ "version": "0.38.4",
8
8
  "devDependencies": {
9
9
  "@changesets/cli": "^2.27.5",
10
10
  "@mdi/js": "^7.4.47",