@next-library/theme 1.0.10 → 1.0.12

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/dist/client.js CHANGED
@@ -10,7 +10,7 @@ import Link3 from 'next/link';
10
10
  import Image from 'next/image';
11
11
  import { createPortal } from 'react-dom';
12
12
  import { useRouter } from 'next/navigation';
13
- import { Search, Loader2, ArrowUp, ArrowDown, CornerDownLeft, CheckIcon, CircleIcon, ChevronRightIcon, LanguagesIcon, XIcon, PanelLeftIcon, FolderOpenIcon, FolderClosedIcon, ChevronRight, ChevronDown, FileTextIcon, Menu, GithubIcon, MoreHorizontal, Home, ExternalLinkIcon, CopyIcon, ChevronDownIcon, CookieIcon, ChevronUpIcon, FolderUp, ChevronLeft, Check, Copy } from 'lucide-react';
13
+ import { Search, Loader2, ArrowUp, ArrowDown, CornerDownLeft, CheckIcon, CircleIcon, ChevronRightIcon, LanguagesIcon, XIcon, PanelLeftIcon, FolderOpenIcon, FolderClosedIcon, ChevronRight, ChevronDown, FileTextIcon, Menu, Star, GithubIcon, MoreHorizontal, Home, ExternalLinkIcon, CopyIcon, CookieIcon, ChevronDownIcon, ChevronUpIcon, FolderUp, ChevronLeft, Check, Copy } from 'lucide-react';
14
14
  import { useTheme } from 'next-themes';
15
15
  import { useLocale } from '@next-library/core/hooks';
16
16
  import { Slot } from '@radix-ui/react-slot';
@@ -21,7 +21,6 @@ import * as SeparatorPrimitive from '@radix-ui/react-separator';
21
21
  import * as SheetPrimitive from '@radix-ui/react-dialog';
22
22
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
23
23
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
24
- import GitHubButton from 'react-github-btn';
25
24
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
26
25
  import ReactMarkdown from 'react-markdown';
27
26
  import remarkGfm from 'remark-gfm';
@@ -4210,43 +4209,82 @@ function MobileMenu({ pageData, translations: translations2 = {} }) {
4210
4209
  ] })
4211
4210
  ] }) });
4212
4211
  }
