proto-plugin 0.1.0 → 0.1.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 (91) hide show
  1. package/AGENTS.md +308 -29
  2. package/README.md +55 -13
  3. package/package.json +1 -1
  4. package/scripts/lib/host-config.example.sh +1 -1
  5. package/scripts/publish-package.sh +41 -0
  6. package/scripts/verify-prototype-preview-states.mjs +57 -0
  7. package/src/components/platform-ui/controls-panel-select.tsx +4 -3
  8. package/src/components/platform-ui/prototype-tool-dialog.tsx +117 -0
  9. package/src/components/platform-ui/sidebar.tsx +34 -16
  10. package/src/components/prototype-gallery-client.tsx +77 -37
  11. package/src/components/prototypes/design-exploration-variant-preview-shell.tsx +43 -0
  12. package/src/components/prototypes/prototype-brief-field.tsx +33 -0
  13. package/src/components/prototypes/prototype-change-log-panel.tsx +4 -0
  14. package/src/components/prototypes/prototype-comment-storage-empty-state.tsx +41 -0
  15. package/src/components/prototypes/prototype-create-exploration-modal.tsx +41 -64
  16. package/src/components/prototypes/prototype-create-prototype-modal.tsx +102 -0
  17. package/src/components/prototypes/prototype-create-state-modal.tsx +31 -70
  18. package/src/components/prototypes/prototype-default-state-map-page.tsx +4 -4
  19. package/src/components/prototypes/prototype-design-brief-modal.tsx +10 -10
  20. package/src/components/prototypes/prototype-design-brief-panel.tsx +261 -231
  21. package/src/components/prototypes/prototype-floating-pill.module.scss +16 -9
  22. package/src/components/prototypes/prototype-mobbin-gallery.tsx +18 -2
  23. package/src/components/prototypes/prototype-review-sidebar.tsx +11 -28
  24. package/src/components/prototypes/prototype-spec-panel-content.tsx +5 -5
  25. package/src/components/prototypes/prototype-spec-panel-empty-state.tsx +53 -0
  26. package/src/components/prototypes/prototype-state-canvas-overlay.module.scss +20 -47
  27. package/src/components/prototypes/prototype-state-canvas-overlay.tsx +4 -42
  28. package/src/components/prototypes/prototype-variant-explorer.tsx +32 -78
  29. package/src/components/prototypes/prototype-vercel-preview-modal.tsx +4 -3
  30. package/src/components/prototypes/state-map-annotation-tooltip.module.scss +7 -7
  31. package/src/components/shell/prototype-component-library-empty-state.tsx +59 -0
  32. package/src/components/shell/prototype-gallery-nav.tsx +124 -0
  33. package/src/components/shell/prototype-gallery-shell.tsx +45 -13
  34. package/src/components/shell/prototype-link-source-modal.tsx +100 -0
  35. package/src/components/ui/button.tsx +3 -1
  36. package/src/components/ui/dialog.tsx +43 -4
  37. package/src/config/create-prototype-component-library-page.tsx +74 -0
  38. package/src/config/create-prototype-gallery-page.tsx +26 -23
  39. package/src/config/create-prototype-host-app.tsx +3 -15
  40. package/src/config/create-prototype-site-layout.tsx +14 -1
  41. package/src/config/create-prototype-state-map-page.tsx +44 -0
  42. package/src/config/prototype-site-layout-client.tsx +20 -6
  43. package/src/config/with-prototype.ts +21 -0
  44. package/src/index.ts +54 -10
  45. package/src/lib/copy-text-with-attachments.ts +35 -0
  46. package/src/lib/format-source-directory-name.ts +12 -0
  47. package/src/lib/platform-ui/sidebar-interactive-cursor.ts +19 -0
  48. package/src/lib/pr-split/build-pr-split-plan-prompt.ts +81 -0
  49. package/src/lib/pr-split/pr-split-highlight.ts +3 -0
  50. package/src/lib/prototype-comments/core/annotation-target.ts +12 -3
  51. package/src/lib/prototype-comments/core/comment-capture-blocked.ts +24 -0
  52. package/src/lib/prototype-comments/core/screenshot.ts +68 -31
  53. package/src/lib/prototype-comments/core/storage.ts +3 -6
  54. package/src/lib/prototype-comments/core/types.ts +2 -0
  55. package/src/lib/prototype-comments/hooks/useLayoutShift.ts +9 -2
  56. package/src/lib/prototype-comments/react/CommentCaptureToolbar.tsx +45 -10
  57. package/src/lib/prototype-comments/react/CommentProvider.tsx +19 -0
  58. package/src/lib/prototype-comments/ui/CommentModeToggleButton.tsx +34 -0
  59. package/src/lib/prototype-comments/ui/CommentsGrid.tsx +8 -16
  60. package/src/lib/prototype-comments/ui/CommentsSidebar.tsx +5 -19
  61. package/src/lib/prototype-comments/ui/capture-styles.module.scss +5 -1
  62. package/src/lib/prototype-comments/ui/comments-grid-card.module.scss +0 -7
  63. package/src/lib/prototypes/build-design-exploration-renderers.ts +44 -0
  64. package/src/lib/prototypes/comment-storage-setup-prompt.ts +124 -0
  65. package/src/lib/prototypes/create-prototype-prompt.ts +96 -0
  66. package/src/lib/prototypes/create-prototype-registry.ts +5 -0
  67. package/src/lib/prototypes/design-exploration-types.ts +261 -10
  68. package/src/lib/prototypes/link-source-prompt.ts +93 -0
  69. package/src/lib/prototypes/populate-component-library-prompt.ts +64 -0
  70. package/src/lib/prototypes/prototype-config-types.ts +2 -0
  71. package/src/lib/prototypes/prototype-layout-classes.ts +19 -0
  72. package/src/lib/prototypes/prototype-preview-state-registry.ts +5 -2
  73. package/src/lib/prototypes/prototype-review-context.tsx +4 -4
  74. package/src/lib/prototypes/prototype-state-canvas-constants.ts +1 -1
  75. package/src/lib/prototypes/prototype-state-canvas-types.ts +0 -2
  76. package/src/lib/prototypes/prototype-storage-status.ts +31 -0
  77. package/src/lib/prototypes/sort-prototypes-by-creation-date.ts +43 -0
  78. package/src/lib/prototypes/use-prototype-tool-theme.tsx +1 -1
  79. package/src/lib/prototypes/use-toolbar-hover-panel.ts +12 -1
  80. package/src/lib/prototypes/variant-set-lucide-icon.tsx +24 -0
  81. package/src/lib/tool-portal.ts +24 -0
  82. package/src/lib/use-copy-to-clipboard.ts +7 -13
  83. package/src/server/create-host-api-route.ts +7 -16
  84. package/src/server/create-prototype-api-routes.ts +0 -115
  85. package/src/server/prototype-storage-status-route.ts +29 -0
  86. package/src/server.ts +0 -8
  87. package/src/styles/globals.css +359 -71
  88. package/src/lib/prototypes/design-exploration-default-storage.ts +0 -68
  89. package/src/lib/prototypes/design-exploration-default.ts +0 -51
  90. package/src/lib/prototypes/use-design-exploration-default.ts +0 -114
  91. package/src/server/redis/prototype-design-exploration-default.ts +0 -32
