Skip to content

Commit

Permalink
[sparkle] - refactor: streamline handling of animated text variants
Browse files Browse the repository at this point in the history
 - Abstract animated text background and text color variants into separate records for cleaner code structure
 - Use cva utility from `class-variance-authority` to manage TextArea component styles, introducing a more flexible and scalable approach to variant handling

[sparkle] - fix: mark `isBusy` prop in `Chip` component as potentially undefined

 - Adjust typings for `isBusy` prop to correctly reflect its optional nature in the `Chip` component

[sparkle] - refactor: introduce cva to refactor `TextArea` styles and variants

 - Consolidate `TextArea` styling and variant handling into a single cva call to improve readability and maintainability
 - Simplify the props destructuring in the `TextArea` component by relying on cva to handle default variants and classes
  • Loading branch information
JulesBelveze committed Nov 12, 2024
1 parent 157438d commit 514e6ad
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 61 deletions.
71 changes: 43 additions & 28 deletions sparkle/src/components/AnimatedText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,62 @@ import React from "react";

import { cn } from "@sparkle/lib/utils";

const ANIMATED_TEXT_VARIANTS = [
"muted",
"highlight",
"emerald",
"amber",
"slate",
"purple",
"warning",
"sky",
"pink",
"red",
] as const;

type AnimatedTextVariantType = (typeof ANIMATED_TEXT_VARIANTS)[number];

const animatedVariants: Record<AnimatedTextVariantType, string> = {
muted: "s-from-transparent s-via-primary-950/80 s-via-50% s-to-transparent",
highlight: "s-from-highlight s-via-highlight-800 s-via-50% s-to-highlight",
emerald: "s-from-emerald-800 s-via-emerald-950 s-via-50% s-to-emerald-800",
amber: "s-from-amber-800 s-via-amber-950 s-via-50% s-to-amber-800",
slate: "s-from-slate-600 s-via-slate-950 s-via-50% s-to-slate-600",
purple: "s-from-purple-800 s-via-purple-950 s-via-50% s-to-purple-800",
warning: "s-from-warning-800 s-via-warning-950 s-via-50% s-to-warning-800",
sky: "s-from-sky-800 s-via-sky-950 s-via-50% s-to-sky-800",
pink: "s-from-pink-800 s-via-pink-950 s-via-50% s-to-pink-800",
red: "s-from-red-800 s-via-red-950 s-via-50% s-to-red-800",
};

const animVariants = cva(
"s-relative s-mx-auto s-max-w-md s-text-black/0 s-animate-shiny-text s-bg-clip-text s-bg-no-repeat [background-position:0_0] [background-size:50%_100%] s-bg-gradient-to-r",
{
variants: {
variant: {
muted:
"s-from-transparent s-via-primary-950/80 s-via-50% s-to-transparent",
highlight:
"s-from-highlight s-via-highlight-800 s-via-50% s-to-highlight",
emerald:
"s-from-emerald-800 s-via-emerald-950 s-via-50% s-to-emerald-800",
amber: "s-from-amber-800 s-via-amber-950 s-via-50% s-to-amber-800",
slate: "s-from-slate-600 s-via-slate-950 s-via-50% s-to-slate-600",
purple: "s-from-purple-800 s-via-purple-950 s-via-50% s-to-purple-800",
warning:
"s-from-warning-800 s-via-warning-950 s-via-50% s-to-warning-800",
sky: "s-from-sky-800 s-via-sky-950 s-via-50% s-to-sky-800",
pink: "s-from-pink-800 s-via-pink-950 s-via-50% s-to-pink-800",
red: "s-from-red-800 s-via-red-950 s-via-50% s-to-red-800",
},
variant: animatedVariants,
},
defaultVariants: {
variant: "muted",
},
}
);

const animatedTextVariants: Record<AnimatedTextVariantType, string> = {
muted: "s-text-muted-foreground",
highlight: "s-text-highlight",
emerald: "s-text-emerald-800",
amber: "s-text-amber-800",
slate: "s-text-slate-600",
purple: "s-text-purple-800-800",
warning: "s-text-warning-800",
sky: "s-text-sky-800",
pink: "s-text-pink-800",
red: "s-text-red-800",
};

