@solidjs/babel-plugin 2.0.0-rc.16 → 2.0.0-rc.17
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +13 -0
- package/index.js +74 -11
- package/package.json +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -7,4 +7,4 @@ src/shared/transform.ts -> src/dom/element.ts -> src/universal/element.ts -> src
|
|
|
7
7
|
src/shared/transform.ts -> src/ssr/element.ts -> src/shared/transform.ts
|
|
8
8
|
src/shared/transform.ts -> src/shared/component.ts -> src/shared/transform.ts
|
|
9
9
|
src/shared/transform.ts -> src/shared/fragment.ts -> src/shared/transform.ts
|
|
10
|
-
[32mcreated [1mindex.js[22m in [
|
|
10
|
+
[32mcreated [1mindex.js[22m in [1m2.3s[22m[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @solidjs/babel-plugin
|
|
2
2
|
|
|
3
|
+
## 2.0.0-rc.17
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3e72783: The removed Solid 1.x attribute forms are now compile errors on native elements in the `dom` and `ssr` generates (#4187). `on:`, `oncapture:`, `attr:`, `bool:`, `use:` and `classList` used to compile silently into literal attributes (`<div use:tip="() => {}">`, `classlist="[object Object]"`). Both compilers now reject them with the same message, which names the 2.0 replacement: a camelCase handler or a `ref` callback for `on:`, a plain attribute for `attr:`, a boolean value for `bool:`, a `ref` directive factory for `use:`, and an object or array `class` for `classList`. Components, the universal generate, `prop:` and the XML namespaces (`xlink:`, `xml:`, `xmlns:`) are unaffected. The check runs only at compile time and adds no runtime code.
|
|
8
|
+
- 6cca8b5: Dev builds now warn with `UNCOMMITTED_INPUT_OVERWRITTEN` (#4186) when a stateful DOM property binding (`value`/`checked` on an input, `value` on a textarea, `value`/`selected` on an option, `muted` on media) is about to re-write the value it wrote last time over an edit the user never committed to the bound signal — e.g. `value={props.name} onChange={commit}` with no draft signal, when another dynamic attribute in the same template changes. Runtime behavior is unchanged: the write still happens, once per element and property the warning names the fix (write the signal from `onInput`, use `defaultValue`/`defaultChecked` for an uncontrolled element, or write a rejected edit back with `e.currentTarget.value = next`).
|
|
9
|
+
|
|
10
|
+
Production output is unchanged byte for byte. In dev DOM output both compilers write stateful properties through a new `setStatefulProperty(el, name, value)` helper instead of the inline `el.name = value`; hydratable output keeps `setProperty`, and `spread`/`assign` check in the runtime. The check lives only in `@solidjs/web`'s dev build; the production entry carries a plain `node[name] = value` stub that no production-compiled module imports, so it tree-shakes away.
|
|
11
|
+
|
|
12
|
+
The "Form inputs" section of the DOM RFC, the cheatsheet and the solid-2.0 skill now say that a change to any other dynamic attribute in the same template re-runs a stateful binding, link the new code, and drop `equals: false` as a way to reject input (it is what the warning reports); write the accepted value back with `e.currentTarget.value = next` instead.
|
|
13
|
+
|
|
14
|
+
- 2ba1c4a: A valueless `prop:` attribute (`<el prop:active />`) now compiles as `prop:active={true}`, matching bare plain attributes, instead of being dropped silently (#4180).
|
|
15
|
+
|
|
3
16
|
## 2.0.0-rc.16
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/index.js
CHANGED
|
@@ -2321,11 +2321,6 @@ value,
|
|
|
2321
2321
|
);
|
|
2322
2322
|
}
|
|
2323
2323
|
|
|
2324
|
-
const assignment = t$1.assignmentExpression(
|
|
2325
|
-
"=",
|
|
2326
|
-
t$1.memberExpression(elem, t$1.identifier(name)),
|
|
2327
|
-
value
|
|
2328
|
-
);
|
|
2329
2324
|
if (
|
|
2330
2325
|
(name === "value" || name === "defaultValue") && (
|
|
2331
2326
|
tagName === "input" || tagName === "textarea") &&
|
|
@@ -2334,13 +2329,20 @@ value,
|
|
|
2334
2329
|
{
|
|
2335
2330
|
// prevents undefined on text input/textarea.value/defaultValue, fallback
|
|
2336
2331
|
// to empty string (#2957)
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2332
|
+
value = t$1.logicalExpression("??", value, t$1.stringLiteral(""));
|
|
2333
|
+
}
|
|
2334
|
+
// Dev DOM output writes stateful properties (value/checked/selected/
|
|
2335
|
+
// muted) through `setStatefulProperty` — the same `elem[name] = value`,
|
|
2336
|
+
// preceded in the dev runtime by the UNCOMMITTED_INPUT_OVERWRITTEN check
|
|
2337
|
+
// (#4186). Production output keeps the inline assignment, byte for byte.
|
|
2338
|
+
if (config.dev && config.generate === "dom" && isStatefulDOMProperty(tagName, name)) {
|
|
2339
|
+
return t$1.callExpression(registerImportMethod(path, "setStatefulProperty"), [
|
|
2340
|
+
elem,
|
|
2341
|
+
t$1.stringLiteral(name),
|
|
2342
|
+
value]
|
|
2341
2343
|
);
|
|
2342
2344
|
}
|
|
2343
|
-
return
|
|
2345
|
+
return t$1.assignmentExpression("=", t$1.memberExpression(elem, t$1.identifier(name)), value);
|
|
2344
2346
|
}
|
|
2345
2347
|
|
|
2346
2348
|
const ns = name.indexOf(":") > -1 && Namespaces[name.split(":")[0]];
|
|
@@ -2877,7 +2879,9 @@ results)
|
|
|
2877
2879
|
reservedNameSpace &&
|
|
2878
2880
|
!t$1.isJSXExpressionContainer(value))
|
|
2879
2881
|
{
|
|
2880
|
-
|
|
2882
|
+
// A valueless `prop:x` means `prop:x={true}`, like a bare plain
|
|
2883
|
+
// attribute (#4180).
|
|
2884
|
+
node.value = value = t$1.jsxExpressionContainer(value || t$1.booleanLiteral(true));
|
|
2881
2885
|
}
|
|
2882
2886
|
if (
|
|
2883
2887
|
t$1.isJSXExpressionContainer(value) && (
|
|
@@ -6586,6 +6590,63 @@ config)
|
|
|
6586
6590
|
results.exprs.push(childNodes.length === 1 ? childNodes[0] : t__namespace.arrayExpression(childNodes));
|
|
6587
6591
|
}
|
|
6588
6592
|
|
|
6593
|
+
/**
|
|
6594
|
+
* Solid 1.x attribute forms that 2.0 removed (#4187). Left alone they
|
|
6595
|
+
* compile into literal attributes (`<div use:tip="() => {}">`,
|
|
6596
|
+
* `classlist="[object Object]"`) with no diagnostic, so on native elements
|
|
6597
|
+
* of the web generates (`dom` / `ssr`) they are a compile error that names
|
|
6598
|
+
* the 2.0 replacement. Components are untouched (their props are
|
|
6599
|
+
* user-defined names with no compiler semantics), as is the universal
|
|
6600
|
+
* generate (a custom renderer's `setProp` owns its own naming), and every
|
|
6601
|
+
* other namespace — `prop:`, `xlink:`, `xml:`, `xmlns:`, `svg:`, … — still
|
|
6602
|
+
* compiles as before. The message text is mirrored in the native compiler
|
|
6603
|
+
* (`packages/compiler/src/shared/removed.rs`); keep the two in sync.
|
|
6604
|
+
*/
|
|
6605
|
+
function removedAttributeMessage(tagName, key) {
|
|
6606
|
+
if (key === "classList") {
|
|
6607
|
+
return (
|
|
6608
|
+
`\`classList\` on <${tagName}> was removed in Solid 2.0. ` +
|
|
6609
|
+
"Use `class` with an object or array instead: `class={{ active: isActive() }}` " +
|
|
6610
|
+
'or `class={["base", { active: isActive() }]}`.');
|
|
6611
|
+
|
|
6612
|
+
}
|
|
6613
|
+
const colon = key.indexOf(":");
|
|
6614
|
+
if (colon < 0) return;
|
|
6615
|
+
const namespace = key.slice(0, colon);
|
|
6616
|
+
const name = key.slice(colon + 1);
|
|
6617
|
+
const removed = `\`${key}\` on <${tagName}> uses the \`${namespace}:\` namespace, which was removed in Solid 2.0.`;
|
|
6618
|
+
switch (namespace) {
|
|
6619
|
+
case "on":
|
|
6620
|
+
case "oncapture":
|
|
6621
|
+
return (
|
|
6622
|
+
`${removed} Use a camelCase handler such as \`onClick={handler}\` for Solid events, ` +
|
|
6623
|
+
"or a `ref` callback that calls `addEventListener` for listener options or custom event names.");
|
|
6624
|
+
|
|
6625
|
+
case "attr":
|
|
6626
|
+
return `${removed} Attributes are the default in 2.0: write \`${name}={value}\` (or \`prop:${name}\` to set a DOM property).`;
|
|
6627
|
+
case "bool":
|
|
6628
|
+
return `${removed} Boolean values add or remove the attribute in 2.0: write \`${name}={condition}\`.`;
|
|
6629
|
+
case "use":
|
|
6630
|
+
return (
|
|
6631
|
+
`${removed} Use a \`ref\` directive factory instead: \`ref={${name}(options)}\`, ` +
|
|
6632
|
+
`or \`ref={${name}}\` without options; arrays compose (\`ref={[a, b]}\`).`);
|
|
6633
|
+
|
|
6634
|
+
}
|
|
6635
|
+
}
|
|
6636
|
+
|
|
6637
|
+
/** Throws a code-frame error at the first removed 1.x attribute form. */
|
|
6638
|
+
function assertNoRemovedAttributes(path, tagName) {
|
|
6639
|
+
for (const attribute of path.get("openingElement").get("attributes")) {
|
|
6640
|
+
if (!attribute.isJSXAttribute()) continue;
|
|
6641
|
+
const name = attribute.node.name;
|
|
6642
|
+
const key = t__namespace.isJSXNamespacedName(name) ?
|
|
6643
|
+
`${name.namespace.name}:${name.name.name}` :
|
|
6644
|
+
name.name;
|
|
6645
|
+
const message = removedAttributeMessage(tagName, key);
|
|
6646
|
+
if (message) throw attribute.buildCodeFrameError(message);
|
|
6647
|
+
}
|
|
6648
|
+
}
|
|
6649
|
+
|
|
6589
6650
|
function isTransformConditionStatements(
|
|
6590
6651
|
expr)
|
|
6591
6652
|
{
|
|
@@ -6866,11 +6927,13 @@ info = {})
|
|
|
6866
6927
|
);
|
|
6867
6928
|
|
|
6868
6929
|
if (tagRenderer?.name === "dom" || getConfig(path).generate === "dom") {
|
|
6930
|
+
assertNoRemovedAttributes(path, tagName);
|
|
6869
6931
|
renameElementKey(path, false);
|
|
6870
6932
|
return transformElement$2(path, info);
|
|
6871
6933
|
}
|
|
6872
6934
|
|
|
6873
6935
|
if (getConfig(path).generate === "ssr") {
|
|
6936
|
+
assertNoRemovedAttributes(path, tagName);
|
|
6874
6937
|
renameElementKey(path, true);
|
|
6875
6938
|
return transformElement$1(path, info);
|
|
6876
6939
|
}
|