readOnly disabled 가 아닌 readOnly로 보이게 수정

This commit is contained in:
leedj312
2025-07-10 11:20:58 +09:00
parent 9ab0302e08
commit cce216ad9b
2 changed files with 173 additions and 89 deletions
@@ -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>
);
}
@@ -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 };