Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ A simple, joyful drawing experience:
- **Pressure ink** — a freehand pen whose width breathes with stylus pressure,
or with velocity for mouse users; strokes taper like a real pen
- **Highlighter** that soaks into the paper (and glows on dark boards)
- **Shapes** — rectangle, ellipse, triangle, diamond, hexagon, star — with a
- **Shapes** — rectangle, ellipse, triangle, diamond, hexagon, star, cloud — with a
seeded hand-drawn wobble, four fill styles, and editable labels
- **Arrows** with draggable bend, lines, text, sticky notes
- **Images** — paste, drag-drop, or pick; auto-downscaled and stored in-document
Expand All @@ -48,8 +48,9 @@ A simple, joyful drawing experience:
- **Undo/redo** — one entry per gesture, however many events it took
- **Light & dark themes**, twelve named colors that resolve per theme, and a
theme switch built into the board menu
- **Grid backdrops** — ruled lines or dotted intersections, spacing that adapts
to the zoom and fades in rather than popping
- **Grid backdrops** — plain, ruled lines, notebook rules, dots, crosses
(blueprint), and isometric; default is `lines`; spacing adapts to the zoom
and fades in rather than popping
- **PNG export** — whole board or selection, on paper or transparent
- **A responsive floating toolbar** that sheds tools gracefully as the frame
narrows — or hide it and build your own from the headless API
Expand Down
4 changes: 2 additions & 2 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import '@quickdrawjs/core/quickdraw.css'
const board = createQuickdraw({
container: document.getElementById('board'),
theme: 'light', // or 'dark'
grid: 'lines', // 'none' (default) | 'lines' | 'dots'
grid: 'lines', // 'none' | 'lines' (default) | 'ruled' | 'dots' | 'crosses' | 'iso'
})

// the document store emits a diff after every change
Expand All @@ -49,7 +49,7 @@ without you building any chrome:

```js
board.editor.setTheme('dark') // emits 'theme'
board.editor.setGrid('dots') // 'none' | 'lines' | 'dots', emits 'grid'
board.editor.setGrid('dots') // 'none' | 'lines' (default) | 'ruled' | 'dots' | 'crosses' | 'iso', emits 'grid'
board.editor.clearBoard() // one undoable step (⇧⌘⌫)

// mirror in-board switches into your own app state
Expand Down
29 changes: 29 additions & 0 deletions packages/core/test/type-drift.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { readFileSync } from 'node:fs'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { describe, it, expect } from 'vitest'
import { GEO_IDS, GRID_IDS } from '../src/palette.js'

const __dirname = dirname(fileURLToPath(import.meta.url))
const dts = readFileSync(resolve(__dirname, '../types/index.d.ts'), 'utf8')

function parseUnion(typeName) {
const re = new RegExp(`export type ${typeName}\\s*=\\s*([^\\n]+)`)
const m = dts.match(re)
if (!m) throw new Error(`${typeName} not found in types/index.d.ts`)
return m[1]
.split('|')
.map((s) => s.trim().replace(/^'|'$/g, ''))
.filter(Boolean)
.sort()
}

describe('type declarations stay in sync with palette.js', () => {
it('GeoId union matches GEO_IDS', () => {
expect(parseUnion('GeoId')).toEqual([...GEO_IDS].sort())
})

it('GridId union matches GRID_IDS', () => {
expect(parseUnion('GridId')).toEqual([...GRID_IDS].sort())
})
})
6 changes: 3 additions & 3 deletions packages/core/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export type SizeId = 's' | 'm' | 'l' | 'xl'
export type DashId = 'draw' | 'solid' | 'dashed' | 'dotted'
export type FillId = 'none' | 'semi' | 'solid' | 'pattern'
export type FontId = 'draw' | 'sans' | 'serif' | 'mono'
export type GeoId = 'rectangle' | 'ellipse' | 'triangle' | 'diamond' | 'hexagon' | 'star'
export type GeoId = 'rectangle' | 'ellipse' | 'triangle' | 'diamond' | 'hexagon' | 'star' | 'cloud'
export type ThemeId = 'light' | 'dark'
export type GridId = 'none' | 'lines' | 'dots'
export type GridId = 'none' | 'lines' | 'ruled' | 'dots' | 'crosses' | 'iso'

export interface Bounds { x: number; y: number; w: number; h: number }
export interface Camera { x: number; y: number; z: number }
Expand Down Expand Up @@ -236,7 +236,7 @@ export class Editor {
setTool(tool: ToolId): void
setGeoKind(kind: GeoId): void
setTheme(id: ThemeId | string): void
/** 'none' | 'lines' | 'dots' — the backdrop behind the drawing. */
/** 'none' | 'lines' | 'ruled' | 'dots' | 'crosses' | 'iso' — the backdrop behind the drawing. */
setGrid(id: GridId): void
setReadonly(ro: boolean): void
setPenMode(on: boolean): void
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface QuickdrawRef {

export interface QuickdrawProps {
theme?: ThemeId | string
/** 'none' | 'lines' | 'dots' — the backdrop. Live-switchable. */
/** 'none' | 'lines' | 'ruled' | 'dots' | 'crosses' | 'iso' — the backdrop. Live-switchable. */
grid?: GridId
readonly?: boolean
hideUi?: boolean
Expand Down
2 changes: 1 addition & 1 deletion packages/react/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface QuickdrawRef {
export interface QuickdrawProps {
/** 'light' | 'dark' — live-switchable. */
theme?: ThemeId | string
/** 'none' | 'lines' | 'dots' — the backdrop. Live-switchable. */
/** 'none' | 'lines' | 'ruled' | 'dots' | 'crosses' | 'iso' — the backdrop. Live-switchable. */
grid?: GridId
/** Lock input (also hides the toolbar). */
readonly?: boolean
Expand Down
Loading