@opexa/portal-components 0.1.16 → 0.1.17

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,10 @@
1
+ export declare const SIGN_IN_LOADER_PHASE_LABEL = "Signing you in";
2
+ export interface LoaderProgress {
3
+ barPct: number;
4
+ pctShown: number;
5
+ phaseLabel: string;
6
+ }
7
+ /** Drives loader bar while `active` is true. */
8
+ export declare function useLoaderProgress(active: boolean, phaseLabel: string): LoaderProgress;
9
+ /** Drives loader bar while a sign-in mutation is active. */
10
+ export declare function useSignInLoaderProgress(active: boolean): LoaderProgress;
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { useEffect, useState } from 'react';
3
+ export const SIGN_IN_LOADER_PHASE_LABEL = 'Signing you in';
4
+ const PROGRESS_INTERVAL_MS = 240;
5
+ const INITIAL_BAR_PCT = 6;
6
+ const BAR_CAP = 97;
7
+ function clamp(n, min, max) {
8
+ return Math.min(max, Math.max(min, n));
9
+ }
10
+ function advanceBar(p) {
11
+ const cap = BAR_CAP;
12
+ if (p >= cap)
13
+ return p;
14
+ const delta = (cap - p) * 0.055 + 0.45;
15
+ return clamp(p + delta, 0, cap);
16
+ }
17
+ /** Drives loader bar while `active` is true. */
18
+ export function useLoaderProgress(active, phaseLabel) {
19
+ const [barPct, setBarPct] = useState(INITIAL_BAR_PCT);
20
+ useEffect(() => {
21
+ if (!active) {
22
+ setBarPct(INITIAL_BAR_PCT);
23
+ return;
24
+ }
25
+ setBarPct(INITIAL_BAR_PCT);
26
+ const progressId = setInterval(() => {
27
+ setBarPct((p) => advanceBar(p));
28
+ }, PROGRESS_INTERVAL_MS);
29
+ return () => clearInterval(progressId);
30
+ }, [active]);
31
+ return {
32
+ barPct,
33
+ pctShown: Math.min(99, Math.round(barPct)),
34
+ phaseLabel,
35
+ };
36
+ }
37
+ /** Drives loader bar while a sign-in mutation is active. */
38
+ export function useSignInLoaderProgress(active) {
39
+ return useLoaderProgress(active, SIGN_IN_LOADER_PHASE_LABEL);
40
+ }
@@ -0,0 +1,10 @@
1
+ import type { ImageProps } from 'next/image';
2
+ export interface MigrateProps {
3
+ /** Controls loader dialog visibility and progress animation. */
4
+ open: boolean;
5
+ /** Shown inside the loading spinner; omit for default user icon. */
6
+ logo?: ImageProps['src'];
7
+ /** Extra classes merged onto the inner card. */
8
+ cardClassName?: string;
9
+ }
10
+ export declare function Migrate(props: MigrateProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { MigrateLoadingDialog } from './MigrateLoadingDialog.js';
4
+ export function Migrate(props) {
5
+ return (_jsx(MigrateLoadingDialog, { open: props.open, active: props.open, logo: props.logo, variant: "migrate", cardClassName: props.cardClassName }));
6
+ }
@@ -0,0 +1,17 @@
1
+ import { type ImageProps } from 'next/image';
2
+ export declare const LOADER_HEADLINE = "Please wait while we finish setting things up for your account.";
3
+ export declare const LOADER_FOOTER = "You'll be redirected automatically once everything is ready.";
4
+ export declare const MIGRATE_LOADER_PHASE_LABEL = "Setting things up";
5
+ export declare const MIGRATE_LOADER_TITLE = "Account migration";
6
+ export declare const SIGN_IN_LOADER_TITLE = "Signing in";
7
+ export interface MigrateInitializingProps {
8
+ title: string;
9
+ phaseLabel: string;
10
+ barPct: number;
11
+ pctShown: number;
12
+ /** Brand mark in the spinner; omit to show the default user icon. */
13
+ logo?: ImageProps['src'];
14
+ footerText?: string;
15
+ className?: string;
16
+ }
17
+ export declare function MigrateInitializing(props: MigrateInitializingProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import Image, {} from 'next/image';
4
+ import { User01Icon } from '../../icons/User01Icon.js';
5
+ import { mergeMigrateCardClassName } from './migrateCard.js';
6
+ export const LOADER_HEADLINE = 'Please wait while we finish setting things up for your account.';
7
+ export const LOADER_FOOTER = "You'll be redirected automatically once everything is ready.";
8
+ export const MIGRATE_LOADER_PHASE_LABEL = 'Setting things up';
9
+ export const MIGRATE_LOADER_TITLE = 'Account migration';
10
+ export const SIGN_IN_LOADER_TITLE = 'Signing in';
11
+ export function MigrateInitializing(props) {
12
+ const footerText = props.footerText ?? LOADER_FOOTER;
13
+ return (_jsx("div", { className: mergeMigrateCardClassName(props.className), children: _jsxs("div", { className: "flex flex-col items-stretch gap-5 px-0.5 py-1 sm:px-1", children: [_jsx("div", { className: "flex justify-center", children: _jsxs("div", { className: "relative h-20 w-20 shrink-0", "aria-hidden": true, children: [_jsx("div", { className: "absolute inset-0 animate-spin rounded-full border-4 border-bg-tertiary border-t-button-tertiary-fg [animation-duration:1s]" }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center text-button-tertiary-fg", children: props.logo ? (_jsx(Image, { src: props.logo, alt: "", width: 20, height: 20, className: "h-12 w-12 object-contain" })) : (_jsx(User01Icon, { className: "h-7 w-7", "aria-hidden": true })) })] }) }), _jsxs("div", { className: "flex w-full min-w-0 flex-col gap-1.5", children: [_jsx("h1", { className: "font-semibold text-text-primary-900 text-lg tracking-tight", children: props.title }), _jsx("p", { className: "min-w-0 max-w-full text-balance text-center text-sm text-text-secondary-700 leading-relaxed", children: LOADER_HEADLINE })] }), _jsxs("div", { className: "w-full min-w-0 space-y-1.5", children: [_jsxs("div", { className: "flex w-full min-w-0 items-center justify-between gap-3 text-text-tertiary-600 text-xs", children: [_jsx("span", { className: "min-w-0 truncate text-left", children: props.phaseLabel }), _jsxs("span", { className: "shrink-0 text-text-tertiary-600/90 tabular-nums", children: [props.pctShown, "%"] })] }), _jsx("div", { className: "h-2 w-full min-w-0 overflow-hidden rounded-full bg-bg-tertiary", children: _jsx("div", { className: "h-full rounded-full bg-button-primary-bg transition-[width] duration-1000 ease-[cubic-bezier(0.33,1,0.68,1)]", style: { width: `${props.barPct}%` } }) })] }), _jsx("p", { className: "min-w-0 max-w-full text-balance text-center text-text-tertiary-600/80 text-xs leading-relaxed", children: footerText })] }) }));
14
+ }
@@ -0,0 +1,18 @@
1
+ import type { ImageProps } from 'next/image';
2
+ export interface MigrateLoadingDialogProps {
3
+ /**
4
+ * When true, renders only `Dialog.Content` (for use inside an existing
5
+ * `Dialog.Root`, e.g. SignIn).
6
+ */
7
+ contentOnly?: boolean;
8
+ /** Controls dialog visibility when not `contentOnly`. */
9
+ open?: boolean;
10
+ /** Drives progress bar animation. */
11
+ active: boolean;
12
+ logo?: ImageProps['src'];
13
+ variant?: 'signIn' | 'migrate';
14
+ cardClassName?: string;
15
+ contentClassName?: string;
16
+ }
17
+ /** Loading dialog with spinner, static copy, and mutation-driven progress. */
18
+ export declare function MigrateLoadingDialog(props: MigrateLoadingDialogProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { useLoaderProgress, useSignInLoaderProgress, } from '../../client/hooks/signInLoaderProgress.js';
5
+ import { Dialog } from '../../ui/Dialog/index.js';
6
+ import { Portal } from '../../ui/Portal/index.js';
7
+ import { MIGRATE_LOADER_PHASE_LABEL, MIGRATE_LOADER_TITLE, MigrateInitializing, SIGN_IN_LOADER_TITLE, } from './MigrateInitializing.js';
8
+ function useVariantLoaderProgress(active, variant) {
9
+ const signInProgress = useSignInLoaderProgress(variant === 'signIn' ? active : false);
10
+ const migrateProgress = useLoaderProgress(variant === 'migrate' ? active : false, MIGRATE_LOADER_PHASE_LABEL);
11
+ return variant === 'signIn' ? signInProgress : migrateProgress;
12
+ }
13
+ function LoaderCard(props) {
14
+ const variant = props.variant ?? 'signIn';
15
+ const progress = useVariantLoaderProgress(props.active, variant);
16
+ const title = variant === 'signIn' ? SIGN_IN_LOADER_TITLE : MIGRATE_LOADER_TITLE;
17
+ return (_jsx(MigrateInitializing, { title: title, phaseLabel: progress.phaseLabel, barPct: progress.barPct, pctShown: progress.pctShown, logo: props.logo, className: props.cardClassName }));
18
+ }
19
+ /** Loading dialog with spinner, static copy, and mutation-driven progress. */
20
+ export function MigrateLoadingDialog(props) {
21
+ const content = (_jsx(Dialog.Content, { className: twMerge('relative mx-auto bg-transparent shadow-none lg:rounded-xl', props.contentClassName), children: _jsx(LoaderCard, { ...props }) }));
22
+ if (props.contentOnly) {
23
+ return content;
24
+ }
25
+ return (_jsx(Dialog.Root, { open: props.open, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { children: content })] }) }));
26
+ }
@@ -0,0 +1,4 @@
1
+ export * from './Migrate';
2
+ export * from './MigrateInitializing';
3
+ export * from './MigrateLoadingDialog';
4
+ export * from './migrateCard';
@@ -0,0 +1,4 @@
1
+ export * from './Migrate.js';
2
+ export * from './MigrateInitializing.js';
3
+ export * from './MigrateLoadingDialog.js';
4
+ export * from './migrateCard.js';
@@ -0,0 +1,7 @@
1
+ /** Shared shell for MigrateInitializing / MigrateLoadingDialog. */
2
+ export declare const migrateCardClassName = "box-border w-full min-w-0 max-w-full self-stretch rounded-2xl border border-border-primary bg-bg-primary-alt p-5 text-center shadow-black/20 shadow-lg sm:p-6 md:w-[30dvw] md:max-w-[30dvw] md:shrink-0 md:self-center";
3
+ /**
4
+ * Merges the default migrate card shell with optional classes (e.g. `Migrate`’s
5
+ * `cardClassName` or a subcomponent’s `className`).
6
+ */
7
+ export declare function mergeMigrateCardClassName(className?: string): string;
@@ -0,0 +1,10 @@
1
+ import { twMerge } from 'tailwind-merge';
2
+ /** Shared shell for MigrateInitializing / MigrateLoadingDialog. */
3
+ export const migrateCardClassName = 'box-border w-full min-w-0 max-w-full self-stretch rounded-2xl border border-border-primary bg-bg-primary-alt p-5 text-center shadow-black/20 shadow-lg sm:p-6 md:w-[30dvw] md:max-w-[30dvw] md:shrink-0 md:self-center';
4
+ /**
5
+ * Merges the default migrate card shell with optional classes (e.g. `Migrate`’s
6
+ * `cardClassName` or a subcomponent’s `className`).
7
+ */
8
+ export function mergeMigrateCardClassName(className) {
9
+ return twMerge(migrateCardClassName, className);
10
+ }
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useIsMutating } from '@tanstack/react-query';
3
4
  import Image, {} from 'next/image';
4
5
  import { twMerge } from 'tailwind-merge';
5
6
  import { useShallow } from 'zustand/shallow';
@@ -7,6 +8,8 @@ import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
7
8
  import { XIcon } from '../../icons/XIcon.js';
8
9
  import { Dialog } from '../../ui/Dialog/index.js';
9
10
  import { Portal } from '../../ui/Portal/index.js';
11
+ import { MigrateLoadingDialog } from '../Migrate/MigrateLoadingDialog.js';
12
+ import { getSignInMutationKey } from '../../utils/mutationKeys.js';
10
13
  import { SignInForm as CWSignInForm } from './CrazyWin/SignInForm.js';
11
14
  import { SignInForm as HBSignInForm } from './HappyBingo/SignInForm.js';
12
15
  import { SignInPropsProvider, SignInProvider } from './SignInContext.js';
@@ -19,11 +22,15 @@ export function SignIn(props) {
19
22
  termsAndConditions: ctx.termsAndConditions,
20
23
  responsibleGaming: ctx.responsibleGaming,
21
24
  })));
25
+ const mutating = useIsMutating({ mutationKey: getSignInMutationKey() }) > 0;
26
+ const showLoader = mutating &&
27
+ props.versionSession === 'Inplay' &&
28
+ signIn.type === 'NAME_AND_PASSWORD';
22
29
  return (_jsx(SignInPropsProvider, { value: props, children: _jsx(SignInProvider, { value: signIn, children: _jsx(Dialog.Root, { open: signInStore.open, onOpenChange: (details) => {
23
30
  signInStore.setOpen(details.open);
24
31
  }, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, onExitComplete: () => {
25
32
  // Reset checkbox state when dialog closes
26
33
  globalStore.termsAndConditions.setAccepted(false);
27
34
  globalStore.responsibleGaming.setAccepted(false);
28
- }, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { children: props.variant === 'crazywin' ? (_jsxs(Dialog.Content, { className: twMerge(`relative w-[20.6875rem] bg-transparent`, props.className?.root), children: [_jsxs("div", { children: [_jsx(Dialog.CloseTrigger, { className: "md:-right-5 absolute top-0 right-2 z-10 size-5.5 rounded-md bg-gradient-to-t from-[#FFE5AF] to-[#EAC467] p-0.5", children: _jsx(XIcon, { className: "h-4.5 w-4.5 text-[#6C5200]" }) }), _jsx(Image, { src: "https://assets.opexacms.atalos.io/hdQJS7VHEaDvb3ZtV", alt: "", width: 200, height: 100, className: "mx-auto h-auto w-[8rem] object-contain md:mt-10 md:w-[12rem]", draggable: false })] }), _jsx("div", { className: "rounded-[1.25em] border-white/10 bg-[radial-gradient(103.87%_100%_at_50.15%_0%,_#072b37_20.3%,_#051125_100%)] p-[1.25rem] shadow-[0_4px_14px_6px_rgba(0,0,0,0.6)] backdrop-blur-[25px]", children: _jsx(CWSignInForm, {}) }), _jsxs("div", { className: "mt-5 flex items-center justify-center gap-1 text-xs md:mt-10", children: [_jsx("span", { children: "Don't have an account?" }), _jsx("button", { type: "button", className: "font-semibold text-[#FFE595]", children: "Register Here" })] })] })) : props.variant === 'happybingo' ? (_jsxs(Dialog.Content, { className: twMerge('h-full w-full lg:mx-auto lg:grid lg:h-[50rem] lg:w-[55rem] lg:grid-cols-2', props.className?.root), style: { msOverflowStyle: 'none', scrollbarWidth: 'none' }, children: [_jsx("div", { className: "hidden h-full overflow-hidden rounded-l-xl lg:block", children: _jsx(Image, { src: "https://assets.opexacms.atalos.io/hd48QiKmacXs1XWnY", alt: "login banner", width: 1000, height: 1000, className: "h-full w-full", draggable: false }) }), _jsxs("div", { className: "relative flex min-h-full flex-col bg-white p-5 lg:rounded-r-xl lg:p-3xl dark:bg-[#0C111D]", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx(Image, { src: "https://assets.opexacms.atalos.io/hdKuiVnx6WePuJy6C", alt: "happy bingo logo", width: 433, height: 211, className: "mx-auto mb-xl h-auto w-[7.125rem]", draggable: false }), _jsx(HBSignInForm, {})] })] })) : (_jsxs(Dialog.Content, { className: twMerge('mx-auto h-full w-full items-start overflow-y-auto bg-bg-primary-alt p-3xl pb-4xl lg:h-auto lg:max-h-[80vh] lg:w-[400px] lg:rounded-xl', props.className?.root), style: { msOverflowStyle: 'none', scrollbarWidth: 'none' }, children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx(Image, { src: props.logo, alt: "", width: 200, height: 100, className: "mx-auto h-7.5 w-auto", draggable: false }), _jsx("div", { children: _jsx(SignInForm, {}) })] })) })] }) }) }) }));
35
+ }, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsxs(Dialog.Positioner, { children: [showLoader && (_jsx(MigrateLoadingDialog, { contentOnly: true, active: mutating, logo: props.logo, variant: "signIn" })), _jsx(Dialog.Content, { className: twMerge(showLoader ? 'hidden' : ''), children: props.variant === 'crazywin' ? (_jsxs("div", { className: twMerge(`relative w-[20.6875rem] bg-transparent`, props.className?.root), children: [_jsxs("div", { children: [_jsx(Dialog.CloseTrigger, { className: "md:-right-5 absolute top-0 right-2 z-10 size-5.5 rounded-md bg-gradient-to-t from-[#FFE5AF] to-[#EAC467] p-0.5", children: _jsx(XIcon, { className: "h-4.5 w-4.5 text-[#6C5200]" }) }), _jsx(Image, { src: "https://assets.opexacms.atalos.io/hdQJS7VHEaDvb3ZtV", alt: "", width: 200, height: 100, className: "mx-auto h-auto w-[8rem] object-contain md:mt-10 md:w-[12rem]", draggable: false })] }), _jsx("div", { className: "rounded-[1.25em] border-white/10 bg-[radial-gradient(103.87%_100%_at_50.15%_0%,_#072b37_20.3%,_#051125_100%)] p-[1.25rem] shadow-[0_4px_14px_6px_rgba(0,0,0,0.6)] backdrop-blur-[25px]", children: _jsx(CWSignInForm, {}) }), _jsxs("div", { className: "mt-5 flex items-center justify-center gap-1 text-xs md:mt-10", children: [_jsx("span", { children: "Don't have an account?" }), _jsx("button", { type: "button", className: "font-semibold text-[#FFE595]", children: "Register Here" })] })] })) : props.variant === 'happybingo' ? (_jsxs("div", { className: twMerge('relative h-full w-full lg:mx-auto lg:grid lg:h-[50rem] lg:w-[55rem] lg:grid-cols-2', props.className?.root), style: { msOverflowStyle: 'none', scrollbarWidth: 'none' }, children: [_jsx("div", { className: "hidden h-full overflow-hidden rounded-l-xl lg:block", children: _jsx(Image, { src: "https://assets.opexacms.atalos.io/hd48QiKmacXs1XWnY", alt: "login banner", width: 1000, height: 1000, className: "h-full w-full", draggable: false }) }), _jsxs("div", { className: "relative flex min-h-full flex-col bg-white p-5 lg:rounded-r-xl lg:p-3xl dark:bg-[#0C111D]", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx(Image, { src: "https://assets.opexacms.atalos.io/hdKuiVnx6WePuJy6C", alt: "happy bingo logo", width: 433, height: 211, className: "mx-auto mb-xl h-auto w-[7.125rem]", draggable: false }), _jsx(HBSignInForm, {})] })] })) : (_jsxs("div", { className: twMerge('relative mx-auto h-full w-full items-start overflow-y-auto bg-bg-primary-alt p-3xl pb-4xl lg:h-auto lg:max-h-[80vh] lg:w-[400px] lg:rounded-xl', props.className?.root), style: { msOverflowStyle: 'none', scrollbarWidth: 'none' }, children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx(Image, { src: props.logo, alt: "", width: 200, height: 100, className: "mx-auto h-7.5 w-auto", draggable: false }), _jsx("div", { children: _jsx(SignInForm, {}) })] })) })] })] }) }) }) }));
29
36
  }
