Skip to content

Commit

Permalink
Add tabs to demo site and PresetPlugin (microsoft#2511)
Browse files Browse the repository at this point in the history
* top right buttons

* fix sidepane reload

* tabs

* remove icon table edit buttons

* Preset Plugin base and presets

* FormatStatePane add Image and table border

* Add PresetPlugin and implement tabs on MainPane

* fix correct export button

* reorder buttons and tabs

* cleanup

* adapt for formatPainterPlugin  button
  • Loading branch information
Andres-CT98 authored Mar 19, 2024
1 parent cbe2205 commit ca960e2
Show file tree
Hide file tree
Showing 22 changed files with 3,428 additions and 35 deletions.
5 changes: 5 additions & 0 deletions demo/scripts/controlsV2/demoButtons/darkModeButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ export const darkModeButton: RibbonButton<DarkModeButtonStringKey> = {
MainPane.getInstance().toggleDarkMode();
return true;
},
commandBarProperties: {
buttonStyles: {
icon: { paddingBottom: '10px' },
},
},
};
5 changes: 5 additions & 0 deletions demo/scripts/controlsV2/demoButtons/exportContentButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ export const exportContentButton: RibbonButton<ExportButtonStringKey> = {
const html = exportContent(editor);
win.document.write(editor.getTrustedHTMLHandler()(html));
},
commandBarProperties: {
buttonStyles: {
icon: { paddingBottom: '10px' },
},
},
};
5 changes: 5 additions & 0 deletions demo/scripts/controlsV2/demoButtons/popoutButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ export const popoutButton: RibbonButton<PopoutButtonStringKey> = {
onClick: _ => {
MainPane.getInstance().popout();
},
commandBarProperties: {
buttonStyles: {
icon: { paddingBottom: '10px' },
},
},
};
20 changes: 16 additions & 4 deletions demo/scripts/controlsV2/demoButtons/tableEditButtons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const tableMergeButton: RibbonButton<
'ribbonButtonTableMerge' | TableEditMergeMenuItemStringKey
> = {
key: 'ribbonButtonTableMerge',
iconName: 'TableComputed',
iconName: '',
unlocalizedText: 'Merge',
isDisabled: formatState => !formatState.isInTable,
dropDownMenu: {
Expand All @@ -102,13 +102,16 @@ export const tableMergeButton: RibbonButton<
editTable(editor, TableEditOperationMap[key]);
}
},
commandBarProperties: {
iconOnly: false,
},
};

export const tableSplitButton: RibbonButton<
'ribbonButtonTableSplit' | TableEditSplitMenuItemStringKey
> = {
key: 'ribbonButtonTableSplit',
iconName: 'TableComputed',
iconName: '',
unlocalizedText: 'Split',
isDisabled: formatState => !formatState.isInTable,
dropDownMenu: {
Expand All @@ -122,13 +125,16 @@ export const tableSplitButton: RibbonButton<
editTable(editor, TableEditOperationMap[key]);
}
},
commandBarProperties: {
iconOnly: false,
},
};

export const tableAlignCellButton: RibbonButton<
'ribbonButtonTableAlignCell' | TableEditAlignMenuItemStringKey
> = {
key: 'ribbonButtonTableAlignCell',
iconName: 'TableComputed',
iconName: '',
unlocalizedText: 'Align table cell',
isDisabled: formatState => !formatState.isInTable,
dropDownMenu: {
Expand All @@ -147,13 +153,16 @@ export const tableAlignCellButton: RibbonButton<
editTable(editor, TableEditOperationMap[key]);
}
},
commandBarProperties: {
iconOnly: false,
},
};

export const tableAlignTableButton: RibbonButton<
'ribbonButtonTableAlignTable' | TableEditAlignTableMenuItemStringKey
> = {
key: 'ribbonButtonTableAlignTable',
iconName: 'TableComputed',
iconName: '',
unlocalizedText: 'Align table',
isDisabled: formatState => !formatState.isInTable,
dropDownMenu: {
Expand All @@ -168,4 +177,7 @@ export const tableAlignTableButton: RibbonButton<
editTable(editor, TableEditOperationMap[key]);
}
},
commandBarProperties: {
iconOnly: false,
},
};
6 changes: 6 additions & 0 deletions demo/scripts/controlsV2/demoButtons/zoomButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,10 @@ export const zoomButton: RibbonButton<ZoomButtonStringKey> = {

editor.triggerEvent('zoomChanged', { newZoomScale: zoomScale });
},
commandBarProperties: {
buttonStyles: {
icon: { paddingBottom: '10px' },
menuIcon: { paddingBottom: '10px' },
},
},
};
7 changes: 7 additions & 0 deletions demo/scripts/controlsV2/mainPane/MainPane.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
overflow-x: hidden;
}

.menuTab {
border-radius: 30% 30% 0 0;
background-color: $primaryLighter;
color: white;
font-weight: bold;
}

