├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
└── settings.json
├── LICENSE.md
├── README.md
├── apps
├── docs
│ ├── .gitignore
│ ├── app
│ │ ├── (home)
│ │ │ ├── layout.tsx
│ │ │ └── page.tsx
│ │ ├── docs
│ │ │ ├── [[...slug]]
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ └── not-found.tsx
│ │ ├── error.tsx
│ │ ├── layout-preview
│ │ │ └── dashboard
│ │ │ │ └── [id]
│ │ │ │ ├── DashboardLayout.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ └── not-found.tsx
│ ├── components.json
│ ├── content
│ │ └── docs
│ │ │ ├── guide
│ │ │ ├── cli.mdx
│ │ │ ├── data-fetching-api-client.mdx
│ │ │ ├── data-fetching-enhance-ux.mdx
│ │ │ ├── data-fetching-invalidation.mdx
│ │ │ ├── data-fetching-overview.mdx
│ │ │ ├── decisions-on-dx.mdx
│ │ │ ├── form-basic.mdx
│ │ │ ├── form-conditional-fields.mdx
│ │ │ ├── form-dependant-validation.mdx
│ │ │ ├── form-field-array.mdx
│ │ │ ├── form-large.mdx
│ │ │ ├── form-overview.mdx
│ │ │ ├── form-submission-errors.mdx
│ │ │ ├── form-validation.mdx
│ │ │ ├── form-with-loading.mdx
│ │ │ ├── installation.mdx
│ │ │ ├── introduction.mdx
│ │ │ ├── philosophy.mdx
│ │ │ ├── react-code-convention.mdx
│ │ │ ├── react-folder-structure.mdx
│ │ │ └── tech-stack.mdx
│ │ │ └── ui
│ │ │ ├── accordion.mdx
│ │ │ ├── avatar.mdx
│ │ │ ├── button.mdx
│ │ │ ├── calendar.mdx
│ │ │ ├── checkbox.mdx
│ │ │ ├── combobox.mdx
│ │ │ ├── confirm-dialog.mdx
│ │ │ ├── data-table.mdx
│ │ │ ├── date-field.mdx
│ │ │ ├── date-picker.mdx
│ │ │ ├── date-range-picker.mdx
│ │ │ ├── dialog.mdx
│ │ │ ├── file-trigger.mdx
│ │ │ ├── input.mdx
│ │ │ ├── loading-overlay.mdx
│ │ │ ├── menu.mdx
│ │ │ ├── nprogress.mdx
│ │ │ ├── number-field.mdx
│ │ │ ├── pagination.mdx
│ │ │ ├── popover.mdx
│ │ │ ├── radio-group.mdx
│ │ │ ├── range-calendar.mdx
│ │ │ ├── select.mdx
│ │ │ ├── separator.mdx
│ │ │ ├── sheet.mdx
│ │ │ ├── sidebar.mdx
│ │ │ ├── skeleton.mdx
│ │ │ ├── sonner.mdx
│ │ │ ├── spinner.mdx
│ │ │ ├── switch.mdx
│ │ │ ├── table.mdx
│ │ │ ├── textarea.mdx
│ │ │ ├── time-field.mdx
│ │ │ ├── tooltip.mdx
│ │ │ ├── unused.mdx
│ │ │ └── uploader.mdx
│ ├── contentlayer.config.ts
│ ├── eslint.config.js
│ ├── features
│ │ ├── docs
│ │ │ └── components
│ │ │ │ ├── Article.tsx
│ │ │ │ └── TocPortal.tsx
│ │ └── home
│ │ │ └── components
│ │ │ ├── FeatureSection.tsx
│ │ │ ├── FooterSection.tsx
│ │ │ ├── HeroSection.tsx
│ │ │ └── HomePage.tsx
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── public
│ │ ├── favicon.ico
│ │ ├── hero-background.webp
│ │ ├── images
│ │ │ ├── folder-feature-based.avif
│ │ │ ├── folder-features.avif
│ │ │ ├── folder-import-flow.avif
│ │ │ ├── folder-overview.avif
│ │ │ ├── folder-routing.avif
│ │ │ ├── folder-shared.avif
│ │ │ └── og-image-2.jpg
│ │ └── logo.png
│ ├── shared
│ │ ├── actions
│ │ │ └── examples
│ │ │ │ ├── payments.data.ts
│ │ │ │ ├── payments.ts
│ │ │ │ └── payments.type.ts
│ │ ├── components
│ │ │ ├── CopyToClipboard.tsx
│ │ │ ├── Logo.tsx
│ │ │ ├── ProjectFeatures.tsx
│ │ │ ├── Providers.tsx
│ │ │ ├── ThemeSwitcher.tsx
│ │ │ ├── Toc.tsx
│ │ │ ├── examples
│ │ │ │ ├── AccordionDemo.tsx
│ │ │ │ ├── AvatarDemo.tsx
│ │ │ │ ├── AvatarSizes.tsx
│ │ │ │ ├── ButtonAsALink.tsx
│ │ │ │ ├── ButtonDemo.tsx
│ │ │ │ ├── ButtonDestructive.tsx
│ │ │ │ ├── ButtonGhost.tsx
│ │ │ │ ├── ButtonIcon.tsx
│ │ │ │ ├── ButtonLoading.tsx
│ │ │ │ ├── ButtonOutline.tsx
│ │ │ │ ├── ButtonWithIcon.tsx
│ │ │ │ ├── CalendarControlled.tsx
│ │ │ │ ├── CalendarDemo.tsx
│ │ │ │ ├── CalendarMinMax.tsx
│ │ │ │ ├── CalendarUnstyled.tsx
│ │ │ │ ├── CheckboxDemo.tsx
│ │ │ │ ├── CheckboxDisabled.tsx
│ │ │ │ ├── CheckboxForm.tsx
│ │ │ │ ├── CheckboxGroupDemo.tsx
│ │ │ │ ├── CheckboxIndeterminate.tsx
│ │ │ │ ├── ConfirmDialogDemo.tsx
│ │ │ │ ├── ConfirmDialogDestructive.tsx
│ │ │ │ ├── DataTableColumnAlignment.tsx
│ │ │ │ ├── DataTableDemo.tsx
│ │ │ │ ├── DataTableLoadingState.tsx
│ │ │ │ ├── DataTableRealworld.tsx
│ │ │ │ ├── DataTableRowSelection.tsx
│ │ │ │ ├── DataTableSorting.tsx
│ │ │ │ ├── DataTableSticky.tsx
│ │ │ │ ├── DateFieldDemo.tsx
│ │ │ │ ├── DateFieldDisabled.tsx
│ │ │ │ ├── DateFieldForm.tsx
│ │ │ │ ├── DateFieldWithLabel.tsx
│ │ │ │ ├── DatePickerDemo.tsx
│ │ │ │ ├── DatePickerDisabled.tsx
│ │ │ │ ├── DatePickerForm.tsx
│ │ │ │ ├── DatePickerWithLabel.tsx
│ │ │ │ ├── DateRangePickerDemo.tsx
│ │ │ │ ├── DateRangePickerDisabled.tsx
│ │ │ │ ├── DateRangePickerForm.tsx
│ │ │ │ ├── DateRangePickerWithLabel.tsx
│ │ │ │ ├── DialogDemo.tsx
│ │ │ │ ├── FileTriggerAvatar.tsx
│ │ │ │ ├── FileTriggerDemo.tsx
│ │ │ │ ├── InputDemo.tsx
│ │ │ │ ├── InputDisabled.tsx
│ │ │ │ ├── InputFile.tsx
│ │ │ │ ├── InputForm.tsx
│ │ │ │ ├── InputWithButton.tsx
│ │ │ │ ├── InputWithLabel.tsx
│ │ │ │ ├── LoadingOverlayDemo.tsx
│ │ │ │ ├── MenuDemo.tsx
│ │ │ │ ├── MenuWithIcon.tsx
│ │ │ │ ├── MenuWithKeyboard.tsx
│ │ │ │ ├── MenuWithSubmenu.tsx
│ │ │ │ ├── NProgressDemo.tsx
│ │ │ │ ├── NumberFieldCurrency.tsx
│ │ │ │ ├── NumberFieldDemo.tsx
│ │ │ │ ├── NumberFieldDisabled.tsx
│ │ │ │ ├── NumberFieldForm.tsx
│ │ │ │ ├── NumberFieldMinMax.tsx
│ │ │ │ ├── NumberFieldPercentages.tsx
│ │ │ │ ├── NumberFieldUnits.tsx
│ │ │ │ ├── NumberFieldWithLabel.tsx
│ │ │ │ ├── NumberFieldWithoutStepper.tsx
│ │ │ │ ├── PaginationDemo.tsx
│ │ │ │ ├── PaginationWithPageSelector.tsx
│ │ │ │ ├── PaginationWithQueryParams.tsx
│ │ │ │ ├── PopoverBottomRight.tsx
│ │ │ │ ├── PopoverDemo.tsx
│ │ │ │ ├── RadioGroupDemo.tsx
│ │ │ │ ├── RadioGroupDisabled.tsx
│ │ │ │ ├── RadioGroupForm.tsx
│ │ │ │ ├── RadioGroupHorizontal.tsx
│ │ │ │ ├── RangeCalendarControlled.tsx
│ │ │ │ ├── RangeCalendarDefault.tsx
│ │ │ │ ├── RangeCalendarDemo.tsx
│ │ │ │ ├── RangeCalendarMinMax.tsx
│ │ │ │ ├── RangeCalendarUnstyled.tsx
│ │ │ │ ├── RecDependantValidation.tsx
│ │ │ │ ├── RecFormBasic.tsx
│ │ │ │ ├── RecFormConditionalFields.tsx
│ │ │ │ ├── RecFormFieldArray.tsx
│ │ │ │ ├── RecFormLargeForm.tsx
│ │ │ │ ├── RecFormSubmissionErrors.tsx
│ │ │ │ ├── RecFormValidation.tsx
│ │ │ │ ├── RecFormWithLoading.tsx
│ │ │ │ ├── SelectCustom.tsx
│ │ │ │ ├── SelectDemo.tsx
│ │ │ │ ├── SelectDisabled.tsx
│ │ │ │ ├── SelectForm.tsx
│ │ │ │ ├── SelectMultiple.tsx
│ │ │ │ ├── SelectMultipleCustomization.tsx
│ │ │ │ ├── SelectMultipleDisabled.tsx
│ │ │ │ ├── SelectMultipleSearchable.tsx
│ │ │ │ ├── SelectSearchable.tsx
│ │ │ │ ├── SelectWithClearButton.tsx
│ │ │ │ ├── SeparatorDemo.tsx
│ │ │ │ ├── SheetDemo.tsx
│ │ │ │ ├── SkeletonDemo.tsx
│ │ │ │ ├── SkeletonScreen.tsx
│ │ │ │ ├── SonnerDemo.tsx
│ │ │ │ ├── SpinnerDemo.tsx
│ │ │ │ ├── SwitchDemo.tsx
│ │ │ │ ├── SwitchDisabled.tsx
│ │ │ │ ├── SwitchForm.tsx
│ │ │ │ ├── TableDemo.tsx
│ │ │ │ ├── TextAreaDemo.tsx
│ │ │ │ ├── TextAreaDisabled.tsx
│ │ │ │ ├── TextAreaForm.tsx
│ │ │ │ ├── TextAreaWithButton.tsx
│ │ │ │ ├── TextAreaWithLabel.tsx
│ │ │ │ ├── TimeFieldDemo.tsx
│ │ │ │ ├── TimeFieldDisabled.tsx
│ │ │ │ ├── TimeFieldForm.tsx
│ │ │ │ ├── TimeFieldGranularity.tsx
│ │ │ │ ├── TimeFieldWithLabel.tsx
│ │ │ │ ├── TooltipBasic.tsx
│ │ │ │ ├── TooltipCustom.tsx
│ │ │ │ ├── TooltipDemo.tsx
│ │ │ │ ├── UploaderCustom.tsx
│ │ │ │ ├── UploaderDemo.tsx
│ │ │ │ ├── UploaderDemo.utils.ts
│ │ │ │ ├── UploaderDisabled.tsx
│ │ │ │ ├── UploaderForm.tsx
│ │ │ │ ├── UploaderRetry.tsx
│ │ │ │ ├── UploaderValidation.tsx
│ │ │ │ ├── UploaderVariantListType.tsx
│ │ │ │ └── UploaderVariantTriggerType.tsx
│ │ │ ├── icons
│ │ │ │ ├── GithubIcon.tsx
│ │ │ │ ├── NextJsIcon.tsx
│ │ │ │ ├── ReactAriaIcon.tsx
│ │ │ │ ├── ReactIcon.tsx
│ │ │ │ ├── ReactQueryIcon.tsx
│ │ │ │ ├── ShadcnIcon.tsx
│ │ │ │ └── ViteIcon.tsx
│ │ │ └── mdx-helpers
│ │ │ │ ├── CodeCollapsible.tsx
│ │ │ │ ├── ComponentPreview.tsx
│ │ │ │ ├── Mdx.tsx
│ │ │ │ ├── MdxImage.tsx
│ │ │ │ ├── MdxSnippet.tsx
│ │ │ │ └── MdxTip.tsx
│ │ ├── consts
│ │ │ └── common.ts
│ │ ├── hooks
│ │ │ └── useMounted.tsx
│ │ ├── layouts
│ │ │ ├── DocsLayout
│ │ │ │ ├── DocContent.tsx
│ │ │ │ ├── HamburgerMenu.tsx
│ │ │ │ ├── Icons.tsx
│ │ │ │ ├── ModulePicker.tsx
│ │ │ │ ├── SidebarHeader.tsx
│ │ │ │ ├── SidebarMenu.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── DocsSearch.tsx
│ │ │ ├── HeaderIconButtons.tsx
│ │ │ ├── LandingPageLayout
│ │ │ │ └── index.tsx
│ │ │ └── TopNavLinks.tsx
│ │ └── lib
│ │ │ ├── composition.ts
│ │ │ ├── highlight-code.ts
│ │ │ └── toc.ts
│ └── tsconfig.json
├── next
│ ├── components.json
│ ├── eslint.config.js
│ ├── next-env.d.ts
│ ├── next.config.mjs
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── src
│ │ ├── app
│ │ │ ├── favicon.ico
│ │ │ ├── layout.tsx
│ │ │ └── page.tsx
│ │ └── shared
│ │ │ ├── components
│ │ │ ├── Providers.tsx
│ │ │ └── ThemeSwitcher.tsx
│ │ │ ├── hooks
│ │ │ └── useMounted.tsx
│ │ │ ├── layouts
│ │ │ └── DashboardLayout.tsx
│ │ │ └── lib
│ │ │ └── api.ts
│ └── tsconfig.json
└── tanstack-router
│ ├── .gitignore
│ ├── .vscode
│ └── settings.json
│ ├── README.md
│ ├── eslint.config.js
│ ├── index.html
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── src
│ ├── main.tsx
│ ├── routeTree.gen.ts
│ ├── routes
│ │ ├── __root.tsx
│ │ └── index.tsx
│ └── shared
│ │ ├── components
│ │ ├── Providers.tsx
│ │ ├── ThemeProvider.tsx
│ │ └── ThemeSwitcher.tsx
│ │ ├── layouts
│ │ └── DashboardLayout.tsx
│ │ └── lib
│ │ └── api.ts
│ ├── tsconfig.json
│ └── vite.config.js
├── images
└── project-preview-1.png
├── lefthook.yml
├── package.json
├── packages
├── eslint-config
│ ├── README.md
│ ├── base.js
│ ├── next.js
│ ├── package.json
│ └── react-internal.js
├── lib
│ ├── eslint.config.js
│ ├── package.json
│ ├── src
│ │ ├── api
│ │ │ ├── index.ts
│ │ │ └── sdk
│ │ │ │ ├── example.api.ts
│ │ │ │ └── example.type.ts
│ │ └── validation
│ │ │ └── index.ts
│ └── tsconfig.json
├── typescript-config
│ ├── README.md
│ ├── base.json
│ ├── nextjs.json
│ ├── package.json
│ └── react-library.json
└── ui
│ ├── components.json
│ ├── eslint.config.js
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── src
│ ├── components
│ │ ├── Accordion.tsx
│ │ ├── Avatar.tsx
│ │ ├── Badge.tsx
│ │ ├── Breadcrumbs.tsx
│ │ ├── Button.tsx
│ │ ├── Calendar.helper.tsx
│ │ ├── Calendar.tsx
│ │ ├── Card.tsx
│ │ ├── Checkbox.tsx
│ │ ├── Collapsible.tsx
│ │ ├── ConfirmDialog.tsx
│ │ ├── DataTable.tsx
│ │ ├── DataTable.utils.tsx
│ │ ├── DatePicker.tsx
│ │ ├── Datefield.tsx
│ │ ├── Datefield.utils.ts
│ │ ├── Dialog.tsx
│ │ ├── Dropzone.tsx
│ │ ├── Field.tsx
│ │ ├── Form.tsx
│ │ ├── GridList.tsx
│ │ ├── ListBox.tsx
│ │ ├── LoadingOverlay.tsx
│ │ ├── Menu.tsx
│ │ ├── NProgress.tsx
│ │ ├── Numberfield.tsx
│ │ ├── Pagination.tsx
│ │ ├── Popover.tsx
│ │ ├── Progress.tsx
│ │ ├── Provider.tsx
│ │ ├── RadioGroup.tsx
│ │ ├── ScrollArea.tsx
│ │ ├── Searchfield.tsx
│ │ ├── Select.tsx
│ │ ├── Separator.tsx
│ │ ├── Sheet.tsx
│ │ ├── Sidebar.helpers.tsx
│ │ ├── Sidebar.tsx
│ │ ├── Skeleton.tsx
│ │ ├── Slider.tsx
│ │ ├── Sonner.tsx
│ │ ├── Spinner.tsx
│ │ ├── Switch.tsx
│ │ ├── Table.tsx
│ │ ├── Tabs.tsx
│ │ ├── Textfield.tsx
│ │ ├── Toggle.tsx
│ │ ├── Tooltip.tsx
│ │ ├── Uploader.tsx
│ │ ├── Uploader.util.tsx
│ │ ├── UploaderIcon.tsx
│ │ ├── UploaderItem.tsx
│ │ └── UploaderTrigger.tsx
│ ├── hooks
│ │ ├── .gitkeep
│ │ └── use-mobile.ts
│ ├── lib
│ │ ├── file.ts
│ │ └── utils.ts
│ └── styles
│ │ └── globals.css
│ ├── tsconfig.json
│ └── tsconfig.lint.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── scripts
└── sync-templates.ts
├── tooling
└── cli
│ ├── .gitignore
│ ├── README.md
│ ├── commands
│ ├── add.ts
│ └── init.ts
│ ├── consts.ts
│ ├── index.ts
│ ├── package.json
│ ├── templates
│ ├── base
│ │ ├── .prettierignore
│ │ ├── .prettierrc
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── README.md
│ │ ├── gitignore
│ │ ├── lefthook.yml
│ │ ├── package.json
│ │ ├── packages
│ │ │ ├── eslint-config
│ │ │ │ ├── README.md
│ │ │ │ ├── base.js
│ │ │ │ ├── next.js
│ │ │ │ ├── package.json
│ │ │ │ └── react-internal.js
│ │ │ ├── lib
│ │ │ │ ├── eslint.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── src
│ │ │ │ │ ├── api
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── sdk
│ │ │ │ │ │ │ ├── example.api.ts
│ │ │ │ │ │ │ └── example.type.ts
│ │ │ │ │ └── validation
│ │ │ │ │ │ └── index.ts
│ │ │ │ └── tsconfig.json
│ │ │ ├── typescript-config
│ │ │ │ ├── README.md
│ │ │ │ ├── base.json
│ │ │ │ ├── nextjs.json
│ │ │ │ ├── package.json
│ │ │ │ └── react-library.json
│ │ │ └── ui
│ │ │ │ ├── components.json
│ │ │ │ ├── eslint.config.js
│ │ │ │ ├── package.json
│ │ │ │ ├── postcss.config.mjs
│ │ │ │ ├── src
│ │ │ │ ├── components
│ │ │ │ │ ├── Accordion.tsx
│ │ │ │ │ ├── Avatar.tsx
│ │ │ │ │ ├── Badge.tsx
│ │ │ │ │ ├── Breadcrumbs.tsx
│ │ │ │ │ ├── Button.tsx
│ │ │ │ │ ├── Calendar.helper.tsx
│ │ │ │ │ ├── Calendar.tsx
│ │ │ │ │ ├── Card.tsx
│ │ │ │ │ ├── Checkbox.tsx
│ │ │ │ │ ├── Collapsible.tsx
│ │ │ │ │ ├── ConfirmDialog.tsx
│ │ │ │ │ ├── DataTable.tsx
│ │ │ │ │ ├── DataTable.utils.tsx
│ │ │ │ │ ├── DatePicker.tsx
│ │ │ │ │ ├── Datefield.tsx
│ │ │ │ │ ├── Datefield.utils.ts
│ │ │ │ │ ├── Dialog.tsx
│ │ │ │ │ ├── Dropzone.tsx
│ │ │ │ │ ├── Field.tsx
│ │ │ │ │ ├── Form.tsx
│ │ │ │ │ ├── GridList.tsx
│ │ │ │ │ ├── ListBox.tsx
│ │ │ │ │ ├── LoadingOverlay.tsx
│ │ │ │ │ ├── Menu.tsx
│ │ │ │ │ ├── NProgress.tsx
│ │ │ │ │ ├── Numberfield.tsx
│ │ │ │ │ ├── Pagination.tsx
│ │ │ │ │ ├── Popover.tsx
│ │ │ │ │ ├── Progress.tsx
│ │ │ │ │ ├── Provider.tsx
│ │ │ │ │ ├── RadioGroup.tsx
│ │ │ │ │ ├── ScrollArea.tsx
│ │ │ │ │ ├── Searchfield.tsx
│ │ │ │ │ ├── Select.tsx
│ │ │ │ │ ├── Separator.tsx
│ │ │ │ │ ├── Sheet.tsx
│ │ │ │ │ ├── Sidebar.helpers.tsx
│ │ │ │ │ ├── Sidebar.tsx
│ │ │ │ │ ├── Skeleton.tsx
│ │ │ │ │ ├── Slider.tsx
│ │ │ │ │ ├── Sonner.tsx
│ │ │ │ │ ├── Spinner.tsx
│ │ │ │ │ ├── Switch.tsx
│ │ │ │ │ ├── Table.tsx
│ │ │ │ │ ├── Tabs.tsx
│ │ │ │ │ ├── Textfield.tsx
│ │ │ │ │ ├── Toggle.tsx
│ │ │ │ │ ├── Tooltip.tsx
│ │ │ │ │ ├── Uploader.tsx
│ │ │ │ │ ├── Uploader.util.tsx
│ │ │ │ │ ├── UploaderIcon.tsx
│ │ │ │ │ ├── UploaderItem.tsx
│ │ │ │ │ └── UploaderTrigger.tsx
│ │ │ │ ├── hooks
│ │ │ │ │ ├── .gitkeep
│ │ │ │ │ └── use-mobile.ts
│ │ │ │ ├── lib
│ │ │ │ │ ├── file.ts
│ │ │ │ │ └── utils.ts
│ │ │ │ └── styles
│ │ │ │ │ └── globals.css
│ │ │ │ ├── tsconfig.json
│ │ │ │ └── tsconfig.lint.json
│ │ ├── pnpm-workspace.yaml
│ │ ├── tsconfig.json
│ │ └── turbo.json
│ └── extras
│ │ └── apps
│ │ ├── docs
│ │ ├── .gitignore
│ │ ├── app
│ │ │ ├── (home)
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── docs
│ │ │ │ ├── [[...slug]]
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ └── not-found.tsx
│ │ │ ├── error.tsx
│ │ │ ├── layout-preview
│ │ │ │ └── dashboard
│ │ │ │ │ └── [id]
│ │ │ │ │ ├── DashboardLayout.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ └── not-found.tsx
│ │ ├── components.json
│ │ ├── content
│ │ │ └── docs
│ │ │ │ ├── guide
│ │ │ │ ├── cli.mdx
│ │ │ │ ├── data-fetching-api-client.mdx
│ │ │ │ ├── data-fetching-enhance-ux.mdx
│ │ │ │ ├── data-fetching-invalidation.mdx
│ │ │ │ ├── data-fetching-overview.mdx
│ │ │ │ ├── decisions-on-dx.mdx
│ │ │ │ ├── form-basic.mdx
│ │ │ │ ├── form-conditional-fields.mdx
│ │ │ │ ├── form-dependant-validation.mdx
│ │ │ │ ├── form-field-array.mdx
│ │ │ │ ├── form-large.mdx
│ │ │ │ ├── form-overview.mdx
│ │ │ │ ├── form-submission-errors.mdx
│ │ │ │ ├── form-validation.mdx
│ │ │ │ ├── form-with-loading.mdx
│ │ │ │ ├── installation.mdx
│ │ │ │ ├── introduction.mdx
│ │ │ │ ├── philosophy.mdx
│ │ │ │ ├── react-code-convention.mdx
│ │ │ │ ├── react-folder-structure.mdx
│ │ │ │ └── tech-stack.mdx
│ │ │ │ └── ui
│ │ │ │ ├── accordion.mdx
│ │ │ │ ├── avatar.mdx
│ │ │ │ ├── button.mdx
│ │ │ │ ├── calendar.mdx
│ │ │ │ ├── checkbox.mdx
│ │ │ │ ├── combobox.mdx
│ │ │ │ ├── confirm-dialog.mdx
│ │ │ │ ├── data-table.mdx
│ │ │ │ ├── date-field.mdx
│ │ │ │ ├── date-picker.mdx
│ │ │ │ ├── date-range-picker.mdx
│ │ │ │ ├── dialog.mdx
│ │ │ │ ├── file-trigger.mdx
│ │ │ │ ├── input.mdx
│ │ │ │ ├── loading-overlay.mdx
│ │ │ │ ├── menu.mdx
│ │ │ │ ├── nprogress.mdx
│ │ │ │ ├── number-field.mdx
│ │ │ │ ├── pagination.mdx
│ │ │ │ ├── popover.mdx
│ │ │ │ ├── radio-group.mdx
│ │ │ │ ├── range-calendar.mdx
│ │ │ │ ├── select.mdx
│ │ │ │ ├── separator.mdx
│ │ │ │ ├── sheet.mdx
│ │ │ │ ├── sidebar.mdx
│ │ │ │ ├── skeleton.mdx
│ │ │ │ ├── sonner.mdx
│ │ │ │ ├── spinner.mdx
│ │ │ │ ├── switch.mdx
│ │ │ │ ├── table.mdx
│ │ │ │ ├── textarea.mdx
│ │ │ │ ├── time-field.mdx
│ │ │ │ ├── tooltip.mdx
│ │ │ │ ├── unused.mdx
│ │ │ │ └── uploader.mdx
│ │ ├── contentlayer.config.ts
│ │ ├── eslint.config.js
│ │ ├── features
│ │ │ ├── docs
│ │ │ │ └── components
│ │ │ │ │ ├── Article.tsx
│ │ │ │ │ └── TocPortal.tsx
│ │ │ └── home
│ │ │ │ └── components
│ │ │ │ ├── FeatureSection.tsx
│ │ │ │ ├── FooterSection.tsx
│ │ │ │ ├── HeroSection.tsx
│ │ │ │ └── HomePage.tsx
│ │ ├── next.config.ts
│ │ ├── package.json
│ │ ├── postcss.config.mjs
│ │ ├── public
│ │ │ ├── hero-background.webp
│ │ │ ├── images
│ │ │ │ ├── folder-feature-based.avif
│ │ │ │ ├── folder-features.avif
│ │ │ │ ├── folder-import-flow.avif
│ │ │ │ ├── folder-overview.avif
│ │ │ │ ├── folder-routing.avif
│ │ │ │ ├── folder-shared.avif
│ │ │ │ └── og-image-2.jpg
│ │ │ └── logo.png
│ │ ├── shared
│ │ │ ├── actions
│ │ │ │ └── examples
│ │ │ │ │ ├── payments.data.ts
│ │ │ │ │ ├── payments.ts
│ │ │ │ │ └── payments.type.ts
│ │ │ ├── components
│ │ │ │ ├── CopyToClipboard.tsx
│ │ │ │ ├── Logo.tsx
│ │ │ │ ├── ProjectFeatures.tsx
│ │ │ │ ├── Providers.tsx
│ │ │ │ ├── ThemeSwitcher.tsx
│ │ │ │ ├── Toc.tsx
│ │ │ │ ├── examples
│ │ │ │ │ ├── AccordionDemo.tsx
│ │ │ │ │ ├── AvatarDemo.tsx
│ │ │ │ │ ├── AvatarSizes.tsx
│ │ │ │ │ ├── ButtonAsALink.tsx
│ │ │ │ │ ├── ButtonDemo.tsx
│ │ │ │ │ ├── ButtonDestructive.tsx
│ │ │ │ │ ├── ButtonGhost.tsx
│ │ │ │ │ ├── ButtonIcon.tsx
│ │ │ │ │ ├── ButtonLoading.tsx
│ │ │ │ │ ├── ButtonOutline.tsx
│ │ │ │ │ ├── ButtonWithIcon.tsx
│ │ │ │ │ ├── CalendarControlled.tsx
│ │ │ │ │ ├── CalendarDemo.tsx
│ │ │ │ │ ├── CalendarMinMax.tsx
│ │ │ │ │ ├── CalendarUnstyled.tsx
│ │ │ │ │ ├── CheckboxDemo.tsx
│ │ │ │ │ ├── CheckboxDisabled.tsx
│ │ │ │ │ ├── CheckboxForm.tsx
│ │ │ │ │ ├── CheckboxGroupDemo.tsx
│ │ │ │ │ ├── CheckboxIndeterminate.tsx
│ │ │ │ │ ├── ConfirmDialogDemo.tsx
│ │ │ │ │ ├── ConfirmDialogDestructive.tsx
│ │ │ │ │ ├── DataTableColumnAlignment.tsx
│ │ │ │ │ ├── DataTableDemo.tsx
│ │ │ │ │ ├── DataTableLoadingState.tsx
│ │ │ │ │ ├── DataTableRealworld.tsx
│ │ │ │ │ ├── DataTableRowSelection.tsx
│ │ │ │ │ ├── DataTableSorting.tsx
│ │ │ │ │ ├── DataTableSticky.tsx
│ │ │ │ │ ├── DateFieldDemo.tsx
│ │ │ │ │ ├── DateFieldDisabled.tsx
│ │ │ │ │ ├── DateFieldForm.tsx
│ │ │ │ │ ├── DateFieldWithLabel.tsx
│ │ │ │ │ ├── DatePickerDemo.tsx
│ │ │ │ │ ├── DatePickerDisabled.tsx
│ │ │ │ │ ├── DatePickerForm.tsx
│ │ │ │ │ ├── DatePickerWithLabel.tsx
│ │ │ │ │ ├── DateRangePickerDemo.tsx
│ │ │ │ │ ├── DateRangePickerDisabled.tsx
│ │ │ │ │ ├── DateRangePickerForm.tsx
│ │ │ │ │ ├── DateRangePickerWithLabel.tsx
│ │ │ │ │ ├── DialogDemo.tsx
│ │ │ │ │ ├── FileTriggerAvatar.tsx
│ │ │ │ │ ├── FileTriggerDemo.tsx
│ │ │ │ │ ├── InputDemo.tsx
│ │ │ │ │ ├── InputDisabled.tsx
│ │ │ │ │ ├── InputFile.tsx
│ │ │ │ │ ├── InputForm.tsx
│ │ │ │ │ ├── InputWithButton.tsx
│ │ │ │ │ ├── InputWithLabel.tsx
│ │ │ │ │ ├── LoadingOverlayDemo.tsx
│ │ │ │ │ ├── MenuDemo.tsx
│ │ │ │ │ ├── MenuWithIcon.tsx
│ │ │ │ │ ├── MenuWithKeyboard.tsx
│ │ │ │ │ ├── MenuWithSubmenu.tsx
│ │ │ │ │ ├── NProgressDemo.tsx
│ │ │ │ │ ├── NumberFieldCurrency.tsx
│ │ │ │ │ ├── NumberFieldDemo.tsx
│ │ │ │ │ ├── NumberFieldDisabled.tsx
│ │ │ │ │ ├── NumberFieldForm.tsx
│ │ │ │ │ ├── NumberFieldMinMax.tsx
│ │ │ │ │ ├── NumberFieldPercentages.tsx
│ │ │ │ │ ├── NumberFieldUnits.tsx
│ │ │ │ │ ├── NumberFieldWithLabel.tsx
│ │ │ │ │ ├── NumberFieldWithoutStepper.tsx
│ │ │ │ │ ├── PaginationDemo.tsx
│ │ │ │ │ ├── PaginationWithPageSelector.tsx
│ │ │ │ │ ├── PaginationWithQueryParams.tsx
│ │ │ │ │ ├── PopoverBottomRight.tsx
│ │ │ │ │ ├── PopoverDemo.tsx
│ │ │ │ │ ├── RadioGroupDemo.tsx
│ │ │ │ │ ├── RadioGroupDisabled.tsx
│ │ │ │ │ ├── RadioGroupForm.tsx
│ │ │ │ │ ├── RadioGroupHorizontal.tsx
│ │ │ │ │ ├── RangeCalendarControlled.tsx
│ │ │ │ │ ├── RangeCalendarDefault.tsx
│ │ │ │ │ ├── RangeCalendarDemo.tsx
│ │ │ │ │ ├── RangeCalendarMinMax.tsx
│ │ │ │ │ ├── RangeCalendarUnstyled.tsx
│ │ │ │ │ ├── RecDependantValidation.tsx
│ │ │ │ │ ├── RecFormBasic.tsx
│ │ │ │ │ ├── RecFormConditionalFields.tsx
│ │ │ │ │ ├── RecFormFieldArray.tsx
│ │ │ │ │ ├── RecFormLargeForm.tsx
│ │ │ │ │ ├── RecFormSubmissionErrors.tsx
│ │ │ │ │ ├── RecFormValidation.tsx
│ │ │ │ │ ├── RecFormWithLoading.tsx
│ │ │ │ │ ├── SelectCustom.tsx
│ │ │ │ │ ├── SelectDemo.tsx
│ │ │ │ │ ├── SelectDisabled.tsx
│ │ │ │ │ ├── SelectForm.tsx
│ │ │ │ │ ├── SelectMultiple.tsx
│ │ │ │ │ ├── SelectMultipleCustomization.tsx
│ │ │ │ │ ├── SelectMultipleDisabled.tsx
│ │ │ │ │ ├── SelectMultipleSearchable.tsx
│ │ │ │ │ ├── SelectSearchable.tsx
│ │ │ │ │ ├── SelectWithClearButton.tsx
│ │ │ │ │ ├── SeparatorDemo.tsx
│ │ │ │ │ ├── SheetDemo.tsx
│ │ │ │ │ ├── SkeletonDemo.tsx
│ │ │ │ │ ├── SkeletonScreen.tsx
│ │ │ │ │ ├── SonnerDemo.tsx
│ │ │ │ │ ├── SpinnerDemo.tsx
│ │ │ │ │ ├── SwitchDemo.tsx
│ │ │ │ │ ├── SwitchDisabled.tsx
│ │ │ │ │ ├── SwitchForm.tsx
│ │ │ │ │ ├── TableDemo.tsx
│ │ │ │ │ ├── TextAreaDemo.tsx
│ │ │ │ │ ├── TextAreaDisabled.tsx
│ │ │ │ │ ├── TextAreaForm.tsx
│ │ │ │ │ ├── TextAreaWithButton.tsx
│ │ │ │ │ ├── TextAreaWithLabel.tsx
│ │ │ │ │ ├── TimeFieldDemo.tsx
│ │ │ │ │ ├── TimeFieldDisabled.tsx
│ │ │ │ │ ├── TimeFieldForm.tsx
│ │ │ │ │ ├── TimeFieldGranularity.tsx
│ │ │ │ │ ├── TimeFieldWithLabel.tsx
│ │ │ │ │ ├── TooltipBasic.tsx
│ │ │ │ │ ├── TooltipCustom.tsx
│ │ │ │ │ ├── TooltipDemo.tsx
│ │ │ │ │ ├── UploaderCustom.tsx
│ │ │ │ │ ├── UploaderDemo.tsx
│ │ │ │ │ ├── UploaderDemo.utils.ts
│ │ │ │ │ ├── UploaderDisabled.tsx
│ │ │ │ │ ├── UploaderForm.tsx
│ │ │ │ │ ├── UploaderRetry.tsx
│ │ │ │ │ ├── UploaderValidation.tsx
│ │ │ │ │ ├── UploaderVariantListType.tsx
│ │ │ │ │ └── UploaderVariantTriggerType.tsx
│ │ │ │ ├── icons
│ │ │ │ │ ├── GithubIcon.tsx
│ │ │ │ │ ├── NextJsIcon.tsx
│ │ │ │ │ ├── ReactAriaIcon.tsx
│ │ │ │ │ ├── ReactIcon.tsx
│ │ │ │ │ ├── ReactQueryIcon.tsx
│ │ │ │ │ ├── ShadcnIcon.tsx
│ │ │ │ │ └── ViteIcon.tsx
│ │ │ │ └── mdx-helpers
│ │ │ │ │ ├── CodeCollapsible.tsx
│ │ │ │ │ ├── ComponentPreview.tsx
│ │ │ │ │ ├── Mdx.tsx
│ │ │ │ │ ├── MdxImage.tsx
│ │ │ │ │ ├── MdxSnippet.tsx
│ │ │ │ │ └── MdxTip.tsx
│ │ │ ├── consts
│ │ │ │ └── common.ts
│ │ │ ├── hooks
│ │ │ │ └── useMounted.tsx
│ │ │ ├── layouts
│ │ │ │ ├── DocsLayout
│ │ │ │ │ ├── DocContent.tsx
│ │ │ │ │ ├── HamburgerMenu.tsx
│ │ │ │ │ ├── Icons.tsx
│ │ │ │ │ ├── ModulePicker.tsx
│ │ │ │ │ ├── SidebarHeader.tsx
│ │ │ │ │ ├── SidebarMenu.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── DocsSearch.tsx
│ │ │ │ ├── HeaderIconButtons.tsx
│ │ │ │ ├── LandingPageLayout
│ │ │ │ │ └── index.tsx
│ │ │ │ └── TopNavLinks.tsx
│ │ │ └── lib
│ │ │ │ ├── composition.ts
│ │ │ │ ├── highlight-code.ts
│ │ │ │ └── toc.ts
│ │ └── tsconfig.json
│ │ ├── next
│ │ ├── components.json
│ │ ├── eslint.config.js
│ │ ├── next-env.d.ts
│ │ ├── next.config.mjs
│ │ ├── package.json
│ │ ├── postcss.config.mjs
│ │ ├── src
│ │ │ ├── app
│ │ │ │ ├── favicon.ico
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ └── shared
│ │ │ │ ├── components
│ │ │ │ ├── Providers.tsx
│ │ │ │ └── ThemeSwitcher.tsx
│ │ │ │ ├── hooks
│ │ │ │ └── useMounted.tsx
│ │ │ │ ├── layouts
│ │ │ │ └── DashboardLayout.tsx
│ │ │ │ └── lib
│ │ │ │ └── api.ts
│ │ └── tsconfig.json
│ │ └── tanstack-router
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ └── settings.json
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── postcss.config.mjs
│ │ ├── src
│ │ ├── main.tsx
│ │ ├── routeTree.gen.ts
│ │ ├── routes
│ │ │ ├── __root.tsx
│ │ │ └── index.tsx
│ │ └── shared
│ │ │ ├── components
│ │ │ ├── Providers.tsx
│ │ │ ├── ThemeProvider.tsx
│ │ │ └── ThemeSwitcher.tsx
│ │ │ ├── layouts
│ │ │ └── DashboardLayout.tsx
│ │ │ └── lib
│ │ │ └── api.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.js
│ ├── tsconfig.json
│ ├── tsup.config.ts
│ └── utils
│ └── error-handling.ts
├── tsconfig.json
└── turbo.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # Local env files
9 | .env
10 | .env.local
11 | .env.development.local
12 | .env.test.local
13 | .env.production.local
14 |
15 | # Testing
16 | coverage
17 |
18 | # Turbo
19 | .turbo
20 |
21 | # Vercel
22 | .vercel
23 |
24 | # Build Outputs
25 | .next/
26 | out/
27 | build
28 | dist
29 |
30 |
31 | # Debug
32 | npm-debug.log*
33 |
34 | # Misc
35 | .DS_Store
36 | *.pem
37 |
38 | # contentlayer
39 | .contentlayer
40 |
41 | # next.js
42 | next-env.d.ts
43 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | routeTree.gen.ts
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true,
4 | "trailingComma": "all",
5 | "printWidth": 120,
6 | "tabWidth": 4,
7 | "useTabs": false,
8 | "bracketSpacing": true,
9 | "bracketSameLine": false,
10 | "jsxBracketSameLine": false,
11 | "jsxSingleQuote": false,
12 | "arrowParens": "avoid"
13 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "tailwindCSS.experimental.configFile": "packages/ui/src/styles/globals.css"
3 | }
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Base Stack
2 | This is a **React starter kit** that provides an opinionated, production-ready foundation for building modern web applications. It's designed to give you everything you need to start building immediately, with carefully chosen tools and patterns that work together seamlessly.
3 |
4 | 
5 |
6 | ## Documentation
7 | https://base-stack.dev
8 |
--------------------------------------------------------------------------------
/apps/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 |
32 | # env files (can opt-in for commiting if needed)
33 | .env*
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
42 | # contentlayer
43 | .contentlayer
44 |
45 | # uploaded files (temporary storage)
46 | /public/uploads
--------------------------------------------------------------------------------
/apps/docs/app/(home)/layout.tsx:
--------------------------------------------------------------------------------
1 | import { LandingPageLayout } from '@/shared/layouts/LandingPageLayout'
2 |
3 | export default function Layout({ children }: { children: React.ReactNode }) {
4 | return {children}
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/app/(home)/page.tsx:
--------------------------------------------------------------------------------
1 | import { HomePage } from '@/features/home/components/HomePage'
2 |
3 | export default function Home() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/app/docs/layout.tsx:
--------------------------------------------------------------------------------
1 | import { DocsLayout } from '@/shared/layouts/DocsLayout'
2 |
3 | export default function Layout({ children }: { children: React.ReactNode }) {
4 | return }>{children}
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/app/docs/not-found.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import Link from 'next/link'
3 |
4 | export default function NotFound() {
5 | return (
6 |
7 |
Not Found
8 |
Could not find document
9 |
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/apps/docs/app/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import React from 'react'
4 |
5 | export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
6 | React.useEffect(() => {
7 | console.error(error)
8 | }, [error])
9 |
10 | return (
11 |
12 |
Something went wrong!
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/docs/app/layout-preview/dashboard/[id]/layout.tsx:
--------------------------------------------------------------------------------
1 | import { DashboardLayout } from './DashboardLayout'
2 | import { cookies } from 'next/headers'
3 |
4 | interface LayoutProps {
5 | children: React.ReactNode
6 | }
7 |
8 | export default async function Layout({ children }: LayoutProps) {
9 | const cookieStore = await cookies()
10 | const defaultOpen = cookieStore.get('sidebar_state')?.value !== 'false'
11 |
12 | return {children}
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import Link from 'next/link'
3 |
4 | export default function NotFound() {
5 | return (
6 |
7 |
Not Found
8 |
Could not find requested resource
9 |
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/apps/docs/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "",
8 | "css": "../../packages/ui/src/styles/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true
11 | },
12 | "iconLibrary": "lucide",
13 | "aliases": {
14 | "components": "@/components",
15 | "hooks": "@/hooks",
16 | "lib": "@/lib",
17 | "utils": "@workspace/ui/lib/utils",
18 | "ui": "@workspace/ui/components"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Basic Form
3 | description: Learn how to create and use a basic form, including setup, input fields, and form submission handling.
4 | ---
5 |
6 | ## Usage
7 |
8 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-conditional-fields.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Conditional Fields
3 | description: Show and validate fields based on other field values.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-dependant-validation.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Dependent Validation
3 | description: Validate a field based on the value of another field.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-field-array.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Field Array
3 | description: Dynamically add and remove groups of fields with validation.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-large.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Large Form
3 | description: Build a multi-section form with arrays, selectors and toggles.
4 | ---
5 |
6 | ## Usage
7 | For large forms, you can split the form into multiple sub-sections. Within each section, use `useFormContext` to access the parent form.
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-submission-errors.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Submission Errors
3 | description: Handle server-side submission errors and map them to fields.
4 | ---
5 |
6 | ## Usage
7 | Submission errors generally fall into two categories: field-specific errors and general form errors. Here’s a common approach to display both types:
8 | - For field-specific errors, use `setSubmitErrors`.
9 | - For general form errors, simply display a toast message.
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-validation.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Validation Form
3 | description: Add client-side validation rules to inputs using our helpers.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/guide/form-with-loading.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Form with Loading
3 | description: Learn how to build a form with a loading overlay, handling form state and UX during async operations.
4 | ---
5 |
6 | ## Usage
7 | Simply wrap your form fields with the `LoadingOverlay` component and set `isLoading = true` when submitting data.
8 |
9 | If you're using a mutation from React Query, pass the `isPending` state to `isLoading`.
10 |
11 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/accordion.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Accordion
3 | description: A vertically stacked set of interactive headings that each reveal a section of content.
4 | originalDocs: https://www.radix-ui.com/primitives/docs/components/accordion
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Accordion.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/avatar.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Avatar
3 | description: An image element with a fallback to represent the user, and displays a profile picture, initials, or an icon.
4 | originalDocs: https://www.radix-ui.com/primitives/docs/components/avatar
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Avatar.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Different Sizes
14 |
15 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/calendar.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Calendar
3 | description: A calendar displays a grid of days in one or more months and allows users to select a single date.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Calendar.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Calendar.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
12 | ## Examples
13 |
14 | ### Default
15 |
16 |
17 |
18 | ### Controlled
19 |
20 |
21 |
22 | ### Unstyled
23 |
24 |
25 |
26 | ### With Min/Max Date
27 |
28 |
29 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/checkbox.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Checkbox
3 | description: A control that allows the user to toggle between checked and not checked states.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Checkbox.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Checkbox.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Default
14 |
15 |
16 | ### Disabled
17 |
18 |
19 | ### Indeterminate
20 |
21 |
22 | ### Group
23 |
24 |
25 | ### In Form
26 |
27 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/combobox.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: ComboBox
3 | description: A combobox combines a text input with a listbox, allowing users to filter a list of options to find the one they want.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/ComboBox.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/ComboBox.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/confirm-dialog.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Confirm Dialog
3 | description: A confirm dialog is a modal window that asks users to confirm or cancel a critical action.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Dialog.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/ConfirmDialog.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Basic
14 |
15 |
16 | ### Destructive
17 |
18 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/dialog.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Dialog
3 | description: A dialog is a window overlaid on either the primary window or another dialog window.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Dialog.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Dialog.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/file-trigger.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: FileTrigger
3 | description: A FileTrigger allows a user to access the file system with any pressable React Aria or React Spectrum component, or custom components built with usePress.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/FileTrigger.html
5 | ---
6 |
7 | ## Demo
8 |
9 |
10 | ## Examples
11 |
12 | ### Avatar
13 | We recommend validating files by their extensions, as MIME types may be inconsistent across platforms.
14 |
15 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/loading-overlay.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Loading Overlay
3 | description: A simple overlay spinner to indicate loading states and prevent user interaction.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/LoadingOverlay.tsx
5 | ---
6 |
7 | ## Usage
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/menu.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Menu
3 | description: A menu displays a list of actions or options in a popover.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Menu.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Menu.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
12 | ## Examples
13 |
14 | ### With Icon
15 |
16 |
17 | ### With Submenu
18 |
19 |
20 | ### With Keyboard Shortcuts
21 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/nprogress.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: NProgress
3 | description: Slim progress bars for Ajax'y applications. Inspired by Google, YouTube, and Medium.
4 | originalDocs: https://github.com/rstacruz/nprogress
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/NProgress.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/pagination.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Pagination
3 | description: A ReactJS component to render a pagination.
4 | originalDocs: https://www.npmjs.com/package/react-paginate
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Pagination.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
12 | ## Examples
13 |
14 | ### Using query parameters
15 |
16 |
17 |
18 | ### With page selector
19 |
20 |
21 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/popover.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Popover
3 | description: A popover is an overlay element positioned relative to a trigger.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Popover.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Popover.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Bottom Left
14 |
15 |
16 | ### Bottom Right
17 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/radio-group.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Radio Group
3 | description: A set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/RadioGroup.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/RadioGroup.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Default
14 |
15 |
16 | ### Horizontal
17 |
18 |
19 | ### Disabled
20 |
21 |
22 | ### In Form
23 |
24 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/range-calendar.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: RangeCalendar
3 | description: A range calendar displays a grid of days in one or more months and allows users to select a contiguous range of dates.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/RangeCalendar.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Calendar.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Default
14 |
15 |
16 |
17 | ### Controlled
18 |
19 |
20 |
21 | ### Unstyled
22 |
23 |
24 |
25 | ### With Min/Max Date
26 |
27 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/separator.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Separator
3 | description: Visually or semantically separates content.
4 | originalDocs: https://www.radix-ui.com/primitives/docs/components/separator
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Separator.tsx
6 | ---
7 |
8 | ## Demo
9 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/sheet.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Sheet
3 | description: Extends the Dialog component to display content that complements the main content of the screen.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Dialog.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Sheet.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/skeleton.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Skeleton
3 | description: Use to show a placeholder while content is loading.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Skeleton.tsx
5 | ---
6 |
7 | ## Demo
8 |
9 |
10 | ## Examples
11 |
12 | ### Skeleton screen
13 | Below is an example of a general-purpose skeleton used to represent a full screen layout while loading.
14 | Although this version works for many use cases, consider creating page-specific skeletons for a more accurate loading experience.
15 |
16 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/sonner.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Sonner
3 | description: An opinionated toast component for React.
4 | originalDocs: https://sonner.emilkowal.ski
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Sonner.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/spinner.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Spinner
3 | description: An indicator that can be used to show a loading state.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Spinner.tsx
5 | ---
6 |
7 | ## Usage
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/switch.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Switch
3 | description: A control that allows the user to toggle between checked and not checked.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Switch.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Switch.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Default
14 |
15 |
16 | ### Disabled
17 |
18 |
19 | ### In Form
20 |
21 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/table.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Table
3 | description: A responsive table component.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Table.tsx
5 | ---
6 |
7 | ## Usage
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/tooltip.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Tooltip
3 | description: A tooltip provides a short description of an element on hover or focus.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Tooltip.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Tooltip.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Basic Tooltip
14 |
15 |
16 | ### Tooltip with Custom Content
17 |
18 |
--------------------------------------------------------------------------------
/apps/docs/content/docs/ui/unused.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: This is just a file to trigger deployment
3 | description: v5
4 | ---
--------------------------------------------------------------------------------
/apps/docs/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { nextJsConfig } from "@workspace/eslint-config/next-js"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default nextJsConfig
5 |
--------------------------------------------------------------------------------
/apps/docs/features/docs/components/TocPortal.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { useMounted } from '@/shared/hooks/useMounted'
3 | import * as Portal from '@radix-ui/react-portal'
4 |
5 | export function TocPortal({ children }: { children: React.ReactNode }) {
6 | const mounted = useMounted()
7 |
8 | if (!mounted) return null
9 |
10 | return {children}
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/features/home/components/HomePage.tsx:
--------------------------------------------------------------------------------
1 | import { HeroSection } from '@/features/home/components/HeroSection'
2 | import { Separator } from '@workspace/ui/components/Separator'
3 | import { FooterSection } from '@/features/home/components/FooterSection'
4 | import { FeatureSection } from '@/features/home/components/FeatureSection'
5 |
6 | export function HomePage() {
7 | return (
8 | <>
9 |
10 |
11 |
12 |
13 |
14 | >
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/docs/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from 'next'
2 | import { withContentlayer } from 'next-contentlayer2'
3 |
4 | const nextConfig: NextConfig = withContentlayer({
5 | images: {
6 | domains: ['images.unsplash.com'],
7 | },
8 | async redirects() {
9 | return [
10 | {
11 | source: '/docs/guide',
12 | destination: '/docs/guide/introduction',
13 | permanent: false,
14 | },
15 | {
16 | source: '/docs/ui',
17 | destination: '/docs/ui/sidebar',
18 | permanent: false,
19 | },
20 | ]
21 | },
22 | })
23 |
24 | export default nextConfig
25 |
--------------------------------------------------------------------------------
/apps/docs/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from "@workspace/ui/postcss.config";
--------------------------------------------------------------------------------
/apps/docs/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/favicon.ico
--------------------------------------------------------------------------------
/apps/docs/public/hero-background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/hero-background.webp
--------------------------------------------------------------------------------
/apps/docs/public/images/folder-feature-based.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/images/folder-feature-based.avif
--------------------------------------------------------------------------------
/apps/docs/public/images/folder-features.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/images/folder-features.avif
--------------------------------------------------------------------------------
/apps/docs/public/images/folder-import-flow.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/images/folder-import-flow.avif
--------------------------------------------------------------------------------
/apps/docs/public/images/folder-overview.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/images/folder-overview.avif
--------------------------------------------------------------------------------
/apps/docs/public/images/folder-routing.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/images/folder-routing.avif
--------------------------------------------------------------------------------
/apps/docs/public/images/folder-shared.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/images/folder-shared.avif
--------------------------------------------------------------------------------
/apps/docs/public/images/og-image-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/images/og-image-2.jpg
--------------------------------------------------------------------------------
/apps/docs/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/docs/public/logo.png
--------------------------------------------------------------------------------
/apps/docs/shared/actions/examples/payments.type.ts:
--------------------------------------------------------------------------------
1 | export interface Payment {
2 | id: string
3 | amount: string
4 | status: 'pending' | 'processing' | 'success' | 'failed'
5 | email: string
6 | paymentMethod: 'credit_card' | 'debit_card' | 'paypal' | 'bank_transfer'
7 | transactionDate: string
8 | paymentReference: string
9 | }
10 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/Logo.tsx:
--------------------------------------------------------------------------------
1 | import { PROJECT_NAME } from '@/shared/consts/common'
2 | import { cn } from '@workspace/ui/lib/utils'
3 | import Link from 'next/link'
4 |
5 | interface LogoProps {
6 | className?: string
7 | textClassName?: string
8 | withName?: boolean
9 | }
10 |
11 | export function Logo({ className, textClassName, withName = true }: LogoProps) {
12 | return (
13 |
14 |
15 | {withName && (
16 | {PROJECT_NAME}
17 | )}
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/ThemeSwitcher.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useMounted } from '@/shared/hooks/useMounted'
4 | import { Button } from '@workspace/ui/components/Button'
5 | import { MoonStar, SunIcon } from 'lucide-react'
6 | import { useTheme } from 'next-themes'
7 |
8 | enum Theme {
9 | LIGHT = 'light',
10 | DARK = 'dark',
11 | }
12 |
13 | export function ThemeSwitcher() {
14 | const { theme, setTheme } = useTheme()
15 | const mounted = useMounted()
16 |
17 | return (
18 |
26 | )
27 | }
28 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/AvatarDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/Avatar'
2 |
3 | export function AvatarDemo() {
4 | return (
5 |
6 |
7 | HP
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonAsALink.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { SquareArrowOutUpRight } from 'lucide-react'
3 | import Link from 'next/link'
4 |
5 | export function ButtonAsALink() {
6 | return (
7 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonDestructive.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonDestructive() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonGhost.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonGhost() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonIcon.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Trash } from 'lucide-react'
3 |
4 | export function ButtonIcon() {
5 | return (
6 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonLoading.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Spinner } from '@workspace/ui/components/Spinner'
3 |
4 | export function ButtonLoading() {
5 | return (
6 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonOutline.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonOutline() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/ButtonWithIcon.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Plus } from 'lucide-react'
3 |
4 | export function ButtonWithIcon() {
5 | return (
6 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/CalendarControlled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsCalendar } from '@workspace/ui/components/Calendar'
4 | import { useState } from 'react'
5 |
6 | export function CalendarControlled() {
7 | const [value, setValue] = useState()
8 |
9 | return (
10 |
11 |
12 |
13 | {value ? JSON.stringify(value) : 'No value'}
14 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/CalendarDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function CalendarDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/CalendarMinMax.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsCalendar } from '@workspace/ui/components/Calendar'
4 | import dayjs from 'dayjs'
5 |
6 | export function CalendarMinMax() {
7 | return (
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/CalendarUnstyled.tsx:
--------------------------------------------------------------------------------
1 | import { BsCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function CalendarUnstyled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/CheckboxDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Checkbox } from '@workspace/ui/components/Checkbox'
2 |
3 | export function CheckboxDemo() {
4 | return Accept terms and conditions
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/CheckboxDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { Checkbox } from '@workspace/ui/components/Checkbox'
2 |
3 | export function CheckboxDisabled() {
4 | return Accept terms and conditions
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/CheckboxGroupDemo.tsx:
--------------------------------------------------------------------------------
1 | import { CheckboxGroup, Checkbox } from '@workspace/ui/components/Checkbox'
2 | import { Label } from '@workspace/ui/components/Field'
3 |
4 | export function CheckboxGroupDemo() {
5 | return (
6 |
7 |
8 |
9 | Apple
10 | Banana
11 | Orange
12 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DateFieldDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDateField } from '@workspace/ui/components/Datefield'
4 |
5 | export function DateFieldDemo() {
6 | return
7 | }
8 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DateFieldDisabled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDateField } from '@workspace/ui/components/Datefield'
4 |
5 | export function DateFieldDisabled() {
6 | return
7 | }
8 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DateFieldWithLabel.tsx:
--------------------------------------------------------------------------------
1 | import { BsDateField } from '@workspace/ui/components/Datefield'
2 | import { Label } from '@workspace/ui/components/Field'
3 |
4 | export function DateFieldWithLabel() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DatePickerDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsDatePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DatePickerDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DatePickerDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsDatePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DatePickerDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DatePickerWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDatePicker } from '@workspace/ui/components/DatePicker'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function DatePickerWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DateRangePickerDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsDateRangePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DateRangePickerDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DateRangePickerDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsDateRangePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DateRangePickerDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/DateRangePickerWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDateRangePicker } from '@workspace/ui/components/DatePicker'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function DateRangePickerWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/InputDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from '@workspace/ui/components/Textfield'
2 |
3 | export function InputDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/InputDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from '@workspace/ui/components/Textfield'
2 |
3 | export function InputDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/InputFile.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from '@workspace/ui/components/Textfield'
2 |
3 | export function InputFile() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/InputWithButton.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Input } from '@workspace/ui/components/Textfield'
3 |
4 | export function InputWithButton() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/InputWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Input } from '@workspace/ui/components/Textfield'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function InputWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/MenuDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Button } from '@workspace/ui/components/Button'
4 | import { Menu, MenuItem, MenuPopover, MenuTrigger } from '@workspace/ui/components/Menu'
5 | import { MenuIcon } from 'lucide-react'
6 |
7 | export function MenuDemo() {
8 | return (
9 |
10 |
13 |
14 |
19 |
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/MenuWithKeyboard.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { MenuTrigger, MenuItem, MenuKeyboard, MenuPopover, Menu } from '@workspace/ui/components/Menu'
3 |
4 | export function MenuWithKeyboard() {
5 | return (
6 |
7 |
8 |
9 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldCurrency.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldCurrency() {
4 | return (
5 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldMinMax.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldMinMax() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldPercentages.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldPercentages() {
4 | return (
5 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldUnits.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldUnits() {
4 | return (
5 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldWithLabel.tsx:
--------------------------------------------------------------------------------
1 | import { Label } from '@workspace/ui/components/Field'
2 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
3 |
4 | export function NumberFieldWithLabel() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/NumberFieldWithoutStepper.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldWithoutStepper() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/PaginationDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Pagination } from '@workspace/ui/components/Pagination'
2 |
3 | export function PaginationDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/PaginationWithPageSelector.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Pagination, PaginationPageSizeSelector } from '@workspace/ui/components/Pagination'
4 |
5 | export function PaginationWithPageSelector() {
6 | return (
7 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RadioGroupDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Label } from '@workspace/ui/components/Field'
4 | import { RadioGroup, Radio } from '@workspace/ui/components/RadioGroup'
5 |
6 | export function RadioGroupDemo() {
7 | return (
8 |
9 |
10 | Red
11 | Green
12 | Blue
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RadioGroupDisabled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Label } from '@workspace/ui/components/Field'
4 | import { RadioGroup, Radio } from '@workspace/ui/components/RadioGroup'
5 |
6 | export function RadioGroupDisabled() {
7 | return (
8 |
9 |
10 | Red
11 | Blue
12 | Green
13 | Yellow
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RadioGroupHorizontal.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Label } from '@workspace/ui/components/Field'
4 | import { RadioGroup, Radio } from '@workspace/ui/components/RadioGroup'
5 |
6 | export function RadioGroupHorizontal() {
7 | return (
8 |
9 |
10 | xs
11 | sm
12 | md
13 | lg
14 | xl
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RangeCalendarControlled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsRangeCalendar, BsRangeCalendarValue } from '@workspace/ui/components/Calendar'
4 | import { useState } from 'react'
5 |
6 | export function RangeCalendarControlled() {
7 | const [value, setValue] = useState()
8 |
9 | return (
10 |
11 |
12 |
13 | {value ? JSON.stringify(value, null, 2) : 'No value'}
14 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RangeCalendarDefault.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function RangeCalendarDefault() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RangeCalendarDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 | import dayjs from 'dayjs'
3 |
4 | export function RangeCalendarDemo() {
5 | return (
6 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RangeCalendarMinMax.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 | import dayjs from 'dayjs'
3 |
4 | export function RangeCalendarMinMax() {
5 | return (
6 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/RangeCalendarUnstyled.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function RangeCalendarUnstyled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SelectDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsSelect } from '@workspace/ui/components/Select'
4 | import React from 'react'
5 |
6 | const languages = [
7 | { id: 1, name: 'English' },
8 | { id: 2, name: 'Spanish' },
9 | { id: 3, name: 'French' },
10 | { id: 4, name: 'German' },
11 | { id: 5, name: 'Italian' },
12 | ]
13 |
14 | export function SelectDemo() {
15 | return (
16 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SelectDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 |
3 | export function SelectDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SelectMultiple.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsSelect } from '@workspace/ui/components/Select'
4 |
5 | const languages = [
6 | { id: 1, name: 'English' },
7 | { id: 2, name: 'Spanish' },
8 | { id: 3, name: 'French' },
9 | { id: 4, name: 'German' },
10 | { id: 5, name: 'Italian' },
11 | ]
12 |
13 | export function SelectMultiple() {
14 | return
15 | }
16 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SelectMultipleDisabled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsSelect } from '@workspace/ui/components/Select'
4 |
5 | const languages = [
6 | { id: 1, name: 'English' },
7 | { id: 2, name: 'Spanish' },
8 | { id: 3, name: 'French' },
9 | { id: 4, name: 'German' },
10 | { id: 5, name: 'Italian' },
11 | ]
12 |
13 | export function SelectMultipleDisabled() {
14 | return
15 | }
16 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SelectMultipleSearchable.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 |
3 | const languages = [
4 | { id: 1, name: 'English' },
5 | { id: 2, name: 'Spanish' },
6 | { id: 3, name: 'French' },
7 | { id: 4, name: 'German' },
8 | { id: 5, name: 'Italian' },
9 | ]
10 |
11 | export function SelectMultipleSearchable() {
12 | return
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SelectSearchable.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 |
3 | const languages = [
4 | { id: 1, name: 'English' },
5 | { id: 2, name: 'Spanish' },
6 | { id: 3, name: 'French' },
7 | { id: 4, name: 'German' },
8 | { id: 5, name: 'Italian' },
9 | ]
10 |
11 | export function SelectSearchable() {
12 | return
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SelectWithClearButton.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 | import React from 'react'
3 |
4 | const languages = [
5 | { id: 1, name: 'English' },
6 | { id: 2, name: 'Spanish' },
7 | { id: 3, name: 'French' },
8 | { id: 4, name: 'German' },
9 | { id: 5, name: 'Italian' },
10 | ]
11 |
12 | export function SelectWithClearButton() {
13 | return (
14 |
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SkeletonDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from '@workspace/ui/components/Skeleton'
2 |
3 | export function SkeletonDemo() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SpinnerDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Spinner } from '@workspace/ui/components/Spinner'
2 |
3 | export function SpinnerDemo() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SwitchDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Switch } from '@workspace/ui/components/Switch'
2 |
3 | export function SwitchDemo() {
4 | return Airplane mode
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/SwitchDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { Switch } from '@workspace/ui/components/Switch'
2 |
3 | export function SwitchDisabled() {
4 | return Airplane mode
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TextAreaDemo.tsx:
--------------------------------------------------------------------------------
1 | import { TextArea } from '@workspace/ui/components/Textfield'
2 |
3 | export function TextAreaDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TextAreaDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { TextArea } from '@workspace/ui/components/Textfield'
2 |
3 | export function TextAreaDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TextAreaWithButton.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { TextArea } from '@workspace/ui/components/Textfield'
3 |
4 | export function TextAreaWithButton() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TextAreaWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { TextArea } from '@workspace/ui/components/Textfield'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function TextAreaWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TimeFieldDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 |
3 | export function TimeFieldDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TimeFieldDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 |
3 | export function TimeFieldDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TimeFieldGranularity.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 |
3 | export function TimeFieldGranularity() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TimeFieldWithLabel.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 | import { Label } from '@workspace/ui/components/Field'
3 |
4 | export function TimeFieldWithLabel() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TooltipBasic.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Button } from '@workspace/ui/components/Button'
4 | import { Tooltip, TooltipTrigger } from '@workspace/ui/components/Tooltip'
5 |
6 | export function TooltipBasic() {
7 | return (
8 |
9 |
10 |
11 |
12 | Simple tooltip text
13 |
14 |
15 |
16 |
17 |
18 | Another simple tooltip
19 |
20 |
21 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/TooltipDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Button } from '@workspace/ui/components/Button'
4 | import { Tooltip, TooltipTrigger } from '@workspace/ui/components/Tooltip'
5 | import { Pencil } from 'lucide-react'
6 |
7 | export function TooltipDemo() {
8 | return (
9 |
10 |
13 | Edit
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/UploaderDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Uploader } from '@workspace/ui/components/Uploader'
4 | import { CustomUploaderAction } from './UploaderDemo.utils'
5 |
6 | export function UploaderDemo() {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/UploaderDemo.utils.ts:
--------------------------------------------------------------------------------
1 | import { UploaderAction } from '@workspace/ui/components/Uploader'
2 | import { AxiosResponse } from 'axios'
3 |
4 | interface TmpResponse {
5 | status: string
6 | data: {
7 | url: string
8 | }
9 | }
10 |
11 | export class CustomUploaderAction extends UploaderAction {
12 | constructor() {
13 | super('https://tmpfiles.org/api/v1/upload')
14 | }
15 |
16 | formatResponse(response: AxiosResponse) {
17 | const url = response.data?.data?.url
18 | const id = url.split('/').slice(-2).join('/')
19 | const downloadUrl = `https://tmpfiles.org/dl/${id}`
20 |
21 | return {
22 | id: url,
23 | url: downloadUrl,
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/UploaderRetry.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Uploader, UploaderAction } from '@workspace/ui/components/Uploader'
4 |
5 | export function UploaderRetry() {
6 | return (
7 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/examples/UploaderValidation.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Uploader } from '@workspace/ui/components/Uploader'
4 | import { CustomUploaderAction } from './UploaderDemo.utils'
5 |
6 | export function UploaderValidation() {
7 | return (
8 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/icons/ReactAriaIcon.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function ReactAriaIcon({ className }: { className?: string }) {
4 | return (
5 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/icons/ShadcnIcon.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@workspace/ui/lib/utils'
2 | import * as React from 'react'
3 |
4 | export function ShadcnIcon({ className }: { className?: string }) {
5 | return (
6 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/mdx-helpers/MdxImage.tsx:
--------------------------------------------------------------------------------
1 | export function MdxImage({ src, alt }: { src: string; alt: string }) {
2 | return (
3 |
4 |

5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/apps/docs/shared/components/mdx-helpers/MdxTip.tsx:
--------------------------------------------------------------------------------
1 | import { InfoIcon } from 'lucide-react'
2 |
3 | interface MdxTipProps {
4 | children: React.ReactNode
5 | title: string
6 | }
7 |
8 | export function MdxTip({ children, title = 'Note' }: MdxTipProps) {
9 | return (
10 |
11 |
12 |
13 |
14 | {title}
15 |
16 |
{children}
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/apps/docs/shared/consts/common.ts:
--------------------------------------------------------------------------------
1 | export const PROJECT_NAME = 'BaseStack'
2 | export const PROJECT_NAME_SLUG = 'base-stack'
3 | export const PROJECT_DESCRIPTION =
4 | 'A modern React starter kit with best practices and all the essentials to quickly launch your frontend.'
5 | export const GITHUB_URL = `https://github.com/henry-phm/${PROJECT_NAME_SLUG}`
6 | export const GITHUB_URL_AUTHOR = 'https://github.com/henry-phm'
7 |
--------------------------------------------------------------------------------
/apps/docs/shared/hooks/useMounted.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function useMounted() {
4 | const [mounted, setMounted] = React.useState(false)
5 |
6 | React.useEffect(() => {
7 | setMounted(true)
8 | }, [])
9 |
10 | return mounted
11 | }
12 |
--------------------------------------------------------------------------------
/apps/docs/shared/layouts/DocsLayout/Icons.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function CrossIcon({ className }: { className?: string }) {
4 | return (
5 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/apps/docs/shared/layouts/DocsLayout/SidebarHeader.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Logo } from '@/shared/components/Logo'
3 |
4 | export function SidebarHeader() {
5 | return (
6 |
7 |
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/apps/docs/shared/layouts/DocsSearch.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { SearchIcon } from 'lucide-react'
3 |
4 | export function DocsSearch() {
5 | // TODO: Add search functionality
6 | return null
7 |
8 | return (
9 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/shared/layouts/HeaderIconButtons.tsx:
--------------------------------------------------------------------------------
1 | import { GithubIcon } from '@/shared/components/icons/GithubIcon'
2 | import { ThemeSwitcher } from '@/shared/components/ThemeSwitcher'
3 | import { GITHUB_URL } from '@/shared/consts/common'
4 | import { DocsSearch } from '@/shared/layouts/DocsSearch'
5 | import { Button } from '@workspace/ui/components/Button'
6 | import Link from 'next/link'
7 |
8 | export function HeaderIconButtons() {
9 | return (
10 |
11 |
12 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/apps/docs/shared/lib/composition.ts:
--------------------------------------------------------------------------------
1 | import { readFile } from 'node:fs/promises'
2 | import { resolve } from 'node:path'
3 |
4 | export const readExampleFile = async (name: string, ext = 'tsx') => {
5 | const filePath = resolve(`shared/components/examples`, `${name}.${ext}`)
6 |
7 | const fileContent = await readFile(filePath, 'utf-8')
8 |
9 | return fileContent
10 | }
11 |
--------------------------------------------------------------------------------
/apps/docs/shared/lib/highlight-code.ts:
--------------------------------------------------------------------------------
1 | import { codeToHtml } from 'shiki'
2 |
3 | export const highlightCode = (code: string, opts?: Partial[1]>) => {
4 | return codeToHtml(code, {
5 | lang: 'tsx',
6 | themes: {
7 | light: 'github-light',
8 | dark: 'github-dark',
9 | },
10 | colorReplacements: {
11 | '#fff': '#FAFAFA',
12 | '#24292e': '#212121',
13 | },
14 | ...opts,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/apps/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "baseUrl": ".",
22 | "paths": {
23 | "contentlayer/generated": ["./.contentlayer/generated"],
24 | "@/*": ["./*"]
25 | }
26 | },
27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".contentlayer/generated"],
28 | "exclude": ["node_modules"]
29 | }
30 |
--------------------------------------------------------------------------------
/apps/next/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "",
8 | "css": "../../packages/ui/src/styles/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true
11 | },
12 | "iconLibrary": "lucide",
13 | "aliases": {
14 | "components": "@/components",
15 | "hooks": "@/hooks",
16 | "lib": "@/lib",
17 | "utils": "@workspace/ui/lib/utils",
18 | "ui": "@workspace/ui/components"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/apps/next/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { nextJsConfig } from "@workspace/eslint-config/next-js"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default nextJsConfig
5 |
--------------------------------------------------------------------------------
/apps/next/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
6 |
--------------------------------------------------------------------------------
/apps/next/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | transpilePackages: ["@workspace/ui"],
4 | }
5 |
6 | export default nextConfig
7 |
--------------------------------------------------------------------------------
/apps/next/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from "@workspace/ui/postcss.config";
--------------------------------------------------------------------------------
/apps/next/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/apps/next/src/app/favicon.ico
--------------------------------------------------------------------------------
/apps/next/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Providers } from '@/shared/components/Providers'
2 | import '@workspace/ui/globals.css'
3 |
4 | export default function RootLayout({
5 | children,
6 | }: Readonly<{
7 | children: React.ReactNode
8 | }>) {
9 | return (
10 |
11 |
12 | {children}
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/next/src/shared/components/ThemeSwitcher.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useMounted } from '@/shared/hooks/useMounted'
4 | import { Button } from '@workspace/ui/components/Button'
5 | import { MoonStar, SunIcon } from 'lucide-react'
6 | import { useTheme } from 'next-themes'
7 |
8 | enum Theme {
9 | LIGHT = 'light',
10 | DARK = 'dark',
11 | }
12 |
13 | export function ThemeSwitcher() {
14 | const { theme, setTheme } = useTheme()
15 | const mounted = useMounted()
16 |
17 | return (
18 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/apps/next/src/shared/hooks/useMounted.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function useMounted() {
4 | const [mounted, setMounted] = React.useState(false)
5 |
6 | React.useEffect(() => {
7 | setMounted(true)
8 | }, [])
9 |
10 | return mounted
11 | }
12 |
--------------------------------------------------------------------------------
/apps/next/src/shared/lib/api.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Api } from '@workspace/lib/api'
3 |
4 | export type * from '@workspace/lib/api'
5 |
6 | export const api = new Api(
7 | axios.create({
8 | baseURL: 'http://localhost:8080', // TODO: move to env
9 | }),
10 | )
11 |
--------------------------------------------------------------------------------
/apps/next/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./src/*"],
7 | "@workspace/ui/*": ["../../packages/ui/src/*"]
8 | },
9 | "plugins": [
10 | {
11 | "name": "next"
12 | }
13 | ]
14 | },
15 | "include": [
16 | "next-env.d.ts",
17 | "next.config.ts",
18 | "**/*.ts",
19 | "**/*.tsx",
20 | ".next/types/**/*.ts"
21 | ],
22 | "exclude": ["node_modules"]
23 | }
24 |
--------------------------------------------------------------------------------
/apps/tanstack-router/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | dist-ssr
5 | *.local
6 |
--------------------------------------------------------------------------------
/apps/tanstack-router/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.watcherExclude": {
3 | "**/routeTree.gen.ts": true
4 | },
5 | "search.exclude": {
6 | "**/routeTree.gen.ts": true
7 | },
8 | "files.readonlyInclude": {
9 | "**/routeTree.gen.ts": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/apps/tanstack-router/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | To run this example:
4 |
5 | - `npm install` or `yarn`
6 | - `npm start` or `yarn start`
7 |
--------------------------------------------------------------------------------
/apps/tanstack-router/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { config } from "@workspace/eslint-config/react-internal"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default config
5 |
--------------------------------------------------------------------------------
/apps/tanstack-router/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Vite App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apps/tanstack-router/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from "@workspace/ui/postcss.config";
--------------------------------------------------------------------------------
/apps/tanstack-router/src/main.tsx:
--------------------------------------------------------------------------------
1 | import ReactDOM from 'react-dom/client'
2 | import { RouterProvider, createRouter } from '@tanstack/react-router'
3 | import { routeTree } from './routeTree.gen'
4 | import '@workspace/ui/globals.css'
5 |
6 | // Set up a Router instance
7 | const router = createRouter({
8 | routeTree,
9 | defaultPreload: 'intent',
10 | scrollRestoration: true,
11 | })
12 |
13 | // Register things for typesafety
14 | declare module '@tanstack/react-router' {
15 | interface Register {
16 | router: typeof router
17 | }
18 | }
19 |
20 | const rootElement = document.getElementById('app')!
21 |
22 | if (!rootElement.innerHTML) {
23 | const root = ReactDOM.createRoot(rootElement)
24 | root.render()
25 | }
26 |
--------------------------------------------------------------------------------
/apps/tanstack-router/src/routes/__root.tsx:
--------------------------------------------------------------------------------
1 | import { Outlet, createRootRoute } from '@tanstack/react-router'
2 | import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
3 | import { Providers } from '@/shared/components/Providers'
4 |
5 | export const Route = createRootRoute({
6 | component: RootComponent,
7 | })
8 |
9 | function RootComponent() {
10 | return (
11 |
12 |
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/apps/tanstack-router/src/shared/components/ThemeSwitcher.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useTheme } from '@/shared/components/ThemeProvider'
4 | import { Button } from '@workspace/ui/components/Button'
5 | import { MoonStar, SunIcon } from 'lucide-react'
6 |
7 | export function ThemeSwitcher() {
8 | const { theme, setTheme } = useTheme()
9 |
10 | return (
11 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/apps/tanstack-router/src/shared/lib/api.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Api } from '@workspace/lib/api'
3 |
4 | export type * from '@workspace/lib/api'
5 |
6 | export const api = new Api(
7 | axios.create({
8 | baseURL: 'http://localhost:8080', // TODO: move to env
9 | }),
10 | )
11 |
--------------------------------------------------------------------------------
/apps/tanstack-router/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./src/*"],
7 | "@workspace/ui/*": ["../../packages/ui/src/*"]
8 | },
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/apps/tanstack-router/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import { tanstackRouter } from '@tanstack/router-plugin/vite'
4 | import { resolve } from 'node:path'
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [tanstackRouter({ target: 'react', autoCodeSplitting: true }), react()],
9 | resolve: {
10 | alias: {
11 | '@': resolve(__dirname, './src'),
12 | },
13 | },
14 | })
15 |
--------------------------------------------------------------------------------
/images/project-preview-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/images/project-preview-1.png
--------------------------------------------------------------------------------
/lefthook.yml:
--------------------------------------------------------------------------------
1 | pre-commit:
2 | commands:
3 | check:
4 | glob: '*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}'
5 | run: npx prettier --write {staged_files}
6 | stage_fixed: true
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "base-stack",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "build": "turbo build",
7 | "dev": "turbo dev",
8 | "lint": "turbo lint",
9 | "format": "prettier --write \"**/*.{ts,tsx,md}\"",
10 | "prepare": "lefthook install"
11 | },
12 | "devDependencies": {
13 | "@workspace/eslint-config": "workspace:*",
14 | "@workspace/typescript-config": "workspace:*",
15 | "prettier": "^3.6.2",
16 | "tsx": "^4.20.6",
17 | "turbo": "^2.5.5",
18 | "typescript": "^5.9.2",
19 | "lefthook": "^1.11.8"
20 | },
21 | "packageManager": "pnpm@10.4.1",
22 | "engines": {
23 | "node": ">=20"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/eslint-config/README.md:
--------------------------------------------------------------------------------
1 | # `@workspace/eslint-config`
2 |
3 | Shared eslint configuration for the workspace.
4 |
--------------------------------------------------------------------------------
/packages/lib/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { config } from "@workspace/eslint-config/react-internal"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default config
5 |
--------------------------------------------------------------------------------
/packages/lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@workspace/lib",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "private": true,
6 | "scripts": {
7 | "lint": "eslint . --max-warnings 0"
8 | },
9 | "dependencies": {
10 | "@tanstack/react-query": "^5.87.1",
11 | "axios": "^1.12.2",
12 | "react-dom": "^19.1.1",
13 | "zod": "^3.25.76"
14 | },
15 | "devDependencies": {
16 | "@types/react": "^19.1.9",
17 | "@types/react-dom": "^19.1.7",
18 | "@workspace/eslint-config": "workspace:*",
19 | "@workspace/typescript-config": "workspace:*",
20 | "eslint": "^9.35.0",
21 | "typescript": "^5.9.2"
22 | },
23 | "exports": {
24 | "./*": "./src/*/index.ts"
25 | }
26 | }
--------------------------------------------------------------------------------
/packages/lib/src/api/index.ts:
--------------------------------------------------------------------------------
1 | import { AxiosInstance } from 'axios'
2 | import { ExampleApi } from './sdk/example.api'
3 |
4 | /**
5 | * API class for the application
6 | * @example
7 | * const api = new Api(
8 | * axios.create({
9 | baseURL: 'http://localhost:8080',
10 | }),
11 | * )
12 | * api.example.hello()
13 | */
14 | export class Api {
15 | example: ExampleApi
16 |
17 | constructor(private readonly client: AxiosInstance) {
18 | this.example = new ExampleApi(this.client)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/lib/src/api/sdk/example.api.ts:
--------------------------------------------------------------------------------
1 | import { queryOptions } from '@tanstack/react-query'
2 | import { AxiosInstance } from 'axios'
3 | import { ExampleResponse } from './example.type'
4 |
5 | export class ExampleApi {
6 | constructor(private readonly client: AxiosInstance) {}
7 |
8 | hello() {
9 | return queryOptions({
10 | queryKey: ['hello'],
11 | queryFn: () => {
12 | const response: ExampleResponse = {
13 | message: 'Hello World',
14 | }
15 |
16 | return response
17 | },
18 | })
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/lib/src/api/sdk/example.type.ts:
--------------------------------------------------------------------------------
1 | export interface ExampleResponse {
2 | message: string
3 | }
--------------------------------------------------------------------------------
/packages/lib/src/validation/index.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | declare module 'zod' {
4 | interface ZodType {
5 | validateFn(): (value: any) => string | boolean
6 | }
7 | }
8 |
9 | z.ZodType.prototype.validateFn = function () {
10 | return (value: any): string | boolean => {
11 | const result = this.safeParse(value)
12 | return result.success || result.error?.errors?.[0]?.message || ''
13 | }
14 | }
15 |
16 | export { z }
17 |
--------------------------------------------------------------------------------
/packages/lib/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@workspace/lib/*": ["./src/*"]
7 | }
8 | },
9 | "include": ["."],
10 | "exclude": ["node_modules", "dist"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/typescript-config/README.md:
--------------------------------------------------------------------------------
1 | # `@workspace/typescript-config`
2 |
3 | Shared typescript configuration for the workspace.
4 |
--------------------------------------------------------------------------------
/packages/typescript-config/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "declaration": true,
6 | "declarationMap": true,
7 | "esModuleInterop": true,
8 | "incremental": false,
9 | "isolatedModules": true,
10 | "lib": ["es2022", "DOM", "DOM.Iterable"],
11 | "module": "ESNext",
12 | "moduleDetection": "force",
13 | "moduleResolution": "bundler",
14 | "noUncheckedIndexedAccess": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 | "strict": true,
18 | "target": "ES2022"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/typescript-config/nextjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Next.js",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "plugins": [{ "name": "next" }],
7 | "module": "ESNext",
8 | "moduleResolution": "Bundler",
9 | "allowJs": true,
10 | "jsx": "preserve",
11 | "noEmit": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/typescript-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@workspace/typescript-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "license": "PROPRIETARY",
6 | "publishConfig": {
7 | "access": "public"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/typescript-config/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/ui/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "",
8 | "css": "src/styles/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true
11 | },
12 | "iconLibrary": "lucide",
13 | "aliases": {
14 | "components": "@workspace/ui/components",
15 | "utils": "@workspace/ui/lib/utils",
16 | "hooks": "@workspace/ui/hooks",
17 | "lib": "@workspace/ui/lib",
18 | "ui": "@workspace/ui/components"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/ui/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { config } from "@workspace/eslint-config/react-internal"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default config
5 |
--------------------------------------------------------------------------------
/packages/ui/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: { "@tailwindcss/postcss": {} },
4 | };
5 |
6 | export default config;
7 |
--------------------------------------------------------------------------------
/packages/ui/src/components/Collapsible.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'
4 |
5 | function Collapsible({ ...props }: React.ComponentProps) {
6 | return
7 | }
8 |
9 | function CollapsibleTrigger({ ...props }: React.ComponentProps) {
10 | return
11 | }
12 |
13 | function CollapsibleContent({ ...props }: React.ComponentProps) {
14 | return
15 | }
16 |
17 | export { Collapsible, CollapsibleTrigger, CollapsibleContent }
18 |
--------------------------------------------------------------------------------
/packages/ui/src/components/Datefield.utils.ts:
--------------------------------------------------------------------------------
1 | import { Time } from '@internationalized/date'
2 |
3 | export const parseTime = (time: string) => {
4 | try {
5 | const timeArray = time.split(':').map(Number)
6 | return new Time(...timeArray)
7 | } catch (error) {
8 | return null
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/ui/src/components/LoadingOverlay.tsx:
--------------------------------------------------------------------------------
1 | import { Slot, Slottable } from '@radix-ui/react-slot'
2 | import { Spinner } from '@workspace/ui/components/Spinner'
3 | import { cn } from '@workspace/ui/lib/utils'
4 |
5 | export interface LoadingOverlayProps {
6 | children: React.ReactNode
7 | isLoading?: boolean
8 | }
9 |
10 | export function LoadingOverlay({ children, isLoading }: LoadingOverlayProps) {
11 | return (
12 |
13 | {children}
14 | {isLoading && (
15 |
16 |
17 |
18 | )}
19 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/packages/ui/src/components/NProgress.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import NProgressJs from 'nprogress'
3 |
4 | NProgressJs.configure({
5 | showSpinner: false,
6 | trickleSpeed: 150,
7 | template:
8 | '',
9 | })
10 |
11 | function useNProgress({ isFetching }: { isFetching: boolean }) {
12 | React.useEffect(() => {
13 | if (isFetching) {
14 | NProgressJs.start()
15 | } else {
16 | NProgressJs.done()
17 | }
18 | }, [isFetching])
19 | }
20 |
21 | export { useNProgress }
22 |
--------------------------------------------------------------------------------
/packages/ui/src/components/Separator.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Separator as AriaSeparator, SeparatorProps as AriaSeparatorProps } from 'react-aria-components'
4 |
5 | import { cn } from '@workspace/ui/lib/utils'
6 |
7 | const Separator = ({ className, orientation = 'horizontal', ...props }: AriaSeparatorProps) => (
8 |
18 | )
19 |
20 | export { Separator }
21 |
--------------------------------------------------------------------------------
/packages/ui/src/components/Skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@workspace/ui/lib/utils'
2 |
3 | function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
4 | return
5 | }
6 |
7 | export { Skeleton }
8 |
--------------------------------------------------------------------------------
/packages/ui/src/components/Spinner.tsx:
--------------------------------------------------------------------------------
1 | import { Loader2Icon } from 'lucide-react'
2 |
3 | import { cn } from '@workspace/ui/lib/utils'
4 |
5 | function Spinner({ className, ...props }: React.ComponentProps<'svg'>) {
6 | return (
7 |
8 | )
9 | }
10 |
11 | export { Spinner }
12 |
--------------------------------------------------------------------------------
/packages/ui/src/hooks/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/packages/ui/src/hooks/.gitkeep
--------------------------------------------------------------------------------
/packages/ui/src/hooks/use-mobile.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | const DEFAULT_MOBILE_BREAKPOINT = 768
4 |
5 | interface UseIsMobileProps {
6 | breakpoint?: number
7 | }
8 |
9 | export function useIsMobile({ breakpoint = DEFAULT_MOBILE_BREAKPOINT }: UseIsMobileProps = {}) {
10 | const [isMobile, setIsMobile] = React.useState(undefined)
11 |
12 | React.useEffect(() => {
13 | const mql = window.matchMedia(`(max-width: ${breakpoint - 1}px)`)
14 | const onChange = () => {
15 | setIsMobile(window.innerWidth < breakpoint)
16 | }
17 | mql.addEventListener('change', onChange)
18 | setIsMobile(window.innerWidth < breakpoint)
19 | return () => mql.removeEventListener('change', onChange)
20 | }, [])
21 |
22 | return !!isMobile
23 | }
24 |
--------------------------------------------------------------------------------
/packages/ui/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from 'clsx'
2 | import { twMerge } from 'tailwind-merge'
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@workspace/ui/*": ["./src/*"]
7 | },
8 | },
9 | "include": ["."],
10 | "exclude": ["node_modules", "dist"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/ui/tsconfig.lint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "outDir": "dist"
5 | },
6 | "include": ["src", "turbo"],
7 | "exclude": ["node_modules", "dist"]
8 | }
9 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'apps/*'
3 | - 'packages/*'
4 | - 'tooling/*'
--------------------------------------------------------------------------------
/tooling/cli/.gitignore:
--------------------------------------------------------------------------------
1 | my-app
--------------------------------------------------------------------------------
/tooling/cli/README.md:
--------------------------------------------------------------------------------
1 | ## Base Stack CLI
2 |
3 | Scaffold a Base Stack monorepo and add apps.
4 |
5 | - **CLI**: `base-stack`
6 | - **Node**: >= 18
7 |
8 | ## Commands
9 |
10 | ### init
11 | Create a new project.
12 |
13 | ```bash
14 | npx base-stack init
15 | ```
16 |
17 | ### add
18 | Add an app to an existing project (run from repo root).
19 |
20 | ```bash
21 | npx base-stack add
22 | ```
23 |
--------------------------------------------------------------------------------
/tooling/cli/index.ts:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 | import { Command } from 'commander'
3 | import { init } from './commands/init'
4 | import { add } from './commands/add'
5 | import { CLI_NAME } from './consts'
6 | import packageJson from './package.json'
7 |
8 | export async function main() {
9 | const program = new Command()
10 | .name(CLI_NAME)
11 | .version(packageJson.version)
12 | .description('CLI to create a new Base Stack application')
13 |
14 | program.addCommand(init)
15 | program.addCommand(add)
16 |
17 | program.parse()
18 | }
19 |
20 | main()
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/.prettierignore:
--------------------------------------------------------------------------------
1 | routeTree.gen.ts
--------------------------------------------------------------------------------
/tooling/cli/templates/base/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true,
4 | "trailingComma": "all",
5 | "printWidth": 120,
6 | "tabWidth": 4,
7 | "useTabs": false,
8 | "bracketSpacing": true,
9 | "bracketSameLine": false,
10 | "jsxBracketSameLine": false,
11 | "jsxSingleQuote": false,
12 | "arrowParens": "avoid"
13 | }
--------------------------------------------------------------------------------
/tooling/cli/templates/base/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "tailwindCSS.experimental.configFile": "packages/ui/src/styles/globals.css"
3 | }
4 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/README.md:
--------------------------------------------------------------------------------
1 | # Base Stack
2 | This is a **React starter kit** that provides an opinionated, production-ready foundation for building modern web applications. It's designed to give you everything you need to start building immediately, with carefully chosen tools and patterns that work together seamlessly.
3 |
4 | 
5 |
6 | ## Documentation
7 | https://base-stack.dev
8 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # Local env files
9 | .env
10 | .env.local
11 | .env.development.local
12 | .env.test.local
13 | .env.production.local
14 |
15 | # Testing
16 | coverage
17 |
18 | # Turbo
19 | .turbo
20 |
21 | # Vercel
22 | .vercel
23 |
24 | # Build Outputs
25 | .next/
26 | out/
27 | build
28 | dist
29 |
30 |
31 | # Debug
32 | npm-debug.log*
33 |
34 | # Misc
35 | .DS_Store
36 | *.pem
37 |
38 | # contentlayer
39 | .contentlayer
40 |
41 | # next.js
42 | next-env.d.ts
43 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/lefthook.yml:
--------------------------------------------------------------------------------
1 | pre-commit:
2 | commands:
3 | check:
4 | glob: '*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}'
5 | run: npx prettier --write {staged_files}
6 | stage_fixed: true
7 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "base-stack",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "build": "turbo build",
7 | "dev": "turbo dev",
8 | "lint": "turbo lint",
9 | "format": "prettier --write \"**/*.{ts,tsx,md}\"",
10 | "prepare": "lefthook install"
11 | },
12 | "devDependencies": {
13 | "@workspace/eslint-config": "workspace:*",
14 | "@workspace/typescript-config": "workspace:*",
15 | "prettier": "^3.6.2",
16 | "tsx": "^4.20.6",
17 | "turbo": "^2.5.5",
18 | "typescript": "^5.9.2",
19 | "lefthook": "^1.11.8"
20 | },
21 | "packageManager": "pnpm@10.4.1",
22 | "engines": {
23 | "node": ">=20"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/eslint-config/README.md:
--------------------------------------------------------------------------------
1 | # `@workspace/eslint-config`
2 |
3 | Shared eslint configuration for the workspace.
4 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/lib/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { config } from "@workspace/eslint-config/react-internal"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default config
5 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@workspace/lib",
3 | "version": "0.0.0",
4 | "type": "module",
5 | "private": true,
6 | "scripts": {
7 | "lint": "eslint . --max-warnings 0"
8 | },
9 | "dependencies": {
10 | "@tanstack/react-query": "^5.87.1",
11 | "axios": "^1.12.2",
12 | "react-dom": "^19.1.1",
13 | "zod": "^3.25.76"
14 | },
15 | "devDependencies": {
16 | "@types/react": "^19.1.9",
17 | "@types/react-dom": "^19.1.7",
18 | "@workspace/eslint-config": "workspace:*",
19 | "@workspace/typescript-config": "workspace:*",
20 | "eslint": "^9.35.0",
21 | "typescript": "^5.9.2"
22 | },
23 | "exports": {
24 | "./*": "./src/*/index.ts"
25 | }
26 | }
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/lib/src/api/index.ts:
--------------------------------------------------------------------------------
1 | import { AxiosInstance } from 'axios'
2 | import { ExampleApi } from './sdk/example.api'
3 |
4 | /**
5 | * API class for the application
6 | * @example
7 | * const api = new Api(
8 | * axios.create({
9 | baseURL: 'http://localhost:8080',
10 | }),
11 | * )
12 | * api.example.hello()
13 | */
14 | export class Api {
15 | example: ExampleApi
16 |
17 | constructor(private readonly client: AxiosInstance) {
18 | this.example = new ExampleApi(this.client)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/lib/src/api/sdk/example.api.ts:
--------------------------------------------------------------------------------
1 | import { queryOptions } from '@tanstack/react-query'
2 | import { AxiosInstance } from 'axios'
3 | import { ExampleResponse } from './example.type'
4 |
5 | export class ExampleApi {
6 | constructor(private readonly client: AxiosInstance) {}
7 |
8 | hello() {
9 | return queryOptions({
10 | queryKey: ['hello'],
11 | queryFn: () => {
12 | const response: ExampleResponse = {
13 | message: 'Hello World',
14 | }
15 |
16 | return response
17 | },
18 | })
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/lib/src/api/sdk/example.type.ts:
--------------------------------------------------------------------------------
1 | export interface ExampleResponse {
2 | message: string
3 | }
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/lib/src/validation/index.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod'
2 |
3 | declare module 'zod' {
4 | interface ZodType {
5 | validateFn(): (value: any) => string | boolean
6 | }
7 | }
8 |
9 | z.ZodType.prototype.validateFn = function () {
10 | return (value: any): string | boolean => {
11 | const result = this.safeParse(value)
12 | return result.success || result.error?.errors?.[0]?.message || ''
13 | }
14 | }
15 |
16 | export { z }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/lib/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@workspace/lib/*": ["./src/*"]
7 | }
8 | },
9 | "include": ["."],
10 | "exclude": ["node_modules", "dist"]
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/typescript-config/README.md:
--------------------------------------------------------------------------------
1 | # `@workspace/typescript-config`
2 |
3 | Shared typescript configuration for the workspace.
4 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/typescript-config/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "declaration": true,
6 | "declarationMap": true,
7 | "esModuleInterop": true,
8 | "incremental": false,
9 | "isolatedModules": true,
10 | "lib": ["es2022", "DOM", "DOM.Iterable"],
11 | "module": "ESNext",
12 | "moduleDetection": "force",
13 | "moduleResolution": "bundler",
14 | "noUncheckedIndexedAccess": true,
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 | "strict": true,
18 | "target": "ES2022"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/typescript-config/nextjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Next.js",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "plugins": [{ "name": "next" }],
7 | "module": "ESNext",
8 | "moduleResolution": "Bundler",
9 | "allowJs": true,
10 | "jsx": "preserve",
11 | "noEmit": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/typescript-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@workspace/typescript-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "license": "PROPRIETARY",
6 | "publishConfig": {
7 | "access": "public"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/typescript-config/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "",
8 | "css": "src/styles/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true
11 | },
12 | "iconLibrary": "lucide",
13 | "aliases": {
14 | "components": "@workspace/ui/components",
15 | "utils": "@workspace/ui/lib/utils",
16 | "hooks": "@workspace/ui/hooks",
17 | "lib": "@workspace/ui/lib",
18 | "ui": "@workspace/ui/components"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { config } from "@workspace/eslint-config/react-internal"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default config
5 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: { "@tailwindcss/postcss": {} },
4 | };
5 |
6 | export default config;
7 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/components/Datefield.utils.ts:
--------------------------------------------------------------------------------
1 | import { Time } from '@internationalized/date'
2 |
3 | export const parseTime = (time: string) => {
4 | try {
5 | const timeArray = time.split(':').map(Number)
6 | return new Time(...timeArray)
7 | } catch (error) {
8 | return null
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/components/LoadingOverlay.tsx:
--------------------------------------------------------------------------------
1 | import { Slot, Slottable } from '@radix-ui/react-slot'
2 | import { Spinner } from '@workspace/ui/components/Spinner'
3 | import { cn } from '@workspace/ui/lib/utils'
4 |
5 | export interface LoadingOverlayProps {
6 | children: React.ReactNode
7 | isLoading?: boolean
8 | }
9 |
10 | export function LoadingOverlay({ children, isLoading }: LoadingOverlayProps) {
11 | return (
12 |
13 | {children}
14 | {isLoading && (
15 |
16 |
17 |
18 | )}
19 |
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/components/NProgress.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import NProgressJs from 'nprogress'
3 |
4 | NProgressJs.configure({
5 | showSpinner: false,
6 | trickleSpeed: 150,
7 | template:
8 | '',
9 | })
10 |
11 | function useNProgress({ isFetching }: { isFetching: boolean }) {
12 | React.useEffect(() => {
13 | if (isFetching) {
14 | NProgressJs.start()
15 | } else {
16 | NProgressJs.done()
17 | }
18 | }, [isFetching])
19 | }
20 |
21 | export { useNProgress }
22 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/components/Separator.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Separator as AriaSeparator, SeparatorProps as AriaSeparatorProps } from 'react-aria-components'
4 |
5 | import { cn } from '@workspace/ui/lib/utils'
6 |
7 | const Separator = ({ className, orientation = 'horizontal', ...props }: AriaSeparatorProps) => (
8 |
18 | )
19 |
20 | export { Separator }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/components/Skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@workspace/ui/lib/utils'
2 |
3 | function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
4 | return
5 | }
6 |
7 | export { Skeleton }
8 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/components/Spinner.tsx:
--------------------------------------------------------------------------------
1 | import { Loader2Icon } from 'lucide-react'
2 |
3 | import { cn } from '@workspace/ui/lib/utils'
4 |
5 | function Spinner({ className, ...props }: React.ComponentProps<'svg'>) {
6 | return (
7 |
8 | )
9 | }
10 |
11 | export { Spinner }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/hooks/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/base/packages/ui/src/hooks/.gitkeep
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from 'clsx'
2 | import { twMerge } from 'tailwind-merge'
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@workspace/ui/*": ["./src/*"]
7 | },
8 | },
9 | "include": ["."],
10 | "exclude": ["node_modules", "dist"]
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/packages/ui/tsconfig.lint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "outDir": "dist"
5 | },
6 | "include": ["src", "turbo"],
7 | "exclude": ["node_modules", "dist"]
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'apps/*'
3 | - 'packages/*'
4 | - 'tooling/*'
--------------------------------------------------------------------------------
/tooling/cli/templates/base/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/base.json"
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/tooling/cli/templates/base/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "ui": "tui",
4 | "tasks": {
5 | "build": {
6 | "dependsOn": ["^build"],
7 | "inputs": ["$TURBO_DEFAULT$", ".env*"],
8 | "outputs": [".next/**", "!.next/cache/**", "dist/**"]
9 | },
10 | "lint": {
11 | "dependsOn": ["^lint"]
12 | },
13 | "check-types": {
14 | "dependsOn": ["^check-types"]
15 | },
16 | "dev": {
17 | "cache": false,
18 | "persistent": true
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 |
32 | # env files (can opt-in for commiting if needed)
33 | .env*
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
42 | # contentlayer
43 | .contentlayer
44 |
45 | # uploaded files (temporary storage)
46 | /public/uploads
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/app/(home)/layout.tsx:
--------------------------------------------------------------------------------
1 | import { LandingPageLayout } from '@/shared/layouts/LandingPageLayout'
2 |
3 | export default function Layout({ children }: { children: React.ReactNode }) {
4 | return {children}
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/app/(home)/page.tsx:
--------------------------------------------------------------------------------
1 | import { HomePage } from '@/features/home/components/HomePage'
2 |
3 | export default function Home() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/app/docs/layout.tsx:
--------------------------------------------------------------------------------
1 | import { DocsLayout } from '@/shared/layouts/DocsLayout'
2 |
3 | export default function Layout({ children }: { children: React.ReactNode }) {
4 | return }>{children}
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/app/docs/not-found.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import Link from 'next/link'
3 |
4 | export default function NotFound() {
5 | return (
6 |
7 |
Not Found
8 |
Could not find document
9 |
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/app/error.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import React from 'react'
4 |
5 | export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
6 | React.useEffect(() => {
7 | console.error(error)
8 | }, [error])
9 |
10 | return (
11 |
12 |
Something went wrong!
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/app/layout-preview/dashboard/[id]/layout.tsx:
--------------------------------------------------------------------------------
1 | import { DashboardLayout } from './DashboardLayout'
2 | import { cookies } from 'next/headers'
3 |
4 | interface LayoutProps {
5 | children: React.ReactNode
6 | }
7 |
8 | export default async function Layout({ children }: LayoutProps) {
9 | const cookieStore = await cookies()
10 | const defaultOpen = cookieStore.get('sidebar_state')?.value !== 'false'
11 |
12 | return {children}
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import Link from 'next/link'
3 |
4 | export default function NotFound() {
5 | return (
6 |
7 |
Not Found
8 |
Could not find requested resource
9 |
12 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "",
8 | "css": "../../packages/ui/src/styles/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true
11 | },
12 | "iconLibrary": "lucide",
13 | "aliases": {
14 | "components": "@/components",
15 | "hooks": "@/hooks",
16 | "lib": "@/lib",
17 | "utils": "@workspace/ui/lib/utils",
18 | "ui": "@workspace/ui/components"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-basic.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Basic Form
3 | description: Learn how to create and use a basic form, including setup, input fields, and form submission handling.
4 | ---
5 |
6 | ## Usage
7 |
8 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-conditional-fields.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Conditional Fields
3 | description: Show and validate fields based on other field values.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-dependant-validation.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Dependent Validation
3 | description: Validate a field based on the value of another field.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-field-array.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Field Array
3 | description: Dynamically add and remove groups of fields with validation.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-large.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Large Form
3 | description: Build a multi-section form with arrays, selectors and toggles.
4 | ---
5 |
6 | ## Usage
7 | For large forms, you can split the form into multiple sub-sections. Within each section, use `useFormContext` to access the parent form.
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-submission-errors.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Submission Errors
3 | description: Handle server-side submission errors and map them to fields.
4 | ---
5 |
6 | ## Usage
7 | Submission errors generally fall into two categories: field-specific errors and general form errors. Here’s a common approach to display both types:
8 | - For field-specific errors, use `setSubmitErrors`.
9 | - For general form errors, simply display a toast message.
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-validation.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Validation Form
3 | description: Add client-side validation rules to inputs using our helpers.
4 | ---
5 |
6 | ## Usage
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/guide/form-with-loading.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Form with Loading
3 | description: Learn how to build a form with a loading overlay, handling form state and UX during async operations.
4 | ---
5 |
6 | ## Usage
7 | Simply wrap your form fields with the `LoadingOverlay` component and set `isLoading = true` when submitting data.
8 |
9 | If you're using a mutation from React Query, pass the `isPending` state to `isLoading`.
10 |
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/accordion.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Accordion
3 | description: A vertically stacked set of interactive headings that each reveal a section of content.
4 | originalDocs: https://www.radix-ui.com/primitives/docs/components/accordion
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Accordion.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/avatar.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Avatar
3 | description: An image element with a fallback to represent the user, and displays a profile picture, initials, or an icon.
4 | originalDocs: https://www.radix-ui.com/primitives/docs/components/avatar
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Avatar.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Different Sizes
14 |
15 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/calendar.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Calendar
3 | description: A calendar displays a grid of days in one or more months and allows users to select a single date.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Calendar.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Calendar.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
12 | ## Examples
13 |
14 | ### Default
15 |
16 |
17 |
18 | ### Controlled
19 |
20 |
21 |
22 | ### Unstyled
23 |
24 |
25 |
26 | ### With Min/Max Date
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/checkbox.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Checkbox
3 | description: A control that allows the user to toggle between checked and not checked states.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Checkbox.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Checkbox.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Default
14 |
15 |
16 | ### Disabled
17 |
18 |
19 | ### Indeterminate
20 |
21 |
22 | ### Group
23 |
24 |
25 | ### In Form
26 |
27 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/combobox.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: ComboBox
3 | description: A combobox combines a text input with a listbox, allowing users to filter a list of options to find the one they want.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/ComboBox.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/ComboBox.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/confirm-dialog.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Confirm Dialog
3 | description: A confirm dialog is a modal window that asks users to confirm or cancel a critical action.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Dialog.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/ConfirmDialog.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Basic
14 |
15 |
16 | ### Destructive
17 |
18 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/dialog.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Dialog
3 | description: A dialog is a window overlaid on either the primary window or another dialog window.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Dialog.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Dialog.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/file-trigger.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: FileTrigger
3 | description: A FileTrigger allows a user to access the file system with any pressable React Aria or React Spectrum component, or custom components built with usePress.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/FileTrigger.html
5 | ---
6 |
7 | ## Demo
8 |
9 |
10 | ## Examples
11 |
12 | ### Avatar
13 | We recommend validating files by their extensions, as MIME types may be inconsistent across platforms.
14 |
15 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/loading-overlay.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Loading Overlay
3 | description: A simple overlay spinner to indicate loading states and prevent user interaction.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/LoadingOverlay.tsx
5 | ---
6 |
7 | ## Usage
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/menu.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Menu
3 | description: A menu displays a list of actions or options in a popover.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Menu.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Menu.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
12 | ## Examples
13 |
14 | ### With Icon
15 |
16 |
17 | ### With Submenu
18 |
19 |
20 | ### With Keyboard Shortcuts
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/nprogress.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: NProgress
3 | description: Slim progress bars for Ajax'y applications. Inspired by Google, YouTube, and Medium.
4 | originalDocs: https://github.com/rstacruz/nprogress
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/NProgress.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/pagination.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Pagination
3 | description: A ReactJS component to render a pagination.
4 | originalDocs: https://www.npmjs.com/package/react-paginate
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Pagination.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
12 | ## Examples
13 |
14 | ### Using query parameters
15 |
16 |
17 |
18 | ### With page selector
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/popover.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Popover
3 | description: A popover is an overlay element positioned relative to a trigger.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Popover.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Popover.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Bottom Left
14 |
15 |
16 | ### Bottom Right
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/radio-group.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Radio Group
3 | description: A set of checkable buttons, known as radio buttons, where no more than one of the buttons can be checked at a time.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/RadioGroup.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/RadioGroup.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Default
14 |
15 |
16 | ### Horizontal
17 |
18 |
19 | ### Disabled
20 |
21 |
22 | ### In Form
23 |
24 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/separator.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Separator
3 | description: Visually or semantically separates content.
4 | originalDocs: https://www.radix-ui.com/primitives/docs/components/separator
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Separator.tsx
6 | ---
7 |
8 | ## Demo
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/sheet.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Sheet
3 | description: Extends the Dialog component to display content that complements the main content of the screen.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Dialog.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Sheet.tsx
6 | ---
7 |
8 | ## Usage
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/skeleton.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Skeleton
3 | description: Use to show a placeholder while content is loading.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Skeleton.tsx
5 | ---
6 |
7 | ## Demo
8 |
9 |
10 | ## Examples
11 |
12 | ### Skeleton screen
13 | Below is an example of a general-purpose skeleton used to represent a full screen layout while loading.
14 | Although this version works for many use cases, consider creating page-specific skeletons for a more accurate loading experience.
15 |
16 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/sonner.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Sonner
3 | description: An opinionated toast component for React.
4 | originalDocs: https://sonner.emilkowal.ski
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Sonner.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/spinner.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Spinner
3 | description: An indicator that can be used to show a loading state.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Spinner.tsx
5 | ---
6 |
7 | ## Usage
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/switch.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Switch
3 | description: A control that allows the user to toggle between checked and not checked.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Switch.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Switch.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Default
14 |
15 |
16 | ### Disabled
17 |
18 |
19 | ### In Form
20 |
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/table.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Table
3 | description: A responsive table component.
4 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Table.tsx
5 | ---
6 |
7 | ## Usage
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/tooltip.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Tooltip
3 | description: A tooltip provides a short description of an element on hover or focus.
4 | originalDocs: https://react-spectrum.adobe.com/react-aria/Tooltip.html
5 | sourceCode: https://github.com/henry-phm/base-stack/blob/main/packages/ui/src/components/Tooltip.tsx
6 | ---
7 |
8 | ## Usage
9 |
10 |
11 | ## Examples
12 |
13 | ### Basic Tooltip
14 |
15 |
16 | ### Tooltip with Custom Content
17 |
18 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/content/docs/ui/unused.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: This is just a file to trigger deployment
3 | description: v5
4 | ---
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { nextJsConfig } from "@workspace/eslint-config/next-js"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default nextJsConfig
5 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/features/docs/components/TocPortal.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 | import { useMounted } from '@/shared/hooks/useMounted'
3 | import * as Portal from '@radix-ui/react-portal'
4 |
5 | export function TocPortal({ children }: { children: React.ReactNode }) {
6 | const mounted = useMounted()
7 |
8 | if (!mounted) return null
9 |
10 | return {children}
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/features/home/components/HomePage.tsx:
--------------------------------------------------------------------------------
1 | import { HeroSection } from '@/features/home/components/HeroSection'
2 | import { Separator } from '@workspace/ui/components/Separator'
3 | import { FooterSection } from '@/features/home/components/FooterSection'
4 | import { FeatureSection } from '@/features/home/components/FeatureSection'
5 |
6 | export function HomePage() {
7 | return (
8 | <>
9 |
10 |
11 |
12 |
13 |
14 | >
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from 'next'
2 | import { withContentlayer } from 'next-contentlayer2'
3 |
4 | const nextConfig: NextConfig = withContentlayer({
5 | images: {
6 | domains: ['images.unsplash.com'],
7 | },
8 | async redirects() {
9 | return [
10 | {
11 | source: '/docs/guide',
12 | destination: '/docs/guide/introduction',
13 | permanent: false,
14 | },
15 | {
16 | source: '/docs/ui',
17 | destination: '/docs/ui/button',
18 | permanent: false,
19 | },
20 | ]
21 | },
22 | })
23 |
24 | export default nextConfig
25 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from "@workspace/ui/postcss.config";
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/hero-background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/hero-background.webp
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/images/folder-feature-based.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/images/folder-feature-based.avif
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/images/folder-features.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/images/folder-features.avif
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/images/folder-import-flow.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/images/folder-import-flow.avif
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/images/folder-overview.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/images/folder-overview.avif
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/images/folder-routing.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/images/folder-routing.avif
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/images/folder-shared.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/images/folder-shared.avif
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/images/og-image-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/images/og-image-2.jpg
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/docs/public/logo.png
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/actions/examples/payments.type.ts:
--------------------------------------------------------------------------------
1 | export interface Payment {
2 | id: string
3 | amount: string
4 | status: 'pending' | 'processing' | 'success' | 'failed'
5 | email: string
6 | paymentMethod: 'credit_card' | 'debit_card' | 'paypal' | 'bank_transfer'
7 | transactionDate: string
8 | paymentReference: string
9 | }
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/Logo.tsx:
--------------------------------------------------------------------------------
1 | import { PROJECT_NAME } from '@/shared/consts/common'
2 | import { cn } from '@workspace/ui/lib/utils'
3 | import Link from 'next/link'
4 |
5 | interface LogoProps {
6 | className?: string
7 | textClassName?: string
8 | withName?: boolean
9 | }
10 |
11 | export function Logo({ className, textClassName, withName = true }: LogoProps) {
12 | return (
13 |
14 |
15 | {withName && (
16 | {PROJECT_NAME}
17 | )}
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/AvatarDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/Avatar'
2 |
3 | export function AvatarDemo() {
4 | return (
5 |
6 |
7 | HP
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonAsALink.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { SquareArrowOutUpRight } from 'lucide-react'
3 | import Link from 'next/link'
4 |
5 | export function ButtonAsALink() {
6 | return (
7 |
13 | )
14 | }
15 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonDestructive.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonDestructive() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonGhost.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonGhost() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonIcon.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Trash } from 'lucide-react'
3 |
4 | export function ButtonIcon() {
5 | return (
6 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonLoading.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Spinner } from '@workspace/ui/components/Spinner'
3 |
4 | export function ButtonLoading() {
5 | return (
6 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonOutline.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 |
3 | export function ButtonOutline() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/ButtonWithIcon.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Plus } from 'lucide-react'
3 |
4 | export function ButtonWithIcon() {
5 | return (
6 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/CalendarControlled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsCalendar } from '@workspace/ui/components/Calendar'
4 | import { useState } from 'react'
5 |
6 | export function CalendarControlled() {
7 | const [value, setValue] = useState()
8 |
9 | return (
10 |
11 |
12 |
13 | {value ? JSON.stringify(value) : 'No value'}
14 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/CalendarDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function CalendarDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/CalendarMinMax.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsCalendar } from '@workspace/ui/components/Calendar'
4 | import dayjs from 'dayjs'
5 |
6 | export function CalendarMinMax() {
7 | return (
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/CalendarUnstyled.tsx:
--------------------------------------------------------------------------------
1 | import { BsCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function CalendarUnstyled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/CheckboxDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Checkbox } from '@workspace/ui/components/Checkbox'
2 |
3 | export function CheckboxDemo() {
4 | return Accept terms and conditions
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/CheckboxDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { Checkbox } from '@workspace/ui/components/Checkbox'
2 |
3 | export function CheckboxDisabled() {
4 | return Accept terms and conditions
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/CheckboxGroupDemo.tsx:
--------------------------------------------------------------------------------
1 | import { CheckboxGroup, Checkbox } from '@workspace/ui/components/Checkbox'
2 | import { Label } from '@workspace/ui/components/Field'
3 |
4 | export function CheckboxGroupDemo() {
5 | return (
6 |
7 |
8 |
9 | Apple
10 | Banana
11 | Orange
12 |
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DateFieldDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDateField } from '@workspace/ui/components/Datefield'
4 |
5 | export function DateFieldDemo() {
6 | return
7 | }
8 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DateFieldDisabled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDateField } from '@workspace/ui/components/Datefield'
4 |
5 | export function DateFieldDisabled() {
6 | return
7 | }
8 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DateFieldWithLabel.tsx:
--------------------------------------------------------------------------------
1 | import { BsDateField } from '@workspace/ui/components/Datefield'
2 | import { Label } from '@workspace/ui/components/Field'
3 |
4 | export function DateFieldWithLabel() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DatePickerDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsDatePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DatePickerDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DatePickerDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsDatePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DatePickerDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DatePickerWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDatePicker } from '@workspace/ui/components/DatePicker'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function DatePickerWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DateRangePickerDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsDateRangePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DateRangePickerDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DateRangePickerDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsDateRangePicker } from '@workspace/ui/components/DatePicker'
2 |
3 | export function DateRangePickerDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/DateRangePickerWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsDateRangePicker } from '@workspace/ui/components/DatePicker'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function DateRangePickerWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/InputDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from '@workspace/ui/components/Textfield'
2 |
3 | export function InputDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/InputDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from '@workspace/ui/components/Textfield'
2 |
3 | export function InputDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/InputFile.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from '@workspace/ui/components/Textfield'
2 |
3 | export function InputFile() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/InputWithButton.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { Input } from '@workspace/ui/components/Textfield'
3 |
4 | export function InputWithButton() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/InputWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Input } from '@workspace/ui/components/Textfield'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function InputWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/MenuDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Button } from '@workspace/ui/components/Button'
4 | import { Menu, MenuItem, MenuPopover, MenuTrigger } from '@workspace/ui/components/Menu'
5 | import { MenuIcon } from 'lucide-react'
6 |
7 | export function MenuDemo() {
8 | return (
9 |
10 |
13 |
14 |
19 |
20 |
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/MenuWithKeyboard.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { MenuTrigger, MenuItem, MenuKeyboard, MenuPopover, Menu } from '@workspace/ui/components/Menu'
3 |
4 | export function MenuWithKeyboard() {
5 | return (
6 |
7 |
8 |
9 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldCurrency.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldCurrency() {
4 | return (
5 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldMinMax.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldMinMax() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldPercentages.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldPercentages() {
4 | return (
5 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldUnits.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldUnits() {
4 | return (
5 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldWithLabel.tsx:
--------------------------------------------------------------------------------
1 | import { Label } from '@workspace/ui/components/Field'
2 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
3 |
4 | export function NumberFieldWithLabel() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/NumberFieldWithoutStepper.tsx:
--------------------------------------------------------------------------------
1 | import { BsNumberField } from '@workspace/ui/components/Numberfield'
2 |
3 | export function NumberFieldWithoutStepper() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/PaginationDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Pagination } from '@workspace/ui/components/Pagination'
2 |
3 | export function PaginationDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/PaginationWithPageSelector.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Pagination, PaginationPageSizeSelector } from '@workspace/ui/components/Pagination'
4 |
5 | export function PaginationWithPageSelector() {
6 | return (
7 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RadioGroupDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Label } from '@workspace/ui/components/Field'
4 | import { RadioGroup, Radio } from '@workspace/ui/components/RadioGroup'
5 |
6 | export function RadioGroupDemo() {
7 | return (
8 |
9 |
10 | Red
11 | Green
12 | Blue
13 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RadioGroupDisabled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Label } from '@workspace/ui/components/Field'
4 | import { RadioGroup, Radio } from '@workspace/ui/components/RadioGroup'
5 |
6 | export function RadioGroupDisabled() {
7 | return (
8 |
9 |
10 | Red
11 | Blue
12 | Green
13 | Yellow
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RadioGroupHorizontal.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Label } from '@workspace/ui/components/Field'
4 | import { RadioGroup, Radio } from '@workspace/ui/components/RadioGroup'
5 |
6 | export function RadioGroupHorizontal() {
7 | return (
8 |
9 |
10 | xs
11 | sm
12 | md
13 | lg
14 | xl
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RangeCalendarControlled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsRangeCalendar, BsRangeCalendarValue } from '@workspace/ui/components/Calendar'
4 | import { useState } from 'react'
5 |
6 | export function RangeCalendarControlled() {
7 | const [value, setValue] = useState()
8 |
9 | return (
10 |
11 |
12 |
13 | {value ? JSON.stringify(value, null, 2) : 'No value'}
14 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RangeCalendarDefault.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function RangeCalendarDefault() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RangeCalendarDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 | import dayjs from 'dayjs'
3 |
4 | export function RangeCalendarDemo() {
5 | return (
6 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RangeCalendarMinMax.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 | import dayjs from 'dayjs'
3 |
4 | export function RangeCalendarMinMax() {
5 | return (
6 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/RangeCalendarUnstyled.tsx:
--------------------------------------------------------------------------------
1 | import { BsRangeCalendar } from '@workspace/ui/components/Calendar'
2 |
3 | export function RangeCalendarUnstyled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SelectDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsSelect } from '@workspace/ui/components/Select'
4 | import React from 'react'
5 |
6 | const languages = [
7 | { id: 1, name: 'English' },
8 | { id: 2, name: 'Spanish' },
9 | { id: 3, name: 'French' },
10 | { id: 4, name: 'German' },
11 | { id: 5, name: 'Italian' },
12 | ]
13 |
14 | export function SelectDemo() {
15 | return (
16 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SelectDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 |
3 | export function SelectDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SelectMultiple.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsSelect } from '@workspace/ui/components/Select'
4 |
5 | const languages = [
6 | { id: 1, name: 'English' },
7 | { id: 2, name: 'Spanish' },
8 | { id: 3, name: 'French' },
9 | { id: 4, name: 'German' },
10 | { id: 5, name: 'Italian' },
11 | ]
12 |
13 | export function SelectMultiple() {
14 | return
15 | }
16 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SelectMultipleDisabled.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { BsSelect } from '@workspace/ui/components/Select'
4 |
5 | const languages = [
6 | { id: 1, name: 'English' },
7 | { id: 2, name: 'Spanish' },
8 | { id: 3, name: 'French' },
9 | { id: 4, name: 'German' },
10 | { id: 5, name: 'Italian' },
11 | ]
12 |
13 | export function SelectMultipleDisabled() {
14 | return
15 | }
16 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SelectMultipleSearchable.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 |
3 | const languages = [
4 | { id: 1, name: 'English' },
5 | { id: 2, name: 'Spanish' },
6 | { id: 3, name: 'French' },
7 | { id: 4, name: 'German' },
8 | { id: 5, name: 'Italian' },
9 | ]
10 |
11 | export function SelectMultipleSearchable() {
12 | return
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SelectSearchable.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 |
3 | const languages = [
4 | { id: 1, name: 'English' },
5 | { id: 2, name: 'Spanish' },
6 | { id: 3, name: 'French' },
7 | { id: 4, name: 'German' },
8 | { id: 5, name: 'Italian' },
9 | ]
10 |
11 | export function SelectSearchable() {
12 | return
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SelectWithClearButton.tsx:
--------------------------------------------------------------------------------
1 | import { BsSelect } from '@workspace/ui/components/Select'
2 | import React from 'react'
3 |
4 | const languages = [
5 | { id: 1, name: 'English' },
6 | { id: 2, name: 'Spanish' },
7 | { id: 3, name: 'French' },
8 | { id: 4, name: 'German' },
9 | { id: 5, name: 'Italian' },
10 | ]
11 |
12 | export function SelectWithClearButton() {
13 | return (
14 |
15 |
16 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SkeletonDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from '@workspace/ui/components/Skeleton'
2 |
3 | export function SkeletonDemo() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SpinnerDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Spinner } from '@workspace/ui/components/Spinner'
2 |
3 | export function SpinnerDemo() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SwitchDemo.tsx:
--------------------------------------------------------------------------------
1 | import { Switch } from '@workspace/ui/components/Switch'
2 |
3 | export function SwitchDemo() {
4 | return Airplane mode
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/SwitchDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { Switch } from '@workspace/ui/components/Switch'
2 |
3 | export function SwitchDisabled() {
4 | return Airplane mode
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TextAreaDemo.tsx:
--------------------------------------------------------------------------------
1 | import { TextArea } from '@workspace/ui/components/Textfield'
2 |
3 | export function TextAreaDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TextAreaDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { TextArea } from '@workspace/ui/components/Textfield'
2 |
3 | export function TextAreaDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TextAreaWithButton.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { TextArea } from '@workspace/ui/components/Textfield'
3 |
4 | export function TextAreaWithButton() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TextAreaWithLabel.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { TextArea } from '@workspace/ui/components/Textfield'
4 | import { Label } from '@workspace/ui/components/Field'
5 |
6 | export function TextAreaWithLabel() {
7 | return (
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TimeFieldDemo.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 |
3 | export function TimeFieldDemo() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TimeFieldDisabled.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 |
3 | export function TimeFieldDisabled() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TimeFieldGranularity.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 |
3 | export function TimeFieldGranularity() {
4 | return
5 | }
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TimeFieldWithLabel.tsx:
--------------------------------------------------------------------------------
1 | import { BsTimeField } from '@workspace/ui/components/Datefield'
2 | import { Label } from '@workspace/ui/components/Field'
3 |
4 | export function TimeFieldWithLabel() {
5 | return (
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/TooltipDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Button } from '@workspace/ui/components/Button'
4 | import { Tooltip, TooltipTrigger } from '@workspace/ui/components/Tooltip'
5 | import { Pencil } from 'lucide-react'
6 |
7 | export function TooltipDemo() {
8 | return (
9 |
10 |
13 | Edit
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/UploaderDemo.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Uploader } from '@workspace/ui/components/Uploader'
4 | import { CustomUploaderAction } from './UploaderDemo.utils'
5 |
6 | export function UploaderDemo() {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/UploaderDemo.utils.ts:
--------------------------------------------------------------------------------
1 | import { UploaderAction } from '@workspace/ui/components/Uploader'
2 | import { AxiosResponse } from 'axios'
3 |
4 | interface TmpResponse {
5 | status: string
6 | data: {
7 | url: string
8 | }
9 | }
10 |
11 | export class CustomUploaderAction extends UploaderAction {
12 | constructor() {
13 | super('https://tmpfiles.org/api/v1/upload')
14 | }
15 |
16 | formatResponse(response: AxiosResponse) {
17 | const url = response.data?.data?.url
18 | const id = url.split('/').slice(-2).join('/')
19 | const downloadUrl = `https://tmpfiles.org/dl/${id}`
20 |
21 | return {
22 | id: url,
23 | url: downloadUrl,
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/UploaderRetry.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Uploader, UploaderAction } from '@workspace/ui/components/Uploader'
4 |
5 | export function UploaderRetry() {
6 | return (
7 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/examples/UploaderValidation.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { Uploader } from '@workspace/ui/components/Uploader'
4 | import { CustomUploaderAction } from './UploaderDemo.utils'
5 |
6 | export function UploaderValidation() {
7 | return (
8 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/icons/ReactAriaIcon.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function ReactAriaIcon({ className }: { className?: string }) {
4 | return (
5 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/icons/ShadcnIcon.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@workspace/ui/lib/utils'
2 | import * as React from 'react'
3 |
4 | export function ShadcnIcon({ className }: { className?: string }) {
5 | return (
6 |
17 | )
18 | }
19 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/mdx-helpers/MdxImage.tsx:
--------------------------------------------------------------------------------
1 | export function MdxImage({ src, alt }: { src: string; alt: string }) {
2 | return (
3 |
4 |

5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/components/mdx-helpers/MdxTip.tsx:
--------------------------------------------------------------------------------
1 | import { InfoIcon } from 'lucide-react'
2 |
3 | interface MdxTipProps {
4 | children: React.ReactNode
5 | title: string
6 | }
7 |
8 | export function MdxTip({ children, title = 'Note' }: MdxTipProps) {
9 | return (
10 |
11 |
12 |
13 |
14 | {title}
15 |
16 |
{children}
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/consts/common.ts:
--------------------------------------------------------------------------------
1 | export const PROJECT_NAME = 'BaseStack'
2 | export const PROJECT_NAME_SLUG = 'base-stack'
3 | export const PROJECT_DESCRIPTION =
4 | 'A modern React starter kit with best practices and all the essentials to quickly launch your frontend.'
5 | export const GITHUB_URL = `https://github.com/henry-phm/${PROJECT_NAME_SLUG}`
6 | export const GITHUB_URL_AUTHOR = 'https://github.com/henry-phm'
7 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/hooks/useMounted.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function useMounted() {
4 | const [mounted, setMounted] = React.useState(false)
5 |
6 | React.useEffect(() => {
7 | setMounted(true)
8 | }, [])
9 |
10 | return mounted
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/layouts/DocsLayout/Icons.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function CrossIcon({ className }: { className?: string }) {
4 | return (
5 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/layouts/DocsLayout/SidebarHeader.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Logo } from '@/shared/components/Logo'
3 |
4 | export function SidebarHeader() {
5 | return (
6 |
7 |
8 |
9 | )
10 | }
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/layouts/DocsSearch.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from '@workspace/ui/components/Button'
2 | import { SearchIcon } from 'lucide-react'
3 |
4 | export function DocsSearch() {
5 | // TODO: Add search functionality
6 | return null
7 |
8 | return (
9 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/layouts/HeaderIconButtons.tsx:
--------------------------------------------------------------------------------
1 | import { GithubIcon } from '@/shared/components/icons/GithubIcon'
2 | import { ThemeSwitcher } from '@/shared/components/ThemeSwitcher'
3 | import { GITHUB_URL } from '@/shared/consts/common'
4 | import { DocsSearch } from '@/shared/layouts/DocsSearch'
5 | import { Button } from '@workspace/ui/components/Button'
6 | import Link from 'next/link'
7 |
8 | export function HeaderIconButtons() {
9 | return (
10 |
11 |
12 |
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/lib/composition.ts:
--------------------------------------------------------------------------------
1 | import { readFile } from 'node:fs/promises'
2 | import { resolve } from 'node:path'
3 |
4 | export const readExampleFile = async (name: string, ext = 'tsx') => {
5 | const filePath = resolve(`shared/components/examples`, `${name}.${ext}`)
6 |
7 | const fileContent = await readFile(filePath, 'utf-8')
8 |
9 | return fileContent
10 | }
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/docs/shared/lib/highlight-code.ts:
--------------------------------------------------------------------------------
1 | import { codeToHtml } from 'shiki'
2 |
3 | export const highlightCode = (code: string, opts?: Partial[1]>) => {
4 | return codeToHtml(code, {
5 | lang: 'tsx',
6 | themes: {
7 | light: 'github-light',
8 | dark: 'github-dark',
9 | },
10 | colorReplacements: {
11 | '#fff': '#FAFAFA',
12 | '#24292e': '#212121',
13 | },
14 | ...opts,
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "",
8 | "css": "../../packages/ui/src/styles/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true
11 | },
12 | "iconLibrary": "lucide",
13 | "aliases": {
14 | "components": "@/components",
15 | "hooks": "@/hooks",
16 | "lib": "@/lib",
17 | "utils": "@workspace/ui/lib/utils",
18 | "ui": "@workspace/ui/components"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { nextJsConfig } from "@workspace/eslint-config/next-js"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default nextJsConfig
5 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | transpilePackages: ["@workspace/ui"],
4 | }
5 |
6 | export default nextConfig
7 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from "@workspace/ui/postcss.config";
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/henry-phm/base-stack/260b64035a0ebfbb440e238e5b66b5ee7d9feeed/tooling/cli/templates/extras/apps/next/src/app/favicon.ico
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Providers } from '@/shared/components/Providers'
2 | import '@workspace/ui/globals.css'
3 |
4 | export default function RootLayout({
5 | children,
6 | }: Readonly<{
7 | children: React.ReactNode
8 | }>) {
9 | return (
10 |
11 |
12 | {children}
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/src/shared/components/ThemeSwitcher.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useMounted } from '@/shared/hooks/useMounted'
4 | import { Button } from '@workspace/ui/components/Button'
5 | import { MoonStar, SunIcon } from 'lucide-react'
6 | import { useTheme } from 'next-themes'
7 |
8 | enum Theme {
9 | LIGHT = 'light',
10 | DARK = 'dark',
11 | }
12 |
13 | export function ThemeSwitcher() {
14 | const { theme, setTheme } = useTheme()
15 | const mounted = useMounted()
16 |
17 | return (
18 |
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/src/shared/hooks/useMounted.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | export function useMounted() {
4 | const [mounted, setMounted] = React.useState(false)
5 |
6 | React.useEffect(() => {
7 | setMounted(true)
8 | }, [])
9 |
10 | return mounted
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/src/shared/lib/api.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Api } from '@workspace/lib/api'
3 |
4 | export type * from '@workspace/lib/api'
5 |
6 | export const api = new Api(
7 | axios.create({
8 | baseURL: 'http://localhost:8080', // TODO: move to env
9 | }),
10 | )
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/next/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./src/*"],
7 | "@workspace/ui/*": ["../../packages/ui/src/*"]
8 | },
9 | "plugins": [
10 | {
11 | "name": "next"
12 | }
13 | ]
14 | },
15 | "include": [
16 | "next-env.d.ts",
17 | "next.config.ts",
18 | "**/*.ts",
19 | "**/*.tsx",
20 | ".next/types/**/*.ts"
21 | ],
22 | "exclude": ["node_modules"]
23 | }
24 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | dist-ssr
5 | *.local
6 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.watcherExclude": {
3 | "**/routeTree.gen.ts": true
4 | },
5 | "search.exclude": {
6 | "**/routeTree.gen.ts": true
7 | },
8 | "files.readonlyInclude": {
9 | "**/routeTree.gen.ts": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | To run this example:
4 |
5 | - `npm install` or `yarn`
6 | - `npm start` or `yarn start`
7 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { config } from "@workspace/eslint-config/react-internal"
2 |
3 | /** @type {import("eslint").Linter.Config} */
4 | export default config
5 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Vite App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from "@workspace/ui/postcss.config";
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/src/main.tsx:
--------------------------------------------------------------------------------
1 | import ReactDOM from 'react-dom/client'
2 | import { RouterProvider, createRouter } from '@tanstack/react-router'
3 | import { routeTree } from './routeTree.gen'
4 | import '@workspace/ui/globals.css'
5 |
6 | // Set up a Router instance
7 | const router = createRouter({
8 | routeTree,
9 | defaultPreload: 'intent',
10 | scrollRestoration: true,
11 | })
12 |
13 | // Register things for typesafety
14 | declare module '@tanstack/react-router' {
15 | interface Register {
16 | router: typeof router
17 | }
18 | }
19 |
20 | const rootElement = document.getElementById('app')!
21 |
22 | if (!rootElement.innerHTML) {
23 | const root = ReactDOM.createRoot(rootElement)
24 | root.render()
25 | }
26 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/src/routes/__root.tsx:
--------------------------------------------------------------------------------
1 | import { Outlet, createRootRoute } from '@tanstack/react-router'
2 | import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
3 | import { Providers } from '@/shared/components/Providers'
4 |
5 | export const Route = createRootRoute({
6 | component: RootComponent,
7 | })
8 |
9 | function RootComponent() {
10 | return (
11 |
12 |
13 |
14 |
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/src/shared/components/ThemeSwitcher.tsx:
--------------------------------------------------------------------------------
1 | 'use client'
2 |
3 | import { useTheme } from '@/shared/components/ThemeProvider'
4 | import { Button } from '@workspace/ui/components/Button'
5 | import { MoonStar, SunIcon } from 'lucide-react'
6 |
7 | export function ThemeSwitcher() {
8 | const { theme, setTheme } = useTheme()
9 |
10 | return (
11 |
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/src/shared/lib/api.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { Api } from '@workspace/lib/api'
3 |
4 | export type * from '@workspace/lib/api'
5 |
6 | export const api = new Api(
7 | axios.create({
8 | baseURL: 'http://localhost:8080', // TODO: move to env
9 | }),
10 | )
11 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./src/*"],
7 | "@workspace/ui/*": ["../../packages/ui/src/*"]
8 | },
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/tooling/cli/templates/extras/apps/tanstack-router/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import { tanstackRouter } from '@tanstack/router-plugin/vite'
4 | import { resolve } from 'node:path'
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [tanstackRouter({ target: 'react', autoCodeSplitting: true }), react()],
9 | resolve: {
10 | alias: {
11 | '@': resolve(__dirname, './src'),
12 | },
13 | },
14 | })
15 |
--------------------------------------------------------------------------------
/tooling/cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2019",
4 | "moduleResolution": "bundler",
5 | "strict": true,
6 | "resolveJsonModule": true,
7 | "esModuleInterop": true,
8 | "skipLibCheck": false
9 | },
10 | "exclude": ["templates", "dist"]
11 | }
12 |
--------------------------------------------------------------------------------
/tooling/cli/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'tsup'
2 |
3 | export default defineConfig({
4 | entry: ['index.ts'],
5 | splitting: false,
6 | sourcemap: true,
7 | clean: true,
8 | })
9 |
--------------------------------------------------------------------------------
/tooling/cli/utils/error-handling.ts:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk'
2 |
3 | interface ShowErrorOptions {
4 | exit?: boolean
5 | code?: number
6 | hint?: string
7 | }
8 |
9 | export function showError(message: string, options: ShowErrorOptions = {}) {
10 | const { exit = true, code = 1, hint } = options
11 |
12 | console.error(chalk.red('✗ Error:'), message)
13 |
14 | if (hint) {
15 | console.error(chalk.dim(` Hint: ${hint}`))
16 | }
17 |
18 | if (exit) {
19 | process.exit(code)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@workspace/typescript-config/base.json"
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "ui": "tui",
4 | "tasks": {
5 | "build": {
6 | "dependsOn": ["^build"],
7 | "inputs": ["$TURBO_DEFAULT$", ".env*"],
8 | "outputs": [".next/**", "!.next/cache/**", "dist/**"]
9 | },
10 | "lint": {
11 | "dependsOn": ["^lint"]
12 | },
13 | "check-types": {
14 | "dependsOn": ["^check-types"]
15 | },
16 | "dev": {
17 | "cache": false,
18 | "persistent": true
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------