diff --git a/src/components/ButtonGroup.tsx b/src/components/ButtonGroup.tsx
index c22aa36f6..657635c3c 100644
--- a/src/components/ButtonGroup.tsx
+++ b/src/components/ButtonGroup.tsx
@@ -32,7 +32,7 @@ export function ButtonGroup({
'[&>*]:border-0! [&>*+*]:border-l! [&>*+*]:border-border-default!',
'bg-background-surface text-text-primary',
'shadow-sm',
- '[&>[aria-pressed=true]]:bg-text-primary [&>[aria-pressed=true]]:text-background-default [&>[aria-pressed=true]]:shadow-sm',
+ '[&>[aria-pressed=true]]:border-transparent [&>[aria-pressed=true]]:bg-text-primary [&>[aria-pressed=true]]:text-background-default [&>[aria-pressed=true]]:shadow-sm',
className,
)}
>
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx
index 6d2a637b3..e07cc0e1f 100644
--- a/src/components/Navbar.tsx
+++ b/src/components/Navbar.tsx
@@ -945,27 +945,24 @@ function MobileNavigation({
Ask AI
- {loadAuthControls ? (
-
- ) : (
- signIn
- )
- }
- >
-
-
- ) : (
- signIn
- )}
+ onClick={onNavigate}
+ className="flex w-full items-center gap-3.5 rounded-xl px-3 py-4 text-left font-ds-display text-ds-heading-3 text-[#a3a3a3] transition-colors hover:bg-[#171717] hover:text-white focus-visible:bg-[#171717] focus-visible:text-white focus-visible:outline-none"
+ >
+
+ Sign In
+
+ }
+ >
+
+
diff --git a/src/components/NavbarAuthControls.tsx b/src/components/NavbarAuthControls.tsx
index f15260943..1fd4d2688 100644
--- a/src/components/NavbarAuthControls.tsx
+++ b/src/components/NavbarAuthControls.tsx
@@ -1,11 +1,13 @@
import * as React from 'react'
-import { GearIcon } from '@phosphor-icons/react/Gear'
-import { KeyIcon } from '@phosphor-icons/react/Key'
-import { LockIcon } from '@phosphor-icons/react/Lock'
-import { HammerIcon } from '@phosphor-icons/react/Hammer'
-import { SignInIcon } from '@phosphor-icons/react/SignIn'
-import { SignOutIcon } from '@phosphor-icons/react/SignOut'
-import { SparkleIcon } from '@phosphor-icons/react/Sparkle'
+import {
+ GearIcon as Gear,
+ KeyIcon as Key,
+ LockIcon as Lock,
+ SignInIcon,
+ SignInIcon as SignIn,
+ SignOutIcon as SignOut,
+ SparkleIcon as Sparkle,
+} from '@phosphor-icons/react'
import { Link, useNavigate } from '@tanstack/react-router'
import { twMerge } from 'tailwind-merge'
import {
@@ -137,21 +139,14 @@ export function MobileNavbarAuthControls({
onClick={onNavigate}
className={itemClassName}
>
-
+
Sign In
)
- const loadingPlaceholder = (
-
- )
-
return (
<>
- {loadingPlaceholder}
+ {signIn}
{signIn}
-
+
Account
-
-
- My Projects
-
-
+
My Showcases
{user && (
@@ -188,7 +174,7 @@ export function MobileNavbarAuthControls({
onClick={onNavigate}
className={itemClassName}
>
-
+
Integrations
)}
@@ -199,7 +185,7 @@ export function MobileNavbarAuthControls({
onClick={onNavigate}
className={itemClassName}
>
-
+
Admin
)}
@@ -209,7 +195,7 @@ export function MobileNavbarAuthControls({
onClick={signOut}
className={itemClassName}
>
-
+
Sign Out
diff --git a/src/components/ds/BrandAssets.tsx b/src/components/ds/BrandAssets.tsx
index 21bf1ca08..6a144da60 100644
--- a/src/components/ds/BrandAssets.tsx
+++ b/src/components/ds/BrandAssets.tsx
@@ -1,9 +1,9 @@
import * as React from 'react'
import {
- CaretDownIcon,
- CheckIcon,
- CopyIcon,
- DownloadSimpleIcon,
+ CaretDownIcon as CaretDown,
+ CheckIcon as Check,
+ CopyIcon as Copy,
+ DownloadSimpleIcon as DownloadSimple,
} from '@phosphor-icons/react'
import { DsSection } from '~/components/ds/DsKit'
import { useToast } from '~/components/ToastProvider'
@@ -100,13 +100,9 @@ function CopyAssetButton({
}
copied.trigger()
- notify(Copied {label}
, {
- id: 'brand-asset-copied',
- })
+ notify(Copied {label}
)
} catch {
- notify(Could not copy {label}
, {
- id: 'brand-asset-copy-failed',
- })
+ notify(Could not copy {label}
)
}
}
@@ -121,9 +117,9 @@ function CopyAssetButton({
onClick={copyAsset}
>
{copied.active ? (
-
+
) : (
-
+
)}
)
@@ -237,7 +233,7 @@ function BrandLogoPicker() {
{logo.label}
-
+
@@ -248,7 +244,7 @@ function BrandLogoPicker() {
>
{option.label}
{option.value === logo.value ? (
-
+
) : null}
))}
@@ -264,7 +260,7 @@ function BrandLogoPicker() {
style={{ background: color.swatch }}
/>
{color.label}
-
+
@@ -280,7 +276,7 @@ function BrandLogoPicker() {
/>
{option.label}
{option.value === color.value ? (
-
+
) : null}
))}
@@ -291,7 +287,7 @@ function BrandLogoPicker() {
{format.label}
-
+
@@ -302,7 +298,7 @@ function BrandLogoPicker() {
>
{option.label}
{option.value === format.value ? (
-
+
) : null}
))}
@@ -326,7 +322,7 @@ function BrandLogoPicker() {
aria-label={`Download ${logo.label} ${color.label} as ${format.label}`}
title={`Download ${format.label}`}
>
-
+
@@ -419,7 +415,7 @@ function SocialLogoPicker() {
{orientation.label}
-
+
@@ -430,7 +426,7 @@ function SocialLogoPicker() {
>
{option.label}
{option.value === orientation.value ? (
-
+
) : null}
))}
@@ -446,7 +442,7 @@ function SocialLogoPicker() {
style={{ background: color.swatch }}
/>
{color.label}
-
+
@@ -462,7 +458,7 @@ function SocialLogoPicker() {
/>
{option.label}
{option.value === color.value ? (
-
+
) : null}
))}
@@ -473,7 +469,7 @@ function SocialLogoPicker() {
{format.label}
-
+
@@ -484,7 +480,7 @@ function SocialLogoPicker() {
>
{option.label}
{option.value === format.value ? (
-
+
) : null}
))}
@@ -508,7 +504,7 @@ function SocialLogoPicker() {
aria-label={`Download ${orientation.label} ${color.label} as ${format.label}`}
title={`Download ${format.label}`}
>
-
+
@@ -584,7 +580,7 @@ function AssetCard({ asset }: { asset: GalleryAsset }) {
title={`Download ${download.format}`}
className="text-white hover:bg-transparent hover:text-white/70 max-[899px]:bg-transparent"
>
-
+
))}
diff --git a/src/components/ds/ds-nav.ts b/src/components/ds/ds-nav.ts
index 027387d0b..2fc0fcd7b 100644
--- a/src/components/ds/ds-nav.ts
+++ b/src/components/ds/ds-nav.ts
@@ -99,26 +99,6 @@ export const dsNav: Array = [
{
title: 'Components',
items: [
- {
- label: 'Avatar',
- to: '/ds/avatar',
- sections: [
- 'Sizes',
- 'Fallbacks',
- 'Maintainer card',
- 'Responsive maintainer grid',
- ],
- },
- {
- label: 'Badges',
- to: '/ds/badges',
- sections: ['Variants', 'Corner styles', 'In context', 'Library status'],
- },
- {
- label: 'Breadcrumbs',
- to: '/ds/breadcrumbs',
- sections: ['Section + on-this-page'],
- },
{
label: 'Buttons',
to: '/ds/buttons',
@@ -137,41 +117,9 @@ export const dsNav: Array = [
],
},
{
- label: 'Cards & Surfaces',
- to: '/ds/cards',
- sections: ['Card', 'Inline code', 'Blog post card', 'Tooltip'],
- },
- {
- label: 'Dialog',
- to: '/ds/dialog',
- sections: [
- 'Basic',
- 'Sizes',
- 'Scrolling body',
- 'Destructive confirm',
- 'Tinted header',
- 'Status panel',
- 'Token coverage',
- 'Behaviour from Radix',
- ],
- },
- {
- label: 'Drawer',
- to: '/ds/drawer',
- sections: [
- 'Sides',
- 'Sizes',
- 'Fit to content',
- 'Anchor',
- 'Header actions',
- 'With a footer',
- 'Motion',
- ],
- },
- {
- label: 'Dropdown',
- to: '/ds/dropdown',
- sections: ['Basic menu', 'Scrollable'],
+ label: 'Badges',
+ to: '/ds/badges',
+ sections: ['Variants', 'Corner styles', 'In context'],
},
{
label: 'Eyebrow',
@@ -183,7 +131,7 @@ export const dsNav: Array = [
to: '/ds/inputs',
sections: [
'Default',
- 'Focus',
+ 'Focus rings',
'With a label & disabled',
'Progressive search',
'Persistent search',
@@ -191,45 +139,39 @@ export const dsNav: Array = [
],
},
{
- label: 'Navbar',
- to: '/ds/navbar',
- sections: [
- 'Anatomy',
- 'Mega menu item',
- 'Layout & spacing',
- 'Responsive behavior',
- 'Source',
- ],
+ label: 'Dropdown',
+ to: '/ds/dropdown',
+ sections: ['Basic menu'],
},
{
- label: 'Overlay Audit',
- to: '/ds/overlays',
+ label: 'Avatar',
+ to: '/ds/avatar',
sections: [
- 'Launch',
- 'Property matrix',
- 'Divergence',
- 'Notes per specimen',
+ 'Sizes',
+ 'Fallbacks',
+ 'Maintainer card',
+ 'Responsive maintainer grid',
],
},
{
- label: 'Page Header',
- to: '/ds/page-header',
- sections: ['Left-aligned', 'Centered', 'Marks & actions'],
+ label: 'Spinner',
+ to: '/ds/spinner',
+ sections: ['Sizes & color', 'Headbanger'],
},
{
- label: 'Panel',
- to: '/ds/panel',
+ label: 'Collapsible',
+ to: '/ds/collapsible',
sections: ['Disclosure'],
},
{
- label: 'Partner Rail',
- to: '/ds/partner-rail',
- sections: ['Rail', 'Tiers', 'Per-logo scale'],
+ label: 'Breadcrumbs',
+ to: '/ds/breadcrumbs',
+ sections: ['Section + on-this-page'],
},
{
- label: 'Spinner',
- to: '/ds/spinner',
- sections: ['Sizes & color', 'Headbanger'],
+ label: 'Cards & Surfaces',
+ to: '/ds/cards',
+ sections: ['Card', 'Inline code', 'Blog post card', 'Tooltip'],
},
{
label: 'Stats Section',
@@ -237,14 +179,17 @@ export const dsNav: Array = [
sections: ['Preview'],
},
{
- label: 'Takeover',
- to: '/ds/takeover',
- sections: ['Scrims', 'Leading action', 'Notes'],
- },
- {
- label: 'Tabs',
- to: '/ds/tabs',
- sections: ['Primary', 'Secondary', 'Icon only'],
+ label: 'Navbar',
+ to: '/ds/navbar',
+ sections: [
+ 'Anatomy',
+ 'Mega menu item',
+ 'Menu variants',
+ 'Regions',
+ 'Layout & spacing',
+ 'Responsive behavior',
+ 'Source',
+ ],
},
],
},
diff --git a/src/components/ds/ui/index.tsx b/src/components/ds/ui/index.tsx
index b3725f4f6..564f35dab 100644
--- a/src/components/ds/ui/index.tsx
+++ b/src/components/ds/ui/index.tsx
@@ -2,11 +2,13 @@ import * as React from 'react'
import { twMerge } from 'tailwind-merge'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import { Link } from '@tanstack/react-router'
-import { CaretDownIcon } from '@phosphor-icons/react/CaretDown'
-import { CircleNotchIcon } from '@phosphor-icons/react/CircleNotch'
-import { MagnifyingGlassIcon } from '@phosphor-icons/react/MagnifyingGlass'
-import { UserIcon } from '@phosphor-icons/react/User'
-import { XIcon } from '@phosphor-icons/react/X'
+import {
+ CaretDownIcon,
+ CircleNotchIcon,
+ MagnifyingGlassIcon as MagnifyingGlass,
+ UserIcon,
+ XIcon as X,
+} from '@phosphor-icons/react'
import type { MarkdownHeading } from '~/utils/markdown'
import type { LibraryId } from '~/libraries/ids'
import type { LibraryCategory } from '~/libraries/categories'
@@ -440,13 +442,11 @@ type SearchInputProps = Omit<
> & {
size?: 'default' | 'large'
progressive?: boolean
- /** Node rendered inside the field, right of the input (e.g. an RSS link). */
- trailing?: React.ReactNode
}
export const SearchInput = React.forwardRef(
function SearchInput(
- { className, size = 'default', progressive = false, trailing, ...props },
+ { className, size = 'default', progressive = false, ...props },
forwardedRef,
) {
const [open, setOpen] = React.useState(!progressive)
@@ -494,36 +494,22 @@ export const SearchInput = React.forwardRef(
if (!progressive) {
return (
-
- {/* The label wraps only the icon + input so clicking the field
- focuses it. Interactive `trailing` controls (links, buttons) sit
- outside the label — a form control inside a that also
- contains other interactive controls is invalid HTML. */}
-
-
- {input}
-
- {trailing ? (
- {trailing}
- ) : null}
-
+
+ {input}
+
)
}
@@ -538,7 +524,7 @@ export const SearchInput = React.forwardRef(
onClick={reveal}
className="grid size-10 shrink-0 place-items-center transition-colors duration-150 hover:text-text-primary focus-visible:text-text-accent focus-visible:outline-none motion-reduce:transition-none"
>
-
+
{React.cloneElement(input, {
tabIndex: open ? props.tabIndex : -1,
@@ -563,7 +549,7 @@ export const SearchInput = React.forwardRef(
skipMotion && 'transition-none',
)}
>
-
+
(
+ (newest, product) => {
+ if (!product.publishedAt) return newest
+ if (
+ !newest?.publishedAt ||
+ new Date(product.publishedAt) > new Date(newest.publishedAt)
+ ) {
+ return product
+ }
+ return newest
+ },
+ null,
+ )
const typeOptions = React.useMemo(() => {
const counts = new Map()
@@ -210,10 +222,7 @@ export function ShopBrowsePage({
= newProductCutoff
- }
+ isNew={product.id === newestProduct?.id}
loading={i < 8 ? 'eager' : 'lazy'}
onQuickView={onProductSelect}
/>
diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx
index 468c4cf40..7c9d92c41 100644
--- a/src/routes/__root.tsx
+++ b/src/routes/__root.tsx
@@ -345,64 +345,54 @@ function ShellComponent({ children }: { children: React.ReactNode }) {
{hasBaseParent ? : null}
-
-
-
-
-
-
-
-
- {hideNavbar ? (
- routeContent
- ) : (
-
- {routeContent}
- {hideFooter ? null : }
-
- )}
-
- {showDevtools && LazyAppDevtools ? (
-
-
-
-
-
- ) : null}
-
-
-
- {isNavigating && showNavigationSpinner ? (
-
- ) : null}
-
-
-
-
-
-
-
-
-
+
+
+
+
+ {hideNavbar ? (
+ children
+ ) : (
+
+ {children}
+
+
+ )}
+
+ {showDevtools && LazyAppDevtools ? (
+
+
+
+
+
+ ) : null}
+
+
+
+