diff --git a/js/react/lib/components/progress-bar/index.ts b/js/react/lib/components/progress-bar/index.ts new file mode 100644 index 0000000..7a5a721 --- /dev/null +++ b/js/react/lib/components/progress-bar/index.ts @@ -0,0 +1 @@ +export * from "./progress-bar.component"; diff --git a/js/react/lib/components/progress-bar/progress-bar.component.tsx b/js/react/lib/components/progress-bar/progress-bar.component.tsx new file mode 100644 index 0000000..c005d40 --- /dev/null +++ b/js/react/lib/components/progress-bar/progress-bar.component.tsx @@ -0,0 +1,41 @@ +import { Ferris } from "@/icons/ferris"; +import { cn } from "@/utils/tw-merge"; + +type ProgressBarProps = { + percentage: number; +}; +export const ProgressBar = (props: ProgressBarProps) => { + const percentage = Number(props.percentage ?? 0); + const isZeroProgress = percentage === 0; + const progressIsInLimit = isZeroProgress || percentage === 100; + const isInMinLimit = percentage < 25; + + const position = { + right: isInMinLimit ? "auto" : `${100 - percentage}%`, + left: isInMinLimit ? `${percentage}%` : "auto", + }; + + return ( +
+
+ + {percentage}% + + +
+
+
+ ); +}; diff --git a/js/react/lib/icons/ferris.tsx b/js/react/lib/icons/ferris.tsx new file mode 100644 index 0000000..f985efc --- /dev/null +++ b/js/react/lib/icons/ferris.tsx @@ -0,0 +1,32 @@ +import { SVGProps } from "react"; +export const Ferris = (props: SVGProps) => ( + + + + + + + +); diff --git a/js/react/lib/index.ts b/js/react/lib/index.ts index dfabc86..a63f98f 100644 --- a/js/react/lib/index.ts +++ b/js/react/lib/index.ts @@ -13,4 +13,5 @@ export * from "./components/dropdown"; export * from "./components/calendar"; export * from "./components/dropdown-tree"; export * from "./components/input-search"; +export * from "./components/progress-bar"; export * from "./icons"; diff --git a/js/react/showcase/App.tsx b/js/react/showcase/App.tsx index b054de9..00be923 100644 --- a/js/react/showcase/App.tsx +++ b/js/react/showcase/App.tsx @@ -15,6 +15,7 @@ import { Calendar, CalendarRangeDate, DropdownTree, + ProgressBar, InputSearch, } from "@rustlanges/react"; import { ShowComponent } from "./ShowComponent"; @@ -512,6 +513,17 @@ export function App() {
+ ); } diff --git a/styles/components.css b/styles/components.css index 814cb07..a7f7d88 100644 --- a/styles/components.css +++ b/styles/components.css @@ -15,3 +15,4 @@ @import "./components/dropdown-tree-subtopic.css"; @import "./components/dropdown-tree-end.css"; @import "./components/input-search.css"; +@import "./components/progress-bar.css"; diff --git a/styles/components/progress-bar.css b/styles/components/progress-bar.css new file mode 100644 index 0000000..8a861e2 --- /dev/null +++ b/styles/components/progress-bar.css @@ -0,0 +1,35 @@ +@layer components { + .rustlanges-progress-bar__container { + @apply h-[33px] w-full; + } + + .rustlanges-progress-bar { + @apply relative h-2.5 w-full rounded-xl border border-black; + @apply bg-neutral-100 dark:bg-neutral-900; + } + .rustlanges-progress-bar__fill { + @apply absolute left-0 h-full; + @apply border-r border-r-black; + @apply rounded-l-xl; + @apply transition-all duration-1000; + @apply bg-primary-500; + } + .rustlanges-progress-bar__percentage { + @apply absolute -top-6; + @apply flex items-center gap-1; + @apply h-fit w-fit; + @apply px-1 py-0.5; + @apply text-primary-500; + @apply border border-black; + @apply rounded-l-xs rounded-tr-xs; + @apply transition-all duration-1000; + @apply bg-white dark:bg-neutral-900; + } + + .rustlanges-progress-bar__fill--limit { + @apply rounded-r-xl border-none; + } + .rustlanges-progress-bar__percentage--invert { + @apply rounded-r-xs rounded-bl-none; + } +} diff --git a/styles/theme.css b/styles/theme.css index f594b00..69a7bb8 100644 --- a/styles/theme.css +++ b/styles/theme.css @@ -124,6 +124,8 @@ --font-monospace-body: monospace; /* Border radiuses */ + + --radius-xs: 4px; --radius-sm: 8px; --radius-md: 16px; --radius-DEFAULT: 16px;