Skip to content

Commit 09462ba

Browse files
committed
docs: fix some errors and describe the recommended pattern of writing styleName
1 parent 93d4498 commit 09462ba

9 files changed

Lines changed: 101 additions & 67 deletions

File tree

docs/api/jsx-props.md

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,21 @@ Apply class-based styles to an element. Works like `className` but with scoped,
1313
**Syntax Options:**
1414

1515
```jsx
16-
// String
16+
// String — simple static class
1717
<div styleName="card" />
1818

19-
// Object - keys with truthy values are included
20-
<div styleName={{ card: true, active, highlighted }} />
21-
22-
// Array - falsy values are filtered out
23-
<div styleName={['card', active && 'active']} />
24-
25-
// Mixed - combine arrays, strings, and objects (recommended)
26-
<div styleName={['button', variant, { active, disabled }]} />
19+
// Array with object — recommended for dynamic classes
20+
<div styleName={['card', variant, { active, disabled }]} />
2721
```
2822

29-
### Modifier Classes with Object/Array Syntax
23+
### Array Pattern (Recommended)
3024

31-
The object and array syntax is cleaner than string interpolation for conditional classes. Name your variables to match the CSS class names for the cleanest syntax:
25+
Use arrays with an object at the end for modifiers:
3226

3327
```jsx
34-
function Card({ highlighted, compact }) {
28+
function Card({ variant, highlighted, compact }) {
3529
return (
36-
// Object shorthand - cleanest when variable names match class names
37-
<div styleName={{ card: true, highlighted, compact }}>
30+
<div styleName={['card', variant, { highlighted, compact }]}>
3831
Content
3932
</div>
4033
)
@@ -44,21 +37,22 @@ function Card({ highlighted, compact }) {
4437
background white
4538
border 1px solid #ddd
4639
padding 16px
40+
.card.featured
41+
border 2px solid gold
4742
.card.highlighted
48-
border-color gold
4943
box-shadow 0 0 10px gold
5044
.card.compact
5145
padding 8px
5246
`
5347
}
5448
```
5549

56-
Compare this to the less readable string interpolation:
50+
The pattern:
51+
- Static base classes first (`'card'`)
52+
- Dynamic variant strings next (`variant` — could be `'featured'`, `'simple'`, etc.)
53+
- Boolean modifiers in an object at the end (`{ highlighted, compact }`)
5754

58-
```jsx
59-
// Avoid - harder to read with multiple modifiers
60-
<div styleName={`card ${highlighted ? 'highlighted' : ''} ${compact ? 'compact' : ''}`}>
61-
```
55+
**Tip:** Name variables to match class names for clean shorthand: `{ active }` instead of `{ active: isActive }`.
6256

6357
### Dynamic Styles
6458

docs/api/pug.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ div.card.featured.large
6060
### Dynamic Classes
6161

6262
```jsx
63-
// With condition
64-
div.button(styleName={active && 'active'})
63+
// Array with object for modifiers (recommended)
64+
div.button(styleName=['button', variant, { active, disabled }])
6565

6666
// Object syntax
67-
div.button(styleName={{ active, disabled }})
67+
div.button(styleName={ active, disabled })
6868
```
6969

7070
## Attributes
@@ -90,9 +90,9 @@ div.card(part="root")
9090
### Text Content
9191

9292
```jsx
93-
h1.title= title // Variable
94-
p.text Hello World // Static text
95-
span.count {count} items // Inline JS
93+
h1.title= title // Variable
94+
p.text Hello World // Static text
95+
span.count #{count} items // Inline interpolation
9696
```
9797

9898
### Children
@@ -262,7 +262,7 @@ If you don't use Pug, disable it for faster builds:
262262
|---------|-----|-----|
263263
| Class names | `styleName="a b"` | `.a.b` |
264264
| Attributes | `prop={value}` | `(prop=value)` |
265-
| Text | `{text}` | `= text` |
265+
| Text | `{text}` | `= text` or `#{text}` inline |
266266
| Conditionals | `{cond && <El />}` | `if cond` |
267267
| Loops | `{items.map(...)}` | `each item in items` |
268268