@@ -1,22 +1,13 @@
1
1
  "use client";
2
2
 
3
- import {
4
- Dialog,
5
- DialogClose,
6
- DialogContent,
7
- DialogTitle,
8
- } from "@prototype/components/ui/dialog";
3
+ import { PrototypeToolDialog } from "@prototype/components/platform-ui/prototype-tool-dialog";
4
+ import { PrototypeBriefTextarea } from "@prototype/components/prototypes/prototype-brief-field";
5
+ import { Button } from "@prototype/components/ui/button";
6
+ import { Switch } from "@prototype/components/ui/switch";
9
7
  import { buildCreateDesignExplorationCopyText } from "@prototype/lib/prototypes/design-exploration-types";
10
8
  import useCopyToClipboard from "@prototype/lib/use-copy-to-clipboard";
11
- import { X } from "lucide-react";
12
9
  import { useEffect, useState } from "react";
13
10
 
14
- const MODAL_CHROME_BUTTON_CLASS =
15
- "text-muted-foreground hover:text-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-sm border-0 bg-transparent p-0 opacity-70 transition-opacity duration-200 ease hover:opacity-100 outline-none focus:outline-hidden focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-40 disabled:hover:opacity-40 disabled:hover:text-muted-foreground motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
16
-
17
- const BRIEF_TEXTAREA_CLASS =
18
- "field-sizing-content min-h-[min(50vh,20rem)] w-full resize-y border-0 bg-transparent px-0 py-0 text-sm leading-relaxed text-foreground shadow-none outline-none placeholder:text-muted-foreground focus-visible:ring-0";
19
-
20
11
  export type PrototypeCreateExplorationModalProps = {
21
12
  open: boolean;
22
13
  onOpenChange: (open: boolean) => void;
@@ -31,6 +22,7 @@ export function PrototypeCreateExplorationModal({
31
22
  existingExplorations,
32
23
  }: PrototypeCreateExplorationModalProps) {
33
24
  const [brief, setBrief] = useState("");
25
+ const [includeMobbin, setIncludeMobbin] = useState(true);
34
26
  const { copy, icon, isCopied } = useCopyToClipboard();
35
27
  const canCopy = brief.trim().length > 0;
36
28
 
@@ -51,67 +43,52 @@ export function PrototypeCreateExplorationModal({
51
43
  existingExplorations,
52
44
  origin,
53
45
  briefText: brief,
46
+ includeMobbin,
54
47
  }),
55
48
  );
56
49
  };
