daliry-mobile-date-picker 1.0.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/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "daliry-mobile-date-picker",
3
+ "version": "1.0.0",
4
+ "packageManager": "yarn@4.5.2",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/MobileDatePicker.d.ts",
8
+ "scripts": {
9
+ "build": "node build.js && tsc"
10
+ },
11
+ "peerDependencies": {
12
+ "react": "^18.3.1",
13
+ "react-dom": "^18.3.1"
14
+ },
15
+ "dependencies": {
16
+ "@alwatr/nano-build": "^5.5.0",
17
+ "moment-jalaali": "^0.10.4",
18
+ "react": "^18.3.1",
19
+ "react-dom": "^18.3.1"
20
+ },
21
+ "devDependencies": {
22
+ "@types/moment-jalaali": "^0.7.9",
23
+ "@types/react": "^19.0.10",
24
+ "@types/react-dom": "^19.0.4",
25
+ "esbuild": "^0.25.1"
26
+ },
27
+ "keywords": ["react", "datepicker", "jalali", "persian", "calendar"],
28
+ "author": "Mahdi Daliry",
29
+ "license": "MIT"
30
+ }
@@ -0,0 +1,123 @@
1
+ import { useState, useRef, useEffect } from "react";
2
+ import moment, { Moment } from "moment-jalaali";
3
+ import "./mobileDatePicker.css";
4
+ // export * from '.';
5
+
6
+ export interface IDate {
7
+ jYear: number;
8
+ jMonth: number;
9
+ jDay: number;
10
+ jDate: string;
11
+ date: string;
12
+ gDate: string;
13
+ moment: Moment;
14
+ }
15
+
16
+ interface IMobileDatePicker {
17
+ onDateChange: (date: IDate) => void;
18
+ isBirthdate?: boolean;
19
+ }
20
+
21
+ const jalaliMonths = [
22
+ "", "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور",
23
+ "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", ""
24
+ ];
25
+
26
+ const years = Array.from({ length: 1308 }, (_, i) => 1308 + i);
27
+ const days = Array.from({ length: 33 }, (_, i) => i);
28
+
29
+ const MobileDatePicker = ({ onDateChange, isBirthdate = false }: IMobileDatePicker) => {
30
+ const today = moment();
31
+ const [selectedYear, setSelectedYear] = useState(isBirthdate ? 1388 : today.jYear() - 1);
32
+ const [selectedMonth, setSelectedMonth] = useState(isBirthdate ? 6 : today.jMonth());
33
+ const [selectedDay, setSelectedDay] = useState(isBirthdate ? 2 : today.jDate() - 1);
34
+
35
+ const listRef = useRef<HTMLDivElement>(null);
36
+ const listRefMonths = useRef<HTMLDivElement>(null);
37
+ const listRefDays = useRef<HTMLDivElement>(null);
38
+
39
+ const selectDateFunction = () => {
40
+ const gDate = moment(`${selectedYear}-${selectedMonth}-${selectedDay}`, "jYYYY-jMM-jDD").format("YYYY-MM-DD");
41
+ onDateChange({
42
+ jYear: selectedYear,
43
+ jMonth: selectedMonth,
44
+ jDay: selectedDay,
45
+ jDate: `${selectedYear}-${selectedMonth}-${selectedDay}`,
46
+ date: gDate,
47
+ gDate,
48
+ moment: moment(`${selectedYear}-${selectedMonth}-${selectedDay}`, "jYYYY-jMM-jDD"),
49
+ });
50
+ };
51
+
52
+ useEffect(() => {
53
+ if (isBirthdate) selectDateFunction();
54
+ }, [selectedYear, selectedMonth, selectedDay]);
55
+
56
+ useEffect(() => {
57
+ listRef.current?.scrollTo({ top: years.indexOf(selectedYear) * 45, behavior: "smooth" });
58
+ listRefMonths.current?.scrollTo({ top: selectedMonth * 45, behavior: "smooth" });
59
+ listRefDays.current?.scrollTo({ top: selectedDay * 45, behavior: "smooth" });
60
+ }, []);
61
+
62
+ const handleScroll = () => {
63
+ const index = Math.round((listRef.current?.scrollTop || 0) / 45);
64
+ setSelectedYear(years[index + 1]);
65
+ };
66
+
67
+ const handleScrollMonths = () => {
68
+ const index = Math.round((listRefMonths.current?.scrollTop || 0) / 45);
69
+ setSelectedMonth(index + 1);
70
+ };
71
+
72
+ const handleScrollDays = () => {
73
+ const index = Math.round((listRefDays.current?.scrollTop || 0) / 45);
74
+ setSelectedDay(index + 1);
75
+ };
76
+
77
+ return (
78
+ <div className="datepicker-container">
79
+ <div className="scroll-lists">
80
+ <div className="scroll-list" onScroll={handleScrollDays} ref={listRefDays}>
81
+ {days.map((day, i) => (
82
+ <div
83
+ key={i}
84
+ className={`scroll-item ${day === selectedDay ? "selected" : ""}`}
85
+ >
86
+ {day}
87
+ </div>
88
+ ))}
89
+ </div>
90
+
91
+ <div className="scroll-list" onScroll={handleScrollMonths} ref={listRefMonths}>
92
+ {jalaliMonths.map((month, i) => (
93
+ <div
94
+ key={i}
95
+ className={`scroll-item ${i === selectedMonth ? "selected" : ""}`}
96
+ >
97
+ {month}
98
+ </div>
99
+ ))}
100
+ </div>
101
+
102
+ <div className="scroll-list" onScroll={handleScroll} ref={listRef}>
103
+ {years.map((year) => (
104
+ <div
105
+ key={year}
106
+ className={`scroll-item ${year === selectedYear ? "selected" : ""}`}
107
+ >
108
+ {year}
109
+ </div>
110
+ ))}
111
+ </div>
112
+ </div>
113
+
114
+ {!isBirthdate && (
115
+ <button className="apply-button" onClick={selectDateFunction}>
116
+ اعمال تاریخ
117
+ </button>
118
+ )}
119
+ </div>
120
+ );
121
+ };
122
+
123
+ export default MobileDatePicker;
package/src/index.tsx ADDED
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ import {useEffect} from "react";
3
+
4
+
5
+ const NegarAuth: React.FC = () => {
6
+ useEffect(() => {
7
+ console.log('test')
8
+ }, []);
9
+ return <div>Negar Auth Component</div>;
10
+ };
11
+ export default NegarAuth;
12
+
@@ -0,0 +1,59 @@
1
+ .datepicker-container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ gap: 16px;
6
+ width: 100%;
7
+ }
8
+
9
+ .scroll-lists {
10
+ display: flex;
11
+ justify-content: space-between;
12
+ background-color: #f5f5f5;
13
+ border-radius: 12px;
14
+ height: 152px;
15
+ width: 100%;
16
+ }
17
+
18
+ .scroll-list {
19
+ width: 110px;
20
+ height: 152px;
21
+ overflow-y: auto;
22
+ scroll-snap-type: y mandatory;
23
+ scrollbar-width: none;
24
+ -ms-overflow-style: none;
25
+ }
26
+
27
+ .scroll-list::-webkit-scrollbar {
28
+ display: none;
29
+ }
30
+
31
+ .scroll-item {
32
+ height: 45px;
33
+ line-height: 45px;
34
+ text-align: center;
35
+ scroll-snap-align: center;
36
+ color: #bbb;
37
+ font-size: 16px;
38
+ opacity: 0.5;
39
+ filter: blur(4px);
40
+ font-weight: normal;
41
+ }
42
+
43
+ .scroll-item.selected {
44
+ color: #333;
45
+ font-size: 20px;
46
+ font-weight: bold;
47
+ opacity: 1;
48
+ filter: none;
49
+ }
50
+
51
+ .apply-button {
52
+ padding: 10px 20px;
53
+ background-color: #1976d2;
54
+ color: white;
55
+ border: none;
56
+ border-radius: 8px;
57
+ font-size: 16px;
58
+ cursor: pointer;
59
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "declaration": true,
4
+ "emitDeclarationOnly": true,
5
+ "outDir": "dist",
6
+ "jsx": "react-jsx",
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "module": "ESNext",
10
+ "target": "ESNext",
11
+ "moduleResolution": "Node",
12
+ "strict": true,
13
+ "baseUrl": "./src",
14
+ "allowSyntheticDefaultImports": true
15
+ },
16
+ "include": ["src"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }