From 5feeac60661e50cc8aeee1a34c09fc545272ff08 Mon Sep 17 00:00:00 2001 From: Jeff Sagal Date: Fri, 22 Oct 2021 12:12:42 -0700 Subject: [PATCH] WIP - use `grid` instead of `flex` in dropdown-menu - make long values centered by dropping the height of the search input to zero when select is filled --- .../components/OptionWrapStrategy.vue | 18 +++++ docs/guide/css.md | 69 ++++++++++++++----- src/components/Select.vue | 2 + src/scss/modules/_dropdown-menu.scss | 42 +++++------ src/scss/modules/_search-input.scss | 56 ++++++++------- 5 files changed, 127 insertions(+), 60 deletions(-) create mode 100644 docs/.vuepress/components/OptionWrapStrategy.vue diff --git a/docs/.vuepress/components/OptionWrapStrategy.vue b/docs/.vuepress/components/OptionWrapStrategy.vue new file mode 100644 index 0000000..ede0b7a --- /dev/null +++ b/docs/.vuepress/components/OptionWrapStrategy.vue @@ -0,0 +1,18 @@ + + + diff --git a/docs/guide/css.md b/docs/guide/css.md index 20f28e5..97de7bd 100644 --- a/docs/guide/css.md +++ b/docs/guide/css.md @@ -1,17 +1,17 @@ -Vue Select offers many APIs for customizing the look and feel from the component. You can use -[scoped slots](../api/slots.md), [custom child components](components.md), or modify the built in -SCSS variables. +Vue Select offers many APIs for customizing the look and feel from the component. You can use +[scoped slots](../api/slots.md), [custom child components](components.md), or modify the built in +SCSS variables. -::: tip -Support for CSS variables (custom properties) is currently on the road map for those -that are not using sass in their projects. -::: +::: tip Support for CSS variables (custom properties) is currently on the road map for those that +are not using sass in their projects. +::: ## SCSS Variables Variables are leveraged in as much of the component styles as possible. If you really want to dig into the SCSS, the files are located in `src/scss`. The variables listed below can be found at -[`src/scss/global/_variables`](https://github.com/sagalbot/vue-select/blob/master/src/scss/global/_variables.scss). +[`src/scss/global/_variables`](https://github.com/sagalbot/vue-select/blob/master/src/scss/global/_variables.scss) +. All variables are implemented with `!default` in order to make them easier to override in your application. @@ -23,12 +23,12 @@ application. Vue Select takes the approach of using selectors with a single level of specificity, while using classes that are very specific to Vue Select to avoid collisions with your app. -All classes within Vue Select use the `vs__` prefix, and selectors are generally a single classname +All classes within Vue Select use the `vs__` prefix, and selectors are generally a single classname – unless there is a state being applied to the component. -In order to override a default property in your app, you should add one level of specificity. -The easiest way to do this, is to add `.v-select` before the `vs__*` selector if you want to adjust -all instances of Vue Select, or add your own classname if you just want to affect one. +In order to override a default property in your app, you should add one level of specificity. The +easiest way to do this, is to add `.v-select` before the `vs__*` selector if you want to adjust all +instances of Vue Select, or add your own classname if you just want to affect one. @@ -38,17 +38,18 @@ all instances of Vue Select, or add your own classname if you just want to affec By default, the dropdown transitions with a `.15s` cubic-bezier opacity fade in/out. The component uses the [VueJS transition system](https://vuejs.org/v2/guide/transitions.html). By default, the - transition name is `vs__fade`. There's a couple ways to override or change this transition. +transition name is `vs__fade`. There's a couple ways to override or change this transition. 1. Use the `transition` prop. Applying this prop will change the name of the animation classes and -negate the default CSS. If you want to remove it entirely, you can set it to an empty string. + negate the default CSS. If you want to remove it entirely, you can set it to an empty string. ```html + ``` -2. You can also override the default CSS for the `vs__fade` transition. Again, if you -wanted to eliminate the transition entirely: +2. You can also override the default CSS for the `vs__fade` transition. Again, if you wanted to + eliminate the transition entirely: ```css .vs__fade-enter-active, @@ -56,3 +57,39 @@ wanted to eliminate the transition entirely: transition: none; } ``` + +## Option Wrapping Strategy + +When options in the dropdown are wider than the dropdown itself, there are three strategies +available. The strategy can be set with the `dropdownOptionWrap` prop. This prop accepts one of +three strings: + +### `wrap` + +Break options that are wider than the dropdown onto the next line. No horizontal scrollbar. + +```vue + +``` + + + +### `truncate` + +Truncate options that are wider than the dropdown using an ellipsis `...`. No horizontal scrollbar. + +```vue + +``` + + + +### `nowrap` + +Don't wrap or truncate options wider than the dropdown. Introduces horizontal scrollbar. + +```vue + +``` + + diff --git a/src/components/Select.vue b/src/components/Select.vue index aabaace..a2b9c0b 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -835,6 +835,8 @@ export default { 'vs--open': this.dropdownOpen, 'vs--single': !this.multiple, 'vs--multiple': this.multiple, + 'vs--empty': this.selectedValue.length === 0, + 'vs--not-empty': this.selectedValue.length !== 0, 'vs--searching': this.searching && !this.noDrop, 'vs--searchable': this.searchable && !this.noDrop, 'vs--unsearchable': !this.searchable, diff --git a/src/scss/modules/_dropdown-menu.scss b/src/scss/modules/_dropdown-menu.scss index 3e1af38..521d08a 100644 --- a/src/scss/modules/_dropdown-menu.scss +++ b/src/scss/modules/_dropdown-menu.scss @@ -12,27 +12,29 @@ $min-width: $vs-dropdown-min-width; $max-height: $vs-dropdown-max-height; .vs__dropdown-menu { - display: block; - box-sizing: border-box; - position: absolute; - top: calc(100% - #{$border-width}); // -{#$border-width} here ensures the left and right borders of the dropdown appear flush with the toggle. - left: 0; - z-index: $z-index; - padding: 5px 0; - margin: 0; - width: 100%; - max-height: $max-height; - min-width: $min-width; - overflow-y: auto; - box-shadow: $box-shadow; - border: $border-width $border-style $border-color; - border-top-style: none; - border-radius: 0 0 $border-radius $border-radius; - text-align: left; - list-style: none; - background: $bg-color; + display: grid; + box-sizing: border-box; + position: absolute; + top: calc( + 100% - #{$border-width} + ); // -{#$border-width} here ensures the left and right borders of the dropdown appear flush with the toggle. + left: 0; + z-index: $z-index; + padding: 5px 0; + margin: 0; + width: 100%; + max-height: $max-height; + min-width: $min-width; + overflow-y: auto; + box-shadow: $box-shadow; + border: $border-width $border-style $border-color; + border-top-style: none; + border-radius: 0 0 $border-radius $border-radius; + text-align: left; + list-style: none; + background: $bg-color; } .vs__no-options { - text-align: center; + text-align: center; } diff --git a/src/scss/modules/_search-input.scss b/src/scss/modules/_search-input.scss index 892fae3..6bcc61a 100644 --- a/src/scss/modules/_search-input.scss +++ b/src/scss/modules/_search-input.scss @@ -9,54 +9,62 @@ $font-size: 1em; * If it's up here on it's own, it'll hide it. */ .vs__search::-webkit-search-cancel-button { - display: none; + display: none; } .vs__search::-webkit-search-decoration, .vs__search::-webkit-search-results-button, .vs__search::-webkit-search-results-decoration, .vs__search::-ms-clear { - display: none; + display: none; } .vs__search, .vs__search:focus { - appearance: none; - line-height: $line-height; - font-size: $font-size; - border: 1px solid transparent; - border-left: none; - outline: none; - margin: 4px 0 0 0; - padding: 0 7px; - background: none; - box-shadow: none; - width: 0; - max-width: 100%; - flex-grow: 1; - z-index: 1; + appearance: none; + line-height: $line-height; + font-size: $font-size; + border: 1px solid transparent; + border-left: none; + outline: none; + margin: 4px 0 0 0; + padding: 0 7px; + background: none; + box-shadow: none; + width: 0; + max-width: 100%; + flex-grow: 1; + z-index: 1; } .vs__search::placeholder { - color: $vs-component-placeholder-color; + color: $vs-component-placeholder-color; } /** States */ +// Empty +.vs--not-empty .vs__search { + height: 0; +} +.vs--not-empty .vs__search:focus { + height: auto; +} + // Unsearchable .vs--unsearchable { - .vs__search { - opacity: 1; - } - &:not(.vs--disabled) .vs__search { - cursor: pointer; - } + .vs__search { + opacity: 1; + } + &:not(.vs--disabled) .vs__search { + cursor: pointer; + } } // Single, when searching but not loading or open .vs--single.vs--searching:not(.vs--open):not(.vs--loading) { .vs__search { - opacity: .2; + opacity: 0.2; } }