Skip to content

Commit 66b7880

Browse files
committed
feat: add lion-select-rich
1 parent 33652e5 commit 66b7880

23 files changed

+2577
-0
lines changed

packages/option/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# LionOption
2+
3+
[//]: # 'AUTO INSERT HEADER PREPUBLISH'
4+
5+
`lion-option` is a selectable within a [lion-select-rich](../select-rich/)
6+
7+
## Features
8+
9+
- has checked state
10+
- has a modelValue
11+
- can be disabled
12+
- fully accessible
13+
14+
## How to use
15+
16+
### Installation
17+
18+
```sh
19+
npm i --save @lion/select-rich
20+
```
21+
22+
```js
23+
import '@lion/select-rich/lion-select-rich.js';
24+
import '@lion/select-rich/lion-options.js';
25+
import '@lion/option/lion-option.js';
26+
```
27+
28+
### Example
29+
30+
```html
31+
<lion-select-rich
32+
name="favoriteColor"
33+
label="Favorite color"
34+
.errorValidators=${[['required']]}
35+
>
36+
<lion-options slot="input">
37+
<lion-option .choiceValue=${'red'}>Red</lion-option>
38+
<lion-option .choiceValue=${'hotpink'} checked>Hotpink</lion-option>
39+
</lion-options>
40+
</lion-select-rich>
41+
```
42+
43+
You can also set the full modelValue for each option.
44+
45+
```html
46+
<lion-option .modelValue=${{ value: 'red', checked: false }}>Red</lion-option>
47+
```
48+
49+
For more details please see [lion-select-rich](../select-rich/).

packages/option/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { LionOption } from './src/LionOption.js';

packages/option/lion-option.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { LionOption } from './src/LionOption.js';
2+
3+
customElements.define('lion-option', LionOption);

packages/option/package.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@lion/option",
3+
"version": "0.0.0",
4+
"description": "Allows to provide options for a rich select",
5+
"author": "ing-bank",
6+
"homepage": "https://github.com/ing-bank/lion/",
7+
"license": "MIT",
8+
"publishConfig": {
9+
"access": "public"
10+
},
11+
"repository": {
12+
"type": "git",
13+
"url": "https://github.com/ing-bank/lion.git",
14+
"directory": "packages/option"
15+
},
16+
"scripts": {
17+
"prepublishOnly": "../../scripts/npm-prepublish.js"
18+
},
19+
"keywords": [
20+
"lion",
21+
"web-components",
22+
"option"
23+
],
24+
"main": "index.js",
25+
"module": "index.js",
26+
"files": [
27+
"docs",
28+
"src",
29+
"stories",
30+
"test",
31+
"translations",
32+
"*.js"
33+
],
34+
"dependencies": {
35+
"@lion/core": "^0.1.13",
36+
"@lion/field": "^0.1.38",
37+
"@lion/choice-input": "^0.2.18"
38+
},
39+
"devDependencies": {
40+
"@open-wc/demoing-storybook": "^0.2.0",
41+
"@open-wc/testing": "^2.0.6",
42+
"sinon": "^7.2.2"
43+
}
44+
}

