Skip to content

Instantly share code, notes, and snippets.

@coorasse
Created February 16, 2024 15:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coorasse/51efbdab14afe721e0832b95231f185c to your computer and use it in GitHub Desktop.
Save coorasse/51efbdab14afe721e0832b95231f185c to your computer and use it in GitHub Desktop.
choices.js - bootstrap5 theme
@use "sass:color";
$choices-selector: "choices" !default;
$choices-font-size-lg: $font-size-lg !default;
$choices-font-size-md: $font-size-base !default;
$choices-font-size-sm: $font-size-sm !default;
$choices-border-radius: var(--bs-border-radius) !default;
$choices-border-radius-item: 20px !default;
$choices-bg-color: var(--bs-body-bg) !default;
$choices-bg-color-disabled: #eaeaea !default;
$choices-bg-color-dropdown: #fff !default;
$choices-keyline-color: #ddd !default;
$choices-primary-color: #00bcd4 !default;
$choices-disabled-color: #eaeaea !default;
$choices-highlight-color: $choices-primary-color !default;
$choices-button-dimension: 8px !default;
$choices-button-offset: 8px !default;
$choices-icon-cross: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==") !default;
$choices-icon-cross-inverse: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==") !default;
$choices-z-index: 1 !default;
.#{$choices-selector} {
position: relative;
overflow: hidden;
font-size: $choices-font-size-lg;
&:focus {
outline: none;
}
&:last-child {
margin-bottom: 0;
}
&.is-open {
overflow: visible;
}
&.is-focused:not(.is-open) {
border-color: $form-select-focus-border-color;
border-radius: $choices-border-radius;
outline: 0;
@if $enable-shadows {
@include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $form-select-focus-box-shadow;
}
.#{$choices-selector}__inner {
border-color: $form-select-focus-border-color;
}
}
&.is-disabled {
.#{$choices-selector}__inner,
.#{$choices-selector}__input {
background-color: $choices-bg-color-disabled;
cursor: not-allowed;
user-select: none;
}
.#{$choices-selector}__item {
cursor: not-allowed;
}
}
[hidden] {
display: none !important;
}
.#{$choices-selector}__inner {
border-radius: $choices-border-radius;
}
}
.#{$choices-selector}[data-type*='select-one'] {
cursor: pointer;
.#{$choices-selector}__input {
display: block;
width: 100%;
border-bottom: 1px solid $choices-keyline-color;
background-color: #fff;
margin: 0;
}
.#{$choices-selector}__button {
background-image: $choices-icon-cross-inverse;
padding: 0;
background-size: 8px;
position: absolute;
top: 50%;
right: 0;
margin-top: -10px;
margin-right: 25px;
height: 20px;
width: 20px;
border-radius: 10em;
opacity: 0.25;
&:hover,
&:focus {
opacity: 1;
}
&:focus {
box-shadow: 0 0 0 2px $choices-highlight-color;
}
}
.#{$choices-selector}__item[data-value=''] .#{$choices-selector}__button {
display: none;
}
&.is-open::after {
margin-top: -7.5px;
}
&[dir="rtl"] {
&::after {
left: 11.5px;
right: auto;
}
.#{$choices-selector}__button {
right: auto;
left: 0;
margin-left: 25px;
margin-right: 0;
}
}
}
.#{$choices-selector}[data-type*='select-multiple'],
.#{$choices-selector}[data-type*='text'] {
.#{$choices-selector}__inner {
cursor: text;
}
.#{$choices-selector}__button {
position: relative;
display: inline-block;
margin: 0 -$choices-button-offset * 0.5 0 $choices-button-offset;
padding-left: $choices-button-offset * 2;
border-left: 1px solid color.adjust($choices-primary-color, $lightness: -10%);
background-image: $choices-icon-cross;
background-size: $choices-button-dimension;
width: $choices-button-dimension;
line-height: 1;
opacity: 0.75;
border-radius: 0;
&:hover,
&:focus {
opacity: 1;
}
}
}
.#{$choices-selector}__inner {
@extend .form-select;
display: inline-block;
vertical-align: top;
width: 100%;
background-color: $choices-bg-color;
border: var(--bs-border-width) solid var(--bs-border-color);
font-size: $choices-font-size-md;
overflow: hidden;
.is-open & {
border-radius: $choices-border-radius $choices-border-radius 0 0;
}
.is-flipped.is-open & {
border-radius: 0 0 $choices-border-radius $choices-border-radius;
}
}
.#{$choices-selector}__list {
margin: 0;
padding-left: 0;
list-style: none;
&[aria-expanded] {
@extend %choices-dropdown;
}
}
.#{$choices-selector}__list--single {
display: inline-block;
width: 100%;
[dir="rtl"] & {
padding-right: 4px;
padding-left: 16px;
}
.#{$choices-selector}__item {
width: 100%;
}
}
.#{$choices-selector}__list--multiple {
display: inline;
.#{$choices-selector}__item {
display: inline-block;
vertical-align: middle;
border-radius: $choices-border-radius-item;
padding: 4px 10px;
font-size: $choices-font-size-sm;
font-weight: 500;
margin-right: 3.75px;
margin-bottom: 3.75px;
background-color: $choices-primary-color;
border: 1px solid color.adjust($choices-primary-color, $lightness: -5%);
color: #fff;
word-break: break-all;
box-sizing: border-box;
&[data-deletable] {
padding-right: 5px;
}
[dir="rtl"] & {
margin-right: 0;
margin-left: 3.75px;
}
&.is-highlighted {
background-color: color.adjust($choices-primary-color, $lightness: -5%);
border: 1px solid color.adjust($choices-primary-color, $lightness: -10%);
}
.is-disabled & {
background-color: color.adjust($choices-disabled-color, $lightness: -25%);
border: 1px solid color.adjust($choices-disabled-color, $lightness: -35%);
}
}
}
%choices-dropdown {
visibility: hidden;
z-index: $choices-z-index;
position: absolute;
width: 100%;
background-color: $choices-bg-color-dropdown;
border: 1px solid var(--bs-border-color);
top: 0; // change to 100% to have it on the bottom of the input field
margin-top: -1px;
border-radius: $choices-border-radius;
overflow: hidden;
word-break: break-all;
will-change: visibility;
[data-type="select-multiple"] & {
top: 100%;
}
&.is-active {
visibility: visible;
}
.is-open & {
border-color: $form-select-focus-border-color;
border-top: 0;
outline: 0;
@if $enable-shadows {
@include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $form-select-focus-box-shadow;
}
}
.is-flipped & {
top: auto;
bottom: 100%;
margin-top: 0;
margin-bottom: -1px;
border-radius: 0.25rem 0.25rem 0 0;
}
.#{$choices-selector}__list {
position: relative;
max-height: 300px;
overflow: auto;
-webkit-overflow-scrolling: touch;
will-change: scroll-position;
}
.#{$choices-selector}__item {
position: relative;
padding: 10px;
font-size: $choices-font-size-md;
[dir="rtl"] & {
text-align: right;
}
}
.#{$choices-selector}__item--selectable {
@media (min-width: 640px) {
padding-right: 100px;
&::after {
content: attr(data-select-text);
font-size: $choices-font-size-sm;
opacity: 0;
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
}
[dir="rtl"] & {
text-align: right;
padding-left: 100px;
padding-right: 10px;
&::after {
right: auto;
left: 10px;
}
}
}
&.is-highlighted {
background-color: color.mix(#000, #fff, 5%);
&::after {
opacity: 0.5;
}
}
}
}
.#{$choices-selector}__list--dropdown {
@extend %choices-dropdown;
}
.#{$choices-selector}__item {
cursor: default;
}
.#{$choices-selector}__item--selectable {
cursor: pointer;
}
.#{$choices-selector}__item--disabled {
cursor: not-allowed;
user-select: none;
opacity: 0.5;
}
.#{$choices-selector}__heading {
font-weight: 600;
//font-size: $choices-font-size-sm;
padding: 10px;
border-bottom: 1px solid color.adjust($choices-keyline-color, $lightness: 10%);
color: color.adjust(#333, $lightness: 30%);
}
.#{$choices-selector}__button {
text-indent: -9999px;
appearance: none;
border: 0;
background-color: transparent;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
&:focus {
outline: none;
}
}
.#{$choices-selector}__input {
display: inline-block;
vertical-align: baseline;
background-color: $choices-bg-color;
font-size: $choices-font-size-md;
margin-bottom: 5px;
border: 0;
border-radius: 0;
max-width: 100%;
padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
&:focus {
outline: 0;
}
&::-webkit-search-decoration,
&::-webkit-search-cancel-button,
&::-webkit-search-results-button,
&::-webkit-search-results-decoration {
display: none;
}
&::-ms-clear,
&::-ms-reveal {
display: none;
width: 0;
height: 0;
}
[dir="rtl"] & {
padding-right: 2px;
padding-left: 0;
}
}
@coorasse
Copy link
Author

I realised this scss file for choices integration with bootstrap 5.3.
The file makes use as much as possible of already existing bootstrap mixins and variables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment