@descope-ui/common 0.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.
- package/.eslintrc.json +18 -0
- package/README.md +7 -0
- package/package.json +36 -0
- package/project.json +7 -0
- package/src/baseClasses/baseClasses/createBaseClass.js +66 -0
- package/src/baseClasses/baseClasses/createBaseInputClass.js +14 -0
- package/src/baseClasses/baseClasses/createCssVarImageClass.js +55 -0
- package/src/baseClasses/index.js +3 -0
- package/src/componentsHelpers/index.js +95 -0
- package/src/componentsMixins/helpers/mixinsHelpers.js +10 -0
- package/src/componentsMixins/index.js +1 -0
- package/src/componentsMixins/mixins/activableMixin.js +14 -0
- package/src/componentsMixins/mixins/changeMixin.js +22 -0
- package/src/componentsMixins/mixins/componentNameValidationMixin.js +23 -0
- package/src/componentsMixins/mixins/componentsContextMixin.js +12 -0
- package/src/componentsMixins/mixins/createDynamicDataMixin.js +100 -0
- package/src/componentsMixins/mixins/createProxy.js +58 -0
- package/src/componentsMixins/mixins/createStyleMixin/helpers.js +106 -0
- package/src/componentsMixins/mixins/createStyleMixin/index.js +167 -0
- package/src/componentsMixins/mixins/draggableMixin.js +62 -0
- package/src/componentsMixins/mixins/externalInputHelpers.js +93 -0
- package/src/componentsMixins/mixins/externalInputMixin.js +170 -0
- package/src/componentsMixins/mixins/hoverableMixin.js +13 -0
- package/src/componentsMixins/mixins/index.js +14 -0
- package/src/componentsMixins/mixins/inputEventsDispatchingMixin.js +76 -0
- package/src/componentsMixins/mixins/inputValidationMixin.js +210 -0
- package/src/componentsMixins/mixins/lifecycleEventsMixin.js +23 -0
- package/src/componentsMixins/mixins/normalizeBooleanAttributesMixin.js +59 -0
- package/src/componentsMixins/mixins/portalMixin.js +112 -0
- package/src/componentsMixins/mixins/proxyInputMixin.js +242 -0
- package/src/constants.js +4 -0
- package/src/icons/errorMessageIconBase64.js +1 -0
- package/src/sbControls.js +302 -0
- package/src/sbHelpers.js +53 -0
- package/src/themeHelpers/colorsHelpers.js +94 -0
- package/src/themeHelpers/componentsThemeManager.js +45 -0
- package/src/themeHelpers/index.js +191 -0
- package/src/themeHelpers/resetHelpers.js +144 -0
- package/src/utils/index.js +68 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import errorMessageIconBase64 from './icons/errorMessageIconBase64';
|
|
2
|
+
|
|
3
|
+
export const labelControl = {
|
|
4
|
+
label: {
|
|
5
|
+
name: 'Label',
|
|
6
|
+
control: { type: 'text' },
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const helperTextControl = {
|
|
11
|
+
'helper-text': {
|
|
12
|
+
name: 'Helper Text',
|
|
13
|
+
control: { type: 'text' },
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const placeholderControl = {
|
|
18
|
+
placeholder: {
|
|
19
|
+
name: 'Placeholder',
|
|
20
|
+
control: { type: 'text' },
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const sizeControl = {
|
|
25
|
+
size: {
|
|
26
|
+
name: 'Size',
|
|
27
|
+
options: ['xs', 'sm', 'md', 'lg'],
|
|
28
|
+
control: { type: 'select' },
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const loadingControl = {
|
|
33
|
+
loading: {
|
|
34
|
+
name: 'Loading',
|
|
35
|
+
control: { type: 'boolean' },
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const fullWidthControl = {
|
|
40
|
+
'full-width': {
|
|
41
|
+
name: 'Full Width',
|
|
42
|
+
control: { type: 'boolean' },
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const disabledControl = {
|
|
47
|
+
disabled: {
|
|
48
|
+
name: 'Disabled',
|
|
49
|
+
control: { type: 'boolean' },
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const readOnlyControl = {
|
|
54
|
+
readonly: {
|
|
55
|
+
name: 'Read Only',
|
|
56
|
+
control: { type: 'boolean' },
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const requiredControl = {
|
|
61
|
+
required: {
|
|
62
|
+
name: 'Required',
|
|
63
|
+
control: { type: 'boolean' },
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const directionControl = {
|
|
68
|
+
direction: {
|
|
69
|
+
name: 'Direction',
|
|
70
|
+
options: ['ltr', 'rtl'],
|
|
71
|
+
control: { type: 'select' },
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const borderedControl = {
|
|
76
|
+
bordered: {
|
|
77
|
+
name: 'Bordered',
|
|
78
|
+
control: { type: 'boolean' },
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const minLengthControl = {
|
|
83
|
+
minlength: {
|
|
84
|
+
name: 'Min. Length',
|
|
85
|
+
control: { type: 'text' },
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const maxLengthControl = {
|
|
90
|
+
maxlength: {
|
|
91
|
+
name: 'Max. Length',
|
|
92
|
+
control: { type: 'text' },
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const textContentControl = {
|
|
97
|
+
text: {
|
|
98
|
+
name: 'Content',
|
|
99
|
+
control: { type: 'text' },
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const modeControl = {
|
|
104
|
+
mode: {
|
|
105
|
+
name: 'Mode',
|
|
106
|
+
options: ['none', 'primary', 'secondary', 'success', 'error'],
|
|
107
|
+
control: { type: 'select' },
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const textAlignControl = {
|
|
112
|
+
'text-align': {
|
|
113
|
+
name: 'Text Align',
|
|
114
|
+
options: ['left', 'center', 'right'],
|
|
115
|
+
control: { type: 'select' },
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const errorMissingValueControl = {
|
|
120
|
+
'data-errormessage-value-missing': {
|
|
121
|
+
name: 'Custom Error: Mandatory',
|
|
122
|
+
control: { type: 'text' },
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const errorPatternMismatchControl = {
|
|
127
|
+
'data-errormessage-pattern-mismatch': {
|
|
128
|
+
name: 'Custom Error: Pattern Mismatch',
|
|
129
|
+
control: { type: 'text' },
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const errorTypeMismatchControl = {
|
|
134
|
+
'data-errormessage-type-mismatch': {
|
|
135
|
+
name: 'Custom Error: Type Mismatch',
|
|
136
|
+
control: { type: 'text' },
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const errorBadInputControl = {
|
|
141
|
+
'data-errormessage-bad-input': {
|
|
142
|
+
name: 'Custom Error: Bad Input',
|
|
143
|
+
control: { type: 'text' },
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const errorRangeUnderflowControl = {
|
|
148
|
+
'data-errormessage-range-underflow': {
|
|
149
|
+
name: 'Custom Error: Below minimum value',
|
|
150
|
+
control: { type: 'text' },
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const errorRangeOverflowControl = {
|
|
155
|
+
'data-errormessage-range-overflow': {
|
|
156
|
+
name: 'Custom Error: Exceeds maximum value',
|
|
157
|
+
control: { type: 'text' },
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export const fillControl = {
|
|
162
|
+
'st-fill': {
|
|
163
|
+
name: 'Fill',
|
|
164
|
+
control: { type: 'color' },
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const customHeightControl = {
|
|
169
|
+
'st-host-height': {
|
|
170
|
+
name: 'Custom Height',
|
|
171
|
+
control: { type: 'text' },
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export const customWidthControl = {
|
|
176
|
+
'st-host-width': {
|
|
177
|
+
name: 'Custom Width',
|
|
178
|
+
control: { type: 'text' },
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export const checkboxValueControl = {
|
|
183
|
+
checked: {
|
|
184
|
+
name: 'Checked',
|
|
185
|
+
control: { type: 'boolean' },
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const buttonVariantControl = {
|
|
190
|
+
variant: {
|
|
191
|
+
name: 'Button Variant',
|
|
192
|
+
options: ['contained', 'outline', 'link'],
|
|
193
|
+
control: { type: 'select' },
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const boxShadowControl = {
|
|
198
|
+
shadow: {
|
|
199
|
+
name: 'Shadow',
|
|
200
|
+
options: ['sm', 'md', 'lg', 'xl', '2xl'],
|
|
201
|
+
control: { type: 'select' },
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export const borderRadiusControl = {
|
|
206
|
+
'border-radius': {
|
|
207
|
+
name: 'Radius',
|
|
208
|
+
options: ['sm', 'md', 'lg', 'xl', '2xl', '3xl'],
|
|
209
|
+
control: { type: 'select' },
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export const imgSrcControl = {
|
|
214
|
+
src: {
|
|
215
|
+
name: 'Image Source',
|
|
216
|
+
control: { type: 'text' },
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
export const typographyVariantControl = {
|
|
221
|
+
variant: {
|
|
222
|
+
name: 'Variant',
|
|
223
|
+
options: ['h1', 'h2', 'h3', 'subtitle1', 'subtitle2', 'body1', 'body2'],
|
|
224
|
+
control: { type: 'select' },
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export const overrideRenderItemControl = {
|
|
229
|
+
overrideRenderItem: {
|
|
230
|
+
name: 'Override the default item renderer function',
|
|
231
|
+
control: { type: 'boolean' },
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
export const itemsSourceControl = {
|
|
236
|
+
itemsSource: {
|
|
237
|
+
name: 'Where to take the items from',
|
|
238
|
+
control: {
|
|
239
|
+
type: 'select',
|
|
240
|
+
options: {
|
|
241
|
+
Children: 'children',
|
|
242
|
+
'"data" attribute': 'attr',
|
|
243
|
+
'"data" property': 'prop',
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export const minItemsSelectionControl = {
|
|
250
|
+
minItemsSelection: {
|
|
251
|
+
name: 'Min Items Selection',
|
|
252
|
+
control: { type: 'number' },
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export const maxItemsSelectionControl = {
|
|
257
|
+
maxItemsSelection: {
|
|
258
|
+
name: 'Max Items Selection',
|
|
259
|
+
control: { type: 'number' },
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
export const labelSpacingControl = {
|
|
264
|
+
'label-spacing': {
|
|
265
|
+
name: 'Label Spacing',
|
|
266
|
+
control: { type: 'range', min: 0, max: 200, step: 1 },
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export const inputLabelTypeControl = {
|
|
271
|
+
'label-type': {
|
|
272
|
+
name: 'Label Type',
|
|
273
|
+
control: {
|
|
274
|
+
type: 'select',
|
|
275
|
+
options: ['static', 'floating'],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
export const inputCopyToClipboardControl = {
|
|
281
|
+
'copy-to-clipboard': {
|
|
282
|
+
name: 'Copy to clipboard',
|
|
283
|
+
control: {
|
|
284
|
+
type: 'boolean',
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
export const errorMessageIconControl = {
|
|
290
|
+
errorMsgIcon: {
|
|
291
|
+
name: 'Error Message Icon',
|
|
292
|
+
control: {
|
|
293
|
+
type: 'boolean',
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
export const errorMessageIconAttrs = `
|
|
299
|
+
st-error-message-icon="url(${errorMessageIconBase64})"
|
|
300
|
+
st-error-message-icon-size="14px"
|
|
301
|
+
st-error-message-icon-padding="1.5em"
|
|
302
|
+
`;
|
package/src/sbHelpers.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const withForm = (children) => {
|
|
2
|
+
return `
|
|
3
|
+
<form onsubmit="event.preventDefault()">
|
|
4
|
+
<div>${children}</div>
|
|
5
|
+
<div style="margin-top: 6em">
|
|
6
|
+
<button type="submit" data-testid="submit-button">Submit</button>
|
|
7
|
+
</div>
|
|
8
|
+
</form>
|
|
9
|
+
`;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const appleIcon = `
|
|
13
|
+
<svg
|
|
14
|
+
width="1.5em"
|
|
15
|
+
height="1.5em"
|
|
16
|
+
viewBox="0 0 800 1000"
|
|
17
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
18
|
+
fill="white"
|
|
19
|
+
data-icon="apple"
|
|
20
|
+
>
|
|
21
|
+
<path
|
|
22
|
+
d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"
|
|
23
|
+
/>
|
|
24
|
+
</svg>`;
|
|
25
|
+
|
|
26
|
+
export const fingerprintBase64 = `data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPG1hc2sgaWQ9Im1hc2swXzI4NDRfMTE0Mzk0IiBzdHlsZT0ibWFzay10eXBlOmFscGhhIiBtYXNrVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4PSIwIiB5PSIwIiB3aWR0aD0iNDAiIGhlaWdodD0iNDAiPgo8cmVjdCB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIGZpbGw9IiNEOUQ5RDkiLz4KPC9tYXNrPgo8ZyBtYXNrPSJ1cmwoI21hc2swXzI4NDRfMTE0Mzk0KSI+CjxwYXRoIGQ9Ik01LjMzMjc3IDE2LjA4M0M1LjEzODc3IDE1Ljk3MjMgNS4wMjA3NyAxNS44MTI3IDQuOTc4NzcgMTUuNjA0QzQuOTM3NDQgMTUuMzk2IDQuOTcyMTEgMTUuMTk0NyA1LjA4Mjc3IDE1QzYuNzc3NDQgMTIuNTU1MyA4Ljk1MTExIDEwLjY1OTcgMTEuNjAzOCA5LjMxMzAxQzE0LjI1NjQgNy45NjU2NyAxNy4wODI4IDcuMjkyMDEgMjAuMDgyOCA3LjI5MjAxQzIzLjA1NTQgNy4yOTIwMSAyNS44NjExIDcuOTM3NjcgMjguNDk5OCA5LjIyOTAxQzMxLjEzODQgMTAuNTIxIDMzLjMxOTEgMTIuMzYxMyAzNS4wNDE4IDE0Ljc1QzM1LjIwODQgMTUgMzUuMjYzOCAxNS4yMjIzIDM1LjIwNzggMTUuNDE3QzM1LjE1MjQgMTUuNjExIDM1LjA0MTQgMTUuNzc3NyAzNC44NzQ4IDE1LjkxN0MzNC43MzYxIDE2LjA1NTcgMzQuNTU1NCAxNi4xMTggMzQuMzMyOCAxNi4xMDRDMzQuMTEwOCAxNi4wOSAzMy45MTY0IDE1Ljk3MiAzMy43NDk4IDE1Ljc1QzMyLjIyMTggMTMuNTU1MyAzMC4yNDI0IDExLjg3NDcgMjcuODExOCAxMC43MDhDMjUuMzgxOCA5LjU0MTM0IDIyLjgwNTQgOC45NDQzNCAyMC4wODI4IDguOTE3MDFDMTcuMzYwOCA4LjkxNzAxIDE0Ljc5ODQgOS41MDczNCAxMi4zOTU4IDEwLjY4OEM5Ljk5MzExIDExLjg2OCA4LjAyNzc3IDEzLjU1NTMgNi40OTk3NyAxNS43NUM2LjMwNTExIDE2IDYuMTAzNzcgMTYuMTQ2IDUuODk1NzcgMTYuMTg4QzUuNjg3MTEgMTYuMjI5MyA1LjQ5OTQ0IDE2LjE5NDMgNS4zMzI3NyAxNi4wODNaTTI1LjIwNzggMzdDMjIuMDk3MSAzNi4zMDUzIDE5LjYxODEgMzQuODQ3IDE3Ljc3MDggMzIuNjI1QzE1LjkyMzQgMzAuNDAzIDE0Ljk5OTggMjcuNzM2MyAxNC45OTk4IDI0LjYyNUMxNC45OTk4IDIzLjIwODMgMTUuNDk5OCAyMi4wMTQgMTYuNDk5OCAyMS4wNDJDMTcuNDk5OCAyMC4wNjkzIDE4LjY5NDEgMTkuNTgzIDIwLjA4MjggMTkuNTgzQzIxLjQ5OTQgMTkuNTgzIDIyLjcwNzggMjAuMDU1MyAyMy43MDc4IDIxQzI0LjcwNzggMjEuOTQ0NyAyNS4yMDc4IDIzLjExMTMgMjUuMjA3OCAyNC41QzI1LjIwNzggMjUuNDQ0NyAyNS41NTUxIDI2LjI1MDMgMjYuMjQ5OCAyNi45MTdDMjYuOTQ0NCAyNy41ODM3IDI3Ljc3NzggMjcuOTE3IDI4Ljc0OTggMjcuOTE3QzI5LjY5NDQgMjcuOTE3IDMwLjUwMDEgMjcuNTgzNyAzMS4xNjY4IDI2LjkxN0MzMS44MzM0IDI2LjI1MDMgMzIuMTY2OCAyNS40NDQ3IDMyLjE2NjggMjQuNUMzMi4xNjY4IDIxLjI1IDMwLjk4NjEgMTguNTIwNyAyOC42MjQ4IDE2LjMxMkMyNi4yNjM0IDE0LjEwNCAyMy40MTYxIDEzIDIwLjA4MjggMTNDMTYuNzQ5NCAxMyAxMy45MDkxIDE0LjEyNSAxMS41NjE4IDE2LjM3NUM5LjIxNTExIDE4LjYyNSA4LjA0MTc3IDIxLjM3NSA4LjA0MTc3IDI0LjYyNUM4LjA0MTc3IDI1LjUxMzcgOC4xMTgxMSAyNi40NTggOC4yNzA3NyAyNy40NThDOC40MjM0NCAyOC40NTggOC42OTQxMSAyOS41MTM3IDkuMDgyNzcgMzAuNjI1QzkuMTY2MTEgMzAuODc1IDkuMTY2MTEgMzEuMDgzMyA5LjA4Mjc3IDMxLjI1QzguOTk5NDQgMzEuNDE2NyA4Ljg2MDc3IDMxLjU0MTcgOC42NjY3NyAzMS42MjVDOC40NDQxMSAzMS43MDgzIDguMjI4NzcgMzEuNzE1MyA4LjAyMDc3IDMxLjY0NkM3LjgxMjExIDMxLjU3NjcgNy42NTI0NCAzMS40MDMgNy41NDE3NyAzMS4xMjVDNy4yMDg0NCAzMC4yMzYzIDYuOTQ0NDQgMjkuMjM2MyA2Ljc0OTc3IDI4LjEyNUM2LjU1NTExIDI3LjAxMzcgNi40NTc3NyAyNS44NDcgNi40NTc3NyAyNC42MjVDNi40NTc3NyAyMC45NTgzIDcuNzk4MTEgMTcuODI2MyAxMC40Nzg4IDE1LjIyOUMxMy4xNTk0IDEyLjYzMTcgMTYuMzYwOCAxMS4zMzMgMjAuMDgyOCAxMS4zMzNDMjMuODYwOCAxMS4zMzMgMjcuMDkwMSAxMi42MDQgMjkuNzcwOCAxNS4xNDZDMzIuNDUxNCAxNy42ODczIDMzLjc5MTggMjAuODA1MyAzMy43OTE4IDI0LjVDMzMuNzkxOCAyNS44ODg3IDMzLjI5ODQgMjcuMDY5MyAzMi4zMTE4IDI4LjA0MkMzMS4zMjU4IDI5LjAxNCAzMC4xMzg0IDI5LjUgMjguNzQ5OCAyOS41QzI3LjMwNTEgMjkuNSAyNi4wODI4IDI5LjAyNzcgMjUuMDgyOCAyOC4wODNDMjQuMDgyOCAyNy4xMzkgMjMuNTgyOCAyNS45ODYzIDIzLjU4MjggMjQuNjI1QzIzLjU4MjggMjMuNjUzIDIzLjI0MjQgMjIuODMzNyAyMi41NjE4IDIyLjE2N0MyMS44ODE4IDIxLjUwMDMgMjEuMDU1NCAyMS4xNjcgMjAuMDgyOCAyMS4xNjdDMTkuMTM4OCAyMS4xNjcgMTguMzI2NCAyMS41MDAzIDE3LjY0NTggMjIuMTY3QzE2Ljk2NTEgMjIuODMzNyAxNi42MjQ4IDIzLjY1MyAxNi42MjQ4IDI0LjYyNUMxNi42MjQ4IDI3LjQwMyAxNy40MzA0IDI5LjczNjMgMTkuMDQxOCAzMS42MjVDMjAuNjUyNCAzMy41MTM3IDIyLjg0NjggMzQuODA1MyAyNS42MjQ4IDM1LjVDMjUuODc0OCAzNS41NTUzIDI2LjA0MTQgMzUuNjY2MyAyNi4xMjQ4IDM1LjgzM0MyNi4yMDgxIDM1Ljk5OTcgMjYuMjM1OCAzNi4xOTQzIDI2LjIwNzggMzYuNDE3QzI2LjE1MjQgMzYuNjExIDI2LjA0ODQgMzYuNzcwNyAyNS44OTU4IDM2Ljg5NkMyNS43NDMxIDM3LjAyMDcgMjUuNTEzOCAzNy4wNTUzIDI1LjIwNzggMzdaTTEwLjQ5OTggNy4xNjcwMUMxMC4yNDk4IDcuMzA1NjcgMTAuMDM0NCA3LjM0MDM0IDkuODUzNzcgNy4yNzEwMUM5LjY3MzExIDcuMjAxNjcgOS41Mjc0NCA3LjA4MzY3IDkuNDE2NzcgNi45MTcwMUM5LjMwNTQ0IDYuNzc3NjcgOS4yNzA0NCA2LjU5MDAxIDkuMzExNzcgNi4zNTQwMUM5LjM1Mzc3IDYuMTE4MDEgOS40NzIxMSA1Ljk1ODM0IDkuNjY2NzcgNS44NzUwMUMxMS4yNzc0IDQuOTU4MzQgMTIuOTY0OCA0LjI4NDY3IDE0LjcyODggMy44NTQwMUMxNi40OTI4IDMuNDIzMzQgMTguMjc3NCAzLjIwODAxIDIwLjA4MjggMy4yMDgwMUMyMS45MTYxIDMuMjA4MDEgMjMuNzAxMSAzLjQyMzM0IDI1LjQzNzggMy44NTQwMUMyNy4xNzM4IDQuMjg0NjcgMjguODMzNCA0LjkxNjY3IDMwLjQxNjggNS43NTAwMUMzMC42NjY4IDUuODYxMzQgMzAuODEyNCA2LjAyMTAxIDMwLjg1MzggNi4yMjkwMUMzMC44OTU4IDYuNDM3NjcgMzAuODc1MSA2LjYyNTM0IDMwLjc5MTggNi43OTIwMUMzMC43MDg0IDYuOTg2MDEgMzAuNTY5NCA3LjEzMTY3IDMwLjM3NDggNy4yMjkwMUMzMC4xODAxIDcuMzI2MzQgMjkuOTU3OCA3LjMwNTY3IDI5LjcwNzggNy4xNjcwMUMyOC4yMzU4IDYuNDE3MDEgMjYuNjg3MSA1LjgzMzY3IDI1LjA2MTggNS40MTcwMUMyMy40MzcxIDUuMDAwMzQgMjEuNzc3NCA0Ljc5MjAxIDIwLjA4MjggNC43OTIwMUMxOC40MTYxIDQuNzkyMDEgMTYuNzcwNCA0Ljk4NjM0IDE1LjE0NTggNS4zNzUwMUMxMy41MjA0IDUuNzYzNjcgMTEuOTcxOCA2LjM2MTAxIDEwLjQ5OTggNy4xNjcwMVpNMTUuNjY2OCAzNi4zMzNDMTQuMDU1NCAzNC42NjYzIDEyLjgzMzEgMzIuODk1NyAxMS45OTk4IDMxLjAyMUMxMS4xNjY0IDI5LjE0NTcgMTAuNzQ5OCAyNy4wMTM3IDEwLjc0OTggMjQuNjI1QzEwLjc0OTggMjIuMDY5NyAxMS42NTk0IDE5LjkwMyAxMy40Nzg4IDE4LjEyNUMxNS4yOTgxIDE2LjM0NyAxNy40OTk0IDE1LjQ1OCAyMC4wODI4IDE1LjQ1OEMyMi42NjYxIDE1LjQ1OCAyNC44ODg0IDE2LjMzMyAyNi43NDk4IDE4LjA4M0MyOC42MTExIDE5LjgzMyAyOS41NDE4IDIxLjk3MiAyOS41NDE4IDI0LjVDMjkuNTQxOCAyNC43NzggMjkuNDcyMSAyNC45OTMzIDI5LjMzMjggMjUuMTQ2QzI5LjE5NDEgMjUuMjk4NyAyOC45OTk4IDI1LjM3NSAyOC43NDk4IDI1LjM3NUMyOC40NzE4IDI1LjM3NSAyOC4yNTY0IDI1LjI5ODcgMjguMTAzOCAyNS4xNDZDMjcuOTUxMSAyNC45OTMzIDI3Ljg3NDggMjQuNzc4IDI3Ljg3NDggMjQuNUMyNy44NzQ4IDIyLjM4ODcgMjcuMTEwOCAyMC42MTggMjUuNTgyOCAxOS4xODhDMjQuMDU1NCAxNy43NTczIDIyLjIyMjEgMTcuMDQyIDIwLjA4MjggMTcuMDQyQzE3Ljk0NDEgMTcuMDQyIDE2LjEyNDggMTcuNzc4IDE0LjYyNDggMTkuMjVDMTMuMTI0OCAyMC43MjIgMTIuMzc0OCAyMi41MTM3IDEyLjM3NDggMjQuNjI1QzEyLjM3NDggMjYuODQ3IDEyLjczNTggMjguNzcwNyAxMy40NTc4IDMwLjM5NkMxNC4xODA0IDMyLjAyMDcgMTUuMzE5NCAzMy42Mzg3IDE2Ljg3NDggMzUuMjVDMTcuMDY5NCAzNS40NDQ3IDE3LjE1OTggMzUuNjM5IDE3LjE0NTggMzUuODMzQzE3LjEzMTggMzYuMDI3NyAxNy4wNjkxIDM2LjIwODMgMTYuOTU3OCAzNi4zNzVDMTYuODE5MSAzNi41NDE3IDE2LjYxNzggMzYuNjI1IDE2LjM1MzggMzYuNjI1QzE2LjA4OTggMzYuNjI1IDE1Ljg2MDggMzYuNTI3NyAxNS42NjY4IDM2LjMzM1pNMjguNzkxOCAzMy41QzI2LjE4MDQgMzMuNSAyMy45NDQxIDMyLjY5NDMgMjIuMDgyOCAzMS4wODNDMjAuMjIyMSAyOS40NzIzIDE5LjI5MTggMjcuMjkyIDE5LjI5MTggMjQuNTQyQzE5LjI5MTggMjQuMjkyIDE5LjM2MTEgMjQuMDgzNyAxOS40OTk4IDIzLjkxN0MxOS42Mzg0IDIzLjc1MDMgMTkuODMyOCAyMy42NjcgMjAuMDgyOCAyMy42NjdDMjAuMzMyOCAyMy42NjcgMjAuNTI3NCAyMy43NTAzIDIwLjY2NjggMjMuOTE3QzIwLjgwNTQgMjQuMDgzNyAyMC44NzQ4IDI0LjI5MiAyMC44NzQ4IDI0LjU0MkMyMC44NzQ4IDI2Ljg0NzMgMjEuNjU5NCAyOC42NTI3IDIzLjIyODggMjkuOTU4QzI0Ljc5ODEgMzEuMjY0IDI2LjY1MjQgMzEuOTE3IDI4Ljc5MTggMzEuOTE3QzI5LjA0MTggMzEuOTE3IDI5LjMzMzQgMzEuODk2IDI5LjY2NjggMzEuODU0QzMwLjAwMDEgMzEuODEyNyAzMC4zMzM0IDMxLjc3OCAzMC42NjY4IDMxLjc1QzMwLjg4ODggMzEuNzIyIDMxLjA3NjEgMzEuNzc3NyAzMS4yMjg4IDMxLjkxN0MzMS4zODE0IDMyLjA1NTcgMzEuNDU3OCAzMi4yMDgzIDMxLjQ1NzggMzIuMzc1QzMxLjQ4NTggMzIuNTk3IDMxLjQ0NDEgMzIuNzc3NyAzMS4zMzI4IDMyLjkxN0MzMS4yMjIxIDMzLjA1NTcgMzEuMDgzNCAzMy4xNTI3IDMwLjkxNjggMzMuMjA4QzMwLjQ3MjEgMzMuMzQ3MyAzMC4wNTU0IDMzLjQzMDcgMjkuNjY2OCAzMy40NThDMjkuMjc3NCAzMy40ODYgMjguOTg1OCAzMy41IDI4Ljc5MTggMzMuNVoiIGZpbGw9ImJsYWNrIi8+CjwvZz4KPC9zdmc+Cg==`;
|
|
27
|
+
|
|
28
|
+
export const googleIcon = `
|
|
29
|
+
<svg
|
|
30
|
+
width="1.5em"
|
|
31
|
+
height="1.5em"
|
|
32
|
+
viewBox="0 0 20 20"
|
|
33
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
34
|
+
fill=""
|
|
35
|
+
data-icon="google"
|
|
36
|
+
>
|
|
37
|
+
<path
|
|
38
|
+
d="m19.6 10.2274c0-.70912-.0636-1.39092-.1818-2.04552h-9.4182v3.86822h5.3818c-.2318 1.25-.9363 2.3091-1.9954 3.0182v2.5091h3.2318c1.8909-1.7409 2.9818-4.3046 2.9818-7.35z"
|
|
39
|
+
fill="#4285f4"
|
|
40
|
+
/>
|
|
41
|
+
<path
|
|
42
|
+
d="m10 19.9999c2.7 0 4.9636-.8955 6.6181-2.4227l-3.2318-2.5091c-.8954.6-2.0409.9545-3.3863.9545-2.6046 0-4.8091-1.7591-5.5955-4.1227h-3.3409v2.5909c1.6455 3.2682 5.0273 5.5091 8.9364 5.5091z"
|
|
43
|
+
fill="#34a853"
|
|
44
|
+
/>
|
|
45
|
+
<path
|
|
46
|
+
d="m4.4045 11.8999c-.2-.6-.3136-1.2409-.3136-1.89997 0-.6591.1136-1.3.3136-1.9v-2.5909h-3.3409c-.6772 1.35-1.0636 2.8773-1.0636 4.4909 0 1.61357.3864 3.14087 1.0636 4.49087z"
|
|
47
|
+
fill="#fbbc04"
|
|
48
|
+
/>
|
|
49
|
+
<path
|
|
50
|
+
d="m10 3.9773c1.4681 0 2.7863.5045 3.8227 1.4954l2.8682-2.8682c-1.7318-1.6136-3.9955-2.6045-6.6909-2.6045-3.9091 0-7.2909 2.2409-8.9364 5.5091l3.3409 2.5909c.7864-2.3636 2.9909-4.1227 5.5955-4.1227z"
|
|
51
|
+
fill="#e94235"
|
|
52
|
+
/>
|
|
53
|
+
</svg>`;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import Color from 'color';
|
|
2
|
+
|
|
3
|
+
const colorGaps = {
|
|
4
|
+
darkLight: 0.4,
|
|
5
|
+
highlight: 0.8,
|
|
6
|
+
contrast: 1,
|
|
7
|
+
edgeColor: {
|
|
8
|
+
darkLight: 0.25,
|
|
9
|
+
highlight: 0.1,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const darken = (c, percentage) => c.darken(percentage).hex();
|
|
14
|
+
|
|
15
|
+
const contrast = (c) => {
|
|
16
|
+
const isDark = c.isDark();
|
|
17
|
+
return c
|
|
18
|
+
.mix(Color(isDark ? 'white' : 'black'), colorGaps.contrast)
|
|
19
|
+
.saturate(1)
|
|
20
|
+
.hex();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const lighten = (c, percentage) => {
|
|
24
|
+
const isDark = c.lightness() < 0.5;
|
|
25
|
+
|
|
26
|
+
if (isDark) {
|
|
27
|
+
return c.lightness(percentage * 100).hex();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return c.lighten(percentage).hex();
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const isNearBlack = (color) => color.luminosity() < 0.01;
|
|
34
|
+
const isNearWhite = (color) => color.luminosity() > 0.99;
|
|
35
|
+
|
|
36
|
+
const generateDarkColor = (color, theme) => {
|
|
37
|
+
if (theme === 'dark') {
|
|
38
|
+
return isNearWhite(color)
|
|
39
|
+
? darken(color, colorGaps.edgeColor.darkLight)
|
|
40
|
+
: lighten(color, colorGaps.darkLight);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return isNearBlack(color)
|
|
44
|
+
? lighten(color, colorGaps.edgeColor.darkLight)
|
|
45
|
+
: darken(color, colorGaps.darkLight);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const generateLightColor = (color, theme) => {
|
|
49
|
+
if (theme === 'dark') {
|
|
50
|
+
return isNearBlack(color)
|
|
51
|
+
? lighten(color, colorGaps.edgeColor.darkLight)
|
|
52
|
+
: darken(color, colorGaps.darkLight);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return isNearWhite(color)
|
|
56
|
+
? darken(color, colorGaps.edgeColor.darkLight)
|
|
57
|
+
: lighten(color, colorGaps.darkLight);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const generateHighlightColor = (color, theme) => {
|
|
61
|
+
if (theme === 'dark') {
|
|
62
|
+
return isNearBlack(color)
|
|
63
|
+
? lighten(color, colorGaps.edgeColor.highlight)
|
|
64
|
+
: darken(color, colorGaps.highlight);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return isNearWhite(color)
|
|
68
|
+
? darken(color, colorGaps.edgeColor.highlight)
|
|
69
|
+
: lighten(color, colorGaps.highlight);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const genColor = (color, theme) => {
|
|
73
|
+
const mainColor = new Color(color.main || color);
|
|
74
|
+
|
|
75
|
+
const res = {
|
|
76
|
+
main: mainColor.hex(),
|
|
77
|
+
dark: color.dark || generateDarkColor(mainColor, theme),
|
|
78
|
+
light: color.light || generateLightColor(mainColor, theme),
|
|
79
|
+
highlight: color.highlight || generateHighlightColor(mainColor, theme),
|
|
80
|
+
contrast: color.contrast || contrast(mainColor),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return res;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const genColors = (colors) => {
|
|
87
|
+
return Object.keys(colors).reduce((acc, colorName) => {
|
|
88
|
+
const currentColor = colors[colorName];
|
|
89
|
+
|
|
90
|
+
return Object.assign(acc, {
|
|
91
|
+
[colorName]: genColor(currentColor),
|
|
92
|
+
});
|
|
93
|
+
}, {});
|
|
94
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
class ComponentsThemeManager {
|
|
2
|
+
static mountOnPropName = 'DescopeThemeManager';
|
|
3
|
+
|
|
4
|
+
#themes = {};
|
|
5
|
+
|
|
6
|
+
#currentThemeName = 'light';
|
|
7
|
+
|
|
8
|
+
#callbacks = new Set();
|
|
9
|
+
|
|
10
|
+
#notify() {
|
|
11
|
+
this.#callbacks.forEach((cb) => cb?.());
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get currentThemeName() {
|
|
15
|
+
return this.#currentThemeName;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
set currentThemeName(themeName) {
|
|
19
|
+
this.#currentThemeName = themeName;
|
|
20
|
+
this.#notify();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get currentTheme() {
|
|
24
|
+
return this.#themes[this.currentThemeName];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
onCurrentThemeChange(cb) {
|
|
28
|
+
this.#callbacks.add(cb);
|
|
29
|
+
|
|
30
|
+
return () => {
|
|
31
|
+
this.#callbacks.delete(cb);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
set themes(themes) {
|
|
36
|
+
this.#themes = themes;
|
|
37
|
+
this.#notify();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get hasThemes() {
|
|
41
|
+
return !!Object.keys(this.#themes).length;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const componentsThemeManager = new ComponentsThemeManager();
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import merge from 'lodash.merge';
|
|
2
|
+
import {
|
|
3
|
+
BASE_THEME_SECTION,
|
|
4
|
+
DESCOPE_PREFIX,
|
|
5
|
+
PORTAL_THEME_PREFIX,
|
|
6
|
+
} from '../constants';
|
|
7
|
+
import { isUrl, kebabCase } from '../utils';
|
|
8
|
+
import { getComponentName, getCssVarName } from '../componentsHelpers';
|
|
9
|
+
|
|
10
|
+
const getVarName = (path) => getCssVarName(DESCOPE_PREFIX, ...path);
|
|
11
|
+
|
|
12
|
+
// lodash.set alternative
|
|
13
|
+
const set = (obj, path, value) => {
|
|
14
|
+
const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
|
|
15
|
+
|
|
16
|
+
pathArray.reduce((acc, key, i) => {
|
|
17
|
+
if (acc[key] === undefined) acc[key] = {};
|
|
18
|
+
if (i === pathArray.length - 1) acc[key] = value;
|
|
19
|
+
return acc[key];
|
|
20
|
+
}, obj);
|
|
21
|
+
|
|
22
|
+
return obj;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const transformTheme = (theme, path, getTransformation) => {
|
|
26
|
+
return Object.entries(theme).reduce((acc, [key, val]) => {
|
|
27
|
+
if (val?.constructor !== Object) {
|
|
28
|
+
return merge(acc, getTransformation(path.concat(key), val));
|
|
29
|
+
}
|
|
30
|
+
return merge(acc, transformTheme(val, [...path, key], getTransformation));
|
|
31
|
+
}, {});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const stringifyArray = (strArr) =>
|
|
35
|
+
strArr.map((str) => (str.includes(' ') ? `"${str}"` : str)).join(', ');
|
|
36
|
+
|
|
37
|
+
const getCssVarValue = (val) => {
|
|
38
|
+
switch (true) {
|
|
39
|
+
case Array.isArray(val):
|
|
40
|
+
return stringifyArray(val);
|
|
41
|
+
case isUrl(val):
|
|
42
|
+
return `url(${val})`;
|
|
43
|
+
default:
|
|
44
|
+
return val;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const themeToCSSVarsObj = (theme) =>
|
|
49
|
+
transformTheme(theme, [], (path, val) => ({
|
|
50
|
+
[getVarName(path)]: getCssVarValue(val),
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
export const getThemeRefs = (theme, prefix) =>
|
|
54
|
+
transformTheme(theme, [], (path) =>
|
|
55
|
+
set({}, path, `var(${getVarName(prefix ? [prefix, ...path] : path)})`),
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export const getThemeVars = (theme, prefix) =>
|
|
59
|
+
transformTheme(theme, [], (path) =>
|
|
60
|
+
set({}, path, getVarName(prefix ? [prefix, ...path] : path)),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export const globalsThemeToStyle = (theme, themeName = '') => {
|
|
64
|
+
const style = Object.entries(themeToCSSVarsObj(theme)).reduce(
|
|
65
|
+
(acc, entry) => `${acc}${entry.join(':')};\n`,
|
|
66
|
+
'',
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (!themeName) return style;
|
|
70
|
+
|
|
71
|
+
return `*[data-theme="${themeName}"] {${style}}`;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const componentsThemeToStyleObj = (componentsTheme) =>
|
|
75
|
+
transformTheme(componentsTheme, [], (path, val) => {
|
|
76
|
+
const [component, ...restPath] = path;
|
|
77
|
+
const property = restPath.pop();
|
|
78
|
+
const componentName = getComponentName(component);
|
|
79
|
+
|
|
80
|
+
if (property === 'undefined') {
|
|
81
|
+
// eslint-disable-next-line no-console
|
|
82
|
+
console.warn(
|
|
83
|
+
componentName,
|
|
84
|
+
`theme value: "${val}" is mapped to an invalid property`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// we need a support for portal components theme (e.g. overlay)
|
|
89
|
+
// this allows us to generate those themes under different sections
|
|
90
|
+
// if the theme has root level attribute that starts with #
|
|
91
|
+
// we are generating a new theme
|
|
92
|
+
let themeName = BASE_THEME_SECTION;
|
|
93
|
+
|
|
94
|
+
if (restPath[0] && restPath[0].startsWith(PORTAL_THEME_PREFIX)) {
|
|
95
|
+
themeName = restPath.shift();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// do not start with underscore -> key:value, must have 2 no underscore attrs in a row
|
|
99
|
+
// starts with underscore -> attribute selector
|
|
100
|
+
const attrsSelector = restPath.reduce((acc, section, idx) => {
|
|
101
|
+
if (section.startsWith('_'))
|
|
102
|
+
return `${acc}[${kebabCase(section.replace(/^_/, ''))}="true"]`;
|
|
103
|
+
|
|
104
|
+
const nextSection = restPath[idx + 1];
|
|
105
|
+
|
|
106
|
+
if (typeof nextSection !== 'string' || nextSection.startsWith('_')) {
|
|
107
|
+
// eslint-disable-next-line no-console
|
|
108
|
+
console.error(
|
|
109
|
+
'theme generator',
|
|
110
|
+
`your theme structure is invalid, attribute "${section}" is followed by "${nextSection}" which is not allowed`,
|
|
111
|
+
);
|
|
112
|
+
return acc;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return `${acc}[${kebabCase(section)}="${restPath
|
|
116
|
+
.splice(idx + 1, 1)
|
|
117
|
+
.join('')}"]`;
|
|
118
|
+
}, '');
|
|
119
|
+
|
|
120
|
+
const selector = `:host${attrsSelector ? `(${attrsSelector})` : ''}`;
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
[componentName]: {
|
|
124
|
+
[themeName]: {
|
|
125
|
+
[selector]: {
|
|
126
|
+
[property]: getCssVarValue(val),
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const componentsThemeToStyle = (componentsTheme) =>
|
|
134
|
+
Object.entries(componentsTheme).reduce(
|
|
135
|
+
(acc, [selector, vars]) =>
|
|
136
|
+
`${acc}${selector} { \n${Object.entries(vars)
|
|
137
|
+
.map(([key, val]) => `${key}: ${val}`)
|
|
138
|
+
.join(';\n')} \n}\n\n`,
|
|
139
|
+
'',
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
export const createComponentsTheme = (componentsTheme) => {
|
|
143
|
+
const styleObj = componentsThemeToStyleObj(componentsTheme);
|
|
144
|
+
|
|
145
|
+
return Object.keys(styleObj).reduce((acc, componentName) => {
|
|
146
|
+
const componentThemes = styleObj[componentName];
|
|
147
|
+
|
|
148
|
+
return Object.assign(acc, {
|
|
149
|
+
[componentName]: Object.keys(componentThemes).reduce(
|
|
150
|
+
(res, theme) =>
|
|
151
|
+
Object.assign(res, {
|
|
152
|
+
[theme]: componentsThemeToStyle(componentThemes[theme]),
|
|
153
|
+
}),
|
|
154
|
+
{},
|
|
155
|
+
),
|
|
156
|
+
});
|
|
157
|
+
}, {});
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export const themeToStyle = ({ globals, components }, themeName) => ({
|
|
161
|
+
globals: globalsThemeToStyle(globals, themeName),
|
|
162
|
+
components: createComponentsTheme(components),
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// allows to generate css variables with nested fallbacks
|
|
166
|
+
export const useVar = (...varNames) => {
|
|
167
|
+
return varNames.reduceRight((acc, value) => {
|
|
168
|
+
if (value.startsWith('--')) return `var(${value}${acc ? `, ${acc}` : acc})`;
|
|
169
|
+
|
|
170
|
+
return `${value}${acc ? `, ${acc}` : acc}`;
|
|
171
|
+
}, '');
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const createHelperVars = (theme, prefix) => {
|
|
175
|
+
const res = transformTheme(theme, [], (path, value) => {
|
|
176
|
+
const modifiedPath = [...path];
|
|
177
|
+
const property = modifiedPath.splice(-1);
|
|
178
|
+
const varName = getCssVarName(prefix, property);
|
|
179
|
+
|
|
180
|
+
const vars = { [property]: varName };
|
|
181
|
+
const useVars = { [property]: useVar(varName) };
|
|
182
|
+
|
|
183
|
+
return { theme: set({}, [...modifiedPath, varName], value), useVars, vars };
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
return [res.theme, res.useVars, res.vars];
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export { componentsThemeManager } from './componentsThemeManager';
|
|
190
|
+
export * from './colorsHelpers';
|
|
191
|
+
export * from './resetHelpers';
|