@cellarnode/ui 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +238 -0
- package/dist/globe/country-coords.d.ts +29 -0
- package/dist/globe/country-coords.d.ts.map +1 -0
- package/dist/globe/country-coords.js +117 -0
- package/dist/globe/country-coords.js.map +1 -0
- package/dist/globe/globe-loading-skeleton.d.ts +10 -0
- package/dist/globe/globe-loading-skeleton.d.ts.map +1 -0
- package/dist/globe/globe-loading-skeleton.js +23 -0
- package/dist/globe/globe-loading-skeleton.js.map +1 -0
- package/dist/globe/index.d.ts +2 -0
- package/dist/globe/index.d.ts.map +1 -1
- package/dist/globe/index.js +2 -0
- package/dist/globe/index.js.map +1 -1
- package/dist/hooks/use-deferred-mount.d.ts +16 -0
- package/dist/hooks/use-deferred-mount.d.ts.map +1 -0
- package/dist/hooks/use-deferred-mount.js +32 -0
- package/dist/hooks/use-deferred-mount.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/nav/app-shell.d.ts +18 -0
- package/dist/nav/app-shell.d.ts.map +1 -0
- package/dist/nav/app-shell.js +9 -0
- package/dist/nav/app-shell.js.map +1 -0
- package/dist/nav/app-sidebar.d.ts +33 -0
- package/dist/nav/app-sidebar.d.ts.map +1 -0
- package/dist/nav/app-sidebar.js +46 -0
- package/dist/nav/app-sidebar.js.map +1 -0
- package/dist/nav/expandable-nav-item.d.ts +11 -0
- package/dist/nav/expandable-nav-item.d.ts.map +1 -0
- package/dist/nav/expandable-nav-item.js +27 -0
- package/dist/nav/expandable-nav-item.js.map +1 -0
- package/dist/nav/index.d.ts +6 -0
- package/dist/nav/index.d.ts.map +1 -0
- package/dist/nav/index.js +5 -0
- package/dist/nav/index.js.map +1 -0
- package/dist/nav/types.d.ts +40 -0
- package/dist/nav/types.d.ts.map +1 -0
- package/dist/nav/types.js +4 -0
- package/dist/nav/types.js.map +1 -0
- package/package.json +11 -2
- package/src/theme/tokens.css +6 -0
package/README.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./docs/banner.svg" alt="@cellarnode/ui" width="900"/>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://img.shields.io/badge/version-0.2.1-0ea5e9?style=flat-square" alt="version"/>
|
|
7
|
+
<img src="https://img.shields.io/badge/react-19-61dafb?style=flat-square&logo=react" alt="react 19"/>
|
|
8
|
+
<img src="https://img.shields.io/badge/TypeScript-5.9-3178c6?style=flat-square&logo=typescript" alt="typescript"/>
|
|
9
|
+
<img src="https://img.shields.io/badge/Tailwind-v4-06b6d4?style=flat-square&logo=tailwindcss" alt="tailwind v4"/>
|
|
10
|
+
<img src="https://img.shields.io/badge/Storybook-10-ff4785?style=flat-square&logo=storybook" alt="storybook"/>
|
|
11
|
+
<img src="https://img.shields.io/badge/license-UNLICENSED-gray?style=flat-square" alt="license"/>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Shared React component library for CellarNode dashboards. Ships UI primitives, design tokens, chat components, offer components, a globe visualisation, and a Kanban drag-and-drop system — all typed, tree-shakeable, and tested via Storybook.
|
|
17
|
+
|
|
18
|
+
## Contents
|
|
19
|
+
|
|
20
|
+
- [Architecture](#architecture)
|
|
21
|
+
- [Install](#install)
|
|
22
|
+
- [Peer Dependencies](#peer-dependencies)
|
|
23
|
+
- [Exports](#exports)
|
|
24
|
+
- [Theme & Design Tokens](#theme--design-tokens)
|
|
25
|
+
- [Development](#development)
|
|
26
|
+
- [Writing Stories](#writing-stories)
|
|
27
|
+
- [Make Commands](#make-commands)
|
|
28
|
+
- [Storybook MCP (AI Integration)](#storybook-mcp-ai-integration)
|
|
29
|
+
- [Publishing](#publishing)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
src/
|
|
37
|
+
├── components/ UI primitives (Button, Card, Dialog, Table, Sidebar…)
|
|
38
|
+
├── chat/ Chat & negotiation UI (CommunicationPanel, WebSocket client)
|
|
39
|
+
├── offer/ Offer workflow components (BeverageDetails, OrgBanner…)
|
|
40
|
+
├── globe/ Interactive 3-D globe visualisation (react-globe.gl)
|
|
41
|
+
├── hooks/ Shared hooks (useIsMobile, useToast, useKanbanDnd)
|
|
42
|
+
├── lib/ Utilities (cn, semantic tones, currencies, kanban transitions)
|
|
43
|
+
└── theme/
|
|
44
|
+
└── tokens.css Canonical Tailwind v4 design tokens
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Primitive layers**
|
|
48
|
+
|
|
49
|
+
| Layer | Package | Used for |
|
|
50
|
+
|-------|---------|----------|
|
|
51
|
+
| Radix UI | `@radix-ui/*` | Dialog, Dropdown, Select, Tabs, Toast… |
|
|
52
|
+
| Headless UI | `@headlessui/react` | Dropdown (Catalyst), Fieldset, Combobox |
|
|
53
|
+
| shadcn/ui | built on Radix | Chat & offer internal variants |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pnpm add @cellarnode/ui
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> **Note:** This package is published to a private npm registry. Ensure your `.npmrc` points to the correct registry.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Peer Dependencies
|
|
68
|
+
|
|
69
|
+
Install the peers your app uses:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Always required
|
|
73
|
+
pnpm add react react-dom
|
|
74
|
+
|
|
75
|
+
# Optional — only needed when importing the specific sub-path
|
|
76
|
+
pnpm add motion # animations
|
|
77
|
+
pnpm add @dnd-kit/react @dnd-kit/dom # ./kanban-dnd
|
|
78
|
+
pnpm add @tanstack/react-query # chat hooks
|
|
79
|
+
pnpm add react-globe.gl three topojson-client world-atlas # ./globe
|
|
80
|
+
pnpm add @cellarnode/beverage-utils i18n-iso-countries # ./offer
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Exports
|
|
86
|
+
|
|
87
|
+
| Import path | Contents |
|
|
88
|
+
|-------------|----------|
|
|
89
|
+
| `@cellarnode/ui` | All UI primitives, hooks, and utilities |
|
|
90
|
+
| `@cellarnode/ui/theme/tokens.css` | Tailwind v4 design token CSS |
|
|
91
|
+
| `@cellarnode/ui/chat` | CommunicationPanel, MessengerLayout, chat hooks |
|
|
92
|
+
| `@cellarnode/ui/offer` | BeverageDetails, OrgBanner, OfferStatusBadge… |
|
|
93
|
+
| `@cellarnode/ui/kanban-dnd` | KanbanDndBoard component |
|
|
94
|
+
| `@cellarnode/ui/kanban-dnd-hooks` | useDraggableCard, useDroppableColumn |
|
|
95
|
+
| `@cellarnode/ui/globe` | GlobeView component |
|
|
96
|
+
| `@cellarnode/ui/animated-list` | AnimatedList component |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Theme & Design Tokens
|
|
101
|
+
|
|
102
|
+
Import the canonical token sheet **before** Tailwind in your app's root CSS:
|
|
103
|
+
|
|
104
|
+
```css
|
|
105
|
+
@import "@cellarnode/ui/theme/tokens.css";
|
|
106
|
+
@import "tailwindcss";
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Tokens expose semantic CSS variables (`--color-background`, `--color-primary`, `--color-brand-secondary`, etc.) that are automatically mapped into Tailwind utility classes.
|
|
110
|
+
|
|
111
|
+
Light/dark mode is toggled by adding the `dark` class to `<html>`.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Development
|
|
116
|
+
|
|
117
|
+
**Prerequisites:** Node 20+, pnpm 9+, Playwright Chromium (for browser tests).
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Install dependencies
|
|
121
|
+
pnpm install
|
|
122
|
+
|
|
123
|
+
# Install Playwright browser
|
|
124
|
+
pnpm playwright install chromium
|
|
125
|
+
|
|
126
|
+
# Start Storybook dev server
|
|
127
|
+
make storybook # → http://localhost:6006
|
|
128
|
+
|
|
129
|
+
# Type-check
|
|
130
|
+
make typecheck
|
|
131
|
+
|
|
132
|
+
# Lint
|
|
133
|
+
make lint
|
|
134
|
+
|
|
135
|
+
# Run tests (Storybook browser tests, headless)
|
|
136
|
+
make test
|
|
137
|
+
|
|
138
|
+
# Full build
|
|
139
|
+
make build
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Writing Stories
|
|
145
|
+
|
|
146
|
+
Every component **must** have a `.stories.tsx` file co-located next to it.
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
150
|
+
import { Button } from "./button";
|
|
151
|
+
|
|
152
|
+
const meta = {
|
|
153
|
+
title: "Components/Button",
|
|
154
|
+
component: Button,
|
|
155
|
+
tags: ["autodocs"],
|
|
156
|
+
} satisfies Meta<typeof Button>;
|
|
157
|
+
|
|
158
|
+
export default meta;
|
|
159
|
+
type Story = StoryObj<typeof meta>;
|
|
160
|
+
|
|
161
|
+
export const Default: Story = {
|
|
162
|
+
args: { children: "Click me" },
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const Variants: Story = {
|
|
166
|
+
render: () => (
|
|
167
|
+
<div className="flex gap-3">
|
|
168
|
+
<Button color="brand">Brand</Button>
|
|
169
|
+
<Button outline>Outline</Button>
|
|
170
|
+
<Button plain>Plain</Button>
|
|
171
|
+
</div>
|
|
172
|
+
),
|
|
173
|
+
};
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Conventions
|
|
177
|
+
|
|
178
|
+
- `tags: ["autodocs"]` → auto-generated prop docs
|
|
179
|
+
- Include a `Default` story + at least one variant story
|
|
180
|
+
- Use `argTypes` for enum-like props (color, size, variant)
|
|
181
|
+
- Check the **A11y** addon panel — fix all violations before merging
|
|
182
|
+
- Toggle **light / dark** via the Themes toolbar
|
|
183
|
+
- Write `play` functions for interaction testing when behaviour is complex
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Make Commands
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
make build Full build: lint + typecheck + compile
|
|
191
|
+
make clean Remove dist/
|
|
192
|
+
make compile Compile TypeScript to dist/
|
|
193
|
+
make lint Run ESLint
|
|
194
|
+
make typecheck TypeScript type checking (no emit)
|
|
195
|
+
make test Run Storybook/Vitest browser tests (headless Chromium)
|
|
196
|
+
make test-watch Run Vitest in watch mode
|
|
197
|
+
make storybook Start Storybook dev server on :6006
|
|
198
|
+
make build-storybook Build static Storybook to storybook-static/
|
|
199
|
+
make publish Build and publish current version to npm
|
|
200
|
+
make release-patch Bump patch version, publish, and git tag
|
|
201
|
+
make release-minor Bump minor version, publish, and git tag
|
|
202
|
+
make release-major Bump major version, publish, and git tag
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Storybook MCP (AI Integration)
|
|
208
|
+
|
|
209
|
+
When Storybook is running (`make storybook`), the `@storybook/addon-mcp` addon exposes an MCP server at `http://localhost:6006/mcp`.
|
|
210
|
+
|
|
211
|
+
**Register it with Claude Code once:**
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
claude mcp add storybook-mcp --transport http http://localhost:6006/mcp --scope project
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Available MCP tools:**
|
|
218
|
+
|
|
219
|
+
| Tool | Description |
|
|
220
|
+
|------|-------------|
|
|
221
|
+
| `get_ui_building_instructions` | Guidelines for creating components and stories |
|
|
222
|
+
| `get_story_urls` | Direct browser links to every story |
|
|
223
|
+
|
|
224
|
+
**Component manifest** (for AI context): `http://localhost:6006/manifests/components.html`
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Publishing
|
|
229
|
+
|
|
230
|
+
Packages are published to npm (restricted access). Releases are managed via Make:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
make release-patch # 0.2.1 → 0.2.2
|
|
234
|
+
make release-minor # 0.2.1 → 0.3.0
|
|
235
|
+
make release-major # 0.2.1 → 1.0.0
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Each release target: bumps version in `package.json`, publishes to npm, commits, and creates a git tag `ui-vX.Y.Z`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact country centroid coordinates (ISO-3166-1 alpha-2 → lat/lng).
|
|
3
|
+
* Covers all major wine & beverage producing/importing regions plus full global coverage.
|
|
4
|
+
* Centroids are approximate geographic centers suitable for globe arc endpoints.
|
|
5
|
+
*/
|
|
6
|
+
export declare const COUNTRY_COORDS: Record<string, {
|
|
7
|
+
lat: number;
|
|
8
|
+
lng: number;
|
|
9
|
+
name: string;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Look up coordinates for an ISO-3166-1 alpha-2 country code.
|
|
13
|
+
* Returns null if the code is unknown.
|
|
14
|
+
*/
|
|
15
|
+
export declare function countryCoords(code: string): {
|
|
16
|
+
lat: number;
|
|
17
|
+
lng: number;
|
|
18
|
+
name: string;
|
|
19
|
+
} | null;
|
|
20
|
+
/**
|
|
21
|
+
* Batch look up coordinates, skipping unknown codes.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveCountries(codes: string[]): Array<{
|
|
24
|
+
code: string;
|
|
25
|
+
lat: number;
|
|
26
|
+
lng: number;
|
|
27
|
+
name: string;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=country-coords.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"country-coords.d.ts","sourceRoot":"","sources":["../../src/globe/country-coords.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA6FrF,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAI7F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAMjH"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact country centroid coordinates (ISO-3166-1 alpha-2 → lat/lng).
|
|
3
|
+
* Covers all major wine & beverage producing/importing regions plus full global coverage.
|
|
4
|
+
* Centroids are approximate geographic centers suitable for globe arc endpoints.
|
|
5
|
+
*/
|
|
6
|
+
export const COUNTRY_COORDS = {
|
|
7
|
+
// Europe — wine & spirits heartland
|
|
8
|
+
FR: { lat: 46.23, lng: 2.21, name: "France" },
|
|
9
|
+
IT: { lat: 42.83, lng: 12.83, name: "Italy" },
|
|
10
|
+
ES: { lat: 40.46, lng: -3.75, name: "Spain" },
|
|
11
|
+
PT: { lat: 39.4, lng: -8.22, name: "Portugal" },
|
|
12
|
+
DE: { lat: 51.17, lng: 10.45, name: "Germany" },
|
|
13
|
+
AT: { lat: 47.52, lng: 14.55, name: "Austria" },
|
|
14
|
+
CH: { lat: 46.82, lng: 8.23, name: "Switzerland" },
|
|
15
|
+
GB: { lat: 55.38, lng: -3.44, name: "United Kingdom" },
|
|
16
|
+
BE: { lat: 50.5, lng: 4.47, name: "Belgium" },
|
|
17
|
+
NL: { lat: 52.13, lng: 5.29, name: "Netherlands" },
|
|
18
|
+
SE: { lat: 60.13, lng: 18.64, name: "Sweden" },
|
|
19
|
+
NO: { lat: 60.47, lng: 8.47, name: "Norway" },
|
|
20
|
+
DK: { lat: 56.26, lng: 9.5, name: "Denmark" },
|
|
21
|
+
FI: { lat: 61.92, lng: 25.75, name: "Finland" },
|
|
22
|
+
IE: { lat: 53.41, lng: -8.24, name: "Ireland" },
|
|
23
|
+
GR: { lat: 39.07, lng: 21.82, name: "Greece" },
|
|
24
|
+
HR: { lat: 45.1, lng: 15.2, name: "Croatia" },
|
|
25
|
+
SI: { lat: 46.15, lng: 14.99, name: "Slovenia" },
|
|
26
|
+
HU: { lat: 47.16, lng: 19.5, name: "Hungary" },
|
|
27
|
+
CZ: { lat: 49.82, lng: 15.47, name: "Czech Republic" },
|
|
28
|
+
SK: { lat: 48.67, lng: 19.7, name: "Slovakia" },
|
|
29
|
+
PL: { lat: 51.92, lng: 19.14, name: "Poland" },
|
|
30
|
+
RO: { lat: 45.94, lng: 24.97, name: "Romania" },
|
|
31
|
+
BG: { lat: 42.73, lng: 25.49, name: "Bulgaria" },
|
|
32
|
+
MD: { lat: 47.41, lng: 28.37, name: "Moldova" },
|
|
33
|
+
UA: { lat: 48.38, lng: 31.17, name: "Ukraine" },
|
|
34
|
+
RS: { lat: 44.02, lng: 21.01, name: "Serbia" },
|
|
35
|
+
ME: { lat: 42.71, lng: 19.37, name: "Montenegro" },
|
|
36
|
+
BA: { lat: 44.16, lng: 17.68, name: "Bosnia and Herzegovina" },
|
|
37
|
+
MK: { lat: 41.61, lng: 21.75, name: "North Macedonia" },
|
|
38
|
+
AL: { lat: 41.15, lng: 20.17, name: "Albania" },
|
|
39
|
+
LU: { lat: 49.82, lng: 6.13, name: "Luxembourg" },
|
|
40
|
+
MT: { lat: 35.94, lng: 14.37, name: "Malta" },
|
|
41
|
+
CY: { lat: 35.13, lng: 33.43, name: "Cyprus" },
|
|
42
|
+
// Americas
|
|
43
|
+
US: { lat: 37.09, lng: -95.71, name: "United States" },
|
|
44
|
+
CA: { lat: 56.13, lng: -106.35, name: "Canada" },
|
|
45
|
+
MX: { lat: 23.63, lng: -102.55, name: "Mexico" },
|
|
46
|
+
AR: { lat: -38.42, lng: -63.62, name: "Argentina" },
|
|
47
|
+
CL: { lat: -35.68, lng: -71.54, name: "Chile" },
|
|
48
|
+
BR: { lat: -14.24, lng: -51.93, name: "Brazil" },
|
|
49
|
+
UY: { lat: -32.52, lng: -55.77, name: "Uruguay" },
|
|
50
|
+
PE: { lat: -9.19, lng: -75.02, name: "Peru" },
|
|
51
|
+
CO: { lat: 4.57, lng: -74.3, name: "Colombia" },
|
|
52
|
+
EC: { lat: -1.83, lng: -78.18, name: "Ecuador" },
|
|
53
|
+
BO: { lat: -16.29, lng: -63.59, name: "Bolivia" },
|
|
54
|
+
// Oceania
|
|
55
|
+
AU: { lat: -25.27, lng: 133.78, name: "Australia" },
|
|
56
|
+
NZ: { lat: -40.9, lng: 174.89, name: "New Zealand" },
|
|
57
|
+
// Asia
|
|
58
|
+
CN: { lat: 35.86, lng: 104.2, name: "China" },
|
|
59
|
+
JP: { lat: 36.2, lng: 138.25, name: "Japan" },
|
|
60
|
+
KR: { lat: 35.91, lng: 127.77, name: "South Korea" },
|
|
61
|
+
IN: { lat: 20.59, lng: 78.96, name: "India" },
|
|
62
|
+
SG: { lat: 1.35, lng: 103.82, name: "Singapore" },
|
|
63
|
+
HK: { lat: 22.32, lng: 114.17, name: "Hong Kong" },
|
|
64
|
+
TW: { lat: 23.7, lng: 120.96, name: "Taiwan" },
|
|
65
|
+
TH: { lat: 15.87, lng: 100.99, name: "Thailand" },
|
|
66
|
+
VN: { lat: 14.06, lng: 108.28, name: "Vietnam" },
|
|
67
|
+
MY: { lat: 4.21, lng: 101.98, name: "Malaysia" },
|
|
68
|
+
ID: { lat: -0.79, lng: 113.92, name: "Indonesia" },
|
|
69
|
+
PH: { lat: 12.88, lng: 121.77, name: "Philippines" },
|
|
70
|
+
PK: { lat: 30.38, lng: 69.35, name: "Pakistan" },
|
|
71
|
+
BD: { lat: 23.68, lng: 90.36, name: "Bangladesh" },
|
|
72
|
+
LK: { lat: 7.87, lng: 80.77, name: "Sri Lanka" },
|
|
73
|
+
NP: { lat: 28.39, lng: 84.12, name: "Nepal" },
|
|
74
|
+
IL: { lat: 31.05, lng: 34.85, name: "Israel" },
|
|
75
|
+
TR: { lat: 38.96, lng: 35.24, name: "Turkey" },
|
|
76
|
+
GE: { lat: 42.32, lng: 43.36, name: "Georgia" },
|
|
77
|
+
AM: { lat: 40.07, lng: 45.04, name: "Armenia" },
|
|
78
|
+
AZ: { lat: 40.14, lng: 47.58, name: "Azerbaijan" },
|
|
79
|
+
UZ: { lat: 41.38, lng: 64.59, name: "Uzbekistan" },
|
|
80
|
+
KZ: { lat: 48.02, lng: 66.92, name: "Kazakhstan" },
|
|
81
|
+
AE: { lat: 23.42, lng: 53.85, name: "United Arab Emirates" },
|
|
82
|
+
SA: { lat: 23.89, lng: 45.08, name: "Saudi Arabia" },
|
|
83
|
+
QA: { lat: 25.35, lng: 51.18, name: "Qatar" },
|
|
84
|
+
// Africa
|
|
85
|
+
ZA: { lat: -30.56, lng: 22.94, name: "South Africa" },
|
|
86
|
+
MA: { lat: 31.79, lng: -7.09, name: "Morocco" },
|
|
87
|
+
TN: { lat: 33.89, lng: 9.54, name: "Tunisia" },
|
|
88
|
+
DZ: { lat: 28.03, lng: 1.66, name: "Algeria" },
|
|
89
|
+
EG: { lat: 26.82, lng: 30.8, name: "Egypt" },
|
|
90
|
+
NG: { lat: 9.08, lng: 8.68, name: "Nigeria" },
|
|
91
|
+
ET: { lat: 9.15, lng: 40.49, name: "Ethiopia" },
|
|
92
|
+
KE: { lat: -0.02, lng: 37.91, name: "Kenya" },
|
|
93
|
+
GH: { lat: 7.95, lng: -1.02, name: "Ghana" },
|
|
94
|
+
TZ: { lat: -6.37, lng: 34.89, name: "Tanzania" },
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Look up coordinates for an ISO-3166-1 alpha-2 country code.
|
|
98
|
+
* Returns null if the code is unknown.
|
|
99
|
+
*/
|
|
100
|
+
export function countryCoords(code) {
|
|
101
|
+
if (!code)
|
|
102
|
+
return null;
|
|
103
|
+
const normalized = code.trim().toUpperCase();
|
|
104
|
+
return COUNTRY_COORDS[normalized] ?? null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Batch look up coordinates, skipping unknown codes.
|
|
108
|
+
*/
|
|
109
|
+
export function resolveCountries(codes) {
|
|
110
|
+
return codes.flatMap((code) => {
|
|
111
|
+
const coords = countryCoords(code);
|
|
112
|
+
if (!coords)
|
|
113
|
+
return [];
|
|
114
|
+
return [{ code: code.toUpperCase(), ...coords }];
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=country-coords.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"country-coords.js","sourceRoot":"","sources":["../../src/globe/country-coords.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animated loading skeleton shown while globe data is being fetched.
|
|
3
|
+
* Renders a pulsing globe silhouette with arc-trace lines and a status label.
|
|
4
|
+
*/
|
|
5
|
+
export declare function GlobeLoadingSkeleton({ height, label, className, }: {
|
|
6
|
+
height?: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=globe-loading-skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globe-loading-skeleton.d.ts","sourceRoot":"","sources":["../../src/globe/globe-loading-skeleton.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAoC,EACpC,KAA+B,EAC/B,SAAc,GACf,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CA4DA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Animated loading skeleton shown while globe data is being fetched.
|
|
4
|
+
* Renders a pulsing globe silhouette with arc-trace lines and a status label.
|
|
5
|
+
*/
|
|
6
|
+
export function GlobeLoadingSkeleton({ height = "clamp(320px, 40vw, 450px)", label = "Mapping global flows…", className = "", }) {
|
|
7
|
+
return (_jsxs("div", { className: `relative flex flex-col items-center justify-center overflow-hidden rounded-xl bg-primary/5 dark:bg-white/[0.03] ${className}`, style: { height }, "aria-label": label, "aria-busy": "true", children: [_jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute inset-0 rounded-full animate-ping bg-primary/10 dark:bg-white/5 scale-110" }), _jsxs("div", { className: "relative size-36 rounded-full border-2 border-primary/20 dark:border-white/10 bg-primary/5 dark:bg-white/5 animate-pulse", children: [_jsx("div", { className: "absolute inset-x-0 top-[30%] h-px bg-primary/15 dark:bg-white/10" }), _jsx("div", { className: "absolute inset-x-0 top-[50%] h-px bg-primary/20 dark:bg-white/15" }), _jsx("div", { className: "absolute inset-x-0 top-[70%] h-px bg-primary/15 dark:bg-white/10" }), _jsx("div", { className: "absolute inset-y-0 left-[50%] w-px -translate-x-1/2 bg-primary/15 dark:bg-white/10" }), _jsx("div", { className: "absolute inset-y-0 bg-primary/10 dark:bg-white/8", style: {
|
|
8
|
+
left: "25%",
|
|
9
|
+
right: "25%",
|
|
10
|
+
borderLeft: "1px solid",
|
|
11
|
+
borderRight: "1px solid",
|
|
12
|
+
borderColor: "rgba(var(--color-primary-rgb, 14 165 114) / 0.12)",
|
|
13
|
+
borderRadius: "50%",
|
|
14
|
+
} })] })] }), _jsxs("svg", { className: "absolute inset-0 size-full opacity-30", viewBox: "0 0 400 400", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [_jsx(ArcTrace, { d: "M 60 250 Q 200 80 340 200", delay: "0s" }), _jsx(ArcTrace, { d: "M 80 180 Q 180 300 320 160", delay: "0.4s" }), _jsx(ArcTrace, { d: "M 100 300 Q 230 120 360 280", delay: "0.8s" }), _jsx(ArcTrace, { d: "M 50 200 Q 160 60 300 220", delay: "1.2s" })] }), _jsxs("div", { className: "mt-6 flex items-center gap-2", children: [_jsx("span", { className: "inline-block size-1.5 rounded-full bg-primary/60 dark:bg-white/40 animate-bounce [animation-delay:0ms]" }), _jsx("span", { className: "inline-block size-1.5 rounded-full bg-primary/60 dark:bg-white/40 animate-bounce [animation-delay:150ms]" }), _jsx("span", { className: "inline-block size-1.5 rounded-full bg-primary/60 dark:bg-white/40 animate-bounce [animation-delay:300ms]" }), _jsx("span", { className: "ml-2 text-xs font-medium text-muted-foreground/70 tracking-wide", children: label })] })] }));
|
|
15
|
+
}
|
|
16
|
+
function ArcTrace({ d, delay }) {
|
|
17
|
+
return (_jsx("path", { d: d, stroke: "currentColor", strokeWidth: "1.5", strokeDasharray: "6 4", className: "text-primary dark:text-white", style: {
|
|
18
|
+
animation: `dash-trace 2s linear infinite`,
|
|
19
|
+
animationDelay: delay,
|
|
20
|
+
opacity: 0.4,
|
|
21
|
+
} }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=globe-loading-skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globe-loading-skeleton.js","sourceRoot":"","sources":["../../src/globe/globe-loading-skeleton.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,MAAM,GAAG,2BAA2B,EACpC,KAAK,GAAG,uBAAuB,EAC/B,SAAS,GAAG,EAAE,GAKf;IACC,OAAO,CACL,eACE,SAAS,EAAE,mHAAmH,SAAS,EAAE,EACzI,KAAK,EAAE,EAAE,MAAM,EAAE,gBACL,KAAK,eACP,MAAM,aAGhB,eAAK,SAAS,EAAC,UAAU,aAEvB,cAAK,SAAS,EAAC,oFAAoF,GAAG,EAEtG,eAAK,SAAS,EAAC,0HAA0H,aAEvI,cAAK,SAAS,EAAC,kEAAkE,GAAG,EACpF,cAAK,SAAS,EAAC,kEAAkE,GAAG,EACpF,cAAK,SAAS,EAAC,kEAAkE,GAAG,EAEpF,cAAK,SAAS,EAAC,oFAAoF,GAAG,EAEtG,cACE,SAAS,EAAC,kDAAkD,EAC5D,KAAK,EAAE;oCACL,IAAI,EAAE,KAAK;oCACX,KAAK,EAAE,KAAK;oCACZ,UAAU,EAAE,WAAW;oCACvB,WAAW,EAAE,WAAW;oCACxB,WAAW,EAAE,mDAAmD;oCAChE,YAAY,EAAE,KAAK;iCACpB,GACD,IACE,IACF,EAGN,eACE,SAAS,EAAC,uCAAuC,EACjD,OAAO,EAAC,aAAa,EACrB,IAAI,EAAC,MAAM,EACX,KAAK,EAAC,4BAA4B,iBACtB,MAAM,aAElB,KAAC,QAAQ,IAAC,CAAC,EAAC,2BAA2B,EAAC,KAAK,EAAC,IAAI,GAAG,EACrD,KAAC,QAAQ,IAAC,CAAC,EAAC,4BAA4B,EAAC,KAAK,EAAC,MAAM,GAAG,EACxD,KAAC,QAAQ,IAAC,CAAC,EAAC,6BAA6B,EAAC,KAAK,EAAC,MAAM,GAAG,EACzD,KAAC,QAAQ,IAAC,CAAC,EAAC,2BAA2B,EAAC,KAAK,EAAC,MAAM,GAAG,IACnD,EAGN,eAAK,SAAS,EAAC,8BAA8B,aAC3C,eAAM,SAAS,EAAC,wGAAwG,GAAG,EAC3H,eAAM,SAAS,EAAC,0GAA0G,GAAG,EAC7H,eAAM,SAAS,EAAC,0GAA0G,GAAG,EAC7H,eAAM,SAAS,EAAC,iEAAiE,YAC9E,KAAK,GACD,IACH,IACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,EAAE,CAAC,EAAE,KAAK,EAAgC;IAC1D,OAAO,CACL,eACE,CAAC,EAAE,CAAC,EACJ,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,KAAK,EACjB,eAAe,EAAC,KAAK,EACrB,SAAS,EAAC,8BAA8B,EACxC,KAAK,EAAE;YACL,SAAS,EAAE,+BAA+B;YAC1C,cAAc,EAAE,KAAK;YACrB,OAAO,EAAE,GAAG;SACb,GACD,CACH,CAAC;AACJ,CAAC"}
|
package/dist/globe/index.d.ts
CHANGED
|
@@ -9,4 +9,6 @@ export { useElectronEmitter } from "./electron-arc";
|
|
|
9
9
|
export { GlobeView } from "./globe-view";
|
|
10
10
|
export type { GlobeViewProps } from "./globe-view";
|
|
11
11
|
export { addStarfield, addHalo, getVignetteStyle } from "./scene-extras";
|
|
12
|
+
export { GlobeLoadingSkeleton } from "./globe-loading-skeleton";
|
|
13
|
+
export { countryCoords, resolveCountries, COUNTRY_COORDS } from "./country-coords";
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/globe/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjG,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE1E,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/globe/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjG,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE1E,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/globe/index.js
CHANGED
|
@@ -4,4 +4,6 @@ export { numericToAlpha2, alpha2ToNumeric } from "./map/country-code-map";
|
|
|
4
4
|
export { useElectronEmitter } from "./electron-arc";
|
|
5
5
|
export { GlobeView } from "./globe-view";
|
|
6
6
|
export { addStarfield, addHalo, getVignetteStyle } from "./scene-extras";
|
|
7
|
+
export { GlobeLoadingSkeleton } from "./globe-loading-skeleton";
|
|
8
|
+
export { countryCoords, resolveCountries, COUNTRY_COORDS } from "./country-coords";
|
|
7
9
|
//# sourceMappingURL=index.js.map
|
package/dist/globe/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/globe/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGjG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/globe/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGjG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defers mounting of heavy components (e.g. WebGL globe) until the browser is
|
|
3
|
+
* idle, preventing them from blocking the main thread during initial page paint.
|
|
4
|
+
*
|
|
5
|
+
* Uses `requestIdleCallback` with a `setTimeout` fallback for browsers that
|
|
6
|
+
* don't support it (Safari < 18).
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* function GlobeWrapper() {
|
|
10
|
+
* const mounted = useDeferredMount();
|
|
11
|
+
* if (!mounted) return <Skeleton className="h-96 w-full rounded-xl" />;
|
|
12
|
+
* return <Suspense fallback={<Skeleton />}><GlobeView /></Suspense>;
|
|
13
|
+
* }
|
|
14
|
+
*/
|
|
15
|
+
export declare function useDeferredMount(delayMs?: number): boolean;
|
|
16
|
+
//# sourceMappingURL=use-deferred-mount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-deferred-mount.d.ts","sourceRoot":"","sources":["../../src/hooks/use-deferred-mount.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAK,GAAG,OAAO,CAmBtD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Defers mounting of heavy components (e.g. WebGL globe) until the browser is
|
|
4
|
+
* idle, preventing them from blocking the main thread during initial page paint.
|
|
5
|
+
*
|
|
6
|
+
* Uses `requestIdleCallback` with a `setTimeout` fallback for browsers that
|
|
7
|
+
* don't support it (Safari < 18).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* function GlobeWrapper() {
|
|
11
|
+
* const mounted = useDeferredMount();
|
|
12
|
+
* if (!mounted) return <Skeleton className="h-96 w-full rounded-xl" />;
|
|
13
|
+
* return <Suspense fallback={<Skeleton />}><GlobeView /></Suspense>;
|
|
14
|
+
* }
|
|
15
|
+
*/
|
|
16
|
+
export function useDeferredMount(delayMs = 50) {
|
|
17
|
+
const [mounted, setMounted] = useState(false);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
let handle;
|
|
20
|
+
if (typeof requestIdleCallback !== "undefined") {
|
|
21
|
+
handle = requestIdleCallback(() => setMounted(true), {
|
|
22
|
+
timeout: delayMs,
|
|
23
|
+
});
|
|
24
|
+
return () => cancelIdleCallback(handle);
|
|
25
|
+
}
|
|
26
|
+
// Safari fallback
|
|
27
|
+
const timer = setTimeout(() => setMounted(true), delayMs);
|
|
28
|
+
return () => clearTimeout(timer);
|
|
29
|
+
}, [delayMs]);
|
|
30
|
+
return mounted;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=use-deferred-mount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-deferred-mount.js","sourceRoot":"","sources":["../../src/hooks/use-deferred-mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAO,GAAG,EAAE;IAC3C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAc,CAAC;QAEnB,IAAI,OAAO,mBAAmB,KAAK,WAAW,EAAE,CAAC;YAC/C,MAAM,GAAG,mBAAmB,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;gBACnD,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,kBAAkB;QAClB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { toneClass, offerStatusTone, type SemanticTone, } from "./lib/semantic-t
|
|
|
3
3
|
export { COMMON_CURRENCIES, type CurrencyCode } from "./lib/currencies";
|
|
4
4
|
export { useIsMobile } from "./hooks/use-mobile";
|
|
5
5
|
export { useToast, toast as radixToast } from "./hooks/use-toast";
|
|
6
|
+
export { useDeferredMount } from "./hooks/use-deferred-mount";
|
|
6
7
|
export * from "./components/accordion";
|
|
7
8
|
export * from "./components/alert";
|
|
8
9
|
export * from "./components/avatar";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,SAAS,EACT,eAAe,EACf,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGxE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export { COMMON_CURRENCIES } from "./lib/currencies";
|
|
|
4
4
|
// Hooks
|
|
5
5
|
export { useIsMobile } from "./hooks/use-mobile";
|
|
6
6
|
export { useToast, toast as radixToast } from "./hooks/use-toast";
|
|
7
|
+
export { useDeferredMount } from "./hooks/use-deferred-mount";
|
|
7
8
|
// Components (alphabetical)
|
|
8
9
|
export * from "./components/accordion";
|
|
9
10
|
export * from "./components/alert";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,SAAS,EACT,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAqB,MAAM,kBAAkB,CAAC;AAExE,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface AppShellProps {
|
|
3
|
+
/** The rendered sidebar content (e.g. <AppSidebar ...props />) */
|
|
4
|
+
sidebar: React.ReactNode;
|
|
5
|
+
/** Main page content */
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
/** Page title for mobile top bar */
|
|
8
|
+
mobileTitle?: string;
|
|
9
|
+
/** Right-side slot for mobile top bar (notifications, avatar, etc.) */
|
|
10
|
+
mobileTray?: React.ReactNode;
|
|
11
|
+
/** Floating overlay (e.g. Chat FAB) rendered outside the scroll area */
|
|
12
|
+
overlay?: React.ReactNode;
|
|
13
|
+
/** Optional extra class on the main content wrapper */
|
|
14
|
+
contentClassName?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function AppShell({ sidebar, children, mobileTitle, mobileTray, overlay, contentClassName, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=app-shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../src/nav/app-shell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,UAAU,aAAa;IACrB,kEAAkE;IAClE,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,wBAAwB;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,wEAAwE;IACxE,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,WAAW,EACX,UAAU,EACV,OAAO,EACP,gBAAgB,GACjB,EAAE,aAAa,2CA8Ef"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Sheet, SheetContent } from "../components/sheet";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
export function AppShell({ sidebar, children, mobileTitle, mobileTray, overlay, contentClassName, }) {
|
|
6
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
7
|
+
return (_jsxs("div", { className: "min-h-dvh", children: [_jsx(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: _jsx(SheetContent, { side: "left", className: "w-72 max-w-xs p-0 border-r-0 [&>button]:hidden", children: _jsx("div", { className: "flex h-full flex-col", children: sidebar }) }) }), _jsx("div", { className: "hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-72 lg:flex-col", children: sidebar }), _jsxs("div", { className: cn("lg:pl-72 flex flex-col min-h-dvh", contentClassName), children: [_jsxs("div", { className: "sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b border-border bg-card px-4 shadow-xs sm:gap-x-6 sm:px-6 lg:hidden", children: [_jsx("button", { type: "button", onClick: () => setMobileOpen(true), className: "-m-2.5 p-2.5 text-foreground", "aria-label": "Open sidebar", children: _jsx("svg", { className: "size-6", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" }) }) }), _jsx("div", { "aria-hidden": "true", className: "h-6 w-px bg-border" }), _jsxs("div", { className: "flex items-center gap-2 truncate", children: [_jsx("img", { src: "/android-chrome-192x192.png", alt: "", className: "size-4 shrink-0 rounded-xs" }), mobileTitle && (_jsx("span", { className: "text-sm font-semibold font-display text-foreground truncate", children: mobileTitle }))] }), mobileTray && (_jsx("div", { className: "ml-auto flex items-center gap-x-3", children: mobileTray }))] }), _jsx("main", { className: "flex-1 flex flex-col py-8", children: _jsx("div", { className: "flex-1 flex flex-col px-4 sm:px-6 lg:px-8", children: children }) })] }), overlay] }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=app-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-shell.js","sourceRoot":"","sources":["../../src/nav/app-shell.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAiBlC,MAAM,UAAU,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,WAAW,EACX,UAAU,EACV,OAAO,EACP,gBAAgB,GACF;IACd,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpD,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,aAExB,KAAC,KAAK,IAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,YAClD,KAAC,YAAY,IACX,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,gDAAgD,YAE1D,cAAK,SAAS,EAAC,sBAAsB,YAAE,OAAO,GAAO,GACxC,GACT,EAGR,cAAK,SAAS,EAAC,kEAAkE,YAC9E,OAAO,GACJ,EAGN,eAAK,SAAS,EAAE,EAAE,CAAC,kCAAkC,EAAE,gBAAgB,CAAC,aAEtE,eAAK,SAAS,EAAC,sIAAsI,aACnJ,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAClC,SAAS,EAAC,8BAA8B,gBAC7B,cAAc,YAEzB,cACE,SAAS,EAAC,QAAQ,EAClB,IAAI,EAAC,MAAM,EACX,OAAO,EAAC,WAAW,EACnB,WAAW,EAAE,GAAG,EAChB,MAAM,EAAC,cAAc,iBACT,MAAM,YAElB,eACE,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,CAAC,EAAC,8CAA8C,GAChD,GACE,GACC,EAET,6BAAiB,MAAM,EAAC,SAAS,EAAC,oBAAoB,GAAG,EAEzD,eAAK,SAAS,EAAC,kCAAkC,aAC/C,cACE,GAAG,EAAC,6BAA6B,EACjC,GAAG,EAAC,EAAE,EACN,SAAS,EAAC,4BAA4B,GACtC,EACD,WAAW,IAAI,CACd,eAAM,SAAS,EAAC,6DAA6D,YAC1E,WAAW,GACP,CACR,IACG,EAEL,UAAU,IAAI,CACb,cAAK,SAAS,EAAC,mCAAmC,YAAE,UAAU,GAAO,CACtE,IACG,EAGN,eAAM,SAAS,EAAC,2BAA2B,YACzC,cAAK,SAAS,EAAC,2CAA2C,YACvD,QAAQ,GACL,GACD,IACH,EAGL,OAAO,IACJ,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type SidebarNavLeafItem, type SidebarNavSection, type SidebarUser, type RenderLinkFn } from "./types";
|
|
3
|
+
interface AppSidebarProps {
|
|
4
|
+
/** "Producer Portal" | "Importer Portal" | any custom label */
|
|
5
|
+
portalLabel: string;
|
|
6
|
+
/** Optional pinned dashboard item shown above nav sections */
|
|
7
|
+
dashboardItem?: SidebarNavLeafItem;
|
|
8
|
+
navSections: SidebarNavSection[];
|
|
9
|
+
/** Current route pathname for active-state determination */
|
|
10
|
+
currentPath: string;
|
|
11
|
+
/** Provide the router-aware Link component */
|
|
12
|
+
renderLink: RenderLinkFn;
|
|
13
|
+
user: SidebarUser | null;
|
|
14
|
+
isDark: boolean;
|
|
15
|
+
onToggleTheme: () => void;
|
|
16
|
+
onSignOut: () => void;
|
|
17
|
+
/** Notification button (e.g. <NotificationPanel />) rendered in footer */
|
|
18
|
+
notificationSlot?: React.ReactNode;
|
|
19
|
+
/** Language switcher rendered in footer */
|
|
20
|
+
languageSwitcherSlot?: React.ReactNode;
|
|
21
|
+
/** Any dashboard-specific controls in the footer (e.g. data-source toggle) */
|
|
22
|
+
extraFooterContent?: React.ReactNode;
|
|
23
|
+
/** i18n overrides */
|
|
24
|
+
labels?: {
|
|
25
|
+
signOut?: string;
|
|
26
|
+
user?: string;
|
|
27
|
+
switchToLight?: string;
|
|
28
|
+
switchToDark?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export declare function AppSidebar({ portalLabel, dashboardItem, navSections, currentPath, renderLink, user, isDark, onToggleTheme, onSignOut, notificationSlot, languageSwitcherSlot, extraFooterContent, labels, }: AppSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=app-sidebar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../src/nav/app-sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,SAAS,CAAC;AAIjB,UAAU,eAAe;IACvB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,UAAU,EAAE,YAAY,CAAC;IACzB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,2CAA2C;IAC3C,oBAAoB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvC,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC,qBAAqB;IACrB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAOD,wBAAgB,UAAU,CAAC,EACzB,WAAW,EACX,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,EACV,IAAI,EACJ,MAAM,EACN,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,MAAW,GACZ,EAAE,eAAe,2CAkKjB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Sun, Moon } from "lucide-react";
|
|
3
|
+
import { cn } from "../lib/utils";
|
|
4
|
+
import { ExpandableNavItem } from "./expandable-nav-item";
|
|
5
|
+
import { isSidebarNavExpandable, } from "./types";
|
|
6
|
+
const BRAND_NAME = "CellarNode";
|
|
7
|
+
function isActive(currentPath, href) {
|
|
8
|
+
if (href === "/" || href === "/dashboard")
|
|
9
|
+
return currentPath === href;
|
|
10
|
+
return currentPath.startsWith(href);
|
|
11
|
+
}
|
|
12
|
+
export function AppSidebar({ portalLabel, dashboardItem, navSections, currentPath, renderLink, user, isDark, onToggleTheme, onSignOut, notificationSlot, languageSwitcherSlot, extraFooterContent, labels = {}, }) {
|
|
13
|
+
const ThemeIcon = isDark ? Sun : Moon;
|
|
14
|
+
const initials = user?.initials
|
|
15
|
+
?? (user?.name
|
|
16
|
+
? user.name
|
|
17
|
+
.split(" ")
|
|
18
|
+
.map((n) => n[0])
|
|
19
|
+
.join("")
|
|
20
|
+
.toUpperCase()
|
|
21
|
+
.slice(0, 2)
|
|
22
|
+
: "?");
|
|
23
|
+
return (_jsxs("div", { className: "relative flex grow flex-col gap-y-5 overflow-y-auto bg-primary px-6 dark:bg-sidebar dark:before:pointer-events-none dark:before:absolute dark:before:inset-0 dark:before:border-r dark:before:border-white/5 dark:before:bg-white/[0.015]", children: [_jsx("div", { className: "relative flex h-16 shrink-0 items-center gap-3", children: renderLink({
|
|
24
|
+
href: dashboardItem?.href ?? "/",
|
|
25
|
+
className: "flex items-center gap-3",
|
|
26
|
+
children: (_jsxs(_Fragment, { children: [_jsx("img", { src: "/android-chrome-192x192.png", alt: BRAND_NAME, className: "size-10 shrink-0 rounded-[1.15rem]" }), _jsxs("div", { className: "flex flex-col leading-none", children: [_jsx("span", { className: "text-sm font-semibold font-display tracking-tight text-white dark:text-sidebar-foreground", children: BRAND_NAME }), _jsx("span", { className: "text-[11px] uppercase tracking-[0.16em] text-white/65 dark:text-sidebar-foreground/65", children: portalLabel })] })] })),
|
|
27
|
+
}) }), _jsx("nav", { className: "relative flex flex-1 flex-col", children: _jsxs("ul", { role: "list", className: "flex flex-1 flex-col gap-y-7", children: [dashboardItem && (_jsx("li", { children: _jsx("ul", { role: "list", className: "-mx-2 mt-2 space-y-1.5", children: _jsx(NavLeafItem, { item: dashboardItem, current: isActive(currentPath, dashboardItem.href), renderLink: renderLink }) }) })), navSections.map((section) => (_jsxs("li", { children: [_jsx("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-white/50 dark:text-sidebar-foreground/50 mb-2", children: section.label }), _jsx("ul", { role: "list", className: "-mx-2 space-y-1.5", children: section.items.map((item) => isSidebarNavExpandable(item) ? (_jsx(ExpandableNavItem, { name: item.title, icon: item.icon, children: item.children, currentPath: currentPath, renderLink: renderLink }, item.title)) : (_jsx(NavLeafItem, { item: item, current: isActive(currentPath, item.href), renderLink: renderLink }, item.href))) })] }, section.label))), _jsxs("li", { className: "-mx-6 mt-auto", children: [extraFooterContent && (_jsx("div", { className: "px-6 pb-3", children: extraFooterContent })), _jsxs("div", { className: "flex items-center gap-x-4 px-6 py-3", children: [renderLink({
|
|
28
|
+
href: user?.profileHref ?? "/profile",
|
|
29
|
+
className: "flex flex-1 items-center gap-x-4 text-sm/6 font-semibold text-primary-foreground hover:opacity-80 truncate min-w-0",
|
|
30
|
+
children: (_jsxs(_Fragment, { children: [_jsx("span", { className: "inline-grid size-8 shrink-0 select-none place-items-center rounded-full bg-primary/80 text-xs font-semibold text-white outline -outline-offset-1 outline-white/10 dark:bg-white/5", "aria-hidden": "true", children: user?.avatarUrl ? (_jsx("img", { src: user.avatarUrl, alt: user.name, className: "size-full rounded-full object-cover" })) : (initials) }), _jsx("span", { className: "font-display truncate", children: user?.name ?? labels.user ?? "User" })] })),
|
|
31
|
+
}), _jsxs("div", { className: "flex items-center gap-x-2", children: [_jsx("button", { type: "button", onClick: onToggleTheme, "aria-label": isDark
|
|
32
|
+
? (labels.switchToLight ?? "Switch to light theme")
|
|
33
|
+
: (labels.switchToDark ?? "Switch to dark theme"), className: "inline-flex size-9 items-center justify-center rounded-full border border-white/15 bg-white/5 text-white/80 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white/20 dark:border-white/10 dark:bg-white/5 dark:text-zinc-200 dark:hover:bg-white/10 dark:hover:text-zinc-50", children: _jsx(ThemeIcon, { className: "size-4.5", "aria-hidden": "true" }) }), notificationSlot] })] }), languageSwitcherSlot && (_jsx("div", { className: "flex items-center justify-between px-6 pb-3", children: languageSwitcherSlot })), _jsx("div", { className: "px-6 pb-4", children: _jsx("button", { type: "button", onClick: onSignOut, className: "w-full rounded-md border border-white/20 px-3 py-2 text-sm font-semibold text-white/80 hover:bg-white/5 hover:text-white dark:border-white/10 dark:text-zinc-200 dark:hover:bg-white/5 dark:hover:text-zinc-50", children: labels.signOut ?? "Sign out" }) })] })] }) })] }));
|
|
34
|
+
}
|
|
35
|
+
function NavLeafItem({ item, current, renderLink, }) {
|
|
36
|
+
return (_jsx("li", { children: renderLink({
|
|
37
|
+
href: item.href,
|
|
38
|
+
className: cn("group relative flex min-h-11 items-center gap-x-3 rounded-md px-3 py-2 text-sm/6 transition-colors ring-1 ring-transparent", current
|
|
39
|
+
? "bg-white/10 text-white font-semibold before:absolute before:left-1.5 before:top-1/2 before:h-5 before:w-0.5 before:-translate-y-1/2 before:rounded-full before:bg-white/85 dark:bg-white/6 dark:text-zinc-50 dark:ring-1 dark:ring-white/10 dark:before:bg-primary/80"
|
|
40
|
+
: "text-white/80 font-medium hover:bg-white/6 hover:text-white dark:text-zinc-300 dark:hover:bg-white/5 dark:hover:text-zinc-100"),
|
|
41
|
+
children: (_jsxs(_Fragment, { children: [_jsx(item.icon, { "aria-hidden": "true", className: cn("size-6 shrink-0 transition-opacity", current ? "opacity-100" : "opacity-80 group-hover:opacity-100") }), _jsx("span", { className: cn("font-display truncate", current ? "tracking-[0.01em]" : ""), children: item.title }), item.badgeCount != null && item.badgeCount > 0 ? (_jsx("span", { "aria-hidden": "true", className: cn("ml-auto w-9 min-w-max rounded-full px-2.5 py-0.5 text-center text-xs/5 font-medium whitespace-nowrap outline-1 -outline-offset-1", current
|
|
42
|
+
? "bg-white/12 text-white outline-white/15 dark:bg-white/8 dark:text-zinc-100 dark:outline-white/10"
|
|
43
|
+
: "bg-white/8 text-white/80 outline-white/10 dark:bg-white/5 dark:text-zinc-300 dark:outline-white/5"), children: item.badgeCount > 99 ? "99+" : item.badgeCount })) : null] })),
|
|
44
|
+
}) }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=app-sidebar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-sidebar.js","sourceRoot":"","sources":["../../src/nav/app-sidebar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SidebarNavSubItem, IconType, RenderLinkFn } from "./types";
|
|
2
|
+
interface ExpandableNavItemProps {
|
|
3
|
+
name: string;
|
|
4
|
+
icon: IconType;
|
|
5
|
+
children: SidebarNavSubItem[];
|
|
6
|
+
currentPath: string;
|
|
7
|
+
renderLink: RenderLinkFn;
|
|
8
|
+
}
|
|
9
|
+
export declare function ExpandableNavItem({ name, icon: Icon, children, currentPath, renderLink, }: ExpandableNavItemProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=expandable-nav-item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expandable-nav-item.d.ts","sourceRoot":"","sources":["../../src/nav/expandable-nav-item.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzE,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,YAAY,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EACR,WAAW,EACX,UAAU,GACX,EAAE,sBAAsB,2CAuExB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
export function ExpandableNavItem({ name, icon: Icon, children, currentPath, renderLink, }) {
|
|
6
|
+
const isChildActive = children.some((child) => child.href === "/" ? currentPath === "/" : currentPath.startsWith(child.href));
|
|
7
|
+
const [open, setOpen] = useState(isChildActive);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (isChildActive)
|
|
10
|
+
setOpen(true);
|
|
11
|
+
}, [isChildActive]);
|
|
12
|
+
return (_jsxs("li", { children: [_jsxs("button", { type: "button", onClick: () => setOpen((prev) => !prev), className: cn("group relative flex w-full min-h-11 items-center gap-x-3 rounded-md px-3 py-2 text-sm/6 transition-colors ring-1 ring-transparent", isChildActive
|
|
13
|
+
? "text-white font-semibold"
|
|
14
|
+
: "text-white/80 font-medium hover:bg-white/6 hover:text-white dark:text-zinc-300 dark:hover:bg-white/5 dark:hover:text-zinc-100"), children: [_jsx(Icon, { "aria-hidden": "true", className: cn("size-6 shrink-0 transition-opacity", isChildActive ? "opacity-100" : "opacity-80 group-hover:opacity-100") }), _jsx("span", { className: cn("font-display truncate", isChildActive ? "tracking-[0.01em]" : ""), children: name }), open ? (_jsx(ChevronUp, { "aria-hidden": "true", className: "ml-auto size-4 shrink-0 opacity-60 group-hover:opacity-80" })) : (_jsx(ChevronDown, { "aria-hidden": "true", className: "ml-auto size-4 shrink-0 opacity-60 group-hover:opacity-80" }))] }), open && (_jsx("ul", { role: "list", className: "mt-1 space-y-1", children: children.map((child, index) => {
|
|
15
|
+
const current = index === 0
|
|
16
|
+
? currentPath === child.href
|
|
17
|
+
: currentPath === child.href || currentPath.startsWith(child.href + "/");
|
|
18
|
+
return (_jsx("li", { children: renderLink({
|
|
19
|
+
href: child.href,
|
|
20
|
+
className: cn("group relative flex min-h-9 items-center gap-x-3 rounded-md pl-12 pr-3 py-1.5 text-sm/6 transition-colors ring-1 ring-transparent", current
|
|
21
|
+
? "bg-white/10 text-white font-semibold before:absolute before:left-1.5 before:top-1/2 before:h-5 before:w-0.5 before:-translate-y-1/2 before:rounded-full before:bg-white/85 dark:bg-white/6 dark:text-zinc-50 dark:ring-1 dark:ring-white/10 dark:before:bg-primary/80"
|
|
22
|
+
: "text-white/80 font-medium hover:bg-white/6 hover:text-white dark:text-zinc-300 dark:hover:bg-white/5 dark:hover:text-zinc-100"),
|
|
23
|
+
children: (_jsx("span", { className: cn("font-display truncate", current ? "tracking-[0.01em]" : ""), children: child.title })),
|
|
24
|
+
}) }, child.href));
|
|
25
|
+
}) }))] }));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=expandable-nav-item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expandable-nav-item.js","sourceRoot":"","sources":["../../src/nav/expandable-nav-item.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAWlC,MAAM,UAAU,iBAAiB,CAAC,EAChC,IAAI,EACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EACR,WAAW,EACX,UAAU,GACa;IACvB,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC5C,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAC9E,CAAC;IAEF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,aAAa;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,OAAO,CACL,yBACE,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EACvC,SAAS,EAAE,EAAE,CACX,mIAAmI,EACnI,aAAa;oBACX,CAAC,CAAC,0BAA0B;oBAC5B,CAAC,CAAC,+HAA+H,CACpI,aAED,KAAC,IAAI,mBACS,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,oCAAoC,EACpC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,oCAAoC,CACrE,GACD,EACF,eAAM,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,aAAa,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,YACnF,IAAI,GACA,EACN,IAAI,CAAC,CAAC,CAAC,CACN,KAAC,SAAS,mBAAa,MAAM,EAAC,SAAS,EAAC,2DAA2D,GAAG,CACvG,CAAC,CAAC,CAAC,CACF,KAAC,WAAW,mBAAa,MAAM,EAAC,SAAS,EAAC,2DAA2D,GAAG,CACzG,IACM,EAER,IAAI,IAAI,CACP,aAAI,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,gBAAgB,YACvC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;oBAC7B,MAAM,OAAO,GACX,KAAK,KAAK,CAAC;wBACT,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,IAAI;wBAC5B,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;oBAE7E,OAAO,CACL,uBACG,UAAU,CAAC;4BACV,IAAI,EAAE,KAAK,CAAC,IAAI;4BAChB,SAAS,EAAE,EAAE,CACX,mIAAmI,EACnI,OAAO;gCACL,CAAC,CAAC,uQAAuQ;gCACzQ,CAAC,CAAC,+HAA+H,CACpI;4BACD,QAAQ,EAAE,CACR,eAAM,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,YAC7E,KAAK,CAAC,KAAK,GACP,CACR;yBACF,CAAC,IAdK,KAAK,CAAC,IAAI,CAed,CACN,CAAC;gBACJ,CAAC,CAAC,GACC,CACN,IACE,CACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AppSidebar } from "./app-sidebar";
|
|
2
|
+
export { AppShell } from "./app-shell";
|
|
3
|
+
export { ExpandableNavItem } from "./expandable-nav-item";
|
|
4
|
+
export type { IconType, RenderLinkFn, SidebarNavLeafItem, SidebarNavExpandableItem, SidebarNavSectionItem, SidebarNavSection, SidebarNavSubItem, SidebarUser, } from "./types";
|
|
5
|
+
export { isSidebarNavExpandable } from "./types";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nav/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nav/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAW1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
export type IconType = React.ComponentType<{
|
|
3
|
+
className?: string;
|
|
4
|
+
"aria-hidden"?: boolean | "true" | "false";
|
|
5
|
+
}>;
|
|
6
|
+
export type RenderLinkFn = (props: {
|
|
7
|
+
href: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}) => React.ReactElement;
|
|
11
|
+
export interface SidebarNavSubItem {
|
|
12
|
+
title: string;
|
|
13
|
+
href: string;
|
|
14
|
+
}
|
|
15
|
+
export interface SidebarNavLeafItem {
|
|
16
|
+
title: string;
|
|
17
|
+
href: string;
|
|
18
|
+
icon: IconType;
|
|
19
|
+
badgeCount?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SidebarNavExpandableItem {
|
|
22
|
+
title: string;
|
|
23
|
+
icon: IconType;
|
|
24
|
+
expandable: true;
|
|
25
|
+
children: SidebarNavSubItem[];
|
|
26
|
+
}
|
|
27
|
+
export type SidebarNavSectionItem = SidebarNavLeafItem | SidebarNavExpandableItem;
|
|
28
|
+
export interface SidebarNavSection {
|
|
29
|
+
label: string;
|
|
30
|
+
items: SidebarNavSectionItem[];
|
|
31
|
+
}
|
|
32
|
+
export interface SidebarUser {
|
|
33
|
+
name: string;
|
|
34
|
+
email?: string;
|
|
35
|
+
initials?: string;
|
|
36
|
+
avatarUrl?: string;
|
|
37
|
+
profileHref: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function isSidebarNavExpandable(item: SidebarNavSectionItem): item is SidebarNavExpandableItem;
|
|
40
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/nav/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;CAC5C,CAAC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,KAAK,KAAK,CAAC,YAAY,CAAC;AAEzB,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,GAAG,wBAAwB,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,qBAAqB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,qBAAqB,GAC1B,IAAI,IAAI,wBAAwB,CAElC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/nav/types.ts"],"names":[],"mappings":"AA+CA,MAAM,UAAU,sBAAsB,CACpC,IAA2B;IAE3B,OAAO,YAAY,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC;AAC1D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cellarnode/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Shared UI components, theme tokens, and chat/offer primitives for CellarNode dashboards.",
|
|
@@ -46,6 +46,10 @@
|
|
|
46
46
|
"./animated-list": {
|
|
47
47
|
"types": "./dist/components/animated-list.d.ts",
|
|
48
48
|
"default": "./dist/components/animated-list.js"
|
|
49
|
+
},
|
|
50
|
+
"./nav": {
|
|
51
|
+
"types": "./dist/nav/index.d.ts",
|
|
52
|
+
"default": "./dist/nav/index.js"
|
|
49
53
|
}
|
|
50
54
|
},
|
|
51
55
|
"files": [
|
|
@@ -61,10 +65,10 @@
|
|
|
61
65
|
"build-storybook": "storybook build"
|
|
62
66
|
},
|
|
63
67
|
"peerDependencies": {
|
|
68
|
+
"@cellarnode/beverage-utils": ">=0.3.0",
|
|
64
69
|
"@dnd-kit/dom": "^0.3.2",
|
|
65
70
|
"@dnd-kit/react": "^0.3.2",
|
|
66
71
|
"@tanstack/react-query": "^5.0.0",
|
|
67
|
-
"@cellarnode/beverage-utils": ">=0.3.0",
|
|
68
72
|
"i18n-iso-countries": ">=7.0.0",
|
|
69
73
|
"motion": "^12.0.0",
|
|
70
74
|
"react": "^19.0.0",
|
|
@@ -139,6 +143,8 @@
|
|
|
139
143
|
"devDependencies": {
|
|
140
144
|
"@dnd-kit/dom": "^0.3.2",
|
|
141
145
|
"@dnd-kit/react": "^0.3.2",
|
|
146
|
+
"@eslint-react/eslint-plugin": "^3.0.0",
|
|
147
|
+
"@eslint/js": "^10.0.1",
|
|
142
148
|
"@storybook/addon-a11y": "^10.3.3",
|
|
143
149
|
"@storybook/addon-docs": "^10.3.3",
|
|
144
150
|
"@storybook/addon-mcp": "^0.4.2",
|
|
@@ -155,6 +161,8 @@
|
|
|
155
161
|
"@types/topojson-specification": "^1.0.5",
|
|
156
162
|
"@vitest/browser-playwright": "^4.1.2",
|
|
157
163
|
"@vitest/coverage-v8": "^4.1.2",
|
|
164
|
+
"eslint": "^10.1.0",
|
|
165
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
158
166
|
"i18n-iso-countries": "^7.14.0",
|
|
159
167
|
"motion": "^12.38.0",
|
|
160
168
|
"playwright": "^1.58.2",
|
|
@@ -164,6 +172,7 @@
|
|
|
164
172
|
"three": "^0.182.0",
|
|
165
173
|
"topojson-client": "^3.1.0",
|
|
166
174
|
"typescript": "^5.9.3",
|
|
175
|
+
"typescript-eslint": "^8.57.2",
|
|
167
176
|
"vitest": "^4.1.2",
|
|
168
177
|
"world-atlas": "^2.0.2"
|
|
169
178
|
}
|