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 (
{children} {/*
) } ================================================ 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 { 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 ( <>

{post.title}

{post.description}

) } ================================================ 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 } children: React.ReactNode }) { const post = allComponentDocuments.find((post) => { return ( post._raw.flattenedPath.replace('docs/', '') === params.slug.join('/') ) }) if (!post) { notFound() } return (
{children} {/*
*/}
) } ================================================ 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 { 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 } }) { const post = allComponentDocuments.find((post) => { return ( post._raw.flattenedPath.replace('docs/', '') === params.slug.join('/') ) }) if (!post) { notFound() } return ( <>

{post.title}

{post.description}

) } ================================================ 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 } children: React.ReactNode }) { const post = allGeneralDocuments.find((post) => { return ( post._raw.flattenedPath.replace('getting-started/', '') === params.slug.join('/') ) }) if (!post) { notFound() } return (
{children} {/*
*/}
) } ================================================ 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 { 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 ( <>
{post.toc.length > 0 ? : null}

{post.title}

{post.description}

) } ================================================ 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 ( {/* 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 */} {children} ) } ================================================ 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 (

Accessibility doesn't
have to be hard

Draft UI is a collection of simply designed React components focused on making web accessibility as easy as copy & paste.

Built with{' '} React Aria Components {' '} and{' '} Tailwind CSS

25+ Accessible Components

) } ================================================ 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 {children} } ================================================ 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 ( <> ) } ================================================ 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 ( Code copied! ) } ================================================ 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', () => (
Info
{children}
)) .with('important', () => (
Important
{children}
)) .with('warning', () => (
Warning
{children}
)) .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 { 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 (

{name}{' '} "{story}" {' '} not found in registry.

) } return }, [name, story]) return (
Example Code
{Story}
{Code}
) } ================================================ 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 (
{Code}
) } ================================================ 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
{headingEl}
} ================================================ 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 }) { const focusAnchorElement = (anchor: string) => { const el = document?.getElementById(anchor) if (el) el.focus() } return ( focusAnchorElement(slug)} > Landmark Regions Page Content Site Navigation Page Navigation {toc ? ( Headings {toc.map((heading: TocItemProps, idx: number) => ( {heading.content} ))} ) : null} ) } ================================================ FILE: apps/docs/components/docs/list-stepper.tsx ================================================ import * as React from 'react' export function ListStepper({ children }: { children: React.ReactNode }) { return (
    {children}
) } export function ListStep({ children }: { children: React.ReactNode }) { return (
  • {children}
  • ) } ================================================ 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 (
    ) => ( ), figure: ({ className, __npmCommand__, __yarnCommand__, __pnpmCommand__, __niCommand__, __rawString__, ...props }: React.HTMLAttributes & { __rawString__?: string } & NpmCommands) => ( <> {/* TODO: Introduce buttons that let you choose package manager */}
    ), }} />
    ) } ================================================ 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 (
      Edit this page Give us feedback
    ) } const LinkItem = ({ href, children, }: { href: string children?: React.ReactNode }) => (
  • {children}
  • ) ================================================ 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 ( ) } ================================================ 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 (
    Get Started Components
    ) } ================================================ 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 (
    ) } ================================================ 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 (
      {list.map((link, idx) => (
    • { 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', )} > {link.title} {link?.isComing ? ( Coming Soon ) : link?.isNew ? ( New! ) : link?.isWip ? ( WIP ) : null}
    • ))}
    ) } ================================================ 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 ( {resolvedTheme === 'dark' ? ( ) : ( )} setTheme(value)} > ) } ================================================ 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 (
    Draft UI {/* Desktop Nav */}
    Getting Started Components
    {/* Mobile Nav */}
    setIsModalOpen(true)} > Menu setIsModalOpen(false)} autoFocus >

    Getting Started

    Components

    ) } ================================================ 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 }) { const activeHeading = useActiveHeading((headings || []).map((h) => h.slug)) return ( ) } function useActiveHeading(itemIds: string[]) { const [activeId, setActiveId] = useState(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 ( <> setIsOpen(true)} aria-label="Search" className="md:hidden" size="sm" variant="ghost" > {isOpen ? ( 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 ( {children} ) } ================================================ 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 {children} } ================================================ 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 --- By default, **`BreadcrumbLink`** uses a React Aria Component **`Link`**. To ensure this navigation works as expected with your framework, be sure to follow the Configure Routing step of the Draft UI installation. ## Installation CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui breadcrumbs ``` ## Examples ### Default This is an example of the default Breadcrumb component ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui button ``` ## Examples ### Default The default **`Button`** uses variant `solid` and size `md`. ### Themes You can use the `variant` prop to alter the **`Button`** theme. Variants `solid`, `outline`, `subtle`, `ghost`, `destructive`, and `link` are included by default. ### Sizes You can use the `size` prop to alter the **`Button`** size. Sizes `xs`, `sm`, `md`, and `lg` are included by default. ### Disabled Use the `isDisabled` prop to make the **`Button`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui checkbox-group ``` ## Examples ### Default The default **`CheckboxGroup`** uses orientation `vertical`. ### Horizontal Set the `orientation` prop to `horizontal` to use a horizontal **`CheckboxGroup`**. ### Disabled Use the `isDisabled` prop to make the entire **`CheckboxGroup`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui checkbox ``` ## Examples ### Default The default **`Checkbox`** uses size `md`. ### Sizes You can use the `size` prop to alter the **`Checkbox`** size. Sizes `sm`, `md`, and `lg` are included by default. ### Disabled Use the `isDisabled` prop to make an individual **`Checkbox`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui combobox ``` ## Examples ### Default This is the default **`ComboBox`** ### With Button Any React Aria Component **`Button`** placed inside **`ComboBox`**, will automatically toggle the appearance of **`ComboBoxContent`** when pressed. ### Disabled Keys To disable specific **`ComboBoxItem`**'s, add an array of `disabledKey`'s to **`ComboBox`**. Ensure the **`ComboBoxItem`**'s have appropriate, corresponding `id`'s. ### Disabled Use the `isDisabled` prop to disable the **`ComboxInput`** altogether. ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui date-picker ``` ## Examples ### Default This is the default **`DatePicker`** example. ### Disabled Use the `isDisabled` prop to disable the entire **`DatePicker`** including the **`DateInput`**. ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui date-range-picker ``` ## Examples ### Default This is the default **`DateRangePicker`** ### Disabled Use the `isDisabled` prop to disable the entire **`DateRangePicker`** including the **`DateInput`**'s. ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui grid-list ``` ## 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui icon-button ``` ## Examples ### Default The default **`IconButton`** uses variant `solid` and size `md`. 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. ### Themes You can use the `variant` prop to alter the button theme. Variants `solid`, `outline`, `subtle`, `ghost`, `destructive`, and `link` are included by default. ### Sizes You can use the `size` prop to alter the button size. Sizes `xs`, `sm`, `md`, and `lg` are included by default. ### Disabled Use the `isDisabled` prop to make the **`IconButton`** 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 --- **`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`**. ## Installation CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui input ``` ## Examples ### Default The default **`Input`** uses size `md`. ### Size You can use the `size` prop to alter the input size. Sizes `xs`, `sm`, `md`, and `lg` are included by default. ### Disabled Use the `disabled` prop to make the **`Input`** disabled. Currently, the **`Input`** component uses the `disabled` prop rather than `isDisabled`. ================================================ 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 --- **`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. ## Installation CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui label ``` ## Examples ### Default This is the default **`Label`** ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui menu ``` ## Examples ### Default This is the default **`Menu`** example. ### Disabled Make specific **`MenuItem`**'s disabled by adding their `id` to the **`MenuContent`**'s `disabledKeys` prop. ### With Sections Add sections to the menu by using **`MenuSection`** and **`MenuHeader`**. ### As Checkbox List **`MenuItem`** can act checkboxes by setting the **`MenuContent`**'s `selectionMode` prop to `multiple`. ### As Radio List **`MenuItem`** can act radios by setting the **`MenuContent`**'s `selectionMode` prop to `single`. ### 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui meter ``` ## Examples Althought similar to **`ProgressBar`**, **`Meter`** is used to represent an amount or quantity. For example: Storage space, download speed, or battery life. ### Default This is the default **`Meter`** ### 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui modal ``` ## Examples ### Default The default **`Modal`** uses size `md`. ### Sizes You can use the `size` prop to alter the button size. Sizes `xs`, `sm`, `md`, `lg`, `xl`, and `full` are included by default. ### Set Autofocus You can manually control which element recieves focus when the **`Modal`** opens by setting `autoFocus` on a focusable element. ### Dismissable Modals are dismissable by clicking outside by default or by pressing the Esc key. To prevent this, set `isDismissable` to `false` and/or `isKeyboardDismissDisabled` to `true`. ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui number-field ``` ## Examples ### Default This is the default **`NumberField`** ### With Stepper This is an example using the built-in **`NumberInputStepper`**. ### With Mobile Stepper This is an example of a custom **`NumberField`** that makes the stepper buttons easier to press on touch devices. ### Disabled Use the `isDisabled` prop to make the **`NumberField`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui progress-bar ``` ## Examples 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. ### Default This is the default **`ProgressBar`** ### 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui radio-group ``` ## Examples ### Default The default **`RadioGroup`** uses orientation `vertical`. ### Horizontal Set the `orientation` prop to `horizontal` to use a horizontal **`RadioGroup`**. ### Disabled Use the `isDisabled` prop to make the entire **`RadioGroup`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui radio ``` ## Examples **`Radio`** is a primitive component, it is not meant to be used on it's own. It must be wrapped in a **`RadioGroup`**. ### Default The default **`Radio`** uses size `md`. ### Sizes You can use the `size` prop to alter the **`Radio`** size. Sizes `sm`, `md`, and `lg` are included by default. ### Disabled Use the `isDisabled` prop to make an individual **`Radio`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui search-field ``` ## Examples ### Default This is the default **`SearchField`** ### 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. ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui select ``` ## Examples ### Default This is the default **`Select`**. ### Disabled Use the `isDisabled` prop to make the **`Select`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui slider ``` ## Examples ### Default The default **`Slider`** uses orientation `horizontal`. ### Vertical Set the `orientation` prop to `vertical` to use a vertical **`Slider`**. `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. ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui switch ``` ## Examples ### Default The default **`Switch`** uses size `md`. ### Alignment Switches can be either left or right aligned. ### Sizes You can use the `size` prop to alter the **`Switch`** size. Sizes `sm`, `md`, and `lg` are included by default. ### Disabled Use the `isDisabled` prop to make the **`Switch`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui table ``` ## 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui tabs ``` ## Examples ### Default The default **`Tabs`** uses orientation `horizontal`. ### Vertical Set the `orientation` prop to `vertical` to use vertical **`Tabs`**. ### Disabled Keys Use `disabledKeys` prop to disable specific **`Tab`**'s **`ComboBox`**. ### Disabled Use the `isDisabled` prop to disable all **`Tab`**'s. ================================================ 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui text-field ``` ## Examples ### Default This is the default **`TextField`**. ### 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. ### Disabled Use the `isDisabled` prop to make the **`Input`** 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui toggle-button ``` ## 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 CLI Copy & Paste ```bash title="bash" npx @sly-cli/sly add draft-ui tooltip ``` ## Examples ### Default The default **`Tooltip`** uses placement `top`. ### Placement Set the `placement` prop to change the default **`Tooltip`** 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 --- ## 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. ## 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) ## 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 ``` ## Configure Path Aliases Draft UI uses the path alias @/\* 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": { "@/*": ["./*"] } } } // ... ``` ## 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'), ], } ``` ## 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), }, }) ``` ## 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. Next.js App Next.js Pages Remix React Router ```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 ( {children} ) } ``` ```tsx title="app/layout.tsx" import { ClientProviders } from './provider'; export default function RootLayout({ children }) { return ( {children} ); } ``` ```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 ( ) } ``` ```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 ( {/* ... */} {/* ... */} ) } ``` ```tsx import { BrowserRouter, useNavigate } from 'react-router-dom' import { RouterProvider } from 'react-aria-components' function App() { let navigate = useNavigate() return ( {/* Your app here... */} } /> {/* ... */} ) } ``` For more information, go to the React Aria [Client Side Routing](https://react-spectrum.adobe.com/react-aria/routing.html). ## 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 CLI page to learn more. ## All Done! Now you're ready to start building your application! ================================================ 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 ( }> Home }> React Aria useBreadcrumbs ) } ================================================ FILE: apps/docs/registry/button/default.tsx ================================================ import { Button } from 'ui' export default function Default() { return } ================================================ FILE: apps/docs/registry/button/disabled.tsx ================================================ import { Button } from 'ui' export default function Disabled() { return (
    ) } ================================================ FILE: apps/docs/registry/button/sizes.tsx ================================================ import { Button } from 'ui' export default function Sizes() { return (
    ) } ================================================ FILE: apps/docs/registry/button/theme.tsx ================================================ import { Button } from 'ui' export default function Theme() { return (
    ) } ================================================ 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 ( {(day) => {day}} {(date) => } ) } ================================================ FILE: apps/docs/registry/checkbox/default.tsx ================================================ import { Checkbox } from 'ui' export default function Default() { return (
    Cat Dog Reptile
    ) } ================================================ FILE: apps/docs/registry/checkbox/disabled.tsx ================================================ import { Checkbox } from 'ui' export default function Sizes() { return (
    Medium Cat Medium Dog Medium Reptile
    ) } ================================================ FILE: apps/docs/registry/checkbox/sizes.tsx ================================================ import { Checkbox } from 'ui' export default function Sizes() { return (
    Small Cat Small Dog Small Reptile
    Medium Cat Medium Dog Medium Reptile
    Large Cat Large Dog Large Reptile
    ) } ================================================ FILE: apps/docs/registry/checkbox-group/default.tsx ================================================ import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui' export default function Default() { return ( Soccer Baseball Basketball ) } ================================================ FILE: apps/docs/registry/checkbox-group/disabled.tsx ================================================ import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui' export default function Default() { return ( Soccer Baseball Basketball ) } ================================================ FILE: apps/docs/registry/checkbox-group/horizontal.tsx ================================================ import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui' export default function Horizontal() { return ( Soccer Baseball Basketball ) } ================================================ FILE: apps/docs/registry/combobox/default.tsx ================================================ import { ComboBox, ComboBoxContent, ComboBoxInput, ComboBoxItem, Label, } from 'ui' export default function Default() { return ( Aardvark Cat Dog Kangaroo Panda Snake ) } ================================================ 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 (
    Aardvark Cat Dog Kangaroo Panda Snake
    ) } ================================================ 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 (
    Aardvark Cat Dog Kangaroo Panda Snake
    ) } ================================================ 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 (
    Aardvark Cat Dog Kangaroo Panda Snake
    ) } ================================================ FILE: apps/docs/registry/date-field/default.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui' export default function Default() { return ( {(segment) => } ) } ================================================ FILE: apps/docs/registry/date-field/disabled.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui' export default function Disabled() { return ( {(segment) => } ) } ================================================ FILE: apps/docs/registry/date-input/default.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui' export default function Default() { return ( {(segment) => } ) } ================================================ FILE: apps/docs/registry/date-input/sizes.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui' export default function Sizes() { return (
    {(segment) => } {(segment) => } {(segment) => } {(segment) => }
    ) } ================================================ 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 ( {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ 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 ( {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ 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 ( {(segment) => } {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ 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 ( {(segment) => } {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ 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 ( Charizard Blastoise Venusaur Pikachu ) } ================================================ FILE: apps/docs/registry/icon-button/default.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Default() { return ( ) } ================================================ FILE: apps/docs/registry/icon-button/disabled.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Disabled() { return (
    ) } ================================================ FILE: apps/docs/registry/icon-button/sizes.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Sizes() { return (
    ) } ================================================ FILE: apps/docs/registry/icon-button/theme.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Theme() { return (
    ) } ================================================ FILE: apps/docs/registry/input/default.tsx ================================================ import { Input } from 'ui' export default function Default() { return } ================================================ FILE: apps/docs/registry/input/disabled.tsx ================================================ import { Input } from 'ui' export default function Disabled() { return } ================================================ FILE: apps/docs/registry/input/sizes.tsx ================================================ import { Input } from 'ui' export default function Sizes() { return (
    ) } ================================================ FILE: apps/docs/registry/label/default.tsx ================================================ import { Label } from 'ui' export default function Default() { return } ================================================ 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(new Set(['bar1'])) return ( Foo Bar Baz ) } ================================================ 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(new Set(['bar1'])) return ( Foo Bar Baz ) } ================================================ FILE: apps/docs/registry/menu/default.tsx ================================================ import { ChevronDown } from 'lucide-react' import { Button, Menu, MenuContent, MenuItem } from 'ui' export default function Default() { return ( Foo Bar Baz ) } ================================================ FILE: apps/docs/registry/menu/disabled.tsx ================================================ import { ChevronDown } from 'lucide-react' import { Button, Menu, MenuContent, MenuItem } from 'ui' export default function Disabled() { return ( Foo Bar Baz ) } ================================================ 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 ( Styles Foo Bar Baz Align Foo Bar Baz ) } ================================================ FILE: apps/docs/registry/meter/default.tsx ================================================ import { Label, Meter, MeterFilledTrack, MeterTrack } from 'ui' export default function Default() { return ( {({ percentage }) => ( <> )} ) } ================================================ 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 ( <> Modal Title setIsOpen(false)} >

    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.

    ) } ================================================ 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 ( <> Modal Title setIsOpen(false)} >

    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.

    ) } ================================================ 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 ( <> Modal Title setIsOpen(false)} > ) } ================================================ 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['size'] export default function Default() { const [isOpen, setIsOpen] = React.useState(false) const [modalSize, setModalSize] = React.useState('md') const sizes: Size[] = ['xs', 'sm', 'md', 'lg', 'xl', 'full'] const handlePress = (size: Size, open: boolean) => { setModalSize(size) setIsOpen(open) } return ( <>
    {sizes.map((size, idx) => ( ))}
    Modal Title setIsOpen(false)} >

    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.

    ) } ================================================ FILE: apps/docs/registry/number-field/default.tsx ================================================ import { Input, Label, NumberField } from 'ui' export default function Default() { return ( ) } ================================================ 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 ( ) } ================================================ 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 ( ) } ================================================ 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 ( ) } ================================================ FILE: apps/docs/registry/progress-bar/default.tsx ================================================ import { Label, ProgressBar, ProgressBarFilledTrack, ProgressBarTrack, } from 'ui' export default function Default() { return ( {({ percentage }) => ( <> )} ) } ================================================ FILE: apps/docs/registry/radio/default.tsx ================================================ import { Radio, RadioGroup } from 'ui' export default function Default() { return ( Cat Dog ) } ================================================ FILE: apps/docs/registry/radio/disabled.tsx ================================================ import { Radio, RadioGroup } from 'ui' export default function Default() { return ( Cat Dog ) } ================================================ FILE: apps/docs/registry/radio/sizes.tsx ================================================ import { Radio, RadioGroup } from 'ui' export default function Sizes() { return (
    Small Cat Small Dog Medium Cat Medium Dog Large Cat Large Dog
    ) } ================================================ FILE: apps/docs/registry/radio-group/default.tsx ================================================ import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui' export default function Default() { return ( Dog Cat Dragon ) } ================================================ FILE: apps/docs/registry/radio-group/disabled.tsx ================================================ import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui' export default function Disabled() { return ( Dog Cat Dragon ) } ================================================ FILE: apps/docs/registry/radio-group/horizontal.tsx ================================================ import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui' export default function Horizontal() { return ( Dog Cat Dragon ) } ================================================ 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 ( {(day) => {day}} {(date) => } ) } ================================================ FILE: apps/docs/registry/search-field/default.tsx ================================================ import { Search } from 'lucide-react' import { Label, SearchField, SearchFieldInput } from 'ui' export default function Default() { return (
    ) } ================================================ 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 (
    ) } ================================================ 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 ( <> ) } ================================================ 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 ( <> ) } ================================================ FILE: apps/docs/registry/slider/default.tsx ================================================ import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui' export default function Default() { return ( {({ state }) => ( <> )} ) } ================================================ FILE: apps/docs/registry/slider/vertical.tsx ================================================ import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui' export default function Vertical() { return ( {({ state }) => ( <> )} ) } ================================================ FILE: apps/docs/registry/switch/alignment.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Alignment() { return (
    I'm on the right I'm on the left
    ) } ================================================ FILE: apps/docs/registry/switch/default.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Default() { return ( Low power mode ) } ================================================ FILE: apps/docs/registry/switch/disabled.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Default() { return ( Low power mode ) } ================================================ FILE: apps/docs/registry/switch/sizes.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Default() { return (
    ) } ================================================ FILE: apps/docs/registry/tabs/default.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function Default() { return ( Founding of Rome Monarchy and Republic Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/docs/registry/tabs/disabled-keys.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function DisabledKeys() { return ( Founding of Rome Monarchy and Republic Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/docs/registry/tabs/disabled.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function Disabled() { return ( Founding of Rome Monarchy and Republic Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/docs/registry/tabs/vertical.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function Vertical() { return ( Founding of Rome Monarchy and Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/docs/registry/text-field/default.tsx ================================================ import { Input, Label, TextField } from 'ui' export default function Default() { return ( ) } ================================================ FILE: apps/docs/registry/text-field/disabled.tsx ================================================ import { Input, Label, TextField } from 'ui' export default function Default() { return ( ) } ================================================ FILE: apps/docs/registry/text-field/with-error.tsx ================================================ import { Input, Label, TextField, TextFieldErrorMessage } from 'ui' export default function withError() { return ( This is an error message ) } ================================================ FILE: apps/docs/registry/tooltip/default.tsx ================================================ import { Button, Tooltip, TooltipContent } from 'ui' export default function Default() { return ( Hello! ) } ================================================ FILE: apps/docs/registry/tooltip/placement.tsx ================================================ import { type TooltipProps } from 'react-aria-components' import { Button, Tooltip, TooltipContent } from 'ui' type Placement = Pick['placement'] export default function Placement() { const placements: Placement[] = [ 'bottom', 'bottom left', 'bottom right', 'bottom start', 'bottom end', 'top', 'top left', 'top right', 'top start', 'top end', 'left', 'left top', 'left bottom', 'start', 'start top', 'start bottom', 'right', 'right top', 'right bottom', 'end', 'end top', 'end bottom', ] return (
    {placements.map((placement, idx) => ( Hello! ))}
    ) } ================================================ FILE: apps/docs/styles/globals.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: apps/docs/tailwind.config.js ================================================ /** @type {import('tailwindcss').Config} */ // eslint-disable-next-line @typescript-eslint/no-var-requires const sharedConfig = require('tailwind-config/tailwind.config.cjs') module.exports = { presets: [sharedConfig], content: [ './app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}', './registry/**/*.{js,ts,jsx,tsx}', '../../packages/**/*.{js,ts,jsx,tsx}', ], theme: { extend: { typography: (theme) => ({ DEFAULT: { css: { 'code::before': { content: 'none', }, 'code::after': { content: 'none', }, 'code:not([data-rehype-pretty-code-figure] code)': { color: theme('colors.slate.800'), fontWeight: 'normal', backgroundColor: theme('colors.slate.100'), paddingTop: '2px', paddingRight: theme('spacing.1'), paddingBottom: '2px', paddingLeft: theme('spacing.1'), borderRadius: theme('spacing.1'), letterSpacing: theme('letterSpacing.wide'), }, 'strong code:not([data-rehype-pretty-code-figure] code)': { fontWeight: 'bolder', }, '[data-rehype-pretty-code-title]': { backgroundColor: '#282a36', borderTopLeftRadius: theme('borderRadius.md'), borderTopRightRadius: theme('borderRadius.md'), paddingLeft: theme('spacing.4'), paddingRight: theme('spacing.4'), paddingTop: theme('spacing.3'), marginTop: theme('spacing.0'), paddingBottom: theme('spacing.1'), color: theme('colors.gray.400'), userSelect: 'none', '+ pre': { borderTopLeftRadius: theme('borderRadius.none'), borderTopRightRadius: theme('borderRadius.none'), marginTop: theme('spacing.0'), }, }, '[data-rehype-pretty-code-figure]': { '> pre': { paddingLeft: theme('spacing.0'), paddingRight: theme('spacing.0'), code: { paddingLeft: theme('spacing.0'), paddingRight: theme('spacing.0'), '[data-line]': { paddingLeft: theme('spacing.4'), paddingRight: theme('spacing.4'), }, }, }, }, }, }, invert: { css: { 'code:not([data-rehype-pretty-code-figure] code)': { color: theme('colors.white'), backgroundColor: theme('colors.slate.800'), }, }, }, }), }, }, plugins: [require('@tailwindcss/typography')], } ================================================ FILE: apps/docs/tsconfig.json ================================================ { "extends": "ts-config/nextjs.json", "compilerOptions": { "plugins": [ { "name": "next", }, ], "baseUrl": ".", "paths": { "contentlayer/generated": ["./.contentlayer/generated"], "@/components/ui": [ "./../../packages/ui/src", // Mock importing as local components ], "@/*": ["./*"], }, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "esModuleInterop": true, "moduleResolution": "node", "isolatedModules": true, "strictNullChecks": true, }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".contentlayer/generated", ], "exclude": ["node_modules"], } ================================================ FILE: apps/docs/types.ts ================================================ import { type Node } from 'unist' export interface UnistNode extends Node { type: string name?: string tagName?: string value?: string properties?: { __rawString__?: string __className__?: string __event__?: string [key: string]: unknown } & NpmCommands attributes?: { name: string value: unknown type?: string }[] children?: UnistNode[] } export interface UnistTree extends Node { children: UnistNode[] } export interface NpmCommands { __npmCommand__?: string __yarnCommand__?: string __pnpmCommand__?: string __niCommand__?: string } export interface ExamplesListItem { name: string variant: string text: string functionName: string } export interface TocItemProps { slug: string content: string lvl: number } ================================================ FILE: apps/storybook/.eslintignore ================================================ !.storybook ================================================ FILE: apps/storybook/.eslintrc.js ================================================ // eslint-disable-next-line @typescript-eslint/no-var-requires const path = require('path') module.exports = { root: true, extends: ['custom', 'plugin:storybook/recommended'], settings: { tailwindcss: { config: path.join(__dirname, './tailwind.config.js'), }, }, } ================================================ FILE: apps/storybook/.gitignore ================================================ .turbo storybook-static/ ================================================ FILE: apps/storybook/.storybook/main.ts ================================================ import { dirname, join } from "path"; /** @type { import('@storybook/react-vite').StorybookConfig } */ import { mergeConfig } from 'vite' import tsconfigPaths from 'vite-tsconfig-paths' import type { StorybookConfig } from '@storybook/react-vite' const config: StorybookConfig = { framework: getAbsolutePath("@storybook/react-vite"), stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: [ getAbsolutePath("@storybook/addon-a11y"), getAbsolutePath("@storybook/addon-links"), getAbsolutePath("@storybook/addon-essentials"), { name: '@storybook/addon-styling', }, ], typescript: { reactDocgen: false, }, viteFinal(config, { configType }) { return mergeConfig(config, { plugins: [tsconfigPaths()], }) }, } export default config function getAbsolutePath(value: string): any { return dirname(require.resolve(join(value, "package.json"))); } ================================================ FILE: apps/storybook/.storybook/preview.ts ================================================ /** @type { import('@storybook/react').Preview } */ import { withThemeByClassName } from '@storybook/addon-styling' import '../src/styles.css' import { Preview } from '@storybook/react' const preview: Preview = { parameters: { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }, } export const decorators = [ withThemeByClassName({ themes: { light: '', dark: 'dark bg-slate-800', }, defaultTheme: 'light', }), ] export default preview ================================================ FILE: apps/storybook/package.json ================================================ { "name": "storybook", "version": "0.1.0", "private": true, "main": "src/index.ts", "types": "src/index.ts", "scripts": { "lint": "eslint --ignore-path .gitignore '**/*.{js,jsx,cjs,mjs,ts,tsx,json}'", "storybook": "storybook dev -p 6006", "build": "storybook build", "upgrade": "pnpm dlx sb@latest upgrade", "typecheck": "tsc --noEmit --pretty" }, "dependencies": { "@babel/preset-env": "^7.23.7", "@babel/preset-react": "^7.23.3", "@babel/preset-typescript": "^7.23.3", "@storybook/addon-a11y": "^7.6.7", "@storybook/addon-essentials": "^7.6.7", "@storybook/addon-interactions": "^7.6.7", "@storybook/addon-links": "^7.6.7", "@storybook/addon-styling": "^1.3.7", "@storybook/blocks": "^7.6.7", "@storybook/react": "^7.6.7", "@storybook/react-vite": "^7.6.7", "@storybook/testing-library": "^0.2.2", "autoprefixer": "^10.4.16", "lucide-react": "^0.259.0", "postcss-loader": "^7.3.4", "prop-types": "^15.8.1", "react": "^18.2.0", "react-aria-components": "1.0.0", "react-dom": "^18.2.0", "storybook": "^7.6.7", "tailwindcss": "^3.4.1", "tailwindcss-animate": "^1.0.7", "typescript": "^5.1.6", "ui": "workspace:*", "vite": "^4.5.1", "vite-tsconfig-paths": "^4.2.3" }, "devDependencies": { "@storybook/manager-api": "^7.6.7", "@storybook/theming": "^7.6.7", "@types/react": "18.0.27", "@types/react-dom": "18.0.10", "@typescript-eslint/eslint-plugin": "^5.62.0", "eslint": "^8.56.0", "eslint-config-custom": "workspace:*", "eslint-plugin-storybook": "^0.6.15", "postcss": "^8.4.33", "postcss-config": "workspace:*", "tailwind-config": "workspace:*", "ts-config": "workspace:*" } } ================================================ FILE: apps/storybook/postcss.config.cjs ================================================ /** @type {import('postcss').Config} */ module.exports = require('postcss-config/postcss.config.cjs') ================================================ FILE: apps/storybook/src/components/breadcrumbs/breadcrumbs.stories.tsx ================================================ import { Breadcrumbs } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' const meta: Meta = { title: 'Breadcrumbs', component: Breadcrumbs, } export default meta export const Default = () => ================================================ FILE: apps/storybook/src/components/breadcrumbs/stories/default.tsx ================================================ import { ChevronRight } from 'lucide-react' import { BreadcrumbItem, BreadcrumbLink, Breadcrumbs } from 'ui' export default function Default() { return ( }> Home }> React Aria useBreadcrumbs ) } ================================================ FILE: apps/storybook/src/components/button/button.stories.tsx ================================================ import { Button } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import SizesStory from './stories/sizes' import ThemeStory from './stories/theme' const meta: Meta = { title: 'Button', component: Button, } export default meta export const Default = () => export const Sizes = () => export const Theme = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/button/stories/default.tsx ================================================ import { Button } from 'ui' export default function Default() { return } ================================================ FILE: apps/storybook/src/components/button/stories/disabled.tsx ================================================ import { Button } from 'ui' export default function Disabled() { return (
    ) } ================================================ FILE: apps/storybook/src/components/button/stories/sizes.tsx ================================================ import { Button } from 'ui' export default function Sizes() { return (
    ) } ================================================ FILE: apps/storybook/src/components/button/stories/theme.tsx ================================================ import { Button } from 'ui' export default function Theme() { return (
    ) } ================================================ FILE: apps/storybook/src/components/calendar/calendar.stories.tsx ================================================ import { Calendar } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' const meta: Meta = { title: 'Calendar', component: Calendar, } export default meta export const Default = () => ================================================ FILE: apps/storybook/src/components/calendar/stories/default.tsx ================================================ import { Calendar, CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeader, CalendarHeaderCell, CalendarHeading, CalendarNextButton, CalendarPrevButton, } from 'ui' export default function Default() { return ( {(day) => {day}} {(date) => } ) } ================================================ FILE: apps/storybook/src/components/checkbox/checkbox.stories.tsx ================================================ import { Checkbox } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import SizesStory from './stories/sizes' const meta: Meta = { title: 'Checkbox', component: Checkbox, } export default meta export const Default = () => export const Sizes = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/checkbox/stories/default.tsx ================================================ import { Checkbox } from 'ui' export default function Default() { return (
    Cat Dog Reptile
    ) } ================================================ FILE: apps/storybook/src/components/checkbox/stories/disabled.tsx ================================================ import { Checkbox } from 'ui' export default function Sizes() { return (
    Medium Cat Medium Dog Medium Reptile
    ) } ================================================ FILE: apps/storybook/src/components/checkbox/stories/sizes.tsx ================================================ import { Checkbox } from 'ui' export default function Sizes() { return (
    Small Cat Small Dog Small Reptile
    Medium Cat Medium Dog Medium Reptile
    Large Cat Large Dog Large Reptile
    ) } ================================================ FILE: apps/storybook/src/components/checkbox-group/checkbox-group.stories.tsx ================================================ import { CheckboxGroup } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import HorizontalStory from './stories/horizontal' const meta: Meta = { title: 'CheckboxGroup', component: CheckboxGroup, } export default meta export const Default = () => export const Horizontal = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/checkbox-group/stories/default.tsx ================================================ import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui' export default function Default() { return ( Soccer Baseball Basketball ) } ================================================ FILE: apps/storybook/src/components/checkbox-group/stories/disabled.tsx ================================================ import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui' export default function Default() { return ( Soccer Baseball Basketball ) } ================================================ FILE: apps/storybook/src/components/checkbox-group/stories/horizontal.tsx ================================================ import { Checkbox, CheckboxGroup, CheckboxGroupContent, Label } from 'ui' export default function Horizontal() { return ( Soccer Baseball Basketball ) } ================================================ FILE: apps/storybook/src/components/combobox/combo-box.stories.tsx ================================================ import { ComboBox } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import DisabledKeysStory from './stories/disabled-keys' import WithButtonStory from './stories/with-button' const meta: Meta = { title: 'ComboBox', component: ComboBox, } export default meta export const Default = () => export const WithButton = () => export const Disabled = () => export const DisabledKeys = () => ================================================ FILE: apps/storybook/src/components/combobox/stories/default.tsx ================================================ import { ComboBox, ComboBoxContent, ComboBoxInput, ComboBoxItem, Label, } from 'ui' export default function Default() { return ( Aardvark Cat Dog Kangaroo Panda Snake ) } ================================================ FILE: apps/storybook/src/components/combobox/stories/disabled-keys.tsx ================================================ import { ChevronDown } from 'lucide-react' import { ComboBox, ComboBoxButton, ComboBoxContent, ComboBoxInput, ComboBoxItem, iconButtonVariants, Label, } from 'ui' export default function DisabledKeys() { return (
    Aardvark Cat Dog Kangaroo Panda Snake
    ) } ================================================ FILE: apps/storybook/src/components/combobox/stories/disabled.tsx ================================================ import { ChevronDown } from 'lucide-react' import { ComboBox, ComboBoxButton, ComboBoxContent, ComboBoxInput, ComboBoxItem, iconButtonVariants, Label, } from 'ui' export default function Disabled() { return (
    Aardvark Cat Dog Kangaroo Panda Snake
    ) } ================================================ FILE: apps/storybook/src/components/combobox/stories/with-button.tsx ================================================ import { ChevronDown } from 'lucide-react' import { ComboBox, ComboBoxButton, ComboBoxContent, ComboBoxInput, ComboBoxItem, iconButtonVariants, Label, } from 'ui' export default function WithButton() { return (
    Aardvark Cat Dog Kangaroo Panda Snake
    ) } ================================================ FILE: apps/storybook/src/components/date-field/date-field.stories.tsx ================================================ import { DateField } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' const meta: Meta = { title: 'DateField', component: DateField, } export default meta export const Default = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/date-field/stories/default.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui' export default function Default() { return ( {(segment) => } ) } ================================================ FILE: apps/storybook/src/components/date-field/stories/disabled.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment, Label } from 'ui' export default function Disabled() { return ( {(segment) => } ) } ================================================ FILE: apps/storybook/src/components/date-input/date-input.stories.tsx ================================================ import { DateInput } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import SizesStory from './stories/sizes' const meta: Meta = { title: 'DateInput', component: DateInput, } export default meta export const Default = () => export const Sizes = () => ================================================ FILE: apps/storybook/src/components/date-input/stories/default.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui' export default function Default() { return ( {(segment) => } ) } ================================================ FILE: apps/storybook/src/components/date-input/stories/sizes.tsx ================================================ import { DateField, DateInput, DateInputGroup, DateSegment } from 'ui' export default function Sizes() { return (
    {(segment) => } {(segment) => } {(segment) => } {(segment) => }
    ) } ================================================ FILE: apps/storybook/src/components/date-picker/date-picker.stories.tsx ================================================ import { DatePicker } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' const meta: Meta = { title: 'DatePicker', component: DatePicker, } export default meta export const Default = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/date-picker/stories/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 ( {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ FILE: apps/storybook/src/components/date-picker/stories/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 ( {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ FILE: apps/storybook/src/components/date-range-picker/date-range-picker.stories.tsx ================================================ import { DateRangePicker } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' const meta: Meta = { title: 'DateRangePicker', component: DateRangePicker, } export default meta export const Default = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/date-range-picker/stories/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 ( {(segment) => } {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ FILE: apps/storybook/src/components/date-range-picker/stories/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 ( {(segment) => } {(segment) => }
    {(day) => {day}} {(date) => }
    ) } ================================================ FILE: apps/storybook/src/components/grid-list/grid-list.stories.tsx ================================================ import { GridList } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' const meta: Meta = { title: 'GridList', component: GridList, } export default meta export const Default = () => ================================================ FILE: apps/storybook/src/components/grid-list/stories/default.tsx ================================================ import { Info } from 'lucide-react' import { Checkbox, GridList, GridListItem, IconButton } from 'ui' export default function Default() { return ( Charizard Blastoise Venusaur Pikachu ) } ================================================ FILE: apps/storybook/src/components/icon-button/icon-button.stories.tsx ================================================ import { IconButton } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import SizesStory from './stories/sizes' import ThemeStory from './stories/theme' const meta: Meta = { title: 'IconButton', component: IconButton, } export default meta export const Default = () => export const Sizes = () => export const Theme = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/icon-button/stories/default.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Default() { return ( ) } ================================================ FILE: apps/storybook/src/components/icon-button/stories/disabled.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Disabled() { return (
    ) } ================================================ FILE: apps/storybook/src/components/icon-button/stories/sizes.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Sizes() { return (
    ) } ================================================ FILE: apps/storybook/src/components/icon-button/stories/theme.tsx ================================================ import { AlertCircle } from 'lucide-react' import { IconButton } from 'ui' export default function Theme() { return (
    ) } ================================================ FILE: apps/storybook/src/components/input/input.stories.tsx ================================================ import { Input } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import SizesStory from './stories/sizes' const meta: Meta = { title: 'Input', component: Input, } export default meta export const Default = () => export const Sizes = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/input/stories/default.tsx ================================================ import { Input } from 'ui' export default function Default() { return } ================================================ FILE: apps/storybook/src/components/input/stories/disabled.tsx ================================================ import { Input } from 'ui' export default function Disabled() { return } ================================================ FILE: apps/storybook/src/components/input/stories/sizes.tsx ================================================ import { Input } from 'ui' export default function Sizes() { return (
    ) } ================================================ FILE: apps/storybook/src/components/label/label.stories.tsx ================================================ import { Label } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' const meta: Meta = { title: 'Label', component: Label, } export default meta export const Default = () => ================================================ FILE: apps/storybook/src/components/label/stories/default.tsx ================================================ import { Label } from 'ui' export default function Default() { return } ================================================ FILE: apps/storybook/src/components/menu/menu.stories.tsx ================================================ import { Menu } from 'ui' import { type Meta } from '@storybook/react' import AsCheckboxStory from './stories/as-checkbox' import AsRadioStory from './stories/as-radio' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import WithSectionsStory from './stories/with-sections' const meta: Meta = { title: 'Menu', component: Menu, } export default meta export const Default = () => export const WithSections = () => export const AsCheckbox = () => export const AsRadio = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/menu/stories/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(new Set(['bar1'])) return ( Foo Bar Baz ) } ================================================ FILE: apps/storybook/src/components/menu/stories/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(new Set(['bar1'])) return ( Foo Bar Baz ) } ================================================ FILE: apps/storybook/src/components/menu/stories/default.tsx ================================================ import { ChevronDown } from 'lucide-react' import { Button, Menu, MenuContent, MenuItem } from 'ui' export default function Default() { return ( Foo Bar Baz ) } ================================================ FILE: apps/storybook/src/components/menu/stories/disabled.tsx ================================================ import { ChevronDown } from 'lucide-react' import { Button, Menu, MenuContent, MenuItem } from 'ui' export default function Disabled() { return ( Foo Bar Baz ) } ================================================ FILE: apps/storybook/src/components/menu/stories/with-sections.tsx ================================================ import { ChevronDown } from 'lucide-react' import { Button, Menu, MenuContent, MenuHeader, MenuItem, MenuSection, MenuSeparator, } from 'ui' export default function WithSections() { return ( Styles Foo Bar Baz Align Foo Bar Baz ) } ================================================ FILE: apps/storybook/src/components/meter/meter.stories.tsx ================================================ import { Meter } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' const meta: Meta = { title: 'Meter', component: Meter, } export default meta export const Default = () => ================================================ FILE: apps/storybook/src/components/meter/stories/default.tsx ================================================ import { Label, Meter, MeterFilledTrack, MeterTrack } from 'ui' export default function Default() { return ( {({ percentage }) => ( <> )} ) } ================================================ FILE: apps/storybook/src/components/modal/modal.stories.tsx ================================================ import { ModalContent } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DismissableFalseStory from './stories/dismissable-false' import SizesStory from './stories/sizes' const meta: Meta = { title: 'Modal', component: ModalContent, } export default meta export const Default = () => export const Sizes = () => export const DismissableFalse = () => ================================================ FILE: apps/storybook/src/components/modal/stories/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 ( <> Modal Title setIsOpen(false)} >

    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.

    ) } ================================================ FILE: apps/storybook/src/components/modal/stories/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 ( <> Modal Title setIsOpen(false)} >

    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.

    ) } ================================================ FILE: apps/storybook/src/components/modal/stories/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 ( <> Modal Title setIsOpen(false)} > ) } ================================================ FILE: apps/storybook/src/components/modal/stories/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['size'] export default function Default() { const [isOpen, setIsOpen] = React.useState(false) const [modalSize, setModalSize] = React.useState('md') const sizes: Size[] = ['xs', 'sm', 'md', 'lg', 'xl', 'full'] const handlePress = (size: Size, open: boolean) => { setModalSize(size) setIsOpen(open) } return ( <>
    {sizes.map((size, idx) => ( ))}
    Modal Title setIsOpen(false)} >

    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.

    ) } ================================================ FILE: apps/storybook/src/components/number-field/number-field.stories.tsx ================================================ import { NumberField } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import MobileStepperStory from './stories/with-mobile-stepper' import StepperStory from './stories/with-stepper' const meta: Meta = { title: 'NumberField', component: NumberField, } export default meta export const Default = () => export const Stepper = () => export const MobileStepper = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/number-field/stories/default.tsx ================================================ import { Input, Label, NumberField } from 'ui' export default function Default() { return ( ) } ================================================ FILE: apps/storybook/src/components/number-field/stories/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 ( ) } ================================================ FILE: apps/storybook/src/components/number-field/stories/with-mobile-stepper.tsx ================================================ import { ChevronDown, ChevronUp } from 'lucide-react' import { IconButton, Input, Label, NumberField, NumberInputGroup } from 'ui' export default function Mobile() { return ( ) } ================================================ FILE: apps/storybook/src/components/number-field/stories/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 ( ) } ================================================ FILE: apps/storybook/src/components/progress-bar/progress-bar.stories.tsx ================================================ import { ProgressBar } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' const meta: Meta = { title: 'ProgressBar', component: ProgressBar, } export default meta export const Default = () => ================================================ FILE: apps/storybook/src/components/progress-bar/stories/default.tsx ================================================ import { Label, ProgressBar, ProgressBarFilledTrack, ProgressBarTrack, } from 'ui' export default function Default() { return ( {({ percentage }) => ( <> )} ) } ================================================ FILE: apps/storybook/src/components/radio/radio.stories.tsx ================================================ import { Radio } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import SizesStory from './stories/sizes' const meta: Meta = { title: 'Radio', component: Radio, } export default meta export const Default = () => export const Sizes = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/radio/stories/default.tsx ================================================ import { Radio, RadioGroup } from 'ui' export default function Default() { return ( Cat Dog ) } ================================================ FILE: apps/storybook/src/components/radio/stories/disabled.tsx ================================================ import { Radio, RadioGroup } from 'ui' export default function Default() { return ( Cat Dog ) } ================================================ FILE: apps/storybook/src/components/radio/stories/sizes.tsx ================================================ import { Radio, RadioGroup } from 'ui' export default function Sizes() { return (
    Small Cat Small Dog Medium Cat Medium Dog Large Cat Large Dog
    ) } ================================================ FILE: apps/storybook/src/components/radio-group/radio-group.stories.tsx ================================================ import { RadioGroup } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import HorizontalStory from './stories/horizontal' const meta: Meta = { title: 'RadioGroup', component: RadioGroup, } export default meta export const Default = () => export const Horizontal = () => ================================================ FILE: apps/storybook/src/components/radio-group/stories/default.tsx ================================================ import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui' export default function Default() { return ( Dog Cat Dragon ) } ================================================ FILE: apps/storybook/src/components/radio-group/stories/disabled.tsx ================================================ import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui' export default function Disabled() { return ( Dog Cat Dragon ) } ================================================ FILE: apps/storybook/src/components/radio-group/stories/horizontal.tsx ================================================ import { Label, Radio, RadioGroup, RadioGroupContent } from 'ui' export default function Horizontal() { return ( Dog Cat Dragon ) } ================================================ FILE: apps/storybook/src/components/range-calendar/range-calendar.stories.tsx ================================================ import { RangeCalendar } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' const meta: Meta = { title: 'RangeCalendar', component: RangeCalendar, } export default meta export const Default = () => ================================================ FILE: apps/storybook/src/components/range-calendar/stories/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 ( {(day) => {day}} {(date) => } ) } ================================================ FILE: apps/storybook/src/components/search-field/search-field.stories.tsx ================================================ import { SearchField } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import WithClearButtonStory from './stories/with-clear-button' const meta: Meta = { title: 'SearchField', component: SearchField, } export default meta export const Default = () => export const WithClearButton = () => ================================================ FILE: apps/storybook/src/components/search-field/stories/default.tsx ================================================ import { Search } from 'lucide-react' import { Label, SearchField, SearchFieldInput } from 'ui' export default function Default() { return (
    ) } ================================================ FILE: apps/storybook/src/components/search-field/stories/with-clear-button.tsx ================================================ import { Search } from 'lucide-react' import { Label, SearchField, SearchFieldClearButton, SearchFieldInput, } from 'ui' export default function WithClearButton() { return (
    ) } ================================================ FILE: apps/storybook/src/components/select/select.stories.tsx ================================================ import { Select } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' const meta: Meta = { title: 'Select', component: Select, } export default meta export const Default = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/select/stories/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 ( <> ) } ================================================ FILE: apps/storybook/src/components/select/stories/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 ( <> ) } ================================================ FILE: apps/storybook/src/components/slider/slider.stories.tsx ================================================ import { Slider } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import VerticalStory from './stories/vertical' const meta: Meta = { title: 'Slider', component: Slider, } export default meta export const Default = () => export const Vertical = () => ================================================ FILE: apps/storybook/src/components/slider/stories/default.tsx ================================================ import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui' export default function Default() { return ( {({ state }) => ( <> )} ) } ================================================ FILE: apps/storybook/src/components/slider/stories/vertical.tsx ================================================ import { Label, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from 'ui' export default function Vertical() { return ( {({ state }) => ( <> )} ) } ================================================ FILE: apps/storybook/src/components/switch/stories/alignment.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Alignment() { return (
    I'm on the right I'm on the left
    ) } ================================================ FILE: apps/storybook/src/components/switch/stories/default.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Default() { return ( Low power mode ) } ================================================ FILE: apps/storybook/src/components/switch/stories/disabled.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Default() { return ( Low power mode ) } ================================================ FILE: apps/storybook/src/components/switch/stories/sizes.tsx ================================================ import { Switch, SwitchIndicator } from 'ui' export default function Default() { return (
    ) } ================================================ FILE: apps/storybook/src/components/switch/switch.stories.tsx ================================================ import { Switch } from 'ui' import { type Meta } from '@storybook/react' import AlignmentStory from './stories/alignment' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import SizesStory from './stories/sizes' const meta: Meta = { title: 'Switch', component: Switch, } export default meta export const Default = () => export const Alignment = () => export const Sizes = () => export const Disabled = () => ================================================ FILE: apps/storybook/src/components/tabs/stories/default.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function Default() { return ( Founding of Rome Monarchy and Republic Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/storybook/src/components/tabs/stories/disabled-keys.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function DisabledKeys() { return ( Founding of Rome Monarchy and Republic Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/storybook/src/components/tabs/stories/disabled.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function Disabled() { return ( Founding of Rome Monarchy and Republic Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/storybook/src/components/tabs/stories/vertical.tsx ================================================ import { Tab, TabList, TabPanel, Tabs } from 'ui' export default function Vertical() { return ( Founding of Rome Monarchy and Empire Arma virumque cano, Troiae qui primus ab oris. Senatus Populusque Romanus. Alea jacta est. ) } ================================================ FILE: apps/storybook/src/components/tabs/tabs.stories.tsx ================================================ import { Tabs } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import DisabledKeysStory from './stories/disabled-keys' import VerticalStory from './stories/vertical' const meta: Meta = { title: 'Tabs', component: Tabs, } export default meta export const Default = () => export const Vertical = () => export const Disabled = () => export const DisabledKeys = () => ================================================ FILE: apps/storybook/src/components/text-field/stories/default.tsx ================================================ import { Input, Label, TextField } from 'ui' export default function Default() { return ( ) } ================================================ FILE: apps/storybook/src/components/text-field/stories/disabled.tsx ================================================ import { Input, Label, TextField } from 'ui' export default function Default() { return ( ) } ================================================ FILE: apps/storybook/src/components/text-field/stories/with-error.tsx ================================================ import { Input, Label, TextField, TextFieldErrorMessage } from 'ui' export default function withError() { return ( This is an error message ) } ================================================ FILE: apps/storybook/src/components/text-field/text-field.stories.tsx ================================================ import { TextField } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import DisabledStory from './stories/disabled' import WithErrorStory from './stories/with-error' const meta: Meta = { title: 'TextField', component: TextField, } export default meta export const Default = () => export const Disabled = () => export const WithError = () => ================================================ FILE: apps/storybook/src/components/tooltip/stories/default.tsx ================================================ import { Button, Tooltip, TooltipContent } from 'ui' export default function Default() { return ( Hello! ) } ================================================ FILE: apps/storybook/src/components/tooltip/stories/placement.tsx ================================================ import { type TooltipProps } from 'react-aria-components' import { Button, Tooltip, TooltipContent } from 'ui' type Placement = Pick['placement'] export default function Placement() { const placements: Placement[] = [ 'bottom', 'bottom left', 'bottom right', 'bottom start', 'bottom end', 'top', 'top left', 'top right', 'top start', 'top end', 'left', 'left top', 'left bottom', 'start', 'start top', 'start bottom', 'right', 'right top', 'right bottom', 'end', 'end top', 'end bottom', ] return (
    {placements.map((placement, idx) => ( Hello! ))}
    ) } ================================================ FILE: apps/storybook/src/components/tooltip/tooltip.stories.tsx ================================================ import { Tooltip } from 'ui' import { type Meta } from '@storybook/react' import DefaultStory from './stories/default' import PlacementStory from './stories/placement' const meta: Meta = { title: 'Tooltip', component: Tooltip, } export default meta export const Default = () => export const Placement = () => ================================================ FILE: apps/storybook/src/styles.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; ================================================ FILE: apps/storybook/tailwind.config.cjs ================================================ /** @type {import('tailwindcss').Config} */ // eslint-disable-next-line @typescript-eslint/no-var-requires const sharedConfig = require('tailwind-config/tailwind.config.cjs') module.exports = { presets: [sharedConfig], content: [ './.storybook/**/*.{js,ts,jsx,tsx}', './src/**/*.{js,ts,jsx,tsx}', '../../packages/**/*.{js,ts,jsx,tsx}', ], } ================================================ FILE: apps/storybook/tsconfig.json ================================================ { "extends": "ts-config/base.json", "include": ["."], "exclude": ["node_modules"], "compilerOptions": { "jsx": "react-jsx", }, } ================================================ FILE: package.json ================================================ { "name": "draft-ui", "scripts": { "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run lint", "storybook": "turbo run storybook", "prepare": "husky install", "build-registry": "turbo run build-registry", "typecheck": "turbo run typecheck" }, "devDependencies": { "@ianvs/prettier-plugin-sort-imports": "^3.7.2", "eslint": "^8.56.0", "eslint-config-custom": "workspace:*", "husky": "^8.0.3", "lint-staged": "^15.2.0", "prettier": "^2.8.8", "ts-config": "workspace:*", "turbo": "^1.11.3" }, "lint-staged": { "**/*.{js,jsx,cjs,mjs,ts,tsx,json}": [ "eslint --fix" ] } } ================================================ FILE: packages/eslint-config-custom/index.js ================================================ module.exports = { parser: '@typescript-eslint/parser', extends: [ 'next', 'turbo', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', 'plugin:tailwindcss/recommended', ], parserOptions: { ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features sourceType: 'module', // Allows for the use of imports }, plugins: ['@typescript-eslint/eslint-plugin'], rules: { '@next/next/no-html-link-for-pages': 'off', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/ban-ts-comment': 'off', 'react/react-in-jsx-scope': 'off', 'react/prop-types': 'off', 'prettier/prettier': 'error', '@typescript-eslint/no-unused-vars': [ 'warn', { varsIgnorePattern: '^_', argsIgnorePattern: '^_', destructuredArrayIgnorePattern: '^_', }, ], '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/consistent-type-imports': [ 'error', { prefer: 'type-imports', fixStyle: 'inline-type-imports' }, ], 'tailwindcss/no-custom-classname': 'off', }, settings: { react: { version: 'detect', }, tailwindcss: { callees: ['cva', 'cn', 'clsx'], }, }, } ================================================ FILE: packages/eslint-config-custom/package.json ================================================ { "name": "eslint-config-custom", "version": "0.0.0", "main": "index.js", "publishConfig": { "access": "public" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.59.2", "@typescript-eslint/parser": "^5.59.2", "eslint": "^8.39.0", "eslint-config-next": "^13.3.4", "eslint-config-prettier": "^9.0.0", "eslint-config-turbo": "^1.9.3", "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "7.32.2", "eslint-plugin-tailwindcss": "^3.13.0", "typescript": "^5.1.6" } } ================================================ FILE: packages/postcss-config/package.json ================================================ { "name": "postcss-config", "dependencies": { "postcss": "^8.4.23" } } ================================================ FILE: packages/postcss-config/postcss.config.cjs ================================================ /** @type {import('postcss').Config} */ module.exports = { plugins: { 'tailwindcss/nesting': {}, tailwindcss: {}, autoprefixer: {}, }, } ================================================ FILE: packages/tailwind-config/package.json ================================================ { "name": "tailwind-config", "dependencies": { "tailwindcss": "^3.4.1", "tailwindcss-animate": "^1.0.7", "tailwindcss-react-aria-components": "1.0.0" } } ================================================ FILE: packages/tailwind-config/tailwind.config.cjs ================================================ /** @type {import('tailwindcss').Config} */ module.exports = { darkMode: ['class'], theme: { extend: {}, }, plugins: [ require('tailwindcss-animate'), require('tailwindcss-react-aria-components'), ], // safelist: [ // { // pattern: /react-aria-.+/, // }, // ], } ================================================ FILE: packages/ts-config/base.json ================================================ { "$schema": "https://json.schemastore.org/tsconfig", "display": "Default", "compilerOptions": { "composite": false, "declaration": true, "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "inlineSources": false, "isolatedModules": true, "moduleResolution": "node", "noUnusedLocals": false, "noUnusedParameters": false, "preserveWatchOutput": true, "skipLibCheck": true, "strict": true }, "include": ["**/*.ts", "**/*.tsx"], "exclude": ["node_modules", "**/*.cjs"] } ================================================ FILE: packages/ts-config/nextjs.json ================================================ { "$schema": "https://json.schemastore.org/tsconfig", "display": "Next.js", "compilerOptions": { "plugins": [ { "name": "next" } ], "allowJs": true, "declaration": false, "declarationMap": false, "incremental": true, "jsx": "preserve", "lib": ["dom", "dom.iterable", "esnext"], "module": "esnext", "noEmit": true, "resolveJsonModule": true, "strict": false, "target": "es5" }, "include": ["src", "next-env.d.ts"], "exclude": ["node_modules"] } ================================================ FILE: packages/ts-config/package.json ================================================ { "name": "ts-config", "version": "0.0.0", "private": true, "license": "MIT", "publishConfig": { "access": "public" } } ================================================ FILE: packages/ts-config/react-library.json ================================================ { "$schema": "https://json.schemastore.org/tsconfig", "display": "React Library", "extends": "./base.json", "compilerOptions": { "jsx": "react-jsx", "lib": ["ES2015", "DOM"], "module": "ESNext", "target": "es6" } } ================================================ FILE: packages/ui/.eslintrc.js ================================================ module.exports = { root: true, extends: ['custom'], } ================================================ FILE: packages/ui/.gitignore ================================================ .turbo dist/ ================================================ FILE: packages/ui/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: packages/ui/package.json ================================================ { "name": "ui", "version": "0.1.0", "main": "./src/index.tsx", "types": "./src/index.tsx", "license": "MIT", "scripts": { "lint": "eslint --ignore-path .gitignore '**/*.{js,jsx,cjs,mjs,ts,tsx,json}'", "typecheck": "tsc --noEmit --pretty" }, "peerDependencies": { "react": "^18.2.0" }, "dependencies": { "cva": "1.0.0-beta.1", "lucide-react": "^0.259.0", "react-aria-components": "1.0.0", "tailwind-merge": "^1.13.2" }, "devDependencies": { "@types/react": "18.0.27", "eslint": "^8.37.0", "eslint-config-custom": "workspace:*", "postcss": "^8.4.21", "postcss-config": "workspace:*", "react": "^18.2.0", "tailwind-config": "workspace:*", "ts-config": "workspace:*", "typescript": "^5.1.6" } } ================================================ FILE: packages/ui/postcss.config.cjs ================================================ /** @type {import('postcss').Config} */ module.exports = require('postcss-config/postcss.config.cjs') ================================================ FILE: packages/ui/src/breadcrumbs.tsx ================================================ import * as React from 'react' import * as ReactAria from 'react-aria-components' import { cx } from '../lib/cva.config' export const Breadcrumbs = ({ className, ...props }: ReactAria.BreadcrumbsProps) => { return ( ) } export interface BreadcrumbItemProps extends ReactAria.BreadcrumbProps { separator?: React.ReactNode } export const BreadcrumbItem = ({ separator, children, ...props }: BreadcrumbItemProps) => { return ( {children} {separator ? ( ) : null} ) } export const BreadcrumbLink = ({ children, className, ...props }: ReactAria.LinkProps) => { return ( {children} ) } ================================================ FILE: packages/ui/src/button.tsx ================================================ import { type VariantProps } from 'cva' import * as ReactAria from 'react-aria-components' import { cva, cx } from '../lib/cva.config' export const buttonVariants = cva({ base: [ 'inline-flex items-center justify-center rounded-md font-semibold outline-none transition-colors', // Focus 'focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 dark:focus:ring-slate-400 dark:focus:ring-offset-slate-900', // Disabled 'disabled:pointer-events-none disabled:opacity-40', ], variants: { variant: { solid: 'bg-slate-900 text-white open:bg-slate-100 hover:bg-slate-700 dark:bg-slate-50 dark:text-slate-900 dark:open:bg-slate-800 dark:hover:bg-slate-200', destructive: 'bg-red-600 text-white hover:bg-red-700 dark:hover:bg-red-700', outline: 'border border-slate-200 bg-transparent hover:bg-slate-100 focus:bg-slate-100 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-slate-700 dark:focus:bg-slate-700', subtle: 'bg-slate-100 text-slate-900 hover:bg-slate-200 focus:bg-slate-200 dark:bg-slate-700 dark:text-slate-100 dark:hover:bg-slate-700 dark:focus:bg-slate-700', ghost: 'bg-transparent open:bg-transparent hover:bg-slate-100 focus:bg-slate-100 dark:text-slate-100 dark:open:bg-transparent dark:hover:bg-slate-800 dark:hover:text-slate-100 dark:focus:bg-slate-800 dark:focus:text-slate-100', link: 'bg-transparent text-slate-900 underline-offset-4 hover:bg-transparent hover:underline focus:bg-transparent focus:underline dark:bg-transparent dark:text-slate-100 dark:hover:bg-transparent dark:focus:bg-transparent', }, size: { lg: 'h-12 px-6 text-lg', md: 'h-10 px-4 text-base', sm: 'h-8 px-3 text-sm', xs: 'h-6 px-2 text-xs', }, }, defaultVariants: { variant: 'solid', size: 'md', }, }) export interface ButtonProps extends ReactAria.ButtonProps, VariantProps { className?: string } export const Button = ({ className, variant, size, ...props }: ButtonProps) => { return ( ) } ================================================ FILE: packages/ui/src/calendar.tsx ================================================ import * as React from 'react' import * as ReactAria from 'react-aria-components' import { cx } from '../lib/cva.config' export const Calendar = ({ className, ...props }: ReactAria.CalendarProps) => { return ( ) } export const RangeCalendar = ({ className, ...props }: ReactAria.RangeCalendarProps) => { return ( ) } export const CalendarGrid = ({ className, ...props }: ReactAria.CalendarGridProps) => { return } export const CalendarGridHeader = ( props: ReactAria.CalendarGridHeaderProps, ) => { return } export const CalendarHeaderCell = ({ className, ...props }: ReactAria.CalendarHeaderCellProps) => { return ( ) } export const CalendarGridBody = ({ className, ...props }: ReactAria.CalendarGridBodyProps) => { return ( ) } export const CalendarCell = ({ className, ...props }: ReactAria.CalendarCellProps) => { return ( ) } export const CalendarHeading = ({ className, ...props }: ReactAria.HeadingProps) => { return ( ) } export const CalendarHeader = ({ className, ...props }: React.HTMLAttributes) => { return (
    ) } export const CalendarFooter = ({ className, ...props }: React.HTMLAttributes) => { return