@clearstory/drywall-react 7.0.1 → 7.2.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.
- package/dist/eslint-config/index.js +18 -6
- package/dist/eslint-config/no-shorthand-spacing.d.ts +3 -0
- package/dist/eslint-config/no-shorthand-spacing.js +57 -0
- package/dist/eslint-config/no-system-props.js +58 -29
- package/dist/eslint-config/prefer-logical-properties.d.ts +3 -0
- package/dist/eslint-config/prefer-logical-properties.js +72 -0
- package/dist/eslint-config/prefer-vars-palette.d.ts +3 -0
- package/dist/eslint-config/prefer-vars-palette.js +130 -0
- package/dist/eslint-config/sx-utils.d.ts +53 -0
- package/dist/eslint-config/sx-utils.js +67 -0
- package/package.json +3 -3
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import e from "./no-
|
|
1
|
+
import e from "./no-shorthand-spacing.js";
|
|
2
|
+
import l from "./no-system-props.js";
|
|
3
|
+
import a from "./prefer-logical-properties.js";
|
|
4
|
+
import o from "./prefer-vars-palette.js";
|
|
2
5
|
const r = {
|
|
3
6
|
rules: {
|
|
4
|
-
"no-
|
|
7
|
+
"no-shorthand-spacing": e,
|
|
8
|
+
"no-system-props": l,
|
|
9
|
+
"prefer-logical-properties": a,
|
|
10
|
+
"prefer-vars-palette": o
|
|
5
11
|
},
|
|
6
12
|
configs: {}
|
|
7
13
|
};
|
|
@@ -11,19 +17,25 @@ r.configs.recommended = {
|
|
|
11
17
|
"@clearstory/drywall-react": r
|
|
12
18
|
},
|
|
13
19
|
rules: {
|
|
14
|
-
"@clearstory/drywall-react/no-
|
|
20
|
+
"@clearstory/drywall-react/no-shorthand-spacing": "error",
|
|
21
|
+
"@clearstory/drywall-react/no-system-props": "error",
|
|
22
|
+
"@clearstory/drywall-react/prefer-logical-properties": "error",
|
|
23
|
+
"@clearstory/drywall-react/prefer-vars-palette": "error"
|
|
15
24
|
}
|
|
16
25
|
};
|
|
17
|
-
const
|
|
26
|
+
const y = {
|
|
18
27
|
name: "@clearstory/drywall-react",
|
|
19
28
|
plugins: {
|
|
20
29
|
"@clearstory/drywall-react": r
|
|
21
30
|
},
|
|
22
31
|
rules: {
|
|
23
|
-
"@clearstory/drywall-react/no-
|
|
32
|
+
"@clearstory/drywall-react/no-shorthand-spacing": "error",
|
|
33
|
+
"@clearstory/drywall-react/no-system-props": "error",
|
|
34
|
+
"@clearstory/drywall-react/prefer-logical-properties": "error",
|
|
35
|
+
"@clearstory/drywall-react/prefer-vars-palette": "error"
|
|
24
36
|
}
|
|
25
37
|
};
|
|
26
38
|
export {
|
|
27
|
-
|
|
39
|
+
y as default,
|
|
28
40
|
r as plugin
|
|
29
41
|
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { createSxVisitor as i } from "./sx-utils.js";
|
|
2
|
+
const s = {
|
|
3
|
+
p: "padding",
|
|
4
|
+
pt: "paddingTop",
|
|
5
|
+
pr: "paddingRight",
|
|
6
|
+
pb: "paddingBottom",
|
|
7
|
+
pl: "paddingLeft",
|
|
8
|
+
px: "paddingX",
|
|
9
|
+
py: "paddingY",
|
|
10
|
+
m: "margin",
|
|
11
|
+
mt: "marginTop",
|
|
12
|
+
mr: "marginRight",
|
|
13
|
+
mb: "marginBottom",
|
|
14
|
+
ml: "marginLeft",
|
|
15
|
+
mx: "marginX",
|
|
16
|
+
my: "marginY"
|
|
17
|
+
}, g = {
|
|
18
|
+
meta: {
|
|
19
|
+
type: "suggestion",
|
|
20
|
+
fixable: "code",
|
|
21
|
+
docs: {
|
|
22
|
+
description: "Disallow MUI spacing shorthands (p, pt, m, mx, etc.) in sx props",
|
|
23
|
+
category: "Best Practices",
|
|
24
|
+
recommended: !0
|
|
25
|
+
},
|
|
26
|
+
messages: {
|
|
27
|
+
shorthandSpacing: 'Use "{{replacement}}" instead of shorthand "{{property}}" in sx for readability.'
|
|
28
|
+
},
|
|
29
|
+
schema: []
|
|
30
|
+
},
|
|
31
|
+
create(a) {
|
|
32
|
+
return i({
|
|
33
|
+
onProperty(n, e) {
|
|
34
|
+
const t = s[n];
|
|
35
|
+
t && a.report({
|
|
36
|
+
node: e,
|
|
37
|
+
messageId: "shorthandSpacing",
|
|
38
|
+
data: { property: n, replacement: t },
|
|
39
|
+
fix(p) {
|
|
40
|
+
const r = e;
|
|
41
|
+
if (e.type === "Literal") {
|
|
42
|
+
const o = a.sourceCode.getText(r)[0];
|
|
43
|
+
return p.replaceText(
|
|
44
|
+
r,
|
|
45
|
+
`${o}${t}${o}`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return p.replaceText(r, t);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export {
|
|
56
|
+
g as default
|
|
57
|
+
};
|
|
@@ -122,10 +122,28 @@ const g = [
|
|
|
122
122
|
"typography",
|
|
123
123
|
// other common system props
|
|
124
124
|
"spacing"
|
|
125
|
-
],
|
|
125
|
+
], u = {
|
|
126
|
+
// color: semantic theme colors (primary, secondary, error, etc.)
|
|
126
127
|
Typography: ["color"],
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
Link: ["color"],
|
|
129
|
+
Button: ["color"],
|
|
130
|
+
ButtonGroup: ["color"],
|
|
131
|
+
IconButton: ["color"],
|
|
132
|
+
Chip: ["color"],
|
|
133
|
+
Badge: ["color"],
|
|
134
|
+
Alert: ["color"],
|
|
135
|
+
CircularProgress: ["color"],
|
|
136
|
+
LinearProgress: ["color"],
|
|
137
|
+
Radio: ["color"],
|
|
138
|
+
Checkbox: ["color"],
|
|
139
|
+
Switch: ["color"],
|
|
140
|
+
SvgIcon: ["color"],
|
|
141
|
+
FormLabel: ["color"],
|
|
142
|
+
FormControl: ["color"],
|
|
143
|
+
ToggleButton: ["color"],
|
|
144
|
+
ToggleButtonGroup: ["color"],
|
|
145
|
+
// Container: maxWidth accepts breakpoint values (xs, sm, md, lg, xl), not CSS values
|
|
146
|
+
Container: ["maxWidth"]
|
|
129
147
|
}, h = {
|
|
130
148
|
meta: {
|
|
131
149
|
type: "problem",
|
|
@@ -139,52 +157,55 @@ const g = [
|
|
|
139
157
|
},
|
|
140
158
|
schema: []
|
|
141
159
|
},
|
|
142
|
-
create(
|
|
143
|
-
const o = /* @__PURE__ */ new
|
|
160
|
+
create(t) {
|
|
161
|
+
const o = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Set();
|
|
144
162
|
return {
|
|
145
163
|
ImportDeclaration(l) {
|
|
146
164
|
const r = l;
|
|
147
165
|
r.source.value === "@clearstory/drywall-react" && r.specifiers.forEach((e) => {
|
|
148
|
-
e.type === "ImportSpecifier" && e.imported
|
|
166
|
+
e.type === "ImportSpecifier" && e.imported ? o.set(e.local.name, e.imported.name) : e.type === "ImportNamespaceSpecifier" && p.add(e.local.name);
|
|
149
167
|
});
|
|
150
168
|
},
|
|
151
169
|
JSXOpeningElement(l) {
|
|
152
170
|
const r = l;
|
|
153
|
-
let e;
|
|
171
|
+
let e, s;
|
|
154
172
|
if ("name" in r.name) {
|
|
155
173
|
if (e = r.name.name, !o.has(e))
|
|
156
174
|
return;
|
|
175
|
+
s = o.get(e);
|
|
157
176
|
} else if (r.name.type === "JSXMemberExpression") {
|
|
158
|
-
const
|
|
159
|
-
if (e = r.name.property.name,
|
|
177
|
+
const n = r.name.object.name;
|
|
178
|
+
if (e = r.name.property.name, s = e, !p.has(n))
|
|
160
179
|
return;
|
|
161
180
|
} else
|
|
162
181
|
return;
|
|
163
|
-
const
|
|
164
|
-
r.attributes.forEach((
|
|
165
|
-
const i =
|
|
182
|
+
const m = [];
|
|
183
|
+
r.attributes.forEach((n) => {
|
|
184
|
+
const i = n;
|
|
166
185
|
if (i.type !== "JSXAttribute" || !i.name)
|
|
167
186
|
return;
|
|
168
187
|
const a = i.name.name;
|
|
169
188
|
if (a === "sx" || !g.includes(a))
|
|
170
189
|
return;
|
|
171
|
-
const
|
|
172
|
-
if (
|
|
173
|
-
if (a === "color"
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
190
|
+
const d = u[s];
|
|
191
|
+
if (d && d.includes(a))
|
|
192
|
+
if (a === "color") {
|
|
193
|
+
if (i.value) {
|
|
194
|
+
const c = f(i.value);
|
|
195
|
+
if (y(c))
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
177
198
|
} else
|
|
178
199
|
return;
|
|
179
|
-
|
|
200
|
+
m.push(
|
|
180
201
|
i
|
|
181
202
|
);
|
|
182
|
-
}),
|
|
183
|
-
|
|
184
|
-
node:
|
|
203
|
+
}), m.forEach((n) => {
|
|
204
|
+
t.report({
|
|
205
|
+
node: n,
|
|
185
206
|
messageId: "systemProp",
|
|
186
207
|
data: {
|
|
187
|
-
prop:
|
|
208
|
+
prop: n.name.name,
|
|
188
209
|
component: e
|
|
189
210
|
}
|
|
190
211
|
});
|
|
@@ -193,9 +214,9 @@ const g = [
|
|
|
193
214
|
};
|
|
194
215
|
}
|
|
195
216
|
};
|
|
196
|
-
function f(
|
|
197
|
-
if (!
|
|
198
|
-
const o =
|
|
217
|
+
function f(t) {
|
|
218
|
+
if (!t) return null;
|
|
219
|
+
const o = t;
|
|
199
220
|
if (o.type === "Literal")
|
|
200
221
|
return String(o.value);
|
|
201
222
|
if (o.type === "JSXExpressionContainer" && o.expression) {
|
|
@@ -206,7 +227,7 @@ function f(n) {
|
|
|
206
227
|
}
|
|
207
228
|
return null;
|
|
208
229
|
}
|
|
209
|
-
function y(
|
|
230
|
+
function y(t) {
|
|
210
231
|
return [
|
|
211
232
|
"inherit",
|
|
212
233
|
"primary",
|
|
@@ -214,8 +235,16 @@ function y(n) {
|
|
|
214
235
|
"error",
|
|
215
236
|
"warning",
|
|
216
237
|
"info",
|
|
217
|
-
"success"
|
|
218
|
-
|
|
238
|
+
"success",
|
|
239
|
+
"default",
|
|
240
|
+
// Badge, Radio, Checkbox, Switch
|
|
241
|
+
"action",
|
|
242
|
+
// SvgIcon
|
|
243
|
+
"disabled",
|
|
244
|
+
// SvgIcon
|
|
245
|
+
"standard"
|
|
246
|
+
// ToggleButton, ToggleButtonGroup
|
|
247
|
+
].includes(t || "");
|
|
219
248
|
}
|
|
220
249
|
export {
|
|
221
250
|
h as default
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createSxVisitor as d } from "./sx-utils.js";
|
|
2
|
+
const l = {
|
|
3
|
+
// Positioning (inset)
|
|
4
|
+
top: "insetBlockStart",
|
|
5
|
+
bottom: "insetBlockEnd",
|
|
6
|
+
left: "insetInlineStart",
|
|
7
|
+
right: "insetInlineEnd",
|
|
8
|
+
// Padding
|
|
9
|
+
paddingTop: "paddingBlockStart",
|
|
10
|
+
paddingBottom: "paddingBlockEnd",
|
|
11
|
+
paddingLeft: "paddingInlineStart",
|
|
12
|
+
paddingRight: "paddingInlineEnd",
|
|
13
|
+
paddingX: "paddingInline",
|
|
14
|
+
paddingY: "paddingBlock",
|
|
15
|
+
// Margin
|
|
16
|
+
marginTop: "marginBlockStart",
|
|
17
|
+
marginBottom: "marginBlockEnd",
|
|
18
|
+
marginLeft: "marginInlineStart",
|
|
19
|
+
marginRight: "marginInlineEnd",
|
|
20
|
+
marginX: "marginInline",
|
|
21
|
+
marginY: "marginBlock",
|
|
22
|
+
// Border
|
|
23
|
+
borderTop: "borderBlockStart",
|
|
24
|
+
borderBottom: "borderBlockEnd",
|
|
25
|
+
borderLeft: "borderInlineStart",
|
|
26
|
+
borderRight: "borderInlineEnd",
|
|
27
|
+
// Border color
|
|
28
|
+
borderTopColor: "borderBlockStartColor",
|
|
29
|
+
borderBottomColor: "borderBlockEndColor",
|
|
30
|
+
borderLeftColor: "borderInlineStartColor",
|
|
31
|
+
borderRightColor: "borderInlineEndColor"
|
|
32
|
+
}, g = {
|
|
33
|
+
meta: {
|
|
34
|
+
type: "suggestion",
|
|
35
|
+
fixable: "code",
|
|
36
|
+
docs: {
|
|
37
|
+
description: "Enforce CSS logical properties instead of physical direction properties in sx props",
|
|
38
|
+
category: "Best Practices",
|
|
39
|
+
recommended: !0
|
|
40
|
+
},
|
|
41
|
+
messages: {
|
|
42
|
+
physicalProperty: 'Use logical property "{{replacement}}" instead of "{{property}}" in sx for RTL support.'
|
|
43
|
+
},
|
|
44
|
+
schema: []
|
|
45
|
+
},
|
|
46
|
+
create(t) {
|
|
47
|
+
return d({
|
|
48
|
+
onProperty(n, o) {
|
|
49
|
+
const r = l[n];
|
|
50
|
+
r && t.report({
|
|
51
|
+
node: o,
|
|
52
|
+
messageId: "physicalProperty",
|
|
53
|
+
data: { property: n, replacement: r },
|
|
54
|
+
fix(i) {
|
|
55
|
+
const e = o;
|
|
56
|
+
if (o.type === "Literal") {
|
|
57
|
+
const a = t.sourceCode.getText(e)[0];
|
|
58
|
+
return i.replaceText(
|
|
59
|
+
e,
|
|
60
|
+
`${a}${r}${a}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return i.replaceText(e, r);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
export {
|
|
71
|
+
g as default
|
|
72
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createSxVisitor as l } from "./sx-utils.js";
|
|
2
|
+
const f = /* @__PURE__ */ new Set([
|
|
3
|
+
"color",
|
|
4
|
+
"backgroundColor",
|
|
5
|
+
"bgcolor",
|
|
6
|
+
"background",
|
|
7
|
+
"borderColor",
|
|
8
|
+
"borderTopColor",
|
|
9
|
+
"borderRightColor",
|
|
10
|
+
"borderBottomColor",
|
|
11
|
+
"borderLeftColor",
|
|
12
|
+
"outlineColor",
|
|
13
|
+
"fill",
|
|
14
|
+
"stroke",
|
|
15
|
+
"caretColor",
|
|
16
|
+
"textDecorationColor",
|
|
17
|
+
"columnRuleColor"
|
|
18
|
+
]), p = /* @__PURE__ */ new Set([
|
|
19
|
+
"inherit",
|
|
20
|
+
"transparent",
|
|
21
|
+
"currentColor",
|
|
22
|
+
"currentcolor",
|
|
23
|
+
"initial",
|
|
24
|
+
"unset",
|
|
25
|
+
"none"
|
|
26
|
+
]), d = {
|
|
27
|
+
meta: {
|
|
28
|
+
type: "suggestion",
|
|
29
|
+
docs: {
|
|
30
|
+
description: "Enforce using vars.palette for color properties in sx props instead of string literals or theme.palette",
|
|
31
|
+
category: "Best Practices",
|
|
32
|
+
recommended: !0
|
|
33
|
+
},
|
|
34
|
+
messages: {
|
|
35
|
+
stringColor: 'Avoid string literal "{{value}}" for "{{property}}" in sx. Use vars.palette for type-safe, dark mode-friendly colors.',
|
|
36
|
+
useVarsPalette: "Use vars.palette instead of {{access}} for CSS variable-based dark mode support."
|
|
37
|
+
},
|
|
38
|
+
schema: []
|
|
39
|
+
},
|
|
40
|
+
create(s) {
|
|
41
|
+
return l({
|
|
42
|
+
onProperty(t, r, e) {
|
|
43
|
+
f.has(t) && i(s, t, e);
|
|
44
|
+
},
|
|
45
|
+
onCallback(t) {
|
|
46
|
+
c(s, t);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
function i(s, t, r) {
|
|
52
|
+
if (r.type === "ObjectExpression") {
|
|
53
|
+
const e = r.properties;
|
|
54
|
+
for (const o of e) {
|
|
55
|
+
if (o.type === "SpreadElement" || o.type !== "Property") continue;
|
|
56
|
+
i(s, t, o.value);
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (r.type === "ArrowFunctionExpression" || r.type === "FunctionExpression") {
|
|
61
|
+
c(s, r);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (r.type === "Literal") {
|
|
65
|
+
const e = r.value;
|
|
66
|
+
typeof e == "string" && !p.has(e) && s.report({
|
|
67
|
+
node: r,
|
|
68
|
+
messageId: "stringColor",
|
|
69
|
+
data: { value: e, property: t }
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (r.type === "TemplateLiteral") {
|
|
74
|
+
const e = r;
|
|
75
|
+
if (e.expressions.length === 0) {
|
|
76
|
+
const o = e.quasis[0]?.value.raw;
|
|
77
|
+
o && !p.has(o) && s.report({
|
|
78
|
+
node: r,
|
|
79
|
+
messageId: "stringColor",
|
|
80
|
+
data: { value: o, property: t }
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (r.type === "ConditionalExpression") {
|
|
86
|
+
const e = r;
|
|
87
|
+
i(s, t, e.consequent), i(s, t, e.alternate);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function c(s, t) {
|
|
91
|
+
const r = t.params;
|
|
92
|
+
if (!r || r.length === 0) return;
|
|
93
|
+
const e = r[0];
|
|
94
|
+
if (e.type === "Identifier") {
|
|
95
|
+
const o = e.name, n = t.body;
|
|
96
|
+
a(s, n, o);
|
|
97
|
+
} else e.type === "ObjectPattern" && e.properties.forEach((n) => {
|
|
98
|
+
if (n.type !== "Property") return;
|
|
99
|
+
n.key.name === "palette" && s.report({
|
|
100
|
+
node: n,
|
|
101
|
+
messageId: "useVarsPalette",
|
|
102
|
+
data: { access: "destructured palette" }
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function a(s, t, r) {
|
|
107
|
+
if (!(!t || typeof t != "object")) {
|
|
108
|
+
if (t.type === "MemberExpression") {
|
|
109
|
+
const e = t.object, o = t.property;
|
|
110
|
+
if (e.type === "Identifier" && e.name === r && o.name === "palette") {
|
|
111
|
+
s.report({
|
|
112
|
+
node: t,
|
|
113
|
+
messageId: "useVarsPalette",
|
|
114
|
+
data: { access: `${r}.palette` }
|
|
115
|
+
});
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const e of Object.keys(t)) {
|
|
120
|
+
if (e === "parent") continue;
|
|
121
|
+
const o = t[e];
|
|
122
|
+
o && typeof o == "object" && (Array.isArray(o) ? o.forEach((n) => {
|
|
123
|
+
n && typeof n == "object" && "type" in n && a(s, n, r);
|
|
124
|
+
}) : "type" in o && a(s, o, r));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export {
|
|
129
|
+
d as default
|
|
130
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Rule } from 'eslint';
|
|
2
|
+
/**
|
|
3
|
+
* Shared AST traversal utilities for ESLint rules that inspect MUI `sx` props.
|
|
4
|
+
*
|
|
5
|
+
* Provides a visitor pattern that:
|
|
6
|
+
* 1. Finds the `sx` attribute on JSXOpeningElement nodes
|
|
7
|
+
* 2. Traverses the expression (object, callback, or array)
|
|
8
|
+
* 3. Recurses into nested objects (pseudo-selectors like "&:hover")
|
|
9
|
+
* 4. Calls rule-specific callbacks for each property encountered
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Minimal AST node type for traversal within ESLint rules.
|
|
13
|
+
*/
|
|
14
|
+
export type ASTNode = Record<string, unknown> & {
|
|
15
|
+
type: string;
|
|
16
|
+
};
|
|
17
|
+
export interface SxVisitorCallbacks {
|
|
18
|
+
/**
|
|
19
|
+
* Called for each property in an sx object expression, including properties
|
|
20
|
+
* inside nested objects (pseudo-selectors like "&:hover").
|
|
21
|
+
* Recursion into nested objects is handled automatically by the visitor.
|
|
22
|
+
*/
|
|
23
|
+
onProperty: (keyName: string, keyNode: ASTNode, valueNode: ASTNode) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Called when the sx value (or an array element) is a callback function
|
|
26
|
+
* (ArrowFunctionExpression or FunctionExpression). Fires before the
|
|
27
|
+
* returned object's properties are visited via onProperty.
|
|
28
|
+
*/
|
|
29
|
+
onCallback?: (func: ASTNode) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates a JSXOpeningElement visitor that locates the `sx` attribute
|
|
33
|
+
* and walks its value, invoking the provided callbacks for each property.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createSxVisitor(callbacks: SxVisitorCallbacks): Rule.RuleListener;
|
|
36
|
+
/**
|
|
37
|
+
* Walk an sx value expression (object, callback, or array) and invoke
|
|
38
|
+
* the provided callbacks for each property encountered.
|
|
39
|
+
*/
|
|
40
|
+
export declare function visitSxValue(node: ASTNode, callbacks: SxVisitorCallbacks): void;
|
|
41
|
+
/**
|
|
42
|
+
* Extract the returned ObjectExpression from a function/arrow function body.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getReturnedObjectExpression(func: ASTNode): ASTNode | null;
|
|
45
|
+
/**
|
|
46
|
+
* Get the string name of a property key.
|
|
47
|
+
* Returns null for computed keys or non-string keys.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getKeyName(key: {
|
|
50
|
+
type: string;
|
|
51
|
+
name?: string;
|
|
52
|
+
value?: string;
|
|
53
|
+
}, computed: boolean): string | null;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
function f(e) {
|
|
2
|
+
return {
|
|
3
|
+
JSXOpeningElement(t) {
|
|
4
|
+
const n = t.attributes.find(
|
|
5
|
+
(i) => i.type === "JSXAttribute" && i.name?.name === "sx"
|
|
6
|
+
);
|
|
7
|
+
if (!n) return;
|
|
8
|
+
const r = n.value;
|
|
9
|
+
if (r && r.type === "JSXExpressionContainer") {
|
|
10
|
+
const i = r.expression;
|
|
11
|
+
u(i, e);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function u(e, t) {
|
|
17
|
+
if (e)
|
|
18
|
+
switch (e.type) {
|
|
19
|
+
case "ObjectExpression":
|
|
20
|
+
o(e, t);
|
|
21
|
+
break;
|
|
22
|
+
case "ArrowFunctionExpression":
|
|
23
|
+
case "FunctionExpression": {
|
|
24
|
+
t.onCallback?.(e);
|
|
25
|
+
const s = p(e);
|
|
26
|
+
s && o(s, t);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case "ArrayExpression": {
|
|
30
|
+
e.elements.forEach((n) => {
|
|
31
|
+
n && u(n, t);
|
|
32
|
+
});
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function o(e, t) {
|
|
38
|
+
e.properties.forEach((n) => {
|
|
39
|
+
if (n.type !== "Property") return;
|
|
40
|
+
const r = n, i = c(r.key, r.computed);
|
|
41
|
+
i && (r.value.type === "ObjectExpression" && o(r.value, t), t.onProperty(i, r.key, r.value));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function p(e) {
|
|
45
|
+
const t = e.body;
|
|
46
|
+
if (t.type === "ObjectExpression")
|
|
47
|
+
return t;
|
|
48
|
+
if (t.type === "BlockStatement") {
|
|
49
|
+
const s = t.body;
|
|
50
|
+
for (const n of s)
|
|
51
|
+
if (n.type === "ReturnStatement") {
|
|
52
|
+
const r = n.argument;
|
|
53
|
+
if (r?.type === "ObjectExpression")
|
|
54
|
+
return r;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
function c(e, t) {
|
|
60
|
+
return e.type === "Identifier" && !t ? e.name || null : e.type === "Literal" && typeof e.value == "string" ? e.value : null;
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
f as createSxVisitor,
|
|
64
|
+
c as getKeyName,
|
|
65
|
+
p as getReturnedObjectExpression,
|
|
66
|
+
u as visitSxValue
|
|
67
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clearstory/drywall-react",
|
|
3
|
-
"version": "7.0
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"description": "a Clearstory software design system",
|
|
6
6
|
"type": "module",
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
"@mui/material": "7.3.7",
|
|
38
38
|
"@mui/system": "7.3.7",
|
|
39
39
|
"@mui/utils": "7.3.7",
|
|
40
|
-
"@mui/x-date-pickers": "8.
|
|
40
|
+
"@mui/x-date-pickers": "8.27.0",
|
|
41
41
|
"react-hot-toast": "2.6.0",
|
|
42
42
|
"react-number-format": "^5.4.4"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@chromatic-com/storybook": "^
|
|
45
|
+
"@chromatic-com/storybook": "^5.0.1",
|
|
46
46
|
"@eslint/js": "^9.29.0",
|
|
47
47
|
"@storybook/addon-a11y": "^10.0.5",
|
|
48
48
|
"@storybook/addon-docs": "^10.0.5",
|