@native-mate/core 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/dist/primitives/Spinner/Spinner.js +2 -2
- package/dist/primitives/Text/Text.js +2 -2
- package/package.json +31 -31
- package/src/__tests__/makeStyles.test.ts +56 -56
- package/src/__tests__/perf.test.ts +46 -46
- package/src/__tests__/platform.test.ts +34 -34
- package/src/__tests__/theme.test.ts +58 -58
- package/src/__tests__/tokens.test.ts +105 -105
- package/src/index.ts +27 -27
- package/src/primitives/Icon/Icon.tsx +11 -11
- package/src/primitives/Icon/Icon.types.ts +7 -7
- package/src/primitives/Separator/Separator.tsx +22 -22
- package/src/primitives/Separator/Separator.types.ts +6 -6
- package/src/primitives/Spinner/Spinner.tsx +50 -50
- package/src/primitives/Spinner/Spinner.types.ts +4 -4
- package/src/primitives/Text/Text.tsx +45 -45
- package/src/primitives/Text/Text.types.ts +15 -15
- package/src/theme/ThemeContext.ts +6 -6
- package/src/theme/ThemeProvider.tsx +27 -27
- package/src/theme/makeStyles.ts +15 -15
- package/src/theme/useTheme.ts +7 -7
- package/src/tokens/index.ts +29 -29
- package/src/tokens/presets/midnight.ts +24 -24
- package/src/tokens/presets/rose.ts +24 -24
- package/src/tokens/presets/slate.ts +24 -24
- package/src/tokens/presets/zinc.ts +37 -37
- package/src/tokens/types.ts +72 -72
- package/src/utils/platform.ts +20 -20
- package/src/utils/useBreakpoint.ts +10 -10
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import React, { useMemo } from 'react'
|
|
2
|
-
import { useColorScheme } from 'react-native'
|
|
3
|
-
import { ThemeContext } from './ThemeContext'
|
|
4
|
-
import { presets, resolveTokens } from '../tokens'
|
|
5
|
-
import type { ThemePreset, NativeMateTokenOverrides } from '../tokens/types'
|
|
6
|
-
|
|
7
|
-
interface ThemeProviderProps {
|
|
8
|
-
preset?: ThemePreset
|
|
9
|
-
forcedColorScheme?: 'light' | 'dark'
|
|
10
|
-
overrides?: { light?: NativeMateTokenOverrides; dark?: NativeMateTokenOverrides }
|
|
11
|
-
children: React.ReactNode
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
15
|
-
preset = 'zinc',
|
|
16
|
-
forcedColorScheme,
|
|
17
|
-
overrides,
|
|
18
|
-
children,
|
|
19
|
-
}) => {
|
|
20
|
-
const systemColorScheme = useColorScheme()
|
|
21
|
-
const mode = forcedColorScheme ?? systemColorScheme ?? 'light'
|
|
22
|
-
const theme = useMemo(
|
|
23
|
-
() => resolveTokens(presets[preset], mode, overrides?.[mode]),
|
|
24
|
-
[preset, mode, overrides],
|
|
25
|
-
)
|
|
26
|
-
return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
|
|
27
|
-
}
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
|
+
import { useColorScheme } from 'react-native'
|
|
3
|
+
import { ThemeContext } from './ThemeContext'
|
|
4
|
+
import { presets, resolveTokens } from '../tokens'
|
|
5
|
+
import type { ThemePreset, NativeMateTokenOverrides } from '../tokens/types'
|
|
6
|
+
|
|
7
|
+
interface ThemeProviderProps {
|
|
8
|
+
preset?: ThemePreset
|
|
9
|
+
forcedColorScheme?: 'light' | 'dark'
|
|
10
|
+
overrides?: { light?: NativeMateTokenOverrides; dark?: NativeMateTokenOverrides }
|
|
11
|
+
children: React.ReactNode
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
15
|
+
preset = 'zinc',
|
|
16
|
+
forcedColorScheme,
|
|
17
|
+
overrides,
|
|
18
|
+
children,
|
|
19
|
+
}) => {
|
|
20
|
+
const systemColorScheme = useColorScheme()
|
|
21
|
+
const mode = forcedColorScheme ?? systemColorScheme ?? 'light'
|
|
22
|
+
const theme = useMemo(
|
|
23
|
+
() => resolveTokens(presets[preset], mode, overrides?.[mode]),
|
|
24
|
+
[preset, mode, overrides],
|
|
25
|
+
)
|
|
26
|
+
return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
|
|
27
|
+
}
|
package/src/theme/makeStyles.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { useMemo } from 'react'
|
|
2
|
-
import { StyleSheet } from 'react-native'
|
|
3
|
-
import { useTheme } from './useTheme'
|
|
4
|
-
import type { ResolvedTheme } from '../tokens/types'
|
|
5
|
-
|
|
6
|
-
type StyleFactory<T extends StyleSheet.NamedStyles<T>> = (theme: ResolvedTheme) => T
|
|
7
|
-
|
|
8
|
-
export function makeStyles<T extends StyleSheet.NamedStyles<T>>(
|
|
9
|
-
factory: StyleFactory<T>,
|
|
10
|
-
): () => T {
|
|
11
|
-
return function useStyles(): T {
|
|
12
|
-
const theme = useTheme()
|
|
13
|
-
return useMemo(() => StyleSheet.create(factory(theme)), [theme])
|
|
14
|
-
}
|
|
15
|
-
}
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { StyleSheet } from 'react-native'
|
|
3
|
+
import { useTheme } from './useTheme'
|
|
4
|
+
import type { ResolvedTheme } from '../tokens/types'
|
|
5
|
+
|
|
6
|
+
type StyleFactory<T extends StyleSheet.NamedStyles<T>> = (theme: ResolvedTheme) => T
|
|
7
|
+
|
|
8
|
+
export function makeStyles<T extends StyleSheet.NamedStyles<T>>(
|
|
9
|
+
factory: StyleFactory<T>,
|
|
10
|
+
): () => T {
|
|
11
|
+
return function useStyles(): T {
|
|
12
|
+
const theme = useTheme()
|
|
13
|
+
return useMemo(() => StyleSheet.create(factory(theme)), [theme])
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/theme/useTheme.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useContext } from 'react'
|
|
2
|
-
import { ThemeContext } from './ThemeContext'
|
|
3
|
-
import type { ResolvedTheme } from '../tokens/types'
|
|
4
|
-
|
|
5
|
-
export function useTheme(): ResolvedTheme {
|
|
6
|
-
return useContext(ThemeContext)
|
|
7
|
-
}
|
|
1
|
+
import { useContext } from 'react'
|
|
2
|
+
import { ThemeContext } from './ThemeContext'
|
|
3
|
+
import type { ResolvedTheme } from '../tokens/types'
|
|
4
|
+
|
|
5
|
+
export function useTheme(): ResolvedTheme {
|
|
6
|
+
return useContext(ThemeContext)
|
|
7
|
+
}
|
package/src/tokens/index.ts
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import type { TokenSet, ResolvedTheme, NativeMateTokenOverrides } from './types'
|
|
2
|
-
import { zinc } from './presets/zinc'
|
|
3
|
-
import { slate } from './presets/slate'
|
|
4
|
-
import { rose } from './presets/rose'
|
|
5
|
-
import { midnight } from './presets/midnight'
|
|
6
|
-
|
|
7
|
-
export { zinc, slate, rose, midnight }
|
|
8
|
-
export * from './types'
|
|
9
|
-
|
|
10
|
-
export const presets = { zinc, slate, rose, midnight } as const
|
|
11
|
-
|
|
12
|
-
export function resolveTokens(
|
|
13
|
-
preset: TokenSet,
|
|
14
|
-
mode: 'light' | 'dark',
|
|
15
|
-
overrides?: NativeMateTokenOverrides,
|
|
16
|
-
): ResolvedTheme {
|
|
17
|
-
const resolvedColors = Object.fromEntries(
|
|
18
|
-
Object.entries(preset.colors).map(([key, token]) => [key, token[mode]])
|
|
19
|
-
) as ResolvedTheme['colors']
|
|
20
|
-
|
|
21
|
-
const colors = overrides?.colors ? { ...resolvedColors, ...overrides.colors } : resolvedColors
|
|
22
|
-
const spacing = overrides?.spacing ? { ...preset.spacing, ...overrides.spacing } : preset.spacing
|
|
23
|
-
const radius = overrides?.radius ? { ...preset.radius, ...overrides.radius } : preset.radius
|
|
24
|
-
const animation = overrides?.animation?.speed
|
|
25
|
-
? { ...preset.animation, speed: { ...preset.animation.speed, ...overrides.animation.speed } }
|
|
26
|
-
: preset.animation
|
|
27
|
-
|
|
28
|
-
return { colors, spacing, radius, typography: preset.typography, animation, colorScheme: mode }
|
|
29
|
-
}
|
|
1
|
+
import type { TokenSet, ResolvedTheme, NativeMateTokenOverrides } from './types'
|
|
2
|
+
import { zinc } from './presets/zinc'
|
|
3
|
+
import { slate } from './presets/slate'
|
|
4
|
+
import { rose } from './presets/rose'
|
|
5
|
+
import { midnight } from './presets/midnight'
|
|
6
|
+
|
|
7
|
+
export { zinc, slate, rose, midnight }
|
|
8
|
+
export * from './types'
|
|
9
|
+
|
|
10
|
+
export const presets = { zinc, slate, rose, midnight } as const
|
|
11
|
+
|
|
12
|
+
export function resolveTokens(
|
|
13
|
+
preset: TokenSet,
|
|
14
|
+
mode: 'light' | 'dark',
|
|
15
|
+
overrides?: NativeMateTokenOverrides,
|
|
16
|
+
): ResolvedTheme {
|
|
17
|
+
const resolvedColors = Object.fromEntries(
|
|
18
|
+
Object.entries(preset.colors).map(([key, token]) => [key, token[mode]])
|
|
19
|
+
) as ResolvedTheme['colors']
|
|
20
|
+
|
|
21
|
+
const colors = overrides?.colors ? { ...resolvedColors, ...overrides.colors } : resolvedColors
|
|
22
|
+
const spacing = overrides?.spacing ? { ...preset.spacing, ...overrides.spacing } : preset.spacing
|
|
23
|
+
const radius = overrides?.radius ? { ...preset.radius, ...overrides.radius } : preset.radius
|
|
24
|
+
const animation = overrides?.animation?.speed
|
|
25
|
+
? { ...preset.animation, speed: { ...preset.animation.speed, ...overrides.animation.speed } }
|
|
26
|
+
: preset.animation
|
|
27
|
+
|
|
28
|
+
return { colors, spacing, radius, typography: preset.typography, animation, colorScheme: mode }
|
|
29
|
+
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import type { TokenSet } from '../types'
|
|
2
|
-
import { zinc } from './zinc'
|
|
3
|
-
|
|
4
|
-
export const midnight: TokenSet = {
|
|
5
|
-
...zinc,
|
|
6
|
-
colors: {
|
|
7
|
-
background: { light: '#f8fafc', dark: '#000000' },
|
|
8
|
-
surface: { light: '#f1f5f9', dark: '#111111' },
|
|
9
|
-
surfaceRaised: { light: '#ffffff', dark: '#1a1a1a' },
|
|
10
|
-
border: { light: '#e2e8f0', dark: '#2a2a2a' },
|
|
11
|
-
primary: { light: '#6366f1', dark: '#818cf8' },
|
|
12
|
-
onPrimary: { light: '#ffffff', dark: '#000000' },
|
|
13
|
-
foreground: { light: '#0f172a', dark: '#f8fafc' },
|
|
14
|
-
onBackground: { light: '#0f172a', dark: '#f8fafc' },
|
|
15
|
-
onSurface: { light: '#1e293b', dark: '#e2e8f0' },
|
|
16
|
-
muted: { light: '#64748b', dark: '#6b7280' },
|
|
17
|
-
destructive: { light: '#ef4444', dark: '#f87171' },
|
|
18
|
-
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
19
|
-
success: { light: '#22c55e', dark: '#4ade80' },
|
|
20
|
-
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
21
|
-
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
22
|
-
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
23
|
-
},
|
|
24
|
-
}
|
|
1
|
+
import type { TokenSet } from '../types'
|
|
2
|
+
import { zinc } from './zinc'
|
|
3
|
+
|
|
4
|
+
export const midnight: TokenSet = {
|
|
5
|
+
...zinc,
|
|
6
|
+
colors: {
|
|
7
|
+
background: { light: '#f8fafc', dark: '#000000' },
|
|
8
|
+
surface: { light: '#f1f5f9', dark: '#111111' },
|
|
9
|
+
surfaceRaised: { light: '#ffffff', dark: '#1a1a1a' },
|
|
10
|
+
border: { light: '#e2e8f0', dark: '#2a2a2a' },
|
|
11
|
+
primary: { light: '#6366f1', dark: '#818cf8' },
|
|
12
|
+
onPrimary: { light: '#ffffff', dark: '#000000' },
|
|
13
|
+
foreground: { light: '#0f172a', dark: '#f8fafc' },
|
|
14
|
+
onBackground: { light: '#0f172a', dark: '#f8fafc' },
|
|
15
|
+
onSurface: { light: '#1e293b', dark: '#e2e8f0' },
|
|
16
|
+
muted: { light: '#64748b', dark: '#6b7280' },
|
|
17
|
+
destructive: { light: '#ef4444', dark: '#f87171' },
|
|
18
|
+
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
19
|
+
success: { light: '#22c55e', dark: '#4ade80' },
|
|
20
|
+
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
21
|
+
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
22
|
+
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
23
|
+
},
|
|
24
|
+
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import type { TokenSet } from '../types'
|
|
2
|
-
import { zinc } from './zinc'
|
|
3
|
-
|
|
4
|
-
export const rose: TokenSet = {
|
|
5
|
-
...zinc,
|
|
6
|
-
colors: {
|
|
7
|
-
background: { light: '#ffffff', dark: '#0c0a0b' },
|
|
8
|
-
surface: { light: '#fff1f2', dark: '#1c1115' },
|
|
9
|
-
surfaceRaised: { light: '#ffffff', dark: '#2d1a1f' },
|
|
10
|
-
border: { light: '#fecdd3', dark: '#4c2030' },
|
|
11
|
-
primary: { light: '#e11d48', dark: '#fb7185' },
|
|
12
|
-
onPrimary: { light: '#ffffff', dark: '#1c0a0f' },
|
|
13
|
-
foreground: { light: '#0f0a0b', dark: '#fef2f4' },
|
|
14
|
-
onBackground: { light: '#0f0a0b', dark: '#fef2f4' },
|
|
15
|
-
onSurface: { light: '#881337', dark: '#fecdd3' },
|
|
16
|
-
muted: { light: '#9f4258', dark: '#be738a' },
|
|
17
|
-
destructive: { light: '#dc2626', dark: '#f87171' },
|
|
18
|
-
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
19
|
-
success: { light: '#22c55e', dark: '#4ade80' },
|
|
20
|
-
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
21
|
-
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
22
|
-
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
23
|
-
},
|
|
24
|
-
}
|
|
1
|
+
import type { TokenSet } from '../types'
|
|
2
|
+
import { zinc } from './zinc'
|
|
3
|
+
|
|
4
|
+
export const rose: TokenSet = {
|
|
5
|
+
...zinc,
|
|
6
|
+
colors: {
|
|
7
|
+
background: { light: '#ffffff', dark: '#0c0a0b' },
|
|
8
|
+
surface: { light: '#fff1f2', dark: '#1c1115' },
|
|
9
|
+
surfaceRaised: { light: '#ffffff', dark: '#2d1a1f' },
|
|
10
|
+
border: { light: '#fecdd3', dark: '#4c2030' },
|
|
11
|
+
primary: { light: '#e11d48', dark: '#fb7185' },
|
|
12
|
+
onPrimary: { light: '#ffffff', dark: '#1c0a0f' },
|
|
13
|
+
foreground: { light: '#0f0a0b', dark: '#fef2f4' },
|
|
14
|
+
onBackground: { light: '#0f0a0b', dark: '#fef2f4' },
|
|
15
|
+
onSurface: { light: '#881337', dark: '#fecdd3' },
|
|
16
|
+
muted: { light: '#9f4258', dark: '#be738a' },
|
|
17
|
+
destructive: { light: '#dc2626', dark: '#f87171' },
|
|
18
|
+
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
19
|
+
success: { light: '#22c55e', dark: '#4ade80' },
|
|
20
|
+
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
21
|
+
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
22
|
+
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
23
|
+
},
|
|
24
|
+
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import type { TokenSet } from '../types'
|
|
2
|
-
import { zinc } from './zinc'
|
|
3
|
-
|
|
4
|
-
export const slate: TokenSet = {
|
|
5
|
-
...zinc,
|
|
6
|
-
colors: {
|
|
7
|
-
background: { light: '#ffffff', dark: '#0f172a' },
|
|
8
|
-
surface: { light: '#f1f5f9', dark: '#1e293b' },
|
|
9
|
-
surfaceRaised: { light: '#ffffff', dark: '#334155' },
|
|
10
|
-
border: { light: '#cbd5e1', dark: '#475569' },
|
|
11
|
-
primary: { light: '#0f172a', dark: '#f8fafc' },
|
|
12
|
-
onPrimary: { light: '#f8fafc', dark: '#0f172a' },
|
|
13
|
-
foreground: { light: '#020617', dark: '#f8fafc' },
|
|
14
|
-
onBackground: { light: '#020617', dark: '#f8fafc' },
|
|
15
|
-
onSurface: { light: '#0f172a', dark: '#e2e8f0' },
|
|
16
|
-
muted: { light: '#64748b', dark: '#94a3b8' },
|
|
17
|
-
destructive: { light: '#ef4444', dark: '#f87171' },
|
|
18
|
-
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
19
|
-
success: { light: '#22c55e', dark: '#4ade80' },
|
|
20
|
-
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
21
|
-
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
22
|
-
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
23
|
-
},
|
|
24
|
-
}
|
|
1
|
+
import type { TokenSet } from '../types'
|
|
2
|
+
import { zinc } from './zinc'
|
|
3
|
+
|
|
4
|
+
export const slate: TokenSet = {
|
|
5
|
+
...zinc,
|
|
6
|
+
colors: {
|
|
7
|
+
background: { light: '#ffffff', dark: '#0f172a' },
|
|
8
|
+
surface: { light: '#f1f5f9', dark: '#1e293b' },
|
|
9
|
+
surfaceRaised: { light: '#ffffff', dark: '#334155' },
|
|
10
|
+
border: { light: '#cbd5e1', dark: '#475569' },
|
|
11
|
+
primary: { light: '#0f172a', dark: '#f8fafc' },
|
|
12
|
+
onPrimary: { light: '#f8fafc', dark: '#0f172a' },
|
|
13
|
+
foreground: { light: '#020617', dark: '#f8fafc' },
|
|
14
|
+
onBackground: { light: '#020617', dark: '#f8fafc' },
|
|
15
|
+
onSurface: { light: '#0f172a', dark: '#e2e8f0' },
|
|
16
|
+
muted: { light: '#64748b', dark: '#94a3b8' },
|
|
17
|
+
destructive: { light: '#ef4444', dark: '#f87171' },
|
|
18
|
+
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
19
|
+
success: { light: '#22c55e', dark: '#4ade80' },
|
|
20
|
+
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
21
|
+
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
22
|
+
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
23
|
+
},
|
|
24
|
+
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import type { TokenSet } from '../types'
|
|
2
|
-
|
|
3
|
-
export const zinc: TokenSet = {
|
|
4
|
-
colors: {
|
|
5
|
-
background: { light: '#ffffff', dark: '#070709' },
|
|
6
|
-
surface: { light: '#e4e4e7', dark: '#0f0f11' },
|
|
7
|
-
surfaceRaised: { light: '#f4f4f5', dark: '#161619' },
|
|
8
|
-
border: { light: '#d4d4d8', dark: '#252529' },
|
|
9
|
-
primary: { light: '#18181b', dark: '#fafafa' },
|
|
10
|
-
onPrimary: { light: '#fafafa', dark: '#18181b' },
|
|
11
|
-
foreground: { light: '#09090b', dark: '#fafafa' },
|
|
12
|
-
onBackground: { light: '#09090b', dark: '#fafafa' },
|
|
13
|
-
onSurface: { light: '#18181b', dark: '#e4e4e7' },
|
|
14
|
-
muted: { light: '#71717a', dark: '#71717a' },
|
|
15
|
-
destructive: { light: '#ef4444', dark: '#f87171' },
|
|
16
|
-
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
17
|
-
success: { light: '#22c55e', dark: '#4ade80' },
|
|
18
|
-
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
19
|
-
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
20
|
-
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
21
|
-
},
|
|
22
|
-
spacing: { xs: 4, sm: 8, md: 12, lg: 16, xl: 24, '2xl': 32, '3xl': 48 },
|
|
23
|
-
radius: { sm: 6, md: 10, lg: 16, xl: 24, full: 9999 },
|
|
24
|
-
typography: {
|
|
25
|
-
size: { xs: 11, sm: 13, md: 15, lg: 17, xl: 20, '2xl': 24, '3xl': 30 },
|
|
26
|
-
weight: { regular: '400', medium: '500', semibold: '600', bold: '700' },
|
|
27
|
-
lineHeight: { tight: 18, normal: 22, relaxed: 28 },
|
|
28
|
-
},
|
|
29
|
-
animation: {
|
|
30
|
-
speed: { fast: 150, normal: 250, slow: 400 },
|
|
31
|
-
easing: {
|
|
32
|
-
standard: [0.4, 0.0, 0.2, 1],
|
|
33
|
-
decelerate: [0.0, 0.0, 0.2, 1],
|
|
34
|
-
spring: { damping: 15, stiffness: 200, mass: 1 },
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
}
|
|
1
|
+
import type { TokenSet } from '../types'
|
|
2
|
+
|
|
3
|
+
export const zinc: TokenSet = {
|
|
4
|
+
colors: {
|
|
5
|
+
background: { light: '#ffffff', dark: '#070709' },
|
|
6
|
+
surface: { light: '#e4e4e7', dark: '#0f0f11' },
|
|
7
|
+
surfaceRaised: { light: '#f4f4f5', dark: '#161619' },
|
|
8
|
+
border: { light: '#d4d4d8', dark: '#252529' },
|
|
9
|
+
primary: { light: '#18181b', dark: '#fafafa' },
|
|
10
|
+
onPrimary: { light: '#fafafa', dark: '#18181b' },
|
|
11
|
+
foreground: { light: '#09090b', dark: '#fafafa' },
|
|
12
|
+
onBackground: { light: '#09090b', dark: '#fafafa' },
|
|
13
|
+
onSurface: { light: '#18181b', dark: '#e4e4e7' },
|
|
14
|
+
muted: { light: '#71717a', dark: '#71717a' },
|
|
15
|
+
destructive: { light: '#ef4444', dark: '#f87171' },
|
|
16
|
+
onDestructive: { light: '#ffffff', dark: '#ffffff' },
|
|
17
|
+
success: { light: '#22c55e', dark: '#4ade80' },
|
|
18
|
+
onSuccess: { light: '#ffffff', dark: '#000000' },
|
|
19
|
+
warning: { light: '#f59e0b', dark: '#fbbf24' },
|
|
20
|
+
onWarning: { light: '#ffffff', dark: '#000000' },
|
|
21
|
+
},
|
|
22
|
+
spacing: { xs: 4, sm: 8, md: 12, lg: 16, xl: 24, '2xl': 32, '3xl': 48 },
|
|
23
|
+
radius: { sm: 6, md: 10, lg: 16, xl: 24, full: 9999 },
|
|
24
|
+
typography: {
|
|
25
|
+
size: { xs: 11, sm: 13, md: 15, lg: 17, xl: 20, '2xl': 24, '3xl': 30 },
|
|
26
|
+
weight: { regular: '400', medium: '500', semibold: '600', bold: '700' },
|
|
27
|
+
lineHeight: { tight: 18, normal: 22, relaxed: 28 },
|
|
28
|
+
},
|
|
29
|
+
animation: {
|
|
30
|
+
speed: { fast: 150, normal: 250, slow: 400 },
|
|
31
|
+
easing: {
|
|
32
|
+
standard: [0.4, 0.0, 0.2, 1],
|
|
33
|
+
decelerate: [0.0, 0.0, 0.2, 1],
|
|
34
|
+
spring: { damping: 15, stiffness: 200, mass: 1 },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
}
|
package/src/tokens/types.ts
CHANGED
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
export interface ColorToken {
|
|
2
|
-
light: string
|
|
3
|
-
dark: string
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface TokenColors {
|
|
7
|
-
background: ColorToken
|
|
8
|
-
surface: ColorToken
|
|
9
|
-
surfaceRaised: ColorToken
|
|
10
|
-
border: ColorToken
|
|
11
|
-
primary: ColorToken
|
|
12
|
-
onPrimary: ColorToken
|
|
13
|
-
foreground: ColorToken
|
|
14
|
-
onBackground: ColorToken
|
|
15
|
-
onSurface: ColorToken
|
|
16
|
-
muted: ColorToken
|
|
17
|
-
destructive: ColorToken
|
|
18
|
-
onDestructive: ColorToken
|
|
19
|
-
success: ColorToken
|
|
20
|
-
onSuccess: ColorToken
|
|
21
|
-
warning: ColorToken
|
|
22
|
-
onWarning: ColorToken
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface TokenSet {
|
|
26
|
-
colors: TokenColors
|
|
27
|
-
spacing: { xs: number; sm: number; md: number; lg: number; xl: number; '2xl': number; '3xl': number }
|
|
28
|
-
radius: { sm: number; md: number; lg: number; xl: number; full: number }
|
|
29
|
-
typography: {
|
|
30
|
-
size: { xs: number; sm: number; md: number; lg: number; xl: number; '2xl': number; '3xl': number }
|
|
31
|
-
weight: { regular: string; medium: string; semibold: string; bold: string }
|
|
32
|
-
lineHeight: { tight: number; normal: number; relaxed: number }
|
|
33
|
-
}
|
|
34
|
-
animation: {
|
|
35
|
-
speed: { fast: number; normal: number; slow: number }
|
|
36
|
-
easing: {
|
|
37
|
-
standard: readonly [number, number, number, number]
|
|
38
|
-
decelerate: readonly [number, number, number, number]
|
|
39
|
-
spring: { damping: number; stiffness: number; mass: number }
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export type ResolvedColors = { [K in keyof TokenColors]: string }
|
|
45
|
-
|
|
46
|
-
export interface ResolvedTheme {
|
|
47
|
-
colors: ResolvedColors
|
|
48
|
-
spacing: TokenSet['spacing']
|
|
49
|
-
radius: TokenSet['radius']
|
|
50
|
-
typography: TokenSet['typography']
|
|
51
|
-
animation: TokenSet['animation']
|
|
52
|
-
colorScheme: 'light' | 'dark'
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export type ThemePreset = 'zinc' | 'slate' | 'rose' | 'midnight'
|
|
56
|
-
|
|
57
|
-
export interface NativeMateTokenOverrides {
|
|
58
|
-
colors?: Partial<ResolvedColors>
|
|
59
|
-
spacing?: Partial<TokenSet['spacing']>
|
|
60
|
-
radius?: Partial<TokenSet['radius']>
|
|
61
|
-
animation?: { speed?: Partial<TokenSet['animation']['speed']> }
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface NativeMateConfig {
|
|
65
|
-
theme: ThemePreset
|
|
66
|
-
componentsDir: string
|
|
67
|
-
registry: string
|
|
68
|
-
tokens?: {
|
|
69
|
-
light?: NativeMateTokenOverrides
|
|
70
|
-
dark?: NativeMateTokenOverrides
|
|
71
|
-
}
|
|
72
|
-
}
|
|
1
|
+
export interface ColorToken {
|
|
2
|
+
light: string
|
|
3
|
+
dark: string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface TokenColors {
|
|
7
|
+
background: ColorToken
|
|
8
|
+
surface: ColorToken
|
|
9
|
+
surfaceRaised: ColorToken
|
|
10
|
+
border: ColorToken
|
|
11
|
+
primary: ColorToken
|
|
12
|
+
onPrimary: ColorToken
|
|
13
|
+
foreground: ColorToken
|
|
14
|
+
onBackground: ColorToken
|
|
15
|
+
onSurface: ColorToken
|
|
16
|
+
muted: ColorToken
|
|
17
|
+
destructive: ColorToken
|
|
18
|
+
onDestructive: ColorToken
|
|
19
|
+
success: ColorToken
|
|
20
|
+
onSuccess: ColorToken
|
|
21
|
+
warning: ColorToken
|
|
22
|
+
onWarning: ColorToken
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface TokenSet {
|
|
26
|
+
colors: TokenColors
|
|
27
|
+
spacing: { xs: number; sm: number; md: number; lg: number; xl: number; '2xl': number; '3xl': number }
|
|
28
|
+
radius: { sm: number; md: number; lg: number; xl: number; full: number }
|
|
29
|
+
typography: {
|
|
30
|
+
size: { xs: number; sm: number; md: number; lg: number; xl: number; '2xl': number; '3xl': number }
|
|
31
|
+
weight: { regular: string; medium: string; semibold: string; bold: string }
|
|
32
|
+
lineHeight: { tight: number; normal: number; relaxed: number }
|
|
33
|
+
}
|
|
34
|
+
animation: {
|
|
35
|
+
speed: { fast: number; normal: number; slow: number }
|
|
36
|
+
easing: {
|
|
37
|
+
standard: readonly [number, number, number, number]
|
|
38
|
+
decelerate: readonly [number, number, number, number]
|
|
39
|
+
spring: { damping: number; stiffness: number; mass: number }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type ResolvedColors = { [K in keyof TokenColors]: string }
|
|
45
|
+
|
|
46
|
+
export interface ResolvedTheme {
|
|
47
|
+
colors: ResolvedColors
|
|
48
|
+
spacing: TokenSet['spacing']
|
|
49
|
+
radius: TokenSet['radius']
|
|
50
|
+
typography: TokenSet['typography']
|
|
51
|
+
animation: TokenSet['animation']
|
|
52
|
+
colorScheme: 'light' | 'dark'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type ThemePreset = 'zinc' | 'slate' | 'rose' | 'midnight'
|
|
56
|
+
|
|
57
|
+
export interface NativeMateTokenOverrides {
|
|
58
|
+
colors?: Partial<ResolvedColors>
|
|
59
|
+
spacing?: Partial<TokenSet['spacing']>
|
|
60
|
+
radius?: Partial<TokenSet['radius']>
|
|
61
|
+
animation?: { speed?: Partial<TokenSet['animation']['speed']> }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface NativeMateConfig {
|
|
65
|
+
theme: ThemePreset
|
|
66
|
+
componentsDir: string
|
|
67
|
+
registry: string
|
|
68
|
+
tokens?: {
|
|
69
|
+
light?: NativeMateTokenOverrides
|
|
70
|
+
dark?: NativeMateTokenOverrides
|
|
71
|
+
}
|
|
72
|
+
}
|
package/src/utils/platform.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { Platform } from 'react-native'
|
|
2
|
-
|
|
3
|
-
export function shadow(level: 1 | 2 | 3 | 4 = 1) {
|
|
4
|
-
const config = {
|
|
5
|
-
1: { opacity: 0.06, radius: 4, offsetY: 1, elevation: 2 },
|
|
6
|
-
2: { opacity: 0.10, radius: 8, offsetY: 2, elevation: 4 },
|
|
7
|
-
3: { opacity: 0.14, radius: 16, offsetY: 4, elevation: 8 },
|
|
8
|
-
4: { opacity: 0.18, radius: 24, offsetY: 8, elevation: 12 },
|
|
9
|
-
}[level]
|
|
10
|
-
|
|
11
|
-
if (Platform.OS === 'ios') {
|
|
12
|
-
return {
|
|
13
|
-
shadowColor: '#000',
|
|
14
|
-
shadowOpacity: config.opacity,
|
|
15
|
-
shadowRadius: config.radius,
|
|
16
|
-
shadowOffset: { width: 0, height: config.offsetY },
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return { elevation: config.elevation }
|
|
20
|
-
}
|
|
1
|
+
import { Platform } from 'react-native'
|
|
2
|
+
|
|
3
|
+
export function shadow(level: 1 | 2 | 3 | 4 = 1) {
|
|
4
|
+
const config = {
|
|
5
|
+
1: { opacity: 0.06, radius: 4, offsetY: 1, elevation: 2 },
|
|
6
|
+
2: { opacity: 0.10, radius: 8, offsetY: 2, elevation: 4 },
|
|
7
|
+
3: { opacity: 0.14, radius: 16, offsetY: 4, elevation: 8 },
|
|
8
|
+
4: { opacity: 0.18, radius: 24, offsetY: 8, elevation: 12 },
|
|
9
|
+
}[level]
|
|
10
|
+
|
|
11
|
+
if (Platform.OS === 'ios') {
|
|
12
|
+
return {
|
|
13
|
+
shadowColor: '#000',
|
|
14
|
+
shadowOpacity: config.opacity,
|
|
15
|
+
shadowRadius: config.radius,
|
|
16
|
+
shadowOffset: { width: 0, height: config.offsetY },
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return { elevation: config.elevation }
|
|
20
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { useWindowDimensions } from 'react-native'
|
|
2
|
-
|
|
3
|
-
export type Breakpoint = 'sm' | 'md' | 'lg'
|
|
4
|
-
|
|
5
|
-
export function useBreakpoint(): Breakpoint {
|
|
6
|
-
const { width } = useWindowDimensions()
|
|
7
|
-
if (width >= 1024) return 'lg'
|
|
8
|
-
if (width >= 768) return 'md'
|
|
9
|
-
return 'sm'
|
|
10
|
-
}
|
|
1
|
+
import { useWindowDimensions } from 'react-native'
|
|
2
|
+
|
|
3
|
+
export type Breakpoint = 'sm' | 'md' | 'lg'
|
|
4
|
+
|
|
5
|
+
export function useBreakpoint(): Breakpoint {
|
|
6
|
+
const { width } = useWindowDimensions()
|
|
7
|
+
if (width >= 1024) return 'lg'
|
|
8
|
+
if (width >= 768) return 'md'
|
|
9
|
+
return 'sm'
|
|
10
|
+
}
|