.body {
flex: 1 1 auto;
position: relative;
Expand Down
77 changes: 62 additions & 15 deletions demo/scripts/controlsV2/mainPane/MainPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,31 @@ import * as ReactDOM from 'react-dom';
import SampleEntityPlugin from '../plugins/SampleEntityPlugin';
import { ApiPlaygroundPlugin } from '../sidePane/apiPlayground/ApiPlaygroundPlugin';
import { Border, ContentModelDocument, EditorOptions } from 'roosterjs-content-model-types';
import { buttons, buttonsWithPopout } from './ribbonButtons';
import { Colors, EditorPlugin, IEditor, Snapshots } from 'roosterjs-content-model-types';
import { ContentModelPanePlugin } from '../sidePane/contentModel/ContentModelPanePlugin';
import { createEmojiPlugin } from '../roosterjsReact/emoji';
import { createFormatPainterButton } from '../demoButtons/formatPainterButton';
import { createImageEditMenuProvider } from '../roosterjsReact/contextMenu/menus/createImageEditMenuProvider';
import { createLegacyPlugins } from '../plugins/createLegacyPlugins';
import { createListEditMenuProvider } from '../roosterjsReact/contextMenu/menus/createListEditMenuProvider';
import { createPasteOptionPlugin } from '../roosterjsReact/pasteOptions';
import { createRibbonPlugin, Ribbon, RibbonButton, RibbonPlugin } from '../roosterjsReact/ribbon';
import { darkModeButton } from '../demoButtons/darkModeButton';
import { Editor } from 'roosterjs-content-model-core';
import { EditorAdapter } from 'roosterjs-editor-adapter';
import { EditorOptionsPlugin } from '../sidePane/editorOptions/EditorOptionsPlugin';
import { EventViewPlugin } from '../sidePane/eventViewer/EventViewPlugin';
import { exportContentButton } from '../demoButtons/exportContentButton';
import { FormatPainterPlugin } from '../plugins/FormatPainterPlugin';
import { FormatStatePlugin } from '../sidePane/formatState/FormatStatePlugin';
import { getButtons } from '../tabs/ribbonButtons';
import { getDarkColor } from 'roosterjs-color-utils';
import { getPresetModelById } from '../sidePane/presets/allPresets/allPresets';
import { getTabs, tabNames } from '../tabs/getTabs';
import { getTheme } from '../theme/themes';
import { OptionState } from '../sidePane/editorOptions/OptionState';
import { popoutButton } from '../demoButtons/popoutButton';
import { PresetPlugin } from '../sidePane/presets/PresetPlugin';
import { redoButton } from '../roosterjsReact/ribbon/buttons/redoButton';
import { registerWindowForCss, unregisterWindowForCss } from '../../utils/cssMonitor';
import { Rooster } from '../roosterjsReact/rooster';
import { SidePane } from '../sidePane/SidePane';
Expand All @@ -30,8 +36,10 @@ import { SnapshotPlugin } from '../sidePane/snapshot/SnapshotPlugin';
import { ThemeProvider } from '@fluentui/react/lib/Theme';
import { TitleBar } from '../titleBar/TitleBar';
import { trustedHTMLHandler } from '../../utils/trustedHTMLHandler';
import { undoButton } from '../roosterjsReact/ribbon/buttons/undoButton';
import { UpdateContentPlugin } from '../plugins/UpdateContentPlugin';
import { WindowProvider } from '@fluentui/react/lib/WindowProvider';
import { zoomButton } from '../demoButtons/zoomButton';
import {
createContextMenuPlugin,
createTableEditMenuProvider,
Expand All @@ -54,6 +62,7 @@ export interface MainPaneState {
scale: number;
isDarkMode: boolean;
isRtl: boolean;
activeTab: tabNames;
tableBorderFormat?: Border;
editorCreator: (div: HTMLDivElement, options: EditorOptions) => IEditor;
}
Expand All @@ -73,12 +82,11 @@ export class MainPane extends React.Component<{}, MainPaneState> {
private eventViewPlugin: EventViewPlugin;
private apiPlaygroundPlugin: ApiPlaygroundPlugin;
private contentModelPanePlugin: ContentModelPanePlugin;
private presetPlugin: PresetPlugin;
private ribbonPlugin: RibbonPlugin;
private snapshotPlugin: SnapshotPlugin;
private formatPainterPlugin: FormatPainterPlugin;
private snapshots: Snapshots;
private buttons: RibbonButton<any>[];
private buttonsWithPopout: RibbonButton<any>[];

protected sidePane = React.createRef<SidePane>();
protected updateContentPlugin: UpdateContentPlugin;
Expand Down Expand Up @@ -112,12 +120,10 @@ export class MainPane extends React.Component<{}, MainPaneState> {
this.apiPlaygroundPlugin = new ApiPlaygroundPlugin();
this.snapshotPlugin = new SnapshotPlugin(this.snapshots);
this.contentModelPanePlugin = new ContentModelPanePlugin();
this.presetPlugin = new PresetPlugin();
this.ribbonPlugin = createRibbonPlugin();
this.formatPainterPlugin = new FormatPainterPlugin();

const baseButtons = [createFormatPainterButton(this.formatPainterPlugin)];
this.buttons = baseButtons.concat(buttons);
this.buttonsWithPopout = baseButtons.concat(buttonsWithPopout);
this.state = {
showSidePane: window.location.hash != '',
popoutWindow: null,
Expand All @@ -131,17 +137,17 @@ export class MainPane extends React.Component<{}, MainPaneState> {
style: 'solid',
color: '#ABABAB',
},
activeTab: 'all',
};
}

render() {
const theme = getTheme(this.state.isDarkMode);
return (
<ThemeProvider
applyTo="body"
theme={getTheme(this.state.isDarkMode)}
className={styles.mainPane}>
<ThemeProvider applyTo="body" theme={theme} className={styles.mainPane}>
{this.renderTitleBar()}
{!this.state.popoutWindow && this.renderRibbon(false /*isPopout*/)}
{!this.state.popoutWindow && this.renderTabs()}
{!this.state.popoutWindow && this.renderRibbon()}
<div className={styles.body + ' ' + (this.state.isDarkMode ? 'dark' : '')}>
{this.state.popoutWindow ? this.renderPopout() : this.renderMainPane()}
</div>
Expand Down Expand Up @@ -220,6 +226,16 @@ export class MainPane extends React.Component<{}, MainPaneState> {
});
}

changeRibbon(id: tabNames): void {
this.setState({
activeTab: id,
});
}

setPreset(preset: ContentModelDocument) {
this.model = preset;
}

setPageDirection(isRtl: boolean): void {
this.setState({ isRtl: isRtl });
[window, this.state.popoutWindow].forEach(win => {
Expand All @@ -233,10 +249,32 @@ export class MainPane extends React.Component<{}, MainPaneState> {
return <TitleBar className={styles.noGrow} />;
}

private renderRibbon(isPopout: boolean) {
private renderTabs() {
const tabs = getTabs();
const topRightButtons: RibbonButton<any>[] = [
undoButton,
redoButton,
zoomButton,
darkModeButton,
exportContentButton,
];
this.state.popoutWindow ? null : topRightButtons.push(popoutButton);

return (
<div
style={{ display: 'inline-flex', justifyContent: 'space-between', height: '30px' }}>
<Ribbon
buttons={tabs}
plugin={this.ribbonPlugin}
dir={this.state.isRtl ? 'rtl' : 'ltr'}></Ribbon>
<Ribbon buttons={topRightButtons} plugin={this.ribbonPlugin}></Ribbon>
</div>
);
}
private renderRibbon() {
return (
<Ribbon
buttons={isPopout ? this.buttons : this.buttonsWithPopout}
buttons={getButtons(this.state.activeTab, this.formatPainterPlugin)}
plugin={this.ribbonPlugin}
dir={this.state.isRtl ? 'rtl' : 'ltr'}
/>
Expand Down Expand Up @@ -271,6 +309,13 @@ export class MainPane extends React.Component<{}, MainPaneState> {
}

private renderEditor() {
// Set preset if found
const search = new URLSearchParams(document.location.search);
const hasPreset = search.get('preset');
if (hasPreset) {
this.setPreset(getPresetModelById(hasPreset));
}

const editorStyles = {
transform: `scale(${this.state.scale})`,
transformOrigin: this.state.isRtl ? 'right top' : 'left top',
Expand Down Expand Up @@ -353,7 +398,8 @@ export class MainPane extends React.Component<{}, MainPaneState> {
<WindowProvider window={this.state.popoutWindow}>
<ThemeProvider applyTo="body" theme={getTheme(this.state.isDarkMode)}>
<div className={styles.mainPane}>
{this.renderRibbon(true /*isPopout*/)}
{this.renderTabs()}
{this.renderRibbon()}
<div className={styles.body}>{this.renderEditor()}</div>
</div>
</ThemeProvider>
Expand Down Expand Up @@ -415,6 +461,7 @@ export class MainPane extends React.Component<{}, MainPaneState> {
this.apiPlaygroundPlugin,
this.snapshotPlugin,
this.contentModelPanePlugin,
this.presetPlugin,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ export const redoButton: RibbonButton<RedoButtonStringKey> = {
onClick: editor => {
redo(editor);
},
commandBarProperties: {
buttonStyles: {
icon: { paddingBottom: '10px' },
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ export const undoButton: RibbonButton<UndoButtonStringKey> = {
onClick: editor => {
undo(editor);
},
commandBarProperties: {
buttonStyles: {
icon: { paddingBottom: '10px' },
},
},
};
1 change: 1 addition & 0 deletions demo/scripts/controlsV2/sidePane/SidePane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class SidePane extends React.Component<SidePaneProps, SidePaneState> {
};

window.addEventListener('hashchange', this.updateStateFromHash);
window.location.hash ? this.updateStateFromHash() : this.updateHash();
}

componentDidMount() {
Expand Down
Loading

0 comments on commit ca960e2

Please sign in to comment.