@wishket/design-system 2.1.4 → 2.2.0
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/Inputs/Calendar/Calendar.d.ts +18 -1
- package/dist/Components/Inputs/Calendar/Calendar.js +26 -9
- package/dist/Components/Inputs/Calendar/Calendar.types.d.ts +4 -0
- package/dist/Components/Inputs/Calendar/Calendar.utils.d.ts +1 -0
- package/dist/Components/Inputs/Calendar/Calendar.utils.js +1 -1
- package/dist/cjs/Components/Inputs/Calendar/Calendar.js +7 -7
- package/dist/cjs/Components/Inputs/Calendar/Calendar.utils.js +1 -1
- package/package.json +1 -1
|
@@ -12,6 +12,10 @@ import { CalendarProps } from './Calendar.types';
|
|
|
12
12
|
* @param {boolean} [props.disabled] - 캘린더 비활성화 여부
|
|
13
13
|
* @param {string} [props.placeholder] - 날짜가 선택되지 않았을 때 표시될 텍스트
|
|
14
14
|
* @param {boolean} [props.isError] - 에러 상태 표시 여부
|
|
15
|
+
* @param {string} [props.className] - 컨테이너에 머지될 클래스 (예: 부모 너비에 맞추기 위한 `w-full`)
|
|
16
|
+
* @param {string} [props.triggerClassName] - 트리거(TextFieldContainer)에 머지될 클래스
|
|
17
|
+
* @param {string} [props.minDate] - 선택 가능한 최소 날짜 (YYYY-MM-DD). 이전 날짜 셀은 disabled 처리
|
|
18
|
+
* @param {string} [props.maxDate] - 선택 가능한 최대 날짜 (YYYY-MM-DD). 이후 날짜 셀은 disabled 처리
|
|
15
19
|
*
|
|
16
20
|
* @example
|
|
17
21
|
* ```tsx
|
|
@@ -33,7 +37,20 @@ import { CalendarProps } from './Calendar.types';
|
|
|
33
37
|
* isError={true}
|
|
34
38
|
* selected="2024-03-21"
|
|
35
39
|
* />
|
|
40
|
+
*
|
|
41
|
+
* // 부모 너비에 맞추기 (popover/dialog 안에 풀-너비 배치)
|
|
42
|
+
* <Calendar
|
|
43
|
+
* className="w-full"
|
|
44
|
+
* triggerClassName="w-full"
|
|
45
|
+
* selected="2024-03-21"
|
|
46
|
+
* />
|
|
47
|
+
*
|
|
48
|
+
* // 과거 날짜 선택 disable (오늘 이후만 선택 가능)
|
|
49
|
+
* <Calendar
|
|
50
|
+
* minDate="2026-05-04"
|
|
51
|
+
* placeholder="시작일"
|
|
52
|
+
* />
|
|
36
53
|
* ```
|
|
37
54
|
*/
|
|
38
|
-
declare const Calendar: ({ defaultDate, selected, onChange, disabled, placeholder, isError, }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
declare const Calendar: ({ defaultDate, selected, onChange, disabled, placeholder, isError, className, triggerClassName, minDate, maxDate, }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
|
|
39
56
|
export { Calendar };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";import{jsxs as e,jsx as
|
|
1
|
+
"use client";import{jsxs as e,jsx as a}from"react/jsx-runtime";import{useState as t,useEffect as r}from"react";import{twMerge as s}from"tailwind-merge";import"../../DataDisplays/Avatar/Avatar.js";import{Typography as n}from"../../Base/Typography/Typography.js";import{Box as i}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{SystemIcon as o}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import"../../DataDisplays/Accordion/Accordion.js";import{TextFieldContainer as l}from"../TextFieldContainer/TextFieldContainer.js";import{SelectHeader as d,WeekHeader as m,DateBox as c}from"./Calendar.parts.js";import{generateDate as p,today as y,getKoreanTimeString as g,getMonthDate as x,isSameDate as h,isDateOutOfRange as u}from"./Calendar.utils.js";
|
|
2
2
|
/**
|
|
3
3
|
* 날짜를 선택할 수 있는 캘린더 컴포넌트입니다.
|
|
4
4
|
*
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
* @param {boolean} [props.disabled] - 캘린더 비활성화 여부
|
|
13
13
|
* @param {string} [props.placeholder] - 날짜가 선택되지 않았을 때 표시될 텍스트
|
|
14
14
|
* @param {boolean} [props.isError] - 에러 상태 표시 여부
|
|
15
|
+
* @param {string} [props.className] - 컨테이너에 머지될 클래스 (예: 부모 너비에 맞추기 위한 `w-full`)
|
|
16
|
+
* @param {string} [props.triggerClassName] - 트리거(TextFieldContainer)에 머지될 클래스
|
|
17
|
+
* @param {string} [props.minDate] - 선택 가능한 최소 날짜 (YYYY-MM-DD). 이전 날짜 셀은 disabled 처리
|
|
18
|
+
* @param {string} [props.maxDate] - 선택 가능한 최대 날짜 (YYYY-MM-DD). 이후 날짜 셀은 disabled 처리
|
|
15
19
|
*
|
|
16
20
|
* @example
|
|
17
21
|
* ```tsx
|
|
@@ -33,13 +37,26 @@
|
|
|
33
37
|
* isError={true}
|
|
34
38
|
* selected="2024-03-21"
|
|
35
39
|
* />
|
|
40
|
+
*
|
|
41
|
+
* // 부모 너비에 맞추기 (popover/dialog 안에 풀-너비 배치)
|
|
42
|
+
* <Calendar
|
|
43
|
+
* className="w-full"
|
|
44
|
+
* triggerClassName="w-full"
|
|
45
|
+
* selected="2024-03-21"
|
|
46
|
+
* />
|
|
47
|
+
*
|
|
48
|
+
* // 과거 날짜 선택 disable (오늘 이후만 선택 가능)
|
|
49
|
+
* <Calendar
|
|
50
|
+
* minDate="2026-05-04"
|
|
51
|
+
* placeholder="시작일"
|
|
52
|
+
* />
|
|
36
53
|
* ```
|
|
37
|
-
*/const
|
|
54
|
+
*/const f=({defaultDate:f,selected:w,onChange:D,disabled:b,placeholder:j,isError:C,className:N,triggerClassName:$,minDate:B,maxDate:v})=>{const[A,F]=t(!1),I=()=>{b||F((e=>!e))},S=f?p(f):y,[T,L]=t(w?p(w):S),k=w?p(w):S,{year:z,month:E,date:_}=g(k),{dateList:q}=x(T.year,T.month),G=[...Array.from({length:q[0].day},(()=>null)),...q],H=e=>{if(w&&h(e,k))return;if(u(e,B,v))return;const a=`${e.year}-${e.month}-${e.date}`;null==D||D(a),F(!1)};return r((()=>{!A&&w&&L(p(w));
|
|
38
55
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39
|
-
}),[
|
|
40
|
-
/*#__PURE__*/
|
|
41
|
-
/*#__PURE__*/
|
|
42
|
-
/*#__PURE__*/
|
|
43
|
-
/*#__PURE__*/
|
|
44
|
-
/*#__PURE__*/
|
|
45
|
-
/*#__PURE__*/
|
|
56
|
+
}),[A]),/*#__PURE__*/e(i,{className:s("relative h-fit w-fit select-none",N),"data-testid":"design-system-calendar--container",children:[
|
|
57
|
+
/*#__PURE__*/a(i,{className:"cursor-pointer",children:/*#__PURE__*/e(l,{isFocused:A,isError:C,isDisabled:b,testId:"design-system-calendar--trigger",onClick:I,className:$,children:[
|
|
58
|
+
/*#__PURE__*/a(o,{name:"medium_calendar",className:b||!w?"text-w-gray-300":"text-w-gray-400"}),
|
|
59
|
+
/*#__PURE__*/a(n,{variant:"body16",className:s("text-w-gray-600 min-w-[178px]",!w&&"text-w-gray-300",b&&"text-w-gray-300"),"data-testid":"design-system-calendar--selected-date",children:w?`${z} ${E} ${_}`:j})]})}),A&&/*#__PURE__*/a("div",{className:"fixed top-0 left-0 z-10 h-screen w-screen bg-transparent",onClick:I}),A&&/*#__PURE__*/e(i,{"data-testid":"design-system-calendar--content",className:"border-w-gray-200 bg-w-white shadow-graymedium absolute top-[54px] z-30 flex w-[350px] flex-col gap-4 rounded-xl border px-[15px] py-[23px]",children:[
|
|
60
|
+
/*#__PURE__*/a(d,{visibleDate:T,onChange:e=>{L(e)}}),
|
|
61
|
+
/*#__PURE__*/a(m,{}),
|
|
62
|
+
/*#__PURE__*/a(i,{className:"grid w-full grid-cols-7 place-content-center place-items-center gap-1",children:G.map(((e,t)=>{const r=!(!e||!w)&&h(e,k);return e?/*#__PURE__*/a(c,{date:e,selected:r,disabled:u(e,B,v),onChange:H},`${e.year}-${e.month}-${e.date}`):/*#__PURE__*/a(c,{disabled:!0},t)}))})]})]})};export{f as Calendar};
|
|
@@ -2,6 +2,7 @@ import { DateType } from './Calendar.types';
|
|
|
2
2
|
export declare const today: DateType;
|
|
3
3
|
export declare const generateDate: (data: string) => DateType;
|
|
4
4
|
export declare const isSameDate: (referencePoint: string | DateType, target: DateType) => boolean | undefined;
|
|
5
|
+
export declare const isDateOutOfRange: (date: DateType, minDate?: string, maxDate?: string) => boolean;
|
|
5
6
|
export declare const getMonthDate: (year: number, month: number) => {
|
|
6
7
|
lastDate: number;
|
|
7
8
|
firstDay: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dayMap as e}from"./Calendar.constants.js";const t={year:(new Date).getFullYear(),month:(new Date).getMonth()+1,date:(new Date).getDate(),day:(new Date).getDay()},a=e=>{const[t,a,r]=null==e?void 0:e.split("-"),n=new Date(Number(t),Number(a)-1,Number(r)).getDay();return{year:Number(t),month:Number(a),date:Number(r),day:n}},r=(e,t)=>{if("string"==typeof e){const[a,r,n]=e.split("-");return new Date(Number(a),Number(r)-1,Number(n)).getTime()==new Date(t.year,Number(t.month)-1,Number(t.date)).getTime()}if("object"==typeof e)return new Date(e.year,Number(e.month)-1,Number(e.date)).getTime()==new Date(t.year,Number(t.month)-1,Number(t.date)).getTime()},n=(e,t)=>{const a=new Date(e,t,0).getDate();return{lastDate:a,firstDay:new Date(e,t-1,1).getDay(),lastDay:new Date(e,t-1,a).getDay(),dateList:new Array(a).fill(null).map(((a,r)=>({year:e,month:t,date:r+1,day:new Date(e,t-1,r+1).getDay()})))}},
|
|
1
|
+
import{dayMap as e}from"./Calendar.constants.js";const t={year:(new Date).getFullYear(),month:(new Date).getMonth()+1,date:(new Date).getDate(),day:(new Date).getDay()},a=e=>{const[t,a,r]=null==e?void 0:e.split("-"),n=new Date(Number(t),Number(a)-1,Number(r)).getDay();return{year:Number(t),month:Number(a),date:Number(r),day:n}},r=(e,t)=>{if("string"==typeof e){const[a,r,n]=e.split("-");return new Date(Number(a),Number(r)-1,Number(n)).getTime()==new Date(t.year,Number(t.month)-1,Number(t.date)).getTime()}if("object"==typeof e)return new Date(e.year,Number(e.month)-1,Number(e.date)).getTime()==new Date(t.year,Number(t.month)-1,Number(t.date)).getTime()},n=(e,t,a)=>{if(!t&&!a)return!1;if(void 0===e.date)return!1;const r=new Date(e.year,e.month-1,e.date).getTime();if(t){const[e,a,n]=t.split("-").map(Number);if(r<new Date(e,a-1,n).getTime())return!0}if(a){const[e,t,n]=a.split("-").map(Number);if(r>new Date(e,t-1,n).getTime())return!0}return!1},m=(e,t)=>{const a=new Date(e,t,0).getDate();return{lastDate:a,firstDay:new Date(e,t-1,1).getDay(),lastDay:new Date(e,t-1,a).getDay(),dateList:new Array(a).fill(null).map(((a,r)=>({year:e,month:t,date:r+1,day:new Date(e,t-1,r+1).getDay()})))}},i=t=>{const{year:a,month:r,date:n}=t,m=r.toString().padStart(2,"0"),i=null==n?void 0:n.toString().padStart(2,"0"),u=new Date(`${a}-${m}-${i}`),o=new Intl.DateTimeFormat("ko-KR",{timeZone:"Asia/Seoul",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!0}).format(u),[D,d,g,y,s]=o.replace(/\./g,"").split(" "),b=new Date(Number(D),Number(d)-1,Number(g)).getDay();return{year:`${D}년`,month:`${d}월`,date:`${g}일`,time:`${y} ${s}`,day:e.get(b)}};export{a as generateDate,i as getKoreanTimeString,m as getMonthDate,n as isDateOutOfRange,r as isSameDate,t as today};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use client";"use strict";var e=require("react/jsx-runtime"),a=require("react"),t=require("tailwind-merge");require("../../DataDisplays/Avatar/Avatar.js");var r=require("../../Base/Typography/Typography.js"),s=require("../../Base/Layouts/Box/Box.js");require("../../Base/Layouts/FullBleed/FullBleed.js");var n=require("../../DataDisplays/SystemIcon/SystemIcon.js");require("../../DataDisplays/SystemIcon/SystemIcon.constants.js"),require("../../DataDisplays/Accordion/Accordion.js");var i=require("../TextFieldContainer/TextFieldContainer.js"),l=require("./Calendar.parts.js"),d=require("./Calendar.utils.js");exports.Calendar=({defaultDate:o,selected:c,onChange:x,disabled:
|
|
1
|
+
"use client";"use strict";var e=require("react/jsx-runtime"),a=require("react"),t=require("tailwind-merge");require("../../DataDisplays/Avatar/Avatar.js");var r=require("../../Base/Typography/Typography.js"),s=require("../../Base/Layouts/Box/Box.js");require("../../Base/Layouts/FullBleed/FullBleed.js");var n=require("../../DataDisplays/SystemIcon/SystemIcon.js");require("../../DataDisplays/SystemIcon/SystemIcon.constants.js"),require("../../DataDisplays/Accordion/Accordion.js");var i=require("../TextFieldContainer/TextFieldContainer.js"),l=require("./Calendar.parts.js"),d=require("./Calendar.utils.js");exports.Calendar=({defaultDate:o,selected:c,onChange:x,disabled:g,placeholder:u,isError:m,className:y,triggerClassName:p,minDate:D,maxDate:h})=>{const[j,w]=a.useState(!1),f=()=>{g||w((e=>!e))},q=o?d.generateDate(o):d.today,[B,C]=a.useState(c?d.generateDate(c):q),b=c?d.generateDate(c):q,{year:S,month:v,date:N}=d.getKoreanTimeString(b),{dateList:$}=d.getMonthDate(B.year,B.month),T=[...Array.from({length:$[0].day},(()=>null)),...$],F=e=>{if(c&&d.isSameDate(e,b))return;if(d.isDateOutOfRange(e,D,h))return;const a=`${e.year}-${e.month}-${e.date}`;null==x||x(a),w(!1)};return a.useEffect((()=>{!j&&c&&C(d.generateDate(c));
|
|
2
2
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3
|
-
}),[
|
|
4
|
-
/*#__PURE__*/e.jsx(s.Box,{className:"cursor-pointer",children:/*#__PURE__*/e.jsxs(i.TextFieldContainer,{isFocused:
|
|
5
|
-
/*#__PURE__*/e.jsx(n.SystemIcon,{name:"medium_calendar",className:
|
|
6
|
-
/*#__PURE__*/e.jsx(r.Typography,{variant:"body16",className:t.twMerge("text-w-gray-600 min-w-[178px]",!c&&"text-w-gray-300",
|
|
7
|
-
/*#__PURE__*/e.jsx(l.SelectHeader,{visibleDate:
|
|
3
|
+
}),[j]),/*#__PURE__*/e.jsxs(s.Box,{className:t.twMerge("relative h-fit w-fit select-none",y),"data-testid":"design-system-calendar--container",children:[
|
|
4
|
+
/*#__PURE__*/e.jsx(s.Box,{className:"cursor-pointer",children:/*#__PURE__*/e.jsxs(i.TextFieldContainer,{isFocused:j,isError:m,isDisabled:g,testId:"design-system-calendar--trigger",onClick:f,className:p,children:[
|
|
5
|
+
/*#__PURE__*/e.jsx(n.SystemIcon,{name:"medium_calendar",className:g||!c?"text-w-gray-300":"text-w-gray-400"}),
|
|
6
|
+
/*#__PURE__*/e.jsx(r.Typography,{variant:"body16",className:t.twMerge("text-w-gray-600 min-w-[178px]",!c&&"text-w-gray-300",g&&"text-w-gray-300"),"data-testid":"design-system-calendar--selected-date",children:c?`${S} ${v} ${N}`:u})]})}),j&&/*#__PURE__*/e.jsx("div",{className:"fixed top-0 left-0 z-10 h-screen w-screen bg-transparent",onClick:f}),j&&/*#__PURE__*/e.jsxs(s.Box,{"data-testid":"design-system-calendar--content",className:"border-w-gray-200 bg-w-white shadow-graymedium absolute top-[54px] z-30 flex w-[350px] flex-col gap-4 rounded-xl border px-[15px] py-[23px]",children:[
|
|
7
|
+
/*#__PURE__*/e.jsx(l.SelectHeader,{visibleDate:B,onChange:e=>{C(e)}}),
|
|
8
8
|
/*#__PURE__*/e.jsx(l.WeekHeader,{}),
|
|
9
|
-
/*#__PURE__*/e.jsx(s.Box,{className:"grid w-full grid-cols-7 place-content-center place-items-center gap-1",children:
|
|
9
|
+
/*#__PURE__*/e.jsx(s.Box,{className:"grid w-full grid-cols-7 place-content-center place-items-center gap-1",children:T.map(((a,t)=>{const r=!(!a||!c)&&d.isSameDate(a,b);return a?/*#__PURE__*/e.jsx(l.DateBox,{date:a,selected:r,disabled:d.isDateOutOfRange(a,D,h),onChange:F},`${a.year}-${a.month}-${a.date}`):/*#__PURE__*/e.jsx(l.DateBox,{disabled:!0},t)}))})]})]})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("./Calendar.constants.js");const t={year:(new Date).getFullYear(),month:(new Date).getMonth()+1,date:(new Date).getDate(),day:(new Date).getDay()};exports.generateDate=e=>{const[t,a,r]=null==e?void 0:e.split("-"),n=new Date(Number(t),Number(a)-1,Number(r)).getDay();return{year:Number(t),month:Number(a),date:Number(r),day:n}},exports.getKoreanTimeString=t=>{const{year:a,month:r,date:n}=t,
|
|
1
|
+
"use strict";var e=require("./Calendar.constants.js");const t={year:(new Date).getFullYear(),month:(new Date).getMonth()+1,date:(new Date).getDate(),day:(new Date).getDay()};exports.generateDate=e=>{const[t,a,r]=null==e?void 0:e.split("-"),n=new Date(Number(t),Number(a)-1,Number(r)).getDay();return{year:Number(t),month:Number(a),date:Number(r),day:n}},exports.getKoreanTimeString=t=>{const{year:a,month:r,date:n}=t,i=r.toString().padStart(2,"0"),m=null==n?void 0:n.toString().padStart(2,"0"),o=new Date(`${a}-${i}-${m}`),u=new Intl.DateTimeFormat("ko-KR",{timeZone:"Asia/Seoul",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!0}).format(o),[D,s,g,d,y]=u.replace(/\./g,"").split(" "),b=new Date(Number(D),Number(s)-1,Number(g)).getDay();return{year:`${D}년`,month:`${s}월`,date:`${g}일`,time:`${d} ${y}`,day:e.dayMap.get(b)}},exports.getMonthDate=(e,t)=>{const a=new Date(e,t,0).getDate();return{lastDate:a,firstDay:new Date(e,t-1,1).getDay(),lastDay:new Date(e,t-1,a).getDay(),dateList:new Array(a).fill(null).map(((a,r)=>({year:e,month:t,date:r+1,day:new Date(e,t-1,r+1).getDay()})))}},exports.isDateOutOfRange=(e,t,a)=>{if(!t&&!a)return!1;if(void 0===e.date)return!1;const r=new Date(e.year,e.month-1,e.date).getTime();if(t){const[e,a,n]=t.split("-").map(Number);if(r<new Date(e,a-1,n).getTime())return!0}if(a){const[e,t,n]=a.split("-").map(Number);if(r>new Date(e,t-1,n).getTime())return!0}return!1},exports.isSameDate=(e,t)=>{if("string"==typeof e){const[a,r,n]=e.split("-");return new Date(Number(a),Number(r)-1,Number(n)).getTime()==new Date(t.year,Number(t.month)-1,Number(t.date)).getTime()}if("object"==typeof e)return new Date(e.year,Number(e.month)-1,Number(e.date)).getTime()==new Date(t.year,Number(t.month)-1,Number(t.date)).getTime()},exports.today=t;
|