@animus-ui/theming 0.1.1-beta.3 → 0.1.1-beta.30
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/CHANGELOG.md +101 -5
- package/CLAUDE.md +334 -0
- package/dist/core/ThemeBuilder.d.ts +34 -34
- package/dist/index.d.ts +1 -1
- package/dist/index.js +289 -0
- package/dist/utils/createTheme.d.ts +53 -53
- package/dist/utils/flattenScale.d.ts +20 -20
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/serializeTokens.d.ts +19 -18
- package/dist/utils/types.d.ts +41 -41
- package/package.json +11 -10
- package/rollup.config.js +2 -2
- package/tsconfig.json +4 -3
- package/dist/index.cjs.js +0 -1
- package/dist/index.esm.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,37 +3,133 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [0.1.1-beta.
|
|
6
|
+
## [0.1.1-beta.30](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.28...@animus-ui/theming@0.1.1-beta.30) (2025-07-01)
|
|
7
7
|
|
|
8
8
|
**Note:** Version bump only for package @animus-ui/theming
|
|
9
9
|
|
|
10
|
+
## 0.1.1-beta.29 (2025-06-15)
|
|
10
11
|
|
|
12
|
+
## 0.1.1-beta.1 (2022-01-09)
|
|
11
13
|
|
|
14
|
+
## 0.1.1-beta.0 (2022-01-09)
|
|
12
15
|
|
|
16
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
13
17
|
|
|
14
|
-
## 0.1.1-beta.
|
|
18
|
+
## [0.1.1-beta.28](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.27...@animus-ui/theming@0.1.1-beta.28) (2025-06-13)
|
|
15
19
|
|
|
20
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
16
21
|
|
|
22
|
+
## [0.1.1-beta.27](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.26...@animus-ui/theming@0.1.1-beta.27) (2025-05-29)
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
19
25
|
|
|
26
|
+
## [0.1.1-beta.26](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.25...@animus-ui/theming@0.1.1-beta.26) (2025-05-29)
|
|
20
27
|
|
|
28
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
21
29
|
|
|
22
|
-
## 0.1.1-beta.0 (
|
|
30
|
+
## [0.1.1-beta.25](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.24...@animus-ui/theming@0.1.1-beta.25) (2023-03-15)
|
|
23
31
|
|
|
24
32
|
**Note:** Version bump only for package @animus-ui/theming
|
|
25
33
|
|
|
34
|
+
## [0.1.1-beta.24](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.23...@animus-ui/theming@0.1.1-beta.24) (2023-03-15)
|
|
26
35
|
|
|
36
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
27
37
|
|
|
38
|
+
## [0.1.1-beta.23](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.21...@animus-ui/theming@0.1.1-beta.23) (2023-03-13)
|
|
28
39
|
|
|
40
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
29
41
|
|
|
30
|
-
## [0.1.1-beta.
|
|
42
|
+
## [0.1.1-beta.22](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.21...@animus-ui/theming@0.1.1-beta.22) (2022-03-25)
|
|
43
|
+
|
|
44
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
45
|
+
|
|
46
|
+
## [0.1.1-beta.21](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.20...@animus-ui/theming@0.1.1-beta.21) (2022-02-14)
|
|
47
|
+
|
|
48
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
49
|
+
|
|
50
|
+
## [0.1.1-beta.20](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.19...@animus-ui/theming@0.1.1-beta.20) (2022-02-14)
|
|
51
|
+
|
|
52
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
53
|
+
|
|
54
|
+
## [0.1.1-beta.19](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.18...@animus-ui/theming@0.1.1-beta.19) (2022-02-12)
|
|
55
|
+
|
|
56
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
57
|
+
|
|
58
|
+
## [0.1.1-beta.18](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.17...@animus-ui/theming@0.1.1-beta.18) (2022-02-11)
|
|
59
|
+
|
|
60
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
61
|
+
|
|
62
|
+
## [0.1.1-beta.17](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.16...@animus-ui/theming@0.1.1-beta.17) (2022-02-02)
|
|
63
|
+
|
|
64
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
65
|
+
|
|
66
|
+
## [0.1.1-beta.16](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.15...@animus-ui/theming@0.1.1-beta.16) (2022-02-02)
|
|
67
|
+
|
|
68
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
69
|
+
|
|
70
|
+
## [0.1.1-beta.15](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.14...@animus-ui/theming@0.1.1-beta.15) (2022-01-26)
|
|
71
|
+
|
|
72
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
73
|
+
|
|
74
|
+
## [0.1.1-beta.14](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.13...@animus-ui/theming@0.1.1-beta.14) (2022-01-24)
|
|
31
75
|
|
|
32
76
|
**Note:** Version bump only for package @animus-ui/theming
|
|
33
77
|
|
|
78
|
+
## [0.1.1-beta.13](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.12...@animus-ui/theming@0.1.1-beta.13) (2022-01-24)
|
|
34
79
|
|
|
80
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
35
81
|
|
|
82
|
+
## [0.1.1-beta.12](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.11...@animus-ui/theming@0.1.1-beta.12) (2022-01-24)
|
|
83
|
+
|
|
84
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
36
85
|
|
|
86
|
+
## [0.1.1-beta.11](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.10...@animus-ui/theming@0.1.1-beta.11) (2022-01-24)
|
|
87
|
+
|
|
88
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
89
|
+
|
|
90
|
+
## [0.1.1-beta.10](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.9...@animus-ui/theming@0.1.1-beta.10) (2022-01-23)
|
|
91
|
+
|
|
92
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
93
|
+
|
|
94
|
+
## [0.1.1-beta.9](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.8...@animus-ui/theming@0.1.1-beta.9) (2022-01-18)
|
|
95
|
+
|
|
96
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
97
|
+
|
|
98
|
+
## [0.1.1-beta.8](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.7...@animus-ui/theming@0.1.1-beta.8) (2022-01-16)
|
|
99
|
+
|
|
100
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
101
|
+
|
|
102
|
+
## [0.1.1-beta.7](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.6...@animus-ui/theming@0.1.1-beta.7) (2022-01-16)
|
|
103
|
+
|
|
104
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
105
|
+
|
|
106
|
+
## [0.1.1-beta.6](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.5...@animus-ui/theming@0.1.1-beta.6) (2022-01-11)
|
|
107
|
+
|
|
108
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
109
|
+
|
|
110
|
+
## [0.1.1-beta.5](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.4...@animus-ui/theming@0.1.1-beta.5) (2022-01-09)
|
|
111
|
+
|
|
112
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
113
|
+
|
|
114
|
+
## [0.1.1-beta.4](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.3...@animus-ui/theming@0.1.1-beta.4) (2022-01-09)
|
|
115
|
+
|
|
116
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
117
|
+
|
|
118
|
+
## [0.1.1-beta.3](https://github.com/codecaaron/animus/compare/@animus-ui/theming@0.1.1-beta.2...@animus-ui/theming@0.1.1-beta.3) (2022-01-09)
|
|
119
|
+
|
|
120
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
121
|
+
|
|
122
|
+
## 0.1.1-beta.2 (2022-01-09)
|
|
123
|
+
|
|
124
|
+
## 0.1.1-beta.1 (2022-01-09)
|
|
125
|
+
|
|
126
|
+
## 0.1.1-beta.0 (2022-01-09)
|
|
127
|
+
|
|
128
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
129
|
+
|
|
130
|
+
## [0.1.1-beta.1](https://github.com/codecaaron/animus/compare/v0.1.1-beta.0...v0.1.1-beta.1) (2022-01-09)
|
|
131
|
+
|
|
132
|
+
**Note:** Version bump only for package @animus-ui/theming
|
|
37
133
|
|
|
38
134
|
## 0.1.1-beta.0 (2022-01-09)
|
|
39
135
|
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# ThemeBuilder Architecture & Animus Integration
|
|
2
|
+
|
|
3
|
+
This document captures deep architectural insights about the ThemeBuilder system and its integration with the Animus builder from the core package.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [ThemeBuilder Architecture](#themebuilder-architecture)
|
|
8
|
+
2. [Design Token Resolution Process](#design-token-resolution-process)
|
|
9
|
+
3. [Animus Builder Integration](#animus-builder-integration)
|
|
10
|
+
4. [Critical Integration Points](#critical-integration-points)
|
|
11
|
+
5. [Recommendations & Improvements](#recommendations--improvements)
|
|
12
|
+
6. [Open Questions](#open-questions)
|
|
13
|
+
|
|
14
|
+
## ThemeBuilder Architecture
|
|
15
|
+
|
|
16
|
+
### Overview
|
|
17
|
+
|
|
18
|
+
The ThemeBuilder provides a fluent, type-safe API for building themes with design tokens, CSS variables, and color modes. It follows a Producer-Consumer pattern where ThemeBuilder produces theme configuration and Animus consumes it via Emotion's ThemeProvider.
|
|
19
|
+
|
|
20
|
+
### Core Components
|
|
21
|
+
|
|
22
|
+
#### 1. Current ThemeBuilder Implementation (`createTheme.ts`)
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
export class ThemeBuilder<T extends AbstractTheme> {
|
|
26
|
+
#theme = {} as T;
|
|
27
|
+
|
|
28
|
+
constructor(baseTheme: T) { /* ... */ }
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Key Methods:**
|
|
33
|
+
- `createScaleVariables(key)` - Transforms theme scales into CSS variables
|
|
34
|
+
- `addColors(colors)` - Adds color tokens to the theme
|
|
35
|
+
- `addColorModes(initialMode, modeConfig)` - Implements color mode switching
|
|
36
|
+
- `addScale(key, createScale)` - Adds new scale to the theme
|
|
37
|
+
- `updateScale(key, updateFn)` - Updates existing scale values
|
|
38
|
+
- `build()` - Finalizes the theme
|
|
39
|
+
|
|
40
|
+
#### 2. Legacy ThemeBuilder (`ThemeBuilder.ts`)
|
|
41
|
+
|
|
42
|
+
Uses class inheritance hierarchy:
|
|
43
|
+
```
|
|
44
|
+
ThemeUnitialized → ThemeWithBreakpoints → ThemeWithRawColors → ThemeWithAll
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Theme Object Structure
|
|
48
|
+
|
|
49
|
+
The built theme contains three critical structures:
|
|
50
|
+
|
|
51
|
+
1. **Public Scales** (e.g., `theme.colors`): CSS variable references (`'var(--colors-primary)'`)
|
|
52
|
+
2. **Private Variables** (`theme._variables`): CSS variable definitions
|
|
53
|
+
3. **Private Tokens** (`theme._tokens`): Original values (currently redundant)
|
|
54
|
+
|
|
55
|
+
## Design Token Resolution Process
|
|
56
|
+
|
|
57
|
+
### 1. Token Definition Phase
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
createTheme(baseTheme)
|
|
61
|
+
.addColors({ primary: '#007bff' })
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. Serialization Phase
|
|
65
|
+
|
|
66
|
+
The `serializeTokens` function creates:
|
|
67
|
+
- **Token References**: `{ primary: 'var(--colors-primary)' }`
|
|
68
|
+
- **Token Variables**: `{ '--colors-primary': '#007bff' }`
|
|
69
|
+
|
|
70
|
+
### 3. Storage Phase
|
|
71
|
+
|
|
72
|
+
- `theme.colors.primary` = `'var(--colors-primary)'`
|
|
73
|
+
- `theme._variables.root['--colors-primary']` = `'#007bff'`
|
|
74
|
+
- `theme._tokens.colors.primary` = `'#007bff'`
|
|
75
|
+
|
|
76
|
+
### 4. Injection Phase (Critical Gap)
|
|
77
|
+
|
|
78
|
+
**Currently missing**: A mechanism to inject CSS variables into the DOM. Applications must implement:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const MyGlobalStyles = () => {
|
|
82
|
+
const theme = useTheme();
|
|
83
|
+
return (
|
|
84
|
+
<Global
|
|
85
|
+
styles={css`
|
|
86
|
+
:root {
|
|
87
|
+
/* Inject theme._variables.root here */
|
|
88
|
+
}
|
|
89
|
+
`}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 5. Component Usage Phase
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
<MyComponent color="primary" />
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 6. Style Resolution Phase
|
|
102
|
+
|
|
103
|
+
1. `createPropertyStyle` invoked for `color` prop
|
|
104
|
+
2. Calls `lookupScaleValue('primary', 'colors', theme)`
|
|
105
|
+
3. Returns `'var(--colors-primary)'`
|
|
106
|
+
4. Emotion generates CSS: `color: var(--colors-primary);`
|
|
107
|
+
|
|
108
|
+
### 7. Browser Resolution Phase
|
|
109
|
+
|
|
110
|
+
Browser applies styles using CSS Custom Properties from injected variables.
|
|
111
|
+
|
|
112
|
+
## Animus Builder Integration
|
|
113
|
+
|
|
114
|
+
### Architecture Overview
|
|
115
|
+
|
|
116
|
+
Animus uses a class hierarchy with fluent API:
|
|
117
|
+
```
|
|
118
|
+
Animus → AnimusWithBase → AnimusWithVariants → AnimusWithStates → AnimusWithSystem → AnimusWithAll
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Integration Points
|
|
122
|
+
|
|
123
|
+
1. **Theme Access**: Animus components receive theme via Emotion's ThemeProvider
|
|
124
|
+
2. **Scale Lookup**: `lookupScaleValue` resolves theme values from scales
|
|
125
|
+
3. **CSS Variable Support**: Animus treats CSS variable strings as opaque values
|
|
126
|
+
4. **Responsive Breakpoints**: Both systems use `theme.breakpoints` for media queries
|
|
127
|
+
|
|
128
|
+
### Value Resolution Flow
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
Component Prop → createPropertyStyle → lookupScaleValue → Theme Scale → CSS Variable → Browser
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Critical Integration Points
|
|
135
|
+
|
|
136
|
+
### 1. Scale Value Resolution
|
|
137
|
+
|
|
138
|
+
The `lookupScaleValue` function in core/src/scales/lookupScaleValue.ts:
|
|
139
|
+
- Resolves values from theme scales
|
|
140
|
+
- Falls back to compatTheme
|
|
141
|
+
- **Limitation**: Doesn't support negative values (e.g., `m="-4"`)
|
|
142
|
+
|
|
143
|
+
### 2. Responsive Values
|
|
144
|
+
|
|
145
|
+
- **ThemeBuilder**: Creates breakpoint CSS variables
|
|
146
|
+
- **Animus**: Uses breakpoints for media query generation
|
|
147
|
+
- Both systems must coordinate on breakpoint definitions
|
|
148
|
+
|
|
149
|
+
### 3. Color Modes
|
|
150
|
+
|
|
151
|
+
Current implementation has complexity:
|
|
152
|
+
- `_variables.mode` contains initial mode values
|
|
153
|
+
- `_tokens.modes` structure unclear
|
|
154
|
+
- Application responsible for mode switching logic
|
|
155
|
+
|
|
156
|
+
## Recommendations & Improvements
|
|
157
|
+
|
|
158
|
+
### 1. Simplify Theme Contract
|
|
159
|
+
|
|
160
|
+
Remove `_tokens` from final output, keeping only:
|
|
161
|
+
- **Public Scales**: CSS variable references
|
|
162
|
+
- **Private Variables**: CSS variable definitions
|
|
163
|
+
|
|
164
|
+
### 2. Provide Global Styles Utility
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
export const createGlobalStyles = (theme) => {
|
|
168
|
+
const { root, modes } = theme._variables;
|
|
169
|
+
|
|
170
|
+
return css`
|
|
171
|
+
:root {
|
|
172
|
+
${varsToCss(root)}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
${Object.entries(modes).map(([mode, vars]) => `
|
|
176
|
+
[data-theme='${mode}'] {
|
|
177
|
+
${varsToCss(vars)}
|
|
178
|
+
}
|
|
179
|
+
`).join('')}
|
|
180
|
+
`;
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 3. Support Negative Values
|
|
185
|
+
|
|
186
|
+
Update `lookupScaleValue` to handle string-prefixed negatives:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
if (isString(val) && val.startsWith('-')) {
|
|
190
|
+
const positiveKey = val.substring(1);
|
|
191
|
+
const scaleValue = get(usedScale, positiveKey);
|
|
192
|
+
|
|
193
|
+
if (isString(scaleValue) || isNumber(scaleValue)) {
|
|
194
|
+
return `-${scaleValue}`;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 4. Improve Color Mode Architecture
|
|
200
|
+
|
|
201
|
+
Restructure `_variables` for clarity:
|
|
202
|
+
```typescript
|
|
203
|
+
{
|
|
204
|
+
_variables: {
|
|
205
|
+
root: { /* base tokens */ },
|
|
206
|
+
modes: {
|
|
207
|
+
light: { /* semantic aliases */ },
|
|
208
|
+
dark: { /* semantic aliases */ }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### 5. Type Safety Enhancements
|
|
215
|
+
|
|
216
|
+
- Create comprehensive type tests for chained builder calls
|
|
217
|
+
- Provide `GetAnimusProps<T>` utility type
|
|
218
|
+
- Make `build()` method generic for better inference
|
|
219
|
+
|
|
220
|
+
## Open Questions
|
|
221
|
+
|
|
222
|
+
### Critical Architecture Questions
|
|
223
|
+
|
|
224
|
+
1. **Variable Injection Strategy**: Should we provide an official `ThemeProvider` wrapper that handles CSS variable injection automatically?
|
|
225
|
+
- Current gap: Apps must manually inject `theme._variables` into DOM
|
|
226
|
+
- Consideration: Auto-injection could simplify setup but reduce flexibility
|
|
227
|
+
|
|
228
|
+
2. **Migration Path**: How do we support gradual migration from literal-value themes to CSS-variable-based themes?
|
|
229
|
+
- Challenge: Mixed themes with both literal values and CSS variables
|
|
230
|
+
- Need: Clear documentation and tooling for incremental adoption
|
|
231
|
+
|
|
232
|
+
3. **Performance Optimization**: Is the extensive use of `lodash.merge` in builder chains a performance concern?
|
|
233
|
+
- Impact: Each builder method creates new merged objects
|
|
234
|
+
- Alternative: Investigate more performant merge strategies or lazy evaluation
|
|
235
|
+
|
|
236
|
+
4. **Type Complexity**: How can we simplify the generic type chains while maintaining type safety?
|
|
237
|
+
- Current: Heavy generic usage can create complex error messages
|
|
238
|
+
- Goal: Better developer experience with clearer type errors
|
|
239
|
+
|
|
240
|
+
### Integration Improvements
|
|
241
|
+
|
|
242
|
+
5. **Negative Value Support**: Should negative values use string prefix pattern (like Chakra UI)?
|
|
243
|
+
- Current: `lookupScaleValue` doesn't support negative theme values
|
|
244
|
+
- Proposed: Support `m="-4"` syntax for negative margins
|
|
245
|
+
|
|
246
|
+
6. **Color Mode Architecture**: Should we simplify the current three-source-of-truth pattern?
|
|
247
|
+
- Current: `_variables`, `_tokens`, and public scales create confusion
|
|
248
|
+
- Proposed: Eliminate `_tokens` from final build output
|
|
249
|
+
|
|
250
|
+
7. **Responsive Value Coordination**: How to ensure array/object responsive syntax works consistently?
|
|
251
|
+
- Need: Integration tests between ThemeBuilder breakpoints and Animus responsive arrays
|
|
252
|
+
- Challenge: Both systems must coordinate on breakpoint definitions
|
|
253
|
+
|
|
254
|
+
### Developer Experience
|
|
255
|
+
|
|
256
|
+
8. **Official Global Styles Utility**: Should we provide `createGlobalStyles` helper?
|
|
257
|
+
- Benefit: Standardized way to inject CSS variables
|
|
258
|
+
- Implementation: Could be part of @animus-ui/theming package
|
|
259
|
+
|
|
260
|
+
9. **Theme Structure Validation**: Should we validate theme structure at runtime?
|
|
261
|
+
- Use case: Catch missing CSS variable injections early
|
|
262
|
+
- Trade-off: Runtime validation vs. bundle size
|
|
263
|
+
|
|
264
|
+
10. **Documentation Gaps**: Which patterns need more comprehensive examples?
|
|
265
|
+
- Compound components with theming
|
|
266
|
+
- Global styles and CSS resets
|
|
267
|
+
- Performance optimization patterns
|
|
268
|
+
- Common UI patterns (modals, dropdowns, forms)
|
|
269
|
+
|
|
270
|
+
### Technical Debt
|
|
271
|
+
|
|
272
|
+
11. **Legacy ThemeBuilder**: Should we deprecate the class inheritance version?
|
|
273
|
+
- Current: Two implementations create confusion
|
|
274
|
+
- Migration: Need clear upgrade path for existing users
|
|
275
|
+
|
|
276
|
+
12. **Theme Contract Clarity**: How to better document the theme object contract?
|
|
277
|
+
- Issue: Unclear when to use `_variables` vs `_tokens` vs public scales
|
|
278
|
+
- Solution: Clearer separation of concerns in documentation
|
|
279
|
+
|
|
280
|
+
### New Questions from Real-World Usage Analysis
|
|
281
|
+
|
|
282
|
+
13. **Gradient Token System**: How should gradient tokens be defined in ThemeBuilder?
|
|
283
|
+
- Observed: Components use `gradient: 'flowX'` tokens
|
|
284
|
+
- Need: Clear pattern for defining complex gradient tokens as CSS variables
|
|
285
|
+
|
|
286
|
+
14. **Numeric Value Normalization**: How do numeric theme values (0, 1, 0.5) map to CSS?
|
|
287
|
+
- Observed: `width: 1`, `size: 1`, `left: 0.5` in components
|
|
288
|
+
- Question: Is this a percentage system or theme scale reference?
|
|
289
|
+
|
|
290
|
+
15. **Semantic Token Categories**: What token categories should ThemeBuilder support?
|
|
291
|
+
- Observed: text-shadow tokens ('flush', 'link-raised')
|
|
292
|
+
- Observed: gradient tokens ('flowX')
|
|
293
|
+
- Question: How to organize non-standard CSS tokens?
|
|
294
|
+
|
|
295
|
+
16. **WebKit-Specific Properties**: Should ThemeBuilder handle vendor prefixes?
|
|
296
|
+
- Observed: `WebkitTextFillColor`, `WebkitBackgroundClip` usage
|
|
297
|
+
- Challenge: CSS variables with vendor prefixes
|
|
298
|
+
|
|
299
|
+
17. **Grid Template Token Support**: Should grid templates be tokenized?
|
|
300
|
+
- Observed: Complex responsive grid templates in Layout
|
|
301
|
+
- Consideration: Token vs. inline definition trade-offs
|
|
302
|
+
|
|
303
|
+
18. **Animation Token Integration**: How should keyframe animations work with tokens?
|
|
304
|
+
- Observed: Imported keyframes used with Animus styles
|
|
305
|
+
- Question: Can animations reference theme tokens?
|
|
306
|
+
|
|
307
|
+
19. **Performance Benchmarks**: What's the performance impact of CSS variables?
|
|
308
|
+
- Heavy use of pseudo-elements with gradient variables
|
|
309
|
+
- Need: Benchmarks comparing literal values vs. CSS variables
|
|
310
|
+
|
|
311
|
+
20. **Custom Property Mappings**: Should ThemeBuilder know about Animus prop shorthands?
|
|
312
|
+
- Observed: `area` → `gridArea`, `gradient` → complex gradient
|
|
313
|
+
- Question: Where should this mapping knowledge live?
|
|
314
|
+
|
|
315
|
+
## Technical Notes
|
|
316
|
+
|
|
317
|
+
### Key Files
|
|
318
|
+
|
|
319
|
+
- `/packages/theming/src/utils/createTheme.ts` - Main builder implementation
|
|
320
|
+
- `/packages/theming/src/utils/serializeTokens.ts` - CSS variable generation
|
|
321
|
+
- `/packages/theming/src/utils/flattenScale.ts` - Object flattening utilities
|
|
322
|
+
- `/packages/core/src/scales/lookupScaleValue.ts` - Theme value resolution
|
|
323
|
+
- `/packages/core/src/Animus.ts` - Style builder integration
|
|
324
|
+
|
|
325
|
+
### Dependencies
|
|
326
|
+
|
|
327
|
+
- Emotion for CSS-in-JS and theming
|
|
328
|
+
- Lodash for object manipulation
|
|
329
|
+
- TypeScript for type safety
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
*Last Updated: January 2025*
|
|
334
|
+
*Analysis based on deep architectural review and integration testing*
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { Breakpoints } from '@animus-ui/core';
|
|
2
|
-
/**
|
|
3
|
-
* 1. Breakpoints
|
|
4
|
-
* 2. Scales
|
|
5
|
-
* 3. Tokens
|
|
6
|
-
* 4. Variables
|
|
7
|
-
* 5. Colors
|
|
8
|
-
* 6. Color Modes
|
|
9
|
-
*/
|
|
10
|
-
export declare class ThemeWithAll<Bps, Scales, Tokens, Vars> {
|
|
11
|
-
breakpoints: Bps;
|
|
12
|
-
scales: Scales;
|
|
13
|
-
tokens: Tokens;
|
|
14
|
-
variables: Vars;
|
|
15
|
-
constructor(breakpoints: Bps, scales: Scales, tokens: Tokens, vars: Vars);
|
|
16
|
-
addScale(): ThemeWithAll<Bps, Scales, Tokens, Vars>;
|
|
17
|
-
build(): {
|
|
18
|
-
breakpoints: Bps;
|
|
19
|
-
} & Scales & {
|
|
20
|
-
_tokens: Tokens;
|
|
21
|
-
_variables: Vars;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
export declare class ThemeWithRawColors<Bps extends Breakpoints, Scales, Tokens, Vars> extends ThemeWithAll<Bps, Scales, Tokens, Vars> {
|
|
25
|
-
constructor(breakpoints: Bps, scales: Scales, tokens: Tokens, vars: Vars);
|
|
26
|
-
addColorModes(): ThemeWithAll<Bps, Scales, Tokens, Vars>;
|
|
27
|
-
}
|
|
28
|
-
export declare class ThemeWithBreakpoints<Bps extends Breakpoints> extends ThemeWithAll<Bps, {}, {}, {}> {
|
|
29
|
-
constructor(breakpoints: Bps);
|
|
30
|
-
addColors(): ThemeWithRawColors<Bps, {}, {}, {}>;
|
|
31
|
-
}
|
|
32
|
-
export declare class ThemeUnitialized {
|
|
33
|
-
addBreakpoints<Bps extends Breakpoints>(breakpoints: Bps): ThemeWithBreakpoints<Bps>;
|
|
34
|
-
}
|
|
1
|
+
import { Breakpoints } from '@animus-ui/core';
|
|
2
|
+
/**
|
|
3
|
+
* 1. Breakpoints
|
|
4
|
+
* 2. Scales
|
|
5
|
+
* 3. Tokens
|
|
6
|
+
* 4. Variables
|
|
7
|
+
* 5. Colors
|
|
8
|
+
* 6. Color Modes
|
|
9
|
+
*/
|
|
10
|
+
export declare class ThemeWithAll<Bps, Scales, Tokens, Vars> {
|
|
11
|
+
breakpoints: Bps;
|
|
12
|
+
scales: Scales;
|
|
13
|
+
tokens: Tokens;
|
|
14
|
+
variables: Vars;
|
|
15
|
+
constructor(breakpoints: Bps, scales: Scales, tokens: Tokens, vars: Vars);
|
|
16
|
+
addScale(): ThemeWithAll<Bps, Scales, Tokens, Vars>;
|
|
17
|
+
build(): {
|
|
18
|
+
breakpoints: Bps;
|
|
19
|
+
} & Scales & {
|
|
20
|
+
_tokens: Tokens;
|
|
21
|
+
_variables: Vars;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare class ThemeWithRawColors<Bps extends Breakpoints, Scales, Tokens, Vars> extends ThemeWithAll<Bps, Scales, Tokens, Vars> {
|
|
25
|
+
constructor(breakpoints: Bps, scales: Scales, tokens: Tokens, vars: Vars);
|
|
26
|
+
addColorModes(): ThemeWithAll<Bps, Scales, Tokens, Vars>;
|
|
27
|
+
}
|
|
28
|
+
export declare class ThemeWithBreakpoints<Bps extends Breakpoints> extends ThemeWithAll<Bps, {}, {}, {}> {
|
|
29
|
+
constructor(breakpoints: Bps);
|
|
30
|
+
addColors(): ThemeWithRawColors<Bps, {}, {}, {}>;
|
|
31
|
+
}
|
|
32
|
+
export declare class ThemeUnitialized {
|
|
33
|
+
addBreakpoints<Bps extends Breakpoints>(breakpoints: Bps): ThemeWithBreakpoints<Bps>;
|
|
34
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './utils';
|
|
1
|
+
export * from './utils';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { isObject, merge, mapValues } from 'lodash';
|
|
2
|
+
|
|
3
|
+
function _assertClassBrand(e, t, n) {
|
|
4
|
+
if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
|
|
5
|
+
throw new TypeError("Private element is not present on this object");
|
|
6
|
+
}
|
|
7
|
+
function _checkPrivateRedeclaration(e, t) {
|
|
8
|
+
if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
9
|
+
}
|
|
10
|
+
function _classCallCheck(a, n) {
|
|
11
|
+
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
|
|
12
|
+
}
|
|
13
|
+
function _classPrivateFieldGet2(s, a) {
|
|
14
|
+
return s.get(_assertClassBrand(s, a));
|
|
15
|
+
}
|
|
16
|
+
function _classPrivateFieldInitSpec(e, t, a) {
|
|
17
|
+
_checkPrivateRedeclaration(e, t), t.set(e, a);
|
|
18
|
+
}
|
|
19
|
+
function _defineProperties(e, r) {
|
|
20
|
+
for (var t = 0; t < r.length; t++) {
|
|
21
|
+
var o = r[t];
|
|
22
|
+
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function _createClass(e, r, t) {
|
|
26
|
+
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
|
|
27
|
+
writable: !1
|
|
28
|
+
}), e;
|
|
29
|
+
}
|
|
30
|
+
function _defineProperty(e, r, t) {
|
|
31
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
32
|
+
value: t,
|
|
33
|
+
enumerable: !0,
|
|
34
|
+
configurable: !0,
|
|
35
|
+
writable: !0
|
|
36
|
+
}) : e[r] = t, e;
|
|
37
|
+
}
|
|
38
|
+
function ownKeys(e, r) {
|
|
39
|
+
var t = Object.keys(e);
|
|
40
|
+
if (Object.getOwnPropertySymbols) {
|
|
41
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
42
|
+
r && (o = o.filter(function (r) {
|
|
43
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
44
|
+
})), t.push.apply(t, o);
|
|
45
|
+
}
|
|
46
|
+
return t;
|
|
47
|
+
}
|
|
48
|
+
function _objectSpread2(e) {
|
|
49
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
50
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
51
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
|
52
|
+
_defineProperty(e, r, t[r]);
|
|
53
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
54
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return e;
|
|
58
|
+
}
|
|
59
|
+
function _objectWithoutProperties(e, t) {
|
|
60
|
+
if (null == e) return {};
|
|
61
|
+
var o,
|
|
62
|
+
r,
|
|
63
|
+
i = _objectWithoutPropertiesLoose(e, t);
|
|
64
|
+
if (Object.getOwnPropertySymbols) {
|
|
65
|
+
var n = Object.getOwnPropertySymbols(e);
|
|
66
|
+
for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
|
67
|
+
}
|
|
68
|
+
return i;
|
|
69
|
+
}
|
|
70
|
+
function _objectWithoutPropertiesLoose(r, e) {
|
|
71
|
+
if (null == r) return {};
|
|
72
|
+
var t = {};
|
|
73
|
+
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
|
74
|
+
if (-1 !== e.indexOf(n)) continue;
|
|
75
|
+
t[n] = r[n];
|
|
76
|
+
}
|
|
77
|
+
return t;
|
|
78
|
+
}
|
|
79
|
+
function _toPrimitive(t, r) {
|
|
80
|
+
if ("object" != typeof t || !t) return t;
|
|
81
|
+
var e = t[Symbol.toPrimitive];
|
|
82
|
+
if (void 0 !== e) {
|
|
83
|
+
var i = e.call(t, r || "default");
|
|
84
|
+
if ("object" != typeof i) return i;
|
|
85
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
86
|
+
}
|
|
87
|
+
return ("string" === r ? String : Number)(t);
|
|
88
|
+
}
|
|
89
|
+
function _toPropertyKey(t) {
|
|
90
|
+
var i = _toPrimitive(t, "string");
|
|
91
|
+
return "symbol" == typeof i ? i : i + "";
|
|
92
|
+
}
|
|
93
|
+
function _classApplyDescriptorGet(e, t) {
|
|
94
|
+
return t.get ? t.get.call(e) : t.value;
|
|
95
|
+
}
|
|
96
|
+
function _classApplyDescriptorSet(e, t, l) {
|
|
97
|
+
if (t.set) t.set.call(e, l);else {
|
|
98
|
+
if (!t.writable) throw new TypeError("attempted to set read only private field");
|
|
99
|
+
t.value = l;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function _classPrivateFieldGet(e, t) {
|
|
103
|
+
var r = _classPrivateFieldGet2(t, e);
|
|
104
|
+
return _classApplyDescriptorGet(e, r);
|
|
105
|
+
}
|
|
106
|
+
function _classPrivateFieldSet(e, t, r) {
|
|
107
|
+
var s = _classPrivateFieldGet2(t, e);
|
|
108
|
+
return _classApplyDescriptorSet(e, s, r), r;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function flattenScale(object, path) {
|
|
112
|
+
return Object.keys(object).reduce(function (carry, key) {
|
|
113
|
+
var nextKey = path ? "".concat(path).concat(key === '_' ? '' : "-".concat(key)) : key;
|
|
114
|
+
var current = object[key];
|
|
115
|
+
if (isObject(current)) {
|
|
116
|
+
return _objectSpread2(_objectSpread2({}, carry), flattenScale(current, nextKey));
|
|
117
|
+
}
|
|
118
|
+
return _objectSpread2(_objectSpread2({}, carry), {}, _defineProperty({}, nextKey, object[key]));
|
|
119
|
+
}, {});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var _excluded = ["_"];
|
|
123
|
+
var templateBreakpoints = function templateBreakpoints(value, alias, theme) {
|
|
124
|
+
if (isObject(value)) {
|
|
125
|
+
var _ = value._,
|
|
126
|
+
rest = _objectWithoutProperties(value, _excluded);
|
|
127
|
+
var css = _defineProperty({}, alias, _);
|
|
128
|
+
if (theme) {
|
|
129
|
+
var breakpoints = theme.breakpoints;
|
|
130
|
+
Object.keys(breakpoints).forEach(function (key) {
|
|
131
|
+
if (rest[key]) {
|
|
132
|
+
css[breakpoints[key]] = _defineProperty({}, alias, rest[key]);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return css;
|
|
137
|
+
}
|
|
138
|
+
return _defineProperty({}, alias, value);
|
|
139
|
+
};
|
|
140
|
+
var serializeTokens = function serializeTokens(tokens, prefix, theme) {
|
|
141
|
+
var tokenReferences = {};
|
|
142
|
+
var tokenVariables = {};
|
|
143
|
+
Object.keys(tokens).forEach(function (key) {
|
|
144
|
+
var varName = "--".concat(prefix, "-").concat(key.replace('$', ''));
|
|
145
|
+
tokenReferences[key] = "var(".concat(varName, ")");
|
|
146
|
+
merge(tokenVariables, templateBreakpoints(tokens[key], varName, theme));
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
tokens: tokenReferences,
|
|
150
|
+
variables: tokenVariables
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
var _theme = /*#__PURE__*/new WeakMap();
|
|
155
|
+
var ThemeBuilder = /*#__PURE__*/function () {
|
|
156
|
+
function ThemeBuilder(baseTheme) {
|
|
157
|
+
_classCallCheck(this, ThemeBuilder);
|
|
158
|
+
_classPrivateFieldInitSpec(this, _theme, {
|
|
159
|
+
writable: true,
|
|
160
|
+
value: {}
|
|
161
|
+
});
|
|
162
|
+
_classPrivateFieldSet(this, _theme, baseTheme);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
*
|
|
166
|
+
* @param key A key of the current theme to transform into CSS Variables and Variable References
|
|
167
|
+
* @example .createScaleVariables('fontSize')
|
|
168
|
+
*/
|
|
169
|
+
_createClass(ThemeBuilder, [{
|
|
170
|
+
key: "createScaleVariables",
|
|
171
|
+
value: function createScaleVariables(key) {
|
|
172
|
+
var _merge;
|
|
173
|
+
var _serializeTokens = serializeTokens(_classPrivateFieldGet(this, _theme)[key], key, _classPrivateFieldGet(this, _theme)),
|
|
174
|
+
variables = _serializeTokens.variables,
|
|
175
|
+
tokens = _serializeTokens.tokens;
|
|
176
|
+
_classPrivateFieldSet(this, _theme, merge({}, _classPrivateFieldGet(this, _theme), (_merge = {}, _defineProperty(_merge, key, tokens), _defineProperty(_merge, "_variables", _defineProperty({}, key, variables)), _defineProperty(_merge, "_tokens", _defineProperty({}, key, _classPrivateFieldGet(this, _theme)[key])), _merge)));
|
|
177
|
+
return this;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
*
|
|
181
|
+
* @param colors A map of color tokens to add to the theme. These tokens are immediately converted to CSS Variables `--color-${key}`.
|
|
182
|
+
* @example .addColors({ navy: 'navy', hyper: 'purple' })
|
|
183
|
+
*/
|
|
184
|
+
}, {
|
|
185
|
+
key: "addColors",
|
|
186
|
+
value: function addColors(colors) {
|
|
187
|
+
var flatColors = flattenScale(colors);
|
|
188
|
+
var _serializeTokens2 = serializeTokens(flatColors, 'color', _classPrivateFieldGet(this, _theme)),
|
|
189
|
+
variables = _serializeTokens2.variables,
|
|
190
|
+
tokens = _serializeTokens2.tokens;
|
|
191
|
+
_classPrivateFieldSet(this, _theme, merge({}, _classPrivateFieldGet(this, _theme), {
|
|
192
|
+
colors: tokens,
|
|
193
|
+
_variables: {
|
|
194
|
+
root: variables
|
|
195
|
+
},
|
|
196
|
+
_tokens: {
|
|
197
|
+
colors: flatColors
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
*
|
|
204
|
+
* @param initialMode A key of the object passed for modes. This sets the default state for the theme and transforms the correct variables.
|
|
205
|
+
* @param modes A map of color modes with keys of each possible mode with a value of alias to color keys. This must be called after `addColors`
|
|
206
|
+
* @example .addColorModes('light', { light: { primary: 'hyper' }, { dark: { primary: 'navy' } } })
|
|
207
|
+
*/
|
|
208
|
+
}, {
|
|
209
|
+
key: "addColorModes",
|
|
210
|
+
value: function addColorModes(initialMode, modeConfig) {
|
|
211
|
+
var _classPrivateFieldGet2,
|
|
212
|
+
_this = this;
|
|
213
|
+
var modes = mapValues(modeConfig, function (mode) {
|
|
214
|
+
return flattenScale(mode);
|
|
215
|
+
});
|
|
216
|
+
var _serializeTokens3 = serializeTokens(mapValues(merge({}, (_classPrivateFieldGet2 = _classPrivateFieldGet(this, _theme).modes) === null || _classPrivateFieldGet2 === void 0 ? void 0 : _classPrivateFieldGet2[initialMode], modes[initialMode]), function (color) {
|
|
217
|
+
return _classPrivateFieldGet(_this, _theme).colors[color];
|
|
218
|
+
}), 'color', _classPrivateFieldGet(this, _theme)),
|
|
219
|
+
colors = _serializeTokens3.tokens,
|
|
220
|
+
variables = _serializeTokens3.variables;
|
|
221
|
+
var getColorValue = function getColorValue(color) {
|
|
222
|
+
var _classPrivateFieldGet3, _classPrivateFieldGet4;
|
|
223
|
+
return (_classPrivateFieldGet3 = _classPrivateFieldGet(_this, _theme)._tokens) === null || _classPrivateFieldGet3 === void 0 ? void 0 : (_classPrivateFieldGet4 = _classPrivateFieldGet3.colors) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4[color];
|
|
224
|
+
};
|
|
225
|
+
_classPrivateFieldSet(this, _theme, merge({}, _classPrivateFieldGet(this, _theme), {
|
|
226
|
+
colors: colors,
|
|
227
|
+
modes: modes,
|
|
228
|
+
mode: initialMode,
|
|
229
|
+
_getColorValue: getColorValue,
|
|
230
|
+
_variables: {
|
|
231
|
+
mode: variables
|
|
232
|
+
},
|
|
233
|
+
_tokens: {
|
|
234
|
+
modes: mapValues(modes, function (mode) {
|
|
235
|
+
return mapValues(mode, getColorValue);
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
}));
|
|
239
|
+
return this;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
*
|
|
243
|
+
* @param key A new key of theme
|
|
244
|
+
* @param createScale A function that accepts the current theme and returns a new object of scale values.
|
|
245
|
+
* @example .addScale('fonts', () => ({ basic: 'Gotham', cool: 'Wingdings' }))
|
|
246
|
+
*/
|
|
247
|
+
}, {
|
|
248
|
+
key: "addScale",
|
|
249
|
+
value: function addScale(key, createScale) {
|
|
250
|
+
_classPrivateFieldSet(this, _theme, merge({}, _classPrivateFieldGet(this, _theme), _defineProperty({}, key, flattenScale(createScale(_classPrivateFieldGet(this, _theme))))));
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
*
|
|
255
|
+
* @param key A current key of theme to be updated with new or computed values
|
|
256
|
+
* @param updateFn A function that accepts an argument of the current values at the specified keys an returns a map of new values to merge.
|
|
257
|
+
* @example .updateScale('fonts', ({ basic }) => ({ basicFallback: `{basic}, Montserrat` }))
|
|
258
|
+
*/
|
|
259
|
+
}, {
|
|
260
|
+
key: "updateScale",
|
|
261
|
+
value: function updateScale(key, updateFn) {
|
|
262
|
+
_classPrivateFieldSet(this, _theme, merge({}, _classPrivateFieldGet(this, _theme), _defineProperty({}, key, updateFn(_classPrivateFieldGet(this, _theme)[key]))));
|
|
263
|
+
return this;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* This finalizes the theme build and returns the final theme and variables to be provided.
|
|
267
|
+
*/
|
|
268
|
+
}, {
|
|
269
|
+
key: "build",
|
|
270
|
+
value: function build() {
|
|
271
|
+
var _serializeTokens4 = serializeTokens(mapValues(_classPrivateFieldGet(this, _theme).breakpoints, function (val) {
|
|
272
|
+
return "".concat(val, "px");
|
|
273
|
+
}), 'breakpoint', _classPrivateFieldGet(this, _theme)),
|
|
274
|
+
variables = _serializeTokens4.variables;
|
|
275
|
+
return merge({}, _classPrivateFieldGet(this, _theme), {
|
|
276
|
+
_variables: {
|
|
277
|
+
breakpoints: variables
|
|
278
|
+
},
|
|
279
|
+
_tokens: {}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}]);
|
|
283
|
+
return ThemeBuilder;
|
|
284
|
+
}();
|
|
285
|
+
function createTheme(base) {
|
|
286
|
+
return new ThemeBuilder(base);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export { ThemeBuilder, createTheme, flattenScale, serializeTokens };
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { LiteralPaths } from './flattenScale';
|
|
3
|
-
import { KeyAsVariable } from './serializeTokens';
|
|
4
|
-
import { ColorModeConfig, Merge, MergeTheme, PrivateThemeKeys } from './types';
|
|
5
|
-
export declare class ThemeBuilder<T extends AbstractTheme> {
|
|
6
|
-
#private;
|
|
7
|
-
constructor(baseTheme: T);
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @param key A key of the current theme to transform into CSS Variables and Variable References
|
|
11
|
-
* @example .createScaleVariables('fontSize')
|
|
12
|
-
*/
|
|
13
|
-
createScaleVariables<Key extends keyof Omit<T, 'breakpoints'> & string>(key: Key): ThemeBuilder<MergeTheme<T, PrivateThemeKeys, Record<Key, Record<Key, KeyAsVariable<T[Key], Key>>>>>;
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
* @param colors A map of color tokens to add to the theme. These tokens are immediately converted to CSS Variables `--color-${key}`.
|
|
17
|
-
* @example .addColors({ navy: 'navy', hyper: 'purple' })
|
|
18
|
-
*/
|
|
19
|
-
addColors<Colors extends Record<string, string | number | CSSObject>, NextColors extends LiteralPaths<Colors, '-'>>(colors: Colors): ThemeBuilder<MergeTheme<T & PrivateThemeKeys, Record<'colors', KeyAsVariable<NextColors, 'color'>>>>;
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
* @param initialMode A key of the object passed for modes. This sets the default state for the theme and transforms the correct variables.
|
|
23
|
-
* @param modes A map of color modes with keys of each possible mode with a value of alias to color keys. This must be called after `addColors`
|
|
24
|
-
* @example .addColorModes('light', { light: { primary: 'hyper' }, { dark: { primary: 'navy' } } })
|
|
25
|
-
*/
|
|
26
|
-
addColorModes<Modes extends string, InitialMode extends keyof Config, Colors extends keyof T['colors'], ModeColors extends ColorModeConfig<Colors>, Config extends Record<Modes, ModeColors>, ColorAliases extends {
|
|
27
|
-
[K in keyof Config]: LiteralPaths<Config[K], '-', '_'>;
|
|
28
|
-
}>(initialMode: InitialMode, modeConfig: Config): ThemeBuilder<MergeTheme<T & PrivateThemeKeys, {
|
|
29
|
-
colors: KeyAsVariable<LiteralPaths<Config[keyof Config], '-', '_'>, 'colors'> & T['colors'];
|
|
30
|
-
modes: Merge<T['modes'], ColorAliases>;
|
|
31
|
-
mode: keyof Config;
|
|
32
|
-
_getColorValue: (color: keyof T['colors']) => string;
|
|
33
|
-
}>>;
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
* @param key A new key of theme
|
|
37
|
-
* @param createScale A function that accepts the current theme and returns a new object of scale values.
|
|
38
|
-
* @example .addScale('fonts', () => ({ basic: 'Gotham', cool: 'Wingdings' }))
|
|
39
|
-
*/
|
|
40
|
-
addScale<Key extends string, Fn extends (theme: T) => Record<string | number, string | number | Record<string, string | number>>, NewScale extends LiteralPaths<ReturnType<Fn>, '-'>>(key: Key, createScale: Fn): ThemeBuilder<MergeTheme<T, Record<Key, NewScale>>>;
|
|
41
|
-
/**
|
|
42
|
-
*
|
|
43
|
-
* @param key A current key of theme to be updated with new or computed values
|
|
44
|
-
* @param updateFn A function that accepts an argument of the current values at the specified keys an returns a map of new values to merge.
|
|
45
|
-
* @example .updateScale('fonts', ({ basic }) => ({ basicFallback: `{basic}, Montserrat` }))
|
|
46
|
-
*/
|
|
47
|
-
updateScale<Key extends keyof T, Fn extends (tokens: T[Key]) => Record<string | number, unknown>>(key: Key, updateFn: Fn): ThemeBuilder<T & Record<Key, T[Key] & ReturnType<Fn>>>;
|
|
48
|
-
/**
|
|
49
|
-
* This finalizes the theme build and returns the final theme and variables to be provided.
|
|
50
|
-
*/
|
|
51
|
-
build(): T & PrivateThemeKeys;
|
|
52
|
-
}
|
|
53
|
-
export declare function createTheme<T extends AbstractTheme>(base: T): ThemeBuilder<T>;
|
|
1
|
+
import { AbstractTheme, CSSObject } from '@animus-ui/core';
|
|
2
|
+
import { LiteralPaths } from './flattenScale';
|
|
3
|
+
import { KeyAsVariable } from './serializeTokens';
|
|
4
|
+
import { ColorModeConfig, Merge, MergeTheme, PrivateThemeKeys } from './types';
|
|
5
|
+
export declare class ThemeBuilder<T extends AbstractTheme> {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(baseTheme: T);
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param key A key of the current theme to transform into CSS Variables and Variable References
|
|
11
|
+
* @example .createScaleVariables('fontSize')
|
|
12
|
+
*/
|
|
13
|
+
createScaleVariables<Key extends keyof Omit<T, 'breakpoints'> & string>(key: Key): ThemeBuilder<MergeTheme<T, PrivateThemeKeys, Record<Key, Record<Key, KeyAsVariable<T[Key], Key>>>>>;
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param colors A map of color tokens to add to the theme. These tokens are immediately converted to CSS Variables `--color-${key}`.
|
|
17
|
+
* @example .addColors({ navy: 'navy', hyper: 'purple' })
|
|
18
|
+
*/
|
|
19
|
+
addColors<Colors extends Record<string, string | number | CSSObject>, NextColors extends LiteralPaths<Colors, '-'>>(colors: Colors): ThemeBuilder<MergeTheme<T & PrivateThemeKeys, Record<'colors', KeyAsVariable<NextColors, 'color'>>>>;
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @param initialMode A key of the object passed for modes. This sets the default state for the theme and transforms the correct variables.
|
|
23
|
+
* @param modes A map of color modes with keys of each possible mode with a value of alias to color keys. This must be called after `addColors`
|
|
24
|
+
* @example .addColorModes('light', { light: { primary: 'hyper' }, { dark: { primary: 'navy' } } })
|
|
25
|
+
*/
|
|
26
|
+
addColorModes<Modes extends string, InitialMode extends keyof Config, Colors extends keyof T['colors'], ModeColors extends ColorModeConfig<Colors>, Config extends Record<Modes, ModeColors>, ColorAliases extends {
|
|
27
|
+
[K in keyof Config]: LiteralPaths<Config[K], '-', '_'>;
|
|
28
|
+
}>(initialMode: InitialMode, modeConfig: Config): ThemeBuilder<MergeTheme<T & PrivateThemeKeys, {
|
|
29
|
+
colors: KeyAsVariable<LiteralPaths<Config[keyof Config], '-', '_'>, 'colors'> & T['colors'];
|
|
30
|
+
modes: Merge<T['modes'], ColorAliases>;
|
|
31
|
+
mode: keyof Config;
|
|
32
|
+
_getColorValue: (color: keyof T['colors']) => string;
|
|
33
|
+
}>>;
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @param key A new key of theme
|
|
37
|
+
* @param createScale A function that accepts the current theme and returns a new object of scale values.
|
|
38
|
+
* @example .addScale('fonts', () => ({ basic: 'Gotham', cool: 'Wingdings' }))
|
|
39
|
+
*/
|
|
40
|
+
addScale<Key extends string, Fn extends (theme: T) => Record<string | number, string | number | Record<string, string | number>>, NewScale extends LiteralPaths<ReturnType<Fn>, '-'>>(key: Key, createScale: Fn): ThemeBuilder<MergeTheme<T, Record<Key, NewScale>>>;
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param key A current key of theme to be updated with new or computed values
|
|
44
|
+
* @param updateFn A function that accepts an argument of the current values at the specified keys an returns a map of new values to merge.
|
|
45
|
+
* @example .updateScale('fonts', ({ basic }) => ({ basicFallback: `{basic}, Montserrat` }))
|
|
46
|
+
*/
|
|
47
|
+
updateScale<Key extends keyof T, Fn extends (tokens: T[Key]) => Record<string | number, unknown>>(key: Key, updateFn: Fn): ThemeBuilder<T & Record<Key, T[Key] & ReturnType<Fn>>>;
|
|
48
|
+
/**
|
|
49
|
+
* This finalizes the theme build and returns the final theme and variables to be provided.
|
|
50
|
+
*/
|
|
51
|
+
build(): T & PrivateThemeKeys;
|
|
52
|
+
}
|
|
53
|
+
export declare function createTheme<T extends AbstractTheme>(base: T): ThemeBuilder<T>;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns an exhaustive list of all possible paths of an object T for keys K.
|
|
3
|
-
* Possibilities are returned as `k1.k2.k3`.
|
|
4
|
-
*/
|
|
5
|
-
export
|
|
6
|
-
/** Returns valid paths of object T */
|
|
7
|
-
export
|
|
8
|
-
/** Returns the value of a valid path P `k1.k2.k3` in object T */
|
|
9
|
-
export
|
|
10
|
-
/** Check if path has a primitive end value and return only the union of end paths */
|
|
11
|
-
export
|
|
12
|
-
/**
|
|
13
|
-
* Reduce all paths to a single map of paths with primitive values removing all extra non stateful paths
|
|
14
|
-
* { path: { sub: 1 } } => { 'path-sub': 1 }
|
|
15
|
-
*
|
|
16
|
-
*/
|
|
17
|
-
export
|
|
18
|
-
[K in Path<T, D> as PathToLiteral<T, K, D, Base>]: PathValue<T, PathToLiteral<T, K, D>, D>;
|
|
19
|
-
};
|
|
20
|
-
export declare function flattenScale<T extends Record<string | number,
|
|
1
|
+
/**
|
|
2
|
+
* Returns an exhaustive list of all possible paths of an object T for keys K.
|
|
3
|
+
* Possibilities are returned as `k1.k2.k3`.
|
|
4
|
+
*/
|
|
5
|
+
export type FindPath<T, K extends keyof T, D extends string = '.'> = K extends string | number ? T[K] extends Record<string | number, any> ? T[K] extends ArrayLike<any> ? K | `${K}${D}${FindPath<T[K], Exclude<keyof T[K], keyof any[]>, D>}` : K | `${K}${D}${FindPath<T[K], keyof T[K], D>}` : K : never;
|
|
6
|
+
/** Returns valid paths of object T */
|
|
7
|
+
export type Path<T, D extends string = '.'> = FindPath<T, keyof T, D> | keyof T;
|
|
8
|
+
/** Returns the value of a valid path P `k1.k2.k3` in object T */
|
|
9
|
+
export type PathValue<T, P extends Path<T, D>, D extends string = '.'> = P extends `${infer K}${D}${infer Rest}` ? K extends keyof T ? Rest extends Path<T[K], D> ? PathValue<T[K], Rest, D> : never : never : P extends keyof T ? T[P] : never;
|
|
10
|
+
/** Check if path has a primitive end value and return only the union of end paths */
|
|
11
|
+
export type PathToLiteral<T, K extends Path<T, D>, D extends string = '.', Base extends string = ''> = PathValue<T, K, D> extends string | number ? K extends string | number ? K extends `${infer BasePath}${D}${Base}` ? BasePath : K : never : never;
|
|
12
|
+
/**
|
|
13
|
+
* Reduce all paths to a single map of paths with primitive values removing all extra non stateful paths
|
|
14
|
+
* { path: { sub: 1 } } => { 'path-sub': 1 }
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
export type LiteralPaths<T extends Record<string | number, any>, D extends string = '.', Base extends string = ''> = {
|
|
18
|
+
[K in Path<T, D> as PathToLiteral<T, K, D, Base>]: PathValue<T, PathToLiteral<T, K, D>, D>;
|
|
19
|
+
};
|
|
20
|
+
export declare function flattenScale<T extends Record<string | number, unknown>, P extends string>(object: T, path?: P): LiteralPaths<T, '-', '_'>;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './createTheme';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
1
|
+
export * from './createTheme';
|
|
2
|
+
export * from './flattenScale';
|
|
3
|
+
export * from './serializeTokens';
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
/**
|
|
4
|
-
* Returns an type of any object with { key: 'var(--key) }
|
|
5
|
-
*/
|
|
6
|
-
export
|
|
7
|
-
[V in keyof T]: `var(--${Prefix}-${Extract<V, string
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
[i:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
import { CSSObject } from '@animus-ui/core';
|
|
2
|
+
import { Theme } from '@emotion/react';
|
|
3
|
+
/**
|
|
4
|
+
* Returns an type of any object with { key: 'var(--key) }
|
|
5
|
+
*/
|
|
6
|
+
export type KeyAsVariable<T extends Record<string, any>, Prefix extends string> = {
|
|
7
|
+
[V in keyof T]: `var(--${Prefix}-${SanitizeKey<Extract<V, string>>})`;
|
|
8
|
+
};
|
|
9
|
+
export type SanitizeKey<T extends string> = T extends `${'$'}${infer Y}` ? Y : T;
|
|
10
|
+
type SerializedTokensInput = Record<string, string | number | CSSObject | SerializedTokensInputRecursive>;
|
|
11
|
+
interface SerializedTokensInputRecursive {
|
|
12
|
+
[i: number]: SerializedTokensInput;
|
|
13
|
+
[i: string]: SerializedTokensInput;
|
|
14
|
+
}
|
|
15
|
+
export declare const serializeTokens: <T extends SerializedTokensInput, Prefix extends string>(tokens: T, prefix: Prefix, theme: Theme | undefined) => {
|
|
16
|
+
tokens: KeyAsVariable<T, Prefix>;
|
|
17
|
+
variables: CSSObject;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { AbstractTheme, CSSObject } from '@animus-ui/core';
|
|
2
|
-
/**
|
|
3
|
-
* This is a custom generic that ensures the safety of adding additional values to a theme object without accidentally wiping out
|
|
4
|
-
* required keys like `breakpoints`. It works by creating a new mapped type and merging the values of the union of Base & Next:
|
|
5
|
-
* 1. If the key exists on both Base and Next return the intersection of both values
|
|
6
|
-
* 2. If the key exists on next use the value on next.
|
|
7
|
-
* 3. If the key exists on base but nothing else use the value on base.
|
|
8
|
-
*
|
|
9
|
-
* The resulting type is then rejoined with keys that cannot be mutated (breakpoints) as the next version of Theme
|
|
10
|
-
*/
|
|
11
|
-
export
|
|
12
|
-
/** This merges at 2 levels of depth */
|
|
13
|
-
export
|
|
14
|
-
[K in keyof (A & B)]: K extends keyof B ? K extends keyof A ? AssignValueIfUnmergable<A[K], B[K]> : B[K] : K extends keyof A ? A[K] : never;
|
|
15
|
-
};
|
|
16
|
-
/** Extract mergable objects */
|
|
17
|
-
export
|
|
18
|
-
/** Return B if either A or B is unmergable */
|
|
19
|
-
export
|
|
20
|
-
/** Prefer all values from B */
|
|
21
|
-
export
|
|
22
|
-
[K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never;
|
|
23
|
-
};
|
|
24
|
-
/** These are keys that are consistent for all theme builds - they are loosely typed as they are not meant to be accessed directly */
|
|
25
|
-
export
|
|
26
|
-
_variables: Record<string, CSSObject>;
|
|
27
|
-
_tokens: Record<string | number, any>;
|
|
28
|
-
};
|
|
29
|
-
/** This allows 3 layers of color aliases to be constructed when adding colorModes
|
|
30
|
-
* @example
|
|
31
|
-
* {
|
|
32
|
-
* button: {
|
|
33
|
-
* bg: {
|
|
34
|
-
* hover: 'someAlias'
|
|
35
|
-
* }
|
|
36
|
-
* }
|
|
37
|
-
* }
|
|
38
|
-
*
|
|
39
|
-
* `button-bg-hover`
|
|
40
|
-
* */
|
|
41
|
-
export
|
|
1
|
+
import { AbstractTheme, CSSObject } from '@animus-ui/core';
|
|
2
|
+
/**
|
|
3
|
+
* This is a custom generic that ensures the safety of adding additional values to a theme object without accidentally wiping out
|
|
4
|
+
* required keys like `breakpoints`. It works by creating a new mapped type and merging the values of the union of Base & Next:
|
|
5
|
+
* 1. If the key exists on both Base and Next return the intersection of both values
|
|
6
|
+
* 2. If the key exists on next use the value on next.
|
|
7
|
+
* 3. If the key exists on base but nothing else use the value on base.
|
|
8
|
+
*
|
|
9
|
+
* The resulting type is then rejoined with keys that cannot be mutated (breakpoints) as the next version of Theme
|
|
10
|
+
*/
|
|
11
|
+
export type MergeTheme<Base extends AbstractTheme, Next, Unmergable = Record<'breakpoints', Base['breakpoints']>> = Unmergable & Merge<Base, Next>;
|
|
12
|
+
/** This merges at 2 levels of depth */
|
|
13
|
+
export type Merge<A, B> = {
|
|
14
|
+
[K in keyof (A & B)]: K extends keyof B ? K extends keyof A ? AssignValueIfUnmergable<A[K], B[K]> : B[K] : K extends keyof A ? A[K] : never;
|
|
15
|
+
};
|
|
16
|
+
/** Extract mergable objects */
|
|
17
|
+
export type Mergable<T> = Exclude<T, ((...args: any) => any) | string | boolean | symbol | number | any[]>;
|
|
18
|
+
/** Return B if either A or B is unmergable */
|
|
19
|
+
export type AssignValueIfUnmergable<A, B> = Mergable<A> extends never ? B : Mergable<B> extends never ? B : Assign<A, B>;
|
|
20
|
+
/** Prefer all values from B */
|
|
21
|
+
export type Assign<A, B> = {
|
|
22
|
+
[K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never;
|
|
23
|
+
};
|
|
24
|
+
/** These are keys that are consistent for all theme builds - they are loosely typed as they are not meant to be accessed directly */
|
|
25
|
+
export type PrivateThemeKeys = {
|
|
26
|
+
_variables: Record<string, CSSObject>;
|
|
27
|
+
_tokens: Record<string | number, any>;
|
|
28
|
+
};
|
|
29
|
+
/** This allows 3 layers of color aliases to be constructed when adding colorModes
|
|
30
|
+
* @example
|
|
31
|
+
* {
|
|
32
|
+
* button: {
|
|
33
|
+
* bg: {
|
|
34
|
+
* hover: 'someAlias'
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* `button-bg-hover`
|
|
40
|
+
* */
|
|
41
|
+
export type ColorModeConfig<Colors> = Record<string, Colors | Record<string, Colors> | Record<string, Colors | Record<string, Colors>>>;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@animus-ui/theming",
|
|
3
|
-
"version": "0.1.1-beta.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.1-beta.30",
|
|
4
|
+
"description": "Theming Utilities",
|
|
5
5
|
"author": "Aaron Robb <airrobb@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/codecaaron/animus#readme",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"types": "dist/index.d.ts",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
11
|
"publishConfig": {
|
|
12
12
|
"access": "public"
|
|
13
13
|
},
|
|
@@ -18,19 +18,20 @@
|
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build:clean": "rm -rf ./dist",
|
|
20
20
|
"build": "yarn build:clean && rollup -c",
|
|
21
|
-
"lernaBuildTask": "yarn build"
|
|
21
|
+
"lernaBuildTask": "yarn build",
|
|
22
|
+
"compile": "tsc --noEmit"
|
|
22
23
|
},
|
|
23
24
|
"bugs": {
|
|
24
25
|
"url": "https://github.com/codecaaron/animus/issues"
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@animus-ui/core": "^0.
|
|
28
|
+
"@animus-ui/core": "^0.2.0-beta.2",
|
|
29
|
+
"@emotion/react": "^11.14.0",
|
|
30
|
+
"@emotion/styled": "^11.14.0"
|
|
28
31
|
},
|
|
29
32
|
"peerDependencies": {
|
|
30
|
-
"@emotion/react": ">=11.0.0",
|
|
31
|
-
"@emotion/styled": ">=11.0.0",
|
|
32
33
|
"lodash": "*",
|
|
33
34
|
"typescript": ">=4.3.5"
|
|
34
35
|
},
|
|
35
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "fbc53708e472bbc9b68a06d81a97614c504c8025"
|
|
36
37
|
}
|
package/rollup.config.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
const config = require('../../rollup.config');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
module.exports = config();
|
package/tsconfig.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": "../../tsconfig.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
|
-
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"rootDir": "./src",
|
|
5
6
|
"outDir": "./dist"
|
|
6
7
|
},
|
|
7
|
-
"include": ["
|
|
8
|
-
"exclude": ["
|
|
8
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
9
|
+
"exclude": ["**/*.test.ts", "**/*.test.tsx"]
|
|
9
10
|
}
|
package/dist/index.cjs.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("lodash");function t(s,r){return Object.keys(s).reduce(((o,h)=>{const i=r?`${r}${"_"===h?"":`-${h}`}`:h,a=s[h];return e.isObject(a)?{...o,...t(a,i)}:{...o,[i]:s[h]}}),{})}const s=(t,s,r)=>{const o={},h={};return Object.keys(t).forEach((i=>{const a=`--${s}-${i}`;o[i]=`var(${a})`,e.merge(h,((t,s,r)=>{if(e.isObject(t)){const{_:e,base:o,...h}=t,i={[s]:e??o};if(r){const{breakpoints:e}=r;Object.keys(e).forEach((t=>{i[e[t]]={[s]:h[t]}}))}return i}return{[s]:t}})(t[i],a,r))})),{tokens:o,variables:h}};class r{#e={};constructor(e){this.#e=e}createScaleVariables(t){const{variables:r,tokens:o}=s(this.#e[t],t,this.#e);return this.#e=e.merge({},this.#e,{[t]:o,_variables:{root:r},_tokens:{[t]:this.#e[t]}}),this}addColors(r){const o=t(r),{variables:h,tokens:i}=s(o,"color",this.#e);return this.#e=e.merge({},this.#e,{colors:i,_variables:{root:h},_tokens:{colors:o}}),this}addColorModes(r,o){const h=e.mapValues(o,(e=>t(e))),{tokens:i,variables:a}=s(e.mapValues(e.merge({},this.#e.modes?.[r],h[r]),(e=>this.#e.colors[e])),"color",this.#e),m=e=>this.#e._tokens?.colors?.[e];return this.#e=e.merge({},this.#e,{colors:i,modes:h,mode:r,_getColorValue:m,_variables:{mode:a},_tokens:{modes:e.mapValues(h,(t=>e.mapValues(t,m)))}}),this}addScale(s,r){return this.#e=e.merge({},this.#e,{[s]:t(r(this.#e))}),this}updateScale(t,s){return this.#e=e.merge({},this.#e,{[t]:s(this.#e[t])}),this}build(){return e.merge({},this.#e,{_variables:{},_tokens:{}})}}exports.ThemeBuilder=r,exports.createTheme=function(e){return new r(e)},exports.flattenScale=t,exports.serializeTokens=s;
|
package/dist/index.esm.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{isObject as e,merge as t,mapValues as s}from"lodash";function o(t,s){return Object.keys(t).reduce(((r,h)=>{const i=s?`${s}${"_"===h?"":`-${h}`}`:h,n=t[h];return e(n)?{...r,...o(n,i)}:{...r,[i]:t[h]}}),{})}const r=(s,o,r)=>{const h={},i={};return Object.keys(s).forEach((n=>{const a=`--${o}-${n}`;h[n]=`var(${a})`,t(i,((t,s,o)=>{if(e(t)){const{_:e,base:r,...h}=t,i={[s]:e??r};if(o){const{breakpoints:e}=o;Object.keys(e).forEach((t=>{i[e[t]]={[s]:h[t]}}))}return i}return{[s]:t}})(s[n],a,r))})),{tokens:h,variables:i}};class h{#e={};constructor(e){this.#e=e}createScaleVariables(e){const{variables:s,tokens:o}=r(this.#e[e],e,this.#e);return this.#e=t({},this.#e,{[e]:o,_variables:{root:s},_tokens:{[e]:this.#e[e]}}),this}addColors(e){const s=o(e),{variables:h,tokens:i}=r(s,"color",this.#e);return this.#e=t({},this.#e,{colors:i,_variables:{root:h},_tokens:{colors:s}}),this}addColorModes(e,h){const i=s(h,(e=>o(e))),{tokens:n,variables:a}=r(s(t({},this.#e.modes?.[e],i[e]),(e=>this.#e.colors[e])),"color",this.#e),c=e=>this.#e._tokens?.colors?.[e];return this.#e=t({},this.#e,{colors:n,modes:i,mode:e,_getColorValue:c,_variables:{mode:a},_tokens:{modes:s(i,(e=>s(e,c)))}}),this}addScale(e,s){return this.#e=t({},this.#e,{[e]:o(s(this.#e))}),this}updateScale(e,s){return this.#e=t({},this.#e,{[e]:s(this.#e[e])}),this}build(){return t({},this.#e,{_variables:{},_tokens:{}})}}function i(e){return new h(e)}export{h as ThemeBuilder,i as createTheme,o as flattenScale,r as serializeTokens};
|