bitwrench 2.0.11 → 2.0.12

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.
@@ -1,4 +1,4 @@
1
- /*! bitwrench-lean v2.0.11 | BSD-2-Clause | https://deftio.github.com/bitwrench/pages */
1
+ /*! bitwrench-lean v2.0.12 | BSD-2-Clause | https://deftio.github.com/bitwrench/pages */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4
4
  typeof define === 'function' && define.amd ? define(factory) :
@@ -189,14 +189,14 @@
189
189
  */
190
190
 
191
191
  var VERSION_INFO = {
192
- version: '2.0.11',
192
+ version: '2.0.12',
193
193
  name: 'bitwrench',
194
194
  description: 'A library for javascript UI functions.',
195
195
  license: 'BSD-2-Clause',
196
196
  homepage: 'https://deftio.github.com/bitwrench/pages',
197
197
  repository: 'git+https://github.com/deftio/bitwrench.git',
198
198
  author: 'manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)',
199
- buildDate: '2026-03-07T11:05:08.522Z'
199
+ buildDate: '2026-03-07T22:31:35.755Z'
200
200
  };
201
201
 
202
202
  /**
@@ -1137,14 +1137,34 @@
1137
1137
  rules[scopeSelector(scope, '.bw-accordion-button')] = {
1138
1138
  'color': palette.dark.base
1139
1139
  };
1140
+ rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed)')] = {
1141
+ 'color': palette.primary.darkText,
1142
+ 'background-color': palette.primary.light
1143
+ };
1140
1144
  rules[scopeSelector(scope, '.bw-accordion-button:hover')] = {
1141
1145
  'background-color': palette.light.light
1142
1146
  };
1147
+ rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed):hover')] = {
1148
+ 'background-color': palette.primary.hover
1149
+ };
1150
+ rules[scopeSelector(scope, '.bw-accordion-button:focus-visible')] = {
1151
+ 'box-shadow': '0 0 0 0.2rem ' + palette.primary.focus
1152
+ };
1143
1153
  rules[scopeSelector(scope, '.bw-accordion-body')] = {
1144
1154
  'border-top': '1px solid ' + palette.light.border
1145
1155
  };
1146
1156
  return rules;
1147
1157
  }
1158
+ function generateCarouselThemed(scope, palette) {
1159
+ var rules = {};
1160
+ rules[scopeSelector(scope, '.bw-carousel')] = {
1161
+ 'background-color': palette.light.light
1162
+ };
1163
+ rules[scopeSelector(scope, '.bw-carousel-indicator.active')] = {
1164
+ 'background-color': palette.primary.base
1165
+ };
1166
+ return rules;
1167
+ }
1148
1168
  function generateModalThemed(scope, palette) {
1149
1169
  var rules = {};
1150
1170
  rules[scopeSelector(scope, '.bw-modal-content')] = {
@@ -1221,7 +1241,7 @@
1221
1241
  function generateSkeletonThemed(scope, palette) {
1222
1242
  var rules = {};
1223
1243
  rules[scopeSelector(scope, '.bw-skeleton')] = {
1224
- 'background-color': palette.light.border
1244
+ 'background': 'linear-gradient(90deg, ' + palette.light.border + ' 25%, ' + palette.light.light + ' 37%, ' + palette.light.border + ' 63%)'
1225
1245
  };
1226
1246
  return rules;
1227
1247
  }
@@ -1247,7 +1267,7 @@
1247
1267
  * @returns {Object} CSS rules object
1248
1268
  */
1249
1269
  function generateThemedCSS(scopeName, palette, layout) {
1250
- return Object.assign({}, generateResetThemed(scopeName, palette), generateTypographyThemed(scopeName, palette), generateButtons(scopeName, palette, layout), generateAlerts(scopeName, palette, layout), generateBadges(scopeName, palette), generateCards(scopeName, palette, layout), generateForms(scopeName, palette, layout), generateNavigation(scopeName, palette), generateTables(scopeName, palette, layout), generateTabs(scopeName, palette), generateListGroups(scopeName, palette, layout), generatePagination(scopeName, palette), generateProgress(scopeName, palette), generateHero(scopeName, palette), generateBreadcrumbThemed(scopeName, palette), generateSpinnerThemed(scopeName, palette), generateCloseButtonThemed(scopeName, palette), generateSectionsThemed(scopeName, palette), generateAccordionThemed(scopeName, palette), generateModalThemed(scopeName, palette), generateToastThemed(scopeName, palette), generateDropdownThemed(scopeName, palette), generateSwitchThemed(scopeName, palette), generateSkeletonThemed(scopeName, palette), generateAvatarThemed(scopeName, palette), generateUtilityColors(scopeName, palette));
1270
+ return Object.assign({}, generateResetThemed(scopeName, palette), generateTypographyThemed(scopeName, palette), generateButtons(scopeName, palette, layout), generateAlerts(scopeName, palette, layout), generateBadges(scopeName, palette), generateCards(scopeName, palette, layout), generateForms(scopeName, palette, layout), generateNavigation(scopeName, palette), generateTables(scopeName, palette, layout), generateTabs(scopeName, palette), generateListGroups(scopeName, palette, layout), generatePagination(scopeName, palette), generateProgress(scopeName, palette), generateHero(scopeName, palette), generateBreadcrumbThemed(scopeName, palette), generateSpinnerThemed(scopeName, palette), generateCloseButtonThemed(scopeName, palette), generateSectionsThemed(scopeName, palette), generateAccordionThemed(scopeName, palette), generateCarouselThemed(scopeName, palette), generateModalThemed(scopeName, palette), generateToastThemed(scopeName, palette), generateDropdownThemed(scopeName, palette), generateSwitchThemed(scopeName, palette), generateSkeletonThemed(scopeName, palette), generateAvatarThemed(scopeName, palette), generateUtilityColors(scopeName, palette));
1251
1271
  }
1252
1272
 
1253
1273
  // =========================================================================
@@ -1274,7 +1294,7 @@
1274
1294
  'font-weight': '600',
1275
1295
  'line-height': '1.25',
1276
1296
  'letter-spacing': '-0.01em',
1277
- 'color': '#1a1a1a'
1297
+ 'color': 'inherit'
1278
1298
  },