57
50
 
58
51
  return (
59
- <Dialog open={open} onOpenChange={onOpenChange}>
60
- <DialogContent
61
- showCloseButton={false}
62
- className="tool-dialog-surface flex max-h-[min(92svh,calc(100%-2rem))] w-[min(42rem,calc(100vw-2rem))] max-w-[min(42rem,calc(100vw-2rem))] flex-col gap-0 overflow-hidden border-0 p-0 sm:max-w-[min(42rem,calc(100vw-2rem))]"
63
- >
64
- <div className="flex items-start justify-between gap-3 px-5 py-4">
65
- <div className="flex min-w-0 flex-col gap-1">
66
- <DialogTitle className="text-base font-medium text-foreground">
67
- New exploration
68
- </DialogTitle>
69
- <p className="text-sm text-muted-foreground">
70
- Describe what you&apos;re trying to build, and we&apos;ll give you
71
- a few different versions.
72
- </p>
73
- </div>
74
- <DialogClose className={MODAL_CHROME_BUTTON_CLASS}>
75
- <X />
76
- <span className="sr-only">Close</span>
77
- </DialogClose>
78
- </div>
79
-
80
- <div
81
- className="h-px w-full shrink-0 bg-border"
82
- role="separator"
83
- aria-hidden
84
- />
85
-
86
- <div className="flex min-h-0 flex-1 flex-col overflow-y-auto px-5 py-4">
87
- <textarea
88
- value={brief}
89
- onChange={(event) => setBrief(event.target.value)}
90
- placeholder="e.g. Give me a settings page with a profile picture, name, plan, and bio"
91
- aria-label="Exploration brief"
92
- className={BRIEF_TEXTAREA_CLASS}
93
- />
94
- </div>
95
-
96
- <div
97
- className="h-px w-full shrink-0 bg-border"
98
- role="separator"
99
- aria-hidden
100
- />
101
-
102
- <div className="flex items-center justify-end gap-2 px-5 py-4">
103
- <button
52
+ <PrototypeToolDialog
53
+ open={open}
54
+ onOpenChange={onOpenChange}
55
+ title="New exploration"
56
+ description="Describe what you're trying to build, and we'll give you a few different versions."
57
+ footerClassName="justify-between gap-4"
58
+ footer={
59
+ <>
60
+ <label className="flex cursor-pointer items-center gap-2">
61
+ <Switch
62
+ checked={includeMobbin}
63
+ onCheckedChange={setIncludeMobbin}
64
+ aria-label="Gather references from Mobbin"
65
+ className="data-[state=checked]:bg-foreground"
66
+ />
67
+ <span className="text-sm text-muted-foreground">
68
+ Gather references from Mobbin
69
+ </span>
70
+ </label>
71
+ <Button
104
72
  type="button"
73
+ variant="chrome"
74
+ size="sm"
75
+ className="h-8 gap-1.5"
105
76
  disabled={!canCopy}
106
77
  onClick={handleCopy}
107
- className="inline-flex h-9 items-center gap-2 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors duration-200 ease hover:bg-primary-dark disabled:pointer-events-none disabled:opacity-50"
108
78
  aria-label="Copy exploration brief and prompt"
109
79
  >
110
- {isCopied ? "Copied" : "Copy prompt"}
80
+ {isCopied ? "Copied prompt" : "Copy prompt"}
111
81
  {icon}
112
- </button>
113
- </div>
114
- </DialogContent>
115
- </Dialog>
82
+ </Button>
83
+ </>
84
+ }
85
+ >
86
+ <PrototypeBriefTextarea
87
+ value={brief}
88
+ onChange={(event) => setBrief(event.target.value)}
89
+ placeholder="e.g. Give me a settings page with a profile picture, name, plan, and bio"
90
+ aria-label="Exploration brief"
91
+ />
92
+ </PrototypeToolDialog>
116
93
  );
