@things-factory/figure-ui 10.1.224 → 10.1.226

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.
Files changed (84) hide show
  1. package/client/modeller/consumer-capabilities.ts +15 -0
  2. package/client/modeller/editor-styles.ts +21 -3
  3. package/client/modeller/editor.ts +41 -27
  4. package/client/modeller/figure-capability-panel.ts +37 -10
  5. package/client/modeller/figure-clips.ts +3 -2
  6. package/client/modeller/figure-controls.ts +4 -3
  7. package/client/modeller/figure-data-panel.ts +41 -21
  8. package/client/modeller/figure-links.ts +5 -5
  9. package/client/modeller/figure-material-panel.ts +2 -0
  10. package/client/modeller/figure-preview.ts +115 -8
  11. package/client/modeller/figure-recipe-catalog.ts +4 -0
  12. package/client/modeller/figure-slot-layout-panel.ts +25 -8
  13. package/client/modeller/figure-verdict.ts +4 -1
  14. package/client/modeller/product-session.ts +3 -2
  15. package/client/modeller/unit-words.ts +11 -0
  16. package/client/pages/figure-modeller-page.ts +5 -4
  17. package/dist-client/modeller/consumer-capabilities.d.ts +11 -0
  18. package/dist-client/modeller/consumer-capabilities.js +14 -0
  19. package/dist-client/modeller/consumer-capabilities.js.map +1 -1
  20. package/dist-client/modeller/editor-styles.js +21 -3
  21. package/dist-client/modeller/editor-styles.js.map +1 -1
  22. package/dist-client/modeller/editor.js +43 -29
  23. package/dist-client/modeller/editor.js.map +1 -1
  24. package/dist-client/modeller/figure-capability-panel.d.ts +3 -0
  25. package/dist-client/modeller/figure-capability-panel.js +35 -11
  26. package/dist-client/modeller/figure-capability-panel.js.map +1 -1
  27. package/dist-client/modeller/figure-clips.js +3 -2
  28. package/dist-client/modeller/figure-clips.js.map +1 -1
  29. package/dist-client/modeller/figure-controls.js +4 -3
  30. package/dist-client/modeller/figure-controls.js.map +1 -1
  31. package/dist-client/modeller/figure-data-panel.js +42 -21
  32. package/dist-client/modeller/figure-data-panel.js.map +1 -1
  33. package/dist-client/modeller/figure-links.js +5 -5
  34. package/dist-client/modeller/figure-links.js.map +1 -1
  35. package/dist-client/modeller/figure-material-panel.js +2 -0
  36. package/dist-client/modeller/figure-material-panel.js.map +1 -1
  37. package/dist-client/modeller/figure-preview.d.ts +3 -0
  38. package/dist-client/modeller/figure-preview.js +124 -8
  39. package/dist-client/modeller/figure-preview.js.map +1 -1
  40. package/dist-client/modeller/figure-recipe-catalog.js +4 -0
  41. package/dist-client/modeller/figure-recipe-catalog.js.map +1 -1
  42. package/dist-client/modeller/figure-slot-layout-panel.d.ts +1 -1
  43. package/dist-client/modeller/figure-slot-layout-panel.js +25 -8
  44. package/dist-client/modeller/figure-slot-layout-panel.js.map +1 -1
  45. package/dist-client/modeller/figure-verdict.js +4 -1
  46. package/dist-client/modeller/figure-verdict.js.map +1 -1
  47. package/dist-client/modeller/product-session.d.ts +4 -2
  48. package/dist-client/modeller/product-session.js +3 -2
  49. package/dist-client/modeller/product-session.js.map +1 -1
  50. package/dist-client/modeller/unit-words.d.ts +5 -0
  51. package/dist-client/modeller/unit-words.js +12 -0
  52. package/dist-client/modeller/unit-words.js.map +1 -0
  53. package/dist-client/pages/figure-modeller-page.js +5 -4
  54. package/dist-client/pages/figure-modeller-page.js.map +1 -1
  55. package/dist-client/tsconfig.tsbuildinfo +1 -1
  56. package/package.json +10 -10
  57. package/test/ai-proposal.test.ts +2 -2
  58. package/test/browser/editing-page.js +3 -3
  59. package/test/browser/editing.check.mjs +5 -5
  60. package/test/browser/links-page.js +1 -1
  61. package/test/browser/links.check.mjs +2 -3
  62. package/test/browser/modeller-page.js +4 -4
  63. package/test/browser/modeller-revision.check.mjs +5 -5
  64. package/test/browser/modeller.check.mjs +5 -5
  65. package/test/browser/parts.check.mjs +2 -2
  66. package/test/browser/product-page.check.mjs +31 -0
  67. package/test/browser/props.check.mjs +3 -4
  68. package/test/browser/row-preview.check.mjs +3 -3
  69. package/test/browser/screen.check.mjs +13 -11
  70. package/test/browser/side-panel-sweep.check.mjs +182 -0
  71. package/test/consumer-capabilities.test.ts +7 -0
  72. package/test/figure-assistant-surface.test.ts +1 -1
  73. package/test/first-save.test.ts +2 -2
  74. package/test/links.test.ts +1 -1
  75. package/test/product-session.test.ts +5 -5
  76. package/test/proposal-record.test.ts +3 -3
  77. package/test/refusals.test.ts +1 -1
  78. package/test/revert-keeping.test.ts +1 -1
  79. package/translations/en.json +24 -12
  80. package/translations/es.json +24 -12
  81. package/translations/ja.json +25 -13
  82. package/translations/ko.json +83 -71
  83. package/translations/ms.json +24 -12
  84. package/translations/zh.json +24 -12
