@fairmint/ui 0.3.19 → 0.3.21

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.
Files changed (41) hide show
  1. package/dist/components/generic/AgentSuggestion/AgentSuggestion.cjs +186 -0
  2. package/dist/components/generic/AgentSuggestion/AgentSuggestion.cjs.map +1 -0
  3. package/dist/components/generic/AgentSuggestion/AgentSuggestion.d.ts +44 -0
  4. package/dist/components/generic/AgentSuggestion/AgentSuggestion.d.ts.map +1 -0
  5. package/dist/components/generic/AgentSuggestion/AgentSuggestion.js +186 -0
  6. package/dist/components/generic/AgentSuggestion/AgentSuggestion.js.map +1 -0
  7. package/dist/components/generic/NotificationRow/NotificationRow.cjs +169 -0
  8. package/dist/components/generic/NotificationRow/NotificationRow.cjs.map +1 -0
  9. package/dist/components/generic/NotificationRow/NotificationRow.d.ts +51 -0
  10. package/dist/components/generic/NotificationRow/NotificationRow.d.ts.map +1 -0
  11. package/dist/components/generic/NotificationRow/NotificationRow.js +169 -0
  12. package/dist/components/generic/NotificationRow/NotificationRow.js.map +1 -0
  13. package/dist/components/generic/TaskRow/TaskRow.cjs +151 -0
  14. package/dist/components/generic/TaskRow/TaskRow.cjs.map +1 -0
  15. package/dist/components/generic/TaskRow/TaskRow.d.ts +56 -0
  16. package/dist/components/generic/TaskRow/TaskRow.d.ts.map +1 -0
  17. package/dist/components/generic/TaskRow/TaskRow.js +151 -0
  18. package/dist/components/generic/TaskRow/TaskRow.js.map +1 -0
  19. package/dist/components/primitives/layout.cjs.map +1 -1
  20. package/dist/components/primitives/layout.d.ts +1 -1
  21. package/dist/components/primitives/layout.d.ts.map +1 -1
  22. package/dist/components/primitives/layout.js.map +1 -1
  23. package/dist/fairmint-ui.cjs +7 -0
  24. package/dist/fairmint-ui.cjs.map +1 -1
  25. package/dist/fairmint-ui.js +7 -0
  26. package/dist/fairmint-ui.js.map +1 -1
  27. package/dist/index.d.ts +6 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-computed-color-scheme.cjs +11 -0
  30. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-computed-color-scheme.cjs.map +1 -0
  31. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-computed-color-scheme.js +11 -0
  32. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-computed-color-scheme.js.map +1 -0
  33. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-mantine-color-scheme.cjs +66 -0
  34. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-mantine-color-scheme.cjs.map +1 -0
  35. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-mantine-color-scheme.js +66 -0
  36. package/dist/node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-mantine-color-scheme.js.map +1 -0
  37. package/dist/node_modules/@mantine/hooks/esm/use-color-scheme/use-color-scheme.cjs +8 -0
  38. package/dist/node_modules/@mantine/hooks/esm/use-color-scheme/use-color-scheme.cjs.map +1 -0
  39. package/dist/node_modules/@mantine/hooks/esm/use-color-scheme/use-color-scheme.js +8 -0
  40. package/dist/node_modules/@mantine/hooks/esm/use-color-scheme/use-color-scheme.js.map +1 -0
  41. package/package.json +1 -1
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const index = require("../../../theme/index.cjs");
6
+ const ActionIcon = require("../../primitives/ActionIcon/ActionIcon.cjs");
7
+ const layout = require("../../primitives/layout.cjs");
8
+ const Tooltip = require("../../primitives/Tooltip/Tooltip.cjs");
9
+ const spacing = require("../../../theme/spacing.cjs");
10
+ const Text = require("../../../node_modules/@mantine/core/esm/components/Text/Text.cjs");
11
+ const MantineThemeProvider = require("../../../node_modules/@mantine/core/esm/core/MantineProvider/MantineThemeProvider/MantineThemeProvider.cjs");
12
+ const useComputedColorScheme = require("../../../node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-computed-color-scheme.cjs");
13
+ function useCaptableAiBrandPaint() {
14
+ const theme = MantineThemeProvider.useMantineTheme();
15
+ const scheme = useComputedColorScheme.useComputedColorScheme("light");
16
+ const dark = scheme === "dark";
17
+ const blue = dark ? theme.colors.fairmintBlue[3] : index.brandColors.blue;
18
+ const purple = dark ? theme.colors.fairmintPurple[2] : index.brandColors.purple;
19
+ const markStops = dark ? ["#D0F8FF", "#AEEBFF", "#557CFF"] : ["#557CFF", theme.colors.fairmintBlue[4], index.brandColors.blue];
20
+ return {
21
+ blue,
22
+ purple,
23
+ markStops,
24
+ accent: `linear-gradient(180deg, ${blue} 0%, ${purple} 100%)`
25
+ };
26
+ }
27
+ const CAPTABLE_AI_MARK_PATH = "M 120 2 L 73 48 L 16 81 L 17 134 L 16 148 L 12 166 L 5 187 L 0 212 L 47 261 L 78 315 L 141 316 L 153 318 L 187 328 L 210 333 L 253 290 L 276 275 L 314 254 L 314 194 L 315 185 L 331 126 L 331 122 L 284 74 L 252 19 L 185 18 L 160 12 L 131 3 Z M 15 208 L 23 178 L 26 177 L 93 216 L 101 213 L 148 185 L 154 184 L 140 237 L 138 241 L 67 260 Z M 168 187 L 180 206 L 198 239 L 163 300 L 161 302 L 88 302 L 85 299 L 71 274 L 78 271 L 150 252 L 166 191 Z M 125 17 L 143 21 L 157 26 L 126 78 L 116 97 L 147 149 L 148 155 L 115 147 L 92 140 L 73 69 Z M 56 74 L 60 74 L 79 148 L 81 152 L 135 166 L 146 170 L 94 200 L 31 163 L 30 136 L 31 90 L 37 85 Z M 235 135 L 238 135 L 300 171 L 301 244 L 298 247 L 272 262 L 270 259 L 251 184 L 249 182 L 190 167 L 186 164 Z M 316 128 L 307 159 L 236 118 L 178 152 L 178 146 L 184 127 L 186 116 L 192 95 L 194 93 L 260 75 L 264 75 Z M 181 180 L 187 180 L 191 182 L 232 192 L 239 195 L 252 246 L 258 265 L 205 318 L 178 311 L 174 308 L 214 239 L 204 219 L 190 197 Z M 242 32 L 245 35 L 259 60 L 257 62 L 239 66 L 181 82 L 163 148 L 159 143 L 133 98 L 133 95 L 169 34 L 183 32 L 219 33 Z";
28
+ function CaptableAiMarkIcon({ stops }) {
29
+ const rawId = React.useId();
30
+ const gradId = `agent-suggestion-captable-ai-mark-${rawId.replace(/:/g, "")}`;
31
+ const [start, mid, end] = stops;
32
+ return /* @__PURE__ */ jsxRuntime.jsxs(
33
+ "svg",
34
+ {
35
+ width: 16,
36
+ height: 16,
37
+ viewBox: "0 0 333 334",
38
+ fill: "none",
39
+ "aria-hidden": "true",
40
+ focusable: "false",
41
+ "data-captable-ai-mark": "",
42
+ children: [
43
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("linearGradient", { id: gradId, x1: "0", y1: "0", x2: "1", y2: "1", children: [
44
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: start, "data-mark-stop": "start" }),
45
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "48%", stopColor: mid, "data-mark-stop": "mid" }),
46
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "100%", stopColor: end, "data-mark-stop": "end" })
47
+ ] }) }),
48
+ /* @__PURE__ */ jsxRuntime.jsx(
49
+ "path",
50
+ {
51
+ fill: `url(#${gradId})`,
52
+ fillRule: "evenodd",
53
+ clipRule: "evenodd",
54
+ d: CAPTABLE_AI_MARK_PATH
55
+ }
56
+ )
57
+ ]
58
+ }
59
+ );
60
+ }
61
+ function DismissIcon() {
62
+ return /* @__PURE__ */ jsxRuntime.jsxs(
63
+ "svg",
64
+ {
65
+ "aria-hidden": "true",
66
+ width: "14",
67
+ height: "14",
68
+ viewBox: "0 0 24 24",
69
+ fill: "none",
70
+ stroke: "currentColor",
71
+ strokeWidth: "2",
72
+ strokeLinecap: "round",
73
+ strokeLinejoin: "round",
74
+ children: [
75
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18" }),
76
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 6 12 12" })
77
+ ]
78
+ }
79
+ );
80
+ }
81
+ function AgentSuggestion({
82
+ title,
83
+ message,
84
+ tone = "info",
85
+ icon,
86
+ onDismiss,
87
+ dismissLabel = "Dismiss",
88
+ role,
89
+ className,
90
+ style
91
+ }) {
92
+ const brand = useCaptableAiBrandPaint();
93
+ const resolvedRole = role ?? (tone === "error" ? "alert" : "status");
94
+ const resolvedIcon = icon === null ? null : icon ?? /* @__PURE__ */ jsxRuntime.jsx(CaptableAiMarkIcon, { stops: brand.markStops });
95
+ const surface = tone === "warning" ? {
96
+ background: "transparent",
97
+ border: index.fairmintVars.colorWarningBorder,
98
+ accent: index.fairmintVars.colorWarningBorder
99
+ } : tone === "error" ? {
100
+ background: "transparent",
101
+ border: index.fairmintVars.colorErrorBorder,
102
+ accent: index.fairmintVars.colorErrorSolid
103
+ } : {
104
+ background: "transparent",
105
+ border: index.fairmintVars.colorBorderDefault,
106
+ accent: brand.accent
107
+ };
108
+ return /* @__PURE__ */ jsxRuntime.jsxs(
109
+ layout.Box,
110
+ {
111
+ className,
112
+ role: resolvedRole,
113
+ "data-tone": tone,
114
+ style: {
115
+ position: "relative",
116
+ display: "flex",
117
+ alignItems: "flex-start",
118
+ gap: spacing.spacing.xs,
119
+ backgroundColor: surface.background,
120
+ border: `1px solid ${surface.border}`,
121
+ borderRadius: 2,
122
+ paddingBlock: spacing.spacing.xs,
123
+ paddingInlineStart: spacing.spacing.sm,
124
+ paddingInlineEnd: spacing.spacing.xs,
125
+ overflow: "hidden",
126
+ ...style
127
+ },
128
+ children: [
129
+ /* @__PURE__ */ jsxRuntime.jsx(
130
+ layout.Box,
131
+ {
132
+ "aria-hidden": true,
133
+ "data-accent": "",
134
+ style: {
135
+ position: "absolute",
136
+ insetBlock: 0,
137
+ insetInlineStart: 0,
138
+ width: 3,
139
+ background: surface.accent
140
+ // No own radius — container overflow:hidden + borderRadius:2 clips flush.
141
+ }
142
+ }
143
+ ),
144
+ resolvedIcon ? /* @__PURE__ */ jsxRuntime.jsx(
145
+ layout.Box,
146
+ {
147
+ style: {
148
+ display: "flex",
149
+ flexShrink: 0,
150
+ marginTop: 2,
151
+ width: 16,
152
+ height: 16
153
+ },
154
+ children: resolvedIcon
155
+ }
156
+ ) : null,
157
+ /* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
158
+ /* @__PURE__ */ jsxRuntime.jsx(Text.Text, { size: "sm", fw: 500, c: index.fairmintVars.colorTextPrimary, lh: 1.3, children: title }),
159
+ message ? /* @__PURE__ */ jsxRuntime.jsx(Text.Text, { size: "xs", c: index.fairmintVars.colorTextSecondary, lh: 1.4, children: message }) : null
160
+ ] }),
161
+ onDismiss ? /* @__PURE__ */ jsxRuntime.jsx(Tooltip.Tooltip, { label: dismissLabel, withArrow: true, position: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
162
+ ActionIcon.ActionIcon,
163
+ {
164
+ size: "sm",
165
+ variant: "subtle",
166
+ color: "gray",
167
+ "aria-label": dismissLabel,
168
+ onClick: onDismiss,
169
+ style: { flexShrink: 0, marginTop: -2 },
170
+ children: /* @__PURE__ */ jsxRuntime.jsx(DismissIcon, {})
171
+ }
172
+ ) }) : null
173
+ ]
174
+ }
175
+ );
176
+ }
177
+ function AgentSuggestionList({
178
+ children,
179
+ gap = spacing.spacing.xs,
180
+ className
181
+ }) {
182
+ return /* @__PURE__ */ jsxRuntime.jsx(layout.Stack, { gap, className, children });
183
+ }
184
+ exports.AgentSuggestion = AgentSuggestion;
185
+ exports.AgentSuggestionList = AgentSuggestionList;
186
+ //# sourceMappingURL=AgentSuggestion.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentSuggestion.cjs","sources":["../../../../src/components/generic/AgentSuggestion/AgentSuggestion.tsx"],"sourcesContent":["import type { AriaRole, CSSProperties, ReactNode } from \"react\";\nimport { useId } from \"react\";\nimport { brandColors, fairmintVars, spacing } from \"../../../theme\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Box, Stack, Text, useComputedColorScheme, useMantineTheme } from \"../../primitives/layout\";\nimport { Tooltip } from \"../../primitives/Tooltip/Tooltip\";\n\nexport type AgentSuggestionTone = \"info\" | \"warning\" | \"error\";\n\nexport interface AgentSuggestionProps {\n /** Short title — typically a humanized agent code label. */\n title: ReactNode;\n /** Supporting detail from the agent. */\n message?: ReactNode;\n /**\n * Semantic meaning. `error` / `warning` use severity surfaces because they\n * map to actionable / blocking review states in CaptableAI. `info` stays\n * CaptableAI-branded (blue→purple accent).\n * @default \"info\"\n */\n tone?: AgentSuggestionTone;\n /**\n * Leading icon. Pass `null` to hide.\n * When omitted, the CaptableAI brand mark is shown.\n */\n icon?: ReactNode | null;\n /** When set, renders a dismiss control. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss control. @default \"Dismiss\" */\n dismissLabel?: string;\n /** Override the default accessible role. Error defaults to alert; other tones use status. */\n role?: AriaRole;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * CaptableAI brand stops for the left accent (Fairmint blue→purple) and the\n * logo-symbol mark (CaptableAI cyan→blue). Dark mode uses the official\n * CaptableAILogoSymbol gradient so the mark reads on charcoal; light mode\n * shifts toward stronger blues for contrast on white.\n */\nfunction useCaptableAiBrandPaint() {\n const theme = useMantineTheme();\n const scheme = useComputedColorScheme(\"light\");\n const dark = scheme === \"dark\";\n\n const blue = dark ? theme.colors.fairmintBlue[3] : brandColors.blue;\n const purple = dark ? theme.colors.fairmintPurple[2] : brandColors.purple;\n\n // From studiov2 CaptableAILogoSymbol.svg (dark / brand-on-navy).\n const markStops: [string, string, string] = dark\n ? [\"#D0F8FF\", \"#AEEBFF\", \"#557CFF\"]\n : [\"#557CFF\", theme.colors.fairmintBlue[4], brandColors.blue];\n\n return {\n blue,\n purple,\n markStops,\n accent: `linear-gradient(180deg, ${blue} 0%, ${purple} 100%)`,\n };\n}\n\n/** CaptableAI logo symbol path — studiov2 `CaptableAILogoSymbol.svg` / `captable-ai-icon.svg`. */\nconst CAPTABLE_AI_MARK_PATH =\n \"M 120 2 L 73 48 L 16 81 L 17 134 L 16 148 L 12 166 L 5 187 L 0 212 L 47 261 L 78 315 L 141 316 L 153 318 L 187 328 L 210 333 L 253 290 L 276 275 L 314 254 L 314 194 L 315 185 L 331 126 L 331 122 L 284 74 L 252 19 L 185 18 L 160 12 L 131 3 Z M 15 208 L 23 178 L 26 177 L 93 216 L 101 213 L 148 185 L 154 184 L 140 237 L 138 241 L 67 260 Z M 168 187 L 180 206 L 198 239 L 163 300 L 161 302 L 88 302 L 85 299 L 71 274 L 78 271 L 150 252 L 166 191 Z M 125 17 L 143 21 L 157 26 L 126 78 L 116 97 L 147 149 L 148 155 L 115 147 L 92 140 L 73 69 Z M 56 74 L 60 74 L 79 148 L 81 152 L 135 166 L 146 170 L 94 200 L 31 163 L 30 136 L 31 90 L 37 85 Z M 235 135 L 238 135 L 300 171 L 301 244 L 298 247 L 272 262 L 270 259 L 251 184 L 249 182 L 190 167 L 186 164 Z M 316 128 L 307 159 L 236 118 L 178 152 L 178 146 L 184 127 L 186 116 L 192 95 L 194 93 L 260 75 L 264 75 Z M 181 180 L 187 180 L 191 182 L 232 192 L 239 195 L 252 246 L 258 265 L 205 318 L 178 311 L 174 308 L 214 239 L 204 219 L 190 197 Z M 242 32 L 245 35 L 259 60 L 257 62 L 239 66 L 181 82 L 163 148 L 159 143 L 133 98 L 133 95 L 169 34 L 183 32 L 219 33 Z\";\n\nfunction CaptableAiMarkIcon({ stops }: { stops: [string, string, string] }) {\n const rawId = useId();\n const gradId = `agent-suggestion-captable-ai-mark-${rawId.replace(/:/g, \"\")}`;\n const [start, mid, end] = stops;\n\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 333 334\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n data-captable-ai-mark=\"\"\n >\n <defs>\n <linearGradient id={gradId} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stopColor={start} data-mark-stop=\"start\" />\n <stop offset=\"48%\" stopColor={mid} data-mark-stop=\"mid\" />\n <stop offset=\"100%\" stopColor={end} data-mark-stop=\"end\" />\n </linearGradient>\n </defs>\n <path\n fill={`url(#${gradId})`}\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d={CAPTABLE_AI_MARK_PATH}\n />\n </svg>\n );\n}\n\nfunction DismissIcon() {\n return (\n <svg\n aria-hidden=\"true\"\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 >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Dense, agent-originated review note. Distinct from Alert/Banner so stacked\n * suggestions do not compete with a single page-level severity summary.\n *\n * Pattern candidate: compose a list of `AgentSuggestion` under one parent\n * Alert or Banner (\"N suggestions need review\") — never N banners.\n */\nexport function AgentSuggestion({\n title,\n message,\n tone = \"info\",\n icon,\n onDismiss,\n dismissLabel = \"Dismiss\",\n role,\n className,\n style,\n}: AgentSuggestionProps) {\n const brand = useCaptableAiBrandPaint();\n const resolvedRole = role ?? (tone === \"error\" ? \"alert\" : \"status\");\n const resolvedIcon =\n icon === null ? null : (icon ?? <CaptableAiMarkIcon stops={brand.markStops} />);\n\n // Warning accent shares the border token so the strip reads orange (not the\n // red-adjacent Solid). Error keeps Solid — in dark it matches the border.\n const surface =\n tone === \"warning\"\n ? {\n background: \"transparent\",\n border: fairmintVars.colorWarningBorder,\n accent: fairmintVars.colorWarningBorder,\n }\n : tone === \"error\"\n ? {\n background: \"transparent\",\n border: fairmintVars.colorErrorBorder,\n accent: fairmintVars.colorErrorSolid,\n }\n : {\n background: \"transparent\",\n border: fairmintVars.colorBorderDefault,\n accent: brand.accent,\n };\n\n return (\n <Box\n className={className}\n role={resolvedRole}\n data-tone={tone}\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: spacing.xs,\n backgroundColor: surface.background,\n border: `1px solid ${surface.border}`,\n borderRadius: 2,\n paddingBlock: spacing.xs,\n paddingInlineStart: spacing.sm,\n paddingInlineEnd: spacing.xs,\n overflow: \"hidden\",\n ...style,\n }}\n >\n <Box\n aria-hidden\n data-accent=\"\"\n style={{\n position: \"absolute\",\n insetBlock: 0,\n insetInlineStart: 0,\n width: 3,\n background: surface.accent,\n // No own radius — container overflow:hidden + borderRadius:2 clips flush.\n }}\n />\n\n {resolvedIcon ? (\n <Box\n style={{\n display: \"flex\",\n flexShrink: 0,\n marginTop: 2,\n width: 16,\n height: 16,\n }}\n >\n {resolvedIcon}\n </Box>\n ) : null}\n\n <Stack gap={4} style={{ flex: 1, minWidth: 0 }}>\n <Text size=\"sm\" fw={500} c={fairmintVars.colorTextPrimary} lh={1.3}>\n {title}\n </Text>\n {message ? (\n <Text size=\"xs\" c={fairmintVars.colorTextSecondary} lh={1.4}>\n {message}\n </Text>\n ) : null}\n </Stack>\n\n {onDismiss ? (\n <Tooltip label={dismissLabel} withArrow position=\"top\">\n <ActionIcon\n size=\"sm\"\n variant=\"subtle\"\n color=\"gray\"\n aria-label={dismissLabel}\n onClick={onDismiss}\n style={{ flexShrink: 0, marginTop: -2 }}\n >\n <DismissIcon />\n </ActionIcon>\n </Tooltip>\n ) : null}\n </Box>\n );\n}\n\n/** Convenience stack for composing multiple agent suggestions without inventing layout. */\nexport interface AgentSuggestionListProps {\n children: ReactNode;\n gap?: number | string;\n className?: string;\n}\n\nexport function AgentSuggestionList({\n children,\n gap = spacing.xs,\n className,\n}: AgentSuggestionListProps) {\n return (\n <Stack gap={gap} className={className}>\n {children}\n </Stack>\n );\n}\n"],"names":["useMantineTheme","useComputedColorScheme","brandColors","useId","jsxs","jsx","fairmintVars","Box","spacing","Stack","Text","Tooltip","ActionIcon"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { AriaRole, CSSProperties, ReactNode } from 'react';
2
+ export type AgentSuggestionTone = "info" | "warning" | "error";
3
+ export interface AgentSuggestionProps {
4
+ /** Short title — typically a humanized agent code label. */
5
+ title: ReactNode;
6
+ /** Supporting detail from the agent. */
7
+ message?: ReactNode;
8
+ /**
9
+ * Semantic meaning. `error` / `warning` use severity surfaces because they
10
+ * map to actionable / blocking review states in CaptableAI. `info` stays
11
+ * CaptableAI-branded (blue→purple accent).
12
+ * @default "info"
13
+ */
14
+ tone?: AgentSuggestionTone;
15
+ /**
16
+ * Leading icon. Pass `null` to hide.
17
+ * When omitted, the CaptableAI brand mark is shown.
18
+ */
19
+ icon?: ReactNode | null;
20
+ /** When set, renders a dismiss control. */
21
+ onDismiss?: () => void;
22
+ /** Accessible label for the dismiss control. @default "Dismiss" */
23
+ dismissLabel?: string;
24
+ /** Override the default accessible role. Error defaults to alert; other tones use status. */
25
+ role?: AriaRole;
26
+ className?: string;
27
+ style?: CSSProperties;
28
+ }
29
+ /**
30
+ * Dense, agent-originated review note. Distinct from Alert/Banner so stacked
31
+ * suggestions do not compete with a single page-level severity summary.
32
+ *
33
+ * Pattern candidate: compose a list of `AgentSuggestion` under one parent
34
+ * Alert or Banner ("N suggestions need review") — never N banners.
35
+ */
36
+ export declare function AgentSuggestion({ title, message, tone, icon, onDismiss, dismissLabel, role, className, style, }: AgentSuggestionProps): import("react/jsx-runtime").JSX.Element;
37
+ /** Convenience stack for composing multiple agent suggestions without inventing layout. */
38
+ export interface AgentSuggestionListProps {
39
+ children: ReactNode;
40
+ gap?: number | string;
41
+ className?: string;
42
+ }
43
+ export declare function AgentSuggestionList({ children, gap, className, }: AgentSuggestionListProps): import("react/jsx-runtime").JSX.Element;
44
+ //# sourceMappingURL=AgentSuggestion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentSuggestion.d.ts","sourceRoot":"","sources":["../../../../src/components/generic/AgentSuggestion/AgentSuggestion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOhE,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/D,MAAM,WAAW,oBAAoB;IACnC,4DAA4D;IAC5D,KAAK,EAAE,SAAS,CAAC;IACjB,wCAAwC;IACxC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAoFD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,OAAO,EACP,IAAa,EACb,IAAI,EACJ,SAAS,EACT,YAAwB,EACxB,IAAI,EACJ,SAAS,EACT,KAAK,GACN,EAAE,oBAAoB,2CAqGtB;AAED,2FAA2F;AAC3F,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,GAAgB,EAChB,SAAS,GACV,EAAE,wBAAwB,2CAM1B"}
@@ -0,0 +1,186 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useId } from "react";
3
+ import { fairmintVars, brandColors } from "../../../theme/index.js";
4
+ import { ActionIcon } from "../../primitives/ActionIcon/ActionIcon.js";
5
+ import { Box, Stack } from "../../primitives/layout.js";
6
+ import { Tooltip } from "../../primitives/Tooltip/Tooltip.js";
7
+ import { spacing } from "../../../theme/spacing.js";
8
+ import { Text } from "../../../node_modules/@mantine/core/esm/components/Text/Text.js";
9
+ import { useMantineTheme } from "../../../node_modules/@mantine/core/esm/core/MantineProvider/MantineThemeProvider/MantineThemeProvider.js";
10
+ import { useComputedColorScheme } from "../../../node_modules/@mantine/core/esm/core/MantineProvider/use-mantine-color-scheme/use-computed-color-scheme.js";
11
+ function useCaptableAiBrandPaint() {
12
+ const theme = useMantineTheme();
13
+ const scheme = useComputedColorScheme("light");
14
+ const dark = scheme === "dark";
15
+ const blue = dark ? theme.colors.fairmintBlue[3] : brandColors.blue;
16
+ const purple = dark ? theme.colors.fairmintPurple[2] : brandColors.purple;
17
+ const markStops = dark ? ["#D0F8FF", "#AEEBFF", "#557CFF"] : ["#557CFF", theme.colors.fairmintBlue[4], brandColors.blue];
18
+ return {
19
+ blue,
20
+ purple,
21
+ markStops,
22
+ accent: `linear-gradient(180deg, ${blue} 0%, ${purple} 100%)`
23
+ };
24
+ }
25
+ const CAPTABLE_AI_MARK_PATH = "M 120 2 L 73 48 L 16 81 L 17 134 L 16 148 L 12 166 L 5 187 L 0 212 L 47 261 L 78 315 L 141 316 L 153 318 L 187 328 L 210 333 L 253 290 L 276 275 L 314 254 L 314 194 L 315 185 L 331 126 L 331 122 L 284 74 L 252 19 L 185 18 L 160 12 L 131 3 Z M 15 208 L 23 178 L 26 177 L 93 216 L 101 213 L 148 185 L 154 184 L 140 237 L 138 241 L 67 260 Z M 168 187 L 180 206 L 198 239 L 163 300 L 161 302 L 88 302 L 85 299 L 71 274 L 78 271 L 150 252 L 166 191 Z M 125 17 L 143 21 L 157 26 L 126 78 L 116 97 L 147 149 L 148 155 L 115 147 L 92 140 L 73 69 Z M 56 74 L 60 74 L 79 148 L 81 152 L 135 166 L 146 170 L 94 200 L 31 163 L 30 136 L 31 90 L 37 85 Z M 235 135 L 238 135 L 300 171 L 301 244 L 298 247 L 272 262 L 270 259 L 251 184 L 249 182 L 190 167 L 186 164 Z M 316 128 L 307 159 L 236 118 L 178 152 L 178 146 L 184 127 L 186 116 L 192 95 L 194 93 L 260 75 L 264 75 Z M 181 180 L 187 180 L 191 182 L 232 192 L 239 195 L 252 246 L 258 265 L 205 318 L 178 311 L 174 308 L 214 239 L 204 219 L 190 197 Z M 242 32 L 245 35 L 259 60 L 257 62 L 239 66 L 181 82 L 163 148 L 159 143 L 133 98 L 133 95 L 169 34 L 183 32 L 219 33 Z";
26
+ function CaptableAiMarkIcon({ stops }) {
27
+ const rawId = useId();
28
+ const gradId = `agent-suggestion-captable-ai-mark-${rawId.replace(/:/g, "")}`;
29
+ const [start, mid, end] = stops;
30
+ return /* @__PURE__ */ jsxs(
31
+ "svg",
32
+ {
33
+ width: 16,
34
+ height: 16,
35
+ viewBox: "0 0 333 334",
36
+ fill: "none",
37
+ "aria-hidden": "true",
38
+ focusable: "false",
39
+ "data-captable-ai-mark": "",
40
+ children: [
41
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradId, x1: "0", y1: "0", x2: "1", y2: "1", children: [
42
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: start, "data-mark-stop": "start" }),
43
+ /* @__PURE__ */ jsx("stop", { offset: "48%", stopColor: mid, "data-mark-stop": "mid" }),
44
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: end, "data-mark-stop": "end" })
45
+ ] }) }),
46
+ /* @__PURE__ */ jsx(
47
+ "path",
48
+ {
49
+ fill: `url(#${gradId})`,
50
+ fillRule: "evenodd",
51
+ clipRule: "evenodd",
52
+ d: CAPTABLE_AI_MARK_PATH
53
+ }
54
+ )
55
+ ]
56
+ }
57
+ );
58
+ }
59
+ function DismissIcon() {
60
+ return /* @__PURE__ */ jsxs(
61
+ "svg",
62
+ {
63
+ "aria-hidden": "true",
64
+ width: "14",
65
+ height: "14",
66
+ viewBox: "0 0 24 24",
67
+ fill: "none",
68
+ stroke: "currentColor",
69
+ strokeWidth: "2",
70
+ strokeLinecap: "round",
71
+ strokeLinejoin: "round",
72
+ children: [
73
+ /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
74
+ /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
75
+ ]
76
+ }
77
+ );
78
+ }
79
+ function AgentSuggestion({
80
+ title,
81
+ message,
82
+ tone = "info",
83
+ icon,
84
+ onDismiss,
85
+ dismissLabel = "Dismiss",
86
+ role,
87
+ className,
88
+ style
89
+ }) {
90
+ const brand = useCaptableAiBrandPaint();
91
+ const resolvedRole = role ?? (tone === "error" ? "alert" : "status");
92
+ const resolvedIcon = icon === null ? null : icon ?? /* @__PURE__ */ jsx(CaptableAiMarkIcon, { stops: brand.markStops });
93
+ const surface = tone === "warning" ? {
94
+ background: "transparent",
95
+ border: fairmintVars.colorWarningBorder,
96
+ accent: fairmintVars.colorWarningBorder
97
+ } : tone === "error" ? {
98
+ background: "transparent",
99
+ border: fairmintVars.colorErrorBorder,
100
+ accent: fairmintVars.colorErrorSolid
101
+ } : {
102
+ background: "transparent",
103
+ border: fairmintVars.colorBorderDefault,
104
+ accent: brand.accent
105
+ };
106
+ return /* @__PURE__ */ jsxs(
107
+ Box,
108
+ {
109
+ className,
110
+ role: resolvedRole,
111
+ "data-tone": tone,
112
+ style: {
113
+ position: "relative",
114
+ display: "flex",
115
+ alignItems: "flex-start",
116
+ gap: spacing.xs,
117
+ backgroundColor: surface.background,
118
+ border: `1px solid ${surface.border}`,
119
+ borderRadius: 2,
120
+ paddingBlock: spacing.xs,
121
+ paddingInlineStart: spacing.sm,
122
+ paddingInlineEnd: spacing.xs,
123
+ overflow: "hidden",
124
+ ...style
125
+ },
126
+ children: [
127
+ /* @__PURE__ */ jsx(
128
+ Box,
129
+ {
130
+ "aria-hidden": true,
131
+ "data-accent": "",
132
+ style: {
133
+ position: "absolute",
134
+ insetBlock: 0,
135
+ insetInlineStart: 0,
136
+ width: 3,
137
+ background: surface.accent
138
+ // No own radius — container overflow:hidden + borderRadius:2 clips flush.
139
+ }
140
+ }
141
+ ),
142
+ resolvedIcon ? /* @__PURE__ */ jsx(
143
+ Box,
144
+ {
145
+ style: {
146
+ display: "flex",
147
+ flexShrink: 0,
148
+ marginTop: 2,
149
+ width: 16,
150
+ height: 16
151
+ },
152
+ children: resolvedIcon
153
+ }
154
+ ) : null,
155
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: 1, minWidth: 0 }, children: [
156
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, c: fairmintVars.colorTextPrimary, lh: 1.3, children: title }),
157
+ message ? /* @__PURE__ */ jsx(Text, { size: "xs", c: fairmintVars.colorTextSecondary, lh: 1.4, children: message }) : null
158
+ ] }),
159
+ onDismiss ? /* @__PURE__ */ jsx(Tooltip, { label: dismissLabel, withArrow: true, position: "top", children: /* @__PURE__ */ jsx(
160
+ ActionIcon,
161
+ {
162
+ size: "sm",
163
+ variant: "subtle",
164
+ color: "gray",
165
+ "aria-label": dismissLabel,
166
+ onClick: onDismiss,
167
+ style: { flexShrink: 0, marginTop: -2 },
168
+ children: /* @__PURE__ */ jsx(DismissIcon, {})
169
+ }
170
+ ) }) : null
171
+ ]
172
+ }
173
+ );
174
+ }
175
+ function AgentSuggestionList({
176
+ children,
177
+ gap = spacing.xs,
178
+ className
179
+ }) {
180
+ return /* @__PURE__ */ jsx(Stack, { gap, className, children });
181
+ }
182
+ export {
183
+ AgentSuggestion,
184
+ AgentSuggestionList
185
+ };
186
+ //# sourceMappingURL=AgentSuggestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentSuggestion.js","sources":["../../../../src/components/generic/AgentSuggestion/AgentSuggestion.tsx"],"sourcesContent":["import type { AriaRole, CSSProperties, ReactNode } from \"react\";\nimport { useId } from \"react\";\nimport { brandColors, fairmintVars, spacing } from \"../../../theme\";\nimport { ActionIcon } from \"../../primitives/ActionIcon/ActionIcon\";\nimport { Box, Stack, Text, useComputedColorScheme, useMantineTheme } from \"../../primitives/layout\";\nimport { Tooltip } from \"../../primitives/Tooltip/Tooltip\";\n\nexport type AgentSuggestionTone = \"info\" | \"warning\" | \"error\";\n\nexport interface AgentSuggestionProps {\n /** Short title — typically a humanized agent code label. */\n title: ReactNode;\n /** Supporting detail from the agent. */\n message?: ReactNode;\n /**\n * Semantic meaning. `error` / `warning` use severity surfaces because they\n * map to actionable / blocking review states in CaptableAI. `info` stays\n * CaptableAI-branded (blue→purple accent).\n * @default \"info\"\n */\n tone?: AgentSuggestionTone;\n /**\n * Leading icon. Pass `null` to hide.\n * When omitted, the CaptableAI brand mark is shown.\n */\n icon?: ReactNode | null;\n /** When set, renders a dismiss control. */\n onDismiss?: () => void;\n /** Accessible label for the dismiss control. @default \"Dismiss\" */\n dismissLabel?: string;\n /** Override the default accessible role. Error defaults to alert; other tones use status. */\n role?: AriaRole;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * CaptableAI brand stops for the left accent (Fairmint blue→purple) and the\n * logo-symbol mark (CaptableAI cyan→blue). Dark mode uses the official\n * CaptableAILogoSymbol gradient so the mark reads on charcoal; light mode\n * shifts toward stronger blues for contrast on white.\n */\nfunction useCaptableAiBrandPaint() {\n const theme = useMantineTheme();\n const scheme = useComputedColorScheme(\"light\");\n const dark = scheme === \"dark\";\n\n const blue = dark ? theme.colors.fairmintBlue[3] : brandColors.blue;\n const purple = dark ? theme.colors.fairmintPurple[2] : brandColors.purple;\n\n // From studiov2 CaptableAILogoSymbol.svg (dark / brand-on-navy).\n const markStops: [string, string, string] = dark\n ? [\"#D0F8FF\", \"#AEEBFF\", \"#557CFF\"]\n : [\"#557CFF\", theme.colors.fairmintBlue[4], brandColors.blue];\n\n return {\n blue,\n purple,\n markStops,\n accent: `linear-gradient(180deg, ${blue} 0%, ${purple} 100%)`,\n };\n}\n\n/** CaptableAI logo symbol path — studiov2 `CaptableAILogoSymbol.svg` / `captable-ai-icon.svg`. */\nconst CAPTABLE_AI_MARK_PATH =\n \"M 120 2 L 73 48 L 16 81 L 17 134 L 16 148 L 12 166 L 5 187 L 0 212 L 47 261 L 78 315 L 141 316 L 153 318 L 187 328 L 210 333 L 253 290 L 276 275 L 314 254 L 314 194 L 315 185 L 331 126 L 331 122 L 284 74 L 252 19 L 185 18 L 160 12 L 131 3 Z M 15 208 L 23 178 L 26 177 L 93 216 L 101 213 L 148 185 L 154 184 L 140 237 L 138 241 L 67 260 Z M 168 187 L 180 206 L 198 239 L 163 300 L 161 302 L 88 302 L 85 299 L 71 274 L 78 271 L 150 252 L 166 191 Z M 125 17 L 143 21 L 157 26 L 126 78 L 116 97 L 147 149 L 148 155 L 115 147 L 92 140 L 73 69 Z M 56 74 L 60 74 L 79 148 L 81 152 L 135 166 L 146 170 L 94 200 L 31 163 L 30 136 L 31 90 L 37 85 Z M 235 135 L 238 135 L 300 171 L 301 244 L 298 247 L 272 262 L 270 259 L 251 184 L 249 182 L 190 167 L 186 164 Z M 316 128 L 307 159 L 236 118 L 178 152 L 178 146 L 184 127 L 186 116 L 192 95 L 194 93 L 260 75 L 264 75 Z M 181 180 L 187 180 L 191 182 L 232 192 L 239 195 L 252 246 L 258 265 L 205 318 L 178 311 L 174 308 L 214 239 L 204 219 L 190 197 Z M 242 32 L 245 35 L 259 60 L 257 62 L 239 66 L 181 82 L 163 148 L 159 143 L 133 98 L 133 95 L 169 34 L 183 32 L 219 33 Z\";\n\nfunction CaptableAiMarkIcon({ stops }: { stops: [string, string, string] }) {\n const rawId = useId();\n const gradId = `agent-suggestion-captable-ai-mark-${rawId.replace(/:/g, \"\")}`;\n const [start, mid, end] = stops;\n\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 333 334\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n data-captable-ai-mark=\"\"\n >\n <defs>\n <linearGradient id={gradId} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stopColor={start} data-mark-stop=\"start\" />\n <stop offset=\"48%\" stopColor={mid} data-mark-stop=\"mid\" />\n <stop offset=\"100%\" stopColor={end} data-mark-stop=\"end\" />\n </linearGradient>\n </defs>\n <path\n fill={`url(#${gradId})`}\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d={CAPTABLE_AI_MARK_PATH}\n />\n </svg>\n );\n}\n\nfunction DismissIcon() {\n return (\n <svg\n aria-hidden=\"true\"\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 >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/**\n * Dense, agent-originated review note. Distinct from Alert/Banner so stacked\n * suggestions do not compete with a single page-level severity summary.\n *\n * Pattern candidate: compose a list of `AgentSuggestion` under one parent\n * Alert or Banner (\"N suggestions need review\") — never N banners.\n */\nexport function AgentSuggestion({\n title,\n message,\n tone = \"info\",\n icon,\n onDismiss,\n dismissLabel = \"Dismiss\",\n role,\n className,\n style,\n}: AgentSuggestionProps) {\n const brand = useCaptableAiBrandPaint();\n const resolvedRole = role ?? (tone === \"error\" ? \"alert\" : \"status\");\n const resolvedIcon =\n icon === null ? null : (icon ?? <CaptableAiMarkIcon stops={brand.markStops} />);\n\n // Warning accent shares the border token so the strip reads orange (not the\n // red-adjacent Solid). Error keeps Solid — in dark it matches the border.\n const surface =\n tone === \"warning\"\n ? {\n background: \"transparent\",\n border: fairmintVars.colorWarningBorder,\n accent: fairmintVars.colorWarningBorder,\n }\n : tone === \"error\"\n ? {\n background: \"transparent\",\n border: fairmintVars.colorErrorBorder,\n accent: fairmintVars.colorErrorSolid,\n }\n : {\n background: \"transparent\",\n border: fairmintVars.colorBorderDefault,\n accent: brand.accent,\n };\n\n return (\n <Box\n className={className}\n role={resolvedRole}\n data-tone={tone}\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: spacing.xs,\n backgroundColor: surface.background,\n border: `1px solid ${surface.border}`,\n borderRadius: 2,\n paddingBlock: spacing.xs,\n paddingInlineStart: spacing.sm,\n paddingInlineEnd: spacing.xs,\n overflow: \"hidden\",\n ...style,\n }}\n >\n <Box\n aria-hidden\n data-accent=\"\"\n style={{\n position: \"absolute\",\n insetBlock: 0,\n insetInlineStart: 0,\n width: 3,\n background: surface.accent,\n // No own radius — container overflow:hidden + borderRadius:2 clips flush.\n }}\n />\n\n {resolvedIcon ? (\n <Box\n style={{\n display: \"flex\",\n flexShrink: 0,\n marginTop: 2,\n width: 16,\n height: 16,\n }}\n >\n {resolvedIcon}\n </Box>\n ) : null}\n\n <Stack gap={4} style={{ flex: 1, minWidth: 0 }}>\n <Text size=\"sm\" fw={500} c={fairmintVars.colorTextPrimary} lh={1.3}>\n {title}\n </Text>\n {message ? (\n <Text size=\"xs\" c={fairmintVars.colorTextSecondary} lh={1.4}>\n {message}\n </Text>\n ) : null}\n </Stack>\n\n {onDismiss ? (\n <Tooltip label={dismissLabel} withArrow position=\"top\">\n <ActionIcon\n size=\"sm\"\n variant=\"subtle\"\n color=\"gray\"\n aria-label={dismissLabel}\n onClick={onDismiss}\n style={{ flexShrink: 0, marginTop: -2 }}\n >\n <DismissIcon />\n </ActionIcon>\n </Tooltip>\n ) : null}\n </Box>\n );\n}\n\n/** Convenience stack for composing multiple agent suggestions without inventing layout. */\nexport interface AgentSuggestionListProps {\n children: ReactNode;\n gap?: number | string;\n className?: string;\n}\n\nexport function AgentSuggestionList({\n children,\n gap = spacing.xs,\n className,\n}: AgentSuggestionListProps) {\n return (\n <Stack gap={gap} className={className}>\n {children}\n </Stack>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const index = require("../../../theme/index.cjs");
5
+ const colors = require("../../../theme/colors.cjs");
6
+ const ActionIcon = require("../../primitives/ActionIcon/ActionIcon.cjs");
7
+ const Badge = require("../../primitives/Badge/Badge.cjs");
8
+ const layout = require("../../primitives/layout.cjs");
9
+ const ColorDot = require("../ColorDot/ColorDot.cjs");
10
+ const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
11
+ const Text = require("../../../node_modules/@mantine/core/esm/components/Text/Text.cjs");
12
+ const SEVERITY_BADGE_COLORS = {
13
+ critical: colors.colors.error,
14
+ high: colors.colors.warning,
15
+ medium: colors.colors.info,
16
+ low: colors.colors.neutral,
17
+ info: colors.colors.info,
18
+ success: colors.colors.success,
19
+ resolved: colors.colors.success
20
+ };
21
+ const DEFAULT_SEVERITY_LABELS = {
22
+ critical: "Critical",
23
+ high: "High",
24
+ medium: "Medium",
25
+ low: "Low",
26
+ info: "Info",
27
+ success: "Success",
28
+ resolved: "Completed"
29
+ };
30
+ function DefaultCheckIcon() {
31
+ return /* @__PURE__ */ jsxRuntime.jsx(
32
+ "svg",
33
+ {
34
+ "aria-hidden": "true",
35
+ width: "16",
36
+ height: "16",
37
+ viewBox: "0 0 24 24",
38
+ fill: "none",
39
+ stroke: "currentColor",
40
+ strokeWidth: "2",
41
+ strokeLinecap: "round",
42
+ strokeLinejoin: "round",
43
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" })
44
+ }
45
+ );
46
+ }
47
+ function DefaultMailIcon() {
48
+ return /* @__PURE__ */ jsxRuntime.jsxs(
49
+ "svg",
50
+ {
51
+ "aria-hidden": "true",
52
+ width: "16",
53
+ height: "16",
54
+ viewBox: "0 0 24 24",
55
+ fill: "none",
56
+ stroke: "currentColor",
57
+ strokeWidth: "2",
58
+ strokeLinecap: "round",
59
+ strokeLinejoin: "round",
60
+ children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 4h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" }),
62
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m22 6-10 7L2 6" })
63
+ ]
64
+ }
65
+ );
66
+ }
67
+ function NotificationRow({
68
+ ariaLabel,
69
+ body,
70
+ className,
71
+ isUnread = false,
72
+ onToggleRead,
73
+ severity = "medium",
74
+ severityLabel,
75
+ timestamp,
76
+ title,
77
+ toggleReadLabel,
78
+ variant = "standalone",
79
+ withDivider = true
80
+ }) {
81
+ const resolvedSeverityLabel = severityLabel ?? DEFAULT_SEVERITY_LABELS[severity];
82
+ const resolvedToggleReadLabel = toggleReadLabel ?? (isUnread ? `Mark read: ${title}` : `Mark unread: ${title}`);
83
+ const readStateLabel = isUnread ? "Unread notification" : "Read notification";
84
+ const resolvedAriaLabel = ariaLabel ?? (timestamp ? `${title}. ${resolvedSeverityLabel}. ${readStateLabel}. ${timestamp}` : `${title}. ${resolvedSeverityLabel}. ${readStateLabel}`);
85
+ const isList = variant === "list";
86
+ const badgeColor = SEVERITY_BADGE_COLORS[severity];
87
+ return /* @__PURE__ */ jsxRuntime.jsx(
88
+ layout.Box,
89
+ {
90
+ "aria-label": resolvedAriaLabel,
91
+ role: "group",
92
+ className,
93
+ "data-severity": severity,
94
+ "data-testid": "notification-row",
95
+ "data-unread": isUnread || void 0,
96
+ "data-variant": variant,
97
+ px: "md",
98
+ py: "sm",
99
+ w: "100%",
100
+ style: {
101
+ backgroundColor: isUnread ? index.fairmintVars.colorBgSurface : index.fairmintVars.colorBgSurfaceSecondary,
102
+ border: isList ? "none" : `1px solid ${index.fairmintVars.colorBorderDefault}`,
103
+ borderBottom: isList && withDivider ? `1px solid ${index.fairmintVars.colorBorderDefault}` : void 0,
104
+ borderRadius: isList ? 0 : 10
105
+ },
106
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { align: "flex-start", gap: "sm", justify: "space-between", wrap: "nowrap", children: [
107
+ /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { align: "flex-start", gap: "sm", miw: 0, wrap: "nowrap", style: { flex: 1 }, children: [
108
+ /* @__PURE__ */ jsxRuntime.jsx(
109
+ layout.Box,
110
+ {
111
+ "aria-hidden": true,
112
+ mt: 6,
113
+ style: {
114
+ flexShrink: 0,
115
+ width: 8,
116
+ display: "flex",
117
+ justifyContent: "center"
118
+ },
119
+ children: /* @__PURE__ */ jsxRuntime.jsx(
120
+ ColorDot.ColorDot,
121
+ {
122
+ color: isUnread ? index.fairmintVars.colorBrandPrimary : index.fairmintVars.colorBorderDisabled,
123
+ size: 8
124
+ }
125
+ )
126
+ }
127
+ ),
128
+ /* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { gap: 4, miw: 0, style: { flex: 1 }, children: [
129
+ /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { color: badgeColor, size: "xs", variant: "light", children: resolvedSeverityLabel }),
130
+ /* @__PURE__ */ jsxRuntime.jsx(
131
+ Text.Text,
132
+ {
133
+ fw: isUnread ? 600 : 500,
134
+ lineClamp: 2,
135
+ size: "sm",
136
+ c: index.fairmintVars.colorTextPrimary,
137
+ style: { minWidth: 0 },
138
+ children: title
139
+ }
140
+ ),
141
+ /* @__PURE__ */ jsxRuntime.jsx(
142
+ Text.Text,
143
+ {
144
+ c: index.fairmintVars.colorTextSecondary,
145
+ lineClamp: 3,
146
+ size: "sm",
147
+ style: { minWidth: 0 },
148
+ children: body
149
+ }
150
+ )
151
+ ] })
152
+ ] }),
153
+ onToggleRead ? /* @__PURE__ */ jsxRuntime.jsx(
154
+ ActionIcon.ActionIcon,
155
+ {
156
+ "aria-label": resolvedToggleReadLabel,
157
+ color: colors.colors.neutral,
158
+ onClick: onToggleRead,
159
+ size: "md",
160
+ variant: "subtle",
161
+ children: isUnread ? /* @__PURE__ */ jsxRuntime.jsx(DefaultCheckIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(DefaultMailIcon, {})
162
+ }
163
+ ) : null
164
+ ] })
165
+ }
166
+ );
167
+ }
168
+ exports.NotificationRow = NotificationRow;
169
+ //# sourceMappingURL=NotificationRow.cjs.map