@loword/loword-design-system 0.0.2 → 0.0.3
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/dist/components/BreadCrumb/BreadCrumb.d.ts +17 -0
- package/dist/components/BreadCrumb/BreadCrumb.d.ts.map +1 -0
- package/dist/components/BreadCrumb/BreadCrumb.js +37 -0
- package/dist/components/BreadCrumb/BreadCrumbBase.d.ts +9 -0
- package/dist/components/BreadCrumb/BreadCrumbBase.d.ts.map +1 -0
- package/dist/components/BreadCrumb/BreadCrumbBase.js +17 -0
- package/dist/components/Button/ButtonSpinner.d.ts +1 -2
- package/dist/components/Button/ButtonSpinner.d.ts.map +1 -1
- package/dist/components/Button/ButtonSpinner.js +3 -2
- package/dist/components/Callout/Callout.d.ts +10 -0
- package/dist/components/Callout/Callout.d.ts.map +1 -0
- package/dist/components/Callout/Callout.js +6 -0
- package/dist/components/Callout/CalloutBase.d.ts +18 -0
- package/dist/components/Callout/CalloutBase.d.ts.map +1 -0
- package/dist/components/Callout/CalloutBase.js +21 -0
- package/dist/components/Divider/Divider.d.ts +9 -0
- package/dist/components/Divider/Divider.d.ts.map +1 -0
- package/dist/components/Divider/Divider.js +11 -0
- package/dist/components/Divider/DividerBase.d.ts +9 -0
- package/dist/components/Divider/DividerBase.d.ts.map +1 -0
- package/dist/components/Divider/DividerBase.js +9 -0
- package/dist/components/FileUpload/FileUploadBase.d.ts +5 -5
- package/dist/components/FileUpload/FileUploadBase.d.ts.map +1 -1
- package/dist/components/FileUpload/FileUploadBase.js +4 -4
- package/dist/components/Form/FormField.d.ts +2 -2
- package/dist/components/LDAvatar/AvatarBase.d.ts +32 -0
- package/dist/components/LDAvatar/AvatarBase.d.ts.map +1 -0
- package/dist/components/LDAvatar/AvatarBase.js +49 -0
- package/dist/components/LDAvatar/LDAvatar.d.ts +11 -0
- package/dist/components/LDAvatar/LDAvatar.d.ts.map +1 -0
- package/dist/components/LDAvatar/LDAvatar.js +24 -0
- package/dist/components/LDBadge/BadgeBase.d.ts +10 -0
- package/dist/components/LDBadge/BadgeBase.d.ts.map +1 -0
- package/dist/components/LDBadge/BadgeBase.js +9 -0
- package/dist/components/LDBadge/LDBadge.d.ts +25 -0
- package/dist/components/LDBadge/LDBadge.d.ts.map +1 -0
- package/dist/components/LDBadge/LDBadge.js +36 -0
- package/dist/components/LDBreadCrumb/BreadCrumbBase.d.ts +9 -0
- package/dist/components/LDBreadCrumb/BreadCrumbBase.d.ts.map +1 -0
- package/dist/components/LDBreadCrumb/BreadCrumbBase.js +17 -0
- package/dist/components/LDBreadCrumb/LDBreadCrumb.d.ts +17 -0
- package/dist/components/LDBreadCrumb/LDBreadCrumb.d.ts.map +1 -0
- package/dist/components/LDBreadCrumb/LDBreadCrumb.js +37 -0
- package/dist/components/LDButton/ButtonBase.d.ts +5 -0
- package/dist/components/LDButton/ButtonBase.d.ts.map +1 -0
- package/dist/components/LDButton/ButtonBase.js +10 -0
- package/dist/components/LDButton/ButtonSpinner.d.ts +8 -0
- package/dist/components/LDButton/ButtonSpinner.d.ts.map +1 -0
- package/dist/components/LDButton/ButtonSpinner.js +15 -0
- package/dist/components/LDButton/LDButton.d.ts +26 -0
- package/dist/components/LDButton/LDButton.d.ts.map +1 -0
- package/dist/components/LDButton/LDButton.js +102 -0
- package/dist/components/LDCalendar/LDCalendar.d.ts +16 -0
- package/dist/components/LDCalendar/LDCalendar.d.ts.map +1 -0
- package/dist/components/LDCalendar/LDCalendar.js +75 -0
- package/dist/components/LDCallout/CalloutBase.d.ts +18 -0
- package/dist/components/LDCallout/CalloutBase.d.ts.map +1 -0
- package/dist/components/LDCallout/CalloutBase.js +21 -0
- package/dist/components/LDCallout/LDCallout.d.ts +10 -0
- package/dist/components/LDCallout/LDCallout.d.ts.map +1 -0
- package/dist/components/LDCallout/LDCallout.js +6 -0
- package/dist/components/LDCarousel/CarouselBase.d.ts +98 -0
- package/dist/components/LDCarousel/CarouselBase.d.ts.map +1 -0
- package/dist/components/LDCarousel/CarouselBase.js +144 -0
- package/dist/components/LDCarousel/LDCarousel.d.ts +50 -0
- package/dist/components/LDCarousel/LDCarousel.d.ts.map +1 -0
- package/dist/components/LDCarousel/LDCarousel.js +22 -0
- package/dist/components/LDCheckbox/CheckboxBase.d.ts +40 -0
- package/dist/components/LDCheckbox/CheckboxBase.d.ts.map +1 -0
- package/dist/components/LDCheckbox/CheckboxBase.js +57 -0
- package/dist/components/LDCheckbox/FormCheckbox.d.ts +14 -0
- package/dist/components/LDCheckbox/FormCheckbox.d.ts.map +1 -0
- package/dist/components/LDCheckbox/FormCheckbox.js +9 -0
- package/dist/components/LDCheckbox/FormCheckboxGroup.d.ts +13 -0
- package/dist/components/LDCheckbox/FormCheckboxGroup.d.ts.map +1 -0
- package/dist/components/LDCheckbox/FormCheckboxGroup.js +9 -0
- package/dist/components/LDCheckbox/LDCheckbox.d.ts +27 -0
- package/dist/components/LDCheckbox/LDCheckbox.d.ts.map +1 -0
- package/dist/components/LDCheckbox/LDCheckbox.js +30 -0
- package/dist/components/LDCheckbox/LDCheckboxGroup.d.ts +22 -0
- package/dist/components/LDCheckbox/LDCheckboxGroup.d.ts.map +1 -0
- package/dist/components/LDCheckbox/LDCheckboxGroup.js +13 -0
- package/dist/components/LDDataCalendar/DataCalendarBase.d.ts +45 -0
- package/dist/components/LDDataCalendar/DataCalendarBase.d.ts.map +1 -0
- package/dist/components/LDDataCalendar/DataCalendarBase.js +57 -0
- package/dist/components/LDDataCalendar/LDDataCalendar.d.ts +12 -0
- package/dist/components/LDDataCalendar/LDDataCalendar.d.ts.map +1 -0
- package/dist/components/LDDataCalendar/LDDataCalendar.js +13 -0
- package/dist/components/LDDatePicker/FormDatePicker.d.ts +12 -0
- package/dist/components/LDDatePicker/FormDatePicker.d.ts.map +1 -0
- package/dist/components/LDDatePicker/FormDatePicker.js +12 -0
- package/dist/components/LDDatePicker/LDDatePicker.d.ts +34 -0
- package/dist/components/LDDatePicker/LDDatePicker.d.ts.map +1 -0
- package/dist/components/LDDatePicker/LDDatePicker.js +44 -0
- package/dist/components/LDDateRangePicker/FormDateRangePicker.d.ts +12 -0
- package/dist/components/LDDateRangePicker/FormDateRangePicker.d.ts.map +1 -0
- package/dist/components/LDDateRangePicker/FormDateRangePicker.js +10 -0
- package/dist/components/LDDateRangePicker/LDDateRangePicker.d.ts +49 -0
- package/dist/components/LDDateRangePicker/LDDateRangePicker.d.ts.map +1 -0
- package/dist/components/LDDateRangePicker/LDDateRangePicker.js +197 -0
- package/dist/components/LDDivider/DividerBase.d.ts +9 -0
- package/dist/components/LDDivider/DividerBase.d.ts.map +1 -0
- package/dist/components/LDDivider/DividerBase.js +9 -0
- package/dist/components/LDDivider/LDDivider.d.ts +9 -0
- package/dist/components/LDDivider/LDDivider.d.ts.map +1 -0
- package/dist/components/LDDivider/LDDivider.js +11 -0
- package/dist/components/LDDrawer/DrawerBase.d.ts +52 -0
- package/dist/components/LDDrawer/DrawerBase.d.ts.map +1 -0
- package/dist/components/LDDrawer/DrawerBase.js +38 -0
- package/dist/components/LDDrawer/LDDrawer.d.ts +51 -0
- package/dist/components/LDDrawer/LDDrawer.d.ts.map +1 -0
- package/dist/components/LDDrawer/LDDrawer.js +30 -0
- package/dist/components/LDEditor/EditorBase.d.ts +52 -0
- package/dist/components/LDEditor/EditorBase.d.ts.map +1 -0
- package/dist/components/LDEditor/EditorBase.js +89 -0
- package/dist/components/LDEditor/LDEditor.d.ts +12 -0
- package/dist/components/LDEditor/LDEditor.d.ts.map +1 -0
- package/dist/components/LDEditor/LDEditor.js +162 -0
- package/dist/components/LDEditor/LDViewer.d.ts +7 -0
- package/dist/components/LDEditor/LDViewer.d.ts.map +1 -0
- package/dist/components/LDEditor/LDViewer.js +9 -0
- package/dist/components/LDEditor/extensions.d.ts +6 -0
- package/dist/components/LDEditor/extensions.d.ts.map +1 -0
- package/dist/components/LDEditor/extensions.js +38 -0
- package/dist/components/LDInput/FormInput.d.ts +15 -0
- package/dist/components/LDInput/FormInput.d.ts.map +1 -0
- package/dist/components/LDInput/FormInput.js +19 -0
- package/dist/components/LDInput/InputBase.d.ts +22 -0
- package/dist/components/LDInput/InputBase.d.ts.map +1 -0
- package/dist/components/LDInput/InputBase.js +17 -0
- package/dist/components/LDInput/LDInput.d.ts +24 -0
- package/dist/components/LDInput/LDInput.d.ts.map +1 -0
- package/dist/components/LDInput/LDInput.js +71 -0
- package/dist/components/LDLoadingDots/LDLoadingDots.d.ts +8 -0
- package/dist/components/LDLoadingDots/LDLoadingDots.d.ts.map +1 -0
- package/dist/components/LDLoadingDots/LDLoadingDots.js +29 -0
- package/dist/components/LDMenuBar/LDMenuBar.d.ts +21 -0
- package/dist/components/LDMenuBar/LDMenuBar.d.ts.map +1 -0
- package/dist/components/LDMenuBar/LDMenuBar.js +33 -0
- package/dist/components/LDMenuBar/MenuBarBase.d.ts +43 -0
- package/dist/components/LDMenuBar/MenuBarBase.d.ts.map +1 -0
- package/dist/components/LDMenuBar/MenuBarBase.js +69 -0
- package/dist/components/LDModal/LDModal.d.ts +51 -0
- package/dist/components/LDModal/LDModal.d.ts.map +1 -0
- package/dist/components/LDModal/LDModal.js +72 -0
- package/dist/components/LDModal/ModalBase.d.ts +42 -0
- package/dist/components/LDModal/ModalBase.d.ts.map +1 -0
- package/dist/components/LDModal/ModalBase.js +30 -0
- package/dist/components/LDModal/openModal.d.ts +24 -0
- package/dist/components/LDModal/openModal.d.ts.map +1 -0
- package/dist/components/LDModal/openModal.js +52 -0
- package/dist/components/LDOTPInput/LDOTPInput.d.ts +46 -0
- package/dist/components/LDOTPInput/LDOTPInput.d.ts.map +1 -0
- package/dist/components/LDOTPInput/LDOTPInput.js +87 -0
- package/dist/components/LDPagination/LDPagination.d.ts +12 -0
- package/dist/components/LDPagination/LDPagination.d.ts.map +1 -0
- package/dist/components/LDPagination/LDPagination.js +5 -0
- package/dist/components/LDPagination/PaginationBase.d.ts +36 -0
- package/dist/components/LDPagination/PaginationBase.d.ts.map +1 -0
- package/dist/components/LDPagination/PaginationBase.js +44 -0
- package/dist/components/LDPagination/paginationUtils.d.ts +2 -0
- package/dist/components/LDPagination/paginationUtils.d.ts.map +1 -0
- package/dist/components/LDPagination/paginationUtils.js +18 -0
- package/dist/components/LDPopover/LDPopover.d.ts +42 -0
- package/dist/components/LDPopover/LDPopover.d.ts.map +1 -0
- package/dist/components/LDPopover/LDPopover.js +31 -0
- package/dist/components/LDPopover/PopoverBase.d.ts +31 -0
- package/dist/components/LDPopover/PopoverBase.d.ts.map +1 -0
- package/dist/components/LDPopover/PopoverBase.js +18 -0
- package/dist/components/LDRadio/FormRadioGroup.d.ts +13 -0
- package/dist/components/LDRadio/FormRadioGroup.d.ts.map +1 -0
- package/dist/components/LDRadio/FormRadioGroup.js +9 -0
- package/dist/components/LDRadio/LDRadio.d.ts +24 -0
- package/dist/components/LDRadio/LDRadio.d.ts.map +1 -0
- package/dist/components/LDRadio/LDRadio.js +39 -0
- package/dist/components/LDRadio/LDRadioGroup.d.ts +22 -0
- package/dist/components/LDRadio/LDRadioGroup.d.ts.map +1 -0
- package/dist/components/LDRadio/LDRadioGroup.js +7 -0
- package/dist/components/LDRadio/RadioBase.d.ts +38 -0
- package/dist/components/LDRadio/RadioBase.d.ts.map +1 -0
- package/dist/components/LDRadio/RadioBase.js +46 -0
- package/dist/components/LDScrollArea/LDScrollArea.d.ts +15 -0
- package/dist/components/LDScrollArea/LDScrollArea.d.ts.map +1 -0
- package/dist/components/LDScrollArea/LDScrollArea.js +10 -0
- package/dist/components/LDSelect/FormMultiSelect.d.ts +13 -0
- package/dist/components/LDSelect/FormMultiSelect.d.ts.map +1 -0
- package/dist/components/LDSelect/FormMultiSelect.js +14 -0
- package/dist/components/LDSelect/FormSelect.d.ts +13 -0
- package/dist/components/LDSelect/FormSelect.d.ts.map +1 -0
- package/dist/components/LDSelect/FormSelect.js +10 -0
- package/dist/components/LDSelect/LDMultiSelect.d.ts +31 -0
- package/dist/components/LDSelect/LDMultiSelect.d.ts.map +1 -0
- package/dist/components/LDSelect/LDMultiSelect.js +59 -0
- package/dist/components/LDSelect/LDSelect.d.ts +41 -0
- package/dist/components/LDSelect/LDSelect.d.ts.map +1 -0
- package/dist/components/LDSelect/LDSelect.js +55 -0
- package/dist/components/LDSelect/SelectBase.d.ts +59 -0
- package/dist/components/LDSelect/SelectBase.d.ts.map +1 -0
- package/dist/components/LDSelect/SelectBase.js +211 -0
- package/dist/components/LDSkeleton/LDSkeleton.d.ts +10 -0
- package/dist/components/LDSkeleton/LDSkeleton.d.ts.map +1 -0
- package/dist/components/LDSkeleton/LDSkeleton.js +8 -0
- package/dist/components/LDSlider/LDSlider.d.ts +23 -0
- package/dist/components/LDSlider/LDSlider.d.ts.map +1 -0
- package/dist/components/LDSlider/LDSlider.js +195 -0
- package/dist/components/LDSpinner/LDSpinner.d.ts +25 -0
- package/dist/components/LDSpinner/LDSpinner.d.ts.map +1 -0
- package/dist/components/LDSpinner/LDSpinner.js +20 -0
- package/dist/components/LDTable/LDTable.d.ts +34 -0
- package/dist/components/LDTable/LDTable.d.ts.map +1 -0
- package/dist/components/LDTable/LDTable.js +29 -0
- package/dist/components/LDTable/LDTanstackTable.d.ts +23 -0
- package/dist/components/LDTable/LDTanstackTable.d.ts.map +1 -0
- package/dist/components/LDTable/LDTanstackTable.js +35 -0
- package/dist/components/LDTable/TableBase.d.ts +37 -0
- package/dist/components/LDTable/TableBase.d.ts.map +1 -0
- package/dist/components/LDTable/TableBase.js +39 -0
- package/dist/components/LDTable/TableField.d.ts +64 -0
- package/dist/components/LDTable/TableField.d.ts.map +1 -0
- package/dist/components/LDTable/TableField.js +87 -0
- package/dist/components/LDTimePicker/FormTimePicker.d.ts +12 -0
- package/dist/components/LDTimePicker/FormTimePicker.d.ts.map +1 -0
- package/dist/components/LDTimePicker/FormTimePicker.js +12 -0
- package/dist/components/LDTimePicker/LDTimePicker.d.ts +27 -0
- package/dist/components/LDTimePicker/LDTimePicker.d.ts.map +1 -0
- package/dist/components/LDTimePicker/LDTimePicker.js +120 -0
- package/dist/components/LDToggleButton/FormToggleButton.d.ts +12 -0
- package/dist/components/LDToggleButton/FormToggleButton.d.ts.map +1 -0
- package/dist/components/LDToggleButton/FormToggleButton.js +9 -0
- package/dist/components/LDToggleButton/LDToggleButton.d.ts +31 -0
- package/dist/components/LDToggleButton/LDToggleButton.d.ts.map +1 -0
- package/dist/components/LDToggleButton/LDToggleButton.js +42 -0
- package/dist/components/LDToggleButton/ToggleButtonBase.d.ts +41 -0
- package/dist/components/LDToggleButton/ToggleButtonBase.d.ts.map +1 -0
- package/dist/components/LDToggleButton/ToggleButtonBase.js +59 -0
- package/dist/components/LDTooltip/LDTooltip.d.ts +18 -0
- package/dist/components/LDTooltip/LDTooltip.d.ts.map +1 -0
- package/dist/components/LDTooltip/LDTooltip.js +13 -0
- package/dist/components/LDTooltip/TooltipBase.d.ts +39 -0
- package/dist/components/LDTooltip/TooltipBase.d.ts.map +1 -0
- package/dist/components/LDTooltip/TooltipBase.js +46 -0
- package/dist/components/LNB/LNBBase.js +2 -2
- package/dist/components/Spinner/Spinner.d.ts +1 -1
- package/dist/components/Spinner/Spinner.d.ts.map +1 -1
- package/dist/components/Spinner/Spinner.js +1 -1
- package/dist/index.css +115 -13
- package/dist/index.d.ts +48 -45
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -75
- package/package.json +1 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useState, } from 'react';
|
|
4
|
+
import useEmblaCarousel from 'embla-carousel-react';
|
|
5
|
+
import Autoplay from 'embla-carousel-autoplay';
|
|
6
|
+
import AutoScroll from 'embla-carousel-auto-scroll';
|
|
7
|
+
import LucideIcon from '../Icon/LucideIcon.js';
|
|
8
|
+
import cn from '../../utils/cn.js';
|
|
9
|
+
const CarouselContext = createContext(null);
|
|
10
|
+
const useCarouselContext = () => {
|
|
11
|
+
const ctx = useContext(CarouselContext);
|
|
12
|
+
if (!ctx)
|
|
13
|
+
throw new Error('LDCarousel 하위 컴포넌트는 Root 내부에서 사용해야 합니다.');
|
|
14
|
+
return ctx;
|
|
15
|
+
};
|
|
16
|
+
/** 외부에서 캐러셀 컨트롤(emblaApi)에 접근하고 싶을 때 사용하는 훅 */
|
|
17
|
+
export const useCarousel = useCarouselContext;
|
|
18
|
+
const Root = ({ orientation = 'horizontal', loop = false, autoplay = false, autoScroll = false, align = 'start', options, gap = 16, className, style, children, }) => {
|
|
19
|
+
// 자동 이동 플러그인 조립. autoScroll(연속 흐름)이 설정되면 autoplay(스텝형)보다 우선.
|
|
20
|
+
const plugins = [];
|
|
21
|
+
if (autoScroll) {
|
|
22
|
+
const c = typeof autoScroll === 'object' ? autoScroll : {};
|
|
23
|
+
plugins.push(AutoScroll({
|
|
24
|
+
speed: c.speed ?? 2,
|
|
25
|
+
direction: c.direction ?? 'forward',
|
|
26
|
+
stopOnInteraction: c.stopOnInteraction ?? false,
|
|
27
|
+
stopOnMouseEnter: c.stopOnMouseEnter ?? false,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
else if (autoplay) {
|
|
31
|
+
const c = typeof autoplay === 'object' ? autoplay : {};
|
|
32
|
+
plugins.push(Autoplay({
|
|
33
|
+
delay: c.delay ?? 4000,
|
|
34
|
+
stopOnInteraction: c.stopOnInteraction ?? false,
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
const [emblaRef, emblaApi] = useEmblaCarousel({
|
|
38
|
+
...options,
|
|
39
|
+
align,
|
|
40
|
+
loop,
|
|
41
|
+
axis: orientation === 'vertical' ? 'y' : 'x',
|
|
42
|
+
}, plugins);
|
|
43
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
44
|
+
const [scrollSnaps, setScrollSnaps] = useState([]);
|
|
45
|
+
const [canScrollPrev, setCanScrollPrev] = useState(false);
|
|
46
|
+
const [canScrollNext, setCanScrollNext] = useState(false);
|
|
47
|
+
// 슬라이드 선택 변경시 실행되는 함수
|
|
48
|
+
const onSelect = useCallback((api) => {
|
|
49
|
+
setSelectedIndex(api.selectedScrollSnap());
|
|
50
|
+
setCanScrollPrev(api.canScrollPrev());
|
|
51
|
+
setCanScrollNext(api.canScrollNext());
|
|
52
|
+
}, []);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (!emblaApi)
|
|
55
|
+
return;
|
|
56
|
+
setScrollSnaps(emblaApi.scrollSnapList());
|
|
57
|
+
//슬라이드 초기 상태 설정
|
|
58
|
+
onSelect(emblaApi);
|
|
59
|
+
emblaApi.on('select', onSelect);
|
|
60
|
+
emblaApi.on('reInit', onSelect);
|
|
61
|
+
emblaApi.on('reInit', () => setScrollSnaps(emblaApi.scrollSnapList()));
|
|
62
|
+
return () => {
|
|
63
|
+
//클린업 함수
|
|
64
|
+
emblaApi.off('select', onSelect);
|
|
65
|
+
emblaApi.off('reInit', onSelect);
|
|
66
|
+
};
|
|
67
|
+
}, [emblaApi, onSelect]);
|
|
68
|
+
const scrollPrev = useCallback(() => emblaApi?.scrollPrev(), [emblaApi]);
|
|
69
|
+
const scrollNext = useCallback(() => emblaApi?.scrollNext(), [emblaApi]);
|
|
70
|
+
const scrollTo = useCallback((index) => emblaApi?.scrollTo(index), [emblaApi]);
|
|
71
|
+
return (_jsx(CarouselContext.Provider, { value: {
|
|
72
|
+
emblaRef,
|
|
73
|
+
emblaApi,
|
|
74
|
+
selectedIndex,
|
|
75
|
+
scrollSnaps,
|
|
76
|
+
canScrollPrev,
|
|
77
|
+
canScrollNext,
|
|
78
|
+
scrollPrev,
|
|
79
|
+
scrollNext,
|
|
80
|
+
scrollTo,
|
|
81
|
+
orientation,
|
|
82
|
+
gap,
|
|
83
|
+
}, children: _jsx("div", { className: cn('ld-carousel relative', className), style: style, role: "region", "aria-roledescription": "carousel", children: children }) }));
|
|
84
|
+
};
|
|
85
|
+
const Viewport = ({ className, children }) => {
|
|
86
|
+
const { emblaRef } = useCarouselContext();
|
|
87
|
+
return (_jsx("div", { ref: emblaRef, className: cn('ld-carousel__viewport', className), children: children }));
|
|
88
|
+
};
|
|
89
|
+
const Container = ({ className, style, children }) => {
|
|
90
|
+
const { orientation, gap } = useCarouselContext();
|
|
91
|
+
const isVertical = orientation === 'vertical';
|
|
92
|
+
return (_jsx("div", { className: cn('flex', isVertical ? 'flex-col h-full' : 'flex-row', className),
|
|
93
|
+
// embla 공식 방식: 간격을 Slide 패딩으로 주고, 첫 칸 패딩만 음수 마진으로 상쇄.
|
|
94
|
+
// flex gap과 달리 loop 이음새(마지막↔처음)에도 간격이 유지됨.
|
|
95
|
+
style: {
|
|
96
|
+
[isVertical ? 'marginTop' : 'marginLeft']: -gap,
|
|
97
|
+
...style,
|
|
98
|
+
}, children: children }));
|
|
99
|
+
};
|
|
100
|
+
const Slide = ({ size = '100%', index, total, className, style, children, }) => {
|
|
101
|
+
const { orientation, gap } = useCarouselContext();
|
|
102
|
+
const isVertical = orientation === 'vertical';
|
|
103
|
+
return (_jsx("div", { role: "group", "aria-roledescription": "slide", "aria-label": index != null && total != null ? `${index + 1} / ${total}` : undefined, className: cn('min-w-0 shrink-0 grow-0', className),
|
|
104
|
+
// 간격을 슬라이드 박스의 패딩으로 포함시켜야 embla가 크기를 정확히 재고
|
|
105
|
+
// loop 이음새에도 간격이 유지된다 (embla 공식 방식).
|
|
106
|
+
style: {
|
|
107
|
+
flexBasis: size,
|
|
108
|
+
[isVertical ? 'height' : 'width']: size,
|
|
109
|
+
[isVertical ? 'paddingTop' : 'paddingLeft']: gap,
|
|
110
|
+
...style,
|
|
111
|
+
}, children: children }));
|
|
112
|
+
};
|
|
113
|
+
const Prev = ({ className, children, ...props }) => {
|
|
114
|
+
const { scrollPrev, canScrollPrev, orientation } = useCarouselContext();
|
|
115
|
+
return (_jsx("button", { type: "button", onClick: scrollPrev, disabled: !canScrollPrev, "aria-label": props['aria-label'] ?? '이전', className: cn('ld-carousel__nav inline-flex items-center justify-center rounded-full bg-mono50 border border-mono200 w-9 h-9 ld-transition', 'hover:bg-neutral50 disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer', className), children: children ?? (_jsx(LucideIcon, { name: orientation === 'vertical' ? 'chevronUp' : 'chevronLeft', size: 18, className: "text-neutral900" })) }));
|
|
116
|
+
};
|
|
117
|
+
const Next = ({ className, children, ...props }) => {
|
|
118
|
+
const { scrollNext, canScrollNext, orientation } = useCarouselContext();
|
|
119
|
+
return (_jsx("button", { type: "button", onClick: scrollNext, disabled: !canScrollNext, "aria-label": props['aria-label'] ?? '다음', className: cn('ld-carousel__nav inline-flex items-center justify-center rounded-full bg-mono50 border border-mono200 w-9 h-9 ld-transition', 'hover:bg-neutral50 disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer', className), children: children ?? (_jsx(LucideIcon, { name: orientation === 'vertical' ? 'chevronDown' : 'chevronRight', size: 18, className: "text-neutral900" })) }));
|
|
120
|
+
};
|
|
121
|
+
const Dots = ({ className, dotClassName }) => {
|
|
122
|
+
const { scrollSnaps, selectedIndex, scrollTo } = useCarouselContext();
|
|
123
|
+
return (_jsx("div", { className: cn('flex items-center justify-center gap-2', className), children: scrollSnaps.map((_, i) => {
|
|
124
|
+
const isActive = i === selectedIndex;
|
|
125
|
+
return (_jsx("button", { type: "button", onClick: () => scrollTo(i), "aria-label": `${i + 1}번째 슬라이드로 이동`, "aria-current": isActive || undefined, className: cn('rounded-full ld-transition cursor-pointer', isActive ? 'w-5 h-2 bg-lb500' : 'w-2 h-2 bg-mono200', dotClassName) }, i));
|
|
126
|
+
}) }));
|
|
127
|
+
};
|
|
128
|
+
const Counter = ({ className, format }) => {
|
|
129
|
+
const { selectedIndex, scrollSnaps } = useCarouselContext();
|
|
130
|
+
const current = selectedIndex + 1;
|
|
131
|
+
const total = scrollSnaps.length;
|
|
132
|
+
return (_jsx("span", { "aria-live": "polite", className: cn('display14 regular text-neutral500', className), children: format ? format(current, total) : `${current} / ${total}` }));
|
|
133
|
+
};
|
|
134
|
+
export const CarouselBase = {
|
|
135
|
+
Root,
|
|
136
|
+
Viewport,
|
|
137
|
+
Container,
|
|
138
|
+
Slide,
|
|
139
|
+
Prev,
|
|
140
|
+
Next,
|
|
141
|
+
Dots,
|
|
142
|
+
Counter,
|
|
143
|
+
};
|
|
144
|
+
export default CarouselBase;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
import { type CarouselOrientation, type RootProps } from './CarouselBase.js';
|
|
3
|
+
export interface LDCarouselProps {
|
|
4
|
+
/** 슬라이드로 렌더링할 노드 배열 */
|
|
5
|
+
slides: ReactNode[];
|
|
6
|
+
/** 가로/세로 방향. 기본 'horizontal' */
|
|
7
|
+
orientation?: CarouselOrientation;
|
|
8
|
+
/** 무한 루프. 기본 false */
|
|
9
|
+
loop?: boolean;
|
|
10
|
+
/** 자동재생(스텝형). true 또는 { delay, stopOnInteraction } */
|
|
11
|
+
autoplay?: boolean | {
|
|
12
|
+
delay?: number;
|
|
13
|
+
stopOnInteraction?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/** 연속 흐름(Auto Scroll). autoplay와 동시 사용 불가, loop와 함께 권장 */
|
|
16
|
+
autoScroll?: RootProps['autoScroll'];
|
|
17
|
+
/** 슬라이드 정렬 위치. 기본 'start'(왼쪽 끝 붙음) */
|
|
18
|
+
align?: RootProps['align'];
|
|
19
|
+
/** 이전/다음 화살표 표시. 기본 true */
|
|
20
|
+
showArrows?: boolean;
|
|
21
|
+
/** 하단 도트 페이지네이션 표시. 기본 true */
|
|
22
|
+
showDots?: boolean;
|
|
23
|
+
/** "현재 / 전체" 숫자 표시. 기본 false */
|
|
24
|
+
showCounter?: boolean;
|
|
25
|
+
/** 슬라이드 한 개의 크기(basis). 기본 '100%' */
|
|
26
|
+
slideSize?: string;
|
|
27
|
+
/** 슬라이드 사이 간격(Tailwind gap 단위 px). 기본 16 */
|
|
28
|
+
gap?: number;
|
|
29
|
+
className?: string;
|
|
30
|
+
style?: CSSProperties;
|
|
31
|
+
/** Viewport에 적용할 클래스 (세로 모드 높이 지정 등) */
|
|
32
|
+
viewportClassName?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* embla-carousel 기반 기본 캐러셀.
|
|
36
|
+
* 고급 커스터마이징이 필요하면 `LDCarousel.Root` 등 compound API를 직접 조합하세요.
|
|
37
|
+
*/
|
|
38
|
+
declare const LDCarousel: {
|
|
39
|
+
({ slides, orientation, loop, autoplay, autoScroll, align, showArrows, showDots, showCounter, slideSize, gap, className, style, viewportClassName, }: LDCarouselProps): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
Root: ({ orientation, loop, autoplay, autoScroll, align, options, gap, className, style, children, }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
Viewport: ({ className, children }: import("./CarouselBase.js").ViewportProps) => import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
Container: ({ className, style, children }: import("./CarouselBase.js").ContainerProps) => import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
Slide: ({ size, index, total, className, style, children, }: import("./CarouselBase.js").SlideProps) => import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
Prev: ({ className, children, ...props }: import("./CarouselBase.js").NavButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
Next: ({ className, children, ...props }: import("./CarouselBase.js").NavButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
Dots: ({ className, dotClassName }: import("./CarouselBase.js").DotsProps) => import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
Counter: ({ className, format }: import("./CarouselBase.js").CounterProps) => import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
};
|
|
49
|
+
export default LDCarousel;
|
|
50
|
+
//# sourceMappingURL=LDCarousel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDCarousel.d.ts","sourceRoot":"","sources":["../../../src/components/LDCarousel/LDCarousel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAqB,EACnB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gCAAgC;IAChC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,sBAAsB;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrE,0DAA0D;IAC1D,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,sCAAsC;IACtC,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3B,4BAA4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,wCAAwC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,QAAA,MAAM,UAAU;0JAeb,eAAe;;;;;;;;;CAuDjB,CAAC;AAWF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import CarouselBase from './CarouselBase.js';
|
|
4
|
+
import cn from '../../utils/cn.js';
|
|
5
|
+
/**
|
|
6
|
+
* embla-carousel 기반 기본 캐러셀.
|
|
7
|
+
* 고급 커스터마이징이 필요하면 `LDCarousel.Root` 등 compound API를 직접 조합하세요.
|
|
8
|
+
*/
|
|
9
|
+
const LDCarousel = ({ slides, orientation = 'horizontal', loop = false, autoplay = false, autoScroll = false, align = 'start', showArrows = true, showDots = true, showCounter = false, slideSize = '100%', gap = 16, className, style, viewportClassName, }) => {
|
|
10
|
+
const isVertical = orientation === 'vertical';
|
|
11
|
+
const total = slides.length;
|
|
12
|
+
return (_jsx(CarouselBase.Root, { orientation: orientation, loop: loop, autoplay: autoplay, autoScroll: autoScroll, align: align, gap: gap, className: className, style: style, children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: cn('flex items-center gap-3 w-full', isVertical && 'flex-col'), children: [showArrows && _jsx(CarouselBase.Prev, {}), _jsx(CarouselBase.Viewport, { className: cn('w-full', viewportClassName), children: _jsx(CarouselBase.Container, { children: slides.map((slide, i) => (_jsx(CarouselBase.Slide, { size: slideSize, index: i, total: total, children: slide }, i))) }) }), showArrows && _jsx(CarouselBase.Next, {})] }), (showDots || showCounter) && (_jsxs("div", { className: "flex items-center justify-center gap-3", children: [showDots && (_jsx(CarouselBase.Dots, { className: isVertical ? 'flex-col' : undefined })), showCounter && _jsx(CarouselBase.Counter, {})] }))] }) }));
|
|
13
|
+
};
|
|
14
|
+
LDCarousel.Root = CarouselBase.Root;
|
|
15
|
+
LDCarousel.Viewport = CarouselBase.Viewport;
|
|
16
|
+
LDCarousel.Container = CarouselBase.Container;
|
|
17
|
+
LDCarousel.Slide = CarouselBase.Slide;
|
|
18
|
+
LDCarousel.Prev = CarouselBase.Prev;
|
|
19
|
+
LDCarousel.Next = CarouselBase.Next;
|
|
20
|
+
LDCarousel.Dots = CarouselBase.Dots;
|
|
21
|
+
LDCarousel.Counter = CarouselBase.Counter;
|
|
22
|
+
export default LDCarousel;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ReactNode, type Ref } from 'react';
|
|
2
|
+
import { type IconName } from '../Icon/LucideIcon.js';
|
|
3
|
+
interface CheckboxContextType {
|
|
4
|
+
checked: boolean;
|
|
5
|
+
onCheckedChange: (checked: boolean) => void;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
isFocused: boolean;
|
|
8
|
+
setIsFocused: (focused: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const useCheckboxContext: () => CheckboxContextType;
|
|
11
|
+
interface RootProps {
|
|
12
|
+
checked?: boolean;
|
|
13
|
+
defaultChecked?: boolean;
|
|
14
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
className?: string | ((checked: boolean) => string);
|
|
17
|
+
style?: React.CSSProperties;
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
}
|
|
20
|
+
interface HiddenInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
21
|
+
ref?: Ref<HTMLInputElement>;
|
|
22
|
+
}
|
|
23
|
+
interface IndicatorProps {
|
|
24
|
+
icon?: IconName;
|
|
25
|
+
iconSize?: number;
|
|
26
|
+
className?: string;
|
|
27
|
+
iconClassName?: string;
|
|
28
|
+
}
|
|
29
|
+
interface LabelProps {
|
|
30
|
+
className?: string;
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
export declare const CheckboxBase: {
|
|
34
|
+
Root: ({ checked, defaultChecked, onCheckedChange, disabled, className, style, children, }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
HiddenInput: ({ ref, onFocus, onBlur, onChange, ...props }: HiddenInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
Indicator: ({ icon, iconSize, className, iconClassName, }: IndicatorProps) => import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
Label: ({ className, children }: LabelProps) => import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
};
|
|
39
|
+
export default CheckboxBase;
|
|
40
|
+
//# sourceMappingURL=CheckboxBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckboxBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDCheckbox/CheckboxBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,GAAG,EAIT,MAAM,OAAO,CAAC;AACf,OAAmB,EAAE,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAI/D,UAAU,mBAAmB;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C;AAID,eAAO,MAAM,kBAAkB,2BAO9B,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;AAiDD,UAAU,gBAAiB,SAAQ,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC;IAC5E,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAqCD,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,YAAY;gGA5GtB,SAAS;gEAiDT,gBAAgB;+DAyChB,cAAc;qCAcuB,UAAU;CASjD,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
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 CheckboxContext = createContext(null);
|
|
6
|
+
export const useCheckboxContext = () => {
|
|
7
|
+
const ctx = useContext(CheckboxContext);
|
|
8
|
+
if (!ctx)
|
|
9
|
+
throw new Error('CheckboxBase 하위 컴포넌트는 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 [isFocused, setIsFocused] = useState(false);
|
|
15
|
+
const isControlled = checked !== undefined;
|
|
16
|
+
const resolved = isControlled ? checked : internal;
|
|
17
|
+
const handleChange = (val) => {
|
|
18
|
+
if (!isControlled)
|
|
19
|
+
setInternal(val);
|
|
20
|
+
onCheckedChange?.(val);
|
|
21
|
+
};
|
|
22
|
+
const resolvedClassName = typeof className === 'function' ? className(resolved) : className;
|
|
23
|
+
return (_jsx(CheckboxContext, { value: {
|
|
24
|
+
checked: resolved,
|
|
25
|
+
onCheckedChange: handleChange,
|
|
26
|
+
disabled,
|
|
27
|
+
isFocused,
|
|
28
|
+
setIsFocused,
|
|
29
|
+
}, children: _jsx("label", { style: style, onClick: (e) => e.stopPropagation(), className: cn('flex flex-row w-fit gap-2.5 shrink-0', disabled ? 'cursor-not-allowed' : 'cursor-pointer', resolvedClassName), children: children }) }));
|
|
30
|
+
};
|
|
31
|
+
const HiddenInput = ({ ref, onFocus, onBlur, onChange, ...props }) => {
|
|
32
|
+
const { checked, onCheckedChange, disabled, setIsFocused } = useCheckboxContext();
|
|
33
|
+
return (_jsx("input", { type: "checkbox", ref: ref, className: "sr-only peer", checked: checked, disabled: disabled, onChange: (e) => {
|
|
34
|
+
e.stopPropagation(); // 이벤트 전파 중단
|
|
35
|
+
onCheckedChange(e.target.checked);
|
|
36
|
+
onChange?.(e);
|
|
37
|
+
}, onFocus: (e) => {
|
|
38
|
+
setIsFocused(true);
|
|
39
|
+
onFocus?.(e);
|
|
40
|
+
}, onBlur: (e) => {
|
|
41
|
+
setIsFocused(false);
|
|
42
|
+
onBlur?.(e);
|
|
43
|
+
}, ...props }));
|
|
44
|
+
};
|
|
45
|
+
const Indicator = ({ icon = 'check', iconSize = 24, className, iconClassName, }) => {
|
|
46
|
+
return (_jsx("div", { className: className, children: _jsx(LucideIcon, { name: icon, size: iconSize, className: iconClassName }) }));
|
|
47
|
+
};
|
|
48
|
+
const Label = ({ className, children }) => {
|
|
49
|
+
return _jsx("span", { className: className, children: children });
|
|
50
|
+
};
|
|
51
|
+
export const CheckboxBase = {
|
|
52
|
+
Root,
|
|
53
|
+
HiddenInput,
|
|
54
|
+
Indicator,
|
|
55
|
+
Label,
|
|
56
|
+
};
|
|
57
|
+
export default CheckboxBase;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Ref } from 'react';
|
|
2
|
+
import { type RegisterOptions } from 'react-hook-form';
|
|
3
|
+
import { type LDCheckboxProps } from './LDCheckbox.js';
|
|
4
|
+
interface FormCheckboxProps extends Omit<LDCheckboxProps, 'checked' | 'name' | 'onCheckedChange'> {
|
|
5
|
+
name: string;
|
|
6
|
+
options?: RegisterOptions;
|
|
7
|
+
ref?: Ref<HTMLInputElement>;
|
|
8
|
+
customErrorMessage?: string;
|
|
9
|
+
isHiddenErrorMessage?: boolean;
|
|
10
|
+
errorClassName?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const FormCheckbox: ({ name, options, ref, customErrorMessage, isHiddenErrorMessage, errorClassName, disabled, ...props }: FormCheckboxProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export default FormCheckbox;
|
|
14
|
+
//# sourceMappingURL=FormCheckbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormCheckbox.d.ts","sourceRoot":"","sources":["../../../src/components/LDCheckbox/FormCheckbox.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAIhE,UAAU,iBAAkB,SAAQ,IAAI,CACtC,eAAe,EACf,SAAS,GAAG,MAAM,GAAG,iBAAiB,CACvC;IACC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,QAAA,MAAM,YAAY,GAAI,sGASnB,iBAAiB,4CA8BnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import LDCheckbox from './LDCheckbox.js';
|
|
4
|
+
import FormField from '../Form/FormField.js';
|
|
5
|
+
import FormErrorMessage from '../Form/FormErrorMessage.js';
|
|
6
|
+
const FormCheckbox = ({ name, options, ref, customErrorMessage = '', isHiddenErrorMessage = false, errorClassName, disabled = false, ...props }) => {
|
|
7
|
+
return (_jsx(FormField, { name: name, options: options, customErrorMessage: customErrorMessage, disabled: disabled, ref: ref, children: ({ field, fieldState }) => (_jsxs("div", { className: "relative", children: [_jsx(LDCheckbox, { ...props, checked: !!field.value, onCheckedChange: field.onChange, onBlur: field.onBlur, disabled: disabled, ref: field.ref }), !isHiddenErrorMessage && (_jsx(FormErrorMessage, { error: fieldState.error, disabled: disabled, className: errorClassName }))] })) }));
|
|
8
|
+
};
|
|
9
|
+
export default FormCheckbox;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type RegisterOptions } from 'react-hook-form';
|
|
2
|
+
import { type LDCheckboxGroupProps } from './LDCheckboxGroup.js';
|
|
3
|
+
interface FormCheckboxGroupProps extends Omit<LDCheckboxGroupProps, 'value' | 'onChange'> {
|
|
4
|
+
name: string;
|
|
5
|
+
options?: RegisterOptions;
|
|
6
|
+
customErrorMessage?: string;
|
|
7
|
+
isHiddenErrorMessage?: boolean;
|
|
8
|
+
errorClassName?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const FormCheckboxGroup: ({ name, options, customErrorMessage, isHiddenErrorMessage, errorClassName, disabled, ...props }: FormCheckboxGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default FormCheckboxGroup;
|
|
13
|
+
//# sourceMappingURL=FormCheckboxGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormCheckboxGroup.d.ts","sourceRoot":"","sources":["../../../src/components/LDCheckbox/FormCheckboxGroup.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAwB,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAI/E,UAAU,sBAAuB,SAAQ,IAAI,CAC3C,oBAAoB,EACpB,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,iBAAiB,GAAI,iGAQxB,sBAAsB,4CA2BxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import LDCheckboxGroup from './LDCheckboxGroup.js';
|
|
4
|
+
import FormField from '../Form/FormField.js';
|
|
5
|
+
import FormErrorMessage from '../Form/FormErrorMessage.js';
|
|
6
|
+
const FormCheckboxGroup = ({ 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(LDCheckboxGroup, { ...props, value: field.value ?? [], onChange: field.onChange, disabled: disabled }), !isHiddenErrorMessage && (_jsx(FormErrorMessage, { error: fieldState.error, disabled: disabled, className: errorClassName }))] })) }));
|
|
8
|
+
};
|
|
9
|
+
export default FormCheckboxGroup;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type InputHTMLAttributes, type Ref } from 'react';
|
|
2
|
+
type CheckboxSize = 'small';
|
|
3
|
+
type CheckboxFontSize = 'small' | 'regular';
|
|
4
|
+
type CheckboxType = 'default' | 'checkbox' | 'pill';
|
|
5
|
+
export interface LDCheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size' | 'value'> {
|
|
6
|
+
/** 체크 상태 변경 콜백 (boolean) */
|
|
7
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
8
|
+
/** input value */
|
|
9
|
+
value?: string;
|
|
10
|
+
/** 체크 아이콘 크기 프리셋 */
|
|
11
|
+
size?: CheckboxSize;
|
|
12
|
+
/** 라벨 텍스트 크기 프리셋 */
|
|
13
|
+
fontSize?: CheckboxFontSize;
|
|
14
|
+
/** 라벨 텍스트 */
|
|
15
|
+
label?: string;
|
|
16
|
+
/** '필수' 라벨 표시 여부 */
|
|
17
|
+
isRequired?: boolean;
|
|
18
|
+
/** 체크박스 유형 (default: 체크 아이콘, checkbox: 박스형, pill: 알약형 토글) */
|
|
19
|
+
type?: CheckboxType;
|
|
20
|
+
/** 라벨과 체크박스 세로 가운데 정렬 */
|
|
21
|
+
itemCenter?: boolean;
|
|
22
|
+
/** input 요소 ref */
|
|
23
|
+
ref?: Ref<HTMLInputElement>;
|
|
24
|
+
}
|
|
25
|
+
declare const LDCheckbox: ({ checked, defaultChecked, onCheckedChange, onChange, size, fontSize, label, isRequired, type, itemCenter, disabled, className, style, ref, ...props }: LDCheckboxProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export default LDCheckbox;
|
|
27
|
+
//# sourceMappingURL=LDCheckbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDCheckbox.d.ts","sourceRoot":"","sources":["../../../src/components/LDCheckbox/LDCheckbox.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAK3D,KAAK,YAAY,GAAG,OAAO,CAAC;AAC5B,KAAK,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AAC5C,KAAK,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAiBpD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,MAAM,GAAG,MAAM,GAAG,OAAO,CAC1B;IACC,4BAA4B;IAC5B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,aAAa;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6DAA6D;IAC7D,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,yBAAyB;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AA8FD,QAAA,MAAM,UAAU,GAAI,wJAgBjB,eAAe,4CAgDjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import CheckboxBase, { useCheckboxContext } from './CheckboxBase.js';
|
|
3
|
+
import cn from '../../utils/cn.js';
|
|
4
|
+
const checkIconSizes = {
|
|
5
|
+
small: 24,
|
|
6
|
+
};
|
|
7
|
+
const labelHeight = {
|
|
8
|
+
small: 'min-h-6 leading-6',
|
|
9
|
+
};
|
|
10
|
+
const labelSizeClasses = {
|
|
11
|
+
small: 'display14',
|
|
12
|
+
regular: 'display16',
|
|
13
|
+
};
|
|
14
|
+
// ── Inner: Context에서 checked를 읽어 스타일 적용 ──
|
|
15
|
+
const PillInner = ({ label, ref, ...props }) => {
|
|
16
|
+
const { checked } = useCheckboxContext();
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsx(CheckboxBase.HiddenInput, { ref: ref, ...props }), _jsxs("div", { className: "relative flex items-center", children: [_jsx(CheckboxBase.Indicator, { icon: "check", iconSize: 16, className: cn('absolute left-0'), iconClassName: cn('shrink-0 transition-all duration-200 ease-out', checked ? 'opacity-100' : 'opacity-0') }), label && (_jsx(CheckboxBase.Label, { className: cn('transition-all ld-transition text-nowrap', checked ? 'pl-5' : 'pl-sm pr-sm'), children: label }))] })] }));
|
|
18
|
+
};
|
|
19
|
+
const DefaultInner = ({ type, size, label, isRequired, ref, ...props }) => {
|
|
20
|
+
const { checked, disabled } = useCheckboxContext();
|
|
21
|
+
return (_jsxs(_Fragment, { children: [_jsx(CheckboxBase.HiddenInput, { ref: ref, ...props }), _jsx(CheckboxBase.Indicator, { icon: "check", iconSize: type === 'checkbox' ? 10 : checkIconSizes[size], className: cn('ld-transition', type === 'checkbox' &&
|
|
22
|
+
'border-2 rounded-[5px] border-mono300 p-[3px]', type === 'checkbox' && checked && 'bg-lb500 border-lb500', type === 'checkbox' && disabled && 'bg-mono100 border-mono100', 'peer-focus-visible:ring-2 peer-focus-visible:ring-lb500 peer-focus-visible:ring-offset-2'), iconClassName: cn('shrink-0', checked ? 'ld-transition text-blue400' : 'text-neutral500', type === 'checkbox' && 'text-white') }), isRequired && (_jsx(CheckboxBase.Label, { className: cn('text-blue400 shrink-0 block', labelHeight[size]), children: "\uD544\uC218" })), label && (_jsx(CheckboxBase.Label, { className: cn('text-neutral900 block', labelHeight[size]), children: label }))] }));
|
|
23
|
+
};
|
|
24
|
+
const LDCheckbox = ({ checked, defaultChecked, onCheckedChange, onChange, size = 'small', fontSize = 'small', label, isRequired = false, type = 'default', itemCenter = false, disabled = false, className, style, ref, ...props }) => {
|
|
25
|
+
if (type === 'pill') {
|
|
26
|
+
return (_jsx(CheckboxBase.Root, { checked: checked, defaultChecked: defaultChecked, onCheckedChange: onCheckedChange, disabled: disabled, style: style, 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, onChange: onChange, ...props }) }));
|
|
27
|
+
}
|
|
28
|
+
return (_jsx(CheckboxBase.Root, { checked: checked, defaultChecked: defaultChecked, onCheckedChange: onCheckedChange, disabled: disabled, style: style, className: cn('bold items-start ld-transition', itemCenter && 'items-center', labelSizeClasses[fontSize], className), children: _jsx(DefaultInner, { type: type, size: size, label: label, isRequired: isRequired, ref: ref, onChange: onChange, ...props }) }));
|
|
29
|
+
};
|
|
30
|
+
export default LDCheckbox;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
export interface CheckboxGroupOption {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
sub?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface LDCheckboxGroupProps {
|
|
9
|
+
items: CheckboxGroupOption[];
|
|
10
|
+
value?: string[];
|
|
11
|
+
onChange?: (value: string[]) => void;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
type?: 'default' | 'checkbox' | 'pill';
|
|
14
|
+
size?: 'small';
|
|
15
|
+
fontSize?: 'small' | 'regular';
|
|
16
|
+
orientation?: 'horizontal' | 'vertical';
|
|
17
|
+
className?: string;
|
|
18
|
+
style?: React.CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
declare const LDCheckboxGroup: ({ items, value, onChange, disabled, type, size, fontSize, orientation, className, style, }: LDCheckboxGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export default LDCheckboxGroup;
|
|
22
|
+
//# sourceMappingURL=LDCheckboxGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDCheckboxGroup.d.ts","sourceRoot":"","sources":["../../../src/components/LDCheckbox/LDCheckboxGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,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,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,QAAA,MAAM,eAAe,GAAI,4FAWtB,oBAAoB,4CA+BtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import LDCheckbox from './LDCheckbox.js';
|
|
3
|
+
import cn from '../../utils/cn.js';
|
|
4
|
+
const LDCheckboxGroup = ({ items, value = [], onChange, disabled = false, type = 'pill', size = 'small', fontSize = 'small', orientation = 'horizontal', className, style, }) => {
|
|
5
|
+
const handleChange = (target) => {
|
|
6
|
+
const arr = value.includes(target)
|
|
7
|
+
? value.filter((v) => v !== target)
|
|
8
|
+
: [...value, target];
|
|
9
|
+
onChange?.(arr);
|
|
10
|
+
};
|
|
11
|
+
return (_jsx("div", { className: cn('flex gap-2.5', orientation === 'vertical' ? 'flex-col' : 'flex-row', className), style: style, children: items.map((option) => (_jsx(LDCheckbox, { type: type, size: size, fontSize: fontSize, checked: value.includes(option.value), onCheckedChange: () => handleChange(option.value), label: option.label, disabled: disabled || option.disabled }, option.value))) }));
|
|
12
|
+
};
|
|
13
|
+
export default LDCheckboxGroup;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type Dayjs } from 'dayjs';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
interface DataCalendarContextType {
|
|
4
|
+
month: Dayjs;
|
|
5
|
+
changeMonth: (delta: number) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const useDataCalendarContext: () => DataCalendarContextType;
|
|
8
|
+
interface RootProps {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
defaultMonth?: Dayjs;
|
|
12
|
+
onMonthChange?: (month: Dayjs) => void;
|
|
13
|
+
}
|
|
14
|
+
interface TitleProps {
|
|
15
|
+
className?: string;
|
|
16
|
+
format?: string;
|
|
17
|
+
}
|
|
18
|
+
interface NavButtonProps {
|
|
19
|
+
children?: ReactNode;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
interface GridProps {
|
|
23
|
+
renderCell: (date: Dayjs, index: number, isOutside: boolean) => ReactNode;
|
|
24
|
+
weekdays?: string[];
|
|
25
|
+
className?: string;
|
|
26
|
+
weekdayClassName?: string;
|
|
27
|
+
}
|
|
28
|
+
interface CellProps {
|
|
29
|
+
date: Dayjs;
|
|
30
|
+
/** 현재 표시 중인 월과 다른 달 날짜 여부 (이전/다음 달) */
|
|
31
|
+
isOutside?: boolean;
|
|
32
|
+
children?: ReactNode;
|
|
33
|
+
className?: string;
|
|
34
|
+
dateClassName?: string;
|
|
35
|
+
}
|
|
36
|
+
declare const DataCalendarBase: {
|
|
37
|
+
Root: ({ children, className, defaultMonth, onMonthChange, }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
Title: ({ className, format }: TitleProps) => import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
Prev: ({ children, className }: NavButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
Next: ({ children, className }: NavButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
Grid: ({ renderCell, weekdays, className, weekdayClassName, }: GridProps) => import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
Cell: ({ date, isOutside, children, className, dateClassName, }: CellProps) => import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
};
|
|
44
|
+
export default DataCalendarBase;
|
|
45
|
+
//# sourceMappingURL=DataCalendarBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataCalendarBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDDataCalendar/DataCalendarBase.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAE,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,UAAU,uBAAuB;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAID,eAAO,MAAM,sBAAsB,+BAOlC,CAAC;AAIF,UAAU,SAAS;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACxC;AA2BD,UAAU,UAAU;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AASD,UAAU,cAAc;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwBD,UAAU,SAAS;IACjB,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,SAAS,CAAC;IAC1E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAgDD,UAAU,SAAS;IACjB,IAAI,EAAE,KAAK,CAAC;IACZ,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA6BD,QAAA,MAAM,gBAAgB;kEApJnB,SAAS;mCAyBuC,UAAU;oCAYtB,cAAc;oCASd,cAAc;mEAyBlD,SAAS;qEAwDT,SAAS;CAqBoD,CAAC;AAEjE,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import dayjs from 'dayjs';
|
|
4
|
+
import { createContext, useContext, useState } from 'react';
|
|
5
|
+
const DataCalendarContext = createContext(null);
|
|
6
|
+
export const useDataCalendarContext = () => {
|
|
7
|
+
const ctx = useContext(DataCalendarContext);
|
|
8
|
+
if (!ctx)
|
|
9
|
+
throw new Error('DataCalendarBase 서브컴포넌트는 DataCalendarBase.Root 내부에서 사용해야 합니다.');
|
|
10
|
+
return ctx;
|
|
11
|
+
};
|
|
12
|
+
const Root = ({ children, className, defaultMonth, onMonthChange, }) => {
|
|
13
|
+
const [month, setMonth] = useState((defaultMonth ?? dayjs()).startOf('month'));
|
|
14
|
+
const changeMonth = (delta) => {
|
|
15
|
+
const next = month.add(delta, 'month');
|
|
16
|
+
setMonth(next);
|
|
17
|
+
onMonthChange?.(next);
|
|
18
|
+
};
|
|
19
|
+
return (_jsx(DataCalendarContext, { value: { month, changeMonth }, children: _jsx("div", { className: className, children: children }) }));
|
|
20
|
+
};
|
|
21
|
+
const Title = ({ className, format = 'YYYY년 M월' }) => {
|
|
22
|
+
const { month } = useDataCalendarContext();
|
|
23
|
+
return _jsx("span", { className: className, children: month.format(format) });
|
|
24
|
+
};
|
|
25
|
+
const Prev = ({ children, className }) => {
|
|
26
|
+
const { changeMonth } = useDataCalendarContext();
|
|
27
|
+
return (_jsx("button", { type: "button", onClick: () => changeMonth(-1), className: className, children: children }));
|
|
28
|
+
};
|
|
29
|
+
const Next = ({ children, className }) => {
|
|
30
|
+
const { changeMonth } = useDataCalendarContext();
|
|
31
|
+
return (_jsx("button", { type: "button", onClick: () => changeMonth(1), className: className, children: children }));
|
|
32
|
+
};
|
|
33
|
+
// ── Grid ──
|
|
34
|
+
const DEFAULT_WEEKDAYS = ['일', '월', '화', '수', '목', '금', '토'];
|
|
35
|
+
const Grid = ({ renderCell, weekdays = DEFAULT_WEEKDAYS, className, weekdayClassName, }) => {
|
|
36
|
+
const { month } = useDataCalendarContext();
|
|
37
|
+
const startOffset = month.startOf('month').day();
|
|
38
|
+
const daysInMonth = month.daysInMonth();
|
|
39
|
+
const prevMonth = month.subtract(1, 'month');
|
|
40
|
+
const nextMonth = month.add(1, 'month');
|
|
41
|
+
const prevDays = prevMonth.daysInMonth();
|
|
42
|
+
const cells = Array.from({ length: startOffset + daysInMonth }, (_, i) => i < startOffset
|
|
43
|
+
? prevMonth.date(prevDays - startOffset + i + 1)
|
|
44
|
+
: month.date(i - startOffset + 1));
|
|
45
|
+
let nextDay = 1;
|
|
46
|
+
while (cells.length % 7 !== 0)
|
|
47
|
+
cells.push(nextMonth.date(nextDay++));
|
|
48
|
+
return (_jsxs("div", { className: className, children: [_jsx("div", { className: "grid grid-cols-7", children: weekdays.map((d) => (_jsx("span", { className: weekdayClassName, children: d }, d))) }), _jsx("div", { className: "grid grid-cols-7", children: cells.map((date, i) => renderCell(date, i, !date.isSame(month, 'month'))) })] }));
|
|
49
|
+
};
|
|
50
|
+
const Cell = ({ date, isOutside, children, className, dateClassName, }) => {
|
|
51
|
+
const isToday = date.isSame(dayjs(), 'day');
|
|
52
|
+
const isWeekend = date.day() === 0 || date.day() === 6;
|
|
53
|
+
return (_jsxs("div", { className: className, "data-outside": isOutside || undefined, children: [_jsx("span", { "data-today": isToday || undefined, "data-outside": isOutside || undefined, "data-weekend": isWeekend || undefined, className: dateClassName, children: date.date() }), children] }));
|
|
54
|
+
};
|
|
55
|
+
// ── Export ──
|
|
56
|
+
const DataCalendarBase = { Root, Title, Prev, Next, Grid, Cell };
|
|
57
|
+
export default DataCalendarBase;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import DataCalendarBase from './DataCalendarBase.js';
|
|
3
|
+
declare const LDDataCalendar: {
|
|
4
|
+
Root: ({ className, ...props }: ComponentProps<typeof DataCalendarBase.Root>) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
Title: ({ className, ...props }: ComponentProps<typeof DataCalendarBase.Title>) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
Prev: ({ className, children, ...props }: ComponentProps<typeof DataCalendarBase.Prev>) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
Next: ({ className, children, ...props }: ComponentProps<typeof DataCalendarBase.Next>) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
Grid: ({ className, weekdayClassName, ...props }: ComponentProps<typeof DataCalendarBase.Grid>) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
Cell: ({ className, dateClassName, ...props }: ComponentProps<typeof DataCalendarBase.Cell>) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
};
|
|
11
|
+
export default LDDataCalendar;
|
|
12
|
+
//# sourceMappingURL=LDDataCalendar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDDataCalendar.d.ts","sourceRoot":"","sources":["../../../src/components/LDDataCalendar/LDDataCalendar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAoFlD,QAAA,MAAM,cAAc;oCA/EjB,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC;qCAU5C,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC;8CAW7C,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC;8CAgB5C,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC;sDAgB5C,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC;mDAY5C,cAAc,CAAC,OAAO,gBAAgB,CAAC,IAAI,CAAC;CAce,CAAC;AAE/D,eAAe,cAAc,CAAC"}
|