@fabrika/canvas-kernel 0.1.44 → 0.2.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/README.md +33 -67
- package/index.ts +19 -83
- package/package.json +68 -72
- package/src/client/AnnotationProvider.tsx +227 -268
- package/src/client/AnnotationSidebar.tsx +392 -338
- package/src/client/FileIcon.tsx +106 -65
- package/src/client/PlanRenderer.tsx +607 -551
- package/src/client/RenderErrorContext.ts +7 -7
- package/src/client/ResponsePreview.tsx +192 -173
- package/src/client/annotationDom.ts +43 -97
- package/src/client/annotationDraft.ts +98 -92
- package/src/client/appContext.tsx +40 -40
- package/src/client/components/Callout.tsx +20 -20
- package/src/client/components/Checklist.tsx +28 -28
- package/src/client/components/Choice.tsx +178 -159
- package/src/client/components/CodeBlock.tsx +26 -26
- package/src/client/components/Diff.tsx +17 -17
- package/src/client/components/FilePreview.tsx +99 -74
- package/src/client/components/Image.tsx +41 -39
- package/src/client/components/Markdown.tsx +33 -32
- package/src/client/components/Mermaid.tsx +592 -542
- package/src/client/components/Note.tsx +8 -8
- package/src/client/components/Priority.tsx +11 -11
- package/src/client/components/ResponseNote.tsx +17 -15
- package/src/client/components/Section.tsx +28 -26
- package/src/client/components/Table.tsx +34 -29
- package/src/client/components/Task.tsx +58 -60
- package/src/client/components/UserInput.tsx +169 -152
- package/src/client/components/index.ts +16 -16
- package/src/client/components/renderMarkdownChildren.tsx +86 -68
- package/src/client/diffLines.ts +51 -39
- package/src/client/generateMarkdown.ts +197 -191
- package/src/client/hostContext.tsx +34 -34
- package/src/client/index.ts +43 -125
- package/src/client/preact-all.ts +4 -4
- package/src/client/runtime.ts +58 -111
- package/src/client/styles.css +1 -74
- package/src/engine/compiler.ts +316 -313
- package/src/engine/paths.ts +44 -44
- package/src/engine/session.ts +623 -618
- package/src/engine/watcher.ts +63 -60
- package/src/engine/websocket.ts +123 -121
- package/annotate.ts +0 -94
- package/daemon.ts +0 -46
- package/src/client/AnnotationDraftFooter.tsx +0 -76
- package/src/client/AnnotationEditor.tsx +0 -320
- package/src/client/AnnotationList.tsx +0 -190
- package/src/client/Popover.tsx +0 -361
- package/src/client/SessionContext.tsx +0 -3
- package/src/client/annotationContext.ts +0 -130
- package/src/client/annotationMarkdown.ts +0 -102
- package/src/client/annotationTarget.ts +0 -73
- package/src/client/blockTarget.ts +0 -127
- package/src/client/highlightRange.ts +0 -262
- package/src/client/popoverPosition.ts +0 -46
- package/src/client/regionTarget.ts +0 -180
- package/src/client/testing/dom.ts +0 -58
- package/src/client/textTarget.ts +0 -31
- package/src/client/useRegionAnnotation.tsx +0 -188
- package/src/client/useTextAnnotation.tsx +0 -194
- package/src/client/utils.ts +0 -33
- package/src/engine/channel.ts +0 -278
- package/src/engine/http-utils.ts +0 -14
- package/src/engine/lifecycle.ts +0 -302
- package/src/engine/router.ts +0 -16
- package/src/engine/waiter.ts +0 -188
package/src/client/index.ts
CHANGED
|
@@ -1,128 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
// it, minus the app shell (navigation, file browser, revision chrome), which
|
|
5
|
-
// each host builds itself.
|
|
6
|
-
|
|
7
|
-
// --- Annotation state ------------------------------------------------------
|
|
8
|
-
// Everything that lives in runtime.ts is re-exported through `#canvas/runtime`,
|
|
9
|
-
// never through a relative path. The runtime holds the React contexts and ships
|
|
10
|
-
// as its own bundle shared with the compiled canvas; importing it relatively
|
|
11
|
-
// would bundle a second copy, and the provider and its consumers would then be
|
|
12
|
-
// writing to and reading from different contexts.
|
|
13
|
-
export { AnnotationProvider } from "./AnnotationProvider";
|
|
14
|
-
export type { PersistedState } from "./AnnotationProvider";
|
|
1
|
+
export { AnnotationProvider } from './AnnotationProvider'
|
|
2
|
+
export type { PersistedState } from './AnnotationProvider'
|
|
3
|
+
// Canvas documents and the shell must read the same external context instance.
|
|
15
4
|
export {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} from
|
|
5
|
+
ActiveViewCtx,
|
|
6
|
+
AnnotationCtx,
|
|
7
|
+
CanvasFileCtx,
|
|
8
|
+
SessionContext,
|
|
9
|
+
useAnnotations,
|
|
10
|
+
useCanvasFile,
|
|
11
|
+
useFeedback,
|
|
12
|
+
useResponseRegistration,
|
|
13
|
+
} from '#canvas/runtime'
|
|
25
14
|
export type {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
} from
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export {
|
|
41
|
-
export
|
|
42
|
-
export {
|
|
43
|
-
export type { AnnotationDraftFooterProps } from "./AnnotationDraftFooter";
|
|
44
|
-
export { AnnotationEditor, imageToUrl } from "./AnnotationEditor";
|
|
45
|
-
export { PlanRenderer } from "./PlanRenderer";
|
|
46
|
-
export { Popover, AnnotationPopover, AnnotationCreatePopover, AnnotationEditPopover } from "./Popover";
|
|
47
|
-
export { ResponsePreview, MarkdownPreview } from "./ResponsePreview";
|
|
48
|
-
export { FileIcon } from "./FileIcon";
|
|
49
|
-
|
|
50
|
-
/** The kernel component set, as a namespace for hosts that inject it wholesale. */
|
|
51
|
-
export * as components from "./components";
|
|
52
|
-
export { useTextAnnotation } from "./useTextAnnotation";
|
|
53
|
-
export { useRegionAnnotation } from "./useRegionAnnotation";
|
|
54
|
-
|
|
55
|
-
// --- Host-provided context -------------------------------------------------
|
|
56
|
-
export { CanvasHostContext, localCanvasHost, useCanvasHost } from "./hostContext";
|
|
57
|
-
export type { CanvasHost } from "./hostContext";
|
|
58
|
-
export { ActiveViewContext, RevisionContext } from "./appContext";
|
|
59
|
-
export type { CanvasFileInfo, RevisionInfo } from "./appContext";
|
|
60
|
-
export { RenderErrorContext } from "./RenderErrorContext";
|
|
61
|
-
export type { CanvasRenderError } from "./RenderErrorContext";
|
|
62
|
-
|
|
63
|
-
// --- Annotation plumbing ---------------------------------------------------
|
|
64
|
-
export { extractContext, formatSnippetInContext } from "./annotationContext";
|
|
15
|
+
ActiveView,
|
|
16
|
+
Annotation,
|
|
17
|
+
AnnotationAttachment,
|
|
18
|
+
AnnotationAuthor,
|
|
19
|
+
AnnotationContext,
|
|
20
|
+
AnnotationContextValue,
|
|
21
|
+
FeedbackEntry,
|
|
22
|
+
PlanResponse,
|
|
23
|
+
} from '#canvas/runtime'
|
|
24
|
+
export { findAnnotationElement, scrollToAnnotation } from './annotationDom'
|
|
25
|
+
export { annotationDraftKey, carryUnsubmittedDraft, clearPersistedDraft } from './annotationDraft'
|
|
26
|
+
export type { AnnotationDraftPhase } from './annotationDraft'
|
|
27
|
+
export { AnnotationSidebar } from './AnnotationSidebar'
|
|
28
|
+
export { ActiveViewContext, RevisionContext } from './appContext'
|
|
29
|
+
export type { CanvasFileInfo, RevisionInfo } from './appContext'
|
|
30
|
+
export * as components from './components'
|
|
31
|
+
export { FileIcon } from './FileIcon'
|
|
65
32
|
export {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
} from
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// for writes one of these; nothing else has to change.
|
|
81
|
-
export { sealTarget } from "./annotationTarget";
|
|
82
|
-
export type { AnnotationTarget, SealedAnnotationTarget, TargetAnnotation } from "./annotationTarget";
|
|
83
|
-
export { blockTarget } from "./blockTarget";
|
|
84
|
-
export type { BlockLocator } from "./blockTarget";
|
|
85
|
-
export { textTarget } from "./textTarget";
|
|
86
|
-
export type { TextLocator } from "./textTarget";
|
|
87
|
-
export {
|
|
88
|
-
createRegionOverlay,
|
|
89
|
-
describeRegion,
|
|
90
|
-
findRegionHost,
|
|
91
|
-
isDrawableRegion,
|
|
92
|
-
regionBetween,
|
|
93
|
-
regionPointIn,
|
|
94
|
-
regionStyle,
|
|
95
|
-
regionTarget,
|
|
96
|
-
REGION_HOST_ATTR,
|
|
97
|
-
REGION_UNITS,
|
|
98
|
-
} from "./regionTarget";
|
|
99
|
-
export type { RegionBox, RegionLocator, RegionPoint, RegionShape } from "./regionTarget";
|
|
100
|
-
export {
|
|
101
|
-
annotationDraftKey,
|
|
102
|
-
carryUnsubmittedDraft,
|
|
103
|
-
clearPersistedDraft,
|
|
104
|
-
} from "./annotationDraft";
|
|
105
|
-
export type { AnnotationDraftPhase } from "./annotationDraft";
|
|
106
|
-
export {
|
|
107
|
-
restoreMarks,
|
|
108
|
-
renameMarkId,
|
|
109
|
-
setMarkActive,
|
|
110
|
-
unwrapMarks,
|
|
111
|
-
updateAllMarkStates,
|
|
112
|
-
wrapRangeWithMark,
|
|
113
|
-
} from "./highlightRange";
|
|
114
|
-
// One annotation as markdown — the half of feedback that belongs to no
|
|
115
|
-
// particular document format. `generateMarkdown` below is the canvas format
|
|
116
|
-
// built on it; a host with its own headings calls this directly.
|
|
117
|
-
export { renderAnnotation } from "./annotationMarkdown";
|
|
118
|
-
export type { RenderableAnnotation } from "./annotationMarkdown";
|
|
119
|
-
export {
|
|
120
|
-
canPruneResponses,
|
|
121
|
-
generateMarkdown,
|
|
122
|
-
getMissingRequired,
|
|
123
|
-
getMissingRequiredFeedback,
|
|
124
|
-
getMissingRequiredLabels,
|
|
125
|
-
hasValue,
|
|
126
|
-
pruneStaleResponses,
|
|
127
|
-
} from "./generateMarkdown";
|
|
128
|
-
export { autoResizeTextarea, fileAnnotationPath, generateAnnotationId, hostAcceptsUploads, RESPONSE_ANNOTATION_PATH } from "./utils";
|
|
33
|
+
canPruneResponses,
|
|
34
|
+
generateMarkdown,
|
|
35
|
+
getMissingRequired,
|
|
36
|
+
getMissingRequiredFeedback,
|
|
37
|
+
getMissingRequiredLabels,
|
|
38
|
+
hasValue,
|
|
39
|
+
pruneStaleResponses,
|
|
40
|
+
} from './generateMarkdown'
|
|
41
|
+
export { CanvasHostContext, localCanvasHost, useCanvasHost } from './hostContext'
|
|
42
|
+
export type { CanvasHost } from './hostContext'
|
|
43
|
+
export { PlanRenderer } from './PlanRenderer'
|
|
44
|
+
export { RenderErrorContext } from './RenderErrorContext'
|
|
45
|
+
export type { CanvasRenderError } from './RenderErrorContext'
|
|
46
|
+
export { MarkdownPreview, ResponsePreview } from './ResponsePreview'
|
package/src/client/preact-all.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export { default } from
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
1
|
+
export * from 'preact/compat'
|
|
2
|
+
export { default } from 'preact/compat'
|
|
3
|
+
export { createRoot, hydrateRoot } from 'preact/compat/client'
|
|
4
|
+
export { jsx, jsxs } from 'preact/jsx-runtime'
|
package/src/client/runtime.ts
CHANGED
|
@@ -2,105 +2,52 @@
|
|
|
2
2
|
// The React.createContext call MUST live here (not in AnnotationProvider)
|
|
3
3
|
// so that both bundles reference the same context object.
|
|
4
4
|
|
|
5
|
-
import { createContext, useContext, useEffect } from
|
|
5
|
+
import { createContext, useContext, useEffect } from 'react'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
after: string;
|
|
10
|
-
hierarchy: string[];
|
|
11
|
-
lineStart?: number;
|
|
12
|
-
lineEnd?: number;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** Identifies the person who created an annotation. For local annotations
|
|
16
|
-
* this is the daemon owner (unset). For remote annotations it carries the
|
|
17
|
-
* reviewer's self-reported name + stable anonymous id assigned by the worker. */
|
|
18
|
-
export interface AnnotationAuthor {
|
|
19
|
-
id: string;
|
|
20
|
-
name: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** An image or other file attached to an annotation. The richer sibling of
|
|
24
|
-
* `images: string[]`, carrying a mime type alongside a URL that can point at
|
|
25
|
-
* either a local upload (daemon) or a remote blob (CF Worker R2). */
|
|
26
|
-
export interface AnnotationAttachment {
|
|
27
|
-
url: string;
|
|
28
|
-
mime?: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface Annotation {
|
|
32
|
-
id: string;
|
|
33
|
-
snippet: string;
|
|
34
|
-
note: string;
|
|
35
|
-
createdAt: string;
|
|
36
|
-
filePath?: string;
|
|
37
|
-
canvasFile?: string;
|
|
38
|
-
context?: AnnotationContext;
|
|
39
|
-
/** Attachments written by the local editor, as bare upload paths/URLs. Still
|
|
40
|
-
* the only field it writes, and what persisted drafts hold. */
|
|
41
|
-
images?: string[];
|
|
42
|
-
/** Attachments that arrived over the wire, from a reviewer on a shared
|
|
43
|
-
* canvas. Both fields render — see `renderAnnotation`. */
|
|
44
|
-
attachments?: AnnotationAttachment[];
|
|
45
|
-
/** "remote" annotations come from a shared view and are read-only locally. */
|
|
46
|
-
source?: "local" | "remote";
|
|
47
|
-
/** Only set for source === "remote". */
|
|
48
|
-
author?: AnnotationAuthor;
|
|
49
|
-
}
|
|
7
|
+
import type { AnnotationContextValue as BaseAnnotationContextValue } from '@fabrika/annotations/runtime'
|
|
8
|
+
export type { Annotation, AnnotationAttachment, AnnotationAuthor, AnnotationContext } from '@fabrika/annotations/runtime'
|
|
50
9
|
|
|
51
10
|
export interface PlanResponse {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
11
|
+
id: string
|
|
12
|
+
type: 'select' | 'radio' | 'checkbox' | 'text' | 'range'
|
|
13
|
+
label: string
|
|
14
|
+
value: any
|
|
15
|
+
options?: string[]
|
|
16
|
+
required?: boolean
|
|
17
|
+
note?: string
|
|
59
18
|
}
|
|
60
19
|
|
|
61
20
|
export interface FeedbackEntry {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
21
|
+
id: string
|
|
22
|
+
markdown: string
|
|
23
|
+
label?: string
|
|
24
|
+
required?: boolean
|
|
66
25
|
}
|
|
67
26
|
|
|
68
|
-
export interface AnnotationContextValue {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
* Everything that reports feedback — markdown, validation, "has content" —
|
|
87
|
-
* reads this instead, so a carried-over answer to a since-removed question
|
|
88
|
-
* is not submitted. Identical to `responses` until the host supplies the
|
|
89
|
-
* canvas file list and every one of them has rendered. */
|
|
90
|
-
submittableResponses: Map<string, PlanResponse>;
|
|
91
|
-
registerResponse: (id: string) => void;
|
|
92
|
-
registerCanvasRendered: (filename: string) => void;
|
|
93
|
-
feedbackEntries: Map<string, FeedbackEntry>;
|
|
94
|
-
setFeedbackEntry: (id: string, entry: FeedbackEntry) => void;
|
|
95
|
-
removeFeedbackEntry: (id: string) => void;
|
|
96
|
-
/** Canvas is rendered read-only (reviewing history). */
|
|
97
|
-
isReadOnly: boolean;
|
|
27
|
+
export interface AnnotationContextValue extends BaseAnnotationContextValue {
|
|
28
|
+
/** Every answer held for this draft, including ones carried in from an
|
|
29
|
+
* earlier revision. Controls read and write this one. */
|
|
30
|
+
responses: Map<string, PlanResponse>
|
|
31
|
+
setResponse: (id: string, response: PlanResponse) => void
|
|
32
|
+
/** `responses` narrowed to the questions this revision actually asks.
|
|
33
|
+
* Everything that reports feedback — markdown, validation, "has content" —
|
|
34
|
+
* reads this instead, so a carried-over answer to a since-removed question
|
|
35
|
+
* is not submitted. Identical to `responses` until the host supplies the
|
|
36
|
+
* canvas file list and every one of them has rendered. */
|
|
37
|
+
submittableResponses: Map<string, PlanResponse>
|
|
38
|
+
registerResponse: (id: string) => void
|
|
39
|
+
registerCanvasRendered: (filename: string) => void
|
|
40
|
+
feedbackEntries: Map<string, FeedbackEntry>
|
|
41
|
+
setFeedbackEntry: (id: string, entry: FeedbackEntry) => void
|
|
42
|
+
removeFeedbackEntry: (id: string) => void
|
|
43
|
+
/** Canvas is rendered read-only (reviewing history). */
|
|
44
|
+
isReadOnly: boolean
|
|
98
45
|
}
|
|
99
46
|
|
|
100
|
-
export const AnnotationCtx = createContext<AnnotationContextValue>(null!)
|
|
47
|
+
export const AnnotationCtx = createContext<AnnotationContextValue>(null!)
|
|
101
48
|
|
|
102
49
|
export function useAnnotations(): AnnotationContextValue {
|
|
103
|
-
|
|
50
|
+
return useContext(AnnotationCtx)
|
|
104
51
|
}
|
|
105
52
|
|
|
106
53
|
/** Record that this revision asks the question, so submission can tell it from
|
|
@@ -108,42 +55,42 @@ export function useAnnotations(): AnnotationContextValue {
|
|
|
108
55
|
* cleanup: unmounting means the reader navigated away, not that the question
|
|
109
56
|
* disappeared. */
|
|
110
57
|
export function useResponseRegistration(id: string): void {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
58
|
+
const { registerResponse } = useAnnotations()
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
registerResponse(id)
|
|
61
|
+
}, [id, registerResponse])
|
|
115
62
|
}
|
|
116
63
|
|
|
117
64
|
export function useFeedback(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
65
|
+
id: string,
|
|
66
|
+
markdown: string,
|
|
67
|
+
options?: { label?: string; required?: boolean },
|
|
121
68
|
): void {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
69
|
+
const { setFeedbackEntry, removeFeedbackEntry } = useAnnotations()
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
setFeedbackEntry(id, {
|
|
72
|
+
id,
|
|
73
|
+
markdown,
|
|
74
|
+
label: options?.label,
|
|
75
|
+
required: options?.required,
|
|
76
|
+
})
|
|
77
|
+
return () => removeFeedbackEntry(id)
|
|
78
|
+
}, [id, markdown, options?.label, options?.required])
|
|
132
79
|
}
|
|
133
80
|
|
|
134
|
-
export { SessionContext } from
|
|
81
|
+
export { SessionContext } from '@fabrika/annotations/runtime'
|
|
135
82
|
|
|
136
83
|
// CanvasFile context — tells components which canvas file they belong to
|
|
137
|
-
export const CanvasFileCtx = createContext<string>(
|
|
84
|
+
export const CanvasFileCtx = createContext<string>('')
|
|
138
85
|
export function useCanvasFile(): string {
|
|
139
|
-
|
|
86
|
+
return useContext(CanvasFileCtx)
|
|
140
87
|
}
|
|
141
88
|
|
|
142
89
|
// ActiveView navigation — allows components (e.g. FilePreview) to open files
|
|
143
|
-
export type ActiveView = { type:
|
|
90
|
+
export type ActiveView = { type: 'overview' } | { type: 'canvas'; filename: string } | { type: 'file'; path: string }
|
|
144
91
|
|
|
145
92
|
export const ActiveViewCtx = createContext<{
|
|
146
|
-
|
|
93
|
+
setActiveView: (v: ActiveView) => void
|
|
147
94
|
}>({
|
|
148
|
-
|
|
149
|
-
})
|
|
95
|
+
setActiveView: () => {},
|
|
96
|
+
})
|
package/src/client/styles.css
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
@import "tailwindcss";
|
|
4
4
|
@import "./theme.css";
|
|
5
|
+
@import "@fabrika/annotations/styles.css";
|
|
5
6
|
@source "./**/*.{tsx,ts,jsx,js}";
|
|
6
7
|
|
|
7
8
|
/* ── Non-theme CSS variables (not used by Tailwind utilities, just custom CSS) ── */
|
|
@@ -96,80 +97,6 @@ code, pre, .font-mono {
|
|
|
96
97
|
font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
/* Annotation inline marks */
|
|
100
|
-
mark[data-annotation-id] {
|
|
101
|
-
background: var(--color-highlight-annotation);
|
|
102
|
-
border-bottom: 1.5px solid var(--color-highlight-bg);
|
|
103
|
-
border-radius: 2px;
|
|
104
|
-
cursor: pointer;
|
|
105
|
-
transition: background 150ms ease, box-shadow 150ms ease;
|
|
106
|
-
color: inherit;
|
|
107
|
-
padding: 1px 0;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
mark[data-annotation-id].mark-active {
|
|
111
|
-
background: var(--color-highlight-active);
|
|
112
|
-
border-bottom: 2px solid var(--color-highlight-border);
|
|
113
|
-
box-shadow: 0 0 0 1px var(--color-highlight-border);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@keyframes ann-flash {
|
|
117
|
-
0%, 100% { background: var(--color-highlight-annotation); }
|
|
118
|
-
25%, 75% { background: var(--color-highlight-active); }
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.ann-flash {
|
|
122
|
-
animation: ann-flash 0.6s ease 2;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/* Region annotations — a normalized box drawn over an image block. The host
|
|
126
|
-
positions the boxes, so every host that marks one gets them placed right. */
|
|
127
|
-
[data-annotation-image] {
|
|
128
|
-
position: relative;
|
|
129
|
-
cursor: crosshair;
|
|
130
|
-
touch-action: none;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.ann-region {
|
|
134
|
-
position: absolute;
|
|
135
|
-
background: var(--color-highlight-annotation);
|
|
136
|
-
border: 2px solid var(--color-highlight-bg);
|
|
137
|
-
border-radius: 2px;
|
|
138
|
-
cursor: pointer;
|
|
139
|
-
transition: background 150ms ease, box-shadow 150ms ease;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.ann-region[data-annotation-region="ellipse"] {
|
|
143
|
-
border-radius: 50%;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.ann-region.mark-active {
|
|
147
|
-
background: var(--color-highlight-active);
|
|
148
|
-
border-color: var(--color-highlight-border);
|
|
149
|
-
box-shadow: 0 0 0 1px var(--color-highlight-border);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/* The box being dragged out: not yet an annotation, and never a hit target. */
|
|
153
|
-
.ann-region-draft {
|
|
154
|
-
pointer-events: none;
|
|
155
|
-
border-style: dashed;
|
|
156
|
-
border-color: var(--color-highlight-border);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/* Annotation highlight (legacy) */
|
|
160
|
-
.annotation-highlight {
|
|
161
|
-
background: var(--color-highlight-bg);
|
|
162
|
-
border-bottom: 2px solid var(--color-highlight-border);
|
|
163
|
-
border-radius: 2px;
|
|
164
|
-
cursor: pointer;
|
|
165
|
-
transition: background 150ms ease;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
.annotation-highlight:hover,
|
|
169
|
-
.annotation-highlight.active {
|
|
170
|
-
background: var(--color-highlight-active);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
100
|
/* Selection color */
|
|
174
101
|
::selection {
|
|
175
102
|
background-color: var(--color-highlight-active);
|