@operato/input 10.0.0 → 10.2.0
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 +28 -0
- package/STYLING.md +194 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/input-styles.d.ts +38 -0
- package/dist/src/input-styles.js +108 -0
- package/dist/src/input-styles.js.map +1 -0
- package/dist/src/ox-buttons-radio.js +6 -4
- package/dist/src/ox-buttons-radio.js.map +1 -1
- package/dist/src/ox-form-field.d.ts +41 -0
- package/dist/src/ox-form-field.js +68 -1
- package/dist/src/ox-form-field.js.map +1 -1
- package/dist/src/ox-input-3axis.js +3 -1
- package/dist/src/ox-input-3axis.js.map +1 -1
- package/dist/src/ox-input-3dish.js +4 -2
- package/dist/src/ox-input-3dish.js.map +1 -1
- package/dist/src/ox-input-audio.js +4 -2
- package/dist/src/ox-input-audio.js.map +1 -1
- package/dist/src/ox-input-barcode.js +3 -1
- package/dist/src/ox-input-barcode.js.map +1 -1
- package/dist/src/ox-input-code.js +3 -1
- package/dist/src/ox-input-code.js.map +1 -1
- package/dist/src/ox-input-color.js +4 -2
- package/dist/src/ox-input-color.js.map +1 -1
- package/dist/src/ox-input-crontab.d.ts +1 -1
- package/dist/src/ox-input-crontab.js +6 -5
- package/dist/src/ox-input-crontab.js.map +1 -1
- package/dist/src/ox-input-data.js +5 -3
- package/dist/src/ox-input-data.js.map +1 -1
- package/dist/src/ox-input-duration.d.ts +1 -1
- package/dist/src/ox-input-duration.js +5 -4
- package/dist/src/ox-input-duration.js.map +1 -1
- package/dist/src/ox-input-file.js +3 -1
- package/dist/src/ox-input-file.js.map +1 -1
- package/dist/src/ox-input-formula-help-popup.js +30 -28
- package/dist/src/ox-input-formula-help-popup.js.map +1 -1
- package/dist/src/ox-input-formula.js +112 -111
- package/dist/src/ox-input-formula.js.map +1 -1
- package/dist/src/ox-input-hashtags.d.ts +1 -1
- package/dist/src/ox-input-hashtags.js +9 -8
- package/dist/src/ox-input-hashtags.js.map +1 -1
- package/dist/src/ox-input-i18n-label.d.ts +1 -1
- package/dist/src/ox-input-i18n-label.js +5 -4
- package/dist/src/ox-input-i18n-label.js.map +1 -1
- package/dist/src/ox-input-image.js +4 -2
- package/dist/src/ox-input-image.js.map +1 -1
- package/dist/src/ox-input-key-values.d.ts +1 -1
- package/dist/src/ox-input-key-values.js +10 -9
- package/dist/src/ox-input-key-values.js.map +1 -1
- package/dist/src/ox-input-mass-fraction.js +7 -5
- package/dist/src/ox-input-mass-fraction.js.map +1 -1
- package/dist/src/ox-input-multiple-colors.d.ts +1 -1
- package/dist/src/ox-input-multiple-colors.js +5 -4
- package/dist/src/ox-input-multiple-colors.js.map +1 -1
- package/dist/src/ox-input-options.d.ts +1 -1
- package/dist/src/ox-input-options.js +8 -7
- package/dist/src/ox-input-options.js.map +1 -1
- package/dist/src/ox-input-partition-keys.d.ts +1 -1
- package/dist/src/ox-input-partition-keys.js +10 -9
- package/dist/src/ox-input-partition-keys.js.map +1 -1
- package/dist/src/ox-input-privilege.d.ts +1 -1
- package/dist/src/ox-input-privilege.js +9 -8
- package/dist/src/ox-input-privilege.js.map +1 -1
- package/dist/src/ox-input-quantifier.d.ts +1 -1
- package/dist/src/ox-input-quantifier.js +6 -5
- package/dist/src/ox-input-quantifier.js.map +1 -1
- package/dist/src/ox-input-range.js +9 -8
- package/dist/src/ox-input-range.js.map +1 -1
- package/dist/src/ox-input-search.js +3 -1
- package/dist/src/ox-input-search.js.map +1 -1
- package/dist/src/ox-input-secret.js +3 -1
- package/dist/src/ox-input-secret.js.map +1 -1
- package/dist/src/ox-input-select-buttons.d.ts +1 -1
- package/dist/src/ox-input-select-buttons.js +4 -3
- package/dist/src/ox-input-select-buttons.js.map +1 -1
- package/dist/src/ox-input-signature.js +5 -3
- package/dist/src/ox-input-signature.js.map +1 -1
- package/dist/src/ox-input-stack.js +3 -1
- package/dist/src/ox-input-stack.js.map +1 -1
- package/dist/src/ox-input-table-column-config.js +5 -3
- package/dist/src/ox-input-table-column-config.js.map +1 -1
- package/dist/src/ox-input-table.js +5 -3
- package/dist/src/ox-input-table.js.map +1 -1
- package/dist/src/ox-input-unit-number.js +5 -3
- package/dist/src/ox-input-unit-number.js.map +1 -1
- package/dist/src/ox-input-value-map.d.ts +1 -1
- package/dist/src/ox-input-value-map.js +10 -9
- package/dist/src/ox-input-value-map.js.map +1 -1
- package/dist/src/ox-input-value-ranges.d.ts +1 -1
- package/dist/src/ox-input-value-ranges.js +11 -10
- package/dist/src/ox-input-value-ranges.js.map +1 -1
- package/dist/src/ox-input-video.js +4 -2
- package/dist/src/ox-input-video.js.map +1 -1
- package/dist/src/ox-input-work-shift.d.ts +1 -1
- package/dist/src/ox-input-work-shift.js +10 -9
- package/dist/src/ox-input-work-shift.js.map +1 -1
- package/dist/src/ox-select-floor.js +5 -3
- package/dist/src/ox-select-floor.js.map +1 -1
- package/dist/src/ox-select.js +20 -11
- package/dist/src/ox-select.js.map +1 -1
- package/dist/test/ox-form-field.test.d.ts +1 -0
- package/dist/test/ox-form-field.test.js +125 -0
- package/dist/test/ox-form-field.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/test/ox-form-field.test.ts +159 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@operato/input",
|
|
3
3
|
"description": "Webcomponents for input following open-wc recommendations",
|
|
4
4
|
"author": "heartyoh@hatiolab.com",
|
|
5
|
-
"version": "10.
|
|
5
|
+
"version": "10.2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/src/index.js",
|
|
8
8
|
"module": "dist/src/index.js",
|
|
@@ -245,8 +245,8 @@
|
|
|
245
245
|
"@material/web": "^2.0.0",
|
|
246
246
|
"@operato/i18n": "^10.0.0",
|
|
247
247
|
"@operato/pickr": "^10.0.0",
|
|
248
|
-
"@operato/popup": "^10.
|
|
249
|
-
"@operato/styles": "^10.
|
|
248
|
+
"@operato/popup": "^10.2.0",
|
|
249
|
+
"@operato/styles": "^10.2.0",
|
|
250
250
|
"@operato/utils": "^10.0.0",
|
|
251
251
|
"@types/codemirror": "^5.60.5",
|
|
252
252
|
"@undecaf/zbar-wasm": "^0.11.0",
|
|
@@ -288,5 +288,5 @@
|
|
|
288
288
|
"prettier --write"
|
|
289
289
|
]
|
|
290
290
|
},
|
|
291
|
-
"gitHead": "
|
|
291
|
+
"gitHead": "76b17317691c6dbc0e2804812c108241bf11b1c0"
|
|
292
292
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { html } from 'lit'
|
|
2
|
+
import { customElement } from 'lit/decorators.js'
|
|
3
|
+
import { fixture, expect } from '@open-wc/testing'
|
|
4
|
+
|
|
5
|
+
import { OxFormField } from '../src/ox-form-field.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* OxFormField 계약 테스트.
|
|
9
|
+
*
|
|
10
|
+
* 이 기반 클래스는 51개 입력 컴포넌트가 상속하므로, 계약이 깨지면 전 패키지에 파급된다.
|
|
11
|
+
* 검증 대상:
|
|
12
|
+
* - 상태 속성의 attribute reflect (InputStyles 의 :host([...]) 선택자가 동작하기 위한 전제)
|
|
13
|
+
* - required 기반 검증(checkValidity / invalid / invalid 이벤트)
|
|
14
|
+
* - isEmpty 의 경계값(0·false 는 유효한 값)
|
|
15
|
+
* - 폼 데이터 수집(formdata) 과 disabled 제외 규칙
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** 테스트용 최소 구현체 — 기반 계약만 노출한다. */
|
|
19
|
+
@customElement('test-form-field')
|
|
20
|
+
class TestFormField extends OxFormField<any> {
|
|
21
|
+
render() {
|
|
22
|
+
return html`<span>field</span>`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* 테스트에서 보호된 멤버를 확인하기 위한 창구 */
|
|
26
|
+
public callIsEmpty(): boolean {
|
|
27
|
+
return this.isEmpty()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function makeField(template = html`<test-form-field></test-form-field>`) {
|
|
32
|
+
return (await fixture(template)) as TestFormField
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('OxFormField — 상태 계약', () => {
|
|
36
|
+
it('상태 속성이 attribute 로 reflect 된다 (프로퍼티로 설정해도 :host([...]) 가 동작)', async () => {
|
|
37
|
+
const el = await makeField()
|
|
38
|
+
|
|
39
|
+
el.disabled = true
|
|
40
|
+
el.readonly = true
|
|
41
|
+
el.required = true
|
|
42
|
+
el.invalid = true
|
|
43
|
+
await el.updateComplete
|
|
44
|
+
|
|
45
|
+
expect(el.hasAttribute('disabled')).to.be.true
|
|
46
|
+
expect(el.hasAttribute('readonly')).to.be.true
|
|
47
|
+
expect(el.hasAttribute('required')).to.be.true
|
|
48
|
+
expect(el.hasAttribute('invalid')).to.be.true
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('상태를 해제하면 attribute 도 제거된다', async () => {
|
|
52
|
+
const el = await makeField(html`<test-form-field disabled readonly></test-form-field>`)
|
|
53
|
+
|
|
54
|
+
expect(el.disabled).to.be.true
|
|
55
|
+
expect(el.readonly).to.be.true
|
|
56
|
+
|
|
57
|
+
el.disabled = false
|
|
58
|
+
el.readonly = false
|
|
59
|
+
await el.updateComplete
|
|
60
|
+
|
|
61
|
+
expect(el.hasAttribute('disabled')).to.be.false
|
|
62
|
+
expect(el.hasAttribute('readonly')).to.be.false
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
describe('OxFormField — isEmpty 경계값', () => {
|
|
67
|
+
it('nullish / 빈 문자열 / 공백 / 빈 배열은 비어 있다', async () => {
|
|
68
|
+
const el = await makeField()
|
|
69
|
+
|
|
70
|
+
for (const v of [undefined, null, '', ' ', [] as any[]]) {
|
|
71
|
+
el.value = v
|
|
72
|
+
expect(el.callIsEmpty(), `value=${JSON.stringify(v)}`).to.be.true
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('숫자 0 과 false 는 유효한 값이므로 비어 있지 않다', async () => {
|
|
77
|
+
const el = await makeField()
|
|
78
|
+
|
|
79
|
+
el.value = 0
|
|
80
|
+
expect(el.callIsEmpty(), 'value=0').to.be.false
|
|
81
|
+
|
|
82
|
+
el.value = false
|
|
83
|
+
expect(el.callIsEmpty(), 'value=false').to.be.false
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
describe('OxFormField — 검증', () => {
|
|
88
|
+
it('required 가 아니면 값이 비어도 유효하다', async () => {
|
|
89
|
+
const el = await makeField()
|
|
90
|
+
|
|
91
|
+
expect(el.checkValidity()).to.be.true
|
|
92
|
+
expect(el.invalid).to.be.false
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('required 인데 값이 비면 invalid 가 되고 invalid 이벤트가 올라온다', async () => {
|
|
96
|
+
const el = await makeField(html`<test-form-field required name="f"></test-form-field>`)
|
|
97
|
+
|
|
98
|
+
let detail: any = null
|
|
99
|
+
el.addEventListener('invalid', (e: Event) => {
|
|
100
|
+
detail = (e as CustomEvent).detail
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
expect(el.checkValidity()).to.be.false
|
|
104
|
+
expect(el.invalid).to.be.true
|
|
105
|
+
expect(detail).to.deep.equal({ field: 'f' })
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('값을 채우면 다시 유효해지고 invalid 가 해제된다', async () => {
|
|
109
|
+
const el = await makeField(html`<test-form-field required></test-form-field>`)
|
|
110
|
+
|
|
111
|
+
expect(el.checkValidity()).to.be.false
|
|
112
|
+
|
|
113
|
+
el.value = 'filled'
|
|
114
|
+
expect(el.checkValidity()).to.be.true
|
|
115
|
+
expect(el.invalid).to.be.false
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
describe('OxFormField — 폼 데이터 수집', () => {
|
|
120
|
+
async function collect(fieldTemplate: unknown) {
|
|
121
|
+
const form = (await fixture(html`<form>${fieldTemplate}</form>`)) as HTMLFormElement
|
|
122
|
+
return new FormData(form)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
it('name 이 있으면 값이 폼 데이터에 담긴다', async () => {
|
|
126
|
+
const data = await collect(html`<test-form-field name="a" .value=${'1'}></test-form-field>`)
|
|
127
|
+
|
|
128
|
+
expect(data.get('a')).to.equal('1')
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('배열 값은 여러 항목으로 담긴다', async () => {
|
|
132
|
+
const data = await collect(html`<test-form-field name="b" .value=${['x', 'y']}></test-form-field>`)
|
|
133
|
+
|
|
134
|
+
expect(data.getAll('b')).to.deep.equal(['x', 'y'])
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('disabled 는 폼 데이터에 포함되지 않는다 (HTML 표준 거동)', async () => {
|
|
138
|
+
const data = await collect(html`<test-form-field name="c" disabled .value=${'skip'}></test-form-field>`)
|
|
139
|
+
|
|
140
|
+
expect(data.has('c')).to.be.false
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('readonly 는 수정만 막는 상태이므로 폼 데이터에 포함된다', async () => {
|
|
144
|
+
const data = await collect(html`<test-form-field name="d" readonly .value=${'keep'}></test-form-field>`)
|
|
145
|
+
|
|
146
|
+
expect(data.get('d')).to.equal('keep')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('name 이 없으면 수집되지 않는다', async () => {
|
|
150
|
+
const form = (await fixture(
|
|
151
|
+
html`<form><test-form-field .value=${'anon'}></test-form-field></form>`
|
|
152
|
+
)) as HTMLFormElement
|
|
153
|
+
const data = new FormData(form)
|
|
154
|
+
|
|
155
|
+
/* name 이 없으면 어떤 키로도 담기지 않는다 */
|
|
156
|
+
expect(data.has('')).to.be.false
|
|
157
|
+
expect(data.get('undefined')).to.be.null
|
|
158
|
+
})
|
|
159
|
+
})
|