Skip to content

Commit

Permalink
pass slate attributes correctly and redesign rich text component
Browse files Browse the repository at this point in the history
  • Loading branch information
Southclaws committed Nov 26, 2023
1 parent f01bddf commit d98edd7
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 75 deletions.
23 changes: 0 additions & 23 deletions web/src/components/content/ContentComposer/ContentComposer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { PropsWithChildren, useCallback } from "react";
import { Editor, Transforms } from "slate";
import { Editable, Slate } from "slate-react";

import { Box } from "@/styled-system/jsx";
Expand All @@ -8,7 +7,6 @@ import { FileDrop } from "./components/FileDrop/FileDrop";
import { Element } from "./render/Element";
import { Leaf } from "./render/Leaf";
import { Props, useContentComposer } from "./useContentComposer";
import { getURL } from "./utils";

export function ContentComposer({
disabled,
Expand All @@ -35,27 +33,6 @@ export function ContentComposer({
<Editable
renderLeaf={renderLeaf}
renderElement={renderElement}
// onKeyDown={(event: React.KeyboardEvent<HTMLElement>) => {
// // NOTE: this hook prevents Slate from duplicating the previous
// // node (which results in images being duplicated.)

// if (event.key === "Enter") {
// event.preventDefault();

// console.log("enter", editor.selection);

// Transforms.insertNodes(editor, [
// {
// type: "paragraph",
// children: [
// {
// text: "",
// },
// ],
// },
// ]);
// }
// }}
readOnly={disabled}
placeholder="Write your heart out..."
style={{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import { PropsWithChildren } from "react";
import { useFocused, useSelected } from "slate-react";
import { RenderElementProps, useFocused, useSelected } from "slate-react";

import { Box, styled } from "@/styled-system/jsx";
import { Box, Flex, styled } from "@/styled-system/jsx";

import { Props, useRichLink } from "./useRichLink";

export function RichLink(props: PropsWithChildren<Props>) {
export function RichLink(props: PropsWithChildren<Props & RenderElementProps>) {
const selected = useSelected();
const focused = useFocused();
const { link } = useRichLink(props);

if (!link) {
return (
<styled.a bgColor="accent.100" borderRadius="sm" px="1" href={props.href}>
<styled.a
bgColor="zinc.100"
borderRadius="sm"
color="gray.500"
lineClamp={1}
px="1"
contentEditable={true}
suppressContentEditableWarning
href={props.href}
{...props.attributes}
>
{props.href} {props.children}
</styled.a>
);
Expand All @@ -25,13 +35,15 @@ export function RichLink(props: PropsWithChildren<Props>) {
contentEditable={false}
data-selected={selected && focused}
display="flex"
flexDir="column"
gap="1"
w="full"
bgColor="accent.100"
bgColor="zinc.100"
borderRadius="md"
overflow="hidden"
outlineStyle="solid"
outlineWidth="medium"
outlineColor="accent.100"
outlineColor="gray.100"
mb="2"
css={{
"&[data-selected=true]": {
Expand All @@ -41,47 +53,52 @@ export function RichLink(props: PropsWithChildren<Props>) {
outlineColor: "accent.200",
},
}}
{...props.attributes}
>
<styled.span
color="gray.600"
color="gray.500"
lineClamp={1}
px="1"
contentEditable={true}
suppressContentEditableWarning
>
{props.children}
{props.href} {props.children}
</styled.span>

{asset && (
<Box flexGrow="1" flexShrink="0" width="32">
<styled.img
src={asset.url}
height="full"
width="full"
objectPosition="center"
objectFit="cover"
/>
</Box>
)}
<Flex gap="2">
{asset && (
<Box flexGrow="1" flexShrink="0" width="32">
<styled.img
src={asset.url}
height="full"
width="full"
objectPosition="center"
objectFit="cover"
/>
</Box>
)}

<styled.p
display="flex"
flexDir="column"
w="full"
justifyContent="space-evenly"
gap="0"
p="2"
>
<styled.span lineClamp={1} fontSize="md" fontWeight="bold">
<styled.a href={link.url} target="=_blank">
{link.title || link.url}
</styled.a>
</styled.span>
<styled.p
display="flex"
flexDir="column"
justifyContent="space-evenly"
alignItems="start"
w="full"
h="full"
gap="1"
>
<styled.span lineClamp={1} fontSize="md" fontWeight="bold">
<styled.a href={link.url} target="=_blank">
{link.title || link.url}
</styled.a>
</styled.span>

<styled.span lineClamp={2}>
{link.description || "(No description)"} <br />
<br />
</styled.span>
</styled.p>
<styled.span lineClamp={2}>
{link.description || "(No description)"} <br />
<br />
</styled.span>
</styled.p>
</Flex>
</styled.article>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { Link } from "src/api/openapi/schemas";

export type Props = {
href: string;
initial?: Link;
};

async function hydrateLink(url: string) {
return await linkCreate({ url });
}

export function useRichLink({ href }: Props) {
const [link, setLink] = useState<Link | undefined>(undefined);
export function useRichLink({ href, initial }: Props) {
const [link, setLink] = useState<Link | undefined>(initial);

useEffect(() => {
hydrateLink(href).then(setLink).catch();
Expand Down
31 changes: 18 additions & 13 deletions web/src/components/content/ContentComposer/render/Element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,26 @@ import { getURL } from "../utils";
import { styled } from "@/styled-system/jsx";

export function Element({
attributes,
children,
element,
...props
}: PropsWithChildren<RenderElementProps>) {
switch (element.type) {
switch (props.element.type) {
case "paragraph": {
const url = getURL(element);
const url = getURL(props.element);
if (url) {
return <RichLink href={url}>{children}</RichLink>;
return (
<RichLink {...props} href={url}>
{children}
</RichLink>
);
}

return <styled.p {...attributes}>{children}</styled.p>;
return <styled.p {...props.attributes}>{children}</styled.p>;
}

case "link":
return (
<a href={element.link} {...attributes}>
<a href={props.element.link} {...props.attributes}>
{children}
</a>
);
Expand All @@ -47,24 +50,26 @@ export function Element({
return <h6>{children}</h6>;

case "ol_list":
return <styled.ol {...attributes}>{children}</styled.ol>;
return <styled.ol {...props.attributes}>{children}</styled.ol>;

case "ul_list":
return <styled.ul {...attributes}>{children}</styled.ul>;
return <styled.ul {...props.attributes}>{children}</styled.ul>;

case "list_item":
return <styled.li {...attributes}>{children}</styled.li>;
return <styled.li {...props.attributes}>{children}</styled.li>;

case "image":
return (
<>
<styled.img src={element.link} alt="" {...attributes} />
<styled.img src={props.element.link} alt="" {...props.attributes} />
{children}
</>
);

case "block_quote":
return <styled.blockquote {...attributes}>{children}</styled.blockquote>;
return (
<styled.blockquote {...props.attributes}>{children}</styled.blockquote>
);

case "code_block":
return (
Expand All @@ -77,7 +82,7 @@ export function Element({
return <hr />;

default:
console.error("Unknown markdown element rendered", element);
console.error("Unknown markdown element rendered", props.element);
return null;
}
}
3 changes: 3 additions & 0 deletions web/src/components/content/ContentComposer/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ export const withExtensions = (editor: BaseEditor & ReactEditor) => {
},
);

Transforms.deselect(editor);
Transforms.select(editor, nextNodePath);

return;
}

Expand Down

0 comments on commit d98edd7

Please sign in to comment.