Skip to content

Commit

Permalink
feat(ld-select): implement keyboard navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
borisdiakur committed Jun 30, 2021
1 parent 6b6dc95 commit c1828c5
Show file tree
Hide file tree
Showing 10 changed files with 416 additions and 114 deletions.
18 changes: 9 additions & 9 deletions src/liquid/components/ld-button/ld-button.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ ld-button {
opacity: 0.2;
}

&:where(:not(:disabled):not([aria-disabled])) {
&:where(:not(:disabled):not([aria-disabled='true'])) {
cursor: pointer;
}

Expand Down Expand Up @@ -133,7 +133,7 @@ ld-button {
background-color: var(--ld-thm-ocean-bg-primary);
color: var(--ld-col-wht);

&:where(:not(:disabled):not([aria-disabled])) {
&:where(:not(:disabled):not([aria-disabled='true'])) {
&:where(:focus:focus-visible) {
background-color: var(--ld-col-rb-focus);
color: var(--ld-thm-ocean-bg-secondary);
Expand Down Expand Up @@ -361,7 +361,7 @@ ld-button {
[class*='ld-theme'] .ld-theme-shake & {
box-shadow: inset 0px 0px 0px 2px var(--ld-col-rp-default);

&:where(&:not(:disabled):not([aria-disabled])) {
&:where(&:not(:disabled):not([aria-disabled='true'])) {
&:focus:focus-visible {
box-shadow: inset 0px 0px 0px 2px var(--ld-col-rp-focus);
}
Expand All @@ -381,7 +381,7 @@ ld-button {
[class*='ld-theme'] .ld-theme-tea & {
box-shadow: inset 0px 0px 0px 2px var(--ld-col-rg-default);

&:where(&:not(:disabled):not([aria-disabled])) {
&:where(&:not(:disabled):not([aria-disabled='true'])) {
&:focus:focus-visible {
box-shadow: inset 0px 0px 0px 2px var(--ld-col-rg-focus);
}
Expand All @@ -406,7 +406,7 @@ ld-button {
--ld-col-ob-wht-focus: rgba(255, 255, 255, 0.9);
background-color: var(--ld-col-wht);

&:where(&:not(:disabled):not([aria-disabled])) {
&:where(&:not(:disabled):not([aria-disabled='true'])) {
&:focus:focus-visible {
background-color: var(--ld-col-ob-wht-focus);
}
Expand All @@ -427,7 +427,7 @@ ld-button {
[class*='ld-theme'] .ld-theme-ocean .ld-button--on-brand-color {
color: var(--ld-col-rb-default);

&:where(&:not(:disabled):not([aria-disabled])) {
&:where(&:not(:disabled):not([aria-disabled='true'])) {
&:focus:focus-visible {
color: var(--ld-col-rb-focus);
}
Expand All @@ -439,7 +439,7 @@ ld-button {
[class*='ld-theme'] .ld-theme-tea & {
color: var(--ld-col-rg-default);

&:where(&:not(:disabled):not([aria-disabled])) {
&:where(&:not(:disabled):not([aria-disabled='true'])) {
&:focus:focus-visible {
color: var(--ld-col-rg-focus);
}
Expand All @@ -454,7 +454,7 @@ ld-button {
[class*='ld-theme'] .ld-theme-shake & {
color: var(--ld-col-rp-default);

&:where(&:not(:disabled):not([aria-disabled])) {
&:where(&:not(:disabled):not([aria-disabled='true'])) {
&:focus:focus-visible {
color: var(--ld-col-rp-focus);
}
Expand All @@ -472,7 +472,7 @@ ld-button {
color: var(--ld-col-wht);
box-shadow: inset 0px 0px 0px 2px var(--ld-col-wht);

&:where(&:not(:disabled):not([aria-disabled])) {
&:where(&:not(:disabled):not([aria-disabled='true'])) {
@media (hover: hover) {
&:hover {
background-color: var(--ld-col-sob-wht-hover-bg);
Expand Down
13 changes: 0 additions & 13 deletions src/liquid/components/ld-checkbox/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -596,19 +596,6 @@ The `ld-checkbox` web component provides a low level API for integrating the com
| `tone` | `tone` | Checkbox tone. Use `'dark'` on white backgrounds. Default is a light tone. | `"dark"` | `undefined` |


## Dependencies

### Used by

- [ld-option](../ld-option)

### Graph
```mermaid
graph TD;
ld-option --> ld-checkbox
style ld-checkbox fill:#f9f,stroke:#333,stroke-width:4px
```

----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
11 changes: 5 additions & 6 deletions src/liquid/components/ld-input/ld-input.css

Large diffs are not rendered by default.

13 changes: 0 additions & 13 deletions src/liquid/components/ld-label/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,6 @@ The default size is small. You can use a slightly bigger label (size medium) by
| `size` | `size` | Size of the label. Default is small. | `"m"` | `undefined` |


## Dependencies

### Used by

- [ld-option](../ld-option)

### Graph
```mermaid
graph TD;
ld-option --> ld-label
style ld-label fill:#f9f,stroke:#333,stroke-width:4px
```

----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
130 changes: 129 additions & 1 deletion src/liquid/components/ld-option/ld-option.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,131 @@
.ld-option {
display: block;
display: flex;
position: relative;
background-color: var(--ld-col-wht);
padding: var(--ld-sp-8) var(--ld-sp-12);
font: var(--ld-typo-label-m);
min-height: 2.5rem;
user-select: none;
touch-action: manipulation;
border: 0;
-webkit-touch-callout: none;

[data-popper-placement*='bottom'] & {
&:first-of-type {
border-top: solid var(--ld-col-rblck1) 1px;
}
&:last-of-type {
border-bottom-left-radius: var(--ld-br-m);
border-bottom-right-radius: var(--ld-br-m);
}
}
[data-popper-placement*='top'] & {
&:last-of-type {
border-bottom: solid var(--ld-col-rblck1) 1px;
}
&:first-of-type {
border-top-left-radius: var(--ld-br-m);
border-top-right-radius: var(--ld-br-m);
}
}

&:not(:last-of-type) {
border-bottom: solid var(--ld-col-rblck1) 1px;
}

&:not([aria-disabled='true']) {
cursor: pointer;
}

&[aria-disabled='true'] {
color: var(--ld-col-disabled);
}
}

.ld-option__check {
align-self: center;
flex-shrink: 0;
margin-right: var(--ld-sp-4);
transform: translateX(calc(-1 * var(--ld-sp-2)));
}

/* .ld-theme-ocean -> default */
.ld-option,
.ld-theme-ocean .ld-option,
[class*='ld-theme'] .ld-theme-ocean .ld-option {
&:where(:not([disabled]):not([aria-disabled='true'])) {
.ld-option__check {
color: var(--ld-thm-ocean-bg-primary);
}

&:where(:focus:focus-visible) {
background-color: var(--ld-col-rb1);
}
@media (hover: hover) {
&:where(:hover) {
background-color: var(--ld-col-rb1);
}
}
&:where(:active),
&:where(:active:focus-visible) {
background-color: var(--ld-col-rb1);
}
}
}

.ld-theme-bubblegum,
[class*='ld-theme'] .ld-theme-bubblegum,
.ld-theme-shake,
[class*='ld-theme'] .ld-theme-shake,
.ld-theme-solvent,
[class*='ld-theme'] .ld-theme-solvent {
:where(.ld-option) {
&:where(:not([disabled]):not([aria-disabled='true'])) {
.ld-option__check {
color: var(--ld-thm-solvent-bg-primary);
}

&:where(:focus:focus-visible) {
background-color: var(--ld-col-rp1);
}
@media (hover: hover) {
&:where(:hover) {
background-color: var(--ld-col-rp1);
}
}
&:where(:active),
&:where(:active:focus-visible) {
background-color: var(--ld-col-rp1);
}
}
}
}

.ld-theme-tea,
[class*='ld-theme'] .ld-theme-tea {
:where(.ld-option) {
&:where(:not([disabled]):not([aria-disabled='true'])) {
.ld-option__check {
color: var(--ld-thm-tea-bg-primary);
}

&:where(:focus:focus-visible) {
background-color: var(--ld-col-rg1);
}
@media (hover: hover) {
&:where(:hover) {
background-color: var(--ld-col-rg1);
}
}
&:where(:active),
&:where(:active:focus-visible) {
background-color: var(--ld-col-rg1);
}
}
}
}

.ld-option__label {
overflow: hidden;
text-overflow: ellipsis;
}
75 changes: 64 additions & 11 deletions src/liquid/components/ld-option/ld-option.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import '../../components' // type definitions for type checks and intelliSense
import { Component, h, Host, Prop, Element } from '@stencil/core'
import {
Component,
h,
Host,
Prop,
Element,
Event,
EventEmitter,
Listen,
} from '@stencil/core'

@Component({
tag: 'ld-option',
Expand All @@ -19,10 +28,34 @@ export class LdOption {
/**
* If present, this boolean attribute indicates that the option is selected.
*/
@Prop({ mutable: true, reflect: true }) selected: false
@Prop({ mutable: true, reflect: true }) selected = false

private handleInput(ev) {
this.selected = ev.target.checked
/**
* Disables the option.
*/
@Prop() disabled = false

/**
* Emitted on either selection or de-selection of the option.
*/
@Event() ldOptionSelect: EventEmitter<boolean>

private handleClick() {
if (this.disabled) {
return
}

this.selected = !this.selected
this.ldOptionSelect.emit(this.selected)
}

@Listen('keydown', { passive: false })
handleKeyDown(ev: KeyboardEvent) {
if (ev.key === ' ' || ev.key === 'Enter') {
ev.preventDefault()
ev.stopImmediatePropagation()
this.handleClick()
}
}

componentWillLoad() {
Expand All @@ -35,14 +68,34 @@ export class LdOption {

render() {
return (
<Host class="ld-option" role="option" tabindex="-1">
<ld-label position="right" size="m">
<ld-checkbox
checked={this.selected}
onInput={this.handleInput.bind(this)}
></ld-checkbox>
<Host
class="ld-option"
role="option"
aria-selected={this.selected ? 'true' : 'false'}
aria-disabled={this.disabled ? 'true' : 'false'}
onClick={this.handleClick.bind(this)}
tabindex="-1"
>
<svg
style={{ visibility: this.selected ? 'inherit' : 'hidden' }}
class="ld-option__check"
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15 7L8.40795 13L5 9.63964"
stroke="currentColor"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="ld-option__label">
<slot></slot>
</ld-label>
</span>
</Host>
)
}
Expand Down
19 changes: 6 additions & 13 deletions src/liquid/components/ld-option/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,17 @@

| Property | Attribute | Description | Type | Default |
| ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- |
| `selected` | `selected` | If present, this boolean attribute indicates that the option is selected. | `boolean` | `undefined` |
| `disabled` | `disabled` | Disables the option. | `boolean` | `false` |
| `selected` | `selected` | If present, this boolean attribute indicates that the option is selected. | `boolean` | `false` |
| `value` | `value` | The content of this attribute represents the value to be submitted with the form, should this option be selected. If this attribute is omitted, the value is taken from the text content of the option element. | `string` | `undefined` |


## Dependencies
## Events

### Depends on
| Event | Description | Type |
| ---------------- | ---------------------------------------------------------- | ---------------------- |
| `ldOptionSelect` | Emitted on either selection or de-selection of the option. | `CustomEvent<boolean>` |

- [ld-label](../ld-label)
- [ld-checkbox](../ld-checkbox)

### Graph
```mermaid
graph TD;
ld-option --> ld-label
ld-option --> ld-checkbox
style ld-option fill:#f9f,stroke:#333,stroke-width:4px
```

----------------------------------------------

Expand Down
Loading

0 comments on commit c1828c5

Please sign in to comment.