From b1322f15040539e42bf60515a5f5c5549f363c96 Mon Sep 17 00:00:00 2001 From: Baptiste Morelle Date: Thu, 19 Oct 2023 12:03:14 +0200 Subject: [PATCH] feat(slice-machine-ui): update Slice Builder layout --- cypress/e2e/slices/00-create.cy.js | 17 +-- .../scenario_custom_screenshots.cy.js | 6 +- cypress/helpers/slices.js | 1 - cypress/pages/slices/sliceBuilder.js | 20 +--- cypress/pages/slices/sliceCard.js | 10 +- .../components/ScreenshotPreview/index.tsx | 32 +++--- .../Header/VariationsPopover/MenuList.tsx | 0 .../Header/VariationsPopover/index.tsx | 0 .../Simulator/components/Header/index.tsx | 9 +- .../Simulator/components/Header}/links.ts | 0 .../SliceBuilder/FieldZones/index.tsx | 8 +- .../builders/SliceBuilder/Header/index.tsx | 64 ----------- .../SliceBuilder/SideBar/icons/prismic.svg | 12 --- .../SliceBuilder/SideBar/icons/sb-logo.png | Bin 23691 -> 0 bytes .../SliceBuilder/SideBar/icons/storybook.svg | 13 --- .../SideBar/icons/storybookGrey.svg | 13 --- .../builders/SliceBuilder/SideBar/index.tsx | 97 ----------------- .../{Header => Sidebar}/VariationModal.tsx | 0 .../builders/SliceBuilder/Sidebar/index.tsx | 86 +++++++++++++++ .../{Header => }/SimulatorButton/index.tsx | 0 .../lib/builders/SliceBuilder/index.tsx | 74 +++---------- .../lib/builders/common/Zone/Card/index.jsx | 4 +- .../Zone/components/ZoneHeader/index.tsx | 30 ------ .../lib/builders/common/Zone/index.jsx | 102 ++++++------------ .../src/components/List/List.css.ts | 1 + .../src/components/List/List.stories.tsx | 2 +- .../src/components/List/List.tsx | 2 +- .../slices/sliceCards/SharedSliceCard.tsx | 1 + .../src/hooks/useScreenshotChangesModal.ts | 2 - 29 files changed, 177 insertions(+), 429 deletions(-) rename packages/slice-machine/{lib/builders/SliceBuilder => components/Simulator/components}/Header/VariationsPopover/MenuList.tsx (100%) rename packages/slice-machine/{lib/builders/SliceBuilder => components/Simulator/components}/Header/VariationsPopover/index.tsx (100%) rename packages/slice-machine/{lib/builders/SliceBuilder => components/Simulator/components/Header}/links.ts (100%) delete mode 100644 packages/slice-machine/lib/builders/SliceBuilder/Header/index.tsx delete mode 100644 packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/prismic.svg delete mode 100644 packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/sb-logo.png delete mode 100644 packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybook.svg delete mode 100644 packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybookGrey.svg delete mode 100644 packages/slice-machine/lib/builders/SliceBuilder/SideBar/index.tsx rename packages/slice-machine/lib/builders/SliceBuilder/{Header => Sidebar}/VariationModal.tsx (100%) create mode 100644 packages/slice-machine/lib/builders/SliceBuilder/Sidebar/index.tsx rename packages/slice-machine/lib/builders/SliceBuilder/{Header => }/SimulatorButton/index.tsx (100%) delete mode 100644 packages/slice-machine/lib/builders/common/Zone/components/ZoneHeader/index.tsx diff --git a/cypress/e2e/slices/00-create.cy.js b/cypress/e2e/slices/00-create.cy.js index 2c4ae05ce0..db119e44ac 100644 --- a/cypress/e2e/slices/00-create.cy.js +++ b/cypress/e2e/slices/00-create.cy.js @@ -31,8 +31,7 @@ describe("Create Slices", () => { // add a variation - cy.get("button").contains("Default").click(); - cy.contains("+ Add new variation").click(); + cy.contains("button", "Add a new variation").click(); cy.getInputByLabel("Variation name*").type("foo"); cy.getInputByLabel("Variation ID*").clear(); @@ -47,20 +46,12 @@ describe("Create Slices", () => { "contain", "Save your work in order to simulate", ); - cy.contains("button", "Update screenshot").should("have.attr", "disabled"); - cy.contains("button", "Update screenshot").realHover(); - cy.get("#update-screenshot-button-tooltip").should("be.visible"); - cy.get("#update-screenshot-button-tooltip").should( - "contain", - "Save your work in order to update the screenshot", - ); cy.location("pathname", { timeout: 20000 }).should( "eq", `/slices/${lib}/${sliceName}/bar`, ); - cy.get("button").contains("foo").click(); - cy.contains("Default").click(); + cy.contains("a", "Default").click(); cy.location("pathname", { timeout: 20000 }).should( "eq", `/slices/${lib}/${sliceName}/default`, @@ -69,10 +60,6 @@ describe("Create Slices", () => { cy.contains("Save").click(); cy.contains("button", "Simulate").should("not.have.attr", "disabled"); - cy.contains("button", "Update screenshot").should( - "not.have.attr", - "disabled", - ); // simulator diff --git a/cypress/e2e/user-flows/scenario_custom_screenshots.cy.js b/cypress/e2e/user-flows/scenario_custom_screenshots.cy.js index cbdbf1068f..a683cc6869 100644 --- a/cypress/e2e/user-flows/scenario_custom_screenshots.cy.js +++ b/cypress/e2e/user-flows/scenario_custom_screenshots.cy.js @@ -71,11 +71,13 @@ describe("I am an existing SM user and I want to upload screenshots on variation }); it("Error displayed when non-image files are uploaded", () => { + const variationName = "Error handling"; + sliceBuilder.goTo(slice.library, slice.name); - sliceBuilder.addVariation("Error handling"); + sliceBuilder.addVariation(variationName); sliceBuilder.save(); - sliceBuilder.openScreenshotModal(); + new SliceCard(slice.name, variationName).openScreenshotModal(); cy.contains("Select file").selectFile( { contents: Cypress.Buffer.from("this is not an image"), diff --git a/cypress/helpers/slices.js b/cypress/helpers/slices.js index c68da17d05..81443d7573 100644 --- a/cypress/helpers/slices.js +++ b/cypress/helpers/slices.js @@ -121,7 +121,6 @@ function addFieldToSlice(elements, fieldType, fieldName, fieldId) { * @param {string} variationName Name of the variation. */ export function addVariationToSlice(variationName) { - sliceBuilder.variationsDropdown.click({ force: true }); sliceBuilder.addVariationButton.click(); addVariationModal.root.within(() => { diff --git a/cypress/pages/slices/sliceBuilder.js b/cypress/pages/slices/sliceBuilder.js index c12ecbaa60..9780748f9e 100644 --- a/cypress/pages/slices/sliceBuilder.js +++ b/cypress/pages/slices/sliceBuilder.js @@ -35,12 +35,8 @@ class SliceBuilder extends BaseBuilder { return cy.get("[data-cy=add-Repeatable-field]"); } - get variationsDropdown() { - return cy.get("[aria-label='Expand variations']"); - } - get addVariationButton() { - return cy.contains("button", "Add new variation"); + return cy.contains("button", "Add a new variation"); } goTo(sliceLibrary, sliceName, variation = "default") { @@ -50,17 +46,6 @@ class SliceBuilder extends BaseBuilder { return this; } - openScreenshotModal() { - cy.contains("Update screenshot").click(); - return this; - } - - openVariationModal() { - cy.get("[aria-label='Expand variations']").parent().click(); - cy.contains("Add new variation").click(); - return this; - } - changeToVariation(startVariation, targetVariation) { cy.get("button").contains(startVariation).click(); cy.contains(targetVariation).click(); @@ -103,8 +88,7 @@ class SliceBuilder extends BaseBuilder { * @param {string} variationName Name of the variation. */ addVariation(variationName) { - cy.get("[aria-label='Expand variations']").click({ force: true }); - cy.contains("button", "Add new variation").click(); + cy.contains("button", "Add a new variation").click(); cy.get("[aria-modal]").within(() => { cy.getInputByLabel("Variation name*").type(variationName); diff --git a/cypress/pages/slices/sliceCard.js b/cypress/pages/slices/sliceCard.js index 435fa4507c..04723918de 100644 --- a/cypress/pages/slices/sliceCard.js +++ b/cypress/pages/slices/sliceCard.js @@ -1,6 +1,9 @@ export class SliceCard { - constructor(sliceName) { - this.root = `[aria-label="${sliceName} slice card"]`; + constructor(sliceName, variationName) { + this.root = + variationName !== undefined + ? `[aria-label="${sliceName} ${variationName} slice card"]` + : `[aria-label^="${sliceName}"][aria-label$="slice card"]`; } get content() { @@ -12,7 +15,8 @@ export class SliceCard { } openScreenshotModal() { - cy.get(this.root).contains("Update screenshot").click(); + cy.get(this.root).find('[aria-haspopup="menu"]').click(); + cy.contains("Update screenshot").click(); return this; } } diff --git a/packages/slice-machine/components/ScreenshotPreview/index.tsx b/packages/slice-machine/components/ScreenshotPreview/index.tsx index b4b2b79264..086cd7ff95 100644 --- a/packages/slice-machine/components/ScreenshotPreview/index.tsx +++ b/packages/slice-machine/components/ScreenshotPreview/index.tsx @@ -9,11 +9,9 @@ const MemoedImage = memo<{ src: string | undefined }>(({ src }) => ( interface ScreenshotPreviewProps { src?: string; sx: { height: string | number } & ThemeUIStyleObject; - hideMissingWarning?: boolean; } export const ScreenshotPreview: React.FC = ({ - hideMissingWarning = false, src, sx, }) => { @@ -32,23 +30,19 @@ export const ScreenshotPreview: React.FC = ({ ...sx, }} > - {hideMissingWarning ? null : ( - <> - {src !== undefined ? ( - - ) : ( - - - You have no screenshot yet. - - )} - + {src !== undefined ? ( + + ) : ( + + + You have no screenshot yet. + )} ); diff --git a/packages/slice-machine/lib/builders/SliceBuilder/Header/VariationsPopover/MenuList.tsx b/packages/slice-machine/components/Simulator/components/Header/VariationsPopover/MenuList.tsx similarity index 100% rename from packages/slice-machine/lib/builders/SliceBuilder/Header/VariationsPopover/MenuList.tsx rename to packages/slice-machine/components/Simulator/components/Header/VariationsPopover/MenuList.tsx diff --git a/packages/slice-machine/lib/builders/SliceBuilder/Header/VariationsPopover/index.tsx b/packages/slice-machine/components/Simulator/components/Header/VariationsPopover/index.tsx similarity index 100% rename from packages/slice-machine/lib/builders/SliceBuilder/Header/VariationsPopover/index.tsx rename to packages/slice-machine/components/Simulator/components/Header/VariationsPopover/index.tsx diff --git a/packages/slice-machine/components/Simulator/components/Header/index.tsx b/packages/slice-machine/components/Simulator/components/Header/index.tsx index 2f525d496f..f1c5cbe958 100644 --- a/packages/slice-machine/components/Simulator/components/Header/index.tsx +++ b/packages/slice-machine/components/Simulator/components/Header/index.tsx @@ -1,16 +1,15 @@ import router from "next/router"; import { Text, Flex, Switch, Label } from "theme-ui"; -import VarationsPopover from "@lib/builders/SliceBuilder/Header/VariationsPopover"; -import { ComponentUI } from "@lib/models/common/ComponentUI"; - import { Button } from "@components/Button"; +import VariationsPopover from "@components/Simulator/components/Header/VariationsPopover"; +import * as Links from "@components/Simulator/components/Header/links"; import SliceMachineLogo from "@src/icons/SliceMachineLogo"; import { useSelector } from "react-redux"; import { selectSavingMock } from "@src/modules/simulator"; -import * as Links from "@lib/builders/SliceBuilder/links"; import { SliceMachineStoreType } from "@src/redux/type"; +import { ComponentUI } from "@lib/models/common/ComponentUI"; import { VariationSM } from "@lib/models/common/Slice"; const redirect = ( @@ -80,7 +79,7 @@ const Header: React.FunctionComponent = ({ > {slice.model.name} - redirect(slice, v, true)} diff --git a/packages/slice-machine/lib/builders/SliceBuilder/links.ts b/packages/slice-machine/components/Simulator/components/Header/links.ts similarity index 100% rename from packages/slice-machine/lib/builders/SliceBuilder/links.ts rename to packages/slice-machine/components/Simulator/components/Header/links.ts diff --git a/packages/slice-machine/lib/builders/SliceBuilder/FieldZones/index.tsx b/packages/slice-machine/lib/builders/SliceBuilder/FieldZones/index.tsx index 98165959f7..1fb204e5bd 100644 --- a/packages/slice-machine/lib/builders/SliceBuilder/FieldZones/index.tsx +++ b/packages/slice-machine/lib/builders/SliceBuilder/FieldZones/index.tsx @@ -1,5 +1,3 @@ -import { Box } from "theme-ui"; - import { ensureDnDDestination } from "@lib/utils"; import { transformKeyAccessor } from "@utils/str"; @@ -10,6 +8,7 @@ import * as Widgets from "@lib/models/common/widgets"; import sliceBuilderWidgetsArray from "@lib/models/common/widgets/sliceBuilderArray"; import { DropResult } from "react-beautiful-dnd"; +import { List } from "@src/components/List"; import useSliceMachineActions from "@src/modules/useSliceMachineActions"; import { VariationSM, WidgetsArea } from "@lib/models/common/Slice"; @@ -118,7 +117,7 @@ const FieldZones: React.FunctionComponent = ({ }; return ( - <> + = ({ dataCy="slice-non-repeatable-zone" isRepeatableCustomType={undefined} /> - = ({ dataCy="slice-repeatable-zone" isRepeatableCustomType={undefined} /> - + ); }; diff --git a/packages/slice-machine/lib/builders/SliceBuilder/Header/index.tsx b/packages/slice-machine/lib/builders/SliceBuilder/Header/index.tsx deleted file mode 100644 index 1203c6ff99..0000000000 --- a/packages/slice-machine/lib/builders/SliceBuilder/Header/index.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { useState } from "react"; -import { Box, Flex, Text } from "theme-ui"; -import VariationModal from "./VariationModal"; -import { useRouter } from "next/router"; -import * as Links from "../links"; -import VariationPopover from "./VariationsPopover"; -import useSliceMachineActions from "@src/modules/useSliceMachineActions"; -import { VariationSM } from "@lib/models/common/Slice"; -import { ComponentUI } from "@lib/models/common/ComponentUI"; -import { ModelStatus } from "@lib/models/common/ModelStatus"; - -const Header: React.FC<{ - component: ComponentUI; - status: ModelStatus; - variation: VariationSM; - imageLoading?: boolean; -}> = ({ component, variation }) => { - const router = useRouter(); - const [showVariationModal, setShowVariationModal] = useState(false); - - const { copyVariationSlice } = useSliceMachineActions(); - - return ( - <> - - setShowVariationModal(true)} - onChange={(v) => - void router.push( - ...Links.variation({ - lib: component.href, - sliceName: component.model.name, - variationId: v.id, - }).all, - ) - } - /> - - Variation id : {variation.id} - - - - setShowVariationModal(false)} - onSubmit={(id, name, copiedVariation) => { - copyVariationSlice(id, name, copiedVariation); - void router.push( - ...Links.variation({ - lib: component.href, - sliceName: component.model.name, - variationId: id, - }).all, - ); - }} - initialVariation={variation} - variations={component.model.variations} - /> - - ); -}; -export default Header; diff --git a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/prismic.svg b/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/prismic.svg deleted file mode 100644 index 4522f56063..0000000000 --- a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/prismic.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - Group - - - - - - - - - \ No newline at end of file diff --git a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/sb-logo.png b/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/sb-logo.png deleted file mode 100644 index 9201193134c0f94a842c4f929b9c23f62060e0d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23691 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

v~@_a&Z9cf5AZfpjZJAgT?MtJoO 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 diff --git a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybook.svg b/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybook.svg deleted file mode 100644 index a5121d4fbf..0000000000 --- a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybook.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybookGrey.svg b/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybookGrey.svg deleted file mode 100644 index 857f5b9422..0000000000 --- a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/icons/storybookGrey.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/index.tsx b/packages/slice-machine/lib/builders/SliceBuilder/SideBar/index.tsx deleted file mode 100644 index 9a8c46d56c..0000000000 --- a/packages/slice-machine/lib/builders/SliceBuilder/SideBar/index.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React from "react"; - -import { Box, Flex } from "theme-ui"; - -import Card from "@components/Card"; -import { ReactTooltipPortal } from "@components/ReactTooltipPortal"; - -import { ScreenshotPreview } from "@components/ScreenshotPreview"; - -import { ComponentUI } from "@lib/models/common/ComponentUI"; -import ScreenshotChangesModal from "@components/ScreenshotChangesModal"; -import { useScreenshotChangesModal } from "@src/hooks/useScreenshotChangesModal"; -import { Button } from "@components/Button"; -import { AiOutlineCamera } from "react-icons/ai"; -import { VariationSM } from "@lib/models/common/Slice"; -import ReactTooltip from "react-tooltip"; - -type SideBarProps = { - component: ComponentUI; - variation: VariationSM; - isTouched: boolean; -}; - -const NeedToSaveTooltip: React.FC = () => ( - - - Save your work in order to update the screenshot - - -); - -const SideBar: React.FunctionComponent = ({ - component, - variation, - isTouched, -}) => { - const { screenshots } = component; - const { openScreenshotsModal } = useScreenshotChangesModal(); - - return ( - - ( - <> - - + + + { + setShowVariationModal(false); + }} + onSubmit={(id, name, copiedVariation) => { + copyVariationSlice(id, name, copiedVariation); + const url = SLICES_CONFIG.getBuilderPagePathname({ + libraryName: slice.href, + sliceName: slice.model.name, + variationId: variation.id, + }); + void router.replace(url); + }} + variations={slice.model.variations} + /> + + ); +}; diff --git a/packages/slice-machine/lib/builders/SliceBuilder/Header/SimulatorButton/index.tsx b/packages/slice-machine/lib/builders/SliceBuilder/SimulatorButton/index.tsx similarity index 100% rename from packages/slice-machine/lib/builders/SliceBuilder/Header/SimulatorButton/index.tsx rename to packages/slice-machine/lib/builders/SliceBuilder/SimulatorButton/index.tsx diff --git a/packages/slice-machine/lib/builders/SliceBuilder/index.tsx b/packages/slice-machine/lib/builders/SliceBuilder/index.tsx index 4fa5466809..075061dfaf 100644 --- a/packages/slice-machine/lib/builders/SliceBuilder/index.tsx +++ b/packages/slice-machine/lib/builders/SliceBuilder/index.tsx @@ -1,18 +1,16 @@ -import { Button } from "@prismicio/editor-ui"; +import { Box, Button } from "@prismicio/editor-ui"; import React, { useState, useEffect } from "react"; import { handleRemoteResponse } from "@src/modules/toaster/utils"; -import { BaseStyles, Box, Grid } from "theme-ui"; - import FieldZones from "./FieldZones"; -import SideBar from "./SideBar"; -import Header from "./Header"; +import { Sidebar } from "./Sidebar"; import useSliceMachineActions from "src/modules/useSliceMachineActions"; import { useSelector } from "react-redux"; import { SliceMachineStoreType } from "@src/redux/type"; +import SimulatorButton from "@builders/SliceBuilder/SimulatorButton"; import { AppLayout, AppLayoutActions, @@ -21,44 +19,28 @@ import { AppLayoutContent, AppLayoutHeader, } from "@components/AppLayout"; -import SimulatorButton from "@lib/builders/SliceBuilder/Header/SimulatorButton"; -import { SliceSM, VariationSM } from "@lib/models/common/Slice"; +import { VariationSM } from "@lib/models/common/Slice"; import { ComponentUI } from "@lib/models/common/ComponentUI"; import { FloatingBackButton } from "@src/features/slices/sliceBuilder/FloatingBackButton"; import { selectIsSimulatorAvailableForFramework } from "@src/modules/environment"; import { isSelectedSliceTouched } from "@src/modules/selectedSlice/selectors"; -import { getRemoteSlice } from "@src/modules/slices"; -import { useModelStatus } from "@src/hooks/useModelStatus"; import { ComponentWithSliceProps } from "@src/layouts/WithSlice"; -import { - LocalAndRemoteSlice, - LocalOnlySlice, -} from "@lib/models/common/ModelData"; export type SliceBuilderState = { - imageLoading: boolean; loading: boolean; done: boolean; - error: null | string; - status: number | null; }; export const initialState: SliceBuilderState = { - imageLoading: false, loading: false, done: false, - error: null, - status: null, }; const SliceBuilder: ComponentWithSliceProps = ({ slice, variation }) => { const { openToaster, updateSlice } = useSliceMachineActions(); - const { isTouched, remoteSlice } = useSelector( - (store: SliceMachineStoreType) => ({ - isTouched: isSelectedSliceTouched(store, slice.from, slice.model.id), - remoteSlice: getRemoteSlice(store, slice.model.id), - }), + const isTouched = useSelector((store: SliceMachineStoreType) => + isSelectedSliceTouched(store, slice.from, slice.model.id), ); // We need to move this state to somewhere global to update the UI if any action from anywhere save or update to the filesystem I'd guess @@ -88,7 +70,6 @@ const SliceBuilder: ComponentWithSliceProps = ({ slice, variation }) => { updateSlice={updateSlice.bind(null, slice, setData)} slice={slice} variation={variation} - remoteSlice={remoteSlice} isTouched={isTouched} data={data} /> @@ -99,7 +80,6 @@ type SliceBuilderForVariationProps = { updateSlice: () => void; slice: ComponentUI; variation: VariationSM; - remoteSlice: SliceSM | undefined; isTouched: boolean; data: SliceBuilderState; }; @@ -107,24 +87,13 @@ const SliceBuilderForVariation: React.FC = ({ updateSlice, slice, variation, - remoteSlice, isTouched, data, }) => { - const { isSimulatorAvailableForFramework } = useSelector( - (state: SliceMachineStoreType) => ({ - isSimulatorAvailableForFramework: - selectIsSimulatorAvailableForFramework(state), - }), + const isSimulatorAvailableForFramework = useSelector( + selectIsSimulatorAvailableForFramework, ); - const sliceModel: LocalAndRemoteSlice | LocalOnlySlice = { - local: slice.model, - localScreenshots: slice.screenshots, - ...(remoteSlice ? { remote: remoteSlice } : {}), - }; - const { modelsStatuses } = useModelStatus({ slices: [sliceModel] }); - return ( @@ -146,24 +115,15 @@ const SliceBuilderForVariation: React.FC = ({ - -

- - - - - - - + + + + diff --git a/packages/slice-machine/lib/builders/common/Zone/Card/index.jsx b/packages/slice-machine/lib/builders/common/Zone/Card/index.jsx index 4a47905377..5a7dc1ed59 100644 --- a/packages/slice-machine/lib/builders/common/Zone/Card/index.jsx +++ b/packages/slice-machine/lib/builders/common/Zone/Card/index.jsx @@ -23,7 +23,6 @@ const FieldZone = ({ isRepeatable, dataCy, isRepeatableCustomType, - sx, }) => { return ( { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call diff --git a/packages/slice-machine/lib/builders/common/Zone/components/ZoneHeader/index.tsx b/packages/slice-machine/lib/builders/common/Zone/components/ZoneHeader/index.tsx deleted file mode 100644 index 408d642c63..0000000000 --- a/packages/slice-machine/lib/builders/common/Zone/components/ZoneHeader/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Flex } from "theme-ui"; - -interface ZoneHeaderProps { - Heading: JSX.Element; - Actions: JSX.Element; -} - -const ZoneHeader: React.FunctionComponent = ({ - Heading, - Actions, -}) => ( - - {Heading} - {Actions} - -); - -export default ZoneHeader; diff --git a/packages/slice-machine/lib/builders/common/Zone/index.jsx b/packages/slice-machine/lib/builders/common/Zone/index.jsx index 441c8706f7..e164ae4993 100644 --- a/packages/slice-machine/lib/builders/common/Zone/index.jsx +++ b/packages/slice-machine/lib/builders/common/Zone/index.jsx @@ -1,7 +1,7 @@ -import { Button, ButtonGroup, Switch, Text } from "@prismicio/editor-ui"; +import { Button, Switch, Text } from "@prismicio/editor-ui"; import { array, arrayOf, bool, func, object, shape, string } from "prop-types"; import { useState } from "react"; -import { BaseStyles, Heading } from "theme-ui"; +import { BaseStyles } from "theme-ui"; import { ListHeader } from "@src/components/List"; @@ -9,7 +9,6 @@ import SelectFieldTypeModal from "../SelectFieldTypeModal"; import NewField from "./Card/components/NewField"; import Card from "./Card"; import EmptyState from "./components/EmptyState"; -import ZoneHeader from "./components/ZoneHeader"; const Zone = ({ zoneType /* type of the zone: customType or slice */, @@ -30,8 +29,6 @@ const Zone = ({ dataCy, isRepeatableCustomType, }) => { - const isCustomType = zoneType === "customType"; - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const widgetsArrayWithCondUid = (() => { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument @@ -74,68 +71,38 @@ const Zone = ({ return ( <> - {isCustomType ? ( - 0 ? ( - <> - - Show code snippets? - - - - - ) : undefined - } - > - {title} - - ) : ( - - {title}} - Actions={ - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - fields.length > 0 ? ( - - - - - ) : null - } - /> - - )} + 0 ? ( + <> + + Show code snippets? + + + + + ) : undefined + } + > + {title} + { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/strict-boolean-expressions fields.length === 0 && !newFieldData ? ( @@ -191,7 +158,6 @@ const Zone = ({ /> ) } - sx={isCustomType ? { paddingInline: "16px !important" } : {}} /> ) : undefined diff --git a/packages/slice-machine/src/components/List/List.css.ts b/packages/slice-machine/src/components/List/List.css.ts index 26f31ca4d2..226e09c6a1 100644 --- a/packages/slice-machine/src/components/List/List.css.ts +++ b/packages/slice-machine/src/components/List/List.css.ts @@ -64,6 +64,7 @@ export const headerActions = style([ flexGrow: 1, gap: 8, justifyContent: "end", + minWidth: 0, }), ]); diff --git a/packages/slice-machine/src/components/List/List.stories.tsx b/packages/slice-machine/src/components/List/List.stories.tsx index 79cc81e196..fb9f1147bb 100644 --- a/packages/slice-machine/src/components/List/List.stories.tsx +++ b/packages/slice-machine/src/components/List/List.stories.tsx @@ -19,7 +19,7 @@ export const Default = { - + Show code snippets? diff --git a/packages/slice-machine/src/components/List/List.tsx b/packages/slice-machine/src/components/List/List.tsx index 10ff5a16bd..681ce7efd1 100644 --- a/packages/slice-machine/src/components/List/List.tsx +++ b/packages/slice-machine/src/components/List/List.tsx @@ -23,7 +23,7 @@ export const ListHeader: FC = ({ ...otherProps }) => (
- + {children} {toggle} diff --git a/packages/slice-machine/src/features/slices/sliceCards/SharedSliceCard.tsx b/packages/slice-machine/src/features/slices/sliceCards/SharedSliceCard.tsx index 783cae52a3..2077f0ca96 100644 --- a/packages/slice-machine/src/features/slices/sliceCards/SharedSliceCard.tsx +++ b/packages/slice-machine/src/features/slices/sliceCards/SharedSliceCard.tsx @@ -107,6 +107,7 @@ export const SharedSliceCard: FC = (props) => { return ( void; - openScreenshotsModal: () => void; }; export const useScreenshotChangesModal = (): Payload => { @@ -29,6 +28,5 @@ export const useScreenshotChangesModal = (): Payload => { return { modalPayload, onOpenModal, - openScreenshotsModal, }; };