Skip to content

Commit

Permalink
[cc] Add section in add drawer specific for code components
Browse files Browse the repository at this point in the history
Change-Id: I3ec9ab4959fc911a1f3f0703ae731c6eb21493b1
GitOrigin-RevId: 4023cac68c2a6515f7f4758c4f9841202aa7975b
  • Loading branch information
FMota0 authored and Copybara committed May 13, 2024
1 parent cf58b10 commit 8570d77
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
createAddHostLessComponent,
createAddInsertableTemplate,
createAddTemplateComponent,
createAddTplCodeComponents,
createAddTplComponent,
createAddTplImage,
createFakeHostLessComponent,
Expand Down Expand Up @@ -77,9 +78,11 @@ import {
} from "@/wab/common";
import { HighlightBlinker } from "@/wab/commons/components/HighlightBlinker";
import {
CodeComponent,
getSubComponents,
getSuperComponents,
isCodeComponent,
isCodeComponentWithSection,
isComponentHiddenFromContentEditor,
isContextCodeComponent,
isDefaultComponentKind,
Expand Down Expand Up @@ -275,10 +278,13 @@ const AddDrawerContent = observer(function AddDrawerContent(props: {

let itemIndex = 0;
const isAtomicSection = atomicHostlessSections.includes(section);

const virtualItems: VirtualItem[] = groupedItems
.filter((group) => query || (group.sectionKey ?? group.key) === section)
.flatMap((group, index) => [
...(!isAtomicSection ? [{ type: "header", group } as const] : []),
...(!isAtomicSection && !group.isHeaderLess
? [{ type: "header", group } as const]
: []),
...group.items.map(
(item) =>
({ type: "item", item, group, itemIndex: itemIndex++ } as const)
Expand Down Expand Up @@ -936,6 +942,49 @@ function getLeafProjectIdForHostLessPackageMeta(pkg: HostLessPackageInfo) {
return last(ensureArray(pkg.projectId));
}

function getCodeComponentsGroups(studioCtx: StudioCtx): AddItemGroup[] {
// All code components with studio UI will receive a dedicated section
// in the AddDrawer.
const components: CodeComponent[] = studioCtx.site.components.filter(
(c): c is CodeComponent => isCodeComponentWithSection(c)
);
const groups = groupBy(components, (c) => c.codeComponentMeta.section);
return sortBy(
Object.entries(groups)
.map(([section, sectionComponents]) => {
const subGroups = groupBy(sectionComponents, (c) => {
const meta = c.codeComponentMeta;
if (!meta.displayName) {
return "";
}
const parts = meta.displayName.split("/");
// Remove the last part to get the sub-section
return parts.length > 1 ? parts.slice(0, -1).join("/") : "";
});

return Object.entries(subGroups).map(
([subSection, subSectionComponents]) => {
return {
key: `code-components-${section}${
subSection ? `-${subSection}` : ""
}`,
isHeaderLess: !subSection,
sectionKey: section,
sectionLabel: section,
label: subSection,
items: sortBy(
createAddTplCodeComponents(subSectionComponents),
(item) => item.label
),
};
}
);
})
.flat(),
(itemGroup) => itemGroup.key
);
}

export function buildAddItemGroups({
studioCtx,
includeFrames = true,
Expand Down Expand Up @@ -1155,6 +1204,9 @@ export function buildAddItemGroups({
}
),

// Code components groups
...getCodeComponentsGroups(studioCtx),

includeFrames &&
canInsertAlias(uiConfig, "frame", canInsertContext) && {
key: "frames",
Expand All @@ -1166,6 +1218,7 @@ export function buildAddItemGroups({
],
},

// Custom components includes all the components from the project
{
key: "components",
label: "Custom components",
Expand All @@ -1174,6 +1227,7 @@ export function buildAddItemGroups({
(c) =>
isReusableComponent(c) &&
!isContextCodeComponent(c) &&
!isCodeComponentWithSection(c) &&
!(
contentEditorMode &&
isComponentHiddenFromContentEditor(c, studioCtx)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.preview-image {
position: relative;
width: 100%;
height: 100%;
object-fit: contain;
min-width: 0;
min-height: 0;
}
151 changes: 61 additions & 90 deletions platform/wab/src/wab/client/components/studio/add-drawer/AddDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
getPlumeImage,
} from "@/wab/client/components/plume/plume-display-utils";
import { PlumyIcon } from "@/wab/client/components/plume/plume-markers";
import sty from "@/wab/client/components/studio/add-drawer/AddDrawer.module.css";
import AddDrawerItem from "@/wab/client/components/studio/add-drawer/AddDrawerItem";
import { AddItemGroup } from "@/wab/client/components/studio/add-drawer/AddDrawerSection";
import { DraggableInsertable } from "@/wab/client/components/studio/add-drawer/DraggableInsertable";
Expand All @@ -58,13 +59,15 @@ import {
getScreenVariantToInsertableTemplate,
postInsertableTemplate,
} from "@/wab/client/insertable-templates";
import ComponentIcon from "@/wab/client/plasmic/plasmic_kit/PlasmicIcon__Component";
import PlumeMarkIcon from "@/wab/client/plasmic/plasmic_kit_design_system/icons/PlasmicIcon__PlumeMark";
import { PlasmicAddDrawer } from "@/wab/client/plasmic/plasmic_kit_left_pane/PlasmicAddDrawer";
import { StudioCtx } from "@/wab/client/studio-ctx/StudioCtx";
import { ViewCtx } from "@/wab/client/studio-ctx/view-ctx";
import { trackEvent } from "@/wab/client/tracking";
import {
assert,
cx,
ensure,
ensureArray,
filterFalsy,
Expand Down Expand Up @@ -109,6 +112,7 @@ import {
} from "@/wab/shared/code-components/code-components";
import { isRenderableType } from "@/wab/shared/core/model-util";
import { isTagListContainer } from "@/wab/shared/core/rich-text-util";
import { CSSProperties } from "@/wab/shared/element-repr/element-repr-v2";
import { InsertableTemplateExtraInfo } from "@/wab/shared/insertable-templates/types";
import { FRAMES_CAP } from "@/wab/shared/Labels";
import {
Expand Down Expand Up @@ -448,6 +452,51 @@ export function createAddTplComponent(component: Component): AddTplItem {
};
}

function getAddTplItemPreviewImage(
url: string,
objectPosition: CSSProperties["objectPosition"]
) {
return (
<img
className={cx("no-pointer-events", sty.previewImage)}
style={{
objectPosition,
}}
role="img"
src={url}
/>
);
}

export function createAddTplCodeComponent(
component: CodeComponent
): AddTplItem {
const thumbUrl = component.codeComponentMeta.thumbnailUrl;
return {
...createAddTplComponent(component),
previewImage: thumbUrl ? (
getAddTplItemPreviewImage(thumbUrl, "center center")
) : (
<Icon icon={ComponentIcon} size="100%" />
),
isCompact: true,
};
}

export function createAddTplCodeComponents(
components: CodeComponent[]
): AddTplItem[] {
return components.flatMap((component) => {
// It shouldn't be possible to have a sub component that is not a code component
// but we'll be safe and filter them out
const subComponents = getSubComponents(component).filter(isCodeComponent);
return [
createAddTplCodeComponent(component),
...subComponents.map(createAddTplCodeComponent),
];
});
}

export function createAddComponentPreset(
studioCtx: StudioCtx,
component: CodeComponent,
Expand Down Expand Up @@ -481,22 +530,9 @@ export function createAddInsertableTemplate(
label: meta.componentName,
canWrap: false,
icon: COMBINATION_ICON,
previewImage: meta.imageUrl ? (
<img
className={"no-pointer-events"}
style={{
position: "relative",
width: "100%",
height: "100%",
objectPosition: "center top",
objectFit: "contain",
minWidth: 0,
minHeight: 0,
}}
role={"img"}
src={meta.imageUrl}
/>
) : null,
previewImage: meta.imageUrl
? getAddTplItemPreviewImage(meta.imageUrl, "center top")
: null,
factory: (
vc: ViewCtx,
extraInfo: InsertableTemplateExtraInfo,
Expand Down Expand Up @@ -547,22 +583,9 @@ export function createAddTemplateComponent(
label: meta.displayName ?? meta.componentName,
canWrap: false,
icon: COMBINATION_ICON,
previewImage: meta.imageUrl ? (
<img
className={"no-pointer-events"}
style={{
position: "relative",
width: "100%",
height: "100%",
objectPosition: "center top",
objectFit: "contain",
minWidth: 0,
minHeight: 0,
}}
role={"img"}
src={meta.imageUrl}
/>
) : null,
previewImage: meta.imageUrl
? getAddTplItemPreviewImage(meta.imageUrl, "center top")
: null,
factory: (
vc: ViewCtx,
extraInfo: InsertableTemplateComponentExtraInfo,
Expand Down Expand Up @@ -639,21 +662,7 @@ export function createAddHostLessComponent(
icon: COMBINATION_ICON,
gray: meta.gray,
previewImage: meta.imageUrl ? (
<img
className={"no-pointer-events"}
style={{
position: "relative",
width: "100%",
height: "100%",
objectPosition: "center center",
objectFit: "contain",
minWidth: 0,
minHeight: 0,
pointerEvents: "none",
}}
role={"img"}
src={meta.imageUrl}
/>
getAddTplItemPreviewImage(meta.imageUrl, "center center")
) : meta.videoUrl ? (
<video
className={"no-pointer-events"}
Expand Down Expand Up @@ -737,20 +746,7 @@ export function createInstallOnlyPackage(
hostLessPackageInfo: packageMeta,
hostLessComponentInfo: meta,
previewImage: meta.imageUrl ? (
<img
style={{
position: "relative",
width: "100%",
height: "100%",
objectPosition: "center center",
objectFit: "contain",
minWidth: 0,
minHeight: 0,
pointerEvents: "none",
}}
role={"img"}
src={meta.imageUrl}
/>
getAddTplItemPreviewImage(meta.imageUrl, "center center")
) : meta.videoUrl ? (
<video
src={meta.videoUrl}
Expand Down Expand Up @@ -804,21 +800,7 @@ export function createFakeHostLessComponent(
monospaced: meta.monospaced,
description: meta.description,
previewImage: meta.imageUrl ? (
<img
className={"no-pointer-events"}
style={{
position: "relative",
width: "100%",
height: "100%",
objectPosition: "center center",
objectFit: "contain",
minWidth: 0,
minHeight: 0,
pointerEvents: "none",
}}
role={"img"}
src={meta.imageUrl}
/>
getAddTplItemPreviewImage(meta.imageUrl, "center center")
) : meta.videoUrl ? (
<video
className={"no-pointer-events"}
Expand Down Expand Up @@ -1485,20 +1467,9 @@ export function makePlumeInsertables(
asyncExtraInfo: async (_studioCtx, opts) => {
return { attachComponent: !opts?.isDragging };
},
previewImage: (
<img
src={getPlumeImage(component.plumeInfo.type)}
style={{
position: "relative",
width: "100%",
height: "100%",
objectPosition: "center center",
objectFit: "contain",
minWidth: 0,
minHeight: 0,
pointerEvents: "none",
}}
/>
previewImage: getAddTplItemPreviewImage(
getPlumeImage(component.plumeInfo.type),
"center center"
),
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface AddItemGroup {
codeName?: string;
codeLink?: string;
hostLessPackageInfo?: HostLessPackageInfo;
isHeaderLess?: boolean;
}

interface AddDrawerSectionProps {
Expand Down
2 changes: 1 addition & 1 deletion platform/wab/src/wab/client/components/widgets/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function Icon(
props: React.ComponentProps<"svg"> & {
monochromeExempt?: boolean;
icon: React.ComponentType<React.ComponentProps<"svg">>;
size?: number;
size?: number | string;
}
) {
const {
Expand Down
8 changes: 8 additions & 0 deletions platform/wab/src/wab/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2124,6 +2124,14 @@ export function isPlasmicComponent(component: Component) {
return !isFrameComponent(component) && !isCodeComponent(component);
}

export function isCodeComponentWithSection(
component: Component
): component is CodeComponent & {
codeComponentMeta: CodeComponentMeta & { section: string };
} {
return isCodeComponent(component) && !!component.codeComponentMeta.section;
}

export function isReusableComponent(component: Component) {
return !isFrameComponent(component) && !isPageComponent(component);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,8 @@ function refreshCodeComponentMeta(
c.codeComponentMeta.importName = meta.importName ?? null;
c.codeComponentMeta.displayName = meta.displayName ?? null;
c.codeComponentMeta.description = meta.description ?? null;
c.codeComponentMeta.section = meta.section ?? null;
c.codeComponentMeta.thumbnailUrl = meta.thumbnailUrl ?? null;
c.codeComponentMeta.isAttachment = !!meta.isAttachment;
c.codeComponentMeta.providesData = !!meta.providesData;
c.codeComponentMeta.isRepeatable = meta.isRepeatable ?? true;
Expand Down

0 comments on commit 8570d77

Please sign in to comment.