@erclx/canon 5.53.0 → 5.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +10 -9
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/canon-cli/SKILL.md +5 -5
- package/claude/skills/design-identity/REQUIREMENT.md +2 -2
- package/claude/skills/design-identity/SKILL.md +6 -6
- package/claude/skills/design-record/REQUIREMENT.md +2 -2
- package/claude/skills/design-record/SKILL.md +4 -4
- package/claude/skills/design-record/references/folder.md +1 -1
- package/claude/skills/design-taste/REQUIREMENT.md +1 -1
- package/claude/skills/draw-figure/REQUIREMENT.md +1 -1
- package/claude/skills/draw-figure/SKILL.md +1 -1
- package/claude/skills/pick-by-eye/REQUIREMENT.md +4 -4
- package/claude/skills/pick-by-eye/SKILL.md +34 -41
- package/claude/skills/pick-by-eye/references/board.md +42 -0
- package/claude/skills/pick-by-eye/references/live-arms.md +3 -3
- package/claude/skills/plan-groundwork/SKILL.md +1 -1
- package/claude/skills/teach-craft/REQUIREMENT.md +1 -1
- package/claude/skills/teach-craft/SKILL.md +32 -1
- package/claude/skills/teach-craft/references/adopted.md +113 -0
- package/claude/skills/teach-craft/references/lesson-craft.md +10 -2
- package/claude/skills/teach-craft/references/pedagogy.md +29 -2
- package/docs/agents/install-and-sync.md +0 -8
- package/docs/target/migrations.md +8 -3
- package/docs/target/projects.md +1 -1
- package/docs/workflow/skill-map.md +0 -1
- package/docs/workflow/visual-design-workflow.md +1 -4
- package/governance/detect.toml +1 -6
- package/governance/renames.toml +0 -1
- package/package.json +2 -5
- package/src/claude/cases/misc.ts +0 -5
- package/src/claude/skills-audit.ts +1 -0
- package/src/cli/help.ts +0 -3
- package/src/cli.ts +0 -2
- package/src/commands/design.ts +16 -315
- package/src/commands/sync.ts +4 -5
- package/src/design/regen.ts +5 -32
- package/src/design/render.ts +1 -1
- package/src/design/tokens.ts +3 -2
- package/src/gate/stages.ts +4 -10
- package/src/gov/audit.ts +1 -6
- package/src/markdown/scope.ts +2 -4
- package/src/shipped/references.ts +1 -2
- package/src/sync/check.ts +4 -29
- package/src/sync/stamp.ts +6 -6
- package/src/sync/target.ts +1 -4
- package/tooling/claude/reference.md +1 -1
- package/tooling/claude/seeds/canon/DESIGN.md +1 -1
- package/claude/skills/canvas-board/REQUIREMENT.md +0 -35
- package/claude/skills/canvas-board/SKILL.md +0 -143
- package/claude/skills/canvas-board/references/canvas.md +0 -170
- package/governance/rules/ui/canvas.md +0 -13
- package/src/canvas/address.ts +0 -227
- package/src/canvas/arrange.ts +0 -66
- package/src/canvas/capture.ts +0 -391
- package/src/canvas/client/app.tsx +0 -188
- package/src/canvas/client/inspector/align-grid.tsx +0 -162
- package/src/canvas/client/inspector/color-field.tsx +0 -398
- package/src/canvas/client/inspector/color-inputs.tsx +0 -139
- package/src/canvas/client/inspector/color-picker.tsx +0 -668
- package/src/canvas/client/inspector/color-space.ts +0 -240
- package/src/canvas/client/inspector/field.tsx +0 -263
- package/src/canvas/client/inspector/fields.css +0 -763
- package/src/canvas/client/inspector/section.tsx +0 -27
- package/src/canvas/client/inspector/size-field.tsx +0 -69
- package/src/canvas/client/inspector/token-select.tsx +0 -109
- package/src/canvas/client/inspector/values.ts +0 -297
- package/src/canvas/client/inspector.tsx +0 -692
- package/src/canvas/client/keys.ts +0 -71
- package/src/canvas/client/layers.tsx +0 -118
- package/src/canvas/client/main.tsx +0 -71
- package/src/canvas/client/pages-panel.tsx +0 -212
- package/src/canvas/client/panel-handle.tsx +0 -90
- package/src/canvas/client/selection.tsx +0 -199
- package/src/canvas/client/shell.css +0 -762
- package/src/canvas/client/state.ts +0 -792
- package/src/canvas/client/surface.tsx +0 -803
- package/src/canvas/client/theme-panel.tsx +0 -55
- package/src/canvas/client/tools.tsx +0 -153
- package/src/canvas/content.ts +0 -781
- package/src/canvas/edit.ts +0 -575
- package/src/canvas/editing.ts +0 -203
- package/src/canvas/fit.ts +0 -238
- package/src/canvas/global.d.ts +0 -15
- package/src/canvas/history.ts +0 -116
- package/src/canvas/index.html +0 -20
- package/src/canvas/server.ts +0 -766
- package/src/canvas/tokens.ts +0 -221
- package/src/commands/canvas.ts +0 -1097
- package/src/design/adapter.ts +0 -59
- package/src/design/base.css +0 -203
- package/src/design/brand-favicon.ts +0 -18
- package/src/design/neutral.ts +0 -127
- package/src/design/project-fonts.ts +0 -392
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
/** @jsxImportSource preact */
|
|
2
|
-
import type { JSX } from 'preact'
|
|
3
|
-
import { useRef, useState } from 'preact/hooks'
|
|
4
|
-
import { shownTool, view } from '@/canvas/client/state'
|
|
5
|
-
|
|
6
|
-
/** Screen pixels a press travels before it reads as a drag and not a click. */
|
|
7
|
-
export const DRAG_THRESHOLD = 3
|
|
8
|
-
|
|
9
|
-
/** The smallest box a handle drag leaves, in surface units. */
|
|
10
|
-
const MIN_SIZE = 1
|
|
11
|
-
|
|
12
|
-
export type Corner = 'nw' | 'ne' | 'sw' | 'se'
|
|
13
|
-
|
|
14
|
-
const CORNERS: readonly Corner[] = ['nw', 'ne', 'sw', 'se']
|
|
15
|
-
|
|
16
|
-
export interface OverlayBox {
|
|
17
|
-
readonly x: number
|
|
18
|
-
readonly y: number
|
|
19
|
-
readonly width: number
|
|
20
|
-
readonly height: number
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The box a corner drag leaves, with the delta already in surface units. The
|
|
25
|
-
* corner opposite the one dragged stays put, so a west or north handle moves
|
|
26
|
-
* the box as it resizes it.
|
|
27
|
-
*/
|
|
28
|
-
export function resizedBox(
|
|
29
|
-
origin: OverlayBox,
|
|
30
|
-
corner: Corner,
|
|
31
|
-
dx: number,
|
|
32
|
-
dy: number,
|
|
33
|
-
): OverlayBox {
|
|
34
|
-
const isWest = corner === 'nw' || corner === 'sw'
|
|
35
|
-
const isNorth = corner === 'nw' || corner === 'ne'
|
|
36
|
-
const width = Math.max(MIN_SIZE, origin.width + (isWest ? -dx : dx))
|
|
37
|
-
const height = Math.max(MIN_SIZE, origin.height + (isNorth ? -dy : dy))
|
|
38
|
-
return {
|
|
39
|
-
x: isWest ? origin.x + origin.width - width : origin.x,
|
|
40
|
-
y: isNorth ? origin.y + origin.height - height : origin.y,
|
|
41
|
-
width,
|
|
42
|
-
height,
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function sizeLabel(box: Pick<OverlayBox, 'width' | 'height'>): string {
|
|
47
|
-
return `${Math.round(box.width)} × ${Math.round(box.height)}`
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface HandleGesture {
|
|
51
|
-
readonly corner: Corner
|
|
52
|
-
readonly startX: number
|
|
53
|
-
readonly startY: number
|
|
54
|
-
readonly origin: OverlayBox
|
|
55
|
-
box: OverlayBox
|
|
56
|
-
moved: boolean
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface SelectionOverlayProps {
|
|
60
|
-
readonly kind: 'frame' | 'element'
|
|
61
|
-
/** Read on every render, so a box the drag previewed is what shows after. */
|
|
62
|
-
readonly measure: () => OverlayBox
|
|
63
|
-
/** Subtracted from the box to place the overlay inside its container. */
|
|
64
|
-
readonly offset?: { readonly x: number; readonly y: number }
|
|
65
|
-
readonly hasChip?: boolean
|
|
66
|
-
/**
|
|
67
|
-
* Draws the target's own measured box during a drag rather than the dragged
|
|
68
|
-
* one. An element in normal flow grows from its own top left whichever corner
|
|
69
|
-
* is dragged, so only its measured box shows where it actually sits.
|
|
70
|
-
*/
|
|
71
|
-
readonly isMeasuredWhileDragging?: boolean
|
|
72
|
-
readonly onStart?: () => void
|
|
73
|
-
readonly onPreview?: (box: OverlayBox, origin: OverlayBox) => void
|
|
74
|
-
readonly onCommit: (box: OverlayBox, origin: OverlayBox) => void
|
|
75
|
-
readonly onCancel?: (origin: OverlayBox) => void
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* The selected frame's or element's outline, its four corner handles, and an
|
|
80
|
-
* element's size chip. Every part sizes against `--outline-scale`, so it keeps
|
|
81
|
-
* one screen weight at any zoom.
|
|
82
|
-
*/
|
|
83
|
-
export function SelectionOverlay({
|
|
84
|
-
kind,
|
|
85
|
-
measure,
|
|
86
|
-
offset = { x: 0, y: 0 },
|
|
87
|
-
hasChip = false,
|
|
88
|
-
isMeasuredWhileDragging = false,
|
|
89
|
-
onStart,
|
|
90
|
-
onPreview,
|
|
91
|
-
onCommit,
|
|
92
|
-
onCancel,
|
|
93
|
-
}: SelectionOverlayProps): JSX.Element {
|
|
94
|
-
const gesture = useRef<HandleGesture | undefined>(undefined)
|
|
95
|
-
const [dragged, setDragged] = useState<OverlayBox | undefined>(undefined)
|
|
96
|
-
const box = dragged ?? measure()
|
|
97
|
-
|
|
98
|
-
const handlePointerDown = (corner: Corner) => (event: PointerEvent) => {
|
|
99
|
-
if (event.button !== 0) return
|
|
100
|
-
/* A pan drag starting on a handle belongs to the surface behind it. */
|
|
101
|
-
if (shownTool.value === 'pan') return
|
|
102
|
-
event.preventDefault()
|
|
103
|
-
event.stopPropagation()
|
|
104
|
-
const origin = measure()
|
|
105
|
-
gesture.current = {
|
|
106
|
-
corner,
|
|
107
|
-
startX: event.clientX,
|
|
108
|
-
startY: event.clientY,
|
|
109
|
-
origin,
|
|
110
|
-
box: origin,
|
|
111
|
-
moved: false,
|
|
112
|
-
}
|
|
113
|
-
;(event.currentTarget as HTMLElement).setPointerCapture?.(event.pointerId)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const handlePointerMove = (event: PointerEvent) => {
|
|
117
|
-
const current = gesture.current
|
|
118
|
-
if (!current) return
|
|
119
|
-
const dx = event.clientX - current.startX
|
|
120
|
-
const dy = event.clientY - current.startY
|
|
121
|
-
if (!current.moved && Math.hypot(dx, dy) < DRAG_THRESHOLD) return
|
|
122
|
-
if (!current.moved) onStart?.()
|
|
123
|
-
current.moved = true
|
|
124
|
-
/* The delta is in screen pixels and the box in surface units. */
|
|
125
|
-
const { zoom } = view.value
|
|
126
|
-
current.box = resizedBox(
|
|
127
|
-
current.origin,
|
|
128
|
-
current.corner,
|
|
129
|
-
Math.round(dx / zoom),
|
|
130
|
-
Math.round(dy / zoom),
|
|
131
|
-
)
|
|
132
|
-
onPreview?.(current.box, current.origin)
|
|
133
|
-
setDragged(isMeasuredWhileDragging ? measure() : current.box)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const handlePointerUp = () => {
|
|
137
|
-
const current = gesture.current
|
|
138
|
-
gesture.current = undefined
|
|
139
|
-
if (current?.moved) onCommit(current.box, current.origin)
|
|
140
|
-
setDragged(undefined)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const handlePointerCancel = () => {
|
|
144
|
-
const current = gesture.current
|
|
145
|
-
gesture.current = undefined
|
|
146
|
-
if (current?.moved) onCancel?.(current.origin)
|
|
147
|
-
setDragged(undefined)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<div
|
|
152
|
-
class="selection"
|
|
153
|
-
data-selection={kind}
|
|
154
|
-
data-resizing={dragged ? 'true' : undefined}
|
|
155
|
-
style={{
|
|
156
|
-
left: `${box.x - offset.x}px`,
|
|
157
|
-
top: `${box.y - offset.y}px`,
|
|
158
|
-
width: `${box.width}px`,
|
|
159
|
-
height: `${box.height}px`,
|
|
160
|
-
}}
|
|
161
|
-
>
|
|
162
|
-
{CORNERS.map((corner) => (
|
|
163
|
-
<span
|
|
164
|
-
key={corner}
|
|
165
|
-
class="selection-handle"
|
|
166
|
-
data-handle={corner}
|
|
167
|
-
aria-hidden="true"
|
|
168
|
-
onPointerDown={handlePointerDown(corner)}
|
|
169
|
-
onPointerMove={handlePointerMove}
|
|
170
|
-
onPointerUp={handlePointerUp}
|
|
171
|
-
onPointerCancel={handlePointerCancel}
|
|
172
|
-
/>
|
|
173
|
-
))}
|
|
174
|
-
{hasChip ? (
|
|
175
|
-
<span class="selection-chip" aria-hidden="true">
|
|
176
|
-
{sizeLabel(box)}
|
|
177
|
-
</span>
|
|
178
|
-
) : null}
|
|
179
|
-
</div>
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/** The element under the pointer, drawn without handles. */
|
|
184
|
-
export function HoverOutline({ element }: { readonly element: Element }) {
|
|
185
|
-
const rect = element.getBoundingClientRect()
|
|
186
|
-
return (
|
|
187
|
-
<div
|
|
188
|
-
class="element-outline"
|
|
189
|
-
data-outline="hover"
|
|
190
|
-
aria-hidden="true"
|
|
191
|
-
style={{
|
|
192
|
-
left: `${rect.left}px`,
|
|
193
|
-
top: `${rect.top}px`,
|
|
194
|
-
width: `${rect.width}px`,
|
|
195
|
-
height: `${rect.height}px`,
|
|
196
|
-
}}
|
|
197
|
-
/>
|
|
198
|
-
)
|
|
199
|
-
}
|