4212
+ var CACHE_TTL_MS = 60 * 60 * 1e3;
4213
+ function parseGithubRepo(repoUrl) {
4214
+ const match = repoUrl.match(/^https?:\/\/(?:www\.)?github\.com\/([^/\s]+)\/([^/\s#?]+)/i);
4215
+ if (!match) return null;
4216
+ return `${match[1]}/${match[2].replace(/\.git$/, "")}`;
4217
+ }
4218
+ function formatStarCount(count) {
4219
+ if (count < 1e3) return String(count);
4220
+ const k = count / 1e3;
4221
+ return `${k >= 10 ? Math.round(k) : Math.round(k * 10) / 10}k`;
4222
+ }
4223
+ function readCachedCount(repo) {
4224
+ try {
4225
+ const raw = sessionStorage.getItem(`nl-stars:${repo}`);
4226
+ if (!raw) return null;
4227
+ const { count, at } = JSON.parse(raw);
4228
+ return Date.now() - at < CACHE_TTL_MS ? count : null;
4229
+ } catch {
4230
+ return null;
4231
+ }
4232
+ }
4233
+ function writeCachedCount(repo, count) {
4234
+ try {
4235
+ sessionStorage.setItem(`nl-stars:${repo}`, JSON.stringify({ count, at: Date.now() }));
4236
+ } catch {
4237
+ }
4238
+ }
4213
4239
  function GithubStar({ repoUrl }) {
4214
- const [isVisible, setIsVisible] = useState(false);
4240
+ const repo = repoUrl ? parseGithubRepo(repoUrl) : null;
4241
+ const [count, setCount] = useState(null);
4215
4242
  useEffect(() => {
4216
- const timer = setTimeout(() => {
4217
- setIsVisible(true);
4218
- }, 500);
4219
- return () => clearTimeout(timer);
4220
- }, []);
4243
+ if (!repo) return;
4244
+ const cached = readCachedCount(repo);
4245
+ if (cached !== null) {
4246
+ setCount(cached);
4247
+ return;
4248
+ }
4249
+ const controller = new AbortController();
4250
+ fetch(`https://api.github.com/repos/${repo}`, {
4251
+ signal: controller.signal,
4252
+ headers: { Accept: "application/vnd.github+json" }
4253
+ }).then((res) => res.ok ? res.json() : null).then((data) => {
4254
+ if (data && typeof data.stargazers_count === "number") {
4255
+ writeCachedCount(repo, data.stargazers_count);
4256
+ setCount(data.stargazers_count);
4257
+ }
4258
+ }).catch(() => {
4259
+ });
4260
+ return () => controller.abort();
4261
+ }, [repo]);
4221
4262
  if (!repoUrl) {
4222
4263
  return null;
4223
4264
  }
4224
- return /* @__PURE__ */ jsxs("div", { className: "h-5 relative flex items-center", children: [
4225
- !isVisible && /* @__PURE__ */ jsx(Skeleton, { className: "w-16 h-5 rounded-xs" }),
4226
- /* @__PURE__ */ jsx(
4227
- "div",
4228
- {
4229
- className: isVisible ? "opacity-100" : "opacity-0",
4230
- style: {
4231
- transition: "opacity 0.3s ease-in",
4232
- pointerEvents: isVisible ? "auto" : "none",
4233
- minHeight: "20px"
4234
- // Prevent layout shift
4235
- },
4236
- children: /* @__PURE__ */ jsx(
4237
- GitHubButton,
4265
+ return /* @__PURE__ */ jsxs(
4266
+ "a",
4267
+ {
4268
+ href: repoUrl,
4269
+ target: "_blank",
4270
+ rel: "noopener noreferrer",
4271
+ "aria-label": "Star on GitHub",
4272
+ "data-testid": "github-star-link",
4273
+ className: "ml-1 inline-flex h-8 items-center gap-1.5 rounded-md border px-2.5 text-[13px] font-medium text-foreground transition-colors hover:bg-accent",
4274
+ children: [
4275
+ /* @__PURE__ */ jsx(Star, { className: "size-3.5", "aria-hidden": "true" }),
4276
+ /* @__PURE__ */ jsx("span", { children: "Star" }),
4277
+ count !== null && /* @__PURE__ */ jsx(
4278
+ "span",
4238
4279
  {
4239
- href: repoUrl,
4240
- "data-color-scheme": "no-preference: dark-high-contrast; light: light; dark: dark-high-contrast;",
4241
- "data-icon": "octicon-star",
4242
- "data-show-count": "true",
4243
- "aria-label": "Star on GitHub",
4244
- children: "Star"
4280
+ className: "ml-0.5 border-l pl-2 tabular-nums text-muted-foreground",
4281
+ "data-testid": "github-star-count",
4282
+ children: formatStarCount(count)
4245
4283
  }
4246
4284
  )
4247
- }
4248
- )
4249
- ] });
4285
+ ]
4286
+ }
4287
+ );
4250
4288
  }
4251
4289
  function GithubLink({ language = "en", repoUrl }) {
4252
4290
  if (!repoUrl) {
@@ -4952,56 +4990,47 @@ function CopyPageButton({
4952
4990
  const claudeUrl = `https://claude.ai/new?q=${encodedMessage}`;
4953
4991
  window.open(claudeUrl, "_blank", "noopener,noreferrer");
4954
4992
  }
4955
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
4956
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
4957
- Button,
4958
- {
4959
- variant: "outline",
4960
- size: "sm",
4961
- className: cn(
4962
- "flex gap-2 text-sm font-medium items-center",
4963
- isCopied && "opacity-70",
4964
- className
4993
+ const segment = "inline-flex h-8 items-center gap-1.5 whitespace-nowrap px-2.5 text-[13px] font-medium text-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50";
4994
+ return /* @__PURE__ */ jsxs(
4995
+ "div",
4996
+ {
4997
+ role: "group",
4998
+ "aria-label": _askAboutThisPage,
4999
+ className: cn(
5000
+ // Segmented control: one border, dividers between the three actions.
5001
+ "inline-flex items-stretch overflow-hidden rounded-md border bg-card shadow-xs divide-x divide-border",
5002
+ className
5003
+ ),
5004
+ children: [
5005
+ /* @__PURE__ */ jsxs(
5006
+ "button",
5007
+ {
5008
+ type: "button",
5009
+ onClick: handleCopy,
5010
+ title: copyPageDescription,
5011
+ "aria-live": "polite",
5012
+ className: cn(segment, isCopied && "text-muted-foreground"),
5013
+ children: [
5014
+ isCopied ? /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5", "aria-hidden": true }) : /* @__PURE__ */ jsx(CopyIcon, { className: "size-3.5", "aria-hidden": true }),
5015
+ isCopied ? copied : copyPage
5016
+ ]
5017
+ }
4965
5018
  ),
4966
- children: [
4967
- /* @__PURE__ */ jsx(CopyIcon, { width: "16" }),
4968
- isCopied ? copied : copyPage,
4969
- /* @__PURE__ */ jsx(ChevronDownIcon, { width: "14", className: "opacity-50" })
4970
- ]
4971
- }
4972
- ) }),
4973
- /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "min-w-[200px]", children: [
4974
- /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: handleCopy, children: [
4975
- /* @__PURE__ */ jsx(CopyIcon, { width: "16", className: "mr-2" }),
4976
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
4977
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: copyPage }),
4978
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: copyPageDescription })
4979
- ] })
4980
- ] }),
4981
- pageUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
4982
- /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: handleOpenInChatGPT, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4983
- /* @__PURE__ */ jsx(ChatGPTIcon, { className: "w-4 h-4 shrink-0" }),
4984
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1", children: [
4985
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
4986
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: openInChatGPT }),
4987
- /* @__PURE__ */ jsx(ExternalLinkIcon, { width: "12", className: "text-muted-foreground shrink-0" })
4988
- ] }),
4989
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: askQuestionsDescription })
4990
- ] })
4991
- ] }) }),
4992
- /* @__PURE__ */ jsx(DropdownMenuItem, { onClick: handleOpenInClaude, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4993
- /* @__PURE__ */ jsx(ClaudeIcon, { className: "w-4 h-4 shrink-0" }),
4994
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1", children: [
4995
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
4996
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: openInClaude }),
4997
- /* @__PURE__ */ jsx(ExternalLinkIcon, { width: "12", className: "text-muted-foreground shrink-0" })
4998
- ] }),
4999
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: askQuestionsDescription })
5019
+ pageUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
5020
+ /* @__PURE__ */ jsxs("button", { type: "button", onClick: handleOpenInChatGPT, title: askQuestionsDescription, className: segment, children: [
5021
+ /* @__PURE__ */ jsx(ChatGPTIcon, { className: "size-3.5 shrink-0" }),
5022
+ /* @__PURE__ */ jsx("span", { children: openInChatGPT }),
5023
+ /* @__PURE__ */ jsx(ExternalLinkIcon, { className: "size-3 text-muted-foreground", "aria-hidden": true })
5024
+ ] }),
5025
+ /* @__PURE__ */ jsxs("button", { type: "button", onClick: handleOpenInClaude, title: askQuestionsDescription, className: segment, children: [
5026
+ /* @__PURE__ */ jsx(ClaudeIcon, { className: "size-3.5 shrink-0" }),
5027
+ /* @__PURE__ */ jsx("span", { children: openInClaude }),
5028
+ /* @__PURE__ */ jsx(ExternalLinkIcon, { className: "size-3 text-muted-foreground", "aria-hidden": true })
5000
5029
  ] })
5001
- ] }) })
5002
- ] })
5003
- ] })
5004
- ] });
5030
+ ] })
5031
+ ]
5032
+ }
5033
+ );
5005
5034
  }
5006
5035
  function track(event, data) {
5007
5036
  if (typeof window !== "undefined") {