@tscircuit/fake-snippets 0.0.108 → 0.0.110
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/.github/workflows/bun-formatcheck.yml +2 -2
- package/.github/workflows/bun-pver-release.yml +3 -3
- package/.github/workflows/bun-test.yml +1 -1
- package/.github/workflows/bun-typecheck.yml +2 -2
- package/.github/workflows/update-snapshots.yml +1 -1
- package/README.md +4 -0
- package/api/generated-index.js +37 -3
- package/biome.json +2 -1
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +31 -3
- package/bun-tests/fake-snippets-api/fixtures/preload.ts +18 -0
- package/bun-tests/fake-snippets-api/routes/orgs/add_member.test.ts +26 -0
- package/bun-tests/fake-snippets-api/routes/orgs/create.test.ts +37 -0
- package/bun-tests/fake-snippets-api/routes/orgs/get.test.ts +52 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list.test.ts +17 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list_members.test.ts +23 -0
- package/bun-tests/fake-snippets-api/routes/orgs/remove_member.test.ts +81 -0
- package/bun-tests/fake-snippets-api/routes/orgs/update.test.ts +99 -0
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +1 -1
- package/bun-tests/fake-snippets-api/routes/package_files/create.test.ts +15 -13
- package/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +26 -24
- package/bun-tests/fake-snippets-api/routes/package_files/delete.test.ts +9 -9
- package/bun-tests/fake-snippets-api/routes/package_files/download.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_files/get.test.ts +38 -28
- package/bun-tests/fake-snippets-api/routes/package_files/list.test.ts +23 -15
- package/bun-tests/fake-snippets-api/routes/package_releases/create.test.ts +33 -0
- package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_releases/get_image_generation_fields.test.ts +38 -0
- package/bun-tests/fake-snippets-api/routes/packages/create.test.ts +19 -0
- package/bun-tests/fake-snippets-api/routes/packages/fork.test.ts +3 -4
- package/bun-tests/fake-snippets-api/routes/packages/get.test.ts +30 -0
- package/bun-tests/fake-snippets-api/routes/packages/images.test.ts +4 -2
- package/bun-tests/fake-snippets-api/routes/packages/list-1.test.ts +34 -0
- package/bun.lock +389 -450
- package/bunfig.toml +2 -1
- package/dist/bundle.js +1255 -625
- package/dist/index.d.ts +296 -4
- package/dist/index.js +325 -24
- package/dist/schema.d.ts +282 -1
- package/dist/schema.js +54 -2
- package/fake-snippets-api/lib/db/autoload-dev-packages.ts +31 -20
- package/fake-snippets-api/lib/db/db-client.ts +214 -3
- package/fake-snippets-api/lib/db/schema.ts +62 -0
- package/fake-snippets-api/lib/db/seed.ts +100 -0
- package/fake-snippets-api/lib/middleware/with-session-auth.ts +1 -1
- package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +2 -2
- package/fake-snippets-api/lib/public-mapping/public-map-org.ts +32 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +10 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +17 -0
- package/fake-snippets-api/routes/api/orgs/add_member.ts +52 -0
- package/fake-snippets-api/routes/api/orgs/create.ts +46 -0
- package/fake-snippets-api/routes/api/orgs/get.ts +39 -0
- package/fake-snippets-api/routes/api/orgs/list.ts +31 -0
- package/fake-snippets-api/routes/api/orgs/list_members.ts +67 -0
- package/fake-snippets-api/routes/api/orgs/remove_member.ts +46 -0
- package/fake-snippets-api/routes/api/orgs/update.ts +93 -0
- package/fake-snippets-api/routes/api/package_files/get.ts +3 -6
- package/fake-snippets-api/routes/api/package_files/list.ts +7 -4
- package/fake-snippets-api/routes/api/packages/create.ts +54 -10
- package/fake-snippets-api/routes/api/packages/get.ts +23 -0
- package/fake-snippets-api/routes/api/packages/images/[owner_github_username]/[unscoped_name]/[view_format].ts +13 -11
- package/fake-snippets-api/routes/api/packages/list.ts +29 -2
- package/fake-snippets-api/routes/api/packages/update_ai_description.ts +37 -0
- package/package.json +27 -24
- package/renovate.json +1 -1
- package/scripts/generate-sitemap.ts +1 -1
- package/src/App.tsx +29 -10
- package/src/ContextProviders.tsx +25 -2
- package/src/components/CircuitJsonImportDialog.tsx +1 -1
- package/src/components/CmdKMenu.tsx +281 -247
- package/src/components/DownloadButtonAndMenu.tsx +133 -36
- package/src/components/FileSidebar.tsx +41 -50
- package/src/components/Footer.tsx +8 -10
- package/src/components/Header.tsx +19 -32
- package/src/components/Header2.tsx +16 -32
- package/src/components/HeaderDropdown.tsx +13 -8
- package/src/components/HeaderLogin.tsx +44 -16
- package/src/components/HiddenFilesDropdown.tsx +0 -2
- package/src/components/NotFound.tsx +5 -5
- package/src/components/PackageBreadcrumb.tsx +6 -12
- package/src/components/PackageCard.tsx +0 -1
- package/src/components/PackageSearchResults.tsx +1 -1
- package/src/components/PrefetchPageLink.tsx +7 -1
- package/src/components/ProfileRouter.tsx +32 -0
- package/src/components/SearchComponent.tsx +12 -8
- package/src/components/UserCard.tsx +80 -0
- package/src/components/ViewPackagePage/components/ShikiCodeViewer.tsx +20 -11
- package/src/components/ViewPackagePage/components/build-status.tsx +1 -1
- package/src/components/ViewPackagePage/components/important-files-view.tsx +174 -87
- package/src/components/ViewPackagePage/components/main-content-header.tsx +8 -4
- package/src/components/ViewPackagePage/components/main-content-view-selector.tsx +1 -2
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +54 -20
- package/src/components/ViewPackagePage/components/package-header.tsx +26 -37
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +11 -19
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +33 -25
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +16 -10
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +11 -11
- package/src/components/ViewPackagePage/components/sidebar.tsx +0 -2
- package/src/components/ViewPackagePage/components/tab-views/files-view.tsx +18 -17
- package/src/components/ViewPackagePage/components/tab-views/pcb-view.tsx +1 -2
- package/src/components/ViewPackagePage/components/tab-views/schematic-view.tsx +2 -1
- package/src/components/ViewPackagePage/components/theme-toggle.tsx +0 -2
- package/src/components/ViewPackagePage/hooks/use-toast.tsx +0 -1
- package/src/components/dialogs/GitHubRepositorySelector.tsx +56 -49
- package/src/components/dialogs/edit-package-details-dialog.tsx +5 -6
- package/src/components/dialogs/import-component-dialog.tsx +16 -9
- package/src/components/dialogs/import-package-dialog.tsx +3 -2
- package/src/components/dialogs/new-package-save-prompt-dialog.tsx +190 -0
- package/src/components/organization/OrganizationCard.tsx +204 -0
- package/src/components/organization/OrganizationCardSkeleton.tsx +55 -0
- package/src/components/organization/OrganizationHeader.tsx +154 -0
- package/src/components/organization/OrganizationMembers.tsx +146 -0
- package/src/components/package-port/CodeAndPreview.tsx +32 -46
- package/src/components/package-port/CodeEditor.tsx +28 -31
- package/src/components/package-port/CodeEditorHeader.tsx +128 -63
- package/src/components/package-port/EditorNav.tsx +32 -49
- package/src/components/preview/ConnectedPackagesList.tsx +8 -8
- package/src/components/preview/ConnectedRepoOverview.tsx +102 -2
- package/src/components/preview/PackageReleasesDashboard.tsx +53 -36
- package/src/components/ui/tree-view.tsx +6 -3
- package/src/hooks/use-add-org-member-mutation.ts +51 -0
- package/src/hooks/use-create-org-mutation.ts +38 -0
- package/src/hooks/use-create-package-mutation.ts +3 -0
- package/src/hooks/use-current-package-id.ts +5 -30
- package/src/hooks/use-current-package-info.ts +29 -5
- package/src/hooks/use-current-package-release.ts +4 -3
- package/src/hooks/use-download-zip.ts +2 -2
- package/src/hooks/use-global-store.ts +6 -4
- package/src/hooks/use-jlcpcb-component-import.tsx +164 -0
- package/src/hooks/use-list-org-members.ts +27 -0
- package/src/hooks/use-list-user-orgs.ts +25 -0
- package/src/hooks/use-org-by-github-handle.ts +26 -0
- package/src/hooks/use-org.ts +24 -0
- package/src/hooks/use-organization.ts +42 -0
- package/src/hooks/use-package-as-snippet.ts +4 -2
- package/src/hooks/use-package-builds.ts +6 -2
- package/src/hooks/use-package-files.ts +5 -3
- package/src/hooks/use-package-release-by-id-or-version.ts +29 -20
- package/src/hooks/use-package-release-images.ts +105 -0
- package/src/hooks/use-package-release.ts +2 -2
- package/src/hooks/use-package-stars.ts +80 -4
- package/src/hooks/use-preview-images.ts +6 -3
- package/src/hooks/use-remove-org-member-mutation.ts +32 -0
- package/src/hooks/use-update-ai-description-mutation.ts +42 -0
- package/src/hooks/use-update-org-mutation.ts +41 -0
- package/src/hooks/use-warn-user-on-page-change.ts +71 -4
- package/src/hooks/useFileManagement.ts +183 -35
- package/src/hooks/useOptimizedPackageFilesLoader.ts +136 -0
- package/src/hooks/usePackageFilesLoader.ts +2 -2
- package/src/hooks/useUpdatePackageFilesMutation.ts +15 -1
- package/src/lib/download-fns/download-circuit-png.ts +11 -3
- package/src/lib/download-fns/download-gltf-from-circuit-json.ts +44 -0
- package/src/lib/download-fns/download-kicad-files.ts +12 -11
- package/src/lib/normalize-svg-for-tile.ts +50 -0
- package/src/lib/posthog.ts +11 -9
- package/src/lib/react-query-api-failure-tracking.ts +148 -0
- package/src/lib/sentry.ts +14 -0
- package/src/lib/templates/blank-circuit-board-template.ts +0 -4
- package/src/lib/ts-lib-cache.ts +122 -7
- package/src/lib/utils/checkIfManualEditsImported.ts +4 -4
- package/src/lib/utils/findTargetFile.ts +45 -10
- package/src/lib/utils/isComponentExported.ts +10 -0
- package/src/main.tsx +2 -1
- package/src/pages/authorize.tsx +0 -2
- package/src/pages/create-organization.tsx +168 -0
- package/src/pages/dashboard.tsx +38 -6
- package/src/pages/datasheet.tsx +1 -1
- package/src/pages/datasheets.tsx +3 -3
- package/src/pages/editor.tsx +4 -6
- package/src/pages/landing.tsx +6 -7
- package/src/pages/latest.tsx +3 -0
- package/src/pages/organization-profile.tsx +199 -0
- package/src/pages/organization-settings.tsx +566 -0
- package/src/pages/package-editor.tsx +21 -21
- package/src/pages/preview-release.tsx +76 -136
- package/src/pages/quickstart.tsx +159 -123
- package/src/pages/release-detail.tsx +119 -31
- package/src/pages/search.tsx +192 -57
- package/src/pages/settings-redirect.tsx +44 -0
- package/src/pages/trending.tsx +29 -20
- package/src/pages/user-profile.tsx +58 -7
- package/src/pages/view-package.tsx +21 -26
- package/vite.config.ts +9 -0
- package/fake-snippets-api/routes/api/autocomplete/create_autocomplete.ts +0 -133
- package/src/components/Footer2.tsx +0 -100
- package/src/components/JLCPCBImportDialog.tsx +0 -280
- package/src/components/PackageBuildsPage/LogContent.tsx +0 -72
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +0 -115
- package/src/components/PackageBuildsPage/build-preview-content.tsx +0 -27
- package/src/components/PackageBuildsPage/collapsible-section.tsx +0 -63
- package/src/components/PackageBuildsPage/package-build-details-panel.tsx +0 -166
- package/src/components/PackageBuildsPage/package-build-header.tsx +0 -79
- package/src/components/PageSearchComponent.tsx +0 -148
- package/src/components/ShippingInformationForm.tsx +0 -423
- package/src/components/StaticViewSnippetHeader.tsx +0 -70
- package/src/components/ViewPackagePage/components/file-explorer.tsx +0 -67
- package/src/components/ViewPackagePage/components/readme-view.tsx +0 -58
- package/src/components/ViewPackagePage/components/repo-header-button.tsx +0 -36
- package/src/components/ViewPackagePage/components/repo-header.tsx +0 -4
- package/src/components/ViewPackagePage/components/sidebar-contributors-section.tsx +0 -31
- package/src/components/ViewSnippetHeader.tsx +0 -181
- package/src/components/ui/input-otp.tsx +0 -69
- package/src/pages/package-builds.tsx +0 -33
- package/src/pages/settings.tsx +0 -25
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { JLCPCBImportDialog } from "@/components/JLCPCBImportDialog"
|
|
2
1
|
import { useAxios } from "@/hooks/use-axios"
|
|
3
2
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
4
3
|
import { useHotkeyCombo } from "@/hooks/use-hotkey"
|
|
5
4
|
import { useNotImplementedToast } from "@/hooks/use-toast"
|
|
6
5
|
import { fuzzyMatch } from "@/components/ViewPackagePage/utils/fuzz-search"
|
|
6
|
+
import { useImportComponentDialog } from "@/components/dialogs/import-component-dialog"
|
|
7
|
+
import { useJlcpcbComponentImport } from "@/hooks/use-jlcpcb-component-import"
|
|
7
8
|
import { Command } from "cmdk"
|
|
8
9
|
import { Package, Account } from "fake-snippets-api/lib/db/schema"
|
|
9
|
-
import React, { useCallback, useEffect, useMemo, useRef } from "react"
|
|
10
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
|
10
11
|
import { useQuery } from "react-query"
|
|
11
12
|
import {
|
|
12
13
|
Search,
|
|
@@ -19,7 +20,14 @@ import {
|
|
|
19
20
|
Star,
|
|
20
21
|
User,
|
|
21
22
|
} from "lucide-react"
|
|
22
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
Dialog,
|
|
25
|
+
DialogContent,
|
|
26
|
+
DialogTitle,
|
|
27
|
+
DialogDescription,
|
|
28
|
+
} from "@/components/ui/dialog"
|
|
29
|
+
import { CircuitJsonImportDialog } from "./CircuitJsonImportDialog"
|
|
30
|
+
import { JlcpcbComponentTsxLoadedPayload } from "@tscircuit/runframe/runner"
|
|
23
31
|
|
|
24
32
|
type SnippetType = "board" | "package" | "model" | "footprint"
|
|
25
33
|
|
|
@@ -48,13 +56,33 @@ interface ScoredAccount extends Account {
|
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
const CmdKMenu = () => {
|
|
51
|
-
const [open, setOpen] =
|
|
52
|
-
const [searchQuery, setSearchQuery] =
|
|
53
|
-
const [
|
|
54
|
-
|
|
59
|
+
const [open, setOpen] = useState(false)
|
|
60
|
+
const [searchQuery, setSearchQuery] = useState("")
|
|
61
|
+
const [isCircuitJsonImportDialogOpen, setIsCircuitJsonImportDialogOpen] =
|
|
62
|
+
useState(false)
|
|
63
|
+
const [selectedIndex, setSelectedIndex] = useState(0)
|
|
55
64
|
const toastNotImplemented = useNotImplementedToast()
|
|
56
65
|
const axios = useAxios()
|
|
57
|
-
const
|
|
66
|
+
const { Dialog: ImportComponentDialog, openDialog: openImportDialog } =
|
|
67
|
+
useImportComponentDialog()
|
|
68
|
+
const { importComponent: importJlcpcbComponent } = useJlcpcbComponentImport()
|
|
69
|
+
const session = useGlobalStore((s) => s.session)
|
|
70
|
+
const currentUser = session?.github_username
|
|
71
|
+
const jlcpcbProxyRequestHeaders = useMemo(
|
|
72
|
+
() =>
|
|
73
|
+
session?.token
|
|
74
|
+
? {
|
|
75
|
+
Authorization: `Bearer ${session.token}`,
|
|
76
|
+
}
|
|
77
|
+
: undefined,
|
|
78
|
+
[session?.token],
|
|
79
|
+
)
|
|
80
|
+
const handleJlcpcbComponentSelected = useCallback(
|
|
81
|
+
async (payload: JlcpcbComponentTsxLoadedPayload) => {
|
|
82
|
+
await importJlcpcbComponent(payload)
|
|
83
|
+
},
|
|
84
|
+
[importJlcpcbComponent],
|
|
85
|
+
)
|
|
58
86
|
const selectedItemRef = useRef<HTMLDivElement>(null)
|
|
59
87
|
|
|
60
88
|
const blankTemplates = useMemo(
|
|
@@ -92,19 +120,10 @@ const CmdKMenu = () => {
|
|
|
92
120
|
const importOptions = useMemo(
|
|
93
121
|
(): ImportOption[] => [
|
|
94
122
|
{
|
|
95
|
-
name: "
|
|
96
|
-
type: "footprint",
|
|
97
|
-
icon: <Download className="w-4 h-4 text-gray-500" />,
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: "KiCad Project",
|
|
101
|
-
type: "board",
|
|
102
|
-
icon: <Download className="w-4 h-4 text-gray-500" />,
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: "KiCad Module",
|
|
123
|
+
name: "Circuit JSON",
|
|
106
124
|
type: "package",
|
|
107
|
-
|
|
125
|
+
special: true,
|
|
126
|
+
icon: <Download className="w-4 h-4 text-red-500" />,
|
|
108
127
|
},
|
|
109
128
|
{
|
|
110
129
|
name: "JLCPCB Component",
|
|
@@ -369,8 +388,16 @@ const CmdKMenu = () => {
|
|
|
369
388
|
break
|
|
370
389
|
case "import":
|
|
371
390
|
if (item.special) {
|
|
372
|
-
|
|
373
|
-
|
|
391
|
+
switch (item.name) {
|
|
392
|
+
case "Circuit JSON":
|
|
393
|
+
setOpen(false)
|
|
394
|
+
setIsCircuitJsonImportDialogOpen(true)
|
|
395
|
+
break
|
|
396
|
+
case "JLCPCB Component":
|
|
397
|
+
setOpen(false)
|
|
398
|
+
openImportDialog()
|
|
399
|
+
break
|
|
400
|
+
}
|
|
374
401
|
} else {
|
|
375
402
|
setOpen(false)
|
|
376
403
|
toastNotImplemented(`${item.name} Import`)
|
|
@@ -401,8 +428,8 @@ const CmdKMenu = () => {
|
|
|
401
428
|
const isSelected = index === selectedIndex
|
|
402
429
|
|
|
403
430
|
const baseClasses = `
|
|
404
|
-
group flex items-center justify-between px-3 py-2 rounded-md cursor-pointer
|
|
405
|
-
transition-all duration-150 border border-transparent text-sm
|
|
431
|
+
group flex items-center justify-between px-2 sm:px-3 py-2 rounded-md cursor-pointer
|
|
432
|
+
transition-all duration-150 border border-transparent text-sm w-full
|
|
406
433
|
${isSelected ? "bg-blue-50 border-blue-200" : "hover:bg-gray-50"}
|
|
407
434
|
${disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
408
435
|
`
|
|
@@ -417,32 +444,32 @@ const CmdKMenu = () => {
|
|
|
417
444
|
className={baseClasses}
|
|
418
445
|
onClick={() => !disabled && handleItemSelect(item)}
|
|
419
446
|
>
|
|
420
|
-
<div className="flex items-center gap-2 min-w-0">
|
|
447
|
+
<div className="flex items-center gap-2 min-w-0 flex-1 overflow-hidden">
|
|
421
448
|
<Package2 className="w-4 h-4 text-blue-500 flex-shrink-0" />
|
|
422
|
-
<div className="flex flex-col min-w-0">
|
|
423
|
-
<span className="font-medium text-gray-900 truncate">
|
|
449
|
+
<div className="flex flex-col min-w-0 flex-1 overflow-hidden">
|
|
450
|
+
<span className="font-medium text-gray-900 truncate max-w-full">
|
|
424
451
|
{type === "package"
|
|
425
452
|
? renderHighlighted(data, data.name)
|
|
426
453
|
: data.name}
|
|
427
454
|
</span>
|
|
428
455
|
{data.description && (
|
|
429
|
-
<span className="text-xs text-gray-500 truncate">
|
|
456
|
+
<span className="text-xs text-gray-500 truncate max-w-full">
|
|
430
457
|
{data.description}
|
|
431
458
|
</span>
|
|
432
459
|
)}
|
|
433
460
|
{type === "recent" && (
|
|
434
|
-
<span className="text-xs text-gray-400">
|
|
461
|
+
<span className="text-xs text-gray-400 hidden sm:block truncate">
|
|
435
462
|
{new Date(data.updated_at).toLocaleDateString()}
|
|
436
463
|
</span>
|
|
437
464
|
)}
|
|
438
465
|
</div>
|
|
439
466
|
</div>
|
|
440
|
-
<div className="flex items-center gap-2 flex-shrink-0">
|
|
467
|
+
<div className="flex items-center gap-1 sm:gap-2 flex-shrink-0">
|
|
441
468
|
<div className="flex items-center gap-1 text-gray-500">
|
|
442
469
|
<Star className="w-3 h-3 fill-yellow-400 text-yellow-400" />
|
|
443
470
|
<span className="text-xs">{data.star_count ?? 0}</span>
|
|
444
471
|
</div>
|
|
445
|
-
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded">
|
|
472
|
+
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded hidden sm:inline">
|
|
446
473
|
package
|
|
447
474
|
</span>
|
|
448
475
|
{isSelected && <ArrowRight className="w-3 h-3 text-gray-400" />}
|
|
@@ -458,7 +485,7 @@ const CmdKMenu = () => {
|
|
|
458
485
|
className={baseClasses}
|
|
459
486
|
onClick={() => !disabled && handleItemSelect(item)}
|
|
460
487
|
>
|
|
461
|
-
<div className="flex items-center gap-2 min-w-0">
|
|
488
|
+
<div className="flex items-center gap-2 min-w-0 flex-1">
|
|
462
489
|
<img
|
|
463
490
|
src={`https://github.com/${data.github_username}.png`}
|
|
464
491
|
alt={`${data.github_username} avatar`}
|
|
@@ -470,14 +497,14 @@ const CmdKMenu = () => {
|
|
|
470
497
|
}}
|
|
471
498
|
/>
|
|
472
499
|
<User className="w-6 h-6 text-gray-400 flex-shrink-0 hidden" />
|
|
473
|
-
<div className="flex flex-col min-w-0">
|
|
500
|
+
<div className="flex flex-col min-w-0 flex-1">
|
|
474
501
|
<span className="font-medium text-gray-900 truncate">
|
|
475
502
|
{renderHighlighted(data, data.github_username)}
|
|
476
503
|
</span>
|
|
477
504
|
</div>
|
|
478
505
|
</div>
|
|
479
506
|
<div className="flex items-center gap-1 flex-shrink-0">
|
|
480
|
-
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded">
|
|
507
|
+
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded hidden sm:inline">
|
|
481
508
|
user
|
|
482
509
|
</span>
|
|
483
510
|
{isSelected && <ArrowRight className="w-3 h-3 text-gray-400" />}
|
|
@@ -494,14 +521,14 @@ const CmdKMenu = () => {
|
|
|
494
521
|
className={baseClasses}
|
|
495
522
|
onClick={() => !disabled && handleItemSelect(item)}
|
|
496
523
|
>
|
|
497
|
-
<div className="flex items-center gap-2">
|
|
524
|
+
<div className="flex items-center gap-2 min-w-0 flex-1">
|
|
498
525
|
{data.icon}
|
|
499
|
-
<span className="font-medium text-gray-900">
|
|
526
|
+
<span className="font-medium text-gray-900 truncate">
|
|
500
527
|
{renderHighlighted(data, data.name)}
|
|
501
528
|
</span>
|
|
502
529
|
</div>
|
|
503
|
-
<div className="flex items-center gap-1">
|
|
504
|
-
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded">
|
|
530
|
+
<div className="flex items-center gap-1 flex-shrink-0">
|
|
531
|
+
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded hidden sm:inline">
|
|
505
532
|
{data.type}
|
|
506
533
|
</span>
|
|
507
534
|
{isSelected && <ArrowRight className="w-3 h-3 text-gray-400" />}
|
|
@@ -517,14 +544,14 @@ const CmdKMenu = () => {
|
|
|
517
544
|
className={baseClasses}
|
|
518
545
|
onClick={() => handleItemSelect(item)}
|
|
519
546
|
>
|
|
520
|
-
<div className="flex items-center gap-2">
|
|
547
|
+
<div className="flex items-center gap-2 min-w-0 flex-1">
|
|
521
548
|
{data.icon}
|
|
522
|
-
<span className="font-medium text-gray-900">
|
|
549
|
+
<span className="font-medium text-gray-900 truncate">
|
|
523
550
|
Import {renderHighlighted(data, data.name)}
|
|
524
551
|
</span>
|
|
525
552
|
</div>
|
|
526
|
-
<div className="flex items-center gap-1">
|
|
527
|
-
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded">
|
|
553
|
+
<div className="flex items-center gap-1 flex-shrink-0">
|
|
554
|
+
<span className="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded hidden sm:inline">
|
|
528
555
|
{data.type}
|
|
529
556
|
</span>
|
|
530
557
|
{isSelected && <ArrowRight className="w-3 h-3 text-gray-400" />}
|
|
@@ -541,229 +568,236 @@ const CmdKMenu = () => {
|
|
|
541
568
|
|
|
542
569
|
if (!open)
|
|
543
570
|
return (
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
571
|
+
<>
|
|
572
|
+
<ImportComponentDialog
|
|
573
|
+
onJlcpcbComponentTsxLoaded={handleJlcpcbComponentSelected}
|
|
574
|
+
jlcpcbProxyRequestHeaders={jlcpcbProxyRequestHeaders}
|
|
575
|
+
/>
|
|
576
|
+
<CircuitJsonImportDialog
|
|
577
|
+
open={isCircuitJsonImportDialogOpen}
|
|
578
|
+
onOpenChange={setIsCircuitJsonImportDialogOpen}
|
|
579
|
+
/>
|
|
580
|
+
</>
|
|
548
581
|
)
|
|
549
582
|
|
|
550
583
|
return (
|
|
551
584
|
<>
|
|
552
|
-
<
|
|
553
|
-
className="
|
|
554
|
-
|
|
555
|
-
|
|
585
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
586
|
+
<DialogContent className="max-w-xl lg:max-w-2xl w-[95vw] bg-white rounded-lg shadow-xl border border-gray-200 p-0 top-[10vh] translate-y-0">
|
|
587
|
+
<DialogTitle className="sr-only">Command Menu</DialogTitle>
|
|
588
|
+
<DialogDescription className="sr-only">
|
|
589
|
+
Use this menu to search packages and commands.
|
|
590
|
+
</DialogDescription>
|
|
591
|
+
<Command
|
|
592
|
+
className="w-full overflow-hidden"
|
|
593
|
+
loop={false}
|
|
594
|
+
onKeyDown={handleKeyDown}
|
|
595
|
+
>
|
|
596
|
+
<div className="flex items-center border-b border-gray-200 px-3 sm:px-4 py-3">
|
|
597
|
+
<Search className="w-4 h-4 mr-2 text-gray-400 flex-shrink-0" />
|
|
598
|
+
<Command.Input
|
|
599
|
+
placeholder="Search packages and commands..."
|
|
600
|
+
value={searchQuery}
|
|
601
|
+
onValueChange={setSearchQuery}
|
|
602
|
+
className="w-full bg-transparent border-none outline-none text-sm text-gray-900 placeholder-gray-500"
|
|
603
|
+
/>
|
|
604
|
+
</div>
|
|
556
605
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
onKeyDown={handleKeyDown}
|
|
564
|
-
aria-describedby="dialog-description"
|
|
565
|
-
>
|
|
566
|
-
<DialogTitle className="sr-only">Command Menu</DialogTitle>
|
|
567
|
-
<DialogDescription id="dialog-description" className="sr-only">
|
|
568
|
-
Use this menu to search packages and commands.
|
|
569
|
-
</DialogDescription>
|
|
570
|
-
<div className="flex items-center border-b border-gray-200 px-4 py-3">
|
|
571
|
-
<Search className="w-4 h-4 mr-2 text-gray-400 flex-shrink-0" />
|
|
572
|
-
<Command.Input
|
|
573
|
-
placeholder="Search packages and commands..."
|
|
574
|
-
value={searchQuery}
|
|
575
|
-
onValueChange={setSearchQuery}
|
|
576
|
-
className="w-full bg-transparent border-none outline-none text-gray-900 placeholder-gray-500"
|
|
577
|
-
/>
|
|
578
|
-
</div>
|
|
579
|
-
|
|
580
|
-
<Command.List className="max-h-80 overflow-y-auto p-2 space-y-4">
|
|
581
|
-
{isSearching || isSearchingAccounts ? (
|
|
582
|
-
<Command.Loading className="p-6 text-center text-gray-500">
|
|
583
|
-
<div className="flex items-center justify-center gap-2">
|
|
584
|
-
<div className="w-3 h-3 border-2 border-gray-300 border-t-gray-600 rounded-full animate-spin"></div>
|
|
585
|
-
Loading...
|
|
586
|
-
</div>
|
|
587
|
-
</Command.Loading>
|
|
588
|
-
) : (
|
|
589
|
-
<>
|
|
590
|
-
{searchQuery && searchResults.length > 0 && (
|
|
591
|
-
<div>
|
|
592
|
-
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2 px-2">
|
|
593
|
-
Packages
|
|
594
|
-
</h3>
|
|
595
|
-
<div className="space-y-1">
|
|
596
|
-
{searchResults.slice(0, 8).map((pkg, localIndex) => {
|
|
597
|
-
const globalIndex = localIndex
|
|
598
|
-
return renderItem(
|
|
599
|
-
{ type: "package", item: pkg },
|
|
600
|
-
globalIndex,
|
|
601
|
-
)
|
|
602
|
-
})}
|
|
606
|
+
<Command.List className="max-h-[60vh] sm:max-h-[50vh] overflow-y-auto p-2 sm:p-3 space-y-3 no-scrollbar">
|
|
607
|
+
{isSearching || isSearchingAccounts ? (
|
|
608
|
+
<Command.Loading className="p-6 text-center text-gray-500">
|
|
609
|
+
<div className="flex items-center justify-center gap-2">
|
|
610
|
+
<div className="w-3 h-3 border-2 border-gray-300 border-t-gray-600 rounded-full animate-spin"></div>
|
|
611
|
+
Loading...
|
|
603
612
|
</div>
|
|
604
|
-
</
|
|
605
|
-
)
|
|
613
|
+
</Command.Loading>
|
|
614
|
+
) : (
|
|
615
|
+
<>
|
|
616
|
+
{searchQuery && searchResults.length > 0 && (
|
|
617
|
+
<div>
|
|
618
|
+
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2 px-2">
|
|
619
|
+
Packages
|
|
620
|
+
</h3>
|
|
621
|
+
<div className="space-y-1">
|
|
622
|
+
{searchResults.slice(0, 8).map((pkg, localIndex) => {
|
|
623
|
+
const globalIndex = localIndex
|
|
624
|
+
return renderItem(
|
|
625
|
+
{ type: "package", item: pkg },
|
|
626
|
+
globalIndex,
|
|
627
|
+
)
|
|
628
|
+
})}
|
|
629
|
+
</div>
|
|
630
|
+
</div>
|
|
631
|
+
)}
|
|
606
632
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
633
|
+
{searchQuery && accountSearchResults.length > 0 && (
|
|
634
|
+
<div>
|
|
635
|
+
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2 px-2">
|
|
636
|
+
Users
|
|
637
|
+
</h3>
|
|
638
|
+
<div className="space-y-1">
|
|
639
|
+
{accountSearchResults
|
|
640
|
+
.slice(0, 5)
|
|
641
|
+
.map((account, localIndex) => {
|
|
642
|
+
const globalIndex =
|
|
643
|
+
searchResults.length + localIndex
|
|
644
|
+
return renderItem(
|
|
645
|
+
{ type: "account", item: account },
|
|
646
|
+
globalIndex,
|
|
647
|
+
)
|
|
648
|
+
})}
|
|
649
|
+
</div>
|
|
650
|
+
</div>
|
|
651
|
+
)}
|
|
625
652
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
653
|
+
{!searchQuery && recentPackages.length > 0 && (
|
|
654
|
+
<div>
|
|
655
|
+
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2 px-2 flex items-center gap-1">
|
|
656
|
+
<Clock className="w-3 h-3" />
|
|
657
|
+
Recent
|
|
658
|
+
</h3>
|
|
659
|
+
<div className="space-y-1">
|
|
660
|
+
{recentPackages.slice(0, 6).map((pkg, localIndex) => {
|
|
661
|
+
const globalIndex = localIndex
|
|
662
|
+
return renderItem(
|
|
663
|
+
{ type: "recent", item: pkg },
|
|
664
|
+
globalIndex,
|
|
665
|
+
)
|
|
666
|
+
})}
|
|
667
|
+
</div>
|
|
668
|
+
</div>
|
|
669
|
+
)}
|
|
643
670
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
671
|
+
{filteredStaticOptions.blankTemplates.length > 0 && (
|
|
672
|
+
<div>
|
|
673
|
+
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2 px-2">
|
|
674
|
+
Create
|
|
675
|
+
</h3>
|
|
676
|
+
<div className="space-y-1">
|
|
677
|
+
{filteredStaticOptions.blankTemplates.map(
|
|
678
|
+
(template, localIndex) => {
|
|
679
|
+
const globalIndex =
|
|
680
|
+
(searchQuery
|
|
681
|
+
? searchResults.length +
|
|
682
|
+
accountSearchResults.length
|
|
683
|
+
: recentPackages.length) + localIndex
|
|
684
|
+
return renderItem(
|
|
685
|
+
{
|
|
686
|
+
type: "blank",
|
|
687
|
+
item: template,
|
|
688
|
+
disabled: template.disabled,
|
|
689
|
+
},
|
|
690
|
+
globalIndex,
|
|
691
|
+
)
|
|
661
692
|
},
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
</div>
|
|
667
|
-
</div>
|
|
668
|
-
)}
|
|
693
|
+
)}
|
|
694
|
+
</div>
|
|
695
|
+
</div>
|
|
696
|
+
)}
|
|
669
697
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
698
|
+
{filteredStaticOptions.templates.length > 0 && (
|
|
699
|
+
<div>
|
|
700
|
+
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2 px-2">
|
|
701
|
+
Templates
|
|
702
|
+
</h3>
|
|
703
|
+
<div className="space-y-1">
|
|
704
|
+
{filteredStaticOptions.templates.map(
|
|
705
|
+
(template, localIndex) => {
|
|
706
|
+
const globalIndex =
|
|
707
|
+
(searchQuery
|
|
708
|
+
? searchResults.length +
|
|
709
|
+
accountSearchResults.length
|
|
710
|
+
: recentPackages.length) +
|
|
711
|
+
filteredStaticOptions.blankTemplates.length +
|
|
712
|
+
localIndex
|
|
713
|
+
return renderItem(
|
|
714
|
+
{ type: "template", item: template },
|
|
715
|
+
globalIndex,
|
|
716
|
+
)
|
|
717
|
+
},
|
|
718
|
+
)}
|
|
719
|
+
</div>
|
|
720
|
+
</div>
|
|
721
|
+
)}
|
|
693
722
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
723
|
+
{filteredStaticOptions.importOptions.length > 0 && (
|
|
724
|
+
<div>
|
|
725
|
+
<h3 className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-2 px-2">
|
|
726
|
+
Import
|
|
727
|
+
</h3>
|
|
728
|
+
<div className="space-y-1">
|
|
729
|
+
{filteredStaticOptions.importOptions.map(
|
|
730
|
+
(option, localIndex) => {
|
|
731
|
+
const globalIndex =
|
|
732
|
+
(searchQuery
|
|
733
|
+
? searchResults.length +
|
|
734
|
+
accountSearchResults.length
|
|
735
|
+
: recentPackages.length) +
|
|
736
|
+
filteredStaticOptions.blankTemplates.length +
|
|
737
|
+
filteredStaticOptions.templates.length +
|
|
738
|
+
localIndex
|
|
739
|
+
return renderItem(
|
|
740
|
+
{ type: "import", item: option },
|
|
741
|
+
globalIndex,
|
|
742
|
+
)
|
|
743
|
+
},
|
|
744
|
+
)}
|
|
745
|
+
</div>
|
|
746
|
+
</div>
|
|
747
|
+
)}
|
|
748
|
+
|
|
749
|
+
{searchQuery &&
|
|
750
|
+
!searchResults.length &&
|
|
751
|
+
!accountSearchResults.length &&
|
|
752
|
+
!filteredStaticOptions.blankTemplates.length &&
|
|
753
|
+
!filteredStaticOptions.templates.length &&
|
|
754
|
+
!filteredStaticOptions.importOptions.length &&
|
|
755
|
+
!isSearching &&
|
|
756
|
+
!isSearchingAccounts && (
|
|
757
|
+
<Command.Empty className="py-8 text-center">
|
|
758
|
+
<div className="text-gray-400 mb-1">
|
|
759
|
+
No results found
|
|
760
|
+
</div>
|
|
761
|
+
<div className="text-gray-500 text-xs">
|
|
762
|
+
Try different search terms
|
|
763
|
+
</div>
|
|
764
|
+
</Command.Empty>
|
|
714
765
|
)}
|
|
766
|
+
</>
|
|
767
|
+
)}
|
|
768
|
+
</Command.List>
|
|
769
|
+
|
|
770
|
+
<div className="border-t border-gray-200 px-2 py-2 bg-gray-50/50 rounded-b-lg">
|
|
771
|
+
<div className="flex justify-between items-center text-[11px] sm:text-xs text-gray-500">
|
|
772
|
+
<div className="flex items-center gap-1.5 sm:gap-3">
|
|
773
|
+
<div className="flex items-center gap-1">
|
|
774
|
+
<kbd className="px-1 py-0.5 font-mono bg-white border border-gray-200 shadow-sm rounded text-[10px] sm:text-xs">
|
|
775
|
+
↑↓
|
|
776
|
+
</kbd>
|
|
777
|
+
<span className="hidden sm:inline">navigate</span>
|
|
778
|
+
</div>
|
|
779
|
+
<div className="flex items-center gap-1">
|
|
780
|
+
<kbd className="px-1 py-0.5 font-mono bg-white border border-gray-200 shadow-sm rounded text-[10px] sm:text-xs">
|
|
781
|
+
↵
|
|
782
|
+
</kbd>
|
|
783
|
+
<span className="hidden sm:inline">select</span>
|
|
715
784
|
</div>
|
|
716
785
|
</div>
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
!filteredStaticOptions.templates.length &&
|
|
724
|
-
!filteredStaticOptions.importOptions.length &&
|
|
725
|
-
!isSearching &&
|
|
726
|
-
!isSearchingAccounts && (
|
|
727
|
-
<Command.Empty className="py-8 text-center">
|
|
728
|
-
<div className="text-gray-400 mb-1">No results found</div>
|
|
729
|
-
<div className="text-gray-500 text-xs">
|
|
730
|
-
Try different search terms
|
|
731
|
-
</div>
|
|
732
|
-
</Command.Empty>
|
|
733
|
-
)}
|
|
734
|
-
</>
|
|
735
|
-
)}
|
|
736
|
-
</Command.List>
|
|
737
|
-
|
|
738
|
-
<div className="border-t border-gray-200 px-4 py-2 bg-gray-50/50 rounded-b-lg">
|
|
739
|
-
<div className="flex justify-between items-center text-xs text-gray-500">
|
|
740
|
-
<div className="flex items-center gap-4">
|
|
741
|
-
<div className="flex items-center gap-1">
|
|
742
|
-
<kbd className="px-1.5 py-0.5 font-mono bg-white border border-gray-300 rounded text-xs">
|
|
743
|
-
↑↓
|
|
744
|
-
</kbd>
|
|
745
|
-
<span>navigate</span>
|
|
746
|
-
</div>
|
|
747
|
-
<div className="flex items-center gap-1">
|
|
748
|
-
<kbd className="px-1.5 py-0.5 font-mono bg-white border border-gray-300 rounded text-xs">
|
|
749
|
-
↵
|
|
750
|
-
</kbd>
|
|
751
|
-
<span>select</span>
|
|
786
|
+
<div className="flex items-center gap-1">
|
|
787
|
+
<kbd className="px-1 py-0.5 font-mono bg-white border border-gray-200 shadow-sm rounded text-[10px] sm:text-xs">
|
|
788
|
+
⌘K
|
|
789
|
+
</kbd>
|
|
790
|
+
<span className="hidden sm:inline">close</span>
|
|
791
|
+
</div>
|
|
752
792
|
</div>
|
|
753
793
|
</div>
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
</kbd>
|
|
758
|
-
<span>close</span>
|
|
759
|
-
</div>
|
|
760
|
-
</div>
|
|
761
|
-
</div>
|
|
762
|
-
</Command.Dialog>
|
|
794
|
+
</Command>
|
|
795
|
+
</DialogContent>
|
|
796
|
+
</Dialog>
|
|
763
797
|
|
|
764
|
-
<
|
|
765
|
-
|
|
766
|
-
|
|
798
|
+
<ImportComponentDialog
|
|
799
|
+
onJlcpcbComponentTsxLoaded={handleJlcpcbComponentSelected}
|
|
800
|
+
jlcpcbProxyRequestHeaders={jlcpcbProxyRequestHeaders}
|
|
767
801
|
/>
|
|
768
802
|
</>
|
|
769
803
|
)
|