@fairmint/ui 0.4.11 → 0.4.13
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/_virtual/index3.cjs +5 -3
- package/dist/_virtual/index3.cjs.map +1 -1
- package/dist/_virtual/index3.js +5 -2
- package/dist/_virtual/index3.js.map +1 -1
- package/dist/_virtual/index4.cjs +3 -5
- package/dist/_virtual/index4.cjs.map +1 -1
- package/dist/_virtual/index4.js +2 -5
- package/dist/_virtual/index4.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/node_modules/@mantine/form/esm/hooks/use-form-status/use-form-status.cjs +1 -1
- package/dist/node_modules/@mantine/form/esm/hooks/use-form-status/use-form-status.js +1 -1
- package/dist/node_modules/prop-types/index.cjs +1 -1
- package/dist/node_modules/prop-types/index.js +1 -1
- package/package.json +1 -1
package/dist/_virtual/index3.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const _commonjsHelpers = require("./_commonjsHelpers.cjs");
|
|
3
|
+
const index = require("../node_modules/fast-deep-equal/index.cjs");
|
|
4
|
+
var fastDeepEqualExports = index.__require();
|
|
5
|
+
const isEqual = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(fastDeepEqualExports);
|
|
6
|
+
module.exports = isEqual;
|
|
5
7
|
//# sourceMappingURL=index3.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index3.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index3.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
package/dist/_virtual/index3.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { getDefaultExportFromCjs } from "./_commonjsHelpers.js";
|
|
2
|
+
import { __require as requireFastDeepEqual } from "../node_modules/fast-deep-equal/index.js";
|
|
3
|
+
var fastDeepEqualExports = requireFastDeepEqual();
|
|
4
|
+
const isEqual = /* @__PURE__ */ getDefaultExportFromCjs(fastDeepEqualExports);
|
|
2
5
|
export {
|
|
3
|
-
|
|
6
|
+
isEqual as default
|
|
4
7
|
};
|
|
5
8
|
//# sourceMappingURL=index3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index3.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
package/dist/_virtual/index4.cjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const isEqual = /* @__PURE__ */ _commonjsHelpers.getDefaultExportFromCjs(fastDeepEqualExports);
|
|
6
|
-
module.exports = isEqual;
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
var propTypes = { exports: {} };
|
|
4
|
+
exports.__module = propTypes;
|
|
7
5
|
//# sourceMappingURL=index4.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index4.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index4.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
package/dist/_virtual/index4.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import { __require as requireFastDeepEqual } from "../node_modules/fast-deep-equal/index.js";
|
|
3
|
-
var fastDeepEqualExports = requireFastDeepEqual();
|
|
4
|
-
const isEqual = /* @__PURE__ */ getDefaultExportFromCjs(fastDeepEqualExports);
|
|
1
|
+
var propTypes = { exports: {} };
|
|
5
2
|
export {
|
|
6
|
-
|
|
3
|
+
propTypes as __module
|
|
7
4
|
};
|
|
8
5
|
//# sourceMappingURL=index4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -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 Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
|
|
10
9
|
const Text = require("../../primitives/Text/Text.cjs");
|
|
10
|
+
const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.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 { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
|
|
8
7
|
import { Text } from "../../primitives/Text/Text.js";
|
|
8
|
+
import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.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":"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"}
|
|
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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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const React = require("react");
|
|
4
|
-
const index = require("../../../../../../_virtual/
|
|
4
|
+
const index = require("../../../../../../_virtual/index3.cjs");
|
|
5
5
|
const getStatus = require("../../get-status/get-status.cjs");
|
|
6
6
|
const clearListState = require("../../lists/clear-list-state.cjs");
|
|
7
7
|
const getPath = require("../../paths/get-path.cjs");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useRef, useCallback } from "react";
|
|
2
|
-
import isEqual from "../../../../../../_virtual/
|
|
2
|
+
import isEqual from "../../../../../../_virtual/index3.js";
|
|
3
3
|
import { getStatus } from "../../get-status/get-status.js";
|
|
4
4
|
import { clearListState } from "../../lists/clear-list-state.js";
|
|
5
5
|
import { getPath } from "../../paths/get-path.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const index$1 = require("../../_virtual/
|
|
3
|
+
const index$1 = require("../../_virtual/index4.cjs");
|
|
4
4
|
const index = require("./node_modules/react-is/index.cjs");
|
|
5
5
|
const factoryWithTypeCheckers = require("./factoryWithTypeCheckers.cjs");
|
|
6
6
|
const factoryWithThrowingShims = require("./factoryWithThrowingShims.cjs");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __module as propTypes } from "../../_virtual/
|
|
1
|
+
import { __module as propTypes } from "../../_virtual/index4.js";
|
|
2
2
|
import { __require as requireReactIs } from "./node_modules/react-is/index.js";
|
|
3
3
|
import { __require as requireFactoryWithTypeCheckers } from "./factoryWithTypeCheckers.js";
|
|
4
4
|
import { __require as requireFactoryWithThrowingShims } from "./factoryWithThrowingShims.js";
|