@docubook/create 2.4.0 → 2.5.1

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.
Files changed (54) hide show
  1. package/package.json +1 -1
  2. package/src/dist/app/docs/[[...slug]]/page.tsx +55 -59
  3. package/src/dist/app/docs/layout.tsx +11 -4
  4. package/src/dist/app/layout.tsx +10 -7
  5. package/src/dist/app/page.tsx +1 -1
  6. package/src/dist/components/{context-popover.tsx → ContextPopover.tsx} +3 -2
  7. package/src/dist/components/DocSearch.tsx +16 -15
  8. package/src/dist/components/{docs-breadcrumb.tsx → DocsBreadcrumb.tsx} +1 -1
  9. package/src/dist/components/DocsNavbar.tsx +46 -0
  10. package/src/dist/components/DocsSidebar.tsx +207 -0
  11. package/src/dist/components/Github.tsx +26 -0
  12. package/src/dist/components/{scroll-to-top.tsx → ScrollToTop.tsx} +16 -9
  13. package/src/dist/components/SearchBox.tsx +39 -0
  14. package/src/dist/components/SearchContext.tsx +47 -0
  15. package/src/dist/components/SearchModal.tsx +77 -79
  16. package/src/dist/components/SearchTrigger.tsx +20 -15
  17. package/src/dist/components/Sponsor.tsx +2 -2
  18. package/src/dist/components/{theme-toggle.tsx → ThemeToggle.tsx} +10 -10
  19. package/src/dist/components/TocObserver.tsx +197 -0
  20. package/src/dist/components/footer.tsx +16 -12
  21. package/src/dist/components/leftbar.tsx +45 -73
  22. package/src/dist/components/markdown/AccordionContext.tsx +21 -0
  23. package/src/dist/components/markdown/AccordionGroupMdx.tsx +11 -22
  24. package/src/dist/components/markdown/AccordionMdx.tsx +58 -59
  25. package/src/dist/components/markdown/PreMdx.tsx +2 -2
  26. package/src/dist/components/navbar.tsx +130 -53
  27. package/src/dist/components/toc.tsx +16 -14
  28. package/src/dist/components/typography.tsx +1 -1
  29. package/src/dist/components/ui/icon-cloud.tsx +353 -0
  30. package/src/dist/components/ui/scroll-area.tsx +2 -2
  31. package/src/dist/components/ui/sheet.tsx +4 -4
  32. package/src/dist/components/ui/toggle.tsx +3 -3
  33. package/src/dist/docs/components/accordion-group.mdx +13 -12
  34. package/src/dist/docs/components/accordion.mdx +11 -14
  35. package/src/dist/docu.json +3 -0
  36. package/src/dist/hooks/useActiveSection.ts +45 -33
  37. package/src/dist/hooks/useScrollPosition.ts +16 -14
  38. package/src/dist/lib/search/algolia.ts +5 -0
  39. package/src/dist/lib/search/built-in.ts +43 -0
  40. package/src/dist/lib/search/config.ts +7 -0
  41. package/src/dist/lib/toc.ts +1 -0
  42. package/src/dist/lib/utils.ts +13 -54
  43. package/src/dist/package.json +1 -1
  44. package/src/dist/styles/algolia.css +12 -35
  45. package/src/dist/styles/{syntax.css → override.css} +82 -39
  46. package/src/dist/tailwind.config.ts +11 -110
  47. package/src/dist/components/AccordionContext.ts +0 -4
  48. package/src/dist/components/GithubStart.tsx +0 -44
  49. package/src/dist/components/mob-toc.tsx +0 -134
  50. package/src/dist/components/search.tsx +0 -55
  51. package/src/dist/components/toc-observer.tsx +0 -254
  52. /package/src/dist/components/{docs-menu.tsx → DocsMenu.tsx} +0 -0
  53. /package/src/dist/components/{edit-on-github.tsx → EditWithGithub.tsx} +0 -0
  54. /package/src/dist/components/{theme-provider.tsx → ThemeProvider.tsx} +0 -0
@@ -7,7 +7,7 @@ import { cva, type VariantProps } from "class-variance-authority"
7
7
  import { cn } from "@/lib/utils"
8
8
 
