| 1 | import { BaseTablePlugin } from "@platejs/table"; |
| 2 | import { type TTableCellElement, type TTableElement } from "platejs"; |
| 3 | import { SlateElement, type SlateElementProps } from "platejs/static"; |
| 4 | import type * as React from "react"; |
| 5 | |
| 6 | import { cn } from "@/lib/utils"; |
| 7 | |
| 8 | export function PresentationTableElementStatic({ |
| 9 | children, |
| 10 | ...props |
| 11 | }: SlateElementProps<TTableElement>) { |
| 12 | const { disableMarginLeft } = props.editor.getOptions(BaseTablePlugin); |
| 13 | const marginLeft = disableMarginLeft ? 0 : props.element.marginLeft; |
| 14 | |
| 15 | return ( |
| 16 | <SlateElement |
| 17 | {...props} |
| 18 | className="overflow-x-auto py-5 transition-all duration-300" |
| 19 | style={{ paddingLeft: marginLeft }} |
| 20 | > |
| 21 | <div className="group/table relative w-full bg-transparent"> |
| 22 | <table className="mr-0 ml-px table h-px w-full max-w-[calc(100%-2rem)] table-fixed border-collapse bg-transparent text-(--presentation-text)"> |
| 23 | <tbody className="w-full">{children}</tbody> |
| 24 | </table> |
| 25 | </div> |
| 26 | </SlateElement> |
| 27 | ); |
| 28 | } |
| 29 | |
| 30 | export function PresentationTableRowElementStatic(props: SlateElementProps) { |
| 31 | return ( |
| 32 | <SlateElement {...props} as="tr" className="h-full"> |
| 33 | {props.children} |
| 34 | </SlateElement> |
| 35 | ); |
| 36 | } |
| 37 | |
| 38 | export function PresentationTableCellElementStatic({ |
| 39 | isHeader, |
| 40 | ...props |
| 41 | }: SlateElementProps<TTableCellElement> & { |
| 42 | isHeader?: boolean; |
| 43 | }) { |
| 44 | const { editor, element } = props; |
| 45 | const { api } = editor.getPlugin(BaseTablePlugin); |
| 46 | |
| 47 | const { minHeight } = api.table.getCellSize({ element }); |
| 48 | const borders = api.table.getCellBorders({ element }); |
| 49 | |
| 50 | return ( |
| 51 | <SlateElement |
| 52 | {...props} |
| 53 | as={isHeader ? "th" : "td"} |
| 54 | className={cn( |
| 55 | "h-full overflow-visible border-none bg-transparent p-0", |
| 56 | element.background ? "bg-(--cellBackground)" : "bg-transparent", |
| 57 | isHeader && "text-left *:m-0", |
| 58 | "before:size-full", |
| 59 | "before:absolute before:box-border before:content-[''] before:select-none", |
| 60 | borders.bottom?.size && `before:border-b before:border-b-border`, |
| 61 | borders.right?.size && `before:border-r before:border-r-border`, |
| 62 | borders.left?.size && `before:border-l before:border-l-border`, |
| 63 | borders.top?.size && `before:border-t before:border-t-border`, |
| 64 | )} |
| 65 | style={ |
| 66 | { |
| 67 | "--cellBackground": element.background, |
| 68 | ...(isHeader && { |
| 69 | backgroundColor: |
| 70 | element.color || "var(--presentation-card-background)", |
| 71 | }), |
| 72 | } as React.CSSProperties |
| 73 | } |
| 74 | attributes={{ |
| 75 | ...props.attributes, |
| 76 | colSpan: api.table.getColSpan(element), |
| 77 | rowSpan: api.table.getRowSpan(element), |
| 78 | }} |
| 79 | > |
| 80 | <div |
| 81 | className={cn( |
| 82 | "relative z-20 box-border h-full rounded-md px-3 py-2", |
| 83 | isHeader ? "text-lg font-bold text-primary" : "presentation-text", |
| 84 | )} |
| 85 | style={{ minHeight }} |
| 86 | > |
| 87 | {props.children} |
| 88 | </div> |
| 89 | </SlateElement> |
| 90 | ); |
| 91 | } |
| 92 | |
| 93 | export function PresentationTableCellHeaderElementStatic( |
| 94 | props: SlateElementProps<TTableCellElement>, |
| 95 | ) { |
| 96 | return <PresentationTableCellElementStatic {...props} isHeader />; |
| 97 | } |
| 98 |