@hkdigital/lib-sveltekit 0.1.28 → 0.1.30

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.
@@ -0,0 +1,17 @@
1
+ export const carPaintImages: {
2
+ rusty: import("../../config/typedef.js").ImageMeta[];
3
+ "army-green": import("../../config/typedef.js").ImageMeta[];
4
+ "electric-blue": import("../../config/typedef.js").ImageMeta[];
5
+ "lemon-yellow": import("../../config/typedef.js").ImageMeta[];
6
+ "opaque-purple": import("../../config/typedef.js").ImageMeta[];
7
+ "sunset-orange": import("../../config/typedef.js").ImageMeta[];
8
+ "tomato-red": import("../../config/typedef.js").ImageMeta[];
9
+ };
10
+ import Rusty from './car-paint-picker/rusty.jpg?preset=render&responsive';
11
+ import ArmyGreen from './car-paint-picker/army-green.jpg?preset=render&responsive';
12
+ import ElectricBlue from './car-paint-picker/electric-blue.jpg?preset=render&responsive';
13
+ import LemonYellow from './car-paint-picker/lemon-yellow.jpg?preset=render&responsive';
14
+ import OpaquePurple from './car-paint-picker/opaque-purple.jpg?preset=render&responsive';
15
+ import SunsetOrange from './car-paint-picker/sunset-orange.jpg?preset=render&responsive';
16
+ import TomatoRed from './car-paint-picker/tomato-red.jpg?preset=render&responsive';
17
+ export { Rusty, ArmyGreen, ElectricBlue, LemonYellow, OpaquePurple, SunsetOrange, TomatoRed };
@@ -0,0 +1,41 @@
1
+ import {
2
+ LABEL_RUSTY,
3
+ LABEL_ARMY_GREEN,
4
+ LABEL_ELECTRIC_BLUE,
5
+ LABEL_LEMON_YELLOW,
6
+ LABEL_OPAQUE_PURPLE,
7
+ LABEL_SUNSET_ORANGE,
8
+ LABEL_TOMATO_RED
9
+ } from './labels.js';
10
+
11
+ import Rusty from './car-paint-picker/rusty.jpg?preset=render&responsive';
12
+
13
+ import ArmyGreen from './car-paint-picker/army-green.jpg?preset=render&responsive';
14
+ import ElectricBlue from './car-paint-picker/electric-blue.jpg?preset=render&responsive';
15
+ import LemonYellow from './car-paint-picker/lemon-yellow.jpg?preset=render&responsive';
16
+ import OpaquePurple from './car-paint-picker/opaque-purple.jpg?preset=render&responsive';
17
+ import SunsetOrange from './car-paint-picker/sunset-orange.jpg?preset=render&responsive';
18
+ import TomatoRed from './car-paint-picker/tomato-red.jpg?preset=render&responsive';
19
+
20
+ // console.log('ArmyGreen', ArmyGreen);
21
+
22
+ export const carPaintImages = {
23
+ [LABEL_RUSTY]: Rusty,
24
+ [LABEL_ARMY_GREEN]: ArmyGreen,
25
+ [LABEL_ELECTRIC_BLUE]: ElectricBlue,
26
+ [LABEL_LEMON_YELLOW]: LemonYellow,
27
+ [LABEL_OPAQUE_PURPLE]: OpaquePurple,
28
+ [LABEL_SUNSET_ORANGE]: SunsetOrange,
29
+ [LABEL_TOMATO_RED]: TomatoRed
30
+ };
31
+
32
+ /* Also export as individual images */
33
+ export {
34
+ Rusty,
35
+ ArmyGreen,
36
+ ElectricBlue,
37
+ LemonYellow,
38
+ OpaquePurple,
39
+ SunsetOrange,
40
+ TomatoRed
41
+ };
@@ -0,0 +1,7 @@
1
+ export const LABEL_RUSTY: "rusty";
2
+ export const LABEL_ARMY_GREEN: "army-green";
3
+ export const LABEL_ELECTRIC_BLUE: "electric-blue";
4
+ export const LABEL_LEMON_YELLOW: "lemon-yellow";
5
+ export const LABEL_OPAQUE_PURPLE: "opaque-purple";
6
+ export const LABEL_SUNSET_ORANGE: "sunset-orange";
7
+ export const LABEL_TOMATO_RED: "tomato-red";
@@ -0,0 +1,7 @@
1
+ export const LABEL_RUSTY = 'rusty';
2
+ export const LABEL_ARMY_GREEN = 'army-green';
3
+ export const LABEL_ELECTRIC_BLUE = 'electric-blue';
4
+ export const LABEL_LEMON_YELLOW = 'lemon-yellow';
5
+ export const LABEL_OPAQUE_PURPLE = 'opaque-purple';
6
+ export const LABEL_SUNSET_ORANGE = 'sunset-orange';
7
+ export const LABEL_TOMATO_RED = 'tomato-red';
@@ -27,17 +27,15 @@ export class PresenterState {
27
27
  currentSlideName: string;
28
28
  /** @type {string} */
29
29
  pendingSlideName: string;
30
+ /** @type {boolean} */
31
+ configured: boolean;
30
32
  /**
31
33
  * Configure the presentation
32
34
  *
33
35
  * @param {object} _
34
- * @param {boolean} [_.autostart=false] - Whether to start automatically
35
- * @param {string} [_.startSlide] - Name of the slide to start with
36
36
  * @param {Slide[]} [_.slides] - Array of slides for the presentation
37
37
  */
38
- configure({ slides, autostart, startSlide }: {
39
- autostart?: boolean;
40
- startSlide?: string;
38
+ configure({ slides }: {
41
39
  slides?: Slide[];
42
40
  }): void;
43
41
  /**
@@ -52,11 +50,15 @@ export class PresenterState {
52
50
  * @param {string} name - Name of the slide to transition to
53
51
  */
54
52
  gotoSlide(name: string): Promise<void>;
53
+ /**
54
+ * Returns a simplified presenter reference with essential methods
55
+ * for slide components to use
56
+ *
57
+ * @returns {PresenterRef} A reference object with presenter methods
58
+ */
59
+ getPresenterRef(): PresenterRef;
55
60
  #private;
56
61
  }
57
- export const createOrGetState: (instanceKey?: string | Symbol) => PresenterState;
58
- export const createState: (instanceKey?: string | Symbol) => PresenterState;
59
- export const getState: (instanceKey?: string | Symbol) => PresenterState;
60
62
  export type Slide = import("./typedef").Slide;
61
63
  export type Transition = import("./typedef").Transition;
62
64
  export type Layer = import("./typedef").Layer;
@@ -1,15 +1,11 @@
1
1
  import { tick } from 'svelte';
2
2
 
3
- import { defineStateContext } from '../../util/svelte/state-context/index.js';
4
-
5
3
  import { findFirst } from '../../util/array/index.js';
6
4
 
7
5
  import { untrack } from 'svelte';
8
6
 
9
7
  import { HkPromise } from '../../classes/promise/index.js';
10
8
 
11
- /* ----------------------------------------------------------------- typedefs */
12
-
13
9
  /**
14
10
  * @typedef {import("./typedef").Slide} Slide
15
11
  */
@@ -34,16 +30,12 @@ import { HkPromise } from '../../classes/promise/index.js';
34
30
  * @property {() => string} getCurrentSlideName - Get the current slide name
35
31
  */
36
32
 
37
- /* -------------------------------------------------------------- Constants */
38
-
39
33
  const Z_BACK = 0;
40
34
  const Z_FRONT = 10;
41
35
 
42
36
  const LABEL_A = 'A';
43
37
  const LABEL_B = 'B';
44
38
 
45
- /* ------------------------------------------------------- Define state class */
46
-
47
39
  export class PresenterState {
48
40
  /** @type {Slide[]} */
49
41
  slides = $state.raw([]);
@@ -99,11 +91,14 @@ export class PresenterState {
99
91
  /** @type {string} */
100
92
  pendingSlideName;
101
93
 
94
+ /** @type {boolean} */
95
+ configured = false;
96
+
102
97
  /**
103
98
  * Initialize the presenter state and set up reactivity
104
99
  */
105
100
  constructor() {
106
- this.#setupStageTransitions();
101
+ // this.#setupStageTransitions();
107
102
 
108
103
  let timeout;
109
104
 
@@ -130,21 +125,21 @@ export class PresenterState {
130
125
  * Set up reactivity for stage transitions between the before/after states
131
126
  * This handles the animation timing for both layers
132
127
  */
133
- #setupStageTransitions() {
134
- // Handle layer A stage transitions
135
- $effect(() => {
136
- if (this.layerA.stageBeforeIn || this.layerA.stageBeforeOut) {
137
- this.layerA = this.#processStageTransition(this.layerA);
138
- }
139
- });
128
+ // #setupStageTransitions() {
129
+ // // Handle layer A stage transitions
130
+ // $effect(() => {
131
+ // if (this.layerA.stageBeforeIn || this.layerA.stageBeforeOut) {
132
+ // this.layerA = this.#processStageTransition(this.layerA);
133
+ // }
134
+ // });
140
135
 
141
- // Handle layer B stage transitions
142
- $effect(() => {
143
- if (this.layerB.stageBeforeIn || this.layerB.stageBeforeOut) {
144
- this.layerB = this.#processStageTransition(this.layerB);
145
- }
146
- });
147
- }
136
+ // // Handle layer B stage transitions
137
+ // $effect(() => {
138
+ // if (this.layerB.stageBeforeIn || this.layerB.stageBeforeOut) {
139
+ // this.layerB = this.#processStageTransition(this.layerB);
140
+ // }
141
+ // });
142
+ // }
148
143
 
149
144
  /**
150
145
  * Process a single stage transition for a layer
@@ -166,40 +161,22 @@ export class PresenterState {
166
161
  return updatedLayer;
167
162
  }
168
163
 
169
- // /**
170
- // * Set up reactivity for tracking transition promises
171
- // * This handles the completion of animations and layer swapping
172
- // */
173
- // #setupTransitionTracking() {
174
- // $effect(() => {
175
- // const promises = this.transitionPromises;
176
-
177
- // if (promises.length > 0) {
178
- // const nextSlide = this.#getSlide(this.nextLayerLabel);
179
-
180
- // if (!nextSlide) {
181
- // return;
182
- // }
183
-
184
- // untrack(() => {
185
- // this.#executeTransition(promises);
186
- // });
187
- // }
188
- // });
189
- // }
190
-
191
164
  /**
192
- * Execute the transition by waiting for all promises and then
193
- * completing the transition
165
+ * Waiting for all transition timing promises to finish,
166
+ * this should be the same amount of time as it takes for the real
167
+ * transitions to finish
194
168
  *
195
- * @param {HkPromise[]} promises - Array of transition promises to wait for
169
+ * @param {HkPromise[]} promises
170
+ * Array of transition promises to wait for
196
171
  */
197
- async #executeTransition(promises) {
172
+ async #waitForTransitionPromises(promises) {
198
173
  try {
199
- // console.debug('executeTransition');
174
+ // console.debug('waitForTransitionPromises', promises);
200
175
 
201
176
  await Promise.allSettled(promises);
202
177
 
178
+ // console.debug('waitForTransitionPromises:done', promises);
179
+
203
180
  untrack(() => {
204
181
  this.#completeTransition();
205
182
  });
@@ -250,25 +227,15 @@ export class PresenterState {
250
227
  * Configure the presentation
251
228
  *
252
229
  * @param {object} _
253
- * @param {boolean} [_.autostart=false] - Whether to start automatically
254
- * @param {string} [_.startSlide] - Name of the slide to start with
255
230
  * @param {Slide[]} [_.slides] - Array of slides for the presentation
256
231
  */
257
- configure({ slides, autostart = true, startSlide }) {
258
- untrack(() => {
259
- if (slides) {
260
- // Only update slides if provided
261
- this.slides = slides;
262
- }
232
+ configure({ slides }) {
233
+ this.configured = true;
263
234
 
264
- if ((autostart || startSlide) && this.slides?.length) {
265
- if (startSlide) {
266
- this.gotoSlide(startSlide);
267
- } else {
268
- this.#gotoSlide(this.slides[0]);
269
- }
270
- }
271
- });
235
+ if (slides) {
236
+ // Only update slides if provided
237
+ this.slides = slides;
238
+ }
272
239
  }
273
240
 
274
241
  /**
@@ -286,6 +253,8 @@ export class PresenterState {
286
253
  * @param {string} name - Name of the slide to transition to
287
254
  */
288
255
  async gotoSlide(name) {
256
+ // throw new Error('gotoSlide');
257
+
289
258
  untrack(() => {
290
259
  const slide = findFirst(this.slides, { name });
291
260
 
@@ -304,6 +273,10 @@ export class PresenterState {
304
273
  * @param {Slide} slide - The slide to transition to
305
274
  */
306
275
  async #gotoSlide(slide) {
276
+ if (!this.configured) {
277
+ throw new Error('Not configured yet');
278
+ }
279
+
307
280
  if (this.busy) {
308
281
  this.pendingSlideName = slide.name;
309
282
  return;
@@ -312,7 +285,7 @@ export class PresenterState {
312
285
  this.slideLoadingPromise = null;
313
286
 
314
287
  // Get a presenter reference to pass to the slide
315
- const presenterRef = this.#getPresenterRef();
288
+ const presenterRef = this.getPresenterRef();
316
289
 
317
290
  // Create a copy of the slide to avoid mutating the original
318
291
  const slideWithProps = {
@@ -356,7 +329,7 @@ export class PresenterState {
356
329
  const currentSlide = this.#getSlide(this.currentLayerLabel);
357
330
  const nextSlide = this.#getSlide(this.nextLayerLabel);
358
331
 
359
- // console.debug('Checkpoint 4');
332
+ // console.debug('Checkpoint 4', currentSlide, nextSlide);
360
333
 
361
334
  // Make next layer visible, move to front, and prepare for
362
335
  // transition in
@@ -378,10 +351,42 @@ export class PresenterState {
378
351
 
379
352
  // console.debug('Checkpoint 5');
380
353
 
354
+ // Wait briefly to ensure the stageBeforeIn/stageBeforeOut states are rendered
355
+ await tick();
356
+
357
+ // Now manually process the transitions for both layers
358
+ const layerA = this.layerA;
359
+ const layerB = this.layerB;
360
+
361
+ // Process stageBeforeIn transition for both layers
362
+ if (layerA.stageBeforeIn) {
363
+ this.layerA = this.#processStageTransition(layerA);
364
+ }
365
+
366
+ if (layerB.stageBeforeIn) {
367
+ this.layerB = this.#processStageTransition(layerB);
368
+ }
369
+
370
+ // Wait for another tick to ensure the stageIn states are rendered
371
+ await tick();
372
+
373
+ // Process stageBeforeOut transition for both layers
374
+ if (layerA.stageBeforeOut) {
375
+ this.layerA = this.#processStageTransition(layerA);
376
+ }
377
+
378
+ if (layerB.stageBeforeOut) {
379
+ this.layerB = this.#processStageTransition(layerB);
380
+ }
381
+
382
+ // console.debug('Checkpoint 7');
383
+
381
384
  // Start transitions
382
- this.#applyTransitions();
385
+ this.#createTransitionPromises();
383
386
 
384
- await this.#executeTransition(this.transitionPromises);
387
+ // console.debug('Checkpoint 8');
388
+
389
+ await this.#waitForTransitionPromises(this.transitionPromises);
385
390
 
386
391
  // Check if there's a pending slide transition
387
392
  if (this.pendingSlideName) {
@@ -398,9 +403,10 @@ export class PresenterState {
398
403
  }
399
404
 
400
405
  /**
401
- * Apply transitions between current and next slide
406
+ * Create transition promises that can be used to determine the timing
407
+ * of the transitions between current and next slide
402
408
  */
403
- #applyTransitions() {
409
+ #createTransitionPromises() {
404
410
  // Cancel existing transitions
405
411
  let transitionPromises = this.transitionPromises;
406
412
 
@@ -417,9 +423,11 @@ export class PresenterState {
417
423
  // Apply transitions `out` from currentslide
418
424
  const transitionsOut = currentSlide?.outro;
419
425
 
426
+ // console.log('transitionsOut', transitionsOut);
427
+
420
428
  if (transitionsOut) {
421
429
  for (const transition of transitionsOut) {
422
- const promise = this.#applyTransition(transition);
430
+ const promise = this.#createTransitionPromise(transition);
423
431
  transitionPromises.push(promise);
424
432
  }
425
433
  }
@@ -427,9 +435,11 @@ export class PresenterState {
427
435
  // Apply transitions `in` from next slide
428
436
  const transitionsIn = nextSlide?.intro;
429
437
 
438
+ // console.log('transitionsIn', transitionsIn);
439
+
430
440
  if (transitionsIn) {
431
441
  for (const transition of transitionsIn) {
432
- const promise = this.#applyTransition(transition);
442
+ const promise = this.#createTransitionPromise(transition);
433
443
  transitionPromises.push(promise);
434
444
  }
435
445
  }
@@ -438,12 +448,16 @@ export class PresenterState {
438
448
  }
439
449
 
440
450
  /**
441
- * Apply a transition and return a transition promise
451
+ * Create a transition promise for the specified transition
452
+ *
442
453
  *
443
454
  * @param {Transition} transition - The transition to apply
444
- * @returns {HkPromise} Promise that resolves when transition completes
455
+ *
456
+ * @returns {HkPromise}
457
+ * Promise that resolves after the same amount of time that it
458
+ * takes for the transition to finish
445
459
  */
446
- #applyTransition(transition) {
460
+ #createTransitionPromise(transition) {
447
461
  const delay = (transition.delay ?? 0) + (transition.duration ?? 0);
448
462
 
449
463
  if (0 === delay) {
@@ -527,7 +541,7 @@ export class PresenterState {
527
541
  *
528
542
  * @returns {PresenterRef} A reference object with presenter methods
529
543
  */
530
- #getPresenterRef() {
544
+ getPresenterRef() {
531
545
  return {
532
546
  gotoSlide: (name) => this.gotoSlide(name),
533
547
  getCurrentSlideName: () => this.currentSlideName
@@ -564,8 +578,3 @@ export class PresenterState {
564
578
  };
565
579
  }
566
580
  }
567
-
568
- /* -------------------------------------- Export create & get state functions */
569
-
570
- export const [createOrGetState, createState, getState] =
571
- defineStateContext(PresenterState);
@@ -1,13 +1,10 @@
1
1
  <script>
2
- /* ---------------------------------------------------------------- Imports */
2
+ import { onMount } from 'svelte';
3
3
 
4
4
  import { GridLayers } from '../../components/layout/index.js';
5
5
 
6
6
  import { PresenterState } from './Presenter.state.svelte.js';
7
- import { getPresenterState } from './index.js';
8
- import { cssBefore, cssDuring } from './util.js';
9
-
10
- /* ------------------------------------------------------------------ Props */
7
+ import { cssBefore, cssDuring, waitForRender } from './util.js';
11
8
 
12
9
  /**
13
10
  * @typedef {import("./typedef.js").Slide} Slide
@@ -21,10 +18,7 @@
21
18
  * @type {{
22
19
  * classes?: string,
23
20
  * slides?: import("./typedef.js").Slide[],
24
- * autostart?: boolean,
25
- * startSlide?: string,
26
- * instanceKey?: Symbol | string,
27
- * presenter?: import('./Presenter.state.svelte.js').PresenterState,
21
+ * presenterRef?: import('./Presenter.state.svelte.js').PresenterRef,
28
22
  * layoutSnippet: import('svelte').Snippet<[Slide|null, Layer]>,
29
23
  * loadingSnippet?: import('svelte').Snippet,
30
24
  * }}
@@ -35,32 +29,23 @@
35
29
 
36
30
  // > Functional
37
31
  slides,
38
- autostart = false,
39
- startSlide,
40
-
41
- // State
42
- instanceKey,
43
-
44
- presenter = $bindable(new PresenterState()),
32
+ presenterRef = $bindable(),
45
33
 
46
34
  // Snippets
47
35
  layoutSnippet,
48
36
  loadingSnippet
49
37
  } = $props();
50
38
 
51
- // > Create presenter state object and register using setContext
52
-
53
- // FIXME: Using getPresenterState to force creation of presenter outside
54
- // the component. Otherwise transitions doe not work somehow..
55
- presenter = getPresenterState(instanceKey);
56
-
57
- // > State
39
+ const presenter = new PresenterState();
58
40
 
59
- $effect.pre(() => {
41
+ onMount(() => {
60
42
  // Configure presenter with slides if provided
61
- presenter.configure({ slides, autostart, startSlide });
43
+ presenter.configure({ slides });
44
+ presenterRef = presenter.getPresenterRef();
62
45
  });
63
46
 
47
+ // > State
48
+
64
49
  let classesA = $state('');
65
50
  let classesB = $state('');
66
51
 
@@ -75,11 +60,18 @@
75
60
  const { stageBeforeIn, stageIn, stageBeforeOut, stageOut, transitions } =
76
61
  presenter.layerA;
77
62
 
78
- if (transitions && transitions.length) {
63
+ if (transitions?.length) {
64
+ // console.debug('layerA:transitions', transitions, {
65
+ // stageBeforeIn,
66
+ // stageIn,
67
+ // stageBeforeOut,
68
+ // stageOut
69
+ // });
70
+
79
71
  if (stageBeforeIn || stageBeforeOut) {
80
72
  ({ style: stylesA, classes: classesA } = cssBefore(transitions));
81
73
  } else if (stageIn || stageOut) {
82
- setTimeout(() => {
74
+ waitForRender(() => {
83
75
  ({ style: stylesA, classes: classesA } = cssDuring(transitions));
84
76
  });
85
77
  }
@@ -95,11 +87,18 @@
95
87
  const { stageBeforeIn, stageIn, stageBeforeOut, stageOut, transitions } =
96
88
  presenter.layerB;
97
89
 
98
- if (transitions) {
90
+ if (transitions?.length) {
91
+ // console.debug('layerB:transitions', transitions, {
92
+ // stageBeforeIn,
93
+ // stageIn,
94
+ // stageBeforeOut,
95
+ // stageOut
96
+ // });
97
+
99
98
  if (stageBeforeIn || stageBeforeOut) {
100
99
  ({ style: stylesB, classes: classesB } = cssBefore(transitions));
101
100
  } else if (stageIn || stageOut) {
102
- setTimeout(() => {
101
+ waitForRender(() => {
103
102
  ({ style: stylesB, classes: classesB } = cssDuring(transitions));
104
103
  });
105
104
  }
@@ -2,10 +2,7 @@ export default Presenter;
2
2
  declare const Presenter: import("svelte").Component<{
3
3
  classes?: string;
4
4
  slides?: import("./typedef.js").Slide[];
5
- autostart?: boolean;
6
- startSlide?: string;
7
- instanceKey?: Symbol | string;
8
- presenter?: import("./Presenter.state.svelte.js").PresenterState;
5
+ presenterRef?: import("./Presenter.state.svelte.js").PresenterRef;
9
6
  layoutSnippet: import("svelte").Snippet<[import("./typedef.js").Slide | null, import("./typedef.js").Layer]>;
10
7
  loadingSnippet?: import("svelte").Snippet;
11
- }, {}, "presenter">;
8
+ }, {}, "presenterRef">;
@@ -1,6 +1,6 @@
1
1
  export { default as Presenter } from "./Presenter.svelte";
2
2
  export { default as ImageSlide } from "./ImageSlide.svelte";
3
+ export { PresenterState } from "./Presenter.state.svelte.js";
3
4
  export * from "./typedef.js";
4
5
  export * from "./constants.js";
5
6
  export * from "./util.js";
6
- export { PresenterState, createOrGetState as createOrGetPresenterState, createState as createPresenterState, getState as getPresenterState } from "./Presenter.state.svelte.js";
@@ -1,12 +1,7 @@
1
1
  export { default as Presenter } from './Presenter.svelte';
2
2
  export { default as ImageSlide } from './ImageSlide.svelte';
3
3
 
4
- export {
5
- PresenterState,
6
- createOrGetState as createOrGetPresenterState,
7
- createState as createPresenterState,
8
- getState as getPresenterState
9
- } from './Presenter.state.svelte.js';
4
+ export { PresenterState } from './Presenter.state.svelte.js';
10
5
 
11
6
  export * from './typedef.js';
12
7
  export * from './constants.js';
@@ -1,8 +1,15 @@
1
1
  /**
2
2
  * @typedef {import("./typedef").Transition} Transition
3
3
  */
4
- /** ----------------------------------------------------------------- Exports */
5
- /** ----------------------------------- Generate CSS for lists of transitions */
4
+ /**
5
+ * Ensures DOM is updated by Svelte and then painted by the browser
6
+ * before executing the callback function.
7
+ *
8
+ * @param {Function} callback - Function to execute after DOM update and paint
9
+ * @returns {Promise<void>} - Promise that resolves after the callback is executed
10
+ */
11
+ export function waitForRender(callback: Function): Promise<void>;
12
+ /** === Generate CSS for lists of transitions */
6
13
  /**
7
14
  * Generates style and class names to be used before the transitions
8
15
  * become active
@@ -26,7 +33,7 @@ export function cssDuring(transitions: Transition[]): {
26
33
  style: string;
27
34
  classes: string;
28
35
  };
29
- /** ------------------------------------- Generate CSS for single transitions */
36
+ /** === Generate CSS for single transitions */
30
37
  /**
31
38
  * Generates style and class names for specified transition for
32
39
  * the stage 'stageBeforeIn'
@@ -1,3 +1,5 @@
1
+ import { tick } from 'svelte';
2
+
1
3
  import * as expect from '../../util/expect/index.js';
2
4
 
3
5
  import { pushNotEmpty } from '../../util/array/index.js';
@@ -8,9 +10,27 @@ import { TRANSITION_CSS, FADE_IN, FADE_OUT } from './constants.js';
8
10
  * @typedef {import("./typedef").Transition} Transition
9
11
  */
10
12
 
11
- /** ----------------------------------------------------------------- Exports */
13
+ /**
14
+ * Ensures DOM is updated by Svelte and then painted by the browser
15
+ * before executing the callback function.
16
+ *
17
+ * @param {Function} callback - Function to execute after DOM update and paint
18
+ * @returns {Promise<void>} - Promise that resolves after the callback is executed
19
+ */
20
+ export function waitForRender(callback) {
21
+ return tick().then(() => {
22
+ return new Promise((resolve) => {
23
+ requestAnimationFrame(() => {
24
+ requestAnimationFrame(() => {
25
+ callback();
26
+ resolve();
27
+ });
28
+ });
29
+ });
30
+ });
31
+ }
12
32
 
13
- /** ----------------------------------- Generate CSS for lists of transitions */
33
+ /** === Generate CSS for lists of transitions */
14
34
 
15
35
  /**
16
36
  * Generates style and class names to be used before the transitions
@@ -79,7 +99,7 @@ export function cssDuring(transitions) {
79
99
  return { style, classes: classesArr.join() };
80
100
  }
81
101
 
82
- /** ------------------------------------- Generate CSS for single transitions */
102
+ /** === Generate CSS for single transitions */
83
103
 
84
104
  /**
85
105
  * Generates style and class names for specified transition for
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-sveltekit",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"