@@ -3,6 +3,7 @@ import '@material/web/icon/icon.js';
3
3
  import { css, html, LitElement, nothing } from 'lit';
4
4
  import { customElement, property, state } from 'lit/decorators.js';
5
5
  import { i18next, localize } from '@operato/i18n';
6
+ import { unitWord } from './unit-words.js';
6
7
  import { FIGURE_UNITS, figureDataExample, inferFigureDataSchema } from '@hatiolab/figure-model';
7
8
  import { accessorOfRow, behaviorKeyOf, behaviorsOf, bindingDraftOf, domainOf, endlessJointsOf, fieldAt, fieldOfKind, fitsField, freeCodeOf, legendRoleOf, methodOf, methodsOf, partsOf, rotationStepsOf, sampleOf, schemaRowsOf, schemaWithField, schemaWithFieldReplaced, schemaWithoutField, schemaFollowingCodes, stateInputsOf, tableColumnsOf, tableDraftOf, tableWithKeys, tableWithLook, tableWithTargets } from './data-interface.js';
8
9
  import { SidePanelStyles } from '@things-factory/figure-viewer/dist-client/side-panel-styles.js';
@@ -112,6 +113,17 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
112
113
  overflow-wrap: anywhere;
113
114
  cursor: pointer;
114
115
  }
116
+ /* What it reads and where on the first line, its method under it: a method wrapped alone read 「· 배율」 (sweep 2026-10-27 U11). */
117
+ div[head] button[line] small {
118
+ display: block;
119
+ color: var(--md-sys-color-on-surface-variant);
120
+ }
121
+ /* A binding a product capability takes over is marked where the list is read, folded or not (sweep 2026-10-27 U18). */
122
+ div[head] button[line] span[rests] {
123
+ padding: 0 6px;
124
+ border: 1px solid var(--md-sys-color-outline-variant);
125
+ border-radius: 999px;
126
+ }
115
127
  div[head] button[act] {
116
128
  width: 30px;
117
129
  min-height: var(--figure-control-height);
@@ -255,7 +267,7 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
255
267
  const kind = i18next.t('figure.label.data-kind-' + node.kind);
256
268
  if (node.kind === 'number') {
257
269
  const range = node.min !== undefined || node.max !== undefined ? ` ${node.min ?? ''}~${node.max ?? ''}` : '';
258
- return `${kind}${node.unit ? ` ${node.unit}` : ''}${range}`;
270
+ return `${kind}${node.unit ? ` ${unitWord(node.unit)}` : ''}${range}`;
259
271
  }
260
272
  if (node.kind === 'text' && node.values)
261
273
  return `${kind} (${node.values.join(', ')})`;
@@ -302,7 +314,7 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
302
314
  this.edit({ kind: 'set-data-schema', schema: schemaWithoutField(schema, row.path) });
303
315
  }}
