bitwrench 2.0.17 → 2.0.19

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 (72) hide show
  1. package/README.md +169 -75
  2. package/dist/bitwrench-bccl.cjs.js +228 -55
  3. package/dist/bitwrench-bccl.cjs.min.js +3 -3
  4. package/dist/bitwrench-bccl.esm.js +228 -55
  5. package/dist/bitwrench-bccl.esm.min.js +3 -3
  6. package/dist/bitwrench-bccl.umd.js +228 -55
  7. package/dist/bitwrench-bccl.umd.min.js +3 -3
  8. package/dist/bitwrench-code-edit.cjs.js +7 -9
  9. package/dist/bitwrench-code-edit.cjs.min.js +5 -7
  10. package/dist/bitwrench-code-edit.es5.js +6 -8
  11. package/dist/bitwrench-code-edit.es5.min.js +5 -7
  12. package/dist/bitwrench-code-edit.esm.js +7 -9
  13. package/dist/bitwrench-code-edit.esm.min.js +5 -7
  14. package/dist/bitwrench-code-edit.umd.js +7 -9
  15. package/dist/bitwrench-code-edit.umd.min.js +5 -7
  16. package/dist/bitwrench-debug.js +268 -0
  17. package/dist/bitwrench-debug.min.js +3 -0
  18. package/dist/bitwrench-lean.cjs.js +1190 -2348
  19. package/dist/bitwrench-lean.cjs.min.js +20 -20
  20. package/dist/bitwrench-lean.es5.js +1285 -2551
  21. package/dist/bitwrench-lean.es5.min.js +18 -18
  22. package/dist/bitwrench-lean.esm.js +1190 -2348
  23. package/dist/bitwrench-lean.esm.min.js +20 -20
  24. package/dist/bitwrench-lean.umd.js +1190 -2348
  25. package/dist/bitwrench-lean.umd.min.js +20 -20
  26. package/dist/bitwrench-util-css.cjs.js +236 -0
  27. package/dist/bitwrench-util-css.cjs.min.js +22 -0
  28. package/dist/bitwrench-util-css.es5.js +414 -0
  29. package/dist/bitwrench-util-css.es5.min.js +21 -0
  30. package/dist/bitwrench-util-css.esm.js +230 -0
  31. package/dist/bitwrench-util-css.esm.min.js +21 -0
  32. package/dist/bitwrench-util-css.umd.js +242 -0
  33. package/dist/bitwrench-util-css.umd.min.js +21 -0
  34. package/dist/bitwrench.cjs.js +1404 -2388
  35. package/dist/bitwrench.cjs.min.js +21 -21
  36. package/dist/bitwrench.css +503 -132
  37. package/dist/bitwrench.es5.js +1588 -2659
  38. package/dist/bitwrench.es5.min.js +19 -19
  39. package/dist/bitwrench.esm.js +1405 -2389
  40. package/dist/bitwrench.esm.min.js +21 -21
  41. package/dist/bitwrench.min.css +1 -1
  42. package/dist/bitwrench.umd.js +1404 -2388
  43. package/dist/bitwrench.umd.min.js +21 -21
  44. package/dist/builds.json +214 -104
  45. package/dist/bwserve.cjs.js +514 -68
  46. package/dist/bwserve.esm.js +513 -69
  47. package/dist/sri.json +46 -36
  48. package/package.json +6 -3
  49. package/readme.html +183 -85
  50. package/src/bitwrench-bccl-entry.js +3 -4
  51. package/src/bitwrench-bccl.js +224 -50
  52. package/src/bitwrench-code-edit.js +6 -8
  53. package/src/bitwrench-color-utils.js +31 -9
  54. package/src/bitwrench-debug.js +245 -0
  55. package/src/bitwrench-esm-entry.js +11 -0
  56. package/src/bitwrench-styles.js +474 -240
  57. package/src/bitwrench-util-css.js +229 -0
  58. package/src/bitwrench.js +689 -2042
  59. package/src/bwserve/attach.js +57 -0
  60. package/src/bwserve/bwclient.js +141 -0
  61. package/src/bwserve/bwshell.js +102 -0
  62. package/src/bwserve/client.js +151 -1
  63. package/src/bwserve/index.js +127 -28
  64. package/src/cli/attach.js +587 -0
  65. package/src/cli/convert.js +2 -5
  66. package/src/cli/index.js +7 -0
  67. package/src/cli/inject.js +1 -1
  68. package/src/cli/serve.js +185 -5
  69. package/src/generate-css.js +11 -4
  70. package/src/vendor/html2canvas.min.js +20 -0
  71. package/src/version.js +3 -3
  72. package/src/bwserve/shell.js +0 -106