@@ -2,7 +2,6 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import Image from 'next/image';
4
4
  import { useShallow } from 'zustand/shallow';
5
- import { useFeatureFlag } from '../../client/hooks/useFeatureFlag.js';
6
5
  import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
7
6
  import inplayLogo from '../../images/inplay-logo.png';
8
7
  import lightBg from '../../images/light-bg.png';
@@ -14,15 +13,12 @@ import { useAutoOpen, } from './hooks/useAutoOpen.js';
14
13
  import { useUpdateMobileFlow } from './hooks/useUpdateMobileFlow.js';
15
14
  export function UpdateMobilePhoneNumber({ shouldOnlyShow = 'MobileVerified', } = {}) {
16
15
  useAutoOpen(shouldOnlyShow);
17
- const featureFlag = useFeatureFlag();
18
16
  const globalStore = useGlobalStore(useShallow((ctx) => ({
19
17
  updateMobilePhoneNumber: ctx.updateMobilePhoneNumber,
20
18
  kyc: ctx.kyc,
21
19
  })));
22
20
  const { step, step1Form, step2Form, cooldown, formRef, mobileNumberParser, submitStep1, submitStep2, resend, goBackToStep1, } = useUpdateMobileFlow();
23
- const isOpen = globalStore.updateMobilePhoneNumber.open &&
24
- featureFlag.enabled &&
25
- !globalStore.kyc.open;
21
+ const isOpen = globalStore.updateMobilePhoneNumber.open && !globalStore.kyc.open;
26
22
  return (_jsx(Dialog.Root, { open: isOpen, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { className: "flex items-center", children: _jsxs(Dialog.Content, { className: "flex w-[375px] flex-col items-center space-y-4 rounded-xl bg-[#111827] p-6 text-center", style: {
27
23
  backgroundImage: `url(${lightBg.src})`,
28
24
  }, children: [_jsx(Image, { src: inplayLogo, alt: "inplay logo", width: 82, height: 34, className: "h-auto w-[82px]" }), _jsxs("div", { children: [step === 1 && (_jsx(Step1MobileNumberForm, { step1Form: step1Form, submitStep1: submitStep1 })), step === 2 && (_jsx(Step2VerificationForm, { step1Form: step1Form, step2Form: step2Form, cooldown: cooldown, formRef: formRef, mobileNumberParser: mobileNumberParser, submitStep2: submitStep2, resend: resend, goBackToStep1: goBackToStep1 }))] })] }) })] }) }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opexa/portal-components",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "exports": {
5
5
  "./ui/*": {
6
6
  "types": "./dist/ui/*/index.d.ts",