@codeleap/styles 4.0.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.
Files changed (94) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +26 -0
  3. package/dist/lib/Cacher.d.ts +37 -0
  4. package/dist/lib/Cacher.js +104 -0
  5. package/dist/lib/StaleControl.d.ts +21 -0
  6. package/dist/lib/StaleControl.js +78 -0
  7. package/dist/lib/StyleCache.d.ts +20 -0
  8. package/dist/lib/StyleCache.js +52 -0
  9. package/dist/lib/StylePersistor.d.ts +13 -0
  10. package/dist/lib/StylePersistor.js +22 -0
  11. package/dist/lib/StyleRegistry.d.ts +46 -0
  12. package/dist/lib/StyleRegistry.js +499 -0
  13. package/dist/lib/borderCreator.d.ts +11 -0
  14. package/dist/lib/borderCreator.js +44 -0
  15. package/dist/lib/constants.d.ts +5 -0
  16. package/dist/lib/constants.js +8 -0
  17. package/dist/lib/createAppVariants.d.ts +6 -0
  18. package/dist/lib/createAppVariants.js +9 -0
  19. package/dist/lib/createStyles.d.ts +4 -0
  20. package/dist/lib/createStyles.js +27 -0
  21. package/dist/lib/createTheme.d.ts +7 -0
  22. package/dist/lib/createTheme.js +76 -0
  23. package/dist/lib/defaultVariants.d.ts +178 -0
  24. package/dist/lib/defaultVariants.js +179 -0
  25. package/dist/lib/dynamicVariants.d.ts +12 -0
  26. package/dist/lib/dynamicVariants.js +88 -0
  27. package/dist/lib/hashKey.d.ts +1 -0
  28. package/dist/lib/hashKey.js +14 -0
  29. package/dist/lib/hooks.d.ts +8 -0
  30. package/dist/lib/hooks.js +76 -0
  31. package/dist/lib/index.d.ts +10 -0
  32. package/dist/lib/index.js +37 -0
  33. package/dist/lib/mediaQuery.d.ts +11 -0
  34. package/dist/lib/mediaQuery.js +65 -0
  35. package/dist/lib/minifier.d.ts +6 -0
  36. package/dist/lib/minifier.js +21 -0
  37. package/dist/lib/multiplierProperty.d.ts +3 -0
  38. package/dist/lib/multiplierProperty.js +13 -0
  39. package/dist/lib/spacing.d.ts +11 -0
  40. package/dist/lib/spacing.js +104 -0
  41. package/dist/lib/themeStore.d.ts +7 -0
  42. package/dist/lib/themeStore.js +9 -0
  43. package/dist/lib/utils.d.ts +8 -0
  44. package/dist/lib/utils.js +172 -0
  45. package/dist/lib/validateTheme.d.ts +2 -0
  46. package/dist/lib/validateTheme.js +68 -0
  47. package/dist/types/cache.d.ts +1 -0
  48. package/dist/types/cache.js +2 -0
  49. package/dist/types/component.d.ts +25 -0
  50. package/dist/types/component.js +2 -0
  51. package/dist/types/core.d.ts +20 -0
  52. package/dist/types/core.js +2 -0
  53. package/dist/types/icon.d.ts +4 -0
  54. package/dist/types/icon.js +3 -0
  55. package/dist/types/index.d.ts +5 -0
  56. package/dist/types/index.js +21 -0
  57. package/dist/types/spacing.d.ts +6 -0
  58. package/dist/types/spacing.js +21 -0
  59. package/dist/types/style.d.ts +13 -0
  60. package/dist/types/style.js +2 -0
  61. package/dist/types/theme.d.ts +62 -0
  62. package/dist/types/theme.js +2 -0
  63. package/package.json +34 -0
  64. package/src/index.ts +7 -0
  65. package/src/lib/Cacher.ts +131 -0
  66. package/src/lib/StaleControl.ts +73 -0
  67. package/src/lib/StyleCache.ts +69 -0
  68. package/src/lib/StylePersistor.ts +28 -0
  69. package/src/lib/StyleRegistry.ts +549 -0
  70. package/src/lib/borderCreator.ts +42 -0
  71. package/src/lib/constants.ts +6 -0
  72. package/src/lib/createAppVariants.ts +12 -0
  73. package/src/lib/createStyles.ts +32 -0
  74. package/src/lib/createTheme.ts +89 -0
  75. package/src/lib/defaultVariants.ts +180 -0
  76. package/src/lib/dynamicVariants.ts +83 -0
  77. package/src/lib/hashKey.ts +12 -0
  78. package/src/lib/hooks.ts +52 -0
  79. package/src/lib/index.ts +11 -0
  80. package/src/lib/mediaQuery.ts +70 -0
  81. package/src/lib/minifier.ts +20 -0
  82. package/src/lib/multiplierProperty.ts +13 -0
  83. package/src/lib/spacing.ts +83 -0
  84. package/src/lib/themeStore.ts +14 -0
  85. package/src/lib/utils.ts +74 -0
  86. package/src/lib/validateTheme.ts +22 -0
  87. package/src/types/cache.ts +2 -0
  88. package/src/types/component.ts +40 -0
  89. package/src/types/core.ts +40 -0
  90. package/src/types/icon.ts +8 -0
  91. package/src/types/index.ts +5 -0
  92. package/src/types/spacing.ts +35 -0
  93. package/src/types/style.ts +41 -0
  94. package/src/types/theme.ts +77 -0
