1import { BadgeDelta } from "~/components/ui/badge-delta";2
3export default function BadgeDemo() {4 return (5 <div class="flex flex-col items-center gap-2">6 <div class="flex w-full flex-wrap gap-2">7 <BadgeDelta deltaType="decrease">-5</BadgeDelta>8 <BadgeDelta deltaType="moderateDecrease">-1</BadgeDelta>9 <BadgeDelta deltaType="unchanged">0</BadgeDelta>10 <BadgeDelta deltaType="moderateIncrease">+1</BadgeDelta>11 <BadgeDelta deltaType="increase">+5</BadgeDelta>12 </div>13 </div>14 );15}
npx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/badge-delta.json
yarn shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/badge-delta.json
pnpm dlx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/badge-delta.json
bunx --bun shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/badge-delta.json
Install the following component dependencies
Copy and paste the following code into your project
1import type { BadgeProps } from "~/components/ui/badge";2import type { VariantProps } from "class-variance-authority";3import type { Component, JSXElement } from "solid-js";4
5import { createEffect, on, Show, splitProps } from "solid-js";6import { cva } from "class-variance-authority";7import ArrowDownIcon from "lucide-solid/icons/arrow-down";8import ArrowDownRightIcon from "lucide-solid/icons/arrow-down-right";9import ArrowRightIcon from "lucide-solid/icons/arrow-right";10import ArrowUpIcon from "lucide-solid/icons/arrow-up";11import ArrowUpRightIcon from "lucide-solid/icons/arrow-up-right";12
13import { Badge } from "~/components/ui/badge";14import { cn } from "~/lib/utils";15
16type DeltaType =17 | "increase"18 | "moderateIncrease"19 | "unchanged"20 | "moderateDecrease"21 | "decrease";22
23const badgeDeltaVariants = cva("", {24 variants: {25 variant: {26 success: "bg-success text-success-foreground hover:bg-success",27 warning: "bg-warning text-warning-foreground hover:bg-warning",28 error: "bg-error text-error-foreground hover:bg-error",29 },30 },31});32type DeltaVariant = NonNullable<33 VariantProps<typeof badgeDeltaVariants>["variant"]34>;35
36const iconMap: {37 [key in DeltaType]: (props: { class?: string }) => JSXElement;38} = {39 increase: (props) => <ArrowUpIcon class={props.class} />,40 moderateIncrease: (props) => <ArrowUpRightIcon class={props.class} />,41 unchanged: (props) => <ArrowRightIcon class={props.class} />,42 moderateDecrease: (props) => <ArrowDownRightIcon class={props.class} />,43 decrease: (props) => <ArrowDownIcon class={props.class} />,44};45
46const variantMap: { [key in DeltaType]: DeltaVariant } = {47 increase: "success",48 moderateIncrease: "success",49 unchanged: "warning",50 moderateDecrease: "error",51 decrease: "error",52};53
54type BadgeDeltaProps = Omit<BadgeProps, "variant"> & {55 deltaType: DeltaType;56 iconLocation?: "left" | "right";57};58
59const BadgeDelta: Component<BadgeDeltaProps> = (props) => {60 const [local, others] = splitProps(props, [61 "class",62 "children",63 "deltaType",64 "iconLocation",65 ]);66
67 // eslint-disable-next-line solid/reactivity68 let Icon = iconMap[local.deltaType];69 createEffect(70 on(71 () => local.deltaType,72 () => {73 Icon = iconMap[local.deltaType];74 },75 ),76 );77
78 return (79 <Badge80 class={cn(81 badgeDeltaVariants({ variant: variantMap[local.deltaType] }),82 local.class,83 )}84 {...others}85 >86 <span class="flex gap-1">87 <Show88 when={89 local.iconLocation === undefined || local.iconLocation === "left"90 }91 >92 <Icon class="size-4" />93 </Show>94 {local.children}95 <Show when={local.iconLocation === "right"}>96 <Icon class="size-4" />97 </Show>98 </span>99 </Badge>100 );101};102
103export { BadgeDelta };
Update the import paths to match your project setup.
1import { BadgeDelta } from "~/components/ui/badge-delta";
1<BadgeDelta deltaType="increase">2 <span>+10</span>3 <span>New followers</span>4</BadgeDelta>