@operato/property-panel 10.0.0-beta.5 → 10.0.0-beta.50

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 (45) hide show
  1. package/CHANGELOG.md +318 -0
  2. package/dist/src/ox-property-panel.d.ts +7 -0
  3. package/dist/src/ox-property-panel.js +62 -34
  4. package/dist/src/ox-property-panel.js.map +1 -1
  5. package/dist/src/property-panel/abstract-property.js +11 -2
  6. package/dist/src/property-panel/abstract-property.js.map +1 -1
  7. package/dist/src/property-panel/data-binding/data-binding-mapper.js +11 -3
  8. package/dist/src/property-panel/data-binding/data-binding-mapper.js.map +1 -1
  9. package/dist/src/property-panel/data-binding/data-binding-popup.d.ts +63 -0
  10. package/dist/src/property-panel/data-binding/data-binding-popup.js +1414 -0
  11. package/dist/src/property-panel/data-binding/data-binding-popup.js.map +1 -0
  12. package/dist/src/property-panel/data-binding/data-binding.d.ts +1 -0
  13. package/dist/src/property-panel/data-binding/data-binding.js +33 -2
  14. package/dist/src/property-panel/data-binding/data-binding.js.map +1 -1
  15. package/dist/src/property-panel/effects/property-event-tap.js +21 -1
  16. package/dist/src/property-panel/effects/property-event-tap.js.map +1 -1
  17. package/dist/src/property-panel/effects/property-shadow.js +14 -5
  18. package/dist/src/property-panel/effects/property-shadow.js.map +1 -1
  19. package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.d.ts +20 -0
  20. package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.js +125 -0
  21. package/dist/src/property-panel/shapes/ox-placeholder-convert-editor.js.map +1 -0
  22. package/dist/src/property-panel/shapes/placeholder-convert.d.ts +34 -0
  23. package/dist/src/property-panel/shapes/placeholder-convert.js +117 -0
  24. package/dist/src/property-panel/shapes/placeholder-convert.js.map +1 -0
  25. package/dist/src/property-panel/shapes/shapes.js +28 -10
  26. package/dist/src/property-panel/shapes/shapes.js.map +1 -1
  27. package/dist/src/property-panel/specifics/specifics.d.ts +1 -0
  28. package/dist/src/property-panel/specifics/specifics.js +2 -1
  29. package/dist/src/property-panel/specifics/specifics.js.map +1 -1
  30. package/dist/src/property-panel/styles/styles.js +2 -0
  31. package/dist/src/property-panel/styles/styles.js.map +1 -1
  32. package/dist/src/property-panel/threed/property-material3d.js +8 -1
  33. package/dist/src/property-panel/threed/property-material3d.js.map +1 -1
  34. package/dist/src/property-panel/threed/property-scene3d.d.ts +34 -7
  35. package/dist/src/property-panel/threed/property-scene3d.js +329 -246
  36. package/dist/src/property-panel/threed/property-scene3d.js.map +1 -1
  37. package/dist/src/property-panel/threed/threed.js +8 -0
  38. package/dist/src/property-panel/threed/threed.js.map +1 -1
  39. package/dist/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +6 -5
  41. package/translations/en.json +27 -1
  42. package/translations/ja.json +27 -1
  43. package/translations/ko.json +27 -1
  44. package/translations/ms.json +27 -1
  45. package/translations/zh.json +27 -1
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/property-panel/styles/styles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/help/ox-title-with-help.js'\nimport '@operato/popup/ox-popup-list.js'\nimport '@operato/input/ox-input-range.js'\nimport '@operato/input/ox-input-color.js'\nimport '@operato/input/ox-input-fill-style.js'\nimport '@operato/input/ox-select.js'\nimport '@operato/font/ox-font-selector.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, nothing } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component } from '@hatiolab/things-scene'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\nimport { LineStyles } from '@operato/styles/line-styles.js'\n\nimport { AbstractProperty } from '../abstract-property.js'\n\nexport class PropertyStyles extends AbstractProperty {\n static styles = [\n PropertyGridStyles,\n LineStyles,\n css`\n ox-input-range {\n width: 100%;\n }\n\n .btn-group {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-medium, 8px);\n }\n\n .btn-group * {\n width: 30px;\n min-width: initial;\n border-radius: 0;\n border-bottom: 2px solid #fff;\n }\n\n .btn-group [active] {\n border-bottom: 2px solid #f2471c;\n }\n `\n ]\n\n @property({ type: Object }) value: any = {}\n @property({ type: Array }) selected: Component[] = []\n @property({ type: Array }) fonts: any[] = []\n @property({ type: Boolean, attribute: 'is-line' }) isLine: boolean = false\n\n connectedCallback() {\n super.connectedCallback()\n\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n }\n\n onButtonGroupClick(e: Event) {\n const target = e.target as HTMLElement\n\n if (target.hasAttribute('value-key')) {\n target.toggleAttribute('active')\n\n target.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true\n })\n )\n }\n }\n\n render() {\n var {\n alpha = 1,\n fontFamily,\n fontSize,\n lineHeight,\n fontColor,\n letterSpacing,\n bold,\n italic,\n fillStyle,\n lineWidth,\n strokeStyle,\n lineDash = 'solid',\n lineCap,\n lineJoin,\n begin = 'none',\n beginSize = 'size1',\n end = 'none',\n endSize = 'size1'\n } = this.value || {}\n\n return html`\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/styles/opacity\" msgid=\"label.opacity\">opacity</ox-title-with-help>\n </legend>\n <ox-input-range min=\"0\" max=\"1\" step=\"0.1\" value-key=\"alpha\" .value=${alpha} editable> </ox-input-range>\n </fieldset>\n\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/styles/text-style\" msgid=\"label.text-style\"\n >text style</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label>\n <ox-i18n msgid=\"label.font-family\">Font Family</ox-i18n>\n </label>\n\n <ox-font-selector class=\"custom-editor\" value-key=\"fontFamily\" .value=${fontFamily}></ox-font-selector>\n\n <label class=\"onethird-label icon-only-label\"><md-icon>format_size</md-icon></label>\n <input type=\"number\" value-key=\"fontSize\" .value=${fontSize} class=\"onethird-editor\" />\n\n <label class=\"onethird-label icon-only-label\"><md-icon>format_line_spacing</md-icon></label>\n <input type=\"number\" value-key=\"lineHeight\" .value=${lineHeight} class=\"onethird-editor\" />\n\n <label class=\"onethird-label icon-only-label\"><md-icon>format_letter_spacing</md-icon></label>\n <input type=\"number\" value-key=\"letterSpacing\" .value=${letterSpacing} class=\"onethird-editor\" />\n\n <label class=\"twothird-label icon-only-label\"><md-icon>format_color_text</md-icon></label>\n <ox-input-color value-key=\"fontColor\" .value=${fontColor} class=\"twothird-editor\"> </ox-input-color>\n\n <div class=\"onethird-full btn-group\" @click=${this.onButtonGroupClick}>\n <md-icon value-key=\"bold\" ?active=${bold}>format_bold</md-icon>\n <md-icon value-key=\"italic\" ?active=${italic}>format_italic</md-icon>\n </div>\n </div>\n </fieldset>\n\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/styles/fill-style\" msgid=\"label.fill-style\"\n >fill style</ox-title-with-help\n >\n </legend>\n\n <ox-input-fill-style value-key=\"fillStyle\" .value=${fillStyle}> </ox-input-fill-style>\n </fieldset>\n\n <fieldset>\n <legend>\n <ox-title-with-help msgid=\"label.line-style\" topic=\"board-modeller/styles/line-style\"></ox-title-with-help>\n </legend>\n\n <div class=\"property-grid\">\n <label class=\"half-label icon-only-label\"><md-icon>line_weight</md-icon></label>\n <input type=\"number\" value-key=\"lineWidth\" .value=${lineWidth} class=\"half-editor\" />\n\n <label class=\"half-label icon-only-label\"><md-icon>border_color</md-icon></label>\n <ox-input-color value-key=\"strokeStyle\" .value=${strokeStyle} class=\"half-editor\"> </ox-input-color>\n\n <label>\n <ox-i18n msgid=\"label.line-type\">line type</ox-i18n>\n </label>\n <ox-select value-key=\"lineDash\" .value=${lineDash} class=\"custom-editor\">\n <div class=\"line-type ${lineDash}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"line-type solid\" value=\"solid\" option></div>\n <div class=\"line-type round-dot\" value=\"round-dot\" option></div>\n <div class=\"line-type square-dot\" value=\"square-dot\" option></div>\n <div class=\"line-type dash\" value=\"dash\" option></div>\n <div class=\"line-type dash-dot\" value=\"dash-dot\" option></div>\n <div class=\"line-type long-dash\" value=\"long-dash\" option></div>\n <div class=\"line-type long-dash-dot\" value=\"long-dash-dot\" option></div>\n <div class=\"line-type long-dash-dot-dot\" value=\"long-dash-dot-dot\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.cap-type\">cap type</ox-i18n>\n </label>\n <select value-key=\"lineCap\" .value=${lineCap}>\n <option value=\"butt\"><ox-i18n msgid=\"label.square\">square</ox-i18n></option>\n <option value=\"round\"><ox-i18n msgid=\"label.round\">round</ox-i18n></option>\n </select>\n\n <label>\n <ox-i18n msgid=\"label.join-type\">join type</ox-i18n>\n </label>\n <select value-key=\"lineJoin\" .value=${lineJoin}>\n <option value=\"miter\"><ox-i18n msgid=\"label.miter\">miter</ox-i18n></option>\n <option value=\"round\"><ox-i18n msgid=\"label.round\">round</ox-i18n></option>\n <option value=\"bevel\"><ox-i18n msgid=\"label.bevel\">bevel</ox-i18n></option>\n </select>\n\n ${this.isLine\n ? html`\n <label>\n <ox-i18n msgid=\"label.begin-type\">begin type</ox-i18n>\n </label>\n <ox-select value-key=\"begin\" .value=${begin} class=\"custom-editor\">\n <div class=\"arrow-type ${begin ? `begin-${begin}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type begin-none\" value=\"none\" option></div>\n <div class=\"arrow-type begin-arrow\" value=\"arrow\" option></div>\n <div class=\"arrow-type begin-open-arrow\" value=\"open-arrow\" option></div>\n <div class=\"arrow-type begin-sharp-arrow\" value=\"sharp-arrow\" option></div>\n <div class=\"arrow-type begin-diamond\" value=\"diamond\" option></div>\n <div class=\"arrow-type begin-oval\" value=\"oval\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.begin-size\">begin size</ox-i18n>\n </label>\n <ox-select value-key=\"beginSize\" .value=${beginSize} class=\"custom-editor\">\n <div class=\"arrow-type ${beginSize ? `begin-${beginSize}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type begin-size1\" value=\"size1\" option></div>\n <div class=\"arrow-type begin-size2\" value=\"size2\" option></div>\n <div class=\"arrow-type begin-size3\" value=\"size3\" option></div>\n <div class=\"arrow-type begin-size4\" value=\"size4\" option></div>\n <div class=\"arrow-type begin-size5\" value=\"size5\" option></div>\n <div class=\"arrow-type begin-size6\" value=\"size6\" option></div>\n <div class=\"arrow-type begin-size7\" value=\"size7\" option></div>\n <div class=\"arrow-type begin-size8\" value=\"size8\" option></div>\n <div class=\"arrow-type begin-size9\" value=\"size9\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.end-type\">end type</ox-i18n>\n </label>\n <ox-select value-key=\"end\" .value=${end} class=\"custom-editor\">\n <div class=\"arrow-type ${end ? `end-${end}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type end-none\" value=\"none\" option></div>\n <div class=\"arrow-type end-arrow\" value=\"arrow\" option></div>\n <div class=\"arrow-type end-open-arrow\" value=\"open-arrow\" option></div>\n <div class=\"arrow-type end-sharp-arrow\" value=\"sharp-arrow\" option></div>\n <div class=\"arrow-type end-diamond\" value=\"diamond\" option></div>\n <div class=\"arrow-type end-oval\" value=\"oval\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.end-size\">end size</ox-i18n>\n </label>\n <ox-select value-key=\"endSize\" .value=${endSize} class=\"custom-editor\">\n <div class=\"arrow-type ${endSize ? `end-${endSize}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type end-size1\" value=\"size1\" option></div>\n <div class=\"arrow-type end-size2\" value=\"size2\" option></div>\n <div class=\"arrow-type end-size3\" value=\"size3\" option></div>\n <div class=\"arrow-type end-size4\" value=\"size4\" option></div>\n <div class=\"arrow-type end-size5\" value=\"size5\" option></div>\n <div class=\"arrow-type end-size6\" value=\"size6\" option></div>\n <div class=\"arrow-type end-size7\" value=\"size7\" option></div>\n <div class=\"arrow-type end-size8\" value=\"size8\" option></div>\n <div class=\"arrow-type end-size9\" value=\"size9\" option></div>\n </ox-popup-list>\n </ox-select>\n `\n : html``}\n </div>\n </fieldset>\n `\n }\n}\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../src/property-panel/styles/styles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport '@operato/help/ox-title-with-help.js'\nimport '@operato/popup/ox-popup-list.js'\nimport '@operato/input/ox-input-range.js'\nimport '@operato/input/ox-input-color.js'\nimport '@operato/input/ox-input-fill-style.js'\nimport '@operato/input/ox-select.js'\nimport '@operato/font/ox-font-selector.js'\nimport '@operato/i18n/ox-i18n.js'\n\nimport { css, html, nothing } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { Component } from '@hatiolab/things-scene'\nimport { PropertyGridStyles } from '@operato/styles/property-grid-styles.js'\nimport { LineStyles } from '@operato/styles/line-styles.js'\n\nimport { AbstractProperty } from '../abstract-property.js'\n\nexport class PropertyStyles extends AbstractProperty {\n static styles = [\n PropertyGridStyles,\n LineStyles,\n css`\n ox-input-range {\n width: 100%;\n }\n\n .btn-group {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-medium, 8px);\n }\n\n .btn-group * {\n width: 30px;\n min-width: initial;\n border-radius: 0;\n border-bottom: 2px solid #fff;\n }\n\n .btn-group [active] {\n border-bottom: 2px solid #f2471c;\n }\n `\n ]\n\n @property({ type: Object }) value: any = {}\n @property({ type: Array }) selected: Component[] = []\n @property({ type: Array }) fonts: any[] = []\n @property({ type: Boolean, attribute: 'is-line' }) isLine: boolean = false\n\n connectedCallback() {\n super.connectedCallback()\n\n this.renderRoot.addEventListener('change', this.onValueChange.bind(this))\n }\n\n onButtonGroupClick(e: Event) {\n const target = e.target as HTMLElement\n\n if (target.hasAttribute('value-key')) {\n target.toggleAttribute('active')\n\n target.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true\n })\n )\n }\n }\n\n render() {\n var {\n alpha = 1,\n fontFamily,\n fontSize,\n lineHeight,\n fontColor,\n letterSpacing,\n bold,\n italic,\n fillStyle,\n lineWidth,\n strokeStyle,\n lineDash = 'solid',\n lineCap,\n lineJoin,\n begin = 'none',\n beginSize = 'size1',\n end = 'none',\n endSize = 'size1'\n } = this.value || {}\n\n return html`\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/styles/opacity\" msgid=\"label.opacity\">opacity</ox-title-with-help>\n </legend>\n <ox-input-range min=\"0\" max=\"1\" step=\"0.1\" value-key=\"alpha\" .value=${alpha} editable> </ox-input-range>\n </fieldset>\n\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/styles/text-style\" msgid=\"label.text-style\"\n >text style</ox-title-with-help\n >\n </legend>\n\n <div class=\"property-grid\">\n <label>\n <ox-i18n msgid=\"label.font-family\">Font Family</ox-i18n>\n </label>\n\n <ox-font-selector class=\"custom-editor\" value-key=\"fontFamily\" .value=${fontFamily}></ox-font-selector>\n\n <label class=\"onethird-label icon-only-label\"><md-icon>format_size</md-icon></label>\n <input type=\"number\" value-key=\"fontSize\" .value=${fontSize} class=\"onethird-editor\" />\n\n <label class=\"onethird-label icon-only-label\"><md-icon>format_line_spacing</md-icon></label>\n <input type=\"number\" value-key=\"lineHeight\" .value=${lineHeight} class=\"onethird-editor\" />\n\n <label class=\"onethird-label icon-only-label\"><md-icon>format_letter_spacing</md-icon></label>\n <input type=\"number\" value-key=\"letterSpacing\" .value=${letterSpacing} class=\"onethird-editor\" />\n\n <label class=\"twothird-label icon-only-label\"><md-icon>format_color_text</md-icon></label>\n <ox-input-color value-key=\"fontColor\" .value=${fontColor} class=\"twothird-editor\"> </ox-input-color>\n\n <div class=\"onethird-full btn-group\" @click=${this.onButtonGroupClick}>\n <md-icon value-key=\"bold\" ?active=${bold}>format_bold</md-icon>\n <md-icon value-key=\"italic\" ?active=${italic}>format_italic</md-icon>\n </div>\n </div>\n </fieldset>\n\n <fieldset>\n <legend>\n <ox-title-with-help topic=\"board-modeller/styles/fill-style\" msgid=\"label.fill-style\"\n >fill style</ox-title-with-help\n >\n </legend>\n\n <ox-input-fill-style value-key=\"fillStyle\" .value=${fillStyle}> </ox-input-fill-style>\n </fieldset>\n\n <fieldset>\n <legend>\n <ox-title-with-help msgid=\"label.line-style\" topic=\"board-modeller/styles/line-style\"></ox-title-with-help>\n </legend>\n\n <div class=\"property-grid\">\n <label class=\"half-label icon-only-label\"><md-icon>line_weight</md-icon></label>\n <input type=\"number\" value-key=\"lineWidth\" .value=${lineWidth} class=\"half-editor\" />\n\n <label class=\"half-label icon-only-label\"><md-icon>border_color</md-icon></label>\n <ox-input-color value-key=\"strokeStyle\" .value=${strokeStyle} class=\"half-editor\"> </ox-input-color>\n\n <label>\n <ox-i18n msgid=\"label.line-type\">line type</ox-i18n>\n </label>\n <ox-select value-key=\"lineDash\" .value=${lineDash} class=\"custom-editor\">\n <div class=\"line-type ${lineDash}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"line-type solid\" value=\"solid\" option></div>\n <div class=\"line-type round-dot\" value=\"round-dot\" option></div>\n <div class=\"line-type square-dot\" value=\"square-dot\" option></div>\n <div class=\"line-type dash\" value=\"dash\" option></div>\n <div class=\"line-type dash-dot\" value=\"dash-dot\" option></div>\n <div class=\"line-type long-dash\" value=\"long-dash\" option></div>\n <div class=\"line-type long-dash-dot\" value=\"long-dash-dot\" option></div>\n <div class=\"line-type long-dash-dot-dot\" value=\"long-dash-dot-dot\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.cap-type\">cap type</ox-i18n>\n </label>\n <select value-key=\"lineCap\" .value=${lineCap}>\n <option value=\"butt\"><ox-i18n msgid=\"label.square\">square</ox-i18n></option>\n <option value=\"round\"><ox-i18n msgid=\"label.round\">round</ox-i18n></option>\n </select>\n\n <label>\n <ox-i18n msgid=\"label.join-type\">join type</ox-i18n>\n </label>\n <select value-key=\"lineJoin\" .value=${lineJoin}>\n <option value=\"miter\"><ox-i18n msgid=\"label.miter\">miter</ox-i18n></option>\n <option value=\"round\"><ox-i18n msgid=\"label.round\">round</ox-i18n></option>\n <option value=\"bevel\"><ox-i18n msgid=\"label.bevel\">bevel</ox-i18n></option>\n </select>\n\n ${this.isLine\n ? html`\n <label>\n <ox-i18n msgid=\"label.begin-type\">begin type</ox-i18n>\n </label>\n <ox-select value-key=\"begin\" .value=${begin} class=\"custom-editor\">\n <div class=\"arrow-type ${begin ? `begin-${begin}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type begin-none\" value=\"none\" option></div>\n <div class=\"arrow-type begin-arrow\" value=\"arrow\" option></div>\n <div class=\"arrow-type begin-open-arrow\" value=\"open-arrow\" option></div>\n <div class=\"arrow-type begin-sharp-arrow\" value=\"sharp-arrow\" option></div>\n <div class=\"arrow-type begin-diamond\" value=\"diamond\" option></div>\n <div class=\"arrow-type begin-oval\" value=\"oval\" option></div>\n <div class=\"arrow-type begin-cross\" value=\"cross\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.begin-size\">begin size</ox-i18n>\n </label>\n <ox-select value-key=\"beginSize\" .value=${beginSize} class=\"custom-editor\">\n <div class=\"arrow-type ${beginSize ? `begin-${beginSize}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type begin-size1\" value=\"size1\" option></div>\n <div class=\"arrow-type begin-size2\" value=\"size2\" option></div>\n <div class=\"arrow-type begin-size3\" value=\"size3\" option></div>\n <div class=\"arrow-type begin-size4\" value=\"size4\" option></div>\n <div class=\"arrow-type begin-size5\" value=\"size5\" option></div>\n <div class=\"arrow-type begin-size6\" value=\"size6\" option></div>\n <div class=\"arrow-type begin-size7\" value=\"size7\" option></div>\n <div class=\"arrow-type begin-size8\" value=\"size8\" option></div>\n <div class=\"arrow-type begin-size9\" value=\"size9\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.end-type\">end type</ox-i18n>\n </label>\n <ox-select value-key=\"end\" .value=${end} class=\"custom-editor\">\n <div class=\"arrow-type ${end ? `end-${end}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type end-none\" value=\"none\" option></div>\n <div class=\"arrow-type end-arrow\" value=\"arrow\" option></div>\n <div class=\"arrow-type end-open-arrow\" value=\"open-arrow\" option></div>\n <div class=\"arrow-type end-sharp-arrow\" value=\"sharp-arrow\" option></div>\n <div class=\"arrow-type end-diamond\" value=\"diamond\" option></div>\n <div class=\"arrow-type end-oval\" value=\"oval\" option></div>\n <div class=\"arrow-type end-cross\" value=\"cross\" option></div>\n </ox-popup-list>\n </ox-select>\n\n <label>\n <ox-i18n msgid=\"label.end-size\">end size</ox-i18n>\n </label>\n <ox-select value-key=\"endSize\" .value=${endSize} class=\"custom-editor\">\n <div class=\"arrow-type ${endSize ? `end-${endSize}` : nothing}\" slot=\"label\"></div>\n <ox-popup-list align-left nowrap>\n <style>\n ${LineStyles.cssText}\n </style>\n <div class=\"arrow-type end-size1\" value=\"size1\" option></div>\n <div class=\"arrow-type end-size2\" value=\"size2\" option></div>\n <div class=\"arrow-type end-size3\" value=\"size3\" option></div>\n <div class=\"arrow-type end-size4\" value=\"size4\" option></div>\n <div class=\"arrow-type end-size5\" value=\"size5\" option></div>\n <div class=\"arrow-type end-size6\" value=\"size6\" option></div>\n <div class=\"arrow-type end-size7\" value=\"size7\" option></div>\n <div class=\"arrow-type end-size8\" value=\"size8\" option></div>\n <div class=\"arrow-type end-size9\" value=\"size9\" option></div>\n </ox-popup-list>\n </ox-select>\n `\n : html``}\n </div>\n </fieldset>\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,19 +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>;
17
- private _renderMode;
18
+ /**
19
+ * Camera 초기 설정 — Initial View(뷰 프리셋), FOV/Near/Far, 현재 카메라 저장 버튼.
20
+ * 사용자가 씬을 3D로 돌려본 후 "이 각도가 마음에 든다" 싶으면
21
+ * Save Current View로 현재 viewport의 position을 모델에 기록 → 다음 로드 시 같은 각도로 시작.
22
+ */
18
23
  private _renderCamera;
19
- private _renderBookmarks;
20
- private _longPressTimer?;
21
- private _pressTarget?;
22
- private _onBookmarkMouseDown;
23
- private _onBookmarkMouseUp;
24
- private _bookmarkAction;
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;
36
+ private _renderMode;
25
37
  private _renderRenderer;
38
+ /**
39
+ * Environment 드롭다운 — 씬의 공간적 맥락을 정의.
40
+ * 선택 시 sky 값과 함께 ENVIRONMENT_DEFAULTS의 기본 조명까지 한 번에 적용한다.
41
+ * "원클릭 전체 look" — 사용자가 원하면 Light Mood/원자 컨트롤로 위에 얹어 조정.
42
+ */
26
43
  private _renderSky;
44
+ /**
45
+ * Environment 선택 핸들러 — sky 필드만 바꾸는 게 아니라 ENVIRONMENT_DEFAULTS에
46
+ * 정의된 hemi/dir 기본 조명까지 한 번의 property-change로 함께 적용한다.
47
+ */
48
+ private _onEnvironmentChange;
27
49
  private _renderHemisphereLight;
28
50
  private _renderKeyLight;
51
+ /**
52
+ * Light Mood — Environment가 설정한 기본 조명 위에 얹는 분위기 오버라이드.
53
+ * sky는 건드리지 않고 hemi/dir 값만 적용. Environment와 독립적으로 조합 가능.
54
+ */
29
55
  private _renderLightingPresets;
56
+ private _onPresetChange;
30
57
  private _renderFloor;
31
58
  private _applyLightingPreset;
32
59
  private _onFloorMaterialChange;