Skip to content

Commit

Permalink
refactor: use primitives in SlateGrid
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonas-C committed Oct 8, 2024
1 parent 9497ec9 commit 5dd3fef
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 72 deletions.
87 changes: 46 additions & 41 deletions src/components/SlateEditor/plugins/grid/SlateGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,39 @@ import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { Editor, Path, Transforms } from "slate";
import { ReactEditor, RenderElementProps } from "slate-react";
import styled from "@emotion/styled";
import { spacing } from "@ndla/core";
import { Portal } from "@ark-ui/react";
import { Pencil } from "@ndla/icons/action";
import { Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalTitle, ModalTrigger } from "@ndla/modal";
import { IconButton } from "@ndla/primitives";
import {
DialogBody,
DialogContent,
DialogHeader,
DialogRoot,
DialogTitle,
DialogTrigger,
IconButton,
} from "@ndla/primitives";
import { styled } from "@ndla/styled-system/jsx";
import { EmbedWrapper, Grid, GridType } from "@ndla/ui";
import { GridElement } from ".";
import { GridProvider } from "./GridContext";
import GridForm from "./GridForm";
import DeleteButton from "../../../DeleteButton";
import { DialogCloseButton } from "../../../DialogCloseButton";

interface Props extends RenderElementProps {
element: GridElement;
editor: Editor;
}

const StyledModalHeader = styled(ModalHeader)`
padding-bottom: 0px;
`;

const StyledModalBody = styled(ModalBody)`
padding-top: 0px;
`;

const ButtonContainer = styled.div`
display: flex;
flex-direction: column;
position: absolute;
right: -${spacing.large};
`;
const ButtonContainer = styled("div", {
base: {
display: "flex",
flexDirection: "column",
position: "absolute",
right: "-xlarge",
gap: "3xsmall",
},
});

export const SlateGrid = ({ element, editor, children }: Props) => {
const { t } = useTranslation();
Expand Down Expand Up @@ -78,31 +81,33 @@ export const SlateGrid = ({ element, editor, children }: Props) => {
);

return (
<EmbedWrapper>
<ButtonContainer>
<DeleteButton aria-label={t("delete")} data-testid="remove-grid" onClick={handleRemove} />
<Modal open={isEditing} onOpenChange={setIsEditing}>
<ModalTrigger>
<DialogRoot open={isEditing} size="small" onOpenChange={(details) => setIsEditing(details.open)}>
<EmbedWrapper>
<ButtonContainer>
<DeleteButton aria-label={t("delete")} data-testid="remove-grid" onClick={handleRemove} />
<DialogTrigger asChild>
<IconButton variant="tertiary" aria-label={t("gridForm.title")} data-testid="edit-grid-button" size="small">
<Pencil />
</IconButton>
</ModalTrigger>
<ModalContent size="small">
<StyledModalHeader>
<ModalTitle>{t("gridForm.title")}</ModalTitle>
<ModalCloseButton />
</StyledModalHeader>
<StyledModalBody>
<GridForm onCancel={onClose} initialData={element.data} onSave={onSave} />
</StyledModalBody>
</ModalContent>
</Modal>
</ButtonContainer>
<GridProvider value={true}>
<Grid border="none" columns={element.data.columns} background={element.data.background}>
{children}
</Grid>
</GridProvider>
</EmbedWrapper>
</DialogTrigger>
<Portal>
<DialogContent>
<DialogHeader>
<DialogTitle>{t("gridForm.title")}</DialogTitle>
<DialogCloseButton />
</DialogHeader>
<DialogBody>
<GridForm onCancel={onClose} initialData={element.data} onSave={onSave} />
</DialogBody>
</DialogContent>
</Portal>
</ButtonContainer>
<GridProvider value={true}>
<Grid border="none" columns={element.data.columns} background={element.data.background}>
{children}
</Grid>
</GridProvider>
</EmbedWrapper>
</DialogRoot>
);
};
52 changes: 21 additions & 31 deletions src/components/SlateEditor/plugins/grid/SlateGridCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,24 @@ import { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Editor, Transforms } from "slate";
import { ReactEditor, RenderElementProps } from "slate-react";
import styled from "@emotion/styled";
import { spacing, colors, stackOrder } from "@ndla/core";
import { Pin } from "@ndla/icons/common";
import { IconButton } from "@ndla/primitives";
import { styled } from "@ndla/styled-system/jsx";
import { GridCellElement } from ".";

interface Props extends RenderElementProps {
editor: Editor;
element: GridCellElement;
}

const StyledButton = styled(IconButton)`
position: absolute;
z-index: ${stackOrder.offsetDouble};
top: ${spacing.xxsmall};
right: ${spacing.xxsmall};
`;
const StyledIconButton = styled(IconButton, {
base: {
position: "absolute",
zIndex: "docked",
top: "xxsmall",
right: "xxsmall",
},
});

// TODO: Having the sticky button messes with the actual styling of the cell (I think)
// TODO: We seem to render empty paragraphs in the grid cells, which messes with margin.
Expand All @@ -46,7 +47,7 @@ const GridCell = ({ element, editor, attributes, children }: Props) => {

return (
<StyledGridCell {...attributes} data-testid="slate-grid-cell">
<StyledButton
<StyledIconButton
contentEditable={false}
onClick={onClickSticky}
variant={element.data?.parallaxCell === "true" ? "primary" : "tertiary"}
Expand All @@ -56,32 +57,21 @@ const GridCell = ({ element, editor, attributes, children }: Props) => {
data-testid="grid-cell-parallax"
>
<Pin />
</StyledButton>
</StyledIconButton>
{children}
</StyledGridCell>
);
};

const StyledGridCell = styled.div`
position: relative;
display: flex;
flex-direction: column;
border: 1px solid ${colors.brand.light};
min-width: 50px;
overflow-wrap: break-word;
> p {
padding: 0 ${spacing.xxsmall};
word-break: break-word;
}
> div,
> figure,
> iframe {
width: 100% !important;
inset: 0;
}
`;
const StyledGridCell = styled("div", {
base: {
position: "relative",
display: "flex",
flexDirection: "column",
border: "1px solid",
borderColor: "stroke.default",
minWidth: "xxlarge",
},
});

export default GridCell;

0 comments on commit 5dd3fef

Please sign in to comment.