function createEditor()

in sample/script/FocusOutShellSample.tsx [61:222]


function createEditor(name: string, loadEmojiStrings: boolean = false): JSX.Element {
    let leanRoosterContentDiv: HTMLDivElement;
    const leanRoosterContentDivOnRef = (ref: HTMLDivElement) => (leanRoosterContentDiv = ref);

    let leanRooster: LeanRooster;
    const leanRoosterOnRef = (ref: LeanRooster) => (leanRooster = ref);

    let commandBar: RoosterCommandBar;
    const commandBarOnRef = (ref: RoosterCommandBar) => (commandBar = ref);

    const imageManager = new ImageManager({
        uploadImage: (image: File) =>
            new Promise<string>((resolve, reject) => {
                const timeoutMs = Math.random() * 5000;
                console.log(`Imitating uploading... (${timeoutMs}ms)`);

                // fake upload failure if type isn't image
                if (image.type.indexOf("image/") !== 0) {
                    window.setTimeout(() => {
                        reject();
                        console.log(`Upload failed`);
                    }, timeoutMs);

                    return;
                }

                const reader = new FileReader();
                reader.onload = (event: ProgressEvent) => {
                    const dataURL: string = (event.target as FileReader).result as string;
                    window.setTimeout(() => resolve(dataURL), timeoutMs);
                };
                reader.readAsDataURL(image);
            }),
        placeholderImageClassName
    } as ImageManagerOptions);
    const leanRoosterViewState = createEditorViewState(`Hello LeanRooster! (${name})`);
    const imagePlugin = new PasteImagePlugin(imageManager);
    const imageResizePlugin = new ImageResize(undefined, undefined, undefined, undefined, excludePlaceholderSelector);

    const focusOutShellAllowMouseDown = (element: HTMLElement): boolean => leanRoosterContentDiv && leanRoosterContentDiv.contains(element);
    const focusOutShellOnFocus = (ev: React.FocusEvent<HTMLElement>) => {
        console.log(`FocusOutShell (${name}) gained focus (hasPlaceholder: ${leanRooster.hasPlaceholder()})`);
        commandBarPlugin.registerRoosterCommandBar(commandBar); // re-register command b/c we're changing mode on blur
        leanRooster.mode = LeanRoosterModes.Edit;
    };

    let suppressBlur = false;
    const focusOutShellOnBlur = (ev: React.FocusEvent<HTMLElement>) => {
        console.log(`FocusOutShell (${name}) lost focus (hasPlaceholder: ${leanRooster.hasPlaceholder()})`);
        leanRooster.mode = LeanRoosterModes.View;
        imageResizePlugin.hideResizeHandle();
    };
    const shouldCallBlur = (nextTarget: HTMLElement, shouldCallBlurDefault: (nextTarget: HTMLElement) => boolean): boolean => {
        if (suppressBlur) {
            suppressBlur = false;
            return false;
        }

        return shouldCallBlurDefault(nextTarget);
    };
    const onEmojiKeyboardTriggered = () => {
        if (loadEmojiStrings) {
            emojiPlugin.setStrings({ ...EmojiDescriptionStrings, ...EmojiKeywordStrings, ...EmojiFamilyStrings });
        }
        console.log("Emoji started from keyboard");
    };
    let commandBarPlugin: RoosterCommandBarPlugin = null;
    let emojiPlugin: EmojiPlugin = null;

    return (
        <FocusOutShell allowMouseDown={focusOutShellAllowMouseDown} onBlur={focusOutShellOnBlur} onFocus={focusOutShellOnFocus} shouldCallBlur={shouldCallBlur}>
            {(calloutClassName: string, calloutOnDismiss: FocusEventHandler) => {
                emojiPlugin =
                    emojiPlugin ||
                    new EmojiPlugin({
                        calloutClassName,
                        calloutOnDismiss,
                        onKeyboardTriggered: onEmojiKeyboardTriggered,
                        emojiPaneProps
                    } as EmojiPluginOptions);
                commandBarPlugin =
                    commandBarPlugin ||
                    new RoosterCommandBarPlugin({
                        onShortcutTriggered: (command: RoosterShortcutCommands) => console.log(command),
                        disableListWorkaround: true,
                        calloutClassName,
                        calloutOnDismiss,
                        strings: {
                            [InsertLinkStringKeys.InsertButton]: "Insert Link",
                            [InsertLinkStringKeys.CancelButton]: "Close",
                            [InsertLinkStringKeys.Title]: "Insert link",
                            [InsertLinkStringKeys.LinkFieldLabel]: "Url"
                        },
                        linkDialogClassName: "link-diag"
                    });

                return [
                    <LeanRooster
                        key="rooster"
                        viewState={leanRoosterViewState}
                        placeholder={`${name} placeholder`}
                        plugins={[
                            commandBarPlugin,
                            imagePlugin,
                            emojiPlugin,
                            imageResizePlugin,
                            new TableResize(),
                            new ContentChangedLoggerPlugin(),
                            new DoubleClickImagePlugin(excludePlaceholderSelector)
                        ]}
                        undo={new UndoWithImagePlugin(imageManager)}
                        ref={leanRoosterOnRef}
                        contentDivRef={leanRoosterContentDivOnRef}
                        hyperlinkToolTipCallback={(url: string) => `CTRL+Click to follow link\n${url}`}
                        clickOpenHyperlinkViewMode={true}
                        defaultFormat={{}}
                        data-foo="bar"
                    />,
                    <RoosterCommandBar
                        key="cmd"
                        className="lean-cmdbar"
                        buttonOverrides={[
                            { key: ButtonKeys.Strikethrough, exclude: true },
                            {
                                key: "vacation",
                                name: "Vacation",
                                iconProps: { iconName: "Vacation" },
                                handleChange: () => {
                                    console.log(leanRooster.getContent());
                                    alert("Hello");
                                    setTimeout(() => {
                                        leanRoosterViewState.content = "";
                                        leanRooster.reloadContent();
                                    }, 2000);
                                },
                                order: 0
                            },
                            { key: ButtonKeys.Bold, className: "my-button-root", buttonClassName: "my-button" },
                            { key: ButtonKeys.FontColor, className: "my-button-root", buttonClassName: "my-button" }
                        ]}
                        roosterCommandBarPlugin={commandBarPlugin}
                        emojiPlugin={emojiPlugin}
                        calloutClassName={calloutClassName}
                        calloutOnDismiss={calloutOnDismiss}
                        imageManager={imageManager}
                        ref={commandBarOnRef}
                        onButtonClicked={buttonKey => {
                            if (buttonKey === ButtonKeys.InsertImage) {
                                suppressBlur = true;
                            }

                            console.log(buttonKey);
                        }}
                        overflowMenuProps={{ className: "custom-overflow" }}
                        disableListWorkaround={true}
                        tooltipDirectionHint={DirectionalHint.bottomCenter}
                    />
                ];
            }}
        </FocusOutShell>
    );
}