├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .husky └── commit-msg ├── .nvmrc ├── .storybook ├── main.js ├── manager.js ├── preview-head.html ├── preview.js └── storybook-logo.svg ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── apps └── www │ ├── next.config.mjs │ ├── package.json │ ├── postcss.config.mjs │ ├── public │ ├── favicon.svg │ ├── images │ │ └── v2.0 │ │ │ ├── cli.jpg │ │ │ ├── new-components.jpg │ │ │ ├── sidebar.png │ │ │ └── variant-props.jpg │ ├── open-graphs │ │ ├── og-browse-components.png │ │ ├── og-installation.png │ │ ├── og-website.png │ │ └── updates │ │ │ └── v2.0.webp │ ├── registry │ │ ├── .auto-generated │ │ └── components │ │ │ ├── accordion.json │ │ │ ├── animated-tabs.json │ │ │ ├── badge.json │ │ │ ├── button.json │ │ │ ├── card.json │ │ │ ├── checkbox.json │ │ │ ├── dialog.json │ │ │ ├── dropdown-menu.json │ │ │ ├── index.json │ │ │ ├── input.json │ │ │ ├── multi-step-modal.json │ │ │ ├── spinner.json │ │ │ ├── switch.json │ │ │ ├── text.json │ │ │ └── tooltip.json │ └── videos │ │ └── v2.0 │ │ ├── cli.mp4 │ │ ├── new-components.mp4 │ │ └── variant-props.mp4 │ ├── src │ ├── @types │ │ ├── docs.ts │ │ └── images.d.ts │ ├── app │ │ ├── (home) │ │ │ ├── _components │ │ │ │ ├── AnimateEnter.tsx │ │ │ │ ├── BlurBackground.tsx │ │ │ │ ├── FloatToggleTheme.tsx │ │ │ │ ├── GridBackground.tsx │ │ │ │ ├── components-section │ │ │ │ │ ├── ComponentsExample.tsx │ │ │ │ │ ├── ComponentsSection.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── feedbacks-section │ │ │ │ │ ├── FeedbacksCard.tsx │ │ │ │ │ ├── FeedbacksSection.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── hero-section │ │ │ │ │ ├── AnimatedBadge.tsx │ │ │ │ │ ├── AnimatedNumber.tsx │ │ │ │ │ ├── HeroContent.tsx │ │ │ │ │ ├── HeroSection.tsx │ │ │ │ │ ├── Spotlight.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── slogan-section │ │ │ │ │ ├── GalleryButton.tsx │ │ │ │ │ ├── GetStartedButton.tsx │ │ │ │ │ ├── SloganSection.tsx │ │ │ │ │ ├── TypewriterTitle.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── techs-section │ │ │ │ │ ├── Techs.tsx │ │ │ │ │ ├── TechsSection.tsx │ │ │ │ │ └── index.ts │ │ │ └── page.tsx │ │ ├── _components │ │ │ ├── BlurImage.tsx │ │ │ ├── ButtonGlitchBrightness.tsx │ │ │ ├── Divider.tsx │ │ │ ├── Footer.tsx │ │ │ ├── GradientLine.tsx │ │ │ ├── Icons.tsx │ │ │ ├── OldMultiStepModal.tsx │ │ │ ├── RequestComponentButton.tsx │ │ │ ├── TextAnimateEnter.tsx │ │ │ ├── TextMorph.tsx │ │ │ ├── mdx │ │ │ │ ├── MDXComponents.tsx │ │ │ │ └── index.ts │ │ │ └── ui │ │ │ │ ├── accordion.tsx │ │ │ │ ├── animated-tabs.tsx │ │ │ │ ├── badge.tsx │ │ │ │ ├── button.tsx │ │ │ │ ├── card.tsx │ │ │ │ ├── checkbox.tsx │ │ │ │ ├── dialog.tsx │ │ │ │ ├── dropdown-menu.tsx │ │ │ │ ├── input.tsx │ │ │ │ ├── multi-step-modal.tsx │ │ │ │ ├── spinner.tsx │ │ │ │ ├── switch.tsx │ │ │ │ ├── text.tsx │ │ │ │ └── tooltip.tsx │ │ ├── _docs │ │ │ ├── accordion.mdx │ │ │ ├── animated-tabs.mdx │ │ │ ├── badge.mdx │ │ │ ├── button.mdx │ │ │ ├── card.mdx │ │ │ ├── checkbox.mdx │ │ │ ├── dialog.mdx │ │ │ ├── dropdown-menu.mdx │ │ │ ├── get-started │ │ │ │ ├── cli.mdx │ │ │ │ ├── next.mdx │ │ │ │ └── vite.mdx │ │ │ ├── input.mdx │ │ │ ├── multi-step-modal.mdx │ │ │ ├── spinner.mdx │ │ │ ├── switch.mdx │ │ │ ├── text.mdx │ │ │ ├── tooltip.mdx │ │ │ └── updates │ │ │ │ └── v2.0.mdx │ │ ├── layout.tsx │ │ ├── not-found.tsx │ │ ├── theme-provider.tsx │ │ ├── ui │ │ │ ├── [slug] │ │ │ │ └── page.tsx │ │ │ ├── _components │ │ │ │ ├── Breadcrumbs.tsx │ │ │ │ ├── CodeBlock.tsx │ │ │ │ ├── CommandBlock.tsx │ │ │ │ ├── ComponentView.tsx │ │ │ │ ├── CopyCode.tsx │ │ │ │ ├── Drawer.tsx │ │ │ │ ├── Header.tsx │ │ │ │ ├── OnThisPage.tsx │ │ │ │ ├── Pagination.tsx │ │ │ │ ├── Tabs.tsx │ │ │ │ ├── ToggleTheme.tsx │ │ │ │ ├── cmdk │ │ │ │ │ ├── CommandMenu.tsx │ │ │ │ │ ├── CommandMenuPrimitives.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── examples │ │ │ │ │ ├── AccordionExample.tsx │ │ │ │ │ ├── CheckboxExample.tsx │ │ │ │ │ ├── DialogExample.tsx │ │ │ │ │ ├── DropdownMenuExample.tsx │ │ │ │ │ ├── MultiStepModalExample.tsx │ │ │ │ │ ├── SwitchExample.tsx │ │ │ │ │ └── TooltipExample.tsx │ │ │ │ └── sidebar │ │ │ │ │ ├── Sidebar.tsx │ │ │ │ │ └── SidebarButton.tsx │ │ │ ├── cli │ │ │ │ └── page.tsx │ │ │ ├── installation │ │ │ │ ├── [slug] │ │ │ │ │ └── page.tsx │ │ │ │ ├── _components │ │ │ │ │ └── Card.tsx │ │ │ │ ├── _data │ │ │ │ │ └── installation.tsx │ │ │ │ └── page.tsx │ │ │ └── layout.tsx │ │ └── updates │ │ │ ├── [slug] │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ ├── assets │ │ └── icons │ │ │ ├── code │ │ │ ├── dark-mode.json │ │ │ └── light-mode.json │ │ │ ├── file │ │ │ ├── dark-mode.json │ │ │ └── light-mode.json │ │ │ ├── home │ │ │ ├── dark-mode.json │ │ │ └── light-mode.json │ │ │ ├── search-icon.json │ │ │ ├── thunder │ │ │ ├── dark-mode.json │ │ │ └── light-mode.json │ │ │ └── updates │ │ │ ├── dark-mode.json │ │ │ └── light-mode.json │ ├── data │ │ ├── get-started.ts │ │ ├── techs.tsx │ │ └── updates.ts │ ├── lib │ │ └── mdx.ts │ ├── styles │ │ ├── globals.css │ │ └── luxe.css │ └── utils │ │ ├── cn.ts │ │ ├── detect-os.ts │ │ ├── fonts.ts │ │ ├── get-components.ts │ │ ├── get-file-content.ts │ │ └── shiki.ts │ └── tsconfig.json ├── biome.json ├── commitlint.config.js ├── config └── ts-config │ ├── base.json │ ├── package.json │ └── react.json ├── package.json ├── packages ├── cli │ ├── package.json │ ├── src │ │ ├── commands │ │ │ ├── add │ │ │ │ ├── handler.ts │ │ │ │ ├── index.ts │ │ │ │ ├── preflight.ts │ │ │ │ └── utils.ts │ │ │ └── init │ │ │ │ ├── handler.ts │ │ │ │ ├── index.ts │ │ │ │ ├── preflight.ts │ │ │ │ └── utils.ts │ │ ├── index.ts │ │ ├── lib │ │ │ └── postcss │ │ │ │ ├── index.ts │ │ │ │ └── plugins.ts │ │ ├── schemas │ │ │ ├── manifest.ts │ │ │ └── registry.ts │ │ ├── services │ │ │ └── api-config.ts │ │ └── utils │ │ │ ├── cli-error.ts │ │ │ ├── const.ts │ │ │ ├── logger.ts │ │ │ ├── manifest-manager.ts │ │ │ ├── resolve-alias-to-absolute-path.ts │ │ │ ├── resolve-package-manager-command.ts │ │ │ └── run-shell-command.ts │ ├── tsconfig.json │ └── tsup.config.ts └── react │ ├── __stories__ │ └── components │ │ ├── accordion.stories.tsx │ │ ├── animated-tabs.stories.tsx │ │ ├── badge.stories.tsx │ │ ├── button.stories.tsx │ │ ├── card.stories.tsx │ │ ├── checkbox.stories.tsx │ │ ├── dialog.stories.tsx │ │ ├── dropdown-menu.stories.tsx │ │ ├── input.stories.tsx │ │ ├── multi-step-modal.stories.tsx │ │ ├── spinner.stories.tsx │ │ ├── switch.stories.tsx │ │ ├── text.stories.tsx │ │ └── tooltip.stories.tsx │ ├── package.json │ ├── postcss.config.mjs │ ├── src │ ├── components │ │ ├── accordion.tsx │ │ ├── animated-tabs.tsx │ │ ├── badge.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── checkbox.tsx │ │ ├── dialog.tsx │ │ ├── dropdown-menu.tsx │ │ ├── input.tsx │ │ ├── multi-step-modal.tsx │ │ ├── spinner.tsx │ │ ├── switch.tsx │ │ ├── text.tsx │ │ └── tooltip.tsx │ ├── styles │ │ ├── globals.css │ │ └── luxe.css │ └── utils │ │ └── cn.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts └── build-registry.ts ├── turbo.json └── vite.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | insert_final_newline = true 6 | end_of_line = lf 7 | indent_style = space 8 | indent_size = 2 9 | max_line_length = 80 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [guhrodrrigues] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules/ 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | coverage/ 11 | 12 | # next.js 13 | .next/ 14 | /out/ 15 | 16 | # production 17 | build/ 18 | dist/ 19 | 20 | # misc 21 | .DS_Store 22 | *.pem 23 | .turbo 24 | 25 | # debug 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | *storybook.log 30 | 31 | # local env files 32 | .env*.local 33 | 34 | # vercel 35 | .vercel 36 | 37 | # typescript 38 | *.tsbuildinfo 39 | next-env.d.ts 40 | 41 | # luxe 42 | luxe.json 43 | packages/cli/src/components 44 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | npx --no -- commitlint --edit $1 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v20.17.0 2 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | import { join, dirname } from 'node:path' 2 | 3 | /** 4 | * This function is used to resolve the absolute path of a package. 5 | * It is needed in projects that use Yarn PnP or are set up within a monorepo. 6 | */ 7 | function getAbsolutePath(value) { 8 | return dirname(require.resolve(join(value, 'package.json'))) 9 | } 10 | 11 | /** @type { import('@storybook/react-vite').StorybookConfig } */ 12 | const config = { 13 | stories: [ 14 | '../packages/react/__stories__/**/*.mdx', 15 | '../packages/react/__stories__/**/*.stories.@(ts|tsx)', 16 | ], 17 | addons: [ 18 | getAbsolutePath('@storybook/addon-onboarding'), 19 | getAbsolutePath('@storybook/addon-essentials'), 20 | getAbsolutePath('@chromatic-com/storybook'), 21 | getAbsolutePath('@storybook/addon-interactions'), 22 | getAbsolutePath('@storybook/addon-themes'), 23 | getAbsolutePath('@storybook/addon-a11y'), 24 | ], 25 | framework: { 26 | name: getAbsolutePath('@storybook/react-vite'), 27 | options: {}, 28 | }, 29 | } 30 | export default config 31 | -------------------------------------------------------------------------------- /.storybook/manager.js: -------------------------------------------------------------------------------- 1 | import { addons } from '@storybook/manager-api' 2 | import { create } from '@storybook/theming' 3 | 4 | import brandImage from './storybook-logo.svg' 5 | 6 | addons.setConfig({ 7 | theme: create({ 8 | base: 'light', 9 | brandImage, 10 | }), 11 | }) 12 | -------------------------------------------------------------------------------- /.storybook/preview-head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import '@luxe/react/styles.css' 2 | 3 | import { withThemeByClassName } from '@storybook/addon-themes' 4 | 5 | export const decorators = [ 6 | withThemeByClassName({ 7 | themes: { 8 | light: 'light', 9 | dark: 'dark', 10 | }, 11 | defaultTheme: 'light', 12 | }), 13 | ] 14 | 15 | /** @type {import('@storybook/react-vite').Preview} */ 16 | const preview = { 17 | decorators, 18 | } 19 | 20 | export default preview 21 | -------------------------------------------------------------------------------- /.storybook/storybook-logo.svg: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 15 | 19 | 23 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | The goal is to make contributing to Luxe as easy and transparent as possible, whether it's: 4 | 5 | - Reporting a bug 6 | - Discussing the current state of the code 7 | - Submitting a fix 8 | - Proposing new features 9 | 10 | ## About this repository 11 | 12 | This repository is a monorepo. 13 | 14 | - Using [pnpm](https://pnpm.io) and [`workspaces`](https://pnpm.io/workspaces) for development. 15 | - Using [Turborepo](https://turbo.build/repo) as our build system. 16 | 17 | ## Structure 18 | 19 | This repository is structured as follows: 20 | 21 | ``` 22 | apps 23 | └── www 24 | ├── app 25 | ├── _components 26 | ├── _docs 27 | ├── ui 28 | packages 29 | └── cli 30 | ``` 31 | 32 | | Path | Description | 33 | | -------------------------- | ---------------------------------------- | 34 | | `apps/www/app` | The Next.js application for the website. | 35 | | `apps/www/app/_components` | The React components for the website. | 36 | | `packages/cli` | The `@luxeui/ui` package. | 37 | 38 | ## Pull requests 39 | 40 | Pull requests are the best way to propose changes to the codebase. Pull requests are actively welcome: 41 | 42 | 1. Fork the repo and create your branch from `main`. 43 | 2. If you've changed APIs, update the documentation. 44 | 3. Ensure the test suite passes. 45 | 4. Make sure your code lints. 46 | 5. Issue that pull request. 47 | 48 | ## Report bugs using [GitHub's issues](https://github.com/guhrodrrigues/luxe/issues) 49 | 50 | GitHub issues are used to track public bugs. Report a bug by [opening a new issue](https://github.com/guhrodrrigues/luxe/issues/new)! 51 | 52 | ## Use a Consistent Coding Style 53 | 54 | - Use 2 spaces for indentation rather than tabs 55 | - You can try running `pnpm lint` for style unification 56 | 57 | ## CLI 58 | 59 | The `@luxeui/ui` package is a CLI for adding components to your project. You can find the [docs](https://luxeui.com/ui/cli). 60 | 61 | Any changes to the CLI should be made in the packages/cli directory. 62 | 63 | ## What is Accepted 64 | 65 | Contributions are welcome for: 66 | 67 | - Fixing bugs and issues 68 | - Improving CLI performance 69 | - Enhancing existing features 70 | - Adding better error handling 71 | - Improving docs 72 | - Adding new CLI commands that extend functionality 73 | 74 | ## What is Not Accepted 75 | 76 | Contributions will not be accepted for: 77 | 78 | - Creating new UI components 79 | - Adding new frameworks 80 | - Changing the core architecture without discussion 81 | - Adding features that are outside the scope of the CLI tool 82 | 83 | ## Development Process 84 | 85 | 1. Create a new branch for your feature/fix 86 | 2. Make your changes 87 | 3. Add tests if applicable 88 | 4. Update docs 89 | 5. Submit a pull request 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Gustavo Rodrigues 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![hero](apps/www/public/open-graphs/og-website.png) 2 | 3 | ### Luxe 4 | 5 | Library of copy and paste components to illuminate your applications with elegance and sophistication.
Build fast. Ship with style. 6 | 7 | See the website 8 | 9 | ### Docs 10 | 11 | https://luxeui.com/ui/installation 12 | 13 | ### Contributing 14 | 15 | Read the [contributing guide](/CONTRIBUTING.md). 16 | 17 | ### License 18 | 19 | © Licensed under the [MIT LICENSE](https://github.com/guhrodrrigues/luxe/blob/main/LICENSE). 20 | -------------------------------------------------------------------------------- /apps/www/next.config.mjs: -------------------------------------------------------------------------------- 1 | import nextMDX from "@next/mdx"; 2 | 3 | const nextConfig = { 4 | pageExtensions: ["md", "mdx", "tsx", "ts", "jsx", "js"], 5 | images: { 6 | domains: ["github.com"], 7 | }, 8 | }; 9 | 10 | const withMDX = nextMDX({ 11 | extension: /\.mdx?$/, 12 | }); 13 | 14 | export default withMDX(nextConfig); 15 | -------------------------------------------------------------------------------- /apps/www/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "www", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "biome check --write .", 10 | "prepare": "husky" 11 | }, 12 | "dependencies": { 13 | "@mdx-js/loader": "^3.1.0", 14 | "@mdx-js/mdx": "^3.1.0", 15 | "@mdx-js/react": "^3.1.0", 16 | "@next/mdx": "^15.3.0", 17 | "@radix-ui/react-accordion": "^1.2.8", 18 | "@radix-ui/react-checkbox": "^1.1.2", 19 | "@radix-ui/react-dialog": "^1.1.6", 20 | "@radix-ui/react-hover-card": "^1.1.2", 21 | "@radix-ui/react-switch": "^1.2.3", 22 | "@radix-ui/react-tabs": "^1.1.2", 23 | "@radix-ui/react-slot": "^1.2.3", 24 | "@radix-ui/react-tooltip": "^1.2.4", 25 | "clsx": "^2.1.0", 26 | "cmdk": "^1.1.1", 27 | "geist": "^1.3.1", 28 | "gray-matter": "^4.0.3", 29 | "lottie-react": "^2.4.1", 30 | "lucide-react": "^0.330.0", 31 | "motion": "^11.15.0", 32 | "next": "15.3.2", 33 | "next-mdx-remote": "^5.0.0", 34 | "next-themes": "^0.4.4", 35 | "next-view-transitions": "^0.3.4", 36 | "path": "^0.12.7", 37 | "react": "^19.0.0", 38 | "react-dom": "^19.0.0", 39 | "react-use-measure": "^2.1.1", 40 | "rehype-pretty-code": "^0.14.1", 41 | "rehype-slug": "^6.0.0", 42 | "remark-gfm": "^4.0.1", 43 | "tailwind-merge": "^2.2.1", 44 | "tailwind-variants": "0.2.0", 45 | "tailwindcss-animate": "^1.0.7", 46 | "unified": "^11.0.5", 47 | "usehooks-ts": "^3.1.0", 48 | "vaul": "^1.1.1" 49 | }, 50 | "devDependencies": { 51 | "@types/mdx": "^2.0.13", 52 | "@types/node": "^20", 53 | "@types/react": "^18", 54 | "@types/react-dom": "^18", 55 | "autoprefixer": "^10.0.1", 56 | "husky": "9.0.11", 57 | "postcss": "^8", 58 | "shiki": "^1.10.1", 59 | "tw-animate-css": "^1.2.8", 60 | "typescript": "^5" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /apps/www/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: { 3 | "@tailwindcss/postcss": {}, 4 | }, 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /apps/www/public/images/v2.0/cli.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/images/v2.0/cli.jpg -------------------------------------------------------------------------------- /apps/www/public/images/v2.0/new-components.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/images/v2.0/new-components.jpg -------------------------------------------------------------------------------- /apps/www/public/images/v2.0/sidebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/images/v2.0/sidebar.png -------------------------------------------------------------------------------- /apps/www/public/images/v2.0/variant-props.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/images/v2.0/variant-props.jpg -------------------------------------------------------------------------------- /apps/www/public/open-graphs/og-browse-components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/open-graphs/og-browse-components.png -------------------------------------------------------------------------------- /apps/www/public/open-graphs/og-installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/open-graphs/og-installation.png -------------------------------------------------------------------------------- /apps/www/public/open-graphs/og-website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/open-graphs/og-website.png -------------------------------------------------------------------------------- /apps/www/public/open-graphs/updates/v2.0.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/open-graphs/updates/v2.0.webp -------------------------------------------------------------------------------- /apps/www/public/registry/.auto-generated: -------------------------------------------------------------------------------- 1 | The files inside this folder are auto-generated by the registry script. 2 | -------------------------------------------------------------------------------- /apps/www/public/registry/components/accordion.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "accordion", 3 | "externalDependencies": [ 4 | "@radix-ui/react-accordion" 5 | ], 6 | "internalDependencies": [], 7 | "file": { 8 | "name": "accordion.tsx", 9 | "content": "import * as RadixAccordion from '@radix-ui/react-accordion'\r\n\r\nimport { cn } from '<%= it.aliases.utils %>/cn'\r\n\r\nexport const Accordion = RadixAccordion.Root\r\n\r\ntype AccordionItemProps = React.ComponentProps\r\n\r\nexport function AccordionItem({\r\n children,\r\n value,\r\n className,\r\n ...props\r\n}: AccordionItemProps) {\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n\r\ntype AccordionTriggerProps = React.ComponentProps\r\n\r\nexport function AccordionTrigger({\r\n children,\r\n className,\r\n ...props\r\n}: AccordionTriggerProps) {\r\n return (\r\n \r\n svg]:rotate-45',\r\n className,\r\n )}\r\n {...props}\r\n >\r\n {children}\r\n \r\n Trigger\r\n \r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\ntype AccordionContentProps = React.ComponentProps\r\n\r\nexport function AccordionContent({\r\n children,\r\n className,\r\n ...props\r\n}: AccordionContentProps) {\r\n return (\r\n \r\n
{children}
\r\n \r\n )\r\n}\r\n" 10 | } 11 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/animated-tabs.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "animated-tabs", 3 | "externalDependencies": [], 4 | "internalDependencies": [], 5 | "file": { 6 | "name": "animated-tabs.tsx", 7 | "content": "'use client' // @NOTE: Add in case you are using Next.js\r\n\r\nimport { useEffect, useRef, useState } from 'react'\r\n\r\nimport { cn } from '<%= it.aliases.utils %>/cn'\r\n\r\ntype AnimatedTabsProps = {\r\n tabs: Array\r\n}\r\n\r\nexport function AnimatedTabs({ tabs }: AnimatedTabsProps) {\r\n const [activeTab, setActiveTab] = useState(tabs[0])\r\n\r\n const containerRef = useRef(null)\r\n const activeTabRef = useRef(null)\r\n\r\n useEffect(() => {\r\n const container = containerRef.current\r\n\r\n if (container && activeTab) {\r\n const activeTabElement = activeTabRef.current\r\n\r\n if (activeTabElement) {\r\n const { offsetLeft, offsetWidth } = activeTabElement\r\n\r\n const clipLeft = offsetLeft\r\n const clipRight = offsetLeft + offsetWidth\r\n\r\n container.style.clipPath = `inset(0 ${Number(100 - (clipRight / container.offsetWidth) * 100).toFixed()}% 0 ${Number((clipLeft / container.offsetWidth) * 100).toFixed()}% round 17px)`\r\n }\r\n }\r\n }, [activeTab])\r\n\r\n return (\r\n
\r\n \r\n
\r\n {tabs.map((tab, index) => (\r\n setActiveTab(tab)}\r\n className={cn(\r\n 'flex h-8 items-center rounded-full p-3 font-medium text-primary-invert text-sm/5.5',\r\n )}\r\n tabIndex={-1}\r\n >\r\n {tab}\r\n \r\n ))}\r\n
\r\n
\r\n
\r\n {tabs.map((tab, index) => {\r\n const isActive = activeTab === tab\r\n\r\n return (\r\n setActiveTab(tab)}\r\n className='flex h-8 items-center rounded-full p-3 font-medium text-primary-muted text-sm/5.5'\r\n >\r\n {tab}\r\n \r\n )\r\n })}\r\n
\r\n \r\n )\r\n}\r\n" 8 | } 9 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/checkbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "checkbox", 3 | "externalDependencies": [ 4 | "@radix-ui/react-checkbox" 5 | ], 6 | "internalDependencies": [], 7 | "file": { 8 | "name": "checkbox.tsx", 9 | "content": "\"use client\"; // @NOTE: Add in case you are using Next.js\r\n\r\nimport * as RadixCheckbox from \"@radix-ui/react-checkbox\";\r\n\r\nimport { AnimatePresence, motion } from \"motion/react\";\r\n\r\ntype CheckboxProps = React.CustomComponentPropsWithRef<\r\n typeof RadixCheckbox.Root\r\n>;\r\n\r\nexport function Checkbox(props: CheckboxProps) {\r\n const { checked } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\ntype CheckIconProps = {\r\n checkedState: CheckboxProps[\"checked\"];\r\n};\r\n\r\nfunction CheckIcon({ checkedState }: CheckIconProps) {\r\n const CHECK_PATH = \"M5 13 L10 18 L20 6\";\r\n const INDETERMINATE_PATH = \"M6 12 H18\";\r\n\r\n return (\r\n \r\n Check\r\n\r\n \r\n \r\n );\r\n}\r\n" 10 | } 11 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/dialog.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dialog", 3 | "externalDependencies": [ 4 | "@radix-ui/react-dialog" 5 | ], 6 | "internalDependencies": [], 7 | "file": { 8 | "name": "dialog.tsx", 9 | "content": "import * as RadixDialog from '@radix-ui/react-dialog'\r\n\r\nimport { cn } from '<%= it.aliases.utils %>/cn'\r\n\r\nexport const Dialog = RadixDialog.Root\r\n\r\nexport const DialogTrigger = RadixDialog.Trigger\r\n\r\nexport const DialogClose = RadixDialog.Close\r\n\r\nfunction DialogOverlay() {\r\n return (\r\n \r\n \r\n \r\n )\r\n}\r\n\r\ntype DialogContentProps = React.ComponentProps\r\n\r\nexport function DialogContent({\r\n children,\r\n className,\r\n ...props\r\n}: DialogContentProps) {\r\n return (\r\n \r\n \r\n \r\n {children}\r\n \r\n \r\n )\r\n}\r\n\r\ntype DialogTitleProps = React.ComponentProps\r\n\r\nexport function DialogTitle({\r\n children,\r\n className,\r\n ...props\r\n}: DialogTitleProps) {\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n\r\ntype DialogDescriptionProps = React.ComponentProps<\r\n typeof RadixDialog.Description\r\n>\r\n\r\nexport function DialogDescription({\r\n children,\r\n className,\r\n ...props\r\n}: DialogDescriptionProps) {\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n\r\ntype DialogFooterProps = React.ComponentProps<'div'>\r\n\r\nexport function DialogFooter({\r\n children,\r\n className,\r\n ...props\r\n}: DialogFooterProps) {\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n" 10 | } 11 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "components": [ 3 | "tooltip", 4 | "text", 5 | "switch", 6 | "spinner", 7 | "multi-step-modal", 8 | "input", 9 | "dropdown-menu", 10 | "dialog", 11 | "checkbox", 12 | "card", 13 | "button", 14 | "badge", 15 | "animated-tabs", 16 | "accordion" 17 | ] 18 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "input", 3 | "externalDependencies": [], 4 | "internalDependencies": [], 5 | "file": { 6 | "name": "input.tsx", 7 | "content": "\"use client\"; // @NOTE: Add in case you are using Next.js\r\n\r\nimport { useState } from \"react\";\r\n\r\nimport { AnimatePresence, motion, type Variants } from \"motion/react\";\r\n\r\nimport { cn } from '<%= it.aliases.utils %>/cn';\r\n\r\nexport type InputProps = React.ComponentPropsWithRef<\"input\">;\r\ntype FieldState = \"idle\" | \"filled\";\r\n\r\nexport function Input({\r\n placeholder,\r\n onChange,\r\n className,\r\n ...props\r\n}: InputProps) {\r\n const [fieldState, setFieldState] = useState(\"idle\");\r\n\r\n const animatedPlaceholderVariants: Variants = {\r\n show: {\r\n x: 0,\r\n opacity: 1,\r\n filter: \"blur(var(--blur-none))\",\r\n },\r\n hidden: {\r\n x: 28,\r\n opacity: 0,\r\n filter: \"blur(var(--blur-xs))\",\r\n },\r\n };\r\n\r\n return (\r\n \r\n {\r\n setFieldState(event.target.value.length > 0 ? \"filled\" : \"idle\");\r\n onChange?.(event);\r\n }}\r\n />\r\n\r\n \r\n {fieldState !== \"filled\" && (\r\n \r\n {placeholder}\r\n \r\n )}\r\n \r\n \r\n );\r\n}\r\n" 8 | } 9 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/spinner.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "spinner", 3 | "externalDependencies": [], 4 | "internalDependencies": [], 5 | "file": { 6 | "name": "spinner.tsx", 7 | "content": "import { cn } from '<%= it.aliases.utils %>/cn'\r\n\r\ntype SpinnerProps = {\r\n size?: string\r\n} & React.ComponentProps<'div'>\r\n\r\nexport function Spinner({\r\n size = 'size-6',\r\n className,\r\n ...props\r\n}: SpinnerProps) {\r\n const bars = Array(12).fill(0)\r\n\r\n return (\r\n
\r\n
\r\n {bars.map((_, i) => (\r\n \r\n ))}\r\n
\r\n
\r\n )\r\n}\r\n" 8 | } 9 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/switch.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "switch", 3 | "externalDependencies": [ 4 | "@radix-ui/react-switch" 5 | ], 6 | "internalDependencies": [], 7 | "file": { 8 | "name": "switch.tsx", 9 | "content": "import * as RadixSwitch from '@radix-ui/react-switch'\r\n\r\nimport { cn } from '<%= it.aliases.utils %>/cn'\r\n\r\nexport type SwitchProps = React.ComponentProps\r\n\r\nexport function Switch({ className, ...props }: SwitchProps) {\r\n return (\r\n \r\n \r\n \r\n )\r\n}\r\n" 10 | } 11 | } -------------------------------------------------------------------------------- /apps/www/public/registry/components/tooltip.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tooltip", 3 | "externalDependencies": [ 4 | "@radix-ui/react-tooltip" 5 | ], 6 | "internalDependencies": [], 7 | "file": { 8 | "name": "tooltip.tsx", 9 | "content": "import * as RadixTooltip from '@radix-ui/react-tooltip'\r\n\r\nimport { cn } from '<%= it.aliases.utils %>/cn'\r\n\r\nexport const Tooltip = RadixTooltip.Root\r\n\r\nexport const TooltipTrigger = RadixTooltip.Trigger\r\n\r\ntype TooltipProviderProps = React.ComponentProps\r\n\r\nexport function TooltipProvider({ children, ...props }: TooltipProviderProps) {\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n\r\ntype TooltipContentProps = React.ComponentProps\r\n\r\nexport function TooltipContent({\r\n children,\r\n className,\r\n sideOffset = 6,\r\n ...props\r\n}: TooltipContentProps) {\r\n return (\r\n \r\n \r\n {children}\r\n \r\n \r\n )\r\n}\r\n" 10 | } 11 | } -------------------------------------------------------------------------------- /apps/www/public/videos/v2.0/cli.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/videos/v2.0/cli.mp4 -------------------------------------------------------------------------------- /apps/www/public/videos/v2.0/new-components.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/videos/v2.0/new-components.mp4 -------------------------------------------------------------------------------- /apps/www/public/videos/v2.0/variant-props.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guhrodrrigues/luxe/35f351c6514246a73cb0fdaa28484226f1644208/apps/www/public/videos/v2.0/variant-props.mp4 -------------------------------------------------------------------------------- /apps/www/src/@types/docs.ts: -------------------------------------------------------------------------------- 1 | export type Docs = { 2 | title: string; 3 | description: string; 4 | slug: string; 5 | date?: string; 6 | content: string; 7 | externalDocs?: string; 8 | externalApi?: string; 9 | author_image?: string; 10 | author_twitter?: string; 11 | banner?: string; 12 | author?: string; 13 | }; 14 | -------------------------------------------------------------------------------- /apps/www/src/@types/images.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.jpg' 2 | declare module '*.svg' 3 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/AnimateEnter.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { motion } from 'motion/react' 4 | 5 | import { cn } from '@/utils/cn' 6 | 7 | type AnimateEnterProps = { 8 | className?: string 9 | delay?: number 10 | children: React.ReactNode 11 | duration?: number 12 | } 13 | 14 | export function AnimateEnter({ 15 | className, 16 | delay, 17 | children, 18 | duration = 0.4, 19 | }: AnimateEnterProps) { 20 | return ( 21 | 28 | {children} 29 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/FloatToggleTheme.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useEffect, useState } from 'react' 4 | 5 | import { useTheme } from 'next-themes' 6 | 7 | import { Icons } from '@/app/_components/Icons' 8 | import { TextMorph } from '@/app/_components/TextMorph' 9 | import { AnimatePresence, motion, useScroll } from 'motion/react' 10 | 11 | export function FloatToggleTheme() { 12 | const [visible, setVisible] = useState(false) 13 | 14 | const { resolvedTheme, setTheme } = useTheme() 15 | const { scrollY } = useScroll() 16 | 17 | useEffect(() => { 18 | const unsubscribe = scrollY.on('change', value => { 19 | setVisible(value > 100) 20 | }) 21 | 22 | return () => unsubscribe() 23 | }, [scrollY]) 24 | 25 | return ( 26 | 27 | {visible && ( 28 | setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')} 30 | initial={{ width: 0, y: -100, opacity: 0 }} 31 | animate={{ width: 112, y: 0, opacity: 1 }} 32 | exit={{ width: 0, y: -100, opacity: 0 }} 33 | className="fixed left-0 right-0 top-4 z-[999] mx-auto flex h-8 items-center justify-between rounded-2xl border border-border bg-background px-2 text-primary shadow dark:border-transparent dark:bg-[#161616] dark:shadow-inner dark:shadow-neutral-800/80" 34 | > 35 | 36 | {resolvedTheme === 'dark' ? ( 37 | 47 | 48 | 49 | ) : ( 50 | 60 | 61 | 62 | )} 63 | 64 | 74 | 75 | 76 | {resolvedTheme === 'dark' ? 'Dark' : 'Light'} 77 | 78 | mode 79 | 80 | 81 | 82 | )} 83 | 84 | ) 85 | } 86 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/GridBackground.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/utils/cn"; 2 | 3 | export function GridBackground() { 4 | return ( 5 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/components-section/ComponentsExample.tsx: -------------------------------------------------------------------------------- 1 | import { MultiStepModal } from "@/app/_components/OldMultiStepModal"; 2 | import { AnimatedTabs } from "@/app/_components/ui/animated-tabs"; 3 | import { TooltipExample } from "@/app/ui/_components/examples/TooltipExample"; 4 | import { ComponentView } from "@/app/ui/_components/ComponentView"; 5 | 6 | import { AnimateEnter } from "../AnimateEnter"; 7 | 8 | import { cn } from "@/utils/cn"; 9 | import { AccordionExample } from "@/app/ui/_components/examples/AccordionExample"; 10 | import { Button } from "@/app/_components/ui/button"; 11 | import { Text } from "@/app/_components/ui/text"; 12 | import { DropdownMenuExample } from "@/app/ui/_components/examples/DropdownMenuExample"; 13 | 14 | const COMPONENTS_EXAMPLE = [ 15 | { 16 | component: ( 17 | This is a text generation effect. 18 | ), 19 | isReloadAnimation: true, 20 | }, 21 | { component: }, 22 | { component: }, 23 | { 24 | component: , 25 | className: "md:col-span-1", 26 | componentViewClassName: "min-h-[350px]", 27 | }, 28 | { 29 | component: , 30 | className: "md:col-span-2", 31 | componentViewClassName: "min-h-[350px]", 32 | }, 33 | { 34 | component: , 35 | className: "md:col-span-2", 36 | componentViewClassName: "min-h-[300px]", 37 | }, 38 | { 39 | component: Generating code..., 40 | componentViewClassName: "min-h-[300px]", 41 | }, 42 | { 43 | component: , 44 | componentViewClassName: "min-h-[300px]", 45 | }, 46 | { 47 | component: ( 48 | 49 | ), 50 | className: "md:col-span-2", 51 | componentViewClassName: "min-h-[300px]", 52 | }, 53 | ]; 54 | 55 | export function ComponentsExample() { 56 | return ( 57 |
58 | {COMPONENTS_EXAMPLE.map( 59 | ( 60 | { isReloadAnimation, component, className, componentViewClassName }, 61 | idx, 62 | ) => ( 63 | 64 | 71 | {component} 72 | 73 | 74 | ), 75 | )} 76 |
77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/components-section/ComponentsSection.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "next-view-transitions"; 2 | 3 | import { ChevronRightIcon } from "lucide-react"; 4 | 5 | import { AnimateEnter } from "../AnimateEnter"; 6 | import { ComponentsExample } from "./ComponentsExample"; 7 | 8 | export function ComponentsSection() { 9 | return ( 10 |
11 | 12 |

13 | Elevate your web apps with sophisticated interfaces 14 |

15 |

16 | Choose a component, copy the code, and instantly elevate your 17 | interface. With just a few clicks, and your app shines. 18 |

19 |
20 | 21 | 22 |
25 | ); 26 | } 27 | 28 | function Button() { 29 | return ( 30 | 34 | 35 | Explore All Components 36 | 37 | 38 |
39 |
40 |
41 | 42 | ); 43 | } 44 | 45 | function ChevronIconGlitch() { 46 | return ( 47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
58 | ); 59 | } 60 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/components-section/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ComponentsSection' 2 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/feedbacks-section/FeedbacksCard.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | 3 | export function FeedbacksCard() { 4 | return ( 5 |
6 |

7 | “Luxe is an ultra-aesthetic user interface library. I think it's 8 | promising when built as an abstract layer on top of your existing design 9 | system.” 10 |

11 |
12 | Rodz's profile image 19 |
20 | 26 | Guilherme Rodz 27 | 28 | 29 | Creator of input-otp 30 | 31 |
32 |
33 |
34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /apps/www/src/app/(home)/_components/feedbacks-section/FeedbacksSection.tsx: -------------------------------------------------------------------------------- 1 | import { AnimateEnter } from "../AnimateEnter"; 2 | import { FeedbacksCard } from "./FeedbacksCard"; 3 | 4 | export function FeedbacksSection() { 5 | return ( 6 |
7 |
8 | 9 | 10 | 14 | 15 | 16 |
17 |
18 | ); 19 | } 20 | 21 | function Blur() { 22 | return ( 23 |