@things-factory/figure-ui 10.1.176 → 10.1.178
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/client/modeller/editor-styles.ts +3 -5
- package/client/modeller/editor.ts +41 -39
- package/client/modeller/figure-links.ts +36 -9
- package/dist-client/modeller/editor-styles.js +3 -5
- package/dist-client/modeller/editor-styles.js.map +1 -1
- package/dist-client/modeller/editor.d.ts +6 -10
- package/dist-client/modeller/editor.js +34 -37
- package/dist-client/modeller/editor.js.map +1 -1
- package/dist-client/modeller/figure-links.d.ts +6 -1
- package/dist-client/modeller/figure-links.js +40 -8
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/test/browser/editing-page.js +2 -1
- package/test/browser/links.check.mjs +18 -9
- package/test/browser/modeller.check.mjs +6 -0
- package/test/browser/parts.check.mjs +3 -12
- package/test/browser/places-mesh.check.mjs +4 -9
- package/test/browser/props.check.mjs +27 -10
- package/test/browser/row-preview.check.mjs +4 -0
- package/test/browser/screen.check.mjs +27 -19
- package/test/place-words.test.ts +31 -0
- package/translations/en.json +6 -3
- package/translations/es.json +3 -0
- package/translations/ja.json +3 -0
- package/translations/ko.json +6 -3
- package/translations/ms.json +3 -0
- package/translations/zh.json +3 -0
|
@@ -265,13 +265,11 @@ export const EditorStyles = css`
|
|
|
265
265
|
display: grid;
|
|
266
266
|
gap: 6px;
|
|
267
267
|
}
|
|
268
|
-
/*
|
|
269
|
-
section[more] > details > summary
|
|
270
|
-
section[capability] > details > summary {
|
|
268
|
+
/* The folded 「더 보기」: its title is the fold's handle, at the title's size. */
|
|
269
|
+
section[more] > details > summary {
|
|
271
270
|
padding: 0;
|
|
272
271
|
}
|
|
273
|
-
section[more] > details > summary > h3
|
|
274
|
-
section[capability] > details > summary > h3 {
|
|
272
|
+
section[more] > details > summary > h3 {
|
|
275
273
|
margin: 0;
|
|
276
274
|
}
|
|
277
275
|
div[more-body] {
|
|
@@ -72,12 +72,13 @@ import { groupMenu, GroupMenuStyles } from './group-menu.js'
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
* The side's
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
75
|
+
* The side's six tabs (user 2026-10-17: up to six): properties -- the part's shape, place and look; 「반응형」 -- how it
|
|
76
|
+
* answers a size it is placed at (its size rules, a position that follows the size, its row; the figure's range);
|
|
77
|
+
* motion; what it does (its places); its data (ADR-0051); the verdict. The view is a menu over the canvas and the
|
|
78
|
+
* release history opens from the bar, since neither is about the part chosen. The verdict gives way to properties when
|
|
79
|
+
* a part is chosen; a tab about parts keeps showing the newly chosen part.
|
|
79
80
|
*/
|
|
80
|
-
type SideTab = 'properties' | 'motion' | 'data' | 'verdict'
|
|
81
|
+
type SideTab = 'properties' | 'response' | 'motion' | 'capability' | 'data' | 'verdict'
|
|
81
82
|
|
|
82
83
|
/** What opens over the work from the bar: the view settings or the release history, one at a time. */
|
|
83
84
|
type BarOverlay = 'view' | 'history'
|
|
@@ -134,8 +135,6 @@ export class FigureEditor extends LitElement {
|
|
|
134
135
|
@state() private tab: SideTab = 'properties'
|
|
135
136
|
/** The view settings or the release history, open over the work from the bar. */
|
|
136
137
|
@state() private overlay?: BarOverlay
|
|
137
|
-
/** The capability group open: the canvas marks the places only while their group is in sight. */
|
|
138
|
-
@state() private capabilityOpen = false
|
|
139
138
|
/** 「더 보기」 open, as this person left it last (chief architect 2026-10-16: kept per person). */
|
|
140
139
|
@state() private moreOpen = FigureEditor.storedMoreOpen()
|
|
141
140
|
private static storedMoreOpen(): boolean {
|
|
@@ -199,7 +198,7 @@ export class FigureEditor extends LitElement {
|
|
|
199
198
|
session: () => this.session,
|
|
200
199
|
selected: () => this.selected,
|
|
201
200
|
shown: () => this.shown(),
|
|
202
|
-
formsInSight: () => this.middle === 'edit' && this.tab === 'properties',
|
|
201
|
+
formsInSight: () => this.middle === 'edit' && (this.tab === 'properties' || this.tab === 'response'),
|
|
203
202
|
said: error => this.said(error)
|
|
204
203
|
})
|
|
205
204
|
/**
|
|
@@ -752,12 +751,14 @@ export class FigureEditor extends LitElement {
|
|
|
752
751
|
}
|
|
753
752
|
}
|
|
754
753
|
/** Size response, fastening and motion for the selected part, as authoring commands. */
|
|
755
|
-
private renderLinks(unavailable: boolean, section: 'shape' | 'places' | 'motion', slotted: unknown = nothing) {
|
|
754
|
+
private renderLinks(unavailable: boolean, section: 'shape' | 'response' | 'places' | 'motion', slotted: unknown = nothing) {
|
|
756
755
|
const shown = this.shown()
|
|
757
756
|
if (!shown) return null
|
|
757
|
+
const tab: SideTab = section === 'shape' ? 'properties' : section === 'places' ? 'capability' : section
|
|
758
758
|
return html`<figure-links
|
|
759
759
|
.revision=${shown}
|
|
760
760
|
.section=${section}
|
|
761
|
+
.active=${this.tab === tab}
|
|
761
762
|
.partId=${this.selected}
|
|
762
763
|
?locked=${unavailable}
|
|
763
764
|
@command=${(e: CustomEvent) => this.linkCommand(e.detail.action)}
|
|
@@ -772,9 +773,10 @@ export class FigureEditor extends LitElement {
|
|
|
772
773
|
>${slotted}</figure-links>`
|
|
773
774
|
}
|
|
774
775
|
/**
|
|
775
|
-
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place
|
|
776
|
-
*
|
|
777
|
-
*
|
|
776
|
+
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place. The links draw
|
|
777
|
+
* the groups; the part's own numbers go into them by slot. How the part answers a size -- its rules, a position that
|
|
778
|
+
* follows, its row -- is the 「반응형」 tab's. A fastened part's place and turn are its fastening's: the place group
|
|
779
|
+
* says it in one line and the locked cells are not drawn (user 2026-10-16).
|
|
778
780
|
*/
|
|
779
781
|
private renderPartGroups(shown: FigureRevision | undefined, geometry: readonly { id: string }[], fields: FieldLike[], unavailable: boolean, held?: HeldValues) {
|
|
780
782
|
const groups = this.withSizeRow(groupFields(fields, this.selected), held)
|
|
@@ -795,28 +797,12 @@ export class FigureEditor extends LitElement {
|
|
|
795
797
|
: nothing}
|
|
796
798
|
${place.length && !placeLocked
|
|
797
799
|
? html`<div slot="place" group-fields>${place.map(g => this.renderVector(g, unavailable, held))}${this.renderHeldAxes(place)}</div>`
|
|
798
|
-
: nothing}
|
|
799
|
-
${this.renderRepeat(shown, geometry, unavailable)}`
|
|
800
|
+
: nothing}`
|
|
800
801
|
)
|
|
801
802
|
}
|
|
802
|
-
/**
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
*/
|
|
806
|
-
private renderCapability(asset: FigureAsset | undefined, unavailable: boolean) {
|
|
807
|
-
return html`<section capability>
|
|
808
|
-
<details capability-fold ?open=${this.capabilityOpen} @toggle=${(e: Event) => (this.capabilityOpen = (e.target as HTMLDetailsElement).open)}>
|
|
809
|
-
<summary><h3>${i18next.t('figure.label.tab-capability')}</h3></summary>
|
|
810
|
-
${this.selected ? this.renderLinks(unavailable, 'places') : nothing}
|
|
811
|
-
<figure-capability-panel
|
|
812
|
-
.asset=${asset}
|
|
813
|
-
.selected=${this.selected}
|
|
814
|
-
?locked=${unavailable}
|
|
815
|
-
@select-part=${(e: CustomEvent) => this.choose(e.detail.id)}
|
|
816
|
-
@part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
|
|
817
|
-
></figure-capability-panel>
|
|
818
|
-
</details>
|
|
819
|
-
</section>`
|
|
803
|
+
/** The 「반응형」 tab of a part: the links' response groups, its row's own section put in by slot. */
|
|
804
|
+
private renderResponse(shown: FigureRevision | undefined, geometry: readonly { id: string }[], unavailable: boolean) {
|
|
805
|
+
return this.renderLinks(unavailable, 'response', this.renderRepeat(shown, geometry, unavailable))
|
|
820
806
|
}
|
|
821
807
|
/**
|
|
822
808
|
* 「더 보기」: what few parts need, folded by default and left as this person last left it (chief architect
|
|
@@ -1747,7 +1733,7 @@ export class FigureEditor extends LitElement {
|
|
|
1747
1733
|
@configure-size=${async (e: CustomEvent<{ part: string }>) => {
|
|
1748
1734
|
this.middle = 'edit'
|
|
1749
1735
|
this.selected = e.detail.part
|
|
1750
|
-
this.tab = '
|
|
1736
|
+
this.tab = 'response'
|
|
1751
1737
|
await this.updateComplete
|
|
1752
1738
|
this.renderRoot.querySelector('figure-links')?.scrollIntoView({ block: 'nearest' })
|
|
1753
1739
|
}}
|
|
@@ -1764,7 +1750,7 @@ export class FigureEditor extends LitElement {
|
|
|
1764
1750
|
.fan=${this.fanOf(shown, live)}
|
|
1765
1751
|
.ghost=${this.previewShown().ghost}
|
|
1766
1752
|
.highlight=${this.previewShown().highlight}
|
|
1767
|
-
.marks=${this.tab === '
|
|
1753
|
+
.marks=${this.tab === 'capability' ? this.slotMarks(view, asset) : NO_MARKS}
|
|
1768
1754
|
.palette=${view.palette ?? {}}
|
|
1769
1755
|
.context=${view.context ?? ''}
|
|
1770
1756
|
.selected=${this.selected}
|
|
@@ -1778,7 +1764,9 @@ export class FigureEditor extends LitElement {
|
|
|
1778
1764
|
<aside slot="end">
|
|
1779
1765
|
<div tabs>
|
|
1780
1766
|
${this.renderTab('properties', 'tune', i18next.t('figure.label.properties'))}
|
|
1767
|
+
${this.renderTab('response', 'aspect_ratio', i18next.t('figure.label.tab-response'))}
|
|
1781
1768
|
${this.renderTab('motion', 'animation', i18next.t('figure.label.motion'))}
|
|
1769
|
+
${this.renderTab('capability', 'conveyor_belt', i18next.t('figure.label.tab-capability'))}
|
|
1782
1770
|
${this.renderTab('data', 'sensors', i18next.t('figure.label.tab-data'))}
|
|
1783
1771
|
${this.renderTab('verdict', 'insights', i18next.t('figure.label.maturity'), this.instances)}
|
|
1784
1772
|
</div>
|
|
@@ -1809,7 +1797,6 @@ export class FigureEditor extends LitElement {
|
|
|
1809
1797
|
@part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
|
|
1810
1798
|
@part-live=${(e: CustomEvent) => this.hold({}, e.detail.edit)}
|
|
1811
1799
|
></figure-material-panel>
|
|
1812
|
-
${this.renderCapability(asset, unavailable)}
|
|
1813
1800
|
${this.renderMore(part, view.palette ?? {}, unavailable)}`
|
|
1814
1801
|
: view.geometry.length === 0
|
|
1815
1802
|
? html`${this.renderSubject()}<section empty-figure>
|
|
@@ -1819,16 +1806,31 @@ export class FigureEditor extends LitElement {
|
|
|
1819
1806
|
<slot name="figure"></slot>
|
|
1820
1807
|
</details>
|
|
1821
1808
|
</section>`
|
|
1822
|
-
: html`${this.renderSubject()}<slot name="figure"></slot
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1809
|
+
: html`${this.renderSubject()}<slot name="figure"></slot>`}
|
|
1810
|
+
</div>
|
|
1811
|
+
<div panel ?off=${tab !== 'response'}>
|
|
1812
|
+
${this.renderSubject()}
|
|
1813
|
+
${this.selected && part
|
|
1814
|
+
? this.renderResponse(shown, view.geometry, unavailable)
|
|
1815
|
+
: html`${this.renderGroups(groupFields(common), 'figure.label.group-figure-size', 'figure.label.design-inputs', unavailable)}
|
|
1816
|
+
${this.renderInstanceRange(shown, unavailable)}`}
|
|
1826
1817
|
</div>
|
|
1827
1818
|
<div panel ?off=${tab !== 'motion'}>
|
|
1828
1819
|
${this.renderSubject()}
|
|
1829
1820
|
${this.selected && part ? this.renderLinks(unavailable, 'motion') : html`<section><p hint>${i18next.t('figure.text.choose-a-part-to-move')}</p></section>`}
|
|
1830
1821
|
${this.renderControls(view, unavailable)}
|
|
1831
1822
|
</div>
|
|
1823
|
+
<div panel ?off=${tab !== 'capability'}>
|
|
1824
|
+
${this.renderSubject()}
|
|
1825
|
+
${this.selected && part ? this.renderLinks(unavailable, 'places') : nothing}
|
|
1826
|
+
<figure-capability-panel
|
|
1827
|
+
.asset=${asset}
|
|
1828
|
+
.selected=${this.selected}
|
|
1829
|
+
?locked=${unavailable}
|
|
1830
|
+
@select-part=${(e: CustomEvent) => this.choose(e.detail.id)}
|
|
1831
|
+
@part-edit=${(e: CustomEvent) => this.run(() => this.session!.edit(e.detail.edit))}
|
|
1832
|
+
></figure-capability-panel>
|
|
1833
|
+
</div>
|
|
1832
1834
|
<div panel ?off=${tab !== 'data'}>
|
|
1833
1835
|
${this.renderSubject()}
|
|
1834
1836
|
<figure-data-panel
|
|
@@ -184,7 +184,12 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
184
184
|
@property() partId = ''
|
|
185
185
|
@property({ type: Boolean }) locked = false
|
|
186
186
|
/** Which ties this shows: the part's shape (size and placement, in 속성), its places (자리·능력) or its motion (움직임). */
|
|
187
|
-
@property() section: 'shape' | 'places' | 'motion' = 'shape'
|
|
187
|
+
@property() section: 'shape' | 'response' | 'places' | 'motion' = 'shape'
|
|
188
|
+
/**
|
|
189
|
+
* Its tab is the one shown. Two sections speak of what a command would draw -- the properties' fastening and the
|
|
190
|
+
* response's row -- and only the one in sight may: the hidden one's silence would clear what the shown one draws.
|
|
191
|
+
*/
|
|
192
|
+
@property({ type: Boolean }) active = true
|
|
188
193
|
/** What the fastening command would do, in words (the editor works it out: `command-preview.ts`). */
|
|
189
194
|
@property({ attribute: false }) previewWords: string[] = []
|
|
190
195
|
/** Where the selected part's motion takes it, at both ends of its range (the editor draws them on the canvas). */
|
|
@@ -231,6 +236,8 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
231
236
|
fastening it has" over an empty target (2026-09-27, :3391, the doors). */
|
|
232
237
|
private loadedFor?: string
|
|
233
238
|
willUpdate(changed: Map<string, unknown>) {
|
|
239
|
+
/* Its tab shown again: what it would draw is said again, over whatever the other tab left. */
|
|
240
|
+
if (changed.has('active') && this.active && changed.get('active') === false) this.told = ''
|
|
234
241
|
/* What 고치기 said is about the figure as it was: another step or another part, and it no longer holds. */
|
|
235
242
|
if (changed.has('asset') || changed.has('partId')) this.fixNote = ''
|
|
236
243
|
if (this.asset && this.partId && this.partId !== this.loadedFor) {
|
|
@@ -248,9 +255,10 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
248
255
|
}
|
|
249
256
|
|
|
250
257
|
updated() {
|
|
251
|
-
/* Only the
|
|
252
|
-
others' silence cleared what it showed (2026-09-27, :3391). */
|
|
253
|
-
|
|
258
|
+
/* Only the sections that hold a form speak of what it would do, and only while their tab is shown: the panel has
|
|
259
|
+
one of these per section, and the others' silence cleared what it showed (2026-09-27, :3391). */
|
|
260
|
+
const speaks = this.active && (this.section === 'shape' || this.section === 'response')
|
|
261
|
+
if (!speaks) return
|
|
254
262
|
const said = JSON.stringify(this.candidate ?? null)
|
|
255
263
|
if (said === this.told) return
|
|
256
264
|
this.told = said
|
|
@@ -301,12 +309,33 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
301
309
|
*/
|
|
302
310
|
/* Fastened, by a face or by an origin: either can be taken off, from the place group's 「⋯」. */
|
|
303
311
|
const held = !!heldBy(asset, this.partId) || !!(this.revision && fasteningOf(this.revision, this.partId)?.atOrigin)
|
|
312
|
+
if (this.section === 'response') {
|
|
313
|
+
/*
|
|
314
|
+
How the part answers a size it is placed at (user 2026-10-17, the 「반응형」 tab): its own measures, where it
|
|
315
|
+
stands, and the row it may make -- what Build Once, Fit Anywhere is authored with, in one place.
|
|
316
|
+
*/
|
|
317
|
+
const positions = positionsWorkedOut(asset, this.partId)
|
|
318
|
+
const response = html`
|
|
319
|
+
<section size-response>
|
|
320
|
+
<h3>${i18next.t('figure.label.group-size')}</h3>
|
|
321
|
+
<p group-question>${i18next.t('figure.label.resize-intent')}</p>
|
|
322
|
+
${canFollow(asset, this.partId) ? this.renderDimensions(asset) : html`<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
|
|
323
|
+
</section>
|
|
324
|
+
${positions.length
|
|
325
|
+
? html`<section position-response>
|
|
326
|
+
<h3>${i18next.t('figure.label.group-position-response')}</h3>
|
|
327
|
+
${this.renderPositions(asset)}
|
|
328
|
+
</section>`
|
|
329
|
+
: nothing}
|
|
330
|
+
${rowOf(asset, this.partId) ? html`<slot name="row"></slot>` : this.renderRow(asset)}
|
|
331
|
+
`
|
|
332
|
+
this.candidate = this.working === 'row' && this.rowCandidate ? { action: this.rowCandidate } : undefined
|
|
333
|
+
return response
|
|
334
|
+
}
|
|
304
335
|
const shown = html`
|
|
305
336
|
<section size>
|
|
306
337
|
<h3>${i18next.t('figure.label.group-size')}</h3>
|
|
307
338
|
<slot name="size"></slot>
|
|
308
|
-
<p group-question>${i18next.t('figure.label.resize-intent')}</p>
|
|
309
|
-
${canFollow(asset, this.partId) ? this.renderDimensions(asset) : html`<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
|
|
310
339
|
</section>
|
|
311
340
|
<section fastening ?spotlit=${this.spotlit} @focusin=${() => (this.working = 'fasten')}>
|
|
312
341
|
<h3>
|
|
@@ -314,12 +343,10 @@ export class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
314
343
|
${groupMenu([{ label: i18next.t('figure.button.detach'), icon: 'link_off', disabled: this.locked || !held, run: () => this.command({ kind: 'detach', part: this.partId }) }])}
|
|
315
344
|
</h3>${this.help.hint('figure.text.fastening-explained')}
|
|
316
345
|
<slot name="place"></slot>
|
|
317
|
-
${this.renderPositions(asset)}
|
|
318
346
|
${canFasten(asset, this.partId) ? this.renderFastening(asset) : html`<p hint>${i18next.t('figure.text.links-need-a-box')}</p>`}
|
|
319
347
|
</section>
|
|
320
|
-
${rowOf(asset, this.partId) ? html`<slot name="row"></slot>` : this.renderRow(asset)}
|
|
321
348
|
`
|
|
322
|
-
this.candidate = this.
|
|
349
|
+
this.candidate = this.fastenCandidate
|
|
323
350
|
return shown
|
|
324
351
|
}
|
|
325
352
|
|
|
@@ -264,13 +264,11 @@ export const EditorStyles = css `
|
|
|
264
264
|
display: grid;
|
|
265
265
|
gap: 6px;
|
|
266
266
|
}
|
|
267
|
-
/*
|
|
268
|
-
section[more] > details > summary
|
|
269
|
-
section[capability] > details > summary {
|
|
267
|
+
/* The folded 「더 보기」: its title is the fold's handle, at the title's size. */
|
|
268
|
+
section[more] > details > summary {
|
|
270
269
|
padding: 0;
|
|
271
270
|
}
|
|
272
|
-
section[more] > details > summary > h3
|
|
273
|
-
section[capability] > details > summary > h3 {
|
|
271
|
+
section[more] > details > summary > h3 {
|
|
274
272
|
margin: 0;
|
|
275
273
|
}
|
|
276
274
|
div[more-body] {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-styles.js","sourceRoot":"","sources":["../../client/modeller/editor-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,gHAAgH;AAChH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmZ9B,CAAA","sourcesContent":["import { css } from 'lit'\n\n/** The modeller editor's own styles: the bar's tools, the panes, the start card, the side's tabs and panels. */\nexport const EditorStyles = css`\n :host {\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n /* The editor folds by the width it is given, not the window's (UX ruling, 2026-09-24). */\n container-type: inline-size;\n /* The app's one face (its typography theme's --theme-font) at the body size: a bare sans-serif here put a second\n face under everything the editor draws, beside the parts list and the shell in the app's own (2026-10-16). */\n font-family: var(--theme-font, ui-sans-serif, system-ui, sans-serif);\n font-size: var(--ui-t-body, 13px);\n color: var(--md-sys-color-on-surface);\n }\n /* The bar over the work is ox-canvas-bar (ADR-0060 decision 8): the folds at its edges, undo, redo and\n fit in the suite's places. What the editor puts in it - the mode switch, the status, save - is styled here. */\n ox-canvas-bar button[mode] {\n height: 28px;\n border: 1px solid transparent;\n padding: 0 10px;\n border-radius: 999em;\n border-color: transparent;\n background: none;\n }\n ox-canvas-bar button[mode][aria-pressed='true'] {\n border-color: var(--md-sys-color-primary);\n }\n /* The gizmo's tools, drawn as the bar's own icon buttons (undo, redo, fit). */\n ox-canvas-bar .gizmo-tools {\n display: inline-flex;\n gap: 2px;\n padding-left: 4px;\n border-left: 1px solid var(--md-sys-color-outline-variant);\n }\n ox-canvas-bar button[tool] {\n display: inline-grid;\n place-items: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n background: transparent;\n color: var(--md-sys-color-on-surface-variant);\n cursor: pointer;\n }\n ox-canvas-bar button[tool]:hover:not(:disabled) {\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n }\n ox-canvas-bar button[tool][aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n ox-canvas-bar button[tool]:disabled {\n opacity: 0.38;\n cursor: default;\n }\n /*\n Slotted into the bar from here, the tools do not get the bar's own icon size (20px, set inside its shadow): they\n showed at md-icon's 24px, heavier than undo, redo and fit beside them. The same size, and the bar's focus ring.\n */\n ox-canvas-bar button[tool] md-icon {\n --md-icon-size: 20px;\n }\n ox-canvas-bar button[tool]:focus-visible {\n outline: 2px solid var(--md-sys-color-primary);\n outline-offset: 1px;\n }\n figure-preview {\n min-width: 0;\n min-height: 0;\n }\n /* The edit canvas stays standing while the preview is in front (a 3D scene costs a third of a second to make), out of sight. */\n div[middle][hidden] {\n display: none;\n }\n /* The preview, once made, stays standing out of sight too: its 3D scene is not made again each time it is asked for. */\n figure-preview[hidden] {\n display: none;\n }\n ox-canvas-bar .status {\n padding: 0 8px;\n color: var(--md-sys-color-on-surface-variant);\n }\n ox-canvas-bar .status[dirty] {\n color: var(--md-sys-color-primary);\n font-weight: 600;\n }\n ox-canvas-bar button[save] {\n height: 32px;\n padding: 0 14px;\n border: none;\n border-radius: 999em;\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n }\n /* The three panes are ox-three-pane's (ADR-0060 decision 8): widths 200 | 1fr | 340, 160 | 300 under\n 860px and one column with the middle first under 560px are the frame's, as are the dividers. */\n ox-three-pane {\n flex: 1;\n min-height: 0;\n }\n figure-parts {\n min-height: 0;\n }\n figure-canvas {\n flex: 1;\n min-width: 0;\n min-height: 0;\n }\n div[middle] {\n position: relative;\n display: flex;\n min-width: 0;\n min-height: 0;\n }\n /* A new figure's first question, over the empty canvas. */\n div[start] {\n position: absolute;\n inset: 50% auto auto 50%;\n z-index: 10;\n color: var(--md-sys-color-on-surface);\n transform: translate(-50%, -50%);\n width: min(440px, calc(100% - 32px));\n box-sizing: border-box;\n padding: 20px;\n border-radius: 12px;\n background: var(--md-sys-color-surface, #fff);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);\n }\n div[start] button[start-button] {\n width: auto;\n margin: 0;\n font-size: var(--ui-t-body);\n height: 36px;\n padding: 0 16px;\n border: 1px solid var(--md-sys-color-outline);\n border-radius: 999em;\n color: var(--md-sys-color-primary);\n background: var(--md-sys-color-surface, #fff);\n cursor: pointer;\n }\n div[start] button[start-button]:hover:not(:disabled) {\n background: var(--md-sys-color-primary-container);\n }\n div[start] button[start-button][pressed] {\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n border-color: var(--md-sys-color-primary);\n }\n div[start] button[start-button]:disabled {\n opacity: 0.5;\n cursor: default;\n }\n div[start] h2 {\n margin: 0 0 12px;\n font-size: var(--ui-t-title);\n }\n div[start-paths] {\n display: grid;\n gap: 14px;\n }\n div[start-paths] h3 {\n margin: 0 0 6px;\n font-size: var(--ui-t-body);\n }\n div[start-shapes] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n }\n div[start] small {\n display: block;\n margin-top: 4px;\n color: var(--md-sys-color-on-surface-variant);\n }\n /* The side: tabs over one panel at a time, each using the whole height. */\n /*\n The side's words at the panel's size (side-panel-styles: titles body, the rest small). The editor's host is at body\n for the bar, and the fields the editor drew itself -- the part's name -- stood a step larger than every other field.\n */\n aside {\n display: flex;\n flex-direction: column;\n min-height: 0;\n font-size: var(--ui-t-small, 11.5px);\n background: var(--md-sys-color-surface-container-lowest);\n }\n div[tabs] {\n display: flex;\n flex: none;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n button[tab] {\n flex: 1;\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 1px;\n min-width: 0;\n height: 48px;\n padding: 0;\n border: none;\n border-radius: 0;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--md-sys-color-on-surface-variant);\n }\n button[tab]:hover:not([on]) {\n background: var(--md-sys-color-surface-container);\n }\n button[tab][on] {\n color: var(--md-sys-color-primary);\n border-bottom-color: var(--md-sys-color-primary);\n }\n button[tab] md-icon {\n font-size: 20px;\n width: 20px;\n height: 20px;\n }\n button[tab] span[tab-label] {\n max-width: 100%;\n overflow: hidden;\n font-size: var(--ui-t-micro, 11px);\n line-height: 1.2;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n span[badge] {\n position: absolute;\n top: 3px;\n right: 2px;\n padding: 0 5px;\n font-size: var(--ui-t-micro, 11px);\n font-weight: 700;\n line-height: 1.5;\n color: var(--md-sys-color-on-primary-container);\n background: var(--md-sys-color-primary-container);\n border-radius: 999em;\n pointer-events: none;\n }\n /* The sections inside carry the margins (side-panel-styles); the panel only scrolls. */\n div[panel] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 0;\n }\n div[panel][flush] {\n padding: 0;\n }\n /* Hidden, not removed: a panel keeps what it holds (the verdict its last answer) while another tab is open. */\n [off] {\n display: none !important;\n }\n /* The part's own numbers inside a group the links draw (size, place): one column, the panel's gap. */\n div[group-fields] {\n display: grid;\n gap: 6px;\n }\n /* A folded group (capability, 「더 보기」): its title is the fold's handle, at the title's size. */\n section[more] > details > summary,\n section[capability] > details > summary {\n padding: 0;\n }\n section[more] > details > summary > h3,\n section[capability] > details > summary > h3 {\n margin: 0;\n }\n div[more-body] {\n display: grid;\n gap: 16px;\n margin-top: 12px;\n }\n /*\n The view settings and the release history, opened from the bar over the right of the work: neither is about the\n part chosen, so neither takes a tab beside the part's (chief architect 2026-10-16).\n */\n :host {\n position: relative;\n }\n div[bar-overlay-panel] {\n position: absolute;\n top: var(--figure-bar-height, 44px);\n right: 8px;\n z-index: 5;\n display: flex;\n flex-direction: column;\n width: min(360px, calc(100% - 16px));\n max-height: calc(100% - var(--figure-bar-height, 44px) - 16px);\n background: var(--md-sys-color-surface-container-lowest);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16);\n }\n div[overlay-head] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 8px 8px 12px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n div[overlay-head] h3 {\n margin: 0;\n }\n div[overlay-head] button[quiet] {\n margin-left: 0;\n }\n div[overlay-body] {\n min-height: 0;\n overflow: auto;\n }\n /* Which part the panel speaks of. */\n div[subject] {\n position: sticky;\n top: 0;\n z-index: 1;\n display: grid;\n gap: 4px;\n padding: 10px 12px;\n background: var(--md-sys-color-surface-container-lowest);\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n /* The panel's three sizes (side-panel-styles): the part's kind at the title's, its two lines at the hint's. */\n div[subject-summary] {\n display: grid;\n gap: 2px;\n }\n div[subject-summary] b {\n font-size: var(--ui-t-body, 13px);\n font-weight: 600;\n }\n div[subject-summary] b span {\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant);\n }\n div[subject-summary] small {\n color: var(--md-sys-color-on-surface-variant);\n }\n /*\n No rule here draws every button as a box: the side's buttons take the shared panel rules (SidePanelStyles), one\n height with the fields beside them, and only the bar's publish keeps an outline (user 2026-10-16: 「버튼 박스도\n 과하게 사용되어서」 -- a bare 「button」 rule had put a 32px box round every button the editor drew).\n */\n button {\n font: inherit;\n box-sizing: border-box;\n color: inherit;\n min-width: 0;\n cursor: pointer;\n }\n /* What blocks release, beside 「발행」: one red word button, and its list under the bar. */\n ox-canvas-bar button[release-blocked] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 32px;\n padding: 0 10px;\n border: none;\n border-radius: 6px;\n color: var(--md-sys-color-on-error-container);\n background: var(--md-sys-color-error-container);\n }\n ox-canvas-bar button[release-blocked] md-icon {\n --md-icon-size: 18px;\n }\n div[release-blockers] {\n position: absolute;\n top: 46px;\n right: 8px;\n z-index: 6;\n width: min(340px, calc(100% - 16px));\n padding: 8px 10px 10px;\n box-sizing: border-box;\n background: var(--md-sys-color-surface);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: var(--md-sys-elevation-2, 0 2px 8px #0003);\n }\n ox-canvas-bar button[publish] {\n height: 32px;\n padding: 0 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: var(--md-sys-color-surface);\n }\n button:disabled {\n opacity: 0.45;\n cursor: default;\n }\n button[aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n border-color: var(--md-sys-color-primary);\n }\n .hint {\n color: var(--md-sys-color-on-surface-variant);\n line-height: 1.5;\n }\n`\n"]}
|
|
1
|
+
{"version":3,"file":"editor-styles.js","sourceRoot":"","sources":["../../client/modeller/editor-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,gHAAgH;AAChH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiZ9B,CAAA","sourcesContent":["import { css } from 'lit'\n\n/** The modeller editor's own styles: the bar's tools, the panes, the start card, the side's tabs and panels. */\nexport const EditorStyles = css`\n :host {\n position: relative;\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n /* The editor folds by the width it is given, not the window's (UX ruling, 2026-09-24). */\n container-type: inline-size;\n /* The app's one face (its typography theme's --theme-font) at the body size: a bare sans-serif here put a second\n face under everything the editor draws, beside the parts list and the shell in the app's own (2026-10-16). */\n font-family: var(--theme-font, ui-sans-serif, system-ui, sans-serif);\n font-size: var(--ui-t-body, 13px);\n color: var(--md-sys-color-on-surface);\n }\n /* The bar over the work is ox-canvas-bar (ADR-0060 decision 8): the folds at its edges, undo, redo and\n fit in the suite's places. What the editor puts in it - the mode switch, the status, save - is styled here. */\n ox-canvas-bar button[mode] {\n height: 28px;\n border: 1px solid transparent;\n padding: 0 10px;\n border-radius: 999em;\n border-color: transparent;\n background: none;\n }\n ox-canvas-bar button[mode][aria-pressed='true'] {\n border-color: var(--md-sys-color-primary);\n }\n /* The gizmo's tools, drawn as the bar's own icon buttons (undo, redo, fit). */\n ox-canvas-bar .gizmo-tools {\n display: inline-flex;\n gap: 2px;\n padding-left: 4px;\n border-left: 1px solid var(--md-sys-color-outline-variant);\n }\n ox-canvas-bar button[tool] {\n display: inline-grid;\n place-items: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: none;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n background: transparent;\n color: var(--md-sys-color-on-surface-variant);\n cursor: pointer;\n }\n ox-canvas-bar button[tool]:hover:not(:disabled) {\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n }\n ox-canvas-bar button[tool][aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n ox-canvas-bar button[tool]:disabled {\n opacity: 0.38;\n cursor: default;\n }\n /*\n Slotted into the bar from here, the tools do not get the bar's own icon size (20px, set inside its shadow): they\n showed at md-icon's 24px, heavier than undo, redo and fit beside them. The same size, and the bar's focus ring.\n */\n ox-canvas-bar button[tool] md-icon {\n --md-icon-size: 20px;\n }\n ox-canvas-bar button[tool]:focus-visible {\n outline: 2px solid var(--md-sys-color-primary);\n outline-offset: 1px;\n }\n figure-preview {\n min-width: 0;\n min-height: 0;\n }\n /* The edit canvas stays standing while the preview is in front (a 3D scene costs a third of a second to make), out of sight. */\n div[middle][hidden] {\n display: none;\n }\n /* The preview, once made, stays standing out of sight too: its 3D scene is not made again each time it is asked for. */\n figure-preview[hidden] {\n display: none;\n }\n ox-canvas-bar .status {\n padding: 0 8px;\n color: var(--md-sys-color-on-surface-variant);\n }\n ox-canvas-bar .status[dirty] {\n color: var(--md-sys-color-primary);\n font-weight: 600;\n }\n ox-canvas-bar button[save] {\n height: 32px;\n padding: 0 14px;\n border: none;\n border-radius: 999em;\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n }\n /* The three panes are ox-three-pane's (ADR-0060 decision 8): widths 200 | 1fr | 340, 160 | 300 under\n 860px and one column with the middle first under 560px are the frame's, as are the dividers. */\n ox-three-pane {\n flex: 1;\n min-height: 0;\n }\n figure-parts {\n min-height: 0;\n }\n figure-canvas {\n flex: 1;\n min-width: 0;\n min-height: 0;\n }\n div[middle] {\n position: relative;\n display: flex;\n min-width: 0;\n min-height: 0;\n }\n /* A new figure's first question, over the empty canvas. */\n div[start] {\n position: absolute;\n inset: 50% auto auto 50%;\n z-index: 10;\n color: var(--md-sys-color-on-surface);\n transform: translate(-50%, -50%);\n width: min(440px, calc(100% - 32px));\n box-sizing: border-box;\n padding: 20px;\n border-radius: 12px;\n background: var(--md-sys-color-surface, #fff);\n box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);\n }\n div[start] button[start-button] {\n width: auto;\n margin: 0;\n font-size: var(--ui-t-body);\n height: 36px;\n padding: 0 16px;\n border: 1px solid var(--md-sys-color-outline);\n border-radius: 999em;\n color: var(--md-sys-color-primary);\n background: var(--md-sys-color-surface, #fff);\n cursor: pointer;\n }\n div[start] button[start-button]:hover:not(:disabled) {\n background: var(--md-sys-color-primary-container);\n }\n div[start] button[start-button][pressed] {\n color: var(--md-sys-color-on-primary);\n background: var(--md-sys-color-primary);\n border-color: var(--md-sys-color-primary);\n }\n div[start] button[start-button]:disabled {\n opacity: 0.5;\n cursor: default;\n }\n div[start] h2 {\n margin: 0 0 12px;\n font-size: var(--ui-t-title);\n }\n div[start-paths] {\n display: grid;\n gap: 14px;\n }\n div[start-paths] h3 {\n margin: 0 0 6px;\n font-size: var(--ui-t-body);\n }\n div[start-shapes] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n }\n div[start] small {\n display: block;\n margin-top: 4px;\n color: var(--md-sys-color-on-surface-variant);\n }\n /* The side: tabs over one panel at a time, each using the whole height. */\n /*\n The side's words at the panel's size (side-panel-styles: titles body, the rest small). The editor's host is at body\n for the bar, and the fields the editor drew itself -- the part's name -- stood a step larger than every other field.\n */\n aside {\n display: flex;\n flex-direction: column;\n min-height: 0;\n font-size: var(--ui-t-small, 11.5px);\n background: var(--md-sys-color-surface-container-lowest);\n }\n div[tabs] {\n display: flex;\n flex: none;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n button[tab] {\n flex: 1;\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 1px;\n min-width: 0;\n height: 48px;\n padding: 0;\n border: none;\n border-radius: 0;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--md-sys-color-on-surface-variant);\n }\n button[tab]:hover:not([on]) {\n background: var(--md-sys-color-surface-container);\n }\n button[tab][on] {\n color: var(--md-sys-color-primary);\n border-bottom-color: var(--md-sys-color-primary);\n }\n button[tab] md-icon {\n font-size: 20px;\n width: 20px;\n height: 20px;\n }\n button[tab] span[tab-label] {\n max-width: 100%;\n overflow: hidden;\n font-size: var(--ui-t-micro, 11px);\n line-height: 1.2;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n span[badge] {\n position: absolute;\n top: 3px;\n right: 2px;\n padding: 0 5px;\n font-size: var(--ui-t-micro, 11px);\n font-weight: 700;\n line-height: 1.5;\n color: var(--md-sys-color-on-primary-container);\n background: var(--md-sys-color-primary-container);\n border-radius: 999em;\n pointer-events: none;\n }\n /* The sections inside carry the margins (side-panel-styles); the panel only scrolls. */\n div[panel] {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: 0;\n }\n div[panel][flush] {\n padding: 0;\n }\n /* Hidden, not removed: a panel keeps what it holds (the verdict its last answer) while another tab is open. */\n [off] {\n display: none !important;\n }\n /* The part's own numbers inside a group the links draw (size, place): one column, the panel's gap. */\n div[group-fields] {\n display: grid;\n gap: 6px;\n }\n /* The folded 「더 보기」: its title is the fold's handle, at the title's size. */\n section[more] > details > summary {\n padding: 0;\n }\n section[more] > details > summary > h3 {\n margin: 0;\n }\n div[more-body] {\n display: grid;\n gap: 16px;\n margin-top: 12px;\n }\n /*\n The view settings and the release history, opened from the bar over the right of the work: neither is about the\n part chosen, so neither takes a tab beside the part's (chief architect 2026-10-16).\n */\n :host {\n position: relative;\n }\n div[bar-overlay-panel] {\n position: absolute;\n top: var(--figure-bar-height, 44px);\n right: 8px;\n z-index: 5;\n display: flex;\n flex-direction: column;\n width: min(360px, calc(100% - 16px));\n max-height: calc(100% - var(--figure-bar-height, 44px) - 16px);\n background: var(--md-sys-color-surface-container-lowest);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.16);\n }\n div[overlay-head] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 8px 8px 12px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n div[overlay-head] h3 {\n margin: 0;\n }\n div[overlay-head] button[quiet] {\n margin-left: 0;\n }\n div[overlay-body] {\n min-height: 0;\n overflow: auto;\n }\n /* Which part the panel speaks of. */\n div[subject] {\n position: sticky;\n top: 0;\n z-index: 1;\n display: grid;\n gap: 4px;\n padding: 10px 12px;\n background: var(--md-sys-color-surface-container-lowest);\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n }\n /* The panel's three sizes (side-panel-styles): the part's kind at the title's, its two lines at the hint's. */\n div[subject-summary] {\n display: grid;\n gap: 2px;\n }\n div[subject-summary] b {\n font-size: var(--ui-t-body, 13px);\n font-weight: 600;\n }\n div[subject-summary] b span {\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant);\n }\n div[subject-summary] small {\n color: var(--md-sys-color-on-surface-variant);\n }\n /*\n No rule here draws every button as a box: the side's buttons take the shared panel rules (SidePanelStyles), one\n height with the fields beside them, and only the bar's publish keeps an outline (user 2026-10-16: 「버튼 박스도\n 과하게 사용되어서」 -- a bare 「button」 rule had put a 32px box round every button the editor drew).\n */\n button {\n font: inherit;\n box-sizing: border-box;\n color: inherit;\n min-width: 0;\n cursor: pointer;\n }\n /* What blocks release, beside 「발행」: one red word button, and its list under the bar. */\n ox-canvas-bar button[release-blocked] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n height: 32px;\n padding: 0 10px;\n border: none;\n border-radius: 6px;\n color: var(--md-sys-color-on-error-container);\n background: var(--md-sys-color-error-container);\n }\n ox-canvas-bar button[release-blocked] md-icon {\n --md-icon-size: 18px;\n }\n div[release-blockers] {\n position: absolute;\n top: 46px;\n right: 8px;\n z-index: 6;\n width: min(340px, calc(100% - 16px));\n padding: 8px 10px 10px;\n box-sizing: border-box;\n background: var(--md-sys-color-surface);\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px;\n box-shadow: var(--md-sys-elevation-2, 0 2px 8px #0003);\n }\n ox-canvas-bar button[publish] {\n height: 32px;\n padding: 0 8px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 6px;\n background: var(--md-sys-color-surface);\n }\n button:disabled {\n opacity: 0.45;\n cursor: default;\n }\n button[aria-pressed='true'] {\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n border-color: var(--md-sys-color-primary);\n }\n .hint {\n color: var(--md-sys-color-on-surface-variant);\n line-height: 1.5;\n }\n`\n"]}
|
|
@@ -61,8 +61,6 @@ export declare class FigureEditor extends LitElement {
|
|
|
61
61
|
private tab;
|
|
62
62
|
/** The view settings or the release history, open over the work from the bar. */
|
|
63
63
|
private overlay?;
|
|
64
|
-
/** The capability group open: the canvas marks the places only while their group is in sight. */
|
|
65
|
-
private capabilityOpen;
|
|
66
64
|
/** 「더 보기」 open, as this person left it last (chief architect 2026-10-16: kept per person). */
|
|
67
65
|
private moreOpen;
|
|
68
66
|
private static storedMoreOpen;
|
|
@@ -203,16 +201,14 @@ export declare class FigureEditor extends LitElement {
|
|
|
203
201
|
/** Size response, fastening and motion for the selected part, as authoring commands. */
|
|
204
202
|
private renderLinks;
|
|
205
203
|
/**
|
|
206
|
-
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place
|
|
207
|
-
*
|
|
208
|
-
*
|
|
204
|
+
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place. The links draw
|
|
205
|
+
* the groups; the part's own numbers go into them by slot. How the part answers a size -- its rules, a position that
|
|
206
|
+
* follows, its row -- is the 「반응형」 tab's. A fastened part's place and turn are its fastening's: the place group
|
|
207
|
+
* says it in one line and the locked cells are not drawn (user 2026-10-16).
|
|
209
208
|
*/
|
|
210
209
|
private renderPartGroups;
|
|
211
|
-
/**
|
|
212
|
-
|
|
213
|
-
* whose marks on the canvas show while it is open. A verdict that finds it empty still says where it is.
|
|
214
|
-
*/
|
|
215
|
-
private renderCapability;
|
|
210
|
+
/** The 「반응형」 tab of a part: the links' response groups, its row's own section put in by slot. */
|
|
211
|
+
private renderResponse;
|
|
216
212
|
/**
|
|
217
213
|
* 「더 보기」: what few parts need, folded by default and left as this person last left it (chief architect
|
|
218
214
|
* 2026-10-16) -- the section, its corners and inside; transparency, glow and segments; the mirrored copy and the
|
|
@@ -78,8 +78,6 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
78
78
|
this.selected = '';
|
|
79
79
|
this.error = '';
|
|
80
80
|
this.tab = 'properties';
|
|
81
|
-
/** The capability group open: the canvas marks the places only while their group is in sight. */
|
|
82
|
-
this.capabilityOpen = false;
|
|
83
81
|
/** 「더 보기」 open, as this person left it last (chief architect 2026-10-16: kept per person). */
|
|
84
82
|
this.moreOpen = FigureEditor_1.storedMoreOpen();
|
|
85
83
|
/** What the middle shows: the parts being edited, or the figure placed on a board at eight sizes. */
|
|
@@ -107,7 +105,7 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
107
105
|
session: () => this.session,
|
|
108
106
|
selected: () => this.selected,
|
|
109
107
|
shown: () => this.shown(),
|
|
110
|
-
formsInSight: () => this.middle === 'edit' && this.tab === 'properties',
|
|
108
|
+
formsInSight: () => this.middle === 'edit' && (this.tab === 'properties' || this.tab === 'response'),
|
|
111
109
|
said: error => this.said(error)
|
|
112
110
|
});
|
|
113
111
|
this.keys = new ModellerKeys(this, {
|
|
@@ -757,9 +755,11 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
757
755
|
const shown = this.shown();
|
|
758
756
|
if (!shown)
|
|
759
757
|
return null;
|
|
758
|
+
const tab = section === 'shape' ? 'properties' : section === 'places' ? 'capability' : section;
|
|
760
759
|
return html `<figure-links
|
|
761
760
|
.revision=${shown}
|
|
762
761
|
.section=${section}
|
|
762
|
+
.active=${this.tab === tab}
|
|
763
763
|
.partId=${this.selected}
|
|
764
764
|
?locked=${unavailable}
|
|
765
765
|
@command=${(e) => this.linkCommand(e.detail.action)}
|
|
@@ -774,9 +774,10 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
774
774
|
>${slotted}</figure-links>`;
|
|
775
775
|
}
|
|
776
776
|
/**
|
|
777
|
-
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place
|
|
778
|
-
*
|
|
779
|
-
*
|
|
777
|
+
* A part's groups in one order whatever its state (chief architect 2026-10-16): its size, its place. The links draw
|
|
778
|
+
* the groups; the part's own numbers go into them by slot. How the part answers a size -- its rules, a position that
|
|
779
|
+
* follows, its row -- is the 「반응형」 tab's. A fastened part's place and turn are its fastening's: the place group
|
|
780
|
+
* says it in one line and the locked cells are not drawn (user 2026-10-16).
|
|
780
781
|
*/
|
|
781
782
|
renderPartGroups(shown, geometry, fields, unavailable, held) {
|
|
782
783
|
const groups = this.withSizeRow(groupFields(fields, this.selected), held);
|
|
@@ -794,27 +795,11 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
794
795
|
: nothing}
|
|
795
796
|
${place.length && !placeLocked
|
|
796
797
|
? html `<div slot="place" group-fields>${place.map(g => this.renderVector(g, unavailable, held))}${this.renderHeldAxes(place)}</div>`
|
|
797
|
-
: nothing}
|
|
798
|
-
${this.renderRepeat(shown, geometry, unavailable)}`);
|
|
798
|
+
: nothing}`);
|
|
799
799
|
}
|
|
800
|
-
/**
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
*/
|
|
804
|
-
renderCapability(asset, unavailable) {
|
|
805
|
-
return html `<section capability>
|
|
806
|
-
<details capability-fold ?open=${this.capabilityOpen} @toggle=${(e) => (this.capabilityOpen = e.target.open)}>
|
|
807
|
-
<summary><h3>${i18next.t('figure.label.tab-capability')}</h3></summary>
|
|
808
|
-
${this.selected ? this.renderLinks(unavailable, 'places') : nothing}
|
|
809
|
-
<figure-capability-panel
|
|
810
|
-
.asset=${asset}
|
|
811
|
-
.selected=${this.selected}
|
|
812
|
-
?locked=${unavailable}
|
|
813
|
-
@select-part=${(e) => this.choose(e.detail.id)}
|
|
814
|
-
@part-edit=${(e) => this.run(() => this.session.edit(e.detail.edit))}
|
|
815
|
-
></figure-capability-panel>
|
|
816
|
-
</details>
|
|
817
|
-
</section>`;
|
|
800
|
+
/** The 「반응형」 tab of a part: the links' response groups, its row's own section put in by slot. */
|
|
801
|
+
renderResponse(shown, geometry, unavailable) {
|
|
802
|
+
return this.renderLinks(unavailable, 'response', this.renderRepeat(shown, geometry, unavailable));
|
|
818
803
|
}
|
|
819
804
|
/**
|
|
820
805
|
* 「더 보기」: what few parts need, folded by default and left as this person last left it (chief architect
|
|
@@ -1764,7 +1749,7 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1764
1749
|
@configure-size=${async (e) => {
|
|
1765
1750
|
this.middle = 'edit';
|
|
1766
1751
|
this.selected = e.detail.part;
|
|
1767
|
-
this.tab = '
|
|
1752
|
+
this.tab = 'response';
|
|
1768
1753
|
await this.updateComplete;
|
|
1769
1754
|
this.renderRoot.querySelector('figure-links')?.scrollIntoView({ block: 'nearest' });
|
|
1770
1755
|
}}
|
|
@@ -1781,7 +1766,7 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1781
1766
|
.fan=${this.fanOf(shown, live)}
|
|
1782
1767
|
.ghost=${this.previewShown().ghost}
|
|
1783
1768
|
.highlight=${this.previewShown().highlight}
|
|
1784
|
-
.marks=${this.tab === '
|
|
1769
|
+
.marks=${this.tab === 'capability' ? this.slotMarks(view, asset) : NO_MARKS}
|
|
1785
1770
|
.palette=${view.palette ?? {}}
|
|
1786
1771
|
.context=${view.context ?? ''}
|
|
1787
1772
|
.selected=${this.selected}
|
|
@@ -1795,7 +1780,9 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1795
1780
|
<aside slot="end">
|
|
1796
1781
|
<div tabs>
|
|
1797
1782
|
${this.renderTab('properties', 'tune', i18next.t('figure.label.properties'))}
|
|
1783
|
+
${this.renderTab('response', 'aspect_ratio', i18next.t('figure.label.tab-response'))}
|
|
1798
1784
|
${this.renderTab('motion', 'animation', i18next.t('figure.label.motion'))}
|
|
1785
|
+
${this.renderTab('capability', 'conveyor_belt', i18next.t('figure.label.tab-capability'))}
|
|
1799
1786
|
${this.renderTab('data', 'sensors', i18next.t('figure.label.tab-data'))}
|
|
1800
1787
|
${this.renderTab('verdict', 'insights', i18next.t('figure.label.maturity'), this.instances)}
|
|
1801
1788
|
</div>
|
|
@@ -1826,7 +1813,6 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1826
1813
|
@part-edit=${(e) => this.run(() => this.session.edit(e.detail.edit))}
|
|
1827
1814
|
@part-live=${(e) => this.hold({}, e.detail.edit)}
|
|
1828
1815
|
></figure-material-panel>
|
|
1829
|
-
${this.renderCapability(asset, unavailable)}
|
|
1830
1816
|
${this.renderMore(part, view.palette ?? {}, unavailable)}`
|
|
1831
1817
|
: view.geometry.length === 0
|
|
1832
1818
|
? html `${this.renderSubject()}<section empty-figure>
|
|
@@ -1836,16 +1822,31 @@ let FigureEditor = class FigureEditor extends LitElement {
|
|
|
1836
1822
|
<slot name="figure"></slot>
|
|
1837
1823
|
</details>
|
|
1838
1824
|
</section>`
|
|
1839
|
-
: html `${this.renderSubject()}<slot name="figure"></slot
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1825
|
+
: html `${this.renderSubject()}<slot name="figure"></slot>`}
|
|
1826
|
+
</div>
|
|
1827
|
+
<div panel ?off=${tab !== 'response'}>
|
|
1828
|
+
${this.renderSubject()}
|
|
1829
|
+
${this.selected && part
|
|
1830
|
+
? this.renderResponse(shown, view.geometry, unavailable)
|
|
1831
|
+
: html `${this.renderGroups(groupFields(common), 'figure.label.group-figure-size', 'figure.label.design-inputs', unavailable)}
|
|
1832
|
+
${this.renderInstanceRange(shown, unavailable)}`}
|
|
1843
1833
|
</div>
|
|
1844
1834
|
<div panel ?off=${tab !== 'motion'}>
|
|
1845
1835
|
${this.renderSubject()}
|
|
1846
1836
|
${this.selected && part ? this.renderLinks(unavailable, 'motion') : html `<section><p hint>${i18next.t('figure.text.choose-a-part-to-move')}</p></section>`}
|
|
1847
1837
|
${this.renderControls(view, unavailable)}
|
|
1848
1838
|
</div>
|
|
1839
|
+
<div panel ?off=${tab !== 'capability'}>
|
|
1840
|
+
${this.renderSubject()}
|
|
1841
|
+
${this.selected && part ? this.renderLinks(unavailable, 'places') : nothing}
|
|
1842
|
+
<figure-capability-panel
|
|
1843
|
+
.asset=${asset}
|
|
1844
|
+
.selected=${this.selected}
|
|
1845
|
+
?locked=${unavailable}
|
|
1846
|
+
@select-part=${(e) => this.choose(e.detail.id)}
|
|
1847
|
+
@part-edit=${(e) => this.run(() => this.session.edit(e.detail.edit))}
|
|
1848
|
+
></figure-capability-panel>
|
|
1849
|
+
</div>
|
|
1849
1850
|
<div panel ?off=${tab !== 'data'}>
|
|
1850
1851
|
${this.renderSubject()}
|
|
1851
1852
|
<figure-data-panel
|
|
@@ -2086,10 +2087,6 @@ __decorate([
|
|
|
2086
2087
|
state(),
|
|
2087
2088
|
__metadata("design:type", String)
|
|
2088
2089
|
], FigureEditor.prototype, "overlay", void 0);
|
|
2089
|
-
__decorate([
|
|
2090
|
-
state(),
|
|
2091
|
-
__metadata("design:type", Object)
|
|
2092
|
-
], FigureEditor.prototype, "capabilityOpen", void 0);
|
|
2093
2090
|
__decorate([
|
|
2094
2091
|
state(),
|
|
2095
2092
|
__metadata("design:type", Object)
|