@@ -1,4 +1,4 @@
1
- /*! bitwrench-bccl v2.0.17 | BSD-2-Clause | https://deftio.github.com/bitwrench/pages */
1
+ /*! bitwrench-bccl v2.0.19 | BSD-2-Clause | https://deftio.github.com/bitwrench/pages */
2
2
  'use strict';
3
3
 
4
4
  /**
@@ -175,7 +175,12 @@ function makeCard(props = {}) {
175
175
  },
176
176
  o: {
177
177
  type: 'card',
178
- state: props.state || {}
178
+ state: props.state || {},
179
+ slots: {
180
+ title: '.bw_card_title',
181
+ content: '.bw_card_body',
182
+ footer: '.bw_card_footer'
183
+ }
179
184
  }
180
185
  };
181
186
  }
@@ -186,7 +191,12 @@ function makeCard(props = {}) {
186
191
  c: cardContent,
187
192
  o: {
188
193
  type: 'card',
189
- state: props.state || {}
194
+ state: props.state || {},
195
+ slots: {
196
+ title: '.bw_card_title',
197
+ content: '.bw_card_body',
198
+ footer: '.bw_card_footer'
199
+ }
190
200
  }
191
201
  };
192
202
  }
@@ -330,7 +340,7 @@ function makeCol(props = {}) {
330
340
  if (breakpoint === 'xs') {
331
341
  classes.push(`bw_col_${value}`);
332
342
  } else {
333
- classes.push(`bw_col_${breakpoint}-${value}`);
343
+ classes.push(`bw_col_${breakpoint}_${value}`);
334
344
  }
335
345
  });
336
346
  } else if (size) {
@@ -504,6 +514,24 @@ function makeTabs(props = {}) {
504
514
  }
505
515
  });
506
516
 
517
+ // Shared tab switching logic
518
+ function switchTab(el, index) {
519
+ var allTabs = el.querySelectorAll('.bw_nav_link');
520
+ var allPanes = el.querySelectorAll('.bw_tab_pane');
521
+ if (index < 0 || index >= allTabs.length) return;
522
+ allTabs.forEach(function(t) {
523
+ t.classList.remove('active');
524
+ t.setAttribute('aria-selected', 'false');
525
+ t.setAttribute('tabindex', '-1');
526
+ });
527
+ allPanes.forEach(function(p) { p.classList.remove('active'); });
528
+ allTabs[index].classList.add('active');
529
+ allTabs[index].setAttribute('aria-selected', 'true');
530
+ allTabs[index].setAttribute('tabindex', '0');
531
+ allPanes[index].classList.add('active');
532
+ if (el._bw_state) el._bw_state.activeIndex = index;
533
+ }
534
+
507
535
  return {
508
536
  t: 'div',
509
537
  a: { class: 'bw_tabs' },
@@ -522,24 +550,8 @@ function makeTabs(props = {}) {
522
550
  role: 'tab',
523
551
  tabindex: index === actualActiveIndex ? '0' : '-1',
524
552
  'aria-selected': index === actualActiveIndex ? 'true' : 'false',
525
- 'data-tab-index': index,
526
553
  onclick: (e) => {
527
- const tabsContainer = e.target.closest('.bw_tabs');
528
- const allTabs = tabsContainer.querySelectorAll('.bw_nav_link');
529
- const allPanes = tabsContainer.querySelectorAll('.bw_tab_pane');
530
-
531
- allTabs.forEach(t => {
532
- t.classList.remove('active');
533
- t.setAttribute('aria-selected', 'false');
534
- t.setAttribute('tabindex', '-1');
535
- });
536
- allPanes.forEach(p => p.classList.remove('active'));
537
-
538
- e.target.classList.add('active');
539
- e.target.setAttribute('aria-selected', 'true');
540
- e.target.setAttribute('tabindex', '0');
541
- const targetIndex = parseInt(e.target.getAttribute('data-tab-index'));
542
- allPanes[targetIndex].classList.add('active');
554
+ switchTab(e.target.closest('.bw_tabs'), index);
543
555
  }
544
556
  },
545
557
  c: tab.label
@@ -562,6 +574,10 @@ function makeTabs(props = {}) {
562
574
  o: {
563
575
  type: 'tabs',
564
576
  state: { activeIndex: actualActiveIndex },
577
+ handle: {
578
+ setActiveTab: switchTab,
579
+ getActiveTab: function(el) { return (el._bw_state && el._bw_state.activeIndex) || 0; }
580
+ },
565
581
  mounted: function(el) {
566
582
  var tablist = el.querySelector('[role="tablist"]');
567
583
  if (!tablist) return;
@@ -647,7 +663,13 @@ function makeAlert(props = {}) {
647
663
  },
648
664
  c: '×'
649
665
  }
650
- ].filter(Boolean)
666
+ ].filter(Boolean),
667
+ o: {
668
+ type: 'alert',
669
+ handle: {
670
+ dismiss: function(el) { if (el && el.parentNode) el.parentNode.removeChild(el); }
671
+ }
672
+ }
651
673
  };
652
674
  }
653
675
 
@@ -745,6 +767,24 @@ function makeProgress(props = {}) {
745
767
  'aria-valuemax': max
746
768
  },
747
769
  c: label || `${percentage}%`
770
+ },
771
+ o: {
772
+ type: 'progress',
773
+ handle: {
774
+ setValue: function(el, n) {
775
+ var bar = el.querySelector('.bw_progress_bar');
776
+ if (!bar) return;
777
+ var maxVal = parseInt(bar.getAttribute('aria-valuemax')) || 100;
778
+ var pct = Math.round((n / maxVal) * 100);
779
+ bar.style.width = pct + '%';
780
+ bar.setAttribute('aria-valuenow', n);
781
+ bar.textContent = pct + '%';
782
+ },
783
+ getValue: function(el) {
784
+ var bar = el.querySelector('.bw_progress_bar');
785
+ return bar ? parseInt(bar.getAttribute('aria-valuenow')) || 0 : 0;
786
+ }
787
+ }
748
788
  }
749
789
  };
750
790
  }
@@ -1713,8 +1753,8 @@ function makePagination(props = {}) {
1713
1753
  t: 'li',
1714
1754
  a: { class: `bw_page_item ${currentPage <= 1 ? 'bw_disabled' : ''}`.trim() },
1715
1755
  c: {
1716
- t: 'a',
1717
- a: { class: 'bw_page_link', href: '#', onclick: handleClick(currentPage - 1), 'aria-label': 'Previous' },
1756
+ t: 'button',
1757
+ a: { class: 'bw_page_link', type: 'button', onclick: handleClick(currentPage - 1), 'aria-label': 'Previous', disabled: currentPage <= 1 ? true : undefined },
1718
1758
  c: '\u2039'
1719
1759
  }
1720
1760
  });
@@ -1726,8 +1766,8 @@ function makePagination(props = {}) {
1726
1766
  t: 'li',
1727
1767
  a: { class: `bw_page_item ${pageNum === currentPage ? 'bw_active' : ''}`.trim() },
1728
1768
  c: {
1729
- t: 'a',
1730
- a: { class: 'bw_page_link', href: '#', onclick: handleClick(pageNum) },
1769
+ t: 'button',
1770
+ a: { class: 'bw_page_link', type: 'button', onclick: handleClick(pageNum), 'aria-current': pageNum === currentPage ? 'page' : undefined },
1731
1771
  c: '' + pageNum
1732
1772
  }
1733
1773
  });
@@ -1739,8 +1779,8 @@ function makePagination(props = {}) {
1739
1779
  t: 'li',
1740
1780
  a: { class: `bw_page_item ${currentPage >= pages ? 'bw_disabled' : ''}`.trim() },
1741
1781
  c: {
1742
- t: 'a',
1743
- a: { class: 'bw_page_link', href: '#', onclick: handleClick(currentPage + 1), 'aria-label': 'Next' },
1782
+ t: 'button',
1783
+ a: { class: 'bw_page_link', type: 'button', onclick: handleClick(currentPage + 1), 'aria-label': 'Next', disabled: currentPage >= pages ? true : undefined },
1744
1784
  c: '\u203A'
1745
1785
  }
1746
1786
  });
@@ -1754,6 +1794,26 @@ function makePagination(props = {}) {
1754
1794
  class: `bw_pagination ${size ? 'bw_pagination_' + size : ''} ${className}`.trim()
1755
1795
  },
1756
1796
  c: items
1797
+ },
1798
+ o: {
1799
+ type: 'pagination',
1800
+ state: { currentPage: currentPage, pages: pages },
1801
+ handle: {
1802
+ setPage: function(el, n) {
1803
+ if (n < 1 || n > pages) return;
1804
+ var allItems = el.querySelectorAll('.bw_page_item');
1805
+ for (var i = 0; i < allItems.length; i++) {
1806
+ allItems[i].classList.remove('bw_active');
1807
+ }
1808
+ // +1 offset: first item is prev arrow
1809
+ if (allItems[n]) allItems[n].classList.add('bw_active');
1810
+ if (el._bw_state) el._bw_state.currentPage = n;
1811
+ if (onPageChange) onPageChange(n);
1812
+ },
1813
+ getPage: function(el) {
1814
+ return (el._bw_state && el._bw_state.currentPage) || 1;
1815
+ }
1816
+ }
1757
1817
  }
1758
1818
  };
1759
1819
  }
@@ -1902,7 +1962,6 @@ function makeAccordion(props = {}) {
1902
1962
  class: `bw_accordion_button ${item.open ? '' : 'bw_collapsed'}`.trim(),
1903
1963
  type: 'button',
1904
1964
  'aria-expanded': item.open ? 'true' : 'false',
1905
- 'data-accordion-index': index,
1906
1965
  onclick: function(e) {
1907
1966
  var btn = e.target.closest('.bw_accordion_button');
1908
1967
  var accordionEl = btn.closest('.bw_accordion');
@@ -1977,7 +2036,43 @@ function makeAccordion(props = {}) {
1977
2036
  }),
1978
2037
  o: {
1979
2038
  type: 'accordion',
1980
- state: { multiOpen: multiOpen }
2039
+ state: { multiOpen: multiOpen },
2040
+ handle: {
2041
+ toggle: function(el, index) {
2042
+ var items = el.querySelectorAll('.bw_accordion_item');
2043
+ if (index < 0 || index >= items.length) return;
2044
+ var btn = items[index].querySelector('.bw_accordion_button');
2045
+ if (btn) btn.click();
2046
+ },
2047
+ openAll: function(el) {
2048
+ var items = el.querySelectorAll('.bw_accordion_item');
2049
+ for (var i = 0; i < items.length; i++) {
2050
+ var collapse = items[i].querySelector('.bw_accordion_collapse');
2051
+ var btn = items[i].querySelector('.bw_accordion_button');
2052
+ if (!collapse.classList.contains('bw_collapse_show')) {
2053
+ collapse.classList.add('bw_collapse_show');
2054
+ collapse.style.maxHeight = 'none';
2055
+ btn.classList.remove('bw_collapsed');
2056
+ btn.setAttribute('aria-expanded', 'true');
2057
+ }
2058
+ }
2059
+ },
2060
+ closeAll: function(el) {
2061
+ var items = el.querySelectorAll('.bw_accordion_item');
2062
+ for (var i = 0; i < items.length; i++) {
2063
+ var collapse = items[i].querySelector('.bw_accordion_collapse');
2064
+ var btn = items[i].querySelector('.bw_accordion_button');
2065
+ if (collapse.classList.contains('bw_collapse_show')) {
2066
+ collapse.style.maxHeight = collapse.scrollHeight + 'px';
2067
+ collapse.offsetHeight;
2068
+ collapse.style.maxHeight = '0px';
2069
+ collapse.classList.remove('bw_collapse_show');
2070
+ btn.classList.add('bw_collapsed');
2071
+ btn.setAttribute('aria-expanded', 'false');
2072
+ }
2073
+ }
2074
+ }
2075
+ }
1981
2076
  }
1982
2077
  };
1983
2078
  }
@@ -2067,6 +2162,14 @@ function makeModal(props = {}) {
2067
2162
  },
2068
2163
  o: {
2069
2164
  type: 'modal',
2165
+ handle: {
2166
+ open: function(el) {
2167
+ el.classList.add('bw_modal_show');
2168
+ el.style.display = 'flex';
2169
+ document.body.style.overflow = 'hidden';
2170
+ },
2171
+ close: function(el) { closeModal(el); }
2172
+ },
2070
2173
  mounted: function(el) {
2071
2174
  // Click backdrop to close
2072
2175
  el.addEventListener('click', function(e) {
@@ -2125,9 +2228,8 @@ function makeToast(props = {}) {
2125
2228
  return {
2126
2229
  t: 'div',
2127
2230
  a: {
2128
- class: `bw_toast ${variantClass(variant)} ${className}`.trim(),
2129
- role: 'alert',
2130
- 'data-position': position
2231
+ class: `bw_toast ${variantClass(variant)} bw_toast_${position.replace(/-/g, '_')} ${className}`.trim(),
2232
+ role: 'alert'
2131
2233
  },
2132
2234
  c: [
2133
2235
  (title) && {
@@ -2161,6 +2263,12 @@ function makeToast(props = {}) {
2161
2263
  ].filter(Boolean),
2162
2264
  o: {
2163
2265
  type: 'toast',
2266
+ handle: {
2267
+ dismiss: function(el) {
2268
+ el.classList.add('bw_toast_hiding');
2269
+ setTimeout(function() { if (el.parentNode) el.parentNode.removeChild(el); }, 300);
2270
+ }
2271
+ },
2164
2272
  mounted: function(el) {
2165
2273
  // Trigger show animation
2166
2274
  requestAnimationFrame(function() {
@@ -2518,7 +2626,7 @@ function makeCarousel(props = {}) {
2518
2626
  var total = carouselEl.querySelectorAll('.bw_carousel_slide').length;
2519
2627
  if (index < 0) index = total - 1;
2520
2628
  if (index >= total) index = 0;
2521
- carouselEl.setAttribute('data-carousel-index', index);
2629
+ carouselEl._bw_carouselIndex = index;
2522
2630
  var track = carouselEl.querySelector('.bw_carousel_track');
2523
2631
  track.style.transform = 'translateX(-' + (index * 100) + '%)';
2524
2632
  // Update indicators
@@ -2575,7 +2683,7 @@ function makeCarousel(props = {}) {
2575
2683
  'aria-label': 'Previous slide',
2576
2684
  onclick: function(e) {
2577
2685
  var carousel = e.target.closest('.bw_carousel');
2578
- var idx = parseInt(carousel.getAttribute('data-carousel-index') || '0');
2686
+ var idx = carousel._bw_carouselIndex || 0;
2579
2687
  goToSlide(carousel, idx - 1);
2580
2688
  }
2581
2689
  },
@@ -2589,7 +2697,7 @@ function makeCarousel(props = {}) {
2589
2697
  'aria-label': 'Next slide',
2590
2698
  onclick: function(e) {
2591
2699
  var carousel = e.target.closest('.bw_carousel');
2592
- var idx = parseInt(carousel.getAttribute('data-carousel-index') || '0');
2700
+ var idx = carousel._bw_carouselIndex || 0;
2593
2701
  goToSlide(carousel, idx + 1);
2594
2702
  }
2595
2703
  },
@@ -2609,11 +2717,9 @@ function makeCarousel(props = {}) {
2609
2717
  class: 'bw_carousel_indicator' + (i === startIndex ? ' active' : ''),
2610
2718
  type: 'button',
2611
2719
  'aria-label': 'Go to slide ' + (i + 1),
2612
- 'data-slide-index': i,
2613
2720
  onclick: function(e) {
2614
2721
  var carousel = e.target.closest('.bw_carousel');
2615
- var idx = parseInt(e.target.getAttribute('data-slide-index'));
2616
- goToSlide(carousel, idx);
2722
+ goToSlide(carousel, i);
2617
2723
  }
2618
2724
  }
2619
2725
  };
@@ -2627,17 +2733,37 @@ function makeCarousel(props = {}) {
2627
2733
  class: ('bw_carousel ' + className).trim(),
2628
2734
  style: 'height: ' + height,
2629
2735
  tabindex: '0',
2630
- 'aria-roledescription': 'carousel',
2631
- 'data-carousel-index': startIndex
2736
+ 'aria-roledescription': 'carousel'
2632
2737
  },
2633
2738
  c: children,
2634
2739
  o: {
2635
2740
  type: 'carousel',
2636
2741
  state: { activeIndex: startIndex, autoPlay: autoPlay, interval: interval },
2742
+ handle: {
2743
+ goToSlide: function(el, index) { goToSlide(el, index); },
2744
+ next: function(el) { goToSlide(el, (el._bw_carouselIndex || 0) + 1); },
2745
+ prev: function(el) { goToSlide(el, (el._bw_carouselIndex || 0) - 1); },
2746
+ getActiveIndex: function(el) { return el._bw_carouselIndex || 0; },
2747
+ pause: function(el) {
2748
+ if (el._bw_carouselInterval) {
2749
+ clearInterval(el._bw_carouselInterval);
2750
+ el._bw_carouselInterval = null;
2751
+ }
2752
+ },
2753
+ play: function(el) {
2754
+ if (!el._bw_carouselInterval && el._bw_state) {
2755
+ var ms = el._bw_state.interval || 5000;
2756
+ el._bw_carouselInterval = setInterval(function() {
2757
+ goToSlide(el, (el._bw_carouselIndex || 0) + 1);
2758
+ }, ms);
2759
+ }
2760
+ }
2761
+ },
2637
2762
  mounted: function(el) {
2763
+ el._bw_carouselIndex = startIndex;
2638
2764
  // Keyboard navigation
2639
2765
  el.addEventListener('keydown', function(e) {
2640
- var idx = parseInt(el.getAttribute('data-carousel-index') || '0');
2766
+ var idx = el._bw_carouselIndex || 0;
2641
2767
  if (e.key === 'ArrowLeft') {
2642
2768
  e.preventDefault();
2643
2769
  goToSlide(el, idx - 1);
@@ -2649,7 +2775,7 @@ function makeCarousel(props = {}) {
2649
2775
  // Auto-play
2650
2776
  if (autoPlay) {
2651
2777
  var intervalId = setInterval(function() {
2652
- var idx = parseInt(el.getAttribute('data-carousel-index') || '0');
2778
+ var idx = el._bw_carouselIndex || 0;
2653
2779
  goToSlide(el, idx + 1);
2654
2780
  }, interval);
2655
2781
  el._bw_carouselInterval = intervalId;
@@ -2659,7 +2785,7 @@ function makeCarousel(props = {}) {
2659
2785
  });
2660
2786
  el.addEventListener('mouseleave', function() {
2661
2787
  el._bw_carouselInterval = setInterval(function() {
2662
- var idx = parseInt(el.getAttribute('data-carousel-index') || '0');
2788
+ var idx = el._bw_carouselIndex || 0;
2663
2789
  goToSlide(el, idx + 1);
2664
2790
  }, interval);
2665
2791
  });
@@ -2775,7 +2901,13 @@ function makeStatCard(props = {}) {
2775
2901
  t: 'div',
2776
2902
  a: { class: classes, style: style },
2777
2903
  c: children,
2778
- o: { type: 'stat-card' }
2904
+ o: {
2905
+ type: 'stat-card',
2906
+ slots: {
2907
+ value: '.bw_stat_value',
2908
+ label: '.bw_stat_label'
2909
+ }
2910
+ }
2779
2911
  };
2780
2912
  }
2781
2913
 
@@ -3454,7 +3586,7 @@ function makeChipInput(props = {}) {
3454
3586
  function makeChipEl(text) {
3455
3587
  return {
3456
3588
  t: 'span',
3457
- a: { class: 'bw_chip', 'data-chip-value': text },
3589
+ a: { class: 'bw_chip' },
3458
3590
  c: [
3459
3591
  text,
3460
3592
  {
@@ -3465,9 +3597,8 @@ function makeChipInput(props = {}) {
3465
3597
  'aria-label': 'Remove ' + text,
3466
3598
  onclick: function(e) {
3467
3599
  var chip = e.target.closest('.bw_chip');
3468
- var val = chip.getAttribute('data-chip-value');
3469
3600
  chip.parentNode.removeChild(chip);
3470
- if (onRemove) onRemove(val);
3601
+ if (onRemove) onRemove(text);
3471
3602
  }
3472
3603
  },
3473
3604
  c: '\u00D7'
@@ -3495,7 +3626,7 @@ function makeChipInput(props = {}) {
3495
3626
  // Insert chip before the input
3496
3627
  var chipEl = document.createElement('span');
3497
3628
  chipEl.className = 'bw_chip';
3498
- chipEl.setAttribute('data-chip-value', val);
3629
+ chipEl._bw_chipValue = val;
3499
3630
  chipEl.innerHTML = '';
3500
3631
  chipEl.textContent = val;
3501
3632
  var removeBtn = document.createElement('button');
@@ -3518,7 +3649,7 @@ function makeChipInput(props = {}) {
3518
3649
  var chipEls = wrapper.querySelectorAll('.bw_chip');
3519
3650
  if (chipEls.length) {
3520
3651
  var last = chipEls[chipEls.length - 1];
3521
- var removedVal = last.getAttribute('data-chip-value');
3652
+ var removedVal = last._bw_chipValue || last.firstChild.textContent;
3522
3653
  last.parentNode.removeChild(last);
3523
3654
  if (onRemove) onRemove(removedVal);
3524
3655
  }
@@ -3527,7 +3658,50 @@ function makeChipInput(props = {}) {
3527
3658
  }
3528
3659
  }
3529
3660
  ],
3530
- o: { type: 'chip-input' }
3661
+ o: {
3662
+ type: 'chip-input',
3663
+ handle: {
3664
+ addChip: function(el, text) {
3665
+ if (!text) return;
3666
+ var input = el.querySelector('.bw_chip_field');
3667
+ var chipEl = document.createElement('span');
3668
+ chipEl.className = 'bw_chip';
3669
+ chipEl._bw_chipValue = text;
3670
+ chipEl.textContent = text;
3671
+ var removeBtn = document.createElement('button');
3672
+ removeBtn.type = 'button';
3673
+ removeBtn.className = 'bw_chip_remove';
3674
+ removeBtn.setAttribute('aria-label', 'Remove ' + text);
3675
+ removeBtn.textContent = '\u00D7';
3676
+ removeBtn.onclick = function() { chipEl.parentNode.removeChild(chipEl); };
3677
+ chipEl.appendChild(removeBtn);
3678
+ el.insertBefore(chipEl, input);
3679
+ },
3680
+ removeChip: function(el, text) {
3681
+ var chips = el.querySelectorAll('.bw_chip');
3682
+ for (var i = 0; i < chips.length; i++) {
3683
+ if ((chips[i]._bw_chipValue || chips[i].firstChild.textContent) === text) {
3684
+ chips[i].parentNode.removeChild(chips[i]);
3685
+ return;
3686
+ }
3687
+ }
3688
+ },
3689
+ getChips: function(el) {
3690
+ var chips = el.querySelectorAll('.bw_chip');
3691
+ var values = [];
3692
+ for (var i = 0; i < chips.length; i++) {
3693
+ values.push(chips[i]._bw_chipValue || chips[i].firstChild.textContent);
3694
+ }
3695
+ return values;
3696
+ },
3697
+ clear: function(el) {
3698
+ var chips = el.querySelectorAll('.bw_chip');
3699
+ for (var i = chips.length - 1; i >= 0; i--) {
3700
+ chips[i].parentNode.removeChild(chips[i]);
3701
+ }
3702
+ }
3703
+ }
3704
+ }
3531
3705
  };
3532
3706
  }
3533
3707
 
@@ -3721,15 +3895,14 @@ function registerBCCL(bw) {
3721
3895
  // Variant class helper
3722
3896
  bw.variantClass = variantClass;
3723
3897
 
3724
- // Create functions that return handles
3725
- if (typeof bw.renderComponent === 'function') {
3898
+ // Create functions that return DOM elements
3899
+ if (typeof bw.createDOM === 'function') {
3726
3900
  Object.entries(components).forEach(function(entry) {
3727
3901
  var name = entry[0], fn = entry[1];
3728
3902
  if (name.indexOf('make') === 0) {
3729
3903
  var createName = 'create' + name.substring(4);
3730
3904
  bw[createName] = function(props) {
3731
- var taco = fn(props);
3732
- return bw.renderComponent(taco);
3905
+ return bw.createDOM(fn(props));
3733
3906
  };
3734
3907
  }
3735
3908
  });