@dynamic-framework/ui-react 2.6.0 → 2.8.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.
Files changed (49) hide show
  1. package/dist/css/dynamic-ui.css +278 -3
  2. package/dist/css/dynamic-ui.min.css +2 -2
  3. package/dist/index.esm.js +575 -284
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +577 -281
  6. package/dist/index.js.map +1 -1
  7. package/dist/types/components/DCarousel/DCarousel.d.ts +9 -2
  8. package/dist/types/components/DDropdown/DDropdown.d.ts +10 -2
  9. package/dist/types/components/DIcon/DIcon.d.ts +4 -4
  10. package/dist/types/components/DIconBase/DIconBase.d.ts +3 -2
  11. package/dist/types/components/DIconBase/index.d.ts +1 -0
  12. package/dist/types/components/DOffcanvas/DOffcanvas.d.ts +15 -3
  13. package/dist/types/components/DOtp/DOtp.d.ts +1 -0
  14. package/dist/types/components/DOtp/components/OtpCountdown.d.ts +3 -2
  15. package/dist/types/components/DVoucher/DVoucher.d.ts +3 -1
  16. package/dist/types/components/DVoucher/hooks/useScreenshotDownload.d.ts +1 -1
  17. package/dist/types/components/DVoucher/hooks/useScreenshotDownload.spec.d.ts +1 -0
  18. package/dist/types/components/DVoucher/hooks/useScreenshotWebShare.d.ts +1 -1
  19. package/dist/types/components/DVoucher/hooks/useScreenshotWebShare.spec.d.ts +1 -0
  20. package/dist/types/components/DVoucher/index.d.ts +3 -0
  21. package/dist/types/components/index.d.ts +1 -1
  22. package/dist/types/components/interface.d.ts +5 -3
  23. package/dist/types/contexts/DContext.d.ts +3 -2
  24. package/dist/types/hooks/index.d.ts +3 -0
  25. package/dist/types/hooks/tests/useCountdown.spec.d.ts +1 -0
  26. package/dist/types/hooks/useCountdown.d.ts +14 -0
  27. package/dist/types/hooks/useInputCurrency.d.ts +1 -6
  28. package/dist/types/hooks/useOtp.d.ts +98 -0
  29. package/package.json +3 -1
  30. package/src/style/abstracts/variables/_+import.scss +1 -0
  31. package/src/style/abstracts/variables/_input-currency.scss +1 -0
  32. package/src/style/abstracts/variables/_offcanvas.scss +8 -0
  33. package/src/style/components/_+import.scss +7 -0
  34. package/src/style/components/_d-box-file.scss +5 -0
  35. package/src/style/components/_d-carousel.scss +19 -1
  36. package/src/style/components/_d-close.scss +1 -0
  37. package/src/style/components/_d-confirm-modal.scss +17 -0
  38. package/src/style/components/_d-data-state-wrapper.scss +47 -0
  39. package/src/style/components/_d-datepicker.scss +11 -0
  40. package/src/style/components/_d-error-boundary.scss +7 -0
  41. package/src/style/components/_d-input-currency.scss +5 -0
  42. package/src/style/components/_d-otp.scss +54 -0
  43. package/src/style/components/_d-password-strength-meter.scss +76 -0
  44. package/src/style/components/_d-popover.scss +4 -0
  45. package/src/style/components/_d-stepper.scss +8 -0
  46. package/src/style/components/_d-tabs.scss +18 -0
  47. package/src/style/components/_d-voucher.scss +30 -0
  48. package/dist/types/components/DOtp/DOtpspec.d.ts +0 -0
  49. package/dist/types/components/DOtp/hooks/useCountdown.d.ts +0 -4
@@ -1,11 +1,18 @@
1
- /// <reference types="react" />
2
1
  import { Splide } from '@splidejs/react-splide';
2
+ import type { ComponentProps } from 'react';
3
3
  import type { SplideProps } from '@splidejs/react-splide';
4
+ import DIcon from '../DIcon';
4
5
  import DCarouselSlide from './components/DCarouselSlide';
5
6
  import type { BaseProps } from '../interface';
