@fairmint/ui 0.3.39 → 0.3.41
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/README.md +7 -0
- package/dist/components/generic/EmptyState/EmptyState.cjs +35 -6
- package/dist/components/generic/EmptyState/EmptyState.cjs.map +1 -1
- package/dist/components/generic/EmptyState/EmptyState.d.ts +12 -4
- package/dist/components/generic/EmptyState/EmptyState.d.ts.map +1 -1
- package/dist/components/generic/EmptyState/EmptyState.js +36 -7
- package/dist/components/generic/EmptyState/EmptyState.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Fairmint's shared design system and UI component library.
|
|
4
4
|
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- [@fairmint/ui shared components](https://github.com/Fairmint/dev-docs/blob/main/docs/development/ui.md)
|
|
8
|
+
- [GitHub wiki](https://github.com/Fairmint/ui/wiki)
|
|
9
|
+
|
|
10
|
+
The canonical developer map is now in Fairmint/dev-docs. The GitHub wiki remains until that replacement is on main, then it will be disabled.
|
|
11
|
+
|
|
5
12
|
## Design quality
|
|
6
13
|
|
|
7
14
|
Read [docs/design-quality.md](docs/design-quality.md) before creating or reviewing product UI. It records the approved onboarding v5 quality bar, the shared spacing and hierarchy rules, reusable component expectations, and the visual-review gate for founder, investor, onboarding, SAFE, grant, and cap-table work.
|
|
@@ -1,13 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
-
const index = require("../../../theme/index.cjs");
|
|
5
4
|
const colors = require("../../../theme/colors.cjs");
|
|
5
|
+
const Avatar = require("../../primitives/Avatar/Avatar.cjs");
|
|
6
6
|
const Button = require("../../primitives/Button/Button.cjs");
|
|
7
7
|
const layout = require("../../primitives/layout.cjs");
|
|
8
|
-
const Title = require("../../../node_modules/@mantine/core/esm/components/Title/Title.cjs");
|
|
9
8
|
const Text = require("../../../node_modules/@mantine/core/esm/components/Text/Text.cjs");
|
|
9
|
+
const EMPTY_STATE_AVATAR_SIZE = 56;
|
|
10
|
+
const EMPTY_STATE_ICON_SIZE = 28;
|
|
11
|
+
function EmptyStateAvatar({ avatar, icon }) {
|
|
12
|
+
if (avatar) {
|
|
13
|
+
return avatar;
|
|
14
|
+
}
|
|
15
|
+
if (!icon) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
19
|
+
Avatar.Avatar,
|
|
20
|
+
{
|
|
21
|
+
"aria-hidden": true,
|
|
22
|
+
color: colors.colors.neutral,
|
|
23
|
+
radius: "xl",
|
|
24
|
+
size: EMPTY_STATE_AVATAR_SIZE,
|
|
25
|
+
styles: {
|
|
26
|
+
root: {
|
|
27
|
+
"& svg": {
|
|
28
|
+
height: EMPTY_STATE_ICON_SIZE,
|
|
29
|
+
width: EMPTY_STATE_ICON_SIZE
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
variant: "light",
|
|
34
|
+
children: icon
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
10
38
|
function EmptyState({
|
|
39
|
+
avatar,
|
|
11
40
|
icon,
|
|
12
41
|
title,
|
|
13
42
|
description,
|
|
@@ -16,10 +45,10 @@ function EmptyState({
|
|
|
16
45
|
actionColor = colors.colors.primary
|
|
17
46
|
}) {
|
|
18
47
|
return /* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { align: "center", gap: "md", py: "xl", role: "status", children: [
|
|
19
|
-
|
|
20
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
21
|
-
description && /* @__PURE__ */ jsxRuntime.jsx(Text.Text, { c:
|
|
22
|
-
actionLabel && onAction && /* @__PURE__ */ jsxRuntime.jsx(Button.Button, {
|
|
48
|
+
/* @__PURE__ */ jsxRuntime.jsx(EmptyStateAvatar, { avatar, icon }),
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text.Text, { fw: 500, size: "lg", ta: "center", children: title }),
|
|
50
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(Text.Text, { c: "dimmed", maw: 360, size: "sm", ta: "center", children: description }),
|
|
51
|
+
actionLabel && onAction && /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { color: actionColor, onClick: onAction, variant: "light", children: actionLabel })
|
|
23
52
|
] });
|
|
24
53
|
}
|
|
25
54
|
exports.EmptyState = EmptyState;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.cjs","sources":["../../../../src/components/generic/EmptyState/EmptyState.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {
|
|
1
|
+
{"version":3,"file":"EmptyState.cjs","sources":["../../../../src/components/generic/EmptyState/EmptyState.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { colors } from \"../../../theme/colors\";\nimport { Avatar } from \"../../primitives/Avatar/Avatar\";\nimport { Button } from \"../../primitives/Button/Button\";\nimport { Stack, Text } from \"../../primitives/layout\";\n\nconst EMPTY_STATE_AVATAR_SIZE = 56;\nconst EMPTY_STATE_ICON_SIZE = 28;\n\nexport interface EmptyStateProps {\n /**\n * Fully composed avatar (photo, initials, or custom node). Takes precedence\n * over `icon`. Use this when the empty state represents a person or entity.\n */\n avatar?: ReactNode;\n /**\n * Icon glyph (e.g. from `@tabler/icons-react`). Wrapped in the canonical\n * empty-state Avatar: 56px, light gray, circular.\n */\n icon?: ReactNode;\n /** Primary heading. */\n title: ReactNode;\n /** Supporting description. */\n description?: ReactNode;\n /** CTA button label. Rendered only when `onAction` is also provided. */\n actionLabel?: string;\n /** CTA button callback. The CTA is omitted unless this is set. */\n onAction?: () => void;\n /** CTA button color. @default colors.primary */\n actionColor?: string;\n}\n\nfunction EmptyStateAvatar({ avatar, icon }: Pick<EmptyStateProps, \"avatar\" | \"icon\">) {\n if (avatar) {\n return avatar;\n }\n if (!icon) {\n return null;\n }\n return (\n <Avatar\n aria-hidden\n color={colors.neutral}\n radius=\"xl\"\n size={EMPTY_STATE_AVATAR_SIZE}\n styles={{\n root: {\n \"& svg\": {\n height: EMPTY_STATE_ICON_SIZE,\n width: EMPTY_STATE_ICON_SIZE,\n },\n },\n }}\n variant=\"light\"\n >\n {icon}\n </Avatar>\n );\n}\n\nexport function EmptyState({\n avatar,\n icon,\n title,\n description,\n actionLabel,\n onAction,\n actionColor = colors.primary,\n}: EmptyStateProps) {\n return (\n <Stack align=\"center\" gap=\"md\" py=\"xl\" role=\"status\">\n <EmptyStateAvatar avatar={avatar} icon={icon} />\n <Text fw={500} size=\"lg\" ta=\"center\">\n {title}\n </Text>\n {description && (\n <Text c=\"dimmed\" maw={360} size=\"sm\" ta=\"center\">\n {description}\n </Text>\n )}\n {actionLabel && onAction && (\n <Button color={actionColor} onClick={onAction} variant=\"light\">\n {actionLabel}\n </Button>\n )}\n </Stack>\n );\n}\n"],"names":["jsx","Avatar","colors","jsxs","Stack","Text","Button"],"mappings":";;;;;;;;AAMA,MAAM,0BAA0B;AAChC,MAAM,wBAAwB;AAyB9B,SAAS,iBAAiB,EAAE,QAAQ,QAAkD;AACpF,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SACEA,2BAAAA;AAAAA,IAACC,OAAAA;AAAAA,IAAA;AAAA,MACC,eAAW;AAAA,MACX,OAAOC,OAAAA,OAAO;AAAA,MACd,QAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,SAAS;AAAA,YACP,QAAQ;AAAA,YACR,OAAO;AAAA,UAAA;AAAA,QACT;AAAA,MACF;AAAA,MAEF,SAAQ;AAAA,MAEP,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAcA,OAAAA,OAAO;AACvB,GAAoB;AAClB,SACEC,gCAACC,OAAAA,SAAM,OAAM,UAAS,KAAI,MAAK,IAAG,MAAK,MAAK,UAC1C,UAAA;AAAA,IAAAJ,2BAAAA,IAAC,kBAAA,EAAiB,QAAgB,KAAA,CAAY;AAAA,IAC9CA,2BAAAA,IAACK,KAAAA,QAAK,IAAI,KAAK,MAAK,MAAK,IAAG,UACzB,UAAA,MAAA,CACH;AAAA,IACC,eACCL,2BAAAA,IAACK,KAAAA,MAAA,EAAK,GAAE,UAAS,KAAK,KAAK,MAAK,MAAK,IAAG,UACrC,UAAA,YAAA,CACH;AAAA,IAED,eAAe,YACdL,2BAAAA,IAACM,OAAAA,QAAA,EAAO,OAAO,aAAa,SAAS,UAAU,SAAQ,SACpD,UAAA,YAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;;"}
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
export interface EmptyStateProps {
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Fully composed avatar (photo, initials, or custom node). Takes precedence
|
|
5
|
+
* over `icon`. Use this when the empty state represents a person or entity.
|
|
6
|
+
*/
|
|
7
|
+
avatar?: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Icon glyph (e.g. from `@tabler/icons-react`). Wrapped in the canonical
|
|
10
|
+
* empty-state Avatar: 56px, light gray, circular.
|
|
11
|
+
*/
|
|
4
12
|
icon?: ReactNode;
|
|
5
13
|
/** Primary heading. */
|
|
6
14
|
title: ReactNode;
|
|
7
15
|
/** Supporting description. */
|
|
8
16
|
description?: ReactNode;
|
|
9
|
-
/** CTA button label.
|
|
17
|
+
/** CTA button label. Rendered only when `onAction` is also provided. */
|
|
10
18
|
actionLabel?: string;
|
|
11
|
-
/** CTA button callback. */
|
|
19
|
+
/** CTA button callback. The CTA is omitted unless this is set. */
|
|
12
20
|
onAction?: () => void;
|
|
13
21
|
/** CTA button color. @default colors.primary */
|
|
14
22
|
actionColor?: string;
|
|
15
23
|
}
|
|
16
|
-
export declare function EmptyState({ icon, title, description, actionLabel, onAction, actionColor, }: EmptyStateProps): import("react").JSX.Element;
|
|
24
|
+
export declare function EmptyState({ avatar, icon, title, description, actionLabel, onAction, actionColor, }: EmptyStateProps): import("react").JSX.Element;
|
|
17
25
|
//# sourceMappingURL=EmptyState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.d.ts","sourceRoot":"","sources":["../../../../src/components/generic/EmptyState/EmptyState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"EmptyState.d.ts","sourceRoot":"","sources":["../../../../src/components/generic/EmptyState/EmptyState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AASvC,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,uBAAuB;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA8BD,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,IAAI,EACJ,KAAK,EACL,WAAW,EACX,WAAW,EACX,QAAQ,EACR,WAA4B,GAC7B,EAAE,eAAe,+BAmBjB"}
|
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { fairmintVars } from "../../../theme/index.js";
|
|
3
2
|
import { colors } from "../../../theme/colors.js";
|
|
3
|
+
import { Avatar } from "../../primitives/Avatar/Avatar.js";
|
|
4
4
|
import { Button } from "../../primitives/Button/Button.js";
|
|
5
|
-
import { Stack
|
|
6
|
-
import { Title } from "../../../node_modules/@mantine/core/esm/components/Title/Title.js";
|
|
5
|
+
import { Stack } from "../../primitives/layout.js";
|
|
7
6
|
import { Text } from "../../../node_modules/@mantine/core/esm/components/Text/Text.js";
|
|
7
|
+
const EMPTY_STATE_AVATAR_SIZE = 56;
|
|
8
|
+
const EMPTY_STATE_ICON_SIZE = 28;
|
|
9
|
+
function EmptyStateAvatar({ avatar, icon }) {
|
|
10
|
+
if (avatar) {
|
|
11
|
+
return avatar;
|
|
12
|
+
}
|
|
13
|
+
if (!icon) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
Avatar,
|
|
18
|
+
{
|
|
19
|
+
"aria-hidden": true,
|
|
20
|
+
color: colors.neutral,
|
|
21
|
+
radius: "xl",
|
|
22
|
+
size: EMPTY_STATE_AVATAR_SIZE,
|
|
23
|
+
styles: {
|
|
24
|
+
root: {
|
|
25
|
+
"& svg": {
|
|
26
|
+
height: EMPTY_STATE_ICON_SIZE,
|
|
27
|
+
width: EMPTY_STATE_ICON_SIZE
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
variant: "light",
|
|
32
|
+
children: icon
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
8
36
|
function EmptyState({
|
|
37
|
+
avatar,
|
|
9
38
|
icon,
|
|
10
39
|
title,
|
|
11
40
|
description,
|
|
@@ -14,10 +43,10 @@ function EmptyState({
|
|
|
14
43
|
actionColor = colors.primary
|
|
15
44
|
}) {
|
|
16
45
|
return /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "md", py: "xl", role: "status", children: [
|
|
17
|
-
|
|
18
|
-
/* @__PURE__ */ jsx(
|
|
19
|
-
description && /* @__PURE__ */ jsx(Text, { c:
|
|
20
|
-
actionLabel && onAction && /* @__PURE__ */ jsx(Button, {
|
|
46
|
+
/* @__PURE__ */ jsx(EmptyStateAvatar, { avatar, icon }),
|
|
47
|
+
/* @__PURE__ */ jsx(Text, { fw: 500, size: "lg", ta: "center", children: title }),
|
|
48
|
+
description && /* @__PURE__ */ jsx(Text, { c: "dimmed", maw: 360, size: "sm", ta: "center", children: description }),
|
|
49
|
+
actionLabel && onAction && /* @__PURE__ */ jsx(Button, { color: actionColor, onClick: onAction, variant: "light", children: actionLabel })
|
|
21
50
|
] });
|
|
22
51
|
}
|
|
23
52
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.js","sources":["../../../../src/components/generic/EmptyState/EmptyState.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {
|
|
1
|
+
{"version":3,"file":"EmptyState.js","sources":["../../../../src/components/generic/EmptyState/EmptyState.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { colors } from \"../../../theme/colors\";\nimport { Avatar } from \"../../primitives/Avatar/Avatar\";\nimport { Button } from \"../../primitives/Button/Button\";\nimport { Stack, Text } from \"../../primitives/layout\";\n\nconst EMPTY_STATE_AVATAR_SIZE = 56;\nconst EMPTY_STATE_ICON_SIZE = 28;\n\nexport interface EmptyStateProps {\n /**\n * Fully composed avatar (photo, initials, or custom node). Takes precedence\n * over `icon`. Use this when the empty state represents a person or entity.\n */\n avatar?: ReactNode;\n /**\n * Icon glyph (e.g. from `@tabler/icons-react`). Wrapped in the canonical\n * empty-state Avatar: 56px, light gray, circular.\n */\n icon?: ReactNode;\n /** Primary heading. */\n title: ReactNode;\n /** Supporting description. */\n description?: ReactNode;\n /** CTA button label. Rendered only when `onAction` is also provided. */\n actionLabel?: string;\n /** CTA button callback. The CTA is omitted unless this is set. */\n onAction?: () => void;\n /** CTA button color. @default colors.primary */\n actionColor?: string;\n}\n\nfunction EmptyStateAvatar({ avatar, icon }: Pick<EmptyStateProps, \"avatar\" | \"icon\">) {\n if (avatar) {\n return avatar;\n }\n if (!icon) {\n return null;\n }\n return (\n <Avatar\n aria-hidden\n color={colors.neutral}\n radius=\"xl\"\n size={EMPTY_STATE_AVATAR_SIZE}\n styles={{\n root: {\n \"& svg\": {\n height: EMPTY_STATE_ICON_SIZE,\n width: EMPTY_STATE_ICON_SIZE,\n },\n },\n }}\n variant=\"light\"\n >\n {icon}\n </Avatar>\n );\n}\n\nexport function EmptyState({\n avatar,\n icon,\n title,\n description,\n actionLabel,\n onAction,\n actionColor = colors.primary,\n}: EmptyStateProps) {\n return (\n <Stack align=\"center\" gap=\"md\" py=\"xl\" role=\"status\">\n <EmptyStateAvatar avatar={avatar} icon={icon} />\n <Text fw={500} size=\"lg\" ta=\"center\">\n {title}\n </Text>\n {description && (\n <Text c=\"dimmed\" maw={360} size=\"sm\" ta=\"center\">\n {description}\n </Text>\n )}\n {actionLabel && onAction && (\n <Button color={actionColor} onClick={onAction} variant=\"light\">\n {actionLabel}\n </Button>\n )}\n </Stack>\n );\n}\n"],"names":[],"mappings":";;;;;;AAMA,MAAM,0BAA0B;AAChC,MAAM,wBAAwB;AAyB9B,SAAS,iBAAiB,EAAE,QAAQ,QAAkD;AACpF,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AACA,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,eAAW;AAAA,MACX,OAAO,OAAO;AAAA,MACd,QAAO;AAAA,MACP,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,SAAS;AAAA,YACP,QAAQ;AAAA,YACR,OAAO;AAAA,UAAA;AAAA,QACT;AAAA,MACF;AAAA,MAEF,SAAQ;AAAA,MAEP,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc,OAAO;AACvB,GAAoB;AAClB,SACE,qBAAC,SAAM,OAAM,UAAS,KAAI,MAAK,IAAG,MAAK,MAAK,UAC1C,UAAA;AAAA,IAAA,oBAAC,kBAAA,EAAiB,QAAgB,KAAA,CAAY;AAAA,IAC9C,oBAAC,QAAK,IAAI,KAAK,MAAK,MAAK,IAAG,UACzB,UAAA,MAAA,CACH;AAAA,IACC,eACC,oBAAC,MAAA,EAAK,GAAE,UAAS,KAAK,KAAK,MAAK,MAAK,IAAG,UACrC,UAAA,YAAA,CACH;AAAA,IAED,eAAe,YACd,oBAAC,QAAA,EAAO,OAAO,aAAa,SAAS,UAAU,SAAQ,SACpD,UAAA,YAAA,CACH;AAAA,EAAA,GAEJ;AAEJ;"}
|