@operato/input 10.10.0 → 10.10.5
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 +17 -0
- package/dist/src/image-selector.d.ts +5 -5
- package/dist/src/image-selector.js +22 -29
- package/dist/src/image-selector.js.map +1 -1
- package/dist/src/ox-input-background-pattern.d.ts +6 -6
- package/dist/src/ox-input-background-pattern.js +7 -7
- package/dist/src/ox-input-background-pattern.js.map +1 -1
- package/dist/src/ox-input-formula.js +6 -6
- package/dist/src/ox-input-formula.js.map +1 -1
- package/dist/src/ox-input-search.js +7 -7
- package/dist/src/ox-input-search.js.map +1 -1
- package/dist/test/image-selector.test.js +17 -16
- package/dist/test/image-selector.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/test/image-selector.test.ts +17 -16
- package/yarn-error.log +17084 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-input-search.js","sourceRoot":"","sources":["../../src/ox-input-search.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/web/icon/icon.js'\n\n// import debounce from 'lodash-es/debounce.js'\nimport { css, html } from 'lit'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\n\nimport { OxFormField } from './ox-form-field.js'\nimport { InputStyles } from './input-styles.js'\n\n@customElement('ox-input-search')\nexport class OxInputSearch extends OxFormField {\n static styles = [\n InputStyles,\n css`\n :host {\n display: flex;\n position: relative;\n align-items: center;\n\n color: var(--ox-input-search-color, var(--md-sys-color-on-surface-variant));\n background-color: var(--ox-input-search-background-color, var(--md-sys-color-surface-variant));\n\n --md-icon-size: 20px;\n }\n\n [type='text'] {\n flex: 1;\n color: inherit;\n background-color: transparent;\n border: 0;\n padding: var(--input-search-padding, calc(var(--ox-input-gap) / 2));\n padding-left: 25px;\n overflow: hidden;\n }\n\n [type='text']:focus {\n outline: none;\n }\n\n /*\n * 아이콘 색을 글자와 따로 받는다.\n *\n * 돋보기는 **장치**이고 입력한 글자는 **값**이다. 둘이 같은 색이면 장치가 값만큼 눈에 걸린다.\n * 기본은 물려받는 색이라 지금 쓰는 곳의 거동이 바뀌지 않고, 담는 화면이 필요할 때만 내린다.\n */\n md-icon {\n position: absolute;\n color: var(--ox-input-search-icon-color, inherit);\n }\n\n input {\n background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));\n color: var(--input-field-color, var(--md-sys-color-on-surface));\n width: 100%;\n }\n `\n ]\n\n @property({ type: String }) placeholder?: string\n @property({ attribute: 'select-after-change', type: Boolean }) selectAfterChange?: boolean\n @property({ type: Number, attribute: 'max-length' }) maxLength?: number\n\n @query('input') input!: HTMLInputElement\n\n // private dispatchChangeEventDebouncer = debounce((value: string) => this.dispatchChangeEvent(value), 100)\n\n render() {\n return html`\n <!--\n
|
|
1
|
+
{"version":3,"file":"ox-input-search.js","sourceRoot":"","sources":["../../src/ox-input-search.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@material/web/icon/icon.js'\n\n// import debounce from 'lodash-es/debounce.js'\nimport { css, html } from 'lit'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\n\nimport { OxFormField } from './ox-form-field.js'\nimport { InputStyles } from './input-styles.js'\n\n@customElement('ox-input-search')\nexport class OxInputSearch extends OxFormField {\n static styles = [\n InputStyles,\n css`\n :host {\n display: flex;\n position: relative;\n align-items: center;\n\n color: var(--ox-input-search-color, var(--md-sys-color-on-surface-variant));\n background-color: var(--ox-input-search-background-color, var(--md-sys-color-surface-variant));\n\n --md-icon-size: 20px;\n }\n\n [type='text'] {\n flex: 1;\n color: inherit;\n background-color: transparent;\n border: 0;\n padding: var(--input-search-padding, calc(var(--ox-input-gap) / 2));\n padding-left: 25px;\n overflow: hidden;\n }\n\n [type='text']:focus {\n outline: none;\n }\n\n /*\n * 아이콘 색을 글자와 따로 받는다.\n *\n * 돋보기는 **장치**이고 입력한 글자는 **값**이다. 둘이 같은 색이면 장치가 값만큼 눈에 걸린다.\n * 기본은 물려받는 색이라 지금 쓰는 곳의 거동이 바뀌지 않고, 담는 화면이 필요할 때만 내린다.\n */\n md-icon {\n position: absolute;\n color: var(--ox-input-search-icon-color, inherit);\n }\n\n input {\n background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));\n color: var(--input-field-color, var(--md-sys-color-on-surface));\n width: 100%;\n }\n `\n ]\n\n @property({ type: String }) placeholder?: string\n @property({ attribute: 'select-after-change', type: Boolean }) selectAfterChange?: boolean\n @property({ type: Number, attribute: 'max-length' }) maxLength?: number\n\n @query('input') input!: HTMLInputElement\n\n // private dispatchChangeEventDebouncer = debounce((value: string) => this.dispatchChangeEvent(value), 100)\n\n render() {\n return html`\n <!--\n The magnifier runs the search on click, but md-icon takes no focus, so the keyboard never\n reaches it. Enter in the input does the same thing, so no function is blocked. Hiding it\n from assistive tech removes one more unnamed click target and costs nothing.\n -->\n <md-icon aria-hidden=\"true\" @click=${(e: Event) => !this.disabled && this._onClickSearch(e)}>search</md-icon>\n <!--\n Name the input. It had only a placeholder, and a placeholder is not a name: it disappears\n the moment you type, so there is no way to ask again what you were entering, and when the\n caller passes none — which most screens do — nothing is left.\n\n Use whatever the caller set, and fall back to \"search\".\n -->\n <input\n type=\"text\"\n aria-label=${this.placeholder || i18next.t('label.search', { defaultValue: 'search' })}\n .value=${this.value || ''}\n .placeholder=${this.placeholder || ''}\n maxlength=${ifDefined(this.maxLength)}\n @change=${(e: Event) => {\n e.stopPropagation()\n this.dispatchChangeEvent((e.target as HTMLInputElement).value)\n // this.dispatchChangeEventDebouncer((e.target as HTMLInputElement).value)\n }}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n if ((e.target as HTMLInputElement).value == this.value) {\n /* Even if the value has not changed, the enter key triggers a change event. */\n e.preventDefault() /* Prevent change event from occurring twice. */\n\n this.input.dispatchEvent(\n new CustomEvent('change', {\n detail: (e.target as HTMLInputElement).value\n })\n )\n }\n }\n }}\n ?disabled=${this.disabled}\n />\n `\n }\n\n firstUpdated() {\n if (this.autofocus) {\n this.input.focus()\n }\n }\n\n dispatchChangeEvent(value: string) {\n this.value = value\n\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: value\n })\n )\n\n if (this.selectAfterChange) {\n requestAnimationFrame(() => {\n this.input.select()\n })\n }\n }\n\n _onClickSearch(e: Event) {\n if (this._form) {\n e.stopPropagation()\n this._form.requestSubmit()\n } else {\n this.input.dispatchEvent(\n new CustomEvent('change', {\n detail: this.input.value\n })\n )\n }\n }\n}\n"]}
|
|
@@ -3,47 +3,48 @@ import { html } from 'lit';
|
|
|
3
3
|
import '../src/ox-input-background-pattern.js';
|
|
4
4
|
import { registerImageSelector } from '../src/image-selector.js';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* The image-picking slot.
|
|
7
7
|
*
|
|
8
|
-
* ##
|
|
8
|
+
* ## Why this is tested
|
|
9
9
|
*
|
|
10
|
-
* `@operato/input`
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* `@operato/input` used to import `@operato/attachment` directly. The bottom layer reached for a
|
|
11
|
+
* feature above it, closing a cycle (input ▶ attachment ▶ data-grist ▶ input) that stopped this
|
|
12
|
+
* package from building — TS5055 on seven files, with `noEmitOnError`.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* Reversing that arrow has to hold two things:
|
|
15
15
|
*
|
|
16
16
|
* ```
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* never empty with nothing registered there must still be a field; an unregistered
|
|
18
|
+
* custom element renders as a silent empty box
|
|
19
|
+
* value lands either branch carries value-key and raises change, so the value takes
|
|
20
|
+
* the same path out
|
|
19
21
|
* ```
|
|
20
22
|
*/
|
|
21
|
-
describe('
|
|
23
|
+
describe('image-picking field', () => {
|
|
22
24
|
async function pattern(value = {}) {
|
|
23
25
|
const el = await fixture(html `<ox-input-background-pattern .value=${value}></ox-input-background-pattern>`);
|
|
24
26
|
await el.updateComplete;
|
|
25
27
|
return el;
|
|
26
28
|
}
|
|
27
|
-
it('
|
|
29
|
+
it('falls back to a text box when nothing is registered', async () => {
|
|
28
30
|
const el = await pattern({ image: 'https://example.com/a.png' });
|
|
29
31
|
const field = el.renderRoot.querySelector('[value-key="image"]');
|
|
30
|
-
expect(field, '
|
|
32
|
+
expect(field, 'no image field at all').to.exist;
|
|
31
33
|
expect(field.tagName).to.equal('INPUT');
|
|
32
|
-
expect(field.value, '
|
|
34
|
+
expect(field.value, 'existing address did not reach the field').to.equal('https://example.com/a.png');
|
|
33
35
|
});
|
|
34
|
-
it('
|
|
36
|
+
it('takes an address typed into the fallback text box', async () => {
|
|
35
37
|
const el = await pattern({});
|
|
36
38
|
const field = el.renderRoot.querySelector('[value-key="image"]');
|
|
37
39
|
field.value = 'https://example.com/b.png';
|
|
38
40
|
field.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
39
41
|
expect(el.value.image).to.equal('https://example.com/b.png');
|
|
40
42
|
});
|
|
41
|
-
it('
|
|
43
|
+
it('swaps in the registered field, even when registration lands after render', async () => {
|
|
42
44
|
class FakeSelector extends HTMLElement {
|
|
43
45
|
}
|
|
44
46
|
customElements.define('test-image-selector', FakeSelector);
|
|
45
47
|
const el = await pattern({ image: 'https://example.com/c.png' });
|
|
46
|
-
/* 요소가 먼저 그려지고 등록이 나중에 와도 자리가 글자 칸으로 남아 있으면 안 된다. */
|
|
47
48
|
registerImageSelector('test-image-selector');
|
|
48
49
|
await el.updateComplete;
|
|
49
50
|
const field = el.renderRoot.querySelector('[value-key="image"]');
|
|
@@ -51,7 +52,7 @@ describe('그림 고르는 칸은 위 layer 가 채운다', () => {
|
|
|
51
52
|
expect(field.value).to.equal('https://example.com/c.png');
|
|
52
53
|
expect(field.properties).to.deep.equal({ category: 'image' });
|
|
53
54
|
});
|
|
54
|
-
it('
|
|
55
|
+
it('takes a change raised by the registered field the same way', async () => {
|
|
55
56
|
registerImageSelector('test-image-selector');
|
|
56
57
|
const el = await pattern({});
|
|
57
58
|
const field = el.renderRoot.querySelector('[value-key="image"]');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-selector.test.js","sourceRoot":"","sources":["../../test/image-selector.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,uCAAuC,CAAA;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE
|
|
1
|
+
{"version":3,"file":"image-selector.test.js","sourceRoot":"","sources":["../../test/image-selector.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/ox-input-background-pattern.js'\nimport { registerImageSelector } from '../src/image-selector.js'\n\n/**\n * The image-picking slot.\n *\n * ## Why this is tested\n *\n * `@operato/input` used to import `@operato/attachment` directly. The bottom layer reached for a\n * feature above it, closing a cycle (input ▶ attachment ▶ data-grist ▶ input) that stopped this\n * package from building — TS5055 on seven files, with `noEmitOnError`.\n *\n * Reversing that arrow has to hold two things:\n *\n * ```\n * never empty with nothing registered there must still be a field; an unregistered\n * custom element renders as a silent empty box\n * value lands either branch carries value-key and raises change, so the value takes\n * the same path out\n * ```\n */\ndescribe('image-picking field', () => {\n async function pattern(value: any = {}) {\n const el: any = await fixture(html`<ox-input-background-pattern .value=${value}></ox-input-background-pattern>`)\n await el.updateComplete\n return el\n }\n\n it('falls back to a text box when nothing is registered', async () => {\n const el = await pattern({ image: 'https://example.com/a.png' })\n\n const field = el.renderRoot.querySelector('[value-key=\"image\"]') as HTMLInputElement\n\n expect(field, 'no image field at all').to.exist\n expect(field.tagName).to.equal('INPUT')\n expect(field.value, 'existing address did not reach the field').to.equal('https://example.com/a.png')\n })\n\n it('takes an address typed into the fallback text box', async () => {\n const el = await pattern({})\n\n const field = el.renderRoot.querySelector('[value-key=\"image\"]') as HTMLInputElement\n field.value = 'https://example.com/b.png'\n field.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n\n expect(el.value.image).to.equal('https://example.com/b.png')\n })\n\n it('swaps in the registered field, even when registration lands after render', async () => {\n class FakeSelector extends HTMLElement {\n value: any\n properties: any\n }\n customElements.define('test-image-selector', FakeSelector)\n\n const el = await pattern({ image: 'https://example.com/c.png' })\n\n registerImageSelector('test-image-selector')\n await el.updateComplete\n\n const field = el.renderRoot.querySelector('[value-key=\"image\"]') as any\n\n expect(field.tagName).to.equal('TEST-IMAGE-SELECTOR')\n expect(field.value).to.equal('https://example.com/c.png')\n expect(field.properties).to.deep.equal({ category: 'image' })\n })\n\n it('takes a change raised by the registered field the same way', async () => {\n registerImageSelector('test-image-selector')\n\n const el = await pattern({})\n const field = el.renderRoot.querySelector('[value-key=\"image\"]') as any\n\n field.value = 'https://example.com/d.png'\n field.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n\n expect(el.value.image).to.equal('https://example.com/d.png')\n })\n})\n"]}
|