7
+ type ArrowIconProps = {
8
+ /** DIcon props used to render the "previous" arrow icon. */
9
+ iconArrowLeft?: ComponentProps<typeof DIcon>;
10
+ /** DIcon props used to render the "next" arrow icon. */
11
+ iconArrowRight?: ComponentProps<typeof DIcon>;
12
+ };
6
13
  declare const _default: import("react").ForwardRefExoticComponent<SplideProps & BaseProps & {
7
14
  children?: import("react").ReactNode;
8
- } & import("react").RefAttributes<Splide>> & {
15
+ } & ArrowIconProps & import("react").RefAttributes<Splide>> & {
9
16
  Slide: typeof DCarouselSlide;
10
17
  };
11
18
  export default _default;
@@ -8,7 +8,14 @@ export type DropdownAction = {
8
8
  isDivider?: boolean;
9
9
  label: string;
10
10
  };
11
- type DropdownPlacement = 'auto' | 'down' | 'up' | 'start' | 'end';
11
+ type ResolvedSide = 'down' | 'up' | 'start' | 'end';
12
+ type DropdownPlacement = 'auto' | ResolvedSide;
13
+ /**
14
+ * Horizontal alignment of the menu relative to the toggle, applied only when
15
+ * the resolved placement is vertical (`down`/`up`) — mirrors Bootstrap's
16
+ * `dropdown-menu-end`/`dropdown-center` menu alignment options.
17
+ */
18
+ export type DropdownAlignment = 'start' | 'end' | 'center';
12
19
  type Props = {
13
20
  actions: DropdownAction[];
14
21
  dropdownToggle?: ((props: {
@@ -19,6 +26,7 @@ type Props = {
19
26
  classNameMenu?: string;
20
27
  asPortal?: boolean;
21
28
  placement?: DropdownPlacement;
29
+ alignment?: DropdownAlignment;
22
30
  };
23
- export default function DDropdown({ actions, dropdownToggle, className, classNameMenu, asPortal, placement, }: Props): import("react").JSX.Element;
31
+ export default function DDropdown({ actions, dropdownToggle, className, classNameMenu, asPortal, placement, alignment, }: Props): import("react").JSX.Element;
24
32
  export {};
@@ -1,5 +1,5 @@
1
- import type { ComponentProps } from 'react';
2
- import DIconBase from '../DIconBase';
3
- type Props = ComponentProps<typeof DIconBase>;
4
- export default function DIcon({ familyClass: propFamilyClass, familyPrefix: propFamilyPrefix, materialStyle: propMaterialStyle, ...props }: Props): import("react").JSX.Element;
1
+ /// <reference types="react" />
2
+ import type { DIconBaseProps } from '../DIconBase';
3
+ type Props = DIconBaseProps;
4
+ export default function DIcon({ icon, familyClass: propFamilyClass, familyPrefix: propFamilyPrefix, materialStyle: propMaterialStyle, ...props }: Props): import("react").JSX.Element;
5
5
  export {};
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
- import type { BaseProps, ComponentColor } from '../interface';
2
+ import type { BaseProps, ComponentColor, IconValue } from '../interface';
3
3
  import { ResponsiveProp } from '../../hooks/useResponsiveProp';
4
4
  type Props = BaseProps & {
5
- icon: string;
5
+ icon: IconValue;
6
6
  color?: ComponentColor;
7
7
  size?: string | ResponsiveProp;
8
8
  /**
@@ -18,5 +18,6 @@ type Props = BaseProps & {
18
18
  familyPrefix?: string;
19
19
  strokeWidth?: number;
20
20
  };
21
+ export type DIconBaseProps = Props;
21
22
  export default function DIconBase({ icon, color, style, className, size, useListenerSize, hasCircle, materialStyle, familyClass, familyPrefix, strokeWidth, dataAttributes, }: Props): import("react").JSX.Element;
22
23
  export {};
@@ -1,2 +1,3 @@
1
1
  import DIconBase from './DIconBase';
2
+ export type { DIconBaseProps } from './DIconBase';
2
3
  export default DIconBase;
@@ -1,17 +1,29 @@
1
1
  import { type Transition } from 'framer-motion';
2
- import type { PropsWithChildren } from 'react';
2
+ import { type PropsWithChildren } from 'react';
3
+ import { ResponsiveProp } from '../../hooks/useResponsiveProp';
3
4
  import DOffcanvasHeader from './components/DOffcanvasHeader';
4
5
  import DOffcanvasBody from './components/DOffcanvasBody';
5
6
  import DOffcanvasFooter from './components/DOffcanvasFooter';
6
7
  import type { BaseProps, OffcanvasPositionToggleFrom } from '../interface';
8
+ type OffcanvasResponsivePlacement = Partial<Record<'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl', OffcanvasPositionToggleFrom>>;
7
9
  type Props = BaseProps & PropsWithChildren<{
8
10
  name: string;
9
11
  staticBackdrop?: boolean;
10
12
  scrollable?: boolean;
11
- openFrom?: OffcanvasPositionToggleFrom;
13
+ openFrom?: OffcanvasPositionToggleFrom | OffcanvasResponsivePlacement;
14
+ /**
15
+ * Overrides the offcanvas size on the `start`/`end` placements (defaults to `400px`).
16
+ * Accepts any CSS length (e.g. `'320px'`, `'50vw'`, `'100%'`) or a `ResponsiveProp` object.
17
+ */
18
+ width?: string | ResponsiveProp;
19
+ /**
20
+ * Overrides the offcanvas size on the `top`/`bottom` placements (defaults to `100%`).
21
+ * Accepts any CSS length (e.g. `'50vh'`, `'320px'`) or a `ResponsiveProp` object.
22
+ */
23
+ height?: string | ResponsiveProp;
12
24
  transition?: Transition;
13
25
  }>;
14
- declare function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom, transition, children, dataAttributes, }: Props): import("react").JSX.Element;
26
+ declare function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom, width, height, transition, children, dataAttributes, }: Props): import("react").JSX.Element;
15
27
  declare const _default: typeof DOffcanvas & {
16
28
  Header: typeof DOffcanvasHeader;
17
29
  Body: typeof DOffcanvasBody;
@@ -11,6 +11,7 @@ export type PropsOtp = PropsWithChildren<{
11
11
  title?: string;
12
12
  contact?: string | React.ReactNode;
13
13
  resendText?: string;
14
+ invalidCode?: string;
14
15
  };
15
16
  }>;
