@fairmint/ui 0.4.10 → 0.4.12
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/BrandedLoadingScreen/BrandedLoadingScreen.cjs +1 -1
- package/dist/components/BrandedLoadingScreen/BrandedLoadingScreen.js +1 -1
- package/dist/components/ErrorFallback/ErrorFallback.cjs +1 -1
- package/dist/components/ErrorFallback/ErrorFallback.js +1 -1
- package/dist/components/form/FormField.cjs +1 -1
- package/dist/components/form/FormField.js +1 -1
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.cjs +1 -1
- package/dist/components/generic/AgentSuggestion/AgentSuggestion.js +1 -1
- package/dist/components/generic/Banner/Banner.cjs +1 -1
- package/dist/components/generic/Banner/Banner.js +1 -1
- package/dist/components/generic/BottomSheet/BottomSheet.cjs +1 -1
- package/dist/components/generic/BottomSheet/BottomSheet.js +1 -1
- package/dist/components/generic/CompanyBanner/CompanyBanner.cjs +1 -1
- package/dist/components/generic/CompanyBanner/CompanyBanner.js +1 -1
- package/dist/components/generic/ConfidentialityBanner/ConfidentialityBanner.cjs +1 -1
- package/dist/components/generic/ConfidentialityBanner/ConfidentialityBanner.js +1 -1
- package/dist/components/generic/Currency/Currency.cjs +1 -1
- package/dist/components/generic/Currency/Currency.js +1 -1
- package/dist/components/generic/DataRow/DataRow.cjs +24 -3
- package/dist/components/generic/DataRow/DataRow.cjs.map +1 -1
- package/dist/components/generic/DataRow/DataRow.d.ts.map +1 -1
- package/dist/components/generic/DataRow/DataRow.js +24 -3
- package/dist/components/generic/DataRow/DataRow.js.map +1 -1
- package/dist/components/generic/DataTable/DataTable.cjs +2 -2
- package/dist/components/generic/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/generic/DataTable/DataTable.js +2 -2
- package/dist/components/generic/DataTable/DataTable.js.map +1 -1
- package/dist/components/generic/DateDisplay/DateDisplay.cjs +1 -1
- package/dist/components/generic/DateDisplay/DateDisplay.js +1 -1
- package/dist/components/generic/DocumentRow/DocumentRow.cjs +1 -1
- package/dist/components/generic/DocumentRow/DocumentRow.js +1 -1
- package/dist/components/generic/EditableSection/EditableSection.cjs +1 -1
- package/dist/components/generic/EditableSection/EditableSection.js +1 -1
- package/dist/components/generic/EmptyState/EmptyState.cjs +1 -1
- package/dist/components/generic/EmptyState/EmptyState.js +1 -1
- package/dist/components/generic/ErrorPage/ErrorPage.cjs +1 -1
- package/dist/components/generic/ErrorPage/ErrorPage.js +1 -1
- package/dist/components/generic/Eyebrow/Eyebrow.cjs +1 -1
- package/dist/components/generic/Eyebrow/Eyebrow.js +1 -1
- package/dist/components/generic/FileDropzone/FileDropzone.cjs +1 -1
- package/dist/components/generic/FileDropzone/FileDropzone.js +1 -1
- package/dist/components/generic/ListRow/ListRow.cjs +5 -4
- package/dist/components/generic/ListRow/ListRow.cjs.map +1 -1
- package/dist/components/generic/ListRow/ListRow.d.ts.map +1 -1
- package/dist/components/generic/ListRow/ListRow.js +5 -4
- package/dist/components/generic/ListRow/ListRow.js.map +1 -1
- package/dist/components/generic/MultiSelectSearch/MultiSelectSearch.cjs +1 -1
- package/dist/components/generic/MultiSelectSearch/MultiSelectSearch.js +1 -1
- package/dist/components/generic/NotificationRow/NotificationRow.cjs +1 -1
- package/dist/components/generic/NotificationRow/NotificationRow.js +1 -1
- package/dist/components/generic/Percent/Percent.cjs +1 -1
- package/dist/components/generic/Percent/Percent.js +1 -1
- package/dist/components/generic/PhotoCropModal/PhotoCropModal.cjs +1 -1
- package/dist/components/generic/PhotoCropModal/PhotoCropModal.js +1 -1
- package/dist/components/generic/ProcessingState/ProcessingState.cjs +1 -1
- package/dist/components/generic/ProcessingState/ProcessingState.js +1 -1
- package/dist/components/generic/RadioCard/RadioCard.cjs +1 -1
- package/dist/components/generic/RadioCard/RadioCard.js +1 -1
- package/dist/components/generic/StatCard/StatCard.cjs +1 -1
- package/dist/components/generic/StatCard/StatCard.js +1 -1
- package/dist/components/generic/StepCard/StepCard.cjs +3 -2
- package/dist/components/generic/StepCard/StepCard.cjs.map +1 -1
- package/dist/components/generic/StepCard/StepCard.d.ts.map +1 -1
- package/dist/components/generic/StepCard/StepCard.js +3 -2
- package/dist/components/generic/StepCard/StepCard.js.map +1 -1
- package/dist/components/generic/TablePagination/TablePagination.cjs +1 -1
- package/dist/components/generic/TablePagination/TablePagination.js +1 -1
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.cjs +1 -1
- package/dist/components/generic/TaskInboxPopover/TaskInboxPopover.js +1 -1
- package/dist/components/generic/TaskRow/TaskRow.cjs +1 -1
- package/dist/components/generic/TaskRow/TaskRow.js +1 -1
- package/dist/components/layout/AccountSheet/AccountSheet.cjs +1 -1
- package/dist/components/layout/AccountSheet/AccountSheet.js +1 -1
- package/dist/components/layout/MobileNav/MobileNav.cjs +1 -1
- package/dist/components/layout/MobileNav/MobileNav.js +1 -1
- package/dist/components/layout/PageHeader/PageHeader.cjs +1 -1
- package/dist/components/layout/PageHeader/PageHeader.js +1 -1
- package/dist/components/primitives/Glossary/GlossaryContext.cjs +39 -0
- package/dist/components/primitives/Glossary/GlossaryContext.cjs.map +1 -0
- package/dist/components/primitives/Glossary/GlossaryContext.d.ts +49 -0
- package/dist/components/primitives/Glossary/GlossaryContext.d.ts.map +1 -0
- package/dist/components/primitives/Glossary/GlossaryContext.js +39 -0
- package/dist/components/primitives/Glossary/GlossaryContext.js.map +1 -0
- package/dist/components/primitives/Glossary/GlossaryTerm.cjs +147 -0
- package/dist/components/primitives/Glossary/GlossaryTerm.cjs.map +1 -0
- package/dist/components/primitives/Glossary/GlossaryTerm.d.ts +10 -0
- package/dist/components/primitives/Glossary/GlossaryTerm.d.ts.map +1 -0
- package/dist/components/primitives/Glossary/GlossaryTerm.js +147 -0
- package/dist/components/primitives/Glossary/GlossaryTerm.js.map +1 -0
- package/dist/components/primitives/Glossary/index.d.ts +3 -0
- package/dist/components/primitives/Glossary/index.d.ts.map +1 -0
- package/dist/components/primitives/Text/Text.cjs +112 -0
- package/dist/components/primitives/Text/Text.cjs.map +1 -0
- package/dist/components/primitives/Text/Text.d.ts +22 -0
- package/dist/components/primitives/Text/Text.d.ts.map +1 -0
- package/dist/components/primitives/Text/Text.js +112 -0
- package/dist/components/primitives/Text/Text.js.map +1 -0
- package/dist/components/primitives/Text/index.d.ts +2 -0
- package/dist/components/primitives/Text/index.d.ts.map +1 -0
- package/dist/components/primitives/index.d.ts +2 -0
- package/dist/components/primitives/index.d.ts.map +1 -1
- package/dist/components/primitives/layout.cjs.map +1 -1
- package/dist/components/primitives/layout.d.ts +2 -1
- package/dist/components/primitives/layout.d.ts.map +1 -1
- package/dist/components/primitives/layout.js.map +1 -1
- package/dist/components/primitives/muiCompat.cjs +8 -8
- package/dist/components/primitives/muiCompat.cjs.map +1 -1
- package/dist/components/primitives/muiCompat.d.ts.map +1 -1
- package/dist/components/primitives/muiCompat.js +8 -8
- package/dist/components/primitives/muiCompat.js.map +1 -1
- package/dist/components/specific/DocumentRow/DocumentRow.cjs +91 -14
- package/dist/components/specific/DocumentRow/DocumentRow.cjs.map +1 -1
- package/dist/components/specific/DocumentRow/DocumentRow.d.ts +7 -1
- package/dist/components/specific/DocumentRow/DocumentRow.d.ts.map +1 -1
- package/dist/components/specific/DocumentRow/DocumentRow.js +92 -15
- package/dist/components/specific/DocumentRow/DocumentRow.js.map +1 -1
- package/dist/components/specific/InvestorProfileCard/InvestorProfileCard.cjs +1 -1
- package/dist/components/specific/InvestorProfileCard/InvestorProfileCard.js +1 -1
- package/dist/components/specific/WalletList/WalletList.cjs +1 -1
- package/dist/components/specific/WalletList/WalletList.js +1 -1
- package/dist/components/specific/WalletListItem/WalletListItem.cjs +3 -2
- package/dist/components/specific/WalletListItem/WalletListItem.cjs.map +1 -1
- package/dist/components/specific/WalletListItem/WalletListItem.d.ts.map +1 -1
- package/dist/components/specific/WalletListItem/WalletListItem.js +3 -2
- package/dist/components/specific/WalletListItem/WalletListItem.js.map +1 -1
- package/dist/constants/glossary.cjs +210 -0
- package/dist/constants/glossary.cjs.map +1 -0
- package/dist/constants/glossary.d.ts +26 -0
- package/dist/constants/glossary.d.ts.map +1 -0
- package/dist/constants/glossary.js +210 -0
- package/dist/constants/glossary.js.map +1 -0
- package/dist/fairmint-ui.cjs +13 -1
- package/dist/fairmint-ui.cjs.map +1 -1
- package/dist/fairmint-ui.js +13 -1
- package/dist/fairmint-ui.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/utils/glossaryMatcher.cjs +89 -0
- package/dist/utils/glossaryMatcher.cjs.map +1 -0
- package/dist/utils/glossaryMatcher.d.ts +23 -0
- package/dist/utils/glossaryMatcher.d.ts.map +1 -0
- package/dist/utils/glossaryMatcher.js +89 -0
- package/dist/utils/glossaryMatcher.js.map +1 -0
- package/package.json +1 -1
|
@@ -6,8 +6,8 @@ const colors = require("../../../theme/colors.cjs");
|
|
|
6
6
|
const format = require("../../../utils/format.cjs");
|
|
7
7
|
const layout = require("../../primitives/layout.cjs");
|
|
8
8
|
const ThemeIcon = require("../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.cjs");
|
|
9
|
+
const Text = require("../../primitives/Text/Text.cjs");
|
|
9
10
|
const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
|
|
10
|
-
const Text = require("../../../node_modules/@mantine/core/esm/components/Text/Text.cjs");
|
|
11
11
|
const UnstyledButton = require("../../../node_modules/@mantine/core/esm/components/UnstyledButton/UnstyledButton.cjs");
|
|
12
12
|
const DefaultDocumentIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
13
13
|
"svg",
|
|
@@ -45,6 +45,54 @@ const DefaultChevronIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
|
45
45
|
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" })
|
|
46
46
|
}
|
|
47
47
|
);
|
|
48
|
+
const NATIVE_CONTROL_SELECTOR = "a, button, input, select, textarea, label, summary, [contenteditable]:not([contenteditable='false'])";
|
|
49
|
+
const INTERACTIVE_ARIA_ROLES = /* @__PURE__ */ new Set([
|
|
50
|
+
"button",
|
|
51
|
+
"checkbox",
|
|
52
|
+
"combobox",
|
|
53
|
+
"gridcell",
|
|
54
|
+
"link",
|
|
55
|
+
"listbox",
|
|
56
|
+
"menu",
|
|
57
|
+
"menuitem",
|
|
58
|
+
"menuitemcheckbox",
|
|
59
|
+
"menuitemradio",
|
|
60
|
+
"option",
|
|
61
|
+
"radio",
|
|
62
|
+
"scrollbar",
|
|
63
|
+
"searchbox",
|
|
64
|
+
"slider",
|
|
65
|
+
"spinbutton",
|
|
66
|
+
"switch",
|
|
67
|
+
"tab",
|
|
68
|
+
"textbox",
|
|
69
|
+
"treeitem"
|
|
70
|
+
]);
|
|
71
|
+
function clickLandedOnControl(target, root) {
|
|
72
|
+
if (!(target instanceof Element) || !(root instanceof Element)) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
const native = target.closest(NATIVE_CONTROL_SELECTOR);
|
|
76
|
+
if (native !== null && root.contains(native)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
let node = target;
|
|
80
|
+
while (node !== null && node !== root && root.contains(node)) {
|
|
81
|
+
const role = node.getAttribute("role");
|
|
82
|
+
if (role !== null) {
|
|
83
|
+
for (const token of role.split(/\s+/)) {
|
|
84
|
+
if (INTERACTIVE_ARIA_ROLES.has(token)) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
node = node.parentElement;
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
function hasTrailingContent(node) {
|
|
94
|
+
return node != null && typeof node !== "boolean";
|
|
95
|
+
}
|
|
48
96
|
function DocumentRow({
|
|
49
97
|
name,
|
|
50
98
|
caption,
|
|
@@ -74,15 +122,12 @@ function DocumentRow({
|
|
|
74
122
|
children: /* @__PURE__ */ jsxRuntime.jsx(DefaultDocumentIcon, {})
|
|
75
123
|
}
|
|
76
124
|
);
|
|
77
|
-
const
|
|
125
|
+
const chevron = showChevron ? /* @__PURE__ */ jsxRuntime.jsx(layout.Box, { c: index.fairmintVars.colorTextTertiary, style: { display: "inline-flex" }, children: /* @__PURE__ */ jsxRuntime.jsx(DefaultChevronIcon, {}) }) : null;
|
|
126
|
+
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
78
127
|
/* @__PURE__ */ jsxRuntime.jsx(layout.Box, { style: { flexShrink: 0 }, children: leadingNode }),
|
|
79
128
|
/* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { gap: 2, style: { minWidth: 0, flex: 1 }, children: [
|
|
80
129
|
/* @__PURE__ */ jsxRuntime.jsx(Text.Text, { fw: 500, size: "sm", lineClamp: 1, children: name }),
|
|
81
130
|
resolvedCaption !== void 0 && resolvedCaption !== null && resolvedCaption !== "" ? typeof resolvedCaption === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Text.Text, { size: "xs", c: index.fairmintVars.colorTextSecondary, lineClamp: 1, children: resolvedCaption }) : resolvedCaption : null
|
|
82
|
-
] }),
|
|
83
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: "xs", wrap: "nowrap", style: { flexShrink: 0 }, children: [
|
|
84
|
-
rightSection,
|
|
85
|
-
showChevron && /* @__PURE__ */ jsxRuntime.jsx(layout.Box, { c: index.fairmintVars.colorTextTertiary, style: { display: "inline-flex" }, children: /* @__PURE__ */ jsxRuntime.jsx(DefaultChevronIcon, {}) })
|
|
86
131
|
] })
|
|
87
132
|
] });
|
|
88
133
|
const animationStyle = animate ? {
|
|
@@ -91,19 +136,51 @@ function DocumentRow({
|
|
|
91
136
|
animationDelay: `${animationDelay}s`
|
|
92
137
|
} : void 0;
|
|
93
138
|
if (!isClickable) {
|
|
94
|
-
return /* @__PURE__ */ jsxRuntime.jsx(layout.Box, { py: "sm", px: "md", style: animationStyle, children:
|
|
139
|
+
return /* @__PURE__ */ jsxRuntime.jsx(layout.Box, { py: "sm", px: "md", w: "100%", style: animationStyle, children: /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: "md", wrap: "nowrap", align: "center", children: [
|
|
140
|
+
body,
|
|
141
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: "xs", wrap: "nowrap", style: { flexShrink: 0 }, children: [
|
|
142
|
+
rightSection,
|
|
143
|
+
chevron
|
|
144
|
+
] })
|
|
145
|
+
] }) });
|
|
95
146
|
}
|
|
96
|
-
|
|
97
|
-
|
|
147
|
+
const handleShellClick = (event) => {
|
|
148
|
+
if (!(event.target instanceof Node) || !event.currentTarget.contains(event.target)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (clickLandedOnControl(event.target, event.currentTarget)) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
onClick?.();
|
|
155
|
+
};
|
|
156
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
157
|
+
Group.Group,
|
|
98
158
|
{
|
|
99
|
-
|
|
159
|
+
gap: "md",
|
|
160
|
+
wrap: "nowrap",
|
|
161
|
+
align: "center",
|
|
100
162
|
className: "fairmint-list-row",
|
|
101
163
|
w: "100%",
|
|
102
|
-
py: "sm",
|
|
103
|
-
px: "md",
|
|
104
164
|
style: animationStyle,
|
|
105
|
-
|
|
106
|
-
children:
|
|
165
|
+
onClick: handleShellClick,
|
|
166
|
+
children: [
|
|
167
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
168
|
+
UnstyledButton.UnstyledButton,
|
|
169
|
+
{
|
|
170
|
+
onClick,
|
|
171
|
+
py: "sm",
|
|
172
|
+
pl: "md",
|
|
173
|
+
pr: hasTrailingContent(rightSection) ? 0 : "md",
|
|
174
|
+
style: { flex: 1, minWidth: 0, display: "flex" },
|
|
175
|
+
"aria-label": ariaLabel ?? name,
|
|
176
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: "md", wrap: "nowrap", align: "center", style: { flex: 1, minWidth: 0 }, children: [
|
|
177
|
+
body,
|
|
178
|
+
chevron
|
|
179
|
+
] })
|
|
180
|
+
}
|
|
181
|
+
),
|
|
182
|
+
hasTrailingContent(rightSection) ? /* @__PURE__ */ jsxRuntime.jsx(Group.Group, { gap: "xs", wrap: "nowrap", py: "sm", pr: "md", style: { flexShrink: 0 }, children: typeof rightSection === "string" || typeof rightSection === "number" ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: rightSection }) : rightSection }) : null
|
|
183
|
+
]
|
|
107
184
|
}
|
|
108
185
|
);
|
|
109
186
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentRow.cjs","sources":["../../../../src/components/specific/DocumentRow/DocumentRow.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { formatDate } from \"../../../utils/format\";\nimport { Box, Group, Stack, Text, ThemeIcon, UnstyledButton } from \"../../primitives/layout\";\n\n/**\n * Default file-glyph SVG. Inlined so the library doesn't depend on\n * `@tabler/icons-react` (per the icon-injection rule). Consumers can\n * override the leading slot via the `icon` prop when a different glyph\n * (or a stacked badge) is more appropriate.\n */\nconst DefaultDocumentIcon = () => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\" />\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\" />\n <polyline points=\"10 9 9 9 8 9\" />\n </svg>\n);\n\nconst DefaultChevronIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n);\n\nexport interface DocumentRowProps {\n /** Primary title — usually the file or agreement name. */\n name: string;\n /**\n * Description below the title. Accepts a `ReactNode` so consumers can mix\n * Badges, Text, dates, and inline metadata (companyName, seriesName, etc.)\n * without working around a single-string subtitle slot.\n */\n caption?: ReactNode;\n /**\n * @deprecated Use `caption` directly. When `caption` is omitted and\n * `type` and/or `date` is supplied, they are joined with \" · \" to\n * produce a string caption. Preserved for backwards compatibility\n * with the previous, ListRow-backed API.\n */\n type?: string;\n /**\n * @deprecated Use `caption` directly. The date is now consumer-\n * formatted; pass a formatted string via `caption` instead. Preserved\n * for backwards compatibility.\n */\n date?: string;\n /**\n * Leading visual — defaults to a tinted file-icon `ThemeIcon`. Pass a\n * custom node (an icon, a badge, a small Avatar, etc.) when you want\n * a different leading affordance.\n */\n icon?: ReactNode;\n /** Right-side content — download button, lock badge, preview link, etc. */\n rightSection?: ReactNode;\n /**\n * Drill-in chevron. Defaults to `false` — the right-side glyph (a\n * download icon, a preview link, a status badge) usually conveys the\n * affordance and the chevron is visual noise. Set to `true` for \"row\n * that opens a detail view\" patterns.\n */\n showChevron?: boolean;\n /** Click handler. */\n onClick?: () => void;\n /** Entrance animation delay in seconds. Omit to skip animation. */\n animationDelay?: number;\n /** aria-label for the clickable wrapper. Defaults to `name`. */\n ariaLabel?: string;\n}\n\n/**\n * Document list item — title, free-form caption, optional leading icon,\n * optional right-side affordance, optional drill-in chevron.\n *\n * Designed against three real consumers (investorv2's `OpportunityDocuments`,\n * `SignSection` legal-doc list, and the mobile card view on `/documents`)\n * so the shape covers the actual patterns rather than an imagined one.\n *\n * Backwards-compat note: the previous `type` + `date` API still works.\n * When `caption` is omitted, the legacy props are joined with \" · \" into\n * a string caption.\n */\nexport function DocumentRow({\n name,\n caption,\n type,\n date,\n icon,\n rightSection,\n onClick,\n showChevron = false,\n animationDelay,\n ariaLabel,\n}: DocumentRowProps) {\n const isClickable = Boolean(onClick);\n const animate = animationDelay !== undefined;\n\n const resolvedCaption: ReactNode =\n caption ??\n (type || date\n ? [type, date ? formatDate(date) : undefined].filter(Boolean).join(\" · \")\n : undefined);\n\n const leadingNode = icon ?? (\n <ThemeIcon\n size={36}\n radius=\"md\"\n variant=\"light\"\n color={colors.primary}\n style={{\n backgroundColor: fairmintVars.colorBgBrandSubtle,\n color: fairmintVars.colorBrandPrimary,\n }}\n >\n <DefaultDocumentIcon />\n </ThemeIcon>\n );\n\n const content = (\n <Group gap=\"md\" wrap=\"nowrap\" align=\"center\">\n <Box style={{ flexShrink: 0 }}>{leadingNode}</Box>\n <Stack gap={2} style={{ minWidth: 0, flex: 1 }}>\n <Text fw={500} size=\"sm\" lineClamp={1}>\n {name}\n </Text>\n {resolvedCaption !== undefined && resolvedCaption !== null && resolvedCaption !== \"\" ? (\n typeof resolvedCaption === \"string\" ? (\n <Text size=\"xs\" c={fairmintVars.colorTextSecondary} lineClamp={1}>\n {resolvedCaption}\n </Text>\n ) : (\n resolvedCaption\n )\n ) : null}\n </Stack>\n <Group gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n {rightSection}\n {showChevron && (\n <Box c={fairmintVars.colorTextTertiary} style={{ display: \"inline-flex\" }}>\n <DefaultChevronIcon />\n </Box>\n )}\n </Group>\n </Group>\n );\n\n const animationStyle = animate\n ? ({\n opacity: 0 as const,\n animation: \"rowSlideIn 0.35s cubic-bezier(0.22, 1, 0.36, 1) forwards\",\n animationDelay: `${animationDelay}s`,\n } as const)\n : undefined;\n\n if (!isClickable) {\n return (\n <Box py=\"sm\" px=\"md\" style={animationStyle}>\n {content}\n </Box>\n );\n }\n\n return (\n <UnstyledButton\n onClick={onClick}\n className=\"fairmint-list-row\"\n w=\"100%\"\n py=\"sm\"\n px=\"md\"\n style={animationStyle}\n aria-label={ariaLabel ?? name}\n >\n {content}\n </UnstyledButton>\n );\n}\n"],"names":["jsxs","jsx","formatDate","ThemeIcon","colors","fairmintVars","Group","Box","Stack","Text","UnstyledButton"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DocumentRow.cjs","sources":["../../../../src/components/specific/DocumentRow/DocumentRow.tsx"],"sourcesContent":["import type { MouseEvent, ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { formatDate } from \"../../../utils/format\";\nimport { Box, Group, Stack, Text, ThemeIcon, UnstyledButton } from \"../../primitives/layout\";\n\n/**\n * Default file-glyph SVG. Inlined so the library doesn't depend on\n * `@tabler/icons-react` (per the icon-injection rule). Consumers can\n * override the leading slot via the `icon` prop when a different glyph\n * (or a stacked badge) is more appropriate.\n */\nconst DefaultDocumentIcon = () => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\" />\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\" />\n <polyline points=\"10 9 9 9 8 9\" />\n </svg>\n);\n\nconst DefaultChevronIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n);\n\nconst NATIVE_CONTROL_SELECTOR =\n \"a, button, input, select, textarea, label, summary, [contenteditable]:not([contenteditable='false'])\";\n\nconst INTERACTIVE_ARIA_ROLES = new Set([\n \"button\",\n \"checkbox\",\n \"combobox\",\n \"gridcell\",\n \"link\",\n \"listbox\",\n \"menu\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"radio\",\n \"scrollbar\",\n \"searchbox\",\n \"slider\",\n \"spinbutton\",\n \"switch\",\n \"tab\",\n \"textbox\",\n \"treeitem\",\n]);\n\nfunction clickLandedOnControl(target: EventTarget | null, root: EventTarget): boolean {\n if (!(target instanceof Element) || !(root instanceof Element)) {\n return false;\n }\n const native = target.closest(NATIVE_CONTROL_SELECTOR);\n if (native !== null && root.contains(native)) {\n return true;\n }\n let node: Element | null = target;\n while (node !== null && node !== root && root.contains(node)) {\n const role = node.getAttribute(\"role\");\n if (role !== null) {\n for (const token of role.split(/\\s+/)) {\n if (INTERACTIVE_ARIA_ROLES.has(token)) {\n return true;\n }\n }\n }\n node = node.parentElement;\n }\n return false;\n}\n\nfunction hasTrailingContent(node: ReactNode): boolean {\n return node != null && typeof node !== \"boolean\";\n}\n\nexport interface DocumentRowProps {\n /** Primary title — usually the file or agreement name. */\n name: string;\n /**\n * Description below the title. Accepts a `ReactNode` so consumers can mix\n * Badges, Text, dates, and inline metadata (companyName, seriesName, etc.)\n * without working around a single-string subtitle slot.\n */\n caption?: ReactNode;\n /**\n * @deprecated Use `caption` directly. When `caption` is omitted and\n * `type` and/or `date` is supplied, they are joined with \" · \" to\n * produce a string caption. Preserved for backwards compatibility\n * with the previous, ListRow-backed API.\n */\n type?: string;\n /**\n * @deprecated Use `caption` directly. The date is now consumer-\n * formatted; pass a formatted string via `caption` instead. Preserved\n * for backwards compatibility.\n */\n date?: string;\n /**\n * Leading visual — defaults to a tinted file-icon `ThemeIcon`. Pass a\n * custom node (an icon, a badge, a small Avatar, etc.) when you want\n * a different leading affordance.\n */\n icon?: ReactNode;\n /**\n * Right-side content — download button, lock badge, preview link, etc.\n *\n * On a clickable row this is a sibling of the row button (never nested).\n * Clicks on decorative trailing content still fire `onClick`; clicks on\n * buttons, links, and other controls do not.\n */\n rightSection?: ReactNode;\n /**\n * Drill-in chevron. Defaults to `false` — the right-side glyph (a\n * download icon, a preview link, a status badge) usually conveys the\n * affordance and the chevron is visual noise. Set to `true` for \"row\n * that opens a detail view\" patterns.\n */\n showChevron?: boolean;\n /** Click handler. */\n onClick?: () => void;\n /** Entrance animation delay in seconds. Omit to skip animation. */\n animationDelay?: number;\n /** aria-label for the clickable wrapper. Defaults to `name`. */\n ariaLabel?: string;\n}\n\n/**\n * Document list item — title, free-form caption, optional leading icon,\n * optional right-side affordance, optional drill-in chevron.\n *\n * Designed against three real consumers (investorv2's `OpportunityDocuments`,\n * `SignSection` legal-doc list, and the mobile card view on `/documents`)\n * so the shape covers the actual patterns rather than an imagined one.\n *\n * Backwards-compat note: the previous `type` + `date` API still works.\n * When `caption` is omitted, the legacy props are joined with \" · \" into\n * a string caption.\n */\nexport function DocumentRow({\n name,\n caption,\n type,\n date,\n icon,\n rightSection,\n onClick,\n showChevron = false,\n animationDelay,\n ariaLabel,\n}: DocumentRowProps) {\n const isClickable = Boolean(onClick);\n const animate = animationDelay !== undefined;\n\n const resolvedCaption: ReactNode =\n caption ??\n (type || date\n ? [type, date ? formatDate(date) : undefined].filter(Boolean).join(\" · \")\n : undefined);\n\n const leadingNode = icon ?? (\n <ThemeIcon\n size={36}\n radius=\"md\"\n variant=\"light\"\n color={colors.primary}\n style={{\n backgroundColor: fairmintVars.colorBgBrandSubtle,\n color: fairmintVars.colorBrandPrimary,\n }}\n >\n <DefaultDocumentIcon />\n </ThemeIcon>\n );\n\n const chevron = showChevron ? (\n <Box c={fairmintVars.colorTextTertiary} style={{ display: \"inline-flex\" }}>\n <DefaultChevronIcon />\n </Box>\n ) : null;\n\n // Leading icon + name/caption. On a clickable row this sits in the button\n // with padding and the optional chevron; `rightSection` is a sibling.\n const body = (\n <>\n <Box style={{ flexShrink: 0 }}>{leadingNode}</Box>\n <Stack gap={2} style={{ minWidth: 0, flex: 1 }}>\n <Text fw={500} size=\"sm\" lineClamp={1}>\n {name}\n </Text>\n {resolvedCaption !== undefined && resolvedCaption !== null && resolvedCaption !== \"\" ? (\n typeof resolvedCaption === \"string\" ? (\n <Text size=\"xs\" c={fairmintVars.colorTextSecondary} lineClamp={1}>\n {resolvedCaption}\n </Text>\n ) : (\n resolvedCaption\n )\n ) : null}\n </Stack>\n </>\n );\n\n const animationStyle = animate\n ? ({\n opacity: 0 as const,\n animation: \"rowSlideIn 0.35s cubic-bezier(0.22, 1, 0.36, 1) forwards\",\n animationDelay: `${animationDelay}s`,\n } as const)\n : undefined;\n\n if (!isClickable) {\n return (\n <Box py=\"sm\" px=\"md\" w=\"100%\" style={animationStyle}>\n <Group gap=\"md\" wrap=\"nowrap\" align=\"center\">\n {body}\n <Group gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n {rightSection}\n {chevron}\n </Group>\n </Group>\n </Box>\n );\n }\n\n const handleShellClick = (event: MouseEvent<HTMLDivElement>) => {\n if (!(event.target instanceof Node) || !event.currentTarget.contains(event.target)) {\n return;\n }\n if (clickLandedOnControl(event.target, event.currentTarget)) {\n return;\n }\n onClick?.();\n };\n\n // Primary button: padding, body, chevron. `rightSection` is always a sibling\n // so trailing controls never nest. Shell clicks (gap, decorative trailers)\n // still fire `onClick`. `fairmint-list-row` is only on the shell.\n return (\n <Group\n gap=\"md\"\n wrap=\"nowrap\"\n align=\"center\"\n className=\"fairmint-list-row\"\n w=\"100%\"\n style={animationStyle}\n onClick={handleShellClick}\n >\n <UnstyledButton\n onClick={onClick}\n py=\"sm\"\n pl=\"md\"\n pr={hasTrailingContent(rightSection) ? 0 : \"md\"}\n style={{ flex: 1, minWidth: 0, display: \"flex\" }}\n aria-label={ariaLabel ?? name}\n >\n <Group gap=\"md\" wrap=\"nowrap\" align=\"center\" style={{ flex: 1, minWidth: 0 }}>\n {body}\n {chevron}\n </Group>\n </UnstyledButton>\n {hasTrailingContent(rightSection) ? (\n <Group gap=\"xs\" wrap=\"nowrap\" py=\"sm\" pr=\"md\" style={{ flexShrink: 0 }}>\n {typeof rightSection === \"string\" || typeof rightSection === \"number\" ? (\n <span>{rightSection}</span>\n ) : (\n rightSection\n )}\n </Group>\n ) : null}\n </Group>\n );\n}\n"],"names":["jsxs","jsx","formatDate","ThemeIcon","colors","fairmintVars","Box","Fragment","Stack","Text","Group","UnstyledButton"],"mappings":"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"}
|
|
@@ -27,7 +27,13 @@ export interface DocumentRowProps {
|
|
|
27
27
|
* a different leading affordance.
|
|
28
28
|
*/
|
|
29
29
|
icon?: ReactNode;
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Right-side content — download button, lock badge, preview link, etc.
|
|
32
|
+
*
|
|
33
|
+
* On a clickable row this is a sibling of the row button (never nested).
|
|
34
|
+
* Clicks on decorative trailing content still fire `onClick`; clicks on
|
|
35
|
+
* buttons, links, and other controls do not.
|
|
36
|
+
*/
|
|
31
37
|
rightSection?: ReactNode;
|
|
32
38
|
/**
|
|
33
39
|
* Drill-in chevron. Defaults to `false` — the right-side glyph (a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentRow.d.ts","sourceRoot":"","sources":["../../../../src/components/specific/DocumentRow/DocumentRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"DocumentRow.d.ts","sourceRoot":"","sources":["../../../../src/components/specific/DocumentRow/DocumentRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAC;AAqGnD,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,WAAmB,EACnB,cAAc,EACd,SAAS,GACV,EAAE,gBAAgB,+BA0HlB"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { fairmintVars } from "../../../theme/index.js";
|
|
3
3
|
import { colors } from "../../../theme/colors.js";
|
|
4
4
|
import { formatDate } from "../../../utils/format.js";
|
|
5
5
|
import { Box, Stack } from "../../primitives/layout.js";
|
|
6
6
|
import { ThemeIcon } from "../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.js";
|
|
7
|
+
import { Text } from "../../primitives/Text/Text.js";
|
|
7
8
|
import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
|
|
8
|
-
import { Text } from "../../../node_modules/@mantine/core/esm/components/Text/Text.js";
|
|
9
9
|
import { UnstyledButton } from "../../../node_modules/@mantine/core/esm/components/UnstyledButton/UnstyledButton.js";
|
|
10
10
|
const DefaultDocumentIcon = () => /* @__PURE__ */ jsxs(
|
|
11
11
|
"svg",
|
|
@@ -43,6 +43,54 @@ const DefaultChevronIcon = () => /* @__PURE__ */ jsx(
|
|
|
43
43
|
children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" })
|
|
44
44
|
}
|
|
45
45
|
);
|
|
46
|
+
const NATIVE_CONTROL_SELECTOR = "a, button, input, select, textarea, label, summary, [contenteditable]:not([contenteditable='false'])";
|
|
47
|
+
const INTERACTIVE_ARIA_ROLES = /* @__PURE__ */ new Set([
|
|
48
|
+
"button",
|
|
49
|
+
"checkbox",
|
|
50
|
+
"combobox",
|
|
51
|
+
"gridcell",
|
|
52
|
+
"link",
|
|
53
|
+
"listbox",
|
|
54
|
+
"menu",
|
|
55
|
+
"menuitem",
|
|
56
|
+
"menuitemcheckbox",
|
|
57
|
+
"menuitemradio",
|
|
58
|
+
"option",
|
|
59
|
+
"radio",
|
|
60
|
+
"scrollbar",
|
|
61
|
+
"searchbox",
|
|
62
|
+
"slider",
|
|
63
|
+
"spinbutton",
|
|
64
|
+
"switch",
|
|
65
|
+
"tab",
|
|
66
|
+
"textbox",
|
|
67
|
+
"treeitem"
|
|
68
|
+
]);
|
|
69
|
+
function clickLandedOnControl(target, root) {
|
|
70
|
+
if (!(target instanceof Element) || !(root instanceof Element)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const native = target.closest(NATIVE_CONTROL_SELECTOR);
|
|
74
|
+
if (native !== null && root.contains(native)) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
let node = target;
|
|
78
|
+
while (node !== null && node !== root && root.contains(node)) {
|
|
79
|
+
const role = node.getAttribute("role");
|
|
80
|
+
if (role !== null) {
|
|
81
|
+
for (const token of role.split(/\s+/)) {
|
|
82
|
+
if (INTERACTIVE_ARIA_ROLES.has(token)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
node = node.parentElement;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
function hasTrailingContent(node) {
|
|
92
|
+
return node != null && typeof node !== "boolean";
|
|
93
|
+
}
|
|
46
94
|
function DocumentRow({
|
|
47
95
|
name,
|
|
48
96
|
caption,
|
|
@@ -72,15 +120,12 @@ function DocumentRow({
|
|
|
72
120
|
children: /* @__PURE__ */ jsx(DefaultDocumentIcon, {})
|
|
73
121
|
}
|
|
74
122
|
);
|
|
75
|
-
const
|
|
123
|
+
const chevron = showChevron ? /* @__PURE__ */ jsx(Box, { c: fairmintVars.colorTextTertiary, style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx(DefaultChevronIcon, {}) }) : null;
|
|
124
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
76
125
|
/* @__PURE__ */ jsx(Box, { style: { flexShrink: 0 }, children: leadingNode }),
|
|
77
126
|
/* @__PURE__ */ jsxs(Stack, { gap: 2, style: { minWidth: 0, flex: 1 }, children: [
|
|
78
127
|
/* @__PURE__ */ jsx(Text, { fw: 500, size: "sm", lineClamp: 1, children: name }),
|
|
79
128
|
resolvedCaption !== void 0 && resolvedCaption !== null && resolvedCaption !== "" ? typeof resolvedCaption === "string" ? /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, lineClamp: 1, children: resolvedCaption }) : resolvedCaption : null
|
|
80
|
-
] }),
|
|
81
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { flexShrink: 0 }, children: [
|
|
82
|
-
rightSection,
|
|
83
|
-
showChevron && /* @__PURE__ */ jsx(Box, { c: fairmintVars.colorTextTertiary, style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx(DefaultChevronIcon, {}) })
|
|
84
129
|
] })
|
|
85
130
|
] });
|
|
86
131
|
const animationStyle = animate ? {
|
|
@@ -89,19 +134,51 @@ function DocumentRow({
|
|
|
89
134
|
animationDelay: `${animationDelay}s`
|
|
90
135
|
} : void 0;
|
|
91
136
|
if (!isClickable) {
|
|
92
|
-
return /* @__PURE__ */ jsx(Box, { py: "sm", px: "md", style: animationStyle, children:
|
|
137
|
+
return /* @__PURE__ */ jsx(Box, { py: "sm", px: "md", w: "100%", style: animationStyle, children: /* @__PURE__ */ jsxs(Group, { gap: "md", wrap: "nowrap", align: "center", children: [
|
|
138
|
+
body,
|
|
139
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", style: { flexShrink: 0 }, children: [
|
|
140
|
+
rightSection,
|
|
141
|
+
chevron
|
|
142
|
+
] })
|
|
143
|
+
] }) });
|
|
93
144
|
}
|
|
94
|
-
|
|
95
|
-
|
|
145
|
+
const handleShellClick = (event) => {
|
|
146
|
+
if (!(event.target instanceof Node) || !event.currentTarget.contains(event.target)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (clickLandedOnControl(event.target, event.currentTarget)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
onClick?.();
|
|
153
|
+
};
|
|
154
|
+
return /* @__PURE__ */ jsxs(
|
|
155
|
+
Group,
|
|
96
156
|
{
|
|
97
|
-
|
|
157
|
+
gap: "md",
|
|
158
|
+
wrap: "nowrap",
|
|
159
|
+
align: "center",
|
|
98
160
|
className: "fairmint-list-row",
|
|
99
161
|
w: "100%",
|
|
100
|
-
py: "sm",
|
|
101
|
-
px: "md",
|
|
102
162
|
style: animationStyle,
|
|
103
|
-
|
|
104
|
-
children:
|
|
163
|
+
onClick: handleShellClick,
|
|
164
|
+
children: [
|
|
165
|
+
/* @__PURE__ */ jsx(
|
|
166
|
+
UnstyledButton,
|
|
167
|
+
{
|
|
168
|
+
onClick,
|
|
169
|
+
py: "sm",
|
|
170
|
+
pl: "md",
|
|
171
|
+
pr: hasTrailingContent(rightSection) ? 0 : "md",
|
|
172
|
+
style: { flex: 1, minWidth: 0, display: "flex" },
|
|
173
|
+
"aria-label": ariaLabel ?? name,
|
|
174
|
+
children: /* @__PURE__ */ jsxs(Group, { gap: "md", wrap: "nowrap", align: "center", style: { flex: 1, minWidth: 0 }, children: [
|
|
175
|
+
body,
|
|
176
|
+
chevron
|
|
177
|
+
] })
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
hasTrailingContent(rightSection) ? /* @__PURE__ */ jsx(Group, { gap: "xs", wrap: "nowrap", py: "sm", pr: "md", style: { flexShrink: 0 }, children: typeof rightSection === "string" || typeof rightSection === "number" ? /* @__PURE__ */ jsx("span", { children: rightSection }) : rightSection }) : null
|
|
181
|
+
]
|
|
105
182
|
}
|
|
106
183
|
);
|
|
107
184
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentRow.js","sources":["../../../../src/components/specific/DocumentRow/DocumentRow.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { formatDate } from \"../../../utils/format\";\nimport { Box, Group, Stack, Text, ThemeIcon, UnstyledButton } from \"../../primitives/layout\";\n\n/**\n * Default file-glyph SVG. Inlined so the library doesn't depend on\n * `@tabler/icons-react` (per the icon-injection rule). Consumers can\n * override the leading slot via the `icon` prop when a different glyph\n * (or a stacked badge) is more appropriate.\n */\nconst DefaultDocumentIcon = () => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\" />\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\" />\n <polyline points=\"10 9 9 9 8 9\" />\n </svg>\n);\n\nconst DefaultChevronIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n);\n\nexport interface DocumentRowProps {\n /** Primary title — usually the file or agreement name. */\n name: string;\n /**\n * Description below the title. Accepts a `ReactNode` so consumers can mix\n * Badges, Text, dates, and inline metadata (companyName, seriesName, etc.)\n * without working around a single-string subtitle slot.\n */\n caption?: ReactNode;\n /**\n * @deprecated Use `caption` directly. When `caption` is omitted and\n * `type` and/or `date` is supplied, they are joined with \" · \" to\n * produce a string caption. Preserved for backwards compatibility\n * with the previous, ListRow-backed API.\n */\n type?: string;\n /**\n * @deprecated Use `caption` directly. The date is now consumer-\n * formatted; pass a formatted string via `caption` instead. Preserved\n * for backwards compatibility.\n */\n date?: string;\n /**\n * Leading visual — defaults to a tinted file-icon `ThemeIcon`. Pass a\n * custom node (an icon, a badge, a small Avatar, etc.) when you want\n * a different leading affordance.\n */\n icon?: ReactNode;\n /** Right-side content — download button, lock badge, preview link, etc. */\n rightSection?: ReactNode;\n /**\n * Drill-in chevron. Defaults to `false` — the right-side glyph (a\n * download icon, a preview link, a status badge) usually conveys the\n * affordance and the chevron is visual noise. Set to `true` for \"row\n * that opens a detail view\" patterns.\n */\n showChevron?: boolean;\n /** Click handler. */\n onClick?: () => void;\n /** Entrance animation delay in seconds. Omit to skip animation. */\n animationDelay?: number;\n /** aria-label for the clickable wrapper. Defaults to `name`. */\n ariaLabel?: string;\n}\n\n/**\n * Document list item — title, free-form caption, optional leading icon,\n * optional right-side affordance, optional drill-in chevron.\n *\n * Designed against three real consumers (investorv2's `OpportunityDocuments`,\n * `SignSection` legal-doc list, and the mobile card view on `/documents`)\n * so the shape covers the actual patterns rather than an imagined one.\n *\n * Backwards-compat note: the previous `type` + `date` API still works.\n * When `caption` is omitted, the legacy props are joined with \" · \" into\n * a string caption.\n */\nexport function DocumentRow({\n name,\n caption,\n type,\n date,\n icon,\n rightSection,\n onClick,\n showChevron = false,\n animationDelay,\n ariaLabel,\n}: DocumentRowProps) {\n const isClickable = Boolean(onClick);\n const animate = animationDelay !== undefined;\n\n const resolvedCaption: ReactNode =\n caption ??\n (type || date\n ? [type, date ? formatDate(date) : undefined].filter(Boolean).join(\" · \")\n : undefined);\n\n const leadingNode = icon ?? (\n <ThemeIcon\n size={36}\n radius=\"md\"\n variant=\"light\"\n color={colors.primary}\n style={{\n backgroundColor: fairmintVars.colorBgBrandSubtle,\n color: fairmintVars.colorBrandPrimary,\n }}\n >\n <DefaultDocumentIcon />\n </ThemeIcon>\n );\n\n const content = (\n <Group gap=\"md\" wrap=\"nowrap\" align=\"center\">\n <Box style={{ flexShrink: 0 }}>{leadingNode}</Box>\n <Stack gap={2} style={{ minWidth: 0, flex: 1 }}>\n <Text fw={500} size=\"sm\" lineClamp={1}>\n {name}\n </Text>\n {resolvedCaption !== undefined && resolvedCaption !== null && resolvedCaption !== \"\" ? (\n typeof resolvedCaption === \"string\" ? (\n <Text size=\"xs\" c={fairmintVars.colorTextSecondary} lineClamp={1}>\n {resolvedCaption}\n </Text>\n ) : (\n resolvedCaption\n )\n ) : null}\n </Stack>\n <Group gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n {rightSection}\n {showChevron && (\n <Box c={fairmintVars.colorTextTertiary} style={{ display: \"inline-flex\" }}>\n <DefaultChevronIcon />\n </Box>\n )}\n </Group>\n </Group>\n );\n\n const animationStyle = animate\n ? ({\n opacity: 0 as const,\n animation: \"rowSlideIn 0.35s cubic-bezier(0.22, 1, 0.36, 1) forwards\",\n animationDelay: `${animationDelay}s`,\n } as const)\n : undefined;\n\n if (!isClickable) {\n return (\n <Box py=\"sm\" px=\"md\" style={animationStyle}>\n {content}\n </Box>\n );\n }\n\n return (\n <UnstyledButton\n onClick={onClick}\n className=\"fairmint-list-row\"\n w=\"100%\"\n py=\"sm\"\n px=\"md\"\n style={animationStyle}\n aria-label={ariaLabel ?? name}\n >\n {content}\n </UnstyledButton>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,MAAM,sBAAsB,MAC1B;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IAEZ,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAK,GAAE,6DAAA,CAA6D;AAAA,MACrE,oBAAC,YAAA,EAAS,QAAO,iBAAA,CAAiB;AAAA,MAClC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAA,CAAK;AAAA,MACrC,oBAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAA,CAAK;AAAA,MACrC,oBAAC,YAAA,EAAS,QAAO,eAAA,CAAe;AAAA,IAAA;AAAA,EAAA;AAClC;AAGF,MAAM,qBAAqB,MACzB;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAY;AAAA,IAEZ,UAAA,oBAAC,QAAA,EAAK,GAAE,gBAAA,CAAgB;AAAA,EAAA;AAC1B;AA4DK,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,cAAc,QAAQ,OAAO;AACnC,QAAM,UAAU,mBAAmB;AAEnC,QAAM,kBACJ,YACC,QAAQ,OACL,CAAC,MAAM,OAAO,WAAW,IAAI,IAAI,MAAS,EAAE,OAAO,OAAO,EAAE,KAAK,KAAK,IACtE;AAEN,QAAM,cAAc,QAClB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,OAAO,OAAO;AAAA,MACd,OAAO;AAAA,QACL,iBAAiB,aAAa;AAAA,QAC9B,OAAO,aAAa;AAAA,MAAA;AAAA,MAGtB,8BAAC,qBAAA,CAAA,CAAoB;AAAA,IAAA;AAAA,EAAA;AAIzB,QAAM,+BACH,OAAA,EAAM,KAAI,MAAK,MAAK,UAAS,OAAM,UAClC,UAAA;AAAA,IAAA,oBAAC,OAAI,OAAO,EAAE,YAAY,EAAA,GAAM,UAAA,aAAY;AAAA,IAC5C,qBAAC,OAAA,EAAM,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,MAAM,EAAA,GACzC,UAAA;AAAA,MAAA,oBAAC,QAAK,IAAI,KAAK,MAAK,MAAK,WAAW,GACjC,UAAA,KAAA,CACH;AAAA,MACC,oBAAoB,UAAa,oBAAoB,QAAQ,oBAAoB,KAChF,OAAO,oBAAoB,WACzB,oBAAC,QAAK,MAAK,MAAK,GAAG,aAAa,oBAAoB,WAAW,GAC5D,UAAA,iBACH,IAEA,kBAEA;AAAA,IAAA,GACN;AAAA,IACA,qBAAC,OAAA,EAAM,KAAI,MAAK,MAAK,UAAS,OAAO,EAAE,YAAY,EAAA,GAChD,UAAA;AAAA,MAAA;AAAA,MACA,eACC,oBAAC,KAAA,EAAI,GAAG,aAAa,mBAAmB,OAAO,EAAE,SAAS,cAAA,GACxD,UAAA,oBAAC,sBAAmB,EAAA,CACtB;AAAA,IAAA,EAAA,CAEJ;AAAA,EAAA,GACF;AAGF,QAAM,iBAAiB,UAClB;AAAA,IACC,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB,GAAG,cAAc;AAAA,EAAA,IAEnC;AAEJ,MAAI,CAAC,aAAa;AAChB,WACE,oBAAC,OAAI,IAAG,MAAK,IAAG,MAAK,OAAO,gBACzB,UAAA,QAAA,CACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,WAAU;AAAA,MACV,GAAE;AAAA,MACF,IAAG;AAAA,MACH,IAAG;AAAA,MACH,OAAO;AAAA,MACP,cAAY,aAAa;AAAA,MAExB,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
|
1
|
+
{"version":3,"file":"DocumentRow.js","sources":["../../../../src/components/specific/DocumentRow/DocumentRow.tsx"],"sourcesContent":["import type { MouseEvent, ReactNode } from \"react\";\nimport { fairmintVars } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { formatDate } from \"../../../utils/format\";\nimport { Box, Group, Stack, Text, ThemeIcon, UnstyledButton } from \"../../primitives/layout\";\n\n/**\n * Default file-glyph SVG. Inlined so the library doesn't depend on\n * `@tabler/icons-react` (per the icon-injection rule). Consumers can\n * override the leading slot via the `icon` prop when a different glyph\n * (or a stacked badge) is more appropriate.\n */\nconst DefaultDocumentIcon = () => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\" />\n <line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\" />\n <polyline points=\"10 9 9 9 8 9\" />\n </svg>\n);\n\nconst DefaultChevronIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n);\n\nconst NATIVE_CONTROL_SELECTOR =\n \"a, button, input, select, textarea, label, summary, [contenteditable]:not([contenteditable='false'])\";\n\nconst INTERACTIVE_ARIA_ROLES = new Set([\n \"button\",\n \"checkbox\",\n \"combobox\",\n \"gridcell\",\n \"link\",\n \"listbox\",\n \"menu\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"option\",\n \"radio\",\n \"scrollbar\",\n \"searchbox\",\n \"slider\",\n \"spinbutton\",\n \"switch\",\n \"tab\",\n \"textbox\",\n \"treeitem\",\n]);\n\nfunction clickLandedOnControl(target: EventTarget | null, root: EventTarget): boolean {\n if (!(target instanceof Element) || !(root instanceof Element)) {\n return false;\n }\n const native = target.closest(NATIVE_CONTROL_SELECTOR);\n if (native !== null && root.contains(native)) {\n return true;\n }\n let node: Element | null = target;\n while (node !== null && node !== root && root.contains(node)) {\n const role = node.getAttribute(\"role\");\n if (role !== null) {\n for (const token of role.split(/\\s+/)) {\n if (INTERACTIVE_ARIA_ROLES.has(token)) {\n return true;\n }\n }\n }\n node = node.parentElement;\n }\n return false;\n}\n\nfunction hasTrailingContent(node: ReactNode): boolean {\n return node != null && typeof node !== \"boolean\";\n}\n\nexport interface DocumentRowProps {\n /** Primary title — usually the file or agreement name. */\n name: string;\n /**\n * Description below the title. Accepts a `ReactNode` so consumers can mix\n * Badges, Text, dates, and inline metadata (companyName, seriesName, etc.)\n * without working around a single-string subtitle slot.\n */\n caption?: ReactNode;\n /**\n * @deprecated Use `caption` directly. When `caption` is omitted and\n * `type` and/or `date` is supplied, they are joined with \" · \" to\n * produce a string caption. Preserved for backwards compatibility\n * with the previous, ListRow-backed API.\n */\n type?: string;\n /**\n * @deprecated Use `caption` directly. The date is now consumer-\n * formatted; pass a formatted string via `caption` instead. Preserved\n * for backwards compatibility.\n */\n date?: string;\n /**\n * Leading visual — defaults to a tinted file-icon `ThemeIcon`. Pass a\n * custom node (an icon, a badge, a small Avatar, etc.) when you want\n * a different leading affordance.\n */\n icon?: ReactNode;\n /**\n * Right-side content — download button, lock badge, preview link, etc.\n *\n * On a clickable row this is a sibling of the row button (never nested).\n * Clicks on decorative trailing content still fire `onClick`; clicks on\n * buttons, links, and other controls do not.\n */\n rightSection?: ReactNode;\n /**\n * Drill-in chevron. Defaults to `false` — the right-side glyph (a\n * download icon, a preview link, a status badge) usually conveys the\n * affordance and the chevron is visual noise. Set to `true` for \"row\n * that opens a detail view\" patterns.\n */\n showChevron?: boolean;\n /** Click handler. */\n onClick?: () => void;\n /** Entrance animation delay in seconds. Omit to skip animation. */\n animationDelay?: number;\n /** aria-label for the clickable wrapper. Defaults to `name`. */\n ariaLabel?: string;\n}\n\n/**\n * Document list item — title, free-form caption, optional leading icon,\n * optional right-side affordance, optional drill-in chevron.\n *\n * Designed against three real consumers (investorv2's `OpportunityDocuments`,\n * `SignSection` legal-doc list, and the mobile card view on `/documents`)\n * so the shape covers the actual patterns rather than an imagined one.\n *\n * Backwards-compat note: the previous `type` + `date` API still works.\n * When `caption` is omitted, the legacy props are joined with \" · \" into\n * a string caption.\n */\nexport function DocumentRow({\n name,\n caption,\n type,\n date,\n icon,\n rightSection,\n onClick,\n showChevron = false,\n animationDelay,\n ariaLabel,\n}: DocumentRowProps) {\n const isClickable = Boolean(onClick);\n const animate = animationDelay !== undefined;\n\n const resolvedCaption: ReactNode =\n caption ??\n (type || date\n ? [type, date ? formatDate(date) : undefined].filter(Boolean).join(\" · \")\n : undefined);\n\n const leadingNode = icon ?? (\n <ThemeIcon\n size={36}\n radius=\"md\"\n variant=\"light\"\n color={colors.primary}\n style={{\n backgroundColor: fairmintVars.colorBgBrandSubtle,\n color: fairmintVars.colorBrandPrimary,\n }}\n >\n <DefaultDocumentIcon />\n </ThemeIcon>\n );\n\n const chevron = showChevron ? (\n <Box c={fairmintVars.colorTextTertiary} style={{ display: \"inline-flex\" }}>\n <DefaultChevronIcon />\n </Box>\n ) : null;\n\n // Leading icon + name/caption. On a clickable row this sits in the button\n // with padding and the optional chevron; `rightSection` is a sibling.\n const body = (\n <>\n <Box style={{ flexShrink: 0 }}>{leadingNode}</Box>\n <Stack gap={2} style={{ minWidth: 0, flex: 1 }}>\n <Text fw={500} size=\"sm\" lineClamp={1}>\n {name}\n </Text>\n {resolvedCaption !== undefined && resolvedCaption !== null && resolvedCaption !== \"\" ? (\n typeof resolvedCaption === \"string\" ? (\n <Text size=\"xs\" c={fairmintVars.colorTextSecondary} lineClamp={1}>\n {resolvedCaption}\n </Text>\n ) : (\n resolvedCaption\n )\n ) : null}\n </Stack>\n </>\n );\n\n const animationStyle = animate\n ? ({\n opacity: 0 as const,\n animation: \"rowSlideIn 0.35s cubic-bezier(0.22, 1, 0.36, 1) forwards\",\n animationDelay: `${animationDelay}s`,\n } as const)\n : undefined;\n\n if (!isClickable) {\n return (\n <Box py=\"sm\" px=\"md\" w=\"100%\" style={animationStyle}>\n <Group gap=\"md\" wrap=\"nowrap\" align=\"center\">\n {body}\n <Group gap=\"xs\" wrap=\"nowrap\" style={{ flexShrink: 0 }}>\n {rightSection}\n {chevron}\n </Group>\n </Group>\n </Box>\n );\n }\n\n const handleShellClick = (event: MouseEvent<HTMLDivElement>) => {\n if (!(event.target instanceof Node) || !event.currentTarget.contains(event.target)) {\n return;\n }\n if (clickLandedOnControl(event.target, event.currentTarget)) {\n return;\n }\n onClick?.();\n };\n\n // Primary button: padding, body, chevron. `rightSection` is always a sibling\n // so trailing controls never nest. Shell clicks (gap, decorative trailers)\n // still fire `onClick`. `fairmint-list-row` is only on the shell.\n return (\n <Group\n gap=\"md\"\n wrap=\"nowrap\"\n align=\"center\"\n className=\"fairmint-list-row\"\n w=\"100%\"\n style={animationStyle}\n onClick={handleShellClick}\n >\n <UnstyledButton\n onClick={onClick}\n py=\"sm\"\n pl=\"md\"\n pr={hasTrailingContent(rightSection) ? 0 : \"md\"}\n style={{ flex: 1, minWidth: 0, display: \"flex\" }}\n aria-label={ariaLabel ?? name}\n >\n <Group gap=\"md\" wrap=\"nowrap\" align=\"center\" style={{ flex: 1, minWidth: 0 }}>\n {body}\n {chevron}\n </Group>\n </UnstyledButton>\n {hasTrailingContent(rightSection) ? (\n <Group gap=\"xs\" wrap=\"nowrap\" py=\"sm\" pr=\"md\" style={{ flexShrink: 0 }}>\n {typeof rightSection === \"string\" || typeof rightSection === \"number\" ? (\n <span>{rightSection}</span>\n ) : (\n rightSection\n )}\n </Group>\n ) : null}\n </Group>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ const Loader = require("../../primitives/Loader/Loader.cjs");
|
|
|
10
10
|
const layout = require("../../primitives/layout.cjs");
|
|
11
11
|
const Tooltip = require("../../primitives/Tooltip/Tooltip.cjs");
|
|
12
12
|
const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
|
|
13
|
-
const Text = require("
|
|
13
|
+
const Text = require("../../primitives/Text/Text.cjs");
|
|
14
14
|
function DefaultPencilIcon() {
|
|
15
15
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16
16
|
"svg",
|
|
@@ -8,7 +8,7 @@ import { Loader } from "../../primitives/Loader/Loader.js";
|
|
|
8
8
|
import { Stack, Box } from "../../primitives/layout.js";
|
|
9
9
|
import { Tooltip } from "../../primitives/Tooltip/Tooltip.js";
|
|
10
10
|
import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
|
|
11
|
-
import { Text } from "
|
|
11
|
+
import { Text } from "../../primitives/Text/Text.js";
|
|
12
12
|
function DefaultPencilIcon() {
|
|
13
13
|
return /* @__PURE__ */ jsx(
|
|
14
14
|
"svg",
|
|
@@ -13,7 +13,7 @@ const layout = require("../../primitives/layout.cjs");
|
|
|
13
13
|
const Menu = require("../../primitives/Menu/Menu.cjs");
|
|
14
14
|
const TextInput = require("../../primitives/TextInput/TextInput.cjs");
|
|
15
15
|
const WalletListItem = require("../WalletListItem/WalletListItem.cjs");
|
|
16
|
-
const Text = require("
|
|
16
|
+
const Text = require("../../primitives/Text/Text.cjs");
|
|
17
17
|
const colors = require("../../../theme/colors.cjs");
|
|
18
18
|
const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
|
|
19
19
|
const ThemeIcon = require("../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.cjs");
|
|
@@ -11,7 +11,7 @@ import { Stack } from "../../primitives/layout.js";
|
|
|
11
11
|
import { Menu } from "../../primitives/Menu/Menu.js";
|
|
12
12
|
import { TextInput } from "../../primitives/TextInput/TextInput.js";
|
|
13
13
|
import { WalletListItem } from "../WalletListItem/WalletListItem.js";
|
|
14
|
-
import { Text } from "
|
|
14
|
+
import { Text } from "../../primitives/Text/Text.js";
|
|
15
15
|
import { colors } from "../../../theme/colors.js";
|
|
16
16
|
import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
|
|
17
17
|
import { ThemeIcon } from "../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.js";
|
|
@@ -9,7 +9,7 @@ const Badge = require("../../primitives/Badge/Badge.cjs");
|
|
|
9
9
|
const layout = require("../../primitives/layout.cjs");
|
|
10
10
|
const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
|
|
11
11
|
const ThemeIcon = require("../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.cjs");
|
|
12
|
-
const Text = require("
|
|
12
|
+
const Text = require("../../primitives/Text/Text.cjs");
|
|
13
13
|
const colors = require("../../../theme/colors.cjs");
|
|
14
14
|
const UnstyledButton = require("../../../node_modules/@mantine/core/esm/components/UnstyledButton/UnstyledButton.cjs");
|
|
15
15
|
function moveRadioSelection(current, delta) {
|
|
@@ -99,7 +99,7 @@ function WalletListItem({
|
|
|
99
99
|
),
|
|
100
100
|
/* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { gap: isCompact ? 2 : 4, style: { flex: 1, minWidth: 0 }, children: [
|
|
101
101
|
/* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { gap: "xs", align: "center", wrap: "wrap", children: [
|
|
102
|
-
/* @__PURE__ */ jsxRuntime.jsx(Text.Text, { size: "sm", fw: 600, style: { wordBreak: "break-word" }, children: displayName }),
|
|
102
|
+
/* @__PURE__ */ jsxRuntime.jsx(Text.Text, { size: "sm", fw: 600, style: { wordBreak: "break-word" }, glossary: false, children: displayName }),
|
|
103
103
|
wallet.defaultRecipient && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { size: "xs", color: colors.colors.warning, variant: "light", tt: "uppercase", children: "Default" }),
|
|
104
104
|
/* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { size: "xs", variant: "light", color: colors.colors.neutral, children: kindPill })
|
|
105
105
|
] }),
|
|
@@ -112,6 +112,7 @@ function WalletListItem({
|
|
|
112
112
|
title: wallet.address,
|
|
113
113
|
...isClickable ? { "aria-hidden": true } : { "aria-label": `Wallet address ${wallet.address}` },
|
|
114
114
|
style: { overflowWrap: "anywhere" },
|
|
115
|
+
glossary: false,
|
|
115
116
|
children: displayAddress
|
|
116
117
|
}
|
|
117
118
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WalletListItem.cjs","sources":["../../../../src/components/specific/WalletListItem/WalletListItem.tsx"],"sourcesContent":["import { type KeyboardEvent, type ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { brandColors, colors, fairmintVars, neutralColors, radii } from \"../../../theme\";\nimport { truncateAddress } from \"../../../utils/address\";\nimport {\n getWalletDisplayName,\n getWalletIconColor,\n getWalletKindPill,\n type Wallet,\n} from \"../../../utils/wallets\";\nimport { Badge } from \"../../primitives/Badge/Badge\";\nimport { Box, Group, Stack, Text, ThemeIcon, UnstyledButton } from \"../../primitives/layout\";\n\nexport interface WalletListItemProps {\n /** Wallet data used to derive the name, kind badge, and address. */\n wallet: Wallet;\n /** Number of address characters shown on each side of the ellipsis in compact density. */\n addressChars?: number;\n /** Row density. Compact is intended for picker/dropdown options. */\n density?: \"comfortable\" | \"compact\";\n /** Applies the indigo outline selected treatment. */\n selected?: boolean;\n /** Content rendered at the trailing edge of the row. */\n rightSection?: ReactNode;\n /** Leading wallet visual. Apps provide the icon so the library stays icon-package agnostic. */\n walletIcon?: ReactNode;\n /** Optional override for wallet type labels. */\n typeLabels?: Record<string, string>;\n /** Makes the primary row content a selectable radio option when supplied. */\n onClick?: () => void;\n /**\n * Accessible name for a clickable row.\n * Defaults to `{displayName}, {address}` so unlabeled wallets stay distinguishable.\n */\n ariaLabel?: string;\n}\n\nfunction moveRadioSelection(current: HTMLElement, delta: number): void {\n const group = current.closest('[role=\"radiogroup\"]');\n if (!group) return;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const index = radios.indexOf(current);\n if (index < 0 || radios.length === 0) return;\n const next = radios[(index + delta + radios.length) % radios.length];\n next.focus();\n next.click();\n}\n\nfunction handleRadioKeyDown(event: KeyboardEvent<HTMLButtonElement>): void {\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n event.preventDefault();\n moveRadioSelection(event.currentTarget, 1);\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n event.preventDefault();\n moveRadioSelection(event.currentTarget, -1);\n break;\n default:\n break;\n }\n}\n\nfunction radioTabIndex(radio: HTMLElement | null, selected: boolean): number {\n if (!radio) return 0;\n const group = radio.closest('[role=\"radiogroup\"]');\n if (!group) return 0;\n if (selected) return 0;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const anySelected = radios.some((item) => item.getAttribute(\"aria-checked\") === \"true\");\n if (!anySelected && radios[0] === radio) return 0;\n return -1;\n}\n\n/**\n * Reusable wallet display shell for lists, pickers, and read-only review rows.\n * Management actions such as rename, remove, and connect remain owned by the\n * composing flow.\n */\nexport function WalletListItem({\n wallet,\n addressChars = 6,\n density = \"comfortable\",\n selected = false,\n rightSection,\n walletIcon,\n typeLabels,\n onClick,\n ariaLabel,\n}: WalletListItemProps) {\n const isCompact = density === \"compact\";\n const displayName = getWalletDisplayName(wallet, typeLabels);\n const kindPill = getWalletKindPill(wallet.type, typeLabels);\n const displayAddress = isCompact ? truncateAddress(wallet.address, addressChars) : wallet.address;\n const padding = isCompact ? \"xs\" : \"md\";\n const alignment = isCompact ? \"center\" : \"flex-start\";\n const isClickable = Boolean(onClick);\n const radioRef = useRef<HTMLButtonElement>(null);\n const [tabIndex, setTabIndex] = useState(0);\n\n useLayoutEffect(() => {\n if (!isClickable) return;\n const radio = radioRef.current;\n if (!radio) return;\n\n const updateTabIndex = () => {\n setTabIndex(radioTabIndex(radio, selected));\n };\n updateTabIndex();\n\n const group = radio.closest('[role=\"radiogroup\"]');\n if (!group) return;\n\n const observer = new MutationObserver(updateTabIndex);\n observer.observe(group, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: [\"aria-checked\", \"role\"],\n });\n return () => observer.disconnect();\n }, [isClickable, selected]);\n\n const mainContent = (\n <Group gap=\"sm\" align={alignment} wrap=\"nowrap\" style={{ flex: 1, minWidth: 0 }}>\n {walletIcon && (\n <ThemeIcon\n size={isCompact ? 32 : 40}\n radius=\"xl\"\n variant=\"light\"\n color={getWalletIconColor(wallet.type)}\n style={{ flexShrink: 0 }}\n >\n {walletIcon}\n </ThemeIcon>\n )}\n <Stack gap={isCompact ? 2 : 4} style={{ flex: 1, minWidth: 0 }}>\n <Group gap=\"xs\" align=\"center\" wrap=\"wrap\">\n <Text size=\"sm\" fw={600} style={{ wordBreak: \"break-word\" }}>\n {displayName}\n </Text>\n {wallet.defaultRecipient && (\n <Badge size=\"xs\" color={colors.warning} variant=\"light\" tt=\"uppercase\">\n Default\n </Badge>\n )}\n <Badge size=\"xs\" variant=\"light\" color={colors.neutral}>\n {kindPill}\n </Badge>\n </Group>\n <Text\n size=\"xs\"\n ff=\"monospace\"\n c={fairmintVars.colorTextSecondary}\n title={wallet.address}\n {...(isClickable\n ? { \"aria-hidden\": true }\n : { \"aria-label\": `Wallet address ${wallet.address}` })}\n style={{ overflowWrap: \"anywhere\" }}\n >\n {displayAddress}\n </Text>\n </Stack>\n </Group>\n );\n\n const trailing = rightSection ? <Box style={{ flexShrink: 0 }}>{rightSection}</Box> : null;\n\n const style = {\n borderRadius: radii.lg,\n border: selected\n ? `1px solid ${brandColors.indigo}`\n : isCompact\n ? \"1px solid transparent\"\n : `1px solid ${neutralColors[200]}`,\n } as const;\n\n const radioLabel = ariaLabel ?? `${displayName}, ${wallet.address}`;\n\n if (isClickable) {\n return (\n <Box\n data-selected={selected || undefined}\n className=\"fairmint-list-row\"\n w=\"100%\"\n p={padding}\n style={style}\n >\n <Group justify=\"space-between\" align={alignment} wrap=\"nowrap\" gap=\"xs\" w=\"100%\">\n <UnstyledButton\n ref={radioRef}\n onClick={onClick}\n onKeyDown={handleRadioKeyDown}\n role=\"radio\"\n aria-checked={selected}\n aria-label={radioLabel}\n tabIndex={tabIndex}\n style={{ flex: 1, minWidth: 0, textAlign: \"left\" }}\n >\n {mainContent}\n </UnstyledButton>\n {trailing}\n </Group>\n </Box>\n );\n }\n\n return (\n <Box data-selected={selected || undefined} w=\"100%\" p={padding} style={style}>\n <Group justify=\"space-between\" align={alignment} wrap=\"nowrap\" gap=\"xs\" w=\"100%\">\n {mainContent}\n {trailing}\n </Group>\n </Box>\n );\n}\n"],"names":["index","getWalletDisplayName","getWalletKindPill","truncateAddress","useRef","useState","useLayoutEffect","jsxs","Group","jsx","ThemeIcon","getWalletIconColor","Stack","Text","Badge","colors","fairmintVars","Box","radii","brandColors","neutralColors","UnstyledButton"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WalletListItem.cjs","sources":["../../../../src/components/specific/WalletListItem/WalletListItem.tsx"],"sourcesContent":["import { type KeyboardEvent, type ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { brandColors, colors, fairmintVars, neutralColors, radii } from \"../../../theme\";\nimport { truncateAddress } from \"../../../utils/address\";\nimport {\n getWalletDisplayName,\n getWalletIconColor,\n getWalletKindPill,\n type Wallet,\n} from \"../../../utils/wallets\";\nimport { Badge } from \"../../primitives/Badge/Badge\";\nimport { Box, Group, Stack, Text, ThemeIcon, UnstyledButton } from \"../../primitives/layout\";\n\nexport interface WalletListItemProps {\n /** Wallet data used to derive the name, kind badge, and address. */\n wallet: Wallet;\n /** Number of address characters shown on each side of the ellipsis in compact density. */\n addressChars?: number;\n /** Row density. Compact is intended for picker/dropdown options. */\n density?: \"comfortable\" | \"compact\";\n /** Applies the indigo outline selected treatment. */\n selected?: boolean;\n /** Content rendered at the trailing edge of the row. */\n rightSection?: ReactNode;\n /** Leading wallet visual. Apps provide the icon so the library stays icon-package agnostic. */\n walletIcon?: ReactNode;\n /** Optional override for wallet type labels. */\n typeLabels?: Record<string, string>;\n /** Makes the primary row content a selectable radio option when supplied. */\n onClick?: () => void;\n /**\n * Accessible name for a clickable row.\n * Defaults to `{displayName}, {address}` so unlabeled wallets stay distinguishable.\n */\n ariaLabel?: string;\n}\n\nfunction moveRadioSelection(current: HTMLElement, delta: number): void {\n const group = current.closest('[role=\"radiogroup\"]');\n if (!group) return;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const index = radios.indexOf(current);\n if (index < 0 || radios.length === 0) return;\n const next = radios[(index + delta + radios.length) % radios.length];\n next.focus();\n next.click();\n}\n\nfunction handleRadioKeyDown(event: KeyboardEvent<HTMLButtonElement>): void {\n switch (event.key) {\n case \"ArrowDown\":\n case \"ArrowRight\":\n event.preventDefault();\n moveRadioSelection(event.currentTarget, 1);\n break;\n case \"ArrowUp\":\n case \"ArrowLeft\":\n event.preventDefault();\n moveRadioSelection(event.currentTarget, -1);\n break;\n default:\n break;\n }\n}\n\nfunction radioTabIndex(radio: HTMLElement | null, selected: boolean): number {\n if (!radio) return 0;\n const group = radio.closest('[role=\"radiogroup\"]');\n if (!group) return 0;\n if (selected) return 0;\n const radios = Array.from(group.querySelectorAll<HTMLElement>('[role=\"radio\"]'));\n const anySelected = radios.some((item) => item.getAttribute(\"aria-checked\") === \"true\");\n if (!anySelected && radios[0] === radio) return 0;\n return -1;\n}\n\n/**\n * Reusable wallet display shell for lists, pickers, and read-only review rows.\n * Management actions such as rename, remove, and connect remain owned by the\n * composing flow.\n */\nexport function WalletListItem({\n wallet,\n addressChars = 6,\n density = \"comfortable\",\n selected = false,\n rightSection,\n walletIcon,\n typeLabels,\n onClick,\n ariaLabel,\n}: WalletListItemProps) {\n const isCompact = density === \"compact\";\n const displayName = getWalletDisplayName(wallet, typeLabels);\n const kindPill = getWalletKindPill(wallet.type, typeLabels);\n const displayAddress = isCompact ? truncateAddress(wallet.address, addressChars) : wallet.address;\n const padding = isCompact ? \"xs\" : \"md\";\n const alignment = isCompact ? \"center\" : \"flex-start\";\n const isClickable = Boolean(onClick);\n const radioRef = useRef<HTMLButtonElement>(null);\n const [tabIndex, setTabIndex] = useState(0);\n\n useLayoutEffect(() => {\n if (!isClickable) return;\n const radio = radioRef.current;\n if (!radio) return;\n\n const updateTabIndex = () => {\n setTabIndex(radioTabIndex(radio, selected));\n };\n updateTabIndex();\n\n const group = radio.closest('[role=\"radiogroup\"]');\n if (!group) return;\n\n const observer = new MutationObserver(updateTabIndex);\n observer.observe(group, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: [\"aria-checked\", \"role\"],\n });\n return () => observer.disconnect();\n }, [isClickable, selected]);\n\n const mainContent = (\n <Group gap=\"sm\" align={alignment} wrap=\"nowrap\" style={{ flex: 1, minWidth: 0 }}>\n {walletIcon && (\n <ThemeIcon\n size={isCompact ? 32 : 40}\n radius=\"xl\"\n variant=\"light\"\n color={getWalletIconColor(wallet.type)}\n style={{ flexShrink: 0 }}\n >\n {walletIcon}\n </ThemeIcon>\n )}\n <Stack gap={isCompact ? 2 : 4} style={{ flex: 1, minWidth: 0 }}>\n <Group gap=\"xs\" align=\"center\" wrap=\"wrap\">\n <Text size=\"sm\" fw={600} style={{ wordBreak: \"break-word\" }} glossary={false}>\n {displayName}\n </Text>\n {wallet.defaultRecipient && (\n <Badge size=\"xs\" color={colors.warning} variant=\"light\" tt=\"uppercase\">\n Default\n </Badge>\n )}\n <Badge size=\"xs\" variant=\"light\" color={colors.neutral}>\n {kindPill}\n </Badge>\n </Group>\n <Text\n size=\"xs\"\n ff=\"monospace\"\n c={fairmintVars.colorTextSecondary}\n title={wallet.address}\n {...(isClickable\n ? { \"aria-hidden\": true }\n : { \"aria-label\": `Wallet address ${wallet.address}` })}\n style={{ overflowWrap: \"anywhere\" }}\n glossary={false}\n >\n {displayAddress}\n </Text>\n </Stack>\n </Group>\n );\n\n const trailing = rightSection ? <Box style={{ flexShrink: 0 }}>{rightSection}</Box> : null;\n\n const style = {\n borderRadius: radii.lg,\n border: selected\n ? `1px solid ${brandColors.indigo}`\n : isCompact\n ? \"1px solid transparent\"\n : `1px solid ${neutralColors[200]}`,\n } as const;\n\n const radioLabel = ariaLabel ?? `${displayName}, ${wallet.address}`;\n\n if (isClickable) {\n return (\n <Box\n data-selected={selected || undefined}\n className=\"fairmint-list-row\"\n w=\"100%\"\n p={padding}\n style={style}\n >\n <Group justify=\"space-between\" align={alignment} wrap=\"nowrap\" gap=\"xs\" w=\"100%\">\n <UnstyledButton\n ref={radioRef}\n onClick={onClick}\n onKeyDown={handleRadioKeyDown}\n role=\"radio\"\n aria-checked={selected}\n aria-label={radioLabel}\n tabIndex={tabIndex}\n style={{ flex: 1, minWidth: 0, textAlign: \"left\" }}\n >\n {mainContent}\n </UnstyledButton>\n {trailing}\n </Group>\n </Box>\n );\n }\n\n return (\n <Box data-selected={selected || undefined} w=\"100%\" p={padding} style={style}>\n <Group justify=\"space-between\" align={alignment} wrap=\"nowrap\" gap=\"xs\" w=\"100%\">\n {mainContent}\n {trailing}\n </Group>\n </Box>\n );\n}\n"],"names":["index","getWalletDisplayName","getWalletKindPill","truncateAddress","useRef","useState","useLayoutEffect","jsxs","Group","jsx","ThemeIcon","getWalletIconColor","Stack","Text","Badge","colors","fairmintVars","Box","radii","brandColors","neutralColors","UnstyledButton"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WalletListItem.d.ts","sourceRoot":"","sources":["../../../../src/components/specific/WalletListItem/WalletListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAqC,MAAM,OAAO,CAAC;AAG9F,OAAO,EAIL,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAC;AAIhC,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyCD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,YAAgB,EAChB,OAAuB,EACvB,QAAgB,EAChB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAO,EACP,SAAS,GACV,EAAE,mBAAmB,+
|
|
1
|
+
{"version":3,"file":"WalletListItem.d.ts","sourceRoot":"","sources":["../../../../src/components/specific/WalletListItem/WalletListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAqC,MAAM,OAAO,CAAC;AAG9F,OAAO,EAIL,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAC;AAIhC,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyCD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,YAAgB,EAChB,OAAuB,EACvB,QAAgB,EAChB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAO,EACP,SAAS,GACV,EAAE,mBAAmB,+BA+HrB"}
|
|
@@ -7,7 +7,7 @@ import { Badge } from "../../primitives/Badge/Badge.js";
|
|
|
7
7
|
import { Stack, Box } from "../../primitives/layout.js";
|
|
8
8
|
import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
|
|
9
9
|
import { ThemeIcon } from "../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.js";
|
|
10
|
-
import { Text } from "
|
|
10
|
+
import { Text } from "../../primitives/Text/Text.js";
|
|
11
11
|
import { colors } from "../../../theme/colors.js";
|
|
12
12
|
import { UnstyledButton } from "../../../node_modules/@mantine/core/esm/components/UnstyledButton/UnstyledButton.js";
|
|
13
13
|
function moveRadioSelection(current, delta) {
|
|
@@ -97,7 +97,7 @@ function WalletListItem({
|
|
|
97
97
|
),
|
|
98
98
|
/* @__PURE__ */ jsxs(Stack, { gap: isCompact ? 2 : 4, style: { flex: 1, minWidth: 0 }, children: [
|
|
99
99
|
/* @__PURE__ */ jsxs(Group, { gap: "xs", align: "center", wrap: "wrap", children: [
|
|
100
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { wordBreak: "break-word" }, children: displayName }),
|
|
100
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, style: { wordBreak: "break-word" }, glossary: false, children: displayName }),
|
|
101
101
|
wallet.defaultRecipient && /* @__PURE__ */ jsx(Badge, { size: "xs", color: colors.warning, variant: "light", tt: "uppercase", children: "Default" }),
|
|
102
102
|
/* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: colors.neutral, children: kindPill })
|
|
103
103
|
] }),
|
|
@@ -110,6 +110,7 @@ function WalletListItem({
|
|
|
110
110
|
title: wallet.address,
|
|
111
111
|
...isClickable ? { "aria-hidden": true } : { "aria-label": `Wallet address ${wallet.address}` },
|
|
112
112
|
style: { overflowWrap: "anywhere" },
|
|
113
|
+
glossary: false,
|
|
113
114
|
children: displayAddress
|
|
114
115
|
}
|
|
115
116
|
)
|