docs/api/styl-function.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,7 @@ The first argument supports the same syntax as `styleName`:
5858
// String
5959
<Card {...styl('card')} />
6060
61-
// Object
62-
<Card {...styl({ card: true, highlighted, compact })} />
63-
64-
// Array
65-
<Card {...styl(['card', active && 'active'])} />
66-
67-
// Mixed
61+
// Array with object (recommended)
6862
<Card {...styl(['card', variant, { highlighted, disabled }])} />
6963
```
7064

docs/examples/button.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ A simple button with variants and sizes.
55
```jsx
66
import { styl } from 'cssxjs'
77

8-
function Button({ variant = 'primary', size = 'medium', children }) {
8+
function Button({ variant = 'primary', size = 'medium', disabled, children }) {
99
return (
10-
<button styleName={{ button: true, [variant]: true, [size]: true }}>
10+
<button styleName={['button', variant, size, { disabled }]}>
1111
{children}
1212
</button>
1313
)
@@ -60,6 +60,6 @@ function Button({ variant = 'primary', size = 'medium', children }) {
6060

6161
## Key Concepts
6262

63-
- **Dynamic class names** with computed property syntax `[variant]: true`
63+
- **Array pattern** `['button', variant, size, { disabled }]` — base class, variants, then boolean modifiers
6464
- **Compound selectors** for size variants (`.small`, `.medium`, `.large`)
65-
- **Object shorthand** in `styleName` for cleaner conditional classes
65+
- **Object shorthand** `{ disabled }` for boolean modifiers

docs/examples/form.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ function Input({
1111
hint,
1212
...inputProps // native input props (type, value, onChange, etc.)
1313
}) {
14+
const hasError = !!error
1415
return (
15-
<div part="root" styleName={{ field: true, error: !!error }}>
16+
<div part="root" styleName={['field', { error: hasError }]}>
1617
{label && (
1718
<label part="label" styleName="label">
1819
{label}
@@ -88,7 +89,7 @@ function Input({
8889

8990
## Key Concepts
9091

91-
- **Conditional error class** with `{ error: !!error }`
92+
- **Array pattern** with boolean modifier `['field', { error: hasError }]`
9293
- **Nested selectors** for error state styling (`.error .input`)
9394
- **Focus states** with `&:focus`
9495
- **`part` attribute** for external customization

docs/examples/list.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function SelectableList({ items, onSelect }) {
1919
{items.map(item => (
2020
<li
2121
key={item.id}
22-
styleName={{ item: true, selected: selectedId === item.id }}
22+
styleName={['item', { selected: selectedId === item.id }]}
2323
onClick={() => handleSelect(item)}
2424
>
2525
<span styleName="icon">{item.icon}</span>
@@ -98,6 +98,6 @@ const items = [
9898
9999
## Key Concepts
100100
101-
- **Dynamic selection state** with `{ selected: selectedId === item.id }`
101+
- **Array pattern** `['item', { selected: ... }]` for dynamic selection
102102
- **List item layout** with flexbox
103103
- **Modifier class** `.selected` for active state

docs/examples/tabs.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function Tabs({ tabs, defaultTab }) {
1717
{tabs.map(tab => (
1818
<button
1919
key={tab.id}
20-
styleName={{ tab: true, active: activeTab === tab.id }}
20+
styleName={['tab', { active: activeTab === tab.id }]}
2121
onClick={() => setActiveTab(tab.id)}
2222
role="tab"
2323
aria-selected={activeTab === tab.id}
@@ -95,7 +95,7 @@ const tabs = [
9595
9696
## Key Concepts
9797
98-
- **Active indicator** using `::after` pseudo-element
98+
- **Array pattern** `['tab', { active: ... }]` for dynamic active state
99+
- **Active indicator** using `&.active::after` pseudo-element
99100
- **Accessibility** with `role="tablist"`, `role="tab"`, `aria-selected`
100-
- **Dynamic active class** with `{ active: activeTab === tab.id }`
101101
- **Flexible layout** with `flex: 1` for equal-width tabs

docs/guide/pug.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,16 @@ div.card.featured.large
8181

8282
### Dynamic Classes
8383

84-
Use curly braces for dynamic values:
84+
Use array with object for modifiers (recommended):
8585

8686
```jsx
87-
div.button(styleName={isActive && 'active'})
88-
// → <div styleName={`button ${isActive && 'active'}`} />
87+
div.button(styleName=['button', variant, { active, disabled }])
8988
```
9089

91-
Or with object syntax:
90+
Or object syntax only:
9291

9392
```jsx
94-
div.button(styleName={active: isActive, disabled: isDisabled})
93+
div.button(styleName={ active, disabled })
9594
```
9695

9796
## Attributes
@@ -119,9 +118,9 @@ div.card(part="root")
119118
Use `=` for interpolated text or plain text after the tag:
120119

121120
```jsx
122-
h1.title= title // Variable interpolation
123-
p.text Hello World // Static text
124-
span.count {count} items // Curly braces for inline JS
121+
h1.title= title // Variable interpolation
122+
p.text Hello World // Static text
123+
span.count #{count} items // Inline interpolation with #{}
125124
```
126125

127126
### Children

docs/guide/usage.md

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ This guide covers the essentials of CSSX: writing styles and applying them to co
77
```jsx
88
import { styl } from 'cssxjs'
99

10-
function Button({ children, primary }) {
10+
function Button({ children, variant, disabled }) {
1111
return (
12-
<button styleName={{ button: true, primary }}>
12+
<button styleName={['button', variant, { disabled }]}>
1313
{children}
1414
</button>
1515
)
@@ -24,6 +24,9 @@ function Button({ children, primary }) {
2424
.button.primary
2525
background #007bff
2626
color white
27+
28+
.button.disabled
29+
opacity 0.5
2730
`
2831
}
2932
```
@@ -66,32 +69,72 @@ css`
6669
6770
## Applying Styles with styleName
6871

69-
The `styleName` prop connects elements to CSS classes:
72+
The `styleName` prop connects elements to CSS classes. For simple cases, use a string:
7073

7174
```jsx
72-
// String
7375
<div styleName="card" />
76+
```
77+
78+
### The Recommended Pattern
79+
80+
For dynamic styling, use the **array pattern** — it's the cleanest and most maintainable approach:
81+
82+
```jsx
83+
<div styleName={['card', variant, { highlighted, compact }]} />
84+
```
85+
86+
This pattern has three parts, in order:
87+
88+
1. **Base class** — the main class name (`'card'`)
89+
2. **Variant variables** — string variables that map to class names (`variant`)
90+
3. **Boolean modifiers** — an object where keys become classes when values are truthy (`{ highlighted, compact }`)
91+
92+
**Example breakdown:**
93+
94+
```jsx
95+
function Card({ variant = 'default', highlighted, compact }) {
96+
// If variant='featured', highlighted=true, compact=false
97+
// Results in: class="card featured highlighted"
98+
return (
99+
<div styleName={['card', variant, { highlighted, compact }]}>
100+
Content
101+
</div>
102+
)
74103

75-
// Object — keys with truthy values are included
76-
<div styleName={{ card: true, active, highlighted }} />
104+
styl`
105+
.card
106+
background white
107+
padding 16px
77108
78-
// Array — falsy values are filtered out
79-
<div styleName={['card', active && 'active']} />
109+
.card.featured
110+
border 2px solid gold
111+
112+
.card.highlighted
113+
box-shadow 0 0 10px gold
80114
81-
// Mixed — combine all syntaxes
82-
<div styleName={['card', variant, { active, disabled }]} />
115+
.card.compact
116+
padding 8px
117+
`
118+
}
83119
```
84120

85-
**Tip:** Name variables to match class names for clean shorthand: `{ active }` instead of `{ active: isActive }`.
121+
**Why this pattern works:**
122+
123+
- **Readable** — clear separation between base, variants, and modifiers
124+
- **Clean** — no verbose `{ card: true, [variant]: true }` syntax
125+
- **Flexible** — add as many variants or modifiers as needed
126+
- **Maintainable** — easy to see what classes are applied
127+
128+
**Tip:** Name your variables to match class names for clean shorthand: use `{ active }` instead of `{ active: isActive }`. This makes the code self-documenting.
86129

87130
## Modifier Classes
88131

89132
Use compound selectors for variants:
90133

91134
```jsx
92-
function Card({ highlighted, compact }) {
135+
function Card({ variant, highlighted, compact }) {
93136
return (
94-
<div styleName={{ card: true, highlighted, compact }}>
137+
<div styleName={['card', variant, { highlighted, compact }]}>
95138
Content
96139
</div>
97140
)
@@ -101,9 +144,12 @@ function Card({ highlighted, compact }) {
101144
background white
102145
padding 16px
103146
104-
.card.highlighted
147+
.card.featured
105148
border 2px solid gold
106149
150+
.card.highlighted
151+
box-shadow 0 0 10px gold
152+
107153
.card.compact
108154
padding 8px
109155
`

0 commit comments

Comments
 (0)