@tamagui/create-theme 1.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/src/index.tsx ADDED
@@ -0,0 +1,132 @@
1
+ import type { Variable } from '@tamagui/web'
2
+
3
+ export type ThemeMask = Record<string, string | number>
4
+ export type Palette = string[]
5
+ export type ShiftMaskProps = { by: number; max: number; min?: number }
6
+ export type MaskOptions = { skip?: Partial<ThemeMask> }
7
+
8
+ type GenericTheme = { [key: string]: string | Variable }
9
+ type CreateMask = <A extends ThemeMask>(template: A, options: MaskOptions) => A
10
+
11
+ const THEME_INFO = new WeakMap<
12
+ any,
13
+ { palette: Palette; definition: ThemeMask; cache: WeakMap<any, any> }
14
+ >()
15
+
16
+ export function createTheme<
17
+ Definition extends ThemeMask,
18
+ Extras extends Record<string, string> = {}
19
+ >(
20
+ palette: Palette,
21
+ definition: Definition,
22
+ options?: {
23
+ nonInheritedValues?: Extras
24
+ }
25
+ ): {
26
+ [key in keyof Definition | keyof Extras]: string
27
+ } {
28
+ const theme = {
29
+ ...(Object.fromEntries(
30
+ Object.entries(definition).map(([key, offset]) => {
31
+ return [key, getValue(palette, offset)]
32
+ })
33
+ ) as any),
34
+ ...options?.nonInheritedValues,
35
+ }
36
+ THEME_INFO.set(theme, { palette, definition, cache: new WeakMap() })
37
+ return theme
38
+ }
39
+
40
+ const getValue = (palette: Palette, value: string | number) => {
41
+ if (typeof value === 'string') return value
42
+ const max = palette.length - 1
43
+ const isPositive = value === 0 ? !isMinusZero(value) : value >= 0
44
+ const next = isPositive ? value : max + value
45
+ const index = Math.min(Math.max(0, next), max)
46
+ return palette[index]
47
+ }
48
+
49
+ type SubThemeKeys<ParentKeys, ChildKeys> = `${ParentKeys extends string
50
+ ? ParentKeys
51
+ : never}_${ChildKeys extends string ? ChildKeys : never}`
52
+
53
+ export function addChildren<
54
+ Theme extends GenericTheme,
55
+ Themes extends { [key: string]: Theme },
56
+ GetChildren extends (name: keyof Themes, theme: Theme) => { [key: string]: Theme }
57
+ >(
58
+ themes: Themes,
59
+ getChildren: GetChildren
60
+ ): Themes & {
61
+ [key in SubThemeKeys<keyof Themes, keyof ReturnType<GetChildren>>]: Theme
62
+ } {
63
+ const out = { ...themes }
64
+ for (const key in themes) {
65
+ const subThemes = getChildren(key, themes[key])
66
+ for (const sKey in subThemes) {
67
+ out[`${key}_${sKey}`] = subThemes[sKey] as any
68
+ }
69
+ }
70
+ return out as any
71
+ }
72
+
73
+ export const createWeakenMask = ({
74
+ by = 1,
75
+ max,
76
+ min = 0,
77
+ inverseNegatives,
78
+ }: ShiftMaskProps & { inverseNegatives?: boolean }) => {
79
+ return ((template, { skip }) => {
80
+ const values = Object.entries(template) // .filter(Number)
81
+ const out = {}
82
+ for (const [key, value] of values) {
83
+ if (typeof value === 'string') continue
84
+ if (skip && key in skip) {
85
+ out[key] = value
86
+ continue
87
+ }
88
+ const isPositive = value === 0 ? !isMinusZero(value) : value >= 0
89
+ const direction = isPositive ? 1 : -1
90
+ const invert = inverseNegatives && !isPositive ? -1 : 1
91
+ const next = value + by * direction * invert
92
+ const clamped = isPositive
93
+ ? Math.max(min, Math.min(max, next))
94
+ : Math.min(-min, Math.max(-max, next))
95
+
96
+ out[key] = clamped
97
+ }
98
+ return out as typeof template
99
+ }) as CreateMask
100
+ }
101
+
102
+ function isMinusZero(value) {
103
+ return 1 / value === -Infinity
104
+ }
105
+
106
+ export const createStrengthenMask = (props: ShiftMaskProps) =>
107
+ createWeakenMask({ ...props, inverseNegatives: true })
108
+
109
+ export function applyMask<Theme extends GenericTheme>(
110
+ theme: Theme,
111
+ mask: CreateMask,
112
+ options: MaskOptions = {}
113
+ ): Theme {
114
+ const info = THEME_INFO.get(theme)
115
+ if (!info) {
116
+ throw new Error(
117
+ process.env.NODE_ENV !== 'production'
118
+ ? `No info found for theme, you must pass the theme created by createThemeFromPalette directly to extendTheme`
119
+ : `❌ Err2`
120
+ )
121
+ }
122
+ if (info.cache.has(mask)) {
123
+ return info.cache.get(mask)
124
+ }
125
+
126
+ const template = mask(info.definition, options)
127
+ const next = createTheme(info.palette, template) as Theme
128
+
129
+ info.cache.set(mask, next)
130
+
131
+ return next
132
+ }
@@ -0,0 +1,35 @@
1
+ import type { Variable } from '@tamagui/web';
2
+ export type ThemeMask = Record<string, string | number>;
3
+ export type Palette = string[];
4
+ export type ShiftMaskProps = {
5
+ by: number;
6
+ max: number;
7
+ min?: number;
8
+ };
9
+ export type MaskOptions = {
10
+ skip?: Partial<ThemeMask>;
11
+ };
12
+ type GenericTheme = {
13
+ [key: string]: string | Variable;
14
+ };
15
+ type CreateMask = <A extends ThemeMask>(template: A, options: MaskOptions) => A;
16
+ export declare function createTheme<Definition extends ThemeMask, Extras extends Record<string, string> = {}>(palette: Palette, definition: Definition, options?: {
17
+ nonInheritedValues?: Extras;
18
+ }): {
19
+ [key in keyof Definition | keyof Extras]: string;
20
+ };
21
+ type SubThemeKeys<ParentKeys, ChildKeys> = `${ParentKeys extends string ? ParentKeys : never}_${ChildKeys extends string ? ChildKeys : never}`;
22
+ export declare function addChildren<Theme extends GenericTheme, Themes extends {
23
+ [key: string]: Theme;
24
+ }, GetChildren extends (name: keyof Themes, theme: Theme) => {
25
+ [key: string]: Theme;
26
+ }>(themes: Themes, getChildren: GetChildren): Themes & {
27
+ [key in SubThemeKeys<keyof Themes, keyof ReturnType<GetChildren>>]: Theme;
28
+ };
29
+ export declare const createWeakenMask: ({ by, max, min, inverseNegatives, }: ShiftMaskProps & {
30
+ inverseNegatives?: boolean | undefined;
31
+ }) => CreateMask;
32
+ export declare const createStrengthenMask: (props: ShiftMaskProps) => CreateMask;
33
+ export declare function applyMask<Theme extends GenericTheme>(theme: Theme, mask: CreateMask, options?: MaskOptions): Theme;
34
+ export {};
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE5C,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;AACvD,MAAM,MAAM,OAAO,GAAG,MAAM,EAAE,CAAA;AAC9B,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACtE,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;CAAE,CAAA;AAEvD,KAAK,YAAY,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;CAAE,CAAA;AACxD,KAAK,UAAU,GAAG,CAAC,CAAC,SAAS,SAAS,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,WAAW,KAAK,CAAC,CAAA;AAO/E,wBAAgB,WAAW,CACzB,UAAU,SAAS,SAAS,EAC5B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,EAE1C,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE;IACR,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,GACA;KACA,GAAG,IAAI,MAAM,UAAU,GAAG,MAAM,MAAM,GAAG,MAAM;CACjD,CAWA;AAWD,KAAK,YAAY,CAAC,UAAU,EAAE,SAAS,IAAI,GAAG,UAAU,SAAS,MAAM,GACnE,UAAU,GACV,KAAK,IAAI,SAAS,SAAS,MAAM,GAAG,SAAS,GAAG,KAAK,EAAE,CAAA;AAE3D,wBAAgB,WAAW,CACzB,KAAK,SAAS,YAAY,EAC1B,MAAM,SAAS;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,EACvC,WAAW,SAAS,CAAC,IAAI,EAAE,MAAM,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAA;CAAE,EAElF,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,GACvB,MAAM,GAAG;KACT,GAAG,IAAI,YAAY,CAAC,MAAM,MAAM,EAAE,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC,GAAG,KAAK;CAC1E,CASA;AAED,eAAO,MAAM,gBAAgB;;gBA2B5B,CAAA;AAMD,eAAO,MAAM,oBAAoB,UAAW,cAAc,eACF,CAAA;AAExD,wBAAgB,SAAS,CAAC,KAAK,SAAS,YAAY,EAClD,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,WAAgB,GACxB,KAAK,CAmBP"}