@operato/property-panel 10.0.0-beta.7 → 10.0.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +478 -0
  2. package/dist/src/graphql/data-subscription.js +5 -1
  3. package/dist/src/graphql/data-subscription.js.map +1 -1
  4. package/dist/src/index.d.ts +4 -0
  5. package/dist/src/index.js +6 -0
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/ox-property-panel.d.ts +17 -0
  8. package/dist/src/ox-property-panel.js +105 -39
  9. package/dist/src/ox-property-panel.js.map +1 -1
  10. package/dist/src/property-panel/abstract-property.js +11 -2
  11. package/dist/src/property-panel/abstract-property.js.map +1 -1
  12. package/dist/src/property-panel/data-binding/data-binding-mapper.js +11 -3
  13. package/dist/src/property-panel/data-binding/data-binding-mapper.js.map +1 -1
  14. package/dist/src/property-panel/data-binding/data-binding-popup.d.ts +63 -0
  15. package/dist/src/property-panel/data-binding/data-binding-popup.js +1414 -0
  16. package/dist/src/property-panel/data-binding/data-binding-popup.js.map +1 -0
  17. package/dist/src/property-panel/data-binding/data-binding.d.ts +1 -0
  18. package/dist/src/property-panel/data-binding/data-binding.js +37 -5
  19. package/dist/src/property-panel/data-binding/data-binding.js.map +1 -1
  20. package/dist/src/property-panel/effects/effects.js +1 -1
  21. package/dist/src/property-panel/effects/effects.js.map +1 -1
  22. package/dist/src/property-panel/effects/property-event-tap.js +21 -1
  23. package/dist/src/property-panel/effects/property-event-tap.js.map +1 -1
  24. package/dist/src/property-panel/effects/property-event.d.ts +15 -7
  25. package/dist/src/property-panel/effects/property-event.js +17 -38
  26. package/dist/src/property-panel/effects/property-event.js.map +1 -1
  27. package/dist/src/property-panel/effects/property-shadow.js +14 -5
  28. package/dist/src/property-panel/effects/property-shadow.js.map +1 -1
  29. package/dist/src/property-panel/event-handlers/event-handlers-help.d.ts +23 -0
  30. package/dist/src/property-panel/event-handlers/event-handlers-help.js +356 -0
  31. package/dist/src/property-panel/event-handlers/event-handlers-help.js.map +1 -0
  32. package/dist/src/property-panel/event-handlers/event-handlers-mapper.d.ts +31 -0
  33. package/dist/src/property-panel/event-handlers/event-handlers-mapper.js +238 -0
  34. package/dist/src/property-panel/event-handlers/event-handlers-mapper.js.map +1 -0
  35. package/dist/src/property-panel/event-handlers/event-handlers-popup.d.ts +42 -0
  36. package/dist/src/property-panel/event-handlers/event-handlers-popup.js +375 -0
  37. package/dist/src/property-panel/event-handlers/event-handlers-popup.js.map +1 -0
  38. package/dist/src/property-panel/event-handlers/event-handlers.d.ts +54 -0
  39. package/dist/src/property-panel/event-handlers/event-handlers.js +410 -0
  40. package/dist/src/property-panel/event-handlers/event-handlers.js.map +1 -0
  41. package/dist/src/property-panel/inspector/inspector-controller.d.ts +66 -0
  42. package/dist/src/property-panel/inspector/inspector-controller.js +288 -0
  43. package/dist/src/property-panel/inspector/inspector-controller.js.map +1 -0
  44. package/dist/src/property-panel/inspector/inspector-group-view.d.ts +15 -0
  45. package/dist/src/property-panel/inspector/inspector-group-view.js +59 -0
  46. package/dist/src/property-panel/inspector/inspector-group-view.js.map +1 -0
  47. package/dist/src/property-panel/inspector/inspector-highlight.d.ts +7 -0
  48. package/dist/src/property-panel/inspector/inspector-highlight.js +25 -0
  49. package/dist/src/property-panel/inspector/inspector-highlight.js.map +1 -0
  50. package/dist/src/property-panel/inspector/inspector-model.d.ts +44 -0
  51. package/dist/src/property-panel/inspector/inspector-model.js +72 -0
  52. package/dist/src/property-panel/inspector/inspector-model.js.map +1 -0
  53. package/dist/src/property-panel/inspector/inspector-tree-view.d.ts +18 -0
  54. package/dist/src/property-panel/inspector/inspector-tree-view.js +61 -0
  55. package/dist/src/property-panel/inspector/inspector-tree-view.js.map +1 -0
  56. package/dist/src/property-panel/inspector/inspector.d.ts +17 -12
  57. package/dist/src/property-panel/inspector/inspector.js +281 -179
  58. package/dist/src/property-panel/inspector/inspector.js.map +1 -1
  59. package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.d.ts +20 -0
  60. package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.js +125 -0
  61. package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.js.map +1 -0
  62. package/dist/src/property-panel/shapes/placeholder-convert.d.ts +34 -0
  63. package/dist/src/property-panel/shapes/placeholder-convert.js +117 -0
  64. package/dist/src/property-panel/shapes/placeholder-convert.js.map +1 -0
  65. package/dist/src/property-panel/shapes/shapes.js +28 -10
  66. package/dist/src/property-panel/shapes/shapes.js.map +1 -1
  67. package/dist/src/property-panel/specifics/specifics.d.ts +1 -0
  68. package/dist/src/property-panel/specifics/specifics.js +2 -1
  69. package/dist/src/property-panel/specifics/specifics.js.map +1 -1
  70. package/dist/src/property-panel/threed/property-material3d.js +8 -1
  71. package/dist/src/property-panel/threed/property-material3d.js.map +1 -1
  72. package/dist/src/property-panel/threed/property-scene3d.d.ts +34 -6
  73. package/dist/src/property-panel/threed/property-scene3d.js +332 -201
  74. package/dist/src/property-panel/threed/property-scene3d.js.map +1 -1
  75. package/dist/src/property-panel/threed/threed.js +8 -0
  76. package/dist/src/property-panel/threed/threed.js.map +1 -1
  77. package/dist/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +8 -7
  79. package/themes/grist-theme.css +1 -1
  80. package/translations/en.json +34 -1
  81. package/translations/ja.json +34 -1
  82. package/translations/ko.json +34 -1
  83. package/translations/ms.json +34 -1
  84. package/translations/zh.json +34 -1
