@juspay/svelte-ui-components 2.69.3 → 2.71.0

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.
@@ -30,6 +30,7 @@
30
30
  presetCheckmark = false,
31
31
  showDateInputs = false,
32
32
  showTimeSelection = false,
33
+ presetToggle = false,
33
34
  placeholder = 'Select date',
34
35
  dualMonth,
35
36
  timePicker,
@@ -388,6 +389,21 @@
388
389
  }
389
390
 
390
391
  function handlePreset(preset: DateRangePreset): void {
392
+ // presetToggle: clicking the already-selected preset deselects it and reverts the
393
+ // draft to the committed selection (mirrors openPicker). Lets a toggle-style preset
394
+ // such as "No Comparison" be switched back off without having to pick a calendar
395
+ // date, instead of being a one-way radio choice.
396
+ if (presetToggle && selectedPresetLabel === preset.label) {
397
+ draftStart = rangeStart;
398
+ draftEnd = rangeEnd;
399
+ draftValue = value;
400
+ selectedPresetLabel = committedPresetLabel;
401
+ const anchor = rangeStart !== null ? rangeStart : value !== null ? value : now;
402
+ leftYear = anchor.getFullYear();
403
+ leftMonth = anchor.getMonth();
404
+ calendarKey++;
405
+ return;
406
+ }
391
407
  // User explicitly picked a preset — clear the initial-preset display label
392
408
  activePresetLabel = null;
393
409
  const { start, end } = preset.getValue();
@@ -52,6 +52,13 @@ export type OptionalDateRangePickerProperties = {
52
52
  * Opt-in. Default: false.
53
53
  */
54
54
  showTimeSelection?: boolean;
55
+ /**
56
+ * Make presets toggle instead of being one-way: clicking the already-selected
57
+ * preset deselects it and reverts the draft to the committed selection. Lets a
58
+ * toggle-style preset such as "No Comparison" be switched back off without having
59
+ * to pick a calendar date. Opt-in. Default: false.
60
+ */
61
+ presetToggle?: boolean;
55
62
  /** Placeholder shown when no range is selected. */
56
63
  placeholder?: string;
57
64
  /** Show two months side by side. Defaults to true for range mode, false for single. */
@@ -0,0 +1,121 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import type { AnimationItem } from 'lottie-web';
4
+ import type { LottiePlayerProperties } from './properties';
5
+
6
+ type LocalAnimationItem = Pick<
7
+ AnimationItem,
8
+ 'play' | 'pause' | 'stop' | 'destroy' | 'setSpeed' | 'addEventListener' | 'removeEventListener'
9
+ >;
10
+
11
+ let {
12
+ src,
13
+ animationData,
14
+ autoplay = true,
15
+ loop = true,
16
+ speed = 1,
17
+ renderer = 'svg',
18
+ ariaHidden = true,
19
+ testId,
20
+ classes,
21
+ oncomplete,
22
+ onerror
23
+ }: LottiePlayerProperties = $props();
24
+
25
+ let containerEl: HTMLDivElement | null = $state(null);
26
+ let animationItem: LocalAnimationItem | null = $state(null);
27
+
28
+ let rootClass = $derived(['lottie-player', classes ?? ''].filter((c) => c.length > 0).join(' '));
29
+
30
+ export function play(): void {
31
+ animationItem?.play();
32
+ }
33
+
34
+ export function pause(): void {
35
+ animationItem?.pause();
36
+ }
37
+
38
+ export function stop(): void {
39
+ animationItem?.stop();
40
+ }
41
+
42
+ // eslint-disable-next-line no-restricted-syntax
43
+ $effect(() => {
44
+ if (animationItem !== null) {
45
+ animationItem.setSpeed(speed);
46
+ }
47
+ });
48
+
49
+ onMount(() => {
50
+ if (containerEl === null) {
51
+ return;
52
+ }
53
+
54
+ let item: LocalAnimationItem | null = null;
55
+
56
+ const handleComplete = (): void => {
57
+ oncomplete?.();
58
+ };
59
+
60
+ const handleError = (): void => {
61
+ onerror?.();
62
+ };
63
+
64
+ void import('lottie-web').then((lottie) => {
65
+ if (containerEl === null) {
66
+ return;
67
+ }
68
+
69
+ const lottieApi = lottie.default ?? lottie;
70
+
71
+ const config: Parameters<typeof lottieApi.loadAnimation>[0] = {
72
+ container: containerEl,
73
+ renderer,
74
+ loop,
75
+ autoplay,
76
+ ...(animationData != null
77
+ ? { animationData }
78
+ : typeof src === 'string' && src.length > 0
79
+ ? { path: src }
80
+ : {})
81
+ };
82
+
83
+ const loaded = lottieApi.loadAnimation(config);
84
+ item = loaded;
85
+ animationItem = item;
86
+
87
+ loaded.setSpeed(speed);
88
+
89
+ loaded.addEventListener('complete', handleComplete);
90
+ loaded.addEventListener('data_failed', handleError);
91
+ });
92
+
93
+ return () => {
94
+ if (item !== null) {
95
+ item.removeEventListener('complete', handleComplete);
96
+ item.removeEventListener('data_failed', handleError);
97
+ item.destroy();
98
+ animationItem = null;
99
+ }
100
+ };
101
+ });
102
+ </script>
103
+
104
+ <div
105
+ class={rootClass}
106
+ bind:this={containerEl}
107
+ aria-hidden={ariaHidden ? 'true' : null}
108
+ role={ariaHidden ? null : 'img'}
109
+ data-pw={typeof testId === 'string' ? testId : null}
110
+ ></div>
111
+
112
+ <style>
113
+ .lottie-player {
114
+ display: var(--lottie-player-display, inline-block);
115
+ width: var(--lottie-player-width, 100%);
116
+ height: var(--lottie-player-height, 100%);
117
+ background: var(--lottie-player-background, transparent);
118
+ border-radius: var(--lottie-player-border-radius, 0px);
119
+ overflow: var(--lottie-player-overflow, hidden);
120
+ }
121
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { LottiePlayerProperties } from './properties';
2
+ declare const LottiePlayer: import("svelte").Component<LottiePlayerProperties, {
3
+ play: () => void;
4
+ pause: () => void;
5
+ stop: () => void;
6
+ }, "">;
7
+ type LottiePlayer = ReturnType<typeof LottiePlayer>;
8
+ export default LottiePlayer;
@@ -0,0 +1,36 @@
1
+ export type LottieRendererType = 'svg' | 'canvas' | 'html';
2
+ export type LottiePlayerProperties = MandatoryLottiePlayerProperties & OptionalLottiePlayerProperties & LottiePlayerEventProperties;
3
+ /**
4
+ * Placeholder for future mandatory props. Follows the library-wide pattern used by Card, Badge,
5
+ * etc. — kept so the type shape is consistent when mandatory props are added later.
6
+ */
7
+ export type MandatoryLottiePlayerProperties = Record<never, never>;
8
+ export type OptionalLottiePlayerProperties = {
9
+ /**
10
+ * URL or path to the Lottie animation JSON file. Ignored when `animationData` is provided.
11
+ */
12
+ src?: string;
13
+ /**
14
+ * Inline animation data object. Takes precedence over `src` when both are provided.
15
+ */
16
+ animationData?: Record<string, unknown>;
17
+ autoplay?: boolean;
18
+ loop?: boolean;
19
+ /** Playback speed multiplier. Default 1. */
20
+ speed?: number;
21
+ /** Rendering backend. Default 'svg'. */
22
+ renderer?: LottieRendererType;
23
+ /**
24
+ * Whether the player element is hidden from assistive technology.
25
+ * Default true — decorative animations should be invisible to screen readers.
26
+ */
27
+ ariaHidden?: boolean;
28
+ testId?: string;
29
+ classes?: string;
30
+ };
31
+ export type LottiePlayerEventProperties = {
32
+ /** Fired when the animation completes (non-looping). */
33
+ oncomplete?: () => void;
34
+ /** Fired when the animation fails to load. */
35
+ onerror?: () => void;
36
+ };
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -65,6 +65,7 @@ export { default as AreaChart } from './AreaChart/AreaChart.svelte';
65
65
  export { default as BarChart } from './BarChart/BarChart.svelte';
66
66
  export { default as PieChart } from './PieChart/PieChart.svelte';
67
67
  export { default as SankeyChart } from './SankeyChart/SankeyChart.svelte';
68
+ export { default as LottiePlayer } from './LottiePlayer/LottiePlayer.svelte';
68
69
  export type * from './Button/properties';
69
70
  export type * from './Modal/properties';
70
71
  export type * from './Input/properties';
@@ -126,5 +127,6 @@ export type * from './AreaChart/properties';
126
127
  export type * from './BarChart/properties';
127
128
  export type * from './PieChart/properties';
128
129
  export type * from './SankeyChart/properties';
130
+ export type * from './LottiePlayer/properties';
129
131
  export { validateInput } from './utils';
130
132
  export { formatNumberIndian } from './_chart/format';
package/dist/index.js CHANGED
@@ -65,5 +65,6 @@ export { default as AreaChart } from './AreaChart/AreaChart.svelte';
65
65
  export { default as BarChart } from './BarChart/BarChart.svelte';
66
66
  export { default as PieChart } from './PieChart/PieChart.svelte';
67
67
  export { default as SankeyChart } from './SankeyChart/SankeyChart.svelte';
68
+ export { default as LottiePlayer } from './LottiePlayer/LottiePlayer.svelte';
68
69
  export { validateInput } from './utils';
69
70
  export { formatNumberIndian } from './_chart/format';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/svelte-ui-components",
3
- "version": "2.69.3",
3
+ "version": "2.71.0",
4
4
  "description": "A themeable Svelte 5 UI component library with CSS custom property driven styling",
5
5
  "keywords": [
6
6
  "svelte",
@@ -48,7 +48,13 @@
48
48
  ],
49
49
  "peerDependencies": {
50
50
  "svelte": "^5.41.2",
51
- "type-decoder": "^2.1.0"
51
+ "type-decoder": "^2.1.0",
52
+ "lottie-web": ">=5.0.0"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "lottie-web": {
56
+ "optional": true
57
+ }
52
58
  },
53
59
  "devDependencies": {
54
60
  "@commitlint/cli": "^21.0.2",
@@ -79,6 +85,7 @@
79
85
  "type-decoder": "^2.3.1",
80
86
  "typescript": "^6.0.3",
81
87
  "typescript-eslint": "^8.60.1",
88
+ "lottie-web": "^5.13.0",
82
89
  "vite": "^8.0.16",
83
90
  "vitest": "^4.1.8"
84
91
  },