@tachui/primitives 0.8.0-alpha
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/LICENSE +363 -0
- package/README.md +458 -0
- package/dist/BasicInput-CWFHw9rL.js +390 -0
- package/dist/Divider-DWgDKavU.js +474 -0
- package/dist/HTML-aWcvQ0VC.js +321 -0
- package/dist/Picker-DrZ7ibdt.js +1675 -0
- package/dist/Text-DYyFBJ6i.js +165 -0
- package/dist/controls/Button.d.ts +250 -0
- package/dist/controls/Button.d.ts.map +1 -0
- package/dist/controls/Link.d.ts +365 -0
- package/dist/controls/Link.d.ts.map +1 -0
- package/dist/controls/Picker.d.ts +153 -0
- package/dist/controls/Picker.d.ts.map +1 -0
- package/dist/controls/Toggle.d.ts +207 -0
- package/dist/controls/Toggle.d.ts.map +1 -0
- package/dist/controls/index.d.ts +8 -0
- package/dist/controls/index.d.ts.map +1 -0
- package/dist/controls/index.js +18 -0
- package/dist/display/HTML.d.ts +120 -0
- package/dist/display/HTML.d.ts.map +1 -0
- package/dist/display/Image.d.ts +192 -0
- package/dist/display/Image.d.ts.map +1 -0
- package/dist/display/Text.d.ts +269 -0
- package/dist/display/Text.d.ts.map +1 -0
- package/dist/display/index.d.ts +7 -0
- package/dist/display/index.d.ts.map +1 -0
- package/dist/display/index.js +21 -0
- package/dist/forms/BasicForm.d.ts +141 -0
- package/dist/forms/BasicForm.d.ts.map +1 -0
- package/dist/forms/BasicInput.d.ts +116 -0
- package/dist/forms/BasicInput.d.ts.map +1 -0
- package/dist/forms/index.d.ts +6 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/index.js +10 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +485 -0
- package/dist/layout/Divider.d.ts +168 -0
- package/dist/layout/Divider.d.ts.map +1 -0
- package/dist/layout/Spacer.d.ts +35 -0
- package/dist/layout/Spacer.d.ts.map +1 -0
- package/dist/layout/Stack.d.ts +74 -0
- package/dist/layout/Stack.d.ts.map +1 -0
- package/dist/layout/index.d.ts +7 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +15 -0
- package/dist/validation.d.ts +91 -0
- package/dist/validation.d.ts.map +1 -0
- package/package.json +82 -0
package/README.md
ADDED
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# @tachui/primitives
|
|
2
|
+
|
|
3
|
+
Foundation UI components for tachUI applications - the building blocks of modern web interfaces.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `@tachui/primitives` package provides essential UI components that serve as the foundation for all tachUI applications. These components offer SwiftUI-inspired APIs with web-native performance and accessibility.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @tachui/primitives@0.8.0-alpha
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @tachui/primitives@0.8.0-alpha
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Core Components
|
|
18
|
+
|
|
19
|
+
### Layout Components
|
|
20
|
+
|
|
21
|
+
#### VStack
|
|
22
|
+
|
|
23
|
+
Vertically stacks child components with customizable spacing and alignment.
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { VStack, Text } from '@tachui/primitives'
|
|
27
|
+
|
|
28
|
+
VStack({
|
|
29
|
+
spacing: 16,
|
|
30
|
+
alignment: 'leading',
|
|
31
|
+
children: [Text('First Item'), Text('Second Item'), Text('Third Item')],
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### HStack
|
|
36
|
+
|
|
37
|
+
Horizontally arranges child components with flexible alignment options.
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { HStack, Button } from '@tachui/primitives'
|
|
41
|
+
|
|
42
|
+
HStack({
|
|
43
|
+
spacing: 12,
|
|
44
|
+
alignment: 'center',
|
|
45
|
+
children: [Button('Cancel'), Spacer(), Button('Save')],
|
|
46
|
+
})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### ZStack
|
|
50
|
+
|
|
51
|
+
Overlays components on top of each other with alignment control.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { ZStack, Image, Text } from '@tachui/primitives'
|
|
55
|
+
|
|
56
|
+
ZStack({
|
|
57
|
+
alignment: 'bottomTrailing',
|
|
58
|
+
children: [
|
|
59
|
+
Image('/hero-background.jpg'),
|
|
60
|
+
Text('Overlay Text')
|
|
61
|
+
.modifier.padding(16)
|
|
62
|
+
.backgroundColor('rgba(0,0,0,0.7)')
|
|
63
|
+
.foregroundColor('white')
|
|
64
|
+
.build(),
|
|
65
|
+
],
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Spacer
|
|
70
|
+
|
|
71
|
+
Flexible space that expands to fill available space in stacks.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
HStack({
|
|
75
|
+
children: [
|
|
76
|
+
Text('Left'),
|
|
77
|
+
Spacer(), // Pushes content to edges
|
|
78
|
+
Text('Right'),
|
|
79
|
+
],
|
|
80
|
+
})
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Divider
|
|
84
|
+
|
|
85
|
+
Visual separator line with customizable appearance.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
VStack({
|
|
89
|
+
children: [Text('Section 1'), Divider(), Text('Section 2')],
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Display Components
|
|
94
|
+
|
|
95
|
+
#### Text
|
|
96
|
+
|
|
97
|
+
Displays text content with full typography control.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
Text('Hello, tachUI!')
|
|
101
|
+
.modifier.font({ family: 'San Francisco', size: 18, weight: 600 })
|
|
102
|
+
.foregroundColor('#007AFF')
|
|
103
|
+
.textAlign('center')
|
|
104
|
+
.build()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Advanced Text Features:**
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// Multiline text with line clamping
|
|
111
|
+
Text(longContent).modifier.lineClamp(3).wordBreak('break-word').build()
|
|
112
|
+
|
|
113
|
+
// Reactive text content
|
|
114
|
+
const [count, setCount] = createSignal(0)
|
|
115
|
+
Text(() => `Count: ${count()}`)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Image
|
|
119
|
+
|
|
120
|
+
Displays images with loading states and aspect ratio control.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
Image('/path/to/image.jpg')
|
|
124
|
+
.modifier.size({ width: 200, height: 150 })
|
|
125
|
+
.cornerRadius(8)
|
|
126
|
+
.aspectRatio('cover')
|
|
127
|
+
.build()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Image with Assets:**
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { Assets } from '@tachui/core'
|
|
134
|
+
|
|
135
|
+
Image(Assets.profilePicture)
|
|
136
|
+
.modifier.size({ width: 60, height: 60 })
|
|
137
|
+
.cornerRadius(30)
|
|
138
|
+
.build()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### HTML
|
|
142
|
+
|
|
143
|
+
Renders raw HTML content safely with sanitization.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
HTML({
|
|
147
|
+
content: '<p>Safe <strong>HTML</strong> content</p>',
|
|
148
|
+
sanitize: true,
|
|
149
|
+
})
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Control Components
|
|
153
|
+
|
|
154
|
+
#### Button
|
|
155
|
+
|
|
156
|
+
Interactive button component with full customization support.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
Button('Click Me', () => {
|
|
160
|
+
console.log('Button clicked!')
|
|
161
|
+
})
|
|
162
|
+
.modifier.padding({ horizontal: 16, vertical: 8 })
|
|
163
|
+
.backgroundColor('#007AFF')
|
|
164
|
+
.foregroundColor('white')
|
|
165
|
+
.cornerRadius(8)
|
|
166
|
+
.build()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Button States:**
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
Button('Stateful Button', handleClick)
|
|
173
|
+
.modifier.backgroundColor('#007AFF')
|
|
174
|
+
.hover({ backgroundColor: '#0051D5' })
|
|
175
|
+
.active({ transform: 'scale(0.95)' })
|
|
176
|
+
.disabled({ opacity: 0.5 })
|
|
177
|
+
.build()
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### Toggle
|
|
181
|
+
|
|
182
|
+
Switch/toggle component for boolean states.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
const [isEnabled, setIsEnabled] = createSignal(false)
|
|
186
|
+
|
|
187
|
+
Toggle({
|
|
188
|
+
isOn: () => isEnabled(),
|
|
189
|
+
onToggle: setIsEnabled,
|
|
190
|
+
})
|
|
191
|
+
.modifier.accentColor('#007AFF')
|
|
192
|
+
.build()
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### Picker
|
|
196
|
+
|
|
197
|
+
Selection component for choosing from multiple options.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
const options = ['Option 1', 'Option 2', 'Option 3']
|
|
201
|
+
const [selected, setSelected] = createSignal(options[0])
|
|
202
|
+
|
|
203
|
+
Picker({
|
|
204
|
+
selection: () => selected(),
|
|
205
|
+
onSelectionChange: setSelected,
|
|
206
|
+
options: options,
|
|
207
|
+
renderOption: option => Text(option),
|
|
208
|
+
})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Form Components
|
|
212
|
+
|
|
213
|
+
#### BasicInput
|
|
214
|
+
|
|
215
|
+
Text input component with validation and formatting support.
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
const [text, setText] = createSignal('')
|
|
219
|
+
|
|
220
|
+
BasicInput({
|
|
221
|
+
value: () => text(),
|
|
222
|
+
onInput: setText,
|
|
223
|
+
placeholder: 'Enter your name',
|
|
224
|
+
})
|
|
225
|
+
.modifier.padding(12)
|
|
226
|
+
.border(1, '#E5E5EA')
|
|
227
|
+
.cornerRadius(8)
|
|
228
|
+
.build()
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Advanced Input Features:**
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
BasicInput({
|
|
235
|
+
value: () => email(),
|
|
236
|
+
onInput: setEmail,
|
|
237
|
+
type: 'email',
|
|
238
|
+
validation: value => value.includes('@'),
|
|
239
|
+
errorMessage: 'Please enter a valid email',
|
|
240
|
+
})
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### BasicForm
|
|
244
|
+
|
|
245
|
+
Simple form container with validation and submission handling.
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
BasicForm({
|
|
249
|
+
onSubmit: data => {
|
|
250
|
+
console.log('Form submitted:', data)
|
|
251
|
+
},
|
|
252
|
+
children: [
|
|
253
|
+
BasicInput({ name: 'username', placeholder: 'Username' }),
|
|
254
|
+
BasicInput({ name: 'email', type: 'email', placeholder: 'Email' }),
|
|
255
|
+
Button('Submit', null), // null indicates form submission
|
|
256
|
+
],
|
|
257
|
+
})
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Usage Patterns
|
|
261
|
+
|
|
262
|
+
### Building Complex Layouts
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
VStack({
|
|
266
|
+
spacing: 20,
|
|
267
|
+
children: [
|
|
268
|
+
// Header
|
|
269
|
+
HStack({
|
|
270
|
+
alignment: 'center',
|
|
271
|
+
children: [
|
|
272
|
+
Image(Assets.logo).modifier.size({ width: 40, height: 40 }).build(),
|
|
273
|
+
Text('My App').modifier.font({ size: 24, weight: 'bold' }).build(),
|
|
274
|
+
Spacer(),
|
|
275
|
+
Button('Menu', toggleMenu),
|
|
276
|
+
],
|
|
277
|
+
}),
|
|
278
|
+
|
|
279
|
+
// Content
|
|
280
|
+
VStack({
|
|
281
|
+
spacing: 16,
|
|
282
|
+
children: [
|
|
283
|
+
Text('Welcome to tachUI!')
|
|
284
|
+
.modifier.font({ size: 18 })
|
|
285
|
+
.textAlign('center')
|
|
286
|
+
.build(),
|
|
287
|
+
|
|
288
|
+
Divider(),
|
|
289
|
+
|
|
290
|
+
HStack({
|
|
291
|
+
spacing: 12,
|
|
292
|
+
children: [
|
|
293
|
+
Button('Get Started', startOnboarding),
|
|
294
|
+
Button('Learn More', openDocs)
|
|
295
|
+
.modifier.backgroundColor('transparent')
|
|
296
|
+
.foregroundColor('#007AFF')
|
|
297
|
+
.build(),
|
|
298
|
+
],
|
|
299
|
+
}),
|
|
300
|
+
],
|
|
301
|
+
}),
|
|
302
|
+
],
|
|
303
|
+
})
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Responsive Design
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
VStack({
|
|
310
|
+
children: items.map(item =>
|
|
311
|
+
HStack({
|
|
312
|
+
spacing: { mobile: 8, desktop: 16 },
|
|
313
|
+
children: [
|
|
314
|
+
Image(item.image)
|
|
315
|
+
.modifier.size({ mobile: 40, desktop: 60 })
|
|
316
|
+
.cornerRadius({ mobile: 4, desktop: 8 })
|
|
317
|
+
.build(),
|
|
318
|
+
|
|
319
|
+
VStack({
|
|
320
|
+
alignment: 'leading',
|
|
321
|
+
children: [
|
|
322
|
+
Text(item.title)
|
|
323
|
+
.modifier.font({ size: { mobile: 16, desktop: 18 } })
|
|
324
|
+
.build(),
|
|
325
|
+
|
|
326
|
+
Text(item.description)
|
|
327
|
+
.modifier.font({ size: { mobile: 14, desktop: 16 } })
|
|
328
|
+
.opacity(0.7)
|
|
329
|
+
.build(),
|
|
330
|
+
],
|
|
331
|
+
}),
|
|
332
|
+
],
|
|
333
|
+
})
|
|
334
|
+
),
|
|
335
|
+
})
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Accessibility Features
|
|
339
|
+
|
|
340
|
+
All primitive components include comprehensive accessibility support:
|
|
341
|
+
|
|
342
|
+
- **ARIA Labels**: Automatic and customizable ARIA attributes
|
|
343
|
+
- **Keyboard Navigation**: Full keyboard support for interactive elements
|
|
344
|
+
- **Screen Reader Support**: Optimized for screen reader compatibility
|
|
345
|
+
- **Focus Management**: Proper focus handling and visual indicators
|
|
346
|
+
- **High Contrast**: Support for high contrast modes
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
Button('Accessible Button', handleClick)
|
|
350
|
+
.modifier.accessibilityLabel('Save document')
|
|
351
|
+
.accessibilityRole('button')
|
|
352
|
+
.accessibilityHint('Saves the current document')
|
|
353
|
+
.build()
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Styling Integration
|
|
357
|
+
|
|
358
|
+
Primitives work seamlessly with the modifier system:
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
import { padding, margin, backgroundColor } from '@tachui/modifiers'
|
|
362
|
+
|
|
363
|
+
Text('Styled with modifiers')
|
|
364
|
+
.modifier.apply(padding(16))
|
|
365
|
+
.apply(margin({ vertical: 8 }))
|
|
366
|
+
.apply(backgroundColor('#F2F2F7'))
|
|
367
|
+
.build()
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Performance Characteristics
|
|
371
|
+
|
|
372
|
+
- **Minimal Bundle Size**: Tree-shakeable components
|
|
373
|
+
- **Efficient Rendering**: Fine-grained reactivity with minimal re-renders
|
|
374
|
+
- **Memory Efficient**: Automatic cleanup and memory management
|
|
375
|
+
- **GPU Accelerated**: CSS transforms and animations when possible
|
|
376
|
+
|
|
377
|
+
## Component Validation
|
|
378
|
+
|
|
379
|
+
Built-in validation ensures proper component usage:
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
// Development warnings for common mistakes
|
|
383
|
+
VStack({
|
|
384
|
+
children: 'String', // ❌ Warning: children should be array
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
// Type-safe props
|
|
388
|
+
Text(123) // ❌ TypeScript error: content must be string or signal
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Integration with Other Packages
|
|
392
|
+
|
|
393
|
+
### With Flow Control
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { Show, ForEach } from '@tachui/flow-control'
|
|
397
|
+
|
|
398
|
+
VStack({
|
|
399
|
+
children: [
|
|
400
|
+
Show({
|
|
401
|
+
when: () => isLoading(),
|
|
402
|
+
children: Text('Loading...'),
|
|
403
|
+
}),
|
|
404
|
+
|
|
405
|
+
ForEach({
|
|
406
|
+
data: () => items(),
|
|
407
|
+
renderItem: item =>
|
|
408
|
+
HStack({
|
|
409
|
+
children: [
|
|
410
|
+
Text(item.name),
|
|
411
|
+
Spacer(),
|
|
412
|
+
Button('Edit', () => editItem(item)),
|
|
413
|
+
],
|
|
414
|
+
}),
|
|
415
|
+
}),
|
|
416
|
+
],
|
|
417
|
+
})
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### With Navigation
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
import { NavigationLink } from '@tachui/navigation'
|
|
424
|
+
|
|
425
|
+
VStack({
|
|
426
|
+
children: [
|
|
427
|
+
NavigationLink({
|
|
428
|
+
destination: '/profile',
|
|
429
|
+
children: HStack({
|
|
430
|
+
children: [
|
|
431
|
+
Image(userAvatar),
|
|
432
|
+
Text(userName),
|
|
433
|
+
Spacer(),
|
|
434
|
+
Text('>').modifier.opacity(0.5).build(),
|
|
435
|
+
],
|
|
436
|
+
}),
|
|
437
|
+
}),
|
|
438
|
+
],
|
|
439
|
+
})
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
## Best Practices
|
|
443
|
+
|
|
444
|
+
1. **Use Semantic Components**: Choose components based on meaning, not appearance
|
|
445
|
+
2. **Leverage the Stack System**: Use VStack, HStack, and ZStack for layouts instead of CSS
|
|
446
|
+
3. **Apply Modifiers Consistently**: Use the modifier chain for all styling
|
|
447
|
+
4. **Consider Accessibility**: Always provide appropriate labels and roles
|
|
448
|
+
5. **Optimize for Performance**: Use signals for reactive content, avoid object creation in renders
|
|
449
|
+
|
|
450
|
+
## Browser Support
|
|
451
|
+
|
|
452
|
+
- Modern browsers (Chrome 88+, Firefox 85+, Safari 14+, Edge 88+)
|
|
453
|
+
- Progressive enhancement for older browsers
|
|
454
|
+
- Graceful fallback for unsupported features
|
|
455
|
+
|
|
456
|
+
## License
|
|
457
|
+
|
|
458
|
+
This package is part of the tachUI framework and is licensed under the MPL-2.0 License.
|