From e790441943177b851e11ecd88382832fb43c8cfc Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Wed, 14 Aug 2024 15:20:37 -0700 Subject: [PATCH 1/2] Add example for `markdown` component + Test out ability to import markdown files from the source code - ensure that works through the webpack build. --- client-app/src/desktop/AppModel.ts | 1 + .../src/desktop/tabs/other/MarkdownPanel.tsx | 71 +++++++++++++++++++ .../tabs/other/MarkdownPanelContent.md | 43 +++++++++++ client-app/src/desktop/tabs/other/OtherTab.ts | 2 + 4 files changed, 117 insertions(+) create mode 100644 client-app/src/desktop/tabs/other/MarkdownPanel.tsx create mode 100644 client-app/src/desktop/tabs/other/MarkdownPanelContent.md diff --git a/client-app/src/desktop/AppModel.ts b/client-app/src/desktop/AppModel.ts index 9373af48c..5e4213fe4 100755 --- a/client-app/src/desktop/AppModel.ts +++ b/client-app/src/desktop/AppModel.ts @@ -177,6 +177,7 @@ export class AppModel extends BaseAppModel { {name: 'inspector', path: '/inspector'}, {name: 'jsx', path: '/jsx'}, {name: 'leftRightChooser', path: '/leftRightChooser'}, + {name: 'markdown', path: '/markdown'}, {name: 'pinPad', path: '/pinPad'}, {name: 'placeholder', path: '/placeholder'}, {name: 'popups', path: '/popups'}, diff --git a/client-app/src/desktop/tabs/other/MarkdownPanel.tsx b/client-app/src/desktop/tabs/other/MarkdownPanel.tsx new file mode 100644 index 000000000..518f1c8da --- /dev/null +++ b/client-app/src/desktop/tabs/other/MarkdownPanel.tsx @@ -0,0 +1,71 @@ +import {div, vbox} from '@xh/hoist/cmp/layout'; +import {markdown} from '@xh/hoist/cmp/markdown'; +import {creates, hoistCmp, HoistModel} from '@xh/hoist/core'; +import {codeInput} from '@xh/hoist/desktop/cmp/input'; +import {panel} from '@xh/hoist/desktop/cmp/panel'; +import {Icon} from '@xh/hoist/icon'; +import {bindable, makeObservable} from '@xh/hoist/mobx'; +import React from 'react'; +import {wrapper} from '../../common'; +import './JsxPanel.scss'; +// @ts-ignore +import content from './MarkdownPanelContent.md'; + +class MarkdownModel extends HoistModel { + @bindable content: string = ''; + + constructor() { + super(); + makeObservable(this); + + fetch(content) + .then(response => response.text()) + .then(text => (this.content = text)); + } +} + +export const markdownPanel = hoistCmp.factory({ + model: creates(MarkdownModel), + render({model}) { + return wrapper({ + description: [ +

+ Hoist supplies a markdown component that wraps the react-markdown + library and will convert a markdown string into a React element tree. +

+ ], + item: vbox({ + width: 800, + height: 800, + style: {gap: '10px'}, + items: [ + panel({ + title: 'Source Text', + icon: Icon.edit(), + flex: 1, + item: codeInput({ + bind: 'content', + commitOnChange: true, + width: '100%', + height: '100%' + }) + }), + panel({ + title: 'Rendered Markdown', + icon: Icon.magic(), + modelConfig: { + modalSupport: true, + collapsible: false, + resizable: false + }, + flex: 1, + item: div({ + style: {overflowY: 'scroll', padding: '5px 10px'}, + item: markdown({content: model.content, lineBreaks: false}) + }) + }) + ] + }) + }); + } +}); diff --git a/client-app/src/desktop/tabs/other/MarkdownPanelContent.md b/client-app/src/desktop/tabs/other/MarkdownPanelContent.md new file mode 100644 index 000000000..f65d76e1a --- /dev/null +++ b/client-app/src/desktop/tabs/other/MarkdownPanelContent.md @@ -0,0 +1,43 @@ +# Markdown Demo + +You can edit this sample text using the `codeInput` below to see the rendered output +update as you go. + +------ + +## GitHub Flavored Markdown + +The Hoist wrapper automatically includes support for GitHub Flavored Markdown (GFM) +via the `react-gfm` plugin. + +### Table Support + +| GFM Extension | Supported | +|:--------------|:---------:| +| Tables | ✅ | +| Tasks | ✅ | +| Magic | ❌ | + +### Task Lists + +- [x] Add initial markdown content +- [x] Test GFM support for things like task lists +- [ ] Continue winning + +## Customizations in this Example + +The rendered markdown below includes a few customizations: +* The `lineBreaks` option is set to `false` to allow this markdown source to wrap + more aggressively, without introducing line breaks in the rendered output. +* The `markdown` component has been nested within a `div` to provide a bit of padding + and set `overflow-y: scroll`. The component itself does not do this automatically. + +## Importing markdown content from source files + +This initial markdown content was imported from a file checked in alongside the code. +This might be useful for lengthy markdown content that should land in source control, +e.g. inline documentation. + +See the source within [`MarkdownPanel.tsx`](https://github.com/xh/toolbox/blob/develop/client-app/src/desktop/tabs/other/MarkdownPanel.tsx) +to review how it is imported and loaded _(hint, `fetch` is involved)_. + diff --git a/client-app/src/desktop/tabs/other/OtherTab.ts b/client-app/src/desktop/tabs/other/OtherTab.ts index b417b0f70..d6fce9eab 100644 --- a/client-app/src/desktop/tabs/other/OtherTab.ts +++ b/client-app/src/desktop/tabs/other/OtherTab.ts @@ -13,6 +13,7 @@ import {iconsPanel} from './IconsPanel'; import {inspectorPanel} from './InspectorPanel'; import {jsxPanel} from './JsxPanel'; import {leftRightChooserPanel} from './LeftRightChooserPanel'; +import {markdownPanel} from './MarkdownPanel'; import {pinPadPanel} from './PinPadPanel'; import {placeholderPanel} from './PlaceholderPanel'; import {popupsPanel} from './PopupsPanel'; @@ -42,6 +43,7 @@ export const otherTab = hoistCmp.factory(() => {id: 'icons', content: iconsPanel}, {id: 'inspector', content: inspectorPanel}, {id: 'leftRightChooser', title: 'LeftRightChooser', content: leftRightChooserPanel}, + {id: 'markdown', content: markdownPanel}, {id: 'pinPad', title: 'PIN Pad', content: pinPadPanel}, {id: 'placeholder', title: 'Placeholder', content: placeholderPanel}, {id: 'popups', content: popupsPanel}, From cc860d33d69938c38a95adb423ac0243d7c33eac Mon Sep 17 00:00:00 2001 From: Anselm McClain Date: Wed, 14 Aug 2024 15:39:54 -0700 Subject: [PATCH 2/2] Tweak flex between editor and preview --- client-app/src/desktop/tabs/other/MarkdownPanel.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client-app/src/desktop/tabs/other/MarkdownPanel.tsx b/client-app/src/desktop/tabs/other/MarkdownPanel.tsx index 518f1c8da..5b829862d 100644 --- a/client-app/src/desktop/tabs/other/MarkdownPanel.tsx +++ b/client-app/src/desktop/tabs/other/MarkdownPanel.tsx @@ -42,7 +42,7 @@ export const markdownPanel = hoistCmp.factory({ panel({ title: 'Source Text', icon: Icon.edit(), - flex: 1, + flex: 2, item: codeInput({ bind: 'content', commitOnChange: true, @@ -58,7 +58,7 @@ export const markdownPanel = hoistCmp.factory({ collapsible: false, resizable: false }, - flex: 1, + flex: 3, item: div({ style: {overflowY: 'scroll', padding: '5px 10px'}, item: markdown({content: model.content, lineBreaks: false})