@tutti-os/commerce 0.0.216 → 0.0.217
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.
- package/dist/react/index.js +11 -4
- package/dist/react/index.js.map +1 -1
- package/package.json +2 -2
package/dist/react/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
BillingIcon,
|
|
10
10
|
CreditsIcon,
|
|
11
11
|
LaunchIcon,
|
|
12
|
-
|
|
12
|
+
UserLinedIcon
|
|
13
13
|
} from "@tutti-os/ui-system";
|
|
14
14
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
15
|
function CommerceMenuContent({
|
|
@@ -73,9 +73,16 @@ function CommerceMenuContent({
|
|
|
73
73
|
disabled: !state.links.settingsUrl.trim(),
|
|
74
74
|
onClick: () => openExternal(state.links.settingsUrl),
|
|
75
75
|
children: [
|
|
76
|
-
/* @__PURE__ */ jsx(
|
|
76
|
+
/* @__PURE__ */ jsx(UserLinedIcon, { "aria-hidden": "true", size: 15 }),
|
|
77
77
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: labels.accountCenter }),
|
|
78
|
-
/* @__PURE__ */ jsx(
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
LaunchIcon,
|
|
80
|
+
{
|
|
81
|
+
"aria-hidden": "true",
|
|
82
|
+
className: "text-[var(--text-secondary)]",
|
|
83
|
+
size: 14
|
|
84
|
+
}
|
|
85
|
+
)
|
|
79
86
|
]
|
|
80
87
|
}
|
|
81
88
|
),
|
|
@@ -139,7 +146,7 @@ function MembershipBadge({
|
|
|
139
146
|
return /* @__PURE__ */ jsxs2(
|
|
140
147
|
"span",
|
|
141
148
|
{
|
|
142
|
-
className: `inline-flex max-w-full items-center gap-1 rounded-[5px]
|
|
149
|
+
className: `inline-flex max-w-full items-center gap-1 rounded-[5px] py-0.5 text-[11px] font-normal leading-3 text-[var(--text-secondary)] ${className}`,
|
|
143
150
|
"data-commerce-membership-badge": "true",
|
|
144
151
|
children: [
|
|
145
152
|
tierKey ? /* @__PURE__ */ jsx3(
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/CommerceMenuContent.tsx","../../src/react/MembershipBadge.tsx","../../src/react/MembershipTierIcon.tsx","../../src/react/RegistrationCreditsToast.tsx"],"sourcesContent":["import { useCallback } from \"react\";\nimport {\n BillingIcon,\n CreditsIcon,\n LaunchIcon,\n SettingsIcon\n} from \"@tutti-os/ui-system\";\nimport { resolveMembershipAction, type CommerceMenuState } from \"../index\";\n\nexport interface CommerceMenuLabels {\n member: string;\n upgradeMembership: string;\n rechargeCredits: string;\n viewCreditPlans: string;\n creditsBalance: string;\n accountCenter: string;\n loading: string;\n unavailable: string;\n dataUnavailable: string;\n}\n\nexport interface CommerceMenuContentProps {\n state: CommerceMenuState;\n labels: CommerceMenuLabels;\n}\n\nexport function CommerceMenuContent({\n state,\n labels\n}: CommerceMenuContentProps): React.JSX.Element {\n const creditsLabel =\n state.loading && !state.creditsLabel\n ? labels.loading\n : (state.creditsLabel ?? labels.unavailable);\n const openExternal = useCallback(\n (url: string) => {\n if (!url.trim()) {\n return;\n }\n try {\n const result = state.onOpenExternal(url);\n if (result) {\n void result.catch((error: unknown) => {\n state.onActionError?.(error);\n });\n }\n } catch (error) {\n state.onActionError?.(error);\n }\n },\n [state]\n );\n const membershipActionLabel = resolveMembershipActionLabel(state, labels);\n\n return (\n <div className=\"flex min-w-0 flex-col\" data-testid=\"commerce-menu-content\">\n <button\n type=\"button\"\n className=\"nodrag flex h-8 items-center gap-2 rounded-[6px] px-2 text-[13px] text-[var(--text-primary)] hover:bg-[var(--transparency-hover)] disabled:cursor-not-allowed disabled:opacity-50 [-webkit-app-region:no-drag]\"\n disabled={!state.links.planUrl.trim()}\n onClick={() => openExternal(state.links.planUrl)}\n >\n <BillingIcon aria-hidden=\"true\" size={15} />\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {labels.member}\n </span>\n <span className=\"shrink-0 text-[12px] text-[var(--tutti-purple)]\">\n {membershipActionLabel}\n </span>\n </button>\n <button\n type=\"button\"\n className=\"nodrag flex h-8 items-center gap-2 rounded-[6px] px-2 text-[13px] text-[var(--text-primary)] hover:bg-[var(--transparency-hover)] disabled:cursor-not-allowed disabled:opacity-50 [-webkit-app-region:no-drag]\"\n disabled={!state.links.usageUrl.trim()}\n onClick={() => openExternal(state.links.usageUrl)}\n >\n <CreditsIcon aria-hidden=\"true\" size={15} />\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {labels.creditsBalance}\n </span>\n <span className=\"truncate text-[var(--text-secondary)]\">\n {creditsLabel}\n </span>\n </button>\n <button\n type=\"button\"\n className=\"nodrag flex h-8 items-center gap-2 rounded-[6px] px-2 text-[13px] text-[var(--text-primary)] hover:bg-[var(--transparency-hover)] disabled:cursor-not-allowed disabled:opacity-50 [-webkit-app-region:no-drag]\"\n disabled={!state.links.settingsUrl.trim()}\n onClick={() => openExternal(state.links.settingsUrl)}\n >\n <SettingsIcon aria-hidden=\"true\" size={15} />\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {labels.accountCenter}\n </span>\n <LaunchIcon aria-hidden=\"true\" size={14} />\n </button>\n {state.dataUnavailable ? (\n <span className=\"px-2 py-1 text-[11px] leading-4 text-[var(--text-danger)]\">\n {labels.dataUnavailable}\n </span>\n ) : null}\n </div>\n );\n}\n\nfunction resolveMembershipActionLabel(\n state: CommerceMenuState,\n labels: Pick<\n CommerceMenuLabels,\n \"upgradeMembership\" | \"rechargeCredits\" | \"viewCreditPlans\"\n >\n): string {\n switch (resolveMembershipAction(state.membershipAccess)) {\n case \"upgrade-membership\":\n return labels.upgradeMembership;\n case \"recharge-credits\":\n return labels.rechargeCredits;\n case \"view-credit-plans\":\n return labels.viewCreditPlans;\n }\n}\n","import { BillingIcon } from \"@tutti-os/ui-system\";\nimport { MembershipTierIcon } from \"./MembershipTierIcon\";\n\nexport interface MembershipBadgeProps {\n label: string;\n tierKey?: string | null;\n className?: string;\n}\n\nexport function MembershipBadge({\n label,\n tierKey = null,\n className = \"\"\n}: MembershipBadgeProps): React.JSX.Element {\n return (\n <span\n className={`inline-flex max-w-full items-center gap-1 rounded-[5px] bg-[color-mix(in_srgb,var(--tutti-purple)_18%,transparent)] px-1.5 py-0.5 text-[11px] font-semibold leading-3 text-[var(--tutti-purple)] ${className}`}\n data-commerce-membership-badge=\"true\"\n >\n {tierKey ? (\n <MembershipTierIcon\n className=\"size-3.5 shrink-0 object-contain\"\n tierKey={tierKey}\n />\n ) : (\n <BillingIcon aria-hidden=\"true\" size={11} />\n )}\n <span className=\"min-w-0 truncate\">{label}</span>\n </span>\n );\n}\n","import freeIconUrl from \"@tutti-os/commerce/assets/star-free.png\";\nimport liteIconUrl from \"@tutti-os/commerce/assets/star-lite.png\";\nimport proIconUrl from \"@tutti-os/commerce/assets/star-pro.png\";\nimport ultraIconUrl from \"@tutti-os/commerce/assets/star-ultra.png\";\nimport {\n resolveMembershipTierVisual,\n type MembershipTierVisual\n} from \"../index\";\n\nconst ICON_URLS: Readonly<Record<MembershipTierVisual, string>> = {\n free: freeIconUrl,\n lite: liteIconUrl,\n pro: proIconUrl,\n ultra: ultraIconUrl\n};\n\nexport interface MembershipTierIconProps {\n tierKey: string | null | undefined;\n className?: string;\n}\n\nexport function MembershipTierIcon({\n tierKey,\n className = \"\"\n}: MembershipTierIconProps): React.JSX.Element | null {\n const visual = resolveMembershipTierVisual(tierKey);\n if (!visual) {\n return null;\n }\n return (\n <img\n alt=\"\"\n aria-hidden=\"true\"\n draggable={false}\n src={ICON_URLS[visual]}\n className={className}\n data-membership-tier-visual={visual}\n />\n );\n}\n","import { memo, useEffect } from \"react\";\nimport registrationCreditsBackgroundUrl from \"@tutti-os/commerce/assets/registration-credits-bg.png\";\nimport { CloseIcon, CreditsIcon } from \"@tutti-os/ui-system\";\nimport type { RegistrationCreditsToastState } from \"../index\";\n\nexport interface RegistrationCreditsToastLabels {\n title: string;\n creditsUnit: string;\n description: string;\n close: string;\n}\n\nexport interface RegistrationCreditsToastProps {\n toast: RegistrationCreditsToastState;\n labels: RegistrationCreditsToastLabels;\n}\n\nconst defaultAutoDismissMs = 120_000;\n\nexport const RegistrationCreditsToast = memo(function RegistrationCreditsToast({\n toast,\n labels\n}: RegistrationCreditsToastProps): React.JSX.Element | null {\n \"use memo\";\n useEffect(() => {\n if (!toast.visible) {\n return;\n }\n const timeout = window.setTimeout(\n toast.onDismiss,\n toast.autoDismissMs ?? defaultAutoDismissMs\n );\n return () => window.clearTimeout(timeout);\n }, [toast.autoDismissMs, toast.onDismiss, toast.visible]);\n\n if (!toast.visible) {\n return null;\n }\n\n return (\n <div\n className=\"nodrag relative mx-3 mb-1 w-[calc(100%-24px)] max-w-[calc(100%-24px)] overflow-hidden rounded-[14px] border border-[rgba(218,233,255,0.62)] p-2.5 pr-9 text-white shadow-[0_14px_28px_rgba(0,0,0,0.2),inset_0_0_0_1px_rgba(255,255,255,0.24)] [-webkit-app-region:no-drag]\"\n data-testid=\"commerce-registration-credits-toast\"\n role=\"status\"\n style={{\n backgroundImage: `linear-gradient(90deg, rgba(18, 60, 142, 0.08), rgba(20, 66, 160, 0.2) 58%, rgba(12, 32, 92, 0.34)), url(${JSON.stringify(\n registrationCreditsBackgroundUrl\n )})`,\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n backgroundSize: \"cover\"\n }}\n >\n <div className=\"pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/90 to-transparent\" />\n <div className=\"relative flex min-w-0 items-center gap-2.5\">\n <span className=\"grid h-10 w-10 shrink-0 place-items-center rounded-[12px] bg-[rgba(250,255,236,0.78)] text-emerald-400 shadow-[0_9px_18px_rgba(20,184,166,0.18),0_0_0_1px_rgba(255,255,255,0.5)_inset]\">\n <CreditsIcon aria-hidden=\"true\" size={23} />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-[12px] font-semibold leading-4 text-white\">\n {labels.title}\n </span>\n <span className=\"block truncate text-[20px] font-semibold leading-6 text-white\">\n +{toast.creditsLabel} {labels.creditsUnit}\n </span>\n <span className=\"block truncate text-[11px] font-medium leading-4 text-white/88\">\n {labels.description}\n </span>\n </span>\n </div>\n <button\n type=\"button\"\n aria-label={labels.close}\n className=\"nodrag absolute right-2.5 top-2.5 grid h-6 w-6 place-items-center rounded-[7px] text-white/85 hover:bg-white/18 hover:text-white [-webkit-app-region:no-drag]\"\n onClick={toast.onDismiss}\n >\n <CloseIcon aria-hidden=\"true\" size={16} />\n </button>\n </div>\n );\n});\n"],"mappings":"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","names":["BillingIcon","jsx","jsx","jsxs","BillingIcon","CreditsIcon","jsx","jsxs","RegistrationCreditsToast"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/CommerceMenuContent.tsx","../../src/react/MembershipBadge.tsx","../../src/react/MembershipTierIcon.tsx","../../src/react/RegistrationCreditsToast.tsx"],"sourcesContent":["import { useCallback } from \"react\";\nimport {\n BillingIcon,\n CreditsIcon,\n LaunchIcon,\n UserLinedIcon\n} from \"@tutti-os/ui-system\";\nimport { resolveMembershipAction, type CommerceMenuState } from \"../index\";\n\nexport interface CommerceMenuLabels {\n member: string;\n upgradeMembership: string;\n rechargeCredits: string;\n viewCreditPlans: string;\n creditsBalance: string;\n accountCenter: string;\n loading: string;\n unavailable: string;\n dataUnavailable: string;\n}\n\nexport interface CommerceMenuContentProps {\n state: CommerceMenuState;\n labels: CommerceMenuLabels;\n}\n\nexport function CommerceMenuContent({\n state,\n labels\n}: CommerceMenuContentProps): React.JSX.Element {\n const creditsLabel =\n state.loading && !state.creditsLabel\n ? labels.loading\n : (state.creditsLabel ?? labels.unavailable);\n const openExternal = useCallback(\n (url: string) => {\n if (!url.trim()) {\n return;\n }\n try {\n const result = state.onOpenExternal(url);\n if (result) {\n void result.catch((error: unknown) => {\n state.onActionError?.(error);\n });\n }\n } catch (error) {\n state.onActionError?.(error);\n }\n },\n [state]\n );\n const membershipActionLabel = resolveMembershipActionLabel(state, labels);\n\n return (\n <div className=\"flex min-w-0 flex-col\" data-testid=\"commerce-menu-content\">\n <button\n type=\"button\"\n className=\"nodrag flex h-8 items-center gap-2 rounded-[6px] px-2 text-[13px] text-[var(--text-primary)] hover:bg-[var(--transparency-hover)] disabled:cursor-not-allowed disabled:opacity-50 [-webkit-app-region:no-drag]\"\n disabled={!state.links.planUrl.trim()}\n onClick={() => openExternal(state.links.planUrl)}\n >\n <BillingIcon aria-hidden=\"true\" size={15} />\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {labels.member}\n </span>\n <span className=\"shrink-0 text-[12px] text-[var(--tutti-purple)]\">\n {membershipActionLabel}\n </span>\n </button>\n <button\n type=\"button\"\n className=\"nodrag flex h-8 items-center gap-2 rounded-[6px] px-2 text-[13px] text-[var(--text-primary)] hover:bg-[var(--transparency-hover)] disabled:cursor-not-allowed disabled:opacity-50 [-webkit-app-region:no-drag]\"\n disabled={!state.links.usageUrl.trim()}\n onClick={() => openExternal(state.links.usageUrl)}\n >\n <CreditsIcon aria-hidden=\"true\" size={15} />\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {labels.creditsBalance}\n </span>\n <span className=\"truncate text-[var(--text-secondary)]\">\n {creditsLabel}\n </span>\n </button>\n <button\n type=\"button\"\n className=\"nodrag flex h-8 items-center gap-2 rounded-[6px] px-2 text-[13px] text-[var(--text-primary)] hover:bg-[var(--transparency-hover)] disabled:cursor-not-allowed disabled:opacity-50 [-webkit-app-region:no-drag]\"\n disabled={!state.links.settingsUrl.trim()}\n onClick={() => openExternal(state.links.settingsUrl)}\n >\n <UserLinedIcon aria-hidden=\"true\" size={15} />\n <span className=\"min-w-0 flex-1 truncate text-left\">\n {labels.accountCenter}\n </span>\n <LaunchIcon\n aria-hidden=\"true\"\n className=\"text-[var(--text-secondary)]\"\n size={14}\n />\n </button>\n {state.dataUnavailable ? (\n <span className=\"px-2 py-1 text-[11px] leading-4 text-[var(--text-danger)]\">\n {labels.dataUnavailable}\n </span>\n ) : null}\n </div>\n );\n}\n\nfunction resolveMembershipActionLabel(\n state: CommerceMenuState,\n labels: Pick<\n CommerceMenuLabels,\n \"upgradeMembership\" | \"rechargeCredits\" | \"viewCreditPlans\"\n >\n): string {\n switch (resolveMembershipAction(state.membershipAccess)) {\n case \"upgrade-membership\":\n return labels.upgradeMembership;\n case \"recharge-credits\":\n return labels.rechargeCredits;\n case \"view-credit-plans\":\n return labels.viewCreditPlans;\n }\n}\n","import { BillingIcon } from \"@tutti-os/ui-system\";\nimport { MembershipTierIcon } from \"./MembershipTierIcon\";\n\nexport interface MembershipBadgeProps {\n label: string;\n tierKey?: string | null;\n className?: string;\n}\n\nexport function MembershipBadge({\n label,\n tierKey = null,\n className = \"\"\n}: MembershipBadgeProps): React.JSX.Element {\n return (\n <span\n className={`inline-flex max-w-full items-center gap-1 rounded-[5px] py-0.5 text-[11px] font-normal leading-3 text-[var(--text-secondary)] ${className}`}\n data-commerce-membership-badge=\"true\"\n >\n {tierKey ? (\n <MembershipTierIcon\n className=\"size-3.5 shrink-0 object-contain\"\n tierKey={tierKey}\n />\n ) : (\n <BillingIcon aria-hidden=\"true\" size={11} />\n )}\n <span className=\"min-w-0 truncate\">{label}</span>\n </span>\n );\n}\n","import freeIconUrl from \"@tutti-os/commerce/assets/star-free.png\";\nimport liteIconUrl from \"@tutti-os/commerce/assets/star-lite.png\";\nimport proIconUrl from \"@tutti-os/commerce/assets/star-pro.png\";\nimport ultraIconUrl from \"@tutti-os/commerce/assets/star-ultra.png\";\nimport {\n resolveMembershipTierVisual,\n type MembershipTierVisual\n} from \"../index\";\n\nconst ICON_URLS: Readonly<Record<MembershipTierVisual, string>> = {\n free: freeIconUrl,\n lite: liteIconUrl,\n pro: proIconUrl,\n ultra: ultraIconUrl\n};\n\nexport interface MembershipTierIconProps {\n tierKey: string | null | undefined;\n className?: string;\n}\n\nexport function MembershipTierIcon({\n tierKey,\n className = \"\"\n}: MembershipTierIconProps): React.JSX.Element | null {\n const visual = resolveMembershipTierVisual(tierKey);\n if (!visual) {\n return null;\n }\n return (\n <img\n alt=\"\"\n aria-hidden=\"true\"\n draggable={false}\n src={ICON_URLS[visual]}\n className={className}\n data-membership-tier-visual={visual}\n />\n );\n}\n","import { memo, useEffect } from \"react\";\nimport registrationCreditsBackgroundUrl from \"@tutti-os/commerce/assets/registration-credits-bg.png\";\nimport { CloseIcon, CreditsIcon } from \"@tutti-os/ui-system\";\nimport type { RegistrationCreditsToastState } from \"../index\";\n\nexport interface RegistrationCreditsToastLabels {\n title: string;\n creditsUnit: string;\n description: string;\n close: string;\n}\n\nexport interface RegistrationCreditsToastProps {\n toast: RegistrationCreditsToastState;\n labels: RegistrationCreditsToastLabels;\n}\n\nconst defaultAutoDismissMs = 120_000;\n\nexport const RegistrationCreditsToast = memo(function RegistrationCreditsToast({\n toast,\n labels\n}: RegistrationCreditsToastProps): React.JSX.Element | null {\n \"use memo\";\n useEffect(() => {\n if (!toast.visible) {\n return;\n }\n const timeout = window.setTimeout(\n toast.onDismiss,\n toast.autoDismissMs ?? defaultAutoDismissMs\n );\n return () => window.clearTimeout(timeout);\n }, [toast.autoDismissMs, toast.onDismiss, toast.visible]);\n\n if (!toast.visible) {\n return null;\n }\n\n return (\n <div\n className=\"nodrag relative mx-3 mb-1 w-[calc(100%-24px)] max-w-[calc(100%-24px)] overflow-hidden rounded-[14px] border border-[rgba(218,233,255,0.62)] p-2.5 pr-9 text-white shadow-[0_14px_28px_rgba(0,0,0,0.2),inset_0_0_0_1px_rgba(255,255,255,0.24)] [-webkit-app-region:no-drag]\"\n data-testid=\"commerce-registration-credits-toast\"\n role=\"status\"\n style={{\n backgroundImage: `linear-gradient(90deg, rgba(18, 60, 142, 0.08), rgba(20, 66, 160, 0.2) 58%, rgba(12, 32, 92, 0.34)), url(${JSON.stringify(\n registrationCreditsBackgroundUrl\n )})`,\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n backgroundSize: \"cover\"\n }}\n >\n <div className=\"pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/90 to-transparent\" />\n <div className=\"relative flex min-w-0 items-center gap-2.5\">\n <span className=\"grid h-10 w-10 shrink-0 place-items-center rounded-[12px] bg-[rgba(250,255,236,0.78)] text-emerald-400 shadow-[0_9px_18px_rgba(20,184,166,0.18),0_0_0_1px_rgba(255,255,255,0.5)_inset]\">\n <CreditsIcon aria-hidden=\"true\" size={23} />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate text-[12px] font-semibold leading-4 text-white\">\n {labels.title}\n </span>\n <span className=\"block truncate text-[20px] font-semibold leading-6 text-white\">\n +{toast.creditsLabel} {labels.creditsUnit}\n </span>\n <span className=\"block truncate text-[11px] font-medium leading-4 text-white/88\">\n {labels.description}\n </span>\n </span>\n </div>\n <button\n type=\"button\"\n aria-label={labels.close}\n className=\"nodrag absolute right-2.5 top-2.5 grid h-6 w-6 place-items-center rounded-[7px] text-white/85 hover:bg-white/18 hover:text-white [-webkit-app-region:no-drag]\"\n onClick={toast.onDismiss}\n >\n <CloseIcon aria-hidden=\"true\" size={16} />\n </button>\n </div>\n );\n});\n"],"mappings":";;;;;;AAAA,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAkDD,SAME,KANF;AA9BC,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAAgD;AAC9C,QAAM,eACJ,MAAM,WAAW,CAAC,MAAM,eACpB,OAAO,UACN,MAAM,gBAAgB,OAAO;AACpC,QAAM,eAAe;AAAA,IACnB,CAAC,QAAgB;AACf,UAAI,CAAC,IAAI,KAAK,GAAG;AACf;AAAA,MACF;AACA,UAAI;AACF,cAAM,SAAS,MAAM,eAAe,GAAG;AACvC,YAAI,QAAQ;AACV,eAAK,OAAO,MAAM,CAAC,UAAmB;AACpC,kBAAM,gBAAgB,KAAK;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF,SAAS,OAAO;AACd,cAAM,gBAAgB,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,CAAC,KAAK;AAAA,EACR;AACA,QAAM,wBAAwB,6BAA6B,OAAO,MAAM;AAExE,SACE,qBAAC,SAAI,WAAU,yBAAwB,eAAY,yBACjD;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,UAAU,CAAC,MAAM,MAAM,QAAQ,KAAK;AAAA,QACpC,SAAS,MAAM,aAAa,MAAM,MAAM,OAAO;AAAA,QAE/C;AAAA,8BAAC,eAAY,eAAY,QAAO,MAAM,IAAI;AAAA,UAC1C,oBAAC,UAAK,WAAU,qCACb,iBAAO,QACV;AAAA,UACA,oBAAC,UAAK,WAAU,mDACb,iCACH;AAAA;AAAA;AAAA,IACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,UAAU,CAAC,MAAM,MAAM,SAAS,KAAK;AAAA,QACrC,SAAS,MAAM,aAAa,MAAM,MAAM,QAAQ;AAAA,QAEhD;AAAA,8BAAC,eAAY,eAAY,QAAO,MAAM,IAAI;AAAA,UAC1C,oBAAC,UAAK,WAAU,qCACb,iBAAO,gBACV;AAAA,UACA,oBAAC,UAAK,WAAU,yCACb,wBACH;AAAA;AAAA;AAAA,IACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,UAAU,CAAC,MAAM,MAAM,YAAY,KAAK;AAAA,QACxC,SAAS,MAAM,aAAa,MAAM,MAAM,WAAW;AAAA,QAEnD;AAAA,8BAAC,iBAAc,eAAY,QAAO,MAAM,IAAI;AAAA,UAC5C,oBAAC,UAAK,WAAU,qCACb,iBAAO,eACV;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,eAAY;AAAA,cACZ,WAAU;AAAA,cACV,MAAM;AAAA;AAAA,UACR;AAAA;AAAA;AAAA,IACF;AAAA,IACC,MAAM,kBACL,oBAAC,UAAK,WAAU,6DACb,iBAAO,iBACV,IACE;AAAA,KACN;AAEJ;AAEA,SAAS,6BACP,OACA,QAIQ;AACR,UAAQ,wBAAwB,MAAM,gBAAgB,GAAG;AAAA,IACvD,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO;AAAA,EAClB;AACF;;;AC5HA,SAAS,eAAAA,oBAAmB;;;ACA5B,OAAO,iBAAiB;AACxB,OAAO,iBAAiB;AACxB,OAAO,gBAAgB;AACvB,OAAO,kBAAkB;AA2BrB,gBAAAC,YAAA;AArBJ,IAAM,YAA4D;AAAA,EAChE,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AACT;AAOO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,YAAY;AACd,GAAsD;AACpD,QAAM,SAAS,4BAA4B,OAAO;AAClD,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,KAAI;AAAA,MACJ,eAAY;AAAA,MACZ,WAAW;AAAA,MACX,KAAK,UAAU,MAAM;AAAA,MACrB;AAAA,MACA,+BAA6B;AAAA;AAAA,EAC/B;AAEJ;;;ADxBI,SAKI,OAAAC,MALJ,QAAAC,aAAA;AANG,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,UAAU;AAAA,EACV,YAAY;AACd,GAA4C;AAC1C,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,iIAAiI,SAAS;AAAA,MACrJ,kCAA+B;AAAA,MAE9B;AAAA,kBACC,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV;AAAA;AAAA,QACF,IAEA,gBAAAA,KAACE,cAAA,EAAY,eAAY,QAAO,MAAM,IAAI;AAAA,QAE5C,gBAAAF,KAAC,UAAK,WAAU,oBAAoB,iBAAM;AAAA;AAAA;AAAA,EAC5C;AAEJ;;;AE9BA,SAAS,MAAM,iBAAiB;AAChC,OAAO,sCAAsC;AAC7C,SAAS,WAAW,eAAAG,oBAAmB;AAmDjC,gBAAAC,MASI,QAAAC,aATJ;AApCN,IAAM,uBAAuB;AAEtB,IAAM,2BAA2B,KAAK,SAASC,0BAAyB;AAAA,EAC7E;AAAA,EACA;AACF,GAA4D;AAC1D;AACA,YAAU,MAAM;AACd,QAAI,CAAC,MAAM,SAAS;AAClB;AAAA,IACF;AACA,UAAM,UAAU,OAAO;AAAA,MACrB,MAAM;AAAA,MACN,MAAM,iBAAiB;AAAA,IACzB;AACA,WAAO,MAAM,OAAO,aAAa,OAAO;AAAA,EAC1C,GAAG,CAAC,MAAM,eAAe,MAAM,WAAW,MAAM,OAAO,CAAC;AAExD,MAAI,CAAC,MAAM,SAAS;AAClB,WAAO;AAAA,EACT;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAY;AAAA,MACZ,MAAK;AAAA,MACL,OAAO;AAAA,QACL,iBAAiB,4GAA4G,KAAK;AAAA,UAChI;AAAA,QACF,CAAC;AAAA,QACD,oBAAoB;AAAA,QACpB,kBAAkB;AAAA,QAClB,gBAAgB;AAAA,MAClB;AAAA,MAEA;AAAA,wBAAAD,KAAC,SAAI,WAAU,mHAAkH;AAAA,QACjI,gBAAAC,MAAC,SAAI,WAAU,8CACb;AAAA,0BAAAD,KAAC,UAAK,WAAU,0LACd,0BAAAA,KAACD,cAAA,EAAY,eAAY,QAAO,MAAM,IAAI,GAC5C;AAAA,UACA,gBAAAE,MAAC,UAAK,WAAU,kBACd;AAAA,4BAAAD,KAAC,UAAK,WAAU,iEACb,iBAAO,OACV;AAAA,YACA,gBAAAC,MAAC,UAAK,WAAU,iEAAgE;AAAA;AAAA,cAC5E,MAAM;AAAA,cAAa;AAAA,cAAE,OAAO;AAAA,eAChC;AAAA,YACA,gBAAAD,KAAC,UAAK,WAAU,kEACb,iBAAO,aACV;AAAA,aACF;AAAA,WACF;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAY,OAAO;AAAA,YACnB,WAAU;AAAA,YACV,SAAS,MAAM;AAAA,YAEf,0BAAAA,KAAC,aAAU,eAAY,QAAO,MAAM,IAAI;AAAA;AAAA,QAC1C;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;","names":["BillingIcon","jsx","jsx","jsxs","BillingIcon","CreditsIcon","jsx","jsxs","RegistrationCreditsToast"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutti-os/commerce",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.217",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"directory": "packages/commerce/web"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@tutti-os/ui-system": "0.0.
|
|
57
|
+
"@tutti-os/ui-system": "0.0.217"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@testing-library/jest-dom": "^6.9.1",
|