Select / Search CSS:

- Promote image styling from Et2LinkAppSelect to all Selects
- fix double scrollbar if there are a lot of options
- different cursor for editable tags
- align +# right to make it stand out a little more
This commit is contained in:
nathan 2022-06-10 14:11:57 -06:00
parent a7cafb590c
commit 1215626473
4 changed files with 68 additions and 97 deletions

View File

@ -25,12 +25,6 @@ export class Et2LinkAppSelect extends SlotMixin(Et2Select)
border: none;
box-shadow: initial;
}
et2-image {
width: var(--icon-width);
}
::slotted(img), img {
vertical-align: middle;
}
`
]
}

View File

@ -9,7 +9,6 @@
import {css, html, PropertyValues, TemplateResult} from "@lion/core";
import {cssImage} from "../Et2Widget/Et2Widget";
import {StaticOptions} from "./StaticOptions";
import {Et2widgetWithSelectMixin} from "./Et2WidgetWithSelectMixin";
import {SelectOption} from "./FindSelectOptions";
@ -36,26 +35,7 @@ export class Et2Select extends Et2WithSearchMixin(Et2InvokerMixin(Et2WidgetWithS
css`
:host {
display: block;
}
select {
width: 100%
color: var(--input-text-color, #26537c);
border-radius: 3px;
flex: 1 0 auto;
padding-top: 4px;
padding-bottom: 4px;
padding-right: 20px;
border-width: 1px;
border-style: solid;
border-color: #e6e6e6;
-webkit-appearance: none;
-moz-appearance: none;
margin: 0;
background: #fff no-repeat center right;
background-image: ${cssImage('arrow_down')};
background-size: 8px auto;
background-position-x: calc(100% - 8px);
text-indent: 5px;
--icon-width: 20px;
}
/* This is the drop-down arrow on the right */
@ -65,6 +45,16 @@ export class Et2Select extends Et2WithSearchMixin(Et2InvokerMixin(Et2WidgetWithS
color: gray !important;
}
::slotted(img), img {
vertical-align: middle;
}
/* Avoid double scrollbar if there are a lot of options */
.select__menu
{
max-height: initial;
}
select:hover {
box-shadow: 1px 1px 1px rgb(0 0 0 / 60%);
}`
@ -278,7 +268,8 @@ export class Et2Select extends Et2WithSearchMixin(Et2InvokerMixin(Et2WidgetWithS
_optionTemplate(option : SelectOption) : TemplateResult
{
let icon = option.icon ? html`
<et2-image slot="prefix" src="${option.icon}"></et2-image>` : "";
<et2-image slot="prefix" part="icon" style="width: var(--icon-width)"
src="${option.icon}"></et2-image>` : "";
return html`
<sl-menu-item value="${option.value}" title="${option.title}" class="${option.class}">

View File

@ -8,7 +8,7 @@
*/
import {Et2Select} from "./Et2Select";
import {css, html} from "@lion/core";
import {css} from "@lion/core";
import {IsEmail} from "../Validators/IsEmail";
export class Et2SelectEmail extends Et2Select
@ -88,44 +88,6 @@ export class Et2SelectEmail extends Et2Select
results.forEach(r => r.value = r.id);
super.processRemoteResults(results);
}
/**
* Customise how tags are rendered. This overrides what SlSelect
* does in syncItemsFromValue().
* This is a copy+paste from SlSelect.syncItemsFromValue().
*
* @param item
* @protected
*/
protected _tagTemplate(item)
{
let image = item.querySelector("et2-image");
if(image)
{
image = image.clone();
image.slot = "prefix";
}
return html`
<et2-tag
removable
@click=${this.handleTagInteraction}
@keydown=${this.handleTagInteraction}
@sl-remove=${(event) =>
{
event.stopPropagation();
if(!this.disabled)
{
item.checked = false;
this.syncValueFromItems();
}
}}
>
${image}
${this.getItemLabel(item)}
</et2-tag>
`;
}
}
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement

View File

@ -153,6 +153,14 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
display: none;
}
/* Different cursor for editable tags */
:host([allowfreeentries]) .search_tag::part(base) {
cursor: text;
}
/* styling for icon inside tag (not option) */
.tag_image {
margin-right: var(--sl-spacing-x-small);
}
/* Keep overflow tag right-aligned. It's the only sl-tag. */
.select__tags sl-tag {
margin-left: auto;
@ -220,6 +228,17 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
this._unbindListeners();
}
willUpdate(changedProperties)
{
super.willUpdate(changedProperties);
// If searchURL is set, turn on search
if(changedProperties.has("searchUrl") && this.searchUrl)
{
this.search = true;
}
}
/**
* Add the nodes we need to search
*
@ -270,9 +289,19 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
return this.querySelector(".search_input");
}
/**
* Tag used for rendering options
* Used for finding & filtering options, they're created by the mixed-in class
* @returns {string}
*/
public get optionTag()
{
return "sl-menu-item";
}
protected get menuItems()
{
return this.querySelectorAll("sl-menu-item");
return this.querySelectorAll(this.optionTag);
}
/**
@ -282,12 +311,12 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
*/
protected get localItems()
{
return this.querySelectorAll("sl-menu-item:not(.remote)");
return this.querySelectorAll(this.optionTag + ":not(.remote)");
}
protected get remoteItems()
{
return this.querySelectorAll("sl-menu-item.remote");
return this.querySelectorAll(this.optionTag + ".remote");
}
get value()
@ -319,11 +348,6 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
}
}
getItems()
{
return [...this.querySelectorAll("sl-menu-item:not(.no-match)")];
}
protected _bindListeners()
{
this.addEventListener("sl-blur", this._handleSearchAbort);
@ -687,6 +711,7 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
}
}
/**
* Customise how tags are rendered. This overrides what SlSelect
* does in syncItemsFromValue().
@ -697,30 +722,29 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
*/
protected _tagTemplate(item)
{
let image = item.querySelector("et2-image");
if(image)
{
image = image.clone();
image.slot = "prefix";
image.class = "tag_image";
}
return html`
<et2-tag
part="tag"
exportparts="
base:tag__base,
content:tag__content,
remove-button:tag__remove-button
"
variant="neutral"
size=${this.size}
?pill=${this.pill}
removable
@click=${this.handleTagInteraction}
@keydown=${this.handleTagInteraction}
@sl-remove=${(event) =>
{
event.stopPropagation();
if(!this.disabled)
{
item.checked = false;
this.syncValueFromItems();
}
}}
<et2-tag class="search_tag"
removable
@click=${this.handleTagInteraction}
@keydown=${this.handleTagInteraction}
@sl-remove=${(event) =>
{
event.stopPropagation();
if(!this.disabled)
{
item.checked = false;
this.syncValueFromItems();
}
}}
>
${image}
${this.getItemLabel(item)}
</et2-tag>
`;