ar-design 0.4.25 → 0.4.27
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/assets/css/components/data-display/calendar/styles.css +15 -0
- package/dist/assets/css/components/data-display/calendar/styles.week-view.css +124 -0
- package/dist/components/data-display/calendar/Body.d.ts +21 -0
- package/dist/components/data-display/calendar/Body.js +14 -0
- package/dist/components/data-display/calendar/Header.d.ts +20 -0
- package/dist/components/data-display/calendar/Header.js +26 -0
- package/dist/components/data-display/calendar/IProps.d.ts +12 -0
- package/dist/components/data-display/calendar/IProps.js +1 -0
- package/dist/components/data-display/calendar/index.d.ts +5 -0
- package/dist/components/data-display/calendar/index.js +27 -0
- package/dist/components/data-display/calendar/views/Day.d.ts +3 -0
- package/dist/components/data-display/calendar/views/Day.js +5 -0
- package/dist/components/data-display/calendar/views/Month.d.ts +3 -0
- package/dist/components/data-display/calendar/views/Month.js +5 -0
- package/dist/components/data-display/calendar/views/Week.d.ts +17 -0
- package/dist/components/data-display/calendar/views/Week.js +99 -0
- package/dist/components/data-display/table/IProps.d.ts +1 -0
- package/dist/components/data-display/table/body/Editable.d.ts +3 -1
- package/dist/components/data-display/table/body/Editable.js +3 -3
- package/dist/components/data-display/table/body/TBody.js +7 -1
- package/dist/components/data-display/table/index.js +1 -1
- package/dist/components/form/date-picker/Props.d.ts +1 -0
- package/dist/components/form/input/decimal/Decimal.js +25 -13
- package/dist/components/form/input/decimal/IProps.d.ts +1 -0
- package/dist/components/form/input/formatted-decimal/FormattedDecimal.js +30 -40
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/libs/types/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
.ar-calendar {
|
|
2
|
+
> .ar-calendar-week-view {
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
align-items: flex-end;
|
|
6
|
+
background-color: var(--white);
|
|
7
|
+
padding: 0.75rem 0.75rem 0.75rem 2rem;
|
|
8
|
+
border-radius: var(--border-radius-sm);
|
|
9
|
+
|
|
10
|
+
> .head {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: row;
|
|
13
|
+
width: 100%;
|
|
14
|
+
|
|
15
|
+
> .item {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: 1rem;
|
|
20
|
+
width: calc(100% / 7);
|
|
21
|
+
padding: 0.5rem 0;
|
|
22
|
+
|
|
23
|
+
> .day-name {
|
|
24
|
+
color: var(--gray-400);
|
|
25
|
+
font-size: 0.75rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
> .date {
|
|
29
|
+
font-size: 1.5rem;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
> .body {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: row;
|
|
37
|
+
width: 100%;
|
|
38
|
+
|
|
39
|
+
> .clocks {
|
|
40
|
+
> div {
|
|
41
|
+
height: 60px;
|
|
42
|
+
|
|
43
|
+
> span {
|
|
44
|
+
color: var(--gray-700);
|
|
45
|
+
font-size: 0.75rem;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
> .grid {
|
|
51
|
+
position: relative;
|
|
52
|
+
width: 100%;
|
|
53
|
+
border: solid 1px transparent;
|
|
54
|
+
border-top-color: var(--gray-200);
|
|
55
|
+
|
|
56
|
+
> .events-layer {
|
|
57
|
+
position: absolute;
|
|
58
|
+
top: 0;
|
|
59
|
+
left: 0;
|
|
60
|
+
right: 0;
|
|
61
|
+
z-index: 1;
|
|
62
|
+
|
|
63
|
+
> .event-box {
|
|
64
|
+
position: absolute;
|
|
65
|
+
background-color: rgba(var(--primary-rgb), 0.75);
|
|
66
|
+
width: calc(100% / 7);
|
|
67
|
+
padding: 0.5rem;
|
|
68
|
+
border-radius: var(--border-radius-sm);
|
|
69
|
+
color: var(--white);
|
|
70
|
+
font-size: 12px;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
> .row {
|
|
75
|
+
position: relative;
|
|
76
|
+
margin: auto;
|
|
77
|
+
|
|
78
|
+
&:nth-child(2) {
|
|
79
|
+
> .cell {
|
|
80
|
+
&::before {
|
|
81
|
+
content: "";
|
|
82
|
+
position: absolute;
|
|
83
|
+
left: -1px;
|
|
84
|
+
background-color: var(--gray-200);
|
|
85
|
+
width: 1px;
|
|
86
|
+
height: 25px;
|
|
87
|
+
transform: translateY(-25px);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&:last-child {
|
|
93
|
+
> .cell {
|
|
94
|
+
border-bottom-color: transparent;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
> .cell {
|
|
99
|
+
position: relative;
|
|
100
|
+
width: calc(100% / 7);
|
|
101
|
+
height: 60px;
|
|
102
|
+
padding: 0;
|
|
103
|
+
border: solid 1px transparent;
|
|
104
|
+
border-left-color: var(--gray-200);
|
|
105
|
+
border-bottom-color: var(--gray-200);
|
|
106
|
+
|
|
107
|
+
&:first-child {
|
|
108
|
+
&::after {
|
|
109
|
+
content: "";
|
|
110
|
+
position: absolute;
|
|
111
|
+
top: -2px;
|
|
112
|
+
left: 0;
|
|
113
|
+
background-color: var(--gray-200);
|
|
114
|
+
width: 15px;
|
|
115
|
+
height: 1px;
|
|
116
|
+
transform: translateX(-15px);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "../../../libs/types";
|
|
3
|
+
import { CalendarEvent } from "./IProps";
|
|
4
|
+
interface IProps {
|
|
5
|
+
data: CalendarEvent[];
|
|
6
|
+
states: {
|
|
7
|
+
currentDate: {
|
|
8
|
+
get: Date;
|
|
9
|
+
set: React.Dispatch<React.SetStateAction<Date>>;
|
|
10
|
+
};
|
|
11
|
+
view: {
|
|
12
|
+
get: View;
|
|
13
|
+
set: React.Dispatch<React.SetStateAction<View>>;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
config?: {
|
|
17
|
+
locale?: Intl.LocalesArgument;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
declare const Body: ({ data, states, config }: IProps) => React.JSX.Element;
|
|
21
|
+
export default Body;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Day from "./views/Day";
|
|
3
|
+
import Week from "./views/Week";
|
|
4
|
+
import Month from "./views/Month";
|
|
5
|
+
const Body = ({ data, states, config }) => {
|
|
6
|
+
if (states.view.get === "Day")
|
|
7
|
+
return React.createElement(Day, null);
|
|
8
|
+
else if (states.view.get === "Week")
|
|
9
|
+
return React.createElement(Week, { data: data, states: { currentDate: states.currentDate }, config: config });
|
|
10
|
+
else if (states.view.get === "Month")
|
|
11
|
+
return React.createElement(Month, null);
|
|
12
|
+
return React.createElement(React.Fragment, null, "...");
|
|
13
|
+
};
|
|
14
|
+
export default Body;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "../../../libs/types";
|
|
3
|
+
interface IProps {
|
|
4
|
+
states: {
|
|
5
|
+
currentDate: {
|
|
6
|
+
get: Date;
|
|
7
|
+
set: React.Dispatch<React.SetStateAction<Date>>;
|
|
8
|
+
};
|
|
9
|
+
view: {
|
|
10
|
+
get: View;
|
|
11
|
+
set: React.Dispatch<React.SetStateAction<View>>;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
config?: {
|
|
15
|
+
locale?: Intl.LocalesArgument;
|
|
16
|
+
weekStartsOn?: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
declare const Header: ({ states, config }: IProps) => React.JSX.Element;
|
|
20
|
+
export default Header;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Button from "../../form/button";
|
|
3
|
+
import { ARIcon } from "../../icons";
|
|
4
|
+
import Box from "../grid-system/box/Box";
|
|
5
|
+
const Header = ({ states, config }) => {
|
|
6
|
+
// methods
|
|
7
|
+
const changeWeek = (direction) => {
|
|
8
|
+
states.currentDate.set((prev) => {
|
|
9
|
+
if (direction === "today")
|
|
10
|
+
return new Date();
|
|
11
|
+
const newDate = new Date(prev);
|
|
12
|
+
newDate.setDate(prev.getDate() + (direction === "next" ? 7 : -7));
|
|
13
|
+
return newDate;
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
return (React.createElement("div", { className: "header" },
|
|
17
|
+
React.createElement(Box, null,
|
|
18
|
+
React.createElement(Button, { variant: "outlined", color: "green", border: { radius: "xxl" }, onClick: () => changeWeek("today") }, "Bug\u00FCn"),
|
|
19
|
+
React.createElement(Button, { variant: "borderless", color: "light", border: { radius: "pill" }, icon: { element: React.createElement(ARIcon, { icon: "ArrowLeft", stroke: "currentColor" }) }, onClick: () => changeWeek("prev") }),
|
|
20
|
+
React.createElement(Button, { variant: "borderless", color: "light", border: { radius: "pill" }, icon: { element: React.createElement(ARIcon, { icon: "ArrowRight", stroke: "currentColor" }) }, onClick: () => changeWeek("next") }),
|
|
21
|
+
React.createElement("span", { className: "week-time" },
|
|
22
|
+
states.currentDate.get.toLocaleString(config?.locale ?? "tr-TR", { month: "long" }),
|
|
23
|
+
" ",
|
|
24
|
+
states.currentDate.get.getFullYear()))));
|
|
25
|
+
};
|
|
26
|
+
export default Header;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import Body from "./Body";
|
|
4
|
+
import Header from "./Header";
|
|
5
|
+
import "../../../assets/css/components/data-display/calendar/styles.css";
|
|
6
|
+
const Calendar = ({ data, config }) => {
|
|
7
|
+
// states
|
|
8
|
+
const [currentDate, setCurrentDate] = useState(new Date());
|
|
9
|
+
const [view, setView] = useState("Week");
|
|
10
|
+
return (React.createElement("div", { className: "ar-calendar" },
|
|
11
|
+
React.createElement(Header, { states: {
|
|
12
|
+
currentDate: { get: currentDate, set: setCurrentDate },
|
|
13
|
+
view: {
|
|
14
|
+
get: view,
|
|
15
|
+
set: setView,
|
|
16
|
+
},
|
|
17
|
+
}, config: config }),
|
|
18
|
+
React.createElement(Body, { data: data, states: {
|
|
19
|
+
currentDate: { get: currentDate, set: setCurrentDate },
|
|
20
|
+
view: {
|
|
21
|
+
get: view,
|
|
22
|
+
set: setView,
|
|
23
|
+
},
|
|
24
|
+
}, config: config })));
|
|
25
|
+
};
|
|
26
|
+
Calendar.displayName = "DatePicker";
|
|
27
|
+
export default Calendar;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CalendarEvent } from "../IProps";
|
|
3
|
+
interface IProps {
|
|
4
|
+
data: CalendarEvent[];
|
|
5
|
+
states: {
|
|
6
|
+
currentDate: {
|
|
7
|
+
get: Date;
|
|
8
|
+
set: React.Dispatch<React.SetStateAction<Date>>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
config?: {
|
|
12
|
+
locale?: Intl.LocalesArgument;
|
|
13
|
+
weekStartsOn?: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
declare const Week: ({ data, states, config }: IProps) => React.JSX.Element;
|
|
17
|
+
export default Week;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, useState } from "react";
|
|
2
|
+
const Week = ({ data, states, config }) => {
|
|
3
|
+
const startHour = 0;
|
|
4
|
+
const endHour = 24;
|
|
5
|
+
const hours = endHour - startHour;
|
|
6
|
+
const cellHeight = 60;
|
|
7
|
+
// const slotDuration = 15;
|
|
8
|
+
// const slotHeight = cellHeight / (60 / slotDuration);
|
|
9
|
+
// states
|
|
10
|
+
const [events, setEvents] = useState([]);
|
|
11
|
+
// const [tempStart, setTempStart] = useState<{
|
|
12
|
+
// date: Date;
|
|
13
|
+
// minutes: number;
|
|
14
|
+
// } | null>(null);
|
|
15
|
+
// methods
|
|
16
|
+
// const handleClick = (weekDay: Date, hourIndex: number) => (event: React.MouseEvent<HTMLDivElement>) => {
|
|
17
|
+
// const rect = event.currentTarget.getBoundingClientRect();
|
|
18
|
+
// const y = event.clientY - rect.top;
|
|
19
|
+
// const slotIndex = Math.floor(y / slotHeight);
|
|
20
|
+
// const minutes = hourIndex * 60 + slotIndex * slotDuration;
|
|
21
|
+
// if (!tempStart) {
|
|
22
|
+
// setTempStart({ date: weekDay, minutes });
|
|
23
|
+
// return;
|
|
24
|
+
// }
|
|
25
|
+
// const startMinutes = Math.min(tempStart.minutes, minutes);
|
|
26
|
+
// const endMinutes = Math.max(tempStart.minutes, minutes) + slotDuration;
|
|
27
|
+
// const startDate = new Date(weekDay);
|
|
28
|
+
// startDate.setHours(Math.floor(startMinutes / 60), startMinutes % 60, 0, 0);
|
|
29
|
+
// const endDate = new Date(weekDay);
|
|
30
|
+
// endDate.setHours(Math.floor(endMinutes / 60), endMinutes % 60, 0, 0);
|
|
31
|
+
// setEvents((prev) => [...prev, { start: startDate, end: endDate }]);
|
|
32
|
+
// setTempStart(null);
|
|
33
|
+
// };
|
|
34
|
+
const weekDays = useMemo(() => getWeekDays(states.currentDate.get, config?.weekStartsOn ?? 1), [states.currentDate.get, config?.weekStartsOn]);
|
|
35
|
+
// useEffects
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
setEvents(data);
|
|
38
|
+
}, [data]);
|
|
39
|
+
return (React.createElement("div", { className: "ar-calendar-week-view" },
|
|
40
|
+
React.createElement("div", { className: "head" }, weekDays.map((day) => (React.createElement("div", { key: day.toISOString(), className: "item" },
|
|
41
|
+
React.createElement("span", { className: "day-name" }, day
|
|
42
|
+
.toLocaleString(config?.locale ?? "tr", {
|
|
43
|
+
weekday: "short",
|
|
44
|
+
})
|
|
45
|
+
.toUpperCase()),
|
|
46
|
+
React.createElement("span", { className: "date" }, day.getDate()))))),
|
|
47
|
+
React.createElement("div", { className: "body" },
|
|
48
|
+
React.createElement("div", { className: "clocks" }, Array.from({ length: hours }, (_, index) => (React.createElement("div", { key: index },
|
|
49
|
+
React.createElement("span", null,
|
|
50
|
+
String(startHour + index).padStart(2, "0"),
|
|
51
|
+
":00"))))),
|
|
52
|
+
React.createElement("div", { role: "grid", className: "grid" },
|
|
53
|
+
React.createElement("div", { className: "events-layer" }, events.map((event, index) => {
|
|
54
|
+
const dayIndex = weekDays.findIndex((d) => d.toDateString() === event.start.toDateString());
|
|
55
|
+
if (dayIndex === -1)
|
|
56
|
+
return null;
|
|
57
|
+
const startMinutes = event.start.getHours() * 60 + event.start.getMinutes();
|
|
58
|
+
const durationMinutes = (event.end.getTime() - event.start.getTime()) / 60000;
|
|
59
|
+
const top = (startMinutes / 60) * cellHeight;
|
|
60
|
+
const height = (durationMinutes / 60) * cellHeight;
|
|
61
|
+
return (React.createElement("div", { key: index, className: "event-box", style: {
|
|
62
|
+
top,
|
|
63
|
+
height,
|
|
64
|
+
left: `${(100 / 7) * dayIndex}%`,
|
|
65
|
+
} },
|
|
66
|
+
event.start.toLocaleTimeString(config?.locale ?? "tr-TR", {
|
|
67
|
+
hour: "2-digit",
|
|
68
|
+
minute: "2-digit",
|
|
69
|
+
}),
|
|
70
|
+
" - ",
|
|
71
|
+
event.end.toLocaleTimeString(config?.locale ?? "tr-TR", {
|
|
72
|
+
hour: "2-digit",
|
|
73
|
+
minute: "2-digit",
|
|
74
|
+
})));
|
|
75
|
+
})),
|
|
76
|
+
Array.from({ length: hours }).map((_, rowIndex) => (React.createElement("div", { key: rowIndex, className: "row" }, weekDays.map((_, colIndex) => (
|
|
77
|
+
// <div key={colIndex} className="cell" onClick={handleClick(weekDay, rowIndex)} />
|
|
78
|
+
React.createElement("div", { key: colIndex, className: "cell" }))))))))));
|
|
79
|
+
};
|
|
80
|
+
const getWeekRange = (date, weekStartsOn = 1) => {
|
|
81
|
+
const current = new Date(date);
|
|
82
|
+
const currentDay = current.getDay();
|
|
83
|
+
const diff = (currentDay - weekStartsOn + 7) % 7;
|
|
84
|
+
const start = new Date(current);
|
|
85
|
+
start.setDate(current.getDate() - diff);
|
|
86
|
+
start.setHours(0, 0, 0, 0);
|
|
87
|
+
const end = new Date(start);
|
|
88
|
+
end.setDate(start.getDate() + 6);
|
|
89
|
+
return { start, end };
|
|
90
|
+
};
|
|
91
|
+
const getWeekDays = (date, weekStartsOn = 1) => {
|
|
92
|
+
const { start } = getWeekRange(date, weekStartsOn);
|
|
93
|
+
return Array.from({ length: 7 }, (_, i) => {
|
|
94
|
+
const d = new Date(start);
|
|
95
|
+
d.setDate(start.getDate() + i);
|
|
96
|
+
return d;
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
export default Week;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Errors, TableColumnType } from "../../../../libs/types";
|
|
3
|
+
import { Config } from "../IProps";
|
|
3
4
|
interface IProps<T> {
|
|
4
5
|
c: TableColumnType<T>;
|
|
5
6
|
item: T;
|
|
6
7
|
trackByValue: string;
|
|
7
8
|
onEditable: (item: T, trackByValue: string) => void;
|
|
8
9
|
validation?: Errors<T>;
|
|
10
|
+
config: Config<T>;
|
|
9
11
|
}
|
|
10
|
-
declare const Editable: <T>({ c, item, trackByValue, onEditable, validation }: IProps<T>) => React.JSX.Element | null;
|
|
12
|
+
declare const Editable: <T>({ c, item, trackByValue, onEditable, validation, config }: IProps<T>) => React.JSX.Element | null;
|
|
11
13
|
export default Editable;
|
|
@@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react";
|
|
|
3
3
|
import Input from "../../../form/input";
|
|
4
4
|
import DatePicker from "../../../form/date-picker";
|
|
5
5
|
import Select from "../../../form/select";
|
|
6
|
-
const Editable = function ({ c, item, trackByValue, onEditable, validation }) {
|
|
6
|
+
const Editable = function ({ c, item, trackByValue, onEditable, validation, config }) {
|
|
7
7
|
// variables
|
|
8
8
|
const key = c.key;
|
|
9
9
|
const itemValue = item[c.key];
|
|
@@ -29,13 +29,13 @@ const Editable = function ({ c, item, trackByValue, onEditable, validation }) {
|
|
|
29
29
|
const { value } = event.target;
|
|
30
30
|
setValue(value);
|
|
31
31
|
onEditable({ ...item, [key]: value }, trackByValue);
|
|
32
|
-
}, validation: { text: _vText } }));
|
|
32
|
+
}, validation: { text: _vText }, locale: config.locale }));
|
|
33
33
|
case "input-formatted-decimal":
|
|
34
34
|
return (React.createElement(Input.FormattedDecimal, { variant: "borderless", name: c.key, value: _value, onChange: (event) => {
|
|
35
35
|
const { value } = event.target;
|
|
36
36
|
setValue(value);
|
|
37
37
|
onEditable({ ...item, [key]: value }, trackByValue);
|
|
38
|
-
}, validation: { text: _vText } }));
|
|
38
|
+
}, validation: { text: _vText }, locale: config.locale }));
|
|
39
39
|
case "date-picker":
|
|
40
40
|
return (React.createElement(DatePicker, { variant: "borderless", value: _value, onChange: (value) => {
|
|
41
41
|
setValue(value);
|
|
@@ -4,6 +4,7 @@ import Checkbox from "../../../form/checkbox";
|
|
|
4
4
|
import Editable from "./Editable";
|
|
5
5
|
function TBody({ data, columns, refs, methods, states, config }) {
|
|
6
6
|
// refs
|
|
7
|
+
const _hasMeasured = useRef(false);
|
|
7
8
|
const _tBodyTR = useRef([]);
|
|
8
9
|
// states
|
|
9
10
|
const [triggerForRender, setTriggerForRender] = useState(false);
|
|
@@ -88,7 +89,7 @@ function TBody({ data, columns, refs, methods, states, config }) {
|
|
|
88
89
|
return (React.createElement("div", { key: `last-before-${i}`, style: { left: `${i + 0.65}rem` }, className: "last-before" }));
|
|
89
90
|
}),
|
|
90
91
|
React.createElement("div", { className: "before" }))),
|
|
91
|
-
React.isValidElement(render) ? (render) : column.editable && methods.onEditable ? (React.createElement(Editable, { c: column, item: item, trackByValue: methods.trackBy?.(item) ?? "", onEditable: methods.onEditable, validation: config.validation })) : (React.createElement("span", null, render)),
|
|
92
|
+
React.isValidElement(render) ? (render) : column.editable && methods.onEditable ? (React.createElement(Editable, { c: column, item: item, trackByValue: methods.trackBy?.(item) ?? "", onEditable: methods.onEditable, validation: config.validation, config: config })) : (React.createElement("span", null, render)),
|
|
92
93
|
config.isTreeView && cIndex === 0 && (React.createElement("div", { className: "after" },
|
|
93
94
|
React.createElement("div", { className: "circle" }))))));
|
|
94
95
|
};
|
|
@@ -128,9 +129,14 @@ function TBody({ data, columns, refs, methods, states, config }) {
|
|
|
128
129
|
};
|
|
129
130
|
// useEffects
|
|
130
131
|
useEffect(() => {
|
|
132
|
+
if (_hasMeasured.current)
|
|
133
|
+
return;
|
|
134
|
+
if (!data || data.length === 0)
|
|
135
|
+
return;
|
|
131
136
|
const heights = _tBodyTR.current.map((el) => (el ? el.getBoundingClientRect().height : 0));
|
|
132
137
|
setRowHeights(heights);
|
|
133
138
|
setTriggerForRender((prev) => !prev);
|
|
139
|
+
_hasMeasured.current = true;
|
|
134
140
|
}, [data]);
|
|
135
141
|
useEffect(() => {
|
|
136
142
|
if (Array.isArray(refs._checkboxItems.current) && refs._checkboxItems.current.length > 0) {
|
|
@@ -383,7 +383,7 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
383
383
|
_data = _data.slice(indexOfFirstRow, indexOfLastRow);
|
|
384
384
|
}
|
|
385
385
|
return _data;
|
|
386
|
-
}, [data, searchedText, currentPage, selectedPerPage, sortConfig]);
|
|
386
|
+
}, [data, searchedText, currentPage, selectedPerPage, sortConfig, config.isServerSide]);
|
|
387
387
|
// useEffects
|
|
388
388
|
useEffect(() => {
|
|
389
389
|
if (!previousSelections || previousSelections.length === 0) {
|
|
@@ -1,38 +1,50 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import React, { useRef, useState, useEffect } from "react";
|
|
2
|
+
import React, { useRef, useState, useEffect, useMemo } from "react";
|
|
3
3
|
import Input from "..";
|
|
4
|
-
const Decimal = ({ variant, color, name, value, onChange, placeholder, validation, disabled }) => {
|
|
5
|
-
// refs
|
|
4
|
+
const Decimal = ({ variant, color, name, value, onChange, placeholder, validation, disabled, locale = "tr-TR", }) => {
|
|
6
5
|
const _input = useRef(null);
|
|
7
|
-
// states
|
|
8
6
|
const [_value, setValue] = useState("");
|
|
9
7
|
// methods
|
|
8
|
+
const decimalSeparator = useMemo(() => {
|
|
9
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(1.1);
|
|
10
|
+
return parts.find((p) => p.type === "decimal")?.value ?? ".";
|
|
11
|
+
}, [locale]);
|
|
10
12
|
const handleChange = (event) => {
|
|
11
13
|
let inputValue = event.target.value;
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
+
// Locale’a göre izin verilen karakterler. (rakam, decimal, -)
|
|
15
|
+
const regex = new RegExp(`[^0-9\\${decimalSeparator}-]`, "g");
|
|
16
|
+
inputValue = inputValue.replace(regex, "");
|
|
17
|
+
// Sadece başta negatif işarete izin ver.
|
|
18
|
+
if (inputValue.includes("-")) {
|
|
19
|
+
inputValue = (inputValue.startsWith("-") ? "-" : "") + inputValue.replace(/-/g, "");
|
|
20
|
+
}
|
|
21
|
+
// Tek decimal separator’a izin ver.
|
|
22
|
+
const parts = inputValue.split(decimalSeparator);
|
|
14
23
|
if (parts.length > 2) {
|
|
15
|
-
inputValue = parts[0] +
|
|
24
|
+
inputValue = parts[0] + decimalSeparator + parts.slice(1).join("");
|
|
16
25
|
}
|
|
17
26
|
setValue(inputValue);
|
|
27
|
+
// Parent’a normalize edilmiş "." decimal gönder.
|
|
28
|
+
const normalized = inputValue.replace(decimalSeparator, ".");
|
|
18
29
|
onChange?.({
|
|
19
30
|
...event,
|
|
20
31
|
target: {
|
|
21
32
|
...event.target,
|
|
22
33
|
name,
|
|
23
|
-
value:
|
|
34
|
+
value: normalized,
|
|
24
35
|
},
|
|
25
36
|
});
|
|
26
37
|
};
|
|
27
38
|
// useEffects
|
|
28
39
|
useEffect(() => {
|
|
29
|
-
if (value === undefined || value === null) {
|
|
40
|
+
if (value === undefined || value === null || value === "") {
|
|
30
41
|
setValue("");
|
|
42
|
+
return;
|
|
31
43
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}, [value]);
|
|
44
|
+
const stringValue = String(value);
|
|
45
|
+
const localized = stringValue.replace(".", decimalSeparator);
|
|
46
|
+
setValue(localized);
|
|
47
|
+
}, [value, decimalSeparator]);
|
|
36
48
|
return (React.createElement(Input, { ref: _input, name: name, variant: variant, color: color, type: "text", inputMode: "decimal", value: _value, onChange: (e) => {
|
|
37
49
|
if (disabled)
|
|
38
50
|
return;
|
|
@@ -3,5 +3,6 @@ interface IProps extends IVariant, IColors, IBorder, IUpperCase, IValidation, IP
|
|
|
3
3
|
name: string;
|
|
4
4
|
value: string | number | readonly string[] | undefined;
|
|
5
5
|
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
6
|
+
locale?: Intl.LocalesArgument;
|
|
6
7
|
}
|
|
7
8
|
export default IProps;
|
|
@@ -3,12 +3,16 @@ import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
|
3
3
|
import Input from "..";
|
|
4
4
|
import { NUMBER } from "../../../../libs/infrastructure/shared";
|
|
5
5
|
const FormattedDecimal = ({ variant, color, name, value, onChange, locale = "tr-TR", digits, placeholder, validation, disabled, }) => {
|
|
6
|
-
// refs
|
|
7
|
-
// const _firstLoad = useRef<boolean>(false);
|
|
8
6
|
const _input = useRef(null);
|
|
9
|
-
// states
|
|
10
7
|
const [_value, setValue] = useState("");
|
|
11
8
|
// methods
|
|
9
|
+
const getSeparators = (locale) => {
|
|
10
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(1000.1);
|
|
11
|
+
const group = parts.find((p) => p.type === "group")?.value ?? ",";
|
|
12
|
+
const decimal = parts.find((p) => p.type === "decimal")?.value ?? ".";
|
|
13
|
+
return { group, decimal };
|
|
14
|
+
};
|
|
15
|
+
const getFormatter = useMemo(() => NUMBER.Decimal(locale, digits), [locale, digits]);
|
|
12
16
|
const handleClick = () => {
|
|
13
17
|
const input = _input.current;
|
|
14
18
|
if (!input)
|
|
@@ -33,48 +37,34 @@ const FormattedDecimal = ({ variant, color, name, value, onChange, locale = "tr-
|
|
|
33
37
|
};
|
|
34
38
|
const handleChange = (event) => {
|
|
35
39
|
let { value } = event.target;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const { group, decimal } = getSeparators(locale);
|
|
41
|
+
// Locale’a göre izin verilen karakterleri temizle.
|
|
42
|
+
const regex = new RegExp(`[^0-9\\${group}\\${decimal}]`, "g");
|
|
43
|
+
value = value.replace(regex, "");
|
|
44
|
+
// Normalize et (decimal her zaman "." olacak şekilde)
|
|
45
|
+
let normalized = value.replace(new RegExp(`\\${group}`, "g"), "").replace(decimal, ".");
|
|
46
|
+
const parsed = parseFloat(normalized);
|
|
47
|
+
const numericValue = isNaN(parsed) ? 0 : parsed;
|
|
48
|
+
const formatted = value === "" ? "" : getFormatter.format(numericValue);
|
|
45
49
|
setValue(formatted);
|
|
46
|
-
onChange?.({
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
else if (input.includes(",") && !input.includes(".")) {
|
|
55
|
-
// Virgül ondalık, binlik yok (fr-FR gibi)
|
|
56
|
-
return input.replace(",", ".");
|
|
57
|
-
}
|
|
58
|
-
else if (input.includes(".") && !input.includes(",")) {
|
|
59
|
-
// Nokta ondalık, binlik yok veya US format
|
|
60
|
-
return input.replace(/,/g, "");
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
// Hiçbiri yok, zaten sayı
|
|
64
|
-
return input;
|
|
65
|
-
}
|
|
50
|
+
onChange?.({
|
|
51
|
+
...event,
|
|
52
|
+
target: {
|
|
53
|
+
...event.target,
|
|
54
|
+
name,
|
|
55
|
+
value: normalized,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
66
58
|
};
|
|
67
59
|
// useEffects
|
|
68
60
|
useEffect(() => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// }
|
|
61
|
+
if (value === undefined || value === null || value === "") {
|
|
62
|
+
setValue("");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
74
65
|
setValue(getFormatter.format(Number(value)));
|
|
75
|
-
}, [value]);
|
|
76
|
-
return (React.createElement(Input, { ref: _input, name: name, variant: variant, color: color, value: _value
|
|
77
|
-
// Disabled gelmesi durumunda işlem yapmasına izin verme...
|
|
66
|
+
}, [value, getFormatter]);
|
|
67
|
+
return (React.createElement(Input, { ref: _input, name: name, variant: variant, color: color, value: _value, type: "text", inputMode: "decimal", onChange: (event) => {
|
|
78
68
|
if (disabled)
|
|
79
69
|
return;
|
|
80
70
|
handleChange(event);
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import Select from "./components/form/select";
|
|
|
10
10
|
import Switch from "./components/form/switch";
|
|
11
11
|
import TextEditor from "./components/form/text-editor";
|
|
12
12
|
import Upload from "./components/form/upload";
|
|
13
|
+
import Calendar from "./components/data-display/calendar";
|
|
13
14
|
import Card from "./components/data-display/card";
|
|
14
15
|
import Chip from "./components/data-display/chip";
|
|
15
16
|
import Diagram from "./components/data-display/diagram/index";
|
|
@@ -33,4 +34,4 @@ import Pagination from "./components/navigation/pagination";
|
|
|
33
34
|
import Steps from "./components/navigation/steps";
|
|
34
35
|
import Grid from "./components/data-display/grid-system";
|
|
35
36
|
import Layout from "./components/layout";
|
|
36
|
-
export { Button, ButtonAction, ButtonGroup, Checkbox, DatePicker, Input, Radio, Select, Switch, TextEditor, Upload, Card, Chip, Diagram, Divider, DnD, KanbanBoard, Paper, SyntaxHighlighter, Table, Tabs, Typography, Alert, Drawer, Modal, Popover, Progress, Tooltip, Breadcrumb, Menu, Pagination, Steps, Grid, Layout, };
|
|
37
|
+
export { Button, ButtonAction, ButtonGroup, Checkbox, DatePicker, Input, Radio, Select, Switch, TextEditor, Upload, Calendar, Card, Chip, Diagram, Divider, DnD, KanbanBoard, Paper, SyntaxHighlighter, Table, Tabs, Typography, Alert, Drawer, Modal, Popover, Progress, Tooltip, Breadcrumb, Menu, Pagination, Steps, Grid, Layout, };
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import Switch from "./components/form/switch";
|
|
|
12
12
|
import TextEditor from "./components/form/text-editor";
|
|
13
13
|
import Upload from "./components/form/upload";
|
|
14
14
|
// Data Display
|
|
15
|
+
import Calendar from "./components/data-display/calendar";
|
|
15
16
|
import Card from "./components/data-display/card";
|
|
16
17
|
import Chip from "./components/data-display/chip";
|
|
17
18
|
import Diagram from "./components/data-display/diagram/index";
|
|
@@ -42,7 +43,7 @@ export {
|
|
|
42
43
|
// Form Elements
|
|
43
44
|
Button, ButtonAction, ButtonGroup, Checkbox, DatePicker, Input, Radio, Select, Switch, TextEditor, Upload,
|
|
44
45
|
// Data Display
|
|
45
|
-
Card, Chip, Diagram, Divider, DnD, KanbanBoard, Paper, SyntaxHighlighter, Table, Tabs, Typography,
|
|
46
|
+
Calendar, Card, Chip, Diagram, Divider, DnD, KanbanBoard, Paper, SyntaxHighlighter, Table, Tabs, Typography,
|
|
46
47
|
// Feedback
|
|
47
48
|
Alert, Drawer, Modal, Popover, Progress, Tooltip,
|
|
48
49
|
// Navigation
|