117
94
  }
@@ -0,0 +1,102 @@
1
+ "use client";
2
+
3
+ import { PrototypeToolDialog } from "@prototype/components/platform-ui/prototype-tool-dialog";
4
+ import { Button } from "@prototype/components/ui/button";
5
+ import { Input } from "@prototype/components/ui/input";
6
+ import { Label } from "@prototype/components/ui/label";
7
+ import {
8
+ PROTOTYPE_BRIEF_FIELD_BORDER_CLASS,
9
+ PrototypeBriefTextarea,
10
+ } from "@prototype/components/prototypes/prototype-brief-field";
11
+ import { buildCreatePrototypeCopyText } from "@prototype/lib/prototypes/create-prototype-prompt";
12
+ import useCopyToClipboard from "@prototype/lib/use-copy-to-clipboard";
13
+ import { useEffect, useId, useState } from "react";
14
+
15
+ export type PrototypeCreatePrototypeModalProps = {
16
+ open: boolean;
17
+ onOpenChange: (open: boolean) => void;
18
+ };
19
+
20
+ export function PrototypeCreatePrototypeModal({
21
+ open,
22
+ onOpenChange,
23
+ }: PrototypeCreatePrototypeModalProps) {
24
+ const titleFieldId = useId();
25
+ const descriptionFieldId = useId();
26
+ const [title, setTitle] = useState("");
27
+ const [description, setDescription] = useState("");
28
+ const { copy, icon, isCopied } = useCopyToClipboard();
29
+ const canCopy = title.trim().length > 0 && description.trim().length > 0;
30
+
31
+ useEffect(() => {
32
+ if (!open) {
33
+ setTitle("");
34
+ setDescription("");
35
+ }
36
+ }, [open]);
37
+
38
+ const handleCopy = () => {
39
+ if (!canCopy) return;
40
+
41
+ const origin =
42
+ typeof window !== "undefined" ? window.location.origin : undefined;
43
+
44
+ copy(
45
+ buildCreatePrototypeCopyText({
46
+ title,
47
+ description,
48
+ origin,
49
+ }),
50
+ );
51
+ };
52
+
53
+ return (
54
+ <PrototypeToolDialog
55
+ open={open}
56
+ onOpenChange={onOpenChange}
57
+ title="New prototype"
58
+ description="Name the prototype and describe what you want to build, then copy the prompt into your agent to scaffold it."
59
+ bodyClassName="gap-4"
60
+ footerClassName="justify-end"
61
+ footer={
62
+ <Button
63
+ type="button"
64
+ variant="chrome"
65
+ size="sm"
66
+ className="h-8 gap-1.5"
67
+ disabled={!canCopy}
68
+ onClick={handleCopy}
69
+ aria-label="Copy prototype brief and prompt"
70
+ >
71
+ {isCopied ? "Copied prompt" : "Copy prompt"}
72
+ {icon}
73
+ </Button>
74
+ }
75
+ >
76
+ <div className="flex flex-col gap-1.5">
77
+ <Label htmlFor={titleFieldId} className="text-foreground">
78
+ Title
79
+ </Label>
80
+ <Input
81
+ id={titleFieldId}
82
+ value={title}
83
+ onChange={(event) => setTitle(event.target.value)}
84
+ placeholder="ex. Team Settings"
85
+ className={PROTOTYPE_BRIEF_FIELD_BORDER_CLASS}
86
+ />
87
+ </div>
88
+ <div className="flex min-h-0 flex-1 flex-col gap-1.5">
89
+ <Label htmlFor={descriptionFieldId} className="text-foreground">
90
+ Description
91
+ </Label>
92
+ <PrototypeBriefTextarea
93
+ id={descriptionFieldId}
94
+ value={description}
95
+ onChange={(event) => setDescription(event.target.value)}
96
+ placeholder="ex. Replicate the team settings page from the source app — members list, invite flow, and role badges."
97
+ aria-label="Prototype description"
98
+ />
99
+ </div>
100
+ </PrototypeToolDialog>
101
+ );
102
+ }
@@ -1,22 +1,12 @@
1
1
  "use client";
