Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .changeset/jsx-tokenizer-solid2-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
"@solid-primitives/jsx-tokenizer": major
---

Migrate to Solid.js v2.0 (beta.10)

## Breaking Changes

**Peer dependencies**: `solid-js@^2.0.0-beta.10` and `@solidjs/web@^2.0.0-beta.10` are now required.

### API changes

- `isServer` is now imported from `@solidjs/web` (not `solid-js/web`)
- `JSX` types are now imported from `@solidjs/web`
- `ResolvedJSXElement` type renamed to `ResolvedElement` (from `solid-js`) in `resolveTokens` overloads
- `renderToString` in SSR tests moved to `@solidjs/web`

### Usage changes

- `createEffect` now requires the split compute/apply form — update any `createEffect` calls in consuming code
- Context is now its own provider: `<MyContext value={...}>` replaces `<MyContext.Provider value={...}>`
- `classList` is replaced by the `class` object/array form

### Vitest config

- Added `moduleName: "@solidjs/web"` to the shared vitest config `solid` option so JSX transforms target `@solidjs/web` instead of the removed `solid-js/web` subpath. This affects all packages with `.tsx` test files.
2 changes: 1 addition & 1 deletion configs/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default defineConfig(({ mode }) => {
// https://github.com/solidjs/solid-refresh/issues/29
hot: false,
// For testing SSR we need to do a SSR JSX transform
solid: { generate: testSSR ? "ssr" : "dom", omitNestedClosingTags: false },
solid: { generate: testSSR ? "ssr" : "dom", omitNestedClosingTags: false, moduleName: "@solidjs/web" },
}),
],
test: {
Expand Down
50 changes: 27 additions & 23 deletions packages/jsx-tokenizer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function Tabs<T>(props: { children: (Tab: Component<{ value: T }>) => JSX.Elemen
return (
<ul>
<For each={tokens()}>
{token => <li classList={{ active: token.data === props.active }}>{token.data}</li>}
{token => <li class={{ active: token.data === props.active }}>{token.data}</li>}
</For>
</ul>
);
Expand Down Expand Up @@ -163,13 +163,14 @@ import { resolveTokens } from "@solid-primitives/jsx-tokenizer";

const tokens = resolveTokens(tokenizer, () => props.children);

createEffect(() => {
tokens().forEach(token => {
createEffect(
() => tokens(),
tokens => {
// token is a function that returns the JSX Element fallback
// token.data is the data returned by the tokenData function
console.log(token.data);
});
});
tokens.forEach(token => console.log(token.data));
}
);

// the return value of resolveTokens can be used in JSX (will render the fallback JSX Elements)
return <>{els()}</>;
Expand All @@ -188,17 +189,20 @@ const els = resolveTokens(tokenizer, () => props.children, {
includeJSXElements: true,
});

createEffect(() => {
els().forEach(el => {
if (!isToken(tokenizer, el)) {
// el is a normal JSX Element
return;
}
// token is a function that returns the JSX Element fallback
// token.data is the data returned by the tokenData function
console.log(token.data);
});
});
createEffect(
() => els(),
els => {
els.forEach(el => {
if (!isToken(tokenizer, el)) {
// el is a normal JSX Element
return;
}
// token is a function that returns the JSX Element fallback
// token.data is the data returned by the tokenData function
console.log(el.data);
});
}
);

// the return value of resolveTokens can be used in JSX
return <>{els()}</>;
Expand All @@ -221,15 +225,15 @@ Since `resolveTokens` is eagerly resolving the JSX structure, if you want to pro
```tsx
function ParentComponent(props) {
return (
<MyContext.Provider value={{} /* some value */}>
<MyContext value={{} /* some value */}>
{untrack(() => {
const tokens = resolveTokens(tokenizer, () => props.children);

// handle tokens ...

return <>{tokens()}</>;
})}
</MyContext.Provider>
</MyContext>
);
}
```
Expand All @@ -243,13 +247,13 @@ For example, [`@solidjs/router`](https://github.com/solidjs/solid-router) which
function App() {
return (
<Routes>
<MyContext.Provider value={{} /* some value */}>
<MyContext value={{} /* some value */}>
{/*
<Route> component prop is not rendered immediately, it is rendered within <Routes>
as later time, so the context will not be available in Home component
*/}
<Route path="/" component={Home} />
</MyContext.Provider>
</MyContext>
</Routes>
);
}
Expand All @@ -262,11 +266,11 @@ function Home() {
// do this instead
function App() {
return (
<MyContext.Provider value={{} /* some value */}>
<MyContext value={{} /* some value */}>
<Routes>
<Route path="/" component={Home} />
</Routes>
</MyContext.Provider>
</MyContext>
);
}
```
Expand Down
8 changes: 5 additions & 3 deletions packages/jsx-tokenizer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@solid-primitives/jsx-tokenizer",
"version": "1.1.3",
"version": "2.0.0",
"description": "A primitive to tokenize your solid-components to enable custom parsing.",
"author": "Vincent Van Dijck <vandijckv@gmail.com>",
"contributors": [
Expand Down Expand Up @@ -59,9 +59,11 @@
"@solid-primitives/utils": "workspace:^"
},
"peerDependencies": {
"solid-js": "^1.6.12"
"@solidjs/web": "^2.0.0-beta.10",
"solid-js": "^2.0.0-beta.10"
},
"devDependencies": {
"solid-js": "^1.9.7"
"@solidjs/web": "2.0.0-beta.10",
"solid-js": "2.0.0-beta.10"
}
}
11 changes: 5 additions & 6 deletions packages/jsx-tokenizer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import {
type Component,
createComponent,
createMemo,
type JSX,
DEV,
type ResolvedJSXElement,
type ResolvedElement,
} from "solid-js";
import { isServer } from "solid-js/web";
import { isServer, type JSX } from "@solidjs/web";
import type { NoInfer, Many } from "@solid-primitives/utils";
import { asArray } from "@solid-primitives/utils";

Expand Down Expand Up @@ -178,7 +177,7 @@ export function resolveTokens<TData>(
options: {
includeJSXElements: true;
},
): Accessor<(TokenElement<TData> | ResolvedJSXElement)[]>;
): Accessor<(TokenElement<TData> | ResolvedElement)[]>;

export function resolveTokens<TTokenizers extends readonly JSXTokenizer<any>[]>(
tokenizers: TTokenizers,
Expand All @@ -194,15 +193,15 @@ export function resolveTokens<TTokenizers extends readonly JSXTokenizer<any>[]>(
options: {
includeJSXElements: true;
},
): Accessor<(TokenElement<JSXTokenizerData<TTokenizers[number]>> | ResolvedJSXElement)[]>;
): Accessor<(TokenElement<JSXTokenizerData<TTokenizers[number]>> | ResolvedElement)[]>;

export function resolveTokens<T>(
tokenizers: Many<JSXTokenizer<T>>,
fn: Accessor<JSX.Element>,
options?: {
includeJSXElements?: boolean;
},
): Accessor<(TokenElement<T> | ResolvedJSXElement)[]> {
): Accessor<(TokenElement<T> | ResolvedElement)[]> {
const symbols = new Set(asArray(tokenizers).map(p => p[$TOKENIZER]));
const children = createMemo(fn);
return createMemo(() => getResolvedTokens([], children(), symbols, options?.includeJSXElements));
Expand Down
21 changes: 12 additions & 9 deletions packages/jsx-tokenizer/test/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { children, createRoot, createSignal, Show } from "solid-js";
import { children, createRoot, createSignal, flush, Show } from "solid-js";
import { describe, expect, it } from "vitest";
import {
createTokenizer,
Expand Down Expand Up @@ -70,24 +70,27 @@ describe("jsx-tokenizer", () => {
});

it("handled reactive children", () => {
createRoot(() => {
const [show, setShow] = createSignal(true);
const [show, setShow] = createSignal(true);

const tokens = resolveTokens(parser1, () => (
const { tokens, dispose } = createRoot(dispose => ({
tokens: resolveTokens(parser1, () => (
<>
<Show when={show()}>
<MyToken1 text="foo" />
</Show>
<MyToken1 text="bar" />
</>
));
)),
dispose,
}));

expect(tokens()).toHaveLength(2);
expect(tokens()).toHaveLength(2);

setShow(false);
setShow(false);
flush();
expect(tokens()).toHaveLength(1);

expect(tokens()).toHaveLength(1);
});
dispose();
});

it("should render tokens", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/jsx-tokenizer/test/server.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { renderToString } from "solid-js/web";
import { renderToString } from "@solidjs/web";
import { describe, expect, it } from "vitest";
import { createTokenizer, createToken, resolveTokens } from "../src/index.js";

Expand Down
Loading