@juspay/svelte-ui-components 2.114.1 → 2.116.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.
@@ -1,13 +1,14 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import { fly, fade } from 'svelte/transition';
4
- import type { ModalAlign } from '../Modal/properties';
4
+ import type { ModalAlign, ModalEntryAnimation } from '../Modal/properties';
5
5
  import type { ModalTransition } from '../types';
6
6
 
7
7
  type Props = {
8
8
  enable?: boolean;
9
9
  align?: ModalAlign;
10
10
  transitionType?: ModalTransition;
11
+ entryAnimation?: ModalEntryAnimation;
11
12
  children?: Snippet;
12
13
  testId?: string;
13
14
  };
@@ -16,6 +17,7 @@
16
17
  enable = true,
17
18
  align = 'bottom',
18
19
  transitionType = 'ALL',
20
+ entryAnimation,
19
21
  children,
20
22
  testId
21
23
  }: Props = $props();
@@ -23,6 +25,16 @@
23
25
  let flyAnimationProperties = $derived.by(() => {
24
26
  const base = { x: 0, y: 0, duration: 380 };
25
27
 
28
+ // entryAnimation, when set, overrides the align-based default below —
29
+ // e.g. a centered modal (which normally fades) can opt into the same
30
+ // fly distances top/bottom alignment already use.
31
+ if (entryAnimation === 'slide-up') {
32
+ return { ...base, y: 300 };
33
+ }
34
+ if (entryAnimation === 'slide-down') {
35
+ return { ...base, y: -30 };
36
+ }
37
+
26
38
  switch (align) {
27
39
  case 'top':
28
40
  return { ...base, y: -30 };
@@ -35,7 +47,9 @@
35
47
 
36
48
  let fadeAnimationProperties = { duration: 300 };
37
49
 
38
- let useFlyAnimation = $derived(align === 'top' || align === 'bottom');
50
+ let useFlyAnimation = $derived(
51
+ entryAnimation != null ? entryAnimation !== 'fade' : align === 'top' || align === 'bottom'
52
+ );
39
53
  let useOutTransition = $derived(transitionType === 'ALL');
40
54
  </script>
41
55
 
@@ -1,10 +1,11 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { ModalAlign } from '../Modal/properties';
2
+ import type { ModalAlign, ModalEntryAnimation } from '../Modal/properties';
3
3
  import type { ModalTransition } from '../types';
4
4
  type Props = {
5
5
  enable?: boolean;
6
6
  align?: ModalAlign;
7
7
  transitionType?: ModalTransition;
8
+ entryAnimation?: ModalEntryAnimation;
8
9
  children?: Snippet;
9
10
  testId?: string;
10
11
  };
@@ -5,15 +5,28 @@
5
5
  type Props = {
6
6
  children?: Snippet;
7
7
  testId?: string;
8
+ /** When true, fades in on mount (same 350ms duration as the existing fade-out). Default false preserves the current instant-appear behavior. */
9
+ fadeIn?: boolean;
8
10
  };
9
11
 
10
- let { children, testId }: Props = $props();
12
+ let { children, testId, fadeIn = false }: Props = $props();
11
13
  </script>
12
14
 
13
- <div
14
- out:fade={{ duration: 350 }}
15
- data-pw={typeof testId === 'string' ? testId : null}
16
- testID={typeof testId === 'string' ? testId : null}
17
- >
18
- {@render children?.()}
19
- </div>
15
+ {#if fadeIn}
16
+ <div
17
+ in:fade={{ duration: 350 }}
18
+ out:fade={{ duration: 350 }}
19
+ data-pw={typeof testId === 'string' ? testId : null}
20
+ testID={typeof testId === 'string' ? testId : null}
21
+ >
22
+ {@render children?.()}
23
+ </div>
24
+ {:else}
25
+ <div
26
+ out:fade={{ duration: 350 }}
27
+ data-pw={typeof testId === 'string' ? testId : null}
28
+ testID={typeof testId === 'string' ? testId : null}
29
+ >
30
+ {@render children?.()}
31
+ </div>
32
+ {/if}
@@ -2,6 +2,8 @@ import type { Snippet } from 'svelte';
2
2
  type Props = {
3
3
  children?: Snippet;
4
4
  testId?: string;
5
+ /** When true, fades in on mount (same 350ms duration as the existing fade-out). Default false preserves the current instant-appear behavior. */
6
+ fadeIn?: boolean;
5
7
  };
6
8
  declare const OverlayAnimation: import("svelte").Component<Props, {}, "">;
7
9
  type OverlayAnimation = ReturnType<typeof OverlayAnimation>;
@@ -198,6 +198,10 @@
198
198
  font-weight: var(--button-font-weight, 500);
199
199
  font-size: var(--button-font-size, var(--_btn-font-size, 14px));
200
200
  background-color: var(--button-color, var(--_btn-color, #3a4550));
201
+ /* Image layer, deliberately not the `background` shorthand — the shorthand
202
+ would reset a consumer's own background-image/position/size layers
203
+ whenever the hook is unset. Gradients go here; solids stay on --button-color. */
204
+ background-image: var(--button-background, none);
201
205
  color: var(--button-text-color, var(--_btn-text-color, white));
202
206
  height: var(--button-height, fit-content);
203
207
  padding: var(--button-padding, var(--_btn-padding, 16px));
@@ -216,6 +220,7 @@
216
220
  gap: var(--button-content-gap, 16px);
217
221
  visibility: var(--button-visibility, visible);
218
222
  box-shadow: var(--button-box-shadow, none);
223
+ transition: var(--button-transition, none);
219
224
 
220
225
  /* A button label should never soft-wrap onto a second line as the label text
221
226
  changes (e.g. "Select" -> "Select (1)") — that jitters the layout around it.
@@ -232,7 +237,10 @@
232
237
  font-weight: var(--disabled-font-weight);
233
238
  /* Preserve the variant border when disabled so secondary (bordered) stays distinct from ghost. */
234
239
  border: var(--disabled-border, var(--button-border, var(--_btn-border, none)));
235
- background: var(--disabled-background-color, var(--button-color, var(--_btn-color, #3a4550)));
240
+ background: var(
241
+ --disabled-background-color,
242
+ var(--button-background, var(--button-color, var(--_btn-color, #3a4550)))
243
+ );
236
244
  box-shadow: var(
237
245
  --button-disabled-box-shadow,
238
246
  var(--disabled-box-shadow, var(--button-box-shadow, none))
@@ -262,7 +270,10 @@
262
270
  .button-el:hover:not(.disabled) {
263
271
  background: var(
264
272
  --button-hover-color,
265
- var(--_btn-hover-color, var(--button-color, var(--_btn-color, #3a4550)))
273
+ var(
274
+ --_btn-hover-color,
275
+ var(--button-background, var(--button-color, var(--_btn-color, #3a4550)))
276
+ )
266
277
  );
267
278
  color: var(
268
279
  --button-hover-text-color,
@@ -278,7 +289,10 @@
278
289
 
279
290
  .button-el:active:not(.disabled) {
280
291
  transform: var(--button-active-transform);
281
- background: var(--button-active-background, var(--button-color, var(--_btn-color, #3a4550)));
292
+ background: var(
293
+ --button-active-background,
294
+ var(--button-background, var(--button-color, var(--_btn-color, #3a4550)))
295
+ );
282
296
  box-shadow: var(--button-active-box-shadow, var(--button-box-shadow, none));
283
297
  }
284
298
 
@@ -17,6 +17,7 @@
17
17
  supportHardwareBackPress = false,
18
18
  enableTransition = true,
19
19
  transitionType = 'ALL',
20
+ entryAnimation,
20
21
  header = {},
21
22
  footer,
22
23
  debounceTime = 700,
@@ -34,6 +35,7 @@
34
35
  onkeydown,
35
36
  classes,
36
37
  overlayBackdropFilter,
38
+ overlayFadeIn = false,
37
39
  usePortal = false
38
40
  }: ModalProperties = $props();
39
41
 
@@ -138,7 +140,7 @@
138
140
  <svelte:window onkeydown={handleKeyDown} />
139
141
 
140
142
  {#if typeof content === 'function'}
141
- <OverlayAnimation>
143
+ <OverlayAnimation fadeIn={overlayFadeIn}>
142
144
  <div
143
145
  bind:this={overlayDiv}
144
146
  use:portalAction={{ usePortal }}
@@ -153,7 +155,7 @@
153
155
  data-pw={testId}
154
156
  testID={testId}
155
157
  >
156
- <ModalAnimation enable={enableTransition} {align} {transitionType}>
158
+ <ModalAnimation enable={enableTransition} {align} {transitionType} {entryAnimation}>
157
159
  <div class="modal-content {size}">
158
160
  {#if (typeof header?.leftImage === 'string' && header.leftImage.length > 0) || (typeof header?.text === 'string' && header.text.length > 0) || (typeof header?.rightImage === 'string' && header.rightImage.length > 0)}
159
161
  <div class="header">
@@ -3,6 +3,14 @@ import type { ModalTransition } from '../types';
3
3
  import type { Snippet } from 'svelte';
4
4
  export type ModalSize = 'large' | 'medium' | 'small' | 'fit-content';
5
5
  export type ModalAlign = 'top' | 'center' | 'bottom';
6
+ /**
7
+ * Overrides ModalAnimation's default per-align entry transition ('top'/'bottom'
8
+ * fly, 'center' fade). 'slide-up' and 'slide-down' reuse the same fly
9
+ * distance/duration constants as bottom/top alignment respectively, so e.g. a
10
+ * centered modal can slide up like a bottom sheet instead of just fading in.
11
+ * Leave unset to keep the existing per-align default.
12
+ */
13
+ export type ModalEntryAnimation = 'fade' | 'slide-up' | 'slide-down';
6
14
  export type ModalProperties = OptionalModalProperties & ModalEventProperties;
7
15
  export type OptionalModalProperties = {
8
16
  size?: ModalSize;
@@ -11,6 +19,8 @@ export type OptionalModalProperties = {
11
19
  supportHardwareBackPress?: boolean;
12
20
  enableTransition?: boolean;
13
21
  transitionType?: ModalTransition;
22
+ /** Overrides the default per-align entry transition. See ModalEntryAnimation. Default: unset (per-align behavior). */
23
+ entryAnimation?: ModalEntryAnimation;
14
24
  header?: {
15
25
  leftImage?: string;
16
26
  rightImage?: string;
@@ -34,6 +44,8 @@ export type OptionalModalProperties = {
34
44
  classes?: string;
35
45
  /** CSS value applied to backdrop-filter on the overlay (e.g. "blur(6px)"). Exposed as --modal-overlay-backdrop-filter CSS var. Default: none (no blur). */
36
46
  overlayBackdropFilter?: string;
47
+ /** When true, the overlay backdrop fades in on mount instead of appearing instantly. Pairs well with entryAnimation="slide-up" for a softer combined entrance. Default: false (current instant-appear behavior). */
48
+ overlayFadeIn?: boolean;
37
49
  /** When true, mounts the overlay at document.body to escape clipping/stacking contexts. Default: false. */
38
50
  usePortal?: boolean;
39
51
  };
@@ -177,6 +177,7 @@
177
177
  top: var(--toast-top, 10px);
178
178
  left: var(--toast-left, 0);
179
179
  right: var(--toast-right, 0);
180
+ bottom: var(--toast-bottom, auto);
180
181
  background-color: var(--toast-background-color, #87ceeb);
181
182
  opacity: var(--toast-opacity, 1);
182
183
  box-sizing: var(--toast-box-sizing);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/svelte-ui-components",
3
- "version": "2.114.1",
3
+ "version": "2.116.0",
4
4
  "description": "A themeable Svelte 5 UI component library with CSS custom property driven styling",
5
5
  "keywords": [
6
6
  "svelte",