Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Plenum component DropdownWithMultiSelect #90

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run_unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: "18" # Specify the Node.js version you want
node-version: "20" # Specify the Node.js version you want
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bumping these up to match manager app repo


- name: Install dependencies
run: yarn install # Installs dependencies using Yarn
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/type-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: "18" # Specify the Node.js version you want
node-version: "20" # Specify the Node.js version you want

- name: Install dependencies
run: yarn install # Or `npm install` if you're using npm
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@agility/plenum-ui",
"version": "2.1.18",
"version": "2.1.20",
"license": "MIT",
"main": "dist/index.js",
"module": "dist/index.js",
Expand Down Expand Up @@ -29,8 +29,8 @@
},
"dependencies": {
"@floating-ui/react": "^0.25.0",
"@headlessui/react": "^1.7.10",
"@headlessui/tailwindcss": "^0.1.2",
"@headlessui/react": "2.1",
"@headlessui/tailwindcss": "0.2.1",
"@heroicons/react": "^1.0.5",
"@next/font": "^13.4.12",
"@tabler/icons": "^2.26.0",
Expand Down Expand Up @@ -62,7 +62,8 @@
"@testing-library/jest-dom": "^6.6.2",
"@testing-library/react": "^16.0.1",
"@types/jest": "^29.5.14",
"@types/node": "18.11.18",
"@types/node": "^22.10.2",
"@types/react": "^18.2.0",
"autoprefixer": "^10.4.13",
"esbuild": "^0.18.19",
"eslint": "8.32.0",
Expand Down
11 changes: 6 additions & 5 deletions stories/atoms/buttons/Button/tests/Button.test.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { vi } from "vitest";
import Button from "../Button";
import { render, screen, fireEvent } from "@testing-library/react";

Expand Down Expand Up @@ -58,28 +59,28 @@ describe("<Button>", () => {
expect(buttonElement).toHaveClass("px-[13px]");
});

it("redners with size xs", () => {
it("renders with size xs", () => {
render(<Button {...defaultProps} size="xs" />);

const buttonElement = screen.getByRole("button");
expect(buttonElement).toHaveClass("px-[11px]");
});

it("redners with size md", () => {
it("renders with size md", () => {
render(<Button {...defaultProps} size="md" />);

const buttonElement = screen.getByRole("button");
expect(buttonElement).toHaveClass("px-[17px] text-sm");
});

it("redners with size lg", () => {
it("renders with size lg", () => {
render(<Button {...defaultProps} size="lg" />);

const buttonElement = screen.getByRole("button");
expect(buttonElement).toHaveClass("px-[17px] text-base");
});

it("redners with size xl", () => {
it("renders with size xl", () => {
render(<Button {...defaultProps} size="xl" />);

const buttonElement = screen.getByRole("button");
Expand All @@ -104,7 +105,7 @@ describe("<Button>", () => {
});

it("calls onClick when clicked", () => {
const handleClick = vitest.fn();
const handleClick = vi.fn();
render(<Button {...defaultProps} onClick={handleClick} />);

const buttonElement = screen.getByRole("button");
Expand Down
21 changes: 11 additions & 10 deletions stories/atoms/icons/TablerIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import React from "react"
import { TablerIconName } from "./tablerIconNames"
import * as TablerIcons from "@tabler/icons-react"
import { ClassNameWithAutocomplete } from "@/utils/types"
import React from "react";
import { TablerIconName } from "./tablerIconNames";
import * as TablerIcons from "@tabler/icons-react";
import { ClassNameWithAutocomplete } from "@/utils/types";

export interface ITablerIconProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> {
icon: TablerIconName
className?: ClassNameWithAutocomplete
icon: TablerIconName;
className?: ClassNameWithAutocomplete;
}

const TablerIcon: React.FC<ITablerIconProps> = ({
icon,
className = "w-6 h-6 text-gray-600"
}: ITablerIconProps): JSX.Element => {
const Icon = TablerIcons[icon]
//@ts-ignore
const Icon = TablerIcons[icon];
return (
<i>
<Icon className={className} />
</i>
)
}
export default TablerIcon
);
};
export default TablerIcon;
26 changes: 15 additions & 11 deletions stories/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//Atomic Components, props, and type gaurds.
//Atomic Components, props, and type guards.
import {
IAvatarProps,
IBadgeProps,
Expand All @@ -24,8 +24,8 @@ import {
isHeroIcon,
isTablerIcon,
isUnifiedIconName
} from "./atoms"
// Molecular Components, props, and type gaurds.
} from "./atoms";
// Molecular Components, props, and type guards.
import {
ICheckboxProps,
IComboboxProps,
Expand All @@ -49,8 +49,8 @@ import {
TextInput,
ITextInputProps,
ISimpleSelectOptions
} from "./molecules"
// Organism Components, props, and type gaurds.
} from "./molecules";
// Organism Components, props, and type guards.
import {
IAnimatedLabelInputProps,
AnimatedLabelTextArea,
Expand All @@ -68,8 +68,10 @@ import {
TextInputSelect,
ITextInputSelectProps,
IAnimatedFormInputWithAddons,
AnimatedFormInputWithAddons
} from "./organisms"
AnimatedFormInputWithAddons,
DropdownWithMultiSelect,
MultiSelectItemProps
} from "./organisms";

export type {
IAvatarProps,
Expand Down Expand Up @@ -104,8 +106,9 @@ export type {
BTNActionType,
ITextInputProps,
ISimpleSelectOptions,
IAnimatedFormInputWithAddons
}
IAnimatedFormInputWithAddons,
MultiSelectItemProps
};
export {
Avatar,
Checkbox,
Expand Down Expand Up @@ -136,5 +139,6 @@ export {
isUnifiedIconName,
TextInput,
TextInputSelect,
AnimatedFormInputWithAddons
}
AnimatedFormInputWithAddons,
DropdownWithMultiSelect
};
11 changes: 8 additions & 3 deletions stories/molecules/inputs/InputLabel/InputLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export interface IInputLabelProps {
isActive?: boolean;
isFocused?: boolean;
label?: string;
truncateLabel?: boolean;
fullWidthLabel?: boolean;
}

/** Comment */
Expand All @@ -24,7 +26,9 @@ const InputLabel: FC<IInputLabelProps> = ({
isDisabled,
isActive,
isError,
label
label,
truncateLabel = false,
fullWidthLabel = false
}: IInputLabelProps) => {
const labelStyles = cn(
"z-[2] ",
Expand All @@ -34,12 +38,13 @@ const InputLabel: FC<IInputLabelProps> = ({
{ "text-xs text-red-500 px-1 top-[10px] bg-white": isPlaceholder && isError },
{ "text-red-500 bg-white": !isPlaceholder && isError },
{ "text-gray-500/[.5]": isDisabled },
{ "inline-block transition-all text-sm text-gray-700 mb-1": !isPlaceholder }
{ "inline-block transition-all text-sm text-gray-700 mb-1": !isPlaceholder },
{ "block w-full": fullWidthLabel }
);
if (!label) return null;
return (
<label htmlFor={id} className={labelStyles}>
{label}
<div className={truncateLabel ? "break-all line-clamp-1" : ""}>{label}</div>
{isRequired && <span className="text-red-500"> *</span>}
</label>
);
Expand Down
73 changes: 41 additions & 32 deletions stories/molecules/inputs/checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import React, { FC } from "react"
import { default as cn } from "classnames"
import InputLabel from "@/stories/molecules/inputs/InputLabel"
import { useId } from "@/utils/useId"
import React, { FC } from "react";
import { default as cn } from "classnames";
import InputLabel from "@/stories/molecules/inputs/InputLabel";
import { useId } from "@/utils/useId";

export interface ICheckboxProps {
/** Checkbox label */
label: string
label: string;
/** Checkbox ID */
id?: string
id?: string;
/** Disabled state */
isDisabled?: boolean
isDisabled?: boolean;
/** value */
value?: string
value?: string;
/** Check state */
isChecked?: boolean
isChecked?: boolean;
/** If field is required */
isRequired?: boolean
isRequired?: boolean;
/** Error state */
isError?: boolean
isError?: boolean;
/** Message or description */
message?: string
message?: string;
/** Callback on input change */
onChange?(value: string, isChecked: boolean): void
onChange?(value: string, isChecked: boolean): void;
/** Has a border around the checkbox and label */
hasBorder?: boolean
hasBorder?: boolean;
/** any arbitrary classNames to add to the wrapper */
className?: string
/** Label ClassName */
labelClassName?: string
className?: string;
/** Truncate label */
truncateLabel?: boolean;
/** Full width label */
fullWidthLabel?: boolean;
}
Comment on lines +30 to +32
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just passing these down from the new component to inputlabel


/** Comment */
Expand All @@ -43,29 +45,30 @@ const Checkbox: FC<ICheckboxProps> = ({
onChange,
hasBorder,
className,
labelClassName,
truncateLabel = false,
fullWidthLabel = false,
...props
}: ICheckboxProps) => {
const uniqueID = useId()
if (!id) id = `cb-${uniqueID}`
const uniqueID = useId();
if (!id) id = `cb-${uniqueID}`;

const checkboxStyles = cn(
"rounded-sm border-gray-300 text-sm font-normal leading-5 text-purple-600 focus:ring-purple-600",
{ "border-red-500 shadow-none": isError }
)
);
const wrapperStyles = cn(
"relative flex items-center min-h-[38px]",
{ "opacity-50": isDisabled },
{ "rounded-sm border border-1 px-3 border-gray-200": hasBorder },
{ "py-3": hasBorder && message },
className
)
);

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const targetValue = e.target.value
const targetChecked = e.target.checked
typeof onChange === "function" && onChange(targetValue, targetChecked)
}
const targetValue = e.target.value;
const targetChecked = e.target.checked;
typeof onChange === "function" && onChange(targetValue, targetChecked);
};

return (
<div className={wrapperStyles}>
Expand All @@ -80,14 +83,20 @@ const Checkbox: FC<ICheckboxProps> = ({
disabled={isDisabled}
checked={isChecked}
onChange={(e) => {
handleChange(e)
handleChange(e);
}}
{...props}
/>
</div>
<div className="ml-3 text-sm ">
<div className="ml-3 text-sm flex items-center w-full">
<>
<InputLabel label={label} isRequired={isRequired} id={id} />
<InputLabel
label={label}
isRequired={isRequired}
id={id}
truncateLabel={truncateLabel}
fullWidthLabel={fullWidthLabel}
/>
</>

{message && (
Expand All @@ -97,6 +106,6 @@ const Checkbox: FC<ICheckboxProps> = ({
)}
</div>
</div>
)
}
export default Checkbox
);
};
export default Checkbox;
Loading
Loading