Skip to content

Commit b14788f

Browse files
committed
docs: add info on conditional parts
1 parent ae42623 commit b14788f

1 file changed

Lines changed: 99 additions & 0 deletions

File tree

docs/guide/component-parts.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,105 @@ part="wrapper" // Too generic
245245
part="theBlueBox" // Describes appearance
246246
```
247247

248+
## Multiple and Conditional Parts
249+
250+
An element can expose multiple parts, and parts can be conditionally applied based on component state.
251+
252+
### Multiple Parts (Space-Separated)
253+
254+
Use space-separated names to expose multiple parts on one element:
255+
256+
```jsx
257+
function ListItem({ children }) {
258+
return (
259+
<div part="item row" styleName="item">
260+
{children}
261+
</div>
262+
)
263+
}
264+
```
265+
266+
Parents can style either part:
267+
268+
```jsx
269+
styl`
270+
.my-list:part(item)
271+
padding 12px
272+
.my-list:part(row)
273+
flex-direction row
274+
`
275+
```
276+
277+
### Conditional Parts (Array Syntax)
278+
279+
Use an array with an object to conditionally apply parts based on props or state:
280+
281+
```jsx
282+
function ListItem({ layout, selected, children }) {
283+
return (
284+
<div
285+
part={['item', { row: layout === 'row', column: layout === 'column', selected }]}
286+
styleName="item"
287+
>
288+
{children}
289+
</div>
290+
)
291+
}
292+
```
293+
294+
- `'item'` — always exposed as a part
295+
- `row: layout === 'row'` — exposed only when `layout` is `'row'`
296+
- `column: layout === 'column'` — exposed only when `layout` is `'column'`
297+
- `selected` — exposed when the `selected` prop is truthy (shorthand for `selected: selected`)
298+
299+
Parents can then style each conditional part:
300+
301+
```jsx
302+
styl`
303+
.my-list:part(item)
304+
padding 12px
305+
306+
.my-list:part(row)
307+
flex-direction row
308+
309+
.my-list:part(column)
310+
flex-direction column
311+
312+
.my-list:part(selected)
313+
background #e3f2fd
314+
`
315+
```
316+
317+
### Object-Only Syntax
318+
319+
You can also use just an object for all conditional parts:
320+
321+
```jsx
322+
<div part={{ content: true, active, disabled: isDisabled }} />
323+
```
324+
325+
### Limitations
326+
327+
Part names must be **statically known at compile time**. The Babel transform needs to generate the corresponding `*Style` props, so it must know all possible part names.
328+
329+
**Allowed:**
330+
```jsx
331+
part="root icon" // Static string
332+
part={['content', { active }]} // Array with static strings and objects
333+
part={{ content: true, active }} // Object with static keys
334+
part={['item', { selected: isSelected }]} // Boolean expressions as values
335+
```
336+
337+
**Not allowed:**
338+
```jsx
339+
part={variant} // Dynamic value — part names unknown
340+
part={['card', variant]} // Dynamic string in array
341+
part={{ [variant]: true }} // Computed/dynamic key
342+
part={{ ...partConfig }} // Spread operator
343+
```
344+
345+
If you need fully dynamic parts, pass style props directly instead of using the `part` system.
346+
248347
## Compound Selectors with Parts
249348

250349
Combine class selectors with parts for conditional styling:

0 commit comments

Comments
 (0)