Merge branch 'iipbs/common/main' into iipbs/sn/dev
This commit is contained in:
+3
-1
@@ -5,4 +5,6 @@
|
||||
node_modules
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
apps/wr/.next/**/*
|
||||
apps/fo/.next/**/*
|
||||
@@ -1,6 +1,6 @@
|
||||
## business_components 패키지
|
||||
### 원앤올에서 제공받는 컴포넌트 외에 업무 파트에서 사용할 수 있는 별도 components 패키지지
|
||||
  1) 설정
|
||||
  1) 환경설정
|
||||
|
||||
    (1) tsconfig.json 'path'에 '@common/business_components' 변수를 추가
|
||||
```json
|
||||
@@ -8,7 +8,7 @@
|
||||
"@/*": ["./*"],
|
||||
"@common/components/*": ["../../packages/common/components/src/*"],
|
||||
"@common/components": ["../../packages/common/components/src/index"],
|
||||
// 작성구문문
|
||||
//아래에 해당하는 부분을 추가해줘야함.
|
||||
"@common/business_components/*": ["../../packages/common/business_components/src/*"],
|
||||
"@common/business_components": ["../../packages/common/business_components/src/index"]
|
||||
}
|
||||
@@ -19,4 +19,15 @@
|
||||
"@common/business_components": "workspace:*",
|
||||
"next": "15.1.7"
|
||||
},
|
||||
```
|
||||
```
|
||||
|
||||
    (3) tailwind.config.ts 추가
|
||||
``` json
|
||||
content: [
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"../../packages/common/components/src/ui/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
//아래에 해당하는 부분을 추가해줘야함.
|
||||
"../../packages/common/business_components/src/ui/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
```
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"@common/components": "workspace:*",
|
||||
"@hookform/resolvers": "^4.1.3",
|
||||
"@radix-ui/react-label": "^2.1.2",
|
||||
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
@tailwind components;
|
||||
|
||||
@layer components {
|
||||
.date-picker-trigger {
|
||||
@apply h-[3rem] w-[12rem] justify-between border-input !bg-background px-4 py-2 text-left text-[1.3rem] font-normal leading-none text-muted-foreground hover:!bg-accent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import "./date-picker.css";
|
||||
|
||||
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 { cn } from "../../lib/utils";
|
||||
import { FormControl } from "../form";
|
||||
|
||||
type DatePickerProps = DayPickerSingleProps & { field: { value: Date; onChange: (date: Date | undefined) => void } };
|
||||
|
||||
export function DatePicker({ field }: DatePickerProps) {
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl>
|
||||
<Button
|
||||
variant={"outline"}
|
||||
className={cn(
|
||||
"w-[240px] pl-3 text-left font-normal",
|
||||
!field?.value && "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{field?.value ? (
|
||||
format(field?.value, "PPP")
|
||||
) : (
|
||||
<span>Pick a date</span>
|
||||
)}
|
||||
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
mode="single"
|
||||
selected={field?.value}
|
||||
onSelect={field?.onChange}
|
||||
initialFocus
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import { FormControl, FormItem, FormLabel, FormMessage } from "../form";
|
||||
|
||||
const FormUi = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement> & {label:string|undefined}
|
||||
>(({children, label},ref)=>{
|
||||
return (
|
||||
<FormItem ref={ref}>
|
||||
{label?<FormLabel className="text-xl">{label}</FormLabel>:<></>}
|
||||
<FormControl>
|
||||
{children}
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)
|
||||
})
|
||||
FormUi.displayName = 'FormUi';
|
||||
export { FormUi };
|
||||
@@ -1,6 +1,12 @@
|
||||
export * from "./chart";
|
||||
export * from "./date_picker";
|
||||
export * from "./file-upload";
|
||||
export * from "./form";
|
||||
export * from "./form_ui";
|
||||
export * from "./scroll";
|
||||
export * from "./search_form";
|
||||
export * from "./search_input";
|
||||
export * from "./search_input_select";
|
||||
export * from "./select";
|
||||
export * from "./table";
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||
import * as React from "react"
|
||||
|
||||
import { cn } from "../../lib/utils"
|
||||
|
||||
const ScrollArea = React.forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn("relative overflow-hidden", className)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
<ScrollBar />
|
||||
<ScrollAreaPrimitive.Corner />
|
||||
</ScrollAreaPrimitive.Root>
|
||||
))
|
||||
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
|
||||
|
||||
const ScrollBar = React.forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
>(({ className, orientation = "vertical", ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||
ref={ref}
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"flex touch-none select-none transition-colors",
|
||||
orientation === "vertical" &&
|
||||
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
||||
orientation === "horizontal" &&
|
||||
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
||||
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
))
|
||||
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
|
||||
|
||||
export { ScrollArea, ScrollBar }
|
||||
@@ -1,21 +1,9 @@
|
||||
/**
|
||||
* 검색영역 스타일
|
||||
*/
|
||||
const styles = {
|
||||
divStyle : {
|
||||
border: '1px solid black',
|
||||
margin: '1rem',
|
||||
display: 'flex',
|
||||
borderRadius: '1rem'
|
||||
} as React.CSSProperties
|
||||
}
|
||||
|
||||
function SearchDiv ({children}:{ children: React.ReactNode; }) {
|
||||
return (
|
||||
<div style={styles.divStyle}>
|
||||
<div className="flex border border-black m-4 rounded-lg min-h-[80px]">
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export { SearchDiv };
|
||||
export { SearchDiv };
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Input, Label } from "@common/components";
|
||||
import React from "react";
|
||||
|
||||
const SearchInput = React.forwardRef<
|
||||
HTMLDivElement& HTMLInputElement,
|
||||
React.HTMLAttributes<HTMLDivElement> & {className:string, label:string}>
|
||||
(({className, label}, ref) => {
|
||||
console.log(ref);
|
||||
return (
|
||||
<div className={className+" flex"} >
|
||||
{label && <Label className="m-4 text-2xl w-1/4">{label}</Label>}
|
||||
<Input className="ml-8 w-3/4 text-lg" ref={ref}></Input>
|
||||
</div>
|
||||
)
|
||||
});
|
||||
export { SearchInput };
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Input, Label } from "@common/components";
|
||||
import React from "react";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../select/lib/selectBox";
|
||||
export type SelectDataType = {
|
||||
text: string;
|
||||
val: string;
|
||||
}
|
||||
/**
|
||||
* 검색 입력 및 선택 컴포넌트
|
||||
* @param className - string tailwindcss class
|
||||
* @param label - string label
|
||||
* @param selectData - SelectDataType[] 선택 데이터
|
||||
* @param onSelectValue - (val:string)=>void 선택 값 콜백
|
||||
* @param refs - React.forwardRef<HTMLInputElement> | null 입력값 ref
|
||||
* @returns React.FC
|
||||
*/
|
||||
const SearchInputSelect = React.forwardRef<HTMLInputElement, {className:string, label:string, selectData: SelectDataType[], onSelectValue:(val:string)=>void}>(({className, label, selectData, onSelectValue}, refs) => {
|
||||
return (
|
||||
<div className={className+" flex items-center"} >
|
||||
{label && <Label className="m-4 text-2xl w-1/4">{label}</Label>}
|
||||
<div className="flex w-full items-center">
|
||||
<Input className="w-2/3 text-lg" ref={refs}/>
|
||||
<Select onValueChange={onSelectValue}>
|
||||
<SelectTrigger className="ml-2 w-1/3 text-lg" >
|
||||
<SelectValue placeholder={selectData?.[0]?.text ?? ""} />
|
||||
</SelectTrigger>
|
||||
{/* <SelectContent ref={refs ? (refs as unknown as RefType)?.selectValue : null}> */}
|
||||
<SelectContent >
|
||||
{selectData.map((selectArray) => (
|
||||
<SelectItem key={selectArray.val} value={selectArray.val}>{selectArray.text}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
});
|
||||
export { SearchInputSelect };
|
||||
@@ -1,45 +1,35 @@
|
||||
import { Label } from "@common/components";
|
||||
import React from "react";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./lib/selectBox";
|
||||
|
||||
/** 차트 기본 스타일 */
|
||||
const styles = {
|
||||
selectBoxDiv : {
|
||||
marginLeft : '2rem',
|
||||
display : 'flex'
|
||||
} as React.CSSProperties,
|
||||
selectStyle : {
|
||||
marginLeft: '1rem',
|
||||
width:'8rem'
|
||||
} as React.CSSProperties,
|
||||
labelStyle : {
|
||||
margin:'0.8rem 0.8rem 0.8rem 0.8rem',
|
||||
fontSize: '10px',
|
||||
} as React.CSSProperties
|
||||
}
|
||||
|
||||
interface SelectBox1 {
|
||||
text:string,
|
||||
val:string
|
||||
}
|
||||
|
||||
function SelectBox(props: {label : string, selectArray: SelectBox1[]}){
|
||||
const placeHolder = props.selectArray.length > 0 ? props.selectArray[0].text : "";
|
||||
|
||||
const SelectBox = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement> & {label:string, className:string, selectArray:SelectBox1[], onSelectValue:(val:string)=>void}
|
||||
>(({ label, className, selectArray, onSelectValue }, ref)=>{
|
||||
const placeHolder = selectArray?.[0]?.text ?? "";
|
||||
|
||||
return (
|
||||
<div style={styles.selectBoxDiv}>
|
||||
{props.label && <Label style={styles.labelStyle}>{props.label}</Label>}
|
||||
<Select style={styles.selectStyle}>
|
||||
<SelectTrigger style={styles.selectStyle} className="w-[180px]">
|
||||
<div className={className+" flex items-center"} ref={ref}>
|
||||
{label && <Label className="m-4 text-2xl w-1/4">{label}</Label>}
|
||||
<Select onValueChange={onSelectValue}>
|
||||
<SelectTrigger className="ml-8 w-3/4 text-2xl">
|
||||
<SelectValue placeholder={placeHolder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{props.selectArray.map((selectArray) => (
|
||||
{selectArray.map((selectArray) => (
|
||||
<SelectItem key={selectArray.val} value={selectArray.val}>{selectArray.text}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export { SelectBox };
|
||||
export { SelectBox };
|
||||
|
||||
@@ -1,46 +1,49 @@
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components";
|
||||
import UiPageNations from "./uiPageNations";
|
||||
|
||||
|
||||
interface UiTableProps {
|
||||
headName: string;
|
||||
publicReuseFacility: any[];
|
||||
headlist: { id: string; title: string; }[];
|
||||
|
||||
|
||||
type UiTableProps = {
|
||||
headName: React.ReactNode | undefined;
|
||||
tableData: { [key: string]: string | number | boolean }[];
|
||||
headlist: UiHeadProps[];
|
||||
pageSize: number;
|
||||
total: number;
|
||||
children: React.ReactNode|undefined;
|
||||
children: React.ReactNode | undefined;
|
||||
}
|
||||
|
||||
export function UiTable(UiTableProps: UiTableProps) {
|
||||
const { publicReuseFacility, headlist,pageSize , total, children,headName} = UiTableProps;
|
||||
type UiHeadProps = {
|
||||
id: string;
|
||||
title: string;
|
||||
|
||||
}
|
||||
export function UiTable({ tableData, headlist, pageSize, total, children, headName }: UiTableProps) {
|
||||
const cur = 1;
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>{headName}</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{children? <>{children}</>:<TableRow>
|
||||
{headlist.map((head) => (
|
||||
<TableHead key={head.id}>{head.title}</TableHead>
|
||||
))}
|
||||
</TableRow>}
|
||||
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{publicReuseFacility.map((el: any,index) => (
|
||||
<TableRow key={index+"row"} >
|
||||
{headlist.map((head) => (
|
||||
<TableCell key={head.id+index}>{el[head.id]}</TableCell>
|
||||
))}
|
||||
|
||||
</TableRow>
|
||||
return (
|
||||
<>
|
||||
{headName ? headName : <></>}
|
||||
<Table>
|
||||
<TableHeader>
|
||||
{children ? <>{children}</> : <TableRow>
|
||||
{headlist?.map((head) => (
|
||||
<TableHead key={head.id}>{head.title}</TableHead>
|
||||
))}
|
||||
</TableBody>
|
||||
|
||||
</Table>
|
||||
<UiPageNations total={total} cur={cur} pageSize={pageSize} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
</TableRow>}
|
||||
|
||||
</TableHeader>
|
||||
<TableBody className='text-center'>
|
||||
{tableData?.map((el: { [key: string]: string | number | boolean }, index) => (
|
||||
<TableRow key={index + "row"} >
|
||||
{headlist.map((head) => (
|
||||
<TableCell key={head.id + index}>{el[head.id]}</TableCell>
|
||||
))}
|
||||
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
|
||||
</Table>
|
||||
{total <= 0 ? <></> : <UiPageNations total={total} cur={cur} pageSize={pageSize} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user