@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.
Files changed (79) hide show
  1. package/dist/components/annotation-marker.svelte +163 -0
  2. package/dist/components/annotation-marker.svelte.d.ts +11 -0
  3. package/dist/components/annotation-popup.svelte +669 -0
  4. package/dist/components/annotation-popup.svelte.d.ts +42 -0
  5. package/dist/components/highlight-overlay.svelte +48 -0
  6. package/dist/components/highlight-overlay.svelte.d.ts +8 -0
  7. package/dist/components/settings-panel.svelte +446 -0
  8. package/dist/components/settings-panel.svelte.d.ts +24 -0
  9. package/dist/components/toolbar.svelte +1111 -0
  10. package/dist/components/toolbar.svelte.d.ts +46 -0
  11. package/dist/constants.d.ts +9 -0
  12. package/dist/constants.js +37 -0
  13. package/dist/feedback.svelte +2879 -0
  14. package/dist/feedback.svelte.d.ts +4 -0
  15. package/dist/index.d.ts +10 -0
  16. package/dist/index.js +7 -0
  17. package/dist/layout-mode/catalog.d.ts +16 -0
  18. package/dist/layout-mode/catalog.js +81 -0
  19. package/dist/layout-mode/component-actions.svelte +84 -0
  20. package/dist/layout-mode/component-actions.svelte.d.ts +18 -0
  21. package/dist/layout-mode/component-picker.svelte +73 -0
  22. package/dist/layout-mode/component-picker.svelte.d.ts +10 -0
  23. package/dist/layout-mode/design-mode.svelte +1115 -0
  24. package/dist/layout-mode/design-mode.svelte.d.ts +24 -0
  25. package/dist/layout-mode/design-palette.svelte +396 -0
  26. package/dist/layout-mode/design-palette.svelte.d.ts +20 -0
  27. package/dist/layout-mode/element-heuristics.d.ts +5 -0
  28. package/dist/layout-mode/element-heuristics.js +51 -0
  29. package/dist/layout-mode/freeze.d.ts +6 -0
  30. package/dist/layout-mode/freeze.js +163 -0
  31. package/dist/layout-mode/generated-library.d.ts +940 -0
  32. package/dist/layout-mode/generated-library.js +1445 -0
  33. package/dist/layout-mode/geometry.d.ts +38 -0
  34. package/dist/layout-mode/geometry.js +133 -0
  35. package/dist/layout-mode/history.d.ts +10 -0
  36. package/dist/layout-mode/history.js +45 -0
  37. package/dist/layout-mode/index.d.ts +23 -0
  38. package/dist/layout-mode/index.js +18 -0
  39. package/dist/layout-mode/live-mount.d.ts +20 -0
  40. package/dist/layout-mode/live-mount.js +70 -0
  41. package/dist/layout-mode/output.d.ts +26 -0
  42. package/dist/layout-mode/output.js +550 -0
  43. package/dist/layout-mode/placement-skeleton.d.ts +9 -0
  44. package/dist/layout-mode/placement-skeleton.js +535 -0
  45. package/dist/layout-mode/rearrange-overlay.svelte +1293 -0
  46. package/dist/layout-mode/rearrange-overlay.svelte.d.ts +18 -0
  47. package/dist/layout-mode/responsive-bar.svelte +39 -0
  48. package/dist/layout-mode/responsive-bar.svelte.d.ts +8 -0
  49. package/dist/layout-mode/route-creator.svelte +70 -0
  50. package/dist/layout-mode/route-creator.svelte.d.ts +8 -0
  51. package/dist/layout-mode/section-detection.d.ts +6 -0
  52. package/dist/layout-mode/section-detection.js +214 -0
  53. package/dist/layout-mode/spatial.d.ts +42 -0
  54. package/dist/layout-mode/spatial.js +156 -0
  55. package/dist/layout-mode/types.d.ts +144 -0
  56. package/dist/layout-mode/types.js +84 -0
  57. package/dist/types.d.ts +157 -0
  58. package/dist/types.js +1 -0
  59. package/dist/utils/dryui-detection.d.ts +1 -0
  60. package/dist/utils/dryui-detection.js +219 -0
  61. package/dist/utils/element-id.d.ts +12 -0
  62. package/dist/utils/element-id.js +333 -0
  63. package/dist/utils/freeze.d.ts +7 -0
  64. package/dist/utils/freeze.js +168 -0
  65. package/dist/utils/output.d.ts +15 -0
  66. package/dist/utils/output.js +245 -0
  67. package/dist/utils/selection.d.ts +22 -0
  68. package/dist/utils/selection.js +58 -0
  69. package/dist/utils/shadow-dom.d.ts +4 -0
  70. package/dist/utils/shadow-dom.js +39 -0
  71. package/dist/utils/storage.d.ts +30 -0
  72. package/dist/utils/storage.js +206 -0
  73. package/dist/utils/svelte-detection.d.ts +8 -0
  74. package/dist/utils/svelte-detection.js +86 -0
  75. package/dist/utils/svelte-meta.d.ts +6 -0
  76. package/dist/utils/svelte-meta.js +69 -0
  77. package/dist/utils/sync.d.ts +18 -0
  78. package/dist/utils/sync.js +62 -0
  79. package/package.json +65 -0