@@ -1 +1 @@
1
- {"version":3,"file":"shapes.js","sourceRoot":"","sources":["../../../../src/property-panel/shapes/shapes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/input/ox-input-angle.js'\nimport '@operato/input/ox-buttons-radio.js'\nimport '@material/web/icon/icon.js'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/help/ox-title-with-help.js'\n\nimport { css, html } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\n\nimport { BOUNDS, Component, Properties } from '@hatiolab/things-scene'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\nimport { BoxPaddingEditorStyles } from '@operato/styles/box-padding-editor-styles.js'\n\nimport { AbstractProperty } from '../abstract-property.js'\n\nexport class PropertyShapes extends AbstractProperty {\n static styles = [PropertyGridStyles, BoxPaddingEditorStyles]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) bounds: BOUNDS | null = null\n @property({ type: Array }) selected: Component[] = []\n\n @state() private _positionExpanded: boolean = false\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n }\n\n render() {\n const value = this.value || {}\n const { width = '', height = '' } = this.bounds || {}\n\n return html`\n <fieldset>\n <div class=\"property-grid\">\n ${this._isIdentifiable(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.id\">ID</ox-i18n> </label>\n <input value-key=\"id\" .value=${value.id || ''} />\n `\n : html``}\n ${this._isClassIdentifiable(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.class\">Class</ox-i18n> </label>\n <input value-key=\"class\" .value=${value.class || ''} />\n `\n : html``}\n ${this._hasTextProperty(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.text\">Text</ox-i18n> </label>\n <input value-key=\"text\" .value=${value.text || ''} />\n <label> <ox-i18n msgid=\"label.text-format\">Text Format</ox-i18n> </label>\n <input value-key=\"textFormat\" .value=${value.textFormat || ''} list=\"format-list\" />\n <datalist id=\"format-list\">\n <option value=\"#,###.\"></option>\n <option value=\"#,###.#\"></option>\n <option value=\"#,###.0\"></option>\n <option value=\"#,##0.#\"></option>\n <option value=\"#,##0.0\"></option>\n <option value=\"#,##0.0%\"></option>\n </datalist>\n `\n : html``}\n ${this._hasProperties(this.selected)\n ? html`\n <input id=\"checkbox-hidden\" value-key=\"hidden\" type=\"checkbox\" .checked=${value.hidden} />\n <label for=\"checkbox-hidden\"> <ox-i18n msgid=\"label.item-hidden\">Item Hidden</ox-i18n> </label>\n\n <input id=\"checkbox-locked\" value-key=\"locked\" type=\"checkbox\" .checked=${value.locked} />\n <label for=\"checkbox-locked\"> <ox-i18n msgid=\"label.locked\">Locked</ox-i18n> </label>\n `\n : html``}\n </div>\n </fieldset>\n\n ${!this._isLine(this.selected)\n ? keyed(\n this.selected,\n html`\n <fieldset class=\"icon-label\">\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/size\" msgid=\"label.size\">size</ox-title-with-help>\n </legend>\n\n <div class=\"property-grid\">\n <label> <md-icon>arrow_range</md-icon><ox-i18n msgid=\"label.width\">width</ox-i18n> </label>\n <input type=\"number\" value-key=\"bounds.width\" .value=${String(width)} />\n <label> <md-icon>height</md-icon><ox-i18n msgid=\"label.height\">height</ox-i18n> </label>\n <input type=\"number\" value-key=\"bounds.height\" .value=${String(height)} />\n\n ${this.selected.length && this.selected[0].isRootModel()\n ? html``\n : html`\n <label class=\"rotate\">\n <md-icon>rotate_90_degrees_cw</md-icon><ox-i18n msgid=\"label.rotate\">rotate</ox-i18n>\n </label>\n <ox-input-angle value-key=\"rotation\" .value=${value.rotation ?? 0}> </ox-input-angle>\n `}\n </div>\n </fieldset>\n `\n )\n : html``}\n ${this._isPositionable(this.selected)\n ? keyed(\n this.selected,\n html`\n <fieldset class=\"icon-label\" collapsable ?collapsed=${!this._positionExpanded}>\n <legend\n @click=${(e: Event) => {\n this._positionExpanded = !this._positionExpanded\n }}\n >\n <ox-title-with-help topic=\"board-modeller/shapes/position\" msgid=\"label.position\"\n >position</ox-title-with-help\n >\n <md-icon>${this._positionExpanded ? 'expand_less' : 'expand_more'}</md-icon>\n </legend>\n\n <div class=\"property-grid\">\n <label>Position</label>\n <select value-key=\"position\" .value=${value.position}>\n <option value=\"\">&nbsp;</option>\n <option value=\"static\">static</option>\n <option value=\"relative\">relative</option>\n <option value=\"absolute\">absolute</option>\n <option value=\"fixed\">fixed</option>\n <option value=\"sticky\">sticky</option>\n </select>\n\n <label>Origin</label>\n <select value-key=\"origin\" .value=${value.origin}>\n <option value=\"\">&nbsp;</option>\n <option value=\"left-top\">left-top</option>\n <option value=\"center-top\">center-top</option>\n <option value=\"right-top\">right-top</option>\n <option value=\"left-middle\">left-middle</option>\n <option value=\"center-middle\">center-middle</option>\n <option value=\"right-middle\">right-middle</option>\n <option value=\"left-bottom\">left-bottom</option>\n <option value=\"center-bottom\">center-bottom</option>\n <option value=\"right-bottom\">right-bottom</option>\n </select>\n\n <label> <ox-i18n msgid=\"label.offset-x\">offset-X</ox-i18n> </label>\n <input type=\"number\" value-key=\"offsetX\" .value=${String(value.offsetX ?? '')} />\n <label> <ox-i18n msgid=\"label.offset-y\">offset-Y</ox-i18n> </label>\n <input type=\"number\" value-key=\"offsetY\" .value=${String(value.offsetY ?? '')} />\n </div>\n </fieldset>\n `\n )\n : html``}\n ${this._hasTextProperty(this.selected)\n ? html`\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/text-box\" msgid=\"label.text-box\"\n >text box</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label> <ox-i18n msgid=\"label.horizontal\">horizontal</ox-i18n> </label>\n <ox-buttons-radio value-key=\"textAlign\" .value=${value.textAlign}>\n <md-icon data-value=\"left\">format_align_left</md-icon>\n <md-icon data-value=\"center\">format_align_center</md-icon>\n <md-icon data-value=\"right\">format_align_right</md-icon>\n <md-icon data-value=\"justify\">format_align_justify</md-icon>\n </ox-buttons-radio>\n\n <label> <ox-i18n msgid=\"label.vertical\">vertical</ox-i18n> </label>\n <ox-buttons-radio value-key=\"textBaseline\" .value=${value.textBaseline}>\n <md-icon data-value=\"top\">align_vertical_top</md-icon>\n <md-icon data-value=\"middle\">align_vertical_center</md-icon>\n <md-icon data-value=\"bottom\">align_vertical_bottom</md-icon>\n </ox-buttons-radio>\n\n <input\n id=\"checkbox-support-markdown\"\n type=\"checkbox\"\n value-key=\"supportMarkdown\"\n .checked=${value.supportMarkdown}\n />\n <label for=\"checkbox-support-markdown\">\n <ox-i18n msgid=\"label.support-markdown\">Support Markdown</ox-i18n>\n </label>\n\n <input id=\"checkbox-textwrap\" type=\"checkbox\" value-key=\"textWrap\" .checked=${value.textWrap} />\n <label for=\"checkbox-textwrap\"> <ox-i18n msgid=\"label.text-wrap\">Text Wrap</ox-i18n> </label>\n\n ${!value.textWrap\n ? html` <label for=\"checkbox-textOverflow\">\n <ox-i18n msgid=\"label.text-overflow\">Text Overflow</ox-i18n>\n </label>\n <select value-key=\"textOverflow\" .value=${value.textOverflow || ''}>\n <option value=\"\" selected>none</option>\n <option value=\"ellipsis\">ellipsis</option>\n <option value=\"clip\">clip</option>\n </select>`\n : ''}\n\n <label> <ox-i18n msgid=\"label.padding\">padding</ox-i18n> </label>\n <table class=\"box-padding custom-editor\">\n <tr>\n <td class=\"slide1\"></td>\n <td class=\"slide2\"></td>\n <td class=\"slide3\"></td>\n </tr>\n <tr>\n <td class=\"slide4\"></td>\n <td class=\"slide5\">\n <input type=\"number\" value-key=\"paddingTop\" .value=${value.paddingTop || 0} />\n <input type=\"number\" value-key=\"paddingLeft\" .value=${value.paddingLeft || 0} />\n <input type=\"number\" value-key=\"paddingRight\" .value=${value.paddingRight || 0} />\n <input type=\"number\" value-key=\"paddingBottom\" .value=${value.paddingBottom || 0} />\n </td>\n <td class=\"slide6\"></td>\n </tr>\n <tr>\n <td class=\"slide7\"></td>\n <td class=\"slide8\"></td>\n <td class=\"slide9\"></td>\n </tr>\n </table>\n </div>\n </fieldset>\n `\n : html``}\n ${this.selected.length && this.selected[0].isRootModel()\n ? html`\n <fieldset class=\"icon-label\">\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/viewer-option\" msgid=\"label.viewer-option\"\n >Viewer Option</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label><ox-i18n msgid=\"label.fit\">Fit</ox-i18n></label>\n <select value-key=\"fitMode\" .value=${value.fitMode || 'ratio'}>\n <option value=\"none\">none</option>\n <option value=\"center\">center</option>\n <option value=\"ratio\" selected>ratio</option>\n <option value=\"both\">both</option>\n <option value=\"width\">width</option>\n <option value=\"height\">height</option>\n </select>\n </div>\n </fieldset>\n <fieldset class=\"icon-label\">\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/print-option\" msgid=\"label.label-print\"\n >Print Option</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label class=\"rotate\"><ox-i18n msgid=\"label.label-rotation\">Label Rotation</ox-i18n></label>\n <select value-key=\"labelRotation\" .value=${value.labelRotation || 'N'}>\n <option value=\"N\" selected>0°</option>\n <option value=\"B\">90°</option>\n <option value=\"I\">180°</option>\n <option value=\"R\">270°</option>\n </select>\n </div>\n </fieldset>\n `\n : html``}\n `\n }\n\n onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this.getValueFromEventTarget(element)\n\n if (key.indexOf('bounds.') == 0) {\n if (isNaN(value)) return\n this.dispatchEvent(\n new CustomEvent('bounds-change', {\n bubbles: true,\n composed: true,\n detail: {\n [key.substr(7)]: value\n }\n })\n )\n } else {\n this.onAfterValueChange(key, value)\n }\n }\n\n _hasTextProperty(selected: Component[]) {\n for (let i = 0; i < selected.length; i++) {\n if (!selected[i].hasTextProperty) return false\n }\n\n return true\n }\n\n _hasProperties(selected: Component[]) {\n if (!selected || selected.length == 0 || (selected[0] && selected[0].isLayer && selected[0].isLayer())) return false\n\n return true\n }\n\n _isIdentifiable(selected: Component[]) {\n if (!selected || selected.length == 0 || selected.length > 1 || (selected[0].isLayer && selected[0].isLayer()))\n return false\n\n return true\n }\n\n _isClassIdentifiable(selected: Component[]) {\n if (!selected || (selected[0] && selected[0].isLayer())) return false\n\n return true\n }\n\n _isLine(selected: Component[]) {\n if (!selected || !(selected[0] && selected[0].isLine())) return false\n\n return true\n }\n\n _isPositionable(selected: Component[]) {\n if (!selected || !(selected[0] && selected[0].isPositionable())) return false\n\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"shapes.js","sourceRoot":"","sources":["../../../../src/property-panel/shapes/shapes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/input/ox-input-angle.js'\nimport '@operato/input/ox-buttons-radio.js'\nimport '@material/web/icon/icon.js'\nimport '@operato/i18n/ox-i18n.js'\nimport '@operato/help/ox-title-with-help.js'\n\nimport { css, html } from 'lit'\nimport { property, state } from 'lit/decorators.js'\nimport { keyed } from 'lit/directives/keyed.js'\n\nimport { BOUNDS, Component, Properties } from '@hatiolab/things-scene'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\nimport { BoxPaddingEditorStyles } from '@operato/styles/box-padding-editor-styles.js'\n\nimport { AbstractProperty } from '../abstract-property.js'\n\nexport class PropertyShapes extends AbstractProperty {\n static styles = [\n PropertyGridStyles,\n BoxPaddingEditorStyles,\n css`\n `\n ]\n\n @property({ type: Object }) value?: Properties\n @property({ type: Object }) bounds: BOUNDS | null = null\n @property({ type: Array }) selected: Component[] = []\n\n @state() private _positionExpanded: boolean = false\n\n firstUpdated() {\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n }\n\n render() {\n const value = this.value || {}\n const { width = '', height = '' } = this.bounds || {}\n\n return html`\n <fieldset>\n <div class=\"property-grid\">\n ${this._isIdentifiable(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.id\">ID</ox-i18n> </label>\n <input value-key=\"id\" .value=${value.id || ''} />\n `\n : html``}\n ${this._isClassIdentifiable(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.class\">Class</ox-i18n> </label>\n <input value-key=\"class\" .value=${value.class || ''} />\n `\n : html``}\n ${this._hasTextProperty(this.selected)\n ? html`\n <label> <ox-i18n msgid=\"label.text\">Text</ox-i18n> </label>\n <input value-key=\"text\" .value=${value.text || ''} />\n <label> <ox-i18n msgid=\"label.text-format\">Text Format</ox-i18n> </label>\n <input value-key=\"textFormat\" .value=${value.textFormat || ''} list=\"format-list\" />\n <datalist id=\"format-list\">\n <option value=\"#,###.\"></option>\n <option value=\"#,###.#\"></option>\n <option value=\"#,###.0\"></option>\n <option value=\"#,##0.#\"></option>\n <option value=\"#,##0.0\"></option>\n <option value=\"#,##0.0%\"></option>\n </datalist>\n `\n : html``}\n ${this._hasProperties(this.selected)\n ? html`\n <input id=\"checkbox-hidden\" value-key=\"hidden\" type=\"checkbox\" .checked=${value.hidden} />\n <label for=\"checkbox-hidden\"> <ox-i18n msgid=\"label.item-hidden\">Item Hidden</ox-i18n> </label>\n\n <input id=\"checkbox-locked\" value-key=\"locked\" type=\"checkbox\" .checked=${value.locked} />\n <label for=\"checkbox-locked\"> <ox-i18n msgid=\"label.locked\">Locked</ox-i18n> </label>\n `\n : html``}\n </div>\n </fieldset>\n\n ${!this._isLine(this.selected)\n ? keyed(\n this.selected,\n html`\n <fieldset class=\"icon-label\">\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/size\" msgid=\"label.size\">size</ox-title-with-help>\n </legend>\n\n <div class=\"property-grid\">\n <label> <md-icon>arrow_range</md-icon><ox-i18n msgid=\"label.width\">width</ox-i18n> </label>\n <input type=\"number\" value-key=\"bounds.width\" .value=${String(width)} />\n <label> <md-icon>height</md-icon><ox-i18n msgid=\"label.height\">height</ox-i18n> </label>\n <input type=\"number\" value-key=\"bounds.height\" .value=${String(height)} />\n\n ${this.selected.length &&\n this.selected[0] &&\n typeof this.selected[0].isRootModel === 'function' &&\n this.selected[0].isRootModel()\n ? html``\n : html`\n <label class=\"rotate\">\n <md-icon>rotate_90_degrees_cw</md-icon><ox-i18n msgid=\"label.rotate\">rotate</ox-i18n>\n </label>\n <ox-input-angle value-key=\"rotation\" .value=${value.rotation ?? 0}> </ox-input-angle>\n `}\n </div>\n </fieldset>\n `\n )\n : html``}\n ${this._isPositionable(this.selected)\n ? keyed(\n this.selected,\n html`\n <fieldset class=\"icon-label\" collapsable ?collapsed=${!this._positionExpanded}>\n <legend\n @click=${(e: Event) => {\n this._positionExpanded = !this._positionExpanded\n }}\n >\n <ox-title-with-help topic=\"board-modeller/shapes/position\" msgid=\"label.position\"\n >position</ox-title-with-help\n >\n <md-icon>${this._positionExpanded ? 'expand_less' : 'expand_more'}</md-icon>\n </legend>\n\n <div class=\"property-grid\">\n <label>Position</label>\n <select value-key=\"position\" .value=${value.position}>\n <option value=\"\">&nbsp;</option>\n <option value=\"static\">static</option>\n <option value=\"relative\">relative</option>\n <option value=\"absolute\">absolute</option>\n <option value=\"fixed\">fixed</option>\n <option value=\"sticky\">sticky</option>\n <option value=\"popup\">popup (template)</option>\n </select>\n\n <label>Origin</label>\n <select value-key=\"origin\" .value=${value.origin}>\n <option value=\"\">&nbsp;</option>\n <option value=\"left-top\">left-top</option>\n <option value=\"center-top\">center-top</option>\n <option value=\"right-top\">right-top</option>\n <option value=\"left-middle\">left-middle</option>\n <option value=\"center-middle\">center-middle</option>\n <option value=\"right-middle\">right-middle</option>\n <option value=\"left-bottom\">left-bottom</option>\n <option value=\"center-bottom\">center-bottom</option>\n <option value=\"right-bottom\">right-bottom</option>\n </select>\n\n <label> <ox-i18n msgid=\"label.offset-x\">offset-X</ox-i18n> </label>\n <input type=\"number\" value-key=\"offsetX\" .value=${String(value.offsetX ?? '')} />\n <label> <ox-i18n msgid=\"label.offset-y\">offset-Y</ox-i18n> </label>\n <input type=\"number\" value-key=\"offsetY\" .value=${String(value.offsetY ?? '')} />\n </div>\n </fieldset>\n `\n )\n : html``}\n ${this._hasTextProperty(this.selected)\n ? html`\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/text-box\" msgid=\"label.text-box\"\n >text box</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label> <ox-i18n msgid=\"label.horizontal\">horizontal</ox-i18n> </label>\n <ox-buttons-radio value-key=\"textAlign\" .value=${value.textAlign}>\n <md-icon data-value=\"left\">format_align_left</md-icon>\n <md-icon data-value=\"center\">format_align_center</md-icon>\n <md-icon data-value=\"right\">format_align_right</md-icon>\n <md-icon data-value=\"justify\">format_align_justify</md-icon>\n </ox-buttons-radio>\n\n <label> <ox-i18n msgid=\"label.vertical\">vertical</ox-i18n> </label>\n <ox-buttons-radio value-key=\"textBaseline\" .value=${value.textBaseline}>\n <md-icon data-value=\"top\">align_vertical_top</md-icon>\n <md-icon data-value=\"middle\">align_vertical_center</md-icon>\n <md-icon data-value=\"bottom\">align_vertical_bottom</md-icon>\n </ox-buttons-radio>\n\n <input\n id=\"checkbox-support-markdown\"\n type=\"checkbox\"\n value-key=\"supportMarkdown\"\n .checked=${value.supportMarkdown}\n />\n <label for=\"checkbox-support-markdown\">\n <ox-i18n msgid=\"label.support-markdown\">Support Markdown</ox-i18n>\n </label>\n\n <input id=\"checkbox-textwrap\" type=\"checkbox\" value-key=\"textWrap\" .checked=${value.textWrap} />\n <label for=\"checkbox-textwrap\"> <ox-i18n msgid=\"label.text-wrap\">Text Wrap</ox-i18n> </label>\n\n ${!value.textWrap\n ? html` <label for=\"checkbox-textOverflow\">\n <ox-i18n msgid=\"label.text-overflow\">Text Overflow</ox-i18n>\n </label>\n <select value-key=\"textOverflow\" .value=${value.textOverflow || ''}>\n <option value=\"\" selected>none</option>\n <option value=\"ellipsis\">ellipsis</option>\n <option value=\"clip\">clip</option>\n </select>`\n : ''}\n\n <label> <ox-i18n msgid=\"label.padding\">padding</ox-i18n> </label>\n <table class=\"box-padding custom-editor\">\n <tr>\n <td class=\"slide1\"></td>\n <td class=\"slide2\"></td>\n <td class=\"slide3\"></td>\n </tr>\n <tr>\n <td class=\"slide4\"></td>\n <td class=\"slide5\">\n <input type=\"number\" value-key=\"paddingTop\" .value=${value.paddingTop || 0} />\n <input type=\"number\" value-key=\"paddingLeft\" .value=${value.paddingLeft || 0} />\n <input type=\"number\" value-key=\"paddingRight\" .value=${value.paddingRight || 0} />\n <input type=\"number\" value-key=\"paddingBottom\" .value=${value.paddingBottom || 0} />\n </td>\n <td class=\"slide6\"></td>\n </tr>\n <tr>\n <td class=\"slide7\"></td>\n <td class=\"slide8\"></td>\n <td class=\"slide9\"></td>\n </tr>\n </table>\n </div>\n </fieldset>\n `\n : html``}\n ${this.selected.length &&\n this.selected[0] &&\n typeof this.selected[0].isRootModel === 'function' &&\n this.selected[0].isRootModel()\n ? html`\n <fieldset class=\"icon-label\">\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/viewer-option\" msgid=\"label.viewer-option\"\n >Viewer Option</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label><ox-i18n msgid=\"label.fit\">Fit</ox-i18n></label>\n <select value-key=\"fitMode\" .value=${value.fitMode || 'ratio'}>\n <option value=\"none\">none</option>\n <option value=\"center\">center</option>\n <option value=\"ratio\" selected>ratio</option>\n <option value=\"both\">both</option>\n <option value=\"width\">width</option>\n <option value=\"height\">height</option>\n </select>\n </div>\n </fieldset>\n <fieldset class=\"icon-label\">\n <legend>\n <ox-title-with-help topic=\"board-modeller/shapes/print-option\" msgid=\"label.label-print\"\n >Print Option</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label class=\"rotate\"><ox-i18n msgid=\"label.label-rotation\">Label Rotation</ox-i18n></label>\n <select value-key=\"labelRotation\" .value=${value.labelRotation || 'N'}>\n <option value=\"N\" selected>0°</option>\n <option value=\"B\">90°</option>\n <option value=\"I\">180°</option>\n <option value=\"R\">270°</option>\n </select>\n </div>\n </fieldset>\n `\n : html``}\n `\n }\n\n onValueChange(e: Event) {\n var element = e.target as HTMLElement\n var key = element.getAttribute('value-key')\n\n if (!key) {\n return\n }\n\n var value = this.getValueFromEventTarget(element)\n\n if (key.indexOf('bounds.') == 0) {\n if (isNaN(value)) return\n this.dispatchEvent(\n new CustomEvent('bounds-change', {\n bubbles: true,\n composed: true,\n detail: {\n [key.substr(7)]: value\n }\n })\n )\n } else {\n this.onAfterValueChange(key, value)\n }\n }\n\n _hasTextProperty(selected: Component[]) {\n for (let i = 0; i < selected.length; i++) {\n if (!selected[i] || !selected[i].hasTextProperty) return false\n }\n\n return true\n }\n\n _hasProperties(selected: Component[]) {\n if (\n !selected ||\n selected.length == 0 ||\n (selected[0] && typeof selected[0].isLayer === 'function' && selected[0].isLayer())\n )\n return false\n\n return true\n }\n\n _isIdentifiable(selected: Component[]) {\n if (\n !selected ||\n selected.length == 0 ||\n selected.length > 1 ||\n !selected[0] ||\n (typeof selected[0].isLayer === 'function' && selected[0].isLayer())\n )\n return false\n\n return true\n }\n\n _isClassIdentifiable(selected: Component[]) {\n if (!selected || (selected[0] && typeof selected[0].isLayer === 'function' && selected[0].isLayer())) return false\n\n return true\n }\n\n _isLine(selected: Component[]) {\n if (!selected || !(selected[0] && typeof selected[0].isLine === 'function' && selected[0].isLine())) return false\n\n return true\n }\n\n _isPositionable(selected: Component[]) {\n if (!selected || !(selected[0] && typeof selected[0].isPositionable === 'function' && selected[0].isPositionable()))\n return false\n\n return true\n }\n}\n"]}
@@ -2,6 +2,7 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
  import '@operato/help/ox-help-icon.js';
5
+ import '../shapes/ox-placeholder-convert-editor.js';
5
6
  import { LitElement } from 'lit';
6
7
  import { Component, Scene } from '@hatiolab/things-scene';
7
8
  import { SpecificPropertiesBuilder } from './specific-properties-builder.js';
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { __decorate } from "tslib";
5
5
  import '@operato/help/ox-help-icon.js';
6
+ import '../shapes/ox-placeholder-convert-editor.js';
6
7
  import { css, html, LitElement } from 'lit';
7
8
  import { property } from 'lit/decorators.js';
8
9
  import { ScopedElementsMixin } from '@open-wc/scoped-elements';
@@ -37,7 +38,7 @@ export class PropertySpecific extends ScopedElementsMixin(LitElement) {
37
38
  const value = this.value || {};
38
39
  return html `
39
40
  <label
40
- >${i18next.t(`component.${value.type}`)}<ox-help-icon .topic=${(_a = selected === null || selected === void 0 ? void 0 : selected.nature) === null || _a === void 0 ? void 0 : _a.help}></ox-help-icon
41
+ >${value.type ? i18next.t(`component.${value.type}`) : i18next.t('label.mixed-selection')}<ox-help-icon .topic=${(_a = selected === null || selected === void 0 ? void 0 : selected.nature) === null || _a === void 0 ? void 0 : _a.help}></ox-help-icon
41
42
  ></label>
42
43
 
43
44
  <specific-properties-builder .value=${value} .props=${this.props} .propertyEditor=${this.propertyEditor}>
@@ -1 +1 @@
1
- {"version":3,"file":"specifics.js","sourceRoot":"","sources":["../../../../src/property-panel/specifics/specifics.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,+BAA+B,CAAA;AAEtC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAE5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE5E,MAAM,OAAO,gBAAiB,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAArE;;QAiB8B,UAAK,GAAiB,IAAI,CAAA;QAC3B,aAAQ,GAAgB,EAAE,CAAA;QAC1B,UAAK,GAAU,EAAE,CAAA;QACjB,mBAAc,GAAU,EAAE,CAAA;QAE7C,uBAAkB,GAAQ,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAyCnE,CAAC;IAvCC,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QAEzB,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;IACnE,CAAC;IAED,oBAAoB;QAClB,KAAK,CAAC,oBAAoB,EAAE,CAAA;QAE5B,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;IACtE,CAAC;IACD,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,6BAA6B,EAAE,yBAAyB;SACzD,CAAA;IACH,CAAC;IACD,MAAM;;QACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,OAAO,IAAI,CAAA;;WAEJ,OAAO,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,IAAI,EAAE,CAAC,wBAAwB,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,0CAAE,IAAI;;;4CAGjD,KAAK,WAAW,IAAI,CAAC,KAAK,oBAAoB,IAAI,CAAC,cAAc;;KAExG,CAAA;IACH,CAAC;IAEO,eAAe,CAAC,CAAc;QACpC,CAAC,CAAC,eAAe,EAAE,CAAA;QAEnB,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAA;QAE3B,IAAI,CAAC,KAAM,CAAC,cAAc,CAAC,GAAG,EAAE;YAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QACpC,CAAC,CAAC,CAAA;IACJ,CAAC;;AA7DM,uBAAM,GAAG;IACd,kBAAkB;IAClB,GAAG,CAAA;;;;;;;;;;KAUF;CACF,AAbY,CAaZ;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAW;AACV;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAA2B;AAC3B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;kDAA2B;AAC1B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;+CAAkB;AACjB;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;wDAA2B","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/help/ox-help-icon.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { i18next } from '@operato/i18n'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\n\nimport { SpecificPropertiesBuilder } from './specific-properties-builder.js'\n\nexport class PropertySpecific extends ScopedElementsMixin(LitElement) {\n static styles = [\n PropertyGridStyles,\n css`\n label {\n display: flex;\n margin: 10px;\n text-align: right;\n font: bold 14px var(--theme-font);\n color: var(--md-sys-color-on-primary-container);\n text-transform: capitalize;\n align-items: center;\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: Object }) scene: Scene | null = null\n @property({ type: Array }) selected: Component[] = []\n @property({ type: Array }) props: any[] = []\n @property({ type: Array }) propertyEditor: any[] = []\n\n private boundINeedSelected: any = this.onINeedSelected.bind(this)\n\n connectedCallback() {\n super.connectedCallback()\n\n this.addEventListener('i-need-selected', this.boundINeedSelected)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.removeEventListener('i-need-selected', this.boundINeedSelected)\n }\n static get scopedElements() {\n return {\n 'specific-properties-builder': SpecificPropertiesBuilder\n }\n }\n render() {\n const selected = this.selected && this.selected[0]\n const value = this.value || {}\n\n return html`\n <label\n >${i18next.t(`component.${value.type}`)}<ox-help-icon .topic=${selected?.nature?.help}></ox-help-icon\n ></label>\n\n <specific-properties-builder .value=${value} .props=${this.props} .propertyEditor=${this.propertyEditor}>\n </specific-properties-builder>\n `\n }\n\n private onINeedSelected(e: CustomEvent) {\n e.stopPropagation()\n\n var { callback } = e.detail\n\n this.scene!.undoableChange(() => {\n callback.call(null, this.selected)\n })\n }\n}\n"]}
1
+ {"version":3,"file":"specifics.js","sourceRoot":"","sources":["../../../../src/property-panel/specifics/specifics.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,OAAO,+BAA+B,CAAA;AACtC,OAAO,4CAA4C,CAAA;AAEnD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAE5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE5E,MAAM,OAAO,gBAAiB,SAAQ,mBAAmB,CAAC,UAAU,CAAC;IAArE;;QAiB8B,UAAK,GAAiB,IAAI,CAAA;QAC3B,aAAQ,GAAgB,EAAE,CAAA;QAC1B,UAAK,GAAU,EAAE,CAAA;QACjB,mBAAc,GAAU,EAAE,CAAA;QAE7C,uBAAkB,GAAQ,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAyCnE,CAAC;IAvCC,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QAEzB,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;IACnE,CAAC;IAED,oBAAoB;QAClB,KAAK,CAAC,oBAAoB,EAAE,CAAA;QAE5B,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAA;IACtE,CAAC;IACD,MAAM,KAAK,cAAc;QACvB,OAAO;YACL,6BAA6B,EAAE,yBAAyB;SACzD,CAAA;IACH,CAAC;IACD,MAAM;;QACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,OAAO,IAAI,CAAA;;WAEJ,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,wBAAwB,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,0CAAE,IAAI;;;4CAGnG,KAAK,WAAW,IAAI,CAAC,KAAK,oBAAoB,IAAI,CAAC,cAAc;;KAExG,CAAA;IACH,CAAC;IAEO,eAAe,CAAC,CAAc;QACpC,CAAC,CAAC,eAAe,EAAE,CAAA;QAEnB,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAA;QAE3B,IAAI,CAAC,KAAM,CAAC,cAAc,CAAC,GAAG,EAAE;YAC9B,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QACpC,CAAC,CAAC,CAAA;IACJ,CAAC;;AA7DM,uBAAM,GAAG;IACd,kBAAkB;IAClB,GAAG,CAAA;;;;;;;;;;KAUF;CACF,AAbY,CAaZ;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAW;AACV;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAA2B;AAC3B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;kDAA2B;AAC1B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;+CAAkB;AACjB;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;wDAA2B","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/help/ox-help-icon.js'\nimport '../shapes/ox-placeholder-convert-editor.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component, Scene } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\n\nimport { i18next } from '@operato/i18n'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\n\nimport { SpecificPropertiesBuilder } from './specific-properties-builder.js'\n\nexport class PropertySpecific extends ScopedElementsMixin(LitElement) {\n static styles = [\n PropertyGridStyles,\n css`\n label {\n display: flex;\n margin: 10px;\n text-align: right;\n font: bold 14px var(--theme-font);\n color: var(--md-sys-color-on-primary-container);\n text-transform: capitalize;\n align-items: center;\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: Object }) scene: Scene | null = null\n @property({ type: Array }) selected: Component[] = []\n @property({ type: Array }) props: any[] = []\n @property({ type: Array }) propertyEditor: any[] = []\n\n private boundINeedSelected: any = this.onINeedSelected.bind(this)\n\n connectedCallback() {\n super.connectedCallback()\n\n this.addEventListener('i-need-selected', this.boundINeedSelected)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this.removeEventListener('i-need-selected', this.boundINeedSelected)\n }\n static get scopedElements() {\n return {\n 'specific-properties-builder': SpecificPropertiesBuilder\n }\n }\n render() {\n const selected = this.selected && this.selected[0]\n const value = this.value || {}\n\n return html`\n <label\n >${value.type ? i18next.t(`component.${value.type}`) : i18next.t('label.mixed-selection')}<ox-help-icon .topic=${selected?.nature?.help}></ox-help-icon\n ></label>\n\n <specific-properties-builder .value=${value} .props=${this.props} .propertyEditor=${this.propertyEditor}>\n </specific-properties-builder>\n `\n }\n\n private onINeedSelected(e: CustomEvent) {\n e.stopPropagation()\n\n var { callback } = e.detail\n\n this.scene!.undoableChange(() => {\n callback.call(null, this.selected)\n })\n }\n}\n"]}
@@ -135,7 +135,14 @@ let PropertyMaterial3d = class PropertyMaterial3d extends LitElement {
135
135
  });
