From faf4cfd22ff995acc9bdbc0c92d1f00c64c632bb Mon Sep 17 00:00:00 2001 From: Damien Schneider <74979845+damien-schneider@users.noreply.github.com> Date: Mon, 30 Dec 2024 22:04:42 +0100 Subject: [PATCH] Add create-error utility and update import paths for cn() (#72) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ Add create-error utility with preview and category * ✨ Update import paths for utility functions to use cuicui package one --- apps/website/src/components/coming-soon.tsx | 2 +- .../animated-tab-motion-div.tsx | 2 +- .../component-tab-renderer.tsx | 2 +- .../component-wrapper/component-wrapper.tsx | 2 +- .../component-wrapper/variant-tabs.tsx | 2 +- .../components/custom-iframe-component.tsx | 3 +- .../floating-dock-toggle-theme.tsx | 3 +- .../floating-dock.tsx | 2 +- .../navigation/animated-background.tsx | 2 +- .../components/navigation/desktop-menu.tsx | 2 +- .../components/navigation/navigation-item.tsx | 2 +- .../components/navigation/navigation-menu.tsx | 2 +- .../website/src/components/not-found-card.tsx | 2 +- apps/website/src/ui/badge.tsx | 2 +- apps/website/src/ui/button.tsx | 2 +- apps/website/src/ui/byline.tsx | 2 - .../website/src/ui/code-command-container.tsx | 2 +- apps/website/src/ui/code-highlighter.tsx | 2 +- ...opy-to-clipboard-code-snippet-dropdown.tsx | 1 - apps/website/src/ui/gradient-container.tsx | 2 +- apps/website/src/ui/gradient-text.tsx | 2 +- apps/website/src/ui/navigation-menu.tsx | 2 +- apps/website/src/ui/shadcn/button.tsx | 2 +- apps/website/src/ui/shadcn/command.tsx | 2 +- apps/website/src/ui/shadcn/dialog.tsx | 2 +- apps/website/src/ui/shadcn/dropdown-menu.tsx | 2 +- apps/website/src/ui/shadcn/resizable.tsx | 2 +- apps/website/src/ui/shadcn/scrollarea.tsx | 2 +- apps/website/src/ui/shadcn/select.tsx | 2 +- apps/website/src/ui/shadcn/tabs.tsx | 2 +- apps/website/src/ui/stepper.tsx | 2 +- apps/website/src/utils/cn.ts | 6 -- packages/ui/categories-previews-list.ts | 2 + .../ui/cuicui/utils/create-error/category.ts | 11 +++ .../create-error/create-error/component.ts | 8 ++ .../create-error/create-error.variant.tsx | 39 +++++++++ .../ui/cuicui/utils/create-error/index.ts | 86 +++++++++++++++++++ .../ui/cuicui/utils/create-error/preview.tsx | 16 ++++ packages/ui/section-list.ts | 23 +++++ 39 files changed, 215 insertions(+), 39 deletions(-) delete mode 100644 apps/website/src/utils/cn.ts create mode 100644 packages/ui/cuicui/utils/create-error/category.ts create mode 100644 packages/ui/cuicui/utils/create-error/create-error/component.ts create mode 100644 packages/ui/cuicui/utils/create-error/create-error/create-error.variant.tsx create mode 100644 packages/ui/cuicui/utils/create-error/index.ts create mode 100644 packages/ui/cuicui/utils/create-error/preview.tsx diff --git a/apps/website/src/components/coming-soon.tsx b/apps/website/src/components/coming-soon.tsx index 6741225a..cee695c8 100644 --- a/apps/website/src/components/coming-soon.tsx +++ b/apps/website/src/components/coming-soon.tsx @@ -1,5 +1,5 @@ import GradientText from "../ui/gradient-text"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export default function ComingSoonCard() { return ( diff --git a/apps/website/src/components/component-wrapper/animated-tab-motion-div.tsx b/apps/website/src/components/component-wrapper/animated-tab-motion-div.tsx index f9750f16..7b9ce1fd 100644 --- a/apps/website/src/components/component-wrapper/animated-tab-motion-div.tsx +++ b/apps/website/src/components/component-wrapper/animated-tab-motion-div.tsx @@ -1,7 +1,7 @@ "use client"; import { type MotionProps, motion } from "motion/react"; import type React from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export default function AnimatedTabMotionDiv({ className, ...props diff --git a/apps/website/src/components/component-wrapper/component-tab-renderer.tsx b/apps/website/src/components/component-wrapper/component-tab-renderer.tsx index 8b9753f8..4d7aeb8b 100644 --- a/apps/website/src/components/component-wrapper/component-tab-renderer.tsx +++ b/apps/website/src/components/component-wrapper/component-tab-renderer.tsx @@ -14,7 +14,7 @@ import { ScrollAreaViewport, ScrollBar, } from "#/src/ui/shadcn/scrollarea"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import { getContainerHeightClass } from "#/src/components/component-wrapper/get-container-height-class"; import { createElement } from "react"; import { diff --git a/apps/website/src/components/component-wrapper/component-wrapper.tsx b/apps/website/src/components/component-wrapper/component-wrapper.tsx index a42027b6..571f2d11 100644 --- a/apps/website/src/components/component-wrapper/component-wrapper.tsx +++ b/apps/website/src/components/component-wrapper/component-wrapper.tsx @@ -2,7 +2,7 @@ import { useLayoutEffect, useState, type ReactNode } from "react"; import { CustomIframe } from "#/src/components/custom-iframe-component"; import type { ComponentHeightType } from "@cuicui/ui/lib/types/component"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import { getContainerHeightClass } from "#/src/components/component-wrapper/get-container-height-class"; import { RefreshCwIcon } from "lucide-react"; import { ScrollArea, ScrollAreaViewport } from "#/src/ui/shadcn/scrollarea"; diff --git a/apps/website/src/components/component-wrapper/variant-tabs.tsx b/apps/website/src/components/component-wrapper/variant-tabs.tsx index 69821c2f..8cdbf831 100644 --- a/apps/website/src/components/component-wrapper/variant-tabs.tsx +++ b/apps/website/src/components/component-wrapper/variant-tabs.tsx @@ -1,7 +1,7 @@ import * as Tabs from "@radix-ui/react-tabs"; import ComponentTabRenderer from "#/src/components/component-wrapper/component-tab-renderer"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import type { ComponentType } from "@cuicui/ui/lib/types/component"; export type TabType = "preview" | "code-component" | "code-preview"; diff --git a/apps/website/src/components/custom-iframe-component.tsx b/apps/website/src/components/custom-iframe-component.tsx index b68209c5..e6f92ec3 100644 --- a/apps/website/src/components/custom-iframe-component.tsx +++ b/apps/website/src/components/custom-iframe-component.tsx @@ -3,8 +3,9 @@ import type React from "react"; import Frame from "react-frame-component"; import type { ComponentHeightType } from "@cuicui/ui/lib/types/component"; -import { cn } from "#/src/utils/cn"; + import { getContainerHeightClass } from "#/src/components/component-wrapper/get-container-height-class"; +import { cn } from "@/cuicui/utils/cn"; export const CustomIframe = ({ children, diff --git a/apps/website/src/components/floating-dock-navigation/floating-dock-toggle-theme.tsx b/apps/website/src/components/floating-dock-navigation/floating-dock-toggle-theme.tsx index df41eccd..fbfb6dde 100644 --- a/apps/website/src/components/floating-dock-navigation/floating-dock-toggle-theme.tsx +++ b/apps/website/src/components/floating-dock-navigation/floating-dock-toggle-theme.tsx @@ -1,6 +1,5 @@ "use client"; -import React from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import { MoonIcon, SunIcon } from "lucide-react"; import { useTheme } from "next-themes"; diff --git a/apps/website/src/components/floating-dock-navigation/floating-dock.tsx b/apps/website/src/components/floating-dock-navigation/floating-dock.tsx index 885c5b18..46fdd92d 100644 --- a/apps/website/src/components/floating-dock-navigation/floating-dock.tsx +++ b/apps/website/src/components/floating-dock-navigation/floating-dock.tsx @@ -1,7 +1,7 @@ import { sectionList } from "@/section-list"; import { FloatingDock } from "#/src/components/floating-dock-navigation/floating-docks-component"; import { ArrowUpRightIcon, GithubIcon } from "lucide-react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import Link from "next/link"; import PillToggleTheme from "@/cuicui/application-ui/theme/pill-switch-theme/default.variant"; diff --git a/apps/website/src/components/navigation/animated-background.tsx b/apps/website/src/components/navigation/animated-background.tsx index 4ee0b77e..ab90a94b 100644 --- a/apps/website/src/components/navigation/animated-background.tsx +++ b/apps/website/src/components/navigation/animated-background.tsx @@ -9,7 +9,7 @@ import { useId, useState, } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export type AnimatedBackgroundProps = { children: diff --git a/apps/website/src/components/navigation/desktop-menu.tsx b/apps/website/src/components/navigation/desktop-menu.tsx index 04d5d7fb..ddd328ba 100644 --- a/apps/website/src/components/navigation/desktop-menu.tsx +++ b/apps/website/src/components/navigation/desktop-menu.tsx @@ -3,7 +3,6 @@ import Link from "next/link"; import Image from "next/image"; import LogoLarge from "#/src/assets/logo/logo-large.png"; -import { cn } from "../../utils/cn"; import Byline from "../../ui/byline"; @@ -12,6 +11,7 @@ import StarCuicuiGithubButton from "../../ui/star-github-project-button"; import { SearchMenu } from "../search-menu/search-menu"; import NavigationMenu from "./navigation-menu"; import InfoMenuList from "#/src/components/navigation/info-menu-list"; +import { cn } from "@/cuicui/utils/cn"; export function DesktopSideMenu({ className, diff --git a/apps/website/src/components/navigation/navigation-item.tsx b/apps/website/src/components/navigation/navigation-item.tsx index 7adc7c9b..79701db8 100644 --- a/apps/website/src/components/navigation/navigation-item.tsx +++ b/apps/website/src/components/navigation/navigation-item.tsx @@ -4,7 +4,7 @@ import Link from "next/link"; import { usePathname, useSelectedLayoutSegments } from "next/navigation"; import type { AnchorHTMLAttributes, ReactNode } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import type { SectionType } from "@cuicui/ui/lib/types/component"; export function GlobalNavItem({ diff --git a/apps/website/src/components/navigation/navigation-menu.tsx b/apps/website/src/components/navigation/navigation-menu.tsx index 683c5072..0e613756 100644 --- a/apps/website/src/components/navigation/navigation-menu.tsx +++ b/apps/website/src/components/navigation/navigation-menu.tsx @@ -6,7 +6,7 @@ import { } from "#/src/components/navigation/navigation-item"; import { sectionList } from "@/section-list"; import type { CategoryType } from "@cuicui/ui/lib/types/component"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export default function NavigationMenu({ isMobile, diff --git a/apps/website/src/components/not-found-card.tsx b/apps/website/src/components/not-found-card.tsx index 1e45e8f1..27fc41e3 100644 --- a/apps/website/src/components/not-found-card.tsx +++ b/apps/website/src/components/not-found-card.tsx @@ -1,6 +1,6 @@ import Link from "next/link"; import GradientText from "../ui/gradient-text"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export default function NotFoundCard() { return ( diff --git a/apps/website/src/ui/badge.tsx b/apps/website/src/ui/badge.tsx index 3b8100e2..3a7028b3 100644 --- a/apps/website/src/ui/badge.tsx +++ b/apps/website/src/ui/badge.tsx @@ -1,7 +1,7 @@ import { type VariantProps, cva } from "class-variance-authority"; import type React from "react"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const badgeVariants = cva( cn( diff --git a/apps/website/src/ui/button.tsx b/apps/website/src/ui/button.tsx index 1e458d29..ea8475c0 100644 --- a/apps/website/src/ui/button.tsx +++ b/apps/website/src/ui/button.tsx @@ -1,7 +1,7 @@ import { type VariantProps, cva } from "class-variance-authority"; import { type HTMLMotionProps, motion } from "motion/react"; import type React from "react"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import GradientContainer from "./gradient-container"; import GradientText from "./gradient-text"; diff --git a/apps/website/src/ui/byline.tsx b/apps/website/src/ui/byline.tsx index aa9bef81..e5f88d79 100644 --- a/apps/website/src/ui/byline.tsx +++ b/apps/website/src/ui/byline.tsx @@ -1,6 +1,4 @@ import Link from "next/link"; -import { cn } from "../utils/cn"; -import GradientContainer from "./gradient-container"; import { ModernGradientContainerContent, ModernGradientContainerRoot, diff --git a/apps/website/src/ui/code-command-container.tsx b/apps/website/src/ui/code-command-container.tsx index 108be902..51fe116e 100644 --- a/apps/website/src/ui/code-command-container.tsx +++ b/apps/website/src/ui/code-command-container.tsx @@ -1,4 +1,4 @@ -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import CodeHighlighter from "./code-highlighter"; // import { ScrollArea, ScrollBar } from "./shadcn/scrollarea"; diff --git a/apps/website/src/ui/code-highlighter.tsx b/apps/website/src/ui/code-highlighter.tsx index 403a80ca..ded338b9 100644 --- a/apps/website/src/ui/code-highlighter.tsx +++ b/apps/website/src/ui/code-highlighter.tsx @@ -2,7 +2,7 @@ import type { HTMLAttributes } from "react"; import CopyToClipboardButton from "#/src/components/component-wrapper/copy-to-clipboard-button"; import ShikiCode from "@cuicui/ui/cuicui/application-ui/code/advanced-code-block/code-highlighter"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export default function CodeHighlighter({ code, className, diff --git a/apps/website/src/ui/copy-to-clipboard-code-snippet-dropdown.tsx b/apps/website/src/ui/copy-to-clipboard-code-snippet-dropdown.tsx index 48dffa1a..1b58b821 100644 --- a/apps/website/src/ui/copy-to-clipboard-code-snippet-dropdown.tsx +++ b/apps/website/src/ui/copy-to-clipboard-code-snippet-dropdown.tsx @@ -2,7 +2,6 @@ import { CheckIcon, ClipboardIcon } from "lucide-react"; import { toast } from "sonner"; -import { cn } from "../utils/cn"; import { Button } from "./shadcn/button"; import { ScrollArea, ScrollAreaViewport, ScrollBar } from "./shadcn/scrollarea"; diff --git a/apps/website/src/ui/gradient-container.tsx b/apps/website/src/ui/gradient-container.tsx index 8918995e..5ec71ade 100644 --- a/apps/website/src/ui/gradient-container.tsx +++ b/apps/website/src/ui/gradient-container.tsx @@ -1,5 +1,5 @@ import type { HTMLAttributes, ReactNode } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export const GradientContainer = ({ children, diff --git a/apps/website/src/ui/gradient-text.tsx b/apps/website/src/ui/gradient-text.tsx index 0e890d2b..158fa5e1 100644 --- a/apps/website/src/ui/gradient-text.tsx +++ b/apps/website/src/ui/gradient-text.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from "react"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export const GradientText = ({ children, diff --git a/apps/website/src/ui/navigation-menu.tsx b/apps/website/src/ui/navigation-menu.tsx index fdfdc10e..0bfe6d3d 100644 --- a/apps/website/src/ui/navigation-menu.tsx +++ b/apps/website/src/ui/navigation-menu.tsx @@ -9,7 +9,7 @@ import { useEffect, } from "react"; import { cloneElement, isValidElement, useId, useState } from "react"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; interface NavigationMenuProps extends React.HTMLAttributes { children: ReactNode; diff --git a/apps/website/src/ui/shadcn/button.tsx b/apps/website/src/ui/shadcn/button.tsx index d0f3d9dc..85e8429f 100644 --- a/apps/website/src/ui/shadcn/button.tsx +++ b/apps/website/src/ui/shadcn/button.tsx @@ -2,7 +2,7 @@ import { Slot } from "@radix-ui/react-slot"; import { type VariantProps, cva } from "class-variance-authority"; import { type ButtonHTMLAttributes, forwardRef } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const buttonVariants = cva( cn( diff --git a/apps/website/src/ui/shadcn/command.tsx b/apps/website/src/ui/shadcn/command.tsx index ab485c00..9a29f4c8 100644 --- a/apps/website/src/ui/shadcn/command.tsx +++ b/apps/website/src/ui/shadcn/command.tsx @@ -11,7 +11,7 @@ import { forwardRef, } from "react"; import { Dialog, DialogContent } from "#/src/ui/shadcn/dialog"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const Command = forwardRef< ElementRef, diff --git a/apps/website/src/ui/shadcn/dialog.tsx b/apps/website/src/ui/shadcn/dialog.tsx index 5dcbf6c6..d7158c41 100644 --- a/apps/website/src/ui/shadcn/dialog.tsx +++ b/apps/website/src/ui/shadcn/dialog.tsx @@ -10,7 +10,7 @@ import { type HTMLAttributes, forwardRef, } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const Dialog = DialogPrimitive.Root; diff --git a/apps/website/src/ui/shadcn/dropdown-menu.tsx b/apps/website/src/ui/shadcn/dropdown-menu.tsx index 770dc89f..f748c06f 100644 --- a/apps/website/src/ui/shadcn/dropdown-menu.tsx +++ b/apps/website/src/ui/shadcn/dropdown-menu.tsx @@ -9,7 +9,7 @@ import { type HTMLAttributes, forwardRef, } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const DropdownMenu = DropdownMenuPrimitive.Root; diff --git a/apps/website/src/ui/shadcn/resizable.tsx b/apps/website/src/ui/shadcn/resizable.tsx index c6b68c8c..3cd2157c 100644 --- a/apps/website/src/ui/shadcn/resizable.tsx +++ b/apps/website/src/ui/shadcn/resizable.tsx @@ -4,7 +4,7 @@ import { GripVertical } from "lucide-react"; import type { ComponentProps } from "react"; import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const ResizablePanelGroup = ({ className, diff --git a/apps/website/src/ui/shadcn/scrollarea.tsx b/apps/website/src/ui/shadcn/scrollarea.tsx index f786f128..0a8fe427 100644 --- a/apps/website/src/ui/shadcn/scrollarea.tsx +++ b/apps/website/src/ui/shadcn/scrollarea.tsx @@ -1,6 +1,6 @@ "use client"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"; import * as React from "react"; diff --git a/apps/website/src/ui/shadcn/select.tsx b/apps/website/src/ui/shadcn/select.tsx index 1cb61838..833d18e4 100644 --- a/apps/website/src/ui/shadcn/select.tsx +++ b/apps/website/src/ui/shadcn/select.tsx @@ -8,7 +8,7 @@ import { type ElementRef, forwardRef, } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const Select = SelectPrimitive.Root; diff --git a/apps/website/src/ui/shadcn/tabs.tsx b/apps/website/src/ui/shadcn/tabs.tsx index 62406d44..36905c26 100644 --- a/apps/website/src/ui/shadcn/tabs.tsx +++ b/apps/website/src/ui/shadcn/tabs.tsx @@ -7,7 +7,7 @@ import { type ElementRef, forwardRef, } from "react"; -import { cn } from "#/src/utils/cn"; +import { cn } from "@/cuicui/utils/cn"; const Tabs = TabsPrimitive.Root; diff --git a/apps/website/src/ui/stepper.tsx b/apps/website/src/ui/stepper.tsx index a1ac9051..cf68cc0f 100644 --- a/apps/website/src/ui/stepper.tsx +++ b/apps/website/src/ui/stepper.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from "react"; -import { cn } from "../utils/cn"; +import { cn } from "@/cuicui/utils/cn"; export const StaticStep = ({ step, diff --git a/apps/website/src/utils/cn.ts b/apps/website/src/utils/cn.ts deleted file mode 100644 index 365058ce..00000000 --- a/apps/website/src/utils/cn.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type ClassValue, clsx } from "clsx"; -import { twMerge } from "tailwind-merge"; - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} diff --git a/packages/ui/categories-previews-list.ts b/packages/ui/categories-previews-list.ts index 5f57288d..c1608015 100644 --- a/packages/ui/categories-previews-list.ts +++ b/packages/ui/categories-previews-list.ts @@ -8,6 +8,7 @@ import other_cursors_preview from "./cuicui/other/cursors/preview"; import utils_catch_error_preview from "./cuicui/utils/catch-error/preview"; import utils_sleep_preview from "./cuicui/utils/sleep/preview"; import utils_cn_preview from "./cuicui/utils/cn/preview"; +import utils_create_error_preview from "./cuicui/utils/create-error/preview"; import marketing_ui_statistics_preview from "./cuicui/marketing-ui/statistics/preview"; import marketing_ui_footer_preview from "./cuicui/marketing-ui/footer/preview"; import marketing_ui_carousels_preview from "./cuicui/marketing-ui/carousels/preview"; @@ -91,6 +92,7 @@ export const categoriesPreviewsList: Record JSX.Element> = { "catch-error": utils_catch_error_preview, sleep: utils_sleep_preview, cn: utils_cn_preview, + "create-error": utils_create_error_preview, statistics: marketing_ui_statistics_preview, footer: marketing_ui_footer_preview, carousels: marketing_ui_carousels_preview, diff --git a/packages/ui/cuicui/utils/create-error/category.ts b/packages/ui/cuicui/utils/create-error/category.ts new file mode 100644 index 00000000..b4041d33 --- /dev/null +++ b/packages/ui/cuicui/utils/create-error/category.ts @@ -0,0 +1,11 @@ +import type { CategoryMetaType } from "@/lib/types/component"; +import { ChevronsLeftRightEllipsisIcon } from "lucide-react"; + +export const Category: CategoryMetaType = { + name: "Create Error", + description: "Utilities to create normalized errors accross the application", + icon: ChevronsLeftRightEllipsisIcon, + latestUpdateDate: new Date("2024-12-30"), +}; + +export default Category; diff --git a/packages/ui/cuicui/utils/create-error/create-error/component.ts b/packages/ui/cuicui/utils/create-error/create-error/component.ts new file mode 100644 index 00000000..9e62218c --- /dev/null +++ b/packages/ui/cuicui/utils/create-error/create-error/component.ts @@ -0,0 +1,8 @@ +import type { ComponentMetaType } from "@/lib/types/component"; + +export const Component: ComponentMetaType = { + name: "Create Error", + description: "Utilities to create normalized errors accross the application", +}; + +export default Component; diff --git a/packages/ui/cuicui/utils/create-error/create-error/create-error.variant.tsx b/packages/ui/cuicui/utils/create-error/create-error/create-error.variant.tsx new file mode 100644 index 00000000..821fd541 --- /dev/null +++ b/packages/ui/cuicui/utils/create-error/create-error/create-error.variant.tsx @@ -0,0 +1,39 @@ +"use client"; +import { createError, type NormalizedError } from "@/cuicui/utils/create-error"; +import { useEffect, useState } from "react"; + +export const PreviewCreateError = () => { + const [error, setError] = useState(null); + useEffect(() => { + console.log("error", error); + }, [error]); + return ( +
+ + +

Error message: {error?.message}

+
{JSON.stringify(error, null, 2)}
+
+ ); +}; + +export default PreviewCreateError; diff --git a/packages/ui/cuicui/utils/create-error/index.ts b/packages/ui/cuicui/utils/create-error/index.ts new file mode 100644 index 00000000..bf0b046c --- /dev/null +++ b/packages/ui/cuicui/utils/create-error/index.ts @@ -0,0 +1,86 @@ +/** + * Options for creating a normalized error. + */ +export interface CreateErrorOptions { + statusCode?: number; + statusMessage?: string; + message?: string; + fatal?: boolean; + data?: unknown; + cause?: unknown; + stack?: string; +} + +export type CreateErrorInput = + | string + | (CreateErrorOptions & Record); + +/** + * A specialized error type that extends the native `Error` object + */ +export class NormalizedError extends Error { + statusCode: number; + statusMessage?: string; + fatal?: boolean; + data?: unknown; + cause?: unknown; + + constructor(opts: CreateErrorOptions) { + super(opts.message || "An unexpected error occurred"); + Object.setPrototypeOf(this, new.target.prototype); + + this.statusCode = opts.statusCode ?? 500; + this.statusMessage = opts.statusMessage; + this.fatal = opts.fatal; + this.data = opts.data; + this.cause = opts.cause; + this.message = opts.message || "An unexpected error occurred"; + + if (opts.stack) { + this.stack = opts.stack; + } else if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } +} + +interface DefaultErrorMap { + [key: string]: CreateErrorOptions; +} + +const defaultErrors = { + BAD_REQUEST: { statusCode: 400, statusMessage: "Bad Request" }, + UNAUTHORIZED: { statusCode: 401, statusMessage: "Unauthorized" }, + FORBIDDEN: { statusCode: 403, statusMessage: "Forbidden" }, + NOT_FOUND: { statusCode: 404, statusMessage: "Not Found" }, + INTERNAL_ERROR: { statusCode: 500, statusMessage: "Internal Server Error" }, +} satisfies DefaultErrorMap; + +type KeyOfDefaultErrors = keyof typeof defaultErrors; + +export function createError( + input: KeyOfDefaultErrors | string | CreateErrorOptions, + overrides?: CreateErrorOptions, +): NormalizedError { + // If input is a string, check if it matches a default error key + if (typeof input === "string") { + if (input in defaultErrors) { + // Narrow input to KeyOfDefaultErrors for indexing + const combinedOptions = { + ...defaultErrors[input as KeyOfDefaultErrors], + ...overrides, + }; + return new NormalizedError(combinedOptions); + } + + // Otherwise treat input as the error message + return new NormalizedError({ + ...overrides, + message: input, + statusCode: overrides?.statusCode ?? 500, + }); + } + + // If input is an object (CreateErrorOptions) + return new NormalizedError(input); +} diff --git a/packages/ui/cuicui/utils/create-error/preview.tsx b/packages/ui/cuicui/utils/create-error/preview.tsx new file mode 100644 index 00000000..ca289319 --- /dev/null +++ b/packages/ui/cuicui/utils/create-error/preview.tsx @@ -0,0 +1,16 @@ +export default function () { + return ( +
+ {/* Exclamation Mark */} +
+
+
+
+ + {/* Error-like lines */} +
+
+
+
+ ); +} diff --git a/packages/ui/section-list.ts b/packages/ui/section-list.ts index 1219a7f0..17fce147 100644 --- a/packages/ui/section-list.ts +++ b/packages/ui/section-list.ts @@ -83,6 +83,7 @@ import other_qr_code_category from "@/cuicui/other/qr-code/category"; import other_transition_wrappers_category from "@/cuicui/other/transition-wrappers/category"; import utils_catch_error_category from "@/cuicui/utils/catch-error/category"; import utils_cn_category from "@/cuicui/utils/cn/category"; +import utils_create_error_category from "@/cuicui/utils/create-error/category"; import utils_sleep_category from "@/cuicui/utils/sleep/category"; import application_ui_action_menu_advanced_bottom_action_menu_component from "@/cuicui/application-ui/action-menu/advanced-bottom-action-menu/component"; import application_ui_alert_modern_glassy_alert_component from "@/cuicui/application-ui/alert/modern-glassy-alert/component"; @@ -206,6 +207,7 @@ import other_transition_wrappers_blur_appear_component from "@/cuicui/other/tran import other_transition_wrappers_text_effect_wrapper_component from "@/cuicui/other/transition-wrappers/text-effect-wrapper/component"; import utils_catch_error_catch_error_component from "@/cuicui/utils/catch-error/catch-error/component"; import utils_cn_cn_component from "@/cuicui/utils/cn/cn/component"; +import utils_create_error_create_error_component from "@/cuicui/utils/create-error/create-error/component"; import utils_sleep_sleep_component from "@/cuicui/utils/sleep/sleep/component"; import application_ui_action_menu_advanced_bottom_action_menu_default_variant from "@/cuicui/application-ui/action-menu/advanced-bottom-action-menu/default.variant"; import application_ui_alert_modern_glassy_alert_modern_glassy_alert_variant from "@/cuicui/application-ui/alert/modern-glassy-alert/modern-glassy-alert.variant"; @@ -356,6 +358,7 @@ import other_transition_wrappers_text_effect_wrapper_per_line_variant from "@/cu import other_transition_wrappers_text_effect_wrapper_per_word_variant from "@/cuicui/other/transition-wrappers/text-effect-wrapper/per-word.variant"; import utils_catch_error_catch_error_catch_error_variant from "@/cuicui/utils/catch-error/catch-error/catch-error.variant"; import utils_cn_cn_default_variant from "@/cuicui/utils/cn/cn/default.variant"; +import utils_create_error_create_error_create_error_variant from "@/cuicui/utils/create-error/create-error/create-error.variant"; import utils_sleep_sleep_sleep_variant from "@/cuicui/utils/sleep/sleep/sleep.variant"; import type { SectionType } from "@/lib/types/component"; @@ -2762,6 +2765,26 @@ export const sectionList: SectionType[] = [ }, ], }, + { + meta: utils_create_error_category, + slug: "create-error", + components: [ + { + meta: utils_create_error_create_error_component, + slug: "create-error", + variants: [ + { + name: "create-error", + variantComponent: + utils_create_error_create_error_create_error_variant, + slug: "create-error", + pathname: + "cuicui/utils/create-error/create-error/create-error.variant.tsx", + }, + ], + }, + ], + }, { meta: utils_sleep_category, slug: "sleep",