Merge remote-tracking branch 'origin/iipbs/common/main' into iipbs/sn/ii
This commit is contained in:
@@ -6,62 +6,100 @@ import { format } from "date-fns";
|
||||
import { CalendarIcon } from "lucide-react";
|
||||
import type { DayPickerSingleProps } from "react-day-picker";
|
||||
|
||||
import { Button, Calendar, Popover, PopoverContent, PopoverTrigger } from "@common/components/ui";
|
||||
import {
|
||||
Button,
|
||||
Calendar,
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@common/components/ui";
|
||||
import { cn } from "../../lib/utils";
|
||||
import { FormControl } from "../form";
|
||||
import { ko } from "date-fns/locale";
|
||||
import { useState } from "react";
|
||||
|
||||
type DatePickerProps = DayPickerSingleProps & { field: { value: Date; onChange: (date: Date | undefined) => void }, selectClass: string | undefined, readOnly?: boolean };
|
||||
type DatePickerProps = DayPickerSingleProps & {
|
||||
field: { value: Date; onChange: (date: Date | undefined) => void };
|
||||
selectClass: string | undefined;
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
export function DatePicker({
|
||||
field,
|
||||
selectClass,
|
||||
readOnly = false,
|
||||
...props
|
||||
}: DatePickerProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
export function DatePicker({ field, selectClass, readOnly = false, ...props }: DatePickerProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const handleSelect = (date: Date | undefined) => {
|
||||
if (!readOnly) {
|
||||
// readOnly가 아닐 때만 변경 허용
|
||||
field.onChange(date); // React Hook Form 업데이트
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelect = (date: Date | undefined) => {
|
||||
if (!readOnly) { // readOnly가 아닐 때만 변경 허용
|
||||
field.onChange(date); // React Hook Form 업데이트
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Popover
|
||||
open={open && !readOnly}
|
||||
onOpenChange={readOnly ? undefined : setOpen}
|
||||
>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl>
|
||||
<Button
|
||||
color="white"
|
||||
variant={"outline"}
|
||||
className={
|
||||
!selectClass
|
||||
? cn(
|
||||
"w-[240px] pl-3 text-left font-normal",
|
||||
!field?.value && "text-muted-foreground",
|
||||
|
||||
return (
|
||||
<Popover open={open && !readOnly} onOpenChange={readOnly ? undefined : setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl>
|
||||
<Button
|
||||
color="white"
|
||||
variant={"outline"}
|
||||
disabled={readOnly} // readOnly일 때 버튼 비활성화
|
||||
className={!selectClass ? cn(
|
||||
"w-[240px] pl-3 text-left font-normal",
|
||||
!field?.value && "text-muted-foreground",
|
||||
readOnly && "opacity-60 cursor-not-allowed" // readOnly 스타일 추가
|
||||
) : cn(selectClass, readOnly && "opacity-60 cursor-not-allowed")}
|
||||
>
|
||||
{field?.value ? (
|
||||
format(
|
||||
field.value instanceof Date && !isNaN(field.value.getTime())
|
||||
? field.value
|
||||
: new Date()
|
||||
//감리 지적사항으로 삭제 예정 리드온리는 리드온리 로만 보일수 있도록 수정
|
||||
// disabled={readOnly} // readOnly일 때 버튼 비활성화
|
||||
//readOnly && "opacity-60 cursor-not-allowed" 감리 지적사항으로
|
||||
)
|
||||
: cn(
|
||||
selectClass,
|
||||
// , readOnly && "opacity-60 cursor-not-allowed"
|
||||
)
|
||||
}
|
||||
>
|
||||
{field?.value ? (
|
||||
format(
|
||||
field.value instanceof Date && !isNaN(field.value.getTime())
|
||||
? field.value
|
||||
: new Date(),
|
||||
|
||||
, "PPP", { locale: ko })
|
||||
) : (
|
||||
<span>Pick a date</span>
|
||||
)}
|
||||
<CalendarIcon className="h-4" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={field?.value}
|
||||
onSelect={handleSelect}
|
||||
initialFocus
|
||||
locale={ko}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
"PPP",
|
||||
{ locale: ko },
|
||||
)
|
||||
) : (
|
||||
<span>날짜를 선택해주세요 </span>
|
||||
)}
|
||||
<CalendarIcon className="h-4" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
className="w-full"
|
||||
|
||||
//-- 데이트 피커가 드롭박스 형태로 년월을 선택할수 있도록 하는 Props 로 활성화 되면 드롭박스로 선택
|
||||
|
||||
// captionLayout="dropdown-buttons"
|
||||
// fromYear={2000}
|
||||
// toYear={new Date().getFullYear()}
|
||||
toDate={new Date()} // 금일까지만 표시됨 (금일 이후는 안보임)
|
||||
showOutsideDays={false} // 금월 까지만 표출되도록
|
||||
mode="single"
|
||||
selected={field?.value}
|
||||
onSelect={handleSelect}
|
||||
initialFocus
|
||||
locale={ko}
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,12 +12,14 @@ import { Popover, PopoverContent, PopoverTrigger } from "@common/components/ui";
|
||||
type DatePickerRangeProps = {
|
||||
placeholder?: string;
|
||||
disabled?: boolean | ((date: Date) => boolean);
|
||||
zIndex?: number; // z-index prop 추가
|
||||
} & DayPickerSingleProps;
|
||||
|
||||
export function DatePickerRange({
|
||||
className,
|
||||
placeholder = "날짜 선택",
|
||||
disabled,
|
||||
zIndex,
|
||||
...props
|
||||
}: DatePickerRangeProps) {
|
||||
return (
|
||||
@@ -36,8 +38,8 @@ export function DatePickerRange({
|
||||
)}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0">
|
||||
<Calendar initialFocus classNames={{ cell: "rounded-md" }} {...props}
|
||||
<PopoverContent className={cn("w-auto p-0", zIndex ? `!z-[${zIndex}]` : "")}>
|
||||
<Calendar initialFocus classNames={{ cell: "rounded-md" }} {...props}
|
||||
disabled={typeof disabled === "function" ? disabled : undefined}
|
||||
/>
|
||||
</PopoverContent>
|
||||
|
||||
@@ -1,57 +1,103 @@
|
||||
// selectBox
|
||||
|
||||
import { Label } from "@common/components";
|
||||
import React from "react";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./lib/selectBox";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "./lib/selectBox";
|
||||
|
||||
/** 차트 기본 스타일 */
|
||||
interface SelectBox1 {
|
||||
text:string,
|
||||
val:string|number,
|
||||
hidden?: boolean
|
||||
text: string;
|
||||
val: string | number;
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
||||
const SelectBox = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement> & {
|
||||
label:string,
|
||||
selectClass:string|undefined,
|
||||
className:string,
|
||||
selectArray:SelectBox1[],
|
||||
onSelectValue:(val:string|number)=>void,
|
||||
value?: string|number,
|
||||
readOnly?: boolean // readOnly 속성 추가
|
||||
label: string;
|
||||
selectClass: string | undefined;
|
||||
className: string;
|
||||
selectArray: SelectBox1[];
|
||||
onSelectValue: (val: string | number) => void;
|
||||
value?: string | number;
|
||||
readOnly?: boolean; // readOnly 속성 추가
|
||||
}
|
||||
>(({ label, className, selectClass, selectArray, onSelectValue, value, readOnly = false }, ref)=>{
|
||||
// hidden이 true인 첫 번째 항목을 placeholder로 사용
|
||||
const hiddenItem = selectArray.find(item => item.hidden);
|
||||
const placeHolder = hiddenItem?.text ?? "선택";
|
||||
|
||||
// hidden이 true인 항목만 드롭다운에서 제외
|
||||
const visibleItems = selectArray.filter(item => !item.hidden);
|
||||
>(
|
||||
(
|
||||
{
|
||||
label,
|
||||
className,
|
||||
selectClass,
|
||||
selectArray,
|
||||
onSelectValue,
|
||||
value,
|
||||
readOnly = false,
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
// hidden이 true인 첫 번째 항목을 placeholder로 사용
|
||||
const hiddenItem = selectArray.find((item) => item.hidden);
|
||||
const placeHolder = hiddenItem?.text ?? "선택";
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
// hidden이 true인 항목만 드롭다운에서 제외
|
||||
const visibleItems = selectArray.filter((item) => !item.hidden);
|
||||
|
||||
// 현재 값이 hidden 항목이거나 빈 값인 경우 undefined로 설정하여 placeholder가 표시되도록 함
|
||||
const currentValue = value !== undefined &&
|
||||
hiddenItem &&
|
||||
(String(value) === String(hiddenItem.val) || value === "" || value === "0" || value === 0)
|
||||
? undefined
|
||||
: (value !== undefined ? String(value) : undefined);
|
||||
// 현재 값이 hidden 항목이거나 빈 값인 경우 undefined로 설정하여 placeholder가 표시되도록 함
|
||||
const currentValue =
|
||||
value !== undefined &&
|
||||
hiddenItem &&
|
||||
(String(value) === String(hiddenItem.val) ||
|
||||
value === "" ||
|
||||
value === "0" ||
|
||||
value === 0)
|
||||
? undefined
|
||||
: value !== undefined
|
||||
? String(value)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<div className={className+" flex items-center"} ref={ref}>
|
||||
{label && <Label className="whitespace-nowrap w-20 text-xl text-gray-600">{label}</Label>}
|
||||
<Select onValueChange={onSelectValue} value={currentValue} disabled={readOnly}>
|
||||
<SelectTrigger className={selectClass?selectClass:"flex-1 p-2 border rounded"}>
|
||||
<SelectValue placeholder={placeHolder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{visibleItems.map((selectArray) => (
|
||||
<SelectItem key={selectArray.val} value={String(selectArray.val)}>{selectArray.text}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
return (
|
||||
<div className={className + " flex items-center"} ref={ref}>
|
||||
{label && (
|
||||
<Label className="w-20 whitespace-nowrap text-xl text-gray-600">
|
||||
{label}
|
||||
</Label>
|
||||
)}
|
||||
<Select
|
||||
open={isOpen}
|
||||
onOpenChange={(open) => {
|
||||
if (readOnly === true) {
|
||||
// readOnly 일경우 Select 선택안하게 하기
|
||||
setIsOpen(false);
|
||||
} else {
|
||||
setIsOpen(open);
|
||||
}
|
||||
}}
|
||||
onValueChange={onSelectValue}
|
||||
value={currentValue}
|
||||
// disabled={readOnly} //물재이용 감리 지적사항으로 일단 주석처리
|
||||
>
|
||||
<SelectTrigger
|
||||
className={selectClass ? selectClass : "flex-1 rounded border p-2"}
|
||||
>
|
||||
<SelectValue placeholder={placeHolder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{visibleItems.map((selectArray) => (
|
||||
<SelectItem key={selectArray.val} value={String(selectArray.val)}>
|
||||
{selectArray.text}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export { SelectBox };
|
||||
|
||||
Reference in New Issue
Block a user