mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-25 11:51:07 +00:00
161 lines
5.3 KiB
TypeScript
161 lines
5.3 KiB
TypeScript
// TODO The purpose of importing this source file https://github.com/nteract/nteract/blob/main/packages/stateful-components/src/cells/markdown-cell.tsx
|
|
// into our source is to be able to overwrite the version of react-markdown which has this fix ("escape html to false")
|
|
// https://github.com/nteract/markdown/commit/e19c7cc590a4379fc507f67a7b4228363b9d8631 without having to upgrade
|
|
// @nteract/stateful-component which causes runtime issues.
|
|
|
|
import { ImmutableCell } from "@nteract/commutable/src";
|
|
import { actions, AppState, ContentRef, selectors } from "@nteract/core";
|
|
import { MarkdownPreviewer } from "@nteract/markdown";
|
|
import { defineConfigOption } from "@nteract/mythic-configuration";
|
|
import { Source as BareSource } from "@nteract/presentational-components";
|
|
import Editor, { EditorSlots } from "@nteract/stateful-components/lib/inputs/editor";
|
|
import React from "react";
|
|
import { ReactMarkdownProps } from "react-markdown";
|
|
import { connect } from "react-redux";
|
|
import { Dispatch } from "redux";
|
|
import styled from "styled-components";
|
|
|
|
const { selector: markdownConfig } = defineConfigOption({
|
|
key: "markdownOptions",
|
|
label: "Markdown Editor Options",
|
|
defaultValue: {},
|
|
});
|
|
|
|
interface NamedMDCellSlots {
|
|
editor?: EditorSlots;
|
|
toolbar?: () => JSX.Element;
|
|
}
|
|
|
|
interface ComponentProps {
|
|
id: string;
|
|
contentRef: ContentRef;
|
|
cell_type?: "markdown";
|
|
children?: NamedMDCellSlots;
|
|
}
|
|
|
|
interface StateProps {
|
|
isCellFocused: boolean;
|
|
isEditorFocused: boolean;
|
|
cell?: ImmutableCell;
|
|
markdownOptions: ReactMarkdownProps;
|
|
}
|
|
|
|
interface DispatchProps {
|
|
focusAboveCell: () => void;
|
|
focusBelowCell: () => void;
|
|
focusEditor: () => void;
|
|
unfocusEditor: () => void;
|
|
}
|
|
|
|
// Add missing style to make the editor show https://github.com/nteract/nteract/commit/7fa580011578350e56deac81359f6294fdfcad20#diff-07829a1908e4bf98d4420f868a1c6f890b95d77297b9805c9590d2dba11e80ce
|
|
export const Source = styled(BareSource)`
|
|
width: 100%;
|
|
width: -webkit-fill-available;
|
|
width: -moz-available;
|
|
`;
|
|
export class PureMarkdownCell extends React.Component<ComponentProps & DispatchProps & StateProps> {
|
|
render() {
|
|
const { contentRef, id, cell, children } = this.props;
|
|
|
|
const { isEditorFocused, isCellFocused, markdownOptions } = this.props;
|
|
|
|
const { focusAboveCell, focusBelowCell, focusEditor, unfocusEditor } = this.props;
|
|
|
|
/**
|
|
* We don't set the editor slots as defaults to support dynamic imports
|
|
* Users can continue to add the editorSlots as children
|
|
*/
|
|
const editor = children?.editor;
|
|
const toolbar = children?.toolbar;
|
|
|
|
const source = cell ? cell.get("source", "") : "";
|
|
|
|
return (
|
|
<div className="nteract-md-cell nteract-cell">
|
|
<div className="nteract-cell-row">
|
|
<div className="nteract-cell-gutter">{toolbar && toolbar()}</div>
|
|
<div className="nteract-cell-body">
|
|
<MarkdownPreviewer
|
|
focusAbove={focusAboveCell}
|
|
focusBelow={focusBelowCell}
|
|
focusEditor={focusEditor}
|
|
cellFocused={isCellFocused}
|
|
editorFocused={isEditorFocused}
|
|
unfocusEditor={unfocusEditor}
|
|
source={source}
|
|
markdownOptions={markdownOptions}
|
|
>
|
|
<Source className="nteract-cell-source">
|
|
<Editor id={id} contentRef={contentRef}>
|
|
{editor}
|
|
</Editor>
|
|
</Source>
|
|
</MarkdownPreviewer>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export const makeMapStateToProps = (
|
|
initialState: AppState,
|
|
ownProps: ComponentProps
|
|
): ((state: AppState) => StateProps) => {
|
|
const { id, contentRef } = ownProps;
|
|
const mapStateToProps = (state: AppState): StateProps => {
|
|
const model = selectors.model(state, { contentRef });
|
|
let isCellFocused = false;
|
|
let isEditorFocused = false;
|
|
let cell;
|
|
|
|
if (model && model.type === "notebook") {
|
|
cell = selectors.notebook.cellById(model, { id });
|
|
isCellFocused = model.cellFocused === id;
|
|
isEditorFocused = model.editorFocused === id;
|
|
}
|
|
|
|
const markdownOptionsDefaults = {
|
|
linkTarget: "_blank",
|
|
};
|
|
const currentMarkdownOptions = markdownConfig(state);
|
|
|
|
const markdownOptions = Object.assign({}, markdownOptionsDefaults, currentMarkdownOptions);
|
|
|
|
return {
|
|
cell,
|
|
isCellFocused,
|
|
isEditorFocused,
|
|
markdownOptions,
|
|
};
|
|
};
|
|
|
|
return mapStateToProps;
|
|
};
|
|
|
|
const makeMapDispatchToProps = (
|
|
initialDispatch: Dispatch,
|
|
ownProps: ComponentProps
|
|
): ((dispatch: Dispatch) => DispatchProps) => {
|
|
const { id, contentRef } = ownProps;
|
|
|
|
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
|
|
focusAboveCell: () => {
|
|
dispatch(actions.focusPreviousCell({ id, contentRef }));
|
|
dispatch(actions.focusPreviousCellEditor({ id, contentRef }));
|
|
},
|
|
focusBelowCell: () => {
|
|
dispatch(actions.focusNextCell({ id, createCellIfUndefined: true, contentRef }));
|
|
dispatch(actions.focusNextCellEditor({ id, contentRef }));
|
|
},
|
|
focusEditor: () => dispatch(actions.focusCellEditor({ id, contentRef })),
|
|
unfocusEditor: () => dispatch(actions.focusCellEditor({ id: undefined, contentRef })),
|
|
});
|
|
|
|
return mapDispatchToProps;
|
|
};
|
|
|
|
const MarkdownCell = connect(makeMapStateToProps, makeMapDispatchToProps)(PureMarkdownCell);
|
|
|
|
export default MarkdownCell;
|