@@ -0,0 +1,89 @@
1
+ import { AppTheme, ColorScheme, Theme } from '../types'
2
+ import { borderCreator } from './borderCreator'
3
+ import { createMediaQueries } from './mediaQuery'
4
+ import { multiplierProperty } from './multiplierProperty'
5
+ import { defaultVariants } from './defaultVariants'
6
+ import { spacingFactory } from './spacing'
7
+ import { themeStore } from './themeStore'
8
+
9
+ type ColorSchemaPersistor = {
10
+ get: () => string
11
+ set: (colorSchema: string) => void
12
+ }
13
+
14
+ export const createTheme = <T extends Theme>(theme: T, colorSchemaPersistor: ColorSchemaPersistor): AppTheme<T> => {
15
+ const themeObj:AppTheme<T> = {
16
+ get currentColorScheme(): string {
17
+ return themeStore.getState().colorScheme
18
+ },
19
+
20
+ breakpoints: theme.breakpoints ?? {},
21
+
22
+ get colors() {
23
+ const colorScheme = themeStore.getState().colorScheme
24
+
25
+ if (colorScheme === 'default') return theme.colors
26
+
27
+ return theme.alternateColors?.[colorScheme]
28
+ },
29
+
30
+ setColorScheme(colorScheme: ColorScheme<Theme>) {
31
+ themeStore.setState({ colorScheme: colorScheme as string })
32
+ colorSchemaPersistor.set(colorScheme as string)
33
+ },
34
+
35
+ baseSpacing: theme.baseSpacing,
36
+ value: (n = 1) => theme.baseSpacing * n,
37
+
38
+ spacing: {
39
+ value: (n = 1) => theme.baseSpacing * n,
40
+ gap: multiplierProperty(theme.baseSpacing, 'gap'),
41
+ ...spacingFactory(theme.baseSpacing, 'padding'),
42
+ ...spacingFactory(theme.baseSpacing, 'margin'),
43
+ ...spacingFactory(theme.baseSpacing, 'p', true),
44
+ ...spacingFactory(theme.baseSpacing, 'm', true),
45
+ },
46
+
47
+ inset: {
48
+ top: multiplierProperty(theme.baseSpacing, 'top'),
49
+ bottom: multiplierProperty(theme.baseSpacing, 'bottom'),
50
+ left: multiplierProperty(theme.baseSpacing, 'left'),
51
+ right: multiplierProperty(theme.baseSpacing, 'right')
52
+ },
53
+
54
+ presets: {
55
+ ...defaultVariants,
56
+ ...theme.presets,
57
+ },
58
+
59
+ borderRadius: theme.borderRadius ?? {},
60
+
61
+ effects: theme.effects ?? {},
62
+
63
+ media: createMediaQueries(theme.breakpoints),
64
+
65
+ border: borderCreator,
66
+
67
+ typography: theme.typography ?? {},
68
+
69
+ icons: theme.icons,
70
+
71
+ values: theme.values ?? {},
72
+
73
+ sized: (size) => {
74
+ const value = typeof size == 'number' ? size * theme.baseSpacing : size
75
+
76
+ return {
77
+ width: value,
78
+ height: value,
79
+ }
80
+ },
81
+ }
82
+
83
+ themeStore.setState({
84
+ current: themeObj,
85
+ colorScheme: colorSchemaPersistor.get() ?? 'default'
86
+ })
87
+
88
+ return themeObj
89
+ }
@@ -0,0 +1,180 @@
1
+ import { ICSS } from '../types'
2
+
3
+ export const defaultVariants = {
4
+ inline: {
5
+ display: 'inline-block',
6
+ },
7
+ block: {
8
+ display: 'block',
9
+ },
10
+ flex: {
11
+ display: 'flex',
12
+ flex: 1,
13
+ },
14
+ inlineFlex: {
15
+ display: 'inline-flex',
16
+ },
17
+ absolute: {
18
+ position: 'absolute',
19
+ },
20
+ relative: {
21
+ position: 'relative',
22
+ },
23
+ fixed: {
24
+ position: 'fixed',
25
+ },
26
+ sticky: {
27
+ position: 'sticky',
28
+ },
29
+ inset: {
30
+ top: 0,
31
+ right: 0,
32
+ bottom: 0,
33
+ left: 0,
34
+ },
35
+ insetX: {
36
+ left: 0,
37
+ right: 0,
38
+ },
39
+ insetY: {
40
+ top: 0,
41
+ bottom: 0,
42
+ },
43
+ hidden: {
44
+ display: 'none',
45
+ },
46
+ full: {
47
+ width: '100%',
48
+ height: '100%',
49
+ },
50
+ noWrap: {
51
+ whiteSpace: 'nowrap',
52
+ },
53
+ fullWidth: {
54
+ width: '100%',
55
+ },
56
+ fullHeight: {
57
+ height: '100%',
58
+ },
59
+ fullView: {
60
+ width: '100vw',
61
+ height: 'calc(100vh - calc(100vh - 100%))',
62
+ },
63
+ fullViewWidth: {
64
+ width: '100vw',
65
+ },
66
+ fullViewHeight: {
67
+ height: 'calc(100vh - calc(100vh - 100%))',
68
+ },
69
+ whole: {
70
+ top: 0,
71
+ bottom: 0,
72
+ left: 0,
73
+ right: 0,
74
+ },
75
+ centerRow: {
76
+ display: 'flex',
77
+ flexDirection: 'row',
78
+ alignItems: 'center',
79
+ },
80
+ row: {
81
+ display: 'flex',
82
+ flexDirection: 'row',
83
+ },
84
+ listStyles: {
85
+ overflow: 'auto',
86
+ },
87
+ column: {
88
+ flexDirection: 'column',
89
+ },
90
+ center: {
91
+ alignItems: 'center',
92
+ justifyContent: 'center',
93
+ },
94
+ alignStart: {
95
+ alignItems: 'flex-start',
96
+ },
97
+ alignEnd: {
98
+ alignItems: 'flex-end',
99
+ },
100
+ alignCenter: {
101
+ alignItems: 'center',
102
+ },
103
+ alignStretch: {
104
+ alignItems: 'stretch',
105
+ },
106
+ alignSelfCenter: {
107
+ alignSelf: 'center',
108
+ },
109
+ alignSelfStart: {
110
+ alignSelf: 'flex-start',
111
+ },
112
+ alignSelfStretch: {
113
+ alignSelf: 'stretch',
114
+ },
115
+ alignSelfEnd: {
116
+ alignSelf: 'flex-end',
117
+ },
118
+ justifyStart: {
119
+ justifyContent: 'flex-start',
120
+ },
121
+ justifyEnd: {
122
+ justifyContent: 'flex-end',
123
+ },
124
+ justifyCenter: {
125
+ justifyContent: 'center',
126
+ },
127
+ justifySpaceBetween: {
128
+ justifyContent: 'space-between',
129
+ },
130
+ justifySpaceAround: {
131
+ justifyContent: 'space-around',
132
+ },
133
+ textRight: {
134
+ textAlign: 'right',
135
+ },
136
+ textLeft: {
137
+ textAlign: 'left',
138
+ },
139
+ textCenter: {
140
+ textAlign: 'center',
141
+ },
142
+ blur: {
143
+ backdropFilter: 'blur(4px)',
144
+ '-webkit-backdrop-filter': 'blur(4px)',
145
+ transition: '500ms',
146
+ },
147
+ elevated: {
148
+ boxShadow: '0px 0px 16px 16px #aaaaaa1a',
149
+ },
150
+ neumorphism: {
151
+ boxShadow: '10px 10px 20px 0 #AEAEC077, -10px -10px 20px 0 #fff',
152
+ },
153
+ scrollX: {
154
+ overflowX: 'auto',
155
+ },
156
+ scrollY: {
157
+ overflowY: 'auto',
158
+ },
159
+ scrollXY: {
160
+ overflowX: 'auto',
161
+ overflowY: 'auto',
162
+ },
163
+ wrap: {
164
+ flexWrap: 'wrap',
165
+ },
166
+ debRed: {
167
+ backgroundColor: '#f00',
168
+ },
169
+ debGreen: {
170
+ backgroundColor: '#0f0',
171
+ },
172
+ debBlue: {
173
+ backgroundColor: '#00f',
174
+ },
175
+ debYellow: {
176
+ backgroundColor: '#f9e902',
177
+ },
178
+ } as const
179
+
180
+ export type DefaultVariants = Record<keyof typeof defaultVariants, ICSS>
@@ -0,0 +1,83 @@
1
+ import { IBorderRadius, IColors, IEffects } from '../types'
2
+ import { capitalize } from './utils'
3
+
4
+ export type VariantFunction = (value: any) => any
5
+
6
+ export const colorVariants = ['backgroundColor', 'color'] as const
7
+
8
+ export const borderXDirection = ['left', 'right'] as const
9
+ export const borderYDirection = ['bottom', 'top'] as const
10
+ export const borderDirection = [...borderYDirection, ...borderXDirection, ''] as const
11
+ export const borderProperties = ['color', 'radius', 'width'] as const
12
+
13
+ export const cursorTypes = [
14
+ 'not-allowed',
15
+ 'help',
16
+ 'pointer',
17
+ 'wait',
18
+ ''
19
+ ] as const
20
+
21
+ export type Value =
22
+ | number
23
+ | ''
24
+
25
+ export type DynamicVariants =
26
+ `${typeof colorVariants[number]}:${keyof IColors}` |
27
+ `border${Capitalize<typeof borderDirection[number]>}Width:${keyof IBorderRadius}` |
28
+ `border${Capitalize<typeof borderDirection[number]>}Color:${keyof IColors}` |
29
+ `borderRadius:${keyof IBorderRadius}` |
30
+ `border${Capitalize<typeof borderYDirection[number]>}${Capitalize<typeof borderXDirection[number]>}Radius:${keyof IBorderRadius}` |
31
+ `cursor:${typeof cursorTypes[number]}` |
32
+ `bg:${keyof IColors}` |
33
+ `scale:${Value}`
34
+
35
+ export const createDynamicVariants = () => {
36
+ const dynamicVariants = {}
37
+
38
+ function createVariant(variantName: string, variantReturn: any) {
39
+ dynamicVariants[variantName] = variantReturn
40
+ }
41
+
42
+ colorVariants.forEach(variant => {
43
+ createVariant(variant, (theme, color: keyof IColors) => ({
44
+ [variant]: theme['colors'][color]
45
+ }))
46
+ })
47
+
48
+ borderDirection.forEach(direction => {
49
+ if (borderYDirection.includes(direction as any)) {
50
+ borderXDirection.forEach(y => {
51
+ const variant = `border${capitalize(direction)}${capitalize(y)}Radius`
52
+
53
+ createVariant(variant, (theme, value: keyof IBorderRadius) => ({
54
+ [variant]: theme['borderRadius'][value]
55
+ }))
56
+ })
57
+ }
58
+
59
+ borderProperties.forEach(property => {
60
+ const variant = `border${capitalize(direction)}${capitalize(property)}`
61
+
62
+ createVariant(variant, (theme, value: string) => ({
63
+ [variant]: property == 'color' ? theme['colors'][value] : theme['borderRadius'][value]
64
+ }))
65
+ })
66
+ })
67
+
68
+ createVariant('cursor', (theme, cursor: typeof cursorTypes[number]) => ({ cursor }))
69
+
70
+ createVariant('bg', (theme, color: keyof IColors) => ({
71
+ backgroundColor: theme['colors'][color]
72
+ }))
73
+
74
+ createVariant('effect', (theme, effect: keyof IEffects) => theme['effects'][effect])
75
+
76
+ createVariant('scale', (theme, value: any) => ({
77
+ transform: typeof localStorage !== 'undefined' ? `scale(${value})` : [{ 'scale': Number(value) }]
78
+ }))
79
+
80
+ return dynamicVariants
81
+ }
82
+
83
+ export const dynamicVariants = createDynamicVariants()
@@ -0,0 +1,12 @@
1
+ import { sha256 } from 'js-sha256'
2
+
3
+ const styleKey = '@styles-version'
4
+ const version = require('../../package.json')?.version
5
+
6
+ export const hashKey = (value: Array<any>): string => {
7
+ value.push({ [styleKey]: version })
8
+
9
+ const str = JSON.stringify(value)
10
+
11
+ return sha256(str)
12
+ }
@@ -0,0 +1,52 @@
1
+ import { useMemo } from 'react'
2
+ import { ICSS } from '../types'
3
+ import { getNestedStylesByKey } from './utils'
4
+ import { useShallow } from 'zustand/react/shallow'
5
+ import { ThemeStore, themeStore } from './themeStore'
6
+
7
+ export const useStyleObserver = (style) => {
8
+ return useMemo(() => {
9
+ if (Array.isArray(style)) {
10
+ return JSON.stringify(style?.filter(v => !!v))
11
+ } else if (typeof style === 'object'){
12
+ return JSON.stringify(style)
13
+ } else {
14
+ return style
15
+ }
16
+ }, [style])
17
+ }
18
+
19
+ export function useNestedStylesByKey<T extends string>(match: string, componentStyles: Partial<Record<T, ICSS>>) {
20
+ const styles = {
21
+ ...componentStyles
22
+ }
23
+
24
+ return useMemo(() => {
25
+ return getNestedStylesByKey(match, styles)
26
+ }, [styles])
27
+ }
28
+
29
+ type ThemeSelector<T extends Record<string, any>> = (store: ThemeStore) => T
30
+
31
+ export const useTheme = <T extends Record<string, any>>(selector: ThemeSelector<T>): T => {
32
+ return themeStore(useShallow(selector))
33
+ }
34
+
35
+ export function useCompositionStyles<T extends string, C extends string>(
36
+ composition: Array<T>,
37
+ componentStyles: Partial<Record<C, ICSS>>
38
+ ): Partial<Record<T, ICSS>> {
39
+ const styles = {
40
+ ...componentStyles
41
+ }
42
+
43
+ return useMemo(() => {
44
+ const compositionStyles = {}
45
+
46
+ for (const element of composition) {
47
+ compositionStyles[element as string] = getNestedStylesByKey(element, styles)
48
+ }
49
+
50
+ return compositionStyles
51
+ }, [styles])
52
+ }
@@ -0,0 +1,11 @@
1
+ export { validateTheme } from './validateTheme'
2
+ export { themeStore } from './themeStore'
3
+ export { createTheme } from './createTheme'
4
+ export { createAppVariants } from './createAppVariants'
5
+ export { createStyles } from './createStyles'
6
+ export { getNestedStylesByKey, mergeStyles, concatStyles } from './utils'
7
+ export { CodeleapStyleRegistry } from './StyleRegistry'
8
+ export { StylePersistor } from './StylePersistor'
9
+
10
+ export * from './constants'
11
+ export * from './hooks'
@@ -0,0 +1,70 @@
1
+ import { Breakpoint } from '../types'
2
+
3
+ export type Queries = {
4
+ up: (breakpoint: string) => string
5
+ down: (breakpoint: Breakpoint) => string
6
+ is: (breakpoint: string) => string
7
+ not: (breakpoint: string) => string
8
+ }
9
+
10
+ export type MediaQueries = Queries & {
11
+ renderToPlatformQuery: (props: Record<keyof Queries, any>) => string
12
+ }
13
+
14
+ function getBreakpointValue(breakpoint: any, breakpoints: any) {
15
+ if (breakpoints[breakpoint]) {
16
+ return breakpoints[breakpoint]
17
+ }
18
+
19
+ return Infinity
20
+ }
21
+
22
+ export function createMediaQueries<T extends any>(breakpoints: T): MediaQueries {
23
+ function getBreakpoint(breakpoint: any) {
24
+ return getBreakpointValue(breakpoint, breakpoints)
25
+ }
26
+
27
+ const queries: Queries = {
28
+ up: (breakpoint: any) => {
29
+ // Upwards of... (excluding)
30
+ const min = getBreakpoint(breakpoint)
31
+ return `@media screen and (min-width:${min}px)`
32
+ },
33
+ down: (breakpoint: any) => {
34
+ // Downwards of... (excluding)
35
+ const max = getBreakpoint(breakpoint)
36
+ return `@media screen and (max-width:${max}px)`
37
+ },
38
+ is: (breakpoint: any) => {
39
+ // Is media... (exact)
40
+ const value = getBreakpoint(breakpoint)
41
+ return `@media screen and (min-width:${value}px) and (max-width:${value}px)`
42
+ },
43
+ not: (breakpoint: any) => {
44
+ // Is NOT media... (exact)
45
+ const value = getBreakpoint(breakpoint)
46
+ return `@media not screen and (min-width:${value}px) and (max-width:${value}px)`
47
+ },
48
+ }
49
+
50
+ const renderToPlatformQuery = (props: Record<keyof Queries, any>) => {
51
+ let query = ''
52
+
53
+ if (props?.is) {
54
+ query = queries.not(props.is as never)
55
+ } else if (props?.not) {
56
+ query = queries.is(props.not as never)
57
+ } else if (props?.up) {
58
+ query = queries.down(props.up as never)
59
+ } else if (props?.down) {
60
+ query = queries.up(props.down as never)
61
+ }
62
+
63
+ return query
64
+ }
65
+
66
+ return {
67
+ ...queries,
68
+ renderToPlatformQuery,
69
+ }
70
+ }
@@ -0,0 +1,20 @@
1
+ import { compressToBase64, decompressFromBase64 } from 'lz-string'
2
+
3
+ export function compress(value: any): any {
4
+ if (!value) return value
5
+
6
+ return compressToBase64(JSON.stringify(value))
7
+ }
8
+
9
+ export function decompress(value: any): any {
10
+ if (!value) return value
11
+
12
+ const decoded = decompressFromBase64(value)
13
+
14
+ return JSON.parse(decoded)
15
+ }
16
+
17
+ export const minifier = {
18
+ compress,
19
+ decompress,
20
+ }
@@ -0,0 +1,13 @@
1
+
2
+ export function multiplierProperty<T extends string>(
3
+ base: number,
4
+ property: T,
5
+ ) {
6
+ return (multiplier: number | string) => {
7
+ const value = base * Number(multiplier)
8
+
9
+ return {
10
+ [property]: value,
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,83 @@
1
+ import { ICSS } from '../types'
2
+ import { spacingVariants, spacingShortVariants, SpacingVariants, SpacingShortVariants } from '../types/spacing'
3
+
4
+ export type MultiplierFunction = (multiplier: number | string) => ICSS
5
+
6
+ export type Spacings<T extends string, S = boolean> = {
7
+ [Property in (S extends boolean ? SpacingVariants : SpacingShortVariants) as `${T}${string & Property}`]: MultiplierFunction;
8
+ } & {
9
+ [Property in T]: (multiplier: number) => ICSS;
10
+ } & {
11
+ value: (multiplier: number) => number
12
+ }
13
+
14
+ const shortMapValues = {
15
+ 'x': 'Horizontal',
16
+ 'y': 'Vertical',
17
+ 'l': 'Left',
18
+ 'r': 'Right',
19
+ 't': 'Top',
20
+ 'b': 'Bottom',
21
+ 'm': 'margin',
22
+ 'p': 'padding'
23
+ }
24
+
25
+ export function spacingFactory<T extends string>(
26
+ base: number,
27
+ spacingProperty: T,
28
+ isShort: boolean = false
29
+ ): any {
30
+ const property = isShort ? shortMapValues[spacingProperty as string] : spacingProperty
31
+ const positions = isShort ? spacingShortVariants : spacingVariants
32
+
33
+ const spacings = {
34
+ [`${spacingProperty}`]: (n: number | string) => ({
35
+ [`${property}`]: base * Number(n),
36
+ }),
37
+ }
38
+
39
+ for (const _position of positions) {
40
+ const position = isShort ? shortMapValues[_position] : _position
41
+ const key = `${spacingProperty}${_position}`
42
+
43
+ let getter = null
44
+
45
+ switch (position) {
46
+ case 'Horizontal':
47
+ getter = (value: number) => ({
48
+ [`${property}Left`]: value,
49
+ [`${property}Right`]: value,
50
+ })
51
+ break
52
+ case 'Vertical':
53
+ getter = (value: number) => ({
54
+ [`${property}Top`]: value,
55
+ [`${property}Bottom`]: value,
56
+ })
57
+ break
58
+ case '':
59
+ getter = (value: number) => ({
60
+ [`${property}Top`]: value,
61
+ [`${property}Left`]: value,
62
+ [`${property}Right`]: value,
63
+ [`${property}Bottom`]: value,
64
+ })
65
+ break
66
+ default:
67
+ getter = (value: number) => ({
68
+ [`${property}${position}`]: value,
69
+ })
70
+ break
71
+ }
72
+
73
+ spacings[key] = (n: number | string) => {
74
+ if (n == 'auto') return getter('auto')
75
+
76
+ const value = base * Number(n)
77
+
78
+ return getter(value)
79
+ }
80
+ }
81
+
82
+ return spacings
83
+ }
@@ -0,0 +1,14 @@
1
+ import { create } from 'zustand'
2
+ import { IAppVariants, ITheme } from '../types'
3
+
4
+ export type ThemeStore = {
5
+ colorScheme: string | null
6
+ current: ITheme | null
7
+ variants: IAppVariants
8
+ }
9
+
10
+ export const themeStore = create<ThemeStore>(() => ({
11
+ colorScheme: null,
12
+ current: null,
13
+ variants: {},
14
+ }))
@@ -0,0 +1,74 @@
1
+ import deepmerge from '@fastify/deepmerge'
2
+ import { ICSS, StyledProp } from '../types'
3
+ import { spacingShortVariants, spacingVariants } from '../types/spacing'
4
+
5
+ export function capitalize(str: string, reverse = false) {
6
+ if (!str.length) return str
7
+ const firstChar = reverse ? str[0].toLowerCase() : str[0].toUpperCase()
8
+ return firstChar + str.substring(1)
9
+ }
10
+
11
+ export const spacingKeys = [
12
+ 'gap',
13
+ 'top',
14
+ 'left',
15
+ 'right',
16
+ 'bottom',
17
+ ]
18
+
19
+ for (const longProperty of ['padding', 'margin']) {
20
+ for (const variant of spacingVariants) {
21
+ spacingKeys.push(`${longProperty}${capitalize(variant)}`)
22
+ }
23
+ }
24
+
25
+ for (const shortProperty of ['p', 'm']) {
26
+ for (const shortVariant of spacingShortVariants) {
27
+ spacingKeys.push(shortProperty + shortVariant)
28
+ }
29
+ }
30
+
31
+ export function isSpacingKey(key: string) {
32
+ if (!key) return false
33
+
34
+ return spacingKeys?.includes(key)
35
+ }
36
+
37
+ export function getNestedStylesByKey<T extends string>(match: string, styles: Partial<Record<T, ICSS>>) {
38
+ const stylesByKey = {}
39
+
40
+ for (const [key, value] of Object.entries(styles)) {
41
+ if (key.startsWith(match)) {
42
+ const partName = capitalize(key.replace(match, ''), true)
43
+ stylesByKey[partName] = value
44
+ }
45
+ }
46
+
47
+ return stylesByKey
48
+ }
49
+
50
+ export const mergeStyles = (styles: Array<any>) => {
51
+ const style = styles?.filter(s => !!s)
52
+
53
+ return deepmerge({ all: true })(...style)
54
+ }
55
+
56
+ export const ignoredStyleKeys = [
57
+ 'textAlign',
58
+ 'textDecoration',
59
+ 'textOverflow'
60
+ ]
61
+
62
+ export const concatStyles = <T extends string>(styles: Array<StyledProp<T>>): StyledProp<T> => {
63
+ const results = []
64
+
65
+ for (const style of styles) {
66
+ if (Array.isArray(style)) {
67
+ results.push(...style)
68
+ } else {
69
+ results.push(style)
70
+ }
71
+ }
72
+
73
+ return results as unknown as StyledProp<T>
74
+ }