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,4 +1,4 @@
|
|
|
1
|
-
/*! bitwrench-lean v2.0.
|
|
1
|
+
/*! bitwrench-lean v2.0.21 | 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) :
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
const VERSION_INFO = {
|
|
15
|
-
version: '2.0.
|
|
15
|
+
version: '2.0.21',
|
|
16
16
|
name: 'bitwrench',
|
|
17
17
|
description: 'A library for javascript UI functions.',
|
|
18
18
|
license: 'BSD-2-Clause',
|
|
19
19
|
homepage: 'https://deftio.github.com/bitwrench/pages',
|
|
20
20
|
repository: 'git+https://github.com/deftio/bitwrench.git',
|
|
21
21
|
author: 'manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)',
|
|
22
|
-
buildDate: '2026-03-
|
|
22
|
+
buildDate: '2026-03-24T05:30:22.242Z'
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
/**
|
|
@@ -585,10 +585,10 @@
|
|
|
585
585
|
xl: '0 4px 12px rgba(0,0,0,0.12)'
|
|
586
586
|
},
|
|
587
587
|
md: {
|
|
588
|
-
sm: '0 1px 3px rgba(0,0,0,0.
|
|
589
|
-
md: '0
|
|
590
|
-
lg: '0 4px
|
|
591
|
-
xl: '0 8px
|
|
588
|
+
sm: '0 1px 3px rgba(0,0,0,0.10), 0 1px 2px rgba(0,0,0,0.06)',
|
|
589
|
+
md: '0 4px 6px rgba(0,0,0,0.10), 0 2px 4px rgba(0,0,0,0.06)',
|
|
590
|
+
lg: '0 10px 15px rgba(0,0,0,0.12), 0 4px 6px rgba(0,0,0,0.08)',
|
|
591
|
+
xl: '0 20px 25px rgba(0,0,0,0.15), 0 8px 10px rgba(0,0,0,0.10)'
|
|
592
592
|
},
|
|
593
593
|
lg: {
|
|
594
594
|
sm: '0 2px 4px rgba(0,0,0,0.10)',
|
|
@@ -782,6 +782,9 @@
|
|
|
782
782
|
rules[_sx(scope, '.bw_card:hover')] = {
|
|
783
783
|
'box-shadow': elev.md
|
|
784
784
|
};
|
|
785
|
+
rules[_sx(scope, '.bw_card_hoverable')] = {
|
|
786
|
+
'transition': 'box-shadow ' + motion.slow + ' ' + motion.easing + ', transform ' + motion.slow + ' ' + motion.easing
|
|
787
|
+
};
|
|
785
788
|
rules[_sx(scope, '.bw_card_hoverable:hover')] = {
|
|
786
789
|
'box-shadow': elev.lg
|
|
787
790
|
};
|
|
@@ -882,7 +885,8 @@
|
|
|
882
885
|
};
|
|
883
886
|
rules[_sx(scope, '.bw_navbar_nav .bw_nav_link')] = {
|
|
884
887
|
'color': palette.secondary.base,
|
|
885
|
-
'border-radius': layout.radius.btn
|
|
888
|
+
'border-radius': layout.radius.btn,
|
|
889
|
+
'transition': 'color ' + layout.motion.fast + ' ' + layout.motion.easing + ', background-color ' + layout.motion.fast + ' ' + layout.motion.easing
|
|
886
890
|
};
|
|
887
891
|
rules[_sx(scope, '.bw_navbar_nav .bw_nav_link:hover')] = {
|
|
888
892
|
'color': palette.dark.base,
|
|
@@ -1045,15 +1049,18 @@
|
|
|
1045
1049
|
return rules;
|
|
1046
1050
|
}
|
|
1047
1051
|
|
|
1048
|
-
function generateProgress(scope, palette) {
|
|
1052
|
+
function generateProgress(scope, palette, layout) {
|
|
1049
1053
|
var rules = {};
|
|
1054
|
+
var rd = layout ? layout.radius : { badge: '.375rem' };
|
|
1050
1055
|
rules[_sx(scope, '.bw_progress')] = {
|
|
1051
1056
|
'background-color': palette.surfaceAlt,
|
|
1057
|
+
'border-radius': rd.badge,
|
|
1052
1058
|
'box-shadow': 'inset 0 1px 2px rgba(0,0,0,.1)'
|
|
1053
1059
|
};
|
|
1054
1060
|
rules[_sx(scope, '.bw_progress_bar')] = {
|
|
1055
1061
|
'color': palette.primary.textOn,
|
|
1056
1062
|
'background-color': palette.primary.base,
|
|
1063
|
+
'border-radius': 'inherit',
|
|
1057
1064
|
'box-shadow': 'inset 0 -1px 0 rgba(0,0,0,.15)'
|
|
1058
1065
|
};
|
|
1059
1066
|
// Variant progress bar colors handled by palette class
|
|
@@ -1177,7 +1184,8 @@
|
|
|
1177
1184
|
};
|
|
1178
1185
|
rules[_sx(scope, '.bw_carousel_control')] = {
|
|
1179
1186
|
'background-color': palette.dark.base,
|
|
1180
|
-
'color': palette.dark.textOn
|
|
1187
|
+
'color': palette.dark.textOn,
|
|
1188
|
+
'transition': 'background-color 0.15s ease-out'
|
|
1181
1189
|
};
|
|
1182
1190
|
rules[_sx(scope, '.bw_carousel_control:hover')] = {
|
|
1183
1191
|
'background-color': palette.dark.hover
|
|
@@ -1191,9 +1199,11 @@
|
|
|
1191
1199
|
|
|
1192
1200
|
function generateModalThemed(scope, palette, layout) {
|
|
1193
1201
|
var rules = {};
|
|
1202
|
+
var rd = layout ? layout.radius : { card: '8px' };
|
|
1194
1203
|
rules[_sx(scope, '.bw_modal_content')] = {
|
|
1195
1204
|
'background-color': palette.surface || '#fff',
|
|
1196
1205
|
'border-color': palette.light.border,
|
|
1206
|
+
'border-radius': rd.card,
|
|
1197
1207
|
'box-shadow': layout.elevation.lg
|
|
1198
1208
|
};
|
|
1199
1209
|
rules[_sx(scope, '.bw_modal_header')] = {
|
|
@@ -1210,9 +1220,11 @@
|
|
|
1210
1220
|
|
|
1211
1221
|
function generateToastThemed(scope, palette, layout) {
|
|
1212
1222
|
var rules = {};
|
|
1223
|
+
var rd = layout ? layout.radius : { card: '8px' };
|
|
1213
1224
|
rules[_sx(scope, '.bw_toast')] = {
|
|
1214
1225
|
'background-color': palette.surface || '#fff',
|
|
1215
1226
|
'border-color': palette.light.border,
|
|
1227
|
+
'border-radius': rd.card,
|
|
1216
1228
|
'box-shadow': layout.elevation.lg
|
|
1217
1229
|
};
|
|
1218
1230
|
rules[_sx(scope, '.bw_toast_header')] = {
|
|
@@ -1224,9 +1236,11 @@
|
|
|
1224
1236
|
|
|
1225
1237
|
function generateDropdownThemed(scope, palette, layout) {
|
|
1226
1238
|
var rules = {};
|
|
1239
|
+
var rd = layout ? layout.radius : { card: '8px' };
|
|
1227
1240
|
rules[_sx(scope, '.bw_dropdown_menu')] = {
|
|
1228
1241
|
'background-color': palette.surface || '#fff',
|
|
1229
1242
|
'border-color': palette.light.border,
|
|
1243
|
+
'border-radius': rd.card,
|
|
1230
1244
|
'box-shadow': layout.elevation.md
|
|
1231
1245
|
};
|
|
1232
1246
|
rules[_sx(scope, '.bw_dropdown_item')] = {
|
|
@@ -1259,6 +1273,10 @@
|
|
|
1259
1273
|
rules[_sx(scope, '.bw_form_switch .bw_switch_input:focus')] = {
|
|
1260
1274
|
'box-shadow': '0 0 0 0.25rem ' + palette.primary.focus
|
|
1261
1275
|
};
|
|
1276
|
+
rules[_sx(scope, '.bw_form_switch .bw_switch_input:focus-visible')] = {
|
|
1277
|
+
'box-shadow': '0 0 0 0.25rem ' + palette.primary.focus,
|
|
1278
|
+
'outline': 'none'
|
|
1279
|
+
};
|
|
1262
1280
|
return rules;
|
|
1263
1281
|
}
|
|
1264
1282
|
|
|
@@ -1322,12 +1340,14 @@
|
|
|
1322
1340
|
return rules;
|
|
1323
1341
|
}
|
|
1324
1342
|
|
|
1325
|
-
function generateChipInputThemed(scope, palette) {
|
|
1343
|
+
function generateChipInputThemed(scope, palette, layout) {
|
|
1326
1344
|
var rules = {};
|
|
1345
|
+
var rd = layout ? layout.radius : { input: '6px' };
|
|
1327
1346
|
rules[_sx(scope, '.bw_chip_input')] = {
|
|
1328
1347
|
'border-color': palette.light.border,
|
|
1329
1348
|
'background-color': palette.surface || '#fff',
|
|
1330
|
-
'color': palette.dark.base
|
|
1349
|
+
'color': palette.dark.base,
|
|
1350
|
+
'border-radius': rd.input
|
|
1331
1351
|
};
|
|
1332
1352
|
rules[_sx(scope, '.bw_chip_input:focus-within')] = {
|
|
1333
1353
|
'border-color': palette.primary.base,
|
|
@@ -1612,7 +1632,7 @@
|
|
|
1612
1632
|
generateTabs(scopeName, palette, layout),
|
|
1613
1633
|
generateListGroups(scopeName, palette, layout),
|
|
1614
1634
|
generatePagination(scopeName, palette, layout),
|
|
1615
|
-
generateProgress(scopeName, palette),
|
|
1635
|
+
generateProgress(scopeName, palette, layout),
|
|
1616
1636
|
generateBreadcrumbThemed(scopeName, palette, layout),
|
|
1617
1637
|
generateCloseButtonThemed(scopeName, palette),
|
|
1618
1638
|
generateSectionsThemed(scopeName, palette),
|
|
@@ -1626,7 +1646,7 @@
|
|
|
1626
1646
|
generateStatCardThemed(scopeName, palette, layout),
|
|
1627
1647
|
generateTimelineThemed(scopeName, palette),
|
|
1628
1648
|
generateStepperThemed(scopeName, palette),
|
|
1629
|
-
generateChipInputThemed(scopeName, palette),
|
|
1649
|
+
generateChipInputThemed(scopeName, palette, layout),
|
|
1630
1650
|
generateFileUploadThemed(scopeName, palette, layout),
|
|
1631
1651
|
generateRangeThemed(scopeName, palette),
|
|
1632
1652
|
generateSearchThemed(scopeName, palette, layout),
|
|
@@ -1774,7 +1794,7 @@
|
|
|
1774
1794
|
'.bw_card_text': { 'margin-bottom': '0', 'font-size': '0.9375rem', 'line-height': '1.6' },
|
|
1775
1795
|
'.bw_card_header': { 'margin-bottom': '0', 'font-weight': '600', 'font-size': '0.875rem' },
|
|
1776
1796
|
'.bw_card_footer': { 'font-size': '0.875rem' },
|
|
1777
|
-
'.bw_card_hoverable': {
|
|
1797
|
+
'.bw_card_hoverable': {},
|
|
1778
1798
|
'.bw_card_hoverable:hover': { 'transform': 'translateY(-4px)' },
|
|
1779
1799
|
'.bw_card_img_top': { 'width': '100%' },
|
|
1780
1800
|
'.bw_card_img_bottom': { 'width': '100%' },
|
|
@@ -1789,7 +1809,8 @@
|
|
|
1789
1809
|
'display': 'block', 'width': '100%',
|
|
1790
1810
|
'font-size': '0.9375rem', 'font-weight': '400', 'line-height': '1.5',
|
|
1791
1811
|
'background-clip': 'padding-box', 'appearance': 'none',
|
|
1792
|
-
'border': '1px solid transparent', 'font-family': 'inherit'
|
|
1812
|
+
'border': '1px solid transparent', 'font-family': 'inherit',
|
|
1813
|
+
'transition': 'border-color 0.15s ease-out, box-shadow 0.15s ease-out'
|
|
1793
1814
|
},
|
|
1794
1815
|
'.bw_form_control:focus': { 'outline': '2px solid currentColor', 'outline-offset': '-1px' },
|
|
1795
1816
|
'.bw_form_control::placeholder': { 'opacity': '1' },
|
|
@@ -1916,6 +1937,7 @@
|
|
|
1916
1937
|
'text-decoration': 'none', 'cursor': 'pointer',
|
|
1917
1938
|
'border': 'none', 'background': 'transparent', 'font-family': 'inherit'
|
|
1918
1939
|
},
|
|
1940
|
+
'.bw_nav_link:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '-2px' },
|
|
1919
1941
|
'.bw_nav_tabs .bw_nav_link': { 'border': 'none', 'border-bottom': '2px solid transparent', 'border-radius': '0', 'background-color': 'transparent' },
|
|
1920
1942
|
'.bw_nav_vertical': { 'flex-direction': 'column' },
|
|
1921
1943
|
'.bw_tab_content': { 'padding': '1.25rem 0' },
|
|
@@ -2033,9 +2055,11 @@
|
|
|
2033
2055
|
'display': 'inline-flex', 'align-items': 'center', 'justify-content': 'center',
|
|
2034
2056
|
'width': '1.5rem', 'height': '1.5rem', 'padding': '0',
|
|
2035
2057
|
'font-size': '1.25rem', 'font-weight': '700', 'line-height': '1',
|
|
2036
|
-
'background': 'transparent', 'border': '0', 'border-radius': '0.25rem', 'cursor': 'pointer'
|
|
2058
|
+
'background': 'transparent', 'border': '0', 'border-radius': '0.25rem', 'cursor': 'pointer',
|
|
2059
|
+
'transition': 'opacity 0.15s ease-out'
|
|
2037
2060
|
},
|
|
2038
|
-
'.bw_close:hover': { 'opacity': '0.75' }
|
|
2061
|
+
'.bw_close:hover': { 'opacity': '0.75' },
|
|
2062
|
+
'.bw_close:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '2px' }
|
|
2039
2063
|
},
|
|
2040
2064
|
|
|
2041
2065
|
// ---- Stacks ----
|
|
@@ -2117,7 +2141,8 @@
|
|
|
2117
2141
|
'flex-shrink': '0', 'width': '1.25rem', 'height': '1.25rem', 'margin-left': 'auto',
|
|
2118
2142
|
'content': '""',
|
|
2119
2143
|
'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\")",
|
|
2120
|
-
'background-repeat': 'no-repeat', 'background-size': '1.25rem'
|
|
2144
|
+
'background-repeat': 'no-repeat', 'background-size': '1.25rem',
|
|
2145
|
+
'transition': 'transform 0.2s ease-out'
|
|
2121
2146
|
},
|
|
2122
2147
|
'.bw_accordion_button:not(.bw_collapsed)::after': { 'transform': 'rotate(-180deg)' },
|
|
2123
2148
|
'.bw_accordion_body': { 'padding': '1rem 1.25rem' },
|
|
@@ -2142,6 +2167,7 @@
|
|
|
2142
2167
|
'z-index': '2', 'padding': '0'
|
|
2143
2168
|
},
|
|
2144
2169
|
'.bw_carousel_control img': { 'width': '20px', 'height': '20px', 'pointer-events': 'none' },
|
|
2170
|
+
'.bw_carousel_control:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '2px' },
|
|
2145
2171
|
'.bw_carousel_control_prev': { 'left': '10px' },
|
|
2146
2172
|
'.bw_carousel_control_next': { 'right': '10px' },
|
|
2147
2173
|
'.bw_carousel_indicators': {
|
|
@@ -2161,12 +2187,14 @@
|
|
|
2161
2187
|
'display': 'flex', 'align-items': 'center', 'justify-content': 'center',
|
|
2162
2188
|
'position': 'fixed', 'top': '0', 'left': '0', 'width': '100%', 'height': '100%',
|
|
2163
2189
|
'z-index': '1050', 'overflow-x': 'hidden', 'overflow-y': 'auto',
|
|
2164
|
-
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none'
|
|
2190
|
+
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none',
|
|
2191
|
+
'transition': 'opacity 0.2s ease-out, visibility 0.2s ease-out'
|
|
2165
2192
|
},
|
|
2166
2193
|
'.bw_modal.bw_modal_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto' },
|
|
2167
2194
|
'.bw_modal_dialog': {
|
|
2168
2195
|
'position': 'relative', 'width': 'calc(100% - 1rem)', 'max-width': '500px', 'margin': '1.75rem auto',
|
|
2169
|
-
'pointer-events': 'none'
|
|
2196
|
+
'pointer-events': 'none', 'transform': 'translateY(-16px)',
|
|
2197
|
+
'transition': 'transform 0.2s ease-out'
|
|
2170
2198
|
},
|
|
2171
2199
|
'.bw_modal.bw_modal_show .bw_modal_dialog': { 'transform': 'translateY(0)' },
|
|
2172
2200
|
'.bw_modal_sm': { 'max-width': '300px' },
|
|
@@ -2196,10 +2224,11 @@
|
|
|
2196
2224
|
'.bw_toast_container.bw_toast_bottom_center': { 'bottom': '0', 'left': '50%', 'transform': 'translateX(-50%)' },
|
|
2197
2225
|
'.bw_toast': {
|
|
2198
2226
|
'pointer-events': 'auto', 'width': '350px', 'max-width': 'calc(100vw - 2rem)', 'background-clip': 'padding-box',
|
|
2199
|
-
'opacity': '0'
|
|
2227
|
+
'opacity': '0', 'transform': 'translateY(-8px)',
|
|
2228
|
+
'transition': 'opacity 0.2s ease-out, transform 0.2s ease-out'
|
|
2200
2229
|
},
|
|
2201
2230
|
'.bw_toast.bw_toast_show': { 'opacity': '1', 'transform': 'translateY(0)' },
|
|
2202
|
-
'.bw_toast.bw_toast_hiding': { 'opacity': '0' },
|
|
2231
|
+
'.bw_toast.bw_toast_hiding': { 'opacity': '0', 'transform': 'translateY(-8px)' },
|
|
2203
2232
|
'.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' },
|
|
2204
2233
|
'.bw_toast_body': { 'padding': '0.5rem 0.75rem', 'font-size': '0.9375rem' }
|
|
2205
2234
|
},
|
|
@@ -2216,9 +2245,11 @@
|
|
|
2216
2245
|
'position': 'absolute', 'top': '100%', 'left': '0', 'z-index': '1000', 'display': 'block',
|
|
2217
2246
|
'min-width': '10rem', 'padding': '0.5rem 0', 'margin': '0.125rem 0 0',
|
|
2218
2247
|
'background-clip': 'padding-box', 'border': '1px solid transparent',
|
|
2219
|
-
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none'
|
|
2248
|
+
'opacity': '0', 'visibility': 'hidden', 'pointer-events': 'none',
|
|
2249
|
+
'transform': 'translateY(-4px)',
|
|
2250
|
+
'transition': 'opacity 0.15s ease-out, transform 0.15s ease-out, visibility 0.15s ease-out'
|
|
2220
2251
|
},
|
|
2221
|
-
'.bw_dropdown_menu.bw_dropdown_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto' },
|
|
2252
|
+
'.bw_dropdown_menu.bw_dropdown_show': { 'opacity': '1', 'visibility': 'visible', 'pointer-events': 'auto', 'transform': 'translateY(0)' },
|
|
2222
2253
|
'.bw_dropdown_menu_end': { 'left': 'auto', 'right': '0' },
|
|
2223
2254
|
'.bw_dropdown_item': {
|
|
2224
2255
|
'display': 'block', 'width': '100%', 'padding': '0.4rem 1rem', 'clear': 'both',
|
|
@@ -2237,7 +2268,8 @@
|
|
|
2237
2268
|
'appearance': 'none',
|
|
2238
2269
|
'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\")",
|
|
2239
2270
|
'background-position': 'left center', 'background-repeat': 'no-repeat',
|
|
2240
|
-
'background-size': 'contain', 'cursor': 'pointer'
|
|
2271
|
+
'background-size': 'contain', 'cursor': 'pointer',
|
|
2272
|
+
'transition': 'background-color 0.15s ease-out, background-position 0.15s ease-out, border-color 0.15s ease-out'
|
|
2241
2273
|
},
|
|
2242
2274
|
'.bw_form_switch .bw_switch_input:checked': { 'background-position': 'right center' },
|
|
2243
2275
|
'.bw_form_switch .bw_switch_input:disabled': { 'opacity': '0.5', 'cursor': 'not-allowed' }
|
|
@@ -2271,9 +2303,7 @@
|
|
|
2271
2303
|
'.bw_stat_card': {
|
|
2272
2304
|
'padding': '1.25rem',
|
|
2273
2305
|
'border-left': '4px solid transparent',
|
|
2274
|
-
'
|
|
2275
|
-
'background-color': 'inherit',
|
|
2276
|
-
'transition': 'transform 0.15s ease'
|
|
2306
|
+
'background-color': 'inherit'
|
|
2277
2307
|
},
|
|
2278
2308
|
'.bw_stat_card:hover': { 'transform': 'translateY(-1px)' },
|
|
2279
2309
|
'.bw_stat_icon': { 'font-size': '1.5rem', 'margin-bottom': '0.5rem' },
|
|
@@ -2333,7 +2363,8 @@
|
|
|
2333
2363
|
'width': '1.5rem', 'height': '1.5rem',
|
|
2334
2364
|
'border': 'none', 'background': 'none',
|
|
2335
2365
|
'font-size': '1.25rem', 'cursor': 'pointer', 'padding': '0', 'border-radius': '50%'
|
|
2336
|
-
}
|
|
2366
|
+
},
|
|
2367
|
+
'.bw_search_clear:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '2px' }
|
|
2337
2368
|
},
|
|
2338
2369
|
|
|
2339
2370
|
// ---- Range ----
|
|
@@ -2425,6 +2456,7 @@
|
|
|
2425
2456
|
'width': '1rem', 'height': '1rem', 'border': 'none', 'background': 'none',
|
|
2426
2457
|
'font-size': '0.875rem', 'cursor': 'pointer', 'padding': '0', 'border-radius': '50%'
|
|
2427
2458
|
},
|
|
2459
|
+
'.bw_chip_remove:focus-visible': { 'outline': '2px solid currentColor', 'outline-offset': '1px' },
|
|
2428
2460
|
'.bw_chip_field': { 'flex': '1', 'min-width': '80px', 'border': 'none', 'outline': 'none', 'font-size': '0.875rem', 'padding': '0.125rem 0', 'background': 'transparent' }
|
|
2429
2461
|
},
|
|
2430
2462
|
|
|
@@ -3464,6 +3496,287 @@
|
|
|
3464
3496
|
return intervalID;
|
|
3465
3497
|
}
|
|
3466
3498
|
|
|
3499
|
+
/**
|
|
3500
|
+
* Bitwrench Router -- client-side URL routing for SPAs
|
|
3501
|
+
*
|
|
3502
|
+
* Single export: initRouter(bw) attaches bw.router(), bw.navigate(), bw.link()
|
|
3503
|
+
*
|
|
3504
|
+
* @license BSD-2-Clause
|
|
3505
|
+
*/
|
|
3506
|
+
|
|
3507
|
+
// -- internal helpers --
|
|
3508
|
+
|
|
3509
|
+
function normalizePath(p) {
|
|
3510
|
+
// strip query string (handled separately)
|
|
3511
|
+
var qi = p.indexOf('?');
|
|
3512
|
+
if (qi >= 0) p = p.substring(0, qi);
|
|
3513
|
+
// collapse double slashes, strip trailing slash
|
|
3514
|
+
p = p.replace(/\/\/+/g, '/');
|
|
3515
|
+
if (p.length > 1 && p.charAt(p.length - 1) === '/') p = p.substring(0, p.length - 1);
|
|
3516
|
+
return p || '/';
|
|
3517
|
+
}
|
|
3518
|
+
|
|
3519
|
+
function parseQuery(fullPath) {
|
|
3520
|
+
var qi = fullPath.indexOf('?');
|
|
3521
|
+
if (qi < 0) return {};
|
|
3522
|
+
var qs = fullPath.substring(qi + 1);
|
|
3523
|
+
var result = {};
|
|
3524
|
+
var pairs = qs.split('&');
|
|
3525
|
+
for (var i = 0; i < pairs.length; i++) {
|
|
3526
|
+
var kv = pairs[i].split('=');
|
|
3527
|
+
if (kv[0]) result[decodeURIComponent(kv[0])] = kv.length > 1 ? decodeURIComponent(kv[1]) : '';
|
|
3528
|
+
}
|
|
3529
|
+
return result;
|
|
3530
|
+
}
|
|
3531
|
+
|
|
3532
|
+
function matchRoute(routes, rawPath) {
|
|
3533
|
+
var query = parseQuery(rawPath);
|
|
3534
|
+
var path = normalizePath(rawPath);
|
|
3535
|
+
var segs = path === '/' ? [''] : path.split('/');
|
|
3536
|
+
|
|
3537
|
+
var globalWild = null;
|
|
3538
|
+
|
|
3539
|
+
for (var i = 0; i < routes.length; i++) {
|
|
3540
|
+
var r = routes[i];
|
|
3541
|
+
var pattern = r.pattern;
|
|
3542
|
+
|
|
3543
|
+
// global wildcard -- save for last
|
|
3544
|
+
if (pattern === '*') { globalWild = r; continue; }
|
|
3545
|
+
|
|
3546
|
+
// catch-all: ends with /*
|
|
3547
|
+
if (pattern.length > 1 && pattern.substring(pattern.length - 2) === '/*') {
|
|
3548
|
+
var prefix = pattern.substring(0, pattern.length - 2);
|
|
3549
|
+
var prefixSegs = prefix === '' ? [''] : prefix.split('/');
|
|
3550
|
+
if (segs.length < prefixSegs.length) continue;
|
|
3551
|
+
var params = {};
|
|
3552
|
+
var ok = true;
|
|
3553
|
+
for (var j = 0; j < prefixSegs.length; j++) {
|
|
3554
|
+
if (prefixSegs[j].charAt(0) === ':') {
|
|
3555
|
+
params[prefixSegs[j].substring(1)] = segs[j];
|
|
3556
|
+
} else if (prefixSegs[j] !== segs[j]) {
|
|
3557
|
+
ok = false; break;
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
if (ok) {
|
|
3561
|
+
params._rest = segs.slice(prefixSegs.length).join('/');
|
|
3562
|
+
params._query = query;
|
|
3563
|
+
return { handler: r.handler, params: params };
|
|
3564
|
+
}
|
|
3565
|
+
continue;
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
// exact / parameterized match
|
|
3569
|
+
var rSegs = pattern === '/' ? [''] : pattern.split('/');
|
|
3570
|
+
if (rSegs.length !== segs.length) continue;
|
|
3571
|
+
var params2 = {};
|
|
3572
|
+
var match = true;
|
|
3573
|
+
for (var k = 0; k < rSegs.length; k++) {
|
|
3574
|
+
if (rSegs[k].charAt(0) === ':') {
|
|
3575
|
+
params2[rSegs[k].substring(1)] = segs[k];
|
|
3576
|
+
} else if (rSegs[k] !== segs[k]) {
|
|
3577
|
+
match = false; break;
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
if (match) {
|
|
3581
|
+
params2._query = query;
|
|
3582
|
+
return { handler: r.handler, params: params2 };
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3586
|
+
// global wildcard fallback
|
|
3587
|
+
if (globalWild) {
|
|
3588
|
+
return { handler: globalWild.handler, params: { _query: query } };
|
|
3589
|
+
}
|
|
3590
|
+
return null;
|
|
3591
|
+
}
|
|
3592
|
+
|
|
3593
|
+
|
|
3594
|
+
// -- public API factory --
|
|
3595
|
+
|
|
3596
|
+
function initRouter(bw) {
|
|
3597
|
+
var _activeRouter = null;
|
|
3598
|
+
|
|
3599
|
+
bw.router = function(config) {
|
|
3600
|
+
if (!config || !config.routes) throw new Error('bw.router: config.routes is required');
|
|
3601
|
+
if (!bw._isBrowser) throw new Error('bw.router: requires a browser environment');
|
|
3602
|
+
|
|
3603
|
+
var mode = config.mode || 'hash';
|
|
3604
|
+
var base = config.base || '/';
|
|
3605
|
+
if (base.length > 1 && base.charAt(base.length - 1) === '/') base = base.substring(0, base.length - 1);
|
|
3606
|
+
var target = config.target || null;
|
|
3607
|
+
|
|
3608
|
+
// compile routes (preserve registration order)
|
|
3609
|
+
var routes = [];
|
|
3610
|
+
var keys = Object.keys(config.routes);
|
|
3611
|
+
for (var i = 0; i < keys.length; i++) {
|
|
3612
|
+
routes.push({ pattern: keys[i], handler: config.routes[keys[i]] });
|
|
3613
|
+
}
|
|
3614
|
+
|
|
3615
|
+
var currentPath = '/';
|
|
3616
|
+
var destroyed = false;
|
|
3617
|
+
|
|
3618
|
+
function getPath() {
|
|
3619
|
+
if (mode === 'hash') {
|
|
3620
|
+
var h = window.location.hash.replace(/^#/, '');
|
|
3621
|
+
return h || '/';
|
|
3622
|
+
}
|
|
3623
|
+
var p = window.location.pathname;
|
|
3624
|
+
if (base !== '/' && p.indexOf(base) === 0) {
|
|
3625
|
+
p = p.substring(base.length) || '/';
|
|
3626
|
+
}
|
|
3627
|
+
var s = window.location.search || '';
|
|
3628
|
+
return p + s;
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3631
|
+
function handleRoute(toRaw, opts) {
|
|
3632
|
+
if (destroyed) return;
|
|
3633
|
+
var fromPath = currentPath;
|
|
3634
|
+
var toPath = normalizePath(toRaw);
|
|
3635
|
+
|
|
3636
|
+
// before guard
|
|
3637
|
+
if (config.before) {
|
|
3638
|
+
var result = config.before(toPath, fromPath);
|
|
3639
|
+
if (result === false) return;
|
|
3640
|
+
if (typeof result === 'string') {
|
|
3641
|
+
toPath = normalizePath(result);
|
|
3642
|
+
toRaw = result;
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
|
|
3646
|
+
currentPath = toPath;
|
|
3647
|
+
|
|
3648
|
+
// match route
|
|
3649
|
+
var m = matchRoute(routes, toRaw);
|
|
3650
|
+
if (m) {
|
|
3651
|
+
var rendered = m.handler(m.params);
|
|
3652
|
+
if (rendered != null && target) {
|
|
3653
|
+
bw.DOM(target, rendered);
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
// pub/sub
|
|
3658
|
+
var query = parseQuery(toRaw);
|
|
3659
|
+
bw.pub('bw:route', {
|
|
3660
|
+
path: toPath,
|
|
3661
|
+
params: m ? m.params : {},
|
|
3662
|
+
query: query,
|
|
3663
|
+
from: fromPath
|
|
3664
|
+
});
|
|
3665
|
+
|
|
3666
|
+
// after hook
|
|
3667
|
+
if (config.after) config.after(toPath, fromPath);
|
|
3668
|
+
}
|
|
3669
|
+
|
|
3670
|
+
function navigate(path, opts) {
|
|
3671
|
+
if (destroyed) return;
|
|
3672
|
+
opts = opts || {};
|
|
3673
|
+
if (mode === 'hash') {
|
|
3674
|
+
if (opts.replace) {
|
|
3675
|
+
var loc = window.location;
|
|
3676
|
+
loc.replace(loc.pathname + loc.search + '#' + path);
|
|
3677
|
+
} else {
|
|
3678
|
+
window.location.hash = path;
|
|
3679
|
+
}
|
|
3680
|
+
// hashchange listener will fire handleRoute; but if same hash, trigger manually
|
|
3681
|
+
var currentHash = window.location.hash.replace(/^#/, '') || '/';
|
|
3682
|
+
if (normalizePath(currentHash) === normalizePath(path)) {
|
|
3683
|
+
handleRoute(path);
|
|
3684
|
+
}
|
|
3685
|
+
} else {
|
|
3686
|
+
var url = (base === '/' ? '' : base) + path;
|
|
3687
|
+
if (opts.replace) {
|
|
3688
|
+
window.history.replaceState(null, '', url);
|
|
3689
|
+
} else {
|
|
3690
|
+
window.history.pushState(null, '', url);
|
|
3691
|
+
}
|
|
3692
|
+
handleRoute(path);
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
function onHashChange() {
|
|
3697
|
+
if (destroyed) return;
|
|
3698
|
+
handleRoute(getPath());
|
|
3699
|
+
}
|
|
3700
|
+
|
|
3701
|
+
function onPopState() {
|
|
3702
|
+
if (destroyed) return;
|
|
3703
|
+
handleRoute(getPath());
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
// listen
|
|
3707
|
+
if (mode === 'hash') {
|
|
3708
|
+
window.addEventListener('hashchange', onHashChange);
|
|
3709
|
+
} else {
|
|
3710
|
+
window.addEventListener('popstate', onPopState);
|
|
3711
|
+
}
|
|
3712
|
+
|
|
3713
|
+
// initial render
|
|
3714
|
+
handleRoute(getPath());
|
|
3715
|
+
|
|
3716
|
+
var routerObj = {
|
|
3717
|
+
navigate: navigate,
|
|
3718
|
+
current: function() {
|
|
3719
|
+
var raw = getPath();
|
|
3720
|
+
var m = matchRoute(routes, raw);
|
|
3721
|
+
return {
|
|
3722
|
+
path: currentPath,
|
|
3723
|
+
params: m ? m.params : {},
|
|
3724
|
+
query: parseQuery(raw)
|
|
3725
|
+
};
|
|
3726
|
+
},
|
|
3727
|
+
destroy: function() {
|
|
3728
|
+
destroyed = true;
|
|
3729
|
+
if (mode === 'hash') {
|
|
3730
|
+
window.removeEventListener('hashchange', onHashChange);
|
|
3731
|
+
} else {
|
|
3732
|
+
window.removeEventListener('popstate', onPopState);
|
|
3733
|
+
}
|
|
3734
|
+
if (_activeRouter === routerObj) _activeRouter = null;
|
|
3735
|
+
}
|
|
3736
|
+
};
|
|
3737
|
+
|
|
3738
|
+
_activeRouter = routerObj;
|
|
3739
|
+
return routerObj;
|
|
3740
|
+
};
|
|
3741
|
+
|
|
3742
|
+
bw.navigate = function(path, opts) {
|
|
3743
|
+
if (_activeRouter) {
|
|
3744
|
+
_activeRouter.navigate(path, opts);
|
|
3745
|
+
} else {
|
|
3746
|
+
if (typeof console !== 'undefined' && console.warn) {
|
|
3747
|
+
console.warn('bw.navigate: no active router');
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
};
|
|
3751
|
+
|
|
3752
|
+
bw.link = function(path, content, attrs) {
|
|
3753
|
+
var a = {};
|
|
3754
|
+
if (attrs) {
|
|
3755
|
+
var keys = Object.keys(attrs);
|
|
3756
|
+
for (var i = 0; i < keys.length; i++) a[keys[i]] = attrs[keys[i]];
|
|
3757
|
+
}
|
|
3758
|
+
if (_activeRouter) {
|
|
3759
|
+
a.href = '#' + path;
|
|
3760
|
+
} else {
|
|
3761
|
+
a.href = path;
|
|
3762
|
+
}
|
|
3763
|
+
a.onclick = function(e) {
|
|
3764
|
+
e.preventDefault();
|
|
3765
|
+
bw.navigate(path);
|
|
3766
|
+
};
|
|
3767
|
+
return { t: 'a', a: a, c: content };
|
|
3768
|
+
};
|
|
3769
|
+
|
|
3770
|
+
// expose for testing: internal helpers
|
|
3771
|
+
bw._router = {
|
|
3772
|
+
matchRoute: matchRoute,
|
|
3773
|
+
normalizePath: normalizePath,
|
|
3774
|
+
parseQuery: parseQuery,
|
|
3775
|
+
getActiveRouter: function() { return _activeRouter; },
|
|
3776
|
+
resetActiveRouter: function() { _activeRouter = null; }
|
|
3777
|
+
};
|
|
3778
|
+
}
|
|
3779
|
+
|
|
3467
3780
|
/**
|
|
3468
3781
|
* Empty stub for bitwrench-bccl.js.
|
|
3469
3782
|
* Used by the lean build to exclude all BCCL component code.
|
|
@@ -7030,6 +7343,7 @@
|
|
|
7030
7343
|
bw.getAllComponents = function() {
|
|
7031
7344
|
return new Map(bw._componentRegistry);
|
|
7032
7345
|
};
|
|
7346
|
+
initRouter(bw);
|
|
7033
7347
|
|
|
7034
7348
|
// Register all make functions
|
|
7035
7349
|
Object.entries(components).forEach(([name, fn]) => {
|