@fairmint/ui 0.2.12 → 0.2.14
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/components/ErrorFallback/ErrorFallback.d.ts.map +1 -1
- package/dist/components/FairmintProvider/FairmintProvider.d.ts.map +1 -1
- package/dist/components/form/FormField.d.ts.map +1 -1
- package/dist/components/form/PhoneField.d.ts +31 -2
- package/dist/components/form/PhoneField.d.ts.map +1 -1
- package/dist/components/generic/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/components/generic/ErrorPage/ErrorPage.d.ts +21 -0
- package/dist/components/generic/ErrorPage/ErrorPage.d.ts.map +1 -0
- package/dist/components/generic/ListRow/ListRow.d.ts.map +1 -1
- package/dist/components/generic/StatCard/StatCard.d.ts.map +1 -1
- package/dist/components/layout/PageHeader/PageHeader.d.ts.map +1 -1
- package/dist/components/specific/InvestorProfileCard/InvestorProfileCard.d.ts +5 -1
- package/dist/components/specific/InvestorProfileCard/InvestorProfileCard.d.ts.map +1 -1
- package/dist/fairmint-ui.cjs +375 -132
- package/dist/fairmint-ui.cjs.map +1 -1
- package/dist/fairmint-ui.js +375 -132
- package/dist/fairmint-ui.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/theme/index.d.ts +205 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/fairmint-ui.js
CHANGED
|
@@ -26802,110 +26802,6 @@ const AVATAR_PALETTE = [
|
|
|
26802
26802
|
colors.accent2,
|
|
26803
26803
|
colors.accent3
|
|
26804
26804
|
];
|
|
26805
|
-
const ActionIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(ActionIcon$1, { color: colors.primary, variant: "subtle", ...props, ref }));
|
|
26806
|
-
ActionIcon.displayName = "ActionIcon";
|
|
26807
|
-
function Alert(props) {
|
|
26808
|
-
return /* @__PURE__ */ jsx(Alert$1, { ...props });
|
|
26809
|
-
}
|
|
26810
|
-
const Avatar = forwardRef((props, ref) => /* @__PURE__ */ jsx(Avatar$1, { radius: "md", color: colors.primary, ...props, ref }));
|
|
26811
|
-
Avatar.displayName = "Avatar";
|
|
26812
|
-
const Badge = forwardRef((props, ref) => /* @__PURE__ */ jsx(Badge$1, { variant: "light", ...props, ref }));
|
|
26813
|
-
Badge.displayName = "Badge";
|
|
26814
|
-
const Button = forwardRef((props, ref) => /* @__PURE__ */ jsx(Button$1, { color: colors.primary, ...props, ref }));
|
|
26815
|
-
Button.displayName = "Button";
|
|
26816
|
-
const Card = forwardRef((props, ref) => /* @__PURE__ */ jsx(Card$1, { padding: "lg", radius: "xl", withBorder: true, ...props, ref }));
|
|
26817
|
-
Card.displayName = "Card";
|
|
26818
|
-
const Checkbox = forwardRef((props, ref) => /* @__PURE__ */ jsx(Checkbox$1, { color: colors.primary, ...props, ref }));
|
|
26819
|
-
Checkbox.displayName = "Checkbox";
|
|
26820
|
-
function Drawer(props) {
|
|
26821
|
-
return /* @__PURE__ */ jsx(Drawer$1, { position: "right", size: "lg", p: "lg", ...props });
|
|
26822
|
-
}
|
|
26823
|
-
function Loader(props) {
|
|
26824
|
-
return /* @__PURE__ */ jsx(Loader$1, { ...props });
|
|
26825
|
-
}
|
|
26826
|
-
function MenuBase(props) {
|
|
26827
|
-
return /* @__PURE__ */ jsx(Menu$1, { shadow: "md", ...props });
|
|
26828
|
-
}
|
|
26829
|
-
const Menu = Object.assign(MenuBase, {
|
|
26830
|
-
Target: Menu$1.Target,
|
|
26831
|
-
Dropdown: Menu$1.Dropdown,
|
|
26832
|
-
Item: Menu$1.Item,
|
|
26833
|
-
Label: Menu$1.Label,
|
|
26834
|
-
Divider: Menu$1.Divider
|
|
26835
|
-
});
|
|
26836
|
-
function Modal(props) {
|
|
26837
|
-
return /* @__PURE__ */ jsx(Modal$1, { centered: true, radius: "lg", ...props });
|
|
26838
|
-
}
|
|
26839
|
-
const PasswordInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(PasswordInput$1, { size: "md", ...props, ref }));
|
|
26840
|
-
PasswordInput.displayName = "PasswordInput";
|
|
26841
|
-
const Select = forwardRef((props, ref) => /* @__PURE__ */ jsx(Select$1, { size: "md", ...props, ref }));
|
|
26842
|
-
Select.displayName = "Select";
|
|
26843
|
-
function Skeleton(props) {
|
|
26844
|
-
return /* @__PURE__ */ jsx(Skeleton$1, { ...props });
|
|
26845
|
-
}
|
|
26846
|
-
const Switch = forwardRef((props, ref) => /* @__PURE__ */ jsx(Switch$1, { color: colors.primary, ...props, ref }));
|
|
26847
|
-
Switch.displayName = "Switch";
|
|
26848
|
-
function TableBase(props) {
|
|
26849
|
-
return /* @__PURE__ */ jsx(Table$1, { ...props });
|
|
26850
|
-
}
|
|
26851
|
-
const Table = Object.assign(TableBase, {
|
|
26852
|
-
Thead: Table$1.Thead,
|
|
26853
|
-
Tbody: Table$1.Tbody,
|
|
26854
|
-
Tr: Table$1.Tr,
|
|
26855
|
-
Th: Table$1.Th,
|
|
26856
|
-
Td: Table$1.Td,
|
|
26857
|
-
Tfoot: Table$1.Tfoot,
|
|
26858
|
-
Caption: Table$1.Caption
|
|
26859
|
-
});
|
|
26860
|
-
function TabsBase(props) {
|
|
26861
|
-
return /* @__PURE__ */ jsx(Tabs$1, { color: colors.primary, ...props });
|
|
26862
|
-
}
|
|
26863
|
-
const Tabs = Object.assign(TabsBase, {
|
|
26864
|
-
List: Tabs$1.List,
|
|
26865
|
-
Tab: Tabs$1.Tab,
|
|
26866
|
-
Panel: Tabs$1.Panel
|
|
26867
|
-
});
|
|
26868
|
-
const TextInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(TextInput$1, { size: "md", ...props, ref }));
|
|
26869
|
-
TextInput.displayName = "TextInput";
|
|
26870
|
-
function Tooltip(props) {
|
|
26871
|
-
return /* @__PURE__ */ jsx(Tooltip$1, { ...props });
|
|
26872
|
-
}
|
|
26873
|
-
function ErrorFallback({
|
|
26874
|
-
title = "Something went wrong",
|
|
26875
|
-
description = "We've been notified and are working on a fix.",
|
|
26876
|
-
onAction,
|
|
26877
|
-
actionLabel = "Reload Page",
|
|
26878
|
-
error: error2
|
|
26879
|
-
}) {
|
|
26880
|
-
if (error2 !== void 0) {
|
|
26881
|
-
console.error("[ErrorFallback]", error2);
|
|
26882
|
-
}
|
|
26883
|
-
const handleAction = onAction ?? (() => window.location.reload());
|
|
26884
|
-
return /* @__PURE__ */ jsx(Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "md", children: [
|
|
26885
|
-
/* @__PURE__ */ jsx(Title, { order: 2, children: title }),
|
|
26886
|
-
/* @__PURE__ */ jsx(Text, { c: "dimmed", children: description }),
|
|
26887
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleAction, children: actionLabel })
|
|
26888
|
-
] }) });
|
|
26889
|
-
}
|
|
26890
|
-
function FairmintLogo({
|
|
26891
|
-
src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
|
|
26892
|
-
width = 140,
|
|
26893
|
-
height = 30,
|
|
26894
|
-
className,
|
|
26895
|
-
alt = "Fairmint"
|
|
26896
|
-
}) {
|
|
26897
|
-
return /* @__PURE__ */ jsx(
|
|
26898
|
-
"img",
|
|
26899
|
-
{
|
|
26900
|
-
src,
|
|
26901
|
-
alt,
|
|
26902
|
-
width,
|
|
26903
|
-
height,
|
|
26904
|
-
className,
|
|
26905
|
-
style: { objectFit: "contain" }
|
|
26906
|
-
}
|
|
26907
|
-
);
|
|
26908
|
-
}
|
|
26909
26805
|
const radii = {
|
|
26910
26806
|
xs: "0.25rem",
|
|
26911
26807
|
sm: "0.375rem",
|
|
@@ -27009,12 +26905,16 @@ const info = [
|
|
|
27009
26905
|
"#155B75",
|
|
27010
26906
|
"#164C63"
|
|
27011
26907
|
];
|
|
26908
|
+
const typography = {
|
|
26909
|
+
fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"',
|
|
26910
|
+
headingFontFamily: '"Plus Jakarta Sans", sans-serif'
|
|
26911
|
+
};
|
|
27012
26912
|
const theme = createTheme({
|
|
27013
26913
|
primaryColor: "indigo",
|
|
27014
26914
|
colors: { indigo, gray: neutral, fairmintBlue, fairmintPurple, success, warning, error, info },
|
|
27015
|
-
fontFamily:
|
|
26915
|
+
fontFamily: typography.fontFamily,
|
|
27016
26916
|
headings: {
|
|
27017
|
-
fontFamily:
|
|
26917
|
+
fontFamily: typography.headingFontFamily,
|
|
27018
26918
|
fontWeight: "700"
|
|
27019
26919
|
},
|
|
27020
26920
|
radius: radii,
|
|
@@ -27064,6 +26964,49 @@ const theme = createTheme({
|
|
|
27064
26964
|
}
|
|
27065
26965
|
}
|
|
27066
26966
|
});
|
|
26967
|
+
const fairmintCssVariables = () => ({
|
|
26968
|
+
variables: {
|
|
26969
|
+
"--fairmint-font-headings": typography.headingFontFamily,
|
|
26970
|
+
"--fairmint-font-body": typography.fontFamily
|
|
26971
|
+
},
|
|
26972
|
+
light: {
|
|
26973
|
+
/** Large decorative background text on error/empty pages. */
|
|
26974
|
+
"--fairmint-watermark-color": neutral[1],
|
|
26975
|
+
/** Supporting / muted text (subtitles, secondary labels). Replaces c="dimmed" and neutral.5 */
|
|
26976
|
+
"--fairmint-color-text-secondary": neutral[5],
|
|
26977
|
+
/** Faint metadata text (timestamps, tertiary labels). Replaces neutral.4 */
|
|
26978
|
+
"--fairmint-color-text-tertiary": neutral[4],
|
|
26979
|
+
/** Background tint for selected / active rows. Replaces primary.0 */
|
|
26980
|
+
"--fairmint-color-surface-selected": indigo[0]
|
|
26981
|
+
},
|
|
26982
|
+
dark: {
|
|
26983
|
+
"--fairmint-watermark-color": neutral[7],
|
|
26984
|
+
"--fairmint-color-text-secondary": neutral[4],
|
|
26985
|
+
"--fairmint-color-text-tertiary": neutral[5],
|
|
26986
|
+
"--fairmint-color-surface-selected": indigo[9]
|
|
26987
|
+
}
|
|
26988
|
+
});
|
|
26989
|
+
const fairmintVars = {
|
|
26990
|
+
/** Secondary / muted text — subtitles, supporting labels. Adapts to color scheme. */
|
|
26991
|
+
colorTextSecondary: `var(--fairmint-color-text-secondary, ${neutral[5]})`,
|
|
26992
|
+
/** Tertiary / faint text — timestamps, metadata. Adapts to color scheme. */
|
|
26993
|
+
colorTextTertiary: `var(--fairmint-color-text-tertiary, ${neutral[4]})`,
|
|
26994
|
+
/** Background tint for selected / active rows. Adapts to color scheme. */
|
|
26995
|
+
colorSurfaceSelected: `var(--fairmint-color-surface-selected, ${indigo[0]})`,
|
|
26996
|
+
/** Large decorative watermark on error/empty pages. Adapts to color scheme. */
|
|
26997
|
+
watermarkColor: `var(--fairmint-watermark-color, ${neutral[1]})`,
|
|
26998
|
+
/** Heading font family (Plus Jakarta Sans). */
|
|
26999
|
+
fontHeadings: `var(--fairmint-font-headings, ${typography.headingFontFamily})`,
|
|
27000
|
+
/** Body font family (Inter). */
|
|
27001
|
+
fontBody: `var(--fairmint-font-body, ${typography.fontFamily})`
|
|
27002
|
+
};
|
|
27003
|
+
function createFairmintMantineProviderProps(colorScheme = "light") {
|
|
27004
|
+
return {
|
|
27005
|
+
theme,
|
|
27006
|
+
cssVariablesResolver: fairmintCssVariables,
|
|
27007
|
+
defaultColorScheme: colorScheme
|
|
27008
|
+
};
|
|
27009
|
+
}
|
|
27067
27010
|
const brandColors = {
|
|
27068
27011
|
blue: "#0A4EFB",
|
|
27069
27012
|
purple: "#9E03FF",
|
|
@@ -27088,15 +27031,127 @@ const semanticColors = {
|
|
|
27088
27031
|
error: "#F04438",
|
|
27089
27032
|
info: "#06AED4"
|
|
27090
27033
|
};
|
|
27034
|
+
const ActionIcon = forwardRef((props, ref) => /* @__PURE__ */ jsx(ActionIcon$1, { color: colors.primary, variant: "subtle", ...props, ref }));
|
|
27035
|
+
ActionIcon.displayName = "ActionIcon";
|
|
27036
|
+
function Alert(props) {
|
|
27037
|
+
return /* @__PURE__ */ jsx(Alert$1, { ...props });
|
|
27038
|
+
}
|
|
27039
|
+
const Avatar = forwardRef((props, ref) => /* @__PURE__ */ jsx(Avatar$1, { radius: "md", color: colors.primary, ...props, ref }));
|
|
27040
|
+
Avatar.displayName = "Avatar";
|
|
27041
|
+
const Badge = forwardRef((props, ref) => /* @__PURE__ */ jsx(Badge$1, { variant: "light", ...props, ref }));
|
|
27042
|
+
Badge.displayName = "Badge";
|
|
27043
|
+
const Button = forwardRef((props, ref) => /* @__PURE__ */ jsx(Button$1, { color: colors.primary, ...props, ref }));
|
|
27044
|
+
Button.displayName = "Button";
|
|
27045
|
+
const Card = forwardRef((props, ref) => /* @__PURE__ */ jsx(Card$1, { padding: "lg", radius: "xl", withBorder: true, ...props, ref }));
|
|
27046
|
+
Card.displayName = "Card";
|
|
27047
|
+
const Checkbox = forwardRef((props, ref) => /* @__PURE__ */ jsx(Checkbox$1, { color: colors.primary, ...props, ref }));
|
|
27048
|
+
Checkbox.displayName = "Checkbox";
|
|
27049
|
+
function Drawer(props) {
|
|
27050
|
+
return /* @__PURE__ */ jsx(Drawer$1, { position: "right", size: "lg", p: "lg", ...props });
|
|
27051
|
+
}
|
|
27052
|
+
function Loader(props) {
|
|
27053
|
+
return /* @__PURE__ */ jsx(Loader$1, { ...props });
|
|
27054
|
+
}
|
|
27055
|
+
function MenuBase(props) {
|
|
27056
|
+
return /* @__PURE__ */ jsx(Menu$1, { shadow: "md", ...props });
|
|
27057
|
+
}
|
|
27058
|
+
const Menu = Object.assign(MenuBase, {
|
|
27059
|
+
Target: Menu$1.Target,
|
|
27060
|
+
Dropdown: Menu$1.Dropdown,
|
|
27061
|
+
Item: Menu$1.Item,
|
|
27062
|
+
Label: Menu$1.Label,
|
|
27063
|
+
Divider: Menu$1.Divider
|
|
27064
|
+
});
|
|
27065
|
+
function Modal(props) {
|
|
27066
|
+
return /* @__PURE__ */ jsx(Modal$1, { centered: true, radius: "lg", ...props });
|
|
27067
|
+
}
|
|
27068
|
+
const PasswordInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(PasswordInput$1, { size: "md", ...props, ref }));
|
|
27069
|
+
PasswordInput.displayName = "PasswordInput";
|
|
27070
|
+
const Select = forwardRef((props, ref) => /* @__PURE__ */ jsx(Select$1, { size: "md", ...props, ref }));
|
|
27071
|
+
Select.displayName = "Select";
|
|
27072
|
+
function Skeleton(props) {
|
|
27073
|
+
return /* @__PURE__ */ jsx(Skeleton$1, { ...props });
|
|
27074
|
+
}
|
|
27075
|
+
const Switch = forwardRef((props, ref) => /* @__PURE__ */ jsx(Switch$1, { color: colors.primary, ...props, ref }));
|
|
27076
|
+
Switch.displayName = "Switch";
|
|
27077
|
+
function TableBase(props) {
|
|
27078
|
+
return /* @__PURE__ */ jsx(Table$1, { ...props });
|
|
27079
|
+
}
|
|
27080
|
+
const Table = Object.assign(TableBase, {
|
|
27081
|
+
Thead: Table$1.Thead,
|
|
27082
|
+
Tbody: Table$1.Tbody,
|
|
27083
|
+
Tr: Table$1.Tr,
|
|
27084
|
+
Th: Table$1.Th,
|
|
27085
|
+
Td: Table$1.Td,
|
|
27086
|
+
Tfoot: Table$1.Tfoot,
|
|
27087
|
+
Caption: Table$1.Caption
|
|
27088
|
+
});
|
|
27089
|
+
function TabsBase(props) {
|
|
27090
|
+
return /* @__PURE__ */ jsx(Tabs$1, { color: colors.primary, ...props });
|
|
27091
|
+
}
|
|
27092
|
+
const Tabs = Object.assign(TabsBase, {
|
|
27093
|
+
List: Tabs$1.List,
|
|
27094
|
+
Tab: Tabs$1.Tab,
|
|
27095
|
+
Panel: Tabs$1.Panel
|
|
27096
|
+
});
|
|
27097
|
+
const TextInput = forwardRef((props, ref) => /* @__PURE__ */ jsx(TextInput$1, { size: "md", ...props, ref }));
|
|
27098
|
+
TextInput.displayName = "TextInput";
|
|
27099
|
+
function Tooltip(props) {
|
|
27100
|
+
return /* @__PURE__ */ jsx(Tooltip$1, { fz: "xs", ...props });
|
|
27101
|
+
}
|
|
27102
|
+
function ErrorFallback({
|
|
27103
|
+
title = "Something went wrong",
|
|
27104
|
+
description = "We've been notified and are working on a fix.",
|
|
27105
|
+
onAction,
|
|
27106
|
+
actionLabel = "Reload Page",
|
|
27107
|
+
error: error2
|
|
27108
|
+
}) {
|
|
27109
|
+
if (error2 !== void 0) {
|
|
27110
|
+
console.error("[ErrorFallback]", error2);
|
|
27111
|
+
}
|
|
27112
|
+
const handleAction = onAction ?? (() => window.location.reload());
|
|
27113
|
+
return /* @__PURE__ */ jsx(Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "md", children: [
|
|
27114
|
+
/* @__PURE__ */ jsx(Title, { order: 2, children: title }),
|
|
27115
|
+
/* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, children: description }),
|
|
27116
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleAction, children: actionLabel })
|
|
27117
|
+
] }) });
|
|
27118
|
+
}
|
|
27119
|
+
function FairmintLogo({
|
|
27120
|
+
src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
|
|
27121
|
+
width = 140,
|
|
27122
|
+
height = 30,
|
|
27123
|
+
className,
|
|
27124
|
+
alt = "Fairmint"
|
|
27125
|
+
}) {
|
|
27126
|
+
return /* @__PURE__ */ jsx(
|
|
27127
|
+
"img",
|
|
27128
|
+
{
|
|
27129
|
+
src,
|
|
27130
|
+
alt,
|
|
27131
|
+
width,
|
|
27132
|
+
height,
|
|
27133
|
+
className,
|
|
27134
|
+
style: { objectFit: "contain" }
|
|
27135
|
+
}
|
|
27136
|
+
);
|
|
27137
|
+
}
|
|
27091
27138
|
function FairmintProvider({
|
|
27092
27139
|
children,
|
|
27093
27140
|
colorScheme = "light",
|
|
27094
27141
|
notificationPosition = "top-right"
|
|
27095
27142
|
}) {
|
|
27096
|
-
return /* @__PURE__ */ jsxs(
|
|
27097
|
-
|
|
27098
|
-
|
|
27099
|
-
|
|
27143
|
+
return /* @__PURE__ */ jsxs(
|
|
27144
|
+
MantineProvider,
|
|
27145
|
+
{
|
|
27146
|
+
theme,
|
|
27147
|
+
defaultColorScheme: colorScheme,
|
|
27148
|
+
cssVariablesResolver: fairmintCssVariables,
|
|
27149
|
+
children: [
|
|
27150
|
+
/* @__PURE__ */ jsx(Notifications, { position: notificationPosition }),
|
|
27151
|
+
children
|
|
27152
|
+
]
|
|
27153
|
+
}
|
|
27154
|
+
);
|
|
27100
27155
|
}
|
|
27101
27156
|
const emailSchema = stringType().email("Please enter a valid email address");
|
|
27102
27157
|
function EmailField({ error: error2, ...rest }) {
|
|
@@ -28211,7 +28266,7 @@ function FormField({
|
|
|
28211
28266
|
}
|
|
28212
28267
|
),
|
|
28213
28268
|
children && inputProps.error && /* @__PURE__ */ jsx(Text, { size: "xs", c: "error", role: "alert", children: inputProps.error }),
|
|
28214
|
-
children && description && !inputProps.error && /* @__PURE__ */ jsx(Text, { size: "xs", c:
|
|
28269
|
+
children && description && !inputProps.error && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: description })
|
|
28215
28270
|
] });
|
|
28216
28271
|
}
|
|
28217
28272
|
const passwordSchema = stringType().min(8, "Password must be at least 8 characters");
|
|
@@ -28227,17 +28282,77 @@ function PasswordField({ error: error2, ...rest }) {
|
|
|
28227
28282
|
}
|
|
28228
28283
|
);
|
|
28229
28284
|
}
|
|
28230
|
-
const phoneSchema = stringType().
|
|
28231
|
-
|
|
28285
|
+
const phoneSchema = stringType().refine((value) => {
|
|
28286
|
+
if (!/^\+?[\d\s\-().]*$/.test(value)) return false;
|
|
28287
|
+
const digits = value.replace(/\D/g, "");
|
|
28288
|
+
if (value.startsWith("+")) {
|
|
28289
|
+
if (digits.startsWith("1")) return digits.length === 11;
|
|
28290
|
+
return digits.length >= 8 && digits.length <= 15;
|
|
28291
|
+
}
|
|
28292
|
+
return digits.length === 10 || digits.length === 11 && digits.startsWith("1");
|
|
28293
|
+
}, "Please enter a valid phone number");
|
|
28294
|
+
function formatPhone(raw) {
|
|
28295
|
+
const hasPlus = raw.startsWith("+");
|
|
28296
|
+
const digits = raw.replace(/\D/g, "");
|
|
28297
|
+
if (!digits) return hasPlus ? "+" : "";
|
|
28298
|
+
if (!hasPlus && digits.length === 11 && digits.startsWith("1")) {
|
|
28299
|
+
return formatPhone(`+${digits}`);
|
|
28300
|
+
}
|
|
28301
|
+
if (hasPlus && digits.startsWith("1")) {
|
|
28302
|
+
const local = digits.slice(1);
|
|
28303
|
+
if (!local.length) return "+1";
|
|
28304
|
+
if (local.length <= 3) return `+1 (${local}`;
|
|
28305
|
+
if (local.length <= 6) return `+1 (${local.slice(0, 3)}) ${local.slice(3)}`;
|
|
28306
|
+
return `+1 (${local.slice(0, 3)}) ${local.slice(3, 6)}-${local.slice(6, 10)}`;
|
|
28307
|
+
}
|
|
28308
|
+
if (hasPlus) return `+${digits}`;
|
|
28309
|
+
if (digits.length <= 3) return digits;
|
|
28310
|
+
if (digits.length <= 6) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`;
|
|
28311
|
+
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
|
|
28312
|
+
}
|
|
28313
|
+
function normalizePhone(formatted) {
|
|
28314
|
+
const hasPlus = formatted.startsWith("+");
|
|
28315
|
+
const digits = formatted.replace(/\D/g, "");
|
|
28316
|
+
if (!digits) return "";
|
|
28317
|
+
if (hasPlus) return `+${digits}`;
|
|
28318
|
+
if (digits.length === 10) return `+1${digits}`;
|
|
28319
|
+
return `+${digits}`;
|
|
28320
|
+
}
|
|
28321
|
+
const formatPhoneDisplay = formatPhone;
|
|
28322
|
+
function PhoneField({ error: error2, onChange, value, ...rest }) {
|
|
28323
|
+
const inputRef = React__default.useRef(null);
|
|
28324
|
+
const handleChange = (e) => {
|
|
28325
|
+
const raw = e.target.value;
|
|
28326
|
+
const hasPlus = raw.startsWith("+");
|
|
28327
|
+
let digits = raw.replace(/\D/g, "");
|
|
28328
|
+
const shouldFormatAsUsCountryCode = digits.startsWith("1") && (hasPlus || !hasPlus && digits.length > 10);
|
|
28329
|
+
if (shouldFormatAsUsCountryCode) {
|
|
28330
|
+
digits = digits.slice(0, 11);
|
|
28331
|
+
} else {
|
|
28332
|
+
digits = digits.slice(0, hasPlus ? 15 : 10);
|
|
28333
|
+
}
|
|
28334
|
+
const formatted = formatPhone(hasPlus || shouldFormatAsUsCountryCode ? `+${digits}` : digits);
|
|
28335
|
+
e.target.value = formatted;
|
|
28336
|
+
onChange?.(e);
|
|
28337
|
+
};
|
|
28338
|
+
const displayValue = typeof value === "string" ? formatPhone(value) : value;
|
|
28339
|
+
React__default.useEffect(() => {
|
|
28340
|
+
if (inputRef.current && displayValue != null && inputRef.current.value !== String(displayValue)) {
|
|
28341
|
+
inputRef.current.value = String(displayValue);
|
|
28342
|
+
}
|
|
28343
|
+
}, [displayValue]);
|
|
28232
28344
|
return /* @__PURE__ */ jsx(
|
|
28233
28345
|
TextInput,
|
|
28234
28346
|
{
|
|
28347
|
+
ref: inputRef,
|
|
28235
28348
|
type: "tel",
|
|
28236
28349
|
label: rest.label ?? "Phone",
|
|
28237
|
-
placeholder: rest.placeholder ?? "
|
|
28350
|
+
placeholder: rest.placeholder ?? "(555) 000-0000",
|
|
28238
28351
|
autoComplete: "tel",
|
|
28352
|
+
...rest,
|
|
28239
28353
|
error: error2,
|
|
28240
|
-
|
|
28354
|
+
value: displayValue,
|
|
28355
|
+
onChange: handleChange
|
|
28241
28356
|
}
|
|
28242
28357
|
);
|
|
28243
28358
|
}
|
|
@@ -28441,9 +28556,9 @@ function EmptyState({
|
|
|
28441
28556
|
actionColor = colors.primary
|
|
28442
28557
|
}) {
|
|
28443
28558
|
return /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "md", py: "xl", role: "status", children: [
|
|
28444
|
-
icon && /* @__PURE__ */ jsx(Box, { c:
|
|
28559
|
+
icon && /* @__PURE__ */ jsx(Box, { c: fairmintVars.colorTextSecondary, fz: "2.5rem", children: icon }),
|
|
28445
28560
|
/* @__PURE__ */ jsx(Title, { order: 4, ta: "center", children: title }),
|
|
28446
|
-
description && /* @__PURE__ */ jsx(Text, { c:
|
|
28561
|
+
description && /* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, size: "sm", ta: "center", maw: 360, children: description }),
|
|
28447
28562
|
actionLabel && onAction && /* @__PURE__ */ jsx(Button, { variant: "light", color: actionColor, onClick: onAction, children: actionLabel })
|
|
28448
28563
|
] });
|
|
28449
28564
|
}
|
|
@@ -28631,6 +28746,102 @@ function EditableSection({
|
|
|
28631
28746
|
] }) : readView
|
|
28632
28747
|
] });
|
|
28633
28748
|
}
|
|
28749
|
+
const ERROR_CONFIGS = {
|
|
28750
|
+
400: {
|
|
28751
|
+
title: "Bad request",
|
|
28752
|
+
description: "Your request could not be understood. Please check your input and try again.",
|
|
28753
|
+
actionLabel: "Go back"
|
|
28754
|
+
},
|
|
28755
|
+
401: {
|
|
28756
|
+
title: "Authentication required",
|
|
28757
|
+
description: "You need to sign in to access this page. If you believe this is a mistake, please contact support.",
|
|
28758
|
+
actionLabel: "Go back"
|
|
28759
|
+
},
|
|
28760
|
+
403: {
|
|
28761
|
+
title: "Access denied",
|
|
28762
|
+
description: "You don't have permission to access this page. Contact support if you believe this is a mistake.",
|
|
28763
|
+
actionLabel: "Go back"
|
|
28764
|
+
},
|
|
28765
|
+
404: {
|
|
28766
|
+
title: "Nothing to see here",
|
|
28767
|
+
description: "The page you are trying to open does not exist. You may have mistyped the address, or the page has been moved to another URL.",
|
|
28768
|
+
actionLabel: "Go back"
|
|
28769
|
+
},
|
|
28770
|
+
429: {
|
|
28771
|
+
title: "Too many requests",
|
|
28772
|
+
description: "You have made too many requests in a short period. Please wait a moment before trying again.",
|
|
28773
|
+
actionLabel: "Try again"
|
|
28774
|
+
},
|
|
28775
|
+
500: {
|
|
28776
|
+
title: "Something went wrong",
|
|
28777
|
+
description: "An unexpected error occurred on our end. We have been notified and are working on a fix.",
|
|
28778
|
+
actionLabel: "Reload page"
|
|
28779
|
+
},
|
|
28780
|
+
503: {
|
|
28781
|
+
title: "Service unavailable",
|
|
28782
|
+
description: "We are temporarily unavailable for scheduled maintenance. Please check back shortly.",
|
|
28783
|
+
actionLabel: "Try again"
|
|
28784
|
+
}
|
|
28785
|
+
};
|
|
28786
|
+
function defaultAction(errorCode) {
|
|
28787
|
+
if (errorCode >= 500 || errorCode === 429) return () => window.location.reload();
|
|
28788
|
+
return () => {
|
|
28789
|
+
if (window.history.length > 1) window.history.back();
|
|
28790
|
+
else window.location.assign(window.location.origin);
|
|
28791
|
+
};
|
|
28792
|
+
}
|
|
28793
|
+
function ErrorPage({
|
|
28794
|
+
errorCode = 404,
|
|
28795
|
+
title,
|
|
28796
|
+
description,
|
|
28797
|
+
onAction,
|
|
28798
|
+
actionLabel
|
|
28799
|
+
}) {
|
|
28800
|
+
const config2 = ERROR_CONFIGS[errorCode] ?? ERROR_CONFIGS[500];
|
|
28801
|
+
const resolvedTitle = title ?? config2.title;
|
|
28802
|
+
const resolvedDescription = description ?? config2.description;
|
|
28803
|
+
const resolvedActionLabel = actionLabel ?? config2.actionLabel;
|
|
28804
|
+
const handleAction = onAction ?? defaultAction(errorCode);
|
|
28805
|
+
return /* @__PURE__ */ jsxs(
|
|
28806
|
+
Flex,
|
|
28807
|
+
{
|
|
28808
|
+
pos: "relative",
|
|
28809
|
+
align: "center",
|
|
28810
|
+
justify: "center",
|
|
28811
|
+
style: { minHeight: "100dvh", overflow: "hidden" },
|
|
28812
|
+
children: [
|
|
28813
|
+
/* @__PURE__ */ jsx(
|
|
28814
|
+
Box,
|
|
28815
|
+
{
|
|
28816
|
+
pos: "absolute",
|
|
28817
|
+
"aria-hidden": true,
|
|
28818
|
+
fw: 900,
|
|
28819
|
+
lh: 1,
|
|
28820
|
+
w: "100%",
|
|
28821
|
+
ta: "center",
|
|
28822
|
+
c: fairmintVars.watermarkColor,
|
|
28823
|
+
ff: fairmintVars.fontHeadings,
|
|
28824
|
+
style: {
|
|
28825
|
+
fontSize: "clamp(200px, 30vw, 380px)",
|
|
28826
|
+
userSelect: "none",
|
|
28827
|
+
letterSpacing: "-0.04em",
|
|
28828
|
+
top: "50%",
|
|
28829
|
+
left: "50%",
|
|
28830
|
+
transform: "translate(-50%, -50%)",
|
|
28831
|
+
pointerEvents: "none"
|
|
28832
|
+
},
|
|
28833
|
+
children: errorCode
|
|
28834
|
+
}
|
|
28835
|
+
),
|
|
28836
|
+
/* @__PURE__ */ jsx(Container, { size: "sm", pos: "relative", style: { zIndex: 1 }, children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "lg", children: [
|
|
28837
|
+
/* @__PURE__ */ jsx(Title, { order: 2, ta: "center", children: resolvedTitle }),
|
|
28838
|
+
/* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, ta: "center", maw: 500, size: "lg", children: resolvedDescription }),
|
|
28839
|
+
/* @__PURE__ */ jsx(Button, { color: colors.primary, onClick: handleAction, children: resolvedActionLabel })
|
|
28840
|
+
] }) })
|
|
28841
|
+
]
|
|
28842
|
+
}
|
|
28843
|
+
);
|
|
28844
|
+
}
|
|
28634
28845
|
const DefaultChevronIcon = () => /* @__PURE__ */ jsx(
|
|
28635
28846
|
"svg",
|
|
28636
28847
|
{
|
|
@@ -28669,14 +28880,22 @@ function ListRow({
|
|
|
28669
28880
|
/* @__PURE__ */ jsx(Avatar, { src: avatarSrc, alt: title, radius: "md", size: 40, color: avatarColor, children: avatarFallback ?? title.charAt(0).toUpperCase() }),
|
|
28670
28881
|
/* @__PURE__ */ jsxs(Box, { flex: 1, miw: 0, children: [
|
|
28671
28882
|
/* @__PURE__ */ jsx(Text, { fw: 500, size: "sm", truncate: true, children: title }),
|
|
28672
|
-
subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c:
|
|
28883
|
+
subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, lh: 1.3, children: subtitle })
|
|
28673
28884
|
] }),
|
|
28674
28885
|
/* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
28675
28886
|
rightSection ?? (value !== void 0 && /* @__PURE__ */ jsxs(Stack, { gap: 2, align: "flex-end", children: [
|
|
28676
28887
|
/* @__PURE__ */ jsx(Text, { fw: 500, size: "sm", style: { whiteSpace: "nowrap" }, children: value }),
|
|
28677
|
-
valueSubtitle && /* @__PURE__ */ jsx(
|
|
28888
|
+
valueSubtitle && /* @__PURE__ */ jsx(
|
|
28889
|
+
Text,
|
|
28890
|
+
{
|
|
28891
|
+
size: "xs",
|
|
28892
|
+
c: fairmintVars.colorTextSecondary,
|
|
28893
|
+
style: { whiteSpace: "nowrap" },
|
|
28894
|
+
children: valueSubtitle
|
|
28895
|
+
}
|
|
28896
|
+
)
|
|
28678
28897
|
] })),
|
|
28679
|
-
displayChevron && (chevronIcon ?? /* @__PURE__ */ jsx(Box, { c:
|
|
28898
|
+
displayChevron && (chevronIcon ?? /* @__PURE__ */ jsx(Box, { c: fairmintVars.colorTextTertiary, style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx(DefaultChevronIcon, {}) }))
|
|
28680
28899
|
] })
|
|
28681
28900
|
] });
|
|
28682
28901
|
const animationStyle = animate ? {
|
|
@@ -28688,7 +28907,7 @@ function ListRow({
|
|
|
28688
28907
|
return /* @__PURE__ */ jsx(
|
|
28689
28908
|
Box,
|
|
28690
28909
|
{
|
|
28691
|
-
bg: isSelected ?
|
|
28910
|
+
bg: isSelected ? fairmintVars.colorSurfaceSelected : void 0,
|
|
28692
28911
|
py: "sm",
|
|
28693
28912
|
px: "md",
|
|
28694
28913
|
style: animationStyle,
|
|
@@ -28699,7 +28918,7 @@ function ListRow({
|
|
|
28699
28918
|
return /* @__PURE__ */ jsx(
|
|
28700
28919
|
UnstyledButton,
|
|
28701
28920
|
{
|
|
28702
|
-
bg: isSelected ?
|
|
28921
|
+
bg: isSelected ? fairmintVars.colorSurfaceSelected : void 0,
|
|
28703
28922
|
onClick,
|
|
28704
28923
|
w: "100%",
|
|
28705
28924
|
py: "sm",
|
|
@@ -29969,9 +30188,9 @@ function PhotoCropModal({
|
|
|
29969
30188
|
)
|
|
29970
30189
|
}
|
|
29971
30190
|
),
|
|
29972
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c:
|
|
30191
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, ta: "center", children: "Drag to reposition · Scroll or pinch to zoom" }),
|
|
29973
30192
|
/* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
|
|
29974
|
-
/* @__PURE__ */ jsx(Button, { variant: "subtle", color:
|
|
30193
|
+
/* @__PURE__ */ jsx(Button, { variant: "subtle", color: colors.neutral, onClick: onClose, disabled: isConfirming, children: "Cancel" }),
|
|
29975
30194
|
/* @__PURE__ */ jsx(Button, { onClick: handleConfirm, loading: isConfirming, disabled: !croppedAreaPixels, children: "Apply" })
|
|
29976
30195
|
] })
|
|
29977
30196
|
] }) });
|
|
@@ -30070,7 +30289,7 @@ function StatCard({
|
|
|
30070
30289
|
}
|
|
30071
30290
|
),
|
|
30072
30291
|
/* @__PURE__ */ jsx(Text, { fw: 700, size: "xl", lh: 1, children: value }),
|
|
30073
|
-
trend && /* @__PURE__ */ jsx(Text, { size: "xs", c:
|
|
30292
|
+
trend && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: trend })
|
|
30074
30293
|
] }),
|
|
30075
30294
|
icon && /* @__PURE__ */ jsx(Box, { c: `${color}.5`, fz: "1.5rem", children: icon })
|
|
30076
30295
|
] }) });
|
|
@@ -30165,7 +30384,7 @@ function PageHeader({ title, subtitle, action }) {
|
|
|
30165
30384
|
return /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", mb: "lg", children: [
|
|
30166
30385
|
/* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
30167
30386
|
/* @__PURE__ */ jsx(Title, { order: 2, children: title }),
|
|
30168
|
-
subtitle && /* @__PURE__ */ jsx(Text, { c:
|
|
30387
|
+
subtitle && /* @__PURE__ */ jsx(Text, { c: fairmintVars.colorTextSecondary, size: "sm", children: subtitle })
|
|
30169
30388
|
] }),
|
|
30170
30389
|
action
|
|
30171
30390
|
] });
|
|
@@ -30355,6 +30574,8 @@ function InvestorProfileCard({
|
|
|
30355
30574
|
subtitle,
|
|
30356
30575
|
children,
|
|
30357
30576
|
onEditName,
|
|
30577
|
+
editNameDisabled,
|
|
30578
|
+
editNameTooltip,
|
|
30358
30579
|
onUploadPhoto,
|
|
30359
30580
|
photoUploading,
|
|
30360
30581
|
editNameIcon,
|
|
@@ -30443,11 +30664,25 @@ function InvestorProfileCard({
|
|
|
30443
30664
|
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", align: "center", children: [
|
|
30444
30665
|
/* @__PURE__ */ jsx(Text, { fw: 600, size: "md", children: displayName }),
|
|
30445
30666
|
verificationStatus && /* @__PURE__ */ jsx(StatusBadge, { status: verificationStatus, size: "xs" }),
|
|
30446
|
-
onEditName && /* @__PURE__ */ jsx(
|
|
30667
|
+
onEditName && (editNameDisabled ? /* @__PURE__ */ jsx(Tooltip, { label: editNameTooltip ?? "Coming soon", children: /* @__PURE__ */ jsx(
|
|
30668
|
+
ActionIcon,
|
|
30669
|
+
{
|
|
30670
|
+
variant: "subtle",
|
|
30671
|
+
size: "sm",
|
|
30672
|
+
"aria-label": "Edit name",
|
|
30673
|
+
"aria-disabled": "true",
|
|
30674
|
+
onClick: (event) => {
|
|
30675
|
+
event.preventDefault();
|
|
30676
|
+
event.stopPropagation();
|
|
30677
|
+
},
|
|
30678
|
+
style: { opacity: 0.5, cursor: "not-allowed" },
|
|
30679
|
+
children: editNameIcon ?? /* @__PURE__ */ jsx(DefaultPencilIcon, {})
|
|
30680
|
+
}
|
|
30681
|
+
) }) : /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", onClick: onEditName, "aria-label": "Edit name", children: editNameIcon ?? /* @__PURE__ */ jsx(DefaultPencilIcon, {}) }))
|
|
30447
30682
|
] }),
|
|
30448
|
-
email && /* @__PURE__ */ jsx(Text, { size: "sm", c:
|
|
30449
|
-
memberSinceText && /* @__PURE__ */ jsx(Text, { size: "xs", c:
|
|
30450
|
-
subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c:
|
|
30683
|
+
email && /* @__PURE__ */ jsx(Text, { size: "sm", c: fairmintVars.colorTextSecondary, children: email }),
|
|
30684
|
+
memberSinceText && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextTertiary, children: memberSinceText }),
|
|
30685
|
+
subtitle && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: subtitle })
|
|
30451
30686
|
] })
|
|
30452
30687
|
] }),
|
|
30453
30688
|
children
|
|
@@ -30547,7 +30782,7 @@ function WalletList({
|
|
|
30547
30782
|
children: [
|
|
30548
30783
|
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
30549
30784
|
/* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: getTypeLabel(w.type, typeLabels) }),
|
|
30550
|
-
w.label && /* @__PURE__ */ jsx(Text, { size: "xs", c:
|
|
30785
|
+
w.label && /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, children: w.label }),
|
|
30551
30786
|
/* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", children: truncateAddress(w.address) })
|
|
30552
30787
|
] }),
|
|
30553
30788
|
/* @__PURE__ */ jsxs(Group, { gap: 4, children: [
|
|
@@ -30625,7 +30860,7 @@ function WalletList({
|
|
|
30625
30860
|
title: "Remove Wallet",
|
|
30626
30861
|
message: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
30627
30862
|
/* @__PURE__ */ jsx(Text, { size: "sm", children: "Are you sure you want to remove this wallet address? This action cannot be undone." }),
|
|
30628
|
-
walletToRemove && /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", c:
|
|
30863
|
+
walletToRemove && /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", c: fairmintVars.colorTextSecondary, children: walletToRemove }),
|
|
30629
30864
|
removeError && /* @__PURE__ */ jsx(Text, { size: "sm", c: colors.error, children: removeError })
|
|
30630
30865
|
] }),
|
|
30631
30866
|
opened: walletToRemove !== null,
|
|
@@ -30704,6 +30939,7 @@ export {
|
|
|
30704
30939
|
EmptyState,
|
|
30705
30940
|
EquityGrantCard,
|
|
30706
30941
|
ErrorFallback,
|
|
30942
|
+
ErrorPage,
|
|
30707
30943
|
EthereumAddressField,
|
|
30708
30944
|
FairmintLogo,
|
|
30709
30945
|
FairmintProvider,
|
|
@@ -30762,18 +30998,24 @@ export {
|
|
|
30762
30998
|
ZipField,
|
|
30763
30999
|
brandColors,
|
|
30764
31000
|
colors,
|
|
31001
|
+
createFairmintMantineProviderProps,
|
|
30765
31002
|
createZipSchema,
|
|
30766
31003
|
emailSchema,
|
|
30767
31004
|
ethereumAddressSchema,
|
|
31005
|
+
fairmintCssVariables,
|
|
31006
|
+
fairmintVars,
|
|
30768
31007
|
formatCurrency,
|
|
30769
31008
|
formatCurrencyPrecise,
|
|
30770
31009
|
formatDate,
|
|
30771
31010
|
formatNumber,
|
|
30772
31011
|
formatPercent,
|
|
31012
|
+
formatPhone,
|
|
31013
|
+
formatPhoneDisplay,
|
|
30773
31014
|
formatPreciseWithCurrency,
|
|
30774
31015
|
getAvatarColor,
|
|
30775
31016
|
isEthereumAddress,
|
|
30776
31017
|
neutralColors,
|
|
31018
|
+
normalizePhone,
|
|
30777
31019
|
notify,
|
|
30778
31020
|
passwordSchema,
|
|
30779
31021
|
phoneSchema,
|
|
@@ -30781,6 +31023,7 @@ export {
|
|
|
30781
31023
|
semanticColors,
|
|
30782
31024
|
theme,
|
|
30783
31025
|
truncateAddress,
|
|
31026
|
+
typography,
|
|
30784
31027
|
useClickOutside,
|
|
30785
31028
|
useClipboard,
|
|
30786
31029
|
useDebouncedCallback,
|