136
136
  }
137
137
  _onRange(key, e) {
138
- this._dispatch({ ...this.value, [key]: parseFloat(e.target.value) });
138
+ // Range inputs always carry a finite number, but parseFloat('') is NaN
139
+ // — be defensive in case a parent rebinds the input mid-edit and the
140
+ // value is briefly empty. NaN material props (e.g. metalness/roughness)
141
+ // would surface as console warnings from three.js.
142
+ const n = parseFloat(e.target.value);
143
+ if (!Number.isFinite(n))
144
+ return;
145
+ this._dispatch({ ...this.value, [key]: n });
139
146
  }
140
147
  _onSideChange(e) {
141
148
  this._dispatch({ ...this.value, side: e.target.value });
@@ -1 +1 @@
1
- {"version":3,"file":"property-material3d.js","sourceRoot":"","sources":["../../../../src/property-panel/threed/property-material3d.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\n\ninterface Material3DValue {\n preset?: string\n metalness?: number\n roughness?: number\n opacity?: number\n envMapIntensity?: number\n side?: string\n castShadow?: boolean\n receiveShadow?: boolean\n [key: string]: unknown\n}\n\nconst PRESETS: Record<string, { metalness: number; roughness: number; opacity?: number; envMapIntensity?: number }> = {\n default: { metalness: 0, roughness: 0.4 },\n metal: { metalness: 1.0, roughness: 0.3, envMapIntensity: 1.0 },\n glass: { metalness: 0, roughness: 0.1, opacity: 0.3, envMapIntensity: 1.5 },\n plastic: { metalness: 0, roughness: 0.4 },\n wood: { metalness: 0, roughness: 0.8, envMapIntensity: 0.3 },\n ceramic: { metalness: 0.1, roughness: 0.2, envMapIntensity: 0.3 },\n rubber: { metalness: 0, roughness: 0.9, envMapIntensity: 0.3 }\n}\n\nconst PRESET_NAMES = Object.keys(PRESETS)\n\nfunction resolve(m?: Material3DValue) {\n const preset = PRESETS[m?.preset ?? 'default'] ?? PRESETS.default\n return {\n metalness: m?.metalness ?? preset.metalness,\n roughness: m?.roughness ?? preset.roughness,\n opacity: m?.opacity ?? preset.opacity ?? 1,\n envMapIntensity: m?.envMapIntensity ?? preset.envMapIntensity ?? 0.5,\n side: m?.side ?? 'double',\n castShadow: m?.castShadow ?? true,\n receiveShadow: m?.receiveShadow ?? false\n }\n}\n\n@customElement('property-material3d')\nexport class PropertyMaterial3d extends LitElement {\n static styles = [\n PropertyGridStyles,\n css`\n .range-with-value {\n grid-column: 9 / -1;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .range-with-value input[type='range'] {\n flex: 1;\n border: none;\n background: transparent;\n padding: 0;\n }\n\n .range-with-value span {\n min-width: 2.5em;\n text-align: right;\n font-size: 11px;\n color: var(--md-sys-color-on-secondary-container);\n }\n `\n ]\n\n @property({ type: Object }) value: Material3DValue = {}\n @property({ type: String }) legend: string = 'Material 3D'\n\n render() {\n const r = resolve(this.value)\n const preset = this.value?.preset ?? 'default'\n\n return html`\n <fieldset>\n <legend>${this.legend}</legend>\n <div class=\"property-grid\">\n <label>Preset</label>\n <select @change=${this._onPresetChange}>\n ${PRESET_NAMES.map(name => html`<option value=${name} ?selected=${preset === name}>${name}</option>`)}\n </select>\n\n <label>Metalness</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n .value=${String(r.metalness)}\n @change=${(e: Event) => this._onRange('metalness', e)}\n />\n <span>${r.metalness.toFixed(2)}</span>\n </div>\n\n <label>Roughness</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n .value=${String(r.roughness)}\n @change=${(e: Event) => this._onRange('roughness', e)}\n />\n <span>${r.roughness.toFixed(2)}</span>\n </div>\n\n <label>Opacity</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n .value=${String(r.opacity)}\n @change=${(e: Event) => this._onRange('opacity', e)}\n />\n <span>${r.opacity.toFixed(2)}</span>\n </div>\n\n <label>Env Map</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"3\"\n step=\"0.1\"\n .value=${String(r.envMapIntensity)}\n @change=${(e: Event) => this._onRange('envMapIntensity', e)}\n />\n <span>${r.envMapIntensity.toFixed(1)}</span>\n </div>\n\n <label>Side</label>\n <select @change=${this._onSideChange}>\n ${['double', 'front', 'back'].map(\n s => html`<option value=${s} ?selected=${r.side === s}>${s}</option>`\n )}\n </select>\n\n <input\n id=\"cb-cast\"\n type=\"checkbox\"\n .checked=${r.castShadow}\n @change=${(e: Event) => this._onCheck('castShadow', e)}\n />\n <label for=\"cb-cast\">Cast Shadow</label>\n\n <input\n id=\"cb-recv\"\n type=\"checkbox\"\n .checked=${r.receiveShadow}\n @change=${(e: Event) => this._onCheck('receiveShadow', e)}\n />\n <label for=\"cb-recv\">Receive Shadow</label>\n </div>\n </fieldset>\n `\n }\n\n private _onPresetChange(e: Event) {\n const preset = (e.target as HTMLSelectElement).value\n // Preset 변경 시 PBR 값을 리셋하고 프리셋 기본값 사용 (side, shadow는 유지)\n this._dispatch({\n preset,\n side: this.value?.side,\n castShadow: this.value?.castShadow,\n receiveShadow: this.value?.receiveShadow\n })\n }\n\n private _onRange(key: string, e: Event) {\n this._dispatch({ ...this.value, [key]: parseFloat((e.target as HTMLInputElement).value) })\n }\n\n private _onSideChange(e: Event) {\n this._dispatch({ ...this.value, side: (e.target as HTMLSelectElement).value })\n }\n\n private _onCheck(key: string, e: Event) {\n this._dispatch({ ...this.value, [key]: (e.target as HTMLInputElement).checked })\n }\n\n private _dispatch(material3d: Material3DValue) {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: { material3d }\n })\n )\n }\n}\n"]}
1
+ {"version":3,"file":"property-material3d.js","sourceRoot":"","sources":["../../../../src/property-panel/threed/property-material3d.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\n\ninterface Material3DValue {\n preset?: string\n metalness?: number\n roughness?: number\n opacity?: number\n envMapIntensity?: number\n side?: string\n castShadow?: boolean\n receiveShadow?: boolean\n [key: string]: unknown\n}\n\nconst PRESETS: Record<string, { metalness: number; roughness: number; opacity?: number; envMapIntensity?: number }> = {\n default: { metalness: 0, roughness: 0.4 },\n metal: { metalness: 1.0, roughness: 0.3, envMapIntensity: 1.0 },\n glass: { metalness: 0, roughness: 0.1, opacity: 0.3, envMapIntensity: 1.5 },\n plastic: { metalness: 0, roughness: 0.4 },\n wood: { metalness: 0, roughness: 0.8, envMapIntensity: 0.3 },\n ceramic: { metalness: 0.1, roughness: 0.2, envMapIntensity: 0.3 },\n rubber: { metalness: 0, roughness: 0.9, envMapIntensity: 0.3 }\n}\n\nconst PRESET_NAMES = Object.keys(PRESETS)\n\nfunction resolve(m?: Material3DValue) {\n const preset = PRESETS[m?.preset ?? 'default'] ?? PRESETS.default\n return {\n metalness: m?.metalness ?? preset.metalness,\n roughness: m?.roughness ?? preset.roughness,\n opacity: m?.opacity ?? preset.opacity ?? 1,\n envMapIntensity: m?.envMapIntensity ?? preset.envMapIntensity ?? 0.5,\n side: m?.side ?? 'double',\n castShadow: m?.castShadow ?? true,\n receiveShadow: m?.receiveShadow ?? false\n }\n}\n\n@customElement('property-material3d')\nexport class PropertyMaterial3d extends LitElement {\n static styles = [\n PropertyGridStyles,\n css`\n .range-with-value {\n grid-column: 9 / -1;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .range-with-value input[type='range'] {\n flex: 1;\n border: none;\n background: transparent;\n padding: 0;\n }\n\n .range-with-value span {\n min-width: 2.5em;\n text-align: right;\n font-size: 11px;\n color: var(--md-sys-color-on-secondary-container);\n }\n `\n ]\n\n @property({ type: Object }) value: Material3DValue = {}\n @property({ type: String }) legend: string = 'Material 3D'\n\n render() {\n const r = resolve(this.value)\n const preset = this.value?.preset ?? 'default'\n\n return html`\n <fieldset>\n <legend>${this.legend}</legend>\n <div class=\"property-grid\">\n <label>Preset</label>\n <select @change=${this._onPresetChange}>\n ${PRESET_NAMES.map(name => html`<option value=${name} ?selected=${preset === name}>${name}</option>`)}\n </select>\n\n <label>Metalness</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n .value=${String(r.metalness)}\n @change=${(e: Event) => this._onRange('metalness', e)}\n />\n <span>${r.metalness.toFixed(2)}</span>\n </div>\n\n <label>Roughness</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n .value=${String(r.roughness)}\n @change=${(e: Event) => this._onRange('roughness', e)}\n />\n <span>${r.roughness.toFixed(2)}</span>\n </div>\n\n <label>Opacity</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.05\"\n .value=${String(r.opacity)}\n @change=${(e: Event) => this._onRange('opacity', e)}\n />\n <span>${r.opacity.toFixed(2)}</span>\n </div>\n\n <label>Env Map</label>\n <div class=\"range-with-value\">\n <input\n type=\"range\"\n min=\"0\"\n max=\"3\"\n step=\"0.1\"\n .value=${String(r.envMapIntensity)}\n @change=${(e: Event) => this._onRange('envMapIntensity', e)}\n />\n <span>${r.envMapIntensity.toFixed(1)}</span>\n </div>\n\n <label>Side</label>\n <select @change=${this._onSideChange}>\n ${['double', 'front', 'back'].map(\n s => html`<option value=${s} ?selected=${r.side === s}>${s}</option>`\n )}\n </select>\n\n <input\n id=\"cb-cast\"\n type=\"checkbox\"\n .checked=${r.castShadow}\n @change=${(e: Event) => this._onCheck('castShadow', e)}\n />\n <label for=\"cb-cast\">Cast Shadow</label>\n\n <input\n id=\"cb-recv\"\n type=\"checkbox\"\n .checked=${r.receiveShadow}\n @change=${(e: Event) => this._onCheck('receiveShadow', e)}\n />\n <label for=\"cb-recv\">Receive Shadow</label>\n </div>\n </fieldset>\n `\n }\n\n private _onPresetChange(e: Event) {\n const preset = (e.target as HTMLSelectElement).value\n // Preset 변경 시 PBR 값을 리셋하고 프리셋 기본값 사용 (side, shadow는 유지)\n this._dispatch({\n preset,\n side: this.value?.side,\n castShadow: this.value?.castShadow,\n receiveShadow: this.value?.receiveShadow\n })\n }\n\n private _onRange(key: string, e: Event) {\n // Range inputs always carry a finite number, but parseFloat('') is NaN\n // — be defensive in case a parent rebinds the input mid-edit and the\n // value is briefly empty. NaN material props (e.g. metalness/roughness)\n // would surface as console warnings from three.js.\n const n = parseFloat((e.target as HTMLInputElement).value)\n if (!Number.isFinite(n)) return\n this._dispatch({ ...this.value, [key]: n })\n }\n\n private _onSideChange(e: Event) {\n this._dispatch({ ...this.value, side: (e.target as HTMLSelectElement).value })\n }\n\n private _onCheck(key: string, e: Event) {\n this._dispatch({ ...this.value, [key]: (e.target as HTMLInputElement).checked })\n }\n\n private _dispatch(material3d: Material3DValue) {\n this.dispatchEvent(\n new CustomEvent('property-change', {\n bubbles: true,\n composed: true,\n detail: { material3d }\n })\n )\n }\n}\n"]}
@@ -2,6 +2,7 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
  import '@operato/input/ox-input-color.js';
5
+ import '@operato/i18n/ox-i18n.js';
5
6
  import './property-material3d.js';
6
7
  import { Properties, Scene } from '@hatiolab/things-scene';
7
8
  import { AbstractProperty } from '../abstract-property.js';
@@ -14,18 +15,45 @@ export declare class PropertyScene3D extends AbstractProperty {
14
15
  value?: Properties;
15
16
  scene: Scene | null;
16
17
  render(): import("lit-html").TemplateResult<1>;
18
+ /**
19
+ * Camera 초기 설정 — Initial View(뷰 프리셋), FOV/Near/Far, 현재 카메라 저장 버튼.
20
+ * 사용자가 씬을 3D로 돌려본 후 "이 각도가 마음에 든다" 싶으면
21
+ * Save Current View로 현재 viewport의 position을 모델에 기록 → 다음 로드 시 같은 각도로 시작.
22
+ */
23
+ private _renderCamera;
24
+ /**
25
+ * 현재 3D viewport의 카메라 상태를 모델에 저장한다.
26
+ * scene의 getCameraState를 호출하여 view/cameraX/cameraY/cameraZ를 얻어 property-change로 전파.
27
+ */
28
+ private _onSaveCameraView;
29
+ /**
30
+ * Scene placement 모드 선택 — zPos 해석과 볼륨 origin 방향을 씬 전체에 일관 적용.
31
+ * floor : zPos=바닥 높이, 볼륨이 위로 쌓임 (공장/창고/건축)
32
+ * space : zPos=볼륨 중심 Y, 바닥 개념 없음 (우주/추상/전시)
33
+ * inverted: zPos=천장, 볼륨이 아래로 매달림 (천장 설비, 베타)
34
+ */
35
+ private _renderPlacement;
17
36
  private _renderMode;
18
- private _renderBookmarks;
19
- private _longPressTimer?;
20
- private _pressTarget?;
21
- private _onBookmarkMouseDown;
22
- private _onBookmarkMouseUp;
23
- private _bookmarkAction;
24
37
  private _renderRenderer;
38
+ /**
39
+ * Environment 드롭다운 — 씬의 공간적 맥락을 정의.
40
+ * 선택 시 sky 값과 함께 ENVIRONMENT_DEFAULTS의 기본 조명까지 한 번에 적용한다.
41
+ * "원클릭 전체 look" — 사용자가 원하면 Light Mood/원자 컨트롤로 위에 얹어 조정.
42
+ */
25
43
  private _renderSky;
44
+ /**
45
+ * Environment 선택 핸들러 — sky 필드만 바꾸는 게 아니라 ENVIRONMENT_DEFAULTS에
46
+ * 정의된 hemi/dir 기본 조명까지 한 번의 property-change로 함께 적용한다.
47
+ */
48
+ private _onEnvironmentChange;
26
49
  private _renderHemisphereLight;
27
50
  private _renderKeyLight;
51
+ /**
52
+ * Light Mood — Environment가 설정한 기본 조명 위에 얹는 분위기 오버라이드.
53
+ * sky는 건드리지 않고 hemi/dir 값만 적용. Environment와 독립적으로 조합 가능.
54
+ */
28
55
  private _renderLightingPresets;
56
+ private _onPresetChange;
29
57
  private _renderFloor;
30
58
  private _applyLightingPreset;
31
59
  private _onFloorMaterialChange;