bitwrench 2.0.19 → 2.0.21
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/README.md +0 -2
- package/dist/bitwrench-bccl.cjs.js +1 -1
- package/dist/bitwrench-bccl.cjs.min.js +1 -1
- package/dist/bitwrench-bccl.esm.js +1 -1
- package/dist/bitwrench-bccl.esm.min.js +1 -1
- package/dist/bitwrench-bccl.umd.js +1 -1
- package/dist/bitwrench-bccl.umd.min.js +1 -1
- package/dist/bitwrench-code-edit.cjs.js +1 -1
- package/dist/bitwrench-code-edit.cjs.min.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-debug.js +1 -1
- package/dist/bitwrench-debug.min.js +1 -1
- package/dist/bitwrench-lean.cjs.js +344 -30
- package/dist/bitwrench-lean.cjs.min.js +14 -6
- package/dist/bitwrench-lean.es5.js +379 -29
- package/dist/bitwrench-lean.es5.min.js +12 -4
- package/dist/bitwrench-lean.esm.js +344 -30
- package/dist/bitwrench-lean.esm.min.js +14 -6
- package/dist/bitwrench-lean.umd.js +344 -30
- package/dist/bitwrench-lean.umd.min.js +14 -6
- package/dist/bitwrench-util-css.cjs.js +1 -1
- package/dist/bitwrench-util-css.cjs.min.js +1 -1
- package/dist/bitwrench-util-css.es5.js +1 -1
- package/dist/bitwrench-util-css.es5.min.js +1 -1
- package/dist/bitwrench-util-css.esm.js +1 -1
- package/dist/bitwrench-util-css.esm.min.js +1 -1
- package/dist/bitwrench-util-css.umd.js +1 -1
- package/dist/bitwrench-util-css.umd.min.js +1 -1
- package/dist/bitwrench.cjs.js +344 -30
- package/dist/bitwrench.cjs.min.js +14 -6
- package/dist/bitwrench.css +65 -14
- package/dist/bitwrench.es5.js +379 -29
- package/dist/bitwrench.es5.min.js +13 -5
- package/dist/bitwrench.esm.js +344 -30
- package/dist/bitwrench.esm.min.js +15 -7
- package/dist/bitwrench.min.css +1 -1
- package/dist/bitwrench.umd.js +344 -30
- package/dist/bitwrench.umd.min.js +14 -6
- package/dist/builds.json +94 -94
- package/dist/bwserve.cjs.js +2 -2
- package/dist/bwserve.esm.js +2 -2
- package/dist/sri.json +46 -46
- package/package.json +5 -6
- package/readme.html +2 -2
- package/src/bitwrench-router.js +282 -0
- package/src/bitwrench-styles.js +59 -27
- package/src/bitwrench.js +6 -0
- package/src/version.js +3 -3
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
/*! bitwrench-lean v2.0.
|
|
1
|
+
/*! bitwrench-lean v2.0.21 | 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.
|
|
8
|
+
version: '2.0.21',
|
|
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-
|
|
15
|
+
buildDate: '2026-03-24T05:30:22.242Z'
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -578,10 +578,10 @@ var ELEVATION_PRESETS = {
|
|
|
578
578
|
xl: '0 4px 12px rgba(0,0,0,0.12)'
|
|
579
579
|
},
|
|
580
580
|
md: {
|
|
581
|
-
sm: '0 1px 3px rgba(0,0,0,0.
|
|
582
|
-
md: '0
|
|
583
|
-
lg: '0 4px
|
|
584
|
-
xl: '0 8px
|
|
581
|
+
sm: '0 1px 3px rgba(0,0,0,0.10), 0 1px 2px rgba(0,0,0,0.06)',
|
|
582
|
+
md: '0 4px 6px rgba(0,0,0,0.10), 0 2px 4px rgba(0,0,0,0.06)',
|
|
583
|
+
lg: '0 10px 15px rgba(0,0,0,0.12), 0 4px 6px rgba(0,0,0,0.08)',
|
|
584
|
+
xl: '0 20px 25px rgba(0,0,0,0.15), 0 8px 10px rgba(0,0,0,0.10)'
|
|
585
585
|
},
|
|
586
586
|
lg: {
|
|
587
587
|
sm: '0 2px 4px rgba(0,0,0,0.10)',
|
|
@@ -775,6 +775,9 @@ function generateCards(scope, palette, layout) {
|
|
|
775
775
|
rules[_sx(scope, '.bw_card:hover')] = {
|
|
776
776
|
'box-shadow': elev.md
|
|
777
777
|
};
|
|
778
|
+
rules[_sx(scope, '.bw_card_hoverable')] = {
|
|
779
|
+
'transition': 'box-shadow ' + motion.slow + ' ' + motion.easing + ', transform ' + motion.slow + ' ' + motion.easing
|
|
780
|
+
};
|
|
778
781
|
rules[_sx(scope, '.bw_card_hoverable:hover')] = {
|
|
779
782
|
'box-shadow': elev.lg
|
|
780
783
|
};
|
|
@@ -875,7 +878,8 @@ function generateNavigation(scope, palette, layout) {
|
|
|
875
878
|
};
|
|
876
879
|
rules[_sx(scope, '.bw_navbar_nav .bw_nav_link')] = {
|
|
877
880
|
'color': palette.secondary.base,
|
|
878
|
-
'border-radius': layout.radius.btn
|
|
881
|
+
'border-radius': layout.radius.btn,
|
|
882
|
+
'transition': 'color ' + layout.motion.fast + ' ' + layout.motion.easing + ', background-color ' + layout.motion.fast + ' ' + layout.motion.easing
|
|
879
883
|
};
|
|
880
884
|
rules[_sx(scope, '.bw_navbar_nav .bw_nav_link:hover')] = {
|
|
881
885
|
'color': palette.dark.base,
|
|
@@ -1038,15 +1042,18 @@ function generatePagination(scope, palette, layout) {
|
|
|
1038
1042
|
return rules;
|
|
1039
1043
|
}
|
|
1040
1044
|
|
|
1041
|
-
function generateProgress(scope, palette) {
|
|
1045
|
+
function generateProgress(scope, palette, layout) {
|
|
1042
1046
|
var rules = {};
|
|
1047
|
+
var rd = layout ? layout.radius : { badge: '.375rem' };
|
|
1043
1048
|
rules[_sx(scope, '.bw_progress')] = {
|
|
1044
1049
|
'background-color': palette.surfaceAlt,
|
|
1050
|
+
'border-radius': rd.badge,
|
|
1045
1051
|
'box-shadow': 'inset 0 1px 2px rgba(0,0,0,.1)'
|
|
1046
1052
|
};
|
|
1047
1053
|
rules[_sx(scope, '.bw_progress_bar')] = {
|
|
1048
1054
|
'color': palette.primary.textOn,
|
|
1049
1055
|
'background-color': palette.primary.base,
|
|
1056
|
+
'border-radius': 'inherit',
|
|
1050
1057
|
'box-shadow': 'inset 0 -1px 0 rgba(0,0,0,.15)'
|
|
1051
1058
|
};
|
|
1052
1059
|
// Variant progress bar colors handled by palette class
|
|
@@ -1170,7 +1177,8 @@ function generateCarouselThemed(scope, palette) {
|
|
|
1170
1177
|
};
|
|
1171
1178
|
rules[_sx(scope, '.bw_carousel_control')] = {
|
|
1172
1179
|
'background-color': palette.dark.base,
|
|
1173
|
-
'color': palette.dark.textOn
|
|
1180
|
+
'color': palette.dark.textOn,
|
|
1181
|
+
'transition': 'background-color 0.15s ease-out'
|
|
1174
1182
|
};
|
|
1175
1183
|
rules[_sx(scope, '.bw_carousel_control:hover')] = {
|
|
1176
1184
|
'background-color': palette.dark.hover
|
|
@@ -1184,9 +1192,11 @@ function generateCarouselThemed(scope, palette) {
|
|
|
1184
1192
|
|
|
1185
1193
|
function generateModalThemed(scope, palette, layout) {
|
|
1186
1194
|
var rules = {};
|
|
1195
|
+
var rd = layout ? layout.radius : { card: '8px' };
|
|
1187
1196
|
rules[_sx(scope, '.bw_modal_content')] = {
|
|
1188
1197
|
'background-color': palette.surface || '#fff',
|
|
1189
1198
|
'border-color': palette.light.border,
|
|
1199
|
+
'border-radius': rd.card,
|
|
1190
1200
|
'box-shadow': layout.elevation.lg
|
|
1191
1201
|
};
|
|
1192
1202
|
rules[_sx(scope, '.bw_modal_header')] = {
|
|
@@ -1203,9 +1213,11 @@ function generateModalThemed(scope, palette, layout) {
|
|
|
1203
1213
|
|
|
1204
1214
|
function generateToastThemed(scope, palette, layout) {
|
|
1205
1215
|
var rules = {};
|
|
1216
|
+
var rd = layout ? layout.radius : { card: '8px' };
|
|
1206
1217
|
rules[_sx(scope, '.bw_toast')] = {
|
|
1207
1218
|
'background-color': palette.surface || '#fff',
|
|
1208
1219
|
'border-color': palette.light.border,
|
|
1220
|
+
'border-radius': rd.card,
|
|
1209
1221
|
'box-shadow': layout.elevation.lg
|
|
1210
1222
|
};
|
|
1211
1223
|
rules[_sx(scope, '.bw_toast_header')] = {
|
|
@@ -1217,9 +1229,11 @@ function generateToastThemed(scope, palette, layout) {
|
|
|
1217
1229
|
|
|
1218
1230
|
function generateDropdownThemed(scope, palette, layout) {
|
|
1219
1231
|
var rules = {};
|
|
1232
|
+
var rd = layout ? layout.radius : { card: '8px' };
|
|
1220
1233
|
rules[_sx(scope, '.bw_dropdown_menu')] = {
|
|
1221
1234
|
'background-color': palette.surface || '#fff',
|
|
1222
1235
|
'border-color': palette.light.border,
|
|
1236
|
+
'border-radius': rd.card,
|
|
1223
1237
|
'box-shadow': layout.elevation.md
|
|
1224
1238
|
};
|
|
1225
1239
|
rules[_sx(scope, '.bw_dropdown_item')] = {
|
|
@@ -1252,6 +1266,10 @@ function generateSwitchThemed(scope, palette) {
|
|
|
1252
1266
|
rules[_sx(scope, '.bw_form_switch .bw_switch_input:focus')] = {
|
|
1253
1267
|
'box-shadow': '0 0 0 0.25rem ' + palette.primary.focus
|
|
1254
1268
|
};
|
|
1269
|
+
rules[_sx(scope, '.bw_form_switch .bw_switch_input:focus-visible')] = {
|
|
1270
|
+
'box-shadow': '0 0 0 0.25rem ' + palette.primary.focus,
|
|
1271
|
+
'outline': 'none'
|
|
1272
|
+
};
|
|
1255
1273
|
return rules;
|
|
1256
1274
|
}
|
|
1257
1275
|
|
|
@@ -1315,12 +1333,14 @@ function generateStepperThemed(scope, palette) {
|
|
|
1315
1333
|
return rules;
|
|
1316
1334
|
}
|
|
1317
1335
|
|
|
1318
|
-
function generateChipInputThemed(scope, palette) {
|
|
1336
|
+
function generateChipInputThemed(scope, palette, layout) {
|
|
1319
1337
|
var rules = {};
|
|
1338
|
+
var rd = layout ? layout.radius : { input: '6px' };
|
|
1320
1339
|
rules[_sx(scope, '.bw_chip_input')] = {
|
|
1321
1340
|
'border-color': palette.light.border,
|
|
1322
1341
|
'background-color': palette.surface || '#fff',
|
|
1323
|
-
'color': palette.dark.base
|
|
1342
|
+
'color': palette.dark.base,
|
|
1343
|
+
'border-radius': rd.input
|
|
1324
1344
|
};
|
|
1325
1345
|
rules[_sx(scope, '.bw_chip_input:focus-within')] = {
|
|
1326
1346
|
'border-color': palette.primary.base,
|
|
@@ -1605,7 +1625,7 @@ function generateThemedCSS(scopeName, palette, layout) {
|
|
|
1605
1625
|
generateTabs(scopeName, palette, layout),
|
|
1606
1626
|
generateListGroups(scopeName, palette, layout),
|
|
1607
1627
|
generatePagination(scopeName, palette, layout),
|
|
1608
|
-
generateProgress(scopeName, palette),
|
|
1628
|
+
generateProgress(scopeName, palette, layout),
|
|
1609
1629
|
generateBreadcrumbThemed(scopeName, palette, layout),
|
|
1610
1630
|
generateCloseButtonThemed(scopeName, palette),
|
|
1611
1631
|
generateSectionsThemed(scopeName, palette),
|
|
@@ -1619,7 +1639,7 @@ function generateThemedCSS(scopeName, palette, layout) {
|
|
|
1619
1639
|
generateStatCardThemed(scopeName, palette, layout),
|
|
1620
1640
|
generateTimelineThemed(scopeName, palette),
|
|
1621
1641
|
generateStepperThemed(scopeName, palette),
|
|
1622
|
-
generateChipInputThemed(scopeName, palette),
|
|
1642
|
+
generateChipInputThemed(scopeName, palette, layout),
|
|
1623
1643
|
generateFileUploadThemed(scopeName, palette, layout),
|
|
1624
1644
|
generateRangeThemed(scopeName, palette),
|
|
1625
1645
|
generateSearchThemed(scopeName, palette, layout),
|
|
@@ -1767,7 +1787,7 @@ var structuralRules = {
|
|
|
1767
1787
|
'.bw_card_text': { 'margin-bottom': '0', 'font-size': '0.9375rem', 'line-height': '1.6' },
|
|
1768
1788
|
'.bw_card_header': { 'margin-bottom': '0', 'font-weight': '600', 'font-size': '0.875rem' },
|
|
1769
1789
|
'.bw_card_footer': { 'font-size': '0.875rem' },
|
|
1770
|
-
'.bw_card_hoverable': {
|
|
1790
|
+
'.bw_card_hoverable': {},
|
|
1771
1791
|
'.bw_card_hoverable:hover': { 'transform': 'translateY(-4px)' },
|
|
1772
1792
|
'.bw_card_img_top': { 'width': '100%' },
|
|
1773
1793
|
'.bw_card_img_bottom': { 'width': '100%' },
|
|
@@ -1782,7 +1802,8 @@ var structuralRules = {
|
|
|
1782
1802
|
'display': 'block', 'width': '100%',
|
|
1783
1803
|
'font-size': '0.9375rem', 'font-weight': '400', 'line-height': '1.5',
|
|
1784
1804
|
'background-clip': 'padding-box', 'appearance': 'none',
|
|
1785
|
-
'border': '1px solid transparent', 'font-family': 'inherit'
|
|
1805
|
+
'border': '1px solid transparent', 'font-family': 'inherit',
|
|
1806
|
+
'transition': 'border-color 0.15s ease-out, box-shadow 0.15s ease-out'
|
|
1786
1807
|
},
|
|
1787
1808
|
'.bw_form_control:focus': { 'outline': '2px solid currentColor', 'outline-offset': '-1px' },
|
|
1788
1809
|
'.bw_form_control::placeholder': { 'opacity': '1' },
|
|
@@ -1909,6 +1930,7 @@ var structuralRules = {
|
|
|
1909
1930
|
'text-decoration': 'none', 'cursor': 'pointer',
|
|
1910
1931
|
'border': 'none', 'background': 'transparent', 'font-family': 'inherit'
|
|
1911
1932
|
},
|
|
1933
|
+
'.bw_nav_link:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '-2px' },
|
|
1912
1934
|
'.bw_nav_tabs .bw_nav_link': { 'border': 'none', 'border-bottom': '2px solid transparent', 'border-radius': '0', 'background-color': 'transparent' },
|
|
1913
1935
|
'.bw_nav_vertical': { 'flex-direction': 'column' },
|
|
1914
1936
|
'.bw_tab_content': { 'padding': '1.25rem 0' },
|
|
@@ -2026,9 +2048,11 @@ var structuralRules = {
|
|
|
2026
2048
|
'display': 'inline-flex', 'align-items': 'center', 'justify-content': 'center',
|
|
2027
2049
|
'width': '1.5rem', 'height': '1.5rem', 'padding': '0',
|
|
2028
2050
|
'font-size': '1.25rem', 'font-weight': '700', 'line-height': '1',
|
|
2029
|
-
'background': 'transparent', 'border': '0', 'border-radius': '0.25rem', 'cursor': 'pointer'
|
|
2051
|
+
'background': 'transparent', 'border': '0', 'border-radius': '0.25rem', 'cursor': 'pointer',
|
|
2052
|
+
'transition': 'opacity 0.15s ease-out'
|
|
2030
2053
|
},
|
|
2031
|
-
'.bw_close:hover': { 'opacity': '0.75' }
|
|
2054
|
+
'.bw_close:hover': { 'opacity': '0.75' },
|
|
2055
|
+
'.bw_close:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '2px' }
|
|
2032
2056
|
},
|
|
2033
2057
|
|
|
2034
2058
|
// ---- Stacks ----
|
|
@@ -2110,7 +2134,8 @@ var structuralRules = {
|
|
|
2110
2134
|
'flex-shrink': '0', 'width': '1.25rem', 'height': '1.25rem', 'margin-left': 'auto',
|
|
2111
2135
|
'content': '""',
|
|
2112
2136
|
'background-image': "url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\")",
|
|
2113
|
-
'background-repeat': 'no-repeat', 'background-size': '1.25rem'
|
|
2137
|
+
'background-repeat': 'no-repeat', 'background-size': '1.25rem',
|
|
2138
|
+
'transition': 'transform 0.2s ease-out'
|
|
2114
2139
|
},
|
|
2115
2140
|
'.bw_accordion_button:not(.bw_collapsed)::after': { 'transform': 'rotate(-180deg)' },
|
|
2116
2141
|
'.bw_accordion_body': { 'padding': '1rem 1.25rem' },
|
|
@@ -2135,6 +2160,7 @@ var structuralRules = {
|
|
|
2135
2160
|
'z-index': '2', 'padding': '0'
|
|
2136
2161
|
},
|
|
2137
2162
|
'.bw_carousel_control img': { 'width': '20px', 'height': '20px', 'pointer-events': 'none' },
|
|
2163
|
+
'.bw_carousel_control:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '2px' },
|
|
2138
2164
|
'.bw_carousel_control_prev': { 'left': '10px' },
|
|
2139
2165
|
'.bw_carousel_control_next': { 'right': '10px' },
|
|
2140
2166
|
'.bw_carousel_indicators': {
|
|
@@ -2154,12 +2180,14 @@ var structuralRules = {
|
|
|
2154
2180
|
'display': 'flex', 'align-items': 'center', 'justify-content': 'center',
|
|
2155
2181
|
'position': 'fixed', 'top': '0', 'left': '0', 'width': '100%', 'height': '100%',
|
|
2156
2182
|
'z-index': '1050', 'overflow-x': 'hidden', 'overflow-y': 'auto',
|
|
2157
|
-
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none'
|
|
2183
|
+
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none',
|
|
2184
|
+
'transition': 'opacity 0.2s ease-out, visibility 0.2s ease-out'
|
|
2158
2185
|
},
|
|
2159
2186
|
'.bw_modal.bw_modal_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto' },
|
|
2160
2187
|
'.bw_modal_dialog': {
|
|
2161
2188
|
'position': 'relative', 'width': 'calc(100% - 1rem)', 'max-width': '500px', 'margin': '1.75rem auto',
|
|
2162
|
-
'pointer-events': 'none'
|
|
2189
|
+
'pointer-events': 'none', 'transform': 'translateY(-16px)',
|
|
2190
|
+
'transition': 'transform 0.2s ease-out'
|
|
2163
2191
|
},
|
|
2164
2192
|
'.bw_modal.bw_modal_show .bw_modal_dialog': { 'transform': 'translateY(0)' },
|
|
2165
2193
|
'.bw_modal_sm': { 'max-width': '300px' },
|
|
@@ -2189,10 +2217,11 @@ var structuralRules = {
|
|
|
2189
2217
|
'.bw_toast_container.bw_toast_bottom_center': { 'bottom': '0', 'left': '50%', 'transform': 'translateX(-50%)' },
|
|
2190
2218
|
'.bw_toast': {
|
|
2191
2219
|
'pointer-events': 'auto', 'width': '350px', 'max-width': 'calc(100vw - 2rem)', 'background-clip': 'padding-box',
|
|
2192
|
-
'opacity': '0'
|
|
2220
|
+
'opacity': '0', 'transform': 'translateY(-8px)',
|
|
2221
|
+
'transition': 'opacity 0.2s ease-out, transform 0.2s ease-out'
|
|
2193
2222
|
},
|
|
2194
2223
|
'.bw_toast.bw_toast_show': { 'opacity': '1', 'transform': 'translateY(0)' },
|
|
2195
|
-
'.bw_toast.bw_toast_hiding': { 'opacity': '0' },
|
|
2224
|
+
'.bw_toast.bw_toast_hiding': { 'opacity': '0', 'transform': 'translateY(-8px)' },
|
|
2196
2225
|
'.bw_toast_header': { 'display': 'flex', 'align-items': 'center', 'justify-content': 'space-between', 'padding': '0.5rem 0.75rem', 'font-size': '0.875rem', 'border-bottom': '1px solid transparent' },
|
|
2197
2226
|
'.bw_toast_body': { 'padding': '0.5rem 0.75rem', 'font-size': '0.9375rem' }
|
|
2198
2227
|
},
|
|
@@ -2209,9 +2238,11 @@ var structuralRules = {
|
|
|
2209
2238
|
'position': 'absolute', 'top': '100%', 'left': '0', 'z-index': '1000', 'display': 'block',
|
|
2210
2239
|
'min-width': '10rem', 'padding': '0.5rem 0', 'margin': '0.125rem 0 0',
|
|
2211
2240
|
'background-clip': 'padding-box', 'border': '1px solid transparent',
|
|
2212
|
-
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none'
|
|
2241
|
+
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none',
|
|
2242
|
+
'transform': 'translateY(-4px)',
|
|
2243
|
+
'transition': 'opacity 0.15s ease-out, transform 0.15s ease-out, visibility 0.15s ease-out'
|
|
2213
2244
|
},
|
|
2214
|
-
'.bw_dropdown_menu.bw_dropdown_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto' },
|
|
2245
|
+
'.bw_dropdown_menu.bw_dropdown_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto', 'transform': 'translateY(0)' },
|
|
2215
2246
|
'.bw_dropdown_menu_end': { 'left': 'auto', 'right': '0' },
|
|
2216
2247
|
'.bw_dropdown_item': {
|
|
2217
2248
|
'display': 'block', 'width': '100%', 'padding': '0.4rem 1rem', 'clear': 'both',
|
|
@@ -2230,7 +2261,8 @@ var structuralRules = {
|
|
|
2230
2261
|
'appearance': 'none',
|
|
2231
2262
|
'background-image': "url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba(255,255,255,1)'/%3e%3c/svg%3e\")",
|
|
2232
2263
|
'background-position': 'left center', 'background-repeat': 'no-repeat',
|
|
2233
|
-
'background-size': 'contain', 'cursor': 'pointer'
|
|
2264
|
+
'background-size': 'contain', 'cursor': 'pointer',
|
|
2265
|
+
'transition': 'background-color 0.15s ease-out, background-position 0.15s ease-out, border-color 0.15s ease-out'
|
|
2234
2266
|
},
|
|
2235
2267
|
'.bw_form_switch .bw_switch_input:checked': { 'background-position': 'right center' },
|
|
2236
2268
|
'.bw_form_switch .bw_switch_input:disabled': { 'opacity': '0.5', 'cursor': 'not-allowed' }
|
|
@@ -2264,9 +2296,7 @@ var structuralRules = {
|
|
|
2264
2296
|
'.bw_stat_card': {
|
|
2265
2297
|
'padding': '1.25rem',
|
|
2266
2298
|
'border-left': '4px solid transparent',
|
|
2267
|
-
'
|
|
2268
|
-
'background-color': 'inherit',
|
|
2269
|
-
'transition': 'transform 0.15s ease'
|
|
2299
|
+
'background-color': 'inherit'
|
|
2270
2300
|
},
|
|
2271
2301
|
'.bw_stat_card:hover': { 'transform': 'translateY(-1px)' },
|
|
2272
2302
|
'.bw_stat_icon': { 'font-size': '1.5rem', 'margin-bottom': '0.5rem' },
|
|
@@ -2326,7 +2356,8 @@ var structuralRules = {
|
|
|
2326
2356
|
'width': '1.5rem', 'height': '1.5rem',
|
|
2327
2357
|
'border': 'none', 'background': 'none',
|
|
2328
2358
|
'font-size': '1.25rem', 'cursor': 'pointer', 'padding': '0', 'border-radius': '50%'
|
|
2329
|
-
}
|
|
2359
|
+
},
|
|
2360
|
+
'.bw_search_clear:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '2px' }
|
|
2330
2361
|
},
|
|
2331
2362
|
|
|
2332
2363
|
// ---- Range ----
|
|
@@ -2418,6 +2449,7 @@ var structuralRules = {
|
|
|
2418
2449
|
'width': '1rem', 'height': '1rem', 'border': 'none', 'background': 'none',
|
|
2419
2450
|
'font-size': '0.875rem', 'cursor': 'pointer', 'padding': '0', 'border-radius': '50%'
|
|
2420
2451
|
},
|
|
2452
|
+
'.bw_chip_remove:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '1px' },
|
|
2421
2453
|
'.bw_chip_field': { 'flex': '1', 'min-width': '80px', 'border': 'none', 'outline': 'none', 'font-size': '0.875rem', 'padding': '0.125rem 0', 'background': 'transparent' }
|
|
2422
2454
|
},
|
|
2423
2455
|
|
|
@@ -3457,6 +3489,287 @@ function repeatUntil(testFn, successFn, failFn, delay = 250, maxReps = 10, lastF
|
|
|
3457
3489
|
return intervalID;
|
|
3458
3490
|
}
|
|
3459
3491
|
|
|
3492
|
+
/**
|
|
3493
|
+
* Bitwrench Router -- client-side URL routing for SPAs
|
|
3494
|
+
*
|
|
3495
|
+
* Single export: initRouter(bw) attaches bw.router(), bw.navigate(), bw.link()
|
|
3496
|
+
*
|
|
3497
|
+
* @license BSD-2-Clause
|
|
3498
|
+
*/
|
|
3499
|
+
|
|
3500
|
+
// -- internal helpers --
|
|
3501
|
+
|
|
3502
|
+
function normalizePath(p) {
|
|
3503
|
+
// strip query string (handled separately)
|
|
3504
|
+
var qi = p.indexOf('?');
|
|
3505
|
+
if (qi >= 0) p = p.substring(0, qi);
|
|
3506
|
+
// collapse double slashes, strip trailing slash
|
|
3507
|
+
p = p.replace(/\/\/+/g, '/');
|
|
3508
|
+
if (p.length > 1 && p.charAt(p.length - 1) === '/') p = p.substring(0, p.length - 1);
|
|
3509
|
+
return p || '/';
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3512
|
+
function parseQuery(fullPath) {
|
|
3513
|
+
var qi = fullPath.indexOf('?');
|
|
3514
|
+
if (qi < 0) return {};
|
|
3515
|
+
var qs = fullPath.substring(qi + 1);
|
|
3516
|
+
var result = {};
|
|
3517
|
+
var pairs = qs.split('&');
|
|
3518
|
+
for (var i = 0; i < pairs.length; i++) {
|
|
3519
|
+
var kv = pairs[i].split('=');
|
|
3520
|
+
if (kv[0]) result[decodeURIComponent(kv[0])] = kv.length > 1 ? decodeURIComponent(kv[1]) : '';
|
|
3521
|
+
}
|
|
3522
|
+
return result;
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
function matchRoute(routes, rawPath) {
|
|
3526
|
+
var query = parseQuery(rawPath);
|
|
3527
|
+
var path = normalizePath(rawPath);
|
|
3528
|
+
var segs = path === '/' ? [''] : path.split('/');
|
|
3529
|
+
|
|
3530
|
+
var globalWild = null;
|
|
3531
|
+
|
|
3532
|
+
for (var i = 0; i < routes.length; i++) {
|
|
3533
|
+
var r = routes[i];
|
|
3534
|
+
var pattern = r.pattern;
|
|
3535
|
+
|
|
3536
|
+
// global wildcard -- save for last
|
|
3537
|
+
if (pattern === '*') { globalWild = r; continue; }
|
|
3538
|
+
|
|
3539
|
+
// catch-all: ends with /*
|
|
3540
|
+
if (pattern.length > 1 && pattern.substring(pattern.length - 2) === '/*') {
|
|
3541
|
+
var prefix = pattern.substring(0, pattern.length - 2);
|
|
3542
|
+
var prefixSegs = prefix === '' ? [''] : prefix.split('/');
|
|
3543
|
+
if (segs.length < prefixSegs.length) continue;
|
|
3544
|
+
var params = {};
|
|
3545
|
+
var ok = true;
|
|
3546
|
+
for (var j = 0; j < prefixSegs.length; j++) {
|
|
3547
|
+
if (prefixSegs[j].charAt(0) === ':') {
|
|
3548
|
+
params[prefixSegs[j].substring(1)] = segs[j];
|
|
3549
|
+
} else if (prefixSegs[j] !== segs[j]) {
|
|
3550
|
+
ok = false; break;
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
if (ok) {
|
|
3554
|
+
params._rest = segs.slice(prefixSegs.length).join('/');
|
|
3555
|
+
params._query = query;
|
|
3556
|
+
return { handler: r.handler, params: params };
|
|
3557
|
+
}
|
|
3558
|
+
continue;
|
|
3559
|
+
}
|
|
3560
|
+
|
|
3561
|
+
// exact / parameterized match
|
|
3562
|
+
var rSegs = pattern === '/' ? [''] : pattern.split('/');
|
|
3563
|
+
if (rSegs.length !== segs.length) continue;
|
|
3564
|
+
var params2 = {};
|
|
3565
|
+
var match = true;
|
|
3566
|
+
for (var k = 0; k < rSegs.length; k++) {
|
|
3567
|
+
if (rSegs[k].charAt(0) === ':') {
|
|
3568
|
+
params2[rSegs[k].substring(1)] = segs[k];
|
|
3569
|
+
} else if (rSegs[k] !== segs[k]) {
|
|
3570
|
+
match = false; break;
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
if (match) {
|
|
3574
|
+
params2._query = query;
|
|
3575
|
+
return { handler: r.handler, params: params2 };
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3579
|
+
// global wildcard fallback
|
|
3580
|
+
if (globalWild) {
|
|
3581
|
+
return { handler: globalWild.handler, params: { _query: query } };
|
|
3582
|
+
}
|
|
3583
|
+
return null;
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3586
|
+
|
|
3587
|
+
// -- public API factory --
|
|
3588
|
+
|
|
3589
|
+
function initRouter(bw) {
|
|
3590
|
+
var _activeRouter = null;
|
|
3591
|
+
|
|
3592
|
+
bw.router = function(config) {
|
|
3593
|
+
if (!config || !config.routes) throw new Error('bw.router: config.routes is required');
|
|
3594
|
+
if (!bw._isBrowser) throw new Error('bw.router: requires a browser environment');
|
|
3595
|
+
|
|
3596
|
+
var mode = config.mode || 'hash';
|
|
3597
|
+
var base = config.base || '/';
|
|
3598
|
+
if (base.length > 1 && base.charAt(base.length - 1) === '/') base = base.substring(0, base.length - 1);
|
|
3599
|
+
var target = config.target || null;
|
|
3600
|
+
|
|
3601
|
+
// compile routes (preserve registration order)
|
|
3602
|
+
var routes = [];
|
|
3603
|
+
var keys = Object.keys(config.routes);
|
|
3604
|
+
for (var i = 0; i < keys.length; i++) {
|
|
3605
|
+
routes.push({ pattern: keys[i], handler: config.routes[keys[i]] });
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
var currentPath = '/';
|
|
3609
|
+
var destroyed = false;
|
|
3610
|
+
|
|
3611
|
+
function getPath() {
|
|
3612
|
+
if (mode === 'hash') {
|
|
3613
|
+
var h = window.location.hash.replace(/^#/, '');
|
|
3614
|
+
return h || '/';
|
|
3615
|
+
}
|
|
3616
|
+
var p = window.location.pathname;
|
|
3617
|
+
if (base !== '/' && p.indexOf(base) === 0) {
|
|
3618
|
+
p = p.substring(base.length) || '/';
|
|
3619
|
+
}
|
|
3620
|
+
var s = window.location.search || '';
|
|
3621
|
+
return p + s;
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3624
|
+
function handleRoute(toRaw, opts) {
|
|
3625
|
+
if (destroyed) return;
|
|
3626
|
+
var fromPath = currentPath;
|
|
3627
|
+
var toPath = normalizePath(toRaw);
|
|
3628
|
+
|
|
3629
|
+
// before guard
|
|
3630
|
+
if (config.before) {
|
|
3631
|
+
var result = config.before(toPath, fromPath);
|
|
3632
|
+
if (result === false) return;
|
|
3633
|
+
if (typeof result === 'string') {
|
|
3634
|
+
toPath = normalizePath(result);
|
|
3635
|
+
toRaw = result;
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
|
|
3639
|
+
currentPath = toPath;
|
|
3640
|
+
|
|
3641
|
+
// match route
|
|
3642
|
+
var m = matchRoute(routes, toRaw);
|
|
3643
|
+
if (m) {
|
|
3644
|
+
var rendered = m.handler(m.params);
|
|
3645
|
+
if (rendered != null && target) {
|
|
3646
|
+
bw.DOM(target, rendered);
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3650
|
+
// pub/sub
|
|
3651
|
+
var query = parseQuery(toRaw);
|
|
3652
|
+
bw.pub('bw:route', {
|
|
3653
|
+
path: toPath,
|
|
3654
|
+
params: m ? m.params : {},
|
|
3655
|
+
query: query,
|
|
3656
|
+
from: fromPath
|
|
3657
|
+
});
|
|
3658
|
+
|
|
3659
|
+
// after hook
|
|
3660
|
+
if (config.after) config.after(toPath, fromPath);
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3663
|
+
function navigate(path, opts) {
|
|
3664
|
+
if (destroyed) return;
|
|
3665
|
+
opts = opts || {};
|
|
3666
|
+
if (mode === 'hash') {
|
|
3667
|
+
if (opts.replace) {
|
|
3668
|
+
var loc = window.location;
|
|
3669
|
+
loc.replace(loc.pathname + loc.search + '#' + path);
|
|
3670
|
+
} else {
|
|
3671
|
+
window.location.hash = path;
|
|
3672
|
+
}
|
|
3673
|
+
// hashchange listener will fire handleRoute; but if same hash, trigger manually
|
|
3674
|
+
var currentHash = window.location.hash.replace(/^#/, '') || '/';
|
|
3675
|
+
if (normalizePath(currentHash) === normalizePath(path)) {
|
|
3676
|
+
handleRoute(path);
|
|
3677
|
+
}
|
|
3678
|
+
} else {
|
|
3679
|
+
var url = (base === '/' ? '' : base) + path;
|
|
3680
|
+
if (opts.replace) {
|
|
3681
|
+
window.history.replaceState(null, '', url);
|
|
3682
|
+
} else {
|
|
3683
|
+
window.history.pushState(null, '', url);
|
|
3684
|
+
}
|
|
3685
|
+
handleRoute(path);
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
function onHashChange() {
|
|
3690
|
+
if (destroyed) return;
|
|
3691
|
+
handleRoute(getPath());
|
|
3692
|
+
}
|
|
3693
|
+
|
|
3694
|
+
function onPopState() {
|
|
3695
|
+
if (destroyed) return;
|
|
3696
|
+
handleRoute(getPath());
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
// listen
|
|
3700
|
+
if (mode === 'hash') {
|
|
3701
|
+
window.addEventListener('hashchange', onHashChange);
|
|
3702
|
+
} else {
|
|
3703
|
+
window.addEventListener('popstate', onPopState);
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
// initial render
|
|
3707
|
+
handleRoute(getPath());
|
|
3708
|
+
|
|
3709
|
+
var routerObj = {
|
|
3710
|
+
navigate: navigate,
|
|
3711
|
+
current: function() {
|
|
3712
|
+
var raw = getPath();
|
|
3713
|
+
var m = matchRoute(routes, raw);
|
|
3714
|
+
return {
|
|
3715
|
+
path: currentPath,
|
|
3716
|
+
params: m ? m.params : {},
|
|
3717
|
+
query: parseQuery(raw)
|
|
3718
|
+
};
|
|
3719
|
+
},
|
|
3720
|
+
destroy: function() {
|
|
3721
|
+
destroyed = true;
|
|
3722
|
+
if (mode === 'hash') {
|
|
3723
|
+
window.removeEventListener('hashchange', onHashChange);
|
|
3724
|
+
} else {
|
|
3725
|
+
window.removeEventListener('popstate', onPopState);
|
|
3726
|
+
}
|
|
3727
|
+
if (_activeRouter === routerObj) _activeRouter = null;
|
|
3728
|
+
}
|
|
3729
|
+
};
|
|
3730
|
+
|
|
3731
|
+
_activeRouter = routerObj;
|
|
3732
|
+
return routerObj;
|
|
3733
|
+
};
|
|
3734
|
+
|
|
3735
|
+
bw.navigate = function(path, opts) {
|
|
3736
|
+
if (_activeRouter) {
|
|
3737
|
+
_activeRouter.navigate(path, opts);
|
|
3738
|
+
} else {
|
|
3739
|
+
if (typeof console !== 'undefined' && console.warn) {
|
|
3740
|
+
console.warn('bw.navigate: no active router');
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
};
|
|
3744
|
+
|
|
3745
|
+
bw.link = function(path, content, attrs) {
|
|
3746
|
+
var a = {};
|
|
3747
|
+
if (attrs) {
|
|
3748
|
+
var keys = Object.keys(attrs);
|
|
3749
|
+
for (var i = 0; i < keys.length; i++) a[keys[i]] = attrs[keys[i]];
|
|
3750
|
+
}
|
|
3751
|
+
if (_activeRouter) {
|
|
3752
|
+
a.href = '#' + path;
|
|
3753
|
+
} else {
|
|
3754
|
+
a.href = path;
|
|
3755
|
+
}
|
|
3756
|
+
a.onclick = function(e) {
|
|
3757
|
+
e.preventDefault();
|
|
3758
|
+
bw.navigate(path);
|
|
3759
|
+
};
|
|
3760
|
+
return { t: 'a', a: a, c: content };
|
|
3761
|
+
};
|
|
3762
|
+
|
|
3763
|
+
// expose for testing: internal helpers
|
|
3764
|
+
bw._router = {
|
|
3765
|
+
matchRoute: matchRoute,
|
|
3766
|
+
normalizePath: normalizePath,
|
|
3767
|
+
parseQuery: parseQuery,
|
|
3768
|
+
getActiveRouter: function() { return _activeRouter; },
|
|
3769
|
+
resetActiveRouter: function() { _activeRouter = null; }
|
|
3770
|
+
};
|
|
3771
|
+
}
|
|
3772
|
+
|
|
3460
3773
|
/**
|
|
3461
3774
|
* Empty stub for bitwrench-bccl.js.
|
|
3462
3775
|
* Used by the lean build to exclude all BCCL component code.
|
|
@@ -7023,6 +7336,7 @@ bw.getComponent = function(id) {
|
|
|
7023
7336
|
bw.getAllComponents = function() {
|
|
7024
7337
|
return new Map(bw._componentRegistry);
|
|
7025
7338
|
};
|
|
7339
|
+
initRouter(bw);
|
|
7026
7340
|
|
|
7027
7341
|
// Register all make functions
|
|
7028
7342
|
Object.entries(components).forEach(([name, fn]) => {
|