@ponti-studios/ui 1.6.0 → 1.8.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 +7 -11
- package/package.json +6 -31
- package/src/components/feedback/alert.tsx +8 -4
- package/src/components/feedback/index.ts +0 -4
- package/src/components/feedback/progress.stories.tsx +15 -0
- package/src/components/feedback/progress.tsx +14 -3
- package/src/components/feedback/update-guard.stories.tsx +4 -8
- package/src/components/feedback/update-guard.tsx +41 -272
- package/src/components/filters/filter-select.tsx +3 -5
- package/src/components/forms/date-picker.stories.tsx +158 -18
- package/src/components/forms/date-picker.tsx +286 -64
- package/src/components/forms/date-utils.ts +7 -2
- package/src/components/forms/drop-zone.tsx +11 -12
- package/src/components/forms/index.ts +2 -6
- package/src/components/forms/passkey-management.stories.tsx +8 -4
- package/src/components/forms/passkey-management.tsx +78 -42
- package/src/components/forms/radio-group.stories.tsx +3 -5
- package/src/components/forms/radio-group.tsx +2 -2
- package/src/components/forms/select.stories.tsx +16 -13
- package/src/components/forms/textarea.stories.tsx +1 -1
- package/src/components/layout/index.ts +2 -0
- package/src/components/layout/particle-background.stories.tsx +38 -0
- package/src/components/layout/particle-background.tsx +378 -0
- package/src/components/layout/scroll-area.stories.tsx +12 -4
- package/src/components/layout/scroll-area.tsx +41 -4
- package/src/components/navigation/tabs.stories.tsx +0 -21
- package/src/components/overlays/dialog.stories.tsx +38 -1
- package/src/components/overlays/dialog.tsx +53 -12
- package/src/components/overlays/index.ts +0 -11
- package/src/components/primitives/avatar-placeholder.svg +13 -0
- package/src/components/primitives/avatar.stories.tsx +2 -1
- package/src/components/primitives/badge.stories.tsx +13 -3
- package/src/components/primitives/badge.tsx +1 -1
- package/src/components/primitives/button.tsx +1 -1
- package/src/components/primitives/card.tsx +6 -2
- package/src/components/primitives/index.ts +0 -3
- package/src/index.ts +1 -3
- package/src/lib/index.ts +2 -3
- package/src/styles/animations.css +62 -0
- package/src/styles/index.css +31 -4
- package/src/styles/tokens/color-systems.stories.tsx +173 -25
- package/src/styles/tokens/generated/dark.colors.generated.ts +20 -12
- package/src/styles/tokens/generated/dark.css +20 -12
- package/src/styles/tokens/generated/light.colors.generated.ts +19 -11
- package/src/styles/tokens/generated/light.css +19 -11
- package/src/styles/tokens/index.ts +0 -3
- package/src/styles/tokens/scripts/check-source.mjs +7 -0
- package/src/styles/tokens/source/dark.tokens.json +44 -12
- package/src/styles/tokens/source/light.tokens.json +43 -11
- package/src/styles/tokens/typography.stories.tsx +157 -0
- package/src/components/feedback/file-upload-status.stories.tsx +0 -57
- package/src/components/feedback/file-upload-status.tsx +0 -160
- package/src/components/feedback/progress-bar.stories.tsx +0 -39
- package/src/components/feedback/progress-bar.tsx +0 -22
- package/src/components/forms/calendar.stories.tsx +0 -30
- package/src/components/forms/calendar.tsx +0 -75
- package/src/components/forms/date-field.stories.tsx +0 -202
- package/src/components/forms/date-field.tsx +0 -179
- package/src/components/overlays/alert-dialog.stories.tsx +0 -45
- package/src/components/overlays/alert-dialog.tsx +0 -116
- package/src/components/primitives/label.stories.tsx +0 -29
- package/src/components/primitives/label.tsx +0 -20
- package/src/components/primitives/status-badge.stories.tsx +0 -52
- package/src/components/primitives/status-badge.tsx +0 -33
- package/src/lib/create-memory-storage.ts +0 -24
- package/src/native/card.tsx +0 -36
- package/src/native/icon-button.tsx +0 -41
- package/src/native/index.ts +0 -38
- package/src/native/list-row.tsx +0 -67
- package/src/native/make-styles.ts +0 -32
- package/src/native/shadows.ts +0 -38
- package/src/native/text-field.tsx +0 -34
- package/src/native/uniwind.d.ts +0 -1
- package/src/native/use-theme-colors.ts +0 -19
- package/src/styles/tokens/foundations.stories.tsx +0 -109
- package/src/styles/tokens/generated/native.generated.ts +0 -266
- package/src/styles/tokens/normalize-native.ts +0 -88
- package/src/styles/tokens/source/native.tokens.json +0 -204
- package/src/styles/tokens/style-dictionary.native.mjs +0 -26
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { ImageStyle, TextStyle, ViewStyle } from "react-native";
|
|
2
|
-
|
|
3
|
-
export type NamedStyles = Record<string, ViewStyle | TextStyle | ImageStyle>;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Builds a `makeStyles` helper bound to a consuming app's own theme hook.
|
|
7
|
-
*
|
|
8
|
-
* The theme *shape* stays owned by the app — this package supplies only the
|
|
9
|
-
* mechanism — so `Theme` is a type parameter rather than a type exported from
|
|
10
|
-
* here. An app calls this once with its `useTheme` and uses the result
|
|
11
|
-
* everywhere:
|
|
12
|
-
*
|
|
13
|
-
* ```ts
|
|
14
|
-
* export const makeStyles = createMakeStyles(useTheme);
|
|
15
|
-
*
|
|
16
|
-
* const useStyles = makeStyles((theme) => ({
|
|
17
|
-
* card: { backgroundColor: theme.colors.card },
|
|
18
|
-
* }));
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* The returned `useStyles` is a hook: it calls `useTheme` on every render, so
|
|
22
|
-
* styles re-resolve when the color mode changes. Styles are returned as plain
|
|
23
|
-
* objects rather than passed through `StyleSheet.create`, since they are
|
|
24
|
-
* rebuilt per render and React Native accepts plain style objects directly.
|
|
25
|
-
*/
|
|
26
|
-
export function createMakeStyles<Theme>(useTheme: () => Theme) {
|
|
27
|
-
return function makeStyles<T extends NamedStyles>(factory: (theme: Theme) => T & NamedStyles) {
|
|
28
|
-
return function useStyles(): T {
|
|
29
|
-
return factory(useTheme());
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
}
|
package/src/native/shadows.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { shadows, type ShadowToken } from "../styles/tokens/index";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* One layer of a shadow in the shape React Native's `boxShadow` expects.
|
|
5
|
-
*
|
|
6
|
-
* The shared shadow tokens are authored for CSS, where each dimension carries
|
|
7
|
-
* its own unit. React Native takes bare numbers (density-independent pixels),
|
|
8
|
-
* so the unit is dropped here rather than at every call site.
|
|
9
|
-
*/
|
|
10
|
-
export interface NativeShadowLayer {
|
|
11
|
-
color: string;
|
|
12
|
-
offsetX: number;
|
|
13
|
-
offsetY: number;
|
|
14
|
-
blurRadius: number;
|
|
15
|
-
spreadDistance: number;
|
|
16
|
-
inset: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* The shared shadow scale translated to React Native's `boxShadow` shape.
|
|
21
|
-
*
|
|
22
|
-
* Every token maps to an array of layers, including `none`, which is a single
|
|
23
|
-
* fully transparent layer rather than an empty array — that keeps the value
|
|
24
|
-
* assignable wherever a real shadow is expected.
|
|
25
|
-
*/
|
|
26
|
-
export const nativeShadows = Object.fromEntries(
|
|
27
|
-
Object.entries(shadows).map(([name, layers]) => [
|
|
28
|
-
name,
|
|
29
|
-
layers.map((layer) => ({
|
|
30
|
-
color: layer.color,
|
|
31
|
-
offsetX: layer.offsetX.value,
|
|
32
|
-
offsetY: layer.offsetY.value,
|
|
33
|
-
blurRadius: layer.blur.value,
|
|
34
|
-
spreadDistance: layer.spread.value,
|
|
35
|
-
inset: false,
|
|
36
|
-
})),
|
|
37
|
-
]),
|
|
38
|
-
) as Record<ShadowToken, NativeShadowLayer[]>;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useState } from "react";
|
|
2
|
-
import { TextInput, type TextInputProps } from "react-native";
|
|
3
|
-
import { useCSSVariable } from "uniwind";
|
|
4
|
-
|
|
5
|
-
export const TextField = forwardRef<TextInput, TextInputProps>(function TextField(
|
|
6
|
-
{ onBlur, onFocus, style, ...props },
|
|
7
|
-
ref,
|
|
8
|
-
) {
|
|
9
|
-
const [ring, borderInput, foreground, mutedForeground] = useCSSVariable([
|
|
10
|
-
"--color-ring",
|
|
11
|
-
"--color-input",
|
|
12
|
-
"--color-foreground",
|
|
13
|
-
"--color-muted-foreground",
|
|
14
|
-
]) as string[];
|
|
15
|
-
const [focused, setFocused] = useState(false);
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<TextInput
|
|
19
|
-
{...props}
|
|
20
|
-
ref={ref}
|
|
21
|
-
onBlur={(event) => {
|
|
22
|
-
setFocused(false);
|
|
23
|
-
onBlur?.(event);
|
|
24
|
-
}}
|
|
25
|
-
onFocus={(event) => {
|
|
26
|
-
setFocused(true);
|
|
27
|
-
onFocus?.(event);
|
|
28
|
-
}}
|
|
29
|
-
placeholderTextColor={props.placeholderTextColor ?? mutedForeground}
|
|
30
|
-
className="rounded-md border min-h-11 px-4 py-3 text-base"
|
|
31
|
-
style={[{ borderColor: focused ? ring : borderInput, color: foreground }, style]}
|
|
32
|
-
/>
|
|
33
|
-
);
|
|
34
|
-
});
|
package/src/native/uniwind.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference types="uniwind/types" />
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { useColorScheme } from "react-native";
|
|
2
|
-
|
|
3
|
-
import { colorThemes, type ColorMode, type ColorTheme } from "../styles/tokens/index";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Resolves the active color mode from the OS appearance setting.
|
|
7
|
-
*
|
|
8
|
-
* React Native's `useColorScheme` reports `null` before the appearance module
|
|
9
|
-
* has settled, so anything that isn't explicitly "dark" resolves to light —
|
|
10
|
-
* callers always receive a concrete mode rather than having to handle null.
|
|
11
|
-
*/
|
|
12
|
-
export function useColorMode(): ColorMode {
|
|
13
|
-
return useColorScheme() === "dark" ? "dark" : "light";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** The full color token set for the active OS appearance. */
|
|
17
|
-
export function useThemeColors(): ColorTheme {
|
|
18
|
-
return colorThemes[useColorMode()];
|
|
19
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
|
|
3
|
-
const meta: Meta = { title: "Foundations/Tailwind Defaults", parameters: { layout: "fullscreen" } };
|
|
4
|
-
export default meta;
|
|
5
|
-
type Story = StoryObj<typeof meta>;
|
|
6
|
-
|
|
7
|
-
export const SpacingAndType: Story = {
|
|
8
|
-
render: () => (
|
|
9
|
-
<main className="bg-background text-foreground grid min-h-screen gap-10 p-6 md:p-10">
|
|
10
|
-
<section className="grid gap-6">
|
|
11
|
-
<header className="grid gap-2">
|
|
12
|
-
<p className="text-muted-foreground text-sm">Foundations / rhythm</p>
|
|
13
|
-
<h1 className="text-4xl font-semibold tracking-tight">Tailwind defaults, directly.</h1>
|
|
14
|
-
<p className="text-muted-foreground max-w-2xl text-base">
|
|
15
|
-
The specimen uses the shared Tailwind spacing and type scales.
|
|
16
|
-
</p>
|
|
17
|
-
</header>
|
|
18
|
-
<div className="grid gap-2">
|
|
19
|
-
{[1, 2, 3, 4, 6, 8, 12, 16].map((size) => (
|
|
20
|
-
<div key={size} className="flex items-center gap-3">
|
|
21
|
-
<span className="text-muted-foreground w-12 font-mono text-xs tabular-nums">
|
|
22
|
-
{size}
|
|
23
|
-
</span>
|
|
24
|
-
<div
|
|
25
|
-
className="bg-accent h-3 rounded-sm"
|
|
26
|
-
style={{ width: `calc(var(--spacing) * ${size})` }}
|
|
27
|
-
aria-hidden="true"
|
|
28
|
-
/>
|
|
29
|
-
</div>
|
|
30
|
-
))}
|
|
31
|
-
</div>
|
|
32
|
-
</section>
|
|
33
|
-
<section className="border-border bg-card grid gap-5 rounded-xl border p-6">
|
|
34
|
-
<h2 className="text-2xl font-semibold">Typography scale</h2>
|
|
35
|
-
<div className="grid gap-4">
|
|
36
|
-
{(
|
|
37
|
-
[
|
|
38
|
-
"text-xs",
|
|
39
|
-
"text-sm",
|
|
40
|
-
"text-base",
|
|
41
|
-
"text-lg",
|
|
42
|
-
"text-xl",
|
|
43
|
-
"text-2xl",
|
|
44
|
-
"text-4xl",
|
|
45
|
-
] as const
|
|
46
|
-
).map((size) => (
|
|
47
|
-
<p key={size} className={`${size} text-foreground`}>
|
|
48
|
-
{size}
|
|
49
|
-
</p>
|
|
50
|
-
))}
|
|
51
|
-
</div>
|
|
52
|
-
</section>
|
|
53
|
-
</main>
|
|
54
|
-
),
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export const Surfaces: Story = {
|
|
58
|
-
render: () => (
|
|
59
|
-
<main className="bg-background text-foreground grid min-h-screen gap-6 p-6 md:p-10">
|
|
60
|
-
<header className="grid gap-2">
|
|
61
|
-
<p className="text-muted-foreground text-sm">Foundations / surfaces</p>
|
|
62
|
-
<h1 className="text-4xl font-semibold tracking-tight">Standard semantic layers.</h1>
|
|
63
|
-
</header>
|
|
64
|
-
<div className="grid gap-4 md:grid-cols-2">
|
|
65
|
-
{[
|
|
66
|
-
["Background", "bg-background"],
|
|
67
|
-
["Card", "bg-card"],
|
|
68
|
-
["Popover", "bg-popover"],
|
|
69
|
-
["Muted", "bg-muted"],
|
|
70
|
-
].map(([name, className]) => (
|
|
71
|
-
<div
|
|
72
|
-
key={name}
|
|
73
|
-
className={`${className} border-border grid min-h-40 content-start gap-2 rounded-xl border p-5`}
|
|
74
|
-
>
|
|
75
|
-
<h2 className="text-lg font-semibold">{name}</h2>
|
|
76
|
-
<p className="text-muted-foreground text-sm">{className}</p>
|
|
77
|
-
</div>
|
|
78
|
-
))}
|
|
79
|
-
</div>
|
|
80
|
-
</main>
|
|
81
|
-
),
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const Motion: Story = {
|
|
85
|
-
render: () => (
|
|
86
|
-
<main className="bg-background text-foreground grid min-h-screen gap-8 p-6 md:p-10">
|
|
87
|
-
<header className="grid gap-2">
|
|
88
|
-
<p className="text-muted-foreground text-sm">Foundations / motion</p>
|
|
89
|
-
<h1 className="text-4xl font-semibold tracking-tight">
|
|
90
|
-
Motion stays standard and reducible.
|
|
91
|
-
</h1>
|
|
92
|
-
</header>
|
|
93
|
-
<div className="grid gap-4 sm:grid-cols-3">
|
|
94
|
-
<div className="motion-safe:animate-in motion-safe:fade-in-0 border-border bg-card grid min-h-32 place-content-center gap-2 rounded-xl border p-5 motion-reduce:animate-none">
|
|
95
|
-
<span className="text-lg font-semibold">Enter</span>
|
|
96
|
-
<span className="text-muted-foreground text-sm">150ms</span>
|
|
97
|
-
</div>
|
|
98
|
-
<button className="border-border bg-card hover:bg-accent focus-visible:ring-ring grid min-h-32 place-content-center gap-2 rounded-xl border p-5 text-left transition-colors focus-visible:ring-2 focus-visible:outline-none motion-reduce:transition-none">
|
|
99
|
-
<span className="text-lg font-semibold">Press</span>
|
|
100
|
-
<span className="text-muted-foreground text-sm">System focus</span>
|
|
101
|
-
</button>
|
|
102
|
-
<div className="border-border bg-card grid min-h-32 place-content-center gap-2 rounded-xl border p-5 motion-safe:animate-pulse motion-reduce:animate-none">
|
|
103
|
-
<span className="text-lg font-semibold">Loading</span>
|
|
104
|
-
<span className="text-muted-foreground text-sm">Stable geometry</span>
|
|
105
|
-
</div>
|
|
106
|
-
</div>
|
|
107
|
-
</main>
|
|
108
|
-
),
|
|
109
|
-
};
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Do not edit directly, this file was auto-generated.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
text: {
|
|
7
|
-
"large-title": {
|
|
8
|
-
fontSize: {
|
|
9
|
-
value: 34,
|
|
10
|
-
unit: "px",
|
|
11
|
-
},
|
|
12
|
-
lineHeight: {
|
|
13
|
-
value: 41,
|
|
14
|
-
unit: "px",
|
|
15
|
-
},
|
|
16
|
-
fontWeight: 700,
|
|
17
|
-
letterSpacing: {
|
|
18
|
-
value: -0.6,
|
|
19
|
-
unit: "px",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
title1: {
|
|
23
|
-
fontSize: {
|
|
24
|
-
value: 28,
|
|
25
|
-
unit: "px",
|
|
26
|
-
},
|
|
27
|
-
lineHeight: {
|
|
28
|
-
value: 34,
|
|
29
|
-
unit: "px",
|
|
30
|
-
},
|
|
31
|
-
fontWeight: 700,
|
|
32
|
-
letterSpacing: {
|
|
33
|
-
value: -0.4,
|
|
34
|
-
unit: "px",
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
title2: {
|
|
38
|
-
fontSize: {
|
|
39
|
-
value: 22,
|
|
40
|
-
unit: "px",
|
|
41
|
-
},
|
|
42
|
-
lineHeight: {
|
|
43
|
-
value: 28,
|
|
44
|
-
unit: "px",
|
|
45
|
-
},
|
|
46
|
-
fontWeight: 600,
|
|
47
|
-
letterSpacing: {
|
|
48
|
-
value: -0.2,
|
|
49
|
-
unit: "px",
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
headline: {
|
|
53
|
-
fontSize: {
|
|
54
|
-
value: 17,
|
|
55
|
-
unit: "px",
|
|
56
|
-
},
|
|
57
|
-
lineHeight: {
|
|
58
|
-
value: 22,
|
|
59
|
-
unit: "px",
|
|
60
|
-
},
|
|
61
|
-
fontWeight: 600,
|
|
62
|
-
letterSpacing: {
|
|
63
|
-
value: -0.1,
|
|
64
|
-
unit: "px",
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
body: {
|
|
68
|
-
fontSize: {
|
|
69
|
-
value: 17,
|
|
70
|
-
unit: "px",
|
|
71
|
-
},
|
|
72
|
-
lineHeight: {
|
|
73
|
-
value: 24,
|
|
74
|
-
unit: "px",
|
|
75
|
-
},
|
|
76
|
-
fontWeight: 400,
|
|
77
|
-
letterSpacing: {
|
|
78
|
-
value: 0,
|
|
79
|
-
unit: "px",
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
callout: {
|
|
83
|
-
fontSize: {
|
|
84
|
-
value: 16,
|
|
85
|
-
unit: "px",
|
|
86
|
-
},
|
|
87
|
-
lineHeight: {
|
|
88
|
-
value: 22,
|
|
89
|
-
unit: "px",
|
|
90
|
-
},
|
|
91
|
-
fontWeight: 400,
|
|
92
|
-
letterSpacing: {
|
|
93
|
-
value: -0.1,
|
|
94
|
-
unit: "px",
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
subhead: {
|
|
98
|
-
fontSize: {
|
|
99
|
-
value: 15,
|
|
100
|
-
unit: "px",
|
|
101
|
-
},
|
|
102
|
-
lineHeight: {
|
|
103
|
-
value: 20,
|
|
104
|
-
unit: "px",
|
|
105
|
-
},
|
|
106
|
-
fontWeight: 400,
|
|
107
|
-
letterSpacing: {
|
|
108
|
-
value: 0,
|
|
109
|
-
unit: "px",
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
footnote: {
|
|
113
|
-
fontSize: {
|
|
114
|
-
value: 13,
|
|
115
|
-
unit: "px",
|
|
116
|
-
},
|
|
117
|
-
lineHeight: {
|
|
118
|
-
value: 18,
|
|
119
|
-
unit: "px",
|
|
120
|
-
},
|
|
121
|
-
fontWeight: 400,
|
|
122
|
-
letterSpacing: {
|
|
123
|
-
value: 0,
|
|
124
|
-
unit: "px",
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
caption1: {
|
|
128
|
-
fontSize: {
|
|
129
|
-
value: 12,
|
|
130
|
-
unit: "px",
|
|
131
|
-
},
|
|
132
|
-
lineHeight: {
|
|
133
|
-
value: 16,
|
|
134
|
-
unit: "px",
|
|
135
|
-
},
|
|
136
|
-
fontWeight: 400,
|
|
137
|
-
letterSpacing: {
|
|
138
|
-
value: 0,
|
|
139
|
-
unit: "px",
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
caption2: {
|
|
143
|
-
fontSize: {
|
|
144
|
-
value: 11,
|
|
145
|
-
unit: "px",
|
|
146
|
-
},
|
|
147
|
-
lineHeight: {
|
|
148
|
-
value: 14,
|
|
149
|
-
unit: "px",
|
|
150
|
-
},
|
|
151
|
-
fontWeight: 500,
|
|
152
|
-
letterSpacing: {
|
|
153
|
-
value: 0.2,
|
|
154
|
-
unit: "px",
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
display: {
|
|
158
|
-
fontSize: {
|
|
159
|
-
value: 40,
|
|
160
|
-
unit: "px",
|
|
161
|
-
},
|
|
162
|
-
lineHeight: {
|
|
163
|
-
value: 44,
|
|
164
|
-
unit: "px",
|
|
165
|
-
},
|
|
166
|
-
fontWeight: 700,
|
|
167
|
-
letterSpacing: {
|
|
168
|
-
value: -1.2,
|
|
169
|
-
unit: "px",
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
overline: {
|
|
173
|
-
fontSize: {
|
|
174
|
-
value: 11,
|
|
175
|
-
unit: "px",
|
|
176
|
-
},
|
|
177
|
-
lineHeight: {
|
|
178
|
-
value: 16,
|
|
179
|
-
unit: "px",
|
|
180
|
-
},
|
|
181
|
-
fontWeight: 500,
|
|
182
|
-
letterSpacing: {
|
|
183
|
-
value: 0.8,
|
|
184
|
-
unit: "px",
|
|
185
|
-
},
|
|
186
|
-
textTransform: "uppercase",
|
|
187
|
-
},
|
|
188
|
-
mono: {
|
|
189
|
-
fontFamily: "Menlo",
|
|
190
|
-
fontSize: {
|
|
191
|
-
value: 12,
|
|
192
|
-
unit: "px",
|
|
193
|
-
},
|
|
194
|
-
lineHeight: {
|
|
195
|
-
value: 16,
|
|
196
|
-
unit: "px",
|
|
197
|
-
},
|
|
198
|
-
fontWeight: 400,
|
|
199
|
-
letterSpacing: {
|
|
200
|
-
value: 0,
|
|
201
|
-
unit: "px",
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
space: {
|
|
206
|
-
sm: "0.5rem",
|
|
207
|
-
md: "0.75rem",
|
|
208
|
-
lg: "1rem",
|
|
209
|
-
xl: "1.5rem",
|
|
210
|
-
},
|
|
211
|
-
"screen-margin": "1rem",
|
|
212
|
-
"component-size": {
|
|
213
|
-
sm: "1rem",
|
|
214
|
-
md: "1.5rem",
|
|
215
|
-
lg: "2rem",
|
|
216
|
-
xl: "2.75rem",
|
|
217
|
-
icon: "1.25rem",
|
|
218
|
-
},
|
|
219
|
-
"border-radius": {
|
|
220
|
-
sm: "0.25rem",
|
|
221
|
-
md: "0.375rem",
|
|
222
|
-
lg: "0.5rem",
|
|
223
|
-
icon: "0.375rem",
|
|
224
|
-
},
|
|
225
|
-
"stream-item": {
|
|
226
|
-
"border-radius": "0rem",
|
|
227
|
-
"border-width": "1px",
|
|
228
|
-
gap: "0.75rem",
|
|
229
|
-
"icon-size": "1.25rem",
|
|
230
|
-
"min-height": "3.5rem",
|
|
231
|
-
"padding-horizontal": "1rem",
|
|
232
|
-
"padding-vertical": "0.5rem",
|
|
233
|
-
},
|
|
234
|
-
"font-family": {
|
|
235
|
-
primary: "System",
|
|
236
|
-
mono: "Menlo",
|
|
237
|
-
},
|
|
238
|
-
motion: {
|
|
239
|
-
duration: {
|
|
240
|
-
instant: "0ms",
|
|
241
|
-
quick: "150ms",
|
|
242
|
-
standard: "300ms",
|
|
243
|
-
deliberate: "500ms",
|
|
244
|
-
},
|
|
245
|
-
easing: {
|
|
246
|
-
enter: [0, 0, 0.2, 1],
|
|
247
|
-
exit: [0.4, 0, 1, 1],
|
|
248
|
-
inOut: [0.4, 0, 0.2, 1],
|
|
249
|
-
},
|
|
250
|
-
distance: {
|
|
251
|
-
rowEnter: "0.5rem",
|
|
252
|
-
sceneReveal: "2rem",
|
|
253
|
-
},
|
|
254
|
-
opacity: {
|
|
255
|
-
hidden: 0,
|
|
256
|
-
visible: 1,
|
|
257
|
-
disabled: 0.5,
|
|
258
|
-
},
|
|
259
|
-
interruption: {
|
|
260
|
-
policy: "cancel-and-settle",
|
|
261
|
-
},
|
|
262
|
-
reducedMotion: {
|
|
263
|
-
policy: "replace-transform-with-opacity",
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
};
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import nativeGenerated from "./generated/native.generated";
|
|
2
|
-
|
|
3
|
-
const toPixels = (value: string) => {
|
|
4
|
-
if (value.endsWith("rem")) return Number.parseFloat(value) * 16;
|
|
5
|
-
if (value.endsWith("px")) return Number.parseFloat(value);
|
|
6
|
-
throw new Error(`Unsupported dimension: ${value}`);
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const unwrap = (v: { value: number; unit?: string } | number) =>
|
|
10
|
-
typeof v === "number" ? v : v.value;
|
|
11
|
-
|
|
12
|
-
type DimensionValue = number | { value: number; unit?: string };
|
|
13
|
-
|
|
14
|
-
const makeFlat = (raw: Record<string, unknown>) => ({
|
|
15
|
-
fontFamily: raw.fontFamily as string | undefined,
|
|
16
|
-
fontSize: unwrap(raw.fontSize as DimensionValue),
|
|
17
|
-
fontWeight: raw.fontWeight as number,
|
|
18
|
-
lineHeight: unwrap(raw.lineHeight as DimensionValue),
|
|
19
|
-
letterSpacing: unwrap(raw.letterSpacing as DimensionValue),
|
|
20
|
-
...(raw.textTransform
|
|
21
|
-
? { textTransform: raw.textTransform as "uppercase" | "lowercase" | "capitalize" | "none" }
|
|
22
|
-
: {}),
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const generated = nativeGenerated as unknown as {
|
|
26
|
-
text: Record<string, Record<string, unknown>>;
|
|
27
|
-
space: Record<string, string>;
|
|
28
|
-
"screen-margin": string;
|
|
29
|
-
"component-size": Record<string, string>;
|
|
30
|
-
"border-radius": Record<string, string>;
|
|
31
|
-
"stream-item": Record<string, string>;
|
|
32
|
-
"font-family": { primary: string; mono: string };
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const primaryFont = generated["font-family"].primary;
|
|
36
|
-
|
|
37
|
-
const typographyEntries = Object.entries(generated.text).map(([key, raw]) => {
|
|
38
|
-
const flat = makeFlat(raw);
|
|
39
|
-
if (!flat.fontFamily) flat.fontFamily = primaryFont;
|
|
40
|
-
return [key, flat] as const;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
export const typography = Object.fromEntries(typographyEntries) as Record<
|
|
44
|
-
string,
|
|
45
|
-
{
|
|
46
|
-
fontFamily: string;
|
|
47
|
-
fontSize: number;
|
|
48
|
-
fontWeight: number;
|
|
49
|
-
lineHeight: number;
|
|
50
|
-
letterSpacing: number;
|
|
51
|
-
textTransform?: "uppercase" | "lowercase" | "capitalize" | "none";
|
|
52
|
-
}
|
|
53
|
-
>;
|
|
54
|
-
|
|
55
|
-
export type TypographyVariant = keyof typeof typography;
|
|
56
|
-
|
|
57
|
-
export const spacing = Object.fromEntries(
|
|
58
|
-
Object.entries(generated.space).map(([key, value]) => [key, toPixels(value)]),
|
|
59
|
-
) as Record<keyof typeof generated.space, number>;
|
|
60
|
-
|
|
61
|
-
export type SpacingToken = keyof typeof spacing;
|
|
62
|
-
|
|
63
|
-
export const screenMargin = toPixels(generated["screen-margin"]);
|
|
64
|
-
|
|
65
|
-
export const componentSize = Object.fromEntries(
|
|
66
|
-
Object.entries(generated["component-size"]).map(([key, value]) => [key, toPixels(value)]),
|
|
67
|
-
) as Record<keyof (typeof generated)["component-size"], number>;
|
|
68
|
-
|
|
69
|
-
export type ComponentSizeToken = keyof typeof componentSize;
|
|
70
|
-
|
|
71
|
-
export const borderRadius = Object.fromEntries(
|
|
72
|
-
Object.entries(generated["border-radius"]).map(([key, value]) => [key, toPixels(value)]),
|
|
73
|
-
) as Record<keyof (typeof generated)["border-radius"], number>;
|
|
74
|
-
|
|
75
|
-
export type BorderRadiusToken = keyof typeof borderRadius;
|
|
76
|
-
|
|
77
|
-
const rawStreamItem = generated["stream-item"];
|
|
78
|
-
export const streamItem = {
|
|
79
|
-
borderRadius: toPixels(rawStreamItem["border-radius"]),
|
|
80
|
-
borderWidth: toPixels(rawStreamItem["border-width"]),
|
|
81
|
-
gap: toPixels(rawStreamItem.gap),
|
|
82
|
-
iconSize: toPixels(rawStreamItem["icon-size"]),
|
|
83
|
-
minHeight: toPixels(rawStreamItem["min-height"]),
|
|
84
|
-
paddingHorizontal: toPixels(rawStreamItem["padding-horizontal"]),
|
|
85
|
-
paddingVertical: toPixels(rawStreamItem["padding-vertical"]),
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
export const fontFamily = generated["font-family"];
|