@operato/board 10.22.0 → 10.24.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.
- package/CHANGELOG.md +32 -0
- package/dist/src/modeller/component-toolbar/component-menu.js +5 -5
- package/dist/src/modeller/component-toolbar/component-menu.js.map +1 -1
- package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +3 -5
- package/dist/src/modeller/component-toolbar/component-toolbar.js +114 -47
- package/dist/src/modeller/component-toolbar/component-toolbar.js.map +1 -1
- package/dist/src/modeller/edit-toolbar-style.js +47 -3
- package/dist/src/modeller/edit-toolbar-style.js.map +1 -1
- package/dist/src/modeller/edit-toolbar.d.ts +6 -0
- package/dist/src/modeller/edit-toolbar.js +71 -5
- package/dist/src/modeller/edit-toolbar.js.map +1 -1
- package/dist/src/modeller/selection-toolbar.d.ts +61 -0
- package/dist/src/modeller/selection-toolbar.js +402 -0
- package/dist/src/modeller/selection-toolbar.js.map +1 -0
- package/dist/src/ox-board-modeller.d.ts +4 -0
- package/dist/src/ox-board-modeller.js +24 -0
- package/dist/src/ox-board-modeller.js.map +1 -1
- package/dist/src/types.d.ts +1 -0
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,38 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [10.24.0](https://github.com/hatiolab/operato/compare/v10.23.0...v10.24.0) (2026-09-24)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @operato/board
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [10.23.0](https://github.com/hatiolab/operato/compare/v10.22.0...v10.23.0) (2026-09-24)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### :sparkles: Styling
|
|
18
|
+
|
|
19
|
+
* **property-panel,input,styles:** quiet inspector, one vocabulary in both schemes ([40e67e9](https://github.com/hatiolab/operato/commit/40e67e9aced202151a4f2f8d7ef96ec840defc18))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### :bug: Bug Fix
|
|
23
|
+
|
|
24
|
+
* **board:** centre the compact toolbar's icons in the bar; new fullscreen and panel glyphs ([37f135f](https://github.com/hatiolab/operato/commit/37f135f74e064377d16378765604e028c29fdafa))
|
|
25
|
+
* **board:** the compact modeller toolbar draws glyphs in the scheme's ink ([6385901](https://github.com/hatiolab/operato/commit/63859013e60445b53e9d5d1e5a3f6122527ea3e7))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### :rocket: New Features
|
|
29
|
+
|
|
30
|
+
* **board,property-panel:** docked placement for the contextual bar; quieter effect/binding cards ([c6ad7bb](https://github.com/hatiolab/operato/commit/c6ad7bbcd4c20890f27eba1680322058da453110))
|
|
31
|
+
* **board:** contextual floating toolbar in the modeller ([02fa968](https://github.com/hatiolab/operato/commit/02fa9682ac905ca7d7d995da0e4b5971e28bab78))
|
|
32
|
+
* **board:** palette rail with one Material glyph and a caption per group ([ee53d2b](https://github.com/hatiolab/operato/commit/ee53d2b8f5eba3271fe136af08de2cc2645dfa21))
|
|
33
|
+
* **data-grist,property-panel:** card reorder, quiet gutters, panel heading ([3ad5843](https://github.com/hatiolab/operato/commit/3ad5843287c75007b52bbf18d6117fcffdbd1a83))
|
|
34
|
+
* **property-panel:** one start flow for data binding and event handlers; quiet Specific tab ([2059375](https://github.com/hatiolab/operato/commit/20593753327d169954f1913bbe531359f8bfc944))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
6
38
|
## [10.22.0](https://github.com/hatiolab/operato/compare/v10.21.0...v10.22.0) (2026-09-24)
|
|
7
39
|
|
|
8
40
|
**Note:** Version bump only for package @operato/board
|
|
@@ -119,7 +119,7 @@ ComponentMenu.styles = [
|
|
|
119
119
|
|
|
120
120
|
overflow: visible;
|
|
121
121
|
|
|
122
|
-
border:
|
|
122
|
+
border: 1px solid var(--component-menu-border-color, var(--md-sys-color-outline-variant));
|
|
123
123
|
box-sizing: border-box;
|
|
124
124
|
|
|
125
125
|
position: absolute;
|
|
@@ -129,11 +129,11 @@ ComponentMenu.styles = [
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
h2 {
|
|
132
|
-
background-color: var(--component-menu-
|
|
133
|
-
padding:
|
|
132
|
+
background-color: var(--component-menu-title-background, var(--md-sys-color-surface-container-highest));
|
|
133
|
+
padding: 4px 8px;
|
|
134
134
|
margin: 0;
|
|
135
135
|
font: var(--component-menu-title);
|
|
136
|
-
color: var(--md-sys-color-on-
|
|
136
|
+
color: var(--component-menu-title-color, var(--md-sys-color-on-surface));
|
|
137
137
|
text-transform: capitalize;
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -154,7 +154,7 @@ ComponentMenu.styles = [
|
|
|
154
154
|
align-items: center;
|
|
155
155
|
min-height: var(--component-menu-item-icon-size);
|
|
156
156
|
padding: 0 5px 0 0;
|
|
157
|
-
border-bottom: 1px solid
|
|
157
|
+
border-bottom: 1px solid var(--md-sys-color-outline-variant);
|
|
158
158
|
font-size: 11px;
|
|
159
159
|
color: var(--component-menu-item-color, var(--md-sys-color-on-secondary-container));
|
|
160
160
|
text-transform: capitalize;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-menu.js","sourceRoot":"","sources":["../../../../src/modeller/component-toolbar/component-menu.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\n\nimport { Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { ScrollbarStyles } from '@operato/styles'\nimport { i18next } from '@operato/i18n'\n\nimport { Pallet, PalletItem } from '../../types.js'\nimport { ComponentDetail } from './component-detail.js'\n\nconst noImage = new URL('../../../../icons/components/no-image.png', import.meta.url).href\n\nexport class ComponentMenu extends ScopedElementsMixin(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n align-content: stretch;\n\n background-color: var(--component-menu-background-color, var(--md-sys-color-secondary-container));\n color: var(--component-menu-color, var(--md-sys-color-on-secondary-container));\n margin: 0px;\n padding: 0px;\n\n width: 180px;\n height: 100%;\n\n overflow: visible;\n\n border: 2px solid var(--component-menu-border-color, var(--md-sys-color-secondary));\n box-sizing: border-box;\n\n position: absolute;\n top: 0px;\n\n z-index: 1;\n }\n\n h2 {\n background-color: var(--component-menu-border-color, var(--md-sys-color-secondary));\n padding: 1px 5px;\n margin: 0;\n font: var(--component-menu-title);\n color: var(--md-sys-color-on-secondary);\n text-transform: capitalize;\n }\n\n [templates] {\n flex: 1;\n\n display: block;\n margin: 0;\n padding: 0;\n overflow-y: auto;\n\n background-color: var(--component-menu-background-color, var(--md-sys-color-secondary-container));\n color: var(--component-menu-color, var(--md-sys-color-on-secondary-container));\n }\n\n [template] {\n display: flex;\n align-items: center;\n min-height: var(--component-menu-item-icon-size);\n padding: 0 5px 0 0;\n border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n font-size: 11px;\n color: var(--component-menu-item-color, var(--md-sys-color-on-secondary-container));\n text-transform: capitalize;\n }\n\n [template]:hover,\n [template]:focus {\n color: var(--component-menu-item-hover-color, var(--md-sys-color-secondary));\n font-weight: bold;\n cursor: pointer;\n }\n\n [template] img {\n margin: 5px;\n width: var(--component-menu-item-icon-size);\n height: var(--component-menu-item-icon-size);\n }\n\n component-detail {\n position: absolute;\n top: 0;\n left: 180px;\n height: 100%;\n outline: none;\n }\n\n component-detail[hidden] {\n display: none;\n }\n `\n ]\n\n @property({ type: Object }) groups: Pallet[] = []\n @property({ type: Object }) scene: Scene | null = null\n @property({ type: String }) group: string | null = ''\n\n @state() templates: PalletItem[] = []\n @state() template: PalletItem | any\n\n @query('component-detail') detail!: HTMLElement\n\n static get scopedElements() {\n return {\n 'component-detail': ComponentDetail\n }\n }\n\n render() {\n return this.group\n ? html`\n <h2 onclick=${(e: MouseEvent) => e.stopPropagation()}>\n ${/* group label — translate via group.<name> key, fall back to the\n raw group name so untranslated groups keep working.\n \"list\" is also translatable; defaults to the literal \"list\"\n which is what users have been seeing all along. */ ''}\n ${i18next.t(`group.${this.group}`, { defaultValue: this.group })}\n ${i18next.t('label.list', { defaultValue: 'list' })}\n </h2>\n\n <div templates @mouseover=${(e: MouseEvent) => this.onHoverComponent(e)}>\n ${(this.templates || []).map(template => {\n const { type } = template\n\n return html`\n <div @click=${this.onClickTemplate} data-type=${type} template>\n <img src=${String(this.templateIcon(template))} />${i18next.t(`component.${type}`)}\n </div>\n `\n })}\n </div>\n\n <component-detail\n tabindex=\"-1\"\n @focusout=${() => {\n this.template = null\n }}\n .template=${this.template}\n hidden\n >\n </component-detail>\n `\n : html``\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('group')) {\n if (!this.group) {\n this.templates = []\n this.setAttribute('hidden', '')\n } else {\n this.templates = this.groups.find((g: Pallet) => g.name === this.group)?.templates || []\n this.removeAttribute('active')\n }\n }\n\n if (changes.has('template')) {\n this.template && this.template.about\n ? this.detail.removeAttribute('hidden')\n : this.detail.setAttribute('hidden', '')\n }\n }\n\n findTemplate(type: string | null | undefined) {\n this.template = type && this.templates.find(template => template.type == type)\n }\n\n onHoverComponent(e: MouseEvent) {\n const button = e.target as HTMLElement\n this.findTemplate(button!.closest('[data-type]')?.getAttribute('data-type'))\n }\n\n onClickTemplate(e: MouseEvent) {\n var item = e.target as HTMLElement\n var type = item.closest('[data-type]')?.getAttribute('data-type')\n\n if (!type) {\n return\n }\n\n if (this.scene) {\n this.scene.rootContainer?.trigger('addstop') // 새로운 컴포넌트 클릭시 이전 추가 모드 정지\n this.template = this.templates.find(template => template.type == type)\n this.template && this.scene.startAddMode(JSON.parse(JSON.stringify(this.template.model)))\n }\n\n this.group = null\n }\n\n templateIcon(template: PalletItem) {\n return template.icon || noImage\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"component-menu.js","sourceRoot":"","sources":["../../../../src/modeller/component-toolbar/component-menu.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\n\nimport { Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { ScrollbarStyles } from '@operato/styles'\nimport { i18next } from '@operato/i18n'\n\nimport { Pallet, PalletItem } from '../../types.js'\nimport { ComponentDetail } from './component-detail.js'\n\nconst noImage = new URL('../../../../icons/components/no-image.png', import.meta.url).href\n\nexport class ComponentMenu extends ScopedElementsMixin(LitElement) {\n static styles = [\n ScrollbarStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n align-content: stretch;\n\n background-color: var(--component-menu-background-color, var(--md-sys-color-secondary-container));\n color: var(--component-menu-color, var(--md-sys-color-on-secondary-container));\n margin: 0px;\n padding: 0px;\n\n width: 180px;\n height: 100%;\n\n overflow: visible;\n\n border: 1px solid var(--component-menu-border-color, var(--md-sys-color-outline-variant));\n box-sizing: border-box;\n\n position: absolute;\n top: 0px;\n\n z-index: 1;\n }\n\n h2 {\n background-color: var(--component-menu-title-background, var(--md-sys-color-surface-container-highest));\n padding: 4px 8px;\n margin: 0;\n font: var(--component-menu-title);\n color: var(--component-menu-title-color, var(--md-sys-color-on-surface));\n text-transform: capitalize;\n }\n\n [templates] {\n flex: 1;\n\n display: block;\n margin: 0;\n padding: 0;\n overflow-y: auto;\n\n background-color: var(--component-menu-background-color, var(--md-sys-color-secondary-container));\n color: var(--component-menu-color, var(--md-sys-color-on-secondary-container));\n }\n\n [template] {\n display: flex;\n align-items: center;\n min-height: var(--component-menu-item-icon-size);\n padding: 0 5px 0 0;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n font-size: 11px;\n color: var(--component-menu-item-color, var(--md-sys-color-on-secondary-container));\n text-transform: capitalize;\n }\n\n [template]:hover,\n [template]:focus {\n color: var(--component-menu-item-hover-color, var(--md-sys-color-secondary));\n font-weight: bold;\n cursor: pointer;\n }\n\n [template] img {\n margin: 5px;\n width: var(--component-menu-item-icon-size);\n height: var(--component-menu-item-icon-size);\n }\n\n component-detail {\n position: absolute;\n top: 0;\n left: 180px;\n height: 100%;\n outline: none;\n }\n\n component-detail[hidden] {\n display: none;\n }\n `\n ]\n\n @property({ type: Object }) groups: Pallet[] = []\n @property({ type: Object }) scene: Scene | null = null\n @property({ type: String }) group: string | null = ''\n\n @state() templates: PalletItem[] = []\n @state() template: PalletItem | any\n\n @query('component-detail') detail!: HTMLElement\n\n static get scopedElements() {\n return {\n 'component-detail': ComponentDetail\n }\n }\n\n render() {\n return this.group\n ? html`\n <h2 onclick=${(e: MouseEvent) => e.stopPropagation()}>\n ${/* group label — translate via group.<name> key, fall back to the\n raw group name so untranslated groups keep working.\n \"list\" is also translatable; defaults to the literal \"list\"\n which is what users have been seeing all along. */ ''}\n ${i18next.t(`group.${this.group}`, { defaultValue: this.group })}\n ${i18next.t('label.list', { defaultValue: 'list' })}\n </h2>\n\n <div templates @mouseover=${(e: MouseEvent) => this.onHoverComponent(e)}>\n ${(this.templates || []).map(template => {\n const { type } = template\n\n return html`\n <div @click=${this.onClickTemplate} data-type=${type} template>\n <img src=${String(this.templateIcon(template))} />${i18next.t(`component.${type}`)}\n </div>\n `\n })}\n </div>\n\n <component-detail\n tabindex=\"-1\"\n @focusout=${() => {\n this.template = null\n }}\n .template=${this.template}\n hidden\n >\n </component-detail>\n `\n : html``\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('group')) {\n if (!this.group) {\n this.templates = []\n this.setAttribute('hidden', '')\n } else {\n this.templates = this.groups.find((g: Pallet) => g.name === this.group)?.templates || []\n this.removeAttribute('active')\n }\n }\n\n if (changes.has('template')) {\n this.template && this.template.about\n ? this.detail.removeAttribute('hidden')\n : this.detail.setAttribute('hidden', '')\n }\n }\n\n findTemplate(type: string | null | undefined) {\n this.template = type && this.templates.find(template => template.type == type)\n }\n\n onHoverComponent(e: MouseEvent) {\n const button = e.target as HTMLElement\n this.findTemplate(button!.closest('[data-type]')?.getAttribute('data-type'))\n }\n\n onClickTemplate(e: MouseEvent) {\n var item = e.target as HTMLElement\n var type = item.closest('[data-type]')?.getAttribute('data-type')\n\n if (!type) {\n return\n }\n\n if (this.scene) {\n this.scene.rootContainer?.trigger('addstop') // 새로운 컴포넌트 클릭시 이전 추가 모드 정지\n this.template = this.templates.find(template => template.type == type)\n this.template && this.scene.startAddMode(JSON.parse(JSON.stringify(this.template.model)))\n }\n\n this.group = null\n }\n\n templateIcon(template: PalletItem) {\n return template.icon || noImage\n }\n}\n"]}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
|
-
*/
|
|
1
|
+
import '@material/web/icon/icon.js';
|
|
4
2
|
import { LitElement, PropertyValues } from 'lit';
|
|
5
3
|
import { Scene, SceneMode } from '@hatiolab/things-scene';
|
|
6
4
|
import { ComponentGroup } from '../../types.js';
|
|
@@ -8,15 +6,15 @@ import { ComponentMenu } from './component-menu.js';
|
|
|
8
6
|
declare const ComponentToolbar_base: typeof LitElement & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types.js").ScopedElementsHost>;
|
|
9
7
|
export declare class ComponentToolbar extends ComponentToolbar_base {
|
|
10
8
|
static styles: import("lit").CSSResult[];
|
|
9
|
+
static readonly GROUP_SYMBOLS: Record<string, string>;
|
|
11
10
|
componentGroupList: ComponentGroup[];
|
|
12
11
|
group?: string | null;
|
|
13
12
|
scene: Scene;
|
|
14
13
|
mode: SceneMode;
|
|
15
|
-
shift:
|
|
14
|
+
shift: HTMLElement;
|
|
16
15
|
private menu;
|
|
17
16
|
private componentsContainer;
|
|
18
17
|
private groups;
|
|
19
|
-
private icons;
|
|
20
18
|
updated(changes: PropertyValues<this>): void;
|
|
21
19
|
static get scopedElements(): {
|
|
22
20
|
'component-menu': typeof ComponentMenu;
|
|
@@ -1,35 +1,21 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import '@material/web/icon/icon.js';
|
|
1
3
|
/**
|
|
2
4
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
5
|
*/
|
|
4
|
-
import {
|
|
6
|
+
import { i18next } from '@operato/i18n';
|
|
5
7
|
import { css, html, LitElement } from 'lit';
|
|
6
8
|
import { property, query, queryAll } from 'lit/decorators.js';
|
|
7
9
|
import { SCENE_MODE } from '@hatiolab/things-scene';
|
|
8
10
|
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
9
11
|
import { ComponentMenu } from './component-menu.js';
|
|
10
|
-
import { ICON_EDIT_MODE, ICON_SHIFT_MODE } from './mode-icons.js';
|
|
11
12
|
export class ComponentToolbar extends ScopedElementsMixin(LitElement) {
|
|
12
13
|
constructor() {
|
|
13
14
|
super(...arguments);
|
|
14
15
|
this.componentGroupList = [];
|
|
15
16
|
this.mode = SCENE_MODE.EDIT;
|
|
16
|
-
this.icons = {};
|
|
17
17
|
}
|
|
18
18
|
updated(changes) {
|
|
19
|
-
if (changes.has('componentGroupList')) {
|
|
20
|
-
const color = getComputedStyle(this, null).getPropertyValue('--md-sys-color-primary');
|
|
21
|
-
this.icons = (this.componentGroupList || [])
|
|
22
|
-
.filter(group => { var _a; return ((_a = group.templates) === null || _a === void 0 ? void 0 : _a.length) > 0; })
|
|
23
|
-
.reduce((sum, group) => {
|
|
24
|
-
sum[group.name] =
|
|
25
|
-
'data:image/svg+xml;charset=UTF-8;base64,' + btoa(group.icon.replace(/{{strokeColor}}/g, color));
|
|
26
|
-
return sum;
|
|
27
|
-
}, {});
|
|
28
|
-
this.icons['mode-edit'] =
|
|
29
|
-
'data:image/svg+xml;charset=UTF-8;base64,' + btoa(ICON_EDIT_MODE.replace(/{{strokeColor}}/g, color));
|
|
30
|
-
this.icons['mode-shift'] =
|
|
31
|
-
'data:image/svg+xml;charset=UTF-8;base64,' + btoa(ICON_SHIFT_MODE.replace(/{{strokeColor}}/g, color));
|
|
32
|
-
}
|
|
33
19
|
if (changes.has('group')) {
|
|
34
20
|
this.groups.forEach(group => {
|
|
35
21
|
group.getAttribute('data-group') === this.group
|
|
@@ -46,20 +32,29 @@ export class ComponentToolbar extends ScopedElementsMixin(LitElement) {
|
|
|
46
32
|
}
|
|
47
33
|
render() {
|
|
48
34
|
const componentList = this.componentGroupList || [];
|
|
49
|
-
const
|
|
35
|
+
const shift = this.mode === SCENE_MODE.SHIFT;
|
|
50
36
|
return html `
|
|
51
37
|
<div components @mousewheel=${(e) => this.onWheelEvent(e)}>
|
|
52
|
-
<
|
|
38
|
+
<div
|
|
39
|
+
id="shift"
|
|
40
|
+
?active=${shift}
|
|
41
|
+
title=${shift ? 'pan (shift)' : 'select (edit)'}
|
|
42
|
+
@click=${(e) => this._onClickShift(e)}
|
|
43
|
+
>
|
|
44
|
+
<md-icon>${shift ? 'pan_tool' : 'arrow_selector_tool'}</md-icon>
|
|
45
|
+
</div>
|
|
53
46
|
|
|
54
47
|
${componentList
|
|
55
48
|
.filter(group => { var _a; return ((_a = group.templates) === null || _a === void 0 ? void 0 : _a.length) > 0; })
|
|
56
|
-
.map(group =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
.map(group => {
|
|
50
|
+
const caption = i18next.t(`group.${group.name}`, { defaultValue: group.name });
|
|
51
|
+
return html `
|
|
52
|
+
<div group data-group=${group.name} title=${caption} @click=${(e) => this._onClickGroup(e)}>
|
|
53
|
+
<md-icon>${group.symbol || ComponentToolbar.GROUP_SYMBOLS[group.name] || 'category'}</md-icon>
|
|
54
|
+
<span>${caption}</span>
|
|
55
|
+
</div>
|
|
56
|
+
`;
|
|
57
|
+
})}
|
|
63
58
|
</div>
|
|
64
59
|
|
|
65
60
|
<component-menu
|
|
@@ -89,15 +84,7 @@ export class ComponentToolbar extends ScopedElementsMixin(LitElement) {
|
|
|
89
84
|
}));
|
|
90
85
|
}
|
|
91
86
|
_onClickShift(e) {
|
|
92
|
-
|
|
93
|
-
if (shift.hasAttribute('active')) {
|
|
94
|
-
shift.removeAttribute('active');
|
|
95
|
-
this._setMode(SCENE_MODE.EDIT);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
shift.setAttribute('active', '');
|
|
99
|
-
this._setMode(SCENE_MODE.SHIFT);
|
|
100
|
-
}
|
|
87
|
+
this._setMode(this.mode === SCENE_MODE.SHIFT ? SCENE_MODE.EDIT : SCENE_MODE.SHIFT);
|
|
101
88
|
}
|
|
102
89
|
async _onClickGroup(e) {
|
|
103
90
|
var _a, _b;
|
|
@@ -111,6 +98,13 @@ export class ComponentToolbar extends ScopedElementsMixin(LitElement) {
|
|
|
111
98
|
}
|
|
112
99
|
ComponentToolbar.styles = [
|
|
113
100
|
css `
|
|
101
|
+
/*
|
|
102
|
+
* The palette rail: one glyph and one word per group, in the same Material family and ink
|
|
103
|
+
* as the toolbar and the panel tabs. The old rail was a column of filled pictograms (a
|
|
104
|
+
* factory with smoke, a forklift) drawn at different densities, with no captions - a
|
|
105
|
+
* person hunting for a component had to guess from a picture. The caption is the point;
|
|
106
|
+
* the rail is a little wider to hold it.
|
|
107
|
+
*/
|
|
114
108
|
:host {
|
|
115
109
|
left: 0;
|
|
116
110
|
display: block;
|
|
@@ -118,34 +112,86 @@ ComponentToolbar.styles = [
|
|
|
118
112
|
|
|
119
113
|
width: var(--component-toolbar-icon-size);
|
|
120
114
|
background-color: var(--component-toolbar-background-color);
|
|
115
|
+
border-right: var(--component-toolbar-border);
|
|
116
|
+
box-sizing: border-box;
|
|
121
117
|
}
|
|
122
118
|
|
|
123
119
|
[components] {
|
|
124
120
|
display: block;
|
|
125
|
-
padding: 0;
|
|
121
|
+
padding: 4px 0;
|
|
126
122
|
margin: 0;
|
|
127
123
|
|
|
128
124
|
width: 100%;
|
|
129
125
|
height: 100%;
|
|
130
126
|
overflow: hidden;
|
|
127
|
+
box-sizing: border-box;
|
|
131
128
|
}
|
|
132
129
|
|
|
133
|
-
[components] >
|
|
130
|
+
[components] > [group],
|
|
131
|
+
[components] > #shift {
|
|
134
132
|
display: flex;
|
|
135
|
-
flex-direction:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
min-width: 50%;
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
gap: 3px;
|
|
140
137
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
width: calc(100% - 8px);
|
|
139
|
+
min-height: 50px;
|
|
140
|
+
margin: 0 4px 2px;
|
|
141
|
+
padding: 6px 2px 5px;
|
|
144
142
|
box-sizing: border-box;
|
|
143
|
+
border-radius: 8px;
|
|
144
|
+
|
|
145
|
+
color: var(--component-toolbar-icon-color, var(--md-sys-color-on-surface-variant));
|
|
146
|
+
cursor: pointer;
|
|
147
|
+
user-select: none;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
[components] > [group] md-icon,
|
|
151
|
+
[components] > #shift md-icon {
|
|
152
|
+
--md-icon-size: 22px;
|
|
153
|
+
font-variation-settings: 'wght' 300, 'opsz' 24;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
[components] > [group] span {
|
|
157
|
+
max-width: 100%;
|
|
158
|
+
font-size: 0.58rem;
|
|
159
|
+
line-height: 1.15;
|
|
160
|
+
letter-spacing: 0.01em;
|
|
161
|
+
text-align: center;
|
|
162
|
+
overflow: hidden;
|
|
163
|
+
display: -webkit-box;
|
|
164
|
+
-webkit-line-clamp: 2;
|
|
165
|
+
-webkit-box-orient: vertical;
|
|
166
|
+
/* Break between words only; a long single word gets the full width, never a hyphen-less split. */
|
|
167
|
+
word-break: normal;
|
|
168
|
+
overflow-wrap: normal;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
[components] > [group]:hover,
|
|
172
|
+
[components] > #shift:hover {
|
|
173
|
+
color: var(--md-sys-color-on-surface);
|
|
174
|
+
background-color: var(--component-toolbar-hover-background, var(--md-sys-color-surface-container-high));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* The open group and the pressed mode read as pressed, in the scheme's own container tone. */
|
|
178
|
+
[components] > [group][active],
|
|
179
|
+
[components] > #shift[active] {
|
|
180
|
+
color: var(--md-sys-color-on-secondary-container);
|
|
181
|
+
background-color: var(--component-toolbar-active-background, var(--md-sys-color-secondary-container));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
[components] > [group][active] md-icon,
|
|
185
|
+
[components] > #shift[active] md-icon {
|
|
186
|
+
font-variation-settings: 'wght' 500, 'opsz' 24, 'FILL' 1;
|
|
145
187
|
}
|
|
146
188
|
|
|
147
|
-
|
|
148
|
-
|
|
189
|
+
/* The mode switch stands apart from the groups below it. */
|
|
190
|
+
[components] > #shift {
|
|
191
|
+
min-height: 40px;
|
|
192
|
+
margin-bottom: 6px;
|
|
193
|
+
border-bottom: 1px solid var(--md-sys-color-outline-variant);
|
|
194
|
+
border-radius: 8px 8px 0 0;
|
|
149
195
|
}
|
|
150
196
|
|
|
151
197
|
component-menu {
|
|
@@ -161,6 +207,27 @@ ComponentToolbar.styles = [
|
|
|
161
207
|
}
|
|
162
208
|
`
|
|
163
209
|
];
|
|
210
|
+
/* One glyph per known group; a group registered with its own `symbol` wins. */
|
|
211
|
+
ComponentToolbar.GROUP_SYMBOLS = {
|
|
212
|
+
line: 'timeline',
|
|
213
|
+
shape: 'category',
|
|
214
|
+
textAndMedia: 'text_fields',
|
|
215
|
+
chartAndGauge: 'bar_chart',
|
|
216
|
+
table: 'table_chart',
|
|
217
|
+
container: 'space_dashboard',
|
|
218
|
+
dataSource: 'database',
|
|
219
|
+
IoT: 'sensors',
|
|
220
|
+
'3D': 'view_in_ar',
|
|
221
|
+
facility: 'factory',
|
|
222
|
+
conveyance: 'conveyor_belt',
|
|
223
|
+
storage: 'warehouse',
|
|
224
|
+
warehouse: 'inventory_2',
|
|
225
|
+
transport: 'forklift',
|
|
226
|
+
manufacturing: 'precision_manufacturing',
|
|
227
|
+
form: 'list_alt',
|
|
228
|
+
materialDesign: 'widgets',
|
|
229
|
+
etc: 'more_horiz'
|
|
230
|
+
};
|
|
164
231
|
__decorate([
|
|
165
232
|
property({ type: Array })
|
|
166
233
|
], ComponentToolbar.prototype, "componentGroupList", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-toolbar.js","sourceRoot":"","sources":["../../../../src/modeller/component-toolbar/component-toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { property, query, queryAll } from 'lit/decorators.js'\n\nimport { Scene, SCENE_MODE, SceneMode } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { ComponentGroup } from '../../types.js'\nimport { ComponentMenu } from './component-menu.js'\nimport { ICON_EDIT_MODE, ICON_SHIFT_MODE } from './mode-icons.js'\n\nexport class ComponentToolbar extends ScopedElementsMixin(LitElement) {\n static styles = [\n css`\n :host {\n left: 0;\n display: block;\n position: relative;\n\n width: var(--component-toolbar-icon-size);\n background-color: var(--component-toolbar-background-color);\n }\n\n [components] {\n display: block;\n padding: 0;\n margin: 0;\n\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n\n [components] > img {\n display: flex;\n flex-direction: row;\n\n width: var(--component-toolbar-icon-size);\n height: var(--component-toolbar-icon-size);\n min-width: 50%;\n\n border-bottom: var(--component-toolbar-border);\n margin: 0;\n padding: 6px;\n box-sizing: border-box;\n }\n\n #shift[active] {\n background-color: #beb9b3;\n }\n\n component-menu {\n position: absolute;\n top: 0;\n left: var(--component-toolbar-icon-size);\n height: 100%;\n outline: none;\n }\n\n component-menu[hidden] {\n display: none;\n }\n `\n ]\n\n @property({ type: Array }) componentGroupList: ComponentGroup[] = []\n @property({ type: String }) group?: string | null\n @property({ type: Object }) scene!: Scene\n @property({ type: Number }) mode: SceneMode = SCENE_MODE.EDIT\n\n @query('#shift') shift!: HTMLImageElement\n @query('component-menu') private menu!: HTMLElement\n @query('div[components]') private componentsContainer!: HTMLElement\n @queryAll('[data-group]') private groups!: NodeListOf<HTMLElement>\n\n private icons: { [name: string]: string } = {}\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('componentGroupList')) {\n const color = getComputedStyle(this, null).getPropertyValue('--md-sys-color-primary')\n\n this.icons = (this.componentGroupList || [])\n .filter(group => group.templates?.length > 0)\n .reduce(\n (sum, group: ComponentGroup) => {\n sum[group.name] =\n 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(group.icon.replace(/{{strokeColor}}/g, color))\n return sum\n },\n {} as { [name: string]: string }\n )\n\n this.icons['mode-edit'] =\n 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(ICON_EDIT_MODE.replace(/{{strokeColor}}/g, color))\n this.icons['mode-shift'] =\n 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(ICON_SHIFT_MODE.replace(/{{strokeColor}}/g, color))\n }\n\n if (changes.has('group')) {\n this.groups.forEach(group => {\n group.getAttribute('data-group') === this.group\n ? group.setAttribute('active', '')\n : group.removeAttribute('active')\n })\n\n this.group ? this.menu.removeAttribute('hidden') : this.menu.setAttribute('hidden', '')\n }\n }\n\n static get scopedElements() {\n return {\n 'component-menu': ComponentMenu\n }\n }\n\n render() {\n const componentList = this.componentGroupList || []\n const modeIcon = this.icons[this.mode === SCENE_MODE.SHIFT ? 'mode-shift' : 'mode-edit']\n\n return html`\n <div components @mousewheel=${(e: MouseEvent) => this.onWheelEvent(e)}>\n <img id=\"shift\" .src=${modeIcon} @click=${(e: MouseEvent) => this._onClickShift(e)} />\n\n ${componentList\n .filter(group => group.templates?.length > 0)\n .map(\n group => html`\n <img\n data-group=${group.name}\n @click=${(e: MouseEvent) => this._onClickGroup(e)}\n .src=${this.icons[group.name]}\n />\n `\n )}\n </div>\n\n <component-menu\n tabindex=\"-1\"\n @focusout=${() => {\n this.group = null\n }}\n .scene=${this.scene}\n .group=${this.group}\n .groups=${componentList}\n hidden\n >\n </component-menu>\n `\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.componentsContainer.scrollTop += delta * 10\n\n e.preventDefault()\n }\n\n _setMode(mode: SceneMode) {\n this.mode = mode\n\n this.dispatchEvent(\n new CustomEvent('mode-changed', {\n bubbles: true,\n composed: true,\n detail: { value: mode }\n })\n )\n }\n\n _onClickShift(e: MouseEvent) {\n const shift = this.shift\n\n if (shift.hasAttribute('active')) {\n shift.removeAttribute('active')\n this._setMode(SCENE_MODE.EDIT)\n } else {\n shift.setAttribute('active', '')\n this._setMode(SCENE_MODE.SHIFT)\n }\n }\n\n async _onClickGroup(e: MouseEvent) {\n var button = e.target as HTMLElement\n\n this.group = button!.closest('[data-group]')?.getAttribute('data-group')\n\n if (!this.group) return\n\n await this.updateComplete\n\n this.menu?.focus()\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"component-toolbar.js","sourceRoot":"","sources":["../../../../src/modeller/component-toolbar/component-toolbar.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE7D,OAAO,EAAS,UAAU,EAAa,MAAM,wBAAwB,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,OAAO,gBAAiB,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAArE;;QAuI6B,uBAAkB,GAAqB,EAAE,CAAA;QAGxC,SAAI,GAAc,UAAU,CAAC,IAAI,CAAA;IAqG/D,CAAC;IA9FC,OAAO,CAAC,OAA6B;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBAC1B,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC,KAAK;oBAC7C,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;oBAClC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;YACrC,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QACzF,CAAC;IACH,CAAC;IAED,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,gBAAgB,EAAE,aAAa;SAChC,CAAA;IACH,CAAC;IAED,MAAM;QACJ,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,IAAI,EAAE,CAAA;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK,CAAA;QAE5C,OAAO,IAAI,CAAA;oCACqB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;;;oBAGvD,KAAK;kBACP,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe;mBACtC,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;;qBAEtC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,qBAAqB;;;UAGrD,aAAa;aACZ,MAAM,CAAC,KAAK,CAAC,EAAE,WAAC,OAAA,CAAA,MAAA,KAAK,CAAC,SAAS,0CAAE,MAAM,IAAG,CAAC,CAAA,EAAA,CAAC;aAC5C,GAAG,CAAC,KAAK,CAAC,EAAE;YACX,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;YAC9E,OAAO,IAAI,CAAA;sCACe,KAAK,CAAC,IAAI,UAAU,OAAO,WAAW,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;2BACzF,KAAK,CAAC,MAAM,IAAI,gBAAgB,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU;wBAC3E,OAAO;;aAElB,CAAA;QACH,CAAC,CAAC;;;;;oBAKQ,GAAG,EAAE;YACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACnB,CAAC;iBACQ,IAAI,CAAC,KAAK;iBACV,IAAI,CAAC,KAAK;kBACT,aAAa;;;;KAI1B,CAAA;IACH,CAAC;IAED,YAAY,CAAC,CAAQ;QACnB,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAG,CAAgB,CAAC,MAAM,IAAI,CAAE,CAAgB,CAAC,MAAM,CAAC,CAAC,CAAA;QAC5F,IAAI,CAAC,mBAAmB,CAAC,SAAS,IAAI,KAAK,GAAG,EAAE,CAAA;QAEhD,CAAC,CAAC,cAAc,EAAE,CAAA;IACpB,CAAC;IAED,QAAQ,CAAC,IAAe;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAEhB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,cAAc,EAAE;YAC9B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;SACxB,CAAC,CACH,CAAA;IACH,CAAC;IAED,aAAa,CAAC,CAAa;QACzB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACpF,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,CAAa;;QAC/B,IAAI,MAAM,GAAG,CAAC,CAAC,MAAqB,CAAA;QAEpC,IAAI,CAAC,KAAK,GAAG,MAAA,MAAO,CAAC,OAAO,CAAC,cAAc,CAAC,0CAAE,YAAY,CAAC,YAAY,CAAC,CAAA;QAExE,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QAEvB,MAAM,IAAI,CAAC,cAAc,CAAA;QAEzB,MAAA,IAAI,CAAC,IAAI,0CAAE,KAAK,EAAE,CAAA;IACpB,CAAC;;AA7OM,uBAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4GF;CACF,AA9GY,CA8GZ;AAED,+EAA+E;AAC/D,8BAAa,GAA2B;IACtD,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,YAAY,EAAE,aAAa;IAC3B,aAAa,EAAE,WAAW;IAC1B,KAAK,EAAE,aAAa;IACpB,SAAS,EAAE,iBAAiB;IAC5B,UAAU,EAAE,UAAU;IACtB,GAAG,EAAE,SAAS;IACd,IAAI,EAAE,YAAY;IAClB,QAAQ,EAAE,SAAS;IACnB,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,WAAW;IACpB,SAAS,EAAE,aAAa;IACxB,SAAS,EAAE,UAAU;IACrB,aAAa,EAAE,yBAAyB;IACxC,IAAI,EAAE,UAAU;IAChB,cAAc,EAAE,SAAS;IACzB,GAAG,EAAE,YAAY;CAClB,AAnB4B,CAmB5B;AAE0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;4DAA0C;AACxC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAsB;AACrB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAc;AACb;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAkC;AAE5C;IAAhB,KAAK,CAAC,QAAQ,CAAC;+CAAoB;AACH;IAAhC,KAAK,CAAC,gBAAgB,CAAC;8CAA2B;AACjB;IAAjC,KAAK,CAAC,iBAAiB,CAAC;6DAA0C;AACjC;IAAjC,QAAQ,CAAC,cAAc,CAAC;gDAAyC","sourcesContent":["import '@material/web/icon/icon.js'\n/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { i18next } from '@operato/i18n'\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { property, query, queryAll } from 'lit/decorators.js'\n\nimport { Scene, SCENE_MODE, SceneMode } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { ComponentGroup } from '../../types.js'\nimport { ComponentMenu } from './component-menu.js'\n\nexport class ComponentToolbar extends ScopedElementsMixin(LitElement) {\n static styles = [\n css`\n /*\n * The palette rail: one glyph and one word per group, in the same Material family and ink\n * as the toolbar and the panel tabs. The old rail was a column of filled pictograms (a\n * factory with smoke, a forklift) drawn at different densities, with no captions - a\n * person hunting for a component had to guess from a picture. The caption is the point;\n * the rail is a little wider to hold it.\n */\n :host {\n left: 0;\n display: block;\n position: relative;\n\n width: var(--component-toolbar-icon-size);\n background-color: var(--component-toolbar-background-color);\n border-right: var(--component-toolbar-border);\n box-sizing: border-box;\n }\n\n [components] {\n display: block;\n padding: 4px 0;\n margin: 0;\n\n width: 100%;\n height: 100%;\n overflow: hidden;\n box-sizing: border-box;\n }\n\n [components] > [group],\n [components] > #shift {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 3px;\n\n width: calc(100% - 8px);\n min-height: 50px;\n margin: 0 4px 2px;\n padding: 6px 2px 5px;\n box-sizing: border-box;\n border-radius: 8px;\n\n color: var(--component-toolbar-icon-color, var(--md-sys-color-on-surface-variant));\n cursor: pointer;\n user-select: none;\n }\n\n [components] > [group] md-icon,\n [components] > #shift md-icon {\n --md-icon-size: 22px;\n font-variation-settings: 'wght' 300, 'opsz' 24;\n }\n\n [components] > [group] span {\n max-width: 100%;\n font-size: 0.58rem;\n line-height: 1.15;\n letter-spacing: 0.01em;\n text-align: center;\n overflow: hidden;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n /* Break between words only; a long single word gets the full width, never a hyphen-less split. */\n word-break: normal;\n overflow-wrap: normal;\n }\n\n [components] > [group]:hover,\n [components] > #shift:hover {\n color: var(--md-sys-color-on-surface);\n background-color: var(--component-toolbar-hover-background, var(--md-sys-color-surface-container-high));\n }\n\n /* The open group and the pressed mode read as pressed, in the scheme's own container tone. */\n [components] > [group][active],\n [components] > #shift[active] {\n color: var(--md-sys-color-on-secondary-container);\n background-color: var(--component-toolbar-active-background, var(--md-sys-color-secondary-container));\n }\n\n [components] > [group][active] md-icon,\n [components] > #shift[active] md-icon {\n font-variation-settings: 'wght' 500, 'opsz' 24, 'FILL' 1;\n }\n\n /* The mode switch stands apart from the groups below it. */\n [components] > #shift {\n min-height: 40px;\n margin-bottom: 6px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 8px 8px 0 0;\n }\n\n component-menu {\n position: absolute;\n top: 0;\n left: var(--component-toolbar-icon-size);\n height: 100%;\n outline: none;\n }\n\n component-menu[hidden] {\n display: none;\n }\n `\n ]\n\n /* One glyph per known group; a group registered with its own `symbol` wins. */\n static readonly GROUP_SYMBOLS: Record<string, string> = {\n line: 'timeline',\n shape: 'category',\n textAndMedia: 'text_fields',\n chartAndGauge: 'bar_chart',\n table: 'table_chart',\n container: 'space_dashboard',\n dataSource: 'database',\n IoT: 'sensors',\n '3D': 'view_in_ar',\n facility: 'factory',\n conveyance: 'conveyor_belt',\n storage: 'warehouse',\n warehouse: 'inventory_2',\n transport: 'forklift',\n manufacturing: 'precision_manufacturing',\n form: 'list_alt',\n materialDesign: 'widgets',\n etc: 'more_horiz'\n }\n\n @property({ type: Array }) componentGroupList: ComponentGroup[] = []\n @property({ type: String }) group?: string | null\n @property({ type: Object }) scene!: Scene\n @property({ type: Number }) mode: SceneMode = SCENE_MODE.EDIT\n\n @query('#shift') shift!: HTMLElement\n @query('component-menu') private menu!: HTMLElement\n @query('div[components]') private componentsContainer!: HTMLElement\n @queryAll('[data-group]') private groups!: NodeListOf<HTMLElement>\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('group')) {\n this.groups.forEach(group => {\n group.getAttribute('data-group') === this.group\n ? group.setAttribute('active', '')\n : group.removeAttribute('active')\n })\n\n this.group ? this.menu.removeAttribute('hidden') : this.menu.setAttribute('hidden', '')\n }\n }\n\n static get scopedElements() {\n return {\n 'component-menu': ComponentMenu\n }\n }\n\n render() {\n const componentList = this.componentGroupList || []\n const shift = this.mode === SCENE_MODE.SHIFT\n\n return html`\n <div components @mousewheel=${(e: MouseEvent) => this.onWheelEvent(e)}>\n <div\n id=\"shift\"\n ?active=${shift}\n title=${shift ? 'pan (shift)' : 'select (edit)'}\n @click=${(e: MouseEvent) => this._onClickShift(e)}\n >\n <md-icon>${shift ? 'pan_tool' : 'arrow_selector_tool'}</md-icon>\n </div>\n\n ${componentList\n .filter(group => group.templates?.length > 0)\n .map(group => {\n const caption = i18next.t(`group.${group.name}`, { defaultValue: group.name })\n return html`\n <div group data-group=${group.name} title=${caption} @click=${(e: MouseEvent) => this._onClickGroup(e)}>\n <md-icon>${group.symbol || ComponentToolbar.GROUP_SYMBOLS[group.name] || 'category'}</md-icon>\n <span>${caption}</span>\n </div>\n `\n })}\n </div>\n\n <component-menu\n tabindex=\"-1\"\n @focusout=${() => {\n this.group = null\n }}\n .scene=${this.scene}\n .group=${this.group}\n .groups=${componentList}\n hidden\n >\n </component-menu>\n `\n }\n\n onWheelEvent(e: Event) {\n var delta = Math.max(-1, Math.min(1, (e as WheelEvent).deltaY || -(e as WheelEvent).detail))\n this.componentsContainer.scrollTop += delta * 10\n\n e.preventDefault()\n }\n\n _setMode(mode: SceneMode) {\n this.mode = mode\n\n this.dispatchEvent(\n new CustomEvent('mode-changed', {\n bubbles: true,\n composed: true,\n detail: { value: mode }\n })\n )\n }\n\n _onClickShift(e: MouseEvent) {\n this._setMode(this.mode === SCENE_MODE.SHIFT ? SCENE_MODE.EDIT : SCENE_MODE.SHIFT)\n }\n\n async _onClickGroup(e: MouseEvent) {\n var button = e.target as HTMLElement\n\n this.group = button!.closest('[data-group]')?.getAttribute('data-group')\n\n if (!this.group) return\n\n await this.updateComplete\n\n this.menu?.focus()\n }\n}\n"]}
|
|
@@ -24,6 +24,9 @@ export const style = css `
|
|
|
24
24
|
[tools] {
|
|
25
25
|
display: flex;
|
|
26
26
|
align-items: center;
|
|
27
|
+
/* The row fills the bar, so centring the icons means the bar's middle, not the row's. */
|
|
28
|
+
height: 100%;
|
|
29
|
+
box-sizing: border-box;
|
|
27
30
|
overflow: hidden;
|
|
28
31
|
padding: 0px 10px;
|
|
29
32
|
}
|
|
@@ -43,8 +46,8 @@ export const style = css `
|
|
|
43
46
|
[tools] > .vline {
|
|
44
47
|
display: block;
|
|
45
48
|
flex: none;
|
|
46
|
-
border-left: 1px solid
|
|
47
|
-
border-right:
|
|
49
|
+
border-left: 1px solid var(--md-sys-color-outline-variant);
|
|
50
|
+
border-right: 0;
|
|
48
51
|
width: 0px;
|
|
49
52
|
height: 18px;
|
|
50
53
|
margin: 0 3px;
|
|
@@ -56,13 +59,42 @@ export const style = css `
|
|
|
56
59
|
background: var(--url-icon-htoolbar) no-repeat;
|
|
57
60
|
background-position-x: 50%;
|
|
58
61
|
opacity: 0.8;
|
|
62
|
+
/* The sprite is white art; on a light bar the theme sets a filter that darkens it. */
|
|
63
|
+
filter: var(--edit-toolbar-icon-filter, none);
|
|
59
64
|
}
|
|
60
65
|
span[button]:hover {
|
|
61
66
|
opacity: 1;
|
|
62
|
-
background-color:
|
|
67
|
+
background-color: var(--md-sys-color-surface-container-highest);
|
|
63
68
|
cursor: pointer;
|
|
64
69
|
}
|
|
65
70
|
|
|
71
|
+
/* Glyph buttons (the compact row): no sprite, the scheme's ink, a soft hover. */
|
|
72
|
+
span[button][icon] {
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
min-width: 32px;
|
|
77
|
+
min-height: 32px;
|
|
78
|
+
margin: 0 1px;
|
|
79
|
+
border-radius: 6px;
|
|
80
|
+
background: transparent;
|
|
81
|
+
filter: none;
|
|
82
|
+
opacity: 1;
|
|
83
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
84
|
+
}
|
|
85
|
+
span[button][icon] md-icon {
|
|
86
|
+
--md-icon-size: 19px;
|
|
87
|
+
font-variation-settings: 'wght' 400;
|
|
88
|
+
}
|
|
89
|
+
span[button][icon]:hover {
|
|
90
|
+
color: var(--md-sys-color-on-surface);
|
|
91
|
+
background-color: var(--md-sys-color-surface-container-highest);
|
|
92
|
+
}
|
|
93
|
+
span[button][icon][disabled] {
|
|
94
|
+
opacity: 0.35;
|
|
95
|
+
pointer-events: none;
|
|
96
|
+
}
|
|
97
|
+
|
|
66
98
|
#fullscreen,
|
|
67
99
|
#toggle-property {
|
|
68
100
|
flex: none;
|
|
@@ -276,5 +308,17 @@ export const style = css `
|
|
|
276
308
|
#toggle-property[active] {
|
|
277
309
|
background: var(--url-icon-collapse-active) 80% 10px no-repeat;
|
|
278
310
|
}
|
|
311
|
+
|
|
312
|
+
/* Glyph buttons win over the id rules above (an id outranks an attribute): no sprite, no
|
|
313
|
+
* bigger-icon box, no left rule, whatever the id says. */
|
|
314
|
+
span[button][icon]#fullscreen,
|
|
315
|
+
span[button][icon]#toggle-property,
|
|
316
|
+
span[button][icon]#toggle-property[active] {
|
|
317
|
+
background: transparent;
|
|
318
|
+
width: auto;
|
|
319
|
+
height: auto;
|
|
320
|
+
border-left: 0;
|
|
321
|
+
float: none;
|
|
322
|
+
}
|
|
279
323
|
`;
|
|
280
324
|
//# sourceMappingURL=edit-toolbar-style.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit-toolbar-style.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar-style.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"edit-toolbar-style.js","sourceRoot":"","sources":["../../../src/modeller/edit-toolbar-style.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8TvB,CAAA","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css } from 'lit'\n\nexport const style = css`\n /*\n * 편집 툴바는 도구 표면이다. 기본값이 secondary 였는데, 그 역할은 어두운 표면 위에 놓는\n * 강조색이라 다크 스킴에서 밝은 색이 된다 — 툴바 전체가 밝은 갈색 띠로 보였다.\n * 표면 계단을 쓰고 아래쪽 캔버스와의 경계는 경계선으로 준다.\n */\n :host {\n background-color: var(--edit-toolbar-background-color, var(--md-sys-color-surface-container-high));\n color: var(--edit-toolbar-color, var(--md-sys-color-on-surface));\n /*\n * 아래 구분선을 border 로 주면 1px 이 레이아웃을 늘린다. overflow-x: hidden 은 CSS 규칙상\n * overflow-y 를 auto 로 만들기 때문에, 그 1px 때문에 툴바에 세로 스크롤바가 생겼다.\n * inset box-shadow 는 레이아웃에 영향을 주지 않으므로 같은 선을 안전하게 얻는다.\n */\n box-shadow: inset 0 -1px 0 var(--md-sys-color-outline-variant);\n\n overflow: hidden;\n }\n\n [tools] {\n display: flex;\n align-items: center;\n /* The row fills the bar, so centring the icons means the bar's middle, not the row's. */\n height: 100%;\n box-sizing: border-box;\n overflow: hidden;\n padding: 0px 10px;\n }\n\n [tools] > * {\n padding: 0px;\n }\n\n [tools] > span[button] {\n min-width: 30px;\n }\n\n [tools] > span[padding] {\n flex: 1;\n }\n\n [tools] > .vline {\n display: block;\n flex: none;\n border-left: 1px solid var(--md-sys-color-outline-variant);\n border-right: 0;\n width: 0px;\n height: 18px;\n margin: 0 3px;\n }\n\n span[button] {\n min-height: 35px;\n\n background: var(--url-icon-htoolbar) no-repeat;\n background-position-x: 50%;\n opacity: 0.8;\n /* The sprite is white art; on a light bar the theme sets a filter that darkens it. */\n filter: var(--edit-toolbar-icon-filter, none);\n }\n span[button]:hover {\n opacity: 1;\n background-color: var(--md-sys-color-surface-container-highest);\n cursor: pointer;\n }\n\n /* Glyph buttons (the compact row): no sprite, the scheme's ink, a soft hover. */\n span[button][icon] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n min-height: 32px;\n margin: 0 1px;\n border-radius: 6px;\n background: transparent;\n filter: none;\n opacity: 1;\n color: var(--md-sys-color-on-surface-variant);\n }\n span[button][icon] md-icon {\n --md-icon-size: 19px;\n font-variation-settings: 'wght' 400;\n }\n span[button][icon]:hover {\n color: var(--md-sys-color-on-surface);\n background-color: var(--md-sys-color-surface-container-highest);\n }\n span[button][icon][disabled] {\n opacity: 0.35;\n pointer-events: none;\n }\n\n #fullscreen,\n #toggle-property {\n flex: none;\n }\n\n #align-left {\n background-position-y: 8px;\n }\n\n #align-center {\n background-position-y: -42px;\n }\n\n #align-right {\n background-position-y: -92px;\n }\n\n #align-top {\n background-position-y: -142px;\n }\n\n #align-middle {\n background-position-y: -192px;\n }\n\n #align-bottom {\n background-position-y: -242px;\n }\n\n #undo {\n background-position-y: -592px;\n }\n\n #redo {\n background-position-y: -642px;\n }\n\n #front {\n background-position-y: -292px;\n }\n\n #back {\n background-position-y: -342px;\n }\n\n #forward {\n background-position-y: -392px;\n }\n\n #backward {\n background-position-y: -442px;\n }\n\n #symmetry-x {\n background-position-y: -492px;\n }\n\n #symmetry-y {\n background-position-y: -542px;\n }\n\n #group {\n background-position-y: -492px;\n }\n\n #ungroup {\n background-position-y: -542px;\n }\n\n #fullscreen {\n background-position-y: -692px;\n }\n\n #toggle-property {\n background-position-y: -692px;\n float: right;\n }\n\n #zoomin {\n background-position-y: -742px;\n }\n\n #zoomout {\n background-position-y: -792px;\n }\n\n #fit-scene {\n background-position-y: -1492px;\n }\n\n #cut {\n background-position-y: -842px;\n }\n\n #copy {\n background-position-y: -892px;\n }\n\n #paste {\n background-position-y: -942px;\n }\n\n #delete {\n background-position-y: -992px;\n }\n\n #font-increase {\n background-position-y: -1042px;\n }\n\n #font-decrease {\n background-position-y: -1092px;\n }\n\n #style-copy {\n background-position-y: -1142px;\n }\n\n #databind-copy {\n background-position-y: -1692px;\n }\n\n #context-menu {\n background-position-y: -692px;\n }\n\n #symmetry-x {\n background-position-y: -1192px;\n }\n\n #symmetry-y {\n background-position-y: -1242px;\n }\n\n #rotate-cw {\n background-position-y: -1292px;\n }\n\n #rotate-ccw {\n background-position-y: -1342px;\n }\n\n #distribute-horizontal {\n background-position-y: -1542px;\n }\n\n #distribute-vertical {\n background-position-y: -1593px;\n }\n\n #align-z-front {\n background-position-y: -142px;\n filter: hue-rotate(180deg);\n }\n\n #align-z-middle {\n background-position-y: -192px;\n filter: hue-rotate(180deg);\n }\n\n #align-z-back {\n background-position-y: -242px;\n filter: hue-rotate(180deg);\n }\n\n #distribute-z {\n background-position-y: -1593px;\n filter: hue-rotate(180deg);\n }\n\n .gizmo-btn {\n background: none !important;\n color: rgba(255, 255, 255, 0.5);\n min-width: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n border-radius: 3px;\n padding: 2px;\n }\n\n .gizmo-btn[disabled] {\n opacity: 0.3;\n pointer-events: none;\n }\n\n #toggle-property {\n background-position-y: -1392px;\n }\n\n #preview {\n background-position-y: -1640px;\n }\n\n /* bigger buttons */\n #fullscreen {\n background: var(--url-icon-fullscreen) 50% 10px no-repeat;\n width: var(--edit-toolbar-bigger-icon-size);\n height: var(--edit-toolbar-bigger-icon-size);\n border-left: var(--edit-toolbar-bigger-icon-line);\n }\n\n #toggle-property {\n background: var(--url-icon-collapse) 80% 10px no-repeat;\n width: var(--edit-toolbar-bigger-icon-size);\n height: var(--edit-toolbar-bigger-icon-size);\n border-left: var(--edit-toolbar-bigger-icon-line);\n }\n\n #toggle-property[active] {\n background: var(--url-icon-collapse-active) 80% 10px no-repeat;\n }\n\n /* Glyph buttons win over the id rules above (an id outranks an attribute): no sprite, no\n * bigger-icon box, no left rule, whatever the id says. */\n span[button][icon]#fullscreen,\n span[button][icon]#toggle-property,\n span[button][icon]#toggle-property[active] {\n background: transparent;\n width: auto;\n height: auto;\n border-left: 0;\n float: none;\n }\n`\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license Copyright © HatioLab Inc. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
+
import '@material/web/icon/icon.js';
|
|
4
5
|
import { LitElement, PropertyValues } from 'lit';
|
|
5
6
|
import { Component, Scene } from '@hatiolab/things-scene';
|
|
6
7
|
import './bulk-create-dialog.js';
|
|
@@ -9,12 +10,17 @@ export declare class EditToolbar extends LitElement {
|
|
|
9
10
|
scene?: Scene;
|
|
10
11
|
selected: any[];
|
|
11
12
|
hideProperty: boolean;
|
|
13
|
+
compact: boolean;
|
|
12
14
|
private _dimension;
|
|
13
15
|
private _gizmoAttached;
|
|
14
16
|
private cliped?;
|
|
17
|
+
connectedCallback(): void;
|
|
18
|
+
disconnectedCallback(): void;
|
|
15
19
|
firstUpdated(): void;
|
|
16
20
|
updated(changes: PropertyValues<this>): void;
|
|
17
21
|
render(): import("lit-html").TemplateResult<1>;
|
|
22
|
+
private renderWindowButtons;
|
|
23
|
+
private _onFullscreenChange;
|
|
18
24
|
onWheelEvent(e: Event): void;
|
|
19
25
|
getSymbol(key: string): string;
|
|
20
26
|
private getShortcutString;
|