@dryui/feedback 0.0.2
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/dist/components/annotation-marker.svelte +163 -0
- package/dist/components/annotation-marker.svelte.d.ts +11 -0
- package/dist/components/annotation-popup.svelte +669 -0
- package/dist/components/annotation-popup.svelte.d.ts +42 -0
- package/dist/components/highlight-overlay.svelte +48 -0
- package/dist/components/highlight-overlay.svelte.d.ts +8 -0
- package/dist/components/settings-panel.svelte +446 -0
- package/dist/components/settings-panel.svelte.d.ts +24 -0
- package/dist/components/toolbar.svelte +1111 -0
- package/dist/components/toolbar.svelte.d.ts +46 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.js +37 -0
- package/dist/feedback.svelte +2879 -0
- package/dist/feedback.svelte.d.ts +4 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +7 -0
- package/dist/layout-mode/catalog.d.ts +16 -0
- package/dist/layout-mode/catalog.js +81 -0
- package/dist/layout-mode/component-actions.svelte +84 -0
- package/dist/layout-mode/component-actions.svelte.d.ts +18 -0
- package/dist/layout-mode/component-picker.svelte +73 -0
- package/dist/layout-mode/component-picker.svelte.d.ts +10 -0
- package/dist/layout-mode/design-mode.svelte +1115 -0
- package/dist/layout-mode/design-mode.svelte.d.ts +24 -0
- package/dist/layout-mode/design-palette.svelte +396 -0
- package/dist/layout-mode/design-palette.svelte.d.ts +20 -0
- package/dist/layout-mode/element-heuristics.d.ts +5 -0
- package/dist/layout-mode/element-heuristics.js +51 -0
- package/dist/layout-mode/freeze.d.ts +6 -0
- package/dist/layout-mode/freeze.js +163 -0
- package/dist/layout-mode/generated-library.d.ts +940 -0
- package/dist/layout-mode/generated-library.js +1445 -0
- package/dist/layout-mode/geometry.d.ts +38 -0
- package/dist/layout-mode/geometry.js +133 -0
- package/dist/layout-mode/history.d.ts +10 -0
- package/dist/layout-mode/history.js +45 -0
- package/dist/layout-mode/index.d.ts +23 -0
- package/dist/layout-mode/index.js +18 -0
- package/dist/layout-mode/live-mount.d.ts +20 -0
- package/dist/layout-mode/live-mount.js +70 -0
- package/dist/layout-mode/output.d.ts +26 -0
- package/dist/layout-mode/output.js +550 -0
- package/dist/layout-mode/placement-skeleton.d.ts +9 -0
- package/dist/layout-mode/placement-skeleton.js +535 -0
- package/dist/layout-mode/rearrange-overlay.svelte +1293 -0
- package/dist/layout-mode/rearrange-overlay.svelte.d.ts +18 -0
- package/dist/layout-mode/responsive-bar.svelte +39 -0
- package/dist/layout-mode/responsive-bar.svelte.d.ts +8 -0
- package/dist/layout-mode/route-creator.svelte +70 -0
- package/dist/layout-mode/route-creator.svelte.d.ts +8 -0
- package/dist/layout-mode/section-detection.d.ts +6 -0
- package/dist/layout-mode/section-detection.js +214 -0
- package/dist/layout-mode/spatial.d.ts +42 -0
- package/dist/layout-mode/spatial.js +156 -0
- package/dist/layout-mode/types.d.ts +144 -0
- package/dist/layout-mode/types.js +84 -0
- package/dist/types.d.ts +157 -0
- package/dist/types.js +1 -0
- package/dist/utils/dryui-detection.d.ts +1 -0
- package/dist/utils/dryui-detection.js +219 -0
- package/dist/utils/element-id.d.ts +12 -0
- package/dist/utils/element-id.js +333 -0
- package/dist/utils/freeze.d.ts +7 -0
- package/dist/utils/freeze.js +168 -0
- package/dist/utils/output.d.ts +15 -0
- package/dist/utils/output.js +245 -0
- package/dist/utils/selection.d.ts +22 -0
- package/dist/utils/selection.js +58 -0
- package/dist/utils/shadow-dom.d.ts +4 -0
- package/dist/utils/shadow-dom.js +39 -0
- package/dist/utils/storage.d.ts +30 -0
- package/dist/utils/storage.js +206 -0
- package/dist/utils/svelte-detection.d.ts +8 -0
- package/dist/utils/svelte-detection.js +86 -0
- package/dist/utils/svelte-meta.d.ts +6 -0
- package/dist/utils/svelte-meta.js +69 -0
- package/dist/utils/sync.d.ts +18 -0
- package/dist/utils/sync.js +62 -0
- package/package.json +65 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export type LayoutModeComponentType = 'navigation' | 'hero' | 'card' | 'button' | 'sidebar' | 'table' | 'form' | 'input' | 'modal' | 'footer' | 'avatar' | 'badge' | 'text' | 'image' | 'list' | 'tabs' | 'header' | 'section' | 'grid' | 'dropdown' | 'toggle' | 'breadcrumb' | 'pagination' | 'progress' | 'divider' | 'accordion' | 'carousel' | 'chart' | 'video' | 'search' | 'toast' | 'tooltip' | 'pricing' | 'testimonial' | 'cta' | 'alert' | 'banner' | 'stat' | 'stepper' | 'tag' | 'rating' | 'map' | 'timeline' | 'fileUpload' | 'codeBlock' | 'calendar' | 'notification' | 'productCard' | 'profile' | 'drawer' | 'popover' | 'logo' | 'faq' | 'gallery' | 'checkbox' | 'radio' | 'slider' | 'datePicker' | 'skeleton' | 'chip' | 'icon' | 'spinner' | 'feature' | 'team' | 'login' | 'contact';
|
|
2
|
+
export type CanvasPurpose = 'new-page' | 'replace-current';
|
|
3
|
+
export interface Rect {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
}
|
|
9
|
+
export interface DesignPlacement {
|
|
10
|
+
id: string;
|
|
11
|
+
type: LayoutModeComponentType;
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
scrollY: number;
|
|
17
|
+
timestamp: number;
|
|
18
|
+
text?: string;
|
|
19
|
+
note?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface DetectedSection {
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
tagName: string;
|
|
25
|
+
selector: string;
|
|
26
|
+
role: string | null;
|
|
27
|
+
className: string | null;
|
|
28
|
+
textSnippet: string | null;
|
|
29
|
+
originalRect: Rect;
|
|
30
|
+
currentRect: Rect;
|
|
31
|
+
originalIndex: number;
|
|
32
|
+
isFixed?: boolean;
|
|
33
|
+
note?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface RearrangeState {
|
|
36
|
+
sections: DetectedSection[];
|
|
37
|
+
originalOrder: string[];
|
|
38
|
+
detectedAt: number;
|
|
39
|
+
}
|
|
40
|
+
export interface ComponentDefinition {
|
|
41
|
+
type: LayoutModeComponentType;
|
|
42
|
+
label: string;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
description: string;
|
|
46
|
+
sourceKind: 'component' | 'block';
|
|
47
|
+
sourceId: string;
|
|
48
|
+
sourceName: string;
|
|
49
|
+
sourceLabel: string;
|
|
50
|
+
sourceImport: string | null;
|
|
51
|
+
routePath: string | null;
|
|
52
|
+
tags: string[];
|
|
53
|
+
structure: string | null;
|
|
54
|
+
guidance: string;
|
|
55
|
+
}
|
|
56
|
+
export interface ComponentSection {
|
|
57
|
+
section: string;
|
|
58
|
+
items: ComponentDefinition[];
|
|
59
|
+
}
|
|
60
|
+
export interface ViewportSize {
|
|
61
|
+
width: number;
|
|
62
|
+
height: number;
|
|
63
|
+
}
|
|
64
|
+
export interface SpatialContext {
|
|
65
|
+
top: number | null;
|
|
66
|
+
right: number | null;
|
|
67
|
+
bottom: number | null;
|
|
68
|
+
left: number | null;
|
|
69
|
+
centerX: number;
|
|
70
|
+
centerY: number;
|
|
71
|
+
rowCount: number;
|
|
72
|
+
columnCount: number;
|
|
73
|
+
}
|
|
74
|
+
export interface CSSContext {
|
|
75
|
+
parentSelector: string;
|
|
76
|
+
parentDisplay: string;
|
|
77
|
+
flexDirection?: string | null;
|
|
78
|
+
gridCols?: string | null;
|
|
79
|
+
gap?: string | null;
|
|
80
|
+
}
|
|
81
|
+
export declare const DEFAULT_SIZES: Record<LayoutModeComponentType, {
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
}>;
|
|
85
|
+
export declare const COMPONENT_REGISTRY: ComponentSection[];
|
|
86
|
+
export declare const COMPONENT_MAP: Record<LayoutModeComponentType, ComponentDefinition>;
|
|
87
|
+
/** Responsive width presets for the sketch canvas */
|
|
88
|
+
export type CanvasWidth = 375 | 768 | 1280 | 1536;
|
|
89
|
+
export declare const CANVAS_WIDTHS: readonly [{
|
|
90
|
+
readonly label: "Mobile";
|
|
91
|
+
readonly value: 375;
|
|
92
|
+
}, {
|
|
93
|
+
readonly label: "Tablet";
|
|
94
|
+
readonly value: 768;
|
|
95
|
+
}, {
|
|
96
|
+
readonly label: "Desktop";
|
|
97
|
+
readonly value: 1280;
|
|
98
|
+
}, {
|
|
99
|
+
readonly label: "Wide";
|
|
100
|
+
readonly value: 1536;
|
|
101
|
+
}];
|
|
102
|
+
/** Component action from context-aware click */
|
|
103
|
+
export type ComponentAction = {
|
|
104
|
+
kind: 'swap';
|
|
105
|
+
targetSelector: string;
|
|
106
|
+
fromComponent: string;
|
|
107
|
+
toComponent: string;
|
|
108
|
+
reason: string;
|
|
109
|
+
} | {
|
|
110
|
+
kind: 'refine';
|
|
111
|
+
targetSelector: string;
|
|
112
|
+
component: string;
|
|
113
|
+
comment: string;
|
|
114
|
+
} | {
|
|
115
|
+
kind: 'delete';
|
|
116
|
+
targetSelector: string;
|
|
117
|
+
component: string;
|
|
118
|
+
};
|
|
119
|
+
/** Catalog entry: merged metadata from spec.json + composition-data */
|
|
120
|
+
export interface CatalogEntry {
|
|
121
|
+
name: string;
|
|
122
|
+
category: string;
|
|
123
|
+
description: string;
|
|
124
|
+
tags: string[];
|
|
125
|
+
compound: boolean;
|
|
126
|
+
importPath: string;
|
|
127
|
+
structure: string | null;
|
|
128
|
+
alternatives: {
|
|
129
|
+
component: string;
|
|
130
|
+
useWhen: string;
|
|
131
|
+
rank: number;
|
|
132
|
+
}[];
|
|
133
|
+
antiPatterns: {
|
|
134
|
+
pattern: string;
|
|
135
|
+
reason: string;
|
|
136
|
+
fix: string;
|
|
137
|
+
}[];
|
|
138
|
+
combinesWith: string[];
|
|
139
|
+
}
|
|
140
|
+
/** Undo/redo history snapshot */
|
|
141
|
+
export interface HistoryEntry {
|
|
142
|
+
placements: DesignPlacement[];
|
|
143
|
+
timestamp: number;
|
|
144
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { GENERATED_LAYOUT_LIBRARY } from './generated-library.js';
|
|
2
|
+
export const DEFAULT_SIZES = {
|
|
3
|
+
navigation: { width: 800, height: 56 },
|
|
4
|
+
hero: { width: 800, height: 320 },
|
|
5
|
+
header: { width: 800, height: 80 },
|
|
6
|
+
section: { width: 800, height: 400 },
|
|
7
|
+
sidebar: { width: 240, height: 400 },
|
|
8
|
+
footer: { width: 800, height: 160 },
|
|
9
|
+
modal: { width: 480, height: 300 },
|
|
10
|
+
card: { width: 280, height: 240 },
|
|
11
|
+
text: { width: 400, height: 120 },
|
|
12
|
+
image: { width: 320, height: 200 },
|
|
13
|
+
video: { width: 480, height: 270 },
|
|
14
|
+
table: { width: 560, height: 220 },
|
|
15
|
+
grid: { width: 600, height: 300 },
|
|
16
|
+
list: { width: 300, height: 180 },
|
|
17
|
+
chart: { width: 400, height: 240 },
|
|
18
|
+
button: { width: 140, height: 40 },
|
|
19
|
+
input: { width: 280, height: 56 },
|
|
20
|
+
form: { width: 360, height: 320 },
|
|
21
|
+
tabs: { width: 480, height: 240 },
|
|
22
|
+
dropdown: { width: 200, height: 200 },
|
|
23
|
+
toggle: { width: 44, height: 24 },
|
|
24
|
+
search: { width: 320, height: 44 },
|
|
25
|
+
avatar: { width: 48, height: 48 },
|
|
26
|
+
badge: { width: 80, height: 28 },
|
|
27
|
+
breadcrumb: { width: 300, height: 24 },
|
|
28
|
+
pagination: { width: 300, height: 36 },
|
|
29
|
+
progress: { width: 240, height: 8 },
|
|
30
|
+
divider: { width: 600, height: 1 },
|
|
31
|
+
accordion: { width: 400, height: 200 },
|
|
32
|
+
carousel: { width: 600, height: 300 },
|
|
33
|
+
toast: { width: 320, height: 64 },
|
|
34
|
+
tooltip: { width: 180, height: 40 },
|
|
35
|
+
pricing: { width: 300, height: 360 },
|
|
36
|
+
testimonial: { width: 360, height: 200 },
|
|
37
|
+
cta: { width: 600, height: 160 },
|
|
38
|
+
alert: { width: 400, height: 56 },
|
|
39
|
+
banner: { width: 800, height: 48 },
|
|
40
|
+
stat: { width: 200, height: 120 },
|
|
41
|
+
stepper: { width: 480, height: 48 },
|
|
42
|
+
tag: { width: 72, height: 28 },
|
|
43
|
+
rating: { width: 160, height: 28 },
|
|
44
|
+
map: { width: 480, height: 300 },
|
|
45
|
+
timeline: { width: 360, height: 320 },
|
|
46
|
+
fileUpload: { width: 360, height: 180 },
|
|
47
|
+
codeBlock: { width: 480, height: 200 },
|
|
48
|
+
calendar: { width: 300, height: 300 },
|
|
49
|
+
notification: { width: 360, height: 72 },
|
|
50
|
+
productCard: { width: 280, height: 360 },
|
|
51
|
+
profile: { width: 280, height: 200 },
|
|
52
|
+
drawer: { width: 320, height: 400 },
|
|
53
|
+
popover: { width: 240, height: 160 },
|
|
54
|
+
logo: { width: 120, height: 40 },
|
|
55
|
+
faq: { width: 560, height: 320 },
|
|
56
|
+
gallery: { width: 560, height: 360 },
|
|
57
|
+
checkbox: { width: 20, height: 20 },
|
|
58
|
+
radio: { width: 20, height: 20 },
|
|
59
|
+
slider: { width: 240, height: 32 },
|
|
60
|
+
datePicker: { width: 300, height: 320 },
|
|
61
|
+
skeleton: { width: 320, height: 120 },
|
|
62
|
+
chip: { width: 96, height: 32 },
|
|
63
|
+
icon: { width: 24, height: 24 },
|
|
64
|
+
spinner: { width: 32, height: 32 },
|
|
65
|
+
feature: { width: 360, height: 200 },
|
|
66
|
+
team: { width: 560, height: 280 },
|
|
67
|
+
login: { width: 360, height: 360 },
|
|
68
|
+
contact: { width: 400, height: 320 },
|
|
69
|
+
};
|
|
70
|
+
export const COMPONENT_REGISTRY = GENERATED_LAYOUT_LIBRARY.map((section) => ({
|
|
71
|
+
section: section.section,
|
|
72
|
+
items: section.items.map(({ section: _section, ...item }) => ({
|
|
73
|
+
...item,
|
|
74
|
+
tags: [...item.tags],
|
|
75
|
+
...DEFAULT_SIZES[item.type],
|
|
76
|
+
})),
|
|
77
|
+
}));
|
|
78
|
+
export const COMPONENT_MAP = Object.fromEntries(COMPONENT_REGISTRY.flatMap((section) => section.items.map((item) => [item.type, item])));
|
|
79
|
+
export const CANVAS_WIDTHS = [
|
|
80
|
+
{ label: 'Mobile', value: 375 },
|
|
81
|
+
{ label: 'Tablet', value: 768 },
|
|
82
|
+
{ label: 'Desktop', value: 1280 },
|
|
83
|
+
{ label: 'Wide', value: 1536 },
|
|
84
|
+
];
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
export type AnnotationColor = 'brand' | 'info' | 'success' | 'warning' | 'error' | 'neutral';
|
|
2
|
+
export type AnnotationKind = 'feedback' | 'placement' | 'rearrange';
|
|
3
|
+
export type OutputDetail = 'compact' | 'standard' | 'detailed' | 'forensic';
|
|
4
|
+
export type AnnotationIntent = 'fix' | 'change' | 'question' | 'approve';
|
|
5
|
+
export type AnnotationSeverity = 'blocking' | 'important' | 'suggestion';
|
|
6
|
+
export type AnnotationStatus = 'pending' | 'acknowledged' | 'resolved' | 'dismissed' | 'failed';
|
|
7
|
+
export type SessionStatus = 'active' | 'approved' | 'closed';
|
|
8
|
+
export type ConnectionStatus = 'disconnected' | 'connecting' | 'connected';
|
|
9
|
+
export type ResolvedBy = 'human' | 'agent';
|
|
10
|
+
export type FeedbackTheme = 'dark' | 'light' | 'system';
|
|
11
|
+
export type MarkerClickBehavior = 'edit' | 'delete';
|
|
12
|
+
export type FeedbackLayoutMode = 'idle' | 'design' | 'rearrange';
|
|
13
|
+
export type LayoutModeComponentType = import('./layout-mode/types.js').LayoutModeComponentType;
|
|
14
|
+
export type CanvasPurpose = import('./layout-mode/types.js').CanvasPurpose;
|
|
15
|
+
export interface Rect {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
}
|
|
21
|
+
export interface ThreadMessage {
|
|
22
|
+
id: string;
|
|
23
|
+
role: 'human' | 'agent';
|
|
24
|
+
content: string;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
}
|
|
27
|
+
export interface DesignPlacement {
|
|
28
|
+
id: string;
|
|
29
|
+
type: LayoutModeComponentType;
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
scrollY: number;
|
|
35
|
+
timestamp: number;
|
|
36
|
+
text?: string;
|
|
37
|
+
note?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface DetectedSection {
|
|
40
|
+
id: string;
|
|
41
|
+
label: string;
|
|
42
|
+
tagName: string;
|
|
43
|
+
selector: string;
|
|
44
|
+
role: string | null;
|
|
45
|
+
className: string | null;
|
|
46
|
+
textSnippet: string | null;
|
|
47
|
+
originalRect: Rect;
|
|
48
|
+
currentRect: Rect;
|
|
49
|
+
originalIndex: number;
|
|
50
|
+
isFixed?: boolean;
|
|
51
|
+
note?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface RearrangeState {
|
|
54
|
+
sections: DetectedSection[];
|
|
55
|
+
originalOrder: string[];
|
|
56
|
+
detectedAt: number;
|
|
57
|
+
}
|
|
58
|
+
export interface WireframeState {
|
|
59
|
+
rearrange: RearrangeState | null;
|
|
60
|
+
placements: DesignPlacement[];
|
|
61
|
+
purpose: CanvasPurpose;
|
|
62
|
+
prompt: string;
|
|
63
|
+
}
|
|
64
|
+
export interface Session {
|
|
65
|
+
id: string;
|
|
66
|
+
url: string;
|
|
67
|
+
status: SessionStatus;
|
|
68
|
+
createdAt: string;
|
|
69
|
+
updatedAt?: string;
|
|
70
|
+
projectId?: string;
|
|
71
|
+
metadata?: Record<string, unknown>;
|
|
72
|
+
}
|
|
73
|
+
export interface SessionWithAnnotations extends Session {
|
|
74
|
+
annotations: Annotation[];
|
|
75
|
+
}
|
|
76
|
+
export interface Annotation {
|
|
77
|
+
id: string;
|
|
78
|
+
x: number;
|
|
79
|
+
y: number;
|
|
80
|
+
isFixed: boolean;
|
|
81
|
+
timestamp: number;
|
|
82
|
+
element: string;
|
|
83
|
+
elementPath: string;
|
|
84
|
+
comment: string;
|
|
85
|
+
kind?: AnnotationKind;
|
|
86
|
+
color: AnnotationColor;
|
|
87
|
+
selectedText?: string;
|
|
88
|
+
boundingBox?: Rect;
|
|
89
|
+
nearbyText?: string;
|
|
90
|
+
cssClasses?: string;
|
|
91
|
+
nearbyElements?: string;
|
|
92
|
+
computedStyles?: string;
|
|
93
|
+
accessibility?: string;
|
|
94
|
+
fullPath?: string;
|
|
95
|
+
reactComponents?: string;
|
|
96
|
+
svelteComponent?: string;
|
|
97
|
+
sourceFile?: string;
|
|
98
|
+
dryuiComponent?: string;
|
|
99
|
+
isMultiSelect?: boolean;
|
|
100
|
+
drawingIndex?: number;
|
|
101
|
+
elementBoundingBoxes?: Rect[];
|
|
102
|
+
placement?: DesignPlacement;
|
|
103
|
+
rearrange?: {
|
|
104
|
+
selector: string;
|
|
105
|
+
label: string;
|
|
106
|
+
tagName: string;
|
|
107
|
+
originalRect: Rect;
|
|
108
|
+
currentRect: Rect;
|
|
109
|
+
};
|
|
110
|
+
sessionId?: string;
|
|
111
|
+
url?: string;
|
|
112
|
+
status?: AnnotationStatus;
|
|
113
|
+
intent?: AnnotationIntent;
|
|
114
|
+
severity?: AnnotationSeverity;
|
|
115
|
+
thread?: ThreadMessage[];
|
|
116
|
+
createdAt?: string;
|
|
117
|
+
updatedAt?: string;
|
|
118
|
+
resolvedAt?: string;
|
|
119
|
+
resolvedBy?: ResolvedBy;
|
|
120
|
+
resolutionNote?: string;
|
|
121
|
+
authorId?: string;
|
|
122
|
+
_syncedTo?: string;
|
|
123
|
+
}
|
|
124
|
+
export interface FeedbackSettings {
|
|
125
|
+
outputDetail: OutputDetail;
|
|
126
|
+
autoClearAfterCopy: boolean;
|
|
127
|
+
annotationColor: AnnotationColor;
|
|
128
|
+
blockInteractions: boolean;
|
|
129
|
+
svelteDetection: boolean;
|
|
130
|
+
markerClickBehavior: MarkerClickBehavior;
|
|
131
|
+
theme: FeedbackTheme;
|
|
132
|
+
webhookUrl: string;
|
|
133
|
+
webhooksEnabled: boolean;
|
|
134
|
+
}
|
|
135
|
+
export interface FeedbackProps {
|
|
136
|
+
annotations?: Annotation[];
|
|
137
|
+
onAnnotationAdd?: (annotation: Annotation) => void;
|
|
138
|
+
onAnnotationUpdate?: (annotation: Annotation) => void;
|
|
139
|
+
onAnnotationReply?: (annotation: Annotation, message: ThreadMessage) => void;
|
|
140
|
+
onAnnotationDelete?: (annotation: Annotation) => void;
|
|
141
|
+
onAnnotationsClear?: (annotations: Annotation[]) => void;
|
|
142
|
+
onCopy?: (markdown: string) => void;
|
|
143
|
+
onSubmit?: (output: string, annotations: Annotation[]) => void;
|
|
144
|
+
onSessionCreated?: (sessionId: string) => void;
|
|
145
|
+
defaultDetail?: OutputDetail;
|
|
146
|
+
defaultColor?: AnnotationColor;
|
|
147
|
+
defaultTheme?: FeedbackTheme;
|
|
148
|
+
copyToClipboard?: boolean;
|
|
149
|
+
enableDesignMode?: boolean;
|
|
150
|
+
enableRearrange?: boolean;
|
|
151
|
+
enableSvelteDetection?: boolean;
|
|
152
|
+
endpoint?: string;
|
|
153
|
+
sessionId?: string;
|
|
154
|
+
webhookUrl?: string;
|
|
155
|
+
shortcut?: string;
|
|
156
|
+
class?: string;
|
|
157
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function detectDryUIComponent(target: EventTarget | null): string | undefined;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { collectRawSvelteLocations, findTargetElement } from './svelte-meta.js';
|
|
2
|
+
const DRYUI_FILE_PATTERNS = [
|
|
3
|
+
/\/packages\/ui\/src\/([^/]+)\//i,
|
|
4
|
+
/\/node_modules\/@dryui\/ui\/src\/([^/]+)\//i,
|
|
5
|
+
/\/@dryui\/ui\/src\/([^/]+)\//i,
|
|
6
|
+
];
|
|
7
|
+
const ATTRIBUTE_KEYS = [
|
|
8
|
+
'variant',
|
|
9
|
+
'size',
|
|
10
|
+
'color',
|
|
11
|
+
'tone',
|
|
12
|
+
'align',
|
|
13
|
+
'orientation',
|
|
14
|
+
'shape',
|
|
15
|
+
'position',
|
|
16
|
+
'status',
|
|
17
|
+
'side',
|
|
18
|
+
'part',
|
|
19
|
+
'state',
|
|
20
|
+
];
|
|
21
|
+
const CLASS_PROP_GROUPS = {
|
|
22
|
+
variant: new Set(['solid', 'outline', 'ghost', 'soft', 'secondary', 'link', 'default', 'elevated', 'interactive']),
|
|
23
|
+
size: new Set(['sm', 'md', 'lg', 'icon', 'icon-sm', 'icon-lg']),
|
|
24
|
+
color: new Set(['primary', 'danger', 'gray', 'brand', 'info', 'success', 'warning', 'error', 'neutral', 'blue', 'cyan', 'green', 'yellow', 'orange', 'red', 'indigo']),
|
|
25
|
+
align: new Set(['left', 'center', 'right']),
|
|
26
|
+
orientation: new Set(['horizontal', 'vertical']),
|
|
27
|
+
};
|
|
28
|
+
function isPropLikeLocalToken(token) {
|
|
29
|
+
return Object.values(CLASS_PROP_GROUPS).some((group) => group.has(token));
|
|
30
|
+
}
|
|
31
|
+
function collectRawSvelteFiles(target) {
|
|
32
|
+
return collectRawSvelteLocations(target).map((location) => location.file);
|
|
33
|
+
}
|
|
34
|
+
function toComponentName(value) {
|
|
35
|
+
return value
|
|
36
|
+
.split(/[-_]+/)
|
|
37
|
+
.filter(Boolean)
|
|
38
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
39
|
+
.join('');
|
|
40
|
+
}
|
|
41
|
+
function detectComponentFromFiles(target) {
|
|
42
|
+
for (const file of collectRawSvelteFiles(target)) {
|
|
43
|
+
for (const pattern of DRYUI_FILE_PATTERNS) {
|
|
44
|
+
const match = file.match(pattern);
|
|
45
|
+
if (match?.[1]) {
|
|
46
|
+
return toComponentName(match[1]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
function normalizeClassToken(token) {
|
|
53
|
+
const trimmed = token.trim();
|
|
54
|
+
const normalized = trimmed.replace(/^_+/, '');
|
|
55
|
+
if (trimmed.startsWith('_')) {
|
|
56
|
+
const localOnlyMatch = normalized.match(/^([A-Za-z0-9-]+)_[A-Za-z0-9-]+(?:_\d+)?$/);
|
|
57
|
+
if (localOnlyMatch?.[1]) {
|
|
58
|
+
return ['', localOnlyMatch[1]];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const moduleMatch = normalized.match(/^([a-z0-9-]+)_([A-Za-z0-9-]+)(?:__|_[A-Za-z0-9-]+$)/);
|
|
62
|
+
if (moduleMatch) {
|
|
63
|
+
return [moduleMatch[1] ?? '', moduleMatch[2] ?? ''];
|
|
64
|
+
}
|
|
65
|
+
const localOnlyMatch = normalized.match(/^([A-Za-z0-9-]+)_[A-Za-z0-9-]+(?:_\d+)?$/);
|
|
66
|
+
if (localOnlyMatch?.[1]) {
|
|
67
|
+
return ['', localOnlyMatch[1]];
|
|
68
|
+
}
|
|
69
|
+
if (/^[a-z][a-z0-9-]*$/.test(normalized)) {
|
|
70
|
+
return ['', normalized];
|
|
71
|
+
}
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
function collectClassTokenGroups(element) {
|
|
75
|
+
const groups = new Map();
|
|
76
|
+
let current = element;
|
|
77
|
+
let depth = 0;
|
|
78
|
+
while (current && depth < 3) {
|
|
79
|
+
for (const token of getClassTokens(current)) {
|
|
80
|
+
const [prefix, local] = normalizeClassToken(token);
|
|
81
|
+
if (!prefix || !local)
|
|
82
|
+
continue;
|
|
83
|
+
let group = groups.get(prefix);
|
|
84
|
+
if (!group) {
|
|
85
|
+
group = new Set();
|
|
86
|
+
groups.set(prefix, group);
|
|
87
|
+
}
|
|
88
|
+
group.add(normalizePropValue(local));
|
|
89
|
+
}
|
|
90
|
+
current = current.parentElement;
|
|
91
|
+
depth += 1;
|
|
92
|
+
}
|
|
93
|
+
return groups;
|
|
94
|
+
}
|
|
95
|
+
function collectLocalClassTokens(element, depthLimit) {
|
|
96
|
+
const locals = new Set();
|
|
97
|
+
let current = element;
|
|
98
|
+
let depth = 0;
|
|
99
|
+
while (current && depth < depthLimit) {
|
|
100
|
+
for (const token of getClassTokens(current)) {
|
|
101
|
+
const [, local] = normalizeClassToken(token);
|
|
102
|
+
if (local) {
|
|
103
|
+
locals.add(normalizePropValue(local));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
current = current.parentElement;
|
|
107
|
+
depth += 1;
|
|
108
|
+
}
|
|
109
|
+
return locals;
|
|
110
|
+
}
|
|
111
|
+
function getRuntimeSignatureToken(token) {
|
|
112
|
+
const trimmed = token.trim();
|
|
113
|
+
if (!trimmed.startsWith('_')) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const normalized = trimmed.replace(/^_+/, '');
|
|
117
|
+
const match = normalized.match(/^([A-Za-z0-9-]+)_([A-Za-z0-9-]+)(?:_\d+)?$/);
|
|
118
|
+
if (!match?.[1] || !match[2]) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
signature: match[2],
|
|
123
|
+
local: normalizePropValue(match[1]),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function collectRuntimeSignatureGroups(element, depthLimit) {
|
|
127
|
+
const groups = new Map();
|
|
128
|
+
let current = element;
|
|
129
|
+
let depth = 0;
|
|
130
|
+
while (current && depth < depthLimit) {
|
|
131
|
+
for (const token of getClassTokens(current)) {
|
|
132
|
+
const normalized = getRuntimeSignatureToken(token);
|
|
133
|
+
if (!normalized)
|
|
134
|
+
continue;
|
|
135
|
+
let group = groups.get(normalized.signature);
|
|
136
|
+
if (!group) {
|
|
137
|
+
group = new Set();
|
|
138
|
+
groups.set(normalized.signature, group);
|
|
139
|
+
}
|
|
140
|
+
group.add(normalized.local);
|
|
141
|
+
}
|
|
142
|
+
current = current.parentElement;
|
|
143
|
+
depth += 1;
|
|
144
|
+
}
|
|
145
|
+
return groups;
|
|
146
|
+
}
|
|
147
|
+
function detectComponentFromClassTokens(element) {
|
|
148
|
+
for (const [prefix, locals] of collectClassTokenGroups(element)) {
|
|
149
|
+
if (!locals.has('wrapper'))
|
|
150
|
+
continue;
|
|
151
|
+
if (!locals.has(prefix) && !locals.has('root'))
|
|
152
|
+
continue;
|
|
153
|
+
return toComponentName(prefix);
|
|
154
|
+
}
|
|
155
|
+
const tagName = element.tagName.toLowerCase();
|
|
156
|
+
const currentRuntimeGroups = collectRuntimeSignatureGroups(element, 1);
|
|
157
|
+
const nearbyRuntimeGroups = collectRuntimeSignatureGroups(element, 3);
|
|
158
|
+
for (const [signature, currentLocals] of currentRuntimeGroups) {
|
|
159
|
+
const nearbyLocals = nearbyRuntimeGroups.get(signature);
|
|
160
|
+
if (!nearbyLocals?.has('wrapper'))
|
|
161
|
+
continue;
|
|
162
|
+
const hasPropToken = Array.from(currentLocals).some((local) => isPropLikeLocalToken(local));
|
|
163
|
+
if (currentLocals.has(tagName) && hasPropToken) {
|
|
164
|
+
return toComponentName(tagName);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
function getClassTokens(element) {
|
|
170
|
+
return (element.getAttribute('class') ?? '')
|
|
171
|
+
.split(/\s+/)
|
|
172
|
+
.map((token) => token.trim())
|
|
173
|
+
.filter(Boolean);
|
|
174
|
+
}
|
|
175
|
+
function normalizePropValue(value) {
|
|
176
|
+
return value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`).replace(/^-/, '');
|
|
177
|
+
}
|
|
178
|
+
function collectProps(element) {
|
|
179
|
+
const props = new Set();
|
|
180
|
+
let current = element;
|
|
181
|
+
let depth = 0;
|
|
182
|
+
while (current && depth < 4) {
|
|
183
|
+
for (const key of ATTRIBUTE_KEYS) {
|
|
184
|
+
const value = current.getAttribute(`data-${key}`);
|
|
185
|
+
if (value === null)
|
|
186
|
+
continue;
|
|
187
|
+
props.add(value === '' ? key : `${key}=${normalizePropValue(value)}`);
|
|
188
|
+
}
|
|
189
|
+
for (const token of getClassTokens(current)) {
|
|
190
|
+
const [, local] = normalizeClassToken(token);
|
|
191
|
+
if (!local)
|
|
192
|
+
continue;
|
|
193
|
+
const normalized = normalizePropValue(local);
|
|
194
|
+
if (CLASS_PROP_GROUPS.variant.has(normalized))
|
|
195
|
+
props.add(`variant=${normalized}`);
|
|
196
|
+
if (CLASS_PROP_GROUPS.size.has(normalized))
|
|
197
|
+
props.add(`size=${normalized}`);
|
|
198
|
+
if (CLASS_PROP_GROUPS.color.has(normalized))
|
|
199
|
+
props.add(`color=${normalized}`);
|
|
200
|
+
if (CLASS_PROP_GROUPS.align.has(normalized))
|
|
201
|
+
props.add(`align=${normalized}`);
|
|
202
|
+
if (CLASS_PROP_GROUPS.orientation.has(normalized))
|
|
203
|
+
props.add(`orientation=${normalized}`);
|
|
204
|
+
}
|
|
205
|
+
current = current.parentElement;
|
|
206
|
+
depth += 1;
|
|
207
|
+
}
|
|
208
|
+
return Array.from(props);
|
|
209
|
+
}
|
|
210
|
+
export function detectDryUIComponent(target) {
|
|
211
|
+
const element = findTargetElement(target);
|
|
212
|
+
if (!element)
|
|
213
|
+
return undefined;
|
|
214
|
+
const component = detectComponentFromFiles(target) ?? detectComponentFromClassTokens(element);
|
|
215
|
+
if (!component)
|
|
216
|
+
return undefined;
|
|
217
|
+
const props = collectProps(element);
|
|
218
|
+
return props.length > 0 ? `${component} ${props.join(' ')}` : component;
|
|
219
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function identifyElement(el: Element): {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function getElementPath(el: Element, maxDepth?: number): string;
|
|
6
|
+
export declare function getFullElementPath(el: Element): string;
|
|
7
|
+
export declare function getNearbyText(el: Element): string;
|
|
8
|
+
export declare function getNearbyElements(el: Element): string;
|
|
9
|
+
export declare function getElementClasses(el: Element): string;
|
|
10
|
+
export declare function getDetailedComputedStyles(el: Element): Record<string, string>;
|
|
11
|
+
export declare function getForensicComputedStyles(el: Element): string;
|
|
12
|
+
export declare function getAccessibilityInfo(el: Element): string;
|