@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,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import DrawerBase from './DrawerBase.js';
|
|
3
|
+
import LucideIcon from '../Icon/LucideIcon.js';
|
|
4
|
+
import LDButton from '../LDButton/LDButton.js';
|
|
5
|
+
import cn from '../../utils/cn.js';
|
|
6
|
+
// ── 방향별 스타일 매핑 ──
|
|
7
|
+
const directionClasses = {
|
|
8
|
+
bottom: 'bottom-0 left-0 right-0 rounded-t-2xl max-h-[95dvh] flex flex-col',
|
|
9
|
+
top: 'top-0 left-0 right-0 rounded-b-2xl max-h-[95dvh] flex flex-col',
|
|
10
|
+
left: 'left-0 top-0 bottom-0 rounded-r-2xl w-[400px] h-full flex flex-col',
|
|
11
|
+
right: 'right-0 top-0 bottom-0 rounded-l-2xl w-[400px] h-full flex flex-col',
|
|
12
|
+
};
|
|
13
|
+
const LDDrawer = ({ open, defaultOpen, onOpenChange, direction = 'bottom', snapPoints, activeSnapPoint, setActiveSnapPoint, title, description, children, buttons, trigger, showHandle, className, style, onButtonClick, }) => {
|
|
14
|
+
const isVertical = direction === 'bottom' || direction === 'top';
|
|
15
|
+
const shouldShowHandle = showHandle ?? isVertical;
|
|
16
|
+
const handleButtonClick = async (button) => {
|
|
17
|
+
let shouldClose = true;
|
|
18
|
+
if (button.onClick) {
|
|
19
|
+
const res = await button.onClick();
|
|
20
|
+
if (res === false)
|
|
21
|
+
shouldClose = false;
|
|
22
|
+
}
|
|
23
|
+
if (shouldClose) {
|
|
24
|
+
onButtonClick?.(button.value);
|
|
25
|
+
onOpenChange?.(false);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return (_jsxs(DrawerBase.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, direction: direction, snapPoints: snapPoints, activeSnapPoint: activeSnapPoint, setActiveSnapPoint: setActiveSnapPoint, children: [trigger && _jsx(DrawerBase.Trigger, { asChild: true, children: trigger }), _jsx(DrawerBase.Overlay, {}), _jsxs(DrawerBase.Content, { className: cn('bg-white', directionClasses[direction], className), style: style, children: [shouldShowHandle && _jsx(DrawerBase.Handle, {}), _jsxs("div", { className: "relative flex flex-col flex-1 overflow-hidden p-5 gap-6", children: [_jsx(DrawerBase.Close, { asChild: true, children: _jsx("button", { className: "absolute top-4 right-5 text-neutral500 cursor-pointer outline-hidden", children: _jsx(LucideIcon, { name: "x", size: 16 }) }) }), (title || description) && (_jsxs("div", { className: "flex flex-col gap-2 pt-2", children: [title && (_jsx(DrawerBase.Title, { className: "display20 bold", children: title })), description && (_jsx(DrawerBase.Description, { className: "display14 text-neutral500", children: description }))] })), children && _jsx("div", { className: "flex-1 overflow-auto", children: children }), buttons && buttons.length > 0 && (_jsx("div", { className: "flex gap-2", children: buttons.map((button, index) => (_jsx(LDButton, { block: true, variant: button.variant, color: button.color, onClick: () => handleButtonClick(button), children: button.label }, index))) }))] })] })] }));
|
|
29
|
+
};
|
|
30
|
+
export default LDDrawer;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type Editor, type Extensions } from '@tiptap/react';
|
|
3
|
+
interface EditorContextType {
|
|
4
|
+
editor: Editor | null;
|
|
5
|
+
}
|
|
6
|
+
export declare const useEditorContext: () => EditorContextType;
|
|
7
|
+
interface RootProps {
|
|
8
|
+
extensions: Extensions;
|
|
9
|
+
content?: string;
|
|
10
|
+
onChange?: (html: string) => void;
|
|
11
|
+
className?: string;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
interface ContentProps {
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
interface ToolbarProps {
|
|
18
|
+
className?: string;
|
|
19
|
+
children?: ReactNode;
|
|
20
|
+
}
|
|
21
|
+
interface ToolbarButtonProps {
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
onClick?: () => void;
|
|
24
|
+
className?: string;
|
|
25
|
+
children?: ReactNode;
|
|
26
|
+
}
|
|
27
|
+
interface ToolbarDropdownProps {
|
|
28
|
+
trigger: (args: {
|
|
29
|
+
open: boolean;
|
|
30
|
+
toggle: () => void;
|
|
31
|
+
}) => ReactNode;
|
|
32
|
+
className?: string;
|
|
33
|
+
children?: ReactNode | ((args: {
|
|
34
|
+
close: () => void;
|
|
35
|
+
}) => ReactNode);
|
|
36
|
+
}
|
|
37
|
+
interface LDViewerProps {
|
|
38
|
+
extensions: Extensions;
|
|
39
|
+
content: string;
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare const EditorBase: {
|
|
43
|
+
Root: ({ extensions, content, onChange, className, children, }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
Content: ({ className }: ContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
Toolbar: (({ className, children }: ToolbarProps) => import("react/jsx-runtime").JSX.Element | null) & {
|
|
46
|
+
LDButton: ({ disabled, onClick, className, children, }: ToolbarButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
Dropdown: ({ trigger, className, children, }: ToolbarDropdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
};
|
|
49
|
+
LDViewer: ({ extensions, content, className }: LDViewerProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
50
|
+
};
|
|
51
|
+
export default EditorBase;
|
|
52
|
+
//# sourceMappingURL=EditorBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/EditorBase.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAIvB,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAID,eAAO,MAAM,gBAAgB,yBAS5B,CAAC;AAGF,UAAU,SAAS;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAuCD,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAeD,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAwBD,UAAU,oBAAoB;IAC5B,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,SAAS,CAAC;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,SAAS,CAAC,CAAC;CACrE;AA0CD,UAAU,aAAa;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAeD,eAAO,MAAM,UAAU;oEAzJpB,SAAS;6BAmCoB,YAAY;wCAWE,YAAY;gEAyBvD,kBAAkB;sDA2BlB,oBAAoB;;mDA0C+B,aAAa;CAkBlE,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useEffect, useRef, useState, } from 'react';
|
|
4
|
+
import { EditorContent, useEditor, } from '@tiptap/react';
|
|
5
|
+
import cn from '../../utils/cn.js';
|
|
6
|
+
const EditorContext = createContext(null);
|
|
7
|
+
export const useEditorContext = () => {
|
|
8
|
+
const editorContext = useContext(EditorContext);
|
|
9
|
+
if (!editorContext) {
|
|
10
|
+
throw new Error('EditorBase 하위 컴포넌트는 Root 내부에서 사용해야 합니다.');
|
|
11
|
+
}
|
|
12
|
+
return editorContext;
|
|
13
|
+
};
|
|
14
|
+
const Root = ({ extensions, content = '', onChange, className, children, }) => {
|
|
15
|
+
const editor = useEditor({
|
|
16
|
+
extensions,
|
|
17
|
+
content,
|
|
18
|
+
onUpdate: ({ editor }) => onChange?.(editor.getHTML()),
|
|
19
|
+
immediatelyRender: false,
|
|
20
|
+
editorProps: {
|
|
21
|
+
attributes: {
|
|
22
|
+
class: cn('prose prose-lg max-w-none px-4 py-3 border-b border-r border-l border-neutral200 rounded-bl-md rounded-br-md outline-none h-[818px] mobile:h-[320px] overflow-y-auto focus:outline-none', className),
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!editor)
|
|
28
|
+
return;
|
|
29
|
+
if ((content || '') !== editor.getHTML()) {
|
|
30
|
+
editor.commands.setContent(content || '');
|
|
31
|
+
}
|
|
32
|
+
}, [content, editor]);
|
|
33
|
+
return (_jsx(EditorContext.Provider, { value: { editor }, children: _jsx("div", { className: cn('w-full', className), children: editor && children }) }));
|
|
34
|
+
};
|
|
35
|
+
const Content = ({ className }) => {
|
|
36
|
+
const { editor } = useEditorContext();
|
|
37
|
+
return _jsx(EditorContent, { editor: editor, className: className });
|
|
38
|
+
};
|
|
39
|
+
const ToolbarRoot = ({ className, children }) => {
|
|
40
|
+
const { editor } = useEditorContext();
|
|
41
|
+
if (!editor)
|
|
42
|
+
return null;
|
|
43
|
+
return (_jsx("div", { className: cn('flex flex-wrap items-center', className), children: children }));
|
|
44
|
+
};
|
|
45
|
+
const ToolbarButton = ({ disabled, onClick, className, children, }) => {
|
|
46
|
+
return (_jsx("button", { type: "button", disabled: disabled, onClick: (e) => {
|
|
47
|
+
e.preventDefault();
|
|
48
|
+
onClick?.();
|
|
49
|
+
}, className: className, children: children }));
|
|
50
|
+
};
|
|
51
|
+
const ToolbarDropdown = ({ trigger, className, children, }) => {
|
|
52
|
+
const [open, setOpen] = useState(false);
|
|
53
|
+
const ref = useRef(null);
|
|
54
|
+
const toggle = () => setOpen((prev) => !prev);
|
|
55
|
+
const close = () => setOpen(false);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const handler = (e) => {
|
|
58
|
+
if (!ref.current?.contains(e.target)) {
|
|
59
|
+
setOpen(false);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
document.addEventListener('mousedown', handler);
|
|
63
|
+
return () => document.removeEventListener('mousedown', handler);
|
|
64
|
+
}, []);
|
|
65
|
+
return (_jsxs("div", { ref: ref, className: "relative", children: [trigger({ open, toggle }), open && (_jsx("div", { className: cn('absolute top-full left-0 mt-1 z-50', className), children: typeof children === 'function' ? children({ close }) : children }))] }));
|
|
66
|
+
};
|
|
67
|
+
const Toolbar = Object.assign(ToolbarRoot, {
|
|
68
|
+
LDButton: ToolbarButton,
|
|
69
|
+
Dropdown: ToolbarDropdown,
|
|
70
|
+
});
|
|
71
|
+
const LDViewer = ({ extensions, content, className }) => {
|
|
72
|
+
const editor = useEditor({
|
|
73
|
+
extensions,
|
|
74
|
+
content: content || '',
|
|
75
|
+
editable: false,
|
|
76
|
+
injectCSS: false,
|
|
77
|
+
immediatelyRender: false,
|
|
78
|
+
});
|
|
79
|
+
if (!editor)
|
|
80
|
+
return null;
|
|
81
|
+
return _jsx(EditorContent, { editor: editor, className: className });
|
|
82
|
+
};
|
|
83
|
+
export const EditorBase = {
|
|
84
|
+
Root,
|
|
85
|
+
Content,
|
|
86
|
+
Toolbar,
|
|
87
|
+
LDViewer,
|
|
88
|
+
};
|
|
89
|
+
export default EditorBase;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LDEditorProps {
|
|
2
|
+
content: string;
|
|
3
|
+
onChange?: (html: string) => void;
|
|
4
|
+
className?: string;
|
|
5
|
+
handleImageUpload?: (fileData: {
|
|
6
|
+
filebase64: string;
|
|
7
|
+
fileName: string;
|
|
8
|
+
}) => Promise<string | null>;
|
|
9
|
+
}
|
|
10
|
+
declare const LDEditor: ({ content, onChange, className, handleImageUpload, }: LDEditorProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export default LDEditor;
|
|
12
|
+
//# sourceMappingURL=LDEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDEditor.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/LDEditor.tsx"],"names":[],"mappings":"AA0EA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC9B;AAED,QAAA,MAAM,QAAQ,GAAI,sDAKf,aAAa,4CAWf,CAAC;AAmXF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold, ChevronDown, Image as ImageIcon, Italic, Link2, List, ListOrdered, Redo, Strikethrough, Underline, Undo, Unlink, } from 'lucide-react';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { useEditorState } from '@tiptap/react';
|
|
6
|
+
import EditorBase, { useEditorContext } from './EditorBase.js';
|
|
7
|
+
import { createEditorExtensions } from './extensions.js';
|
|
8
|
+
import cn from '../../utils/cn.js';
|
|
9
|
+
import Toast from '../Toast/Toast.js';
|
|
10
|
+
import { fileToBase64, getFileSizeUnit, isImage, validAllowedExtesions, validFileSize, validImageSize, } from '../../utils/file.js';
|
|
11
|
+
import { FILE_EXTENSIONS, TOOLBAR_ALLOWED_EXTENSIONS, TOOLBAR_MAX_SIZE, } from '../../constants/file.js';
|
|
12
|
+
const FONT_SIZES = [
|
|
13
|
+
'12px',
|
|
14
|
+
'14px',
|
|
15
|
+
'16px',
|
|
16
|
+
'18px',
|
|
17
|
+
'20px',
|
|
18
|
+
'24px',
|
|
19
|
+
'28px',
|
|
20
|
+
'32px',
|
|
21
|
+
'36px',
|
|
22
|
+
'40px',
|
|
23
|
+
];
|
|
24
|
+
const COLORS = [
|
|
25
|
+
{ label: '검정', value: '#111827' },
|
|
26
|
+
{ label: '빨강', value: '#ef4444' },
|
|
27
|
+
{ label: '파랑', value: '#3b82f6' },
|
|
28
|
+
{ label: '초록', value: '#16a34a' },
|
|
29
|
+
{ label: '주황', value: '#f97316' },
|
|
30
|
+
];
|
|
31
|
+
const HEADINGS = [
|
|
32
|
+
{ label: '본문', level: 0 },
|
|
33
|
+
{ label: '제목 1', level: 1 },
|
|
34
|
+
{ label: '제목 2', level: 2 },
|
|
35
|
+
{ label: '제목 3', level: 3 },
|
|
36
|
+
];
|
|
37
|
+
const iconBtn = 'p-1 rounded-lg cursor-pointer transition hover:bg-mono100 disabled:opacity-30 disabled:cursor-not-allowed';
|
|
38
|
+
const activeBtn = 'bg-mono100';
|
|
39
|
+
const LDDivider = () => _jsx("div", { className: "w-px h-6 bg-neutral200 mx-1" });
|
|
40
|
+
const LDEditor = ({ content, onChange, className, handleImageUpload, }) => {
|
|
41
|
+
return (_jsxs(EditorBase.Root, { extensions: createEditorExtensions(), content: content, onChange: onChange, children: [_jsx(EditorToolbar, { handleImageUpload: handleImageUpload }), _jsx(EditorBase.Content, { className: className })] }));
|
|
42
|
+
};
|
|
43
|
+
const EditorToolbar = ({ handleImageUpload, }) => {
|
|
44
|
+
const [linkUrl, setLinkUrl] = useState('');
|
|
45
|
+
const { editor } = useEditorContext();
|
|
46
|
+
const state = useEditorState({
|
|
47
|
+
editor,
|
|
48
|
+
selector: ({ editor }) => {
|
|
49
|
+
if (!editor)
|
|
50
|
+
return null;
|
|
51
|
+
return {
|
|
52
|
+
fontSize: editor.getAttributes('textStyle')?.fontSize || '18px',
|
|
53
|
+
color: editor.getAttributes('textStyle')?.color || '#111827',
|
|
54
|
+
headingLevel: [1, 2, 3].find((l) => editor.isActive('heading', { level: l })),
|
|
55
|
+
isBold: editor.isActive('bold'),
|
|
56
|
+
isItalic: editor.isActive('italic'),
|
|
57
|
+
isUnderline: editor.isActive('underline'),
|
|
58
|
+
isStrike: editor.isActive('strike'),
|
|
59
|
+
align: {
|
|
60
|
+
left: editor.isActive({ textAlign: 'left' }),
|
|
61
|
+
center: editor.isActive({ textAlign: 'center' }),
|
|
62
|
+
right: editor.isActive({ textAlign: 'right' }),
|
|
63
|
+
justify: editor.isActive({ textAlign: 'justify' }),
|
|
64
|
+
},
|
|
65
|
+
isBulletList: editor.isActive('bulletList'),
|
|
66
|
+
isOrderedList: editor.isActive('orderedList'),
|
|
67
|
+
canUndo: editor.can().undo(),
|
|
68
|
+
canRedo: editor.can().redo(),
|
|
69
|
+
isLink: editor.isActive('link'),
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
const handleImageUploadAction = async (files) => {
|
|
74
|
+
if (!files?.[0] || !editor)
|
|
75
|
+
return;
|
|
76
|
+
const file = files[0];
|
|
77
|
+
if (!validAllowedExtesions(file, TOOLBAR_ALLOWED_EXTENSIONS)) {
|
|
78
|
+
const allowedFiles = TOOLBAR_ALLOWED_EXTENSIONS.map((item) => FILE_EXTENSIONS[item].toUpperCase()).join(', ');
|
|
79
|
+
Toast.error(`지원하지 않는 파일 형식입니다. ${allowedFiles} 파일만 업로드 가능합니다.`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!validFileSize(file, TOOLBAR_MAX_SIZE)) {
|
|
83
|
+
Toast.error(`파일 크기가 너무 큽니다. ${getFileSizeUnit(TOOLBAR_MAX_SIZE)} 이하 파일을 선택해주세요.`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (isImage(file.name) && !(await validImageSize(file))) {
|
|
87
|
+
Toast.error('이미지 해상도가 너무 큽니다. 더 작은 이미지를 선택해주세요.');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const { fileBase64, fileName } = await fileToBase64(file);
|
|
92
|
+
const res = await handleImageUpload?.({
|
|
93
|
+
filebase64: fileBase64,
|
|
94
|
+
fileName,
|
|
95
|
+
});
|
|
96
|
+
if (!res) {
|
|
97
|
+
Toast.error('이미지 업로드에 실패했습니다.');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
editor.commands.setImage({ src: res });
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
Toast.error('파일 업로드 중 문제가 발생했습니다. 잠시 후 다시 시도해주세요.');
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
if (!editor || !state)
|
|
107
|
+
return null;
|
|
108
|
+
return (_jsxs(EditorBase.Toolbar, { className: "gap-5 px-4 py-3 rounded-t-md border border-neutral200", children: [_jsx(EditorBase.Toolbar.Dropdown, { className: "bg-white border border-neutral200 rounded-lg shadow-lg min-w-[120px]", trigger: ({ toggle }) => (_jsx(EditorBase.Toolbar.LDButton, { onClick: toggle, className: cn(iconBtn, 'flex items-center gap-5 px-2'), children: _jsx("span", { className: "whitespace-nowrap min-w-10", children: state.headingLevel ? `제목 ${state.headingLevel}` : '본문' }) })), children: ({ close }) => HEADINGS.map(({ label, level }) => (_jsx("button", { type: "button", onClick: (e) => {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
if (level === 0)
|
|
111
|
+
editor.chain().focus().setParagraph().run();
|
|
112
|
+
else
|
|
113
|
+
editor.chain().focus().toggleHeading({ level }).run();
|
|
114
|
+
close();
|
|
115
|
+
}, className: "w-full px-3 py-2 cursor-pointer text-left text-sm hover:bg-mono100 first:rounded-t-lg last:rounded-b-lg", children: label }, level))) }), _jsx(LDDivider, {}), _jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleBold().run(), className: cn(iconBtn, state.isBold && activeBtn), children: _jsx(Bold, { className: "w-5 h-5" }) }), _jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleItalic().run(), className: cn(iconBtn, state.isItalic && activeBtn), children: _jsx(Italic, { className: "w-5 h-5" }) }), _jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleUnderline().run(), className: cn(iconBtn, state.isUnderline && activeBtn), children: _jsx(Underline, { className: "w-5 h-5" }) }), _jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleStrike().run(), className: cn(iconBtn, state.isStrike && activeBtn), children: _jsx(Strikethrough, { className: "w-5 h-5" }) }), _jsx(LDDivider, {}), _jsx(EditorBase.Toolbar.Dropdown, { className: "border border-neutral200 bg-white rounded-lg shadow-lg min-w-[100px]", trigger: ({ toggle }) => (_jsxs(EditorBase.Toolbar.LDButton, { onClick: toggle, className: cn(iconBtn, 'flex items-center gap-1 px-2'), children: [_jsx("span", { className: "text-sm whitespace-nowrap", children: state.fontSize }), _jsx(ChevronDown, { className: "w-4 h-4" })] })), children: ({ close }) => FONT_SIZES.map((size) => (_jsx("button", { type: "button", onClick: (e) => {
|
|
116
|
+
e.preventDefault();
|
|
117
|
+
editor.chain().focus().setFontSize(size).run();
|
|
118
|
+
close();
|
|
119
|
+
}, className: "w-full px-3 py-2 cursor-pointer text-left text-sm hover:bg-mono100 first:rounded-t-lg last:rounded-b-lg", children: size }, size))) }), _jsx(EditorBase.Toolbar.Dropdown, { className: "bg-white border border-neutral200 rounded-lg shadow-lg min-w-[140px]", trigger: ({ toggle }) => (_jsxs(EditorBase.Toolbar.LDButton, { onClick: toggle, className: cn(iconBtn, 'flex items-center gap-2 px-2'), children: [_jsx("span", { className: "w-4 h-4 rounded-full", style: { backgroundColor: state.color } }), state.color, _jsx(ChevronDown, { className: "w-4 h-4" })] })), children: ({ close }) => COLORS.map((color) => (_jsxs("button", { type: "button", onClick: (e) => {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
editor.chain().focus().setColor(color.value).run();
|
|
122
|
+
close();
|
|
123
|
+
}, className: "flex items-center gap-2 w-full px-3 py-2 cursor-pointer text-left text-sm hover:bg-mono100 first:rounded-t-lg last:rounded-b-lg", children: [_jsx("span", { className: "w-4 h-4 rounded-full", style: { backgroundColor: color.value } }), _jsx("span", { children: color.label })] }, color.value))) }), _jsx(LDDivider, {}), ['left', 'center', 'right', 'justify'].map((align) => {
|
|
124
|
+
const Icon = {
|
|
125
|
+
left: AlignLeft,
|
|
126
|
+
center: AlignCenter,
|
|
127
|
+
right: AlignRight,
|
|
128
|
+
justify: AlignJustify,
|
|
129
|
+
}[align];
|
|
130
|
+
return (_jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().setTextAlign(align).run(), className: cn(iconBtn, state.align[align] && activeBtn), children: _jsx(Icon, { className: "w-5 h-5" }) }, align));
|
|
131
|
+
}), _jsx(LDDivider, {}), _jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleBulletList().run(), className: cn(iconBtn, state.isBulletList && activeBtn), children: _jsx(List, { className: "w-5 h-5" }) }), _jsx(EditorBase.Toolbar.LDButton, { onClick: () => editor.chain().focus().toggleOrderedList().run(), className: cn(iconBtn, state.isOrderedList && activeBtn), children: _jsx(ListOrdered, { className: "w-5 h-5" }) }), _jsx(LDDivider, {}), _jsx(EditorBase.Toolbar.LDButton, { disabled: !state.canUndo, onClick: () => editor.chain().focus().undo().run(), className: iconBtn, children: _jsx(Undo, { className: "w-5 h-5" }) }), _jsx(EditorBase.Toolbar.LDButton, { disabled: !state.canRedo, onClick: () => editor.chain().focus().redo().run(), className: iconBtn, children: _jsx(Redo, { className: "w-5 h-5" }) }), _jsx(LDDivider, {}), _jsx(EditorBase.Toolbar.Dropdown, { className: "bg-white border border-neutral200 rounded-lg shadow-lg p-3 min-w-[280px]", trigger: ({ toggle }) => (_jsx(EditorBase.Toolbar.LDButton, { onClick: () => {
|
|
132
|
+
setLinkUrl(editor.getAttributes('link').href || '');
|
|
133
|
+
toggle();
|
|
134
|
+
}, className: cn(iconBtn, state.isLink && activeBtn), children: _jsx(Link2, { className: "w-5 h-5" }) })), children: ({ close }) => {
|
|
135
|
+
const applyLink = () => {
|
|
136
|
+
const chain = editor.chain().focus().extendMarkRange('link');
|
|
137
|
+
if (linkUrl === '') {
|
|
138
|
+
chain.unsetLink().run();
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const url = /^https?:\/\//.test(linkUrl)
|
|
142
|
+
? linkUrl
|
|
143
|
+
: `https://${linkUrl}`;
|
|
144
|
+
chain.setLink({ href: url }).run();
|
|
145
|
+
}
|
|
146
|
+
setLinkUrl('');
|
|
147
|
+
close();
|
|
148
|
+
};
|
|
149
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { type: "text", autoFocus: true, placeholder: "URL\uC744 \uC785\uB825\uD558\uC138\uC694", value: linkUrl, onChange: (e) => setLinkUrl(e.target.value), onKeyDown: (e) => e.key === 'Enter' && applyLink(), className: "w-full px-3 py-2 border border-neutral200 rounded-lg text-sm outline-none transition duration-300 focus:border-blue-500" }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx("button", { type: "button", onClick: (e) => {
|
|
150
|
+
e.preventDefault();
|
|
151
|
+
applyLink();
|
|
152
|
+
}, className: "flex-1 px-3 py-1.5 bg-blue-500 text-white rounded-lg text-sm transition duration-300 hover:bg-blue-600", children: "\uC801\uC6A9" }), _jsx("button", { type: "button", onClick: (e) => {
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
setLinkUrl('');
|
|
155
|
+
close();
|
|
156
|
+
}, className: "px-3 py-1.5 border border-neutral200 rounded-lg text-sm transition duration-300 hover:bg-mono100", children: "\uCDE8\uC18C" })] })] }));
|
|
157
|
+
} }), _jsx(EditorBase.Toolbar.LDButton, { disabled: !state.isLink, onClick: () => editor.chain().focus().unsetLink().run(), className: iconBtn, children: _jsx(Unlink, { className: "w-5 h-5" }) }), _jsx(LDDivider, {}), _jsxs("label", { className: cn(iconBtn, 'relative'), children: [_jsx(ImageIcon, { className: "w-5 h-5" }), _jsx("input", { type: "file", accept: "image/*", className: "absolute inset-0 w-full h-full opacity-0 cursor-pointer", onChange: (e) => {
|
|
158
|
+
handleImageUploadAction(e.target.files);
|
|
159
|
+
e.target.value = '';
|
|
160
|
+
} })] })] }));
|
|
161
|
+
};
|
|
162
|
+
export default LDEditor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDViewer.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/LDViewer.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,QAAA,MAAM,QAAQ,GAAI,wBAAwB,aAAa,4CAQtD,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import EditorBase from './EditorBase.js';
|
|
4
|
+
import { createEditorExtensions } from './extensions.js';
|
|
5
|
+
import cn from '../../utils/cn.js';
|
|
6
|
+
const LDViewer = ({ content, className }) => {
|
|
7
|
+
return (_jsx(EditorBase.LDViewer, { extensions: createEditorExtensions({ resizableImage: false }), content: content, className: cn('prose prose-lg max-w-none w-full', className) }));
|
|
8
|
+
};
|
|
9
|
+
export default LDViewer;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Extensions } from '@tiptap/react';
|
|
2
|
+
export interface EditorExtensionOptions {
|
|
3
|
+
resizableImage?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const createEditorExtensions: ({ resizableImage, }?: EditorExtensionOptions) => Extensions;
|
|
6
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../../src/components/LDEditor/extensions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,sBAAsB,GAAI,sBAEpC,sBAA2B,KAAG,UA+BhC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
2
|
+
import Underline from '@tiptap/extension-underline';
|
|
3
|
+
import Image from '@tiptap/extension-image';
|
|
4
|
+
import TextAlign from '@tiptap/extension-text-align';
|
|
5
|
+
import { TextStyle, FontSize, Color } from '@tiptap/extension-text-style';
|
|
6
|
+
import Link from '@tiptap/extension-link';
|
|
7
|
+
export const createEditorExtensions = ({ resizableImage = true, } = {}) => [
|
|
8
|
+
StarterKit.configure({
|
|
9
|
+
heading: {
|
|
10
|
+
levels: [1, 2, 3],
|
|
11
|
+
},
|
|
12
|
+
}),
|
|
13
|
+
Underline,
|
|
14
|
+
TextStyle,
|
|
15
|
+
FontSize,
|
|
16
|
+
Color,
|
|
17
|
+
TextAlign.configure({
|
|
18
|
+
types: ['heading', 'paragraph', 'image'],
|
|
19
|
+
alignments: ['left', 'center', 'right', 'justify'],
|
|
20
|
+
}),
|
|
21
|
+
Image.configure({
|
|
22
|
+
inline: false,
|
|
23
|
+
allowBase64: true,
|
|
24
|
+
resize: resizableImage
|
|
25
|
+
? {
|
|
26
|
+
enabled: true,
|
|
27
|
+
alwaysPreserveAspectRatio: true,
|
|
28
|
+
}
|
|
29
|
+
: false,
|
|
30
|
+
}),
|
|
31
|
+
Link.configure({
|
|
32
|
+
openOnClick: false,
|
|
33
|
+
autolink: true,
|
|
34
|
+
HTMLAttributes: {
|
|
35
|
+
class: 'text-blue-500 underline cursor-pointer',
|
|
36
|
+
},
|
|
37
|
+
}),
|
|
38
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Ref } from 'react';
|
|
2
|
+
import { type RegisterOptions } from 'react-hook-form';
|
|
3
|
+
import { type LDInputProps } from './LDInput.js';
|
|
4
|
+
interface FormInputProps extends Omit<LDInputProps, 'name' | 'color' | 'onChange' | 'value' | 'onBlur'> {
|
|
5
|
+
name: string;
|
|
6
|
+
options?: RegisterOptions;
|
|
7
|
+
ref?: Ref<HTMLInputElement>;
|
|
8
|
+
customErrorMessage?: string;
|
|
9
|
+
isHiddenErrorMessage?: boolean;
|
|
10
|
+
errorClassName?: string;
|
|
11
|
+
showEditIcon?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare const FormInput: ({ name, options, variant, size, block, disabled, ref, customErrorMessage, isHiddenErrorMessage, errorClassName, showEditIcon, rightAddon, ...props }: FormInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export default FormInput;
|
|
15
|
+
//# sourceMappingURL=FormInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormInput.d.ts","sourceRoot":"","sources":["../../../src/components/LDInput/FormInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAgB,EAAE,KAAK,YAAY,EAAa,MAAM,WAAW,CAAC;AAMlE,UAAU,cAAe,SAAQ,IAAI,CACnC,YAAY,EACZ,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CACnD;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;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,QAAA,MAAM,SAAS,GAAI,sJAchB,cAAc,4CA6EhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import LDInput, { iconSizes } from './LDInput.js';
|
|
4
|
+
import LucideIcon from '../Icon/LucideIcon.js';
|
|
5
|
+
import FormField from '../Form/FormField.js';
|
|
6
|
+
import FormErrorMessage from '../Form/FormErrorMessage.js';
|
|
7
|
+
import cn from '../../utils/cn.js';
|
|
8
|
+
const FormInput = ({ name, options, variant = 'filled', size = 'small', block = false, disabled = false, ref, customErrorMessage = '', isHiddenErrorMessage = false, errorClassName, showEditIcon = false, rightAddon, ...props }) => {
|
|
9
|
+
const iconSize = iconSizes[size ?? 'sm'];
|
|
10
|
+
return (_jsx(FormField, { name: name, options: options, customErrorMessage: customErrorMessage, disabled: disabled, ref: ref, children: ({ field, fieldState, resetField }) => {
|
|
11
|
+
const editIconAddon = showEditIcon && !disabled ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "group-focus-within:hidden", children: _jsx(LucideIcon, { name: "pencil", size: iconSize }) }), _jsx("button", { type: "button", "aria-label": "\uC785\uB825 \uB0B4\uC6A9 \uCD08\uAE30\uD654", onMouseDown: (e) => {
|
|
12
|
+
e.preventDefault();
|
|
13
|
+
resetField({ defaultValue: '' });
|
|
14
|
+
}, className: "hidden group-focus-within:block text-neutral40 cursor-pointer hover:text-lb500 ld-transition", children: _jsx(LucideIcon, { name: "x", size: iconSize }) })] })) : null;
|
|
15
|
+
const combinedAddon = editIconAddon || rightAddon ? (_jsxs(_Fragment, { children: [editIconAddon, rightAddon] })) : undefined;
|
|
16
|
+
return (_jsxs("div", { className: cn('relative border-2 border-transparent', block ? 'w-full' : 'w-auto'), children: [_jsx(LDInput, { ...props, ...field, value: field.value ?? '', variant: variant, color: fieldState.hasError ? 'danger' : 'neutral', size: size, block: block, rightAddon: combinedAddon, "aria-invalid": fieldState.hasError, "aria-describedby": fieldState.hasError ? fieldState.errorId : undefined }), !isHiddenErrorMessage && (_jsx(FormErrorMessage, { id: fieldState.errorId, error: fieldState.error, disabled: disabled, className: cn((showEditIcon || rightAddon) && 'right-8', errorClassName) }))] }));
|
|
17
|
+
} }));
|
|
18
|
+
};
|
|
19
|
+
export default FormInput;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type InputHTMLAttributes, type ReactNode, type Ref } from 'react';
|
|
2
|
+
interface RootProps {
|
|
3
|
+
block?: boolean;
|
|
4
|
+
className?: string;
|
|
5
|
+
style?: React.CSSProperties;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
interface FieldProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
9
|
+
ref?: Ref<HTMLInputElement>;
|
|
10
|
+
}
|
|
11
|
+
interface AddonProps {
|
|
12
|
+
position?: 'left' | 'right';
|
|
13
|
+
className?: string;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare const InputBase: {
|
|
17
|
+
Root: ({ block, className, style, children }: RootProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
Field: ({ ref, ...props }: FieldProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
Addon: ({ position, className, children }: AddonProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
};
|
|
21
|
+
export default InputBase;
|
|
22
|
+
//# sourceMappingURL=InputBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDInput/InputBase.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAI3E,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAcD,UAAU,UAAW,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAChE,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAOD,UAAU,UAAU;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAgBD,eAAO,MAAM,SAAS;kDAzCuC,SAAS;+BAgBpC,UAAU;+CAWgB,UAAU;CAkBrE,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import cn from '../../utils/cn.js';
|
|
3
|
+
const Root = ({ block = false, className, style, children }) => {
|
|
4
|
+
return (_jsx("div", { style: style, className: cn('relative flex group', block && 'w-full', className), children: children }));
|
|
5
|
+
};
|
|
6
|
+
const Field = ({ ref, ...props }) => {
|
|
7
|
+
return _jsx("input", { ref: ref, ...props });
|
|
8
|
+
};
|
|
9
|
+
const Addon = ({ position = 'right', className, children }) => {
|
|
10
|
+
return (_jsx("span", { className: cn('absolute top-1/2 -translate-y-1/2 flex items-center', position === 'left' ? 'left-0' : 'right-0', className), children: children }));
|
|
11
|
+
};
|
|
12
|
+
export const InputBase = {
|
|
13
|
+
Root,
|
|
14
|
+
Field,
|
|
15
|
+
Addon,
|
|
16
|
+
};
|
|
17
|
+
export default InputBase;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type InputHTMLAttributes, type ReactNode, type Ref } from 'react';
|
|
2
|
+
type InputVariant = 'filled' | 'outline' | 'ghost';
|
|
3
|
+
type InputColor = 'neutral' | 'point' | 'danger';
|
|
4
|
+
type InputSize = 'xSmall' | 'small' | 'medium' | 'large' | 'big' | 'xLarge';
|
|
5
|
+
export declare const iconSizes: Record<InputSize, number>;
|
|
6
|
+
export interface LDInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'color' | 'size'> {
|
|
7
|
+
/** 입력 필드 스타일 유형 */
|
|
8
|
+
variant?: InputVariant;
|
|
9
|
+
/** 색상 테마 */
|
|
10
|
+
color?: InputColor;
|
|
11
|
+
/** 입력 필드 높이 및 폰트 크기 프리셋 */
|
|
12
|
+
size?: InputSize;
|
|
13
|
+
/** 비밀번호 표시/숨김 토글 버튼 */
|
|
14
|
+
showPasswordToggle?: boolean;
|
|
15
|
+
/** true 시 너비 100% */
|
|
16
|
+
block?: boolean;
|
|
17
|
+
/** 우측 부가 요소 (아이콘 등) */
|
|
18
|
+
rightAddon?: ReactNode;
|
|
19
|
+
/** input 요소 ref */
|
|
20
|
+
ref?: Ref<HTMLInputElement>;
|
|
21
|
+
}
|
|
22
|
+
declare const LDInput: ({ variant, color, size, showPasswordToggle, block, type, disabled, className, style, rightAddon, ref, ...props }: LDInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export default LDInput;
|
|
24
|
+
//# sourceMappingURL=LDInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDInput.d.ts","sourceRoot":"","sources":["../../../src/components/LDInput/LDInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,GAAG,EACT,MAAM,OAAO,CAAC;AAMf,KAAK,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AACnD,KAAK,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AACjD,KAAK,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAqD5E,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAO/C,CAAC;AAGF,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,mBAAmB,CAAC,gBAAgB,CAAC,EACrC,OAAO,GAAG,MAAM,CACjB;IACC,mBAAmB;IACnB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,YAAY;IACZ,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,uBAAuB;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uBAAuB;IACvB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,mBAAmB;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAED,QAAA,MAAM,OAAO,GAAI,kHAad,YAAY,4CAuEd,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, } from 'react';
|
|
3
|
+
import InputBase from './InputBase.js';
|
|
4
|
+
import LucideIcon from '../Icon/LucideIcon.js';
|
|
5
|
+
import cn from '../../utils/cn.js';
|
|
6
|
+
// ── 스타일 매핑 ──
|
|
7
|
+
const variantColorClasses = {
|
|
8
|
+
filled: {
|
|
9
|
+
neutral: 'bg-mono100 text-neutral900 outline-2 outline-transparent focus:bg-tintBlue focus:outline-lb500',
|
|
10
|
+
point: 'bg-mono100 text-neutral900 outline-2 outline-transparent focus:bg-tintBlue focus:outline-lb500',
|
|
11
|
+
danger: 'bg-tintRed text-neutral900 outline-2 outline-red500',
|
|
12
|
+
},
|
|
13
|
+
outline: {
|
|
14
|
+
neutral: 'bg-transparent text-neutral900 border border-mono200 focus:border-lb500',
|
|
15
|
+
point: 'bg-transparent text-neutral900 border border-mono200 focus:border-lb500',
|
|
16
|
+
danger: 'bg-transparent text-neutral900 border border-danger100 focus:border-red500',
|
|
17
|
+
},
|
|
18
|
+
ghost: {
|
|
19
|
+
neutral: 'bg-transparent text-neutral900 outline-2 outline-transparent hover:bg-mono50 focus:bg-mono100 focus:outline-lb500',
|
|
20
|
+
point: 'bg-transparent text-neutral900 outline-2 outline-transparent hover:bg-mono50 focus:bg-mono100 focus:outline-lb500',
|
|
21
|
+
danger: 'bg-transparent text-danger500 outline-2 outline-transparent hover:bg-tintRed focus:bg-tintRed focus:outline-red500',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
const disabledVariantClasses = {
|
|
25
|
+
filled: 'bg-mono100 text-mono400',
|
|
26
|
+
outline: 'bg-transparent text-mono400 border border-mono200',
|
|
27
|
+
ghost: 'bg-transparent text-mono400',
|
|
28
|
+
};
|
|
29
|
+
const sizeClasses = {
|
|
30
|
+
xSmall: 'input-2xs',
|
|
31
|
+
small: 'input-xs',
|
|
32
|
+
medium: 'input-sm',
|
|
33
|
+
large: 'input-md',
|
|
34
|
+
big: 'input-lg',
|
|
35
|
+
xLarge: 'input-xl',
|
|
36
|
+
};
|
|
37
|
+
const addonRightPaddingClasses = {
|
|
38
|
+
xSmall: 'pr-8',
|
|
39
|
+
small: 'pr-8',
|
|
40
|
+
medium: 'pr-8',
|
|
41
|
+
large: 'pr-10',
|
|
42
|
+
big: 'pr-11',
|
|
43
|
+
xLarge: 'pr-12',
|
|
44
|
+
};
|
|
45
|
+
export const iconSizes = {
|
|
46
|
+
xSmall: 10,
|
|
47
|
+
small: 12,
|
|
48
|
+
medium: 14,
|
|
49
|
+
large: 16,
|
|
50
|
+
big: 18,
|
|
51
|
+
xLarge: 20,
|
|
52
|
+
};
|
|
53
|
+
const LDInput = ({ variant, color = 'neutral', size, showPasswordToggle = false, block = false, type = 'text', disabled = false, className, style, rightAddon, ref, ...props }) => {
|
|
54
|
+
const [passwordVisible, setPasswordVisible] = useState(false);
|
|
55
|
+
const resolvedType = showPasswordToggle
|
|
56
|
+
? passwordVisible
|
|
57
|
+
? 'text'
|
|
58
|
+
: 'password'
|
|
59
|
+
: type;
|
|
60
|
+
const iconSize = iconSizes[size ?? 'medium'];
|
|
61
|
+
const passwordToggleAddon = showPasswordToggle ? (_jsx("button", { type: "button", "aria-label": passwordVisible ? '비밀번호 숨기기' : '비밀번호 표시', "aria-pressed": passwordVisible, onClick: () => setPasswordVisible(!passwordVisible), disabled: disabled, className: cn('text-neutral40 ld-transition', disabled ? 'cursor-not-allowed' : 'cursor-pointer hover:text-lb500'), children: _jsx(LucideIcon, { name: passwordVisible ? 'eye' : 'eyeOff', size: iconSize }) })) : null;
|
|
62
|
+
const resolvedRightAddon = rightAddon ?? passwordToggleAddon;
|
|
63
|
+
const { width, height, minWidth, maxWidth, minHeight, maxHeight, ...fieldStyle } = style ?? {};
|
|
64
|
+
const rootStyle = { width, height, minWidth, maxWidth, minHeight, maxHeight };
|
|
65
|
+
const fieldClassName = cn('w-full bold placeholder-mono400 ld-transition outline-none', variant &&
|
|
66
|
+
(disabled
|
|
67
|
+
? disabledVariantClasses[variant]
|
|
68
|
+
: variantColorClasses[variant][color]), size && !height && sizeClasses[size], height && 'h-full', disabled && 'cursor-not-allowed', 'read-only:cursor-not-allowed', resolvedRightAddon && size && addonRightPaddingClasses[size], className);
|
|
69
|
+
return (_jsxs(InputBase.Root, { block: block, style: rootStyle, children: [_jsx(InputBase.Field, { ref: ref, type: resolvedType, disabled: disabled, className: fieldClassName, style: fieldStyle, ...props }), resolvedRightAddon && (_jsx(InputBase.Addon, { position: "right", className: "right-2.5 text-neutral40", children: resolvedRightAddon }))] }));
|
|
70
|
+
};
|
|
71
|
+
export default LDInput;
|