@vanilla-bean/components 1.0.2 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Component/Component.js +5 -5
- package/Component/Component.scenarios.js +2 -2
- package/Component/Component.test.js +2 -2
- package/Component/observeElementConnection.js +1 -1
- package/README.md +1 -1
- package/components/BottomSheet/README.md +1 -1
- package/components/Button/Button.lld.md +1 -1
- package/components/Code/Code.lld.md +1 -1
- package/components/ColorPicker/ColorPicker.js +1 -1
- package/components/Dialog/Dialog.js +1 -1
- package/components/Dialog/Dialog.lld.md +1 -1
- package/components/Dialog/README.md +10 -10
- package/components/Form/Form.js +9 -9
- package/components/Form/Form.lld.md +2 -2
- package/components/Form/README.md +3 -3
- package/components/Input/README.md +7 -7
- package/components/Keyboard/Keyboard.lld.md +1 -1
- package/components/Menu/Menu.js +3 -3
- package/components/Notify/Notify.lld.md +2 -2
- package/components/Page/Page.lld.md +1 -1
- package/components/RadioButton/RadioButton.lld.md +1 -1
- package/components/Router/README.md +12 -12
- package/components/Select/README.md +5 -5
- package/components/Select/Select.js +1 -1
- package/components/Table/README.md +4 -4
- package/components/Table/Table.lld.md +1 -1
- package/components/TagList/TagList.lld.md +1 -1
- package/components/TooltipWrapper/TooltipWrapper.lld.md +2 -2
- package/components/Whiteboard/Whiteboard.lld.md +1 -1
- package/index.d.ts +4 -3
- package/package.json +1 -1
- package/theme/.test.js +20 -4
- package/theme/README.md +15 -8
- package/theme/button.js +1 -1
- package/theme/colors.js +9 -2
- package/theme/input.js +3 -3
- package/theme/page.js +6 -0
- package/theme/scrollbar.js +7 -3
- package/theme/table.js +2 -2
- package/utils/browser.js +1 -1
- package/Component/README.md +0 -455
- package/Elem/README.md +0 -373
- package/styled/README.md +0 -329
package/Elem/README.md
DELETED
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
# Elem
|
|
2
|
-
|
|
3
|
-
Enhanced DOM element wrapper providing fluent API methods while maintaining direct access to the underlying HTMLElement.
|
|
4
|
-
|
|
5
|
-
## Basic Usage
|
|
6
|
-
|
|
7
|
-
### Simple Element Creation
|
|
8
|
-
|
|
9
|
-
Create DOM elements with enhanced manipulation capabilities:
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
import { Elem } from '@vanilla-bean/components';
|
|
13
|
-
|
|
14
|
-
const button = new Elem({
|
|
15
|
-
tag: 'button',
|
|
16
|
-
textContent: 'Click me',
|
|
17
|
-
className: 'btn btn-primary',
|
|
18
|
-
onclick: () => alert('Clicked!'),
|
|
19
|
-
appendTo: document.body,
|
|
20
|
-
});
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Complex Nested Structures
|
|
24
|
-
|
|
25
|
-
Build complex DOM hierarchies with nested elements:
|
|
26
|
-
|
|
27
|
-
```js
|
|
28
|
-
const card = new Elem(
|
|
29
|
-
{
|
|
30
|
-
tag: 'div',
|
|
31
|
-
className: 'card',
|
|
32
|
-
style: { padding: '20px', margin: '10px' },
|
|
33
|
-
},
|
|
34
|
-
new Elem({ tag: 'h3', textContent: 'Card Title' }),
|
|
35
|
-
new Elem({ tag: 'p', textContent: 'Card content goes here.' }),
|
|
36
|
-
);
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Method Chaining
|
|
40
|
-
|
|
41
|
-
Chain methods for fluent DOM construction:
|
|
42
|
-
|
|
43
|
-
```js
|
|
44
|
-
const navigation = new Elem({ tag: 'nav' })
|
|
45
|
-
.addClass('menu', 'horizontal')
|
|
46
|
-
.setStyle({ display: 'flex', gap: '16px' })
|
|
47
|
-
.append(
|
|
48
|
-
new Elem({ tag: 'a', textContent: 'Home', href: '/' }),
|
|
49
|
-
new Elem({ tag: 'a', textContent: 'About', href: '/about' }),
|
|
50
|
-
new Elem({ tag: 'a', textContent: 'Contact', href: '/contact' }),
|
|
51
|
-
)
|
|
52
|
-
.appendTo(document.body);
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Direct DOM Access
|
|
56
|
-
|
|
57
|
-
Access the full HTMLElement API when needed:
|
|
58
|
-
|
|
59
|
-
```js
|
|
60
|
-
const input = new Elem({ tag: 'input', type: 'text' });
|
|
61
|
-
|
|
62
|
-
// Enhanced methods
|
|
63
|
-
input.addClass('form-control').setStyle({ width: '100%' });
|
|
64
|
-
|
|
65
|
-
// Direct DOM access
|
|
66
|
-
input.elem.focus();
|
|
67
|
-
input.elem.select();
|
|
68
|
-
input.elem.scrollIntoView({ behavior: 'smooth' });
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Configuration Options
|
|
72
|
-
|
|
73
|
-
### Constructor Syntax
|
|
74
|
-
|
|
75
|
-
```js
|
|
76
|
-
new Elem(options?, ...children)
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**Parameters:**
|
|
80
|
-
|
|
81
|
-
- `options` (Object) - Configuration options and HTML properties
|
|
82
|
-
- `children` (...Elem|HTMLElement|string) - Child elements or text content
|
|
83
|
-
|
|
84
|
-
### Core Options
|
|
85
|
-
|
|
86
|
-
| Option | Type | Description |
|
|
87
|
-
| ------------ | --------------------------- | ---------------------------------- |
|
|
88
|
-
| `tag` | `string` | HTML tag name (default: 'div') |
|
|
89
|
-
| `style` | `object` | CSS properties as key-value pairs |
|
|
90
|
-
| `attributes` | `object` | HTML attributes as key-value pairs |
|
|
91
|
-
| `content` | `string\|Elem\|HTMLElement` | Element content |
|
|
92
|
-
| `appendTo` | `Elem\|HTMLElement` | Parent element to append to |
|
|
93
|
-
| `prependTo` | `Elem\|HTMLElement` | Parent element to prepend to |
|
|
94
|
-
| `append` | `Array` | Child elements to append |
|
|
95
|
-
| `prepend` | `Array` | Child elements to prepend |
|
|
96
|
-
|
|
97
|
-
### HTML Properties
|
|
98
|
-
|
|
99
|
-
All standard HTMLElement properties work as options:
|
|
100
|
-
|
|
101
|
-
```js
|
|
102
|
-
new Elem({
|
|
103
|
-
// Content properties
|
|
104
|
-
textContent: 'Button text',
|
|
105
|
-
innerHTML: '<span>HTML content</span>',
|
|
106
|
-
|
|
107
|
-
// Form properties
|
|
108
|
-
value: 'input value',
|
|
109
|
-
checked: true,
|
|
110
|
-
disabled: false,
|
|
111
|
-
|
|
112
|
-
// Element properties
|
|
113
|
-
id: 'unique-id',
|
|
114
|
-
className: 'btn primary',
|
|
115
|
-
title: 'Tooltip text',
|
|
116
|
-
|
|
117
|
-
// Link properties
|
|
118
|
-
href: 'https://example.com',
|
|
119
|
-
target: '_blank',
|
|
120
|
-
|
|
121
|
-
// Image properties
|
|
122
|
-
src: 'image.jpg',
|
|
123
|
-
alt: 'Image description',
|
|
124
|
-
});
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Event Handler Properties
|
|
128
|
-
|
|
129
|
-
Event handlers can be assigned directly:
|
|
130
|
-
|
|
131
|
-
```js
|
|
132
|
-
new Elem({
|
|
133
|
-
tag: 'button',
|
|
134
|
-
onclick: event => console.log('clicked'),
|
|
135
|
-
onmouseover: event => console.log('hover'),
|
|
136
|
-
onchange: event => console.log('changed'),
|
|
137
|
-
onfocus: event => console.log('focused'),
|
|
138
|
-
});
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## DOM Manipulation
|
|
142
|
-
|
|
143
|
-
### Content Management
|
|
144
|
-
|
|
145
|
-
```js
|
|
146
|
-
// Set content (replaces existing)
|
|
147
|
-
elem.content('New text content');
|
|
148
|
-
elem.content(new Elem({ tag: 'span', textContent: 'HTML element' }));
|
|
149
|
-
|
|
150
|
-
// Clear all content
|
|
151
|
-
elem.empty();
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### Child Element Management
|
|
155
|
-
|
|
156
|
-
```js
|
|
157
|
-
// Add children
|
|
158
|
-
elem.append(child1, child2, 'text content');
|
|
159
|
-
elem.prepend(child1, child2);
|
|
160
|
-
|
|
161
|
-
// Access children
|
|
162
|
-
const childElements = elem.children; // Array of Elem instances
|
|
163
|
-
const nativeChildren = elem.elem.children; // HTMLCollection
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Hierarchy Management
|
|
167
|
-
|
|
168
|
-
```js
|
|
169
|
-
// Add to DOM
|
|
170
|
-
elem.appendTo(document.body);
|
|
171
|
-
elem.prependTo(document.querySelector('.container'));
|
|
172
|
-
|
|
173
|
-
// Navigate hierarchy
|
|
174
|
-
const parentElem = elem.parent; // Parent Elem instance (if exists)
|
|
175
|
-
const nativeParent = elem.parentElem; // Parent HTMLElement
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Style and Attribute Management
|
|
179
|
-
|
|
180
|
-
```js
|
|
181
|
-
// Set multiple styles
|
|
182
|
-
elem.setStyle({
|
|
183
|
-
color: 'red',
|
|
184
|
-
fontSize: '16px',
|
|
185
|
-
backgroundColor: '#f0f0f0',
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Set multiple attributes
|
|
189
|
-
elem.setAttributes({
|
|
190
|
-
'data-id': '123',
|
|
191
|
-
'aria-label': 'Close button',
|
|
192
|
-
role: 'button',
|
|
193
|
-
});
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## Class Management
|
|
197
|
-
|
|
198
|
-
### Enhanced Class Operations
|
|
199
|
-
|
|
200
|
-
Elem provides enhanced class manipulation with regular expression support:
|
|
201
|
-
|
|
202
|
-
```js
|
|
203
|
-
// Check for classes
|
|
204
|
-
elem.hasClass('active'); // Check single class
|
|
205
|
-
elem.hasClass('btn', 'primary'); // Check multiple classes
|
|
206
|
-
elem.hasClass(/^btn-/); // Check with regex pattern
|
|
207
|
-
|
|
208
|
-
// Add classes
|
|
209
|
-
elem.addClass('new-class');
|
|
210
|
-
elem.addClass('class1', 'class2', 'class3');
|
|
211
|
-
|
|
212
|
-
// Remove classes
|
|
213
|
-
elem.removeClass('old-class');
|
|
214
|
-
elem.removeClass(/^temp-/); // Remove all classes starting with 'temp-'
|
|
215
|
-
elem.removeClass(/\bmobile-\w+/g); // Remove classes matching pattern
|
|
216
|
-
|
|
217
|
-
// Toggle class based on a condition (add when true, remove when false)
|
|
218
|
-
elem.toggleClass('active', isActive);
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Class Manipulation Examples
|
|
222
|
-
|
|
223
|
-
```js
|
|
224
|
-
const button = new Elem({ tag: 'button', className: 'btn btn-primary temp-123' });
|
|
225
|
-
|
|
226
|
-
// Remove all temporary classes
|
|
227
|
-
button.removeClass(/^temp-/);
|
|
228
|
-
|
|
229
|
-
// Add state classes
|
|
230
|
-
button.addClass('btn-large', 'btn-rounded');
|
|
231
|
-
|
|
232
|
-
// Conditional classes
|
|
233
|
-
if (isActive) {
|
|
234
|
-
button.addClass('active', 'selected');
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Check for button variants
|
|
238
|
-
if (button.hasClass(/^btn-(primary|secondary|danger)$/)) {
|
|
239
|
-
console.log('Has button variant class');
|
|
240
|
-
}
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
## Event Handling
|
|
244
|
-
|
|
245
|
-
### EventTarget Integration
|
|
246
|
-
|
|
247
|
-
Elem extends EventTarget, providing full event capabilities:
|
|
248
|
-
|
|
249
|
-
```js
|
|
250
|
-
const button = new Elem({ tag: 'button', textContent: 'Click me' });
|
|
251
|
-
|
|
252
|
-
// Option-based event handlers
|
|
253
|
-
new Elem({
|
|
254
|
-
tag: 'input',
|
|
255
|
-
onchange: event => console.log('Value changed:', event.target.value),
|
|
256
|
-
onfocus: event => event.target.select(),
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
// addEventListener method
|
|
260
|
-
button.addEventListener('click', event => {
|
|
261
|
-
console.log('Button clicked');
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
// Custom events
|
|
265
|
-
button.addEventListener('customEvent', event => {
|
|
266
|
-
console.log('Custom event data:', event.detail);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
// Dispatch events
|
|
270
|
-
button.dispatchEvent(
|
|
271
|
-
new CustomEvent('customEvent', {
|
|
272
|
-
detail: { message: 'Hello' },
|
|
273
|
-
}),
|
|
274
|
-
);
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Event Handler Options vs Methods
|
|
278
|
-
|
|
279
|
-
```js
|
|
280
|
-
// Via constructor options (preferred for initial setup)
|
|
281
|
-
const elem = new Elem({
|
|
282
|
-
tag: 'button',
|
|
283
|
-
onclick: handleClick,
|
|
284
|
-
onmouseover: handleHover,
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
// Via addEventListener (preferred for dynamic binding)
|
|
288
|
-
elem.addEventListener('click', handleClick);
|
|
289
|
-
elem.addEventListener('mouseover', handleHover);
|
|
290
|
-
|
|
291
|
-
// Via native element
|
|
292
|
-
elem.elem.addEventListener('click', handleClick);
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## API Reference
|
|
296
|
-
|
|
297
|
-
### Constructor
|
|
298
|
-
|
|
299
|
-
```js
|
|
300
|
-
new Elem(options?, ...children)
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### Core Methods
|
|
304
|
-
|
|
305
|
-
#### Content Methods
|
|
306
|
-
|
|
307
|
-
```js
|
|
308
|
-
elem.content(content); // Set element content
|
|
309
|
-
elem.empty(); // Remove all child elements
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
#### Child Management Methods
|
|
313
|
-
|
|
314
|
-
```js
|
|
315
|
-
elem.append(...children); // Append child elements
|
|
316
|
-
elem.prepend(...children); // Prepend child elements
|
|
317
|
-
elem.appendTo(parent); // Append to parent element
|
|
318
|
-
elem.prependTo(parent); // Prepend to parent element
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
#### Style and Attribute Methods
|
|
322
|
-
|
|
323
|
-
```js
|
|
324
|
-
elem.setStyle(styles); // Set CSS properties
|
|
325
|
-
elem.setAttributes(attributes); // Set HTML attributes
|
|
326
|
-
elem.setOptions(options); // Set multiple options at once
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
#### Class Methods
|
|
330
|
-
|
|
331
|
-
```js
|
|
332
|
-
elem.hasClass(...classes); // Check for classes (supports regex)
|
|
333
|
-
elem.addClass(...classes); // Add CSS classes
|
|
334
|
-
elem.removeClass(...classes); // Remove CSS classes (supports regex)
|
|
335
|
-
elem.toggleClass(className, condition); // Add when condition is true, remove when false
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Properties
|
|
339
|
-
|
|
340
|
-
```js
|
|
341
|
-
elem.elem; // Underlying HTMLElement
|
|
342
|
-
elem.parent; // Parent Elem instance (if created by Elem)
|
|
343
|
-
elem.parentElem; // Parent HTMLElement
|
|
344
|
-
elem.children; // Array of child Elem instances
|
|
345
|
-
elem.options; // Configuration options object
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Utility Methods
|
|
349
|
-
|
|
350
|
-
```js
|
|
351
|
-
elem.toString(); // Returns '[object Elem]'
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## Integration with Component
|
|
355
|
-
|
|
356
|
-
Elem serves as the foundation for the Component class:
|
|
357
|
-
|
|
358
|
-
```js
|
|
359
|
-
import { Component } from '@vanilla-bean/components';
|
|
360
|
-
|
|
361
|
-
// Component extends Elem with reactive options
|
|
362
|
-
const component = new Component({
|
|
363
|
-
tag: 'div',
|
|
364
|
-
textContent: 'I am reactive!',
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
// All Elem methods available
|
|
368
|
-
component.addClass('component-class');
|
|
369
|
-
component.setStyle({ padding: '16px' });
|
|
370
|
-
|
|
371
|
-
// Plus Component-specific features
|
|
372
|
-
component.options.textContent = 'Updated reactively!';
|
|
373
|
-
```
|
package/styled/README.md
DELETED
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
# styled
|
|
2
|
-
|
|
3
|
-
Create Component subclasses with scoped CSS: each `styled()` call generates a unique class, processes the theme, and injects a `<style>` element into `<head>`.
|
|
4
|
-
|
|
5
|
-
## Basic Usage
|
|
6
|
-
|
|
7
|
-
### Template Literal Syntax
|
|
8
|
-
|
|
9
|
-
Create styled components using template literals with theme integration:
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
const StyledIcon = styled.Icon`
|
|
13
|
-
background-color: ${({ colors }) => colors.black};
|
|
14
|
-
width: 24px;
|
|
15
|
-
height: 24px;
|
|
16
|
-
|
|
17
|
-
&:before {
|
|
18
|
-
${({ fonts }) => fonts.fontAwesomeSolid}
|
|
19
|
-
content: "\f015";
|
|
20
|
-
}
|
|
21
|
-
`;
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### Function Syntax with Configuration
|
|
25
|
-
|
|
26
|
-
Use function syntax when you need to pass component configuration options:
|
|
27
|
-
|
|
28
|
-
```js
|
|
29
|
-
const ConfiguredComponent = styled(
|
|
30
|
-
Component,
|
|
31
|
-
({ colors }) => `
|
|
32
|
-
background-color: ${colors.black};
|
|
33
|
-
color: ${colors.lighter(colors.blue)};
|
|
34
|
-
padding: 12px;
|
|
35
|
-
|
|
36
|
-
&:hover {
|
|
37
|
-
background-color: ${colors.dark(colors.blue)};
|
|
38
|
-
}
|
|
39
|
-
`,
|
|
40
|
-
{
|
|
41
|
-
tag: 'section',
|
|
42
|
-
role: 'banner',
|
|
43
|
-
textContent: 'Default Text',
|
|
44
|
-
},
|
|
45
|
-
);
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Named Component Shortcuts
|
|
49
|
-
|
|
50
|
-
All top-level components are available as shorthand methods:
|
|
51
|
-
|
|
52
|
-
```js
|
|
53
|
-
const StyledButton = styled.Button`
|
|
54
|
-
background-color: ${({ colors }) => colors.green};
|
|
55
|
-
border-radius: 8px;
|
|
56
|
-
`;
|
|
57
|
-
|
|
58
|
-
const StyledInput = styled.Input`
|
|
59
|
-
${({ fonts }) => fonts.kodeMono}
|
|
60
|
-
border: 2px solid ${({ colors }) => colors.blue};
|
|
61
|
-
`;
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**Note**: Template literal syntax creates components with empty configuration. Use function syntax to pass component options.
|
|
65
|
-
|
|
66
|
-
## Theme Integration
|
|
67
|
-
|
|
68
|
-
Style functions receive the complete theme object containing colors, fonts, and component styles:
|
|
69
|
-
|
|
70
|
-
```js
|
|
71
|
-
const ThemedComponent = styled.Component`
|
|
72
|
-
${({ button }) => button} /* Apply base button styles */
|
|
73
|
-
${({ fonts }) => fonts.kodeMono}
|
|
74
|
-
background: ${({ colors }) => colors.darker(colors.blue)};
|
|
75
|
-
color: ${({ colors }) => colors.mostReadable(colors.blue, [colors.white, colors.black])};
|
|
76
|
-
`;
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Runtime Style Override
|
|
80
|
-
|
|
81
|
-
Override or extend styles when creating component instances:
|
|
82
|
-
|
|
83
|
-
```js
|
|
84
|
-
const instance = new StyledComponent({
|
|
85
|
-
styles: ({ colors }) => ({
|
|
86
|
-
backgroundColor: colors.red,
|
|
87
|
-
border: `2px solid ${colors.darker(colors.red)}`,
|
|
88
|
-
}),
|
|
89
|
-
});
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Object-based styles apply as inline styles. Function-based styles generate scoped CSS.
|
|
93
|
-
|
|
94
|
-
## Component Inheritance
|
|
95
|
-
|
|
96
|
-
### Extending Styled Components
|
|
97
|
-
|
|
98
|
-
Build component hierarchies by extending existing styled components:
|
|
99
|
-
|
|
100
|
-
```js
|
|
101
|
-
const BaseButton = styled.Button`
|
|
102
|
-
padding: 8px 16px;
|
|
103
|
-
border-radius: 4px;
|
|
104
|
-
`;
|
|
105
|
-
|
|
106
|
-
const PrimaryButton = styled(BaseButton)`
|
|
107
|
-
background: ${({ colors }) => colors.blue};
|
|
108
|
-
color: ${({ colors }) => colors.white};
|
|
109
|
-
`;
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Template Literals with Any Styled Component
|
|
113
|
-
|
|
114
|
-
Template literal syntax works with any styled component, including those created with function syntax:
|
|
115
|
-
|
|
116
|
-
```js
|
|
117
|
-
const BaseComponent = styled(Component, () => 'color: red;');
|
|
118
|
-
|
|
119
|
-
// Extend any styled component with template literals
|
|
120
|
-
const ExtendedComponent = styled(BaseComponent)`
|
|
121
|
-
background: ${({ colors }) => colors.blue};
|
|
122
|
-
padding: 16px;
|
|
123
|
-
`;
|
|
124
|
-
|
|
125
|
-
// Use in class definitions for custom methods
|
|
126
|
-
class MyComponent extends (styled(BaseComponent)`
|
|
127
|
-
font-weight: bold;
|
|
128
|
-
border-radius: 4px;
|
|
129
|
-
`) {
|
|
130
|
-
// Add custom methods here
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Component Functionality Inheritance
|
|
135
|
-
|
|
136
|
-
Styled components inherit all functionality from their base component:
|
|
137
|
-
|
|
138
|
-
```js
|
|
139
|
-
const StyledInput = styled.Input`
|
|
140
|
-
border: 2px solid ${({ colors }) => colors.blue};
|
|
141
|
-
`;
|
|
142
|
-
|
|
143
|
-
const instance = new StyledInput({
|
|
144
|
-
value: 'initial value',
|
|
145
|
-
onChange: event => console.log(event.value),
|
|
146
|
-
placeholder: 'Enter text...',
|
|
147
|
-
});
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
## CSS Processing
|
|
151
|
-
|
|
152
|
-
### Native CSS Nesting
|
|
153
|
-
|
|
154
|
-
Styles are injected as written, no transformation, no runtime compilation. VBC requires Chrome 112+, Firefox 117+, and Safari 16.5+, all of which support the `&` nesting syntax natively.
|
|
155
|
-
|
|
156
|
-
```js
|
|
157
|
-
const NestedComponent = styled.Component`
|
|
158
|
-
padding: 16px;
|
|
159
|
-
|
|
160
|
-
& .child {
|
|
161
|
-
margin: 8px;
|
|
162
|
-
|
|
163
|
-
&:hover {
|
|
164
|
-
background: ${({ colors }) => colors.blue};
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
@media (max-width: 768px) {
|
|
169
|
-
padding: 8px;
|
|
170
|
-
}
|
|
171
|
-
`;
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Automatic Scoping
|
|
175
|
-
|
|
176
|
-
Each styled component receives a unique class identifier to prevent CSS conflicts:
|
|
177
|
-
|
|
178
|
-
```js
|
|
179
|
-
const StyledDiv = styled(Component, () => `color: red;`);
|
|
180
|
-
const instance = new StyledDiv();
|
|
181
|
-
|
|
182
|
-
// Generated CSS: .a1b2c3d4 { color: red; }
|
|
183
|
-
// Component class: "a1b2c3d4"
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
### Conditional Styles
|
|
187
|
-
|
|
188
|
-
Apply conditional styles using CSS classes and selectors:
|
|
189
|
-
|
|
190
|
-
```js
|
|
191
|
-
const ConditionalComponent = styled.Component`
|
|
192
|
-
padding: 12px;
|
|
193
|
-
background: ${({ colors }) => colors.white};
|
|
194
|
-
|
|
195
|
-
&.active {
|
|
196
|
-
background: ${({ colors }) => colors.blue};
|
|
197
|
-
color: ${({ colors }) => colors.white};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
&.disabled {
|
|
201
|
-
opacity: 0.5;
|
|
202
|
-
pointer-events: none;
|
|
203
|
-
}
|
|
204
|
-
`;
|
|
205
|
-
|
|
206
|
-
const instance = new ConditionalComponent({
|
|
207
|
-
addClass: 'active',
|
|
208
|
-
textContent: 'Active Button',
|
|
209
|
-
});
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## Performance
|
|
213
|
-
|
|
214
|
-
### Processing Pipeline
|
|
215
|
-
|
|
216
|
-
The styled system processes styles through this pipeline:
|
|
217
|
-
|
|
218
|
-
1. **Component Creation** - Generates unique class identifier via `classSafeNanoid()`
|
|
219
|
-
2. **Style Processing** - Converts template literals into theme functions
|
|
220
|
-
3. **Theme Application** - Injects complete theme object into style functions
|
|
221
|
-
4. **CSS Processing** - Processes styles through `shimCSS()` pipeline
|
|
222
|
-
5. **DOM Injection** - Injects final CSS via `appendStyles()`
|
|
223
|
-
|
|
224
|
-
### Load-Time Optimization
|
|
225
|
-
|
|
226
|
-
Style processing timing depends on document state:
|
|
227
|
-
|
|
228
|
-
| Document State | Behavior |
|
|
229
|
-
| ------------------- | ------------------------------------------ |
|
|
230
|
-
| Complete | Processes and injects immediately |
|
|
231
|
-
| Loading | Queues for batch processing on window load |
|
|
232
|
-
| Multiple Components | Batches together for efficiency |
|
|
233
|
-
|
|
234
|
-
```js
|
|
235
|
-
// Document loaded - processes immediately
|
|
236
|
-
const StyledComponent = styled(Component, () => 'color: red;');
|
|
237
|
-
|
|
238
|
-
// Document loading - queued for batch processing
|
|
239
|
-
const AnotherStyled = styled(Component, () => 'color: blue;');
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
## API Reference
|
|
243
|
-
|
|
244
|
-
### styled(BaseComponent, styles?, options?)
|
|
245
|
-
|
|
246
|
-
Creates a styled component class.
|
|
247
|
-
|
|
248
|
-
**Parameters:**
|
|
249
|
-
|
|
250
|
-
- `BaseComponent` (Function) - Component class to extend
|
|
251
|
-
- `styles` (Function|String) - Style function or CSS string
|
|
252
|
-
- `options` (Object) - Component configuration options
|
|
253
|
-
|
|
254
|
-
**Returns:** Extended component class with scoped styling
|
|
255
|
-
|
|
256
|
-
### configured(BaseComponent, options)
|
|
257
|
-
|
|
258
|
-
Creates a component with configuration but no styles:
|
|
259
|
-
|
|
260
|
-
```js
|
|
261
|
-
const ConfiguredComponent = configured(Component, {
|
|
262
|
-
tag: 'article',
|
|
263
|
-
role: 'main',
|
|
264
|
-
textContent: 'Default Content',
|
|
265
|
-
});
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Utility Functions
|
|
269
|
-
|
|
270
|
-
#### appendStyles(css, id?)
|
|
271
|
-
|
|
272
|
-
Inject CSS directly into the page:
|
|
273
|
-
|
|
274
|
-
```js
|
|
275
|
-
appendStyles(
|
|
276
|
-
`
|
|
277
|
-
.my-global-class {
|
|
278
|
-
font-weight: bold;
|
|
279
|
-
color: red;
|
|
280
|
-
}
|
|
281
|
-
`,
|
|
282
|
-
'my-global-styles',
|
|
283
|
-
);
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
#### themeStyles({ styles, scope })
|
|
287
|
-
|
|
288
|
-
Generate themed CSS with optional scoping:
|
|
289
|
-
|
|
290
|
-
```js
|
|
291
|
-
const themedCSS = themeStyles({
|
|
292
|
-
styles: ({ colors }) => `color: ${colors.white}; background: ${colors.black};`,
|
|
293
|
-
scope: '.my-component',
|
|
294
|
-
});
|
|
295
|
-
// Returns: ".my-component { color: hsl(0, 0%, 90%); background: hsl(0, 0%, 10%); }"
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
#### shimCSS(styleConfig)
|
|
299
|
-
|
|
300
|
-
Complete style processing pipeline:
|
|
301
|
-
|
|
302
|
-
```js
|
|
303
|
-
shimCSS({
|
|
304
|
-
styles: ({ colors }) => `
|
|
305
|
-
display: flex;
|
|
306
|
-
background: ${colors.blue};
|
|
307
|
-
& .item { padding: 8px; }
|
|
308
|
-
`,
|
|
309
|
-
scope: '.my-scoped-component',
|
|
310
|
-
});
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
## Development Features
|
|
314
|
-
|
|
315
|
-
### Debug Class Names
|
|
316
|
-
|
|
317
|
-
Development mode adds inheritance-based class names for easier debugging:
|
|
318
|
-
|
|
319
|
-
```js
|
|
320
|
-
// Development classes: "a1b2c3 MyCustomComponent Component Elem"
|
|
321
|
-
class MyCustomComponent extends Component {}
|
|
322
|
-
const StyledCustom = styled(MyCustomComponent, () => 'color: blue;');
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### Memory Management
|
|
326
|
-
|
|
327
|
-
Class-level styles injected by `styled()` persist for the page lifetime. They are scoped to a unique class and do not interfere with other components, but are not removed when instances disconnect.
|
|
328
|
-
|
|
329
|
-
Per-instance styles set via the `styles` option on a component instance are cleaned up when that component disconnects from the DOM.
|