@fairmint/ui 0.1.0 → 0.1.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 (37) hide show
  1. package/README.md +48 -61
  2. package/dist/components/AppHeader/AppHeader.d.ts +15 -0
  3. package/dist/components/AppHeader/AppHeader.d.ts.map +1 -0
  4. package/dist/components/ErrorFallback/ErrorFallback.d.ts +14 -0
  5. package/dist/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
  6. package/dist/components/FairmintLogo/FairmintLogo.d.ts +14 -0
  7. package/dist/components/FairmintLogo/FairmintLogo.d.ts.map +1 -0
  8. package/dist/components/FairmintProvider/FairmintProvider.d.ts +9 -0
  9. package/dist/components/FairmintProvider/FairmintProvider.d.ts.map +1 -0
  10. package/dist/components/LoadingSpinner/LoadingSpinner.d.ts +10 -0
  11. package/dist/components/LoadingSpinner/LoadingSpinner.d.ts.map +1 -0
  12. package/dist/components/PageHeader/PageHeader.d.ts +11 -0
  13. package/dist/components/PageHeader/PageHeader.d.ts.map +1 -0
  14. package/dist/components/SideNav/SideNav.d.ts +21 -0
  15. package/dist/components/SideNav/SideNav.d.ts.map +1 -0
  16. package/dist/components/UserMenu/UserMenu.d.ts +31 -0
  17. package/dist/components/UserMenu/UserMenu.d.ts.map +1 -0
  18. package/dist/{fairmint-ui.cjs.js → fairmint-ui.cjs} +76 -62
  19. package/dist/fairmint-ui.cjs.map +1 -0
  20. package/dist/{fairmint-ui.es.js → fairmint-ui.js} +77 -63
  21. package/dist/fairmint-ui.js.map +1 -0
  22. package/dist/index.d.ts +18 -301
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/styles.css +6 -2
  25. package/dist/test/setup.d.ts +1 -0
  26. package/dist/test/setup.d.ts.map +1 -0
  27. package/dist/theme/index.d.ts +170 -0
  28. package/dist/theme/index.d.ts.map +1 -0
  29. package/dist/vite.cjs +30 -0
  30. package/dist/vite.cjs.map +1 -0
  31. package/dist/vite.d.ts +18 -0
  32. package/dist/vite.d.ts.map +1 -0
  33. package/dist/vite.js +30 -0
  34. package/dist/vite.js.map +1 -0
  35. package/package.json +29 -21
  36. package/dist/fairmint-ui.cjs.js.map +0 -1
  37. package/dist/fairmint-ui.es.js.map +0 -1
package/README.md CHANGED
@@ -1,101 +1,88 @@
1
1
  # @fairmint/ui
2
2
 
3
- Fairmint's shared design system and UI component library. Built with Mantine v8, React 19, TypeScript, and Storybook.
3
+ Fairmint's shared design system and UI component library.
4
4
 
5
- ## Install
5
+ ## Quick Start
6
6
 
7
- ```bash
8
- yarn add @fairmint/ui
9
- ```
10
-
11
- Peer dependencies (must be installed in your app):
7
+ ### 1. Install
12
8
 
13
9
  ```bash
14
- yarn add @mantine/core @mantine/hooks react react-dom
10
+ bun add @fairmint/ui
15
11
  ```
16
12
 
17
- ## Setup
18
-
19
- ### CSS
13
+ Mantine is included as a dependency — no extra packages to install.
20
14
 
21
- Import in your app entry point:
15
+ ### 2. Import styles
22
16
 
23
17
  ```typescript
24
- import '@mantine/core/styles.css';
25
- import '@fairmint/ui/styles.css'; // LoadingSpinner keyframe animation
18
+ import '@fairmint/ui/styles.css';
26
19
  ```
27
20
 
28
- If your app already imports `@mantine/core/styles.css`, you do not need to import it again. `@fairmint/ui/styles.css` only contains the library's component-specific styles.
21
+ This single import includes both Mantine core styles and Fairmint component styles.
29
22
 
30
- ### Fonts
23
+ ### 3. Wrap with provider
31
24
 
32
- Add to your `index.html`:
25
+ ```tsx
26
+ import { FairmintProvider } from '@fairmint/ui';
33
27
 
34
- ```html
35
- <link rel="preconnect" href="https://fonts.googleapis.com" />
36
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
37
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@600;700&display=swap" rel="stylesheet" />
28
+ function App() {
29
+ return (
30
+ <FairmintProvider>
31
+ {/* Your app */}
32
+ </FairmintProvider>
33
+ );
34
+ }
38
35
  ```
39
36
 
40
- Or use `@fontsource`:
37
+ ### 4. Use components
41
38
 
42
- ```bash
43
- yarn add @fontsource/inter @fontsource/plus-jakarta-sans
44
- ```
45
-
46
- ```typescript
47
- import '@fontsource/inter/400.css';
48
- import '@fontsource/inter/500.css';
49
- import '@fontsource/inter/600.css';
50
- import '@fontsource/inter/700.css';
51
- import '@fontsource/plus-jakarta-sans/600.css';
52
- import '@fontsource/plus-jakarta-sans/700.css';
39
+ ```tsx
40
+ import { PageHeader, FairmintLogo, LoadingSpinner } from '@fairmint/ui';
53
41
  ```
