Skip to content

Commit

Permalink
Chore/modify editor drawer context (#219)
Browse files Browse the repository at this point in the history
* Fix: modify stored data in context

* chore: update state management for editor pages

* chore: remove commented code and add todos
  • Loading branch information
alexanderleegs authored Jun 25, 2024
1 parent a43ad30 commit 5812c23
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 129 deletions.
64 changes: 34 additions & 30 deletions apps/studio/src/components/PageEditor/ComponentSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Wrap,
} from '@chakra-ui/react'
import { Button, IconButton } from '@opengovsg/design-system-react'
import { IconType } from 'react-icons'
import { type IconType } from 'react-icons'
import {
BiCard,
BiColumns,
Expand All @@ -26,29 +26,30 @@ import {
BiText,
BiX,
} from 'react-icons/bi'
import { SectionType } from './types'
import { type SectionType } from './types'
import { useEditorDrawerContext } from '~/contexts/EditorDrawerContext'

const Section = ({ children }: React.PropsWithChildren) => {
function Section({ children }: React.PropsWithChildren) {
return (
<VStack gap="0.5rem" alignItems={'start'}>
<VStack gap="0.5rem" alignItems="start">
{children}
</VStack>
)
}

const SectionTitle = ({ title }: { title: string }) => {
function SectionTitle({ title }: { title: string }) {
return (
<Text textStyle={'subhead-3'} textColor="base.content.medium">
<Text textStyle="subhead-3" textColor="base.content.medium">
{title}
</Text>
)
}

const BlockList = ({ children }: React.PropsWithChildren) => {
function BlockList({ children }: React.PropsWithChildren) {
return <Wrap spacing="0">{children}</Wrap>
}

const BlockItem = ({
function BlockItem({
icon: Icon,
label,
onProceed,
Expand All @@ -60,7 +61,7 @@ const BlockItem = ({
onProceed: (sectionType: SectionType) => void
sectionType: SectionType
description: string
}) => {
}) {
return (
<Popover trigger="hover" placement="right">
<PopoverTrigger>
Expand All @@ -74,16 +75,16 @@ const BlockItem = ({
>
<VStack gap="0.5rem" color="base.content.default">
<Icon size="1.25rem" />
<Text textStyle={'caption-1'}>{label}</Text>
<Text textStyle="caption-1">{label}</Text>
</VStack>
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<VStack p="1.5rem" alignItems={'start'} gap="0.75rem">
<Flex alignItems={'center'} gap="0.5rem">
<VStack p="1.5rem" alignItems="start" gap="0.75rem">
<Flex alignItems="center" gap="0.5rem">
<Icon size="1.25rem" />
<Text textStyle={'subhead-2'}>{label}</Text>
<Text textStyle="subhead-2">{label}</Text>
</Flex>
<Text textStyle="body-2">{description}</Text>
</VStack>
Expand All @@ -92,29 +93,30 @@ const BlockItem = ({
)
}

interface ComponentSelectorProps {
onClose: () => void
onProceed: (sectionType: SectionType) => void
}

const ComponentSelector = ({ onClose, onProceed }: ComponentSelectorProps) => {
function ComponentSelector() {
const { setDrawerState, setPageState, setEditorState } =
useEditorDrawerContext()
const onProceed = (sectionType: SectionType) => {
// TODO: add new section to page/editor state
setDrawerState({ state: 'root' })
}
return (
<VStack w="full" gap="0">
<Flex
w="full"
py="1.25rem"
px="2rem"
alignItems={'center'}
justifyContent={'space-between'}
borderBottom={'solid'}
borderWidth={'1px'}
borderColor={'base.divider.medium'}
alignItems="center"
justifyContent="space-between"
borderBottom="solid"
borderWidth="1px"
borderColor="base.divider.medium"
>
<VStack alignItems={'start'}>
<Text as={'h5'} textStyle={'h5'}>
<VStack alignItems="start">
<Text as="h5" textStyle="h5">
Add a new block
</Text>
<Text textStyle={'body-2'}>Click a block to add to the page</Text>
<Text textStyle="body-2">Click a block to add to the page</Text>
</VStack>
<IconButton
size="lg"
Expand All @@ -123,10 +125,12 @@ const ComponentSelector = ({ onClose, onProceed }: ComponentSelectorProps) => {
color="interaction.sub.default"
aria-label="Close add component"
icon={<BiX />}
onClick={onClose}
onClick={() => {
setDrawerState({ state: 'root' })
}}
/>
</Flex>
<VStack p="2rem" w="full" gap="1.25rem" alignItems={'start'}>
<VStack p="2rem" w="full" gap="1.25rem" alignItems="start">
<Section>
<SectionTitle title="Basic Building Blocks" />
<BlockList>
Expand All @@ -136,7 +140,7 @@ const ComponentSelector = ({ onClose, onProceed }: ComponentSelectorProps) => {
onProceed={onProceed}
sectionType="paragraph"
description="Add text to your page - lists, headings, paragraph, and links."
></BlockItem>
/>
<BlockItem
label="Image"
icon={BiImage}
Expand Down
29 changes: 25 additions & 4 deletions apps/studio/src/contexts/EditorDrawerContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,44 @@ import React, {
useMemo,
type PropsWithChildren,
} from 'react'
import { type DrawerState } from '~/types/editorDrawer'
import { type Block, type DrawerState } from '~/types/editorDrawer'

export interface DrawerContextType {
drawerState: DrawerState | null
drawerState: DrawerState
setDrawerState: (state: DrawerState) => void
pageState: Block[]
setPageState: (state: Block[]) => void
editorState: Block[]
setEditorState: (state: Block[]) => void
}
const EditorDrawerContext = createContext<DrawerContextType | null>(null)

export function EditorDrawerProvider({ children }: PropsWithChildren) {
const [drawerState, setDrawerState] = useState<DrawerState | null>(null)
const [drawerState, setDrawerState] = useState<DrawerState>({
state: 'root',
})
// Current saved state of page
const [pageState, setPageState] = useState<Block[]>([])
// Current edit view of page
const [editorState, setEditorState] = useState<Block[]>([])

const value = useMemo(
() => ({
drawerState,
setDrawerState,
pageState,
setPageState,
editorState,
setEditorState,
}),
[drawerState, setDrawerState],
[
drawerState,
setDrawerState,
pageState,
setPageState,
editorState,
setEditorState,
],
)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,18 @@ import TipTapComponent from './TipTapComponent'

type EditPageDrawerProps = {
isOpen: boolean
state: DrawerState
}

export function EditPageDrawer({ isOpen: open, state }: EditPageDrawerProps) {
const { drawerState: currState, setDrawerState: setCurrState } =
useEditorDrawerContext()
export function EditPageDrawer({ isOpen: open }: EditPageDrawerProps) {
const { drawerState: currState } = useEditorDrawerContext()

useEffect(() => {
setCurrState(state)
}, [])

if (!currState) return <></>
console.log(currState.state)
switch (currState.state) {
case 'root':
return <RootStateDrawer blocks={currState.blocks} />
return <RootStateDrawer />
case 'addBlock':
return (
<ComponentSelector
onClose={() => setCurrState(state)}
onProceed={(componentType) => console.log(componentType)}
/>
)
return <ComponentSelector />
case 'nativeEditor':
return (
<TipTapComponent
data="test"
path="test"
handleChange={(path: string, data: any) => console.log(path, data)}
onProceed={(path: string, data: any) => console.log(path, data)}
onClose={() => setCurrState(state)}
type="paragraph"
/>
)
return <TipTapComponent data="test" path="test" type="paragraph" />
default:
return <h1>Edit Page Drawer</h1>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,23 @@ import {
} from '@hello-pangea/dnd'
import { BsPlus } from 'react-icons/bs'
import { MdOutlineDragIndicator } from 'react-icons/md'
import { useState } from 'react'
import { type Block } from '~/types/editorDrawer'
import { useEditorDrawerContext } from '~/contexts/EditorDrawerContext'

type RootStateDrawerProps = {
blocks: Block[]
}
export default function RootStateDrawer({ blocks }: RootStateDrawerProps) {
const { setDrawerState } = useEditorDrawerContext()
const [currState, setCurrState] = useState<{ blocks: Block[] }>({ blocks })
export default function RootStateDrawer() {
const { setDrawerState, pageState, setPageState, setEditorState } =
useEditorDrawerContext()

const onDragEnd = (result: DropResult) => {
if (!result.destination) return

const updatedBlocks = Array.from(currState.blocks)
const updatedBlocks = Array.from(pageState)
// Remove block at source index
const [movedBlock] = updatedBlocks.splice(result.source.index, 1)
// Insert at destination index
updatedBlocks.splice(result.destination.index, 0, movedBlock!)

setCurrState({ blocks: updatedBlocks })
setPageState(updatedBlocks)
setEditorState(updatedBlocks)
}

return (
Expand Down Expand Up @@ -70,7 +66,7 @@ export default function RootStateDrawer({ blocks }: RootStateDrawerProps) {
Custom blocks
</Text>
<Box w="100%">
{currState.blocks.map((block, index) => (
{pageState.map((block, index) => (
<Draggable
key={block.id}
draggableId={block.id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ import Underline from '@tiptap/extension-underline'
import { MenuBar } from '~/components/PageEditor/MenuBar'

import { Table } from './extensions/Table'
import { useEditorDrawerContext } from '~/contexts/EditorDrawerContext'

type NativeComponentType = 'paragraph' | 'image'

export interface TipTapComponentProps {
type: NativeComponentType
data: any
handleChange(path: string, value: any): void
onProceed(path: string, value: any): void
onClose(): void
path: string
}

Expand All @@ -50,14 +48,9 @@ const typeMapping = {
},
}

function TipTapComponent({
type,
data,
handleChange,
onProceed,
onClose,
path,
}: TipTapComponentProps) {
function TipTapComponent({ type, data, path }: TipTapComponentProps) {
const { setDrawerState, setPageState, setEditorState } =
useEditorDrawerContext()
const editor = useEditor({
extensions: [
Blockquote,
Expand Down Expand Up @@ -106,7 +99,7 @@ function TipTapComponent({
],
content: data,
onUpdate({ editor }) {
handleChange(path, editor.getJSON().content)
// TODO: set editor state - content is retrieved via editor.getJSON().content
},
})

Expand All @@ -133,7 +126,7 @@ function TipTapComponent({
color="interaction.sub.default"
aria-label="Close add component"
icon={<BiX />}
onClick={onClose}
onClick={() => setDrawerState({ state: 'root' })}
/>
</Flex>
<Box
Expand Down Expand Up @@ -175,7 +168,13 @@ function TipTapComponent({
w="100%"
justifyContent="end"
>
<Button onClick={() => onProceed(path, editor.getJSON().content)}>
<Button
onClick={() => {
// TODO: save page and update pageState
console.log('saving')
setDrawerState({ state: 'root' })
}}
>
Save
</Button>
</Flex>
Expand Down
Loading

0 comments on commit 5812c23

Please sign in to comment.