@usecross/docs 0.4.2 → 0.6.0
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/index.d.ts +38 -3
- package/dist/index.js +390 -135
- package/dist/index.js.map +1 -1
- package/dist/ssr.d.ts +1 -1
- package/dist/ssr.js +79 -1
- package/dist/ssr.js.map +1 -1
- package/dist/{types-CCdOzu28.d.ts → types-CR-kx8KP.d.ts} +2 -0
- package/package.json +2 -3
- package/src/app.tsx +6 -3
- package/src/components/DocsLayout.tsx +28 -19
- package/src/components/HomePage.tsx +59 -36
- package/src/components/Sidebar.tsx +4 -4
- package/src/components/ThemeProvider.tsx +125 -0
- package/src/components/ThemeToggle.tsx +188 -0
- package/src/components/index.ts +2 -0
- package/src/index.ts +6 -0
- package/src/ssr.tsx +6 -1
- package/src/styles.css +116 -14
- package/src/types.ts +2 -0
- package/src/tailwind.preset.cjs +0 -118
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from 'react'
|
|
2
|
+
import { useTheme, type Theme } from './ThemeProvider'
|
|
3
|
+
import { cn } from '../lib/utils'
|
|
4
|
+
|
|
5
|
+
interface ThemeToggleProps {
|
|
6
|
+
/** Additional CSS classes */
|
|
7
|
+
className?: string
|
|
8
|
+
/** Size variant */
|
|
9
|
+
size?: 'sm' | 'md' | 'lg'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Refined sun icon with balanced proportions
|
|
13
|
+
const SunIcon = ({ className }: { className?: string }) => (
|
|
14
|
+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
15
|
+
<circle cx="12" cy="12" r="4" stroke="currentColor" strokeWidth="1.5" />
|
|
16
|
+
<path d="M12 5V3M12 21v-2M5 12H3m18 0h-2M7.05 7.05 5.636 5.636m12.728 12.728L16.95 16.95M7.05 16.95l-1.414 1.414M18.364 5.636 16.95 7.05" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
|
|
17
|
+
</svg>
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
// Refined moon icon - elegant crescent
|
|
21
|
+
const MoonIcon = ({ className }: { className?: string }) => (
|
|
22
|
+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
23
|
+
<path d="M21.752 15.002A9.718 9.718 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
24
|
+
</svg>
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
// Refined monitor icon - clean display shape
|
|
28
|
+
const MonitorIcon = ({ className }: { className?: string }) => (
|
|
29
|
+
<svg className={className} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
30
|
+
<rect x="2" y="3" width="20" height="14" rx="2" stroke="currentColor" strokeWidth="1.5" />
|
|
31
|
+
<path d="M8 21h8m-4-4v4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
|
|
32
|
+
</svg>
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
const themeOptions: { value: Theme; label: string; icon: typeof SunIcon }[] = [
|
|
36
|
+
{ value: 'light', label: 'Light', icon: SunIcon },
|
|
37
|
+
{ value: 'dark', label: 'Dark', icon: MoonIcon },
|
|
38
|
+
{ value: 'system', label: 'System', icon: MonitorIcon },
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Theme toggle dropdown with Light, Dark, and System options.
|
|
43
|
+
* Refined design with smooth animations and premium feel.
|
|
44
|
+
*/
|
|
45
|
+
export function ThemeToggle({ className, size = 'md' }: ThemeToggleProps) {
|
|
46
|
+
const { theme, resolvedTheme, setTheme } = useTheme()
|
|
47
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
48
|
+
const dropdownRef = useRef<HTMLDivElement>(null)
|
|
49
|
+
|
|
50
|
+
// Close dropdown when clicking outside
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
53
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
54
|
+
setIsOpen(false)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (isOpen) {
|
|
59
|
+
document.addEventListener('mousedown', handleClickOutside)
|
|
60
|
+
return () => document.removeEventListener('mousedown', handleClickOutside)
|
|
61
|
+
}
|
|
62
|
+
}, [isOpen])
|
|
63
|
+
|
|
64
|
+
// Close on escape key
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const handleEscape = (event: KeyboardEvent) => {
|
|
67
|
+
if (event.key === 'Escape') setIsOpen(false)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (isOpen) {
|
|
71
|
+
document.addEventListener('keydown', handleEscape)
|
|
72
|
+
return () => document.removeEventListener('keydown', handleEscape)
|
|
73
|
+
}
|
|
74
|
+
}, [isOpen])
|
|
75
|
+
|
|
76
|
+
const iconSizes = {
|
|
77
|
+
sm: 'w-[18px] h-[18px]',
|
|
78
|
+
md: 'w-5 h-5',
|
|
79
|
+
lg: 'w-[22px] h-[22px]',
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<div className="relative" ref={dropdownRef}>
|
|
84
|
+
{/* Toggle Button */}
|
|
85
|
+
<button
|
|
86
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
87
|
+
className={cn(
|
|
88
|
+
'relative inline-flex items-center justify-center',
|
|
89
|
+
'rounded-full p-4',
|
|
90
|
+
'text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white',
|
|
91
|
+
'hover:bg-gray-100 dark:hover:bg-white/10',
|
|
92
|
+
'transition-all duration-200 ease-out',
|
|
93
|
+
'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-[#0f0f0f]',
|
|
94
|
+
iconSizes[size],
|
|
95
|
+
className
|
|
96
|
+
)}
|
|
97
|
+
aria-label="Toggle theme"
|
|
98
|
+
aria-expanded={isOpen}
|
|
99
|
+
aria-haspopup="listbox"
|
|
100
|
+
>
|
|
101
|
+
{/* Sun icon - visible in light mode */}
|
|
102
|
+
<SunIcon
|
|
103
|
+
className={cn(
|
|
104
|
+
iconSizes[size],
|
|
105
|
+
'absolute inset-0 m-auto transition-all duration-300 ease-out',
|
|
106
|
+
resolvedTheme === 'light'
|
|
107
|
+
? 'rotate-0 scale-100 opacity-100'
|
|
108
|
+
: 'rotate-90 scale-75 opacity-0'
|
|
109
|
+
)}
|
|
110
|
+
/>
|
|
111
|
+
|
|
112
|
+
{/* Moon icon - visible in dark mode */}
|
|
113
|
+
<MoonIcon
|
|
114
|
+
className={cn(
|
|
115
|
+
iconSizes[size],
|
|
116
|
+
'absolute inset-0 m-auto transition-all duration-300 ease-out',
|
|
117
|
+
resolvedTheme === 'dark'
|
|
118
|
+
? 'rotate-0 scale-100 opacity-100'
|
|
119
|
+
: '-rotate-90 scale-75 opacity-0'
|
|
120
|
+
)}
|
|
121
|
+
/>
|
|
122
|
+
</button>
|
|
123
|
+
|
|
124
|
+
{/* Dropdown Menu */}
|
|
125
|
+
<div
|
|
126
|
+
className={cn(
|
|
127
|
+
'absolute right-0 mt-2 min-w-[140px]',
|
|
128
|
+
'p-1',
|
|
129
|
+
'bg-white dark:bg-[#171717]',
|
|
130
|
+
'border border-gray-200 dark:border-[#262626]',
|
|
131
|
+
'rounded-xl',
|
|
132
|
+
'shadow-lg shadow-black/5 dark:shadow-black/40',
|
|
133
|
+
'z-50',
|
|
134
|
+
'transition-all duration-200 ease-out origin-top-right',
|
|
135
|
+
isOpen
|
|
136
|
+
? 'opacity-100 scale-100 translate-y-0'
|
|
137
|
+
: 'opacity-0 scale-95 -translate-y-1 pointer-events-none'
|
|
138
|
+
)}
|
|
139
|
+
role="listbox"
|
|
140
|
+
aria-label="Select theme"
|
|
141
|
+
>
|
|
142
|
+
{themeOptions.map((option, index) => {
|
|
143
|
+
const Icon = option.icon
|
|
144
|
+
const isSelected = theme === option.value
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<button
|
|
148
|
+
key={option.value}
|
|
149
|
+
onClick={() => {
|
|
150
|
+
setTheme(option.value)
|
|
151
|
+
setIsOpen(false)
|
|
152
|
+
}}
|
|
153
|
+
className={cn(
|
|
154
|
+
'w-full flex items-center gap-2.5 px-3 py-2',
|
|
155
|
+
'rounded-lg',
|
|
156
|
+
'text-[13px] font-medium',
|
|
157
|
+
'transition-all duration-150 ease-out',
|
|
158
|
+
'focus:outline-none',
|
|
159
|
+
isSelected
|
|
160
|
+
? 'text-gray-900 dark:text-white bg-gray-100 dark:bg-[#262626]'
|
|
161
|
+
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-[#1f1f1f]'
|
|
162
|
+
)}
|
|
163
|
+
role="option"
|
|
164
|
+
aria-selected={isSelected}
|
|
165
|
+
style={{
|
|
166
|
+
animationDelay: isOpen ? `${index * 25}ms` : '0ms'
|
|
167
|
+
}}
|
|
168
|
+
>
|
|
169
|
+
<Icon className={cn(
|
|
170
|
+
'w-4 h-4 flex-shrink-0',
|
|
171
|
+
'transition-transform duration-150',
|
|
172
|
+
isSelected ? 'scale-110' : 'scale-100'
|
|
173
|
+
)} />
|
|
174
|
+
<span className="flex-1 text-left">{option.label}</span>
|
|
175
|
+
<div className={cn(
|
|
176
|
+
'w-1.5 h-1.5 rounded-full',
|
|
177
|
+
'transition-all duration-200',
|
|
178
|
+
isSelected
|
|
179
|
+
? 'bg-primary-500 scale-100 opacity-100'
|
|
180
|
+
: 'bg-transparent scale-0 opacity-0'
|
|
181
|
+
)} />
|
|
182
|
+
</button>
|
|
183
|
+
)
|
|
184
|
+
})}
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
)
|
|
188
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -5,3 +5,5 @@ export { EmojiConfetti } from './EmojiConfetti'
|
|
|
5
5
|
export { HomePage } from './HomePage'
|
|
6
6
|
export { Markdown } from './Markdown'
|
|
7
7
|
export { Sidebar } from './Sidebar'
|
|
8
|
+
export { ThemeProvider, useTheme, themeInitScript } from './ThemeProvider'
|
|
9
|
+
export { ThemeToggle } from './ThemeToggle'
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,10 @@ export {
|
|
|
8
8
|
InlineCode,
|
|
9
9
|
Markdown,
|
|
10
10
|
Sidebar,
|
|
11
|
+
ThemeProvider,
|
|
12
|
+
ThemeToggle,
|
|
13
|
+
useTheme,
|
|
14
|
+
themeInitScript,
|
|
11
15
|
} from './components'
|
|
12
16
|
|
|
13
17
|
// HomePage sub-components (for compound component pattern)
|
|
@@ -40,6 +44,8 @@ export type {
|
|
|
40
44
|
SidebarProps,
|
|
41
45
|
} from './types'
|
|
42
46
|
|
|
47
|
+
export type { Theme, ResolvedTheme } from './components/ThemeProvider'
|
|
48
|
+
|
|
43
49
|
export type {
|
|
44
50
|
HomePageProps,
|
|
45
51
|
HomePageContextValue,
|
package/src/ssr.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import { createInertiaApp } from '@inertiajs/react'
|
|
|
2
2
|
import createServer from '@inertiajs/react/server'
|
|
3
3
|
import ReactDOMServer from 'react-dom/server'
|
|
4
4
|
import type { DocsAppConfig } from './types'
|
|
5
|
+
import { ThemeProvider } from './components/ThemeProvider'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Create an SSR server for documentation.
|
|
@@ -33,7 +34,11 @@ export function createDocsServer(config: DocsAppConfig): void {
|
|
|
33
34
|
}
|
|
34
35
|
return pageComponent
|
|
35
36
|
},
|
|
36
|
-
setup: ({ App, props }) =>
|
|
37
|
+
setup: ({ App, props }) => (
|
|
38
|
+
<ThemeProvider>
|
|
39
|
+
<App {...props} />
|
|
40
|
+
</ThemeProvider>
|
|
41
|
+
),
|
|
37
42
|
})
|
|
38
43
|
)
|
|
39
44
|
}
|
package/src/styles.css
CHANGED
|
@@ -1,22 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cross-Docs default styles
|
|
2
|
+
* Cross-Docs default styles (Tailwind CSS v4)
|
|
3
3
|
*
|
|
4
|
-
* Import this file in your app's CSS entry point:
|
|
4
|
+
* Import this file in your app's CSS entry point after importing Tailwind:
|
|
5
|
+
*
|
|
6
|
+
* @import "tailwindcss";
|
|
7
|
+
* @plugin "@tailwindcss/typography";
|
|
8
|
+
* @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&display=swap');
|
|
5
9
|
* @import '@usecross/docs/styles.css';
|
|
10
|
+
* @source "../node_modules/@usecross/docs";
|
|
11
|
+
*
|
|
12
|
+
* Note: The @source directive ensures Tailwind scans the package for utility classes.
|
|
13
|
+
* Note: The Google Fonts import must come before other imports to avoid CSS ordering warnings.
|
|
6
14
|
*/
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
/* Theme customizations for Tailwind v4 */
|
|
17
|
+
@theme {
|
|
18
|
+
/* Max width */
|
|
19
|
+
--max-width-8xl: 88rem;
|
|
20
|
+
|
|
21
|
+
/* Font families */
|
|
22
|
+
--font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial,
|
|
23
|
+
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
24
|
+
--font-heading: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
25
|
+
--font-mono: 'Fira Code', Consolas, Monaco, 'Andale Mono', monospace;
|
|
26
|
+
|
|
27
|
+
/* Default primary colors - sky blue (can be overridden via CSS variables) */
|
|
28
|
+
--color-primary-50: #f0f9ff;
|
|
29
|
+
--color-primary-100: #e0f2fe;
|
|
30
|
+
--color-primary-200: #bae6fd;
|
|
31
|
+
--color-primary-300: #7dd3fc;
|
|
32
|
+
--color-primary-400: #38bdf8;
|
|
33
|
+
--color-primary-500: #0ea5e9;
|
|
34
|
+
--color-primary-600: #0284c7;
|
|
35
|
+
--color-primary-700: #0369a1;
|
|
36
|
+
--color-primary-800: #075985;
|
|
37
|
+
--color-primary-900: #0c4a6e;
|
|
38
|
+
--color-primary-950: #082f49;
|
|
39
|
+
|
|
40
|
+
/* Dark colors for code blocks */
|
|
41
|
+
--color-dark-800: #1e293b;
|
|
42
|
+
--color-dark-900: #0f172a;
|
|
43
|
+
}
|
|
11
44
|
|
|
12
45
|
@layer base {
|
|
13
46
|
:root {
|
|
14
|
-
/* Font stacks */
|
|
15
|
-
--font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial,
|
|
16
|
-
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
17
|
-
--font-heading: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
18
|
-
--font-mono: 'Fira Code', Consolas, Monaco, 'Andale Mono', monospace;
|
|
19
|
-
|
|
20
47
|
/* Code highlighting - matches Starlight/Expressive Code dark theme */
|
|
21
48
|
--shiki-color-text: #e2e8f0;
|
|
22
49
|
--shiki-color-background: #24292f;
|
|
@@ -29,6 +56,31 @@
|
|
|
29
56
|
--shiki-token-string-expression: #86efac;
|
|
30
57
|
--shiki-token-punctuation: #94a3b8;
|
|
31
58
|
--shiki-token-link: #38bdf8;
|
|
59
|
+
|
|
60
|
+
/* Surface colors for light mode */
|
|
61
|
+
--surface-primary: #ffffff;
|
|
62
|
+
--surface-secondary: #f9fafb;
|
|
63
|
+
--surface-tertiary: #f3f4f6;
|
|
64
|
+
--border-primary: #e5e7eb;
|
|
65
|
+
--border-secondary: #d1d5db;
|
|
66
|
+
--text-primary: #111827;
|
|
67
|
+
--text-secondary: #4b5563;
|
|
68
|
+
--text-tertiary: #6b7280;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.dark {
|
|
72
|
+
/* Surface colors for dark mode */
|
|
73
|
+
--surface-primary: #0f0f0f;
|
|
74
|
+
--surface-secondary: #171717;
|
|
75
|
+
--surface-tertiary: #262626;
|
|
76
|
+
--border-primary: #262626;
|
|
77
|
+
--border-secondary: #404040;
|
|
78
|
+
--text-primary: #fafafa;
|
|
79
|
+
--text-secondary: #a3a3a3;
|
|
80
|
+
--text-tertiary: #737373;
|
|
81
|
+
|
|
82
|
+
/* Slightly lighter code blocks in dark mode for contrast */
|
|
83
|
+
--shiki-color-background: #1a1a1a;
|
|
32
84
|
}
|
|
33
85
|
|
|
34
86
|
html {
|
|
@@ -41,11 +93,17 @@
|
|
|
41
93
|
}
|
|
42
94
|
|
|
43
95
|
body {
|
|
44
|
-
@apply antialiased;
|
|
96
|
+
@apply antialiased bg-white text-gray-800;
|
|
45
97
|
font-family: var(--font-sans);
|
|
46
98
|
font-weight: 400;
|
|
47
|
-
|
|
48
|
-
|
|
99
|
+
transition: background-color 0.2s ease, color 0.2s ease;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Dark mode body - using direct selector for cross-package compatibility */
|
|
103
|
+
.dark body,
|
|
104
|
+
:root.dark body {
|
|
105
|
+
background-color: #0f0f0f;
|
|
106
|
+
color: #f3f4f6;
|
|
49
107
|
}
|
|
50
108
|
|
|
51
109
|
/* Headings use heading font */
|
|
@@ -63,10 +121,21 @@
|
|
|
63
121
|
@layer components {
|
|
64
122
|
/* Prose content styles */
|
|
65
123
|
.prose {
|
|
124
|
+
max-width: none;
|
|
66
125
|
font-size: 1rem;
|
|
67
126
|
line-height: 1.75;
|
|
68
127
|
}
|
|
69
128
|
|
|
129
|
+
/* Prose link styling */
|
|
130
|
+
.prose a {
|
|
131
|
+
@apply text-primary-600 hover:text-primary-700;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Dark mode prose link styling */
|
|
135
|
+
.prose-invert a {
|
|
136
|
+
@apply text-primary-400 hover:text-primary-300;
|
|
137
|
+
}
|
|
138
|
+
|
|
70
139
|
/* Scroll margin for headings (so they don't hide under fixed header) */
|
|
71
140
|
.prose h1,
|
|
72
141
|
.prose h2,
|
|
@@ -93,12 +162,36 @@
|
|
|
93
162
|
/* Inline code styling */
|
|
94
163
|
.prose :not(pre) > code {
|
|
95
164
|
@apply bg-gray-100 px-1.5 py-0.5 rounded text-sm font-medium text-gray-800;
|
|
165
|
+
@apply dark:bg-gray-800 dark:text-gray-200;
|
|
96
166
|
}
|
|
97
167
|
|
|
98
168
|
.prose :not(pre) > code::before,
|
|
99
169
|
.prose :not(pre) > code::after {
|
|
100
170
|
content: none;
|
|
101
171
|
}
|
|
172
|
+
|
|
173
|
+
/* Dark mode inline code */
|
|
174
|
+
.prose-invert :not(pre) > code {
|
|
175
|
+
@apply bg-gray-800;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Dark mode prose text colors */
|
|
179
|
+
.dark .prose {
|
|
180
|
+
--tw-prose-body: theme(colors.gray.300);
|
|
181
|
+
--tw-prose-headings: theme(colors.white);
|
|
182
|
+
--tw-prose-lead: theme(colors.gray.400);
|
|
183
|
+
--tw-prose-bold: theme(colors.white);
|
|
184
|
+
--tw-prose-counters: theme(colors.gray.400);
|
|
185
|
+
--tw-prose-bullets: theme(colors.gray.600);
|
|
186
|
+
--tw-prose-hr: theme(colors.gray.700);
|
|
187
|
+
--tw-prose-quotes: theme(colors.gray.100);
|
|
188
|
+
--tw-prose-quote-borders: theme(colors.gray.700);
|
|
189
|
+
--tw-prose-captions: theme(colors.gray.400);
|
|
190
|
+
--tw-prose-kbd: theme(colors.white);
|
|
191
|
+
--tw-prose-kbd-shadows: 0 0 0 theme(colors.gray.100);
|
|
192
|
+
--tw-prose-th-borders: theme(colors.gray.600);
|
|
193
|
+
--tw-prose-td-borders: theme(colors.gray.700);
|
|
194
|
+
}
|
|
102
195
|
}
|
|
103
196
|
|
|
104
197
|
/* Syntax highlighting - rounded corners like Starlight */
|
|
@@ -129,6 +222,15 @@
|
|
|
129
222
|
@apply bg-gray-400;
|
|
130
223
|
}
|
|
131
224
|
|
|
225
|
+
/* Dark mode scrollbars */
|
|
226
|
+
.dark ::-webkit-scrollbar-thumb {
|
|
227
|
+
@apply bg-gray-700;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.dark ::-webkit-scrollbar-thumb:hover {
|
|
231
|
+
@apply bg-gray-600;
|
|
232
|
+
}
|
|
233
|
+
|
|
132
234
|
/* Emoji confetti animation */
|
|
133
235
|
@keyframes emojiConfettiBurst {
|
|
134
236
|
0% {
|
package/src/types.ts
CHANGED
|
@@ -26,6 +26,8 @@ export interface SharedProps {
|
|
|
26
26
|
logoInvertedUrl?: string
|
|
27
27
|
/** Footer logo image URL (from Python backend) */
|
|
28
28
|
footerLogoUrl?: string
|
|
29
|
+
/** Footer logo image URL for dark mode (from Python backend) */
|
|
30
|
+
footerLogoInvertedUrl?: string
|
|
29
31
|
/** GitHub repository URL (from Python backend) */
|
|
30
32
|
githubUrl?: string
|
|
31
33
|
/** Additional navigation links (from Python backend) */
|
package/src/tailwind.preset.cjs
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cross-Docs Tailwind CSS preset
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```js
|
|
6
|
-
* // tailwind.config.js
|
|
7
|
-
* const docsPreset = require('@usecross/docs/tailwind.preset')
|
|
8
|
-
*
|
|
9
|
-
* module.exports = {
|
|
10
|
-
* presets: [docsPreset],
|
|
11
|
-
* content: [
|
|
12
|
-
* './frontend/**\/*.{ts,tsx}',
|
|
13
|
-
* './node_modules/@usecross/docs/**\/*.{js,tsx}',
|
|
14
|
-
* ],
|
|
15
|
-
* theme: {
|
|
16
|
-
* extend: {
|
|
17
|
-
* colors: {
|
|
18
|
-
* primary: { // Override with your brand colors },
|
|
19
|
-
* },
|
|
20
|
-
* },
|
|
21
|
-
* },
|
|
22
|
-
* }
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
module.exports = {
|
|
26
|
-
darkMode: 'class',
|
|
27
|
-
theme: {
|
|
28
|
-
extend: {
|
|
29
|
-
maxWidth: {
|
|
30
|
-
'8xl': '88rem',
|
|
31
|
-
},
|
|
32
|
-
fontFamily: {
|
|
33
|
-
sans: [
|
|
34
|
-
'system-ui',
|
|
35
|
-
'-apple-system',
|
|
36
|
-
'Segoe UI',
|
|
37
|
-
'Roboto',
|
|
38
|
-
'Helvetica',
|
|
39
|
-
'Arial',
|
|
40
|
-
'sans-serif',
|
|
41
|
-
'Apple Color Emoji',
|
|
42
|
-
'Segoe UI Emoji',
|
|
43
|
-
'Segoe UI Symbol',
|
|
44
|
-
],
|
|
45
|
-
heading: [
|
|
46
|
-
'system-ui',
|
|
47
|
-
'-apple-system',
|
|
48
|
-
'Segoe UI',
|
|
49
|
-
'Roboto',
|
|
50
|
-
'sans-serif',
|
|
51
|
-
],
|
|
52
|
-
mono: ['Fira Code', 'Consolas', 'Monaco', 'Andale Mono', 'monospace'],
|
|
53
|
-
},
|
|
54
|
-
colors: {
|
|
55
|
-
// Default primary colors - sky blue (can be overridden)
|
|
56
|
-
primary: {
|
|
57
|
-
50: '#f0f9ff',
|
|
58
|
-
100: '#e0f2fe',
|
|
59
|
-
200: '#bae6fd',
|
|
60
|
-
300: '#7dd3fc',
|
|
61
|
-
400: '#38bdf8',
|
|
62
|
-
500: '#0ea5e9',
|
|
63
|
-
600: '#0284c7',
|
|
64
|
-
700: '#0369a1',
|
|
65
|
-
800: '#075985',
|
|
66
|
-
900: '#0c4a6e',
|
|
67
|
-
950: '#082f49',
|
|
68
|
-
},
|
|
69
|
-
// Dark colors for code blocks
|
|
70
|
-
dark: {
|
|
71
|
-
800: '#1e293b',
|
|
72
|
-
900: '#0f172a',
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
typography: (theme) => ({
|
|
76
|
-
DEFAULT: {
|
|
77
|
-
css: {
|
|
78
|
-
maxWidth: 'none',
|
|
79
|
-
color: theme('colors.gray.700'),
|
|
80
|
-
a: {
|
|
81
|
-
color: theme('colors.primary.600'),
|
|
82
|
-
'&:hover': {
|
|
83
|
-
color: theme('colors.primary.700'),
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
'code::before': {
|
|
87
|
-
content: '""',
|
|
88
|
-
},
|
|
89
|
-
'code::after': {
|
|
90
|
-
content: '""',
|
|
91
|
-
},
|
|
92
|
-
code: {
|
|
93
|
-
backgroundColor: theme('colors.gray.100'),
|
|
94
|
-
padding: '0.25rem 0.375rem',
|
|
95
|
-
borderRadius: '0.25rem',
|
|
96
|
-
fontWeight: '500',
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
invert: {
|
|
101
|
-
css: {
|
|
102
|
-
color: theme('colors.gray.300'),
|
|
103
|
-
a: {
|
|
104
|
-
color: theme('colors.primary.400'),
|
|
105
|
-
'&:hover': {
|
|
106
|
-
color: theme('colors.primary.300'),
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
code: {
|
|
110
|
-
backgroundColor: theme('colors.gray.800'),
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
}),
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
plugins: [require('@tailwindcss/typography')],
|
|
118
|
-
}
|