bitwrench 2.0.31 → 2.1.0

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 (126) hide show
  1. package/README.md +210 -125
  2. package/dist/bitwrench-bccl.cjs.js +349 -188
  3. package/dist/bitwrench-bccl.cjs.min.js +2 -39
  4. package/dist/bitwrench-bccl.cjs.min.js.gz +0 -0
  5. package/dist/bitwrench-bccl.esm.js +349 -188
  6. package/dist/bitwrench-bccl.esm.min.js +2 -39
  7. package/dist/bitwrench-bccl.esm.min.js.gz +0 -0
  8. package/dist/bitwrench-bccl.umd.js +349 -188
  9. package/dist/bitwrench-bccl.umd.min.js +2 -39
  10. package/dist/bitwrench-bccl.umd.min.js.gz +0 -0
  11. package/dist/bitwrench-code-edit.cjs.js +17 -6
  12. package/dist/bitwrench-code-edit.cjs.min.js +2 -20
  13. package/dist/bitwrench-code-edit.es5.js +8 -3
  14. package/dist/bitwrench-code-edit.es5.min.js +2 -19
  15. package/dist/bitwrench-code-edit.esm.js +17 -6
  16. package/dist/bitwrench-code-edit.esm.min.js +2 -19
  17. package/dist/bitwrench-code-edit.umd.js +17 -6
  18. package/dist/bitwrench-code-edit.umd.min.js +2 -19
  19. package/dist/bitwrench-code-edit.umd.min.js.gz +0 -0
  20. package/dist/bitwrench-debug.js +1 -1
  21. package/dist/bitwrench-debug.min.js +1 -1
  22. package/dist/bitwrench-lean.cjs.js +2492 -1628
  23. package/dist/bitwrench-lean.cjs.min.js +2 -80
  24. package/dist/bitwrench-lean.cjs.min.js.gz +0 -0
  25. package/dist/bitwrench-lean.es5.js +2740 -1838
  26. package/dist/bitwrench-lean.es5.min.js +2 -49
  27. package/dist/bitwrench-lean.es5.min.js.gz +0 -0
  28. package/dist/bitwrench-lean.esm.js +2492 -1628
  29. package/dist/bitwrench-lean.esm.min.js +2 -80
  30. package/dist/bitwrench-lean.esm.min.js.gz +0 -0
  31. package/dist/bitwrench-lean.umd.js +2492 -1628
  32. package/dist/bitwrench-lean.umd.min.js +2 -80
  33. package/dist/bitwrench-lean.umd.min.js.gz +0 -0
  34. package/dist/bitwrench-util-color.cjs.js +251 -0
  35. package/dist/bitwrench-util-color.cjs.min.js +3 -0
  36. package/dist/bitwrench-util-color.es5.js +256 -0
  37. package/dist/bitwrench-util-color.es5.min.js +3 -0
  38. package/dist/bitwrench-util-color.esm.js +241 -0
  39. package/dist/bitwrench-util-color.esm.min.js +3 -0
  40. package/dist/bitwrench-util-color.umd.js +257 -0
  41. package/dist/bitwrench-util-color.umd.min.js +3 -0
  42. package/dist/bitwrench-util-css.cjs.js +2 -1
  43. package/dist/bitwrench-util-css.cjs.min.js +2 -21
  44. package/dist/bitwrench-util-css.es5.js +2 -1
  45. package/dist/bitwrench-util-css.es5.min.js +2 -20
  46. package/dist/bitwrench-util-css.esm.js +2 -1
  47. package/dist/bitwrench-util-css.esm.min.js +1 -19
  48. package/dist/bitwrench-util-css.umd.js +2 -1
  49. package/dist/bitwrench-util-css.umd.min.js +2 -20
  50. package/dist/bitwrench-util-css.umd.min.js.gz +0 -0
  51. package/dist/bitwrench.cjs.js +2826 -1801
  52. package/dist/bitwrench.cjs.min.js +2 -99
  53. package/dist/bitwrench.cjs.min.js.gz +0 -0
  54. package/dist/bitwrench.css +403 -479
  55. package/dist/bitwrench.d.ts +70 -73
  56. package/dist/bitwrench.es5.js +3106 -2020
  57. package/dist/bitwrench.es5.min.js +2 -67
  58. package/dist/bitwrench.es5.min.js.gz +0 -0
  59. package/dist/bitwrench.esm.js +2826 -1801
  60. package/dist/bitwrench.esm.min.js +2 -99
  61. package/dist/bitwrench.esm.min.js.gz +0 -0
  62. package/dist/bitwrench.min.css +1 -1
  63. package/dist/bitwrench.umd.js +2826 -1801
  64. package/dist/bitwrench.umd.min.js +2 -99
  65. package/dist/bitwrench.umd.min.js.gz +0 -0
  66. package/dist/builds.json +222 -134
  67. package/dist/bwserve.cjs.js +308 -298
  68. package/dist/bwserve.d.ts +157 -0
  69. package/dist/bwserve.esm.js +309 -299
  70. package/dist/sri.json +54 -46
  71. package/docs/README.md +6 -3
  72. package/docs/app-patterns.md +7 -6
  73. package/docs/bitwrench-for-wasm.md +53 -54
  74. package/docs/bitwrench-mcp.md +2 -2
  75. package/docs/bitwrench-northstar-principles.md +406 -0
  76. package/docs/bitwrench-taco-schema-discussion.md +2 -2
  77. package/docs/bitwrench_api.md +191 -106
  78. package/docs/bitwrench_typescript_usage.md +5 -5
  79. package/docs/bw-attach.md +29 -75
  80. package/docs/bwserve.md +200 -168
  81. package/docs/cli.md +36 -12
  82. package/docs/component-cheatsheet.md +2 -2
  83. package/docs/component-library.md +4 -4
  84. package/docs/component-lifecycle.md +234 -0
  85. package/docs/drift-lint.md +268 -0
  86. package/docs/framework-translation-table.md +4 -4
  87. package/docs/llm-bitwrench-guide.md +60 -50
  88. package/docs/routing.md +11 -13
  89. package/docs/state-management.md +110 -109
  90. package/docs/taco-format.md +13 -14
  91. package/docs/theming.md +13 -3
  92. package/docs/thinking-in-bitwrench.md +858 -983
  93. package/docs/tutorial-bwserve.md +37 -36
  94. package/docs/tutorial-embedded.md +10 -21
  95. package/docs/tutorial-website.md +2 -2
  96. package/package.json +38 -7
  97. package/readme.html +262 -160
  98. package/src/bitwrench-bccl-entry.js +2 -2
  99. package/src/bitwrench-bccl.js +346 -185
  100. package/src/bitwrench-code-edit.js +16 -5
  101. package/src/bitwrench-color-utils.js +117 -181
  102. package/src/bitwrench-file-ops.js +2 -2
  103. package/src/bitwrench-lean.js +4 -3
  104. package/src/bitwrench-router.js +5 -2
  105. package/src/bitwrench-styles.js +420 -504
  106. package/src/bitwrench-util-color.js +240 -0
  107. package/src/bitwrench-util-css.js +1 -0
  108. package/src/bitwrench-utils.js +4 -0
  109. package/src/bitwrench.d.ts +70 -73
  110. package/src/bitwrench.h +5 -0
  111. package/src/bitwrench.js +1939 -933
  112. package/src/bwserve/attach.js +0 -1
  113. package/src/bwserve/bwclient.js +172 -32
  114. package/src/bwserve/bwshell.js +0 -4
  115. package/src/bwserve/client.js +59 -220
  116. package/src/bwserve/index.js +78 -42
  117. package/src/bwserve.d.ts +157 -0
  118. package/src/bwserve.h +5 -0
  119. package/src/cli/attach.js +12 -75
  120. package/src/cli/convert.js +2 -2
  121. package/src/cli/serve.js +37 -35
  122. package/src/generate-css.js +1 -1
  123. package/src/mcp/knowledge.js +4 -4
  124. package/src/mcp/live.js +21 -13
  125. package/src/mcp/tools.js +0 -1
  126. package/src/version.js +3 -7
@@ -1,4 +1,4 @@
1
- /*! bitwrench-bccl v2.0.31 | BSD-2-Clause | https://deftio.github.com/bitwrench/pages */
1
+ /*! bitwrench-bccl v2.1.0 | BSD-2-Clause | https://deftio.github.io/bitwrench/pages */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
4
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -51,7 +51,7 @@
51
51
  // Handle outline variants: 'outline_primary' or 'outline-primary'
52
52
  if (v.indexOf('outline') === 0) {
53
53
  var base = v.replace(/^outline[_-]/, '');
54
- return 'bw_btn_outline bw_' + base;
54
+ return 'bw_bccl_btn_outline bw_' + base;
55
55
  }
56
56
  return 'bw_' + v;
57
57
  }
@@ -121,48 +121,48 @@
121
121
  };
122
122
 
123
123
  const cardClasses = [
124
- 'bw_card',
124
+ 'bw_bccl_card',
125
125
  variantClass(variant),
126
126
  shadow ? (shadowClasses[shadow] || '') : '',
127
127
  !bordered ? 'bw_border_0' : '',
128
- hoverable ? 'bw_card_hoverable' : '',
128
+ hoverable ? 'bw_bccl_card_hoverable' : '',
129
129
  className
130
130
  ].filter(Boolean).join(' ').trim();
131
131
 
132
132
  const cardContent = [
133
133
  header && {
134
134
  t: 'div',
135
- a: { class: `bw_card_header ${headerClass}`.trim() },
135
+ a: { class: `bw_bccl_card_header ${headerClass}`.trim() },
136
136
  c: header
137
137
  },
138
138
  image && (imagePosition === 'top' || imagePosition === 'left') && {
139
139
  t: 'img',
140
140
  a: {
141
- class: `bw_card_img_${imagePosition}`,
141
+ class: `bw_bccl_card_img_${imagePosition}`,
142
142
  src: image.src,
143
143
  alt: image.alt || ''
144
144
  }
145
145
  },
146
146
  {
147
147
  t: 'div',
148
- a: { class: `bw_card_body ${bodyClass}`.trim() },
148
+ a: { class: `bw_bccl_card_body ${bodyClass}`.trim() },
149
149
  c: [
150
- title && { t: 'h5', a: { class: 'bw_card_title' }, c: title },
151
- subtitle && { t: 'h6', a: { class: 'bw_card_subtitle bw_mb_2 bw_text_muted' }, c: subtitle },
150
+ title && { t: 'h5', a: { class: 'bw_bccl_card_title' }, c: title },
151
+ subtitle && { t: 'h6', a: { class: 'bw_bccl_card_subtitle bw_mb_2 bw_text_muted' }, c: subtitle },
152
152
  content && (Array.isArray(content) ? content : [content])
153
153
  ].flat().filter(Boolean)
154
154
  },
155
155
  image && (imagePosition === 'bottom' || imagePosition === 'right') && {
156
156
  t: 'img',
157
157
  a: {
158
- class: `bw_card_img_${imagePosition}`,
158
+ class: `bw_bccl_card_img_${imagePosition}`,
159
159
  src: image.src,
160
160
  alt: image.alt || ''
161
161
  }
162
162
  },
163
163
  footer && {
164
164
  t: 'div',
165
- a: { class: `bw_card_footer ${footerClass}`.trim() },
165
+ a: { class: `bw_bccl_card_footer ${footerClass}`.trim() },
166
166
  c: footer
167
167
  }
168
168
  ].filter(Boolean);
@@ -181,9 +181,9 @@
181
181
  type: 'card',
182
182
  state: props.state || {},
183
183
  slots: {
184
- title: '.bw_card_title',
185
- content: '.bw_card_body',
186
- footer: '.bw_card_footer'
184
+ title: '.bw_bccl_card_title',
185
+ content: '.bw_bccl_card_body',
186
+ footer: '.bw_bccl_card_footer'
187
187
  }
188
188
  }
189
189
  };
@@ -197,9 +197,9 @@
197
197
  type: 'card',
198
198
  state: props.state || {},
199
199
  slots: {
200
- title: '.bw_card_title',
201
- content: '.bw_card_body',
202
- footer: '.bw_card_footer'
200
+ title: '.bw_bccl_card_title',
201
+ content: '.bw_bccl_card_body',
202
+ footer: '.bw_bccl_card_footer'
203
203
  }
204
204
  }
205
205
  };
@@ -236,6 +236,7 @@
236
236
  size,
237
237
  disabled = false,
238
238
  onclick,
239
+ action,
239
240
  type = 'button',
240
241
  className = '',
241
242
  style
@@ -246,9 +247,10 @@
246
247
  a: {
247
248
  type,
248
249
  class: [
249
- 'bw_btn',
250
+ 'bw_bccl_btn',
250
251
  variantClass(variant),
251
- size && `bw_btn_${size}`,
252
+ size && `bw_bccl_btn_${size}`,
253
+ action && ('bw_act_' + action),
252
254
  className
253
255
  ].filter(Boolean).join(' '),
254
256
  disabled,
@@ -282,7 +284,7 @@
282
284
 
283
285
  return {
284
286
  t: 'div',
285
- a: { class: `bw_container${fluid ? '-fluid' : ''} ${className}`.trim() },
287
+ a: { class: `bw_bccl_container${fluid ? '-fluid' : ''} ${className}`.trim() },
286
288
  c: children
287
289
  };
288
290
  }
@@ -308,7 +310,7 @@
308
310
  return {
309
311
  t: 'div',
310
312
  a: {
311
- class: `bw_row ${gap ? `bw_g_${gap}` : ''} ${className}`.trim()
313
+ class: `bw_bccl_row bw_row ${gap ? `bw_g_${gap}` : ''} ${className}`.trim()
312
314
  },
313
315
  c: children
314
316
  };
@@ -359,7 +361,7 @@
359
361
 
360
362
  return {
361
363
  t: 'div',
362
- a: { class: `${classes.join(' ')} ${className}`.trim() },
364
+ a: { class: `bw_bccl_col ${classes.join(' ')} ${className}`.trim() },
363
365
  c: content || children
364
366
  };
365
367
  }