54
42
 
55
- ## Usage
43
+ ## Local Development (live editing)
56
44
 
57
- ### Theme
45
+ When working on the UI library alongside a consumer app, add the Vite plugin for instant HMR without building:
58
46
 
59
- ```tsx
60
- import { MantineProvider } from '@mantine/core';
61
- import { theme } from '@fairmint/ui';
47
+ ```typescript
48
+ // your-app/vite.config.ts
49
+ import { fairmintUiLocal } from '@fairmint/ui/vite';
62
50
 
63
- function App() {
64
- return <MantineProvider theme={theme}>{/* Your app */}</MantineProvider>;
65
- }
51
+ export default defineConfig({
52
+ plugins: [fairmintUiLocal(), react()],
53
+ });
66
54
  ```
67
55
 
68
- To extend in your app:
69
-
70
- ```tsx
71
- import { mergeThemeOverrides } from '@mantine/core';
72
- import { theme as fairmintTheme } from '@fairmint/ui';
56
+ This auto-detects the sibling `design/ui/` repo and resolves imports to local source. Opt out with `LOCAL_UI=0 bun run dev`. In CI the design repo isn't present, so it falls back to the npm package automatically.
73
57
 
74
- const appTheme = mergeThemeOverrides(fairmintTheme, { /* overrides */ });
75
- ```
58
+ ## Fonts
76
59
 
77
- ### Brand Colors
60
+ Add to your `index.html`:
78
61
 
79
- ```typescript
80
- import { brandColors, neutralColors, semanticColors } from '@fairmint/ui';
62
+ ```html
63
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
64
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
65
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@600;700&display=swap" rel="stylesheet" />
81
66
  ```
82
67
 
83
- ### Components
68
+ ## Exports
84
69
 
85
- ```tsx
86
- import { FairmintLogo, LoadingSpinner, PageHeader, ErrorFallback } from '@fairmint/ui';
87
- import { AppHeader, SideNav, UserMenu } from '@fairmint/ui';
88
- ```
70
+ | Import | Contents |
71
+ |--------|----------|
72
+ | `@fairmint/ui` | FairmintProvider, theme, components, color constants |
73
+ | `@fairmint/ui/styles.css` | Mantine core CSS + library component CSS |
74
+ | `@fairmint/ui/vite` | `fairmintUiLocal()` Vite plugin for local dev |
89
75
 
90
76
  ## Development
91
77
 
92
78
  ```bash
93
- yarn dev # Start Storybook (port 6006)
94
- yarn build # Build library
95
- yarn test # Run tests
96
- yarn lint # Lint
79
+ cd design/ui
80
+ bun run dev # Storybook on port 6006
81
+ bun run build # Build library
82
+ bun run test # Run tests
83
+ bun run lint # Lint (Biome)
97
84
  ```
98
85
 
99
86
  ## Publishing
100
87
 
