@things-factory/figure-ui 10.1.176 → 10.1.177

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.
@@ -28,7 +28,12 @@ export declare class FigureLinks extends FigureLinks_base {
28
28
  partId: string;
29
29
  locked: boolean;
30
30
  /** Which ties this shows: the part's shape (size and placement, in 속성), its places (자리·능력) or its motion (움직임). */
31
- section: 'shape' | 'places' | 'motion';
31
+ section: 'shape' | 'response' | 'places' | 'motion';
32
+ /**
33
+ * Its tab is the one shown. Two sections speak of what a command would draw -- the properties' fastening and the
34
+ * response's row -- and only the one in sight may: the hidden one's silence would clear what the shown one draws.
35
+ */
36
+ active: boolean;
32
37
  /** What the fastening command would do, in words (the editor works it out: `command-preview.ts`). */
33
38
  previewWords: string[];
34
39
  /** Where the selected part's motion takes it, at both ends of its range (the editor draws them on the canvas). */
@@ -69,7 +74,7 @@ export declare class FigureLinks extends FigureLinks_base {
69
74
  willUpdate(changed: Map<string, unknown>): void;
70
75
  updated(): void;
71
76
  disconnectedCallback(): void;
72
- render(): import("lit-html").TemplateResult<1> | typeof nothing;
77
+ render(): typeof nothing | import("lit-html").TemplateResult<1>;
73
78
  /** Where things are held on this part: a seat things rest on, or a grip things are held in. */
74
79
  private renderPlaces;
75
80
  /** The figure holds things: `Capacity` and `Holdable`, the ladder's middle rung. One part edit, one undo step. */
@@ -55,6 +55,11 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
55
55
  this.locked = false;
56
56
  /** Which ties this shows: the part's shape (size and placement, in 속성), its places (자리·능력) or its motion (움직임). */
57
57
  this.section = 'shape';
58
+ /**
59
+ * Its tab is the one shown. Two sections speak of what a command would draw -- the properties' fastening and the
60
+ * response's row -- and only the one in sight may: the hidden one's silence would clear what the shown one draws.
61
+ */
62
+ this.active = true;
58
63
  /** What the fastening command would do, in words (the editor works it out: `command-preview.ts`). */
59
64
  this.previewWords = [];
60
65
  /** Where the selected part's motion takes it, at both ends of its range (the editor draws them on the canvas). */
@@ -159,6 +164,9 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
159
164
  return this.revision?.asset;
160
165
  }
161
166
  willUpdate(changed) {
167
+ /* Its tab shown again: what it would draw is said again, over whatever the other tab left. */
168
+ if (changed.has('active') && this.active && changed.get('active') === false)
169
+ this.told = '';
162
170
  /* What 고치기 said is about the figure as it was: another step or another part, and it no longer holds. */
163
171
  if (changed.has('asset') || changed.has('partId'))
164
172
  this.fixNote = '';
@@ -176,9 +184,10 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
176
184
  }
177
185
  }
178
186
  updated() {
179
- /* Only the section that holds the fastening form speaks of it: the panel has one of these per section, and the
180
- others' silence cleared what it showed (2026-09-27, :3391). */
181
- if (this.section !== 'shape' && !this.told)
187
+ /* Only the sections that hold a form speak of what it would do, and only while their tab is shown: the panel has
188
+ one of these per section, and the others' silence cleared what it showed (2026-09-27, :3391). */
189
+ const speaks = this.active && (this.section === 'shape' || this.section === 'response');
190
+ if (!speaks)
182
191
  return;
183
192
  const said = JSON.stringify(this.candidate ?? null);
184
193
  if (said === this.told)
@@ -231,12 +240,33 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
231
240
  */
232
241
  /* Fastened, by a face or by an origin: either can be taken off, from the place group's 「⋯」. */
233
242
  const held = !!heldBy(asset, this.partId) || !!(this.revision && fasteningOf(this.revision, this.partId)?.atOrigin);
243
+ if (this.section === 'response') {
244
+ /*
245
+ How the part answers a size it is placed at (user 2026-10-17, the 「반응형」 tab): its own measures, where it
246
+ stands, and the row it may make -- what Build Once, Fit Anywhere is authored with, in one place.
247
+ */
248
+ const positions = positionsWorkedOut(asset, this.partId);
249
+ const response = html `
250
+ <section size-response>
251
+ <h3>${i18next.t('figure.label.group-size')}</h3>
252
+ <p group-question>${i18next.t('figure.label.resize-intent')}</p>
253
+ ${canFollow(asset, this.partId) ? this.renderDimensions(asset) : html `<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
254
+ </section>
255
+ ${positions.length
256
+ ? html `<section position-response>
257
+ <h3>${i18next.t('figure.label.group-position-response')}</h3>
258
+ ${this.renderPositions(asset)}
259
+ </section>`
260
+ : nothing}
261
+ ${rowOf(asset, this.partId) ? html `<slot name="row"></slot>` : this.renderRow(asset)}
262
+ `;
263
+ this.candidate = this.working === 'row' && this.rowCandidate ? { action: this.rowCandidate } : undefined;
264
+ return response;
265
+ }
234
266
  const shown = html `
235
267
  <section size>
236
268
  <h3>${i18next.t('figure.label.group-size')}</h3>
237
269
  <slot name="size"></slot>
238
- <p group-question>${i18next.t('figure.label.resize-intent')}</p>
239
- ${canFollow(asset, this.partId) ? this.renderDimensions(asset) : html `<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
240
270
  </section>
241
271
  <section fastening ?spotlit=${this.spotlit} @focusin=${() => (this.working = 'fasten')}>
242
272
  <h3>
@@ -244,12 +274,10 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
244
274
  ${groupMenu([{ label: i18next.t('figure.button.detach'), icon: 'link_off', disabled: this.locked || !held, run: () => this.command({ kind: 'detach', part: this.partId }) }])}
245
275
  </h3>${this.help.hint('figure.text.fastening-explained')}
246
276
  <slot name="place"></slot>
247
- ${this.renderPositions(asset)}
248
277
  ${canFasten(asset, this.partId) ? this.renderFastening(asset) : html `<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
249
278
  </section>
250
- ${rowOf(asset, this.partId) ? html `<slot name="row"></slot>` : this.renderRow(asset)}
251
279
  `;
252
- this.candidate = this.working === 'row' && this.rowCandidate ? { action: this.rowCandidate } : this.fastenCandidate;
280
+ this.candidate = this.fastenCandidate;
253
281
  return shown;
254
282
  }
255
283
  /** Where things are held on this part: a seat things rest on, or a grip things are held in. */
@@ -1005,6 +1033,10 @@ __decorate([
1005
1033
  property(),
1006
1034
  __metadata("design:type", String)
1007
1035
  ], FigureLinks.prototype, "section", void 0);
1036
+ __decorate([
1037
+ property({ type: Boolean }),
1038
+ __metadata("design:type", Object)
1039
+ ], FigureLinks.prototype, "active", void 0);
1008
1040
  __decorate([
1009
1041
  property({ attribute: false }),
1010
1042
  __metadata("design:type", Array)