1279
1299
  'h1': {
1280
1300
  'font-size': 'calc(1.375rem + 1.5vw)'
@@ -2097,6 +2117,15 @@
2097
2117
  rules['.bw-tab-pane.active'] = {
2098
2118
  'display': 'block'
2099
2119
  };
2120
+ rules['.bw-nav-scrollable'] = {
2121
+ 'flex-wrap': 'nowrap',
2122
+ 'overflow-x': 'auto',
2123
+ '-webkit-overflow-scrolling': 'touch',
2124
+ 'scrollbar-width': 'none'
2125
+ };
2126
+ rules['.bw-nav-scrollable .bw-nav-link'] = {
2127
+ 'white-space': 'nowrap'
2128
+ };
2100
2129
 
2101
2130
  // List groups (structural)
2102
2131
  rules['.bw-list-group'] = {
@@ -2605,6 +2634,84 @@
2605
2634
  'gap': '0.5rem'
2606
2635
  };
2607
2636
 
2637
+ // Carousel (structural)
2638
+ rules['.bw-carousel'] = {
2639
+ 'position': 'relative',
2640
+ 'overflow': 'hidden',
2641
+ 'border-radius': '8px'
2642
+ };
2643
+ rules['.bw-carousel-track'] = {
2644
+ 'display': 'flex',
2645
+ 'transition': 'transform 0.4s ease',
2646
+ 'height': '100%'
2647
+ };
2648
+ rules['.bw-carousel-slide'] = {
2649
+ 'min-width': '100%',
2650
+ 'flex-shrink': '0',
2651
+ 'overflow': 'hidden',
2652
+ 'position': 'relative',
2653
+ 'display': 'flex',
2654
+ 'align-items': 'center',
2655
+ 'justify-content': 'center'
2656
+ };
2657
+ rules['.bw-carousel-slide img'] = {
2658
+ 'width': '100%',
2659
+ 'height': '100%',
2660
+ 'object-fit': 'cover'
2661
+ };
2662
+ rules['.bw-carousel-caption'] = {
2663
+ 'position': 'absolute',
2664
+ 'bottom': '0',
2665
+ 'left': '0',
2666
+ 'right': '0',
2667
+ 'padding': '0.75rem 1rem'
2668
+ };
2669
+ rules['.bw-carousel-control'] = {
2670
+ 'position': 'absolute',
2671
+ 'top': '50%',
2672
+ 'transform': 'translateY(-50%)',
2673
+ 'width': '40px',
2674
+ 'height': '40px',
2675
+ 'border': 'none',
2676
+ 'border-radius': '50%',
2677
+ 'cursor': 'pointer',
2678
+ 'display': 'flex',
2679
+ 'align-items': 'center',
2680
+ 'justify-content': 'center',
2681
+ 'z-index': '2',
2682
+ 'padding': '0',
2683
+ 'transition': 'background-color 0.2s ease'
2684
+ };
2685
+ rules['.bw-carousel-control img'] = {
2686
+ 'width': '20px',
2687
+ 'height': '20px',
2688
+ 'pointer-events': 'none'
2689
+ };
2690
+ rules['.bw-carousel-control-prev'] = {
2691
+ 'left': '10px'
2692
+ };
2693
+ rules['.bw-carousel-control-next'] = {
2694
+ 'right': '10px'
2695
+ };
2696
+ rules['.bw-carousel-indicators'] = {
2697
+ 'position': 'absolute',
2698
+ 'bottom': '12px',
2699
+ 'left': '50%',
2700
+ 'transform': 'translateX(-50%)',
2701
+ 'display': 'flex',
2702
+ 'gap': '6px',
2703
+ 'z-index': '2'
2704
+ };
2705
+ rules['.bw-carousel-indicator'] = {
2706
+ 'width': '10px',
2707
+ 'height': '10px',
2708
+ 'border-radius': '50%',
2709
+ 'border': '2px solid transparent',
2710
+ 'padding': '0',
2711
+ 'cursor': 'pointer',
2712
+ 'transition': 'opacity 0.2s ease, background-color 0.2s ease'
2713
+ };
2714
+
2608
2715
  // Toast (structural)
2609
2716
  rules['.bw-toast-container'] = {
2610
2717
  'position': 'fixed',
@@ -2727,7 +2834,8 @@
2727
2834
  // Skeleton (structural)
2728
2835
  rules['.bw-skeleton'] = {
2729
2836
  'border-radius': '4px',
2730
- 'animation': 'bw-skeleton-pulse 1.5s ease-in-out infinite'
2837
+ 'background-size': '400% 100%',
2838
+ 'animation': 'bw-skeleton-shimmer 1.4s ease infinite'
2731
2839
  };
2732
2840
  rules['.bw-skeleton-text'] = {
2733
2841
  'height': '1em',
@@ -2743,15 +2851,12 @@
2743
2851
  'display': 'flex',
2744
2852
  'flex-direction': 'column'
2745
2853
  };
2746
- rules['@keyframes bw-skeleton-pulse'] = {
2854
+ rules['@keyframes bw-skeleton-shimmer'] = {
2747
2855
  '0%': {
2748
- 'opacity': '1'
2749
- },
2750
- '50%': {
2751
- 'opacity': '0.4'
2856
+ 'background-position': '100% 50%'
2752
2857
  },
2753
2858
  '100%': {
2754
- 'opacity': '1'
2859
+ 'background-position': '0 50%'
2755
2860
  }
2756
2861
  };
2757
2862
 
@@ -3319,12 +3424,31 @@
3319
3424
  '.bw-dark .bw-accordion-button': {
3320
3425
  'color': textColor
3321
3426
  },
3427
+ '.bw-dark .bw-accordion-button:not(.bw-collapsed)': {
3428
+ 'color': '#7dd3e0',
3429
+ 'background-color': 'rgba(125, 211, 224, 0.1)'
3430
+ },
3322
3431
  '.bw-dark .bw-accordion-button:hover': {
3323
3432
  'background-color': bodyBg
3324
3433
  },
3434
+ '.bw-dark .bw-accordion-button:not(.bw-collapsed):hover': {
3435
+ 'background-color': 'rgba(125, 211, 224, 0.15)'
3436
+ },
3437
+ '.bw-dark .bw-accordion-button:focus-visible': {
3438
+ 'box-shadow': '0 0 0 0.2rem rgba(125, 211, 224, 0.3)'
3439
+ },
3325
3440
  '.bw-dark .bw-accordion-body': {
3326
3441
  'border-top-color': borderColor
3327
3442
  },
3443
+ '.bw-dark .bw-carousel': {
3444
+ 'background-color': bodyBg
3445
+ },
3446
+ '.bw-dark .bw-carousel-control': {
3447
+ 'background-color': 'rgba(255,255,255,0.15)'
3448
+ },
3449
+ '.bw-dark .bw-carousel-control:hover': {
3450
+ 'background-color': 'rgba(255,255,255,0.25)'
3451
+ },
3328
3452
  '.bw-dark .bw-modal-content': {
3329
3453
  'background-color': surfaceBg,
3330
3454
  'border-color': borderColor
@@ -3360,7 +3484,7 @@
3360
3484
  'border-top-color': borderColor
3361
3485
  },
3362
3486
  '.bw-dark .bw-skeleton': {
3363
- 'background-color': borderColor
3487
+ 'background': 'linear-gradient(90deg, ' + borderColor + ' 25%, ' + surfaceBg + ' 37%, ' + borderColor + ' 63%)'
3364
3488
  },
3365
3489
  '.bw-dark h1, .bw-dark h2, .bw-dark h3, .bw-dark h4, .bw-dark h5, .bw-dark h6': {
3366
3490
  'color': textColor
@@ -3805,6 +3929,29 @@
3805
3929
  });
3806
3930
  };
3807
3931
 
3932
+ /**
3933
+ * Mark a string as raw HTML so it will not be escaped by bw.html() or bw.createDOM().
3934
+ *
3935
+ * By default, bitwrench escapes all text content to prevent XSS. Use bw.raw()
3936
+ * when you need to embed pre-sanitized HTML, entities, or inline markup.
3937
+ *
3938
+ * @param {string} str - HTML string to mark as raw
3939
+ * @returns {Object} Marked object recognized by bw.html() and bw.createDOM()
3940
+ * @category DOM Generation
3941
+ * @see bw.escapeHTML
3942
+ * @see bw.html
3943
+ * @example
3944
+ * bw.raw('Hello &mdash; World')
3945
+ * // Used in TACO content:
3946
+ * { t: 'p', c: bw.raw('Price: <strong>$9.99</strong>') }
3947
+ */
3948
+ bw.raw = function (str) {
3949
+ return {
3950
+ __bw_raw: true,
3951
+ v: String(str)
3952
+ };
3953
+ };
3954
+
3808
3955
  /**
3809
3956
  * Normalize CSS class names by converting underscores to hyphens for bw-prefixed classes.
3810
3957
  *
@@ -3860,6 +4007,11 @@
3860
4007
  }).join('');
3861
4008
  }
3862
4009
 
4010
+ // Handle bw.raw() marked content
4011
+ if (taco && taco.__bw_raw) {
4012
+ return taco.v;
4013
+ }
4014
+
3863
4015
  // Handle primitives and non-TACO objects
3864
4016
  if (_typeof(taco) !== 'object' || !taco.t) {
3865
4017
  return options.raw ? String(taco) : bw.escapeHTML(String(taco));
@@ -3967,6 +4119,15 @@
3967
4119
  // Handle null/undefined
3968
4120
  if (taco == null) return document.createTextNode('');
3969
4121
 
4122
+ // Handle bw.raw() marked content — inject as HTML
4123
+ if (taco && taco.__bw_raw) {
4124
+ var frag = document.createDocumentFragment();
4125
+ var tmp = document.createElement('span');
4126
+ tmp.innerHTML = taco.v;
4127
+ while (tmp.firstChild) frag.appendChild(tmp.firstChild);
4128
+ return frag;
4129
+ }
4130
+
3970
4131
  // Handle text nodes
3971
4132
  if (_typeof(taco) !== 'object' || !taco.t) {
3972
4133
  return document.createTextNode(String(taco));
@@ -4038,6 +4199,9 @@
4038
4199
  }
4039
4200
  }
4040
4201
  });
4202
+ } else if (_typeof(content) === 'object' && content.__bw_raw) {
4203
+ // Raw HTML content — inject via innerHTML
4204
+ el.innerHTML = content.v;
4041
4205
  } else if (_typeof(content) === 'object' && content.t) {
4042
4206
  var childEl = bw.createDOM(content, options);
4043
4207
  el.appendChild(childEl);