diff --git a/src/components/editor/ComponentPreview.tsx b/src/components/editor/ComponentPreview.tsx index 2e9b76e20d..264d800b3b 100644 --- a/src/components/editor/ComponentPreview.tsx +++ b/src/components/editor/ComponentPreview.tsx @@ -34,6 +34,13 @@ import SkeletonPreview, { SkeletonCirclePreview, SkeletonTextPreview, } from './previews/SkeletonPreview' +import TableContainerPreview, { + TablePreview, + TbodyPreview, + TfootPreview, + TheadPreview, + TrPreview, +} from './previews/TableContainerPreview' const ComponentPreview: React.FC<{ componentName: string @@ -70,6 +77,9 @@ const ComponentPreview: React.FC<{ case 'StatLabel': case 'StatNumber': case 'StatArrow': + case 'Th': + case 'Td': + case 'TableCaption': return ( case 'Highlight': return + case 'Table': + return + case 'Thead': + return + case 'Tbody': + return + case 'Tfoot': + return + case 'Tr': + return + case 'TableContainer': + return + case 'Tr': + return case 'Skeleton': return case 'SkeletonText': diff --git a/src/components/editor/previews/TableContainerPreview.tsx b/src/components/editor/previews/TableContainerPreview.tsx new file mode 100644 index 0000000000..ad93cc6488 --- /dev/null +++ b/src/components/editor/previews/TableContainerPreview.tsx @@ -0,0 +1,143 @@ +import React from 'react' +import { useInteractive } from '~hooks/useInteractive' +import { useDropComponent } from '~hooks/useDropComponent' +import { + Box, + Table, + TableContainer, + Tbody, + Tfoot, + Thead, + Tr, +} from '@chakra-ui/react' +import ComponentPreview from '~components/editor/ComponentPreview' + +const acceptedTypesTableContainer: ComponentType[] = ['Table'] + +const TableContainerPreview: React.FC = ({ component }) => { + const { props, ref } = useInteractive(component, true) + const { drop, isOver } = useDropComponent( + component.id, + acceptedTypesTableContainer, + ) + + let boxProps: any = {} + + if (isOver) { + props.bg = 'teal.50' + } + + return ( + + + {component.children.map((key: string) => ( + + ))} + + + ) +} + +const acceptedTypesTable: ComponentType[] = [ + 'TableCaption', + 'Thead', + 'Tbody', + 'Tfoot', +] + +export const TablePreview = ({ component }: IPreviewProps) => { + const { props, ref } = useInteractive(component, true, true) + const { drop, isOver } = useDropComponent(component.id, acceptedTypesTable) + + let boxProps: any = { border: '1px solid red' } + + if (isOver) { + props.bg = 'teal.50' + } + + return ( + + + {component.children.map((key: string) => ( + + ))} +
+
+ ) +} + +const acceptedTypesThead: ComponentType[] = ['Tr'] + +export const TheadPreview = ({ component }: IPreviewProps) => { + const { props, ref } = useInteractive(component, true) + const { drop, isOver } = useDropComponent(component.id, acceptedTypesThead) + + if (isOver) { + props.bg = 'teal.50' + } + + return ( + + {component.children.map((key: string) => ( + + ))} + + ) +} + +const acceptedTypesTr: ComponentType[] = ['Th', 'Td'] + +export const TrPreview = ({ component }: IPreviewProps) => { + const { props, ref } = useInteractive(component, true, true) + const { drop, isOver } = useDropComponent(component.id, acceptedTypesTr) + + if (isOver) { + props.bg = 'teal.50' + } + + return ( + + + {component.children.map((key: string) => ( + + ))} + + + ) +} + +export const TbodyPreview = ({ component }: IPreviewProps) => { + const { props, ref } = useInteractive(component, true) + const { drop, isOver } = useDropComponent(component.id, acceptedTypesThead) + + if (isOver) { + props.bg = 'teal.50' + } + + return ( + + {component.children.map((key: string) => ( + + ))} + + ) +} + +export const TfootPreview = ({ component }: IPreviewProps) => { + const { props, ref } = useInteractive(component, true) + const { drop, isOver } = useDropComponent(component.id, acceptedTypesThead) + + if (isOver) { + props.bg = 'teal.50' + } + + return ( + + {component.children.map((key: string) => ( + + ))} + + ) +} + +export default TableContainerPreview diff --git a/src/components/inspector/panels/Panels.tsx b/src/components/inspector/panels/Panels.tsx index f69f0d611d..759e029a33 100644 --- a/src/components/inspector/panels/Panels.tsx +++ b/src/components/inspector/panels/Panels.tsx @@ -54,6 +54,9 @@ import TabPanel from './components/TabPanel' import StatArrowPanel from './components/StatArrowPanel' import StatLabelPanel from './components/StatLabelPanel' import SkeletonPanel from './components/SkeletonPanel' +import TablePanel from './components/TablePanel' +import TdThPanel from './components/TdThPanel' +import TableCaptionPanel from './components/TableCaptionPanel' const Panels: React.FC<{ component: IComponent; isRoot: boolean }> = ({ component, @@ -127,6 +130,10 @@ const Panels: React.FC<{ component: IComponent; isRoot: boolean }> = ({ {type === 'StatArrow' && } {type === 'StatLabel' && } {type === 'StatNumber' && } + {type === 'Table' && } + {type === 'Td' && } + {type === 'Th' && } + {type === 'TableCaption' && } ) } diff --git a/src/components/inspector/panels/components/TableCaptionPanel.tsx b/src/components/inspector/panels/components/TableCaptionPanel.tsx new file mode 100644 index 0000000000..9c18595ef6 --- /dev/null +++ b/src/components/inspector/panels/components/TableCaptionPanel.tsx @@ -0,0 +1,34 @@ +import { Select } from '@chakra-ui/react' +import { memo } from 'react' +import ChildrenControl from '~components/inspector/controls/ChildrenControl' +import FormControl from '~components/inspector/controls/FormControl' +import SwitchControl from '~components/inspector/controls/SwitchControl' +import { useForm } from '~hooks/useForm' +import usePropsSelector from '~hooks/usePropsSelector' + +const TableCaptionPanel = () => { + const { setValueFromEvent } = useForm() + + const placement = usePropsSelector('placement') + + return ( + <> + + + + + + + ) +} + +export default memo(TableCaptionPanel) diff --git a/src/components/inspector/panels/components/TablePanel.tsx b/src/components/inspector/panels/components/TablePanel.tsx new file mode 100644 index 0000000000..648a5953bc --- /dev/null +++ b/src/components/inspector/panels/components/TablePanel.tsx @@ -0,0 +1,51 @@ +import { Select } from '@chakra-ui/react' +import { memo } from 'react' +import ChildrenControl from '~components/inspector/controls/ChildrenControl' +import ColorsControl from '~components/inspector/controls/ColorsControl' +import FormControl from '~components/inspector/controls/FormControl' +import TextControl from '~components/inspector/controls/TextControl' +import { useForm } from '~hooks/useForm' +import usePropsSelector from '~hooks/usePropsSelector' + +const TablePanel = () => { + const { setValueFromEvent } = useForm() + + const variant = usePropsSelector('variant') + const size = usePropsSelector('size') + + return ( + <> + + + + + + + + + + + ) +} + +export default memo(TablePanel) diff --git a/src/components/inspector/panels/components/TdThPanel.tsx b/src/components/inspector/panels/components/TdThPanel.tsx new file mode 100644 index 0000000000..279c9ededa --- /dev/null +++ b/src/components/inspector/panels/components/TdThPanel.tsx @@ -0,0 +1,14 @@ +import { memo } from 'react' +import ChildrenControl from '~components/inspector/controls/ChildrenControl' +import SwitchControl from '~components/inspector/controls/SwitchControl' + +const TdThPanel = () => { + return ( + <> + + + + ) +} + +export default memo(TdThPanel) diff --git a/src/componentsList.ts b/src/componentsList.ts index 76fee33917..ceaad72ccf 100644 --- a/src/componentsList.ts +++ b/src/componentsList.ts @@ -121,6 +121,19 @@ export const menuItems: MenuItems = { }, }, Tag: {}, + Table: { + children: { + TableContainer: {}, + Table: {}, + Thead: {}, + Tbody: {}, + Tfoot: {}, + Tr: {}, + Th: {}, + Td: {}, + TableCaption: {}, + }, + }, Text: {}, Textarea: {}, Menu: { soon: true }, @@ -199,6 +212,15 @@ export const componentsList: ComponentType[] = [ 'TabPanel', 'TabPanels', 'Tabs', + 'Table', + 'Thead', + 'Tbody', + 'Tfoot', + 'Tr', + 'Th', + 'Td', + 'TableCaption', + 'TableContainer', 'Tag', 'Text', 'Textarea', diff --git a/src/core/models/composer/builder.ts b/src/core/models/composer/builder.ts index 6149d1efed..7772427c51 100644 --- a/src/core/models/composer/builder.ts +++ b/src/core/models/composer/builder.ts @@ -182,6 +182,80 @@ export const buildList = (parent: string): ComposedComponent => { } } +export const buildTable = (parent: string): ComposedComponent => { + const composer = new Composer('TableContainer') + + const nodeId = composer.addNode({ type: 'TableContainer', parent }) + const tableId = composer.addNode({ type: 'Table', parent: nodeId }) + + composer.addNode({ + type: 'TableCaption', + parent: tableId, + props: { children: 'Table Caption Text' }, + }) + + const tableHead = composer.addNode({ type: 'Thead', parent: tableId }) + const tableHeadTr = composer.addNode({ + type: 'Tr', + parent: tableHead, + }) + + composer.addNode({ + type: 'Th', + parent: tableHeadTr, + props: { children: 'Th Text' }, + }) + composer.addNode({ + type: 'Th', + parent: tableHeadTr, + props: { children: 'Th Text' }, + }) + + const tableBody = composer.addNode({ type: 'Tbody', parent: tableId }) + + const tableBodyTr = composer.addNode({ + type: 'Tr', + parent: tableBody, + }) + + composer.addNode({ + type: 'Td', + parent: tableBodyTr, + props: { children: 'Td Textm' }, + }) + composer.addNode({ + type: 'Td', + parent: tableBodyTr, + props: { children: 'Td Text' }, + }) + + const tableFoot = composer.addNode({ type: 'Tfoot', parent: tableId }) + + const tableFootTr = composer.addNode({ + type: 'Tr', + parent: tableFoot, + }) + + composer.addNode({ + type: 'Th', + parent: tableFootTr, + props: { children: 'Th Text' }, + }) + composer.addNode({ + type: 'Th', + parent: tableFootTr, + props: { children: 'Th Text' }, + }) + + const components = composer.getComponents() + + return { + components, + root: nodeId, + parent, + } +} + export const buildInputGroup = (parent: string): ComposedComponent => { const composer = new Composer('Input') @@ -227,6 +301,7 @@ const builders: ComposerBuilders = { BreadcrumbMeta: buildBreadcrumb, TabsMeta: buildTabs, StatMeta: buildStats, + TableMeta: buildTable, } export default builders diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index ae05613707..d72de85fd1 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -80,6 +80,15 @@ type ComponentType = | 'Tag' | 'Text' | 'Textarea' + | 'Table' + | 'Thead' + | 'Tbody' + | 'Tfoot' + | 'Tr' + | 'Th' + | 'Td' + | 'TableCaption' + | 'TableContainer' type MetaComponentType = | 'FormControlMeta' @@ -90,6 +99,7 @@ type MetaComponentType = | 'BreadcrumbMeta' | 'TabsMeta' | 'StatMeta' + | 'TableMeta' interface IComponent { children: string[] diff --git a/src/utils/defaultProps.tsx b/src/utils/defaultProps.tsx index 6ee834d654..8b34783709 100644 --- a/src/utils/defaultProps.tsx +++ b/src/utils/defaultProps.tsx @@ -67,6 +67,14 @@ import { StatNumberProps, StatArrowProps, SkeletonProps, + TableProps, + TableHeadProps, + TableBodyProps, + TableFooterProps, + TableRowProps, + TableColumnHeaderProps, + TableCaptionProps, + TableContainerProps, } from '@chakra-ui/react' import iconsList from '~iconsList' @@ -150,6 +158,15 @@ type PreviewDefaultProps = { Skeleton?: PropsWithForm SkeletonCircle?: PropsWithForm SkeletonText?: PropsWithForm + Table?: PropsWithForm + Thead?: PropsWithForm + Tbody?: PropsWithForm + Tfoot?: PropsWithForm + Tr?: PropsWithForm + Th?: PropsWithForm + Td?: PropsWithForm + TableCaption?: PropsWithForm + TableContainer?: PropsWithForm } export const DEFAULT_PROPS: PreviewDefaultProps = { @@ -330,6 +347,15 @@ export const DEFAULT_PROPS: PreviewDefaultProps = { children: 'Tag name', }, Text: { children: 'Text value' }, + Table: { size: 'md' }, + Thead: {}, + Tbody: {}, + Tfoot: {}, + Tr: {}, + Th: { children: 'Th title' }, + Td: { children: 'Td title' }, + TableCaption: { children: 'Table Caption', placement: 'top' }, + TableContainer: {}, } export const getDefaultFormProps = (type: ComponentType) => { diff --git a/src/utils/editor.ts b/src/utils/editor.ts index adb66607c3..ac2b4a7d9b 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -79,6 +79,15 @@ export const COMPONENTS: (ComponentType | MetaComponentType)[] = [ 'StatHelpText', 'StatArrow', 'StatGroup', + 'Table', + 'Thead', + 'Tbody', + 'Tfoot', + 'Tr', + 'Th', + 'Td', + 'TableCaption', + 'TableContainer', // Allow meta components 'AlertMeta', 'FormControlMeta', @@ -88,6 +97,7 @@ export const COMPONENTS: (ComponentType | MetaComponentType)[] = [ 'BreadcrumbMeta', 'TabsMeta', 'StatMeta', + 'TableMeta', ] export const AccordionWhitelist: (