@animus-ui/system 0.1.0-next.8 → 0.1.0-next.9

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/index.js CHANGED
@@ -1,7 +1,67 @@
1
1
  import { a as borderShorthand, c as numericOrStringScale, i as gridItemRatio, l as numericScale, n as size, o as createTransform, r as gridItem, s as createScale, t as percentageOrAbsolute, u as stringScale } from "./size-Dge_rsuz.js";
2
- import { createElement, forwardRef } from "react";
2
+ import { createElement, forwardRef, useRef } from "react";
3
3
  //#region src/runtime/index.ts
4
4
  /**
5
+ * CSS properties that accept unitless numeric values.
6
+ * Bare numerics on properties NOT in this set receive `px`.
7
+ * Matches @emotion/unitless and React DOM's style handling.
8
+ */
9
+ const UNITLESS_PROPERTIES = new Set([
10
+ "animation-iteration-count",
11
+ "border-image-outset",
12
+ "border-image-slice",
13
+ "border-image-width",
14
+ "box-flex",
15
+ "box-flex-group",
16
+ "box-ordinal-group",
17
+ "column-count",
18
+ "columns",
19
+ "flex",
20
+ "flex-grow",
21
+ "flex-positive",
22
+ "flex-shrink",
23
+ "flex-negative",
24
+ "flex-order",
25
+ "font-weight",
26
+ "grid-area",
27
+ "grid-column",
28
+ "grid-column-end",
29
+ "grid-column-span",
30
+ "grid-column-start",
31
+ "grid-row",
32
+ "grid-row-end",
33
+ "grid-row-span",
34
+ "grid-row-start",
35
+ "line-clamp",
36
+ "line-height",
37
+ "opacity",
38
+ "order",
39
+ "orphans",
40
+ "tab-size",
41
+ "widows",
42
+ "z-index",
43
+ "zoom",
44
+ "fill-opacity",
45
+ "flood-opacity",
46
+ "stop-opacity",
47
+ "stroke-dasharray",
48
+ "stroke-dashoffset",
49
+ "stroke-miterlimit",
50
+ "stroke-opacity",
51
+ "stroke-width"
52
+ ]);
53
+ /**
54
+ * Apply unit fallback to a value for a given CSS property.
55
+ * Unitless numeric values on properties that expect length units receive `px`.
56
+ */
57
+ function applyUnitFallback(value, cssProperty) {
58
+ if (typeof value === "number") {
59
+ if (UNITLESS_PROPERTIES.has(cssProperty)) return String(value);
60
+ return `${value}px`;
61
+ }
62
+ return String(value);
63
+ }
64
+ /**
5
65
  * Serialize a system prop value to a lookup key matching the Rust
6
66
  * css_generator's serialize_value_key output format:
7
67
  * - Numbers and strings → their string representation
@@ -13,6 +73,19 @@ function serializeValueKey(value) {
13
73
  return String(value);
14
74
  }
15
75
  /**
76
+ * Resolve a dynamic prop value through scale lookup → transform → unit fallback.
77
+ * Scale lookup uses pre-resolved values shipped from the extraction pipeline.
78
+ */
79
+ function resolveValue(value, dc) {
80
+ const key = String(value);
81
+ const scaleResolved = dc.scaleValues?.[key];
82
+ if (scaleResolved != null) {
83
+ const transformed = dc.transform ? dc.transform(scaleResolved) : scaleResolved;
84
+ return String(transformed);
85
+ }
86
+ return applyUnitFallback(dc.transform ? dc.transform(value) : value, dc.varName);
87
+ }
88
+ /**
16
89
  * Create a lightweight component that applies extracted CSS class names.
17
90
  * Replaces Emotion's styled() for extracted components.
18
91
  *
@@ -23,8 +96,11 @@ function serializeValueKey(value) {
23
96
  *
24
97
  * The optional systemPropMap parameter provides the shared prop→value→className
25
98
  * lookup table, served as a virtual module by the Vite plugin.
99
+ *
100
+ * The optional dynamicPropConfig parameter provides CSS variable fallback
101
+ * metadata for props with detected dynamic usage.
26
102
  */
