Merge pull request #11932 from dacook/buu-dropdown-tweaks-11518

[BUU] Dropdown UI tweaks (tom-select)
This commit is contained in:
Filipe
2024-01-12 11:41:07 +00:00
committed by GitHub
10 changed files with 124 additions and 66 deletions

View File

@@ -5,10 +5,14 @@
- if producer_options.many?
.producers
= label_tag :producer_id, t('.producers.label')
= select_tag :producer_id, options_for_select(producer_options, producer_id), include_blank: t('.all_producers'), "data-controller": "tom-select", "data-tom-select-options-value": '{ "plugins": [] }', class: "fullwidth"
= select_tag :producer_id, options_for_select(producer_options, producer_id),
include_blank: t('.all_producers'), class: "fullwidth",
data: { "controller": "tom-select", 'tom-select-placeholder-value': t('.search_for_producers')}
.categories
= label_tag :category_id, t('.categories.label')
= select_tag :category_id, options_for_select(category_options, category_id), include_blank: t('.all_categories'), "data-controller": "tom-select", "data-tom-select-options-value": '{ "plugins": [] }', class: "fullwidth"
= select_tag :category_id, options_for_select(category_options, category_id),
include_blank: t('.all_categories'), class: "fullwidth",
data: { "controller": "tom-select", 'tom-select-placeholder-value': t('.search_for_categories')}
.submit
.search-button
= button_tag t(".search"), class: "secondary icon-search relaxed"

View File

@@ -6,4 +6,4 @@
= t(".pagination.clear_search")
%form.with-dropdown
= t(".pagination.per_page.show")
= select_tag :per_page, options_for_select([15, 25, 50, 100].collect{|i| [t('.pagination.per_page.per_page', num: i), i]}, pagy.items), data: { reflex: "change->products#change_per_page" }
= select_tag :per_page, options_for_select([15, 25, 50, 100].collect{|i| [t('.pagination.per_page.per_page', num: i), i]}, pagy.items), class: "no-input per-page", data: { reflex: "change->products#change_per_page", controller: "tom-select", "tom-select-options-value": '{ "plugins": [] }'}

View File

@@ -2,26 +2,20 @@ import { Controller } from "stimulus";
import TomSelect from "tom-select/dist/esm/tom-select.complete";
export default class extends Controller {
static values = { options: Object };
static defaults = {
maxItems: 1,
maxOptions: null,
plugins: ["dropdown_input"],
allowEmptyOption: true,
closeAfterSelect: true,
onItemAdd: function () {
this.setTextboxValue("");
},
};
static values = { options: Object, placeholder: String };
connect(options = {}) {
if (this.#placeholder()) {
options.allowEmptyOption = false;
options.placeholder = this.#placeholder();
}
console.log(this.element, this.placeholderValue);
this.control = new TomSelect(this.element, {
...this.constructor.defaults,
maxItems: 1,
maxOptions: null,
plugins: ["dropdown_input"],
allowEmptyOption: true, // Show blank option (option with empty value)
closeAfterSelect: true,
placeholder: this.placeholderValue || this.#emptyOption(),
onItemAdd: function () {
this.setTextboxValue("");
},
...this.optionsValue,
...options,
});
@@ -33,7 +27,7 @@ export default class extends Controller {
// private
#placeholder() {
#emptyOption() {
const optionsArray = [...this.element.options];
return optionsArray.find((option) => [null, ""].includes(option.value))?.text;
}

View File

@@ -198,9 +198,7 @@
display: flex;
justify-content: space-between;
align-items: center;
}
#sort {
line-height: $btn-relaxed-height;
height: $btn-relaxed-height;
@@ -214,29 +212,21 @@
align-items: center;
gap: 10px;
}
.per-page {
width: 10em;
}
}
#filters {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: 1fr;
grid-column-gap: 20px;
display: flex;
column-gap: 20px;
align-items: end;
margin-bottom: 1rem;
.query {
grid-column: 1 / span 3;
}
flex-grow: 1;
min-width: 15em;
.producers,
.categories {
}
.submit {
grid-column: 6 / span 1;
}
.query {
.search-input {
width: 100%;
position: relative;
@@ -270,10 +260,7 @@
.producers,
.categories {
select {
width: 150px;
height: $btn-relaxed-height;
}
width: 15em;
}
.submit {

View File

@@ -11,7 +11,6 @@
box-shadow: none !important;
@include border-radius($border-radius);
color: $color-1 !important;
font-size: 90%;
height: 31px;
line-height: inherit !important;
padding: 5px 15px 7px;
@@ -23,7 +22,6 @@
.select2-search-choice-close {
background-image: none !important;
font-size: 100% !important;
@extend .icon-remove;
@extend [class^="icon-"], :before;
margin-top: 2px;
@@ -54,7 +52,6 @@
.select2-search {
@extend .icon-search;
font-size: 100%;
color: darken($color-border, 15);
padding: 0 9px 0 0;
@@ -72,7 +69,6 @@
padding: 6px 0 6px 25px;
margin: 5px 0 0 5px;
font-family: $base-font-family;
font-size: 90%;
box-shadow: none;
background-image: none;
}
@@ -102,8 +98,6 @@
padding-left: 0 !important;
li {
font-size: 85% !important;
&.select2-highlighted {
.select2-result-label {
&,
@@ -117,7 +111,6 @@
color: $color-body-text;
min-height: 22px;
clear: both;
overflow: auto;
}
&.select2-no-results,
@@ -160,7 +153,6 @@
border: none;
box-shadow: none;
color: $color-1 !important;
font-size: 85%;
&:hover {
background-color: $color-btn-hover-bg;
@@ -168,7 +160,6 @@
.select2-search-choice-close {
background-image: none !important;
font-size: 85% !important;
@extend .icon-remove;
@extend [class^="icon-"], :before;
margin-left: 2px;
@@ -248,7 +239,6 @@ label .select2-container {
top: 0;
margin: 0;
padding: 0;
font-size: 100% !important;
}
}
}

View File

@@ -4,11 +4,12 @@
&.input-active {
.ts-control {
border-color: $lighter-grey;
border-color: $orient;
background-color: $lighter-grey;
input {
&::placeholder {
color: $light-grey;
color: $medium-light-grey;
}
}
}
@@ -22,24 +23,42 @@
@include border-radius($border-radius);
input {
font-size: $body-font-size;
height: auto;
&::placeholder {
color: $near-black;
}
}
.item {
margin-top: 2px; // Ensure it lines up with the input. I have no idea why it's necessary.
}
}
.ts-dropdown {
@include border-radius($border-radius);
// Unstyled, we style the dropdown-content instead
margin: 0;
background: none;
border: none;
box-shadow: none;
}
.ts-dropdown-content {
margin-top: 4px;
color: $near-black;
background-color: $color-body-bg;
@include border-radius($border-radius);
box-shadow: $shadow-dropdown;
.option {
&.selected {
border-left: 2px solid $orient;
}
padding: 8px;
border-left: 3px solid transparent;
line-height: 20px;
&.selected,
&.active {
border-left: 3px solid $orient;
background-color: $lighter-grey;
color: $near-black;
}
@@ -47,21 +66,80 @@
}
}
.plugin-dropdown_input .dropdown-input {
border-color: $lighter-grey;
.plugin-dropdown_input {
.ts-dropdown {
// Cover up the control with the input
top: 0;
}
&:focus {
border-color: $orient;
.dropdown-input-wrap::after {
position: absolute;
content: "\f077"; // chevron-up
font-family: FontAwesome;
border: none;
top: 0.7rem;
right: 0.7rem;
font-size: 13px;
}
.dropdown-input {
background-color: $color-body-bg;
border: 1px solid $lighter-grey;
box-shadow: none;
padding: 0.6rem 0.75rem;
&:focus {
border: 1px solid $orient;
}
}
}
// For the "single" tom_select, be as clause as native select boxes
// For the "single" tom_select, be as close as possible to native select boxes
// without too many options
.ts-wrapper.single {
max-height: 40px;
max-width: 100%;
&.input-active .ts-control {
cursor: pointer;
.ts-control {
padding: 0.5rem 0.75rem;
padding-right: 1rem !important; // ts has a clever variable-based rule here, but it doesn't seem to work right.
overflow: hidden;
// Icon: Override TS icon with icon-chevron-down
&::after {
content: "\f078";
font-family: FontAwesome;
border: none;
top: 1em;
}
&:not(.rtl)::after {
right: 1.5rem;
}
.item {
margin-right: 1rem;
// Hide overflow with an ellipsis if a width has been set
overflow: hidden;
text-overflow: ellipsis;
text-wrap: nowrap;
}
}
&.dropdown-active .ts-control {
&::after {
content: "\f077"; // chevron-up
}
}
}
// 'no-input' mode, like a native select (hide text input).
.ts-wrapper.single.no-input {
.ts-dropdown {
position: absolute;
top: 0; // we don't need to see the currently selected option, because it's visible in the dropdown
}
.ts-dropdown-content {
margin-top: 0;
}
}

View File

@@ -11,6 +11,7 @@ $yellow: #ff9300 !default; // Yellow
$mystic: #d9e8eb !default; // Mystic
$lighter-grey: #f8f9fa !default; // Lighter grey
$light-grey: #eff1f2 !default; // Light grey (Porcelain)
$medium-light-grey: #babdbe !default; // Silver Sand
$medium-grey: #919191 !default; // Medium grey
$dark-grey: #2e3132 !default; // Dark Grey
$near-black: #191c1d !default; // Near-black (Shark)

View File

@@ -74,6 +74,9 @@ $color-action-save-brd: very-light($color-success, 20 ) !default;
$color-action-mail-bg: very-light($color-success, 5 ) !default;
$color-action-mail-brd: very-light($color-success, 20 ) !default;
// Dropdown styles
$shadow-dropdown: 0px 0px 8px 0px rgba($near-black, 0.25);
// Select2 select field colors
$color-sel-bg: $lighter-grey !default;
$color-sel-hover-bg: $lighter-grey !default;

View File

@@ -19,7 +19,6 @@ fieldset {
padding: $vpadding-txt $hpadding-txt;
border: 1px solid $lighter-grey;
color: $color-txt-text;
font-size: 90%;
background-color: $lighter-grey;
&:focus {

View File

@@ -839,7 +839,9 @@ en:
clear_search: Clear search
filters:
search_products: Search for products
search_for_producers: Search for producers
all_producers: All producers
search_for_categories: Search for categories
all_categories: All categories
producers:
label: Producers