101
- Handled automatically by GitHub Actions on push to `main`. Bump version in `package.json` before merging.
88
+ Automatic on push to `main` when `ui/` files change. Patch version auto-increments if the current version is already published.
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+ export interface AppHeaderProps {
3
+ /** Logo element (typically FairmintLogo). */
4
+ logo: ReactNode;
5
+ /** Right-aligned content (user menu, actions). */
6
+ rightSection?: ReactNode;
7
+ /** Whether mobile nav is open. Controls burger state. */
8
+ mobileNavOpened?: boolean;
9
+ /** Toggle mobile nav callback. */
10
+ onMobileNavToggle?: () => void;
11
+ /** Header height in pixels. @default 60 */
12
+ height?: number;
13
+ }
14
+ export declare function AppHeader({ logo, rightSection, mobileNavOpened, onMobileNavToggle, height, }: AppHeaderProps): import("react/jsx-runtime").JSX.Element;
15
+ //# sourceMappingURL=AppHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppHeader.d.ts","sourceRoot":"","sources":["../../../src/components/AppHeader/AppHeader.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,IAAI,EAAE,SAAS,CAAC;IAChB,kDAAkD;IAClD,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,yDAAyD;IACzD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,YAAY,EACZ,eAAuB,EACvB,iBAAiB,EACjB,MAAW,GACZ,EAAE,cAAc,2CAkBhB"}
@@ -0,0 +1,14 @@
1
+ export interface ErrorFallbackProps {
2
+ /** Title text. @default "Something went wrong" */
3
+ title?: string;
4
+ /** Description text. @default "We've been notified and are working on a fix." */
5
+ description?: string;
6
+ /** Callback when the user clicks the action button. Defaults to window.location.reload(). */
7
+ onAction?: () => void;
8
+ /** Action button label. @default "Reload Page" */
9
+ actionLabel?: string;
10
+ /** Optional error object for dev-mode display or logging. Compatible with Sentry ErrorBoundary render props. */
11
+ error?: unknown;
12
+ }
13
+ export declare function ErrorFallback({ title, description, onAction, actionLabel, error, }: ErrorFallbackProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=ErrorFallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorFallback.d.ts","sourceRoot":"","sources":["../../../src/components/ErrorFallback/ErrorFallback.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gHAAgH;IAChH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAA8B,EAC9B,WAA6D,EAC7D,QAAQ,EACR,WAA2B,EAC3B,KAAK,GACN,EAAE,kBAAkB,2CAgBpB"}
@@ -0,0 +1,14 @@
1
+ export interface FairmintLogoProps {
2
+ /** Image source URL. Defaults to the CDN-hosted black wordmark. */
3
+ src?: string;
4
+ /** Width in pixels. @default 140 */
5
+ width?: number;
6
+ /** Height in pixels. @default 30 */
7
+ height?: number;
8
+ /** Additional CSS class. */
9
+ className?: string;
10
+ /** Alt text. @default "Fairmint" */
11
+ alt?: string;
12
+ }
13
+ export declare function FairmintLogo({ src, width, height, className, alt, }: FairmintLogoProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=FairmintLogo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FairmintLogo.d.ts","sourceRoot":"","sources":["../../../src/components/FairmintLogo/FairmintLogo.tsx"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,EAC3B,GAAoG,EACpG,KAAW,EACX,MAAW,EACX,SAAS,EACT,GAAgB,GACjB,EAAE,iBAAiB,2CAWnB"}
@@ -0,0 +1,9 @@
1
+ import { MantineColorScheme } from '@mantine/core';
2
+ import { ReactNode } from 'react';
3
+ export interface FairmintProviderProps {
4
+ children: ReactNode;
5
+ /** Color scheme. @default "light" */
6
+ colorScheme?: MantineColorScheme;
7
+ }
8
+ export declare function FairmintProvider({ children, colorScheme }: FairmintProviderProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=FairmintProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FairmintProvider.d.ts","sourceRoot":"","sources":["../../../src/components/FairmintProvider/FairmintProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,SAAS,CAAC;IACpB,qCAAqC;IACrC,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,WAAqB,EAAE,EAAE,qBAAqB,2CAU1F"}
@@ -0,0 +1,10 @@
1
+ export interface LoadingSpinnerProps {
2
+ /** Icon size in pixels. @default 32 */
3
+ size?: number;
4
+ }
5
+ /**
6
+ * Animated certificate icon that fills from bottom to top.
7
+ * Requires the consumer to import `@fairmint/ui/styles.css` for the keyframe animation.
8
+ */
9
+ export declare function LoadingSpinner({ size }: LoadingSpinnerProps): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=LoadingSpinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadingSpinner.d.ts","sourceRoot":"","sources":["../../../src/components/LoadingSpinner/LoadingSpinner.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAS,EAAE,EAAE,mBAAmB,2CA2ChE"}
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+ export interface PageHeaderProps {
3
+ /** Page title text. */
4
+ title: string;
5
+ /** Optional subtitle text. */
6
+ subtitle?: string;
7
+ /** Optional right-aligned action element (button, date picker, etc.). */
8
+ action?: ReactNode;
9
+ }
10
+ export declare function PageHeader({ title, subtitle, action }: PageHeaderProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=PageHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageHeader.d.ts","sourceRoot":"","sources":["../../../src/components/PageHeader/PageHeader.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,eAAe,2CActE"}
@@ -0,0 +1,21 @@
1
+ import { ReactNode } from 'react';
2
+ export interface SideNavItem {
3
+ /** Unique identifier for this nav item (e.g., route path or slug). */
4
+ id: string;
5
+ /** Display label. */
6
+ label: string;
7
+ /** Icon element. */
8
+ icon?: ReactNode;
9
+ /** Whether this item is currently active. */
10
+ active?: boolean;
11
+ }
12
+ export interface SideNavProps {
13
+ /** Navigation items to render. */
14
+ items: SideNavItem[];
15
+ /** Callback when a nav item is clicked. Receives the item's `id`. */
16
+ onItemClick: (id: string) => void;
17
+ /** Active color. @default "indigo" */
18
+ color?: string;
19
+ }
20
+ export declare function SideNav({ items, onItemClick, color }: SideNavProps): import("react/jsx-runtime").JSX.Element;
21
+ //# sourceMappingURL=SideNav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../../src/components/SideNav/SideNav.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,qEAAqE;IACrE,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,KAAgB,EAAE,EAAE,YAAY,2CA0B7E"}
@@ -0,0 +1,31 @@
1
+ import { ReactNode } from 'react';
2
+ export interface UserMenuItem {
3
+ /** Unique identifier for this menu item. */
4
+ id: string;
5
+ /** Display label. */
6
+ label: string;
7
+ /** Icon element. */
8
+ icon?: ReactNode;
9
+ /** Item color (e.g., "red" for destructive actions). */
10
+ color?: string;
11
+ /** Optional section label above this item. Set on the first item in a group. */
12
+ sectionLabel?: string;
13
+ /** Show a divider before this item. */
14
+ dividerBefore?: boolean;
15
+ }
16
+ export interface UserMenuProps {
17
+ /** User display name or email. */
18
+ displayName: string;
19
+ /** Single-character avatar initial. Derived from displayName[0] if not provided. */
20
+ avatarInitial?: string;
21
+ /** Avatar color. @default "indigo" */
22
+ avatarColor?: string;
23
+ /** Optional indicator element after the display name (e.g., chevron icon from your app's icon library). */
24
+ indicator?: ReactNode;
25
+ /** Menu items. */
26
+ items: UserMenuItem[];
27
+ /** Callback when a menu item is clicked. Receives the item's `id`. */
28
+ onItemClick: (id: string) => void;
29
+ }
30
+ export declare function UserMenu({ displayName, avatarInitial, avatarColor, indicator, items, onItemClick, }: UserMenuProps): import("react/jsx-runtime").JSX.Element;
31
+ //# sourceMappingURL=UserMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserMenu.d.ts","sourceRoot":"","sources":["../../../src/components/UserMenu/UserMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2GAA2G;IAC3G,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,kBAAkB;IAClB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,sEAAsE;IACtE,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,QAAQ,CAAC,EACvB,WAAW,EACX,aAAa,EACb,WAAsB,EACtB,SAAS,EACT,KAAK,EACL,WAAW,GACZ,EAAE,aAAa,2CAsCf"}
@@ -1,7 +1,67 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const core = require("@mantine/core");
4
3
  const jsxRuntime = require("react/jsx-runtime");
4
+ const core = require("@mantine/core");
5
+ function AppHeader({
6
+ logo,
7
+ rightSection,
8
+ mobileNavOpened = false,
9
+ onMobileNavToggle,
10
+ height = 60
11
+ }) {
12
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Group, { h: height, px: "md", justify: "space-between", children: [
13
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Group, { children: [
14
+ onMobileNavToggle && /* @__PURE__ */ jsxRuntime.jsx(
15
+ core.Burger,
16
+ {
17
+ opened: mobileNavOpened,
18
+ onClick: onMobileNavToggle,
19
+ hiddenFrom: "sm",
20
+ size: "sm",
21
+ "aria-label": "Toggle navigation"
22
+ }
23
+ ),
24
+ logo
25
+ ] }),
26
+ rightSection
27
+ ] });
28
+ }
29
+ function ErrorFallback({
30
+ title = "Something went wrong",
31
+ description = "We've been notified and are working on a fix.",
32
+ onAction,
33
+ actionLabel = "Reload Page",
34
+ error: error2
35
+ }) {
36
+ if (error2 !== void 0) {
37
+ console.error("[ErrorFallback]", error2);
38
+ }
39
+ const handleAction = onAction ?? (() => window.location.reload());
40
+ return /* @__PURE__ */ jsxRuntime.jsx(core.Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxRuntime.jsxs(core.Stack, { align: "center", gap: "md", children: [
41
+ /* @__PURE__ */ jsxRuntime.jsx(core.Title, { order: 2, children: title }),
42
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { c: "dimmed", children: description }),
43
+ /* @__PURE__ */ jsxRuntime.jsx(core.Button, { onClick: handleAction, children: actionLabel })
44
+ ] }) });
45
+ }
46
+ function FairmintLogo({
47
+ src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
48
+ width = 140,
49
+ height = 30,
50
+ className,
51
+ alt = "Fairmint"
52
+ }) {
53
+ return /* @__PURE__ */ jsxRuntime.jsx(
54
+ "img",
55
+ {
56
+ src,
57
+ alt,
58
+ width,
59
+ height,
60
+ className,
61
+ style: { objectFit: "contain" }
62
+ }
63
+ );
64
+ }
5
65
  const indigo = [
6
66
  "#EEF2FF",
7
67
  "#E0E7FF",
@@ -183,24 +243,8 @@ const semanticColors = {
183
243
  error: "#F04438",
184
244
  info: "#06AED4"
185
245
  };
186
- function FairmintLogo({
187
- src = "https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public",
188
- width = 140,
189
- height = 30,
190
- className,
191
- alt = "Fairmint"
192
- }) {
193
- return /* @__PURE__ */ jsxRuntime.jsx(
194
- "img",
195
- {
196
- src,
197
- alt,
198
- width,
199
- height,
200
- className,
201
- style: { objectFit: "contain" }
202
- }
203
- );
246
+ function FairmintProvider({ children, colorScheme = "light" }) {
247
+ return /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme, defaultColorScheme: colorScheme, children });
204
248
  }
