@blerp/design 1.3.17 → 1.4.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/dist/cjs/Blerp/BlerpImageRow.js +176 -57
- package/dist/cjs/Blerp/BlerpSavePopup.js +44 -40
- package/dist/cjs/Blerp/BlerpTitleRow.js +36 -19
- package/dist/cjs/Blerp/BlerpTopRow.js +110 -44
- package/dist/cjs/Blerp.js +9 -16
- package/dist/cjs/BlerpAudioContextProvider.js +2 -2
- package/dist/cjs/BlerpListView.js +318 -168
- package/dist/cjs/BlerpListViewPremium.js +155 -130
- package/dist/cjs/BlerpListViewSkeleton.js +60 -13
- package/dist/cjs/BlerpSkeleton.js +32 -9
- package/dist/cjs/CollectionCard.js +139 -60
- package/dist/cjs/CollectionListViewPremium.js +368 -297
- package/dist/cjs/CollectionSkeleton.js +74 -13
- package/dist/cjs/Dropdown.js +272 -172
- package/dist/cjs/EllipsisLoader.js +66 -21
- package/dist/cjs/GroupCard.js +64 -57
- package/dist/cjs/Icons/Icons.js +288 -426
- package/dist/cjs/ImageEditor.js +247 -0
- package/dist/cjs/ImageUpload.js +226 -0
- package/dist/cjs/NewBlerp.js +354 -160
- package/dist/cjs/NewBlerpTest.js +10 -792
- package/dist/cjs/NewCollectionModal.js +294 -310
- package/dist/cjs/PremiumCollectionCard.js +191 -454
- package/dist/cjs/PurchaseModals/CheckoutModal.js +1 -1
- package/dist/cjs/PurchaseModals/PremiumBlerpCheckoutModal.js +1 -1
- package/dist/cjs/PurchaseModals/PremiumCollectionCheckoutModal.js +1 -1
- package/dist/cjs/PurchaseModals/PremiumSubscriptionCheckoutModal.js +1 -1
- package/dist/cjs/ReactionButtons.js +26 -13
- package/dist/cjs/SnackbarContextProvider.js +200 -116
- package/dist/cjs/Theme.js +217 -90
- package/dist/cjs/Toggle.js +86 -32
- package/dist/cjs/UserCard.js +13 -32
- package/dist/cjs/UserPage/LibraryControls.js +180 -93
- package/dist/cjs/UserPage/UserLibraryHeader.js +23 -14
- package/dist/cjs/UserPage/UserProfileHeader.js +120 -105
- package/dist/cjs/UsernameWithPopout.js +12 -8
- package/dist/cjs/colors.js +15 -8
- package/dist/cjs/helpers.js +131 -0
- package/dist/cjs/index.js +92 -58
- package/dist/cjs/neo-components/Autocomplete.js +280 -0
- package/dist/cjs/neo-components/BottomNavigation.js +120 -0
- package/dist/cjs/neo-components/Box.js +48 -0
- package/dist/cjs/neo-components/Button.js +206 -0
- package/dist/cjs/neo-components/CircularProgress.js +92 -0
- package/dist/cjs/neo-components/Container.js +75 -0
- package/dist/cjs/neo-components/Dialog.js +441 -0
- package/dist/cjs/neo-components/Fab.js +237 -0
- package/dist/cjs/neo-components/FormControls.js +1057 -0
- package/dist/cjs/neo-components/Grid.js +256 -0
- package/dist/cjs/neo-components/IconButton.js +111 -0
- package/dist/cjs/neo-components/Input.js +493 -0
- package/dist/cjs/neo-components/Layout.js +1213 -0
- package/dist/cjs/neo-components/Misc.js +858 -0
- package/dist/cjs/neo-components/Navigation.js +1578 -0
- package/dist/cjs/neo-components/Paper.js +256 -0
- package/dist/cjs/neo-components/Stack.js +194 -0
- package/dist/cjs/neo-components/Stepper.js +291 -0
- package/dist/cjs/neo-components/Text.js +290 -0
- package/dist/cjs/neo-components/ThemeProvider.js +731 -0
- package/dist/cjs/neo-components/ToggleButton.js +223 -0
- package/dist/cjs/neo-components/createTheme.js +306 -0
- package/dist/cjs/neo-components/withSx.js +164 -0
- package/dist/cjs/neo-utils/sxToStyle.js +508 -0
- package/dist/esm/Blerp/BlerpImageRow.js +166 -46
- package/dist/esm/Blerp/BlerpSavePopup.js +35 -27
- package/dist/esm/Blerp/BlerpTitleRow.js +32 -13
- package/dist/esm/Blerp/BlerpTopRow.js +85 -16
- package/dist/esm/Blerp.js +4 -12
- package/dist/esm/BlerpAudioContextProvider.js +1 -2
- package/dist/esm/BlerpListView.js +313 -160
- package/dist/esm/BlerpListViewPremium.js +135 -109
- package/dist/esm/BlerpListViewSkeleton.js +60 -11
- package/dist/esm/BlerpSkeleton.js +32 -7
- package/dist/esm/CollectionCard.js +118 -38
- package/dist/esm/CollectionListViewPremium.js +367 -294
- package/dist/esm/CollectionSkeleton.js +73 -11
- package/dist/esm/Dropdown.js +260 -161
- package/dist/esm/EllipsisLoader.js +63 -18
- package/dist/esm/GroupCard.js +54 -46
- package/dist/esm/Icons/Icons.js +226 -367
- package/dist/esm/ImageEditor.js +240 -0
- package/dist/esm/ImageUpload.js +217 -0
- package/dist/esm/NewBlerp.js +282 -79
- package/dist/esm/NewBlerpTest.js +11 -781
- package/dist/esm/NewCollectionModal.js +289 -304
- package/dist/esm/PremiumCollectionCard.js +192 -451
- package/dist/esm/PurchaseModals/CheckoutModal.js +1 -1
- package/dist/esm/PurchaseModals/PremiumBlerpCheckoutModal.js +1 -1
- package/dist/esm/PurchaseModals/PremiumCollectionCheckoutModal.js +1 -1
- package/dist/esm/PurchaseModals/PremiumSubscriptionCheckoutModal.js +1 -1
- package/dist/esm/ReactionButtons.js +23 -8
- package/dist/esm/SnackbarContextProvider.js +196 -110
- package/dist/esm/Theme.js +187 -66
- package/dist/esm/Toggle.js +84 -29
- package/dist/esm/UserCard.js +1 -20
- package/dist/esm/UserPage/LibraryControls.js +159 -65
- package/dist/esm/UserPage/UserLibraryHeader.js +18 -10
- package/dist/esm/UserPage/UserProfileHeader.js +100 -79
- package/dist/esm/UsernameWithPopout.js +7 -4
- package/dist/esm/colors.js +11 -9
- package/dist/esm/helpers.js +122 -0
- package/dist/esm/icons.js +1 -1
- package/dist/esm/index.js +32 -2
- package/dist/esm/neo-components/Autocomplete.js +269 -0
- package/dist/esm/neo-components/BottomNavigation.js +109 -0
- package/dist/esm/neo-components/Box.js +36 -0
- package/dist/esm/neo-components/Button.js +194 -0
- package/dist/esm/neo-components/CircularProgress.js +81 -0
- package/dist/esm/neo-components/Container.js +63 -0
- package/dist/esm/neo-components/Dialog.js +423 -0
- package/dist/esm/neo-components/Fab.js +225 -0
- package/dist/esm/neo-components/FormControls.js +1041 -0
- package/dist/esm/neo-components/Grid.js +244 -0
- package/dist/esm/neo-components/IconButton.js +99 -0
- package/dist/esm/neo-components/Input.js +478 -0
- package/dist/esm/neo-components/Layout.js +1179 -0
- package/dist/esm/neo-components/Misc.js +840 -0
- package/dist/esm/neo-components/Navigation.js +1556 -0
- package/dist/esm/neo-components/Paper.js +243 -0
- package/dist/esm/neo-components/Stack.js +182 -0
- package/dist/esm/neo-components/Stepper.js +278 -0
- package/dist/esm/neo-components/Text.js +277 -0
- package/dist/esm/neo-components/ThemeProvider.js +718 -0
- package/dist/esm/neo-components/ToggleButton.js +214 -0
- package/dist/esm/neo-components/createTheme.js +297 -0
- package/dist/esm/neo-components/withSx.js +153 -0
- package/dist/esm/neo-utils/sxToStyle.js +502 -0
- package/package.json +19 -15
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import '@babel/runtime/helpers/defineProperty';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts MUI sx prop to inline styles
|
|
5
|
+
* Handles spacing shortcuts, theme colors, pseudo-selectors, nested selectors, and responsive values
|
|
6
|
+
*/
|
|
7
|
+
// Spacing multiplier (MUI default is 8px)
|
|
8
|
+
const SPACING_UNIT = 8; // Map of sx shorthand props to CSS properties
|
|
9
|
+
|
|
10
|
+
const PROP_MAP = {
|
|
11
|
+
// Margin
|
|
12
|
+
m: 'margin',
|
|
13
|
+
mt: 'marginTop',
|
|
14
|
+
mb: 'marginBottom',
|
|
15
|
+
ml: 'marginLeft',
|
|
16
|
+
mr: 'marginRight',
|
|
17
|
+
mx: ['marginLeft', 'marginRight'],
|
|
18
|
+
my: ['marginTop', 'marginBottom'],
|
|
19
|
+
// Padding
|
|
20
|
+
p: 'padding',
|
|
21
|
+
pt: 'paddingTop',
|
|
22
|
+
pb: 'paddingBottom',
|
|
23
|
+
pl: 'paddingLeft',
|
|
24
|
+
pr: 'paddingRight',
|
|
25
|
+
px: ['paddingLeft', 'paddingRight'],
|
|
26
|
+
py: ['paddingTop', 'paddingBottom'],
|
|
27
|
+
// Sizing
|
|
28
|
+
w: 'width',
|
|
29
|
+
h: 'height',
|
|
30
|
+
minW: 'minWidth',
|
|
31
|
+
maxW: 'maxWidth',
|
|
32
|
+
minH: 'minHeight',
|
|
33
|
+
maxH: 'maxHeight',
|
|
34
|
+
// Flexbox
|
|
35
|
+
flexGrow: 'flexGrow',
|
|
36
|
+
flexShrink: 'flexShrink',
|
|
37
|
+
flexBasis: 'flexBasis',
|
|
38
|
+
justifyContent: 'justifyContent',
|
|
39
|
+
alignItems: 'alignItems',
|
|
40
|
+
alignSelf: 'alignSelf',
|
|
41
|
+
// Display
|
|
42
|
+
display: 'display',
|
|
43
|
+
overflow: 'overflow',
|
|
44
|
+
overflowX: 'overflowX',
|
|
45
|
+
overflowY: 'overflowY',
|
|
46
|
+
// Position
|
|
47
|
+
position: 'position',
|
|
48
|
+
top: 'top',
|
|
49
|
+
right: 'right',
|
|
50
|
+
bottom: 'bottom',
|
|
51
|
+
left: 'left',
|
|
52
|
+
zIndex: 'zIndex',
|
|
53
|
+
// Border
|
|
54
|
+
border: 'border',
|
|
55
|
+
borderTop: 'borderTop',
|
|
56
|
+
borderRight: 'borderRight',
|
|
57
|
+
borderBottom: 'borderBottom',
|
|
58
|
+
borderLeft: 'borderLeft',
|
|
59
|
+
borderColor: 'borderColor',
|
|
60
|
+
borderRadius: 'borderRadius',
|
|
61
|
+
borderWidth: 'borderWidth',
|
|
62
|
+
borderStyle: 'borderStyle',
|
|
63
|
+
// Background
|
|
64
|
+
bgcolor: 'backgroundColor',
|
|
65
|
+
backgroundColor: 'backgroundColor',
|
|
66
|
+
background: 'background',
|
|
67
|
+
backgroundImage: 'backgroundImage',
|
|
68
|
+
backgroundSize: 'backgroundSize',
|
|
69
|
+
backgroundPosition: 'backgroundPosition',
|
|
70
|
+
// Typography
|
|
71
|
+
fontFamily: 'fontFamily',
|
|
72
|
+
fontSize: 'fontSize',
|
|
73
|
+
fontStyle: 'fontStyle',
|
|
74
|
+
fontWeight: 'fontWeight',
|
|
75
|
+
letterSpacing: 'letterSpacing',
|
|
76
|
+
lineHeight: 'lineHeight',
|
|
77
|
+
textAlign: 'textAlign',
|
|
78
|
+
textDecoration: 'textDecoration',
|
|
79
|
+
textTransform: 'textTransform',
|
|
80
|
+
// Color
|
|
81
|
+
color: 'color',
|
|
82
|
+
// Shadow
|
|
83
|
+
boxShadow: 'boxShadow',
|
|
84
|
+
// Other
|
|
85
|
+
opacity: 'opacity',
|
|
86
|
+
cursor: 'cursor',
|
|
87
|
+
transition: 'transition',
|
|
88
|
+
transform: 'transform',
|
|
89
|
+
visibility: 'visibility',
|
|
90
|
+
whiteSpace: 'whiteSpace',
|
|
91
|
+
wordBreak: 'wordBreak',
|
|
92
|
+
boxSizing: 'boxSizing',
|
|
93
|
+
gap: 'gap',
|
|
94
|
+
rowGap: 'rowGap',
|
|
95
|
+
columnGap: 'columnGap',
|
|
96
|
+
gridTemplateColumns: 'gridTemplateColumns',
|
|
97
|
+
gridTemplateRows: 'gridTemplateRows',
|
|
98
|
+
gridColumn: 'gridColumn',
|
|
99
|
+
gridRow: 'gridRow',
|
|
100
|
+
flex: 'flex',
|
|
101
|
+
flexDirection: 'flexDirection',
|
|
102
|
+
flexWrap: 'flexWrap',
|
|
103
|
+
order: 'order',
|
|
104
|
+
// Additional MUI props
|
|
105
|
+
width: 'width',
|
|
106
|
+
height: 'height',
|
|
107
|
+
minWidth: 'minWidth',
|
|
108
|
+
maxWidth: 'maxWidth',
|
|
109
|
+
minHeight: 'minHeight',
|
|
110
|
+
maxHeight: 'maxHeight',
|
|
111
|
+
// Margin/padding with specific values
|
|
112
|
+
margin: 'margin',
|
|
113
|
+
padding: 'padding'
|
|
114
|
+
}; // Props that should resolve theme colors
|
|
115
|
+
|
|
116
|
+
const COLOR_PROPS = new Set(['color', 'backgroundColor', 'bgcolor', 'borderColor', 'background', 'borderTopColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'outlineColor', 'fill', 'stroke']);
|
|
117
|
+
/**
|
|
118
|
+
* Convert spacing value to pixels
|
|
119
|
+
* Numbers are multiplied by spacing unit, strings pass through
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
function parseSpacing(value) {
|
|
123
|
+
if (typeof value === 'number') {
|
|
124
|
+
return "".concat(value * SPACING_UNIT, "px");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return value;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if a value looks like a theme color reference
|
|
131
|
+
* e.g., "primary.main", "ibisRed.main", "grey6.main"
|
|
132
|
+
*/
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
function isThemeColorRef(value) {
|
|
136
|
+
if (typeof value !== 'string') return false; // Must have a dot, not be a URL, not have common CSS patterns
|
|
137
|
+
|
|
138
|
+
if (!value.includes('.')) return false;
|
|
139
|
+
if (value.startsWith('http') || value.startsWith('url(')) return false;
|
|
140
|
+
if (value.includes('px') || value.includes('%') || value.includes('rem')) return false;
|
|
141
|
+
if (value.startsWith('#') || value.startsWith('rgb') || value.startsWith('hsl')) return false;
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Resolve a theme color reference to an actual color value
|
|
146
|
+
* Handles: "ibisRed.main" -> "#FE295C"
|
|
147
|
+
* "notBlack.main" -> "#21000C"
|
|
148
|
+
* "grey6.main" -> looks up grey6 in colors
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
function resolveThemeColor(value) {
|
|
153
|
+
let themeColors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
154
|
+
if (!isThemeColorRef(value)) return value;
|
|
155
|
+
const parts = value.split('.');
|
|
156
|
+
let result = themeColors;
|
|
157
|
+
|
|
158
|
+
for (const part of parts) {
|
|
159
|
+
if (result && typeof result === 'object' && part in result) {
|
|
160
|
+
result = result[part];
|
|
161
|
+
} else {
|
|
162
|
+
// Color not found - return original value or a CSS variable fallback
|
|
163
|
+
const varName = "--".concat(value.replace(/\./g, '-').replace(/([A-Z])/g, '-$1').toLowerCase());
|
|
164
|
+
return "var(".concat(varName, ", ").concat(value, ")");
|
|
165
|
+
}
|
|
166
|
+
} // If we got a string, return it; if still an object, try .main
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
if (typeof result === 'string') {
|
|
170
|
+
return result;
|
|
171
|
+
} else if (result && typeof result === 'object' && 'main' in result) {
|
|
172
|
+
return result.main;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check if a key is a nested CSS selector (class, element, or complex selector)
|
|
179
|
+
* Examples: ".braintree-method", "& > div", "& .child", ".foo .bar"
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
function isNestedSelector(key) {
|
|
184
|
+
// Starts with a dot (class selector)
|
|
185
|
+
if (key.startsWith('.')) return true; // Starts with & (parent reference)
|
|
186
|
+
|
|
187
|
+
if (key.startsWith('&')) return true; // Contains spaces (complex selector)
|
|
188
|
+
|
|
189
|
+
if (key.includes(' ')) return true; // Element selectors (common ones)
|
|
190
|
+
|
|
191
|
+
const elementSelectors = ['div', 'span', 'p', 'a', 'button', 'input', 'img', 'svg', 'path'];
|
|
192
|
+
if (elementSelectors.includes(key)) return true;
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Check if a key is a pseudo-selector
|
|
197
|
+
* Examples: "&:hover", "&:disabled", "&[disabled]", "&::before"
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
function isPseudoSelector(key) {
|
|
202
|
+
if (!key.startsWith('&')) return false; // Must have : or [ after the &
|
|
203
|
+
|
|
204
|
+
const afterAmpersand = key.slice(1).trim();
|
|
205
|
+
return afterAmpersand.startsWith(':') || afterAmpersand.startsWith('[');
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check if a key is a media query
|
|
209
|
+
*/
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
function isMediaQuery(key) {
|
|
213
|
+
return key.startsWith('@media');
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Extract different types of styles from sx object
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
function extractSpecialSelectors(sx) {
|
|
221
|
+
const styles = {}; // Regular inline styles
|
|
222
|
+
|
|
223
|
+
const pseudos = {}; // Pseudo-selectors like &:hover
|
|
224
|
+
|
|
225
|
+
const nested = {}; // Nested selectors like .braintree-method
|
|
226
|
+
|
|
227
|
+
const mediaQueries = {}; // Media queries
|
|
228
|
+
|
|
229
|
+
for (const [key, value] of Object.entries(sx)) {
|
|
230
|
+
if (value === null || value === undefined) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (isMediaQuery(key)) {
|
|
235
|
+
mediaQueries[key] = value;
|
|
236
|
+
} else if (isPseudoSelector(key)) {
|
|
237
|
+
pseudos[key] = value;
|
|
238
|
+
} else if (isNestedSelector(key)) {
|
|
239
|
+
nested[key] = value;
|
|
240
|
+
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
241
|
+
// Could be responsive values { xs: ..., sm: ..., md: ... }
|
|
242
|
+
const isResponsive = Object.keys(value).some(k => ['xs', 'sm', 'md', 'lg', 'xl'].includes(k));
|
|
243
|
+
|
|
244
|
+
if (isResponsive) {
|
|
245
|
+
// For now, just use the first value or 'xs'
|
|
246
|
+
styles[key] = value.xs || value.sm || value.md || Object.values(value)[0];
|
|
247
|
+
} else {
|
|
248
|
+
// Unknown object structure - skip for inline styles
|
|
249
|
+
// This might be a nested selector without & prefix
|
|
250
|
+
nested[key] = value;
|
|
251
|
+
}
|
|
252
|
+
} else {
|
|
253
|
+
styles[key] = value;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
styles,
|
|
259
|
+
pseudos,
|
|
260
|
+
nested,
|
|
261
|
+
mediaQueries
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Convert a single sx value to a style value
|
|
266
|
+
*/
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
function convertValue(key, value, themeColors) {
|
|
270
|
+
// Handle null/undefined
|
|
271
|
+
if (value === null || value === undefined) return value; // Handle theme colors for color-related props
|
|
272
|
+
|
|
273
|
+
if (COLOR_PROPS.has(key) || COLOR_PROPS.has(PROP_MAP[key])) {
|
|
274
|
+
return resolveThemeColor(value, themeColors);
|
|
275
|
+
} // Handle spacing props
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
const spacingProps = ['m', 'mt', 'mb', 'ml', 'mr', 'mx', 'my', 'p', 'pt', 'pb', 'pl', 'pr', 'px', 'py', 'gap', 'rowGap', 'columnGap'];
|
|
279
|
+
|
|
280
|
+
if (spacingProps.includes(key)) {
|
|
281
|
+
return parseSpacing(value);
|
|
282
|
+
} // Handle borderRadius with theme spacing
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
if (key === 'borderRadius' && typeof value === 'number') {
|
|
286
|
+
return "".concat(value * 4, "px"); // MUI uses 4px for border radius units
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return value;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Convert an sx styles object to a flat CSS properties object
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
function convertStylesToCSS(styles, themeColors) {
|
|
297
|
+
const result = {};
|
|
298
|
+
|
|
299
|
+
for (const [key, value] of Object.entries(styles)) {
|
|
300
|
+
if (typeof value === 'object' && value !== null) {
|
|
301
|
+
continue; // Skip nested objects
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const cssProps = PROP_MAP[key] || key;
|
|
305
|
+
const convertedValue = convertValue(key, value, themeColors);
|
|
306
|
+
if (convertedValue === null || convertedValue === undefined) continue;
|
|
307
|
+
|
|
308
|
+
if (Array.isArray(cssProps)) {
|
|
309
|
+
cssProps.forEach(prop => {
|
|
310
|
+
result[prop] = convertedValue;
|
|
311
|
+
});
|
|
312
|
+
} else {
|
|
313
|
+
result[cssProps] = convertedValue;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Main function: Convert sx prop to inline style object
|
|
321
|
+
* @param {Object} sx - MUI sx prop object
|
|
322
|
+
* @param {Object} themeColors - Theme color mappings from ThemeProvider
|
|
323
|
+
* @returns {Object} - { style: {...}, pseudoStyles: {...}, nestedStyles: {...}, pseudoClassName: string }
|
|
324
|
+
*/
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
function sxToStyle(sx) {
|
|
328
|
+
let themeColors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
329
|
+
|
|
330
|
+
if (!sx || typeof sx !== 'object') {
|
|
331
|
+
return {
|
|
332
|
+
style: {},
|
|
333
|
+
pseudoStyles: {},
|
|
334
|
+
nestedStyles: {},
|
|
335
|
+
mediaQueries: {},
|
|
336
|
+
pseudoClassName: ''
|
|
337
|
+
};
|
|
338
|
+
} // Handle array of sx objects (MUI supports this)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
if (Array.isArray(sx)) {
|
|
342
|
+
const merged = sx.reduce((acc, sxObj) => {
|
|
343
|
+
if (sxObj) {
|
|
344
|
+
Object.assign(acc, sxObj);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return acc;
|
|
348
|
+
}, {});
|
|
349
|
+
return sxToStyle(merged, themeColors);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const {
|
|
353
|
+
styles,
|
|
354
|
+
pseudos,
|
|
355
|
+
nested,
|
|
356
|
+
mediaQueries
|
|
357
|
+
} = extractSpecialSelectors(sx); // Convert main styles
|
|
358
|
+
|
|
359
|
+
const result = convertStylesToCSS(styles, themeColors); // Process pseudo-selectors
|
|
360
|
+
|
|
361
|
+
const processedPseudos = {};
|
|
362
|
+
|
|
363
|
+
for (const [selector, pseudoSx] of Object.entries(pseudos)) {
|
|
364
|
+
if (typeof pseudoSx === 'object') {
|
|
365
|
+
processedPseudos[selector] = convertStylesToCSS(pseudoSx, themeColors);
|
|
366
|
+
}
|
|
367
|
+
} // Process nested selectors
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
const processedNested = {};
|
|
371
|
+
|
|
372
|
+
for (const [selector, nestedSx] of Object.entries(nested)) {
|
|
373
|
+
if (typeof nestedSx === 'object') {
|
|
374
|
+
// Recursively process nested styles (they might have their own pseudos/nested)
|
|
375
|
+
const {
|
|
376
|
+
styles: nestedStyles,
|
|
377
|
+
pseudos: nestedPseudos
|
|
378
|
+
} = extractSpecialSelectors(nestedSx);
|
|
379
|
+
processedNested[selector] = {
|
|
380
|
+
styles: convertStylesToCSS(nestedStyles, themeColors),
|
|
381
|
+
pseudos: {}
|
|
382
|
+
}; // Process any pseudo-selectors within the nested selector
|
|
383
|
+
|
|
384
|
+
for (const [pSelector, pSx] of Object.entries(nestedPseudos)) {
|
|
385
|
+
if (typeof pSx === 'object') {
|
|
386
|
+
processedNested[selector].pseudos[pSelector] = convertStylesToCSS(pSx, themeColors);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
} // Process media queries
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
const processedMediaQueries = {};
|
|
394
|
+
|
|
395
|
+
for (const [query, querySx] of Object.entries(mediaQueries)) {
|
|
396
|
+
if (typeof querySx === 'object') {
|
|
397
|
+
processedMediaQueries[query] = convertStylesToCSS(querySx, themeColors);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const hasSpecialStyles = Object.keys(processedPseudos).length > 0 || Object.keys(processedNested).length > 0 || Object.keys(processedMediaQueries).length > 0;
|
|
402
|
+
return {
|
|
403
|
+
style: result,
|
|
404
|
+
pseudoStyles: processedPseudos,
|
|
405
|
+
nestedStyles: processedNested,
|
|
406
|
+
mediaQueries: processedMediaQueries,
|
|
407
|
+
pseudoClassName: hasSpecialStyles ? "blerp-sx-".concat(Math.random().toString(36).substr(2, 9)) : ''
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Convert camelCase to kebab-case
|
|
412
|
+
*/
|
|
413
|
+
|
|
414
|
+
function toKebabCase(str) {
|
|
415
|
+
return str.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Convert a styles object to CSS declarations string
|
|
419
|
+
*/
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
function stylesToDeclarations(styles) {
|
|
423
|
+
return Object.entries(styles).filter(_ref => {
|
|
424
|
+
let [, val] = _ref;
|
|
425
|
+
return val !== null && val !== undefined && val !== '';
|
|
426
|
+
}).map(_ref2 => {
|
|
427
|
+
let [prop, val] = _ref2;
|
|
428
|
+
return "".concat(toKebabCase(prop), ": ").concat(val);
|
|
429
|
+
}).join('; ');
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Generate CSS string from all special styles (pseudos, nested, media queries)
|
|
433
|
+
*/
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
function generatePseudoCSS(className, pseudoStyles) {
|
|
437
|
+
let nestedStyles = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
438
|
+
let mediaQueries = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
|
|
439
|
+
|
|
440
|
+
if (!className) {
|
|
441
|
+
return '';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
let css = ''; // Generate pseudo-selector CSS
|
|
445
|
+
|
|
446
|
+
for (const [selector, styles] of Object.entries(pseudoStyles || {})) {
|
|
447
|
+
const cssSelector = selector.replace('&', ".".concat(className));
|
|
448
|
+
const declarations = stylesToDeclarations(styles);
|
|
449
|
+
|
|
450
|
+
if (declarations) {
|
|
451
|
+
css += "".concat(cssSelector, " { ").concat(declarations, " }\n");
|
|
452
|
+
}
|
|
453
|
+
} // Generate nested selector CSS
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
for (const [selector, data] of Object.entries(nestedStyles || {})) {
|
|
457
|
+
// Handle different selector formats
|
|
458
|
+
let cssSelector;
|
|
459
|
+
|
|
460
|
+
if (selector.startsWith('&')) {
|
|
461
|
+
// & .child or & > div
|
|
462
|
+
cssSelector = selector.replace('&', ".".concat(className));
|
|
463
|
+
} else if (selector.startsWith('.')) {
|
|
464
|
+
// .braintree-method - scope it under our class
|
|
465
|
+
cssSelector = ".".concat(className, " ").concat(selector);
|
|
466
|
+
} else {
|
|
467
|
+
// element selector like "div" or "span"
|
|
468
|
+
cssSelector = ".".concat(className, " ").concat(selector);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const declarations = stylesToDeclarations(data.styles || data);
|
|
472
|
+
|
|
473
|
+
if (declarations) {
|
|
474
|
+
css += "".concat(cssSelector, " { ").concat(declarations, " }\n");
|
|
475
|
+
} // Handle pseudo-selectors within nested selectors
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
if (data.pseudos) {
|
|
479
|
+
for (const [pSelector, pStyles] of Object.entries(data.pseudos)) {
|
|
480
|
+
const pCssSelector = "".concat(cssSelector).concat(pSelector.replace('&', ''));
|
|
481
|
+
const pDeclarations = stylesToDeclarations(pStyles);
|
|
482
|
+
|
|
483
|
+
if (pDeclarations) {
|
|
484
|
+
css += "".concat(pCssSelector, " { ").concat(pDeclarations, " }\n");
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
} // Generate media query CSS
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
for (const [query, styles] of Object.entries(mediaQueries || {})) {
|
|
492
|
+
const declarations = stylesToDeclarations(styles);
|
|
493
|
+
|
|
494
|
+
if (declarations) {
|
|
495
|
+
css += "".concat(query, " { .").concat(className, " { ").concat(declarations, " } }\n");
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return css;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export { sxToStyle as default, generatePseudoCSS, sxToStyle };
|
package/package.json
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blerp/design",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Blerp UI",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "rollup -c"
|
|
7
|
+
"build": "rollup -c",
|
|
8
|
+
"watch": "rollup -c -w"
|
|
8
9
|
},
|
|
9
10
|
"peerDependencies": {
|
|
10
|
-
"@mui/icons-material": "5.10.16",
|
|
11
11
|
"@mui/material": "5.10.16",
|
|
12
12
|
"react": "18.2.0",
|
|
13
|
-
"react-dom": "18.2.0"
|
|
13
|
+
"react-dom": "18.2.0",
|
|
14
|
+
"styled-components": "^5.0.0 || ^6.0.0"
|
|
15
|
+
},
|
|
16
|
+
"peerDependenciesMeta": {
|
|
17
|
+
"styled-components": {
|
|
18
|
+
"optional": true
|
|
19
|
+
},
|
|
20
|
+
"@mui/material": {
|
|
21
|
+
"optional": true
|
|
22
|
+
}
|
|
14
23
|
},
|
|
15
24
|
"dependencies": {
|
|
16
25
|
"@babel/runtime": "^7.14.0",
|
|
17
26
|
"@blerp/wavesurfer": "^6.4.2",
|
|
18
|
-
"
|
|
19
|
-
"@mui/styled-engine-sc": "5.10.16",
|
|
20
|
-
"react-avatar-editor": "13.0.0",
|
|
21
|
-
"react-color-extractor": "^1.1.2",
|
|
22
|
-
"react-dropzone": "14.2.3",
|
|
23
|
-
"react-palette": "^1.0.2",
|
|
24
|
-
"styled-components": "5.3.6"
|
|
25
|
-
},
|
|
26
|
-
"resolutions": {
|
|
27
|
-
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
|
|
27
|
+
"autoprefixer": "^10.4.23"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
30
30
|
"react",
|
|
@@ -38,12 +38,16 @@
|
|
|
38
38
|
"@babel/plugin-transform-runtime": "^7.23.9",
|
|
39
39
|
"@babel/preset-env": "^7.12.11",
|
|
40
40
|
"@babel/preset-react": "^7.12.10",
|
|
41
|
+
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest",
|
|
42
|
+
"@mui/styled-engine-sc": "5.10.16",
|
|
41
43
|
"@rollup/plugin-babel": "^5.2.2",
|
|
42
44
|
"@rollup/plugin-json": "^4.1.0",
|
|
45
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
43
46
|
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
|
44
47
|
"rollup": "^2.50.5",
|
|
45
48
|
"rollup-plugin-sourcemaps": "^0.6.3",
|
|
46
49
|
"rollup-plugin-styles": "^3.12.2",
|
|
47
|
-
"rollup-plugin-terser": "^7.0.2"
|
|
50
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
51
|
+
"styled-components": "5.3.6"
|
|
48
52
|
}
|
|
49
53
|
}
|