16
17
  export default function DOtp({ className, action, isLoading, otpSize, texts, seconds, }: PropsOtp): import("react").JSX.Element;
@@ -1,8 +1,9 @@
1
1
  /// <reference types="react" />
2
2
  type Props = {
3
- seconds: number;
3
+ secondsLeft: number;
4
+ restartCountdown: () => void;
4
5
  resendText?: string;
5
6
  message?: (secondsLeft: number) => string;
6
7
  };
7
- export default function OtpCountdown({ seconds, resendText, message, }: Props): import("react").JSX.Element;
8
+ export default function OtpCountdown({ secondsLeft, restartCountdown, resendText, message, }: Props): import("react").JSX.Element;
8
9
  export {};
@@ -9,7 +9,9 @@ type Props = PropsWithChildren<{
9
9
  title: string;
10
10
  downloadText?: string;
11
11
  shareText?: string;
12
+ fileName?: string;
13
+ hideActions?: boolean;
12
14
  onError?: (err: Error) => Promise<void> | void;
13
15
  }>;
14
- export default function DVoucher({ amount, amountDetails, icon, title, onError, message, downloadText, shareText, className, children, }: Props): import("react").JSX.Element;
16
+ export default function DVoucher({ amount, amountDetails, icon, title, onError, message, downloadText, shareText, fileName, hideActions, className, children, }: Props): import("react").JSX.Element;
15
17
  export {};
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  export default function useScreenshotDownload(): {
3
- download: () => Promise<void>;
3
+ download: (fileName?: string) => Promise<void>;
4
4
  downloadRef: import("react").RefObject<HTMLDivElement | null>;
5
5
  };
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  export default function useScreenshotWebShare(): {
3
- share: () => Promise<void>;
3
+ share: (fileName?: string) => Promise<void>;
4
4
  shareRef: import("react").RefObject<HTMLDivElement | null>;
5
5
  };
@@ -1,2 +1,5 @@
1
1
  import DVoucher from './DVoucher';