2
2
 
3
- import {
4
- Dialog,
5
- DialogClose,
6
- DialogContent,
7
- DialogTitle,
8
- } from "@prototype/components/ui/dialog";
3
+ import { PrototypeToolDialog } from "@prototype/components/platform-ui/prototype-tool-dialog";
4
+ import { PrototypeBriefTextarea } from "@prototype/components/prototypes/prototype-brief-field";
5
+ import { Button } from "@prototype/components/ui/button";
9
6
  import { buildCreatePreviewStateCopyText } from "@prototype/lib/prototypes/prototype-preview-state-types";
10
7
  import useCopyToClipboard from "@prototype/lib/use-copy-to-clipboard";
11
- import { X } from "lucide-react";
12
8
  import { useEffect, useState } from "react";
13
9
 
14
- const MODAL_CHROME_BUTTON_CLASS =
15
- "text-muted-foreground hover:text-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-sm border-0 bg-transparent p-0 opacity-70 transition-opacity duration-200 ease hover:opacity-100 outline-none focus:outline-hidden focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-40 disabled:hover:opacity-40 disabled:hover:text-muted-foreground motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
16
-
17
- const BRIEF_TEXTAREA_CLASS =
18
- "field-sizing-content min-h-[min(50vh,20rem)] w-full resize-y border-0 bg-transparent px-0 py-0 text-sm leading-relaxed text-foreground shadow-none outline-none placeholder:text-muted-foreground focus-visible:ring-0";
19
-
20
10
  export type PrototypeCreateStateModalProps = {
21
11
  open: boolean;
22
12
  onOpenChange: (open: boolean) => void;
@@ -56,62 +46,33 @@ export function PrototypeCreateStateModal({
56
46
  };
57
47
 
58
48
  return (
59
- <Dialog open={open} onOpenChange={onOpenChange}>
60
- <DialogContent
61
- showCloseButton={false}
62
- className="tool-dialog-surface flex max-h-[min(92svh,calc(100%-2rem))] w-[min(42rem,calc(100vw-2rem))] max-w-[min(42rem,calc(100vw-2rem))] flex-col gap-0 overflow-hidden border-0 p-0 sm:max-w-[min(42rem,calc(100vw-2rem))]"
63
- >
64
- <div className="flex items-start justify-between gap-3 px-5 py-4">
65
- <div className="flex min-w-0 flex-col gap-1">
66
- <DialogTitle className="text-base font-medium text-foreground">
67
- New state
68
- </DialogTitle>
69
- <p className="text-sm text-muted-foreground">
70
- Describe a page state to add — loading, empty, error, or any other
71
- preview mode.
72
- </p>
73
- </div>
74
- <DialogClose className={MODAL_CHROME_BUTTON_CLASS}>
75
- <X />
76
- <span className="sr-only">Close</span>
77
- </DialogClose>
78
- </div>
79
-
80
- <div
81
- className="h-px w-full shrink-0 bg-border"
82
- role="separator"
83
- aria-hidden
84
- />
85
-
86
- <div className="flex min-h-0 flex-1 flex-col overflow-y-auto px-5 py-4">
87
- <textarea
88
- value={brief}
89
- onChange={(event) => setBrief(event.target.value)}
90
- placeholder="e.g. Add an empty state when the user has no API keys yet"
91
- aria-label="State brief"
92
- className={BRIEF_TEXTAREA_CLASS}
93
- />
94
- </div>
95
-
96
- <div
97
- className="h-px w-full shrink-0 bg-border"
98
- role="separator"
99
- aria-hidden
100
- />
101
-
102
- <div className="flex items-center justify-end gap-2 px-5 py-4">
103
- <button
104
- type="button"
105
- disabled={!canCopy}
106
- onClick={handleCopy}
107
- className="inline-flex h-9 items-center gap-2 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors duration-200 ease hover:bg-primary-dark disabled:pointer-events-none disabled:opacity-50"
108
- aria-label="Copy state brief and prompt"
109
- >
110
- {isCopied ? "Copied" : "Copy prompt"}
111
- {icon}
112
- </button>
113
- </div>
114
- </DialogContent>
115
- </Dialog>
49
+ <PrototypeToolDialog
50
+ open={open}
51
+ onOpenChange={onOpenChange}
52
+ title="New state"
53
+ description="Describe a page state to add — loading, empty, error, or any other preview mode."
54
+ footerClassName="justify-end"
55
+ footer={
56
+ <Button
57
+ type="button"
58
+ variant="chrome"
59
+ size="sm"
60
+ className="h-8 gap-1.5"
61
+ disabled={!canCopy}
62
+ onClick={handleCopy}
63
+ aria-label="Copy state brief and prompt"
64
+ >
65
+ {isCopied ? "Copied prompt" : "Copy prompt"}
66
+ {icon}
67
+ </Button>
68
+ }
69
+ >
70
+ <PrototypeBriefTextarea
71
+ value={brief}
72
+ onChange={(event) => setBrief(event.target.value)}
73
+ placeholder="e.g. Add an empty state when the user has no API keys yet"
74
+ aria-label="State brief"
75
+ />
76
+ </PrototypeToolDialog>
116
77
  );
117
78
  }
@@ -42,7 +42,7 @@ export function PrototypeDefaultStateMapPage({
42
42
  <div>
43
43
  <p className={styles.headerTitle}>State map</p>
44
44
  <p className={styles.headerHint}>
45
- Map prototype preview states once this prototype defines them.
45
+ Preview states appear here once this prototype defines a state map.
46
46
  </p>
47
47
  </div>
48
48
  <Link
@@ -56,9 +56,9 @@ export function PrototypeDefaultStateMapPage({
56
56
 
57
57
  <div className="flex flex-1 items-center justify-center px-6">
58
58
  <EmptyState className="max-w-md text-center">
59
- No states mapped yet. Add a state canvas config and register this route
60
- in `prototype.config.ts`, or follow the example-feature reference in
61
- AGENTS.md.
59
+ No preview states yet. When this prototype adds a `*-preview-states.ts`
60
+ registry, wire a state map page per AGENTS.md until then this map stays
61
+ empty.
62
62
  </EmptyState>
63
63
  </div>
64
64
  </div>
@@ -8,13 +8,14 @@ import {
8
8
  DialogContent,
9
9
  DialogTitle,
10
10
  } from "@prototype/components/ui/dialog";
11
+ import { PROTOTYPE_TOOL_MODAL_CLOSE_CLASS } from "@prototype/components/platform-ui/prototype-tool-dialog";
11
12
  import useCopyToClipboard from "@prototype/lib/use-copy-to-clipboard";
12
13
  import { buildBriefOverviewCopyText } from "@prototype/lib/prototypes/design-exploration-types";
13
14
  import type {
15
+ DesignExplorationBaselineOption,
14
16
  DesignExplorationBrief,
15
17
  DesignExplorationContext,
16
18
  DesignExplorationMobbin,
17
- DesignExplorationRationale,
18
19
  DesignExplorationVariantOption,
19
20
  DesignExplorationVariantsSection,
20
21
  } from "@prototype/lib/prototypes/design-exploration-types";
@@ -22,8 +23,7 @@ import { usePersistedLocalString } from "@prototype/lib/prototypes/use-persisted
22
23
  import type { ReactNode } from "react";
23
24
  import { X } from "lucide-react";
24
25
 
25
- const MODAL_CHROME_BUTTON_CLASS =
26
- "text-muted-foreground hover:text-foreground inline-flex size-8 shrink-0 items-center justify-center rounded-sm border-0 bg-transparent p-0 opacity-70 transition-opacity hover:opacity-100 outline-none focus:outline-hidden focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-40 disabled:hover:opacity-40 disabled:hover:text-muted-foreground motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
26
+ const MODAL_CHROME_BUTTON_CLASS = PROTOTYPE_TOOL_MODAL_CLOSE_CLASS;
27
27
 
28
28
  type PrototypeDesignBriefModalProps<TVariant extends string> = {
29
29
  open: boolean;
@@ -38,10 +38,10 @@ type PrototypeDesignBriefModalProps<TVariant extends string> = {
38
38
  variant: TVariant;
39
39
  onVariantChange: (variant: TVariant) => void;
40
40
  options: DesignExplorationVariantOption<TVariant>[];
41
- rationale: Record<TVariant, DesignExplorationRationale>;
42
41
  renderers: Record<TVariant, () => ReactNode>;
42
+ baseline: DesignExplorationBaselineOption<TVariant>;
43
43
  defaultVariantValue?: TVariant;
44
- onSetDefaultVariant?: (value: TVariant) => void;
44
+ briefConfigFilePath?: string;
45
45
  };
46
46
 
47
47
  export function PrototypeDesignBriefModal<TVariant extends string>({
@@ -57,10 +57,10 @@ export function PrototypeDesignBriefModal<TVariant extends string>({
57
57
  variant,
58
58
  onVariantChange,
59
59
  options,
60
- rationale,
61
60
  renderers,
61
+ baseline,
62
62
  defaultVariantValue,
63
- onSetDefaultVariant,
63
+ briefConfigFilePath,
64
64
  }: PrototypeDesignBriefModalProps<TVariant>) {
65
65
  const { copy: copyOverview, icon: copyIcon } = useCopyToClipboard();
66
66
  const { value: title } = usePersistedLocalString(
@@ -79,9 +79,9 @@ export function PrototypeDesignBriefModal<TVariant extends string>({
79
79
  return (
80
80
  <Dialog open={open} onOpenChange={onOpenChange}>
81
81
  <DialogContent
82
+ portalScope="tool"
82
83
  className="tool-dialog-surface flex h-[min(92svh,calc(100%-2rem))] max-h-[min(92svh,calc(100%-2rem))] w-[min(96rem,calc(100vw-2rem))] max-w-[min(96rem,calc(100vw-2rem))] flex-col gap-0 overflow-hidden border-0 p-0 sm:max-w-[min(96rem,calc(100vw-2rem))]"
83
84
  >
84
- <div className="tool-dialog-accent" aria-hidden />
85
85
  <div className="absolute top-4 right-4 z-10 flex items-center gap-0.5">
86
86
  <PrototypeComponent id={`${componentIdPrefix}.overview-copy-brief`}>
87
87
  <button
@@ -116,10 +116,10 @@ export function PrototypeDesignBriefModal<TVariant extends string>({
116
116
  variant={variant}
117
117
  onVariantChange={onVariantChange}
118
118
  options={options}
119
- rationale={rationale}
120
119
  renderers={renderers}
120
+ baseline={baseline}
121
121
  defaultVariantValue={defaultVariantValue}
122
- onSetDefaultVariant={onSetDefaultVariant}
122
+ briefConfigFilePath={briefConfigFilePath}
123
123
  className="overflow-y-auto overscroll-contain"
124
124
  />
125
125
  </DialogContent>