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: (