Move sortabla and radio input to packages/ui

This commit is contained in:
Satish Gandham 2024-05-23 15:58:14 +05:30
parent d6325320e9
commit 3133207c42
13 changed files with 77 additions and 21 deletions

View File

@ -22,7 +22,7 @@
"dependencies": {
"@blueprintjs/core": "^4.16.3",
"@blueprintjs/popover2": "^1.13.3",
"@headlessui/react": "^1.7.17",
"@headlessui/react": "^2.0.3",
"@popperjs/core": "^2.11.8",
"clsx": "^2.0.0",
"emoji-picker-react": "^4.5.16",

View File

@ -15,3 +15,5 @@ export * from "./toast";
export * from "./drag-handle";
export * from "./typography";
export * from "./drop-indicator";
export * from "./radio-input";
export * from "./sortable";

View File

@ -0,0 +1 @@
export * from "./radio-input";

View File

@ -1,19 +1,33 @@
import { Field, Label, Radio, RadioGroup } from "@headlessui/react";
import React from "react";
import { Field, Label, Radio, RadioGroup } from "@headlessui/react";
import { cn } from "../../helpers";
// helpers
type RadioInputProps = {
label: string | React.ReactNode | undefined;
labelClassName?: string;
ariaLabel?: string;
options: { label: string; value: string; disabled?: boolean }[];
vertical?: boolean;
selected: string;
onChange: (value: string) => void;
className?: string;
};
const RadioInput = ({ label: inputLabel, options, vertical, selected, ariaLabel }: RadioInputProps) => {
const RadioInput = ({
label: inputLabel,
labelClassName: inputLabelClassName,
options,
vertical,
selected,
ariaLabel,
onChange,
className,
}: RadioInputProps) => {
const wrapperClass = vertical ? "flex flex-col gap-1" : "flex gap-2";
const setSelected = (value: string) => {
console.log(value);
onChange(value);
};
let aria = ariaLabel ? ariaLabel.toLowerCase().replace(" ", "-") : "";
@ -23,19 +37,25 @@ const RadioInput = ({ label: inputLabel, options, vertical, selected, ariaLabel
aria = "radio-input";
}
// return <h1>Hello</h1>;
return (
<RadioGroup value={selected} onChange={setSelected} aria-label={aria}>
<Label className="">{inputLabel}</Label>
<RadioGroup value={selected} onChange={setSelected} aria-label={aria} className={className}>
<Label className={cn(`mb-2`, inputLabelClassName)}>{inputLabel}</Label>
<div className={`${wrapperClass}`}>
{options.map(({ value, label }) => (
{options.map(({ value, label, disabled }) => (
<Field key={label} className="flex items-center gap-2">
<Radio
value={value}
className="group flex size-5 items-center justify-center rounded-full border bg-white data-[checked]:bg-blue-400"
className="group flex size-5 items-center justify-center rounded-full border border-custom-border-400 bg-custom-background-500 data-[checked]:bg-custom-primary-200 data-[checked]:border-custom-primary-100 cursor-pointer
data-[disabled]:bg-custom-background-200
data-[disabled]:border-custom-border-200
data-[disabled]:cursor-not-allowed"
disabled={disabled}
>
<span className="invisible size-2 rounded-full bg-white group-data-[checked]:visible" />
</Radio>
<Label>{label}</Label>
<Label className="text-base cursor-pointer">{label}</Label>
</Field>
))}
</div>

View File

@ -1,14 +1,15 @@
import { useEffect, useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import { isEqual } from "lodash";
import { cn } from "@/helpers/common.helper";
import { cn } from "../../helpers";
type Props = {
children: React.ReactNode;
data: any; //@todo make this generic
className?: string;
};
const Draggable = ({ children, data }: Props) => {
const Draggable = ({ children, data, className }: Props) => {
const ref = useRef<HTMLDivElement>(null);
const [dragging, setDragging] = useState<boolean>(false); // NEW
const [isDraggedOver, setIsDraggedOver] = useState(false);
@ -37,7 +38,7 @@ const Draggable = ({ children, data }: Props) => {
}, [data]);
return (
<div ref={ref} className={cn(dragging && "opacity-25", isDraggedOver && "bg-red-500")}>
<div ref={ref} className={cn(dragging && "opacity-25", isDraggedOver && "bg-custom-background-80", className)}>
{children}
</div>
);

View File

@ -0,0 +1,2 @@
export * from "./sortable";
export * from "./draggable";

View File

@ -0,0 +1,32 @@
import type { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { Draggable } from "./draggable";
import { Sortable } from "./sortable";
const meta: Meta<typeof Sortable> = {
title: "Sortable",
component: Sortable,
};
export default meta;
type Story = StoryObj<typeof Sortable>;
const data = [
{ id: "1", name: "John Doe" },
{ id: "2", name: "Jane Doe" },
{ id: "3", name: "Alice" },
{ id: "4", name: "Bob" },
{ id: "5", name: "Charlie" },
];
export const Default: Story = {
args: {
data,
render: (item: any) => (
<Draggable data={item} className="rounded-lg">
<div>{item.name}</div>
</Draggable>
),
onChange: (data) => console.log(data),
keyExtractor: (item: any) => item.id,
},
};

View File

@ -1,10 +1,10 @@
import { FC } from "react";
// components
import { RadioInput } from "@/components/radio-group";
// constants
import { RadioInput } from "@plane/ui";
import { TEstimateSystemKeys } from "@/components/estimates/types";
import { ESTIMATE_SYSTEMS } from "@/constants/estimates";
// types
import { TEstimateSystemKeys } from "@/components/estimates/types";
type TEstimateCreateStageOne = {
estimateSystem: TEstimateSystemKeys;

View File

@ -1,6 +1,6 @@
import { FC } from "react";
import { Plus } from "lucide-react";
import { Button } from "@plane/ui";
import { Button, Sortable } from "@plane/ui";
// components
import { EstimateItem } from "@/components/estimates";
import {
@ -10,7 +10,6 @@ import {
TEstimateSystemKeyObject,
TEstimateSystemKeys,
} from "@/components/estimates/types";
import { Sortable } from "@/components/sortable/sortable";
// constants
import { ESTIMATE_SYSTEMS } from "@/constants/estimates";

View File

@ -1,7 +1,7 @@
import { Fragment, useRef, useState } from "react";
import { Check, GripVertical, MoveRight, Pencil, Trash2, X } from "lucide-react";
import { Select } from "@headlessui/react";
import { Draggable } from "@/components/sortable/draggable";
import { Draggable } from "@plane/ui";
import { InlineEdit } from "./inline-editable";
import { TEstimatePointNumeric, TEstimatePointString } from "./types";

View File

@ -1 +0,0 @@
export * from "./radio-group";

View File

@ -1593,7 +1593,7 @@
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.2.tgz#d8bae93ac8b815b2bd7a98078cf91e2724ef11e5"
integrity sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==
"@headlessui/react@^1.7.13", "@headlessui/react@^1.7.17", "@headlessui/react@^1.7.19":
"@headlessui/react@^1.7.13", "@headlessui/react@^1.7.19":
version "1.7.19"
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.19.tgz#91c78cf5fcb254f4a0ebe96936d48421caf75f40"
integrity sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==
@ -4094,7 +4094,7 @@
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@18.2.48", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^18.2.42", "@types/react@^18.2.48":
"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^18.2.42", "@types/react@^18.2.48":
version "18.2.48"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.48.tgz#11df5664642d0bd879c1f58bc1d37205b064e8f1"
integrity sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==