@shipsite.dev/components 0.2.43 → 0.2.44

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.
@@ -1 +1 @@
1
- {"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/layout/Header.tsx"],"names":[],"mappings":"AAgBA,wBAAgB,MAAM,4CA8ErB"}
1
+ {"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../src/layout/Header.tsx"],"names":[],"mappings":"AAiBA,wBAAgB,MAAM,4CAoFrB"}
@@ -6,10 +6,11 @@ import { Button } from '../ui/button';
6
6
  import { Navbar, NavbarLeft, NavbarRight } from '../ui/navbar';
7
7
  import { Sheet, SheetTrigger, SheetContent, SheetTitle, } from '../ui/sheet';
8
8
  import { ThemeToggle } from '../ui/theme-toggle';
9
+ import { ClientOnly } from '../ui/client-only';
9
10
  export function Header() {
10
11
  const { siteName, logo, navigation, locale, defaultLocale } = useShipSite();
11
12
  const resolveHref = useResolveHref();
12
13
  const logoSrc = typeof logo === 'string' ? logo : logo?.light;
13
- return (_jsx("header", { className: "sticky top-0 z-50 bg-background/80 backdrop-blur-lg border-b border-border", children: _jsx("div", { className: "container-main", children: _jsxs(Navbar, { children: [_jsx(NavbarLeft, { children: _jsxs("a", { href: locale === defaultLocale ? '/' : `/${locale}`, className: "flex items-center gap-2", children: [logoSrc && (_jsx("img", { src: logoSrc, alt: siteName, className: "h-8 w-auto" })), _jsx("span", { className: "font-semibold text-lg text-foreground", children: siteName })] }) }), _jsxs(NavbarRight, { className: "hidden md:flex", children: [navigation.items.map((item) => (_jsx("a", { href: resolveHref(item.href), className: "text-sm font-medium text-muted-foreground hover:text-foreground transition-colors", children: item.label }, item.href))), _jsx(ThemeToggle, {}), navigation.cta && (_jsx(Button, { asChild: true, size: "sm", children: _jsx("a", { href: navigation.cta.href, children: navigation.cta.label }) }))] }), _jsx("div", { className: "md:hidden", children: _jsxs(Sheet, { children: [_jsx(SheetTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Toggle menu", children: _jsx(Menu, { className: "size-5" }) }) }), _jsxs(SheetContent, { side: "right", children: [_jsx(SheetTitle, { className: "sr-only", children: "Navigation" }), _jsxs("nav", { className: "flex flex-col gap-4 mt-8", children: [navigation.items.map((item) => (_jsx("a", { href: resolveHref(item.href), className: "text-sm font-medium text-muted-foreground hover:text-foreground transition-colors", children: item.label }, item.href))), navigation.cta && (_jsx(Button, { asChild: true, className: "mt-2", children: _jsx("a", { href: navigation.cta.href, children: navigation.cta.label }) }))] })] })] }) })] }) }) }));
14
+ return (_jsx("header", { className: "sticky top-0 z-50 bg-background/80 backdrop-blur-lg border-b border-border", children: _jsx("div", { className: "container-main", children: _jsxs(Navbar, { children: [_jsx(NavbarLeft, { children: _jsxs("a", { href: locale === defaultLocale ? '/' : `/${locale}`, className: "flex items-center gap-2", children: [logoSrc && (_jsx("img", { src: logoSrc, alt: siteName, className: "h-8 w-auto" })), _jsx("span", { className: "font-semibold text-lg text-foreground", children: siteName })] }) }), _jsxs(NavbarRight, { className: "hidden md:flex", children: [navigation.items.map((item) => (_jsx("a", { href: resolveHref(item.href), className: "text-sm font-medium text-muted-foreground hover:text-foreground transition-colors", children: item.label }, item.href))), _jsx(ThemeToggle, {}), navigation.cta && (_jsx(Button, { asChild: true, size: "sm", children: _jsx("a", { href: navigation.cta.href, children: navigation.cta.label }) }))] }), _jsx("div", { className: "md:hidden", children: _jsx(ClientOnly, { fallback: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Toggle menu", children: _jsx(Menu, { className: "size-5" }) }), children: _jsxs(Sheet, { children: [_jsx(SheetTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Toggle menu", children: _jsx(Menu, { className: "size-5" }) }) }), _jsxs(SheetContent, { side: "right", children: [_jsx(SheetTitle, { className: "sr-only", children: "Navigation" }), _jsxs("nav", { className: "flex flex-col gap-4 mt-8", children: [navigation.items.map((item) => (_jsx("a", { href: resolveHref(item.href), className: "text-sm font-medium text-muted-foreground hover:text-foreground transition-colors", children: item.label }, item.href))), navigation.cta && (_jsx(Button, { asChild: true, className: "mt-2", children: _jsx("a", { href: navigation.cta.href, children: navigation.cta.label }) }))] })] })] }) }) })] }) }) }));
14
15
  }
15
16
  //# sourceMappingURL=Header.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Header.js","sourceRoot":"","sources":["../../src/layout/Header.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Header.js","sourceRoot":"","sources":["../../src/layout/Header.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FAQ.d.ts","sourceRoot":"","sources":["../../src/marketing/FAQ.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,YAAY,2CAS3D;AAED,UAAU,QAAQ;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,QAAQ,2CAgBjE"}
1
+ {"version":3,"file":"FAQ.d.ts","sourceRoot":"","sources":["../../src/marketing/FAQ.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,YAAY,2CAY3D;AAED,UAAU,QAAQ;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,QAAQ,2CAgBjE"}
@@ -1,11 +1,10 @@
1
- 'use client';
2
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ChevronDownIcon } from 'lucide-react';
3
3
  import { Section } from '../ui/section';
4
- import { Accordion, AccordionItem, AccordionTrigger, AccordionContent, } from '../ui/accordion';
5
4
  export function FAQItem({ question, children }) {
6
- return (_jsxs(AccordionItem, { value: question, children: [_jsx(AccordionTrigger, { children: question }), _jsx(AccordionContent, { children: _jsx("div", { className: "text-muted-foreground leading-relaxed", children: children }) })] }));
5
+ return (_jsxs("details", { className: "border-border dark:border-border/15 border-b group", children: [_jsxs("summary", { className: "flex flex-1 items-center justify-between py-4 text-left text-md font-medium transition-all hover:underline cursor-pointer list-none [&::-webkit-details-marker]:hidden", children: [question, _jsx(ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 transition-transform duration-200 group-open:rotate-180" })] }), _jsx("div", { className: "pb-4 text-sm text-muted-foreground leading-relaxed", children: children })] }));
7
6
  }
8
7
  export function FAQ({ id, title, description, children }) {
9
- return (_jsx(Section, { id: id, children: _jsxs("div", { className: "container-main max-w-3xl", children: [(title || description) && (_jsxs("div", { className: "text-center mb-12", children: [title && _jsx("h2", { className: "text-3xl md:text-4xl font-bold text-foreground mb-4", children: title }), description && _jsx("p", { className: "text-lg text-muted-foreground", children: description })] })), _jsx(Accordion, { type: "single", collapsible: true, children: children })] }) }));
8
+ return (_jsx(Section, { id: id, children: _jsxs("div", { className: "container-main max-w-3xl", children: [(title || description) && (_jsxs("div", { className: "text-center mb-12", children: [title && _jsx("h2", { className: "text-3xl md:text-4xl font-bold text-foreground mb-4", children: title }), description && _jsx("p", { className: "text-lg text-muted-foreground", children: description })] })), _jsx("div", { "data-slot": "accordion", "data-orientation": "vertical", children: children })] }) }));
10
9
  }
11
10
  //# sourceMappingURL=FAQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FAQ.js","sourceRoot":"","sources":["../../src/marketing/FAQ.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EACL,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAOzB,MAAM,UAAU,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAgB;IAC1D,OAAO,CACL,MAAC,aAAa,IAAC,KAAK,EAAE,QAAQ,aAC5B,KAAC,gBAAgB,cAAE,QAAQ,GAAoB,EAC/C,KAAC,gBAAgB,cACf,cAAK,SAAS,EAAC,uCAAuC,YAAE,QAAQ,GAAO,GACtD,IACL,CACjB,CAAC;AACJ,CAAC;AASD,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAY;IAChE,OAAO,CACL,KAAC,OAAO,IAAC,EAAE,EAAE,EAAE,YACb,eAAK,SAAS,EAAC,0BAA0B,aACtC,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CACzB,eAAK,SAAS,EAAC,mBAAmB,aAC/B,KAAK,IAAI,aAAI,SAAS,EAAC,qDAAqD,YAAE,KAAK,GAAM,EACzF,WAAW,IAAI,YAAG,SAAS,EAAC,+BAA+B,YAAE,WAAW,GAAK,IAC1E,CACP,EACD,KAAC,SAAS,IAAC,IAAI,EAAC,QAAQ,EAAC,WAAW,kBACjC,QAAQ,GACC,IACR,GACE,CACX,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"FAQ.js","sourceRoot":"","sources":["../../src/marketing/FAQ.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAOxC,MAAM,UAAU,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAgB;IAC1D,OAAO,CACL,mBAAS,SAAS,EAAC,oDAAoD,aACrE,mBAAS,SAAS,EAAC,wKAAwK,aACxL,QAAQ,EACT,KAAC,eAAe,IAAC,SAAS,EAAC,mHAAmH,GAAG,IACzI,EACV,cAAK,SAAS,EAAC,oDAAoD,YAChE,QAAQ,GACL,IACE,CACX,CAAC;AACJ,CAAC;AASD,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAY;IAChE,OAAO,CACL,KAAC,OAAO,IAAC,EAAE,EAAE,EAAE,YACb,eAAK,SAAS,EAAC,0BAA0B,aACtC,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CACzB,eAAK,SAAS,EAAC,mBAAmB,aAC/B,KAAK,IAAI,aAAI,SAAS,EAAC,qDAAqD,YAAE,KAAK,GAAM,EACzF,WAAW,IAAI,YAAG,SAAS,EAAC,+BAA+B,YAAE,WAAW,GAAK,IAC1E,CACP,EACD,2BAAe,WAAW,sBAAkB,UAAU,YACnD,QAAQ,GACL,IACF,GACE,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Renders children only on the client after hydration.
4
+ * Prevents Radix UI useId() hydration mismatches between server and client.
5
+ */
6
+ export declare function ClientOnly({ children, fallback }: {
7
+ children: ReactNode;
8
+ fallback?: ReactNode;
9
+ }): ReactNode;
10
+ //# sourceMappingURL=client-only.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-only.d.ts","sourceRoot":"","sources":["../../src/ui/client-only.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAe,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,aAItG"}
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { useState, useEffect } from 'react';
3
+ /**
4
+ * Renders children only on the client after hydration.
5
+ * Prevents Radix UI useId() hydration mismatches between server and client.
6
+ */
7
+ export function ClientOnly({ children, fallback = null }) {
8
+ const [mounted, setMounted] = useState(false);
9
+ useEffect(() => setMounted(true), []);
10
+ return mounted ? children : fallback;
11
+ }
12
+ //# sourceMappingURL=client-only.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-only.js","sourceRoot":"","sources":["../../src/ui/client-only.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,EAAiD;IACrG,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,SAAS,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;AACvC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"locale-switcher.d.ts","sourceRoot":"","sources":["../../src/ui/locale-switcher.tsx"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,mDA6C7B"}
1
+ {"version":3,"file":"locale-switcher.d.ts","sourceRoot":"","sources":["../../src/ui/locale-switcher.tsx"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,mDAuD7B"}
@@ -4,15 +4,25 @@ import React from 'react';
4
4
  import { usePathname } from 'next/navigation';
5
5
  import { useShipSite, useAlternateLinks } from '../context/ShipSiteProvider';
6
6
  export function LocaleSwitcher() {
7
- const { locale, locales } = useShipSite();
7
+ const { locale, locales, defaultLocale } = useShipSite();
8
8
  const alternatePathMap = useAlternateLinks();
9
9
  const pathname = usePathname();
10
10
  if (locales.length <= 1)
11
11
  return null;
12
+ // Normalize pathname: with localePrefix:"as-needed", usePathname() may
13
+ // include the default locale prefix on the server (e.g. /en or /en/page)
14
+ // but alternatePathMap uses paths without it (e.g. / or /page).
15
+ let normalizedPathname = pathname;
16
+ if (pathname === `/${defaultLocale}`) {
17
+ normalizedPathname = '/';
18
+ }
19
+ else if (pathname.startsWith(`/${defaultLocale}/`)) {
20
+ normalizedPathname = pathname.slice(defaultLocale.length + 1);
21
+ }
12
22
  // Find the alternatePathMap entry where the current locale's path matches
13
23
  let alternates;
14
24
  for (const entry of Object.values(alternatePathMap)) {
15
- if (entry[locale] === pathname) {
25
+ if (entry[locale] === normalizedPathname) {
16
26
  alternates = entry;
17
27
  break;
18
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"locale-switcher.js","sourceRoot":"","sources":["../../src/ui/locale-switcher.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC;IAC1C,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,0EAA0E;IAC1E,IAAI,UAA8C,CAAC;IACnD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/B,UAAU,GAAG,KAAK,CAAC;YACnB,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,CACL,cAAK,SAAS,EAAC,mCAAmC,YAC/C,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,GAAG,KAAK,MAAM,CAAC;YAEhC,OAAO,CACL,MAAC,KAAK,CAAC,QAAQ,eACZ,CAAC,GAAG,CAAC,IAAI,eAAM,SAAS,EAAC,uBAAuB,uBAAS,EACzD,QAAQ,CAAC,CAAC,CAAC,CACV,eAAM,SAAS,EAAC,yCAAyC,YACtD,GAAG,GACC,CACR,CAAC,CAAC,CAAC,CACF,YACE,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,GAAG,EAAE;4BACZ,QAAQ,CAAC,MAAM,GAAG,eAAe,GAAG,0CAA0C,CAAC;wBACjF,CAAC,EACD,SAAS,EAAC,yEAAyE,YAElF,GAAG,GACF,CACL,KAhBkB,GAAG,CAiBP,CAClB,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"locale-switcher.js","sourceRoot":"","sources":["../../src/ui/locale-switcher.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,WAAW,EAAE,CAAC;IACzD,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,uEAAuE;IACvE,yEAAyE;IACzE,gEAAgE;IAChE,IAAI,kBAAkB,GAAG,QAAQ,CAAC;IAClC,IAAI,QAAQ,KAAK,IAAI,aAAa,EAAE,EAAE,CAAC;QACrC,kBAAkB,GAAG,GAAG,CAAC;IAC3B,CAAC;SAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACrD,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,0EAA0E;IAC1E,IAAI,UAA8C,CAAC;IACnD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,kBAAkB,EAAE,CAAC;YACzC,UAAU,GAAG,KAAK,CAAC;YACnB,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,CACL,cAAK,SAAS,EAAC,mCAAmC,YAC/C,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,GAAG,KAAK,MAAM,CAAC;YAEhC,OAAO,CACL,MAAC,KAAK,CAAC,QAAQ,eACZ,CAAC,GAAG,CAAC,IAAI,eAAM,SAAS,EAAC,uBAAuB,uBAAS,EACzD,QAAQ,CAAC,CAAC,CAAC,CACV,eAAM,SAAS,EAAC,yCAAyC,YACtD,GAAG,GACC,CACR,CAAC,CAAC,CAAC,CACF,YACE,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,GAAG,EAAE;4BACZ,QAAQ,CAAC,MAAM,GAAG,eAAe,GAAG,0CAA0C,CAAC;wBACjF,CAAC,EACD,SAAS,EAAC,yEAAyE,YAElF,GAAG,GACF,CACL,KAhBkB,GAAG,CAiBP,CAClB,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipsite.dev/components",
3
- "version": "0.2.43",
3
+ "version": "0.2.44",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/shipsite/shipsite",
@@ -13,6 +13,7 @@ import {
13
13
  SheetTitle,
14
14
  } from '../ui/sheet';
15
15
  import { ThemeToggle } from '../ui/theme-toggle';
16
+ import { ClientOnly } from '../ui/client-only';
16
17
 
17
18
  export function Header() {
18
19
  const { siteName, logo, navigation, locale, defaultLocale } = useShipSite();
@@ -59,34 +60,40 @@ export function Header() {
59
60
  </NavbarRight>
60
61
 
61
62
  <div className="md:hidden">
62
- <Sheet>
63
- <SheetTrigger asChild>
64
- <Button variant="ghost" size="icon" aria-label="Toggle menu">
65
- <Menu className="size-5" />
66
- </Button>
67
- </SheetTrigger>
68
- <SheetContent side="right">
69
- <SheetTitle className="sr-only">Navigation</SheetTitle>
70
- <nav className="flex flex-col gap-4 mt-8">
71
- {navigation.items.map((item) => (
72
- <a
73
- key={item.href}
74
- href={resolveHref(item.href)}
75
- className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors"
76
- >
77
- {item.label}
78
- </a>
79
- ))}
80
- {navigation.cta && (
81
- <Button asChild className="mt-2">
82
- <a href={navigation.cta.href}>
83
- {navigation.cta.label}
63
+ <ClientOnly fallback={
64
+ <Button variant="ghost" size="icon" aria-label="Toggle menu">
65
+ <Menu className="size-5" />
66
+ </Button>
67
+ }>
68
+ <Sheet>
69
+ <SheetTrigger asChild>
70
+ <Button variant="ghost" size="icon" aria-label="Toggle menu">
71
+ <Menu className="size-5" />
72
+ </Button>
73
+ </SheetTrigger>
74
+ <SheetContent side="right">
75
+ <SheetTitle className="sr-only">Navigation</SheetTitle>
76
+ <nav className="flex flex-col gap-4 mt-8">
77
+ {navigation.items.map((item) => (
78
+ <a
79
+ key={item.href}
80
+ href={resolveHref(item.href)}
81
+ className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors"
82
+ >
83
+ {item.label}
84
84
  </a>
85
- </Button>
86
- )}
87
- </nav>
88
- </SheetContent>
89
- </Sheet>
85
+ ))}
86
+ {navigation.cta && (
87
+ <Button asChild className="mt-2">
88
+ <a href={navigation.cta.href}>
89
+ {navigation.cta.label}
90
+ </a>
91
+ </Button>
92
+ )}
93
+ </nav>
94
+ </SheetContent>
95
+ </Sheet>
96
+ </ClientOnly>
90
97
  </div>
91
98
  </Navbar>
92
99
  </div>
@@ -1,13 +1,6 @@
1
- 'use client';
2
-
3
1
  import React from 'react';
2
+ import { ChevronDownIcon } from 'lucide-react';
4
3
  import { Section } from '../ui/section';
5
- import {
6
- Accordion,
7
- AccordionItem,
8
- AccordionTrigger,
9
- AccordionContent,
10
- } from '../ui/accordion';
11
4
 
12
5
  interface FAQItemProps {
13
6
  question: string;
@@ -16,12 +9,15 @@ interface FAQItemProps {
16
9
 
17
10
  export function FAQItem({ question, children }: FAQItemProps) {
18
11
  return (
19
- <AccordionItem value={question}>
20
- <AccordionTrigger>{question}</AccordionTrigger>
21
- <AccordionContent>
22
- <div className="text-muted-foreground leading-relaxed">{children}</div>
23
- </AccordionContent>
24
- </AccordionItem>
12
+ <details className="border-border dark:border-border/15 border-b group">
13
+ <summary className="flex flex-1 items-center justify-between py-4 text-left text-md font-medium transition-all hover:underline cursor-pointer list-none [&::-webkit-details-marker]:hidden">
14
+ {question}
15
+ <ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 transition-transform duration-200 group-open:rotate-180" />
16
+ </summary>
17
+ <div className="pb-4 text-sm text-muted-foreground leading-relaxed">
18
+ {children}
19
+ </div>
20
+ </details>
25
21
  );
26
22
  }
27
23
 
@@ -42,9 +38,9 @@ export function FAQ({ id, title, description, children }: FAQProps) {
42
38
  {description && <p className="text-lg text-muted-foreground">{description}</p>}
43
39
  </div>
44
40
  )}
45
- <Accordion type="single" collapsible>
41
+ <div data-slot="accordion" data-orientation="vertical">
46
42
  {children}
47
- </Accordion>
43
+ </div>
48
44
  </div>
49
45
  </Section>
50
46
  );
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect, type ReactNode } from 'react';
4
+
5
+ /**
6
+ * Renders children only on the client after hydration.
7
+ * Prevents Radix UI useId() hydration mismatches between server and client.
8
+ */
9
+ export function ClientOnly({ children, fallback = null }: { children: ReactNode; fallback?: ReactNode }) {
10
+ const [mounted, setMounted] = useState(false);
11
+ useEffect(() => setMounted(true), []);
12
+ return mounted ? children : fallback;
13
+ }
@@ -5,16 +5,26 @@ import { usePathname } from 'next/navigation';
5
5
  import { useShipSite, useAlternateLinks } from '../context/ShipSiteProvider';
6
6
 
7
7
  export function LocaleSwitcher() {
8
- const { locale, locales } = useShipSite();
8
+ const { locale, locales, defaultLocale } = useShipSite();
9
9
  const alternatePathMap = useAlternateLinks();
10
10
  const pathname = usePathname();
11
11
 
12
12
  if (locales.length <= 1) return null;
13
13
 
14
+ // Normalize pathname: with localePrefix:"as-needed", usePathname() may
15
+ // include the default locale prefix on the server (e.g. /en or /en/page)
16
+ // but alternatePathMap uses paths without it (e.g. / or /page).
17
+ let normalizedPathname = pathname;
18
+ if (pathname === `/${defaultLocale}`) {
19
+ normalizedPathname = '/';
20
+ } else if (pathname.startsWith(`/${defaultLocale}/`)) {
21
+ normalizedPathname = pathname.slice(defaultLocale.length + 1);
22
+ }
23
+
14
24
  // Find the alternatePathMap entry where the current locale's path matches
15
25
  let alternates: Record<string, string> | undefined;
16
26
  for (const entry of Object.values(alternatePathMap)) {
17
- if (entry[locale] === pathname) {
27
+ if (entry[locale] === normalizedPathname) {
18
28
  alternates = entry;
19
29
  break;
20
30
  }