2
+ export { default as useScreenshot } from './hooks/useScreenshot';
3
+ export { default as useScreenshotDownload } from './hooks/useScreenshotDownload';
4
+ export { default as useScreenshotWebShare } from './hooks/useScreenshotWebShare';
2
5
  export default DVoucher;
@@ -50,7 +50,7 @@ export type { DToastContainerProps, DToastOptions, ToastData } from './DToastCon
50
50
  export { default as DInputPhone } from './DInputPhone';
51
51
  export { default as DCreditCard } from './DCreditCard';
52
52
  export { default as DDropdown } from './DDropdown';
53
- export { default as DVoucher } from './DVoucher';
53
+ export { default as DVoucher, useScreenshot, useScreenshotDownload, useScreenshotWebShare, } from './DVoucher';
54
54
  export { default as DOtp } from './DOtp';
55
55
  export { default as DErrorBoundary, useErrorBoundary, type FallbackProps, getErrorMessage, } from './DErrorBoundary';
56
56
  export { default as DDataStateWrapper, EmptyState, ErrorState, LoadingState, } from './DDataStateWrapper';
@@ -1,4 +1,4 @@
1
- import type { CSSProperties } from 'react';
1
+ import type { ComponentType, CSSProperties, SVGProps } from 'react';
2
2
  export type ClassMap = {
3
3
  [className: string]: boolean;
4
4
  };
@@ -19,13 +19,15 @@ export type BaseProps = {
19
19
  className?: string;
20
20
  dataAttributes?: DataAttributes;
21
21
  };
22
+ export type IconComponent = ComponentType<SVGProps<SVGSVGElement>>;
23
+ export type IconValue = string | IconComponent;
22
24
  export type FamilyIconProps = {
23
25
  iconFamilyClass?: string;
24
26
  iconFamilyPrefix?: string;
25
27
  iconMaterialStyle?: boolean;
26
28
  };
