@vitus-labs/rocketstyle 0.76.0 → 0.79.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,747 @@
1
+ import { context as context$1, Provider as Provider$1, isEmpty, render, set, get, merge, config, pick, omit, compose } from '@vitus-labs/core';
2
+ export { context } from '@vitus-labs/core';
3
+ import React, { createContext, useContext, useState, useCallback, useRef, useImperativeHandle, forwardRef, useMemo } from 'react';
4
+ import hoistNonReactStatics from 'hoist-non-react-statics';
5
+
6
+ const MODE_DEFAULT = 'light';
7
+ const PSEUDO_KEYS = ['hover', 'active', 'focus', 'pressed'];
8
+ const THEME_MODES = {
9
+ light: true,
10
+ dark: true,
11
+ };
12
+ const THEME_MODES_INVERSED = {
13
+ dark: 'light',
14
+ light: 'dark',
15
+ };
16
+ const CONFIG_KEYS = [
17
+ 'provider',
18
+ 'consumer',
19
+ 'DEBUG',
20
+ 'name',
21
+ 'component',
22
+ 'inversed',
23
+ 'passProps',
24
+ 'styled',
25
+ ];
26
+ const STYLING_KEYS = ['theme', 'styles'];
27
+ const STATIC_KEYS = [...STYLING_KEYS, 'compose'];
28
+ const ALL_RESERVED_KEYS = [
29
+ ...Object.keys(THEME_MODES),
30
+ ...CONFIG_KEYS,
31
+ ...STATIC_KEYS,
32
+ 'attrs',
33
+ ];
34
+
35
+ const context = createContext({});
36
+ const useLocalContext = (consumer) => {
37
+ const ctx = consumer ? useContext(context) : {};
38
+ const result = consumer ? consumer((callback) => callback(ctx)) : {};
39
+ return { pseudo: {}, ...result };
40
+ };
41
+ const LocalProvider = context.Provider;
42
+
43
+ const usePseudoState = ({ onBlur, onFocus, onMouseDown, onMouseEnter, onMouseLeave, onMouseUp, }) => {
44
+ const [hover, setHover] = useState(false);
45
+ const [focus, setFocus] = useState(false);
46
+ const [pressed, setPressed] = useState(false);
47
+ const handleOnMouseEnter = useCallback((e) => {
48
+ setHover(true);
49
+ if (onMouseEnter)
50
+ onMouseEnter(e);
51
+ }, [onMouseEnter]);
52
+ const handleOnMouseLeave = useCallback((e) => {
53
+ setHover(false);
54
+ setPressed(false);
55
+ if (onMouseLeave)
56
+ onMouseLeave(e);
57
+ }, [onMouseLeave]);
58
+ const handleOnMouseDown = useCallback((e) => {
59
+ setPressed(true);
60
+ if (onMouseDown)
61
+ onMouseDown(e);
62
+ }, [onMouseDown]);
63
+ const handleOnMouseUp = useCallback((e) => {
64
+ setPressed(false);
65
+ if (onMouseUp)
66
+ onMouseUp(e);
67
+ }, [onMouseUp]);
68
+ const handleOnFocus = useCallback((e) => {
69
+ setFocus(true);
70
+ if (onFocus)
71
+ onFocus(e);
72
+ }, [onFocus]);
73
+ const handleOnBlur = useCallback((e) => {
74
+ setFocus(false);
75
+ if (onBlur)
76
+ onBlur(e);
77
+ }, [onBlur]);
78
+ return {
79
+ state: {
80
+ hover,
81
+ focus,
82
+ pressed,
83
+ },
84
+ events: {
85
+ onMouseEnter: handleOnMouseEnter,
86
+ onMouseLeave: handleOnMouseLeave,
87
+ onMouseDown: handleOnMouseDown,
88
+ onMouseUp: handleOnMouseUp,
89
+ onFocus: handleOnFocus,
90
+ onBlur: handleOnBlur,
91
+ },
92
+ };
93
+ };
94
+
95
+ const useRocketstyleRef = ({ $rocketstyleRef, ref }) => {
96
+ const internalRef = useRef(null);
97
+ useImperativeHandle($rocketstyleRef, () => internalRef.current);
98
+ useImperativeHandle(ref, () => internalRef.current);
99
+ return internalRef;
100
+ };
101
+
102
+ const Provider = ({ provider = Provider$1, inversed, ...props }) => {
103
+ const ctx = useContext(context$1);
104
+ const { theme, mode, provider: RocketstyleProvider, children, } = { ...ctx, ...props, provider };
105
+ let newMode = MODE_DEFAULT;
106
+ if (mode) {
107
+ newMode = inversed ? THEME_MODES_INVERSED[mode] : mode;
108
+ }
109
+ return (React.createElement(RocketstyleProvider, { mode: newMode, isDark: newMode === 'dark', isLight: newMode === 'light', theme: theme, provider: provider }, children));
110
+ };
111
+
112
+ const useThemeAttrs = ({ inversed }) => {
113
+ const { theme, mode: ctxMode = 'light', isDark: ctxDark, } = useContext(context$1) || {};
114
+ const mode = inversed ? THEME_MODES_INVERSED[ctxMode] : ctxMode;
115
+ const isDark = inversed ? !ctxDark : ctxDark;
116
+ const isLight = !isDark;
117
+ return { theme, mode, isDark, isLight };
118
+ };
119
+
120
+ const RocketStyleProviderComponent = (WrappedComponent) => forwardRef(({ onMouseEnter, onMouseLeave, onMouseUp, onMouseDown, onFocus, onBlur, $rocketstate, ...props }, ref) => {
121
+ // pseudo hook to detect states hover / pressed / focus
122
+ const pseudo = usePseudoState({
123
+ onMouseEnter,
124
+ onMouseLeave,
125
+ onMouseUp,
126
+ onMouseDown,
127
+ onFocus,
128
+ onBlur,
129
+ });
130
+ const updatedState = useMemo(() => ({
131
+ ...$rocketstate,
132
+ pseudo: { ...$rocketstate.pseudo, ...pseudo.state },
133
+ }), [$rocketstate, pseudo]);
134
+ return (React.createElement(LocalProvider, { value: updatedState },
135
+ React.createElement(WrappedComponent, { ...props, ...pseudo.events, ref: ref, "$rocketstate": updatedState })));
136
+ });
137
+
138
+ class ThemeManager {
139
+ baseTheme = new WeakMap();
140
+ dimensionsThemes = new WeakMap();
141
+ modeBaseTheme = { light: new WeakMap(), dark: new WeakMap() };
142
+ modeDimensionTheme = { light: new WeakMap(), dark: new WeakMap() };
143
+ }
144
+
145
+ /* eslint-disable no-param-reassign */
146
+ const removeUndefinedProps = (props) => Object.keys(props).reduce((acc, key) => {
147
+ const currentValue = props[key];
148
+ if (currentValue !== undefined)
149
+ return { ...acc, [key]: currentValue };
150
+ return acc;
151
+ }, {});
152
+ const pickStyledAttrs = (props, keywords) => Object.keys(props).reduce((acc, key) => {
153
+ if (keywords[key] && props[key])
154
+ acc[key] = props[key];
155
+ return acc;
156
+ }, {});
157
+ const calculateChainOptions = (options) => (args) => {
158
+ const result = {};
159
+ if (isEmpty(options))
160
+ return result;
161
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
162
+ // @ts-ignore
163
+ return options.reduce((acc, item) => Object.assign(acc, item(...args)), {});
164
+ };
165
+ const calculateStylingAttrs = ({ useBooleans, multiKeys }) => ({ props, dimensions }) => {
166
+ const result = {};
167
+ // (1) find dimension keys values & initialize
168
+ // object with possible options
169
+ Object.keys(dimensions).forEach((item) => {
170
+ const pickedProp = props[item];
171
+ const valueTypes = ['number', 'string'];
172
+ // if the property is mutli key, allow assign array as well
173
+ if (multiKeys && multiKeys[item] && Array.isArray(pickedProp)) {
174
+ result[item] = pickedProp;
175
+ }
176
+ // assign when it's only a string or number otherwise it's considered
177
+ // as invalid param
178
+ else if (valueTypes.includes(typeof pickedProp)) {
179
+ result[item] = pickedProp;
180
+ }
181
+ else {
182
+ result[item] = undefined;
183
+ }
184
+ });
185
+ // (2) if booleans are being used let's find the rest
186
+ if (useBooleans) {
187
+ const propsKeys = Object.keys(props).reverse();
188
+ Object.entries(result).forEach(([key, value]) => {
189
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
190
+ // @ts-ignore
191
+ const isMultiKey = multiKeys[key];
192
+ // when value in result is not assigned yet
193
+ if (!value) {
194
+ let newDimensionValue;
195
+ const keywords = Object.keys(dimensions[key]);
196
+ if (isMultiKey) {
197
+ newDimensionValue = propsKeys.filter((key) => keywords.includes(key));
198
+ }
199
+ else {
200
+ // reverse props to guarantee the last one will have
201
+ // a priority over previous ones
202
+ newDimensionValue = propsKeys.find((key) => {
203
+ if (keywords.includes(key) && props[key])
204
+ return key;
205
+ return false;
206
+ });
207
+ }
208
+ result[key] = newDimensionValue;
209
+ }
210
+ });
211
+ }
212
+ return result;
213
+ };
214
+
215
+ /* eslint-disable no-underscore-dangle */
216
+ const rocketStyleHOC = ({ inversed, attrs, priorityAttrs }) => {
217
+ // --------------------------------------------------
218
+ // .attrs(...)
219
+ // first we need to calculate final props which are
220
+ // being returned by using `attr` chaining method
221
+ // --------------------------------------------------
222
+ const calculateAttrs = calculateChainOptions(attrs);
223
+ const calculatePriorityAttrs = calculateChainOptions(priorityAttrs);
224
+ const Enhanced = (WrappedComponent) => forwardRef((props, ref) => {
225
+ const { theme, mode, isDark, isLight } = useThemeAttrs({
226
+ inversed,
227
+ });
228
+ const callbackParams = [theme, { render, mode, isDark, isLight }];
229
+ // --------------------------------------------------
230
+ // remove undefined props not to override potential default props
231
+ // only props with value (e.g. `null`) should override default props
232
+ // --------------------------------------------------
233
+ const filteredProps = removeUndefinedProps(props);
234
+ const prioritizedAttrs = calculatePriorityAttrs([
235
+ filteredProps,
236
+ ...callbackParams,
237
+ ]);
238
+ const finalAttrs = calculateAttrs([
239
+ {
240
+ ...prioritizedAttrs,
241
+ ...filteredProps,
242
+ },
243
+ ...callbackParams,
244
+ ]);
245
+ return (React.createElement(WrappedComponent, { "$rocketstyleRef": ref, ...prioritizedAttrs, ...finalAttrs, ...filteredProps }));
246
+ });
247
+ return Enhanced;
248
+ };
249
+
250
+ const createStaticsChainingEnhancers = ({ context, dimensionKeys, func, options, }) => {
251
+ const keys = [...dimensionKeys, ...STATIC_KEYS];
252
+ keys.forEach((item) => {
253
+ // eslint-disable-next-line no-param-reassign
254
+ context[item] = (props) => func(options, { [item]: props });
255
+ });
256
+ };
257
+ const createStaticsEnhancers = ({ context, options, }) => {
258
+ if (!isEmpty(options)) {
259
+ Object.assign(context, options);
260
+ }
261
+ };
262
+
263
+ /* eslint-disable import/prefer-default-export */
264
+ const removeNullableValues = (obj) => Object.entries(obj)
265
+ .filter(([, v]) => v != null && v !== false)
266
+ .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
267
+ // --------------------------------------------------------
268
+ // Remove All Empty Values
269
+ // --------------------------------------------------------
270
+ // type RemoveAllEmptyValues = (obj: Record<string, any>) => Record<string, any>
271
+ // export const removeAllEmptyValues: RemoveAllEmptyValues = (obj) =>
272
+ // Object.entries(obj)
273
+ // .filter(([, v]) => v != null)
274
+ // .reduce(
275
+ // (acc, [k, v]) => ({
276
+ // ...acc,
277
+ // [k]: typeof v === 'object' ? removeAllEmptyValues(v) : v,
278
+ // }),
279
+ // {}
280
+ // )
281
+
282
+ const isValidKey = (value) => value !== undefined && value !== null && value !== false;
283
+ const isMultiKey = (value) => {
284
+ if (typeof value === 'object' && value !== null)
285
+ return [true, get(value, 'propName')];
286
+ return [false, value];
287
+ };
288
+ const getDimensionsMap = ({ themes, useBooleans }) => {
289
+ const result = {
290
+ keysMap: {},
291
+ keywords: {},
292
+ };
293
+ if (isEmpty(themes))
294
+ return result;
295
+ return Object.entries(themes).reduce((accumulator, [key, value]) => {
296
+ const { keysMap, keywords } = accumulator;
297
+ keywords[key] = true;
298
+ Object.entries(value).forEach(([itemKey, itemValue]) => {
299
+ if (!isValidKey(itemValue))
300
+ return;
301
+ if (useBooleans) {
302
+ keywords[itemKey] = true;
303
+ }
304
+ set(keysMap, [key, itemKey], true);
305
+ });
306
+ return accumulator;
307
+ }, result);
308
+ };
309
+ const getKeys = (obj) => Object.keys(obj);
310
+ const getValues = (obj) => Object.values(obj);
311
+ const getDimensionsValues = (obj) => getValues(obj).map((item) => {
312
+ if (typeof item === 'object') {
313
+ return item.propName;
314
+ }
315
+ return item;
316
+ });
317
+ const getMultipleDimensions = (obj) => getValues(obj).reduce((accumulator, value) => {
318
+ if (typeof value === 'object') {
319
+ // eslint-disable-next-line no-param-reassign
320
+ if (value.multi === true)
321
+ accumulator[value.propName] = true;
322
+ }
323
+ return accumulator;
324
+ }, {});
325
+
326
+ /* eslint-disable no-param-reassign */
327
+ // --------------------------------------------------------
328
+ // Theme Mode Callback
329
+ // --------------------------------------------------------
330
+ const themeModeCallback = (light, dark) => (mode) => {
331
+ if (!mode || mode === 'light')
332
+ return light;
333
+ return dark;
334
+ };
335
+ themeModeCallback.isMode = true;
336
+ const isModeCallback = (value) => typeof value === 'function' &&
337
+ // @ts-ignore
338
+ value.toString() === themeModeCallback().toString();
339
+ const getThemeFromChain = (options, theme) => {
340
+ const result = {};
341
+ if (!options || isEmpty(options))
342
+ return result;
343
+ return options.reduce((acc, item) => merge(acc, item(theme, themeModeCallback, config.css)), result);
344
+ };
345
+ const getDimensionThemes = (theme, options) => {
346
+ const result = {};
347
+ if (isEmpty(options.dimensions))
348
+ return result;
349
+ return Object.entries(options.dimensions).reduce((acc, [key, value]) => {
350
+ const [, dimension] = isMultiKey(value);
351
+ const helper = options[key];
352
+ if (Array.isArray(helper) && helper.length > 0) {
353
+ const finalDimensionThemes = getThemeFromChain(helper, theme);
354
+ // eslint-disable-next-line no-param-reassign
355
+ acc[dimension] = removeNullableValues(finalDimensionThemes);
356
+ }
357
+ return acc;
358
+ }, result);
359
+ };
360
+ const getTheme = ({ rocketstate, themes, baseTheme }) => {
361
+ // generate final theme which will be passed to styled component
362
+ let finalTheme = { ...baseTheme };
363
+ Object.entries(rocketstate).forEach(([key, value]) => {
364
+ const keyTheme = themes[key];
365
+ if (Array.isArray(value)) {
366
+ value.forEach((item) => {
367
+ finalTheme = merge({}, finalTheme, keyTheme[item]);
368
+ });
369
+ }
370
+ else {
371
+ finalTheme = merge({}, finalTheme, keyTheme[value]);
372
+ }
373
+ });
374
+ return finalTheme;
375
+ };
376
+ const getThemeByMode = (object, mode) => Object.keys(object).reduce((acc, key) => {
377
+ const value = object[key];
378
+ if (typeof value === 'object' && value !== null) {
379
+ acc[key] = getThemeByMode(value, mode);
380
+ }
381
+ else if (isModeCallback(value)) {
382
+ acc[key] = value(mode);
383
+ }
384
+ else {
385
+ acc[key] = value;
386
+ }
387
+ return acc;
388
+ }, {});
389
+
390
+ const chainOptions = (opts, defaultOpts = []) => {
391
+ const result = [...defaultOpts];
392
+ if (typeof opts === 'function')
393
+ result.push(opts);
394
+ else if (typeof opts === 'object')
395
+ result.push(() => opts);
396
+ return result;
397
+ };
398
+ const chainOrOptions = (keys, opts, defaultOpts) => keys.reduce((acc, item) => ({ ...acc, [item]: opts[item] || defaultOpts[item] }), {});
399
+ const chainReservedKeyOptions = (keys, opts, defaultOpts) => keys.reduce((acc, item) => ({
400
+ ...acc,
401
+ [item]: chainOptions(opts[item], defaultOpts[item]),
402
+ }), {});
403
+
404
+ const calculateHocsFuncs = (options = {}) => Object.values(options)
405
+ .filter((item) => typeof item === 'function')
406
+ .reverse();
407
+
408
+ /* eslint-disable import/prefer-default-export */
409
+ const calculateStyles = (styles) => {
410
+ if (!styles)
411
+ return [];
412
+ return styles.map((item) => item(config.css));
413
+ };
414
+
415
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
416
+ const cloneAndEnhance = (defaultOpts, opts) =>
417
+ // @ts-ignore
418
+ rocketComponent({
419
+ ...defaultOpts,
420
+ attrs: chainOptions(opts.attrs, defaultOpts.attrs),
421
+ priorityAttrs: chainOptions(opts.priorityAttrs, defaultOpts.priorityAttrs),
422
+ statics: { ...defaultOpts.statics, ...opts.statics },
423
+ compose: { ...defaultOpts.compose, ...opts.compose },
424
+ ...chainOrOptions(CONFIG_KEYS, opts, defaultOpts),
425
+ ...chainReservedKeyOptions([...defaultOpts.dimensionKeys, ...STYLING_KEYS], opts, defaultOpts),
426
+ });
427
+ // --------------------------------------------------------
428
+ // styleComponent
429
+ // helper function which allows function chaining
430
+ // always returns a valid React component with static functions
431
+ // assigned, so it can be even rendered as a valid component
432
+ // or styles can be extended via its statics
433
+ // --------------------------------------------------------
434
+ // @ts-ignore
435
+ const rocketComponent = (options) => {
436
+ const { component, styles } = options;
437
+ const { styled } = config;
438
+ const _calculateStylingAttrs = calculateStylingAttrs({
439
+ multiKeys: options.multiKeys,
440
+ useBooleans: options.useBooleans,
441
+ });
442
+ const componentName = options.name || options.component.displayName || options.component.name;
443
+ // create styled component with all options.styles if available
444
+ const STYLED_COMPONENT = component.IS_ROCKETSTYLE || options.styled !== true
445
+ ? component
446
+ : styled(component) `
447
+ ${calculateStyles(styles)};
448
+ `;
449
+ // --------------------------------------------------------
450
+ // COMPONENT - Final component to be rendered
451
+ // --------------------------------------------------------
452
+ const RenderComponent = options.provider
453
+ ? RocketStyleProviderComponent(STYLED_COMPONENT)
454
+ : STYLED_COMPONENT;
455
+ // --------------------------------------------------------
456
+ // THEME - Cahed & Calculated theme(s)
457
+ // --------------------------------------------------------
458
+ const ThemeManager$1 = new ThemeManager();
459
+ // --------------------------------------------------------
460
+ // COMPOSE - high-order components
461
+ // --------------------------------------------------------
462
+ const hocsFuncs = [
463
+ rocketStyleHOC(options),
464
+ ...calculateHocsFuncs(options.compose),
465
+ ];
466
+ // --------------------------------------------------------
467
+ // ENHANCED COMPONENT (returned component)
468
+ // --------------------------------------------------------
469
+ // .attrs() chaining option is calculated in HOC and passed as props already
470
+ const EnhancedComponent = forwardRef(({ $rocketstyleRef, // it's forwarded from HOC which is always on top of all hocs
471
+ ...props }, ref) => {
472
+ // --------------------------------------------------
473
+ // handle refs
474
+ // (1) one is passed from inner HOC - $rocketstyleRef
475
+ // (2) second one is used to be used directly (e.g. inside hocs)
476
+ // --------------------------------------------------
477
+ const internalRef = useRocketstyleRef({ $rocketstyleRef, ref });
478
+ // --------------------------------------------------
479
+ // hover - focus - pressed state passed via context from parent component
480
+ // --------------------------------------------------
481
+ const localCtx = useLocalContext(options.consumer);
482
+ // --------------------------------------------------
483
+ // general theme and theme mode dark / light passed in context
484
+ // --------------------------------------------------
485
+ const { theme, mode } = useThemeAttrs(options);
486
+ // --------------------------------------------------
487
+ // calculate themes for all defined styling dimensions
488
+ // .theme(...) + defined dimensions like .states(...), .sizes(...), etc.
489
+ // --------------------------------------------------
490
+ // --------------------------------------------------
491
+ // BASE / DEFAULT THEME Object
492
+ // --------------------------------------------------
493
+ const baseTheme = useMemo(() => {
494
+ const helper = ThemeManager$1.baseTheme;
495
+ if (!helper.has(theme)) {
496
+ helper.set(theme, getThemeFromChain(options.theme, theme));
497
+ }
498
+ return helper.get(theme);
499
+ },
500
+ // recalculate this only when theme mode changes dark / light
501
+ [theme]);
502
+ // --------------------------------------------------
503
+ // DIMENSION(S) THEMES Object
504
+ // --------------------------------------------------
505
+ const themes = useMemo(() => {
506
+ const helper = ThemeManager$1.dimensionsThemes;
507
+ if (!helper.has(theme)) {
508
+ helper.set(theme, getDimensionThemes(theme, options));
509
+ }
510
+ return helper.get(theme);
511
+ },
512
+ // recalculate this only when theme object changes
513
+ [theme]);
514
+ // --------------------------------------------------
515
+ // BASE / DEFAULT MODE THEME Object
516
+ // --------------------------------------------------
517
+ const currentModeBaseTheme = useMemo(() => {
518
+ const helper = ThemeManager$1.modeBaseTheme[mode];
519
+ if (!helper.has(baseTheme)) {
520
+ helper.set(baseTheme, getThemeByMode(baseTheme, mode));
521
+ }
522
+ return helper.get(baseTheme);
523
+ },
524
+ // recalculate this only when theme mode changes dark / light
525
+ [mode, baseTheme]);
526
+ // --------------------------------------------------
527
+ // DIMENSION(S) MODE THEMES Object
528
+ // --------------------------------------------------
529
+ const currentModeThemes = useMemo(() => {
530
+ const helper = ThemeManager$1.modeDimensionTheme[mode];
531
+ if (!helper.has(themes)) {
532
+ helper.set(themes, getThemeByMode(themes, mode));
533
+ }
534
+ return helper.get(themes);
535
+ },
536
+ // recalculate this only when theme mode changes dark / light
537
+ [mode, themes]);
538
+ // --------------------------------------------------
539
+ // calculate reserved Keys defined in dimensions as styling keys
540
+ // there is no need to calculate this each time - keys are based on
541
+ // dimensions definitions
542
+ // --------------------------------------------------
543
+ const { keysMap: dimensions, keywords: reservedPropNames } = useMemo(() => getDimensionsMap({
544
+ themes,
545
+ useBooleans: options.useBooleans,
546
+ }), [themes]);
547
+ const RESERVED_STYLING_PROPS_KEYS = useMemo(() => Object.keys(reservedPropNames), [reservedPropNames]);
548
+ // --------------------------------------------------
549
+ // get final props which are (latest has the highest priority):
550
+ // (1) merged styling from context,
551
+ // (2) `attrs` chaining method, and from
552
+ // (3) passing them directly to component
553
+ // --------------------------------------------------
554
+ const { pseudo, ...mergeProps } = {
555
+ ...localCtx,
556
+ ...props,
557
+ };
558
+ // --------------------------------------------------
559
+ // pseudo rocket state
560
+ // calculate final component pseudo state including pseudo state
561
+ // from props and override by pseudo props from context
562
+ // --------------------------------------------------
563
+ const pseudoRocketstate = {
564
+ ...pseudo,
565
+ ...pick(props, PSEUDO_KEYS),
566
+ };
567
+ // --------------------------------------------------
568
+ // rocketstate
569
+ // calculate final component state including pseudo state
570
+ // passed as $rocketstate prop
571
+ // --------------------------------------------------
572
+ const rocketstate = _calculateStylingAttrs({
573
+ props: pickStyledAttrs(mergeProps, reservedPropNames),
574
+ dimensions,
575
+ });
576
+ const finalRocketstate = { ...rocketstate, pseudo: pseudoRocketstate };
577
+ // --------------------------------------------------
578
+ // rocketstyle
579
+ // calculated (based on styling props) final theme which will be passed
580
+ // to our styled component
581
+ // passed as $rocketstyle prop
582
+ // --------------------------------------------------
583
+ const rocketstyle = getTheme({
584
+ rocketstate,
585
+ themes: currentModeThemes,
586
+ baseTheme: currentModeBaseTheme,
587
+ });
588
+ // --------------------------------------------------
589
+ // final props
590
+ // final props passed to WrappedComponent
591
+ // excluding: styling props
592
+ // including: $rocketstyle, $rocketstate
593
+ // --------------------------------------------------
594
+ const finalProps = {
595
+ // this removes styling state from props and passes its state
596
+ // under rocketstate key only
597
+ ...omit(mergeProps, [...RESERVED_STYLING_PROPS_KEYS, ...PSEUDO_KEYS]),
598
+ // if enforced to pass styling props, we pass them directly
599
+ ...(options.passProps ? pick(mergeProps, options.passProps) : {}),
600
+ ref: ref || $rocketstyleRef ? internalRef : undefined,
601
+ // state props passed to styled component only, therefore the `$` symbol
602
+ $rocketstyle: rocketstyle,
603
+ $rocketstate: finalRocketstate,
604
+ };
605
+ // all the development stuff injected
606
+ if (process.env.NODE_ENV !== 'production') {
607
+ finalProps['data-rocketstyle'] = componentName;
608
+ }
609
+ return React.createElement(RenderComponent, { ...finalProps });
610
+ });
611
+ // ------------------------------------------------------
612
+ // This will hoist and generate dynamically next static methods
613
+ // for all dimensions available in configuration
614
+ // ------------------------------------------------------
615
+ const RocketComponent = compose(...hocsFuncs)(EnhancedComponent);
616
+ RocketComponent.IS_ROCKETSTYLE = true;
617
+ RocketComponent.displayName = componentName;
618
+ hoistNonReactStatics(RocketComponent, options.component);
619
+ // ------------------------------------------------------
620
+ // enhance for chaining methods
621
+ // ------------------------------------------------------
622
+ createStaticsChainingEnhancers({
623
+ context: RocketComponent,
624
+ dimensionKeys: options.dimensionKeys,
625
+ func: cloneAndEnhance,
626
+ options,
627
+ });
628
+ // ------------------------------------------------------
629
+ RocketComponent.IS_ROCKETSTYLE = true;
630
+ RocketComponent.displayName = componentName;
631
+ RocketComponent.meta = {};
632
+ // ------------------------------------------------------
633
+ // ------------------------------------------------------
634
+ // enhance for statics
635
+ // ------------------------------------------------------
636
+ createStaticsEnhancers({
637
+ context: RocketComponent.meta,
638
+ options: options.statics,
639
+ });
640
+ // @ts-ignore
641
+ RocketComponent.attrs = (attrs, { priority } = {}) => {
642
+ if (priority) {
643
+ return cloneAndEnhance(options, {
644
+ priorityAttrs: attrs,
645
+ });
646
+ }
647
+ return cloneAndEnhance(options, {
648
+ attrs: attrs,
649
+ });
650
+ };
651
+ // @ts-ignore
652
+ RocketComponent.config = (opts = {}) => {
653
+ const result = pick(opts, CONFIG_KEYS);
654
+ return cloneAndEnhance(options, result);
655
+ };
656
+ // @ts-ignore
657
+ RocketComponent.statics = (opts) =>
658
+ // @ts-ignore
659
+ cloneAndEnhance(options, { statics: opts });
660
+ RocketComponent.getStaticDimensions = (theme) => {
661
+ const themes = getDimensionThemes(theme, options);
662
+ const { keysMap, keywords } = getDimensionsMap({
663
+ themes,
664
+ useBooleans: options.useBooleans,
665
+ });
666
+ return {
667
+ dimensions: keysMap,
668
+ keywords,
669
+ useBooleans: options.useBooleans,
670
+ multiKeys: options.multiKeys,
671
+ };
672
+ };
673
+ RocketComponent.getDefaultAttrs = (props, theme, mode) => calculateChainOptions(options.attrs)([
674
+ props,
675
+ theme,
676
+ {
677
+ render,
678
+ mode,
679
+ isDark: mode === 'light',
680
+ isLight: mode === 'dark',
681
+ },
682
+ ]);
683
+ return RocketComponent;
684
+ };
685
+
686
+ const DEFAULT_DIMENSIONS = {
687
+ states: 'state',
688
+ sizes: 'size',
689
+ variants: 'variant',
690
+ multiple: {
691
+ propName: 'multiple',
692
+ multi: true,
693
+ },
694
+ };
695
+
696
+ // @ts-nocheck
697
+ const rocketstyle = ({ dimensions = DEFAULT_DIMENSIONS, useBooleans = true } = {}) => ({ name, component }) => {
698
+ // --------------------------------------------------------
699
+ // handle ERRORS in development mode
700
+ // --------------------------------------------------------
701
+ if (process.env.NODE_ENV !== 'production') {
702
+ const errors = {};
703
+ if (!component) {
704
+ errors.component = 'Parameter `component` is missing in params!';
705
+ }
706
+ if (!name) {
707
+ errors.name = 'Parameter `name` is missing in params!';
708
+ }
709
+ if (isEmpty(dimensions)) {
710
+ errors.dimensions = 'Parameter `dimensions` is missing in params!';
711
+ }
712
+ else {
713
+ const definedDimensions = getKeys(dimensions);
714
+ const invalidDimension = ALL_RESERVED_KEYS.some((item) => definedDimensions.includes(item));
715
+ if (invalidDimension) {
716
+ errors.invalidDimensions = `Some of your \`dimensions\` is invalid and uses reserved static keys which are
717
+ ${DEFAULT_DIMENSIONS.toString()}`;
718
+ }
719
+ }
720
+ if (!isEmpty(errors)) {
721
+ throw Error(JSON.stringify(errors));
722
+ }
723
+ }
724
+ return rocketComponent({
725
+ name,
726
+ component,
727
+ useBooleans,
728
+ dimensions,
729
+ dimensionKeys: getKeys(dimensions),
730
+ dimensionValues: getDimensionsValues(dimensions),
731
+ multiKeys: getMultipleDimensions(dimensions),
732
+ styled: true,
733
+ });
734
+ };
735
+
736
+ const isRocketComponent = (component) => {
737
+ if (component &&
738
+ typeof component === 'object' &&
739
+ component !== null &&
740
+ Object.prototype.hasOwnProperty.call(component, 'IS_ROCKETSTYLE')) {
741
+ return true;
742
+ }
743
+ return false;
744
+ };
745
+
746
+ export { Provider, rocketstyle as default, isRocketComponent, rocketstyle };
747
+ //# sourceMappingURL=vitus-labs-rocketstyle.native.js.map