@operato/input 0.2.33 → 0.2.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/demo/index-3dish.html +15 -2
- package/demo/index-angle.html +9 -4
- package/demo/index-button-radio.html +18 -6
- package/demo/index-checkbox.html +16 -5
- package/demo/index-stack.html +15 -3
- package/demo/index.html +79 -69
- package/dist/src/ox-buttons-radio.d.ts +7 -5
- package/dist/src/ox-buttons-radio.js +13 -9
- package/dist/src/ox-buttons-radio.js.map +1 -1
- package/dist/src/ox-checkbox.d.ts +5 -6
- package/dist/src/ox-checkbox.js +28 -25
- package/dist/src/ox-checkbox.js.map +1 -1
- package/dist/src/ox-formfield.d.ts +10 -0
- package/dist/src/ox-formfield.js +38 -0
- package/dist/src/ox-formfield.js.map +1 -0
- package/dist/src/ox-input-3dish.d.ts +15 -14
- package/dist/src/ox-input-3dish.js +51 -23
- package/dist/src/ox-input-3dish.js.map +1 -1
- package/dist/src/ox-input-angle.d.ts +4 -5
- package/dist/src/ox-input-angle.js +10 -12
- package/dist/src/ox-input-angle.js.map +1 -1
- package/dist/src/ox-input-stack.d.ts +5 -3
- package/dist/src/ox-input-stack.js +40 -35
- package/dist/src/ox-input-stack.js.map +1 -1
- package/dist/src/ox-select.d.ts +5 -4
- package/dist/src/ox-select.js +34 -12
- package/dist/src/ox-select.js.map +1 -1
- package/dist/test/property-angle.test.js +3 -3
- package/dist/test/property-angle.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/ox-buttons-radio.ts +15 -9
- package/src/ox-checkbox.ts +32 -25
- package/src/ox-formfield.ts +36 -0
- package/src/ox-input-3dish.ts +65 -29
- package/src/ox-input-angle.ts +11 -12
- package/src/ox-input-stack.ts +43 -24
- package/src/ox-select.ts +44 -15
- package/test/property-angle.test.ts +3 -4
package/src/ox-checkbox.ts
CHANGED
@@ -1,16 +1,14 @@
|
|
1
|
-
/**
|
2
|
-
* @license Copyright © HatioLab Inc. All rights reserved.
|
3
|
-
*/
|
4
|
-
|
5
1
|
/*
|
6
2
|
This component is inspired by https://github.com/Polydile/dile-components, thanks Dile.
|
7
3
|
*/
|
8
4
|
|
9
|
-
import { css, html
|
5
|
+
import { css, html } from 'lit'
|
10
6
|
import { customElement, property, state } from 'lit/decorators.js'
|
11
7
|
|
8
|
+
import { OxFormField } from './ox-formfield'
|
9
|
+
|
12
10
|
@customElement('ox-checkbox')
|
13
|
-
export class OxCheckbox extends
|
11
|
+
export class OxCheckbox extends OxFormField {
|
14
12
|
static styles = [
|
15
13
|
css`
|
16
14
|
:host {
|
@@ -44,7 +42,7 @@ export class OxCheckbox extends LitElement {
|
|
44
42
|
border: var(--ox-checkbox-unchecked-border, 1px solid rgba(0, 0, 0, 0.3));
|
45
43
|
}
|
46
44
|
|
47
|
-
|
45
|
+
:host([checked]) a {
|
48
46
|
background-color: var(--ox-checkbox-checked-background-color, #fff);
|
49
47
|
border: var(--ox-checkbox-checked-border, 1px solid #38a25b);
|
50
48
|
}
|
@@ -53,7 +51,7 @@ export class OxCheckbox extends LitElement {
|
|
53
51
|
fill: var(--ox-checkbox-fill-color, rgba(0, 0, 0, 0.1));
|
54
52
|
}
|
55
53
|
|
56
|
-
[checked] path {
|
54
|
+
:host([checked]) path {
|
57
55
|
fill: var(--ox-checkbox-checked-color, #38a25b);
|
58
56
|
}
|
59
57
|
|
@@ -67,28 +65,22 @@ export class OxCheckbox extends LitElement {
|
|
67
65
|
color: var(--ox-checkbox-label-color, #3a5877);
|
68
66
|
}
|
69
67
|
|
70
|
-
[checked]
|
68
|
+
:host([checked]) [label] {
|
71
69
|
font-weight: var(--ox-checkbox-checked-font-weight, bold);
|
72
70
|
}
|
73
71
|
`
|
74
72
|
]
|
75
73
|
|
76
|
-
@property({ type: Boolean }) checked: boolean = false
|
74
|
+
@property({ type: Boolean, attribute: 'checked', reflect: true }) checked: boolean = false
|
77
75
|
@property({ type: Boolean }) disabled: boolean = false
|
78
|
-
@property({ type: String }) name
|
76
|
+
@property({ type: String }) name?: string
|
79
77
|
|
80
78
|
@state() _hasInner: boolean = !!this.innerHTML.trim().length
|
81
79
|
|
82
80
|
render() {
|
83
81
|
return html`
|
84
82
|
<div @click=${this.onClick} ?disabled=${this.disabled}>
|
85
|
-
<a
|
86
|
-
href="#"
|
87
|
-
@click=${(e: Event) => e.preventDefault()}
|
88
|
-
@keydown=${this.onKeyDown}
|
89
|
-
?checked=${this.checked}
|
90
|
-
checkbox
|
91
|
-
>
|
83
|
+
<a href="#" @click=${(e: Event) => e.preventDefault()} checkbox>
|
92
84
|
${this.checked ? this.checkedIcon : this.uncheckedIcon}
|
93
85
|
</a>
|
94
86
|
${this._hasInner
|
@@ -100,6 +92,13 @@ export class OxCheckbox extends LitElement {
|
|
100
92
|
`
|
101
93
|
}
|
102
94
|
|
95
|
+
connectedCallback() {
|
96
|
+
super.connectedCallback()
|
97
|
+
|
98
|
+
this.setAttribute('tabindex', '0')
|
99
|
+
this.addEventListener('keydown', this.onKeyDown.bind(this))
|
100
|
+
}
|
101
|
+
|
103
102
|
onClick() {
|
104
103
|
if (this.disabled) {
|
105
104
|
return
|
@@ -120,22 +119,30 @@ export class OxCheckbox extends LitElement {
|
|
120
119
|
}
|
121
120
|
|
122
121
|
get checkedIcon() {
|
123
|
-
return html
|
124
|
-
<
|
125
|
-
|
122
|
+
return html`
|
123
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
124
|
+
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
|
125
|
+
</svg>
|
126
|
+
`
|
126
127
|
}
|
127
128
|
|
128
129
|
get uncheckedIcon() {
|
129
|
-
return html
|
130
|
-
<
|
131
|
-
|
130
|
+
return html`
|
131
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
132
|
+
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
|
133
|
+
</svg>
|
134
|
+
`
|
132
135
|
}
|
133
136
|
|
134
137
|
onKeyDown(e: KeyboardEvent) {
|
135
138
|
e.preventDefault()
|
136
139
|
|
137
|
-
if (e.
|
140
|
+
if (e.key === ' ' || e.key == 'Spacebar') {
|
138
141
|
this.onClick()
|
139
142
|
}
|
140
143
|
}
|
144
|
+
|
145
|
+
protected appendFormData({ formData }: FormDataEvent): void {
|
146
|
+
this.name && formData.append(this.name, this.checked ? 'true' : 'false')
|
147
|
+
}
|
141
148
|
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { LitElement } from 'lit-element'
|
2
|
+
import { property } from 'lit/decorators.js'
|
3
|
+
|
4
|
+
export abstract class OxFormField extends LitElement {
|
5
|
+
@property({ type: String }) name?: string
|
6
|
+
@property() value?: any
|
7
|
+
|
8
|
+
private _form: HTMLFormElement | null = null
|
9
|
+
private _formdataEventHandler: EventListener | null = null
|
10
|
+
|
11
|
+
override connectedCallback(): void {
|
12
|
+
super.connectedCallback()
|
13
|
+
|
14
|
+
if (this.name) {
|
15
|
+
this._form = this.closest('form')
|
16
|
+
if (this._form) {
|
17
|
+
this._formdataEventHandler = this.appendFormData.bind(this) as EventListener
|
18
|
+
this._form.addEventListener('formdata', this._formdataEventHandler)
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
override disconnectedCallback(): void {
|
24
|
+
super.disconnectedCallback()
|
25
|
+
|
26
|
+
if (this._form) {
|
27
|
+
this._form.removeEventListener('formdata', this._formdataEventHandler!)
|
28
|
+
this._form = null
|
29
|
+
this._formdataEventHandler = null
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
protected appendFormData({ formData }: FormDataEvent): void {
|
34
|
+
this.name && formData.append(this.name, this.value)
|
35
|
+
}
|
36
|
+
}
|
package/src/ox-input-3dish.ts
CHANGED
@@ -2,13 +2,14 @@
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
3
3
|
*/
|
4
4
|
|
5
|
-
import { css, html
|
5
|
+
import { LitElement, css, html } from 'lit'
|
6
6
|
import { customElement, property } from 'lit/decorators.js'
|
7
7
|
|
8
|
+
import { OxFormField } from './ox-formfield'
|
8
9
|
import { OxInputAngle } from './ox-input-angle'
|
9
10
|
|
10
11
|
@customElement('ox-input-3dish')
|
11
|
-
export class OxInput3Dish extends
|
12
|
+
export class OxInput3Dish extends OxFormField {
|
12
13
|
static styles = [
|
13
14
|
css`
|
14
15
|
:host {
|
@@ -32,19 +33,20 @@ export class OxInput3Dish extends LitElement {
|
|
32
33
|
`
|
33
34
|
]
|
34
35
|
|
35
|
-
@property({ type: Object }) dimension?: { width
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@property({ type: Object })
|
40
|
-
@property({ type: Object }) rotate?: { x: number; y: number; z: number }
|
41
|
-
@property({ type: Object }) scale?: { x: number; y: number; z: number }
|
36
|
+
@property({ type: Object }) dimension?: { width?: number; height?: number; depth?: number }
|
37
|
+
// translate는 고유한 html element의 attribute이므로, property는 translatex로 한다.
|
38
|
+
@property({ type: Object }) translatex?: { x?: number; y?: number; z?: number }
|
39
|
+
@property({ type: Object }) rotate?: { x?: number; y?: number; z?: number }
|
40
|
+
@property({ type: Object }) scale?: { x?: number; y?: number; z?: number }
|
42
41
|
|
43
42
|
firstUpdated() {
|
44
43
|
this.renderRoot.addEventListener('change', this._onChange.bind(this))
|
45
44
|
}
|
46
45
|
|
47
46
|
_onChange(e: Event) {
|
47
|
+
e.stopPropagation()
|
48
|
+
e.preventDefault()
|
49
|
+
|
48
50
|
var element = e.target as HTMLElement
|
49
51
|
var id = element.id
|
50
52
|
var prop = id.substr(1)
|
@@ -52,7 +54,7 @@ export class OxInput3Dish extends LitElement {
|
|
52
54
|
|
53
55
|
switch (element.tagName) {
|
54
56
|
case 'PROPERTY-ANGLE':
|
55
|
-
value = Number((element as OxInputAngle).
|
57
|
+
value = Number((element as OxInputAngle).value || 0)
|
56
58
|
break
|
57
59
|
}
|
58
60
|
|
@@ -60,15 +62,17 @@ export class OxInput3Dish extends LitElement {
|
|
60
62
|
case 'tx':
|
61
63
|
case 'ty':
|
62
64
|
case 'tz':
|
65
|
+
this.translatex = {
|
66
|
+
...this.translatex,
|
67
|
+
[prop]: value
|
68
|
+
}
|
69
|
+
|
63
70
|
this.dispatchEvent(
|
64
71
|
new CustomEvent('translate-changed', {
|
65
72
|
bubbles: true,
|
66
73
|
composed: true,
|
67
74
|
detail: {
|
68
|
-
value:
|
69
|
-
...this.translatex,
|
70
|
-
[prop]: value
|
71
|
-
}
|
75
|
+
value: this.translatex
|
72
76
|
}
|
73
77
|
})
|
74
78
|
)
|
@@ -77,15 +81,17 @@ export class OxInput3Dish extends LitElement {
|
|
77
81
|
case 'rx':
|
78
82
|
case 'ry':
|
79
83
|
case 'rz':
|
84
|
+
this.rotate = {
|
85
|
+
...this.rotate,
|
86
|
+
[prop]: value
|
87
|
+
}
|
88
|
+
|
80
89
|
this.dispatchEvent(
|
81
90
|
new CustomEvent('rotate-changed', {
|
82
91
|
bubbles: true,
|
83
92
|
composed: true,
|
84
93
|
detail: {
|
85
|
-
value:
|
86
|
-
...this.rotate,
|
87
|
-
[prop]: value
|
88
|
-
}
|
94
|
+
value: this.rotate
|
89
95
|
}
|
90
96
|
})
|
91
97
|
)
|
@@ -94,15 +100,17 @@ export class OxInput3Dish extends LitElement {
|
|
94
100
|
case 'sx':
|
95
101
|
case 'sy':
|
96
102
|
case 'sz':
|
103
|
+
this.scale = {
|
104
|
+
...this.scale,
|
105
|
+
[prop]: value
|
106
|
+
}
|
107
|
+
|
97
108
|
this.dispatchEvent(
|
98
109
|
new CustomEvent('scale-changed', {
|
99
110
|
bubbles: true,
|
100
111
|
composed: true,
|
101
112
|
detail: {
|
102
|
-
value:
|
103
|
-
...this.scale,
|
104
|
-
[prop]: value
|
105
|
-
}
|
113
|
+
value: this.scale
|
106
114
|
}
|
107
115
|
})
|
108
116
|
)
|
@@ -110,19 +118,38 @@ export class OxInput3Dish extends LitElement {
|
|
110
118
|
|
111
119
|
default:
|
112
120
|
// dimension
|
121
|
+
this.dimension = {
|
122
|
+
...this.dimension,
|
123
|
+
[prop]: value
|
124
|
+
}
|
125
|
+
|
113
126
|
this.dispatchEvent(
|
114
127
|
new CustomEvent('dimension-changed', {
|
115
128
|
bubbles: true,
|
116
129
|
composed: true,
|
117
130
|
detail: {
|
118
|
-
value:
|
119
|
-
...this.dimension,
|
120
|
-
[prop]: value
|
121
|
-
}
|
131
|
+
value: this.dimension
|
122
132
|
}
|
123
133
|
})
|
124
134
|
)
|
125
135
|
}
|
136
|
+
|
137
|
+
this.value = {
|
138
|
+
translate: this.translatex,
|
139
|
+
rotate: this.rotate,
|
140
|
+
scale: this.scale,
|
141
|
+
dimension: this.dimension
|
142
|
+
}
|
143
|
+
|
144
|
+
this.dispatchEvent(
|
145
|
+
new CustomEvent('change', {
|
146
|
+
bubbles: true,
|
147
|
+
composed: true,
|
148
|
+
detail: {
|
149
|
+
value: this.value
|
150
|
+
}
|
151
|
+
})
|
152
|
+
)
|
126
153
|
}
|
127
154
|
|
128
155
|
render() {
|
@@ -141,10 +168,19 @@ export class OxInput3Dish extends LitElement {
|
|
141
168
|
<input type="number" id="ty" .value=${this.translatex?.y} />
|
142
169
|
<input type="number" id="tz" .value=${this.translatex?.z} />
|
143
170
|
|
171
|
+
<label><i18n-msg msgid="label.scale">scale</i18n-msg></label>
|
172
|
+
<input type="number" id="sx" .value=${this.scale?.x} />
|
173
|
+
<input type="number" id="sy" .value=${this.scale?.y} />
|
174
|
+
<input type="number" id="sz" .value=${this.scale?.z} />
|
175
|
+
|
144
176
|
<label><i18n-msg msgid="label.rotate">rotate</i18n-msg></label>
|
145
|
-
<ox-input-angle id="rx" .
|
146
|
-
<ox-input-angle id="ry" .
|
147
|
-
<ox-input-angle id="rz" .
|
177
|
+
<ox-input-angle id="rx" .value=${this.rotate?.x}></ox-input-angle>
|
178
|
+
<ox-input-angle id="ry" .value=${this.rotate?.y}></ox-input-angle>
|
179
|
+
<ox-input-angle id="rz" .value=${this.rotate?.z}></ox-input-angle>
|
148
180
|
`
|
149
181
|
}
|
182
|
+
|
183
|
+
protected appendFormData({ formData }: FormDataEvent): void {
|
184
|
+
this.name && formData.append(this.name, JSON.stringify(this.value))
|
185
|
+
}
|
150
186
|
}
|
package/src/ox-input-angle.ts
CHANGED
@@ -2,11 +2,13 @@
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
3
3
|
*/
|
4
4
|
|
5
|
-
import { css, html
|
5
|
+
import { css, html } from 'lit'
|
6
6
|
import { customElement, property, query } from 'lit/decorators.js'
|
7
7
|
|
8
|
+
import { OxFormField } from './ox-formfield'
|
9
|
+
|
8
10
|
@customElement('ox-input-angle')
|
9
|
-
export class OxInputAngle extends
|
11
|
+
export class OxInputAngle extends OxFormField {
|
10
12
|
static styles = [
|
11
13
|
css`
|
12
14
|
:host {
|
@@ -22,32 +24,29 @@ export class OxInputAngle extends LitElement {
|
|
22
24
|
`
|
23
25
|
]
|
24
26
|
|
25
|
-
@property({ type:
|
27
|
+
@property({ type: String }) placeholder?: string
|
28
|
+
|
26
29
|
@query('input') input!: HTMLInputElement
|
27
30
|
|
28
31
|
render() {
|
29
32
|
return html`
|
30
33
|
<input
|
31
34
|
type="number"
|
32
|
-
.value=${this._toDegree(this.
|
35
|
+
.value=${this._toDegree(this.value)}
|
36
|
+
.placeholder=${this.placeholder || '0°'}
|
33
37
|
@change=${(e: Event) => this._onChangeValue(e)}
|
34
|
-
.placeholder=${this.placeholder}
|
35
38
|
/>
|
36
39
|
`
|
37
40
|
}
|
38
41
|
|
39
|
-
get placeholder() {
|
40
|
-
return this.getAttribute('placeholder') || '0°'
|
41
|
-
}
|
42
|
-
|
43
42
|
_onChangeValue(e: Event) {
|
44
|
-
this.
|
43
|
+
this.value = this._toRadian(this.input.value)
|
45
44
|
|
46
45
|
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
|
47
46
|
}
|
48
47
|
|
49
|
-
_toDegree(
|
50
|
-
return Math.round(((Number(
|
48
|
+
_toDegree(value: string | number | undefined) {
|
49
|
+
return Math.round(((Number(value) || 0) * 180) / Math.PI)
|
51
50
|
}
|
52
51
|
|
53
52
|
_toRadian(degree: string | number | undefined) {
|
package/src/ox-input-stack.ts
CHANGED
@@ -2,11 +2,13 @@
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
3
3
|
*/
|
4
4
|
|
5
|
-
import { css, html
|
5
|
+
import { css, html } from 'lit'
|
6
6
|
import { customElement, property } from 'lit/decorators.js'
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
import { OxFormField } from './ox-formfield'
|
9
|
+
|
10
|
+
@customElement('ox-input-stack')
|
11
|
+
export default class OxInputStack extends OxFormField {
|
10
12
|
static styles = [
|
11
13
|
css`
|
12
14
|
:host {
|
@@ -43,12 +45,12 @@ export default class OxStack extends LitElement {
|
|
43
45
|
/**
|
44
46
|
* `stack`은 stack에 의해 만들어진 층의 배열을 유지한다.
|
45
47
|
*/
|
46
|
-
@property({ type: Array }) stack: { name: string }[] = []
|
48
|
+
@property({ type: Array }) stack: { name: string; active?: boolean }[] = []
|
47
49
|
|
48
50
|
/**
|
49
51
|
* `activeIndex`은 현재 active된 층의 인덱스를 유지한다.
|
50
52
|
*/
|
51
|
-
@property({ type: Number }) activeIndex: number = 0
|
53
|
+
// @property({ type: Number }) activeIndex: number = 0
|
52
54
|
|
53
55
|
render() {
|
54
56
|
const stack = [...this.stack].reverse()
|
@@ -59,11 +61,7 @@ export default class OxStack extends LitElement {
|
|
59
61
|
|
60
62
|
${stack.map(
|
61
63
|
(item, index) => html`
|
62
|
-
<div
|
63
|
-
?active=${length - index - 1 == this.activeIndex}
|
64
|
-
@click=${(e: Event) => this._onClickToActive(e)}
|
65
|
-
idx=${length - index - 1}
|
66
|
-
>
|
64
|
+
<div floor ?active=${item.active} @click=${(e: Event) => this._onClickToActive(e)} idx=${length - index - 1}>
|
67
65
|
${item.name} <button @click=${(e: Event) => this._onClickRemoveFloor(e)}>-</button>
|
68
66
|
</div>
|
69
67
|
`
|
@@ -71,39 +69,60 @@ export default class OxStack extends LitElement {
|
|
71
69
|
`
|
72
70
|
}
|
73
71
|
|
72
|
+
_notifyChange() {
|
73
|
+
this.value = this.stack
|
74
|
+
|
75
|
+
this.dispatchEvent(new CustomEvent('change', { detail: this.value, bubbles: true, composed: true }))
|
76
|
+
}
|
77
|
+
|
74
78
|
_onClickAddFloor(e: Event) {
|
75
79
|
this.stack.push({ name: String(this.stack.length + 1) })
|
76
80
|
this.requestUpdate()
|
81
|
+
|
82
|
+
this._notifyChange()
|
77
83
|
}
|
78
84
|
|
79
85
|
_onClickToActive(e: Event) {
|
80
|
-
const
|
81
|
-
|
86
|
+
const floor = (e.target as HTMLElement).closest('[floor]')
|
87
|
+
|
88
|
+
if (!floor) {
|
82
89
|
return
|
83
90
|
}
|
84
91
|
|
85
|
-
|
92
|
+
e.stopPropagation()
|
93
|
+
|
94
|
+
const activeIndex = Number(floor.getAttribute('idx'))
|
95
|
+
this.stack = this.stack.map((floor, index) => {
|
96
|
+
return activeIndex === index
|
97
|
+
? {
|
98
|
+
name: floor.name,
|
99
|
+
active: true
|
100
|
+
}
|
101
|
+
: { name: floor.name }
|
102
|
+
})
|
103
|
+
|
104
|
+
this._notifyChange()
|
86
105
|
}
|
87
106
|
|
88
107
|
_onClickRemoveFloor(e: Event) {
|
89
|
-
const
|
108
|
+
const floor = (e.target as HTMLElement).closest('[floor]')
|
90
109
|
|
91
|
-
if (
|
110
|
+
if (!floor) {
|
92
111
|
return
|
93
112
|
}
|
94
113
|
|
95
|
-
|
114
|
+
e.stopPropagation()
|
96
115
|
|
97
|
-
|
116
|
+
const idx = Number(floor.getAttribute('idx'))
|
98
117
|
|
99
|
-
|
100
|
-
this.activeIndex = 0
|
101
|
-
} else if (this.activeIndex >= idx) {
|
102
|
-
this.activeIndex--
|
103
|
-
} else if (this.activeIndex >= this.stack.length) {
|
104
|
-
this.activeIndex = 0
|
105
|
-
}
|
118
|
+
this.stack.splice(idx, 1)
|
106
119
|
|
107
120
|
this.requestUpdate()
|
121
|
+
|
122
|
+
this._notifyChange()
|
123
|
+
}
|
124
|
+
|
125
|
+
protected appendFormData({ formData }: FormDataEvent): void {
|
126
|
+
this.name && formData.append(this.name, JSON.stringify(this.value))
|
108
127
|
}
|
109
128
|
}
|
package/src/ox-select.ts
CHANGED
@@ -5,18 +5,19 @@
|
|
5
5
|
import '@material/mwc-icon'
|
6
6
|
import '@operato/popup'
|
7
7
|
|
8
|
-
import {
|
8
|
+
import { css, html } from 'lit'
|
9
9
|
import { customElement, property, query } from 'lit/decorators.js'
|
10
10
|
|
11
|
-
import {
|
12
|
-
import {
|
11
|
+
import { OxFormField } from './ox-formfield'
|
12
|
+
import { OxPopupList } from '@operato/popup'
|
13
13
|
|
14
14
|
@customElement('ox-select')
|
15
|
-
export class Select extends
|
15
|
+
export class Select extends OxFormField {
|
16
16
|
static styles = [
|
17
17
|
css`
|
18
18
|
:host {
|
19
19
|
display: block;
|
20
|
+
position: relative;
|
20
21
|
}
|
21
22
|
|
22
23
|
div {
|
@@ -29,6 +30,9 @@ export class Select extends LitElement {
|
|
29
30
|
|
30
31
|
span {
|
31
32
|
flex: 1;
|
33
|
+
overflow: hidden;
|
34
|
+
text-overflow: ellipsis;
|
35
|
+
white-space: nowrap;
|
32
36
|
}
|
33
37
|
|
34
38
|
mwc-icon {
|
@@ -47,36 +51,61 @@ export class Select extends LitElement {
|
|
47
51
|
]
|
48
52
|
|
49
53
|
@property({ type: String }) name: string = ''
|
50
|
-
@property({ type: String })
|
54
|
+
@property({ type: String }) placeholder: string = ''
|
51
55
|
|
52
56
|
render() {
|
57
|
+
const label = (this.value instanceof Array ? this.value.join(', ') : this.value) || this.placeholder || ''
|
58
|
+
|
53
59
|
return html`
|
54
60
|
<div @click=${this.expand}>
|
55
|
-
<span>${
|
61
|
+
<span>${label}</span>
|
56
62
|
<mwc-icon>expand_more</mwc-icon>
|
57
63
|
</div>
|
64
|
+
|
58
65
|
<slot></slot>
|
59
66
|
`
|
60
67
|
}
|
61
68
|
|
69
|
+
connectedCallback() {
|
70
|
+
super.connectedCallback()
|
71
|
+
|
72
|
+
this.setAttribute('tabindex', '0')
|
73
|
+
|
74
|
+
this.addEventListener('select', (e: Event) => {
|
75
|
+
this.value = (e as CustomEvent).detail
|
76
|
+
|
77
|
+
this.dispatchEvent(
|
78
|
+
new CustomEvent('change', {
|
79
|
+
bubbles: true,
|
80
|
+
composed: true,
|
81
|
+
detail: this.value
|
82
|
+
})
|
83
|
+
)
|
84
|
+
})
|
85
|
+
|
86
|
+
this.addEventListener('keydown', (e: KeyboardEvent) => {
|
87
|
+
e.preventDefault()
|
88
|
+
|
89
|
+
if (e.key === ' ' || e.key == 'Spacebar' || e.key == 'ArrowDown') {
|
90
|
+
this.expand()
|
91
|
+
}
|
92
|
+
})
|
93
|
+
}
|
94
|
+
|
62
95
|
expand() {
|
63
|
-
const popupList = this.querySelector('ox-popup-list') as
|
96
|
+
const popupList = this.querySelector('ox-popup-list') as OxPopupList
|
64
97
|
|
65
98
|
if (popupList) {
|
66
99
|
popupList.style.width = `${this.offsetWidth}px`
|
67
100
|
|
68
101
|
popupList.open({
|
69
|
-
top: this.
|
70
|
-
left:
|
102
|
+
top: this.offsetHeight,
|
103
|
+
left: 0
|
71
104
|
})
|
72
105
|
}
|
73
106
|
}
|
74
107
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
if (e.keyCode == 32 || e.code == 'Space') {
|
79
|
-
this.expand()
|
80
|
-
}
|
108
|
+
protected appendFormData({ formData }: FormDataEvent): void {
|
109
|
+
this.name && formData.append(this.name, JSON.stringify(this.value))
|
81
110
|
}
|
82
111
|
}
|
@@ -1,22 +1,21 @@
|
|
1
|
-
import { html } from 'lit'
|
2
|
-
|
3
1
|
import { expect, fixture } from '@open-wc/testing'
|
4
2
|
|
5
3
|
import { OxInputAngle } from '../src/ox-input-angle'
|
4
|
+
import { html } from 'lit'
|
6
5
|
|
7
6
|
describe('OxInputAngle', () => {
|
8
7
|
it('has a default title "Hey there" and angle 5', async () => {
|
9
8
|
const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)
|
10
9
|
|
11
10
|
expect(el.title).to.equal('Hey there')
|
12
|
-
expect(el.
|
11
|
+
expect(el.value).to.equal(5)
|
13
12
|
})
|
14
13
|
|
15
14
|
it('increases the angle on button click', async () => {
|
16
15
|
const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)
|
17
16
|
el.shadowRoot!.querySelector('button')!.click()
|
18
17
|
|
19
|
-
expect(el.
|
18
|
+
expect(el.value).to.equal(6)
|
20
19
|
})
|
21
20
|
|
22
21
|
it('can override the title via attribute', async () => {
|