304
316
  >
305
- <md-icon>close</md-icon>
317
+ <md-icon>delete</md-icon>
306
318
  </button>
307
319
  </div>
308
320
  <div form>
@@ -317,8 +329,8 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
317
329
  ${field.kind === 'number'
318
330
  ? html `<span>${i18next.t('figure.label.data-unit')}</span>
319
331
  <select ?disabled=${this.locked} @change=${(e) => set({ unit: value(e) || undefined })}>
320
- <option value="" ?selected=${!field.unit}>-</option>
321
- ${FIGURE_UNITS.map(u => html `<option value=${u} ?selected=${u === field.unit}>${u}</option>`)}
332
+ <option value="" ?selected=${!field.unit}>${i18next.t('figure.label.unit-none')}</option>
333
+ ${FIGURE_UNITS.map(u => html `<option value=${u} ?selected=${u === field.unit}>${unitWord(u)}</option>`)}
322
334
  </select>
323
335
  <span>${i18next.t('figure.label.data-min')}</span>
324
336
  <input type="number" step="any" .value=${field.min === undefined ? '' : String(field.min)} ?disabled=${this.locked} @change=${(e) => set({ min: number(e) })} />
@@ -367,22 +379,26 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
367
379
  renderAddField(schema, under) {
368
380
  const a = this.adding;
369
381
  const named = a.name.trim();
382
+ const add = () => {
383
+ if (this.locked || !named)
384
+ return;
385
+ this.edit({ kind: 'set-data-schema', schema: schemaWithField(schema, under, { name: named, ...nodeOfKind(a.kind) }) });
386
+ this.adding = { ...a, name: '' };
387
+ };
370
388
  return html `<div form>
371
389
  <span>${i18next.t('figure.label.data-name')}</span>
372
- <input .value=${a.name} @input=${(e) => (this.adding = { ...a, name: e.target.value })} />
390
+ <input
391
+ aria-label=${i18next.t('figure.label.data-name')}
392
+ .value=${a.name}
393
+ @input=${(e) => (this.adding = { ...a, name: e.target.value })}
394
+ @keydown=${(e) => e.key === 'Enter' && !e.isComposing && add()}
395
+ />
373
396
  <span>${i18next.t('figure.label.data-kind')}</span>
374
397
  <select @change=${(e) => (this.adding = { ...a, kind: e.target.value })}>
375
398
  ${KINDS.map(k => html `<option value=${k} ?selected=${k === a.kind}>${i18next.t('figure.label.data-kind-' + k)}</option>`)}
376
399
  </select>
377
400
  </div>
378
- <button
379
- act
380
- ?disabled=${this.locked || !named}
381
- @click=${() => {
382
- this.edit({ kind: 'set-data-schema', schema: schemaWithField(schema, under, { name: named, ...nodeOfKind(a.kind) }) });
383
- this.adding = { ...a, name: '' };
384
- }}
385
- >
401
+ <button act ?disabled=${this.locked || !named} @click=${add}>
386
402
  <md-icon>add</md-icon>${i18next.t(under ? 'figure.button.add-data-child' : 'figure.button.add-data-field', { parent: under })}
387
403
  </button>`;
388
404
  }
@@ -449,13 +465,15 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
449
465
  const open = this.opened === b.id;
450
466
  const set = (next) => this.edit({ kind: 'set-data-binding', binding: next });
451
467
  const what = b.rule === 'table' ? this.targetsName(asset, b) : this.behaviorName(asset, choices, b.behavior);
468
+ const rests = resting.some(r => r.id === b.id);
452
469
  return html `<section item>
453
470
  <div head>
454
471
  <button line aria-expanded=${open ? 'true' : 'false'} @click=${() => (this.opened = open ? '' : b.id)}>
455
- <strong>${b.label ?? b.accessor}</strong> → ${what} <small>· ${i18next.t('figure.label.data-method-' + methodOf(b))}</small>
472
+ <strong>${b.label ?? b.accessor}</strong> → ${what}
473
+ <small>${i18next.t('figure.label.data-method-' + methodOf(b))}${rests ? html ` <span rests>${i18next.t('figure.label.data-binding-resting')}</span>` : nothing}</small>
456
474
  </button>
457
475
  <button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-data-binding')} @click=${() => this.edit({ kind: 'remove-data-binding', id: b.id })}>
458
- <md-icon>close</md-icon>
476
+ <md-icon>delete</md-icon>
459
477
  </button>
460
478
  </div>
461
479
  ${resting.filter(r => r.id === b.id).map(r => this.renderResting(r))}
@@ -642,7 +660,7 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
642
660
  return html `<div looks style="grid-template-columns: ${gridOf(keyCells, columns.length)}">
643
661
  <span style="grid-column: span ${keyCells}">${i18next.t('figure.label.data-otherwise')}</span>
644
662
  ${this.lookCells(asset, columns, look, l => set(tableWithLook(b, 'default', l)))}
645
- ${needed ? html `<span></span>` : html `<button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-data-case')} @click=${() => set({ ...b, table: rest })}><md-icon>close</md-icon></button>`}
663
+ ${needed ? html `<span></span>` : html `<button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-data-case')} @click=${() => set({ ...b, table: rest })}><md-icon>delete</md-icon></button>`}
646
664
  </div>`;
647
665
  }
648
666
  /**
@@ -677,7 +695,7 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
677
695
  ${this.lookCells(asset, columns, look, l => set(tableWithLook(b, k, l)))}
678
696
  ${boolean || rows.length < 2 && domain.length > 0
679
697
  ? html `<span></span>`
680
- : html `<button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-data-case')} @click=${() => rekeyed(rows.filter((_, j) => j !== i))}><md-icon>close</md-icon></button>`}`)}
698
+ : html `<button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-data-case')} @click=${() => rekeyed(rows.filter((_, j) => j !== i))}><md-icon>delete</md-icon></button>`}`)}
681
699
  </div>
682
700
  ${this.renderOtherwise(asset, b, columns, domain.length > 0 && !covered, set, 1)}
683
701
  ${boolean
@@ -720,7 +738,7 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
720
738
  return html `<input type="number" step="any" .value=${e.from} ?disabled=${this.locked} @change=${(ev) => rekey(i, 'from', ev.target.value)} />
