fix: show visually missing component in canvas (#3383)

AI sometimes adds components we don't have
here is just a hint for user that some component is missing.

<img width="686" alt="Screenshot 2024-05-19 at 14 25 16"
src="https://github.com/webstudio-is/webstudio/assets/5635476/7ca3faee-7703-4d02-9786-5f5f0a6193d0">

Here's json to paste

```json
{
  "@webstudio/template": [
    {
      "type": "instance",
      "component": "ContentEmbed",
      "children": []
    }
  ]
}
```
This commit is contained in:
Bogdan Chadkin authored and GitHub committed 2024-05-20 09:07:33 +03:00
1 parent be4a02704b
commit 1cb8225a67
1 file changed
+22 -13
@@ -29,6 +29,7 @@ import {
textContentAttribute,
descendantComponent,
} from "@webstudio-is/react-sdk";
import { rawTheme } from "@webstudio-is/design-system";
import {
$propValuesByInstanceSelector,
getIndexedInstanceId,
@@ -100,19 +101,26 @@ const ContentEditable = ({
return renderComponentWithRef(ref);
};
const StubComponent = forwardRef<HTMLDivElement, { children?: ReactNode }>(
(props, ref) => {
return (
<div
{...props}
ref={ref}
style={{ display: props.children ? "contents" : "block" }}
/>
);
}
);
const MissingComponentStub = forwardRef<
HTMLDivElement,
{ children?: ReactNode }
>((props, ref) => {
return (
<div
{...props}
ref={ref}
style={{
padding: rawTheme.spacing[5],
border: `1px solid ${rawTheme.colors.borderDestructiveMain}`,
color: rawTheme.colors.foregroundDestructive,
}}
>
Component {props[componentAttribute as never]} does not exist
</div>
);
});
StubComponent.displayName = "StubComponent";
MissingComponentStub.displayName = "MissingComponentStub";
// this utility is temporary solution to compute instance selectors
// for rich text subtree which cannot have slots so its safe to traverse ancestors
@@ -333,7 +341,8 @@ export const WebstudioComponentCanvas = forwardRef<
}
const Component =
components.get(instance.component) ?? (StubComponent as AnyComponent);
components.get(instance.component) ??
(MissingComponentStub as AnyComponent);
const props: {
[componentAttribute]: string;