Showing preview only (389K chars total). Download the full file or copy to clipboard to get everything.
Repository: IHIutch/draft-ui
Branch: main
Commit: f63a2c8be76d
Files: 329
Total size: 312.1 KB
Directory structure:
gitextract_vesfxg_a/
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .husky/
│ └── pre-commit
├── .npmrc
├── .vscode/
│ └── settings.json
├── LICENSE.md
├── apps/
│ ├── docs/
│ │ ├── .eslintrc.js
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── __registry__/
│ │ │ └── index.tsx
│ │ ├── app/
│ │ │ ├── changelog/
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── docs/
│ │ │ │ └── [[...slug]]/
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── getting-started/
│ │ │ │ └── [[...slug]]/
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── page.tsx
│ │ │ ├── provider.tsx
│ │ │ ├── robots.tsx
│ │ │ └── sitemap.tsx
│ │ ├── components/
│ │ │ ├── analytics.tsx
│ │ │ ├── copy-clipboard-button.tsx
│ │ │ ├── docs/
│ │ │ │ ├── callout.tsx
│ │ │ │ ├── component-example.tsx
│ │ │ │ ├── component-source.tsx
│ │ │ │ ├── heading.tsx
│ │ │ │ ├── jump-to-content-menu.tsx
│ │ │ │ ├── list-stepper.tsx
│ │ │ │ └── markdown.tsx
│ │ │ ├── edit-feedback.tsx
│ │ │ ├── fathom-analytics.tsx
│ │ │ ├── home-page/
│ │ │ │ ├── cta-section.tsx
│ │ │ │ └── example-section.tsx
│ │ │ ├── link-list.tsx
│ │ │ ├── mode-toggle.tsx
│ │ │ ├── navigation.tsx
│ │ │ ├── page-toc.tsx
│ │ │ ├── search-component.tsx
│ │ │ └── theme-provider.tsx
│ │ ├── content/
│ │ │ ├── CHANGELOG.mdx
│ │ │ ├── components/
│ │ │ │ ├── breadcrumbs.mdx
│ │ │ │ ├── button.mdx
│ │ │ │ ├── checkbox-group.mdx
│ │ │ │ ├── checkbox.mdx
│ │ │ │ ├── combo-box.mdx
│ │ │ │ ├── date-picker.mdx
│ │ │ │ ├── date-range-picker.mdx
│ │ │ │ ├── grid-list.mdx
│ │ │ │ ├── icon-button.mdx
│ │ │ │ ├── input.mdx
│ │ │ │ ├── label.mdx
│ │ │ │ ├── menu.mdx
│ │ │ │ ├── meter.mdx
│ │ │ │ ├── modal.mdx
│ │ │ │ ├── number-field.mdx
│ │ │ │ ├── progress-bar.mdx
│ │ │ │ ├── radio-group.mdx
│ │ │ │ ├── radio.mdx
│ │ │ │ ├── search-field.mdx
│ │ │ │ ├── select.mdx
│ │ │ │ ├── slider.mdx
│ │ │ │ ├── switch.mdx
│ │ │ │ ├── table.mdx
│ │ │ │ ├── tabs.mdx
│ │ │ │ ├── text-field.mdx
│ │ │ │ ├── toggle-button.mdx
│ │ │ │ └── tooltip.mdx
│ │ │ └── getting-started/
│ │ │ ├── about.mdx
│ │ │ ├── cli.mdx
│ │ │ ├── installation.mdx
│ │ │ └── introduction.mdx
│ │ ├── contentlayer.config.ts
│ │ ├── lib/
│ │ │ ├── cva.config.ts
│ │ │ ├── rehype-component.ts
│ │ │ └── remark/
│ │ │ └── with-table-of-contents.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── postcss.config.js
│ │ ├── public/
│ │ │ └── site.webmanifest
│ │ ├── registry/
│ │ │ ├── breadcrumbs/
│ │ │ │ └── default.tsx
│ │ │ ├── button/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── sizes.tsx
│ │ │ │ └── theme.tsx
│ │ │ ├── calendar/
│ │ │ │ └── default.tsx
│ │ │ ├── checkbox/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── checkbox-group/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── horizontal.tsx
│ │ │ ├── combobox/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled-keys.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── with-button.tsx
│ │ │ ├── date-field/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── date-input/
│ │ │ │ ├── default.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── date-picker/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── date-range-picker/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── grid-list/
│ │ │ │ └── default.tsx
│ │ │ ├── icon-button/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── sizes.tsx
│ │ │ │ └── theme.tsx
│ │ │ ├── input/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── label/
│ │ │ │ └── default.tsx
│ │ │ ├── menu/
│ │ │ │ ├── as-checkbox.tsx
│ │ │ │ ├── as-radio.tsx
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── with-sections.tsx
│ │ │ ├── meter/
│ │ │ │ └── default.tsx
│ │ │ ├── modal/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── dismissable-false.tsx
│ │ │ │ ├── set-autofocus.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── number-field/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── with-mobile-stepper.tsx
│ │ │ │ └── with-stepper.tsx
│ │ │ ├── progress-bar/
│ │ │ │ └── default.tsx
│ │ │ ├── radio/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── radio-group/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── horizontal.tsx
│ │ │ ├── range-calendar/
│ │ │ │ └── default.tsx
│ │ │ ├── search-field/
│ │ │ │ ├── default.tsx
│ │ │ │ └── with-clear-button.tsx
│ │ │ ├── select/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── slider/
│ │ │ │ ├── default.tsx
│ │ │ │ └── vertical.tsx
│ │ │ ├── switch/
│ │ │ │ ├── alignment.tsx
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── tabs/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled-keys.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── vertical.tsx
│ │ │ ├── text-field/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── with-error.tsx
│ │ │ └── tooltip/
│ │ │ ├── default.tsx
│ │ │ └── placement.tsx
│ │ ├── styles/
│ │ │ └── globals.css
│ │ ├── tailwind.config.js
│ │ ├── tsconfig.json
│ │ └── types.ts
│ └── storybook/
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── .storybook/
│ │ ├── main.ts
│ │ └── preview.ts
│ ├── package.json
│ ├── postcss.config.cjs
│ ├── src/
│ │ ├── components/
│ │ │ ├── breadcrumbs/
│ │ │ │ ├── breadcrumbs.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ └── default.tsx
│ │ │ ├── button/
│ │ │ │ ├── button.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── sizes.tsx
│ │ │ │ └── theme.tsx
│ │ │ ├── calendar/
│ │ │ │ ├── calendar.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ └── default.tsx
│ │ │ ├── checkbox/
│ │ │ │ ├── checkbox.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── checkbox-group/
│ │ │ │ ├── checkbox-group.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── horizontal.tsx
│ │ │ ├── combobox/
│ │ │ │ ├── combo-box.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled-keys.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── with-button.tsx
│ │ │ ├── date-field/
│ │ │ │ ├── date-field.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── date-input/
│ │ │ │ ├── date-input.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── date-picker/
│ │ │ │ ├── date-picker.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── date-range-picker/
│ │ │ │ ├── date-range-picker.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── grid-list/
│ │ │ │ ├── grid-list.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ └── default.tsx
│ │ │ ├── icon-button/
│ │ │ │ ├── icon-button.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── sizes.tsx
│ │ │ │ └── theme.tsx
│ │ │ ├── input/
│ │ │ │ ├── input.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── label/
│ │ │ │ ├── label.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ └── default.tsx
│ │ │ ├── menu/
│ │ │ │ ├── menu.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── as-checkbox.tsx
│ │ │ │ ├── as-radio.tsx
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── with-sections.tsx
│ │ │ ├── meter/
│ │ │ │ ├── meter.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ └── default.tsx
│ │ │ ├── modal/
│ │ │ │ ├── modal.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── dismissable-false.tsx
│ │ │ │ ├── set-autofocus.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── number-field/
│ │ │ │ ├── number-field.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ ├── with-mobile-stepper.tsx
│ │ │ │ └── with-stepper.tsx
│ │ │ ├── progress-bar/
│ │ │ │ ├── progress-bar.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ └── default.tsx
│ │ │ ├── radio/
│ │ │ │ ├── radio.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── sizes.tsx
│ │ │ ├── radio-group/
│ │ │ │ ├── radio-group.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ ├── disabled.tsx
│ │ │ │ └── horizontal.tsx
│ │ │ ├── range-calendar/
│ │ │ │ ├── range-calendar.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ └── default.tsx
│ │ │ ├── search-field/
│ │ │ │ ├── search-field.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── with-clear-button.tsx
│ │ │ ├── select/
│ │ │ │ ├── select.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── disabled.tsx
│ │ │ ├── slider/
│ │ │ │ ├── slider.stories.tsx
│ │ │ │ └── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── vertical.tsx
│ │ │ ├── switch/
│ │ │ │ ├── stories/
│ │ │ │ │ ├── alignment.tsx
│ │ │ │ │ ├── default.tsx
│ │ │ │ │ ├── disabled.tsx
│ │ │ │ │ └── sizes.tsx
│ │ │ │ └── switch.stories.tsx
│ │ │ ├── tabs/
│ │ │ │ ├── stories/
│ │ │ │ │ ├── default.tsx
│ │ │ │ │ ├── disabled-keys.tsx
│ │ │ │ │ ├── disabled.tsx
│ │ │ │ │ └── vertical.tsx
│ │ │ │ └── tabs.stories.tsx
│ │ │ ├── text-field/
│ │ │ │ ├── stories/
│ │ │ │ │ ├── default.tsx
│ │ │ │ │ ├── disabled.tsx
│ │ │ │ │ └── with-error.tsx
│ │ │ │ └── text-field.stories.tsx
│ │ │ └── tooltip/
│ │ │ ├── stories/
│ │ │ │ ├── default.tsx
│ │ │ │ └── placement.tsx
│ │ │ └── tooltip.stories.tsx
│ │ └── styles.css
│ ├── tailwind.config.cjs
│ └── tsconfig.json
├── package.json
├── packages/
│ ├── eslint-config-custom/
│ │ ├── index.js
│ │ └── package.json
│ ├── postcss-config/
│ │ ├── package.json
│ │ └── postcss.config.cjs
│ ├── tailwind-config/
│ │ ├── package.json
│ │ └── tailwind.config.cjs
│ ├── ts-config/
│ │ ├── base.json
│ │ ├── nextjs.json
│ │ ├── package.json
│ │ └── react-library.json
│ └── ui/
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── lib/
│ │ └── cva.config.ts
│ ├── package.json
│ ├── postcss.config.cjs
│ ├── src/
│ │ ├── breadcrumbs.tsx
│ │ ├── button.tsx
│ │ ├── calendar.tsx
│ │ ├── checkbox-group.tsx
│ │ ├── checkbox.tsx
│ │ ├── combobox.tsx
│ │ ├── date-input.tsx
│ │ ├── date-picker.tsx
│ │ ├── date-range-picker.tsx
│ │ ├── grid-list.tsx
│ │ ├── icon-button.tsx
│ │ ├── index.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── menu.tsx
│ │ ├── meter.tsx
│ │ ├── modal.tsx
│ │ ├── number-field.tsx
│ │ ├── progress-bar.tsx
│ │ ├── radio-group.tsx
│ │ ├── radio.tsx
│ │ ├── search-field.tsx
│ │ ├── select.tsx
│ │ ├── slider.tsx
│ │ ├── styles.css
│ │ ├── switch.tsx
│ │ ├── table.tsx
│ │ ├── tabs.tsx
│ │ ├── text-field.tsx
│ │ ├── toggle-button.tsx
│ │ └── tooltip.tsx
│ ├── tailwind.config.cjs
│ └── tsconfig.json
├── pnpm-workspace.yaml
├── prettier.config.cjs
├── scripts/
│ ├── package.json
│ ├── src/
│ │ └── build-registry.ts
│ └── tsconfig.json
├── tsconfig.json
├── turbo.json
└── vercel.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .eslintrc.js
================================================
module.exports = {
root: true,
extends: ['custom'],
settings: {
next: {
rootDir: ['apps/docs/*/'],
},
},
}
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
.pnp
.pnp.js
# testing
coverage
# next.js
.next/
out/
# production
build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
# contentlayer
.contentlayer
storybook-static/
# turbo
.turbo
#ui
dist/
================================================
FILE: .husky/pre-commit
================================================
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
================================================
FILE: .npmrc
================================================
auto-install-peers=true
legacy-peer-deps=true
node-linker=hoisted
================================================
FILE: .vscode/settings.json
================================================
{
"prettier.enable": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// The following is optional.
// It's better to put under project setting `.vscode/settings.json`
// to avoid conflicts with working with different eslint configs
// that does not support all formats.
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
// "markdown",
"json",
"yaml"
],
"files.associations": {
"*.mdx": "mdx"
},
"tailwindCSS.experimental.classRegex": [
[
"cva\\(([^)]*)\\)",
"[\"'`]([^\"'`]*).*?[\"'`]"
],
[
"cx\\(([^)]*)\\)",
"(?:'|\"|`)([^']*)(?:'|\"|`)"
]
],
"typescript.tsdk": "node_modules/typescript/lib"
}
================================================
FILE: LICENSE.md
================================================
MIT License
Copyright (c) 2024 Jonathan Hutchison
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: apps/docs/.eslintrc.js
================================================
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path')
module.exports = {
root: true,
extends: ['custom'],
rules: {
'@next/next/no-html-link-for-pages': 'off',
},
settings: {
tailwindcss: {
config: path.join(__dirname, './tailwind.config.js'),
},
},
overrides: [
// MDX
{
files: ['*.md', '*.mdx'],
extends: ['plugin:mdx/recommended'],
},
],
ignorePatterns: ['registry/**/*.tsx'],
}
================================================
FILE: apps/docs/.gitignore
================================================
.vscode
.env
# contentlayer
.contentlayer
================================================
FILE: apps/docs/README.md
================================================
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
================================================
FILE: apps/docs/__registry__/index.tsx
================================================
/* eslint-disable prettier/prettier */
// @ts-nocheck
// This file is autogenerated by scripts/build-registry.ts
// Do not edit this file directly.
import * as React from "react"
type ComponentRegistry = Record<
string,
Record<
string,
{
name: string
story: string
component: string
file: string
}
>
>
export const Index: ComponentRegistry = {
"breadcrumbs": {
"default": {
name: "breadcrumbs-default",
story: "default",
component: React.lazy(() => import("@/registry/breadcrumbs/default")),
file: "registry/breadcrumbs/default.tsx"
},
},
"button": {
"default": {
name: "button-default",
story: "default",
component: React.lazy(() => import("@/registry/button/default")),
file: "registry/button/default.tsx"
},
"disabled": {
name: "button-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/button/disabled")),
file: "registry/button/disabled.tsx"
},
"sizes": {
name: "button-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/button/sizes")),
file: "registry/button/sizes.tsx"
},
"theme": {
name: "button-theme",
story: "theme",
component: React.lazy(() => import("@/registry/button/theme")),
file: "registry/button/theme.tsx"
},
},
"calendar": {
"default": {
name: "calendar-default",
story: "default",
component: React.lazy(() => import("@/registry/calendar/default")),
file: "registry/calendar/default.tsx"
},
},
"checkbox": {
"default": {
name: "checkbox-default",
story: "default",
component: React.lazy(() => import("@/registry/checkbox/default")),
file: "registry/checkbox/default.tsx"
},
"disabled": {
name: "checkbox-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/checkbox/disabled")),
file: "registry/checkbox/disabled.tsx"
},
"sizes": {
name: "checkbox-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/checkbox/sizes")),
file: "registry/checkbox/sizes.tsx"
},
},
"checkbox-group": {
"default": {
name: "checkbox-group-default",
story: "default",
component: React.lazy(() => import("@/registry/checkbox-group/default")),
file: "registry/checkbox-group/default.tsx"
},
"disabled": {
name: "checkbox-group-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/checkbox-group/disabled")),
file: "registry/checkbox-group/disabled.tsx"
},
"horizontal": {
name: "checkbox-group-horizontal",
story: "horizontal",
component: React.lazy(() => import("@/registry/checkbox-group/horizontal")),
file: "registry/checkbox-group/horizontal.tsx"
},
},
"combobox": {
"default": {
name: "combobox-default",
story: "default",
component: React.lazy(() => import("@/registry/combobox/default")),
file: "registry/combobox/default.tsx"
},
"disabled-keys": {
name: "combobox-disabled-keys",
story: "disabled-keys",
component: React.lazy(() => import("@/registry/combobox/disabled-keys")),
file: "registry/combobox/disabled-keys.tsx"
},
"disabled": {
name: "combobox-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/combobox/disabled")),
file: "registry/combobox/disabled.tsx"
},
"with-button": {
name: "combobox-with-button",
story: "with-button",
component: React.lazy(() => import("@/registry/combobox/with-button")),
file: "registry/combobox/with-button.tsx"
},
},
"date-field": {
"default": {
name: "date-field-default",
story: "default",
component: React.lazy(() => import("@/registry/date-field/default")),
file: "registry/date-field/default.tsx"
},
"disabled": {
name: "date-field-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/date-field/disabled")),
file: "registry/date-field/disabled.tsx"
},
},
"date-input": {
"default": {
name: "date-input-default",
story: "default",
component: React.lazy(() => import("@/registry/date-input/default")),
file: "registry/date-input/default.tsx"
},
"sizes": {
name: "date-input-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/date-input/sizes")),
file: "registry/date-input/sizes.tsx"
},
},
"date-picker": {
"default": {
name: "date-picker-default",
story: "default",
component: React.lazy(() => import("@/registry/date-picker/default")),
file: "registry/date-picker/default.tsx"
},
"disabled": {
name: "date-picker-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/date-picker/disabled")),
file: "registry/date-picker/disabled.tsx"
},
},
"date-range-picker": {
"default": {
name: "date-range-picker-default",
story: "default",
component: React.lazy(() => import("@/registry/date-range-picker/default")),
file: "registry/date-range-picker/default.tsx"
},
"disabled": {
name: "date-range-picker-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/date-range-picker/disabled")),
file: "registry/date-range-picker/disabled.tsx"
},
},
"grid-list": {
"default": {
name: "grid-list-default",
story: "default",
component: React.lazy(() => import("@/registry/grid-list/default")),
file: "registry/grid-list/default.tsx"
},
},
"icon-button": {
"default": {
name: "icon-button-default",
story: "default",
component: React.lazy(() => import("@/registry/icon-button/default")),
file: "registry/icon-button/default.tsx"
},
"disabled": {
name: "icon-button-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/icon-button/disabled")),
file: "registry/icon-button/disabled.tsx"
},
"sizes": {
name: "icon-button-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/icon-button/sizes")),
file: "registry/icon-button/sizes.tsx"
},
"theme": {
name: "icon-button-theme",
story: "theme",
component: React.lazy(() => import("@/registry/icon-button/theme")),
file: "registry/icon-button/theme.tsx"
},
},
"input": {
"default": {
name: "input-default",
story: "default",
component: React.lazy(() => import("@/registry/input/default")),
file: "registry/input/default.tsx"
},
"disabled": {
name: "input-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/input/disabled")),
file: "registry/input/disabled.tsx"
},
"sizes": {
name: "input-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/input/sizes")),
file: "registry/input/sizes.tsx"
},
},
"label": {
"default": {
name: "label-default",
story: "default",
component: React.lazy(() => import("@/registry/label/default")),
file: "registry/label/default.tsx"
},
},
"menu": {
"as-checkbox": {
name: "menu-as-checkbox",
story: "as-checkbox",
component: React.lazy(() => import("@/registry/menu/as-checkbox")),
file: "registry/menu/as-checkbox.tsx"
},
"as-radio": {
name: "menu-as-radio",
story: "as-radio",
component: React.lazy(() => import("@/registry/menu/as-radio")),
file: "registry/menu/as-radio.tsx"
},
"default": {
name: "menu-default",
story: "default",
component: React.lazy(() => import("@/registry/menu/default")),
file: "registry/menu/default.tsx"
},
"disabled": {
name: "menu-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/menu/disabled")),
file: "registry/menu/disabled.tsx"
},
"with-sections": {
name: "menu-with-sections",
story: "with-sections",
component: React.lazy(() => import("@/registry/menu/with-sections")),
file: "registry/menu/with-sections.tsx"
},
},
"meter": {
"default": {
name: "meter-default",
story: "default",
component: React.lazy(() => import("@/registry/meter/default")),
file: "registry/meter/default.tsx"
},
},
"modal": {
"default": {
name: "modal-default",
story: "default",
component: React.lazy(() => import("@/registry/modal/default")),
file: "registry/modal/default.tsx"
},
"dismissable-false": {
name: "modal-dismissable-false",
story: "dismissable-false",
component: React.lazy(() => import("@/registry/modal/dismissable-false")),
file: "registry/modal/dismissable-false.tsx"
},
"set-autofocus": {
name: "modal-set-autofocus",
story: "set-autofocus",
component: React.lazy(() => import("@/registry/modal/set-autofocus")),
file: "registry/modal/set-autofocus.tsx"
},
"sizes": {
name: "modal-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/modal/sizes")),
file: "registry/modal/sizes.tsx"
},
},
"number-field": {
"default": {
name: "number-field-default",
story: "default",
component: React.lazy(() => import("@/registry/number-field/default")),
file: "registry/number-field/default.tsx"
},
"disabled": {
name: "number-field-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/number-field/disabled")),
file: "registry/number-field/disabled.tsx"
},
"with-mobile-stepper": {
name: "number-field-with-mobile-stepper",
story: "with-mobile-stepper",
component: React.lazy(() => import("@/registry/number-field/with-mobile-stepper")),
file: "registry/number-field/with-mobile-stepper.tsx"
},
"with-stepper": {
name: "number-field-with-stepper",
story: "with-stepper",
component: React.lazy(() => import("@/registry/number-field/with-stepper")),
file: "registry/number-field/with-stepper.tsx"
},
},
"progress-bar": {
"default": {
name: "progress-bar-default",
story: "default",
component: React.lazy(() => import("@/registry/progress-bar/default")),
file: "registry/progress-bar/default.tsx"
},
},
"radio": {
"default": {
name: "radio-default",
story: "default",
component: React.lazy(() => import("@/registry/radio/default")),
file: "registry/radio/default.tsx"
},
"disabled": {
name: "radio-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/radio/disabled")),
file: "registry/radio/disabled.tsx"
},
"sizes": {
name: "radio-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/radio/sizes")),
file: "registry/radio/sizes.tsx"
},
},
"radio-group": {
"default": {
name: "radio-group-default",
story: "default",
component: React.lazy(() => import("@/registry/radio-group/default")),
file: "registry/radio-group/default.tsx"
},
"disabled": {
name: "radio-group-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/radio-group/disabled")),
file: "registry/radio-group/disabled.tsx"
},
"horizontal": {
name: "radio-group-horizontal",
story: "horizontal",
component: React.lazy(() => import("@/registry/radio-group/horizontal")),
file: "registry/radio-group/horizontal.tsx"
},
},
"range-calendar": {
"default": {
name: "range-calendar-default",
story: "default",
component: React.lazy(() => import("@/registry/range-calendar/default")),
file: "registry/range-calendar/default.tsx"
},
},
"search-field": {
"default": {
name: "search-field-default",
story: "default",
component: React.lazy(() => import("@/registry/search-field/default")),
file: "registry/search-field/default.tsx"
},
"with-clear-button": {
name: "search-field-with-clear-button",
story: "with-clear-button",
component: React.lazy(() => import("@/registry/search-field/with-clear-button")),
file: "registry/search-field/with-clear-button.tsx"
},
},
"select": {
"default": {
name: "select-default",
story: "default",
component: React.lazy(() => import("@/registry/select/default")),
file: "registry/select/default.tsx"
},
"disabled": {
name: "select-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/select/disabled")),
file: "registry/select/disabled.tsx"
},
},
"slider": {
"default": {
name: "slider-default",
story: "default",
component: React.lazy(() => import("@/registry/slider/default")),
file: "registry/slider/default.tsx"
},
"vertical": {
name: "slider-vertical",
story: "vertical",
component: React.lazy(() => import("@/registry/slider/vertical")),
file: "registry/slider/vertical.tsx"
},
},
"switch": {
"alignment": {
name: "switch-alignment",
story: "alignment",
component: React.lazy(() => import("@/registry/switch/alignment")),
file: "registry/switch/alignment.tsx"
},
"default": {
name: "switch-default",
story: "default",
component: React.lazy(() => import("@/registry/switch/default")),
file: "registry/switch/default.tsx"
},
"disabled": {
name: "switch-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/switch/disabled")),
file: "registry/switch/disabled.tsx"
},
"sizes": {
name: "switch-sizes",
story: "sizes",
component: React.lazy(() => import("@/registry/switch/sizes")),
file: "registry/switch/sizes.tsx"
},
},
"tabs": {
"default": {
name: "tabs-default",
story: "default",
component: React.lazy(() => import("@/registry/tabs/default")),
file: "registry/tabs/default.tsx"
},
"disabled-keys": {
name: "tabs-disabled-keys",
story: "disabled-keys",
component: React.lazy(() => import("@/registry/tabs/disabled-keys")),
file: "registry/tabs/disabled-keys.tsx"
},
"disabled": {
name: "tabs-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/tabs/disabled")),
file: "registry/tabs/disabled.tsx"
},
"vertical": {
name: "tabs-vertical",
story: "vertical",
component: React.lazy(() => import("@/registry/tabs/vertical")),
file: "registry/tabs/vertical.tsx"
},
},
"text-field": {
"default": {
name: "text-field-default",
story: "default",
component: React.lazy(() => import("@/registry/text-field/default")),
file: "registry/text-field/default.tsx"
},
"disabled": {
name: "text-field-disabled",
story: "disabled",
component: React.lazy(() => import("@/registry/text-field/disabled")),
file: "registry/text-field/disabled.tsx"
},
"with-error": {
name: "text-field-with-error",
story: "with-error",
component: React.lazy(() => import("@/registry/text-field/with-error")),
file: "registry/text-field/with-error.tsx"
},
},
"tooltip": {
"default": {
name: "tooltip-default",
story: "default",
component: React.lazy(() => import("@/registry/tooltip/default")),
file: "registry/tooltip/default.tsx"
},
"placement": {
name: "tooltip-placement",
story: "placement",
component: React.lazy(() => import("@/registry/tooltip/placement")),
file: "registry/tooltip/placement.tsx"
},
},
};
================================================
FILE: apps/docs/app/changelog/layout.tsx
================================================
import {
allChangelogDocuments,
allComponentDocuments,
allGeneralDocuments,
} from 'contentlayer/generated'
import { notFound } from 'next/navigation'
import JumpToContentMenu from '@/components/docs/jump-to-content-menu'
import LinkList from '@/components/link-list'
import Navigation from '@/components/navigation'
const sortedComponents = allComponentDocuments
.filter((doc) => doc.isComponent === true)
.sort((a, b) => a.title.localeCompare(b.title))
.map((doc) => ({
isComing: doc?.isComing || false,
isWip: doc?.isWip || false,
slug: doc.slug,
title: doc.title,
}))
const sortedDocuments = [...allGeneralDocuments, ...allChangelogDocuments]
.sort((a, b) => a.order - b.order)
.map((doc) => ({
isNew: 'isNew' in doc ? doc.isNew : false,
slug: doc.slug,
title: doc.title,
}))
export default async function DocsLayout({
children,
}: {
children: React.ReactNode
}) {
const post = allChangelogDocuments[0]
if (!post) {
notFound()
}
return (
<div className="container mx-auto h-full px-4">
<JumpToContentMenu toc={post.toc} />
<Navigation
gettingStartedList={sortedDocuments}
componentList={sortedComponents}
/>
<aside className="fixed top-0 hidden h-full shrink-0 border-r pt-14 dark:border-slate-800 md:w-56 lg:block">
<nav
className="-ml-3 h-full overflow-y-auto py-10 pl-3"
id="site-navigation"
tabIndex={-1}
>
<div className="mb-4">
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Getting Started
</h4>
<div className="mt-3 pr-3">
<LinkList list={sortedDocuments} />
</div>
</div>
<div>
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Components
</h4>
<div className="mt-3 pr-3">
<LinkList list={sortedComponents} />
</div>
</div>
</nav>
</aside>
<div className="pt-16 lg:ml-56">
<main className="flex" id="page-content" tabIndex={-1}>
{children}
{/* <Footer /> */}
</main>
</div>
</div>
)
}
================================================
FILE: apps/docs/app/changelog/page.tsx
================================================
import * as React from 'react'
import { allChangelogDocuments } from 'contentlayer/generated'
import { type Metadata, type ResolvingMetadata } from 'next'
import { notFound } from 'next/navigation'
import Markdown from '@/components/docs/markdown'
import PageToc from '@/components/page-toc'
export function generateStaticParams() {
return allChangelogDocuments
}
export async function generateMetadata(
_,
parent: ResolvingMetadata,
): Promise<Metadata> {
const post = allChangelogDocuments[0]
if (!post) {
notFound()
}
const parentMeta = await parent
return {
title: post.title,
description: post.description || parentMeta?.openGraph?.description,
openGraph: {
siteName: parentMeta?.openGraph?.siteName,
title: post.title || parentMeta?.openGraph?.title,
description: post.description || parentMeta?.openGraph?.description,
images: parentMeta?.openGraph?.images || [],
url: post.slug,
locale: parentMeta?.openGraph?.locale,
},
twitter: {
title: post.title || parentMeta?.twitter?.title,
description: post.description || parentMeta?.twitter?.description || '',
images: parentMeta?.twitter?.images || [],
card: parentMeta?.twitter?.card,
},
alternates: {
canonical: '/changelog',
},
}
}
export default function ChangelogPage() {
const post = allChangelogDocuments[0]
if (!post) {
notFound()
}
return (
<>
<div className="order-2 hidden shrink-0 lg:w-1/4 xl:block">
<div className="fixed top-0 h-screen pt-16">
<div className="h-full overflow-y-auto">
<div className="my-12 px-4 md:pl-8">
<PageToc headings={post.toc} />
</div>
</div>
</div>
</div>
<article className="my-12 w-full">
<div className="prose prose-slate order-1 mx-auto dark:prose-invert">
<h1>{post.title}</h1>
<p className="lead">{post.description}</p>
<Markdown doc={post} />
</div>
</article>
</>
)
}
================================================
FILE: apps/docs/app/docs/[[...slug]]/layout.tsx
================================================
import {
allChangelogDocuments,
allComponentDocuments,
allGeneralDocuments,
} from 'contentlayer/generated'
import { notFound } from 'next/navigation'
import JumpToContentMenu from '@/components/docs/jump-to-content-menu'
import LinkList from '@/components/link-list'
import Navigation from '@/components/navigation'
const sortedComponents = allComponentDocuments
.filter((doc) => doc.isComponent === true)
.sort((a, b) => a.title.localeCompare(b.title))
.map((doc) => ({
isComing: doc?.isComing || false,
isWip: doc?.isWip || false,
slug: doc.slug,
title: doc.title,
}))
const sortedDocuments = [...allGeneralDocuments, ...allChangelogDocuments]
.sort((a, b) => a.order - b.order)
.map((doc) => ({
isNew: 'isNew' in doc ? doc.isNew : false,
slug: doc.slug,
title: doc.title,
}))
export default function DocsLayout({
params,
children,
}: {
params: { slug: Array<string> }
children: React.ReactNode
}) {
const post = allComponentDocuments.find((post) => {
return (
post._raw.flattenedPath.replace('docs/', '') === params.slug.join('/')
)
})
if (!post) {
notFound()
}
return (
<div className="container mx-auto h-full px-4">
<JumpToContentMenu toc={post.toc} />
<Navigation
gettingStartedList={sortedDocuments}
componentList={sortedComponents}
/>
<aside className="fixed top-0 hidden h-full shrink-0 border-r pt-14 dark:border-slate-800 md:w-56 lg:block">
<nav
className="-ml-3 h-full overflow-y-auto py-10 pl-3"
id="site-navigation"
tabIndex={-1}
>
<div className="mb-4">
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Getting Started
</h4>
<div className="mt-3 pr-3">
<LinkList list={sortedDocuments} />
</div>
</div>
<div>
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Components
</h4>
<div className="mt-3 pr-3">
<LinkList list={sortedComponents} />
</div>
</div>
</nav>
</aside>
<div className="pt-16 lg:ml-56">
<div className="flex">
{children}
{/* <Footer /> */}
</div>
</div>
</div>
)
}
================================================
FILE: apps/docs/app/docs/[[...slug]]/page.tsx
================================================
import { allComponentDocuments } from 'contentlayer/generated'
import { type Metadata, type ResolvingMetadata } from 'next'
import { notFound } from 'next/navigation'
import Markdown from '@/components/docs/markdown'
import EditFeedbackLinks from '@/components/edit-feedback'
import PageToc from '@/components/page-toc'
export function generateStaticParams() {
return allComponentDocuments.map((post) => {
return {
slug: post._raw.flattenedPath.split('/'),
}
})
}
export async function generateMetadata(
{ params }: { params: { slug: string[] } },
parent: ResolvingMetadata,
): Promise<Metadata> {
const post = allComponentDocuments.find((post) => {
return (
post._raw.flattenedPath.replace('docs/', '') === params.slug.join('/')
)
})
if (!post) {
notFound()
}
const parentMeta = await parent
return {
title: post.title,
description: post.description || parentMeta?.openGraph?.description,
openGraph: {
siteName: parentMeta?.openGraph?.siteName,
title: post.title || parentMeta?.openGraph?.title,
description: post.description || parentMeta?.openGraph?.description,
images: parentMeta?.openGraph?.images || [],
url: post.slug,
locale: parentMeta?.openGraph?.locale,
},
twitter: {
title: post.title || parentMeta?.twitter?.title,
description: post.description || parentMeta?.twitter?.description || '',
images: parentMeta?.twitter?.images || [],
card: parentMeta?.twitter?.card,
},
alternates: {
canonical: post.slug,
},
}
}
export default function DocPage({
params,
}: {
params: { slug: Array<string> }
}) {
const post = allComponentDocuments.find((post) => {
return (
post._raw.flattenedPath.replace('docs/', '') === params.slug.join('/')
)
})
if (!post) {
notFound()
}
return (
<>
<div className="order-2 hidden shrink-0 lg:w-1/4 xl:block">
<div className="fixed top-0 h-screen pt-16">
<div className="h-full overflow-y-auto">
<div className="my-12 px-4 md:pl-8">
<PageToc headings={post.toc} />
<EditFeedbackLinks
title={post.title}
contentPath={post._raw.sourceFilePath}
/>
</div>
</div>
</div>
</div>
<main
className="order-1 my-12 w-full scroll-mt-20"
id="page-content"
tabIndex={-1}
>
<div className="prose prose-slate mx-auto dark:prose-invert">
<h1>{post.title}</h1>
<p className="lead">{post.description}</p>
<Markdown doc={post} />
</div>
</main>
</>
)
}
================================================
FILE: apps/docs/app/getting-started/[[...slug]]/layout.tsx
================================================
import {
allChangelogDocuments,
allComponentDocuments,
allGeneralDocuments,
} from 'contentlayer/generated'
import { notFound } from 'next/navigation'
import JumpToContentMenu from '@/components/docs/jump-to-content-menu'
import LinkList from '@/components/link-list'
import Navigation from '@/components/navigation'
const sortedComponents = allComponentDocuments
.filter((doc) => doc.isComponent === true)
.sort((a, b) => a.title.localeCompare(b.title))
.map((doc) => ({
isComing: doc?.isComing || false,
isWip: doc?.isWip || false,
slug: doc.slug,
title: doc.title,
}))
const sortedDocuments = [...allGeneralDocuments, ...allChangelogDocuments]
.sort((a, b) => a.order - b.order)
.map((doc) => ({
isNew: 'isNew' in doc ? doc.isNew : false,
slug: doc.slug,
title: doc.title,
}))
export default function DocsLayout({
params,
children,
}: {
params: { slug: Array<string> }
children: React.ReactNode
}) {
const post = allGeneralDocuments.find((post) => {
return (
post._raw.flattenedPath.replace('getting-started/', '') ===
params.slug.join('/')
)
})
if (!post) {
notFound()
}
return (
<div className="container mx-auto h-full px-4">
<JumpToContentMenu toc={post.toc} />
<Navigation
gettingStartedList={sortedDocuments}
componentList={sortedComponents}
/>
<aside className="fixed top-0 hidden h-full shrink-0 border-r pt-14 dark:border-slate-800 md:w-56 lg:block">
<nav
className="-ml-3 h-full overflow-y-auto py-10 pl-3"
id="site-navigation"
tabIndex={-1}
>
<div className="mb-4">
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Getting Started
</h4>
<div className="mt-3 pr-3">
<LinkList list={sortedDocuments} />
</div>
</div>
<div>
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Components
</h4>
<div className="mt-3 pr-3">
<LinkList list={sortedComponents} />
</div>
</div>
</nav>
</aside>
<div className="pt-16 lg:ml-56">
<main className="flex" id="page-content" tabIndex={-1}>
{children}
{/* <Footer /> */}
</main>
</div>
</div>
)
}
================================================
FILE: apps/docs/app/getting-started/[[...slug]]/page.tsx
================================================
import * as React from 'react'
import { allGeneralDocuments } from 'contentlayer/generated'
import { type Metadata, type ResolvingMetadata } from 'next'
import { notFound } from 'next/navigation'
import Markdown from '@/components/docs/markdown'
import EditFeedbackLinks from '@/components/edit-feedback'
import PageToc from '@/components/page-toc'
export function generateStaticParams() {
return allGeneralDocuments.map((post) => {
return {
slug: post._raw.flattenedPath.split('/'),
}
})
}
export async function generateMetadata(
{ params }: { params: { slug: string[] } },
parent: ResolvingMetadata,
): Promise<Metadata> {
const post = allGeneralDocuments.find((post) => {
return (
post._raw.flattenedPath.replace('getting-started/', '') ===
params.slug.join('/')
)
})
if (!post) {
notFound()
}
const parentMeta = await parent
return {
title: post.title,
description: post.description || parentMeta?.openGraph?.description,
openGraph: {
siteName: parentMeta?.openGraph?.siteName,
title: post.title || parentMeta?.openGraph?.title,
description: post.description || parentMeta?.openGraph?.description,
images: parentMeta?.openGraph?.images || [],
url: post.slug,
locale: parentMeta?.openGraph?.locale,
},
twitter: {
title: post.title || parentMeta?.twitter?.title,
description: post.description || parentMeta?.twitter?.description || '',
images: parentMeta?.twitter?.images || [],
card: parentMeta?.twitter?.card,
},
alternates: {
canonical: post.slug,
},
}
}
export default function GettingStartedPage({
params,
}: {
params: { slug: string[] }
}) {
const post = allGeneralDocuments.find((post) => {
return (
post._raw.flattenedPath.replace('getting-started/', '') ===
params.slug.join('/')
)
})
if (!post) {
notFound()
}
return (
<>
<div className="order-2 hidden shrink-0 lg:w-1/4 xl:block">
<div className="fixed top-0 h-screen pt-16">
<div className="h-full overflow-y-auto">
<div className="my-12 px-4 md:pl-8">
{post.toc.length > 0 ? <PageToc headings={post.toc} /> : null}
<EditFeedbackLinks
contentPath={post._raw.sourceFilePath}
title={post.title}
/>
</div>
</div>
</div>
</div>
<article className="my-12 w-full">
<div className="prose prose-slate order-1 mx-auto dark:prose-invert">
<h1>{post.title}</h1>
<p className="lead">{post.description}</p>
<Markdown doc={post} />
</div>
</article>
</>
)
}
================================================
FILE: apps/docs/app/layout.tsx
================================================
import '@/styles/globals.css'
import { type Metadata } from 'next'
import { Inter } from 'next/font/google'
import Analytics from '@/components/analytics'
import ThemeProvider from '@/components/theme-provider'
import { ClientProviders } from './provider'
interface DocsLayoutProps {
children: React.ReactNode
}
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export function generateMetadata(): Metadata {
const siteName = 'Draft UI'
const siteUrl = 'https://draft-ui.com'
const description =
'A collection of simply designed React components focused on making web accessibility easier than ever. Built with React Aria and Tailwind CSS.'
const imageUrl = '/meta.jpg'
const imageAlt =
'The Draft UI name and logo overlaying a whisp of wofting smoke'
return {
metadataBase: new URL(siteUrl),
title: {
template: `%s · ${siteName}`,
default: siteName,
},
description,
openGraph: {
siteName,
title: {
template: `%s · ${siteName}`,
default: siteName,
},
description,
url: '/',
images: {
url: imageUrl,
alt: imageAlt,
},
type: 'website',
locale: 'US_en',
},
twitter: {
title: {
template: `%s · ${siteName}`,
default: siteName,
},
description,
images: {
url: imageUrl,
alt: imageAlt,
},
card: 'summary_large_image',
},
verification: {
google: 'hsAvKsU0gaaI6wN1wUtrHAEMVQORMU08rUqYQHMj1x0',
},
alternates: {
canonical: '/',
},
}
}
export default function DocsLayout({ children }: DocsLayoutProps) {
return (
<html lang="en" className="h-full" suppressHydrationWarning>
{/*
<head /> will contain the components returned by the nearest parent
head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
*/}
<link rel="icon" href="/favicon.ico" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<head />
<body
className={`h-full dark:bg-slate-900 dark:antialiased ${inter.className}`}
>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<ClientProviders>{children}</ClientProviders>
</ThemeProvider>
<Analytics />
</body>
</html>
)
}
================================================
FILE: apps/docs/app/page.tsx
================================================
import {
allChangelogDocuments,
allComponentDocuments,
allGeneralDocuments,
} from 'contentlayer/generated'
import CtaSection from '@/components/home-page/cta-section'
import ExampleSection from '@/components/home-page/example-section'
import Navigation from '@/components/navigation'
export default async function Home() {
const sortedComponents = allComponentDocuments
.filter((doc) => doc.isComponent === true)
.sort((a, b) => a.title.localeCompare(b.title))
const sortedDocuments = [
...allGeneralDocuments,
...allChangelogDocuments,
].sort((a, b) => a.order - b.order)
return (
<div className="pt-14">
<Navigation
gettingStartedList={sortedDocuments}
componentList={sortedComponents}
/>
<div className="container mx-auto px-4 pb-8 pt-20">
<div className="mx-auto max-w-[1024px] text-center">
<h1 className="text-4xl font-extrabold md:text-7xl">
Accessibility doesn't <br className="hidden lg:inline" /> have
to be hard
</h1>
<div className="mx-auto mt-12 max-w-[768px]">
<p className="text-lg leading-normal text-slate-600 dark:text-slate-400 md:text-2xl">
Draft UI is a collection of simply designed React components
focused on making web accessibility as easy as copy & paste.
</p>
<CtaSection />
<p className="mt-32 text-sm text-slate-600 dark:text-slate-400 md:text-base">
Built with{' '}
<a
href="https://react-spectrum.adobe.com/react-aria/react-aria-components.html"
target="_blank"
rel="noopener"
className="font-medium text-black underline dark:text-white"
>
React Aria Components
</a>{' '}
and{' '}
<a
href="https://tailwindcss.com/"
target="_blank"
rel="noopener"
className="font-medium text-black underline dark:text-white"
>
Tailwind CSS
</a>
</p>
</div>
</div>
</div>
<div className="bg-slate-50 py-24 dark:border-y dark:border-slate-800 dark:bg-slate-900">
<div className="container mx-auto px-4">
<div>
<div className="mx-auto text-center">
<h2 className="text-center text-4xl font-extrabold md:text-5xl">
25+ Accessible Components
</h2>
</div>
</div>
<div className="mt-12">
<ExampleSection />
</div>
</div>
</div>
<footer className="container mx-auto justify-between px-4 py-8 text-center md:flex md:text-left">
<p className="mb-4 text-sm text-slate-600 dark:text-slate-400 md:mb-0">
Built with{' '}
<a
href="https://react-spectrum.adobe.com/react-aria/react-aria-components.html"
target="_blank"
rel="noopener"
className="font-medium text-black underline dark:text-white"
>
React Aria Components
</a>{' '}
and{' '}
<a
href="https://tailwindcss.com/"
target="_blank"
rel="noopener"
className="font-medium text-black underline dark:text-white"
>
Tailwind CSS
</a>
</p>
<p className="text-sm text-slate-600 dark:text-slate-400">
Powered by{' '}
<a
href="https://vercel.com/"
target="_blank"
rel="noopener"
className="font-medium text-black underline dark:text-white"
>
Vercel
</a>
</p>
</footer>
</div>
)
}
================================================
FILE: apps/docs/app/provider.tsx
================================================
'use client'
import { useRouter } from 'next/navigation'
import { RouterProvider } from 'react-aria-components'
export function ClientProviders({ children }) {
const router = useRouter()
return <RouterProvider navigate={router.push}>{children}</RouterProvider>
}
================================================
FILE: apps/docs/app/robots.tsx
================================================
import { type MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
disallow: '/private/',
},
sitemap: 'https://draft-ui.com/sitemap.xml',
}
}
================================================
FILE: apps/docs/app/sitemap.tsx
================================================
import { allDocuments } from 'contentlayer/generated'
import { type MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
const siteUrl = 'https://draft-ui.com'
const urls = allDocuments.map((post) => {
return { url: siteUrl + post.slug }
})
return [
{
url: siteUrl,
},
...urls,
]
}
================================================
FILE: apps/docs/components/analytics.tsx
================================================
'use client'
import { Analytics as VercelAnalytics } from '@vercel/analytics/react'
import Fathom from './fathom-analytics'
export default function Analytics() {
return (
<>
<Fathom />
<VercelAnalytics />
</>
)
}
================================================
FILE: apps/docs/components/copy-clipboard-button.tsx
================================================
'use client'
import { useState } from 'react'
import { Copy } from 'lucide-react'
import { IconButton, Tooltip, TooltipContent } from 'ui'
export default function CopyClipboardButton({ text }: { text: string }) {
const [isOpen, setOpen] = useState(false)
const handleCopyToClipboard = () => {
setOpen(true)
navigator.clipboard.writeText(text)
setTimeout(() => {
setOpen(false)
}, 800)
}
return (
<Tooltip isOpen={isOpen}>
<TooltipContent>Code copied!</TooltipContent>
<IconButton
aria-label="Copy component source code"
onPress={handleCopyToClipboard}
variant="link"
size="xs"
className="text-white"
>
<Copy size="1em" />
</IconButton>
</Tooltip>
)
}
================================================
FILE: apps/docs/components/docs/callout.tsx
================================================
import * as React from 'react'
import { AlertTriangle, Info, MessageSquare } from 'lucide-react'
import { match } from 'ts-pattern'
export default function Callout({
type,
children,
}: {
type: 'note' | 'warning' | 'important'
children: React.ReactNode
}) {
return match(type)
.with('note', () => (
<div className="not-prose mb-[2em] flex flex-col gap-2 border-l-4 border-blue-600 bg-blue-50 px-3 py-2 text-sm dark:border-blue-300 dark:bg-blue-400/20">
<div className="flex items-center gap-2 text-blue-600 dark:text-blue-300">
<Info size="1rem" />
<span className="font-semibold">Info</span>
</div>
<div className="dark:text-white">{children}</div>
</div>
))
.with('important', () => (
<div className="not-prose mb-[2em] flex flex-col gap-2 border-l-4 border-purple-700 bg-purple-50 px-3 py-2 text-sm dark:border-purple-300 dark:bg-purple-400/20">
<div className="flex items-center gap-2 text-purple-700 dark:text-purple-300">
<MessageSquare size="1rem" />
<span className="font-semibold">Important</span>
</div>
<div className="dark:text-white">{children}</div>
</div>
))
.with('warning', () => (
<div className="not-prose mb-[2em] flex flex-col gap-2 border-l-4 border-yellow-700 bg-yellow-50 px-3 py-2 text-sm dark:border-yellow-300 dark:bg-yellow-400/20">
<div className="flex items-center gap-2 text-yellow-700 dark:text-yellow-300">
<AlertTriangle size="1rem" />
<span className="font-semibold">Warning</span>
</div>
<div className="dark:text-white">{children}</div>
</div>
))
.exhaustive()
}
================================================
FILE: apps/docs/components/docs/component-example.tsx
================================================
'use client'
import * as React from 'react'
import { Tab, TabList, TabPanel, Tabs } from 'ui'
import { Index } from '@/__registry__'
import { cx } from '@/lib/cva.config'
import CopyClipboardButton from '../copy-clipboard-button'
interface ComponentExampleProps extends React.HTMLAttributes<HTMLDivElement> {
align?: 'center' | 'start' | 'end'
name: string
story: string
}
export default function ComponentExample({
align = 'center',
name,
story,
children,
}: ComponentExampleProps) {
const [Code] = React.Children.toArray(children) as React.ReactElement[]
const codeString = React.useMemo(() => {
if (
typeof Code?.props['data-rehype-pretty-code-fragment'] !== 'undefined'
) {
const [codeToCopy] = React.Children.toArray(
Code.props.children,
) as React.ReactElement[]
return codeToCopy?.props?.__rawString__ || null
}
}, [Code])
const Story = React.useMemo(() => {
const Component = Index[name]?.[story]?.component
if (!Component) {
return (
<p className="text-muted-foreground text-sm">
{name}{' '}
<code className="bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm">
"{story}"
</code>{' '}
not found in registry.
</p>
)
}
return <Component />
}, [name, story])
return (
<div>
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="example">Example</Tab>
<Tab id="code">Code</Tab>
</TabList>
<TabPanel id="example" className="px-0">
<div className="not-prose overflow-x-auto rounded-md border dark:border-slate-700 dark:bg-slate-800">
<div
className={cx(
'flex min-h-[350px] min-w-[max-content] justify-center p-10',
{
'items-center': align === 'center',
'items-start': align === 'start',
'items-end': align === 'end',
},
)}
>
<React.Suspense fallback={null}>{Story}</React.Suspense>
</div>
</div>
</TabPanel>
<TabPanel id="code" className="px-0">
<div className="relative [&_figure]:mt-0 [&_pre]:mt-0">
<div className="absolute right-2 top-2 z-10">
<CopyClipboardButton text={String(codeString)} />
</div>
{Code}
</div>
</TabPanel>
</Tabs>
</div>
)
}
================================================
FILE: apps/docs/components/docs/component-source.tsx
================================================
'use client'
import * as React from 'react'
import CopyClipboardButton from '../copy-clipboard-button'
export default function ComponentSource({ children }) {
const [Code] = React.Children.toArray(children) as React.ReactElement[]
const codeString = React.useMemo(() => {
if (
typeof Code?.props['data-rehype-pretty-code-fragment'] !== 'undefined'
) {
const [Button] = React.Children.toArray(
Code.props.children,
) as React.ReactElement[]
return Button?.props?.value || Button?.props?.__rawString__ || null
}
}, [Code])
return (
<div className="relative [&_figure]:my-0 [&_pre]:my-0 [&_pre]:max-h-[350px] [&_pre]:overflow-auto">
<div className="absolute right-2 top-2 z-10">
<CopyClipboardButton text={String(codeString)} />
</div>
{Code}
</div>
)
}
================================================
FILE: apps/docs/components/docs/heading.tsx
================================================
'use client'
import * as React from 'react'
import { type TocItemProps } from '@/types'
interface HeadingProps extends TocItemProps {
children: React.ReactNode
}
export default function Heading({ slug, lvl, children }: HeadingProps) {
const headingEl = React.createElement(
`h${lvl}`,
{
id: slug,
className:
'mt-0 scroll-mt-20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 dark:focus-visible:ring-slate-400 dark:focus-visible:ring-offset-slate-900 rounded-sm',
tabIndex: -1,
},
children,
)
return <div className="mt-[2em]">{headingEl}</div>
}
================================================
FILE: apps/docs/components/docs/jump-to-content-menu.tsx
================================================
'use client'
import { ChevronDown } from 'lucide-react'
import { Button } from 'ui/src/button'
import {
Menu,
MenuContent,
MenuHeader,
MenuItem,
MenuSection,
MenuSeparator,
} from 'ui/src/menu'
import { type TocItemProps } from '@/types'
export default function JumpToContentMenu({
toc,
}: {
toc: Array<TocItemProps>
}) {
const focusAnchorElement = (anchor: string) => {
const el = document?.getElementById(anchor)
if (el) el.focus()
}
return (
<Menu>
<Button
size="xs"
className="absolute -top-16 left-0 z-50 items-center gap-2 opacity-0 aria-expanded:top-0 aria-expanded:opacity-100 focus-visible:top-0 focus-visible:opacity-100"
>
<span>Skip to Content</span>
<ChevronDown aria-hidden size="16" strokeWidth="3" />
</Button>
<MenuContent
onAction={(slug: TocItemProps['slug']) => focusAnchorElement(slug)}
>
<MenuSection>
<MenuHeader>Landmark Regions</MenuHeader>
<MenuItem id="page-content">Page Content</MenuItem>
<MenuItem id="site-navigation">Site Navigation</MenuItem>
<MenuItem id="page-navigation">Page Navigation</MenuItem>
</MenuSection>
<MenuSeparator />
{toc ? (
<MenuSection>
<MenuHeader>Headings</MenuHeader>
{toc.map((heading: TocItemProps, idx: number) => (
<MenuItem id={heading.slug} key={idx}>
{heading.content}
</MenuItem>
))}
</MenuSection>
) : null}
</MenuContent>
</Menu>
)
}
================================================
FILE: apps/docs/components/docs/list-stepper.tsx
================================================
import * as React from 'react'
export function ListStepper({ children }: { children: React.ReactNode }) {
return (
<ol className="list-none space-y-16 pl-12 [counter-reset:step]">
{children}
</ol>
)
}
export function ListStep({ children }: { children: React.ReactNode }) {
return (
<li className="relative [counter-increment:step] before:absolute before:-left-12 before:flex before:h-8 before:w-8 before:items-center before:justify-center before:rounded-full before:bg-slate-100 before:font-semibold before:leading-none before:text-black before:content-[counter(step)] after:absolute after:-bottom-10 after:-left-8 after:top-14 after:border-l after:border-l-slate-200 last:after:border-l-0 dark:before:bg-slate-800 dark:before:text-slate-100 dark:after:border-l-slate-800">
{children}
</li>
)
}
================================================
FILE: apps/docs/components/docs/markdown.tsx
================================================
'use client'
import * as React from 'react'
import { type DocumentTypes } from 'contentlayer/generated'
import { useMDXComponent } from 'next-contentlayer/hooks'
import Link from 'next/link'
import { Tab, TabList, TabPanel, Tabs } from 'ui'
import Callout from '@/components/docs/callout'
import ComponentExample from '@/components/docs/component-example'
import ComponentSource from '@/components/docs/component-source'
import Heading from '@/components/docs/heading'
import { cx } from '@/lib/cva.config'
import { type NpmCommands } from '@/types'
import CopyClipboardButton from '../copy-clipboard-button'
import { ListStep, ListStepper } from './list-stepper'
type MarkdownProps = {
doc: DocumentTypes
}
export default function Markdown(props: MarkdownProps) {
const { doc } = props
const MDXComponent = useMDXComponent(doc.body.code)
return (
<div>
<MDXComponent
components={{
ComponentSource,
ComponentExample,
Callout,
Heading,
Tabs,
TabList,
Tab,
TabPanel,
ListStepper,
ListStep,
//
Link,
//
code: ({
className,
...props
}: React.HTMLAttributes<HTMLElement>) => (
<code className={cx(className)} {...props} />
),
figure: ({
className,
__npmCommand__,
__yarnCommand__,
__pnpmCommand__,
__niCommand__,
__rawString__,
...props
}: React.HTMLAttributes<HTMLElement> & {
__rawString__?: string
} & NpmCommands) => (
<>
{/* TODO: Introduce buttons that let you choose package manager */}
<div className="relative [&_figure]:mt-0 [&_pre]:mt-0 [&_pre]:max-h-[350px] [&_pre]:overflow-auto">
<div className="absolute right-2 top-2 z-10">
<CopyClipboardButton text={__rawString__ || ''} />
</div>
<figure className={cx(className)} {...props} />
</div>
</>
),
}}
/>
</div>
)
}
================================================
FILE: apps/docs/components/edit-feedback.tsx
================================================
export default function EditFeedbackLinks({
title,
contentPath,
}: {
title: string
contentPath: string
}) {
const pageEditUrl = `https://github.com/IHIutch/draft-ui/tree/main/apps/docs/content/${contentPath}`
const pageFeedbackUrl = new URL(
`https://github.com/IHIutch/draft-ui/issues/new`,
)
pageFeedbackUrl.searchParams.set('title', `Feedback for “${title}”`)
// Is this the right label to set? Do we need to make a new label for this?
pageFeedbackUrl.searchParams.set('labels', 'documentation')
return (
<ul className="mt-3">
<LinkItem href={pageEditUrl}>Edit this page</LinkItem>
<LinkItem href={pageFeedbackUrl.toString()}>Give us feedback</LinkItem>
</ul>
)
}
const LinkItem = ({
href,
children,
}: {
href: string
children?: React.ReactNode
}) => (
<li>
<a
className="block rounded-sm py-1 text-sm text-slate-600 no-underline transition hover:text-slate-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 dark:text-slate-400 dark:hover:text-white dark:focus-visible:ring-slate-400 dark:focus-visible:ring-offset-slate-900"
href={href}
>
{children}
</a>
</li>
)
================================================
FILE: apps/docs/components/fathom-analytics.tsx
================================================
// Fathom.tsx
'use client'
import { Suspense, useEffect } from 'react'
import { load, trackPageview } from 'fathom-client'
import { usePathname, useSearchParams } from 'next/navigation'
function TrackPageView() {
const pathname = usePathname()
const searchParams = useSearchParams()
useEffect(() => {
load('ERIJKXRN', {
includedDomains: ['draft-ui.com'],
auto: false,
})
}, [])
// Record a pageview when route changes
useEffect(() => {
trackPageview()
}, [pathname, searchParams])
return null
}
export default function Fathom() {
return (
<Suspense fallback={null}>
<TrackPageView />
</Suspense>
)
}
================================================
FILE: apps/docs/components/home-page/cta-section.tsx
================================================
'use client'
import * as React from 'react'
import Link from 'next/link'
import { buttonVariants } from '@/components/ui'
export default function CtaSection() {
return (
<div className="mt-12 flex justify-center gap-4 max-sm:flex-col">
<Link
href="/getting-started"
className={buttonVariants({
size: 'lg',
})}
>
Get Started
</Link>
<Link
href="/docs/components"
className={buttonVariants({
size: 'lg',
variant: 'outline',
})}
>
Components
</Link>
</div>
)
}
================================================
FILE: apps/docs/components/home-page/example-section.tsx
================================================
'use client'
import * as React from 'react'
import BreadcrumbsDefault from '@/registry/breadcrumbs/default'
import CheckboxGroupDefault from '@/registry/checkbox-group/default'
import ComboBoxWithButton from '@/registry/combobox/with-button'
import DatePickerDefault from '@/registry/date-picker/default'
import ModalDefault from '@/registry/modal/default'
import NumberInputMobile from '@/registry/number-field/with-mobile-stepper'
import SelectDefault from '@/registry/select/default'
import SliderDefault from '@/registry/slider/default'
import SwitchDefault from '@/registry/switch/default'
import TabsDefault from '@/registry/tabs/default'
export default function ExampleSection() {
return (
<div className="g-4 grid grid-flow-dense grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-2">
<BreadcrumbsDefault />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<DatePickerDefault />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<SelectDefault />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<CheckboxGroupDefault />
</div>
<div className="flex items-center justify-center overflow-x-auto rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-2">
<TabsDefault />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<ModalDefault />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<SwitchDefault />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<SliderDefault />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<ComboBoxWithButton />
</div>
<div className="flex items-center justify-center rounded-md border bg-white p-4 dark:border-slate-700 dark:bg-slate-800 md:col-span-1">
<NumberInputMobile />
</div>
</div>
)
}
================================================
FILE: apps/docs/components/link-list.tsx
================================================
'use client'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { cx } from '@/lib/cva.config'
type LinkListItemProps = {
isComing?: boolean
isWip?: boolean
isNew?: boolean
slug: string
title: string
}
export default function LinkList({ list }: { list: LinkListItemProps[] }) {
const pathname = usePathname()
return (
<ul>
{list.map((link, idx) => (
<li key={idx}>
<Link
role="link"
aria-disabled={!!link?.isComing}
aria-current={pathname === link.slug ? 'page' : undefined}
// @ts-ignore
href={link?.isComing ? '' : link.slug}
onClick={(e) => {
if (!!link?.isComing) {
e.preventDefault()
}
}}
className={cx(
'flex items-center justify-between gap-2 rounded-sm py-1 text-sm transition',
// Focus
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 dark:focus-visible:ring-slate-400 dark:focus-visible:ring-offset-slate-900',
pathname === link.slug
? 'font-medium text-slate-900 dark:text-white'
: 'text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-white',
link?.isComing &&
'cursor-not-allowed text-slate-400 hover:text-slate-400 dark:text-slate-600 dark:hover:text-slate-600',
)}
>
<span className="truncate">{link.title}</span>
{link?.isComing ? (
<span className="rounded bg-slate-500 px-1 text-xs font-medium text-white dark:bg-slate-400 dark:text-slate-900">
Coming Soon
</span>
) : link?.isNew ? (
<span className="rounded bg-black px-1 text-xs font-medium text-white dark:bg-slate-100 dark:text-black">
New!
</span>
) : link?.isWip ? (
<span className="rounded bg-slate-200 px-1 text-xs font-medium text-slate-700 dark:bg-slate-700 dark:text-white">
WIP
</span>
) : null}
</Link>
</li>
))}
</ul>
)
}
================================================
FILE: apps/docs/components/mode-toggle.tsx
================================================
'use client'
import * as React from 'react'
import { LaptopIcon, MoonIcon, SunIcon } from 'lucide-react'
import { useTheme } from 'next-themes'
import { IconButton, Menu, MenuContent, MenuItem } from '@/components/ui'
export function ModeToggle() {
const { setTheme, resolvedTheme } = useTheme()
return (
<Menu>
<IconButton
aria-label={`Select a color theme, current theme is: ${resolvedTheme}`}
size="sm"
variant="ghost"
className="flex items-center gap-2"
>
{resolvedTheme === 'dark' ? (
<MoonIcon size="20" />
) : (
<SunIcon size="20" />
)}
</IconButton>
<MenuContent
onAction={(value: 'light' | 'dark' | 'system') => setTheme(value)}
>
<MenuItem id="light">
<SunIcon aria-hidden="true" size="16" />
<span className="pl-2">Light</span>
</MenuItem>
<MenuItem id="dark">
<MoonIcon aria-hidden="true" size="16" />
<span className="pl-2">Dark</span>
</MenuItem>
<MenuItem id="system">
<LaptopIcon aria-hidden="true" size="16" />
<span className="pl-2">System</span>
</MenuItem>
</MenuContent>
</Menu>
)
}
================================================
FILE: apps/docs/components/navigation.tsx
================================================
'use client'
import { useEffect, useState } from 'react'
import { GithubIcon, MenuIcon, TwitterIcon, XIcon } from 'lucide-react'
import Image from 'next/image'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import {
IconButton,
iconButtonVariants,
ModalBody,
ModalContent,
ModalHeader,
ModalOverlay,
} from 'ui'
import { cx } from '@/lib/cva.config'
import LinkList from './link-list'
import { ModeToggle } from './mode-toggle'
import SearchComponent from './search-component'
type LinkListItemProps = {
isComing?: boolean
isWip?: boolean
isNew?: boolean
slug: string
title: string
}
export default function Navigation({
gettingStartedList,
componentList,
}: {
gettingStartedList: LinkListItemProps[]
componentList: LinkListItemProps[]
}) {
const pathname = usePathname()
const [isModalOpen, setIsModalOpen] = useState(false)
useEffect(() => {
setIsModalOpen(false)
}, [pathname])
return (
<div className="light:shadow-sm fixed inset-x-0 top-0 z-50 h-14 border-b bg-white dark:border-b dark:border-slate-800 dark:bg-slate-900">
<div className="mx-auto flex h-full w-full items-center px-4">
<Link
href="/"
aria-label="Home"
className="flex items-center gap-2 font-semibold"
>
<Image
className="dark:invert"
src="/draft_ui.svg"
alt=""
width={30}
height={30}
/>
<span>Draft UI</span>
</Link>
{/* Desktop Nav */}
<div className="flex grow items-center">
<div className="ml-14 hidden items-center gap-8 lg:flex">
<Link
href="/getting-started"
className="rounded-sm text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 dark:focus-visible:ring-slate-400 dark:focus-visible:ring-offset-slate-900"
>
Getting Started
</Link>
<Link
href="/docs/components"
className="rounded-sm text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 dark:focus-visible:ring-slate-400 dark:focus-visible:ring-offset-slate-900"
>
Components
</Link>
</div>
<div className="mx-auto flex lg:mx-0 lg:ml-auto">
<div className="flex gap-2">
<div className="hidden pr-2 md:block lg:pr-0">
<SearchComponent />
</div>
<div className="hidden gap-2 lg:flex">
<div>
<a
className={cx(
iconButtonVariants({ size: 'sm', variant: 'ghost' }),
)}
href="https://twitter.com/draft__ui"
target="_blank"
rel="noreferrer"
aria-label="Link to our Twitter account"
>
<TwitterIcon size="20" aria-hidden="true" />
</a>
</div>
<div>
<a
className={cx(
iconButtonVariants({ size: 'sm', variant: 'ghost' }),
)}
href="https://github.com/IHIutch/draft-ui"
target="_blank"
rel="noreferrer"
aria-label="Link to GitHub repository"
>
<GithubIcon size="20" aria-hidden="true" />
</a>
</div>
<div>
<ModeToggle />
</div>
</div>
</div>
</div>
</div>
{/* Mobile Nav */}
<div className="ml-auto flex lg:hidden">
<div className="flex items-center gap-1 md:gap-2">
<div>
<a
className={cx(
iconButtonVariants({ size: 'sm', variant: 'ghost' }),
)}
href="https://twitter.com/draft__ui"
target="_blank"
rel="noreferrer"
aria-label="Link to our Twitter account"
>
<TwitterIcon size="20" aria-hidden="true" />
</a>
</div>
<div>
<a
className={cx(
iconButtonVariants({ size: 'sm', variant: 'ghost' }),
)}
href="https://github.com/IHIutch/draft-ui"
target="_blank"
rel="noreferrer"
aria-label="Link to GitHub repository"
>
<GithubIcon size="20" aria-hidden="true" />
</a>
</div>
<div>
<ModeToggle />
</div>
<div className="h-6 border-l border-gray-300" />
<div className="md:hidden">
<SearchComponent />
</div>
<div>
<IconButton
aria-label="Open Navigation Menu"
size="sm"
variant="ghost"
onPress={() => setIsModalOpen(true)}
>
<MenuIcon size="1em" />
</IconButton>
<ModalOverlay
isDismissable
isOpen={isModalOpen}
onOpenChange={setIsModalOpen}
>
<ModalContent size="full" className="max-h-full overflow-auto">
<ModalHeader>Menu</ModalHeader>
<IconButton
aria-label="Close Navigation Menu"
className="absolute right-3 top-2"
size="sm"
variant="ghost"
onPress={() => setIsModalOpen(false)}
autoFocus
>
<XIcon size="1em" />
</IconButton>
<ModalBody>
<div className="mb-4">
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Getting Started
</h4>
<div className="mt-3 pr-3">
<LinkList list={gettingStartedList} />
</div>
</div>
<div>
<h4 className="text-base font-semibold text-slate-900 dark:text-white">
Components
</h4>
<div className="mt-3 pr-3">
<LinkList list={componentList} />
</div>
</div>
</ModalBody>
</ModalContent>
</ModalOverlay>
</div>
</div>
</div>
</div>
</div>
)
}
================================================
FILE: apps/docs/components/page-toc.tsx
================================================
'use client'
import { useEffect, useState } from 'react'
import { cx } from '@/lib/cva.config'
import { type TocItemProps } from '@/types'
export default function PageToc({
headings,
}: {
headings?: Array<TocItemProps>
}) {
const activeHeading = useActiveHeading((headings || []).map((h) => h.slug))
return (
<nav id="page-navigation" tabIndex={-1}>
<div className="mb-3">
<span className="text-base font-semibold text-slate-900 dark:text-white">
On This Page
</span>
</div>
<ul>
{(headings || []).map((h, idx) => (
<li key={idx} className={cx(h.lvl === 3 && 'pl-3')}>
<a
href={'#' + h.slug}
className={cx(
'block rounded-sm py-1 text-sm no-underline transition',
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 dark:focus-visible:ring-slate-400 dark:focus-visible:ring-offset-slate-900',
h.slug === activeHeading
? 'text-slate-900 dark:text-white'
: 'text-slate-600 hover:text-slate-900 dark:text-slate-400 dark:hover:text-white',
)}
>
{h.content}
</a>
</li>
))}
</ul>
</nav>
)
}
function useActiveHeading(itemIds: string[]) {
const [activeId, setActiveId] = useState<null | string>(null)
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveId(entry.target.id)
}
})
},
{ rootMargin: `0% 0% -80% 0%` },
)
itemIds?.forEach((id) => {
const element = document.getElementById(id)
if (element) {
observer.observe(element)
}
})
return () => {
itemIds?.forEach((id) => {
const element = document.getElementById(id)
if (element) {
observer.unobserve(element)
}
})
}
}, [itemIds])
return activeId
}
================================================
FILE: apps/docs/components/search-component.tsx
================================================
'use client'
import { useState } from 'react'
import { Search } from 'lucide-react'
import Link from 'next/link'
import { DocSearchModal } from '@docsearch/react'
import '@docsearch/css/dist/style.css'
import { Button, IconButton } from 'ui'
import { cx } from '@/lib/cva.config'
export default function SearchComponent() {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<Button
size="sm"
variant="outline"
onPress={() => setIsOpen(true)}
className="hidden items-center justify-start text-slate-600 md:flex md:w-72"
>
<Search className="h-4 w-4" />
<span className="ml-2 font-normal">Search the docs...</span>
</Button>
<IconButton
onPress={() => setIsOpen(true)}
aria-label="Search"
className="md:hidden"
size="sm"
variant="ghost"
>
<Search size="20" />
</IconButton>
{isOpen ? (
<DocSearchModal
initialScrollY={window.scrollY}
appId="PEODP0LKUU"
indexName="draft-ui"
apiKey="10b79ceff1a745560608f23d0fcca54a"
onClose={() => setIsOpen(false)}
placeholder="Search the docs..."
hitComponent={Hit}
transformItems={(items) => {
return items.map((item, index) => {
const a = document.createElement('a')
a.href = item.url
if (item.hierarchy?.lvl0) {
item.hierarchy.lvl0 = item.hierarchy.lvl0.replace(/&/g, '&')
}
if (item._highlightResult?.hierarchy?.lvl0?.value) {
item._highlightResult.hierarchy.lvl0.value =
item._highlightResult.hierarchy.lvl0.value.replace(
/&/g,
'&',
)
}
return {
...item,
url: `${a.pathname}${a.hash}`,
__is_result: () => true,
// __is_parent: () =>
// item.type === 'lvl1' && items.length > 1 && index === 0,
// __is_child: () =>
// item.type !== 'lvl1' &&
// items.length > 1 &&
// items[0].type === 'lvl1' &&
// index !== 0,
__is_first: () => index === 1,
__is_last: () => index === items.length - 1 && index !== 0,
}
})
}}
/>
) : null}
</>
)
}
const Hit = ({ hit, children }) => {
return (
<Link
href={hit.url}
className={cx({
'DocSearch-Hit--Result': hit.__is_result?.(),
// 'DocSearch-Hit--Parent': hit.__is_parent?.(),
// 'DocSearch-Hit--Child': hit.__is_child?.(),
'DocSearch-Hit--FirstChild': hit.__is_first?.(),
'DocSearch-Hit--LastChild': hit.__is_last?.(),
})}
>
{children}
</Link>
)
}
================================================
FILE: apps/docs/components/theme-provider.tsx
================================================
'use client'
import * as React from 'react'
import { ThemeProvider as NextThemesProvider } from 'next-themes'
import { type ThemeProviderProps } from 'next-themes/dist/types'
export default function ThemeProvider({
children,
...props
}: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
================================================
FILE: apps/docs/content/CHANGELOG.mdx
================================================
---
title: Changelog
description: Stay up to date on the latest changes and updates
order: 5
---
## January 2024
- We have a **CLI** tool!
- Thanks to [@jolbol1](https://github.com/jolbol1) and [@jacobparis](https://github.com/jacobparis) for getting this set up. And to [@kentcdodds](https://github.com/kentcdodds) for kicking this off and suggesting this approach.
- Docs and installation have been updated to show how to install components with [`@sly-cli/sly`](https://github.com/jacobparis-insiders/sly/blob/main/cli/README.md)
- Update **React Aria Components** to `1.0.0`
- Breadcrumb now exposes `BreadcrumbLink` to correctly handle React Aria **`Link`** within components [@Littletonconnor](https://github.com/Littletonconnor) - [#20](https://github.com/IHIutch/draft-ui/pull/20)
- Updates to installation to show how to integrate React Aria **`Link`** with various frameworks using [`RouterProvider`](https://react-spectrum.adobe.com/react-aria/routing.html).
- No more `'use client'` needed. React Aria handles this automatically, behind the scenes.
- Docs and code samples were tidied up significantly
- You can now copy directly from `bash` snippets
- Thanks to [@itsMapleLeaf's](https://github.com/itsMapleLeaf) [suggestion](https://twitter.com/heyImMapleLeaf/status/1723216226833346848), we're now using namespaced imports from React Aria Components. This has significantly increased readability and helps keep things simple.
- Update Tailwind to `3.4.1`
- While there were several exciting updates in this release, we've not yet integrated things like `:has()` and `size-*`. Since this change is still fairly fresh, we're going hold off on introducing those features because, well, not changing them won't break anything.
- Several spelling and text fixes:
- [@henrikvtcodes](https://github.com/henrikvtcodes) - [#3](https://github.com/IHIutch/draft-ui/pull/3),
- [@Littletonconnor](https://github.com/Littletonconnor) - [#6](https://github.com/IHIutch/draft-ui/pull/6),
- [@Littletonconnor](https://github.com/Littletonconnor) - [#8](https://github.com/IHIutch/draft-ui/pull/18)
## November 2023
- Update **React Aria Components** to RC (`1.0.0-rc.0`)!
- Breadcrumb **`Item`** becomes **`Breadcrumb`**
- ListBox **`Item`** becomes **`ListBoxItem`**
- Menu **`Item`** becomes **`MenuItem`**
- GridList **`Item`** becomes **`GridListItem`**
- Replace **`validationState`** with **`isInvalid`** for error handling
- Add React Aria Components Tailwind config and update various classNames
- Update Installation instructions with specific React Aria Components version
- Update `Slider` example to destructure `state` key
- Replaces `class-variance-authority` with [`cva@beta`](https://beta.cva.style/getting-started/whats-new/)
- Base component styles must now be located within the `base` property:
- Replace `cn(...)` helper function with `cx(...)` by using `CVA` config and including `twMerge`
- Removes `clsx` as a dependency because it is now included in CVA as `cx`
- Updated red/error colors to be WCAG compliant
- Added additional examples to the following components:
- `Checkbox`
- `CheckboxGroup`
- `ComboBox`
- `DatePicker`
- `DateRangePicker`
- `Input`
- `NumberField`
- `Radio`
- `RadioGroup`
- `Select`
- `Tabs`
- `TextField`
## September 2023
- Reordered components' classNames properly
## August 2023
- Doc updates
- Update React imports in components
- Add lots of new examples and variants:
- `Button` variants
- `Checkbox` variants
- `ComboBox` examples
- `DateInput` variants
- `Input` variants
- `Menu` examples
- `Meter` examples
- `NumberField` examples
- `Radio` variants
- `Switch` examples
- `Tooltip` examples
- Fixed a bunch of component layouts
- Add `flex-col` to `Modal`
- Add `w-full` to `NumberField`
- Remove verbose classes from `RadioGroup`
- Add `w-full` to `Select`
- Remove `h-full` from vertical `Slider` variant
## July 2023
Using `react-aria-components@1.0.0-alpha.5`
- We have a logo and a homepage!
- Docs updated; content pages are live including installation
instructions
- Components and the rest of the site support dark mode.
- Tabs now use `--border-width` variable to avoid issues
with nested tabs
================================================
FILE: apps/docs/content/components/breadcrumbs.mdx
================================================
---
title: Breadcrumbs
description: Breadcrumbs display a hierarchy of links to the current page or resource in an application.
isComponent: true
---
<Callout type="important">
By default, **`BreadcrumbLink`** uses a React Aria Component **`Link`**. To ensure this navigation works as expected with your framework, be sure to follow the <Link className="underline" href="/getting-started/installation#configure-routing">Configure Routing</Link> step of the Draft UI installation.
</Callout>
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui breadcrumbs
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/breadcrumbs.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is an example of the default Breadcrumb component
<ComponentExample name="breadcrumbs" story="default" />
================================================
FILE: apps/docs/content/components/button.mdx
================================================
---
title: Button
description: A button allows a user to perform an action, with mouse, touch, and keyboard interactions.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui button
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/button.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Button`** uses variant `solid` and size `md`.
<ComponentExample name="button" story="default" />
### Themes
You can use the `variant` prop to alter the **`Button`** theme. Variants `solid`, `outline`, `subtle`, `ghost`, `destructive`, and `link` are included by default.
<ComponentExample name="button" story="theme" />
### Sizes
You can use the `size` prop to alter the **`Button`** size. Sizes `xs`, `sm`, `md`, and `lg` are included by default.
<ComponentExample name="button" story="sizes" />
### Disabled
Use the `isDisabled` prop to make the **`Button`** disabled.
<ComponentExample name="button" story="disabled" />
================================================
FILE: apps/docs/content/components/checkbox-group.mdx
================================================
---
title: Checkbox Group
description: A checkbox group allows a user to select multiple items from a list of options.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui checkbox-group
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/checkbox-group.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`CheckboxGroup`** uses orientation `vertical`.
<ComponentExample name="checkbox-group" story="default" />
### Horizontal
Set the `orientation` prop to `horizontal` to use a horizontal **`CheckboxGroup`**.
<ComponentExample name="checkbox-group" story="horizontal" />
### Disabled
Use the `isDisabled` prop to make the entire **`CheckboxGroup`** disabled.
<ComponentExample name="checkbox-group" story="disabled" />
================================================
FILE: apps/docs/content/components/checkbox.mdx
================================================
---
title: Checkbox
description: A checkbox allows a user to select multiple items from a list of individual items, or to mark one individual item as selected.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui checkbox
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/checkbox.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Checkbox`** uses size `md`.
<ComponentExample name="checkbox" story="default" />
### Sizes
You can use the `size` prop to alter the **`Checkbox`** size. Sizes `sm`, `md`, and `lg` are included by default.
<ComponentExample name="checkbox" story="sizes" />
### Disabled
Use the `isDisabled` prop to make an individual **`Checkbox`** disabled.
<ComponentExample name="checkbox" story="disabled" />
================================================
FILE: apps/docs/content/components/combo-box.mdx
================================================
---
title: Combo Box
description: A combo box combines a text input with a listbox, allowing users to filter a list of options to items matching a query.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui combobox
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/combobox.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`ComboBox`**
<ComponentExample name="combobox" story="default" />
### With Button
Any React Aria Component **`Button`** placed inside **`ComboBox`**, will automatically toggle the appearance of **`ComboBoxContent`** when pressed.
<ComponentExample name="combobox" story="with-button" />
### Disabled Keys
To disable specific **`ComboBoxItem`**'s, add an array of `disabledKey`'s to **`ComboBox`**. Ensure the **`ComboBoxItem`**'s have appropriate, corresponding `id`'s.
<ComponentExample name="combobox" story="disabled-keys" />
### Disabled
Use the `isDisabled` prop to disable the **`ComboxInput`** altogether.
<ComponentExample name="combobox" story="disabled" />
================================================
FILE: apps/docs/content/components/date-picker.mdx
================================================
---
title: Date Picker
description: A date picker combines a DateField and a Calendar popover to allow users to enter or select a date and time value.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui date-picker
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/date-picker.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`DatePicker`** example.
<ComponentExample name="date-picker" story="default" />
### Disabled
Use the `isDisabled` prop to disable the entire **`DatePicker`** including the **`DateInput`**.
<ComponentExample name="date-picker" story="disabled" />
================================================
FILE: apps/docs/content/components/date-range-picker.mdx
================================================
---
title: Date Range Picker
description: A date range picker combines two DateFields and a RangeCalendar popover to allow users to enter or select a date and time range.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui date-range-picker
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/date-range-picker.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`DateRangePicker`**
<ComponentExample name="date-range-picker" story="default" />
### Disabled
Use the `isDisabled` prop to disable the entire **`DateRangePicker`** including the **`DateInput`**'s.
<ComponentExample name="date-range-picker" story="disabled" />
================================================
FILE: apps/docs/content/components/grid-list.mdx
================================================
---
title: Grid List
description: A grid list displays a list of interactive items, with support for keyboard navigation, single or multiple selection, and row actions.
isComponent: true
isWip: true
isComing: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui grid-list
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/grid-list.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default example
---
### Disabled
This is the disabled example
---
### With Label
This is an example with a label
---
### With Text
This is an example with text
---
### With Input
This is an example with a input
================================================
FILE: apps/docs/content/components/icon-button.mdx
================================================
---
title: Icon Button
description: Displays a form input field or a component that looks like an input field.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui icon-button
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/icon-button.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`IconButton`** uses variant `solid` and size `md`.
<Callout type="note">
When using an **`IconButton`** you should almost always use an `aria-label`.
In some components, however, React Aria Components will automatically assign
an `aria-label` to buttons.
</Callout>
<ComponentExample name="icon-button" story="default" />
### Themes
You can use the `variant` prop to alter the button theme. Variants `solid`, `outline`, `subtle`, `ghost`, `destructive`, and `link` are included by default.
<ComponentExample name="icon-button" story="theme" />
### Sizes
You can use the `size` prop to alter the button size. Sizes `xs`, `sm`, `md`, and `lg` are included by default.
<ComponentExample name="icon-button" story="sizes" />
### Disabled
Use the `isDisabled` prop to make the **`IconButton`** disabled.
<ComponentExample name="icon-button" story="disabled" />
================================================
FILE: apps/docs/content/components/input.mdx
================================================
---
title: Input
description: Displays a form input field or a component that looks like an input field.
isComponent: true
---
<Callout type="important">
**`Input`** is a primitive component, it is not meant to be used on it's own.
Typically, it is used in any component that handles raw text, such as
**`TextField`**, **`NumberField`**, **`SearchField`**, and **`ComboxBox`**.
</Callout>
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui input
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/input.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Input`** uses size `md`.
<ComponentExample name="input" story="default" />
### Size
You can use the `size` prop to alter the input size. Sizes `xs`, `sm`, `md`, and `lg` are included by default.
<ComponentExample name="input" story="sizes" />
### Disabled
Use the `disabled` prop to make the **`Input`** disabled.
<Callout type="warning">
Currently, the **`Input`** component uses the `disabled` prop rather than `isDisabled`.
</Callout>
<ComponentExample name="input" story="disabled" />
================================================
FILE: apps/docs/content/components/label.mdx
================================================
---
title: Label
description: Displays a form input field or a component that looks like an input field.
isComponent: true
---
<Callout type="important">
**`Label`** is a primitive component, it is not meant to be used on it's own.
Many components that behave as form inputs automatically handle linking labels
to their respective inputs, such as **`DatePicker`**, **`RadioGroup`**,
**`Select`**, **`TextField`**, **`Switch`**, etc.
</Callout>
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui label
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/label.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`Label`**
<ComponentExample name="label" story="default" />
================================================
FILE: apps/docs/content/components/menu.mdx
================================================
---
title: Menu
description: A menu displays a list of actions or options that a user can choose.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui menu
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/menu.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`Menu`** example.
<ComponentExample name="menu" story="default" />
### Disabled
Make specific **`MenuItem`**'s disabled by adding their `id` to the **`MenuContent`**'s `disabledKeys` prop.
<ComponentExample name="menu" story="disabled" />
### With Sections
Add sections to the menu by using **`MenuSection`** and **`MenuHeader`**.
<ComponentExample name="menu" story="with-sections" />
### As Checkbox List
**`MenuItem`** can act checkboxes by setting the **`MenuContent`**'s `selectionMode` prop to `multiple`.
<ComponentExample name="menu" story="as-checkbox" />
### As Radio List
**`MenuItem`** can act radios by setting the **`MenuContent`**'s `selectionMode` prop to `single`.
<ComponentExample name="menu" story="as-radio" />
### Complex Menu Items
**Coming Soon**: An example showing how to properly create **`MenuItem`**s with complex content.
================================================
FILE: apps/docs/content/components/meter.mdx
================================================
---
title: Meter
description: A meter represents a quantity within a known range, or a fractional value.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui meter
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/meter.tsx" />
</TabPanel>
</Tabs>
## Examples
<Callout type="note">
Althought similar to **`ProgressBar`**, **`Meter`** is used to represent an
amount or quantity. For example: Storage space, download speed, or battery
life.
</Callout>
### Default
This is the default **`Meter`**
<ComponentExample name="meter" story="default" />
### With Custom Children
{/* TODO */}
**Coming soon:** An example of **`Meter`** with custom children
================================================
FILE: apps/docs/content/components/modal.mdx
================================================
---
title: Modal
description: A modal is an overlay element which blocks interaction with elements outside it.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui modal
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/modal.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Modal`** uses size `md`.
<ComponentExample name="modal" story="default" />
### Sizes
You can use the `size` prop to alter the button size. Sizes `xs`, `sm`, `md`, `lg`, `xl`, and `full` are included by default.
<ComponentExample name="modal" story="sizes" />
### Set Autofocus
You can manually control which element recieves focus when the **`Modal`** opens by setting `autoFocus` on a focusable element.
<ComponentExample name="modal" story="set-autofocus" />
### Dismissable
Modals are dismissable by clicking outside by default or by pressing the <kdb>Esc</kdb> key. To prevent this, set `isDismissable` to `false` and/or `isKeyboardDismissDisabled` to `true`.
<ComponentExample name="modal" story="dismissable-false" />
================================================
FILE: apps/docs/content/components/number-field.mdx
================================================
---
title: Number Field
description: A number field allows a user to enter a number, and increment or decrement the value using stepper buttons.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui number-field
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/number-field.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`NumberField`**
<ComponentExample name="number-field" story="default" />
### With Stepper
This is an example using the built-in **`NumberInputStepper`**.
<ComponentExample name="number-field" story="with-stepper" />
### With Mobile Stepper
This is an example of a custom **`NumberField`** that makes the stepper buttons easier to press on touch devices.
<ComponentExample name="number-field" story="with-mobile-stepper" />
### Disabled
Use the `isDisabled` prop to make the **`NumberField`** disabled.
<ComponentExample name="number-field" story="disabled" />
================================================
FILE: apps/docs/content/components/progress-bar.mdx
================================================
---
title: Progress Bar
description: Progress bars show either determinate or indeterminate progress of an operation over time.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui progress-bar
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/progress-bar.tsx" />
</TabPanel>
</Tabs>
## Examples
<Callout type="note">
Althought similar to **`Meter`**, **`ProgressBar`** is used to represent
progress. In other words, it would typically be used in circumstances that
start at zero and tend toward completion. For example: Loading progress,
download progress, or battery charge progress.
</Callout>
### Default
This is the default **`ProgressBar`**
<ComponentExample name="progress-bar" story="default" />
### With Custom Children
{/* TODO */}
**Coming soon:** This is an example with custom children
================================================
FILE: apps/docs/content/components/radio-group.mdx
================================================
---
title: Radio Group
description: A radio group allows a user to select a single item from a list of mutually exclusive options.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui radio-group
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/radio-group.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`RadioGroup`** uses orientation `vertical`.
<ComponentExample name="radio-group" story="default" />
### Horizontal
Set the `orientation` prop to `horizontal` to use a horizontal **`RadioGroup`**.
<ComponentExample name="radio-group" story="horizontal" />
### Disabled
Use the `isDisabled` prop to make the entire **`RadioGroup`** disabled.
<ComponentExample name="radio-group" story="disabled" />
================================================
FILE: apps/docs/content/components/radio.mdx
================================================
---
title: Radio
description: Displays a form input field or a component that looks like an input field.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui radio
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/radio.tsx" />
</TabPanel>
</Tabs>
## Examples
<Callout type="warning">
**`Radio`** is a primitive component, it is not meant to be used on it's own. It must be wrapped in a **`RadioGroup`**.
</Callout>
### Default
The default **`Radio`** uses size `md`.
<ComponentExample name="radio" story="default" />
### Sizes
You can use the `size` prop to alter the **`Radio`** size. Sizes `sm`, `md`, and `lg` are included by default.
<ComponentExample name="radio" story="sizes" />
### Disabled
Use the `isDisabled` prop to make an individual **`Radio`** disabled.
<ComponentExample name="radio" story="disabled" />
================================================
FILE: apps/docs/content/components/search-field.mdx
================================================
---
title: Search Field
description: A search field allows a user to enter and clear a search query.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui search-field
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/search-field.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`SearchField`**
<ComponentExample name="search-field" story="default" />
### With Clear Button
Use **`SearchFieldClearButton`** to display a button that clear the **`SearchField`** input. By default, it will only show up when the input is not empty.
<ComponentExample name="search-field" story="with-clear-button" />
================================================
FILE: apps/docs/content/components/select.mdx
================================================
---
title: Select
description: A select displays a collapsible list of options and allows a user to select one of them.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui select
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/select.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`Select`**.
<ComponentExample name="select" story="default" />
### Disabled
Use the `isDisabled` prop to make the **`Select`** disabled.
<ComponentExample name="select" story="disabled" />
================================================
FILE: apps/docs/content/components/slider.mdx
================================================
---
title: Slider
description: A slider allows a user to select one or more values within a range.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui slider
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/slider.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Slider`** uses orientation `horizontal`.
<ComponentExample name="slider" story="default" />
### Vertical
Set the `orientation` prop to `vertical` to use a vertical **`Slider`**.
<Callout type="important">
`orientation` value passed to **`SliderFilledTrack`** must be set to `vertical` and you must give **`SliderTrack`** a specific height for this variation to be styled correctly.
</Callout>
<ComponentExample name="slider" story="vertical" />
================================================
FILE: apps/docs/content/components/switch.mdx
================================================
---
title: Switch
description: A text field allows a user to enter a plain text value with a keyboard.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui switch
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/switch.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Switch`** uses size `md`.
<ComponentExample name="switch" story="default" />
### Alignment
Switches can be either left or right aligned.
<ComponentExample name="switch" story="alignment" />
### Sizes
You can use the `size` prop to alter the **`Switch`** size. Sizes `sm`, `md`, and `lg` are included by default.
<ComponentExample name="switch" story="sizes" />
### Disabled
Use the `isDisabled` prop to make the **`Switch`** disabled.
<ComponentExample name="switch" story="disabled" />
================================================
FILE: apps/docs/content/components/table.mdx
================================================
---
title: Table
description: A table displays data in rows and columns and enables a user to navigate its contents via directional navigation keys, and optionally supports row selection and sorting.
isComponent: true
isWip: true
isComing: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui table
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/table.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default example
---
### Disabled
This is the disabled example
---
### With Label
This is an example with a label
---
### With Text
This is an example with text
---
### With Input
This is an example with a input
================================================
FILE: apps/docs/content/components/tabs.mdx
================================================
---
title: Tabs
description: Tabs organize content into multiple sections and allow users to navigate between them.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui tabs
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/tabs.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Tabs`** uses orientation `horizontal`.
<ComponentExample name="tabs" story="default" />
### Vertical
Set the `orientation` prop to `vertical` to use vertical **`Tabs`**.
<ComponentExample name="tabs" story="vertical" />
### Disabled Keys
Use `disabledKeys` prop to disable specific **`Tab`**'s **`ComboBox`**.
<ComponentExample name="tabs" story="disabled-keys" />
### Disabled
Use the `isDisabled` prop to disable all **`Tab`**'s.
<ComponentExample name="tabs" story="disabled" />
================================================
FILE: apps/docs/content/components/text-field.mdx
================================================
---
title: Text Field
description: Displays a form input field or a component that looks like an input field.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui text-field
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/text-field.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
This is the default **`TextField`**.
<ComponentExample name="text-field" story="default" />
### With Error
Use the `isInvalid` prop to make an **`Input`** invalid. You can also include an error message to tell users why the `input` is invalid.
<ComponentExample name="text-field" story="with-error" />
### Disabled
Use the `isDisabled` prop to make the **`Input`** disabled.
<ComponentExample name="text-field" story="disabled" />
================================================
FILE: apps/docs/content/components/toggle-button.mdx
================================================
---
title: Toggle Button
description: A toggle button allows a user to toggle a selection on or off, for example switching between two states or modes.
isComponent: true
isWip: true
isComing: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui toggle-button
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/toggle-button.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
**Coming soon:** This is the default example
{/* TODO */}
---
### Disabled
**Coming soon:** This is the disabled example
{/* TODO */}
================================================
FILE: apps/docs/content/components/tooltip.mdx
================================================
---
title: Tooltip
description: A tooltip displays a description of an element on hover or focus.
isComponent: true
---
## Installation
<Tabs>
<TabList aria-label="Preview and Code Tabs">
<Tab id="cli-install">CLI</Tab>
<Tab id="manual-install">Copy & Paste</Tab>
</TabList>
<TabPanel id="cli-install" className="px-0 [&_pre]:my-0 [&_figure]:my-0">
```bash title="bash"
npx @sly-cli/sly add draft-ui tooltip
```
</TabPanel>
<TabPanel id="manual-install" className="px-0">
<ComponentSource src="../../packages/ui/src/tooltip.tsx" />
</TabPanel>
</Tabs>
## Examples
### Default
The default **`Tooltip`** uses placement `top`.
<ComponentExample name="tooltip" story="default" />
### Placement
Set the `placement` prop to change the default **`Tooltip`** placement.
<ComponentExample name="tooltip" story="placement" />
================================================
FILE: apps/docs/content/getting-started/about.mdx
================================================
---
title: About
description: The purpose of Draft UI is to make building accessible applications
faster and easier than ever
order: 4
---
## Make It Your Own
I've intentionally avoided using the Tailwind config and
arbitrary values as much as possible. While you are welcome to copy
and paste these components and use them in your projects as-is, the
goal of this project is to get your projects up and running as quickly
as possible without having to worry about accessibility and
interactivity.
## Special Thanks
There are many OSS projects who have inspired and power the backbone
of this project. This project is a combination of other folks really
hard work so I'd like to recognize and thank them:
- [shadcn/ui](https://ui.shadcn.com): Without the inspiration of shadcn/ui, this project would not
exist. The idea to create a beautiful, copy and paste library
opened my eyes on how to make a useful tool without having to
worry about bundling, distribution, and a bunch of other things I
don't know much about.
- [React Aria Components](https://react-spectrum.adobe.com/react-aria/react-aria-components.html): The backbone of this project. I consider React Aria to be the de
facto accessibility library on the web. Creating React Aria
Components has made it easier than ever to build UI that is
functional and accessible to all users.
I'd especially like to acknowledge [@devongovett](https://twitter.com/devongovett)
who has been representing React Aria on Twitter and has been very
communicative about the team's progress and quick to respond
to feedback.
- [Chakra UI](): Although not directly involved with this project, I leveraged
many of their styling decisions where I wanted additional
flexibility with components. I also heavily relied on their naming
to conventions to compose components.
I've also been heavily combing through their repo to better
understand how their Storybook and Docs are working together.
================================================
FILE: apps/docs/content/getting-started/cli.mdx
================================================
---
title: CLI
description: Get started using Draft UI faster than ever by installing components right from the command line
isNew: true
order: 3
---
## Install Sly CLI
You're able to install Draft UI components from the command line thanks to an awesome project by [Jacob Paris](https://twitter.com/jacobmparis), [`@sly-cli/sly`](https://sly-cli.fly.dev/).
Run the following code to add Draft UI to your project. **`sly`** will show you a list of components available to download.
```bash title="bash"
npx @sly-cli/sly add draft-ui
```
## Configuration
**`@sly-cli/sly`** let's you configure some specific settings about how you want to install components from the CLI. Assuming you've followed the initial Draft UI installation instructions, this is what your `sly.json` should look like.
```json title="sly.json"
{
"$schema": "https://sly-cli.fly.dev/registry/config.json",
"libraries": [
{
"name": "draft-ui",
"directory": "./components",
"transformers": ["transform-sly-install.ts"], // optional, otherwise leave empty
"postinstall": [],
}
]
}
```
Of course, if you've made your own customizations, you should update your `sly.json` to match those changes.
## Transformers
**`sly`** also allows you to manipulate how you install your components via transformers.
In order to use transformers, you'll need to install **`sly`** into your project:
```bash title="bash"
npm install -D @sly-cli/sly
```
For example, if you're using a different path alias for your directories, overwrite the default values automatically.
```ts title="transform-sly-install.ts"
const cvaConfig = '@/lib/cva.config'
/**
* @type {import('@sly-cli/sly/dist').Transformer}
*/
export default async function transformSlyInstall(input: string) {
input = input.replace('@/lib/cva.config', cvaConfig)
return input
}
```
For additional information on tranformers, go to the [`@sly-cli/sly` repo](https://github.com/jacobparis-insiders/sly/blob/main/cli/README.md#transformers).
================================================
FILE: apps/docs/content/getting-started/installation.mdx
================================================
---
title: Installation
description: Here's everything you need to get started
order: 2
---
<ListStepper>
<ListStep>
## Install TailwindCSS
Depending on your project, steps to install Tailwind may vary.
Check out [their installation page](https://tailwindcss.com/docs/installation/framework-guides) for guidance.
</ListStep>
<ListStep>
## Install Required Dependencies
```bash title="bash"
npm install react-aria-components@1.0.0 cva@beta tailwind-merge tailwindcss-animate tailwindcss-react-aria-components@1.0.0
```
This project requires the following packages:
- [react-aria-components@1.0.0](https://github.com/adobe/react-spectrum/tree/main/packages/react-aria-components)
- [cva@beta](https://github.com/joe-bell/cva)
- [tailwind-merge](https://github.com/dcastil/tailwind-merge)
- [tailwindcss-animate](https://github.com/jamiebuilds/tailwindcss-animate)
- [tailwindcss-react-aria-components@1.0.0](https://github.com/adobe/react-spectrum/tree/main/packages/tailwindcss-react-aria-components)
</ListStep>
<ListStep>
## Install Icons
Draft UI uses [Lucide Icons](https://lucide.dev/guide/packages/lucide-react) by default. You can use whichever library you prefer, but
you'll need to replace the default icons manually.
```bash title="bash"
npm install lucide-react
```
</ListStep>
<ListStep>
## Configure Path Aliases
Draft UI uses the path alias <code>@/\*</code> by default. If you
want to use a different alias, you'll need to update your
components.
```json {3-6} title="tsconfig.json"
// ...
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}
// ...
```
</ListStep>
<ListStep>
## Configure Tailwind
Make sure to include the `tailwindcss-animate` plugin.
```js title="tailwind.config.js"
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['class'],
content: ['app/**/*.{ts,tsx}', 'components/**/*.{ts,tsx}'],
plugins: [
require('tailwindcss-animate'),
require('tailwindcss-react-aria-components'),
],
}
```
</ListStep>
<ListStep>
## Configure CVA
Add **`twMerge`** to your `cva.config.ts`. This way, anytime you use the `cx(...)` function any conflicting Tailwind classes will be gracefully resolved.
```ts title="cva.config.ts"
import { defineConfig } from 'cva'
import { twMerge } from 'tailwind-merge'
export const { cva, cx, compose } = defineConfig({
hooks: {
onComplete: (className) => twMerge(className),
},
})
```
</ListStep>
<ListStep>
## Configure Routing (recommended)
Many components use built-in **`Link`** components to handle navigation. By default, these links perform native browser navigation when they are interacted with.
In order for these links to work as expected with whichever framework you're using, wrap your application using React Aria's `RouterProvider` component.
<Tabs>
<TabList>
<Tab id="nextjs-app">Next.js App</Tab>
<Tab id="nextjs-pages">Next.js Pages</Tab>
<Tab id="remix">Remix</Tab>
<Tab id="react-router">React Router</Tab>
</TabList>
<TabPanel id="nextjs-app" className="px-0">
```tsx title="app/provider.tsx"
'use client'
import { useRouter } from 'next/navigation'
import { RouterProvider } from 'react-aria-components'
export function ClientProviders({ children }) {
const router = useRouter()
return (
<RouterProvider navigate={router.push}>
{children}
</RouterProvider>
)
}
```
```tsx title="app/layout.tsx"
import { ClientProviders } from './provider';
export default function RootLayout({ children }) {
return (
<html>
<body>
<ClientProviders>{children}</ClientProviders>
</body>
</html>
);
}
```
</TabPanel>
<TabPanel id="nextjs-pages" className="px-0">
```tsx title="pages/_app.tsx"
import type { AppProps } from 'next/app'
import { useRouter } from 'next/router'
import { RouterProvider } from 'react-aria-components'
export default function MyApp({ Component, pageProps }: AppProps) {
let router = useRouter()
return (
<RouterProvider navigate={router.push}>
<Component {...pageProps} />
</RouterProvider>
)
}
```
</TabPanel>
<TabPanel id="remix" className="px-0">
```tsx title="app/root.tsx"
import { useNavigate, Outlet } from '@remix-run/react'
import { RouterProvider } from 'react-aria-components'
export default function App() {
let navigate = useNavigate()
return (
<html lang="en">
<head>
{/* ... */}
</head>
<body>
<RouterProvider navigate={navigate}>
<Outlet />
</RouterProvider>
{/* ... */}
</body>
</html>
)
}
```
</TabPanel>
<TabPanel id="react-router" className="px-0">
```tsx
import { BrowserRouter, useNavigate } from 'react-router-dom'
import { RouterProvider } from 'react-aria-components'
function App() {
let navigate = useNavigate()
return (
<RouterProvider navigate={navigate}>
{/* Your app here... */}
<Routes>
<Route path="/" element={<HomePage />} />
{/* ... */}
</Routes>
</RouterProvider>
)
}
<BrowserRouter>
<App />
</BrowserRouter>
```
</TabPanel>
</Tabs>
For more information, go to the React Aria [Client Side Routing](https://react-spectrum.adobe.com/react-aria/routing.html).
</ListStep>
<ListStep>
## Configure @sly-cli/sly (optional)
If your installation varies from any of the configs described above (like if your components are in a different location) you'll want to update your `sly.json` to make sure your CLI installs work correctly.
Go to the <Link href="/getting-started/cli">CLI page</Link> to learn more.
</ListStep>
<ListStep>
## All Done!
Now you're ready to start building your application!
</ListStep>
</ListStepper>
================================================
FILE: apps/docs/content/getting-started/introduction.mdx
================================================
---
title: Introduction
description: Copy and paste-able components built with React Aria Components and
Tailwind CSS
order: 1
---
Draft UI has been massively inspired by **`shadcn/ui`** so I encourage you to take a look at [their introduction page](https://ui.shadcn.com/docs).
---
Long story short, Draft UI follows all the same ideals:
- Copy and paste components give you full control over the component
code, it is yours to use.
- Modify and adapt to your hearts content, using these docs as a
starting point.
- These components should be able to be used in any framework that
supports React.
- Draft UI is free to use on any personal or commercial projects.
And if you do, [let me know!](https://twitter.com/draft__ui)
================================================
FILE: apps/docs/contentlayer.config.ts
================================================
import { defineDocumentType, makeSource } from 'contentlayer/source-files'
// @ts-ignore
import toc from 'markdown-toc'
import rehypePrettyCode from 'rehype-pretty-code'
import remarkGfm from 'remark-gfm'
import { visit } from 'unist-util-visit'
import { rehypeComponent } from './lib/rehype-component'
import { withTableOfContents } from './lib/remark/with-table-of-contents'
import { type TocItemProps } from './types'
export const ComponentDocument = defineDocumentType(() => ({
name: 'ComponentDocument',
filePathPattern: 'components/**/*.mdx',
contentType: 'mdx',
fields: {
title: {
type: 'string',
required: true,
},
description: {
type: 'string',
},
isComponent: {
type: 'boolean',
},
isWip: {
type: 'boolean',
},
isComing: {
type: 'boolean',
},
},
computedFields: {
slug: {
type: 'string',
resolve: (post) => `/docs/${post._raw.flattenedPath}`,
},
toc: {
type: 'json',
resolve: (doc): TocItemProps => toc(doc.body.raw, { maxdepth: 3 }).json,
},
},
}))
export const GeneralDocument = defineDocumentType(() => ({
name: 'GeneralDocument',
filePathPattern: 'getting-started/**/*.mdx',
contentType: 'mdx',
fields: {
title: {
type: 'string',
required: true,
},
description: {
type: 'string',
required: true,
},
isNew: {
type: 'boolean',
},
order: {
type: 'number',
required: true,
},
},
computedFields: {
slug: {
type: 'string',
resolve: (post) => `/${post._raw.flattenedPath}`,
},
toc: {
type: 'json',
resolve: (doc): TocItemProps => toc(doc.body.raw, { maxdepth: 3 }).json,
},
},
}))
export const ChangelogDocument = defineDocumentType(() => ({
name: 'ChangelogDocument',
filePathPattern: 'CHANGELOG.mdx',
contentType: 'mdx',
fields: {
title: {
type: 'string',
required: true,
},
description: {
type: 'string',
required: true,
},
order: {
type: 'number',
required: true,
},
},
computedFields: {
slug: {
type: 'string',
resolve: () => '/changelog',
},
toc: {
type: 'json',
resolve: (doc): TocItemProps => toc(doc.body.raw, { maxdepth: 2 }).json,
},
},
}))
export default makeSource({
contentDirPath: 'content',
documentTypes: [ComponentDocument, ChangelogDocument, GeneralDocument],
mdx: {
rehypePlugins: [
rehypeComponent,
() => (tree) => {
visit(tree, (node) => {
if (node?.type === 'element' && node?.tagName === 'pre') {
const [codeEl] = node.children
if (codeEl.tagName !== 'code') {
return
}
if (codeEl.data?.meta) {
// Extract event from meta and pass it down the tree.
const regex = /event="([^"]*)"/
const match = codeEl.data?.meta.match(regex)
if (match) {
node.__event__ = match ? match[1] : null
codeEl.data.meta = codeEl.data.meta.replace(regex, '')
}
}
node.__rawString__ = codeEl.children?.[0].value
node.__src__ = node.properties?.__src__
node.__style__ = node.properties?.__style__
}
})
},
[
// @ts-expect-error related: https://github.com/atomiks/rehype-pretty-code/issues/145
rehypePrettyCode,
{
theme: 'dracula',
onVisitLine(node) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty
// lines to be copy/pasted
if (node.children.length === 0) {
node.children = [{ type: 'text', value: ' ' }]
}
},
onVisitHighlightedLine(node) {
node.properties?.className?.push('line--highlighted')
},
onVisitHighlightedWord(node) {
node.properties.className = ['word--highlighted']
},
},
],
() => (tree) => {
visit(tree, (node) => {
if (node?.type === 'element' && node?.tagName === 'figure') {
if (!('data-rehype-pretty-code-figure' in node.properties)) {
return
}
// Pass code snippet to figure wrapper
if (node.__rawString__) {
node.properties['__rawString__'] = node.__rawString__
}
// npm install
if (node.__rawString__?.startsWith('npm install')) {
const npmCommand = node.__rawString__
node.properties['__npmCommand__'] = npmCommand
node.properties['__yarnCommand__'] = npmCommand.replace(
'npm install',
'yarn add',
)
node.properties['__pnpmCommand__'] = npmCommand.replace(
'npm install',
'pnpm add',
)
node.properties['__niCommand__'] = npmCommand.replace(
'npm install',
'ni',
)
}
// npx
if (node.__rawString__?.startsWith('npx')) {
const npmCommand = node.__rawString__
node.properties['__npmCommand__'] = npmCommand
node.properties['__yarnCommand__'] = npmCommand
node.properties['__pnpmCommand__'] = npmCommand.replace(
'npx',
'pnpm dlx',
)
node.properties['__niCommand__'] = npmCommand.replace(
'npx',
'nlx',
)
}
}
})
},
],
remarkPlugins: [remarkGfm, withTableOfContents],
},
})
================================================
FILE: apps/docs/lib/cva.config.ts
================================================
import { defineConfig } from 'cva'
import { twMerge } from 'tailwind-merge'
export const { cva, cx, compose } = defineConfig({
hooks: {
onComplete: (className) => twMerge(className),
},
})
================================================
FILE: apps/docs/lib/rehype-component.ts
================================================
import fs from 'fs'
import path from 'path'
import { u } from 'unist-builder'
import { visit } from 'unist-util-visit'
import { type UnistNode, type UnistTree } from '@/types'
import { Index } from '../__registry__'
export function rehypeComponent() {
return async (tree: UnistTree) => {
visit(tree, (node: UnistNode) => {
if (node.name === 'ComponentSource') {
const src = getNodeAttributeByName(node, 'src')?.value as string
if (!src) {
return null
}
try {
// Read the source file.
const filePath = path.join(process.cwd(), src)
let source = fs.readFileSync(filePath, 'utf8')
source = source.replaceAll('export default', 'export')
node.children?.push(
u('element', {
tagName: 'pre',
properties: {
__src__: src,
},
children: [
u('element', {
tagName: 'code',
properties: {
className: ['language-tsx'],
},
children: [
{
type: 'text',
value: source,
},
],
}),
],
}),
)
} catch (error) {
console.error(error)
}
}
if (node.name === 'ComponentExample') {
const name = getNodeAttributeByName(node, 'name')?.value as string
const story = getNodeAttributeByName(node, 'story')?.value as string
if (!name || !story) {
console.log('❌ name or story prop not passed on ComponentExample')
return null
}
try {
const component = Index[name][story]
const src = component.file
// Read the source file.
const filePath = path.join(process.cwd(), src)
let source = fs.readFileSync(filePath, 'utf8')
source = source.replaceAll('export default', 'export')
node.children?.push(
u('element', {
tagName: 'pre',
properties: {
__src__: src,
},
children: [
u('element', {
tagName: 'code',
properties: {
className: ['language-tsx'],
},
children: [
{
type: 'text',
value: source,
},
],
}),
],
}),
)
} catch (error) {
console.error(error)
}
}
})
}
}
function getNodeAttributeByName(node: UnistNode, name: string) {
return node.attributes?.find((attribute) => attribute.name === name)
}
================================================
FILE: apps/docs/lib/remark/with-table-of-contents.ts
================================================
import Slugger from 'github-slugger'
import { toString } from 'hast-util-to-string'
import { visit } from 'unist-util-visit'
export function withTableOfContents() {
const slugs = new Slugger()
return (tree) => {
visit(tree, 'heading', (node) => {
node.data = node.data || {}
node.data = { hName: 'Heading' }
node.data.hProperties = node.data.hProperties || {}
node.data.hProperties.lvl = node.depth
node.data.hProperties.slug = slugs.slug(toString(node))
})
}
}
================================================
FILE: apps/docs/next.config.js
================================================
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withContentlayer } = require('next-contentlayer')
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
typedRoutes: true,
},
reactStrictMode: true,
transpilePackages: ['ui'],
redirects() {
return [
{
source: '/docs/components',
destination: '/docs/components/breadcrumbs',
permanent: true,
},
// Old Links
{
source: '/getting-started',
destination: '/getting-started/introduction',
permanent: true,
},
{
source: '/docs/introduction',
destination: '/getting-started/introduction',
permanent: true,
},
{
source: '/docs/installation',
destination: '/getting-started/installation',
permanent: true,
},
{
source: '/docs/about',
destination: '/getting-started/about',
permanent: true,
},
{
source: '/docs/changelog',
destination: '/changelog',
permanent: true,
},
]
},
}
module.exports = withContentlayer(nextConfig)
================================================
FILE: apps/docs/package.json
================================================
{
"name": "docs",
"version": "0.1.0",
"private": true,
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
"dev": "rm -rf .next & rm -rf .contentlayer && contentlayer build && next dev",
"build": "contentlayer build && next build",
"start": "next start",
"lint": "eslint --ignore-path .gitignore '**/*.{js,jsx,cjs,mjs,ts,tsx,json}'",
"typecheck": "tsc --noEmit --pretty"
},
"dependencies": {
"@docsearch/react": "^3.4.0",
"@vercel/analytics": "^1.0.1",
"contentlayer": "0.3.4",
"fathom-client": "^3.5.0",
"fs-extra": "11.1.1",
"gray-matter": "^4.0.3",
"hast-util-to-string": "^3.0.0",
"lucide-react": "^0.259.0",
"markdown-toc": "^1.2.0",
"next": "14.0.4",
"next-contentlayer": "0.3.4",
"next-themes": "^0.2.1",
"react": "18.2.0",
"react-aria-components": "1.0.0",
"react-dom": "18.2.0",
"react-stately": "^3.21.0",
"rehype-pretty-code": "^0.12.3",
"remark-gfm": "^3.0.1",
"shikiji": "^0.9.0",
"tailwind-merge": "^1.13.2",
"ui": "workspace:*",
"unist-util-visit": "^5.0.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",
"@types/node": "18.16.19",
"@types/react": "18.0.27",
"@types/react-dom": "18.0.10",
"@types/unist": "^3.0.2",
"autoprefixer": "^10.4.14",
"eslint": "^8.56.0",
"eslint-config-custom": "workspace:*",
"eslint-plugin-mdx": "^2.3.2",
"postcss": "^8.4.23",
"postcss-config": "workspace:*",
"tailwind-config": "workspace:*",
"tailwindcss": "^3.4.1",
"ts-config": "workspace:*",
"ts-pattern": "^5.0.6",
"typescript": "^5.1.6",
"unist-builder": "^4.0.0"
}
}
================================================
FILE: apps/docs/postcss.config.js
================================================
/** @type {import('postcss').Config} */
module.exports = require('postcss-config/postcss.config.cjs')
================================================
FILE: apps/docs/public/site.webmanifest
================================================
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
================================================
FILE: apps/docs/registry/breadcrumbs/default.tsx
================================================
import { ChevronRight } from 'lucide-react'
import { BreadcrumbItem, BreadcrumbLink, Breadcrumbs } from 'ui'
export default function Default() {
return (
<Breadcrumbs>
<BreadcrumbItem separator={<ChevronRight size="1em" />}>
<BreadcrumbLink href="#">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbItem separator={<ChevronRight size="1em" />}>
<BreadcrumbLink href="#">React Aria</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbItem>
<BreadcrumbLink>useBreadcrumbs</BreadcrumbLink>
</BreadcrumbItem>
</Breadcrumbs>
)
}
================================================
FILE: apps/docs/registry/button/default.tsx
================================================
import { Button } from 'ui'
export default function Default() {
return <Button>Press Me</Button>
}
================================================
FILE: apps/docs/registry/button/disabled.tsx
================================================
import { Button } from 'ui'
export default function Disabled() {
return (
<div className="flex flex-wrap justify-center gap-4">
<Button variant="solid" isDisabled>
Solid
</Button>
<Button variant="outline" isDisabled>
Outline
</Button>
<Button variant="subtle" isDisabled>
Subtle
</Button>
<Button variant="ghost" isDisabled>
Ghost
</Button>
<Button variant="destructive" isDisabled>
Destructive
</Button>
<Button variant="link" isDisabled>
Link
</Button>
</div>
)
}
================================================
FILE: apps/docs/registry/button/sizes.tsx
================================================
import { Button } from 'ui'
export default function Sizes() {
return (
<div className="flex flex-wrap justify-center gap-4">
<Button size="xs">X Small</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
</div>
)
}
================================================
FILE: apps/docs/registry/button/theme.tsx
================================================
import { Button } from 'ui'
export default function Theme() {
return (
<div className="flex flex-wrap justify-center gap-4">
<Button variant="solid">Solid</Button>
<Button variant="outline">Outline</Button>
<Button variant="subtle">Subtle</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="link">Link</Button>
</div>
)
}
================================================
FILE: apps/docs/registry/calendar/default.tsx
================================================
import {
Calendar,
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeaderCell,
CalendarHeading,
CalendarNextButton,
CalendarPrevButton,
} from 'ui'
export default function Default() {
return (
<Calendar>
<CalendarHeader>
<CalendarPrevButton />
<CalendarHeading />
<CalendarNextButton />
</CalendarHeader>
<CalendarGrid>
<CalendarGridHeader>
{(day) => <CalendarHeaderCell>{day}</CalendarHeaderCell>}
</CalendarGridHeader>
<CalendarGridBody>
{(date) => <CalendarCell date={date} />}
</CalendarGridBody>
</CalendarGrid>
</Calendar>
)
}
================================================
FILE: apps/docs/registry/checkbox/default.tsx
================================================
import { Checkbox } from 'ui'
export default function Default() {
return (
<div className="space-y-4">
<Checkbox value="cat">Cat</Checkbox>
<Checkbox value="dog" defaultSelected>
Dog
</Checkbox>
<Checkbox value="reptile" isIndeterminate>
Reptile
</Checkbox>
</div>
)
}
================================================
FILE: apps/docs/registry/checkbox/disabled.tsx
================================================
import { Checkbox } from 'ui'
export default function Sizes() {
return (
<div className="space-y-4">
<Checkbox value="cat">Medium Cat</Checkbox>
<Checkbox value="dog" isDisabled>
Medium Dog
</Checkbox>
<Checkbox value="reptile" defaultSelected isDisabled>
Medium Reptile
</Checkbox>
</div>
)
}
================================================
FILE: apps/docs/registry/checkbox/sizes.tsx
================================================
import { Checkbox } from 'ui'
export default function Sizes() {
return (
<div className="space-y-6">
<div className="space-y-1">
<Checkbox size="sm" value="cat-sm">
Small Cat
</Checkbox>
<Checkbox size="sm" value="dog-sm">
Small Dog
</Checkbox>
<Checkbox size="sm" value="reptile-sm" isIndeterminate>
Small Reptile
</Checkbox>
</div>
<div className="space-y-2">
<Checkbox size="md" value="cat-md">
Medium Cat
</Checkbox>
<Checkbox size="md" value="dog-md">
Medium Dog
</Checkbox>
<Checkbox size="md" value="reptile-md" isIndeterminate>
Medium Reptile
</Checkbox>
</div>
<div className="space-y-2">
<Checkbox size="lg" value="cat-lg">
Large Cat
</Checkbox>
<Checkbox size="lg" value="dog-lg">
Large Dog
</Checkbox>
<Checkbox size="lg" value="reptile-lg" isIndeterminate>
Large Reptile
</Checkbox>
</div>
</div>
)
}
================================================
FILE: apps/docs/registry/checkbox-group/default.tsx
================================================
import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'
export default function Default() {
return (
<CheckboxGroup>
<Label>Favorite sports</Label>
<CheckboxGroupContent>
<Checkbox value="soccer">Soccer</Checkbox>
<Checkbox value="baseball">Baseball</Checkbox>
<Checkbox value="basketball">Basketball</Checkbox>
</CheckboxGroupContent>
</CheckboxGroup>
)
}
================================================
FILE: apps/docs/registry/checkbox-group/disabled.tsx
================================================
import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'
export default function Default() {
return (
<CheckboxGroup isDisabled defaultValue={['basketball']}>
<Label>Favorite sports</Label>
<CheckboxGroupContent>
<Checkbox value="soccer">Soccer</Checkbox>
<Checkbox value="baseball" isIndeterminate>
Baseball
</Checkbox>
<Checkbox value="basketball">Basketball</Checkbox>
</CheckboxGroupContent>
</CheckboxGroup>
)
}
================================================
FILE: apps/docs/registry/checkbox-group/horizontal.tsx
================================================
import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'
export default function Horizontal() {
return (
<CheckboxGroup orientation="horizontal">
<Label>Favorite sports</Label>
<CheckboxGroupContent>
<Checkbox value="soccer">Soccer</Checkbox>
<Checkbox value="baseball">Baseball</Checkbox>
<Checkbox value="basketball">Basketball</Checkbox>
</CheckboxGroupContent>
</CheckboxGroup>
)
}
================================================
FILE: apps/docs/registry/combobox/default.tsx
================================================
import {
ComboBox,
ComboBoxContent,
ComboBoxInput,
ComboBoxItem,
Label,
} from 'ui'
export default function Default() {
return (
<ComboBox>
<Label>Favorite Animal</Label>
<ComboBoxInput />
<ComboBoxContent>
<ComboBoxItem textValue="Aardvark">Aardvark</ComboBoxItem>
<ComboBoxItem textValue="Cat">Cat</ComboBoxItem>
<ComboBoxItem textValue="Dog">Dog</ComboBoxItem>
<ComboBoxItem textValue="Kangaroo">Kangaroo</ComboBoxItem>
<ComboBoxItem textValue="Panda">Panda</ComboBoxItem>
<ComboBoxItem textValue="Snake">Snake</ComboBoxItem>
</ComboBoxContent>
</ComboBox>
)
}
================================================
FILE: apps/docs/registry/combobox/disabled-keys.tsx
================================================
import { ChevronDown } from 'lucide-react'
import {
ComboBox,
ComboBoxButton,
ComboBoxContent,
ComboBoxInput,
ComboBoxItem,
iconButtonVariants,
Label,
} from 'ui'
export default function DisabledKeys() {
return (
<ComboBox disabledKeys={['cat', 'kangaroo']}>
<Label>Favorite Animal</Label>
<div className="relative">
<ComboBoxInput />
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<ComboBoxButton
className={iconButtonVariants({
variant: 'subtle',
size: 'sm',
className: 'ml-auto shrink-0',
})}
>
<ChevronDown size="16" strokeWidth="3" />
</ComboBoxButton>
</div>
</div>
<ComboBoxContent>
<ComboBoxItem id="aardvark" textValue="Aardvark">
Aardvark
</ComboBoxItem>
<ComboBoxItem id="cat" textValue="Cat">
Cat
</ComboBoxItem>
<ComboBoxItem id="dog" textValue="Dog">
Dog
</ComboBoxItem>
<ComboBoxItem id="kangaroo" textValue="Kangaroo">
Kangaroo
</ComboBoxItem>
<ComboBoxItem id="panda" textValue="Panda">
Panda
</ComboBoxItem>
<ComboBoxItem id="snake" textValue="Snake">
Snake
</ComboBoxItem>
</ComboBoxContent>
</ComboBox>
)
}
================================================
FILE: apps/docs/registry/combobox/disabled.tsx
================================================
import { ChevronDown } from 'lucide-react'
import {
ComboBox,
ComboBoxButton,
ComboBoxContent,
ComboBoxInput,
ComboBoxItem,
iconButtonVariants,
Label,
} from 'ui'
export default function Disabled() {
return (
<ComboBox isDisabled>
<Label>Favorite Animal</Label>
<div className="relative">
<ComboBoxInput />
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<ComboBoxButton
className={iconButtonVariants({
variant: 'subtle',
size: 'sm',
className: 'ml-auto shrink-0',
})}
>
<ChevronDown size="16" strokeWidth="3" />
</ComboBoxButton>
</div>
</div>
<ComboBoxContent>
<ComboBoxItem textValue="Aardvark">Aardvark</ComboBoxItem>
<ComboBoxItem textValue="Cat">Cat</ComboBoxItem>
<ComboBoxItem textValue="Dog">Dog</ComboBoxItem>
<ComboBoxItem textValue="Kangaroo">Kangaroo</ComboBoxItem>
<ComboBoxItem textValue="Panda">Panda</ComboBoxItem>
<ComboBoxItem textValue="Snake">Snake</ComboBoxItem>
</ComboBoxContent>
</ComboBox>
)
}
================================================
FILE: apps/docs/registry/combobox/with-button.tsx
================================================
import { ChevronDown } from 'lucide-react'
import {
ComboBox,
ComboBoxButton,
ComboBoxContent,
ComboBoxInput,
ComboBoxItem,
iconButtonVariants,
Label,
} from 'ui'
export default function WithButton() {
return (
<ComboBox>
<Label>Favorite Animal</Label>
<div className="relative">
<ComboBoxInput />
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<ComboBoxButton
className={iconButtonVariants({
variant: 'subtle',
size: 'sm',
className: 'ml-auto shrink-0',
})}
>
<ChevronDown size="16" strokeWidth="3" />
</ComboBoxButton>
</div>
</div>
<ComboBoxContent>
<ComboBoxItem textValue="Aardvark">Aardvark</ComboBoxItem>
<ComboBoxItem textValue="Cat">Cat</ComboBoxItem>
<ComboBoxItem textValue="Dog">Dog</ComboBoxItem>
<ComboBoxItem textValue="Kangaroo">Kangaroo</ComboBoxItem>
<ComboBoxItem textValue="Panda">Panda</ComboBoxItem>
<ComboBoxItem textValue="Snake">Snake</ComboBoxItem>
</ComboBoxContent>
</ComboBox>
)
}
================================================
FILE: apps/docs/registry/date-field/default.tsx
================================================
import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui'
export default function Default() {
return (
<DateField>
<Label>Date Label</Label>
<DateInputGroup>
<DateInput>{(segment) => <DateSegment segment={segment} />}</DateInput>
</DateInputGroup>
</DateField>
)
}
================================================
FILE: apps/docs/registry/date-field/disabled.tsx
================================================
import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui'
export default function Disabled() {
return (
<DateField isDisabled>
<Label>Date Label</Label>
<DateInputGroup>
<DateInput>{(segment) => <DateSegment segment={segment} />}</DateInput>
</DateInputGroup>
</DateField>
)
}
================================================
FILE: apps/docs/registry/date-input/default.tsx
================================================
import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui'
export default function Default() {
return (
<DateField>
<DateInputGroup>
<DateInput>{(segment) => <DateSegment segment={segment} />}</DateInput>
</DateInputGroup>
</DateField>
)
}
================================================
FILE: apps/docs/registry/date-input/sizes.tsx
================================================
import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui'
export default function Sizes() {
return (
<div className="flex flex-col gap-4">
<DateField>
<DateInputGroup size="xs">
<DateInput>
{(segment) => <DateSegment segment={segment} />}
</DateInput>
</DateInputGroup>
</DateField>
<DateField>
<DateInputGroup size="sm">
<DateInput>
{(segment) => <DateSegment segment={segment} />}
</DateInput>
</DateInputGroup>
</DateField>
<DateField>
<DateInputGroup size="md">
<DateInput>
{(segment) => <DateSegment segment={segment} />}
</DateInput>
</DateInputGroup>
</DateField>
<DateField>
<DateInputGroup size="lg">
<DateInput>
{(segment) => <DateSegment segment={segment} />}
</DateInput>
</DateInputGroup>
</DateField>
</div>
)
}
================================================
FILE: apps/docs/registry/date-picker/default.tsx
================================================
import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react'
import {
Calendar,
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeaderCell,
CalendarHeading,
CalendarNextButton,
CalendarPrevButton,
DateInput,
DateInputGroup,
DatePicker,
DatePickerButton,
DatePickerContent,
DateSegment,
iconButtonVariants,
Label,
} from 'ui'
export default function Default() {
return (
<DatePicker>
<Label>Date</Label>
<DateInputGroup className="relative pr-10">
<DateInput>{(segment) => <DateSegment segment={segment} />}</DateInput>
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<DatePickerButton
className={iconButtonVariants({
variant: 'subtle',
size: 'sm',
className: 'ml-auto shrink-0',
})}
>
<ChevronDown size="16" strokeWidth="3" />
</DatePickerButton>
</div>
</DateInputGroup>
<DatePickerContent>
<Calendar>
<CalendarHeader>
<CalendarPrevButton
className={iconButtonVariants({
variant: 'outline',
size: 'sm',
})}
>
<ChevronLeft size="16" strokeWidth="3" />
</CalendarPrevButton>
<CalendarHeading />
<CalendarNextButton
className={iconButtonVariants({
variant: 'outline',
size: 'sm',
})}
>
<ChevronRight size="16" strokeWidth="3" />
</CalendarNextButton>
</CalendarHeader>
<CalendarGrid>
<CalendarGridHeader>
{(day) => <CalendarHeaderCell>{day}</CalendarHeaderCell>}
</CalendarGridHeader>
<CalendarGridBody>
{(date) => <CalendarCell date={date} />}
</CalendarGridBody>
</CalendarGrid>
</Calendar>
</DatePickerContent>
</DatePicker>
)
}
================================================
FILE: apps/docs/registry/date-picker/disabled.tsx
================================================
import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react'
import {
Calendar,
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeaderCell,
CalendarHeading,
CalendarNextButton,
CalendarPrevButton,
DateInput,
DateInputGroup,
DatePicker,
DatePickerButton,
DatePickerContent,
DateSegment,
iconButtonVariants,
Label,
} from 'ui'
export default function Default() {
return (
<DatePicker isDisabled>
<Label>Date</Label>
<DateInputGroup className="relative pr-10">
<DateInput>{(segment) => <DateSegment segment={segment} />}</DateInput>
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<DatePickerButton
className={iconButtonVariants({
variant: 'subtle',
size: 'sm',
className: 'ml-auto shrink-0',
})}
>
<ChevronDown size="16" strokeWidth="3" />
</DatePickerButton>
</div>
</DateInputGroup>
<DatePickerContent>
<Calendar>
<CalendarHeader>
<CalendarPrevButton
className={iconButtonVariants({
variant: 'outline',
size: 'sm',
})}
>
<ChevronLeft size="16" strokeWidth="3" />
</CalendarPrevButton>
<CalendarHeading />
<CalendarNextButton
className={iconButtonVariants({
variant: 'outline',
size: 'sm',
})}
>
<ChevronRight size="16" strokeWidth="3" />
</CalendarNextButton>
</CalendarHeader>
<CalendarGrid>
<CalendarGridHeader>
{(day) => <CalendarHeaderCell>{day}</CalendarHeaderCell>}
</CalendarGridHeader>
<CalendarGridBody>
{(date) => <CalendarCell date={date} />}
</CalendarGridBody>
</CalendarGrid>
</Calendar>
</DatePickerContent>
</DatePicker>
)
}
================================================
FILE: apps/docs/registry/date-range-picker/default.tsx
================================================
import { ChevronDown } from 'lucide-react'
import {
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeaderCell,
CalendarHeading,
CalendarNextButton,
CalendarPrevButton,
DateInput,
DateInputGroup,
DatePickerButton,
DatePickerContent,
DateRangePicker,
DateSegment,
iconButtonVariants,
Label,
RangeCalendar,
} from 'ui'
export default function Default() {
return (
<DateRangePicker>
<Label>Date Range</Label>
<DateInputGroup className="relative pr-10">
<DateInput slot="start">
{(segment) => <DateSegment segment={segment} />}
</DateInput>
<span aria-hidden="true" className="px-2">
–
</span>
<DateInput slot="end">
{(segment) => <DateSegment segment={segment} />}
</DateInput>
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<DatePickerButton
className={iconButtonVariants({
variant: 'subtle',
size: 'sm',
className: 'ml-auto shrink-0',
})}
>
<ChevronDown size="16" strokeWidth="3" />
</DatePickerButton>
</div>
</DateInputGroup>
<DatePickerContent>
<RangeCalendar>
<CalendarHeader>
<CalendarPrevButton />
<CalendarHeading />
<CalendarNextButton />
</CalendarHeader>
<CalendarGrid>
<CalendarGridHeader>
{(day) => <CalendarHeaderCell>{day}</CalendarHeaderCell>}
</CalendarGridHeader>
<CalendarGridBody>
{(date) => <CalendarCell date={date} />}
</CalendarGridBody>
</CalendarGrid>
</RangeCalendar>
</DatePickerContent>
</DateRangePicker>
)
}
================================================
FILE: apps/docs/registry/date-range-picker/disabled.tsx
================================================
import { ChevronDown } from 'lucide-react'
import {
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeaderCell,
CalendarHeading,
CalendarNextButton,
CalendarPrevButton,
DateInput,
DateInputGroup,
DatePickerButton,
DatePickerContent,
DateRangePicker,
DateSegment,
iconButtonVariants,
Label,
RangeCalendar,
} from 'ui'
export default function Default() {
return (
<DateRangePicker isDisabled>
<Label>Date Range</Label>
<DateInputGroup className="relative pr-10">
<DateInput slot="start">
{(segment) => <DateSegment segment={segment} />}
</DateInput>
<span aria-hidden="true" className="px-2">
–
</span>
<DateInput slot="end">
{(segment) => <DateSegment segment={segment} />}
</DateInput>
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<DatePickerButton
className={iconButtonVariants({
variant: 'subtle',
size: 'sm',
className: 'ml-auto shrink-0',
})}
>
<ChevronDown size="16" strokeWidth="3" />
</DatePickerButton>
</div>
</DateInputGroup>
<DatePickerContent>
<RangeCalendar>
<CalendarHeader>
<CalendarPrevButton />
<CalendarHeading />
<CalendarNextButton />
</CalendarHeader>
<CalendarGrid>
<CalendarGridHeader>
{(day) => <CalendarHeaderCell>{day}</CalendarHeaderCell>}
</CalendarGridHeader>
<CalendarGridBody>
{(date) => <CalendarCell date={date} />}
</CalendarGridBody>
</CalendarGrid>
</RangeCalendar>
</DatePickerContent>
</DateRangePicker>
)
}
================================================
FILE: apps/docs/registry/grid-list/default.tsx
================================================
import { Info } from 'lucide-react'
import { Checkbox, GridList, GridListItem, IconButton } from 'ui'
export default function Default() {
return (
<GridList aria-label="Favorite pokemon" selectionMode="multiple">
<GridListItem
className="[&_[role=gridcell]]:flex [&_[role=gridcell]]:items-center"
textValue="Charizard"
>
<Checkbox />
Charizard
<IconButton
className="ml-2"
size="sm"
variant="subtle"
aria-label="Info"
>
<Info size="1em" />
</IconButton>
</GridListItem>
<GridListItem
className="[&_[role=gridcell]]:flex [&_[role=gridcell]]:items-center"
textValue="Blastoise"
>
<Checkbox />
Blastoise
<IconButton
className="ml-2"
size="sm"
variant="subtle"
aria-label="Info"
>
<Info size="1em" />
</IconButton>
</GridListItem>
<GridListItem
className="[&_[role=gridcell]]:flex [&_[role=gridcell]]:items-center"
textValue="Venusaur"
>
<Checkbox />
Venusaur
<IconButton
className="ml-2"
size="sm"
variant="subtle"
aria-label="Info"
>
<Info size="1em" />
</IconButton>
</GridListItem>
<GridListItem
className="[&_[role=gridcell]]:flex [&_[role=gridcell]]:items-center"
textValue="Pikachu"
>
<Checkbox />
Pikachu
<IconButton
className="ml-2"
size="sm"
variant="subtle"
aria-label="Info"
>
<Info size="1em" />
</IconButton>
</GridListItem>
</GridList>
)
}
================================================
FILE: apps/docs/registry/icon-button/default.tsx
================================================
import { AlertCircle } from 'lucide-react'
import { IconButton } from 'ui'
export default function Default() {
return (
<IconButton aria-label="alert">
<AlertCircle size="1em" />
</IconButton>
)
}
================================================
FILE: apps/docs/registry/icon-button/disabled.tsx
================================================
import { AlertCircle } from 'lucide-react'
import { IconButton } from 'ui'
export default function Disabled() {
return (
<div className="flex flex-wrap justify-center gap-4">
<IconButton variant="solid" aria-label="alert" isDisabled>
<AlertCircle size="1em" />
</IconButton>
<IconButton variant="outline" aria-label="alert" isDisabled>
<AlertCircle size="1em" />
</IconButton>
<IconButton variant="subtle" aria-label="alert" isDisabled>
<AlertCircle size="1em" />
</IconButton>
<IconButton variant="ghost" aria-label="alert" isDisabled>
<AlertCircle size="1em" />
</IconButton>
<IconButton variant="destructive" aria-label="alert" isDisabled>
<AlertCircle size="1em" />
</IconButton>
<IconButton variant="link" aria-label="alert" isDisabled>
<AlertCircle size="1em" />
</IconButton>
</div>
)
}
================================================
FILE: apps/docs/registry/icon-button/sizes.tsx
================================================
import { AlertCircle } from 'lucide-react'
import { IconButton } from 'ui'
export default function Sizes() {
return (
<div className="flex flex-wrap justify-center gap-4">
<IconButton aria-label="alert" size="xs">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" size="sm">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" size="md">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" size="lg">
<AlertCircle size="1em" />
</IconButton>
</div>
)
}
================================================
FILE: apps/docs/registry/icon-button/theme.tsx
================================================
import { AlertCircle } from 'lucide-react'
import { IconButton } from 'ui'
export default function Theme() {
return (
<div className="flex flex-wrap justify-center gap-4">
<IconButton aria-label="alert" variant="solid">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" variant="outline">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" variant="subtle">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" variant="ghost">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" variant="destructive">
<AlertCircle size="1em" />
</IconButton>
<IconButton aria-label="alert" variant="link">
<AlertCircle size="1em" />
</IconButton>
</div>
)
}
================================================
FILE: apps/docs/registry/input/default.tsx
================================================
import { Input } from 'ui'
export default function Default() {
return <Input />
}
================================================
FILE: apps/docs/registry/input/disabled.tsx
================================================
import { Input } from 'ui'
export default function Disabled() {
return <Input disabled />
}
================================================
FILE: apps/docs/registry/input/sizes.tsx
================================================
import { Input } from 'ui'
export default function Sizes() {
return (
<div className="flex flex-col gap-4">
<Input size="xs" />
<Input size="sm" />
<Input size="md" />
<Input size="lg" />
</div>
)
}
================================================
FILE: apps/docs/registry/label/default.tsx
================================================
import { Label } from 'ui'
export default function Default() {
return <Label>This is a label</Label>
}
================================================
FILE: apps/docs/registry/menu/as-checkbox.tsx
================================================
import * as React from 'react'
import { ChevronDown } from 'lucide-react'
import { type Selection } from 'react-aria-components'
import { Button, Menu, MenuContent, MenuItem } from 'ui'
export default function AsCheckbox() {
const [selected, setSelected] = React.useState<Selection>(new Set(['bar1']))
return (
<Menu>
<Button className="flex items-center gap-2">
<span>Menu</span>
<ChevronDown size="16" strokeWidth="3" />
</Button>
<MenuContent
selectionMode="multiple"
onSelectionChange={setSelected}
selectedKeys={selected}
>
<MenuItem id="foo1">Foo</MenuItem>
<MenuItem id="bar1">Bar</MenuItem>
<MenuItem id="baz1">Baz</MenuItem>
</MenuContent>
</Menu>
)
}
================================================
FILE: apps/docs/registry/menu/as-radio.tsx
================================================
import * as React from 'react'
import { ChevronDown } from 'lucide-react'
import { type Selection } from 'react-aria-components'
import { Button, Menu, MenuContent, MenuItem } from 'ui'
export default function AsRadio() {
const [selected, setSelected] = React.useState<Selection>(new Set(['bar1']))
return (
<Menu>
<Button className="flex items-center gap-2">
<span>Menu</span>
<ChevronDown size="16" strokeWidth="3" />
</Button>
<MenuContent
selectionMode="single"
onSelectionChange={setSelected}
selectedKeys={selected}
>
<MenuItem id="foo1">Foo</MenuItem>
<MenuItem id="bar1">Bar</MenuItem>
<MenuItem id="baz1">Baz</MenuItem>
</MenuContent>
</Menu>
)
}
================================================
FILE: apps/docs/registry/menu/default.tsx
================================================
import { ChevronDown } from 'lucide-react'
import { Button, Menu, MenuContent, MenuItem } from 'ui'
export default function Default() {
return (
<Menu>
<Button className="flex items-center gap-2">
<span>Menu</span>
<ChevronDown size="16" strokeWidth="3" />
</Button>
<MenuContent>
<MenuItem id="foo1">Foo</MenuItem>
<MenuItem id="bar1">Bar</MenuItem>
<MenuItem id="baz1">Baz</MenuItem>
</MenuContent>
</Menu>
)
}
================================================
FILE: apps/docs/registry/menu/disabled.tsx
================================================
import { ChevronDown } from 'lucide-react'
import { Button, Menu, MenuContent, MenuItem } from 'ui'
export default function Disabled() {
return (
<Menu>
<Button className="flex items-center gap-2">
<span>Menu</span>
<ChevronDown size="16" strokeWidth="3" />
</Button>
<MenuContent disabledKeys={['baz1']}>
<MenuItem id="foo1">Foo</MenuItem>
<MenuItem id="bar1">Bar</MenuItem>
<MenuItem id="baz1">Baz</MenuItem>
</MenuContent>
</Menu>
)
}
================================================
FILE: apps/docs/registry/menu/with-sections.tsx
================================================
import { ChevronDown } from 'lucide-react'
import {
Button,
Menu,
MenuContent,
MenuHeader,
MenuItem,
MenuSection,
MenuSeparator,
} from 'ui'
export default function WithSections() {
return (
<Menu>
<Button className="flex items-center gap-2">
<span>Menu</span>
<ChevronDown size="16" strokeWidth="3" />
</Button>
<MenuContent>
<MenuSection>
<MenuHeader>Styles</MenuHeader>
<MenuItem id="foo1">Foo</MenuItem>
<MenuItem id="bar1">Bar</MenuItem>
<MenuItem id="baz1">Baz</MenuItem>
</MenuSection>
<MenuSeparator />
<MenuSection>
<MenuHeader>Align</MenuHeader>
<MenuItem id="foo2">Foo</MenuItem>
<MenuItem id="bar2">Bar</MenuItem>
<MenuItem id="baz2">Baz</MenuItem>
</MenuSection>
</MenuContent>
</Menu>
)
}
================================================
FILE: apps/docs/registry/meter/default.tsx
================================================
import { Label, Meter, MeterFilledTrack, MeterTrack } from 'ui'
export default function Default() {
return (
<Meter value={75} minValue={0} maxValue={100}>
{({ percentage }) => (
<>
<Label>Meter Label</Label>
<MeterTrack>
<MeterFilledTrack percentage={percentage} />
</MeterTrack>
</>
)}
</Meter>
)
}
================================================
FILE: apps/docs/registry/modal/default.tsx
================================================
import * as React from 'react'
import { X } from 'lucide-react'
import {
Button,
IconButton,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
} from 'ui'
export default function Default() {
const [isOpen, setIsOpen] = React.useState(false)
return (
<>
<Button onPress={() => setIsOpen(true)}>Open Modal</Button>
<ModalOverlay isOpen={isOpen} onOpenChange={setIsOpen}>
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<IconButton
className="absolute right-2 top-2"
size="sm"
variant="ghost"
aria-label="close"
onPress={() => setIsOpen(false)}
>
<X size="1em" />
</IconButton>
<ModalBody>
<p className="text-black dark:text-white">
Sit nulla est ex deserunt exercitation anim occaecat. Nostrud
ullamco deserunt aute id consequat veniam incididunt duis in sint
irure nisi. Mollit officia cillum Lorem ullamco minim nostrud elit
officia tempor esse quis.
</p>
</ModalBody>
<ModalFooter className="flex">
<Button className="ml-auto" onPress={() => setIsOpen(false)}>
Close
</Button>
<Button
className="ml-2"
variant="outline"
onPress={() => setIsOpen(false)}
>
Confirm
</Button>
</ModalFooter>
</ModalContent>
</ModalOverlay>
</>
)
}
================================================
FILE: apps/docs/registry/modal/dismissable-false.tsx
================================================
import * as React from 'react'
import { X } from 'lucide-react'
import {
Button,
IconButton,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
} from 'ui'
export default function DismissableFalse() {
const [isOpen, setIsOpen] = React.useState(false)
return (
<>
<Button onPress={() => setIsOpen(true)}>Open Modal</Button>
<ModalOverlay
isOpen={isOpen}
onOpenChange={setIsOpen}
isDismissable={false}
isKeyboardDismissDisabled={true}
>
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<IconButton
className="absolute right-2 top-2"
size="sm"
variant="ghost"
aria-label="close"
onPress={() => setIsOpen(false)}
>
<X size="1em" />
</IconButton>
<ModalBody>
<p className="text-black dark:text-white">
Sit nulla est ex deserunt exercitation anim occaecat. Nostrud
ullamco deserunt aute id consequat veniam incididunt duis in sint
irure nisi. Mollit officia cillum Lorem ullamco minim nostrud elit
officia tempor esse quis.
</p>
</ModalBody>
<ModalFooter className="flex">
<Button className="ml-auto" onPress={() => setIsOpen(false)}>
Close
</Button>
<Button
className="ml-2"
variant="outline"
onPress={() => setIsOpen(false)}
>
Confirm
</Button>
</ModalFooter>
</ModalContent>
</ModalOverlay>
</>
)
}
================================================
FILE: apps/docs/registry/modal/set-autofocus.tsx
================================================
import * as React from 'react'
import { X } from 'lucide-react'
import {
Button,
IconButton,
Input,
Label,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
TextField,
} from 'ui'
export default function SetAutofocus() {
const [isOpen, setIsOpen] = React.useState(false)
return (
<>
<Button onPress={() => setIsOpen(true)}>Open Modal</Button>
<ModalOverlay isOpen={isOpen} onOpenChange={setIsOpen}>
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<IconButton
className="absolute right-2 top-2"
size="sm"
variant="ghost"
aria-label="close"
onPress={() => setIsOpen(false)}
>
<X size="1em" />
</IconButton>
<ModalBody className="flex flex-col gap-4">
<TextField autoFocus>
<Label>First Name</Label>
<Input />
</TextField>
<TextField>
<Label>Last Name</Label>
<Input />
</TextField>
</ModalBody>
<ModalFooter className="flex">
<Button className="ml-auto" onPress={() => setIsOpen(false)}>
Close
</Button>
<Button
className="ml-2"
variant="outline"
onPress={() => setIsOpen(false)}
>
Confirm
</Button>
</ModalFooter>
</ModalContent>
</ModalOverlay>
</>
)
}
================================================
FILE: apps/docs/registry/modal/sizes.tsx
================================================
import * as React from 'react'
import { X } from 'lucide-react'
import {
Button,
IconButton,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
type ModalContentProps,
} from 'ui'
type Size = Pick<ModalContentProps, 'size'>['size']
export default function Default() {
const [isOpen, setIsOpen] = React.useState(false)
const [modalSize, setModalSize] = React.useState<Size>('md')
const sizes: Size[] = ['xs', 'sm', 'md', 'lg', 'xl', 'full']
const handlePress = (size: Size, open: boolean) => {
setModalSize(size)
setIsOpen(open)
}
return (
<>
<div className="grid grid-cols-3 gap-4">
{sizes.map((size, idx) => (
<Button onPress={() => handlePress(size, true)} key={idx}>
Open {size}
</Button>
))}
</div>
<ModalOverlay isOpen={isOpen} onOpenChange={setIsOpen}>
<ModalContent size={modalSize}>
<ModalHeader>Modal Title</ModalHeader>
<IconButton
className="absolute right-2 top-2"
size="sm"
variant="ghost"
aria-label="close"
onPress={() => setIsOpen(false)}
>
<X size="1em" />
</IconButton>
<ModalBody>
<p className="text-black dark:text-white">
Sit nulla est ex deserunt exercitation anim occaecat. Nostrud
ullamco deserunt aute id consequat veniam incididunt duis in sint
irure nisi. Mollit officia cillum Lorem ullamco minim nostrud elit
officia tempor esse quis.
</p>
</ModalBody>
<ModalFooter className="flex">
<Button className="ml-auto" onPress={() => setIsOpen(false)}>
Close
</Button>
<Button
className="ml-2"
variant="outline"
onPress={() => setIsOpen(false)}
>
Confirm
</Button>
</ModalFooter>
</ModalContent>
</ModalOverlay>
</>
)
}
================================================
FILE: apps/docs/registry/number-field/default.tsx
================================================
import { Input, Label, NumberField } from 'ui'
export default function Default() {
return (
<NumberField defaultValue={50}>
<Label>Width</Label>
<Input />
</NumberField>
)
}
================================================
FILE: apps/docs/registry/number-field/disabled.tsx
================================================
import * as React from 'react'
import { ChevronDown, ChevronUp } from 'lucide-react'
import {
Label,
NumberDecrementStepper,
NumberField,
NumberIncrementStepper,
NumberInput,
NumberInputGroup,
NumberInputStepper,
} from 'ui'
export default function Default() {
return (
<NumberField defaultValue={50} isDisabled>
<Label>Width</Label>
<NumberInputGroup className="relative">
<NumberInput />
<NumberInputStepper>
<NumberIncrementStepper>
<ChevronUp size="1em" strokeWidth="3" />
</NumberIncrementStepper>
<NumberDecrementStepper>
<ChevronDown size="1em" strokeWidth="3" />
</NumberDecrementStepper>
</NumberInputStepper>
</NumberInputGroup>
</NumberField>
)
}
================================================
FILE: apps/docs/registry/number-field/with-mobile-stepper.tsx
================================================
import { ChevronDown, ChevronUp } from 'lucide-react'
import { IconButton, Input, Label, NumberField, NumberInputGroup } from 'ui'
export default function Mobile() {
return (
<NumberField defaultValue={50}>
<Label>Width</Label>
<NumberInputGroup className="flex gap-1">
<IconButton className="shrink-0" slot="decrement" aria-label="Decrease">
<ChevronDown size="16" strokeWidth="3" />
</IconButton>
<Input />
<IconButton className="shrink-0" slot="increment" aria-label="Increase">
<ChevronUp size="16" strokeWidth="3" />
</IconButton>
</NumberInputGroup>
</NumberField>
)
}
================================================
FILE: apps/docs/registry/number-field/with-stepper.tsx
================================================
import * as React from 'react'
import { ChevronDown, ChevronUp } from 'lucide-react'
import {
Label,
NumberDecrementStepper,
NumberField,
NumberIncrementStepper,
NumberInput,
NumberInputGroup,
NumberInputStepper,
} from 'ui'
export default function Default() {
return (
<NumberField defaultValue={50}>
<Label>Width</Label>
<NumberInputGroup className="relative">
<NumberInput />
<NumberInputStepper>
<NumberIncrementStepper>
<ChevronUp size="1em" strokeWidth="3" />
</NumberIncrementStepper>
<NumberDecrementStepper>
<ChevronDown size="1em" strokeWidth="3" />
</NumberDecrementStepper>
</NumberInputStepper>
</NumberInputGroup>
</NumberField>
)
}
================================================
FILE: apps/docs/registry/progress-bar/default.tsx
================================================
import {
Label,
ProgressBar,
ProgressBarFilledTrack,
ProgressBarTrack,
} from 'ui'
export default function Default() {
return (
<ProgressBar value={75} minValue={0} maxValue={100}>
{({ percentage }) => (
<>
<Label>Progress</Label>
<ProgressBarTrack>
<ProgressBarFilledTrack percentage={percentage} />
</ProgressBarTrack>
</>
)}
</ProgressBar>
)
}
================================================
FILE: apps/docs/registry/radio/default.tsx
================================================
import { Radio, RadioGroup } from 'ui'
export default function Default() {
return (
<RadioGroup>
<Radio value="cat">Cat</Radio>
<Radio value="dog">Dog</Radio>
</RadioGroup>
)
}
================================================
FILE: apps/docs/registry/radio/disabled.tsx
================================================
import { Radio, RadioGroup } from 'ui'
export default function Default() {
return (
<RadioGroup defaultValue="dog">
<Radio value="cat">Cat</Radio>
<Radio value="dog" isDisabled>
Dog
</Radio>
</RadioGroup>
)
}
================================================
FILE: apps/docs/registry/radio/sizes.tsx
================================================
import { Radio, RadioGroup } from 'ui'
export default function Sizes() {
return (
<div className="space-y-4">
<RadioGroup>
<Radio size="sm" value="sm-cat">
Small Cat
</Radio>
<Radio size="sm" value="sm-dog">
Small Dog
</Radio>
</RadioGroup>
<RadioGroup>
<Radio size="md" value="md-cat">
Medium Cat
</Radio>
<Radio size="md" value="md-dog">
Medium Dog
</Radio>
</RadioGroup>
<RadioGroup>
<Radio size="lg" value="lg-cat">
Large Cat
</Radio>
<Radio size="lg" value="lg-dog">
Large Dog
</Radio>
</RadioGroup>
</div>
)
}
================================================
FILE: apps/docs/registry/radio-group/default.tsx
================================================
import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui'
export default function Default() {
return (
<RadioGroup>
<Label>Favorite animal</Label>
<RadioGroupContent>
<Radio value="dog">Dog</Radio>
<Radio value="cat">Cat</Radio>
<Radio value="dragon">Dragon</Radio>
</RadioGroupContent>
</RadioGroup>
)
}
================================================
FILE: apps/docs/registry/radio-group/disabled.tsx
================================================
import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui'
export default function Disabled() {
return (
<RadioGroup isDisabled defaultValue="dragon">
<Label>Favorite animal</Label>
<RadioGroupContent>
<Radio value="dog">Dog</Radio>
<Radio value="cat">Cat</Radio>
<Radio value="dragon">Dragon</Radio>
</RadioGroupContent>
</RadioGroup>
)
}
================================================
FILE: apps/docs/registry/radio-group/horizontal.tsx
================================================
import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui'
export default function Horizontal() {
return (
<RadioGroup orientation="horizontal">
<Label>Favorite animal</Label>
<RadioGroupContent>
<Radio value="dog">Dog</Radio>
<Radio value="cat">Cat</Radio>
<Radio value="dragon">Dragon</Radio>
</RadioGroupContent>
</RadioGroup>
)
}
================================================
FILE: apps/docs/registry/range-calendar/default.tsx
================================================
import * as React from 'react'
import {
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeader,
CalendarHeaderCell,
CalendarHeading,
CalendarNextButton,
CalendarPrevButton,
RangeCalendar,
} from 'ui'
export default function Default() {
return (
<RangeCalendar aria-label="Example range calendar">
<CalendarHeader>
<CalendarPrevButton />
<CalendarHeading />
<CalendarNextButton />
</CalendarHeader>
<CalendarGrid>
<CalendarGridHeader>
{(day) => <CalendarHeaderCell>{day}</CalendarHeaderCell>}
</CalendarGridHeader>
<CalendarGridBody>
{(date) => <CalendarCell date={date} />}
</CalendarGridBody>
</CalendarGrid>
</RangeCalendar>
)
}
================================================
FILE: apps/docs/registry/search-field/default.tsx
================================================
import { Search } from 'lucide-react'
import { Label, SearchField, SearchFieldInput } from 'ui'
export default function Default() {
return (
<SearchField>
<Label>Search</Label>
<div className="relative">
<div
aria-hidden="true"
className="pointer-events-none absolute flex h-full w-10 items-center justify-center text-slate-500 dark:text-slate-400"
>
<Search size="18" />
</div>
<SearchFieldInput className="px-10" />
</div>
</SearchField>
)
}
================================================
FILE: apps/docs/registry/search-field/with-clear-button.tsx
================================================
import { Search } from 'lucide-react'
import {
Label,
SearchField,
SearchFieldClearButton,
SearchFieldInput,
} from 'ui'
export default function WithClearButton() {
return (
<SearchField>
<Label>Search</Label>
<div className="relative">
<div
aria-hidden="true"
className="pointer-events-none absolute flex h-full w-10 items-center justify-center text-slate-500 dark:text-slate-400"
>
<Search size="18" />
</div>
<SearchFieldInput className="px-10" />
<div className="absolute inset-y-0 right-0 flex items-center p-1">
<SearchFieldClearButton
variant="subtle"
size="sm"
aria-label="Clear search"
/>
</div>
</div>
</SearchField>
)
}
================================================
FILE: apps/docs/registry/select/default.tsx
================================================
import * as React from 'react'
import { ChevronDown } from 'lucide-react'
import {
Label,
Select,
SelectButton,
SelectContent,
SelectItem,
SelectValue,
} from 'ui'
export default function Default() {
return (
<>
<Select>
<Label>Favorite Animal</Label>
<SelectButton variant="outline">
<SelectValue>
{({ selectedText }) => (
<span>{selectedText || 'Select an item'}</span>
)}
</SelectValue>
<ChevronDown size="16" strokeWidth="3" />
</SelectButton>
<SelectContent>
<SelectItem textValue="Aardvark">Aardvark</SelectItem>
<SelectItem textValue="Cat">Cat</SelectItem>
<SelectItem textValue="Dog">Dog</SelectItem>
<SelectItem textValue="Kangaroo">Kangaroo</SelectItem>
<SelectItem textValue="Panda">Panda</SelectItem>
<SelectItem textValue="Snake">Snake</SelectItem>
</SelectContent>
</Select>
</>
)
}
================================================
FILE: apps/docs/registry/select/disabled.tsx
================================================
import * as React from 'react'
import { ChevronDown } from 'lucide-react'
import {
Label,
Select,
SelectButton,
SelectContent,
SelectItem,
SelectValue,
} from 'ui'
export default function Disabled() {
return (
<>
<Select isDisabled>
<Label>Favorite Animal</Label>
<SelectButton variant="outline">
<SelectValue>
{({ selectedText }) => (
<span>{selectedText || 'Select an item'}</span>
)}
</SelectValue>
<ChevronDown size="16" strokeWidth="3" />
</SelectButton>
<SelectContent>
<SelectItem textValue="Aardvark">Aardvark</SelectItem>
<SelectItem textValue="Cat">Cat</SelectItem>
<SelectItem textValue="Dog">Dog</SelectItem>
<SelectItem textValue="Kangaroo">Kangaroo</SelectItem>
<SelectItem textValue="Panda">Panda</SelectItem>
<SelectItem textValue="Snake">Snake</SelectItem>
</SelectContent>
</Select>
</>
)
}
================================================
FILE: apps/docs/registry/slider/default.tsx
================================================
import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui'
export default function Default() {
return (
<Slider defaultValue={30}>
<Label>Opacity</Label>
<SliderTrack>
{({ state }) => (
<>
<SliderFilledTrack
percentage={state.getThumbPercent(0) * 100}
orientation={state.orientation}
/>
<SliderThumb />
</>
)}
</SliderTrack>
</Slider>
)
}
================================================
FILE: apps/docs/registry/slider/vertical.tsx
================================================
import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui'
export default function Vertical() {
return (
<Slider orientation="vertical" defaultValue={30}>
<Label>Vertical Slider</Label>
<SliderTrack className="h-72">
{({ state }) => (
<>
<SliderFilledTrack
percentage={state.getThumbPercent(0) * 100}
orientation={state.orientation}
/>
<SliderThumb />
gitextract_vesfxg_a/ ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .husky/ │ └── pre-commit ├── .npmrc ├── .vscode/ │ └── settings.json ├── LICENSE.md ├── apps/ │ ├── docs/ │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── README.md │ │ ├── __registry__/ │ │ │ └── index.tsx │ │ ├── app/ │ │ │ ├── changelog/ │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ ├── docs/ │ │ │ │ └── [[...slug]]/ │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ ├── getting-started/ │ │ │ │ └── [[...slug]]/ │ │ │ │ ├── layout.tsx │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── page.tsx │ │ │ ├── provider.tsx │ │ │ ├── robots.tsx │ │ │ └── sitemap.tsx │ │ ├── components/ │ │ │ ├── analytics.tsx │ │ │ ├── copy-clipboard-button.tsx │ │ │ ├── docs/ │ │ │ │ ├── callout.tsx │ │ │ │ ├── component-example.tsx │ │ │ │ ├── component-source.tsx │ │ │ │ ├── heading.tsx │ │ │ │ ├── jump-to-content-menu.tsx │ │ │ │ ├── list-stepper.tsx │ │ │ │ └── markdown.tsx │ │ │ ├── edit-feedback.tsx │ │ │ ├── fathom-analytics.tsx │ │ │ ├── home-page/ │ │ │ │ ├── cta-section.tsx │ │ │ │ └── example-section.tsx │ │ │ ├── link-list.tsx │ │ │ ├── mode-toggle.tsx │ │ │ ├── navigation.tsx │ │ │ ├── page-toc.tsx │ │ │ ├── search-component.tsx │ │ │ └── theme-provider.tsx │ │ ├── content/ │ │ │ ├── CHANGELOG.mdx │ │ │ ├── components/ │ │ │ │ ├── breadcrumbs.mdx │ │ │ │ ├── button.mdx │ │ │ │ ├── checkbox-group.mdx │ │ │ │ ├── checkbox.mdx │ │ │ │ ├── combo-box.mdx │ │ │ │ ├── date-picker.mdx │ │ │ │ ├── date-range-picker.mdx │ │ │ │ ├── grid-list.mdx │ │ │ │ ├── icon-button.mdx │ │ │ │ ├── input.mdx │ │ │ │ ├── label.mdx │ │ │ │ ├── menu.mdx │ │ │ │ ├── meter.mdx │ │ │ │ ├── modal.mdx │ │ │ │ ├── number-field.mdx │ │ │ │ ├── progress-bar.mdx │ │ │ │ ├── radio-group.mdx │ │ │ │ ├── radio.mdx │ │ │ │ ├── search-field.mdx │ │ │ │ ├── select.mdx │ │ │ │ ├── slider.mdx │ │ │ │ ├── switch.mdx │ │ │ │ ├── table.mdx │ │ │ │ ├── tabs.mdx │ │ │ │ ├── text-field.mdx │ │ │ │ ├── toggle-button.mdx │ │ │ │ └── tooltip.mdx │ │ │ └── getting-started/ │ │ │ ├── about.mdx │ │ │ ├── cli.mdx │ │ │ ├── installation.mdx │ │ │ └── introduction.mdx │ │ ├── contentlayer.config.ts │ │ ├── lib/ │ │ │ ├── cva.config.ts │ │ │ ├── rehype-component.ts │ │ │ └── remark/ │ │ │ └── with-table-of-contents.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── public/ │ │ │ └── site.webmanifest │ │ ├── registry/ │ │ │ ├── breadcrumbs/ │ │ │ │ └── default.tsx │ │ │ ├── button/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ ├── sizes.tsx │ │ │ │ └── theme.tsx │ │ │ ├── calendar/ │ │ │ │ └── default.tsx │ │ │ ├── checkbox/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── checkbox-group/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── horizontal.tsx │ │ │ ├── combobox/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled-keys.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── with-button.tsx │ │ │ ├── date-field/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── date-input/ │ │ │ │ ├── default.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── date-picker/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── date-range-picker/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── grid-list/ │ │ │ │ └── default.tsx │ │ │ ├── icon-button/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ ├── sizes.tsx │ │ │ │ └── theme.tsx │ │ │ ├── input/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── label/ │ │ │ │ └── default.tsx │ │ │ ├── menu/ │ │ │ │ ├── as-checkbox.tsx │ │ │ │ ├── as-radio.tsx │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── with-sections.tsx │ │ │ ├── meter/ │ │ │ │ └── default.tsx │ │ │ ├── modal/ │ │ │ │ ├── default.tsx │ │ │ │ ├── dismissable-false.tsx │ │ │ │ ├── set-autofocus.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── number-field/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ ├── with-mobile-stepper.tsx │ │ │ │ └── with-stepper.tsx │ │ │ ├── progress-bar/ │ │ │ │ └── default.tsx │ │ │ ├── radio/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── radio-group/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── horizontal.tsx │ │ │ ├── range-calendar/ │ │ │ │ └── default.tsx │ │ │ ├── search-field/ │ │ │ │ ├── default.tsx │ │ │ │ └── with-clear-button.tsx │ │ │ ├── select/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── slider/ │ │ │ │ ├── default.tsx │ │ │ │ └── vertical.tsx │ │ │ ├── switch/ │ │ │ │ ├── alignment.tsx │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── tabs/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled-keys.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── vertical.tsx │ │ │ ├── text-field/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── with-error.tsx │ │ │ └── tooltip/ │ │ │ ├── default.tsx │ │ │ └── placement.tsx │ │ ├── styles/ │ │ │ └── globals.css │ │ ├── tailwind.config.js │ │ ├── tsconfig.json │ │ └── types.ts │ └── storybook/ │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .gitignore │ ├── .storybook/ │ │ ├── main.ts │ │ └── preview.ts │ ├── package.json │ ├── postcss.config.cjs │ ├── src/ │ │ ├── components/ │ │ │ ├── breadcrumbs/ │ │ │ │ ├── breadcrumbs.stories.tsx │ │ │ │ └── stories/ │ │ │ │ └── default.tsx │ │ │ ├── button/ │ │ │ │ ├── button.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ ├── sizes.tsx │ │ │ │ └── theme.tsx │ │ │ ├── calendar/ │ │ │ │ ├── calendar.stories.tsx │ │ │ │ └── stories/ │ │ │ │ └── default.tsx │ │ │ ├── checkbox/ │ │ │ │ ├── checkbox.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── checkbox-group/ │ │ │ │ ├── checkbox-group.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── horizontal.tsx │ │ │ ├── combobox/ │ │ │ │ ├── combo-box.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled-keys.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── with-button.tsx │ │ │ ├── date-field/ │ │ │ │ ├── date-field.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── date-input/ │ │ │ │ ├── date-input.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── date-picker/ │ │ │ │ ├── date-picker.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── date-range-picker/ │ │ │ │ ├── date-range-picker.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── grid-list/ │ │ │ │ ├── grid-list.stories.tsx │ │ │ │ └── stories/ │ │ │ │ └── default.tsx │ │ │ ├── icon-button/ │ │ │ │ ├── icon-button.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ ├── sizes.tsx │ │ │ │ └── theme.tsx │ │ │ ├── input/ │ │ │ │ ├── input.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── label/ │ │ │ │ ├── label.stories.tsx │ │ │ │ └── stories/ │ │ │ │ └── default.tsx │ │ │ ├── menu/ │ │ │ │ ├── menu.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── as-checkbox.tsx │ │ │ │ ├── as-radio.tsx │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── with-sections.tsx │ │ │ ├── meter/ │ │ │ │ ├── meter.stories.tsx │ │ │ │ └── stories/ │ │ │ │ └── default.tsx │ │ │ ├── modal/ │ │ │ │ ├── modal.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── dismissable-false.tsx │ │ │ │ ├── set-autofocus.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── number-field/ │ │ │ │ ├── number-field.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ ├── with-mobile-stepper.tsx │ │ │ │ └── with-stepper.tsx │ │ │ ├── progress-bar/ │ │ │ │ ├── progress-bar.stories.tsx │ │ │ │ └── stories/ │ │ │ │ └── default.tsx │ │ │ ├── radio/ │ │ │ │ ├── radio.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── sizes.tsx │ │ │ ├── radio-group/ │ │ │ │ ├── radio-group.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ ├── disabled.tsx │ │ │ │ └── horizontal.tsx │ │ │ ├── range-calendar/ │ │ │ │ ├── range-calendar.stories.tsx │ │ │ │ └── stories/ │ │ │ │ └── default.tsx │ │ │ ├── search-field/ │ │ │ │ ├── search-field.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── with-clear-button.tsx │ │ │ ├── select/ │ │ │ │ ├── select.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── disabled.tsx │ │ │ ├── slider/ │ │ │ │ ├── slider.stories.tsx │ │ │ │ └── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── vertical.tsx │ │ │ ├── switch/ │ │ │ │ ├── stories/ │ │ │ │ │ ├── alignment.tsx │ │ │ │ │ ├── default.tsx │ │ │ │ │ ├── disabled.tsx │ │ │ │ │ └── sizes.tsx │ │ │ │ └── switch.stories.tsx │ │ │ ├── tabs/ │ │ │ │ ├── stories/ │ │ │ │ │ ├── default.tsx │ │ │ │ │ ├── disabled-keys.tsx │ │ │ │ │ ├── disabled.tsx │ │ │ │ │ └── vertical.tsx │ │ │ │ └── tabs.stories.tsx │ │ │ ├── text-field/ │ │ │ │ ├── stories/ │ │ │ │ │ ├── default.tsx │ │ │ │ │ ├── disabled.tsx │ │ │ │ │ └── with-error.tsx │ │ │ │ └── text-field.stories.tsx │ │ │ └── tooltip/ │ │ │ ├── stories/ │ │ │ │ ├── default.tsx │ │ │ │ └── placement.tsx │ │ │ └── tooltip.stories.tsx │ │ └── styles.css │ ├── tailwind.config.cjs │ └── tsconfig.json ├── package.json ├── packages/ │ ├── eslint-config-custom/ │ │ ├── index.js │ │ └── package.json │ ├── postcss-config/ │ │ ├── package.json │ │ └── postcss.config.cjs │ ├── tailwind-config/ │ │ ├── package.json │ │ └── tailwind.config.cjs │ ├── ts-config/ │ │ ├── base.json │ │ ├── nextjs.json │ │ ├── package.json │ │ └── react-library.json │ └── ui/ │ ├── .eslintrc.js │ ├── .gitignore │ ├── lib/ │ │ └── cva.config.ts │ ├── package.json │ ├── postcss.config.cjs │ ├── src/ │ │ ├── breadcrumbs.tsx │ │ ├── button.tsx │ │ ├── calendar.tsx │ │ ├── checkbox-group.tsx │ │ ├── checkbox.tsx │ │ ├── combobox.tsx │ │ ├── date-input.tsx │ │ ├── date-picker.tsx │ │ ├── date-range-picker.tsx │ │ ├── grid-list.tsx │ │ ├── icon-button.tsx │ │ ├── index.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── menu.tsx │ │ ├── meter.tsx │ │ ├── modal.tsx │ │ ├── number-field.tsx │ │ ├── progress-bar.tsx │ │ ├── radio-group.tsx │ │ ├── radio.tsx │ │ ├── search-field.tsx │ │ ├── select.tsx │ │ ├── slider.tsx │ │ ├── styles.css │ │ ├── switch.tsx │ │ ├── table.tsx │ │ ├── tabs.tsx │ │ ├── text-field.tsx │ │ ├── toggle-button.tsx │ │ └── tooltip.tsx │ ├── tailwind.config.cjs │ └── tsconfig.json ├── pnpm-workspace.yaml ├── prettier.config.cjs ├── scripts/ │ ├── package.json │ ├── src/ │ │ └── build-registry.ts │ └── tsconfig.json ├── tsconfig.json ├── turbo.json └── vercel.json
SYMBOL INDEX (235 symbols across 204 files)
FILE: apps/docs/__registry__/index.tsx
type ComponentRegistry (line 7) | type ComponentRegistry = Record<
FILE: apps/docs/app/changelog/layout.tsx
function DocsLayout (line 30) | async function DocsLayout({
FILE: apps/docs/app/changelog/page.tsx
function generateStaticParams (line 10) | function generateStaticParams() {
function generateMetadata (line 14) | async function generateMetadata(
function ChangelogPage (line 49) | function ChangelogPage() {
FILE: apps/docs/app/docs/[[...slug]]/layout.tsx
function DocsLayout (line 30) | function DocsLayout({
FILE: apps/docs/app/docs/[[...slug]]/page.tsx
function generateStaticParams (line 9) | function generateStaticParams() {
function generateMetadata (line 17) | async function generateMetadata(
function DocPage (line 56) | function DocPage({
FILE: apps/docs/app/getting-started/[[...slug]]/layout.tsx
function DocsLayout (line 30) | function DocsLayout({
FILE: apps/docs/app/getting-started/[[...slug]]/page.tsx
function generateStaticParams (line 11) | function generateStaticParams() {
function generateMetadata (line 19) | async function generateMetadata(
function GettingStartedPage (line 59) | function GettingStartedPage({
FILE: apps/docs/app/layout.tsx
type DocsLayoutProps (line 11) | interface DocsLayoutProps {
function generateMetadata (line 20) | function generateMetadata(): Metadata {
function DocsLayout (line 71) | function DocsLayout({ children }: DocsLayoutProps) {
FILE: apps/docs/app/page.tsx
function Home (line 11) | async function Home() {
FILE: apps/docs/app/provider.tsx
function ClientProviders (line 6) | function ClientProviders({ children }) {
FILE: apps/docs/app/robots.tsx
function robots (line 3) | function robots(): MetadataRoute.Robots {
FILE: apps/docs/app/sitemap.tsx
function sitemap (line 4) | function sitemap(): MetadataRoute.Sitemap {
FILE: apps/docs/components/analytics.tsx
function Analytics (line 7) | function Analytics() {
FILE: apps/docs/components/copy-clipboard-button.tsx
function CopyClipboardButton (line 8) | function CopyClipboardButton({ text }: { text: string }) {
FILE: apps/docs/components/docs/callout.tsx
function Callout (line 6) | function Callout({
FILE: apps/docs/components/docs/component-example.tsx
type ComponentExampleProps (line 12) | interface ComponentExampleProps extends React.HTMLAttributes<HTMLDivElem...
function ComponentExample (line 18) | function ComponentExample({
FILE: apps/docs/components/docs/component-source.tsx
function ComponentSource (line 7) | function ComponentSource({ children }) {
FILE: apps/docs/components/docs/heading.tsx
type HeadingProps (line 7) | interface HeadingProps extends TocItemProps {
function Heading (line 11) | function Heading({ slug, lvl, children }: HeadingProps) {
FILE: apps/docs/components/docs/jump-to-content-menu.tsx
function JumpToContentMenu (line 16) | function JumpToContentMenu({
FILE: apps/docs/components/docs/list-stepper.tsx
function ListStepper (line 3) | function ListStepper({ children }: { children: React.ReactNode }) {
function ListStep (line 11) | function ListStep({ children }: { children: React.ReactNode }) {
FILE: apps/docs/components/docs/markdown.tsx
type MarkdownProps (line 20) | type MarkdownProps = {
function Markdown (line 24) | function Markdown(props: MarkdownProps) {
FILE: apps/docs/components/edit-feedback.tsx
function EditFeedbackLinks (line 1) | function EditFeedbackLinks({
FILE: apps/docs/components/fathom-analytics.tsx
function TrackPageView (line 9) | function TrackPageView() {
function Fathom (line 27) | function Fathom() {
FILE: apps/docs/components/home-page/cta-section.tsx
function CtaSection (line 9) | function CtaSection() {
FILE: apps/docs/components/home-page/example-section.tsx
function ExampleSection (line 16) | function ExampleSection() {
FILE: apps/docs/components/link-list.tsx
type LinkListItemProps (line 8) | type LinkListItemProps = {
function LinkList (line 16) | function LinkList({ list }: { list: LinkListItemProps[] }) {
FILE: apps/docs/components/mode-toggle.tsx
function ModeToggle (line 10) | function ModeToggle() {
FILE: apps/docs/components/navigation.tsx
type LinkListItemProps (line 24) | type LinkListItemProps = {
function Navigation (line 32) | function Navigation({
FILE: apps/docs/components/page-toc.tsx
function PageToc (line 8) | function PageToc({
function useActiveHeading (line 44) | function useActiveHeading(itemIds: string[]) {
FILE: apps/docs/components/search-component.tsx
function SearchComponent (line 16) | function SearchComponent() {
FILE: apps/docs/components/theme-provider.tsx
function ThemeProvider (line 8) | function ThemeProvider({
FILE: apps/docs/contentlayer.config.ts
method onVisitLine (line 144) | onVisitLine(node) {
method onVisitHighlightedLine (line 151) | onVisitHighlightedLine(node) {
method onVisitHighlightedWord (line 154) | onVisitHighlightedWord(node) {
FILE: apps/docs/lib/rehype-component.ts
function rehypeComponent (line 11) | function rehypeComponent() {
function getNodeAttributeByName (line 101) | function getNodeAttributeByName(node: UnistNode, name: string) {
FILE: apps/docs/lib/remark/with-table-of-contents.ts
function withTableOfContents (line 5) | function withTableOfContents() {
FILE: apps/docs/next.config.js
method redirects (line 11) | redirects() {
FILE: apps/docs/registry/breadcrumbs/default.tsx
function Default (line 4) | function Default() {
FILE: apps/docs/registry/button/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/button/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/docs/registry/button/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/docs/registry/button/theme.tsx
function Theme (line 3) | function Theme() {
FILE: apps/docs/registry/calendar/default.tsx
function Default (line 14) | function Default() {
FILE: apps/docs/registry/checkbox-group/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/checkbox-group/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/checkbox-group/horizontal.tsx
function Horizontal (line 3) | function Horizontal() {
FILE: apps/docs/registry/checkbox/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/checkbox/disabled.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/docs/registry/checkbox/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/docs/registry/combobox/default.tsx
function Default (line 9) | function Default() {
FILE: apps/docs/registry/combobox/disabled-keys.tsx
function DisabledKeys (line 12) | function DisabledKeys() {
FILE: apps/docs/registry/combobox/disabled.tsx
function Disabled (line 12) | function Disabled() {
FILE: apps/docs/registry/combobox/with-button.tsx
function WithButton (line 12) | function WithButton() {
FILE: apps/docs/registry/date-field/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/date-field/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/docs/registry/date-input/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/date-input/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/docs/registry/date-picker/default.tsx
function Default (line 23) | function Default() {
FILE: apps/docs/registry/date-picker/disabled.tsx
function Default (line 23) | function Default() {
FILE: apps/docs/registry/date-range-picker/default.tsx
function Default (line 23) | function Default() {
FILE: apps/docs/registry/date-range-picker/disabled.tsx
function Default (line 23) | function Default() {
FILE: apps/docs/registry/grid-list/default.tsx
function Default (line 4) | function Default() {
FILE: apps/docs/registry/icon-button/default.tsx
function Default (line 4) | function Default() {
FILE: apps/docs/registry/icon-button/disabled.tsx
function Disabled (line 4) | function Disabled() {
FILE: apps/docs/registry/icon-button/sizes.tsx
function Sizes (line 4) | function Sizes() {
FILE: apps/docs/registry/icon-button/theme.tsx
function Theme (line 4) | function Theme() {
FILE: apps/docs/registry/input/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/input/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/docs/registry/input/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/docs/registry/label/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/menu/as-checkbox.tsx
function AsCheckbox (line 7) | function AsCheckbox() {
FILE: apps/docs/registry/menu/as-radio.tsx
function AsRadio (line 7) | function AsRadio() {
FILE: apps/docs/registry/menu/default.tsx
function Default (line 4) | function Default() {
FILE: apps/docs/registry/menu/disabled.tsx
function Disabled (line 4) | function Disabled() {
FILE: apps/docs/registry/menu/with-sections.tsx
function WithSections (line 12) | function WithSections() {
FILE: apps/docs/registry/meter/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/modal/default.tsx
function Default (line 14) | function Default() {
FILE: apps/docs/registry/modal/dismissable-false.tsx
function DismissableFalse (line 14) | function DismissableFalse() {
FILE: apps/docs/registry/modal/set-autofocus.tsx
function SetAutofocus (line 17) | function SetAutofocus() {
FILE: apps/docs/registry/modal/sizes.tsx
type Size (line 15) | type Size = Pick<ModalContentProps, 'size'>['size']
function Default (line 16) | function Default() {
FILE: apps/docs/registry/number-field/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/number-field/disabled.tsx
function Default (line 14) | function Default() {
FILE: apps/docs/registry/number-field/with-mobile-stepper.tsx
function Mobile (line 4) | function Mobile() {
FILE: apps/docs/registry/number-field/with-stepper.tsx
function Default (line 14) | function Default() {
FILE: apps/docs/registry/progress-bar/default.tsx
function Default (line 8) | function Default() {
FILE: apps/docs/registry/radio-group/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/radio-group/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/docs/registry/radio-group/horizontal.tsx
function Horizontal (line 3) | function Horizontal() {
FILE: apps/docs/registry/radio/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/radio/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/radio/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/docs/registry/range-calendar/default.tsx
function Default (line 16) | function Default() {
FILE: apps/docs/registry/search-field/default.tsx
function Default (line 4) | function Default() {
FILE: apps/docs/registry/search-field/with-clear-button.tsx
function WithClearButton (line 9) | function WithClearButton() {
FILE: apps/docs/registry/select/default.tsx
function Default (line 13) | function Default() {
FILE: apps/docs/registry/select/disabled.tsx
function Disabled (line 13) | function Disabled() {
FILE: apps/docs/registry/slider/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/slider/vertical.tsx
function Vertical (line 3) | function Vertical() {
FILE: apps/docs/registry/switch/alignment.tsx
function Alignment (line 3) | function Alignment() {
FILE: apps/docs/registry/switch/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/switch/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/switch/sizes.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/tabs/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/tabs/disabled-keys.tsx
function DisabledKeys (line 3) | function DisabledKeys() {
FILE: apps/docs/registry/tabs/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/docs/registry/tabs/vertical.tsx
function Vertical (line 3) | function Vertical() {
FILE: apps/docs/registry/text-field/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/text-field/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/text-field/with-error.tsx
function withError (line 3) | function withError() {
FILE: apps/docs/registry/tooltip/default.tsx
function Default (line 3) | function Default() {
FILE: apps/docs/registry/tooltip/placement.tsx
type Placement (line 4) | type Placement = Pick<TooltipProps, 'placement'>['placement']
function Placement (line 5) | function Placement() {
FILE: apps/docs/types.ts
type UnistNode (line 3) | interface UnistNode extends Node {
type UnistTree (line 22) | interface UnistTree extends Node {
type NpmCommands (line 26) | interface NpmCommands {
type ExamplesListItem (line 33) | interface ExamplesListItem {
type TocItemProps (line 40) | interface TocItemProps {
FILE: apps/storybook/.storybook/main.ts
method viteFinal (line 23) | viteFinal(config, { configType }) {
function getAbsolutePath (line 31) | function getAbsolutePath(value: string): any {
FILE: apps/storybook/src/components/breadcrumbs/stories/default.tsx
function Default (line 4) | function Default() {
FILE: apps/storybook/src/components/button/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/button/stories/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/storybook/src/components/button/stories/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/storybook/src/components/button/stories/theme.tsx
function Theme (line 3) | function Theme() {
FILE: apps/storybook/src/components/calendar/stories/default.tsx
function Default (line 14) | function Default() {
FILE: apps/storybook/src/components/checkbox-group/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/checkbox-group/stories/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/checkbox-group/stories/horizontal.tsx
function Horizontal (line 3) | function Horizontal() {
FILE: apps/storybook/src/components/checkbox/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/checkbox/stories/disabled.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/storybook/src/components/checkbox/stories/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/storybook/src/components/combobox/stories/default.tsx
function Default (line 9) | function Default() {
FILE: apps/storybook/src/components/combobox/stories/disabled-keys.tsx
function DisabledKeys (line 12) | function DisabledKeys() {
FILE: apps/storybook/src/components/combobox/stories/disabled.tsx
function Disabled (line 12) | function Disabled() {
FILE: apps/storybook/src/components/combobox/stories/with-button.tsx
function WithButton (line 12) | function WithButton() {
FILE: apps/storybook/src/components/date-field/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/date-field/stories/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/storybook/src/components/date-input/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/date-input/stories/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/storybook/src/components/date-picker/stories/default.tsx
function Default (line 23) | function Default() {
FILE: apps/storybook/src/components/date-picker/stories/disabled.tsx
function Default (line 23) | function Default() {
FILE: apps/storybook/src/components/date-range-picker/stories/default.tsx
function Default (line 23) | function Default() {
FILE: apps/storybook/src/components/date-range-picker/stories/disabled.tsx
function Default (line 23) | function Default() {
FILE: apps/storybook/src/components/grid-list/stories/default.tsx
function Default (line 4) | function Default() {
FILE: apps/storybook/src/components/icon-button/stories/default.tsx
function Default (line 4) | function Default() {
FILE: apps/storybook/src/components/icon-button/stories/disabled.tsx
function Disabled (line 4) | function Disabled() {
FILE: apps/storybook/src/components/icon-button/stories/sizes.tsx
function Sizes (line 4) | function Sizes() {
FILE: apps/storybook/src/components/icon-button/stories/theme.tsx
function Theme (line 4) | function Theme() {
FILE: apps/storybook/src/components/input/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/input/stories/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/storybook/src/components/input/stories/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/storybook/src/components/label/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/menu/stories/as-checkbox.tsx
function AsCheckbox (line 7) | function AsCheckbox() {
FILE: apps/storybook/src/components/menu/stories/as-radio.tsx
function AsRadio (line 7) | function AsRadio() {
FILE: apps/storybook/src/components/menu/stories/default.tsx
function Default (line 4) | function Default() {
FILE: apps/storybook/src/components/menu/stories/disabled.tsx
function Disabled (line 4) | function Disabled() {
FILE: apps/storybook/src/components/menu/stories/with-sections.tsx
function WithSections (line 12) | function WithSections() {
FILE: apps/storybook/src/components/meter/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/modal/stories/default.tsx
function Default (line 14) | function Default() {
FILE: apps/storybook/src/components/modal/stories/dismissable-false.tsx
function DismissableFalse (line 14) | function DismissableFalse() {
FILE: apps/storybook/src/components/modal/stories/set-autofocus.tsx
function SetAutofocus (line 17) | function SetAutofocus() {
FILE: apps/storybook/src/components/modal/stories/sizes.tsx
type Size (line 15) | type Size = Pick<ModalContentProps, 'size'>['size']
function Default (line 16) | function Default() {
FILE: apps/storybook/src/components/number-field/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/number-field/stories/disabled.tsx
function Default (line 14) | function Default() {
FILE: apps/storybook/src/components/number-field/stories/with-mobile-stepper.tsx
function Mobile (line 4) | function Mobile() {
FILE: apps/storybook/src/components/number-field/stories/with-stepper.tsx
function Default (line 14) | function Default() {
FILE: apps/storybook/src/components/progress-bar/stories/default.tsx
function Default (line 8) | function Default() {
FILE: apps/storybook/src/components/radio-group/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/radio-group/stories/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/storybook/src/components/radio-group/stories/horizontal.tsx
function Horizontal (line 3) | function Horizontal() {
FILE: apps/storybook/src/components/radio/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/radio/stories/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/radio/stories/sizes.tsx
function Sizes (line 3) | function Sizes() {
FILE: apps/storybook/src/components/range-calendar/stories/default.tsx
function Default (line 16) | function Default() {
FILE: apps/storybook/src/components/search-field/stories/default.tsx
function Default (line 4) | function Default() {
FILE: apps/storybook/src/components/search-field/stories/with-clear-button.tsx
function WithClearButton (line 9) | function WithClearButton() {
FILE: apps/storybook/src/components/select/stories/default.tsx
function Default (line 13) | function Default() {
FILE: apps/storybook/src/components/select/stories/disabled.tsx
function Disabled (line 13) | function Disabled() {
FILE: apps/storybook/src/components/slider/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/slider/stories/vertical.tsx
function Vertical (line 3) | function Vertical() {
FILE: apps/storybook/src/components/switch/stories/alignment.tsx
function Alignment (line 3) | function Alignment() {
FILE: apps/storybook/src/components/switch/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/switch/stories/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/switch/stories/sizes.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/tabs/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/tabs/stories/disabled-keys.tsx
function DisabledKeys (line 3) | function DisabledKeys() {
FILE: apps/storybook/src/components/tabs/stories/disabled.tsx
function Disabled (line 3) | function Disabled() {
FILE: apps/storybook/src/components/tabs/stories/vertical.tsx
function Vertical (line 3) | function Vertical() {
FILE: apps/storybook/src/components/text-field/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/text-field/stories/disabled.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/text-field/stories/with-error.tsx
function withError (line 3) | function withError() {
FILE: apps/storybook/src/components/tooltip/stories/default.tsx
function Default (line 3) | function Default() {
FILE: apps/storybook/src/components/tooltip/stories/placement.tsx
type Placement (line 4) | type Placement = Pick<TooltipProps, 'placement'>['placement']
function Placement (line 5) | function Placement() {
FILE: packages/ui/src/breadcrumbs.tsx
type BreadcrumbItemProps (line 19) | interface BreadcrumbItemProps extends ReactAria.BreadcrumbProps {
FILE: packages/ui/src/button.tsx
type ButtonProps (line 41) | interface ButtonProps
FILE: packages/ui/src/checkbox-group.tsx
type CheckboxGroupProps (line 7) | interface CheckboxGroupProps extends ReactAria.CheckboxGroupProps {
FILE: packages/ui/src/checkbox.tsx
type CheckboxProps (line 54) | interface CheckboxProps
FILE: packages/ui/src/combobox.tsx
type ComboBoxContentProps (line 21) | interface ComboBoxContentProps<T>
type ListBoxItemProps (line 45) | interface ListBoxItemProps extends ReactAria.ListBoxItemProps {
FILE: packages/ui/src/date-input.tsx
type DateInputGroupProps (line 32) | interface DateInputGroupProps
FILE: packages/ui/src/date-picker.tsx
type DatePickerContentProps (line 12) | interface DatePickerContentProps
FILE: packages/ui/src/date-range-picker.tsx
type DateRangePickerContentProps (line 14) | interface DateRangePickerContentProps
FILE: packages/ui/src/icon-button.tsx
type IconButtonProps (line 90) | interface IconButtonProps
FILE: packages/ui/src/input.tsx
type InputProps (line 31) | interface InputProps
FILE: packages/ui/src/menu.tsx
type MenuContentProps (line 11) | interface MenuContentProps<T>
FILE: packages/ui/src/meter.tsx
type MeterFilledTrackProps (line 29) | interface MeterFilledTrackProps
FILE: packages/ui/src/modal.tsx
type ModalContentProps (line 35) | interface ModalContentProps
FILE: packages/ui/src/progress-bar.tsx
type ProgressBarFilledTrackProps (line 34) | interface ProgressBarFilledTrackProps
FILE: packages/ui/src/radio.tsx
type RadioProps (line 54) | interface RadioProps
FILE: packages/ui/src/select.tsx
type SelectContentProps (line 14) | interface SelectContentProps<T>
FILE: packages/ui/src/slider.tsx
type SliderFilledTrackProps (line 42) | interface SliderFilledTrackProps
FILE: packages/ui/src/switch.tsx
type SwitchProps (line 44) | interface SwitchProps
type SwitchIndicatorProps (line 67) | interface SwitchIndicatorProps
FILE: scripts/src/build-registry.ts
type ComponentRegistry (line 19) | type ComponentRegistry = Record<
function generateNested (line 32) | function generateNested(registry: ComponentRegistry): string {
Condensed preview — 329 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (360K chars).
[
{
"path": ".editorconfig",
"chars": 208,
"preview": "# editorconfig.org\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_"
},
{
"path": ".eslintrc.js",
"chars": 129,
"preview": "module.exports = {\n root: true,\n extends: ['custom'],\n settings: {\n next: {\n rootDir: ['apps/docs/*/'],\n }"
},
{
"path": ".gitignore",
"chars": 453,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n.pnp\n"
},
{
"path": ".husky/pre-commit",
"chars": 69,
"preview": "#!/usr/bin/env sh\n. \"$(dirname -- \"$0\")/_/husky.sh\"\n\nnpx lint-staged\n"
},
{
"path": ".npmrc",
"chars": 65,
"preview": "auto-install-peers=true\nlegacy-peer-deps=true\nnode-linker=hoisted"
},
{
"path": ".vscode/settings.json",
"chars": 835,
"preview": "{\n \"prettier.enable\": false,\n \"editor.formatOnSave\": false,\n \"editor.codeActionsOnSave\": {\n \"source.fixAll.eslint\""
},
{
"path": "LICENSE.md",
"chars": 1075,
"preview": "MIT License\n\nCopyright (c) 2024 Jonathan Hutchison\n\nPermission is hereby granted, free of charge, to any person obtainin"
},
{
"path": "apps/docs/.eslintrc.js",
"chars": 480,
"preview": "// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst path = require('path')\n\nmodule.exports = {\n root: "
},
{
"path": "apps/docs/.gitignore",
"chars": 42,
"preview": ".vscode\n.env\n\n# contentlayer\n.contentlayer"
},
{
"path": "apps/docs/README.md",
"chars": 1748,
"preview": "This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js"
},
{
"path": "apps/docs/__registry__/index.tsx",
"chars": 16133,
"preview": "/* eslint-disable prettier/prettier */\n// @ts-nocheck\n// This file is autogenerated by scripts/build-registry.ts\n// Do n"
},
{
"path": "apps/docs/app/changelog/layout.tsx",
"chars": 2265,
"preview": "import {\n allChangelogDocuments,\n allComponentDocuments,\n allGeneralDocuments,\n} from 'contentlayer/generated'\nimport"
},
{
"path": "apps/docs/app/changelog/page.tsx",
"chars": 2064,
"preview": "import * as React from 'react'\n\nimport { allChangelogDocuments } from 'contentlayer/generated'\nimport { type Metadata, t"
},
{
"path": "apps/docs/app/docs/[[...slug]]/layout.tsx",
"chars": 2384,
"preview": "import {\n allChangelogDocuments,\n allComponentDocuments,\n allGeneralDocuments,\n} from 'contentlayer/generated'\nimport"
},
{
"path": "apps/docs/app/docs/[[...slug]]/page.tsx",
"chars": 2703,
"preview": "import { allComponentDocuments } from 'contentlayer/generated'\nimport { type Metadata, type ResolvingMetadata } from 'ne"
},
{
"path": "apps/docs/app/getting-started/[[...slug]]/layout.tsx",
"chars": 2433,
"preview": "import {\n allChangelogDocuments,\n allComponentDocuments,\n allGeneralDocuments,\n} from 'contentlayer/generated'\nimport"
},
{
"path": "apps/docs/app/getting-started/[[...slug]]/page.tsx",
"chars": 2727,
"preview": "import * as React from 'react'\n\nimport { allGeneralDocuments } from 'contentlayer/generated'\nimport { type Metadata, typ"
},
{
"path": "apps/docs/app/layout.tsx",
"chars": 2718,
"preview": "import '@/styles/globals.css'\n\nimport { type Metadata } from 'next'\nimport { Inter } from 'next/font/google'\n\nimport Ana"
},
{
"path": "apps/docs/app/page.tsx",
"chars": 3849,
"preview": "import {\n allChangelogDocuments,\n allComponentDocuments,\n allGeneralDocuments,\n} from 'contentlayer/generated'\n\nimpor"
},
{
"path": "apps/docs/app/provider.tsx",
"chars": 270,
"preview": "'use client'\n\nimport { useRouter } from 'next/navigation'\nimport { RouterProvider } from 'react-aria-components'\n\nexport"
},
{
"path": "apps/docs/app/robots.tsx",
"chars": 255,
"preview": "import { type MetadataRoute } from 'next'\n\nexport default function robots(): MetadataRoute.Robots {\n return {\n rules"
},
{
"path": "apps/docs/app/sitemap.tsx",
"chars": 350,
"preview": "import { allDocuments } from 'contentlayer/generated'\nimport { type MetadataRoute } from 'next'\n\nexport default function"
},
{
"path": "apps/docs/components/analytics.tsx",
"chars": 240,
"preview": "'use client'\n\nimport { Analytics as VercelAnalytics } from '@vercel/analytics/react'\n\nimport Fathom from './fathom-analy"
},
{
"path": "apps/docs/components/copy-clipboard-button.tsx",
"chars": 768,
"preview": "'use client'\n\nimport { useState } from 'react'\n\nimport { Copy } from 'lucide-react'\nimport { IconButton, Tooltip, Toolti"
},
{
"path": "apps/docs/components/docs/callout.tsx",
"chars": 1707,
"preview": "import * as React from 'react'\n\nimport { AlertTriangle, Info, MessageSquare } from 'lucide-react'\nimport { match } from "
},
{
"path": "apps/docs/components/docs/component-example.tsx",
"chars": 2526,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport { Tab, TabList, TabPanel, Tabs } from 'ui'\n\nimport { Index } from '"
},
{
"path": "apps/docs/components/docs/component-source.tsx",
"chars": 845,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport CopyClipboardButton from '../copy-clipboard-button'\n\nexport default"
},
{
"path": "apps/docs/components/docs/heading.tsx",
"chars": 657,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport { type TocItemProps } from '@/types'\n\ninterface HeadingProps extend"
},
{
"path": "apps/docs/components/docs/jump-to-content-menu.tsx",
"chars": 1600,
"preview": "'use client'\n\nimport { ChevronDown } from 'lucide-react'\nimport { Button } from 'ui/src/button'\nimport {\n Menu,\n MenuC"
},
{
"path": "apps/docs/components/docs/list-stepper.tsx",
"chars": 833,
"preview": "import * as React from 'react'\n\nexport function ListStepper({ children }: { children: React.ReactNode }) {\n return (\n "
},
{
"path": "apps/docs/components/docs/markdown.tsx",
"chars": 2188,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport { type DocumentTypes } from 'contentlayer/generated'\nimport { useMD"
},
{
"path": "apps/docs/components/edit-feedback.tsx",
"chars": 1218,
"preview": "export default function EditFeedbackLinks({\n title,\n contentPath,\n}: {\n title: string\n contentPath: string\n}) {\n co"
},
{
"path": "apps/docs/components/fathom-analytics.tsx",
"chars": 664,
"preview": "// Fathom.tsx\n'use client'\n\nimport { Suspense, useEffect } from 'react'\n\nimport { load, trackPageview } from 'fathom-cli"
},
{
"path": "apps/docs/components/home-page/cta-section.tsx",
"chars": 604,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport Link from 'next/link'\n\nimport { buttonVariants } from '@/components"
},
{
"path": "apps/docs/components/home-page/example-section.tsx",
"chars": 2662,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport BreadcrumbsDefault from '@/registry/breadcrumbs/default'\nimport Che"
},
{
"path": "apps/docs/components/link-list.tsx",
"chars": 2264,
"preview": "'use client'\n\nimport Link from 'next/link'\nimport { usePathname } from 'next/navigation'\n\nimport { cx } from '@/lib/cva."
},
{
"path": "apps/docs/components/mode-toggle.tsx",
"chars": 1251,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport { LaptopIcon, MoonIcon, SunIcon } from 'lucide-react'\nimport { useT"
},
{
"path": "apps/docs/components/navigation.tsx",
"chars": 6960,
"preview": "'use client'\n\nimport { useEffect, useState } from 'react'\n\nimport { GithubIcon, MenuIcon, TwitterIcon, XIcon } from 'luc"
},
{
"path": "apps/docs/components/page-toc.tsx",
"chars": 2097,
"preview": "'use client'\n\nimport { useEffect, useState } from 'react'\n\nimport { cx } from '@/lib/cva.config'\nimport { type TocItemPr"
},
{
"path": "apps/docs/components/search-component.tsx",
"chars": 2936,
"preview": "'use client'\n\nimport { useState } from 'react'\n\nimport { Search } from 'lucide-react'\nimport Link from 'next/link'\n\nimpo"
},
{
"path": "apps/docs/components/theme-provider.tsx",
"chars": 340,
"preview": "'use client'\n\nimport * as React from 'react'\n\nimport { ThemeProvider as NextThemesProvider } from 'next-themes'\nimport {"
},
{
"path": "apps/docs/content/CHANGELOG.mdx",
"chars": 4272,
"preview": "---\ntitle: Changelog\ndescription: Stay up to date on the latest changes and updates\norder: 5\n---\n\n## January 2024\n\n- We "
},
{
"path": "apps/docs/content/components/breadcrumbs.mdx",
"chars": 1116,
"preview": "---\ntitle: Breadcrumbs\ndescription: Breadcrumbs display a hierarchy of links to the current page or resource in an appli"
},
{
"path": "apps/docs/content/components/button.mdx",
"chars": 1291,
"preview": "---\ntitle: Button\ndescription: A button allows a user to perform an action, with mouse, touch, and keyboard interactions"
},
{
"path": "apps/docs/content/components/checkbox-group.mdx",
"chars": 1092,
"preview": "---\ntitle: Checkbox Group\ndescription: A checkbox group allows a user to select multiple items from a list of options.\ni"
},
{
"path": "apps/docs/content/components/checkbox.mdx",
"chars": 1103,
"preview": "---\ntitle: Checkbox\ndescription: A checkbox allows a user to select multiple items from a list of individual items, or t"
},
{
"path": "apps/docs/content/components/combo-box.mdx",
"chars": 1378,
"preview": "---\ntitle: Combo Box\ndescription: A combo box combines a text input with a listbox, allowing users to filter a list of o"
},
{
"path": "apps/docs/content/components/date-picker.mdx",
"chars": 954,
"preview": "---\ntitle: Date Picker\ndescription: A date picker combines a DateField and a Calendar popover to allow users to enter or"
},
{
"path": "apps/docs/content/components/date-range-picker.mdx",
"chars": 1001,
"preview": "---\ntitle: Date Range Picker\ndescription: A date range picker combines two DateFields and a RangeCalendar popover to all"
},
{
"path": "apps/docs/content/components/grid-list.mdx",
"chars": 958,
"preview": "---\ntitle: Grid List\ndescription: A grid list displays a list of interactive items, with support for keyboard navigation"
},
{
"path": "apps/docs/content/components/icon-button.mdx",
"chars": 1528,
"preview": "---\ntitle: Icon Button\ndescription: Displays a form input field or a component that looks like an input field.\nisCompone"
},
{
"path": "apps/docs/content/components/input.mdx",
"chars": 1407,
"preview": "---\ntitle: Input\ndescription: Displays a form input field or a component that looks like an input field.\nisComponent: tr"
},
{
"path": "apps/docs/content/components/label.mdx",
"chars": 1033,
"preview": "---\ntitle: Label\ndescription: Displays a form input field or a component that looks like an input field.\nisComponent: tr"
},
{
"path": "apps/docs/content/components/menu.mdx",
"chars": 1504,
"preview": "---\ntitle: Menu\ndescription: A menu displays a list of actions or options that a user can choose.\nisComponent: true\n---\n"
},
{
"path": "apps/docs/content/components/meter.mdx",
"chars": 1009,
"preview": "---\ntitle: Meter\ndescription: A meter represents a quantity within a known range, or a fractional value.\nisComponent: tr"
},
{
"path": "apps/docs/content/components/modal.mdx",
"chars": 1379,
"preview": "---\ntitle: Modal\ndescription: A modal is an overlay element which blocks interaction with elements outside it.\nisCompone"
},
{
"path": "apps/docs/content/components/number-field.mdx",
"chars": 1270,
"preview": "---\ntitle: Number Field\ndescription: A number field allows a user to enter a number, and increment or decrement the valu"
},
{
"path": "apps/docs/content/components/progress-bar.mdx",
"chars": 1165,
"preview": "---\ntitle: Progress Bar\ndescription: Progress bars show either determinate or indeterminate progress of an operation ove"
},
{
"path": "apps/docs/content/components/radio-group.mdx",
"chars": 1080,
"preview": "---\ntitle: Radio Group\ndescription: A radio group allows a user to select a single item from a list of mutually exclusiv"
},
{
"path": "apps/docs/content/components/radio.mdx",
"chars": 1183,
"preview": "---\ntitle: Radio\ndescription: Displays a form input field or a component that looks like an input field.\nisComponent: tr"
},
{
"path": "apps/docs/content/components/search-field.mdx",
"chars": 977,
"preview": "---\ntitle: Search Field\ndescription: A search field allows a user to enter and clear a search query.\nisComponent: true\n-"
},
{
"path": "apps/docs/content/components/select.mdx",
"chars": 856,
"preview": "---\ntitle: Select\ndescription: A select displays a collapsible list of options and allows a user to select one of them.\n"
},
{
"path": "apps/docs/content/components/slider.mdx",
"chars": 1087,
"preview": "---\ntitle: Slider\ndescription: A slider allows a user to select one or more values within a range.\nisComponent: true\n---"
},
{
"path": "apps/docs/content/components/switch.mdx",
"chars": 1136,
"preview": "---\ntitle: Switch\ndescription: A text field allows a user to enter a plain text value with a keyboard.\nisComponent: true"
},
{
"path": "apps/docs/content/components/table.mdx",
"chars": 981,
"preview": "---\ntitle: Table\ndescription: A table displays data in rows and columns and enables a user to navigate its contents via "
},
{
"path": "apps/docs/content/components/tabs.mdx",
"chars": 1140,
"preview": "---\ntitle: Tabs\ndescription: Tabs organize content into multiple sections and allow users to navigate between them.\nisCo"
},
{
"path": "apps/docs/content/components/text-field.mdx",
"chars": 1077,
"preview": "---\ntitle: Text Field\ndescription: Displays a form input field or a component that looks like an input field.\nisComponen"
},
{
"path": "apps/docs/content/components/toggle-button.mdx",
"chars": 853,
"preview": "---\ntitle: Toggle Button\ndescription: A toggle button allows a user to toggle a selection on or off, for example switchi"
},
{
"path": "apps/docs/content/components/tooltip.mdx",
"chars": 865,
"preview": "---\ntitle: Tooltip\ndescription: A tooltip displays a description of an element on hover or focus.\nisComponent: true\n---\n"
},
{
"path": "apps/docs/content/getting-started/about.mdx",
"chars": 1971,
"preview": "---\ntitle: About\ndescription: The purpose of Draft UI is to make building accessible applications\n faster and easier th"
},
{
"path": "apps/docs/content/getting-started/cli.mdx",
"chars": 2010,
"preview": "---\ntitle: CLI\ndescription: Get started using Draft UI faster than ever by installing components right from the command "
},
{
"path": "apps/docs/content/getting-started/installation.mdx",
"chars": 5898,
"preview": "---\ntitle: Installation\ndescription: Here's everything you need to get started\norder: 2\n---\n\n<ListStepper>\n\n<ListStep>\n#"
},
{
"path": "apps/docs/content/getting-started/introduction.mdx",
"chars": 739,
"preview": "---\ntitle: Introduction\ndescription: Copy and paste-able components built with React Aria Components and\n Tailwind CSS\n"
},
{
"path": "apps/docs/contentlayer.config.ts",
"chars": 5770,
"preview": "import { defineDocumentType, makeSource } from 'contentlayer/source-files'\n// @ts-ignore\nimport toc from 'markdown-toc'\n"
},
{
"path": "apps/docs/lib/cva.config.ts",
"chars": 198,
"preview": "import { defineConfig } from 'cva'\nimport { twMerge } from 'tailwind-merge'\n\nexport const { cva, cx, compose } = defineC"
},
{
"path": "apps/docs/lib/rehype-component.ts",
"chars": 2872,
"preview": "import fs from 'fs'\nimport path from 'path'\n\nimport { u } from 'unist-builder'\nimport { visit } from 'unist-util-visit'\n"
},
{
"path": "apps/docs/lib/remark/with-table-of-contents.ts",
"chars": 508,
"preview": "import Slugger from 'github-slugger'\nimport { toString } from 'hast-util-to-string'\nimport { visit } from 'unist-util-vi"
},
{
"path": "apps/docs/next.config.js",
"chars": 1155,
"preview": "// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { withContentlayer } = require('next-contentlayer')"
},
{
"path": "apps/docs/package.json",
"chars": 1692,
"preview": "{\n \"name\": \"docs\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"main\": \"src/index.ts\",\n \"types\": \"src/index.ts\",\n \"scr"
},
{
"path": "apps/docs/postcss.config.js",
"chars": 102,
"preview": "/** @type {import('postcss').Config} */\nmodule.exports = require('postcss-config/postcss.config.cjs')\n"
},
{
"path": "apps/docs/public/site.webmanifest",
"chars": 263,
"preview": "{\"name\":\"\",\"short_name\":\"\",\"icons\":[{\"src\":\"/android-chrome-192x192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\"},{\"src\":\"/"
},
{
"path": "apps/docs/registry/breadcrumbs/default.tsx",
"chars": 592,
"preview": "import { ChevronRight } from 'lucide-react'\nimport { BreadcrumbItem, BreadcrumbLink, Breadcrumbs } from 'ui'\n\nexport def"
},
{
"path": "apps/docs/registry/button/default.tsx",
"chars": 101,
"preview": "import { Button } from 'ui'\n\nexport default function Default() {\n return <Button>Press Me</Button>\n}"
},
{
"path": "apps/docs/registry/button/disabled.tsx",
"chars": 599,
"preview": "import { Button } from 'ui'\n\nexport default function Disabled() {\n return (\n <div className=\"flex flex-wrap justify-"
},
{
"path": "apps/docs/registry/button/sizes.tsx",
"chars": 307,
"preview": "import { Button } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"flex flex-wrap justify-cen"
},
{
"path": "apps/docs/registry/button/theme.tsx",
"chars": 434,
"preview": "import { Button } from 'ui'\n\nexport default function Theme() {\n return (\n <div className=\"flex flex-wrap justify-cen"
},
{
"path": "apps/docs/registry/calendar/default.tsx",
"chars": 707,
"preview": "import {\n Calendar,\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeader,\n Calen"
},
{
"path": "apps/docs/registry/checkbox/default.tsx",
"chars": 327,
"preview": "import { Checkbox } from 'ui'\n\nexport default function Default() {\n return (\n <div className=\"space-y-4\">\n <Che"
},
{
"path": "apps/docs/registry/checkbox/disabled.tsx",
"chars": 352,
"preview": "import { Checkbox } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"space-y-4\">\n <Check"
},
{
"path": "apps/docs/registry/checkbox/sizes.tsx",
"chars": 1096,
"preview": "import { Checkbox } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"space-y-6\">\n <div c"
},
{
"path": "apps/docs/registry/checkbox-group/default.tsx",
"chars": 429,
"preview": "import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'\n\nexport default function Default() {\n return "
},
{
"path": "apps/docs/registry/checkbox-group/disabled.tsx",
"chars": 506,
"preview": "import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'\n\nexport default function Default() {\n return "
},
{
"path": "apps/docs/registry/checkbox-group/horizontal.tsx",
"chars": 457,
"preview": "import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'\n\nexport default function Horizontal() {\n retu"
},
{
"path": "apps/docs/registry/combobox/default.tsx",
"chars": 658,
"preview": "import {\n ComboBox,\n ComboBoxContent,\n ComboBoxInput,\n ComboBoxItem,\n Label,\n} from 'ui'\n\nexport default function D"
},
{
"path": "apps/docs/registry/combobox/disabled-keys.tsx",
"chars": 1391,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n ComboBox,\n ComboBoxButton,\n ComboBoxContent,\n ComboBoxInput,\n "
},
{
"path": "apps/docs/registry/combobox/disabled.tsx",
"chars": 1175,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n ComboBox,\n ComboBoxButton,\n ComboBoxContent,\n ComboBoxInput,\n "
},
{
"path": "apps/docs/registry/combobox/with-button.tsx",
"chars": 1166,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n ComboBox,\n ComboBoxButton,\n ComboBoxContent,\n ComboBoxInput,\n "
},
{
"path": "apps/docs/registry/date-field/default.tsx",
"chars": 323,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui'\n\nexport default function Default() {\n ret"
},
{
"path": "apps/docs/registry/date-field/disabled.tsx",
"chars": 335,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui'\n\nexport default function Disabled() {\n re"
},
{
"path": "apps/docs/registry/date-input/default.tsx",
"chars": 284,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui'\n\nexport default function Default() {\n return (\n "
},
{
"path": "apps/docs/registry/date-input/sizes.tsx",
"chars": 991,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui'\n\nexport default function Sizes() {\n return (\n "
},
{
"path": "apps/docs/registry/date-picker/default.tsx",
"chars": 2074,
"preview": "import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react'\nimport {\n Calendar,\n CalendarCell,\n CalendarGri"
},
{
"path": "apps/docs/registry/date-picker/disabled.tsx",
"chars": 2085,
"preview": "import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react'\nimport {\n Calendar,\n CalendarCell,\n CalendarGri"
},
{
"path": "apps/docs/registry/date-range-picker/default.tsx",
"chars": 1847,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHe"
},
{
"path": "apps/docs/registry/date-range-picker/disabled.tsx",
"chars": 1858,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHe"
},
{
"path": "apps/docs/registry/grid-list/default.tsx",
"chars": 1759,
"preview": "import { Info } from 'lucide-react'\nimport { Checkbox, GridList, GridListItem, IconButton } from 'ui'\n\nexport default fu"
},
{
"path": "apps/docs/registry/icon-button/default.tsx",
"chars": 215,
"preview": "import { AlertCircle } from 'lucide-react'\nimport { IconButton } from 'ui'\n\nexport default function Default() {\n return"
},
{
"path": "apps/docs/registry/icon-button/disabled.tsx",
"chars": 926,
"preview": "import { AlertCircle } from 'lucide-react'\nimport { IconButton } from 'ui'\n\nexport default function Disabled() {\n retur"
},
{
"path": "apps/docs/registry/icon-button/sizes.tsx",
"chars": 607,
"preview": "import { AlertCircle } from 'lucide-react'\nimport { IconButton } from 'ui'\n\nexport default function Sizes() {\n return ("
},
{
"path": "apps/docs/registry/icon-button/theme.tsx",
"chars": 857,
"preview": "import { AlertCircle } from 'lucide-react'\nimport { IconButton } from 'ui'\n\nexport default function Theme() {\n return ("
},
{
"path": "apps/docs/registry/input/default.tsx",
"chars": 84,
"preview": "import { Input } from 'ui'\n\nexport default function Default() {\n return <Input />\n}"
},
{
"path": "apps/docs/registry/input/disabled.tsx",
"chars": 94,
"preview": "import { Input } from 'ui'\n\nexport default function Disabled() {\n return <Input disabled />\n}"
},
{
"path": "apps/docs/registry/input/sizes.tsx",
"chars": 235,
"preview": "import { Input } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"flex flex-col gap-4\">\n "
},
{
"path": "apps/docs/registry/label/default.tsx",
"chars": 105,
"preview": "import { Label } from 'ui'\n\nexport default function Default() {\n return <Label>This is a label</Label>\n}"
},
{
"path": "apps/docs/registry/menu/as-checkbox.tsx",
"chars": 770,
"preview": "import * as React from 'react'\n\nimport { ChevronDown } from 'lucide-react'\nimport { type Selection } from 'react-aria-co"
},
{
"path": "apps/docs/registry/menu/as-radio.tsx",
"chars": 765,
"preview": "import * as React from 'react'\n\nimport { ChevronDown } from 'lucide-react'\nimport { type Selection } from 'react-aria-co"
},
{
"path": "apps/docs/registry/menu/default.tsx",
"chars": 489,
"preview": "import { ChevronDown } from 'lucide-react'\nimport { Button, Menu, MenuContent, MenuItem } from 'ui'\n\nexport default func"
},
{
"path": "apps/docs/registry/menu/disabled.tsx",
"chars": 514,
"preview": "import { ChevronDown } from 'lucide-react'\nimport { Button, Menu, MenuContent, MenuItem } from 'ui'\n\nexport default func"
},
{
"path": "apps/docs/registry/menu/with-sections.tsx",
"chars": 889,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n Button,\n Menu,\n MenuContent,\n MenuHeader,\n MenuItem,\n MenuSec"
},
{
"path": "apps/docs/registry/meter/default.tsx",
"chars": 383,
"preview": "import { Label, Meter, MeterFilledTrack, MeterTrack } from 'ui'\n\nexport default function Default() {\n return (\n <Met"
},
{
"path": "apps/docs/registry/modal/default.tsx",
"chars": 1575,
"preview": "import * as React from 'react'\n\nimport { X } from 'lucide-react'\nimport {\n Button,\n IconButton,\n ModalBody,\n ModalCo"
},
{
"path": "apps/docs/registry/modal/dismissable-false.tsx",
"chars": 1678,
"preview": "import * as React from 'react'\n\nimport { X } from 'lucide-react'\nimport {\n Button,\n IconButton,\n ModalBody,\n ModalCo"
},
{
"path": "apps/docs/registry/modal/set-autofocus.tsx",
"chars": 1529,
"preview": "import * as React from 'react'\n\nimport { X } from 'lucide-react'\nimport {\n Button,\n IconButton,\n Input,\n Label,\n Mo"
},
{
"path": "apps/docs/registry/modal/sizes.tsx",
"chars": 2055,
"preview": "import * as React from 'react'\n\nimport { X } from 'lucide-react'\nimport {\n Button,\n IconButton,\n ModalBody,\n ModalCo"
},
{
"path": "apps/docs/registry/number-field/default.tsx",
"chars": 198,
"preview": "import { Input, Label, NumberField } from 'ui'\n\nexport default function Default() {\n return (\n <NumberField defaultV"
},
{
"path": "apps/docs/registry/number-field/disabled.tsx",
"chars": 791,
"preview": "import * as React from 'react'\n\nimport { ChevronDown, ChevronUp } from 'lucide-react'\nimport {\n Label,\n NumberDecremen"
},
{
"path": "apps/docs/registry/number-field/with-mobile-stepper.tsx",
"chars": 665,
"preview": "import { ChevronDown, ChevronUp } from 'lucide-react'\nimport { IconButton, Input, Label, NumberField, NumberInputGroup }"
},
{
"path": "apps/docs/registry/number-field/with-stepper.tsx",
"chars": 780,
"preview": "import * as React from 'react'\n\nimport { ChevronDown, ChevronUp } from 'lucide-react'\nimport {\n Label,\n NumberDecremen"
},
{
"path": "apps/docs/registry/progress-bar/default.tsx",
"chars": 437,
"preview": "import {\n Label,\n ProgressBar,\n ProgressBarFilledTrack,\n ProgressBarTrack,\n} from 'ui'\n\nexport default function Defa"
},
{
"path": "apps/docs/registry/radio/default.tsx",
"chars": 201,
"preview": "import { Radio, RadioGroup } from 'ui'\n\nexport default function Default() {\n return (\n <RadioGroup>\n <Radio val"
},
{
"path": "apps/docs/registry/radio/disabled.tsx",
"chars": 247,
"preview": "import { Radio, RadioGroup } from 'ui'\n\nexport default function Default() {\n return (\n <RadioGroup defaultValue=\"dog"
},
{
"path": "apps/docs/registry/radio/sizes.tsx",
"chars": 720,
"preview": "import { Radio, RadioGroup } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"space-y-4\">\n "
},
{
"path": "apps/docs/registry/radio-group/default.tsx",
"chars": 366,
"preview": "import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui'\n\nexport default function Default() {\n return (\n <Ra"
},
{
"path": "apps/docs/registry/radio-group/disabled.tsx",
"chars": 400,
"preview": "import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui'\n\nexport default function Disabled() {\n return (\n <R"
},
{
"path": "apps/docs/registry/radio-group/horizontal.tsx",
"chars": 394,
"preview": "import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui'\n\nexport default function Horizontal() {\n return (\n "
},
{
"path": "apps/docs/registry/range-calendar/default.tsx",
"chars": 790,
"preview": "import * as React from 'react'\n\nimport {\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n Cal"
},
{
"path": "apps/docs/registry/search-field/default.tsx",
"chars": 536,
"preview": "import { Search } from 'lucide-react'\nimport { Label, SearchField, SearchFieldInput } from 'ui'\n\nexport default function"
},
{
"path": "apps/docs/registry/search-field/with-clear-button.tsx",
"chars": 803,
"preview": "import { Search } from 'lucide-react'\nimport {\n Label,\n SearchField,\n SearchFieldClearButton,\n SearchFieldInput,\n} f"
},
{
"path": "apps/docs/registry/select/default.tsx",
"chars": 1002,
"preview": "import * as React from 'react'\n\nimport { ChevronDown } from 'lucide-react'\nimport {\n Label,\n Select,\n SelectButton,\n "
},
{
"path": "apps/docs/registry/select/disabled.tsx",
"chars": 1014,
"preview": "import * as React from 'react'\n\nimport { ChevronDown } from 'lucide-react'\nimport {\n Label,\n Select,\n SelectButton,\n "
},
{
"path": "apps/docs/registry/slider/default.tsx",
"chars": 490,
"preview": "import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui'\n\nexport default function Default() {\n r"
},
{
"path": "apps/docs/registry/slider/vertical.tsx",
"chars": 539,
"preview": "import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui'\n\nexport default function Vertical() {\n "
},
{
"path": "apps/docs/registry/switch/alignment.tsx",
"chars": 330,
"preview": "import { Switch, SwitchIndicator } from 'ui'\n\nexport default function Alignment() {\n return (\n <div className=\"flex "
},
{
"path": "apps/docs/registry/switch/default.tsx",
"chars": 172,
"preview": "import { Switch, SwitchIndicator } from 'ui'\n\nexport default function Default() {\n return (\n <Switch>\n <SwitchI"
},
{
"path": "apps/docs/registry/switch/disabled.tsx",
"chars": 183,
"preview": "import { Switch, SwitchIndicator } from 'ui'\n\nexport default function Default() {\n return (\n <Switch isDisabled>\n "
},
{
"path": "apps/docs/registry/switch/sizes.tsx",
"chars": 358,
"preview": "import { Switch, SwitchIndicator } from 'ui'\n\nexport default function Default() {\n return (\n <div className=\"flex fl"
},
{
"path": "apps/docs/registry/tabs/default.tsx",
"chars": 541,
"preview": "import { Tab, TabList, TabPanel, Tabs } from 'ui'\n\nexport default function Default() {\n return (\n <Tabs>\n <TabL"
},
{
"path": "apps/docs/registry/tabs/disabled-keys.tsx",
"chars": 569,
"preview": "import { Tab, TabList, TabPanel, Tabs } from 'ui'\n\nexport default function DisabledKeys() {\n return (\n <Tabs disable"
},
{
"path": "apps/docs/registry/tabs/disabled.tsx",
"chars": 553,
"preview": "import { Tab, TabList, TabPanel, Tabs } from 'ui'\n\nexport default function Disabled() {\n return (\n <Tabs isDisabled>"
},
{
"path": "apps/docs/registry/tabs/vertical.tsx",
"chars": 575,
"preview": "import { Tab, TabList, TabPanel, Tabs } from 'ui'\n\nexport default function Vertical() {\n return (\n <Tabs orientation"
},
{
"path": "apps/docs/registry/text-field/default.tsx",
"chars": 174,
"preview": "import { Input, Label, TextField } from 'ui'\n\nexport default function Default() {\n return (\n <TextField>\n <Labe"
},
{
"path": "apps/docs/registry/text-field/disabled.tsx",
"chars": 185,
"preview": "import { Input, Label, TextField } from 'ui'\n\nexport default function Default() {\n return (\n <TextField isDisabled>\n"
},
{
"path": "apps/docs/registry/text-field/with-error.tsx",
"chars": 297,
"preview": "import { Input, Label, TextField, TextFieldErrorMessage } from 'ui'\n\nexport default function withError() {\n return (\n "
},
{
"path": "apps/docs/registry/tooltip/default.tsx",
"chars": 257,
"preview": "import { Button, Tooltip, TooltipContent } from 'ui'\n\nexport default function Default() {\n return (\n <Tooltip>\n "
},
{
"path": "apps/docs/registry/tooltip/placement.tsx",
"chars": 966,
"preview": "import { type TooltipProps } from 'react-aria-components'\nimport { Button, Tooltip, TooltipContent } from 'ui'\n\ntype Pla"
},
{
"path": "apps/docs/styles/globals.css",
"chars": 59,
"preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"
},
{
"path": "apps/docs/tailwind.config.js",
"chars": 2875,
"preview": "/** @type {import('tailwindcss').Config} */\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst shared"
},
{
"path": "apps/docs/tsconfig.json",
"chars": 724,
"preview": "{\n \"extends\": \"ts-config/nextjs.json\",\n \"compilerOptions\": {\n \"plugins\": [\n {\n \"name\": \"next\",\n },"
},
{
"path": "apps/docs/types.ts",
"chars": 787,
"preview": "import { type Node } from 'unist'\n\nexport interface UnistNode extends Node {\n type: string\n name?: string\n tagName?: "
},
{
"path": "apps/storybook/.eslintignore",
"chars": 12,
"preview": "!.storybook\n"
},
{
"path": "apps/storybook/.eslintrc.js",
"chars": 288,
"preview": "// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst path = require('path')\n\nmodule.exports = {\n root: "
},
{
"path": "apps/storybook/.gitignore",
"chars": 24,
"preview": ".turbo\nstorybook-static/"
},
{
"path": "apps/storybook/.storybook/main.ts",
"chars": 907,
"preview": "import { dirname, join } from \"path\";\n/** @type { import('@storybook/react-vite').StorybookConfig } */\n\nimport { mergeCo"
},
{
"path": "apps/storybook/.storybook/preview.ts",
"chars": 581,
"preview": "/** @type { import('@storybook/react').Preview } */\nimport { withThemeByClassName } from '@storybook/addon-styling'\n\nimp"
},
{
"path": "apps/storybook/package.json",
"chars": 1772,
"preview": "{\n \"name\": \"storybook\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"main\": \"src/index.ts\",\n \"types\": \"src/index.ts\",\n "
},
{
"path": "apps/storybook/postcss.config.cjs",
"chars": 102,
"preview": "/** @type {import('postcss').Config} */\nmodule.exports = require('postcss-config/postcss.config.cjs')\n"
},
{
"path": "apps/storybook/src/components/breadcrumbs/breadcrumbs.stories.tsx",
"chars": 287,
"preview": "import { Breadcrumbs } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/defa"
},
{
"path": "apps/storybook/src/components/breadcrumbs/stories/default.tsx",
"chars": 593,
"preview": "import { ChevronRight } from 'lucide-react'\nimport { BreadcrumbItem, BreadcrumbLink, Breadcrumbs } from 'ui'\n\nexport def"
},
{
"path": "apps/storybook/src/components/button/button.stories.tsx",
"chars": 528,
"preview": "import { Button } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/default'\n"
},
{
"path": "apps/storybook/src/components/button/stories/default.tsx",
"chars": 102,
"preview": "import { Button } from 'ui'\n\nexport default function Default() {\n return <Button>Press Me</Button>\n}\n"
},
{
"path": "apps/storybook/src/components/button/stories/disabled.tsx",
"chars": 600,
"preview": "import { Button } from 'ui'\n\nexport default function Disabled() {\n return (\n <div className=\"flex flex-wrap justify-"
},
{
"path": "apps/storybook/src/components/button/stories/sizes.tsx",
"chars": 308,
"preview": "import { Button } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"flex flex-wrap justify-cen"
},
{
"path": "apps/storybook/src/components/button/stories/theme.tsx",
"chars": 435,
"preview": "import { Button } from 'ui'\n\nexport default function Theme() {\n return (\n <div className=\"flex flex-wrap justify-cen"
},
{
"path": "apps/storybook/src/components/calendar/calendar.stories.tsx",
"chars": 275,
"preview": "import { Calendar } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/default"
},
{
"path": "apps/storybook/src/components/calendar/stories/default.tsx",
"chars": 708,
"preview": "import {\n Calendar,\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeader,\n Calen"
},
{
"path": "apps/storybook/src/components/checkbox/checkbox.stories.tsx",
"chars": 453,
"preview": "import { Checkbox } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/default"
},
{
"path": "apps/storybook/src/components/checkbox/stories/default.tsx",
"chars": 328,
"preview": "import { Checkbox } from 'ui'\n\nexport default function Default() {\n return (\n <div className=\"space-y-4\">\n <Che"
},
{
"path": "apps/storybook/src/components/checkbox/stories/disabled.tsx",
"chars": 353,
"preview": "import { Checkbox } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"space-y-4\">\n <Check"
},
{
"path": "apps/storybook/src/components/checkbox/stories/sizes.tsx",
"chars": 1097,
"preview": "import { Checkbox } from 'ui'\n\nexport default function Sizes() {\n return (\n <div className=\"space-y-6\">\n <div c"
},
{
"path": "apps/storybook/src/components/checkbox-group/checkbox-group.stories.tsx",
"chars": 493,
"preview": "import { CheckboxGroup } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/de"
},
{
"path": "apps/storybook/src/components/checkbox-group/stories/default.tsx",
"chars": 430,
"preview": "import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'\n\nexport default function Default() {\n return "
},
{
"path": "apps/storybook/src/components/checkbox-group/stories/disabled.tsx",
"chars": 507,
"preview": "import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'\n\nexport default function Default() {\n return "
},
{
"path": "apps/storybook/src/components/checkbox-group/stories/horizontal.tsx",
"chars": 458,
"preview": "import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui'\n\nexport default function Horizontal() {\n retu"
},
{
"path": "apps/storybook/src/components/combobox/combo-box.stories.tsx",
"chars": 586,
"preview": "import { ComboBox } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/default"
},
{
"path": "apps/storybook/src/components/combobox/stories/default.tsx",
"chars": 659,
"preview": "import {\n ComboBox,\n ComboBoxContent,\n ComboBoxInput,\n ComboBoxItem,\n Label,\n} from 'ui'\n\nexport default function D"
},
{
"path": "apps/storybook/src/components/combobox/stories/disabled-keys.tsx",
"chars": 1392,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n ComboBox,\n ComboBoxButton,\n ComboBoxContent,\n ComboBoxInput,\n "
},
{
"path": "apps/storybook/src/components/combobox/stories/disabled.tsx",
"chars": 1176,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n ComboBox,\n ComboBoxButton,\n ComboBoxContent,\n ComboBoxInput,\n "
},
{
"path": "apps/storybook/src/components/combobox/stories/with-button.tsx",
"chars": 1167,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n ComboBox,\n ComboBoxButton,\n ComboBoxContent,\n ComboBoxInput,\n "
},
{
"path": "apps/storybook/src/components/date-field/date-field.stories.tsx",
"chars": 374,
"preview": "import { DateField } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/defaul"
},
{
"path": "apps/storybook/src/components/date-field/stories/default.tsx",
"chars": 324,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui'\n\nexport default function Default() {\n ret"
},
{
"path": "apps/storybook/src/components/date-field/stories/disabled.tsx",
"chars": 336,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui'\n\nexport default function Disabled() {\n re"
},
{
"path": "apps/storybook/src/components/date-input/date-input.stories.tsx",
"chars": 362,
"preview": "import { DateInput } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/defaul"
},
{
"path": "apps/storybook/src/components/date-input/stories/default.tsx",
"chars": 285,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui'\n\nexport default function Default() {\n return (\n "
},
{
"path": "apps/storybook/src/components/date-input/stories/sizes.tsx",
"chars": 992,
"preview": "import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui'\n\nexport default function Sizes() {\n return (\n "
},
{
"path": "apps/storybook/src/components/date-picker/date-picker.stories.tsx",
"chars": 378,
"preview": "import { DatePicker } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/defau"
},
{
"path": "apps/storybook/src/components/date-picker/stories/default.tsx",
"chars": 2075,
"preview": "import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react'\nimport {\n Calendar,\n CalendarCell,\n CalendarGri"
},
{
"path": "apps/storybook/src/components/date-picker/stories/disabled.tsx",
"chars": 2086,
"preview": "import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react'\nimport {\n Calendar,\n CalendarCell,\n CalendarGri"
},
{
"path": "apps/storybook/src/components/date-range-picker/date-range-picker.stories.tsx",
"chars": 398,
"preview": "import { DateRangePicker } from 'ui'\n\nimport { type Meta } from '@storybook/react'\n\nimport DefaultStory from './stories/"
},
{
"path": "apps/storybook/src/components/date-range-picker/stories/default.tsx",
"chars": 1848,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHe"
},
{
"path": "apps/storybook/src/components/date-range-picker/stories/disabled.tsx",
"chars": 1859,
"preview": "import { ChevronDown } from 'lucide-react'\nimport {\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHe"
}
]
// ... and 129 more files (download for full content)
About this extraction
This page contains the full source code of the IHIutch/draft-ui GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 329 files (312.1 KB), approximately 92.2k tokens, and a symbol index with 235 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.