Finish migrating components

This commit is contained in:
adilallo
2026-01-29 17:59:11 -07:00
parent b5735bb2ad
commit 539f6c62e3
79 changed files with 2449 additions and 1730 deletions
+196
View File
@@ -0,0 +1,196 @@
"use client";
import { memo, useCallback, useId, forwardRef } from "react";
import { ToggleView } from "./Toggle.view";
import type { ToggleProps } from "./Toggle.types";
const ToggleContainer = forwardRef<HTMLButtonElement, ToggleProps>(
(
{
label,
checked = false,
onChange,
onFocus,
onBlur,
disabled = false,
state = "default",
showIcon = false,
showText = false,
icon = "I",
text = "Toggle",
className = "",
...props
},
ref,
) => {
const toggleId = useId();
const labelId = useId();
// Size styles - single size with specific dimensions
const sizeStyles = {
toggle: "h-[var(--measures-sizing-032)] px-[16px] py-[8px] gap-[4px]",
label: "text-[12px] leading-[16px]",
};
// State styles
const getStateStyles = (): {
toggle: string;
label: string;
} => {
if (disabled) {
return {
toggle:
"bg-[var(--color-surface-default-tertiary)] text-[var(--color-content-default-tertiary)] cursor-not-allowed",
label: "text-[var(--color-content-default-secondary)]",
};
}
if (checked) {
switch (state) {
case "hover":
return {
toggle:
"bg-[var(--color-surface-default-secondary)] text-[var(--color-content-default-primary)]",
label: "text-[var(--color-content-default-secondary)]",
};
case "focus":
return {
toggle:
"bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)] shadow-[0_0_5px_1px_#3281F8]",
label: "text-[var(--color-content-default-secondary)]",
};
default:
return {
toggle:
"bg-[var(--color-magenta-magenta100)] text-[var(--color-content-default-primary)] shadow-[0_0_0_1px_var(--color-border-default-brand-primary)]",
label: "text-[var(--color-content-default-secondary)]",
};
}
} else {
switch (state) {
case "hover":
return {
toggle:
"bg-[var(--color-surface-default-secondary)] text-[var(--color-content-default-primary)]",
label: "text-[var(--color-content-default-secondary)]",
};
case "focus":
return {
toggle:
"bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)] shadow-[0_0_5px_1px_#3281F8]",
label: "text-[var(--color-content-default-secondary)]",
};
default:
return {
toggle:
"bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)]",
label: "text-[var(--color-content-default-secondary)]",
};
}
}
};
const stateStyles = getStateStyles();
const currentSize = sizeStyles;
// Container classes
const containerClasses = "flex flex-col gap-[4px]";
const labelClasses = `${currentSize.label} font-inter font-medium`;
const toggleClasses = `
${currentSize.toggle}
${stateStyles.toggle}
rounded-full
font-inter
font-normal
text-[12px]
leading-[16px]
cursor-pointer
transition-all
duration-200
focus:outline-none
focus-visible:shadow-[0_0_5px_1px_#3281F8]
${!checked ? "hover:!bg-[var(--color-surface-default-secondary)]" : ""}
flex
items-center
justify-center
gap-[4px]
${className}
`
.trim()
.replace(/\s+/g, " ");
const handleChange = useCallback(
(
e:
| React.MouseEvent<HTMLButtonElement>
| React.KeyboardEvent<HTMLButtonElement>,
) => {
if (!disabled && onChange) {
onChange(e);
}
},
[disabled, onChange],
);
const handleFocus = useCallback(
(e: React.FocusEvent<HTMLButtonElement>) => {
if (!disabled && onFocus) {
onFocus(e);
}
},
[disabled, onFocus],
);
const handleBlur = useCallback(
(e: React.FocusEvent<HTMLButtonElement>) => {
if (!disabled && onBlur) {
onBlur(e);
}
},
[disabled, onBlur],
);
const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLButtonElement>) => {
if (!disabled && (e.key === "Enter" || e.key === " ")) {
e.preventDefault();
if (onChange) {
onChange(e);
}
}
},
[disabled, onChange],
);
return (
<ToggleView
ref={ref}
toggleId={toggleId}
labelId={labelId}
checked={checked}
disabled={disabled}
state={state}
label={label}
showIcon={showIcon}
showText={showText}
icon={icon}
text={text}
className={className}
containerClasses={containerClasses}
labelClasses={labelClasses}
toggleClasses={toggleClasses}
onClick={handleChange}
onKeyDown={handleKeyDown}
onFocus={handleFocus}
onBlur={handleBlur}
{...props}
/>
);
},
);
ToggleContainer.displayName = "Toggle";
export default memo(ToggleContainer);
+44
View File
@@ -0,0 +1,44 @@
export interface ToggleProps
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onChange"> {
label?: string;
checked?: boolean;
onChange?: (
_e:
| React.MouseEvent<HTMLButtonElement>
| React.KeyboardEvent<HTMLButtonElement>,
) => void;
onFocus?: (_e: React.FocusEvent<HTMLButtonElement>) => void;
onBlur?: (_e: React.FocusEvent<HTMLButtonElement>) => void;
disabled?: boolean;
state?: "default" | "hover" | "focus";
showIcon?: boolean;
showText?: boolean;
icon?: string;
text?: string;
className?: string;
}
export interface ToggleViewProps {
toggleId: string;
labelId: string;
checked: boolean;
disabled: boolean;
state: "default" | "hover" | "focus";
label?: string;
showIcon: boolean;
showText: boolean;
icon: string;
text: string;
className: string;
containerClasses: string;
labelClasses: string;
toggleClasses: string;
onClick: (
e:
| React.MouseEvent<HTMLButtonElement>
| React.KeyboardEvent<HTMLButtonElement>,
) => void;
onKeyDown: (e: React.KeyboardEvent<HTMLButtonElement>) => void;
onFocus: (e: React.FocusEvent<HTMLButtonElement>) => void;
onBlur: (e: React.FocusEvent<HTMLButtonElement>) => void;
}
+63
View File
@@ -0,0 +1,63 @@
import { forwardRef } from "react";
import type { ToggleViewProps } from "./Toggle.types";
export const ToggleView = forwardRef<HTMLButtonElement, ToggleViewProps>(
(
{
toggleId,
labelId,
checked,
disabled,
label,
showIcon,
showText,
icon,
text,
containerClasses,
labelClasses,
toggleClasses,
onClick,
onKeyDown,
onFocus,
onBlur,
...rest
},
ref,
) => {
return (
<div className={containerClasses}>
{label && (
<label
id={labelId}
htmlFor={toggleId}
className={`${labelClasses} text-[var(--color-content-default-secondary)]`}
>
{label}
</label>
)}
<div className={disabled ? "opacity-40" : ""}>
<button
ref={ref}
id={toggleId}
type="button"
role="switch"
aria-checked={checked}
aria-labelledby={label ? labelId : undefined}
disabled={disabled}
onClick={onClick}
onKeyDown={onKeyDown}
onFocus={onFocus}
onBlur={onBlur}
className={toggleClasses}
{...rest}
>
{showIcon && <span className="italic">{icon}</span>}
{showText && <span>{text}</span>}
</button>
</div>
</div>
);
},
);
ToggleView.displayName = "ToggleView";
+2
View File
@@ -0,0 +1,2 @@
export { default } from "./Toggle.container";
export type { ToggleProps } from "./Toggle.types";