@loword/loword-design-system 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/components/Avatar/Avatar.d.ts +11 -0
- package/dist/components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar/Avatar.js +24 -0
- package/dist/components/Avatar/AvatarBase.d.ts +32 -0
- package/dist/components/Avatar/AvatarBase.d.ts.map +1 -0
- package/dist/components/Avatar/AvatarBase.js +49 -0
- package/dist/components/Badge/Badge.d.ts +25 -0
- package/dist/components/Badge/Badge.d.ts.map +1 -0
- package/dist/components/Badge/Badge.js +36 -0
- package/dist/components/Badge/BadgeBase.d.ts +10 -0
- package/dist/components/Badge/BadgeBase.d.ts.map +1 -0
- package/dist/components/Badge/BadgeBase.js +9 -0
- package/dist/components/Button/Button.d.ts +26 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/Button.js +102 -0
- package/dist/components/Button/ButtonBase.d.ts +5 -0
- package/dist/components/Button/ButtonBase.d.ts.map +1 -0
- package/dist/components/Button/ButtonBase.js +10 -0
- package/dist/components/Button/ButtonSpinner.d.ts +9 -0
- package/dist/components/Button/ButtonSpinner.d.ts.map +1 -0
- package/dist/components/Button/ButtonSpinner.js +14 -0
- package/dist/components/Calendar/Calendar.d.ts +16 -0
- package/dist/components/Calendar/Calendar.d.ts.map +1 -0
- package/dist/components/Calendar/Calendar.js +75 -0
- package/dist/components/Carousel/Carousel.d.ts +50 -0
- package/dist/components/Carousel/Carousel.d.ts.map +1 -0
- package/dist/components/Carousel/Carousel.js +22 -0
- package/dist/components/Carousel/CarouselBase.d.ts +98 -0
- package/dist/components/Carousel/CarouselBase.d.ts.map +1 -0
- package/dist/components/Carousel/CarouselBase.js +144 -0
- package/dist/components/Checkbox/Checkbox.d.ts +27 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox/Checkbox.js +30 -0
- package/dist/components/Checkbox/CheckboxBase.d.ts +40 -0
- package/dist/components/Checkbox/CheckboxBase.d.ts.map +1 -0
- package/dist/components/Checkbox/CheckboxBase.js +57 -0
- package/dist/components/Checkbox/CheckboxGroup.d.ts +22 -0
- package/dist/components/Checkbox/CheckboxGroup.d.ts.map +1 -0
- package/dist/components/Checkbox/CheckboxGroup.js +13 -0
- package/dist/components/Checkbox/FormCheckbox.d.ts +14 -0
- package/dist/components/Checkbox/FormCheckbox.d.ts.map +1 -0
- package/dist/components/Checkbox/FormCheckbox.js +9 -0
- package/dist/components/Checkbox/FormCheckboxGroup.d.ts +13 -0
- package/dist/components/Checkbox/FormCheckboxGroup.d.ts.map +1 -0
- package/dist/components/Checkbox/FormCheckboxGroup.js +9 -0
- package/dist/components/DataCalendar/DataCalendar.d.ts +12 -0
- package/dist/components/DataCalendar/DataCalendar.d.ts.map +1 -0
- package/dist/components/DataCalendar/DataCalendar.js +13 -0
- package/dist/components/DataCalendar/DataCalendarBase.d.ts +45 -0
- package/dist/components/DataCalendar/DataCalendarBase.d.ts.map +1 -0
- package/dist/components/DataCalendar/DataCalendarBase.js +57 -0
- package/dist/components/DatePicker/DatePicker.d.ts +34 -0
- package/dist/components/DatePicker/DatePicker.d.ts.map +1 -0
- package/dist/components/DatePicker/DatePicker.js +44 -0
- package/dist/components/DatePicker/FormDatePicker.d.ts +12 -0
- package/dist/components/DatePicker/FormDatePicker.d.ts.map +1 -0
- package/dist/components/DatePicker/FormDatePicker.js +12 -0
- package/dist/components/DateRangePicker/DateRangePicker.d.ts +49 -0
- package/dist/components/DateRangePicker/DateRangePicker.d.ts.map +1 -0
- package/dist/components/DateRangePicker/DateRangePicker.js +197 -0
- package/dist/components/DateRangePicker/FormDateRangePicker.d.ts +12 -0
- package/dist/components/DateRangePicker/FormDateRangePicker.d.ts.map +1 -0
- package/dist/components/DateRangePicker/FormDateRangePicker.js +10 -0
- package/dist/components/Drawer/Drawer.d.ts +51 -0
- package/dist/components/Drawer/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer/Drawer.js +30 -0
- package/dist/components/Drawer/DrawerBase.d.ts +52 -0
- package/dist/components/Drawer/DrawerBase.d.ts.map +1 -0
- package/dist/components/Drawer/DrawerBase.js +38 -0
- package/dist/components/Editor/Editor.d.ts +12 -0
- package/dist/components/Editor/Editor.d.ts.map +1 -0
- package/dist/components/Editor/Editor.js +162 -0
- package/dist/components/Editor/EditorBase.d.ts +52 -0
- package/dist/components/Editor/EditorBase.d.ts.map +1 -0
- package/dist/components/Editor/EditorBase.js +89 -0
- package/dist/components/Editor/Viewer.d.ts +7 -0
- package/dist/components/Editor/Viewer.d.ts.map +1 -0
- package/dist/components/Editor/Viewer.js +9 -0
- package/dist/components/Editor/extensions.d.ts +6 -0
- package/dist/components/Editor/extensions.d.ts.map +1 -0
- package/dist/components/Editor/extensions.js +38 -0
- package/dist/components/FileUpload/FileUploadBase.d.ts +50 -0
- package/dist/components/FileUpload/FileUploadBase.d.ts.map +1 -0
- package/dist/components/FileUpload/FileUploadBase.js +102 -0
- package/dist/components/Form/Form.d.ts +21 -0
- package/dist/components/Form/Form.d.ts.map +1 -0
- package/dist/components/Form/Form.js +18 -0
- package/dist/components/Form/FormErrorMessage.d.ts +9 -0
- package/dist/components/Form/FormErrorMessage.d.ts.map +1 -0
- package/dist/components/Form/FormErrorMessage.js +6 -0
- package/dist/components/Form/FormField.d.ts +55 -0
- package/dist/components/Form/FormField.d.ts.map +1 -0
- package/dist/components/Form/FormField.js +43 -0
- package/dist/components/Icon/LucideIcon.d.ts +11 -0
- package/dist/components/Icon/LucideIcon.d.ts.map +1 -0
- package/dist/components/Icon/LucideIcon.js +41 -0
- package/dist/components/Input/FormInput.d.ts +15 -0
- package/dist/components/Input/FormInput.d.ts.map +1 -0
- package/dist/components/Input/FormInput.js +19 -0
- package/dist/components/Input/Input.d.ts +24 -0
- package/dist/components/Input/Input.d.ts.map +1 -0
- package/dist/components/Input/Input.js +71 -0
- package/dist/components/Input/InputBase.d.ts +22 -0
- package/dist/components/Input/InputBase.d.ts.map +1 -0
- package/dist/components/Input/InputBase.js +17 -0
- package/dist/components/LNB/LNBBase.d.ts +82 -0
- package/dist/components/LNB/LNBBase.d.ts.map +1 -0
- package/dist/components/LNB/LNBBase.js +108 -0
- package/dist/components/LoadingDots/LoadingDots.d.ts +8 -0
- package/dist/components/LoadingDots/LoadingDots.d.ts.map +1 -0
- package/dist/components/LoadingDots/LoadingDots.js +29 -0
- package/dist/components/MenuBar/MenuBar.d.ts +21 -0
- package/dist/components/MenuBar/MenuBar.d.ts.map +1 -0
- package/dist/components/MenuBar/MenuBar.js +33 -0
- package/dist/components/MenuBar/MenuBarBase.d.ts +43 -0
- package/dist/components/MenuBar/MenuBarBase.d.ts.map +1 -0
- package/dist/components/MenuBar/MenuBarBase.js +69 -0
- package/dist/components/Modal/Modal.d.ts +51 -0
- package/dist/components/Modal/Modal.d.ts.map +1 -0
- package/dist/components/Modal/Modal.js +72 -0
- package/dist/components/Modal/ModalBase.d.ts +42 -0
- package/dist/components/Modal/ModalBase.d.ts.map +1 -0
- package/dist/components/Modal/ModalBase.js +30 -0
- package/dist/components/Modal/openModal.d.ts +24 -0
- package/dist/components/Modal/openModal.d.ts.map +1 -0
- package/dist/components/Modal/openModal.js +52 -0
- package/dist/components/OTPInput/OTPInput.d.ts +46 -0
- package/dist/components/OTPInput/OTPInput.d.ts.map +1 -0
- package/dist/components/OTPInput/OTPInput.js +87 -0
- package/dist/components/Pagination/Pagination.d.ts +12 -0
- package/dist/components/Pagination/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination/Pagination.js +5 -0
- package/dist/components/Pagination/PaginationBase.d.ts +36 -0
- package/dist/components/Pagination/PaginationBase.d.ts.map +1 -0
- package/dist/components/Pagination/PaginationBase.js +44 -0
- package/dist/components/Pagination/paginationUtils.d.ts +2 -0
- package/dist/components/Pagination/paginationUtils.d.ts.map +1 -0
- package/dist/components/Pagination/paginationUtils.js +18 -0
- package/dist/components/Popover/Popover.d.ts +42 -0
- package/dist/components/Popover/Popover.d.ts.map +1 -0
- package/dist/components/Popover/Popover.js +31 -0
- package/dist/components/Popover/PopoverBase.d.ts +31 -0
- package/dist/components/Popover/PopoverBase.d.ts.map +1 -0
- package/dist/components/Popover/PopoverBase.js +18 -0
- package/dist/components/Radio/FormRadioGroup.d.ts +13 -0
- package/dist/components/Radio/FormRadioGroup.d.ts.map +1 -0
- package/dist/components/Radio/FormRadioGroup.js +9 -0
- package/dist/components/Radio/Radio.d.ts +24 -0
- package/dist/components/Radio/Radio.d.ts.map +1 -0
- package/dist/components/Radio/Radio.js +39 -0
- package/dist/components/Radio/RadioBase.d.ts +38 -0
- package/dist/components/Radio/RadioBase.d.ts.map +1 -0
- package/dist/components/Radio/RadioBase.js +46 -0
- package/dist/components/Radio/RadioGroup.d.ts +22 -0
- package/dist/components/Radio/RadioGroup.d.ts.map +1 -0
- package/dist/components/Radio/RadioGroup.js +7 -0
- package/dist/components/ScrollArea/ScrollArea.d.ts +15 -0
- package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -0
- package/dist/components/ScrollArea/ScrollArea.js +10 -0
- package/dist/components/Select/FormMultiSelect.d.ts +13 -0
- package/dist/components/Select/FormMultiSelect.d.ts.map +1 -0
- package/dist/components/Select/FormMultiSelect.js +14 -0
- package/dist/components/Select/FormSelect.d.ts +13 -0
- package/dist/components/Select/FormSelect.d.ts.map +1 -0
- package/dist/components/Select/FormSelect.js +10 -0
- package/dist/components/Select/MultiSelect.d.ts +31 -0
- package/dist/components/Select/MultiSelect.d.ts.map +1 -0
- package/dist/components/Select/MultiSelect.js +59 -0
- package/dist/components/Select/Select.d.ts +41 -0
- package/dist/components/Select/Select.d.ts.map +1 -0
- package/dist/components/Select/Select.js +55 -0
- package/dist/components/Select/SelectBase.d.ts +59 -0
- package/dist/components/Select/SelectBase.d.ts.map +1 -0
- package/dist/components/Select/SelectBase.js +211 -0
- package/dist/components/Skeleton/Skeleton.d.ts +10 -0
- package/dist/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton/Skeleton.js +8 -0
- package/dist/components/Slider/Slider.d.ts +23 -0
- package/dist/components/Slider/Slider.d.ts.map +1 -0
- package/dist/components/Slider/Slider.js +195 -0
- package/dist/components/Spinner/Spinner.d.ts +25 -0
- package/dist/components/Spinner/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner/Spinner.js +20 -0
- package/dist/components/Table/Table.d.ts +34 -0
- package/dist/components/Table/Table.d.ts.map +1 -0
- package/dist/components/Table/Table.js +29 -0
- package/dist/components/Table/TableBase.d.ts +37 -0
- package/dist/components/Table/TableBase.d.ts.map +1 -0
- package/dist/components/Table/TableBase.js +39 -0
- package/dist/components/Table/TableField.d.ts +64 -0
- package/dist/components/Table/TableField.d.ts.map +1 -0
- package/dist/components/Table/TableField.js +87 -0
- package/dist/components/Table/TanstackTable.d.ts +23 -0
- package/dist/components/Table/TanstackTable.d.ts.map +1 -0
- package/dist/components/Table/TanstackTable.js +35 -0
- package/dist/components/TimePicker/FormTimePicker.d.ts +12 -0
- package/dist/components/TimePicker/FormTimePicker.d.ts.map +1 -0
- package/dist/components/TimePicker/FormTimePicker.js +12 -0
- package/dist/components/TimePicker/TimePicker.d.ts +27 -0
- package/dist/components/TimePicker/TimePicker.d.ts.map +1 -0
- package/dist/components/TimePicker/TimePicker.js +120 -0
- package/dist/components/Toast/Toast.d.ts +18 -0
- package/dist/components/Toast/Toast.d.ts.map +1 -0
- package/dist/components/Toast/Toast.js +42 -0
- package/dist/components/Toast/Toaster.d.ts +7 -0
- package/dist/components/Toast/Toaster.d.ts.map +1 -0
- package/dist/components/Toast/Toaster.js +7 -0
- package/dist/components/ToggleButton/FormToggleButton.d.ts +12 -0
- package/dist/components/ToggleButton/FormToggleButton.d.ts.map +1 -0
- package/dist/components/ToggleButton/FormToggleButton.js +9 -0
- package/dist/components/ToggleButton/ToggleButton.d.ts +31 -0
- package/dist/components/ToggleButton/ToggleButton.d.ts.map +1 -0
- package/dist/components/ToggleButton/ToggleButton.js +42 -0
- package/dist/components/ToggleButton/ToggleButtonBase.d.ts +41 -0
- package/dist/components/ToggleButton/ToggleButtonBase.d.ts.map +1 -0
- package/dist/components/ToggleButton/ToggleButtonBase.js +59 -0
- package/dist/components/Tooltip/Tooltip.d.ts +18 -0
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip/Tooltip.js +13 -0
- package/dist/components/Tooltip/TooltipBase.d.ts +39 -0
- package/dist/components/Tooltip/TooltipBase.d.ts.map +1 -0
- package/dist/components/Tooltip/TooltipBase.js +46 -0
- package/dist/constants/file.d.ts +42 -0
- package/dist/constants/file.d.ts.map +1 -0
- package/dist/constants/file.js +47 -0
- package/dist/index.css +4061 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/types/polymorphic.d.ts +19 -0
- package/dist/types/polymorphic.d.ts.map +1 -0
- package/dist/types/polymorphic.js +1 -0
- package/dist/utils/cn.d.ts +4 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/dist/utils/cn.js +6 -0
- package/dist/utils/file.d.ts +16 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +58 -0
- package/dist/utils/renderIcon.d.ts +4 -0
- package/dist/utils/renderIcon.d.ts.map +1 -0
- package/dist/utils/renderIcon.js +11 -0
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +5 -0
- package/package.json +239 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
interface ProviderProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
currentPage: number;
|
|
5
|
+
totalPages: number;
|
|
6
|
+
onPageChange: (page: number) => void;
|
|
7
|
+
}
|
|
8
|
+
interface RootProps extends HTMLAttributes<HTMLElement> {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
interface PrevProps {
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
interface NextProps {
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
interface ListProps {
|
|
18
|
+
numbersToShow?: number;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
interface ItemProps {
|
|
22
|
+
page: number;
|
|
23
|
+
isActive?: boolean;
|
|
24
|
+
onClick?: () => void;
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
declare const PaginationBase: {
|
|
28
|
+
Provider: ({ children, currentPage, totalPages, onPageChange, }: ProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
Root: ({ className, children, ...props }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
Prev: ({ className }: PrevProps) => import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
Next: ({ className }: NextProps) => import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
List: ({ numbersToShow, className }: ListProps) => import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
Item: ({ page, isActive, onClick, className }: ItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
};
|
|
35
|
+
export default PaginationBase;
|
|
36
|
+
//# sourceMappingURL=PaginationBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaginationBase.d.ts","sourceRoot":"","sources":["../../../src/components/Pagination/PaginationBase.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA0BvD,UAAU,aAAa;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAeD,UAAU,SAAU,SAAQ,cAAc,CAAC,WAAW,CAAC;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAcD,UAAU,SAAS;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD,UAAU,SAAS;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD,UAAU,SAAS;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,QAAA,MAAM,cAAc;qEA1IjB,aAAa;8CAYiC,SAAS;0BAgB7B,SAAS;0BA+BT,SAAS;yCAgCU,SAAS;mDA+BH,SAAS;CAuB9D,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
import cn from '../../utils/cn.js';
|
|
4
|
+
import Button from '../Button/Button.js';
|
|
5
|
+
import { calculatePaginationOptions } from './paginationUtils.js';
|
|
6
|
+
const PaginationContext = createContext(null);
|
|
7
|
+
const usePaginationContext = () => {
|
|
8
|
+
const ctx = useContext(PaginationContext);
|
|
9
|
+
if (!ctx)
|
|
10
|
+
throw new Error('PaginationBase 서브컴포넌트는 PaginationBase.Provider 내부에서 사용해야 합니다.');
|
|
11
|
+
return ctx;
|
|
12
|
+
};
|
|
13
|
+
const Provider = ({ children, currentPage, totalPages, onPageChange, }) => (_jsx(PaginationContext, { value: { currentPage, totalPages, onPageChange }, children: children }));
|
|
14
|
+
const Root = ({ className, children, ...props }) => (_jsx("nav", { role: "navigation", "aria-label": "pagination", className: cn('flex flex-row gap-2.5 items-center', className), ...props, children: children }));
|
|
15
|
+
const Prev = ({ className }) => {
|
|
16
|
+
const { currentPage, onPageChange } = usePaginationContext();
|
|
17
|
+
const canPrevious = currentPage > 1;
|
|
18
|
+
return (_jsx(Button, { variant: "outline", color: "neutral", size: "medium", shape: "capsule", leftIcon: "chevronLeft", disabled: !canPrevious, onClick: () => onPageChange(currentPage - 1), "aria-label": "\uC774\uC804 \uD398\uC774\uC9C0", className: cn('size-lg! regular! p-0!', canPrevious
|
|
19
|
+
? 'bg-neutral100! text-neutral400!'
|
|
20
|
+
: 'bg-neutral50! text-neutral200!', canPrevious && 'hover:bg-neutral200!', className) }));
|
|
21
|
+
};
|
|
22
|
+
const Next = ({ className }) => {
|
|
23
|
+
const { currentPage, totalPages, onPageChange } = usePaginationContext();
|
|
24
|
+
const canNext = currentPage < totalPages;
|
|
25
|
+
return (_jsx(Button, { variant: "outline", color: "neutral", size: "medium", shape: "capsule", leftIcon: "chevronRight", disabled: !canNext, onClick: () => onPageChange(currentPage + 1), "aria-label": "\uB2E4\uC74C \uD398\uC774\uC9C0", className: cn('size-lg! regular! p-0!', canNext
|
|
26
|
+
? 'bg-neutral100! text-neutral400!'
|
|
27
|
+
: 'bg-neutral50! text-neutral200!', canNext && 'hover:bg-neutral200!', className) }));
|
|
28
|
+
};
|
|
29
|
+
const List = ({ numbersToShow = 5, className }) => {
|
|
30
|
+
const { currentPage, totalPages, onPageChange } = usePaginationContext();
|
|
31
|
+
const pages = calculatePaginationOptions(currentPage, totalPages, numbersToShow);
|
|
32
|
+
return (_jsx(_Fragment, { children: pages.map((page, idx) => (_jsx(Item, { page: page, isActive: currentPage === page, onClick: () => onPageChange(page), className: className }, `page_${page}_${idx}`))) }));
|
|
33
|
+
};
|
|
34
|
+
const Item = ({ page, isActive, onClick, className }) => (_jsx(Button, { variant: "ghost", color: isActive ? 'point' : 'neutral', size: "medium", onClick: onClick, "aria-label": `${page} 페이지`, "aria-current": isActive ? 'page' : undefined, className: cn('size-lg! regular! rounded-full', className), children: page }));
|
|
35
|
+
// ── Export ──
|
|
36
|
+
const PaginationBase = {
|
|
37
|
+
Provider,
|
|
38
|
+
Root,
|
|
39
|
+
Prev,
|
|
40
|
+
Next,
|
|
41
|
+
List,
|
|
42
|
+
Item,
|
|
43
|
+
};
|
|
44
|
+
export default PaginationBase;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginationUtils.d.ts","sourceRoot":"","sources":["../../../src/components/Pagination/paginationUtils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,GACrC,cAAa,MAAU,EACvB,aAAY,MAAU,EACtB,gBAAe,MAAU,aAuB1B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const calculatePaginationOptions = (currentPage = 1, totalPages = 1, numbersToShow = 5) => {
|
|
2
|
+
const half = Math.floor(numbersToShow / 2);
|
|
3
|
+
let startPage = currentPage - half;
|
|
4
|
+
let endPage = currentPage + half;
|
|
5
|
+
if (startPage < 1) {
|
|
6
|
+
startPage = 1;
|
|
7
|
+
endPage = Math.min(numbersToShow, totalPages);
|
|
8
|
+
}
|
|
9
|
+
if (endPage > totalPages) {
|
|
10
|
+
endPage = totalPages;
|
|
11
|
+
startPage = Math.max(1, totalPages - numbersToShow + 1);
|
|
12
|
+
}
|
|
13
|
+
const paginationOptions = [];
|
|
14
|
+
for (let i = startPage; i <= endPage; ++i) {
|
|
15
|
+
paginationOptions.push(i);
|
|
16
|
+
}
|
|
17
|
+
return paginationOptions;
|
|
18
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
type ItemColor = 'blue' | 'red' | 'gray';
|
|
3
|
+
type IconSize = 'sm' | 'md' | 'lg';
|
|
4
|
+
export interface PopoverItem {
|
|
5
|
+
/** 메뉴 항목 텍스트 또는 ReactNode */
|
|
6
|
+
label: ReactNode;
|
|
7
|
+
/** 항목 색상 */
|
|
8
|
+
color?: ItemColor;
|
|
9
|
+
/** 항목 클릭 시 실행할 함수 */
|
|
10
|
+
onClick: () => void;
|
|
11
|
+
}
|
|
12
|
+
export interface PopoverProps {
|
|
13
|
+
/** 메뉴 항목 목록 (제공 시 메뉴형으로 동작) */
|
|
14
|
+
items?: PopoverItem[];
|
|
15
|
+
/** 팝오버 내부 커스텀 콘텐츠 (items보다 우선순위가 높음) */
|
|
16
|
+
content?: ReactNode;
|
|
17
|
+
/** 커스텀 트리거 요소 (미제공 시 iconSize/isHorizontal 기반 기본 말줄임표 트리거 렌더) */
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
/** 팝오버 열림 상태 (Controlled) */
|
|
20
|
+
open?: boolean;
|
|
21
|
+
/** 열림 상태 변경 핸들러 (Controlled) */
|
|
22
|
+
onOpenChange?: (open: boolean) => void;
|
|
23
|
+
/** 트리거 아이콘 크기 프리셋 (기본 트리거 사용 시) */
|
|
24
|
+
iconSize?: IconSize;
|
|
25
|
+
/** true 시 가로 말줄임표 아이콘 사용 (기본 트리거 사용 시) */
|
|
26
|
+
isHorizontal?: boolean;
|
|
27
|
+
/** 팝오버 정렬 위치 */
|
|
28
|
+
align?: 'start' | 'center' | 'end';
|
|
29
|
+
/** 트리거와 팝오버 사이 간격 (px) */
|
|
30
|
+
offset?: number;
|
|
31
|
+
/** 콘텐츠 너비 (숫자, 문자열, 혹은 'trigger'로 트리거와 일치) */
|
|
32
|
+
contentWidth?: number | string | 'trigger';
|
|
33
|
+
/** 트리거 버튼 className */
|
|
34
|
+
triggerClassName?: string;
|
|
35
|
+
/** 팝오버 콘텐츠 className */
|
|
36
|
+
popoverClassName?: string;
|
|
37
|
+
/** 인라인 스타일 (트리거 버튼에 적용) */
|
|
38
|
+
style?: React.CSSProperties;
|
|
39
|
+
}
|
|
40
|
+
declare const Popover: ({ items, content, children, open, onOpenChange, iconSize, isHorizontal, align, offset, contentWidth, triggerClassName, popoverClassName, style, }: PopoverProps) => import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export default Popover;
|
|
42
|
+
//# sourceMappingURL=Popover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../../src/components/Popover/Popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvD,KAAK,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEzC,KAAK,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnC,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,YAAY;IACZ,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qBAAqB;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,+BAA+B;IAC/B,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,wCAAwC;IACxC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gCAAgC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,mCAAmC;IACnC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3C,uBAAuB;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wBAAwB;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAeD,QAAA,MAAM,OAAO,GAAI,mJAcd,YAAY,4CA8Dd,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { isValidElement } from 'react';
|
|
3
|
+
import PopoverBase from './PopoverBase.js';
|
|
4
|
+
import LucideIcon from '../Icon/LucideIcon.js';
|
|
5
|
+
import cn from '../../utils/cn.js';
|
|
6
|
+
// ── 스타일 매핑 ──
|
|
7
|
+
const itemColorClasses = {
|
|
8
|
+
blue: 'hover:bg-tintBlue text-lb500',
|
|
9
|
+
red: 'hover:bg-tintRed text-danger600',
|
|
10
|
+
gray: 'hover:bg-mono10 text-neutral40',
|
|
11
|
+
};
|
|
12
|
+
const iconSizes = {
|
|
13
|
+
sm: 12,
|
|
14
|
+
md: 20,
|
|
15
|
+
lg: 24,
|
|
16
|
+
};
|
|
17
|
+
const Popover = ({ items, content, children, open, onOpenChange, iconSize = 'sm', isHorizontal = false, align = 'end', offset, contentWidth, triggerClassName, popoverClassName, style, }) => {
|
|
18
|
+
const isAsChild = isValidElement(children);
|
|
19
|
+
return (_jsxs(PopoverBase.Root, { open: open, onOpenChange: onOpenChange, children: [_jsx(PopoverBase.Trigger, { asChild: isAsChild, style: style, className: cn('flex items-center justify-center cursor-pointer ld-transition rounded-[5px] outline-none', !isAsChild && 'px-2 py-1 min-h-6 hover:bg-mono10', triggerClassName), children: isAsChild ? (children) : (_jsx(LucideIcon, { name: isHorizontal ? 'ellipsis' : 'ellipsisVertical', size: iconSizes[iconSize], className: "text-neutral40" })) }), _jsx(PopoverBase.Content, { align: align, sideOffset: offset, style: {
|
|
20
|
+
width: contentWidth === 'trigger'
|
|
21
|
+
? 'var(--radix-popover-trigger-width)'
|
|
22
|
+
: contentWidth,
|
|
23
|
+
}, className: cn('min-w-[160px] rounded-[5px] bg-white border border-mono10 p-xs flex flex-col gap-xs z-50 shadow-lg', popoverClassName), children: content
|
|
24
|
+
? content
|
|
25
|
+
: items?.map((item, index) => (_jsx("button", { type: "button", className: cn('w-full flex items-center cursor-pointer justify-start px-2 py-1.5 rounded-[5px] ld-transition display12 text-left', itemColorClasses[item.color ?? 'gray']), onClick: (e) => {
|
|
26
|
+
e.stopPropagation();
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
item.onClick();
|
|
29
|
+
}, children: item.label }, index))) })] }));
|
|
30
|
+
};
|
|
31
|
+
export default Popover;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
interface RootProps {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
onOpenChange?: (open: boolean) => void;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
interface TriggerProps {
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
className?: string;
|
|
10
|
+
style?: React.CSSProperties;
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
onClick?: (e: React.MouseEvent) => void;
|
|
13
|
+
/** Radix의 asChild 속성 (자식 요소를 트리거로 사용) */
|
|
14
|
+
asChild?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface ContentProps {
|
|
17
|
+
align?: 'start' | 'center' | 'end';
|
|
18
|
+
sideOffset?: number;
|
|
19
|
+
className?: string;
|
|
20
|
+
children?: ReactNode;
|
|
21
|
+
style?: React.CSSProperties;
|
|
22
|
+
/** 팝오버가 열릴 때 자동으로 포커스되는 동작을 커스텀 */
|
|
23
|
+
onOpenAutoFocus?: (event: Event) => void;
|
|
24
|
+
}
|
|
25
|
+
export declare const PopoverBase: {
|
|
26
|
+
Root: ({ open, onOpenChange, children }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
Trigger: ({ disabled, className, style, children, onClick, asChild, }: TriggerProps) => import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
Content: ({ align, sideOffset, className, children, style, onOpenAutoFocus, }: ContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
};
|
|
30
|
+
export default PopoverBase;
|
|
31
|
+
//# sourceMappingURL=PopoverBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PopoverBase.d.ts","sourceRoot":"","sources":["../../../src/components/Popover/PopoverBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAWD,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC,yCAAyC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAwBD,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,mCAAmC;IACnC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC1C;AA6BD,eAAO,MAAM,WAAW;6CA9EwB,SAAS;2EA0BtD,YAAY;mFAgCZ,YAAY;CAwBd,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as RadixPopover from '@radix-ui/react-popover';
|
|
3
|
+
import cn from '../../utils/cn.js';
|
|
4
|
+
const Root = ({ open, onOpenChange, children }) => {
|
|
5
|
+
return (_jsx(RadixPopover.Root, { open: open, onOpenChange: onOpenChange, children: children }));
|
|
6
|
+
};
|
|
7
|
+
const Trigger = ({ disabled, className, style, children, onClick, asChild, }) => {
|
|
8
|
+
return (_jsx(RadixPopover.Trigger, { asChild: asChild, disabled: disabled, className: cn('inline-flex items-center', className), style: style, onClick: onClick, children: children }));
|
|
9
|
+
};
|
|
10
|
+
const Content = ({ align = 'start', sideOffset = 4, className, children, style, onOpenAutoFocus, }) => {
|
|
11
|
+
return (_jsx(RadixPopover.Portal, { children: _jsx(RadixPopover.Content, { align: align, sideOffset: sideOffset, onOpenAutoFocus: onOpenAutoFocus, className: cn('z-50 outline-hidden', 'animate-in fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0', className), style: style, children: children }) }));
|
|
12
|
+
};
|
|
13
|
+
export const PopoverBase = {
|
|
14
|
+
Root,
|
|
15
|
+
Trigger,
|
|
16
|
+
Content,
|
|
17
|
+
};
|
|
18
|
+
export default PopoverBase;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RegisterOptions } from 'react-hook-form';
|
|
2
|
+
import { type RadioGroupProps } from './RadioGroup.js';
|
|
3
|
+
interface FormRadioGroupProps extends Omit<RadioGroupProps, 'value' | 'onChange'> {
|
|
4
|
+
name: string;
|
|
5
|
+
options?: RegisterOptions;
|
|
6
|
+
customErrorMessage?: string;
|
|
7
|
+
isHiddenErrorMessage?: boolean;
|
|
8
|
+
errorClassName?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const FormRadioGroup: ({ name, options, customErrorMessage, isHiddenErrorMessage, errorClassName, disabled, ...props }: FormRadioGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default FormRadioGroup;
|
|
13
|
+
//# sourceMappingURL=FormRadioGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/Radio/FormRadioGroup.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAIhE,UAAU,mBAAoB,SAAQ,IAAI,CACxC,eAAe,EACf,OAAO,GAAG,UAAU,CACrB;IACC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,QAAA,MAAM,cAAc,GAAI,iGAQrB,mBAAmB,4CA8BrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import RadioGroup from './RadioGroup.js';
|
|
4
|
+
import FormField from '../Form/FormField.js';
|
|
5
|
+
import FormErrorMessage from '../Form/FormErrorMessage.js';
|
|
6
|
+
const FormRadioGroup = ({ name, options, customErrorMessage = '', isHiddenErrorMessage = true, errorClassName, disabled = false, ...props }) => {
|
|
7
|
+
return (_jsx(FormField, { name: name, options: options, customErrorMessage: customErrorMessage, disabled: disabled, children: ({ field, fieldState }) => (_jsxs("div", { className: "relative", children: [_jsx(RadioGroup, { ...props, name: name, value: field.value ?? '', onChange: field.onChange, disabled: disabled, "aria-invalid": field['aria-invalid'], "aria-describedby": field['aria-describedby'] }), !isHiddenErrorMessage && (_jsx(FormErrorMessage, { error: fieldState.error, disabled: disabled, className: errorClassName }))] })) }));
|
|
8
|
+
};
|
|
9
|
+
export default FormRadioGroup;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type InputHTMLAttributes, type Ref } from 'react';
|
|
2
|
+
type RadioSize = 'sm' | 'md';
|
|
3
|
+
type RadioType = 'default' | 'pill';
|
|
4
|
+
export interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'checked' | 'disabled'> {
|
|
5
|
+
/** controlled 체크 상태 */
|
|
6
|
+
checked?: boolean;
|
|
7
|
+
/** 초기 체크 상태 (uncontrolled) */
|
|
8
|
+
defaultChecked?: boolean;
|
|
9
|
+
/** 체크 상태 변경 콜백 */
|
|
10
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
11
|
+
/** 비활성화 여부 */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** 라디오 버튼 크기 프리셋 */
|
|
14
|
+
size?: RadioSize;
|
|
15
|
+
/** 라디오 유형 (default: 원형, pill: 알약형 토글) */
|
|
16
|
+
type?: RadioType;
|
|
17
|
+
/** 라벨 텍스트 */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** input 요소 ref */
|
|
20
|
+
ref?: Ref<HTMLInputElement>;
|
|
21
|
+
}
|
|
22
|
+
declare const Radio: ({ checked, defaultChecked, onCheckedChange, size, type, label, disabled, className, style, ref, ...props }: RadioProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export default Radio;
|
|
24
|
+
//# sourceMappingURL=Radio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Radio.d.ts","sourceRoot":"","sources":["../../../src/components/Radio/Radio.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAK3D,KAAK,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;AAC7B,KAAK,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAkBpC,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CACzC;IACC,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8BAA8B;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB;IAClB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,cAAc;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yCAAyC;IACzC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,aAAa;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAqFD,QAAA,MAAM,KAAK,GAAI,4GAYZ,UAAU,4CA0CZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import RadioBase, { useRadioContext } from './RadioBase.js';
|
|
3
|
+
import cn from '../../utils/cn.js';
|
|
4
|
+
const radioSizeClasses = {
|
|
5
|
+
sm: 'size-4',
|
|
6
|
+
md: 'size-5',
|
|
7
|
+
};
|
|
8
|
+
const checkIconSizes = {
|
|
9
|
+
sm: 10,
|
|
10
|
+
md: 12,
|
|
11
|
+
};
|
|
12
|
+
const labelSizeClasses = {
|
|
13
|
+
sm: 'display12',
|
|
14
|
+
md: 'display14 bold',
|
|
15
|
+
};
|
|
16
|
+
// ── Inner: pill 타입 ──
|
|
17
|
+
const PillInner = ({ label, ref, ...props }) => {
|
|
18
|
+
const { checked } = useRadioContext();
|
|
19
|
+
return (_jsxs(_Fragment, { children: [_jsx(RadioBase.HiddenInput, { ref: ref, ...props }), _jsxs("div", { className: "relative flex items-center", children: [_jsx(RadioBase.Indicator, { icon: "check", iconSize: 16, className: "absolute left-0", iconClassName: cn('shrink-0 transition-all duration-200 ease-out', checked ? 'opacity-100' : 'opacity-0') }), label && (_jsx(RadioBase.Label, { className: cn('transition-all ld-transition text-nowrap', checked ? 'pl-5' : 'pl-sm pr-sm'), children: label }))] })] }));
|
|
20
|
+
};
|
|
21
|
+
// ── Inner: default 타입 ──
|
|
22
|
+
const DefaultInner = ({ size, label, ref, ...props }) => {
|
|
23
|
+
const { checked, disabled } = useRadioContext();
|
|
24
|
+
return (_jsxs(_Fragment, { children: [_jsx(RadioBase.HiddenInput, { ref: ref, ...props }), _jsx(RadioBase.Indicator, { icon: "check", iconSize: checkIconSizes[size], className: cn('flex items-center justify-center rounded-full ld-transition outline outline-transparent shrink-0', !disabled &&
|
|
25
|
+
(checked
|
|
26
|
+
? 'outline-lb500 bg-lb500'
|
|
27
|
+
: 'bg-white outline-neutral300 hover:outline-lb500'), disabled && 'outline-neutral300 bg-neutral300', radioSizeClasses[size]), iconClassName: cn('shrink-0 ld-transition', checked ? (disabled ? 'text-neutral500' : 'text-white') : 'opacity-0') }), label && (_jsx(RadioBase.Label, { className: "text-neutral500", children: label }))] }));
|
|
28
|
+
};
|
|
29
|
+
const Radio = ({ checked, defaultChecked, onCheckedChange, size = 'sm', type = 'default', label, disabled = false, className, style, ref, ...props }) => {
|
|
30
|
+
if (type === 'pill') {
|
|
31
|
+
return (_jsx(RadioBase.Root, { checked: checked, defaultChecked: defaultChecked, onCheckedChange: onCheckedChange, disabled: disabled, style: style,
|
|
32
|
+
// pill은 checked 여부에 따라 Root(<label>) 배경/텍스트가 바뀌어야 함.
|
|
33
|
+
// Inner에서는 Root 밖 스타일을 줄 수 없으므로,
|
|
34
|
+
// className을 함수로 받아 Root 내부의 resolved 값을 주입함.
|
|
35
|
+
className: (c) => cn('items-center gap-2 rounded-full py-sm px-[15px] ld-transition display14 bold', c ? 'bg-tintBlue text-lb500' : 'bg-mono100 text-mono500', disabled && 'opacity-50 cursor-not-allowed', className), children: _jsx(PillInner, { label: label, ref: ref, ...props }) }));
|
|
36
|
+
}
|
|
37
|
+
return (_jsx(RadioBase.Root, { checked: checked, defaultChecked: defaultChecked, onCheckedChange: onCheckedChange, disabled: disabled, style: style, className: cn('items-center gap-[5px]', labelSizeClasses[size], className), children: _jsx(DefaultInner, { size: size, label: label, ref: ref, ...props }) }));
|
|
38
|
+
};
|
|
39
|
+
export default Radio;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type InputHTMLAttributes, type ReactNode, type Ref } from 'react';
|
|
2
|
+
import { type IconName } from '../Icon/LucideIcon.js';
|
|
3
|
+
interface RadioContextType {
|
|
4
|
+
checked: boolean;
|
|
5
|
+
onCheckedChange: (checked: boolean) => void;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const useRadioContext: () => RadioContextType;
|
|
9
|
+
interface RootProps {
|
|
10
|
+
checked?: boolean;
|
|
11
|
+
defaultChecked?: boolean;
|
|
12
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
className?: string | ((checked: boolean) => string);
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
interface HiddenInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'checked' | 'disabled'> {
|
|
19
|
+
ref?: Ref<HTMLInputElement>;
|
|
20
|
+
}
|
|
21
|
+
interface IndicatorProps {
|
|
22
|
+
icon?: IconName;
|
|
23
|
+
iconSize?: number;
|
|
24
|
+
className?: string;
|
|
25
|
+
iconClassName?: string;
|
|
26
|
+
}
|
|
27
|
+
interface LabelProps {
|
|
28
|
+
className?: string;
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
export declare const RadioBase: {
|
|
32
|
+
Root: ({ checked, defaultChecked, onCheckedChange, disabled, className, style, children, }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
HiddenInput: ({ ref, onChange, ...props }: HiddenInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
Indicator: ({ icon, iconSize, className, iconClassName, }: IndicatorProps) => import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
Label: ({ className, children }: LabelProps) => import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
};
|
|
37
|
+
export default RadioBase;
|
|
38
|
+
//# sourceMappingURL=RadioBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioBase.d.ts","sourceRoot":"","sources":["../../../src/components/Radio/RadioBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,GAAG,EAIT,MAAM,OAAO,CAAC;AACf,OAAmB,EAAE,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAI/D,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,eAAO,MAAM,eAAe,wBAK3B,CAAC;AAGF,UAAU,SAAS;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA4CD,UAAU,gBAAiB,SAAQ,IAAI,CACrC,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,GAAG,SAAS,GAAG,UAAU,CAChC;IACC,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAsBD,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAgBD,UAAU,UAAU;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD,eAAO,MAAM,SAAS;gGA3FnB,SAAS;+CAyCsC,gBAAgB;+DAgC/D,cAAc;qCAcuB,UAAU;CASjD,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useState, } from 'react';
|
|
3
|
+
import LucideIcon from '../Icon/LucideIcon.js';
|
|
4
|
+
import cn from '../../utils/cn.js';
|
|
5
|
+
const RadioContext = createContext(null);
|
|
6
|
+
export const useRadioContext = () => {
|
|
7
|
+
const ctx = useContext(RadioContext);
|
|
8
|
+
if (!ctx)
|
|
9
|
+
throw new Error('RadioBase 하위 컴포넌트는 Root 내부에서 사용해야 합니다.');
|
|
10
|
+
return ctx;
|
|
11
|
+
};
|
|
12
|
+
const Root = ({ checked, defaultChecked = false, onCheckedChange, disabled = false, className, style, children, }) => {
|
|
13
|
+
const [internal, setInternal] = useState(defaultChecked);
|
|
14
|
+
const isControlled = checked !== undefined;
|
|
15
|
+
const resolved = isControlled ? checked : internal;
|
|
16
|
+
const handleChange = (val) => {
|
|
17
|
+
if (!isControlled)
|
|
18
|
+
setInternal(val);
|
|
19
|
+
onCheckedChange?.(val);
|
|
20
|
+
};
|
|
21
|
+
const resolvedClassName = typeof className === 'function' ? className(resolved) : className;
|
|
22
|
+
return (_jsx(RadioContext, { value: { checked: resolved, onCheckedChange: handleChange, disabled }, children: _jsx("label", { style: style, className: cn('flex flex-row w-fit gap-2.5 shrink-0', disabled
|
|
23
|
+
? 'cursor-not-allowed pointer-events-none'
|
|
24
|
+
: 'cursor-pointer', resolvedClassName), children: children }) }));
|
|
25
|
+
};
|
|
26
|
+
const HiddenInput = ({ ref, onChange, ...props }) => {
|
|
27
|
+
const { checked, onCheckedChange, disabled } = useRadioContext();
|
|
28
|
+
return (_jsx("input", { type: "radio", ref: ref, className: "sr-only", checked: checked, disabled: disabled, onChange: (e) => {
|
|
29
|
+
e.stopPropagation();
|
|
30
|
+
onCheckedChange(e.target.checked);
|
|
31
|
+
onChange?.(e);
|
|
32
|
+
}, ...props }));
|
|
33
|
+
};
|
|
34
|
+
const Indicator = ({ icon = 'check', iconSize = 24, className, iconClassName, }) => {
|
|
35
|
+
return (_jsx("div", { className: className, children: _jsx(LucideIcon, { name: icon, size: iconSize, className: iconClassName }) }));
|
|
36
|
+
};
|
|
37
|
+
const Label = ({ className, children }) => {
|
|
38
|
+
return _jsx("span", { className: className, children: children });
|
|
39
|
+
};
|
|
40
|
+
export const RadioBase = {
|
|
41
|
+
Root,
|
|
42
|
+
HiddenInput,
|
|
43
|
+
Indicator,
|
|
44
|
+
Label,
|
|
45
|
+
};
|
|
46
|
+
export default RadioBase;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
export interface RadioGroupOption {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface RadioGroupProps {
|
|
8
|
+
items: RadioGroupOption[];
|
|
9
|
+
value?: string;
|
|
10
|
+
onChange?: (value: string) => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
type?: 'default' | 'pill';
|
|
13
|
+
size?: 'sm' | 'md';
|
|
14
|
+
name?: string;
|
|
15
|
+
'aria-invalid'?: boolean | 'true' | 'false';
|
|
16
|
+
'aria-describedby'?: string;
|
|
17
|
+
className?: string;
|
|
18
|
+
style?: React.CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
declare const RadioGroup: ({ items, value, onChange, disabled, type, size, name, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, className, style, }: RadioGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export default RadioGroup;
|
|
22
|
+
//# sourceMappingURL=RadioGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/Radio/RadioGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,QAAA,MAAM,UAAU,GAAI,6IAYjB,eAAe,4CAuBjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import Radio from './Radio.js';
|
|
3
|
+
import cn from '../../utils/cn.js';
|
|
4
|
+
const RadioGroup = ({ items, value, onChange, disabled = false, type = 'pill', size = 'sm', name, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedby, className, style, }) => {
|
|
5
|
+
return (_jsx("div", { role: "radiogroup", "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, className: cn('flex flex-row gap-2.5', className), style: style, children: items.map((option) => (_jsx(Radio, { name: name, type: type, size: size, checked: value === option.value, onCheckedChange: () => onChange?.(option.value), label: option.label, disabled: disabled || option.disabled }, option.value))) }));
|
|
6
|
+
};
|
|
7
|
+
export default RadioGroup;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
type ScrollDirection = 'x' | 'y' | 'both';
|
|
3
|
+
export interface ScrollAreaProps {
|
|
4
|
+
direction?: ScrollDirection;
|
|
5
|
+
/** true이면 스크롤바를 숨깁니다 */
|
|
6
|
+
hideScrollbar?: boolean;
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: React.CSSProperties;
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
/** 스크린리더에 전달할 영역 설명 */
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const ScrollArea: ({ direction, hideScrollbar, className, style, children, ariaLabel, }: ScrollAreaProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export default ScrollArea;
|
|
15
|
+
//# sourceMappingURL=ScrollArea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollArea.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollArea/ScrollArea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,KAAK,eAAe,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wBAAwB;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,QAAA,MAAM,UAAU,GAAI,sEAOjB,eAAe,4CAmBjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import cn from '../../utils/cn.js';
|
|
3
|
+
const DIRECTION_MAP = {
|
|
4
|
+
x: 'overflow-x-auto overflow-y-hidden',
|
|
5
|
+
y: 'overflow-y-auto overflow-x-hidden',
|
|
6
|
+
both: 'overflow-auto',
|
|
7
|
+
};
|
|
8
|
+
const ScrollArea = ({ direction = 'y', hideScrollbar = false, className, style, children, ariaLabel = '스크롤 가능한 영역', }) => (_jsx("div", { role: "region", "aria-label": ariaLabel, tabIndex: 0, className: cn('overflow-hidden outline-none', className), style: style, children: _jsx("div", { className: cn('h-full w-full', DIRECTION_MAP[direction], hideScrollbar &&
|
|
9
|
+
'[&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]'), children: children }) }));
|
|
10
|
+
export default ScrollArea;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RegisterOptions } from 'react-hook-form';
|
|
2
|
+
import { type MultiSelectProps } from './MultiSelect.js';
|
|
3
|
+
interface FormMultiSelectProps extends Omit<MultiSelectProps, 'value' | 'onChange' | 'color' | 'name'> {
|
|
4
|
+
block?: boolean;
|
|
5
|
+
name: string;
|
|
6
|
+
options?: RegisterOptions;
|
|
7
|
+
customErrorMessage?: string;
|
|
8
|
+
isHiddenErrorMessage?: boolean;
|
|
9
|
+
errorClassName?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const FormMultiSelect: ({ name, options, variant, size, block, disabled, customErrorMessage, isHiddenErrorMessage, errorClassName, ...props }: FormMultiSelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default FormMultiSelect;
|
|
13
|
+
//# sourceMappingURL=FormMultiSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormMultiSelect.d.ts","sourceRoot":"","sources":["../../../src/components/Select/FormMultiSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKnE,UAAU,oBAAqB,SAAQ,IAAI,CACzC,gBAAgB,EAChB,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CACxC;IACC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,QAAA,MAAM,eAAe,GAAI,uHAWtB,oBAAoB,4CAuCtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import MultiSelect from './MultiSelect.js';
|
|
4
|
+
import FormField from '../Form/FormField.js';
|
|
5
|
+
import FormErrorMessage from '../Form/FormErrorMessage.js';
|
|
6
|
+
import cn from '../../utils/cn.js';
|
|
7
|
+
const FormMultiSelect = ({ name, options, variant = 'filled', size = 'sm', block = false, disabled = false, customErrorMessage = '', isHiddenErrorMessage = false, errorClassName, ...props }) => {
|
|
8
|
+
return (_jsx(FormField, { name: name, options: options, customErrorMessage: customErrorMessage, disabled: disabled, children: ({ field, fieldState }) => (_jsxs("div", { className: cn('relative', block && 'flex flex-1'), children: [_jsx(MultiSelect, { ...props, name: name, value: Array.isArray(field.value)
|
|
9
|
+
? field.value
|
|
10
|
+
: field.value
|
|
11
|
+
? [field.value]
|
|
12
|
+
: [], onChange: field.onChange, "aria-invalid": field['aria-invalid'], "aria-describedby": field['aria-describedby'], variant: variant, color: fieldState.hasError ? 'danger' : 'neutral', size: size, disabled: disabled }), !isHiddenErrorMessage && (_jsx(FormErrorMessage, { error: fieldState.error, disabled: disabled, className: errorClassName }))] })) }));
|
|
13
|
+
};
|
|
14
|
+
export default FormMultiSelect;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RegisterOptions } from 'react-hook-form';
|
|
2
|
+
import { type SelectProps } from './Select.js';
|
|
3
|
+
interface FormSelectProps extends Omit<SelectProps, 'value' | 'onChange' | 'color' | 'name'> {
|
|
4
|
+
block?: boolean;
|
|
5
|
+
name: string;
|
|
6
|
+
options?: RegisterOptions;
|
|
7
|
+
customErrorMessage?: string;
|
|
8
|
+
isHiddenErrorMessage?: boolean;
|
|
9
|
+
errorClassName?: string;
|
|
10
|
+
}
|
|
11
|
+
declare const FormSelect: ({ name, options, variant, size, block, disabled, customErrorMessage, isHiddenErrorMessage, errorClassName, ...props }: FormSelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default FormSelect;
|
|
13
|
+
//# sourceMappingURL=FormSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSelect.d.ts","sourceRoot":"","sources":["../../../src/components/Select/FormSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAKpD,UAAU,eAAgB,SAAQ,IAAI,CACpC,WAAW,EACX,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CACxC;IACC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,QAAA,MAAM,UAAU,GAAI,uHAWjB,eAAe,4CAiCjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Select from './Select.js';
|
|
4
|
+
import FormField from '../Form/FormField.js';
|
|
5
|
+
import FormErrorMessage from '../Form/FormErrorMessage.js';
|
|
6
|
+
import cn from '../../utils/cn.js';
|
|
7
|
+
const FormSelect = ({ name, options, variant = 'filled', size = 'sm', block = false, disabled = false, customErrorMessage = '', isHiddenErrorMessage = false, errorClassName, ...props }) => {
|
|
8
|
+
return (_jsx(FormField, { name: name, options: options, customErrorMessage: customErrorMessage, disabled: disabled, children: ({ field, fieldState }) => (_jsxs("div", { className: cn('relative', block && 'flex flex-1'), children: [_jsx(Select, { ...props, name: name, value: field.value ?? '', onChange: field.onChange, "aria-invalid": field['aria-invalid'], "aria-describedby": field['aria-describedby'], variant: variant, color: fieldState.hasError ? 'danger' : 'neutral', size: size, disabled: disabled }), !isHiddenErrorMessage && (_jsx(FormErrorMessage, { error: fieldState.error, disabled: disabled, className: errorClassName }))] })) }));
|
|
9
|
+
};
|
|
10
|
+
export default FormSelect;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { type SelectOption } from './SelectBase.js';
|
|
3
|
+
type MultiSelectVariant = 'filled' | 'outline' | 'ghost';
|
|
4
|
+
type MultiSelectColor = 'neutral' | 'point' | 'danger';
|
|
5
|
+
type MultiSelectSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
6
|
+
export interface MultiSelectProps {
|
|
7
|
+
items: SelectOption[];
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
value?: string[];
|
|
10
|
+
onChange?: (value: string[]) => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
name?: string;
|
|
13
|
+
variant?: MultiSelectVariant;
|
|
14
|
+
color?: MultiSelectColor;
|
|
15
|
+
size?: MultiSelectSize;
|
|
16
|
+
maxDisplay?: number;
|
|
17
|
+
/**
|
|
18
|
+
* true(기본): "A, B 외 N개" 요약 텍스트로 표시 (X 삭제 없음).
|
|
19
|
+
* false: X 삭제 버튼이 달린 칩을 전체 나열.
|
|
20
|
+
*/
|
|
21
|
+
truncate?: boolean;
|
|
22
|
+
className?: string;
|
|
23
|
+
style?: React.CSSProperties;
|
|
24
|
+
contentClassName?: string;
|
|
25
|
+
'aria-invalid'?: boolean | 'true' | 'false';
|
|
26
|
+
'aria-describedby'?: string;
|
|
27
|
+
}
|
|
28
|
+
export type { SelectOption as MultiSelectOption };
|
|
29
|
+
declare const MultiSelect: ({ items, placeholder, value, onChange, disabled, name, variant, color, size, maxDisplay, truncate, className, style, contentClassName, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedby, }: MultiSelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export default MultiSelect;
|
|
31
|
+
//# sourceMappingURL=MultiSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiSelect.d.ts","sourceRoot":"","sources":["../../../src/components/Select/MultiSelect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAK7D,KAAK,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AACzD,KAAK,gBAAgB,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AACvD,KAAK,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAsDjD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,YAAY,EAAE,YAAY,IAAI,iBAAiB,EAAE,CAAC;AAElD,QAAA,MAAM,WAAW,GAAI,4MAiBlB,gBAAgB,4CA0HlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|