@agent-native/core-corpus 0.201.0-nightly-20261005153421 → 0.201.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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +14 -4
- package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/analytics/CHANGELOG.md +6 -0
- package/corpus/templates/analytics/README.md +2 -2
- package/corpus/templates/analytics/changelog/2026-10-02-events-with-a-very-long-name-app-or-page-path-no-longer-caus.md +6 -0
- package/corpus/templates/analytics/package.json +1 -0
- package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +9 -19
- package/corpus/templates/analytics/server/handlers/session-replay.ts +34 -47
- package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +9 -6
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -36
- package/corpus/templates/analytics/server/lib/indexed-text.ts +53 -0
- package/corpus/templates/analytics/server/lib/request-errors.ts +73 -0
- package/corpus/templates/analytics/server/lib/session-event-index.ts +6 -16
- package/corpus/templates/analytics/server/lib/session-replay.ts +12 -2
- package/corpus/templates/analytics/server/plugins/auth.ts +2 -1
- package/corpus/templates/analytics/server/plugins/otel.ts +6 -0
- package/corpus/templates/assets/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/assets/CHANGELOG.md +7 -0
- package/corpus/templates/assets/README.md +2 -2
- package/corpus/templates/assets/package.json +1 -0
- package/corpus/templates/assets/server/plugins/auth.ts +2 -1
- package/corpus/templates/assets/server/plugins/otel.ts +6 -0
- package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +2 -1
- package/corpus/templates/brain/.agents/skills/brain/SKILL.md +5 -4
- package/corpus/templates/brain/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/brain/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/brain/CHANGELOG.md +6 -0
- package/corpus/templates/brain/README.md +12 -8
- package/corpus/templates/brain/changelog/2026-10-05-private-slack-channels-are-searchable-org-wide.md +6 -0
- package/corpus/templates/brain/package.json +1 -0
- package/corpus/templates/brain/server/lib/audiences.ts +1 -98
- package/corpus/templates/brain/server/lib/connectors.ts +2 -166
- package/corpus/templates/brain/server/plugins/otel.ts +6 -0
- package/corpus/templates/calendar/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/calendar/CHANGELOG.md +7 -0
- package/corpus/templates/calendar/README.md +2 -2
- package/corpus/templates/calendar/package.json +1 -0
- package/corpus/templates/calendar/server/plugins/auth.ts +2 -1
- package/corpus/templates/calendar/server/plugins/otel.ts +6 -0
- package/corpus/templates/chat/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/chat/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/chat/README.md +2 -2
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +9 -0
- package/corpus/templates/clips/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/clips/CHANGELOG.md +24 -0
- package/corpus/templates/clips/README.md +2 -2
- package/corpus/templates/clips/actions/lib/audio-chunk-list.ts +23 -0
- package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +187 -292
- package/corpus/templates/clips/actions/lib/chunked-transcription.ts +151 -0
- package/corpus/templates/clips/actions/lib/recording-audio-source.ts +191 -0
- package/corpus/templates/clips/actions/request-transcript.ts +81 -135
- package/corpus/templates/clips/actions/search-recordings.ts +19 -5
- package/corpus/templates/clips/app/components/clips-command-menu.tsx +5 -0
- package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -1
- package/corpus/templates/clips/app/components/library/search-bar.tsx +5 -0
- package/corpus/templates/clips/app/hooks/use-library.ts +1 -0
- package/corpus/templates/clips/app/lib/local-recording-upload.ts +13 -6
- package/corpus/templates/clips/app/lib/recording-section.ts +1 -1
- package/corpus/templates/clips/app/routes/_app.r.$recordingId.tsx +7 -5
- package/corpus/templates/clips/app/routes/record.tsx +16 -6
- package/corpus/templates/clips/changelog/2026-10-02-long-uploads-an-hour-or-more-now-transcribe-reliably-instead.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-05-confirming-discard-recording-now-returns-you-to-your-library.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-05-discarding-a-recording-now-removes-its-failed-upload-card-fr.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-05-discarding-a-recovered-recording-no-longer-warns-that-it-s-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-10-05-search-results-identify-recordings-in-trash-and-open-them-wi.md +6 -0
- package/corpus/templates/clips/package.json +1 -0
- package/corpus/templates/clips/server/lib/builder-cdn.ts +5 -0
- package/corpus/templates/clips/server/lib/builder-media-compression.ts +2 -2
- package/corpus/templates/clips/server/plugins/auth.ts +2 -1
- package/corpus/templates/clips/server/plugins/otel.ts +6 -0
- package/corpus/templates/clips/shared/transcript-failure.ts +5 -0
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +8 -2
- package/corpus/templates/content/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/content/CHANGELOG.md +41 -0
- package/corpus/templates/content/README.md +2 -2
- package/corpus/templates/content/actions/_database-navigation.ts +523 -344
- package/corpus/templates/content/actions/_database-row-mutation.ts +44 -10
- package/corpus/templates/content/actions/_database-setup-discovery.ts +9 -3
- package/corpus/templates/content/actions/_database-utils.ts +299 -271
- package/corpus/templates/content/actions/_property-utils.ts +293 -190
- package/corpus/templates/content/actions/_relation-values.ts +3 -1
- package/corpus/templates/content/actions/get-content-database.ts +1 -0
- package/corpus/templates/content/actions/query-content-database-items.ts +32 -5
- package/corpus/templates/content/actions/set-document-property.ts +17 -11
- package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +21 -6
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +127 -43
- package/corpus/templates/content/app/components/editor/DocumentEditorSkeleton.tsx +159 -50
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +12 -28
- package/corpus/templates/content/app/components/editor/PageDraftRecovery.tsx +6 -1
- package/corpus/templates/content/app/components/editor/TableHoverControls.tsx +139 -70
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +16 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +180 -75
- package/corpus/templates/content/app/components/editor/database/DatabaseViewSkeleton.tsx +76 -0
- package/corpus/templates/content/app/components/editor/database/navigation-state.ts +60 -2
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +41 -42
- package/corpus/templates/content/app/components/editor/document-editor-layout.ts +18 -0
- package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +11 -3
- package/corpus/templates/content/app/components/editor/suggestions/draft-session.ts +15 -7
- package/corpus/templates/content/app/components/editor/suggestions/model.ts +13 -0
- package/corpus/templates/content/app/components/editor/suggestions/read-only-blocks.ts +136 -0
- package/corpus/templates/content/app/components/editor/table-view.ts +73 -0
- package/corpus/templates/content/app/components/layout/ContentStartupShell.tsx +1 -1
- package/corpus/templates/content/app/components/layout/Layout.tsx +5 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +57 -16
- package/corpus/templates/content/app/components/sidebar/MovePageDialog.tsx +4 -4
- package/corpus/templates/content/app/components/sidebar/SidebarNavigationRow.tsx +34 -10
- package/corpus/templates/content/app/global.css +16 -8
- package/corpus/templates/content/app/hooks/content-action-refresh.ts +14 -13
- package/corpus/templates/content/app/hooks/use-content-database.ts +72 -9
- package/corpus/templates/content/app/hooks/use-content-personal-navigation.ts +7 -3
- package/corpus/templates/content/app/hooks/use-documents.ts +27 -0
- package/corpus/templates/content/app/i18n-data.ts +3 -2
- package/corpus/templates/content/app/lib/content-landing.ts +3 -31
- package/corpus/templates/content/app/lib/files-navigation.ts +182 -10
- package/corpus/templates/content/app/lib/files-root-hint.ts +20 -32
- package/corpus/templates/content/app/lib/page-startup-hints.ts +108 -0
- package/corpus/templates/content/app/lib/private-link-redirect.ts +25 -0
- package/corpus/templates/content/app/lib/sidebar-layout-hint.ts +34 -1
- package/corpus/templates/content/app/lib/startup-timing.ts +2 -0
- package/corpus/templates/content/app/root.tsx +3 -1
- package/corpus/templates/content/app/routes/_app.home.tsx +10 -19
- package/corpus/templates/content/app/routes/p.$id.tsx +23 -5
- package/corpus/templates/content/changelog/2026-10-02-a-page-link-you-cant-open-now-says-so-instead-of-opening-an.md +6 -0
- package/corpus/templates/content/changelog/2026-10-02-after-a-refresh-the-files-sidebar-shows-the-open-page-s-fold.md +6 -0
- package/corpus/templates/content/changelog/2026-10-02-large-collections-open-faster.md +6 -0
- package/corpus/templates/content/changelog/2026-10-02-pages-stay-inside-the-window-at-every-width-long-inline-code.md +6 -0
- package/corpus/templates/content/changelog/2026-10-02-pages-with-open-comments-and-collections-with-sorted-or-filt.md +6 -0
- package/corpus/templates/content/changelog/2026-10-02-suggest-edits-works-on-pages-written-by-agents-including-pag.md +6 -0
- package/corpus/templates/content/changelog/2026-10-02-while-you-suggest-edits-tables-and-other-blocks-that-suggest.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-collection-view-context-now-survives-quick-page-changes-when.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-collection-views-keep-their-saved-rows-accurate-during-refre.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-exact-saved-view-links-keep-collection-retry-available.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-expanding-a-files-folder-now-shares-one-navigation-read-acro.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-files-navigation-retries-temporary-failures-consistently.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-shared-page-owners-keep-edit-and-manage-controls-in-files-an.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-tagging-an-ai-in-a-comment-works-again-instead-of-failing-ri.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-the-home-loading-shell-keeps-the-layout-of-your-last-opened-.md +6 -0
- package/corpus/templates/content/changelog/2026-10-05-typing-and-a-space-or-inserting-a-toggle-or-callout-no-longe.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.workspace.session-restore.md +4 -1
- package/corpus/templates/content/e2e/playwright.config.ts +1 -1
- package/corpus/templates/content/package.json +2 -1
- package/corpus/templates/content/scripts/seed-perf-database.mjs +600 -0
- package/corpus/templates/content/scripts/trace-startup.mjs +25 -3
- package/corpus/templates/content/server/db/index.ts +1 -1
- package/corpus/templates/content/server/lib/suggested-edits.ts +23 -26
- package/corpus/templates/content/server/plugins/auth.ts +2 -1
- package/corpus/templates/content/server/plugins/otel.ts +6 -0
- package/corpus/templates/content/shared/api.ts +17 -0
- package/corpus/templates/content/shared/suggestion-diff.ts +124 -38
- package/corpus/templates/content/shared/suggestion-formatting.ts +134 -3
- package/corpus/templates/crm/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/crm/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/crm/package.json +1 -0
- package/corpus/templates/crm/server/plugins/otel.ts +6 -0
- package/corpus/templates/design/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/design/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/design/CHANGELOG.md +41 -0
- package/corpus/templates/design/README.md +2 -2
- package/corpus/templates/design/actions/list-designs.ts +11 -4
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +110 -32
- package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +28 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +1 -0
- package/corpus/templates/design/app/components/home/DesignHomeLibrary.tsx +79 -0
- package/corpus/templates/design/app/components/layout/Header.tsx +2 -4
- package/corpus/templates/design/app/components/ui/tabs.tsx +59 -1
- package/corpus/templates/design/app/global.css +1 -34
- package/corpus/templates/design/app/i18n/en-US.ts +4 -0
- package/corpus/templates/design/app/lib/design-filter.ts +4 -2
- package/corpus/templates/design/app/pages/Index.tsx +91 -59
- package/corpus/templates/design/app/pages/design-editor/commands/cross-screen-element-drop.ts +58 -17
- package/corpus/templates/design/changelog/2026-10-01-filter-designs-by-owner.md +6 -0
- package/corpus/templates/design/changelog/2026-10-03-layers-dropped-into-visible-canvas-space-beyond-a-screen-now.md +6 -0
- package/corpus/templates/design/changelog/2026-10-03-visible-screen-overflow-no-longer-routes-drops-to-the-canvas.md +6 -0
- package/corpus/templates/design/changelog/2026-10-05-the-recent-tab-shows-loading-placeholders-until-your-designs.md +6 -0
- package/corpus/templates/design/package.json +1 -0
- package/corpus/templates/design/server/plugins/auth.ts +2 -1
- package/corpus/templates/design/server/plugins/otel.ts +6 -0
- package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/dispatch/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/dispatch/README.md +2 -2
- package/corpus/templates/dispatch/package.json +1 -0
- package/corpus/templates/dispatch/server/plugins/otel.ts +6 -0
- package/corpus/templates/dispatch/server/plugins/setup-dispatch.ts +2 -1
- package/corpus/templates/factory/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/factory/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/factory/package.json +1 -0
- package/corpus/templates/factory/server/plugins/otel.ts +6 -0
- package/corpus/templates/forms/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/forms/README.md +2 -2
- package/corpus/templates/forms/package.json +1 -0
- package/corpus/templates/forms/server/plugins/auth.ts +2 -1
- package/corpus/templates/forms/server/plugins/otel.ts +6 -0
- package/corpus/templates/mail/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/mail/CHANGELOG.md +6 -0
- package/corpus/templates/mail/README.md +2 -2
- package/corpus/templates/mail/package.json +1 -0
- package/corpus/templates/mail/server/plugins/auth.ts +2 -1
- package/corpus/templates/mail/server/plugins/otel.ts +6 -0
- package/corpus/templates/plan/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/plan/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/plan/CHANGELOG.md +1 -0
- package/corpus/templates/plan/README.md +2 -2
- package/corpus/templates/plan/package.json +1 -0
- package/corpus/templates/plan/server/plugins/auth.ts +2 -1
- package/corpus/templates/plan/server/plugins/otel.ts +6 -0
- package/corpus/templates/slides/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/slides/.agents/skills/storing-data/SKILL.md +12 -7
- package/corpus/templates/slides/CHANGELOG.md +23 -0
- package/corpus/templates/slides/README.md +2 -2
- package/corpus/templates/slides/actions/list-decks.ts +11 -4
- package/corpus/templates/slides/app/components/deck/DeckFilterMenu.tsx +44 -36
- package/corpus/templates/slides/app/components/home/SlidesHomeLibrary.tsx +79 -0
- package/corpus/templates/slides/app/components/layout/Header.tsx +2 -15
- package/corpus/templates/slides/app/components/ui/tabs.tsx +59 -0
- package/corpus/templates/slides/app/global.css +3 -54
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/lib/deck-filter.ts +5 -2
- package/corpus/templates/slides/app/pages/Index.tsx +102 -88
- package/corpus/templates/slides/changelog/2026-10-01-filter-decks-by-owner.md +6 -0
- package/corpus/templates/slides/changelog/2026-10-02-hide-recent-until-decks-available.md +6 -0
- package/corpus/templates/slides/changelog/2026-10-05-the-recent-tab-shows-loading-placeholders-until-your-decks-a.md +6 -0
- package/corpus/templates/slides/package.json +1 -0
- package/corpus/templates/slides/server/handlers/request-auth-context.ts +8 -0
- package/corpus/templates/slides/server/plugins/auth.ts +2 -1
- package/corpus/templates/slides/server/plugins/otel.ts +6 -0
- package/corpus/templates/tasks/.agents/skills/security/SKILL.md +9 -2
- package/corpus/templates/tasks/.agents/skills/storing-data/SKILL.md +12 -7
- package/package.json +1 -1
|
@@ -75,10 +75,11 @@ state their PostgreSQL types directly.
|
|
|
75
75
|
|
|
76
76
|
Member offboarding and email changes refuse to run while any column named
|
|
77
77
|
`email`, `*_email`, `*scope_id`, `created_by`, `updated_by`, `invited_by`,
|
|
78
|
-
`owner`, `principal_id`, `session_id`, or `user_id` has no policy.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
`owner`, `principal_id`, `session_id`, or `user_id` has no policy.
|
|
79
|
+
`createSharesTable()` tables are handled for you, and undeclared `owner_email`
|
|
80
|
+
columns transfer to the successor, which is right only for owned content.
|
|
81
|
+
Declare every other one, including columns that are not member identities, from
|
|
82
|
+
the app's database plugin graph (Clips does it in `server/db/index.ts`):
|
|
82
83
|
|
|
83
84
|
```ts
|
|
84
85
|
import { registerIdentityColumns } from "@agent-native/core/org";
|
|
@@ -88,13 +89,17 @@ registerIdentityColumns([
|
|
|
88
89
|
{ table: "space_members", column: "email", emailChange: "rekey", offboard: "delete", orgScope: { column: "space_id", references: { table: "spaces", column: "id", orgColumn: "org_id" } }, reason: "Space membership grants access." },
|
|
89
90
|
// Someone else's address: never rewritten.
|
|
90
91
|
{ table: "meeting_participants", column: "email", emailChange: "retain", offboard: "retain", reason: "Attendee address from the calendar provider." },
|
|
92
|
+
// A credential in an owner_email table: never handed to the successor.
|
|
93
|
+
{ table: "api_keys", column: "owner_email", emailChange: "rekey", offboard: "revoke", reason: "Bearer keys act as their owner." },
|
|
91
94
|
]);
|
|
92
95
|
```
|
|
93
96
|
|
|
94
|
-
Choose `delete` for grants, credentials, and pending tokens
|
|
97
|
+
Choose `delete` for grants, credentials, and pending tokens, or `revoke` (sets
|
|
98
|
+
`revoked_at`) when a reader treats a missing row as "not revoked"; `retain` for
|
|
95
99
|
attribution, history, and third-party addresses; `transfer` only for owned
|
|
96
|
-
data.
|
|
97
|
-
|
|
100
|
+
data. Declare `owner_email` tables that hold credentials or grants, or
|
|
101
|
+
offboarding hands them to the successor. A table without `org_id` needs
|
|
102
|
+
`orgScope` or an organization-scoped removal leaves its rows alone.
|
|
98
103
|
|
|
99
104
|
| Template | Tables |
|
|
100
105
|
| ------------ | --------------------------------------------- |
|
|
@@ -3,17 +3,58 @@
|
|
|
3
3
|
All notable user-facing changes to Design are documented here. Open it any time
|
|
4
4
|
from the command menu (Cmd+K → "What's new") or from Settings.
|
|
5
5
|
|
|
6
|
+
## 2026-10-05
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- The Recent tab shows loading placeholders until your designs are ready.
|
|
11
|
+
|
|
12
|
+
## 2026-10-03
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Alt-drag can increase an oversized corner radius even when CSS did not normalize the radius map.
|
|
17
|
+
- Corner-radius handles resize oversized radii without jumping
|
|
18
|
+
- Cross-screen drops skip flex targets whose axis or item placement cannot be modeled.
|
|
19
|
+
- Layers dropped into visible canvas space beyond a Screen now stay on the board.
|
|
20
|
+
- Reopening a Visual Edit connection keeps screens in its saved project
|
|
21
|
+
- Visible Screen overflow no longer routes drops to the canvas
|
|
22
|
+
|
|
6
23
|
## 2026-10-02
|
|
7
24
|
|
|
25
|
+
### Improved
|
|
26
|
+
|
|
27
|
+
- Builder.io setup now routes account activation through the one-click flow.
|
|
28
|
+
|
|
8
29
|
### Fixed
|
|
9
30
|
|
|
31
|
+
- Cross-screen auto-layout drops avoid guessing when direction comes from stylesheet rules
|
|
32
|
+
- Cross-Screen grid drops preserve the selected cell and the layer's track span
|
|
33
|
+
- Design drops now keep the chosen grid cell and follow reverse flex order when falling back to a fitting container
|
|
34
|
+
- Editing a design source file now refreshes collaborators with that design open.
|
|
35
|
+
- Grid drops avoid cells occupied by generated content
|
|
36
|
+
- Grid drops avoid mis-targeting cells in scrolled grids
|
|
37
|
+
- Layers that exceed a frame's width or height now fall back to the nearest container that fits
|
|
38
|
+
- Oversized drops target the nearest container that can fit the dragged layer.
|
|
39
|
+
- Oversized layers can now drop into a fitting ancestor when a nested frame is too small
|
|
40
|
+
- Reverse auto-layout drops keep their visual and layer order aligned.
|
|
41
|
+
- Drag-and-drop placement follows item size, spacing, and visible order in reversed layouts.
|
|
10
42
|
- Cross-screen drag targets no longer jump when an earlier screen sends a late move.
|
|
11
43
|
- Cross-screen drags continue when focus moves between screens
|
|
12
44
|
|
|
13
45
|
## 2026-10-01
|
|
14
46
|
|
|
47
|
+
### Improved
|
|
48
|
+
|
|
49
|
+
- Collaborators on the same screen now appear in the avatar bar in overview.
|
|
50
|
+
- The Design home opens on Recent when designs are available, hides the empty Recent tab, and distinguishes designs you own from those shared with you.
|
|
51
|
+
|
|
15
52
|
### Fixed
|
|
16
53
|
|
|
54
|
+
- Edits from collaborators now show up in an open design without a refresh, including frame moves and added or deleted screens.
|
|
55
|
+
- PNG and PDF exports now preserve fonts, images, effects, and page framing in imported screens.
|
|
56
|
+
- Two people editing different parts of the same screen no longer lose edits, and one person's undo no longer reverts the other's changes.
|
|
57
|
+
- Viewers on a shared design now see an editor's changes within a few seconds instead of minutes.
|
|
17
58
|
- A prompt you send before connecting AI is sent automatically once you connect.
|
|
18
59
|
- Cross-Screen drags now apply modifier keys reliably when the source screen loses focus.
|
|
19
60
|
- Cross-screen drops now respect modifier keys at release.
|
|
@@ -4,7 +4,7 @@ An agent-native HTML prototyping studio — describe a screen and get a working
|
|
|
4
4
|
Alpine/Tailwind prototype you can refine, tweak, and export. An open-source,
|
|
5
5
|
self-hostable alternative to v0 and Lovable-style prototyping tools.
|
|
6
6
|
|
|
7
|
-
**Live app: [design.agent-native.com](https://design.agent-native.com)**
|
|
7
|
+
**Live app: [design.agent-native.com](https://design.agent-native.com?utm_source=github&utm_medium=referral&utm_content=design-readme)**
|
|
8
8
|
|
|
9
9
|
Instead of a layered drawing canvas, the agent generates complete self-contained
|
|
10
10
|
HTML prototypes, renders them in an iframe, and lets you refine the result with
|
|
@@ -31,4 +31,4 @@ pnpm install
|
|
|
31
31
|
pnpm dev
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
Full docs: [agent-native.com/docs/template-design](https://agent-native.com/docs/template-design).
|
|
34
|
+
Full docs: [agent-native.com/docs/template-design](https://agent-native.com/docs/template-design?utm_source=github&utm_medium=referral&utm_content=design-readme).
|
|
@@ -45,9 +45,11 @@ export default defineAction({
|
|
|
45
45
|
"Set to true only for a lightweight UI picker; it returns the first bounded picker page and hasMore when more exist.",
|
|
46
46
|
),
|
|
47
47
|
createdBy: z
|
|
48
|
-
.enum(["all", "me"])
|
|
48
|
+
.enum(["all", "me", "not-me"])
|
|
49
49
|
.optional()
|
|
50
|
-
.describe(
|
|
50
|
+
.describe(
|
|
51
|
+
"Set to 'me' or 'not-me' to filter by whether the current user owns each design",
|
|
52
|
+
),
|
|
51
53
|
search: z
|
|
52
54
|
.string()
|
|
53
55
|
.trim()
|
|
@@ -82,7 +84,10 @@ export default defineAction({
|
|
|
82
84
|
? DESIGN_LIST_MAX_PAGE_SIZE
|
|
83
85
|
: (args.pageSize ?? DESIGN_LIST_DEFAULT_PAGE_SIZE);
|
|
84
86
|
const ownerEmail = getRequestUserEmail()?.trim().toLowerCase() || null;
|
|
85
|
-
if (
|
|
87
|
+
if (
|
|
88
|
+
(args.createdBy === "me" || args.createdBy === "not-me") &&
|
|
89
|
+
!ownerEmail
|
|
90
|
+
) {
|
|
86
91
|
return {
|
|
87
92
|
count: 0,
|
|
88
93
|
totalCount: 0,
|
|
@@ -100,7 +105,9 @@ export default defineAction({
|
|
|
100
105
|
accessFilter(schema.designs, schema.designShares),
|
|
101
106
|
args.createdBy === "me"
|
|
102
107
|
? sql`lower(trim(${schema.designs.ownerEmail})) = ${ownerEmail}`
|
|
103
|
-
:
|
|
108
|
+
: args.createdBy === "not-me"
|
|
109
|
+
? sql`lower(trim(${schema.designs.ownerEmail})) <> ${ownerEmail}`
|
|
110
|
+
: undefined,
|
|
104
111
|
search
|
|
105
112
|
? sql`lower(${schema.designs.title}) LIKE ${`%${escapeLike(search)}%`} ESCAPE '\\'`
|
|
106
113
|
: undefined,
|
|
@@ -379,6 +379,8 @@ import {
|
|
|
379
379
|
} from "./multi-screen/coordinate-transforms";
|
|
380
380
|
import {
|
|
381
381
|
captureCrossScreenSourceHtmlSnapshot,
|
|
382
|
+
getBoardDropRoute,
|
|
383
|
+
getCrossScreenSourceGeometry,
|
|
382
384
|
getCrossScreenDropGuideForHitTest,
|
|
383
385
|
getCrossScreenDropGuideStyle,
|
|
384
386
|
getCrossScreenGhostStyle,
|
|
@@ -2771,6 +2773,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
2771
2773
|
timeoutMs?: number;
|
|
2772
2774
|
previewGeneration?: number;
|
|
2773
2775
|
previewRequestSeq?: number;
|
|
2776
|
+
sourceScreenId?: string;
|
|
2774
2777
|
sourceElementSize?: { width: number; height: number };
|
|
2775
2778
|
sourceGridSpan?: { columns: number; rows: number };
|
|
2776
2779
|
modifiers?: {
|
|
@@ -2786,7 +2789,23 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
2786
2789
|
);
|
|
2787
2790
|
const targetIsBoard = candidate.id === boardFileId;
|
|
2788
2791
|
if (!targetScreen && !targetIsBoard) return Promise.resolve({});
|
|
2789
|
-
if (
|
|
2792
|
+
if (
|
|
2793
|
+
targetIsBoard &&
|
|
2794
|
+
getBoardDropRoute({
|
|
2795
|
+
point: boardPoint,
|
|
2796
|
+
viewportGeometry: boardViewportGeometry,
|
|
2797
|
+
renderGeometry: boardSurfaceRenderGeometry,
|
|
2798
|
+
sourceScreenGeometry:
|
|
2799
|
+
options.sourceScreenId && options.sourceScreenId !== boardFileId
|
|
2800
|
+
? getCrossScreenSourceGeometry({
|
|
2801
|
+
renderedGeometry:
|
|
2802
|
+
renderedFrameGeometryRef.current[options.sourceScreenId],
|
|
2803
|
+
persistedGeometry:
|
|
2804
|
+
frameGeometryRef.current[options.sourceScreenId],
|
|
2805
|
+
})
|
|
2806
|
+
: undefined,
|
|
2807
|
+
}) !== "board-hit-test"
|
|
2808
|
+
) {
|
|
2790
2809
|
return Promise.resolve({});
|
|
2791
2810
|
}
|
|
2792
2811
|
const targetIframe = targetIsBoard
|
|
@@ -2967,6 +2986,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
2967
2986
|
preview: true,
|
|
2968
2987
|
previewGeneration,
|
|
2969
2988
|
previewRequestSeq: requestSeq,
|
|
2989
|
+
sourceScreenId: crossScreenDragMsgRef.current?.sourceScreenId,
|
|
2970
2990
|
sourceElementSize: crossScreenDragMsgRef.current?.sourceElementSize,
|
|
2971
2991
|
sourceGridSpan: crossScreenDragMsgRef.current?.sourceGridSpan,
|
|
2972
2992
|
modifiers: crossScreenDragMsgRef.current?.modifiers,
|
|
@@ -3155,6 +3175,26 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
3155
3175
|
const target = getFrameEntryAtPoint(boardPoint, {
|
|
3156
3176
|
excludeId: sourceScreenId,
|
|
3157
3177
|
});
|
|
3178
|
+
const boardDropRoute =
|
|
3179
|
+
(sourceScreenId !== boardFileId ||
|
|
3180
|
+
crossScreenDragMsgRef.current?.duplicate === true) &&
|
|
3181
|
+
boardFileId &&
|
|
3182
|
+
boardFrameGeometry
|
|
3183
|
+
? getBoardDropRoute({
|
|
3184
|
+
point: boardPoint,
|
|
3185
|
+
viewportGeometry: boardViewportGeometry,
|
|
3186
|
+
renderGeometry: boardSurfaceRenderGeometry,
|
|
3187
|
+
sourceScreenGeometry:
|
|
3188
|
+
sourceScreenId === boardFileId
|
|
3189
|
+
? undefined
|
|
3190
|
+
: getCrossScreenSourceGeometry({
|
|
3191
|
+
renderedGeometry:
|
|
3192
|
+
renderedFrameGeometryRef.current[sourceScreenId],
|
|
3193
|
+
persistedGeometry:
|
|
3194
|
+
frameGeometryRef.current[sourceScreenId],
|
|
3195
|
+
}),
|
|
3196
|
+
})
|
|
3197
|
+
: null;
|
|
3158
3198
|
traceOnce(
|
|
3159
3199
|
crossScreenResolveTraceRef,
|
|
3160
3200
|
"drop",
|
|
@@ -3190,8 +3230,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
3190
3230
|
crossScreenDragMsgRef.current?.duplicate === true) &&
|
|
3191
3231
|
boardFileId &&
|
|
3192
3232
|
boardFrameGeometry &&
|
|
3193
|
-
|
|
3194
|
-
geometryContainsPoint(boardSurfaceRenderGeometry, boardPoint)
|
|
3233
|
+
boardDropRoute
|
|
3195
3234
|
) {
|
|
3196
3235
|
const nextTarget = { id: boardFileId, geometry: boardFrameGeometry };
|
|
3197
3236
|
if (crossScreenTargetRef.current?.id !== boardFileId) {
|
|
@@ -3314,42 +3353,59 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
3314
3353
|
clearCurrentDrop();
|
|
3315
3354
|
return;
|
|
3316
3355
|
}
|
|
3317
|
-
const sourceFrameGeometry =
|
|
3318
|
-
|
|
3319
|
-
|
|
3356
|
+
const sourceFrameGeometry = getCrossScreenSourceGeometry({
|
|
3357
|
+
renderedGeometry: renderedFrameGeometryRef.current[sourceScreenId],
|
|
3358
|
+
persistedGeometry: frameGeometryRef.current[sourceScreenId],
|
|
3359
|
+
});
|
|
3360
|
+
const boardDropRoute =
|
|
3361
|
+
boardFileId &&
|
|
3320
3362
|
(sourceScreenId !== boardFileId || payload.duplicate) &&
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3363
|
+
boardFrameGeometry
|
|
3364
|
+
? getBoardDropRoute({
|
|
3365
|
+
point: lastBoardPoint,
|
|
3366
|
+
viewportGeometry: boardViewportGeometry,
|
|
3367
|
+
renderGeometry: boardSurfaceRenderGeometry,
|
|
3368
|
+
sourceScreenGeometry:
|
|
3369
|
+
sourceScreenId === boardFileId
|
|
3370
|
+
? undefined
|
|
3371
|
+
: getCrossScreenSourceGeometry({
|
|
3372
|
+
renderedGeometry:
|
|
3373
|
+
renderedFrameGeometryRef.current[sourceScreenId],
|
|
3374
|
+
persistedGeometry:
|
|
3375
|
+
frameGeometryRef.current[sourceScreenId],
|
|
3376
|
+
}),
|
|
3377
|
+
})
|
|
3378
|
+
: null;
|
|
3379
|
+
const boardCanvasHit = boardDropRoute !== null;
|
|
3324
3380
|
const sameBoardDuplicateHit =
|
|
3325
|
-
sourceScreenId === boardFileId && payload.duplicate &&
|
|
3381
|
+
sourceScreenId === boardFileId && payload.duplicate && boardCanvasHit;
|
|
3382
|
+
const resolvedCandidate =
|
|
3383
|
+
candidate?.id === boardFileId && !boardCanvasHit ? null : candidate;
|
|
3326
3384
|
const droppedInsideSourceScreen =
|
|
3327
|
-
!
|
|
3385
|
+
!resolvedCandidate &&
|
|
3328
3386
|
!sameBoardDuplicateHit &&
|
|
3329
3387
|
!!sourceFrameGeometry &&
|
|
3330
|
-
|
|
3331
|
-
lastBoardPoint.x <= sourceFrameGeometry.x + sourceFrameGeometry.width &&
|
|
3332
|
-
lastBoardPoint.y >= sourceFrameGeometry.y &&
|
|
3333
|
-
lastBoardPoint.y <= sourceFrameGeometry.y + sourceFrameGeometry.height;
|
|
3334
|
-
if (droppedInsideSourceScreen) {
|
|
3335
|
-
cancelPendingSourceDelete();
|
|
3336
|
-
finishCommittedDrop();
|
|
3337
|
-
clearCurrentDrop();
|
|
3338
|
-
return;
|
|
3339
|
-
}
|
|
3388
|
+
geometryContainsPoint(sourceFrameGeometry, lastBoardPoint);
|
|
3340
3389
|
trace("drop", "finalize", {
|
|
3341
|
-
candidate:
|
|
3390
|
+
candidate: resolvedCandidate?.id ?? null,
|
|
3342
3391
|
sourceScreen: sourceScreenId,
|
|
3392
|
+
boardDropRoute,
|
|
3343
3393
|
droppedInsideSourceScreen,
|
|
3344
3394
|
outcome: droppedInsideSourceScreen
|
|
3345
3395
|
? "discarded — pointer never left the source screen"
|
|
3346
|
-
:
|
|
3396
|
+
: resolvedCandidate
|
|
3347
3397
|
? "moving into candidate"
|
|
3348
3398
|
: "no candidate — refused unless over the board surface",
|
|
3349
3399
|
});
|
|
3400
|
+
if (droppedInsideSourceScreen) {
|
|
3401
|
+
cancelPendingSourceDelete();
|
|
3402
|
+
finishCommittedDrop();
|
|
3403
|
+
clearCurrentDrop();
|
|
3404
|
+
return;
|
|
3405
|
+
}
|
|
3350
3406
|
const targetCandidate =
|
|
3351
|
-
|
|
3352
|
-
(
|
|
3407
|
+
resolvedCandidate ??
|
|
3408
|
+
(boardCanvasHit && boardFileId && boardFrameGeometry
|
|
3353
3409
|
? { id: boardFileId, geometry: boardFrameGeometry }
|
|
3354
3410
|
: null);
|
|
3355
3411
|
if (!targetCandidate) {
|
|
@@ -3377,6 +3433,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
3377
3433
|
if (targetCandidate.id === boardFileId) {
|
|
3378
3434
|
void runHitTest(targetCandidate, lastBoardPoint, {
|
|
3379
3435
|
timeoutMs: HIT_TEST_COMMIT_TIMEOUT_MS,
|
|
3436
|
+
sourceScreenId,
|
|
3380
3437
|
sourceElementSize: payload.sourceElementSize,
|
|
3381
3438
|
sourceGridSpan: payload.sourceGridSpan,
|
|
3382
3439
|
modifiers: payload.modifiers,
|
|
@@ -3403,8 +3460,33 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
3403
3460
|
const hasAnchor = Boolean(
|
|
3404
3461
|
anchorNodeId || pendingNodeId || anchorSelector,
|
|
3405
3462
|
);
|
|
3463
|
+
const targetLocalPoint = boardSurfaceRenderGeometry
|
|
3464
|
+
? boardPointToBoardSurfaceLocalPoint(
|
|
3465
|
+
lastBoardPoint,
|
|
3466
|
+
boardSurfaceRenderGeometry,
|
|
3467
|
+
)
|
|
3468
|
+
: lastBoardPoint;
|
|
3469
|
+
const targetOutsideBoardRenderGeometry =
|
|
3470
|
+
boardSurfaceRenderGeometry !== undefined &&
|
|
3471
|
+
!geometryContainsPoint(
|
|
3472
|
+
boardSurfaceRenderGeometry,
|
|
3473
|
+
lastBoardPoint,
|
|
3474
|
+
);
|
|
3406
3475
|
const transactionBeforeDrop =
|
|
3407
3476
|
runtimeStructurePendingTransactionRef?.current ?? null;
|
|
3477
|
+
trace("drop", "board-commit-point", {
|
|
3478
|
+
targetCanvasPoint: lastBoardPoint,
|
|
3479
|
+
targetLocalPoint,
|
|
3480
|
+
targetOutsideBoardRenderGeometry,
|
|
3481
|
+
boardSurfaceRenderOrigin: boardSurfaceRenderGeometry
|
|
3482
|
+
? {
|
|
3483
|
+
x: boardSurfaceRenderGeometry.x,
|
|
3484
|
+
y: boardSurfaceRenderGeometry.y,
|
|
3485
|
+
}
|
|
3486
|
+
: null,
|
|
3487
|
+
sourcePointerOffset: payload.sourcePointerOffset ?? null,
|
|
3488
|
+
hasAnchor,
|
|
3489
|
+
});
|
|
3408
3490
|
onCrossScreenElementDropRef.current?.({
|
|
3409
3491
|
sourceSelector: payload.selector,
|
|
3410
3492
|
sourceNodeId: payload.sourceId,
|
|
@@ -3421,13 +3503,8 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
3421
3503
|
targetGridPlacement: gridPlacement,
|
|
3422
3504
|
targetAnchorRect: anchorRect,
|
|
3423
3505
|
targetCanvasPoint: lastBoardPoint,
|
|
3424
|
-
targetLocalPoint
|
|
3425
|
-
|
|
3426
|
-
? boardPointToBoardSurfaceLocalPoint(
|
|
3427
|
-
lastBoardPoint,
|
|
3428
|
-
boardSurfaceRenderGeometry,
|
|
3429
|
-
)
|
|
3430
|
-
: lastBoardPoint,
|
|
3506
|
+
targetLocalPoint,
|
|
3507
|
+
targetOutsideBoardRenderGeometry,
|
|
3431
3508
|
sourcePointerOffset: payload.sourcePointerOffset,
|
|
3432
3509
|
sourceComputedSize: payload.sourceComputedSize,
|
|
3433
3510
|
sourceHtmlSnapshot: payload.sourceHtmlSnapshot,
|
|
@@ -4362,6 +4439,7 @@ export const MultiScreenCanvas = memo(function MultiScreenCanvas({
|
|
|
4362
4439
|
activeId,
|
|
4363
4440
|
boardFileId,
|
|
4364
4441
|
boardFrameGeometry,
|
|
4442
|
+
boardViewportGeometry,
|
|
4365
4443
|
boardSurfaceRenderGeometry,
|
|
4366
4444
|
finishBoardCrossScreenDrop,
|
|
4367
4445
|
getFrameEntryAtPoint,
|
|
@@ -2,6 +2,7 @@ import type { CSSProperties } from "react";
|
|
|
2
2
|
|
|
3
3
|
import type { PortableStyleSnapshot } from "../types";
|
|
4
4
|
import { screenLocalRectToBoardGeometry } from "./coordinate-transforms";
|
|
5
|
+
import { geometryContainsPoint } from "./frame-geometry";
|
|
5
6
|
import { SURFACE_PADDING } from "./overview-layout";
|
|
6
7
|
import type {
|
|
7
8
|
CrossScreenDropAxis,
|
|
@@ -14,6 +15,33 @@ import type {
|
|
|
14
15
|
Point,
|
|
15
16
|
} from "./types";
|
|
16
17
|
|
|
18
|
+
export function getCrossScreenSourceGeometry(args: {
|
|
19
|
+
renderedGeometry?: FrameGeometry;
|
|
20
|
+
persistedGeometry?: FrameGeometry;
|
|
21
|
+
}): FrameGeometry | undefined {
|
|
22
|
+
return args.renderedGeometry ?? args.persistedGeometry;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getBoardDropRoute(args: {
|
|
26
|
+
point: Point;
|
|
27
|
+
viewportGeometry?: FrameGeometry;
|
|
28
|
+
renderGeometry?: FrameGeometry;
|
|
29
|
+
sourceScreenGeometry?: FrameGeometry;
|
|
30
|
+
}): "board-hit-test" | "board-root" | null {
|
|
31
|
+
const { point, viewportGeometry, renderGeometry, sourceScreenGeometry } =
|
|
32
|
+
args;
|
|
33
|
+
if (
|
|
34
|
+
!viewportGeometry ||
|
|
35
|
+
!geometryContainsPoint(viewportGeometry, point) ||
|
|
36
|
+
(sourceScreenGeometry && geometryContainsPoint(sourceScreenGeometry, point))
|
|
37
|
+
) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return renderGeometry && geometryContainsPoint(renderGeometry, point)
|
|
41
|
+
? "board-hit-test"
|
|
42
|
+
: "board-root";
|
|
43
|
+
}
|
|
44
|
+
|
|
17
45
|
export function isPointerInsideSourceIframe(args: {
|
|
18
46
|
iframeX: number;
|
|
19
47
|
iframeY: number;
|
|
@@ -345,6 +345,7 @@ export interface MultiScreenCanvasProps {
|
|
|
345
345
|
targetAnchorRect?: CrossScreenHitTestAnchorRect;
|
|
346
346
|
targetCanvasPoint?: Point;
|
|
347
347
|
targetLocalPoint?: Point;
|
|
348
|
+
targetOutsideBoardRenderGeometry?: boolean;
|
|
348
349
|
sourcePointerOffset?: Point;
|
|
349
350
|
sourceComputedSize?: { width?: number; height?: number };
|
|
350
351
|
sourceHtmlSnapshot?: string;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
4
|
+
|
|
5
|
+
export type DesignHomeLibraryTab = "templates" | "recent";
|
|
6
|
+
|
|
7
|
+
interface DesignHomeLibraryProps {
|
|
8
|
+
value: DesignHomeLibraryTab;
|
|
9
|
+
onValueChange: (value: DesignHomeLibraryTab) => void;
|
|
10
|
+
labels: { templates: string; recent: string };
|
|
11
|
+
browseAll?: ReactNode;
|
|
12
|
+
search?: ReactNode;
|
|
13
|
+
recentActions?: ReactNode;
|
|
14
|
+
templates: ReactNode;
|
|
15
|
+
recent?: ReactNode;
|
|
16
|
+
recentVisible: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function DesignHomeLibrary({
|
|
20
|
+
value,
|
|
21
|
+
onValueChange,
|
|
22
|
+
labels,
|
|
23
|
+
browseAll,
|
|
24
|
+
search,
|
|
25
|
+
recentActions,
|
|
26
|
+
templates,
|
|
27
|
+
recent,
|
|
28
|
+
recentVisible,
|
|
29
|
+
}: DesignHomeLibraryProps) {
|
|
30
|
+
const activeValue = recentVisible ? value : "templates";
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<section
|
|
34
|
+
className="agent-prompt-home-library"
|
|
35
|
+
aria-label={labels.templates}
|
|
36
|
+
>
|
|
37
|
+
<Tabs
|
|
38
|
+
className="agent-prompt-home-tabs"
|
|
39
|
+
value={activeValue}
|
|
40
|
+
onValueChange={(nextValue) => {
|
|
41
|
+
if (nextValue === "templates" || nextValue === "recent") {
|
|
42
|
+
onValueChange(nextValue);
|
|
43
|
+
}
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<div className="flex flex-wrap items-center justify-between gap-3">
|
|
47
|
+
<TabsList variant="line">
|
|
48
|
+
{recentVisible ? (
|
|
49
|
+
<TabsTrigger value="recent" className="flex-none">
|
|
50
|
+
{labels.recent}
|
|
51
|
+
</TabsTrigger>
|
|
52
|
+
) : null}
|
|
53
|
+
<TabsTrigger
|
|
54
|
+
value="templates"
|
|
55
|
+
className="flex-none"
|
|
56
|
+
onClick={() => {
|
|
57
|
+
if (activeValue === "templates") onValueChange("templates");
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
{labels.templates}
|
|
61
|
+
</TabsTrigger>
|
|
62
|
+
</TabsList>
|
|
63
|
+
{activeValue === "recent" ? (
|
|
64
|
+
<div className="flex w-full min-w-0 flex-wrap items-center justify-end gap-2 sm:w-auto">
|
|
65
|
+
{search}
|
|
66
|
+
{recentActions}
|
|
67
|
+
</div>
|
|
68
|
+
) : (
|
|
69
|
+
browseAll
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
<TabsContent value="templates">{templates}</TabsContent>
|
|
73
|
+
{recentVisible ? (
|
|
74
|
+
<TabsContent value="recent">{recent}</TabsContent>
|
|
75
|
+
) : null}
|
|
76
|
+
</Tabs>
|
|
77
|
+
</section>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -94,7 +94,7 @@ export function Header({ onOpenNavigation }: { onOpenNavigation: () => void }) {
|
|
|
94
94
|
);
|
|
95
95
|
|
|
96
96
|
return (
|
|
97
|
-
<div className={cn(isHome ? "
|
|
97
|
+
<div className={cn(isHome ? "shrink-0" : "contents")}>
|
|
98
98
|
<header
|
|
99
99
|
className={cn(
|
|
100
100
|
"shrink-0 items-center gap-3 bg-background px-4 lg:px-6",
|
|
@@ -116,9 +116,7 @@ export function Header({ onOpenNavigation }: { onOpenNavigation: () => void }) {
|
|
|
116
116
|
) : null}
|
|
117
117
|
{title ?? <ResolvedTitle />}
|
|
118
118
|
</div>
|
|
119
|
-
{isHome ?
|
|
120
|
-
<div className="design-home-header-search w-full">{actions}</div>
|
|
121
|
-
) : null}
|
|
119
|
+
{isHome && actions ? <div className="shrink-0">{actions}</div> : null}
|
|
122
120
|
<div className="flex items-center justify-end gap-2 shrink-0">
|
|
123
121
|
{isHome ? <HomeImportButton /> : null}
|
|
124
122
|
{!isHome && actions}
|
|
@@ -1 +1,59 @@
|
|
|
1
|
-
|
|
1
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const Tabs = TabsPrimitive.Root;
|
|
7
|
+
|
|
8
|
+
const TabsList = React.forwardRef<
|
|
9
|
+
React.ElementRef<typeof TabsPrimitive.List>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> & {
|
|
11
|
+
variant?: "default" | "line";
|
|
12
|
+
}
|
|
13
|
+
>(({ className, variant = "default", ...props }, ref) => (
|
|
14
|
+
<TabsPrimitive.List
|
|
15
|
+
ref={ref}
|
|
16
|
+
data-variant={variant}
|
|
17
|
+
className={cn(
|
|
18
|
+
variant === "line"
|
|
19
|
+
? "group/tabs-list inline-flex w-fit items-center justify-start gap-1 border-b border-border bg-transparent p-0 text-muted-foreground"
|
|
20
|
+
: "inline-flex h-9 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
));
|
|
26
|
+
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
27
|
+
|
|
28
|
+
const TabsTrigger = React.forwardRef<
|
|
29
|
+
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
|
30
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
|
31
|
+
>(({ className, ...props }, ref) => (
|
|
32
|
+
<TabsPrimitive.Trigger
|
|
33
|
+
ref={ref}
|
|
34
|
+
className={cn(
|
|
35
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1 text-sm font-medium ring-offset-background transition-[color,background-color,box-shadow] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
36
|
+
"group-data-[variant=line]/tabs-list:relative group-data-[variant=line]/tabs-list:h-9 group-data-[variant=line]/tabs-list:flex-none group-data-[variant=line]/tabs-list:rounded-none group-data-[variant=line]/tabs-list:border-b-2 group-data-[variant=line]/tabs-list:border-transparent group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:font-medium group-data-[variant=line]/tabs-list:text-muted-foreground group-data-[variant=line]/tabs-list:data-[state=active]:border-foreground group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:text-foreground group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none",
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
));
|
|
42
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
43
|
+
|
|
44
|
+
const TabsContent = React.forwardRef<
|
|
45
|
+
React.ElementRef<typeof TabsPrimitive.Content>,
|
|
46
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
|
47
|
+
>(({ className, ...props }, ref) => (
|
|
48
|
+
<TabsPrimitive.Content
|
|
49
|
+
ref={ref}
|
|
50
|
+
className={cn(
|
|
51
|
+
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
52
|
+
className,
|
|
53
|
+
)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
));
|
|
57
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
58
|
+
|
|
59
|
+
export { Tabs, TabsContent, TabsList, TabsTrigger };
|
|
@@ -5,10 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
@source "./**/*.{ts,tsx}";
|
|
7
7
|
|
|
8
|
-
.design-home-toolbar {
|
|
9
|
-
container: design-home-toolbar / inline-size;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
8
|
.design-template-preview-frame {
|
|
13
9
|
width: var(--design-template-width);
|
|
14
10
|
height: var(--design-template-height);
|
|
@@ -43,26 +39,11 @@
|
|
|
43
39
|
}
|
|
44
40
|
|
|
45
41
|
.design-home-header {
|
|
46
|
-
display:
|
|
42
|
+
display: flex;
|
|
47
43
|
height: 3.5rem;
|
|
48
|
-
grid-template-columns: minmax(0, 1fr) minmax(150px, 1fr) minmax(0, 1fr);
|
|
49
|
-
grid-template-rows: 3.5rem;
|
|
50
|
-
column-gap: 0.75rem;
|
|
51
44
|
border-bottom: 0;
|
|
52
45
|
}
|
|
53
46
|
|
|
54
|
-
.design-home-header-search {
|
|
55
|
-
grid-column: 2;
|
|
56
|
-
grid-row: 1;
|
|
57
|
-
display: flex;
|
|
58
|
-
width: 100%;
|
|
59
|
-
min-width: 150px;
|
|
60
|
-
max-width: 30rem;
|
|
61
|
-
align-items: center;
|
|
62
|
-
align-self: center;
|
|
63
|
-
justify-self: center;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
47
|
.design-home-header h1 {
|
|
67
48
|
font-size: 1rem;
|
|
68
49
|
line-height: 1.25rem;
|
|
@@ -74,20 +55,6 @@
|
|
|
74
55
|
}
|
|
75
56
|
}
|
|
76
57
|
|
|
77
|
-
@container design-home-toolbar (max-width: 26rem) {
|
|
78
|
-
.design-home-header {
|
|
79
|
-
height: 7rem;
|
|
80
|
-
grid-template-columns: minmax(0, 1fr) auto;
|
|
81
|
-
grid-template-rows: 3.5rem 3.5rem;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.design-home-header-search {
|
|
85
|
-
grid-column: 1 / -1;
|
|
86
|
-
grid-row: 2;
|
|
87
|
-
justify-self: center;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
58
|
.design-home-prompt-composer-area.agent-composer-area--hero {
|
|
92
59
|
padding: 0;
|
|
93
60
|
}
|
|
@@ -1751,6 +1751,9 @@ export default {
|
|
|
1751
1751
|
allAuthors: "All authors",
|
|
1752
1752
|
me: "Me",
|
|
1753
1753
|
designFilter: "Design filter",
|
|
1754
|
+
ownedByAnyone: "Owned by anyone",
|
|
1755
|
+
ownedByMe: "Owned by me",
|
|
1756
|
+
sharedWithMe: "Shared with me",
|
|
1754
1757
|
mine: "Mine",
|
|
1755
1758
|
all: "All",
|
|
1756
1759
|
showMineDesigns: "Show my designs",
|
|
@@ -1784,6 +1787,7 @@ export default {
|
|
|
1784
1787
|
pickStartingPoint: "Pick a starting point or write your own prompt.",
|
|
1785
1788
|
searchNoResultsTitle: "No designs match your search",
|
|
1786
1789
|
searchNoResultsDescription: "Try a different search.",
|
|
1790
|
+
noDesignsMatchFilter: "No designs match the current filter.",
|
|
1787
1791
|
starterSaas: "SaaS landing page",
|
|
1788
1792
|
starterDashboard: "Dashboard",
|
|
1789
1793
|
starterPricing: "Pricing page",
|