Skip to content

Commit

Permalink
(#0) SelectBubble 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
baegofda committed Nov 29, 2023
1 parent c5678fd commit 8d2e639
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Meta } from "@storybook/react";
import { useState } from "react";

import SelectBubble from "./index";

const meta = {
title: "core/Select/SelectBubble/SelectBubble",
component: SelectBubble,
argTypes: {},
} satisfies Meta<typeof SelectBubble>;

export default meta;

export const Default = () => {
const [ currentValue, setCurrentValue ] = useState("A");
const data = [
{ key: "A", label: "A반" },
{ key: "B", label: "B반" },
{ key: "C", label: "C반" },
];

const items = data.map(item => (
<SelectBubble.Item
label = {item.label}
name = {"class"}
checked = {item.key === currentValue}
value = {item.key}
onChange = {(e: React.ChangeEvent<HTMLInputElement>) => {
const { value } = e.target;

setCurrentValue(value);
}}
/>
));

return (
<div className = "w-[60rem]">
<SelectBubble label = "품목 선택" feedback = "반별로 품목과 수량을 각각 선택해주세요." items = {items} required/>
</div>
);
};
34 changes: 34 additions & 0 deletions src/core/components/Select/SelectBubble/SelectBubble/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { forwardRef } from "react";

import { FormLabel } from "@/index";
import clsx from "clsx";
import SelectBubbleItem from "../SelectBubbleItem";
import { ReturnType, SelectBubbleProps } from "./types";

const SelectBubble = forwardRef((
{
items,
label,
labelColor,
required,
feedback,
...props
}: SelectBubbleProps,
ref: React.Ref<HTMLUListElement>,
) => {
const { className, ...rest } = props;

return (
<div className = {clsx("flex-v-stack gap-y-3", className)}>
<FormLabel label = {label} labelColor = {labelColor} required = {required} feedback = {feedback}/>
<ul ref = {ref} className = {"flex gap-x-3"} {...rest}>
{items}
</ul>
</div>
);
}) as unknown as ReturnType;

export default SelectBubble;

SelectBubble.displayName = "SelectBubble";
SelectBubble.Item = SelectBubbleItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { FormLabelProps } from "@/core/components/FormLabel/types";
import SelectBubbleItem from "../../SelectBubbleItem";

export interface SelectBubbleProps extends React.HTMLAttributes<HTMLUListElement>, FormLabelProps {
items: React.ReactNode[]
}

type TableTabComponent = (props: SelectBubbleProps) => React.ReactElement;

export type ReturnType = TableTabComponent & {
displayName: string;
Item: typeof SelectBubbleItem;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Meta } from "@storybook/react";

import SelectBubble from "../SelectBubble";
import SelectBubbleItem from "./index";
import { SelectButtonItemProps } from "./types";

const meta = {
title: "core/Select/SelectBubble/SelectBubbleItem",
component: SelectBubbleItem,
argTypes: {
label: {
control: "text",
description: "Bubble Label",
},
},
} satisfies Meta<typeof SelectBubbleItem>;

export default meta;

export const Default = (props: SelectButtonItemProps) => {
const { label, ...rest } = props;

return (
<ul>
<SelectBubble.Item label = {label ?? "A반"} {...rest} />
</ul>
);
};
38 changes: 38 additions & 0 deletions src/core/components/Select/SelectBubble/SelectBubbleItem/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { forwardRef, useId } from "react";

import { Typography } from "@/index";
import { SelectButtonItemProps } from "./types";

const SelectBubbleItem = forwardRef((
{
label,
...props
}: Omit<SelectButtonItemProps, "ref">,
ref: React.Ref<HTMLInputElement>,
) => {
const id = useId();

return (
<li>
<label className = "flex" htmlFor = {id}>
<input
ref = {ref}
id = {id}
type = "radio"
className = {"sr-only peer"}
{...props}
/>
<Typography
className = "p-2.5 border border-gray-04 peer-checked:bg-primary-00 peer-checked:border-primary-00 peer-checked:text-primary-03 cursor-pointer rounded-default"
theme = "subhead-02-bold"
color = "gray-05"
text = {label}
/>
</label>
</li>
);
});

export default SelectBubbleItem;

SelectBubbleItem.displayName = "SelectBubbleItem";
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { InputHTMLAttributes } from "react";

import { TypographyProps } from "@/core/components/Typography";

export interface SelectButtonItemProps extends InputHTMLAttributes<HTMLInputElement> {
label: TypographyProps<"span">["text"]
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export { default as ModalBase } from "@/core/components/Modal/ModalBase";
export { default as ModalPopUp } from "@/core/components/Modal/ModalPopUp";
export { default as ModalPortal } from "@/core/components/Modal/ModalPortal";
export { default as Section } from "@/core/components/Section";
export { default as SelectBubble } from "@/core/components/Select/SelectBubble/SelectBubble";
export { default as SelectBubbleItem } from "@/core/components/Select/SelectBubble/SelectBubbleItem";
export { default as SelectOnset } from "@/core/components/Select/SelectOnset/SelectOnset";
export { default as GeneralTab } from "@/core/components/Tab/GeneralTab/GeneralTab";
export { default as GeneralTabItem } from "@/core/components/Tab/GeneralTab/GeneralTabItem";
Expand Down

0 comments on commit 8d2e639

Please sign in to comment.