packages/option/src/LionOption.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { html, css, LitElement, DisabledMixin } from '@lion/core';
2+
import { FormRegisteringMixin } from '@lion/field';
3+
import { ChoiceInputMixin } from '@lion/choice-input';
4+
5+
/**
6+
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option
7+
* Can be a child of datalist/select, or role="listbox"
8+
*
9+
* Element gets state supplied externally, reflects this to attributes,
10+
* enabling SubClassers to style based on those states
11+
*/
12+
export class LionOption extends DisabledMixin(ChoiceInputMixin(FormRegisteringMixin(LitElement))) {
13+
static get properties() {
14+
return {
15+
active: {
16+
type: Boolean,
17+
reflect: true,
18+
},
19+
};
20+
}
21+
22+
static get styles() {
23+
return [
24+
css`
25+
:host {
26+
display: block;
27+
background-color: white;
28+
padding: 4px;
29+
}
30+
31+
:host([active]) {
32+
background-color: #ddd;
33+
}
34+
35+
:host([checked]) {
36+
background-color: #bde4ff;
37+
}
38+
39+
:host([disabled]) {
40+
color: #adadad;
41+
}
42+
`,
43+
];
44+
}
45+
46+
constructor() {
47+
super();
48+
this.active = false;
49+
this.__registerEventListener();
50+
}
51+
52+
_requestUpdate(name, oldValue) {
53+
super._requestUpdate(name, oldValue);
54+
55+
if (name === 'active') {
56+
this.dispatchEvent(new Event('active-changed', { bubbles: true }));
57+
}
58+
}
59+
60+
updated(changedProperties) {
61+
super.updated(changedProperties);
62+
if (changedProperties.has('checked')) {
63+
this.setAttribute('aria-selected', `${this.checked}`);
64+
}
65+
66+
if (changedProperties.has('disabled')) {
67+
this.setAttribute('aria-disabled', `${this.disabled}`);
68+
}
69+
}
70+
71+
render() {
72+
return html`
73+
<div class="choice-field__label">
74+
<slot></slot>
75+
</div>
76+
`;
77+
}
78+
79+
connectedCallback() {
80+
super.connectedCallback();
81+
this.setAttribute('role', 'option');
82+
}
83+
84+
disconnectedCallback() {
85+
super.disconnectedCallback();
86+
this.__unRegisterEventListeners();
87+
}
88+
89+
__registerEventListener() {
90+
this.__onClick = () => {
91+
if (!this.disabled) {
92+
this.checked = true;
93+
}
94+
};
95+
this.__onMouseEnter = () => {
96+
if (!this.disabled) {
97+
this.active = true;
98+
}
99+
};
100+
this.__onMouseLeave = () => {
101+
if (!this.disabled) {
102+
this.active = false;
103+
}
104+
};
105+
this.addEventListener('click', this.__onClick);
106+
this.addEventListener('mouseenter', this.__onMouseEnter);
107+
this.addEventListener('mouseleave', this.__onMouseLeave);
108+
}
109+
110+
__unRegisterEventListeners() {
111+
this.removeEventListener('click', this.__onClick);
112+
this.removeEventListener('mouseenter', this.__onMouseEnter);
113+
this.removeEventListener('mouseleave', this.__onMouseLeave);
114+
}
115+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { storiesOf, html } from '@open-wc/demoing-storybook';
2+
3+
import '../lion-option.js';
4+
5+
storiesOf('Forms|Option', module)
6+
.add(
7+
'States',
8+
() => html`
9+
<lion-option>Default</lion-option><br />
10+
<lion-option disabled>Disabled</lion-option>
11+
<lion-option>
12+
<p style="color: red;">With html</p>
13+
<p>and multi Line</p>
14+
</lion-option>
15+
`,
16+
)
17+
.add(
18+
'Values',
19+
() => html`
20+
<lion-option .modelValue=${{ value: 10, checked: false }}>setting modelValue</lion-option>
21+
<lion-option .modelValue=${{ value: 10, checked: false }} active
22+
>setting modelValue active</lion-option
23+
>
24+
<lion-option .modelValue=${{ value: 10, checked: true }}
25+
>setting modelValue checked</lion-option
26+
>
27+
<lion-option .modelValue=${{ value: 10, checked: false }} disabled
28+
>setting modelValue disabled</lion-option
29+
>
30+
<lion-option .choiceValue=${10}>setting choiceValue</lion-option>
31+
<lion-option .choiceValue=${10} active>setting choiceValue active</lion-option>
32+
<lion-option .choiceValue=${10} checked>setting choiceValue checked</lion-option>
33+
<lion-option .choiceValue=${10} disabled>setting choiceValue disabled</lion-option>
34+
`,
35+
);

0 commit comments

Comments
 (0)