Commit 854f778a authored by Dominique Feyer's avatar Dominique Feyer

TASK: Better hover handling on dropdown component

parent 52175e81
......@@ -110,6 +110,47 @@ declare global {
}
declare global {
namespace StencilComponents {
interface NeosDropdownHeader {
'hovered': boolean;
'label': string;
'open': boolean;
'placeholder': string;
'selectedLabel': string;
}
}
interface HTMLNeosDropdownHeaderElement extends StencilComponents.NeosDropdownHeader, HTMLStencilElement {}
var HTMLNeosDropdownHeaderElement: {
prototype: HTMLNeosDropdownHeaderElement;
new (): HTMLNeosDropdownHeaderElement;
};
interface HTMLElementTagNameMap {
'neos-dropdown-header': HTMLNeosDropdownHeaderElement;
}
interface ElementTagNameMap {
'neos-dropdown-header': HTMLNeosDropdownHeaderElement;
}
namespace JSX {
interface IntrinsicElements {
'neos-dropdown-header': JSXElements.NeosDropdownHeaderAttributes;
}
}
namespace JSXElements {
export interface NeosDropdownHeaderAttributes extends HTMLAttributes {
'hovered'?: boolean;
'label'?: string;
'open'?: boolean;
'placeholder'?: string;
'selectedLabel'?: string;
}
}
}
declare global {
namespace StencilComponents {
......
import {Component, Prop} from '@stencil/core';
@Component({
tag: 'neos-dropdown-header',
styleUrl: 'styles/dropdown-header.dark.scss',
shadow: true
})
export class Dropdown {
@Prop() label: string;
@Prop() selectedLabel: string;
@Prop() placeholder: string = 'Select a value...';
@Prop() open: boolean = false;
@Prop() hovered: boolean = false;
chevronIcon() {
return this.open ? 'chevron-up' : 'chevron-down';
}
chevronTheme() {
return this.hovered ? 'brand' : 'transparent';
}
render() {
return (
<a href="#" class="dropdown">
<div class="icon">
<neos-icon name="file"/>
</div>
<div class="selected-label">{this.label}</div>
<div class="toggle">
<neos-button squared theme={this.chevronTheme()}>
<neos-icon name={this.chevronIcon()} type="solid"></neos-icon>
</neos-button>
</div>
</a>
);
}
}
@import "./dropdown-header";
@import "./dropdown-header.dark.vars";
:host {
color: $text-dark-color-value;
font-family: $font-family-dark-base;
font-weight: 400;
font-size: $font-size-dark-base;
line-height: 1.1;
.dropdown {
display: flex;
color: inherit;
background-color: $background-dark-color;
border: 0;
outline: 1px solid neos-color($colors-dark, 'darker');
box-sizing: content-box;
padding: 0 0 0 $content-padding;
text-decoration: none;
height: $grid-unit;
}
.icon {
margin-right: .65em;
}
.toggle {
margin-left: auto;
}
}
@import "./dropdown-header.vars";
:host {
@include font-smoothing();
.dropdown {
flex: 1;
border: 0;
box-sizing: border-box;
height: $grid-unit;
line-height: $grid-unit;
}
transition: all ease-in 80ms;
}
......@@ -13,12 +13,22 @@ export class Dropdown {
@Prop() placeholder: string = 'Select a value...';
@State() isOpen: boolean = false;
@State() isHovered: boolean = false;
@State() activeLabel: string;
@Listen('neosItemSelected')
neosItemSelectedHandler(event: CustomEvent) {
this.activeLabel = event.detail;
this.isOpen = false;
this.isHovered = false;
}
mouseEnterHandler() {
this.isHovered = true;
}
mouseLeaveHandler() {
this.isHovered = false;
}
componentWillLoad() {
......@@ -36,27 +46,25 @@ export class Dropdown {
render() {
return (
<div>
<div
onMouseEnter={() => this.mouseEnterHandler()}
onMouseLeave={() => this.mouseLeaveHandler()}
>
<neos-form-input-wrapper label={this.label}>
<slot name="metadata"/>
<slot name="before"/>
<slot name="metadata" slot="metadata"/>
<slot name="before" slot="before"/>
<div class={this.wrapperClassName()}>
<a href="#" class="dropdown" onClick={(e) => this.toggle(e)}>
<div class="icon">
<neos-icon name="file"/>
</div>
<div class="selected-label">{this.activeLabel ? this.activeLabel : this.placeholder}</div>
<div class="toggle">
<neos-button squared theme="transparent">
<neos-icon name="chevron-down" type="solid"></neos-icon>
</neos-button>
</div>
</a>
<neos-dropdown-header
label={this.activeLabel ? this.activeLabel : this.placeholder}
open={this.isOpen}
hovered={this.isHovered && this.isOpen === false}
onClick={(e) => this.toggle(e)}
></neos-dropdown-header>
<div class="dropdown-list">
<slot/>
</div>
</div>
<slot name="after"/>
<slot name="after" slot="after"/>
</neos-form-input-wrapper>
</div>
);
......
......@@ -45,14 +45,6 @@
overflow: hidden;
}
.icon {
margin-right: .65em;
}
.toggle {
margin-left: auto;
}
.selected-value {
}
......
......@@ -9,14 +9,4 @@
flex: 1;
}
.dropdown {
flex: 1;
border: 0;
box-sizing: border-box;
height: $grid-unit;
line-height: $grid-unit;
transition: all ease-in 80ms;
}
}
......@@ -17,11 +17,6 @@
.metadata {
margin-left: auto;
margin-right: 1px;
::slotted(neos-badge) {
margin-right: 0;
margin-left: 6px;
}
}
.content {
......@@ -29,13 +24,18 @@
align-items: center;
flex: 1 0 100%;
margin-top: $content-margin-medium;
}
slot[name="before"]::slotted(*) {
margin-right: 2px;
}
slot[name="metadata"]::slotted(neos-badge) {
margin-right: 0;
margin-left: 6px;
}
slot[name="before"]::slotted(*) {
margin-right: 2px;
}
slot[name="after"]::slotted(*) {
margin-left: 2px;
}
slot[name="after"]::slotted(*) {
margin-left: 2px;
}
}
......@@ -250,8 +250,8 @@ export class FormInput {
return (
<label>
<neos-form-input-wrapper label={this.label}>
<slot name="metadata"/>
<slot name="before"/>
<slot name="metadata" slot="metadata"/>
<slot name="before" slot="before"/>
<input
ref={input => this.nativeInput = input as any}
aria-disabled={this.disabled ? 'true' : false}
......@@ -283,7 +283,7 @@ export class FormInput {
onFocus={this.onFocus.bind(this)}
onKeyDown={this.inputKeydown.bind(this)}
/>
<slot name="after"/>
<slot name="after" slot="after"/>
</neos-form-input-wrapper>
</label>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment