├── .gitignore ├── .vscode ├── extensions.json └── launch.json ├── README.md ├── astro.config.mjs ├── package-lock.json ├── package.json ├── public └── favicon.svg ├── src ├── assets │ ├── astro-logo.svg │ ├── astro.png │ ├── dark-logo.svg │ ├── hero.svg │ ├── houston.webp │ ├── light-logo.svg │ └── starmint.jpg ├── components │ ├── Card.astro │ ├── CardGrid.astro │ ├── Footer.astro │ ├── GroupName.astro │ ├── Header.astro │ ├── ThemeToggle.astro │ ├── button.tsx │ ├── components.ts │ ├── dropdown-menu.tsx │ ├── header-menu.tsx │ └── icon.tsx ├── content │ ├── config.ts │ └── docs │ │ ├── components │ │ ├── asides.mdx │ │ ├── badge.mdx │ │ └── tabs.mdx │ │ ├── essentials │ │ ├── creating-pages.mdx │ │ ├── deployments.mdx │ │ ├── images.mdx │ │ └── theming.mdx │ │ ├── getting-started │ │ ├── introduction.mdx │ │ └── quickstart.mdx │ │ ├── index.mdx │ │ └── reference │ │ └── example.md ├── env.d.ts ├── lib │ └── utils.ts └── styles │ ├── custom.css │ └── tailwind.css ├── tailwind.config.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Starmint 2 | -------------------------------------------------------------------------------- /astro.config.mjs: -------------------------------------------------------------------------------- 1 | import react from '@astrojs/react' 2 | import starlight from '@astrojs/starlight' 3 | import tailwind from '@astrojs/tailwind' 4 | import { defineConfig } from 'astro/config' 5 | 6 | export default defineConfig({ 7 | integrations: [ 8 | starlight({ 9 | title: 'starmint', 10 | logo: { 11 | light: './src/assets/dark-logo.svg', 12 | dark: './src/assets/light-logo.svg', 13 | }, 14 | customCss: ['./src/styles/custom.css', './src/styles/tailwind.css'], 15 | social: { 16 | github: 'https://github.com/alexwhitmore/astro-mintlify', 17 | }, 18 | components: { 19 | Header: './src/components/Header.astro', 20 | }, 21 | sidebar: [ 22 | { 23 | label: 'Getting Started', 24 | items: [ 25 | { 26 | label: 'Introduction', 27 | slug: 'getting-started/introduction', 28 | }, 29 | { 30 | label: 'Quickstart', 31 | slug: 'getting-started/quickstart', 32 | }, 33 | ], 34 | }, 35 | { 36 | label: 'Essentials', 37 | items: [ 38 | { 39 | label: 'Creating Pages', 40 | slug: 'essentials/creating-pages', 41 | }, 42 | { 43 | label: 'Theming', 44 | slug: 'essentials/theming', 45 | }, 46 | { 47 | label: 'Images', 48 | slug: 'essentials/images', 49 | }, 50 | { 51 | label: 'Deployments', 52 | slug: 'essentials/deployments', 53 | }, 54 | ], 55 | }, 56 | { 57 | label: 'Components', 58 | items: [ 59 | { 60 | label: 'Badge', 61 | slug: 'components/badge', 62 | }, 63 | { 64 | label: 'Asides', 65 | slug: 'components/asides', 66 | }, 67 | { 68 | label: 'Tabs', 69 | slug: 'components/tabs', 70 | }, 71 | ], 72 | }, 73 | ], 74 | }), 75 | tailwind(), 76 | react(), 77 | ], 78 | }) 79 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starmint", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro check && astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "dependencies": { 13 | "@astrojs/check": "^0.9.4", 14 | "@astrojs/react": "^3.6.2", 15 | "@astrojs/starlight": "^0.29.0", 16 | "@astrojs/starlight-tailwind": "^2.0.3", 17 | "@astrojs/tailwind": "^5.1.2", 18 | "@radix-ui/react-dropdown-menu": "^2.1.5", 19 | "@radix-ui/react-slot": "^1.1.1", 20 | "@types/react": "^18.3.5", 21 | "@types/react-dom": "^18.3.0", 22 | "astro": "^4.16.12", 23 | "class-variance-authority": "^0.7.1", 24 | "lucide-react": "^0.453.0", 25 | "react": "^18.3.1", 26 | "react-dom": "^18.3.1", 27 | "sharp": "^0.32.5", 28 | "tailwind-merge": "^2.5.4", 29 | "tailwindcss": "^3.4.10", 30 | "tailwindcss-animate": "^1.0.7", 31 | "typescript": "^5.5.4" 32 | }, 33 | "devDependencies": { 34 | "@tailwindcss/typography": "^0.5.15" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/astro-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/astro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexwhitmore/astro-mintlify/ab1bc974426693e83e24fb190a95bb9e807c0fb2/src/assets/astro.png -------------------------------------------------------------------------------- /src/assets/dark-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/hero.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /src/assets/houston.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexwhitmore/astro-mintlify/ab1bc974426693e83e24fb190a95bb9e807c0fb2/src/assets/houston.webp -------------------------------------------------------------------------------- /src/assets/light-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/starmint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexwhitmore/astro-mintlify/ab1bc974426693e83e24fb190a95bb9e807c0fb2/src/assets/starmint.jpg -------------------------------------------------------------------------------- /src/components/Card.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { icons } from 'lucide-react' 3 | import { Icon } from './icon' 4 | 5 | interface Props { 6 | iconName?: keyof typeof icons 7 | title: string 8 | iconStyles?: string 9 | href?: string 10 | } 11 | 12 | const { iconName, title, iconStyles, href } = Astro.props 13 | --- 14 | 15 | { 16 | href ? ( 17 | 18 |
19 |

20 | {iconName && ( 21 | 22 | 23 | 24 | )} 25 | 26 |

27 |
28 | 29 |
30 |
31 |
32 | ) : ( 33 |
34 |

35 | {iconName && ( 36 | 37 | 38 | 39 | )} 40 | 41 |

42 |
43 | 44 |
45 |
46 | ) 47 | } -------------------------------------------------------------------------------- /src/components/CardGrid.astro: -------------------------------------------------------------------------------- 1 | --- 2 | interface Props { 3 | stagger?: boolean 4 | } 5 | 6 | const { stagger = false } = Astro.props 7 | --- 8 | 9 |
10 | 11 | 36 | -------------------------------------------------------------------------------- /src/components/Footer.astro: -------------------------------------------------------------------------------- 1 |
2 |
3 | left 4 | right 5 |
6 |
7 | 8 | 18 | -------------------------------------------------------------------------------- /src/components/GroupName.astro: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | -------------------------------------------------------------------------------- /src/components/Header.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Search from '@astrojs/starlight/components/Search.astro' 3 | import type { Props } from '@astrojs/starlight/props' 4 | import ThemeToggle from './ThemeToggle.astro' 5 | import { HeaderMenu } from './header-menu' 6 | --- 7 | 8 |
9 | 94 |
95 | 96 | -------------------------------------------------------------------------------- /src/components/ThemeToggle.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import crypto from 'node:crypto' 3 | 4 | import type { Props } from '@astrojs/starlight/props' 5 | 6 | const id = `moon-mask-${crypto.randomBytes(4).toString('hex')}` 7 | 8 | // https://web.dev/building-a-theme-switch-component/ 9 | // https://github.com/withastro/starlight/blob/9237581c766f68fbb3ce5f9401ca2046f106c7d5/packages/starlight/components/ThemeSelect.astro 10 | --- 11 | 12 | 13 | 37 | 38 | 39 | 131 | 132 | {/* Inlined to avoid FOUC. Uses global scope from `ThemeProvider.astro` */} 133 | 136 | 137 | -------------------------------------------------------------------------------- /src/components/button.tsx: -------------------------------------------------------------------------------- 1 | import { Slot } from '@radix-ui/react-slot' 2 | import { cva, type VariantProps } from 'class-variance-authority' 3 | import * as React from 'react' 4 | 5 | import { cn } from '../lib/utils' 6 | 7 | const buttonVariants = cva( 8 | 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', 9 | { 10 | variants: { 11 | variant: { 12 | default: 13 | 'bg-primary text-primary-foreground shadow hover:bg-primary/90', 14 | destructive: 15 | 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90', 16 | outline: 17 | 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground', 18 | secondary: 19 | 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80', 20 | ghost: 'hover:bg-accent hover:text-accent-foreground', 21 | link: 'text-primary underline-offset-4 hover:underline', 22 | }, 23 | size: { 24 | default: 'h-9 px-4 py-2', 25 | sm: 'h-8 rounded-md px-3 text-xs', 26 | lg: 'h-10 rounded-md px-8', 27 | icon: 'h-9 w-9', 28 | }, 29 | }, 30 | defaultVariants: { 31 | variant: 'default', 32 | size: 'default', 33 | }, 34 | } 35 | ) 36 | 37 | export interface ButtonProps 38 | extends React.ButtonHTMLAttributes, 39 | VariantProps { 40 | asChild?: boolean 41 | } 42 | 43 | const Button = React.forwardRef( 44 | ({ className, variant, size, asChild = false, ...props }, ref) => { 45 | const Comp = asChild ? Slot : 'button' 46 | return ( 47 | 52 | ) 53 | } 54 | ) 55 | Button.displayName = 'Button' 56 | 57 | export { Button, buttonVariants } 58 | -------------------------------------------------------------------------------- /src/components/components.ts: -------------------------------------------------------------------------------- 1 | export { default as Card } from './Card.astro' 2 | export { default as CardGrid } from './CardGrid.astro' 3 | 4 | -------------------------------------------------------------------------------- /src/components/dropdown-menu.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' 4 | import { Check, ChevronRight, Circle } from 'lucide-react' 5 | import * as React from 'react' 6 | 7 | import { cn } from '../lib/utils' 8 | 9 | const DropdownMenu = DropdownMenuPrimitive.Root 10 | 11 | const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger 12 | 13 | const DropdownMenuGroup = DropdownMenuPrimitive.Group 14 | 15 | const DropdownMenuPortal = DropdownMenuPrimitive.Portal 16 | 17 | const DropdownMenuSub = DropdownMenuPrimitive.Sub 18 | 19 | const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup 20 | 21 | const DropdownMenuSubTrigger = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef & { 24 | inset?: boolean 25 | } 26 | >(({ className, inset, children, ...props }, ref) => ( 27 | 35 | {children} 36 | 37 | 38 | )) 39 | DropdownMenuSubTrigger.displayName = 40 | DropdownMenuPrimitive.SubTrigger.displayName 41 | 42 | const DropdownMenuSubContent = React.forwardRef< 43 | React.ElementRef, 44 | React.ComponentPropsWithoutRef 45 | >(({ className, ...props }, ref) => ( 46 | 54 | )) 55 | DropdownMenuSubContent.displayName = 56 | DropdownMenuPrimitive.SubContent.displayName 57 | 58 | const DropdownMenuContent = React.forwardRef< 59 | React.ElementRef, 60 | React.ComponentPropsWithoutRef 61 | >(({ className, sideOffset = 4, ...props }, ref) => ( 62 | 63 | 73 | 74 | )) 75 | DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName 76 | 77 | const DropdownMenuItem = React.forwardRef< 78 | React.ElementRef, 79 | React.ComponentPropsWithoutRef & { 80 | inset?: boolean 81 | } 82 | >(({ className, inset, ...props }, ref) => ( 83 | svg]:size-4 [&>svg]:shrink-0', 87 | inset && 'pl-8', 88 | className 89 | )} 90 | {...props} 91 | /> 92 | )) 93 | DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName 94 | 95 | const DropdownMenuCheckboxItem = React.forwardRef< 96 | React.ElementRef, 97 | React.ComponentPropsWithoutRef 98 | >(({ className, children, checked, ...props }, ref) => ( 99 | 107 | 108 | 109 | 110 | 111 | 112 | {children} 113 | 114 | )) 115 | DropdownMenuCheckboxItem.displayName = 116 | DropdownMenuPrimitive.CheckboxItem.displayName 117 | 118 | const DropdownMenuRadioItem = React.forwardRef< 119 | React.ElementRef, 120 | React.ComponentPropsWithoutRef 121 | >(({ className, children, ...props }, ref) => ( 122 | 129 | 130 | 131 | 132 | 133 | 134 | {children} 135 | 136 | )) 137 | DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName 138 | 139 | const DropdownMenuLabel = React.forwardRef< 140 | React.ElementRef, 141 | React.ComponentPropsWithoutRef & { 142 | inset?: boolean 143 | } 144 | >(({ className, inset, ...props }, ref) => ( 145 | 154 | )) 155 | DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName 156 | 157 | const DropdownMenuSeparator = React.forwardRef< 158 | React.ElementRef, 159 | React.ComponentPropsWithoutRef 160 | >(({ className, ...props }, ref) => ( 161 | 166 | )) 167 | DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName 168 | 169 | const DropdownMenuShortcut = ({ 170 | className, 171 | ...props 172 | }: React.HTMLAttributes) => { 173 | return ( 174 | 178 | ) 179 | } 180 | DropdownMenuShortcut.displayName = 'DropdownMenuShortcut' 181 | 182 | export { 183 | DropdownMenu, 184 | DropdownMenuCheckboxItem, 185 | DropdownMenuContent, 186 | DropdownMenuGroup, 187 | DropdownMenuItem, 188 | DropdownMenuLabel, 189 | DropdownMenuPortal, 190 | DropdownMenuRadioGroup, 191 | DropdownMenuRadioItem, 192 | DropdownMenuSeparator, 193 | DropdownMenuShortcut, 194 | DropdownMenuSub, 195 | DropdownMenuSubContent, 196 | DropdownMenuSubTrigger, 197 | DropdownMenuTrigger, 198 | } 199 | -------------------------------------------------------------------------------- /src/components/header-menu.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | DropdownMenu, 3 | DropdownMenuContent, 4 | DropdownMenuItem, 5 | DropdownMenuTrigger, 6 | } from "./dropdown-menu" 7 | import { MoreVertical } from "lucide-react" 8 | 9 | export function HeaderMenu() { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 | Support 23 | 24 | 25 | 26 | 31 | GitHub 32 | 33 | 34 | 35 | 36 | ) 37 | } -------------------------------------------------------------------------------- /src/components/icon.tsx: -------------------------------------------------------------------------------- 1 | import { icons } from 'lucide-react' 2 | import { memo } from 'react' 3 | 4 | import { type ClassValue, clsx } from 'clsx' 5 | import { twMerge } from 'tailwind-merge' 6 | 7 | export function cn(...inputs: ClassValue[]) { 8 | return twMerge(clsx(inputs)) 9 | } 10 | 11 | export type IconProps = { 12 | name: keyof typeof icons 13 | className?: string 14 | strokeWidth?: number 15 | } 16 | 17 | export const Icon = memo(({ name, className, strokeWidth }: IconProps) => { 18 | const IconComponent = icons[name] 19 | 20 | if (!IconComponent) { 21 | return null 22 | } 23 | 24 | return ( 25 | 29 | ) 30 | }) 31 | 32 | Icon.displayName = 'Icon' 33 | -------------------------------------------------------------------------------- /src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection } from 'astro:content'; 2 | import { docsSchema } from '@astrojs/starlight/schema'; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | }; 7 | -------------------------------------------------------------------------------- /src/content/docs/components/asides.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Asides 3 | description: A guide in my new Starlight docs site. 4 | --- 5 | 6 | import GroupName from '../../../components/GroupName.astro' 7 | import { Aside } from '@astrojs/starlight/components' 8 | import { Card } from '@astrojs/starlight/components' 9 | 10 | Components 11 | 12 | # Asides 13 | 14 | To display secondary information alongside a page’s main content, use the `