Skip to content

Commit

Permalink
feat: implement a standard document model toolbar with out of the box…
Browse files Browse the repository at this point in the history
… functionalities in the document model editor (#430)

* feat(design-system): added DocumentToolbar component

* feat(document-model-libs): added documentToolbar option in EditorConfig type

* feat(codegen): enabled support for ExtendedEditor + import actions in Editor
  • Loading branch information
gpuente authored Oct 24, 2024
1 parent b9d0d44 commit dcc6cc2
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ unless_exists: true
---
<% if(!documentTypes.length){ %>import { Action, EditorProps } from 'document-model/document';<% } else { %>import { EditorProps } from 'document-model/document';<% } %>
<% documentTypes.forEach(type => { _%>
import { <%= documentTypesMap[type] %>State, <%= documentTypesMap[type] %>Action, <%= documentTypesMap[type] %>LocalState } from "../.<%= documentModelsDir %>/<%= h.changeCase.param(documentTypesMap[type]) %>";
import { <%= documentTypesMap[type] %>State, <%= documentTypesMap[type] %>Action, <%= documentTypesMap[type] %>LocalState, actions } from "../.<%= documentModelsDir %>/<%= h.changeCase.param(documentTypesMap[type]) %>";
%><% }); _%>

export type IProps = <% if(!documentTypes.length){ %>EditorProps<unknown, Action><% } else { %><% documentTypes.forEach((type, index) => { _%>EditorProps<<%= documentTypesMap[type] %>State, <%= documentTypesMap[type] %>Action, <%= documentTypesMap[type] %>LocalState%>%>><% if(index < documentTypes.length - 1){ %> | <% }%><% }); _%> <% } %>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
to: "<%= rootDir %>/<%= h.changeCase.param(name) %>/index.ts"
force: true
---
import { type Editor as EditorModule<% if(!documentTypes.length){ %>, Action<% } %> } from 'document-model/document';
import { ExtendedEditor, EditorContextProps } from 'document-model-libs';
import Editor from './editor';
<% documentTypes.forEach(type => { _%>
import { <%= documentTypesMap[type] %>State, <%= documentTypesMap[type] %>Action, <%= documentTypesMap[type] %>LocalState } from "../.<%= documentModelsDir %>/<%= h.changeCase.param(documentTypesMap[type]) %>";
%><% }); _%>

export const module: <% if(!documentTypes.length){ %>EditorModule<unknown, Action><% } else { %><% documentTypes.forEach((type, index) => { _%>EditorModule<<%= documentTypesMap[type] %>State, <%= documentTypesMap[type] %>Action, <%= documentTypesMap[type] %>LocalState%>%>> <% if(index < documentTypes.length - 1){ %>| <% }%><% }); _%> <% } %>= {
export const module: <% if(!documentTypes.length){ %>ExtendedEditor<unknown, Action, unknown, unknown><% } else { %><% documentTypes.forEach((type, index) => { _%>ExtendedEditor<<%= documentTypesMap[type] %>State, <%= documentTypesMap[type] %>Action, <%= documentTypesMap[type] %>LocalState, EditorContextProps%>%>> <% if(index < documentTypes.length - 1){ %>| <% }%><% }); _%> <% } %>= {
Component: Editor,
documentTypes: [<% if(!documentTypes.length){ %>'*'<% } else { %><% documentTypes.forEach(type => { _%>"<%= type %>", %><% }); _%> <% } %>],
config: {
id: 'editor-id',
disableExternalControls: true,
documentToolbarEnabled: true,
},
};

export default module;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Meta, StoryObj } from "@storybook/react";
import { DocumentToolbar } from "./document-toolbar";

const meta = {
title: "Connect/Components/DocumentToolbar",
component: DocumentToolbar,
} satisfies Meta<typeof DocumentToolbar>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
title: "My Document Model V2",
canUndo: true,
canRedo: true,
redo: () => console.log("redo"),
undo: () => console.log("undo"),
onClose: () => console.log("close"),
onExport: () => console.log("export"),
onShowRevisionHistory: () => console.log("show revision history"),
onSwitchboardLinkClick: () => console.log("switchboard link click"),
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
EditorUndoRedoButtons,
EditorUndoRedoButtonsProps,
} from "@/connect/components/editor-undo-redo-buttons";
import {
EditorActionButtons,
EditorActionButtonsProps,
} from "@/connect/components/editor-action-buttons";
import { twMerge } from "tailwind-merge";

export type DocumentToolbarProps = {
title?: string;
className?: string;
} & Partial<EditorUndoRedoButtonsProps> &
EditorActionButtonsProps;

export const DocumentToolbar: React.FC<DocumentToolbarProps> = (props) => {
const {
undo,
canUndo,
redo,
canRedo,
title,
onClose,
onExport,
className,
onShowRevisionHistory,
onSwitchboardLinkClick,
} = props;

return (
<div className={twMerge("flex items-center justify-between", className)}>
<div>
{undo && redo && canUndo && canRedo && (
<EditorUndoRedoButtons
undo={undo}
canUndo={canUndo}
redo={redo}
canRedo={canRedo}
/>
)}
</div>
<div>
<h2 className="text-sm font-semibold">{title}</h2>
</div>
<div>
<EditorActionButtons
onClose={onClose}
onExport={onExport}
onShowRevisionHistory={onShowRevisionHistory}
onSwitchboardLinkClick={onSwitchboardLinkClick}
/>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./document-toolbar";
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Icon } from "@/powerhouse";

type Props = {
readonly onSwitchboardLinkClick: (() => void) | undefined;
export type EditorActionButtonsProps = {
readonly onSwitchboardLinkClick?: (() => void) | undefined;
readonly onExport: () => void;
readonly onClose: () => void;
readonly onShowRevisionHistory: () => void;
};
export function EditorActionButtons(props: Props) {
export function EditorActionButtons(props: EditorActionButtonsProps) {
const { onSwitchboardLinkClick, onExport, onClose, onShowRevisionHistory } =
props;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
import { Icon } from "@/powerhouse";
import { twMerge } from "tailwind-merge";

type Props = {
export type EditorUndoRedoButtonsProps = {
readonly canUndo: boolean;
readonly canRedo: boolean;
readonly undo: () => void;
readonly redo: () => void;
};
export function EditorUndoRedoButtons(props: Props) {
export function EditorUndoRedoButtons(props: EditorUndoRedoButtonsProps) {
const { canUndo, canRedo, undo, redo } = props;
const buttonStyles =
"w-8 h-8 tab-shadow rounded-lg flex justify-center items-center";
"w-8 h-8 rounded-lg flex justify-center items-center rounded border border-gray-200";
return (
<div className="flex gap-x-2 text-gray-500">
<button className={buttonStyles} disabled={!canUndo} onClick={undo}>
<Icon
className={twMerge(
"-scale-x-100",
canUndo ? "active:opacity-50" : "text-gray-500",
canUndo ? "text-gray-900 active:opacity-50" : "text-gray-500",
)}
name="RedoArrow"
size={18}
/>
</button>
<button className={buttonStyles} disabled={!canRedo} onClick={redo}>
<Icon
className={twMerge(canRedo ? "active:opacity-50" : "text-gray-500")}
className={twMerge(
canRedo ? "text-gray-900 active:opacity-50" : "text-gray-500",
)}
name="RedoArrow"
size={18}
/>
</button>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/design-system/src/connect/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ export * from "./toast";
export * from "./toggle";
export * from "./tooltip";
export * from "./tree-view";
export * from "./document-toolbar";
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
MoreDetailsCell,
RWATableCell,
RWATableRow,
SortDirection,
TableBase,
TableColumn,
TableItemType,
Expand Down Expand Up @@ -115,7 +116,9 @@ export function Table(props: TableProps) {
hasSelectedItem={!!selectedTableItem}
headerRef={headerRef}
maxHeight={maxHeight}
onClickSort={sortHandler}
onClickSort={
sortHandler as (key: string, direction: SortDirection) => void
}
ref={tableContainerRef}
renderRow={renderRow}
specialFirstRow={specialFirstRow}
Expand Down
14 changes: 14 additions & 0 deletions packages/document-model-libs/editors/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ import { Action, EditorProps } from "document-model/document";
export type EditorConfig = {
id: string;
disableExternalControls: boolean;
documentToolbarEnabled?: boolean;
};

export type EditorContextProps = {
readonly isAllowedToCreateDocuments: boolean;
readonly isAllowedToEditDocuments: boolean;
readonly canUndo: boolean;
readonly canRedo: boolean;
readonly undo: () => void;
readonly redo: () => void;
readonly onSwitchboardLinkClick: (() => void) | undefined;
readonly onExport: () => void;
readonly onClose: () => void;
readonly onShowRevisionHistory: () => void;
};

export type ExtendedEditor<
Expand Down

0 comments on commit dcc6cc2

Please sign in to comment.