Compare commits

..

16 Commits

93 changed files with 3161 additions and 395 deletions

5
.gitignore vendored
View File

@@ -7,10 +7,7 @@ dist
*.local *.local
.tanstack .tanstack
*.tgz *.tgz
test/coverage coverage
# Editor directories and files
.vscode
# Sonarqube # Sonarqube
sonarBuild.sh sonarBuild.sh

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"sonarlint.connectedMode.project": {
"connectionId": "mattrixwvSonarqube",
"projectKey": "MattrixwvReactComponents"
}
}

View File

@@ -1 +1,5 @@
# Mattrixwv React Components
[![Quality Gate Status](https://sonarqube.mattrixwv.com/api/project_badges/measure?project=MattrixwvReactComponents&metric=alert_status&token=sqb_e8b5362c32319b0612536e683cdbe2a77ec5bb32)](https://sonarqube.mattrixwv.com/dashboard?id=MattrixwvReactComponents)
Under Construction Under Construction

View File

@@ -1,10 +1,9 @@
import type { CheckboxProps } from "$/types/InputTypes"; import type { CheckboxProps } from "$/types/InputTypes";
import { Checkbox } from "@headlessui/react"; import { Checkbox, Field, Label } from "@headlessui/react";
import clsx from "clsx"; import clsx from "clsx";
export default function MattrixwvCheckbox({ export default function MattrixwvCheckbox({
id = crypto.randomUUID().replaceAll("-", ""),
className, className,
labelClassName, labelClassName,
name, name,
@@ -19,65 +18,68 @@ export default function MattrixwvCheckbox({
children children
}: Readonly<CheckboxProps>){ }: Readonly<CheckboxProps>){
return ( return (
<Checkbox <Field
id={id} className="flex flex-row items-center justify-center gap-x-2"
className={clsx(
"group",
"flex flex-row items-center justify-start gap-x-2",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
{
"cursor-pointer": !disabled,
"cursor-not-allowed": disabled
}
)}
name={name}
checked={checked}
defaultChecked={defaultChecked}
onChange={onChange}
value={value}
disabled={disabled}
aria-labelledby={`${id}Label`}
> >
{/* Checkbox */} <Checkbox
<div data-testid="mattrixwv-checkbox"
className={clsx( className={clsx(
className, "group",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
{ {
"border rounded": showBox "cursor-pointer": !disabled,
}, "cursor-not-allowed": disabled
{
"": size === "none",
"size-3": size === "xs",
"size-4": size === "sm",
"size-5": size === "md",
"size-6": size === "lg",
"size-7": size === "xl"
} }
)} )}
name={name}
checked={checked}
defaultChecked={defaultChecked}
onChange={onChange}
value={value}
disabled={disabled}
> >
<svg {/* Checkbox */}
viewBox="0 0 14 14" <div
fill="none" data-testid="mattrixwv-checkbox-graphic"
aria-hidden="true" className={clsx(
className,
{
"border rounded": showBox
},
{
"": size === "none",
"size-3": size === "xs",
"size-4": size === "sm",
"size-5": size === "md",
"size-6": size === "lg",
"size-7": size === "xl"
}
)}
> >
<path <svg
d="M3 8L6 11L11 3.5" viewBox="0 0 14 14"
strokeWidth={strokeWidth} fill="none"
strokeLinecap="round" aria-hidden="true"
strokeLinejoin="round" >
/> <path
</svg> d="M3 8L6 11L11 3.5"
</div> strokeWidth={strokeWidth}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</div>
</Checkbox>
{/* Label */} {/* Label */}
{ {
children && children &&
<span <Label
id={`${id}Label`} data-testid="mattrixwv-checkbox-label"
className={labelClassName} className={labelClassName}
> >
{children} {children}
</span> </Label>
} }
</Checkbox> </Field>
); );
} }

View File

@@ -27,12 +27,15 @@ export default function DragAndDropFileInput({
<label <label
className={clsx( className={clsx(
"flex flex-col items-center justify-center border-2 rounded-lg cursor-pointer", "flex flex-col items-center justify-center border-2 rounded-lg cursor-pointer",
//TODO: Make hover classes "data-drag:border-primary data-drag:text-primary",
className className
)} )}
onDragOver={(e) => e.preventDefault()} onDragOver={(e) => { e.preventDefault(); e.currentTarget.dataset.drag = "true"; }}
onDragLeave={(e) => { e.preventDefault(); delete e.currentTarget.dataset.drag; }}
onDrop={(e) => { onDrop={(e) => {
e.preventDefault(); e.preventDefault();
delete e.currentTarget.dataset.drag;
const currentFile = e.dataTransfer.files[0]; const currentFile = e.dataTransfer.files[0];
setFile(currentFile); setFile(currentFile);

View File

@@ -47,6 +47,8 @@ export { default as DragAndDropFileInput } from "./file/DragAndDropFileInput";
export { default as FileInput } from "./file/FileInput"; export { default as FileInput } from "./file/FileInput";
export { default as NumberInput } from "./number/NumberInput"; export { default as NumberInput } from "./number/NumberInput";
export { default as OptionInput } from "./text/OptionInput"; export { default as OptionInput } from "./text/OptionInput";
export { default as PasswordInput } from "./text/PasswordInput";
export { default as PhoneInput } from "./text/PhoneInput";
export { default as SelectInput } from "./text/SelectInput"; export { default as SelectInput } from "./text/SelectInput";
export { default as TextArea } from "./text/TextArea"; export { default as TextArea } from "./text/TextArea";
export { default as TextInput } from "./text/TextInput"; export { default as TextInput } from "./text/TextInput";

View File

@@ -0,0 +1,66 @@
import type { TextInputProps } from "$/types/InputTypes";
import clsx from "clsx";
import { useId } from "react";
export default function PasswordInput({
id,
className,
inputClassName,
labelClassName,
name,
maxLength,
spellCheck,
placeholder,
value,
onChange,
onKeyDown,
disabled
}: Readonly<TextInputProps>){
const componentId = useId();
const activeId = id ?? componentId;
return (
<div
className={clsx(
"flex flex-row items-center justify-center rounded-lg border-2 w-full",
className
)}
>
<div
className="relative flex flex-row items-center justify-center px-2 py-1 w-full"
>
<input
type="password"
id={activeId}
className={clsx(
"peer bg-transparent outline-none placeholder-transparent w-full",
inputClassName
)}
name={name}
placeholder={placeholder}
maxLength={maxLength}
value={value}
onChange={(e) => onChange?.(e.target.value)}
disabled={disabled}
spellCheck={spellCheck}
onKeyDown={onKeyDown}
/>
<label
className={clsx(
"absolute ml-2 -top-3 left-0 text-sm rounded-md px-1 select-none cursor-default",
"peer-placeholder-shown:top-0 peer-placeholder-shown:-left-1 peer-placeholder-shown:text-inherit peer-placeholder-shown:text-base peer-placeholder-shown:h-full peer-placeholder-shown:cursor-text peer-placeholder-shown:w-[98%]",
"peer-focus:-top-3 peer-focus:left-0 peer-focus:text-sm peer-focus:w-auto peer-focus:h-auto",
"flex items-center",
labelClassName
)}
style={{ transitionProperty: "top, left, font-size, line-height", transitionTimingFunction: "cubic-bezier(0.4 0, 0.2, 1)", transitionDuration: "250ms" }}
htmlFor={activeId}
>
{placeholder}
</label>
</div>
</div>
);
}

View File

@@ -0,0 +1,87 @@
import type { TextInputProps } from "$/types/InputTypes";
import clsx from "clsx";
import { useId } from "react";
export default function PhoneInput({
id,
className,
inputClassName,
labelClassName,
name,
maxLength,
spellCheck,
placeholder,
value,
onChange,
onKeyDown,
disabled
}: Readonly<TextInputProps>){
const componentId = useId();
const activeId = id ?? componentId;
//TODO: Figure out how to setup phone number
return (
<div
className={clsx(
"flex flex-row items-center justify-center rounded-lg border-2 w-full",
className
)}
>
<div
className="relative flex flex-row items-center justify-center px-2 py-1 w-full"
>
<input
type="text"
id={activeId}
className={clsx(
"peer bg-transparent outline-none placeholder-transparent w-full",
inputClassName
)}
name={name}
placeholder={placeholder}
maxLength={maxLength}
value={value}
onChange={(e) => onChange?.(e.target.value)}
onKeyDown={onKeyDown}
disabled={disabled}
spellCheck={spellCheck}
/>
<label
className={clsx(
"absolute ml-2 -top-3 left-0 text-sm rounded-md px-1 select-none cursor-default",
"peer-placeholder-shown:top-0 peer-placeholder-shown:-left-1 peer-placeholder-shown:text-inherit peer-placeholder-shown:text-base peer-placeholder-shown:h-full peer-placeholder-shown:cursor-text peer-placeholder-shown:w-[99%]",
"peer-focus:-top-3 peer-focus:left-0 peer-focus:text-sm peer-focus:w-auto peer-focus:h-auto",
"flex items-center",
labelClassName
)}
style={{ transitionProperty: "top, left, font-size, line-height", transitionTimingFunction: "cubic-bezier(0.4 0, 0.2, 1)", transitionDuration: "250ms" }}
htmlFor={activeId}
>
{placeholder}
</label>
</div>
</div>
);
}
/*
function formatPhoneNumber(phoneNumber: string): string {
const chars: string[] = [];
// Separate the string into individual characters
for(let cnt = 0;cnt < phoneNumber.length;++cnt){
chars.push(phoneNumber.charAt(cnt));
}
// Add _ for any chars that don't exist
for(let cnt = chars.length;cnt < 10;++cnt){
chars.push("_");
}
// Put the values into the correct format
return "(" + chars.slice(0, 3).join() + ") " + chars.slice(3, 6).join() + "-" + chars.slice(6).join();
}
*/

View File

@@ -16,6 +16,7 @@ export default function TextArea({
placeholder, placeholder,
value, value,
onChange, onChange,
onKeyDown,
disabled disabled
}: Readonly<TextAreaProps>){ }: Readonly<TextAreaProps>){
const componentId = useId(); const componentId = useId();
@@ -44,14 +45,15 @@ export default function TextArea({
rows={rows} rows={rows}
cols={cols} cols={cols}
value={value} value={value}
onChange={onChange} onChange={(e) => onChange?.(e.target.value)}
onKeyDown={onKeyDown}
disabled={disabled} disabled={disabled}
spellCheck={spellCheck} spellCheck={spellCheck}
/> />
<label <label
className={clsx( className={clsx(
"absolute ml-2 -top-3 left-0 text-sm rounded-md px-1 select-none cursor-default", "absolute ml-2 -top-3 left-0 text-sm rounded-md px-1 select-none cursor-default",
"peer-placeholder-shown:top-0 peer-placeholder-shown:-left-1 peer-placeholder-shown:text-inherit peer-placeholder-shown:text-base peer-placeholder-shown:bg-transparent peer-placeholder-shown:cursor-text peer-placeholder-shown:w-[99%]", "peer-placeholder-shown:top-0 peer-placeholder-shown:-left-1 peer-placeholder-shown:text-inherit peer-placeholder-shown:text-base peer-placeholder-shown:cursor-text peer-placeholder-shown:w-[98%]",
"peer-focus:-top-3 peer-focus:left-0 peer-focus:text-sm peer-focus:w-auto peer-focus:h-auto", "peer-focus:-top-3 peer-focus:left-0 peer-focus:text-sm peer-focus:w-auto peer-focus:h-auto",
"flex items-center", "flex items-center",
labelClassName labelClassName

View File

@@ -14,6 +14,7 @@ export default function TextInput({
placeholder, placeholder,
value, value,
onChange, onChange,
onKeyDown,
disabled disabled
}: Readonly<TextInputProps>){ }: Readonly<TextInputProps>){
const componentId = useId(); const componentId = useId();
@@ -41,14 +42,15 @@ export default function TextInput({
placeholder={placeholder} placeholder={placeholder}
maxLength={maxLength} maxLength={maxLength}
value={value} value={value}
onChange={onChange} onChange={(e) => onChange?.(e.target.value)}
disabled={disabled} disabled={disabled}
spellCheck={spellCheck} spellCheck={spellCheck}
onKeyDown={onKeyDown}
/> />
<label <label
className={clsx( className={clsx(
"absolute ml-2 -top-3 left-0 text-sm rounded-md px-1 select-none cursor-default", "absolute ml-2 -top-3 left-0 text-sm rounded-md px-1 select-none cursor-default",
"peer-placeholder-shown:top-0 peer-placeholder-shown:-left-1 peer-placeholder-shown:text-inherit peer-placeholder-shown:text-base peer-placeholder-shown:bg-transparent peer-placeholder-shown:h-full peer-placeholder-shown:cursor-text peer-placeholder-shown:w-[99%]", "peer-placeholder-shown:top-0 peer-placeholder-shown:-left-1 peer-placeholder-shown:text-inherit peer-placeholder-shown:text-base peer-placeholder-shown:h-full peer-placeholder-shown:cursor-text peer-placeholder-shown:w-[98%]",
"peer-focus:-top-3 peer-focus:left-0 peer-focus:text-sm peer-focus:w-auto peer-focus:h-auto", "peer-focus:-top-3 peer-focus:left-0 peer-focus:text-sm peer-focus:w-auto peer-focus:h-auto",
"flex items-center", "flex items-center",
labelClassName labelClassName

View File

@@ -1,4 +1,5 @@
import type { LoadingWifiProps } from "$/types/LoadingTypes"; import type { LoadingWifiProps } from "$/types/LoadingTypes";
import { useId } from "react";
export default function Wifi({ export default function Wifi({
@@ -9,9 +10,9 @@ export default function Wifi({
fadeDuration = 0.001, fadeDuration = 0.001,
stroke, stroke,
fill fill
}: LoadingWifiProps){ }: Readonly<LoadingWifiProps>){
//https://github.com/n3r4zzurr0/svg-spinners/blob/main/svg-smil/wifi.svg //https://github.com/n3r4zzurr0/svg-spinners/blob/main/svg-smil/wifi.svg
const id = crypto.randomUUID().replaceAll("-", ""); const id = useId();
return ( return (

View File

@@ -3,17 +3,14 @@ import { Dialog, DialogBackdrop, DialogPanel } from "@headlessui/react";
import clsx from "clsx"; import clsx from "clsx";
export default function Modal(props: ModalProps){ export default function Modal({
const { display,
display, onClose,
onClose, className,
className, backgroundType = "blur",
backgroundType = "blur", top,
top, children
children }: Readonly<ModalProps>){
} = props;
return ( return (
<Dialog <Dialog
open={display} open={display}

View File

@@ -2,19 +2,18 @@ import type { ModalBodyProps } from "$/types/ModalTypes";
import clsx from "clsx"; import clsx from "clsx";
export default function ModalBody(props: ModalBodyProps){ export default function ModalBody({
const { className,
className, children,
children ...props
} = props; }: Readonly<ModalBodyProps>){
return ( return (
<div <div
className={clsx( className={clsx(
"flex flex-col items-center justify-start h-full w-full overflow-scroll", "flex flex-col items-center justify-start h-full w-full overflow-scroll",
className className
)} )}
{...props}
> >
{children} {children}
</div> </div>

View File

@@ -2,19 +2,18 @@ import type { ModalFooterProps } from "$/types/ModalTypes";
import clsx from "clsx"; import clsx from "clsx";
export default function ModalFooter(props: ModalFooterProps){ export default function ModalFooter({
const { className,
className, children,
children ...props
} = props; }: Readonly<ModalFooterProps>){
return ( return (
<div <div
className={clsx( className={clsx(
"flex flex-row items-center justify-center w-full rounded-b-lg", "flex flex-row items-center justify-center w-full rounded-b-lg",
className className
)} )}
{...props}
> >
<div <div
className="flex flex-row items-center justify-center mx-8 my-3" className="flex flex-row items-center justify-center mx-8 my-3"

View File

@@ -1,23 +1,23 @@
import Button from "$/component/button/Button";
import type { ModalHeaderProps } from "$/types/ModalTypes"; import type { ModalHeaderProps } from "$/types/ModalTypes";
import { DialogTitle } from "@headlessui/react"; import { DialogTitle } from "@headlessui/react";
import clsx from "clsx"; import clsx from "clsx";
import { BsXLg } from "react-icons/bs"; import { BsXLg } from "react-icons/bs";
export default function ModalHeader(props: ModalHeaderProps){ export default function ModalHeader({
const { onClose,
onClose, className,
className, children,
children ...props
} = props; }: Readonly<ModalHeaderProps>){
return ( return (
<div <div
className={clsx( className={clsx(
"flex flex-row items-center justify-center w-full rounded-t-lg", "flex flex-row items-center justify-center w-full rounded-t-lg",
className className
)} )}
{...props}
> >
<DialogTitle <DialogTitle
as="div" as="div"
@@ -27,14 +27,16 @@ export default function ModalHeader(props: ModalHeaderProps){
</DialogTitle> </DialogTitle>
{ {
onClose && onClose &&
<div <Button
className="absolute top-1 right-1 cursor-pointer" className="absolute top-1 right-1 cursor-pointer"
onClick={onClose} onClick={onClose}
size="sm"
variant="icon"
> >
<BsXLg <BsXLg
size={20} size={20}
/> />
</div> </Button>
} }
</div> </div>
); );

View File

@@ -1,4 +1,4 @@
import { useTheme } from "$/providers/theme/ThemeProvider"; import { useTheme } from "$/provider/theme/ThemeProvider";
import { BsLightbulb, BsLightbulbFill } from "react-icons/bs"; import { BsLightbulb, BsLightbulbFill } from "react-icons/bs";
@@ -8,7 +8,7 @@ export default function DarkModeSwitch(){
const updateTheme = () => { const updateTheme = () => {
if(theme === "system"){ if(theme === "system"){
if(window.document.documentElement.classList.contains("dark")){ if(globalThis.document.documentElement.classList.contains("dark")){
setTheme("light"); setTheme("light");
} }
else{ else{

View File

@@ -2,13 +2,11 @@ import type { NavBarProps } from "$/types/NavTypes";
import clsx from "clsx"; import clsx from "clsx";
export default function NavBar(props: NavBarProps){ export default function NavBar({
const { className,
className, children,
children ...props
} = props; }: Readonly<NavBarProps>){
return ( return (
<nav <nav
className={clsx( className={clsx(
@@ -16,6 +14,7 @@ export default function NavBar(props: NavBarProps){
"fixed top-0 left-0 w-full z-10", "fixed top-0 left-0 w-full z-10",
"flex flex-row flex-nowrap items-center justify-center" "flex flex-row flex-nowrap items-center justify-center"
)} )}
{...props}
> >
{children} {children}
</nav> </nav>

View File

@@ -3,14 +3,11 @@ import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react";
import clsx from "clsx"; import clsx from "clsx";
import { RiArrowRightSLine } from "react-icons/ri"; import { RiArrowRightSLine } from "react-icons/ri";
export default function PopoverMenu(props: PopoverMenuProps){ export default function PopoverMenu({
const { buttonContent,
buttonContent, anchor,
anchor, children
children }: Readonly<PopoverMenuProps>){
} = props;
return ( return (
<Popover> <Popover>
<PopoverButton <PopoverButton

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function DangerPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-danger-pill"
className={clsx(
className,
"bg-danger text-white"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function DarkPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-dark-pill"
className={clsx(
className,
"bg-dark text-white"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function InfoPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-info-pill"
className={clsx(
className,
"bg-info text-black"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function LightPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-light-pill"
className={clsx(
className,
"bg-light text-black"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function MoltenPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-molten-pill"
className={clsx(
className,
"bg-molten text-black"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,26 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
export default function Pill({
className,
rounding = "full",
...props
}: Readonly<PillProps>){
return (
<div
data-testid="mattrixwv-pill"
className={clsx(
className,
"px-2 text-sm whitespace-nowrap",
{
"rounded-sm": rounding === "sm",
"rounded": rounding === "md",
"rounded-lg": rounding === "lg",
"rounded-full": rounding === "full"
}
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function PrimaryPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-primary-pill"
className={clsx(
className,
"bg-primary text-white"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function SecondaryPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-secondary-pill"
className={clsx(
className,
"bg-secondary text-white"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function SuccessPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-success-pill"
className={clsx(
className,
"bg-success text-black"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function TertiaryPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-tertiary-pill"
className={clsx(
className,
"bg-tertiary text-white"
)}
{...props}
/>
);
}

View File

@@ -0,0 +1,20 @@
import type { PillProps } from "$/types/PillTypes";
import clsx from "clsx";
import Pill from "./Pill";
export default function WarningPill({
className,
...props
}: Readonly<PillProps>){
return (
<Pill
data-testid="mattrixwv-warning-pill"
className={clsx(
className,
"bg-warning text-black"
)}
{...props}
/>
);
}

View File

@@ -3,12 +3,9 @@ import { Tab } from "@headlessui/react";
import clsx from "clsx"; import clsx from "clsx";
export default function MattrixwvTab(props: MattrixwvTabProps){ export default function MattrixwvTab({
const { children
children }: Readonly<MattrixwvTabProps>){
} = props;
return ( return (
<Tab <Tab
className={clsx( className={clsx(

View File

@@ -7,13 +7,10 @@ import MattrixwvTabPanel from "./MattrixwvTabPanel";
import MattrixwvTabPanels from "./MattrixwvTabPanels"; import MattrixwvTabPanels from "./MattrixwvTabPanels";
export default function MattrixwvTabGroup(props: MattrixwvTabGroupProps){ export default function MattrixwvTabGroup({
const { tabs,
tabs, className
className }: Readonly<MattrixwvTabGroupProps>){
} = props;
return ( return (
<TabGroup <TabGroup
className={clsx( className={clsx(
@@ -24,9 +21,7 @@ export default function MattrixwvTabGroup(props: MattrixwvTabGroupProps){
<MattrixwvTabList> <MattrixwvTabList>
{ {
tabs.map((tab, index) => ( tabs.map((tab, index) => (
<MattrixwvTab <MattrixwvTab key={index}>
key={index}
>
{tab.tab} {tab.tab}
</MattrixwvTab> </MattrixwvTab>
)) ))
@@ -35,9 +30,7 @@ export default function MattrixwvTabGroup(props: MattrixwvTabGroupProps){
<MattrixwvTabPanels> <MattrixwvTabPanels>
{ {
tabs.map((tab, index) => ( tabs.map((tab, index) => (
<MattrixwvTabPanel <MattrixwvTabPanel key={index}>
key={index}
>
{tab.content} {tab.content}
</MattrixwvTabPanel> </MattrixwvTabPanel>
)) ))

View File

@@ -2,16 +2,11 @@ import type { MattrixwvTabListProps } from "$/types/TabTypes";
import { TabList } from "@headlessui/react"; import { TabList } from "@headlessui/react";
export default function MattrixwvTabList(props: MattrixwvTabListProps){ export default function MattrixwvTabList({
const { children
children }: Readonly<MattrixwvTabListProps>){
} = props;
return ( return (
<TabList <TabList className="flex flex-row items-center justify-start w-full border-b">
className="flex flex-row items-center justify-start w-full border-b"
>
{children} {children}
</TabList> </TabList>
); );

View File

@@ -2,16 +2,11 @@ import type { MattrixwvTabPanelProps } from "$/types/TabTypes";
import { TabPanel } from "@headlessui/react"; import { TabPanel } from "@headlessui/react";
export default function MattrixwvTabPanel(props: MattrixwvTabPanelProps){ export default function MattrixwvTabPanel({
const { children
children }: Readonly<MattrixwvTabPanelProps>){
} = props;
return ( return (
<TabPanel <TabPanel className="flex flex-row items-start justify-center w-full h-full">
className="flex flex-row items-start justify-center w-full h-full"
>
{children} {children}
</TabPanel> </TabPanel>
); );

View File

@@ -2,16 +2,11 @@ import type { MattrixwvTabPanelsProps } from "$/types/TabTypes";
import { TabPanels } from "@headlessui/react"; import { TabPanels } from "@headlessui/react";
export default function MattrixwvTabPanels(props: MattrixwvTabPanelsProps){ export default function MattrixwvTabPanels({
const { children
children }: Readonly<MattrixwvTabPanelsProps>){
} = props;
return ( return (
<TabPanels <TabPanels className="flex flex-row items-start justify-center w-full h-full overflow-scroll">
className="flex flex-row items-start justify-center w-full h-full overflow-scroll"
>
{children} {children}
</TabPanels> </TabPanels>
); );

View File

@@ -6,7 +6,7 @@ import clsx from "clsx";
export default function Toaster({ export default function Toaster({
toast, toast,
className className
}: ToasterProps){ }: Readonly<ToasterProps>){
return ( return (
<Transition <Transition
show={toast.length > 1 || (toast.length === 1 && toast[0].hideTime > new Date())} show={toast.length > 1 || (toast.length === 1 && toast[0].hideTime > new Date())}

View File

@@ -1,3 +1,2 @@
export { default as ToasterProvider, useToaster } from "$/providers/toaster/ToasterProvider";
export { default as Toaster } from "./Toaster"; export { default as Toaster } from "./Toaster";

View File

@@ -1,5 +1,6 @@
@import "tailwindcss"; @import "tailwindcss";
@theme { @theme {
/* Universal */ /* Universal */
--color-neutral-light: oklch(92.8% 0.006 264.531); /* gray-200 */ --color-neutral-light: oklch(92.8% 0.006 264.531); /* gray-200 */

View File

@@ -7,5 +7,8 @@ export * from "$/component/nav";
export * from "$/component/progress"; export * from "$/component/progress";
export * from "$/component/tab"; export * from "$/component/tab";
export * from "$/component/toaster"; export * from "$/component/toaster";
export * from "$/providers/theme/theme"; export * from "$/provider/axios";
export * from "$/provider/theme";
export * from "$/provider/toaster";
export * from "$/provider/token";

70
lib/layout.css Normal file
View File

@@ -0,0 +1,70 @@
@import "tailwindcss";
body {
margin-inline: auto;
min-width: 320px;
height: 100vh;
text-align: center;
}
#root {
padding-top: 4rem;
padding-bottom: 4rem;
padding-inline: 1rem;
height: 100%;
width: 100%;
overflow: auto;
}
h1 {
font-size: 4rem;
}
h2 {
font-size: 3rem;
}
a.active {
color: oklch(70.7% 0.165 254.624); /* blue-400 */
}
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
flex-wrap: nowrap;
margin-inline: auto;
padding-inline: 1rem;
}
footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
flex-wrap: nowrap;
margin-inline: auto;
padding-inline: 1rem;
}

View File

@@ -0,0 +1,95 @@
import type { AxiosError, AxiosInstance } from "axios";
import axios from "axios";
import { createContext, useContext, useMemo } from "react";
import { useToken } from "../token";
export interface AxiosState {
publicApi: AxiosInstance;
authorizedApi: AxiosInstance;
}
const initialState: AxiosState = {
publicApi: {} as AxiosInstance,
authorizedApi: {} as AxiosInstance
}
const AxiosContext = createContext<AxiosState>(initialState);
export default function AxiosProvider({
apiUrl,
children
}: Readonly<{
apiUrl: string;
children: React.ReactNode;
}>){
const { getToken } = useToken();
const publicApi = useMemo(() => {
const api = axios.create({
baseURL: apiUrl,
withCredentials: true
});
return api;
}, [apiUrl]);
const authorizedApi = useMemo(() => {
const api = axios.create({
baseURL: apiUrl,
withCredentials: true
});
api.interceptors.request.use(async (config) => {
try{
const token = await getToken();
if(token){
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}
catch(error){
return Promise.reject(error as Error);
}
});
api.interceptors.response.use(r => r, async (error: AxiosError) => {
const original = error.config;
if(!original){
return Promise.reject(error);
}
if(error.response?.status === 401 && !original._retry){
original._retry = true;
try{
const newToken = await getToken();
original.headers.Authorization = `Bearer ${newToken}`;
return api(original);
}
catch(refreshError){
return Promise.reject(refreshError as Error);
}
}
});
return api;
}, [apiUrl, getToken]);
const value = useMemo(() => ({
publicApi,
authorizedApi
}), [authorizedApi, publicApi]);
return (
<AxiosContext.Provider value={value}>
{children}
</AxiosContext.Provider>
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useAxios(){
const context = useContext(AxiosContext);
if(!context){
throw new Error("useAxios must be called inside an AxiosProvider");
}
return context;
}

8
lib/provider/axios/axios.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import "axios";
declare module "axios" {
interface InternalAxiosRequestConfig {
_retry?: boolean;
}
}

View File

@@ -0,0 +1 @@
export { default as AxiosProvider, useAxios } from "./AxiosProvider";

View File

@@ -10,7 +10,7 @@ const themeInitialState: ThemeProviderState = {
const ThemeProviderContext = createContext<ThemeProviderState>(themeInitialState); const ThemeProviderContext = createContext<ThemeProviderState>(themeInitialState);
export default function ThemeProvider(props: ThemeProviderProps){ export default function ThemeProvider(props: Readonly<ThemeProviderProps>){
const { const {
children, children,
defaultTheme = "system", defaultTheme = "system",
@@ -20,12 +20,12 @@ export default function ThemeProvider(props: ThemeProviderProps){
const [ theme, setTheme ] = useState<Theme>((localStorage.getItem(storageKey) as Theme) || defaultTheme); const [ theme, setTheme ] = useState<Theme>((localStorage.getItem(storageKey) as Theme) || defaultTheme);
useEffect(() => { useEffect(() => {
const root = window.document.documentElement; const root = globalThis.document.documentElement;
root.classList.remove("light", "dark"); root.classList.remove("light", "dark");
if(theme === "system"){ if(theme === "system"){
const systemTheme = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark"; const systemTheme = globalThis.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
root.classList.add(systemTheme); root.classList.add(systemTheme);
} }

View File

@@ -0,0 +1 @@
export { default as ThemeProvider, useTheme } from "./ThemeProvider";

View File

@@ -19,7 +19,7 @@ const ToasterProviderContext = createContext<ToastProviderState>(toastInitialSta
export default function ToasterProvider({ export default function ToasterProvider({
className, className,
children children
}: ToastProviderProps){ }: Readonly<ToastProviderProps>){
const [ toast, setToast ] = useState<Toast[]>([]); const [ toast, setToast ] = useState<Toast[]>([]);

View File

@@ -0,0 +1 @@
export { default as ToasterProvider, useToaster } from "./ToasterProvider";

View File

@@ -0,0 +1,77 @@
import { createContext, useCallback, useContext, useMemo, useRef } from "react";
import { defaultTokenData, fetchToken, parseToken, type TokenData } from "./TokenUtils";
export interface TokenState {
getToken: () => Promise<string | null | undefined>;
}
const initialState: TokenState = {
getToken: () => new Promise(() => {})
}
const TokenContext = createContext<TokenState>(initialState);
export default function TokenProvider({
apiUrl,
children
}: Readonly<{
apiUrl: string;
children: React.ReactNode;
}>){
const tokenRef = useRef<TokenData>(defaultTokenData);
const refreshPromise = useRef<Promise<string | null | undefined>>(null);
const getToken = useCallback(async () => {
if(refreshPromise.current){
return refreshPromise.current;
}
const { accessToken, expires } = tokenRef.current;
const isExpired = Date.now() > (expires - 5000); //Give a 5 second buffer
if(!accessToken || isExpired){
refreshPromise.current = (async () => {
try {
const rawToken = (await fetchToken(apiUrl)).token;
const parsedToken = parseToken(rawToken);
tokenRef.current = parsedToken;
return rawToken;
}
catch(error){
tokenRef.current = defaultTokenData;
throw error;
}
finally {
refreshPromise.current = null;
}
})();
return refreshPromise.current;
}
return accessToken;
}, [apiUrl]);
const value: TokenState = useMemo(() => ({
getToken
}), [getToken]);
return (
<TokenContext.Provider value={value}>
{children}
</TokenContext.Provider>
);
}
// eslint-disable-next-line react-refresh/only-export-components
export function useToken(){
const context = useContext(TokenContext);
if(!context){
throw new Error("useToken must be called inside a TokenProvider");
}
return context;
}

View File

@@ -0,0 +1,52 @@
interface TokenResponse {
token: string | null | undefined;
}
interface TokenBody {
token: string;
iat: number;
exp: number;
}
export interface LoginBody {
login: string;
password: string;
}
export interface TokenData {
accessToken: string | null | undefined;
issued: number;
expires: number;
}
export const defaultTokenData: TokenData = {
accessToken: "",
issued: 0,
expires: 0
}
export async function fetchToken(apiUrl: string){
const res = await fetch(`${apiUrl}/auth/refresh`, { method: "POST", credentials: "include" });
return await res.json() as TokenResponse;
}
export function parseToken(rawToken: string | null | undefined): TokenData {
if(!rawToken){
return defaultTokenData;
}
const payloads = rawToken.split(".");
if(payloads.length !== 3){
return defaultTokenData;
}
const payload = payloads[1];
const tokenBody = JSON.parse(atob(payload)) as TokenBody;
return ({
accessToken: rawToken,
issued: tokenBody.iat * 1000,
expires: tokenBody.exp * 1000
});
}

View File

@@ -0,0 +1 @@
export { default as TokenProvider, useToken } from "./TokenProvider";

View File

@@ -1,2 +0,0 @@
export { default as ThemeProvider, useTheme } from "$/providers/theme/ThemeProvider";

37
lib/theme.css Normal file
View File

@@ -0,0 +1,37 @@
@import "tailwindcss";
@theme {
--light-text-color: #213547;
--light-bg-color: #FFFFFF;
--dark-text-color: #FFFFFFDE;
--dark-bg-color: #242424;
}
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: var(--text-color);
background-color: var(--bg-color);
}
:root.light {
--text-color: var(--light-text-color);
--bg-color: var(--light-bg-color);
}
:root.dark {
--text-color: var(--dark-text-color);
--bg-color: var(--dark-bg-color);
}

View File

@@ -1,4 +1,4 @@
import type { ButtonHTMLAttributes } from "react"; import type { ComponentProps } from "react";
export type ButtonRounding = "none" | "sm" | "md" | "lg" | "full"; export type ButtonRounding = "none" | "sm" | "md" | "lg" | "full";
@@ -7,7 +7,7 @@ export type ButtonSize = "xs" | "sm" | "md" | "lg" | "xl";
export type ButtonVariant = "standard" | "outline" | "ghost" | "outline-ghost" | "icon"; export type ButtonVariant = "standard" | "outline" | "ghost" | "outline-ghost" | "icon";
export interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "size" | "type"> { export interface ButtonProps extends Omit<ComponentProps<"button">, "size" | "type"> {
type?: "button" | "submit" | "reset"; type?: "button" | "submit" | "reset";
rounding?: ButtonRounding; rounding?: ButtonRounding;
shape?: ButtonShape; shape?: ButtonShape;

View File

@@ -1,5 +1,5 @@
import type React from "react"; import type React from "react";
import type { ChangeEventHandler, InputHTMLAttributes } from "react"; import type { ComponentProps, KeyboardEventHandler } from "react";
export interface TextInputProps { export interface TextInputProps {
@@ -11,8 +11,9 @@ export interface TextInputProps {
maxLength?: number; maxLength?: number;
spellCheck?: boolean; spellCheck?: boolean;
placeholder?: string; placeholder?: string;
value?: string; value: string;
onChange?: ChangeEventHandler<HTMLInputElement>; onChange?: (newValue: string) => void;
onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
disabled?: boolean; disabled?: boolean;
} }
@@ -25,11 +26,12 @@ export interface TextAreaProps {
maxLength?: number; maxLength?: number;
spellCheck?: boolean; spellCheck?: boolean;
placeholder?: string; placeholder?: string;
value?: string; value: string;
disabled?: boolean;
rows?: number; rows?: number;
cols?: number; cols?: number;
onChange?: ChangeEventHandler<HTMLTextAreaElement>; onChange?: (newValue: string) => void;
onKeyDown?: KeyboardEventHandler<HTMLTextAreaElement>;
disabled?: boolean;
} }
export interface SelectInputProps { export interface SelectInputProps {
@@ -128,7 +130,6 @@ export interface FileInputProps {
export type CheckboxSize = "none" | "xs" | "sm" | "md" | "lg" | "xl"; export type CheckboxSize = "none" | "xs" | "sm" | "md" | "lg" | "xl";
export interface CheckboxProps { export interface CheckboxProps {
id?: string;
className?: string; className?: string;
labelClassName?: string; labelClassName?: string;
name?: string; name?: string;
@@ -167,7 +168,7 @@ export interface RadioListProps {
} }
export interface DateInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "step">{ export interface DateInputProps extends Omit<ComponentProps<"input">, "value" | "onChange" | "step">{
step?: number; step?: number;
value: Date | undefined; value: Date | undefined;
onChange: (newValue: Date | undefined) => void; onChange: (newValue: Date | undefined) => void;

View File

@@ -1,7 +1,7 @@
import type { HTMLProps } from "react"; import type { ComponentProps } from "react";
export interface MessageBlockProps extends HTMLProps<HTMLDivElement> { export interface MessageBlockProps extends ComponentProps<"div"> {
outline?: "none" | "sm" | "md" | "lg"; outline?: "none" | "sm" | "md" | "lg";
rounded?: "none" | "xs" | "sm" | "md" | "lg" | "xl"; rounded?: "none" | "xs" | "sm" | "md" | "lg" | "xl";
} }

View File

@@ -1,18 +1,21 @@
import type { ComponentProps } from "react";
export type ModalBackgroundType = "darken" | "lighten" | "blur" | "darken-blur" | "lighten-blur" | "darken-blur-radial" | "lighten-blur-radial" | "transparent" | "none"; export type ModalBackgroundType = "darken" | "lighten" | "blur" | "darken-blur" | "lighten-blur" | "darken-blur-radial" | "lighten-blur-radial" | "transparent" | "none";
export interface ModalHeaderProps { export interface ModalHeaderProps extends ComponentProps<"div"> {
onClose?: () => void; onClose?: () => void;
className?: string; className?: string;
children: React.ReactNode; children: React.ReactNode;
} }
export interface ModalFooterProps { export interface ModalFooterProps extends ComponentProps<"div"> {
className?: string; className?: string;
children: React.ReactNode; children: React.ReactNode;
} }
export interface ModalBodyProps { export interface ModalBodyProps extends ComponentProps<"div"> {
className?: string; className?: string;
children: React.ReactNode; children: React.ReactNode;
} }

View File

@@ -1,3 +1,6 @@
import type { ComponentProps } from "react";
export type Align = "start" | "end"; export type Align = "start" | "end";
export type Placement = "top" | "bottom" | "left" | "right"; export type Placement = "top" | "bottom" | "left" | "right";
export type AnchorTo = `${Placement}` | `${Placement} ${Align}`; export type AnchorTo = `${Placement}` | `${Placement} ${Align}`;
@@ -9,7 +12,7 @@ export interface PopoverMenuProps {
children: React.ReactNode; children: React.ReactNode;
} }
export interface NavBarProps { export interface NavBarProps extends ComponentProps<"nav"> {
className?: string; className?: string;
children: React.ReactNode; children: React.ReactNode;
} }

9
lib/types/PillTypes.ts Normal file
View File

@@ -0,0 +1,9 @@
import type { ComponentProps } from "react";
export type PillRounding = "none" | "sm" | "md" | "lg" | "full";
export interface PillProps extends ComponentProps<"div"> {
rounding?: PillRounding;
}

129
package-lock.json generated
View File

@@ -1,12 +1,17 @@
{ {
"name": "mattrixwv-components", "name": "mattrixwv-components",
"version": "0.0.8", "version": "0.0.9",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "mattrixwv-components", "name": "mattrixwv-components",
"version": "0.0.8", "version": "0.0.9",
"dependencies": {
"axios": "^1.13.6",
"clsx": "^2.1.1",
"react-icons": "^5.5.0"
},
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.39.2", "@eslint/js": "^9.39.2",
"@tailwindcss/vite": "^4.1.18", "@tailwindcss/vite": "^4.1.18",
@@ -39,10 +44,8 @@
}, },
"peerDependencies": { "peerDependencies": {
"@headlessui/react": "^2.2.9", "@headlessui/react": "^2.2.9",
"clsx": "^2.1.1",
"react": "^19.2.3", "react": "^19.2.3",
"react-dom": "^19.2.3", "react-dom": "^19.2.3"
"react-icons": "^5.5.0"
} }
}, },
"node_modules/@acemir/cssom": { "node_modules/@acemir/cssom": {
@@ -4076,6 +4079,12 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/available-typed-arrays": { "node_modules/available-typed-arrays": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -4092,6 +4101,17 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/axios": {
"version": "1.13.6",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz",
"integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/babel-dead-code-elimination": { "node_modules/babel-dead-code-elimination": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.10.tgz", "resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.10.tgz",
@@ -4215,7 +4235,6 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -4367,6 +4386,18 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/compare-versions": { "node_modules/compare-versions": {
"version": "6.1.1", "version": "6.1.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz",
@@ -4603,6 +4634,15 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dequal": { "node_modules/dequal": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -4658,7 +4698,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.1", "call-bind-apply-helpers": "^1.0.1",
@@ -4776,7 +4815,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -4786,7 +4824,6 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -4831,7 +4868,6 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0" "es-errors": "^1.3.0"
@@ -4844,7 +4880,6 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -5329,6 +5364,26 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-each": { "node_modules/for-each": {
"version": "0.3.5", "version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
@@ -5345,6 +5400,22 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/form-data": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "11.3.0", "version": "11.3.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
@@ -5379,7 +5450,6 @@
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
@@ -5430,7 +5500,6 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"call-bind-apply-helpers": "^1.0.2", "call-bind-apply-helpers": "^1.0.2",
@@ -5455,7 +5524,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"dunder-proto": "^1.0.1", "dunder-proto": "^1.0.1",
@@ -5553,7 +5621,6 @@
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -5625,7 +5692,6 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -5638,7 +5704,6 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"has-symbols": "^1.0.3" "has-symbols": "^1.0.3"
@@ -5654,7 +5719,6 @@
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"function-bind": "^1.1.2" "function-bind": "^1.1.2"
@@ -6912,7 +6976,6 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@@ -6925,6 +6988,27 @@
"dev": true, "dev": true,
"license": "CC0-1.0" "license": "CC0-1.0"
}, },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/min-indent": { "node_modules/min-indent": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@@ -7464,6 +7548,12 @@
"react-is": "^16.13.1" "react-is": "^16.13.1"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -7519,7 +7609,6 @@
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
"license": "MIT", "license": "MIT",
"peer": true,
"peerDependencies": { "peerDependencies": {
"react": "*" "react": "*"
} }

View File

@@ -1,7 +1,7 @@
{ {
"name": "mattrixwv-components", "name": "mattrixwv-components",
"private": false, "private": false,
"version": "0.0.8", "version": "0.0.9",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
@@ -18,13 +18,16 @@
"versionMinor": "npm version minor", "versionMinor": "npm version minor",
"versionMajor": "npm version major" "versionMajor": "npm version major"
}, },
"peerDependencies": { "dependencies": {
"@headlessui/react": "^2.2.9",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react-icons": "^5.5.0" "react-icons": "^5.5.0"
}, },
"peerDependencies": {
"axios": "^1.13.6",
"@headlessui/react": "^2.2.9",
"react": "^19.2.3",
"react-dom": "^19.2.3"
},
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.39.2", "@eslint/js": "^9.39.2",
"@tailwindcss/vite": "^4.1.18", "@tailwindcss/vite": "^4.1.18",
@@ -65,9 +68,8 @@
"author": "Mattrixwv", "author": "Mattrixwv",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://bitbucket.org/Mattrixwv/mattrixwvReactComponents.git" "url": "git+https://git.mattrixwv.com/BaseLibraries/MattrixwvReactComponents.git"
}, },
"main": "./dist/mattrixwv-components.cjs",
"module": "./dist/mattrixwv-components.js", "module": "./dist/mattrixwv-components.js",
"types": "./dist/mattrixwv-components.d.ts", "types": "./dist/mattrixwv-components.d.ts",
"exports": { "exports": {
@@ -107,9 +109,21 @@
"types": "./dist/tab.d.ts", "types": "./dist/tab.d.ts",
"import": "./dist/tab.js" "import": "./dist/tab.js"
}, },
"./axios": {
"types": "./dist/axios.d.ts",
"import": "./dist/axios.js"
},
"./theme": {
"types": "./dist/theme.d.ts",
"import": "./dist/theme.js"
},
"./toaster": { "./toaster": {
"types": "./dist/toaster.d.ts", "types": "./dist/toaster.d.ts",
"import": "./dist/toaster.js" "import": "./dist/toaster.js"
},
"./token": {
"types": "./dist/token.d.ts",
"import": "./dist/token.js"
} }
}, },
"files": [ "files": [

View File

@@ -1,85 +1,16 @@
@import "tailwindcss"; @import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *)); @custom-variant dark (&:where(.dark, .dark *));
@import "../lib/styles.css"; @import "../lib/components.css";
@import "../lib/theme.css";
@theme { @theme {
--color-neutral-825: oklch(0.253 0 0); --color-neutral-825: oklch(0.253 0 0);
--color-neutral-850: oklch(0.237 0 0); --color-neutral-850: oklch(0.237 0 0);
--light-text-color: #213547;
--light-bg-color: #FFFFFF;
--dark-text-color: #FFFFFFDE;
--dark-bg-color: #242424;
} }
:root.light {
--text-color: var(--light-text-color);
--bg-color: var(--light-bg-color);
}
:root.dark {
--text-color: var(--dark-text-color);
--bg-color: var(--dark-bg-color);
}
input::-webkit-calendar-picker-indicator { input::-webkit-calendar-picker-indicator {
cursor: pointer; cursor: pointer;
} }
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: var(--text-color);
background-color: var(--bg-color);
}
#root {
padding-top: 4rem;
padding-inline: 1rem;
height: 100%;
width: 100%;
}
body {
margin-inline: auto;
min-width: 320px;
height: 100vh;
text-align: center;
}
a.active {
color: var(--color-blue-400);
}
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-btween;
align-items: center;
margin-inline: auto;
padding-inline: 1rem;
}
@keyframes spinnerAnimate {
100% {
transform: rotate(360deg);
}
}

View File

@@ -1,5 +1,5 @@
import ThemeProvider from "$/providers/theme/ThemeProvider"; import ThemeProvider from "$/provider/theme/ThemeProvider";
import ToasterProvider from "$/providers/toaster/ToasterProvider"; import ToasterProvider from "$/provider/toaster/ToasterProvider";
import { RouterProvider, createRouter } from "@tanstack/react-router"; import { RouterProvider, createRouter } from "@tanstack/react-router";
import { StrictMode } from "react"; import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
@@ -18,7 +18,7 @@ declare module "@tanstack/react-router" {
createRoot(document.getElementById('root')!).render( createRoot(document.getElementById('root')!).render(
<StrictMode> <StrictMode>
<ThemeProvider defaultTheme="dark"> <ThemeProvider defaultTheme="dark">
<ToasterProvider className="bg-zinc-700 text-white px-4 py-2 min-w-32 max-w-128 rounded-lg gap-y-4"> <ToasterProvider className="bg-zinc-700 text-white px-4 py-2 min-w-32 max-w-lg rounded-lg gap-y-4">
<RouterProvider router={router}/> <RouterProvider router={router}/>
</ToasterProvider> </ToasterProvider>
</ThemeProvider> </ThemeProvider>

View File

@@ -12,6 +12,7 @@ import { Route as rootRouteImport } from './routes/__root'
import { Route as IndexRouteImport } from './routes/index' import { Route as IndexRouteImport } from './routes/index'
import { Route as TabIndexRouteImport } from './routes/tab/index' import { Route as TabIndexRouteImport } from './routes/tab/index'
import { Route as ProgressIndexRouteImport } from './routes/progress/index' import { Route as ProgressIndexRouteImport } from './routes/progress/index'
import { Route as PillIndexRouteImport } from './routes/pill/index'
import { Route as ModalIndexRouteImport } from './routes/modal/index' import { Route as ModalIndexRouteImport } from './routes/modal/index'
import { Route as MessageIndexRouteImport } from './routes/message/index' import { Route as MessageIndexRouteImport } from './routes/message/index'
import { Route as LoadingIndexRouteImport } from './routes/loading/index' import { Route as LoadingIndexRouteImport } from './routes/loading/index'
@@ -33,6 +34,11 @@ const ProgressIndexRoute = ProgressIndexRouteImport.update({
path: '/progress/', path: '/progress/',
getParentRoute: () => rootRouteImport, getParentRoute: () => rootRouteImport,
} as any) } as any)
const PillIndexRoute = PillIndexRouteImport.update({
id: '/pill/',
path: '/pill/',
getParentRoute: () => rootRouteImport,
} as any)
const ModalIndexRoute = ModalIndexRouteImport.update({ const ModalIndexRoute = ModalIndexRouteImport.update({
id: '/modal/', id: '/modal/',
path: '/modal/', path: '/modal/',
@@ -66,6 +72,7 @@ export interface FileRoutesByFullPath {
'/loading': typeof LoadingIndexRoute '/loading': typeof LoadingIndexRoute
'/message': typeof MessageIndexRoute '/message': typeof MessageIndexRoute
'/modal': typeof ModalIndexRoute '/modal': typeof ModalIndexRoute
'/pill': typeof PillIndexRoute
'/progress': typeof ProgressIndexRoute '/progress': typeof ProgressIndexRoute
'/tab': typeof TabIndexRoute '/tab': typeof TabIndexRoute
} }
@@ -76,6 +83,7 @@ export interface FileRoutesByTo {
'/loading': typeof LoadingIndexRoute '/loading': typeof LoadingIndexRoute
'/message': typeof MessageIndexRoute '/message': typeof MessageIndexRoute
'/modal': typeof ModalIndexRoute '/modal': typeof ModalIndexRoute
'/pill': typeof PillIndexRoute
'/progress': typeof ProgressIndexRoute '/progress': typeof ProgressIndexRoute
'/tab': typeof TabIndexRoute '/tab': typeof TabIndexRoute
} }
@@ -87,6 +95,7 @@ export interface FileRoutesById {
'/loading/': typeof LoadingIndexRoute '/loading/': typeof LoadingIndexRoute
'/message/': typeof MessageIndexRoute '/message/': typeof MessageIndexRoute
'/modal/': typeof ModalIndexRoute '/modal/': typeof ModalIndexRoute
'/pill/': typeof PillIndexRoute
'/progress/': typeof ProgressIndexRoute '/progress/': typeof ProgressIndexRoute
'/tab/': typeof TabIndexRoute '/tab/': typeof TabIndexRoute
} }
@@ -99,6 +108,7 @@ export interface FileRouteTypes {
| '/loading' | '/loading'
| '/message' | '/message'
| '/modal' | '/modal'
| '/pill'
| '/progress' | '/progress'
| '/tab' | '/tab'
fileRoutesByTo: FileRoutesByTo fileRoutesByTo: FileRoutesByTo
@@ -109,6 +119,7 @@ export interface FileRouteTypes {
| '/loading' | '/loading'
| '/message' | '/message'
| '/modal' | '/modal'
| '/pill'
| '/progress' | '/progress'
| '/tab' | '/tab'
id: id:
@@ -119,6 +130,7 @@ export interface FileRouteTypes {
| '/loading/' | '/loading/'
| '/message/' | '/message/'
| '/modal/' | '/modal/'
| '/pill/'
| '/progress/' | '/progress/'
| '/tab/' | '/tab/'
fileRoutesById: FileRoutesById fileRoutesById: FileRoutesById
@@ -130,6 +142,7 @@ export interface RootRouteChildren {
LoadingIndexRoute: typeof LoadingIndexRoute LoadingIndexRoute: typeof LoadingIndexRoute
MessageIndexRoute: typeof MessageIndexRoute MessageIndexRoute: typeof MessageIndexRoute
ModalIndexRoute: typeof ModalIndexRoute ModalIndexRoute: typeof ModalIndexRoute
PillIndexRoute: typeof PillIndexRoute
ProgressIndexRoute: typeof ProgressIndexRoute ProgressIndexRoute: typeof ProgressIndexRoute
TabIndexRoute: typeof TabIndexRoute TabIndexRoute: typeof TabIndexRoute
} }
@@ -157,6 +170,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ProgressIndexRouteImport preLoaderRoute: typeof ProgressIndexRouteImport
parentRoute: typeof rootRouteImport parentRoute: typeof rootRouteImport
} }
'/pill/': {
id: '/pill/'
path: '/pill'
fullPath: '/pill'
preLoaderRoute: typeof PillIndexRouteImport
parentRoute: typeof rootRouteImport
}
'/modal/': { '/modal/': {
id: '/modal/' id: '/modal/'
path: '/modal' path: '/modal'
@@ -202,6 +222,7 @@ const rootRouteChildren: RootRouteChildren = {
LoadingIndexRoute: LoadingIndexRoute, LoadingIndexRoute: LoadingIndexRoute,
MessageIndexRoute: MessageIndexRoute, MessageIndexRoute: MessageIndexRoute,
ModalIndexRoute: ModalIndexRoute, ModalIndexRoute: ModalIndexRoute,
PillIndexRoute: PillIndexRoute,
ProgressIndexRoute: ProgressIndexRoute, ProgressIndexRoute: ProgressIndexRoute,
TabIndexRoute: TabIndexRoute, TabIndexRoute: TabIndexRoute,
} }

View File

@@ -11,6 +11,7 @@ const navLinks = [
{ to: "/loading", label: "Loading" }, { to: "/loading", label: "Loading" },
{ to: "/message", label: "Message" }, { to: "/message", label: "Message" },
{ to: "/modal", label: "Modal" }, { to: "/modal", label: "Modal" },
{ to: "/pill", label: "Pill" },
{ to: "/progress", label: "Progress" }, { to: "/progress", label: "Progress" },
{ to: "/tab", label: "Tab" } { to: "/tab", label: "Tab" }
]; ];
@@ -20,7 +21,7 @@ export const Route = createRootRoute({
component: () => ( component: () => (
<> <>
<NavBar <NavBar
className="bg-neutral-300 dark:bg-neutral-900 h-12" className="bg-neutral-300 dark:bg-neutral-900 h-12 gap-x-4"
> >
<div <div
className="flex flex-row items-center justify-end gap-x-4" className="flex flex-row items-center justify-end gap-x-4"

View File

@@ -120,10 +120,10 @@ function generateTabContent(Fn: (props: ButtonProps) => JSX.Element, onClick: ()
function ButtonDisplay({ function ButtonDisplay({
title, title,
children children
}:{ }: Readonly<{
title: React.ReactNode; title: React.ReactNode;
children: React.ReactNode; children: React.ReactNode;
}){ }>){
return ( return (
<div <div
className="flex flex-col items-center justify-center gap-y-2" className="flex flex-col items-center justify-center gap-y-2"

View File

@@ -1,13 +1,13 @@
import { DangerMessageBlock, DarkMessageBlock, LightMessageBlock, PrimaryMessageBlock, SecondaryMessageBlock, SuccessMessageBlock, TertiaryMessageBlock, WarningMessageBlock } from '$/component/message'; import { DangerMessageBlock, DarkMessageBlock, LightMessageBlock, PrimaryMessageBlock, SecondaryMessageBlock, SuccessMessageBlock, TertiaryMessageBlock, WarningMessageBlock } from '$/component/message';
import InfoMessageBlock from '$/component/message/InfoMessageBlock'; import InfoMessageBlock from "$/component/message/InfoMessageBlock";
import MoltenMessageBlock from '$/component/message/MoltenMessageBlock'; import MoltenMessageBlock from "$/component/message/MoltenMessageBlock";
import { MattrixwvTabGroup } from '$/component/tab'; import { MattrixwvTabGroup } from "$/component/tab";
import type { MessageBlockProps } from '$/types/MessageTypes'; import type { MessageBlockProps } from "$/types/MessageTypes";
import type { TabGroupContent } from '$/types/TabTypes'; import type { TabGroupContent } from "$/types/TabTypes";
import { createFileRoute } from '@tanstack/react-router'; import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute('/message/')({ export const Route = createFileRoute("/message/")({
component: MessagePage component: MessagePage
}); });

View File

@@ -1,7 +1,7 @@
import { DangerButton, PrimaryButton, SuccessButton, WarningButton } from "$/component/button"; import { DangerButton, PrimaryButton, SuccessButton, WarningButton } from "$/component/button";
import { PrimaryMessageBlock } from "$/component/message"; import { PrimaryMessageBlock } from "$/component/message";
import { Modal } from "$/component/modal"; import { Modal } from "$/component/modal";
import { useToaster } from "$/providers/toaster/ToasterProvider"; import { useToaster } from "$/provider/toaster/ToasterProvider";
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react"; import { useState } from "react";
@@ -77,10 +77,10 @@ function ModalPage(){
function DemoCenteredModal({ function DemoCenteredModal({
display, display,
onClose onClose
}:{ }: Readonly<{
display: boolean; display: boolean;
onClose: () => void; onClose: () => void;
}){ }>){
return ( return (
<Modal <Modal
display={display} display={display}
@@ -97,10 +97,10 @@ function DemoCenteredModal({
function DemoTopModal({ function DemoTopModal({
display, display,
onClose onClose
}:{ }: Readonly<{
display: boolean; display: boolean;
onClose: () => void; onClose: () => void;
}){ }>){
return ( return (
<Modal <Modal
display={display} display={display}

56
src/routes/pill/index.tsx Normal file
View File

@@ -0,0 +1,56 @@
import DangerPill from "$/component/pill/DangerPill";
import DarkPill from "$/component/pill/DarkPill";
import InfoPill from "$/component/pill/InfoPill";
import LightPill from "$/component/pill/LightPill";
import MoltenPill from "$/component/pill/MoltenPill";
import PrimaryPill from "$/component/pill/PrimaryPill";
import SecondaryPill from "$/component/pill/SecondaryPill";
import SuccessPill from "$/component/pill/SuccessPill";
import TertiaryPill from "$/component/pill/TertiaryPill";
import WarningPill from "$/component/pill/WarningPill";
import type { PillProps } from "$/types/PillTypes";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/pill/")({
component: PillPage
});
function PillPage(){
return (
<div className="flex flex-col items-center justify-center gap-y-8">
<PillLayout PillType={PrimaryPill} pillName="Primary"/>
<PillLayout PillType={SecondaryPill} pillName="Secondary"/>
<PillLayout PillType={TertiaryPill} pillName="Tertiary"/>
<PillLayout PillType={InfoPill} pillName="Info"/>
<PillLayout PillType={SuccessPill} pillName="Success"/>
<PillLayout PillType={WarningPill} pillName="Warning"/>
<PillLayout PillType={DangerPill} pillName="Danger"/>
<PillLayout PillType={MoltenPill} pillName="Molten"/>
<PillLayout PillType={DarkPill} pillName="Dark"/>
<PillLayout PillType={LightPill} pillName="Light"/>
</div>
);
}
function PillLayout({
PillType,
pillName
}: Readonly<{
PillType: (props: PillProps) => React.ReactNode;
pillName: string;
}>){
return (
<div className="flex flex-col items-center justify-center gap-y-2">
<h2 className="text-2xl">{pillName}</h2>
<div className="flex flex-row items-center justify-center gap-x-8">
<PillType rounding="none">None</PillType>
<PillType rounding="sm">Small</PillType>
<PillType rounding="md">Medium</PillType>
<PillType rounding="lg">Large</PillType>
<PillType rounding="full">Full</PillType>
</div>
</div>
);
}

View File

@@ -128,13 +128,13 @@ function ProgressPage() {
function ProgressBlock({ function ProgressBlock({
label, label,
children children
}:{ }: Readonly<{
label: string; label: string;
children: React.ReactNode; children: React.ReactNode;
}){ }>){
return ( return (
<div <div
className="flex flex-col items-center justify-center w-128 gap-y-2" className="flex flex-col items-center justify-center w-lg gap-y-2"
> >
<h3 <h3
className="font-bold text-2xl" className="font-bold text-2xl"

View File

@@ -574,18 +574,20 @@ export function TextContent(){
const [ selected, setSelected ] = useState(selectOptions[0]); const [ selected, setSelected ] = useState(selectOptions[0]);
const [ numberValue, setNumberValue ] = useState(0); const [ numberValue, setNumberValue ] = useState(0);
const [ textValue, setTextValue ] = useState("");
const [ secondTextValue, setSecondTextValue ] = useState("");
return ( return (
<div <div
className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full" className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full"
> >
<TextDisplay title="Text Input"> <GeneralInputDisplay title="Text Input">
<TextInput placeholder="Text Input" labelClassName="bg-(--bg-color) peer-focus:bg-(--bg-color)"/> <TextInput placeholder="Text Input" labelClassName="bg-(--bg-color) peer-focus:bg-(--bg-color)" value={textValue} onChange={setTextValue}/>
</TextDisplay> </GeneralInputDisplay>
<TextDisplay title="Text Area"> <GeneralInputDisplay title="Text Area">
<TextArea placeholder="Textarea" className="resize" labelClassName="bg-(--bg-color) peer-focus:bg-(--bg-color)"/> <TextArea placeholder="Textarea" className="resize" labelClassName="bg-(--bg-color) peer-focus:bg-(--bg-color)" value={secondTextValue} onChange={setSecondTextValue}/>
</TextDisplay> </GeneralInputDisplay>
<TextDisplay title="Select"> <GeneralInputDisplay title="Select">
<SelectInput placeholder={selected.label} onChange={(newValue) => setSelected(selectOptions.find((option) => option.value === newValue) || selectOptions[0])}> <SelectInput placeholder={selected.label} onChange={(newValue) => setSelected(selectOptions.find((option) => option.value === newValue) || selectOptions[0])}>
{ {
selectOptions.map((option) => ( selectOptions.map((option) => (
@@ -599,8 +601,8 @@ export function TextContent(){
)) ))
} }
</SelectInput> </SelectInput>
</TextDisplay> </GeneralInputDisplay>
<TextDisplay <GeneralInputDisplay
title="Number Input" title="Number Input"
> >
<NumberInput <NumberInput
@@ -610,9 +612,9 @@ export function TextContent(){
> >
Number Test Number Test
</NumberInput> </NumberInput>
</TextDisplay> </GeneralInputDisplay>
{/* */ {/* */
<TextDisplay <GeneralInputDisplay
title="Number Slider" title="Number Slider"
> >
<NumberSlider <NumberSlider
@@ -621,13 +623,13 @@ export function TextContent(){
value={numberValue} value={numberValue}
onChange={setNumberValue} onChange={setNumberValue}
/> />
</TextDisplay> </GeneralInputDisplay>
/* */} /* */}
</div> </div>
); );
} }
function TextDisplay({ function GeneralInputDisplay({
title, title,
children children
}:Readonly<{ }:Readonly<{
@@ -649,13 +651,13 @@ export function FileContent(){
<div <div
className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full" className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full"
> >
<FileDisplay title="File Input"> <GeneralInputDisplay title="File Input">
<FileInput <FileInput
showFileName={true} showFileName={true}
showSize={true} showSize={true}
/> />
</FileDisplay> </GeneralInputDisplay>
<FileDisplay title="Drag and Drop File Input"> <GeneralInputDisplay title="Drag and Drop File Input">
<DragAndDropFileInput <DragAndDropFileInput
showFileName={true} showFileName={true}
showSize={true} showSize={true}
@@ -664,24 +666,7 @@ export function FileContent(){
> >
Drag And Drop File Input Drag And Drop File Input
</DragAndDropFileInput> </DragAndDropFileInput>
</FileDisplay> </GeneralInputDisplay>
</div>
);
}
function FileDisplay({
title,
children
}:Readonly<{
title: React.ReactNode;
children: React.ReactNode;
}>){
return (
<div
className="flex flex-col items-center justify-center gap-y-2 w-full"
>
<h2 className="text-2xl">{title}</h2>
{children}
</div> </div>
); );
} }
@@ -691,7 +676,7 @@ export function CheckboxContent(){
<div <div
className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full" className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full"
> >
<CheckboxDisplay title="Checkbox"> <GeneralInputDisplay title="Checkbox">
<div className="flex flex-row items-center justify-center gap-x-8"> <div className="flex flex-row items-center justify-center gap-x-8">
<MattrixwvCheckbox className="group-data-checked:stroke-white group-data-checked:bg-amber-400" defaultChecked={true}>Default</MattrixwvCheckbox> <MattrixwvCheckbox className="group-data-checked:stroke-white group-data-checked:bg-amber-400" defaultChecked={true}>Default</MattrixwvCheckbox>
<PrimaryCheckbox defaultChecked={true} >Primary</PrimaryCheckbox> <PrimaryCheckbox defaultChecked={true} >Primary</PrimaryCheckbox>
@@ -705,8 +690,8 @@ export function CheckboxContent(){
<LightCheckbox defaultChecked={true}>Light</LightCheckbox> <LightCheckbox defaultChecked={true}>Light</LightCheckbox>
<DarkCheckbox defaultChecked={true}>Dark</DarkCheckbox> <DarkCheckbox defaultChecked={true}>Dark</DarkCheckbox>
</div> </div>
</CheckboxDisplay> </GeneralInputDisplay>
<CheckboxDisplay title="Checks"> <GeneralInputDisplay title="Checks">
<div className="flex flex-row items-center justify-center gap-x-8"> <div className="flex flex-row items-center justify-center gap-x-8">
<MattrixwvCheckbox className="group-data-checked:stroke-amber-400" defaultChecked={true} showBox={false}>Default</MattrixwvCheckbox> <MattrixwvCheckbox className="group-data-checked:stroke-amber-400" defaultChecked={true} showBox={false}>Default</MattrixwvCheckbox>
<PrimaryCheckbox defaultChecked={true} showBox={false}>Primary</PrimaryCheckbox> <PrimaryCheckbox defaultChecked={true} showBox={false}>Primary</PrimaryCheckbox>
@@ -720,24 +705,7 @@ export function CheckboxContent(){
<LightCheckbox defaultChecked={true} showBox={false}>Light</LightCheckbox> <LightCheckbox defaultChecked={true} showBox={false}>Light</LightCheckbox>
<DarkCheckbox defaultChecked={true} showBox={false}>Dark</DarkCheckbox> <DarkCheckbox defaultChecked={true} showBox={false}>Dark</DarkCheckbox>
</div> </div>
</CheckboxDisplay> </GeneralInputDisplay>
</div>
);
}
function CheckboxDisplay({
title,
children
}:Readonly<{
title: React.ReactNode;
children: React.ReactNode;
}>){
return (
<div
className="flex flex-col items-center justify-center gap-y-2 w-full"
>
<h2 className="text-2xl">{title}</h2>
{children}
</div> </div>
); );
} }
@@ -747,7 +715,7 @@ export function RadioContent(){
<div <div
className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full" className="flex flex-col items-center justify-center gap-y-8 mt-8 w-full"
> >
<RadioDisplay title="Sizes"> <GeneralInputDisplay title="Sizes">
<RadioList <RadioList
> >
<PrimaryRadioButton size="xs" value="xs">Extra Small</PrimaryRadioButton> <PrimaryRadioButton size="xs" value="xs">Extra Small</PrimaryRadioButton>
@@ -756,8 +724,8 @@ export function RadioContent(){
<PrimaryRadioButton size="lg" value="lg">Large</PrimaryRadioButton> <PrimaryRadioButton size="lg" value="lg">Large</PrimaryRadioButton>
<PrimaryRadioButton size="xl" value="xl">Extra Large</PrimaryRadioButton> <PrimaryRadioButton size="xl" value="xl">Extra Large</PrimaryRadioButton>
</RadioList> </RadioList>
</RadioDisplay> </GeneralInputDisplay>
<RadioDisplay title="Radio Checked"> <GeneralInputDisplay title="Radio Checked">
<div <div
className="flex flex-row items-center justify-center gap-x-8" className="flex flex-row items-center justify-center gap-x-8"
> >
@@ -772,8 +740,8 @@ export function RadioContent(){
<RadioList value="Light"><LightRadioButton value="Light">Light</LightRadioButton></RadioList> <RadioList value="Light"><LightRadioButton value="Light">Light</LightRadioButton></RadioList>
<RadioList value="Dark"><DarkRadioButton value="Dark">Dark</DarkRadioButton></RadioList> <RadioList value="Dark"><DarkRadioButton value="Dark">Dark</DarkRadioButton></RadioList>
</div> </div>
</RadioDisplay> </GeneralInputDisplay>
<RadioDisplay title="Radio Horizontal"> <GeneralInputDisplay title="Radio Horizontal">
<RadioList <RadioList
direction="horizontal" direction="horizontal"
> >
@@ -789,8 +757,8 @@ export function RadioContent(){
<LightRadioButton value="light">Light</LightRadioButton> <LightRadioButton value="light">Light</LightRadioButton>
<DarkRadioButton value="dark">Dark</DarkRadioButton> <DarkRadioButton value="dark">Dark</DarkRadioButton>
</RadioList> </RadioList>
</RadioDisplay> </GeneralInputDisplay>
<RadioDisplay title="Radio Vertical"> <GeneralInputDisplay title="Radio Vertical">
<RadioList <RadioList
direction="vertical" direction="vertical"
> >
@@ -806,24 +774,7 @@ export function RadioContent(){
<LightRadioButton value="light">Light</LightRadioButton> <LightRadioButton value="light">Light</LightRadioButton>
<DarkRadioButton value="dark">Dark</DarkRadioButton> <DarkRadioButton value="dark">Dark</DarkRadioButton>
</RadioList> </RadioList>
</RadioDisplay> </GeneralInputDisplay>
</div>
);
}
function RadioDisplay({
title,
children
}:Readonly<{
title: React.ReactNode;
children: React.ReactNode;
}>){
return (
<div
className="flex flex-col items-center justify-center gap-y-2 w-full"
>
<h2 className="text-2xl">{title}</h2>
{children}
</div> </div>
); );
} }

View File

@@ -47,10 +47,10 @@ import type { JSX } from "react";
function LoadingGroup({ function LoadingGroup({
label, label,
elements elements
}:{ }: Readonly<{
label: React.ReactNode; label: React.ReactNode;
elements: JSX.Element[]; elements: JSX.Element[];
}){ }>){
return ( return (
<div <div
className="flex flex-col items-center justify-center" className="flex flex-col items-center justify-center"

View File

@@ -0,0 +1,81 @@
import DangerCheckbox from "$/component/input/checkbox/DangerCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<DangerCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-danger", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<DangerCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-danger", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<DangerCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<DangerCheckbox>{label}</DangerCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<DangerCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-danger", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-danger");
});
it("Renders without box", () => {
render(<DangerCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-danger", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-danger");
});
});

View File

@@ -0,0 +1,81 @@
import DarkCheckbox from "$/component/input/checkbox/DarkCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<DarkCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-dark", "group-data-checked:stroke-light");
});
it("Renders disabled", () => {
render(<DarkCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-dark", "group-data-checked:stroke-light");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<DarkCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<DarkCheckbox>{label}</DarkCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<DarkCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-dark", "group-data-checked:stroke-light");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-dark");
});
it("Renders without box", () => {
render(<DarkCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-dark", "group-data-checked:stroke-light");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-dark");
});
});

View File

@@ -0,0 +1,81 @@
import InfoCheckbox from "$/component/input/checkbox/InfoCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<InfoCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-info", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<InfoCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-info", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<InfoCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<InfoCheckbox>{label}</InfoCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<InfoCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-info", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-info");
});
it("Renders without box", () => {
render(<InfoCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-info", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-info");
});
});

View File

@@ -0,0 +1,81 @@
import LightCheckbox from "$/component/input/checkbox/LightCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<LightCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-light", "group-data-checked:stroke-dark");
});
it("Renders disabled", () => {
render(<LightCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-light", "group-data-checked:stroke-dark");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<LightCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<LightCheckbox>{label}</LightCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<LightCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-light", "group-data-checked:stroke-dark");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-light");
});
it("Renders without box", () => {
render(<LightCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-light", "group-data-checked:stroke-dark");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-light");
});
});

View File

@@ -0,0 +1,235 @@
import { MattrixwvCheckbox } from "$/index";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
describe("Renders", () => {
it("Renders with default properties", () => {
render(<MattrixwvCheckbox/>);
//Checkbox
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox.id).toMatch(/_r_\d+/);
expect(checkbox).toHaveClass("group");
expect(checkbox).toHaveClass("focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2");
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
expect(checkbox).not.toBeChecked();
//Visible checkbox
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
//Label
const label = screen.queryByTestId("mattrixwv-checkbox-label");
expect(label).not.toBeInTheDocument();
});
it("Renders with default properties with custom name and class name", () => {
const className = "my-class-name";
const name = "my-name";
render(
<MattrixwvCheckbox
className={className}
name={name}
/>
);
//Checkbox
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("group");
expect(checkbox).toHaveClass("focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2");
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toBeChecked();
expect(checkbox).not.toHaveAttribute("aria-labelledby");
//Visible checkbox
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkbox).toContain(checkboxGraphic);
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass(className);
//Label
const label = screen.queryByTestId("mattrixwv-checkbox-label");
expect(label).not.toBeInTheDocument();
});
it("Renders with default properties disabled", () => {
render(<MattrixwvCheckbox disabled/>);
//Checkbox
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox.id).toMatch(/_r_\d+/);
expect(checkbox).toHaveClass("group");
expect(checkbox).toHaveClass("focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2");
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
expect(checkbox).not.toBeChecked();
//Visible checkbox
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkbox).toContain(checkboxGraphic);
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
//Label
const label = screen.queryByTestId("mattrixwv-checkbox-label");
expect(label).not.toBeInTheDocument();
});
});
describe("Checkbox", () => {
it("Renders with box", () => {
render(<MattrixwvCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toHaveClass("border", "rounded");
});
it("Renders without box", () => {
render(<MattrixwvCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).not.toHaveClass("border", "rounded");
});
});
describe("Size", () => {
it("Renders with no size", () => {
render(<MattrixwvCheckbox size="none"/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic.className).not.toMatch(/size*/);
});
it("Renders with extra-small size", () => {
render(<MattrixwvCheckbox size="xs"/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-3");
});
it("Renders with small size", () => {
render(<MattrixwvCheckbox size="sm"/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
});
it("Renders with medium size", () => {
render(<MattrixwvCheckbox size="md"/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-5");
});
it("Renders with large size", () => {
render(<MattrixwvCheckbox size="lg"/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-6");
});
it("Renders with extra-large size", () => {
render(<MattrixwvCheckbox size="xl"/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-7");
});
});
describe("Label", () => {
it("Renders with label", () => {
const textContent = "Text";
render(<MattrixwvCheckbox>{textContent}</MattrixwvCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveAttribute("aria-labelledby");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkbox).toContain(checkboxGraphic);
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkbox).toAppearBefore(checkboxLabel);
expect(checkboxLabel.id).toMatch(/headlessui-label-_r_.+_/);
expect(checkboxLabel).toHaveTextContent(textContent);
});
it("Renders with label classes", () => {
const textContent = "Text";
const className = "custom-class-name";
render(<MattrixwvCheckbox labelClassName={className}>{textContent}</MattrixwvCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveAttribute("aria-labelledby");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkbox).toContain(checkboxGraphic);
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkbox).toAppearBefore(checkboxLabel);
expect(checkboxLabel.id).toMatch(/headlessui-label-_r_.+_/);
expect(checkboxLabel).toHaveClass(className);
expect(checkboxLabel).toHaveTextContent(textContent);
});
});
describe("Checking", () => {
it("Renders checked", async () => {
render(<MattrixwvCheckbox checked/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toBeChecked();
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
});
it("Renders default checked", async () => {
render(<MattrixwvCheckbox defaultChecked/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toBeChecked();
await userEvent.click(checkbox);
expect(checkbox).not.toBeChecked();
});
it("Handles changes", async () => {
const label = "Some label";
const handleClick = vi.fn();
render(<MattrixwvCheckbox onChange={handleClick}>{label}</MattrixwvCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
expect(handleClick).toHaveBeenCalledTimes(0);
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(handleClick).toHaveBeenCalledTimes(1);
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
await userEvent.click(checkboxLabel);
expect(checkbox).not.toBeChecked();
expect(handleClick).toHaveBeenCalledTimes(2);
});
});

View File

@@ -0,0 +1,81 @@
import MoltenCheckbox from "$/component/input/checkbox/MoltenCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<MoltenCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-molten", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<MoltenCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-molten", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<MoltenCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<MoltenCheckbox>{label}</MoltenCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<MoltenCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-molten", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-molten");
});
it("Renders without box", () => {
render(<MoltenCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-molten", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-molten");
});
});

View File

@@ -0,0 +1,81 @@
import PrimaryCheckbox from "$/component/input/checkbox/PrimaryCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<PrimaryCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-primary", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<PrimaryCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-primary", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<PrimaryCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<PrimaryCheckbox>{label}</PrimaryCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<PrimaryCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-primary", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-primary");
});
it("Renders without box", () => {
render(<PrimaryCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-primary", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-primary");
});
});

View File

@@ -0,0 +1,81 @@
import SecondaryCheckbox from "$/component/input/checkbox/SecondaryCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<SecondaryCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-secondary", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<SecondaryCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-secondary", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<SecondaryCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<SecondaryCheckbox>{label}</SecondaryCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<SecondaryCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-secondary", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-secondary");
});
it("Renders without box", () => {
render(<SecondaryCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-secondary", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-secondary");
});
});

View File

@@ -0,0 +1,81 @@
import SuccessCheckbox from "$/component/input/checkbox/SuccessCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<SuccessCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-success", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<SuccessCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-success", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<SuccessCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<SuccessCheckbox>{label}</SuccessCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<SuccessCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-success", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-success");
});
it("Renders without box", () => {
render(<SuccessCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-success", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-success");
});
});

View File

@@ -0,0 +1,81 @@
import TertiaryCheckbox from "$/component/input/checkbox/TertiaryCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<TertiaryCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-tertiary", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<TertiaryCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-tertiary", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<TertiaryCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<TertiaryCheckbox>{label}</TertiaryCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<TertiaryCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-tertiary", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-tertiary");
});
it("Renders without box", () => {
render(<TertiaryCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-tertiary", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-tertiary");
});
});

View File

@@ -0,0 +1,81 @@
import WarningCheckbox from "$/component/input/checkbox/WarningCheckbox";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<WarningCheckbox/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-pointer");
expect(checkbox).not.toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-warning", "group-data-checked:stroke-white");
});
it("Renders disabled", () => {
render(<WarningCheckbox disabled/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveClass("cursor-not-allowed");
expect(checkbox).toHaveAttribute("data-disabled");
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("border", "rounded");
expect(checkboxGraphic).toHaveClass("size-4");
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-warning", "group-data-checked:stroke-white");
});
it("Renders with custom classes", () => {
const className = "custom-class";
render(<WarningCheckbox className={className}/>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass(className);
});
it("Renders with label", () => {
const label = "Some Label";
render(<WarningCheckbox>{label}</WarningCheckbox>);
const checkbox = screen.getByTestId("mattrixwv-checkbox");
expect(checkbox).toBeInTheDocument();
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
const checkboxLabel = screen.getByTestId("mattrixwv-checkbox-label");
expect(checkboxLabel).toBeInTheDocument();
expect(checkboxLabel).toHaveTextContent(label);
});
});
describe("Box variants", () => {
it("Renders with box", () => {
render(<WarningCheckbox showBox={true}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).toHaveClass("group-data-checked:bg-warning", "group-data-checked:stroke-white");
expect(checkboxGraphic).not.toHaveClass("group-data-checked:stroke-warning");
});
it("Renders without box", () => {
render(<WarningCheckbox showBox={false}/>);
const checkboxGraphic = screen.getByTestId("mattrixwv-checkbox-graphic");
expect(checkboxGraphic).toBeInTheDocument();
expect(checkboxGraphic).not.toHaveClass("group-data-checked:bg-warning", "group-data-checked:stroke-white");
expect(checkboxGraphic).toHaveClass("group-data-checked:stroke-warning");
});
});

View File

@@ -0,0 +1,84 @@
import DangerPill from "$/component/pill/DangerPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<DangerPill>{textContent}</DangerPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-danger-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-danger", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<DangerPill rounding="none">{textContent}</DangerPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-danger-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-danger", "text-white");
});
it("Renders with small rounding", () => {
render(<DangerPill rounding="sm">{textContent}</DangerPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-danger-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-danger", "text-white");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<DangerPill rounding="md">{textContent}</DangerPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-danger-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-danger", "text-white");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<DangerPill rounding="lg">{textContent}</DangerPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-danger-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-danger", "text-white");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<DangerPill rounding="full">{textContent}</DangerPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-danger-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-danger", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import DarkPill from "$/component/pill/DarkPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<DarkPill>{textContent}</DarkPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-dark-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-dark", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<DarkPill rounding="none">{textContent}</DarkPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-dark-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-dark", "text-white");
});
it("Renders with small rounding", () => {
render(<DarkPill rounding="sm">{textContent}</DarkPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-dark-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-dark", "text-white");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<DarkPill rounding="md">{textContent}</DarkPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-dark-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-dark", "text-white");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<DarkPill rounding="lg">{textContent}</DarkPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-dark-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-dark", "text-white");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<DarkPill rounding="full">{textContent}</DarkPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-dark-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-dark", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import InfoPill from "$/component/pill/InfoPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<InfoPill>{textContent}</InfoPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-info-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-info", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<InfoPill rounding="none">{textContent}</InfoPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-info-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-info", "text-black");
});
it("Renders with small rounding", () => {
render(<InfoPill rounding="sm">{textContent}</InfoPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-info-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-info", "text-black");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<InfoPill rounding="md">{textContent}</InfoPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-info-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-info", "text-black");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<InfoPill rounding="lg">{textContent}</InfoPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-info-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-info", "text-black");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<InfoPill rounding="full">{textContent}</InfoPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-info-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-info", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import LightPill from "$/component/pill/LightPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<LightPill>{textContent}</LightPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-light-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-light", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<LightPill rounding="none">{textContent}</LightPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-light-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-light", "text-black");
});
it("Renders with small rounding", () => {
render(<LightPill rounding="sm">{textContent}</LightPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-light-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-light", "text-black");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<LightPill rounding="md">{textContent}</LightPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-light-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-light", "text-black");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<LightPill rounding="lg">{textContent}</LightPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-light-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-light", "text-black");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<LightPill rounding="full">{textContent}</LightPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-light-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-light", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import MoltenPill from "$/component/pill/MoltenPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<MoltenPill>{textContent}</MoltenPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-molten-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-molten", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<MoltenPill rounding="none">{textContent}</MoltenPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-molten-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-molten", "text-black");
});
it("Renders with small rounding", () => {
render(<MoltenPill rounding="sm">{textContent}</MoltenPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-molten-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-molten", "text-black");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<MoltenPill rounding="md">{textContent}</MoltenPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-molten-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-molten", "text-black");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<MoltenPill rounding="lg">{textContent}</MoltenPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-molten-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-molten", "text-black");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<MoltenPill rounding="full">{textContent}</MoltenPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-molten-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-molten", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,78 @@
import Pill from "$/component/pill/Pill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<Pill>{textContent}</Pill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<Pill rounding="none">{textContent}</Pill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
});
it("Renders with small rounding", () => {
render(<Pill rounding="sm">{textContent}</Pill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<Pill rounding="md">{textContent}</Pill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<Pill rounding="lg">{textContent}</Pill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<Pill rounding="full">{textContent}</Pill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import PrimaryPill from "$/component/pill/PrimaryPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<PrimaryPill>{textContent}</PrimaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-primary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-primary", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<PrimaryPill rounding="none">{textContent}</PrimaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-primary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-primary", "text-white");
});
it("Renders with small rounding", () => {
render(<PrimaryPill rounding="sm">{textContent}</PrimaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-primary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-primary", "text-white");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<PrimaryPill rounding="md">{textContent}</PrimaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-primary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-primary", "text-white");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<PrimaryPill rounding="lg">{textContent}</PrimaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-primary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-primary", "text-white");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<PrimaryPill rounding="full">{textContent}</PrimaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-primary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-primary", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import SecondaryPill from "$/component/pill/SecondaryPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<SecondaryPill>{textContent}</SecondaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-secondary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-secondary", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<SecondaryPill rounding="none">{textContent}</SecondaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-secondary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-secondary", "text-white");
});
it("Renders with small rounding", () => {
render(<SecondaryPill rounding="sm">{textContent}</SecondaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-secondary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-secondary", "text-white");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<SecondaryPill rounding="md">{textContent}</SecondaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-secondary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-secondary", "text-white");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<SecondaryPill rounding="lg">{textContent}</SecondaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-secondary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-secondary", "text-white");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<SecondaryPill rounding="full">{textContent}</SecondaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-secondary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-secondary", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import SuccessPill from "$/component/pill/SuccessPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<SuccessPill>{textContent}</SuccessPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-success-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-success", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<SuccessPill rounding="none">{textContent}</SuccessPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-success-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-success", "text-black");
});
it("Renders with small rounding", () => {
render(<SuccessPill rounding="sm">{textContent}</SuccessPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-success-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-success", "text-black");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<SuccessPill rounding="md">{textContent}</SuccessPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-success-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-success", "text-black");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<SuccessPill rounding="lg">{textContent}</SuccessPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-success-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-success", "text-black");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<SuccessPill rounding="full">{textContent}</SuccessPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-success-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-success", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import TertiaryPill from "$/component/pill/TertiaryPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<TertiaryPill>{textContent}</TertiaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-tertiary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-tertiary", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<TertiaryPill rounding="none">{textContent}</TertiaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-tertiary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-tertiary", "text-white");
});
it("Renders with small rounding", () => {
render(<TertiaryPill rounding="sm">{textContent}</TertiaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-tertiary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-tertiary", "text-white");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<TertiaryPill rounding="md">{textContent}</TertiaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-tertiary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-tertiary", "text-white");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<TertiaryPill rounding="lg">{textContent}</TertiaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-tertiary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-tertiary", "text-white");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<TertiaryPill rounding="full">{textContent}</TertiaryPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-tertiary-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-tertiary", "text-white");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -0,0 +1,84 @@
import WarningPill from "$/component/pill/WarningPill";
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
const textContent = "Testing";
describe("Renders", () => {
it("Renders with defaults", () => {
render(<WarningPill>{textContent}</WarningPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-warning-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-warning", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});
describe("Rounding", () => {
it("Renders with no rounding", () => {
render(<WarningPill rounding="none">{textContent}</WarningPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-warning-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-warning", "text-black");
});
it("Renders with small rounding", () => {
render(<WarningPill rounding="sm">{textContent}</WarningPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-warning-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-warning", "text-black");
expect(pillDiv).toHaveClass("rounded-sm");
});
it("Renders with medium rounding", () => {
render(<WarningPill rounding="md">{textContent}</WarningPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-warning-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-warning", "text-black");
expect(pillDiv).toHaveClass("rounded");
});
it("Renders with large rounding", () => {
render(<WarningPill rounding="lg">{textContent}</WarningPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-warning-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-warning", "text-black");
expect(pillDiv).toHaveClass("rounded-lg");
});
it("Renders with full rounding", () => {
render(<WarningPill rounding="full">{textContent}</WarningPill>);
//Make sure the pill div is present
const pillDiv = screen.getByTestId("mattrixwv-warning-pill");
expect(pillDiv).toBeInTheDocument();
expect(pillDiv).toHaveTextContent(textContent);
//Check for the default classes
expect(pillDiv).toHaveClass("px-2", "text-sm", "whitespace-nowrap");
expect(pillDiv).toHaveClass("bg-warning", "text-black");
expect(pillDiv).toHaveClass("rounded-full");
});
});

View File

@@ -10,7 +10,8 @@ import { viteStaticCopy } from "vite-plugin-static-copy";
import { peerDependencies } from "./package.json"; import { peerDependencies } from "./package.json";
const modules = [ "button", "input", "loading", "message", "modal", "nav", "progress", "tab", "toaster" ]; const components = [ "button", "input", "loading", "message", "modal", "nav", "progress", "tab", "toaster" ];
const providers = [ "axios", "theme", "toaster", "token" ];
// https://vite.dev/config/ // https://vite.dev/config/
@@ -35,7 +36,15 @@ export default defineConfig({
viteStaticCopy({ viteStaticCopy({
targets: [ targets: [
{ {
src: resolve(__dirname, "lib/styles.css"), src: resolve(__dirname, "lib/components.css"),
dest: ""
},
{
src: resolve(__dirname, "lib/layout.css"),
dest: ""
},
{
src: resolve(__dirname, "lib/theme.css"),
dest: "" dest: ""
} }
] ]
@@ -51,8 +60,9 @@ export default defineConfig({
build: { build: {
lib: { lib: {
entry: { entry: {
index: resolve(__dirname, "lib/index.ts"), "mattrixwv-components": resolve(__dirname, "lib/index.ts"),
...Object.fromEntries(modules.map(mod => [mod, resolve(__dirname, `lib/component/${mod}/index.ts`)])) ...Object.fromEntries(components.map(mod => [mod, resolve(__dirname, `lib/component/${mod}/index.ts`)])),
...Object.fromEntries(providers.map(mod => [mod, resolve(__dirname, `lib/provider/${mod}/index.ts`)]))
}, },
formats: [ "es" ], formats: [ "es" ],
name: "Mattrixwv Component Library" name: "Mattrixwv Component Library"
@@ -83,6 +93,10 @@ export default defineConfig({
test: { test: {
globals: true, globals: true,
environment: "jsdom", environment: "jsdom",
setupFiles: [ "test/vitest.setup.ts" ] setupFiles: [ "test/vitest.setup.ts" ],
coverage: {
provider: "v8",
reporter: [ "html", "text", "lcov" ]
}
} }
}); });