@fairmint/ui 0.3.0 → 0.3.1

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 (38) hide show
  1. package/dist/_virtual/index3.cjs +5 -3
  2. package/dist/_virtual/index3.cjs.map +1 -1
  3. package/dist/_virtual/index3.js +5 -2
  4. package/dist/_virtual/index3.js.map +1 -1
  5. package/dist/_virtual/index4.cjs +3 -5
  6. package/dist/_virtual/index4.cjs.map +1 -1
  7. package/dist/_virtual/index4.js +2 -5
  8. package/dist/_virtual/index4.js.map +1 -1
  9. package/dist/components/generic/Banner/Banner.cjs +200 -0
  10. package/dist/components/generic/Banner/Banner.cjs.map +1 -0
  11. package/dist/components/generic/Banner/Banner.d.ts +36 -0
  12. package/dist/components/generic/Banner/Banner.d.ts.map +1 -0
  13. package/dist/components/generic/Banner/Banner.js +200 -0
  14. package/dist/components/generic/Banner/Banner.js.map +1 -0
  15. package/dist/components/generic/FileDropzone/FileDropzone.cjs +396 -0
  16. package/dist/components/generic/FileDropzone/FileDropzone.cjs.map +1 -0
  17. package/dist/components/generic/FileDropzone/FileDropzone.d.ts +91 -0
  18. package/dist/components/generic/FileDropzone/FileDropzone.d.ts.map +1 -0
  19. package/dist/components/generic/FileDropzone/FileDropzone.js +396 -0
  20. package/dist/components/generic/FileDropzone/FileDropzone.js.map +1 -0
  21. package/dist/fairmint-ui.cjs +6 -0
  22. package/dist/fairmint-ui.cjs.map +1 -1
  23. package/dist/fairmint-ui.js +6 -0
  24. package/dist/fairmint-ui.js.map +1 -1
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/node_modules/@mantine/form/esm/hooks/use-form-status/use-form-status.cjs +1 -1
  28. package/dist/node_modules/@mantine/form/esm/hooks/use-form-status/use-form-status.js +1 -1
  29. package/dist/node_modules/prop-types/index.cjs +1 -1
  30. package/dist/node_modules/prop-types/index.js +1 -1
  31. package/dist/styles.css +73 -0
  32. package/dist/theme/index.cjs +4 -0
  33. package/dist/theme/index.cjs.map +1 -1
  34. package/dist/theme/index.d.ts +2 -0
  35. package/dist/theme/index.d.ts.map +1 -1
  36. package/dist/theme/index.js +4 -0
  37. package/dist/theme/index.js.map +1 -1
  38. package/package.json +1 -1
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- var propTypes = { exports: {} };
4
- exports.__module = propTypes;
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":";;;;;;"}
@@ -1,5 +1,8 @@
1
- var propTypes = { exports: {} };
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
- propTypes as __module
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":";;;;"}
@@ -1,7 +1,5 @@
1
1
  "use strict";
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;
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":";;;;"}
@@ -1,8 +1,5 @@
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);
1
+ var propTypes = { exports: {} };
5
2
  export {
6
- isEqual as default
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":";"}
@@ -0,0 +1,200 @@
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 Badge = require("../../primitives/Badge/Badge.cjs");
7
+ const Button = require("../../primitives/Button/Button.cjs");
8
+ const layout = require("../../primitives/layout.cjs");
9
+ const Group = require("../../../node_modules/@mantine/core/esm/components/Group/Group.cjs");
10
+ const ThemeIcon = require("../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.cjs");
11
+ const Text = require("../../../node_modules/@mantine/core/esm/components/Text/Text.cjs");
12
+ const fontSizes = require("../../../theme/fontSizes.cjs");
13
+ const TONE_COLORS = {
14
+ brand: colors.colors.primary,
15
+ neutral: colors.colors.neutral,
16
+ info: colors.colors.info,
17
+ success: colors.colors.success,
18
+ warning: colors.colors.warning,
19
+ error: colors.colors.error
20
+ };
21
+ const DefaultStatusIcon = ({ tone }) => {
22
+ const commonProps = {
23
+ width: 20,
24
+ height: 20,
25
+ viewBox: "0 0 24 24",
26
+ fill: "none",
27
+ stroke: "currentColor",
28
+ strokeWidth: 1.75,
29
+ strokeLinecap: "round",
30
+ strokeLinejoin: "round",
31
+ "aria-hidden": true
32
+ };
33
+ if (tone === "success") {
34
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...commonProps, children: [
35
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: "Success" }),
36
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "9" }),
37
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m8.5 12 2.25 2.25L15.75 9" })
38
+ ] });
39
+ }
40
+ if (tone === "warning") {
41
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...commonProps, children: [
42
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: "Warning" }),
43
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10.3 4.2 2.6 18a2 2 0 0 0 1.75 3h15.3a2 2 0 0 0 1.75-3L13.7 4.2a2 2 0 0 0-3.4 0Z" }),
44
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 9v4" }),
45
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 17h.01" })
46
+ ] });
47
+ }
48
+ if (tone === "error") {
49
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...commonProps, children: [
50
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: "Error" }),
51
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "9" }),
52
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 9 6 6" }),
53
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m15 9-6 6" })
54
+ ] });
55
+ }
56
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...commonProps, children: [
57
+ /* @__PURE__ */ jsxRuntime.jsx("title", { children: "Information" }),
58
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "9" }),
59
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 11v5" }),
60
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 8h.01" })
61
+ ] });
62
+ };
63
+ const surfaceProps = (tone, presentation) => {
64
+ const color = TONE_COLORS[tone];
65
+ if (presentation === "page-level") {
66
+ return {
67
+ bg: `${color}.1`,
68
+ style: {
69
+ borderRadius: 0
70
+ }
71
+ };
72
+ }
73
+ const borderShade = tone === "brand" ? 1 : tone === "neutral" ? 3 : 2;
74
+ return {
75
+ bg: `${color}.0`,
76
+ bd: `1px solid ${color}.${borderShade}`,
77
+ style: {
78
+ borderRadius: index.radii.lg
79
+ }
80
+ };
81
+ };
82
+ const titleColor = (tone, presentation) => {
83
+ if (presentation === "page-level") {
84
+ const color = TONE_COLORS[tone];
85
+ return `${color}.${tone === "neutral" ? 9 : 8}`;
86
+ }
87
+ return index.neutralColors[900];
88
+ };
89
+ const actionVariant = (tone) => {
90
+ if (tone === "brand") return "light";
91
+ if (tone === "neutral") return "outline";
92
+ return "filled";
93
+ };
94
+ const descriptionTextProps = {
95
+ size: "sm",
96
+ c: index.neutralColors[500],
97
+ style: { lineHeight: 1.4 }
98
+ };
99
+ function BannerDescription({ children }) {
100
+ if (typeof children === "string" || typeof children === "number") {
101
+ return /* @__PURE__ */ jsxRuntime.jsx(Text.Text, { ...descriptionTextProps, children });
102
+ }
103
+ return /* @__PURE__ */ jsxRuntime.jsx(
104
+ layout.Box,
105
+ {
106
+ c: index.neutralColors[500],
107
+ style: {
108
+ fontSize: fontSizes.fontSizes.sm,
109
+ lineHeight: 1.4
110
+ },
111
+ children
112
+ }
113
+ );
114
+ }
115
+ function Banner({
116
+ action,
117
+ ariaLabel,
118
+ badgeLabel,
119
+ className,
120
+ description,
121
+ icon,
122
+ presentation = "inline",
123
+ role,
124
+ style,
125
+ title,
126
+ tone = "brand"
127
+ }) {
128
+ const color = TONE_COLORS[tone];
129
+ const iconNode = icon === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(DefaultStatusIcon, { tone }) : icon;
130
+ const resolvedRole = role ?? (tone === "error" ? "alert" : "status");
131
+ const resolvedAriaLabel = ariaLabel ?? (typeof title === "string" ? title : void 0);
132
+ const surface = surfaceProps(tone, presentation);
133
+ let actionNode = null;
134
+ if (action !== void 0) {
135
+ const { label, ...buttonProps } = action;
136
+ actionNode = /* @__PURE__ */ jsxRuntime.jsx(
137
+ Button.Button,
138
+ {
139
+ ...buttonProps,
140
+ color,
141
+ variant: actionVariant(tone),
142
+ style: { flex: "0 0 auto", ...buttonProps.style },
143
+ children: label
144
+ }
145
+ );
146
+ }
147
+ return /* @__PURE__ */ jsxRuntime.jsx(
148
+ layout.Box,
149
+ {
150
+ "aria-label": resolvedAriaLabel,
151
+ className,
152
+ "data-presentation": presentation,
153
+ "data-tone": tone,
154
+ role: resolvedRole,
155
+ px: "md",
156
+ py: "md",
157
+ bg: surface.bg,
158
+ bd: "bd" in surface ? surface.bd : void 0,
159
+ style: {
160
+ boxSizing: "border-box",
161
+ width: "100%",
162
+ ...surface.style,
163
+ ...style
164
+ },
165
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { align: "center", gap: "sm", wrap: "wrap", children: [
166
+ iconNode !== null && /* @__PURE__ */ jsxRuntime.jsx(
167
+ ThemeIcon.ThemeIcon,
168
+ {
169
+ "aria-hidden": true,
170
+ color,
171
+ radius: "sm",
172
+ size: 40,
173
+ variant: "light",
174
+ style: { flex: "0 0 auto" },
175
+ children: iconNode
176
+ }
177
+ ),
178
+ /* @__PURE__ */ jsxRuntime.jsxs(layout.Stack, { gap: 4, style: { flex: "1 1 240px", minWidth: 0 }, children: [
179
+ title !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(Group.Group, { align: "center", gap: "xs", wrap: "wrap", children: [
180
+ /* @__PURE__ */ jsxRuntime.jsx(
181
+ Text.Text,
182
+ {
183
+ fw: 600,
184
+ size: "md",
185
+ c: titleColor(tone, presentation),
186
+ style: { lineHeight: 1.35 },
187
+ children: title
188
+ }
189
+ ),
190
+ badgeLabel !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { color, size: "sm", variant: "light", children: badgeLabel })
191
+ ] }),
192
+ description !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(BannerDescription, { children: description })
193
+ ] }),
194
+ actionNode
195
+ ] })
196
+ }
197
+ );
198
+ }
199
+ exports.Banner = Banner;
200
+ //# sourceMappingURL=Banner.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.cjs","sources":["../../../../src/components/generic/Banner/Banner.tsx"],"sourcesContent":["import type { AriaRole, CSSProperties, ReactNode } from \"react\";\nimport { fontSizes, neutralColors, radii } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { Badge } from \"../../primitives/Badge/Badge\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Stack, Text, ThemeIcon } from \"../../primitives/layout\";\n\nexport type BannerTone = \"brand\" | \"neutral\" | \"info\" | \"success\" | \"warning\" | \"error\";\nexport type BannerPresentation = \"inline\" | \"page-level\";\n\nexport interface BannerActionProps extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\"> {\n /** Visible action label. */\n label: ReactNode;\n}\n\nexport interface BannerProps {\n /** Primary message. Omit when the banner is description-only; set `ariaLabel` for accessibility. */\n title?: ReactNode;\n /** Supporting context. Omit for a title-only banner. */\n description?: ReactNode;\n /** Semantic meaning and visual treatment. @default \"brand\" */\n tone?: BannerTone;\n /** Inline content callout or full-width page-edge treatment. @default \"inline\" */\n presentation?: BannerPresentation;\n /** Icon shown in the 40px semantic tile. Pass `null` to hide the tile. */\n icon?: ReactNode | null;\n /** Optional badge label displayed beside the title. */\n badgeLabel?: ReactNode;\n /** Optional standardized CTA. */\n action?: BannerActionProps;\n /** Override the default accessible role. Error defaults to alert; other tones use status. */\n role?: AriaRole;\n /** Accessible label for the banner region. Defaults to the string title when possible. */\n ariaLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst TONE_COLORS = {\n brand: colors.primary,\n neutral: colors.neutral,\n info: colors.info,\n success: colors.success,\n warning: colors.warning,\n error: colors.error,\n} as const;\n\nconst DefaultStatusIcon = ({ tone }: { tone: BannerTone }) => {\n const commonProps = {\n width: 20,\n height: 20,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 1.75,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n \"aria-hidden\": true,\n };\n\n if (tone === \"success\") {\n return (\n <svg {...commonProps}>\n <title>Success</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m8.5 12 2.25 2.25L15.75 9\" />\n </svg>\n );\n }\n\n if (tone === \"warning\") {\n return (\n <svg {...commonProps}>\n <title>Warning</title>\n <path d=\"M10.3 4.2 2.6 18a2 2 0 0 0 1.75 3h15.3a2 2 0 0 0 1.75-3L13.7 4.2a2 2 0 0 0-3.4 0Z\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n }\n\n if (tone === \"error\") {\n return (\n <svg {...commonProps}>\n <title>Error</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m9 9 6 6\" />\n <path d=\"m15 9-6 6\" />\n </svg>\n );\n }\n\n return (\n <svg {...commonProps}>\n <title>Information</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 11v5\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n};\n\nconst surfaceProps = (tone: BannerTone, presentation: BannerPresentation) => {\n const color = TONE_COLORS[tone];\n\n if (presentation === \"page-level\") {\n return {\n bg: `${color}.1`,\n style: {\n borderRadius: 0,\n } satisfies CSSProperties,\n };\n }\n\n // Chip Banner: tinted surface + semantic border (error border = error.2)\n const borderShade = tone === \"brand\" ? 1 : tone === \"neutral\" ? 3 : 2;\n\n return {\n bg: `${color}.0`,\n bd: `1px solid ${color}.${borderShade}`,\n style: {\n borderRadius: radii.lg,\n } satisfies CSSProperties,\n };\n};\n\n/**\n * Inline Chip banners keep light semantic fills across color schemes, so titles\n * stay dark primary text for WCAG AA. Page-level uses a deeper semantic shade.\n */\nconst titleColor = (tone: BannerTone, presentation: BannerPresentation) => {\n if (presentation === \"page-level\") {\n const color = TONE_COLORS[tone];\n return `${color}.${tone === \"neutral\" ? 9 : 8}`;\n }\n return neutralColors[900];\n};\n\nconst actionVariant = (tone: BannerTone): ButtonProps[\"variant\"] => {\n if (tone === \"brand\") return \"light\";\n if (tone === \"neutral\") return \"outline\";\n return \"filled\";\n};\n\nconst descriptionTextProps = {\n size: \"sm\" as const,\n c: neutralColors[500],\n style: { lineHeight: 1.4 },\n};\n\nfunction BannerDescription({ children }: { children: ReactNode }) {\n if (typeof children === \"string\" || typeof children === \"number\") {\n return <Text {...descriptionTextProps}>{children}</Text>;\n }\n\n return (\n <Box\n c={neutralColors[500]}\n style={{\n fontSize: fontSizes.sm,\n lineHeight: 1.4,\n }}\n >\n {children}\n </Box>\n );\n}\n\n/**\n * Persistent contextual guidance with semantic inline and page-level presentations.\n * Position page-level banners in the consuming layout; the component does not use fixed positioning.\n */\nexport function Banner({\n action,\n ariaLabel,\n badgeLabel,\n className,\n description,\n icon,\n presentation = \"inline\",\n role,\n style,\n title,\n tone = \"brand\",\n}: BannerProps) {\n const color = TONE_COLORS[tone];\n const iconNode = icon === undefined ? <DefaultStatusIcon tone={tone} /> : icon;\n const resolvedRole = role ?? (tone === \"error\" ? \"alert\" : \"status\");\n const resolvedAriaLabel = ariaLabel ?? (typeof title === \"string\" ? title : undefined);\n const surface = surfaceProps(tone, presentation);\n let actionNode: ReactNode = null;\n\n if (action !== undefined) {\n const { label, ...buttonProps } = action;\n actionNode = (\n <Button\n {...buttonProps}\n color={color}\n variant={actionVariant(tone)}\n style={{ flex: \"0 0 auto\", ...buttonProps.style }}\n >\n {label}\n </Button>\n );\n }\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n className={className}\n data-presentation={presentation}\n data-tone={tone}\n role={resolvedRole}\n px=\"md\"\n py=\"md\"\n bg={surface.bg}\n bd={\"bd\" in surface ? surface.bd : undefined}\n style={{\n boxSizing: \"border-box\",\n width: \"100%\",\n ...surface.style,\n ...style,\n }}\n >\n <Group align=\"center\" gap=\"sm\" wrap=\"wrap\">\n {iconNode !== null && (\n <ThemeIcon\n aria-hidden\n color={color}\n radius=\"sm\"\n size={40}\n variant=\"light\"\n style={{ flex: \"0 0 auto\" }}\n >\n {iconNode}\n </ThemeIcon>\n )}\n\n <Stack gap={4} style={{ flex: \"1 1 240px\", minWidth: 0 }}>\n {title !== undefined && (\n <Group align=\"center\" gap=\"xs\" wrap=\"wrap\">\n <Text\n fw={600}\n size=\"md\"\n c={titleColor(tone, presentation)}\n style={{ lineHeight: 1.35 }}\n >\n {title}\n </Text>\n {badgeLabel !== undefined && (\n <Badge color={color} size=\"sm\" variant=\"light\">\n {badgeLabel}\n </Badge>\n )}\n </Group>\n )}\n {description !== undefined && <BannerDescription>{description}</BannerDescription>}\n </Stack>\n\n {actionNode}\n </Group>\n </Box>\n );\n}\n"],"names":["colors","jsxs","jsx","radii","neutralColors","Text","Box","fontSizes","Button","Group","ThemeIcon","Stack","Badge"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { AriaRole, CSSProperties, ReactNode } from 'react';
2
+ import { ButtonProps } from '../../primitives/Button/Button';
3
+ export type BannerTone = "brand" | "neutral" | "info" | "success" | "warning" | "error";
4
+ export type BannerPresentation = "inline" | "page-level";
5
+ export interface BannerActionProps extends Omit<ButtonProps, "children" | "color" | "variant"> {
6
+ /** Visible action label. */
7
+ label: ReactNode;
8
+ }
9
+ export interface BannerProps {
10
+ /** Primary message. Omit when the banner is description-only; set `ariaLabel` for accessibility. */
11
+ title?: ReactNode;
12
+ /** Supporting context. Omit for a title-only banner. */
13
+ description?: ReactNode;
14
+ /** Semantic meaning and visual treatment. @default "brand" */
15
+ tone?: BannerTone;
16
+ /** Inline content callout or full-width page-edge treatment. @default "inline" */
17
+ presentation?: BannerPresentation;
18
+ /** Icon shown in the 40px semantic tile. Pass `null` to hide the tile. */
19
+ icon?: ReactNode | null;
20
+ /** Optional badge label displayed beside the title. */
21
+ badgeLabel?: ReactNode;
22
+ /** Optional standardized CTA. */
23
+ action?: BannerActionProps;
24
+ /** Override the default accessible role. Error defaults to alert; other tones use status. */
25
+ role?: AriaRole;
26
+ /** Accessible label for the banner region. Defaults to the string title when possible. */
27
+ ariaLabel?: string;
28
+ className?: string;
29
+ style?: CSSProperties;
30
+ }
31
+ /**
32
+ * Persistent contextual guidance with semantic inline and page-level presentations.
33
+ * Position page-level banners in the consuming layout; the component does not use fixed positioning.
34
+ */
35
+ export declare function Banner({ action, ariaLabel, badgeLabel, className, description, icon, presentation, role, style, title, tone, }: BannerProps): import("react/jsx-runtime").JSX.Element;
36
+ //# sourceMappingURL=Banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../../../../src/components/generic/Banner/Banner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIhE,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAG1E,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AACxF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzD,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;IAC5F,4BAA4B;IAC5B,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,oGAAoG;IACpG,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,wDAAwD;IACxD,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,kFAAkF;IAClF,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,0EAA0E;IAC1E,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,uDAAuD;IACvD,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,iCAAiC;IACjC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,6FAA6F;IAC7F,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAoID;;;GAGG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,IAAI,EACJ,YAAuB,EACvB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAc,GACf,EAAE,WAAW,2CA+Eb"}
@@ -0,0 +1,200 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { radii, neutralColors } from "../../../theme/index.js";
3
+ import { colors } from "../../../theme/colors.js";
4
+ import { Badge } from "../../primitives/Badge/Badge.js";
5
+ import { Button } from "../../primitives/Button/Button.js";
6
+ import { Box, Stack } from "../../primitives/layout.js";
7
+ import { Group } from "../../../node_modules/@mantine/core/esm/components/Group/Group.js";
8
+ import { ThemeIcon } from "../../../node_modules/@mantine/core/esm/components/ThemeIcon/ThemeIcon.js";
9
+ import { Text } from "../../../node_modules/@mantine/core/esm/components/Text/Text.js";
10
+ import { fontSizes } from "../../../theme/fontSizes.js";
11
+ const TONE_COLORS = {
12
+ brand: colors.primary,
13
+ neutral: colors.neutral,
14
+ info: colors.info,
15
+ success: colors.success,
16
+ warning: colors.warning,
17
+ error: colors.error
18
+ };
19
+ const DefaultStatusIcon = ({ tone }) => {
20
+ const commonProps = {
21
+ width: 20,
22
+ height: 20,
23
+ viewBox: "0 0 24 24",
24
+ fill: "none",
25
+ stroke: "currentColor",
26
+ strokeWidth: 1.75,
27
+ strokeLinecap: "round",
28
+ strokeLinejoin: "round",
29
+ "aria-hidden": true
30
+ };
31
+ if (tone === "success") {
32
+ return /* @__PURE__ */ jsxs("svg", { ...commonProps, children: [
33
+ /* @__PURE__ */ jsx("title", { children: "Success" }),
34
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
35
+ /* @__PURE__ */ jsx("path", { d: "m8.5 12 2.25 2.25L15.75 9" })
36
+ ] });
37
+ }
38
+ if (tone === "warning") {
39
+ return /* @__PURE__ */ jsxs("svg", { ...commonProps, children: [
40
+ /* @__PURE__ */ jsx("title", { children: "Warning" }),
41
+ /* @__PURE__ */ jsx("path", { d: "M10.3 4.2 2.6 18a2 2 0 0 0 1.75 3h15.3a2 2 0 0 0 1.75-3L13.7 4.2a2 2 0 0 0-3.4 0Z" }),
42
+ /* @__PURE__ */ jsx("path", { d: "M12 9v4" }),
43
+ /* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
44
+ ] });
45
+ }
46
+ if (tone === "error") {
47
+ return /* @__PURE__ */ jsxs("svg", { ...commonProps, children: [
48
+ /* @__PURE__ */ jsx("title", { children: "Error" }),
49
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
50
+ /* @__PURE__ */ jsx("path", { d: "m9 9 6 6" }),
51
+ /* @__PURE__ */ jsx("path", { d: "m15 9-6 6" })
52
+ ] });
53
+ }
54
+ return /* @__PURE__ */ jsxs("svg", { ...commonProps, children: [
55
+ /* @__PURE__ */ jsx("title", { children: "Information" }),
56
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
57
+ /* @__PURE__ */ jsx("path", { d: "M12 11v5" }),
58
+ /* @__PURE__ */ jsx("path", { d: "M12 8h.01" })
59
+ ] });
60
+ };
61
+ const surfaceProps = (tone, presentation) => {
62
+ const color = TONE_COLORS[tone];
63
+ if (presentation === "page-level") {
64
+ return {
65
+ bg: `${color}.1`,
66
+ style: {
67
+ borderRadius: 0
68
+ }
69
+ };
70
+ }
71
+ const borderShade = tone === "brand" ? 1 : tone === "neutral" ? 3 : 2;
72
+ return {
73
+ bg: `${color}.0`,
74
+ bd: `1px solid ${color}.${borderShade}`,
75
+ style: {
76
+ borderRadius: radii.lg
77
+ }
78
+ };
79
+ };
80
+ const titleColor = (tone, presentation) => {
81
+ if (presentation === "page-level") {
82
+ const color = TONE_COLORS[tone];
83
+ return `${color}.${tone === "neutral" ? 9 : 8}`;
84
+ }
85
+ return neutralColors[900];
86
+ };
87
+ const actionVariant = (tone) => {
88
+ if (tone === "brand") return "light";
89
+ if (tone === "neutral") return "outline";
90
+ return "filled";
91
+ };
92
+ const descriptionTextProps = {
93
+ size: "sm",
94
+ c: neutralColors[500],
95
+ style: { lineHeight: 1.4 }
96
+ };
97
+ function BannerDescription({ children }) {
98
+ if (typeof children === "string" || typeof children === "number") {
99
+ return /* @__PURE__ */ jsx(Text, { ...descriptionTextProps, children });
100
+ }
101
+ return /* @__PURE__ */ jsx(
102
+ Box,
103
+ {
104
+ c: neutralColors[500],
105
+ style: {
106
+ fontSize: fontSizes.sm,
107
+ lineHeight: 1.4
108
+ },
109
+ children
110
+ }
111
+ );
112
+ }
113
+ function Banner({
114
+ action,
115
+ ariaLabel,
116
+ badgeLabel,
117
+ className,
118
+ description,
119
+ icon,
120
+ presentation = "inline",
121
+ role,
122
+ style,
123
+ title,
124
+ tone = "brand"
125
+ }) {
126
+ const color = TONE_COLORS[tone];
127
+ const iconNode = icon === void 0 ? /* @__PURE__ */ jsx(DefaultStatusIcon, { tone }) : icon;
128
+ const resolvedRole = role ?? (tone === "error" ? "alert" : "status");
129
+ const resolvedAriaLabel = ariaLabel ?? (typeof title === "string" ? title : void 0);
130
+ const surface = surfaceProps(tone, presentation);
131
+ let actionNode = null;
132
+ if (action !== void 0) {
133
+ const { label, ...buttonProps } = action;
134
+ actionNode = /* @__PURE__ */ jsx(
135
+ Button,
136
+ {
137
+ ...buttonProps,
138
+ color,
139
+ variant: actionVariant(tone),
140
+ style: { flex: "0 0 auto", ...buttonProps.style },
141
+ children: label
142
+ }
143
+ );
144
+ }
145
+ return /* @__PURE__ */ jsx(
146
+ Box,
147
+ {
148
+ "aria-label": resolvedAriaLabel,
149
+ className,
150
+ "data-presentation": presentation,
151
+ "data-tone": tone,
152
+ role: resolvedRole,
153
+ px: "md",
154
+ py: "md",
155
+ bg: surface.bg,
156
+ bd: "bd" in surface ? surface.bd : void 0,
157
+ style: {
158
+ boxSizing: "border-box",
159
+ width: "100%",
160
+ ...surface.style,
161
+ ...style
162
+ },
163
+ children: /* @__PURE__ */ jsxs(Group, { align: "center", gap: "sm", wrap: "wrap", children: [
164
+ iconNode !== null && /* @__PURE__ */ jsx(
165
+ ThemeIcon,
166
+ {
167
+ "aria-hidden": true,
168
+ color,
169
+ radius: "sm",
170
+ size: 40,
171
+ variant: "light",
172
+ style: { flex: "0 0 auto" },
173
+ children: iconNode
174
+ }
175
+ ),
176
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, style: { flex: "1 1 240px", minWidth: 0 }, children: [
177
+ title !== void 0 && /* @__PURE__ */ jsxs(Group, { align: "center", gap: "xs", wrap: "wrap", children: [
178
+ /* @__PURE__ */ jsx(
179
+ Text,
180
+ {
181
+ fw: 600,
182
+ size: "md",
183
+ c: titleColor(tone, presentation),
184
+ style: { lineHeight: 1.35 },
185
+ children: title
186
+ }
187
+ ),
188
+ badgeLabel !== void 0 && /* @__PURE__ */ jsx(Badge, { color, size: "sm", variant: "light", children: badgeLabel })
189
+ ] }),
190
+ description !== void 0 && /* @__PURE__ */ jsx(BannerDescription, { children: description })
191
+ ] }),
192
+ actionNode
193
+ ] })
194
+ }
195
+ );
196
+ }
197
+ export {
198
+ Banner
199
+ };
200
+ //# sourceMappingURL=Banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.js","sources":["../../../../src/components/generic/Banner/Banner.tsx"],"sourcesContent":["import type { AriaRole, CSSProperties, ReactNode } from \"react\";\nimport { fontSizes, neutralColors, radii } from \"../../../theme\";\nimport { colors } from \"../../../theme/colors\";\nimport { Badge } from \"../../primitives/Badge/Badge\";\nimport { Button, type ButtonProps } from \"../../primitives/Button/Button\";\nimport { Box, Group, Stack, Text, ThemeIcon } from \"../../primitives/layout\";\n\nexport type BannerTone = \"brand\" | \"neutral\" | \"info\" | \"success\" | \"warning\" | \"error\";\nexport type BannerPresentation = \"inline\" | \"page-level\";\n\nexport interface BannerActionProps extends Omit<ButtonProps, \"children\" | \"color\" | \"variant\"> {\n /** Visible action label. */\n label: ReactNode;\n}\n\nexport interface BannerProps {\n /** Primary message. Omit when the banner is description-only; set `ariaLabel` for accessibility. */\n title?: ReactNode;\n /** Supporting context. Omit for a title-only banner. */\n description?: ReactNode;\n /** Semantic meaning and visual treatment. @default \"brand\" */\n tone?: BannerTone;\n /** Inline content callout or full-width page-edge treatment. @default \"inline\" */\n presentation?: BannerPresentation;\n /** Icon shown in the 40px semantic tile. Pass `null` to hide the tile. */\n icon?: ReactNode | null;\n /** Optional badge label displayed beside the title. */\n badgeLabel?: ReactNode;\n /** Optional standardized CTA. */\n action?: BannerActionProps;\n /** Override the default accessible role. Error defaults to alert; other tones use status. */\n role?: AriaRole;\n /** Accessible label for the banner region. Defaults to the string title when possible. */\n ariaLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\nconst TONE_COLORS = {\n brand: colors.primary,\n neutral: colors.neutral,\n info: colors.info,\n success: colors.success,\n warning: colors.warning,\n error: colors.error,\n} as const;\n\nconst DefaultStatusIcon = ({ tone }: { tone: BannerTone }) => {\n const commonProps = {\n width: 20,\n height: 20,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 1.75,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n \"aria-hidden\": true,\n };\n\n if (tone === \"success\") {\n return (\n <svg {...commonProps}>\n <title>Success</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m8.5 12 2.25 2.25L15.75 9\" />\n </svg>\n );\n }\n\n if (tone === \"warning\") {\n return (\n <svg {...commonProps}>\n <title>Warning</title>\n <path d=\"M10.3 4.2 2.6 18a2 2 0 0 0 1.75 3h15.3a2 2 0 0 0 1.75-3L13.7 4.2a2 2 0 0 0-3.4 0Z\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n }\n\n if (tone === \"error\") {\n return (\n <svg {...commonProps}>\n <title>Error</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"m9 9 6 6\" />\n <path d=\"m15 9-6 6\" />\n </svg>\n );\n }\n\n return (\n <svg {...commonProps}>\n <title>Information</title>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 11v5\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n};\n\nconst surfaceProps = (tone: BannerTone, presentation: BannerPresentation) => {\n const color = TONE_COLORS[tone];\n\n if (presentation === \"page-level\") {\n return {\n bg: `${color}.1`,\n style: {\n borderRadius: 0,\n } satisfies CSSProperties,\n };\n }\n\n // Chip Banner: tinted surface + semantic border (error border = error.2)\n const borderShade = tone === \"brand\" ? 1 : tone === \"neutral\" ? 3 : 2;\n\n return {\n bg: `${color}.0`,\n bd: `1px solid ${color}.${borderShade}`,\n style: {\n borderRadius: radii.lg,\n } satisfies CSSProperties,\n };\n};\n\n/**\n * Inline Chip banners keep light semantic fills across color schemes, so titles\n * stay dark primary text for WCAG AA. Page-level uses a deeper semantic shade.\n */\nconst titleColor = (tone: BannerTone, presentation: BannerPresentation) => {\n if (presentation === \"page-level\") {\n const color = TONE_COLORS[tone];\n return `${color}.${tone === \"neutral\" ? 9 : 8}`;\n }\n return neutralColors[900];\n};\n\nconst actionVariant = (tone: BannerTone): ButtonProps[\"variant\"] => {\n if (tone === \"brand\") return \"light\";\n if (tone === \"neutral\") return \"outline\";\n return \"filled\";\n};\n\nconst descriptionTextProps = {\n size: \"sm\" as const,\n c: neutralColors[500],\n style: { lineHeight: 1.4 },\n};\n\nfunction BannerDescription({ children }: { children: ReactNode }) {\n if (typeof children === \"string\" || typeof children === \"number\") {\n return <Text {...descriptionTextProps}>{children}</Text>;\n }\n\n return (\n <Box\n c={neutralColors[500]}\n style={{\n fontSize: fontSizes.sm,\n lineHeight: 1.4,\n }}\n >\n {children}\n </Box>\n );\n}\n\n/**\n * Persistent contextual guidance with semantic inline and page-level presentations.\n * Position page-level banners in the consuming layout; the component does not use fixed positioning.\n */\nexport function Banner({\n action,\n ariaLabel,\n badgeLabel,\n className,\n description,\n icon,\n presentation = \"inline\",\n role,\n style,\n title,\n tone = \"brand\",\n}: BannerProps) {\n const color = TONE_COLORS[tone];\n const iconNode = icon === undefined ? <DefaultStatusIcon tone={tone} /> : icon;\n const resolvedRole = role ?? (tone === \"error\" ? \"alert\" : \"status\");\n const resolvedAriaLabel = ariaLabel ?? (typeof title === \"string\" ? title : undefined);\n const surface = surfaceProps(tone, presentation);\n let actionNode: ReactNode = null;\n\n if (action !== undefined) {\n const { label, ...buttonProps } = action;\n actionNode = (\n <Button\n {...buttonProps}\n color={color}\n variant={actionVariant(tone)}\n style={{ flex: \"0 0 auto\", ...buttonProps.style }}\n >\n {label}\n </Button>\n );\n }\n\n return (\n <Box\n aria-label={resolvedAriaLabel}\n className={className}\n data-presentation={presentation}\n data-tone={tone}\n role={resolvedRole}\n px=\"md\"\n py=\"md\"\n bg={surface.bg}\n bd={\"bd\" in surface ? surface.bd : undefined}\n style={{\n boxSizing: \"border-box\",\n width: \"100%\",\n ...surface.style,\n ...style,\n }}\n >\n <Group align=\"center\" gap=\"sm\" wrap=\"wrap\">\n {iconNode !== null && (\n <ThemeIcon\n aria-hidden\n color={color}\n radius=\"sm\"\n size={40}\n variant=\"light\"\n style={{ flex: \"0 0 auto\" }}\n >\n {iconNode}\n </ThemeIcon>\n )}\n\n <Stack gap={4} style={{ flex: \"1 1 240px\", minWidth: 0 }}>\n {title !== undefined && (\n <Group align=\"center\" gap=\"xs\" wrap=\"wrap\">\n <Text\n fw={600}\n size=\"md\"\n c={titleColor(tone, presentation)}\n style={{ lineHeight: 1.35 }}\n >\n {title}\n </Text>\n {badgeLabel !== undefined && (\n <Badge color={color} size=\"sm\" variant=\"light\">\n {badgeLabel}\n </Badge>\n )}\n </Group>\n )}\n {description !== undefined && <BannerDescription>{description}</BannerDescription>}\n </Stack>\n\n {actionNode}\n </Group>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}