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,18 +1,18 @@
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
  /**
3
3
  * Auto-generated version file from package.json
4
4
  * DO NOT EDIT DIRECTLY - Use npm run generate-version
5
5
  */
6
6
 
7
7
  const VERSION_INFO = {
8
- version: '2.0.11',
8
+ version: '2.0.12',
9
9
  name: 'bitwrench',
10
10
  description: 'A library for javascript UI functions.',
11
11
  license: 'BSD-2-Clause',
12
12
  homepage: 'https://deftio.github.com/bitwrench/pages',
13
13
  repository: 'git+https://github.com/deftio/bitwrench.git',
14
14
  author: 'manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)',
15
- buildDate: '2026-03-07T11:05:08.522Z'
15
+ buildDate: '2026-03-07T22:31:35.755Z'
16
16
  };
17
17
 
18
18
  /**
@@ -887,15 +887,36 @@ function generateAccordionThemed(scope, palette) {
887
887
  rules[scopeSelector(scope, '.bw-accordion-button')] = {
888
888
  'color': palette.dark.base
889
889
  };
890
+ rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed)')] = {
891
+ 'color': palette.primary.darkText,
892
+ 'background-color': palette.primary.light
893
+ };
890
894
  rules[scopeSelector(scope, '.bw-accordion-button:hover')] = {
891
895
  'background-color': palette.light.light
892
896
  };
897
+ rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed):hover')] = {
898
+ 'background-color': palette.primary.hover
899
+ };
900
+ rules[scopeSelector(scope, '.bw-accordion-button:focus-visible')] = {
901
+ 'box-shadow': '0 0 0 0.2rem ' + palette.primary.focus
902
+ };
893
903
  rules[scopeSelector(scope, '.bw-accordion-body')] = {
894
904
  'border-top': '1px solid ' + palette.light.border
895
905
  };
896
906
  return rules;
897
907
  }
898
908
 
909
+ function generateCarouselThemed(scope, palette) {
910
+ var rules = {};
911
+ rules[scopeSelector(scope, '.bw-carousel')] = {
912
+ 'background-color': palette.light.light
913
+ };
914
+ rules[scopeSelector(scope, '.bw-carousel-indicator.active')] = {
915
+ 'background-color': palette.primary.base
916
+ };
917
+ return rules;
918
+ }
919
+
899
920
  function generateModalThemed(scope, palette) {
900
921
  var rules = {};
901
922
  rules[scopeSelector(scope, '.bw-modal-content')] = {
@@ -976,7 +997,7 @@ function generateSwitchThemed(scope, palette) {
976
997
  function generateSkeletonThemed(scope, palette) {
977
998
  var rules = {};
978
999
  rules[scopeSelector(scope, '.bw-skeleton')] = {
979
- 'background-color': palette.light.border
1000
+ 'background': 'linear-gradient(90deg, ' + palette.light.border + ' 25%, ' + palette.light.light + ' 37%, ' + palette.light.border + ' 63%)'
980
1001
  };
981
1002
  return rules;
982
1003
  }
@@ -1023,6 +1044,7 @@ function generateThemedCSS(scopeName, palette, layout) {
1023
1044
  generateCloseButtonThemed(scopeName, palette),
1024
1045
  generateSectionsThemed(scopeName, palette),
1025
1046
  generateAccordionThemed(scopeName, palette),
1047
+ generateCarouselThemed(scopeName, palette),
1026
1048
  generateModalThemed(scopeName, palette),
1027
1049
  generateToastThemed(scopeName, palette),
1028
1050
  generateDropdownThemed(scopeName, palette),
@@ -1382,6 +1404,8 @@ function getStructuralStyles() {
1382
1404
  rules['.bw-tab-content'] = { 'padding': '1.25rem 0' };
1383
1405
  rules['.bw-tab-pane'] = { 'display': 'none' };
1384
1406
  rules['.bw-tab-pane.active'] = { 'display': 'block' };
1407
+ rules['.bw-nav-scrollable'] = { 'flex-wrap': 'nowrap', 'overflow-x': 'auto', '-webkit-overflow-scrolling': 'touch', 'scrollbar-width': 'none' };
1408
+ rules['.bw-nav-scrollable .bw-nav-link'] = { 'white-space': 'nowrap' };
1385
1409
 
1386
1410
  // List groups (structural)
1387
1411
  rules['.bw-list-group'] = { 'display': 'flex', 'flex-direction': 'column', 'padding-left': '0', 'margin-bottom': '0', 'border-radius': '0.375rem' };
@@ -1548,6 +1572,29 @@ function getStructuralStyles() {
1548
1572
  rules['.bw-modal-body'] = { 'position': 'relative', 'flex': '1 1 auto', 'padding': '1.5rem' };
1549
1573
  rules['.bw-modal-footer'] = { 'display': 'flex', 'flex-wrap': 'wrap', 'align-items': 'center', 'justify-content': 'flex-end', 'padding': '0.75rem 1.5rem', 'gap': '0.5rem' };
1550
1574
 
1575
+ // Carousel (structural)
1576
+ rules['.bw-carousel'] = { 'position': 'relative', 'overflow': 'hidden', 'border-radius': '8px' };
1577
+ rules['.bw-carousel-track'] = { 'display': 'flex', 'transition': 'transform 0.4s ease', 'height': '100%' };
1578
+ rules['.bw-carousel-slide'] = { 'min-width': '100%', 'flex-shrink': '0', 'overflow': 'hidden', 'position': 'relative', 'display': 'flex', 'align-items': 'center', 'justify-content': 'center' };
1579
+ rules['.bw-carousel-slide img'] = { 'width': '100%', 'height': '100%', 'object-fit': 'cover' };
1580
+ rules['.bw-carousel-caption'] = { 'position': 'absolute', 'bottom': '0', 'left': '0', 'right': '0', 'padding': '0.75rem 1rem' };
1581
+ rules['.bw-carousel-control'] = {
1582
+ 'position': 'absolute', 'top': '50%', 'transform': 'translateY(-50%)', 'width': '40px', 'height': '40px',
1583
+ 'border': 'none', 'border-radius': '50%', 'cursor': 'pointer', 'display': 'flex', 'align-items': 'center',
1584
+ 'justify-content': 'center', 'z-index': '2', 'padding': '0', 'transition': 'background-color 0.2s ease'
1585
+ };
1586
+ rules['.bw-carousel-control img'] = { 'width': '20px', 'height': '20px', 'pointer-events': 'none' };
1587
+ rules['.bw-carousel-control-prev'] = { 'left': '10px' };
1588
+ rules['.bw-carousel-control-next'] = { 'right': '10px' };
1589
+ rules['.bw-carousel-indicators'] = {
1590
+ 'position': 'absolute', 'bottom': '12px', 'left': '50%', 'transform': 'translateX(-50%)',
1591
+ 'display': 'flex', 'gap': '6px', 'z-index': '2'
1592
+ };
1593
+ rules['.bw-carousel-indicator'] = {
1594
+ 'width': '10px', 'height': '10px', 'border-radius': '50%', 'border': '2px solid transparent',
1595
+ 'padding': '0', 'cursor': 'pointer', 'transition': 'opacity 0.2s ease, background-color 0.2s ease'
1596
+ };
1597
+
1551
1598
  // Toast (structural)
1552
1599
  rules['.bw-toast-container'] = {
1553
1600
  'position': 'fixed', 'z-index': '1080', 'pointer-events': 'none',
@@ -1597,12 +1644,12 @@ function getStructuralStyles() {
1597
1644
  rules['.bw-form-switch .bw-switch-input:disabled'] = { 'opacity': '0.5', 'cursor': 'not-allowed' };
1598
1645
 
1599
1646
  // Skeleton (structural)
1600
- rules['.bw-skeleton'] = { 'border-radius': '4px', 'animation': 'bw-skeleton-pulse 1.5s ease-in-out infinite' };
1647
+ rules['.bw-skeleton'] = { 'border-radius': '4px', 'background-size': '400% 100%', 'animation': 'bw-skeleton-shimmer 1.4s ease infinite' };
1601
1648
  rules['.bw-skeleton-text'] = { 'height': '1em', 'margin-bottom': '0.5rem' };
1602
1649
  rules['.bw-skeleton-circle'] = { 'border-radius': '50%' };
1603
1650
  rules['.bw-skeleton-rect'] = { 'border-radius': '8px' };
1604
1651
  rules['.bw-skeleton-group'] = { 'display': 'flex', 'flex-direction': 'column' };
1605
- rules['@keyframes bw-skeleton-pulse'] = { '0%': { 'opacity': '1' }, '50%': { 'opacity': '0.4' }, '100%': { 'opacity': '1' } };
1652
+ rules['@keyframes bw-skeleton-shimmer'] = { '0%': { 'background-position': '100% 50%' }, '100%': { 'background-position': '0 50%' } };
1606
1653
 
1607
1654
  // Avatar (structural)
1608
1655
  rules['.bw-avatar'] = {
@@ -1964,12 +2011,31 @@ function generateDarkModeCSS(palette) {
1964
2011
  '.bw-dark .bw-accordion-button': {
1965
2012
  'color': textColor
1966
2013
  },
2014
+ '.bw-dark .bw-accordion-button:not(.bw-collapsed)': {
2015
+ 'color': '#7dd3e0',
2016
+ 'background-color': 'rgba(125, 211, 224, 0.1)'
2017
+ },
1967
2018
  '.bw-dark .bw-accordion-button:hover': {
1968
2019
  'background-color': bodyBg
1969
2020
  },
2021
+ '.bw-dark .bw-accordion-button:not(.bw-collapsed):hover': {
2022
+ 'background-color': 'rgba(125, 211, 224, 0.15)'
2023
+ },
2024
+ '.bw-dark .bw-accordion-button:focus-visible': {
2025
+ 'box-shadow': '0 0 0 0.2rem rgba(125, 211, 224, 0.3)'
2026
+ },
1970
2027
  '.bw-dark .bw-accordion-body': {
1971
2028
  'border-top-color': borderColor
1972
2029
  },
2030
+ '.bw-dark .bw-carousel': {
2031
+ 'background-color': bodyBg
2032
+ },
2033
+ '.bw-dark .bw-carousel-control': {
2034
+ 'background-color': 'rgba(255,255,255,0.15)'
2035
+ },
2036
+ '.bw-dark .bw-carousel-control:hover': {
2037
+ 'background-color': 'rgba(255,255,255,0.25)'
2038
+ },
1973
2039
  '.bw-dark .bw-modal-content': {
1974
2040
  'background-color': surfaceBg,
1975
2041
  'border-color': borderColor
@@ -2005,7 +2071,7 @@ function generateDarkModeCSS(palette) {
2005
2071
  'border-top-color': borderColor
2006
2072
  },
2007
2073
  '.bw-dark .bw-skeleton': {
2008
- 'background-color': borderColor
2074
+ 'background': 'linear-gradient(90deg, ' + borderColor + ' 25%, ' + surfaceBg + ' 37%, ' + borderColor + ' 63%)'
2009
2075
  },
2010
2076
  '.bw-dark h1, .bw-dark h2, .bw-dark h3, .bw-dark h4, .bw-dark h5, .bw-dark h6': {
2011
2077
  'color': textColor
@@ -2466,6 +2532,26 @@ bw.escapeHTML = function(str) {
2466
2532
  return str.replace(/[&<>"'/]/g, (char) => escapeMap[char]);
2467
2533
  };
2468
2534
 
2535
+ /**
2536
+ * Mark a string as raw HTML so it will not be escaped by bw.html() or bw.createDOM().
2537
+ *
2538
+ * By default, bitwrench escapes all text content to prevent XSS. Use bw.raw()
2539
+ * when you need to embed pre-sanitized HTML, entities, or inline markup.
2540
+ *
2541
+ * @param {string} str - HTML string to mark as raw
2542
+ * @returns {Object} Marked object recognized by bw.html() and bw.createDOM()
2543
+ * @category DOM Generation
2544
+ * @see bw.escapeHTML
2545
+ * @see bw.html
2546
+ * @example
2547
+ * bw.raw('Hello &mdash; World')
2548
+ * // Used in TACO content:
2549
+ * { t: 'p', c: bw.raw('Price: <strong>$9.99</strong>') }
2550
+ */
2551
+ bw.raw = function(str) {
2552
+ return { __bw_raw: true, v: String(str) };
2553
+ };
2554
+
2469
2555
  /**
2470
2556
  * Normalize CSS class names by converting underscores to hyphens for bw-prefixed classes.
2471
2557
  *
@@ -2517,6 +2603,11 @@ bw.html = function(taco, options = {}) {
2517
2603
  return taco.map(t => bw.html(t, options)).join('');
2518
2604
  }
2519
2605
 
2606
+ // Handle bw.raw() marked content
2607
+ if (taco && taco.__bw_raw) {
2608
+ return taco.v;
2609
+ }
2610
+
2520
2611
  // Handle primitives and non-TACO objects
2521
2612
  if (typeof taco !== 'object' || !taco.t) {
2522
2613
  return options.raw ? String(taco) : bw.escapeHTML(String(taco));
@@ -2617,12 +2708,21 @@ bw.createDOM = function(taco, options = {}) {
2617
2708
 
2618
2709
  // Handle null/undefined
2619
2710
  if (taco == null) return document.createTextNode('');
2620
-
2711
+
2712
+ // Handle bw.raw() marked content — inject as HTML
2713
+ if (taco && taco.__bw_raw) {
2714
+ var frag = document.createDocumentFragment();
2715
+ var tmp = document.createElement('span');
2716
+ tmp.innerHTML = taco.v;
2717
+ while (tmp.firstChild) frag.appendChild(tmp.firstChild);
2718
+ return frag;
2719
+ }
2720
+
2621
2721
  // Handle text nodes
2622
2722
  if (typeof taco !== 'object' || !taco.t) {
2623
2723
  return document.createTextNode(String(taco));
2624
2724
  }
2625
-
2725
+
2626
2726
  const { t: tag, a: attrs = {}, c: content, o: opts = {} } = taco;
2627
2727
 
2628
2728
  // Create element
@@ -2687,6 +2787,9 @@ bw.createDOM = function(taco, options = {}) {
2687
2787
  }
2688
2788
  }
2689
2789
  });
2790
+ } else if (typeof content === 'object' && content.__bw_raw) {
2791
+ // Raw HTML content — inject via innerHTML
2792
+ el.innerHTML = content.v;
2690
2793
  } else if (typeof content === 'object' && content.t) {
2691
2794
  var childEl = bw.createDOM(content, options);
2692
2795
  el.appendChild(childEl);