205
249
  function LoadingSpinner({ size = 32 }) {
206
250
  const iconProps = {
@@ -222,13 +266,23 @@ function LoadingSpinner({ size = 32 }) {
222
266
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 15h2" })
223
267
  ] });
224
268
  return /* @__PURE__ */ jsxRuntime.jsxs(core.Box, { pos: "relative", style: { width: size, height: size }, role: "status", "aria-label": "Loading", children: [
225
- /* @__PURE__ */ jsxRuntime.jsx("svg", { ...iconProps, stroke: "var(--mantine-color-gray-3)", style: { position: "absolute", inset: 0 }, children: paths }),
269
+ /* @__PURE__ */ jsxRuntime.jsx(
270
+ "svg",
271
+ {
272
+ ...iconProps,
273
+ stroke: "var(--mantine-color-gray-3)",
274
+ style: { position: "absolute", inset: 0 },
275
+ "aria-hidden": "true",
276
+ children: paths
277
+ }
278
+ ),
226
279
  /* @__PURE__ */ jsxRuntime.jsx(
227
280
  "svg",
228
281
  {
229
282
  ...iconProps,
230
283
  stroke: "var(--mantine-color-indigo-5)",
231
284
  style: { position: "absolute", inset: 0, animation: "fillUp 1.4s ease-in-out infinite" },
285
+ "aria-hidden": "true",
232
286
  children: paths
233
287
  }
234
288
  )
@@ -243,47 +297,6 @@ function PageHeader({ title, subtitle, action }) {
243
297
  action
244
298
  ] });
245
299
  }
246
- function ErrorFallback({
247
- title = "Something went wrong",
248
- description = "We've been notified and are working on a fix.",
249
- onAction,
250
- actionLabel = "Reload Page",
251
- error: error2
252
- }) {
253
- if (error2 !== void 0) {
254
- console.error("[ErrorFallback]", error2);
255
- }
256
- const handleAction = onAction ?? (() => window.location.reload());
257
- return /* @__PURE__ */ jsxRuntime.jsx(core.Container, { size: "sm", py: "xl", children: /* @__PURE__ */ jsxRuntime.jsxs(core.Stack, { align: "center", gap: "md", children: [
258
- /* @__PURE__ */ jsxRuntime.jsx(core.Title, { order: 2, children: title }),
259
- /* @__PURE__ */ jsxRuntime.jsx(core.Text, { c: "dimmed", children: description }),
260
- /* @__PURE__ */ jsxRuntime.jsx(core.Button, { onClick: handleAction, children: actionLabel })
261
- ] }) });
262
- }
263
- function AppHeader({
264
- logo,
265
- rightSection,
266
- mobileNavOpened = false,
267
- onMobileNavToggle,
268
- height = 60
269
- }) {
270
- return /* @__PURE__ */ jsxRuntime.jsxs(core.Group, { h: height, px: "md", justify: "space-between", children: [
271
- /* @__PURE__ */ jsxRuntime.jsxs(core.Group, { children: [
272
- onMobileNavToggle && /* @__PURE__ */ jsxRuntime.jsx(
273
- core.Burger,
274
- {
275
- opened: mobileNavOpened,
276
- onClick: onMobileNavToggle,
277
- hiddenFrom: "sm",
278
- size: "sm",
279
- "aria-label": "Toggle navigation"
280
- }
281
- ),
282
- logo
283
- ] }),
284
- rightSection
285
- ] });
286
- }
287
300
  function SideNav({ items, onItemClick, color = "indigo" }) {
288
301
  return /* @__PURE__ */ jsxRuntime.jsx(core.Stack, { component: "nav", gap: 4, p: "md", "aria-label": "Main navigation", children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
289
302
  core.NavLink,
@@ -341,6 +354,7 @@ function UserMenu({
341
354
  exports.AppHeader = AppHeader;
342
355
  exports.ErrorFallback = ErrorFallback;
343
356
  exports.FairmintLogo = FairmintLogo;
357
+ exports.FairmintProvider = FairmintProvider;
344
358
  exports.LoadingSpinner = LoadingSpinner;
345
359
  exports.PageHeader = PageHeader;
346
360
  exports.SideNav = SideNav;
@@ -349,4 +363,4 @@ exports.brandColors = brandColors;
349
363
  exports.neutralColors = neutralColors;
350
364
  exports.semanticColors = semanticColors;
351
365
  exports.theme = theme;
352
- //# sourceMappingURL=fairmint-ui.cjs.js.map
366
+ //# sourceMappingURL=fairmint-ui.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fairmint-ui.cjs","sources":["../src/components/AppHeader/AppHeader.tsx","../src/components/ErrorFallback/ErrorFallback.tsx","../src/components/FairmintLogo/FairmintLogo.tsx","../src/theme/index.ts","../src/components/FairmintProvider/FairmintProvider.tsx","../src/components/LoadingSpinner/LoadingSpinner.tsx","../src/components/PageHeader/PageHeader.tsx","../src/components/SideNav/SideNav.tsx","../src/components/UserMenu/UserMenu.tsx"],"sourcesContent":["import { Burger, Group } from \"@mantine/core\";\nimport type { ReactNode } from \"react\";\n\nexport interface AppHeaderProps {\n /** Logo element (typically FairmintLogo). */\n logo: ReactNode;\n /** Right-aligned content (user menu, actions). */\n rightSection?: ReactNode;\n /** Whether mobile nav is open. Controls burger state. */\n mobileNavOpened?: boolean;\n /** Toggle mobile nav callback. */\n onMobileNavToggle?: () => void;\n /** Header height in pixels. @default 60 */\n height?: number;\n}\n\nexport function AppHeader({\n logo,\n rightSection,\n mobileNavOpened = false,\n onMobileNavToggle,\n height = 60,\n}: AppHeaderProps) {\n return (\n <Group h={height} px=\"md\" justify=\"space-between\">\n <Group>\n {onMobileNavToggle && (\n <Burger\n opened={mobileNavOpened}\n onClick={onMobileNavToggle}\n hiddenFrom=\"sm\"\n size=\"sm\"\n aria-label=\"Toggle navigation\"\n />\n )}\n {logo}\n </Group>\n {rightSection}\n </Group>\n );\n}\n","import { Button, Container, Stack, Text, Title } from \"@mantine/core\";\n\nexport interface ErrorFallbackProps {\n /** Title text. @default \"Something went wrong\" */\n title?: string;\n /** Description text. @default \"We've been notified and are working on a fix.\" */\n description?: string;\n /** Callback when the user clicks the action button. Defaults to window.location.reload(). */\n onAction?: () => void;\n /** Action button label. @default \"Reload Page\" */\n actionLabel?: string;\n /** Optional error object for dev-mode display or logging. Compatible with Sentry ErrorBoundary render props. */\n error?: unknown;\n}\n\nexport function ErrorFallback({\n title = \"Something went wrong\",\n description = \"We've been notified and are working on a fix.\",\n onAction,\n actionLabel = \"Reload Page\",\n error,\n}: ErrorFallbackProps) {\n if (error !== undefined) {\n console.error(\"[ErrorFallback]\", error);\n }\n\n const handleAction = onAction ?? (() => window.location.reload());\n\n return (\n <Container size=\"sm\" py=\"xl\">\n <Stack align=\"center\" gap=\"md\">\n <Title order={2}>{title}</Title>\n <Text c=\"dimmed\">{description}</Text>\n <Button onClick={handleAction}>{actionLabel}</Button>\n </Stack>\n </Container>\n );\n}\n","export interface FairmintLogoProps {\n /** Image source URL. Defaults to the CDN-hosted black wordmark. */\n src?: string;\n /** Width in pixels. @default 140 */\n width?: number;\n /** Height in pixels. @default 30 */\n height?: number;\n /** Additional CSS class. */\n className?: string;\n /** Alt text. @default \"Fairmint\" */\n alt?: string;\n}\n\nexport function FairmintLogo({\n src = \"https://imagedelivery.net/Lm6ChJXR4cIKKycsNMvGjA/0367be38-c9d8-4206-aaae-eba5ff830600/public\",\n width = 140,\n height = 30,\n className,\n alt = \"Fairmint\",\n}: FairmintLogoProps) {\n return (\n <img\n src={src}\n alt={alt}\n width={width}\n height={height}\n className={className}\n style={{ objectFit: \"contain\" }}\n />\n );\n}\n","import { createTheme, type MantineColorsTuple } from \"@mantine/core\";\n\n/**\n * Indigo palette — primary UI color.\n * Used for buttons, links, active navigation, focus rings.\n * Shade [5] (#6366F1) is the default primary.\n */\nconst indigo: MantineColorsTuple = [\n \"#EEF2FF\",\n \"#E0E7FF\",\n \"#C7D2FE\",\n \"#A5B4FC\",\n \"#818CF8\",\n \"#6366F1\",\n \"#4F46E5\",\n \"#4338CA\",\n \"#3730A3\",\n \"#312E81\",\n];\n\n/**\n * Neutral scale — replaces Mantine's default gray.\n * Used for text, borders, backgrounds, disabled states.\n */\nconst neutral: MantineColorsTuple = [\n \"#F8F9FA\",\n \"#F3F4F6\",\n \"#E5E7EB\",\n \"#D2D6DB\",\n \"#9DA4AE\",\n \"#6C737F\",\n \"#4D5761\",\n \"#2F3746\",\n \"#1C2536\",\n \"#111927\",\n];\n\n/**\n * Fairmint brand blue — accent color for gradients and brand elements.\n * Shade [5] (#0A4EFB) is the primary brand blue.\n *\n * NOTE: design/README.md lists #2D00F7 as Fairmint Blue.\n * This library uses #0A4EFB (production value from investorv2).\n */\nconst fairmintBlue: MantineColorsTuple = [\n \"#e6f0ff\",\n \"#cce0ff\",\n \"#99c2ff\",\n \"#66a3ff\",\n \"#3385ff\",\n \"#0A4EFB\",\n \"#083ec9\",\n \"#062e97\",\n \"#041f64\",\n \"#020f32\",\n];\n\n/**\n * Fairmint brand purple — accent color for gradients and brand elements.\n * Shade [5] (#9E03FF) is the primary brand purple.\n *\n * NOTE: design/README.md lists #6739FD as Fairmint Purple.\n * This library uses #9E03FF (production value from investorv2).\n */\nconst fairmintPurple: MantineColorsTuple = [\n \"#f5e6ff\",\n \"#e6ccff\",\n \"#cc99ff\",\n \"#b366ff\",\n \"#9933ff\",\n \"#9E03FF\",\n \"#7e02cc\",\n \"#5f0299\",\n \"#3f0166\",\n \"#200133\",\n];\n\nconst success: MantineColorsTuple = [\n \"#F0FDF9\",\n \"#D1FAE5\",\n \"#A7F3D0\",\n \"#6EE7B7\",\n \"#34D399\",\n \"#10B981\",\n \"#059669\",\n \"#047857\",\n \"#065F46\",\n \"#134E48\",\n];\n\nconst warning: MantineColorsTuple = [\n \"#FFFAEB\",\n \"#FEF0C7\",\n \"#FEDF89\",\n \"#FEC84B\",\n \"#FDB022\",\n \"#F79009\",\n \"#DC6803\",\n \"#B54708\",\n \"#93370D\",\n \"#7A2E0E\",\n];\n\nconst error: MantineColorsTuple = [\n \"#FEF3F2\",\n \"#FEE4E2\",\n \"#FECDCA\",\n \"#FDA29B\",\n \"#F97066\",\n \"#F04438\",\n \"#D92D20\",\n \"#B42318\",\n \"#912018\",\n \"#7A271A\",\n];\n\nconst info: MantineColorsTuple = [\n \"#ECFDFF\",\n \"#CFF9FE\",\n \"#A5F0FC\",\n \"#67E3F9\",\n \"#22CCEE\",\n \"#06AED4\",\n \"#088AB2\",\n \"#0E7090\",\n \"#155B75\",\n \"#164C63\",\n];\n\nexport const theme = createTheme({\n primaryColor: \"indigo\",\n colors: { indigo, gray: neutral, fairmintBlue, fairmintPurple, success, warning, error, info },\n\n fontFamily:\n '\"Inter\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\"',\n headings: {\n fontFamily: '\"Plus Jakarta Sans\", sans-serif',\n fontWeight: \"700\",\n },\n\n radius: {\n xs: \"0.25rem\",\n sm: \"0.375rem\",\n md: \"0.5rem\",\n lg: \"0.75rem\",\n xl: \"1rem\",\n },\n defaultRadius: \"md\",\n\n breakpoints: {\n xs: \"30em\",\n sm: \"48em\",\n md: \"64em\",\n lg: \"74em\",\n xl: \"90em\",\n },\n\n components: {\n Button: {\n defaultProps: { size: \"md\" },\n styles: {\n root: {\n fontWeight: 600,\n borderRadius: \"0.75rem\",\n textTransform: \"none\" as const,\n },\n },\n },\n TextInput: {\n defaultProps: { size: \"md\" },\n },\n Card: {\n defaultProps: {\n padding: \"lg\",\n radius: \"xl\",\n withBorder: true,\n },\n },\n Paper: {\n styles: {\n root: { backgroundImage: \"none\" },\n },\n },\n Table: {\n styles: {\n thead: {\n fontSize: \"0.75rem\",\n fontWeight: 600,\n letterSpacing: \"0.5px\",\n textTransform: \"uppercase\" as const,\n },\n },\n },\n },\n});\n\n/** Brand colors for gradients and custom styling. */\nexport const brandColors = {\n blue: \"#0A4EFB\",\n purple: \"#9E03FF\",\n indigo: \"#6366F1\",\n gradient: \"linear-gradient(90deg, #0A4EFB 0%, #9E03FF 100%)\",\n} as const;\n\n/** Neutral scale for direct access outside Mantine's theme system. Keys are numeric literals. */\nexport const neutralColors = {\n 50: \"#F8F9FA\",\n 100: \"#F3F4F6\",\n 200: \"#E5E7EB\",\n 300: \"#D2D6DB\",\n 400: \"#9DA4AE\",\n 500: \"#6C737F\",\n 600: \"#4D5761\",\n 700: \"#2F3746\",\n 800: \"#1C2536\",\n 900: \"#111927\",\n} as const;\n\n/** Semantic colors for status-based styling. */\nexport const semanticColors = {\n success: \"#10B981\",\n warning: \"#F79009\",\n error: \"#F04438\",\n info: \"#06AED4\",\n} as const;\n","import type { MantineColorScheme } from \"@mantine/core\";\nimport { MantineProvider } from \"@mantine/core\";\nimport type { ReactNode } from \"react\";\nimport { theme } from \"../../theme\";\n\nexport interface FairmintProviderProps {\n children: ReactNode;\n /** Color scheme. @default \"light\" */\n colorScheme?: MantineColorScheme;\n}\n\nexport function FairmintProvider({ children, colorScheme = \"light\" }: FairmintProviderProps) {\n if (import.meta.env?.DEV) {\n validateSetup();\n }\n\n return (\n <MantineProvider theme={theme} defaultColorScheme={colorScheme}>\n {children}\n </MantineProvider>\n );\n}\n\nfunction validateSetup() {\n if (typeof window === \"undefined\") return;\n\n requestIdleCallback(() => {\n const root = document.documentElement;\n const mantineCss = getComputedStyle(root).getPropertyValue(\"--mantine-color-scheme\");\n if (!mantineCss) {\n console.warn(\n '[@fairmint/ui] Mantine CSS not detected. Make sure you import \"@fairmint/ui/styles.css\" in your entry file.',\n );\n }\n });\n}\n","import { Box } from \"@mantine/core\";\n\nexport interface LoadingSpinnerProps {\n /** Icon size in pixels. @default 32 */\n size?: number;\n}\n\n/**\n * Animated certificate icon that fills from bottom to top.\n * Requires the consumer to import `@fairmint/ui/styles.css` for the keyframe animation.\n */\nexport function LoadingSpinner({ size = 32 }: LoadingSpinnerProps) {\n const iconProps = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: size,\n height: size,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n strokeWidth: 1.5,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n };\n\n const paths = (\n <>\n <path d=\"M15 15m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0\" />\n <path d=\"M13 17.5v4.5l2 -1.5l2 1.5v-4.5\" />\n <path d=\"M10 19h-5a2 2 0 0 1 -2 -2v-10c0 -1.1 .9 -2 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-1\" />\n <path d=\"M6 9h12\" />\n <path d=\"M6 12h3\" />\n <path d=\"M6 15h2\" />\n </>\n );\n\n return (\n <Box pos=\"relative\" style={{ width: size, height: size }} role=\"status\" aria-label=\"Loading\">\n <svg\n {...iconProps}\n stroke=\"var(--mantine-color-gray-3)\"\n style={{ position: \"absolute\", inset: 0 }}\n aria-hidden=\"true\"\n >\n {paths}\n </svg>\n <svg\n {...iconProps}\n stroke=\"var(--mantine-color-indigo-5)\"\n style={{ position: \"absolute\", inset: 0, animation: \"fillUp 1.4s ease-in-out infinite\" }}\n aria-hidden=\"true\"\n >\n {paths}\n </svg>\n </Box>\n );\n}\n","import { Group, Stack, Text, Title } from \"@mantine/core\";\nimport type { ReactNode } from \"react\";\n\nexport interface PageHeaderProps {\n /** Page title text. */\n title: string;\n /** Optional subtitle text. */\n subtitle?: string;\n /** Optional right-aligned action element (button, date picker, etc.). */\n action?: ReactNode;\n}\n\nexport function PageHeader({ title, subtitle, action }: PageHeaderProps) {\n return (\n <Group justify=\"space-between\" align=\"flex-start\" mb=\"lg\">\n <Stack gap={4}>\n <Title order={2}>{title}</Title>\n {subtitle && (\n <Text c=\"dimmed\" size=\"sm\">\n {subtitle}\n </Text>\n )}\n </Stack>\n {action}\n </Group>\n );\n}\n","import { NavLink, Stack } from \"@mantine/core\";\nimport type { ReactNode } from \"react\";\n\nexport interface SideNavItem {\n /** Unique identifier for this nav item (e.g., route path or slug). */\n id: string;\n /** Display label. */\n label: string;\n /** Icon element. */\n icon?: ReactNode;\n /** Whether this item is currently active. */\n active?: boolean;\n}\n\nexport interface SideNavProps {\n /** Navigation items to render. */\n items: SideNavItem[];\n /** Callback when a nav item is clicked. Receives the item's `id`. */\n onItemClick: (id: string) => void;\n /** Active color. @default \"indigo\" */\n color?: string;\n}\n\nexport function SideNav({ items, onItemClick, color = \"indigo\" }: SideNavProps) {\n return (\n <Stack component=\"nav\" gap={4} p=\"md\" aria-label=\"Main navigation\">\n {items.map((item) => (\n <NavLink\n key={item.id}\n label={item.label}\n leftSection={item.icon}\n active={item.active}\n onClick={() => onItemClick(item.id)}\n color={color}\n variant=\"light\"\n style={{ borderRadius: \"var(--mantine-radius-md)\" }}\n styles={{\n root: {\n color: item.active ? undefined : \"var(--mantine-color-gray-5)\",\n fontWeight: item.active ? 500 : 400,\n },\n section: {\n color: item.active ? undefined : \"var(--mantine-color-gray-4)\",\n },\n }}\n />\n ))}\n </Stack>\n );\n}\n","import { Avatar, Box, Divider, Group, Menu, Text, UnstyledButton } from \"@mantine/core\";\nimport type { ReactNode } from \"react\";\n\nexport interface UserMenuItem {\n /** Unique identifier for this menu item. */\n id: string;\n /** Display label. */\n label: string;\n /** Icon element. */\n icon?: ReactNode;\n /** Item color (e.g., \"red\" for destructive actions). */\n color?: string;\n /** Optional section label above this item. Set on the first item in a group. */\n sectionLabel?: string;\n /** Show a divider before this item. */\n dividerBefore?: boolean;\n}\n\nexport interface UserMenuProps {\n /** User display name or email. */\n displayName: string;\n /** Single-character avatar initial. Derived from displayName[0] if not provided. */\n avatarInitial?: string;\n /** Avatar color. @default \"indigo\" */\n avatarColor?: string;\n /** Optional indicator element after the display name (e.g., chevron icon from your app's icon library). */\n indicator?: ReactNode;\n /** Menu items. */\n items: UserMenuItem[];\n /** Callback when a menu item is clicked. Receives the item's `id`. */\n onItemClick: (id: string) => void;\n}\n\nexport function UserMenu({\n displayName,\n avatarInitial,\n avatarColor = \"indigo\",\n indicator,\n items,\n onItemClick,\n}: UserMenuProps) {\n const initial = avatarInitial ?? displayName.charAt(0).toUpperCase();\n\n return (\n <Menu shadow=\"md\" width={200} position=\"bottom-end\">\n <Menu.Target>\n <UnstyledButton aria-label=\"User menu\">\n <Group gap=\"xs\">\n <Avatar size=\"sm\" radius=\"xl\" color={avatarColor}>\n {initial}\n </Avatar>\n <Box visibleFrom=\"sm\">\n <Text size=\"sm\" fw={500} lineClamp={1} style={{ maxWidth: 150 }}>\n {displayName}\n </Text>\n </Box>\n {indicator}\n </Group>\n </UnstyledButton>\n </Menu.Target>\n\n <Menu.Dropdown>\n {items.map((item) => (\n <div key={item.id}>\n {item.dividerBefore && <Divider my=\"xs\" />}\n {item.sectionLabel && <Menu.Label>{item.sectionLabel}</Menu.Label>}\n <Menu.Item\n leftSection={item.icon}\n color={item.color}\n onClick={() => onItemClick(item.id)}\n >\n {item.label}\n </Menu.Item>\n </div>\n ))}\n </Menu.Dropdown>\n </Menu>\n );\n}\n"],"names":["Group","jsxs","jsx","Burger","error","Container","Stack","Title","Text","Button","createTheme","MantineProvider","Fragment","Box","NavLink","Menu","UnstyledButton","Avatar","Divider"],"mappings":"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"}