Skip to content

Commit 2473116

Browse files
thetarnavgithub-actions[bot]
authored andcommitted
Format
1 parent cfe0620 commit 2473116

File tree

4 files changed

+360
-266
lines changed

4 files changed

+360
-266
lines changed

packages/match/README.md

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -48,40 +48,54 @@ const [value, setValue] = createSignal<MyUnion>({type: "foo", foo: "foo-value"})
4848
The default tag key is `"type"`, but it can be changed with the `tag` prop:
4949

5050
```tsx
51-
type MyUnion = {
52-
kind: "foo",
53-
foo: "foo-value",
54-
} | {
55-
kind: "bar",
56-
bar: "bar-value",
57-
}
58-
59-
<MatchTag on={value()} tag="kind" case={{
60-
foo: v => <>{v().foo}</>,
61-
bar: v => <>{v().bar}</>,
62-
}} />
51+
type MyUnion =
52+
| {
53+
kind: "foo";
54+
foo: "foo-value";
55+
}
56+
| {
57+
kind: "bar";
58+
bar: "bar-value";
59+
};
60+
61+
<MatchTag
62+
on={value()}
63+
tag="kind"
64+
case={{
65+
foo: v => <>{v().foo}</>,
66+
bar: v => <>{v().bar}</>,
67+
}}
68+
/>;
6369
```
6470

6571
### Partial matching
6672

6773
Use the `partial` prop to only handle some of the union members:
6874

6975
```tsx
70-
<MatchTag partial on={value()} case={{
71-
foo: v => <>{v().foo}</>,
72-
// bar case is not handled
73-
}} />
76+
<MatchTag
77+
partial
78+
on={value()}
79+
case={{
80+
foo: v => <>{v().foo}</>,
81+
// bar case is not handled
82+
}}
83+
/>
7484
```
7585

7686
### Fallback
7787

7888
Provide a fallback element when no match is found or the value is `null`/`undefined`:
7989

8090
```tsx
81-
<MatchTag on={value()} case={{
82-
foo: v => <>{v().foo}</>,
83-
bar: v => <>{v().bar}</>,
84-
}} fallback={<div>No match found</div>} />
91+
<MatchTag
92+
on={value()}
93+
case={{
94+
foo: v => <>{v().foo}</>,
95+
bar: v => <>{v().bar}</>,
96+
}}
97+
fallback={<div>No match found</div>}
98+
/>
8599
```
86100

87101
## `MatchValue`
@@ -95,32 +109,43 @@ type MyUnion = "foo" | "bar";
95109

96110
const [value, setValue] = createSignal<MyUnion>("foo");
97111

