bitwrench 2.0.11 → 2.0.13
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 +60 -60
- 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.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! bitwrench v2.0.
|
|
1
|
+
/*! bitwrench v2.0.13 | 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) :
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
const VERSION_INFO = {
|
|
14
|
-
version: '2.0.
|
|
14
|
+
version: '2.0.13',
|
|
15
15
|
name: 'bitwrench',
|
|
16
16
|
description: 'A library for javascript UI functions.',
|
|
17
17
|
license: 'BSD-2-Clause',
|
|
18
18
|
homepage: 'https://deftio.github.com/bitwrench/pages',
|
|
19
19
|
repository: 'git+https://github.com/deftio/bitwrench.git',
|
|
20
20
|
author: 'manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)',
|
|
21
|
-
buildDate: '2026-03-
|
|
21
|
+
buildDate: '2026-03-07T22:35:06.056Z'
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -893,15 +893,36 @@
|
|
|
893
893
|
rules[scopeSelector(scope, '.bw-accordion-button')] = {
|
|
894
894
|
'color': palette.dark.base
|
|
895
895
|
};
|
|
896
|
+
rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed)')] = {
|
|
897
|
+
'color': palette.primary.darkText,
|
|
898
|
+
'background-color': palette.primary.light
|
|
899
|
+
};
|
|
896
900
|
rules[scopeSelector(scope, '.bw-accordion-button:hover')] = {
|
|
897
901
|
'background-color': palette.light.light
|
|
898
902
|
};
|
|
903
|
+
rules[scopeSelector(scope, '.bw-accordion-button:not(.bw-collapsed):hover')] = {
|
|
904
|
+
'background-color': palette.primary.hover
|
|
905
|
+
};
|
|
906
|
+
rules[scopeSelector(scope, '.bw-accordion-button:focus-visible')] = {
|
|
907
|
+
'box-shadow': '0 0 0 0.2rem ' + palette.primary.focus
|
|
908
|
+
};
|
|
899
909
|
rules[scopeSelector(scope, '.bw-accordion-body')] = {
|
|
900
910
|
'border-top': '1px solid ' + palette.light.border
|
|
901
911
|
};
|
|
902
912
|
return rules;
|
|
903
913
|
}
|
|
904
914
|
|
|
915
|
+
function generateCarouselThemed(scope, palette) {
|
|
916
|
+
var rules = {};
|
|
917
|
+
rules[scopeSelector(scope, '.bw-carousel')] = {
|
|
918
|
+
'background-color': palette.light.light
|
|
919
|
+
};
|
|
920
|
+
rules[scopeSelector(scope, '.bw-carousel-indicator.active')] = {
|
|
921
|
+
'background-color': palette.primary.base
|
|
922
|
+
};
|
|
923
|
+
return rules;
|
|
924
|
+
}
|
|
925
|
+
|
|
905
926
|
function generateModalThemed(scope, palette) {
|
|
906
927
|
var rules = {};
|
|
907
928
|
rules[scopeSelector(scope, '.bw-modal-content')] = {
|
|
@@ -982,7 +1003,7 @@
|
|
|
982
1003
|
function generateSkeletonThemed(scope, palette) {
|
|
983
1004
|
var rules = {};
|
|
984
1005
|
rules[scopeSelector(scope, '.bw-skeleton')] = {
|
|
985
|
-
'background
|
|
1006
|
+
'background': 'linear-gradient(90deg, ' + palette.light.border + ' 25%, ' + palette.light.light + ' 37%, ' + palette.light.border + ' 63%)'
|
|
986
1007
|
};
|
|
987
1008
|
return rules;
|
|
988
1009
|
}
|
|
@@ -1029,6 +1050,7 @@
|
|
|
1029
1050
|
generateCloseButtonThemed(scopeName, palette),
|
|
1030
1051
|
generateSectionsThemed(scopeName, palette),
|
|
1031
1052
|
generateAccordionThemed(scopeName, palette),
|
|
1053
|
+
generateCarouselThemed(scopeName, palette),
|
|
1032
1054
|
generateModalThemed(scopeName, palette),
|
|
1033
1055
|
generateToastThemed(scopeName, palette),
|
|
1034
1056
|
generateDropdownThemed(scopeName, palette),
|
|
@@ -1388,6 +1410,8 @@
|
|
|
1388
1410
|
rules['.bw-tab-content'] = { 'padding': '1.25rem 0' };
|
|
1389
1411
|
rules['.bw-tab-pane'] = { 'display': 'none' };
|
|
1390
1412
|
rules['.bw-tab-pane.active'] = { 'display': 'block' };
|
|
1413
|
+
rules['.bw-nav-scrollable'] = { 'flex-wrap': 'nowrap', 'overflow-x': 'auto', '-webkit-overflow-scrolling': 'touch', 'scrollbar-width': 'none' };
|
|
1414
|
+
rules['.bw-nav-scrollable .bw-nav-link'] = { 'white-space': 'nowrap' };
|
|
1391
1415
|
|
|
1392
1416
|
// List groups (structural)
|
|
1393
1417
|
rules['.bw-list-group'] = { 'display': 'flex', 'flex-direction': 'column', 'padding-left': '0', 'margin-bottom': '0', 'border-radius': '0.375rem' };
|
|
@@ -1554,6 +1578,29 @@
|
|
|
1554
1578
|
rules['.bw-modal-body'] = { 'position': 'relative', 'flex': '1 1 auto', 'padding': '1.5rem' };
|
|
1555
1579
|
rules['.bw-modal-footer'] = { 'display': 'flex', 'flex-wrap': 'wrap', 'align-items': 'center', 'justify-content': 'flex-end', 'padding': '0.75rem 1.5rem', 'gap': '0.5rem' };
|
|
1556
1580
|
|
|
1581
|
+
// Carousel (structural)
|
|
1582
|
+
rules['.bw-carousel'] = { 'position': 'relative', 'overflow': 'hidden', 'border-radius': '8px' };
|
|
1583
|
+
rules['.bw-carousel-track'] = { 'display': 'flex', 'transition': 'transform 0.4s ease', 'height': '100%' };
|
|
1584
|
+
rules['.bw-carousel-slide'] = { 'min-width': '100%', 'flex-shrink': '0', 'overflow': 'hidden', 'position': 'relative', 'display': 'flex', 'align-items': 'center', 'justify-content': 'center' };
|
|
1585
|
+
rules['.bw-carousel-slide img'] = { 'width': '100%', 'height': '100%', 'object-fit': 'cover' };
|
|
1586
|
+
rules['.bw-carousel-caption'] = { 'position': 'absolute', 'bottom': '0', 'left': '0', 'right': '0', 'padding': '0.75rem 1rem' };
|
|
1587
|
+
rules['.bw-carousel-control'] = {
|
|
1588
|
+
'position': 'absolute', 'top': '50%', 'transform': 'translateY(-50%)', 'width': '40px', 'height': '40px',
|
|
1589
|
+
'border': 'none', 'border-radius': '50%', 'cursor': 'pointer', 'display': 'flex', 'align-items': 'center',
|
|
1590
|
+
'justify-content': 'center', 'z-index': '2', 'padding': '0', 'transition': 'background-color 0.2s ease'
|
|
1591
|
+
};
|
|
1592
|
+
rules['.bw-carousel-control img'] = { 'width': '20px', 'height': '20px', 'pointer-events': 'none' };
|
|
1593
|
+
rules['.bw-carousel-control-prev'] = { 'left': '10px' };
|
|
1594
|
+
rules['.bw-carousel-control-next'] = { 'right': '10px' };
|
|
1595
|
+
rules['.bw-carousel-indicators'] = {
|
|
1596
|
+
'position': 'absolute', 'bottom': '12px', 'left': '50%', 'transform': 'translateX(-50%)',
|
|
1597
|
+
'display': 'flex', 'gap': '6px', 'z-index': '2'
|
|
1598
|
+
};
|
|
1599
|
+
rules['.bw-carousel-indicator'] = {
|
|
1600
|
+
'width': '10px', 'height': '10px', 'border-radius': '50%', 'border': '2px solid transparent',
|
|
1601
|
+
'padding': '0', 'cursor': 'pointer', 'transition': 'opacity 0.2s ease, background-color 0.2s ease'
|
|
1602
|
+
};
|
|
1603
|
+
|
|
1557
1604
|
// Toast (structural)
|
|
1558
1605
|
rules['.bw-toast-container'] = {
|
|
1559
1606
|
'position': 'fixed', 'z-index': '1080', 'pointer-events': 'none',
|
|
@@ -1603,12 +1650,12 @@
|
|
|
1603
1650
|
rules['.bw-form-switch .bw-switch-input:disabled'] = { 'opacity': '0.5', 'cursor': 'not-allowed' };
|
|
1604
1651
|
|
|
1605
1652
|
// Skeleton (structural)
|
|
1606
|
-
rules['.bw-skeleton'] = { 'border-radius': '4px', 'animation': 'bw-skeleton-
|
|
1653
|
+
rules['.bw-skeleton'] = { 'border-radius': '4px', 'background-size': '400% 100%', 'animation': 'bw-skeleton-shimmer 1.4s ease infinite' };
|
|
1607
1654
|
rules['.bw-skeleton-text'] = { 'height': '1em', 'margin-bottom': '0.5rem' };
|
|
1608
1655
|
rules['.bw-skeleton-circle'] = { 'border-radius': '50%' };
|
|
1609
1656
|
rules['.bw-skeleton-rect'] = { 'border-radius': '8px' };
|
|
1610
1657
|
rules['.bw-skeleton-group'] = { 'display': 'flex', 'flex-direction': 'column' };
|
|
1611
|
-
rules['@keyframes bw-skeleton-
|
|
1658
|
+
rules['@keyframes bw-skeleton-shimmer'] = { '0%': { 'background-position': '100% 50%' }, '100%': { 'background-position': '0 50%' } };
|
|
1612
1659
|
|
|
1613
1660
|
// Avatar (structural)
|
|
1614
1661
|
rules['.bw-avatar'] = {
|
|
@@ -1970,12 +2017,31 @@
|
|
|
1970
2017
|
'.bw-dark .bw-accordion-button': {
|
|
1971
2018
|
'color': textColor
|
|
1972
2019
|
},
|
|
2020
|
+
'.bw-dark .bw-accordion-button:not(.bw-collapsed)': {
|
|
2021
|
+
'color': '#7dd3e0',
|
|
2022
|
+
'background-color': 'rgba(125, 211, 224, 0.1)'
|
|
2023
|
+
},
|
|
1973
2024
|
'.bw-dark .bw-accordion-button:hover': {
|
|
1974
2025
|
'background-color': bodyBg
|
|
1975
2026
|
},
|
|
2027
|
+
'.bw-dark .bw-accordion-button:not(.bw-collapsed):hover': {
|
|
2028
|
+
'background-color': 'rgba(125, 211, 224, 0.15)'
|
|
2029
|
+
},
|
|
2030
|
+
'.bw-dark .bw-accordion-button:focus-visible': {
|
|
2031
|
+
'box-shadow': '0 0 0 0.2rem rgba(125, 211, 224, 0.3)'
|
|
2032
|
+
},
|
|
1976
2033
|
'.bw-dark .bw-accordion-body': {
|
|
1977
2034
|
'border-top-color': borderColor
|
|
1978
2035
|
},
|
|
2036
|
+
'.bw-dark .bw-carousel': {
|
|
2037
|
+
'background-color': bodyBg
|
|
2038
|
+
},
|
|
2039
|
+
'.bw-dark .bw-carousel-control': {
|
|
2040
|
+
'background-color': 'rgba(255,255,255,0.15)'
|
|
2041
|
+
},
|
|
2042
|
+
'.bw-dark .bw-carousel-control:hover': {
|
|
2043
|
+
'background-color': 'rgba(255,255,255,0.25)'
|
|
2044
|
+
},
|
|
1979
2045
|
'.bw-dark .bw-modal-content': {
|
|
1980
2046
|
'background-color': surfaceBg,
|
|
1981
2047
|
'border-color': borderColor
|
|
@@ -2011,7 +2077,7 @@
|
|
|
2011
2077
|
'border-top-color': borderColor
|
|
2012
2078
|
},
|
|
2013
2079
|
'.bw-dark .bw-skeleton': {
|
|
2014
|
-
'background
|
|
2080
|
+
'background': 'linear-gradient(90deg, ' + borderColor + ' 25%, ' + surfaceBg + ' 37%, ' + borderColor + ' 63%)'
|
|
2015
2081
|
},
|
|
2016
2082
|
'.bw-dark h1, .bw-dark h2, .bw-dark h3, .bw-dark h4, .bw-dark h5, .bw-dark h6': {
|
|
2017
2083
|
'color': textColor
|
|
@@ -4761,6 +4827,182 @@
|
|
|
4761
4827
|
};
|
|
4762
4828
|
}
|
|
4763
4829
|
|
|
4830
|
+
/**
|
|
4831
|
+
* Create a carousel/slideshow component with slide transitions
|
|
4832
|
+
*
|
|
4833
|
+
* Supports image slides, TACO content slides, captions, prev/next controls,
|
|
4834
|
+
* dot indicators, and optional auto-play. Uses CSS translateX transitions.
|
|
4835
|
+
*
|
|
4836
|
+
* @param {Object} [props] - Carousel configuration
|
|
4837
|
+
* @param {Array<Object>} [props.items=[]] - Slide items
|
|
4838
|
+
* @param {string|Object} props.items[].content - Slide content (TACO, string, or img element)
|
|
4839
|
+
* @param {string} [props.items[].caption] - Caption text shown at bottom of slide
|
|
4840
|
+
* @param {boolean} [props.showControls=true] - Show prev/next arrow buttons
|
|
4841
|
+
* @param {boolean} [props.showIndicators=true] - Show dot navigation
|
|
4842
|
+
* @param {boolean} [props.autoPlay=false] - Auto-advance slides
|
|
4843
|
+
* @param {number} [props.interval=5000] - Auto-advance interval in ms
|
|
4844
|
+
* @param {string} [props.height='300px'] - Carousel height
|
|
4845
|
+
* @param {number} [props.startIndex=0] - Initial slide index
|
|
4846
|
+
* @param {string} [props.className] - Additional CSS classes
|
|
4847
|
+
* @returns {Object} TACO object representing a carousel
|
|
4848
|
+
* @category Component Builders
|
|
4849
|
+
* @example
|
|
4850
|
+
* const carousel = makeCarousel({
|
|
4851
|
+
* items: [
|
|
4852
|
+
* { content: { t: 'img', a: { src: 'photo.jpg' } }, caption: 'Photo 1' },
|
|
4853
|
+
* { content: { t: 'div', c: 'Text slide' } }
|
|
4854
|
+
* ],
|
|
4855
|
+
* autoPlay: true,
|
|
4856
|
+
* interval: 3000
|
|
4857
|
+
* });
|
|
4858
|
+
*/
|
|
4859
|
+
function makeCarousel(props = {}) {
|
|
4860
|
+
const {
|
|
4861
|
+
items = [],
|
|
4862
|
+
showControls = true,
|
|
4863
|
+
showIndicators = true,
|
|
4864
|
+
autoPlay = false,
|
|
4865
|
+
interval = 5000,
|
|
4866
|
+
height = '300px',
|
|
4867
|
+
startIndex = 0,
|
|
4868
|
+
className = ''
|
|
4869
|
+
} = props;
|
|
4870
|
+
|
|
4871
|
+
// Shared navigation logic
|
|
4872
|
+
function goToSlide(carouselEl, index) {
|
|
4873
|
+
var total = carouselEl.querySelectorAll('.bw-carousel-slide').length;
|
|
4874
|
+
if (index < 0) index = total - 1;
|
|
4875
|
+
if (index >= total) index = 0;
|
|
4876
|
+
carouselEl.setAttribute('data-carousel-index', index);
|
|
4877
|
+
var track = carouselEl.querySelector('.bw-carousel-track');
|
|
4878
|
+
track.style.transform = 'translateX(-' + (index * 100) + '%)';
|
|
4879
|
+
// Update indicators
|
|
4880
|
+
var indicators = carouselEl.querySelectorAll('.bw-carousel-indicator');
|
|
4881
|
+
for (var i = 0; i < indicators.length; i++) {
|
|
4882
|
+
if (i === index) {
|
|
4883
|
+
indicators[i].classList.add('active');
|
|
4884
|
+
} else {
|
|
4885
|
+
indicators[i].classList.remove('active');
|
|
4886
|
+
}
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
|
|
4890
|
+
// Arrow SVGs (inline data URIs, same pattern as accordion chevrons)
|
|
4891
|
+
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";
|
|
4892
|
+
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";
|
|
4893
|
+
|
|
4894
|
+
var slides = items.map(function(item) {
|
|
4895
|
+
var slideContent = [
|
|
4896
|
+
item.content,
|
|
4897
|
+
item.caption && {
|
|
4898
|
+
t: 'div',
|
|
4899
|
+
a: { class: 'bw-carousel-caption' },
|
|
4900
|
+
c: item.caption
|
|
4901
|
+
}
|
|
4902
|
+
].filter(Boolean);
|
|
4903
|
+
|
|
4904
|
+
return {
|
|
4905
|
+
t: 'div',
|
|
4906
|
+
a: { class: 'bw-carousel-slide' },
|
|
4907
|
+
c: slideContent.length === 1 ? slideContent[0] : slideContent
|
|
4908
|
+
};
|
|
4909
|
+
});
|
|
4910
|
+
|
|
4911
|
+
var children = [
|
|
4912
|
+
// Track
|
|
4913
|
+
{
|
|
4914
|
+
t: 'div',
|
|
4915
|
+
a: {
|
|
4916
|
+
class: 'bw-carousel-track',
|
|
4917
|
+
style: 'transform: translateX(-' + (startIndex * 100) + '%)'
|
|
4918
|
+
},
|
|
4919
|
+
c: slides
|
|
4920
|
+
}
|
|
4921
|
+
];
|
|
4922
|
+
|
|
4923
|
+
// Prev/Next controls
|
|
4924
|
+
if (showControls && items.length > 1) {
|
|
4925
|
+
children.push({
|
|
4926
|
+
t: 'button',
|
|
4927
|
+
a: {
|
|
4928
|
+
class: 'bw-carousel-control bw-carousel-control-prev',
|
|
4929
|
+
type: 'button',
|
|
4930
|
+
'aria-label': 'Previous slide',
|
|
4931
|
+
onclick: function(e) {
|
|
4932
|
+
var carousel = e.target.closest('.bw-carousel');
|
|
4933
|
+
var idx = parseInt(carousel.getAttribute('data-carousel-index') || '0');
|
|
4934
|
+
goToSlide(carousel, idx - 1);
|
|
4935
|
+
}
|
|
4936
|
+
},
|
|
4937
|
+
c: { t: 'img', a: { src: prevArrow, alt: '', role: 'presentation' } }
|
|
4938
|
+
});
|
|
4939
|
+
children.push({
|
|
4940
|
+
t: 'button',
|
|
4941
|
+
a: {
|
|
4942
|
+
class: 'bw-carousel-control bw-carousel-control-next',
|
|
4943
|
+
type: 'button',
|
|
4944
|
+
'aria-label': 'Next slide',
|
|
4945
|
+
onclick: function(e) {
|
|
4946
|
+
var carousel = e.target.closest('.bw-carousel');
|
|
4947
|
+
var idx = parseInt(carousel.getAttribute('data-carousel-index') || '0');
|
|
4948
|
+
goToSlide(carousel, idx + 1);
|
|
4949
|
+
}
|
|
4950
|
+
},
|
|
4951
|
+
c: { t: 'img', a: { src: nextArrow, alt: '', role: 'presentation' } }
|
|
4952
|
+
});
|
|
4953
|
+
}
|
|
4954
|
+
|
|
4955
|
+
// Indicators
|
|
4956
|
+
if (showIndicators && items.length > 1) {
|
|
4957
|
+
children.push({
|
|
4958
|
+
t: 'div',
|
|
4959
|
+
a: { class: 'bw-carousel-indicators' },
|
|
4960
|
+
c: items.map(function(_, i) {
|
|
4961
|
+
return {
|
|
4962
|
+
t: 'button',
|
|
4963
|
+
a: {
|
|
4964
|
+
class: 'bw-carousel-indicator' + (i === startIndex ? ' active' : ''),
|
|
4965
|
+
type: 'button',
|
|
4966
|
+
'aria-label': 'Go to slide ' + (i + 1),
|
|
4967
|
+
'data-slide-index': i,
|
|
4968
|
+
onclick: function(e) {
|
|
4969
|
+
var carousel = e.target.closest('.bw-carousel');
|
|
4970
|
+
var idx = parseInt(e.target.getAttribute('data-slide-index'));
|
|
4971
|
+
goToSlide(carousel, idx);
|
|
4972
|
+
}
|
|
4973
|
+
}
|
|
4974
|
+
};
|
|
4975
|
+
})
|
|
4976
|
+
});
|
|
4977
|
+
}
|
|
4978
|
+
|
|
4979
|
+
return {
|
|
4980
|
+
t: 'div',
|
|
4981
|
+
a: {
|
|
4982
|
+
class: ('bw-carousel ' + className).trim(),
|
|
4983
|
+
style: 'height: ' + height,
|
|
4984
|
+
'data-carousel-index': startIndex
|
|
4985
|
+
},
|
|
4986
|
+
c: children,
|
|
4987
|
+
o: {
|
|
4988
|
+
type: 'carousel',
|
|
4989
|
+
state: { activeIndex: startIndex, autoPlay: autoPlay, interval: interval },
|
|
4990
|
+
mounted: autoPlay ? function(el) {
|
|
4991
|
+
var intervalId = setInterval(function() {
|
|
4992
|
+
var idx = parseInt(el.getAttribute('data-carousel-index') || '0');
|
|
4993
|
+
goToSlide(el, idx + 1);
|
|
4994
|
+
}, interval);
|
|
4995
|
+
el._bw_carouselInterval = intervalId;
|
|
4996
|
+
} : undefined,
|
|
4997
|
+
unmount: autoPlay ? function(el) {
|
|
4998
|
+
if (el._bw_carouselInterval) {
|
|
4999
|
+
clearInterval(el._bw_carouselInterval);
|
|
5000
|
+
}
|
|
5001
|
+
} : undefined
|
|
5002
|
+
}
|
|
5003
|
+
};
|
|
5004
|
+
}
|
|
5005
|
+
|
|
4764
5006
|
const componentHandles = {
|
|
4765
5007
|
card: CardHandle,
|
|
4766
5008
|
table: TableHandle,
|
|
@@ -4786,6 +5028,7 @@
|
|
|
4786
5028
|
makeButtonGroup: makeButtonGroup,
|
|
4787
5029
|
makeCTA: makeCTA,
|
|
4788
5030
|
makeCard: makeCard,
|
|
5031
|
+
makeCarousel: makeCarousel,
|
|
4789
5032
|
makeCheckbox: makeCheckbox,
|
|
4790
5033
|
makeCodeDemo: makeCodeDemo,
|
|
4791
5034
|
makeCol: makeCol,
|
|
@@ -5235,6 +5478,26 @@
|
|
|
5235
5478
|
return str.replace(/[&<>"'/]/g, (char) => escapeMap[char]);
|
|
5236
5479
|
};
|
|
5237
5480
|
|
|
5481
|
+
/**
|
|
5482
|
+
* Mark a string as raw HTML so it will not be escaped by bw.html() or bw.createDOM().
|
|
5483
|
+
*
|
|
5484
|
+
* By default, bitwrench escapes all text content to prevent XSS. Use bw.raw()
|
|
5485
|
+
* when you need to embed pre-sanitized HTML, entities, or inline markup.
|
|
5486
|
+
*
|
|
5487
|
+
* @param {string} str - HTML string to mark as raw
|
|
5488
|
+
* @returns {Object} Marked object recognized by bw.html() and bw.createDOM()
|
|
5489
|
+
* @category DOM Generation
|
|
5490
|
+
* @see bw.escapeHTML
|
|
5491
|
+
* @see bw.html
|
|
5492
|
+
* @example
|
|
5493
|
+
* bw.raw('Hello — World')
|
|
5494
|
+
* // Used in TACO content:
|
|
5495
|
+
* { t: 'p', c: bw.raw('Price: <strong>$9.99</strong>') }
|
|
5496
|
+
*/
|
|
5497
|
+
bw.raw = function(str) {
|
|
5498
|
+
return { __bw_raw: true, v: String(str) };
|
|
5499
|
+
};
|
|
5500
|
+
|
|
5238
5501
|
/**
|
|
5239
5502
|
* Normalize CSS class names by converting underscores to hyphens for bw-prefixed classes.
|
|
5240
5503
|
*
|
|
@@ -5286,6 +5549,11 @@
|
|
|
5286
5549
|
return taco.map(t => bw.html(t, options)).join('');
|
|
5287
5550
|
}
|
|
5288
5551
|
|
|
5552
|
+
// Handle bw.raw() marked content
|
|
5553
|
+
if (taco && taco.__bw_raw) {
|
|
5554
|
+
return taco.v;
|
|
5555
|
+
}
|
|
5556
|
+
|
|
5289
5557
|
// Handle primitives and non-TACO objects
|
|
5290
5558
|
if (typeof taco !== 'object' || !taco.t) {
|
|
5291
5559
|
return options.raw ? String(taco) : bw.escapeHTML(String(taco));
|
|
@@ -5386,12 +5654,21 @@
|
|
|
5386
5654
|
|
|
5387
5655
|
// Handle null/undefined
|
|
5388
5656
|
if (taco == null) return document.createTextNode('');
|
|
5389
|
-
|
|
5657
|
+
|
|
5658
|
+
// Handle bw.raw() marked content — inject as HTML
|
|
5659
|
+
if (taco && taco.__bw_raw) {
|
|
5660
|
+
var frag = document.createDocumentFragment();
|
|
5661
|
+
var tmp = document.createElement('span');
|
|
5662
|
+
tmp.innerHTML = taco.v;
|
|
5663
|
+
while (tmp.firstChild) frag.appendChild(tmp.firstChild);
|
|
5664
|
+
return frag;
|
|
5665
|
+
}
|
|
5666
|
+
|
|
5390
5667
|
// Handle text nodes
|
|
5391
5668
|
if (typeof taco !== 'object' || !taco.t) {
|
|
5392
5669
|
return document.createTextNode(String(taco));
|
|
5393
5670
|
}
|
|
5394
|
-
|
|
5671
|
+
|
|
5395
5672
|
const { t: tag, a: attrs = {}, c: content, o: opts = {} } = taco;
|
|
5396
5673
|
|
|
5397
5674
|
// Create element
|
|
@@ -5456,6 +5733,9 @@
|
|
|
5456
5733
|
}
|
|
5457
5734
|
}
|
|
5458
5735
|
});
|
|
5736
|
+
} else if (typeof content === 'object' && content.__bw_raw) {
|
|
5737
|
+
// Raw HTML content — inject via innerHTML
|
|
5738
|
+
el.innerHTML = content.v;
|
|
5459
5739
|
} else if (typeof content === 'object' && content.t) {
|
|
5460
5740
|
var childEl = bw.createDOM(content, options);
|
|
5461
5741
|
el.appendChild(childEl);
|