Skip to content

Instantly share code, notes, and snippets.

@coorasse
Created February 16, 2024 15:19
Show Gist options
  • 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;
}
}
@Xon
Copy link

Xon commented Aug 25, 2024

You'll want to import this CSS/SCSS change: Choices-js/Choices@1c43069

@Xon
Copy link

Xon commented Aug 25, 2024

@coorasse would you mind adding a pull request to add a choices-bootstrap.scss ? I'll then bundle that into the distribution and automatically generate a .css file.

@speed65
Copy link

speed65 commented Sep 19, 2024

Newb here, I think this will theme the choices components to look like bootstrap is that correct? If so, how do I do that? I'm not sure where to put this choices.scss file and how to make it work. Thank you for any help.

@coorasse
Copy link
Author

Hi @Xon , in order to generate the final CSS, you'd need to include also bootstrap, because it requires bootstrap scss variables. I don't think it can be bundled together. But you can bundle the scss!

@jakenuts
Copy link

Silly question, but what are the minimal other files you need to import/use to compile this? I'm a bit of a noob with sass and so far I've learned that if I import, I get two copies of everything so I try to 'use' when possible but the order & such escapes me here.

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