98-
<MatchValue on={value()} case={{
99-
foo: () => <p>foo</p>,
100-
bar: () => <p>bar</p>,
101-
}} />
112+
<MatchValue
113+
on={value()}
114+
case={{
115+
foo: () => <p>foo</p>,
116+
bar: () => <p>bar</p>,
117+
}}
118+
/>;
102119
```
103120

104121
### Partial matching
105122

106123
Use the `partial` prop to only handle some of the union members:
107124

108125
```tsx
109-
<MatchValue partial on={value()} case={{
110-
foo: () => <p>foo</p>,
111-
// bar case is not handled
112-
}} />
126+
<MatchValue
127+
partial
128+
on={value()}
129+
case={{
130+
foo: () => <p>foo</p>,
131+
// bar case is not handled
132+
}}
133+
/>
113134
```
114135

115136
### Fallback
116137

117138
Provide a fallback element when no match is found or the value is `null`/`undefined`:
118139

119140
```tsx
120-
<MatchValue on={value()} case={{
121-
foo: () => <p>foo</p>,
122-
bar: () => <p>bar</p>,
123-
}} fallback={<div>No match found</div>} />
141+
<MatchValue
142+
on={value()}
143+
case={{
144+
foo: () => <p>foo</p>,
145+
bar: () => <p>bar</p>,
146+
}}
147+
fallback={<div>No match found</div>}
148+
/>
124149
```
125150

126151
## Demo

packages/match/dev/index.tsx

Lines changed: 63 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,36 @@
11
import { Component, createSignal } from "solid-js";
22
import { MatchTag, MatchValue } from "../src/index.js";
33

4-
type AnimalDog = {type: 'dog', breed: string};
5-
type AnimalCat = {type: 'cat', lives: number};
6-
type AnimalBird = {type: 'bird', canFly: boolean};
4+
type AnimalDog = { type: "dog"; breed: string };
5+
type AnimalCat = { type: "cat"; lives: number };
6+
type AnimalBird = { type: "bird"; canFly: boolean };
77

88
type Animal = AnimalDog | AnimalCat | AnimalBird;
99

10-
const DogDisplay: Component<{ animal: AnimalDog }> = (props) => (
10+
const DogDisplay: Component<{ animal: AnimalDog }> = props => (
1111
<div class="text-center">
12-
<div class="text-2xl mb-2">🐕</div>
12+
<div class="mb-2 text-2xl">🐕</div>
1313
<div class="text-sm">Breed: {props.animal.breed}</div>
1414
</div>
1515
);
1616

17-
const CatDisplay: Component<{ animal: AnimalCat }> = (props) => (
17+
const CatDisplay: Component<{ animal: AnimalCat }> = props => (
1818
<div class="text-center">
19-
<div class="text-2xl mb-2">🐱</div>
19+
<div class="mb-2 text-2xl">🐱</div>
2020
<div class="text-sm">Lives: {props.animal.lives}</div>
2121
</div>
2222
);
2323

24-
const BirdDisplay: Component<{ animal: AnimalBird }> = (props) => (
24+
const BirdDisplay: Component<{ animal: AnimalBird }> = props => (
2525
<div class="text-center">
26-
<div class="text-2xl mb-2">🐦</div>
27-
<div class="text-sm">
28-
{props.animal.canFly ? 'Can fly' : 'Cannot fly'}
29-
</div>
26+
<div class="mb-2 text-2xl">🐦</div>
27+
<div class="text-sm">{props.animal.canFly ? "Can fly" : "Cannot fly"}</div>
3028
</div>
3129
);
3230

3331
const FallbackDisplay: Component = () => (
3432
<div class="text-center">
35-
<div class="text-2xl mb-2"></div>
33+
<div class="mb-2 text-2xl"></div>
3634
<div>Fallback content</div>
3735
</div>
3836
);
@@ -42,26 +40,26 @@ const App: Component = () => {
4240

4341
const animals: (Animal | null)[] = [
4442
null,
45-
{ type: 'dog', breed: 'Golden Retriever' },
46-
{ type: 'cat', lives: 9 },
47-
{ type: 'bird', canFly: true },
43+
{ type: "dog", breed: "Golden Retriever" },
44+
{ type: "cat", lives: 9 },
45+
{ type: "bird", canFly: true },
4846
];
4947

5048
return (
5149
<div class="min-h-screen p-8">
52-
<div class="max-w-4xl mx-auto space-y-8">
50+
<div class="mx-auto max-w-4xl space-y-8">
5351
<div class="text-center">
54-
<h1 class="text-3xl font-bold mb-2">Match Component Demo</h1>
52+
<h1 class="mb-2 text-3xl font-bold">Match Component Demo</h1>
5553
<p>Control-flow component for matching discriminated union members</p>
5654
</div>
5755

58-
<div class="border border-gray-500 border-2 rounded-lg p-6">
59-
<label class="block text-sm font-medium mb-2">
60-
Select an animal:
61-
</label>
62-
<select
63-
class="w-full p-2 border border-gray-500 border-2 rounded-md"
64-
onChange={e => {setAnimal(animals[parseInt(e.target.value)]!)}}
56+
<div class="rounded-lg border border-2 border-gray-500 p-6">
57+
<label class="mb-2 block text-sm font-medium">Select an animal:</label>
58+
<select
59+
class="w-full rounded-md border border-2 border-gray-500 p-2"
60+
onChange={e => {
61+
setAnimal(animals[parseInt(e.target.value)]!);
62+
}}
6563
>
6664
<option value="0">None (null)</option>
6765
<option value="1">Dog</option>
@@ -70,40 +68,53 @@ const App: Component = () => {
7068
</select>
7169
</div>
7270

73-
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
74-
<div class="border border-gray-500 border-2 rounded-lg p-6">
75-
<h2 class="text-xl font-semibold mb-1">Complete Match</h2>
76-
<p class="text-sm mb-4">Handles all union members with fallback</p>
77-
<div class="border border-gray-500 border-2 rounded p-4 min-h-[100px] flex items-center justify-center">
78-
<MatchTag on={animal()} case={{
79-
dog: v => <DogDisplay animal={v()} />,
80-
cat: v => <CatDisplay animal={v()} />,
81-
bird: v => <BirdDisplay animal={v()} />,
82-
}} fallback={<FallbackDisplay />} />
71+
<div class="grid grid-cols-1 gap-8 md:grid-cols-2">
72+
<div class="rounded-lg border border-2 border-gray-500 p-6">
73+
<h2 class="mb-1 text-xl font-semibold">Complete Match</h2>
74+
<p class="mb-4 text-sm">Handles all union members with fallback</p>
75+
<div class="flex min-h-[100px] items-center justify-center rounded border border-2 border-gray-500 p-4">
76+
<MatchTag
77+
on={animal()}
78+
case={{
79+
dog: v => <DogDisplay animal={v()} />,
80+
cat: v => <CatDisplay animal={v()} />,
81+
bird: v => <BirdDisplay animal={v()} />,
82+
}}
83+
fallback={<FallbackDisplay />}
84+
/>
8385
</div>
8486
</div>
8587

86-
<div class="border border-gray-500 border-2 rounded-lg p-6">
87-
<h2 class="text-xl font-semibold mb-1">Partial Match</h2>
88-
<p class="text-sm mb-4">Only handles dogs and cats</p>
89-
<div class="border border-gray-500 border-2 rounded p-4 min-h-[100px] flex items-center justify-center">
90-
<MatchTag partial on={animal()} case={{
91-
dog: v => <DogDisplay animal={v()} />,
92-
cat: v => <CatDisplay animal={v()} />,
93-
}} fallback={<FallbackDisplay />} />
88+
<div class="rounded-lg border border-2 border-gray-500 p-6">
89+
<h2 class="mb-1 text-xl font-semibold">Partial Match</h2>
90+
<p class="mb-4 text-sm">Only handles dogs and cats</p>
91+
<div class="flex min-h-[100px] items-center justify-center rounded border border-2 border-gray-500 p-4">
92+
<MatchTag
93+
partial
94+
on={animal()}
95+
case={{
96+
dog: v => <DogDisplay animal={v()} />,
97+
cat: v => <CatDisplay animal={v()} />,
98+
}}
99+
fallback={<FallbackDisplay />}
100+
/>
94101
</div>
95102
</div>
96103
</div>
97104

98-
<div class="mt-8 border border-gray-500 border-2 rounded-lg p-6">
99-
<h2 class="text-xl font-semibold mb-1">Value Match</h2>
100-
<p class="text-sm mb-4">Match on union literals</p>
101-
<div class="border border-gray-500 border-2 rounded p-4 min-h-[100px] flex items-center justify-center">
102-
<MatchValue on={animal()?.type} case={{
103-
dog: () => <p>🐕</p>,
104-
cat: () => <p>🐱</p>,
105-
bird: () => <p>🐦</p>,
106-
}} fallback={<FallbackDisplay />} />
105+
<div class="mt-8 rounded-lg border border-2 border-gray-500 p-6">
106+
<h2 class="mb-1 text-xl font-semibold">Value Match</h2>
107+
<p class="mb-4 text-sm">Match on union literals</p>
108+
<div class="flex min-h-[100px] items-center justify-center rounded border border-2 border-gray-500 p-4">
109+
<MatchValue
110+
on={animal()?.type}
111+
case={{
112+
dog: () => <p>🐕</p>,
113+
cat: () => <p>🐱</p>,
114+
bird: () => <p>🐦</p>,
115+
}}
116+
fallback={<FallbackDisplay />}
117+
/>
107118
</div>
108119
</div>
109120
</div>

0 commit comments

Comments
 (0)