const textVariants = cva("s-absolute s-inset-0", {
variants: {
variant: {
muted: "s-text-muted-foreground",
highlight: "s-text-highlight",
emerald: "s-text-emerald-800",
amber: "s-text-amber-800",
slate: "s-text-slate-600",
purple: "s-text-purple-800-800",
warning: "s-text-warning-800",
sky: "s-text-sky-800",
pink: "s-text-pink-800",
red: "s-text-red-800",
},
variant: animatedTextVariants,
},
defaultVariants: {
variant: "muted",
Expand Down
2 changes: 1 addition & 1 deletion sparkle/src/components/Chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function Chip({
label,
children,
className,
isBusy = false,
isBusy,
icon,
}: ChipProps) {
return (
Expand Down
74 changes: 42 additions & 32 deletions sparkle/src/components/TextArea.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { cva } from "class-variance-authority";
import React from "react";

import { cn } from "@sparkle/lib/utils";
Expand All @@ -15,55 +16,64 @@ export interface TextareaProps
isDisplay?: boolean;
}

const textAreaStyles = cn(
"s-flex s-w-full s-px-3 s-py-2",
"s-text-sm placeholder:s-text-muted-foreground s-text-foreground s-bg-muted-background s-ring-offset-background s-border s-border-border-dark/0 s-rounded-xl",
"s-transition s-duration-100",
"focus-visible:s-outline-none focus-visible:s-border-border-dark focus-visible:s-ring-2 focus-visible:s-ring-offset-2 "
const textAreaVariants = cva(
"s-flex s-w-full s-px-3 s-py-2 s-text-sm s-text-foreground s-bg-muted-background s-ring-offset-background s-border s-border-border-dark/0 s-rounded-xl s-transition s-duration-100 focus-visible:s-outline-none focus-visible:s-border-border-dark focus-visible:s-ring-2 focus-visible:s-ring-offset-2",
{
variants: {
resize: {
none: "s-resize-none",
vertical: "s-resize-y",
horizontal: "s-resize-x",
both: "s-resize",
},
error: {
true: "s-ring-warning-200 focus:s-ring-warning-300 dark:s-ring-warning-200-dark dark:focus:s-ring-warning-300-dark",
false:
"s-ring-structure-200 focus:s-ring-action-300 dark:s-ring-structure-300-dark dark:focus:s-ring-action-300-dark",
},
disabled: {
true: "disabled:s-cursor-not-allowed disabled:s-text-muted-foreground",
false: "",
},
isDisplay: {
true: "s-cursor-default",
false: "",
},
},
defaultVariants: {
resize: "both",
error: false,
disabled: false,
isDisplay: false,
},
}
);

const TextArea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
(
{
className,
resize = "both",
resize,
minRows = 10,
error,
showErrorLabel,
disabled = false,
isDisplay = false,
disabled,
isDisplay,
...props
},
ref
) => {
const resizeClass = {
none: "s-resize-none",
vertical: "s-resize-y",
horizontal: "s-resize-x",
both: "s-resize",
};

return (
<div className="s-flex s-flex-col s-gap-1 s-p-px">
<textarea
className={cn(
textAreaStyles,
disabled
? isDisplay
? "s-cursor-default"
: "disabled:s-cursor-not-allowed disabled:s-text-muted-foreground"
: "",
resizeClass[resize],
className,
!error
? cn(
"s-ring-structure-200 focus:s-ring-action-300",
"dark:s-ring-structure-300-dark dark:focus:s-ring-action-300-dark"
)
: cn(
"s-ring-warning-200 focus:s-ring-warning-300",
"dark:s-ring-warning-200-dark dark:focus:s-ring-warning-300-dark"
)
textAreaVariants({
resize,
error: !!error,
disabled,
isDisplay,
className,
})
)}
ref={ref}
rows={minRows}
Expand Down

0 comments on commit 514e6ad

Please sign in to comment.