721
739
  <input type="number" step="any" .value=${e.to} ?disabled=${this.locked} @change=${(ev) => rekey(i, 'to', ev.target.value)} />
722
740
  ${this.lookCells(asset, columns, look, l => set(tableWithLook(b, k, l)))}
723
- <button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-data-range')} @click=${() => set(tableWithKeys(b, rows.filter((_, j) => j !== i)))}><md-icon>close</md-icon></button>`;
741
+ <button act ?disabled=${this.locked} title=${i18next.t('figure.button.remove-data-range')} @click=${() => set(tableWithKeys(b, rows.filter((_, j) => j !== i)))}><md-icon>delete</md-icon></button>`;
724
742
  })}
725
743
  </div>
726
744
  ${this.renderOtherwise(asset, b, columns, false, set, 2)}
@@ -810,9 +828,12 @@ let FigureDataPanel = class FigureDataPanel extends localize(i18next)(LitElement
810
828
  <input .value=${a.name} @input=${(e) => set({ name: typed(e) })} />`
811
829
  : nothing}
812
830
  <span>${i18next.t('figure.label.data-method')}</span>
813
- <select ?disabled=${!methods.length} @change=${(e) => set({ method: typed(e) })}>
814
- ${methods.map(m => html `<option value=${m} ?selected=${m === method}>${i18next.t('figure.label.data-method-' + m)}</option>`)}
815
- </select>
831
+ ${methods.length === 1
832
+ ? /* One way only (a text is read by a code table): said, not offered as a choice of one (sweep 2026-10-27 U10). */
833
+ html `<span method>${i18next.t('figure.label.data-method-' + methods[0])}</span>`
834
+ : html `<select ?disabled=${!methods.length} @change=${(e) => set({ method: typed(e) })}>
835
+ ${methods.map(m => html `<option value=${m} ?selected=${m === method}>${i18next.t('figure.label.data-method-' + m)}</option>`)}
836
+ </select>`}
816
837
  ${!table && fitting.length
817
838
  ? html `<span>${i18next.t('figure.label.data-behavior')}</span>
818
839
  <select @change=${(e) => set({ behavior: typed(e) })}>