27
29
  export type StartIconProps = {
28
- iconStart?: string;
30
+ iconStart?: IconValue;
29
31
  iconStartDisabled?: boolean;
30
32
  iconStartFamilyClass?: string;
31
33
  iconStartFamilyPrefix?: string;
@@ -34,7 +36,7 @@ export type StartIconProps = {
34
36
  iconStartMaterialStyle?: boolean;
35
37
  };
36
38
  export type EndIconProps = {
37
- iconEnd?: string;
39
+ iconEnd?: IconValue;
38
40
  iconEndDisabled?: boolean;
39
41
  iconEndFamilyClass?: string;
40
42
  iconEndFamilyPrefix?: string;
@@ -1,6 +1,6 @@
1
1
  import { type PropsWithChildren } from 'react';
2
2
  import { type PortalContextProps } from './DPortalContext';
3
- import type { AlertThemeIconMap } from '../components/interface';
3
+ import type { AlertThemeIconMap, IconComponent } from '../components/interface';
4
4
  /**
5
5
  * Currency formatting configuration used by `DContextProvider`.
6
6
  */
@@ -86,6 +86,7 @@ type Props = {
86
86
  language: string;
87
87
  currency: CurrencyProps;
88
88
  icon: IconProps;
89
+ iconRegistry?: Record<string, IconComponent>;
89
90
  iconMap: IconMapProps;
90
91
  breakpoints: BreakpointProps;
91
92
  };
@@ -124,7 +125,7 @@ export declare const DContext: import("react").Context<Context>;
124
125
  * @template T - Map of portal name → payload shape (e.g. `{ modal: { title: string } }`).
125
126
  * Pass it once at the top level: `<DContextProvider<MyPortals> ...>`.
126
127
  */
127
- export declare function DContextProvider<T extends Record<string, unknown>>({ language, currency, icon, iconMap, portalName, availablePortals, children, }: PropsWithChildren<Partial<DContextProviderProps<T>>>): import("react").JSX.Element;
128
+ export declare function DContextProvider<T extends Record<string, unknown>>({ language, currency, icon, iconRegistry, iconMap, portalName, availablePortals, children, }: PropsWithChildren<Partial<DContextProviderProps<T>>>): import("react").JSX.Element;
128
129
  /**
129
130
  * Returns the Dynamic UI context value set by `DContextProvider`.
130
131
  * Falls back to the library's built-in defaults when no `DContextProvider`
@@ -9,3 +9,6 @@ export { default as useMediaQuery } from './useMediaQuery';
9
9
  export { default as useConfirmModal } from './useConfirmModal';
10
10
  export type { UseConfirmModalConfig, UseConfirmModalReturn, ConfirmModalColor, CriticalConfirmConfig, } from './useConfirmModal';
11
11
  export { useMediaBreakpointUpXs, useMediaBreakpointUpSm, useMediaBreakpointUpMd, useMediaBreakpointUpLg, useMediaBreakpointUpXl, useMediaBreakpointUpXxl, } from './useMediaBreakpointUp';
12
+ export { default as useCountdown } from './useCountdown';
13
+ export { default as useOtp } from './useOtp';
14
+ export type { UseOtpConfig, UseOtpReturn } from './useOtp';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Generic seconds-based countdown hook.
3
+ *
4
+ * Starts counting down from `seconds` to `0` and exposes `restartCountdown`
5
+ * to reset and restart the timer (e.g. for "resend code in Xs" patterns,
6
+ * session-expiry banners, or any other cooldown/throttle UI).
7
+ *
8
+ * @example
9
+ * const { secondsLeft, restartCountdown } = useCountdown(30);
10
+ */
11
+ export default function useCountdown(seconds: number): {
12
+ secondsLeft: number;
13
+ restartCountdown: () => void;
14
+ };
@@ -1,15 +1,10 @@
1
1
  import type { RefObject, ForwardedRef, FocusEvent } from 'react';
2
2
  import type { Options } from 'currency.js';
3
- import type { CustomStyles } from '../components/interface';
4
- export default function useInputCurrency(currencyOptions: Options, value?: number, onFocus?: (event: FocusEvent<HTMLInputElement>) => void, onChange?: (value?: number) => void, onBlur?: (event: FocusEvent<HTMLInputElement>) => void, ref?: ForwardedRef<HTMLInputElement>): {
3
+ export default function useInputCurrency(currencyOptions: Options, value?: number, onFocus?: (event: FocusEvent<HTMLInputElement>) => void, onChange?: (value?: number) => void, onBlur?: (event: FocusEvent<HTMLInputElement>) => void, ref?: ForwardedRef<HTMLInputElement>, minValue?: number, maxValue?: number): {
5
4
  inputRef: RefObject<HTMLInputElement | null>;
6
5
  innerValue: string;
7
6
  innerType: string;
8
7
  handleOnFocus: (event: FocusEvent<HTMLInputElement>) => void;
9
8
  handleOnChange: (newValue?: string) => void;
10
9
  handleOnBlur: (event: FocusEvent<HTMLInputElement>) => void;
11
- generateStyleVariables: CustomStyles;
12
- generateSymbolStyleVariables: {
13
- color: string;
14
- };
15
10
  };
@@ -0,0 +1,98 @@
1
+ export type UseOtpConfig = {
2
+ /** Called when the OTP reaches the expected length and `submit()` is invoked. */
3
+ action: () => Promise<void> | void;
4
+ /** Expected number of digits/characters for a valid OTP. Defaults to `6`. */
5
+ otpSize?: number;
6
+ /** Initial countdown (in seconds) before resend becomes available. Defaults to `15`. */
7
+ seconds?: number;
8
+ };
9
+ export type UseOtpReturn = {
10
+ /** Current OTP value. */
11
+ otp: string;
12
+ /**
13
+ * Updates the OTP value (wire this to your custom pin input's `onChange`).
14
+ * Also clears `invalid`/`error` as soon as the value actually changes, so
15
+ * the error state disappears once the user edits the code (a no-op call
16
+ * with the same value, e.g. from an uncontrolled input re-notifying its
17
+ * current value, does not reset `invalid`/`error`).
18
+ */
19
+ setOtp: (value: string) => void;
20
+ /**
21
+ * `true` when `submit()` is called with an OTP shorter than `otpSize`, or
22
+ * when `action` throws/rejects (e.g. the backend rejected the entered
23
+ * code as incorrect).
24
+ */
25
+ invalid: boolean;
26
+ /**
27
+ * The value thrown/rejected by `action`, or `null` otherwise. Use it to
28
+ * render a specific message for a wrong code, as opposed to a too-short
29
+ * one.
30
+ */
31
+ error: unknown;
32
+ /**
33
+ * Validates the OTP length; if valid, calls `action`. If `action`
34
+ * rejects, the returned promise rejects too (so callers can still
35
+ * `.catch()` it for logging), and `invalid`/`error` are set beforehand.
36
+ */
37
+ submit: () => Promise<void>;
38
+ /**
39
+ * `true` while `action` is being awaited inside `submit()` (i.e. the OTP
40
+ * passed the length check and the async action hasn't settled yet). Wire
41
+ * it to your submit button's loading/disabled state. It's `false` while
42
+ * idle and immediately after `action` settles (whether it resolves or
43
+ * rejects), and it's never set to `true` for the too-short/length
44
+ * validation failure since `action` isn't called in that case.
45
+ */
46
+ isLoading: boolean;
47
+ /** Seconds remaining until resend is available. */
48
+ secondsLeft: number;
49
+ /** Restarts the resend countdown (call it from your "Resend" action). */
50
+ restartCountdown: () => void;
51
+ };
52
+ /**
53
+ * Headless hook exposing the same OTP logic used internally by `DOtp`
54
+ * (code state, length + correctness validation, submit action and resend
55
+ * countdown), without any bundled markup/styles.
56
+ *
57
+ * Use this when the default `DOtp` component doesn't match your design and
58
+ * you need to build a fully custom UI while reusing the same behavior.
59
+ *
60
+ * Internally composes `useCountdown` for the resend timer and re-exposes
61
+ * `secondsLeft`/`restartCountdown`, so there is no need to call
62
+ * `useCountdown` separately.
63
+ *
64
+ * `invalid` becomes `true` both when the OTP is shorter than `otpSize` and
65
+ * when `action` throws/rejects (e.g. the backend rejected the entered code
66
+ * as incorrect). In the latter case, the thrown value is exposed as `error`
67
+ * so custom UIs can render an appropriate message (e.g. "Invalid code" vs.
68
+ * "Enter all digits"). `invalid`/`error` are cleared automatically as soon
69
+ * as the user edits the code via `setOtp`.
70
+ *
71
+ * @example
72
+ * function CustomOtp() {
73
+ * const {
74
+ * otp,
75
+ * setOtp,
76
+ * invalid,
77
+ * error,
78
+ * submit,
79
+ * isLoading,
80
+ * secondsLeft,
81
+ * restartCountdown,
82
+ * } = useOtp({ action: async () => verifyOtp(otp), otpSize: 6, seconds: 15 });
83
+ *
84
+ * return (
85
+ * <>
86
+ * <MyCustomPinInput value={otp} onChange={setOtp} invalid={invalid} />
87
+ * {invalid && <span>{error ? 'Invalid code' : 'Enter all digits'}</span>}
88
+ * <button disabled={isLoading} onClick={() => { submit().catch(() => {}); }}>
89
+ * {isLoading ? 'Submitting...' : 'Submit'}
90
+ * </button>
91
+ * <button disabled={secondsLeft > 0} onClick={restartCountdown}>
92
+ * Resend {secondsLeft > 0 ? `(${secondsLeft}s)` : ''}
93
+ * </button>
94
+ * </>
95
+ * );
96
+ * }
97
+ */
98
+ export default function useOtp({ action, otpSize, seconds, }: UseOtpConfig): UseOtpReturn;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "sideEffects": [
4
4
  "*.css"
5
5
  ],
6
- "version": "2.6.0",
6
+ "version": "2.8.0",
7
7
  "description": "React Dynamic Framework",
8
8
  "license": "https://github.com/dynamic-framework/dynamic-ui/blob/master/LICENSE.md",
9
9
  "repository": {
@@ -110,6 +110,7 @@
110
110
  "react-datepicker": "~8.3.0",
111
111
  "react-error-boundary": "^6.1.0",
112
112
  "react-international-phone": "~4.6.0",
113
+ "react-is": "^19.2.7",
113
114
  "react-responsive-pagination": "~2.11.3",
114
115
  "react-select": "~5.10.2"
115
116
  },
@@ -132,6 +133,7 @@
132
133
  "@types/node": "^22.0.0",
133
134
  "@types/react": "^19.2.0",
134
135
  "@types/react-dom": "^19.2.0",
136
+ "@types/react-is": "^19.2.0",
135
137
  "@typescript-eslint/eslint-plugin": "~6.9.0",
136
138
  "@typescript-eslint/parser": "~6.9.0",
137
139
  "@vitejs/plugin-react": "~4.7.0",
@@ -94,4 +94,5 @@ $input-btn-border-width: var(--#{$prefix}border-width) !default;
94
94
  @import "box-file";
95
95
  @import "datepicker";
96
96
  @import "input-phone";
97
+ @import "input-currency";
97
98
  // end custom
@@ -0,0 +1 @@
1
+ $input-currency-symbol-color: var(--#{$prefix}secondary) !default;
@@ -15,3 +15,11 @@ $offcanvas-separator-margin-x: var(--#{$prefix}ref-spacer-4) !default;
15
15
 
16
16
  $offcanvas-bg-color: var(--#{$prefix}white) !default;
17
17
  // scss-docs-end offcanvas-variables
18
+
19
+ // custom
20
+ // Bootstrap's default is 30vh, which cuts off top/bottom offcanvas content
21
+ // (e.g. mobile bottom-sheet placements) and forces an inner scroll. Cover the
22
+ // full viewport height instead, relying on `.offcanvas-body`'s own
23
+ // `overflow-y: auto` to scroll long content while header/footer stay fixed.
24
+ $offcanvas-vertical-height: 100% !default;
25
+ // end custom
@@ -22,3 +22,10 @@
22
22
  @import "d-table-head";
23
23
  @import "d-input-phone";
24
24
  @import "d-credit-card";
25
+ @import "d-input-currency";
26
+ @import "d-confirm-modal";
27
+ @import "d-data-state-wrapper";
28
+ @import "d-error-boundary";
29
+ @import "d-otp";
30
+ @import "d-password-strength-meter";
31
+ @import "d-stepper";
@@ -69,6 +69,11 @@
69
69
  }
70
70
  }
71
71
 
72
+ .d-box-file-empty-text {
73
+ margin: 0;
74
+ text-align: center;
75
+ }
76
+
72
77
  .d-box-files {
73
78
  --#{$prefix}box-file-list-gap: #{$box-file-list-gap};
74
79
  --#{$prefix}box-file-list-padding: #{$box-file-list-padding};
@@ -42,9 +42,27 @@
42
42
  height: $carousel-control-height;
43
43
  background: var(--#{$prefix}primary);
44
44
  padding: var(--#{$prefix}ref-spacer-1);
45
- svg {
45
+
46
+ // Only invert the default arrow icon (a bare <svg> as a direct child).
47
+ // Custom icons rendered via `iconArrowLeft`/`iconArrowRight` use DIcon
48
+ // (wrapped in a .d-icon span) and are reset below, so they are untouched here.
49
+ > svg {
46
50
  filter: invert(1);
47
51
  }
52
+
53
+ // Splide's default theme applies `fill` and, for the prev arrow, a
54
+ // `scaleX(-1)` flip to every descendant <svg>, assuming a single arrow
55
+ // path reused for both directions. `iconArrowLeft`/`iconArrowRight` are
56
+ // typed as DIcon props, so the only <svg> rendered here is a Lucide icon,
57
+ // which is always stroke-based with `fill="none"` (see lucide-react
58
+ // defaultAttributes). Resetting to `fill: none` restores that intended
59
+ // stroke-only look and lets DIcon's own `color` (applied via `currentColor`
60
+ // on stroke) keep controlling the icon color; `transform: none` cancels
61
+ // the flip so the icon keeps its intended orientation.
62
+ .d-icon svg {
63
+ fill: none;
64
+ transform: none;
65
+ }
48
66
  }
49
67
 
50
68
  .d-carousel-pagination {
@@ -1,5 +1,6 @@
1
1
  .d-close {
2
2
  display: flex;
3
+ align-self: center;
3
4
  padding: 0;
4
5
  background: transparent;
5
6
  border: 0;
@@ -0,0 +1,17 @@
1
+ .confirm-modal {
2
+ --#{$prefix}confirm-modal-body-padding-y: var(--#{$prefix}ref-spacer-3);
3
+ --#{$prefix}confirm-modal-body-padding-x: var(--#{$prefix}ref-spacer-5);
4
+ --#{$prefix}confirm-modal-field-gap: var(--#{$prefix}ref-spacer-4);
5
+ }
6
+
7
+ .d-confirm-modal-body {
8
+ padding: var(--#{$prefix}confirm-modal-body-padding-y) var(--#{$prefix}confirm-modal-body-padding-x);
9
+ }
10
+
11
+ .d-confirm-modal-message {
12
+ margin-bottom: var(--#{$prefix}confirm-modal-field-gap);
13
+ }
14
+
15
+ .d-confirm-modal-field {
16
+ margin-bottom: var(--#{$prefix}confirm-modal-field-gap);
17
+ }
@@ -0,0 +1,47 @@
1
+ .d-empty-state {
2
+ --#{$prefix}empty-state-padding: var(--#{$prefix}ref-spacer-5);
3
+ --#{$prefix}empty-state-spacing: var(--#{$prefix}ref-spacer-3);
4
+ --#{$prefix}empty-state-color: var(--#{$prefix}secondary);
5
+
6
+ display: flex;
7
+ flex-direction: column;
8
+ align-items: center;
9
+ justify-content: center;
10
+ padding: var(--#{$prefix}empty-state-padding);
11
+ text-align: center;
12
+ }
13
+
14
+ .d-empty-state-icon {
15
+ margin-bottom: var(--#{$prefix}empty-state-spacing);
16
+ color: var(--#{$prefix}empty-state-color);
17
+ }
18
+
19
+ .d-empty-state-message {
20
+ margin-bottom: var(--#{$prefix}empty-state-spacing);
21
+ color: var(--#{$prefix}empty-state-color);
22
+ }
23
+
24
+ .d-error-state {
25
+ --#{$prefix}error-state-gap: var(--#{$prefix}ref-spacer-3);
26
+
27
+ display: flex;
28
+ gap: var(--#{$prefix}error-state-gap);
29
+ align-items: center;
30
+ }
31
+
32
+ .d-error-state-content {
33
+ flex: 1 1 auto;
34
+ }
35
+
36
+ .d-error-state-message {
37
+ margin-bottom: 0;
38
+ }
39
+
40
+ .d-loading-state {
41
+ --#{$prefix}loading-state-padding: var(--#{$prefix}ref-spacer-4);
42
+
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ padding: var(--#{$prefix}loading-state-padding);
47
+ }
@@ -215,6 +215,12 @@
215
215
  }
216
216
  }
217
217
 
218
+ &-year-selector {
219
+ display: flex;
220
+ flex-grow: 1;
221
+ justify-content: center;
222
+ }
223
+
218
224
  &-day-selector {
219
225
  margin-bottom: var(--#{$prefix}ref-spacer-4);
220
226
 
@@ -287,6 +293,11 @@
287
293
  margin-top: -.5rem;
288
294
  }
289
295
 
296
+ .datepicker-top-header-title {
297
+ margin-bottom: 0;
298
+ font-weight: var(--#{$prefix}fw-normal);
299
+ }
300
+
290
301
  .react-datepicker__year,
291
302
  .react-datepicker__quarterPicker {
292
303
  --#{$prefix}datepicker-body-gap: 1rem;
@@ -0,0 +1,7 @@
1
+ .d-error-boundary-content {
2
+ --#{$prefix}error-boundary-gap: var(--#{$prefix}ref-spacer-2);
3
+
4
+ display: flex;
5
+ gap: var(--#{$prefix}error-boundary-gap);
6
+ align-items: center;
7
+ }
@@ -0,0 +1,5 @@
1
+ .d-input-currency-symbol {
2
+ --#{$prefix}input-currency-symbol-color: var(--#{$prefix}input-currency-component-symbol-color, #{$input-currency-symbol-color});
3
+
4
+ color: var(--#{$prefix}input-currency-symbol-color);
5
+ }