@pyreon/rocketstyle 0.11.5 → 0.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +32 -32
  2. package/lib/index.d.ts +25 -6
  3. package/lib/index.js +122 -97
  4. package/package.json +25 -24
  5. package/src/__tests__/attrs.test.ts +49 -49
  6. package/src/__tests__/chaining.test.ts +27 -27
  7. package/src/__tests__/collection.test.ts +12 -12
  8. package/src/__tests__/compose.test.ts +10 -10
  9. package/src/__tests__/context.test.ts +65 -65
  10. package/src/__tests__/createLocalProvider.test.ts +53 -53
  11. package/src/__tests__/dimensions.test.ts +54 -54
  12. package/src/__tests__/e2e-styler.test.ts +142 -136
  13. package/src/__tests__/hooks.test.ts +41 -70
  14. package/src/__tests__/isRocketComponent.test.ts +11 -11
  15. package/src/__tests__/misc.test.ts +91 -91
  16. package/src/__tests__/providerConsumer.test.ts +54 -126
  17. package/src/__tests__/rocketstyleIntegration.test.ts +182 -255
  18. package/src/__tests__/themeUtils.test.ts +173 -173
  19. package/src/cache/index.ts +1 -1
  20. package/src/constants/booleanTags.ts +25 -25
  21. package/src/constants/defaultDimensions.ts +5 -5
  22. package/src/constants/index.ts +16 -16
  23. package/src/context/context.ts +13 -10
  24. package/src/context/createLocalProvider.ts +26 -13
  25. package/src/context/localContext.ts +2 -2
  26. package/src/hoc/index.ts +1 -1
  27. package/src/hoc/rocketstyleAttrsHoc.ts +26 -29
  28. package/src/hooks/index.ts +2 -2
  29. package/src/hooks/usePseudoState.ts +3 -3
  30. package/src/hooks/useTheme.ts +14 -17
  31. package/src/index.ts +32 -15
  32. package/src/init.ts +12 -12
  33. package/src/isRocketComponent.ts +2 -2
  34. package/src/rocketstyle.ts +125 -112
  35. package/src/types/attrs.ts +2 -2
  36. package/src/types/config.ts +4 -4
  37. package/src/types/configuration.ts +5 -5
  38. package/src/types/dimensions.ts +5 -5
  39. package/src/types/hoc.ts +1 -1
  40. package/src/types/rocketComponent.ts +4 -4
  41. package/src/types/rocketstyle.ts +10 -10
  42. package/src/types/styles.ts +9 -4
  43. package/src/types/theme.ts +4 -4
  44. package/src/types/utils.ts +1 -1
  45. package/src/utils/attrs.ts +2 -2
  46. package/src/utils/chaining.ts +2 -2
  47. package/src/utils/compose.ts +1 -1
  48. package/src/utils/dimensions.ts +6 -6
  49. package/src/utils/statics.ts +2 -2
  50. package/src/utils/styles.ts +2 -2
  51. package/src/utils/theme.ts +10 -10
package/README.md CHANGED
@@ -78,12 +78,12 @@ Button({ danger: true, lg: true, label: 'Delete' })
78
78
 
79
79
  A dimension is a named axis of style variation. The factory ships with four defaults:
80
80
 
81
- | Dimension | Prop name | Multi | Example |
82
- | --------- | --------- | ----- | ------- |
83
- | `states` | `state` | no | `primary`, `danger`, `success` |
84
- | `sizes` | `size` | no | `sm`, `md`, `lg` |
85
- | `variants` | `variant` | no | `outlined`, `filled` |
86
- | `multiple` | — | yes | `rounded`, `shadow` |
81
+ | Dimension | Prop name | Multi | Example |
82
+ | ---------- | --------- | ----- | ------------------------------ |
83
+ | `states` | `state` | no | `primary`, `danger`, `success` |
84
+ | `sizes` | `size` | no | `sm`, `md`, `lg` |
85
+ | `variants` | `variant` | no | `outlined`, `filled` |
86
+ | `multiple` | — | yes | `rounded`, `shadow` |
87
87
 
88
88
  Each dimension creates a chain method (`.states()`, `.sizes()`, etc.) and a corresponding prop on the component.
89
89
 
@@ -127,7 +127,9 @@ Factory initializer. Returns a function that accepts component configuration.
127
127
 