27
- function createComponent(element, className, config, systemPropMap) {
103
+ function createComponent(element, className, config, systemPropMap, dynamicPropConfig) {
28
104
  const variantProps = config.variants ? Object.keys(config.variants) : [];
29
105
  const stateProps = config.states || [];
30
106
  const systemPropNames = config.systemPropNames || [];
@@ -36,6 +112,8 @@ function createComponent(element, className, config, systemPropMap) {
36
112
  const isComponentElement = typeof element !== "string";
37
113
  const Component = forwardRef((props, ref) => {
38
114
  const classes = [className];
115
+ const prevDynKey = useRef("");
116
+ const prevDynStyle = useRef(null);
39
117
  if (config.variants) for (const [prop, vc] of Object.entries(config.variants)) {
40
118
  const value = props[prop] ?? vc.default;
41
119
  if (value != null) classes.push(`${className}--${prop}-${value}`);
@@ -43,11 +121,45 @@ function createComponent(element, className, config, systemPropMap) {
43
121
  if (config.states) {
44
122
  for (const state of config.states) if (props[state]) classes.push(`${className}--${state}`);
45
123
  }
46
- if (systemPropMap && systemPropNames.length > 0) {
47
- for (const propName of systemPropNames) if (propName in props) {
48
- const key = serializeValueKey(props[propName]);
49
- const cls = systemPropMap[propName]?.[key];
124
+ let dynKeyParts;
125
+ let dynStyle;
126
+ if (systemPropNames.length > 0) {
127
+ const { customPropMap, customDynamicConfig } = config;
128
+ for (const propName of systemPropNames) {
129
+ if (!(propName in props)) continue;
130
+ const propValue = props[propName];
131
+ if (propValue == null) continue;
132
+ const key = serializeValueKey(propValue);
133
+ const cls = customPropMap?.[propName]?.[key] ?? systemPropMap?.[propName]?.[key];
50
134
  if (cls) classes.push(cls);
135
+ else {
136
+ const dc = customDynamicConfig?.[propName] ?? dynamicPropConfig?.[propName];
137
+ if (dc) {
138
+ if (!dynKeyParts) dynKeyParts = [];
139
+ if (!dynStyle) dynStyle = {};
140
+ if (typeof propValue === "object" && propValue !== null && !Array.isArray(propValue)) for (const [bp, bpVal] of Object.entries(propValue)) {
141
+ if (bpVal == null) continue;
142
+ if (bp === "_") {
143
+ classes.push(dc.slotClass);
144
+ const finalVal = resolveValue(bpVal, dc);
145
+ dynStyle[dc.varName] = finalVal;
146
+ dynKeyParts.push(`${dc.varName}:${finalVal}`);
147
+ } else {
148
+ classes.push(`${dc.slotClass}-${bp}`);
149
+ const varName = `${dc.varName}-${bp}`;
150
+ const finalVal = resolveValue(bpVal, dc);
151
+ dynStyle[varName] = finalVal;
152
+ dynKeyParts.push(`${varName}:${finalVal}`);
153
+ }
154
+ }
155
+ else {
156
+ classes.push(dc.slotClass);
157
+ const finalVal = resolveValue(propValue, dc);
158
+ dynStyle[dc.varName] = finalVal;
159
+ dynKeyParts.push(`${dc.varName}:${finalVal}`);
160
+ }
161
+ }
162
+ }
51
163
  }
52
164
  }
53
165
  if (props.className) classes.push(props.className);
@@ -61,6 +173,17 @@ function createComponent(element, className, config, systemPropMap) {
61
173
  if (!isComponentElement) {}
62
174
  domProps[key] = value;
63
175
  }
176
+ if (dynKeyParts && dynStyle) {
177
+ const dynKey = dynKeyParts.join("|");
178
+ if (dynKey !== prevDynKey.current) {
179
+ prevDynKey.current = dynKey;
180
+ prevDynStyle.current = dynStyle;
181
+ }
182
+ domProps.style = props.style ? {
183
+ ...props.style,
184
+ ...prevDynStyle.current
185
+ } : prevDynStyle.current;
186
+ }
64
187
  return createElement(element, domProps);
65
188
  });
66
189
  Component.displayName = className;
@@ -7,8 +7,17 @@ interface ComponentConfig {
7
7
  variants?: Record<string, VariantConfig>;
8
8
  states?: string[];
9
9
  systemPropNames?: string[];
10
+ customPropMap?: Record<string, Record<string, string>>;
11
+ customDynamicConfig?: DynamicPropConfig;
10
12
  }
11
13
  type SystemPropMap = Record<string, Record<string, string>>;
14
+ type DynamicPropConfig = Record<string, {
15
+ varName: string;
16
+ slotClass: string;
17
+ transformName?: string;
18
+ transform?: (value: string | number) => string | number;
19
+ scaleValues?: Record<string, string>;
20
+ }>;
12
21
  type ElementType = string | React.ComponentType<any>;
13
22
  type AnimusComponent = ReturnType<typeof forwardRef> & {
14
23
  extend: () => never;
@@ -24,7 +33,10 @@ type AnimusComponent = ReturnType<typeof forwardRef> & {
24
33
  *
25
34
  * The optional systemPropMap parameter provides the shared prop→value→className
26
35
  * lookup table, served as a virtual module by the Vite plugin.
36
+ *
37
+ * The optional dynamicPropConfig parameter provides CSS variable fallback
38
+ * metadata for props with detected dynamic usage.
27
39
  */
28
- export declare function createComponent(element: ElementType, className: string, config: ComponentConfig, systemPropMap?: SystemPropMap): AnimusComponent;
40
+ export declare function createComponent(element: ElementType, className: string, config: ComponentConfig, systemPropMap?: SystemPropMap, dynamicPropConfig?: DynamicPropConfig): AnimusComponent;
29
41
  export {};
30
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,UAAU,EAAE,MAAM,OAAO,CAAC;AAElD,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAI5D,KAAK,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AAErD,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG;IACrD,MAAM,EAAE,MAAM,KAAK,CAAC;CACrB,CAAC;AAqBF;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EACvB,aAAa,CAAC,EAAE,aAAa,GAC5B,eAAe,CAwFjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,UAAU,EAAU,MAAM,OAAO,CAAC;AAE1D,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,mBAAmB,CAAC,EAAE,iBAAiB,CAAC;CACzC;AAED,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,KAAK,iBAAiB,GAAG,MAAM,CAC7B,MAAM,EACN;IACE,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,MAAM,GAAG,MAAM,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CACF,CAAC;AAIF,KAAK,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AAErD,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG;IACrD,MAAM,EAAE,MAAM,KAAK,CAAC;CACrB,CAAC;AAwHF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EACvB,aAAa,CAAC,EAAE,aAAa,EAC7B,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,eAAe,CAkKjB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animus-ui/system",
3
- "version": "0.1.0-next.8",
3
+ "version": "0.1.0-next.9",
4
4
  "description": "Animus design system builder — tokens, prop groups, global styles",
5
5
  "author": "codecaaron <airrobb@gmail.com>",
6
6
  "license": "MIT",