9
9
  const toggleVariants = cva(
10
- "inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
10
+ "inline-flex items-center justify-center gap-1 rounded-md text-xs font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-3 [&_svg]:shrink-0",
11
11
  {
12
12
  variants: {
13
13
  variant: {
@@ -18,7 +18,7 @@ const toggleVariants = cva(
18
18
  size: {
19
19
  default: "h-9 px-2 min-w-9",
20
20
  sm: "h-8 px-1.5 min-w-8",
21
- xs: "h-7 px-1 min-w-7",
21
+ xs: "h-6 px-1.5 min-w-6",
22
22
  lg: "h-10 px-2.5 min-w-10",
23
23
  },
24
24
  },
@@ -32,7 +32,7 @@ const toggleVariants = cva(
32
32
  const Toggle = React.forwardRef<
33
33
  React.ElementRef<typeof TogglePrimitive.Root>,
34
34
  React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
35
- VariantProps<typeof toggleVariants>
35
+ VariantProps<typeof toggleVariants>
36
36
  >(({ className, variant, size, ...props }, ref) => (
37
37
  <TogglePrimitive.Root
38
38
  ref={ref}
@@ -1,10 +1,11 @@
1
1
  ---
2
- title : Accordion Group
2
+ title: Accordion Group
3
3
  description: for writing multiple accordions and grouping them together
4
- date : 10-08-2025
4
+ date: 10-08-2025
5
5
  ---
6
6
 
7
- An accordion is like a button that opens and closes information. To avoid clutter, long information can be hidden first and then revealed when clicked.
7
+ An accordion is like a button that opens and closes information. To avoid clutter, long information
8
+ can be hidden first and then revealed when clicked.
8
9
 
9
10
  <Note type="note" title="Note">
10
11
  Group related accordions together using `<AccordionGroup>`. This creates a cohesive section of accordions that can be individually expanded or collapsed.
@@ -18,10 +19,11 @@ An accordion is like a button that opens and closes information. To avoid clutte
18
19
  </Accordion>
19
20
 
20
21
  <Accordion title="With icon props" icon="MousePointerClick">
21
- This accordion includes a [Lucide Icon](https://lucide.dev/icons/) because the `icon` prop is provided.
22
+ This accordion includes a [Lucide Icon](https://lucide.dev/icons/) because the `icon` prop is
23
+ provided.
22
24
  </Accordion>
23
25
 
24
- <Accordion title="Expanded by Default" defaultOpen>
26
+ <Accordion title="With Code Block">
25
27
  You can put other components inside Accordions.
26
28
  ```jsx:helloword.jsx
27
29
  class HelloWorld {
@@ -45,7 +47,7 @@ public static void main(String[] args) {
45
47
  This accordion includes a Lucide icon because the `icon` prop is provided.
46
48
  </Accordion>
47
49
 
48
- <Accordion title="Expanded by Default" defaultOpen>
50
+ <Accordion title="With Code Block">
49
51
  You can put other components inside Accordions.
50
52
  ```jsx:helloword.jsx
51
53
  class HelloWorld {
@@ -60,9 +62,8 @@ public static void main(String[] args) {
60
62
 
61
63
  ## Props
62
64
 
63
- | Prop | Type | Default | Description |
64
- |------|------|---------|-------------|
65
- | `title` | string | - | **Required**. The text displayed in the accordion header. |
66
- | `children` | ReactNode | null | The content to be displayed when the accordion is expanded. Can be plain text, markdown, or React components. |
67
- | `defaultOpen` | boolean | false | When true, the accordion will be expanded by default. |
68
- | `icon` | string | undefined | Optional. Adds a Lucide icon before the title in the accordion header. |
65
+ | Prop | Type | Default | Description |
66
+ | ---------- | --------- | --------- | ------------------------------------------------------------------------------------------------------------- |
67
+ | `title` | string | - | **Required**. The text displayed in the accordion header. |
68
+ | `children` | ReactNode | null | The content to be displayed when the accordion is expanded. Can be plain text, markdown, or React components. |
69
+ | `icon` | string | undefined | Optional. Adds a Lucide icon before the title in the accordion header. |
@@ -4,9 +4,7 @@ description: A component used to create collapsible content that can be hidden a
4
4
  date: 22-12-2024
5
5
  ---
6
6
 
7
- ## Preview
8
-
9
- ### Basic Usage
7
+ ## Basic Usage
10
8
 
11
9
  ```plaintext
12
10
  <Accordion title="Click to expand">
@@ -17,13 +15,14 @@ date: 22-12-2024
17
15
  Render as :
18
16
 
19
17
  <Accordion title="Click to expand">
20
- This is a simple accordion component that can be toggled by clicking the header. The content can include any valid React nodes, including text, components, and markdown.
18
+ This is a simple accordion component that can be toggled by clicking the header. The content can
19
+ include any valid React nodes, including text, components, and markdown.
21
20
  </Accordion>
22
21
 
23
- ### With Code Block
22
+ ## With Icon
24
23
 
25
24
  ````plaintext
26
- <Accordion title="Code Block" defaultOpen={true} icon="Code">
25
+ <Accordion title="Code Block" icon="Code">
27
26
  ```javascript:main.js showLineNumbers {3-4}
28
27
  function isRocketAboutToCrash() {
29
28
  // Check if the rocket is stable
@@ -37,7 +36,7 @@ Render as :
37
36
 
38
37
  Render as :
39
38
 
40
- <Accordion title="Code Block" defaultOpen={true} icon="Code">
39
+ <Accordion title="Code Block" icon="Code">
41
40
  ```javascript:main.js showLineNumbers {3-4}
42
41
  function isRocketAboutToCrash() {
43
42
  // Check if the rocket is stable
@@ -50,10 +49,8 @@ Render as :
50
49
 
51
50
  ## Props
52
51
 
53
- | Prop | Type | Default | Description |
54
- |------|------|---------|-------------|
55
- | `title` | string | - | **Required**. The text displayed in the accordion header. |
56
- | `children` | ReactNode | null | The content to be displayed when the accordion is expanded. Can be plain text, markdown, or React components. |
57
- | `defaultOpen` | boolean | false | When true, the accordion will be expanded by default. |
58
- | `icon` | string | undefined | Optional. Adds a Lucide icon before the title in the accordion header. |
59
-
52
+ | Prop | Type | Default | Description |
53
+ | ---------- | --------- | --------- | ------------------------------------------------------------------------------------------------------------- |
54
+ | `title` | string | - | **Required**. The text displayed in the accordion header. |
55
+ | `children` | ReactNode | null | The content to be displayed when the accordion is expanded. Can be plain text, markdown, or React components. |
56
+ | `icon` | string | undefined | Optional. Adds a Lucide icon before the title in the accordion header. |
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "$schema": "https://docubook.pro/docu.schema.json",
3
+ "search": {
4
+ "type": "default"
5
+ },
3
6
  "meta": {
4
7
  "baseURL": "https://docubook.pro",
5
8
  "title": "DocuBook",
@@ -1,68 +1,80 @@
1
- import { useState, useCallback, useEffect, useRef } from 'react';
2
- import { TocItem } from '@/lib/toc';
1
+ "use client"
2
+
3
+ import { useState, useCallback, useEffect, useRef } from "react"
4
+ import { TocItem } from "@/lib/toc"
3
5
 
4
6
  export function useActiveSection(tocs: TocItem[]) {
5
- const [activeId, setActiveId] = useState<string | null>(null);
6
- const observerRef = useRef<IntersectionObserver | null>(null);
7
- const clickedIdRef = useRef<string | null>(null);
7
+ const [activeId, setActiveId] = useState<string | null>(null)
8
+ const observerRef = useRef<IntersectionObserver | null>(null)
9
+ const clickedIdRef = useRef<string | null>(null)
10
+
11
+ const activeIdRef = useRef<string | null>(null)
12
+
13
+ useEffect(() => {
14
+ activeIdRef.current = activeId
15
+ }, [activeId])
8
16
 
9
17
  // Handle intersection observer for active section
10
18
  useEffect(() => {
11
- if (typeof document === 'undefined' || !tocs.length) return;
19
+ if (typeof document === "undefined" || !tocs.length) return
12
20
 
13
21
  const handleIntersect = (entries: IntersectionObserverEntry[]) => {
14
- if (clickedIdRef.current) return;
22
+ if (clickedIdRef.current) return
15
23
 
16
- const visibleEntries = entries.filter(entry => entry.isIntersecting);
17
- if (!visibleEntries.length) return;
24
+ const visibleEntries = entries.filter((entry) => entry.isIntersecting)
25
+ if (!visibleEntries.length) return
18
26
 
19
27
  // Find the most visible entry
20
28
  const mostVisibleEntry = visibleEntries.reduce((prev, current) => {
21
- return current.intersectionRatio > prev.intersectionRatio ? current : prev;
22
- }, visibleEntries[0]);
29
+ return current.intersectionRatio > prev.intersectionRatio ? current : prev
30
+ }, visibleEntries[0])
23
31
 
24
- const newActiveId = mostVisibleEntry.target.id;
25
- if (newActiveId !== activeId) {
26
- setActiveId(newActiveId);
32
+ const newActiveId = mostVisibleEntry.target.id
33
+ if (newActiveId !== activeIdRef.current) {
34
+ setActiveId(newActiveId)
27
35
  }
28
- };
36
+ }
37
+
38
+ // Determine the scroll root: #scroll-container is only used on desktop (lg)
39
+ const isDesktop = window.innerWidth >= 1024
40
+ const container = isDesktop ? document.getElementById("scroll-container") : null
29
41
 
30
42
  // Initialize intersection observer
31
43
  observerRef.current = new IntersectionObserver(handleIntersect, {
32
- root: null,
33
- rootMargin: '0px 0px -80% 0px',
34
- threshold: 0.1,
35
- });
44
+ root: container,
45
+ rootMargin: isDesktop ? "0px 0px -60% 0px" : "-160px 0px -60% 0px",
46
+ threshold: 0,
47
+ })
36
48
 
37
49
  // Observe all headings
38
- tocs.forEach(toc => {
39
- const element = document.getElementById(toc.href.slice(1));
50
+ tocs.forEach((toc) => {
51
+ const element = document.getElementById(toc.href.slice(1))
40
52
  if (element) {
41
- observerRef.current?.observe(element);
53
+ observerRef.current?.observe(element)
42
54
  }
43
- });
55
+ })
44
56
 
45
57
  // Cleanup
46
58
  return () => {
47
- observerRef.current?.disconnect();
48
- };
49
- }, [tocs, activeId]);
59
+ observerRef.current?.disconnect()
60
+ }
61
+ }, [tocs]) // Only depend on tocs, handle activeId via ref
50
62
 
51
63
  const handleLinkClick = useCallback((id: string) => {
52
- clickedIdRef.current = id;
53
- setActiveId(id);
64
+ clickedIdRef.current = id
65
+ setActiveId(id)
54
66
 
55
67
  // Reset clicked state after scroll completes
56
68
  const timer = setTimeout(() => {
57
- clickedIdRef.current = null;
58
- }, 1000);
69
+ clickedIdRef.current = null
70
+ }, 1000)
59
71
 
60
- return () => clearTimeout(timer);
61
- }, []);
72
+ return () => clearTimeout(timer)
73
+ }, [])
62
74
 
63
75
  return {
64
76
  activeId,
65
77
  setActiveId,
66
78
  handleLinkClick,
67
- };
79
+ }
68
80
  }
@@ -1,29 +1,31 @@
1
- import { useState, useCallback, useEffect } from 'react';
1
+ "use client"
2
+
3
+ import { useState, useCallback, useEffect } from "react"
2
4
 
3
5
  export function useScrollPosition(threshold = 0.5) {
4
- const [isScrolled, setIsScrolled] = useState(false);
6
+ const [isScrolled, setIsScrolled] = useState(false)
5
7
 
6
8
  const handleScroll = useCallback(() => {
7
- if (typeof window === 'undefined') return;
9
+ if (typeof window === "undefined") return
8
10
 
9
- const scrollPosition = window.scrollY;
10
- const viewportHeight = window.innerHeight;
11
- const shouldBeSticky = scrollPosition > viewportHeight * threshold;
11
+ const scrollPosition = window.scrollY
12
+ const viewportHeight = window.innerHeight
13
+ const shouldBeSticky = scrollPosition > viewportHeight * threshold
12
14
 
13
- setIsScrolled(prev => shouldBeSticky !== prev ? shouldBeSticky : prev);
14
- }, [threshold]);
15
+ setIsScrolled((prev) => (shouldBeSticky !== prev ? shouldBeSticky : prev))
16
+ }, [threshold])
15
17
 
16
18
  // Add scroll event listener
17
19
  useEffect(() => {
18
20
  // Initial check
19
21
  // eslint-disable-next-line react-hooks/set-state-in-effect
20
- handleScroll();
22
+ handleScroll()
21
23
 
22
- window.addEventListener('scroll', handleScroll, { passive: true });
24
+ window.addEventListener("scroll", handleScroll, { passive: true })
23
25
  return () => {
24
- window.removeEventListener('scroll', handleScroll);
25
- };
26
- }, [handleScroll]);
26
+ window.removeEventListener("scroll", handleScroll)
27
+ }
28
+ }, [handleScroll])
27
29
 
28
- return isScrolled;
30
+ return isScrolled
29
31
  }
@@ -0,0 +1,5 @@
1
+ export const algoliaConfig = {
2
+ appId: process.env.NEXT_PUBLIC_ALGOLIA_DOCSEARCH_APP_ID,
3
+ apiKey: process.env.NEXT_PUBLIC_ALGOLIA_DOCSEARCH_API_KEY,
4
+ indexName: process.env.NEXT_PUBLIC_ALGOLIA_DOCSEARCH_INDEX_NAME,
5
+ }
@@ -0,0 +1,43 @@
1
+ import { ROUTES, type EachRoute } from "../routes"
2
+
3
+ export type SearchResult = {
4
+ title: string
5
+ href: string
6
+ noLink?: boolean
7
+ items?: undefined
8
+ score?: number
9
+ }
10
+
11
+ function helperSearch(
12
+ query: string,
13
+ node: EachRoute,
14
+ prefix: string,
15
+ currenLevel: number,
16
+ maxLevel?: number
17
+ ) {
18
+ const res: EachRoute[] = []
19
+ let parentHas = false
20
+
21
+ const nextLink = `${prefix}${node.href}`
22
+ if (!node.noLink && node.title.toLowerCase().includes(query.toLowerCase())) {
23
+ res.push({ ...node, items: undefined, href: nextLink })
24
+ parentHas = true
25
+ }
26
+ const goNext = maxLevel ? currenLevel < maxLevel : true
27
+ if (goNext)
28
+ node.items?.forEach((item) => {
29
+ const innerRes = helperSearch(query, item, nextLink, currenLevel + 1, maxLevel)
30
+ if (!!innerRes.length && !parentHas && !node.noLink) {
31
+ res.push({ ...node, items: undefined, href: nextLink })
32
+ parentHas = true
33
+ }
34
+ res.push(...innerRes)
35
+ })
36
+ return res
37
+ }
38
+
39
+ export function advanceSearch(query: string) {
40
+ return ROUTES.map((node) =>
41
+ helperSearch(query, node, "", 1, query.length == 0 ? 2 : undefined)
42
+ ).flat()
43
+ }
@@ -0,0 +1,7 @@
1
+ import docuConfig from "@/docu.json"
2
+
3
+ export type SearchType = "default" | "algolia"
4
+
5
+ export const searchConfig = {
6
+ type: (docuConfig.search?.type as SearchType) ?? "default",
7
+ }
@@ -6,4 +6,5 @@ export interface TocItem {
6
6
 
7
7
  export interface MobTocProps {
8
8
  tocs: TocItem[];
9
+ title?: string;
9
10
  }
@@ -1,80 +1,39 @@
1
- import { type ClassValue, clsx } from "clsx";
2
- import { twMerge } from "tailwind-merge";
3
- import { EachRoute, ROUTES } from "./routes";
1
+ import { type ClassValue, clsx } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
4
3
 
5
4
  export function cn(...inputs: ClassValue[]) {
6
- return twMerge(clsx(inputs));
7
- }
8
-
9
- export function helperSearch(
10
- query: string,
11
- node: EachRoute,
12
- prefix: string,
13
- currenLevel: number,
14
- maxLevel?: number
15
- ) {
16
- const res: EachRoute[] = [];
17
- let parentHas = false;
18
-
19
- const nextLink = `${prefix}${node.href}`;
20
- if (!node.noLink && node.title.toLowerCase().includes(query.toLowerCase())) {
21
- res.push({ ...node, items: undefined, href: nextLink });
22
- parentHas = true;
23
- }
24
- const goNext = maxLevel ? currenLevel < maxLevel : true;
25
- if (goNext)
26
- node.items?.forEach((item) => {
27
- const innerRes = helperSearch(
28
- query,
29
- item,
30
- nextLink,
31
- currenLevel + 1,
32
- maxLevel
33
- );
34
- if (!!innerRes.length && !parentHas && !node.noLink) {
35
- res.push({ ...node, items: undefined, href: nextLink });
36
- parentHas = true;
37
- }
38
- res.push(...innerRes);
39
- });
40
- return res;
41
- }
42
-
43
- export function advanceSearch(query: string) {
44
- return ROUTES.map((node) =>
45
- helperSearch(query, node, "", 1, query.length == 0 ? 2 : undefined)
46
- ).flat();
5
+ return twMerge(clsx(inputs))
47
6
  }
48
7
 
49
8
  // Thursday, May 23, 2024
50
9
  export function formatDate(dateStr: string): string {
51
- const [day, month, year] = dateStr.split("-").map(Number);
52
- const date = new Date(year, month - 1, day);
10
+ const [day, month, year] = dateStr.split("-").map(Number)
11
+ const date = new Date(year, month - 1, day)
53
12
 
54
13
  const options: Intl.DateTimeFormatOptions = {
55
14
  weekday: "long",
56
15
  year: "numeric",
57
16
  month: "long",
58
17
  day: "numeric",
59
- };
18
+ }
60
19
 
61
- return date.toLocaleDateString("en-US", options);
20
+ return date.toLocaleDateString("en-US", options)
62
21
  }
63
22
 
64
23
  // May 23, 2024
65
24
  export function formatDate2(dateStr: string): string {
66
- const [day, month, year] = dateStr.split("-").map(Number);
67
- const date = new Date(year, month - 1, day);
25
+ const [day, month, year] = dateStr.split("-").map(Number)
26
+ const date = new Date(year, month - 1, day)
68
27
 
69
28
  const options: Intl.DateTimeFormatOptions = {
70
29
  month: "short",
71
30
  day: "numeric",
72
31
  year: "numeric",
73
- };
74
- return date.toLocaleDateString("en-US", options);
32
+ }
33
+ return date.toLocaleDateString("en-US", options)
75
34
  }
76
35
 
77
36
  export function stringToDate(date: string) {
78
- const [day, month, year] = date.split("-").map(Number);
79
- return new Date(year, month - 1, day);
37
+ const [day, month, year] = date.split("-").map(Number)
38
+ return new Date(year, month - 1, day)
80
39
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docubook",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "dev": "next dev",
@@ -1,14 +1,3 @@
1
- /*
2
- ================================================================================
3
- DocSearch Component Styling (Refactored Version)
4
- ================================================================================
5
- */
6
-
7
- /* -- LANGKAH 1: Definisi Variabel Global --
8
- Variabel tema DocSearch sekarang didefinisikan secara global di :root.
9
- Ini menyederhanakan pewarisan tema dan memastikan konsistensi.
10
- Mode gelap secara otomatis menimpa variabel ini karena .dark di globals.css.
11
- */
12
1
  :root {
13
2
  --docsearch-primary-color: hsl(var(--primary));
14
3
  --docsearch-text-color: hsl(var(--muted-foreground));
@@ -18,47 +7,43 @@
18
7
  --docsearch-muted-color: hsl(var(--muted-foreground));
19
8
  --docsearch-container-background: rgba(0, 0, 0, 0.7);
20
9
  --docsearch-logo-color: hsl(var(--primary-foreground));
21
-
10
+
22
11
  /* Modal */
23
12
  --docsearch-modal-width: 560px;
24
13
  --docsearch-modal-height: 600px;
25
14
  --docsearch-modal-background: hsl(var(--background));
26
15
  --docsearch-modal-shadow: 0 0 0 1px hsl(var(--border)), 0 8px 20px rgba(0, 0, 0, 0.2);
27
-
16
+
28
17
  /* SearchBox */
29
18
  --docsearch-searchbox-height: 56px;
30
19
  --docsearch-searchbox-background: hsl(var(--input));
31
20
  --docsearch-searchbox-focus-background: hsl(var(--card));
32
21
  --docsearch-searchbox-shadow: none;
33
-
34
- /* Hit (Hasil Pencarian) */
22
+
23
+ /* Hit (Search Result) */
35
24
  --docsearch-hit-height: 56px;
36
25
  --docsearch-hit-color: hsl(var(--foreground));
37
26
  --docsearch-hit-active-color: hsl(var(--primary-foreground));
38
27
  --docsearch-hit-background: hsl(var(--card));
39
28
  --docsearch-hit-shadow: none;
40
-
29
+
41
30
  /* Keys */
42
31
  --docsearch-key-gradient: none;
43
32
  --docsearch-key-shadow: none;
44
33
  --docsearch-key-pressed-shadow: none;
45
-
34
+
46
35
  /* Footer */
47
36
  --docsearch-footer-height: 44px;
48
37
  --docsearch-footer-background: hsl(var(--background));
49
38
  --docsearch-footer-shadow: none;
50
39
  }
51
40
 
52
- /* -- LANGKAH 2: Gaya untuk Tombol Awal --
53
- Gaya ini spesifik untuk tombol yang ada di Navbar,
54
- yang dibungkus oleh <div class="docsearch">.
55
- */
56
41
  .docsearch .DocSearch-Button {
57
42
  background-color: hsl(var(--secondary));
58
43
  border: 1px solid hsl(var(--border));
59
44
  border-radius: 9999px;
60
- width: 160px;
61
- height: 40px;
45
+ width: 250px;
46
+ height: 35px;
62
47
  color: hsl(var(--muted-foreground));
63
48
  transition: width 0.3s ease;
64
49
  margin: 0;
@@ -71,8 +56,8 @@
71
56
 
72
57
  .docsearch .DocSearch-Search-Icon {
73
58
  color: var(--docsearch-muted-color);
74
- width: 1rem;
75
- height: 1rem;
59
+ width: 1.2rem;
60
+ height: 1.2rem;
76
61
  }
77
62
 
78
63
  .docsearch .DocSearch-Button-Placeholder {
@@ -85,7 +70,7 @@
85
70
 
86
71
  .docsearch .DocSearch-Button-Key {
87
72
  background: var(--docsearch-primary-color);
88
- color: var(--docsearch-logo-color); /* Menggunakan variabel yg relevan */
73
+ color: var(--docsearch-logo-color);
89
74
  border-radius: 6px;
90
75
  font-size: 14px;
91
76
  font-weight: 500;
@@ -96,10 +81,6 @@
96
81
  top: 0;
97
82
  }
98
83
 
99
- /* -- LANGKAH 3: Gaya untuk Modal dan Isinya --
100
- Gaya ini menargetkan elemen-elemen modal yang dirender terpisah.
101
- Karena variabel sudah global, kita hanya perlu menata elemennya.
102
- */
103
84
  .DocSearch-Container .DocSearch-Modal {
104
85
  backdrop-filter: blur(8px);
105
86
  }
@@ -117,7 +98,6 @@
117
98
  border-top: 1px solid hsl(var(--border));
118
99
  }
119
100
 
120
- /* Gaya untuk tombol keyboard di footer */
121
101
  .DocSearch-Footer--commands kbd {
122
102
  background-color: hsl(var(--secondary));
123
103
  border: 1px solid hsl(var(--border));
@@ -130,7 +110,6 @@
130
110
  justify-content: center;
131
111
  }
132
112
 
133
- /* Menghilangkan gaya default dari ikon di dalam tombol footer */
134
113
  .DocSearch-Commands-Key {
135
114
  background: none;
136
115
  color: hsl(var(--muted-foreground));
@@ -143,9 +122,6 @@
143
122
  border-radius: 6px;
144
123
  }
145
124
 
146
- /* -- LANGKAH 4: Gaya Responsif --
147
- Tidak ada perubahan, hanya mempertahankan fungsionalitas mobile.
148
- */
149
125
  @media (max-width: 768px) {
150
126
  .docsearch .DocSearch-Button {
151
127
  width: 40px;
@@ -155,6 +131,7 @@
155
131
  background: none;
156
132
  border: none;
157
133
  }
134
+
158
135
  .docsearch .DocSearch-Button-Placeholder,
159
136
  .docsearch .DocSearch-Button-Key {
160
137
  display: none;