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.
- package/dist/bitwrench-code-edit.cjs.js +1 -1
- package/dist/bitwrench-code-edit.es5.js +1 -1
- package/dist/bitwrench-code-edit.es5.min.js +1 -1
- package/dist/bitwrench-code-edit.esm.js +1 -1
- package/dist/bitwrench-code-edit.esm.min.js +1 -1
- package/dist/bitwrench-code-edit.umd.js +1 -1
- package/dist/bitwrench-code-edit.umd.min.js +1 -1
- package/dist/bitwrench-lean.cjs.js +112 -9
- package/dist/bitwrench-lean.cjs.min.js +5 -5
- package/dist/bitwrench-lean.es5.js +178 -14
- package/dist/bitwrench-lean.es5.min.js +3 -3
- package/dist/bitwrench-lean.esm.js +112 -9
- package/dist/bitwrench-lean.esm.min.js +5 -5
- package/dist/bitwrench-lean.umd.js +112 -9
- package/dist/bitwrench-lean.umd.min.js +5 -5
- package/dist/bitwrench.cjs.js +289 -9
- package/dist/bitwrench.cjs.min.js +5 -5
- package/dist/bitwrench.css +425 -21
- package/dist/bitwrench.es5.js +378 -14
- package/dist/bitwrench.es5.min.js +4 -4
- package/dist/bitwrench.esm.js +289 -9
- package/dist/bitwrench.esm.min.js +5 -5
- package/dist/bitwrench.umd.js +289 -9
- package/dist/bitwrench.umd.min.js +5 -5
- package/dist/builds.json +61 -61
- package/dist/sri.json +25 -25
- package/package.json +1 -1
- package/readme.html +1 -1
- package/src/bitwrench-components-v2.js +176 -0
- package/src/bitwrench-styles.js +208 -15
- package/src/bitwrench.js +39 -2
- package/src/generate-css.js +20 -3
- package/src/version.js +3 -3
package/dist/bitwrench.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! bitwrench v2.0.
|
|
1
|
+
/*! bitwrench v2.0.12 | BSD-2-Clause | https://deftio.github.com/bitwrench/pages */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const VERSION_INFO = {
|
|
10
|
-
version: '2.0.
|
|
10
|
+
version: '2.0.12',
|
|
11
11
|
name: 'bitwrench',
|
|
12
12
|
description: 'A library for javascript UI functions.',
|
|
13
13
|
license: 'BSD-2-Clause',
|
|
14
14
|
homepage: 'https://deftio.github.com/bitwrench/pages',
|
|
15
15
|
repository: 'git+https://github.com/deftio/bitwrench.git',
|
|
16
16
|
author: 'manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)',
|
|
17
|
-
buildDate: '2026-03-
|
|
17
|
+
buildDate: '2026-03-07T22:31:35.755Z'
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -889,15 +889,36 @@ function generateAccordionThemed(scope, palette) {
|
|
|
889
889
|
rules[scopeSelector(scope, '.bw-accordion-button')] = {
|
|
890
890
|
'color': palette.dark.base
|
|
891
891
|
};
|
|
892
|
+
rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed)')] = {
|
|
893
|
+
'color': palette.primary.darkText,
|
|
894
|
+
'background-color': palette.primary.light
|
|
895
|
+
};
|
|
892
896
|
rules[scopeSelector(scope, '.bw-accordion-button:hover')] = {
|
|
893
897
|
'background-color': palette.light.light
|
|
894
898
|
};
|
|
899
|
+
rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed):hover')] = {
|
|
900
|
+
'background-color': palette.primary.hover
|
|
901
|
+
};
|
|
902
|
+
rules[scopeSelector(scope, '.bw-accordion-button:focus-visible')] = {
|
|
903
|
+
'box-shadow': '0 0 0 0.2rem ' + palette.primary.focus
|
|
904
|
+
};
|
|
895
905
|
rules[scopeSelector(scope, '.bw-accordion-body')] = {
|
|
896
906
|
'border-top': '1px solid ' + palette.light.border
|
|
897
907
|
};
|
|
898
908
|
return rules;
|
|
899
909
|
}
|
|
900
910
|
|
|
911
|
+
function generateCarouselThemed(scope, palette) {
|
|
912
|
+
var rules = {};
|
|
913
|
+
rules[scopeSelector(scope, '.bw-carousel')] = {
|
|
914
|
+
'background-color': palette.light.light
|
|
915
|
+
};
|
|
916
|
+
rules[scopeSelector(scope, '.bw-carousel-indicator.active')] = {
|
|
917
|
+
'background-color': palette.primary.base
|
|
918
|
+
};
|
|
919
|
+
return rules;
|
|
920
|
+
}
|
|
921
|
+
|
|
901
922
|
function generateModalThemed(scope, palette) {
|
|
902
923
|
var rules = {};
|
|
903
924
|
rules[scopeSelector(scope, '.bw-modal-content')] = {
|
|
@@ -978,7 +999,7 @@ function generateSwitchThemed(scope, palette) {
|
|
|
978
999
|
function generateSkeletonThemed(scope, palette) {
|
|
979
1000
|
var rules = {};
|
|
980
1001
|
rules[scopeSelector(scope, '.bw-skeleton')] = {
|
|
981
|
-
'background
|
|
1002
|
+
'background': 'linear-gradient(90deg, ' + palette.light.border + ' 25%, ' + palette.light.light + ' 37%, ' + palette.light.border + ' 63%)'
|
|
982
1003
|
};
|
|
983
1004
|
return rules;
|
|
984
1005
|
}
|
|
@@ -1025,6 +1046,7 @@ function generateThemedCSS(scopeName, palette, layout) {
|
|
|
1025
1046
|
generateCloseButtonThemed(scopeName, palette),
|
|
1026
1047
|
generateSectionsThemed(scopeName, palette),
|
|
1027
1048
|
generateAccordionThemed(scopeName, palette),
|
|
1049
|
+
generateCarouselThemed(scopeName, palette),
|
|
1028
1050
|
generateModalThemed(scopeName, palette),
|
|
1029
1051
|
generateToastThemed(scopeName, palette),
|
|
1030
1052
|
generateDropdownThemed(scopeName, palette),
|
|
@@ -1384,6 +1406,8 @@ function getStructuralStyles() {
|
|
|
1384
1406
|
rules['.bw-tab-content'] = { 'padding': '1.25rem 0' };
|
|
1385
1407
|
rules['.bw-tab-pane'] = { 'display': 'none' };
|
|
1386
1408
|
rules['.bw-tab-pane.active'] = { 'display': 'block' };
|
|
1409
|
+
rules['.bw-nav-scrollable'] = { 'flex-wrap': 'nowrap', 'overflow-x': 'auto', '-webkit-overflow-scrolling': 'touch', 'scrollbar-width': 'none' };
|
|
1410
|
+
rules['.bw-nav-scrollable .bw-nav-link'] = { 'white-space': 'nowrap' };
|
|
1387
1411
|
|
|
1388
1412
|
// List groups (structural)
|
|
1389
1413
|
rules['.bw-list-group'] = { 'display': 'flex', 'flex-direction': 'column', 'padding-left': '0', 'margin-bottom': '0', 'border-radius': '0.375rem' };
|
|
@@ -1550,6 +1574,29 @@ function getStructuralStyles() {
|
|
|
1550
1574
|
rules['.bw-modal-body'] = { 'position': 'relative', 'flex': '1 1 auto', 'padding': '1.5rem' };
|
|
1551
1575
|
rules['.bw-modal-footer'] = { 'display': 'flex', 'flex-wrap': 'wrap', 'align-items': 'center', 'justify-content': 'flex-end', 'padding': '0.75rem 1.5rem', 'gap': '0.5rem' };
|
|
1552
1576
|
|
|
1577
|
+
// Carousel (structural)
|
|
1578
|
+
rules['.bw-carousel'] = { 'position': 'relative', 'overflow': 'hidden', 'border-radius': '8px' };
|
|
1579
|
+
rules['.bw-carousel-track'] = { 'display': 'flex', 'transition': 'transform 0.4s ease', 'height': '100%' };
|
|
1580
|
+
rules['.bw-carousel-slide'] = { 'min-width': '100%', 'flex-shrink': '0', 'overflow': 'hidden', 'position': 'relative', 'display': 'flex', 'align-items': 'center', 'justify-content': 'center' };
|
|
1581
|
+
rules['.bw-carousel-slide img'] = { 'width': '100%', 'height': '100%', 'object-fit': 'cover' };
|
|
1582
|
+
rules['.bw-carousel-caption'] = { 'position': 'absolute', 'bottom': '0', 'left': '0', 'right': '0', 'padding': '0.75rem 1rem' };
|
|
1583
|
+
rules['.bw-carousel-control'] = {
|
|
1584
|
+
'position': 'absolute', 'top': '50%', 'transform': 'translateY(-50%)', 'width': '40px', 'height': '40px',
|
|
1585
|
+
'border': 'none', 'border-radius': '50%', 'cursor': 'pointer', 'display': 'flex', 'align-items': 'center',
|
|
1586
|
+
'justify-content': 'center', 'z-index': '2', 'padding': '0', 'transition': 'background-color 0.2s ease'
|
|
1587
|
+
};
|
|
1588
|
+
rules['.bw-carousel-control img'] = { 'width': '20px', 'height': '20px', 'pointer-events': 'none' };
|
|
1589
|
+
rules['.bw-carousel-control-prev'] = { 'left': '10px' };
|
|
1590
|
+
rules['.bw-carousel-control-next'] = { 'right': '10px' };
|
|
1591
|
+
rules['.bw-carousel-indicators'] = {
|
|
1592
|
+
'position': 'absolute', 'bottom': '12px', 'left': '50%', 'transform': 'translateX(-50%)',
|
|
1593
|
+
'display': 'flex', 'gap': '6px', 'z-index': '2'
|
|
1594
|
+
};
|
|
1595
|
+
rules['.bw-carousel-indicator'] = {
|
|
1596
|
+
'width': '10px', 'height': '10px', 'border-radius': '50%', 'border': '2px solid transparent',
|
|
1597
|
+
'padding': '0', 'cursor': 'pointer', 'transition': 'opacity 0.2s ease, background-color 0.2s ease'
|
|
1598
|
+
};
|
|
1599
|
+
|
|
1553
1600
|
// Toast (structural)
|
|
1554
1601
|
rules['.bw-toast-container'] = {
|
|
1555
1602
|
'position': 'fixed', 'z-index': '1080', 'pointer-events': 'none',
|
|
@@ -1599,12 +1646,12 @@ function getStructuralStyles() {
|
|
|
1599
1646
|
rules['.bw-form-switch .bw-switch-input:disabled'] = { 'opacity': '0.5', 'cursor': 'not-allowed' };
|
|
1600
1647
|
|
|
1601
1648
|
// Skeleton (structural)
|
|
1602
|
-
rules['.bw-skeleton'] = { 'border-radius': '4px', 'animation': 'bw-skeleton-
|
|
1649
|
+
rules['.bw-skeleton'] = { 'border-radius': '4px', 'background-size': '400% 100%', 'animation': 'bw-skeleton-shimmer 1.4s ease infinite' };
|
|
1603
1650
|
rules['.bw-skeleton-text'] = { 'height': '1em', 'margin-bottom': '0.5rem' };
|
|
1604
1651
|
rules['.bw-skeleton-circle'] = { 'border-radius': '50%' };
|
|
1605
1652
|
rules['.bw-skeleton-rect'] = { 'border-radius': '8px' };
|
|
1606
1653
|
rules['.bw-skeleton-group'] = { 'display': 'flex', 'flex-direction': 'column' };
|
|
1607
|
-
rules['@keyframes bw-skeleton-
|
|
1654
|
+
rules['@keyframes bw-skeleton-shimmer'] = { '0%': { 'background-position': '100% 50%' }, '100%': { 'background-position': '0 50%' } };
|
|
1608
1655
|
|
|
1609
1656
|
// Avatar (structural)
|
|
1610
1657
|
rules['.bw-avatar'] = {
|
|
@@ -1966,12 +2013,31 @@ function generateDarkModeCSS(palette) {
|
|
|
1966
2013
|
'.bw-dark .bw-accordion-button': {
|
|
1967
2014
|
'color': textColor
|
|
1968
2015
|
},
|
|
2016
|
+
'.bw-dark .bw-accordion-button:not(.bw-collapsed)': {
|
|
2017
|
+
'color': '#7dd3e0',
|
|
2018
|
+
'background-color': 'rgba(125, 211, 224, 0.1)'
|
|
2019
|
+
},
|
|
1969
2020
|
'.bw-dark .bw-accordion-button:hover': {
|
|
1970
2021
|
'background-color': bodyBg
|
|
1971
2022
|
},
|
|
2023
|
+
'.bw-dark .bw-accordion-button:not(.bw-collapsed):hover': {
|
|
2024
|
+
'background-color': 'rgba(125, 211, 224, 0.15)'
|
|
2025
|
+
},
|
|
2026
|
+
'.bw-dark .bw-accordion-button:focus-visible': {
|
|
2027
|
+
'box-shadow': '0 0 0 0.2rem rgba(125, 211, 224, 0.3)'
|
|
2028
|
+
},
|
|
1972
2029
|
'.bw-dark .bw-accordion-body': {
|
|
1973
2030
|
'border-top-color': borderColor
|
|
1974
2031
|
},
|
|
2032
|
+
'.bw-dark .bw-carousel': {
|
|
2033
|
+
'background-color': bodyBg
|
|
2034
|
+
},
|
|
2035
|
+
'.bw-dark .bw-carousel-control': {
|
|
2036
|
+
'background-color': 'rgba(255,255,255,0.15)'
|
|
2037
|
+
},
|
|
2038
|
+
'.bw-dark .bw-carousel-control:hover': {
|
|
2039
|
+
'background-color': 'rgba(255,255,255,0.25)'
|
|
2040
|
+
},
|
|
1975
2041
|
'.bw-dark .bw-modal-content': {
|
|
1976
2042
|
'background-color': surfaceBg,
|
|
1977
2043
|
'border-color': borderColor
|
|
@@ -2007,7 +2073,7 @@ function generateDarkModeCSS(palette) {
|
|
|
2007
2073
|
'border-top-color': borderColor
|
|
2008
2074
|
},
|
|
2009
2075
|
'.bw-dark .bw-skeleton': {
|
|
2010
|
-
'background
|
|
2076
|
+
'background': 'linear-gradient(90deg, ' + borderColor + ' 25%, ' + surfaceBg + ' 37%, ' + borderColor + ' 63%)'
|
|
2011
2077
|
},
|
|
2012
2078
|
'.bw-dark h1, .bw-dark h2, .bw-dark h3, .bw-dark h4, .bw-dark h5, .bw-dark h6': {
|
|
2013
2079
|
'color': textColor
|
|
@@ -4757,6 +4823,182 @@ function makeAvatar(props = {}) {
|
|
|
4757
4823
|
};
|
|
4758
4824
|
}
|
|
4759
4825
|
|
|
4826
|
+
/**
|
|
4827
|
+
* Create a carousel/slideshow component with slide transitions
|
|
4828
|
+
*
|
|
4829
|
+
* Supports image slides, TACO content slides, captions, prev/next controls,
|
|
4830
|
+
* dot indicators, and optional auto-play. Uses CSS translateX transitions.
|
|
4831
|
+
*
|
|
4832
|
+
* @param {Object} [props] - Carousel configuration
|
|
4833
|
+
* @param {Array<Object>} [props.items=[]] - Slide items
|
|
4834
|
+
* @param {string|Object} props.items[].content - Slide content (TACO, string, or img element)
|
|
4835
|
+
* @param {string} [props.items[].caption] - Caption text shown at bottom of slide
|
|
4836
|
+
* @param {boolean} [props.showControls=true] - Show prev/next arrow buttons
|
|
4837
|
+
* @param {boolean} [props.showIndicators=true] - Show dot navigation
|
|
4838
|
+
* @param {boolean} [props.autoPlay=false] - Auto-advance slides
|
|
4839
|
+
* @param {number} [props.interval=5000] - Auto-advance interval in ms
|
|
4840
|
+
* @param {string} [props.height='300px'] - Carousel height
|
|
4841
|
+
* @param {number} [props.startIndex=0] - Initial slide index
|
|
4842
|
+
* @param {string} [props.className] - Additional CSS classes
|
|
4843
|
+
* @returns {Object} TACO object representing a carousel
|
|
4844
|
+
* @category Component Builders
|
|
4845
|
+
* @example
|
|
4846
|
+
* const carousel = makeCarousel({
|
|
4847
|
+
* items: [
|
|
4848
|
+
* { content: { t: 'img', a: { src: 'photo.jpg' } }, caption: 'Photo 1' },
|
|
4849
|
+
* { content: { t: 'div', c: 'Text slide' } }
|
|
4850
|
+
* ],
|
|
4851
|
+
* autoPlay: true,
|
|
4852
|
+
* interval: 3000
|
|
4853
|
+
* });
|
|
4854
|
+
*/
|
|
4855
|
+
function makeCarousel(props = {}) {
|
|
4856
|
+
const {
|
|
4857
|
+
items = [],
|
|
4858
|
+
showControls = true,
|
|
4859
|
+
showIndicators = true,
|
|
4860
|
+
autoPlay = false,
|
|
4861
|
+
interval = 5000,
|
|
4862
|
+
height = '300px',
|
|
4863
|
+
startIndex = 0,
|
|
4864
|
+
className = ''
|
|
4865
|
+
} = props;
|
|
4866
|
+
|
|
4867
|
+
// Shared navigation logic
|
|
4868
|
+
function goToSlide(carouselEl, index) {
|
|
4869
|
+
var total = carouselEl.querySelectorAll('.bw-carousel-slide').length;
|
|
4870
|
+
if (index < 0) index = total - 1;
|
|
4871
|
+
if (index >= total) index = 0;
|
|
4872
|
+
carouselEl.setAttribute('data-carousel-index', index);
|
|
4873
|
+
var track = carouselEl.querySelector('.bw-carousel-track');
|
|
4874
|
+
track.style.transform = 'translateX(-' + (index * 100) + '%)';
|
|
4875
|
+
// Update indicators
|
|
4876
|
+
var indicators = carouselEl.querySelectorAll('.bw-carousel-indicator');
|
|
4877
|
+
for (var i = 0; i < indicators.length; i++) {
|
|
4878
|
+
if (i === index) {
|
|
4879
|
+
indicators[i].classList.add('active');
|
|
4880
|
+
} else {
|
|
4881
|
+
indicators[i].classList.remove('active');
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
|
|
4886
|
+
// Arrow SVGs (inline data URIs, same pattern as accordion chevrons)
|
|
4887
|
+
var prevArrow = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e";
|
|
4888
|
+
var nextArrow = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e";
|
|
4889
|
+
|
|
4890
|
+
var slides = items.map(function(item) {
|
|
4891
|
+
var slideContent = [
|
|
4892
|
+
item.content,
|
|
4893
|
+
item.caption && {
|
|
4894
|
+
t: 'div',
|
|
4895
|
+
a: { class: 'bw-carousel-caption' },
|
|
4896
|
+
c: item.caption
|
|
4897
|
+
}
|
|
4898
|
+
].filter(Boolean);
|
|
4899
|
+
|
|
4900
|
+
return {
|
|
4901
|
+
t: 'div',
|
|
4902
|
+
a: { class: 'bw-carousel-slide' },
|
|
4903
|
+
c: slideContent.length === 1 ? slideContent[0] : slideContent
|
|
4904
|
+
};
|
|
4905
|
+
});
|
|
4906
|
+
|
|
4907
|
+
var children = [
|
|
4908
|
+
// Track
|
|
4909
|
+
{
|
|
4910
|
+
t: 'div',
|
|
4911
|
+
a: {
|
|
4912
|
+
class: 'bw-carousel-track',
|
|
4913
|
+
style: 'transform: translateX(-' + (startIndex * 100) + '%)'
|
|
4914
|
+
},
|
|
4915
|
+
c: slides
|
|
4916
|
+
}
|
|
4917
|
+
];
|
|
4918
|
+
|
|
4919
|
+
// Prev/Next controls
|
|
4920
|
+
if (showControls && items.length > 1) {
|
|
4921
|
+
children.push({
|
|
4922
|
+
t: 'button',
|
|
4923
|
+
a: {
|
|
4924
|
+
class: 'bw-carousel-control bw-carousel-control-prev',
|
|
4925
|
+
type: 'button',
|
|
4926
|
+
'aria-label': 'Previous slide',
|
|
4927
|
+
onclick: function(e) {
|
|
4928
|
+
var carousel = e.target.closest('.bw-carousel');
|
|
4929
|
+
var idx = parseInt(carousel.getAttribute('data-carousel-index') || '0');
|
|
4930
|
+
goToSlide(carousel, idx - 1);
|
|
4931
|
+
}
|
|
4932
|
+
},
|
|
4933
|
+
c: { t: 'img', a: { src: prevArrow, alt: '', role: 'presentation' } }
|
|
4934
|
+
});
|
|
4935
|
+
children.push({
|
|
4936
|
+
t: 'button',
|
|
4937
|
+
a: {
|
|
4938
|
+
class: 'bw-carousel-control bw-carousel-control-next',
|
|
4939
|
+
type: 'button',
|
|
4940
|
+
'aria-label': 'Next slide',
|
|
4941
|
+
onclick: function(e) {
|
|
4942
|
+
var carousel = e.target.closest('.bw-carousel');
|
|
4943
|
+
var idx = parseInt(carousel.getAttribute('data-carousel-index') || '0');
|
|
4944
|
+
goToSlide(carousel, idx + 1);
|
|
4945
|
+
}
|
|
4946
|
+
},
|
|
4947
|
+
c: { t: 'img', a: { src: nextArrow, alt: '', role: 'presentation' } }
|
|
4948
|
+
});
|
|
4949
|
+
}
|
|
4950
|
+
|
|
4951
|
+
// Indicators
|
|
4952
|
+
if (showIndicators && items.length > 1) {
|
|
4953
|
+
children.push({
|
|
4954
|
+
t: 'div',
|
|
4955
|
+
a: { class: 'bw-carousel-indicators' },
|
|
4956
|
+
c: items.map(function(_, i) {
|
|
4957
|
+
return {
|
|
4958
|
+
t: 'button',
|
|
4959
|
+
a: {
|
|
4960
|
+
class: 'bw-carousel-indicator' + (i === startIndex ? ' active' : ''),
|
|
4961
|
+
type: 'button',
|
|
4962
|
+
'aria-label': 'Go to slide ' + (i + 1),
|
|
4963
|
+
'data-slide-index': i,
|
|
4964
|
+
onclick: function(e) {
|
|
4965
|
+
var carousel = e.target.closest('.bw-carousel');
|
|
4966
|
+
var idx = parseInt(e.target.getAttribute('data-slide-index'));
|
|
4967
|
+
goToSlide(carousel, idx);
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
};
|
|
4971
|
+
})
|
|
4972
|
+
});
|
|
4973
|
+
}
|
|
4974
|
+
|
|
4975
|
+
return {
|
|
4976
|
+
t: 'div',
|
|
4977
|
+
a: {
|
|
4978
|
+
class: ('bw-carousel ' + className).trim(),
|
|
4979
|
+
style: 'height: ' + height,
|
|
4980
|
+
'data-carousel-index': startIndex
|
|
4981
|
+
},
|
|
4982
|
+
c: children,
|
|
4983
|
+
o: {
|
|
4984
|
+
type: 'carousel',
|
|
4985
|
+
state: { activeIndex: startIndex, autoPlay: autoPlay, interval: interval },
|
|
4986
|
+
mounted: autoPlay ? function(el) {
|
|
4987
|
+
var intervalId = setInterval(function() {
|
|
4988
|
+
var idx = parseInt(el.getAttribute('data-carousel-index') || '0');
|
|
4989
|
+
goToSlide(el, idx + 1);
|
|
4990
|
+
}, interval);
|
|
4991
|
+
el._bw_carouselInterval = intervalId;
|
|
4992
|
+
} : undefined,
|
|
4993
|
+
unmount: autoPlay ? function(el) {
|
|
4994
|
+
if (el._bw_carouselInterval) {
|
|
4995
|
+
clearInterval(el._bw_carouselInterval);
|
|
4996
|
+
}
|
|
4997
|
+
} : undefined
|
|
4998
|
+
}
|
|
4999
|
+
};
|
|
5000
|
+
}
|
|
5001
|
+
|
|
4760
5002
|
const componentHandles = {
|
|
4761
5003
|
card: CardHandle,
|
|
4762
5004
|
table: TableHandle,
|
|
@@ -4782,6 +5024,7 @@ var components = /*#__PURE__*/Object.freeze({
|
|
|
4782
5024
|
makeButtonGroup: makeButtonGroup,
|
|
4783
5025
|
makeCTA: makeCTA,
|
|
4784
5026
|
makeCard: makeCard,
|
|
5027
|
+
makeCarousel: makeCarousel,
|
|
4785
5028
|
makeCheckbox: makeCheckbox,
|
|
4786
5029
|
makeCodeDemo: makeCodeDemo,
|
|
4787
5030
|
makeCol: makeCol,
|
|
@@ -5231,6 +5474,26 @@ bw.escapeHTML = function(str) {
|
|
|
5231
5474
|
return str.replace(/[&<>"'/]/g, (char) => escapeMap[char]);
|
|
5232
5475
|
};
|
|
5233
5476
|
|
|
5477
|
+
/**
|
|
5478
|
+
* Mark a string as raw HTML so it will not be escaped by bw.html() or bw.createDOM().
|
|
5479
|
+
*
|
|
5480
|
+
* By default, bitwrench escapes all text content to prevent XSS. Use bw.raw()
|
|
5481
|
+
* when you need to embed pre-sanitized HTML, entities, or inline markup.
|
|
5482
|
+
*
|
|
5483
|
+
* @param {string} str - HTML string to mark as raw
|
|
5484
|
+
* @returns {Object} Marked object recognized by bw.html() and bw.createDOM()
|
|
5485
|
+
* @category DOM Generation
|
|
5486
|
+
* @see bw.escapeHTML
|
|
5487
|
+
* @see bw.html
|
|
5488
|
+
* @example
|
|
5489
|
+
* bw.raw('Hello — World')
|
|
5490
|
+
* // Used in TACO content:
|
|
5491
|
+
* { t: 'p', c: bw.raw('Price: <strong>$9.99</strong>') }
|
|
5492
|
+
*/
|
|
5493
|
+
bw.raw = function(str) {
|
|
5494
|
+
return { __bw_raw: true, v: String(str) };
|
|
5495
|
+
};
|
|
5496
|
+
|
|
5234
5497
|
/**
|
|
5235
5498
|
* Normalize CSS class names by converting underscores to hyphens for bw-prefixed classes.
|
|
5236
5499
|
*
|
|
@@ -5282,6 +5545,11 @@ bw.html = function(taco, options = {}) {
|
|
|
5282
5545
|
return taco.map(t => bw.html(t, options)).join('');
|
|
5283
5546
|
}
|
|
5284
5547
|
|
|
5548
|
+
// Handle bw.raw() marked content
|
|
5549
|
+
if (taco && taco.__bw_raw) {
|
|
5550
|
+
return taco.v;
|
|
5551
|
+
}
|
|
5552
|
+
|
|
5285
5553
|
// Handle primitives and non-TACO objects
|
|
5286
5554
|
if (typeof taco !== 'object' || !taco.t) {
|
|
5287
5555
|
return options.raw ? String(taco) : bw.escapeHTML(String(taco));
|
|
@@ -5382,12 +5650,21 @@ bw.createDOM = function(taco, options = {}) {
|
|
|
5382
5650
|
|
|
5383
5651
|
// Handle null/undefined
|
|
5384
5652
|
if (taco == null) return document.createTextNode('');
|
|
5385
|
-
|
|
5653
|
+
|
|
5654
|
+
// Handle bw.raw() marked content — inject as HTML
|
|
5655
|
+
if (taco && taco.__bw_raw) {
|
|
5656
|
+
var frag = document.createDocumentFragment();
|
|
5657
|
+
var tmp = document.createElement('span');
|
|
5658
|
+
tmp.innerHTML = taco.v;
|
|
5659
|
+
while (tmp.firstChild) frag.appendChild(tmp.firstChild);
|
|
5660
|
+
return frag;
|
|
5661
|
+
}
|
|
5662
|
+
|
|
5386
5663
|
// Handle text nodes
|
|
5387
5664
|
if (typeof taco !== 'object' || !taco.t) {
|
|
5388
5665
|
return document.createTextNode(String(taco));
|
|
5389
5666
|
}
|
|
5390
|
-
|
|
5667
|
+
|
|
5391
5668
|
const { t: tag, a: attrs = {}, c: content, o: opts = {} } = taco;
|
|
5392
5669
|
|
|
5393
5670
|
// Create element
|
|
@@ -5452,6 +5729,9 @@ bw.createDOM = function(taco, options = {}) {
|
|
|
5452
5729
|
}
|
|
5453
5730
|
}
|
|
5454
5731
|
});
|
|
5732
|
+
} else if (typeof content === 'object' && content.__bw_raw) {
|
|
5733
|
+
// Raw HTML content — inject via innerHTML
|
|
5734
|
+
el.innerHTML = content.v;
|
|
5455
5735
|
} else if (typeof content === 'object' && content.t) {
|
|
5456
5736
|
var childEl = bw.createDOM(content, options);
|
|
5457
5737
|
el.appendChild(childEl);
|