Adds initial docs for code editor

This commit is contained in:
Steve Ruiz 2021-06-27 14:53:06 +01:00
parent d28376845f
commit 3f4f5e73ae
15 changed files with 1234 additions and 24 deletions

View file

@ -1,4 +1,6 @@
import styled from 'styles'
import ReactMarkdown from 'react-markdown'
import docs from './docs-content'
export default function CodeDocs({
isHidden,
@ -7,7 +9,7 @@ export default function CodeDocs({
}): JSX.Element {
return (
<StyledDocs isHidden={isHidden}>
<h2>Docs</h2>
<ReactMarkdown>{docs.content}</ReactMarkdown>
</StyledDocs>
)
}
@ -20,10 +22,11 @@ const StyledDocs = styled('div', {
width: '100%',
height: '100%',
padding: 16,
font: '$docs',
overflowY: 'scroll',
userSelect: 'none',
paddingBottom: 64,
fontFamily: '$body',
fontWeight: 500,
variants: {
isHidden: {
@ -36,11 +39,21 @@ const StyledDocs = styled('div', {
},
},
'& ol': {},
'& p': {
fontSize: '$3',
lineHeight: '1.3',
},
'& ol, ul': {
fontSize: '$3',
lineHeight: '1.3',
marginTop: 16,
marginBottom: 16,
},
'& li': {
marginTop: 8,
marginBottom: 4,
fontSize: '$3',
lineHeight: '1.5',
},
'& code': {
@ -53,7 +66,7 @@ const StyledDocs = styled('div', {
},
'& h2': {
margin: '24px 0px',
margin: '40px 0px 24px 0',
},
'& h3': {
@ -63,7 +76,7 @@ const StyledDocs = styled('div', {
'& h3 > code': {
fontWeight: 600,
font: '$monoheading',
font: '$mono',
},
'& h4': {
@ -71,7 +84,7 @@ const StyledDocs = styled('div', {
},
'& h4 > code': {
font: '$monoheading',
font: '$mono',
fontSize: 16,
userSelect: 'all',
},
@ -82,7 +95,10 @@ const StyledDocs = styled('div', {
},
'& pre': {
backgroundColor: '$bounds_bg',
border: '1px solid $brushStroke',
font: '$ui',
fontWeight: 420,
lineHeight: 1.5,
padding: 16,
borderRadius: 4,
userSelect: 'all',
@ -90,10 +106,10 @@ const StyledDocs = styled('div', {
},
'& p > code, blockquote > code': {
backgroundColor: '$bounds_bg',
padding: '2px 4px',
borderRadius: 2,
color: '$code',
color: '$text',
backgroundColor: '$codeHl',
},
'& blockquote': {

View file

@ -135,6 +135,7 @@ export default function CodePanel(): JSX.Element {
ref={rContainer}
isOpen={isOpen}
variant="code"
onWheel={(e) => e.stopPropagation()}
>
{isOpen ? (
<Panel.Layout>

View file

@ -0,0 +1,130 @@
/* eslint-disable */
// HEY! DO NOT MODIFY THIS FILE. THE CONTENTS OF THIS FILE
// ARE AUTO-GENERATED BY A SCRIPT AT: /scripts/docs-gen.js
// ANY CHANGES WILL BE LOST WHEN THE SCRIPT RUNS AGAIN!
export default {
name: 'docs-content.ts',
content: `
Welcome to the documentation for tldraw's code editor. You can use the code editor to create shapes using JavaScript or TypeScript code.
\`\`\`ts
const rect = new Rectangle({
point: [100, 100],
size: [200, 200],
style: {
color: ColorStyle.Blue
}
})
rect.x = 300
\`\`\`
To run your code, press **Command + S**.
Your new shapes will appear on the canvas. You can interact with code-created shapes just like any other shape: you can move the shape, change its style, delete it, etc.
Each time you run your code, any existing code-created shapes will be replaced by your new code-created shapes. If you want to keep your code-created shapes, select the shapes that you want to keep, press **Command + D** to duplicate them, and move them off to the side.
## Shapes
You can use the code editor to create any of the regular shapes:
- Draw
- Rectangle
- Ellipse
- Arrow
- Text
You can also create shapes that can _only_ be created with code:
- Dot
- Ray
- Line
- Polyline
Each of these shapes is a \`class\`. To create the shape, use the following syntax:
\`\`\`ts
const myShape = new Rectangle()
\`\`\`
You can also create a shape with custom properties like this:
\`\`\`ts
const myShape = new Rectangle({
point: [100, 100],
size: [200, 200],
style: {
color: ColorStyle.Blue,
size: SizeStyle.Large,
dash: DashStyle.Dotted
}
})
\`\`\`
Once you've created a shape, you can set its properties like this:
\`\`\`ts
const myShape = new Rectangle()
myShape.x = 100
myShape.color = ColorStyle.Red
\`\`\`
You can find more information on each shape class by clicking its name in the list above.
## Controls
In addition to shapes, you can also use code to create controls.
\`\`\`ts
new NumberControl({
label: "x",
value: 0
})
const myShape = new Rectangle({
point: [controls.x, 0]
})
\`\`\`
Once you've created a control, the app's will display a panel where you can edit the control's value. As you edit the value, your code will run again with the control's new value.
There are two kinds of controls:
- NumberControl
- VectorControl
- TextControl
Each of these controls is a \`class\`. To create the control, use the following syntax:
\`\`\`ts
const control = new TextControl({
label: "myLabel",
value: "my value"
})
\`\`\`
Once you've created a control, you can use its value in your code like this:
\`\`\`ts
const myShape = new Text({
text: controls.myLabel
})
\`\`\`
You can find more information on each control class by clicking its name in the list above.
## Shape Classes
...
## Control Classes
...
`,
}

View file

@ -388,7 +388,556 @@ type CodeControl =
| NumberCodeControl
| VectorCodeControl
| TextCodeControl
| SelectCodeControl
type PropsOfType<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends boolean ? K : never
}[keyof T]
type Mutable<T extends Shape> = { -readonly [K in keyof T]: T[K] }
interface ShapeUtility<K extends Shape> {
// A cache for the computed bounds of this kind of shape.
boundsCache: WeakMap<K, Bounds>
// Whether to show transform controls when this shape is selected.
canTransform: boolean
// Whether the shape's aspect ratio can change.
canChangeAspectRatio: boolean
// Whether the shape's style can be filled.
canStyleFill: boolean
// Whether the shape may be edited in an editing mode
canEdit: boolean
// Whether the shape is a foreign object.
isForeignObject: boolean
// Whether the shape can contain other shapes.
isParent: boolean
// Whether the shape is only shown when on hovered.
isShy: boolean
// Create a new shape.
create(props: Partial<K>): K
// Update a shape's styles
applyStyles(
this: ShapeUtility<K>,
shape: Mutable<K>,
style: Partial<ShapeStyles>
): ShapeUtility<K>
translateBy(
this: ShapeUtility<K>,
shape: Mutable<K>,
point: number[]
): ShapeUtility<K>
translateTo(
this: ShapeUtility<K>,
shape: Mutable<K>,
point: number[]
): ShapeUtility<K>
rotateBy(
this: ShapeUtility<K>,
shape: Mutable<K>,
rotation: number
): ShapeUtility<K>
rotateTo(
this: ShapeUtility<K>,
shape: Mutable<K>,
rotation: number,
delta: number
): ShapeUtility<K>
// Transform to fit a new bounding box when more than one shape is selected.
transform(
this: ShapeUtility<K>,
shape: Mutable<K>,
bounds: Bounds,
info: {
type: Edge | Corner
initialShape: K
scaleX: number
scaleY: number
transformOrigin: number[]
}
): ShapeUtility<K>
// Transform a single shape to fit a new bounding box.
transformSingle(
this: ShapeUtility<K>,
shape: Mutable<K>,
bounds: Bounds,
info: {
type: Edge | Corner
initialShape: K
scaleX: number
scaleY: number
transformOrigin: number[]
}
): ShapeUtility<K>
setProperty<P extends keyof K>(
this: ShapeUtility<K>,
shape: Mutable<K>,
prop: P,
value: K[P]
): ShapeUtility<K>
// Respond when any child of this shape changes.
onChildrenChange(
this: ShapeUtility<K>,
shape: Mutable<K>,
children: Shape[]
): ShapeUtility<K>
// Respond when a user moves one of the shape's bound elements.
onBindingChange(
this: ShapeUtility<K>,
shape: Mutable<K>,
bindings: Record<string, ShapeBinding>
): ShapeUtility<K>
// Respond when a user moves one of the shape's handles.
onHandleChange(
this: ShapeUtility<K>,
shape: Mutable<K>,
handle: Partial<K['handles']>
): ShapeUtility<K>
onDoublePointHandle(
this: ShapeUtility<K>,
shape: Mutable<K>,
handle: keyof K['handles'],
info: PointerInfo
): ShapeUtility<K>
// Respond when a user double clicks the shape's bounds.
onBoundsReset(this: ShapeUtility<K>, shape: Mutable<K>): ShapeUtility<K>
// Respond when a user double clicks the center of the shape.
onDoubleFocus(this: ShapeUtility<K>, shape: Mutable<K>): ShapeUtility<K>
// Clean up changes when a session ends.
onSessionComplete(this: ShapeUtility<K>, shape: Mutable<K>): ShapeUtility<K>
// Render a shape to JSX.
render(
this: ShapeUtility<K>,
shape: K,
info: {
isEditing: boolean
ref?: React.MutableRefObject<HTMLTextAreaElement>
}
): JSX.Element
invalidate(this: ShapeUtility<K>, shape: K): ShapeUtility<K>
// Get the bounds of the a shape.
getBounds(this: ShapeUtility<K>, shape: K): Bounds
// Get the routated bounds of the a shape.
getRotatedBounds(this: ShapeUtility<K>, shape: K): Bounds
// Get the center of the shape
getCenter(this: ShapeUtility<K>, shape: K): number[]
// Test whether a point lies within a shape.
hitTest(this: ShapeUtility<K>, shape: K, test: number[]): boolean
// Test whether bounds collide with or contain a shape.
hitTestBounds(this: ShapeUtility<K>, shape: K, bounds: Bounds): boolean
// Get whether the shape should delete
shouldDelete(this: ShapeUtility<K>, shape: K): boolean
// Get whether the shape should render
shouldRender(this: ShapeUtility<K>, shape: K, previous: K): boolean
}
enum ShapeType {
Dot = 'dot',
Ellipse = 'ellipse',
Line = 'line',
Ray = 'ray',
Polyline = 'polyline',
Rectangle = 'rectangle',
Draw = 'draw',
Arrow = 'arrow',
Text = 'text',
Group = 'group',
}
enum ColorStyle {
White = 'White',
LightGray = 'LightGray',
Gray = 'Gray',
Black = 'Black',
Green = 'Green',
Cyan = 'Cyan',
Blue = 'Blue',
Indigo = 'Indigo',
Violet = 'Violet',
Red = 'Red',
Orange = 'Orange',
Yellow = 'Yellow',
}
enum SizeStyle {
Small = 'Small',
Medium = 'Medium',
Large = 'Large',
}
enum DashStyle {
Solid = 'Solid',
Dashed = 'Dashed',
Dotted = 'Dotted',
}
enum FontSize {
Small = 'Small',
Medium = 'Medium',
Large = 'Large',
ExtraLarge = 'ExtraLarge',
}
type ShapeStyles = {
color: ColorStyle
size: SizeStyle
dash: DashStyle
isFilled: boolean
}
interface BaseShape {
id: string
type: ShapeType
parentId: string
childIndex: number
isGenerated: boolean
name: string
point: number[]
style: ShapeStyles
rotation: number
children?: string[]
bindings?: Record<string, ShapeBinding>
handles?: Record<string, ShapeHandle>
isLocked: boolean
isHidden: boolean
isAspectRatioLocked: boolean
}
interface DotShape extends BaseShape {
type: ShapeType.Dot
}
interface EllipseShape extends BaseShape {
type: ShapeType.Ellipse
radiusX: number
radiusY: number
}
interface LineShape extends BaseShape {
type: ShapeType.Line
direction: number[]
}
interface RayShape extends BaseShape {
type: ShapeType.Ray
direction: number[]
}
interface PolylineShape extends BaseShape {
type: ShapeType.Polyline
points: number[][]
}
interface RectangleShape extends BaseShape {
type: ShapeType.Rectangle
size: number[]
radius: number
}
interface DrawShape extends BaseShape {
type: ShapeType.Draw
points: number[][]
}
interface ArrowShape extends BaseShape {
type: ShapeType.Arrow
handles: Record<string, ShapeHandle>
bend: number
decorations?: {
start: Decoration
end: Decoration
middle: Decoration
}
}
interface TextShape extends BaseShape {
type: ShapeType.Text
text: string
scale: number
}
interface GroupShape extends BaseShape {
type: ShapeType.Group
children: string[]
size: number[]
}
// type DeepPartial<T> = {
// [P in keyof T]?: DeepPartial<T[P]>
// }
type ShapeProps<T extends Shape> = {
[P in keyof T]?: P extends 'style' ? Partial<T[P]> : T[P]
}
type MutableShape =
| DotShape
| EllipseShape
| LineShape
| RayShape
| PolylineShape
| DrawShape
| RectangleShape
| ArrowShape
| TextShape
| GroupShape
interface Shapes {
[ShapeType.Dot]: Readonly<DotShape>
[ShapeType.Ellipse]: Readonly<EllipseShape>
[ShapeType.Line]: Readonly<LineShape>
[ShapeType.Ray]: Readonly<RayShape>
[ShapeType.Polyline]: Readonly<PolylineShape>
[ShapeType.Draw]: Readonly<DrawShape>
[ShapeType.Rectangle]: Readonly<RectangleShape>
[ShapeType.Arrow]: Readonly<ArrowShape>
[ShapeType.Text]: Readonly<TextShape>
[ShapeType.Group]: Readonly<GroupShape>
}
type Shape = Readonly<MutableShape>
type ShapeByType<T extends ShapeType> = Shapes[T]
enum Decoration {
Arrow = 'Arrow',
}
interface ShapeBinding {
id: string
index: number
point: number[]
}
interface ShapeHandle {
id: string
index: number
point: number[]
}
interface CodeFile {
id: string
name: string
code: string
}
interface CodeError {
message: string
line: number
column: number
}
interface CodeResult {
shapes: Shape[]
controls: CodeControl[]
error: CodeError
}
/* -------------------------------------------------- */
/* Editor UI */
/* -------------------------------------------------- */
interface PointerInfo {
target: string
pointerId: number
origin: number[]
point: number[]
pressure: number
shiftKey: boolean
ctrlKey: boolean
metaKey: boolean
altKey: boolean
}
enum Edge {
Top = 'top_edge',
Right = 'right_edge',
Bottom = 'bottom_edge',
Left = 'left_edge',
}
enum Corner {
TopLeft = 'top_left_corner',
TopRight = 'top_right_corner',
BottomRight = 'bottom_right_corner',
BottomLeft = 'bottom_left_corner',
}
interface Bounds {
minX: number
minY: number
maxX: number
maxY: number
width: number
height: number
rotation?: number
}
interface RotatedBounds extends Bounds {
rotation: number
}
interface ShapeBounds extends Bounds {
id: string
}
interface PointSnapshot extends Bounds {
nx: number
nmx: number
ny: number
nmy: number
}
interface BoundsSnapshot extends PointSnapshot {
nw: number
nh: number
}
type Difference<A, B> = A extends B ? never : A
type ShapeSpecificProps<T extends Shape> = Pick<
T,
Difference<keyof T, keyof BaseShape>
>
type ShapeIndicatorProps<T extends Shape> = ShapeSpecificProps<T>
type ShapeUtil<K extends Shape> = {
create(props: Partial<K>): K
getBounds(shape: K): Bounds
hitTest(shape: K, test: number[]): boolean
hitTestBounds(shape: K, bounds: Bounds): boolean
rotate(shape: K): K
translate(shape: K, delta: number[]): K
scale(shape: K, scale: number): K
stretch(shape: K, scaleX: number, scaleY: number): K
render(shape: K): JSX.Element
}
enum MoveType {
Backward,
Forward,
ToFront,
ToBack,
}
enum AlignType {
Top,
CenterVertical,
Bottom,
Left,
CenterHorizontal,
Right,
}
enum StretchType {
Horizontal,
Vertical,
}
enum DistributeType {
Horizontal,
Vertical,
}
interface BezierCurveSegment {
start: number[]
tangentStart: number[]
normalStart: number[]
pressureStart: number
end: number[]
tangentEnd: number[]
normalEnd: number[]
pressureEnd: number
}
/* -------------------------------------------------- */
/* Code Editor */
/* -------------------------------------------------- */
enum ControlType {
Number = 'number',
Vector = 'vector',
Text = 'text',
Select = 'select',
}
interface BaseCodeControl {
id: string
type: ControlType
label: string
}
interface NumberCodeControl extends BaseCodeControl {
type: ControlType.Number
value: number
min?: number
max?: number
step?: number
format?: (value: number) => number
}
interface VectorCodeControl extends BaseCodeControl {
type: ControlType.Vector
value: number[]
min?: number
max?: number
step?: number
isNormalized?: boolean
format?: (value: number[]) => number[]
}
interface TextCodeControl extends BaseCodeControl {
type: ControlType.Text
value: string
format?: (value: string) => string
}
interface SelectCodeControl<T extends string = ''>
extends BaseCodeControl {
type: ControlType.Select
value: T
options: T[]
format?: (string: T) => string
}
type CodeControl =
| NumberCodeControl
| VectorCodeControl
| TextCodeControl
type PropsOfType<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends boolean ? K : never
@ -2814,6 +3363,20 @@ class VectorControl extends Control<VectorCodeControl> {
}
}
class TextControl extends Control<TextCodeControl> {
constructor(options: ControlProps<TextCodeControl>) {
const { id = uniqueId(), label = 'Text', value = 'text' } = options
super({
type: ControlType.Text,
...options,
label,
value,
id,
})
}
}
const codeShapes = new Set<CodeShape<any>>()
const controls: Record<string, any> = {}

View file

@ -1,6 +1,11 @@
import state, { useSelector } from 'state'
import styled from 'styles'
import { ControlType, NumberCodeControl, VectorCodeControl } from 'types'
import {
ControlType,
NumberCodeControl,
TextCodeControl,
VectorCodeControl,
} from 'types'
export default function Control({ id }: { id: string }): JSX.Element {
const control = useSelector((s) => s.data.codeControls[id])
@ -10,11 +15,16 @@ export default function Control({ id }: { id: string }): JSX.Element {
return (
<>
<label>{control.label}</label>
{control.type === ControlType.Number ? (
<NumberControl {...control} />
) : control.type === ControlType.Vector ? (
<VectorControl {...control} />
) : null}
{(() => {
switch (control.type) {
case ControlType.Number:
return <NumberControl {...control} />
case ControlType.Vector:
return <VectorControl {...control} />
case ControlType.Text:
return <TextControl {...control} />
}
})()}
</>
)
}
@ -112,6 +122,22 @@ function VectorControl({
)
}
function TextControl({ id, value }: TextCodeControl) {
return (
<Inputs>
<input
type="text"
value={value}
onChange={(e) =>
state.send('CHANGED_CODE_CONTROL', {
[id]: e.currentTarget.value,
})
}
/>
</Inputs>
)
}
const Inputs = styled('div', {
display: 'flex',
gap: '8px',
@ -131,4 +157,9 @@ const Inputs = styled('div', {
padding: 0,
flexGrow: 2,
},
"& input[type='text']": {
minWidth: 200,
padding: 4,
flexGrow: 2,
},
})

0
next.config.js Normal file
View file

View file

@ -8,7 +8,7 @@
"dev": "next dev",
"format": "prettier --write .",
"lint": "eslint . --ext ts --ext tsx --ext js",
"scripts": "node scripts/type-gen && prettier --write './components/code-panel/types-import.ts'",
"scripts": "node scripts/type-gen && node scripts/docs-gen && prettier --write './components/code-panel/*'",
"start": "next start",
"test-all": "yarn lint && yarn type-check && yarn test",
"test:update": "jest --updateSnapshot",
@ -61,6 +61,7 @@
"react-dom": "^17.0.2",
"react-error-boundary": "^3.1.3",
"react-feather": "^2.0.9",
"react-markdown": "^6.0.2",
"react-use-gesture": "^9.1.3",
"sucrase": "^3.19.0",
"uuid": "^8.3.2"

44
scripts/docs-gen.js Normal file
View file

@ -0,0 +1,44 @@
// @ts-check
/*
This script will generate content for the code editor's markdown docs. To change
the docs, edit the file at `state/code/docs.md`.
*/
const fs = require('fs/promises')
const root = process.cwd()
async function inlineFileContents(path) {
console.log(`📄 Inlining contents of ${path}`)
const text = await fs.readFile(`${root}${path}`, 'utf-8')
return text.replaceAll('`', '\\`')
}
async function copyDocsToDocsContentFile() {
console.log('⚙️ Generating docs-content.ts')
const content =
`
/* eslint-disable */
// HEY! DO NOT MODIFY THIS FILE. THE CONTENTS OF THIS FILE
// ARE AUTO-GENERATED BY A SCRIPT AT: /scripts/docs-gen.js
// ANY CHANGES WILL BE LOST WHEN THE SCRIPT RUNS AGAIN!
export default {` +
`
name: "docs-content.ts",
content: \`
${await inlineFileContents('/state/code/docs.md')}
\`}`
await fs.writeFile(
__dirname + '/../components/code-panel/docs-content.ts',
content
)
console.log('✅ Process complete')
}
// Kickoff
copyDocsToDocsContentFile()

View file

@ -2,6 +2,7 @@ import {
CodeControl,
ControlType,
NumberCodeControl,
TextCodeControl,
VectorCodeControl,
} from 'types'
import { uniqueId } from 'utils'
@ -81,3 +82,17 @@ export class VectorControl extends Control<VectorCodeControl> {
})
}
}
export class TextControl extends Control<TextCodeControl> {
constructor(options: ControlProps<TextCodeControl>) {
const { id = uniqueId(), label = 'Text', value = 'text' } = options
super({
type: ControlType.Text,
...options,
label,
value,
id,
})
}
}

119
state/code/docs.md Normal file
View file

@ -0,0 +1,119 @@
Welcome to the documentation for tldraw's code editor. You can use the code editor to create shapes using JavaScript or TypeScript code.
```ts
const rect = new Rectangle({
point: [100, 100],
size: [200, 200],
style: {
color: ColorStyle.Blue
}
})
rect.x = 300
```
To run your code, press **Command + S**.
Your new shapes will appear on the canvas. You can interact with code-created shapes just like any other shape: you can move the shape, change its style, delete it, etc.
Each time you run your code, any existing code-created shapes will be replaced by your new code-created shapes. If you want to keep your code-created shapes, select the shapes that you want to keep, press **Command + D** to duplicate them, and move them off to the side.
## Shapes
You can use the code editor to create any of the regular shapes:
- Draw
- Rectangle
- Ellipse
- Arrow
- Text
You can also create shapes that can _only_ be created with code:
- Dot
- Ray
- Line
- Polyline
Each of these shapes is a `class`. To create the shape, use the following syntax:
```ts
const myShape = new Rectangle()
```
You can also create a shape with custom properties like this:
```ts
const myShape = new Rectangle({
point: [100, 100],
size: [200, 200],
style: {
color: ColorStyle.Blue,
size: SizeStyle.Large,
dash: DashStyle.Dotted
}
})
```
Once you've created a shape, you can set its properties like this:
```ts
const myShape = new Rectangle()
myShape.x = 100
myShape.color = ColorStyle.Red
```
You can find more information on each shape class by clicking its name in the list above.
## Controls
In addition to shapes, you can also use code to create controls.
```ts
new NumberControl({
label: "x",
value: 0
})
const myShape = new Rectangle({
point: [controls.x, 0]
})
```
Once you've created a control, the app's will display a panel where you can edit the control's value. As you edit the value, your code will run again with the control's new value.
There are two kinds of controls:
- NumberControl
- VectorControl
- TextControl
Each of these controls is a `class`. To create the control, use the following syntax:
```ts
const control = new TextControl({
label: "myLabel",
value: "my value"
})
```
Once you've created a control, you can use its value in your code like this:
```ts
const myShape = new Text({
text: controls.myLabel
})
```
You can find more information on each control class by clicking its name in the list above.
## Shape Classes
...
## Control Classes
...

View file

@ -9,7 +9,13 @@ import Draw from './draw'
import Text from './text'
import Utils from './utils'
import Vec from 'utils/vec'
import { NumberControl, VectorControl, codeControls, controls } from './control'
import {
NumberControl,
VectorControl,
TextControl,
codeControls,
controls,
} from './control'
import { codeShapes } from './index'
import {
CodeControl,
@ -37,6 +43,7 @@ const baseScope = {
Arrow,
Draw,
Text,
TextControl,
VectorControl,
NumberControl,
DashStyle,

View file

@ -1863,6 +1863,7 @@ const state = createState({
saveCode(data, payload: { code: string }) {
data.document.code[data.currentCodeFileId].code = payload.code
storage.saveDocumentToLocalStorage(data)
storage.saveAppStateToLocalStorage(data)
},
clearBoundsRotation(data) {

View file

@ -6,6 +6,7 @@ const { styled, global, css, theme, getCssString } = createCss({
},
theme: {
colors: {
codeHl: 'rgba(144, 144, 144, .15)',
brushFill: 'rgba(0,0,0,.05)',
brushStroke: 'rgba(0,0,0,.25)',
hint: 'rgba(216, 226, 249, 1.000)',
@ -35,6 +36,8 @@ const { styled, global, css, theme, getCssString } = createCss({
},
fonts: {
ui: '"Recursive", system-ui, sans-serif',
body: '"Recursive", system-ui, sans-serif',
mono: '"Recursive", monospace',
},
fontWeights: {},
lineHeights: {},

View file

@ -433,7 +433,6 @@ export type CodeControl =
| NumberCodeControl
| VectorCodeControl
| TextCodeControl
| SelectCodeControl
export type PropsOfType<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends boolean ? K : never

284
yarn.lock
View file

@ -1990,6 +1990,13 @@
dependencies:
"@types/node" "*"
"@types/hast@^2.0.0":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.1.tgz#b16872f2a6144c7025f296fb9636a667ebb79cd9"
integrity sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==
dependencies:
"@types/unist" "*"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
@ -2027,6 +2034,13 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/mdast@^3.0.0":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb"
integrity sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==
dependencies:
"@types/unist" "*"
"@types/minimatch@*":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21"
@ -2100,6 +2114,11 @@
dependencies:
source-map "^0.6.1"
"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
"@types/uuid@^8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
@ -2628,6 +2647,11 @@ babel-preset-jest@^27.0.1:
babel-plugin-jest-hoist "^27.0.1"
babel-preset-current-node-syntax "^1.0.0"
bail@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"
integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -2891,6 +2915,21 @@ char-regex@^1.0.2:
resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
character-entities-legacy@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==
character-entities@^1.0.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b"
integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==
character-reference-invalid@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
chokidar@3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
@ -3034,6 +3073,11 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
comma-separated-tokens@^1.0.0:
version "1.0.8"
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea"
integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@ -3261,7 +3305,7 @@ debug@2, debug@^2.6.9:
dependencies:
ms "2.0.0"
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1:
debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
@ -3847,6 +3891,11 @@ expect@^27.0.2:
jest-message-util "^27.0.2"
jest-regex-util "^27.0.1"
extend@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@ -4451,6 +4500,11 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
inline-style-parser@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1"
integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==
internal-slot@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
@ -4467,6 +4521,19 @@ invariant@^2.2.4:
dependencies:
loose-envify "^1.0.0"
is-alphabetical@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==
is-alphanumerical@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf"
integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==
dependencies:
is-alphabetical "^1.0.0"
is-decimal "^1.0.0"
is-arguments@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
@ -4498,6 +4565,11 @@ is-boolean-object@^1.1.0:
dependencies:
call-bind "^1.0.2"
is-buffer@^2.0.0:
version "2.0.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
is-callable@^1.1.4, is-callable@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e"
@ -4522,6 +4594,11 @@ is-date-object@^1.0.1:
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5"
integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==
is-decimal@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5"
integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@ -4561,6 +4638,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-hexadecimal@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
is-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
@ -4613,6 +4695,11 @@ is-path-inside@^2.1.0:
dependencies:
path-is-inside "^1.0.2"
is-plain-obj@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
is-potential-custom-element-name@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
@ -5625,6 +5712,48 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
mdast-util-definitions@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2"
integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==
dependencies:
unist-util-visit "^2.0.0"
mdast-util-from-markdown@^0.8.0:
version "0.8.5"
resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c"
integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==
dependencies:
"@types/mdast" "^3.0.0"
mdast-util-to-string "^2.0.0"
micromark "~2.11.0"
parse-entities "^2.0.0"
unist-util-stringify-position "^2.0.0"
mdast-util-to-hast@^10.2.0:
version "10.2.0"
resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz#61875526a017d8857b71abc9333942700b2d3604"
integrity sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==
dependencies:
"@types/mdast" "^3.0.0"
"@types/unist" "^2.0.0"
mdast-util-definitions "^4.0.0"
mdurl "^1.0.0"
unist-builder "^2.0.0"
unist-util-generated "^1.0.0"
unist-util-position "^3.0.0"
unist-util-visit "^2.0.0"
mdast-util-to-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b"
integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==
mdurl@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
@ -5635,6 +5764,14 @@ merge2@^1.3.0:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromark@~2.11.0:
version "2.11.4"
resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a"
integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==
dependencies:
debug "^4.0.0"
parse-entities "^2.0.0"
micromatch@^4.0.2, micromatch@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
@ -6148,6 +6285,18 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5:
pbkdf2 "^3.0.3"
safe-buffer "^5.1.1"
parse-entities@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
dependencies:
character-entities "^1.0.0"
character-entities-legacy "^1.0.0"
character-reference-invalid "^1.0.0"
is-alphanumerical "^1.0.0"
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
parse-json@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
@ -6450,6 +6599,13 @@ prop-types@15.7.2, prop-types@^15.7.2:
object-assign "^4.1.1"
react-is "^16.8.1"
property-information@^5.0.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69"
integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==
dependencies:
xtend "^4.0.0"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
@ -6570,7 +6726,7 @@ react-feather@^2.0.9:
dependencies:
prop-types "^15.7.2"
react-is@17.0.2, react-is@^17.0.1:
react-is@17.0.2, react-is@^17.0.0, react-is@^17.0.1:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
@ -6580,6 +6736,25 @@ react-is@^16.7.0, react-is@^16.8.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-markdown@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-6.0.2.tgz#d89be45c278b1e5f0196f851fffb11e30c69f027"
integrity sha512-Et2AjXAsbmPP1nLQQRqmVgcqzfwcz8uQJ8VAdADs8Nk/aaUA0YeU9RDLuCtD+GwajCnm/+Iiu2KPmXzmD/M3vA==
dependencies:
"@types/hast" "^2.0.0"
"@types/unist" "^2.0.3"
comma-separated-tokens "^1.0.0"
prop-types "^15.7.2"
property-information "^5.0.0"
react-is "^17.0.0"
remark-parse "^9.0.0"
remark-rehype "^8.0.0"
space-separated-tokens "^1.1.0"
style-to-object "^0.3.0"
unified "^9.0.0"
unist-util-visit "^2.0.0"
vfile "^4.0.0"
react-refresh@0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
@ -6738,6 +6913,20 @@ regjsparser@^0.6.4:
dependencies:
jsesc "~0.5.0"
remark-parse@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640"
integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==
dependencies:
mdast-util-from-markdown "^0.8.0"
remark-rehype@^8.0.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-8.1.0.tgz#610509a043484c1e697437fa5eb3fd992617c945"
integrity sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA==
dependencies:
mdast-util-to-hast "^10.2.0"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@ -7086,6 +7275,11 @@ sourcemap-codec@^1.4.4:
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
space-separated-tokens@^1.1.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899"
integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==
spdx-correct@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
@ -7328,6 +7522,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
style-to-object@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46"
integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==
dependencies:
inline-style-parser "0.1.1"
style-value-types@4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-4.1.4.tgz#80f37cb4fb024d6394087403dfb275e8bb627e75"
@ -7562,6 +7763,11 @@ tr46@^2.1.0:
dependencies:
punycode "^2.1.1"
trough@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
ts-interface-checker@^0.1.9:
version "0.1.13"
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
@ -7716,6 +7922,18 @@ unicode-property-aliases-ecmascript@^1.0.4:
resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4"
integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==
unified@^9.0.0:
version "9.2.1"
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.1.tgz#ae18d5674c114021bfdbdf73865ca60f410215a3"
integrity sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA==
dependencies:
bail "^1.0.0"
extend "^3.0.0"
is-buffer "^2.0.0"
is-plain-obj "^2.0.0"
trough "^1.0.0"
vfile "^4.0.0"
unique-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
@ -7723,6 +7941,50 @@ unique-string@^2.0.0:
dependencies:
crypto-random-string "^2.0.0"
unist-builder@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436"
integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==
unist-util-generated@^1.0.0:
version "1.1.6"
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b"
integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==
unist-util-is@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797"
integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==
unist-util-position@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47"
integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==
unist-util-stringify-position@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==
dependencies:
"@types/unist" "^2.0.2"
unist-util-visit-parents@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6"
integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==
dependencies:
"@types/unist" "^2.0.0"
unist-util-is "^4.0.0"
unist-util-visit@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c"
integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==
dependencies:
"@types/unist" "^2.0.0"
unist-util-is "^4.0.0"
unist-util-visit-parents "^3.0.0"
universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
@ -7848,6 +8110,24 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vfile-message@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a"
integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==
dependencies:
"@types/unist" "^2.0.0"
unist-util-stringify-position "^2.0.0"
vfile@^4.0.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624"
integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==
dependencies:
"@types/unist" "^2.0.0"
is-buffer "^2.0.0"
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
vm-browserify@1.1.2, vm-browserify@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"