├── src ├── tests │ ├── unit │ │ └── vitest.setup.ts │ └── integration │ │ └── vitest.setup.ts ├── contexts │ ├── index.tsx │ └── directon.tsx ├── components │ ├── header │ │ ├── index.tsx │ │ ├── header.tsx │ │ └── header.stories.tsx │ ├── input │ │ ├── index.tsx │ │ ├── input.stories.tsx │ │ └── input.tsx │ ├── label │ │ ├── index.tsx │ │ ├── label.stories.tsx │ │ └── label.tsx │ ├── spinner │ │ ├── index.tsx │ │ └── spinner.tsx │ ├── toaster │ │ ├── index.tsx │ │ └── toaster.tsx │ ├── checkbox │ │ ├── index.tsx │ │ └── checkbox.tsx │ ├── progress │ │ ├── index.tsx │ │ ├── progress.tsx │ │ └── progress.stories.tsx │ ├── separator │ │ ├── index.tsx │ │ ├── separator.tsx │ │ └── separator.stories.tsx │ ├── textarea │ │ ├── index.tsx │ │ └── textarea.tsx │ ├── button │ │ ├── index.tsx │ │ ├── button.types.ts │ │ ├── button.styles.ts │ │ ├── button.tsx │ │ └── button.stories.tsx │ ├── tooltip │ │ ├── index.tsx │ │ ├── tooltip-provider.tsx │ │ └── tooltip.tsx │ ├── scroll-area │ │ ├── index.tsx │ │ ├── scroll-area.tsx │ │ └── scroll-bar.tsx │ ├── radio-group │ │ ├── index.tsx │ │ ├── radio-group.tsx │ │ └── radio-group-item.tsx │ ├── color-swatch │ │ ├── index.tsx │ │ ├── color-swatch.types.ts │ │ ├── color-swatch.styles.ts │ │ ├── color-swatch.utils.ts │ │ └── color-swatch.tsx │ ├── avatar │ │ ├── index.tsx │ │ ├── avatar-image.tsx │ │ ├── avatar.tsx │ │ ├── avatar-fallback.tsx │ │ └── avatar.stories.tsx │ ├── badge │ │ ├── index.tsx │ │ ├── badge.types.ts │ │ ├── badge-dot.tsx │ │ ├── badge.tsx │ │ ├── badge-button.tsx │ │ └── badge.styles.ts │ ├── alert │ │ ├── index.tsx │ │ ├── alert.types.ts │ │ ├── alert-title.tsx │ │ ├── alert.tsx │ │ ├── alert-description.tsx │ │ └── alert.styles.ts │ ├── sheet │ │ ├── sheet.tsx │ │ ├── sheet-close.tsx │ │ ├── sheet-trigger.tsx │ │ ├── sheet-content.types.ts │ │ ├── index.tsx │ │ ├── sheet-header.tsx │ │ ├── sheet-footer.tsx │ │ ├── sheet-title.tsx │ │ ├── sheet-description.tsx │ │ ├── sheet-content.styles.ts │ │ └── sheet-content.tsx │ ├── alert-dialog │ │ ├── alert-dialog.tsx │ │ ├── alert-dialog-action.tsx │ │ ├── alert-dialog-cancel.tsx │ │ ├── alert-dialog-trigger.tsx │ │ ├── index.tsx │ │ ├── alert-dialog-header.tsx │ │ ├── alert-dialog-footer.tsx │ │ ├── alert-dialog-title.tsx │ │ ├── alert-dialog-description.tsx │ │ ├── alert-dialog-content.tsx │ │ └── alert-dialog.stories.tsx │ ├── empty │ │ ├── index.tsx │ │ ├── empty-title.tsx │ │ ├── empty-header.tsx │ │ ├── empty-content.tsx │ │ ├── empty-description.tsx │ │ ├── empty.tsx │ │ └── empty-media.tsx │ ├── select │ │ ├── index.tsx │ │ ├── select-group.tsx │ │ ├── select-label.tsx │ │ ├── select-separator.tsx │ │ ├── select-item.tsx │ │ ├── select.tsx │ │ ├── select-content.tsx │ │ └── select.stories.tsx │ ├── card │ │ ├── index.tsx │ │ ├── card-content.tsx │ │ ├── card-description.tsx │ │ ├── card-footer.tsx │ │ ├── card-title.tsx │ │ ├── card-action.tsx │ │ ├── card.tsx │ │ ├── card-header.tsx │ │ └── card.stories.tsx │ ├── dialog │ │ ├── dialog.tsx │ │ ├── dialog-content.types.ts │ │ ├── dialog-close.tsx │ │ ├── index.tsx │ │ ├── dialog-trigger.tsx │ │ ├── dialog-header.tsx │ │ ├── dialog-footer.tsx │ │ ├── dialog-title.tsx │ │ ├── dialog-description.tsx │ │ ├── dialog-content.styles.ts │ │ └── dialog-content.tsx │ ├── item │ │ ├── item-media.types.ts │ │ ├── item.types.ts │ │ ├── item-actions.tsx │ │ ├── item-group.tsx │ │ ├── item-footer.tsx │ │ ├── item-header.tsx │ │ ├── item-separator.tsx │ │ ├── item-title.tsx │ │ ├── index.tsx │ │ ├── item-content.tsx │ │ ├── item-description.tsx │ │ ├── item-media.tsx │ │ ├── item-media.styles.ts │ │ ├── item.styles.ts │ │ └── item.tsx │ ├── field │ │ ├── index.tsx │ │ ├── field-content.tsx │ │ ├── field-title.tsx │ │ ├── field-set.tsx │ │ ├── field-group.tsx │ │ ├── field-legend.tsx │ │ ├── field.tsx │ │ ├── field-description.tsx │ │ ├── field-label.tsx │ │ ├── field-separator.tsx │ │ ├── field.styles.ts │ │ └── field-error.tsx │ ├── stepper │ │ ├── index.tsx │ │ ├── stepper-item.context.tsx │ │ ├── stepper-panel.tsx │ │ ├── stepper.context.tsx │ │ ├── stepper-title.tsx │ │ ├── stepper-focus.context.tsx │ │ ├── stepper-description.tsx │ │ ├── stepper.constants.ts │ │ ├── stepper.types.ts │ │ ├── stepper-content.tsx │ │ ├── stepper-prev-trigger.tsx │ │ ├── stepper-next-trigger.tsx │ │ ├── stepper.utils.tsx │ │ ├── stepper-indicator.tsx │ │ ├── stepper-item.tsx │ │ ├── stepper.tsx │ │ └── stepper.store.tsx │ ├── index.tsx │ └── Components.mdx ├── hooks │ ├── index.tsx │ ├── use-isomorphic-layout-effect.tsx │ ├── use-lazy-ref.tsx │ ├── use-validation-log.tsx │ ├── use-isomorphic-layout-effect.test.tsx │ ├── use-lazy-ref.test.tsx │ └── use-validation-log.test.tsx ├── icons │ ├── index.tsx │ ├── auth0-logo.tsx │ ├── Iconography.mdx │ ├── x-logo.tsx │ ├── google-logo.tsx │ └── loading.tsx ├── stories │ ├── Changelog.mdx │ ├── Styles.mdx │ ├── Introduction.mdx │ ├── Typography.stories.tsx │ └── Colors.mdx ├── utils │ ├── index.ts │ └── index.test.ts ├── tailwind │ ├── scroll.css │ ├── global.css │ ├── animation.css │ └── palette.css └── scripts │ └── post-build.js ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── questions_help.yaml │ ├── documentation_issue.yaml │ ├── feature_request.yaml │ ├── security_issue.yaml │ └── bug_report.yaml ├── dependabot.yml ├── workflows │ ├── publish.yml │ ├── codeql.yml │ └── pr-check.yml └── PULL_REQUEST_TEMPLATE.md ├── eslint.config.js ├── prettier.config.ts ├── .storybook ├── preview-head.html ├── theme │ ├── dark.ts │ └── light.ts ├── manager.ts ├── main.ts └── preview.tsx ├── release.config.js ├── .prettierignore ├── tsup.config.ts ├── LICENSE ├── vitest.config.ts ├── .gitignore └── package.json /src/tests/unit/vitest.setup.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/contexts/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./directon"; 2 | -------------------------------------------------------------------------------- /src/components/header/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./header"; 2 | -------------------------------------------------------------------------------- /src/components/input/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./input"; 2 | -------------------------------------------------------------------------------- /src/components/label/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./label"; 2 | -------------------------------------------------------------------------------- /src/components/spinner/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./spinner"; 2 | -------------------------------------------------------------------------------- /src/components/toaster/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./toaster"; 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /src/components/checkbox/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./checkbox"; 2 | -------------------------------------------------------------------------------- /src/components/progress/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./progress"; 2 | -------------------------------------------------------------------------------- /src/components/separator/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./separator"; 2 | -------------------------------------------------------------------------------- /src/components/textarea/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./textarea"; 2 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | export { default } from "@szum-tech/eslint-config"; 2 | -------------------------------------------------------------------------------- /prettier.config.ts: -------------------------------------------------------------------------------- 1 | export { default } from "@szum-tech/prettier-config"; 2 | -------------------------------------------------------------------------------- /src/components/button/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./button"; 2 | export * from "./button.types"; 3 | -------------------------------------------------------------------------------- /src/components/tooltip/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./tooltip"; 2 | export * from "./tooltip-provider"; 3 | -------------------------------------------------------------------------------- /src/components/scroll-area/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./scroll-area"; 2 | export * from "./scroll-bar"; 3 | -------------------------------------------------------------------------------- /src/components/radio-group/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./radio-group"; 2 | export * from "./radio-group-item"; 3 | -------------------------------------------------------------------------------- /src/components/color-swatch/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./color-swatch"; 2 | export * from "./color-swatch.types"; 3 | -------------------------------------------------------------------------------- /src/components/avatar/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./avatar"; 2 | export * from "./avatar-image"; 3 | export * from "./avatar-fallback"; 4 | -------------------------------------------------------------------------------- /.storybook/preview-head.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/hooks/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./use-validation-log"; 2 | export * from "./use-lazy-ref"; 3 | export * from "./use-isomorphic-layout-effect"; 4 | -------------------------------------------------------------------------------- /src/icons/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./google-logo"; 2 | export * from "./loading"; 3 | export * from "./auth0-logo"; 4 | export * from "./x-logo"; 5 | -------------------------------------------------------------------------------- /release.config.js: -------------------------------------------------------------------------------- 1 | import { getConfig } from "@szum-tech/semantic-release-config"; 2 | 3 | export default getConfig({ features: { npmPublish: true, mdx: true } }); 4 | -------------------------------------------------------------------------------- /src/components/badge/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./badge"; 2 | export * from "./badge.types"; 3 | 4 | export * from "./badge-button"; 5 | export * from "./badge-dot"; 6 | -------------------------------------------------------------------------------- /src/components/alert/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./alert"; 2 | export * from "./alert.types"; 3 | 4 | export * from "./alert-description"; 5 | export * from "./alert-title"; 6 | -------------------------------------------------------------------------------- /src/components/sheet/sheet.tsx: -------------------------------------------------------------------------------- 1 | import { Dialog as ReactSheet } from "radix-ui"; 2 | 3 | export type SheetProps = ReactSheet.DialogProps; 4 | export const Sheet = ReactSheet.Root; 5 | -------------------------------------------------------------------------------- /src/hooks/use-isomorphic-layout-effect.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export const useIsomorphicLayoutEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect; 4 | -------------------------------------------------------------------------------- /src/components/sheet/sheet-close.tsx: -------------------------------------------------------------------------------- 1 | import { Dialog as ReactSheet } from "radix-ui"; 2 | 3 | export type SheetCloseProps = ReactSheet.DialogCloseProps; 4 | export const SheetClose = ReactSheet.Close; 5 | -------------------------------------------------------------------------------- /src/stories/Changelog.mdx: -------------------------------------------------------------------------------- 1 | import { Meta } from "@storybook/addon-docs/blocks"; 2 | import Changelog from "../../CHANGELOG.mdx"; 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/utils/index.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 | -------------------------------------------------------------------------------- /src/components/sheet/sheet-trigger.tsx: -------------------------------------------------------------------------------- 1 | import { Dialog as ReactSheet } from "radix-ui"; 2 | 3 | export type SheetTriggerProps = ReactSheet.DialogTriggerProps; 4 | export const SheetTrigger = ReactSheet.Trigger; 5 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog.tsx: -------------------------------------------------------------------------------- 1 | import { AlertDialog as ReactAlertDialog } from "radix-ui"; 2 | 3 | export type AlertDialogProps = ReactAlertDialog.AlertDialogProps; 4 | export const AlertDialog = ReactAlertDialog.Root; 5 | -------------------------------------------------------------------------------- /src/components/empty/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./empty"; 2 | export * from "./empty-header"; 3 | export * from "./empty-title"; 4 | export * from "./empty-description"; 5 | export * from "./empty-content"; 6 | export * from "./empty-media"; 7 | -------------------------------------------------------------------------------- /src/components/select/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./select"; 2 | export * from "./select-content"; 3 | export * from "./select-group"; 4 | export * from "./select-item"; 5 | export * from "./select-label"; 6 | export * from "./select-separator"; 7 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog-action.tsx: -------------------------------------------------------------------------------- 1 | import { AlertDialog as ReactAlertDialog } from "radix-ui"; 2 | 3 | export type AlertDialogActionProps = ReactAlertDialog.AlertDialogActionProps; 4 | export const AlertDialogAction = ReactAlertDialog.Action; 5 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog-cancel.tsx: -------------------------------------------------------------------------------- 1 | import { AlertDialog as ReactAlertDialog } from "radix-ui"; 2 | 3 | export type AlertDialogCancelProps = ReactAlertDialog.AlertDialogCancelProps; 4 | export const AlertDialogCancel = ReactAlertDialog.Cancel; 5 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog-trigger.tsx: -------------------------------------------------------------------------------- 1 | import { AlertDialog as ReactAlertDialog } from "radix-ui"; 2 | 3 | export type AlertDialogTriggerProps = ReactAlertDialog.AlertDialogTriggerProps; 4 | export const AlertDialogTrigger = ReactAlertDialog.Trigger; 5 | -------------------------------------------------------------------------------- /src/components/card/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./card"; 2 | export * from "./card-header"; 3 | export * from "./card-title"; 4 | export * from "./card-description"; 5 | export * from "./card-content"; 6 | export * from "./card-footer"; 7 | export * from "./card-action"; 8 | -------------------------------------------------------------------------------- /src/hooks/use-lazy-ref.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export function useLazyRef(fn: () => T) { 4 | const ref = React.useRef(null); 5 | 6 | if (ref.current === null) { 7 | ref.current = fn(); 8 | } 9 | 10 | return ref as React.RefObject; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/badge/badge.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type badgeVariants } from "./badge.styles"; 4 | 5 | type BadgeVariantsProps = VariantProps; 6 | 7 | export type BadgeVariant = NonNullable; 8 | -------------------------------------------------------------------------------- /src/components/alert/alert.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type alertVariants } from "~/components/alert/alert.styles"; 4 | 5 | type AlertVariantsProps = VariantProps; 6 | 7 | export type AlertVariant = NonNullable; 8 | -------------------------------------------------------------------------------- /src/components/sheet/sheet-content.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type sheetContentStyles } from "./sheet-content.styles"; 4 | 5 | type SheetContentCvaProps = VariantProps; 6 | 7 | export type SheetContentSide = NonNullable; 8 | -------------------------------------------------------------------------------- /src/components/dialog/dialog.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Dialog as DialogPrimitive } from "radix-ui"; 4 | 5 | export type DialogProps = React.ComponentProps; 6 | 7 | export function Dialog(props: DialogProps) { 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/dialog/dialog-content.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type dialogContentVariants } from "./dialog-content.styles"; 4 | 5 | type DialogContentCvaProps = VariantProps; 6 | 7 | export type DialogContentWidth = NonNullable; 8 | -------------------------------------------------------------------------------- /src/components/item/item-media.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type itemMediaVariants } from "~/components/item/item-media.styles"; 4 | 5 | type ItemMediaVariantsProps = VariantProps; 6 | 7 | export type ItemMediaVariantType = NonNullable; 8 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # build 5 | /dist 6 | /index.* 7 | /*.d.ts 8 | /chunk-*.mjs 9 | /chunk-*.js 10 | /components 11 | /contexts 12 | /hooks 13 | /theme 14 | /src/styles 15 | /storybook-static 16 | 17 | # WebStorm 18 | /.idea 19 | 20 | # VS Code 21 | /.vscode 22 | 23 | # Docs 24 | /CHANGELOG.md 25 | /CLAUDE.md 26 | /.claude -------------------------------------------------------------------------------- /src/components/card/card-content.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type CardContentProps = React.ComponentProps<"div">; 6 | 7 | export function CardContent({ className, ...props }: CardContentProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/sheet/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./sheet"; 2 | export * from "./sheet-trigger"; 3 | export * from "./sheet-close"; 4 | export * from "./sheet-content"; 5 | export * from "./sheet-content.types"; 6 | export * from "./sheet-header"; 7 | export * from "./sheet-footer"; 8 | export * from "./sheet-title"; 9 | export * from "./sheet-description"; 10 | -------------------------------------------------------------------------------- /src/components/color-swatch/color-swatch.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type colorSwatchVariants } from "~/components/color-swatch/color-swatch.styles"; 4 | 5 | type ColorSwatchVariantsProps = VariantProps; 6 | 7 | export type ColorSwatchSize = NonNullable; 8 | -------------------------------------------------------------------------------- /src/components/item/item.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type itemVariants } from "./item.styles"; 4 | 5 | type ItemVariantsProps = VariantProps; 6 | 7 | export type ItemVariantType = NonNullable; 8 | export type ItemSizeType = NonNullable; 9 | -------------------------------------------------------------------------------- /src/components/button/button.types.ts: -------------------------------------------------------------------------------- 1 | import { type VariantProps } from "class-variance-authority"; 2 | 3 | import { type buttonVariants } from "./button.styles"; 4 | 5 | type ButtonCvaProps = VariantProps; 6 | 7 | export type ButtonSizeType = NonNullable; 8 | export type ButtonVariantType = NonNullable; 9 | -------------------------------------------------------------------------------- /src/components/dialog/dialog-close.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Dialog as DialogPrimitive } from "radix-ui"; 4 | 5 | export type DialogCloseProps = React.ComponentProps; 6 | 7 | export function DialogClose(props: DialogCloseProps) { 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/select/select-group.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Select as SelectPrimitive } from "radix-ui"; 4 | 5 | export type SelectGroupProps = React.ComponentProps; 6 | 7 | export function SelectGroup(props: SelectGroupProps) { 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/dialog/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./dialog"; 2 | export * from "./dialog-close"; 3 | 4 | export * from "./dialog-content"; 5 | export * from "./dialog-content.types"; 6 | 7 | export * from "./dialog-trigger"; 8 | export * from "./dialog-header"; 9 | export * from "./dialog-footer"; 10 | export * from "./dialog-title"; 11 | export * from "./dialog-description"; 12 | -------------------------------------------------------------------------------- /src/components/item/item-actions.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type ItemActionsProps = React.ComponentProps<"div">; 6 | 7 | export function ItemActions({ className, ...props }: ItemActionsProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/empty/empty-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type EmptyTitleProps = React.ComponentProps<"div">; 6 | 7 | export function EmptyTitle({ className, ...props }: EmptyTitleProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/field/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./field"; 2 | export * from "./field-content"; 3 | export * from "./field-description"; 4 | export * from "./field-error"; 5 | export * from "./field-group"; 6 | export * from "./field-label"; 7 | export * from "./field-legend"; 8 | export * from "./field-separator"; 9 | export * from "./field-set"; 10 | export * from "./field-title"; 11 | -------------------------------------------------------------------------------- /src/components/dialog/dialog-trigger.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Dialog as DialogPrimitive } from "radix-ui"; 4 | 5 | export type DialogTriggerProps = React.ComponentProps; 6 | 7 | export function DialogTrigger({ ...props }: DialogTriggerProps) { 8 | return ; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/card/card-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type CardDescriptionProps = React.ComponentProps<"div">; 6 | 7 | export function CardDescription({ className, ...props }: CardDescriptionProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/item/item-group.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type ItemGroupProps = React.ComponentProps<"div">; 6 | 7 | export function ItemGroup({ className, ...props }: ItemGroupProps) { 8 | return ( 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /src/components/card/card-footer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type CardFooterProps = React.ComponentProps<"div">; 6 | 7 | export function CardFooter({ className, ...props }: CardFooterProps) { 8 | return ( 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /src/components/alert-dialog/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./alert-dialog"; 2 | export * from "./alert-dialog-trigger"; 3 | export * from "./alert-dialog-content"; 4 | export * from "./alert-dialog-action"; 5 | export * from "./alert-dialog-footer"; 6 | export * from "./alert-dialog-title"; 7 | export * from "./alert-dialog-description"; 8 | export * from "./alert-dialog-cancel"; 9 | export * from "./alert-dialog-header"; 10 | -------------------------------------------------------------------------------- /src/components/card/card-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type CardTitleProps = React.DetailedHTMLProps, HTMLHeadingElement>; 6 | 7 | export function CardTitle({ className, ...props }: CardTitleProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/sheet/sheet-header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type SheetHeaderProps = React.DetailedHTMLProps, HTMLDivElement>; 6 | 7 | export function SheetHeader({ className, ...props }: SheetHeaderProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/index.test.ts: -------------------------------------------------------------------------------- 1 | import { cn } from "~/utils/index"; 2 | 3 | describe("cn function", () => { 4 | test("returns classes correctly", () => { 5 | expect(cn("")).toEqual(""); 6 | expect(cn("class1 class2", "class3 class4")).toEqual("class1 class2 class3 class4"); 7 | }); 8 | 9 | test("override classes correctly", () => { 10 | expect(cn("m-4 h-23 pr-3", "m-3")).toEqual("h-23 pr-3 m-3"); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/components/sheet/sheet-footer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type SheetFooterProps = React.DetailedHTMLProps, HTMLDivElement>; 6 | 7 | export function SheetFooter({ className, ...props }: SheetFooterProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/sheet/sheet-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Dialog as ReactSheet } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type SheetTitleProps = React.ComponentProps; 8 | 9 | export function SheetTitle({ className, ...props }: SheetTitleProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/spinner/spinner.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { LoaderCircle } from "lucide-react"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type SpinnerProps = React.ComponentProps<"svg">; 8 | 9 | export function Spinner({ className, ...props }: SpinnerProps) { 10 | return ( 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/components/item/item-footer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type ItemFooterProps = React.ComponentProps<"div">; 6 | 7 | export function ItemFooter({ className, ...props }: ItemFooterProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/item/item-header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type ItemHeaderProps = React.ComponentProps<"div">; 6 | 7 | export function ItemHeader({ className, ...props }: ItemHeaderProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog-header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type AlertDialogHeaderProps = React.DetailedHTMLProps, HTMLDivElement>; 6 | 7 | export function AlertDialogHeader({ className, ...props }: AlertDialogHeaderProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/item/item-separator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | import { Separator } from "../separator"; 6 | 7 | export type ItemSeparatorProps = React.ComponentProps; 8 | 9 | export function ItemSeparator({ className, ...props }: ItemSeparatorProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/alert/alert-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type AlertTitleProps = React.ComponentProps<"div">; 6 | 7 | export function AlertTitle({ className, ...props }: AlertTitleProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/badge/badge-dot.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type BadgeDotProps = React.ComponentProps<"span">; 6 | 7 | export function BadgeDot({ className, ...props }: React.ComponentProps<"span">) { 8 | return ( 9 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/dialog/dialog-header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type DialogHeaderProps = React.ComponentProps<"div">; 6 | 7 | export function DialogHeader({ className, ...props }: DialogHeaderProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/empty/empty-header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type EmptyHeaderProps = React.ComponentProps<"div">; 6 | 7 | export function EmptyHeader({ className, ...props }: EmptyHeaderProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/item/item-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type ItemTitleProps = React.ComponentProps<"div">; 6 | 7 | export function ItemTitle({ className, ...props }: ItemTitleProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/stories/Styles.mdx: -------------------------------------------------------------------------------- 1 | import { Meta, Title, Subtitle, Unstyled } from "@storybook/addon-docs/blocks"; 2 | 3 | 4 | 5 | Styles 6 | This section provides guidelines and examples predefined styles. 7 | 8 | ## Container 9 | 10 | 11 |
12 |
Main Content
13 |
14 |
15 | -------------------------------------------------------------------------------- /src/components/card/card-action.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type CardActionProps = React.ComponentProps<"div">; 6 | 7 | export function CardAction({ className, ...props }: CardActionProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/item/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./item"; 2 | export * from "./item.types"; 3 | 4 | export * from "./item-media"; 5 | export * from "./item-media.types"; 6 | 7 | export * from "./item-group"; 8 | 9 | export * from "./item-actions"; 10 | export * from "./item-content"; 11 | export * from "./item-description"; 12 | export * from "./item-footer"; 13 | export * from "./item-header"; 14 | export * from "./item-title"; 15 | export * from "./item-separator"; 16 | -------------------------------------------------------------------------------- /src/components/dialog/dialog-footer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type DialogFooterProps = React.ComponentProps<"div">; 6 | 7 | export function DialogFooter({ className, ...props }: DialogFooterProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog-footer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { twMerge } from "tailwind-merge"; 4 | 5 | export type AlertDialogFooterProps = React.DetailedHTMLProps, HTMLDivElement>; 6 | 7 | export function AlertDialogFooter({ className, ...props }: AlertDialogFooterProps) { 8 | return
; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/field/field-content.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type FieldContentProps = React.ComponentProps<"div">; 6 | 7 | export function FieldContent({ className, ...props }: FieldContentProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/radio-group/radio-group.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { RadioGroup as RadioGroupPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type RadioGroupProps = React.ComponentProps; 8 | 9 | export function RadioGroup({ className, ...props }: RadioGroupProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/sheet/sheet-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Dialog as ReactSheet } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type SheetDescriptionProps = React.ComponentProps; 8 | 9 | export function SheetDescription({ className, ...props }: SheetDescriptionProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/questions_help.yaml: -------------------------------------------------------------------------------- 1 | name: "❓ Questions & Help" 2 | description: "Ask a question or request guidance" 3 | title: "[Help]: " 4 | labels: ["question"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: "### 🤔 What do you need help with?" 9 | - type: textarea 10 | attributes: 11 | label: "Question" 12 | description: "Describe your question or request." 13 | - type: input 14 | attributes: 15 | label: "Additional Context" 16 | -------------------------------------------------------------------------------- /src/components/item/item-content.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type ItemContentProps = React.ComponentProps<"div">; 6 | 7 | export function ItemContent({ className, ...props }: React.ComponentProps<"div">) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/stories/Introduction.mdx: -------------------------------------------------------------------------------- 1 | import { Meta, Title, Subtitle } from "@storybook/addon-docs/blocks"; 2 | 3 | 4 | 5 | Welcome to the Szum-Tech Design System 6 | 7 | This is the official documentation for the Szum-Tech Design System. 8 | 9 | The Szum-Tech Design System is a collection of reusable components, guided by clear standards, that can be assembled 10 | together to build any number of applications. 11 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { AlertDialog as ReactAlertDialog } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type AlertDialogTitleProps = React.ComponentProps; 8 | 9 | export function AlertDialogTitle({ className, ref, ...props }: AlertDialogTitleProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/empty/empty-content.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type EmptyContentProps = React.ComponentProps<"div">; 6 | 7 | export function EmptyContent({ className, ...props }: EmptyContentProps) { 8 | return ( 9 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/components/avatar/avatar-image.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Avatar as AvatarPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type AvatarImageProps = React.ComponentProps; 8 | 9 | export function AvatarImage({ className, ...props }: AvatarImageProps) { 10 | return ( 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/components/card/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type CardProps = React.ComponentProps<"div">; 6 | 7 | export function Card({ className, ...props }: CardProps) { 8 | return ( 9 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/components/tooltip/tooltip-provider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Tooltip as ReactTooltip } from "radix-ui"; 4 | 5 | export type TooltipProviderProps = React.ComponentProps; 6 | 7 | export function TooltipProvider({ children, skipDelayDuration = 500, ...props }: TooltipProviderProps) { 8 | return ( 9 | 10 | {children} 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/contexts/directon.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export const Direction = { 4 | LTR: "ltr", 5 | RTL: "rtl" 6 | } as const; 7 | export type Direction = (typeof Direction)[keyof typeof Direction]; 8 | 9 | export const DirectionContext = React.createContext(undefined); 10 | 11 | export function useDirection(dirProp?: Direction): Direction { 12 | const contextDir = React.useContext(DirectionContext); 13 | 14 | return dirProp ?? contextDir ?? Direction.LTR; 15 | } 16 | -------------------------------------------------------------------------------- /src/components/alert-dialog/alert-dialog-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { AlertDialog as ReactAlertDialog } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type AlertDialogDescriptionProps = React.ComponentProps; 8 | 9 | export function AlertDialogDescription({ className, ...props }: AlertDialogDescriptionProps) { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/avatar/avatar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Avatar as ReactAvatar } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type AvatarProps = React.ComponentProps; 8 | 9 | export function Avatar({ className, ...props }: AvatarProps) { 10 | return ( 11 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/components/color-swatch/color-swatch.styles.ts: -------------------------------------------------------------------------------- 1 | import { cva } from "class-variance-authority"; 2 | 3 | export const colorSwatchVariants = cva( 4 | "border-border box-border rounded border shadow-sm [background-clip:padding-box] data-[disabled]:pointer-events-none data-[disabled]:opacity-50", 5 | { 6 | variants: { 7 | size: { 8 | default: "size-8", 9 | sm: "size-6", 10 | lg: "size-12" 11 | } 12 | }, 13 | defaultVariants: { 14 | size: "default" 15 | } 16 | } 17 | ); 18 | -------------------------------------------------------------------------------- /src/components/alert/alert.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { type AlertVariant } from "~/components/alert/alert.types"; 4 | import { cn } from "~/utils"; 5 | 6 | import { alertVariants } from "./alert.styles"; 7 | 8 | export type AlertProps = React.ComponentProps<"div"> & { variant?: AlertVariant }; 9 | 10 | export function Alert({ className, variant = "default", ...props }: AlertProps) { 11 | return
; 12 | } 13 | -------------------------------------------------------------------------------- /src/components/dialog/dialog-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Dialog as DialogPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type DialogTitleProps = React.ComponentProps; 8 | 9 | export function DialogTitle({ className, ...props }: DialogTitleProps) { 10 | return ( 11 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/components/field/field-title.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type FieldTitleProps = React.ComponentProps<"div">; 6 | 7 | export function FieldTitle({ className, ...props }: FieldTitleProps) { 8 | return ( 9 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/components/field/field-set.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type FieldSetProps = React.ComponentProps<"fieldset">; 6 | 7 | export function FieldSet({ className, ...props }: FieldSetProps) { 8 | return ( 9 |
[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3", 14 | className 15 | )} 16 | {...props} 17 | /> 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /src/components/select/select-label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Select as SelectPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type SelectLabelProps = React.ComponentProps; 8 | 9 | export function SelectLabel({ className, ...props }: SelectLabelProps) { 10 | return ( 11 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/tailwind/scroll.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | @layer base { 4 | * { 5 | ::-webkit-scrollbar { 6 | @apply h-2 w-2; 7 | } 8 | ::-webkit-scrollbar-track { 9 | @apply bg-background; 10 | } 11 | ::-webkit-scrollbar-thumb { 12 | @apply bg-border rounded; 13 | } 14 | ::-webkit-scrollbar-thumb:hover { 15 | @apply bg-border/80; 16 | } 17 | ::-webkit-scrollbar-button { 18 | @apply hidden; 19 | } 20 | ::-webkit-scrollbar-corner { 21 | @apply bg-background; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/components/alert/alert-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type AlertDescriptionProps = React.ComponentProps<"div">; 6 | 7 | export function AlertDescription({ className, ...props }: AlertDescriptionProps) { 8 | return ( 9 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/components/empty/empty-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type EmptyDescriptionProps = React.ComponentProps<"p">; 6 | 7 | export function EmptyDescription({ className, ...props }: EmptyDescriptionProps) { 8 | return ( 9 |

a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4", 13 | className 14 | )} 15 | {...props} 16 | /> 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/components/field/field-group.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type FieldGroupProps = React.ComponentProps<"div">; 6 | 7 | export function FieldGroup({ className, ...props }: FieldGroupProps) { 8 | return ( 9 |

[data-slot=field-group]]:gap-4", 13 | className 14 | )} 15 | {...props} 16 | /> 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/components/header/header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export type HeaderProps = React.RefAttributes & { 4 | children?: React.ReactNode; 5 | }; 6 | 7 | export function Header({ children, ...props }: HeaderProps) { 8 | return ( 9 |
13 |
{children}
14 |
15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /src/components/dialog/dialog-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Dialog as DialogPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type DialogDescriptionProps = React.ComponentProps; 8 | 9 | export function DialogDescription({ className, ...props }: DialogDescriptionProps) { 10 | return ( 11 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/components/field/field-legend.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type FieldLegendProps = React.ComponentProps<"legend"> & { variant?: "legend" | "label" }; 6 | 7 | export function FieldLegend({ className, variant = "legend", ...props }: FieldLegendProps) { 8 | return ( 9 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /src/components/select/select-separator.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Select as SelectPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type SelectSeparatorProps = React.ComponentProps; 8 | 9 | export function SelectSeparator({ className, ...props }: SelectSeparatorProps) { 10 | return ( 11 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/icons/auth0-logo.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export function Auth0LogoIcon(props: React.SVGProps) { 4 | return ( 5 | 6 | 7 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/components/avatar/avatar-fallback.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Avatar as AvatarPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type AvatarFallbackProps = React.ComponentProps; 8 | 9 | export function AvatarFallback({ className, ...props }: AvatarFallbackProps) { 10 | return ( 11 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /.storybook/theme/dark.ts: -------------------------------------------------------------------------------- 1 | import { create } from "storybook/theming"; 2 | 3 | export default create({ 4 | base: "dark", 5 | 6 | // Typography 7 | fontBase: "'Poppins', sans-serif", 8 | fontCode: "'JetBrains Mono', monospace", 9 | 10 | brandTitle: "Szum-Tech Design System", 11 | 12 | // 13 | colorPrimary: "#168FFF", 14 | colorSecondary: "#42A4FF", 15 | 16 | appBg: "#111111", 17 | appContentBg: "#1C1C1C", 18 | appBorderRadius: 0, 19 | appBorderColor: "#2e2e2e", 20 | 21 | barBg: "#111111", 22 | barTextColor: "#c0c0c0", 23 | barSelectedColor: "#168FFF", 24 | 25 | textColor: "#eaeaea" 26 | }); 27 | -------------------------------------------------------------------------------- /src/components/item/item-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type ItemDescriptionProps = React.ComponentProps<"p">; 6 | 7 | export function ItemDescription({ className, ...props }: ItemDescriptionProps) { 8 | return ( 9 |

a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", 14 | className 15 | )} 16 | {...props} 17 | /> 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /.storybook/theme/light.ts: -------------------------------------------------------------------------------- 1 | import { create } from "storybook/theming"; 2 | 3 | export default create({ 4 | base: "light", 5 | 6 | // Typography 7 | fontBase: "'Poppins', sans-serif", 8 | fontCode: "'JetBrains Mono', monospace", 9 | 10 | brandTitle: "Szum-Tech Design System", 11 | 12 | // 13 | colorPrimary: "#0085FF", 14 | colorSecondary: "#339CFF", 15 | 16 | appBg: "#ffffff", 17 | appContentBg: "#f7f7f7", 18 | appBorderRadius: 0, 19 | appBorderColor: "#EBEBEB", 20 | 21 | barBg: "#ffffff", 22 | barTextColor: "#585757", 23 | barSelectedColor: "#0085FF", 24 | 25 | textColor: "#1C1C1C" 26 | }); 27 | -------------------------------------------------------------------------------- /src/tests/integration/vitest.setup.ts: -------------------------------------------------------------------------------- 1 | import { beforeAll } from "vitest"; 2 | 3 | import * as a11yAddonAnnotations from "@storybook/addon-a11y/preview"; 4 | import { setProjectAnnotations } from "@storybook/react-vite"; 5 | 6 | import * as projectAnnotations from "../../../.storybook/preview"; 7 | 8 | // This is an important step to apply the right configuration when testing your stories. 9 | // More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations 10 | const project = setProjectAnnotations([projectAnnotations, a11yAddonAnnotations]); 11 | 12 | beforeAll(project.beforeAll); 13 | -------------------------------------------------------------------------------- /src/components/card/card-header.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type CardHeaderProps = React.DetailedHTMLProps, HTMLDivElement>; 6 | 7 | export function CardHeader({ className, ...props }: CardHeaderProps) { 8 | return ( 9 |

17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/icons/Iconography.mdx: -------------------------------------------------------------------------------- 1 | import { Meta, IconGallery, IconItem } from "@storybook/addon-docs/blocks"; 2 | 3 | import * as CustomIcons from "./index"; 4 | 5 | 6 | 7 | # Iconography 8 | 9 | # Custom 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/tailwind/global.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | @import "./typography.css"; 4 | @import "./palette.css"; 5 | @import "./animation.css"; 6 | @import "./scroll.css"; 7 | 8 | @plugin "tailwindcss-animate"; 9 | 10 | @layer base { 11 | button:not(:disabled), 12 | [role="button"]:not(:disabled) { 13 | cursor: pointer; 14 | } 15 | 16 | body { 17 | @apply bg-background font-poppins text-foreground text-body-default antialiased; 18 | } 19 | } 20 | 21 | @utility container { 22 | @apply mx-auto max-w-7xl px-4 sm:px-8; 23 | } 24 | 25 | @utility container-* { 26 | max-width: --value(--container-*); 27 | @apply mx-auto; 28 | } 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation_issue.yaml: -------------------------------------------------------------------------------- 1 | name: "📖 Documentation Issue" 2 | description: "Report an issue with the documentation" 3 | title: "[Docs]: " 4 | labels: ["documentation"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: "### 📝 Describe the documentation issue" 9 | - type: textarea 10 | attributes: 11 | label: "Issue" 12 | description: "What part of the documentation is unclear or incorrect?" 13 | - type: input 14 | attributes: 15 | label: "Suggested Fix" 16 | description: "Provide a suggestion for improvement." 17 | - type: input 18 | attributes: 19 | label: "Additional Context" 20 | -------------------------------------------------------------------------------- /src/components/color-swatch/color-swatch.utils.ts: -------------------------------------------------------------------------------- 1 | export function getIsCssColor(v: string): boolean { 2 | try { 3 | return typeof CSS !== "undefined" && typeof CSS.supports === "function" ? CSS.supports("color", v) : true; 4 | } catch { 5 | return false; 6 | } 7 | } 8 | 9 | export function getHasAlpha(v: string): boolean { 10 | const s = v.trim().toLowerCase(); 11 | 12 | if (s === "transparent") return true; 13 | 14 | if (/^#(?:[0-9a-f]{4}|[0-9a-f]{8})$/i.test(s)) return true; 15 | 16 | if (/\b(?:rgba|hsla)\s*\(/i.test(s)) return true; 17 | 18 | return /\b(?:rgb|hsl|lab|lch|oklab|oklch|color)\s*\([^)]*\/\s*[\d.]+%?\s*\)/i.test(s); 19 | } 20 | -------------------------------------------------------------------------------- /src/components/field/field.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { type VariantProps } from "class-variance-authority"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | import { fieldVariants } from "./field.styles"; 8 | 9 | export type FieldProps = React.ComponentProps<"div"> & VariantProps; 10 | 11 | export function Field({ className, orientation = "vertical", ...props }: FieldProps) { 12 | return ( 13 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /src/hooks/use-validation-log.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | interface UseValidationLogProps { 4 | check: boolean; 5 | scope: string; 6 | message: string; 7 | } 8 | 9 | export function useValidationLog({ check, scope, message }: UseValidationLogProps) { 10 | React.useEffect(() => { 11 | if (!check) { 12 | // eslint-disable-next-line no-console 13 | console.error( 14 | `%c[Szum Tech-Design System]%c\n ${scope}%c\n ${message}`, 15 | "color: #ef4444; font-weight: bold;", 16 | "color: #3b82f6; font-weight: bold;", 17 | "color: #f59e0b;" 18 | ); 19 | } 20 | }, [check, scope, message]); 21 | } 22 | -------------------------------------------------------------------------------- /src/components/empty/empty.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type EmptyProps = React.ComponentProps<"div"> & { border?: boolean | "dashed" }; 6 | 7 | export function Empty({ className, border = false, ...props }: EmptyProps) { 8 | return ( 9 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /src/components/badge/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Slot as SlotPrimitive } from "radix-ui"; 4 | 5 | import { badgeVariants } from "~/components/badge/badge.styles"; 6 | import { cn } from "~/utils"; 7 | 8 | import { type BadgeVariant } from "./badge.types"; 9 | 10 | export type BadgeProps = React.ComponentProps<"span"> & { variant?: BadgeVariant; asChild?: boolean }; 11 | 12 | export function Badge({ className, variant = "primary", asChild = false, ...props }: BadgeProps) { 13 | const Comp = asChild ? SlotPrimitive.Slot : "span"; 14 | 15 | return ; 16 | } 17 | -------------------------------------------------------------------------------- /src/components/alert/alert.styles.ts: -------------------------------------------------------------------------------- 1 | import { cva } from "class-variance-authority"; 2 | 3 | export const alertVariants = cva( 4 | "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border border-border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", 5 | { 6 | variants: { 7 | variant: { 8 | default: "bg-card text-card-foreground", 9 | destructive: "text-error bg-card *:data-[slot=alert-description]:text-error/90 [&>svg]:text-current" 10 | } 11 | }, 12 | defaultVariants: { 13 | variant: "default" 14 | } 15 | } 16 | ); 17 | -------------------------------------------------------------------------------- /src/components/item/item-media.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { itemMediaVariants } from "~/components/item/item-media.styles"; 4 | import { type ItemMediaVariantType } from "~/components/item/item-media.types"; 5 | import { cn } from "~/utils"; 6 | 7 | export type ItemMediaProps = React.ComponentProps<"div"> & { 8 | variant?: ItemMediaVariantType; 9 | }; 10 | 11 | export function ItemMedia({ className, variant = "default", ...props }: ItemMediaProps) { 12 | return ( 13 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /src/scripts/post-build.js: -------------------------------------------------------------------------------- 1 | import fs from "fs/promises"; 2 | 3 | export async function updateFilesWithText(filePaths, text) { 4 | for (const filePath of filePaths) { 5 | try { 6 | const content = await fs.readFile(filePath, "utf8"); 7 | const updatedContent = text + content; 8 | await fs.writeFile(filePath, updatedContent, "utf8"); 9 | console.log(`Updated: ${filePath}`); 10 | } catch (err) { 11 | console.error(`Error updating ${filePath}:`, err); 12 | } 13 | } 14 | } 15 | 16 | updateFilesWithText(["dist/components/index.js", "dist/components/index.cjs"], '"use client";\n\n').then(() => { 17 | console.log("Files updated successfully"); 18 | }); 19 | -------------------------------------------------------------------------------- /src/components/stepper/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./stepper"; 2 | export * from "./stepper.types"; 3 | export { useStepperContext } from "./stepper.context"; 4 | export { useStepperFocusContext } from "./stepper-focus.context"; 5 | 6 | export * from "./stepper-nav"; 7 | 8 | export * from "./stepper-item"; 9 | export { useStepperItemContext } from "./stepper-item.context"; 10 | 11 | export * from "./stepper-trigger"; 12 | export * from "./stepper-indicator"; 13 | export * from "./stepper-title"; 14 | export * from "./stepper-description"; 15 | export * from "./stepper-panel"; 16 | export * from "./stepper-content"; 17 | export * from "./stepper-next-trigger"; 18 | export * from "./stepper-prev-trigger"; 19 | -------------------------------------------------------------------------------- /src/components/label/label.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { type Meta, type StoryObj } from "@storybook/react-vite"; 4 | import { Checkbox } from "~/components/checkbox"; 5 | 6 | import { Label } from "."; 7 | 8 | const meta = { 9 | title: "Components/Label", 10 | component: Label, 11 | tags: ["autodocs", "beta"] 12 | } satisfies Meta; 13 | export default meta; 14 | 15 | type Story = StoryObj; 16 | 17 | export const Example: Story = { 18 | render: () => ( 19 |
20 | 21 | 22 |
23 | ) 24 | }; 25 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | day: "sunday" 9 | time: "21:37" 10 | timezone: "Europe/Warsaw" 11 | groups: 12 | github-dependencies: 13 | patterns: 14 | - "*" 15 | 16 | # Maintain dependencies for npm 17 | - package-ecosystem: "npm" 18 | directory: "/" 19 | schedule: 20 | interval: "weekly" 21 | day: "sunday" 22 | time: "21:37" 23 | timezone: "Europe/Warsaw" 24 | groups: 25 | design-system-dependencies: 26 | patterns: 27 | - "*" 28 | -------------------------------------------------------------------------------- /.storybook/manager.ts: -------------------------------------------------------------------------------- 1 | import { addons } from "storybook/manager-api"; 2 | import { defaultConfig, type TagBadgeParameters } from "storybook-addon-tag-badges/manager-helpers"; 3 | 4 | addons.setConfig({ 5 | tagBadges: [ 6 | { 7 | tags: "test-only", 8 | badge: { 9 | text: "Test ⚡", // Vitest-style lightning bolt 10 | style: { 11 | background: "#729b1b", 12 | color: "white" 13 | }, 14 | tooltip: "Testing story - powered by Vitest spirit ⚡" 15 | }, 16 | display: { 17 | toolbar: true 18 | } 19 | }, 20 | // Place the default config after your custom matchers. 21 | ...defaultConfig 22 | ] satisfies TagBadgeParameters 23 | }); 24 | -------------------------------------------------------------------------------- /src/components/label/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Label as ReactLabel } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type LabelProps = React.ComponentProps; 8 | 9 | export function Label({ className, ...props }: LabelProps) { 10 | return ( 11 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /src/components/stepper/stepper-item.context.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { STEPPER_ITEM_NAME } from "./stepper.constants"; 4 | import { type StepperStepState } from "./stepper.store"; 5 | 6 | export type StepperItemContextValue = { 7 | value: string; 8 | stepState: StepperStepState | undefined; 9 | }; 10 | 11 | export const StepperItemContext = React.createContext(null); 12 | 13 | export function useStepperItemContext(consumerName: string) { 14 | const context = React.useContext(StepperItemContext); 15 | 16 | if (!context) { 17 | throw new Error(`\`${consumerName}\` must be used within \`${STEPPER_ITEM_NAME}\``); 18 | } 19 | 20 | return context; 21 | } 22 | -------------------------------------------------------------------------------- /src/components/item/item-media.styles.ts: -------------------------------------------------------------------------------- 1 | import { cva } from "class-variance-authority"; 2 | 3 | export const itemMediaVariants = cva( 4 | "flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none", 5 | { 6 | variants: { 7 | variant: { 8 | default: "bg-transparent", 9 | icon: "border-border bg-muted size-8 rounded-sm border [&_svg:not([class*='size-'])]:size-4", 10 | image: "size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover" 11 | } 12 | }, 13 | defaultVariants: { 14 | variant: "default" 15 | } 16 | } 17 | ); 18 | -------------------------------------------------------------------------------- /src/components/field/field-description.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type FieldDescriptionProps = React.ComponentProps<"p">; 6 | 7 | export function FieldDescription({ className, ...props }: React.ComponentProps<"p">) { 8 | return ( 9 |

a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", 15 | className 16 | )} 17 | {...props} 18 | /> 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yaml: -------------------------------------------------------------------------------- 1 | name: "✨ Feature Request" 2 | description: "Suggest a new feature or improvement" 3 | title: "[Feature]: " 4 | labels: ["enhancement"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: "### 💡 Feature Description" 9 | - type: textarea 10 | attributes: 11 | label: "Describe the Feature" 12 | description: "What feature would you like to see?" 13 | - type: textarea 14 | attributes: 15 | label: "Use Case" 16 | description: "Explain why this feature is useful." 17 | - type: textarea 18 | attributes: 19 | label: "Alternatives" 20 | description: "Any alternative solutions?" 21 | - type: input 22 | attributes: 23 | label: "Additional Context" 24 | -------------------------------------------------------------------------------- /src/components/item/item.styles.ts: -------------------------------------------------------------------------------- 1 | import { cva } from "class-variance-authority"; 2 | 3 | export const itemVariants = cva( 4 | "group/item [a]:hover:bg-accent/50 [a]:transition-colors focus-visible:border-ring focus-visible:ring-ring/50 flex flex-wrap items-center rounded border border-transparent text-sm outline-none transition-colors duration-100 focus-visible:ring", 5 | { 6 | variants: { 7 | variant: { 8 | default: "bg-transparent", 9 | outline: "border-border", 10 | muted: "bg-muted/50" 11 | }, 12 | size: { 13 | default: "gap-4 p-4 ", 14 | sm: "gap-2.5 px-4 py-3" 15 | } 16 | }, 17 | defaultVariants: { 18 | variant: "default", 19 | size: "default" 20 | } 21 | } 22 | ); 23 | -------------------------------------------------------------------------------- /src/icons/x-logo.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export function XLogoIcon(props: React.SVGProps) { 4 | return ( 5 | 14 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 🚀 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | env: 8 | NODE_VERSION: 24.x 9 | 10 | jobs: 11 | publish: 12 | name: Publish 🚀 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout code 📚 16 | uses: actions/checkout@v6 17 | - name: Set up Node 🟢 18 | uses: actions/setup-node@v6 19 | with: 20 | node-version: ${{ env.NODE_VERSION }} 21 | cache: "npm" 22 | - name: Install packages ⚙️ 23 | run: npm ci 24 | - name: Build 🏗️ 25 | run: npm run build 26 | - name: Publish package 🚀 27 | run: npx semantic-release 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 31 | -------------------------------------------------------------------------------- /src/components/badge/badge-button.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Slot as SlotPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type BadgeButtonProps = React.ComponentProps<"button"> & { asChild?: boolean }; 8 | 9 | export function BadgeButton({ className, asChild = false, ...props }: BadgeButtonProps) { 10 | const Comp = asChild ? SlotPrimitive.Slot : "span"; 11 | return ( 12 | svg]:size-3.5! [&>svg]:opacity-100!", 16 | className 17 | )} 18 | role="button" 19 | {...props} 20 | /> 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/security_issue.yaml: -------------------------------------------------------------------------------- 1 | name: "🔒 Security Issue" 2 | description: "Report a security vulnerability" 3 | title: "[Security]: " 4 | labels: ["security"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: "### 🚨 Security Concern" 9 | - type: textarea 10 | attributes: 11 | label: "Describe the Security Issue" 12 | description: "Provide details of the vulnerability." 13 | - type: input 14 | attributes: 15 | label: "Severity Level" 16 | description: "How critical is this issue?" 17 | - type: textarea 18 | attributes: 19 | label: "Possible Fix" 20 | description: "Do you have a suggested fix?" 21 | - type: textarea 22 | attributes: 23 | label: "Additional Context" 24 | description: "Any other relevant information." 25 | -------------------------------------------------------------------------------- /src/components/separator/separator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Separator as ReactSeparator } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type SeparatorProps = React.ComponentProps; 8 | 9 | export function Separator({ className, orientation = "horizontal", decorative = false, ...props }: SeparatorProps) { 10 | return ( 11 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | splitting: true, 5 | clean: true, 6 | dts: true, 7 | format: ["esm", "cjs"], 8 | bundle: true, 9 | treeshake: true, 10 | outDir: "dist", 11 | entry: [ 12 | "src/components/*/index.tsx", 13 | "src/components/index.tsx", 14 | "src/utils/index.ts", 15 | "src/hooks/index.tsx", 16 | "src/contexts/index.tsx", 17 | "src/icons/index.tsx" 18 | ], 19 | esbuildOptions(options) { 20 | // the directory structure will be the same as the source 21 | options.outbase = "./src"; 22 | }, 23 | external: [ 24 | "react", 25 | "react-dom", 26 | "class-variance-authority", 27 | "radix-ui", 28 | "@radix-ui/react-slot", 29 | "tailwind-merge", 30 | "clx" 31 | ] 32 | }); 33 | -------------------------------------------------------------------------------- /src/components/index.tsx: -------------------------------------------------------------------------------- 1 | export * from "./alert-dialog"; 2 | export * from "./avatar"; 3 | export * from "./badge"; 4 | export * from "./button"; 5 | export * from "./card"; 6 | export * from "./checkbox"; 7 | export * from "./dialog"; 8 | export * from "./field"; 9 | export * from "./header"; 10 | export * from "./input"; 11 | export * from "./item"; 12 | export * from "./label"; 13 | export * from "./progress"; 14 | export * from "./select"; 15 | export * from "./separator"; 16 | export * from "./sheet"; 17 | export * from "./spinner"; 18 | export * from "./stepper"; 19 | export * from "./textarea"; 20 | export * from "./toaster"; 21 | export * from "./tooltip"; 22 | export * from "./radio-group"; 23 | export * from "./color-swatch"; 24 | export * from "./scroll-area"; 25 | export * from "./alert"; 26 | export * from "./empty"; 27 | -------------------------------------------------------------------------------- /src/components/stepper/stepper-panel.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Slot } from "@radix-ui/react-slot"; 4 | import { cn } from "~/utils"; 5 | 6 | import { useStepperStore } from "./stepper.store"; 7 | 8 | export type StepperPanelProps = React.ComponentProps<"div"> & { 9 | asChild?: boolean; 10 | }; 11 | 12 | export function StepperPanel({ children, asChild = false, className, ...props }: StepperPanelProps) { 13 | const currentValue = useStepperStore((state) => state.value); 14 | 15 | const StepperPanelPrimitive = asChild ? Slot : "div"; 16 | 17 | return ( 18 | 24 | {children} 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /src/components/item/item.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Slot } from "@radix-ui/react-slot"; 4 | import { type ItemSizeType, type ItemVariantType } from "~/components"; 5 | import { itemVariants } from "~/components/item/item.styles"; 6 | import { cn } from "~/utils"; 7 | 8 | export type ItemProps = React.ComponentProps<"div"> & { 9 | asChild?: boolean; 10 | variant?: ItemVariantType; 11 | size?: ItemSizeType; 12 | }; 13 | 14 | export function Item({ className, variant = "default", size = "default", asChild = false, ...props }: ItemProps) { 15 | const Comp = asChild ? Slot : "div"; 16 | return ( 17 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /src/components/progress/progress.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Progress as ProgressPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | export type ProgressProps = React.ComponentProps; 8 | 9 | export function Progress({ className, value, ...props }: ProgressProps) { 10 | return ( 11 | 17 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/icons/google-logo.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | export function GoogleLogoIcon(props: React.SVGProps) { 4 | return ( 5 | 15 | 16 | 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /src/components/field/field-label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | import { Label } from "../label"; 6 | 7 | export type FieldLabelProps = React.ComponentProps; 8 | 9 | export function FieldLabel({ className, ...props }: FieldLabelProps) { 10 | return ( 11 |

19 | 20 | {children ? ( 21 | 25 | {children} 26 | 27 | ) : null} 28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /src/components/scroll-area/scroll-area.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { ScrollArea as ScrollAreaPrimitive } from "radix-ui"; 4 | 5 | import { cn } from "~/utils"; 6 | 7 | import { ScrollBar } from "./scroll-bar"; 8 | 9 | export type ScrollAreaProps = React.ComponentProps; 10 | 11 | export function ScrollArea({ className, children, ...props }: ScrollAreaProps) { 12 | return ( 13 | 14 | 18 | {children} 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /src/components/Components.mdx: -------------------------------------------------------------------------------- 1 | import { Meta, Subtitle, Title } from "@storybook/addon-docs/blocks"; 2 | 3 | 4 | 5 | Design System Components 6 | 7 | Welcome to the `@szum-tech/design-system`, a collection of reusable React components that help maintain consistency 8 | and efficiency across projects. Our components are built with accessibility, performance, and customization in mind. 9 | 10 | 11 | ## Usage 12 | 13 | ### Components 14 | 15 | To start using components, import them into your project: 16 | 17 | ```tsx 18 | import { Button } from "@szum-tech/design-system"; 19 | 20 | function App() { 21 | return ; 22 | } 23 | ``` 24 | 25 | ### Icons 26 | 27 | To start using Icons, import them into your project: 28 | 29 | ```tsx 30 | import { GoogleLogoIcon } from "@szum-tech/design-system/icons"; 31 | 32 | function App() { 33 | return ( 34 |
35 | 36 |
37 | ); 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /src/components/textarea/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { cn } from "~/utils"; 4 | 5 | export type TextareaProps = React.ComponentProps<"textarea"> & { 6 | invalid?: boolean; 7 | }; 8 | 9 | export function Textarea({ className, invalid = false, ...props }: TextareaProps) { 10 | return ( 11 |