Repository: themesberg/flowbite-angular Branch: main Commit: 9ee23130fdac Files: 623 Total size: 1.2 MB Directory structure: gitextract_kk6wkjj8/ ├── .coderabbit.yaml ├── .eslintignore ├── .eslintrc.json ├── .github/ │ ├── CODE_OF_CONDUCT │ ├── CONTRIBUTING │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yaml │ │ └── feature_request.yaml │ ├── PULL_REQUEST_TEMPLATE/ │ │ ├── default_request_template.md │ │ └── release_request_template.md │ ├── pull_request_template.md │ └── workflows/ │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .husky/ │ ├── commit-msg │ └── pre-commit ├── .lintstagedrc ├── .prettierignore ├── .prettierrc ├── .stylelintrc.json ├── .vscode/ │ ├── extensions.json │ └── settings.json ├── LICENSE ├── README.md ├── apps/ │ ├── .gitkeep │ ├── docs/ │ │ ├── .eslintrc.json │ │ ├── docs/ │ │ │ ├── components/ │ │ │ │ ├── accordion/ │ │ │ │ │ ├── _always-open.component.html │ │ │ │ │ ├── _always-open.component.ts │ │ │ │ │ ├── _color.component.html │ │ │ │ │ ├── _color.component.ts │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── _flush.component.html │ │ │ │ │ ├── _flush.component.ts │ │ │ │ │ ├── _icon.component.html │ │ │ │ │ ├── _icon.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── alert/ │ │ │ │ │ ├── _border-accent.component.html │ │ │ │ │ ├── _border-accent.component.ts │ │ │ │ │ ├── _border.component.html │ │ │ │ │ ├── _border.component.ts │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── _dismissable.component.html │ │ │ │ │ ├── _dismissable.component.ts │ │ │ │ │ ├── _icon.component.html │ │ │ │ │ ├── _icon.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── badge/ │ │ │ │ │ ├── _border.component.html │ │ │ │ │ ├── _border.component.ts │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── _dismiss.component.html │ │ │ │ │ ├── _dismiss.component.ts │ │ │ │ │ ├── _icon.component.html │ │ │ │ │ ├── _icon.component.ts │ │ │ │ │ ├── _link.component.html │ │ │ │ │ ├── _link.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── breadcrumb/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── button/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── _disabled.component.html │ │ │ │ │ ├── _disabled.component.ts │ │ │ │ │ ├── _group.component.html │ │ │ │ │ ├── _group.component.ts │ │ │ │ │ ├── _icon.component.html │ │ │ │ │ ├── _icon.component.ts │ │ │ │ │ ├── _outline.component.html │ │ │ │ │ ├── _outline.component.ts │ │ │ │ │ ├── _pill.component.html │ │ │ │ │ ├── _pill.component.ts │ │ │ │ │ ├── _size.component.html │ │ │ │ │ ├── _size.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── card/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── clipboard/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── dropdown/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── icon/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── indicator/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── input/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── modal/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── _open-programatically.component.html │ │ │ │ │ ├── _open-programatically.component.ts │ │ │ │ │ ├── _position.component.html │ │ │ │ │ ├── _position.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── navbar/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── ng-doc.category.ts │ │ │ │ ├── pagination/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── sidebar/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── tab/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── table/ │ │ │ │ │ ├── _default.component.html │ │ │ │ │ ├── _default.component.ts │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ └── tooltip/ │ │ │ │ ├── _default.component.html │ │ │ │ ├── _default.component.ts │ │ │ │ ├── index.md │ │ │ │ └── ng-doc.page.ts │ │ │ ├── customize/ │ │ │ │ ├── dark-mode/ │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── ng-doc.category.ts │ │ │ │ ├── override-base-style/ │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── theming/ │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ └── use-custom-style/ │ │ │ │ ├── index.md │ │ │ │ └── ng-doc.page.ts │ │ │ ├── doc-theme.model.ts │ │ │ ├── getting-started/ │ │ │ │ ├── introduction/ │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── license/ │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ ├── ng-doc.category.ts │ │ │ │ ├── ng-primitives/ │ │ │ │ │ ├── index.md │ │ │ │ │ └── ng-doc.page.ts │ │ │ │ └── quickstart/ │ │ │ │ ├── index.md │ │ │ │ └── ng-doc.page.ts │ │ │ ├── ng-doc.api.ts │ │ │ └── shared/ │ │ │ └── theme-macro.md │ │ ├── ng-doc.config.ts │ │ ├── postcss.config.json │ │ ├── project.json │ │ ├── public/ │ │ │ ├── .gitkeep │ │ │ └── css/ │ │ │ ├── ng-doc/ │ │ │ │ └── base.css │ │ │ ├── styles.css │ │ │ └── tw/ │ │ │ └── fonts.css │ │ ├── server.ts │ │ ├── src/ │ │ │ ├── app/ │ │ │ │ ├── app.component.html │ │ │ │ ├── app.component.ts │ │ │ │ ├── app.config.server.ts │ │ │ │ ├── app.config.ts │ │ │ │ ├── app.routes.ts │ │ │ │ ├── pages/ │ │ │ │ │ ├── docs/ │ │ │ │ │ │ ├── docs.component.css │ │ │ │ │ │ ├── docs.component.html │ │ │ │ │ │ ├── docs.component.ts │ │ │ │ │ │ └── docs.routes.ts │ │ │ │ │ └── landing/ │ │ │ │ │ ├── landing.component.html │ │ │ │ │ ├── landing.component.ts │ │ │ │ │ └── landing.routes.ts │ │ │ │ └── shared/ │ │ │ │ ├── components/ │ │ │ │ │ └── flowbite-doc-demo-displayer/ │ │ │ │ │ └── flowbite-doc-demo-displayer.component.ts │ │ │ │ ├── header-template.html │ │ │ │ └── processors/ │ │ │ │ └── doc-demo-displayer-processor/ │ │ │ │ └── doc-demo-displayer-processor.ts │ │ │ ├── environments/ │ │ │ │ ├── environment.prod.ts │ │ │ │ └── environment.ts │ │ │ ├── index.html │ │ │ ├── main.server.ts │ │ │ └── main.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.editor.json │ │ └── tsconfig.json │ └── storybook/ │ ├── .eslintrc.json │ ├── .storybook/ │ │ ├── helper.ts │ │ ├── main.ts │ │ ├── preview-body.html │ │ ├── preview.ts │ │ └── tsconfig.json │ ├── postcss.config.json │ ├── project.json │ ├── src/ │ │ ├── accordion.component.stories.ts │ │ ├── alert.stories.ts │ │ ├── badge.stories.ts │ │ ├── breadcrumb.stories.ts │ │ ├── button.component.stories.ts │ │ ├── card.component.stories.ts │ │ ├── clipboard.component.stories.ts │ │ ├── dropdown.stories.ts │ │ ├── form/ │ │ │ └── form-field.component.stories.ts │ │ ├── icon.component.stories.ts │ │ ├── indicator.stories.ts │ │ ├── modal.component.stories.ts │ │ ├── navbar.component.stories.ts │ │ ├── pagination.component.stories.ts │ │ ├── sidebar.component.stories.ts │ │ ├── tab.component.stories.ts │ │ ├── table.component.stories.ts │ │ └── tooltip.component.stories.ts │ ├── styles.css │ ├── tsconfig.editor.json │ └── tsconfig.json ├── commitlint.config.cjs ├── libs/ │ ├── .gitkeep │ ├── flowbite-angular/ │ │ ├── .eslintrc.json │ │ ├── LICENSE │ │ ├── README.md │ │ ├── accordion/ │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── accordion/ │ │ │ │ ├── accordion-state.ts │ │ │ │ ├── accordion.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── accordion-content/ │ │ │ │ ├── accordion-content-state.ts │ │ │ │ ├── accordion-content.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── accordion-item/ │ │ │ │ ├── accordion-item-state.ts │ │ │ │ ├── accordion-item.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── accordion-title/ │ │ │ │ ├── accordion-title-state.ts │ │ │ │ ├── accordion-title.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ ├── accordion-config.ts │ │ │ │ ├── accordion-content-config.ts │ │ │ │ ├── accordion-item-config.ts │ │ │ │ └── accordion-title-config.ts │ │ │ └── index.ts │ │ ├── alert/ │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── alert/ │ │ │ │ ├── alert-state.ts │ │ │ │ ├── alert.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── alert-button/ │ │ │ │ ├── alert-button-state.ts │ │ │ │ ├── alert-button.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── alert-content/ │ │ │ │ ├── alert-content-state.ts │ │ │ │ ├── alert-content.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ ├── alert-button-config.ts │ │ │ │ ├── alert-config.ts │ │ │ │ └── alert-content-config.ts │ │ │ └── index.ts │ │ ├── badge/ │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── badge/ │ │ │ │ ├── badge-state.ts │ │ │ │ ├── badge.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── badge-button/ │ │ │ │ ├── badge-button-state.ts │ │ │ │ ├── badge-button.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── badge-link/ │ │ │ │ ├── badge-link-state.ts │ │ │ │ ├── badge-link.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ ├── badge-button-config.ts │ │ │ │ ├── badge-config.ts │ │ │ │ └── badge-link-config.ts │ │ │ └── index.ts │ │ ├── breadcrumb/ │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── breadcrumb/ │ │ │ │ ├── breadcrumb-state.ts │ │ │ │ ├── breadcrumb.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── breadcrumb-content/ │ │ │ │ ├── breadcrumb-content-state.ts │ │ │ │ ├── breadcrumb-content.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── breadcrumb-item/ │ │ │ │ ├── breadcrumb-item-state.ts │ │ │ │ ├── breadcrumb-item.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ ├── breadcrumb-config.ts │ │ │ │ ├── breadcrumb-content-config.ts │ │ │ │ └── breadcrumb-item-config.ts │ │ │ └── index.ts │ │ ├── button/ │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── base-button/ │ │ │ │ ├── base-button-state.ts │ │ │ │ ├── base-button.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── button/ │ │ │ │ ├── button-state.ts │ │ │ │ ├── button.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ ├── base-button-config.ts │ │ │ │ └── button-config.ts │ │ │ └── index.ts │ │ ├── button-group/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── button-group/ │ │ │ │ ├── button-group-state.ts │ │ │ │ ├── button-group.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ └── button-group-config.ts │ │ │ └── index.ts │ │ ├── card/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── card/ │ │ │ │ ├── card-state.ts │ │ │ │ ├── card.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── card-content/ │ │ │ │ ├── card-content-state.ts │ │ │ │ ├── card-content.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── card-header/ │ │ │ │ ├── card-header-state.ts │ │ │ │ ├── card-header.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ ├── card-config.ts │ │ │ │ ├── card-content-config.ts │ │ │ │ └── card-header-config.ts │ │ │ └── index.ts │ │ ├── clipboard/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── clipboard/ │ │ │ │ ├── clipboard-state.ts │ │ │ │ ├── clipboard.component.ts │ │ │ │ └── theme.ts │ │ │ ├── config/ │ │ │ │ └── clipboard-config.ts │ │ │ └── index.ts │ │ ├── core/ │ │ │ └── src/ │ │ │ ├── core/ │ │ │ │ ├── flowbite.boolean.ts │ │ │ │ ├── flowbite.colors.ts │ │ │ │ ├── flowbite.deep-partial.ts │ │ │ │ ├── flowbite.positions.ts │ │ │ │ ├── flowbite.sizes.ts │ │ │ │ └── flowbite.themes.ts │ │ │ ├── index.ts │ │ │ └── utils/ │ │ │ ├── clone-deep.ts │ │ │ ├── color-to-theme.ts │ │ │ ├── create-theme.ts │ │ │ ├── is-object.ts │ │ │ └── merge-theme.ts │ │ ├── dropdown/ │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── dropdown-config.ts │ │ │ │ ├── dropdown-content-config.ts │ │ │ │ └── dropdown-item-config.ts │ │ │ ├── dropdown/ │ │ │ │ ├── dropdown-state.ts │ │ │ │ ├── dropdown.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── dropdown-content/ │ │ │ │ ├── dropdown-content-state.ts │ │ │ │ ├── dropdown-content.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── dropdown-item/ │ │ │ │ ├── dropdown-item-state.ts │ │ │ │ ├── dropdown-item.directive.ts │ │ │ │ └── theme.ts │ │ │ └── index.ts │ │ ├── form/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── form-control-config.ts │ │ │ │ ├── form-field-config.ts │ │ │ │ ├── helper-config.ts │ │ │ │ └── label-config.ts │ │ │ ├── form-control/ │ │ │ │ ├── form-control-state.ts │ │ │ │ ├── form-control.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── form-field/ │ │ │ │ ├── form-field-state.ts │ │ │ │ ├── form-field.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── helper/ │ │ │ │ ├── helper-state.ts │ │ │ │ ├── helper.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── index.ts │ │ │ └── label/ │ │ │ ├── label-state.ts │ │ │ ├── label.directive.ts │ │ │ └── theme.ts │ │ ├── icon/ │ │ │ ├── README.md │ │ │ ├── brand/ │ │ │ │ ├── README.md │ │ │ │ ├── ng-package.json │ │ │ │ └── src/ │ │ │ │ └── index.ts │ │ │ ├── ng-package.json │ │ │ ├── outline/ │ │ │ │ ├── README.md │ │ │ │ ├── arrows/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── e-commerce/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── emoji/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── files-folders/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── general/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── media/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── ng-package.json │ │ │ │ ├── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── text/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── user/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ └── weather/ │ │ │ │ ├── ng-package.json │ │ │ │ └── src/ │ │ │ │ └── index.ts │ │ │ ├── solid/ │ │ │ │ ├── README.md │ │ │ │ ├── arrows/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── brands/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── e-commerce/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── emoji/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── files-folder/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── general/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── media/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── ng-package.json │ │ │ │ ├── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── text/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ ├── user/ │ │ │ │ │ ├── ng-package.json │ │ │ │ │ └── src/ │ │ │ │ │ └── index.ts │ │ │ │ └── weather/ │ │ │ │ ├── ng-package.json │ │ │ │ └── src/ │ │ │ │ └── index.ts │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ └── icon-config.ts │ │ │ ├── icon/ │ │ │ │ ├── icon-state.ts │ │ │ │ ├── icon.component.ts │ │ │ │ └── theme.ts │ │ │ └── index.ts │ │ ├── indicator/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ └── indicator-config.ts │ │ │ ├── index.ts │ │ │ └── indicator/ │ │ │ ├── indicator-state.ts │ │ │ ├── indicator.directive.ts │ │ │ └── theme.ts │ │ ├── modal/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── modal-config.ts │ │ │ │ ├── modal-content-config.ts │ │ │ │ ├── modal-footer-config.ts │ │ │ │ ├── modal-header-config.ts │ │ │ │ └── modal-overlay-config.ts │ │ │ ├── index.ts │ │ │ ├── modal/ │ │ │ │ ├── modal-state.ts │ │ │ │ ├── modal.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── modal-content/ │ │ │ │ ├── modal-content-state.ts │ │ │ │ ├── modal-content.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── modal-footer/ │ │ │ │ ├── modal-footer-state.ts │ │ │ │ ├── modal-footer.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── modal-header/ │ │ │ │ ├── modal-header-state.ts │ │ │ │ ├── modal-header.directive.ts │ │ │ │ └── theme.ts │ │ │ └── modal-overlay/ │ │ │ ├── modal-overlay-state.ts │ │ │ ├── modal-overlay.directive.ts │ │ │ └── theme.ts │ │ ├── navbar/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── navbar-brand-config.ts │ │ │ │ ├── navbar-config.ts │ │ │ │ ├── navbar-content-config.ts │ │ │ │ ├── navbar-icon-item-config.ts │ │ │ │ ├── navbar-item-config.ts │ │ │ │ └── navbar-toggle-config.ts │ │ │ ├── index.ts │ │ │ ├── navbar/ │ │ │ │ ├── navbar-state.ts │ │ │ │ ├── navbar.component.ts │ │ │ │ └── theme.ts │ │ │ ├── navbar-brand/ │ │ │ │ ├── navbar-brand-state.ts │ │ │ │ ├── navbar-brand.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── navbar-content/ │ │ │ │ ├── navbar-content-state.ts │ │ │ │ ├── navbar-content.component.ts │ │ │ │ └── theme.ts │ │ │ ├── navbar-icon-item/ │ │ │ │ ├── navbar-icon-item-state.ts │ │ │ │ ├── navbar-icon-item.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── navbar-item/ │ │ │ │ ├── navbar-item-state.ts │ │ │ │ ├── navbar-item.directive.ts │ │ │ │ └── theme.ts │ │ │ └── navbar-toggle/ │ │ │ ├── navbar-toggle-state.ts │ │ │ ├── navbar-toggle.directive.ts │ │ │ └── theme.ts │ │ ├── ng-package.json │ │ ├── package.json │ │ ├── pagination/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── pagination-button-config.ts │ │ │ │ ├── pagination-config.ts │ │ │ │ ├── pagination-first-config.ts │ │ │ │ ├── pagination-last-config.ts │ │ │ │ ├── pagination-next-config.ts │ │ │ │ └── pagination-previous-config.ts │ │ │ ├── index.ts │ │ │ ├── pagination/ │ │ │ │ ├── pagination-state.ts │ │ │ │ ├── pagination.component.ts │ │ │ │ └── theme.ts │ │ │ ├── pagination-button/ │ │ │ │ ├── pagination-button-state.ts │ │ │ │ ├── pagination-button.component.ts │ │ │ │ └── theme.ts │ │ │ ├── pagination-first/ │ │ │ │ ├── pagination-first-state.ts │ │ │ │ ├── pagination-first.component.ts │ │ │ │ └── theme.ts │ │ │ ├── pagination-last/ │ │ │ │ ├── pagination-last-state.ts │ │ │ │ ├── pagination-last.component.ts │ │ │ │ └── theme.ts │ │ │ ├── pagination-next/ │ │ │ │ ├── pagination-next-state.ts │ │ │ │ ├── pagination-next.component.ts │ │ │ │ └── theme.ts │ │ │ └── pagination-previous/ │ │ │ ├── pagination-previous-state.ts │ │ │ ├── pagination-previous.component.ts │ │ │ └── theme.ts │ │ ├── project.json │ │ ├── sidebar/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── sidebar-config.ts │ │ │ │ ├── sidebar-content-config.ts │ │ │ │ ├── sidebar-item-config.ts │ │ │ │ └── sidebar-toggle-config.ts │ │ │ ├── index.ts │ │ │ ├── sidebar/ │ │ │ │ ├── sidebar-state.ts │ │ │ │ ├── sidebar.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── sidebar-content/ │ │ │ │ ├── sidebar-content-state.ts │ │ │ │ ├── sidebar-content.component.ts │ │ │ │ └── theme.ts │ │ │ ├── sidebar-item/ │ │ │ │ ├── sidebar-item-state.ts │ │ │ │ ├── sidebar-item.directive.ts │ │ │ │ └── theme.ts │ │ │ └── sidebar-toggle/ │ │ │ ├── sidebar-toggle-state.ts │ │ │ ├── sidebar-toggle.directive.ts │ │ │ └── theme.ts │ │ ├── styles/ │ │ │ ├── flowbite-angular.css │ │ │ └── part/ │ │ │ └── animation.css │ │ ├── tab/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── tab-button-config.ts │ │ │ │ ├── tab-config.ts │ │ │ │ ├── tab-content-config.ts │ │ │ │ └── tab-list-config.ts │ │ │ ├── index.ts │ │ │ ├── tab/ │ │ │ │ ├── tab-state.ts │ │ │ │ ├── tab.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── tab-button/ │ │ │ │ ├── tab-button-state.ts │ │ │ │ ├── tab-button.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── tab-content/ │ │ │ │ ├── tab-content-state.ts │ │ │ │ ├── tab-content.directive.ts │ │ │ │ └── theme.ts │ │ │ └── tab-list/ │ │ │ ├── tab-list-state.ts │ │ │ ├── tab-list.directive.ts │ │ │ └── theme.ts │ │ ├── table/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── table-body-config.ts │ │ │ │ ├── table-config.ts │ │ │ │ ├── table-foot-config.ts │ │ │ │ └── table-head-config.ts │ │ │ ├── index.ts │ │ │ ├── table/ │ │ │ │ ├── table-state.ts │ │ │ │ ├── table.component.ts │ │ │ │ └── theme.ts │ │ │ ├── table-body/ │ │ │ │ ├── table-body-state.ts │ │ │ │ ├── table-body.directive.ts │ │ │ │ └── theme.ts │ │ │ ├── table-foot/ │ │ │ │ ├── table-foot-state.ts │ │ │ │ ├── table-foot.directive.ts │ │ │ │ └── theme.ts │ │ │ └── table-head/ │ │ │ ├── table-head-state.ts │ │ │ ├── table-head.directive.ts │ │ │ └── theme.ts │ │ ├── theme-toggle/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ ├── theme-config.ts │ │ │ │ └── theme-toggle-config.ts │ │ │ ├── index.ts │ │ │ ├── theme/ │ │ │ │ ├── theme-state.ts │ │ │ │ └── theme.directive.ts │ │ │ └── theme-toggle/ │ │ │ ├── theme-toggle-state.ts │ │ │ ├── theme-toggle.component.ts │ │ │ └── theme.ts │ │ ├── tooltip/ │ │ │ ├── README.md │ │ │ ├── ng-package.json │ │ │ └── src/ │ │ │ ├── config/ │ │ │ │ └── tooltip-config.ts │ │ │ ├── index.ts │ │ │ └── tooltip/ │ │ │ ├── theme.ts │ │ │ ├── tooltip-state.ts │ │ │ └── tooltip.directive.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.lib.json │ │ └── tsconfig.lib.prod.json │ └── tools/ │ ├── .eslintrc.json │ ├── README.md │ ├── generators.json │ ├── package.json │ ├── project.json │ ├── src/ │ │ ├── generators/ │ │ │ ├── component/ │ │ │ │ ├── files/ │ │ │ │ │ ├── component/ │ │ │ │ │ │ └── __directoryName__/ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ ├── __fileName__/ │ │ │ │ │ │ │ ├── __fileName__-state.ts.template │ │ │ │ │ │ │ ├── __fileName__.component.ts.template │ │ │ │ │ │ │ └── theme.ts.template │ │ │ │ │ │ └── config/ │ │ │ │ │ │ └── __fileName__-config.ts.template │ │ │ │ │ └── directive/ │ │ │ │ │ └── __directoryName__/ │ │ │ │ │ └── src/ │ │ │ │ │ ├── __fileName__/ │ │ │ │ │ │ ├── __fileName__-state.ts.template │ │ │ │ │ │ ├── __fileName__.directive.ts.template │ │ │ │ │ │ └── theme.ts.template │ │ │ │ │ └── config/ │ │ │ │ │ └── __fileName__-config.ts.template │ │ │ │ ├── generator.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ ├── documentation/ │ │ │ │ ├── files/ │ │ │ │ │ └── __fileName__/ │ │ │ │ │ ├── _default.component.html.template │ │ │ │ │ ├── _default.component.ts.template │ │ │ │ │ ├── index.md.template │ │ │ │ │ └── ng-doc.page.ts.template │ │ │ │ ├── generator.ts │ │ │ │ ├── schema.d.ts │ │ │ │ └── schema.json │ │ │ └── storybook/ │ │ │ ├── files/ │ │ │ │ └── __fileName__.component.stories.ts.template │ │ │ ├── generator.ts │ │ │ ├── schema.d.ts │ │ │ └── schema.json │ │ ├── index.ts │ │ └── utils/ │ │ └── index.ts │ ├── tsconfig.json │ └── tsconfig.lib.json ├── nx.json ├── package.json ├── pnpm-workspace.yaml └── tsconfig.base.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .coderabbit.yaml ================================================ language: en-US tone_instructions: '' early_access: false enable_free_tier: true reviews: profile: chill request_changes_workflow: false high_level_summary: true high_level_summary_placeholder: '@coderabbitai summary' auto_title_placeholder: '@coderabbitai' poem: true review_status: true collapse_walkthrough: false path_filters: [] path_instructions: [] abort_on_close: true auto_review: enabled: true auto_incremental_review: true ignore_title_keywords: [] labels: [] drafts: true base_branches: [] tools: shellcheck: enabled: true ruff: enabled: true markdownlint: enabled: true github-checks: enabled: true timeout_ms: 90000 languagetool: enabled: true disabled_rules: - EN_UNPAIRED_BRACKETS - EN_UNPAIRED_QUOTES disabled_categories: - TYPOS - TYPOGRAPHY - CASING enabled_only: false level: default biome: enabled: true hadolint: enabled: false swiftlint: enabled: false phpstan: enabled: false level: default golangci-lint: enabled: false yamllint: enabled: true gitleaks: enabled: true checkov: enabled: true chat: auto_reply: true knowledge_base: learnings: scope: auto issues: scope: auto jira: project_keys: [] linear: team_keys: [] ================================================ FILE: .eslintignore ================================================ node_modules dist ================================================ FILE: .eslintrc.json ================================================ { "root": true, "ignorePatterns": ["!**/*"], "plugins": ["@nx", "@typescript-eslint", "prettier"], "extends": ["plugin:@nx/angular", "plugin:@typescript-eslint/recommended", "prettier"], "overrides": [ { "files": "*.json", "parser": "jsonc-eslint-parser", "rules": {} }, { "files": ["*.ts"], "rules": { "prettier/prettier": [ "error", { "endOfLine": "auto" } ], "no-extra-semi": "off", "comma-dangle": "off", "no-empty-function": "off", "@typescript-eslint/no-extra-semi": "error", "@typescript-eslint/no-empty-function": "warn", "@typescript-eslint/no-explicit-any": "warn", "@typescript-eslint/consistent-type-imports": "error", "@nx/enforce-module-boundaries": "error" } } ] } ================================================ FILE: .github/CODE_OF_CONDUCT ================================================ # 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 ================================================ FILE: .github/CONTRIBUTING ================================================ # Contributing guide ## What do I need to know to help? If you are looking to help to with a code contribution our project uses Typescript, Angular and TailwindCSS. If you don't feel ready to make a code contribution yet, no problem! If you are interested in making a code contribution and would like to learn more about the technologies that we use, check out the list below. - [Angular Tutorial for Beginners: Learn Angular & TypeScript](https://www.youtube.com/watch?v=k5E2AVpwsko) - [TypeScript Course](https://www.youtube.com/watch?v=BwuLxPH8IDs) - [TailwindCSS](https://tailwindcss.com/) ## How do I make a contribution? Never made an open source contribution before? Wondering how contributions work in the in our project? Here's a quick rundown! 1. [Find an issue](https://github.com/themesberg/flowbite-angular/issues) that you are interested in addressing or a feature that you would like to add. 2. Fork the repository associated with the issue to your local GitHub organization. This means that you will have a copy of the repository under `your-GitHub-username/repository-name`. 3. Clone the repository to your local machine using `git clone https://github.com/github-username/repository-name.git`. 4. Create a new branch for your fix using `git checkout -b branch-name-here`. 5. Make the appropriate changes for the issue you are trying to address or the feature that you want to add. 6. Use `git add insert-paths-of-changed-files-here` to add the file contents of the changed files to the "snapshot" git uses to manage the state of the project, also known as the index. 7. Use `git commit -m "Insert a short message of the changes made here"` to store the contents of the index with a descriptive message. Use [conventional commits](https://www.conventionalcommits.org/) to create a nice message. 8. Push the changes to the remote repository using `git push origin branch-name-here`. 9. Submit a pull request to the upstream repository. 10. Title the pull request with a short description of the changes made and the issue or bug number associated with your change. For example, you can title an issue like so `"Added more log outputting to resolve #4352"`. 11. In the description of the pull request, explain the changes that you made, any issues you think exist with the pull request you made, and any questions you have for the maintainer. It's OK if your pull request is not perfect (no pull request is), the reviewer will be able to help you fix any problems and improve it! 12. Wait for the pull request to be reviewed by a maintainer. 13. Make changes to the pull request if the reviewing maintainer recommends them. 14. Celebrate your success after your pull request is merged! 🎉 🎉 ## Where can I go for help? If you need help, you can ask questions please, [join us at our Discord Community](https://discord.gg/S6J9pUmj2t). ## What does the Code of Conduct mean for me? Our Code of Conduct means that you are responsible for treating everyone on the project with respect and courtesy regardless of their identity. If you are the victim of any inappropriate behavior or comments as described in our Code of Conduct, we are here for you and will do the best to ensure that the abuser is reprimanded appropriately, per our code. ## Code of conduct For more information [check this file](CODE_OF_CONDUCT). ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yaml ================================================ name: '🐞 Bug Report' description: Report a bug title: '[Bug] {SCOPE} - ' labels: 'Type: bug' assignees: MGREMY body: - type: dropdown id: is-regression attributes: label: Is this a regression? options: - 'Yes' - 'No' - "I don't know" validations: required: true - type: textarea id: description attributes: label: Description placeholder: | A clear and concise description of what the bug is. What is the current behavior? What is the expected behavior? Please provide a link to a minimal reproduction of the problem with instructions. validations: required: true - type: textarea id: exception-or-error attributes: label: Please provide the exception or error you saw render: true - type: dropdown id: os attributes: label: OS options: - Unix (Linux, macOS, etc.) - Windows - iOS, Android, etc. - Something else validations: required: true - type: dropdown id: browser attributes: label: Browser options: - Chrome - Firefox - Safari - Edge - IE - Other - type: input id: node-version attributes: label: Node version validations: required: true - type: input id: flowbite-angular-version attributes: label: Flowbite-angular version validations: required: true - type: textarea id: other attributes: label: Anything else? placeholder: | Please provide any additional information that may be helpful in understanding the issue. If you have a screenshot, attach it here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yaml ================================================ name: '🚀 Feature Request' description: Suggest a feature title: '[Feature] {SCOPE} - ' labels: 'Type: enhancement' assignees: MGREMY body: - type: textarea id: description attributes: label: Description placeholder: | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] validations: required: true - type: textarea id: proposed-solution attributes: label: Proposed solution placeholder: | A clear and concise description of what you want to happen. What is the expected behavior? What is the current behavior? What is the motivation / use case for changing the behavior? validations: required: true - type: textarea id: alternatives-considered attributes: label: Alternatives considered placeholder: | A clear and concise description of any alternative solutions or features you've considered. ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/default_request_template.md ================================================ ## PR Checklist Please check if your PR fulfills the following requirements: - [ ] Docs have been added/updated (for bug fixes/features) ## PR Type What kind of change does this PR introduce? - [ ] Bugfix - [ ] Feature - [ ] Code style update (formatting, local variables) - [ ] Refactoring (no functional changes, no API changes) - [ ] Build related changes - [ ] CI-related changes - [ ] Documentation content changes - [ ] Other... Please describe: ## Issue Number Issue Number: N/A ## Does this PR introduce a breaking change? - [ ] Yes - [ ] No ## Other information @coderabbitai summary ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/release_request_template.md ================================================ ## PR Type What kind of change does this PR introduce? - [x] Release ================================================ FILE: .github/pull_request_template.md ================================================ Please go to the `Preview` tab and select the appropriate sub-template: * [Default](?expand=1&template=default_request_template.md) * [Release](?expand=1&template=release_request_template.md) ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI Checks on: workflow_dispatch: pull_request: concurrency: ${{ github.ref }} jobs: lint: strategy: matrix: node-version: [20] name: Lint the code 🕵 runs-on: ubuntu-latest steps: - name: Check out the code 🗄 uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 10 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' - name: Install dependencies shell: bash run: pnpm install --frozen-lockfile --prefer-offline - name: Lint the code 🕵 run: pnpm all:lint build: strategy: matrix: node-version: [20] name: Build code 🛠 runs-on: ubuntu-latest steps: - name: Check out the code 🗄 uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 10 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' - name: Install dependencies shell: bash run: pnpm install --frozen-lockfile --prefer-offline - name: Build code 🛠 run: pnpm all:build ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: workflow_dispatch: inputs: version: description: 'Specify the version' required: false type: string dryRun: description: 'Start the release with dryRun parameter' required: true type: boolean default: true jobs: release: strategy: matrix: node-version: [20] if: (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/release') || (github.event_name == 'workflow_dispatch' && github.event.inputs.dryRun == 'true') name: Release new version 🛠 runs-on: ubuntu-latest permissions: contents: write actions: write issues: write pull-requests: write id-token: write steps: - name: Check out the code 🗄 uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 10 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' - name: Install dependencies shell: bash run: pnpm install --frozen-lockfile --prefer-offline - name: Create new version 🛠 run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} pnpm exec nx release ${{ github.event.inputs.version || '' }} --skip-publish --verbose --dryRun=${{ github.event.inputs.dryRun }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Sync main with release 📤 if: ${{ github.event.inputs.dryRun == 'false' }} run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git fetch origin git switch main git pull origin main git merge origin/release --ff-only -m "chore: merge release into main" --no-verify git push origin main - name: Build code 🛠 run: pnpm lib:build - name: Publish new version 🛠 run: | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc pnpm exec nx release publish --verbose --dryRun=${{ github.event.inputs.dryRun }} env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_PROVENANCE: true ================================================ FILE: .gitignore ================================================ # See http://help.github.com/ignore-files/ for more about ignoring files. # compiled output /dist /tmp /out-tsc # dependencies node_modules #package-lock.json # IDEs and editors /.idea .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # IDE - VSCode .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json # misc /.sass-cache /connect.lock /coverage /libpeerconnection.log npm-debug.log testem.log /typings # System Files .DS_Store Thumbs.db .angular .vercel .nx .cursor/rules/nx-rules.mdc .github/instructions/nx.instructions.md ================================================ FILE: .husky/commit-msg ================================================ npx --no -- commitlint --edit ================================================ FILE: .husky/pre-commit ================================================ pnpm dlx lint-staged --concurrent false --relative ================================================ FILE: .lintstagedrc ================================================ { "*.ts": ["nx affected:lint --fix --files"], "*": ["npx nx format:write --files"] } ================================================ FILE: .prettierignore ================================================ # Add files here to ignore them from prettier formatting /dist /node_modules /coverage .angular .github /.nx/cache /.nx/workspace-data pnpm-lock.yaml ================================================ FILE: .prettierrc ================================================ { "endOfLine": "crlf", "singleQuote": true, "printWidth": 100, "trailingComma": "es5", "bracketSameLine": true, "bracketSpacing": true, "proseWrap": "always", "singleAttributePerLine": true, "plugins": [ "prettier-plugin-packagejson", "@ianvs/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss" ], "importOrder": [ "^~/(.*)$", "^[.]", "", "(flowbite-angular|shiki)", "", "", "", "" ], "importOrderParserPlugins": ["typescript", "decorators-legacy"], "tailwindFunctions": ["twMerge", "createTheme"] } ================================================ FILE: .stylelintrc.json ================================================ { "extends": "stylelint-config-standard", "rules": { "no-empty-source": null, "at-rule-no-unknown": null } } ================================================ FILE: .vscode/extensions.json ================================================ { "recommendations": [ "angular.ng-template", "nrwl.angular-console", "esbenp.prettier-vscode", "dbaeumer.vscode-eslint" ] } ================================================ FILE: .vscode/settings.json ================================================ { "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "editor.defaultFormatter": "esbenp.prettier-vscode", "files.eol": "\r\n", "editor.formatOnSave": true, "tailwindCSS.experimental.configFile": "apps/docs/public/css/styles.css", "tailwindCSS.classAttributes": ["class", "className", "ngClass", "customStyle"], "tailwindCSS.classFunctions": ["twMerge", "createTheme"], "typescript.tsdk": "node_modules/typescript/lib", "[markdown]": { "editor.unicodeHighlight.ambiguousCharacters": false, "editor.unicodeHighlight.invisibleCharacters": false, "diffEditor.ignoreTrimWhitespace": false, "editor.wordWrap": "on", "editor.quickSuggestions": { "comments": "off", "strings": "off", "other": "off" } }, "eslint.validate": ["json"] } ================================================ FILE: LICENSE ================================================ libs/flowbite-angular/LICENSE ================================================ FILE: README.md ================================================ libs/flowbite-angular/README.md ================================================ FILE: apps/.gitkeep ================================================ ================================================ FILE: apps/docs/.eslintrc.json ================================================ { "extends": ["../../.eslintrc.json"], "ignorePatterns": ["!**/*"], "overrides": [ { "files": ["*.ts"], "extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], "rules": { "@angular-eslint/directive-selector": [ "error", { "type": "attribute", "prefix": "flowbite", "style": "camelCase" } ], "@angular-eslint/component-selector": [ "error", { "type": "element", "prefix": "flowbite", "style": "kebab-case" } ] } }, { "files": ["*.html"], "extends": ["plugin:@nx/angular-template"], "rules": {} } ] } ================================================ FILE: apps/docs/docs/components/accordion/_always-open.component.html ================================================
What is Flowbite?

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.

