calendar-simple 1.0.4

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/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Calendar App
2
+
3
+ A user-friendly calendar app for viewing, selecting, and managing dates with data management capabilities.
4
+
5
+ ## Features
6
+
7
+ - View and navigate through a monthly calendar
8
+ - Select dates and manage selected dates
9
+ - Customizable styling with Styled Components
10
+ - Support for data management and event handling
11
+ - Easy integration into React projects
12
+ - Lightweight and minimal dependencies
13
+
14
+ ## Tech Stack
15
+ - React JS
16
+ - TypeScrpit
17
+ - Styled Component
18
+ - Moment.js
19
+
20
+ ## Key Features
21
+
22
+ - **Monthly Calendar View:** Navigate through a monthly calendar with ease.
23
+ - **Date Selection:** Select single or multiple dates from the calendar.
24
+ - **Data Management:** Add, update, or remove data associated with selected dates.
25
+ - **Custom Styling:** Easily customize the calendar appearance using Styled Components.
26
+ - **Event Handling:** Handle user interactions and events seamlessly within the calendar component.
27
+
28
+ ## Installation
29
+ npm install --save calendar-simple
30
+
31
+ ## Usage
32
+ import React from 'react';
33
+ import { Calendar } from 'calendar-simple';
34
+
35
+ const App: React.FC = () => {
36
+ return (
37
+ <div>
38
+ <h1>Calendar App</h1>
39
+ <Calendar />
40
+ </div>
41
+ );
42
+ };
43
+
44
+ export default App;
45
+
46
+ ## Demo
47
+ For a live demonstration, you can visit [Demo Link](http://calendarsimple.netlify.app).
48
+
49
+ ## License
50
+ This project is licensed under the MIT License - see the LICENSE file for details.
@@ -0,0 +1,34 @@
1
+ import React$1 from 'react';
2
+
3
+ interface CalendarType {
4
+ dayType?: EDayType;
5
+ data?: React.ReactNode[];
6
+ width?: number;
7
+ height?: number;
8
+ selectedDate?: Date;
9
+ onDateClick?: (date: Date) => void;
10
+ onMonthChange?: (date: Date) => void;
11
+ isSelectDate?: boolean;
12
+ className?: string;
13
+ headerClassName?: string;
14
+ tableClassName?: string;
15
+ tableDateClassName?: string;
16
+ dataClassName?: string;
17
+ selectedClassName?: string;
18
+ todayClassName?: string;
19
+ pastYearLength?: number;
20
+ futureYearLength?: number;
21
+ }
22
+ declare enum EDayType {
23
+ fullName = "FULL",
24
+ halfName = "HALF"
25
+ }
26
+
27
+ declare const _default: React$1.NamedExoticComponent<CalendarType>;
28
+
29
+ declare const DAY_TYPE: {
30
+ FULL_NAME: string;
31
+ HALF_NAME: string;
32
+ };
33
+
34
+ export { type CalendarType, DAY_TYPE, EDayType, _default as default };
@@ -0,0 +1,34 @@
1
+ import React$1 from 'react';
2
+
3
+ interface CalendarType {
4
+ dayType?: EDayType;
5
+ data?: React.ReactNode[];
6
+ width?: number;
7
+ height?: number;
8
+ selectedDate?: Date;
9
+ onDateClick?: (date: Date) => void;
10
+ onMonthChange?: (date: Date) => void;
11
+ isSelectDate?: boolean;
12
+ className?: string;
13
+ headerClassName?: string;
14
+ tableClassName?: string;
15
+ tableDateClassName?: string;
16
+ dataClassName?: string;
17
+ selectedClassName?: string;
18
+ todayClassName?: string;
19
+ pastYearLength?: number;
20
+ futureYearLength?: number;
21
+ }
22
+ declare enum EDayType {
23
+ fullName = "FULL",
24
+ halfName = "HALF"
25
+ }
26
+
27
+ declare const _default: React$1.NamedExoticComponent<CalendarType>;
28
+
29
+ declare const DAY_TYPE: {
30
+ FULL_NAME: string;
31
+ HALF_NAME: string;
32
+ };
33
+
34
+ export { type CalendarType, DAY_TYPE, EDayType, _default as default };
package/dist/index.js ADDED
@@ -0,0 +1,445 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ DAY_TYPE: () => DAY_TYPE,
34
+ EDayType: () => EDayType,
35
+ default: () => src_default
36
+ });
37
+ module.exports = __toCommonJS(src_exports);
38
+
39
+ // src/components/Calendar.tsx
40
+ var import_react4 = __toESM(require("react"));
41
+
42
+ // src/components/Calendar.type.ts
43
+ var EDayType = /* @__PURE__ */ ((EDayType2) => {
44
+ EDayType2["fullName"] = "FULL";
45
+ EDayType2["halfName"] = "HALF";
46
+ return EDayType2;
47
+ })(EDayType || {});
48
+ var defaultCalenderProps = {
49
+ dayType: "HALF" /* halfName */,
50
+ data: [],
51
+ width: 400,
52
+ height: 400,
53
+ isSelectDate: false,
54
+ pastYearLength: 5,
55
+ futureYearLength: 5
56
+ };
57
+
58
+ // src/components/Calendar.constant.ts
59
+ var DAY_LIST = {
60
+ SUNDAY: {
61
+ FULL: "Sunday",
62
+ HALF: "Sun"
63
+ },
64
+ MONDAY: {
65
+ FULL: "Monday",
66
+ HALF: "Mon"
67
+ },
68
+ TUESDAY: {
69
+ FULL: "Tuesday",
70
+ HALF: "Tue"
71
+ },
72
+ WEDNESDAY: {
73
+ FULL: "Wednesday",
74
+ HALF: "Wed"
75
+ },
76
+ THURSDAY: {
77
+ FULL: "Thursday",
78
+ HALF: "Thu"
79
+ },
80
+ FRIDAY: {
81
+ FULL: "Friday",
82
+ HALF: "Fri"
83
+ },
84
+ SATURDAY: {
85
+ FULL: "Saturday",
86
+ HALF: "Sat"
87
+ }
88
+ };
89
+ var DAY_LIST_NAME = {
90
+ FULL: [
91
+ DAY_LIST.SUNDAY.FULL,
92
+ DAY_LIST.MONDAY.FULL,
93
+ DAY_LIST.TUESDAY.FULL,
94
+ DAY_LIST.WEDNESDAY.FULL,
95
+ DAY_LIST.THURSDAY.FULL,
96
+ DAY_LIST.FRIDAY.FULL,
97
+ DAY_LIST.SATURDAY.FULL
98
+ ],
99
+ HALF: [
100
+ DAY_LIST.SUNDAY.HALF,
101
+ DAY_LIST.MONDAY.HALF,
102
+ DAY_LIST.TUESDAY.HALF,
103
+ DAY_LIST.WEDNESDAY.HALF,
104
+ DAY_LIST.THURSDAY.HALF,
105
+ DAY_LIST.FRIDAY.HALF,
106
+ DAY_LIST.SATURDAY.HALF
107
+ ]
108
+ };
109
+ var MONTHS = {
110
+ JAN: { label: "January", value: 0 },
111
+ FEB: { label: "February", value: 1 },
112
+ MAR: { label: "March", value: 2 },
113
+ APR: { label: "April", value: 3 },
114
+ MAY: { label: "May", value: 4 },
115
+ JUN: { label: "June", value: 5 },
116
+ JUL: { label: "July", value: 6 },
117
+ AUG: { label: "August", value: 7 },
118
+ SEP: { label: "September", value: 8 },
119
+ OCT: { label: "October", value: 9 },
120
+ NOV: { label: "November", value: 10 },
121
+ DEC: { label: "December", value: 11 }
122
+ };
123
+ var MONTH_LIST = Object.values(MONTHS);
124
+ var CALENDER_STRINGS = {
125
+ MONTH: "monthDropdown",
126
+ YEAR: "yearDropdown"
127
+ };
128
+ var DAY_TYPE = {
129
+ FULL_NAME: "FULL",
130
+ HALF_NAME: "HALF"
131
+ };
132
+
133
+ // src/components/Calendar.utils.ts
134
+ var import_moment = __toESM(require("moment"));
135
+ var getNoOfDays = (date) => {
136
+ const noOfDates = date.daysInMonth();
137
+ return noOfDates;
138
+ };
139
+ var getMonthStartingDay = (date) => {
140
+ const monthStartingDay = Number(date.startOf("month").format("d"));
141
+ return monthStartingDay;
142
+ };
143
+ var convertToDate = (momentDate) => {
144
+ const date = momentDate.toDate();
145
+ return date;
146
+ };
147
+ var convertToMoment = (date) => {
148
+ const momentDate = (0, import_moment.default)(date);
149
+ return momentDate;
150
+ };
151
+ var getYearList = (pastLength, futureLength, selectedYear) => {
152
+ const yearLength = pastLength + futureLength;
153
+ const yearStarting = (0, import_moment.default)().year() - pastLength + 1;
154
+ const yearList = Array.from(
155
+ { length: yearLength },
156
+ (_, index) => index + yearStarting
157
+ );
158
+ if (!yearList.includes(selectedYear)) {
159
+ if ((0, import_moment.default)().year() <= selectedYear) {
160
+ yearList.push(selectedYear);
161
+ } else {
162
+ return [selectedYear, ...yearList];
163
+ }
164
+ }
165
+ return yearList;
166
+ };
167
+ var checkIsToday = (selectedDate, dates) => {
168
+ const cloneSelectedDate = selectedDate.clone();
169
+ cloneSelectedDate.date(dates);
170
+ const isToday = (0, import_moment.default)().isSame(cloneSelectedDate, "D");
171
+ return isToday;
172
+ };
173
+
174
+ // src/components/Calendar.styles.ts
175
+ var import_styled_components = __toESM(require("styled-components"));
176
+ var CalenderStyles = import_styled_components.default.section`
177
+ * {
178
+ padding: 0;
179
+ margin: 0;
180
+ outline: none;
181
+ }
182
+ width: ${(props) => props.$width};
183
+ height: ${(props) => props.$height};
184
+ & > div {
185
+ display: flex;
186
+ justify-content: space-between;
187
+ align-items: center;
188
+ padding: 0 10px;
189
+ margin-bottom: 10px;
190
+ & > div {
191
+ display: flex;
192
+ gap: 20px;
193
+ }
194
+ }
195
+ & > table {
196
+ border-collapse: collapse;
197
+ & th,
198
+ & td {
199
+ border: 1px solid black;
200
+ text-align: center;
201
+ min-width: calc(${(props) => props.$width} / 7);
202
+ max-width: calc(${(props) => props.$width} / 7);
203
+ }
204
+ & th {
205
+ height: calc(${(props) => props.$height} / 10);
206
+ }
207
+ & td {
208
+ height: calc(${(props) => props.$height} / 7);
209
+ }
210
+ }
211
+ `;
212
+ var ButtonStyles = import_styled_components.default.button`
213
+ outline: none;
214
+ border: none;
215
+ background: none;
216
+ color: rgb(211, 211, 211);
217
+ border-radius: 5px;
218
+ &:hover {
219
+ background-color: rgba(211, 211, 211, 0.5);
220
+ transition: 0.2s ease-in-out;
221
+ }
222
+ `;
223
+ var SelectStyles = import_styled_components.default.select`
224
+ border-radius: 3px;
225
+ padding: 2px;
226
+ `;
227
+ var Calendar_styles_default = CalenderStyles;
228
+
229
+ // src/components/DateData.tsx
230
+ var import_react = __toESM(require("react"));
231
+ var import_styled_components2 = __toESM(require("styled-components"));
232
+ var import_classnames = __toESM(require("classnames"));
233
+ function DateData(props) {
234
+ const {
235
+ date,
236
+ data,
237
+ className,
238
+ dataClassName,
239
+ isSelected,
240
+ isToday,
241
+ onClick,
242
+ selectedClassName,
243
+ todayClassName
244
+ } = props;
245
+ return /* @__PURE__ */ import_react.default.createElement(
246
+ DateDataStyles,
247
+ {
248
+ $isSelected: isSelected,
249
+ $isToday: isToday,
250
+ onClick: () => onClick?.(date),
251
+ className: (0, import_classnames.default)(
252
+ className,
253
+ isSelected && selectedClassName,
254
+ isToday && todayClassName
255
+ )
256
+ },
257
+ /* @__PURE__ */ import_react.default.createElement("div", null, /* @__PURE__ */ import_react.default.createElement("p", null, date), data && /* @__PURE__ */ import_react.default.createElement("div", { className: dataClassName }, data))
258
+ );
259
+ }
260
+ var DateDataStyles = import_styled_components2.default.td`
261
+ & > div {
262
+ height: 100%;
263
+ width: 100%;
264
+ display: flex;
265
+ flex-direction: column;
266
+ justify-content: space-around;
267
+ & > div > * {
268
+ overflow: hidden;
269
+ text-overflow: ellipsis;
270
+ white-space: nowrap;
271
+ }
272
+ }
273
+ ${(props) => props.$isSelected ? `
274
+ background-color: #EEEEEE;
275
+ color: #737373;
276
+ font-weight: bold;
277
+ ` : ``}
278
+ ${(props) => props.$isToday ? `
279
+ color: #2E75B6;
280
+ font-size: 18px;
281
+ font-weight: bold;
282
+ ` : ``}
283
+ `;
284
+ var DateData_default = DateData;
285
+
286
+ // src/assets/LeftArrow.tsx
287
+ var import_react2 = __toESM(require("react"));
288
+ function LeftArrow() {
289
+ return /* @__PURE__ */ import_react2.default.createElement("svg", { width: "40px", height: "40px", viewBox: "0 0 24.00 24.00", fill: "none", xmlns: "http://www.w3.org/2000/svg", stroke: "#707070", transform: "rotate(180)" }, /* @__PURE__ */ import_react2.default.createElement("g", { id: "SVGRepo_bgCarrier", strokeWidth: "0" }), /* @__PURE__ */ import_react2.default.createElement("g", { id: "SVGRepo_tracerCarrier", strokeLinecap: "round", strokeLinejoin: "round" }), /* @__PURE__ */ import_react2.default.createElement("g", { id: "SVGRepo_iconCarrier" }, /* @__PURE__ */ import_react2.default.createElement("path", { d: "M10 7L15 12L10 17", stroke: "#707070", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })));
290
+ }
291
+ var LeftArrow_default = LeftArrow;
292
+
293
+ // src/assets/RightArrow.tsx
294
+ var import_react3 = __toESM(require("react"));
295
+ function RightArrow() {
296
+ return /* @__PURE__ */ import_react3.default.createElement("svg", { width: "40px", height: "40px", viewBox: "0 0 24.00 24.00", fill: "none", xmlns: "http://www.w3.org/2000/svg", stroke: "#707070" }, /* @__PURE__ */ import_react3.default.createElement("g", { id: "SVGRepo_bgCarrier", strokeWidth: "0" }), /* @__PURE__ */ import_react3.default.createElement("g", { id: "SVGRepo_tracerCarrier", strokeLinecap: "round", strokeLinejoin: "round" }), /* @__PURE__ */ import_react3.default.createElement("g", { id: "SVGRepo_iconCarrier" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M10 7L15 12L10 17", stroke: "#707070", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })));
297
+ }
298
+ var RightArrow_default = RightArrow;
299
+
300
+ // src/components/Calendar.tsx
301
+ var Calender = (props = defaultCalenderProps) => {
302
+ const {
303
+ dayType = defaultCalenderProps.dayType,
304
+ data = defaultCalenderProps.data,
305
+ width = defaultCalenderProps.width,
306
+ height = defaultCalenderProps.height,
307
+ selectedDate: selected_date,
308
+ onDateClick,
309
+ onMonthChange,
310
+ isSelectDate = defaultCalenderProps.isSelectDate,
311
+ className,
312
+ headerClassName,
313
+ tableClassName,
314
+ tableDateClassName,
315
+ dataClassName,
316
+ selectedClassName,
317
+ todayClassName,
318
+ pastYearLength = defaultCalenderProps.pastYearLength,
319
+ futureYearLength = defaultCalenderProps.futureYearLength
320
+ } = props;
321
+ const selectedDateMoment = (0, import_react4.useMemo)(
322
+ () => selected_date ? convertToMoment(selected_date) : (0, import_moment.default)(),
323
+ [selected_date]
324
+ );
325
+ const [selectedDate, setSelectedDate] = (0, import_react4.useState)(selectedDateMoment);
326
+ (0, import_react4.useLayoutEffect)(() => {
327
+ setSelectedDate(selectedDateMoment);
328
+ }, [selectedDateMoment]);
329
+ const getDates = (0, import_react4.useCallback)(() => {
330
+ const dateComponent = [];
331
+ const noOfDays = getNoOfDays(selectedDate.clone());
332
+ const monthStartDay = getMonthStartingDay(selectedDate.clone());
333
+ const noOfRows = Math.round((noOfDays + monthStartDay) / 7 + 0.4);
334
+ let dates = 1;
335
+ const onClickDateHandler = (date) => {
336
+ const cloneSelectedDate = selectedDate.clone();
337
+ if (date !== cloneSelectedDate.date()) {
338
+ cloneSelectedDate.date(date);
339
+ setSelectedDate(cloneSelectedDate.clone());
340
+ onDateClick?.(convertToDate(cloneSelectedDate.clone()));
341
+ }
342
+ };
343
+ for (let row = 1; row <= noOfRows; row++) {
344
+ const tableRow = [];
345
+ for (let day = 1; day <= 7; day++) {
346
+ if (row === 1 && day <= monthStartDay || dates > noOfDays) {
347
+ const emptyData = /* @__PURE__ */ import_react4.default.createElement("td", { key: `empty_${day}` });
348
+ tableRow.push(emptyData);
349
+ } else {
350
+ const dateData = /* @__PURE__ */ import_react4.default.createElement(
351
+ DateData_default,
352
+ {
353
+ key: `date_${dates}`,
354
+ isSelected: isSelectDate && dates === selectedDate.date(),
355
+ isToday: checkIsToday(selectedDate, dates),
356
+ onClick: isSelectDate ? onClickDateHandler : void 0,
357
+ date: dates,
358
+ data: data[dates - 1],
359
+ className: tableDateClassName,
360
+ dataClassName,
361
+ selectedClassName,
362
+ todayClassName
363
+ }
364
+ );
365
+ dates++;
366
+ tableRow.push(dateData);
367
+ }
368
+ }
369
+ const rowData = /* @__PURE__ */ import_react4.default.createElement("tr", { key: row }, tableRow);
370
+ dateComponent.push(rowData);
371
+ }
372
+ return dateComponent;
373
+ }, [
374
+ data,
375
+ selectedDate,
376
+ dataClassName,
377
+ selectedClassName,
378
+ todayClassName,
379
+ tableDateClassName,
380
+ onDateClick,
381
+ isSelectDate
382
+ ]);
383
+ const onMonthArrowClick = (option) => {
384
+ const clonedSelectedDate = selectedDate.clone();
385
+ if (option === "add" /* add */) {
386
+ clonedSelectedDate.month(clonedSelectedDate.month() + 1);
387
+ } else if (option === "sub" /* sub */) {
388
+ clonedSelectedDate.month(clonedSelectedDate.month() - 1);
389
+ }
390
+ setSelectedDate(clonedSelectedDate);
391
+ onMonthChange?.(convertToDate(clonedSelectedDate));
392
+ };
393
+ const onDropdownClick = (event, option) => {
394
+ const value = Number(event.target.value);
395
+ const clonedSelectedDate = selectedDate.clone();
396
+ if (option === "month" /* month */) {
397
+ clonedSelectedDate.month(value);
398
+ } else if (option === "year" /* year */) {
399
+ clonedSelectedDate.year(value);
400
+ }
401
+ setSelectedDate(clonedSelectedDate);
402
+ onMonthChange?.(convertToDate(clonedSelectedDate));
403
+ };
404
+ return /* @__PURE__ */ import_react4.default.createElement(
405
+ Calendar_styles_default,
406
+ {
407
+ $width: `${width}px`,
408
+ $height: `${height}px`,
409
+ className
410
+ },
411
+ /* @__PURE__ */ import_react4.default.createElement("div", { className: headerClassName }, /* @__PURE__ */ import_react4.default.createElement(ButtonStyles, { onClick: () => onMonthArrowClick("sub" /* sub */) }, /* @__PURE__ */ import_react4.default.createElement(LeftArrow_default, null)), /* @__PURE__ */ import_react4.default.createElement("div", null, /* @__PURE__ */ import_react4.default.createElement(
412
+ SelectStyles,
413
+ {
414
+ id: CALENDER_STRINGS.MONTH,
415
+ name: CALENDER_STRINGS.MONTH,
416
+ value: selectedDate.month(),
417
+ onChange: (e) => onDropdownClick(e, "month" /* month */)
418
+ },
419
+ MONTH_LIST.map((month) => /* @__PURE__ */ import_react4.default.createElement("option", { key: month.label, value: month.value }, month.label))
420
+ ), /* @__PURE__ */ import_react4.default.createElement(
421
+ SelectStyles,
422
+ {
423
+ id: CALENDER_STRINGS.YEAR,
424
+ name: CALENDER_STRINGS.YEAR,
425
+ value: selectedDate.year(),
426
+ onChange: (e) => onDropdownClick(e, "year" /* year */)
427
+ },
428
+ getYearList(
429
+ pastYearLength,
430
+ futureYearLength,
431
+ selectedDate.year()
432
+ ).map((year) => /* @__PURE__ */ import_react4.default.createElement("option", { key: year, value: year }, year))
433
+ )), /* @__PURE__ */ import_react4.default.createElement(ButtonStyles, { onClick: () => onMonthArrowClick("add" /* add */) }, /* @__PURE__ */ import_react4.default.createElement(RightArrow_default, null))),
434
+ /* @__PURE__ */ import_react4.default.createElement("table", { className: tableClassName }, /* @__PURE__ */ import_react4.default.createElement("thead", null, /* @__PURE__ */ import_react4.default.createElement("tr", null, DAY_LIST_NAME[dayType].map((day) => /* @__PURE__ */ import_react4.default.createElement("th", { key: day }, day)))), /* @__PURE__ */ import_react4.default.createElement("tbody", null, getDates()))
435
+ );
436
+ };
437
+ var Calendar_default = (0, import_react4.memo)(Calender);
438
+
439
+ // src/index.ts
440
+ var src_default = Calendar_default;
441
+ // Annotate the CommonJS export names for ESM import in node:
442
+ 0 && (module.exports = {
443
+ DAY_TYPE,
444
+ EDayType
445
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,413 @@
1
+ // src/components/Calendar.tsx
2
+ import React4, {
3
+ useCallback,
4
+ useLayoutEffect,
5
+ useMemo,
6
+ useState,
7
+ memo
8
+ } from "react";
9
+
10
+ // src/components/Calendar.type.ts
11
+ var EDayType = /* @__PURE__ */ ((EDayType2) => {
12
+ EDayType2["fullName"] = "FULL";
13
+ EDayType2["halfName"] = "HALF";
14
+ return EDayType2;
15
+ })(EDayType || {});
16
+ var defaultCalenderProps = {
17
+ dayType: "HALF" /* halfName */,
18
+ data: [],
19
+ width: 400,
20
+ height: 400,
21
+ isSelectDate: false,
22
+ pastYearLength: 5,
23
+ futureYearLength: 5
24
+ };
25
+
26
+ // src/components/Calendar.constant.ts
27
+ var DAY_LIST = {
28
+ SUNDAY: {
29
+ FULL: "Sunday",
30
+ HALF: "Sun"
31
+ },
32
+ MONDAY: {
33
+ FULL: "Monday",
34
+ HALF: "Mon"
35
+ },
36
+ TUESDAY: {
37
+ FULL: "Tuesday",
38
+ HALF: "Tue"
39
+ },
40
+ WEDNESDAY: {
41
+ FULL: "Wednesday",
42
+ HALF: "Wed"
43
+ },
44
+ THURSDAY: {
45
+ FULL: "Thursday",
46
+ HALF: "Thu"
47
+ },
48
+ FRIDAY: {
49
+ FULL: "Friday",
50
+ HALF: "Fri"
51
+ },
52
+ SATURDAY: {
53
+ FULL: "Saturday",
54
+ HALF: "Sat"
55
+ }
56
+ };
57
+ var DAY_LIST_NAME = {
58
+ FULL: [
59
+ DAY_LIST.SUNDAY.FULL,
60
+ DAY_LIST.MONDAY.FULL,
61
+ DAY_LIST.TUESDAY.FULL,
62
+ DAY_LIST.WEDNESDAY.FULL,
63
+ DAY_LIST.THURSDAY.FULL,
64
+ DAY_LIST.FRIDAY.FULL,
65
+ DAY_LIST.SATURDAY.FULL
66
+ ],
67
+ HALF: [
68
+ DAY_LIST.SUNDAY.HALF,
69
+ DAY_LIST.MONDAY.HALF,
70
+ DAY_LIST.TUESDAY.HALF,
71
+ DAY_LIST.WEDNESDAY.HALF,
72
+ DAY_LIST.THURSDAY.HALF,
73
+ DAY_LIST.FRIDAY.HALF,
74
+ DAY_LIST.SATURDAY.HALF
75
+ ]
76
+ };
77
+ var MONTHS = {
78
+ JAN: { label: "January", value: 0 },
79
+ FEB: { label: "February", value: 1 },
80
+ MAR: { label: "March", value: 2 },
81
+ APR: { label: "April", value: 3 },
82
+ MAY: { label: "May", value: 4 },
83
+ JUN: { label: "June", value: 5 },
84
+ JUL: { label: "July", value: 6 },
85
+ AUG: { label: "August", value: 7 },
86
+ SEP: { label: "September", value: 8 },
87
+ OCT: { label: "October", value: 9 },
88
+ NOV: { label: "November", value: 10 },
89
+ DEC: { label: "December", value: 11 }
90
+ };
91
+ var MONTH_LIST = Object.values(MONTHS);
92
+ var CALENDER_STRINGS = {
93
+ MONTH: "monthDropdown",
94
+ YEAR: "yearDropdown"
95
+ };
96
+ var DAY_TYPE = {
97
+ FULL_NAME: "FULL",
98
+ HALF_NAME: "HALF"
99
+ };
100
+
101
+ // src/components/Calendar.utils.ts
102
+ import moment from "moment";
103
+ var getNoOfDays = (date) => {
104
+ const noOfDates = date.daysInMonth();
105
+ return noOfDates;
106
+ };
107
+ var getMonthStartingDay = (date) => {
108
+ const monthStartingDay = Number(date.startOf("month").format("d"));
109
+ return monthStartingDay;
110
+ };
111
+ var convertToDate = (momentDate) => {
112
+ const date = momentDate.toDate();
113
+ return date;
114
+ };
115
+ var convertToMoment = (date) => {
116
+ const momentDate = moment(date);
117
+ return momentDate;
118
+ };
119
+ var getYearList = (pastLength, futureLength, selectedYear) => {
120
+ const yearLength = pastLength + futureLength;
121
+ const yearStarting = moment().year() - pastLength + 1;
122
+ const yearList = Array.from(
123
+ { length: yearLength },
124
+ (_, index) => index + yearStarting
125
+ );
126
+ if (!yearList.includes(selectedYear)) {
127
+ if (moment().year() <= selectedYear) {
128
+ yearList.push(selectedYear);
129
+ } else {
130
+ return [selectedYear, ...yearList];
131
+ }
132
+ }
133
+ return yearList;
134
+ };
135
+ var checkIsToday = (selectedDate, dates) => {
136
+ const cloneSelectedDate = selectedDate.clone();
137
+ cloneSelectedDate.date(dates);
138
+ const isToday = moment().isSame(cloneSelectedDate, "D");
139
+ return isToday;
140
+ };
141
+
142
+ // src/components/Calendar.styles.ts
143
+ import styled from "styled-components";
144
+ var CalenderStyles = styled.section`
145
+ * {
146
+ padding: 0;
147
+ margin: 0;
148
+ outline: none;
149
+ }
150
+ width: ${(props) => props.$width};
151
+ height: ${(props) => props.$height};
152
+ & > div {
153
+ display: flex;
154
+ justify-content: space-between;
155
+ align-items: center;
156
+ padding: 0 10px;
157
+ margin-bottom: 10px;
158
+ & > div {
159
+ display: flex;
160
+ gap: 20px;
161
+ }
162
+ }
163
+ & > table {
164
+ border-collapse: collapse;
165
+ & th,
166
+ & td {
167
+ border: 1px solid black;
168
+ text-align: center;
169
+ min-width: calc(${(props) => props.$width} / 7);
170
+ max-width: calc(${(props) => props.$width} / 7);
171
+ }
172
+ & th {
173
+ height: calc(${(props) => props.$height} / 10);
174
+ }
175
+ & td {
176
+ height: calc(${(props) => props.$height} / 7);
177
+ }
178
+ }
179
+ `;
180
+ var ButtonStyles = styled.button`
181
+ outline: none;
182
+ border: none;
183
+ background: none;
184
+ color: rgb(211, 211, 211);
185
+ border-radius: 5px;
186
+ &:hover {
187
+ background-color: rgba(211, 211, 211, 0.5);
188
+ transition: 0.2s ease-in-out;
189
+ }
190
+ `;
191
+ var SelectStyles = styled.select`
192
+ border-radius: 3px;
193
+ padding: 2px;
194
+ `;
195
+ var Calendar_styles_default = CalenderStyles;
196
+
197
+ // src/components/DateData.tsx
198
+ import React from "react";
199
+ import styled2 from "styled-components";
200
+ import cx from "classnames";
201
+ function DateData(props) {
202
+ const {
203
+ date,
204
+ data,
205
+ className,
206
+ dataClassName,
207
+ isSelected,
208
+ isToday,
209
+ onClick,
210
+ selectedClassName,
211
+ todayClassName
212
+ } = props;
213
+ return /* @__PURE__ */ React.createElement(
214
+ DateDataStyles,
215
+ {
216
+ $isSelected: isSelected,
217
+ $isToday: isToday,
218
+ onClick: () => onClick?.(date),
219
+ className: cx(
220
+ className,
221
+ isSelected && selectedClassName,
222
+ isToday && todayClassName
223
+ )
224
+ },
225
+ /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", null, date), data && /* @__PURE__ */ React.createElement("div", { className: dataClassName }, data))
226
+ );
227
+ }
228
+ var DateDataStyles = styled2.td`
229
+ & > div {
230
+ height: 100%;
231
+ width: 100%;
232
+ display: flex;
233
+ flex-direction: column;
234
+ justify-content: space-around;
235
+ & > div > * {
236
+ overflow: hidden;
237
+ text-overflow: ellipsis;
238
+ white-space: nowrap;
239
+ }
240
+ }
241
+ ${(props) => props.$isSelected ? `
242
+ background-color: #EEEEEE;
243
+ color: #737373;
244
+ font-weight: bold;
245
+ ` : ``}
246
+ ${(props) => props.$isToday ? `
247
+ color: #2E75B6;
248
+ font-size: 18px;
249
+ font-weight: bold;
250
+ ` : ``}
251
+ `;
252
+ var DateData_default = DateData;
253
+
254
+ // src/assets/LeftArrow.tsx
255
+ import React2 from "react";
256
+ function LeftArrow() {
257
+ return /* @__PURE__ */ React2.createElement("svg", { width: "40px", height: "40px", viewBox: "0 0 24.00 24.00", fill: "none", xmlns: "http://www.w3.org/2000/svg", stroke: "#707070", transform: "rotate(180)" }, /* @__PURE__ */ React2.createElement("g", { id: "SVGRepo_bgCarrier", strokeWidth: "0" }), /* @__PURE__ */ React2.createElement("g", { id: "SVGRepo_tracerCarrier", strokeLinecap: "round", strokeLinejoin: "round" }), /* @__PURE__ */ React2.createElement("g", { id: "SVGRepo_iconCarrier" }, /* @__PURE__ */ React2.createElement("path", { d: "M10 7L15 12L10 17", stroke: "#707070", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })));
258
+ }
259
+ var LeftArrow_default = LeftArrow;
260
+
261
+ // src/assets/RightArrow.tsx
262
+ import React3 from "react";
263
+ function RightArrow() {
264
+ return /* @__PURE__ */ React3.createElement("svg", { width: "40px", height: "40px", viewBox: "0 0 24.00 24.00", fill: "none", xmlns: "http://www.w3.org/2000/svg", stroke: "#707070" }, /* @__PURE__ */ React3.createElement("g", { id: "SVGRepo_bgCarrier", strokeWidth: "0" }), /* @__PURE__ */ React3.createElement("g", { id: "SVGRepo_tracerCarrier", strokeLinecap: "round", strokeLinejoin: "round" }), /* @__PURE__ */ React3.createElement("g", { id: "SVGRepo_iconCarrier" }, /* @__PURE__ */ React3.createElement("path", { d: "M10 7L15 12L10 17", stroke: "#707070", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })));
265
+ }
266
+ var RightArrow_default = RightArrow;
267
+
268
+ // src/components/Calendar.tsx
269
+ var Calender = (props = defaultCalenderProps) => {
270
+ const {
271
+ dayType = defaultCalenderProps.dayType,
272
+ data = defaultCalenderProps.data,
273
+ width = defaultCalenderProps.width,
274
+ height = defaultCalenderProps.height,
275
+ selectedDate: selected_date,
276
+ onDateClick,
277
+ onMonthChange,
278
+ isSelectDate = defaultCalenderProps.isSelectDate,
279
+ className,
280
+ headerClassName,
281
+ tableClassName,
282
+ tableDateClassName,
283
+ dataClassName,
284
+ selectedClassName,
285
+ todayClassName,
286
+ pastYearLength = defaultCalenderProps.pastYearLength,
287
+ futureYearLength = defaultCalenderProps.futureYearLength
288
+ } = props;
289
+ const selectedDateMoment = useMemo(
290
+ () => selected_date ? convertToMoment(selected_date) : moment(),
291
+ [selected_date]
292
+ );
293
+ const [selectedDate, setSelectedDate] = useState(selectedDateMoment);
294
+ useLayoutEffect(() => {
295
+ setSelectedDate(selectedDateMoment);
296
+ }, [selectedDateMoment]);
297
+ const getDates = useCallback(() => {
298
+ const dateComponent = [];
299
+ const noOfDays = getNoOfDays(selectedDate.clone());
300
+ const monthStartDay = getMonthStartingDay(selectedDate.clone());
301
+ const noOfRows = Math.round((noOfDays + monthStartDay) / 7 + 0.4);
302
+ let dates = 1;
303
+ const onClickDateHandler = (date) => {
304
+ const cloneSelectedDate = selectedDate.clone();
305
+ if (date !== cloneSelectedDate.date()) {
306
+ cloneSelectedDate.date(date);
307
+ setSelectedDate(cloneSelectedDate.clone());
308
+ onDateClick?.(convertToDate(cloneSelectedDate.clone()));
309
+ }
310
+ };
311
+ for (let row = 1; row <= noOfRows; row++) {
312
+ const tableRow = [];
313
+ for (let day = 1; day <= 7; day++) {
314
+ if (row === 1 && day <= monthStartDay || dates > noOfDays) {
315
+ const emptyData = /* @__PURE__ */ React4.createElement("td", { key: `empty_${day}` });
316
+ tableRow.push(emptyData);
317
+ } else {
318
+ const dateData = /* @__PURE__ */ React4.createElement(
319
+ DateData_default,
320
+ {
321
+ key: `date_${dates}`,
322
+ isSelected: isSelectDate && dates === selectedDate.date(),
323
+ isToday: checkIsToday(selectedDate, dates),
324
+ onClick: isSelectDate ? onClickDateHandler : void 0,
325
+ date: dates,
326
+ data: data[dates - 1],
327
+ className: tableDateClassName,
328
+ dataClassName,
329
+ selectedClassName,
330
+ todayClassName
331
+ }
332
+ );
333
+ dates++;
334
+ tableRow.push(dateData);
335
+ }
336
+ }
337
+ const rowData = /* @__PURE__ */ React4.createElement("tr", { key: row }, tableRow);
338
+ dateComponent.push(rowData);
339
+ }
340
+ return dateComponent;
341
+ }, [
342
+ data,
343
+ selectedDate,
344
+ dataClassName,
345
+ selectedClassName,
346
+ todayClassName,
347
+ tableDateClassName,
348
+ onDateClick,
349
+ isSelectDate
350
+ ]);
351
+ const onMonthArrowClick = (option) => {
352
+ const clonedSelectedDate = selectedDate.clone();
353
+ if (option === "add" /* add */) {
354
+ clonedSelectedDate.month(clonedSelectedDate.month() + 1);
355
+ } else if (option === "sub" /* sub */) {
356
+ clonedSelectedDate.month(clonedSelectedDate.month() - 1);
357
+ }
358
+ setSelectedDate(clonedSelectedDate);
359
+ onMonthChange?.(convertToDate(clonedSelectedDate));
360
+ };
361
+ const onDropdownClick = (event, option) => {
362
+ const value = Number(event.target.value);
363
+ const clonedSelectedDate = selectedDate.clone();
364
+ if (option === "month" /* month */) {
365
+ clonedSelectedDate.month(value);
366
+ } else if (option === "year" /* year */) {
367
+ clonedSelectedDate.year(value);
368
+ }
369
+ setSelectedDate(clonedSelectedDate);
370
+ onMonthChange?.(convertToDate(clonedSelectedDate));
371
+ };
372
+ return /* @__PURE__ */ React4.createElement(
373
+ Calendar_styles_default,
374
+ {
375
+ $width: `${width}px`,
376
+ $height: `${height}px`,
377
+ className
378
+ },
379
+ /* @__PURE__ */ React4.createElement("div", { className: headerClassName }, /* @__PURE__ */ React4.createElement(ButtonStyles, { onClick: () => onMonthArrowClick("sub" /* sub */) }, /* @__PURE__ */ React4.createElement(LeftArrow_default, null)), /* @__PURE__ */ React4.createElement("div", null, /* @__PURE__ */ React4.createElement(
380
+ SelectStyles,
381
+ {
382
+ id: CALENDER_STRINGS.MONTH,
383
+ name: CALENDER_STRINGS.MONTH,
384
+ value: selectedDate.month(),
385
+ onChange: (e) => onDropdownClick(e, "month" /* month */)
386
+ },
387
+ MONTH_LIST.map((month) => /* @__PURE__ */ React4.createElement("option", { key: month.label, value: month.value }, month.label))
388
+ ), /* @__PURE__ */ React4.createElement(
389
+ SelectStyles,
390
+ {
391
+ id: CALENDER_STRINGS.YEAR,
392
+ name: CALENDER_STRINGS.YEAR,
393
+ value: selectedDate.year(),
394
+ onChange: (e) => onDropdownClick(e, "year" /* year */)
395
+ },
396
+ getYearList(
397
+ pastYearLength,
398
+ futureYearLength,
399
+ selectedDate.year()
400
+ ).map((year) => /* @__PURE__ */ React4.createElement("option", { key: year, value: year }, year))
401
+ )), /* @__PURE__ */ React4.createElement(ButtonStyles, { onClick: () => onMonthArrowClick("add" /* add */) }, /* @__PURE__ */ React4.createElement(RightArrow_default, null))),
402
+ /* @__PURE__ */ React4.createElement("table", { className: tableClassName }, /* @__PURE__ */ React4.createElement("thead", null, /* @__PURE__ */ React4.createElement("tr", null, DAY_LIST_NAME[dayType].map((day) => /* @__PURE__ */ React4.createElement("th", { key: day }, day)))), /* @__PURE__ */ React4.createElement("tbody", null, getDates()))
403
+ );
404
+ };
405
+ var Calendar_default = memo(Calender);
406
+
407
+ // src/index.ts
408
+ var src_default = Calendar_default;
409
+ export {
410
+ DAY_TYPE,
411
+ EDayType,
412
+ src_default as default
413
+ };
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "calendar-simple",
3
+ "version": "1.0.4",
4
+ "description": "A user-friendly calendar app for viewing, selecting, and managing dates with data management capabilities.",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.esm.js",
7
+ "types": "./dist/index.d.ts",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/Jaganath-MSJ/CalendarSimple.git"
11
+ },
12
+ "scripts": {
13
+ "build": "tsup"
14
+ },
15
+ "keywords": [
16
+ "calendar",
17
+ "simple",
18
+ "calendar-simple"
19
+ ],
20
+ "author": "jaganath-m-s",
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "classnames": "^2.5.1",
24
+ "moment": "^2.30.1",
25
+ "react-scripts": "5.0.1",
26
+ "styled-components": "^6.1.8"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^16.18.76",
30
+ "@types/react": "^18.2.48",
31
+ "@types/react-dom": "^18.2.18",
32
+ "babel-loader": "^9.1.3",
33
+ "prettier": "^3.2.5",
34
+ "tsup": "^8.0.2",
35
+ "typescript": "^4.9.5",
36
+ "web-vitals": "^2.1.4"
37
+ },
38
+ "peerDependencies": {
39
+ "react": "^18.2.0",
40
+ "react-dom": "^18.2.0"
41
+ }
42
+ }