From b9f65b2a72dc3a7fcfdb73de7114623fb20e60c6 Mon Sep 17 00:00:00 2001 From: Michael Oppitz Date: Thu, 16 Jul 2026 14:15:28 +0200 Subject: [PATCH] SS-9464: toolbar implementation --- public/blank.json | 1 + public/doc-flat.json | 535 ++++----- public/doc-nested.json | 508 ++++----- public/example-toolbar-container.json | 1011 +++++++++++++++++ src/AppBuilderRoot.tsx | 27 +- .../examples/AppBuilderStaticExamplePage.tsx | 4 +- src/pages/examples/ModelSelectPage.tsx | 4 +- src/pages/examples/ViewPage.tsx | 6 +- src/shared | 2 +- 9 files changed, 1497 insertions(+), 601 deletions(-) create mode 100644 public/example-toolbar-container.json diff --git a/public/blank.json b/public/blank.json index 48b182f2..5fb8e130 100644 --- a/public/blank.json +++ b/public/blank.json @@ -13,6 +13,7 @@ "enableFullscreenBtn3States": false, "enableZoomBtn": false, "enableHistoryButtons": false, + "enableResetButton": false, "enableHistoryMenuButton": false } } diff --git a/public/doc-flat.json b/public/doc-flat.json index 21f499b3..c258f3dd 100644 --- a/public/doc-flat.json +++ b/public/doc-flat.json @@ -207,7 +207,7 @@ "properties": { "v8ThemeSupport": { "type": "boolean", - "description": "When `true`, merges Mantine's `v8CssVariablesResolver` with AppBuilder CSS\nvariables (v8 `light` variant colors). Default in product theme: `false`." + "description": "When `true`, merges Mantine's `v8CssVariablesResolver` with AppBuilder CSS\r\nvariables (v8 `light` variant colors). Default in product theme: `false`." }, "forceColorScheme": { "type": "string", @@ -425,6 +425,10 @@ }, "ActionIconProps": { "properties": { + "color": { + "type": "string", + "description": "ActionIcon color. Use \"default\" for neutral hover (Mantine v8 parity)." + }, "variant": { "type": "string" }, @@ -814,6 +818,49 @@ } } }, + "CSSProperties": { + "type": "unknown", + "name": "CSSProperties" + }, + "MantineStyleProp": { + "type": "unknown", + "name": "MantineStyleProp" + }, + "unknown": { + "type": "unknown", + "name": "unknown" + }, + "DividerProps": { + "properties": { + "orientation": { + "type": "string", + "enum": [ + "horizontal", + "vertical" + ] + }, + "color": { + "type": "string" + } + } + }, + "TransitionProps": { + "properties": { + "transition": { + "type": "unknown", + "name": "MantineTransitionName" + }, + "duration": { + "type": "number" + }, + "timingFunction": { + "type": "string" + }, + "keepMounted": { + "type": "boolean" + } + } + }, "HTMLCanvasElement": { "type": "unknown", "name": "HTMLCanvasElement" @@ -862,71 +909,54 @@ "type": "unknown", "name": "object" }, - "CSSProperties": { - "type": "unknown", - "name": "CSSProperties" - }, - "MantineStyleProp": { - "type": "unknown", - "name": "MantineStyleProp" - }, - "ViewportOverlayWrapperProps_and_Partial_OverlayStyleProps": { + "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined": { "properties": { - "children": { - "type": "unknown", - "name": "ReactNode" + "base": { + "$ref": "#/definitions/T", + "description": "" }, - "position": { - "type": "unknown", - "name": "ResponsiveValueType" + "xs": { + "$ref": "#/definitions/T", + "description": "" }, - "offset": { - "type": "string" + "sm": { + "$ref": "#/definitions/T", + "description": "" }, - "offsetX": { - "type": "string" + "md": { + "$ref": "#/definitions/T", + "description": "" }, - "offsetY": { - "type": "string" + "lg": { + "$ref": "#/definitions/T", + "description": "" }, - "className": { - "type": "string" + "xl": { + "$ref": "#/definitions/T", + "description": "" } } }, - "DividerProps": { - "properties": { - "orientation": { - "type": "string", - "enum": [ - "horizontal", - "vertical" - ] - }, - "color": { - "type": "string" - } - } + "T": { + "type": "unknown", + "name": "T" }, - "TransitionProps": { - "properties": { - "transition": { - "type": "unknown", - "name": "MantineTransitionName" - }, - "duration": { - "type": "number" - }, - "timingFunction": { - "type": "string" + "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined_or_T": { + "oneOf": [ + { + "$ref": "#/definitions/base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined" }, - "keepMounted": { - "type": "boolean" + { + "$ref": "#/definitions/T" } - } + ] }, "MantineActionIconProps_and_Unknown": { "properties": { + "color": { + "type": "string", + "description": "ActionIcon color. Use \"default\" for neutral hover (Mantine v8 parity)." + }, "variant": { "type": "string" }, @@ -967,65 +997,6 @@ } } }, - "MenuProps": { - "properties": { - "shadow": { - "type": "string" - }, - "position": { - "$ref": "#/definitions/MantineFloatingPosition" - } - } - }, - "MenuDropdownProps": { - "properties": { - "style": { - "$ref": "#/definitions/MantineCssStyleRecord" - } - } - }, - "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined": { - "properties": { - "base": { - "$ref": "#/definitions/T", - "description": "" - }, - "xs": { - "$ref": "#/definitions/T", - "description": "" - }, - "sm": { - "$ref": "#/definitions/T", - "description": "" - }, - "md": { - "$ref": "#/definitions/T", - "description": "" - }, - "lg": { - "$ref": "#/definitions/T", - "description": "" - }, - "xl": { - "$ref": "#/definitions/T", - "description": "" - } - } - }, - "T": { - "type": "unknown", - "name": "T" - }, - "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined_or_T": { - "oneOf": [ - { - "$ref": "#/definitions/base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined" - }, - { - "$ref": "#/definitions/T" - } - ] - }, "number_or_boolean": { "oneOf": [ { @@ -1197,13 +1168,6 @@ } } }, - "fontWeights": { - "properties": { - "[string]": { - "type": "string" - } - } - }, "radius": { "properties": { "[string]": { @@ -1233,8 +1197,12 @@ } }, "headings": { - "type": "unknown", - "name": "AppBuilderThemeOtherProps" + "properties": { + "[string]": { + "type": "unknown", + "name": "unknown" + } + } }, "defaultGradient": { "properties": { @@ -2127,6 +2095,13 @@ "type": "boolean" } }, + { + "name": "hideDefaultToolbar", + "description": "Whether to hide the default viewport toolbar. Defaults to false.", + "type": { + "type": "boolean" + } + }, { "name": "loadPlatformSettingsFromViewer", "description": "In case we cannot connect to the platform, load settings from the viewer, if they were stored there. (default: undefined)", @@ -2429,335 +2404,282 @@ ] }, { - "configPath": "themeOverrides.components.ViewportComponent.defaultProps", - "name": "ViewportComponent", - "summary": "Props for the ShapeDiver viewport (`ViewportComponent`), including theme defaults via `useProps(\"ViewportComponent\", …)`.", - "source": "src/shared/entities/viewport/config/viewport.ts", + "configPath": "themeOverrides.components.ViewportIcons.defaultProps", + "name": "ViewportIcons", + "summary": "Optional styling and feature toggles for the viewport icon toolbar (`ViewportIcons`).", + "source": "src/shared/entities/viewport/config/legacyViewportIconsTheme.ts", "category": "entity", "properties": [ { - "name": "children", - "description": "", + "name": "style", + "description": "Style properties for the container", "type": { - "$ref": "#/definitions/ReactNode" + "$ref": "#/definitions/MantineCssStyleRecord" } }, { - "name": "className", - "description": "", + "name": "fullscreenId", + "description": "ID of the fullscreen area", "type": { "type": "string" } }, { - "name": "showStatistics", - "description": "", - "type": { - "type": "boolean" - } - }, - { - "name": "canvas", - "description": "The canvas element in which the viewport should be created, it is encourage to provide one. If none was provided, a canvas will be created.", - "type": { - "$ref": "#/definitions/HTMLCanvasElement" - } - }, - { - "name": "id", - "description": "The unique identifier of the session that was specified or automatically chosen on creation of the viewport.", + "name": "color", + "description": "color of the icons", "type": { "type": "string" } }, { - "name": "branding", - "description": "The branding options of the viewport.", - "type": { - "$ref": "#/definitions/ViewportBranding" - } - }, - { - "name": "sessionSettingsId", - "description": "The id of the session of which the settings should be used. Only works when sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION.", + "name": "colorDisabled", + "description": "color of the icons when disabled", "type": { "type": "string" } }, { - "name": "sessionSettingsMode", - "description": "The mode in which settings should be applied. (default: SESSION_SETTINGS_MODE.FIRST)", - "type": { - "$ref": "#/definitions/SESSION_SETTINGS_MODE" - } - }, - { - "name": "visibility", - "description": "The initial visibility of the viewport. (default: VISIBILITY_MODE.SESSION)", - "type": { - "$ref": "#/definitions/VISIBILITY_MODE" - } - }, - { - "name": "visibilitySessionIds", - "description": "The ids of the sessions that should be displayed in the viewport. This only is considered if the visibility is set to VISIBILITY_MODE.SESSIONS.\nIt's recommended that with this workflow, the sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION and a sessionSettingsId is provided.", - "type": { - "items": { - "type": "string" - } - } - }, - { - "name": "flags", - "description": "Optional flags that should be initially set on the viewport.\nThe key is the token that is used to identify the flag, and the value is the type of the flag.", + "name": "variant", + "description": "variant of the icons", "type": { - "$ref": "#/definitions/[key_string]_FLAG_TYPE" + "type": "string" } }, { - "name": "initialAutoAdjust", - "description": "If the viewport should automatically adjust the camera to fit the model on creation. (default: false)", - "type": { - "type": "boolean" - } - } - ] - }, - { - "configPath": "themeOverrides.components.ViewportBranding.defaultProps", - "name": "ViewportBranding", - "summary": "Light/dark branding for the viewport loading overlay (`useProps(\"ViewportBranding\", …)`).", - "source": "src/shared/entities/viewport/config/viewport.ts", - "category": "entity", - "properties": [ - { - "name": "dark", - "description": "Branding settings for dark scheme", + "name": "variantDisabled", + "description": "variant of the icons when disabled", "type": { - "$ref": "#/definitions/ViewportBranding" + "type": "string" } }, { - "name": "light", - "description": "Branding settings for light scheme", - "type": { - "$ref": "#/definitions/ViewportBranding" - } - } - ] - }, - { - "configPath": "themeOverrides.components.ViewportIcons.defaultProps", - "name": "ViewportIcons", - "summary": "Optional styling and feature toggles for the viewport icon toolbar (`ViewportIcons`).", - "source": "src/shared/entities/viewport/config/viewportIcons.ts", - "category": "entity", - "properties": [ - { - "name": "style", - "description": "Style properties for the container", + "name": "iconStyle", + "description": "style of the icons", "type": { - "$ref": "#/definitions/MantineCssStyleRecord" + "$ref": "#/definitions/MantineStyleProp" } }, { - "name": "fullscreenId", - "description": "ID of the fullscreen area", + "name": "size", + "description": "size of the icons", "type": { - "type": "string" + "type": "number" } }, { "name": "enableHistoryButtons", - "description": "enable/disable the \"parameter history\" buttons", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableModelStateButtons", - "description": "enable/disable the \"model state\" buttons", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableImportExportButtons", - "description": "enable/disable the \"import/export JSON file\" buttons", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableResetButton", - "description": "enable/disable the \"reset parameter values\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableArBtn", - "description": "enable/disable the \"AR\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableCamerasBtn", - "description": "enable/disable the \"cameras\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableFullscreenBtn", - "description": "enable/disable the \"fullscreen\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableFullscreenBtn3States", - "description": "enable/disable the \"fullscreen 3 states (normal | fullscreen with inputs | viewer only fullscreen)\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableZoomBtn", - "description": "enable/disable the \"zoom\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableHistoryMenuButton", - "description": "enable/disable the \"history menu\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { - "name": "color", - "description": "color of the icons", + "name": "viewportOverlayProps", + "description": "", "type": { - "type": "string" + "$ref": "#/definitions/unknown" } }, { - "name": "colorDisabled", - "description": "color of the icons when disabled", + "name": "paperProps", + "description": "paper props", "type": { - "type": "string" + "$ref": "#/definitions/PaperProps" } }, { - "name": "variant", - "description": "variant of the icons", + "name": "dividerProps", + "description": "divider props", "type": { - "type": "string" + "$ref": "#/definitions/DividerProps" } }, { - "name": "variantDisabled", - "description": "variant of the icons when disabled", + "name": "transitionProps", + "description": "transition props", + "type": { + "$ref": "#/definitions/TransitionProps" + } + } + ] + }, + { + "configPath": "themeOverrides.components.ViewportComponent.defaultProps", + "name": "ViewportComponent", + "summary": "Props for the ShapeDiver viewport (`ViewportComponent`), including theme defaults via `useProps(\"ViewportComponent\", …)`.", + "source": "src/shared/entities/viewport/config/viewport.ts", + "category": "entity", + "properties": [ + { + "name": "children", + "description": "", + "type": { + "$ref": "#/definitions/ReactNode" + } + }, + { + "name": "className", + "description": "", "type": { "type": "string" } }, { - "name": "iconStyle", - "description": "style of the icons", + "name": "showStatistics", + "description": "", "type": { - "$ref": "#/definitions/MantineStyleProp" + "type": "boolean" } }, { - "name": "size", - "description": "size of the icons", + "name": "canvas", + "description": "The canvas element in which the viewport should be created, it is encourage to provide one. If none was provided, a canvas will be created.", "type": { - "type": "number" + "$ref": "#/definitions/HTMLCanvasElement" } }, { - "name": "viewportOverlayProps", - "description": "viewport overlay props", + "name": "id", + "description": "The unique identifier of the session that was specified or automatically chosen on creation of the viewport.", "type": { - "$ref": "#/definitions/ViewportOverlayWrapperProps_and_Partial_OverlayStyleProps" + "type": "string" } }, { - "name": "paperProps", - "description": "paper props", + "name": "branding", + "description": "The branding options of the viewport.", "type": { - "$ref": "#/definitions/PaperProps" + "$ref": "#/definitions/ViewportBranding" } }, { - "name": "dividerProps", - "description": "divider props", + "name": "sessionSettingsId", + "description": "The id of the session of which the settings should be used. Only works when sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION.", "type": { - "$ref": "#/definitions/DividerProps" + "type": "string" } }, { - "name": "transitionProps", - "description": "transition props", + "name": "sessionSettingsMode", + "description": "The mode in which settings should be applied. (default: SESSION_SETTINGS_MODE.FIRST)", "type": { - "$ref": "#/definitions/TransitionProps" + "$ref": "#/definitions/SESSION_SETTINGS_MODE" } - } - ] - }, - { - "configPath": "themeOverrides.components.ViewportIconButton.defaultProps", - "name": "ViewportIconButton", - "summary": "Theme defaults for a single viewport toolbar icon button.", - "source": "src/shared/entities/viewport/ui/ViewportIconButton.tsx", - "category": "entity", - "properties": [ + }, { - "name": "actionIconProps", - "description": "", + "name": "visibility", + "description": "The initial visibility of the viewport. (default: VISIBILITY_MODE.SESSION)", "type": { - "$ref": "#/definitions/MantineActionIconProps_and_Unknown" + "$ref": "#/definitions/VISIBILITY_MODE" } }, { - "name": "iconProps", - "description": "", + "name": "visibilitySessionIds", + "description": "The ids of the sessions that should be displayed in the viewport. This only is considered if the visibility is set to VISIBILITY_MODE.SESSIONS.\nIt's recommended that with this workflow, the sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION and a sessionSettingsId is provided.", "type": { - "$ref": "#/definitions/IconProps" + "items": { + "type": "string" + } } }, { - "name": "tooltipWrapperProps", - "description": "", + "name": "flags", + "description": "Optional flags that should be initially set on the viewport.\nThe key is the token that is used to identify the flag, and the value is the type of the flag.", "type": { - "$ref": "#/definitions/TooltipProps" + "$ref": "#/definitions/[key_string]_FLAG_TYPE" + } + }, + { + "name": "initialAutoAdjust", + "description": "If the viewport should automatically adjust the camera to fit the model on creation. (default: false)", + "type": { + "type": "boolean" } } ] }, { - "configPath": "themeOverrides.components.ViewportIconButtonDropdowns.defaultProps", - "name": "ViewportIconButtonDropdown", - "summary": "", - "source": "src/shared/entities/viewport/ui/ViewportIconButtonDropdown.tsx", + "configPath": "themeOverrides.components.ViewportBranding.defaultProps", + "name": "ViewportBranding", + "summary": "Light/dark branding for the viewport loading overlay (`useProps(\"ViewportBranding\", …)`).", + "source": "src/shared/entities/viewport/config/viewport.ts", "category": "entity", "properties": [ { - "name": "menuProps", - "description": "", + "name": "dark", + "description": "Branding settings for dark scheme", "type": { - "$ref": "#/definitions/MenuProps" + "$ref": "#/definitions/ViewportBranding" } }, { - "name": "menuDropdownProps", - "description": "", + "name": "light", + "description": "Branding settings for light scheme", "type": { - "$ref": "#/definitions/MenuDropdownProps" + "$ref": "#/definitions/ViewportBranding" } } ] @@ -2913,6 +2835,36 @@ } ] }, + { + "configPath": "themeOverrides.components.AppBuilderToolbarIconButton.defaultProps", + "name": "AppBuilderToolbarIconButton", + "summary": "Theme defaults for App Builder toolbar icon triggers.\n\n`ViewportIconButton` remains supported as a legacy theme override key and is\napplied as a fallback before `AppBuilderToolbarIconButton` defaults.", + "source": "src/shared/features/appbuilder/ui/AppBuilderToolbarIconButton.tsx", + "category": "appbuilder", + "properties": [ + { + "name": "actionIconProps", + "description": "", + "type": { + "$ref": "#/definitions/MantineActionIconProps_and_Unknown" + } + }, + { + "name": "iconProps", + "description": "", + "type": { + "$ref": "#/definitions/IconProps" + } + }, + { + "name": "tooltipWrapperProps", + "description": "", + "type": { + "$ref": "#/definitions/TooltipProps" + } + } + ] + }, { "configPath": "themeOverrides.components.CreateModelStateHook.defaultProps", "name": "CreateModelStateHook", @@ -4498,8 +4450,6 @@ "themeOverrides.components.StargateShared.defaultProps", "themeOverrides.components.ViewportBranding.defaultProps", "themeOverrides.components.ViewportComponent.defaultProps", - "themeOverrides.components.ViewportIconButton.defaultProps", - "themeOverrides.components.ViewportIconButtonDropdowns.defaultProps", "themeOverrides.components.ViewportIcons.defaultProps", "themeOverrides.components.ViewportOverlayWrapper.defaultProps" ], @@ -4508,6 +4458,9 @@ "themeOverrides.components.CreateModelStateHook.defaultProps", "themeOverrides.components.NotificationWrapper.defaultProps" ], + "appbuilder": [ + "themeOverrides.components.AppBuilderToolbarIconButton.defaultProps" + ], "page": [ "themeOverrides.components.AppBuilderAppShellTemplatePage.defaultProps", "themeOverrides.components.AppBuilderContainerWrapper.defaultProps", @@ -4544,4 +4497,4 @@ "themeOverrides.components.ViewportAcceptRejectButtons.defaultProps" ] } -} +} \ No newline at end of file diff --git a/public/doc-nested.json b/public/doc-nested.json index 98c3d50e..44665211 100644 --- a/public/doc-nested.json +++ b/public/doc-nested.json @@ -207,7 +207,7 @@ "properties": { "v8ThemeSupport": { "type": "boolean", - "description": "When `true`, merges Mantine's `v8CssVariablesResolver` with AppBuilder CSS\nvariables (v8 `light` variant colors). Default in product theme: `false`." + "description": "When `true`, merges Mantine's `v8CssVariablesResolver` with AppBuilder CSS\r\nvariables (v8 `light` variant colors). Default in product theme: `false`." }, "forceColorScheme": { "type": "string", @@ -425,6 +425,10 @@ }, "ActionIconProps": { "properties": { + "color": { + "type": "string", + "description": "ActionIcon color. Use \"default\" for neutral hover (Mantine v8 parity)." + }, "variant": { "type": "string" }, @@ -814,6 +818,49 @@ } } }, + "CSSProperties": { + "type": "unknown", + "name": "CSSProperties" + }, + "MantineStyleProp": { + "type": "unknown", + "name": "MantineStyleProp" + }, + "unknown": { + "type": "unknown", + "name": "unknown" + }, + "DividerProps": { + "properties": { + "orientation": { + "type": "string", + "enum": [ + "horizontal", + "vertical" + ] + }, + "color": { + "type": "string" + } + } + }, + "TransitionProps": { + "properties": { + "transition": { + "type": "unknown", + "name": "MantineTransitionName" + }, + "duration": { + "type": "number" + }, + "timingFunction": { + "type": "string" + }, + "keepMounted": { + "type": "boolean" + } + } + }, "HTMLCanvasElement": { "type": "unknown", "name": "HTMLCanvasElement" @@ -862,71 +909,54 @@ "type": "unknown", "name": "object" }, - "CSSProperties": { - "type": "unknown", - "name": "CSSProperties" - }, - "MantineStyleProp": { - "type": "unknown", - "name": "MantineStyleProp" - }, - "ViewportOverlayWrapperProps_and_Partial_OverlayStyleProps": { + "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined": { "properties": { - "children": { - "type": "unknown", - "name": "ReactNode" + "base": { + "$ref": "#/definitions/T", + "description": "" }, - "position": { - "type": "unknown", - "name": "ResponsiveValueType" + "xs": { + "$ref": "#/definitions/T", + "description": "" }, - "offset": { - "type": "string" + "sm": { + "$ref": "#/definitions/T", + "description": "" }, - "offsetX": { - "type": "string" + "md": { + "$ref": "#/definitions/T", + "description": "" }, - "offsetY": { - "type": "string" + "lg": { + "$ref": "#/definitions/T", + "description": "" }, - "className": { - "type": "string" + "xl": { + "$ref": "#/definitions/T", + "description": "" } } }, - "DividerProps": { - "properties": { - "orientation": { - "type": "string", - "enum": [ - "horizontal", - "vertical" - ] - }, - "color": { - "type": "string" - } - } + "T": { + "type": "unknown", + "name": "T" }, - "TransitionProps": { - "properties": { - "transition": { - "type": "unknown", - "name": "MantineTransitionName" - }, - "duration": { - "type": "number" - }, - "timingFunction": { - "type": "string" + "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined_or_T": { + "oneOf": [ + { + "$ref": "#/definitions/base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined" }, - "keepMounted": { - "type": "boolean" + { + "$ref": "#/definitions/T" } - } + ] }, "MantineActionIconProps_and_Unknown": { "properties": { + "color": { + "type": "string", + "description": "ActionIcon color. Use \"default\" for neutral hover (Mantine v8 parity)." + }, "variant": { "type": "string" }, @@ -967,65 +997,6 @@ } } }, - "MenuProps": { - "properties": { - "shadow": { - "type": "string" - }, - "position": { - "$ref": "#/definitions/MantineFloatingPosition" - } - } - }, - "MenuDropdownProps": { - "properties": { - "style": { - "$ref": "#/definitions/MantineCssStyleRecord" - } - } - }, - "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined": { - "properties": { - "base": { - "$ref": "#/definitions/T", - "description": "" - }, - "xs": { - "$ref": "#/definitions/T", - "description": "" - }, - "sm": { - "$ref": "#/definitions/T", - "description": "" - }, - "md": { - "$ref": "#/definitions/T", - "description": "" - }, - "lg": { - "$ref": "#/definitions/T", - "description": "" - }, - "xl": { - "$ref": "#/definitions/T", - "description": "" - } - } - }, - "T": { - "type": "unknown", - "name": "T" - }, - "base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined_or_T": { - "oneOf": [ - { - "$ref": "#/definitions/base_T_xs_T_sm_T_md_T_lg_T_xl_T_[key_string]_T_or_undefined" - }, - { - "$ref": "#/definitions/T" - } - ] - }, "number_or_boolean": { "oneOf": [ { @@ -1197,13 +1168,6 @@ } } }, - "fontWeights": { - "properties": { - "[string]": { - "type": "string" - } - } - }, "radius": { "properties": { "[string]": { @@ -1233,8 +1197,12 @@ } }, "headings": { - "type": "unknown", - "name": "AppBuilderThemeOtherProps" + "properties": { + "[string]": { + "type": "unknown", + "name": "unknown" + } + } }, "defaultGradient": { "properties": { @@ -2088,6 +2056,13 @@ "type": "boolean" } }, + { + "name": "hideDefaultToolbar", + "description": "Whether to hide the default viewport toolbar. Defaults to false.", + "type": { + "type": "boolean" + } + }, { "name": "loadPlatformSettingsFromViewer", "description": "In case we cannot connect to the platform, load settings from the viewer, if they were stored there. (default: undefined)", @@ -2385,324 +2360,275 @@ "category": "entity" } }, - "ViewportComponent": { + "ViewportIcons": { "defaultProps": { "properties": [ { - "name": "children", - "description": "", + "name": "style", + "description": "Style properties for the container", "type": { - "$ref": "#/definitions/ReactNode" + "$ref": "#/definitions/MantineCssStyleRecord" } }, { - "name": "className", - "description": "", + "name": "fullscreenId", + "description": "ID of the fullscreen area", "type": { "type": "string" } }, { - "name": "showStatistics", - "description": "", - "type": { - "type": "boolean" - } - }, - { - "name": "canvas", - "description": "The canvas element in which the viewport should be created, it is encourage to provide one. If none was provided, a canvas will be created.", - "type": { - "$ref": "#/definitions/HTMLCanvasElement" - } - }, - { - "name": "id", - "description": "The unique identifier of the session that was specified or automatically chosen on creation of the viewport.", + "name": "color", + "description": "color of the icons", "type": { "type": "string" } }, { - "name": "branding", - "description": "The branding options of the viewport.", - "type": { - "$ref": "#/definitions/ViewportBranding" - } - }, - { - "name": "sessionSettingsId", - "description": "The id of the session of which the settings should be used. Only works when sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION.", + "name": "colorDisabled", + "description": "color of the icons when disabled", "type": { "type": "string" } }, { - "name": "sessionSettingsMode", - "description": "The mode in which settings should be applied. (default: SESSION_SETTINGS_MODE.FIRST)", - "type": { - "$ref": "#/definitions/SESSION_SETTINGS_MODE" - } - }, - { - "name": "visibility", - "description": "The initial visibility of the viewport. (default: VISIBILITY_MODE.SESSION)", - "type": { - "$ref": "#/definitions/VISIBILITY_MODE" - } - }, - { - "name": "visibilitySessionIds", - "description": "The ids of the sessions that should be displayed in the viewport. This only is considered if the visibility is set to VISIBILITY_MODE.SESSIONS.\nIt's recommended that with this workflow, the sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION and a sessionSettingsId is provided.", - "type": { - "items": { - "type": "string" - } - } - }, - { - "name": "flags", - "description": "Optional flags that should be initially set on the viewport.\nThe key is the token that is used to identify the flag, and the value is the type of the flag.", + "name": "variant", + "description": "variant of the icons", "type": { - "$ref": "#/definitions/[key_string]_FLAG_TYPE" + "type": "string" } }, { - "name": "initialAutoAdjust", - "description": "If the viewport should automatically adjust the camera to fit the model on creation. (default: false)", - "type": { - "type": "boolean" - } - } - ], - "category": "entity" - } - }, - "ViewportBranding": { - "defaultProps": { - "properties": [ - { - "name": "dark", - "description": "Branding settings for dark scheme", + "name": "variantDisabled", + "description": "variant of the icons when disabled", "type": { - "$ref": "#/definitions/ViewportBranding" + "type": "string" } }, { - "name": "light", - "description": "Branding settings for light scheme", - "type": { - "$ref": "#/definitions/ViewportBranding" - } - } - ], - "category": "entity" - } - }, - "ViewportIcons": { - "defaultProps": { - "properties": [ - { - "name": "style", - "description": "Style properties for the container", + "name": "iconStyle", + "description": "style of the icons", "type": { - "$ref": "#/definitions/MantineCssStyleRecord" + "$ref": "#/definitions/MantineStyleProp" } }, { - "name": "fullscreenId", - "description": "ID of the fullscreen area", + "name": "size", + "description": "size of the icons", "type": { - "type": "string" + "type": "number" } }, { "name": "enableHistoryButtons", - "description": "enable/disable the \"parameter history\" buttons", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableModelStateButtons", - "description": "enable/disable the \"model state\" buttons", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableImportExportButtons", - "description": "enable/disable the \"import/export JSON file\" buttons", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableResetButton", - "description": "enable/disable the \"reset parameter values\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableArBtn", - "description": "enable/disable the \"AR\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableCamerasBtn", - "description": "enable/disable the \"cameras\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableFullscreenBtn", - "description": "enable/disable the \"fullscreen\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableFullscreenBtn3States", - "description": "enable/disable the \"fullscreen 3 states (normal | fullscreen with inputs | viewer only fullscreen)\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableZoomBtn", - "description": "enable/disable the \"zoom\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { "name": "enableHistoryMenuButton", - "description": "enable/disable the \"history menu\" button", + "description": "Legacy visibility flag mapped to default toolbar options.", "type": { "type": "boolean" } }, { - "name": "color", - "description": "color of the icons", + "name": "viewportOverlayProps", + "description": "", "type": { - "type": "string" + "$ref": "#/definitions/unknown" } }, { - "name": "colorDisabled", - "description": "color of the icons when disabled", + "name": "paperProps", + "description": "paper props", "type": { - "type": "string" + "$ref": "#/definitions/PaperProps" } }, { - "name": "variant", - "description": "variant of the icons", + "name": "dividerProps", + "description": "divider props", "type": { - "type": "string" + "$ref": "#/definitions/DividerProps" } }, { - "name": "variantDisabled", - "description": "variant of the icons when disabled", + "name": "transitionProps", + "description": "transition props", + "type": { + "$ref": "#/definitions/TransitionProps" + } + } + ], + "category": "entity" + } + }, + "ViewportComponent": { + "defaultProps": { + "properties": [ + { + "name": "children", + "description": "", + "type": { + "$ref": "#/definitions/ReactNode" + } + }, + { + "name": "className", + "description": "", "type": { "type": "string" } }, { - "name": "iconStyle", - "description": "style of the icons", + "name": "showStatistics", + "description": "", "type": { - "$ref": "#/definitions/MantineStyleProp" + "type": "boolean" } }, { - "name": "size", - "description": "size of the icons", + "name": "canvas", + "description": "The canvas element in which the viewport should be created, it is encourage to provide one. If none was provided, a canvas will be created.", "type": { - "type": "number" + "$ref": "#/definitions/HTMLCanvasElement" } }, { - "name": "viewportOverlayProps", - "description": "viewport overlay props", + "name": "id", + "description": "The unique identifier of the session that was specified or automatically chosen on creation of the viewport.", "type": { - "$ref": "#/definitions/ViewportOverlayWrapperProps_and_Partial_OverlayStyleProps" + "type": "string" } }, { - "name": "paperProps", - "description": "paper props", + "name": "branding", + "description": "The branding options of the viewport.", "type": { - "$ref": "#/definitions/PaperProps" + "$ref": "#/definitions/ViewportBranding" } }, { - "name": "dividerProps", - "description": "divider props", + "name": "sessionSettingsId", + "description": "The id of the session of which the settings should be used. Only works when sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION.", "type": { - "$ref": "#/definitions/DividerProps" + "type": "string" } }, { - "name": "transitionProps", - "description": "transition props", + "name": "sessionSettingsMode", + "description": "The mode in which settings should be applied. (default: SESSION_SETTINGS_MODE.FIRST)", "type": { - "$ref": "#/definitions/TransitionProps" + "$ref": "#/definitions/SESSION_SETTINGS_MODE" } - } - ], - "category": "entity" - } - }, - "ViewportIconButton": { - "defaultProps": { - "properties": [ + }, { - "name": "actionIconProps", - "description": "", + "name": "visibility", + "description": "The initial visibility of the viewport. (default: VISIBILITY_MODE.SESSION)", "type": { - "$ref": "#/definitions/MantineActionIconProps_and_Unknown" + "$ref": "#/definitions/VISIBILITY_MODE" } }, { - "name": "iconProps", - "description": "", + "name": "visibilitySessionIds", + "description": "The ids of the sessions that should be displayed in the viewport. This only is considered if the visibility is set to VISIBILITY_MODE.SESSIONS.\nIt's recommended that with this workflow, the sessionSettingsMode is set to SESSION_SETTINGS_MODE.SESSION and a sessionSettingsId is provided.", "type": { - "$ref": "#/definitions/IconProps" + "items": { + "type": "string" + } } }, { - "name": "tooltipWrapperProps", - "description": "", + "name": "flags", + "description": "Optional flags that should be initially set on the viewport.\nThe key is the token that is used to identify the flag, and the value is the type of the flag.", "type": { - "$ref": "#/definitions/TooltipProps" + "$ref": "#/definitions/[key_string]_FLAG_TYPE" + } + }, + { + "name": "initialAutoAdjust", + "description": "If the viewport should automatically adjust the camera to fit the model on creation. (default: false)", + "type": { + "type": "boolean" } } ], "category": "entity" } }, - "ViewportIconButtonDropdowns": { + "ViewportBranding": { "defaultProps": { "properties": [ { - "name": "menuProps", - "description": "", + "name": "dark", + "description": "Branding settings for dark scheme", "type": { - "$ref": "#/definitions/MenuProps" + "$ref": "#/definitions/ViewportBranding" } }, { - "name": "menuDropdownProps", - "description": "", + "name": "light", + "description": "Branding settings for light scheme", "type": { - "$ref": "#/definitions/MenuDropdownProps" + "$ref": "#/definitions/ViewportBranding" } } ], @@ -2856,6 +2782,34 @@ "category": "feature" } }, + "AppBuilderToolbarIconButton": { + "defaultProps": { + "properties": [ + { + "name": "actionIconProps", + "description": "", + "type": { + "$ref": "#/definitions/MantineActionIconProps_and_Unknown" + } + }, + { + "name": "iconProps", + "description": "", + "type": { + "$ref": "#/definitions/IconProps" + } + }, + { + "name": "tooltipWrapperProps", + "description": "", + "type": { + "$ref": "#/definitions/TooltipProps" + } + } + ], + "category": "appbuilder" + } + }, "CreateModelStateHook": { "defaultProps": { "properties": [ @@ -4355,4 +4309,4 @@ } } } -} +} \ No newline at end of file diff --git a/public/example-toolbar-container.json b/public/example-toolbar-container.json new file mode 100644 index 00000000..ba587210 --- /dev/null +++ b/public/example-toolbar-container.json @@ -0,0 +1,1011 @@ +{ + "version": "1.0", + "settings": { + "disableFallbackUi": true + }, + "sessions": [ + { + "id": "default", + "ticket": "50eb2a26ddaa432ca18288b8a120ef194fa35bb813e4f43ae89d657991a865f9deaa20a1c840e47cdf6dbc019cd16ae15a9a6b3a7d91722455299d6bd29b1f26b3ff3b7adaac1df3d50f3ba4d010a560180dff8f745c946dadb41167a3431e223d69b32743f167-5b9465f92a0cf9c235b8ea315aab0cd5", + "modelViewUrl": "https://sdr7euc1.eu-central-1.shapediver.com", + "hideDefaultToolbar": false + } + ], + "appBuilderOverride": { + "version": "1.0", + "containers": [ + { + "name": "toolbar", + "props": { + "id": "manual-default-toolbar", + "side": "bottom", + "align": "center", + "order": 0, + "visibility": "onMouseActivity", + "groups": [ + [ + { + "id": "manual-default-ar", + "type": "action", + "label": "View in AR", + "icon": "tabler:augmented-reality", + "props": { + "definition": { + "type": "ar", + "props": {} + } + } + }, + { + "id": "manual-default-zoom", + "type": "action", + "label": "Zoom extents", + "icon": "tabler:zoom-in", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "zoomTo", + "props": {} + } + } + } + }, + { + "id": "bottom-camera-menu", + "label": "Camera matrix", + "tooltip": "All implemented camera action variants", + "icon": "video", + "items": [ + [ + { + "id": "camera-assign-by-name-top", + "type": "action", + "presentation": "item", + "label": "Top", + "icon": "video", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "assign", + "props": { + "camera": { + "name": "top" + } + } + } + } + } + }, + { + "id": "camera-assign-by-name.bottom", + "type": "action", + "presentation": "item", + "label": "Bottom", + "icon": "video", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "assign", + "props": { + "camera": { + "name": "bottom" + } + } + } + } + } + } + ] + ] + }, + { + "id": "manual-default-fullscreen-3-states", + "type": "action", + "label": "Fullscreen", + "icon": "tabler:maximize", + "props": { + "definition": { + "type": "fullscreen", + "props": { + "type": "fullscreen3States" + } + } + } + } + ], + [ + { + "id": "manual-default-undo", + "type": "action", + "label": "Undo", + "icon": "tabler:arrow-back-up", + "props": { + "definition": { + "type": "undo", + "props": {} + } + } + }, + { + "id": "manual-default-redo", + "type": "action", + "label": "Redo", + "icon": "tabler:arrow-forward-up", + "props": { + "definition": { + "type": "redo", + "props": {} + } + } + }, + { + "id": "manual-default-reset", + "type": "action", + "label": "Reset to default parameters", + "icon": "tabler:reload", + "props": { + "definition": { + "type": "resetParameterValues", + "props": {} + } + } + }, + { + "id": "manual-default-more-options", + "label": "More options", + "icon": "tabler:dots-vertical", + "items": [ + [ + { + "id": "manual-default-import-parameter-values", + "type": "action", + "presentation": "item", + "label": "Import parameter values", + "icon": "tabler:upload", + "props": { + "definition": { + "type": "importParameterValues", + "props": {} + } + } + }, + { + "id": "manual-default-export-parameter-values", + "type": "action", + "presentation": "item", + "label": "Export parameter values", + "icon": "tabler:download", + "props": { + "definition": { + "type": "exportParameterValues", + "props": {} + } + } + } + ], + [ + { + "id": "manual-default-create-model-state", + "type": "action", + "presentation": "item", + "label": "Create model state", + "icon": "tabler:device-floppy", + "props": { + "definition": { + "type": "createModelState", + "props": { + "includeImage": true, + "includeGltf": false + } + } + } + }, + { + "id": "manual-default-import-model-state", + "type": "action", + "presentation": "item", + "label": "Import model state", + "icon": "tabler:file-import", + "props": { + "definition": { + "type": "importModelState", + "props": {} + } + } + } + ] + ] + } + ] + ] + } + }, + { + "name": "toolbar", + "props": { + "id": "left-toolbar", + "side": "left", + "align": "start", + "order": 0, + "visibility": "always", + "groups": [ + [ + { + "id": "top-length-parameter", + "type": "parameter", + "label": "Length", + "tooltip": "Open Length parameter in a toolbar popover", + "icon": "ruler", + "presentation": "button", + "props": { + "name": "Length", + "sessionId": "default", + "disableIfDirty": false, + "acceptRejectMode": true, + "overrides": { + "displayname": "Length override", + "tooltip": "Parameter ref with overrides, accept/reject mode, and explicit session id", + "hidden": false, + "step": 1 + } + } + }, + { + "id": "top-image-export", + "type": "export", + "label": "Image export", + "tooltip": "Export ref with overrides and parameter values", + "icon": "download", + "props": { + "name": "Image Export", + "sessionId": "default", + "overrides": { + "displayname": "Image Export override", + "tooltip": "Toolbar export ref override", + "hidden": false + }, + "parameterValues": [ + { + "parameter": { + "name": "Length", + "sessionId": "default" + }, + "value": "42" + } + ] + } + } + ], + [ + { + "id": "flat-menu-button-presentation", + "label": "Flat menu", + "tooltip": "Flat item array; entries render as regular buttons", + "icon": "list", + "items": [ + { + "id": "flat-set-single-value", + "type": "action", + "presentation": "item", + "label": "Set Hide Door true", + "tooltip": "setParameterValue action rendered as a button in a popover", + "icon": "toggle-right", + "props": { + "definition": { + "type": "setParameterValue", + "props": { + "parameter": { + "name": "Hide Door", + "sessionId": "default" + }, + "value": "true", + "label": "Set single value", + "icon": "toggle-right", + "tooltip": "Set one parameter value" + } + } + } + }, + { + "id": "flat-set-multiple-values", + "type": "action", + "presentation": "item", + "label": "Set multiple values", + "tooltip": "setParameterValues action with multiple parameter entries", + "icon": "adjustments-horizontal", + "props": { + "definition": { + "type": "setParameterValues", + "props": { + "message": "Toolbar test: setting multiple parameter values", + "parameterValues": [ + { + "parameter": { + "name": "Length", + "sessionId": "default" + }, + "value": "25" + }, + { + "parameter": { + "name": "Material Color", + "sessionId": "default" + }, + "value": "#ff8800" + } + ] + } + } + } + } + ] + }, + { + "id": "left-sound-action", + "type": "action", + "label": "Sound", + "tooltip": "Play/pause a sound action", + "icon": "volume", + "props": { + "definition": { + "type": "sound", + "props": { + "href": "https://actions.google.com/sounds/v1/cartoon/wood_plank_flicks.ogg", + "autoplay": false, + "loop": false, + "labelPlaying": "Stop sound", + "iconPlaying": "player-stop" + } + } + } + } + ], + [ + { + "id": "left-parameter-panel", + "label": "Parameters", + "tooltip": "Open parameter controls in a toolbar popover", + "icon": "adjustments-horizontal", + "widgets": [ + { + "type": "controls", + "props": { + "controls": [ + { + "type": "parameter", + "props": { + "name": "Hide Door", + "sessionId": "default", + "disableIfDirty": true, + "acceptRejectMode": false, + "overrides": { + "displayname": "Hide Door override", + "tooltip": "Boolean parameter shown from a toolbar item", + "hidden": false + } + } + }, + { + "type": "parameter", + "props": { + "name": "Material Color", + "sessionId": "default", + "overrides": { + "displayname": "Material Color override", + "tooltip": "Color parameter shown from a toolbar item", + "hidden": false + } + } + } + ] + } + } + ] + } + ] + ] + } + }, + { + "name": "toolbar", + "props": { + "id": "top-camera-matrix-toolbar", + "side": "top", + "align": "end", + "order": 4, + "visibility": "always", + "groups": [ + [ + { + "id": "left-sound-action", + "type": "action", + "label": "Sound", + "tooltip": "Play/pause a sound action", + "icon": "volume", + "props": { + "definition": { + "type": "sound", + "props": { + "href": "https://actions.google.com/sounds/v1/cartoon/wood_plank_flicks.ogg", + "autoplay": false, + "loop": false, + "labelPlaying": "Stop sound", + "iconPlaying": "player-stop" + } + } + } + }, + { + "id": "bottom-camera-menu-items", + "label": "Camera matrix", + "tooltip": "All implemented camera action variants", + "icon": "video", + "items": [ + [ + { + "id": "camera-assign-by-name", + "type": "action", + "presentation": "item", + "label": "Assign named/default camera", + "tooltip": "Assign an existing camera by name or id fallback", + "icon": "camera", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "assign", + "props": { + "camera": { + "name": "top" + } + } + } + } + } + }, + { + "id": "camera-assign-new-perspective", + "type": "action", + "presentation": "item", + "label": "Assign new perspective camera", + "tooltip": "Create and assign a perspective camera", + "icon": "video", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "assign", + "props": { + "camera": { + "type": "perspective", + "position": [ + 8, + 6, + 8 + ], + "target": [ + 0, + 0, + 0 + ] + }, + "options": { + "duration": 800 + } + } + } + } + } + } + ], + [ + { + "id": "camera-set-position", + "type": "action", + "presentation": "item", + "label": "Set camera position", + "icon": "focus-centered", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "set", + "props": { + "position": [ + 5, + 4, + 5 + ], + "target": [ + 0, + 0, + 0 + ], + "options": { + "duration": 600 + } + } + } + } + } + }, + { + "id": "camera-reset", + "type": "action", + "presentation": "item", + "label": "Reset camera", + "icon": "camera", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "reset", + "props": { + "options": { + "duration": 600 + } + } + } + } + } + } + ], + [ + { + "id": "camera-zoom-with-filter", + "type": "action", + "presentation": "item", + "label": "Zoom with filter", + "icon": "zoom-in", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "zoomTo", + "props": { + "initialPosition": [ + 10, + 10, + 10 + ], + "initialTarget": [ + 0, + 0, + 0 + ], + "nameFilter": [ + "Door", + "Frame" + ], + "options": { + "duration": 700 + } + } + } + } + } + }, + { + "id": "camera-animate-path", + "type": "action", + "presentation": "item", + "label": "Animate camera path", + "icon": "route", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "animate", + "props": { + "startFromCurrent": true, + "path": [ + { + "position": [ + 8, + 8, + 8 + ], + "target": [ + 0, + 0, + 0 + ] + }, + { + "position": [ + -8, + 6, + 8 + ], + "target": [ + 0, + 0, + 0 + ] + } + ], + "options": { + "duration": 1200 + } + } + } + } + } + } + ] + ] + }, + { + "id": "bottom-camera-menu", + "label": "Camera matrix", + "tooltip": "All implemented camera action variants", + "icon": "video", + "items": [ + [ + { + "id": "camera-assign-by-name", + "type": "action", + "presentation": "button", + "label": "Assign named/default camera", + "tooltip": "Assign an existing camera by name or id fallback", + "icon": "camera", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "assign", + "props": { + "camera": { + "name": "default" + } + } + } + } + } + }, + { + "id": "camera-assign-new-perspective", + "type": "action", + "presentation": "button", + "label": "Assign new perspective camera", + "tooltip": "Create and assign a perspective camera", + "icon": "video", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "assign", + "props": { + "camera": { + "type": "perspective", + "position": [ + 8, + 6, + 8 + ], + "target": [ + 0, + 0, + 0 + ] + }, + "options": { + "duration": 800 + } + } + } + } + } + } + ], + [ + { + "id": "camera-set-position", + "type": "action", + "presentation": "button", + "label": "Set camera position", + "icon": "focus-centered", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "set", + "props": { + "position": [ + 5, + 4, + 5 + ], + "target": [ + 0, + 0, + 0 + ], + "options": { + "duration": 600 + } + } + } + } + } + }, + { + "id": "camera-reset", + "type": "action", + "presentation": "button", + "label": "Reset camera", + "icon": "camera", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "reset", + "props": { + "options": { + "duration": 600 + } + } + } + } + } + } + ], + [ + { + "id": "camera-zoom-with-filter", + "type": "action", + "presentation": "button", + "label": "Zoom with filter", + "icon": "zoom-in", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "zoomTo", + "props": { + "initialPosition": [ + 10, + 10, + 10 + ], + "initialTarget": [ + 0, + 0, + 0 + ], + "nameFilter": [ + "Door", + "Frame" + ], + "options": { + "duration": 700 + } + } + } + } + } + }, + { + "id": "camera-animate-path", + "type": "action", + "presentation": "button", + "label": "Animate camera path", + "icon": "route", + "props": { + "definition": { + "type": "camera", + "props": { + "type": "animate", + "props": { + "startFromCurrent": true, + "path": [ + { + "position": [ + 8, + 8, + 8 + ], + "target": [ + 0, + 0, + 0 + ] + }, + { + "position": [ + -8, + 6, + 8 + ], + "target": [ + 0, + 0, + 0 + ] + } + ], + "options": { + "duration": 1200 + } + } + } + } + } + } + ] + ] + } + ] + ] + } + }, + { + "name": "toolbar", + "props": { + "id": "bottom-end-refs-toolbar", + "side": "bottom", + "align": "end", + "order": 6, + "visibility": "always", + "groups": [ + [ + { + "id": "bottom-image-export-minimal", + "type": "export", + "label": "Minimal export", + "tooltip": "Export ref with only the required name", + "icon": "download", + "props": { + "name": "Image Export" + } + }, + { + "id": "bottom-length-minimal", + "type": "parameter", + "label": "Minimal parameter", + "tooltip": "Parameter ref with only the required name", + "icon": "hash", + "props": { + "name": "Length" + } + } + ] + ] + } + }, + { + "name": "toolbar", + "props": { + "id": "right-widget-panel-toolbar", + "side": "right", + "align": "center", + "order": 7, + "visibility": "always", + "groups": [ + [ + { + "id": "right-widget-panel-test", + "icon": "layout-dashboard", + "label": "Widgets", + "tooltip": "Open a toolbar panel containing widgets", + "widgets": [ + { + "type": "text", + "props": { + "markdown": "### Toolbar widget panel\nThis panel is rendered from a toolbar item for testing." + } + }, + { + "type": "controls", + "props": { + "controls": [ + { + "type": "parameter", + "props": { + "name": "Length" + } + }, + { + "type": "parameter", + "props": { + "name": "Hide Door" + } + } + ] + } + } + ] + } + ] + ] + } + }, + { + "name": "toolbar", + "props": { + "id": "right-tabbed-panel-toolbar", + "side": "right", + "align": "end", + "order": 8, + "visibility": "onMouseActivity", + "groups": [ + [ + { + "id": "right-sticky-tabs-test", + "icon": "tabler:bookmark", + "label": "Sticky tabs", + "tooltip": "Open a toolbar panel containing tabs with stickyTabs true", + "stickyTabs": true, + "tabs": [ + { + "name": "Info", + "icon": "info-circle", + "tooltip": "Test tab with simple text widgets", + "widgets": [ + { + "type": "text", + "props": { + "markdown": "### Toolbar tabbed panel\nThis item exercises `tabs` and `stickyTabs: true`." + } + } + ] + }, + { + "name": "Controls", + "icon": "adjustments-horizontal", + "tooltip": "Test tab with controls", + "widgets": [ + { + "type": "controls", + "props": { + "controls": [ + { + "type": "parameter", + "props": { + "name": "Length" + } + }, + { + "type": "parameter", + "props": { + "name": "Material Color" + } + } + ] + } + } + ] + } + ] + }, + { + "id": "right-non-sticky-tabs-test", + "icon": "columns", + "label": "Non-sticky tabs", + "tooltip": "Open a toolbar panel containing tabs with stickyTabs false", + "stickyTabs": false, + "tabs": [ + { + "name": "Notes", + "icon": "notes", + "widgets": [ + { + "type": "text", + "props": { + "text": "This item exercises stickyTabs: false." + } + } + ] + } + ] + } + ] + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/AppBuilderRoot.tsx b/src/AppBuilderRoot.tsx index 3f0cd4a9..94134db5 100644 --- a/src/AppBuilderRoot.tsx +++ b/src/AppBuilderRoot.tsx @@ -9,19 +9,8 @@ import ViewportAnchor2d, { import ViewportAnchor3d, { ViewportAnchor3dThemeProps, } from "@AppBuilderLib/entities/viewport-anchor/ui/ViewportAnchor3d"; -import {ViewportIconButtonEnum} from "@AppBuilderLib/entities/viewport/config/viewportIcons"; -import ArButton from "@AppBuilderLib/entities/viewport/ui/ArButton"; -import CamerasButton from "@AppBuilderLib/entities/viewport/ui/CamerasButton"; -import FullscreenButton from "@AppBuilderLib/entities/viewport/ui/FullscreenButton"; -import FullscreenButton3States from "@AppBuilderLib/entities/viewport/ui/FullscreenButton3States"; -import HistoryMenuButton from "@AppBuilderLib/entities/viewport/ui/HistoryMenuButton"; -import RedoButton from "@AppBuilderLib/entities/viewport/ui/RedoButton"; -import ReloadButton from "@AppBuilderLib/entities/viewport/ui/ReloadButton"; -import UndoButton from "@AppBuilderLib/entities/viewport/ui/UndoButton"; import ViewportComponent from "@AppBuilderLib/entities/viewport/ui/ViewportComponent"; -import ViewportIcons from "@AppBuilderLib/entities/viewport/ui/ViewportIcons"; import ViewportOverlayWrapper from "@AppBuilderLib/entities/viewport/ui/ViewportOverlayWrapper"; -import ZoomButton from "@AppBuilderLib/entities/viewport/ui/ZoomButton"; import {IComponentContext} from "@AppBuilderLib/features/appbuilder/config/ComponentContext.types"; import { AppBuilderContainerNameType, @@ -30,6 +19,7 @@ import { isSceneTreeExplorerWidget, } from "@AppBuilderLib/features/appbuilder/config/appbuilder"; import AppBuilderActionCameraComponent from "@AppBuilderLib/features/appbuilder/ui/AppBuilderActionCameraComponent"; +import AppBuilderToolbarLayer from "@AppBuilderLib/features/appbuilder/ui/AppBuilderToolbarLayer"; import RootComponent from "@AppBuilderLib/shared/ui/root/RootComponent"; import AppBuilderAttributeVisualizationWidgetComponent from "@AppBuilderLib/widgets/appbuilder/ui/AppBuilderAttributeVisualizationWidgetComponent"; import AppBuilderContainerComponent from "@AppBuilderLib/widgets/appbuilder/ui/AppBuilderContainerComponent"; @@ -62,20 +52,7 @@ const components: IComponentContext = { }, viewportComponent: {component: ViewportComponent}, viewportOverlayWrapper: {component: ViewportOverlayWrapper}, - viewportIcons: {component: ViewportIcons}, - viewportIconButtons: { - [ViewportIconButtonEnum.Ar]: {component: ArButton}, - [ViewportIconButtonEnum.Zoom]: {component: ZoomButton}, - [ViewportIconButtonEnum.Cameras]: {component: CamerasButton}, - [ViewportIconButtonEnum.Fullscreen]: {component: FullscreenButton}, - [ViewportIconButtonEnum.Fullscreen3States]: { - component: FullscreenButton3States, - }, - [ViewportIconButtonEnum.Undo]: {component: UndoButton}, - [ViewportIconButtonEnum.Redo]: {component: RedoButton}, - [ViewportIconButtonEnum.Reload]: {component: ReloadButton}, - [ViewportIconButtonEnum.HistoryMenu]: {component: HistoryMenuButton}, - }, + appBuilderToolbarLayer: {component: AppBuilderToolbarLayer}, parameters: { [PARAMETER_TYPE.DRAWING]: { component: ParameterDrawingComponent, diff --git a/src/pages/examples/AppBuilderStaticExamplePage.tsx b/src/pages/examples/AppBuilderStaticExamplePage.tsx index 306a98bb..b0820e18 100644 --- a/src/pages/examples/AppBuilderStaticExamplePage.tsx +++ b/src/pages/examples/AppBuilderStaticExamplePage.tsx @@ -9,9 +9,9 @@ import AcceptRejectButtons from "@AppBuilderLib/entities/parameter/ui/AcceptReje import useDefaultSessionDto from "@AppBuilderLib/entities/session/model/useDefaultSessionDto"; import {useSession} from "@AppBuilderLib/entities/session/model/useSession"; import ViewportComponent from "@AppBuilderLib/entities/viewport/ui/ViewportComponent"; -import ViewportIcons from "@AppBuilderLib/entities/viewport/ui/ViewportIcons"; import ViewportOverlayWrapper from "@AppBuilderLib/entities/viewport/ui/ViewportOverlayWrapper"; import {IAppBuilderSettingsSession} from "@AppBuilderLib/features/appbuilder/config/appbuilder"; +import AppBuilderToolbarLayer from "@AppBuilderLib/features/appbuilder/ui/AppBuilderToolbarLayer"; import useAppBuilderSettings from "@AppBuilderLib/features/appbuilder/model/useAppBuilderSettings"; import {Logger} from "@AppBuilderLib/shared/lib/logger"; import AppBuilderImage from "@AppBuilderLib/widgets/appbuilder/ui/AppBuilderImage"; @@ -283,7 +283,7 @@ My favorite search engine is [Duck Duck Go](https://duckduckgo.com "The best sea > - + diff --git a/src/pages/examples/ModelSelectPage.tsx b/src/pages/examples/ModelSelectPage.tsx index 8eac9110..a3dcf56b 100644 --- a/src/pages/examples/ModelSelectPage.tsx +++ b/src/pages/examples/ModelSelectPage.tsx @@ -1,6 +1,6 @@ import ViewportComponent from "@AppBuilderLib/entities/viewport/ui/ViewportComponent"; -import ViewportIcons from "@AppBuilderLib/entities/viewport/ui/ViewportIcons"; import ViewportOverlayWrapper from "@AppBuilderLib/entities/viewport/ui/ViewportOverlayWrapper"; +import AppBuilderToolbarLayer from "@AppBuilderLib/features/appbuilder/ui/AppBuilderToolbarLayer"; import ModelSelect from "@AppBuilderLib/features/model-select/ui/ModelSelect"; import {ExampleModels} from "tickets"; import ExamplePage from "~/pages/examples/ExamplePage"; @@ -19,7 +19,7 @@ export default function ModelSelectPage() { }> - + diff --git a/src/pages/examples/ViewPage.tsx b/src/pages/examples/ViewPage.tsx index b62c38e9..62c46039 100644 --- a/src/pages/examples/ViewPage.tsx +++ b/src/pages/examples/ViewPage.tsx @@ -8,10 +8,10 @@ import {useDefineGenericParameters} from "@AppBuilderLib/entities/parameter/mode import {useSessionPropsParameter} from "@AppBuilderLib/entities/parameter/model/useSessionPropsParameter"; import AcceptRejectButtons from "@AppBuilderLib/entities/parameter/ui/AcceptRejectButtons"; import ViewportComponent from "@AppBuilderLib/entities/viewport/ui/ViewportComponent"; -import ViewportIcons from "@AppBuilderLib/entities/viewport/ui/ViewportIcons"; import ViewportOverlayWrapper from "@AppBuilderLib/entities/viewport/ui/ViewportOverlayWrapper"; import {IAppBuilderSettingsSession} from "@AppBuilderLib/features/appbuilder/config/appbuilder"; import {useSessionWithAppBuilder} from "@AppBuilderLib/features/appbuilder/model/useSessionWithAppBuilder"; +import AppBuilderToolbarLayer from "@AppBuilderLib/features/appbuilder/ui/AppBuilderToolbarLayer"; import {Logger} from "@AppBuilderLib/shared/lib/logger"; import TabsComponent, { ITabsComponentProps, @@ -111,7 +111,7 @@ export default function ViewPage(_props: Partial) { const sessionId = sessionCreateDto?.id ?? ""; // use a session with a ShapeDiver model and register its parameters - const {sessionApi} = useSessionWithAppBuilder(sessionCreateDto); + const {sessionApi, sessionSettings} = useSessionWithAppBuilder(sessionCreateDto); useEffect(() => { if (sessionApi) Logger.debug( @@ -288,7 +288,7 @@ export default function ViewPage(_props: Partial) { sessionSettingsId={sessionId} > - + diff --git a/src/shared b/src/shared index aaa846c6..bc962316 160000 --- a/src/shared +++ b/src/shared @@ -1 +1 @@ -Subproject commit aaa846c6faf7efef2cf84ca7af266b0edd9c48cb +Subproject commit bc96231645782904f7a14b0de809c29684236738