128
128
  ```ts
129
129
  const factory = rocketstyle({
130
- dimensions: { /* custom dimensions */ },
130
+ dimensions: {
131
+ /* custom dimensions */
132
+ },
131
133
  useBooleans: true,
132
134
  })
133
135
 
@@ -200,15 +202,15 @@ Button.states((theme, mode, css) => ({
200
202
  Define the CSS template using `@pyreon/styler`'s `css` tagged template.
201
203
 
202
204
  ```ts
203
- Button.styles((css) => css`
204
- cursor: pointer;
205
- border: none;
206
- transition: all 0.2s;
207
-
208
- ${({ $rocketstyle }) =>
209
- makeItResponsive({ theme: $rocketstyle, styles, css })
210
- }
211
- `)
205
+ Button.styles(
206
+ (css) => css`
207
+ cursor: pointer;
208
+ border: none;
209
+ transition: all 0.2s;
210
+
211
+ ${({ $rocketstyle }) => makeItResponsive({ theme: $rocketstyle, styles, css })}
212
+ `,
213
+ )
212
214
  ```
213
215
 
214
216
  ### .config(options)
@@ -254,11 +256,11 @@ Define your own dimensions by passing them to the factory:
254
256
  ```ts
255
257
  const rocketButton = rocketstyle({
256
258
  dimensions: {
257
- intent: 'intent', // prop: intent="primary"
258
- size: 'size', // prop: size="lg"
259
+ intent: 'intent', // prop: intent="primary"
260
+ size: 'size', // prop: size="lg"
259
261
  appearance: {
260
262
  propName: 'appearance',
261
- multi: true, // allows multiple values
263
+ multi: true, // allows multiple values
262
264
  },
263
265
  },
264
266
  })
@@ -308,9 +310,10 @@ const ButtonIcon = rocketstyle()({
308
310
  component: Element,
309
311
  })
310
312
  .config({
311
- consumer: (ctx) => ctx(({ pseudo }) => ({
312
- state: pseudo.hover ? 'active' : 'default',
313
- })),
313
+ consumer: (ctx) =>
314
+ ctx(({ pseudo }) => ({
315
+ state: pseudo.hover ? 'active' : 'default',
316
+ })),
314
317
  })