Check out this guide to learn how to get started and start developing websites even faster with components on top of Tailwind CSS.

Is there a Figma file available?

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.

Check out the Figma design system based on the utility classes from Tailwind CSS and components from Flowbite.

What are the differences between Flowbite and Tailwind UI?

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.

However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.

Learn more about these technologies:

================================================ FILE: apps/docs/docs/components/accordion/_always-open.component.ts ================================================ import { Accordion, AccordionContent, AccordionItem, AccordionTitle, } from 'flowbite-angular/accordion'; import { Component } from '@angular/core'; @Component({ imports: [Accordion, AccordionItem, AccordionTitle, AccordionContent], templateUrl: './_always-open.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteAlwaysOpenComponent {} ================================================ FILE: apps/docs/docs/components/accordion/_color.component.html ================================================
What is Flowbite?

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.

Check out this guide to learn how to get started and start developing websites even faster with components on top of Tailwind CSS.

Is there a Figma file available?

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.

Check out the Figma design system based on the utility classes from Tailwind CSS and components from Flowbite.

What are the differences between Flowbite and Tailwind UI?

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.

However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.

Learn more about these technologies:

================================================ FILE: apps/docs/docs/components/accordion/_color.component.ts ================================================ import { Accordion, AccordionContent, AccordionItem, AccordionTitle, } from 'flowbite-angular/accordion'; import { Component } from '@angular/core'; @Component({ imports: [Accordion, AccordionItem, AccordionTitle, AccordionContent], templateUrl: './_color.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteColorComponent {} ================================================ FILE: apps/docs/docs/components/accordion/_default.component.html ================================================
What is Flowbite?

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.

Check out this guide to learn how to get started and start developing websites even faster with components on top of Tailwind CSS.

Is there a Figma file available?

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.

Check out the Figma design system based on the utility classes from Tailwind CSS and components from Flowbite.

What are the differences between Flowbite and Tailwind UI?

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.

However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.

Learn more about these technologies:

================================================ FILE: apps/docs/docs/components/accordion/_default.component.ts ================================================ import { Accordion, AccordionContent, AccordionItem, AccordionTitle, } from 'flowbite-angular/accordion'; import { Component } from '@angular/core'; @Component({ imports: [Accordion, AccordionItem, AccordionTitle, AccordionContent], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/accordion/_flush.component.html ================================================
What is Flowbite?

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.

Check out this guide to learn how to get started and start developing websites even faster with components on top of Tailwind CSS.

Is there a Figma file available?

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.

Check out the Figma design system based on the utility classes from Tailwind CSS and components from Flowbite.

What are the differences between Flowbite and Tailwind UI?

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.

However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.

Learn more about these technologies:

================================================ FILE: apps/docs/docs/components/accordion/_flush.component.ts ================================================ import { Accordion, AccordionContent, AccordionItem, AccordionTitle, } from 'flowbite-angular/accordion'; import { Component } from '@angular/core'; @Component({ imports: [Accordion, AccordionItem, AccordionTitle, AccordionContent], templateUrl: './_flush.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteFlushComponent {} ================================================ FILE: apps/docs/docs/components/accordion/_icon.component.html ================================================
What is Flowbite?

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.

Check out this guide to learn how to get started and start developing websites even faster with components on top of Tailwind CSS.

Is there a Figma file available?

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.

Check out the Figma design system based on the utility classes from Tailwind CSS and components from Flowbite.

What are the differences between Flowbite and Tailwind UI?

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.

However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.

Learn more about these technologies:

================================================ FILE: apps/docs/docs/components/accordion/_icon.component.ts ================================================ import { Accordion, AccordionContent, AccordionItem, AccordionTitle, } from 'flowbite-angular/accordion'; import { Icon } from 'flowbite-angular/icon'; import { chevronDown } from 'flowbite-angular/icon/outline/arrows'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Accordion, AccordionItem, AccordionTitle, AccordionContent, Icon], providers: [provideIcons({ chevronDown })], templateUrl: './_icon.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteIconComponent {} ================================================ FILE: apps/docs/docs/components/accordion/index.md ================================================ --- keyword: AccordionPage --- ## Default accordion {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` ## Always open {{ NgDocActions.demo('flowbiteAlwaysOpenComponent', {container: false}) }} ```angular-html file="./_always-open.component.html" group="always-open" name="html" ``` ```angular-ts file="./_always-open.component.ts" group="always-open" name="typescript" ``` ## Color option {{ NgDocActions.demo('flowbiteColorComponent', {container: false}) }} ```angular-html file="./_color.component.html" group="color" name="html" ``` ```angular-ts file="./_color.component.ts" group="color" name="typescript" ``` ## Flush accordion {{ NgDocActions.demo('flowbiteFlushComponent', {container: false}) }} ```angular-html file="./_flush.component.html" group="flush" name="html" ``` ```angular-ts file="./_flush.component.ts" group="flush" name="typescript" ``` ## Accordion with Icon {{ NgDocActions.demo('flowbiteIconComponent', {container: false}) }} ```angular-html file="./_icon.component.html" group="icon" name="html" ``` ```angular-ts file="./_icon.component.ts" group="icon" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/accordion/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteAlwaysOpenComponent } from './_always-open.component'; import { FlowbiteColorComponent } from './_color.component'; import { FlowbiteDefaultComponent } from './_default.component'; import { FlowbiteFlushComponent } from './_flush.component'; import { FlowbiteIconComponent } from './_icon.component'; import { flowbiteAccordionContentTheme, flowbiteAccordionItemTheme, flowbiteAccordionTheme, flowbiteAccordionTitleTheme, } from 'flowbite-angular/accordion'; import type { NgDocPage } from '@ng-doc/core'; /** * Use the accordion component to show hidden information based on the collapse and expand state of the child elements */ const Accordion: NgDocPage = { title: 'Accordion', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, flowbiteAlwaysOpenComponent: FlowbiteAlwaysOpenComponent, flowbiteColorComponent: FlowbiteColorComponent, flowbiteFlushComponent: FlowbiteFlushComponent, flowbiteIconComponent: FlowbiteIconComponent, }, data: { themes: [ { title: 'Accordion theme', content: toIndentedJson(flowbiteAccordionTheme) }, { title: 'Accordion item content', content: toIndentedJson(flowbiteAccordionItemTheme) }, { title: 'Accordion title theme', content: toIndentedJson(flowbiteAccordionTitleTheme) }, { title: 'Accordion content', content: toIndentedJson(flowbiteAccordionContentTheme) }, ] satisfies DocThemes, }, }; export default Accordion; ================================================ FILE: apps/docs/docs/components/alert/_border-accent.component.html ================================================
default alert! Change a few things up and try submitting again.
info alert! Change a few things up and try submitting again.
failure alert! Change a few things up and try submitting again.
warning alert! Change a few things up and try submitting again.
success alert! Change a few things up and try submitting again.
primary alert! Change a few things up and try submitting again.
================================================ FILE: apps/docs/docs/components/alert/_border-accent.component.ts ================================================ import { Alert, AlertContent } from 'flowbite-angular/alert'; import { Component } from '@angular/core'; @Component({ imports: [Alert, AlertContent], templateUrl: './_border-accent.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteBorderAccentComponent {} ================================================ FILE: apps/docs/docs/components/alert/_border.component.html ================================================
default alert! Change a few things up and try submitting again.
info alert! Change a few things up and try submitting again.
failure alert! Change a few things up and try submitting again.
warning alert! Change a few things up and try submitting again.
success alert! Change a few things up and try submitting again.
primary alert! Change a few things up and try submitting again.
================================================ FILE: apps/docs/docs/components/alert/_border.component.ts ================================================ import { Alert, AlertContent } from 'flowbite-angular/alert'; import { Component } from '@angular/core'; @Component({ imports: [Alert, AlertContent], templateUrl: './_border.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteBorderComponent {} ================================================ FILE: apps/docs/docs/components/alert/_default.component.html ================================================
default alert! Change a few things up and try submitting again.
info alert! Change a few things up and try submitting again.
failure alert! Change a few things up and try submitting again.
warning alert! Change a few things up and try submitting again.
success alert! Change a few things up and try submitting again.
primary alert! Change a few things up and try submitting again.
================================================ FILE: apps/docs/docs/components/alert/_default.component.ts ================================================ import { Alert, AlertContent } from 'flowbite-angular/alert'; import { Component } from '@angular/core'; @Component({ imports: [Alert, AlertContent], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/alert/_dismissable.component.html ================================================
default alert! Change a few things up and try submitting again.
info alert! Change a few things up and try submitting again.
failure alert! Change a few things up and try submitting again.
warning alert! Change a few things up and try submitting again.
success alert! Change a few things up and try submitting again.
primary alert! Change a few things up and try submitting again.
================================================ FILE: apps/docs/docs/components/alert/_dismissable.component.ts ================================================ import { Alert, AlertButton, AlertContent } from 'flowbite-angular/alert'; import { Icon } from 'flowbite-angular/icon'; import { close, infoCircle } from 'flowbite-angular/icon/outline/general'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Alert, Icon, AlertButton, AlertContent], providers: [provideIcons({ close, infoCircle })], templateUrl: './_dismissable.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteDismissableComponent { onDismiss(): void { alert('Alert has been dismissed'); } } ================================================ FILE: apps/docs/docs/components/alert/_icon.component.html ================================================
default alert! Change a few things up and try submitting again.
info alert! Change a few things up and try submitting again.
failure alert! Change a few things up and try submitting again.
warning alert! Change a few things up and try submitting again.
success alert! Change a few things up and try submitting again.
primary alert! Change a few things up and try submitting again.
================================================ FILE: apps/docs/docs/components/alert/_icon.component.ts ================================================ import { Alert, AlertContent } from 'flowbite-angular/alert'; import { Icon } from 'flowbite-angular/icon'; import { infoCircle } from 'flowbite-angular/icon/outline/general'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Alert, Icon, AlertContent], providers: [provideIcons({ infoCircle })], templateUrl: './_icon.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteIconComponent {} ================================================ FILE: apps/docs/docs/components/alert/index.md ================================================ --- keyword: AlertPage --- ## Default alert {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` ## Alert with icon {{ NgDocActions.demo('flowbiteIconComponent', {container: false}) }} ```angular-html file="./_icon.component.html" group="icon" name="html" ``` ```angular-ts file="./_icon.component.ts" group="icon" name="typescript" ``` ## Bordered alert {{ NgDocActions.demo('flowbiteBorderComponent', {container: false}) }} ```angular-html file="./_border.component.html" group="border" name="html" ``` ```angular-ts file="./_border.component.ts" group="border" name="typescript" ``` ## Dismissable alert {{ NgDocActions.demo('flowbiteDismissableComponent', {container: false}) }} ```angular-html file="./_dismissable.component.html" group="dismissable" name="html" ``` ```angular-ts file="./_dismissable.component.ts" group="dismissable" name="typescript" ``` ## Border accent {{ NgDocActions.demo('flowbiteBorderAccentComponent', {container: false}) }} ```angular-html file="./_border-accent.component.html" group="borderAccent" name="html" ``` ```angular-ts file="./_border-accent.component.ts" group="borderAccent" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/alert/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteBorderAccentComponent } from './_border-accent.component'; import { FlowbiteBorderComponent } from './_border.component'; import { FlowbiteDefaultComponent } from './_default.component'; import { FlowbiteDismissableComponent } from './_dismissable.component'; import { FlowbiteIconComponent } from './_icon.component'; import { flowbiteAlertButtonTheme, flowbiteAlertContentTheme, flowbiteAlertTheme, } from 'flowbite-angular/alert'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Alert: NgDocPage = { title: 'Alert', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, flowbiteIconComponent: FlowbiteIconComponent, flowbiteBorderComponent: FlowbiteBorderComponent, flowbiteBorderAccentComponent: FlowbiteBorderAccentComponent, flowbiteDismissableComponent: FlowbiteDismissableComponent, }, data: { themes: [ { title: 'Alert theme', content: toIndentedJson(flowbiteAlertTheme) }, { title: 'Alert content theme', content: toIndentedJson(flowbiteAlertContentTheme) }, { title: 'Alert button theme', content: toIndentedJson(flowbiteAlertButtonTheme) }, ] satisfies DocThemes, }, }; export default Alert; ================================================ FILE: apps/docs/docs/components/badge/_border.component.html ================================================ default info failure warning success primary ================================================ FILE: apps/docs/docs/components/badge/_border.component.ts ================================================ import { Badge } from 'flowbite-angular/badge'; import { Component } from '@angular/core'; @Component({ imports: [Badge], templateUrl: './_border.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteBorderComponent {} ================================================ FILE: apps/docs/docs/components/badge/_default.component.html ================================================ default info failure warning success primary ================================================ FILE: apps/docs/docs/components/badge/_default.component.ts ================================================ import { Badge } from 'flowbite-angular/badge'; import { Component } from '@angular/core'; @Component({ imports: [Badge], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/badge/_dismiss.component.html ================================================ default info failure warning success primary ================================================ FILE: apps/docs/docs/components/badge/_dismiss.component.ts ================================================ import { Badge, BadgeButton } from 'flowbite-angular/badge'; import { Icon } from 'flowbite-angular/icon'; import { close, infoCircle } from 'flowbite-angular/icon/outline/general'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Badge, Icon, BadgeButton], providers: [provideIcons({ infoCircle, close })], templateUrl: './_dismiss.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDismissComponent { onDismiss(): void { alert('Badge has been dismissed'); } } ================================================ FILE: apps/docs/docs/components/badge/_icon.component.html ================================================ default info failure success warning primary ================================================ FILE: apps/docs/docs/components/badge/_icon.component.ts ================================================ import { Badge } from 'flowbite-angular/badge'; import { Icon } from 'flowbite-angular/icon'; import { check } from 'flowbite-angular/icon/outline/general'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Badge, Icon], providers: [provideIcons({ check })], templateUrl: './_icon.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteIconComponent {} ================================================ FILE: apps/docs/docs/components/badge/_link.component.html ================================================ default info failure success warning primary ================================================ FILE: apps/docs/docs/components/badge/_link.component.ts ================================================ import { BadgeLink } from 'flowbite-angular/badge'; import { Component } from '@angular/core'; @Component({ imports: [BadgeLink], templateUrl: './_link.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteLinkComponent {} ================================================ FILE: apps/docs/docs/components/badge/index.md ================================================ --- keyword: BadgePage --- ## Default badge {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` ## Bordered badge {{ NgDocActions.demo('flowbiteBorderComponent', {container: false}) }} ```angular-html file="./_border.component.html" group="border" name="html" ``` ```angular-ts file="./_border.component.ts" group="border" name="typescript" ``` ## Badge as link {{ NgDocActions.demo('flowbiteLinkComponent', {container: false}) }} ```angular-html file="./_link.component.html" group="link" name="html" ``` ```angular-ts file="./_link.component.ts" group="link" name="typescript" ``` ## Badge with icon {{ NgDocActions.demo('flowbiteIconComponent', {container: false}) }} ```angular-html file="./_icon.component.html" group="icon" name="html" ``` ```angular-ts file="./_icon.component.ts" group="icon" name="typescript" ``` ## Dismissable badge {{ NgDocActions.demo('flowbiteDismissComponent', {container: false}) }} ```angular-html file="./_dismiss.component.html" group="dismiss" name="html" ``` ```angular-ts file="./_dismiss.component.ts" group="dismiss" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/badge/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteBorderComponent } from './_border.component'; import { FlowbiteDefaultComponent } from './_default.component'; import { FlowbiteDismissComponent } from './_dismiss.component'; import { FlowbiteIconComponent } from './_icon.component'; import { FlowbiteLinkComponent } from './_link.component'; import { flowbiteBadgeButtonTheme, flowbiteBadgeLinkTheme, flowbiteBadgeTheme, } from 'flowbite-angular/badge'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Badge: NgDocPage = { title: 'Badge', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, flowbiteBorderComponent: FlowbiteBorderComponent, flowbiteLinkComponent: FlowbiteLinkComponent, flowbiteIconComponent: FlowbiteIconComponent, flowbiteDismissComponent: FlowbiteDismissComponent, }, data: { themes: [ { title: 'Badge', content: toIndentedJson(flowbiteBadgeTheme) }, { title: 'Badge link', content: toIndentedJson(flowbiteBadgeLinkTheme) }, { title: 'Badge button', content: toIndentedJson(flowbiteBadgeButtonTheme) }, ] satisfies DocThemes, }, }; export default Badge; ================================================ FILE: apps/docs/docs/components/breadcrumb/_default.component.html ================================================ ================================================ FILE: apps/docs/docs/components/breadcrumb/_default.component.ts ================================================ import { Breadcrumb, BreadcrumbContent, BreadcrumbItem } from 'flowbite-angular/breadcrumb'; import { Icon } from 'flowbite-angular/icon'; import { chevronRight } from 'flowbite-angular/icon/outline/arrows'; import { home } from 'flowbite-angular/icon/outline/general'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Breadcrumb, BreadcrumbItem, BreadcrumbContent, Icon], providers: [provideIcons({ home, chevronRight })], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-col gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/breadcrumb/index.md ================================================ --- keyword: BreadcrumbPage --- ## Default breadcrumb {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/breadcrumb/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteBreadcrumbContentTheme, flowbiteBreadcrumbItemTheme, flowbiteBreadcrumbTheme, } from 'flowbite-angular/breadcrumb'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Breadcrumb: NgDocPage = { title: 'Breadcrumb', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Breadcrumb', content: toIndentedJson(flowbiteBreadcrumbTheme) }, { title: 'Breadcrumb content', content: toIndentedJson(flowbiteBreadcrumbContentTheme) }, { title: 'Breadcrumb item', content: toIndentedJson(flowbiteBreadcrumbItemTheme) }, ] satisfies DocThemes, }, }; export default Breadcrumb; ================================================ FILE: apps/docs/docs/components/button/_default.component.html ================================================ ================================================ FILE: apps/docs/docs/components/button/_default.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Component } from '@angular/core'; @Component({ imports: [Button], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/button/_disabled.component.html ================================================ ================================================ FILE: apps/docs/docs/components/button/_disabled.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Component } from '@angular/core'; @Component({ imports: [Button], templateUrl: './_disabled.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDisabledComponent {} ================================================ FILE: apps/docs/docs/components/button/_group.component.html ================================================
================================================ FILE: apps/docs/docs/components/button/_group.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { ButtonGroup } from 'flowbite-angular/button-group'; import { Component } from '@angular/core'; @Component({ imports: [Button, ButtonGroup], templateUrl: './_group.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteGroupComponent {} ================================================ FILE: apps/docs/docs/components/button/_icon.component.html ================================================ ================================================ FILE: apps/docs/docs/components/button/_icon.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Icon } from 'flowbite-angular/icon'; import { brain } from 'flowbite-angular/icon/outline/general'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Button, Icon], providers: [provideIcons({ brain })], templateUrl: './_icon.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteIconComponent {} ================================================ FILE: apps/docs/docs/components/button/_outline.component.html ================================================ ================================================ FILE: apps/docs/docs/components/button/_outline.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Component } from '@angular/core'; @Component({ imports: [Button], templateUrl: './_outline.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteOutlineComponent {} ================================================ FILE: apps/docs/docs/components/button/_pill.component.html ================================================ ================================================ FILE: apps/docs/docs/components/button/_pill.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Component } from '@angular/core'; @Component({ imports: [Button], templateUrl: './_pill.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbitePillComponent {} ================================================ FILE: apps/docs/docs/components/button/_size.component.html ================================================ ================================================ FILE: apps/docs/docs/components/button/_size.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Component } from '@angular/core'; @Component({ imports: [Button], templateUrl: './_size.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteSizeComponent {} ================================================ FILE: apps/docs/docs/components/button/index.md ================================================ --- keyword: ButtonPage --- ## Default button {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` ## Button pill {{ NgDocActions.demo('flowbitePillComponent', {container: false}) }} ```angular-html file="./_pill.component.html" group="pill" name="html" ``` ```angular-ts file="./_pill.component.ts" group="pill" name="typescript" ``` ## Outline button {{ NgDocActions.demo('flowbiteOutlineComponent', {container: false}) }} ```angular-html file="./_outline.component.html" group="outline" name="html" ``` ```angular-ts file="./_outline.component.ts" group="outline" name="typescript" ``` ## Button sizes {{ NgDocActions.demo('flowbiteSizeComponent', {container: false}) }} ```angular-html file="./_size.component.html" group="size" name="html" ``` ```angular-ts file="./_size.component.ts" group="size" name="typescript" ``` ## Button with icon {{ NgDocActions.demo('flowbiteIconComponent', {container: false}) }} ```angular-html file="./_icon.component.html" group="icon" name="html" ``` ```angular-ts file="./_icon.component.ts" group="icon" name="typescript" ``` ## Disabled button {{ NgDocActions.demo('flowbiteDisabledComponent', {container: false}) }} ```angular-html file="./_disabled.component.html" group="disabled" name="html" ``` ```angular-ts file="./_disabled.component.ts" group="disabled" name="typescript" ``` ## Button group {{ NgDocActions.demo('flowbiteGroupComponent', {container: false}) }} ```angular-html file="./_group.component.html" group="group" name="html" ``` ```angular-ts file="./_group.component.ts" group="group" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/button/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { FlowbiteDisabledComponent } from './_disabled.component'; import { FlowbiteGroupComponent } from './_group.component'; import { FlowbiteIconComponent } from './_icon.component'; import { FlowbiteOutlineComponent } from './_outline.component'; import { FlowbitePillComponent } from './_pill.component'; import { FlowbiteSizeComponent } from './_size.component'; import { flowbiteButtonTheme } from 'flowbite-angular/button'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Button: NgDocPage = { title: 'Button', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, flowbitePillComponent: FlowbitePillComponent, flowbiteOutlineComponent: FlowbiteOutlineComponent, flowbiteSizeComponent: FlowbiteSizeComponent, flowbiteIconComponent: FlowbiteIconComponent, flowbiteDisabledComponent: FlowbiteDisabledComponent, flowbiteGroupComponent: FlowbiteGroupComponent, }, data: { themes: [{ title: 'Button', content: toIndentedJson(flowbiteButtonTheme) }] satisfies DocThemes, }, }; export default Button; ================================================ FILE: apps/docs/docs/components/card/_default.component.html ================================================
Noteworthy technology acquisitions 2021

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

================================================ FILE: apps/docs/docs/components/card/_default.component.ts ================================================ import { Card, CardContent, CardHeader } from 'flowbite-angular/card'; import { Component } from '@angular/core'; @Component({ imports: [Card, CardHeader, CardContent], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/card/index.md ================================================ --- keyword: CardPage --- ## Default card {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/card/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteCardContentTheme, flowbiteCardHeaderTheme, flowbiteCardTheme, } from 'flowbite-angular/card'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Card: NgDocPage = { title: 'Card', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Card content', content: toIndentedJson(flowbiteCardContentTheme) }, { title: 'Card header', content: toIndentedJson(flowbiteCardHeaderTheme) }, { title: 'Card', content: toIndentedJson(flowbiteCardTheme) }, ] satisfies DocThemes, }, }; export default Card; ================================================ FILE: apps/docs/docs/components/clipboard/_default.component.html ================================================
================================================ FILE: apps/docs/docs/components/clipboard/_default.component.ts ================================================ import { Clipboard } from 'flowbite-angular/clipboard'; import { Component } from '@angular/core'; @Component({ imports: [Clipboard], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/clipboard/index.md ================================================ --- keyword: ClipboardPage --- ## Default clipboard {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/clipboard/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteClipboardTheme } from 'flowbite-angular/clipboard'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Clipboard: NgDocPage = { title: 'Clipboard', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Clipboard', content: toIndentedJson(flowbiteClipboardTheme) }, ] satisfies DocThemes, }, }; export default Clipboard; ================================================ FILE: apps/docs/docs/components/dropdown/_default.component.html ================================================
  • Dashboard
  • Settings
  • Earnings
  • Sign out
================================================ FILE: apps/docs/docs/components/dropdown/_default.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Dropdown, DropdownContent, DropdownItem } from 'flowbite-angular/dropdown'; import { Icon } from 'flowbite-angular/icon'; import { chevronDown } from 'flowbite-angular/icon/outline/arrows'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; import { NgpMenuTrigger } from 'ng-primitives/menu'; @Component({ imports: [Button, Dropdown, DropdownContent, DropdownItem, NgpMenuTrigger, Icon], providers: [provideIcons({ chevronDown })], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/dropdown/index.md ================================================ --- keyword: DropdownPage --- ## Default dropdown {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/dropdown/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteDropdownContentTheme, flowbiteDropdownItemTheme, flowbiteDropdownTheme, } from 'flowbite-angular/dropdown'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Dropdown: NgDocPage = { title: 'Dropdown', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Dropdown content', content: toIndentedJson(flowbiteDropdownContentTheme) }, { title: 'Dropdown item', content: toIndentedJson(flowbiteDropdownItemTheme) }, { title: 'Dropdown', content: toIndentedJson(flowbiteDropdownTheme) }, ] satisfies DocThemes, }, }; export default Dropdown; ================================================ FILE: apps/docs/docs/components/icon/_default.component.html ================================================ ================================================ FILE: apps/docs/docs/components/icon/_default.component.ts ================================================ import { Icon } from 'flowbite-angular/icon'; import { close } from 'flowbite-angular/icon/outline/general'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Icon], providers: [provideIcons({ close })], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/icon/index.md ================================================ --- keyword: IconPage --- ## Default icon {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/icon/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteIconTheme } from 'flowbite-angular/icon'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Icon: NgDocPage = { title: 'Icon', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [{ title: 'Icon', content: toIndentedJson(flowbiteIconTheme) }] satisfies DocThemes, }, }; export default Icon; ================================================ FILE: apps/docs/docs/components/indicator/_default.component.html ================================================ ================================================ FILE: apps/docs/docs/components/indicator/_default.component.ts ================================================ import { Indicator } from 'flowbite-angular/indicator'; import { Component } from '@angular/core'; @Component({ imports: [Indicator], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/indicator/index.md ================================================ --- keyword: IndicatorPage --- ## Default indicator {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/indicator/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteIndicatorTheme } from 'flowbite-angular/indicator'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Indicator: NgDocPage = { title: 'Indicator', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Indicator', content: toIndentedJson(flowbiteIndicatorTheme) }, ] satisfies DocThemes, }, }; export default Indicator; ================================================ FILE: apps/docs/docs/components/input/_default.component.html ================================================

We’ll never share your details. Read our Privacy Policy .

================================================ FILE: apps/docs/docs/components/input/_default.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { FormControl, FormField, Helper, Label } from 'flowbite-angular/form'; import { Component } from '@angular/core'; @Component({ imports: [FormControl, FormField, Label, Helper, Button], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/input/index.md ================================================ --- keyword: InputFieldPage --- ## Default Input field {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/input/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteFormControlTheme, flowbiteFormFieldTheme, flowbiteHelperTheme, flowbiteLabelTheme, } from 'flowbite-angular/form'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Input: NgDocPage = { title: 'Input field', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Form control', content: toIndentedJson(flowbiteFormControlTheme) }, { title: 'Form field', content: toIndentedJson(flowbiteFormFieldTheme) }, { title: 'Helper', content: toIndentedJson(flowbiteHelperTheme) }, { title: 'Label', content: toIndentedJson(flowbiteLabelTheme) }, ] satisfies DocThemes, }, }; export default Input; ================================================ FILE: apps/docs/docs/components/modal/_default.component.html ================================================

Terms of Service

With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.

The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.

================================================ FILE: apps/docs/docs/components/modal/_default.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Modal, ModalContent, ModalFooter, ModalHeader, ModalOverlay, } from 'flowbite-angular/modal'; import { Component } from '@angular/core'; import { NgpDialogTrigger } from 'ng-primitives/dialog'; @Component({ imports: [Button, NgpDialogTrigger, Modal, ModalContent, ModalFooter, ModalHeader, ModalOverlay], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/modal/_open-programatically.component.html ================================================

Terms of Service

With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.

The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.

================================================ FILE: apps/docs/docs/components/modal/_open-programatically.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Modal, ModalContent, ModalFooter, ModalHeader, ModalOverlay, } from 'flowbite-angular/modal'; import { Component, inject, TemplateRef, viewChild } from '@angular/core'; import { NgpDialogManager } from 'ng-primitives/dialog'; @Component({ imports: [Button, Modal, ModalContent, ModalFooter, ModalHeader, ModalOverlay], templateUrl: './_open-programatically.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteOpenprogramaticallyComponent { public readonly ngpDialogManager = inject(NgpDialogManager); public readonly modal = viewChild('dialog', { read: TemplateRef }); onClick(): void { const modal = this.modal(); if (modal !== undefined) { this.ngpDialogManager.open(modal); } } } ================================================ FILE: apps/docs/docs/components/modal/_position.component.html ================================================

Terms of Service

With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.

The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.

================================================ FILE: apps/docs/docs/components/modal/_position.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Modal, ModalContent, ModalFooter, ModalHeader, ModalOverlay, } from 'flowbite-angular/modal'; import { Component } from '@angular/core'; import { NgpDialogTrigger } from 'ng-primitives/dialog'; @Component({ imports: [Button, NgpDialogTrigger, Modal, ModalContent, ModalFooter, ModalHeader, ModalOverlay], templateUrl: './_position.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbitePositionComponent {} ================================================ FILE: apps/docs/docs/components/modal/index.md ================================================ --- keyword: ModalPage --- ## Default Modal {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` ## Open programatically {{ NgDocActions.demo('flowbiteOpenprogramaticallyComponent', {container: false}) }} ```angular-html file="./_open-programatically.component.html" group="openProgramatically" name="html" ``` ```angular-ts file="./_open-programatically.component.ts" group="openProgramatically" name="typescript" ``` ## Positioned modal {{ NgDocActions.demo('flowbitePositionComponent', {container: false}) }} ```angular-html file="./_position.component.html" group="position" name="html" ``` ```angular-ts file="./_position.component.ts" group="position" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/modal/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { FlowbiteOpenprogramaticallyComponent } from './_open-programatically.component'; import { FlowbitePositionComponent } from './_position.component'; import { flowbiteModalContentTheme, flowbiteModalFooterTheme, flowbiteModalHeaderTheme, flowbiteModalOverlayTheme, flowbiteModalTheme, } from 'flowbite-angular/modal'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Modal: NgDocPage = { title: 'Modal', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, flowbiteOpenprogramaticallyComponent: FlowbiteOpenprogramaticallyComponent, flowbitePositionComponent: FlowbitePositionComponent, }, data: { themes: [ { title: 'Modal content', content: toIndentedJson(flowbiteModalContentTheme) }, { title: 'Modal footer', content: toIndentedJson(flowbiteModalFooterTheme) }, { title: 'Modal header', content: toIndentedJson(flowbiteModalHeaderTheme) }, { title: 'Modal overlay', content: toIndentedJson(flowbiteModalOverlayTheme) }, { title: 'Modal', content: toIndentedJson(flowbiteModalTheme) }, ] satisfies DocThemes, }, }; export default Modal; ================================================ FILE: apps/docs/docs/components/navbar/_default.component.html ================================================
@for (i of [0, 1]; track $index) {

}
================================================ FILE: apps/docs/docs/components/navbar/_default.component.ts ================================================ import { Icon } from 'flowbite-angular/icon'; import { bars } from 'flowbite-angular/icon/outline/general'; import { Navbar, NavbarBrand, NavbarContent, NavbarItem, NavbarToggle, } from 'flowbite-angular/navbar'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Navbar, NavbarBrand, NavbarContent, NavbarItem, NavbarToggle, Icon], providers: [provideIcons({ bars })], templateUrl: './_default.component.html', host: { class: 'flex flex-col gap-3 h-72 overflow-scroll', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/navbar/index.md ================================================ --- keyword: NavbarPage --- ## Default Navbar {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/navbar/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteNavbarBrandTheme, flowbiteNavbarContentTheme, flowbiteNavbarIconItemTheme, flowbiteNavbarItemTheme, flowbiteNavbarTheme, flowbiteNavbarToggleTheme, } from 'flowbite-angular/navbar'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Navbar: NgDocPage = { title: 'Navbar', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Navbar brand', content: toIndentedJson(flowbiteNavbarBrandTheme) }, { title: 'Navbar content', content: toIndentedJson(flowbiteNavbarContentTheme) }, { title: 'Navbar icon item', content: toIndentedJson(flowbiteNavbarIconItemTheme) }, { title: 'Navbar item', content: toIndentedJson(flowbiteNavbarItemTheme) }, { title: 'Navbar', content: toIndentedJson(flowbiteNavbarTheme) }, { title: 'Navbar toggle', content: toIndentedJson(flowbiteNavbarToggleTheme) }, ] satisfies DocThemes, }, }; export default Navbar; ================================================ FILE: apps/docs/docs/components/ng-doc.category.ts ================================================ import type { NgDocCategory } from '@ng-doc/core'; const ComponentCategory: NgDocCategory = { title: 'Components', order: 3, expandable: true, }; export default ComponentCategory; ================================================ FILE: apps/docs/docs/components/pagination/_default.component.html ================================================ ================================================ FILE: apps/docs/docs/components/pagination/_default.component.ts ================================================ import { Pagination } from 'flowbite-angular/pagination'; import { Component, signal } from '@angular/core'; @Component({ imports: [Pagination], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent { readonly page = signal(1); } ================================================ FILE: apps/docs/docs/components/pagination/index.md ================================================ --- keyword: PaginationPage --- ## Default Pagination {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/pagination/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbitePaginationButtonTheme, flowbitePaginationFirstTheme, flowbitePaginationLastTheme, flowbitePaginationNextTheme, flowbitePaginationPreviousTheme, flowbitePaginationTheme, } from 'flowbite-angular/pagination'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Pagination: NgDocPage = { title: 'Pagination', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Pagination button', content: toIndentedJson(flowbitePaginationButtonTheme) }, { title: 'Pagination first', content: toIndentedJson(flowbitePaginationFirstTheme) }, { title: 'Pagination last', content: toIndentedJson(flowbitePaginationLastTheme) }, { title: 'Pagination next', content: toIndentedJson(flowbitePaginationNextTheme) }, { title: 'Pagination previous', content: toIndentedJson(flowbitePaginationPreviousTheme) }, { title: 'Pagination', content: toIndentedJson(flowbitePaginationTheme) }, ] satisfies DocThemes, }, }; export default Pagination; ================================================ FILE: apps/docs/docs/components/sidebar/_default.component.html ================================================
@for (i of [0, 1]; track $index) {

}
================================================ FILE: apps/docs/docs/components/sidebar/_default.component.ts ================================================ import { Icon } from 'flowbite-angular/icon'; import { barsFromLeft } from 'flowbite-angular/icon/outline/general'; import { cart } from 'flowbite-angular/icon/solid/e-commerce'; import { chartPie, drawSquare, inbox } from 'flowbite-angular/icon/solid/general'; import { users } from 'flowbite-angular/icon/solid/user'; import { provideFlowbiteSidebarState, Sidebar, SidebarContent, SidebarItem, SidebarToggle, } from 'flowbite-angular/sidebar'; import { Component } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ imports: [Sidebar, SidebarContent, SidebarItem, SidebarToggle, Icon], templateUrl: './_default.component.html', providers: [ provideIcons({ chartPie, inbox, users, cart, drawSquare, barsFromLeft }), provideFlowbiteSidebarState(), ], host: { class: 'flex flex-row h-72', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/sidebar/index.md ================================================ --- keyword: SidebarPage --- ## Default Sidebar {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/sidebar/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteSidebarContentTheme, flowbiteSidebarItemTheme, flowbiteSidebarTheme, flowbiteSidebarToggleTheme, } from 'flowbite-angular/sidebar'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Sidebar: NgDocPage = { title: 'Sidebar', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Sidebar content', content: toIndentedJson(flowbiteSidebarContentTheme) }, { title: 'Sidebar item', content: toIndentedJson(flowbiteSidebarItemTheme) }, { title: 'Sidebar', content: toIndentedJson(flowbiteSidebarTheme) }, { title: 'Sidebar toggle', content: toIndentedJson(flowbiteSidebarToggleTheme) }, ] satisfies DocThemes, }, }; export default Sidebar; ================================================ FILE: apps/docs/docs/components/tab/_default.component.html ================================================
  • Profile
  • Dashboard
  • Settings
  • Contacts
  • Disabled

Nulla cursus urna id felis egestas, ac rhoncus felis egestas. Curabitur placerat at quam vitae volutpat. Nunc at nunc nec ex dapibus sollicitudin nec eget risus. Curabitur id sagittis nisi, sit amet mollis quam. In hac habitasse platea dictumst. Praesent in augue vitae elit egestas euismod. Aliquam in tempus enim, et elementum lacus. Nullam commodo nulla sollicitudin euismod malesuada. Donec sed massa dui. Sed felis ipsum, malesuada eu urna scelerisque, accumsan pharetra odio. Nullam arcu augue, consequat vel faucibus at, dictum non erat. Morbi metus nisl, scelerisque non accumsan quis, fringilla vitae ipsum. Vestibulum fermentum lorem sit amet augue ultrices, eu pretium ex imperdiet.

Curabitur nibh nisl, tincidunt id purus sed, consectetur vehicula sapien. Cras at malesuada felis, eget imperdiet enim. Maecenas commodo vestibulum turpis non ultrices. Donec ut aliquam ex, id molestie dui. Nullam porttitor ligula vel malesuada ullamcorper. Vivamus aliquam consectetur urna, tempus vehicula est consectetur vitae. Integer vitae commodo quam, eget cursus velit. Nam eget leo diam.

Vivamus sed lacinia mauris. Integer vehicula lorem nec interdum rutrum. Curabitur auctor mollis faucibus. Nulla sit amet semper tortor. Vestibulum at tempus nulla, nec interdum orci. Integer sodales quam sit amet cursus interdum. Fusce consequat ultrices magna a iaculis.

Sed eget pellentesque tellus. Praesent rutrum placerat lacus vitae elementum. Nulla ac orci ac enim dignissim finibus. Duis venenatis rhoncus eros. Etiam euismod tortor in vehicula lacinia. Morbi tempor mollis lacus, nec fringilla mauris vestibulum nec. Donec sapien lacus, semper a commodo eu, ullamcorper et turpis.
Disabled content.
================================================ FILE: apps/docs/docs/components/tab/_default.component.ts ================================================ import { Tab, TabButton, TabContent, TabList } from 'flowbite-angular/tab'; import { Component } from '@angular/core'; @Component({ imports: [Tab, TabButton, TabContent, TabList], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent {} ================================================ FILE: apps/docs/docs/components/tab/index.md ================================================ --- keyword: TabPage --- ## Default Tab {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/tab/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteTabButtonTheme, flowbiteTabContentTheme, flowbiteTabListTheme, flowbiteTabTheme, } from 'flowbite-angular/tab'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Tab: NgDocPage = { title: 'Tab', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Tab button', content: toIndentedJson(flowbiteTabButtonTheme) }, { title: 'Tab content', content: toIndentedJson(flowbiteTabContentTheme) }, { title: 'Tab list', content: toIndentedJson(flowbiteTabListTheme) }, { title: 'Tab', content: toIndentedJson(flowbiteTabTheme) }, ] satisfies DocThemes, }, }; export default Tab; ================================================ FILE: apps/docs/docs/components/table/_default.component.html ================================================
Product name Qty Price
{{ data.name }} {{ data.qty }} {{ data.price }}
Total 10 30
================================================ FILE: apps/docs/docs/components/table/_default.component.ts ================================================ import { Table, TableBody, TableFoot, TableHead } from 'flowbite-angular/table'; import { Component } from '@angular/core'; @Component({ imports: [Table, TableBody, TableFoot, TableHead], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent { readonly data = Array.from({ length: 5 }, (_, i) => i++).map((x) => ({ name: `Product ${x}`, qty: x, price: x * x, })); } ================================================ FILE: apps/docs/docs/components/table/index.md ================================================ --- keyword: TablePage --- ## Default Table {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/table/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteTableBodyTheme, flowbiteTableFootTheme, flowbiteTableHeadTheme, flowbiteTableTheme, } from 'flowbite-angular/table'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Table: NgDocPage = { title: 'Table', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Table', content: toIndentedJson(flowbiteTableTheme) }, { title: 'Table Head', content: toIndentedJson(flowbiteTableHeadTheme) }, { title: 'Table Body', content: toIndentedJson(flowbiteTableBodyTheme) }, { title: 'Table Foot', content: toIndentedJson(flowbiteTableFootTheme) }, ] satisfies DocThemes, }, }; export default Table; ================================================ FILE: apps/docs/docs/components/tooltip/_default.component.html ================================================
Tooltip content
================================================ FILE: apps/docs/docs/components/tooltip/_default.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Tooltip } from 'flowbite-angular/tooltip'; import { Component, ElementRef, inject } from '@angular/core'; import { NgpTooltipTrigger } from 'ng-primitives/tooltip'; @Component({ imports: [Button, NgpTooltipTrigger, Tooltip], templateUrl: './_default.component.html', host: { class: 'flex flex-wrap flex-row gap-3 p-6', }, }) export class FlowbiteDefaultComponent { readonly elementRef = inject(ElementRef); } ================================================ FILE: apps/docs/docs/components/tooltip/index.md ================================================ --- keyword: TooltipPage --- ## Default Tooltip {{ NgDocActions.demo('flowbiteDefaultComponent', {container: false}) }} ```angular-html file="./_default.component.html" group="default" name="html" ``` ```angular-ts file="./_default.component.ts" group="default" name="typescript" ``` {% import "../../shared/theme-macro.md" as themeMacro %} {{ themeMacro.display(NgDocPage.data.themes) }} ================================================ FILE: apps/docs/docs/components/tooltip/ng-doc.page.ts ================================================ import type { DocThemes } from '../../doc-theme.model'; import { toIndentedJson } from '../../doc-theme.model'; import ComponentCategory from '../ng-doc.category'; import { FlowbiteDefaultComponent } from './_default.component'; import { flowbiteTooltipTheme } from 'flowbite-angular/tooltip'; import type { NgDocPage } from '@ng-doc/core'; /** * */ const Tooltip: NgDocPage = { title: 'Tooltip', mdFile: './index.md', category: ComponentCategory, demos: { flowbiteDefaultComponent: FlowbiteDefaultComponent, }, data: { themes: [ { title: 'Tooltip', content: toIndentedJson(flowbiteTooltipTheme) }, ] satisfies DocThemes, }, }; export default Tooltip; ================================================ FILE: apps/docs/docs/customize/dark-mode/index.md ================================================ --- keyword: DarkModePage --- ## Enable dark mode All you need to do is add `Theme` as a `hostDirectives` in your `app.component.ts`. ```angular-ts ... import { Theme } from 'flowbite-angular/theme-toggle'; ... @Component({ ... hostDirectives: [Theme], }) export class AppComponent { ... } ``` The Tailwind configuration depends on the `type` of `Theme`. In `Theme`, you can change its behavior. Here is an example configuration to make it rely on data attributes: ```angular-ts provideFlowbiteThemeConfig({ type: { type: 'attr', name: 'data-theme' }, }), ``` ```css @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); ``` ## Get or set theme manually To access or update the application theme manually, inject `Theme` into your component and call one of its helper functions. ================================================ FILE: apps/docs/docs/customize/dark-mode/ng-doc.page.ts ================================================ import CustomizeCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Add dark theme to your application. */ const darkMode: NgDocPage = { title: 'Dark mode', mdFile: './index.md', category: CustomizeCategory, order: 6, }; export default darkMode; ================================================ FILE: apps/docs/docs/customize/ng-doc.category.ts ================================================ import type { NgDocCategory } from '@ng-doc/core'; const CustomizeCategory: NgDocCategory = { title: 'Customize', order: 2, expandable: true, }; export default CustomizeCategory; ================================================ FILE: apps/docs/docs/customize/override-base-style/index.md ================================================ --- keyword: OverrideBaseStylePage --- ## Override base style Each component provide its own configuration method. Configuration methods are named as follow :
  • provideFlowbiteComponentConfig
You can use them to override the default behavior of components and the applied styles. ```typescript import { provideFlowbiteBaseButtonConfig } from 'flowbite-angular/button'; import { type ApplicationConfig } from '@angular/core'; export const appConfig: ApplicationConfig = { providers: [ provideFlowbiteBaseButtonConfig({ color: 'primary', outline: true, pill: false, size: 'lg', }), ], }; ``` ================================================ FILE: apps/docs/docs/customize/override-base-style/ng-doc.page.ts ================================================ import CustomizeCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Customize Flowbite Angular components by overriding their default styles. */ const OverrideBaseStyle: NgDocPage = { title: 'Override base style', mdFile: './index.md', category: CustomizeCategory, order: 2, }; export default OverrideBaseStyle; ================================================ FILE: apps/docs/docs/customize/theming/index.md ================================================ --- keyword: ThemingPage --- You can use the theme directive from tailwind to define any style related classes, such as the color palette, fonts, breakpoints, and more. Here is the `primary` color theme used for this documentation : ```css @theme { /* Primary */ --color-primary-50: #fff0f1; --color-primary-100: #ffe1e4; --color-primary-200: #ffc8cf; --color-primary-300: #ff9ba8; --color-primary-400: #ff637b; --color-primary-500: #ff2c51; --color-primary-600: #f6083b; --color-primary-700: #c3002f; --color-primary-800: #ae0331; --color-primary-900: #940732; --color-primary-950: #5b041e; } ``` ## Theme structure Some of the more widely used theme keys are screens, colors, and spacing as one of the core utility classes. You can read all of the `TailwindConfigurableKeys`. ### Colors Use the colors key to update the color palette. ```css @theme { /* Primary */ --color-primary-50: #fff0f1; --color-primary-100: #ffe1e4; --color-primary-200: #ffc8cf; --color-primary-300: #ff9ba8; --color-primary-400: #ff637b; --color-primary-500: #ff2c51; --color-primary-600: #f6083b; --color-primary-700: #c3002f; --color-primary-800: #ae0331; --color-primary-900: #940732; --color-primary-950: #5b041e; } ``` ### Fonts You can change de default font used by tailwind. ```css @font-face { font-family: roboto; src: url('../../fonts/roboto.ttf') format('truetype'); } @theme { --default-font-family: 'roboto'; } ``` ## Customizing the theme By default, the configuration file will set the base utility classes from TailwindCSS. However, you can customize them by using the extends object. ### Overriding Alternatively, you can also completely override some settings. For example, the following code will override blue color palette by your own. ```css @theme { /* Blue */ --color-blue-50: #ebf5ff; --color-blue-100: #e1effe; --color-blue-200: #c3ddfd; --color-blue-300: #a4cafe; --color-blue-400: #76a9fa; --color-blue-500: #3f83f8; --color-blue-600: #1c64f2; --color-blue-700: #1a56db; --color-blue-800: #1e429f; --color-blue-900: #233876; } ``` Please read the official `TailwindThemingDocumentation` if you want a full overview of the theming options. ================================================ FILE: apps/docs/docs/customize/theming/ng-doc.page.ts ================================================ import CustomizeCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Use the theming options from the TailwindCSS configuration file to override the default utility classes from Flowbite Angular and change colors, fonts, and the default class values. */ const Theming: NgDocPage = { title: 'Theming', mdFile: './index.md', category: CustomizeCategory, order: 1, }; export default Theming; ================================================ FILE: apps/docs/docs/customize/use-custom-style/index.md ================================================ --- keyword: UseCustomStylePage --- ## Passing customTheme values For each component call, you can pass a customTheme value. ```angular-html
Hello World!
``` You can then pass TailwindCSS classes, following the component's base theme. If one or more keys are not filled in the customTheme, the component falls back to its base styles. ================================================ FILE: apps/docs/docs/customize/use-custom-style/ng-doc.page.ts ================================================ import CustomizeCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Customize flowbite-angular's component style by providing a custom style per component. */ const UseCustomStyle: NgDocPage = { title: 'Use custom style', mdFile: './index.md', category: CustomizeCategory, order: 4, }; export default UseCustomStyle; ================================================ FILE: apps/docs/docs/doc-theme.model.ts ================================================ export type DocTheme = { title: string; content: string; description?: string | undefined }; export type DocThemes = DocTheme[]; export const toIndentedJson = ( value: unknown, replacer?: (this: unknown, key: string, value: unknown) => unknown, space: number = 2 ): string => JSON.stringify(value, replacer, space); ================================================ FILE: apps/docs/docs/getting-started/introduction/index.md ================================================ --- keyword: IntroductionPage --- ## Introduction Flowbite Angular is an open-source library of UI components based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, templates, and more. It includes all of the commonly used components that a website requires, such as buttons, dropdowns, navigator bars, modals, but also some more advanced interactives elements such as date pickers All of the elements are build using the utility classes from Tailwind CSS and vanilla Angular. ## Installing from scratch ### Prerequistes If you want to get started with flowbite-angular : ```bash ng new my-angular-project npm install flowbite-angular ``` ## Typescript Flowbite Angular support type declaration for the interactive IO components including object interfaces and parameter types. Check out the following examples to learn how you can use types with Flowbite Angular. You can view more examples by browsing the **components from Flowbite Angular**. ================================================ FILE: apps/docs/docs/getting-started/introduction/ng-doc.page.ts ================================================ import GettingStartedCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Get started with the most popular open-source library of interactive UI components built with the utility classes from Tailwind CSS */ const Introduction: NgDocPage = { title: 'Introduction', mdFile: './index.md', category: GettingStartedCategory, order: 1, }; export default Introduction; ================================================ FILE: apps/docs/docs/getting-started/license/index.md ================================================ --- keyword: LicensePage --- ## Copyright The Flowbite Angular name and logos are trademarks of Bergside Inc. ## Release code The released code is licensed under the `MITLicense`. Copyright (c) Themesberg (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. ## Documentation The docs code is licensed under the `CreativeCommons`. Attribution: the documentation code was initially forked from `Bootstrap` created by the `BootstrapAuthors` and `Twitter`. and changes have been made since then to adapt to the Tailwind CSS and Flowbite ecosystem and technologies. ================================================ FILE: apps/docs/docs/getting-started/license/ng-doc.page.ts ================================================ import GettingStartedCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Learn more about the licensing terms for Flowbite-angular and Tailwind CSS */ const License: NgDocPage = { title: 'License', mdFile: './index.md', category: GettingStartedCategory, order: 3, }; export default License; ================================================ FILE: apps/docs/docs/getting-started/ng-doc.category.ts ================================================ import type { NgDocCategory } from '@ng-doc/core'; const GettingStartedCategory: NgDocCategory = { title: 'Getting started', order: 1, expandable: true, }; export default GettingStartedCategory; ================================================ FILE: apps/docs/docs/getting-started/ng-primitives/index.md ================================================ --- keyword: NgPrimitivesPage --- ## What's angular primitives Angular Primitives is a low-level headless UI component library with a focus on accessibility, customization, and developer experience. Whether you're building a robust design system from scratch or looking to enhance your existing one, our primitives are here to support you every step of the way. ## Special thanks We're using `NgPrimitivesDocumentation` to provide accessibility and behavior base so flowbite-angular can be on design part. We want to address a special thanks to the maintainer of ng-primitives which has provided a packages called @ng-primitives/state providing a clean way to have state management inside components. ================================================ FILE: apps/docs/docs/getting-started/ng-primitives/ng-doc.page.ts ================================================ import GettingStartedCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Special thanks to ng-primitives */ const NgPrimitives: NgDocPage = { title: 'Ng Primitives', mdFile: 'index.md', category: GettingStartedCategory, order: 4, }; export default NgPrimitives; ================================================ FILE: apps/docs/docs/getting-started/quickstart/index.md ================================================ --- keyword: QuickstartPage --- ## Introduction Flowbite Angular can easily be integrated into your project using NPM. It functions as a common Angular library. ## Require via NPM Make sure that TailwindCSS is installed. ```bash npm install tailwindcss @tailwindcss/postcss postcss ``` Install Flowbite as a dependency using NPM by running this command: ```bash npm install flowbite-angular ng-primitives @ng-icons/core ``` ## TailwindCSS configuration Make sure to use the flowbite-angular configuration preset in your styles.css > **Note** If your `node_modules` folder is located above the parent directory (e.g., in a monorepo > setup), you may need to adjust the path with additional `../` to correctly reference it, such as > `@source "../../../node_modules/flowbite-angular";`. ```css @import 'tailwindcss'; @source "../node_modules/flowbite-angular"; ``` > **Note** If you want a working `primary` color definition, see `*ThemingPage` page ## PostCSS configuration Create a `postcss.config.json` file in the root of your project and add the `@tailwindcss/postcss` plugin to your PostCSS configuration. ```json { "plugins": { "@tailwindcss/postcss": {} } } ``` ================================================ FILE: apps/docs/docs/getting-started/quickstart/ng-doc.page.ts ================================================ import GettingStartedCategory from '../ng-doc.category'; import type { NgDocPage } from '@ng-doc/core'; /** * Get started with flowbite-angular by including it into your project using NPM */ const Quickstart: NgDocPage = { title: 'Quickstart', mdFile: 'index.md', category: GettingStartedCategory, order: 2, }; export default Quickstart; ================================================ FILE: apps/docs/docs/ng-doc.api.ts ================================================ import type { NgDocApi } from '@ng-doc/core'; const api: NgDocApi = { title: 'API Reference', order: 999, scopes: [ { name: 'core', route: 'core', include: 'libs/flowbite-angular/core/src/index.ts', }, { name: 'components', route: 'components', include: [ 'libs/flowbite-angular/accordion/src/index.ts', 'libs/flowbite-angular/alert/src/index.ts', 'libs/flowbite-angular/badge/src/index.ts', 'libs/flowbite-angular/breadcrumb/src/index.ts', 'libs/flowbite-angular/button/src/index.ts', 'libs/flowbite-angular/button-group/src/index.ts', 'libs/flowbite-angular/card/src/index.ts', 'libs/flowbite-angular/clipboard/src/index.ts', 'libs/flowbite-angular/dropdown/src/index.ts', 'libs/flowbite-angular/form/src/index.ts', 'libs/flowbite-angular/icon/src/index.ts', 'libs/flowbite-angular/indicator/src/index.ts', 'libs/flowbite-angular/modal/src/index.ts', 'libs/flowbite-angular/navbar/src/index.ts', 'libs/flowbite-angular/pagination/src/index.ts', 'libs/flowbite-angular/sidebar/src/index.ts', 'libs/flowbite-angular/tab/src/index.ts', 'libs/flowbite-angular/theme-toggle/src/index.ts', 'libs/flowbite-angular/table/src/index.ts', 'libs/flowbite-angular/tooltip/src/index.ts', ], }, ], }; export default api; ================================================ FILE: apps/docs/docs/shared/theme-macro.md ================================================ {% macro display(themes) %}
# Themes {% for theme in themes %} ## {{ theme.title }} {% if theme.description %} > **Note** > {{ theme.description }} {% endif %} ```typescript {{ theme.content }} ``` {% endfor %} {% endmacro %} ================================================ FILE: apps/docs/ng-doc.config.ts ================================================ import type { NgDocConfiguration } from '@ng-doc/builder'; import { ngKeywordsLoader, rxjsKeywordsLoader } from '@ng-doc/keywords-loaders'; const config: NgDocConfiguration = { cache: false, routePrefix: 'docs', docsPath: 'apps/docs/docs', outDir: 'tmp/apps/docs', tsConfig: 'apps/docs/tsconfig.app.json', guide: { anchorHeadings: ['h1', 'h2', 'h3', 'h4'], headerTemplate: 'apps/docs/src/app/shared/header-template.html', }, repoConfig: { url: 'https://github.com/themesberg/flowbite-angular', mainBranch: 'main', releaseBranch: 'release', }, shiki: { themes: { light: 'material-theme-lighter', dark: 'material-theme', }, }, keywords: { keywords: { MITLicense: { title: 'MIT License', url: 'https://github.com/themesberg/flowbite-angular/blob/main/README.md', }, CreativeCommons: { title: 'CC BY 3.0', url: 'https://creativecommons.org/licenses/by/3.0', }, Bootstrap: { title: 'Bootstrap', url: 'https://github.com/twbs/bootstrap', }, BootstrapAuthors: { title: 'Bootstrap authors', url: 'https://github.com/twbs/bootstrap/graphs/contributors', }, Twitter: { title: 'Twitter Inc', url: 'https://twitter.com', }, TailwindConfigurableKeys: { title: 'configurable keys on Tailwind CSS', url: 'https://tailwindcss.com/docs/theme#configuration-reference', }, TailwindThemingDocumentation: { title: 'Tailwind CSS Theming documentation', url: 'https://tailwindcss.com/docs/theme', }, NgPrimitivesDocumentation: { title: 'ng-primitives', url: 'https://angularprimitives.com', }, }, loaders: [ngKeywordsLoader(), rxjsKeywordsLoader()], }, }; export default config; ================================================ FILE: apps/docs/postcss.config.json ================================================ { "plugins": { "@tailwindcss/postcss": {} } } ================================================ FILE: apps/docs/project.json ================================================ { "name": "docs", "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "sourceRoot": "apps/docs/src", "prefix": "flowbite", "tags": [], "implicitDependencies": ["flowbite-angular"], "targets": { "build": { "executor": "@ng-doc/builder:application", "outputs": ["{options.outputPath.base}"], "options": { "outputPath": { "base": "dist/docs-static" }, "index": "apps/docs/src/index.html", "polyfills": ["zone.js"], "tsConfig": "apps/docs/tsconfig.app.json", "inlineStyleLanguage": "css", "assets": [ { "glob": "**/*", "input": "node_modules/@ng-doc/app/assets", "output": "assets/ng-doc/app" }, { "glob": "**/*", "input": "node_modules/@ng-doc/ui-kit/assets", "output": "assets/ng-doc/ui-kit" }, { "glob": "**/*", "input": "tmp/apps/docs/ng-doc/docs/assets", "output": "assets/ng-doc" }, { "glob": "**/*", "input": "apps/docs/public" } ], "styles": ["node_modules/@ng-doc/app/styles/global.css", "apps/docs/public/css/styles.css"], "scripts": [], "browser": "apps/docs/src/main.ts", "server": "apps/docs/src/main.server.ts", "prerender": true, "allowedCommonJsDependencies": ["@ng-doc/core"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kb" }, { "type": "anyComponentStyle", "maximumWarning": "2kb" } ], "fileReplacements": [ { "replace": "apps/docs/src/environments/environment.ts", "with": "apps/docs/src/environments/environment.prod.ts" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true, "namedChunks": true } }, "defaultConfiguration": "production" }, "serve": { "executor": "@ng-doc/builder:dev-server", "configurations": { "production": { "buildTarget": "docs:build:production" }, "development": { "buildTarget": "docs:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { "executor": "@angular-devkit/build-angular:extract-i18n", "options": { "buildTarget": "docs:build" } }, "lint": { "executor": "@nx/eslint:lint" } } } ================================================ FILE: apps/docs/public/.gitkeep ================================================ ================================================ FILE: apps/docs/public/css/ng-doc/base.css ================================================ :root { --ng-doc-font-system: 'roboto'; --ng-doc-primary: #ff2c51; --ng-doc-base-0: #ffffff; --ng-doc-base-1: var(--color-primary-50); --ng-doc-base-2: var(--color-primary-100); --ng-doc-base-3: #fdd6da; --ng-doc-base-4: var(--color-primary-200); --ng-doc-base-5: #fcaab6; --ng-doc-base-6: var(--color-primary-300); --ng-doc-base-7: #fb8192; --ng-doc-base-8: var(--color-primary-400); --ng-doc-base-9: #f9506a; --ng-doc-base-10: var(--color-primary-500); --ng-doc-background: var(--color-white); --ng-doc-sidebar-background: var(--color-white); --ng-doc-heading-color: #000000; --ng-doc-text: #000000; --ng-doc-border-color: var(--color-gray-200); --ng-doc-tab-group-tabs-background: #f9fafb; --ng-doc-code-background: #f9fafb; --ng-doc-text-selection: rgba(255, 44, 81, 0.15); } :root[data-theme='dark'] { --ng-doc-base-0: #0e0a0c; --ng-doc-base-1: var(--color-primary-950); --ng-doc-base-2: #66061e; --ng-doc-base-3: var(--color-primary-900); --ng-doc-base-4: #9e0c34; --ng-doc-base-5: var(--color-primary-800); --ng-doc-base-6: #b90f3b; --ng-doc-base-7: var(--color-primary-700); --ng-doc-base-8: #d91f3b; --ng-doc-base-9: var(--color-primary-600); --ng-doc-base-10: var(--color-primary-500); --ng-doc-background: var(--color-gray-900); --ng-doc-sidebar-background: var(--color-gray-900); --ng-doc-heading-color: #ffffff; --ng-doc-text: #ffffff; --ng-doc-border-color: var(--color-gray-700); --ng-doc-tab-group-tabs-background: #1e1e1e; --ng-doc-code-background: #1e1e1e; --ng-doc-text-selection: rgba(255, 44, 81, 0.25); } :root[data-theme='dark'] .shiki, :root[data-theme='dark'] .shiki span { color: var(--shiki-dark) !important; } ng-doc-tabs { border-radius: 0px !important; margin-top: 0px !important; } ng-doc-tab-group { border-radius: 0px !important; } ================================================ FILE: apps/docs/public/css/styles.css ================================================ @import 'tailwindcss'; @source "../../../../libs/flowbite-angular"; @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *)); @import './tw/fonts.css'; @theme { /* Colors */ /* Primary */ --color-primary-50: #fff0f1; --color-primary-100: #ffe1e4; --color-primary-200: #ffc8cf; --color-primary-300: #ff9ba8; --color-primary-400: #ff637b; --color-primary-500: #ff2c51; --color-primary-600: #f6083b; --color-primary-700: #c3002f; --color-primary-800: #ae0331; --color-primary-900: #940732; --color-primary-950: #5b041e; } @import './ng-doc/base.css'; ================================================ FILE: apps/docs/public/css/tw/fonts.css ================================================ @font-face { font-family: roboto; src: url('../../fonts/roboto.ttf') format('truetype'); } @theme { --default-font-family: 'roboto'; } ================================================ FILE: apps/docs/server.ts ================================================ import bootstrap from './src/main.server'; import { APP_BASE_HREF } from '@angular/common'; import { CommonEngine } from '@angular/ssr/node'; import express from 'express'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; // The Express app is exported so that it can be used by serverless Functions. export function app(): express.Express { const server = express(); const serverDistFolder = dirname(fileURLToPath(import.meta.url)); const browserDistFolder = resolve(serverDistFolder, '../browser'); const indexHtml = join(serverDistFolder, 'index.server.html'); const commonEngine = new CommonEngine(); server.set('view engine', 'html'); server.set('views', browserDistFolder); // Example Express Rest API endpoints // server.get('/api/**', (req, res) => { }); // Serve static files from /browser server.get( '**', express.static(browserDistFolder, { maxAge: '1y', index: 'index.html', }) ); // All regular routes use the Angular engine server.get('**', (req, res, next) => { const { protocol, originalUrl, baseUrl, headers } = req; commonEngine .render({ bootstrap, documentFilePath: indexHtml, url: `${protocol}://${headers.host}${originalUrl}`, publicPath: browserDistFolder, providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }], }) .then((html) => res.send(html)) .catch((err) => next(err)); }); return server; } function run(): void { const port = process.env['PORT'] || 4000; // Start up the Node server const server = app(); server.listen(port, () => { console.log(`Node Express server listening on http://localhost:${port}`); }); } run(); ================================================ FILE: apps/docs/src/app/app.component.html ================================================
Flowbite Logo Flowbite

© 2019-{{ currentYear() }} Flowbite™ is a registered trademark. All Rights Reserved.

================================================ FILE: apps/docs/src/app/app.component.ts ================================================ // Import with relative path since it's not in node_modules and we need to import package.json in order to get version // eslint-disable-next-line @nx/enforce-module-boundaries import flowbiteAngularPackageJson from '../../../../libs/flowbite-angular/package.json'; import { Badge } from 'flowbite-angular/badge'; import { Icon } from 'flowbite-angular/icon'; import { bars } from 'flowbite-angular/icon/outline/general'; import { discord, github, storybook, youtube } from 'flowbite-angular/icon/solid/brands'; import { Navbar, NavbarBrand, NavbarContent, NavbarIconItem, NavbarItem, NavbarToggle, } from 'flowbite-angular/navbar'; import { Theme, ThemeToggle } from 'flowbite-angular/theme-toggle'; import { Location } from '@angular/common'; import { Component, computed, inject } from '@angular/core'; import { RouterLink, RouterOutlet } from '@angular/router'; import { NgDocRootComponent, NgDocSearchComponent, NgDocSidebarComponent, NgDocSidebarService, } from '@ng-doc/app'; import { provideIcons } from '@ng-icons/core'; @Component({ providers: [provideIcons({ github, discord, youtube, bars, storybook })], imports: [ RouterOutlet, NgDocRootComponent, NgDocSidebarComponent, NgDocSearchComponent, Navbar, NavbarBrand, NavbarContent, NavbarIconItem, NavbarItem, NavbarToggle, Badge, ThemeToggle, RouterLink, Icon, ], hostDirectives: [ { directive: Theme, }, ], selector: 'flowbite-root', templateUrl: './app.component.html', host: { '[attr.data-ng-doc-is-landing]': 'isLandingPage', }, }) export class AppComponent { protected readonly sidebarService = inject(NgDocSidebarService); protected readonly location = inject(Location); get isLandingPage(): boolean { return this.location.path() === ''; } public readonly currentYear = computed(() => new Date().getFullYear()); public readonly flowbiteAngularVersion = computed(() => flowbiteAngularPackageJson.version); } ================================================ FILE: apps/docs/src/app/app.config.server.ts ================================================ import { appConfig } from './app.config'; import type { ApplicationConfig } from '@angular/core'; import { mergeApplicationConfig } from '@angular/core'; import { provideServerRendering } from '@angular/ssr'; const serverConfig: ApplicationConfig = { providers: [provideServerRendering()], }; export const config = mergeApplicationConfig(appConfig, serverConfig); ================================================ FILE: apps/docs/src/app/app.config.ts ================================================ import { appRoutes } from './app.routes'; import { docDemoDisplayerProcessor } from './shared/processors/doc-demo-displayer-processor/doc-demo-displayer-processor'; import { provideFlowbiteThemeConfig } from 'flowbite-angular/theme-toggle'; import { provideHttpClient, withFetch, withInterceptorsFromDi } from '@angular/common/http'; import { provideZoneChangeDetection, type ApplicationConfig } from '@angular/core'; import { provideClientHydration } from '@angular/platform-browser'; import { provideRouter, withInMemoryScrolling } from '@angular/router'; import { NG_DOC_DEFAULT_PAGE_PROCESSORS, NG_DOC_DEFAULT_PAGE_SKELETON, NgDocDefaultSearchEngine, provideMainPageProcessor, provideNgDocApp, providePageProcessor, providePageSkeleton, provideSearchEngine, } from '@ng-doc/app'; import { provideNgDocContext } from '@ng-doc/generated'; export const appConfig: ApplicationConfig = { providers: [ // #region NgDoc provideNgDocContext(), provideNgDocApp({ shiki: { themes: [ import('shiki/themes/material-theme.mjs'), import('shiki/themes/material-theme-lighter.mjs'), ], theme: { light: 'material-theme-lighter', dark: 'material-theme', }, }, }), provideSearchEngine(NgDocDefaultSearchEngine, { tolerance: 2 }), providePageSkeleton(NG_DOC_DEFAULT_PAGE_SKELETON), provideMainPageProcessor(NG_DOC_DEFAULT_PAGE_PROCESSORS), providePageProcessor(docDemoDisplayerProcessor), // #endregion provideZoneChangeDetection(), provideClientHydration(), provideRouter( appRoutes, withInMemoryScrolling({ scrollPositionRestoration: 'enabled', anchorScrolling: 'enabled' }) ), provideHttpClient(withInterceptorsFromDi(), withFetch()), provideFlowbiteThemeConfig({ type: { type: 'attr', name: 'data-theme' }, }), ], }; ================================================ FILE: apps/docs/src/app/app.routes.ts ================================================ import type { Routes } from '@angular/router'; export const appRoutes: Routes = [ { path: '', loadChildren: () => import('./pages/landing/landing.routes'), }, { path: 'docs', loadChildren: () => import('./pages/docs/docs.routes'), }, { path: '**', redirectTo: '', pathMatch: 'full', }, ]; ================================================ FILE: apps/docs/src/app/pages/docs/docs.component.css ================================================ ================================================ FILE: apps/docs/src/app/pages/docs/docs.component.html ================================================ ================================================ FILE: apps/docs/src/app/pages/docs/docs.component.ts ================================================ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ selector: 'flowbite-docs', imports: [RouterOutlet], templateUrl: './docs.component.html', styleUrl: './docs.component.css', }) export class DocsComponent {} ================================================ FILE: apps/docs/src/app/pages/docs/docs.routes.ts ================================================ import { DocsComponent } from './docs.component'; import type { Routes } from '@angular/router'; import { NG_DOC_ROUTING } from '@ng-doc/generated'; export default [ { path: '', redirectTo: 'getting-started/introduction', pathMatch: 'full', }, { path: 'getting-started', redirectTo: 'getting-started/introduction', pathMatch: 'full', }, { path: '', component: DocsComponent, children: NG_DOC_ROUTING, }, ] as Routes; ================================================ FILE: apps/docs/src/app/pages/landing/landing.component.html ================================================

Speed up your web development with Flowbite Angular

Flowbite Angular is an official Flowbite component library for Angular. All interactivities are handled by Angular.

Featured in:

UI components in Angular

Flowbite budget is a mobile app that helps users easily track their expenses and create a budget.

With a user-friendly interface, the app allows users to quickly input their income and expenses, and then automatically categorizes them for easy tracking.

Dynamic reports and dashboards

Templates for everyone

Development workflow

Limitless business automation

Knowledge management

Light
Dark

Dark mode integration

Dark mode is a popular feature that is being offered by many applications, operating systems, and websites in recent years.

It changes the color scheme of the user interface from a light background with dark text to a dark background with light text, providing a new and sleek look that many users find appealing.

Reduce eye strain

Better visibility in low light conditions

Accessibility

Work with Tailwind CSS

Flowbite budget is a mobile app that helps users easily track their expenses and create a budget.

With a user-friendly interface, the app allows users to quickly input their income and expenses, and then automatically categorizes them for easy tracking.

Dynamic reports and dashboards

Templates for everyone

Development workflow

Limitless business automation

Knowledge management

================================================ FILE: apps/docs/src/app/pages/landing/landing.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Clipboard } from 'flowbite-angular/clipboard'; import { Icon } from 'flowbite-angular/icon'; import { combinator, dev, productHunt, reddit, youtube } from 'flowbite-angular/icon/brand'; import { arrowRight, chevronRight } from 'flowbite-angular/icon/outline/arrows'; import { check, eye } from 'flowbite-angular/icon/outline/general'; import { moon, sun } from 'flowbite-angular/icon/outline/weather'; import { Component, inject } from '@angular/core'; import { RouterLink } from '@angular/router'; import { NgDocThemeService } from '@ng-doc/app/services/theme'; import { provideIcons } from '@ng-icons/core'; @Component({ selector: 'flowbite-landing', providers: [ provideIcons({ arrowRight, reddit, dev, productHunt, combinator, youtube, sun, moon, check, eye, chevronRight, }), ], imports: [Button, Icon, Clipboard, RouterLink], templateUrl: './landing.component.html', }) export class LandingComponent { protected readonly themeService = inject(NgDocThemeService); public setTheme(id: 'light' | 'dark'): void { this.themeService.set(id); } } ================================================ FILE: apps/docs/src/app/pages/landing/landing.routes.ts ================================================ import { LandingComponent } from './landing.component'; import type { Routes } from '@angular/router'; export default [ { path: '', component: LandingComponent, }, ] as Routes; ================================================ FILE: apps/docs/src/app/shared/components/flowbite-doc-demo-displayer/flowbite-doc-demo-displayer.component.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Icon } from 'flowbite-angular/icon'; import { desktopPc, mobilePhone, tablet } from 'flowbite-angular/icon/outline/general'; import { moon, sun } from 'flowbite-angular/icon/outline/weather'; import { github } from 'flowbite-angular/icon/solid/brands'; import { Component, signal } from '@angular/core'; import { provideIcons } from '@ng-icons/core'; @Component({ selector: 'flowbite-doc-demo', imports: [Button, Icon], providers: [provideIcons({ github, desktopPc, tablet, mobilePhone, sun, moon })], template: `
`, styles: ` ng-doc-demo { margin: 0px; } `, }) export class FlowbiteDocDemoComponent { public themeMode = signal('light'); } ================================================ FILE: apps/docs/src/app/shared/header-template.html ================================================

{{ NgDocPage.title }}

{{ Metadata.description }}
================================================ FILE: apps/docs/src/app/shared/processors/doc-demo-displayer-processor/doc-demo-displayer-processor.ts ================================================ import { FlowbiteDocDemoComponent } from '../../components/flowbite-doc-demo-displayer/flowbite-doc-demo-displayer.component'; import type { Injector } from '@angular/core'; import { Renderer2 } from '@angular/core'; import type { NgDocPageProcessor } from '@ng-doc/app'; export const docDemoDisplayerProcessor: NgDocPageProcessor = { component: FlowbiteDocDemoComponent, selector: 'ng-doc-demo', nodeToReplace: (element: Element, injector: Injector) => { // Get the renderer from the injector const renderer: Renderer2 = injector.get(Renderer2); // Create an anchor element to insert the `FlowbiteDocDemoDisplayerComponent` in the correct place. const anchor: Element = renderer.createElement('div'); renderer.setStyle(element, 'margin', '0px'); // Insert the anchor before the table and return it return element.parentNode?.insertBefore(anchor, element) ?? element; }, // eslint-disable-next-line @typescript-eslint/no-unused-vars extractOptions: (element: Element) => ({ content: [[element]], }), }; ================================================ FILE: apps/docs/src/environments/environment.prod.ts ================================================ export const environment = { production: true, }; ================================================ FILE: apps/docs/src/environments/environment.ts ================================================ // This file can be replaced during build by using the `fileReplacements` array. // `ng build` replaces `environment.ts` with `environment.prod.ts`. // The list of file replacements can be found in `angular.json`. export const environment = { production: false, }; /* * For easier debugging in development mode, you can import the following file * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. * * This import should be commented out in production mode because it will have a negative impact * on performance if an error is thrown. */ // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. ================================================ FILE: apps/docs/src/index.html ================================================ Flowbite Angular ================================================ FILE: apps/docs/src/main.server.ts ================================================ import { AppComponent } from './app/app.component'; import { config } from './app/app.config.server'; import type { BootstrapContext } from '@angular/platform-browser'; import { bootstrapApplication } from '@angular/platform-browser'; const bootstrap = (context: BootstrapContext) => bootstrapApplication(AppComponent, config, context); export default bootstrap; ================================================ FILE: apps/docs/src/main.ts ================================================ import { AppComponent } from './app/app.component'; import { appConfig } from './app/app.config'; import { environment } from './environments/environment'; import { enableProdMode } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; if (environment.production) { enableProdMode(); } bootstrapApplication(AppComponent, appConfig).catch((e) => console.log(e)); ================================================ FILE: apps/docs/tsconfig.app.json ================================================ { "extends": "./tsconfig.json", "compilerOptions": { "allowSyntheticDefaultImports": true, "outDir": "../../dist/out-tsc", "types": ["node"], "target": "ES2022", "useDefineForClassFields": false, "moduleResolution": "bundler" }, "files": ["src/main.ts", "src/main.server.ts", "server.ts"], "include": ["src/**/*.d.ts", "tailwind.config.js"] } ================================================ FILE: apps/docs/tsconfig.editor.json ================================================ { "extends": "./tsconfig.json", "include": ["**/*.ts"], "compilerOptions": { "types": ["node"] } } ================================================ FILE: apps/docs/tsconfig.json ================================================ { "extends": "../../tsconfig.base.json", "files": [], "include": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.editor.json" } ], "compilerOptions": { "resolveJsonModule": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "target": "ES2022", "esModuleInterop": true, "module": "preserve", "moduleResolution": "bundler" }, "angularCompilerOptions": { "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: apps/storybook/.eslintrc.json ================================================ { "extends": ["../../.eslintrc.json", "plugin:storybook/recommended"], "ignorePatterns": ["!**/*", "storybook-static"], "overrides": [ { "files": ["*.ts"], "extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], "rules": { "@angular-eslint/directive-selector": [ "error", { "type": "attribute", "prefix": "storybook", "style": "camelCase" } ], "@angular-eslint/component-selector": [ "error", { "type": "element", "prefix": "storybook", "style": "kebab-case" } ] } }, { "files": ["*.html"], "extends": ["plugin:@nx/angular-template"], "rules": {} } ] } ================================================ FILE: apps/storybook/.storybook/helper.ts ================================================ import { UPDATE_STORY_ARGS } from 'storybook/internal/core-events'; import type { StoryId } from 'storybook/internal/csf'; import { addons } from 'storybook/preview-api'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const updateArgs = (storyId: StoryId, args: any) => { addons.getChannel().emit(UPDATE_STORY_ARGS, { storyId, updatedArgs: args, }); }; export const bindTwoWay = (id: StoryId, prop: keyof T): ((value: T[keyof T]) => void) => { return (value: T[keyof T]) => updateArgs(id, { [prop]: value }); }; export function hiddenOutputActions(...outputs: string[]) { return outputs.reduce( (acc, output) => { acc[output] = { action: output, table: { disable: true }, }; return acc; }, {} as Record ); } ================================================ FILE: apps/storybook/.storybook/main.ts ================================================ // This file has been automatically migrated to valid ESM format by Storybook. import type { StorybookConfig } from '@storybook/angular'; import { createRequire } from 'node:module'; import { dirname, join } from 'node:path'; const require = createRequire(import.meta.url); const config: StorybookConfig = { stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'], staticDirs: ['../public'], addons: [getAbsolutePath('@storybook/addon-themes'), getAbsolutePath('@storybook/addon-docs')], framework: { name: getAbsolutePath('@storybook/angular'), options: {}, }, docs: { defaultName: 'Documentation', }, webpackFinal: (config) => { config.module?.rules?.push({ test: /\.css$/i, exclude: /node_modules/, use: [ { loader: 'postcss-loader', options: { postcssOptions: { plugins: ['@tailwindcss/postcss'], }, }, }, ], }); return config; }, }; export default config; // To customize your webpack configuration you can use the webpackFinal field. // Check https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config // and https://nx.dev/recipes/storybook/custom-builder-configs function getAbsolutePath(value: string): any { return dirname(require.resolve(join(value, 'package.json'))); } ================================================ FILE: apps/storybook/.storybook/preview-body.html ================================================ ================================================ FILE: apps/storybook/.storybook/preview.ts ================================================ import { withThemeByDataAttribute } from '@storybook/addon-themes'; import type { Decorator, Preview } from '@storybook/angular'; export const decorators: Decorator[] = [ withThemeByDataAttribute({ themes: { light: 'light', dark: 'dark', }, defaultTheme: 'light', attributeName: 'data-mode', }), ]; export default { tags: ['autodocs'], } as Preview; ================================================ FILE: apps/storybook/.storybook/tsconfig.json ================================================ { "extends": "../tsconfig.json", "compilerOptions": { "emitDecoratorMetadata": true }, "exclude": ["../**/*.spec.ts"], "include": [ "../src/**/*.stories.ts", "../src/**/*.stories.js", "../src/**/*.stories.jsx", "../src/**/*.stories.tsx", "../src/**/*.stories.mdx", "*.js", "*.ts", "../.postcssrc.json.js" ] } ================================================ FILE: apps/storybook/postcss.config.json ================================================ { "plugins": { "@tailwindcss/postcss": {} } } ================================================ FILE: apps/storybook/project.json ================================================ { "name": "storybook", "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "prefix": "storybook", "sourceRoot": "apps/storybook/src", "tags": [], "implicitDependencies": ["flowbite-angular"], "targets": { "serve-static": { "executor": "@nx/web:file-server", "options": { "buildTarget": "storybook:build", "staticFilePath": "dist/storybook", "spa": true } }, "build": { "executor": "@storybook/angular:build-storybook", "outputs": ["{options.outputDir}"], "options": { "outputDir": "dist/storybook", "configDir": "apps/storybook/.storybook", "browserTarget": "storybook:build", "styles": ["apps/storybook/styles.css"], "assets": [], "compodoc": false }, "configurations": { "production": {}, "development": {}, "ci": { "quiet": true } }, "defaultConfiguration": "production" }, "serve": { "executor": "@storybook/angular:start-storybook", "options": { "port": 4400, "configDir": "apps/storybook/.storybook", "browserTarget": "storybook:build", "styles": ["apps/storybook/styles.css"], "compodoc": false }, "configurations": { "production": {}, "development": {}, "ci": { "quiet": true } }, "defaultConfiguration": "development" } } } ================================================ FILE: apps/storybook/src/accordion.component.stories.ts ================================================ import { Accordion, AccordionContent, AccordionItem, AccordionTitle, defaultFlowbiteAccordionConfig, } from 'flowbite-angular/accordion'; import { Icon } from 'flowbite-angular/icon'; import { chevronDown } from 'flowbite-angular/icon/outline/arrows'; import { NgClass } from '@angular/common'; import { provideIcons } from '@ng-icons/core'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; import type { Meta, StoryObj } from '@storybook/angular'; type StoryType = Accordion & { type: string; disabled: boolean; collapsible: boolean; }; export default { title: 'Component/Accordion', component: Accordion, decorators: [ moduleMetadata({ imports: [AccordionItem, AccordionTitle, AccordionContent, Icon, NgClass], providers: [provideIcons({ chevronDown })], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteAccordionConfig.color), }, }, }, flush: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteAccordionConfig.flush), }, }, }, type: { control: 'select', type: 'string', options: ['single', 'multiple'], table: { category: 'Input', defaultValue: { summary: 'single', }, }, }, disabled: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: 'false', }, }, }, collapsible: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: 'false', }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteAccordionConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteAccordionConfig.color, flush: defaultFlowbiteAccordionConfig.flush, customTheme: defaultFlowbiteAccordionConfig.customTheme, type: 'single', disabled: false, collapsible: false, }, render: (args) => ({ props: args, template: `
What is Flowbite?

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.

Check out this guide to learn how to get started and start developing websites even faster with components on top of Tailwind CSS.

Is there a Figma file available?

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.

Check out the Figma design system based on the utility classes from Tailwind CSS and components from Flowbite.

What are the differences between Flowbite and Tailwind UI?

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.

However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.

Learn more about these technologies:

`, }), }; export const AccordionIconStory: StoryObj = { name: 'Accordion with Icon', args: { color: defaultFlowbiteAccordionConfig.color, flush: defaultFlowbiteAccordionConfig.flush, customTheme: defaultFlowbiteAccordionConfig.customTheme, type: 'single', disabled: false, collapsible: false, }, render: (args) => ({ props: args, template: `
What is Flowbite?

Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.

Check out this guide to learn how to get started and start developing websites even faster with components on top of Tailwind CSS.

Is there a Figma file available?

Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.

Check out the Figma design system based on the utility classes from Tailwind CSS and components from Flowbite.

What are the differences between Flowbite and Tailwind UI?

The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.

However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.

Learn more about these technologies:

`, }), }; ================================================ FILE: apps/storybook/src/alert.stories.ts ================================================ import { Alert, AlertButton, AlertContent, defaultFlowbiteAlertConfig, } from 'flowbite-angular/alert'; import { Button } from 'flowbite-angular/button'; import { Icon } from 'flowbite-angular/icon'; import { close, eye, infoCircle } from 'flowbite-angular/icon/outline/general'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Alert; export default { title: 'Component/Alert', component: Alert, decorators: [ moduleMetadata({ imports: [Icon, AlertButton, AlertContent, Button], providers: [provideIcons({ infoCircle, close, eye })], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteAlertConfig.color), }, }, }, border: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteAlertConfig.border), }, }, }, accent: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteAlertConfig.accent), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteAlertConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteAlertConfig.color, border: defaultFlowbiteAlertConfig.border, accent: defaultFlowbiteAlertConfig.accent, customTheme: defaultFlowbiteAlertConfig.customTheme, }, render: (args) => ({ props: args, template: `
${args.color} alert! Change a few things up and try submitting again.
`, }), }; export const AlertIconStory: StoryObj = { name: 'Alert with icon', args: { color: defaultFlowbiteAlertConfig.color, border: defaultFlowbiteAlertConfig.border, accent: defaultFlowbiteAlertConfig.accent, customTheme: defaultFlowbiteAlertConfig.customTheme, }, render: (args) => ({ props: args, template: `
${args.color} alert! Change a few things up and try submitting again.
`, }), }; export const DismissableAlertStory: StoryObj = { name: 'Dismissable Alert', args: { color: defaultFlowbiteAlertConfig.color, border: defaultFlowbiteAlertConfig.border, accent: defaultFlowbiteAlertConfig.accent, customTheme: defaultFlowbiteAlertConfig.customTheme, }, render: (args) => ({ props: args, template: `
${args.color} alert! Change a few things up and try submitting again.
`, }), }; export const AlertMoreContentStory: StoryObj = { name: 'Alert with more content', args: { color: defaultFlowbiteAlertConfig.color, border: defaultFlowbiteAlertConfig.border, accent: defaultFlowbiteAlertConfig.accent, customTheme: defaultFlowbiteAlertConfig.customTheme, }, render: (args) => ({ props: args, template: `

This is a ${args.color} alert

More ${args.color} about this ${args.color} alert goes here. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.
`, }), }; ================================================ FILE: apps/storybook/src/badge.stories.ts ================================================ import { Badge, BadgeButton, BadgeLink, defaultFlowbiteBadgeConfig } from 'flowbite-angular/badge'; import { Icon } from 'flowbite-angular/icon'; import { close, infoCircle } from 'flowbite-angular/icon/outline/general'; import { clock } from 'flowbite-angular/icon/solid/general'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Badge; export default { title: 'Component/Badge', component: Badge, decorators: [ moduleMetadata({ imports: [BadgeLink, Icon, BadgeButton], providers: [provideIcons({ clock, infoCircle, close })], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBadgeConfig.color), }, }, }, border: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBadgeConfig.border), }, }, }, size: { control: 'select', type: 'string', options: ['xs', 'sm'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBadgeConfig.size), }, }, }, pill: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBadgeConfig.pill), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBadgeConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteBadgeConfig.color, border: defaultFlowbiteBadgeConfig.border, size: defaultFlowbiteBadgeConfig.size, pill: defaultFlowbiteBadgeConfig.pill, customTheme: defaultFlowbiteBadgeConfig.customTheme, }, render: (args) => ({ props: args, template: ` ${args.color} `, }), }; export const BadgeLinkStory: StoryObj = { name: 'Badge as link', args: { color: defaultFlowbiteBadgeConfig.color, border: defaultFlowbiteBadgeConfig.border, size: defaultFlowbiteBadgeConfig.size, pill: defaultFlowbiteBadgeConfig.pill, customTheme: defaultFlowbiteBadgeConfig.customTheme, }, render: (args) => ({ props: args, template: ` ${args.color} `, }), }; export const BadgeIconStory: StoryObj = { name: 'Badge with icon', args: { color: defaultFlowbiteBadgeConfig.color, border: defaultFlowbiteBadgeConfig.border, size: defaultFlowbiteBadgeConfig.size, pill: defaultFlowbiteBadgeConfig.pill, customTheme: defaultFlowbiteBadgeConfig.customTheme, }, render: (args) => ({ props: args, template: ` ${args.color} `, }), }; export const BadgeIconOnlyStory: StoryObj = { name: 'Badge with icon only', args: { color: defaultFlowbiteBadgeConfig.color, border: defaultFlowbiteBadgeConfig.border, size: defaultFlowbiteBadgeConfig.size, pill: true, customTheme: defaultFlowbiteBadgeConfig.customTheme, }, render: (args) => ({ props: args, template: ` `, }), }; export const DismissableBadgeStory: StoryObj = { name: 'Dismissable Badge', args: { color: defaultFlowbiteBadgeConfig.color, border: defaultFlowbiteBadgeConfig.border, size: defaultFlowbiteBadgeConfig.size, pill: defaultFlowbiteBadgeConfig.pill, customTheme: defaultFlowbiteBadgeConfig.customTheme, }, render: (args) => ({ props: args, template: ` ${args.color} `, }), }; ================================================ FILE: apps/storybook/src/breadcrumb.stories.ts ================================================ import { Badge } from 'flowbite-angular/badge'; import { Breadcrumb, BreadcrumbContent, BreadcrumbItem, defaultFlowbiteBreadcrumbConfig, } from 'flowbite-angular/breadcrumb'; import { Button } from 'flowbite-angular/button'; import { Dropdown, DropdownItem } from 'flowbite-angular/dropdown'; import { Icon } from 'flowbite-angular/icon'; import { chevronRight } from 'flowbite-angular/icon/outline/arrows'; import { home } from 'flowbite-angular/icon/outline/general'; import { provideIcons } from '@ng-icons/core'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; import type { Meta, StoryObj } from '@storybook/angular'; import { NgpMenuTrigger } from 'ng-primitives/menu'; type StoryType = Breadcrumb; export default { title: 'Component/Breadcrumb', component: Breadcrumb, decorators: [ moduleMetadata({ providers: [provideIcons({ home, chevronRight })], imports: [ BreadcrumbContent, BreadcrumbItem, Icon, Badge, Button, NgpMenuTrigger, Dropdown, DropdownItem, ], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBreadcrumbConfig.color), }, }, }, solid: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBreadcrumbConfig.solid), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBreadcrumbConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteBreadcrumbConfig.color, solid: defaultFlowbiteBreadcrumbConfig.solid, customTheme: defaultFlowbiteBreadcrumbConfig.customTheme, }, render: (args) => ({ props: args, template: ` `, }), }; export const SolidBreadcrumbStory: StoryObj = { name: 'Solid Breadcrumb', args: { color: defaultFlowbiteBreadcrumbConfig.color, solid: true, customTheme: defaultFlowbiteBreadcrumbConfig.customTheme, }, render: (args) => ({ props: { ...args, }, template: ` `, }), }; export const HeaderBreadcrumbStory: StoryObj = { name: 'Header Breadcrumb', args: { color: defaultFlowbiteBreadcrumbConfig.color, solid: true, customTheme: defaultFlowbiteBreadcrumbConfig.customTheme, }, render: (args) => ({ props: { ...args, }, template: ` `, }), }; ================================================ FILE: apps/storybook/src/button.component.stories.ts ================================================ import type { FlowbiteBaseButtonColors, FlowbiteBaseButtonSizes } from 'flowbite-angular/button'; import { Button, defaultFlowbiteBaseButtonConfig, defaultFlowbiteButtonConfig, } from 'flowbite-angular/button'; import { ButtonGroup } from 'flowbite-angular/button-group'; import { Icon } from 'flowbite-angular/icon'; import { close } from 'flowbite-angular/icon/outline/general'; import { provideIcons } from '@ng-icons/core'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; import type { Meta, StoryObj } from '@storybook/angular'; type StoryType = Button & { disabled: boolean; color: keyof FlowbiteBaseButtonColors; size: keyof FlowbiteBaseButtonSizes; pill: boolean; outline: boolean; }; export default { title: 'Component/Button', component: Button, decorators: [ moduleMetadata({ imports: [Icon, ButtonGroup], providers: [provideIcons({ close })], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBaseButtonConfig.color), }, }, }, size: { control: 'select', type: 'string', options: ['xs', 'sm', 'md', 'lg', 'xl'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBaseButtonConfig.size), }, }, }, pill: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBaseButtonConfig.pill), }, }, }, outline: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteBaseButtonConfig.outline), }, }, }, disabled: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: 'false', }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteButtonConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteBaseButtonConfig.color, size: defaultFlowbiteBaseButtonConfig.size, pill: defaultFlowbiteBaseButtonConfig.pill, outline: defaultFlowbiteBaseButtonConfig.outline, disabled: false, customTheme: defaultFlowbiteButtonConfig.customTheme, }, render: (args) => ({ props: args, template: ` `, }), }; export const IconButtonStory: StoryObj = { name: 'Icon Button', args: { color: defaultFlowbiteBaseButtonConfig.color, size: defaultFlowbiteBaseButtonConfig.size, pill: defaultFlowbiteBaseButtonConfig.pill, outline: defaultFlowbiteBaseButtonConfig.outline, disabled: false, customTheme: defaultFlowbiteButtonConfig.customTheme, }, render: (args) => ({ props: args, template: ` `, }), }; export const IconButtonOnlyStory: StoryObj = { name: 'Icon Button Only', args: { color: defaultFlowbiteBaseButtonConfig.color, size: defaultFlowbiteBaseButtonConfig.size, pill: defaultFlowbiteBaseButtonConfig.pill, outline: defaultFlowbiteBaseButtonConfig.outline, disabled: false, customTheme: defaultFlowbiteButtonConfig.customTheme, }, render: (args) => ({ props: args, template: ` `, }), }; export const ButtonGroupStory: StoryObj = { name: 'Button Group', args: { color: defaultFlowbiteBaseButtonConfig.color, size: defaultFlowbiteBaseButtonConfig.size, pill: defaultFlowbiteBaseButtonConfig.pill, outline: defaultFlowbiteBaseButtonConfig.outline, disabled: false, customTheme: defaultFlowbiteButtonConfig.customTheme, }, render: (args) => ({ props: args, template: `
`, }), }; ================================================ FILE: apps/storybook/src/card.component.stories.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Card, CardContent, CardHeader, defaultFlowbiteCardConfig } from 'flowbite-angular/card'; import { Dropdown, DropdownItem } from 'flowbite-angular/dropdown'; import { Icon } from 'flowbite-angular/icon'; import { arrowRight } from 'flowbite-angular/icon/outline/arrows'; import { dotsHorizontal, link } from 'flowbite-angular/icon/outline/general'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; import { NgpMenuTrigger } from 'ng-primitives/menu'; type StoryType = Card; export default { title: 'Component/Card', component: Card, decorators: [ moduleMetadata({ imports: [CardHeader, CardContent, Button, Icon, NgpMenuTrigger, Dropdown, DropdownItem], providers: [provideIcons({ arrowRight, link, dotsHorizontal })], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteCardConfig.color), }, }, }, size: { control: 'select', type: 'string', options: ['xs', 'sm', 'md', 'lg', 'xl'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteCardConfig.size), }, }, }, orientation: { control: 'select', type: 'string', options: ['vertical', 'horizontal'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteCardConfig.orientation), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteCardConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteCardConfig.color, size: defaultFlowbiteCardConfig.size, orientation: defaultFlowbiteCardConfig.orientation, customTheme: defaultFlowbiteCardConfig.customTheme, }, render: (args) => ({ props: args, template: `
Noteworthy technology acquisitions 2021

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

`, }), }; export const CardButtonStory: StoryObj = { name: 'Card with button', args: { color: defaultFlowbiteCardConfig.color, size: defaultFlowbiteCardConfig.size, orientation: defaultFlowbiteCardConfig.orientation, customTheme: defaultFlowbiteCardConfig.customTheme, }, render: (args) => ({ props: args, template: `
Noteworthy technology acquisitions 2021

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

`, }), }; export const CardLinkStory: StoryObj = { name: 'Card with link', args: { color: defaultFlowbiteCardConfig.color, size: defaultFlowbiteCardConfig.size, orientation: defaultFlowbiteCardConfig.orientation, customTheme: defaultFlowbiteCardConfig.customTheme, }, render: (args) => ({ props: args, template: `
Need a help in Claim?

Go to this step by step guideline process on how to certify for your weekly benefits:

See our guideline
`, }), }; export const CardImageStory: StoryObj = { name: 'Card with image', args: { color: defaultFlowbiteCardConfig.color, size: defaultFlowbiteCardConfig.size, orientation: defaultFlowbiteCardConfig.orientation, customTheme: defaultFlowbiteCardConfig.customTheme, }, render: (args) => ({ props: args, template: `
Noteworthy technology acquisitions 2021

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

`, }), }; export const CardOrientationStory: StoryObj = { name: 'Horizontal Card', args: { color: defaultFlowbiteCardConfig.color, size: defaultFlowbiteCardConfig.size, orientation: 'horizontal', customTheme: defaultFlowbiteCardConfig.customTheme, }, render: (args) => ({ props: args, template: `
Noteworthy technology acquisitions 2021

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

`, }), }; export const UserProfileCardStory: StoryObj = { name: 'User profile Card', args: { color: defaultFlowbiteCardConfig.color, size: 'sm', orientation: defaultFlowbiteCardConfig.orientation, customTheme: defaultFlowbiteCardConfig.customTheme, }, render: (args) => ({ props: args, template: `
  • Edit
  • Export data
  • Delete
  • Bonnie Green
    Visual designer
    `, }), }; ================================================ FILE: apps/storybook/src/clipboard.component.stories.ts ================================================ import { Clipboard, defaultFlowbiteClipboardConfig } from 'flowbite-angular/clipboard'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate } from '@storybook/angular'; type StoryType = Clipboard; export default { title: 'Component/Clipboard', component: Clipboard, argTypes: { id: { control: 'text', type: 'string', table: { category: 'Input', }, }, value: { control: 'text', type: 'string', table: { category: 'Input', }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteClipboardConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { id: 'clipboard', value: 'npm install flowbite-angular', customTheme: defaultFlowbiteClipboardConfig.customTheme, }, render: (args) => ({ props: args, template: `
    `, }), }; ================================================ FILE: apps/storybook/src/dropdown.stories.ts ================================================ import { Button } from 'flowbite-angular/button'; import { defaultFlowbiteDropdownConfig, Dropdown, DropdownContent, DropdownItem, } from 'flowbite-angular/dropdown'; import { Icon } from 'flowbite-angular/icon'; import { chevronDown, chevronRight } from 'flowbite-angular/icon/outline/arrows'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; import { NgpMenuTrigger, NgpSubmenuTrigger } from 'ng-primitives/menu'; type StoryType = Dropdown; export default { title: 'Component/Dropdown', component: Dropdown, decorators: [ moduleMetadata({ imports: [DropdownContent, DropdownItem, NgpMenuTrigger, NgpSubmenuTrigger, Button, Icon], providers: [provideIcons({ chevronRight, chevronDown })], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteDropdownConfig.color), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteDropdownConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteDropdownConfig.color, customTheme: defaultFlowbiteDropdownConfig.customTheme, }, render: (args) => ({ props: args, template: `
    • Dashboard
    • Settings
    • Earnings
    • Sign out
    `, }), }; export const DropdownDividerStory: StoryObj = { name: 'Dropdown with divider', args: { color: defaultFlowbiteDropdownConfig.color, customTheme: defaultFlowbiteDropdownConfig.customTheme, }, render: (args) => ({ props: args, template: `
    • Dashboard
    • Settings
    • Earnings
    • Separated link
    `, }), }; export const DropdownHeaderStory: StoryObj = { name: 'Dropdown with header', args: { color: defaultFlowbiteDropdownConfig.color, customTheme: defaultFlowbiteDropdownConfig.customTheme, }, render: (args) => ({ props: args, template: `
    Bonnie Green
    name@flowbite.com
    • Dashboard
    • Settings
    • Earnings
    • Sign out
    `, }), }; export const MultiLevelDropdownStory: StoryObj = { name: 'Multi level Dropdown', args: { color: defaultFlowbiteDropdownConfig.color, customTheme: defaultFlowbiteDropdownConfig.customTheme, }, render: (args) => ({ props: args, template: `
    Bonnie Green
    name@flowbite.com
    • Dashboard
    • Dropdown
    • Earnings
    • Sign out
    • Overview
    • My downloads
    • Billing
    • Rewards
    `, }), }; ================================================ FILE: apps/storybook/src/form/form-field.component.stories.ts ================================================ import { Button } from 'flowbite-angular/button'; import { defaultFlowbiteFormFieldConfig, FormControl, FormField, Helper, Label, } from 'flowbite-angular/form'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = FormField & { disabled: boolean; }; export default { title: 'Component/Form/FormField', component: FormField, decorators: [ moduleMetadata({ imports: [FormControl, Label, Helper, Button], }), ], argTypes: { size: { control: 'select', type: 'string', options: ['sm', 'md', 'xl'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteFormFieldConfig.size), }, }, }, color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteFormFieldConfig.color), }, }, }, mode: { control: 'select', type: 'string', options: ['normal', 'floating'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteFormFieldConfig.mode), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteFormFieldConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { size: defaultFlowbiteFormFieldConfig.size, color: defaultFlowbiteFormFieldConfig.color, mode: defaultFlowbiteFormFieldConfig.mode, customTheme: defaultFlowbiteFormFieldConfig.customTheme, }, render: (args) => ({ props: args, template: `

    We’ll never share your details. Read our Privacy Policy.

    `, }), }; export const OutlineFormFieldStory: StoryObj = { name: 'Outline Form Field', args: { size: defaultFlowbiteFormFieldConfig.size, color: defaultFlowbiteFormFieldConfig.color, mode: 'floating', customTheme: defaultFlowbiteFormFieldConfig.customTheme, }, render: (args) => ({ props: args, template: `

    We’ll never share your details. Read our Privacy Policy.

    `, }), }; export const DisabledFormControlStory: StoryObj = { name: 'Disabled Form Control', args: { size: defaultFlowbiteFormFieldConfig.size, color: defaultFlowbiteFormFieldConfig.color, mode: defaultFlowbiteFormFieldConfig.mode, customTheme: defaultFlowbiteFormFieldConfig.customTheme, }, render: (args) => ({ props: args, template: `

    We’ll never share your details. Read our Privacy Policy.

    `, }), }; ================================================ FILE: apps/storybook/src/icon.component.stories.ts ================================================ import { defaultFlowbiteIconConfig, Icon } from 'flowbite-angular/icon'; import { close } from 'flowbite-angular/icon/outline/general'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Icon; export default { title: 'Component/Icon', component: Icon, decorators: [ moduleMetadata({ providers: [provideIcons({ close })], }), ], argTypes: { color: { control: 'select', type: 'string', options: [ 'default', 'info', 'failure', 'success', 'warning', 'primary', 'dark', 'light', 'blue', 'cyan', 'gray', 'green', 'indigo', 'lime', 'pink', 'purple', 'red', 'teal', 'yellow', ], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteIconConfig.color), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteIconConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteIconConfig.color, customTheme: defaultFlowbiteIconConfig.customTheme, }, render: (args) => ({ props: args, template: ` `, }), }; ================================================ FILE: apps/storybook/src/indicator.stories.ts ================================================ import { Button } from 'flowbite-angular/button'; import { Icon } from 'flowbite-angular/icon'; import { messages } from 'flowbite-angular/icon/outline/general'; import { defaultFlowbiteIndicatorConfig, Indicator } from 'flowbite-angular/indicator'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Indicator; export default { title: 'Component/Indicator', component: Indicator, decorators: [ moduleMetadata({ imports: [Button, Icon], providers: [provideIcons({ messages })], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteIndicatorConfig.color), }, }, }, size: { control: 'select', type: 'string', options: ['xs', 'sm', 'md', 'lg', 'xl'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteIndicatorConfig.size), }, }, }, border: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteIndicatorConfig.border), }, }, }, position: { control: 'select', type: 'string', options: [ 'bottom-left', 'bottom-right', 'bottom-center', 'top-left', 'top-center', 'top-right', 'center-left', 'center', 'center-right', undefined, ], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteIndicatorConfig.border), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteIndicatorConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteIndicatorConfig.color, size: defaultFlowbiteIndicatorConfig.size, border: defaultFlowbiteIndicatorConfig.border, customTheme: defaultFlowbiteIndicatorConfig.customTheme, }, render: (args) => ({ props: args, template: ``, }), }; export const LegendIndicatorStory: StoryObj = { name: 'Legend indicator', args: { color: defaultFlowbiteIndicatorConfig.color, size: defaultFlowbiteIndicatorConfig.size, border: defaultFlowbiteIndicatorConfig.border, position: defaultFlowbiteIndicatorConfig.position, customTheme: defaultFlowbiteIndicatorConfig.customTheme, }, render: (args) => ({ props: args, template: ` Visitors `, }), }; export const IndicatorCountStory: StoryObj = { name: 'IndicatorCount', args: { color: 'primary', size: 'lg', border: true, position: 'top-right', customTheme: defaultFlowbiteIndicatorConfig.customTheme, }, render: (args) => ({ props: args, template: ` `, }), }; ================================================ FILE: apps/storybook/src/modal.component.stories.ts ================================================ import { Button } from 'flowbite-angular/button'; import { FormControl, FormField, Helper, Label } from 'flowbite-angular/form'; import { defaultFlowbiteModalConfig, Modal, ModalContent, ModalFooter, ModalHeader, ModalOverlay, } from 'flowbite-angular/modal'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; import { NgpDialogTrigger } from 'ng-primitives/dialog'; type StoryType = Modal; export default { title: 'Component/Modal', component: Modal, decorators: [ moduleMetadata({ imports: [ ModalContent, ModalFooter, ModalHeader, ModalOverlay, Button, NgpDialogTrigger, FormControl, FormField, Label, Helper, Button, ], }), ], argTypes: { size: { control: 'select', type: 'string', options: ['sm', 'md', 'lg', 'xl'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteModalConfig.size), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteModalConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { size: defaultFlowbiteModalConfig.size, customTheme: defaultFlowbiteModalConfig.customTheme, }, render: (args) => ({ props: args, template: `

    Terms of Service

    With less than a month to go before the European Union enacts new consumer privacy laws for its citizens, companies around the world are updating their terms of service agreements to comply.

    The European Union’s General Data Protection Regulation (G.D.P.R.) goes into effect on May 25 and is meant to ensure a common set of data rights in the European Union. It requires organizations to notify users as soon as possible of high-risk data breaches that could personally affect them.

    `, }), }; export const FormModalStory: StoryObj = { name: 'Modal with Form', args: { size: defaultFlowbiteModalConfig.size, customTheme: defaultFlowbiteModalConfig.customTheme, }, render: (args) => ({ props: args, template: `

    Sign in to our platform

    We’ll never share your details. Read our Privacy Policy.

    `, }), }; ================================================ FILE: apps/storybook/src/navbar.component.stories.ts ================================================ import { Icon } from 'flowbite-angular/icon'; import { bars } from 'flowbite-angular/icon/outline/general'; import { defaultFlowbiteNavbarConfig, Navbar, NavbarBrand, NavbarContent, NavbarItem, NavbarToggle, } from 'flowbite-angular/navbar'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Navbar; export default { title: 'Component/Navbar', component: Navbar, decorators: [ moduleMetadata({ imports: [NavbarContent, NavbarItem, NavbarToggle, NavbarBrand, Icon], providers: [provideIcons({ bars })], }), ], argTypes: { fixed: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteNavbarConfig.fixed), }, }, }, open: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteNavbarConfig.open), }, }, }, color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteNavbarConfig.color), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteNavbarConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { fixed: defaultFlowbiteNavbarConfig.fixed, open: defaultFlowbiteNavbarConfig.open, color: defaultFlowbiteNavbarConfig.color, customTheme: defaultFlowbiteNavbarConfig.customTheme, }, render: (args) => ({ props: args, template: `
    @for (i of [0, 1]; track $index) {

    }
    `, }), }; ================================================ FILE: apps/storybook/src/pagination.component.stories.ts ================================================ import { bindTwoWay, hiddenOutputActions } from '../.storybook/helper'; import { defaultFlowbitePaginationConfig, Pagination } from 'flowbite-angular/pagination'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate } from '@storybook/angular'; type StoryType = Pagination & { page: number; pageCount: number; disabled: boolean; }; export default { title: 'Component/Pagination', component: Pagination, argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbitePaginationConfig.color), }, }, }, size: { control: 'select', type: 'string', options: ['xs', 'sm', 'md', 'lg', 'xl'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbitePaginationConfig.size), }, }, }, page: { control: 'number', type: 'number', table: { category: 'Input', defaultValue: { summary: JSON.stringify(1), }, }, }, pageCount: { control: 'number', type: 'number', table: { category: 'Input', defaultValue: { summary: JSON.stringify(10), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbitePaginationConfig.customTheme), }, }, }, ...hiddenOutputActions('pageChange'), }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { page: 1, pageCount: 10, color: defaultFlowbitePaginationConfig.color, size: defaultFlowbitePaginationConfig.size, customTheme: defaultFlowbitePaginationConfig.customTheme, }, render: (args, { id }) => ({ props: { ...args, pageChange: bindTwoWay(id, 'page'), }, template: ` `, }), }; ================================================ FILE: apps/storybook/src/sidebar.component.stories.ts ================================================ import { Icon } from 'flowbite-angular/icon'; import { barsFromLeft } from 'flowbite-angular/icon/outline/general'; import { cart } from 'flowbite-angular/icon/solid/e-commerce'; import { chartPie, drawSquare, inbox } from 'flowbite-angular/icon/solid/general'; import { users } from 'flowbite-angular/icon/solid/user'; import { defaultFlowbiteSidebarConfig, provideFlowbiteSidebarState, Sidebar, SidebarContent, SidebarItem, SidebarToggle, } from 'flowbite-angular/sidebar'; import { provideIcons } from '@ng-icons/core'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Sidebar; export default { title: 'Component/Sidebar', component: Sidebar, decorators: [ moduleMetadata({ providers: [ provideFlowbiteSidebarState(), provideIcons({ chartPie, inbox, users, cart, drawSquare, barsFromLeft }), ], imports: [SidebarContent, SidebarToggle, SidebarItem, Icon], }), ], argTypes: { open: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteSidebarConfig.open), }, }, }, color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteSidebarConfig.color), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteSidebarConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { open: defaultFlowbiteSidebarConfig.open, color: defaultFlowbiteSidebarConfig.color, customTheme: defaultFlowbiteSidebarConfig.customTheme, }, render: (args) => ({ props: args, template: `
    @for (i of [0, 1]; track $index) {

    }
    `, }), }; ================================================ FILE: apps/storybook/src/tab.component.stories.ts ================================================ import { defaultFlowbiteTabConfig, Tab, TabButton, TabContent, TabList, } from 'flowbite-angular/tab'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Tab; export default { title: 'Component/Tab', component: Tab, decorators: [ moduleMetadata({ imports: [TabButton, TabContent, TabList], }), ], argTypes: { size: { control: 'select', type: 'string', options: ['sm', 'md', 'lg', 'full'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTabConfig.size), }, }, }, color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTabConfig.color), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTabConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { size: defaultFlowbiteTabConfig.size, color: defaultFlowbiteTabConfig.color, customTheme: defaultFlowbiteTabConfig.customTheme, }, render: (args) => ({ props: args, template: `
    • Profile
    • Dashboard
    • Settings
    • Contacts
    • Disabled

    Nulla cursus urna id felis egestas, ac rhoncus felis egestas. Curabitur placerat at quam vitae volutpat. Nunc at nunc nec ex dapibus sollicitudin nec eget risus. Curabitur id sagittis nisi, sit amet mollis quam. In hac habitasse platea dictumst. Praesent in augue vitae elit egestas euismod. Aliquam in tempus enim, et elementum lacus. Nullam commodo nulla sollicitudin euismod malesuada. Donec sed massa dui. Sed felis ipsum, malesuada eu urna scelerisque, accumsan pharetra odio. Nullam arcu augue, consequat vel faucibus at, dictum non erat. Morbi metus nisl, scelerisque non accumsan quis, fringilla vitae ipsum. Vestibulum fermentum lorem sit amet augue ultrices, eu pretium ex imperdiet.

    Curabitur nibh nisl, tincidunt id purus sed, consectetur vehicula sapien. Cras at malesuada felis, eget imperdiet enim. Maecenas commodo vestibulum turpis non ultrices. Donec ut aliquam ex, id molestie dui. Nullam porttitor ligula vel malesuada ullamcorper. Vivamus aliquam consectetur urna, tempus vehicula est consectetur vitae. Integer vitae commodo quam, eget cursus velit. Nam eget leo diam.

    Vivamus sed lacinia mauris. Integer vehicula lorem nec interdum rutrum. Curabitur auctor mollis faucibus. Nulla sit amet semper tortor. Vestibulum at tempus nulla, nec interdum orci. Integer sodales quam sit amet cursus interdum. Fusce consequat ultrices magna a iaculis.

    Sed eget pellentesque tellus. Praesent rutrum placerat lacus vitae elementum. Nulla ac orci ac enim dignissim finibus. Duis venenatis rhoncus eros. Etiam euismod tortor in vehicula lacinia. Morbi tempor mollis lacus, nec fringilla mauris vestibulum nec. Donec sapien lacus, semper a commodo eu, ullamcorper et turpis.
    Disabled content.
    `, }), }; ================================================ FILE: apps/storybook/src/table.component.stories.ts ================================================ import { defaultFlowbiteTableConfig, Table, TableBody, TableFoot, TableHead, } from 'flowbite-angular/table'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; type StoryType = Table; export default { title: 'Component/Table', component: Table, decorators: [ moduleMetadata({ imports: [TableHead, TableBody, TableFoot], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTableConfig.color), }, }, }, striped: { control: 'boolean', type: 'boolean', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTableConfig.striped), }, }, }, data: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify([]), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTableConfig.customTheme), }, }, }, }, } as Meta; export const Default: StoryObj = { name: 'Default', args: { color: defaultFlowbiteTableConfig.color, striped: defaultFlowbiteTableConfig.striped, data: Array.from({ length: 5 }, (_, i) => i++).map((x) => ({ name: `Product ${x}`, qty: x, price: x * x, })), customTheme: defaultFlowbiteTableConfig.customTheme, }, render: (args) => ({ props: args, template: `
    Product name Qty Price
    {{ data.name }} {{ data.qty }} {{ data.price }}
    Total 10 30
    `, }), }; ================================================ FILE: apps/storybook/src/tooltip.component.stories.ts ================================================ import { Button } from 'flowbite-angular/button'; import { defaultFlowbiteTooltipConfig, Tooltip } from 'flowbite-angular/tooltip'; import type { Meta, StoryObj } from '@storybook/angular'; import { argsToTemplate, moduleMetadata } from '@storybook/angular'; import { NgpTooltipTrigger } from 'ng-primitives/tooltip'; type StoryType = Tooltip; export default { title: 'Component/Tooltip', component: Tooltip, decorators: [ moduleMetadata({ imports: [NgpTooltipTrigger, Button], }), ], argTypes: { color: { control: 'select', type: 'string', options: ['default', 'info', 'failure', 'success', 'warning', 'primary'], table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTooltipConfig.color), }, }, }, customTheme: { control: 'object', type: 'symbol', table: { category: 'Input', defaultValue: { summary: JSON.stringify(defaultFlowbiteTooltipConfig.customTheme), }, }, }, }, } as Meta; export const DefaultStory: StoryObj = { name: 'Default', args: { color: defaultFlowbiteTooltipConfig.color, customTheme: defaultFlowbiteTooltipConfig.customTheme, }, render: (args) => ({ props: args, template: `
    Tooltip content
    `, }), }; ================================================ FILE: apps/storybook/styles.css ================================================ @import 'tailwindcss'; @source "../../../../libs/flowbite-angular"; @custom-variant dark (&:where([data-mode='dark'] &, .dark &)); @font-face { font-family: roboto; src: url('./public/fonts/roboto.ttf') format('truetype'); } @theme { --default-font-family: 'roboto'; } @theme { /* Colors */ /* Primary */ --color-primary-50: #fff0f1; --color-primary-100: #ffe1e4; --color-primary-200: #ffc8cf; --color-primary-300: #ff9ba8; --color-primary-400: #ff637b; --color-primary-500: #ff2c51; --color-primary-600: #f6083b; --color-primary-700: #c3002f; --color-primary-800: #ae0331; --color-primary-900: #940732; --color-primary-950: #5b041e; } ================================================ FILE: apps/storybook/tsconfig.editor.json ================================================ { "extends": "./tsconfig.json", "include": ["src/**/*.ts"], "compilerOptions": {}, "exclude": ["**/*.stories.ts", "**/*.stories.js"] } ================================================ FILE: apps/storybook/tsconfig.json ================================================ { "compilerOptions": { "target": "es2022", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true }, "files": [], "include": [], "references": [ { "path": "./tsconfig.editor.json" }, { "path": "./.storybook/tsconfig.json" } ], "extends": "../../tsconfig.base.json", "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: commitlint.config.cjs ================================================ module.exports = { extends: ['@commitlint/config-conventional'] }; ================================================ FILE: libs/.gitkeep ================================================ ================================================ FILE: libs/flowbite-angular/.eslintrc.json ================================================ { "extends": ["../../.eslintrc.json"], "ignorePatterns": ["!**/*", "storybook-static"], "overrides": [ { "files": ["*.ts"], "extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], "rules": { "@angular-eslint/directive-selector": [ "error", { "type": "attribute", "prefix": "flowbite", "style": "camelCase" } ], "@angular-eslint/directive-class-suffix": "off", "@angular-eslint/component-class-suffix": "off" } }, { "files": ["*.html"], "extends": ["plugin:@nx/angular-template"], "rules": {} } ] } ================================================ FILE: libs/flowbite-angular/LICENSE ================================================ MIT License Copyright (c) 2022 Themesberg Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: libs/flowbite-angular/README.md ================================================

    flowbite-angular

    Build websites even faster with components on top of Angular and Tailwind CSS

    Discord Total Downloads Latest release License

    --- **`flowbite-angular` is an open source collection of UI components, built in Angular, with utility classes from Tailwind CSS that you can use as a starting point for user interfaces and websites.** ## Table of Contents - [Documentation](#documentation) - [Getting started](#getting-started) - [Components](#components) - [Community](#community) - [Contributing](#contributing) - [Figma](#figma) - [Copyright and license](#copyright-and-license) ## Documentation If you want to browse the components, visit [flowbite-angular.com](https://flowbite-angular.com/). If you want to learn more about Flowbite, visit [Flowbite docs](https://flowbite.com/docs/getting-started/introduction/). ## Getting started ## Require via `npm` Make sure that you have Node.js installed. 1. Install `tailwindcss` as a dependency using `npm` by running the following command: ```bash npm i tailwindcss ``` 2. Install `flowbite-angular` as a dependency using `npm` by running the following command: ```bash npm i flowbite-angular ng-primitives @ng-icons/core ``` 3. Import `flowbite-angular` inside your `style.css` file: ```css @import 'tailwindcss'; @source "node_modules/flowbite-angular"; ``` # Components
    Alerts Badges Breadcrumbs
    Tailwind CSS Alerts Tailwind CSS Badge Tailwind CSS Breadcrumbs
    Buttons Button group Cards
    Tailwind CSS Buttons Tailwind CSS Button Group Tailwind CSS Cards
    Dropdown :construction: Forms :construction: List group
    Tailwind CSS Dropdown Tailwind CSS Forms Tailwind CSS List group
    :construction: Typography Modal Tabs
    Tailwind CSS Typography Tailwind CSS Modal Tailwind CSS Tabs
    Navbar Pagination :construction: Timeline
    Tailwind CSS Navbar Tailwind CSS Pagination Tailwind CSS Timeline
    :construction: Progress bar :construction: Tables :construction: Toast
    Tailwind CSS Progress Bar Tailwind CSS Tables Tailwind CSS Toast
    Tooltips :construction: Datepicker :construction: Spinner
    Tailwind CSS Tooltips Tailwind CSS Datepicker Tailwind CSS Spinner
    :construction: Footer Accordion Sidebar
    Tailwind CSS Footer Tailwind CSS Accordion Tailwind CSS Sidebar
    :construction: Carousel :construction: Avatar :construction: Rating
    Tailwind CSS Carousel Tailwind CSS Avatar Tailwind CSS Rating
    Input Field :construction: File Input :construction: Search Input
    Tailwind CSS Input Field Tailwind CSS File Input Tailwind CSS Search Input
    :construction: Select :construction: Textarea :construction: Checkbox
    Tailwind CSS Select Tailwind CSS Textarea Tailwind CSS Checkbox
    :construction: Radio :construction: Toggle :construction: Range Slider
    Tailwind CSS Radio Tailwind CSS Toggle Tailwind CSS Range Slider
    Floating Label
    Tailwind CSS Floating Label
    ## Community If you need help or just want to discuss the library join the community on GitHub: ⌨️ [Discuss Flowbite on GitHub](https://github.com/themesberg/flowbite/discussions) For casual chatting with others using the library: 💬 [Join the Flowbite Discord Server](https://discord.gg/4eeurUVvTy) ## Contributing Thank you for your interest in helping! Visit our [guide on contributing](https://github.com/themesberg/flowbite-angular/blob/main/.github/CONTRIBUTING) to get started. ## Figma If you need the Figma files for the components you can check out our website for more information: 🎨 [Get access to the Figma design files](https://flowbite.com/figma/) ## Copyright and license The Flowbite name and logos are trademarks of Crafty Dwarf Inc. 📝 [Read about the licensing terms](https://flowbite-angular.com/docs/getting-started/license) ================================================ FILE: libs/flowbite-angular/accordion/ng-package.json ================================================ { "lib": { "entryFile": "./src/index.ts" } } ================================================ FILE: libs/flowbite-angular/accordion/src/accordion/accordion-state.ts ================================================ import type { Accordion } from './accordion.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteAccordionStateToken = createStateToken('Flowbite Accordion'); export const provideFlowbiteAccordionState = createStateProvider(FlowbiteAccordionStateToken); export const injectFlowbiteAccordionState = createStateInjector(FlowbiteAccordionStateToken); export const flowbiteAccordionState = createState(FlowbiteAccordionStateToken); ================================================ FILE: libs/flowbite-angular/accordion/src/accordion/accordion.directive.ts ================================================ import { injectFlowbiteAccordionConfig } from '../config/accordion-config'; import { flowbiteAccordionState, provideFlowbiteAccordionState } from './accordion-state'; import { mergeDeep } from 'flowbite-angular'; import { booleanAttribute, computed, Directive, input } from '@angular/core'; import { NgpAccordion, provideAccordionState } from 'ng-primitives/accordion'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` div[flowbiteAccordion] `, exportAs: 'flowbiteAccordion', hostDirectives: [ { directive: NgpAccordion, inputs: [ 'ngpAccordionType:type', 'ngpAccordionDisabled:disabled', 'ngpAccordionCollapsible:collapsible', ], }, ], providers: [provideFlowbiteAccordionState(), provideAccordionState()], host: { '[class]': `theme().host.root` }, }) export class Accordion { readonly config = injectFlowbiteAccordionConfig(); /** * @see {@link injectFlowbiteAccordionConfig} */ readonly color = input(this.config.color); /** * @see {@link injectFlowbiteAccordionConfig} */ readonly flush = input(this.config.flush, { transform: booleanAttribute }); /** * @see {@link injectFlowbiteAccordionConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge(mergedTheme.host.base, mergedTheme.host.transition), }, }; }); /** * @internal */ readonly state = flowbiteAccordionState(this); } ================================================ FILE: libs/flowbite-angular/accordion/src/accordion/theme.ts ================================================ import type { ColorToTheme } from 'flowbite-angular'; import { createTheme, type FlowbiteColors } from 'flowbite-angular'; export interface FlowbiteAccordionColors extends Pick { [key: string]: ColorToTheme; } export interface FlowbiteAccordionTheme { host: FlowbiteAccordionHostTheme; } export interface FlowbiteAccordionHostTheme { base: string; transition: string; } export const flowbiteAccordionTheme: FlowbiteAccordionTheme = createTheme({ host: { base: 'shadow-sm', transition: '', }, }); ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-content/accordion-content-state.ts ================================================ import type { AccordionContent } from './accordion-content.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteAccordionContentStateToken = createStateToken( 'Flowbite AccordionContent' ); export const provideFlowbiteAccordionContentState = createStateProvider( FlowbiteAccordionContentStateToken ); export const injectFlowbiteAccordionContentState = createStateInjector( FlowbiteAccordionContentStateToken ); export const flowbiteAccordionContentState = createState(FlowbiteAccordionContentStateToken); ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-content/accordion-content.directive.ts ================================================ import { injectFlowbiteAccordionState } from '../accordion/accordion-state'; import { injectFlowbiteAccordionContentConfig } from '../config/accordion-content-config'; import { flowbiteAccordionContentState, provideFlowbiteAccordionContentState, } from './accordion-content-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { injectAccordionItemState, NgpAccordionContent } from 'ng-primitives/accordion'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` div[flowbiteAccordionContent] `, exportAs: 'flowbiteAccordionContent', hostDirectives: [ { directive: NgpAccordionContent, inputs: ['id'], outputs: [], }, ], providers: [provideFlowbiteAccordionContentState()], host: { '[class]': `theme().host.root` }, }) export class AccordionContent { readonly config = injectFlowbiteAccordionContentConfig(); readonly accordionState = injectFlowbiteAccordionState(); readonly ngpAccordionItemState = injectAccordionItemState(); /** * @see {@link injectFlowbiteAccordionContentConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.accordionState().color()), mergedTheme.host.flush[this.accordionState().flush() ? 'on' : 'off'], mergedTheme.host.open[this.ngpAccordionItemState().open() ? 'on' : 'off'] ), }, }; }); /** * @internal */ readonly state = flowbiteAccordionContentState(this); } ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-content/theme.ts ================================================ import type { FlowbiteAccordionColors } from '../accordion/theme'; import type { FlowbiteBoolean } from 'flowbite-angular'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteAccordionContentTheme { host: FlowbiteAccordionContentHostTheme; } export interface FlowbiteAccordionContentHostTheme { base: string; transition: string; color: FlowbiteAccordionColors; flush: FlowbiteBoolean; open: FlowbiteBoolean; } export const flowbiteAccordionContentTheme: FlowbiteAccordionContentTheme = createTheme({ host: { base: 'overflow-hidden', transition: '', color: { default: { light: 'border-gray-200 bg-white', dark: 'dark:border-gray-700 dark:bg-gray-900', }, info: { light: 'border-blue-200 bg-white', dark: 'dark:border-blue-700 dark:bg-gray-900', }, failure: { light: 'border-red-200 bg-white', dark: 'dark:border-red-700 dark:bg-gray-900', }, success: { light: 'border-green-200 bg-white', dark: 'dark:border-green-700 dark:bg-gray-900', }, warning: { light: 'border-yellow-200 bg-white', dark: 'dark:border-yellow-700 dark:bg-gray-900', }, primary: { light: 'border-primary-200 bg-white', dark: 'dark:border-primary-700 dark:bg-gray-900', }, }, open: { on: 'h-fit', off: 'h-0', }, flush: { on: 'bg-transparent dark:bg-transparent', off: 'border-x group-last/item:border-b', }, }, }); ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-item/accordion-item-state.ts ================================================ import type { AccordionItem } from './accordion-item.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteAccordionItemStateToken = createStateToken('Flowbite Accordion Item'); export const provideFlowbiteAccordionItemState = createStateProvider( FlowbiteAccordionItemStateToken ); export const injectFlowbiteAccordionItemState = createStateInjector( FlowbiteAccordionItemStateToken ); export const flowbiteAccordionItemState = createState(FlowbiteAccordionItemStateToken); ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-item/accordion-item.directive.ts ================================================ import { injectFlowbiteAccordionState } from '../accordion/accordion-state'; import { injectFlowbiteAccordionItemConfig } from '../config/accordion-item-config'; import { flowbiteAccordionItemState, provideFlowbiteAccordionItemState, } from './accordion-item-state'; import { mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { injectAccordionItemState, NgpAccordionItem, provideAccordionItemState, } from 'ng-primitives/accordion'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` div[flowbiteAccordionItem] `, exportAs: 'flowbiteAccordionItem', hostDirectives: [ { directive: NgpAccordionItem, inputs: ['ngpAccordionItemValue:value', 'ngpAccordionItemDisabled:disabled'], }, ], providers: [provideFlowbiteAccordionItemState(), provideAccordionItemState()], host: { '[class]': `theme().host.root` }, }) export class AccordionItem { readonly config = injectFlowbiteAccordionItemConfig(); readonly accordionState = injectFlowbiteAccordionState(); readonly ngpAccordionItemState = injectAccordionItemState(); /** * @see {@link injectFlowbiteAccordionItemConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge(mergedTheme.host.base, mergedTheme.host.transition), }, }; }); /** * @internal */ readonly state = flowbiteAccordionItemState(this); } ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-item/theme.ts ================================================ import { createTheme } from 'flowbite-angular'; export interface FlowbiteAccordionItemTheme { host: FlowbiteAccordionItemHostTheme; } export interface FlowbiteAccordionItemHostTheme { base: string; transition: string; } export const flowbiteAccordionItemTheme: FlowbiteAccordionItemTheme = createTheme({ host: { base: 'group/item', transition: '', }, }); ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-title/accordion-title-state.ts ================================================ import type { AccordionTitle } from './accordion-title.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteAccordionTitleStateToken = createStateToken('Flowbite AccordionTitle'); export const provideFlowbiteAccordionTitleState = createStateProvider( FlowbiteAccordionTitleStateToken ); export const injectFlowbiteAccordionTitleState = createStateInjector( FlowbiteAccordionTitleStateToken ); export const flowbiteAccordionTitleState = createState(FlowbiteAccordionTitleStateToken); ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-title/accordion-title.directive.ts ================================================ import { injectFlowbiteAccordionState } from '../accordion/accordion-state'; import { injectFlowbiteAccordionTitleConfig } from '../config/accordion-title-config'; import { flowbiteAccordionTitleState, provideFlowbiteAccordionTitleState, } from './accordion-title-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpAccordionTrigger } from 'ng-primitives/accordion'; import { NgpButton } from 'ng-primitives/button'; import { NgpFocus } from 'ng-primitives/interactions'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` [flowbiteAccordionTitle] `, exportAs: 'flowbiteAccordionTitle', hostDirectives: [ { directive: NgpButton, inputs: ['disabled:disabled'], outputs: [], }, { directive: NgpFocus, inputs: [], outputs: [], }, { directive: NgpAccordionTrigger, inputs: ['id'], outputs: [], }, ], providers: [provideFlowbiteAccordionTitleState()], host: { '[class]': `theme().host.root` }, }) export class AccordionTitle { readonly config = injectFlowbiteAccordionTitleConfig(); readonly accordionState = injectFlowbiteAccordionState(); /** * @see {@link injectFlowbiteAccordionTitleConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.accordionState().color()), mergedTheme.host.flush[this.accordionState().flush() ? 'on' : 'off'] ), }, }; }); /** * @internal */ readonly state = flowbiteAccordionTitleState(this); } ================================================ FILE: libs/flowbite-angular/accordion/src/accordion-title/theme.ts ================================================ import type { FlowbiteAccordionColors } from '../accordion/theme'; import type { FlowbiteBoolean } from 'flowbite-angular'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteAccordionTitleTheme { host: FlowbiteAccordionTitleHostTheme; } export interface FlowbiteAccordionTitleHostTheme { base: string; transition: string; color: FlowbiteAccordionColors; flush: FlowbiteBoolean; } export const flowbiteAccordionTitleTheme: FlowbiteAccordionTitleTheme = createTheme({ host: { base: 'flex w-full cursor-pointer flex-row items-center justify-between p-5 text-base font-medium group-first/item:rounded-t-lg', transition: '', color: { default: { light: 'border-gray-200 bg-gray-100 text-gray-900 data-hover:bg-gray-200', dark: 'dark:border-gray-700 dark:bg-gray-800 dark:text-white dark:data-hover:bg-gray-700', }, info: { light: 'border-blue-200 bg-blue-100 text-blue-900 data-hover:bg-blue-200', dark: 'dark:border-blue-700 dark:bg-blue-800 dark:text-white dark:data-hover:bg-blue-700', }, failure: { light: 'border-red-200 bg-red-100 text-red-900 data-hover:bg-red-200', dark: 'dark:border-red-700 dark:bg-red-800 dark:text-white dark:data-hover:bg-red-700', }, success: { light: 'border-green-200 bg-green-100 text-green-900 data-hover:bg-green-200', dark: 'dark:border-green-700 dark:bg-green-800 dark:text-white dark:data-hover:bg-green-700', }, warning: { light: 'border-yellow-200 bg-yellow-100 text-yellow-900 data-hover:bg-yellow-200', dark: 'dark:border-yellow-700 dark:bg-yellow-800 dark:text-white dark:data-hover:bg-yellow-700', }, primary: { light: 'border-primary-200 bg-primary-100 text-primary-900 data-hover:bg-primary-200', dark: 'dark:border-primary-700 dark:bg-primary-800 dark:data-hover:bg-primary-700 dark:text-white', }, }, flush: { on: 'border-b bg-transparent data-hover:bg-transparent dark:bg-transparent dark:data-hover:bg-transparent', off: 'border', }, }, }); ================================================ FILE: libs/flowbite-angular/accordion/src/config/accordion-config.ts ================================================ import type { FlowbiteAccordionColors, FlowbiteAccordionTheme } from '../accordion/theme'; import { flowbiteAccordionTheme } from '../accordion/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteAccordionConfig { /** * The default theme of accordion. */ baseTheme: FlowbiteAccordionTheme; /** * The default color of accordion. */ color: keyof FlowbiteAccordionColors; /** * Whether the accordion is flush. */ flush: boolean; /** * The custom theme of button. */ customTheme: DeepPartial; } export const defaultFlowbiteAccordionConfig: FlowbiteAccordionConfig = { baseTheme: flowbiteAccordionTheme, color: 'default', flush: false, customTheme: {}, }; export const FlowbiteAccordionConfigToken = new InjectionToken( 'FlowbiteAccordionConfig' ); /** * Provide the default Accordion configuration * @param config The Accordion configuration * @returns The provider */ export const provideFlowbiteAccordionConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteAccordionConfigToken, useValue: { ...defaultFlowbiteAccordionConfig, ...config }, }, ]; /** * Inject the Accordion configuration * @see {@link defaultFlowbiteAccordionConfig} * @returns The configuration */ export const injectFlowbiteAccordionConfig = (): FlowbiteAccordionConfig => inject(FlowbiteAccordionConfigToken, { optional: true }) ?? defaultFlowbiteAccordionConfig; ================================================ FILE: libs/flowbite-angular/accordion/src/config/accordion-content-config.ts ================================================ import { flowbiteAccordionContentTheme, type FlowbiteAccordionContentTheme, } from '../accordion-content/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteAccordionContentConfig { /** * The default theme of AccordionContent */ baseTheme: FlowbiteAccordionContentTheme; /** * The custom theme of AccordionContent */ customTheme: DeepPartial; } export const defaultFlowbiteAccordionContentConfig: FlowbiteAccordionContentConfig = { baseTheme: flowbiteAccordionContentTheme, customTheme: {}, }; export const FlowbiteAccordionContentConfigToken = new InjectionToken('FlowbiteAccordionContentConfigToken'); /** * Provide the default AccordionContent configuration * @param config The AccordionContent configuration * @returns The provider */ export const provideFlowbiteAccordionContentConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteAccordionContentConfigToken, useValue: { ...defaultFlowbiteAccordionContentConfig, ...config }, }, ]; /** * Inject the AccordionContent configuration * @see {@link defaultFlowbiteAccordionContentConfig} * @returns The configuration */ export const injectFlowbiteAccordionContentConfig = (): FlowbiteAccordionContentConfig => inject(FlowbiteAccordionContentConfigToken, { optional: true }) ?? defaultFlowbiteAccordionContentConfig; ================================================ FILE: libs/flowbite-angular/accordion/src/config/accordion-item-config.ts ================================================ import { flowbiteAccordionItemTheme, type FlowbiteAccordionItemTheme, } from '../accordion-item/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteAccordionItemConfig { /** * The default theme of accordion item. */ baseTheme: FlowbiteAccordionItemTheme; /** * The custom theme of accordion item. */ customTheme: DeepPartial; } export const defaultFlowbiteAccordionItemConfig: FlowbiteAccordionItemConfig = { baseTheme: flowbiteAccordionItemTheme, customTheme: {}, }; export const FlowbiteAccordionItemConfigToken = new InjectionToken( 'FlowbiteAccordionItemConfig' ); /** * Provide the default Accordion Item configuration * @param config The Accordion Item configuration * @returns The provider */ export const provideFlowbiteAccordionItemConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteAccordionItemConfigToken, useValue: { ...defaultFlowbiteAccordionItemConfig, ...config }, }, ]; /** * Inject the Accordion Item configuration * @see {@link defaultFlowbiteAccordionItemConfig} * @returns The configuration */ export const injectFlowbiteAccordionItemConfig = (): FlowbiteAccordionItemConfig => inject(FlowbiteAccordionItemConfigToken, { optional: true }) ?? defaultFlowbiteAccordionItemConfig; ================================================ FILE: libs/flowbite-angular/accordion/src/config/accordion-title-config.ts ================================================ import { flowbiteAccordionTitleTheme, type FlowbiteAccordionTitleTheme, } from '../accordion-title/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteAccordionTitleConfig { /** * The default theme of AccordionTitle */ baseTheme: FlowbiteAccordionTitleTheme; /** * The custom theme of AccordionTitle */ customTheme: DeepPartial; } export const defaultFlowbiteAccordionTitleConfig: FlowbiteAccordionTitleConfig = { baseTheme: flowbiteAccordionTitleTheme, customTheme: {}, }; export const FlowbiteAccordionTitleConfigToken = new InjectionToken( 'FlowbiteAccordionTitleConfigToken' ); /** * Provide the default AccordionTitle configuration * @param config The AccordionTitle configuration * @returns The provider */ export const provideFlowbiteAccordionTitleConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteAccordionTitleConfigToken, useValue: { ...defaultFlowbiteAccordionTitleConfig, ...config }, }, ]; /** * Inject the AccordionTitle configuration * @see {@link defaultFlowbiteAccordionTitleConfig} * @returns The configuration */ export const injectFlowbiteAccordionTitleConfig = (): FlowbiteAccordionTitleConfig => inject(FlowbiteAccordionTitleConfigToken, { optional: true }) ?? defaultFlowbiteAccordionTitleConfig; ================================================ FILE: libs/flowbite-angular/accordion/src/index.ts ================================================ /* Accordion */ export * from './accordion/accordion.directive'; export * from './accordion/accordion-state'; export * from './accordion/theme'; /* AccordionItem */ export * from './accordion-item/accordion-item.directive'; export * from './accordion-item/accordion-item-state'; export * from './accordion-item/theme'; /* Config */ export * from './config/accordion-item-config'; export * from './config/accordion-config'; /* AccordionTitle */ export * from './accordion-title/accordion-title.directive'; export * from './accordion-title/accordion-title-state'; export * from './accordion-title/theme'; /* Config */ export * from './config/accordion-title-config'; /* AccordionContent */ export * from './accordion-content/accordion-content.directive'; export * from './accordion-content/accordion-content-state'; export * from './accordion-content/theme'; /* Config */ export * from './config/accordion-content-config'; ================================================ FILE: libs/flowbite-angular/alert/ng-package.json ================================================ { "lib": { "entryFile": "./src/index.ts" } } ================================================ FILE: libs/flowbite-angular/alert/src/alert/alert-state.ts ================================================ import type { Alert } from './alert.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteAlertStateToken = createStateToken('Flowbite Alert'); export const provideFlowbiteAlertState = createStateProvider(FlowbiteAlertStateToken); export const injectFlowbiteAlertState = createStateInjector(FlowbiteAlertStateToken); export const flowbiteAlertState = createState(FlowbiteAlertStateToken); ================================================ FILE: libs/flowbite-angular/alert/src/alert/alert.directive.ts ================================================ import { injectFlowbiteAlertConfig } from '../config/alert-config'; import { flowbiteAlertState, provideFlowbiteAlertState } from './alert-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { booleanAttribute, computed, Directive, input } from '@angular/core'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` div[flowbiteAlert] `, exportAs: 'flowbiteAlert', hostDirectives: [], providers: [provideFlowbiteAlertState()], host: { '[class]': `theme().host.root`, }, }) export class Alert { readonly config = injectFlowbiteAlertConfig(); /** * @see {@link injectFlowbiteAlertConfig} */ readonly color = input(this.config.color); /** * @see {@link injectFlowbiteAlertConfig} */ readonly border = input(this.config.border, { transform: booleanAttribute }); /** * @see {@link injectFlowbiteAlertConfig} */ readonly accent = input(this.config.accent, { transform: booleanAttribute }); /** * @see {@link injectFlowbiteAlertConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.state.color()), mergedTheme.host.border[this.state.border() ? 'on' : 'off'], mergedTheme.host.accent[this.state.accent() ? 'on' : 'off'] ), }, }; }); /** * @internal */ readonly state = flowbiteAlertState(this); } ================================================ FILE: libs/flowbite-angular/alert/src/alert/theme.ts ================================================ import type { ColorToTheme, FlowbiteBoolean, FlowbiteColors } from 'flowbite-angular'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteAlertColors extends Pick { [key: string]: ColorToTheme; } export interface FlowbiteAlertTheme { host: FlowbiteAlertHostTheme; } export interface FlowbiteAlertHostTheme { base: string; transition: string; color: FlowbiteAlertColors; border: FlowbiteBoolean; accent: FlowbiteBoolean; } export const flowbiteAlertTheme: FlowbiteAlertTheme = createTheme({ host: { base: 'mb-4 rounded-lg p-4', transition: '', color: { default: { light: 'border-gray-200 bg-gray-50', dark: 'dark:border-gray-700 dark:bg-gray-950', }, info: { light: 'border-blue-200 bg-blue-50', dark: 'dark:border-blue-700 dark:bg-blue-950', }, failure: { light: 'border-red-200 bg-red-50', dark: 'dark:border-red-700 dark:bg-red-950', }, success: { light: 'border-green-200 bg-green-50', dark: 'dark:border-green-700 dark:bg-green-950', }, warning: { light: 'border-yellow-200 bg-yellow-50', dark: 'dark:border-yellow-700 dark:bg-yellow-950', }, primary: { light: 'bg-primary-50 border-primary-200', dark: 'dark:bg-primary-950 dark:border-primary-700', }, }, border: { on: 'border', off: 'border-0', }, accent: { on: 'border-t-4', off: '', }, }, }); ================================================ FILE: libs/flowbite-angular/alert/src/alert-button/alert-button-state.ts ================================================ import type { AlertButton } from './alert-button.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteAlertButtonStateToken = createStateToken('Flowbite AlertButton'); export const provideFlowbiteAlertButtonState = createStateProvider(FlowbiteAlertButtonStateToken); export const injectFlowbiteAlertButtonState = createStateInjector(FlowbiteAlertButtonStateToken); export const flowbiteAlertButtonState = createState(FlowbiteAlertButtonStateToken); ================================================ FILE: libs/flowbite-angular/alert/src/alert-button/alert-button.directive.ts ================================================ import { injectFlowbiteAlertState } from '../alert/alert-state'; import { injectFlowbiteAlertButtonConfig } from '../config/alert-button-config'; import { flowbiteAlertButtonState, provideFlowbiteAlertButtonState } from './alert-button-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpButton } from 'ng-primitives/button'; import { NgpFocus } from 'ng-primitives/interactions'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` button[flowbiteAlertButton], a[flowbiteAlertButton] `, exportAs: 'flowbiteAlertButton', hostDirectives: [ { directive: NgpButton, inputs: ['disabled:disabled'], outputs: [], }, { directive: NgpFocus, inputs: [], outputs: [], }, ], providers: [provideFlowbiteAlertButtonState()], host: { '[class]': `theme().host.root` }, }) export class AlertButton { readonly config = injectFlowbiteAlertButtonConfig(); readonly alertState = injectFlowbiteAlertState(); /** * @see {@link injectFlowbiteAlertButtonConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.alertState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteAlertButtonState(this); } ================================================ FILE: libs/flowbite-angular/alert/src/alert-button/theme.ts ================================================ import type { FlowbiteAlertColors } from '../alert/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteAlertButtonTheme { host: FlowbiteAlertButtonHostTheme; } export interface FlowbiteAlertButtonHostTheme { base: string; transition: string; color: FlowbiteAlertColors; } export const flowbiteAlertButtonTheme: FlowbiteAlertButtonTheme = createTheme({ host: { base: 'flex rounded-lg p-1 first:mr-2 data-hover:cursor-pointer', transition: '', color: { default: { light: 'data-hover:bg-gray-300', dark: 'dark:data-hover:bg-gray-600', }, info: { light: 'data-hover:bg-blue-300', dark: 'dark:data-hover:bg-blue-700', }, failure: { light: 'data-hover:bg-red-300', dark: 'dark:data-hover:bg-red-700', }, success: { light: 'data-hover:bg-green-300', dark: 'dark:data-hover:bg-green-600', }, warning: { light: 'data-hover:bg-yellow-300', dark: 'dark:data-hover:bg-yellow-600', }, primary: { light: 'data-hover:bg-primary-300', dark: 'dark:data-hover:bg-primary-700', }, }, }, }); ================================================ FILE: libs/flowbite-angular/alert/src/alert-content/alert-content-state.ts ================================================ import type { AlertContent } from './alert-content.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteAlertContentStateToken = createStateToken('Flowbite AlertContent'); export const provideFlowbiteAlertContentState = createStateProvider(FlowbiteAlertContentStateToken); export const injectFlowbiteAlertContentState = createStateInjector(FlowbiteAlertContentStateToken); export const flowbiteAlertContentState = createState(FlowbiteAlertContentStateToken); ================================================ FILE: libs/flowbite-angular/alert/src/alert-content/alert-content.directive.ts ================================================ import { injectFlowbiteAlertState } from '../alert/alert-state'; import { injectFlowbiteAlertContentConfig } from '../config/alert-content-config'; import { flowbiteAlertContentState, provideFlowbiteAlertContentState } from './alert-content-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` div[flowbiteAlertContent] `, exportAs: 'flowbiteAlertContent', hostDirectives: [], providers: [provideFlowbiteAlertContentState()], host: { '[class]': `theme().host.root` }, }) export class AlertContent { readonly config = injectFlowbiteAlertContentConfig(); readonly alertState = injectFlowbiteAlertState(); /** * @see {@link injectFlowbiteAlertContentConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.alertState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteAlertContentState(this); } ================================================ FILE: libs/flowbite-angular/alert/src/alert-content/theme.ts ================================================ import type { FlowbiteAlertColors } from '../alert/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteAlertContentTheme { host: FlowbiteAlertContentHostTheme; } export interface FlowbiteAlertContentHostTheme { base: string; transition: string; color: FlowbiteAlertColors; } export const flowbiteAlertContentTheme: FlowbiteAlertContentTheme = createTheme({ host: { base: 'flex items-center justify-between text-sm font-normal', transition: '', color: { default: { light: 'text-gray-800', dark: 'dark:text-gray-300', }, info: { light: 'text-blue-800', dark: 'dark:text-blue-300', }, failure: { light: 'text-red-800', dark: 'dark:text-red-300', }, success: { light: 'text-green-800', dark: 'dark:text-green-300', }, warning: { light: 'text-yellow-800', dark: 'dark:text-yellow-300', }, primary: { light: 'text-primary-800', dark: 'dark:text-primary-300', }, }, }, }); ================================================ FILE: libs/flowbite-angular/alert/src/config/alert-button-config.ts ================================================ import { flowbiteAlertButtonTheme, type FlowbiteAlertButtonTheme } from '../alert-button/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteAlertButtonConfig { /** * The default theme of AlertButton */ baseTheme: FlowbiteAlertButtonTheme; /** * The custom theme of AlertButton */ customTheme: DeepPartial; } export const defaultFlowbiteAlertButtonConfig: FlowbiteAlertButtonConfig = { baseTheme: flowbiteAlertButtonTheme, customTheme: {}, }; export const FlowbiteAlertButtonConfigToken = new InjectionToken( 'FlowbiteAlertButtonConfigToken' ); /** * Provide the default AlertButton configuration * @param config The AlertButton configuration * @returns The provider */ export const provideFlowbiteAlertButtonConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteAlertButtonConfigToken, useValue: { ...defaultFlowbiteAlertButtonConfig, ...config }, }, ]; /** * Inject the AlertButton configuration * @see {@link defaultFlowbiteAlertButtonConfig} * @returns The configuration */ export const injectFlowbiteAlertButtonConfig = (): FlowbiteAlertButtonConfig => inject(FlowbiteAlertButtonConfigToken, { optional: true }) ?? defaultFlowbiteAlertButtonConfig; ================================================ FILE: libs/flowbite-angular/alert/src/config/alert-config.ts ================================================ import { flowbiteAlertTheme, type FlowbiteAlertColors, type FlowbiteAlertTheme, } from '../alert/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteAlertConfig { /** * The default theme of alert */ baseTheme: FlowbiteAlertTheme; /** * The default color of alert */ color: keyof FlowbiteAlertColors; /** * Wether the alert has border */ border: boolean; /** * Wether the alert has border accent */ accent: boolean; /** * The custom theme of alert */ customTheme: DeepPartial; } export const defaultFlowbiteAlertConfig: FlowbiteAlertConfig = { baseTheme: flowbiteAlertTheme, color: 'default', border: false, accent: false, customTheme: {}, }; export const FlowbiteAlertConfigToken = new InjectionToken( 'FlowbiteAlertConfigToken' ); /** * Provide the default Alert configuration * @param config The Alert configuration * @returns The provider */ export const provideFlowbiteAlertConfig = (config: Partial): Provider[] => [ { provide: FlowbiteAlertConfigToken, useValue: { ...defaultFlowbiteAlertConfig, ...config }, }, ]; /** * Inject the Alert configuration * @see {@link defaultFlowbiteAlertConfig} * @returns The configuration */ export const injectFlowbiteAlertConfig = (): FlowbiteAlertConfig => inject(FlowbiteAlertConfigToken, { optional: true }) ?? defaultFlowbiteAlertConfig; ================================================ FILE: libs/flowbite-angular/alert/src/config/alert-content-config.ts ================================================ import { flowbiteAlertContentTheme, type FlowbiteAlertContentTheme } from '../alert-content/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteAlertContentConfig { /** * The default theme of AlertContent */ baseTheme: FlowbiteAlertContentTheme; /** * The custom theme of AlertContent */ customTheme: DeepPartial; } export const defaultFlowbiteAlertContentConfig: FlowbiteAlertContentConfig = { baseTheme: flowbiteAlertContentTheme, customTheme: {}, }; export const FlowbiteAlertContentConfigToken = new InjectionToken( 'FlowbiteAlertContentConfigToken' ); /** * Provide the default AlertContent configuration * @param config The AlertContent configuration * @returns The provider */ export const provideFlowbiteAlertContentConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteAlertContentConfigToken, useValue: { ...defaultFlowbiteAlertContentConfig, ...config }, }, ]; /** * Inject the AlertContent configuration * @see {@link defaultFlowbiteAlertContentConfig} * @returns The configuration */ export const injectFlowbiteAlertContentConfig = (): FlowbiteAlertContentConfig => inject(FlowbiteAlertContentConfigToken, { optional: true }) ?? defaultFlowbiteAlertContentConfig; ================================================ FILE: libs/flowbite-angular/alert/src/index.ts ================================================ /* Alert */ export * from './alert/alert.directive'; export * from './alert/alert-state'; export * from './alert/theme'; /* Config */ export * from './config/alert-config'; /* AlertButton */ export * from './alert-button/alert-button.directive'; export * from './alert-button/alert-button-state'; export * from './alert-button/theme'; /* Config */ export * from './config/alert-button-config'; /* AlertContent */ export * from './alert-content/alert-content.directive'; export * from './alert-content/alert-content-state'; export * from './alert-content/theme'; /* Config */ export * from './config/alert-content-config'; ================================================ FILE: libs/flowbite-angular/badge/ng-package.json ================================================ { "lib": { "entryFile": "./src/index.ts" } } ================================================ FILE: libs/flowbite-angular/badge/src/badge/badge-state.ts ================================================ import type { Badge } from './badge.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteBadgeStateToken = createStateToken('Flowbite Badge'); export const provideFlowbiteBadgeState = createStateProvider(FlowbiteBadgeStateToken); export const injectFlowbiteBadgeState = createStateInjector(FlowbiteBadgeStateToken); export const flowbiteBadgeState = createState(FlowbiteBadgeStateToken); ================================================ FILE: libs/flowbite-angular/badge/src/badge/badge.directive.ts ================================================ import { injectFlowbiteBadgeConfig } from '../config/badge-config'; import { flowbiteBadgeState, provideFlowbiteBadgeState } from './badge-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { booleanAttribute, computed, Directive, input } from '@angular/core'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` span[flowbiteBadge] `, exportAs: 'flowbiteBadge', hostDirectives: [], providers: [provideFlowbiteBadgeState()], host: { '[class]': `theme().host.root`, }, }) export class Badge { readonly config = injectFlowbiteBadgeConfig(); /** * @see {@link injectFlowbiteBadgeConfig} */ readonly color = input(this.config.color); /** * @see {@link injectFlowbiteBadgeConfig} */ readonly border = input(this.config.border, { transform: booleanAttribute }); /** * @see {@link injectFlowbiteBadgeConfig} */ readonly pill = input(this.config.pill, { transform: booleanAttribute }); /** * @see {@link injectFlowbiteBadgeConfig} */ readonly size = input(this.config.size); /** * @see {@link injectFlowbiteBadgeConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.state.color()), mergedTheme.host.border[this.state.border() ? 'on' : 'off'], mergedTheme.host.pill[this.state.pill() ? 'on' : 'off'], mergedTheme.host.size[this.state.size()] ), }, }; }); /** * @internal */ readonly state = flowbiteBadgeState(this); } ================================================ FILE: libs/flowbite-angular/badge/src/badge/theme.ts ================================================ import type { ColorToTheme, FlowbiteBoolean, FlowbiteColors, FlowbiteSizes, } from 'flowbite-angular'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteBadgeColors extends Pick { [key: string]: ColorToTheme; } export interface FlowbiteBadgeSizes extends Pick { [key: string]: string; } export interface FlowbiteBadgeTheme { host: FlowbiteBadgeHostTheme; } export interface FlowbiteBadgeHostTheme { base: string; transition: string; color: FlowbiteBadgeColors; border: FlowbiteBoolean; size: FlowbiteBadgeSizes; pill: FlowbiteBoolean; } export const flowbiteBadgeTheme: FlowbiteBadgeTheme = createTheme({ host: { base: 'inline-flex items-center justify-center font-medium', transition: '', border: { on: 'border', off: 'border-0', }, color: { default: { light: 'border-gray-300 bg-gray-100 text-gray-800', dark: 'dark:border-gray-900 dark:bg-gray-800 dark:text-gray-100', }, info: { light: 'border-blue-300 bg-blue-100 text-blue-800', dark: 'dark:border-blue-900 dark:bg-blue-800 dark:text-blue-100', }, failure: { light: 'border-red-300 bg-red-100 text-red-800', dark: 'dark:border-red-900 dark:bg-red-800 dark:text-red-100', }, success: { light: 'border-green-300 bg-green-100 text-green-800', dark: 'dark:border-green-900 dark:bg-green-800 dark:text-green-100', }, warning: { light: 'border-yellow-300 bg-yellow-100 text-yellow-800', dark: 'dark:border-yellow-900 dark:bg-yellow-800 dark:text-yellow-100', }, primary: { light: 'bg-primary-100 text-primary-800 border-primary-300', dark: 'dark:text-primary-100 dark:bg-primary-800 dark:border-primary-900', }, }, pill: { on: 'rounded-full', off: 'rounded', }, size: { xs: 'p-1 text-xs', sm: 'p-1.5 text-sm', }, }, }); ================================================ FILE: libs/flowbite-angular/badge/src/badge-button/badge-button-state.ts ================================================ import type { BadgeButton } from './badge-button.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteBadgeButtonStateToken = createStateToken('Flowbite BadgeButton'); export const provideFlowbiteBadgeButtonState = createStateProvider(FlowbiteBadgeButtonStateToken); export const injectFlowbiteBadgeButtonState = createStateInjector(FlowbiteBadgeButtonStateToken); export const flowbiteBadgeButtonState = createState(FlowbiteBadgeButtonStateToken); ================================================ FILE: libs/flowbite-angular/badge/src/badge-button/badge-button.directive.ts ================================================ import { injectFlowbiteBadgeState } from '../badge/badge-state'; import { injectFlowbiteBadgeButtonConfig } from '../config/badge-button-config'; import { flowbiteBadgeButtonState, provideFlowbiteBadgeButtonState } from './badge-button-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpButton } from 'ng-primitives/button'; import { NgpFocus } from 'ng-primitives/interactions'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` button[flowbiteBadgeButton], a[flowbiteBadgeButton] `, exportAs: 'flowbiteBadgeButton', hostDirectives: [ { directive: NgpButton, inputs: ['disabled:disabled'], outputs: [], }, { directive: NgpFocus, inputs: [], outputs: [], }, ], providers: [provideFlowbiteBadgeButtonState()], host: { '[class]': `theme().host.root` }, }) export class BadgeButton { readonly config = injectFlowbiteBadgeButtonConfig(); readonly badgeState = injectFlowbiteBadgeState(); /** * @see {@link injectFlowbiteBadgeButtonConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, colorToTheme(mergedTheme.host.color, this.badgeState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteBadgeButtonState(this); } ================================================ FILE: libs/flowbite-angular/badge/src/badge-button/theme.ts ================================================ import type { FlowbiteBadgeColors } from '../badge/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteBadgeButtonTheme { host: FlowbiteBadgeButtonHostTheme; } export interface FlowbiteBadgeButtonHostTheme { base: string; color: FlowbiteBadgeColors; } export const flowbiteBadgeButtonTheme: FlowbiteBadgeButtonTheme = createTheme({ host: { base: 'flex rounded-lg p-1 first:mr-2 last:ml-2 data-hover:cursor-pointer', color: { default: { light: 'data-hover:bg-gray-300', dark: 'dark:data-hover:bg-gray-700', }, info: { light: 'data-hover:bg-blue-300', dark: 'dark:data-hover:bg-blue-400', }, failure: { light: 'data-hover:bg-red-300', dark: 'dark:data-hover:bg-red-400', }, success: { light: 'data-hover:bg-green-300', dark: 'dark:data-hover:bg-green-400', }, warning: { light: 'data-hover:bg-yellow-300', dark: 'dark:data-hover:bg-yellow-400', }, primary: { light: 'data-hover:bg-primary-300', dark: 'dark:data-hover:bg-primary-400', }, }, }, }); ================================================ FILE: libs/flowbite-angular/badge/src/badge-link/badge-link-state.ts ================================================ import type { BadgeLink } from './badge-link.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteBadgeLinkStateToken = createStateToken('Flowbite BadgeLink'); export const provideFlowbiteBadgeLinkState = createStateProvider(FlowbiteBadgeLinkStateToken); export const injectFlowbiteBadgeLinkState = createStateInjector(FlowbiteBadgeLinkStateToken); export const flowbiteBadgeLinkState = createState(FlowbiteBadgeLinkStateToken); ================================================ FILE: libs/flowbite-angular/badge/src/badge-link/badge-link.directive.ts ================================================ import { injectFlowbiteBadgeState } from '../badge/badge-state'; import { Badge } from '../badge/badge.directive'; import { injectFlowbiteBadgeLinkConfig } from '../config/badge-link-config'; import { flowbiteBadgeLinkState, provideFlowbiteBadgeLinkState } from './badge-link-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpButton } from 'ng-primitives/button'; import { NgpFocus } from 'ng-primitives/interactions'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` button[flowbiteBadgeLink], a[flowbiteBadgeLink] `, exportAs: 'flowbiteBadgeLink', hostDirectives: [ { directive: Badge, inputs: ['color', 'border', 'pill', 'size', 'customTheme:badgeCustomTheme'], outputs: [], }, { directive: NgpButton, inputs: ['disabled:disabled'], outputs: [], }, { directive: NgpFocus, inputs: [], outputs: [], }, ], providers: [provideFlowbiteBadgeLinkState()], host: { '[class]': `theme().host.root` }, }) export class BadgeLink { readonly config = injectFlowbiteBadgeLinkConfig(); readonly badgeState = injectFlowbiteBadgeState(); /** * @see {@link injectFlowbiteBadgeLinkConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.badgeState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteBadgeLinkState(this); } ================================================ FILE: libs/flowbite-angular/badge/src/badge-link/theme.ts ================================================ import type { FlowbiteBadgeColors } from '../badge/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteBadgeLinkTheme { host: FlowbiteBadgeLinkHostTheme; } export interface FlowbiteBadgeLinkHostTheme { base: string; transition: string; color: FlowbiteBadgeColors; } export const flowbiteBadgeLinkTheme: FlowbiteBadgeLinkTheme = createTheme({ host: { base: 'data-hover:cursor-pointer', transition: '', color: { default: { light: 'data-hover:bg-gray-200', dark: 'dark:data-hover:bg-gray-700', }, info: { light: 'data-hover:bg-blue-200', dark: 'dark:data-hover:bg-blue-900', }, failure: { light: 'data-hover:bg-red-200', dark: 'dark:data-hover:bg-red-900', }, success: { light: 'data-hover:bg-green-200', dark: 'dark:data-hover:bg-green-900', }, warning: { light: 'data-hover:bg-yellow-200', dark: 'dark:data-hover:bg-yellow-900', }, primary: { light: 'data-hover:bg-primary-200', dark: 'dark:data-hover:bg-primary-900', }, }, }, }); ================================================ FILE: libs/flowbite-angular/badge/src/config/badge-button-config.ts ================================================ import { flowbiteBadgeButtonTheme, type FlowbiteBadgeButtonTheme } from '../badge-button/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteBadgeButtonConfig { /** * The default theme of BadgeButton */ baseTheme: FlowbiteBadgeButtonTheme; /** * The custom theme of BadgeButton */ customTheme: DeepPartial; } export const defaultFlowbiteBadgeButtonConfig: FlowbiteBadgeButtonConfig = { baseTheme: flowbiteBadgeButtonTheme, customTheme: {}, }; export const FlowbiteBadgeButtonConfigToken = new InjectionToken( 'FlowbiteBadgeButtonConfigToken' ); /** * Provide the default BadgeButton configuration * @param config The BadgeButton configuration * @returns The provider */ export const provideFlowbiteBadgeButtonConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteBadgeButtonConfigToken, useValue: { ...defaultFlowbiteBadgeButtonConfig, ...config }, }, ]; /** * Inject the BadgeButton configuration * @see {@link defaultFlowbiteBadgeButtonConfig} * @returns The configuration */ export const injectFlowbiteBadgeButtonConfig = (): FlowbiteBadgeButtonConfig => inject(FlowbiteBadgeButtonConfigToken, { optional: true }) ?? defaultFlowbiteBadgeButtonConfig; ================================================ FILE: libs/flowbite-angular/badge/src/config/badge-config.ts ================================================ import { flowbiteBadgeTheme, type FlowbiteBadgeColors, type FlowbiteBadgeSizes, type FlowbiteBadgeTheme, } from '../badge/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteBadgeConfig { /** * The default theme of badge */ baseTheme: FlowbiteBadgeTheme; /** * The default color of badge */ color: keyof FlowbiteBadgeColors; /** * Wether the badge has border */ border: boolean; /** * Wether the badge is pill */ pill: boolean; /** * The default size of badge */ size: keyof FlowbiteBadgeSizes; /** * The custom theme of badge */ customTheme: DeepPartial; } export const defaultFlowbiteBadgeConfig: FlowbiteBadgeConfig = { baseTheme: flowbiteBadgeTheme, color: 'default', border: false, pill: false, size: 'sm', customTheme: {}, }; export const FlowbiteBadgeConfigToken = new InjectionToken( 'FlowbiteBadgeConfigToken' ); /** * Provide the default Badge configuration * @param config The Badge configuration * @returns The provider */ export const provideFlowbiteBadgeConfig = (config: Partial): Provider[] => [ { provide: FlowbiteBadgeConfigToken, useValue: { ...defaultFlowbiteBadgeConfig, ...config }, }, ]; /** * Inject the Badge configuration * @see {@link defaultFlowbiteBadgeConfig} * @returns The configuration */ export const injectFlowbiteBadgeConfig = (): FlowbiteBadgeConfig => inject(FlowbiteBadgeConfigToken, { optional: true }) ?? defaultFlowbiteBadgeConfig; ================================================ FILE: libs/flowbite-angular/badge/src/config/badge-link-config.ts ================================================ import { flowbiteBadgeLinkTheme, type FlowbiteBadgeLinkTheme } from '../badge-link/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteBadgeLinkConfig { /** * The default theme of BadgeLink */ baseTheme: FlowbiteBadgeLinkTheme; /** * The custom theme of BadgeLink */ customTheme: DeepPartial; } export const defaultFlowbiteBadgeLinkConfig: FlowbiteBadgeLinkConfig = { baseTheme: flowbiteBadgeLinkTheme, customTheme: {}, }; export const FlowbiteBadgeLinkConfigToken = new InjectionToken( 'FlowbiteBadgeLinkConfigToken' ); /** * Provide the default BadgeLink configuration * @param config The BadgeLink configuration * @returns The provider */ export const provideFlowbiteBadgeLinkConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteBadgeLinkConfigToken, useValue: { ...defaultFlowbiteBadgeLinkConfig, ...config }, }, ]; /** * Inject the BadgeLink configuration * @see {@link defaultFlowbiteBadgeLinkConfig} * @returns The configuration */ export const injectFlowbiteBadgeLinkConfig = (): FlowbiteBadgeLinkConfig => inject(FlowbiteBadgeLinkConfigToken, { optional: true }) ?? defaultFlowbiteBadgeLinkConfig; ================================================ FILE: libs/flowbite-angular/badge/src/index.ts ================================================ /* Badge */ export * from './badge/badge.directive'; export * from './badge/badge-state'; export * from './badge/theme'; /* Config */ export * from './config/badge-config'; /* BadgeLink */ export * from './badge-link/badge-link.directive'; export * from './badge-link/badge-link-state'; export * from './badge-link/theme'; /* Config */ export * from './config/badge-link-config'; /* BadgeButton */ export * from './badge-button/badge-button.directive'; export * from './badge-button/badge-button-state'; export * from './badge-button/theme'; /* Config */ export * from './config/badge-button-config'; ================================================ FILE: libs/flowbite-angular/breadcrumb/ng-package.json ================================================ { "lib": { "entryFile": "./src/index.ts" } } ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb/breadcrumb-state.ts ================================================ import type { Breadcrumb } from './breadcrumb.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteBreadcrumbStateToken = createStateToken('Flowbite Breadcrumb'); export const provideFlowbiteBreadcrumbState = createStateProvider(FlowbiteBreadcrumbStateToken); export const injectFlowbiteBreadcrumbState = createStateInjector(FlowbiteBreadcrumbStateToken); export const flowbiteBreadcrumbState = createState(FlowbiteBreadcrumbStateToken); ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb/breadcrumb.directive.ts ================================================ import { injectFlowbiteBreadcrumbConfig } from '../config/breadcrumb-config'; import { flowbiteBreadcrumbState, provideFlowbiteBreadcrumbState } from './breadcrumb-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { booleanAttribute, computed, Directive, input } from '@angular/core'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` nav[flowbiteBreadcrumb] `, exportAs: 'flowbiteBreadcrumb', hostDirectives: [], providers: [provideFlowbiteBreadcrumbState()], host: { '[class]': `theme().host.root`, }, }) export class Breadcrumb { readonly config = injectFlowbiteBreadcrumbConfig(); /** * @see {@link injectFlowbiteBreadcrumbConfig} */ readonly color = input(this.config.color); /** * @see {@link injectFlowbiteBreadcrumbConfig} */ readonly solid = input(this.config.solid, { transform: booleanAttribute }); /** * @see {@link injectFlowbiteBreadcrumbConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, this.state.solid() && mergedTheme.host.solid[this.state.solid() ? 'on' : 'off'] && colorToTheme(mergedTheme.host.color, this.state.color()) ), }, }; }); /** * @internal */ readonly state = flowbiteBreadcrumbState(this); } ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb/theme.ts ================================================ import type { ColorToTheme, FlowbiteBoolean, FlowbiteColors } from 'flowbite-angular'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteBreadcrumbColors extends Pick { [ket: string]: ColorToTheme; } export interface FlowbiteBreadcrumbTheme { host: FlowbiteBreadcrumbHostTheme; } export interface FlowbiteBreadcrumbHostTheme { base: string; transition: string; solid: FlowbiteBoolean; color: FlowbiteBreadcrumbColors; } export const flowbiteBreadcrumbTheme: FlowbiteBreadcrumbTheme = createTheme({ host: { base: 'inline-flex items-center gap-1 rounded-lg px-5 py-3', transition: '', solid: { on: 'border', off: 'border-none bg-transparent', }, color: { default: { light: 'border-gray-300 bg-gray-100', dark: 'dark:border-gray-900 dark:bg-gray-800', }, info: { light: 'border-blue-300 bg-blue-100', dark: 'dark:border-blue-900 dark:bg-blue-800', }, failure: { light: 'border-red-300 bg-red-100', dark: 'dark:border-red-900 dark:bg-red-800', }, success: { light: 'border-green-300 bg-green-100', dark: 'dark:border-green-900 dark:bg-green-800', }, warning: { light: 'border-yellow-300 bg-yellow-100', dark: 'dark:border-yellow-900 dark:bg-yellow-800', }, primary: { light: 'border-primary-300 bg-primary-100', dark: 'dark:border-primary-900 dark:bg-primary-800', }, }, }, }); ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb-content/breadcrumb-content-state.ts ================================================ import type { BreadcrumbContent } from './breadcrumb-content.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteBreadcrumbContentStateToken = createStateToken( 'Flowbite BreadcrumbContent' ); export const provideFlowbiteBreadcrumbContentState = createStateProvider( FlowbiteBreadcrumbContentStateToken ); export const injectFlowbiteBreadcrumbContentState = createStateInjector( FlowbiteBreadcrumbContentStateToken ); export const flowbiteBreadcrumbContentState = createState(FlowbiteBreadcrumbContentStateToken); ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb-content/breadcrumb-content.directive.ts ================================================ import { injectFlowbiteBreadcrumbContentConfig } from '../config/breadcrumb-content-config'; import { flowbiteBreadcrumbContentState, provideFlowbiteBreadcrumbContentState, } from './breadcrumb-content-state'; import { mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` ol[flowbiteBreadcrumbContent] `, exportAs: 'flowbiteBreadcrumbContent', hostDirectives: [], providers: [provideFlowbiteBreadcrumbContentState()], host: { '[class]': `theme().host.root` }, }) export class BreadcrumbContent { readonly config = injectFlowbiteBreadcrumbContentConfig(); /** * @see {@link injectFlowbiteBreadcrumbContentConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge(mergedTheme.host.base, mergedTheme.host.transition), }, }; }); /** * @internal */ readonly state = flowbiteBreadcrumbContentState(this); } ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb-content/theme.ts ================================================ import { createTheme } from 'flowbite-angular'; export interface FlowbiteBreadcrumbContentTheme { host: FlowbiteBreadcrumbContentHostTheme; } export interface FlowbiteBreadcrumbContentHostTheme { base: string; transition: string; } export const flowbiteBreadcrumbContentTheme: FlowbiteBreadcrumbContentTheme = createTheme({ host: { base: 'inline-flex items-center space-x-1 md:space-x-2', transition: '', }, }); ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb-item/breadcrumb-item-state.ts ================================================ import type { BreadcrumbItem } from './breadcrumb-item.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteBreadcrumbItemStateToken = createStateToken( 'Flowbite Breadcrumb Item' ); export const provideFlowbiteBreadcrumbItemState = createStateProvider( FlowbiteBreadcrumbItemStateToken ); export const injectFlowbiteBreadcrumbItemState = createStateInjector( FlowbiteBreadcrumbItemStateToken ); export const flowbiteBreadcrumbItemState = createState(FlowbiteBreadcrumbItemStateToken); ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb-item/breadcrumb-item.directive.ts ================================================ import { injectFlowbiteBreadcrumbState } from '../breadcrumb/breadcrumb-state'; import { injectFlowbiteBreadcrumbItemConfig } from '../config/breadcrumb-item-config'; import { flowbiteBreadcrumbItemState, provideFlowbiteBreadcrumbItemState, } from './breadcrumb-item-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpButton } from 'ng-primitives/button'; import { NgpFocus } from 'ng-primitives/interactions'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` li[flowbiteBreadcrumbItem] `, exportAs: 'flowbiteBreadcrumbItem', hostDirectives: [ { directive: NgpButton, inputs: ['disabled:disabled'], outputs: [], }, { directive: NgpFocus, inputs: [], outputs: [], }, ], providers: [provideFlowbiteBreadcrumbItemState()], host: { '[class]': `theme().host.root`, }, }) export class BreadcrumbItem { readonly config = injectFlowbiteBreadcrumbItemConfig(); readonly breadcrumbState = injectFlowbiteBreadcrumbState(); /** * @see {@link injectFlowbiteBreadcrumbItemConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.breadcrumbState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteBreadcrumbItemState(this); } ================================================ FILE: libs/flowbite-angular/breadcrumb/src/breadcrumb-item/theme.ts ================================================ import type { FlowbiteBreadcrumbColors } from '../breadcrumb/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteBreadcrumbItemTheme { host: FlowbiteBreadcrumbItemHostTheme; } export interface FlowbiteBreadcrumbItemHostTheme { base: string; transition: string; color: FlowbiteBreadcrumbColors; } export const flowbiteBreadcrumbItemTheme: FlowbiteBreadcrumbItemTheme = createTheme({ host: { base: 'group inline-flex items-center justify-between text-sm font-medium data-hover:cursor-pointer', transition: '', color: { default: { light: 'text-gray-700 data-hover:text-gray-900', dark: 'dark:text-gray-100 dark:data-hover:text-white', }, info: { light: 'text-blue-700 data-hover:text-blue-900', dark: 'dark:text-blue-100 dark:data-hover:text-blue-300', }, failure: { light: 'text-red-700 data-hover:text-red-900', dark: 'dark:text-red-100 dark:data-hover:text-red-300', }, success: { light: 'text-green-700 data-hover:text-green-900', dark: 'dark:text-green-100 dark:data-hover:text-green-300', }, warning: { light: 'text-yellow-700 data-hover:text-yellow-900', dark: 'dark:text-yellow-100 dark:data-hover:text-yellow-300', }, primary: { light: 'data-hover:text-primary-900 text-primary-700', dark: 'dark:text-primary-100 dark:data-hover:text-primary-300', }, }, }, }); ================================================ FILE: libs/flowbite-angular/breadcrumb/src/config/breadcrumb-config.ts ================================================ import { flowbiteBreadcrumbTheme, type FlowbiteBreadcrumbColors, type FlowbiteBreadcrumbTheme, } from '../breadcrumb/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteBreadcrumbConfig { /** * The default theme of breadcrumb */ baseTheme: FlowbiteBreadcrumbTheme; /** * The default color of breadcrumb */ color: keyof FlowbiteBreadcrumbColors; /** * Whether the breadcrumb is solid */ solid: boolean; /** * The custom theme of breadcrumb */ customTheme: DeepPartial; } export const defaultFlowbiteBreadcrumbConfig: FlowbiteBreadcrumbConfig = { baseTheme: flowbiteBreadcrumbTheme, color: 'default', solid: false, customTheme: {}, }; export const FlowbiteBreadcrumbConfigToken = new InjectionToken( 'FlowbiteBreadcrumbConfigToken' ); /** * Provide the default Breadcrumb configuration * @param config The Breadcrumb configuration * @returns The provider */ export const provideFlowbiteBreadcrumbConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteBreadcrumbConfigToken, useValue: { ...defaultFlowbiteBreadcrumbConfig, ...config }, }, ]; /** * Inject the Breadcrumb configuration * @see {@link defaultFlowbiteBreadcrumbConfig} * @returns The configuration */ export const injectFlowbiteBreadcrumbConfig = (): FlowbiteBreadcrumbConfig => inject(FlowbiteBreadcrumbConfigToken, { optional: true }) ?? defaultFlowbiteBreadcrumbConfig; ================================================ FILE: libs/flowbite-angular/breadcrumb/src/config/breadcrumb-content-config.ts ================================================ import { flowbiteBreadcrumbContentTheme, type FlowbiteBreadcrumbContentTheme, } from '../breadcrumb-content/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteBreadcrumbContentConfig { /** * The default theme of BreadcrumbContent */ baseTheme: FlowbiteBreadcrumbContentTheme; /** * The custom theme of BreadcrumbContent */ customTheme: DeepPartial; } export const defaultFlowbiteBreadcrumbContentConfig: FlowbiteBreadcrumbContentConfig = { baseTheme: flowbiteBreadcrumbContentTheme, customTheme: {}, }; export const FlowbiteBreadcrumbContentConfigToken = new InjectionToken('FlowbiteBreadcrumbContentConfigToken'); /** * Provide the default BreadcrumbContent configuration * @param config The BreadcrumbContent configuration * @returns The provider */ export const provideFlowbiteBreadcrumbContentConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteBreadcrumbContentConfigToken, useValue: { ...defaultFlowbiteBreadcrumbContentConfig, ...config }, }, ]; /** * Inject the BreadcrumbContent configuration * @see {@link defaultFlowbiteBreadcrumbContentConfig} * @returns The configuration */ export const injectFlowbiteBreadcrumbContentConfig = (): FlowbiteBreadcrumbContentConfig => inject(FlowbiteBreadcrumbContentConfigToken, { optional: true }) ?? defaultFlowbiteBreadcrumbContentConfig; ================================================ FILE: libs/flowbite-angular/breadcrumb/src/config/breadcrumb-item-config.ts ================================================ import type { FlowbiteBreadcrumbItemTheme } from '../breadcrumb-item/theme'; import { flowbiteBreadcrumbItemTheme } from '../breadcrumb-item/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteBreadcrumbItemConfig { /** * The default theme of breadcrumb item */ baseTheme: FlowbiteBreadcrumbItemTheme; /** * The custom theme of breadcrumb item */ customTheme: DeepPartial; } export const defaultFlowbiteBreadcrumbItemConfig: FlowbiteBreadcrumbItemConfig = { baseTheme: flowbiteBreadcrumbItemTheme, customTheme: {}, }; export const FlowbiteBreadcrumbItemConfigToken = new InjectionToken( 'FlowbiteBreadcrumbConfigToken' ); /** * Provide the default Breadcrumb Item configuration * @param config The Breadcrumb configuration * @returns The provider */ export const provideFlowbiteBreadcrumbItemConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteBreadcrumbItemConfigToken, useValue: { ...defaultFlowbiteBreadcrumbItemConfig, ...config }, }, ]; /** * Inject the Breadcrumb Item configuration * @see {@link defaultFlowbiteBreadcrumbItemConfig} * @returns The configuration */ export const injectFlowbiteBreadcrumbItemConfig = (): FlowbiteBreadcrumbItemConfig => inject(FlowbiteBreadcrumbItemConfigToken, { optional: true }) ?? defaultFlowbiteBreadcrumbItemConfig; ================================================ FILE: libs/flowbite-angular/breadcrumb/src/index.ts ================================================ /* Breadcrumb */ export * from './breadcrumb/breadcrumb.directive'; export * from './breadcrumb/breadcrumb-state'; export * from './breadcrumb/theme'; /* BreadcrumbItem */ export * from './breadcrumb-item/breadcrumb-item.directive'; export * from './breadcrumb-item/breadcrumb-item-state'; export * from './breadcrumb-item/theme'; /* Config */ export * from './config/breadcrumb-config'; export * from './config/breadcrumb-item-config'; /* BreadcrumbContent */ export * from './breadcrumb-content/breadcrumb-content.directive'; export * from './breadcrumb-content/breadcrumb-content-state'; export * from './breadcrumb-content/theme'; /* Config */ export * from './config/breadcrumb-content-config'; ================================================ FILE: libs/flowbite-angular/button/ng-package.json ================================================ { "lib": { "entryFile": "./src/index.ts" } } ================================================ FILE: libs/flowbite-angular/button/src/base-button/base-button-state.ts ================================================ import type { BaseButton } from './base-button.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteBaseButtonStateToken = createStateToken('Flowbite BaseButton'); export const provideFlowbiteBaseButtonState = createStateProvider(FlowbiteBaseButtonStateToken); export const injectFlowbiteBaseButtonState = createStateInjector(FlowbiteBaseButtonStateToken); export const flowbiteBaseButtonState = createState(FlowbiteBaseButtonStateToken); ================================================ FILE: libs/flowbite-angular/button/src/base-button/base-button.directive.ts ================================================ import { injectFlowbiteBaseButtonConfig } from '../config/base-button-config'; import { flowbiteBaseButtonState, provideFlowbiteBaseButtonState } from './base-button-state'; import type { FlowbiteBaseButtonColors, FlowbiteBaseButtonSizes } from './theme'; import { booleanAttribute, Directive, input } from '@angular/core'; @Directive({ standalone: true, providers: [provideFlowbiteBaseButtonState()], }) export class BaseButton { readonly config = injectFlowbiteBaseButtonConfig(); /** * @see {@link injectFlowbiteBaseButtonConfig} */ readonly color = input(this.config.color); /** * @see {@link injectFlowbiteBaseButtonConfig} */ readonly size = input(this.config.size); /** * @see {@link injectFlowbiteBaseButtonConfig} */ readonly pill = input(this.config.pill, { transform: booleanAttribute }); /** * @see {@link injectFlowbiteBaseButtonConfig} */ readonly outline = input(this.config.outline, { transform: booleanAttribute }); /** * @internal */ readonly state = flowbiteBaseButtonState(this); } ================================================ FILE: libs/flowbite-angular/button/src/base-button/theme.ts ================================================ import type { ColorToTheme, FlowbiteColors, FlowbiteSizes } from 'flowbite-angular'; export interface FlowbiteBaseButtonSizes extends Pick { [key: string]: string; } export interface FlowbiteBaseButtonColors extends Pick { [key: string]: ColorToTheme; } ================================================ FILE: libs/flowbite-angular/button/src/button/button-state.ts ================================================ import type { Button } from './button.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteButtonStateToken = createStateToken
    Copy to clipboard
    `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) export class Clipboard { readonly config = injectFlowbiteClipboardConfig(); readonly clipboard = inject(CdkClipboard); readonly id = input(); readonly value = input(); /** * @see {@link injectFlowbiteClipboardConfig} */ readonly customTheme = input>(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge(mergedTheme.host.base, mergedTheme.host.transition), }, }; }); /** * @internal */ readonly state = flowbiteClipboardState(this); /** * @internal */ onClick(): void { this.copyToClipboard(); } /** * @internal */ copyToClipboard(): void { const value = this.value(); if (value) { this.clipboard.copy(value); } } } ================================================ FILE: libs/flowbite-angular/clipboard/src/clipboard/theme.ts ================================================ import { createTheme } from 'flowbite-angular'; export interface FlowbiteClipboardTheme { host: FlowbiteClipboardHostTheme; } export interface FlowbiteClipboardHostTheme { base: string; transition: string; } export const flowbiteClipboardTheme: FlowbiteClipboardTheme = createTheme({ host: { base: 'w-full max-w-[16rem]', transition: '', }, }); ================================================ FILE: libs/flowbite-angular/clipboard/src/config/clipboard-config.ts ================================================ import { flowbiteClipboardTheme, type FlowbiteClipboardTheme } from '../clipboard/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteClipboardConfig { /** * The default theme of clipboard */ baseTheme: FlowbiteClipboardTheme; /** * The custom theme of clipboard */ customTheme: DeepPartial; } export const defaultFlowbiteClipboardConfig: FlowbiteClipboardConfig = { baseTheme: flowbiteClipboardTheme, customTheme: {}, }; export const FlowbiteClipboardConfigToken = new InjectionToken( 'FlowbiteClipboardConfigToken' ); /** * Provide the default Clipboard configuration * @param config The Clipboard configuration * @returns The provider */ export const provideFlowbiteClipboardConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteClipboardConfigToken, useValue: { ...defaultFlowbiteClipboardConfig, ...config }, }, ]; /** * Inject the Clipboard configuration * @see {@link defaultFlowbiteClipboardConfig} * @returns The configuration */ export const injectFlowbiteClipboardConfig = (): FlowbiteClipboardConfig => inject(FlowbiteClipboardConfigToken, { optional: true }) ?? defaultFlowbiteClipboardConfig; ================================================ FILE: libs/flowbite-angular/clipboard/src/index.ts ================================================ /* Clipboard */ export * from './clipboard/clipboard.component'; export * from './clipboard/clipboard-state'; export * from './clipboard/theme'; /* Config */ export * from './config/clipboard-config'; ================================================ FILE: libs/flowbite-angular/core/src/core/flowbite.boolean.ts ================================================ export interface FlowbiteBoolean { off: string; on: string; } ================================================ FILE: libs/flowbite-angular/core/src/core/flowbite.colors.ts ================================================ export interface ColorToTheme { light: string; dark: string; } export interface FlowbiteStateColors { default: ColorToTheme; info: ColorToTheme; failure: ColorToTheme; success: ColorToTheme; warning: ColorToTheme; } export interface FlowbiteColors extends FlowbiteStateColors { [key: string]: ColorToTheme; primary: ColorToTheme; dark: ColorToTheme; light: ColorToTheme; blue: ColorToTheme; cyan: ColorToTheme; gray: ColorToTheme; green: ColorToTheme; indigo: ColorToTheme; lime: ColorToTheme; pink: ColorToTheme; purple: ColorToTheme; red: ColorToTheme; teal: ColorToTheme; yellow: ColorToTheme; } export interface FlowbiteGradientColors extends Omit { [key: string]: ColorToTheme; cyan: ColorToTheme; lime: ColorToTheme; pink: ColorToTheme; purple: ColorToTheme; teal: ColorToTheme; } export interface FlowbiteGradientDuoToneColors { cyanToBlue: ColorToTheme; greenToBlue: ColorToTheme; pinkToOrange: ColorToTheme; purpleToBlue: ColorToTheme; purpleToPink: ColorToTheme; redToYellow: ColorToTheme; tealToLime: ColorToTheme; } ================================================ FILE: libs/flowbite-angular/core/src/core/flowbite.deep-partial.ts ================================================ /** * Type describing partial object from another, by getting every sub-child of provided type in itself. */ export type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial; } : T; ================================================ FILE: libs/flowbite-angular/core/src/core/flowbite.positions.ts ================================================ export interface FlowbitePositions { 'bottom-left': string; 'bottom-right': string; 'bottom-center': string; 'top-left': string; 'top-center': string; 'top-right': string; 'center-left': string; center: string; 'center-right': string; } ================================================ FILE: libs/flowbite-angular/core/src/core/flowbite.sizes.ts ================================================ export interface FlowbiteSizes { xs: string; sm: string; md: string; lg: string; xl: string; '2xl': string; '3xl': string; '4xl': string; '5xl': string; '6xl': string; '7xl': string; } ================================================ FILE: libs/flowbite-angular/core/src/core/flowbite.themes.ts ================================================ /** * Base definition of theme used in flowbite-angular. */ export type FlowbiteThemes = 'dark' | 'light'; ================================================ FILE: libs/flowbite-angular/core/src/index.ts ================================================ export * from './core/flowbite.boolean'; export * from './core/flowbite.colors'; export * from './core/flowbite.deep-partial'; export * from './core/flowbite.positions'; export * from './core/flowbite.sizes'; export * from './core/flowbite.themes'; export * from './utils/clone-deep'; export * from './utils/color-to-theme'; export * from './utils/create-theme'; export * from './utils/is-object'; export * from './utils/merge-theme'; ================================================ FILE: libs/flowbite-angular/core/src/utils/clone-deep.ts ================================================ import { isObject } from './is-object'; /** * Function that return the cloned type of the provided generic type. * * @param source Generic object to be cloned. * @returns The clone type of the provided type. */ export function cloneDeep(source: T): T { if (!isObject(source)) { return source; } const output: Record = {}; for (const key in source) { output[key] = cloneDeep(source[key]); } return output as T; } ================================================ FILE: libs/flowbite-angular/core/src/utils/color-to-theme.ts ================================================ import type { FlowbiteColors } from '../core/flowbite.colors'; export function colorToTheme>( set: TSet, key: keyof TSet ): string { return `${set[key]!.light} ${set[key]!.dark}`; } ================================================ FILE: libs/flowbite-angular/core/src/utils/create-theme.ts ================================================ /** * This function is used to create themes for component's while keeping the intellisens up for TailwindCSS and other extensions. * * @param input Generic type to be created. * @returns The generic type's definition. */ export function createTheme(input: T) { return input; } ================================================ FILE: libs/flowbite-angular/core/src/utils/is-object.ts ================================================ /** * Check if the provided parameter is an object or not. * * @param item The unknown type parameter. * @returns true if it's an ibject ; false otherwise. */ export function isObject(item: unknown): item is Record { return item !== null && typeof item === 'object' && item.constructor === Object; } ================================================ FILE: libs/flowbite-angular/core/src/utils/merge-theme.ts ================================================ import { cloneDeep } from './clone-deep'; import { isObject } from './is-object'; /** * Merge two objects into one. * * @param target Object to be merged. * @param source Object to be merged. * @returns The merged object. */ export function mergeDeep(target: T, source: S): T & S { if (isObject(source) && Object.keys(source).length === 0) { return cloneDeep({ ...target, ...source }); } const output = { ...target, ...source }; if (isObject(source) && isObject(target)) { for (const key in source) { if (isObject(source[key]) && key in target && isObject(target[key])) { (output as Record)[key] = mergeDeep( target[key] as object, source[key] as object ); } else { (output as Record)[key] = isObject(source[key]) ? cloneDeep(source[key]) : source[key]; } } } return output; } ================================================ FILE: libs/flowbite-angular/dropdown/ng-package.json ================================================ { "lib": { "entryFile": "./src/index.ts" } } ================================================ FILE: libs/flowbite-angular/dropdown/src/config/dropdown-config.ts ================================================ import type { FLowbiteDropdownColors, FlowbiteDropdownTheme } from '../dropdown/theme'; import { flowbiteDropdownTheme } from '../dropdown/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteDropdownConfig { baseTheme: FlowbiteDropdownTheme; /** * The custom color of dropdown */ color: keyof FLowbiteDropdownColors; /** * The custom theme of dropdown */ customTheme: DeepPartial; } export const defaultFlowbiteDropdownConfig: FlowbiteDropdownConfig = { baseTheme: flowbiteDropdownTheme, color: 'default', customTheme: {}, }; export const FlowbiteDropdownConfigToken = new InjectionToken( 'FlowbiteDropdownConfigToken' ); /** * Provide the default Dropdown configuration * @param config The Dropdown configuration * @returns The provider */ export const provideFlowbiteDropdownConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteDropdownConfigToken, useValue: { ...defaultFlowbiteDropdownConfig, ...config }, }, ]; /** * Inject the Dropdown configuration * @see {@link defaultFlowbiteDropdownConfig} * @returns The configuration */ export const injectFlowbiteDropdownConfig = (): FlowbiteDropdownConfig => inject(FlowbiteDropdownConfigToken, { optional: true }) ?? defaultFlowbiteDropdownConfig; ================================================ FILE: libs/flowbite-angular/dropdown/src/config/dropdown-content-config.ts ================================================ import { flowbiteDropdownContentTheme, type FlowbiteDropdownContentTheme, } from '../dropdown-content/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteDropdownContentConfig { /** * The default theme of DropdownContent */ baseTheme: FlowbiteDropdownContentTheme; /** * The custom theme of DropdownContent */ customTheme: DeepPartial; } export const defaultFlowbiteDropdownContentConfig: FlowbiteDropdownContentConfig = { baseTheme: flowbiteDropdownContentTheme, customTheme: {}, }; export const FlowbiteDropdownContentConfigToken = new InjectionToken( 'FlowbiteDropdownContentConfigToken' ); /** * Provide the default DropdownContent configuration * @param config The DropdownContent configuration * @returns The provider */ export const provideFlowbiteDropdownContentConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteDropdownContentConfigToken, useValue: { ...defaultFlowbiteDropdownContentConfig, ...config }, }, ]; /** * Inject the DropdownContent configuration * @see {@link defaultFlowbiteDropdownContentConfig} * @returns The configuration */ export const injectFlowbiteDropdownContentConfig = (): FlowbiteDropdownContentConfig => inject(FlowbiteDropdownContentConfigToken, { optional: true }) ?? defaultFlowbiteDropdownContentConfig; ================================================ FILE: libs/flowbite-angular/dropdown/src/config/dropdown-item-config.ts ================================================ import type { FlowbiteDropdownItemTheme } from '../dropdown-item/theme'; import { flowbiteDropdownItemTheme } from '../dropdown-item/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteDropdownItemConfig { baseTheme: FlowbiteDropdownItemTheme; /** * The custom theme of dropdown item */ customTheme: DeepPartial; } export const defaultFlowbiteDropdownItemConfig: FlowbiteDropdownItemConfig = { baseTheme: flowbiteDropdownItemTheme, customTheme: {}, }; export const FlowbiteDropdownItemConfigToken = new InjectionToken( 'FlowbiteDropdownItemConfigToken' ); /** * Provide the default Dropdown Item configuration * @param config The Dropdown Item configuration * @returns The provider */ export const provideFlowbiteDropdownItemConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteDropdownItemConfigToken, useValue: { ...defaultFlowbiteDropdownItemConfig, ...config }, }, ]; /** * Inject the Dropdown Item configuration * @see {@link defaultFlowbiteDropdownItemConfig} * @returns The configuration */ export const injectFlowbiteDropdownItemConfig = (): FlowbiteDropdownItemConfig => inject(FlowbiteDropdownItemConfigToken, { optional: true }) ?? defaultFlowbiteDropdownItemConfig; ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown/dropdown-state.ts ================================================ import type { Dropdown } from './dropdown.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteDropdownStateToken = createStateToken('Flowbite Dropdown'); export const provideFlowbiteDropdownState = createStateProvider(FlowbiteDropdownStateToken); export const injectFlowbiteDropdownState = createStateInjector(FlowbiteDropdownStateToken); export const flowbiteDropdownState = createState(FlowbiteDropdownStateToken); ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown/dropdown.directive.ts ================================================ import { injectFlowbiteDropdownConfig } from '../config/dropdown-config'; import { flowbiteDropdownState, provideFlowbiteDropdownState } from './dropdown-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpMenu } from 'ng-primitives/menu'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` div[flowbiteDropdown] `, exportAs: 'flowbiteDropdown', hostDirectives: [ { directive: NgpMenu, inputs: [], outputs: [], }, ], providers: [provideFlowbiteDropdownState()], host: { '[class]': `theme().host.root`, }, }) export class Dropdown { readonly config = injectFlowbiteDropdownConfig(); /** * @see {@link injectFlowbiteDropdownConfig} */ readonly color = input(this.config.color); /** * @see {@link injectFlowbiteDropdownConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.state.color()) ), }, }; }); /** * @internal */ readonly state = flowbiteDropdownState(this); } ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown/theme.ts ================================================ import type { ColorToTheme, FlowbiteColors } from 'flowbite-angular'; import { createTheme } from 'flowbite-angular'; export interface FLowbiteDropdownColors extends Pick { [key: string]: ColorToTheme; } export interface FlowbiteDropdownTheme { host: FlowbiteDropdownHostTheme; } export interface FlowbiteDropdownHostTheme { base: string; transition: string; color: FLowbiteDropdownColors; } export const flowbiteDropdownTheme: FlowbiteDropdownTheme = createTheme({ host: { base: 'fixed z-10 w-max divide-y rounded-lg border shadow-sm', transition: '', color: { default: { light: 'divide-gray-200 border-gray-200 bg-white', dark: 'dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-800', }, info: { light: 'divide-blue-200 border-blue-200 bg-white', dark: 'dark:divide-blue-700 dark:border-blue-700 dark:bg-gray-800', }, failure: { light: 'divide-red-200 border-red-200 bg-white', dark: 'dark:divide-red-700 dark:border-red-700 dark:bg-gray-800', }, success: { light: 'divide-green-200 border-green-200 bg-white', dark: 'dark:divide-green-700 dark:border-green-700 dark:bg-gray-800', }, warning: { light: 'divide-yellow-200 border-yellow-200 bg-white', dark: 'dark:divide-yellow-700 dark:border-yellow-700 dark:bg-gray-800', }, primary: { light: 'divide-primary-200 border-primary-200 bg-white', dark: 'dark:divide-primary-700 dark:border-primary-700 dark:bg-gray-800', }, }, }, }); ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown-content/dropdown-content-state.ts ================================================ import type { DropdownContent } from './dropdown-content.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteDropdownContentStateToken = createStateToken( 'Flowbite DropdownContent' ); export const provideFlowbiteDropdownContentState = createStateProvider( FlowbiteDropdownContentStateToken ); export const injectFlowbiteDropdownContentState = createStateInjector( FlowbiteDropdownContentStateToken ); export const flowbiteDropdownContentState = createState(FlowbiteDropdownContentStateToken); ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown-content/dropdown-content.directive.ts ================================================ import { injectFlowbiteDropdownContentConfig } from '../config/dropdown-content-config'; import { injectFlowbiteDropdownState } from '../dropdown/dropdown-state'; import { flowbiteDropdownContentState, provideFlowbiteDropdownContentState, } from './dropdown-content-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` ul[flowbiteDropdownContent] `, exportAs: 'flowbiteDropdownContent', hostDirectives: [], providers: [provideFlowbiteDropdownContentState()], host: { '[class]': `theme().host.root` }, }) export class DropdownContent { readonly config = injectFlowbiteDropdownContentConfig(); readonly dropdownState = injectFlowbiteDropdownState(); /** * @see {@link injectFlowbiteDropdownContentConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.dropdownState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteDropdownContentState(this); } ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown-content/theme.ts ================================================ import type { FLowbiteDropdownColors } from '../dropdown/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteDropdownContentTheme { host: FlowbiteDropdownContentHostTheme; } export interface FlowbiteDropdownContentHostTheme { base: string; transition: string; color: FLowbiteDropdownColors; } export const flowbiteDropdownContentTheme: FlowbiteDropdownContentTheme = createTheme({ host: { base: 'py-2 text-sm', transition: '', color: { default: { light: 'text-gray-700', dark: 'dark:text-gray-200', }, info: { light: 'text-gray-700', dark: 'dark:text-gray-200', }, failure: { light: 'text-gray-700', dark: 'dark:text-gray-200', }, success: { light: 'text-gray-700', dark: 'dark:text-gray-200', }, warning: { light: 'text-gray-700', dark: 'dark:text-gray-200', }, primary: { light: 'text-gray-700', dark: 'dark:text-gray-200', }, }, }, }); ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown-item/dropdown-item-state.ts ================================================ import type { DropdownItem } from './dropdown-item.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteDropdownItemStateToken = createStateToken('Flowbite Dropdown Item'); export const provideFlowbiteDropdownItemState = createStateProvider(FlowbiteDropdownItemStateToken); export const injectFlowbiteDropdownItemState = createStateInjector(FlowbiteDropdownItemStateToken); export const flowbiteDropdownItemState = createState(FlowbiteDropdownItemStateToken); ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown-item/dropdown-item.directive.ts ================================================ import { injectFlowbiteDropdownItemConfig } from '../config/dropdown-item-config'; import { injectFlowbiteDropdownState } from '../dropdown/dropdown-state'; import { flowbiteDropdownItemState, provideFlowbiteDropdownItemState } from './dropdown-item-state'; import type { FlowbiteDropdownItemTheme } from './theme'; import type { DeepPartial } from 'flowbite-angular'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpFocus } from 'ng-primitives/interactions'; import { NgpMenuItem } from 'ng-primitives/menu'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` li[flowbiteDropdownItem] `, exportAs: 'flowbiteDropdownItem', hostDirectives: [ { directive: NgpMenuItem, inputs: [], outputs: [], }, { directive: NgpFocus, inputs: [], outputs: [], }, ], providers: [provideFlowbiteDropdownItemState()], host: { '[class]': `theme().host.root`, }, }) export class DropdownItem { readonly config = injectFlowbiteDropdownItemConfig(); readonly dropdownState = injectFlowbiteDropdownState(); /** * @see {@link injectFlowbiteDropdownItemConfig} */ readonly customTheme = input>(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.dropdownState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteDropdownItemState(this); } ================================================ FILE: libs/flowbite-angular/dropdown/src/dropdown-item/theme.ts ================================================ import type { FLowbiteDropdownColors } from '../dropdown/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteDropdownItemTheme { host: FlowbiteDropdownItemHostTheme; } export interface FlowbiteDropdownItemHostTheme { base: string; transition: string; color: FLowbiteDropdownColors; } export const flowbiteDropdownItemTheme: FlowbiteDropdownItemTheme = createTheme({ host: { base: 'flex cursor-pointer items-center justify-between px-4 py-2 font-medium', transition: '', color: { default: { light: 'data-hover:bg-gray-100', dark: 'dark:data-hover:bg-gray-700 dark:data-hover:text-white', }, info: { light: 'data-hover:bg-blue-100', dark: 'dark:data-hover:bg-blue-700 dark:data-hover:text-white', }, failure: { light: 'data-hover:bg-red-100', dark: 'dark:data-hover:bg-red-700 dark:data-hover:text-white', }, success: { light: 'data-hover:bg-green-100', dark: 'dark:data-hover:bg-green-700 dark:data-hover:text-white', }, warning: { light: 'data-hover:bg-yellow-100', dark: 'dark:data-hover:bg-yellow-700 dark:data-hover:text-white', }, primary: { light: 'data-hover:bg-primary-100', dark: 'dark:data-hover:bg-primary-700 dark:data-hover:text-white', }, }, }, }); ================================================ FILE: libs/flowbite-angular/dropdown/src/index.ts ================================================ /* Dropdown */ export * from './dropdown/dropdown.directive'; export * from './dropdown/dropdown-state'; export * from './dropdown/theme'; /* Config */ export * from './config/dropdown-config'; /* DropdownItem */ export * from './dropdown-item/dropdown-item.directive'; export * from './dropdown-item/dropdown-item-state'; export * from './dropdown-item/theme'; /* Config */ export * from './config/dropdown-item-config'; /* DropdownContent */ export * from './dropdown-content/dropdown-content.directive'; export * from './dropdown-content/dropdown-content-state'; export * from './dropdown-content/theme'; /* Config */ export * from './config/dropdown-content-config'; ================================================ FILE: libs/flowbite-angular/form/README.md ================================================ # flowbite-angular/form Secondary entry point of `flowbite-angular`. It can be used by importing from `flowbite-angular/form`. ================================================ FILE: libs/flowbite-angular/form/ng-package.json ================================================ { "lib": { "entryFile": "./src/index.ts" } } ================================================ FILE: libs/flowbite-angular/form/src/config/form-control-config.ts ================================================ import { flowbiteFormControlTheme, type FlowbiteFormControlTheme } from '../form-control/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteFormControlConfig { /** * The default theme of FormControl */ baseTheme: FlowbiteFormControlTheme; /** * The custom theme of FormControl */ customTheme: DeepPartial; } export const defaultFlowbiteFormControlConfig: FlowbiteFormControlConfig = { baseTheme: flowbiteFormControlTheme, customTheme: {}, }; export const FlowbiteFormControlConfigToken = new InjectionToken( 'FlowbiteFormControlConfigToken' ); /** * Provide the default FormControl configuration * @param config The FormControl configuration * @returns The provider */ export const provideFlowbiteFormControlConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteFormControlConfigToken, useValue: { ...defaultFlowbiteFormControlConfig, ...config }, }, ]; /** * Inject the FormControl configuration * @see {@link defaultFlowbiteFormControlConfig} * @returns The configuration */ export const injectFlowbiteFormControlConfig = (): FlowbiteFormControlConfig => inject(FlowbiteFormControlConfigToken, { optional: true }) ?? defaultFlowbiteFormControlConfig; ================================================ FILE: libs/flowbite-angular/form/src/config/form-field-config.ts ================================================ import type { FlowbiteFormFieldColors, FlowbiteFormFieldModes, FlowbiteFormFieldSizes, } from '../form-field/theme'; import { flowbiteFormFieldTheme, type FlowbiteFormFieldTheme } from '../form-field/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteFormFieldConfig { /** * The default theme of FormField */ baseTheme: FlowbiteFormFieldTheme; /** * The default size of FormField */ size: keyof FlowbiteFormFieldSizes; /** * The default color of FormField */ color: keyof FlowbiteFormFieldColors; /** * The default mode of FormField */ mode: keyof FlowbiteFormFieldModes; /** * The custom theme of FormField */ customTheme: DeepPartial; } export const defaultFlowbiteFormFieldConfig: FlowbiteFormFieldConfig = { baseTheme: flowbiteFormFieldTheme, size: 'md', color: 'default', mode: 'normal', customTheme: {}, }; export const FlowbiteFormFieldConfigToken = new InjectionToken( 'FlowbiteFormFieldConfigToken' ); /** * Provide the default FormField configuration * @param config The FormField configuration * @returns The provider */ export const provideFlowbiteFormFieldConfig = ( config: Partial ): Provider[] => [ { provide: FlowbiteFormFieldConfigToken, useValue: { ...defaultFlowbiteFormFieldConfig, ...config }, }, ]; /** * Inject the FormField configuration * @see {@link defaultFlowbiteFormFieldConfig} * @returns The configuration */ export const injectFlowbiteFormFieldConfig = (): FlowbiteFormFieldConfig => inject(FlowbiteFormFieldConfigToken, { optional: true }) ?? defaultFlowbiteFormFieldConfig; ================================================ FILE: libs/flowbite-angular/form/src/config/helper-config.ts ================================================ import { flowbiteHelperTheme, type FlowbiteHelperTheme } from '../helper/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteHelperConfig { /** * The default theme of helper */ baseTheme: FlowbiteHelperTheme; /** * The custom theme of helper */ customTheme: DeepPartial; } export const defaultFlowbiteHelperConfig: FlowbiteHelperConfig = { baseTheme: flowbiteHelperTheme, customTheme: {}, }; export const FlowbiteHelperConfigToken = new InjectionToken( 'FlowbiteHelperConfigToken' ); /** * Provide the default Helper configuration * @param config The Helper configuration * @returns The provider */ export const provideFlowbiteHelperConfig = (config: Partial): Provider[] => [ { provide: FlowbiteHelperConfigToken, useValue: { ...defaultFlowbiteHelperConfig, ...config }, }, ]; /** * Inject the Helper configuration * @see {@link defaultFlowbiteHelperConfig} * @returns The configuration */ export const injectFlowbiteHelperConfig = (): FlowbiteHelperConfig => inject(FlowbiteHelperConfigToken, { optional: true }) ?? defaultFlowbiteHelperConfig; ================================================ FILE: libs/flowbite-angular/form/src/config/label-config.ts ================================================ import { flowbiteLabelTheme, type FlowbiteLabelTheme } from '../label/theme'; import type { DeepPartial } from 'flowbite-angular'; import type { Provider } from '@angular/core'; import { inject, InjectionToken } from '@angular/core'; export interface FlowbiteLabelConfig { /** * The default theme of Label */ baseTheme: FlowbiteLabelTheme; /** * The custom theme of Label */ customTheme: DeepPartial; } export const defaultFlowbiteLabelConfig: FlowbiteLabelConfig = { baseTheme: flowbiteLabelTheme, customTheme: {}, }; export const FlowbiteLabelConfigToken = new InjectionToken( 'FlowbiteLabelConfigToken' ); /** * Provide the default Label configuration * @param config The Label configuration * @returns The provider */ export const provideFlowbiteLabelConfig = (config: Partial): Provider[] => [ { provide: FlowbiteLabelConfigToken, useValue: { ...defaultFlowbiteLabelConfig, ...config }, }, ]; /** * Inject the Label configuration * @see {@link defaultFlowbiteLabelConfig} * @returns The configuration */ export const injectFlowbiteLabelConfig = (): FlowbiteLabelConfig => inject(FlowbiteLabelConfigToken, { optional: true }) ?? defaultFlowbiteLabelConfig; ================================================ FILE: libs/flowbite-angular/form/src/form-control/form-control-state.ts ================================================ import type { FormControl } from './form-control.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteFormControlStateToken = createStateToken('Flowbite FormControl'); export const provideFlowbiteFormControlState = createStateProvider(FlowbiteFormControlStateToken); export const injectFlowbiteFormControlState = createStateInjector(FlowbiteFormControlStateToken); export const flowbiteFormControlState = createState(FlowbiteFormControlStateToken); ================================================ FILE: libs/flowbite-angular/form/src/form-control/form-control.directive.ts ================================================ import { injectFlowbiteFormControlConfig } from '../config/form-control-config'; import { injectFlowbiteFormFieldState } from '../form-field/form-field-state'; import { flowbiteFormControlState, provideFlowbiteFormControlState } from './form-control-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpInput } from 'ng-primitives/input'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` [flowbiteFormControl] `, exportAs: 'flowbiteFormControl', hostDirectives: [ { directive: NgpInput, inputs: ['id:id', 'disabled:disabled'], outputs: [], }, ], providers: [provideFlowbiteFormControlState()], host: { '[class]': `theme().host.root` }, }) export class FormControl { readonly config = injectFlowbiteFormControlConfig(); readonly formFieldState = injectFlowbiteFormFieldState(); /** * @see {@link injectFlowbiteFormControlConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, mergedTheme.host.disabled, colorToTheme(mergedTheme.host.color, this.formFieldState().color()), mergedTheme.host.mode[this.formFieldState().mode()], mergedTheme.host.size[this.formFieldState().size()] ), }, }; }); /** * @internal */ readonly state = flowbiteFormControlState(this); } ================================================ FILE: libs/flowbite-angular/form/src/form-control/theme.ts ================================================ import type { FlowbiteFormFieldColors, FlowbiteFormFieldModes, FlowbiteFormFieldSizes, } from '../form-field/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteFormControlTheme { host: FlowbiteFormControlHostTheme; } export interface FlowbiteFormControlHostTheme { base: string; transition: string; disabled: string; size: FlowbiteFormFieldSizes; color: FlowbiteFormFieldColors; mode: FlowbiteFormFieldModes; } export const flowbiteFormControlTheme: FlowbiteFormControlTheme = createTheme({ host: { base: 'block w-full text-sm', transition: '', disabled: 'data-disabled:cursor-not-allowed', size: { sm: 'p-2', md: 'p-2.5', xl: 'p-3', }, color: { default: { light: 'border-gray-300 bg-gray-50 text-gray-900 outline-gray-200', dark: 'dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:outline-gray-700', }, info: { light: 'border-blue-300 bg-gray-50 text-blue-900 outline-blue-200', dark: 'dark:border-blue-600 dark:bg-gray-700 dark:text-blue-500 dark:placeholder-blue-400 dark:outline-blue-700', }, failure: { light: 'border-red-300 bg-gray-50 text-red-900 outline-red-200', dark: 'dark:border-red-600 dark:bg-gray-700 dark:text-red-500 dark:placeholder-red-400 dark:outline-red-700', }, success: { light: 'border-green-300 bg-gray-50 text-green-900 outline-green-200', dark: 'dark:border-green-600 dark:bg-gray-700 dark:text-green-500 dark:placeholder-green-400 dark:outline-green-700', }, warning: { light: 'border-yellow-300 bg-gray-50 text-yellow-900 outline-yellow-200', dark: 'dark:border-yellow-600 dark:bg-gray-700 dark:text-yellow-500 dark:placeholder-yellow-400 dark:outline-yellow-700', }, primary: { light: 'border-primary-300 text-primary-900 outline-primary-200 bg-gray-50', dark: 'dark:border-primary-600 dark:text-primary-500 dark:placeholder-primary-400 dark:outline-primary-700 dark:bg-gray-700', }, }, mode: { normal: 'rounded-lg border data-focus:outline-2', floating: 'peer appearance-none border-b-2 bg-transparent px-0 not-data-focus:border-gray-300 data-focus:outline-0 dark:bg-transparent', }, }, }); ================================================ FILE: libs/flowbite-angular/form/src/form-field/form-field-state.ts ================================================ import type { FormField } from './form-field.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteFormFieldStateToken = createStateToken('Flowbite FormField'); export const provideFlowbiteFormFieldState = createStateProvider(FlowbiteFormFieldStateToken); export const injectFlowbiteFormFieldState = createStateInjector(FlowbiteFormFieldStateToken); export const flowbiteFormFieldState = createState(FlowbiteFormFieldStateToken); ================================================ FILE: libs/flowbite-angular/form/src/form-field/form-field.directive.ts ================================================ import { injectFlowbiteFormFieldConfig } from '../config/form-field-config'; import { flowbiteFormFieldState, provideFlowbiteFormFieldState } from './form-field-state'; import { mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpFormField } from 'ng-primitives/form-field'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` div[flowbiteFormField] `, exportAs: 'flowbiteFormField', hostDirectives: [ { directive: NgpFormField, inputs: [], outputs: [], }, ], providers: [provideFlowbiteFormFieldState()], host: { '[class]': `theme().host.root` }, }) export class FormField { readonly config = injectFlowbiteFormFieldConfig(); /** * @see {@link injectFlowbiteFormFieldConfig} */ readonly size = input(this.config.size); /** * @see {@link injectFlowbiteFormFieldConfig} */ readonly color = input(this.config.color); /** * @see {@link injectFlowbiteFormFieldConfig} */ readonly mode = input(this.config.mode); /** * @see {@link injectFlowbiteFormFieldConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, mergedTheme.host.mode[this.state.mode()] ), }, }; }); /** * @internal */ readonly state = flowbiteFormFieldState(this); } ================================================ FILE: libs/flowbite-angular/form/src/form-field/theme.ts ================================================ import type { ColorToTheme, FlowbiteColors, FlowbiteSizes } from 'flowbite-angular'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteFormFieldColors extends Pick { [key: string]: ColorToTheme; } export interface FlowbiteFormFieldSizes extends Pick { [ket: string]: string; } export interface FlowbiteFormFieldModes { normal: string; floating: string; [key: string]: string; } export interface FlowbiteFormFieldTheme { host: FlowbiteFormFieldHostTheme; } export interface FlowbiteFormFieldHostTheme { base: string; transition: string; mode: FlowbiteFormFieldModes; } export const flowbiteFormFieldTheme: FlowbiteFormFieldTheme = createTheme({ host: { base: 'mb-5', transition: '', mode: { normal: 'block', floating: 'group relative z-0', }, }, }); ================================================ FILE: libs/flowbite-angular/form/src/helper/helper-state.ts ================================================ import type { Helper } from './helper.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteHelperStateToken = createStateToken('Flowbite Helper'); export const provideFlowbiteHelperState = createStateProvider(FlowbiteHelperStateToken); export const injectFlowbiteHelperState = createStateInjector(FlowbiteHelperStateToken); export const flowbiteHelperState = createState(FlowbiteHelperStateToken); ================================================ FILE: libs/flowbite-angular/form/src/helper/helper.directive.ts ================================================ import { injectFlowbiteHelperConfig } from '../config/helper-config'; import { injectFlowbiteFormFieldState } from '../form-field/form-field-state'; import type { FlowbiteFormFieldColors } from '../form-field/theme'; import { flowbiteHelperState, provideFlowbiteHelperState } from './helper-state'; import { colorToTheme, mergeDeep } from 'flowbite-angular'; import { computed, Directive, input } from '@angular/core'; import { NgpDescription } from 'ng-primitives/form-field'; import { twMerge } from 'tailwind-merge'; @Directive({ standalone: true, selector: ` [flowbiteHelper] `, exportAs: 'flowbiteHelper', hostDirectives: [ { directive: NgpDescription, inputs: ['id:id'], outputs: [], }, ], providers: [provideFlowbiteHelperState()], host: { '[class]': `theme().host.root` }, }) export class Helper { readonly config = injectFlowbiteHelperConfig(); readonly formFieldState = injectFlowbiteFormFieldState(); /** * @see {@link injectFlowbiteFormFieldState} */ readonly color = input(); /** * @see {@link injectFlowbiteHelperConfig} */ readonly customTheme = input(this.config.customTheme); readonly theme = computed(() => { const mergedTheme = mergeDeep(this.config.baseTheme, this.state.customTheme()); return { host: { root: twMerge( mergedTheme.host.base, mergedTheme.host.transition, colorToTheme(mergedTheme.host.color, this.state.color() ?? this.formFieldState().color()) ), }, }; }); /** * @internal */ readonly state = flowbiteHelperState(this); } ================================================ FILE: libs/flowbite-angular/form/src/helper/theme.ts ================================================ import type { FlowbiteFormFieldColors } from '../form-field/theme'; import { createTheme } from 'flowbite-angular'; export interface FlowbiteHelperTheme { host: FlowbiteHelperHostTheme; } export interface FlowbiteHelperHostTheme { base: string; transition: string; color: FlowbiteFormFieldColors; } export const flowbiteHelperTheme: FlowbiteHelperTheme = createTheme({ host: { base: 'mt-2 text-sm', transition: '', color: { default: { light: 'text-gray-900', dark: 'dark:text-white', }, info: { light: 'text-gray-900', dark: 'dark:text-white', }, failure: { light: 'text-gray-900', dark: 'dark:text-white', }, success: { light: 'text-gray-900', dark: 'dark:text-white', }, warning: { light: 'text-gray-900', dark: 'dark:text-white', }, primary: { light: 'text-gray-900', dark: 'dark:text-white', }, }, }, }); ================================================ FILE: libs/flowbite-angular/form/src/index.ts ================================================ /* Label */ export * from './label/label.directive'; export * from './label/label-state'; export * from './label/theme'; /* Config */ export * from './config/label-config'; /* Helper */ export * from './helper/helper.directive'; export * from './helper/helper-state'; export * from './helper/theme'; /* Config */ export * from './config/helper-config'; /* FormField */ export * from './form-field/form-field.directive'; export * from './form-field/form-field-state'; export * from './form-field/theme'; /* Config */ export * from './config/form-field-config'; /* FormControl */ export * from './form-control/form-control.directive'; export * from './form-control/form-control-state'; export * from './form-control/theme'; /* Config */ export * from './config/form-control-config'; ================================================ FILE: libs/flowbite-angular/form/src/label/label-state.ts ================================================ import type { Label } from './label.directive'; import { createState, createStateInjector, createStateProvider, createStateToken, } from 'ng-primitives/state'; export const FlowbiteLabelStateToken = createStateToken