@av-pi-studio/ui-library 0.0.0-stage → 0.0.115
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/CHANGELOG.md +24 -0
- package/README.md +137 -2
- package/dist/brand/config.d.ts +125 -0
- package/dist/brand/index.d.ts +3 -0
- package/dist/brand/index.js +6 -0
- package/dist/brand/theme-injection.d.ts +9 -0
- package/dist/breakpoints.d.ts +34 -0
- package/dist/breakpoints.js +32 -0
- package/dist/chunks/theme-injection-BHAAhBYz.js +103 -0
- package/dist/chunks/token-guard-B85Ysv3w.js +813 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1049 -0
- package/dist/kv-store.d.ts +3 -0
- package/dist/primitives/Announcer.d.ts +13 -0
- package/dist/primitives/Avatar.d.ts +15 -0
- package/dist/primitives/Button.d.ts +18 -0
- package/dist/primitives/Checkbox.d.ts +11 -0
- package/dist/primitives/Dialog.d.ts +58 -0
- package/dist/primitives/Divider.d.ts +10 -0
- package/dist/primitives/EmptyState.d.ts +11 -0
- package/dist/primitives/Icon.d.ts +20 -0
- package/dist/primitives/IconButton.d.ts +25 -0
- package/dist/primitives/Menu.d.ts +50 -0
- package/dist/primitives/Panel.d.ts +9 -0
- package/dist/primitives/Popover.d.ts +25 -0
- package/dist/primitives/ResizeHandle.d.ts +20 -0
- package/dist/primitives/ScreenTitle.d.ts +15 -0
- package/dist/primitives/ScrollArea.d.ts +11 -0
- package/dist/primitives/Select.d.ts +25 -0
- package/dist/primitives/Shortcut.d.ts +15 -0
- package/dist/primitives/Spinner.d.ts +14 -0
- package/dist/primitives/StatusBadge.d.ts +13 -0
- package/dist/primitives/StatusDot.d.ts +17 -0
- package/dist/primitives/Surface.d.ts +13 -0
- package/dist/primitives/Switch.d.ts +14 -0
- package/dist/primitives/TextInput.d.ts +14 -0
- package/dist/primitives/ToastViewport.d.ts +17 -0
- package/dist/primitives/helpers.d.ts +47 -0
- package/dist/primitives/index.d.ts +24 -0
- package/dist/primitives/useHover.d.ts +16 -0
- package/dist/reset.css +43 -0
- package/dist/stores/announcer-store.d.ts +37 -0
- package/dist/stores/toast-store.d.ts +37 -0
- package/dist/styles.css +1 -0
- package/dist/theme/ThemeBoundary.d.ts +38 -0
- package/dist/theme/appearance-store.d.ts +37 -0
- package/dist/theme/color-utils.d.ts +13 -0
- package/dist/theme/colors.d.ts +111 -0
- package/dist/theme/css-bridge.d.ts +21 -0
- package/dist/theme/dev-warnings.d.ts +23 -0
- package/dist/theme/index.d.ts +10 -0
- package/dist/theme/index.js +39 -0
- package/dist/theme/palette.d.ts +19 -0
- package/dist/theme/theme.d.ts +47 -0
- package/dist/theme/token-guard.d.ts +20 -0
- package/dist/theme/tokens.d.ts +105 -0
- package/dist/theme/variants.d.ts +12 -0
- package/dist/ui/avatar.d.ts +11 -0
- package/dist/ui/button.d.ts +34 -0
- package/dist/ui/combobox.d.ts +55 -0
- package/dist/ui/index.d.ts +10 -0
- package/dist/ui/index.js +406 -0
- package/dist/ui/option-groups.d.ts +36 -0
- package/dist/ui/screen-header.d.ts +23 -0
- package/dist/ui/shortcut.d.ts +13 -0
- package/dist/ui/status-badge.d.ts +15 -0
- package/dist/ui/status-dot.d.ts +20 -0
- package/dist/ui/toast.d.ts +60 -0
- package/package.json +68 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Breaking changes get a dated entry here. Versions move in lockstep with the other
|
|
4
|
+
`@av-pi-studio/*` packages (0.0.x).
|
|
5
|
+
|
|
6
|
+
## 2026-11-14 — 0.0.115 (initial release)
|
|
7
|
+
|
|
8
|
+
Extracted from `@av-pi-studio/web-client`.
|
|
9
|
+
|
|
10
|
+
### Public surface
|
|
11
|
+
|
|
12
|
+
- `@av-pi-studio/ui-library` — components (`Button`, `IconButton`, `Dialog`, `Menu*`, `Popover*`,
|
|
13
|
+
`Panel`, `Select`, `Switch`, `Checkbox`, `TextInput`, `TextArea`, `Icon`, `Spinner`, `StatusDot`,
|
|
14
|
+
`StatusBadge`, `Avatar`, `EmptyState`, …), `ThemeBoundary` (`store`, `storageKey` default
|
|
15
|
+
`pi-studio-appearance`, `brandConfig`), `useAppearance`, `ToastViewport`, `Announcer`,
|
|
16
|
+
`useToastStore`, `speak`, `localStorageKvStore`.
|
|
17
|
+
- `/theme` (incl. `findTokenProblems`), `/ui`, `/brand`, `/breakpoints` subpath entries.
|
|
18
|
+
- CSS entries: `/styles.css` (tokens + component styles, `piui-` class prefix) and `/reset.css`.
|
|
19
|
+
Import library CSS before your own.
|
|
20
|
+
- Peer dependencies: `react`, `react-dom` ^19. Targets Vite web SPAs and Electron renderers
|
|
21
|
+
(no SSR, no React Native). Dev-only console warnings rely on the consumer's bundler folding
|
|
22
|
+
`process.env.NODE_ENV`.
|
|
23
|
+
- One `ThemeBoundary` per document; one copy of the library per app (toast/announcer stores are
|
|
24
|
+
module singletons).
|
package/README.md
CHANGED
|
@@ -1,3 +1,138 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @av-pi-studio/ui-library
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reusable React UI primitives, theme system and global styles for Pi-Studio client apps.
|
|
4
|
+
Targets Vite web SPAs and Electron renderers. No SSR, no React Native.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
npm i @av-pi-studio/ui-library react react-dom
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Peer dependencies: `react` and `react-dom` `^19`. Radix (dialog, dropdown-menu, popover),
|
|
13
|
+
`lucide-react`, `clsx`, `zustand` and `zod` are regular dependencies.
|
|
14
|
+
|
|
15
|
+
## Quickstart
|
|
16
|
+
|
|
17
|
+
Import the library CSS **before your own CSS**. Library class names carry the `piui-` prefix and
|
|
18
|
+
design tokens are `--pi-*` CSS variables. `styles.css` is required; `reset.css` is an optional
|
|
19
|
+
global reset.
|
|
20
|
+
|
|
21
|
+
<!-- smoke:main.tsx -->
|
|
22
|
+
```tsx
|
|
23
|
+
import "@av-pi-studio/ui-library/reset.css";
|
|
24
|
+
import "@av-pi-studio/ui-library/styles.css";
|
|
25
|
+
|
|
26
|
+
import { StrictMode } from "react";
|
|
27
|
+
import { createRoot } from "react-dom/client";
|
|
28
|
+
import {
|
|
29
|
+
Announcer,
|
|
30
|
+
Button,
|
|
31
|
+
Switch,
|
|
32
|
+
ThemeBoundary,
|
|
33
|
+
ToastViewport,
|
|
34
|
+
useToastStore,
|
|
35
|
+
} from "@av-pi-studio/ui-library";
|
|
36
|
+
|
|
37
|
+
function App() {
|
|
38
|
+
const show = useToastStore((s) => s.show);
|
|
39
|
+
return (
|
|
40
|
+
<main style={{ padding: 16, display: "grid", gap: 12, justifyItems: "start" }}>
|
|
41
|
+
<Button id="smoke-button" onClick={() => show("Hello from ui-library")}>
|
|
42
|
+
Show toast
|
|
43
|
+
</Button>
|
|
44
|
+
<Switch checked onCheckedChange={() => {}} aria-label="Example switch" />
|
|
45
|
+
</main>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
createRoot(document.getElementById("root")!).render(
|
|
50
|
+
<StrictMode>
|
|
51
|
+
<ThemeBoundary>
|
|
52
|
+
<App />
|
|
53
|
+
<ToastViewport />
|
|
54
|
+
<Announcer />
|
|
55
|
+
</ThemeBoundary>
|
|
56
|
+
</StrictMode>,
|
|
57
|
+
);
|
|
58
|
+
```
|
|
59
|
+
<!-- /smoke:main.tsx -->
|
|
60
|
+
|
|
61
|
+
- `ThemeBoundary` applies the theme (light/dark/system) to the document and provides
|
|
62
|
+
`useAppearance()`. Props (all optional):
|
|
63
|
+
- `storageKey` — key the appearance JSON is stored under (default `pi-studio-appearance`).
|
|
64
|
+
- `store` — a custom key-value store instead of `localStorage` (see `localStorageKvStore`).
|
|
65
|
+
- `brandConfig` — e.g. `{ colors: { accent: "#7c3aed" } }` to re-theme the accent.
|
|
66
|
+
- `ToastViewport` and `Announcer` are **not** mounted automatically; mount them once, inside
|
|
67
|
+
`ThemeBoundary`. Fire toasts with `useToastStore.getState().show("text")` (also `copied`,
|
|
68
|
+
`error`) and screen-reader announcements with `speak()`.
|
|
69
|
+
|
|
70
|
+
### Switching the theme
|
|
71
|
+
|
|
72
|
+
`useAppearanceControls()` (root entry, under `ThemeBoundary`) returns `{ setMode, updateSettings }`;
|
|
73
|
+
changes are applied to the document and persisted. `useAppearance()` reads the current state.
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { Button, THEME_NAMES, useAppearance, useAppearanceControls } from "@av-pi-studio/ui-library";
|
|
77
|
+
|
|
78
|
+
function ThemeSwitcher() {
|
|
79
|
+
const { mode } = useAppearance();
|
|
80
|
+
const { setMode } = useAppearanceControls();
|
|
81
|
+
return (
|
|
82
|
+
<>
|
|
83
|
+
{(["system", ...THEME_NAMES] as const).map((name) => (
|
|
84
|
+
<Button key={name} variant={name === mode ? "default" : "outline"} onClick={() => setMode(name)}>
|
|
85
|
+
{name}
|
|
86
|
+
</Button>
|
|
87
|
+
))}
|
|
88
|
+
</>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Components
|
|
94
|
+
|
|
95
|
+
`Button`, `IconButton`, `Dialog`, `Menu*`, `Popover*`, `Panel`, `Surface`, `Select`, `Combobox`,
|
|
96
|
+
`Switch`, `Checkbox`, `TextInput`, `TextArea`, `Icon`, `Spinner`, `StatusDot`, `StatusBadge`,
|
|
97
|
+
`Avatar`, `EmptyState`, `ScrollArea`, `Divider`, `ResizeHandle`, `ShortcutHint`. Types ship
|
|
98
|
+
alongside (`ButtonProps`, ...).
|
|
99
|
+
|
|
100
|
+
`Menu*` is half of a menu: `MenuContent`, `MenuItem`, `MenuGroup`, `MenuSeparator` and
|
|
101
|
+
`MenuCursorTrigger` ship, but `Root`/`Trigger` do not — install `@radix-ui/react-dropdown-menu`
|
|
102
|
+
yourself and import `DropdownMenu.Root`/`.Trigger` from it.
|
|
103
|
+
|
|
104
|
+
## Entry points
|
|
105
|
+
|
|
106
|
+
Only these resolve (the `exports` map); deep imports such as `.../src/...` or `.../dist/...` are
|
|
107
|
+
rejected.
|
|
108
|
+
|
|
109
|
+
| Specifier | Contents |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `@av-pi-studio/ui-library` | Everything: components, `ThemeBoundary`, hooks, stores, and the subpaths below |
|
|
112
|
+
| `.../theme` | Theme/appearance logic and token helpers (`findTokenProblems`), React-free |
|
|
113
|
+
| `.../ui` | Pure UI logic (button/toast helpers), React-free |
|
|
114
|
+
| `.../brand` | `BrandConfig` schema and accent derivation, React-free |
|
|
115
|
+
| `.../breakpoints` | Breakpoint constants, React-free |
|
|
116
|
+
| `.../styles.css` | Required global styles and `--pi-*` tokens |
|
|
117
|
+
| `.../reset.css` | Optional global reset |
|
|
118
|
+
|
|
119
|
+
## Constraints
|
|
120
|
+
|
|
121
|
+
- One `ThemeBoundary` per document.
|
|
122
|
+
- One copy of the package per app: the toast and announcer stores are module singletons.
|
|
123
|
+
- React `^19`.
|
|
124
|
+
- A bundler (Vite, etc.) is required: dev-only warnings read `process.env.NODE_ENV`, which the
|
|
125
|
+
bundler folds. Loading the ESM unbundled would throw `ReferenceError: process` in dev.
|
|
126
|
+
- No SSR, no React Native.
|
|
127
|
+
|
|
128
|
+
## Dev-only warnings
|
|
129
|
+
|
|
130
|
+
In development builds the library logs a console warning when `styles.css` is not loaded, when a
|
|
131
|
+
second `ThemeBoundary` mounts, or when `brandConfig` is invalid. They are stripped from
|
|
132
|
+
production bundles.
|
|
133
|
+
|
|
134
|
+
## Verifying a release
|
|
135
|
+
|
|
136
|
+
`bash packages/ui-library/scripts/pack-smoke.sh` packs the library, installs the tarball into a
|
|
137
|
+
scratch Vite app outside the repo using the Quickstart snippet above, and checks types, build,
|
|
138
|
+
`exports` and CSS. `KEEP_DIR=1` keeps the scratch dir.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const BrandConfigSchema: z.ZodObject<{
|
|
3
|
+
productName: z.ZodOptional<z.ZodString>;
|
|
4
|
+
shortName: z.ZodOptional<z.ZodString>;
|
|
5
|
+
tagline: z.ZodOptional<z.ZodString>;
|
|
6
|
+
colors: z.ZodObject<{
|
|
7
|
+
accent: z.ZodEffects<z.ZodString, string, string>;
|
|
8
|
+
accentBright: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
9
|
+
accentForeground: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
10
|
+
swatch: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
accent: string;
|
|
13
|
+
accentBright?: string | undefined;
|
|
14
|
+
accentForeground?: string | undefined;
|
|
15
|
+
swatch?: string | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
accent: string;
|
|
18
|
+
accentBright?: string | undefined;
|
|
19
|
+
accentForeground?: string | undefined;
|
|
20
|
+
swatch?: string | undefined;
|
|
21
|
+
}>;
|
|
22
|
+
assets: z.ZodOptional<z.ZodObject<{
|
|
23
|
+
logoLight: z.ZodString;
|
|
24
|
+
logoDark: z.ZodString;
|
|
25
|
+
logoMark: z.ZodOptional<z.ZodString>;
|
|
26
|
+
icon: z.ZodString;
|
|
27
|
+
splash: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
logoLight: string;
|
|
30
|
+
logoDark: string;
|
|
31
|
+
logoMark?: string | undefined;
|
|
32
|
+
icon: string;
|
|
33
|
+
splash?: string | undefined;
|
|
34
|
+
}, {
|
|
35
|
+
logoLight: string;
|
|
36
|
+
logoDark: string;
|
|
37
|
+
logoMark?: string | undefined;
|
|
38
|
+
icon: string;
|
|
39
|
+
splash?: string | undefined;
|
|
40
|
+
}>>;
|
|
41
|
+
links: z.ZodOptional<z.ZodObject<{
|
|
42
|
+
docs: z.ZodOptional<z.ZodString>;
|
|
43
|
+
support: z.ZodOptional<z.ZodString>;
|
|
44
|
+
issues: z.ZodOptional<z.ZodString>;
|
|
45
|
+
website: z.ZodOptional<z.ZodString>;
|
|
46
|
+
}, "strip", z.ZodTypeAny, {
|
|
47
|
+
docs?: string | undefined;
|
|
48
|
+
support?: string | undefined;
|
|
49
|
+
issues?: string | undefined;
|
|
50
|
+
website?: string | undefined;
|
|
51
|
+
}, {
|
|
52
|
+
docs?: string | undefined;
|
|
53
|
+
support?: string | undefined;
|
|
54
|
+
issues?: string | undefined;
|
|
55
|
+
website?: string | undefined;
|
|
56
|
+
}>>;
|
|
57
|
+
legal: z.ZodOptional<z.ZodObject<{
|
|
58
|
+
copyright: z.ZodOptional<z.ZodString>;
|
|
59
|
+
companyName: z.ZodOptional<z.ZodString>;
|
|
60
|
+
}, "strip", z.ZodTypeAny, {
|
|
61
|
+
copyright?: string | undefined;
|
|
62
|
+
companyName?: string | undefined;
|
|
63
|
+
}, {
|
|
64
|
+
copyright?: string | undefined;
|
|
65
|
+
companyName?: string | undefined;
|
|
66
|
+
}>>;
|
|
67
|
+
}, "strip", z.ZodTypeAny, {
|
|
68
|
+
productName?: string | undefined;
|
|
69
|
+
shortName?: string | undefined;
|
|
70
|
+
tagline?: string | undefined;
|
|
71
|
+
colors: {
|
|
72
|
+
accent: string;
|
|
73
|
+
accentBright?: string | undefined;
|
|
74
|
+
accentForeground?: string | undefined;
|
|
75
|
+
swatch?: string | undefined;
|
|
76
|
+
};
|
|
77
|
+
assets?: {
|
|
78
|
+
logoLight: string;
|
|
79
|
+
logoDark: string;
|
|
80
|
+
logoMark?: string | undefined;
|
|
81
|
+
icon: string;
|
|
82
|
+
splash?: string | undefined;
|
|
83
|
+
} | undefined;
|
|
84
|
+
links?: {
|
|
85
|
+
docs?: string | undefined;
|
|
86
|
+
support?: string | undefined;
|
|
87
|
+
issues?: string | undefined;
|
|
88
|
+
website?: string | undefined;
|
|
89
|
+
} | undefined;
|
|
90
|
+
legal?: {
|
|
91
|
+
copyright?: string | undefined;
|
|
92
|
+
companyName?: string | undefined;
|
|
93
|
+
} | undefined;
|
|
94
|
+
}, {
|
|
95
|
+
productName?: string | undefined;
|
|
96
|
+
shortName?: string | undefined;
|
|
97
|
+
tagline?: string | undefined;
|
|
98
|
+
colors: {
|
|
99
|
+
accent: string;
|
|
100
|
+
accentBright?: string | undefined;
|
|
101
|
+
accentForeground?: string | undefined;
|
|
102
|
+
swatch?: string | undefined;
|
|
103
|
+
};
|
|
104
|
+
assets?: {
|
|
105
|
+
logoLight: string;
|
|
106
|
+
logoDark: string;
|
|
107
|
+
logoMark?: string | undefined;
|
|
108
|
+
icon: string;
|
|
109
|
+
splash?: string | undefined;
|
|
110
|
+
} | undefined;
|
|
111
|
+
links?: {
|
|
112
|
+
docs?: string | undefined;
|
|
113
|
+
support?: string | undefined;
|
|
114
|
+
issues?: string | undefined;
|
|
115
|
+
website?: string | undefined;
|
|
116
|
+
} | undefined;
|
|
117
|
+
legal?: {
|
|
118
|
+
copyright?: string | undefined;
|
|
119
|
+
companyName?: string | undefined;
|
|
120
|
+
} | undefined;
|
|
121
|
+
}>;
|
|
122
|
+
export type BrandConfig = z.infer<typeof BrandConfigSchema>;
|
|
123
|
+
export type ResolvedBrandColors = Required<Pick<BrandConfig["colors"], "accent" | "accentBright" | "accentForeground" | "swatch">>;
|
|
124
|
+
export declare function resolveAccentColors(colors: BrandConfig["colors"]): ResolvedBrandColors;
|
|
125
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ResolvedBrandColors } from "./config.js";
|
|
2
|
+
import { type Theme } from "../theme/theme.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a branded copy of a theme by replacing only the accent family tokens
|
|
5
|
+
* and swatch. All other tokens (surfaces, semantic status, syntax, terminal)
|
|
6
|
+
* remain unchanged — only the accent family is brand-overridable in this version.
|
|
7
|
+
*/
|
|
8
|
+
export declare function injectBrandAccent(theme: Theme, resolved: ResolvedBrandColors): Theme;
|
|
9
|
+
//# sourceMappingURL=theme-injection.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const breakpoints: {
|
|
2
|
+
readonly xs: 0;
|
|
3
|
+
readonly sm: 576;
|
|
4
|
+
readonly md: 768;
|
|
5
|
+
readonly lg: 992;
|
|
6
|
+
readonly xl: 1200;
|
|
7
|
+
};
|
|
8
|
+
export type Breakpoint = keyof typeof breakpoints;
|
|
9
|
+
/** Returns the active breakpoint name for a given container/window width. */
|
|
10
|
+
export declare function getBreakpoint(width: number): Breakpoint;
|
|
11
|
+
/**
|
|
12
|
+
* Compact form factor = xs or sm (phone-class layout).
|
|
13
|
+
* This is the single source of truth for "phone-class layout" —
|
|
14
|
+
* never use Platform.OS as a layout proxy.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isCompactFormFactor(width: number): boolean;
|
|
17
|
+
export declare const HEADER_INNER_HEIGHT = 48;
|
|
18
|
+
export declare const HEADER_INNER_HEIGHT_MOBILE = 56;
|
|
19
|
+
export declare const HEADER_TOP_PADDING_MOBILE = 8;
|
|
20
|
+
export declare const WORKSPACE_SECONDARY_HEADER_HEIGHT = 36;
|
|
21
|
+
export declare const FOOTER_HEIGHT = 75;
|
|
22
|
+
export declare const MAX_CONTENT_WIDTH = 820;
|
|
23
|
+
export declare const COMPACT_FORM_FACTOR_WIDTH = 500;
|
|
24
|
+
export declare const WINDOW_CHROME: {
|
|
25
|
+
readonly macOS: {
|
|
26
|
+
readonly width: 78;
|
|
27
|
+
readonly height: 45;
|
|
28
|
+
};
|
|
29
|
+
readonly windowsLinux: {
|
|
30
|
+
readonly width: 140;
|
|
31
|
+
readonly height: 48;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=breakpoints.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const n = {
|
|
2
|
+
xs: 0,
|
|
3
|
+
sm: 576,
|
|
4
|
+
md: 768,
|
|
5
|
+
lg: 992,
|
|
6
|
+
xl: 1200
|
|
7
|
+
};
|
|
8
|
+
function s(t) {
|
|
9
|
+
return t >= n.xl ? "xl" : t >= n.lg ? "lg" : t >= n.md ? "md" : t >= n.sm ? "sm" : "xs";
|
|
10
|
+
}
|
|
11
|
+
function o(t) {
|
|
12
|
+
const E = s(t);
|
|
13
|
+
return E === "xs" || E === "sm";
|
|
14
|
+
}
|
|
15
|
+
const _ = 48, r = 56, c = 8, H = 36, O = 75, e = 820, i = 500, I = {
|
|
16
|
+
macOS: { width: 78, height: 45 },
|
|
17
|
+
// traffic-light reserve
|
|
18
|
+
windowsLinux: { width: 140, height: 48 }
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
i as COMPACT_FORM_FACTOR_WIDTH,
|
|
22
|
+
O as FOOTER_HEIGHT,
|
|
23
|
+
_ as HEADER_INNER_HEIGHT,
|
|
24
|
+
r as HEADER_INNER_HEIGHT_MOBILE,
|
|
25
|
+
c as HEADER_TOP_PADDING_MOBILE,
|
|
26
|
+
e as MAX_CONTENT_WIDTH,
|
|
27
|
+
I as WINDOW_CHROME,
|
|
28
|
+
H as WORKSPACE_SECONDARY_HEADER_HEIGHT,
|
|
29
|
+
n as breakpoints,
|
|
30
|
+
s as getBreakpoint,
|
|
31
|
+
o as isCompactFormFactor
|
|
32
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z as o } from "zod";
|
|
2
|
+
function l(n) {
|
|
3
|
+
const t = n.trim().replace(/^#/, ""), a = t.length === 3 ? t.split("").map((r) => r + r).join("") : t;
|
|
4
|
+
if (a.length !== 6 || /[^0-9a-fA-F]/.test(a))
|
|
5
|
+
throw new Error(`Invalid hex color: ${n}`);
|
|
6
|
+
return {
|
|
7
|
+
r: parseInt(a.slice(0, 2), 16),
|
|
8
|
+
g: parseInt(a.slice(2, 4), 16),
|
|
9
|
+
b: parseInt(a.slice(4, 6), 16)
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function h(n) {
|
|
13
|
+
return Math.max(0, Math.min(255, Math.round(n)));
|
|
14
|
+
}
|
|
15
|
+
function u({ r: n, g: t, b: a }) {
|
|
16
|
+
const r = (c) => h(c).toString(16).padStart(2, "0");
|
|
17
|
+
return `#${r(n)}${r(t)}${r(a)}`;
|
|
18
|
+
}
|
|
19
|
+
function p(n) {
|
|
20
|
+
const { r: t, g: a, b: r } = l(n), c = (e) => {
|
|
21
|
+
const g = e / 255;
|
|
22
|
+
return g <= 0.03928 ? g / 12.92 : ((g + 0.055) / 1.055) ** 2.4;
|
|
23
|
+
};
|
|
24
|
+
return 0.2126 * c(t) + 0.7152 * c(a) + 0.0722 * c(r);
|
|
25
|
+
}
|
|
26
|
+
function m(n, t = "#18181b", a = "#ffffff") {
|
|
27
|
+
return p(n) > 0.45 ? t : a;
|
|
28
|
+
}
|
|
29
|
+
function b(n, t) {
|
|
30
|
+
const { r: a, g: r, b: c } = l(n), e = Math.max(0, Math.min(1, t));
|
|
31
|
+
return u({
|
|
32
|
+
r: a + (255 - a) * e,
|
|
33
|
+
g: r + (255 - r) * e,
|
|
34
|
+
b: c + (255 - c) * e
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function F(n, t) {
|
|
38
|
+
const { r: a, g: r, b: c } = l(n), e = Math.max(0, Math.min(1, t));
|
|
39
|
+
return u({ r: a * (1 - e), g: r * (1 - e), b: c * (1 - e) });
|
|
40
|
+
}
|
|
41
|
+
function i(n) {
|
|
42
|
+
const t = n.trim().replace(/^#/, "");
|
|
43
|
+
return (t.length === 3 || t.length === 6) && !/[^0-9a-fA-F]/.test(t);
|
|
44
|
+
}
|
|
45
|
+
const s = o.string().min(1, "Asset path must not be empty"), f = o.object({
|
|
46
|
+
accent: o.string().refine(i, { message: "accent must be a valid #rrggbb hex color" }),
|
|
47
|
+
accentBright: o.string().refine(i, { message: "accentBright must be a valid #rrggbb hex color" }).optional(),
|
|
48
|
+
accentForeground: o.string().refine(i, { message: "accentForeground must be a valid #rrggbb hex color" }).optional(),
|
|
49
|
+
swatch: o.string().refine(i, { message: "swatch must be a valid #rrggbb hex color" }).optional()
|
|
50
|
+
}), d = o.object({
|
|
51
|
+
logoLight: s,
|
|
52
|
+
logoDark: s,
|
|
53
|
+
logoMark: s.optional(),
|
|
54
|
+
icon: s,
|
|
55
|
+
splash: s.optional()
|
|
56
|
+
}), B = o.object({
|
|
57
|
+
docs: o.string().url().optional(),
|
|
58
|
+
support: o.string().url().optional(),
|
|
59
|
+
issues: o.string().url().optional(),
|
|
60
|
+
website: o.string().url().optional()
|
|
61
|
+
}).optional(), x = o.object({
|
|
62
|
+
copyright: o.string().optional(),
|
|
63
|
+
companyName: o.string().optional()
|
|
64
|
+
}).optional(), M = o.object({
|
|
65
|
+
productName: o.string().min(1, "productName must not be empty").optional(),
|
|
66
|
+
shortName: o.string().optional(),
|
|
67
|
+
tagline: o.string().optional(),
|
|
68
|
+
colors: f,
|
|
69
|
+
assets: d.optional(),
|
|
70
|
+
links: B,
|
|
71
|
+
legal: x
|
|
72
|
+
});
|
|
73
|
+
function S(n) {
|
|
74
|
+
const t = n.accent, a = n.accentBright ?? b(t, 0.35), r = n.accentForeground ?? m(t), c = n.swatch ?? t;
|
|
75
|
+
return { accent: t, accentBright: a, accentForeground: r, swatch: c };
|
|
76
|
+
}
|
|
77
|
+
function j(n, t) {
|
|
78
|
+
return {
|
|
79
|
+
...n,
|
|
80
|
+
colors: {
|
|
81
|
+
...n.colors,
|
|
82
|
+
accent: t.accent,
|
|
83
|
+
accentBright: t.accentBright,
|
|
84
|
+
accentForeground: t.accentForeground,
|
|
85
|
+
// Legacy aliases that mirror accent.
|
|
86
|
+
primary: t.accent,
|
|
87
|
+
ring: t.accent
|
|
88
|
+
},
|
|
89
|
+
swatch: t.swatch
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
M as B,
|
|
94
|
+
i as a,
|
|
95
|
+
p as b,
|
|
96
|
+
m as c,
|
|
97
|
+
F as d,
|
|
98
|
+
u as e,
|
|
99
|
+
l as h,
|
|
100
|
+
j as i,
|
|
101
|
+
b as l,
|
|
102
|
+
S as r
|
|
103
|
+
};
|