@@ -398,7 +400,7 @@
398
400
  return {
399
401
  t: 'ul',
400
402
  a: {
401
- class: `bw_nav ${pills ? 'bw_nav_pills' : 'bw_nav_tabs'} ${vertical ? 'bw_nav_vertical' : ''} ${className}`.trim()
403
+ class: `bw_bccl_nav bw_nav ${pills ? 'bw_nav_pills' : 'bw_nav_tabs'} ${vertical ? 'bw_nav_vertical' : ''} ${className}`.trim()
402
404
  },
403
405
  c: items.map(item => ({
404
406
  t: 'li',
@@ -451,7 +453,7 @@
451
453
  return {
452
454
  t: 'nav',
453
455
  a: {
454
- class: `bw_navbar ${dark ? 'bw_navbar_dark' : 'bw_navbar_light'} ${className}`.trim()
456
+ class: `bw_bccl_navbar ${dark ? 'bw_bccl_navbar_dark' : 'bw_bccl_navbar_light'} ${className}`.trim()
455
457
  },
456
458
  c: {
457
459
  t: 'div',
@@ -459,12 +461,12 @@
459
461
  c: [
460
462
  brand && {
461
463
  t: 'a',
462
- a: { href: brandHref, class: 'bw_navbar_brand' },
464
+ a: { href: brandHref, class: 'bw_bccl_navbar_brand' },
463
465
  c: brand
464
466
  },
465
467
  items.length > 0 && {
466
468
  t: 'div',
467
- a: { class: 'bw_navbar_nav' },
469
+ a: { class: 'bw_bccl_navbar_nav' },
468
470
  c: items.map(item => ({
469
471
  t: 'a',
470
472
  a: {
@@ -521,7 +523,7 @@
521
523
  // Shared tab switching logic
522
524
  function switchTab(el, index) {
523
525
  var allTabs = el.querySelectorAll('.bw_nav_link');
524
- var allPanes = el.querySelectorAll('.bw_tab_pane');
526
+ var allPanes = el.querySelectorAll('.bw_bccl_tab_pane');
525
527
  if (index < 0 || index >= allTabs.length) return;
526
528
  allTabs.forEach(function(t) {
527
529
  t.classList.remove('active');
@@ -538,7 +540,7 @@
538
540
 
539
541
  return {
540
542
  t: 'div',
541
- a: { class: 'bw_tabs' },
543
+ a: { class: 'bw_bccl_tabs' },
542
544
  c: [
543
545
  {
544
546
  t: 'ul',
@@ -555,7 +557,7 @@
555
557
  tabindex: index === actualActiveIndex ? '0' : '-1',
556
558
  'aria-selected': index === actualActiveIndex ? 'true' : 'false',
557
559
  onclick: (e) => {
558
- switchTab(e.target.closest('.bw_tabs'), index);
560
+ switchTab(e.target.closest('.bw_bccl_tabs'), index);
559
561
  }
560
562
  },
561
563
  c: tab.label
@@ -564,11 +566,11 @@
564
566
  },
565
567
  {
566
568
  t: 'div',
567
- a: { class: 'bw_tab_content' },
569
+ a: { class: 'bw_bccl_tab_content' },
568
570
  c: tabs.map((tab, index) => ({
569
571
  t: 'div',
570
572
  a: {
571
- class: `bw_tab_pane ${index === actualActiveIndex ? 'active' : ''}`,
573
+ class: `bw_bccl_tab_pane ${index === actualActiveIndex ? 'active' : ''}`,
572
574
  role: 'tabpanel'
573
575
  },
574
576
  c: tab.content
@@ -649,7 +651,7 @@
649
651
  return {
650
652
  t: 'div',
651
653
  a: {
652
- class: `bw_alert ${variantClass(variant)} ${dismissible ? 'bw_alert_dismissible' : ''} ${className}`.trim(),
654
+ class: `bw_bccl_alert ${variantClass(variant)} ${dismissible ? 'bw_bccl_alert_dismissible' : ''} ${className}`.trim(),
653
655
  role: 'alert'
654
656
  },
655
657
  c: [
@@ -661,7 +663,7 @@
661
663
  class: 'bw_close',
662
664
  'aria-label': 'Close',
663
665
  onclick: function(e) {
664
- var alert = e.target.closest('.bw_alert');
666
+ var alert = e.target.closest('.bw_bccl_alert');
665
667
  if (alert) { alert.remove(); }
666
668
  }
667
669
  },
@@ -704,12 +706,12 @@
704
706
  className = ''
705
707
  } = props;
706
708
 
707
- const sizeClass = size === 'sm' ? ' bw_badge_sm' : size === 'lg' ? ' bw_badge_lg' : '';
709
+ const sizeClass = size === 'sm' ? ' bw_bccl_badge_sm' : size === 'lg' ? ' bw_bccl_badge_lg' : '';
708
710
 
709
711
  return {
710
712
  t: 'span',
711
713
  a: {
712
- class: `bw_badge ${variantClass(variant)}${sizeClass} ${pill ? 'bw_badge_pill' : ''} ${className}`.trim()
714
+ class: `bw_bccl_badge ${variantClass(variant)}${sizeClass} ${pill ? 'bw_bccl_badge_pill' : ''} ${className}`.trim()
713
715
  },
714
716
  c: text
715
717
  };
@@ -752,17 +754,17 @@
752
754
  return {
753
755
  t: 'div',
754
756
  a: {
755
- class: 'bw_progress',
757
+ class: 'bw_bccl_progress',
756
758
  style: height ? { height: `${height}px` } : undefined
757
759
  },
758
760
  c: {
759
761
  t: 'div',
760
762
  a: {
761
763
  class: [
762
- 'bw_progress_bar',
764
+ 'bw_bccl_progress_bar',
763
765
  variantClass(variant),
764
- striped && 'bw_progress_bar_striped',
765
- animated && 'bw_progress_bar_animated'
766
+ striped && 'bw_bccl_progress_bar_striped',
767
+ animated && 'bw_bccl_progress_bar_animated'
766
768
  ].filter(Boolean).join(' '),
767
769
  role: 'progressbar',
768
770
  style: { width: `${percentage}%` },
@@ -776,7 +778,7 @@
776
778
  type: 'progress',
777
779
  handle: {
778
780
  setValue: function(el, n) {
779
- var bar = el.querySelector('.bw_progress_bar');
781
+ var bar = el.querySelector('.bw_bccl_progress_bar');
780
782
  if (!bar) return;
781
783
  var maxVal = parseInt(bar.getAttribute('aria-valuemax')) || 100;
782
784
  var pct = Math.round((n / maxVal) * 100);
@@ -785,7 +787,7 @@
785
787
  bar.textContent = pct + '%';
786
788
  },
787
789
  getValue: function(el) {
788
- var bar = el.querySelector('.bw_progress_bar');
790
+ var bar = el.querySelector('.bw_bccl_progress_bar');
789
791
  return bar ? parseInt(bar.getAttribute('aria-valuenow')) || 0 : 0;
790
792
  }
791
793
  }
@@ -826,7 +828,7 @@
826
828
 
827
829
  return {
828
830
  t: 'div',
829
- a: { class: `bw_list_group ${flush ? 'bw_list_group_flush' : ''}`.trim() },
831
+ a: { class: `bw_bccl_listGroup bw_list_group ${flush ? 'bw_list_group_flush' : ''}`.trim() },
830
832
  c: items.map(item => {
831
833
  const isObject = typeof item === 'object';
832
834
  const text = isObject ? item.text : item;
@@ -898,11 +900,11 @@
898
900
 
899
901
  return {
900
902
  t: 'nav',
901
- a: { 'aria-label': 'breadcrumb' },
903
+ a: { 'aria-label': 'breadcrumb', class: 'bw_bccl_breadcrumb' },
902
904
  c: {
903
905
  t: 'ol',
904
906
  a: { class: 'bw_breadcrumb' },
905
- c: items.map((item, index) => ({
907
+ c: items.map((item, _index) => ({
906
908
  t: 'li',
907
909
  a: {
908
910
  class: `bw_breadcrumb_item ${item.active ? 'active' : ''}`,
@@ -937,15 +939,138 @@
937
939
  * });
938
940
  */
939
941
  function makeForm(props = {}) {
940
- const { children, onsubmit, className = '' } = props;
942
+ const { children, fields, onsubmit, className = '' } = props;
943
+
944
+ // Legacy API: just wraps children
945
+ if (!fields) {
946
+ return {
947
+ t: 'form',
948
+ a: {
949
+ class: `bw_bccl_form ${className}`.trim(),
950
+ onsubmit: onsubmit || ((e) => e.preventDefault())
951
+ },
952
+ c: children
953
+ };
954
+ }
955
+
956
+ // New fields-based API with label association, getValues/setValues/validate
957
+ var fieldIds = {};
958
+ var fieldItems = fields.map(function(field) {
959
+ var fieldId = 'bw_field_' + Math.random().toString(36).substr(2, 9);
960
+ fieldIds[field.name] = fieldId;
961
+
962
+ var inputTag = field.type === 'textarea' ? 'textarea' : (field.type === 'select' ? 'select' : 'input');
963
+ var inputAttrs = {
964
+ id: fieldId,
965
+ name: field.name,
966
+ class: 'bw_bccl_form_control'
967
+ };
968
+ if (inputTag === 'input') {
969
+ inputAttrs.type = field.type || 'text';
970
+ }
971
+ if (field.required) {
972
+ inputAttrs.required = true;
973
+ }
974
+ if (field.placeholder) {
975
+ inputAttrs.placeholder = field.placeholder;
976
+ }
977
+
978
+ return {
979
+ t: 'div',
980
+ a: { class: 'bw_bccl_form_group' },
981
+ c: [
982
+ field.label && {
983
+ t: 'label',
984
+ a: { for: fieldId, class: 'bw_bccl_form_label' },
985
+ c: field.required ? [field.label, { t: 'span', a: { class: 'bw_text_danger bw_ms_1' }, c: '*' }] : field.label
986
+ },
987
+ {
988
+ t: inputTag,
989
+ a: inputAttrs
990
+ }
991
+ ].filter(Boolean)
992
+ };
993
+ });
941
994
 
942
995
  return {
943
996
  t: 'form',
944
997
  a: {
945
- class: className,
998
+ class: `bw_bccl_form ${className}`.trim(),
946
999
  onsubmit: onsubmit || ((e) => e.preventDefault())
947
1000
  },
948
- c: children
1001
+ c: fieldItems,
1002
+ o: {
1003
+ type: 'form',
1004
+ handle: {
1005
+ getValues: function(el) {
1006
+ var values = {};
1007
+ fields.forEach(function(field) {
1008
+ var input = el.querySelector('[name="' + field.name + '"]');
1009
+ if (input) {
1010
+ var val = input.value;
1011
+ if (field.type === 'number' && val !== '' && val !== undefined) {
1012
+ val = Number(val);
1013
+ }
1014
+ values[field.name] = val;
1015
+ }
1016
+ });
1017
+ return values;
1018
+ },
1019
+ setValues: function(el, vals) {
1020
+ if (typeof vals !== 'object') return;
1021
+ Object.keys(vals).forEach(function(name) {
1022
+ var input = el.querySelector('[name="' + name + '"]');
1023
+ if (input) {
1024
+ input.value = vals[name];
1025
+ }
1026
+ });
1027
+ },
1028
+ validate: function(el) {
1029
+ var valid = true;
1030
+ fields.forEach(function(field) {
1031
+ var input = el.querySelector('[name="' + field.name + '"]');
1032
+ if (!input) return;
1033
+ // Clear previous error state
1034
+ input.removeAttribute('aria-invalid');
1035
+ input.removeAttribute('aria-describedby');
1036
+ var existingErr = input.parentNode.querySelector('.bw_bccl_form_error');
1037
+ if (existingErr) existingErr.parentNode.removeChild(existingErr);
1038
+
1039
+ var isValid = true;
1040
+ if (field.required && (!input.value || input.value.trim() === '')) {
1041
+ isValid = false;
1042
+ }
1043
+ if (!isValid) {
1044
+ valid = false;
1045
+ input.setAttribute('aria-invalid', 'true');
1046
+ var errId = 'bw_err_' + field.name + '_' + Math.random().toString(36).substr(2, 6);
1047
+ input.setAttribute('aria-describedby', errId);
1048
+ var errEl = document.createElement('div');
1049
+ errEl.id = errId;
1050
+ errEl.className = 'bw_bccl_form_error bw_invalid_feedback';
1051
+ errEl.textContent = (field.label || field.name) + ' is required';
1052
+ input.parentNode.appendChild(errEl);
1053
+ }
1054
+ });
1055
+ return { valid: valid };
1056
+ },
1057
+ setErrors: function(el, errors) {
1058
+ if (typeof errors !== 'object') return;
1059
+ Object.keys(errors).forEach(function(name) {
1060
+ var input = el.querySelector('[name="' + name + '"]');
1061
+ if (!input) return;
1062
+ input.setAttribute('aria-invalid', 'true');
1063
+ var errId = 'bw_err_' + name + '_' + Math.random().toString(36).substr(2, 6);
1064
+ input.setAttribute('aria-describedby', errId);
1065
+ var errEl = document.createElement('div');
1066
+ errEl.id = errId;
1067
+ errEl.className = 'bw_bccl_form_error bw_invalid_feedback';
1068
+ errEl.textContent = errors[name];
1069
+ input.parentNode.appendChild(errEl);
1070
+ });
1071
+ }
1072
+ }
1073
+ }
949
1074
  };
950
1075
  }
951
1076
 
@@ -986,11 +1111,11 @@
986
1111
 
987
1112
  return {
988
1113
  t: 'div',
989
- a: { class: 'bw_form_group' },
1114
+ a: { class: 'bw_bccl_form_group' },
990
1115
  c: [
991
1116
  label && {
992
1117
  t: 'label',
993
- a: { for: id, class: 'bw_form_label' },
1118
+ a: { for: id, class: 'bw_bccl_form_label' },
994
1119
  c: required ? [label, { t: 'span', a: { class: 'bw_text_danger bw_ms_1' }, c: '*' }] : label
995
1120
  },
996
1121
  styledInput,
@@ -1001,7 +1126,7 @@
1001
1126
  },
1002
1127
  help && {
1003
1128
  t: 'small',
1004
- a: { class: 'bw_form_text bw_text_muted' },
1129
+ a: { class: 'bw_bccl_form_text bw_text_muted' },
1005
1130
  c: help
1006
1131
  }
1007
1132
  ].filter(Boolean)
@@ -1054,7 +1179,7 @@
1054
1179
  t: 'input',
1055
1180
  a: {
1056
1181
  type,
1057
- class: `bw_form_control ${className}`.trim(),
1182
+ class: `bw_bccl_form_control ${className}`.trim(),
1058
1183
  placeholder,
1059
1184
  value,
1060
1185
  id,
@@ -1107,7 +1232,7 @@
1107
1232
  return {
1108
1233
  t: 'textarea',
1109
1234
  a: {
1110
- class: `bw_form_control ${className}`.trim(),
1235
+ class: `bw_bccl_form_control ${className}`.trim(),
1111
1236
  placeholder,
1112
1237
  rows,
1113
1238
  id,
@@ -1161,7 +1286,7 @@
1161
1286
  return {
1162
1287
  t: 'select',
1163
1288
  a: {
1164
- class: `bw_form_control ${className}`.trim(),
1289
+ class: `bw_bccl_form_control ${className}`.trim(),
1165
1290
  id,
1166
1291
  name,
1167
1292
  disabled,
@@ -1212,13 +1337,13 @@
1212
1337
 
1213
1338
  return {
1214
1339
  t: 'div',
1215
- a: { class: `bw_form_check ${className}`.trim() },
1340
+ a: { class: `bw_bccl_form_check ${className}`.trim() },
1216
1341
  c: [
1217
1342
  {
1218
1343
  t: 'input',
1219
1344
  a: {
1220
1345
  type: 'checkbox',
1221
- class: 'bw_form_check_input',
1346
+ class: 'bw_bccl_form_check_input',
1222
1347
  checked,
1223
1348
  id,
1224
1349
  name,
@@ -1229,7 +1354,7 @@
1229
1354
  },
1230
1355
  label && {
1231
1356
  t: 'label',
1232
- a: { class: 'bw_form_check_label', for: id },
1357
+ a: { class: 'bw_bccl_form_check_label', for: id },
1233
1358
  c: label
1234
1359
  }
1235
1360
  ].filter(Boolean)
@@ -1267,7 +1392,7 @@
1267
1392
  return {
1268
1393
  t: 'div',
1269
1394
  a: {
1270
- class: `bw_${direction === 'vertical' ? 'vstack' : 'hstack'} bw_gap_${gap} ${className}`.trim()
1395
+ class: `bw_bccl_stack bw_${direction === 'vertical' ? 'vstack' : 'hstack'} bw_gap_${gap} ${className}`.trim()
1271
1396
  },
1272
1397
  c: children
1273
1398
  };
@@ -1295,7 +1420,7 @@
1295
1420
  return {
1296
1421
  t: 'div',
1297
1422
  a: {
1298
- class: `bw_spinner_${type} bw_spinner_${type}-${size} ${variantClass(variant)}`,
1423
+ class: `bw_bccl_spinner bw_spinner_${type} bw_spinner_${type}-${size} ${variantClass(variant)}`,
1299
1424
  role: 'status'
1300
1425
  },
1301
1426
  c: {
@@ -1332,7 +1457,7 @@
1332
1457
  * variant: "dark",
1333
1458
  * actions: [
1334
1459
  * makeButton({ text: "Get Started", variant: "primary", size: "lg" }),
1335
- * makeButton({ text: "Learn More", variant: "outline-light", size: "lg" })
1460
+ * makeButton({ text: "Learn More", variant: "outline_light", size: "lg" })
1336
1461
  * ]
1337
1462
  * });
1338
1463
  */
@@ -1360,35 +1485,35 @@
1360
1485
  return {
1361
1486
  t: 'section',
1362
1487
  a: {
1363
- class: `bw_hero ${variantClass(variant)} ${sizeClasses[size] || sizeClasses.lg} ${centered ? 'bw_text_center' : ''} ${className}`.trim(),
1488
+ class: `bw_bccl_hero ${variantClass(variant)} ${sizeClasses[size] || sizeClasses.lg} ${centered ? 'bw_text_center' : ''} ${className}`.trim(),
1364
1489
  style: backgroundImage ? `background-image: url('${backgroundImage}'); background-size: cover; background-position: center;` : undefined
1365
1490
  },
1366
1491
  c: [
1367
1492
  overlay && {
1368
1493
  t: 'div',
1369
- a: { class: 'bw_hero_overlay' }
1494
+ a: { class: 'bw_bccl_hero_overlay' }
1370
1495
  },
1371
1496
  {
1372
1497
  t: 'div',
1373
1498
  a: { class: 'bw_container' },
1374
1499
  c: {
1375
1500
  t: 'div',
1376
- a: { class: 'bw_hero_content' },
1501
+ a: { class: 'bw_bccl_hero_content' },
1377
1502
  c: [
1378
1503
  title && {
1379
1504
  t: 'h1',
1380
- a: { class: 'bw_hero_title bw_display_4 bw_mb_3' },
1505
+ a: { class: 'bw_bccl_hero_title bw_display_4 bw_mb_3' },
1381
1506
  c: title
1382
1507
  },
1383
1508
  subtitle && {
1384
1509
  t: 'p',
1385
- a: { class: 'bw_hero_subtitle bw_lead bw_mb_4' },
1510
+ a: { class: 'bw_bccl_hero_subtitle bw_lead bw_mb_4' },
1386
1511
  c: subtitle
1387
1512
  },
1388
1513
  content,
1389
1514
  actions && {
1390
1515
  t: 'div',
1391
- a: { class: 'bw_hero_actions bw_mt_4' },
1516
+ a: { class: 'bw_bccl_hero_actions bw_mt_4' },
1392
1517
  c: actions
1393
1518
  }
1394
1519
  ].filter(Boolean)
@@ -1438,7 +1563,7 @@
1438
1563
 
1439
1564
  return {
1440
1565
  t: 'div',
1441
- a: { class: `bw_feature_grid ${className}`.trim() },
1566
+ a: { class: `bw_bccl_featureGrid bw_feature_grid ${className}`.trim() },
1442
1567
  c: {
1443
1568
  t: 'div',
1444
1569
  a: { class: 'bw_row bw_g_4' },
@@ -1508,7 +1633,7 @@
1508
1633
 
1509
1634
  return {
1510
1635
  t: 'section',
1511
- a: { class: `bw_cta bw_bg_${variant} bw_py_5 ${className}`.trim() },
1636
+ a: { class: `bw_bccl_cta bw_cta bw_bg_${variant} bw_py_5 ${className}`.trim() },
1512
1637
  c: {
1513
1638
  t: 'div',
1514
1639
  a: { class: 'bw_container' },
@@ -1569,7 +1694,7 @@
1569
1694
  return {
1570
1695
  t: 'section',
1571
1696
  a: {
1572
- class: `bw_section ${spacingClasses[spacing] || spacingClasses.md} ${variant !== 'default' ? `bw_bg_${variant}` : ''} ${className}`.trim()
1697
+ class: `bw_bccl_section bw_section ${spacingClasses[spacing] || spacingClasses.md} ${variant !== 'default' ? `bw_bg_${variant}` : ''} ${className}`.trim()
1573
1698
  },
1574
1699
  c: {
1575
1700
  t: 'div',
@@ -1670,6 +1795,7 @@
1670
1795
  },
1671
1796
  c: 'Copy'
1672
1797
  },
1798
+ /* c8 ignore next 2 -- codeEditor ternary; requires globalThis.bw.codeEditor setup */
1673
1799
  (typeof globalThis !== 'undefined' && typeof globalThis.bw !== 'undefined' && typeof globalThis.bw.codeEditor === 'function')
1674
1800
  ? globalThis.bw.codeEditor({ code: code, lang: language === 'javascript' ? 'js' : language, readOnly: true, height: 'auto' })
1675
1801
  : {
@@ -1698,7 +1824,7 @@
1698
1824
 
1699
1825
  return {
1700
1826
  t: 'div',
1701
- a: { class: 'bw_code_demo' },
1827
+ a: { class: 'bw_bccl_codeDemo bw_code_demo' },
1702
1828
  c: content
1703
1829
  };
1704
1830
  }
@@ -1795,7 +1921,7 @@
1795
1921
  c: {
1796
1922
  t: 'ul',
1797
1923
  a: {
1798
- class: `bw_pagination ${size ? 'bw_pagination_' + size : ''} ${className}`.trim()
1924
+ class: `bw_bccl_pagination ${size ? 'bw_bccl_pagination_' + size : ''} ${className}`.trim()
1799
1925
  },
1800
1926
  c: items
1801
1927
  },
@@ -1857,13 +1983,13 @@
1857
1983
 
1858
1984
  return {
1859
1985
  t: 'div',
1860
- a: { class: `bw_form_check ${className}`.trim() },
1986
+ a: { class: `bw_bccl_form_check ${className}`.trim() },
1861
1987
  c: [
1862
1988
  {
1863
1989
  t: 'input',
1864
1990
  a: {
1865
1991
  type: 'radio',
1866
- class: 'bw_form_check_input',
1992
+ class: 'bw_bccl_form_check_input',
1867
1993
  name,
1868
1994
  value,
1869
1995
  checked,
@@ -1874,7 +2000,7 @@
1874
2000
  },
1875
2001
  label && {
1876
2002
  t: 'label',
1877
- a: { class: 'bw_form_check_label', for: id },
2003
+ a: { class: 'bw_bccl_form_check_label', for: id },
1878
2004
  c: label
1879
2005
  }
1880
2006
  ].filter(Boolean)
@@ -1911,7 +2037,7 @@
1911
2037
  return {
1912
2038
  t: 'div',
1913
2039
  a: {
1914
- class: `${vertical ? 'bw_btn_group_vertical' : 'bw_btn_group'} ${size ? 'bw_btn_group_' + size : ''} ${className}`.trim(),
2040
+ class: `${vertical ? 'bw_bccl_btn_group_vertical' : 'bw_bccl_btn_group'} ${size ? 'bw_bccl_btn_group_' + size : ''} ${className}`.trim(),
1915
2041
  role: 'group'
1916
2042
  },
1917
2043
  c: children
@@ -1951,35 +2077,37 @@
1951
2077
 
1952
2078
  return {
1953
2079
  t: 'div',
1954
- a: { class: `bw_accordion ${className}`.trim() },
2080
+ a: { class: `bw_bccl_accordion ${className}`.trim() },
1955
2081
  c: items.map(function(item, index) {
2082
+ var panelId = 'bw_acc_panel_' + Math.random().toString(36).substr(2, 9) + '_' + index;
1956
2083
  return {
1957
2084
  t: 'div',
1958
- a: { class: 'bw_accordion_item' },
2085
+ a: { class: 'bw_bccl_accordion_item' },
1959
2086
  c: [
1960
2087
  {
1961
2088
  t: 'h2',
1962
- a: { class: 'bw_accordion_header' },
2089
+ a: { class: 'bw_bccl_accordion_header' },
1963
2090
  c: {
1964
2091
  t: 'button',
1965
2092
  a: {
1966
- class: `bw_accordion_button ${item.open ? '' : 'bw_collapsed'}`.trim(),
2093
+ class: `bw_bccl_accordion_button ${item.open ? '' : 'bw_collapsed'}`.trim(),
1967
2094
  type: 'button',
1968
2095
  'aria-expanded': item.open ? 'true' : 'false',
2096
+ 'aria-controls': panelId,
1969
2097
  onclick: function(e) {
1970
- var btn = e.target.closest('.bw_accordion_button');
1971
- var accordionEl = btn.closest('.bw_accordion');
1972
- var accordionItem = btn.closest('.bw_accordion_item');
1973
- var collapse = accordionItem.querySelector('.bw_accordion_collapse');
2098
+ var btn = e.target.closest('.bw_bccl_accordion_button');
2099
+ var accordionEl = btn.closest('.bw_bccl_accordion');
2100
+ var accordionItem = btn.closest('.bw_bccl_accordion_item');
2101
+ var collapse = accordionItem.querySelector('.bw_bccl_accordion_collapse');
1974
2102
  var isOpen = collapse.classList.contains('bw_collapse_show');
1975
2103
 
1976
2104
  if (!multiOpen) {
1977
2105
  // Animate-close all other open siblings
1978
- var allItems = accordionEl.querySelectorAll('.bw_accordion_item');
2106
+ var allItems = accordionEl.querySelectorAll('.bw_bccl_accordion_item');
1979
2107
  for (var j = 0; j < allItems.length; j++) {
1980
2108
  if (allItems[j] === accordionItem) continue;
1981
- var sibCollapse = allItems[j].querySelector('.bw_accordion_collapse');
1982
- var sibBtn = allItems[j].querySelector('.bw_accordion_button');
2109
+ var sibCollapse = allItems[j].querySelector('.bw_bccl_accordion_collapse');
2110
+ var sibBtn = allItems[j].querySelector('.bw_bccl_accordion_button');
1983
2111
  if (sibCollapse.classList.contains('bw_collapse_show')) {
1984
2112
  sibCollapse.style.maxHeight = sibCollapse.scrollHeight + 'px';
1985
2113
  sibCollapse.offsetHeight; // force reflow
@@ -2023,10 +2151,10 @@
2023
2151
  },
2024
2152
  {
2025
2153
  t: 'div',
2026
- a: { class: `bw_accordion_collapse ${item.open ? 'bw_collapse_show' : ''}`.trim() },
2154
+ a: { id: panelId, class: `bw_bccl_accordion_collapse ${item.open ? 'bw_collapse_show' : ''}`.trim() },
2027
2155
  c: {
2028
2156
  t: 'div',
2029
- a: { class: 'bw_accordion_body' },
2157
+ a: { class: 'bw_bccl_accordion_body' },
2030
2158
  c: item.content
2031
2159
  },
2032
2160
  o: item.open ? {
@@ -2043,16 +2171,16 @@
2043
2171
  state: { multiOpen: multiOpen },
2044
2172
  handle: {
2045
2173
  toggle: function(el, index) {
2046
- var items = el.querySelectorAll('.bw_accordion_item');
2174
+ var items = el.querySelectorAll('.bw_bccl_accordion_item');
2047
2175
  if (index < 0 || index >= items.length) return;
2048
- var btn = items[index].querySelector('.bw_accordion_button');
2176
+ var btn = items[index].querySelector('.bw_bccl_accordion_button');
2049
2177
  if (btn) btn.click();
2050
2178
  },
2051
2179
  openAll: function(el) {
2052
- var items = el.querySelectorAll('.bw_accordion_item');
2180
+ var items = el.querySelectorAll('.bw_bccl_accordion_item');
2053
2181
  for (var i = 0; i < items.length; i++) {
2054
- var collapse = items[i].querySelector('.bw_accordion_collapse');
2055
- var btn = items[i].querySelector('.bw_accordion_button');
2182
+ var collapse = items[i].querySelector('.bw_bccl_accordion_collapse');
2183
+ var btn = items[i].querySelector('.bw_bccl_accordion_button');
2056
2184
  if (!collapse.classList.contains('bw_collapse_show')) {
2057
2185
  collapse.classList.add('bw_collapse_show');
2058
2186
  collapse.style.maxHeight = 'none';
@@ -2062,10 +2190,10 @@
2062
2190
  }
2063
2191
  },
2064
2192
  closeAll: function(el) {
2065
- var items = el.querySelectorAll('.bw_accordion_item');
2193
+ var items = el.querySelectorAll('.bw_bccl_accordion_item');
2066
2194
  for (var i = 0; i < items.length; i++) {
2067
- var collapse = items[i].querySelector('.bw_accordion_collapse');
2068
- var btn = items[i].querySelector('.bw_accordion_button');
2195
+ var collapse = items[i].querySelector('.bw_bccl_accordion_collapse');
2196
+ var btn = items[i].querySelector('.bw_bccl_accordion_button');
2069
2197
  if (collapse.classList.contains('bw_collapse_show')) {
2070
2198
  collapse.style.maxHeight = collapse.scrollHeight + 'px';
2071
2199
  collapse.offsetHeight;
@@ -2111,40 +2239,56 @@
2111
2239
  footer,
2112
2240
  size,
2113
2241
  closeButton = true,
2242
+ closeLabel = 'Close',
2114
2243
  onClose,
2244
+ open = false,
2115
2245
  className = ''
2116
2246
  } = props;
2117
2247
 
2118
2248
  function closeModal(el) {
2119
- var backdrop = el.closest('.bw_modal');
2120
- if (backdrop) {
2121
- backdrop.classList.remove('bw_modal_show');
2122
- document.body.style.overflow = '';
2123
- }
2249
+ var backdrop = el.closest('.bw_bccl_modal');
2250
+ /* c8 ignore next -- defensive; closeModal always called from within modal */
2251
+ if (!backdrop) backdrop = el;
2252
+ // Restore focus to the element that was focused when the modal opened
2253
+ var opener = backdrop._bw_opener || null;
2254
+ backdrop.classList.remove('bw_bccl_modal_show');
2255
+ backdrop.style.display = 'none';
2256
+ document.body.style.overflow = '';
2257
+ // Remove aria-modal when closed
2258
+ var dialog = backdrop.querySelector('[aria-modal]');
2259
+ if (dialog) dialog.removeAttribute('aria-modal');
2260
+ if (opener && typeof opener.focus === 'function') opener.focus();
2124
2261
  if (onClose) onClose();
2125
2262
  }
2126
2263
 
2127
2264
  return {
2128
2265
  t: 'div',
2129
- a: { class: `bw_modal ${className}`.trim() },
2266
+ a: {
2267
+ class: `bw_bccl_modal ${open ? 'bw_bccl_modal_show' : ''} ${className}`.trim(),
2268
+ style: open ? 'display:flex' : undefined
2269
+ },
2130
2270
  c: {
2131
2271
  t: 'div',
2132
- a: { class: `bw_modal_dialog ${size ? 'bw_modal_' + size : ''}`.trim() },
2272
+ a: {
2273
+ class: `bw_bccl_modal_dialog ${size ? 'bw_bccl_modal_' + size : ''}`.trim(),
2274
+ role: 'dialog',
2275
+ 'aria-modal': 'true'
2276
+ },
2133
2277
  c: {
2134
2278
  t: 'div',
2135
- a: { class: 'bw_modal_content' },
2279
+ a: { class: 'bw_bccl_modal_content' },
2136
2280
  c: [
2137
2281
  (title || closeButton) && {
2138
2282
  t: 'div',
2139
- a: { class: 'bw_modal_header' },
2283
+ a: { class: 'bw_bccl_modal_header' },
2140
2284
  c: [
2141
- title && { t: 'h5', a: { class: 'bw_modal_title' }, c: title },
2285
+ title && { t: 'h5', a: { class: 'bw_bccl_modal_title' }, c: title },
2142
2286
  closeButton && {
2143
2287
  t: 'button',
2144
2288
  a: {
2145
2289
  type: 'button',
2146
2290
  class: 'bw_close',
2147
- 'aria-label': 'Close',
2291
+ 'aria-label': closeLabel,
2148
2292
  onclick: function(e) { closeModal(e.target); }
2149
2293
  },
2150
2294
  c: '\u00D7'
@@ -2153,12 +2297,12 @@
2153
2297
  },
2154
2298
  content && {
2155
2299
  t: 'div',
2156
- a: { class: 'bw_modal_body' },
2300
+ a: { class: 'bw_bccl_modal_body' },
2157
2301
  c: content
2158
2302
  },
2159
2303
  footer && {
2160
2304
  t: 'div',
2161
- a: { class: 'bw_modal_footer' },
2305
+ a: { class: 'bw_bccl_modal_footer' },
2162
2306
  c: footer
2163
2307
  }
2164
2308
  ].filter(Boolean)
@@ -2168,25 +2312,36 @@
2168
2312
  type: 'modal',
2169
2313
  handle: {
2170
2314
  open: function(el) {
2171
- el.classList.add('bw_modal_show');
2315
+ el._bw_opener = document.activeElement;
2316
+ el.classList.add('bw_bccl_modal_show');
2172
2317
  el.style.display = 'flex';
2318
+ var dialog = el.querySelector('[role="dialog"]');
2319
+ if (dialog) dialog.setAttribute('aria-modal', 'true');
2173
2320
  document.body.style.overflow = 'hidden';
2174
2321
  },
2175
2322
  close: function(el) { closeModal(el); }
2176
2323
  },
2177
2324
  mounted: function(el) {
2325
+ // Record the opener (the element that had focus when modal was mounted)
2326
+ el._bw_opener = document.activeElement;
2178
2327
  // Click backdrop to close
2179
2328
  el.addEventListener('click', function(e) {
2180
2329
  if (e.target === el) closeModal(el);
2181
2330
  });
2182
- // Escape key to close
2331
+ // Escape key to close — listen on the element and on the document
2183
2332
  var escHandler = function(e) {
2184
- if (e.key === 'Escape' && el.classList.contains('bw_modal_show')) {
2333
+ if (e.key === 'Escape') {
2334
+ closeModal(el);
2335
+ }
2336
+ };
2337
+ el.addEventListener('keydown', escHandler);
2338
+ var docEscHandler = function(e) {
2339
+ if (e.key === 'Escape' && (el.classList.contains('bw_bccl_modal_show') || el.style.display === 'flex')) {
2185
2340
  closeModal(el);
2186
2341
  }
2187
2342
  };
2188
- document.addEventListener('keydown', escHandler);
2189
- el._bw_escHandler = escHandler;
2343
+ document.addEventListener('keydown', docEscHandler);
2344
+ el._bw_escHandler = docEscHandler;
2190
2345
  },
2191
2346
  unmount: function(el) {
2192
2347
  if (el._bw_escHandler) {
@@ -2232,13 +2387,13 @@
2232
2387
  return {
2233
2388
  t: 'div',
2234
2389
  a: {
2235
- class: `bw_toast ${variantClass(variant)} bw_toast_${position.replace(/-/g, '_')} ${className}`.trim(),
2390
+ class: `bw_bccl_toast ${variantClass(variant)} bw_bccl_toast_${position.replace(/-/g, '_')} ${className}`.trim(),
2236
2391
  role: 'alert'
2237
2392
  },
2238
2393
  c: [
2239
2394
  (title) && {
2240
2395
  t: 'div',
2241
- a: { class: 'bw_toast_header' },
2396
+ a: { class: 'bw_bccl_toast_header' },
2242
2397
  c: [
2243
2398
  { t: 'strong', c: title },
2244
2399
  {
@@ -2248,9 +2403,9 @@
2248
2403
  class: 'bw_close',
2249
2404
  'aria-label': 'Close',
2250
2405
  onclick: function(e) {
2251
- var toast = e.target.closest('.bw_toast');
2406
+ var toast = e.target.closest('.bw_bccl_toast');
2252
2407
  if (toast) {
2253
- toast.classList.add('bw_toast_hiding');
2408
+ toast.classList.add('bw_bccl_toast_hiding');
2254
2409
  setTimeout(function() { if (toast.parentNode) toast.parentNode.removeChild(toast); }, 300);
2255
2410
  }
2256
2411
  }
@@ -2261,7 +2416,7 @@
2261
2416
  },
2262
2417
  content && {
2263
2418
  t: 'div',
2264
- a: { class: 'bw_toast_body' },
2419
+ a: { class: 'bw_bccl_toast_body' },
2265
2420
  c: content
2266
2421
  }
2267
2422
  ].filter(Boolean),
@@ -2269,19 +2424,20 @@
2269
2424
  type: 'toast',
2270
2425
  handle: {
2271
2426
  dismiss: function(el) {
2272
- el.classList.add('bw_toast_hiding');
2427
+ el.classList.add('bw_bccl_toast_hiding');
2428
+ /* c8 ignore next -- setTimeout callback; requires real timer advancement */
2273
2429
  setTimeout(function() { if (el.parentNode) el.parentNode.removeChild(el); }, 300);
2274
2430
  }
2275
2431
  },
2276
2432
  mounted: function(el) {
2277
2433
  // Trigger show animation
2278
2434
  requestAnimationFrame(function() {
2279
- el.classList.add('bw_toast_show');
2435
+ el.classList.add('bw_bccl_toast_show');
2280
2436
  });
2281
2437
  // Auto-dismiss
2282
2438
  if (autoDismiss) {
2283
2439
  setTimeout(function() {
2284
- el.classList.add('bw_toast_hiding');
2440
+ el.classList.add('bw_bccl_toast_hiding');
2285
2441
  setTimeout(function() { if (el.parentNode) el.parentNode.removeChild(el); }, 300);
2286
2442
  }, delay);
2287
2443
  }
@@ -2334,12 +2490,12 @@
2334
2490
  triggerTaco = {
2335
2491
  t: 'button',
2336
2492
  a: {
2337
- class: `bw_btn ${variantClass(variant)} bw_dropdown_toggle`,
2493
+ class: `bw_bccl_btn ${variantClass(variant)} bw_bccl_dropdown_toggle`,
2338
2494
  type: 'button',
2339
2495
  onclick: function(e) {
2340
- var dropdown = e.target.closest('.bw_dropdown');
2341
- var menu = dropdown.querySelector('.bw_dropdown_menu');
2342
- menu.classList.toggle('bw_dropdown_show');
2496
+ var dropdown = e.target.closest('.bw_bccl_dropdown');
2497
+ var menu = dropdown.querySelector('.bw_bccl_dropdown_menu');
2498
+ menu.classList.toggle('bw_bccl_dropdown_show');
2343
2499
  }
2344
2500
  },
2345
2501
  c: trigger || 'Dropdown'
@@ -2350,26 +2506,26 @@
2350
2506
 
2351
2507
  return {
2352
2508
  t: 'div',
2353
- a: { class: `bw_dropdown ${className}`.trim() },
2509
+ a: { class: `bw_bccl_dropdown ${className}`.trim() },
2354
2510
  c: [
2355
2511
  triggerTaco,
2356
2512
  {
2357
2513
  t: 'div',
2358
- a: { class: `bw_dropdown_menu ${align === 'end' ? 'bw_dropdown_menu_end' : ''}`.trim() },
2514
+ a: { class: `bw_bccl_dropdown_menu ${align === 'end' ? 'bw_bccl_dropdown_menu_end' : ''}`.trim() },
2359
2515
  c: items.map(function(item) {
2360
2516
  if (item.divider) {
2361
- return { t: 'hr', a: { class: 'bw_dropdown_divider' } };
2517
+ return { t: 'hr', a: { class: 'bw_bccl_dropdown_divider' } };
2362
2518
  }
2363
2519
  return {
2364
2520
  t: 'a',
2365
2521
  a: {
2366
- class: `bw_dropdown_item ${item.disabled ? 'disabled' : ''}`.trim(),
2522
+ class: `bw_bccl_dropdown_item ${item.disabled ? 'disabled' : ''}`.trim(),
2367
2523
  href: item.href || '#',
2368
2524
  onclick: item.disabled ? undefined : function(e) {
2369
2525
  if (!item.href) e.preventDefault();
2370
- var dropdown = e.target.closest('.bw_dropdown');
2371
- var menu = dropdown.querySelector('.bw_dropdown_menu');
2372
- menu.classList.remove('bw_dropdown_show');
2526
+ var dropdown = e.target.closest('.bw_bccl_dropdown');
2527
+ var menu = dropdown.querySelector('.bw_bccl_dropdown_menu');
2528
+ menu.classList.remove('bw_bccl_dropdown_show');
2373
2529
  if (item.onclick) item.onclick(e);
2374
2530
  }
2375
2531
  },
@@ -2384,8 +2540,8 @@
2384
2540
  // Click outside to close
2385
2541
  var outsideHandler = function(e) {
2386
2542
  if (!el.contains(e.target)) {
2387
- var menu = el.querySelector('.bw_dropdown_menu');
2388
- if (menu) menu.classList.remove('bw_dropdown_show');
2543
+ var menu = el.querySelector('.bw_bccl_dropdown_menu');
2544
+ if (menu) menu.classList.remove('bw_bccl_dropdown_show');
2389
2545
  }
2390
2546
  };
2391
2547
  document.addEventListener('click', outsideHandler);
@@ -2432,13 +2588,13 @@
2432
2588
 
2433
2589
  return {
2434
2590
  t: 'div',
2435
- a: { class: `bw_form_check bw_form_switch ${className}`.trim() },
2591
+ a: { class: `bw_bccl_form_check bw_bccl_form_switch ${className}`.trim() },
2436
2592
  c: [
2437
2593
  {
2438
2594
  t: 'input',
2439
2595
  a: {
2440
2596
  type: 'checkbox',
2441
- class: 'bw_form_check_input bw_switch_input',
2597
+ class: 'bw_bccl_form_check_input bw_switch_input',
2442
2598
  role: 'switch',
2443
2599
  checked,
2444
2600
  id,
@@ -2449,7 +2605,7 @@
2449
2605
  },
2450
2606
  label && {
2451
2607
  t: 'label',
2452
- a: { class: 'bw_form_check_label', for: id },
2608
+ a: { class: 'bw_bccl_form_check_label', for: id },
2453
2609
  c: label
2454
2610
  }
2455
2611
  ].filter(Boolean)
@@ -2484,7 +2640,7 @@
2484
2640
  return {
2485
2641
  t: 'div',
2486
2642
  a: {
2487
- class: `bw_skeleton bw_skeleton_circle ${className}`.trim(),
2643
+ class: `bw_bccl_skeleton bw_skeleton bw_skeleton_circle ${className}`.trim(),
2488
2644
  style: { width: circleSize, height: circleSize }
2489
2645
  }
2490
2646
  };
@@ -2494,7 +2650,7 @@
2494
2650
  return {
2495
2651
  t: 'div',
2496
2652
  a: {
2497
- class: `bw_skeleton bw_skeleton_rect ${className}`.trim(),
2653
+ class: `bw_bccl_skeleton bw_skeleton bw_skeleton_rect ${className}`.trim(),
2498
2654
  style: {
2499
2655
  width: width || '100%',
2500
2656
  height: height || '120px'
@@ -2508,7 +2664,7 @@
2508
2664
  return {
2509
2665
  t: 'div',
2510
2666
  a: {
2511
- class: `bw_skeleton bw_skeleton_text ${className}`.trim(),
2667
+ class: `bw_bccl_skeleton bw_skeleton bw_skeleton_text ${className}`.trim(),
2512
2668
  style: {
2513
2669
  width: width || '100%',
2514
2670
  height: height || '1em'
@@ -2533,7 +2689,7 @@
2533
2689
 
2534
2690
  return {
2535
2691
  t: 'div',
2536
- a: { class: `bw_skeleton_group ${className}`.trim() },
2692
+ a: { class: `bw_bccl_skeleton bw_skeleton_group ${className}`.trim() },
2537
2693
  c: lines
2538
2694
  };
2539
2695
  }
@@ -2568,7 +2724,7 @@
2568
2724
  return {
2569
2725
  t: 'img',
2570
2726
  a: {
2571
- class: `bw_avatar bw_avatar_${size} ${className}`.trim(),
2727
+ class: `bw_bccl_avatar bw_avatar bw_avatar_${size} ${className}`.trim(),
2572
2728
  src: src,
2573
2729
  alt: alt
2574
2730
  }
@@ -2578,7 +2734,7 @@
2578
2734
  return {
2579
2735
  t: 'div',
2580
2736
  a: {
2581
- class: `bw_avatar bw_avatar_${size} ${variantClass(variant)} ${className}`.trim()
2737
+ class: `bw_bccl_avatar bw_avatar bw_avatar_${size} ${variantClass(variant)} ${className}`.trim()
2582
2738
  },
2583
2739
  c: initials || ''
2584
2740
  };
@@ -2622,19 +2778,21 @@
2622
2778
  interval = 5000,
2623
2779
  height = '300px',
2624
2780
  startIndex = 0,
2781
+ prevLabel = 'Previous slide',
2782
+ nextLabel = 'Next slide',
2625
2783
  className = ''
2626
2784
  } = props;
2627
2785
 
2628
2786
  // Shared navigation logic
2629
2787
  function goToSlide(carouselEl, index) {
2630
- var total = carouselEl.querySelectorAll('.bw_carousel_slide').length;
2788
+ var total = carouselEl.querySelectorAll('.bw_bccl_carousel_slide').length;
2631
2789
  if (index < 0) index = total - 1;
2632
2790
  if (index >= total) index = 0;
2633
2791
  carouselEl._bw_carouselIndex = index;
2634
- var track = carouselEl.querySelector('.bw_carousel_track');
2792
+ var track = carouselEl.querySelector('.bw_bccl_carousel_track');
2635
2793
  track.style.transform = 'translateX(-' + (index * 100) + '%)';
2636
2794
  // Update indicators
2637
- var indicators = carouselEl.querySelectorAll('.bw_carousel_indicator');
2795
+ var indicators = carouselEl.querySelectorAll('.bw_bccl_carousel_indicator');
2638
2796
  for (var i = 0; i < indicators.length; i++) {
2639
2797
  if (i === index) {
2640
2798
  indicators[i].classList.add('active');
@@ -2653,14 +2811,14 @@
2653
2811
  item.content,
2654
2812
  item.caption && {
2655
2813
  t: 'div',
2656
- a: { class: 'bw_carousel_caption' },
2814
+ a: { class: 'bw_bccl_carousel_caption' },
2657
2815
  c: item.caption
2658
2816
  }
2659
2817
  ].filter(Boolean);
2660
2818
 
2661
2819
  return {
2662
2820
  t: 'div',
2663
- a: { class: 'bw_carousel_slide' },
2821
+ a: { class: 'bw_bccl_carousel_slide' },
2664
2822
  c: slideContent.length === 1 ? slideContent[0] : slideContent
2665
2823
  };
2666
2824
  });
@@ -2670,7 +2828,7 @@
2670
2828
  {
2671
2829
  t: 'div',
2672
2830
  a: {
2673
- class: 'bw_carousel_track',
2831
+ class: 'bw_bccl_carousel_track',
2674
2832
  style: 'transform: translateX(-' + (startIndex * 100) + '%)'
2675
2833
  },
2676
2834
  c: slides
@@ -2682,30 +2840,31 @@
2682
2840
  children.push({
2683
2841
  t: 'button',
2684
2842
  a: {
2685
- class: 'bw_carousel_control bw_carousel_control_prev',
2843
+ class: 'bw_bccl_carousel_control bw_bccl_carousel_control_prev',
2686
2844
  type: 'button',
2687
- 'aria-label': 'Previous slide',
2845
+ 'aria-label': prevLabel,
2688
2846
  onclick: function(e) {
2689
- var carousel = e.target.closest('.bw_carousel');
2847
+ var carousel = e.target.closest('.bw_bccl_carousel');
2848
+ /* c8 ignore next -- carousel index fallback; default 0 */
2690
2849
  var idx = carousel._bw_carouselIndex || 0;
2691
2850
  goToSlide(carousel, idx - 1);
2692
2851
  }
2693
2852
  },
2694
- c: { t: 'img', a: { src: prevArrow, alt: '', role: 'presentation' } }
2853
+ c: [{ t: 'img', a: { src: prevArrow, alt: '', role: 'presentation' } }, { t: 'span', a: { class: 'bw_visually_hidden' }, c: prevLabel }]
2695
2854
  });
2696
2855
  children.push({
2697
2856
  t: 'button',
2698
2857
  a: {
2699
- class: 'bw_carousel_control bw_carousel_control_next',
2858
+ class: 'bw_bccl_carousel_control bw_bccl_carousel_control_next',
2700
2859
  type: 'button',
2701
- 'aria-label': 'Next slide',
2860
+ 'aria-label': nextLabel,
2702
2861
  onclick: function(e) {
2703
- var carousel = e.target.closest('.bw_carousel');
2862
+ var carousel = e.target.closest('.bw_bccl_carousel');
2704
2863
  var idx = carousel._bw_carouselIndex || 0;
2705
2864
  goToSlide(carousel, idx + 1);
2706
2865
  }
2707
2866
  },
2708
- c: { t: 'img', a: { src: nextArrow, alt: '', role: 'presentation' } }
2867
+ c: [{ t: 'img', a: { src: nextArrow, alt: '', role: 'presentation' } }, { t: 'span', a: { class: 'bw_visually_hidden' }, c: nextLabel }]
2709
2868
  });
2710
2869
  }
2711
2870
 
@@ -2713,16 +2872,16 @@
2713
2872
  if (showIndicators && items.length > 1) {
2714
2873
  children.push({
2715
2874
  t: 'div',
2716
- a: { class: 'bw_carousel_indicators' },
2875
+ a: { class: 'bw_bccl_carousel_indicators' },
2717
2876
  c: items.map(function(_, i) {
2718
2877
  return {
2719
2878
  t: 'button',
2720
2879
  a: {
2721
- class: 'bw_carousel_indicator' + (i === startIndex ? ' active' : ''),
2880
+ class: 'bw_bccl_carousel_indicator' + (i === startIndex ? ' active' : ''),
2722
2881
  type: 'button',
2723
2882
  'aria-label': 'Go to slide ' + (i + 1),
2724
2883
  onclick: function(e) {
2725
- var carousel = e.target.closest('.bw_carousel');
2884
+ var carousel = e.target.closest('.bw_bccl_carousel');
2726
2885
  goToSlide(carousel, i);
2727
2886
  }
2728
2887
  }
@@ -2734,7 +2893,7 @@
2734
2893
  return {
2735
2894
  t: 'div',
2736
2895
  a: {
2737
- class: ('bw_carousel ' + className).trim(),
2896
+ class: ('bw_bccl_carousel ' + className).trim(),
2738
2897
  style: 'height: ' + height,
2739
2898
  tabindex: '0',
2740
2899
  'aria-roledescription': 'carousel'
@@ -2746,6 +2905,7 @@
2746
2905
  handle: {
2747
2906
  goToSlide: function(el, index) { goToSlide(el, index); },
2748
2907
  next: function(el) { goToSlide(el, (el._bw_carouselIndex || 0) + 1); },
2908
+ /* c8 ignore next -- carousel index fallback */
2749
2909
  prev: function(el) { goToSlide(el, (el._bw_carouselIndex || 0) - 1); },
2750
2910
  getActiveIndex: function(el) { return el._bw_carouselIndex || 0; },
2751
2911
  pause: function(el) {
@@ -2756,6 +2916,7 @@
2756
2916
  },
2757
2917
  play: function(el) {
2758
2918
  if (!el._bw_carouselInterval && el._bw_state) {
2919
+ /* c8 ignore next -- interval fallback to default 5000ms */
2759
2920
  var ms = el._bw_state.interval || 5000;
2760
2921
  el._bw_carouselInterval = setInterval(function() {
2761
2922
  goToSlide(el, (el._bw_carouselIndex || 0) + 1);
@@ -2862,7 +3023,7 @@
2862
3023
  }
2863
3024
 
2864
3025
  var classes = [
2865
- 'bw_stat_card',
3026
+ 'bw_bccl_statCard bw_stat_card',
2866
3027
  variantClass(variant),
2867
3028
  className
2868
3029
  ].filter(Boolean).join(' ').trim();
@@ -2950,13 +3111,13 @@
2950
3111
 
2951
3112
  return {
2952
3113
  t: 'span',
2953
- a: { class: ('bw_tooltip_wrapper ' + className).trim() },
3114
+ a: { class: ('bw_bccl_tooltip_wrapper ' + className).trim() },
2954
3115
  c: [
2955
3116
  content,
2956
3117
  {
2957
3118
  t: 'span',
2958
3119
  a: {
2959
- class: 'bw_tooltip bw_tooltip_' + placement,
3120
+ class: 'bw_bccl_tooltip bw_bccl_tooltip_' + placement,
2960
3121
  role: 'tooltip'
2961
3122
  },
2962
3123
  c: text
@@ -2965,18 +3126,18 @@
2965
3126
  o: {
2966
3127
  type: 'tooltip',
2967
3128
  mounted: function(el) {
2968
- var tip = el.querySelector('.bw_tooltip');
3129
+ var tip = el.querySelector('.bw_bccl_tooltip');
2969
3130
  el.addEventListener('mouseenter', function() {
2970
- tip.classList.add('bw_tooltip_show');
3131
+ tip.classList.add('bw_bccl_tooltip_show');
2971
3132
  });
2972
3133
  el.addEventListener('mouseleave', function() {
2973
- tip.classList.remove('bw_tooltip_show');
3134
+ tip.classList.remove('bw_bccl_tooltip_show');
2974
3135
  });
2975
3136
  el.addEventListener('focusin', function() {
2976
- tip.classList.add('bw_tooltip_show');
3137
+ tip.classList.add('bw_bccl_tooltip_show');
2977
3138
  });
2978
3139
  el.addEventListener('focusout', function() {
2979
- tip.classList.remove('bw_tooltip_show');
3140
+ tip.classList.remove('bw_bccl_tooltip_show');
2980
3141
  });
2981
3142
  }
2982
3143
  }
@@ -3029,7 +3190,7 @@
3029
3190
 
3030
3191
  return {
3031
3192
  t: 'span',
3032
- a: { class: ('bw_popover_wrapper ' + className).trim() },
3193
+ a: { class: ('bw_bccl_popover bw_popover_wrapper ' + className).trim() },
3033
3194
  c: [
3034
3195
  {
3035
3196
  t: 'span',
@@ -3113,13 +3274,13 @@
3113
3274
 
3114
3275
  return {
3115
3276
  t: 'div',
3116
- a: { class: ('bw_search_input ' + className).trim() },
3277
+ a: { class: ('bw_bccl_searchInput bw_search_input ' + className).trim() },
3117
3278
  c: [
3118
3279
  {
3119
3280
  t: 'input',
3120
3281
  a: {
3121
3282
  type: 'search',
3122
- class: 'bw_form_control bw_search_field',
3283
+ class: 'bw_bccl_form_control bw_search_field',
3123
3284
  placeholder: placeholder,
3124
3285
  value: value,
3125
3286
  id: id,
@@ -3256,7 +3417,7 @@
3256
3417
 
3257
3418
  return {
3258
3419
  t: 'div',
3259
- a: { class: ('bw_range_wrapper ' + className).trim() },
3420
+ a: { class: ('bw_bccl_range bw_range_wrapper ' + className).trim() },
3260
3421
  c: children,
3261
3422
  o: { type: 'range' }
3262
3423
  };
@@ -3317,7 +3478,7 @@
3317
3478
 
3318
3479
  return {
3319
3480
  t: 'div',
3320
- a: { class: ('bw_media ' + (reverse ? 'bw_media_reverse ' : '') + className).trim() },
3481
+ a: { class: ('bw_bccl_mediaObject bw_media ' + (reverse ? 'bw_media_reverse ' : '') + className).trim() },
3321
3482
  c: reverse
3322
3483
  ? [bodyEl, imgEl].filter(Boolean)
3323
3484
  : [imgEl, bodyEl].filter(Boolean),
@@ -3360,7 +3521,7 @@
3360
3521
  return {
3361
3522
  t: 'div',
3362
3523
  a: {
3363
- class: ('bw_file_upload ' + className).trim(),
3524
+ class: ('bw_bccl_fileUpload bw_file_upload ' + className).trim(),
3364
3525
  tabindex: '0',
3365
3526
  role: 'button',
3366
3527
  'aria-label': text
@@ -3454,32 +3615,32 @@
3454
3615
 
3455
3616
  return {
3456
3617
  t: 'div',
3457
- a: { class: ('bw_timeline ' + className).trim() },
3618
+ a: { class: ('bw_bccl_timeline ' + className).trim() },
3458
3619
  c: items.map(function(item) {
3459
3620
  return {
3460
3621
  t: 'div',
3461
- a: { class: 'bw_timeline_item' },
3622
+ a: { class: 'bw_bccl_timeline_item' },
3462
3623
  c: [
3463
3624
  {
3464
3625
  t: 'div',
3465
- a: { class: 'bw_timeline_marker ' + variantClass(item.variant || 'primary') }
3626
+ a: { class: 'bw_bccl_timeline_marker ' + variantClass(item.variant || 'primary') }
3466
3627
  },
3467
3628
  {
3468
3629
  t: 'div',
3469
- a: { class: 'bw_timeline_content' },
3630
+ a: { class: 'bw_bccl_timeline_content' },
3470
3631
  c: [
3471
3632
  item.date && {
3472
3633
  t: 'div',
3473
- a: { class: 'bw_timeline_date' },
3634
+ a: { class: 'bw_bccl_timeline_date' },
3474
3635
  c: item.date
3475
3636
  },
3476
3637
  item.title && {
3477
3638
  t: 'h5',
3478
- a: { class: 'bw_timeline_title' },
3639
+ a: { class: 'bw_bccl_timeline_title' },
3479
3640
  c: item.title
3480
3641
  },
3481
3642
  item.content && (typeof item.content === 'string'
3482
- ? { t: 'p', a: { class: 'bw_timeline_text' }, c: item.content }
3643
+ ? { t: 'p', a: { class: 'bw_bccl_timeline_text' }, c: item.content }
3483
3644
  : item.content)
3484
3645
  ].filter(Boolean)
3485
3646
  }
@@ -3524,7 +3685,7 @@
3524
3685
 
3525
3686
  return {
3526
3687
  t: 'div',
3527
- a: { class: ('bw_stepper ' + className).trim(), role: 'list' },
3688
+ a: { class: ('bw_bccl_stepper bw_stepper ' + className).trim(), role: 'list' },
3528
3689
  c: steps.map(function(step, index) {
3529
3690
  var state = index < currentStep ? 'completed' : index === currentStep ? 'active' : 'pending';
3530
3691
  return {
@@ -3613,7 +3774,7 @@
3613
3774
 
3614
3775
  return {
3615
3776
  t: 'div',
3616
- a: { class: ('bw_chip_input ' + className).trim() },
3777
+ a: { class: ('bw_bccl_chipInput bw_chip_input ' + className).trim() },
3617
3778
  c: [
3618
3779
  ...chips.map(makeChipEl),
3619
3780
  {
@@ -3649,8 +3810,8 @@
3649
3810
  }
3650
3811
  // Backspace on empty input removes last chip
3651
3812
  if (e.key === 'Backspace' && !e.target.value) {
3652
- var wrapper = e.target.closest('.bw_chip_input');
3653
- var chipEls = wrapper.querySelectorAll('.bw_chip');
3813
+ var chipWrapper = e.target.closest('.bw_chip_input');
3814
+ var chipEls = chipWrapper.querySelectorAll('.bw_chip');
3654
3815
  if (chipEls.length) {
3655
3816
  var last = chipEls[chipEls.length - 1];
3656
3817
  var removedVal = last._bw_chipValue || last.firstChild.textContent;
@@ -3900,13 +4061,13 @@
3900
4061
  bw.variantClass = variantClass;
3901
4062
 
3902
4063
  // Create functions that return DOM elements
3903
- if (typeof bw.createDOM === 'function') {
4064
+ if (typeof bw.create === 'function') {
3904
4065
  Object.entries(components).forEach(function(entry) {
3905
4066
  var name = entry[0], fn = entry[1];
3906
4067
  if (name.indexOf('make') === 0) {
3907
4068
  var createName = 'create' + name.substring(4);
3908
4069
  bw[createName] = function(props) {
3909
- return bw.createDOM(fn(props));
4070
+ return bw.create(fn(props));
3910
4071
  };
3911
4072
  }
3912
4073
  });