315
318
  .states({
316
319
  default: { color: '#666' },
@@ -318,10 +321,7 @@ const ButtonIcon = rocketstyle()({
318
321
  })
319
322
 
320
323
  // Icon reacts to parent's hover state
321
- ButtonGroup({ state: 'primary', children: [
322
- ButtonIcon({}),
323
- 'Label',
324
- ]})
324
+ ButtonGroup({ state: 'primary', children: [ButtonIcon({}), 'Label'] })
325
325
  ```
326
326
 
327
327
  ## Light / Dark Mode
@@ -339,12 +339,12 @@ Use `inversed: true` in `.config()` to flip the mode for a component subtree.
339
339
 
340
340
  ## Peer Dependencies
341
341
 
342
- | Package | Version |
343
- | ------- | ------- |
344
- | @pyreon/core | * |
345
- | @pyreon/reactivity | * |
346
- | @pyreon/ui-core | * |
347
- | @pyreon/styler | * |
342
+ | Package | Version |
343
+ | ------------------ | ------- |
344
+ | @pyreon/core | \* |
345
+ | @pyreon/reactivity | \* |
346
+ | @pyreon/ui-core | \* |
347
+ | @pyreon/styler | \* |
348
348
 
349
349
  ## License
350
350
 
package/lib/index.d.ts CHANGED
@@ -9,7 +9,7 @@ type Theme$1 = {
9
9
  type TProvider = {
10
10
  children: VNodeChild;
11
11
  theme?: Theme$1 | undefined;
12
- mode?: "light" | "dark" | undefined;
12
+ mode?: 'light' | 'dark' | undefined;
13
13
  inversed?: boolean | undefined;
14
14
  provider?: ((props: Record<string, unknown>) => VNodeChild) | undefined;
15
15
  };
@@ -95,8 +95,13 @@ type Css = typeof config.css;
95
95
  /**
96
96
  * Props available inside `.styles()` interpolation functions.
97
97
  *
98
- * - `$rocketstyle` — computed theme (inferred from `.theme()` chain)
98
+ * - `$rocketstyle` — resolved theme object (the styled() runtime resolves
99
+ * the reactive accessor before calling interpolation functions)
99
100
  * - `$rocketstate` — active dimension values + pseudo state
101
+ *
102
+ * Note: internally, rocketstyle passes $rocketstyle as a `() => CSS` accessor
103
+ * to DynamicStyled for reactive class swapping. But by the time interpolation
104
+ * functions run, it's always been resolved to a plain CSS object.
100
105
  */
101
106
  type RocketStyleInterpolationProps<CSS extends TObj = TObj> = {
102
107
  $rocketstyle: CSS;
@@ -123,13 +128,13 @@ declare const THEME_MODES: {
123
128
  interface ThemeDefault {}
124
129
  type Theme<T> = T extends unknown ? ThemeDefault : MergeTypes<[ThemeDefault, T]>;
125
130
  type ThemeModeKeys = keyof typeof THEME_MODES;
126
- type ThemeModeCallback = <A = any, B = any>(light: A, dark: B) => (mode: "light" | "dark") => A | B;
131
+ type ThemeModeCallback = <A = any, B = any>(light: A, dark: B) => (mode: 'light' | 'dark') => A | B;
127
132
  type ThemeMode = <A = any, B = any>(light: A, dark: B) => A | B;
128
133
  type ThemeCb<CSS, T> = (theme: T, mode: ThemeModeCallback, css: Css) => Partial<CSS>;
129
134
  //#endregion
130
135
  //#region src/types/dimensions.d.ts
131
136
  type ExtractNullableDimensionKeys<T> = { [P in keyof T as T[P] extends false ? never : P]: T[P] };
132
- type ExtractDimensionKey<T extends DimensionValue> = T extends DimensionValueObj ? T["propName"] : T;
137
+ type ExtractDimensionKey<T extends DimensionValue> = T extends DimensionValueObj ? T['propName'] : T;
133
138
  type ExtractDimensionMulti<T extends DimensionValue> = T extends DimensionValueObj ? true : false;
134
139
  type DimensionValuePrimitive = string;
135
140
  type DimensionValueObj = {
@@ -158,7 +163,7 @@ type RocketComponentType = ElementType & {
158
163
  IS_ROCKETSTYLE: true;
159
164
  $$rocketstyle: Record<string, unknown>;
160
165
  };
161
- type RocketProviderState<T extends RocketComponentType | TObj | unknown = unknown> = T extends RocketComponentType ? Partial<T["$$rocketstyle"]> & {
166
+ type RocketProviderState<T extends RocketComponentType | TObj | unknown = unknown> = T extends RocketComponentType ? Partial<T['$$rocketstyle']> & {
162
167
  pseudo: PseudoState;
163
168
  } : T;
164
169
  type ConsumerCtxCBValue<T extends RocketComponentType, D extends Dimensions, DKP extends TDKP> = (attrs: RocketProviderState<T>) => DKP extends TDKP ? Partial<ExtractDimensions<D, DKP> & {
@@ -290,5 +295,19 @@ type IsRocketComponent = <T>(component: T) => boolean;
290
295
  /** Runtime type guard — checks if a component was created by `rocketstyle()`. */
291
296
  declare const isRocketComponent: IsRocketComponent;
292
297
  //#endregion
293
- export { type AttrsCb, type ComponentFn, type ComposeParam, type ConfigAttrs, type ConsumerCb, type ConsumerCtxCBValue, type ConsumerCtxCb, type DefaultProps, type DimensionCallbackParam, type DimensionProps, type DimensionValue, type Dimensions, type ElementType, type ExtractDimensionProps, type ExtractDimensions, type ExtractProps, type GenericHoc, type IRocketStyleComponent, type IsRocketComponent, type MergeTypes, Provider, type RocketComponentType, type RocketProviderState, type RocketStyleComponent, type RocketStyleInterpolationProps, type Rocketstyle, type StylesCb, type StylesDefault, type TDKP, type TObj, type TProvider, type ThemeCb, type ThemeDefault, type ThemeMode, type ThemeModeCallback, type ThemeModeKeys, context, rocketstyle as default, rocketstyle, isRocketComponent };
298
+ //#region src/index.d.ts
299
+ /**
300
+ * Resolve a $rocketstyle value — handles both function accessor and plain object.
301
+ * Use in styled() interpolation functions when $rocketstyle may be a reactive accessor.
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * styled(Component)`
306
+ * color: ${(props) => resolveTheme(props.$rocketstyle).color};
307
+ * `
308
+ * ```
309
+ */
310
+ declare function resolveTheme<T = Record<string, unknown>>(value: (() => T) | T): T;
311
+ //#endregion
312
+ export { type AttrsCb, type ComponentFn, type ComposeParam, type ConfigAttrs, type ConsumerCb, type ConsumerCtxCBValue, type ConsumerCtxCb, type DefaultProps, type DimensionCallbackParam, type DimensionProps, type DimensionValue, type Dimensions, type ElementType, type ExtractDimensionProps, type ExtractDimensions, type ExtractProps, type GenericHoc, type IRocketStyleComponent, type IsRocketComponent, type MergeTypes, Provider, type RocketComponentType, type RocketProviderState, type RocketStyleComponent, type RocketStyleInterpolationProps, type Rocketstyle, type StylesCb, type StylesDefault, type TDKP, type TObj, type TProvider, type ThemeCb, type ThemeDefault, type ThemeMode, type ThemeModeCallback, type ThemeModeKeys, context, rocketstyle as default, rocketstyle, isRocketComponent, resolveTheme };
294
313
  //# sourceMappingURL=index2.d.ts.map
package/lib/index.js CHANGED
@@ -57,13 +57,13 @@ const ALL_RESERVED_KEYS = [
57
57
  */
58
58
  const Provider = ({ provider = Provider$1, inversed, ...props }) => {
59
59
  const { theme, mode, provider: RocketstyleProvider, children } = {
60
- ...useContext(context),
60
+ ...useContext(context)(),
61
61
  ...props,
62
62
  provider
63
63
  };
64
64
  let newMode = MODE_DEFAULT;
65
65
  if (mode) newMode = inversed ? THEME_MODES_INVERSED[mode] : mode;
66
- return RocketstyleProvider({
66
+ return (RocketstyleProvider ?? Provider$1)({
67
67
  mode: newMode,
68
68
  isDark: newMode === "dark",
69
69
  isLight: newMode === "light",
@@ -148,11 +148,6 @@ const createLocalProvider = (WrappedComponent) => {
148
148
  const hover = signal(false);
149
149
  const focus = signal(false);
150
150
  const pressed = signal(false);
151
- const pseudoState = () => ({
152
- hover: hover(),
153
- focus: focus(),
154
- pressed: pressed()
155
- });
156
151
  const events = {
157
152
  onMouseEnter: (e) => {
158
153
  hover.set(true);
@@ -180,11 +175,20 @@ const createLocalProvider = (WrappedComponent) => {
180
175
  if (onBlur) onBlur(e);
181
176
  }
182
177
  };
178
+ const resolvedState = typeof $rocketstate === "function" ? $rocketstate() : $rocketstate;
183
179
  const updatedState = {
184
- ...$rocketstate,
180
+ ...resolvedState,
185
181
  pseudo: {
186
- ...$rocketstate?.pseudo,
187
- ...pseudoState()
182
+ ...resolvedState?.pseudo,
183
+ get hover() {
184
+ return hover();
185
+ },
186
+ get focus() {
187
+ return focus();
188
+ },
189
+ get pressed() {
190
+ return pressed();
191
+ }
188
192
  }
189
193
  };
190
194
  provide(localContext, updatedState);
@@ -203,29 +207,26 @@ const createLocalProvider = (WrappedComponent) => {
203
207
  * Retrieves the current theme object and resolved mode from context.
204
208
  *
205
209
  * Returns an object with getter properties so that mode/isDark/isLight
206
- * are evaluated lazily on each access. This supports reactive mode
207
- * switching via PyreonUI when PyreonUI provides `get mode()` getters,
208
- * rocketstyle picks up changes on every styled component re-evaluation.
209
- *
210
- * Without getters, destructuring would capture the mode value once at
211
- * setup time, making theme switching permanently broken.
210
+ * are evaluated lazily on each access. The context is a ReactiveContext,
211
+ * so useContext returns `() => CoreContextValue` we call it inside
212
+ * each getter to ensure reactive tracking.
212
213
  */
213
214
  const useThemeAttrs = ({ inversed }) => {
214
- const ctx = useContext(context) || {};
215
+ const getCtx = useContext(context);
215
216
  return {
216
217
  get theme() {
217
- return ctx.theme ?? {};
218
+ return getCtx().theme ?? {};
218
219
  },
219
220
  get mode() {
220
- const ctxMode = ctx.mode ?? "light";
221
+ const ctxMode = getCtx().mode ?? "light";
221
222
  return inversed ? THEME_MODES_INVERSED[ctxMode] : ctxMode;
222
223
  },
223
224
  get isDark() {
224
- const ctxDark = ctx.isDark ?? false;
225
+ const ctxDark = getCtx().isDark ?? false;
225
226
  return inversed ? !ctxDark : ctxDark;
226
227
  },
227
228
  get isLight() {
228
- const ctxDark = ctx.isDark ?? false;
229
+ const ctxDark = getCtx().isDark ?? false;
229
230
  return !(inversed ? !ctxDark : ctxDark);
230
231
  }
231
232
  };
@@ -297,23 +298,21 @@ const rocketStyleHOC = ({ inversed, attrs, priorityAttrs }) => {
297
298
  const HOCComponent = (props) => {
298
299
  const themeAttrs = useThemeAttrs({ inversed });
299
300
  const filteredProps = removeUndefinedProps(props);
300
- return (() => {
301
- const callbackParams = [themeAttrs.theme, {
302
- render,
303
- mode: themeAttrs.mode,
304
- isDark: themeAttrs.isDark,
305
- isLight: themeAttrs.isLight
306
- }];
307
- const prioritizedAttrs = calculatePriorityAttrs([filteredProps, ...callbackParams]);
308
- const finalAttrs = calculateAttrs([{
309
- ...prioritizedAttrs,
310
- ...filteredProps
311
- }, ...callbackParams]);
312
- return WrappedComponent({
313
- ...prioritizedAttrs,
314
- ...finalAttrs,
315
- ...filteredProps
316
- });
301
+ const callbackParams = [themeAttrs.theme, {
302
+ render,
303
+ mode: themeAttrs.mode,
304
+ isDark: themeAttrs.isDark,
305
+ isLight: themeAttrs.isLight
306
+ }];
307
+ const prioritizedAttrs = calculatePriorityAttrs([filteredProps, ...callbackParams]);
308
+ const finalAttrs = calculateAttrs([{
309
+ ...prioritizedAttrs,
310
+ ...filteredProps
311
+ }, ...callbackParams]);
312
+ return WrappedComponent({
313
+ ...prioritizedAttrs,
314
+ ...finalAttrs,
315
+ ...filteredProps
317
316
  });
318
317
  };
319
318
  return HOCComponent;
@@ -499,77 +498,89 @@ const rocketComponent = (options) => {
499
498
  const EnhancedComponent = (props) => {
500
499
  const localCtx = useLocalContext(options.consumer);
501
500
  const themeAttrs = useThemeAttrs(options);
502
- const { pseudo, ...mergeProps } = {
503
- ...localCtx,
504
- ...props
505
- };
506
- const pseudoRocketstate = {
507
- ...pseudo,
508
- ...pick(props, [...PSEUDO_KEYS, ...PSEUDO_META_KEYS])
509
- };
510
- return (() => {
511
- const theme = themeAttrs.theme;
501
+ const theme = themeAttrs.theme;
502
+ const baseThemeHelper = ThemeManager$1.baseTheme;
503
+ if (!baseThemeHelper.has(theme)) baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme));
504
+ const baseTheme = baseThemeHelper.get(theme);
505
+ const dimHelper = ThemeManager$1.dimensionsThemes;
506
+ if (!dimHelper.has(theme)) dimHelper.set(theme, getDimensionThemes(theme, options));
507
+ const themes = dimHelper.get(theme);
508
+ const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
509
+ themes,
510
+ useBooleans: options.useBooleans
511
+ });
512
+ const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames);
513
+ const $rocketstyleAccessor = () => {
514
+ const { pseudo, ...mergeProps } = {
515
+ ...localCtx,
516
+ ...props
517
+ };
512
518
  const mode = themeAttrs.mode;
513
- const baseThemeHelper = ThemeManager$1.baseTheme;
514
- if (!baseThemeHelper.has(theme)) baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme));
515
- const baseTheme = baseThemeHelper.get(theme);
516
- const dimHelper = ThemeManager$1.dimensionsThemes;
517
- if (!dimHelper.has(theme)) dimHelper.set(theme, getDimensionThemes(theme, options));
518
- const themes = dimHelper.get(theme);
519
+ const rocketstate = _calculateStylingAttrs({
520
+ props: pickStyledAttrs(mergeProps, reservedPropNames),
521
+ dimensions
522
+ });
519
523
  const modeBaseHelper = ThemeManager$1.modeBaseTheme[mode];
520
524
  if (!modeBaseHelper.has(baseTheme)) modeBaseHelper.set(baseTheme, getThemeByMode(baseTheme, mode));
521
525
  const currentModeBaseTheme = modeBaseHelper.get(baseTheme);
522
526
  const modeDimHelper = ThemeManager$1.modeDimensionTheme[mode];
523
527
  if (!modeDimHelper.has(themes)) modeDimHelper.set(themes, getThemeByMode(themes, mode));
524
- const currentModeThemes = modeDimHelper.get(themes);
525
- const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
526
- themes,
527
- useBooleans: options.useBooleans
528
- });
529
- const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames);
530
- const rocketstate = _calculateStylingAttrs({
531
- props: pickStyledAttrs(mergeProps, reservedPropNames),
532
- dimensions
533
- });
534
- const finalRocketstate = {
535
- ...rocketstate,
536
- pseudo: pseudoRocketstate
537
- };
538
- const computedRocketstyle = getTheme({
528
+ return getTheme({
539
529
  rocketstate,
540
- themes: currentModeThemes,
530
+ themes: modeDimHelper.get(themes),
541
531
  baseTheme: currentModeBaseTheme,
542
532
  transformKeys: options.transformKeys,
543
533
  appTheme: theme
544
534
  });
545
- const finalProps = {
546
- ...omit(mergeProps, [
547
- ...RESERVED_STYLING_PROPS_KEYS,
548
- ...PSEUDO_KEYS,
549
- ...options.filterAttrs
550
- ]),
551
- ...options.passProps ? pick(mergeProps, options.passProps) : {},
552
- ref: props.ref,
553
- $rocketstyle: computedRocketstyle,
554
- $rocketstate: finalRocketstate
535
+ };
536
+ const $rocketstateAccessor = () => {
537
+ const { pseudo, ...mergeProps } = {
538
+ ...localCtx,
539
+ ...props
555
540
  };
556
- if (process.env.NODE_ENV !== "production") {
557
- finalProps["data-rocketstyle"] = componentName;
558
- if (options.DEBUG) {
559
- const debugPayload = {
560
- component: componentName,
561
- rocketstate: finalRocketstate,
562
- rocketstyle: computedRocketstyle,
563
- dimensions,
564
- mode,
565
- reservedPropNames: RESERVED_STYLING_PROPS_KEYS,
566
- filteredAttrs: options.filterAttrs
567
- };
568
- console.debug(`[rocketstyle] ${componentName} render:`, debugPayload);
569
- }
541
+ const pseudoRocketstate = {
542
+ ...pseudo,
543
+ ...pick(props, [...PSEUDO_KEYS, ...PSEUDO_META_KEYS])
544
+ };
545
+ return {
546
+ ..._calculateStylingAttrs({
547
+ props: pickStyledAttrs(mergeProps, reservedPropNames),
548
+ dimensions
549
+ }),
550
+ pseudo: pseudoRocketstate
551
+ };
552
+ };
553
+ const { pseudo: _pseudo, ...mergeProps } = {
554
+ ...localCtx,
555
+ ...props
556
+ };
557
+ const finalProps = {
558
+ ...omit(mergeProps, [
559
+ ...RESERVED_STYLING_PROPS_KEYS,
560
+ ...PSEUDO_KEYS,
561
+ ...options.filterAttrs
562
+ ]),
563
+ ...options.passProps ? pick(mergeProps, options.passProps) : {},
564
+ ref: props.ref,
565
+ $rocketstyle: $rocketstyleAccessor,
566
+ $rocketstate: $rocketstateAccessor
567
+ };
568
+ if (process.env.NODE_ENV !== "production") {
569
+ finalProps["data-rocketstyle"] = componentName;
570
+ if (options.DEBUG) {
571
+ const debugPayload = {
572
+ component: componentName,
573
+ rocketstate: $rocketstateAccessor(),
574
+ rocketstyle: $rocketstyleAccessor(),
575
+ dimensions,
576
+ mode: themeAttrs.mode,
577
+ reservedPropNames: RESERVED_STYLING_PROPS_KEYS,
578
+ filteredAttrs: options.filterAttrs
579
+ };
580
+ console.debug(`[rocketstyle] ${componentName} render:`, debugPayload);
570
581
  }
571
- return RenderComponent(finalProps);
572
- });
582
+ }
583
+ return RenderComponent(finalProps);
573
584
  };
574
585
  const FinalComponent = compose(...hocsFuncs)(EnhancedComponent);
575
586
  FinalComponent.IS_ROCKETSTYLE = true;
@@ -672,8 +683,22 @@ const isRocketComponent = (component) => {
672
683
 
673
684
  //#endregion
674
685
  //#region src/index.ts
686
+ /**
687
+ * Resolve a $rocketstyle value — handles both function accessor and plain object.
688
+ * Use in styled() interpolation functions when $rocketstyle may be a reactive accessor.
689
+ *
690
+ * @example
691
+ * ```ts
692
+ * styled(Component)`
693
+ * color: ${(props) => resolveTheme(props.$rocketstyle).color};
694
+ * `
695
+ * ```
696
+ */
697
+ function resolveTheme(value) {
698
+ return typeof value === "function" ? value() : value;
699
+ }
675
700
  var src_default = rocketstyle;
676
701
 
677
702
  //#endregion
678
- export { Provider, context, src_default as default, isRocketComponent, rocketstyle };
703
+ export { Provider, context, src_default as default, isRocketComponent, resolveTheme, rocketstyle };
679
704
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,24 +1,13 @@
1
1
  {
2
2
  "name": "@pyreon/rocketstyle",
3
- "version": "0.11.5",
3
+ "version": "0.11.7",
4
+ "description": "Multi-dimensional style composition for Pyreon components",
5
+ "license": "MIT",
4
6
  "repository": {
5
7
  "type": "git",
6
8
  "url": "https://github.com/pyreon/pyreon",
7
9
  "directory": "packages/ui-system/rocketstyle"
8
10
  },
9
- "description": "Multi-dimensional style composition for Pyreon components",
10
- "license": "MIT",
11
- "type": "module",
12
- "sideEffects": false,
13
- "exports": {
14
- ".": {
15
- "bun": "./src/index.ts",
16
- "import": "./lib/index.js",
17
- "types": "./lib/index.d.ts"
18
- }
19
- },
20
- "types": "./lib/index.d.ts",
21
- "main": "./lib/index.js",
22
11
  "files": [
23
12
  "lib",
24
13
  "!lib/**/*.map",
@@ -27,8 +16,16 @@
27
16
  "LICENSE",
28
17
  "src"
29
18
  ],
30
- "engines": {
31
- "node": ">= 22"
19
+ "type": "module",
20
+ "sideEffects": false,
21
+ "main": "./lib/index.js",
22
+ "types": "./lib/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "bun": "./src/index.ts",
26
+ "import": "./lib/index.js",
27
+ "types": "./lib/index.d.ts"
28
+ }
32
29
  },
33
30
  "publishConfig": {
34
31
  "access": "public"
@@ -37,20 +34,24 @@
37
34
  "prepublish": "bun run build",
38
35
  "build": "bun run vl_rolldown_build",
39
36
  "build:watch": "bun run vl_rolldown_build-watch",
40
- "lint": "biome check src/",
37
+ "lint": "oxlint .",
41
38
  "test": "vitest run",
42
39
  "test:coverage": "vitest run --coverage",
43
40
  "test:watch": "vitest",
44
41
  "typecheck": "tsc --noEmit"
45
42
  },
43
+ "devDependencies": {
44
+ "@pyreon/test-utils": "^0.11.7",
45
+ "@pyreon/typescript": "^0.11.7",
46
+ "@vitus-labs/tools-rolldown": "^1.15.3"
47
+ },
46
48
  "peerDependencies": {
47
- "@pyreon/core": "^0.11.5",
48
- "@pyreon/reactivity": "^0.11.5",
49
- "@pyreon/ui-core": "^0.11.5",
50
- "@pyreon/styler": "^0.11.5"
49
+ "@pyreon/core": "^0.11.7",
50
+ "@pyreon/reactivity": "^0.11.7",
51
+ "@pyreon/styler": "^0.11.7",
52
+ "@pyreon/ui-core": "^0.11.7"
51
53
  },
52
- "devDependencies": {
53
- "@vitus-labs/tools-rolldown": "^1.15.3",
54
- "@pyreon/typescript": "^0.11.5"
54
+ "engines": {
55
+ "node": ">= 22"
55
56
  }
56
57
  }