removed padding from printtoPDF, hid mycrozine template tool (need to fix sync), cleaned up redundancies between app & board, installed marked npm package, hid markdown tool (need to fix styles)
This commit is contained in:
parent
02f816e613
commit
7b1fe2b803
File diff suppressed because it is too large
Load Diff
|
|
@ -23,7 +23,9 @@
|
|||
"@tldraw/tldraw": "^3.6.0",
|
||||
"@tldraw/tlschema": "^3.6.0",
|
||||
"@types/markdown-it": "^14.1.1",
|
||||
"@types/marked": "^5.0.2",
|
||||
"@vercel/analytics": "^1.2.2",
|
||||
"cherry-markdown": "^0.8.57",
|
||||
"cloudflare-workers-unfurl": "^0.0.7",
|
||||
"gray-matter": "^4.0.3",
|
||||
"html2canvas": "^1.4.1",
|
||||
|
|
@ -31,6 +33,7 @@
|
|||
"jotai": "^2.6.0",
|
||||
"jspdf": "^2.5.2",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"marked": "^15.0.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^7.0.2",
|
||||
|
|
|
|||
50
src/App.tsx
50
src/App.tsx
|
|
@ -6,15 +6,14 @@ import { BrowserRouter, Route, Routes } from "react-router-dom"
|
|||
import { Contact } from "@/routes/Contact"
|
||||
import { Board } from "./routes/Board"
|
||||
import { Inbox } from "./routes/Inbox"
|
||||
import { Editor, Tldraw, TLShapeId } from "tldraw"
|
||||
import { components } from "./ui/components"
|
||||
import { overrides } from "./ui/overrides"
|
||||
import { ChatBoxShape } from "./shapes/ChatBoxShapeUtil"
|
||||
import { VideoChatShape } from "./shapes/VideoChatShapeUtil"
|
||||
import { ChatBoxTool } from "./tools/ChatBoxTool"
|
||||
import { VideoChatTool } from "./tools/VideoChatTool"
|
||||
import { EmbedTool } from "./tools/EmbedTool"
|
||||
import { EmbedShape } from "./shapes/EmbedShapeUtil"
|
||||
import { MycrozineTemplateTool } from './tools/MycrozineTemplateTool'
|
||||
import { MycrozineTemplateShape } from './shapes/MycrozineTemplateShapeUtil'
|
||||
import { MarkdownShape } from "./shapes/MarkdownShapeUtil"
|
||||
import { MarkdownTool } from "./tools/MarkdownTool"
|
||||
import { createRoot } from "react-dom/client"
|
||||
|
|
@ -22,51 +21,27 @@ import { handleInitialPageLoad } from "./utils/handleInitialPageLoad"
|
|||
import { DailyProvider } from "@daily-co/daily-react"
|
||||
import Daily from "@daily-co/daily-js"
|
||||
|
||||
|
||||
inject()
|
||||
|
||||
const customShapeUtils = [
|
||||
ChatBoxShape,
|
||||
VideoChatShape,
|
||||
EmbedShape,
|
||||
//MarkdownShape,
|
||||
MycrozineTemplateShape,
|
||||
MarkdownShape,
|
||||
]
|
||||
const customTools = [
|
||||
ChatBoxTool,
|
||||
VideoChatTool,
|
||||
EmbedTool,
|
||||
// MycrozineTemplateTool,
|
||||
// MarkdownTool
|
||||
]
|
||||
const customTools = [ChatBoxTool, VideoChatTool, EmbedTool] //, MarkdownTool]
|
||||
|
||||
const callObject = Daily.createCallObject()
|
||||
|
||||
export default function InteractiveShapeExample() {
|
||||
return (
|
||||
<div className="tldraw__editor">
|
||||
<Tldraw
|
||||
shapeUtils={customShapeUtils}
|
||||
tools={customTools}
|
||||
overrides={overrides}
|
||||
components={components}
|
||||
onMount={(editor) => {
|
||||
handleInitialPageLoad(editor)
|
||||
editor.createShape({ type: "my-interactive-shape", x: 100, y: 100 })
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
//createRoot(document.getElementById("root")!).render(<App />)
|
||||
|
||||
function App() {
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
// Comment out console.log override temporarily for debugging
|
||||
// console.log = () => {}
|
||||
// console.debug = () => {}
|
||||
// console.info = () => {}
|
||||
// Keep error and warn for debugging
|
||||
// console.error = () => {};
|
||||
// console.warn = () => {};
|
||||
}
|
||||
|
||||
// Add a debug message to verify console logging is working
|
||||
console.log("App initialized, NODE_ENV:", process.env.NODE_ENV)
|
||||
|
||||
return (
|
||||
<DailyProvider callObject={callObject}>
|
||||
<BrowserRouter>
|
||||
|
|
@ -82,3 +57,4 @@ function App() {
|
|||
}
|
||||
|
||||
createRoot(document.getElementById("root")!).render(<App />)
|
||||
|
||||
|
|
|
|||
|
|
@ -287,6 +287,58 @@ p:has(+ ol) {
|
|||
& p {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Markdown preview styles */
|
||||
& h1 { font-size: 2em; margin: 0.67em 0; }
|
||||
& h2 { font-size: 1.5em; margin: 0.75em 0; }
|
||||
& h3 { font-size: 1.17em; margin: 0.83em 0; }
|
||||
& h4 { margin: 1.12em 0; }
|
||||
& h5 { font-size: 0.83em; margin: 1.5em 0; }
|
||||
& h6 { font-size: 0.75em; margin: 1.67em 0; }
|
||||
|
||||
& ul, & ol {
|
||||
padding-left: 2em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
& p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
& code {
|
||||
background-color: #f5f5f5;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 3px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
& pre {
|
||||
background-color: #f5f5f5;
|
||||
padding: 1em;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
& blockquote {
|
||||
margin: 1em 0;
|
||||
padding-left: 1em;
|
||||
border-left: 4px solid #ddd;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
& table {
|
||||
border-collapse: collapse;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
& th, & td {
|
||||
border: 1px solid #ddd;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
& tr:nth-child(2n) {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
|
||||
.transparent {
|
||||
|
|
|
|||
|
|
@ -17,12 +17,26 @@ import { components } from "@/ui/components"
|
|||
import { overrides } from "@/ui/overrides"
|
||||
import { unfurlBookmarkUrl } from "../utils/unfurlBookmarkUrl"
|
||||
import { handleInitialPageLoad } from "@/utils/handleInitialPageLoad"
|
||||
import { MycrozineTemplateTool } from "@/tools/MycrozineTemplateTool"
|
||||
import { MycrozineTemplateShape } from "@/shapes/MycrozineTemplateShapeUtil"
|
||||
|
||||
// Default to production URL if env var isn't available
|
||||
export const WORKER_URL = "https://jeffemmett-canvas.jeffemmett.workers.dev"
|
||||
|
||||
const shapeUtils = [ChatBoxShape, VideoChatShape, EmbedShape] //, MarkdownShape]
|
||||
const tools = [ChatBoxTool, VideoChatTool, EmbedTool] //, MarkdownTool]
|
||||
const shapeUtils = [
|
||||
ChatBoxShape,
|
||||
VideoChatShape,
|
||||
EmbedShape,
|
||||
// MycrozineTemplateShape,
|
||||
// MarkdownShape
|
||||
]
|
||||
const tools = [
|
||||
ChatBoxTool,
|
||||
VideoChatTool,
|
||||
EmbedTool,
|
||||
// MycrozineTemplateTool,
|
||||
// MarkdownTool
|
||||
]
|
||||
|
||||
export function Board() {
|
||||
const { slug } = useParams<{ slug: string }>()
|
||||
|
|
|
|||
|
|
@ -1,11 +1,38 @@
|
|||
/** TODO: build this */
|
||||
|
||||
import { BaseBoxShapeUtil, TLBaseBoxShape, TLBaseShape } from "tldraw"
|
||||
import { BaseBoxShapeUtil, TLBaseBoxShape, TLBaseShape, StyleProp, T, DefaultSizeStyle, DefaultFontStyle, DefaultColorStyle } from "tldraw"
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { marked } from "marked"
|
||||
|
||||
// Uncomment and use these style definitions
|
||||
const MarkdownColor = StyleProp.defineEnum('markdown:color', {
|
||||
defaultValue: 'black',
|
||||
values: ['black', 'blue', 'green', 'grey', 'light-blue', 'light-green', 'light-red', 'light-violet', 'orange', 'red', 'violet', 'yellow'],
|
||||
})
|
||||
|
||||
const MarkdownSize = StyleProp.defineEnum('markdown:size', {
|
||||
defaultValue: 'medium',
|
||||
values: ['small', 'medium', 'large'],
|
||||
})
|
||||
|
||||
const MarkdownFont = StyleProp.defineEnum('markdown:font', {
|
||||
defaultValue: 'draw',
|
||||
values: ['draw', 'sans', 'serif', 'mono'],
|
||||
})
|
||||
|
||||
//const MarkdownHorizontalAlign = StyleProp.define('markdown:horizontalalign', { defaultValue: 'start' })
|
||||
//const MarkdownVerticalAlign = StyleProp.define('markdown:verticalalign', { defaultValue: 'start' })
|
||||
|
||||
export type IMarkdownShape = TLBaseShape<
|
||||
"MarkdownTool",
|
||||
{
|
||||
content: string
|
||||
isPreview: boolean
|
||||
w: number
|
||||
h: number
|
||||
color: string
|
||||
size: string
|
||||
font: string
|
||||
}
|
||||
>
|
||||
|
||||
|
|
@ -14,19 +41,148 @@ export class MarkdownShape extends BaseBoxShapeUtil<
|
|||
> {
|
||||
static override type = "MarkdownTool"
|
||||
|
||||
indicator(_shape: IMarkdownShape) {
|
||||
return null
|
||||
styles = {
|
||||
color: MarkdownColor,
|
||||
size: MarkdownSize,
|
||||
font: MarkdownFont,
|
||||
}
|
||||
|
||||
getDefaultProps(): IMarkdownShape["props"] & { w: number; h: number } {
|
||||
return {
|
||||
console.log('getDefaultProps called');
|
||||
const props = {
|
||||
content: "",
|
||||
w: 100,
|
||||
h: 100,
|
||||
isPreview: false,
|
||||
w: 400,
|
||||
h: 300,
|
||||
color: 'black',
|
||||
size: 'medium',
|
||||
font: 'draw'
|
||||
};
|
||||
console.log('Default props:', props);
|
||||
return props;
|
||||
}
|
||||
|
||||
indicator(shape: IMarkdownShape) {
|
||||
return (
|
||||
<g>
|
||||
<rect x={0} y={0} width={shape.props.w} height={shape.props.h} />
|
||||
</g>
|
||||
)
|
||||
}
|
||||
|
||||
component(shape: IMarkdownShape) {
|
||||
return <div>{shape.props.content}</div>
|
||||
console.log('Component rendering with shape:', shape);
|
||||
console.log('Available styles:', this.styles);
|
||||
const editor = this.editor
|
||||
return <MarkdownEditor shape={shape} editor={editor} />
|
||||
}
|
||||
}
|
||||
|
||||
function MarkdownEditor({ shape, editor }: { shape: IMarkdownShape; editor: any }) {
|
||||
console.log('MarkdownEditor mounted with shape:', shape);
|
||||
console.log('Editor instance:', editor);
|
||||
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
||||
const [isPreview, setIsPreview] = useState(shape.props.isPreview)
|
||||
const [renderedContent, setRenderedContent] = useState("")
|
||||
|
||||
useEffect(() => {
|
||||
if (textareaRef.current && textareaRef.current.value !== shape.props.content) {
|
||||
textareaRef.current.value = shape.props.content
|
||||
}
|
||||
}, [shape.props.content])
|
||||
|
||||
useEffect(() => {
|
||||
const html = marked.parse(shape.props.content, { breaks: true }) as string
|
||||
setRenderedContent(html)
|
||||
}, [shape.props.content])
|
||||
|
||||
const togglePreview = () => {
|
||||
const newPreviewState = !isPreview
|
||||
setIsPreview(newPreviewState)
|
||||
editor.updateShape(shape.id, {
|
||||
props: {
|
||||
...shape.props,
|
||||
isPreview: newPreviewState
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: 'white',
|
||||
border: '1px solid #e0e0e0',
|
||||
borderRadius: '4px',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
{/* Toolbar */}
|
||||
<div style={{
|
||||
padding: '4px 8px',
|
||||
borderBottom: '1px solid #e0e0e0',
|
||||
backgroundColor: '#f5f5f5',
|
||||
display: 'flex',
|
||||
gap: '8px',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<button
|
||||
onClick={togglePreview}
|
||||
style={{
|
||||
padding: '4px 8px',
|
||||
border: '1px solid #ccc',
|
||||
borderRadius: '4px',
|
||||
backgroundColor: 'white',
|
||||
cursor: 'pointer',
|
||||
fontSize: '12px'
|
||||
}}
|
||||
>
|
||||
{isPreview ? 'Edit' : 'Preview'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Editor/Preview Area */}
|
||||
<div style={{
|
||||
flex: 1,
|
||||
overflow: 'auto',
|
||||
position: 'relative'
|
||||
}}>
|
||||
{isPreview ? (
|
||||
<div
|
||||
style={{
|
||||
padding: '8px',
|
||||
height: '100%',
|
||||
overflow: 'auto'
|
||||
}}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(shape.props.content, { breaks: true }) as string
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<textarea
|
||||
ref={textareaRef}
|
||||
defaultValue={shape.props.content}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
resize: 'none',
|
||||
border: 'none',
|
||||
padding: '8px',
|
||||
fontFamily: 'inherit',
|
||||
}}
|
||||
onChange={(e) => {
|
||||
editor.updateShape(shape.id, {
|
||||
props: {
|
||||
...shape.props,
|
||||
content: e.target.value
|
||||
}
|
||||
})
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
import { BaseBoxShapeUtil, TLBaseShape, TLResizeInfo} from "@tldraw/tldraw"
|
||||
|
||||
export type IMycrozineTemplateShape = TLBaseShape<
|
||||
"MycrozineTemplate",
|
||||
{
|
||||
w: number
|
||||
h: number
|
||||
}
|
||||
>
|
||||
|
||||
export class MycrozineTemplateShape extends BaseBoxShapeUtil<IMycrozineTemplateShape> {
|
||||
static override type = "MycrozineTemplate"
|
||||
|
||||
getDefaultProps(): IMycrozineTemplateShape["props"] {
|
||||
// 8.5" × 11" at 300 DPI = 2550 × 3300 pixels
|
||||
const props = {
|
||||
w: 2550,
|
||||
h: 3300,
|
||||
}
|
||||
console.log('MycrozineTemplate - Default props:', props)
|
||||
return props
|
||||
}
|
||||
|
||||
indicator(shape: IMycrozineTemplateShape) {
|
||||
return (
|
||||
<g>
|
||||
<rect x={0} y={0} width={shape.props.w} height={shape.props.h} />
|
||||
</g>
|
||||
)
|
||||
}
|
||||
|
||||
containerStyle = {
|
||||
position: 'relative' as const,
|
||||
backgroundColor: 'transparent',
|
||||
border: '1px solid #666',
|
||||
borderRadius: '2px',
|
||||
}
|
||||
|
||||
verticalGuideStyle = {
|
||||
position: 'absolute' as const,
|
||||
left: '50%',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
borderLeft: '1px dashed #666',
|
||||
}
|
||||
|
||||
horizontalGuideStyle = {
|
||||
position: 'absolute' as const,
|
||||
left: 0,
|
||||
right: 0,
|
||||
borderTop: '1px dashed #666',
|
||||
}
|
||||
|
||||
component(shape: IMycrozineTemplateShape) {
|
||||
const { w, h } = shape.props
|
||||
const isSelected = this.editor.getSelectedShapeIds().includes(shape.id)
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
...this.containerStyle,
|
||||
width: `${w}px`,
|
||||
height: `${h}px`,
|
||||
pointerEvents: isSelected ? 'none' : 'all'
|
||||
}}
|
||||
>
|
||||
<div style={this.verticalGuideStyle} />
|
||||
{[0.25, 0.5, 0.75].map((ratio, index) => (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
...this.horizontalGuideStyle,
|
||||
top: `${ratio * 100}%`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { BaseBoxShapeTool } from "tldraw"
|
||||
|
||||
export class MycrozineTemplateTool extends BaseBoxShapeTool {
|
||||
static override id = "MycrozineTemplate"
|
||||
shapeType = "MycrozineTemplate"
|
||||
override initial = "idle"
|
||||
}
|
||||
|
|
@ -130,7 +130,18 @@ export function CustomContextMenu(props: TLUiContextMenuProps) {
|
|||
editor.setCurrentTool("Embed")
|
||||
}}
|
||||
/>
|
||||
{/* <TldrawUiMenuItem
|
||||
{/*
|
||||
<TldrawUiMenuItem
|
||||
id="mycrozine-template"
|
||||
label="Create Mycrozine Template"
|
||||
icon="rectangle"
|
||||
kbd="m"
|
||||
disabled={hasSelection}
|
||||
onSelect={() => {
|
||||
editor.setCurrentTool("MycrozineTemplate")
|
||||
}}
|
||||
/>
|
||||
<TldrawUiMenuItem
|
||||
id="markdown"
|
||||
label="Create Markdown"
|
||||
icon="markdown"
|
||||
|
|
@ -139,7 +150,8 @@ export function CustomContextMenu(props: TLUiContextMenuProps) {
|
|||
onSelect={() => {
|
||||
editor.setCurrentTool("Markdown")
|
||||
}}
|
||||
/> */}
|
||||
/>
|
||||
*/}
|
||||
</TldrawUiMenuGroup>
|
||||
|
||||
{/* Frame Controls */}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ export function CustomToolbar() {
|
|||
isSelected={tools["Embed"].id === editor.getCurrentToolId()}
|
||||
/>
|
||||
)}
|
||||
{/*
|
||||
{tools["Markdown"] && (
|
||||
<TldrawUiMenuItem
|
||||
{...tools["Markdown"]}
|
||||
|
|
@ -52,6 +53,7 @@ export function CustomToolbar() {
|
|||
isSelected={tools["Markdown"].id === editor.getCurrentToolId()}
|
||||
/>
|
||||
)}
|
||||
*/}
|
||||
</DefaultToolbar>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,14 +63,24 @@ export const overrides: TLUiOverrides = {
|
|||
readonlyOk: true,
|
||||
onSelect: () => editor.setCurrentTool("Embed"),
|
||||
},
|
||||
// Markdown: {
|
||||
// id: "Markdown",
|
||||
// icon: "markdown",
|
||||
// label: "Markdown",
|
||||
// kbd: "alt+m",
|
||||
// readonlyOk: true,
|
||||
// onSelect: () => editor.setCurrentTool("Markdown"),
|
||||
// },
|
||||
/*
|
||||
Markdown: {
|
||||
id: "Markdown",
|
||||
icon: "markdown",
|
||||
label: "Markdown",
|
||||
kbd: "alt+m",
|
||||
readonlyOk: true,
|
||||
onSelect: () => editor.setCurrentTool("Markdown"),
|
||||
},
|
||||
MycrozineTemplate: {
|
||||
id: "MycrozineTemplate",
|
||||
icon: "rectangle",
|
||||
label: "Mycrozine Template",
|
||||
kbd: "m",
|
||||
readonlyOk: true,
|
||||
onSelect: () => editor.setCurrentTool("MycrozineTemplate"),
|
||||
},
|
||||
*/
|
||||
}
|
||||
},
|
||||
actions(editor, actions) {
|
||||
|
|
@ -124,33 +134,6 @@ export const overrides: TLUiOverrides = {
|
|||
},
|
||||
readonlyOk: true,
|
||||
},
|
||||
// TODO: FIX THIS
|
||||
handleSelectedShapeDrag: {
|
||||
id: "handle-selected-shape-drag",
|
||||
label: "Drag Selected Shape",
|
||||
onSelect: (info: any) => {
|
||||
const shape = editor.getShapeAtPoint(info.point)
|
||||
if (shape && editor.getSelectedShapeIds().includes(shape.id)) {
|
||||
if (editor.isPointInShape(shape, info.point)) {
|
||||
editor.dispatch({
|
||||
type: "pointer",
|
||||
name: "pointer_down",
|
||||
point: info.point,
|
||||
button: info.button,
|
||||
shiftKey: info.shiftKey,
|
||||
altKey: info.altKey,
|
||||
ctrlKey: info.ctrlKey,
|
||||
metaKey: info.metaKey,
|
||||
accelKey: info.ctrlKey || info.metaKey,
|
||||
pointerId: info.pointerId,
|
||||
target: "shape",
|
||||
shape,
|
||||
isPen: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
moveSelectedLeft: {
|
||||
id: "move-selected-left",
|
||||
label: "Move Left",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export const saveToPdf = async (editor: Editor) => {
|
|||
opts: {
|
||||
scale: 2,
|
||||
background: true,
|
||||
padding: 10,
|
||||
padding: 0,
|
||||
preserveAspectRatio: "true",
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import { ChatBoxShape } from "@/shapes/ChatBoxShapeUtil"
|
|||
import { VideoChatShape } from "@/shapes/VideoChatShapeUtil"
|
||||
import { EmbedShape } from "@/shapes/EmbedShapeUtil"
|
||||
import { MarkdownShape } from "@/shapes/MarkdownShapeUtil"
|
||||
import { MycrozineTemplateShape } from "@/shapes/MycrozineTemplateShapeUtil"
|
||||
|
||||
// add custom shapes and bindings here if needed:
|
||||
export const customSchema = createTLSchema({
|
||||
|
|
@ -36,6 +37,10 @@ export const customSchema = createTLSchema({
|
|||
props: MarkdownShape.props,
|
||||
migrations: MarkdownShape.migrations,
|
||||
},
|
||||
MycrozineTemplate: {
|
||||
props: MycrozineTemplateShape.props,
|
||||
migrations: MycrozineTemplateShape.migrations,
|
||||
},
|
||||
},
|
||||
bindings: defaultBindingSchemas,
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue