@ponti-studios/ui 0.1.2 → 0.4.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/LICENSE +21 -0
- package/README.md +7 -7
- package/THIRD_PARTY_NOTICES.md +17 -0
- package/dist/index.js +988 -640
- package/dist/index.js.map +1 -1
- package/package.json +41 -41
- package/src/animations.css +42 -383
- package/src/components/data-display/accordion.tsx +22 -10
- package/src/components/data-display/filter-chip.stories.tsx +38 -0
- package/src/components/data-display/filter-chip.tsx +10 -4
- package/src/components/data-display/index.ts +5 -0
- package/src/components/data-display/metric-card.stories.tsx +48 -0
- package/src/components/data-display/metric-card.tsx +20 -0
- package/src/components/data-display/sort-controls.stories.tsx +45 -0
- package/src/components/data-display/sort-controls.tsx +99 -0
- package/src/components/data-display/sort-row.tsx +74 -0
- package/src/components/data-display/table.tsx +5 -9
- package/src/components/feedback/alert.tsx +4 -4
- package/src/components/feedback/empty-state.tsx +16 -6
- package/src/components/feedback/file-upload-status-badge.stories.tsx +28 -0
- package/src/components/feedback/file-upload-status-badge.tsx +33 -0
- package/src/components/feedback/file-upload-status.stories.tsx +57 -0
- package/src/components/feedback/file-upload-status.tsx +152 -0
- package/src/components/feedback/index.ts +9 -0
- package/src/components/feedback/progress-bar.stories.tsx +39 -0
- package/src/components/feedback/progress-bar.tsx +21 -0
- package/src/components/feedback/progress.stories.tsx +8 -6
- package/src/components/feedback/progress.tsx +3 -3
- package/src/components/feedback/skeleton.stories.tsx +36 -0
- package/src/components/feedback/skeleton.tsx +7 -0
- package/src/components/feedback/spinner.tsx +2 -2
- package/src/components/feedback/update-guard.stories.tsx +32 -0
- package/src/components/feedback/update-guard.tsx +280 -0
- package/src/components/forms/calendar.tsx +14 -11
- package/src/components/forms/date-month-select.stories.tsx +26 -0
- package/src/components/forms/date-month-select.tsx +70 -0
- package/src/components/forms/date-picker.tsx +3 -3
- package/src/components/forms/drop-zone.stories.tsx +56 -0
- package/src/components/forms/drop-zone.tsx +146 -0
- package/src/components/forms/entity-select.stories.tsx +65 -0
- package/src/components/forms/entity-select.tsx +79 -0
- package/src/components/forms/field.tsx +3 -3
- package/src/components/forms/group-by-select.stories.tsx +26 -0
- package/src/components/forms/group-by-select.tsx +47 -0
- package/src/components/forms/index.ts +10 -0
- package/src/components/forms/input.stories.tsx +4 -4
- package/src/components/forms/input.tsx +1 -1
- package/src/components/forms/passkey-management.stories.tsx +81 -0
- package/src/components/forms/passkey-management.tsx +138 -0
- package/src/components/forms/radio-group.tsx +14 -13
- package/src/components/forms/select.stories.tsx +4 -4
- package/src/components/forms/select.tsx +47 -48
- package/src/components/forms/slider.stories.tsx +5 -2
- package/src/components/forms/slider.tsx +39 -17
- package/src/components/forms/stepper.tsx +4 -4
- package/src/components/forms/switch.stories.tsx +1 -1
- package/src/components/forms/switch.tsx +2 -2
- package/src/components/forms/textarea.stories.tsx +2 -2
- package/src/components/forms/textarea.tsx +1 -1
- package/src/components/layout/index.ts +3 -0
- package/src/components/layout/scroll-area.stories.tsx +4 -4
- package/src/components/layout/scroll-area.tsx +23 -21
- package/src/components/layout/section-intro.stories.tsx +29 -0
- package/src/components/layout/section-intro.tsx +31 -0
- package/src/components/layout/surface-panel.stories.tsx +32 -0
- package/src/components/layout/surface-panel.tsx +15 -0
- package/src/components/navigation/app-navigation.stories.tsx +2 -2
- package/src/components/navigation/app-navigation.tsx +13 -13
- package/src/components/navigation/index.ts +4 -0
- package/src/components/navigation/pagination-controls.stories.tsx +41 -0
- package/src/components/navigation/pagination-controls.tsx +50 -0
- package/src/components/navigation/route-link.stories.tsx +30 -0
- package/src/components/navigation/route-link.tsx +42 -0
- package/src/components/navigation/tabs.stories.tsx +5 -5
- package/src/components/navigation/tabs.tsx +8 -8
- package/src/components/overlays/alert-dialog.tsx +22 -25
- package/src/components/overlays/command.tsx +98 -26
- package/src/components/overlays/dialog.tsx +5 -5
- package/src/components/overlays/dropdown-menu.stories.tsx +0 -5
- package/src/components/overlays/dropdown-menu.tsx +49 -31
- package/src/components/overlays/popover.stories.tsx +2 -2
- package/src/components/overlays/popover.tsx +43 -14
- package/src/components/overlays/sheet.stories.tsx +2 -2
- package/src/components/overlays/sheet.tsx +51 -17
- package/src/components/primitives/avatar.tsx +9 -5
- package/src/components/primitives/badge.tsx +11 -12
- package/src/components/primitives/button.tsx +49 -23
- package/src/components/primitives/card.stories.tsx +2 -2
- package/src/components/primitives/card.tsx +2 -5
- package/src/components/primitives/index.ts +2 -0
- package/src/components/primitives/label.stories.tsx +1 -1
- package/src/components/primitives/label.tsx +5 -6
- package/src/components/primitives/status-badge.stories.tsx +52 -0
- package/src/components/primitives/status-badge.tsx +33 -0
- package/src/constants/chart-colors.ts +7 -7
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-sort.ts +20 -0
- package/src/index.ts +30 -11
- package/src/styles.css +100 -974
- package/src/tokens/chart-colors.stories.tsx +192 -0
- package/src/tokens/color-systems.stories.tsx +20 -112
- package/src/tokens/foundations.stories.tsx +58 -100
- package/src/tokens/generated/dark.colors.generated.ts +29 -0
- package/src/tokens/generated/dark.css +29 -0
- package/src/tokens/generated/foundations.css +148 -0
- package/src/tokens/generated/foundations.generated.ts +451 -0
- package/src/tokens/generated/light.colors.generated.ts +29 -0
- package/src/tokens/generated/light.css +29 -0
- package/src/tokens/index.ts +79 -16
- package/src/tokens/layout.stories.tsx +23 -91
- package/src/tokens/colors.ts +0 -156
- package/src/tokens/motion.ts +0 -51
- package/src/tokens/radii.ts +0 -10
- package/src/tokens/shadows.ts +0 -34
- package/src/tokens/spacing.ts +0 -30
- package/src/tokens/typography.ts +0 -42
package/src/tokens/index.ts
CHANGED
|
@@ -1,16 +1,79 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export type
|
|
1
|
+
import darkTokens from "./generated/dark.colors.generated";
|
|
2
|
+
import foundations from "./generated/foundations.generated";
|
|
3
|
+
import lightTokens from "./generated/light.colors.generated";
|
|
4
|
+
|
|
5
|
+
const toPixels = (value: string) => {
|
|
6
|
+
if (value.endsWith("rem")) return Number.parseFloat(value) * 16;
|
|
7
|
+
if (value.endsWith("px")) return Number.parseFloat(value);
|
|
8
|
+
throw new Error(`Unsupported foundation dimension: ${value}`);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const toMilliseconds = (value: string) => Number.parseFloat(value);
|
|
12
|
+
const toBezier = (value: number[]) => `cubic-bezier(${value.join(", ")})`;
|
|
13
|
+
type NormalizedSpacingKey<Key extends string> = Key extends `${infer Whole}-${infer Fraction}`
|
|
14
|
+
? `${Whole}.${Fraction}`
|
|
15
|
+
: Key;
|
|
16
|
+
export type SpacingToken = NormalizedSpacingKey<
|
|
17
|
+
keyof (typeof foundations)["spacing-scale"] & string
|
|
18
|
+
>;
|
|
19
|
+
|
|
20
|
+
export const colorTokenNames = Object.keys(lightTokens) as Array<keyof typeof lightTokens>;
|
|
21
|
+
export type ColorToken = keyof typeof lightTokens;
|
|
22
|
+
export type ColorMode = "light" | "dark";
|
|
23
|
+
export type ColorTheme = Readonly<Record<ColorToken, string>>;
|
|
24
|
+
|
|
25
|
+
export const colorThemes = {
|
|
26
|
+
light: lightTokens,
|
|
27
|
+
dark: darkTokens,
|
|
28
|
+
} as const satisfies Record<ColorMode, ColorTheme>;
|
|
29
|
+
|
|
30
|
+
export const colors = colorTokenNames.reduce(
|
|
31
|
+
(accumulator, token) => {
|
|
32
|
+
accumulator[token] = `var(--${token})`;
|
|
33
|
+
return accumulator;
|
|
34
|
+
},
|
|
35
|
+
{} as Record<ColorToken, `var(--${string})`>,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const spacing = Object.fromEntries(
|
|
39
|
+
Object.entries(foundations["spacing-scale"]).map(([key, value]) => [
|
|
40
|
+
key.replace("-", "."),
|
|
41
|
+
toPixels(value),
|
|
42
|
+
]),
|
|
43
|
+
) as Record<SpacingToken, number>;
|
|
44
|
+
|
|
45
|
+
export const fontFamilies = Object.fromEntries(
|
|
46
|
+
Object.entries(foundations.font).map(([key, value]) => [key, value.join(", ")]),
|
|
47
|
+
) as Record<keyof typeof foundations.font, string>;
|
|
48
|
+
|
|
49
|
+
export const fontFamiliesNative = { sans: "System", serif: "serif", mono: "monospace" } as const;
|
|
50
|
+
export const textSizes = Object.fromEntries(
|
|
51
|
+
Object.entries(foundations.text).map(([key, value]) => [key, toPixels(value)]),
|
|
52
|
+
) as Record<keyof typeof foundations.text, number>;
|
|
53
|
+
export const textLineHeights = foundations["text-line-height"];
|
|
54
|
+
export const fontWeights = Object.fromEntries(
|
|
55
|
+
Object.entries(foundations["font-weight"]).map(([key, value]) => [key, String(value)]),
|
|
56
|
+
) as Record<keyof (typeof foundations)["font-weight"], string>;
|
|
57
|
+
export const tracking = foundations.tracking;
|
|
58
|
+
export const leading = foundations.leading;
|
|
59
|
+
export const radii = Object.fromEntries(
|
|
60
|
+
Object.entries(foundations.radius).map(([key, value]) => [key, toPixels(value)]),
|
|
61
|
+
) as Record<keyof typeof foundations.radius, number>;
|
|
62
|
+
export const shadows = foundations.shadow;
|
|
63
|
+
export const breakpoints = foundations.breakpoint;
|
|
64
|
+
export const containers = foundations.container;
|
|
65
|
+
export const zIndices = foundations["z-index"];
|
|
66
|
+
export const easing = Object.fromEntries(
|
|
67
|
+
Object.entries(foundations.ease).map(([key, value]) => [key, toBezier(value)]),
|
|
68
|
+
) as Record<keyof typeof foundations.ease, string>;
|
|
69
|
+
export const transitionDurations = Object.fromEntries(
|
|
70
|
+
Object.entries(foundations.duration).map(([key, value]) => [key, toMilliseconds(value)]),
|
|
71
|
+
) as Record<keyof typeof foundations.duration, number>;
|
|
72
|
+
export const animations = foundations.animate;
|
|
73
|
+
|
|
74
|
+
export type RadiusToken = keyof typeof radii;
|
|
75
|
+
export type TextSizeToken = keyof typeof textSizes;
|
|
76
|
+
export type FontWeightToken = keyof typeof fontWeights;
|
|
77
|
+
export type TrackingToken = keyof typeof tracking;
|
|
78
|
+
export type LeadingToken = keyof typeof leading;
|
|
79
|
+
export type ShadowToken = keyof typeof shadows;
|
|
@@ -2,26 +2,24 @@ import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
|
2
2
|
|
|
3
3
|
const meta = {
|
|
4
4
|
title: "Foundations/Layout Rhythm",
|
|
5
|
-
parameters: {
|
|
6
|
-
layout: "fullscreen",
|
|
7
|
-
},
|
|
5
|
+
parameters: { layout: "fullscreen" },
|
|
8
6
|
} satisfies Meta;
|
|
9
|
-
|
|
10
7
|
export default meta;
|
|
11
8
|
type Story = StoryObj<typeof meta>;
|
|
12
9
|
|
|
13
10
|
export const PageShell: Story = {
|
|
14
11
|
render: () => (
|
|
15
|
-
<main className="page-shell bg-
|
|
16
|
-
<header className="
|
|
17
|
-
<p className="
|
|
18
|
-
<h1 className="
|
|
12
|
+
<main className="page-shell bg-background text-foreground">
|
|
13
|
+
<header className="flex flex-col gap-4">
|
|
14
|
+
<p className="text-muted-foreground text-sm">Page shell</p>
|
|
15
|
+
<h1 className="text-4xl font-semibold tracking-tight">
|
|
16
|
+
A consistent starting point for content pages.
|
|
17
|
+
</h1>
|
|
19
18
|
</header>
|
|
20
|
-
<section className="
|
|
21
|
-
<h2 className="
|
|
22
|
-
<p className="
|
|
23
|
-
|
|
24
|
-
feeds, and editorial surfaces.
|
|
19
|
+
<section className="flex flex-col gap-4">
|
|
20
|
+
<h2 className="text-2xl font-semibold">Section rhythm</h2>
|
|
21
|
+
<p className="text-muted-foreground max-w-2xl text-base">
|
|
22
|
+
Layout helpers compose standard Tailwind spacing and semantic colors.
|
|
25
23
|
</p>
|
|
26
24
|
</section>
|
|
27
25
|
</main>
|
|
@@ -30,20 +28,18 @@ export const PageShell: Story = {
|
|
|
30
28
|
|
|
31
29
|
export const ListRows: Story = {
|
|
32
30
|
render: () => (
|
|
33
|
-
<main className="page-shell bg-
|
|
34
|
-
<div className="
|
|
35
|
-
<h1 className="
|
|
36
|
-
<div className="border
|
|
37
|
-
{[
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<h2 className="heading-3">{title}</h2>
|
|
46
|
-
<p className="body-3 text-secondary">{description}</p>
|
|
31
|
+
<main className="page-shell bg-background text-foreground">
|
|
32
|
+
<div className="flex flex-col gap-4">
|
|
33
|
+
<h1 className="text-4xl font-semibold tracking-tight">List row rhythm</h1>
|
|
34
|
+
<div className="divide-border border-border divide-y border-b">
|
|
35
|
+
{["A compact row", "A readable row", "A responsive row"].map((title, index) => (
|
|
36
|
+
<div key={title} className="flex gap-4 py-6">
|
|
37
|
+
<span className="text-muted-foreground font-mono text-sm">0{index + 1}</span>
|
|
38
|
+
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
|
39
|
+
<h2 className="text-lg font-semibold">{title}</h2>
|
|
40
|
+
<p className="text-muted-foreground text-sm">
|
|
41
|
+
Consistent padding keeps scanning calm.
|
|
42
|
+
</p>
|
|
47
43
|
</div>
|
|
48
44
|
</div>
|
|
49
45
|
))}
|
|
@@ -52,67 +48,3 @@ export const ListRows: Story = {
|
|
|
52
48
|
</main>
|
|
53
49
|
),
|
|
54
50
|
};
|
|
55
|
-
|
|
56
|
-
export const ListRowsWithMedia: Story = {
|
|
57
|
-
render: () => (
|
|
58
|
-
<main className="page-shell bg-canvas text-primary">
|
|
59
|
-
<div className="layout-stack">
|
|
60
|
-
<h1 className="display-1">List rows with media</h1>
|
|
61
|
-
<div className="border-subtle divide-border-subtle divide-y border-b">
|
|
62
|
-
<div className="list-row items-center">
|
|
63
|
-
<div className="list-media list-media-wide bg-panel" aria-hidden="true">
|
|
64
|
-
<span className="heading-3 text-secondary">WO</span>
|
|
65
|
-
</div>
|
|
66
|
-
<div className="layout-stack min-w-0 gap-1">
|
|
67
|
-
<h2 className="heading-3">Wide media row</h2>
|
|
68
|
-
<p className="body-3 text-secondary">For client or partner marks.</p>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
<div className="list-row items-center">
|
|
72
|
-
<div className="list-media list-media-square bg-panel" aria-hidden="true">
|
|
73
|
-
<span className="heading-3 text-secondary">PR</span>
|
|
74
|
-
</div>
|
|
75
|
-
<div className="layout-stack min-w-0 gap-1">
|
|
76
|
-
<h2 className="heading-3">Square media row</h2>
|
|
77
|
-
<p className="body-3 text-secondary">For product or project marks.</p>
|
|
78
|
-
</div>
|
|
79
|
-
</div>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
</main>
|
|
83
|
-
),
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export const DetailSections: Story = {
|
|
87
|
-
render: () => (
|
|
88
|
-
<main className="bg-canvas text-primary">
|
|
89
|
-
<section className="section section-hero">
|
|
90
|
-
<p className="body-4 text-secondary">Detail hero</p>
|
|
91
|
-
<h1 className="display-1">A detail page with a clear vertical rhythm</h1>
|
|
92
|
-
</section>
|
|
93
|
-
<section className="section">
|
|
94
|
-
<h2 className="heading-2">Standard section</h2>
|
|
95
|
-
<p className="body-1 text-secondary max-w-2xl">
|
|
96
|
-
Sections share a border, gutter, and vertical breathing room without requiring a React
|
|
97
|
-
component.
|
|
98
|
-
</p>
|
|
99
|
-
</section>
|
|
100
|
-
<section className="section gap-8">
|
|
101
|
-
<h2 className="heading-2">Dense section</h2>
|
|
102
|
-
<ol className="layout-stack gap-8">
|
|
103
|
-
<li className="body-1">01 — Start with the problem.</li>
|
|
104
|
-
<li className="body-1">02 — Explain the approach.</li>
|
|
105
|
-
<li className="body-1">03 — Close with the outcome.</li>
|
|
106
|
-
</ol>
|
|
107
|
-
</section>
|
|
108
|
-
<div className="detail-navigation px-4 md:px-6">
|
|
109
|
-
<a className="body-2 text-secondary hover:text-primary" href="#previous">
|
|
110
|
-
← Previous
|
|
111
|
-
</a>
|
|
112
|
-
<a className="body-2 text-secondary hover:text-primary" href="#next">
|
|
113
|
-
Next →
|
|
114
|
-
</a>
|
|
115
|
-
</div>
|
|
116
|
-
</main>
|
|
117
|
-
),
|
|
118
|
-
};
|
package/src/tokens/colors.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical semantic color contract for the Ponti Studios system.
|
|
3
|
-
*
|
|
4
|
-
* Components consume these roles. The runtime CSS provides the light and dark
|
|
5
|
-
* values; this module exists for inspection, tooling, and typed consumers.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const colorTokenNames = [
|
|
9
|
-
"surface-canvas",
|
|
10
|
-
"surface-panel",
|
|
11
|
-
"surface-raised",
|
|
12
|
-
"surface-inset",
|
|
13
|
-
"surface-hover",
|
|
14
|
-
"surface-pressed",
|
|
15
|
-
"surface-selected",
|
|
16
|
-
"surface-disabled",
|
|
17
|
-
"overlay-scrim",
|
|
18
|
-
"text-primary",
|
|
19
|
-
"text-secondary",
|
|
20
|
-
"text-tertiary",
|
|
21
|
-
"text-disabled",
|
|
22
|
-
"text-accent",
|
|
23
|
-
"text-destructive",
|
|
24
|
-
"text-success",
|
|
25
|
-
"text-warning",
|
|
26
|
-
"text-on-accent",
|
|
27
|
-
"text-on-destructive",
|
|
28
|
-
"text-on-success",
|
|
29
|
-
"text-on-warning",
|
|
30
|
-
"border-subtle",
|
|
31
|
-
"border-default",
|
|
32
|
-
"border-strong",
|
|
33
|
-
"border-focus",
|
|
34
|
-
"border-accent",
|
|
35
|
-
"border-destructive",
|
|
36
|
-
"accent",
|
|
37
|
-
"accent-hover",
|
|
38
|
-
"accent-pressed",
|
|
39
|
-
"accent-subtle",
|
|
40
|
-
"destructive",
|
|
41
|
-
"destructive-hover",
|
|
42
|
-
"destructive-pressed",
|
|
43
|
-
"destructive-subtle",
|
|
44
|
-
"success",
|
|
45
|
-
"success-subtle",
|
|
46
|
-
"warning",
|
|
47
|
-
"warning-subtle",
|
|
48
|
-
"ring-focus",
|
|
49
|
-
] as const;
|
|
50
|
-
|
|
51
|
-
export type ColorToken = (typeof colorTokenNames)[number];
|
|
52
|
-
export type ColorMode = "light" | "dark";
|
|
53
|
-
export type ColorSystem = "ponti";
|
|
54
|
-
export type ColorTheme = Record<ColorToken, string>;
|
|
55
|
-
export type ColorSystemThemes = Record<ColorMode, ColorTheme>;
|
|
56
|
-
|
|
57
|
-
const pontiLight: ColorTheme = {
|
|
58
|
-
"surface-canvas": "#ffffff",
|
|
59
|
-
"surface-panel": "#f6f8fa",
|
|
60
|
-
"surface-raised": "#ffffff",
|
|
61
|
-
"surface-inset": "#eff2f5",
|
|
62
|
-
"surface-hover": "#e8ebef",
|
|
63
|
-
"surface-pressed": "#dfe3e8",
|
|
64
|
-
"surface-selected": "rgba(9, 105, 218, 0.1)",
|
|
65
|
-
"surface-disabled": "#eff2f5",
|
|
66
|
-
"overlay-scrim": "rgba(31, 35, 40, 0.42)",
|
|
67
|
-
"text-primary": "#25292e",
|
|
68
|
-
"text-secondary": "#59636e",
|
|
69
|
-
"text-tertiary": "#818b98",
|
|
70
|
-
"text-disabled": "#9ea7b3",
|
|
71
|
-
"text-accent": "#0969da",
|
|
72
|
-
"text-destructive": "#cf222e",
|
|
73
|
-
"text-success": "#1f883d",
|
|
74
|
-
"text-warning": "#9a6700",
|
|
75
|
-
"text-on-accent": "#ffffff",
|
|
76
|
-
"text-on-destructive": "#ffffff",
|
|
77
|
-
"text-on-success": "#ffffff",
|
|
78
|
-
"text-on-warning": "#1c1c1e",
|
|
79
|
-
"border-subtle": "rgba(129, 139, 152, 0.2)",
|
|
80
|
-
"border-default": "#d1d9e0",
|
|
81
|
-
"border-strong": "#8c959f",
|
|
82
|
-
"border-focus": "#0969da",
|
|
83
|
-
"border-accent": "#0969da",
|
|
84
|
-
"border-destructive": "#cf222e",
|
|
85
|
-
accent: "#0969da",
|
|
86
|
-
"accent-hover": "#0550ae",
|
|
87
|
-
"accent-pressed": "#033d8b",
|
|
88
|
-
"accent-subtle": "rgba(9, 105, 218, 0.1)",
|
|
89
|
-
destructive: "#cf222e",
|
|
90
|
-
"destructive-hover": "#a40e26",
|
|
91
|
-
"destructive-pressed": "#82071e",
|
|
92
|
-
"destructive-subtle": "rgba(207, 34, 46, 0.12)",
|
|
93
|
-
success: "#1f883d",
|
|
94
|
-
"success-subtle": "rgba(31, 136, 61, 0.12)",
|
|
95
|
-
warning: "#9a6700",
|
|
96
|
-
"warning-subtle": "rgba(154, 103, 0, 0.12)",
|
|
97
|
-
"ring-focus": "#0969da",
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const pontiDark: ColorTheme = {
|
|
101
|
-
"surface-canvas": "#0d1117",
|
|
102
|
-
"surface-panel": "#161b22",
|
|
103
|
-
"surface-raised": "#21262d",
|
|
104
|
-
"surface-inset": "#1a2029",
|
|
105
|
-
"surface-hover": "#242a33",
|
|
106
|
-
"surface-pressed": "#30363d",
|
|
107
|
-
"surface-selected": "rgba(47, 129, 247, 0.18)",
|
|
108
|
-
"surface-disabled": "#1a2029",
|
|
109
|
-
"overlay-scrim": "rgba(1, 4, 9, 0.78)",
|
|
110
|
-
"text-primary": "#f0f6fc",
|
|
111
|
-
"text-secondary": "#8b949e",
|
|
112
|
-
"text-tertiary": "#6e7681",
|
|
113
|
-
"text-disabled": "#484f58",
|
|
114
|
-
"text-accent": "#58a6ff",
|
|
115
|
-
"text-destructive": "#ff7b72",
|
|
116
|
-
"text-success": "#3fb950",
|
|
117
|
-
"text-warning": "#d29922",
|
|
118
|
-
"text-on-accent": "#ffffff",
|
|
119
|
-
"text-on-destructive": "#ffffff",
|
|
120
|
-
"text-on-success": "#ffffff",
|
|
121
|
-
"text-on-warning": "#0d1117",
|
|
122
|
-
"border-subtle": "rgba(240, 246, 252, 0.14)",
|
|
123
|
-
"border-default": "#30363d",
|
|
124
|
-
"border-strong": "#6e7681",
|
|
125
|
-
"border-focus": "#2f81f7",
|
|
126
|
-
"border-accent": "#2f81f7",
|
|
127
|
-
"border-destructive": "#da3633",
|
|
128
|
-
accent: "#2f81f7",
|
|
129
|
-
"accent-hover": "#58a6ff",
|
|
130
|
-
"accent-pressed": "#1f6feb",
|
|
131
|
-
"accent-subtle": "rgba(47, 129, 247, 0.18)",
|
|
132
|
-
destructive: "#da3633",
|
|
133
|
-
"destructive-hover": "#f85149",
|
|
134
|
-
"destructive-pressed": "#b62324",
|
|
135
|
-
"destructive-subtle": "rgba(218, 54, 51, 0.18)",
|
|
136
|
-
success: "#238636",
|
|
137
|
-
"success-subtle": "rgba(35, 134, 54, 0.18)",
|
|
138
|
-
warning: "#9e6a03",
|
|
139
|
-
"warning-subtle": "rgba(158, 106, 3, 0.18)",
|
|
140
|
-
"ring-focus": "#2f81f7",
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
export const colorSystems = {
|
|
144
|
-
ponti: { light: pontiLight, dark: pontiDark },
|
|
145
|
-
} as const satisfies Record<ColorSystem, ColorSystemThemes>;
|
|
146
|
-
|
|
147
|
-
export const colors = colorTokenNames.reduce(
|
|
148
|
-
(accumulator, token) => {
|
|
149
|
-
accumulator[token] = `var(--color-${token})`;
|
|
150
|
-
return accumulator;
|
|
151
|
-
},
|
|
152
|
-
{} as Record<ColorToken, `var(--color-${string})`>,
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
export const COLOR_SYSTEM_ATTRIBUTE = "data-color-system" as const;
|
|
156
|
-
export const COLOR_MODE_ATTRIBUTE = "data-color-mode" as const;
|
package/src/tokens/motion.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Motion tokens — durations and translate distances.
|
|
3
|
-
*
|
|
4
|
-
* Durations are in milliseconds. Must match animations.css and
|
|
5
|
-
* apps/omiro/theme/motion.ts (which imports from here).
|
|
6
|
-
*
|
|
7
|
-
* CSS easing strings are web-only. Mobile uses react-native-reanimated
|
|
8
|
-
* Easing.* functions which cannot be expressed as strings — the mobile
|
|
9
|
-
* motion.ts keeps those local and imports only the numeric constants here.
|
|
10
|
-
*
|
|
11
|
-
* ## Animation mandate
|
|
12
|
-
*
|
|
13
|
-
* Web interactive animations MUST use the shared GSAP helpers exposed by the
|
|
14
|
-
* consuming app.
|
|
15
|
-
* The canonical sequences (playFocusExpand, playFocusCollapse,
|
|
16
|
-
* playContextSwitch, playSubmitPulse, playEnterRow, playExitRow,
|
|
17
|
-
* playShimmer) read the numeric constants from this file so all motion
|
|
18
|
-
* stays in sync.
|
|
19
|
-
*
|
|
20
|
-
* CSS `motion-anim-*` classes (animations.css) are reserved for Radix UI
|
|
21
|
-
* component enter/exit only — do not add new CSS keyframe animations for
|
|
22
|
-
* interactive product surfaces.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
export const durations = {
|
|
26
|
-
/** Element arrives and settles (decelerate). */
|
|
27
|
-
enter: 150,
|
|
28
|
-
/** Element leaves without lingering (accelerate). */
|
|
29
|
-
exit: 120,
|
|
30
|
-
/** Content animations: loading states, thinking indicators. */
|
|
31
|
-
standard: 120,
|
|
32
|
-
/** Loop / breezy animations. */
|
|
33
|
-
breezy: 1800,
|
|
34
|
-
spin: 1200,
|
|
35
|
-
} as const;
|
|
36
|
-
|
|
37
|
-
export const translateDistances = {
|
|
38
|
-
/** Enter lift (px). */
|
|
39
|
-
enterY: 6,
|
|
40
|
-
/** Exit settle (px). */
|
|
41
|
-
exitY: 4,
|
|
42
|
-
enterX: 6,
|
|
43
|
-
exitX: 4,
|
|
44
|
-
} as const;
|
|
45
|
-
|
|
46
|
-
/** CSS cubic-bezier strings — web only. */
|
|
47
|
-
export const easingWeb = {
|
|
48
|
-
enter: "cubic-bezier(0.0, 0.0, 0.2, 1)",
|
|
49
|
-
exit: "cubic-bezier(0.4, 0.0, 1, 1)",
|
|
50
|
-
standard: "cubic-bezier(0.4, 0, 0.2, 1)",
|
|
51
|
-
} as const;
|
package/src/tokens/radii.ts
DELETED
package/src/tokens/shadows.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shadow tokens.
|
|
3
|
-
*
|
|
4
|
-
* `shadowsWeb` values must match --shadow-* in globals.css.
|
|
5
|
-
* `shadowsNative` are React Native shadow object equivalents.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const shadowsWeb = {
|
|
9
|
-
low: "0 2px 8px rgba(0, 0, 0, 0.35)",
|
|
10
|
-
medium: "0 8px 24px rgba(0, 0, 0, 0.45)",
|
|
11
|
-
high: "0 20px 60px rgba(0, 0, 0, 0.55)",
|
|
12
|
-
} as const;
|
|
13
|
-
|
|
14
|
-
/** React Native shadow objects. Pass these into StyleSheet styles. */
|
|
15
|
-
export const shadowsNative = {
|
|
16
|
-
low: {
|
|
17
|
-
shadowColor: "#0f1113",
|
|
18
|
-
shadowOffset: { width: 0, height: 2 },
|
|
19
|
-
shadowOpacity: 0.35,
|
|
20
|
-
shadowRadius: 8,
|
|
21
|
-
},
|
|
22
|
-
medium: {
|
|
23
|
-
shadowColor: "#0f1113",
|
|
24
|
-
shadowOffset: { width: 0, height: 8 },
|
|
25
|
-
shadowOpacity: 0.45,
|
|
26
|
-
shadowRadius: 24,
|
|
27
|
-
},
|
|
28
|
-
high: {
|
|
29
|
-
shadowColor: "#0f1113",
|
|
30
|
-
shadowOffset: { width: 0, height: 20 },
|
|
31
|
-
shadowOpacity: 0.55,
|
|
32
|
-
shadowRadius: 60,
|
|
33
|
-
},
|
|
34
|
-
} as const;
|
package/src/tokens/spacing.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spacing tokens — 8px primary grid, 4px secondary.
|
|
3
|
-
*
|
|
4
|
-
* Values are unitless numbers (px on web via CSS vars, logical pixels on
|
|
5
|
-
* mobile). Must match --spacing-* in packages/ui/src/styles.css.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const spacing = {
|
|
9
|
-
1: 4,
|
|
10
|
-
2: 8,
|
|
11
|
-
3: 12,
|
|
12
|
-
4: 16,
|
|
13
|
-
5: 24,
|
|
14
|
-
6: 32,
|
|
15
|
-
7: 48,
|
|
16
|
-
8: 64,
|
|
17
|
-
} as const;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Content width tokens for constraining max-width of content.
|
|
21
|
-
* Used for message bubbles, transcript areas, and other content containers.
|
|
22
|
-
*/
|
|
23
|
-
export const contentWidths = {
|
|
24
|
-
bubble: "36rem", // Compact message bubble width (576px)
|
|
25
|
-
transcript: "44rem", // Standard transcript/content width (704px)
|
|
26
|
-
notePreview: "32ch", // Empty-state note preview width
|
|
27
|
-
} as const;
|
|
28
|
-
|
|
29
|
-
export type SpacingToken = keyof typeof spacing;
|
|
30
|
-
export type ContentWidthToken = keyof typeof contentWidths;
|
package/src/tokens/typography.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export const fontFamilies = {
|
|
2
|
-
primary: "-apple-system, BlinkMacSystemFont, system-ui, sans-serif",
|
|
3
|
-
mono: "ui-monospace, monospace",
|
|
4
|
-
} as const;
|
|
5
|
-
|
|
6
|
-
export const fontSizes = {
|
|
7
|
-
micro: 10,
|
|
8
|
-
caption2: 11,
|
|
9
|
-
caption1: 12,
|
|
10
|
-
footnote: 13,
|
|
11
|
-
xs: 12,
|
|
12
|
-
sm: 14,
|
|
13
|
-
subhead: 15,
|
|
14
|
-
md: 16,
|
|
15
|
-
body: 17,
|
|
16
|
-
lg: 18,
|
|
17
|
-
xl: 20,
|
|
18
|
-
headline: 17,
|
|
19
|
-
display: 28,
|
|
20
|
-
} as const;
|
|
21
|
-
|
|
22
|
-
export const fontWeights = {
|
|
23
|
-
regular: "400",
|
|
24
|
-
medium: "500",
|
|
25
|
-
semibold: "600",
|
|
26
|
-
bold: "700",
|
|
27
|
-
} as const;
|
|
28
|
-
|
|
29
|
-
export const lineHeights = {
|
|
30
|
-
tight: 1.2,
|
|
31
|
-
normal: 1.4,
|
|
32
|
-
relaxed: 1.6,
|
|
33
|
-
} as const;
|
|
34
|
-
|
|
35
|
-
export const letterSpacing = {
|
|
36
|
-
tight: -0.05,
|
|
37
|
-
normal: 0,
|
|
38
|
-
relaxed: 0.01,
|
|
39
|
-
} as const;
|
|
40
|
-
|
|
41
|
-
export type FontSizeToken = keyof typeof fontSizes;
|
|
42
|
-
export type FontWeightToken = keyof typeof fontWeights;
|