diff --git a/.changeset/README.md b/.changeset/README.md index e5b6d8d6a..c63edce49 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -1,8 +1,8 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json index a4ba8a296..8e57d89f7 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,11 +1,11 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", - "changelog": ["@changesets/changelog-github", { "repo": "themesberg/flowbite-react" }], - "commit": false, - "fixed": [], - "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": ["storybook", "web"] -} +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": ["@changesets/changelog-github", { "repo": "themesberg/flowbite-react" }], + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": ["storybook", "web"] +} diff --git a/.changeset/plenty-lemons-bow.md b/.changeset/plenty-lemons-bow.md index 29ebd753d..14307e4f7 100644 --- a/.changeset/plenty-lemons-bow.md +++ b/.changeset/plenty-lemons-bow.md @@ -1,5 +1,5 @@ ---- -"flowbite-react": patch ---- - -fix: autocomplete for string enums with dynamic value not working +--- +"flowbite-react": patch +--- + +fix: autocomplete for string enums with dynamic value not working diff --git a/.editorconfig b/.editorconfig index ae10a5cce..b2b5a4ae3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,10 +1,10 @@ -# editorconfig.org -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true +# editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 3abb837be..b05805c78 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -1,73 +1,73 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, race, -religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -- The use of sexualized language or imagery and unwelcome sexual attention or - advances -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic - address, without explicit permission -- Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at {{ email }}. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at {{ email }}. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index edd224e21..5dc0968bb 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,176 +1,176 @@ -# Contributing to flowbite-react - -First off, thanks for taking the time to contribute! ❤️ - -All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 - -And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: - -- Star the project -- Tweet about it -- Refer this project in your project's readme -- Mention the project at local meetups and tell your friends/colleagues - -## Code of Conduct - -This project has adopted the [Contributor Covenant](https://www.contributor-covenant.org/) as its Code of Conduct. Everyone is expected to adhere to these rules, so please read the [full text](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). Thank you. - -## I Have a Question - -**If you want to ask a question, we assume that you have read the available [Documentation](https://flowbite-react.com/docs/getting-started/introduction).** - -Before you ask a question, it is best to search for existing [Issues](https://github.com/themesberg/flowbite-react/issues) that might help you. We also have a [Discord server](https://discord.gg/flowbite-902911619032576090) where you can ask questions and get help from the community directly. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. - -If you then still feel the need to ask a question and need clarification, we recommend the following: - -- Open an [Issue](https://github.com/themesberg/flowbite-react/issues/new). -- Follow the [Issue template](https://github.com/themesberg/flowbite-react/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) and fill it out as completely as possible. Don't forget to: - - Provide as much context as you can about what you're running into. - - Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. - -We will then take care of the issue as soon as possible. - -## I Want To Contribute - -### Legal Notice - -When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the [project license](https://github.com/themesberg/flowbite-react/blob/main/LICENSE). - -### Reporting Bugs - -#### Before Submitting a Bug Report - -A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. - -- Make sure that you are using the latest version. -- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://flowbite-react.com/docs/getting-started/introduction). If you are looking for support, you might want to check [this section](#i-have-a-question)). -- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/themesberg/flowbite-react/issues?q=label%3A%22%3Abug%3A+bug%22). -- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. -- Can you reliably reproduce the issue? And can you also reproduce it with older versions? - -#### How Do I Submit a Good Bug Report? - -We use GitHub issues to track bugs and errors. If you run into an issue with the project: - -- Open an [Issue](https://github.com/themesberg/flowbite-react/issues/new). -- Follow the [Issue template for bug reports](https://github.com/themesberg/flowbite-react/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) to the best of your ability. - -Don't forget to: - -- Explain the behavior you would expect and the actual behavior. -- Please provide as much context as possible and describe the _reproduction steps_ that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. -- Provide the information you collected in the previous section. - -Once it's filed: - -- The project team will label the issue accordingly. -- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs info`. Bugs with the `needs info` tag will not be addressed until they are reproduced. -- If the team is able to reproduce the issue, it will be marked `confirmed`, as well as possibly other tags (such as `bug`, `help wanted`), and the issue will be left to be [implemented by someone](#your-first-code-contribution). - -### Suggesting Enhancements - -This section guides you through submitting an enhancement suggestion for flowbite-react, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. - -#### Before Submitting an Enhancement - -- Make sure that you are using the latest version. -- Read the [documentation](https://flowbite-react.com/docs/getting-started/introduction) carefully and find out if the functionality is already covered, maybe by an individual configuration. -- Perform a [search](https://github.com/themesberg/flowbite-react/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. -- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. - -#### How Do I Submit a Good Enhancement Suggestion? - -Enhancement suggestions are tracked as [GitHub issues](https://github.com/themesberg/flowbite-react/issues). - -- Use a **clear and descriptive title** for the issue to identify the suggestion. -- Follow the [Issue template for feature requests](https://github.com/themesberg/flowbite-react/blob/main/.github/ISSUE_TEMPLATE/feature_request.md) to the best of your ability. - -Don't forget to: - -- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. -- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. -- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. -- **Explain why this enhancement would be useful** to most flowbite-react users. You may also want to point out the other projects that solved it better and which could serve as inspiration. - -### Your First Code Contribution - -#### Prerequisites - -- You need to understand how to use a terminal, `Git`, `Node.js`, and `Bun` -- You should be able to write `Markdown` and `React TypeScript` -- You should be familiar with `Tailwind` `CSS`, `ESLint`, and `Prettier` -- You should understand what [vitest](https://vitest.dev/) is, and be able to write tests if your contribution changes the behavior of the library in some way -- You should strongly consider using [Visual Studio Code](https://code.visualstudio.com/) as your editor, as it has plugins for `Tailwind CSS`, `ESLint`, and `Prettier` which will automatically fix most style issues for you, and offer suggestions for how to fix the rest - -#### Creating a Pull Request - -1. [Fork the repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo) -2. Clone the fork and add a remote called `upstream`: - -```bash -git clone https://github.com//flowbite-react.git -cd flowbite-react -git remote add upstream https://github.com/themesberg/flowbite-react.git -``` - -3. Create a new branch named after your PR: - -```bash -git checkout -b fix/accordion-alwaysopen -``` - -4. Install dependencies with [`bun`](https://bun.sh/): - -```bash -bun install -``` - -5. Start a development server on your machine: - -```bash -bun run dev -``` - -6. Make sure your changes work and don't break anything else: - -```bash -bun run format && bun run lint:fix && bun run test && bun run build -``` - -7. Push to your forked repository - -```bash -git push -u origin fix/accordion-alwaysopen -``` - -8. Go to [the repository](https://github.com/themesberg/flowbite-react) and [create a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) - -9. Fill out the Pull Request template, which will be available automatically - -#### What Happens Next? - -If you have followed the steps above, your Pull Request will be reviewed by a maintainer soon. If it passes review, it will be merged into the `main` branch and will be included in the next release. If not, you will receive feedback about what needs to be improved until it is ready to be merged. - -Please note that you will be expected to update the [documentation](https://flowbite-react.com/docs/getting-started/introduction) and write appropriate unit tests if your contribution changes the behavior of the library in some way. - -### Improving The Documentation - -The [documentation at flowbite-react.com](https://flowbite-react.com/docs/getting-started/introduction) can all be found inside the `app` folder of this repository. It's written in [Next.js](https://nextjs.org/), and we use [Markdown](https://www.markdownguide.org/cheat-sheet/) for almost all of the content, so you don't need to even be able to write React TypeScript to make documentation changes! - -## Styleguides - -### Files - -We use [Prettier](https://prettier.io/) to format all of our code. Please make sure to run `bun run format` before committing any changes. You can also use VS Code as your editor, and install the Prettier and Tailwind CSS IntelliSense plugins to automatically format your code each time you save. - -Please refer to the code written already in the project to see how we format our code, what naming conventions we use, and so on. The more consistent your code is with the rest of the project, the easier it will be to review and merge your Pull Request. - -### Branches & Pull Requests - -Please follow the same guidelines published by [commitizen](https://github.com/commitizen/cz-cli) when you name a branch that will be used for a Pull Request. The branch name should be prefixed with the most significant change that will be introduced in the Pull Request. - -For example, if you are fixing a bug in the accordion component, the branch name should be something like, `fix/accordion-does-x-wrong`. - -## Attribution - -This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)! +# Contributing to flowbite-react + +First off, thanks for taking the time to contribute! ❤️ + +All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉 + +And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: + +- Star the project +- Tweet about it +- Refer this project in your project's readme +- Mention the project at local meetups and tell your friends/colleagues + +## Code of Conduct + +This project has adopted the [Contributor Covenant](https://www.contributor-covenant.org/) as its Code of Conduct. Everyone is expected to adhere to these rules, so please read the [full text](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). Thank you. + +## I Have a Question + +**If you want to ask a question, we assume that you have read the available [Documentation](https://flowbite-react.com/docs/getting-started/introduction).** + +Before you ask a question, it is best to search for existing [Issues](https://github.com/themesberg/flowbite-react/issues) that might help you. We also have a [Discord server](https://discord.gg/flowbite-902911619032576090) where you can ask questions and get help from the community directly. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. + +If you then still feel the need to ask a question and need clarification, we recommend the following: + +- Open an [Issue](https://github.com/themesberg/flowbite-react/issues/new). +- Follow the [Issue template](https://github.com/themesberg/flowbite-react/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) and fill it out as completely as possible. Don't forget to: + - Provide as much context as you can about what you're running into. + - Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. + +We will then take care of the issue as soon as possible. + +## I Want To Contribute + +### Legal Notice + +When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the [project license](https://github.com/themesberg/flowbite-react/blob/main/LICENSE). + +### Reporting Bugs + +#### Before Submitting a Bug Report + +A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible. + +- Make sure that you are using the latest version. +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://flowbite-react.com/docs/getting-started/introduction). If you are looking for support, you might want to check [this section](#i-have-a-question)). +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/themesberg/flowbite-react/issues?q=label%3A%22%3Abug%3A+bug%22). +- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue. +- Can you reliably reproduce the issue? And can you also reproduce it with older versions? + +#### How Do I Submit a Good Bug Report? + +We use GitHub issues to track bugs and errors. If you run into an issue with the project: + +- Open an [Issue](https://github.com/themesberg/flowbite-react/issues/new). +- Follow the [Issue template for bug reports](https://github.com/themesberg/flowbite-react/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) to the best of your ability. + +Don't forget to: + +- Explain the behavior you would expect and the actual behavior. +- Please provide as much context as possible and describe the _reproduction steps_ that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case. +- Provide the information you collected in the previous section. + +Once it's filed: + +- The project team will label the issue accordingly. +- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs info`. Bugs with the `needs info` tag will not be addressed until they are reproduced. +- If the team is able to reproduce the issue, it will be marked `confirmed`, as well as possibly other tags (such as `bug`, `help wanted`), and the issue will be left to be [implemented by someone](#your-first-code-contribution). + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for flowbite-react, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. + +#### Before Submitting an Enhancement + +- Make sure that you are using the latest version. +- Read the [documentation](https://flowbite-react.com/docs/getting-started/introduction) carefully and find out if the functionality is already covered, maybe by an individual configuration. +- Perform a [search](https://github.com/themesberg/flowbite-react/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. +- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library. + +#### How Do I Submit a Good Enhancement Suggestion? + +Enhancement suggestions are tracked as [GitHub issues](https://github.com/themesberg/flowbite-react/issues). + +- Use a **clear and descriptive title** for the issue to identify the suggestion. +- Follow the [Issue template for feature requests](https://github.com/themesberg/flowbite-react/blob/main/.github/ISSUE_TEMPLATE/feature_request.md) to the best of your ability. + +Don't forget to: + +- Provide a **step-by-step description of the suggested enhancement** in as many details as possible. +- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you. +- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +- **Explain why this enhancement would be useful** to most flowbite-react users. You may also want to point out the other projects that solved it better and which could serve as inspiration. + +### Your First Code Contribution + +#### Prerequisites + +- You need to understand how to use a terminal, `Git`, `Node.js`, and `Bun` +- You should be able to write `Markdown` and `React TypeScript` +- You should be familiar with `Tailwind` `CSS`, `ESLint`, and `Prettier` +- You should understand what [vitest](https://vitest.dev/) is, and be able to write tests if your contribution changes the behavior of the library in some way +- You should strongly consider using [Visual Studio Code](https://code.visualstudio.com/) as your editor, as it has plugins for `Tailwind CSS`, `ESLint`, and `Prettier` which will automatically fix most style issues for you, and offer suggestions for how to fix the rest + +#### Creating a Pull Request + +1. [Fork the repository](https://docs.github.com/en/get-started/quickstart/fork-a-repo) +2. Clone the fork and add a remote called `upstream`: + +```bash +git clone https://github.com//flowbite-react.git +cd flowbite-react +git remote add upstream https://github.com/themesberg/flowbite-react.git +``` + +3. Create a new branch named after your PR: + +```bash +git checkout -b fix/accordion-alwaysopen +``` + +4. Install dependencies with [`bun`](https://bun.sh/): + +```bash +bun install +``` + +5. Start a development server on your machine: + +```bash +bun run dev +``` + +6. Make sure your changes work and don't break anything else: + +```bash +bun run format && bun run lint:fix && bun run test && bun run build +``` + +7. Push to your forked repository + +```bash +git push -u origin fix/accordion-alwaysopen +``` + +8. Go to [the repository](https://github.com/themesberg/flowbite-react) and [create a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) + +9. Fill out the Pull Request template, which will be available automatically + +#### What Happens Next? + +If you have followed the steps above, your Pull Request will be reviewed by a maintainer soon. If it passes review, it will be merged into the `main` branch and will be included in the next release. If not, you will receive feedback about what needs to be improved until it is ready to be merged. + +Please note that you will be expected to update the [documentation](https://flowbite-react.com/docs/getting-started/introduction) and write appropriate unit tests if your contribution changes the behavior of the library in some way. + +### Improving The Documentation + +The [documentation at flowbite-react.com](https://flowbite-react.com/docs/getting-started/introduction) can all be found inside the `app` folder of this repository. It's written in [Next.js](https://nextjs.org/), and we use [Markdown](https://www.markdownguide.org/cheat-sheet/) for almost all of the content, so you don't need to even be able to write React TypeScript to make documentation changes! + +## Styleguides + +### Files + +We use [Prettier](https://prettier.io/) to format all of our code. Please make sure to run `bun run format` before committing any changes. You can also use VS Code as your editor, and install the Prettier and Tailwind CSS IntelliSense plugins to automatically format your code each time you save. + +Please refer to the code written already in the project to see how we format our code, what naming conventions we use, and so on. The more consistent your code is with the rest of the project, the easier it will be to review and merge your Pull Request. + +### Branches & Pull Requests + +Please follow the same guidelines published by [commitizen](https://github.com/commitizen/cz-cli) when you name a branch that will be used for a Pull Request. The branch name should be prefixed with the most significant change that will be introduced in the Pull Request. + +For example, if you are fixing a bug in the accordion component, the branch name should be something like, `fix/accordion-does-x-wrong`. + +## Attribution + +This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)! diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 2e357e5f1..9d499affa 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ -# These are supported funding model platforms - -github: [rluders, tulup-conner, SutuSebastian] +# These are supported funding model platforms + +github: [rluders, tulup-conner, SutuSebastian] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d9dac3677..1a9092312 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,27 +1,27 @@ ---- -name: Bug report -about: Report a bug in Flowbite React ---- - -- [ ] I have searched the [Issues](https://github.com/themesberg/flowbite-react/issues) to see if this bug has already been reported -- [ ] I have tested the latest version - -## Steps to reproduce - -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' - -## Current behavior - -Describe what is currently happening and why it's a problem. - -## Expected behavior - -Describe what you expected to happen. - -## Context - -What are you trying to accomplish? Does this only happen on a specific browser, screen size, or operating system? - -If possible, provide a live example URL, screenshot, video, or a repository with the minimal reproduction of the issue. +--- +name: Bug report +about: Report a bug in Flowbite React +--- + +- [ ] I have searched the [Issues](https://github.com/themesberg/flowbite-react/issues) to see if this bug has already been reported +- [ ] I have tested the latest version + +## Steps to reproduce + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' + +## Current behavior + +Describe what is currently happening and why it's a problem. + +## Expected behavior + +Describe what you expected to happen. + +## Context + +What are you trying to accomplish? Does this only happen on a specific browser, screen size, or operating system? + +If possible, provide a live example URL, screenshot, video, or a repository with the minimal reproduction of the issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index e2a20a2e3..da5403c39 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,15 +1,15 @@ ---- -name: Feature request -about: Suggest an idea for Flowbite React ---- - -- [ ] I have searched the [Issues](https://github.com/themesberg/flowbite-react/issues) to see if this bug has already been reported -- [ ] I have tested the latest version - -## Summary - -Describe how it should work, and provide examples of the solution, which might include screenshots or code snippets. - -## Context - -What are you trying to accomplish? How is your use case affected by not having this feature? +--- +name: Feature request +about: Suggest an idea for Flowbite React +--- + +- [ ] I have searched the [Issues](https://github.com/themesberg/flowbite-react/issues) to see if this bug has already been reported +- [ ] I have tested the latest version + +## Summary + +Describe how it should work, and provide examples of the solution, which might include screenshots or code snippets. + +## Context + +What are you trying to accomplish? How is your use case affected by not having this feature? diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 899a97634..03123f031 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,7 +1,7 @@ -- [ ] I have followed the [Your First Code Contribution section of the Contributing guide](https://github.com/themesberg/flowbite-react/blob/main/CONTRIBUTING.md#your-first-code-contribution) - -Summarize the changes made and the motivation behind them. - -Reference related issues using `#` followed by the issue number. - -If there are breaking API changes - like adding or removing props, or changing the structure of the theme - describe them, and provide steps to update existing code. +- [ ] I have followed the [Your First Code Contribution section of the Contributing guide](https://github.com/themesberg/flowbite-react/blob/main/CONTRIBUTING.md#your-first-code-contribution) + +Summarize the changes made and the motivation behind them. + +Reference related issues using `#` followed by the issue number. + +If there are breaking API changes - like adding or removing props, or changing the structure of the theme - describe them, and provide steps to update existing code. diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 00926bafa..e779a92a0 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -1,19 +1,19 @@ -name: Setup -description: Setup Bun, Node and install packages - -runs: - using: composite - steps: - - name: Setup Bun - uses: oven-sh/setup-bun@v1 - with: - bun-version: 1.1.21 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install packages - shell: bash - run: bun install +name: Setup +description: Setup Bun, Node and install packages + +runs: + using: composite + steps: + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.1.21 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install packages + shell: bash + run: bun install diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2d9e2e24..9747eddff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,72 +1,72 @@ -name: CI - -on: - pull_request: - branches: - - main - -jobs: - format: - name: 💅 Format - runs-on: ubuntu-latest - steps: - - name: Checkout branch - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Run format - run: bun run format:check - - lint: - name: 🕵 Lint - runs-on: ubuntu-latest - steps: - - name: Checkout branch - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Run lint - run: bun run lint - - typecheck: - name: ✅ Typecheck - runs-on: ubuntu-latest - steps: - - name: Checkout branch - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Run typecheck - run: bun run typecheck - - test: - name: 🔬 Test - runs-on: ubuntu-latest - steps: - - name: Checkout branch - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Run unit tests - run: bun run test:coverage - - build: - name: 🧰 Build - runs-on: ubuntu-latest - steps: - - name: Checkout branch - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Run build - run: bun run build +name: CI + +on: + pull_request: + branches: + - main + +jobs: + format: + name: 💅 Format + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run format + run: bun run format:check + + lint: + name: 🕵 Lint + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run lint + run: bun run lint + + typecheck: + name: ✅ Typecheck + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run typecheck + run: bun run typecheck + + test: + name: 🔬 Test + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run unit tests + run: bun run test:coverage + + build: + name: 🧰 Build + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run build + run: bun run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 344331497..707b304ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,28 +1,28 @@ -name: Release - -on: - push: - branches: - - main - -concurrency: ${{ github.workflow }}-${{ github.ref }} - -jobs: - release: - name: Release - runs-on: ubuntu-latest - steps: - - name: Checkout branch - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Create Release Pull Request or Publish to NPM - id: changesets - uses: changesets/action@v1 - with: - publish: bun run release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} +name: Release + +on: + push: + branches: + - main + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout branch + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Create Release Pull Request or Publish to NPM + id: changesets + uses: changesets/action@v1 + with: + publish: bun run release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 95c165173..86b442a91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,13 @@ -# dependencies -node_modules - -# misc -.DS_Store -*.backup -*.pem - -# typescript -tsconfig.tsbuildinfo - -# turbo -.turbo +# dependencies +node_modules + +# misc +.DS_Store +*.backup +*.pem + +# typescript +tsconfig.tsbuildinfo + +# turbo +.turbo diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 7ceb3b627..447895bb6 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,11 +1,11 @@ -{ - "recommendations": [ - "oven.bun-vscode", - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint", - "yoavbls.pretty-ts-errors", - "bradlc.vscode-tailwindcss", - "unifiedjs.vscode-mdx", - "DavidAnson.vscode-markdownlint" - ] -} +{ + "recommendations": [ + "oven.bun-vscode", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "yoavbls.pretty-ts-errors", + "bradlc.vscode-tailwindcss", + "unifiedjs.vscode-mdx", + "DavidAnson.vscode-markdownlint" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 8dbffc577..9e50fde82 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,18 +1,18 @@ -{ - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - }, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "eslint.workingDirectories": ["apps/web", "packages/ui"], - "tailwindCSS.classAttributes": ["class", "className", "theme"], - "tailwindCSS.experimental.classRegex": [ - ["twMerge\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], - ["createTheme\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"] - ], - "tailwindCSS.experimental.configFile": { - "apps/web/tailwind.config.cjs": "apps/web/**", - "packages/ui/tailwind.config.cjs": "packages/ui/**" - }, - "typescript.tsdk": "node_modules/typescript/lib" -} +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "eslint.workingDirectories": ["apps/web", "packages/ui"], + "tailwindCSS.classAttributes": ["class", "className", "theme"], + "tailwindCSS.experimental.classRegex": [ + ["twMerge\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], + ["createTheme\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"] + ], + "tailwindCSS.experimental.configFile": { + "apps/web/tailwind.config.cjs": "apps/web/**", + "packages/ui/tailwind.config.cjs": "packages/ui/**" + }, + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/LICENSE b/LICENSE index 5164b9225..4ff375d68 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2024 Bergside Inc. - -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. +MIT License + +Copyright (c) 2024 Bergside Inc. + +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. diff --git a/apps/storybook/.gitignore b/apps/storybook/.gitignore index 20687473b..6140bddfb 100644 --- a/apps/storybook/.gitignore +++ b/apps/storybook/.gitignore @@ -1 +1 @@ -storybook-static +storybook-static diff --git a/apps/storybook/.storybook/main.ts b/apps/storybook/.storybook/main.ts index 2daa674b2..cc08efcc5 100644 --- a/apps/storybook/.storybook/main.ts +++ b/apps/storybook/.storybook/main.ts @@ -1,28 +1,28 @@ -import { dirname, join } from "path"; -import type { StorybookConfig } from "@storybook/react-vite"; - -/** - * This function is used to resolve the absolute path of a package. - * It is needed in projects that use Yarn PnP or are set up within a monorepo. - */ - -function getAbsolutePath(value: string): any { - return dirname(require.resolve(join(value, "package.json"))); -} -const config: StorybookConfig = { - stories: ["../../../packages/ui/**/*.stories.@(ts|tsx)"], - addons: [ - getAbsolutePath("@storybook/addon-links"), - getAbsolutePath("@storybook/addon-essentials"), - getAbsolutePath("@storybook/addon-interactions"), - getAbsolutePath("@storybook/addon-themes"), - ], - framework: { - name: getAbsolutePath("@storybook/react-vite"), - options: {}, - }, - docs: { - autodocs: "tag", - }, -}; -export default config; +import { dirname, join } from "path"; +import type { StorybookConfig } from "@storybook/react-vite"; + +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ + +function getAbsolutePath(value: string): any { + return dirname(require.resolve(join(value, "package.json"))); +} +const config: StorybookConfig = { + stories: ["../../../packages/ui/**/*.stories.@(ts|tsx)"], + addons: [ + getAbsolutePath("@storybook/addon-links"), + getAbsolutePath("@storybook/addon-essentials"), + getAbsolutePath("@storybook/addon-interactions"), + getAbsolutePath("@storybook/addon-themes"), + ], + framework: { + name: getAbsolutePath("@storybook/react-vite"), + options: {}, + }, + docs: { + autodocs: "tag", + }, +}; +export default config; diff --git a/apps/storybook/.storybook/preview.ts b/apps/storybook/.storybook/preview.ts index bd89877ad..5e19d2999 100644 --- a/apps/storybook/.storybook/preview.ts +++ b/apps/storybook/.storybook/preview.ts @@ -1,30 +1,30 @@ -import { withThemeByClassName } from "@storybook/addon-themes"; -import type { Preview } from "@storybook/react"; - -import "./style.css"; - -const preview: Preview = { - parameters: { - actions: { - argTypesRegex: "^on[A-Z].*", - }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, -}; - -export const decorators = [ - withThemeByClassName({ - themes: { - light: "light", - dark: "dark", - }, - defaultTheme: "light", - }), -]; - -export default preview; +import { withThemeByClassName } from "@storybook/addon-themes"; +import type { Preview } from "@storybook/react"; + +import "./style.css"; + +const preview: Preview = { + parameters: { + actions: { + argTypesRegex: "^on[A-Z].*", + }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, +}; + +export const decorators = [ + withThemeByClassName({ + themes: { + light: "light", + dark: "dark", + }, + defaultTheme: "light", + }), +]; + +export default preview; diff --git a/apps/storybook/.storybook/style.css b/apps/storybook/.storybook/style.css index d69619447..5df2f7e98 100644 --- a/apps/storybook/.storybook/style.css +++ b/apps/storybook/.storybook/style.css @@ -1,20 +1,20 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - @font-face { - font-family: "Inter"; - src: url(inter.woff2) format("woff2"); - font-weight: 100 200 300 400 500 600 700 800 900; - font-display: swap; - } - - html { - font-family: "Inter", sans-serif; - } - - html.dark { - background-color: #101827; - } -} +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + @font-face { + font-family: "Inter"; + src: url(inter.woff2) format("woff2"); + font-weight: 100 200 300 400 500 600 700 800 900; + font-display: swap; + } + + html { + font-family: "Inter", sans-serif; + } + + html.dark { + background-color: #101827; + } +} diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 09201890d..2563d7f85 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -1,36 +1,36 @@ -{ - "name": "storybook", - "version": "0.0.0", - "private": true, - "scripts": { - "build": "storybook build", - "clean": "rimraf .turbo node_modules storybook-static", - "dev": "storybook dev -p 6006", - "format": "prettier . --write", - "format:check": "prettier . --check", - "typecheck": "tsc --noEmit" - }, - "dependencies": { - "react": "18.3.1", - "react-dom": "18.3.1" - }, - "devDependencies": { - "@storybook/addon-essentials": "8.1.10", - "@storybook/addon-interactions": "8.1.10", - "@storybook/addon-links": "8.1.10", - "@storybook/addon-themes": "8.1.10", - "@storybook/blocks": "8.1.10", - "@storybook/react": "8.1.10", - "@storybook/react-vite": "8.1.10", - "@storybook/test": "8.1.10", - "@types/react": "18.3.3", - "@types/react-dom": "18.3.0", - "@vitejs/plugin-react": "4.3.1", - "autoprefixer": "10.4.20", - "postcss": "8.4.41", - "storybook": "8.1.10", - "tailwindcss": "3.4.7", - "typescript": "5.5.4", - "vite": "5.3.5" - } -} +{ + "name": "storybook", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "storybook build", + "clean": "rimraf .turbo node_modules storybook-static", + "dev": "storybook dev -p 6006", + "format": "prettier . --write", + "format:check": "prettier . --check", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "react": "18.3.1", + "react-dom": "18.3.1" + }, + "devDependencies": { + "@storybook/addon-essentials": "8.1.10", + "@storybook/addon-interactions": "8.1.10", + "@storybook/addon-links": "8.1.10", + "@storybook/addon-themes": "8.1.10", + "@storybook/blocks": "8.1.10", + "@storybook/react": "8.1.10", + "@storybook/react-vite": "8.1.10", + "@storybook/test": "8.1.10", + "@types/react": "18.3.3", + "@types/react-dom": "18.3.0", + "@vitejs/plugin-react": "4.3.1", + "autoprefixer": "10.4.20", + "postcss": "8.4.41", + "storybook": "8.1.10", + "tailwindcss": "3.4.7", + "typescript": "5.5.4", + "vite": "5.3.5" + } +} diff --git a/apps/storybook/postcss.config.cjs b/apps/storybook/postcss.config.cjs index 12a703d90..a1b36d24e 100644 --- a/apps/storybook/postcss.config.cjs +++ b/apps/storybook/postcss.config.cjs @@ -1,6 +1,6 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/apps/storybook/tailwind.config.cjs b/apps/storybook/tailwind.config.cjs index a0e0fe2be..5a6811a3c 100644 --- a/apps/storybook/tailwind.config.cjs +++ b/apps/storybook/tailwind.config.cjs @@ -1,8 +1,8 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: ["../../packages/ui/src/**/*.{ts,tsx}"], - theme: { - extend: {}, - }, - plugins: [require("flowbite/plugin")], -}; +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["../../packages/ui/src/**/*.{ts,tsx}"], + theme: { + extend: {}, + }, + plugins: [require("flowbite/plugin")], +}; diff --git a/apps/storybook/tsconfig.json b/apps/storybook/tsconfig.json index a7fc6fbf2..9bdaa778c 100644 --- a/apps/storybook/tsconfig.json +++ b/apps/storybook/tsconfig.json @@ -1,25 +1,25 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] -} +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/apps/storybook/tsconfig.node.json b/apps/storybook/tsconfig.node.json index 42872c59f..165a9ba72 100644 --- a/apps/storybook/tsconfig.node.json +++ b/apps/storybook/tsconfig.node.json @@ -1,10 +1,10 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/apps/storybook/turbo.json b/apps/storybook/turbo.json index 5da1fb4c5..b741fcc8f 100644 --- a/apps/storybook/turbo.json +++ b/apps/storybook/turbo.json @@ -1,8 +1,8 @@ -{ - "extends": ["//"], - "tasks": { - "build": { - "outputs": ["storybook-static/**"] - } - } -} +{ + "extends": ["//"], + "tasks": { + "build": { + "outputs": ["storybook-static/**"] + } + } +} diff --git a/apps/storybook/vite.config.mjs b/apps/storybook/vite.config.mjs index 58676f788..592620177 100644 --- a/apps/storybook/vite.config.mjs +++ b/apps/storybook/vite.config.mjs @@ -1,6 +1,6 @@ -import react from "@vitejs/plugin-react"; -import { defineConfig } from "vite"; - -export default defineConfig({ - plugins: [react()], -}); +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [react()], +}); diff --git a/apps/web/.eslintrc.cjs b/apps/web/.eslintrc.cjs index 9bde37089..c6eebdb91 100644 --- a/apps/web/.eslintrc.cjs +++ b/apps/web/.eslintrc.cjs @@ -1,24 +1,24 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - extends: ["next/core-web-vitals", "plugin:tailwindcss/recommended", "prettier"], - settings: { - tailwindcss: { - callees: ["twMerge", "createTheme"], - classRegex: "^(class(Name)|theme)?$", - }, - }, - rules: { - "react/no-unescaped-entities": "off", - "tailwindcss/classnames-order": "off", - }, - overrides: [ - { - files: ["examples/**"], - rules: { - "@next/next/no-img-element": "off", - "tailwindcss/enforces-shorthand": "off", - }, - }, - ], -}; +/** @type {import("eslint").Linter.Config} */ +module.exports = { + root: true, + extends: ["next/core-web-vitals", "plugin:tailwindcss/recommended", "prettier"], + settings: { + tailwindcss: { + callees: ["twMerge", "createTheme"], + classRegex: "^(class(Name)|theme)?$", + }, + }, + rules: { + "react/no-unescaped-entities": "off", + "tailwindcss/classnames-order": "off", + }, + overrides: [ + { + files: ["examples/**"], + rules: { + "@next/next/no-img-element": "off", + "tailwindcss/enforces-shorthand": "off", + }, + }, + ], +}; diff --git a/apps/web/.gitignore b/apps/web/.gitignore index f833c17ee..b90345789 100644 --- a/apps/web/.gitignore +++ b/apps/web/.gitignore @@ -1,12 +1,12 @@ -# next.js -.next -out - -# production -build - -# vercel -.vercel - -# contentlayer -.contentlayer +# next.js +.next +out + +# production +build + +# vercel +.vercel + +# contentlayer +.contentlayer diff --git a/apps/web/app/docs/[[...slug]]/page.tsx b/apps/web/app/docs/[[...slug]]/page.tsx index 20f7bdfca..306c0f248 100644 --- a/apps/web/app/docs/[[...slug]]/page.tsx +++ b/apps/web/app/docs/[[...slug]]/page.tsx @@ -1,165 +1,165 @@ -import { allDocs, type Doc } from "contentlayer/generated"; -import type { Metadata } from "next"; -import Link from "next/link"; -import { notFound } from "next/navigation"; -import Markdown from "react-markdown"; -import { CarbonAds } from "~/components/carbon-ads"; -import { Mdx } from "~/components/mdx"; -import { DOCS_SIDEBAR } from "~/data/docs-sidebar"; - -interface Props { - params: { - slug: string[]; - }; -} - -function getDoc({ params }: Props) { - const slug = params.slug?.join("/") || ""; - - return allDocs.find((doc) => doc.url === slug); -} - -export function generateMetadata({ params }: Props): Metadata { - const doc = getDoc({ params }); - - if (!doc) return {}; - - return { - title: doc.title, - description: doc.description, - openGraph: { - type: "article", - title: doc.title, - description: doc.description, - images: "https://flowbite.s3.amazonaws.com/github/flowbite-react.png", - }, - twitter: { - card: "summary_large_image", - title: doc.title, - description: doc.description, - images: ["https://flowbite.s3.amazonaws.com/github/flowbite-react.png"], - }, - }; -} - -export function generateStaticParams() { - return allDocs.map((doc) => ({ slug: doc.url.split("/") })); -} - -export default function DocPage({ params }: Props) { - const doc = getDoc({ params }); - - if (!doc) notFound(); - - return ( -
-
-
- - - -
- - -
- -
- ); -} - -interface ContentLayoutProps { - title: string; - description: string; - children: React.ReactNode; -} - -function ContentLayout({ title, description, children }: ContentLayoutProps) { - return ( -
-
-

- {title} -

-

{description}

-
-
- {children} -
-
- ); -} - -function DocsPager({ doc }: { doc: Doc }) { - const DOCS_SIDEBAR_ITEMS = DOCS_SIDEBAR.flatMap((section) => section.items); - const currentDocIndex = DOCS_SIDEBAR_ITEMS.findIndex((item) => item.href === `/${doc._raw.flattenedPath}`); - const prevDoc = DOCS_SIDEBAR_ITEMS[currentDocIndex - 1]; - const nextDoc = DOCS_SIDEBAR_ITEMS[currentDocIndex + 1]; - - return ( - - ); -} - -function ToC({ doc }: { doc: Doc }) { - return ( -
-
-
-

- On this page -

- -
-
-
- ); -} +import { allDocs, type Doc } from "contentlayer/generated"; +import type { Metadata } from "next"; +import Link from "next/link"; +import { notFound } from "next/navigation"; +import Markdown from "react-markdown"; +import { CarbonAds } from "~/components/carbon-ads"; +import { Mdx } from "~/components/mdx"; +import { DOCS_SIDEBAR } from "~/data/docs-sidebar"; + +interface Props { + params: { + slug: string[]; + }; +} + +function getDoc({ params }: Props) { + const slug = params.slug?.join("/") || ""; + + return allDocs.find((doc) => doc.url === slug); +} + +export function generateMetadata({ params }: Props): Metadata { + const doc = getDoc({ params }); + + if (!doc) return {}; + + return { + title: doc.title, + description: doc.description, + openGraph: { + type: "article", + title: doc.title, + description: doc.description, + images: "https://flowbite.s3.amazonaws.com/github/flowbite-react.png", + }, + twitter: { + card: "summary_large_image", + title: doc.title, + description: doc.description, + images: ["https://flowbite.s3.amazonaws.com/github/flowbite-react.png"], + }, + }; +} + +export function generateStaticParams() { + return allDocs.map((doc) => ({ slug: doc.url.split("/") })); +} + +export default function DocPage({ params }: Props) { + const doc = getDoc({ params }); + + if (!doc) notFound(); + + return ( +
+
+
+ + + +
+ + +
+ +
+ ); +} + +interface ContentLayoutProps { + title: string; + description: string; + children: React.ReactNode; +} + +function ContentLayout({ title, description, children }: ContentLayoutProps) { + return ( +
+
+

+ {title} +

+

{description}

+
+
+ {children} +
+
+ ); +} + +function DocsPager({ doc }: { doc: Doc }) { + const DOCS_SIDEBAR_ITEMS = DOCS_SIDEBAR.flatMap((section) => section.items); + const currentDocIndex = DOCS_SIDEBAR_ITEMS.findIndex((item) => item.href === `/${doc._raw.flattenedPath}`); + const prevDoc = DOCS_SIDEBAR_ITEMS[currentDocIndex - 1]; + const nextDoc = DOCS_SIDEBAR_ITEMS[currentDocIndex + 1]; + + return ( + + ); +} + +function ToC({ doc }: { doc: Doc }) { + return ( +
+
+
+

+ On this page +

+ +
+
+
+ ); +} diff --git a/apps/web/app/docs/layout.tsx b/apps/web/app/docs/layout.tsx index f775c337a..d104cb3c5 100644 --- a/apps/web/app/docs/layout.tsx +++ b/apps/web/app/docs/layout.tsx @@ -1,192 +1,192 @@ -"use client"; - -import { Navbar } from "flowbite-react"; -import Image from "next/image"; -import Link from "next/link"; -import { usePathname } from "next/navigation"; -import type { PropsWithChildren } from "react"; -import { useEffect, useState } from "react"; -import { HiMenuAlt1, HiX } from "react-icons/hi"; -import { twMerge } from "tailwind-merge"; -import { DocSearchInput } from "~/components/docsearch-input"; -import { MainFooter } from "~/components/main-footer"; -import { NavbarIcons, NavbarLinks } from "~/components/navbar"; -import { DOCS_SIDEBAR, type DocsSidebarItem } from "~/data/docs-sidebar"; - -import "~/styles/docs.css"; - -interface DocsLayoutState { - isCollapsed: boolean; - setCollapsed: (collapsed: boolean) => void; -} - -export default function DocsLayout({ children }: PropsWithChildren) { - const [isCollapsed, setCollapsed] = useState(true); - - const state: DocsLayoutState = { - isCollapsed, - setCollapsed, - }; - - return ( -
-
- {/* */} - -
- -
{children}
-
- -
-
- ); -} - -function DocsNavbar({ isCollapsed, setCollapsed }: DocsLayoutState) { - return ( - -
- {isCollapsed ? ( - - ) : ( - - )} - - Flowbite React logo - Flowbite React - -
- -
-
-
- - -
-
- ); -} - -function DocsSidebar({ isCollapsed, setCollapsed }: DocsLayoutState) { - const pathname = usePathname(); - - // collapse sidebar on small screens when navigating to a new page - useEffect(() => { - if (typeof window !== "undefined" && window.innerWidth < 768) { - setCollapsed(true); - } - }, [pathname, setCollapsed]); - - return ( - <> -
- -
- {!isCollapsed && ( -
setCollapsed(true)} - onKeyUp={(key) => key.code === "Escape" && setCollapsed(true)} - className="fixed inset-0 z-40 bg-gray-900/50 lg:hidden dark:bg-gray-900/60" - /> - )} - - ); -} - -function SidebarSection({ title, children }: PropsWithChildren<{ title: string }>) { - return ( -
  • -
    - {title} -
    -
      {children}
    -
  • - ); -} - -function SidebarItem({ title, href, isNew, isExternal, onClick }: DocsSidebarItem & { onClick(): void }) { - return ( -
  • - - {isNew ? {title} : title} - -
  • - ); -} - -function SidebarLink({ - children, - href, - isExternal, - onClick, -}: PropsWithChildren<{ href: string; isExternal?: boolean; onClick(): void }>) { - const pathname = usePathname(); - - return ( - - {children} - - ); -} - -function NewBadge({ children }: PropsWithChildren) { - return ( - - {children} - - new - - - ); -} +"use client"; + +import { Navbar } from "flowbite-react"; +import Image from "next/image"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import type { PropsWithChildren } from "react"; +import { useEffect, useState } from "react"; +import { HiMenuAlt1, HiX } from "react-icons/hi"; +import { twMerge } from "tailwind-merge"; +import { DocSearchInput } from "~/components/docsearch-input"; +import { MainFooter } from "~/components/main-footer"; +import { NavbarIcons, NavbarLinks } from "~/components/navbar"; +import { DOCS_SIDEBAR, type DocsSidebarItem } from "~/data/docs-sidebar"; + +import "~/styles/docs.css"; + +interface DocsLayoutState { + isCollapsed: boolean; + setCollapsed: (collapsed: boolean) => void; +} + +export default function DocsLayout({ children }: PropsWithChildren) { + const [isCollapsed, setCollapsed] = useState(true); + + const state: DocsLayoutState = { + isCollapsed, + setCollapsed, + }; + + return ( +
    +
    + {/* */} + +
    + +
    {children}
    +
    + +
    +
    + ); +} + +function DocsNavbar({ isCollapsed, setCollapsed }: DocsLayoutState) { + return ( + +
    + {isCollapsed ? ( + + ) : ( + + )} + + Flowbite React logo + Flowbite React + +
    + +
    +
    +
    + + +
    +
    + ); +} + +function DocsSidebar({ isCollapsed, setCollapsed }: DocsLayoutState) { + const pathname = usePathname(); + + // collapse sidebar on small screens when navigating to a new page + useEffect(() => { + if (typeof window !== "undefined" && window.innerWidth < 768) { + setCollapsed(true); + } + }, [pathname, setCollapsed]); + + return ( + <> +
    + +
    + {!isCollapsed && ( +
    setCollapsed(true)} + onKeyUp={(key) => key.code === "Escape" && setCollapsed(true)} + className="fixed inset-0 z-40 bg-gray-900/50 lg:hidden dark:bg-gray-900/60" + /> + )} + + ); +} + +function SidebarSection({ title, children }: PropsWithChildren<{ title: string }>) { + return ( +
  • +
    + {title} +
    +
      {children}
    +
  • + ); +} + +function SidebarItem({ title, href, isNew, isExternal, onClick }: DocsSidebarItem & { onClick(): void }) { + return ( +
  • + + {isNew ? {title} : title} + +
  • + ); +} + +function SidebarLink({ + children, + href, + isExternal, + onClick, +}: PropsWithChildren<{ href: string; isExternal?: boolean; onClick(): void }>) { + const pathname = usePathname(); + + return ( + + {children} + + ); +} + +function NewBadge({ children }: PropsWithChildren) { + return ( + + {children} + + new + + + ); +} diff --git a/apps/web/app/examples/[name]/layout.tsx b/apps/web/app/examples/[name]/layout.tsx index 1ed424f75..75e95c777 100644 --- a/apps/web/app/examples/[name]/layout.tsx +++ b/apps/web/app/examples/[name]/layout.tsx @@ -1,12 +1,12 @@ -"use client"; - -import { useSearchParams } from "next/navigation"; -import type { PropsWithChildren } from "react"; -import { twMerge } from "tailwind-merge"; - -export default function ExamplePageLayout({ children }: PropsWithChildren) { - const searchParams = useSearchParams(); - const noPadding = searchParams.get("noPadding"); - - return
    {children}
    ; -} +"use client"; + +import { useSearchParams } from "next/navigation"; +import type { PropsWithChildren } from "react"; +import { twMerge } from "tailwind-merge"; + +export default function ExamplePageLayout({ children }: PropsWithChildren) { + const searchParams = useSearchParams(); + const noPadding = searchParams.get("noPadding"); + + return
    {children}
    ; +} diff --git a/apps/web/app/examples/[name]/page.tsx b/apps/web/app/examples/[name]/page.tsx index 08b0bb22d..86de2ddec 100644 --- a/apps/web/app/examples/[name]/page.tsx +++ b/apps/web/app/examples/[name]/page.tsx @@ -1,19 +1,19 @@ -import { notFound } from "next/navigation"; - -interface Props { - params: { - name: string; - }; -} - -export default async function ExamplePage({ params }: Props) { - try { - const [key] = params.name.split("."); - - const { Component } = await import(`~/examples/${key}/${params.name}`); - - return Component ? : notFound(); - } catch (e) { - notFound(); - } -} +import { notFound } from "next/navigation"; + +interface Props { + params: { + name: string; + }; +} + +export default async function ExamplePage({ params }: Props) { + try { + const [key] = params.name.split("."); + + const { Component } = await import(`~/examples/${key}/${params.name}`); + + return Component ? : notFound(); + } catch (e) { + notFound(); + } +} diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 2e851f266..f66331e6d 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,68 +1,68 @@ -import { ThemeModeScript } from "flowbite-react"; -import { Inter as InterFont } from "next/font/google"; -import type { Metadata, Viewport } from "next/types"; -import type { PropsWithChildren } from "react"; -import { FathomScript } from "~/components/fathom-script"; - -import "~/styles/globals.css"; - -const interFont = InterFont({ - subsets: ["latin"], - variable: "--font-inter", -}); - -export const metadata: Metadata = { - description: - "Flowbite React is an open-source UI component library built with React components, Tailwind CSS utility classes and based on the Flowbite design system and components.", - icons: { - icon: [ - { url: "/favicon-32x32.png", type: "image/png", sizes: "32x32" }, - { url: "/favicon-16x16.png", type: "image/png", sizes: "16x16" }, - ], - shortcut: "/favicon.ico", - apple: [{ url: "/apple-touch-icon.png", sizes: "180x180" }], - }, - manifest: "/site.webmanifest", - other: { - charSet: "utf-8", - lang: "en", - }, - title: "Flowbite React - UI Component Library", - openGraph: { - description: - "Flowbite React is an open-source UI component library built with React components, Tailwind CSS utility classes and based on the Flowbite design system and components.", - images: "https://flowbite.s3.amazonaws.com/github/flowbite-react.png", - title: "Flowbite React - UI Component Library", - }, - twitter: { - card: "summary_large_image", - title: "Flowbite React - UI component library", - description: - "Flowbite React is an open-source UI component library built with React components, Tailwind CSS utility classes and based on the Flowbite design system and components.", - creator: "@zoltanszogyenyi", - images: ["https://flowbite.s3.amazonaws.com/github/flowbite-react.png"], - }, -}; - -export const viewport: Viewport = { - width: "device-width", - initialScale: 1, - themeColor: [ - { media: "(prefers-color-scheme: light)", color: "#ffffff" }, - { media: "(prefers-color-scheme: dark)", color: "#1f2937" }, - ], -}; - -export default function RootLayout({ children }: PropsWithChildren) { - return ( - - - - - - {children} - - - - ); -} +import { ThemeModeScript } from "flowbite-react"; +import { Inter as InterFont } from "next/font/google"; +import type { Metadata, Viewport } from "next/types"; +import type { PropsWithChildren } from "react"; +import { FathomScript } from "~/components/fathom-script"; + +import "~/styles/globals.css"; + +const interFont = InterFont({ + subsets: ["latin"], + variable: "--font-inter", +}); + +export const metadata: Metadata = { + description: + "Flowbite React is an open-source UI component library built with React components, Tailwind CSS utility classes and based on the Flowbite design system and components.", + icons: { + icon: [ + { url: "/favicon-32x32.png", type: "image/png", sizes: "32x32" }, + { url: "/favicon-16x16.png", type: "image/png", sizes: "16x16" }, + ], + shortcut: "/favicon.ico", + apple: [{ url: "/apple-touch-icon.png", sizes: "180x180" }], + }, + manifest: "/site.webmanifest", + other: { + charSet: "utf-8", + lang: "en", + }, + title: "Flowbite React - UI Component Library", + openGraph: { + description: + "Flowbite React is an open-source UI component library built with React components, Tailwind CSS utility classes and based on the Flowbite design system and components.", + images: "https://flowbite.s3.amazonaws.com/github/flowbite-react.png", + title: "Flowbite React - UI Component Library", + }, + twitter: { + card: "summary_large_image", + title: "Flowbite React - UI component library", + description: + "Flowbite React is an open-source UI component library built with React components, Tailwind CSS utility classes and based on the Flowbite design system and components.", + creator: "@zoltanszogyenyi", + images: ["https://flowbite.s3.amazonaws.com/github/flowbite-react.png"], + }, +}; + +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "#ffffff" }, + { media: "(prefers-color-scheme: dark)", color: "#1f2937" }, + ], +}; + +export default function RootLayout({ children }: PropsWithChildren) { + return ( + + + + + + {children} + + + + ); +} diff --git a/apps/web/app/not-found.tsx b/apps/web/app/not-found.tsx index f3b2d42f7..a318467fe 100644 --- a/apps/web/app/not-found.tsx +++ b/apps/web/app/not-found.tsx @@ -1,17 +1,17 @@ -import { HomeNavbar } from "~/components/homepage"; -import { MainFooter } from "~/components/main-footer"; - -export default function NotFoundPage() { - return ( -
    - -
    -

    404 - Page Not Found

    -

    - Whoops! That page doesn’t exist. But do not fret, check out our other resources to get started. -

    -
    - -
    - ); -} +import { HomeNavbar } from "~/components/homepage"; +import { MainFooter } from "~/components/main-footer"; + +export default function NotFoundPage() { + return ( +
    + +
    +

    404 - Page Not Found

    +

    + Whoops! That page doesn’t exist. But do not fret, check out our other resources to get started. +

    +
    + +
    + ); +} diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx index dfb6d2c50..041ba1642 100644 --- a/apps/web/app/page.tsx +++ b/apps/web/app/page.tsx @@ -1,34 +1,34 @@ -import { - ComponentsSection, - ContributorsSection, - DarkModeSection, - FeaturedSection, - FigmaSection, - HeroSection, - HomeNavbar, - ReactSection, - SocialProofSection, - TailwindSection, -} from "~/components/homepage"; -import { MainFooter } from "~/components/main-footer"; - -export default function HomePage() { - return ( -
    - {/* */} - -
    - - - - - - - - - -
    - -
    - ); -} +import { + ComponentsSection, + ContributorsSection, + DarkModeSection, + FeaturedSection, + FigmaSection, + HeroSection, + HomeNavbar, + ReactSection, + SocialProofSection, + TailwindSection, +} from "~/components/homepage"; +import { MainFooter } from "~/components/main-footer"; + +export default function HomePage() { + return ( +
    + {/* */} + +
    + + + + + + + + + +
    + +
    + ); +} diff --git a/apps/web/components/banner.tsx b/apps/web/components/banner.tsx index d8bf6f479..bc2d45b1d 100644 --- a/apps/web/components/banner.tsx +++ b/apps/web/components/banner.tsx @@ -1,40 +1,40 @@ -import Link from "next/link"; - -export function Banner() { - return ( -
    -
    -

    - - New - - Flowbite React now supports Server Components and has full Next.js App Router support! - - Check it out - - -

    -
    -
    - ); -} +import Link from "next/link"; + +export function Banner() { + return ( +
    +
    +

    + + New + + Flowbite React now supports Server Components and has full Next.js App Router support! + + Check it out + + +

    +
    +
    + ); +} diff --git a/apps/web/components/carbon-ads.tsx b/apps/web/components/carbon-ads.tsx index 14603bb6e..6de1166c4 100644 --- a/apps/web/components/carbon-ads.tsx +++ b/apps/web/components/carbon-ads.tsx @@ -1,40 +1,40 @@ -"use client"; - -import { usePathname } from "next/navigation"; -import { useEffect } from "react"; - -interface WindowWithCarbonAds extends Window { - _carbonads: { - refresh: () => void; - }; -} - -export function CarbonAds() { - const pathname = usePathname(); - - const isDevelopmentMode = process.env.NODE_ENV === "development"; - - useEffect(() => { - const isCarbonAdsRendered = document.querySelector("#carbonads"); - - if (isCarbonAdsRendered) { - (window as unknown as WindowWithCarbonAds)._carbonads.refresh(); - } else { - const script = document.createElement("script"); - script.async = true; - script.id = "_carbonads_js"; - script.src = "//cdn.carbonads.com/carbon.js?serve=CEAIC53L&placement=flowbite-reactcom"; - - const container = document.querySelector("#carbon-container"); - if (container) { - container.appendChild(script); - } - } - }, [pathname]); - - return isDevelopmentMode ? null : ( - - ); -} +"use client"; + +import { usePathname } from "next/navigation"; +import { useEffect } from "react"; + +interface WindowWithCarbonAds extends Window { + _carbonads: { + refresh: () => void; + }; +} + +export function CarbonAds() { + const pathname = usePathname(); + + const isDevelopmentMode = process.env.NODE_ENV === "development"; + + useEffect(() => { + const isCarbonAdsRendered = document.querySelector("#carbonads"); + + if (isCarbonAdsRendered) { + (window as unknown as WindowWithCarbonAds)._carbonads.refresh(); + } else { + const script = document.createElement("script"); + script.async = true; + script.id = "_carbonads_js"; + script.src = "//cdn.carbonads.com/carbon.js?serve=CEAIC53L&placement=flowbite-reactcom"; + + const container = document.querySelector("#carbon-container"); + if (container) { + container.appendChild(script); + } + } + }, [pathname]); + + return isDevelopmentMode ? null : ( + + ); +} diff --git a/apps/web/components/code-demo.tsx b/apps/web/components/code-demo.tsx index b83d0465c..34fdb7a6a 100644 --- a/apps/web/components/code-demo.tsx +++ b/apps/web/components/code-demo.tsx @@ -1,387 +1,387 @@ -"use client"; - -import { Select, Tooltip, useThemeMode } from "flowbite-react"; -import type { ComponentProps, PropsWithChildren } from "react"; -import { useEffect, useRef, useState } from "react"; -import type { IconType } from "react-icons"; -import { FaCopy } from "react-icons/fa"; -import { HiMoon, HiSun } from "react-icons/hi"; -import { HiMiniDeviceTablet } from "react-icons/hi2"; -import { PiDesktop } from "react-icons/pi"; -import { TfiMobile } from "react-icons/tfi"; -import { twMerge } from "tailwind-merge"; -import { CodeHighlight, type Language } from "./code-highlight"; - -type IFrameData = number | IFrameOptions; - -interface IFrameOptions { - height: number; - noPadding?: boolean; -} - -interface BaseCodeData { - type: T; - githubSlug: string; - component: React.ReactNode; - iframe?: IFrameData; -} - -interface VariantCodeData extends BaseCodeData<"variant"> { - variant: V; - code: CodeVariant; -} - -interface SingleCodeData extends BaseCodeData<"single"> { - code: Code; -} - -interface CodeItem { - fileName: string; - language: Language; - code: string; -} - -type Variant = string; -type CodeVariant = Record; -type Code = CodeItem | [CodeItem, ...CodeItem[]]; - -export type CodeData = SingleCodeData | VariantCodeData; - -type View = "desktop" | "tablet" | "mobile"; - -interface CodeDemoProps { - data: CodeData; -} - -export function CodeDemo({ data }: CodeDemoProps) { - const { computedMode } = useThemeMode(); - - const [tabIndex, setTabIndex] = useState(0); - const [variant, setVariant] = useState(getInitialVariant(data)); - - const [view, setView] = useState("desktop"); - const [isRTL, setIsRTL] = useState(false); - const [isDarkMode, setDarkMode] = useState(null); - const [isExpanded, setExpanded] = useState(false); - const [isJustCopied, setJustCopied] = useState(false); - - useEffect(() => setDarkMode(computedMode === "dark"), [computedMode]); - - function copyToClipboard(value: string) { - setJustCopied(true); - navigator.clipboard.writeText(value); - setTimeout(() => setJustCopied(false), 2000); - } - - function getInitialVariant(data: CodeData): Variant { - if (data.type === "variant") return data.variant; - - return ""; - } - - function getVariants(data: CodeData): Variant[] { - if (data.type === "variant") return Object.keys(data.code); - - return []; - } - - function getCode(data: CodeData, variant: Variant): Code { - if (data.type === "variant") return data.code[variant]; - - return data.code; - } - - function getCodeItems(code: Code): CodeItem[] { - return Array.isArray(code) ? code : [code]; - } - - function getCurrent(items: CodeItem[], index: number): CodeItem { - return items[index]; - } - - function handleSelectVariant(variant: Variant) { - setTabIndex(0); - setVariant(variant); - } - - function getShouldExpand(rawCode: string) { - const rem = 16; - const offset = 41; // expand/collapse button height - const padding = 28; - const maxHeight = 18 * rem + offset; // mirror `max-h-72` - const codeHeight = getTextHeight(rawCode) + padding; - - return codeHeight > maxHeight; - } - - function getTextHeight(value: string) { - const fontSize = 16.5; - const lineHeight = 1.25; - - return countLines(value) * fontSize * lineHeight; - } - - function countLines(value: string) { - return (value.match(/\n/g) || "").length + 1; - } - - const variants = getVariants(data); - const code = getCode(data, variant); - const codeItems = getCodeItems(code); - const current = getCurrent(codeItems, tabIndex); - const shouldExpand = getShouldExpand(current.code.trim()); - - return ( -
    -
    -
    - - -
    - setIsRTL((state) => !state)} /> - setDarkMode((state) => !state)} /> -
    -
    -
    - - {data.iframe ?