bitwrench 2.0.22 → 2.0.23

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.
Files changed (88) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +4 -3
  3. package/bin/bwmcp.js +3 -0
  4. package/dist/bitwrench-bccl.cjs.js +1 -1
  5. package/dist/bitwrench-bccl.cjs.min.js +1 -1
  6. package/dist/bitwrench-bccl.cjs.min.js.gz +0 -0
  7. package/dist/bitwrench-bccl.esm.js +1 -1
  8. package/dist/bitwrench-bccl.esm.min.js +1 -1
  9. package/dist/bitwrench-bccl.esm.min.js.gz +0 -0
  10. package/dist/bitwrench-bccl.umd.js +1 -1
  11. package/dist/bitwrench-bccl.umd.min.js +1 -1
  12. package/dist/bitwrench-bccl.umd.min.js.gz +0 -0
  13. package/dist/bitwrench-code-edit.cjs.js +1 -1
  14. package/dist/bitwrench-code-edit.cjs.min.js +1 -1
  15. package/dist/bitwrench-code-edit.es5.js +1 -1
  16. package/dist/bitwrench-code-edit.es5.min.js +1 -1
  17. package/dist/bitwrench-code-edit.esm.js +1 -1
  18. package/dist/bitwrench-code-edit.esm.min.js +1 -1
  19. package/dist/bitwrench-code-edit.umd.js +1 -1
  20. package/dist/bitwrench-code-edit.umd.min.js +1 -1
  21. package/dist/bitwrench-code-edit.umd.min.js.gz +0 -0
  22. package/dist/bitwrench-debug.js +1 -1
  23. package/dist/bitwrench-debug.min.js +1 -1
  24. package/dist/bitwrench-lean.cjs.js +3 -3
  25. package/dist/bitwrench-lean.cjs.min.js +2 -2
  26. package/dist/bitwrench-lean.cjs.min.js.gz +0 -0
  27. package/dist/bitwrench-lean.es5.js +3 -3
  28. package/dist/bitwrench-lean.es5.min.js +2 -2
  29. package/dist/bitwrench-lean.es5.min.js.gz +0 -0
  30. package/dist/bitwrench-lean.esm.js +3 -3
  31. package/dist/bitwrench-lean.esm.min.js +2 -2
  32. package/dist/bitwrench-lean.esm.min.js.gz +0 -0
  33. package/dist/bitwrench-lean.umd.js +3 -3
  34. package/dist/bitwrench-lean.umd.min.js +2 -2
  35. package/dist/bitwrench-lean.umd.min.js.gz +0 -0
  36. package/dist/bitwrench-util-css.cjs.js +1 -1
  37. package/dist/bitwrench-util-css.cjs.min.js +1 -1
  38. package/dist/bitwrench-util-css.es5.js +1 -1
  39. package/dist/bitwrench-util-css.es5.min.js +1 -1
  40. package/dist/bitwrench-util-css.esm.js +1 -1
  41. package/dist/bitwrench-util-css.esm.min.js +1 -1
  42. package/dist/bitwrench-util-css.umd.js +1 -1
  43. package/dist/bitwrench-util-css.umd.min.js +1 -1
  44. package/dist/bitwrench-util-css.umd.min.js.gz +0 -0
  45. package/dist/bitwrench.cjs.js +3 -3
  46. package/dist/bitwrench.cjs.min.js +2 -2
  47. package/dist/bitwrench.cjs.min.js.gz +0 -0
  48. package/dist/bitwrench.css +1 -1
  49. package/dist/bitwrench.es5.js +3 -3
  50. package/dist/bitwrench.es5.min.js +2 -2
  51. package/dist/bitwrench.es5.min.js.gz +0 -0
  52. package/dist/bitwrench.esm.js +3 -3
  53. package/dist/bitwrench.esm.min.js +2 -2
  54. package/dist/bitwrench.esm.min.js.gz +0 -0
  55. package/dist/bitwrench.umd.js +3 -3
  56. package/dist/bitwrench.umd.min.js +2 -2
  57. package/dist/bitwrench.umd.min.js.gz +0 -0
  58. package/dist/builds.json +57 -57
  59. package/dist/bwserve.cjs.js +2 -2
  60. package/dist/bwserve.esm.js +2 -2
  61. package/dist/sri.json +45 -45
  62. package/docs/README.md +76 -0
  63. package/docs/app-patterns.md +264 -0
  64. package/docs/bitwrench-mcp.md +426 -0
  65. package/docs/bitwrench_api.md +2232 -0
  66. package/docs/bw-attach.md +399 -0
  67. package/docs/bwserve.md +841 -0
  68. package/docs/cli.md +307 -0
  69. package/docs/component-cheatsheet.md +144 -0
  70. package/docs/component-library.md +1099 -0
  71. package/docs/framework-translation-table.md +33 -0
  72. package/docs/llm-bitwrench-guide.md +672 -0
  73. package/docs/routing.md +562 -0
  74. package/docs/state-management.md +767 -0
  75. package/docs/taco-format.md +373 -0
  76. package/docs/theming.md +309 -0
  77. package/docs/thinking-in-bitwrench.md +1457 -0
  78. package/docs/tutorial-bwserve.md +297 -0
  79. package/docs/tutorial-embedded.md +314 -0
  80. package/docs/tutorial-website.md +255 -0
  81. package/package.json +11 -3
  82. package/readme.html +5 -4
  83. package/src/mcp/knowledge.js +231 -0
  84. package/src/mcp/live.js +226 -0
  85. package/src/mcp/server.js +216 -0
  86. package/src/mcp/tools.js +369 -0
  87. package/src/mcp/transport.js +55 -0
  88. package/src/version.js +3 -3
