Skip to content

Commit ff6fa8d

Browse files
authored
feat(tasty): extend syntax (#1039)
1 parent 23ae67b commit ff6fa8d

8 files changed

Lines changed: 1339 additions & 13 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"module": "./dist/index.js",
1111
"types": "./dist/index.d.ts",
1212
"sideEffects": false,
13-
"packageManager": "pnpm@10.19.0",
13+
"packageManager": "pnpm@10.30.0",
1414
"exports": {
1515
".": {
1616
"import": "./dist/index.js",

src/stories/Tasty.docs.mdx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,77 @@ const PrimaryButton = tasty(Button, {
5050
<Button styles={{ fill: '#purple' }}>Click me</Button>
5151
```
5252

53+
#### Extending vs. Replacing State Maps
54+
55+
When a style property uses a state map, the merge behavior depends on whether the child provides a `''` (default) key:
56+
57+
- **No `''` key** — extend mode: parent states are preserved, child adds/overrides
58+
- **Has `''` key** — replace mode: child defines everything from scratch
59+
60+
```jsx live=false
61+
// Parent has: fill: { '': '#white', hovered: '#blue', disabled: '#gray' }
62+
63+
// ✅ Extend — no '' key, parent states preserved
64+
const MyButton = tasty(Button, {
65+
styles: {
66+
fill: {
67+
'loading': '#yellow', // append new state
68+
'disabled': '#gray.20', // override existing state in place
69+
},
70+
},
71+
});
72+
73+
// Replace — has '' key, parent states dropped
74+
const MyButton = tasty(Button, {
75+
styles: {
76+
fill: {
77+
'': '#red',
78+
'hovered': '#blue',
79+
},
80+
},
81+
});
82+
```
83+
84+
Use `'@inherit'` to pull a parent state value. In extend mode it repositions the state; in replace mode it cherry-picks it:
85+
86+
```jsx live=false
87+
// Extend mode: reposition disabled to end (highest CSS priority)
88+
fill: {
89+
'loading': '#yellow',
90+
disabled: '@inherit',
91+
}
92+
93+
// Replace mode: cherry-pick disabled from parent
94+
fill: {
95+
'': '#red',
96+
disabled: '@inherit',
97+
}
98+
```
99+
100+
Use `null` inside a state map to remove a state, or `false` to block it entirely (tombstone):
101+
102+
```jsx live=false
103+
fill: { pressed: null } // removes pressed from the result
104+
fill: { disabled: false } // tombstone — no CSS for disabled, blocks recipe too
105+
```
106+
107+
#### Resetting Properties with `null` and `false`
108+
109+
```jsx live=false
110+
const SimpleButton = tasty(Button, {
111+
styles: {
112+
fill: null, // discard parent's fill, let recipe fill in
113+
border: false, // no border at all (tombstone — blocks recipe too)
114+
},
115+
});
116+
```
117+
118+
| Value | Meaning | Recipe fills in? |
119+
|-------|---------|-----------------|
120+
| `undefined` | Not provided — parent preserved | N/A |
121+
| `null` | Intentional unset — parent discarded | Yes |
122+
| `false` | Tombstone — blocks everything | No |
123+
53124
### Essential Patterns
54125

55126
```jsx

0 commit comments

Comments
 (0)