@wwtdev/bsds-css 2.4.1 → 2.5.0

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/wwt-bsds.css CHANGED
@@ -1074,1592 +1074,1646 @@ a:where(.bs-link):where(:focus:not(:focus-visible)) {
1074
1074
  display: inline-flex;
1075
1075
  }
1076
1076
  }
1077
- .bs-button {
1078
- --btn-main: var(--bs-blue-400);
1079
- --btn-secondary: var(--bs-blue-medium);
1080
- --btn-highlight: var(--bs-blue-100);
1081
- --btn-padding: .25rem .75rem;
1082
- --btn-focus-pseudo-width: calc(100% + 0.5rem);
1083
- --btn-ghost-ink: var(--bs-ink-blue);
1084
- --btn-ink: var(--bs-white);
1085
- align-items: center;
1086
- background-color: var(--btn-main);
1087
- border: none;
1088
- border-radius: 0.25rem;
1089
- color: var(--btn-ink);
1090
- cursor: pointer;
1091
- display: inline-flex;
1092
- font-size: var(--btn-text-size, var(--bs-text-md));
1093
- font-weight: var(--btn-weight, 600);
1094
- height: var(--btn-height, 2.5rem);
1095
- justify-content: center;
1096
- line-height: 1.5;
1097
- outline: 2px solid transparent;
1098
- padding: var(--btn-padding);
1077
+ /* Parent */
1078
+ .bs-dropdown-parent {
1079
+ display: inline-block;
1099
1080
  position: relative;
1100
- text-decoration: none;
1101
- transition: all 100ms ease-in-out;
1102
- vertical-align: middle;
1103
1081
  }
1104
- .bs-button:hover {
1105
- background-color: var(--btn-secondary);
1106
- }
1107
- .bs-button:active {
1108
- background-color: var(--btn-secondary);
1109
- transform: scale(0.97);
1110
- transform-origin: center;
1111
- box-shadow: inset 0px 0px 4px 1px var(--btn-main);
1082
+ /* Backdrop for mobile bottom sheet */
1083
+ .bs-dropdown-backdrop {
1084
+ -webkit-backdrop-filter: blur(4px);
1085
+ backdrop-filter: blur(4px);
1086
+ background: rgba(29, 30, 72, 0.05);
1087
+ bottom: 0;
1088
+ content: "";
1089
+ left: 0;
1090
+ position: fixed;
1091
+ right: 0;
1092
+ top: 0;
1093
+ z-index: 998;
1112
1094
  }
1113
- /* ------------ Focus Styles ------------ */
1114
- .bs-button::before {
1115
- border-color: transparent;
1116
- border-radius: 0.5rem;
1117
- border-style: solid;
1118
- border-width: 0.125rem;
1119
- content: '';
1120
- height: calc(100% + 0.5rem);
1121
- inset: -0.25rem;
1122
- left: auto;
1123
- position: absolute;
1124
- right: auto;
1125
- transition: border-color 0.125s ease-in-out;
1126
- width: var(--btn-focus-pseudo-width);
1095
+ /* Content */
1096
+ .bs-dropdown {
1097
+ --dropdown-bottom: 0;
1098
+ --dropdown-left: 0;
1099
+ --dropdown-right: auto;
1100
+ --dropdown-top: auto;
1101
+ --dropdown-width: 100%;
1102
+ --dropdown-transform: translate(0, 100%);
1103
+
1104
+ background-color: var(--bs-bg-base-elevated);
1105
+ border-radius: 4px;
1106
+ bottom: var(--dropdown-bottom);
1107
+ box-shadow: var(--bs-shadow-contentMedium);
1108
+ left: var(--dropdown-left);
1109
+ line-height: 1.5rem;
1110
+ margin: 0;
1111
+ opacity: 0;
1112
+ overflow-y: auto;
1113
+ position: fixed;
1114
+ right: var(--dropdown-right);
1115
+ top: var(--dropdown-top);
1116
+ transform-origin: center bottom;
1117
+ transform: var(--dropdown-transform);
1118
+ transition-duration: 75ms;
1119
+ transition-property: opacity, transform;
1120
+ transition-timing-function: ease-in-out;
1121
+ width: var(--dropdown-width);
1122
+ z-index: 999;
1127
1123
  }
1128
- .bs-button:focus::before {
1129
- border-color: var(--btn-main);
1124
+ /* Mobile Header */
1125
+ .bs-dropdown > :where(header) {
1126
+ border-bottom: 1px solid var(--bs-border-base);
1127
+ display: flex;
1128
+ justify-content: space-between;
1129
+ padding: 1.5rem;
1130
1130
  }
1131
- .bs-button:focus-visible::before {
1132
- border-color: var(--btn-main);
1133
- box-shadow: none;
1131
+ .bs-dropdown > :where(header) :where(h3) {
1132
+ font-size: 1.25rem;
1134
1133
  }
1135
- .bs-button:focus:not(:focus-visible)::before {
1136
- border-color: transparent;
1137
- box-shadow: none;
1134
+ .bs-dropdown > :where(header) :where(p) {
1135
+ font-size: 1rem;
1138
1136
  }
1139
- /* ------------ Ghost Buttons ------------ */
1140
- .bs-button:where([data-ghost]:not([data-ghost="false"])) {
1141
- --btn-ink: var(--btn-ghost-ink);
1142
- --btn-light: var(--bs-blue-10);
1143
- --btn-secondary: var(--bs-blue-10);
1144
- background-color: transparent;
1145
- box-shadow: inset 0 0 0 1px var(--btn-main);
1137
+ .bs-dropdown > :where(header) :where(button) {
1138
+ cursor: pointer;
1139
+ height: 1rem;
1140
+ width: 1rem;
1146
1141
  }
1147
- .bs-button:where([data-ghost]:not([data-ghost="false"]))::before {
1148
- border-radius: 0.4375rem;
1142
+ /* data-shown */
1143
+ .bs-dropdown:where([data-shown]:not([data-shown="false"])) {
1144
+ --dropdown-transform: translate(0, 0);
1145
+ opacity: 1;
1149
1146
  }
1150
- .bs-button:where([data-ghost]:not([data-ghost="false"])):hover,
1151
- .bs-button:where([data-ghost]:not([data-ghost="false"])):focus {
1152
- background-color: var(--btn-light);
1147
+ /* Sizing */
1148
+ .bs-dropdown:where([data-width="sm"]) {
1149
+ --dropdown-wscreen-width: 10rem;
1153
1150
  }
1154
- .bs-button:where([data-ghost]:not([data-ghost="false"])):active {
1155
- box-shadow:
1156
- inset 0 0 0 1px var(--btn-main),
1157
- inset 0px 0px 4px 1px var(--btn-highlight);
1151
+ .bs-dropdown:where([data-width="md"]),
1152
+ .bs-dropdown:where(:not([data-width])) {
1153
+ --dropdown-wscreen-width: 20rem;
1158
1154
  }
1159
- /* ------------ VARIANTS ------------ */
1160
- .bs-button:where([data-variant^='secondary']) {
1161
- --btn-main: var(--bs-plum-400);
1162
- --btn-secondary: var(--bs-plum-medium);
1163
- --btn-light: var(--bs-plum-10);
1164
- --btn-highlight: var(--bs-plum-100);
1165
- --btn-ghost-ink: var(--bs-ink-plum);
1155
+ .bs-dropdown:where([data-width="lg"]) {
1156
+ --dropdown-wscreen-width: 40rem;
1166
1157
  }
1167
- .dark .bs-button:where([data-variant^='secondary']) {
1168
- --btn-main: var(--bs-plum-200);
1169
- --btn-secondary: var(--bs-plum-300);
1170
- --btn-light: var(--bs-navy-400);
1171
- --btn-highlight: var(--bs-plum-400);
1158
+ .bs-dropdown:where([data-width="content"]) {
1159
+ --dropdown-wscreen-width: max-content;
1172
1160
  }
1173
- .bs-button:where([data-variant^='positive']) {
1174
- --btn-main: var(--bs-purple-400);
1175
- --btn-secondary: var(--bs-purple-medium);
1176
- --btn-light: var(--bs-purple-10);
1177
- --btn-highlight: var(--bs-purple-100);
1178
- --btn-ghost-ink: var(--bs-ink-purple);
1161
+ .bs-dropdown-parent:where([data-width="toggle"]) :where(.bs-dropdown),
1162
+ .bs-dropdown-parent:where([data-width="anchor"]) :where(.bs-dropdown) {
1163
+ --dropdown-wscreen-width: 100%;
1179
1164
  }
1180
- .bs-button:where([data-variant^='warning']) {
1181
- --btn-main: var(--bs-orange-warning);
1182
- --btn-secondary: var(--bs-orange-base);
1183
- --btn-light: var(--bs-orange-10);
1184
- --btn-highlight: var(--bs-orange-100);
1185
- --btn-ghost-ink: var(--bs-ink-orange);
1165
+ /* data-top */
1166
+ .bs-dropdown:where([data-top]:not([data-top="false"])) {
1167
+ --dropdown-wscreen-bottom: calc(100% + 0.5rem);
1168
+ --dropdown-wscreen-top: auto;
1186
1169
  }
1187
- .bs-button:where([data-variant^='negative']) {
1188
- --btn-main: var(--bs-red-400);
1189
- --btn-secondary: var(--bs-red-medium);
1190
- --btn-light: var(--bs-red-10);
1191
- --btn-highlight: var(--bs-red-100);
1192
- --btn-ghost-ink: var(--bs-ink-red);
1170
+ /* data-center */
1171
+ .bs-dropdown-parent:where([data-center]:not([data-center="false"])) :where(.bs-dropdown) {
1172
+ --dropdown-transform: translate(-50%, 0);
1173
+ --dropdown-wscreen-left: 50%;
1193
1174
  }
1194
- /* ------------ Text Button ------------ */
1195
- .bs-button:where([data-text]:not([data-text="false"])) {
1196
- --btn-height: auto;
1197
- --btn-ink: var(--bs-ink-blue);
1198
- --btn-padding: 0;
1199
- --btn-focus-pseudo-width: calc(100% + 1rem); /* text btns don't have side padding, but we do want focus outline to look padded */
1200
- --btn-text-size: var(--bs-text-md);
1201
- --btn-weight: 400;
1202
- background-color: transparent;
1203
- cursor: pointer;
1204
- line-height: 150%;
1175
+ /* Overrides mobile style when not min-width 752 */
1176
+ .bs-dropdown:where([data-no-mobile="true"]) {
1177
+ --dropdown-bottom: var(--dropdown-wscreen-bottom, auto);
1178
+ --dropdown-left: var(--dropdown-wscreen-left, initial);
1179
+ --dropdown-right: var(--dropdown-wscreen-right, initial);
1180
+ --dropdown-top: var(--dropdown-wscreen-top, calc(100% + 0.5rem));
1181
+ --dropdown-width: var(--dropdown-wscreen-width, initial);
1182
+ --dropdown-transform: initial;
1183
+
1184
+ position: absolute;
1205
1185
  }
1206
- .bs-button:where([data-text]:not([data-text="false"])):hover {
1207
- --btn-ink: var(--bs-blue-base);
1208
- background-color: transparent;
1209
- text-decoration: underline;
1186
+ .bs-dropdown:where([data-no-mobile="true"]) > :where(header) {
1187
+ display: none;
1210
1188
  }
1211
- .bs-button:where([data-text]:not([data-text="false"])):has(svg):hover {
1212
- text-decoration: none;
1189
+ @media (min-width: 752px) {
1190
+ .bs-dropdown-backdrop {
1191
+ display: none;
1192
+ }
1193
+
1194
+ .bs-dropdown {
1195
+ --dropdown-bottom: var(--dropdown-wscreen-bottom, auto);
1196
+ --dropdown-left: var(--dropdown-wscreen-left, initial);
1197
+ --dropdown-right: var(--dropdown-wscreen-right, initial);
1198
+ --dropdown-top: var(--dropdown-wscreen-top, calc(100% + 0.5rem));
1199
+ --dropdown-width: var(--dropdown-wscreen-width, initial);
1200
+ --dropdown-transform: initial;
1201
+
1202
+ position: absolute;
1203
+ }
1204
+
1205
+ /* Hide the header */
1206
+ .bs-dropdown > :where(header) {
1207
+ display: none;
1208
+ }
1213
1209
  }
1214
- .bs-button:where([data-text]:not([data-text="false"])):active {
1215
- box-shadow: none;
1216
- transform: none;
1210
+ /* Option list */
1211
+ .bs-dropdown-options {
1212
+ display: flex;
1213
+ flex-direction: column;
1214
+ gap: 0.5rem;
1215
+ list-style: none;
1216
+ margin-bottom: 0.25rem;
1217
+ margin-top: 0.25rem;
1218
+ max-height: var(--options-height-max, 20rem);/* constrain scrollable to options section */
1219
+ overflow-y: auto;
1220
+ padding-block: 0.5rem;
1221
+ padding-left: 0;
1222
+ position: relative;
1217
1223
  }
1218
- /* ------------ Button Sizes, Media-based Text Sizing -------------- */
1219
- /* Std button: Mobile text size, DT text size */
1220
- .bs-button {
1221
- --btn-text-size: 1rem;
1224
+ .bs-dropdown-options:focus-visible {
1225
+ outline: none;
1222
1226
  }
1223
- @media (min-width: 1166px) {
1224
- .bs-button {
1225
- --btn-text-size: 1.125rem;
1227
+ /* Stabilize scrollbar gutter for Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=764076) */
1228
+ @media (min-width: 752px) {
1229
+ /* 5th or 8th child triggers overflow-y (depending on variant) */
1230
+ :where([data-width="content"]) > .bs-dropdown-options:where(:has([data-variant*="description"]:nth-child(5))),
1231
+ :where([data-width="content"]) > .bs-dropdown-options:where(:has(li:not([data-variant*="description"]):nth-child(8))) {
1232
+ scrollbar-gutter: stable;
1233
+ }
1234
+
1235
+ /* Fallback for older Firefox+ only if we're not setting data-overflow values */
1236
+ @supports not selector(:has(*)) {
1237
+ :where([data-width="content"]) > .bs-dropdown-options {
1238
+ scrollbar-gutter: stable;
1239
+ }
1240
+ }
1241
+
1242
+ /* Also allow this for js solutions if :has not available via data-overflow */
1243
+ /* Reset scrollbar gutter when data-overflow is used */
1244
+ :where([data-width="content"]) > .bs-dropdown-options:where([data-overflow]) {
1245
+ scrollbar-gutter: auto;
1246
+ }
1247
+
1248
+ :where([data-width="content"]) > .bs-dropdown-options:where([data-overflow="true"]) {
1249
+ scrollbar-gutter: stable;
1226
1250
  }
1227
1251
  }
1228
- .bs-button:where([data-size^='sm']) {
1229
- --btn-height: 1.75rem;
1230
- --btn-padding: .25rem .75rem .375rem;
1231
- /* Std button size="sm" text size is same across all media sizes */
1232
- --btn-text-size: var(--bs-text-sm);
1252
+ /* Option list item */
1253
+ .bs-dropdown-options :where(li) {
1254
+ align-items: center;
1255
+ border-bottom: 2px solid transparent;
1256
+ border-left: 4px solid transparent;
1257
+ border-radius: 3px;
1258
+ border-right: 2px solid transparent;
1259
+ border-top: 2px solid transparent;
1260
+ color: var(--bs-ink-base);
1261
+ -moz-column-gap: 0.5rem;
1262
+ column-gap: 0.5rem;
1263
+ cursor: pointer;
1264
+ display: grid;
1265
+ padding-block: 0.25rem;
1266
+ padding-inline: 1.25rem;
1267
+ row-gap: 0.125rem;
1268
+ word-break: break-word;
1269
+ word-wrap: break-word;
1233
1270
  }
1234
- /* Text buttons: For now, text size not dependent on media size */
1235
- .bs-button:where([data-text]:not([data-text="false"])) {
1236
- --btn-height: auto;
1237
- --btn-padding: 0;
1238
- --btn-text-size: var(--bs-text-md);
1271
+ /* Variant: 2-col */
1272
+ .bs-dropdown-options :where(li[data-variant~="2-col"]) {
1273
+ grid-template-columns: min-content 1fr;
1239
1274
  }
1240
- .bs-button:where([data-size^='sm'][data-text]:not([data-text="false"])) {
1241
- --btn-text-size: var(--bs-text-base);
1275
+ /* Variant: 3-col */
1276
+ .bs-dropdown-options :where(li[data-variant~="3-col"]) {
1277
+ grid-template-columns: min-content min-content 1fr;
1278
+ }
1279
+ /* Variant: description */
1280
+ .bs-dropdown-options :where(li:not([data-variant*="-col"])[data-variant~="description"] > :nth-child(2)),
1281
+ .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"] > :nth-child(3)),
1282
+ .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"] > :nth-child(4)) {
1283
+ color: var(--bs-ink-light);
1284
+ font-size: var(--bs-text-xs);
1285
+ min-height: 1.125rem;
1286
+ line-height: 1.125rem;
1287
+ }
1288
+ /* Variant: 2-col description */
1289
+ .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"] > :nth-child(3)) {
1290
+ grid-column-start: 2;
1291
+ }
1292
+ /* Variant: 3-col description */
1293
+ .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"] > :nth-child(4)) {
1294
+ grid-column-start: 3;
1295
+ }
1296
+ /* Hover or data-selected */
1297
+ .bs-dropdown-options :where(li:not([role="separator"]):hover),
1298
+ .bs-dropdown-options :where(li[data-selected]) {
1299
+ background-color: var(--bs-bg-medium);
1300
+ border-left: 4px solid var(--bs-ink-blue);
1301
+ color: var(--bs-ink-blue);
1302
+ outline: none;
1303
+ }
1304
+ /* Variant: negative */
1305
+ .bs-dropdown-options :where(li[data-variant~="negative"]:hover),
1306
+ .bs-dropdown-options :where(li[data-variant~="negative"][data-selected]),
1307
+ .bs-dropdown-options :where(li[data-variant~="negative"][data-selected]:hover) {
1308
+ /* 25% alpha version of --bs-red-400 */
1309
+ background-color: rgba(248, 169, 170, 0.25);
1310
+ border-left: 4px solid var(--bs-ink-red);
1311
+ color: var(--bs-ink-red);
1242
1312
  }
1243
- /* Size XS & XXS only applies to text buttons */
1244
- .bs-button:where([data-size^='xs'][data-text]:not([data-text="false"])) {
1245
- --btn-text-size: var(--bs-text-sm);
1313
+ /* Hover or data-selected for 2-col/3-col/description variants */
1314
+ .bs-dropdown-options :where(li:not([data-variant*="-col"])[data-variant~="description"]:hover > :nth-child(2)),
1315
+ .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"]:hover > :nth-child(3)),
1316
+ .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"]:hover > :nth-child(4)),
1317
+ .bs-dropdown-options :where(li:not([data-variant*="-col"])[data-variant~="description"][data-selected] > :nth-child(2)),
1318
+ .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"][data-selected] > :nth-child(3)),
1319
+ .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"][data-selected] > :nth-child(4)) {
1320
+ color: var(--bs-ink-blue);
1246
1321
  }
1247
- .bs-button:where([data-size^='xxs'][data-text]:not([data-text="false"])) {
1248
- --btn-text-size: var(--bs-text-xs);
1249
- --btn-weight: 600;
1322
+ /* Hover or data-selected for negative + 2-col/3-col/description variants */
1323
+ .bs-dropdown-options :where(li[data-variant~="negative"]:not([data-variant*="-col"])[data-variant~="description"]:hover > :nth-child(2)),
1324
+ .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="2-col"][data-variant~="description"]:hover > :nth-child(3)),
1325
+ .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="3-col"][data-variant~="description"]:hover > :nth-child(4)),
1326
+ .bs-dropdown-options :where(li[data-variant~="negative"]:not([data-variant*="-col"])[data-variant~="description"][data-selected] > :nth-child(2)),
1327
+ .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="2-col"][data-variant~="description"][data-selected] > :nth-child(3)),
1328
+ .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="3-col"][data-variant~="description"][data-selected] > :nth-child(4)) {
1329
+ color: var(--bs-ink-red);
1250
1330
  }
1251
- /* ------------ Disabled Styling ------------ */
1252
- :where(button:disabled),
1253
- .bs-button:where(:disabled),
1254
- .bs-button:where([aria-disabled="true"]) /* for links as buttons */ {
1255
- pointer-events: none;
1331
+ /* List option keyboard navigation focus */
1332
+ .bs-dropdown-options:where(:focus-visible) :where(li[data-active]) {
1333
+ --focus-border-color: var(--bs-blue-base);
1334
+ border: 2px solid var(--focus-border-color);
1335
+ outline: none;
1336
+ padding-left: 1.375rem;
1256
1337
  }
1257
- .bs-button:where(:disabled),
1258
- .bs-button:where([aria-disabled="true"]) {
1259
- --btn-ink: var(--bs-ink-disabled);
1260
- --btn-main: var(--bs-bg-disabled);
1338
+ /* Navigation focus on a selected element should preserve 4px left border */
1339
+ .bs-dropdown-options:where(:focus-visible) :where(li[data-selected][data-active]) {
1340
+ border-left: 4px solid var(--focus-border-color);
1341
+ padding-left: 1.25rem;
1261
1342
  }
1262
- .bs-button:where([data-ghost]:not([data-ghost="false"])):disabled,
1263
- .bs-button:where([data-ghost]:not([data-ghost="false"]))[aria-disabled="true"] {
1264
- box-shadow: inset 0 0 0 1px var(--bs-gray-400);
1343
+ /* data-variant="negative" list option keyboard navigation focus */
1344
+ .bs-dropdown-options:where(:focus-visible) :where(li[data-variant~="negative"][data-active]) {
1345
+ --focus-border-color: var(--bs-red-200);
1265
1346
  }
1266
- .bs-button:where([data-text]:not([data-text="false"])):disabled,
1267
- .bs-button:where([data-text]:not([data-text="false"]))[aria-disabled="true"] {
1268
- --btn-main: transparent;
1347
+ /* Multi-select divider */
1348
+ .bs-dropdown-options :where(li[role="separator"]) {
1349
+ cursor: default;
1350
+ padding-block: 0.125rem;
1351
+ padding-right: 1.375rem;
1269
1352
  }
1270
- /* ------------ links as buttons ------------ */
1271
- a.bs-button {
1272
- align-items: center;
1273
- display: inline-flex;
1274
- outline: none;
1275
- vertical-align: middle;
1353
+ /* Multi-select divider line */
1354
+ .bs-dropdown-options :where(hr) {
1355
+ background-color: var(--bs-navy-light);
1356
+ height: .0625rem;
1357
+ margin-block: 0;
1358
+ margin-inline: 0;
1276
1359
  }
1277
- .bs-circle-button {
1278
- --btn-main: var(--bs-blue-base);
1279
- --btn-secondary: var(--bs-blue-medium);
1280
- --btn-highlight: var(--bs-blue-lightest);
1281
- --btn-border-color: transparent;
1282
- --btn-border-radius: 50%;
1283
- --btn-icon-bg-color: var(--btn-main);
1284
- --btn-icon-padding: .75rem;
1285
- --btn-icon-size: 1.5rem;
1286
- --btn-icon-stroke-color: var(--bs-white);
1287
- --btn-text-color: var(--bs-ink-base);
1288
- --btn-text-size: var(--bs-text-md);
1289
- align-items: center;
1360
+ /* Disable hover styles */
1361
+ .bs-dropdown-options :where(li[data-no-hover]:hover) {
1290
1362
  background-color: transparent;
1291
- border-radius: var(--btn-border-radius);
1292
- color: var(--btn-text-color);
1363
+ border-left-color: transparent;
1364
+ color: var(--bs-ink-base);
1365
+ cursor: default;
1366
+ }
1367
+ /* Style label to look like other options */
1368
+ .bs-dropdown-options :where(li label) {
1293
1369
  cursor: pointer;
1294
- display: inline-flex;
1295
- font-size: var(--btn-text-size);
1296
- gap: .5rem;
1297
- outline: none;
1298
- position: relative;
1299
- vertical-align: middle;
1370
+ font-size: 1rem;
1371
+ font-weight: 400;
1300
1372
  }
1301
- a.bs-circle-button {
1302
- align-items: center;
1303
- display: inline-flex;
1304
- outline: none;
1305
- text-decoration: none;
1373
+ /* Don't change option color when checkbox is present */
1374
+ .bs-dropdown-options :where(li[data-variant~="checkbox"]):hover,
1375
+ .bs-dropdown-options :where(li[data-variant~="checkbox"][data-selected]) {
1376
+ color: var(--bs-ink-base);
1306
1377
  }
1307
- .bs-circle-button :where(.bs-circle-button-icon)::before {
1308
- border-color: var(--btn-border-color);
1309
- border-radius: var(--btn-border-radius);
1310
- border-style: solid;
1311
- border-width: 0.125rem;
1312
- height: calc(100% + 0.5rem);
1313
- inset: -0.25rem;
1314
- position: absolute;
1315
- transition: border-color 125ms ease-in-out, transform 100ms ease-in-out;
1316
- width: calc(100% + 0.5rem);
1378
+ /* Don't change description color when checkbox is present */
1379
+ .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="2-col"][data-variant~="description"]):hover > :nth-child(3),
1380
+ .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="2-col"][data-variant~="description"][data-selected]) > :nth-child(3),
1381
+ .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="3-col"][data-variant~="description"]):hover > :nth-child(4),
1382
+ .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="3-col"][data-variant~="description"][data-selected]) > :nth-child(4) {
1383
+ color: var(--bs-ink-light);
1317
1384
  }
1318
- .bs-circle-button :where(.bs-circle-button-icon) {
1319
- align-items: center;
1320
- background-color: var(--btn-icon-bg-color);
1321
- border: none;
1322
- border-radius: 50%;
1323
- color: var(--btn-icon-stroke-color);
1324
- display: inline-flex;
1325
- justify-content: center;
1326
- outline: 2px solid transparent;
1327
- padding: var(--btn-icon-padding);
1328
- position: relative;
1329
- transition: all 100ms ease-in-out;
1385
+ /* Overrides mobile style when not min-width 752 */
1386
+ .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options) :where(li) {
1387
+ padding-left: 0.5rem;
1388
+ padding-right: 0.75rem;
1330
1389
  }
1331
- .bs-circle-button :where(.bs-circle-button-icon) :where(.bs-icon) {
1332
- --icon-size: var(--btn-icon-size);
1390
+ .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options) :where(li[role="separator"]) {
1391
+ padding-right: 0.625rem;
1333
1392
  }
1334
- /* non-bs-icon svgs */
1335
- .bs-circle-button :where(.bs-circle-button-icon) > :where(svg) {
1336
- height: var(--btn-icon-size);
1337
- width: var(--btn-icon-size);
1393
+ .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options:focus-visible) :where(li[data-active]) {
1394
+ padding-left: 0.625rem;
1338
1395
  }
1339
- /* Icon Buttons with Text */
1340
- .bs-circle-button:where([data-text]:not([data-text="false"])) {
1341
- --btn-text-size: var(--bs-text-md);
1342
- --btn-icon-size: 0.75rem;
1343
- --btn-icon-padding: 0.375rem;
1396
+ .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options:focus-visible) :where(li[data-selected][data-active]) {
1397
+ padding-left: 0.5rem;
1344
1398
  }
1345
- /* Ghost Buttons */
1346
- .bs-circle-button:where([data-ghost]:not([data-ghost="false"])) {
1347
- --btn-icon-stroke-color: var(--btn-main);
1348
- --btn-light: var(--bs-blue-10);
1349
- --btn-secondary: var(--bs-blue-10);
1399
+ @media (min-width: 752px) {
1400
+ .bs-dropdown-options :where(li) {
1401
+ padding-left: 0.5rem;
1402
+ padding-right: 0.75rem;
1403
+ }
1404
+
1405
+ .bs-dropdown-options :where(li[role="separator"]) {
1406
+ padding-right: 0.625rem;
1407
+ }
1408
+
1409
+ .bs-dropdown-options:where(:focus-visible) :where(li[data-active]) {
1410
+ padding-left: 0.625rem;
1411
+ }
1412
+
1413
+ .bs-dropdown-options:where(:focus-visible) :where(li[data-selected][data-active]) {
1414
+ padding-left: 0.5rem;
1415
+ }
1350
1416
  }
1351
- .bs-circle-button:where([data-ghost]:not([data-ghost="false"])) :where(.bs-circle-button-icon) {
1352
- background-color: transparent;
1353
- box-shadow: inset 0 0 0 1px transparent;
1354
- color: var(--btn-icon-stroke-color);
1417
+ :where(label, legend),
1418
+ label:where(.bs-label) {
1419
+ display: inline-block;
1420
+ width: 100%;
1355
1421
  }
1356
- .bs-circle-button:where([data-ghost]:not([data-ghost="false"])) :where(.bs-circle-button-icon)::before {
1357
- border-radius: 50%;
1422
+ .bs-label,
1423
+ :where(label, legend) {
1424
+ --label-color: var(--bs-ink-base);
1425
+ color: var(--label-color);
1426
+ font-size: var(--bs-text-sm);
1427
+ font-weight: 600;
1428
+ line-height: var(--bs-leading-base);
1358
1429
  }
1359
- /* Active, Hover, Focus states */
1360
- .bs-circle-button:active, .bs-circle-button:hover {
1361
- --btn-icon-bg-color: var(--btn-secondary);
1430
+ /* Required asterisk */
1431
+ :where(label, legend) :where([data-required]:not([data-required="false"])),
1432
+ .bs-label :where([data-required="true"]) {
1433
+ color: var(--label-asterisk-color, var(--bs-ink-red));
1362
1434
  }
1363
- .bs-circle-button:active :where(.bs-circle-button-icon) {
1364
- transform: scale(0.97);
1365
- transform-origin: center;
1366
- box-shadow: inset 0px 0px 4px 1px var(--btn-main);
1435
+ /* Disabled state */
1436
+ :where(label[data-disabled]:not([data-disabled="false"])),
1437
+ :where(label[data-disabled]:not([data-disabled="false"])) *,
1438
+ .bs-label:where([data-disabled="true"]),
1439
+ .bs-label:where([data-disabled="true"]) * {
1440
+ --label-asterisk-color: transparent;
1441
+ --label-color: var(--bs-ink-disabled);
1367
1442
  }
1368
- .bs-circle-button:where([data-direction="right"]):hover :where(.bs-circle-button-icon),
1369
- .bs-circle-button:where([data-direction="right"]):hover::before {
1370
- transform: translateX(.25rem);
1443
+ /* Generally applicable (all input types) */
1444
+ :where([data-required]:not([data-required="false"])) {
1445
+ color: var(--bs-ink-red);
1446
+ font-weight: var(--bs-font-bold, 600);
1371
1447
  }
1372
- .bs-circle-button:where([data-direction="left"]):hover :where(.bs-circle-button-icon),
1373
- .bs-circle-button:where([data-direction="left"]):hover::before {
1374
- transform: translateX(-.25rem);
1448
+ :where([data-disabled]:not([data-disabled="false"]), [data-disabled]:not([data-disabled="false"]) [data-required]:not([data-required="false"])) {
1449
+ color: var(--bs-gray-400);
1375
1450
  }
1376
- .bs-circle-button:where([data-ghost]:not([data-ghost="false"])):hover :where(.bs-circle-button-icon) {
1377
- background-color: var(--btn-light);
1451
+ :where(.box) :is(input, textarea, select):where(:focus-visible),
1452
+ :where(.box) :is(.bs-input, .bs-textarea, .bs-select):where(:focus-visible) {
1453
+ --offset-color: var(--bs-bg-medium);
1378
1454
  }
1379
- .bs-circle-button:where([data-ghost]:not([data-ghost="false"])):active {
1380
- box-shadow:
1381
- inset 0 0 0 1px var(--btn-main),
1382
- inset 0px 0px 4px 1px var(--btn-highlight);
1455
+ :where(.box[data-invert]) :is(input, textarea, select):where(:focus-visible),
1456
+ :where(.box[data-invert]) :is(.bs-input, .bs-textarea, .bs-select):where(:focus-visible) {
1457
+ --offset-color: var(--bs-bg-invert-base);
1383
1458
  }
1384
- .bs-circle-button:where(:focus-visible) {
1385
- --btn-border-color: var(--btn-main);
1459
+ /* Errors and Messages */
1460
+ :is(input, select, textarea):where([data-error]:not([data-error="false"])),
1461
+ :is(.bs-input, .bs-select, .bs-textarea):where([data-error]:not([data-error="false"])) {
1462
+ --input-border: var(--bs-ink-red);
1463
+ }
1464
+ /* Fieldset */
1465
+ :where(fieldset) {
1466
+ border: none;
1467
+ margin-left: 0;
1468
+ margin-right: 0;
1469
+ padding: 0;
1470
+ }
1471
+ :where(fieldset legend) {
1472
+ margin-bottom: 0.25rem;
1473
+ padding: 0;
1386
1474
  }
1387
- .bs-circle-button:where(:focus-visible) :where(.bs-circle-button-icon)::before {
1388
- content: '';
1475
+ :where(label + input, label > input):where(:not([type='checkbox'], [type='radio'])),
1476
+ :where(label + textarea, label > textarea),
1477
+ :where(label + select, label > select) {
1478
+ margin-top: 0.25rem;
1389
1479
  }
1390
- /* Disabled State */
1391
- .bs-circle-button:where(:disabled, [aria-disabled]:not([aria-disabled="false"])) /* for links as buttons */ {
1392
- --btn-icon-stroke-color: var(--bs-ink-disabled);
1393
- --btn-text-color: var(--bs-ink-disabled);
1394
- pointer-events: none;
1480
+ /*
1481
+ Custom properties:
1482
+ --input-bg (background color)
1483
+ --input-border (border color)
1484
+ --input-border-width (border width)
1485
+ --input-caret (caret color)
1486
+ --input-padding-block (padding block)
1487
+ --input-padding-inline (padding inline)
1488
+ --input-placeholder (placeholder color)
1489
+ --input-text-size (font size)
1490
+ */
1491
+ input:where(:not([type='checkbox'], [type='radio'], [type='file'], [type='range'])),
1492
+ textarea,
1493
+ select,
1494
+ :is(.bs-input, .bs-select, .bs-textarea) {
1495
+ -webkit-appearance: none;
1496
+ -moz-appearance: none;
1497
+ appearance: none;
1498
+ background-color: var(--input-bg, var(--bs-bg-base));
1499
+ border-color: var(--input-border, var(--bs-violet-medium));
1500
+ border-radius: 0.25rem;
1501
+ border-style: solid;
1502
+ border-width: var(--input-border-width, 1px);
1503
+ caret-color: var(--input-caret, var(--bs-blue-base));
1504
+ color: var(--bs-ink-base);
1505
+ font-size: var(--input-text-size, var(--bs-text-base));
1506
+ font-weight: 400;
1507
+ height: 2.5rem;
1508
+ line-height: var(--bs-leading-base);
1509
+ padding-block: var(--input-padding-block, 0.0625rem);
1510
+ padding-inline: var(--input-padding-inline, 0.75rem);
1395
1511
  }
1396
- .bs-circle-button:where(:disabled, [aria-disabled]:not([aria-disabled="false"])) :where(.bs-circle-button-icon) {
1397
- background-color: var(--bs-bg-disabled);
1512
+ input:where(:not([type='checkbox'], [type='radio'], [type='file'], [type='range'])),
1513
+ textarea,
1514
+ select {
1515
+ width: 100%;
1398
1516
  }
1399
- /* Button Size */
1400
- .bs-circle-button:where([data-size^='sm']) {
1401
- --btn-icon-padding: .375rem;
1402
- --btn-icon-size: .75rem;
1403
- --btn-text-size: var(--bs-text-sm);
1517
+ input:where([type='text'], [type='email'], [type='url']),
1518
+ select,
1519
+ .bs-input:where([type='text'], [type='email'], [type='url']),
1520
+ .bs-select {
1521
+ text-overflow: ellipsis;
1404
1522
  }
1405
- .bs-circle-button:where([data-size^='sm'][data-text]:not([data-text="false"])) {
1406
- --btn-icon-padding: .3125rem;
1407
- --btn-icon-size: .625rem;
1408
- --btn-text-size: var(--bs-text-base);
1523
+ .bs-textarea,
1524
+ textarea {
1525
+ height: auto;
1526
+ padding-block: 0.5rem;
1527
+ resize: vertical;
1409
1528
  }
1410
- .bs-circle-button:where([data-size='xs'][data-text]:not([data-text="false"])) {
1411
- --btn-icon-padding: .25rem;
1412
- --btn-icon-size: .5rem;
1413
- --btn-text-size: var(--bs-text-sm);
1529
+ :is(input, textarea, select)::-moz-placeholder, :is(.bs-input, .bs-select, .bs-textarea)::-moz-placeholder {
1530
+ color: var(--input-placeholder, var(--bs-violet-lightest));
1414
1531
  }
1415
- /* Parent */
1416
- .bs-dropdown-parent {
1417
- display: inline-block;
1418
- position: relative;
1532
+ :is(input, textarea, select)::placeholder,
1533
+ :is(.bs-input, .bs-select, .bs-textarea)::placeholder {
1534
+ color: var(--input-placeholder, var(--bs-violet-lightest));
1419
1535
  }
1420
- /* Backdrop for mobile bottom sheet */
1421
- .bs-dropdown-backdrop {
1422
- -webkit-backdrop-filter: blur(4px);
1423
- backdrop-filter: blur(4px);
1424
- background: rgba(29, 30, 72, 0.05);
1425
- bottom: 0;
1426
- content: "";
1427
- left: 0;
1428
- position: fixed;
1429
- right: 0;
1430
- top: 0;
1431
- z-index: 998;
1536
+ :is(input, textarea, select):where(:focus-visible)::-moz-placeholder, :is(.bs-input, .bs-select, .bs-textarea):where(:focus-visible)::-moz-placeholder {
1537
+ opacity: 0;
1432
1538
  }
1433
- /* Content */
1434
- .bs-dropdown {
1435
- --dropdown-bottom: 0;
1436
- --dropdown-left: 0;
1437
- --dropdown-right: auto;
1438
- --dropdown-top: auto;
1439
- --dropdown-width: 100%;
1440
- --dropdown-transform: translate(0, 100%);
1441
-
1442
- background-color: var(--bs-bg-base-elevated);
1443
- border-radius: 4px;
1444
- bottom: var(--dropdown-bottom);
1445
- box-shadow: var(--bs-shadow-contentMedium);
1446
- left: var(--dropdown-left);
1447
- line-height: 1.5rem;
1448
- margin: 0;
1539
+ :is(input, textarea, select):where(:focus-visible)::placeholder,
1540
+ :is(.bs-input, .bs-select, .bs-textarea):where(:focus-visible)::placeholder {
1449
1541
  opacity: 0;
1450
- overflow-y: auto;
1451
- position: fixed;
1452
- right: var(--dropdown-right);
1453
- top: var(--dropdown-top);
1454
- transform-origin: center bottom;
1455
- transform: var(--dropdown-transform);
1456
- transition-duration: 75ms;
1457
- transition-property: opacity, transform;
1458
- transition-timing-function: ease-in-out;
1459
- width: var(--dropdown-width);
1460
- z-index: 999;
1461
1542
  }
1462
- /* Mobile Header */
1463
- .bs-dropdown > :where(header) {
1464
- border-bottom: 1px solid var(--bs-border-base);
1465
- display: flex;
1466
- justify-content: space-between;
1467
- padding: 1.5rem;
1543
+ /* FOCUS state */
1544
+ :is(input:where(:not([type='checkbox'], [type='radio'])), textarea, select):where(:focus-visible),
1545
+ :is(.bs-input, .bs-select, .bs-textarea):where(:focus-visible) {
1546
+ --input-border: var(--bs-blue-base);
1547
+ outline-style: none;
1548
+ outline-width: 0px;
1468
1549
  }
1469
- .bs-dropdown > :where(header) :where(h3) {
1470
- font-size: 1.25rem;
1550
+ /* HOVER state */
1551
+ :is(input:where(:not([type='checkbox'], [type='radio'])), textarea, select):where(:hover),
1552
+ :is(.bs-input, .bs-select, .bs-textarea):where(:hover) {
1553
+ --input-bg: var(--bs-bg-input-hover);
1471
1554
  }
1472
- .bs-dropdown > :where(header) :where(p) {
1473
- font-size: 1rem;
1555
+ /* DISABLED state */
1556
+ :is(input:where(:not([type='checkbox'],[type='radio'])), textarea, select):where(:disabled),
1557
+ :is(.bs-input, .bs-select, .bs-textarea):where(:disabled) {
1558
+ --input-border: var(--bs-ink-disabled);
1559
+ --input-bg: var(--bs-bg-disabled);
1560
+ color: var(--bs-ink-disabled);
1474
1561
  }
1475
- .bs-dropdown > :where(header) :where(button) {
1476
- cursor: pointer;
1477
- height: 1rem;
1478
- width: 1rem;
1562
+ /* Errors and Messages */
1563
+ :is(input, select, textarea):where([data-error]:not([data-error="false"])),
1564
+ :is(.bs-input, .bs-select, .bs-textarea):where([data-error="true"]) {
1565
+ --input-border: var(--bs-ink-red);
1479
1566
  }
1480
- /* data-shown */
1481
- .bs-dropdown:where([data-shown]:not([data-shown="false"])) {
1482
- --dropdown-transform: translate(0, 0);
1567
+ /*
1568
+ Removes the built-in 'margin' on bottom of textarea
1569
+ see https://bugs.chromium.org/p/chromium/issues/detail?id=89530
1570
+ */
1571
+ :has(> textarea:only-child),
1572
+ :has(> .bs-textarea:only-child) {
1573
+ display: block;
1574
+ line-height: 0;
1575
+ }
1576
+ /* chrome user agent styling was applying opacity: 0.7 */
1577
+ :where(select:disabled) {
1483
1578
  opacity: 1;
1484
1579
  }
1485
- /* Sizing */
1486
- .bs-dropdown:where([data-width="sm"]) {
1487
- --dropdown-wscreen-width: 10rem;
1580
+ :is(input, textarea, select):disabled::-moz-placeholder, :is(input, textarea, select)[disabled]::-moz-placeholder, :is(.bs-input, .bs-textarea, .bs-select):disabled::-moz-placeholder, :is(.bs-input, .bs-textarea, .bs-select)[disabled]::-moz-placeholder {
1581
+ opacity: 0;
1488
1582
  }
1489
- .bs-dropdown:where([data-width="md"]),
1490
- .bs-dropdown:where(:not([data-width])) {
1491
- --dropdown-wscreen-width: 20rem;
1583
+ :is(input, textarea, select):disabled::placeholder,
1584
+ :is(input, textarea, select)[disabled]::placeholder,
1585
+ :is(.bs-input, .bs-textarea, .bs-select):disabled::placeholder,
1586
+ :is(.bs-input, .bs-textarea, .bs-select)[disabled]::placeholder {
1587
+ opacity: 0;
1492
1588
  }
1493
- .bs-dropdown:where([data-width="lg"]) {
1494
- --dropdown-wscreen-width: 40rem;
1589
+ /* Select */
1590
+ select,
1591
+ .bs-select {
1592
+ /* URL Encoded SVG dropdown caret so there is something there */
1593
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%230A0B19' d='M8.048 13.375a.745.745 0 0 1-.526-.217L0 5.686l1.053-1.061 6.995 6.95 6.897-6.85 1.053 1.06-7.423 7.373a.745.745 0 0 1-.527.217Z'/%3E%3C/svg%3E");
1594
+ background-position: right 0.75rem center;
1595
+ background-repeat: no-repeat;
1596
+ background-size: 1em 1em;
1597
+ padding-right: var(--bs-space-9);
1495
1598
  }
1496
- .bs-dropdown:where([data-width="content"]) {
1497
- --dropdown-wscreen-width: max-content;
1599
+ .dark select,
1600
+ .dark .bs-select {
1601
+ /* URL Encoded SVG dropdown caret so there is something there */
1602
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%23ffffff' d='M8.048 13.375a.745.745 0 0 1-.526-.217L0 5.686l1.053-1.061 6.995 6.95 6.897-6.85 1.053 1.06-7.423 7.373a.745.745 0 0 1-.527.217Z'/%3E%3C/svg%3E");
1498
1603
  }
1499
- .bs-dropdown-parent:where([data-width="toggle"]) :where(.bs-dropdown),
1500
- .bs-dropdown-parent:where([data-width="anchor"]) :where(.bs-dropdown) {
1501
- --dropdown-wscreen-width: 100%;
1604
+ .dark select:disabled,
1605
+ .dark .bs-select:disabled {
1606
+ /* URL Encoded SVG dropdown caret so there is something there */
1607
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%23555775' d='M8.048 13.375a.745.745 0 0 1-.526-.217L0 5.686l1.053-1.061 6.995 6.95 6.897-6.85 1.053 1.06-7.423 7.373a.745.745 0 0 1-.527.217Z'/%3E%3C/svg%3E");
1502
1608
  }
1503
- /* data-top */
1504
- .bs-dropdown:where([data-top]:not([data-top="false"])) {
1505
- --dropdown-wscreen-bottom: calc(100% + 0.5rem);
1506
- --dropdown-wscreen-top: auto;
1609
+ /* 0 0 1 for width to allow e.g. tailwind override */
1610
+ :is(div, *):where(.bs-input-addon) {
1611
+ width: 100%;
1507
1612
  }
1508
- /* data-center */
1509
- .bs-dropdown-parent:where([data-center]:not([data-center="false"])) :where(.bs-dropdown) {
1510
- --dropdown-transform: translate(-50%, 0);
1511
- --dropdown-wscreen-left: 50%;
1613
+ .bs-input-addon {
1614
+ --input-border: var(--bs-violet-300);
1615
+ align-items: center;
1616
+ background-color: var(--input-bg, var(--bs-bg-base));
1617
+ border-radius: .25rem;
1618
+ color: var(--bs-ink-base);
1619
+ display: flex;
1620
+ height: var(--input-addon-height, 2.5rem);
1621
+ overflow: hidden;
1622
+ padding: 0;
1623
+ pointer-events: none;
1624
+ position: relative;
1512
1625
  }
1513
- /* Overrides mobile style when not min-width 752 */
1514
- .bs-dropdown:where([data-no-mobile="true"]) {
1515
- --dropdown-bottom: var(--dropdown-wscreen-bottom, auto);
1516
- --dropdown-left: var(--dropdown-wscreen-left, initial);
1517
- --dropdown-right: var(--dropdown-wscreen-right, initial);
1518
- --dropdown-top: var(--dropdown-wscreen-top, calc(100% + 0.5rem));
1519
- --dropdown-width: var(--dropdown-wscreen-width, initial);
1520
- --dropdown-transform: initial;
1521
-
1626
+ .bs-input-addon * {
1627
+ background-color: transparent;
1628
+ }
1629
+ /**
1630
+ Implement an outer 'border' via pseudo-element instead of
1631
+ on main element to avoid content shifting, double-stroke effect,
1632
+ and issues with box-sizing
1633
+ */
1634
+ .bs-input-addon::after,
1635
+ .bs-input-addon::before,
1636
+ .bs-input-addon ::after,
1637
+ .bs-input-addon ::before {
1638
+ pointer-events: none;
1639
+ }
1640
+ .bs-input-addon::after,
1641
+ .bs-input-addon::before {
1642
+ content: '';
1643
+ height: 100%;
1644
+ left: 0;
1522
1645
  position: absolute;
1646
+ top: 0;
1647
+ width: 100%;
1523
1648
  }
1524
- .bs-dropdown:where([data-no-mobile="true"]) > :where(header) {
1525
- display: none;
1649
+ .bs-input-addon::after {
1650
+ border-radius: .25rem;
1651
+ border: 1px solid var(--input-border);
1526
1652
  }
1527
- @media (min-width: 752px) {
1528
- .bs-dropdown-backdrop {
1529
- display: none;
1530
- }
1531
-
1532
- .bs-dropdown {
1533
- --dropdown-bottom: var(--dropdown-wscreen-bottom, auto);
1534
- --dropdown-left: var(--dropdown-wscreen-left, initial);
1535
- --dropdown-right: var(--dropdown-wscreen-right, initial);
1536
- --dropdown-top: var(--dropdown-wscreen-top, calc(100% + 0.5rem));
1537
- --dropdown-width: var(--dropdown-wscreen-width, initial);
1538
- --dropdown-transform: initial;
1539
-
1540
- position: absolute;
1541
- }
1542
-
1543
- /* Hide the header */
1544
- .bs-dropdown > :where(header) {
1545
- display: none;
1546
- }
1653
+ .bs-input-addon :where(.bs-input-addon)::after {
1654
+ border: 1px solid var(--input-addon-nested-border);
1547
1655
  }
1548
- /* Option list */
1549
- .bs-dropdown-options {
1550
- display: flex;
1551
- flex-direction: column;
1552
- gap: 0.5rem;
1553
- list-style: none;
1554
- margin-bottom: 0.25rem;
1555
- margin-top: 0.25rem;
1556
- max-height: var(--options-height-max, 20rem);/* constrain scrollable to options section */
1557
- overflow-y: auto;
1558
- padding-block: 0.5rem;
1559
- padding-left: 0;
1656
+ .bs-input-addon > * {
1657
+ flex-grow: 0;
1658
+ flex-shrink: 0;
1560
1659
  position: relative;
1561
1660
  }
1562
- .bs-dropdown-options:focus-visible {
1563
- outline: none;
1661
+ .bs-input-addon > :where([data-part="main"], .bs-input-addon, bs-input, .bs-input),
1662
+ .bs-input-addon > :where([data-autowidth]:not([data-autowidth="false"]), .bs-input-addon, bs-input, .bs-input) {
1663
+ flex-grow: 1;
1664
+ flex-shrink: 1;
1564
1665
  }
1565
- /* Stabilize scrollbar gutter for Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=764076) */
1566
- @media (min-width: 752px) {
1567
- /* 5th or 8th child triggers overflow-y (depending on variant) */
1568
- :where([data-width="content"]) > .bs-dropdown-options:where(:has([data-variant*="description"]:nth-child(5))),
1569
- :where([data-width="content"]) > .bs-dropdown-options:where(:has(li:not([data-variant*="description"]):nth-child(8))) {
1570
- scrollbar-gutter: stable;
1571
- }
1572
-
1573
- /* Fallback for older Firefox+ only if we're not setting data-overflow values */
1574
- @supports not selector(:has(*)) {
1575
- :where([data-width="content"]) > .bs-dropdown-options {
1576
- scrollbar-gutter: stable;
1577
- }
1578
- }
1579
-
1580
- /* Also allow this for js solutions if :has not available via data-overflow */
1581
- /* Reset scrollbar gutter when data-overflow is used */
1582
- :where([data-width="content"]) > .bs-dropdown-options:where([data-overflow]) {
1583
- scrollbar-gutter: auto;
1584
- }
1585
-
1586
- :where([data-width="content"]) > .bs-dropdown-options:where([data-overflow="true"]) {
1587
- scrollbar-gutter: stable;
1588
- }
1666
+ .bs-input-addon > :where([data-part="main"]) > :where(input, select),
1667
+ .bs-input-addon > :where([data-autowidth]:not([data-autowidth="false"])) > :where(input, select) {
1668
+ width: 100%;
1589
1669
  }
1590
- /* Option list item */
1591
- .bs-dropdown-options :where(li) {
1670
+ .bs-input-addon > *:where(:not(.bs-input-addon)) {
1592
1671
  align-items: center;
1593
- border-bottom: 2px solid transparent;
1594
- border-left: 4px solid transparent;
1595
- border-radius: 3px;
1596
- border-right: 2px solid transparent;
1597
- border-top: 2px solid transparent;
1598
- color: var(--bs-ink-base);
1599
- -moz-column-gap: 0.5rem;
1600
- column-gap: 0.5rem;
1601
- cursor: pointer;
1602
- display: grid;
1603
- padding-block: 0.25rem;
1604
- padding-inline: 1.25rem;
1605
- row-gap: 0.125rem;
1606
- word-break: break-word;
1607
- word-wrap: break-word;
1608
- }
1609
- /* Variant: 2-col */
1610
- .bs-dropdown-options :where(li[data-variant~="2-col"]) {
1611
- grid-template-columns: min-content 1fr;
1672
+ border-width: 0px;
1673
+ display: flex;
1674
+ height: 100%;
1675
+ overflow: hidden;
1676
+ pointer-events: auto;
1612
1677
  }
1613
- /* Variant: 3-col */
1614
- .bs-dropdown-options :where(li[data-variant~="3-col"]) {
1615
- grid-template-columns: min-content min-content 1fr;
1678
+ /* Remove (hide) children's borders, outlines */
1679
+ .bs-input-addon > *,
1680
+ .bs-input-addon :where(input, select),
1681
+ .bs-input-addon :is(bs-input, bs-select) :where(input, select),
1682
+ .bs-input-addon :is(input, select):where(.bs-input, .bs-select),
1683
+ .bs-input-addon :where(.bs-input-addon) {
1684
+ --input-border: transparent;
1685
+ --input-border-width: 0px;
1616
1686
  }
1617
- /* Variant: description */
1618
- .bs-dropdown-options :where(li:not([data-variant*="-col"])[data-variant~="description"] > :nth-child(2)),
1619
- .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"] > :nth-child(3)),
1620
- .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"] > :nth-child(4)) {
1621
- color: var(--bs-ink-light);
1622
- font-size: var(--bs-text-xs);
1623
- min-height: 1.125rem;
1624
- line-height: 1.125rem;
1687
+ .bs-input-addon {
1688
+ --input-addon-nested-border: transparent;
1625
1689
  }
1626
- /* Variant: 2-col description */
1627
- .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"] > :nth-child(3)) {
1628
- grid-column-start: 2;
1690
+ .bs-input-addon :where(:focus-within) :where(input, select, button),
1691
+ .bs-input-addon :where(:focus-within) :is(bs-input, bs-select) :where(input, select),
1692
+ .bs-input-addon :where(:focus-within) :is(input, select, button):where(.bs-input, .bs-select),
1693
+ .bs-input-addon :where(input, select, button):where(:focus, :focus-within, :focus-visible),
1694
+ .bs-input-addon :is(input, select):where(.bs-input, .bs-select):where(:focus, :focus-within, :focus-visible),
1695
+ .bs-input-addon :is(bs-input, bs-select) :where(input, select):where(:focus, :focus-within, :focus-visible) {
1696
+ --input-border: transparent;
1697
+ box-shadow: none;
1698
+ outline: none;
1629
1699
  }
1630
- /* Variant: 3-col description */
1631
- .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"] > :nth-child(4)) {
1632
- grid-column-start: 3;
1700
+ /* -------- Inner-bordered styles -------- */
1701
+ /** Inner borders should be straight; shown only if variant: "inner-bordered" */
1702
+ .bs-input-addon:where([data-variant="inner-bordered"]) {
1703
+ --input-addon-nested-border: var(--bs-violet-lightest);
1633
1704
  }
1634
- /* Hover or data-selected */
1635
- .bs-dropdown-options :where(li:not([role="separator"]):hover),
1636
- .bs-dropdown-options :where(li[data-selected]) {
1637
- background-color: var(--bs-bg-medium);
1638
- border-left: 4px solid var(--bs-blue-base);
1639
- color: var(--bs-blue-base);
1640
- outline: none;
1705
+ .bs-input-addon > :where(.bs-input-addon:not(:last-child, :focus-within, [data-part="right"])),
1706
+ .bs-input-addon > :where(:not(:last-child, :focus-within, [data-part="right"]))::after {
1707
+ border-top-right-radius: 0;
1708
+ border-bottom-right-radius: 0;
1641
1709
  }
1642
- /* Variant: negative */
1643
- .bs-dropdown-options :where(li[data-variant~="negative"]:hover),
1644
- .bs-dropdown-options :where(li[data-variant~="negative"][data-selected]),
1645
- .bs-dropdown-options :where(li[data-variant~="negative"][data-selected]:hover) {
1646
- /* 25% alpha version of --bs-red-400 */
1647
- background-color: rgba(248, 169, 170, 0.25);
1648
- border-left: 4px solid var(--bs-red-500);
1649
- color: var(--bs-red-500);
1710
+ .bs-input-addon > :where(.bs-input-addon:not(:first-child, :focus-within, [data-part="left"])),
1711
+ .bs-input-addon > :where(:not(:first-child, :focus-within, [data-part="left"]))::after {
1712
+ border-top-left-radius: 0;
1713
+ border-bottom-left-radius: 0;
1650
1714
  }
1651
- /* Hover or data-selected for 2-col/3-col/description variants */
1652
- .bs-dropdown-options :where(li:not([data-variant*="-col"])[data-variant~="description"]:hover > :nth-child(2)),
1653
- .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"]:hover > :nth-child(3)),
1654
- .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"]:hover > :nth-child(4)),
1655
- .bs-dropdown-options :where(li:not([data-variant*="-col"])[data-variant~="description"][data-selected] > :nth-child(2)),
1656
- .bs-dropdown-options :where(li[data-variant~="2-col"][data-variant~="description"][data-selected] > :nth-child(3)),
1657
- .bs-dropdown-options :where(li[data-variant~="3-col"][data-variant~="description"][data-selected] > :nth-child(4)) {
1658
- color: var(--bs-blue-base);
1715
+ .bs-input-addon:where([data-variant="inner-bordered"]) > :where(:not(:focus, :focus-within))::after {
1716
+ border-left-width: 0px;
1717
+ border-right-width: 1px;
1718
+ border-right-color: var(--input-addon-nested-border);
1659
1719
  }
1660
- /* Hover or data-selected for negative + 2-col/3-col/description variants */
1661
- .bs-dropdown-options :where(li[data-variant~="negative"]:not([data-variant*="-col"])[data-variant~="description"]:hover > :nth-child(2)),
1662
- .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="2-col"][data-variant~="description"]:hover > :nth-child(3)),
1663
- .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="3-col"][data-variant~="description"]:hover > :nth-child(4)),
1664
- .bs-dropdown-options :where(li[data-variant~="negative"]:not([data-variant*="-col"])[data-variant~="description"][data-selected] > :nth-child(2)),
1665
- .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="2-col"][data-variant~="description"][data-selected] > :nth-child(3)),
1666
- .bs-dropdown-options :where(li[data-variant~="negative"][data-variant~="3-col"][data-variant~="description"][data-selected] > :nth-child(4)) {
1667
- color: var(--bs-red-500);
1720
+ .bs-input-addon:where([data-variant="inner-bordered"]) > :where(:not(.bs-input-addon, :focus, :focus-within))::after {
1721
+ content: '';
1722
+ height: 100%;
1723
+ left: 0;
1724
+ position: absolute;
1725
+ top: 0;
1726
+ width: 100%;
1668
1727
  }
1669
- /* List option keyboard navigation focus */
1670
- .bs-dropdown-options:where(:focus-visible) :where(li[data-active]) {
1671
- --focus-border-color: var(--bs-blue-base);
1672
- border: 2px solid var(--focus-border-color);
1673
- outline: none;
1674
- padding-left: 1.375rem;
1728
+ .bs-input-addon:where([data-variant="inner-bordered"]) > :where(.bs-input-addon)::after {
1729
+ border-radius: 0px;
1675
1730
  }
1676
- /* Navigation focus on a selected element should preserve 4px left border */
1677
- .bs-dropdown-options:where(:focus-visible) :where(li[data-selected][data-active]) {
1678
- border-left: 4px solid var(--focus-border-color);
1679
- padding-left: 1.25rem;
1731
+ /* -------- Auto Padding for Children, Auto Sizing Icons -------- */
1732
+ /* Opt in for now, for backwards compatibility */
1733
+ .bs-input-addon:where([data-autopad="true"], [data-variant="combobox"]) > *:where(:not(.bs-input-addon)) {
1734
+ padding-inline: 0;
1680
1735
  }
1681
- /* data-variant="negative" list option keyboard navigation focus */
1682
- .bs-dropdown-options:where(:focus-visible) :where(li[data-variant~="negative"][data-active]) {
1683
- --focus-border-color: var(--bs-red-200);
1736
+ .bs-input-addon:where([data-autopad="true"], [data-variant="combobox"]) > :where([data-part="left"]:not(.bs-input-addon)),
1737
+ .bs-input-addon:where([data-autopad="true"], [data-variant="combobox"]) > :where(:first-child:not(.bs-input-addon)) {
1738
+ padding-inline: 0.75rem 0.5rem;
1684
1739
  }
1685
- /* Multi-select divider */
1686
- .bs-dropdown-options :where(li[role="separator"]) {
1687
- cursor: default;
1688
- padding-block: 0.125rem;
1689
- padding-right: 1.375rem;
1740
+ .bs-input-addon:where([data-autopad="true"], [data-variant="combobox"]) > :where([data-part="right"]:not(.bs-input-addon)),
1741
+ .bs-input-addon:where([data-autopad="true"], [data-variant="combobox"]) > :where(:last-child:not(.bs-input-addon)) {
1742
+ padding-inline: 0.5rem 0.75rem;
1690
1743
  }
1691
- /* Multi-select divider line */
1692
- .bs-dropdown-options :where(hr) {
1693
- background-color: var(--bs-navy-light);
1694
- height: .0625rem;
1695
- margin-block: 0;
1696
- margin-inline: 0;
1744
+ .bs-input-addon:where([data-autopad="true"][data-multifocus]) > *:where(:not(.bs-input-addon)) {
1745
+ padding-inline: 0.75rem;
1697
1746
  }
1698
- /* Disable hover styles */
1699
- .bs-dropdown-options :where(li[data-no-hover]:hover) {
1700
- background-color: transparent;
1701
- border-left-color: transparent;
1702
- color: var(--bs-ink-base);
1703
- cursor: default;
1747
+ .bs-input-addon:where([data-autosize-icons="true"], [data-variant="combobox"]) > :where(:not([data-autowidth], [data-part="main"], .bs-input-addon)) {
1748
+ height: 100%;
1749
+ min-width: -moz-min-content;
1750
+ min-width: min-content;
1704
1751
  }
1705
- /* Style label to look like other options */
1706
- .bs-dropdown-options :where(li label) {
1707
- cursor: pointer;
1708
- font-size: 1rem;
1709
- font-weight: 400;
1752
+ .bs-input-addon:where([data-autosize-icons="true"], [data-variant="combobox"]) :where(svg) {
1753
+ height: auto;
1754
+ max-height: 100%;
1755
+ width: 1rem;
1710
1756
  }
1711
- /* Don't change option color when checkbox is present */
1712
- .bs-dropdown-options :where(li[data-variant~="checkbox"]):hover,
1713
- .bs-dropdown-options :where(li[data-variant~="checkbox"][data-selected]) {
1714
- color: var(--bs-ink-base);
1757
+ /* -------- Hover styles -------- */
1758
+ .bs-input-addon:hover {
1759
+ --input-bg: var(--bs-bg-input-hover);
1715
1760
  }
1716
- /* Don't change description color when checkbox is present */
1717
- .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="2-col"][data-variant~="description"]):hover > :nth-child(3),
1718
- .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="2-col"][data-variant~="description"][data-selected]) > :nth-child(3),
1719
- .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="3-col"][data-variant~="description"]):hover > :nth-child(4),
1720
- .bs-dropdown-options :where(li[data-variant~="checkbox"][data-variant~="3-col"][data-variant~="description"][data-selected]) > :nth-child(4) {
1721
- color: var(--bs-ink-light);
1761
+ /* -------- Focus styles -------- */
1762
+ .bs-input-addon {
1763
+ --focus-border: var(--bs-blue-base);
1722
1764
  }
1723
- /* Overrides mobile style when not min-width 752 */
1724
- .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options) :where(li) {
1725
- padding-left: 0.5rem;
1726
- padding-right: 0.75rem;
1765
+ .bs-input-addon:where(:not([data-multifocus]):focus-within),
1766
+ .bs-input-addon:where([data-multifocus="false"]:focus-within),
1767
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :where(input, select):where(:focus, :focus-within, :focus-visible),
1768
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :is(input, select):where(.bs-input, .bs-select):where(:focus, :focus-within, :focus-visible),
1769
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :is(bs-input, bs-select) :where(input, select):where(:focus, :focus-within, :focus-visible) {
1770
+ --input-border: var(--focus-border);
1771
+ position: relative;
1772
+ z-index: 1;
1727
1773
  }
1728
- .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options) :where(li[role="separator"]) {
1729
- padding-right: 0.625rem;
1774
+ .bs-input-addon :where(.bs-input-addon:focus-within) {
1775
+ --input-addon-nested-border: var(--focus-border);
1776
+ z-index: 1;
1730
1777
  }
1731
- .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options:focus-visible) :where(li[data-active]) {
1732
- padding-left: 0.625rem;
1778
+ .bs-input-addon :where(.bs-input-addon:focus-within)::after {
1779
+ z-index: 1;
1733
1780
  }
1734
- .bs-dropdown:where([data-no-mobile="true"]) :where(.bs-dropdown-options:focus-visible) :where(li[data-selected][data-active]) {
1735
- padding-left: 0.5rem;
1781
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :where(:not(.bs-input-addon)) > :is(input, select, button):where(:focus),
1782
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :is(input, select):where(.bs-input, .bs-select):where(:focus),
1783
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :is(bs-input, bs-select) :where(input:focus, select:focus),
1784
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :where(input:focus, select:focus, button:focus) {
1785
+ border-radius: .25rem;
1786
+ box-shadow: var(--focus-border) 0px 0px 0px 1px inset;
1787
+ z-index: 1;
1736
1788
  }
1737
- @media (min-width: 752px) {
1738
- .bs-dropdown-options :where(li) {
1739
- padding-left: 0.5rem;
1740
- padding-right: 0.75rem;
1741
- }
1742
-
1743
- .bs-dropdown-options :where(li[role="separator"]) {
1744
- padding-right: 0.625rem;
1745
- }
1746
-
1747
- .bs-dropdown-options:where(:focus-visible) :where(li[data-active]) {
1748
- padding-left: 0.625rem;
1749
- }
1750
-
1751
- .bs-dropdown-options:where(:focus-visible) :where(li[data-selected][data-active]) {
1752
- padding-left: 0.5rem;
1753
- }
1789
+ .bs-input-addon:where(:not([data-multifocus]):focus-within)::after,
1790
+ .bs-input-addon:where([data-multifocus="false"]:focus-within)::after {
1791
+ border-width: 1px;
1792
+ border-radius: .25rem;
1754
1793
  }
1755
- /*
1756
- custom properties:
1757
- --filterbtn-caret-size
1758
- --filterbtn-caret-transform
1759
- --filterbtn-color
1760
- --filterbtn-focus-color
1761
- --filterbtn-height
1762
- --filterbtn-text-size
1763
- --filterbtn-weight
1764
- */
1765
- button:where(.bs-filter-button) {
1766
- flex-shrink: 0;
1767
- position: relative;
1794
+ .bs-input-addon:where(:focus-within) :where(:not(:focus, :focus-within))::after,
1795
+ .bs-input-addon:where(:focus-within) :where(:not(:focus, :focus-within)) {
1796
+ border-color: transparent;
1768
1797
  }
1769
- .bs-filter-button {
1770
- align-items: center;
1771
- color: var(--filterbtn-color, var(--bs-ink-blue));
1772
- -moz-column-gap: 0.5rem;
1773
- column-gap: 0.5rem;
1774
- cursor: pointer;
1775
- display: inline-flex;
1776
- font-size: var(--filterbtn-text-size, var(--bs-text-base));
1777
- font-weight: var(--filterbtn-weight, 400);
1778
- height: var(--filterbtn-height, 1.5rem);
1779
- line-height: 1.5;
1780
- transition: outline-color 100ms ease-in-out;
1781
- width: -moz-max-content;
1782
- width: max-content;
1798
+ /* Straight-lined ::before border to fill the gap below the rounded ::after border */
1799
+ .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :where(:focus-within)::before {
1800
+ border-bottom-width: 1px;
1801
+ border-color: var(--bs-violet-300);
1802
+ border-radius: 0;
1803
+ border-top-width: 1px;
1804
+ z-index: 1;
1783
1805
  }
1784
- .bs-filter-button::after {
1785
- border: solid var(--filterbtn-focus-color, transparent) 2px;
1786
- border-radius: 0.25rem;
1787
- content: '';
1788
- display: block;
1789
- height: 100%;
1790
- position: absolute;
1791
- transform: scale(1.25);
1792
- width: 100%;
1806
+ /* -------- Disabled styles -------- */
1807
+ .bs-input-addon:where([data-disabled]:not([data-disabled="false"])),
1808
+ .bs-input-addon:where([data-disabled]:not([data-disabled="false"])) .bs-button {
1809
+ --input-bg: var(--bs-bg-disabled);
1810
+ --input-border: var(--bs-ink-disabled);
1811
+ --input-addon-nested-border: var(--bs-ink-disabled);
1812
+ color: var(--bs-ink-disabled);
1793
1813
  }
1794
- .bs-filter-button :where(.bs-icon),
1795
- .bs-filter-button :where(span:has(svg:only-child)) {
1796
- display: block;
1797
- height: var(--filterbtn-caret-size, 1rem);
1798
- line-height: 1;
1799
- transform: var(--filterbtn-caret-transform, rotate(0deg));
1800
- transform-origin: center;
1801
- transition: var(--bs-trans-rotate180);
1802
- width: var(--filterbtn-caret-size, 1rem);
1814
+ .bs-input-addon:where([data-disabled]:not([data-disabled="false"])) * {
1815
+ pointer-events: none;
1803
1816
  }
1804
- .bs-filter-button:where([data-size="sm"],[data-size="xs"]) {
1805
-
1806
- --filterbtn-text-size: var(--bs-text-sm);
1807
- --filterbtn-caret-size: .75rem;
1817
+ /* -------- Error styles -------- */
1818
+ .bs-input-addon:where([data-error]:not([data-error="false"])),
1819
+ .bs-input-addon:where([data-error]:not([data-error="false"])) :where(.bs-input-addon) {
1820
+ --focus-border: var(--bs-ink-red);
1821
+ --input-border: var(--bs-ink-red);
1808
1822
  }
1809
- .bs-filter-button:where([data-size="sm"]) {
1810
- --filterbtn-text-size: var(--bs-text-sm);
1823
+ .bs-input-addon:where([data-error]:not([data-error="false"]),[data-disabled]:not([data-disabled="false"])) > *::before,
1824
+ .bs-input-addon:where(.bs-input-addon[data-error]:not([data-error="false"]) .bs-input-addon, .bs-input-addon[data-disabled]:not([data-disabled="false"]) .bs-input-addon) > *::before {
1825
+ border-color: var(--input-border);
1811
1826
  }
1812
- .bs-filter-button:where([data-size="xs"]) {
1813
- --filterbtn-text-size: var(--bs-text-xs);
1814
- --filterbtn-weight: 600;
1827
+ /* -------- Label margin -------- */
1828
+ :where(label, .bs-label, bs-label) + .bs-input-addon {
1829
+ margin-top: 0.25rem;
1815
1830
  }
1816
- /* Hover state */
1817
- .bs-filter-button:hover {
1818
- --filterbtn-color: var(--bs-blue-base);
1831
+ /* ----------------- Variant: Combobox Input ----------------- */
1832
+ /*
1833
+ Combobox variant also shares styles with data-autopad="true" &
1834
+ data-autosize-icons="true" - see above
1835
+ */
1836
+ .bs-input-addon:where([data-variant="combobox"]) {
1837
+ --input-addon-nested-border: transparent;
1819
1838
  }
1820
- /* Focus state */
1821
- .bs-filter-button:where(:focus-visible) {
1822
- outline: none;
1823
- --filterbtn-focus-color: var(--bs-blue-base);
1839
+ .bs-input-addon:where([data-variant="combobox"]) :where(button svg) {
1840
+ transform: var(--icon-btn-transform, none);
1841
+ transition: var(--bs-trans-rotate180);
1824
1842
  }
1825
- /* Filter open state */
1826
- .bs-filter-button:where([aria-expanded="true"],[data-open="true"]) {
1827
- --filterbtn-caret-transform: rotate(180deg);
1843
+ .bs-input-addon:where([data-variant="combobox"]) :where(button[data-open="true"]) {
1844
+ --icon-btn-transform: rotate(180deg);
1828
1845
  }
1829
- /* Badge non-standard color */
1830
- .bs-filter-button :where(.bs-badge) {
1831
- --badge-bg: var(--bs-ink-blue);
1846
+ .bs-input-addon:where([data-variant="combobox"][data-disabled="true"]) > :where(button) {
1847
+ opacity: 0;
1832
1848
  }
1833
- :where(.dark) .bs-filter-button :where(.bs-badge) {
1834
- --badge-bg: var(--bs-blue-medium);
1849
+ .bs-input-addon:where([data-variant="combobox"]) > :where(button) {
1850
+ border-radius: .25rem;
1851
+ outline: 1px solid transparent;
1835
1852
  }
1836
- .bs-filter-button:hover :where(.bs-badge) {
1837
- --badge-bg: var(--filterbtn-color);
1853
+ .bs-input-addon:where([data-variant="combobox"]) > :where(button:focus-visible:not([data-open])) {
1854
+ outline: 1px solid var(--focus-border);
1838
1855
  }
1839
- /* Disabled state */
1840
- .bs-filter-button:where(:disabled) {
1841
- --filterbtn-color: var(--bs-ink-disabled);
1842
- cursor: default;
1856
+ .bs-input-phone :where(.bs-input-addon) > button {
1857
+ align-items: center;
1858
+ -moz-column-gap: .5rem;
1859
+ column-gap: .5rem;
1860
+ cursor: pointer;
1861
+ display: grid;
1862
+ grid-template-columns: 1.25rem auto .75rem;
1863
+ min-width: 6rem;
1864
+ padding: 0 1rem;
1843
1865
  }
1844
- .bs-filter-button:where(:disabled) :where(.bs-badge) {
1845
- --badge-bg: var(--bs-bg-disabled);
1846
- --badge-text: var(--bs-ink-disabled);
1866
+ .bs-input-phone ul:where(.bs-dropdown-options) {
1867
+ min-width: 7.5rem;
1847
1868
  }
1848
- :where(label, legend),
1849
- label:where(.bs-label) {
1869
+ :where(.bs-input-search) {
1850
1870
  display: inline-block;
1851
1871
  width: 100%;
1852
1872
  }
1853
- .bs-label,
1854
- :where(label, legend) {
1855
- --label-color: var(--bs-ink-base);
1856
- color: var(--label-color);
1857
- font-size: var(--bs-text-sm);
1858
- font-weight: 600;
1859
- line-height: var(--bs-leading-base);
1860
- }
1861
- /* Required asterisk */
1862
- :where(label, legend) :where([data-required]:not([data-required="false"])),
1863
- .bs-label :where([data-required="true"]) {
1864
- color: var(--label-asterisk-color, var(--bs-ink-red));
1873
+ .bs-input-search :where(.bs-icon svg) {
1874
+ box-sizing: content-box;
1865
1875
  }
1866
- /* Disabled state */
1867
- :where(label[data-disabled]:not([data-disabled="false"])),
1868
- :where(label[data-disabled]:not([data-disabled="false"])) *,
1869
- .bs-label:where([data-disabled="true"]),
1870
- .bs-label:where([data-disabled="true"]) * {
1871
- --label-asterisk-color: transparent;
1872
- --label-color: var(--bs-ink-disabled);
1876
+ .bs-input-search :where([data-component="bs-icon-search"]) {
1877
+ --icon-size: var(--search-icon-size, 1.75rem);
1878
+ padding: var(--search-icon-padding, 0 0 0 .75rem);
1873
1879
  }
1874
- /* Generally applicable (all input types) */
1875
- :where([data-required]:not([data-required="false"])) {
1876
- color: var(--bs-ink-red);
1877
- font-weight: var(--bs-font-bold, 600);
1880
+ /* Clear Button */
1881
+ .bs-input-search button {
1882
+ align-items: center;
1883
+ background-color: transparent;
1884
+ cursor: pointer;
1885
+ display: flex;
1886
+ height: 100%;
1887
+ padding-left: 0.75rem;
1888
+ padding-right: 0.75rem;
1889
+ transition: transform 100ms ease-in-out;
1878
1890
  }
1879
- :where([data-disabled]:not([data-disabled="false"]), [data-disabled]:not([data-disabled="false"]) [data-required]:not([data-required="false"])) {
1880
- color: var(--bs-gray-400);
1891
+ .bs-input-search button:where(:active) {
1892
+ transform: scale(0.97);
1893
+ transform-origin: center;
1894
+ box-shadow: inset 0px 0px 4px 1px var(--bs-blue-base);
1881
1895
  }
1882
- :where(.box) :is(input, textarea, select):where(:focus-visible),
1883
- :where(.box) :is(.bs-input, .bs-textarea, .bs-select):where(:focus-visible) {
1884
- --offset-color: var(--bs-bg-medium);
1896
+ .bs-input-search button:where(:focus) {
1897
+ border-radius: .25rem;
1898
+ box-shadow: var(--focus-border) 0px 0px 0px 1px inset;
1899
+ z-index: 1;
1885
1900
  }
1886
- :where(.box[data-invert]) :is(input, textarea, select):where(:focus-visible),
1887
- :where(.box[data-invert]) :is(.bs-input, .bs-textarea, .bs-select):where(:focus-visible) {
1888
- --offset-color: var(--bs-bg-invert-base);
1901
+ /* Filter variant */
1902
+ .bs-input-search:where([data-variant="filter"]) {
1903
+ --focus-border: transparent;
1904
+ --input-border: transparent;
1905
+ --input-addon-height: 1.5rem;
1906
+ --input-caret: var(--bs-blue-base);
1907
+ --input-padding-block: 0 0.125rem;
1908
+ --input-padding-inline: 0.5rem;
1909
+ --input-placeholder: var(--bs-ink-light);
1910
+ --input-text-size: var(--bs-text-sm);
1911
+ --search-icon-size: 1rem;
1912
+ --search-icon-padding: 0;
1889
1913
  }
1890
- /* Errors and Messages */
1891
- :is(input, select, textarea):where([data-error]:not([data-error="false"])),
1892
- :is(.bs-input, .bs-select, .bs-textarea):where([data-error]:not([data-error="false"])) {
1893
- --input-border: var(--bs-ink-red);
1914
+ /* Filter variant: cancels out base hover state styles */
1915
+ .bs-input-addon:where([data-variant="filter"]):hover {
1916
+ --input-bg: var(--bs-bg-base);
1894
1917
  }
1895
- /* Fieldset */
1896
- :where(fieldset) {
1897
- border: none;
1898
- margin-left: 0;
1899
- margin-right: 0;
1900
- padding: 0;
1918
+ /* -------- Disabled styles -------- */
1919
+ .bs-input-addon:where([data-variant="filter"][data-disabled="true"]),
1920
+ .bs-input-addon:where([data-variant="filter"][data-disabled="true"]) :is(.bs-button, .bs-input) {
1921
+ --input-bg: var(--bs-bg-base);
1922
+ --input-border: transparent;
1901
1923
  }
1902
- :where(fieldset legend) {
1903
- margin-bottom: 0.25rem;
1904
- padding: 0;
1924
+ .bs-field-details {
1925
+ display: flex;
1926
+ justify-content: space-between;
1927
+ align-items: flex-start;
1928
+ gap: var(--bs-space-2);
1929
+ padding: 0 0.75rem;
1930
+ margin-top: 0.5rem;
1905
1931
  }
1906
- :where(label + input, label > input):where(:not([type='checkbox'], [type='radio'])),
1907
- :where(label + textarea, label > textarea),
1908
- :where(label + select, label > select) {
1932
+ :where(textarea, bs-textarea) + .bs-field-details {
1909
1933
  margin-top: 0.25rem;
1910
1934
  }
1911
- /*
1912
- Custom properties:
1913
- --input-bg (background color)
1914
- --input-border (border color)
1915
- --input-border-width (border width)
1916
- --input-caret (caret color)
1917
- --input-padding-block (padding block)
1918
- --input-padding-inline (padding inline)
1919
- --input-placeholder (placeholder color)
1920
- --input-text-size (font size)
1921
- */
1922
- input:where(:not([type='checkbox'], [type='radio'], [type='file'], [type='range'])),
1923
- textarea,
1924
- select,
1925
- :is(.bs-input, .bs-select, .bs-textarea) {
1926
- -webkit-appearance: none;
1927
- -moz-appearance: none;
1928
- appearance: none;
1929
- background-color: var(--input-bg, var(--bs-bg-base));
1930
- border-color: var(--input-border, var(--bs-violet-medium));
1931
- border-radius: 0.25rem;
1932
- border-style: solid;
1933
- border-width: var(--input-border-width, 1px);
1934
- caret-color: var(--input-caret, var(--bs-blue-base));
1935
+ .bs-field-details :where(.bs-character-count:first-child) {
1936
+ margin-left: auto;
1937
+ }
1938
+ .bs-character-count {
1935
1939
  color: var(--bs-ink-base);
1936
- font-size: var(--input-text-size, var(--bs-text-base));
1940
+ font-size: var(--bs-text-xs);
1937
1941
  font-weight: 400;
1938
- height: 2.5rem;
1939
- line-height: var(--bs-leading-base);
1940
- padding-block: var(--input-padding-block, 0.0625rem);
1941
- padding-inline: var(--input-padding-inline, 0.75rem);
1942
+ text-align: right;
1943
+ white-space: nowrap;
1942
1944
  }
1943
- input:where(:not([type='checkbox'], [type='radio'], [type='file'], [type='range'])),
1944
- textarea,
1945
- select {
1946
- width: 100%;
1945
+ :where(:disabled, [data-disabled="true"]) + .bs-character-count,
1946
+ :where(:disabled, [data-disabled="true"]) .bs-character-count,
1947
+ .bs-character-count:where([data-disabled="true"]) {
1948
+ color: var(--bs-ink-disabled);
1947
1949
  }
1948
- input:where([type='text'], [type='email'], [type='url']),
1949
- select,
1950
- .bs-input:where([type='text'], [type='email'], [type='url']),
1951
- .bs-select {
1952
- text-overflow: ellipsis;
1950
+ .bs-character-count:where([data-error="true"]) {
1951
+ color: var(--bs-ink-red);
1953
1952
  }
1954
- .bs-textarea,
1955
- textarea {
1956
- height: auto;
1957
- padding-block: 0.5rem;
1958
- resize: vertical;
1953
+ /* Containers and Labels for Checkbox/Radio */
1954
+ .bs-boolean {
1955
+ display: inline-flex;
1956
+ align-items: center;
1957
+ font-size: var(--bs-text-base);
1958
+ font-weight: 400;
1959
+ line-height: 115%;
1959
1960
  }
1960
- :is(input, textarea, select)::-moz-placeholder, :is(.bs-input, .bs-select, .bs-textarea)::-moz-placeholder {
1961
- color: var(--input-placeholder, var(--bs-violet-lightest));
1961
+ .bs-boolean:where([data-size='sm']) input {
1962
+ width: var(--bs-text-xs);
1963
+ height: var(--bs-text-xs);
1962
1964
  }
1963
- :is(input, textarea, select)::placeholder,
1964
- :is(.bs-input, .bs-select, .bs-textarea)::placeholder {
1965
- color: var(--input-placeholder, var(--bs-violet-lightest));
1965
+ .bs-boolean label {
1966
+ font-size: var(--bs-text-base);
1967
+ font-weight: 400;
1968
+ line-height: 1.5;
1969
+ width: auto;
1966
1970
  }
1967
- :is(input, textarea, select):where(:focus-visible)::-moz-placeholder, :is(.bs-input, .bs-select, .bs-textarea):where(:focus-visible)::-moz-placeholder {
1968
- opacity: 0;
1971
+ /* not using gap on .bs-boolean due to dead click zone */
1972
+ .bs-boolean label {
1973
+ padding-inline-end: 0.5em;
1969
1974
  }
1970
- :is(input, textarea, select):where(:focus-visible)::placeholder,
1971
- :is(.bs-input, .bs-select, .bs-textarea):where(:focus-visible)::placeholder {
1972
- opacity: 0;
1975
+ .bs-boolean input + label {
1976
+ padding-inline: 0.5em 0;
1973
1977
  }
1974
- /* FOCUS state */
1975
- :is(input:where(:not([type='checkbox'], [type='radio'])), textarea, select):where(:focus-visible),
1976
- :is(.bs-input, .bs-select, .bs-textarea):where(:focus-visible) {
1977
- --input-border: var(--bs-blue-base);
1978
- outline-style: none;
1979
- outline-width: 0px;
1978
+ .bs-boolean:where([data-size='sm']),
1979
+ .bs-boolean:where([data-size='sm']) label {
1980
+ font-size: var(--bs-text-xs);
1980
1981
  }
1981
- /* HOVER state */
1982
- :is(input:where(:not([type='checkbox'], [type='radio'])), textarea, select):where(:hover),
1983
- :is(.bs-input, .bs-select, .bs-textarea):where(:hover) {
1984
- --input-bg: var(--bs-bg-input-hover);
1982
+ /* Checkbox & Radio Input */
1983
+ :where(input[type='checkbox'], input[type='radio']),
1984
+ :is(.bs-boolean :where(input), .bs-checkbox) { /* .bs-checkbox added to accommodate 'fake' cbs */
1985
+ --box-shadow: var(--bs-ink-base);
1986
+
1987
+ -webkit-appearance: none;
1988
+
1989
+ -moz-appearance: none;
1990
+
1991
+ appearance: none;
1992
+ background-color: var(--bs-bg-base);
1993
+ box-shadow: inset 0 0 0 0.125rem var(--box-shadow);
1994
+ cursor: pointer;
1995
+ display: grid;
1996
+ height: 1rem;
1997
+ margin: 0;
1998
+ place-content: center;
1999
+ position: relative;
2000
+ width: 1rem;
1985
2001
  }
1986
- /* DISABLED state */
1987
- :is(input:where(:not([type='checkbox'],[type='radio'])), textarea, select):where(:disabled),
1988
- :is(.bs-input, .bs-select, .bs-textarea):where(:disabled) {
1989
- --input-border: var(--bs-ink-disabled);
1990
- --input-bg: var(--bs-bg-disabled);
1991
- color: var(--bs-ink-disabled);
2002
+ :where(input[type='checkbox'], input[type='radio']):focus-visible,
2003
+ :is(.bs-boolean :where(input), .bs-checkbox):focus-visible {
2004
+ box-shadow: inset 0 0 0 0.125rem var(--box-shadow),
2005
+ 0 0 0 2px var(--offset-color, var(--bs-bg-base)),
2006
+ 0 0 0 4px var(--outline-color, var(--bs-blue-base));
2007
+ outline: 2px solid transparent;
1992
2008
  }
1993
- /* Errors and Messages */
1994
- :is(input, select, textarea):where([data-error]:not([data-error="false"])),
1995
- :is(.bs-input, .bs-select, .bs-textarea):where([data-error="true"]) {
1996
- --input-border: var(--bs-ink-red);
2009
+ :where(input[type='checkbox']),
2010
+ :is(.bs-boolean :where([type='checkbox']), .bs-checkbox) {
2011
+ border-radius: 0.125rem;
1997
2012
  }
1998
- /*
1999
- Removes the built-in 'margin' on bottom of textarea
2000
- see https://bugs.chromium.org/p/chromium/issues/detail?id=89530
2001
- */
2002
- :has(> textarea:only-child),
2003
- :has(> .bs-textarea:only-child) {
2004
- display: block;
2005
- line-height: 0;
2013
+ :where(input[type='radio']),
2014
+ .bs-boolean :where([type='radio']) {
2015
+ border-radius: 50%;
2006
2016
  }
2007
- /* chrome user agent styling was applying opacity: 0.7 */
2008
- :where(select:disabled) {
2009
- opacity: 1;
2017
+ /* Checkbox's checkmark */
2018
+ input:where([type='checkbox'])::before,
2019
+ :is(.bs-boolean :where([type="checkbox"]), .bs-checkbox)::before {
2020
+ --filled-size: 1rem;
2021
+ --check-fill-color: var(--bs-blue-base);
2022
+
2023
+ content: '';
2024
+ border-radius: 0.125rem;
2025
+ box-shadow: inset var(--filled-size) var(--filled-size) var(--check-fill-color);
2026
+ height: var(--filled-size);
2027
+ visibility: hidden;
2028
+ width: var(--filled-size);
2010
2029
  }
2011
- :is(input, textarea, select):disabled::-moz-placeholder, :is(input, textarea, select)[disabled]::-moz-placeholder, :is(.bs-input, .bs-textarea, .bs-select):disabled::-moz-placeholder, :is(.bs-input, .bs-textarea, .bs-select)[disabled]::-moz-placeholder {
2012
- opacity: 0;
2030
+ input:where([type='checkbox'])::after,
2031
+ :is(.bs-boolean :where([type="checkbox"]), .bs-checkbox)::after {
2032
+ border: solid var(--bs-white);
2033
+ border-width: 0 0.125rem 0.125rem 0;
2034
+ content: '';
2035
+ height: 0.75em;
2036
+ left: 50%;
2037
+ position: absolute;
2038
+ top: 50%;
2039
+ transform-origin: center;
2040
+ transform: translate(-50%, -60%) rotate(45deg);
2041
+ visibility: hidden;
2042
+ width: 0.375em;
2013
2043
  }
2014
- :is(input, textarea, select):disabled::placeholder,
2015
- :is(input, textarea, select)[disabled]::placeholder,
2016
- :is(.bs-input, .bs-textarea, .bs-select):disabled::placeholder,
2017
- :is(.bs-input, .bs-textarea, .bs-select)[disabled]::placeholder {
2018
- opacity: 0;
2044
+ input:where([type='checkbox']):where(:indeterminate)::after,
2045
+ .bs-boolean :where([type="checkbox"]):where(:indeterminate)::after,
2046
+ .bs-checkbox:where([data-indeterminate="true"], :indeterminate)::after {
2047
+ border: none;
2048
+ background-color: var(--bs-white);
2049
+ height: 0.125rem;
2050
+ transform: translate(-50%, -0.0625rem) rotate(0deg);
2051
+ width: 0.625em;
2019
2052
  }
2020
- /* Select */
2021
- select,
2022
- .bs-select {
2023
- /* URL Encoded SVG dropdown caret so there is something there */
2024
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%230A0B19' d='M8.048 13.375a.745.745 0 0 1-.526-.217L0 5.686l1.053-1.061 6.995 6.95 6.897-6.85 1.053 1.06-7.423 7.373a.745.745 0 0 1-.527.217Z'/%3E%3C/svg%3E");
2025
- background-position: right 0.75rem center;
2026
- background-repeat: no-repeat;
2027
- background-size: 1em 1em;
2028
- padding-right: var(--bs-space-9);
2053
+ /* Radio's dot */
2054
+ input:where([type='radio'])::before,
2055
+ .bs-boolean :where([type="radio"])::before {
2056
+ --filled-size: 1rem;
2057
+ --radio-fill-color: var(--bs-blue-base);
2058
+
2059
+ background-color: var(--radio-fill-color);
2060
+ border-radius: 50%;
2061
+ box-sizing: content-box;
2062
+ content: '';
2063
+ height: var(--filled-size);
2064
+ visibility: hidden;
2065
+ width: var(--filled-size);
2029
2066
  }
2030
- .dark select,
2031
- .dark .bs-select {
2032
- /* URL Encoded SVG dropdown caret so there is something there */
2033
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%23ffffff' d='M8.048 13.375a.745.745 0 0 1-.526-.217L0 5.686l1.053-1.061 6.995 6.95 6.897-6.85 1.053 1.06-7.423 7.373a.745.745 0 0 1-.527.217Z'/%3E%3C/svg%3E");
2067
+ input:where([type='radio'])::after,
2068
+ .bs-boolean :where([type="radio"])::after {
2069
+ --inner-size: 0.375rem;
2070
+ --inner-fill-color: var(--bs-white);
2071
+
2072
+ background-color: var(--inner-fill-color);
2073
+ border-radius: 50%;
2074
+ box-sizing: content-box;
2075
+ content: '';
2076
+ height: var(--inner-size);
2077
+ left: 50%;
2078
+ position: absolute;
2079
+ top: 50%;
2080
+ transform: translate(-50%, -50%);
2081
+ visibility: hidden;
2082
+ width: var(--inner-size);
2034
2083
  }
2035
- .dark select:disabled,
2036
- .dark .bs-select:disabled {
2037
- /* URL Encoded SVG dropdown caret so there is something there */
2038
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath fill='%23555775' d='M8.048 13.375a.745.745 0 0 1-.526-.217L0 5.686l1.053-1.061 6.995 6.95 6.897-6.85 1.053 1.06-7.423 7.373a.745.745 0 0 1-.527.217Z'/%3E%3C/svg%3E");
2084
+ /* Show checkmark, indeterminate mark, or radio dot */
2085
+ .bs-checkbox:where([data-indeterminate="true"], [data-checked="true"], :checked, :indeterminate)::before,
2086
+ .bs-checkbox:where([data-indeterminate="true"], [data-checked="true"], :checked, :indeterminate)::after,
2087
+ input:where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::before,
2088
+ input:where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::after,
2089
+ .bs-boolean :where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::before,
2090
+ .bs-boolean :where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::after {
2091
+ visibility: visible;
2092
+ }
2093
+ .bs-boolean:where([data-size='sm']) input::before,
2094
+ .bs-checkbox:where([data-size="sm"])::before {
2095
+ --filled-size: var(--bs-text-xs);
2039
2096
  }
2040
- /* 0 0 1 for width to allow e.g. tailwind override */
2041
- :is(div, *):where(.bs-input-addon) {
2042
- width: 100%;
2097
+ .bs-boolean:where([data-size='sm']) input[type='checkbox']::after,
2098
+ .bs-checkbox:where([data-size="sm"])::after {
2099
+ height: 0.5625rem;
2100
+ width: 0.3125rem;
2043
2101
  }
2044
- .bs-input-addon {
2045
- --input-border: var(--bs-violet-300);
2046
- align-items: center;
2047
- background-color: var(--input-bg, var(--bs-bg-base));
2048
- border-radius: .25rem;
2049
- color: var(--bs-ink-base);
2050
- display: flex;
2051
- height: var(--input-addon-height, 2.5rem);
2052
- overflow: hidden;
2053
- padding: 0;
2054
- pointer-events: none;
2055
- position: relative;
2102
+ .bs-boolean:where([data-size='sm']) input[type='checkbox']:where(:indeterminate)::after,
2103
+ .bs-checkbox:where([data-size="sm"][data-indeterminate="true"], [data-size="sm"]:indeterminate)::after {
2104
+ height: 0.125rem;
2105
+ width: .75em;
2056
2106
  }
2057
- .bs-input-addon * {
2107
+ .bs-boolean:where([data-size='sm']) input[type='radio']::after {
2108
+ --inner-size: 0.25rem;
2109
+ }
2110
+ /* Disabled State */
2111
+ input:where([type='checkbox'], [type='radio']):disabled,
2112
+ .bs-boolean :where(input):disabled,
2113
+ .bs-checkbox:is([data-disabled="true"], :disabled) {
2114
+ --box-shadow: var(--bs-bg-disabled);
2058
2115
  background-color: transparent;
2116
+ cursor: default;
2059
2117
  }
2060
- /**
2061
- Implement an outer 'border' via pseudo-element instead of
2062
- on main element to avoid content shifting, double-stroke effect,
2063
- and issues with box-sizing
2064
- */
2065
- .bs-input-addon::after,
2066
- .bs-input-addon::before,
2067
- .bs-input-addon ::after,
2068
- .bs-input-addon ::before {
2118
+ .bs-checkbox:where([data-disabled="true"]:not(input)) {
2069
2119
  pointer-events: none;
2070
2120
  }
2071
- .bs-input-addon::after,
2072
- .bs-input-addon::before {
2073
- content: '';
2074
- height: 100%;
2075
- left: 0;
2076
- position: absolute;
2077
- top: 0;
2078
- width: 100%;
2121
+ input:where([type='checkbox']):checked:disabled::before,
2122
+ input:where([type='checkbox']):indeterminate:disabled::before,
2123
+ .bs-boolean :where(input[type="checkbox"]):checked:disabled::before,
2124
+ .bs-boolean :where(input[type="checkbox"]):indeterminate:disabled::before,
2125
+ .bs-checkbox:where([data-checked="true"][data-disabled="true"], :checked:disabled)::before,
2126
+ .bs-checkbox:where([data-indeterminate="true"][data-disabled="true"], :indeterminate:disabled)::before {
2127
+ --check-fill-color: var(--bs-bg-disabled);
2079
2128
  }
2080
- .bs-input-addon::after {
2081
- border-radius: .25rem;
2082
- border: 1px solid var(--input-border);
2129
+ input:where([type='radio']):checked:disabled::before,
2130
+ .bs-boolean :where(input[type="radio"]):checked:disabled::before {
2131
+ --radio-fill-color: var(--bs-bg-disabled);
2083
2132
  }
2084
- .bs-input-addon :where(.bs-input-addon)::after {
2085
- border: 1px solid var(--input-addon-nested-border);
2133
+ /* Error state */
2134
+ input:where([type='checkbox'], [type='radio'])[data-error]:where(:not([data-error="false"])),
2135
+ .bs-boolean :where(input[data-error="true"]),
2136
+ .bs-checkbox:where([data-error="true"]) {
2137
+ --box-shadow: var(--bs-red-base);
2138
+ --outline-color: var(--bs-red-base);
2086
2139
  }
2087
- .bs-input-addon > * {
2088
- flex-grow: 0;
2089
- flex-shrink: 0;
2140
+ .bs-switch {
2141
+ --box-shadow: var(--bs-ink-base);
2142
+ --ball-background: var(--bs-white);
2143
+ --ball-diameter: 1rem;
2144
+ --inner-text-line-height: 1;
2145
+ --inner-text-size: var(--bs-text-sm);
2146
+ --inner-text-width: 1rem;
2147
+ --inner-text-padding: 0.5rem;
2148
+ --offset: 0.25rem;
2149
+ --offset-double: .5rem;
2150
+ --switch-background: var(--bs-gray-400);
2151
+ --switch-height: 1.5rem;
2152
+ --switch-width: 2.5rem;
2153
+
2154
+ border: none;
2155
+ border-radius: 100vw;
2156
+ cursor: pointer;
2157
+ height: var(--switch-height);
2090
2158
  position: relative;
2091
2159
  }
2092
- .bs-input-addon > :where([data-autowidth]:not([data-autowidth="false"]), .bs-input-addon, bs-input, .bs-input) {
2093
- flex-grow: 1;
2094
- flex-shrink: 1;
2160
+ .bs-switch:where([data-size="sm"]) {
2161
+ --ball-diameter: .625rem;
2162
+ --inner-text-line-height: 1.6666;
2163
+ --inner-text-size: var(--bs-text-xs);
2164
+ --inner-text-width: .75rem;
2165
+ --inner-text-padding: 0.375rem;
2166
+ --offset: 0.1875rem;
2167
+ --offset-double: .375rem;
2168
+ --switch-height: 1rem;
2169
+ --switch-width: 1.875rem;
2095
2170
  }
2096
- .bs-input-addon > :where([data-autowidth]:not([data-autowidth="false"])) > :where(input, select) {
2171
+ .bs-switch input,
2172
+ .bs-switch:where([data-size="sm"]) input {
2173
+ cursor: pointer;
2174
+ height: 100%;
2175
+ opacity: 0;
2176
+ position: absolute;
2097
2177
  width: 100%;
2098
2178
  }
2099
- .bs-input-addon > *:where(:not(.bs-input-addon)) {
2100
- border-width: 0px;
2101
- display: flex;
2179
+ .bs-switch span {
2180
+ align-items: center;
2181
+ background-color: var(--switch-background);
2182
+ border-radius: 100vw;
2183
+ display: inline-block;
2184
+ font-size: var(--inner-text-size);
2102
2185
  height: 100%;
2103
- overflow: hidden;
2104
- pointer-events: auto;
2105
- }
2106
- /* Remove (hide) children's borders, outlines */
2107
- .bs-input-addon > *,
2108
- .bs-input-addon :where(input, select),
2109
- .bs-input-addon :is(bs-input, bs-select) :where(input, select),
2110
- .bs-input-addon :is(input, select):where(.bs-input, .bs-select),
2111
- .bs-input-addon :where(.bs-input-addon) {
2112
- --input-border: transparent;
2113
- --input-border-width: 0px;
2114
- }
2115
- .bs-input-addon {
2116
- --input-addon-nested-border: transparent;
2117
- }
2118
- .bs-input-addon :where(:focus-within) :where(input, select, button),
2119
- .bs-input-addon :where(:focus-within) :is(bs-input, bs-select) :where(input, select),
2120
- .bs-input-addon :where(:focus-within) :is(input, select, button):where(.bs-input, .bs-select),
2121
- .bs-input-addon :where(input, select, button):where(:focus, :focus-within, :focus-visible),
2122
- .bs-input-addon :is(input, select):where(.bs-input, .bs-select):where(:focus, :focus-within, :focus-visible),
2123
- .bs-input-addon :is(bs-input, bs-select) :where(input, select):where(:focus, :focus-within, :focus-visible) {
2124
- --input-border: transparent;
2125
- box-shadow: none;
2126
- outline: none;
2186
+ padding: 0 var(--inner-text-padding);
2187
+ pointer-events: none;
2188
+ position: relative;
2189
+ transition: 250ms;
2190
+ width: var(--switch-width);
2127
2191
  }
2128
- /* -------- Inner-bordered styles -------- */
2129
- /** Inner borders should be straight; shown only if variant: "inner-bordered" */
2130
- .bs-input-addon:where([data-variant="inner-bordered"]) {
2131
- --input-addon-nested-border: var(--bs-violet-lightest);
2192
+ .bs-switch :where(input:checked) ~ :where(span),
2193
+ .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where(span) {
2194
+ --switch-background: var(--bs-blue-base);
2132
2195
  }
2133
- .bs-input-addon > :where(.bs-input-addon:not(:last-child, :focus-within)),
2134
- .bs-input-addon > :where(:not(:last-child, :focus-within))::after {
2135
- border-top-right-radius: 0;
2136
- border-bottom-right-radius: 0;
2196
+ /* Toggle "ball" */
2197
+ .bs-switch :where(span)::before {
2198
+ background-color: var(--ball-background);
2199
+ border-radius: 50%;
2200
+ box-sizing: border-box;
2201
+ content: '';
2202
+ height: var(--ball-diameter);
2203
+ left: var(--offset);
2204
+ position: absolute;
2205
+ top: 50%;
2206
+ transform: translate(0, -50%);
2207
+ transition: inherit;
2208
+ width: var(--ball-diameter);
2209
+ z-index: 2;
2137
2210
  }
2138
- .bs-input-addon > :where(.bs-input-addon:not(:first-child, :focus-within)),
2139
- .bs-input-addon > :where(:not(:first-child, :focus-within))::after {
2140
- border-top-left-radius: 0;
2141
- border-bottom-left-radius: 0;
2211
+ .bs-switch :where(input:checked) ~ :where(span)::before,
2212
+ .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where(span)::before {
2213
+ transform: translate(calc(var(--switch-width) - var(--offset-double) - var(--ball-diameter)), -50%);
2142
2214
  }
2143
- .bs-input-addon:where([data-variant="inner-bordered"]) > :where(:not(:focus, :focus-within))::after {
2144
- border-left-width: 0px;
2145
- border-right-width: 1px;
2146
- border-right-color: var(--input-addon-nested-border);
2215
+ .bs-switch :where(input:checked) ~ :where(span[data-inner-on-label][data-inner-off-label])::before,
2216
+ .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where(span[data-inner-on-label][data-inner-off-label])::before {
2217
+ transform: translate(calc(var(--switch-width) - var(--offset-double) - var(--ball-diameter)), -50%);
2147
2218
  }
2148
- .bs-input-addon:where([data-variant="inner-bordered"]) > :where(:not(.bs-input-addon, :focus, :focus-within))::after {
2149
- content: '';
2219
+ /* Inner "on/off" text */
2220
+ .bs-switch :where(span)::after {
2221
+ align-items: center;
2222
+ color: var(--ball-background);
2223
+ content: var(--inner-label-text);
2224
+ display: flex;
2150
2225
  height: 100%;
2226
+ justify-content: var(--inner-label-position, flex-start);
2151
2227
  left: 0;
2228
+ line-height: var(--inner-text-line-height);
2229
+ padding: var(--inner-text-padding);
2152
2230
  position: absolute;
2231
+ text-transform: capitalize;
2153
2232
  top: 0;
2154
2233
  width: 100%;
2155
2234
  }
2156
- .bs-input-addon:where([data-variant="inner-bordered"]) > :where(.bs-input-addon)::after {
2157
- border-radius: 0px;
2158
- }
2159
- /* -------- Hover styles -------- */
2160
- .bs-input-addon:hover {
2161
- --input-bg: var(--bs-bg-input-hover);
2162
- }
2163
- /* -------- Focus styles -------- */
2164
- .bs-input-addon {
2165
- --focus-border: var(--bs-blue-base);
2166
- }
2167
- .bs-input-addon:where(:not([data-multifocus]):focus-within),
2168
- .bs-input-addon:where([data-multifocus="false"]:focus-within),
2169
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :where(input, select):where(:focus, :focus-within, :focus-visible),
2170
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :is(input, select):where(.bs-input, .bs-select):where(:focus, :focus-within, :focus-visible),
2171
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :is(bs-input, bs-select) :where(input, select):where(:focus, :focus-within, :focus-visible) {
2172
- --input-border: var(--focus-border);
2173
- position: relative;
2174
- z-index: 1;
2175
- }
2176
- .bs-input-addon :where(.bs-input-addon:focus-within) {
2177
- --input-addon-nested-border: var(--focus-border);
2178
- z-index: 1;
2235
+ .bs-switch :where([data-inner-on-label][data-inner-off-label]) {
2236
+ --switch-width: 3.5rem;
2179
2237
  }
2180
- .bs-input-addon :where(.bs-input-addon:focus-within)::after {
2181
- z-index: 1;
2238
+ .bs-switch:where([data-size="sm"]) :where([data-inner-on-label][data-inner-off-label]) {
2239
+ --switch-width: 2.625rem;
2182
2240
  }
2183
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :where(:not(.bs-input-addon)) > :is(input, select, button):where(:focus),
2184
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :is(input, select):where(.bs-input, .bs-select):where(:focus),
2185
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :is(bs-input, bs-select) :where(input:focus, select:focus),
2186
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) > :where(input:focus, select:focus, button:focus) {
2187
- border-radius: .25rem;
2188
- box-shadow: var(--focus-border) 0px 0px 0px 1px inset;
2189
- z-index: 1;
2241
+ .bs-switch :where(input:not(:checked)) ~ :where([data-inner-on-label][data-inner-off-label])::after,
2242
+ .bs-switch:where([aria-pressed="false"]) :where([data-inner-on-label][data-inner-off-label])::after {
2243
+ --inner-label-position: flex-end;
2244
+ --inner-label-text: attr(data-inner-off-label);
2190
2245
  }
2191
- .bs-input-addon:where(:not([data-multifocus]):focus-within)::after,
2192
- .bs-input-addon:where([data-multifocus="false"]:focus-within)::after {
2193
- border-width: 1px;
2194
- border-radius: .25rem;
2246
+ .bs-switch :where(input:checked) ~ :where([data-inner-on-label][data-inner-off-label])::after,
2247
+ .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where([data-inner-on-label][data-inner-off-label])::after {
2248
+ --inner-label-text: attr(data-inner-on-label);
2195
2249
  }
2196
- .bs-input-addon:where(:focus-within) :where(:not(:focus, :focus-within))::after,
2197
- .bs-input-addon:where(:focus-within) :where(:not(:focus, :focus-within)) {
2198
- border-color: transparent;
2250
+ /* Focus state */
2251
+ .bs-switch :where(input:focus-visible) + :where(span),
2252
+ .bs-switch:where(:focus-visible) :where(button span) {
2253
+ box-shadow: 0 0 0 2px var(--offset-color, var(--bs-bg-base)),
2254
+ 0 0 0 4px var(--outline-color, var(--bs-blue-base));
2255
+ outline: 2px solid transparent;
2199
2256
  }
2200
- /* Straight-lined ::before border to fill the gap below the rounded ::after border */
2201
- .bs-input-addon:where([data-multifocus]:not([data-multifocus="false"])) :where(:focus-within)::before {
2202
- border-bottom-width: 1px;
2203
- border-color: var(--bs-violet-300);
2204
- border-radius: 0;
2205
- border-top-width: 1px;
2206
- z-index: 1;
2257
+ :where(.box) .bs-switch :where(input:focus-visible) + :where(span),
2258
+ :where(.box) .bs-switch:where(:focus-visible) :where(button span) {
2259
+ --offset-color: var(--bs-bg-medium);
2207
2260
  }
2208
- /* -------- Disabled styles -------- */
2209
- .bs-input-addon:where([data-disabled]:not([data-disabled="false"])),
2210
- .bs-input-addon:where([data-disabled]:not([data-disabled="false"])) .bs-button {
2211
- --input-bg: var(--bs-bg-disabled);
2212
- --input-border: var(--bs-ink-disabled);
2213
- --input-addon-nested-border: var(--bs-ink-disabled);
2214
- color: var(--bs-ink-disabled);
2261
+ :where(.box[data-invert]) .bs-switch :where(input:focus-visible) + :where(span),
2262
+ :where(.box[data-invert]) .bs-switch:where(:focus-visible) :where(button span) {
2263
+ --offset-color: var(--bs-bg-invert-base);
2215
2264
  }
2216
- .bs-input-addon:where([data-disabled]:not([data-disabled="false"])) * {
2217
- pointer-events: none;
2265
+ /* Disabled state */
2266
+ .bs-switch:where([data-disabled]:not([data-disabled="false"]), :disabled, [disabled]),
2267
+ .bs-switch:where([data-disabled]:not([data-disabled="false"]), :disabled, [disabled]) :is(input ~ span, button span) {
2268
+ --ball-background: var(--bs-ink-disabled);
2269
+ --switch-background: var(--bs-bg-disabled);
2218
2270
  }
2219
- /* -------- Error styles -------- */
2220
- .bs-input-addon:where([data-error]:not([data-error="false"])),
2221
- .bs-input-addon:where([data-error]:not([data-error="false"])) :where(.bs-input-addon) {
2222
- --focus-border: var(--bs-ink-red);
2223
- --input-border: var(--bs-ink-red);
2271
+ .bs-switch input:where(:disabled) {
2272
+ cursor: default;
2224
2273
  }
2225
- .bs-input-addon:where([data-error]:not([data-error="false"]),[data-disabled]:not([data-disabled="false"])) > *::before,
2226
- .bs-input-addon:where(.bs-input-addon[data-error]:not([data-error="false"]) .bs-input-addon, .bs-input-addon[data-disabled]:not([data-disabled="false"]) .bs-input-addon) > *::before {
2227
- border-color: var(--input-border);
2274
+ .bs-hint {
2275
+ --hint-color: var(--bs-ink-light);
2276
+ min-width: 0;
2277
+ color: var(--hint-color);
2278
+ font-size: var(--bs-text-xs);
2279
+ padding: 0;
2280
+ margin: 0;
2281
+ list-style: none;
2282
+ overflow-wrap: break-word;
2228
2283
  }
2229
- /* -------- Label margin -------- */
2230
- :where(label, .bs-label, bs-label) + .bs-input-addon {
2231
- margin-top: 0.25rem;
2284
+ .bs-hint:where([data-error]:not([data-error="false"])) {
2285
+ --hint-color: var(--bs-ink-red);
2232
2286
  }
2233
- .bs-input-phone :where(.bs-input-addon) > button {
2287
+ .bs-button {
2288
+ --btn-main: var(--bs-blue-400);
2289
+ --btn-secondary: var(--bs-blue-medium);
2290
+ --btn-highlight: var(--bs-blue-100);
2291
+ --btn-padding: .25rem .75rem;
2292
+ --btn-focus-pseudo-width: calc(100% + 0.5rem);
2293
+ --btn-ghost-ink: var(--bs-ink-blue);
2294
+ --btn-ink: var(--bs-white);
2234
2295
  align-items: center;
2235
- -moz-column-gap: .5rem;
2236
- column-gap: .5rem;
2296
+ background-color: var(--btn-main);
2297
+ border: none;
2298
+ border-radius: 0.25rem;
2299
+ color: var(--btn-ink);
2237
2300
  cursor: pointer;
2238
- display: grid;
2239
- grid-template-columns: 1.25rem auto .75rem;
2240
- min-width: 6rem;
2241
- padding: 0 1rem;
2301
+ display: inline-flex;
2302
+ font-size: var(--btn-text-size, var(--bs-text-md));
2303
+ font-weight: var(--btn-weight, 600);
2304
+ height: var(--btn-height, 2.5rem);
2305
+ justify-content: center;
2306
+ line-height: 1.5;
2307
+ outline: 2px solid transparent;
2308
+ padding: var(--btn-padding);
2309
+ position: relative;
2310
+ text-decoration: none;
2311
+ transition: all 100ms ease-in-out;
2312
+ vertical-align: middle;
2242
2313
  }
2243
- .bs-input-phone ul:where(.bs-dropdown-options) {
2244
- min-width: 7.5rem;
2314
+ .bs-button:hover {
2315
+ background-color: var(--btn-secondary);
2245
2316
  }
2246
- :where(.bs-input-search) {
2247
- display: inline-block;
2248
- width: 100%;
2317
+ .bs-button:active {
2318
+ background-color: var(--btn-secondary);
2319
+ transform: scale(0.97);
2320
+ transform-origin: center;
2321
+ box-shadow: inset 0px 0px 4px 1px var(--btn-main);
2249
2322
  }
2250
- .bs-input-search :where(.bs-icon svg) {
2251
- box-sizing: content-box;
2323
+ /* ------------ Focus Styles ------------ */
2324
+ .bs-button::before {
2325
+ border-color: transparent;
2326
+ border-radius: 0.5rem;
2327
+ border-style: solid;
2328
+ border-width: 0.125rem;
2329
+ content: '';
2330
+ height: calc(100% + 0.5rem);
2331
+ inset: -0.25rem;
2332
+ left: auto;
2333
+ position: absolute;
2334
+ right: auto;
2335
+ transition: border-color 0.125s ease-in-out;
2336
+ width: var(--btn-focus-pseudo-width);
2252
2337
  }
2253
- .bs-input-search :where([data-component="bs-icon-search"]) {
2254
- --icon-size: var(--search-icon-size, 1.75rem);
2255
- padding: var(--search-icon-padding, 0 0 0 .75rem);
2338
+ .bs-button:focus::before {
2339
+ border-color: var(--btn-main);
2256
2340
  }
2257
- /* Clear Button */
2258
- .bs-input-search button {
2259
- align-items: center;
2341
+ .bs-button:focus-visible::before {
2342
+ border-color: var(--btn-main);
2343
+ box-shadow: none;
2344
+ }
2345
+ .bs-button:focus:not(:focus-visible)::before {
2346
+ border-color: transparent;
2347
+ box-shadow: none;
2348
+ }
2349
+ /* ------------ Ghost Buttons ------------ */
2350
+ .bs-button:where([data-ghost]:not([data-ghost="false"])) {
2351
+ --btn-ink: var(--btn-ghost-ink);
2352
+ --btn-light: var(--bs-blue-10);
2353
+ --btn-secondary: var(--bs-blue-10);
2260
2354
  background-color: transparent;
2261
- cursor: pointer;
2262
- display: flex;
2263
- height: 100%;
2264
- padding-left: 0.75rem;
2265
- padding-right: 0.75rem;
2266
- transition: transform 100ms ease-in-out;
2355
+ box-shadow: inset 0 0 0 1px var(--btn-main);
2267
2356
  }
2268
- .bs-input-search button:where(:active) {
2269
- transform: scale(0.97);
2270
- transform-origin: center;
2271
- box-shadow: inset 0px 0px 4px 1px var(--bs-blue-base);
2357
+ .bs-button:where([data-ghost]:not([data-ghost="false"]))::before {
2358
+ border-radius: 0.4375rem;
2272
2359
  }
2273
- .bs-input-search button:where(:focus) {
2274
- border-radius: .25rem;
2275
- box-shadow: var(--focus-border) 0px 0px 0px 1px inset;
2276
- z-index: 1;
2360
+ .bs-button:where([data-ghost]:not([data-ghost="false"])):hover,
2361
+ .bs-button:where([data-ghost]:not([data-ghost="false"])):focus {
2362
+ background-color: var(--btn-light);
2277
2363
  }
2278
- /* Filter variant */
2279
- .bs-input-search:where([data-variant="filter"]) {
2280
- --focus-border: transparent;
2281
- --input-border: transparent;
2282
- --input-addon-height: 1.5rem;
2283
- --input-caret: var(--bs-blue-base);
2284
- --input-padding-block: 0 0.125rem;
2285
- --input-padding-inline: 0.5rem;
2286
- --input-placeholder: var(--bs-ink-light);
2287
- --input-text-size: var(--bs-text-sm);
2288
- --search-icon-size: 1rem;
2289
- --search-icon-padding: 0;
2364
+ .bs-button:where([data-ghost]:not([data-ghost="false"])):active {
2365
+ box-shadow:
2366
+ inset 0 0 0 1px var(--btn-main),
2367
+ inset 0px 0px 4px 1px var(--btn-highlight);
2290
2368
  }
2291
- /* Filter variant: cancels out base hover state styles */
2292
- .bs-input-addon:where([data-variant="filter"]):hover {
2293
- --input-bg: var(--bs-bg-base);
2369
+ /* ------------ VARIANTS ------------ */
2370
+ .bs-button:where([data-variant^='secondary']) {
2371
+ --btn-main: var(--bs-plum-400);
2372
+ --btn-secondary: var(--bs-plum-medium);
2373
+ --btn-light: var(--bs-plum-10);
2374
+ --btn-highlight: var(--bs-plum-100);
2375
+ --btn-ghost-ink: var(--bs-ink-plum);
2294
2376
  }
2295
- /* -------- Disabled styles -------- */
2296
- .bs-input-addon:where([data-variant="filter"][data-disabled="true"]),
2297
- .bs-input-addon:where([data-variant="filter"][data-disabled="true"]) :is(.bs-button, .bs-input) {
2298
- --input-bg: var(--bs-bg-base);
2299
- --input-border: transparent;
2377
+ .dark .bs-button:where([data-variant^='secondary']) {
2378
+ --btn-main: var(--bs-plum-200);
2379
+ --btn-secondary: var(--bs-plum-300);
2380
+ --btn-light: var(--bs-navy-400);
2381
+ --btn-highlight: var(--bs-plum-400);
2300
2382
  }
2301
- .bs-field-details {
2302
- display: flex;
2303
- justify-content: space-between;
2304
- align-items: flex-start;
2305
- gap: var(--bs-space-2);
2306
- padding: 0 0.75rem;
2307
- margin-top: 0.5rem;
2383
+ .bs-button:where([data-variant^='positive']) {
2384
+ --btn-main: var(--bs-purple-400);
2385
+ --btn-secondary: var(--bs-purple-medium);
2386
+ --btn-light: var(--bs-purple-10);
2387
+ --btn-highlight: var(--bs-purple-100);
2388
+ --btn-ghost-ink: var(--bs-ink-purple);
2308
2389
  }
2309
- :where(textarea, bs-textarea) + .bs-field-details {
2310
- margin-top: 0.25rem;
2390
+ .bs-button:where([data-variant^='warning']) {
2391
+ --btn-main: var(--bs-orange-warning);
2392
+ --btn-secondary: var(--bs-orange-base);
2393
+ --btn-light: var(--bs-orange-10);
2394
+ --btn-highlight: var(--bs-orange-100);
2395
+ --btn-ghost-ink: var(--bs-ink-orange);
2311
2396
  }
2312
- .bs-field-details :where(.bs-character-count:first-child) {
2313
- margin-left: auto;
2397
+ .bs-button:where([data-variant^='negative']) {
2398
+ --btn-main: var(--bs-red-400);
2399
+ --btn-secondary: var(--bs-red-medium);
2400
+ --btn-light: var(--bs-red-10);
2401
+ --btn-highlight: var(--bs-red-100);
2402
+ --btn-ghost-ink: var(--bs-ink-red);
2314
2403
  }
2315
- .bs-character-count {
2316
- color: var(--bs-ink-base);
2317
- font-size: var(--bs-text-xs);
2318
- font-weight: 400;
2319
- text-align: right;
2320
- white-space: nowrap;
2404
+ /* ------------ Text Button ------------ */
2405
+ .bs-button:where([data-text]:not([data-text="false"])) {
2406
+ --btn-height: auto;
2407
+ --btn-ink: var(--bs-ink-blue);
2408
+ --btn-padding: 0;
2409
+ --btn-focus-pseudo-width: calc(100% + 1rem); /* text btns don't have side padding, but we do want focus outline to look padded */
2410
+ --btn-text-size: var(--bs-text-md);
2411
+ --btn-weight: 400;
2412
+ background-color: transparent;
2413
+ cursor: pointer;
2414
+ line-height: 150%;
2321
2415
  }
2322
- :where(:disabled, [data-disabled="true"]) + .bs-character-count,
2323
- :where(:disabled, [data-disabled="true"]) .bs-character-count,
2324
- .bs-character-count:where([data-disabled="true"]) {
2325
- color: var(--bs-ink-disabled);
2416
+ .bs-button:where([data-text]:not([data-text="false"])):hover {
2417
+ --btn-ink: var(--bs-blue-base);
2418
+ background-color: transparent;
2419
+ text-decoration: underline;
2420
+ }
2421
+ .bs-button:where([data-text]:not([data-text="false"])):has(svg):hover {
2422
+ text-decoration: none;
2423
+ }
2424
+ .bs-button:where([data-text]:not([data-text="false"])):active {
2425
+ box-shadow: none;
2426
+ transform: none;
2427
+ }
2428
+ /* ------------ Button Sizes, Media-based Text Sizing -------------- */
2429
+ /* Std button: Mobile text size, DT text size */
2430
+ .bs-button {
2431
+ --btn-text-size: 1rem;
2432
+ }
2433
+ @media (min-width: 1166px) {
2434
+ .bs-button {
2435
+ --btn-text-size: 1.125rem;
2436
+ }
2326
2437
  }
2327
- .bs-character-count:where([data-error="true"]) {
2328
- color: var(--bs-ink-red);
2438
+ .bs-button:where([data-size^='sm']) {
2439
+ --btn-height: 1.75rem;
2440
+ --btn-padding: .25rem .75rem .375rem;
2441
+ /* Std button size="sm" text size is same across all media sizes */
2442
+ --btn-text-size: var(--bs-text-sm);
2329
2443
  }
2330
- /* Containers and Labels for Checkbox/Radio */
2331
- .bs-boolean {
2332
- display: inline-flex;
2333
- align-items: center;
2334
- font-size: var(--bs-text-base);
2335
- font-weight: 400;
2336
- line-height: 115%;
2444
+ /* Text buttons: For now, text size not dependent on media size */
2445
+ .bs-button:where([data-text]:not([data-text="false"])) {
2446
+ --btn-height: auto;
2447
+ --btn-padding: 0;
2448
+ --btn-text-size: var(--bs-text-md);
2337
2449
  }
2338
- .bs-boolean:where([data-size='sm']) input {
2339
- width: var(--bs-text-xs);
2340
- height: var(--bs-text-xs);
2450
+ .bs-button:where([data-size^='sm'][data-text]:not([data-text="false"])) {
2451
+ --btn-text-size: var(--bs-text-base);
2341
2452
  }
2342
- .bs-boolean label {
2343
- font-size: var(--bs-text-base);
2344
- font-weight: 400;
2345
- line-height: 1.5;
2346
- width: auto;
2453
+ /* Size XS & XXS only applies to text buttons */
2454
+ .bs-button:where([data-size^='xs'][data-text]:not([data-text="false"])) {
2455
+ --btn-text-size: var(--bs-text-sm);
2347
2456
  }
2348
- /* not using gap on .bs-boolean due to dead click zone */
2349
- .bs-boolean label {
2350
- padding-inline-end: 0.5em;
2457
+ .bs-button:where([data-size^='xxs'][data-text]:not([data-text="false"])) {
2458
+ --btn-text-size: var(--bs-text-xs);
2459
+ --btn-weight: 600;
2351
2460
  }
2352
- .bs-boolean input + label {
2353
- padding-inline: 0.5em 0;
2461
+ /* ------------ Disabled Styling ------------ */
2462
+ :where(button:disabled),
2463
+ .bs-button:where(:disabled),
2464
+ .bs-button:where([aria-disabled="true"]) /* for links as buttons */ {
2465
+ pointer-events: none;
2354
2466
  }
2355
- .bs-boolean:where([data-size='sm']),
2356
- .bs-boolean:where([data-size='sm']) label {
2357
- font-size: var(--bs-text-xs);
2467
+ .bs-button:where(:disabled),
2468
+ .bs-button:where([aria-disabled="true"]) {
2469
+ --btn-ink: var(--bs-ink-disabled);
2470
+ --btn-main: var(--bs-bg-disabled);
2358
2471
  }
2359
- /* Checkbox & Radio Input */
2360
- :where(input[type='checkbox'], input[type='radio']),
2361
- :is(.bs-boolean :where(input), .bs-checkbox) { /* .bs-checkbox added to accommodate 'fake' cbs */
2362
- --box-shadow: var(--bs-ink-base);
2363
-
2364
- -webkit-appearance: none;
2365
-
2366
- -moz-appearance: none;
2367
-
2368
- appearance: none;
2369
- background-color: var(--bs-bg-base);
2370
- box-shadow: inset 0 0 0 0.125rem var(--box-shadow);
2371
- cursor: pointer;
2372
- display: grid;
2373
- height: 1rem;
2374
- margin: 0;
2375
- place-content: center;
2376
- position: relative;
2377
- width: 1rem;
2472
+ .bs-button:where([data-ghost]:not([data-ghost="false"])):disabled,
2473
+ .bs-button:where([data-ghost]:not([data-ghost="false"]))[aria-disabled="true"] {
2474
+ box-shadow: inset 0 0 0 1px var(--bs-gray-400);
2378
2475
  }
2379
- :where(input[type='checkbox'], input[type='radio']):focus-visible,
2380
- :is(.bs-boolean :where(input), .bs-checkbox):focus-visible {
2381
- box-shadow: inset 0 0 0 0.125rem var(--box-shadow),
2382
- 0 0 0 2px var(--offset-color, var(--bs-bg-base)),
2383
- 0 0 0 4px var(--outline-color, var(--bs-blue-base));
2384
- outline: 2px solid transparent;
2476
+ .bs-button:where([data-text]:not([data-text="false"])):disabled,
2477
+ .bs-button:where([data-text]:not([data-text="false"]))[aria-disabled="true"] {
2478
+ --btn-main: transparent;
2385
2479
  }
2386
- :where(input[type='checkbox']),
2387
- :is(.bs-boolean :where([type='checkbox']), .bs-checkbox) {
2388
- border-radius: 0.125rem;
2480
+ /* ------------ links as buttons ------------ */
2481
+ a.bs-button {
2482
+ align-items: center;
2483
+ display: inline-flex;
2484
+ outline: none;
2485
+ vertical-align: middle;
2389
2486
  }
2390
- :where(input[type='radio']),
2391
- .bs-boolean :where([type='radio']) {
2392
- border-radius: 50%;
2487
+ .bs-circle-button {
2488
+ --btn-main: var(--bs-blue-base);
2489
+ --btn-secondary: var(--bs-blue-medium);
2490
+ --btn-highlight: var(--bs-blue-lightest);
2491
+ --btn-border-color: transparent;
2492
+ --btn-border-radius: 50%;
2493
+ --btn-icon-bg-color: var(--btn-main);
2494
+ --btn-icon-padding: .75rem;
2495
+ --btn-icon-size: 1.5rem;
2496
+ --btn-icon-stroke-color: var(--bs-white);
2497
+ --btn-text-color: var(--bs-ink-base);
2498
+ --btn-text-size: var(--bs-text-md);
2499
+ align-items: center;
2500
+ background-color: transparent;
2501
+ border-radius: var(--btn-border-radius);
2502
+ color: var(--btn-text-color);
2503
+ cursor: pointer;
2504
+ display: inline-flex;
2505
+ font-size: var(--btn-text-size);
2506
+ gap: .5rem;
2507
+ outline: none;
2508
+ position: relative;
2509
+ vertical-align: middle;
2393
2510
  }
2394
- /* Checkbox's checkmark */
2395
- input:where([type='checkbox'])::before,
2396
- :is(.bs-boolean :where([type="checkbox"]), .bs-checkbox)::before {
2397
- --filled-size: 1rem;
2398
- --check-fill-color: var(--bs-blue-base);
2399
-
2400
- content: '';
2401
- border-radius: 0.125rem;
2402
- box-shadow: inset var(--filled-size) var(--filled-size) var(--check-fill-color);
2403
- height: var(--filled-size);
2404
- visibility: hidden;
2405
- width: var(--filled-size);
2511
+ a.bs-circle-button {
2512
+ align-items: center;
2513
+ display: inline-flex;
2514
+ outline: none;
2515
+ text-decoration: none;
2406
2516
  }
2407
- input:where([type='checkbox'])::after,
2408
- :is(.bs-boolean :where([type="checkbox"]), .bs-checkbox)::after {
2409
- border: solid var(--bs-white);
2410
- border-width: 0 0.125rem 0.125rem 0;
2411
- content: '';
2412
- height: 0.75em;
2413
- left: 50%;
2517
+ .bs-circle-button :where(.bs-circle-button-icon)::before {
2518
+ border-color: var(--btn-border-color);
2519
+ border-radius: var(--btn-border-radius);
2520
+ border-style: solid;
2521
+ border-width: 0.125rem;
2522
+ height: calc(100% + 0.5rem);
2523
+ inset: -0.25rem;
2414
2524
  position: absolute;
2415
- top: 50%;
2416
- transform-origin: center;
2417
- transform: translate(-50%, -60%) rotate(45deg);
2418
- visibility: hidden;
2419
- width: 0.375em;
2525
+ transition: border-color 125ms ease-in-out, transform 100ms ease-in-out;
2526
+ width: calc(100% + 0.5rem);
2420
2527
  }
2421
- input:where([type='checkbox']):where(:indeterminate)::after,
2422
- .bs-boolean :where([type="checkbox"]):where(:indeterminate)::after,
2423
- .bs-checkbox:where([data-indeterminate="true"], :indeterminate)::after {
2528
+ .bs-circle-button :where(.bs-circle-button-icon) {
2529
+ align-items: center;
2530
+ background-color: var(--btn-icon-bg-color);
2424
2531
  border: none;
2425
- background-color: var(--bs-white);
2426
- height: 0.125rem;
2427
- transform: translate(-50%, -0.0625rem) rotate(0deg);
2428
- width: 0.625em;
2429
- }
2430
- /* Radio's dot */
2431
- input:where([type='radio'])::before,
2432
- .bs-boolean :where([type="radio"])::before {
2433
- --filled-size: 1rem;
2434
- --radio-fill-color: var(--bs-blue-base);
2435
-
2436
- background-color: var(--radio-fill-color);
2437
2532
  border-radius: 50%;
2438
- box-sizing: content-box;
2439
- content: '';
2440
- height: var(--filled-size);
2441
- visibility: hidden;
2442
- width: var(--filled-size);
2533
+ color: var(--btn-icon-stroke-color);
2534
+ display: inline-flex;
2535
+ justify-content: center;
2536
+ outline: 2px solid transparent;
2537
+ padding: var(--btn-icon-padding);
2538
+ position: relative;
2539
+ transition: all 100ms ease-in-out;
2443
2540
  }
2444
- input:where([type='radio'])::after,
2445
- .bs-boolean :where([type="radio"])::after {
2446
- --inner-size: 0.375rem;
2447
- --inner-fill-color: var(--bs-white);
2448
-
2449
- background-color: var(--inner-fill-color);
2450
- border-radius: 50%;
2451
- box-sizing: content-box;
2452
- content: '';
2453
- height: var(--inner-size);
2454
- left: 50%;
2455
- position: absolute;
2456
- top: 50%;
2457
- transform: translate(-50%, -50%);
2458
- visibility: hidden;
2459
- width: var(--inner-size);
2541
+ .bs-circle-button :where(.bs-circle-button-icon) :where(.bs-icon) {
2542
+ --icon-size: var(--btn-icon-size);
2460
2543
  }
2461
- /* Show checkmark, indeterminate mark, or radio dot */
2462
- .bs-checkbox:where([data-indeterminate="true"], [data-checked="true"], :checked, :indeterminate)::before,
2463
- .bs-checkbox:where([data-indeterminate="true"], [data-checked="true"], :checked, :indeterminate)::after,
2464
- input:where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::before,
2465
- input:where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::after,
2466
- .bs-boolean :where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::before,
2467
- .bs-boolean :where([type='checkbox']:checked, [type='checkbox']:indeterminate, [type='radio']:checked)::after {
2468
- visibility: visible;
2544
+ /* non-bs-icon svgs */
2545
+ .bs-circle-button :where(.bs-circle-button-icon) > :where(svg) {
2546
+ height: var(--btn-icon-size);
2547
+ width: var(--btn-icon-size);
2469
2548
  }
2470
- .bs-boolean:where([data-size='sm']) input::before,
2471
- .bs-checkbox:where([data-size="sm"])::before {
2472
- --filled-size: var(--bs-text-xs);
2549
+ /* Icon Buttons with Text */
2550
+ .bs-circle-button:where([data-text]:not([data-text="false"])) {
2551
+ --btn-text-size: var(--bs-text-md);
2552
+ --btn-icon-size: 0.75rem;
2553
+ --btn-icon-padding: 0.375rem;
2473
2554
  }
2474
- .bs-boolean:where([data-size='sm']) input[type='checkbox']::after,
2475
- .bs-checkbox:where([data-size="sm"])::after {
2476
- height: 0.5625rem;
2477
- width: 0.3125rem;
2555
+ /* Ghost Buttons */
2556
+ .bs-circle-button:where([data-ghost]:not([data-ghost="false"])) {
2557
+ --btn-icon-stroke-color: var(--btn-main);
2558
+ --btn-light: var(--bs-blue-10);
2559
+ --btn-secondary: var(--bs-blue-10);
2478
2560
  }
2479
- .bs-boolean:where([data-size='sm']) input[type='checkbox']:where(:indeterminate)::after,
2480
- .bs-checkbox:where([data-size="sm"][data-indeterminate="true"], [data-size="sm"]:indeterminate)::after {
2481
- height: 0.125rem;
2482
- width: .75em;
2561
+ .bs-circle-button:where([data-ghost]:not([data-ghost="false"])) :where(.bs-circle-button-icon) {
2562
+ background-color: transparent;
2563
+ box-shadow: inset 0 0 0 1px transparent;
2564
+ color: var(--btn-icon-stroke-color);
2483
2565
  }
2484
- .bs-boolean:where([data-size='sm']) input[type='radio']::after {
2485
- --inner-size: 0.25rem;
2566
+ .bs-circle-button:where([data-ghost]:not([data-ghost="false"])) :where(.bs-circle-button-icon)::before {
2567
+ border-radius: 50%;
2486
2568
  }
2487
- /* Disabled State */
2488
- input:where([type='checkbox'], [type='radio']):disabled,
2489
- .bs-boolean :where(input):disabled,
2490
- .bs-checkbox:is([data-disabled="true"], :disabled) {
2491
- --box-shadow: var(--bs-bg-disabled);
2492
- background-color: transparent;
2493
- cursor: default;
2569
+ /* Active, Hover, Focus states */
2570
+ .bs-circle-button:active, .bs-circle-button:hover {
2571
+ --btn-icon-bg-color: var(--btn-secondary);
2494
2572
  }
2495
- .bs-checkbox:where([data-disabled="true"]:not(input)) {
2496
- pointer-events: none;
2573
+ .bs-circle-button:active :where(.bs-circle-button-icon) {
2574
+ transform: scale(0.97);
2575
+ transform-origin: center;
2576
+ box-shadow: inset 0px 0px 4px 1px var(--btn-main);
2497
2577
  }
2498
- input:where([type='checkbox']):checked:disabled::before,
2499
- input:where([type='checkbox']):indeterminate:disabled::before,
2500
- .bs-boolean :where(input[type="checkbox"]):checked:disabled::before,
2501
- .bs-boolean :where(input[type="checkbox"]):indeterminate:disabled::before,
2502
- .bs-checkbox:where([data-checked="true"][data-disabled="true"], :checked:disabled)::before,
2503
- .bs-checkbox:where([data-indeterminate="true"][data-disabled="true"], :indeterminate:disabled)::before {
2504
- --check-fill-color: var(--bs-bg-disabled);
2578
+ .bs-circle-button:where([data-direction="right"]):hover :where(.bs-circle-button-icon),
2579
+ .bs-circle-button:where([data-direction="right"]):hover::before {
2580
+ transform: translateX(.25rem);
2505
2581
  }
2506
- input:where([type='radio']):checked:disabled::before,
2507
- .bs-boolean :where(input[type="radio"]):checked:disabled::before {
2508
- --radio-fill-color: var(--bs-bg-disabled);
2582
+ .bs-circle-button:where([data-direction="left"]):hover :where(.bs-circle-button-icon),
2583
+ .bs-circle-button:where([data-direction="left"]):hover::before {
2584
+ transform: translateX(-.25rem);
2509
2585
  }
2510
- /* Error state */
2511
- input:where([type='checkbox'], [type='radio'])[data-error]:where(:not([data-error="false"])),
2512
- .bs-boolean :where(input[data-error="true"]),
2513
- .bs-checkbox:where([data-error="true"]) {
2514
- --box-shadow: var(--bs-red-base);
2515
- --outline-color: var(--bs-red-base);
2586
+ .bs-circle-button:where([data-ghost]:not([data-ghost="false"])):hover :where(.bs-circle-button-icon) {
2587
+ background-color: var(--btn-light);
2516
2588
  }
2517
- .bs-switch {
2518
- --box-shadow: var(--bs-ink-base);
2519
- --ball-background: var(--bs-white);
2520
- --ball-diameter: 1rem;
2521
- --inner-text-line-height: 1;
2522
- --inner-text-size: var(--bs-text-sm);
2523
- --inner-text-width: 1rem;
2524
- --inner-text-padding: 0.5rem;
2525
- --offset: 0.25rem;
2526
- --offset-double: .5rem;
2527
- --switch-background: var(--bs-gray-400);
2528
- --switch-height: 1.5rem;
2529
- --switch-width: 2.5rem;
2530
-
2531
- border: none;
2532
- border-radius: 100vw;
2533
- cursor: pointer;
2534
- height: var(--switch-height);
2535
- position: relative;
2589
+ .bs-circle-button:where([data-ghost]:not([data-ghost="false"])):active {
2590
+ box-shadow:
2591
+ inset 0 0 0 1px var(--btn-main),
2592
+ inset 0px 0px 4px 1px var(--btn-highlight);
2536
2593
  }
2537
- .bs-switch:where([data-size="sm"]) {
2538
- --ball-diameter: .625rem;
2539
- --inner-text-line-height: 1.6666;
2540
- --inner-text-size: var(--bs-text-xs);
2541
- --inner-text-width: .75rem;
2542
- --inner-text-padding: 0.375rem;
2543
- --offset: 0.1875rem;
2544
- --offset-double: .375rem;
2545
- --switch-height: 1rem;
2546
- --switch-width: 1.875rem;
2594
+ .bs-circle-button:where(:focus-visible) {
2595
+ --btn-border-color: var(--btn-main);
2547
2596
  }
2548
- .bs-switch input,
2549
- .bs-switch:where([data-size="sm"]) input {
2550
- cursor: pointer;
2551
- height: 100%;
2552
- opacity: 0;
2553
- position: absolute;
2554
- width: 100%;
2597
+ .bs-circle-button:where(:focus-visible) :where(.bs-circle-button-icon)::before {
2598
+ content: '';
2555
2599
  }
2556
- .bs-switch span {
2557
- align-items: center;
2558
- background-color: var(--switch-background);
2559
- border-radius: 100vw;
2560
- display: inline-block;
2561
- font-size: var(--inner-text-size);
2562
- height: 100%;
2563
- padding: 0 var(--inner-text-padding);
2600
+ /* Disabled State */
2601
+ .bs-circle-button:where(:disabled, [aria-disabled]:not([aria-disabled="false"])) /* for links as buttons */ {
2602
+ --btn-icon-stroke-color: var(--bs-ink-disabled);
2603
+ --btn-text-color: var(--bs-ink-disabled);
2564
2604
  pointer-events: none;
2565
- position: relative;
2566
- transition: 250ms;
2567
- width: var(--switch-width);
2568
2605
  }
2569
- .bs-switch :where(input:checked) ~ :where(span),
2570
- .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where(span) {
2571
- --switch-background: var(--bs-blue-base);
2606
+ .bs-circle-button:where(:disabled, [aria-disabled]:not([aria-disabled="false"])) :where(.bs-circle-button-icon) {
2607
+ background-color: var(--bs-bg-disabled);
2572
2608
  }
2573
- /* Toggle "ball" */
2574
- .bs-switch :where(span)::before {
2575
- background-color: var(--ball-background);
2576
- border-radius: 50%;
2577
- box-sizing: border-box;
2578
- content: '';
2579
- height: var(--ball-diameter);
2580
- left: var(--offset);
2581
- position: absolute;
2582
- top: 50%;
2583
- transform: translate(0, -50%);
2584
- transition: inherit;
2585
- width: var(--ball-diameter);
2586
- z-index: 2;
2609
+ /* Button Size */
2610
+ .bs-circle-button:where([data-size^='sm']) {
2611
+ --btn-icon-padding: .375rem;
2612
+ --btn-icon-size: .75rem;
2613
+ --btn-text-size: var(--bs-text-sm);
2587
2614
  }
2588
- .bs-switch :where(input:checked) ~ :where(span)::before,
2589
- .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where(span)::before {
2590
- transform: translate(calc(var(--switch-width) - var(--offset-double) - var(--ball-diameter)), -50%);
2615
+ .bs-circle-button:where([data-size^='sm'][data-text]:not([data-text="false"])) {
2616
+ --btn-icon-padding: .3125rem;
2617
+ --btn-icon-size: .625rem;
2618
+ --btn-text-size: var(--bs-text-base);
2591
2619
  }
2592
- .bs-switch :where(input:checked) ~ :where(span[data-inner-on-label][data-inner-off-label])::before,
2593
- .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where(span[data-inner-on-label][data-inner-off-label])::before {
2594
- transform: translate(calc(var(--switch-width) - var(--offset-double) - var(--ball-diameter)), -50%);
2620
+ .bs-circle-button:where([data-size='xs'][data-text]:not([data-text="false"])) {
2621
+ --btn-icon-padding: .25rem;
2622
+ --btn-icon-size: .5rem;
2623
+ --btn-text-size: var(--bs-text-sm);
2595
2624
  }
2596
- /* Inner "on/off" text */
2597
- .bs-switch :where(span)::after {
2625
+ /*
2626
+ custom properties:
2627
+ --filterbtn-caret-size
2628
+ --filterbtn-caret-transform
2629
+ --filterbtn-color
2630
+ --filterbtn-focus-color
2631
+ --filterbtn-height
2632
+ --filterbtn-text-size
2633
+ --filterbtn-weight
2634
+ */
2635
+ button:where(.bs-filter-button) {
2636
+ flex-shrink: 0;
2637
+ position: relative;
2638
+ }
2639
+ .bs-filter-button {
2598
2640
  align-items: center;
2599
- color: var(--ball-background);
2600
- content: var(--inner-label-text);
2601
- display: flex;
2641
+ color: var(--filterbtn-color, var(--bs-ink-blue));
2642
+ -moz-column-gap: 0.5rem;
2643
+ column-gap: 0.5rem;
2644
+ cursor: pointer;
2645
+ display: inline-flex;
2646
+ font-size: var(--filterbtn-text-size, var(--bs-text-base));
2647
+ font-weight: var(--filterbtn-weight, 400);
2648
+ height: var(--filterbtn-height, 1.5rem);
2649
+ line-height: 1.5;
2650
+ transition: outline-color 100ms ease-in-out;
2651
+ width: -moz-max-content;
2652
+ width: max-content;
2653
+ }
2654
+ .bs-filter-button::after {
2655
+ border: solid var(--filterbtn-focus-color, transparent) 2px;
2656
+ border-radius: 0.25rem;
2657
+ content: '';
2658
+ display: block;
2602
2659
  height: 100%;
2603
- justify-content: var(--inner-label-position, flex-start);
2604
- left: 0;
2605
- line-height: var(--inner-text-line-height);
2606
- padding: var(--inner-text-padding);
2607
2660
  position: absolute;
2608
- text-transform: capitalize;
2609
- top: 0;
2661
+ transform: scale(1.25);
2610
2662
  width: 100%;
2611
2663
  }
2612
- .bs-switch :where([data-inner-on-label][data-inner-off-label]) {
2613
- --switch-width: 3.5rem;
2664
+ .bs-filter-button :where(.bs-icon),
2665
+ .bs-filter-button :where(span:has(svg:only-child)) {
2666
+ display: block;
2667
+ height: var(--filterbtn-caret-size, 1rem);
2668
+ line-height: 1;
2669
+ transform: var(--filterbtn-caret-transform, rotate(0deg));
2670
+ transform-origin: center;
2671
+ transition: var(--bs-trans-rotate180);
2672
+ width: var(--filterbtn-caret-size, 1rem);
2614
2673
  }
2615
- .bs-switch:where([data-size="sm"]) :where([data-inner-on-label][data-inner-off-label]) {
2616
- --switch-width: 2.625rem;
2674
+ .bs-filter-button:where([data-size="sm"],[data-size="xs"]) {
2675
+
2676
+ --filterbtn-text-size: var(--bs-text-sm);
2677
+ --filterbtn-caret-size: .75rem;
2617
2678
  }
2618
- .bs-switch :where(input:not(:checked)) ~ :where([data-inner-on-label][data-inner-off-label])::after,
2619
- .bs-switch:where([aria-pressed="false"]) :where([data-inner-on-label][data-inner-off-label])::after {
2620
- --inner-label-position: flex-end;
2621
- --inner-label-text: attr(data-inner-off-label);
2679
+ .bs-filter-button:where([data-size="sm"]) {
2680
+ --filterbtn-text-size: var(--bs-text-sm);
2622
2681
  }
2623
- .bs-switch :where(input:checked) ~ :where([data-inner-on-label][data-inner-off-label])::after,
2624
- .bs-switch:where([aria-pressed]:not([aria-pressed="false"])) :where([data-inner-on-label][data-inner-off-label])::after {
2625
- --inner-label-text: attr(data-inner-on-label);
2682
+ .bs-filter-button:where([data-size="xs"]) {
2683
+ --filterbtn-text-size: var(--bs-text-xs);
2684
+ --filterbtn-weight: 600;
2685
+ }
2686
+ /* Hover state */
2687
+ .bs-filter-button:hover {
2688
+ --filterbtn-color: var(--bs-blue-base);
2626
2689
  }
2627
2690
  /* Focus state */
2628
- .bs-switch :where(input:focus-visible) + :where(span),
2629
- .bs-switch:where(:focus-visible) :where(button span) {
2630
- box-shadow: 0 0 0 2px var(--offset-color, var(--bs-bg-base)),
2631
- 0 0 0 4px var(--outline-color, var(--bs-blue-base));
2632
- outline: 2px solid transparent;
2691
+ .bs-filter-button:where(:focus-visible) {
2692
+ outline: none;
2693
+ --filterbtn-focus-color: var(--bs-blue-base);
2633
2694
  }
2634
- :where(.box) .bs-switch :where(input:focus-visible) + :where(span),
2635
- :where(.box) .bs-switch:where(:focus-visible) :where(button span) {
2636
- --offset-color: var(--bs-bg-medium);
2695
+ /* Filter open state */
2696
+ .bs-filter-button:where([aria-expanded="true"],[data-open="true"]) {
2697
+ --filterbtn-caret-transform: rotate(180deg);
2637
2698
  }
2638
- :where(.box[data-invert]) .bs-switch :where(input:focus-visible) + :where(span),
2639
- :where(.box[data-invert]) .bs-switch:where(:focus-visible) :where(button span) {
2640
- --offset-color: var(--bs-bg-invert-base);
2699
+ /* Badge non-standard color */
2700
+ .bs-filter-button :where(.bs-badge) {
2701
+ --badge-bg: var(--bs-ink-blue);
2641
2702
  }
2642
- /* Disabled state */
2643
- .bs-switch:where([data-disabled]:not([data-disabled="false"]), :disabled, [disabled]),
2644
- .bs-switch:where([data-disabled]:not([data-disabled="false"]), :disabled, [disabled]) :is(input ~ span, button span) {
2645
- --ball-background: var(--bs-ink-disabled);
2646
- --switch-background: var(--bs-bg-disabled);
2703
+ :where(.dark) .bs-filter-button :where(.bs-badge) {
2704
+ --badge-bg: var(--bs-blue-medium);
2647
2705
  }
2648
- .bs-switch input:where(:disabled) {
2649
- cursor: default;
2706
+ .bs-filter-button:hover :where(.bs-badge) {
2707
+ --badge-bg: var(--filterbtn-color);
2650
2708
  }
2651
- .bs-hint {
2652
- --hint-color: var(--bs-ink-light);
2653
- min-width: 0;
2654
- color: var(--hint-color);
2655
- font-size: var(--bs-text-xs);
2656
- padding: 0;
2657
- margin: 0;
2658
- list-style: none;
2659
- overflow-wrap: break-word;
2709
+ /* Disabled state */
2710
+ .bs-filter-button:where(:disabled) {
2711
+ --filterbtn-color: var(--bs-ink-disabled);
2712
+ cursor: default;
2660
2713
  }
2661
- .bs-hint:where([data-error]:not([data-error="false"])) {
2662
- --hint-color: var(--bs-ink-red);
2714
+ .bs-filter-button:where(:disabled) :where(.bs-badge) {
2715
+ --badge-bg: var(--bs-bg-disabled);
2716
+ --badge-text: var(--bs-ink-disabled);
2663
2717
  }
2664
2718
  .bs-modal {
2665
2719
  background-color: var(--bs-bg-base-elevated);
@@ -3320,6 +3374,7 @@ a.bs-profile:where([data-layout]):hover {
3320
3374
  justify-content: var(--tab-justify);
3321
3375
  line-height: 1.5;
3322
3376
  opacity: var(--tab-list-opacity);
3377
+ overflow: hidden;
3323
3378
  position: relative;
3324
3379
  width: 100%;
3325
3380
  }
@@ -3700,7 +3755,7 @@ table:where([data-sticky^="left"]) :is(td:first-child, th:first-child) {
3700
3755
  background-color: var(--bs-bg-base-elevated);
3701
3756
  border-radius: 4px;
3702
3757
  box-shadow: var(--bs-shadow-contentLowCenter);
3703
- color: var(--bs-violet-base);
3758
+ color: var(--bs-ink-violet);
3704
3759
  display: flex;
3705
3760
  font-size: var(--bs-text-sm);
3706
3761
  justify-content: center;