@@ -0,0 +1,1099 @@
1
+ # Component Library
2
+
3
+ Bitwrench ships over 50 `make*()` factory functions. Each takes a props object and returns a TACO -- a plain JavaScript object that describes UI. No DOM elements are created until you pass the result to `bw.DOM()` or `bw.html()`.
4
+
5
+ > For a quick scannable reference, see [Component Cheat Sheet](component-cheatsheet.md).
6
+
7
+ ```javascript
8
+ // Every factory works the same way
9
+ var card = bw.makeCard({ title: 'Hello', content: 'World' });
10
+
11
+ // The result is a plain object — not a DOM element
12
+ typeof card; // 'object'
13
+ card.t; // 'div'
14
+
15
+ // Render it however you want
16
+ bw.DOM('#app', card); // mount to DOM
17
+ var html = bw.html(card); // or get HTML string
18
+ ```
19
+
20
+ > **Coming from React?** Each `make*()` function is like a React component that returns JSX — except it returns a plain object instead of a virtual DOM node, and there is no build step.
21
+
22
+ > **Coming from Bootstrap?** The factory functions replace Bootstrap's HTML class conventions. Instead of memorizing `<div class="card"><div class="card-body">...`, you write `bw.makeCard({ title, content })` and the correct markup is generated for you.
23
+
24
+ ## Quick Reference
25
+
26
+ | Category | Components |
27
+ |----------|-----------|
28
+ | [Layout](#layout) | makeContainer, makeRow, makeCol, makeStack |
29
+ | [Content](#content) | makeCard\*, makeAlert, makeBadge, makeProgress\*, makeStatCard\*, makeMediaObject, makeTimeline, makeStepper, makeListGroup, makeAvatar, makeSkeleton, makeSpinner |
30
+ | [Navigation](#navigation) | makeNav, makeNavbar, makeTabs\*, makeBreadcrumb, makePagination |
31
+ | [Buttons](#buttons) | makeButton, makeButtonGroup |
32
+ | [Forms](#forms) | makeForm, makeFormGroup, makeInput, makeTextarea, makeSelect, makeCheckbox, makeRadio, makeSwitch, makeRange, makeSearchInput, makeChipInput\*, makeFileUpload |
33
+ | [Interactive](#interactive) | makeAccordion\*, makeModal\*, makeToast\*, makeDropdown, makeCarousel\* |
34
+ | [Overlays](#overlays) | makeTooltip, makePopover |
35
+ | [Loading & Placeholder](#loading--placeholder) | makeSpinner, makeSkeleton, makeAvatar |
36
+ | [Page-Level](#page-level-components) | makeHero, makeSection, makeFeatureGrid, makeCTA, makeCodeDemo |
37
+ | [Tables & Data](#tables--data) | makeTable, makeTableFromArray, makeDataTable, makeBarChart |
38
+
39
+ \*Has imperative handles (`el.bw` methods) -- see [Component Handles](#component-handles)
40
+
41
+ ---
42
+
43
+ ## Layout
44
+
45
+ ### makeContainer
46
+
47
+ Centered page container.
48
+
49
+ ```javascript
50
+ bw.makeContainer({
51
+ fluid: false, // true = full width, false = max-width centered
52
+ children: [...], // content (TACO or array of TACOs)
53
+ className: ''
54
+ })
55
+ ```
56
+
57
+ ### makeRow
58
+
59
+ Flexbox row for grid layouts.
60
+
61
+ ```javascript
62
+ bw.makeRow({
63
+ children: [...], // array of makeCol() TACOs
64
+ gap: 3, // gap size (1-5)
65
+ className: ''
66
+ })
67
+ ```
68
+
69
+ ### makeCol
70
+
71
+ Responsive grid column.
72
+
73
+ ```javascript
74
+ bw.makeCol({
75
+ size: 6, // fixed: 1-12
76
+ // or responsive:
77
+ size: { xs: 12, sm: 6, md: 4, lg: 3 },
78
+ offset: 0, // column offset (1-12)
79
+ content: 'Text or TACO', // alias for children
80
+ children: [...],
81
+ className: ''
82
+ })
83
+ ```
84
+
85
+ ### makeStack
86
+
87
+ Flexbox stack (vertical or horizontal).
88
+
89
+ ```javascript
90
+ bw.makeStack({
91
+ children: [...],
92
+ direction: 'vertical', // 'vertical' or 'horizontal'
93
+ gap: 3, // gap size (1-8)
94
+ className: ''
95
+ })
96
+ ```
97
+
98
+ **Grid example:**
99
+
100
+ ```javascript
101
+ bw.DOM('#app', bw.makeContainer({
102
+ children: bw.makeRow({ gap: 4, children: [
103
+ bw.makeCol({ size: { md: 4 }, children: bw.makeCard({ title: 'One' }) }),
104
+ bw.makeCol({ size: { md: 4 }, children: bw.makeCard({ title: 'Two' }) }),
105
+ bw.makeCol({ size: { md: 4 }, children: bw.makeCard({ title: 'Three' }) })
106
+ ]})
107
+ }));
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Content
113
+
114
+ ### makeCard
115
+
116
+ Content card with optional header, footer, image, and variants.
117
+
118
+ ```javascript
119
+ bw.makeCard({
120
+ title: 'Title',
121
+ subtitle: 'Subtitle',
122
+ content: 'Body text or TACO',
123
+ footer: 'Footer text',
124
+ header: 'Header text',
125
+ image: { src: 'photo.jpg', alt: 'Description' },
126
+ imagePosition: 'top', // 'top' | 'bottom' | 'left' | 'right'
127
+ variant: 'primary', // color variant
128
+ bordered: true,
129
+ shadow: 'md', // 'none' | 'sm' | 'md' | 'lg'
130
+ hoverable: false, // add hover shadow effect
131
+ className: '',
132
+ style: ''
133
+ })
134
+ ```
135
+
136
+ ### makeAlert
137
+
138
+ Dismissible notification banner.
139
+
140
+ ```javascript
141
+ bw.makeAlert({
142
+ title: 'Warning', // optional bold title
143
+ content: 'Check your input.',
144
+ variant: 'warning', // 'info' | 'success' | 'warning' | 'danger'
145
+ dismissible: true, // show close button
146
+ className: ''
147
+ })
148
+ ```
149
+
150
+ ### makeBadge
151
+
152
+ Small status indicator.
153
+
154
+ ```javascript
155
+ bw.makeBadge({
156
+ text: 'New',
157
+ variant: 'primary',
158
+ pill: false, // rounded pill shape
159
+ className: ''
160
+ })
161
+ ```
162
+
163
+ ### makeProgress
164
+
165
+ Progress bar with optional animation.
166
+
167
+ ```javascript
168
+ bw.makeProgress({
169
+ value: 65,
170
+ max: 100,
171
+ variant: 'primary',
172
+ striped: false,
173
+ animated: false,
174
+ label: '65%', // text inside the bar
175
+ height: '' // custom height
176
+ })
177
+ ```
178
+
179
+ ### makeStatCard
180
+
181
+ Statistic display with change indicator.
182
+
183
+ ```javascript
184
+ bw.makeStatCard({
185
+ value: 1234,
186
+ label: 'Active Users',
187
+ change: 12.5, // positive = green arrow up, negative = red arrow down
188
+ format: 'number', // 'number' | 'currency' | 'percent'
189
+ prefix: '', // e.g. '$'
190
+ suffix: '', // e.g. '%'
191
+ icon: '',
192
+ variant: '',
193
+ className: '',
194
+ style: ''
195
+ })
196
+
197
+ // String shorthand:
198
+ bw.makeStatCard('Active Users') // creates card with label only
199
+ ```
200
+
201
+ ### makeMediaObject
202
+
203
+ Image and text side-by-side.
204
+
205
+ ```javascript
206
+ bw.makeMediaObject({
207
+ src: 'avatar.jpg',
208
+ alt: '',
209
+ title: 'User Name',
210
+ content: 'Description text',
211
+ reverse: false, // image on right instead of left
212
+ imageSize: '3rem',
213
+ className: ''
214
+ })
215
+ ```
216
+
217
+ ### makeTimeline
218
+
219
+ Vertical timeline with event markers.
220
+
221
+ ```javascript
222
+ bw.makeTimeline({
223
+ items: [
224
+ { title: 'Event 1', content: 'Details...', date: '2026-01-15', variant: 'success' },
225
+ { title: 'Event 2', content: 'Details...', date: '2026-02-01', variant: 'info' }
226
+ ],
227
+ className: ''
228
+ })
229
+ ```
230
+
231
+ ### makeStepper
232
+
233
+ Multi-step wizard indicator.
234
+
235
+ ```javascript
236
+ bw.makeStepper({
237
+ steps: ['Account', 'Profile', 'Review', 'Confirm'],
238
+ currentStep: 1, // 0-indexed; completed steps show checkmarks
239
+ className: ''
240
+ })
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Navigation
246
+
247
+ ### makeNav
248
+
249
+ Tab or pill navigation.
250
+
251
+ ```javascript
252
+ bw.makeNav({
253
+ items: [
254
+ { text: 'Home', href: '#', active: true },
255
+ { text: 'About', href: '#' },
256
+ { text: 'Contact', href: '#', disabled: true }
257
+ ],
258
+ pills: false, // pill style instead of tabs
259
+ vertical: false,
260
+ className: ''
261
+ })
262
+ ```
263
+
264
+ ### makeNavbar
265
+
266
+ Responsive navigation bar with brand and collapsible menu.
267
+
268
+ ```javascript
269
+ bw.makeNavbar({
270
+ brand: 'My App',
271
+ brandHref: '#',
272
+ items: [
273
+ { text: 'Home', href: '#', active: true },
274
+ { text: 'Docs', href: '#' }
275
+ ],
276
+ dark: true, // dark background
277
+ className: ''
278
+ })
279
+ ```
280
+
281
+ ### makeTabs (handles: setActiveTab/getActiveTab, keyboard nav, WAI-ARIA)
282
+
283
+ Tabbed content panels with click switching.
284
+
285
+ ```javascript
286
+ bw.makeTabs({
287
+ tabs: [
288
+ { label: 'Tab 1', content: 'Panel 1 content' },
289
+ { label: 'Tab 2', content: { t: 'div', c: 'Panel 2 TACO' } },
290
+ { label: 'Tab 3', content: 'Panel 3 content' }
291
+ ],
292
+ activeIndex: 0
293
+ })
294
+ ```
295
+
296
+ ### makeBreadcrumb
297
+
298
+ Navigation breadcrumb trail.
299
+
300
+ ```javascript
301
+ bw.makeBreadcrumb({
302
+ items: [
303
+ { text: 'Home', href: '#' },
304
+ { text: 'Products', href: '#' },
305
+ { text: 'Widget', active: true } // active = no link
306
+ ]
307
+ })
308
+ ```
309
+
310
+ ### makePagination
311
+
312
+ Page navigation control.
313
+
314
+ ```javascript
315
+ bw.makePagination({
316
+ pages: 10,
317
+ currentPage: 3,
318
+ onPageChange: function(page) { /* load page data */ },
319
+ size: '', // 'sm' or 'lg'
320
+ className: ''
321
+ })
322
+ ```
323
+
324
+ ---
325
+
326
+ ## Buttons
327
+
328
+ ### makeButton
329
+
330
+ Standard button with variants.
331
+
332
+ ```javascript
333
+ bw.makeButton({
334
+ text: 'Click Me',
335
+ variant: 'primary', // 'primary' | 'secondary' | 'success' | 'danger' |
336
+ // 'warning' | 'info' | 'light' | 'dark' |
337
+ // 'outline-primary' | 'outline-secondary' | ...
338
+ size: '', // 'sm' or 'lg'
339
+ disabled: false,
340
+ onclick: function() {},
341
+ type: 'button', // 'button' | 'submit' | 'reset'
342
+ className: '',
343
+ style: ''
344
+ })
345
+
346
+ // String shorthand:
347
+ bw.makeButton('OK') // primary button with text "OK"
348
+ ```
349
+
350
+ ### makeButtonGroup
351
+
352
+ Group of buttons with shared border-radius.
353
+
354
+ ```javascript
355
+ bw.makeButtonGroup({
356
+ children: [
357
+ bw.makeButton({ text: 'Left' }),
358
+ bw.makeButton({ text: 'Center' }),
359
+ bw.makeButton({ text: 'Right' })
360
+ ],
361
+ size: '', // 'sm' or 'lg'
362
+ vertical: false,
363
+ className: ''
364
+ })
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Forms
370
+
371
+ ### makeForm
372
+
373
+ Form wrapper with submit handler.
374
+
375
+ ```javascript
376
+ bw.makeForm({
377
+ children: [...], // form controls
378
+ onsubmit: function(e) { e.preventDefault(); },
379
+ className: ''
380
+ })
381
+ ```
382
+
383
+ ### makeFormGroup
384
+
385
+ Label + input + help text wrapper.
386
+
387
+ ```javascript
388
+ bw.makeFormGroup({
389
+ label: 'Email',
390
+ help: 'We will not share your email.',
391
+ error: '', // error message (shows red)
392
+ required: false,
393
+ className: ''
394
+ })
395
+ ```
396
+
397
+ ### makeInput
398
+
399
+ Text input (supports all HTML5 types).
400
+
401
+ ```javascript
402
+ bw.makeInput({
403
+ type: 'text', // 'text' | 'email' | 'password' | 'number' | 'url' | ...
404
+ placeholder: '',
405
+ value: '',
406
+ id: '',
407
+ name: '',
408
+ disabled: false,
409
+ readonly: false,
410
+ required: false,
411
+ className: '',
412
+ style: '',
413
+ oninput: function(e) {},
414
+ onchange: function(e) {},
415
+ onfocus: function(e) {},
416
+ onblur: function(e) {}
417
+ })
418
+ ```
419
+
420
+ ### makeTextarea
421
+
422
+ Multi-line text input.
423
+
424
+ ```javascript
425
+ bw.makeTextarea({
426
+ placeholder: '',
427
+ value: '',
428
+ rows: 3,
429
+ id: '',
430
+ name: '',
431
+ disabled: false,
432
+ readonly: false,
433
+ required: false,
434
+ className: ''
435
+ })
436
+ ```
437
+
438
+ ### makeSelect
439
+
440
+ Dropdown select.
441
+
442
+ ```javascript
443
+ bw.makeSelect({
444
+ options: [
445
+ { value: 'us', text: 'United States' },
446
+ { value: 'uk', text: 'United Kingdom' },
447
+ { value: 'ca', text: 'Canada' }
448
+ ],
449
+ value: 'us', // pre-selected value
450
+ id: '',
451
+ name: '',
452
+ disabled: false,
453
+ required: false,
454
+ className: '',
455
+ onchange: function(e) {}
456
+ })
457
+ ```
458
+
459
+ ### makeCheckbox
460
+
461
+ Checkbox with label.
462
+
463
+ ```javascript
464
+ bw.makeCheckbox({
465
+ label: 'I agree to the terms',
466
+ checked: false,
467
+ id: '',
468
+ name: '',
469
+ disabled: false,
470
+ value: '',
471
+ className: ''
472
+ })
473
+ ```
474
+
475
+ ### makeRadio
476
+
477
+ Radio button.
478
+
479
+ ```javascript
480
+ bw.makeRadio({
481
+ label: 'Option A',
482
+ name: 'choice', // group name
483
+ value: 'a',
484
+ checked: false,
485
+ id: '',
486
+ disabled: false,
487
+ className: ''
488
+ })
489
+ ```
490
+
491
+ ### makeSwitch
492
+
493
+ Toggle switch (styled checkbox).
494
+
495
+ ```javascript
496
+ bw.makeSwitch({
497
+ label: 'Enable notifications',
498
+ checked: false,
499
+ id: '',
500
+ name: '',
501
+ disabled: false,
502
+ className: ''
503
+ })
504
+ ```
505
+
506
+ ### makeRange
507
+
508
+ Range slider.
509
+
510
+ ```javascript
511
+ bw.makeRange({
512
+ min: 0,
513
+ max: 100,
514
+ step: 1,
515
+ value: 50,
516
+ label: 'Volume',
517
+ showValue: false, // show current value next to slider
518
+ id: '',
519
+ name: '',
520
+ disabled: false,
521
+ className: ''
522
+ })
523
+ ```
524
+
525
+ ### makeSearchInput
526
+
527
+ Search box with clear button.
528
+
529
+ ```javascript
530
+ bw.makeSearchInput({
531
+ placeholder: 'Search...',
532
+ value: '',
533
+ onSearch: function(query) {}, // called on Enter
534
+ onInput: function(e) {}, // called on each keystroke
535
+ id: '',
536
+ name: '',
537
+ className: ''
538
+ })
539
+
540
+ // String shorthand:
541
+ bw.makeSearchInput('Search products...')
542
+ ```
543
+
544
+ ### makeChipInput
545
+
546
+ Tag/chip input with add/remove.
547
+
548
+ ```javascript
549
+ bw.makeChipInput({
550
+ chips: ['JavaScript', 'CSS'],
551
+ placeholder: 'Add tag...',
552
+ onAdd: function(text) {},
553
+ onRemove: function(text) {},
554
+ className: ''
555
+ })
556
+ ```
557
+
558
+ ### makeFileUpload
559
+
560
+ Drag-and-drop file upload zone.
561
+
562
+ ```javascript
563
+ bw.makeFileUpload({
564
+ accept: '.pdf,.doc', // file type filter
565
+ multiple: false,
566
+ onFiles: function(files) {},
567
+ text: 'Drop files here or click to browse',
568
+ id: '',
569
+ className: ''
570
+ })
571
+ ```
572
+
573
+ ---
574
+
575
+ ## Interactive
576
+
577
+ ### makeAccordion (handles: toggle/openAll/closeAll, ARIA)
578
+
579
+ Collapsible content sections.
580
+
581
+ ```javascript
582
+ bw.makeAccordion({
583
+ items: [
584
+ { title: 'Section 1', content: 'Content here...', open: true },
585
+ { title: 'Section 2', content: 'More content...' },
586
+ { title: 'Section 3', content: { t: 'div', c: 'TACO content' } }
587
+ ],
588
+ multiOpen: false, // allow multiple sections open at once
589
+ className: ''
590
+ })
591
+ ```
592
+
593
+ ### makeModal (handles: open/close, ESC dismiss)
594
+
595
+ Dialog overlay.
596
+
597
+ ```javascript
598
+ bw.makeModal({
599
+ title: 'Confirm Action',
600
+ content: 'Are you sure?',
601
+ footer: bw.makeButtonGroup({ children: [
602
+ bw.makeButton({ text: 'Cancel', variant: 'secondary' }),
603
+ bw.makeButton({ text: 'Confirm', variant: 'danger' })
604
+ ]}),
605
+ size: '', // 'sm' | 'lg' | 'xl'
606
+ closeButton: true, // show X in header
607
+ onClose: function() {},
608
+ className: ''
609
+ })
610
+ ```
611
+
612
+ ### makeToast (handle: dismiss, auto-dismiss 5s)
613
+
614
+ Toast notification.
615
+
616
+ ```javascript
617
+ bw.makeToast({
618
+ title: 'Success',
619
+ content: 'Your file was saved.',
620
+ variant: 'success',
621
+ autoDismiss: true,
622
+ delay: 5000, // ms before auto-dismiss
623
+ position: 'top-right', // 'top-left' | 'top-center' | 'top-right' |
624
+ // 'bottom-left' | 'bottom-center' | 'bottom-right'
625
+ className: ''
626
+ })
627
+ ```
628
+
629
+ ### makeDropdown
630
+
631
+ Click-triggered dropdown menu.
632
+
633
+ ```javascript
634
+ bw.makeDropdown({
635
+ trigger: 'Actions', // string or button TACO
636
+ items: [
637
+ { text: 'Edit', onclick: function() {} },
638
+ { text: 'Duplicate', onclick: function() {} },
639
+ { divider: true },
640
+ { text: 'Delete', onclick: function() {}, disabled: false }
641
+ ],
642
+ align: 'start', // 'start' | 'end'
643
+ variant: 'primary',
644
+ className: ''
645
+ })
646
+ ```
647
+
648
+ ### makeCarousel (handles: 6 methods, auto-play, keyboard)
649
+
650
+ Image carousel with controls and indicators.
651
+
652
+ ```javascript
653
+ bw.makeCarousel({
654
+ items: [
655
+ { src: 'slide1.jpg', alt: 'Slide 1', caption: 'First slide' },
656
+ { src: 'slide2.jpg', alt: 'Slide 2', caption: 'Second slide' }
657
+ ],
658
+ showControls: true,
659
+ showIndicators: true,
660
+ autoPlay: false,
661
+ interval: 5000, // ms between auto-advance
662
+ height: '300px',
663
+ startIndex: 0,
664
+ className: ''
665
+ })
666
+ ```
667
+
668
+ ---
669
+
670
+ ## Overlays
671
+
672
+ ### makeTooltip
673
+
674
+ Hover/focus tooltip.
675
+
676
+ ```javascript
677
+ bw.makeTooltip({
678
+ content: bw.makeButton({ text: 'Hover me' }), // the trigger element
679
+ text: 'Tooltip text',
680
+ placement: 'top', // 'top' | 'bottom' | 'left' | 'right'
681
+ className: ''
682
+ })
683
+ ```
684
+
685
+ ### makePopover
686
+
687
+ Click-triggered rich popover.
688
+
689
+ ```javascript
690
+ bw.makePopover({
691
+ trigger: bw.makeButton({ text: 'Info' }),
692
+ title: 'Details',
693
+ content: 'Extended information here...',
694
+ placement: 'top', // 'top' | 'bottom' | 'left' | 'right'
695
+ className: ''
696
+ })
697
+ ```
698
+
699
+ ---
700
+
701
+ ## Loading & Placeholder
702
+
703
+ ### makeSpinner
704
+
705
+ Loading spinner.
706
+
707
+ ```javascript
708
+ bw.makeSpinner({
709
+ variant: 'primary',
710
+ size: 'md', // 'sm' | 'md' | 'lg'
711
+ type: 'border' // 'border' | 'grow'
712
+ })
713
+ ```
714
+
715
+ ### makeSkeleton
716
+
717
+ Content placeholder (loading state).
718
+
719
+ ```javascript
720
+ bw.makeSkeleton({
721
+ variant: 'text', // 'text' | 'circle' | 'rect'
722
+ width: '',
723
+ height: '',
724
+ count: 1, // number of text lines
725
+ className: ''
726
+ })
727
+ ```
728
+
729
+ ### makeAvatar
730
+
731
+ User avatar (image or initials).
732
+
733
+ ```javascript
734
+ bw.makeAvatar({
735
+ src: 'photo.jpg', // image URL
736
+ alt: '',
737
+ initials: 'AC', // fallback when no src
738
+ size: 'md', // 'sm' | 'md' | 'lg' | 'xl'
739
+ variant: 'primary', // background color for initials
740
+ className: ''
741
+ })
742
+ ```
743
+
744
+ ---
745
+
746
+ ## Page-Level Components
747
+
748
+ ### makeHero
749
+
750
+ Hero section with optional background image.
751
+
752
+ ```javascript
753
+ bw.makeHero({
754
+ title: 'Welcome',
755
+ subtitle: 'Build fast, ship faster.',
756
+ content: '', // additional TACO content
757
+ variant: 'primary', // background color
758
+ size: 'lg', // 'sm' | 'md' | 'lg' | 'xl'
759
+ centered: true,
760
+ backgroundImage: '', // URL for bg image
761
+ overlay: false, // dark overlay for text readability
762
+ actions: [ // array of button TACOs
763
+ bw.makeButton({ text: 'Get Started', variant: 'light', size: 'lg' })
764
+ ],
765
+ className: ''
766
+ })
767
+ ```
768
+
769
+ ### makeSection
770
+
771
+ Semantic content section.
772
+
773
+ ```javascript
774
+ bw.makeSection({
775
+ title: 'Features',
776
+ subtitle: 'What we offer',
777
+ content: 'Text or TACO',
778
+ variant: 'default',
779
+ spacing: 'md', // vertical padding
780
+ className: ''
781
+ })
782
+ ```
783
+
784
+ ### makeFeatureGrid
785
+
786
+ Grid of feature cards with icons.
787
+
788
+ ```javascript
789
+ bw.makeFeatureGrid({
790
+ features: [
791
+ { icon: '⚡', title: 'Fast', description: 'Sub-second rendering' },
792
+ { icon: '📦', title: 'Small', description: 'Zero dependencies' },
793
+ { icon: '🔧', title: 'Flexible', description: 'Works everywhere' }
794
+ ],
795
+ columns: 3,
796
+ centered: true,
797
+ iconSize: '3rem',
798
+ className: ''
799
+ })
800
+ ```
801
+
802
+ ### makeCTA
803
+
804
+ Call-to-action section.
805
+
806
+ ```javascript
807
+ bw.makeCTA({
808
+ title: 'Ready to get started?',
809
+ description: 'Join thousands of developers.',
810
+ actions: [
811
+ bw.makeButton({ text: 'Sign Up Free', variant: 'primary', size: 'lg' })
812
+ ],
813
+ variant: 'light',
814
+ centered: true,
815
+ className: ''
816
+ })
817
+ ```
818
+
819
+ ### makeCodeDemo
820
+
821
+ Code example with preview.
822
+
823
+ ```javascript
824
+ bw.makeCodeDemo({
825
+ title: 'Button Example',
826
+ description: 'A simple button.',
827
+ code: 'bw.makeButton({ text: "Click" })',
828
+ result: bw.makeButton({ text: 'Click' }),
829
+ language: 'javascript'
830
+ })
831
+ ```
832
+
833
+ ---
834
+
835
+ ## Tables & Data
836
+
837
+ ### makeTable (sortable, pagination, row selection, column renderers)
838
+
839
+ Sortable data table from an array of objects. Supports row selection, custom cell rendering, and pagination.
840
+
841
+ ```javascript
842
+ bw.makeTable({
843
+ data: [
844
+ { name: 'Alice', age: 30, role: 'Engineer' },
845
+ { name: 'Bob', age: 25, role: 'Designer' }
846
+ ],
847
+ columns: [ // optional — auto-detected from data keys
848
+ { key: 'name', label: 'Name' },
849
+ { key: 'age', label: 'Age' },
850
+ { key: 'role', label: 'Role' }
851
+ ],
852
+ sortable: true, // click column headers to sort
853
+ striped: false,
854
+ hover: false,
855
+ selectable: false, // click rows to toggle selection
856
+ onRowClick: null, // function(row, index, event) — fires on row click
857
+ pageSize: undefined, // set to enable pagination (e.g. 10)
858
+ currentPage: 1, // current page (1-based)
859
+ onPageChange: null, // function(newPage) — fires on page navigation
860
+ className: ''
861
+ })
862
+ ```
863
+
864
+ **Cell renderers** — each column definition can include a `render` function for custom cell rendering. The function receives the cell value and the full row object, and can return a string or TACO:
865
+
866
+ ```javascript
867
+ bw.makeTable({
868
+ data: users,
869
+ columns: [
870
+ { key: 'name', label: 'Name' },
871
+ { key: 'status', label: 'Status', render: function(val, row) {
872
+ return bw.makeBadge({ text: val, variant: val === 'active' ? 'success' : 'danger' });
873
+ }},
874
+ { key: 'age', label: 'Age', render: function(val) {
875
+ return val >= 18 ? String(val) : bw.raw('<em>' + val + '</em>');
876
+ }}
877
+ ]
878
+ })
879
+ ```
880
+
881
+ **Row selection** — enables click-to-select with visual feedback:
882
+
883
+ ```javascript
884
+ bw.makeTable({
885
+ data: users,
886
+ selectable: true,
887
+ onRowClick: function(row, index, event) {
888
+ console.log('Selected:', row.name, 'at index', index);
889
+ }
890
+ })
891
+ ```
892
+
893
+ Clicking a row toggles the `bw_table_row_selected` CSS class. The `selectable` flag also enables hover highlighting automatically.
894
+
895
+ **Pagination** — set `pageSize` to limit visible rows:
896
+
897
+ ```javascript
898
+ var page = 1;
899
+ function renderTable() {
900
+ bw.DOM('#table', bw.makeTable({
901
+ data: allData, // full dataset — makeTable slices internally
902
+ pageSize: 10,
903
+ currentPage: page,
904
+ onPageChange: function(newPage) {
905
+ page = newPage;
906
+ renderTable(); // re-render with new page
907
+ }
908
+ }));
909
+ }
910
+ renderTable();
911
+ ```
912
+
913
+ When `pageSize` is set, the table is wrapped in a container with Prev/Next controls and a page indicator. The `onRowClick` index is the global index into the full dataset, not the page-local index.
914
+
915
+ ### makeTableFromArray
916
+
917
+ Table from 2D arrays (CSV data, spreadsheets).
918
+
919
+ ```javascript
920
+ bw.makeTableFromArray({
921
+ data: [
922
+ ['Name', 'Age', 'Role'], // first row = headers
923
+ ['Alice', 30, 'Engineer'],
924
+ ['Bob', 25, 'Designer']
925
+ ],
926
+ headerRow: true, // default true; false = auto-generate col0, col1, ...
927
+ striped: true,
928
+ hover: true,
929
+ sortable: true
930
+ })
931
+ ```
932
+
933
+ ### makeDataTable
934
+
935
+ Convenience wrapper with title and responsive scrolling.
936
+
937
+ ```javascript
938
+ bw.makeDataTable({
939
+ title: 'Team Members',
940
+ data: [...],
941
+ columns: [...],
942
+ responsive: true, // wraps in scrollable div
943
+ striped: true,
944
+ hover: true
945
+ })
946
+ ```
947
+
948
+ ### makeBarChart
949
+
950
+ Vertical bar chart (pure CSS, no external library).
951
+
952
+ ```javascript
953
+ bw.makeBarChart({
954
+ data: [
955
+ { label: 'Jan', value: 4200 },
956
+ { label: 'Feb', value: 5100 },
957
+ { label: 'Mar', value: 3800 }
958
+ ],
959
+ labelKey: 'label',
960
+ valueKey: 'value',
961
+ title: 'Monthly Revenue',
962
+ color: '#006666',
963
+ height: '200px',
964
+ formatValue: function(v) { return '$' + (v/1000).toFixed(1) + 'k'; },
965
+ showValues: true,
966
+ showLabels: true,
967
+ className: ''
968
+ })
969
+ ```
970
+
971
+ ---
972
+
973
+ ## Factory dispatcher
974
+
975
+ The `bw.make()` function dispatches to any factory by type name:
976
+
977
+ ```javascript
978
+ bw.make('card', { title: 'Hello' });
979
+ // equivalent to: bw.makeCard({ title: 'Hello' })
980
+
981
+ bw.make('button', { text: 'OK', variant: 'primary' });
982
+ // equivalent to: bw.makeButton({ text: 'OK', variant: 'primary' })
983
+ ```
984
+
985
+ This enables data-driven component creation:
986
+
987
+ ```javascript
988
+ var layout = [
989
+ { type: 'card', props: { title: 'Stats', content: '42' } },
990
+ { type: 'alert', props: { content: 'Warning!', variant: 'warning' } },
991
+ { type: 'button', props: { text: 'Action' } }
992
+ ];
993
+
994
+ bw.DOM('#app', {
995
+ t: 'div',
996
+ c: layout.map(function(item) { return bw.make(item.type, item.props); })
997
+ });
998
+ ```
999
+
1000
+ List available types with `Object.keys(bw.BCCL)`.
1001
+
1002
+ ---
1003
+
1004
+ ## Component Handles
1005
+
1006
+ All BCCL factories include `o.handle` and/or `o.slots`, giving every rendered component an imperative API via `el.bw`. Use `bw.mount()` instead of `bw.DOM()` to get the element back:
1007
+
1008
+ ```javascript
1009
+ var el = bw.mount('#app', bw.makeCarousel({ items: slides }));
1010
+ el.bw.goToSlide(2);
1011
+ el.bw.pause();
1012
+ ```
1013
+
1014
+ Slot-based factories auto-generate `el.bw.setName()` / `el.bw.getName()` pairs:
1015
+
1016
+ ```javascript
1017
+ var el = bw.mount('#app', bw.makeCard({ title: 'Hello', content: 'World' }));
1018
+ el.bw.setTitle('Updated');
1019
+ el.bw.setContent({ t: 'b', c: '42' }); // accepts TACO objects
1020
+ ```
1021
+
1022
+ ### Handle method reference
1023
+
1024
+ | Factory | Handle methods | Slot methods |
1025
+ |---------|---------------|-------------|
1026
+ | makeCarousel | goToSlide, next, prev, getActiveIndex, pause, play | -- |
1027
+ | makeTabs | setActiveTab, getActiveTab | -- |
1028
+ | makeAccordion | toggle, openAll, closeAll | -- |
1029
+ | makeModal | open, close | -- |
1030
+ | makeProgress | setValue, getValue | -- |
1031
+ | makeChipInput | addChip, removeChip, getChips, clear | -- |
1032
+ | makeCard | -- | setTitle/getTitle, setContent/getContent, setFooter/getFooter |
1033
+ | makeStatCard | -- | setValue/getValue, setLabel/getLabel |
1034
+
1035
+ Build your own with `o.handle` and `o.slots`:
1036
+
1037
+ ```javascript
1038
+ {
1039
+ t: 'div', c: [
1040
+ { t: 'h3', a: { class: 'title' }, c: 'Default' },
1041
+ { t: 'div', a: { class: 'body' }, c: 'Content' }
1042
+ ],
1043
+ o: {
1044
+ slots: { title: '.title', body: '.body' },
1045
+ handle: {
1046
+ reset: function(el) { el.bw.setTitle('Default'); el.bw.setBody('Content'); }
1047
+ }
1048
+ }
1049
+ }
1050
+ ```
1051
+
1052
+ See [State Management -- Level 1.5](state-management.md#level-15-component-handles) for the full guide.
1053
+
1054
+ ---
1055
+
1056
+ ## Color variants
1057
+
1058
+ Most components accept a `variant` prop. The available variants are:
1059
+
1060
+ | Variant | Description |
1061
+ |---------|-------------|
1062
+ | `primary` | Brand color (default for most components) |
1063
+ | `secondary` | Secondary accent |
1064
+ | `success` | Positive action or status |
1065
+ | `danger` | Destructive action or error |
1066
+ | `warning` | Caution or attention needed |
1067
+ | `info` | Informational |
1068
+ | `light` | Light background |
1069
+ | `dark` | Dark background |
1070
+
1071
+ Buttons also support outline variants: `outline-primary`, `outline-secondary`, etc.
1072
+
1073
+ ## Composition
1074
+
1075
+ Because every factory returns a TACO object, you compose components with standard JavaScript:
1076
+
1077
+ ```javascript
1078
+ // Functions as component factories
1079
+ function userRow(user) {
1080
+ return {
1081
+ t: 'div', a: { class: 'bw-card' }, c: [
1082
+ bw.makeAvatar({ initials: user.name[0], size: 'sm' }),
1083
+ { t: 'span', c: user.name },
1084
+ bw.makeBadge({ text: user.role, variant: 'info' })
1085
+ ]
1086
+ };
1087
+ }
1088
+
1089
+ // Arrays for lists
1090
+ var userList = users.map(userRow);
1091
+ bw.DOM('#app', { t: 'div', c: userList });
1092
+
1093
+ // Conditionals for branching
1094
+ var content = hasData
1095
+ ? bw.makeTable({ data: rows })
1096
+ : bw.makeAlert({ content: 'No data available', variant: 'info' });
1097
+ ```
1098
+
1099
+ See [TACO Format](taco-format.md) for more composition patterns.