Fixes types for code editor
This commit is contained in:
parent
000d029354
commit
776c0b5f0e
7 changed files with 415 additions and 35 deletions
|
@ -2,6 +2,181 @@
|
|||
|
||||
exports[`selection creates a code control: generated code controls from code 1`] = `Object {}`;
|
||||
|
||||
exports[`selection generates a draw shape: generated draw from code 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"childIndex": 1,
|
||||
"id": "test-draw",
|
||||
"isAspectRatioLocked": false,
|
||||
"isGenerated": true,
|
||||
"isHidden": false,
|
||||
"isLocked": false,
|
||||
"name": "Test draw",
|
||||
"parentId": "page1",
|
||||
"point": Array [
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"points": Array [
|
||||
Array [
|
||||
100,
|
||||
100,
|
||||
],
|
||||
Array [
|
||||
200,
|
||||
200,
|
||||
],
|
||||
Array [
|
||||
300,
|
||||
300,
|
||||
],
|
||||
],
|
||||
"rotation": 0,
|
||||
"style": Object {
|
||||
"color": "Red",
|
||||
"dash": "Dotted",
|
||||
"isFilled": false,
|
||||
"size": "Medium",
|
||||
},
|
||||
"type": "draw",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`selection generates a rectangle shape: generated rectangle from code 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"childIndex": 1,
|
||||
"id": "test-rectangle",
|
||||
"isAspectRatioLocked": false,
|
||||
"isGenerated": true,
|
||||
"isHidden": false,
|
||||
"isLocked": false,
|
||||
"name": "Test Rectangle",
|
||||
"parentId": "page1",
|
||||
"point": Array [
|
||||
100,
|
||||
100,
|
||||
],
|
||||
"radius": 2,
|
||||
"rotation": 0,
|
||||
"size": Array [
|
||||
200,
|
||||
200,
|
||||
],
|
||||
"style": Object {
|
||||
"color": "Red",
|
||||
"dash": "Dotted",
|
||||
"isFilled": false,
|
||||
"size": "Medium",
|
||||
},
|
||||
"type": "rectangle",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`selection generates an arrow shape: generated draw from code 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"bend": 0,
|
||||
"childIndex": 1,
|
||||
"decorations": Object {
|
||||
"end": "Arrow",
|
||||
"middle": null,
|
||||
"start": null,
|
||||
},
|
||||
"handles": Object {
|
||||
"bend": Object {
|
||||
"id": "bend",
|
||||
"index": 2,
|
||||
"point": Array [
|
||||
0,
|
||||
0,
|
||||
],
|
||||
},
|
||||
"end": Object {
|
||||
"id": "end",
|
||||
"index": 1,
|
||||
"point": Array [
|
||||
0,
|
||||
0,
|
||||
],
|
||||
},
|
||||
"start": Object {
|
||||
"id": "start",
|
||||
"index": 0,
|
||||
"point": Array [
|
||||
0,
|
||||
0,
|
||||
],
|
||||
},
|
||||
},
|
||||
"id": "test-draw",
|
||||
"isAspectRatioLocked": false,
|
||||
"isGenerated": true,
|
||||
"isHidden": false,
|
||||
"isLocked": false,
|
||||
"name": "Test draw",
|
||||
"parentId": "page1",
|
||||
"point": Array [
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"points": Array [
|
||||
Array [
|
||||
100,
|
||||
100,
|
||||
],
|
||||
Array [
|
||||
200,
|
||||
200,
|
||||
],
|
||||
Array [
|
||||
300,
|
||||
300,
|
||||
],
|
||||
],
|
||||
"rotation": 0,
|
||||
"style": Object {
|
||||
"color": "Red",
|
||||
"dash": "Dotted",
|
||||
"isFilled": false,
|
||||
"size": "Medium",
|
||||
},
|
||||
"type": "arrow",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`selection generates an ellipse shape: generated ellipse from code 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"childIndex": 1,
|
||||
"id": "test-ellipse",
|
||||
"isAspectRatioLocked": false,
|
||||
"isGenerated": true,
|
||||
"isHidden": false,
|
||||
"isLocked": false,
|
||||
"name": "Test ellipse",
|
||||
"parentId": "page1",
|
||||
"point": Array [
|
||||
100,
|
||||
100,
|
||||
],
|
||||
"radiusX": 100,
|
||||
"radiusY": 200,
|
||||
"rotation": 0,
|
||||
"style": Object {
|
||||
"color": "Red",
|
||||
"dash": "Dotted",
|
||||
"isFilled": false,
|
||||
"size": "Medium",
|
||||
},
|
||||
"type": "ellipse",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`selection generates shapes: generated rectangle from code 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
|
|
|
@ -131,5 +131,142 @@ describe('selection', () => {
|
|||
expect(state.data.document.code[state.data.currentCodeFileId].code).toBe(
|
||||
code
|
||||
)
|
||||
|
||||
state.send('TOGGLED_READ_ONLY').send('SAVED_CODE', { code: '' })
|
||||
|
||||
expect(state.data.document.code[state.data.currentCodeFileId].code).toBe('')
|
||||
})
|
||||
|
||||
/* --------------------- Methods -------------------- */
|
||||
|
||||
it('moves shape to front', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('moves shape forward', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('moves shape backward', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('moves shape to back', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('rotates a shape', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('rotates a shape by a delta', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('translates a shape', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('translates a shape by a delta', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
/* --------------------- Shapes --------------------- */
|
||||
|
||||
it('generates a rectangle shape', async () => {
|
||||
state.send('CLEARED_PAGE')
|
||||
const code = `
|
||||
const rectangle = new Rectangle({
|
||||
id: "test-rectangle",
|
||||
name: 'Test Rectangle',
|
||||
point: [100, 100],
|
||||
size: [200, 200],
|
||||
style: {
|
||||
size: SizeStyle.Medium,
|
||||
color: ColorStyle.Red,
|
||||
dash: DashStyle.Dotted,
|
||||
},
|
||||
})
|
||||
`
|
||||
|
||||
const { controls, shapes } = await generateFromCode(state.data, code)
|
||||
|
||||
state.send('GENERATED_FROM_CODE', { controls, shapes })
|
||||
|
||||
expect(getShapes(state.data)).toMatchSnapshot(
|
||||
'generated rectangle from code'
|
||||
)
|
||||
})
|
||||
|
||||
it('changes a rectangle size', async () => {
|
||||
null
|
||||
})
|
||||
|
||||
it('generates an ellipse shape', async () => {
|
||||
state.send('CLEARED_PAGE')
|
||||
const code = `
|
||||
const ellipse = new Ellipse({
|
||||
id: 'test-ellipse',
|
||||
name: 'Test ellipse',
|
||||
point: [100, 100],
|
||||
radiusX: 100,
|
||||
radiusY: 200,
|
||||
style: {
|
||||
size: SizeStyle.Medium,
|
||||
color: ColorStyle.Red,
|
||||
dash: DashStyle.Dotted,
|
||||
},
|
||||
})
|
||||
`
|
||||
|
||||
const { controls, shapes } = await generateFromCode(state.data, code)
|
||||
|
||||
state.send('GENERATED_FROM_CODE', { controls, shapes })
|
||||
|
||||
expect(getShapes(state.data)).toMatchSnapshot('generated ellipse from code')
|
||||
})
|
||||
|
||||
it('generates a draw shape', async () => {
|
||||
state.send('CLEARED_PAGE')
|
||||
const code = `
|
||||
const ellipse = new Draw({
|
||||
id: 'test-draw',
|
||||
name: 'Test draw',
|
||||
points: [[100, 100], [200,200], [300,300]],
|
||||
style: {
|
||||
size: SizeStyle.Medium,
|
||||
color: ColorStyle.Red,
|
||||
dash: DashStyle.Dotted,
|
||||
},
|
||||
})
|
||||
`
|
||||
|
||||
const { controls, shapes } = await generateFromCode(state.data, code)
|
||||
|
||||
state.send('GENERATED_FROM_CODE', { controls, shapes })
|
||||
|
||||
expect(getShapes(state.data)).toMatchSnapshot('generated draw from code')
|
||||
})
|
||||
|
||||
it('generates an arrow shape', async () => {
|
||||
state.send('CLEARED_PAGE')
|
||||
const code = `
|
||||
const ellipse = new Arrow({
|
||||
id: 'test-draw',
|
||||
name: 'Test draw',
|
||||
points: [[100, 100], [200,200], [300,300]],
|
||||
style: {
|
||||
size: SizeStyle.Medium,
|
||||
color: ColorStyle.Red,
|
||||
dash: DashStyle.Dotted,
|
||||
},
|
||||
})
|
||||
`
|
||||
|
||||
const { controls, shapes } = await generateFromCode(state.data, code)
|
||||
|
||||
state.send('GENERATED_FROM_CODE', { controls, shapes })
|
||||
|
||||
expect(getShapes(state.data)).toMatchSnapshot('generated draw from code')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -43,7 +43,9 @@ export default function CodeEditor({
|
|||
const rMonaco = useRef<IMonaco>(null)
|
||||
|
||||
const handleBeforeMount = useCallback((monaco: Monaco) => {
|
||||
if (monacoRef) monacoRef.current = monaco
|
||||
if (monacoRef) {
|
||||
monacoRef.current = monaco
|
||||
}
|
||||
rMonaco.current = monaco
|
||||
|
||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||
|
@ -52,26 +54,37 @@ export default function CodeEditor({
|
|||
strict: false,
|
||||
noLib: true,
|
||||
lib: ['es6'],
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2015,
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2016,
|
||||
allowNonTsExtensions: true,
|
||||
})
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
||||
allowJs: true,
|
||||
checkJs: false,
|
||||
strict: false,
|
||||
checkJs: true,
|
||||
strict: true,
|
||||
noLib: true,
|
||||
lib: ['es6'],
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2015,
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2016,
|
||||
allowNonTsExtensions: true,
|
||||
})
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true)
|
||||
monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true)
|
||||
|
||||
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||
noSemanticValidation: false,
|
||||
noSyntaxValidation: false,
|
||||
})
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
||||
noSemanticValidation: false,
|
||||
noSyntaxValidation: false,
|
||||
})
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
||||
typesImport.content
|
||||
)
|
||||
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
typesImport.content
|
||||
)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint-disable */
|
||||
|
||||
// HEY! DO NOT MODIFY THIS FILE. THE CONTENTS OF THIS FILE
|
||||
// ARE AUTO-GENERATED BY A SCRIPT AT: /scripts/type-gen.js
|
||||
// ANY CHANGES WILL BE LOST WHEN THE SCRIPT RUNS AGAIN!
|
||||
|
@ -6,6 +8,13 @@ export default {
|
|||
name: 'types.ts',
|
||||
content: `
|
||||
|
||||
type Partial<T> = { [P in keyof T]?: T[P]; };
|
||||
|
||||
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
|
||||
|
||||
type DeepPartial<T> = {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -141,8 +150,12 @@ interface GroupShape extends BaseShape {
|
|||
size: number[]
|
||||
}
|
||||
|
||||
type ShapeProps<T extends Shape> = Partial<Omit<T, 'style'>> & {
|
||||
style?: Partial<ShapeStyles>
|
||||
// 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 =
|
||||
|
@ -1240,10 +1253,10 @@ interface ShapeUtility<K extends Shape> {
|
|||
P: number[],
|
||||
side: number
|
||||
): number[] {
|
||||
const B = vec.lrp(C, P, 0.5),
|
||||
r1 = vec.dist(C, B),
|
||||
delta = vec.sub(B, C),
|
||||
d = vec.len(delta)
|
||||
const B = Vec.lrp(C, P, 0.5),
|
||||
r1 = Vec.dist(C, B),
|
||||
delta = Vec.sub(B, C),
|
||||
d = Vec.len(delta)
|
||||
|
||||
if (!(d <= r + r1 && d >= Math.abs(r - r1))) {
|
||||
return
|
||||
|
@ -1251,11 +1264,11 @@ interface ShapeUtility<K extends Shape> {
|
|||
|
||||
const a = (r * r - r1 * r1 + d * d) / (2.0 * d),
|
||||
n = 1 / d,
|
||||
p = vec.add(C, vec.mul(delta, a * n)),
|
||||
p = Vec.add(C, Vec.mul(delta, a * n)),
|
||||
h = Math.sqrt(r * r - a * a),
|
||||
k = vec.mul(vec.per(delta), h * n)
|
||||
k = Vec.mul(Vec.per(delta), h * n)
|
||||
|
||||
return side === 0 ? vec.add(p, k) : vec.sub(p, k)
|
||||
return side === 0 ? Vec.add(p, k) : Vec.sub(p, k)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1274,8 +1287,8 @@ interface ShapeUtility<K extends Shape> {
|
|||
C1: number[],
|
||||
r1: number
|
||||
): number[][] {
|
||||
const a0 = vec.angle(C0, C1)
|
||||
const d = vec.dist(C0, C1)
|
||||
const a0 = Vec.angle(C0, C1)
|
||||
const d = Vec.dist(C0, C1)
|
||||
|
||||
// Circles are overlapping, no tangents
|
||||
if (d < Math.abs(r1 - r0)) return
|
||||
|
@ -1303,8 +1316,8 @@ interface ShapeUtility<K extends Shape> {
|
|||
r: number,
|
||||
P: number[]
|
||||
): number[] {
|
||||
const v = vec.sub(C, P)
|
||||
return vec.sub(C, vec.mul(vec.div(v, vec.len(v)), r))
|
||||
const v = Vec.sub(C, P)
|
||||
return Vec.sub(C, Vec.mul(Vec.div(v, Vec.len(v)), r))
|
||||
}
|
||||
|
||||
static det(
|
||||
|
@ -1433,7 +1446,7 @@ interface ShapeUtility<K extends Shape> {
|
|||
* @param B
|
||||
*/
|
||||
static getSweep(C: number[], A: number[], B: number[]): number {
|
||||
return Utils.angleDelta(vec.angle(C, A), vec.angle(C, B))
|
||||
return Utils.angleDelta(Vec.angle(C, A), Vec.angle(C, B))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1571,7 +1584,7 @@ interface ShapeUtility<K extends Shape> {
|
|||
|
||||
return Array.from(Array(steps))
|
||||
.map((_, i) => ease(i / steps))
|
||||
.map((t) => [...vec.lrp(a, b, t), (1 - t) / 2])
|
||||
.map((t) => [...Vec.lrp(a, b, t), (1 - t) / 2])
|
||||
}
|
||||
|
||||
static getRayRayIntersection(
|
||||
|
@ -1580,8 +1593,8 @@ interface ShapeUtility<K extends Shape> {
|
|||
p1: number[],
|
||||
n1: number[]
|
||||
): number[] {
|
||||
const p0e = vec.add(p0, n0),
|
||||
p1e = vec.add(p1, n1),
|
||||
const p0e = Vec.add(p0, n0),
|
||||
p1e = Vec.add(p1, n1),
|
||||
m0 = (p0e[1] - p0[1]) / (p0e[0] - p0[0]),
|
||||
m1 = (p1e[1] - p1[1]) / (p1e[0] - p1[0]),
|
||||
b0 = p0[1] - m0 * p0[0],
|
||||
|
@ -2470,6 +2483,20 @@ class VectorControl extends Control<VectorCodeControl> {
|
|||
}
|
||||
|
||||
|
||||
declare const controls: {[key:string]: any} = {}
|
||||
const codeShapes = new Set<CodeShape<any>>()
|
||||
const controls: Record<string, any> = {}
|
||||
const defaultStyle: ShapeStyles = {
|
||||
color: ColorStyle.Black,
|
||||
size: SizeStyle.Medium,
|
||||
isFilled: false,
|
||||
dash: DashStyle.Solid,
|
||||
}
|
||||
const uniqueId = () => ''
|
||||
const codeControls = new Set([])
|
||||
|
||||
declare function createShape(type: ShapeType, shape: Shape): any
|
||||
declare function getShapeUtils<T>(shape: T): any
|
||||
declare function getOrderedShapes(): CodeShape<any>[]
|
||||
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ async function inlineFileContents(path) {
|
|||
.replaceAll('/* ----------------- Start Copy Here ---------------- */', '')
|
||||
.replaceAll('export default', '')
|
||||
.replaceAll('export ', '')
|
||||
.replaceAll('vec.', 'Vec.')
|
||||
}
|
||||
|
||||
async function copyTypesToFile() {
|
||||
|
@ -34,15 +35,24 @@ async function copyTypesToFile() {
|
|||
|
||||
const content =
|
||||
`
|
||||
// HEY! DO NOT MODIFY THIS FILE. THE CONTENTS OF THIS FILE
|
||||
// ARE AUTO-GENERATED BY A SCRIPT AT: /scripts/type-gen.js
|
||||
// ANY CHANGES WILL BE LOST WHEN THE SCRIPT RUNS AGAIN!
|
||||
/* eslint-disable */
|
||||
|
||||
export default {` +
|
||||
// HEY! DO NOT MODIFY THIS FILE. THE CONTENTS OF THIS FILE
|
||||
// ARE AUTO-GENERATED BY A SCRIPT AT: /scripts/type-gen.js
|
||||
// ANY CHANGES WILL BE LOST WHEN THE SCRIPT RUNS AGAIN!
|
||||
|
||||
export default {` +
|
||||
`
|
||||
name: "types.ts",
|
||||
content: \`
|
||||
name: "types.ts",
|
||||
content: \`
|
||||
|
||||
type Partial<T> = { [P in keyof T]?: T[P]; };
|
||||
|
||||
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
|
||||
|
||||
type DeepPartial<T> = {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
};
|
||||
|
||||
${await inlineFileContents('/types.ts')}
|
||||
|
||||
|
@ -72,7 +82,21 @@ ${await inlineFileContents('/state/code/rectangle.ts')}
|
|||
|
||||
${await inlineFileContents('/state/code/control.ts')}
|
||||
|
||||
declare const controls: {[key:string]: any} = {}
|
||||
const codeShapes = new Set<CodeShape<any>>()
|
||||
const controls: Record<string, any> = {}
|
||||
const defaultStyle: ShapeStyles = {
|
||||
color: ColorStyle.Black,
|
||||
size: SizeStyle.Medium,
|
||||
isFilled: false,
|
||||
dash: DashStyle.Solid,
|
||||
}
|
||||
const uniqueId = () => ''
|
||||
const codeControls = new Set([])
|
||||
|
||||
declare function createShape(type: ShapeType, shape: Shape): any
|
||||
declare function getShapeUtils<T>(shape: T): any
|
||||
declare function getOrderedShapes(): CodeShape<any>[]
|
||||
|
||||
\`}`
|
||||
|
||||
await fs.writeFile(
|
||||
|
|
|
@ -85,7 +85,7 @@ export function getShapeStyle(
|
|||
}
|
||||
}
|
||||
|
||||
export const defaultStyle = {
|
||||
export const defaultStyle: ShapeStyles = {
|
||||
color: ColorStyle.Black,
|
||||
size: SizeStyle.Medium,
|
||||
isFilled: false,
|
||||
|
|
8
types.ts
8
types.ts
|
@ -191,8 +191,12 @@ export interface GroupShape extends BaseShape {
|
|||
size: number[]
|
||||
}
|
||||
|
||||
export type ShapeProps<T extends Shape> = Partial<Omit<T, 'style'>> & {
|
||||
style?: Partial<ShapeStyles>
|
||||
// type DeepPartial<T> = {
|
||||
// [P in keyof T]?: DeepPartial<T[P]>
|
||||
// }
|
||||
|
||||
export type ShapeProps<T extends Shape> = {
|
||||
[P in keyof T]?: P extends 'style' ? Partial<T[P]> : T[P]
|
||||
}
|
||||
|
||||
export type MutableShape =
|
||||
|
|
Loading…
Reference in a new issue