@@ -0,0 +1,4 @@
1
+ import type { FeedbackProps } from './types.js';
2
+ declare const Feedback: import("svelte").Component<FeedbackProps, {}, "">;
3
+ type Feedback = ReturnType<typeof Feedback>;
4
+ export default Feedback;
@@ -0,0 +1,10 @@
1
+ export { default as Feedback } from './feedback.svelte';
2
+ export type { Annotation, AnnotationColor, AnnotationKind, AnnotationIntent, AnnotationSeverity, AnnotationStatus, ConnectionStatus, DesignPlacement, DetectedSection, OutputDetail, Rect, FeedbackSettings, FeedbackTheme, FeedbackProps, MarkerClickBehavior, RearrangeState, Session, SessionStatus, SessionWithAnnotations, ThreadMessage, WireframeState, } from './types.js';
3
+ export type { GenerateOutputOptions } from './utils/output.js';
4
+ export type { ActionResponse } from './utils/sync.js';
5
+ export { identifyElement, getElementPath, getNearbyText, getElementClasses } from './utils/element-id.js';
6
+ export { deepElementFromPoint, isInShadowDOM, getShadowHost, closestCrossingShadow } from './utils/shadow-dom.js';
7
+ export { clearAnnotations, clearDesignPlacements, clearRearrangeState, clearSessionId, clearSettings, clearSyncMarkers, clearWireframeState, getSessionStorageKey, getStorageKey, getUnsyncedAnnotations, loadAllAnnotations, loadAnnotations, loadDesignPlacements, loadRearrangeState, loadSessionId, loadSettings, loadToolbarHidden, loadWireframeState, saveAnnotations, saveAnnotationsWithSyncMarker, saveDesignPlacements, saveRearrangeState, saveSessionId, saveSettings, saveToolbarHidden, saveWireframeState, } from './utils/storage.js';
8
+ export { OUTPUT_DETAIL_OPTIONS, generateDesignOutput, generateFeedbackOutput, generateOutput, generateRearrangeOutput, } from './utils/output.js';
9
+ export { animationsAreFrozen, freezeAnimations, originalRequestAnimationFrame, originalSetInterval, originalSetTimeout, toggleAnimationsFrozen, unfreezeAnimations, } from './utils/freeze.js';
10
+ export { createSession, deleteAnnotation, getSession, listSessions, requestAction, syncAnnotation, updateAnnotation, } from './utils/sync.js';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { default as Feedback } from './feedback.svelte';
2
+ export { identifyElement, getElementPath, getNearbyText, getElementClasses } from './utils/element-id.js';
3
+ export { deepElementFromPoint, isInShadowDOM, getShadowHost, closestCrossingShadow } from './utils/shadow-dom.js';
4
+ export { clearAnnotations, clearDesignPlacements, clearRearrangeState, clearSessionId, clearSettings, clearSyncMarkers, clearWireframeState, getSessionStorageKey, getStorageKey, getUnsyncedAnnotations, loadAllAnnotations, loadAnnotations, loadDesignPlacements, loadRearrangeState, loadSessionId, loadSettings, loadToolbarHidden, loadWireframeState, saveAnnotations, saveAnnotationsWithSyncMarker, saveDesignPlacements, saveRearrangeState, saveSessionId, saveSettings, saveToolbarHidden, saveWireframeState, } from './utils/storage.js';
5
+ export { OUTPUT_DETAIL_OPTIONS, generateDesignOutput, generateFeedbackOutput, generateOutput, generateRearrangeOutput, } from './utils/output.js';
6
+ export { animationsAreFrozen, freezeAnimations, originalRequestAnimationFrame, originalSetInterval, originalSetTimeout, toggleAnimationsFrozen, unfreezeAnimations, } from './utils/freeze.js';
7
+ export { createSession, deleteAnnotation, getSession, listSessions, requestAction, syncAnnotation, updateAnnotation, } from './utils/sync.js';
@@ -0,0 +1,16 @@
1
+ import type { CatalogEntry } from './types.js';
2
+ export declare function getCatalog(): CatalogEntry[];
3
+ export declare function loadCatalog(): Promise<CatalogEntry[]>;
4
+ /**
5
+ * Token-based keyword search over a loaded catalog. Returns entries sorted by
6
+ * descending relevance score (matches against name, tags, description, category).
7
+ */
8
+ export declare function searchCatalog(catalog: CatalogEntry[], query: string): CatalogEntry[];
9
+ /**
10
+ * Return alternatives for a given component name (empty array if unknown).
11
+ */
12
+ export declare function getAlternatives(catalog: CatalogEntry[], name: string): CatalogEntry['alternatives'];
13
+ /**
14
+ * Return anti-patterns for a given component name (empty array if unknown).
15
+ */
16
+ export declare function getAntiPatterns(catalog: CatalogEntry[], name: string): CatalogEntry['antiPatterns'];
@@ -0,0 +1,81 @@
1
+ let cachedCatalog = null;
2
+ export function getCatalog() {
3
+ return cachedCatalog ?? [];
4
+ }
5
+ export async function loadCatalog() {
6
+ if (cachedCatalog)
7
+ return cachedCatalog;
8
+ const [specMod, compMod] = await Promise.all([
9
+ import('@dryui/mcp/spec'),
10
+ import('@dryui/mcp/composition-data'),
11
+ ]);
12
+ const spec = (specMod.default ?? specMod);
13
+ const compositions = compMod.componentCompositions;
14
+ const compositionMap = new Map(compositions.map((c) => [c.component, c]));
15
+ const entries = Object.entries(spec.components).map(([name, meta]) => {
16
+ const comp = compositionMap.get(name);
17
+ return {
18
+ name,
19
+ category: meta.category,
20
+ description: meta.description,
21
+ tags: meta.tags,
22
+ compound: meta.compound,
23
+ importPath: meta.import,
24
+ structure: meta.structure ? meta.structure.tree.join('\n') : null,
25
+ alternatives: comp?.alternatives.map(({ rank, component, useWhen }) => ({ rank, component, useWhen })) ?? [],
26
+ antiPatterns: comp?.antiPatterns ?? [],
27
+ combinesWith: comp?.combinesWith ?? [],
28
+ };
29
+ });
30
+ cachedCatalog = entries;
31
+ return entries;
32
+ }
33
+ /**
34
+ * Token-based keyword search over a loaded catalog. Returns entries sorted by
35
+ * descending relevance score (matches against name, tags, description, category).
36
+ */
37
+ export function searchCatalog(catalog, query) {
38
+ const tokens = query.toLowerCase().split(/\s+/).filter(Boolean);
39
+ if (tokens.length === 0)
40
+ return catalog;
41
+ const scored = catalog.map((entry) => {
42
+ const name = entry.name.toLowerCase();
43
+ const desc = entry.description.toLowerCase();
44
+ const tags = entry.tags.map((t) => t.toLowerCase());
45
+ const category = entry.category.toLowerCase();
46
+ let score = 0;
47
+ for (const token of tokens) {
48
+ if (name === token)
49
+ score += 10;
50
+ else if (name.startsWith(token))
51
+ score += 6;
52
+ else if (name.includes(token))
53
+ score += 4;
54
+ if (tags.includes(token))
55
+ score += 5;
56
+ else if (tags.some((t) => t.includes(token)))
57
+ score += 2;
58
+ if (category === token)
59
+ score += 3;
60
+ if (desc.includes(token))
61
+ score += 1;
62
+ }
63
+ return { entry, score };
64
+ });
65
+ return scored
66
+ .filter(({ score }) => score > 0)
67
+ .sort((a, b) => b.score - a.score)
68
+ .map(({ entry }) => entry);
69
+ }
70
+ /**
71
+ * Return alternatives for a given component name (empty array if unknown).
72
+ */
73
+ export function getAlternatives(catalog, name) {
74
+ return catalog.find((e) => e.name === name)?.alternatives ?? [];
75
+ }
76
+ /**
77
+ * Return anti-patterns for a given component name (empty array if unknown).
78
+ */
79
+ export function getAntiPatterns(catalog, name) {
80
+ return catalog.find((e) => e.name === name)?.antiPatterns ?? [];
81
+ }
@@ -0,0 +1,84 @@
1
+ <script lang="ts">
2
+ import { Button } from '@dryui/ui/button';
3
+ import { Separator } from '@dryui/ui/separator';
4
+ import { Stack } from '@dryui/ui/stack';
5
+ import { Text } from '@dryui/ui/text';
6
+
7
+ interface Props {
8
+ component: { name: string; selector: string; props: Record<string, string> };
9
+ position: { x: number; y: number };
10
+ onSwap: () => void;
11
+ onRefine: (comment: string) => void;
12
+ onDelete: () => void;
13
+ onClose: () => void;
14
+ }
15
+
16
+ let { component, position, onSwap, onRefine, onDelete, onClose }: Props = $props();
17
+
18
+ const propsLabel = $derived(
19
+ Object.entries(component.props)
20
+ .map(([k, v]) => `${k}=${v}`)
21
+ .join(', '),
22
+ );
23
+
24
+ function trapClicks(node: HTMLElement) {
25
+ function stop(e: Event) { e.stopPropagation(); }
26
+ node.addEventListener('click', stop);
27
+ node.addEventListener('mousedown', stop);
28
+ return { destroy() {
29
+ node.removeEventListener('click', stop);
30
+ node.removeEventListener('mousedown', stop);
31
+ }};
32
+ }
33
+ </script>
34
+
35
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
36
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
37
+ <div
38
+ class="component-actions"
39
+ data-dryui-feedback
40
+ use:trapClicks
41
+ style="left: {position.x}px; top: {position.y}px;"
42
+ >
43
+ <Stack gap="2">
44
+ <Stack gap="1">
45
+ <Text weight="semibold" size="sm">{component.name}</Text>
46
+ {#if propsLabel}
47
+ <Text size="xs" color="weak">{propsLabel}</Text>
48
+ {/if}
49
+ </Stack>
50
+
51
+ <Separator />
52
+
53
+ <Stack gap="1">
54
+ <Button variant="ghost" size="sm" onclick={onSwap} style="justify-content: flex-start;">
55
+ Swap component...
56
+ </Button>
57
+ <Button variant="ghost" size="sm" onclick={() => onRefine('')} style="justify-content: flex-start;">
58
+ Refine with note
59
+ </Button>
60
+ <Button
61
+ variant="ghost"
62
+ size="sm"
63
+ color="error"
64
+ onclick={onDelete}
65
+ style="justify-content: flex-start;"
66
+ >
67
+ Delete
68
+ </Button>
69
+ </Stack>
70
+ </Stack>
71
+ </div>
72
+
73
+ <style>
74
+ .component-actions {
75
+ position: fixed;
76
+ z-index: 10003;
77
+ background: var(--dry-color-bg-raised);
78
+ border: 1px solid var(--dry-color-stroke-weak);
79
+ border-radius: var(--dry-radius-lg);
80
+ box-shadow: var(--dry-shadow-lg);
81
+ min-width: 200px;
82
+ padding: var(--dry-space-3);
83
+ }
84
+ </style>
@@ -0,0 +1,18 @@
1
+ interface Props {
2
+ component: {
3
+ name: string;
4
+ selector: string;
5
+ props: Record<string, string>;
6
+ };
7
+ position: {
8
+ x: number;
9
+ y: number;
10
+ };
11
+ onSwap: () => void;
12
+ onRefine: (comment: string) => void;
13
+ onDelete: () => void;
14
+ onClose: () => void;
15
+ }
16
+ declare const ComponentActions: import("svelte").Component<Props, {}, "">;
17
+ type ComponentActions = ReturnType<typeof ComponentActions>;
18
+ export default ComponentActions;
@@ -0,0 +1,73 @@
1
+ <script lang="ts">
2
+ import { CommandPalette, Flex, Text } from '@dryui/ui';
3
+ import { thumbnailMap } from '@dryui/ui/thumbnail';
4
+ import { loadCatalog } from './catalog.js';
5
+ import type { CatalogEntry } from './types.js';
6
+
7
+ interface Props {
8
+ open: boolean;
9
+ filter?: string;
10
+ onSelect: (entry: CatalogEntry) => void;
11
+ onClose: () => void;
12
+ }
13
+
14
+ let { open = $bindable(false), filter = '', onSelect, onClose }: Props = $props();
15
+
16
+ let catalog: CatalogEntry[] = $state([]);
17
+
18
+ $effect(() => {
19
+ loadCatalog()
20
+ .then((c) => { catalog = c; })
21
+ .catch(() => {});
22
+ });
23
+
24
+ const grouped = $derived(
25
+ catalog.reduce<Record<string, CatalogEntry[]>>((acc, entry) => {
26
+ const key = entry.category || 'Other';
27
+ (acc[key] ??= []).push(entry);
28
+ return acc;
29
+ }, {}),
30
+ );
31
+
32
+ function itemValue(entry: CatalogEntry): string {
33
+ return [entry.name, entry.description, ...entry.tags, entry.category].join(' ');
34
+ }
35
+ </script>
36
+
37
+ <CommandPalette.Root bind:open onclose={onClose}>
38
+ <CommandPalette.Input
39
+ placeholder="Search components..."
40
+ value={filter || undefined}
41
+ />
42
+ <CommandPalette.List>
43
+ <CommandPalette.Empty>No components found.</CommandPalette.Empty>
44
+ {#each Object.entries(grouped) as [category, entries]}
45
+ <CommandPalette.Group heading={category}>
46
+ {#each entries as entry (entry.name)}
47
+ <CommandPalette.Item
48
+ value={itemValue(entry)}
49
+ onSelect={() => {
50
+ onSelect(entry);
51
+ open = false;
52
+ }}
53
+ >
54
+ <Flex align="center" gap="sm">
55
+ {#if thumbnailMap[entry.name]}
56
+ {@const Thumb = thumbnailMap[entry.name]}
57
+ <div style="width: 32px; height: 32px; flex-shrink: 0; overflow: hidden; border-radius: var(--dry-radius-sm);">
58
+ <svelte:component this={Thumb} size="sm" />
59
+ </div>
60
+ {/if}
61
+ <Flex direction="column">
62
+ <Text weight="semibold" size="sm">{entry.name}</Text>
63
+ {#if entry.description}
64
+ <Text size="xs" color="secondary">{entry.description}</Text>
65
+ {/if}
66
+ </Flex>
67
+ </Flex>
68
+ </CommandPalette.Item>
69
+ {/each}
70
+ </CommandPalette.Group>
71
+ {/each}
72
+ </CommandPalette.List>
73
+ </CommandPalette.Root>
@@ -0,0 +1,10 @@
1
+ import type { CatalogEntry } from './types.js';
2
+ interface Props {
3
+ open: boolean;
4
+ filter?: string;
5
+ onSelect: (entry: CatalogEntry) => void;
6
+ onClose: () => void;
7
+ }
8
+ declare const ComponentPicker: import("svelte").Component<Props, {}, "open">;
9
+ type ComponentPicker = ReturnType<typeof ComponentPicker>;
10
+ export default ComponentPicker;