@operato/property-editor 10.28.0 → 10.29.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.
@@ -0,0 +1,25 @@
1
+ import { TemplateResult } from 'lit';
2
+ import { OxPropertyEditor } from './ox-property-editor.js';
3
+ import { PropertySpec } from './types.js';
4
+ /** One number of the map: its key, the name shown, and what it is held to. */
5
+ export interface NumberMapEntry {
6
+ key: string;
7
+ label: string;
8
+ unit?: string;
9
+ min?: number;
10
+ max?: number;
11
+ default?: number;
12
+ }
13
+ /**
14
+ * Several numbers kept as one map ({ key: number }) -- a figure's design values a board sets (ADR-0096), a shelf's
15
+ * spacings. Each entry is the number editor's field on a row of its own, its unit beside it, its range and default in
16
+ * the placeholder. A value outside its range is not taken: the field goes back to what it was. A change sends the whole
17
+ * map, so the map is the one value the component holds.
18
+ *
19
+ * Built by the Figure lane after the existing editors (chief architect, 2026-09-26); open for the UX lane's review.
20
+ */
21
+ export declare class OxPropertyEditorNumberMap extends OxPropertyEditor {
22
+ editorTemplate(value: any, spec: PropertySpec): TemplateResult;
23
+ private hintOf;
24
+ _valueChanged(e: Event): void;
25
+ }
@@ -0,0 +1,75 @@
1
+ import { __decorate } from "tslib";
2
+ import { html } from 'lit';
3
+ import { customElement } from 'lit/decorators.js';
4
+ import { ifDefined } from 'lit/directives/if-defined.js';
5
+ import { OxPropertyEditor } from './ox-property-editor.js';
6
+ /**
7
+ * Several numbers kept as one map ({ key: number }) -- a figure's design values a board sets (ADR-0096), a shelf's
8
+ * spacings. Each entry is the number editor's field on a row of its own, its unit beside it, its range and default in
9
+ * the placeholder. A value outside its range is not taken: the field goes back to what it was. A change sends the whole
10
+ * map, so the map is the one value the component holds.
11
+ *
12
+ * Built by the Figure lane after the existing editors (chief architect, 2026-09-26); open for the UX lane's review.
13
+ */
14
+ let OxPropertyEditorNumberMap = class OxPropertyEditorNumberMap extends OxPropertyEditor {
15
+ editorTemplate(value, spec) {
16
+ var _a, _b;
17
+ const entries = (_b = (_a = spec.property) === null || _a === void 0 ? void 0 : _a.entries) !== null && _b !== void 0 ? _b : [];
18
+ const map = value && typeof value === 'object' ? value : {};
19
+ return html `
20
+ <div fullwidth>
21
+ ${entries.map(entry => {
22
+ var _a, _b;
23
+ return html `
24
+ <div data-key=${entry.key} style="display: flex; align-items: center; gap: var(--spacing-small, 4px)">
25
+ <span style="flex: 1">${entry.label}</span>
26
+ <input
27
+ type="number"
28
+ data-key=${entry.key}
29
+ aria-label=${entry.label}
30
+ style="flex: 1"
31
+ .value=${String((_b = (_a = map[entry.key]) !== null && _a !== void 0 ? _a : entry.default) !== null && _b !== void 0 ? _b : '')}
32
+ placeholder=${ifDefined(this.hintOf(entry))}
33
+ min=${ifDefined(entry.min)}
34
+ max=${ifDefined(entry.max)}
35
+ ?disabled=${this.disabled}
36
+ />
37
+ ${entry.unit ? html `<span>${entry.unit}</span>` : ''}
38
+ </div>
39
+ `;
40
+ })}
41
+ </div>
42
+ `;
43
+ }
44
+ hintOf(entry) {
45
+ const range = entry.min !== undefined && entry.max !== undefined ? `${entry.min}–${entry.max}` : undefined;
46
+ const standard = entry.default !== undefined ? `(${entry.default})` : undefined;
47
+ return [range, standard].filter(Boolean).join(' ') || undefined;
48
+ }
49
+ _valueChanged(e) {
50
+ var _a, _b, _c, _d;
51
+ e.stopPropagation();
52
+ const input = e.target;
53
+ const key = input.getAttribute('data-key');
54
+ if (!key)
55
+ return;
56
+ const entry = ((_b = (_a = this.property) === null || _a === void 0 ? void 0 : _a.entries) !== null && _b !== void 0 ? _b : []).find(one => one.key === key);
57
+ const map = this.value && typeof this.value === 'object' ? { ...this.value } : {};
58
+ const number = input.valueAsNumber;
59
+ const outside = !Number.isFinite(number) || ((entry === null || entry === void 0 ? void 0 : entry.min) !== undefined && number < entry.min) || ((entry === null || entry === void 0 ? void 0 : entry.max) !== undefined && number > entry.max);
60
+ if (outside) {
61
+ /* Not taken: the field shows what the map holds. */
62
+ input.value = String((_d = (_c = map[key]) !== null && _c !== void 0 ? _c : entry === null || entry === void 0 ? void 0 : entry.default) !== null && _d !== void 0 ? _d : '');
63
+ return;
64
+ }
65
+ map[key] = number;
66
+ this.value = map;
67
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
68
+ this.observe(this.value);
69
+ }
70
+ };
71
+ OxPropertyEditorNumberMap = __decorate([
72
+ customElement('ox-property-editor-number-map')
73
+ ], OxPropertyEditorNumberMap);
74
+ export { OxPropertyEditorNumberMap };
75
+ //# sourceMappingURL=ox-property-editor-number-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ox-property-editor-number-map.js","sourceRoot":"","sources":["../../src/ox-property-editor-number-map.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { OxPropertyEditor } from './ox-property-editor.js'\nimport { PropertySpec } from './types.js'\n\n/** One number of the map: its key, the name shown, and what it is held to. */\nexport interface NumberMapEntry {\n key: string\n label: string\n unit?: string\n min?: number\n max?: number\n default?: number\n}\n\n/**\n * Several numbers kept as one map ({ key: number }) -- a figure's design values a board sets (ADR-0096), a shelf's\n * spacings. Each entry is the number editor's field on a row of its own, its unit beside it, its range and default in\n * the placeholder. A value outside its range is not taken: the field goes back to what it was. A change sends the whole\n * map, so the map is the one value the component holds.\n *\n * Built by the Figure lane after the existing editors (chief architect, 2026-09-26); open for the UX lane's review.\n */\n@customElement('ox-property-editor-number-map')\nexport class OxPropertyEditorNumberMap extends OxPropertyEditor {\n editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n const entries: NumberMapEntry[] = spec.property?.entries ?? []\n const map: Record<string, number> = value && typeof value === 'object' ? value : {}\n return html`\n <div fullwidth>\n ${entries.map(\n entry => html`\n <div data-key=${entry.key} style=\"display: flex; align-items: center; gap: var(--spacing-small, 4px)\">\n <span style=\"flex: 1\">${entry.label}</span>\n <input\n type=\"number\"\n data-key=${entry.key}\n aria-label=${entry.label}\n style=\"flex: 1\"\n .value=${String(map[entry.key] ?? entry.default ?? '')}\n placeholder=${ifDefined(this.hintOf(entry))}\n min=${ifDefined(entry.min)}\n max=${ifDefined(entry.max)}\n ?disabled=${this.disabled}\n />\n ${entry.unit ? html`<span>${entry.unit}</span>` : ''}\n </div>\n `\n )}\n </div>\n `\n }\n\n private hintOf(entry: NumberMapEntry): string | undefined {\n const range = entry.min !== undefined && entry.max !== undefined ? `${entry.min}–${entry.max}` : undefined\n const standard = entry.default !== undefined ? `(${entry.default})` : undefined\n return [range, standard].filter(Boolean).join(' ') || undefined\n }\n\n override _valueChanged(e: Event) {\n e.stopPropagation()\n const input = e.target as HTMLInputElement\n const key = input.getAttribute('data-key')\n if (!key) return\n const entry = ((this.property?.entries ?? []) as NumberMapEntry[]).find(one => one.key === key)\n const map: Record<string, number> = this.value && typeof this.value === 'object' ? { ...this.value } : {}\n const number = input.valueAsNumber\n const outside = !Number.isFinite(number) || (entry?.min !== undefined && number < entry.min) || (entry?.max !== undefined && number > entry.max)\n if (outside) {\n /* Not taken: the field shows what the map holds. */\n input.value = String(map[key] ?? entry?.default ?? '')\n return\n }\n map[key] = number\n this.value = map\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n this.observe(this.value)\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ import '../src/ox-property-editor-number-map.js';
@@ -0,0 +1,55 @@
1
+ import { expect, fixture, oneEvent } from '@open-wc/testing';
2
+ import { html } from 'lit';
3
+ import '../src/ox-property-editor-number-map.js';
4
+ /**
5
+ * Several numbers as one map (ADR-0096): a board's design values for a figure. A value within range becomes part of the
6
+ * map and the whole map is told; one outside its range is not taken and the field shows what the map holds.
7
+ */
8
+ describe('number-map', () => {
9
+ const entries = [
10
+ { key: 'pitch', label: '롤러 간격', unit: 'mm', min: 100, max: 400, default: 200 },
11
+ { key: 'gap', label: '틈', unit: 'mm', min: 0, max: 50, default: 10 }
12
+ ];
13
+ const make = () => fixture(html `<ox-property-editor-number-map name="designInputs" .property=${{ entries }} .value=${{ pitch: 150 }}></ox-property-editor-number-map>`);
14
+ const field = (el, key) => el.renderRoot.querySelector(`input[data-key="${key}"]`);
15
+ it('shows each value, or its default, with its range', async () => {
16
+ const el = await make();
17
+ expect(field(el, 'pitch').value).to.equal('150');
18
+ expect(field(el, 'gap').value).to.equal('10');
19
+ expect(field(el, 'pitch').placeholder).to.equal('100–400 (200)');
20
+ });
21
+ it('a value within range: the whole map is told', async () => {
22
+ const el = await make();
23
+ const input = field(el, 'gap');
24
+ input.value = '20';
25
+ const told = oneEvent(el, 'change');
26
+ input.dispatchEvent(new Event('change', { bubbles: true }));
27
+ await told;
28
+ expect(el.value).to.deep.equal({ pitch: 150, gap: 20 });
29
+ });
30
+ it('a value outside its range is not taken: nothing is told, the field shows the map again', async () => {
31
+ const el = await make();
32
+ let told = false;
33
+ el.addEventListener('change', () => (told = true));
34
+ const input = field(el, 'pitch');
35
+ input.value = '1000';
36
+ input.dispatchEvent(new Event('change', { bubbles: true }));
37
+ await el.updateComplete;
38
+ expect(told).to.equal(false);
39
+ expect(el.value).to.deep.equal({ pitch: 150 });
40
+ expect(input.value).to.equal('150');
41
+ });
42
+ it('an emptied field is not a number: not taken, the field shows the map again', async () => {
43
+ const el = await make();
44
+ let told = false;
45
+ el.addEventListener('change', () => (told = true));
46
+ const input = field(el, 'gap');
47
+ input.value = '';
48
+ input.dispatchEvent(new Event('change', { bubbles: true }));
49
+ await el.updateComplete;
50
+ expect(told).to.equal(false);
51
+ expect(el.value).to.deep.equal({ pitch: 150 });
52
+ expect(input.value).to.equal('10');
53
+ });
54
+ });
55
+ //# sourceMappingURL=number-map.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-map.test.js","sourceRoot":"","sources":["../../test/number-map.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,yCAAyC,CAAA;AAGhD;;;GAGG;AACH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,MAAM,OAAO,GAAG;QACd,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;QAC9E,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;KACrE,CAAA;IACD,MAAM,IAAI,GAAG,GAAG,EAAE,CAChB,OAAO,CAA4B,IAAI,CAAA,gEAAgE,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,mCAAmC,CAAC,CAAA;IACjL,MAAM,KAAK,GAAG,CAAC,EAA6B,EAAE,GAAW,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,GAAG,IAAI,CAAqB,CAAA;IAEzI,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QACvB,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAChD,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC7C,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QAC9B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;QACnC,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC3D,MAAM,IAAI,CAAA;QACV,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wFAAwF,EAAE,KAAK,IAAI,EAAE;QACtG,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QACvB,IAAI,IAAI,GAAG,KAAK,CAAA;QAChB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QAChC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAA;QACpB,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC3D,MAAM,EAAE,CAAC,cAAc,CAAA;QACvB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QAC9C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QACvB,IAAI,IAAI,GAAG,KAAK,CAAA;QAChB,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;QAC9B,KAAK,CAAC,KAAK,GAAG,EAAE,CAAA;QAChB,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC3D,MAAM,EAAE,CAAC,cAAc,CAAA;QACvB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QAC9C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { expect, fixture, oneEvent } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/ox-property-editor-number-map.js'\nimport type { OxPropertyEditorNumberMap } from '../src/ox-property-editor-number-map.js'\n\n/**\n * Several numbers as one map (ADR-0096): a board's design values for a figure. A value within range becomes part of the\n * map and the whole map is told; one outside its range is not taken and the field shows what the map holds.\n */\ndescribe('number-map', () => {\n const entries = [\n { key: 'pitch', label: '롤러 간격', unit: 'mm', min: 100, max: 400, default: 200 },\n { key: 'gap', label: '틈', unit: 'mm', min: 0, max: 50, default: 10 }\n ]\n const make = () =>\n fixture<OxPropertyEditorNumberMap>(html`<ox-property-editor-number-map name=\"designInputs\" .property=${{ entries }} .value=${{ pitch: 150 }}></ox-property-editor-number-map>`)\n const field = (el: OxPropertyEditorNumberMap, key: string) => el.renderRoot.querySelector(`input[data-key=\"${key}\"]`) as HTMLInputElement\n\n it('shows each value, or its default, with its range', async () => {\n const el = await make()\n expect(field(el, 'pitch').value).to.equal('150')\n expect(field(el, 'gap').value).to.equal('10')\n expect(field(el, 'pitch').placeholder).to.equal('100–400 (200)')\n })\n\n it('a value within range: the whole map is told', async () => {\n const el = await make()\n const input = field(el, 'gap')\n input.value = '20'\n const told = oneEvent(el, 'change')\n input.dispatchEvent(new Event('change', { bubbles: true }))\n await told\n expect(el.value).to.deep.equal({ pitch: 150, gap: 20 })\n })\n\n it('a value outside its range is not taken: nothing is told, the field shows the map again', async () => {\n const el = await make()\n let told = false\n el.addEventListener('change', () => (told = true))\n const input = field(el, 'pitch')\n input.value = '1000'\n input.dispatchEvent(new Event('change', { bubbles: true }))\n await el.updateComplete\n expect(told).to.equal(false)\n expect(el.value).to.deep.equal({ pitch: 150 })\n expect(input.value).to.equal('150')\n })\n\n it('an emptied field is not a number: not taken, the field shows the map again', async () => {\n const el = await make()\n let told = false\n el.addEventListener('change', () => (told = true))\n const input = field(el, 'gap')\n input.value = ''\n input.dispatchEvent(new Event('change', { bubbles: true }))\n await el.updateComplete\n expect(told).to.equal(false)\n expect(el.value).to.deep.equal({ pitch: 150 })\n expect(input.value).to.equal('10')\n })\n})\n"]}