Skip to content

Commit

Permalink
upgrd unified, md; rewire deps; render types; opt. CodeMirror; sandbox;
Browse files Browse the repository at this point in the history
  • Loading branch information
elbakerino committed Aug 23, 2024
1 parent 091c060 commit 7faad78
Show file tree
Hide file tree
Showing 60 changed files with 28,319 additions and 15,958 deletions.
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"eslint:recommended",
"plugin:react-hooks/recommended"
],
"ignorePatterns": [
"apps/sandbox/**/*"
],
"settings": {
"react": {
"version": "detect"
Expand Down
44 changes: 35 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,37 @@

> ⚗ experimental content viewer & editor
🕹️ [codesandbox](https://codesandbox.io/p/devbox/github/control-ui/content-ui/tree/main/apps/sandbox?file=%2Fsrc%2Fmain.tsx) | [stackblitz](https://stackblitz.com/github/control-ui/content-ui/tree/main/apps/sandbox) | [source in apps/sandbox](./apps/sandbox)

## Packages

- [@content-ui/md](./packages/md) [![MIT license](https://img.shields.io/npm/l/@content-ui/md?style=flat-square)](https://github.com/control-ui/content-ui/blob/main/LICENSE) [![npm (scoped)](https://img.shields.io/npm/v/@content-ui/md?style=flat-square)](https://www.npmjs.com/package/@content-ui/md) [![JS compatibility](https://img.shields.io/badge/ESM--f7e018?style=flat-square&logo=javascript)](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c)
- markdown to AST, using [remark](https://unifiedjs.com/) for parsing
- markdown to AST, using [unifiedjs / remarkjs](https://unifiedjs.com/) for parsing
- [@content-ui/react](./packages/react) [![MIT license](https://img.shields.io/npm/l/@content-ui/react?style=flat-square)](https://github.com/control-ui/content-ui/blob/main/LICENSE) [![npm (scoped)](https://img.shields.io/npm/v/@content-ui/react?style=flat-square)](https://www.npmjs.com/package/@content-ui/react) [![react compatibility](https://img.shields.io/badge/React-%3E%3D17-success?style=flat-square&logo=react)](https://reactjs.org/) [![JS compatibility](https://img.shields.io/badge/ESM--f7e018?style=flat-square&logo=javascript)](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c)
- ReactJS hooks and providers for the other react packages
- [@content-ui/md-mui](./packages/md-mui) [![MIT license](https://img.shields.io/npm/l/@content-ui/md-mui?style=flat-square)](https://github.com/control-ui/content-ui/blob/main/LICENSE) [![npm (scoped)](https://img.shields.io/npm/v/@content-ui/md-mui?style=flat-square)](https://www.npmjs.com/package/@content-ui/md-mui) [![react compatibility](https://img.shields.io/badge/React-%3E%3D17-success?style=flat-square&logo=react)](https://reactjs.org/) [![depends on MUI](https://img.shields.io/badge/MUI-green?labelColor=1a237e&color=0d47a1&logoColor=ffffff&style=flat-square&logo=mui)](https://mui.com)
- MUI leafs for content-leafs, using [@tactic-ui](https://github.com/ui-schema/tactic-ui) for rendering
- MUI leafs for content-leafs
- [@content-ui/input](./packages/input) [![MIT license](https://img.shields.io/npm/l/@content-ui/input?style=flat-square)](https://github.com/control-ui/content-ui/blob/main/LICENSE) [![npm (scoped)](https://img.shields.io/npm/v/@content-ui/input?style=flat-square)](https://www.npmjs.com/package/@content-ui/input) [![react compatibility](https://img.shields.io/badge/React-%3E%3D17-success?style=flat-square&logo=react)](https://reactjs.org/) [![depends on MUI](https://img.shields.io/badge/MUI-green?labelColor=1a237e&color=0d47a1&logoColor=ffffff&style=flat-square&logo=mui)](https://mui.com)
- MUI styled code / text input field based on `CodeMirror`
- MUI styled code / text input field based on `CodeMirror` with preview and linting
- [@content-ui/struct](./packages/struct) [![MIT license](https://img.shields.io/npm/l/@content-ui/struct?style=flat-square)](https://github.com/control-ui/content-ui/blob/main/LICENSE) [![npm (scoped)](https://img.shields.io/npm/v/@content-ui/struct?style=flat-square)](https://www.npmjs.com/package/@content-ui/struct) [![JS compatibility](https://img.shields.io/badge/ESM--f7e018?style=flat-square&logo=javascript)](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c)
- structural helper utils and mdast typing extensions

```shell
npm i -S @content-ui/md @content-ui/react @content-ui/md-mui @content-ui/input
npm i -S @content-ui/md @content-ui/react @content-ui/md-mui
# peer-dependencies:
npm i -S @mui/material @mui/icons-material
# peer-dependencies for /input:
npm i -S react-progress-state @ui-controls/progress
# peer-dependencies for CodeMirror
npm i -S @ui-schema/kit-codemirror @codemirror/state .. todo ..
npm i -D @types/mdast

# input component with CodeMirror:
npm i -S @content-ui/md @content-ui/react @content-ui/md-mui @content-ui/input
# peer-dependencies:
npm i -S react-progress-state @ui-controls/progress @ui-schema/kit-codemirror @codemirror/state
```

> all packages are ESM-only, those with the `ESM` flag support strict-ESM for browser + NodeJS
See [CustomCodeMirror.tsx](./apps/demo/src/components/CustomCodeMirror.tsx) for an example CodeMirror component, for viewer and input, with nested syntax highlighting and quite some other things.

See [WidgetMarkdownEditor.tsx](./apps/demo/src/components/CustomWidgets/WidgetMarkdownEditor.tsx) for an example [UI-Schema widget](https://ui-schema.bemit.codes) with Markdown editor, linting and preview.

## Development
Expand All @@ -43,17 +49,37 @@ npm i
Start development servers from root folder:

```shell
npm run start
npm run dev
```

Now open the [app at `localhost:4221`](http://localhost:4221) or the [server at `localhost:4222`](http://localhost:4222).

---

Only start the simplified sandbox:

```shell
npm run start -w content-ui-sandbox
```

And open the [app at `localhost:5173`](http://localhost:5173/).

---

Lint, build typings + JS:

```shell
npm run build
```

Create new lock-file for sandbox/server requires setting `workspaces` to false.

```shell
# updating lock file requires already published packages
# first release, then update lock, then push again
cd apps/sandbox && npm i --package-lock-only --workspaces false
```

## License

This project is distributed as **free software** under the **MIT License**, see [License](https://github.com/control-ui/content-ui/blob/main/LICENSE).
Expand Down
8 changes: 4 additions & 4 deletions apps/demo/src/components/ContentUI.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { renderMapping } from '@content-ui/md-mui/LeafsMarkdown'
import { ContentLeafComponents, ContentLeafsNodeMapping, LeafsRenderMapping } from '@content-ui/react/ContentLeaf'
import { MuiContentRenderComponents, renderMapping } from '@content-ui/md-mui/LeafsMarkdown'
import { ContentLeafsNodeMapping, LeafsRenderMapping, ContentLeafMatchParams } from '@content-ui/react/ContentLeaf'
import { CustomCodeMirror } from './CustomCodeMirror.js'

export const contentUIMapping: LeafsRenderMapping<ContentLeafsNodeMapping, ContentLeafComponents, { type: string }> = {
export const contentUIMapping: LeafsRenderMapping<ContentLeafsNodeMapping, MuiContentRenderComponents, ContentLeafMatchParams> = {
...renderMapping,
leafs: {
...renderMapping.leafs,
},
components: {
...renderMapping.components,
CodeMirror: CustomCodeMirror,
Code: CustomCodeMirror,
},
matchLeaf: (p, l) => l[p.type],
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import IcEdit from '@mui/icons-material/Edit'
import IcPreview from '@mui/icons-material/Preview'
import { CustomCodeMirror, getHighlight } from '../CustomCodeMirror'
import { ContentInput } from '@content-ui/input/ContentInput'
import { useContentEditor } from '@content-ui/react/useContentEditor'
import { useContentEditor } from '@content-ui/input/useContentEditor'
import { useContent } from '@content-ui/react/useContent'
import { ContentFileProvider } from '@content-ui/react/ContentFileProvider'

Expand Down
4 changes: 2 additions & 2 deletions apps/demo/src/components/UISchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export const getCustomWidgets: () => CustomWidgetsBinding = () => ({
Time: CustomTimePicker,
Date: CustomDatePicker,
DateTime: CustomDateTimePicker,
MarkDown: WidgetMarkdownEditor,
Markdown: WidgetMarkdownEditor,
},
})

Expand All @@ -145,6 +145,6 @@ export const readWidgets: any = {
Time: TextRendererRead,
Date: TextRendererRead,
DateTime: TextRendererRead,
MarkDown: WidgetMarkdownViewer,
Markdown: WidgetMarkdownViewer,
},
}
6 changes: 3 additions & 3 deletions apps/demo/src/pages/PageForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { readWidgets } from '../components/UISchema'
import { GridContainer } from '@ui-schema/ds-material/GridContainer'
import { OrderedMap } from 'immutable'

const mdIntro = `UI-Schema based form with **read-or-write mode** and MarkDown editor.
const mdIntro = `UI-Schema based form with **read-or-write mode** and Markdown editor.
*CodeMirror* input field with highlighting and **preview mode**.
`
Expand Down Expand Up @@ -53,11 +53,11 @@ const schema = createOrderedMap<JsonSchema>({
},
intro: {
type: 'string',
widget: 'MarkDown',
widget: 'Markdown',
},
content: {
type: 'string',
widget: 'MarkDown',
widget: 'Markdown',
},
},
})
Expand Down
4 changes: 1 addition & 3 deletions apps/demo/src/pages/PageHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ Hey there this is some content, rendered from Markdown as ReactJS components usi
Some code: \`var some = true\`.
> Blockqoutes on the go..
> Blockquotes :+1:
>
> With multiple rows and a link [to the *input page*](/input).
Lorem ipsum __breaking **line**__.
---
> ⚠️ Warning Note: Experimental ⚗️
Expand Down
30 changes: 26 additions & 4 deletions apps/demo/src/pages/PageInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { ContentParser } from '@content-ui/md/parser/ContentParser'
import React from 'react'
import { useMediaQuery } from '@mui/material'
import Button from '@mui/material/Button'
import IcVisibility from '@mui/icons-material/Visibility'
import IcVisibilityOff from '@mui/icons-material/VisibilityOff'
import useTheme from '@mui/material/styles/useTheme'
import React, { useState } from 'react'
import Helmet from 'react-helmet'
import { useTranslation } from 'react-i18next'
import Grid2 from '@mui/material/Unstable_Grid2'
Expand All @@ -8,7 +13,7 @@ import { CustomCodeMirror, getHighlight } from '../components/CustomCodeMirror'
import Box from '@mui/material/Box'
import { Viewer } from '@content-ui/md-mui/Viewer'
import { SettingsProvider } from '@content-ui/react/LeafSettings'
import { useContentEditor } from '@content-ui/react/useContentEditor'
import { useContentEditor } from '@content-ui/input/useContentEditor'
import { useContent } from '@content-ui/react/useContent'
import { ContentFileProvider } from '@content-ui/react/ContentFileProvider'

Expand Down Expand Up @@ -49,6 +54,8 @@ With even more sentences, words and other things.
export const PageInput: React.ComponentType = () => {
const {t} = useTranslation('translation')
const [value, setValue] = React.useState(md)
const {breakpoints} = useTheme()
const isMediumScreen = useMediaQuery(breakpoints.up('md'))
const {
textValue,
handleOnChange,
Expand Down Expand Up @@ -79,6 +86,8 @@ export const PageInput: React.ComponentType = () => {
]
}, [])

const [showAst, setShowAst] = useState(false)

return <>
<Helmet>
<title>{t('brand')} · Content-UI</title>
Expand All @@ -91,12 +100,12 @@ export const PageInput: React.ComponentType = () => {
editorSelection={editorSelection}
>
<SettingsProvider
followEditor
followEditor={isMediumScreen}
headlineLinkable
headlineSelectable
headlineSelectableOnHover
>
<Grid2 container spacing={2} sx={{overflow: 'auto'}}>
<Grid2 container spacing={2} sx={{overflow: 'auto', flexWrap: {xs: 'wrap', md: 'nowrap'}}}>
<Grid2 xs={12} md={6} sx={{overflow: 'auto', scrollbarWidth: 'thin', maxHeight: {md: '100%'}}}>
<ContentInput
CodeMirror={CustomCodeMirror}
Expand Down Expand Up @@ -126,6 +135,19 @@ export const PageInput: React.ComponentType = () => {
processing={processing}
editorSelection={editorSelection}
/>
<Button
startIcon={showAst ? <IcVisibility/> : <IcVisibilityOff/>}
onClick={() => setShowAst(s => !s)}
variant={'outlined'}
sx={{mt: 2, mb: 1}}
>
{'AST'}
</Button>
{showAst ?
<CustomCodeMirror
value={JSON.stringify(root || null, undefined, 4)}
lang={'json'}
/> : null}
</Grid2>
</Grid2>
</SettingsProvider>
Expand Down
2 changes: 2 additions & 0 deletions apps/sandbox/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
node_modules
3 changes: 3 additions & 0 deletions apps/sandbox/.stackblitzrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"startCommand": "npm start"
}
21 changes: 21 additions & 0 deletions apps/sandbox/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 bemit UG (haftungsbeschränkt), Michael Becker https://i-am-digital.eu

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
20 changes: 20 additions & 0 deletions apps/sandbox/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Content-UI MD-MUI Sandbox</title>
<style>
#root {
display: flex;
flex-direction: column;
overflow: auto;
max-height: 100vh;
}
</style>
</head>
<body>
<div id="root">...</div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
67 changes: 67 additions & 0 deletions apps/sandbox/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"name": "content-ui-sandbox",
"version": "0.0.9",
"description": "Content-UI MD-MUI demo",
"keywords": [
"typescript",
"react",
"content-ui",
"remarkjs",
"markdown",
"mui"
],
"private": true,
"license": "MIT",
"main": "src/main.tsx",
"type": "module",
"dependencies": {
"@codemirror/commands": "^6.0.0",
"@codemirror/lang-css": "^6.0.0",
"@codemirror/lang-html": "^6.0.0",
"@codemirror/lang-javascript": "^6.0.0",
"@codemirror/lang-json": "^6.0.0",
"@codemirror/lang-lezer": "^6.0.0",
"@codemirror/lang-markdown": "^6.0.0",
"@codemirror/language": "^6.1.0",
"@codemirror/language-data": "^6.1.0",
"@codemirror/legacy-modes": "^6.1.0",
"@codemirror/search": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@content-ui/input": "0.0.6",
"@content-ui/md": "0.0.8",
"@content-ui/md-mui": "0.0.9",
"@content-ui/react": "0.0.9",
"@content-ui/struct": "0.0.2",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.10",
"@mui/lab": "^5.0.0-alpha.80",
"@mui/material": "^5.1",
"@ui-controls/progress": "~0.0.4",
"@ui-schema/ds-material": "~0.4.1",
"@ui-schema/kit-codemirror": "~0.1.0-alpha.1",
"@ui-schema/material-code": "~0.4.2",
"@ui-schema/ui-schema": "~0.4.5",
"cross-env": "^7.0.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-progress-state": "~0.3.1",
"react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"vfile": "^6.0.2",
"vfile-reporter": "^8.1.1"
},
"devDependencies": {
"@types/node": "^18.19.45",
"@types/react": "^18.3.4",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.0.0",
"typescript": "~5.3.3",
"vite": "^4.0.0"
},
"scripts": {
"start": "tsc && cross-env NODE_ENV=development vite",
"build": "tsc && cross-env NODE_ENV=production vite build"
}
}
3 changes: 3 additions & 0 deletions apps/sandbox/sandbox.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"startScript": "start"
}
Loading

0 comments on commit 7faad78

Please sign in to comment.