Skip to content

Commit 608d671

Browse files
committed
rtl support
1 parent c7f3f84 commit 608d671

17 files changed

+152
-91
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import { Scheduler } from "@aldabil/react-scheduler";
6565
| resourceFields | Object. Map the resources correct fields. <br>_Example_: <pre>{<br> idField: "admin_id", <br>textField: "title", <br>subTextField: "mobile", <br>avatarField: "title", <br>colorField: "background",<br> }</pre> |
6666
| recourseHeaderComponent | Function(resource). Override header component of resource |
6767
| resourceViewMode | Display resources mode. <br>_Options_: "default", "tabs" |
68+
| direction | string. Table direction. "rtl", "ltr" |
6869

6970
### Demos
7071

@@ -79,3 +80,4 @@ import { Scheduler } from "@aldabil/react-scheduler";
7980
- Tests
8081
- Drag&Drop
8182
- Recurring events
83+
- Localization

public/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!DOCTYPE html>
2-
<html lang="en">
2+
<html lang="en" dir="ltr">
33
<head>
44
<meta charset="utf-8" />
55
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />

src/App.tsx

+9-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Scheduler } from "./lib/Scheduler";
33
const App = () => {
44
return (
55
<Scheduler
6+
// view="month"
67
// loading={loading}
78
// view="month"
89
// events={EVENTS}
@@ -15,13 +16,13 @@ const App = () => {
1516
// });
1617
// }}
1718
// resources={[
18-
// {
19-
// admin_id: 1,
20-
// title: "One",
21-
// mobile: "555666777",
22-
// avatar: "https://picsum.photos/200/300",
23-
// color: "#ab2d2d",
24-
// },
19+
// {
20+
// admin_id: 1,
21+
// title: "One",
22+
// mobile: "555666777",
23+
// avatar: "https://picsum.photos/200/300",
24+
// color: "#ab2d2d",
25+
// },
2526
// {
2627
// admin_id: 2,
2728
// title: "Two",
@@ -131,6 +132,7 @@ const App = () => {
131132
// // </div>
132133
// // );
133134
// }}
135+
// direction={dir}
134136
/>
135137
);
136138
};

src/lib/Scheduler.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ export interface SchedulerProps {
175175
* @default "default"
176176
*/
177177
resourceViewMode: "default" | "tabs";
178+
/**Direction of table */
179+
direction: "rtl" | "ltr";
178180
}
179181

180182
const Scheduler = (props: SchedulerProps) => {

src/lib/SchedulerComponent.tsx

+13-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Month } from "./views/Month";
99
import { Day } from "./views/Day";
1010

1111
const SchedulerComponent = () => {
12-
const { loading, view, dialog } = useAppState();
12+
const { loading, view, dialog, direction } = useAppState();
1313

1414
const renderViews = () => {
1515
switch (view) {
@@ -36,7 +36,18 @@ const SchedulerComponent = () => {
3636
)}
3737
<Navigation />
3838
<div className="outer-table">
39-
<table>{renderViews()}</table>
39+
<table>
40+
<style>
41+
{`
42+
table td {
43+
border-${
44+
direction === "rtl" ? "right" : "left"
45+
}: 1px solid #eeeeee;
46+
}
47+
`}
48+
</style>
49+
{renderViews()}
50+
</table>
4051
</div>
4152
{dialog && <Editor />}
4253
</div>

src/lib/assets/css/index.css

+1-30
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ table {
1616
table td {
1717
vertical-align: top;
1818
border-bottom: 1px solid #eeeeee;
19-
border-left: 1px solid #eeeeee;
2019
}
2120
.day_indent,
2221
.indent {
@@ -30,44 +29,16 @@ table td {
3029
width: 80px;
3130
vertical-align: top;
3231
}
33-
.month_day_table td {
34-
border-bottom: 0;
35-
border-left: 0;
36-
}
37-
.month_cells td:first-child {
38-
border-left: 0;
39-
}
4032
.month_cells tr:last-child td {
4133
border-bottom: 0;
4234
}
43-
.month_cells thead td {
44-
border: 0;
45-
border-left: 1px solid #eeeeee;
46-
}
35+
4736
.hour_table tr:last-child td:last-child {
4837
border: 0;
4938
}
5039
.hour_table td {
5140
border-left: 0;
5241
}
53-
.cells_table tr:last-child td {
54-
border-width: 0 0 0 1px;
55-
}
56-
.week_day_table td {
57-
border-color: #eeeeee;
58-
border-style: solid;
59-
border-width: 0 1px 0 0;
60-
}
61-
.week_day_table td:last-child {
62-
border-width: 0;
63-
}
64-
.cells_table td:first-child {
65-
border-left: 0;
66-
}
67-
68-
/* .c_cell {
69-
overflow: hidden;
70-
} */
7142
.c_cell:hover {
7243
background: #f8f8f8;
7344
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useAppState } from "../../hooks/useAppState";
2+
import NavigateBeforeRoundedIcon from "@material-ui/icons/NavigateBeforeRounded";
3+
import NavigateNextRoundedIcon from "@material-ui/icons/NavigateNextRounded";
4+
5+
interface LocaleArrowProps {
6+
type: "prev" | "next";
7+
}
8+
const LocaleArrow = (props: LocaleArrowProps) => {
9+
const { type } = props;
10+
const { direction } = useAppState();
11+
12+
let Arrow = NavigateNextRoundedIcon;
13+
if (type === "prev") {
14+
Arrow =
15+
direction === "rtl" ? NavigateNextRoundedIcon : NavigateBeforeRoundedIcon;
16+
} else if (type === "next") {
17+
Arrow =
18+
direction === "rtl" ? NavigateBeforeRoundedIcon : NavigateNextRoundedIcon;
19+
}
20+
21+
return <Arrow {...props} />;
22+
};
23+
24+
export { LocaleArrow };

src/lib/components/common/ResourceHeader.tsx

+12-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ interface ResourceHeaderProps {
1313
resource: DefaultRecourse;
1414
}
1515
const ResourceHeader = ({ resource }: ResourceHeaderProps) => {
16-
const { recourseHeaderComponent, resourceFields, resources } = useAppState();
16+
const {
17+
recourseHeaderComponent,
18+
resourceFields,
19+
resources,
20+
direction,
21+
} = useAppState();
1722
const { width } = useWindowResize();
1823

1924
const text = resource[resourceFields.textField];
@@ -26,7 +31,12 @@ const ResourceHeader = ({ resource }: ResourceHeaderProps) => {
2631
}
2732

2833
return (
29-
<ListItem style={{ padding: "2px 10px" }}>
34+
<ListItem
35+
style={{
36+
padding: "2px 10px",
37+
textAlign: direction === "rtl" ? "right" : "left",
38+
}}
39+
>
3040
<ListItemAvatar>
3141
<Avatar style={{ background: color }} alt={text} src={avatar} />
3242
</ListItemAvatar>

src/lib/components/nav/DayDateBtn.tsx

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import React, { useState } from "react";
1+
import { useState } from "react";
22
import DateProvider from "../hoc/DateProvider";
33
import { DatePicker } from "@material-ui/pickers";
44
import { Button, IconButton } from "@material-ui/core";
5-
import NavigateBeforeRoundedIcon from "@material-ui/icons/NavigateBeforeRounded";
6-
import NavigateNextRoundedIcon from "@material-ui/icons/NavigateNextRounded";
75
import { MaterialUiPickersDate } from "@material-ui/pickers/typings/date";
8-
import { addDays } from "date-fns/esm";
9-
import { format } from "date-fns";
6+
import { format, addDays } from "date-fns";
7+
import { LocaleArrow } from "../common/LocaleArrow";
108

119
interface DayDateBtnProps {
1210
selectedDate: Date;
@@ -33,14 +31,14 @@ const DayDateBtn = ({ selectedDate, onChange }: DayDateBtnProps) => {
3331
<div>
3432
<div>
3533
<IconButton style={{ padding: 2 }} onClick={handlePrev}>
36-
<NavigateBeforeRoundedIcon />
34+
<LocaleArrow type="prev" />
3735
</IconButton>
3836
<Button style={{ padding: 4 }} onClick={toggleDialog}>{`${format(
3937
selectedDate,
4038
"dd, MMMM yyyy"
4139
)}`}</Button>
4240
<IconButton style={{ padding: 2 }} onClick={handleNext}>
43-
<NavigateNextRoundedIcon />
41+
<LocaleArrow type="next" />
4442
</IconButton>
4543
</div>
4644
<DateProvider>

src/lib/components/nav/MonthDateBtn.tsx

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import React, { useState } from "react";
1+
import { useState } from "react";
22
import DateProvider from "../hoc/DateProvider";
33
import { DatePicker } from "@material-ui/pickers";
44
import { Button, IconButton } from "@material-ui/core";
5-
import { format, getMonth } from "date-fns";
6-
import NavigateBeforeRoundedIcon from "@material-ui/icons/NavigateBeforeRounded";
7-
import NavigateNextRoundedIcon from "@material-ui/icons/NavigateNextRounded";
5+
import { format, getMonth, setMonth } from "date-fns";
86
import { MaterialUiPickersDate } from "@material-ui/pickers/typings/date";
9-
import { setMonth } from "date-fns/esm";
7+
import { LocaleArrow } from "../common/LocaleArrow";
108

119
interface MonthDateBtnProps {
1210
selectedDate: Date;
@@ -34,13 +32,13 @@ const MonthDateBtn = ({ selectedDate, onChange }: MonthDateBtnProps) => {
3432
return (
3533
<div>
3634
<IconButton style={{ padding: 2 }} onClick={handlePrev}>
37-
<NavigateBeforeRoundedIcon />
35+
<LocaleArrow type="prev" />
3836
</IconButton>
3937
<Button style={{ padding: 4 }} onClick={toggleDialog}>
4038
{format(selectedDate, "MMMM yyyy")}
4139
</Button>
4240
<IconButton style={{ padding: 2 }} onClick={handleNext}>
43-
<NavigateNextRoundedIcon />
41+
<LocaleArrow type="next" />
4442
</IconButton>
4543
<DateProvider>
4644
<DatePicker

src/lib/components/nav/WeekDateBtn.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import React, { useState } from "react";
1+
import { useState } from "react";
22
import DateProvider from "../hoc/DateProvider";
33
import { DatePicker } from "@material-ui/pickers";
44
import { Button, IconButton } from "@material-ui/core";
55
import { endOfWeek, format, startOfWeek } from "date-fns";
66
import { WeekProps } from "../../views/Week";
7-
import NavigateBeforeRoundedIcon from "@material-ui/icons/NavigateBeforeRounded";
8-
import NavigateNextRoundedIcon from "@material-ui/icons/NavigateNextRounded";
97
import { MaterialUiPickersDate } from "@material-ui/pickers/typings/date";
108
import { addDays } from "date-fns/esm";
9+
import { LocaleArrow } from "../common/LocaleArrow";
1110

1211
interface WeekDateBtnProps {
1312
selectedDate: Date;
@@ -42,14 +41,14 @@ const WeekDateBtn = ({
4241
return (
4342
<div>
4443
<IconButton style={{ padding: 2 }} onClick={handlePrev}>
45-
<NavigateBeforeRoundedIcon />
44+
<LocaleArrow type="prev" />
4645
</IconButton>
4746
<Button style={{ padding: 4 }} onClick={toggleDialog}>{`${format(
4847
weekStart,
4948
"dd"
5049
)} - ${format(weekEnd, "dd MMMM yyyy")}`}</Button>
5150
<IconButton style={{ padding: 2 }} onClick={handleNext}>
52-
<NavigateNextRoundedIcon />
51+
<LocaleArrow type="next" />
5352
</IconButton>
5453
<DateProvider>
5554
<DatePicker

src/lib/context/state/State.tsx

+12-27
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ const initialState = (initial: SchedulerProps): SchedulerState => {
2828
};
2929

3030
const AppState = ({ initial, children }: AppProps) => {
31-
const {
32-
events,
33-
loading,
34-
view,
35-
resourceViewMode,
36-
fields,
37-
resources,
38-
selectedDate,
39-
} = initial;
31+
// const {
32+
// events,
33+
// loading,
34+
// view,
35+
// resourceViewMode,
36+
// fields,
37+
// resources,
38+
// selectedDate,
39+
// direction,
40+
// } = initial;
4041
const [state, dispatch] = useReducer(stateReducer, initialState(initial));
4142

4243
const handleState = (
@@ -50,24 +51,8 @@ const AppState = ({ initial, children }: AppProps) => {
5051
dispatch({ type: "updateProps", payload: initials });
5152
};
5253
useEffect(() => {
53-
updateProps({
54-
events,
55-
loading,
56-
view,
57-
resourceViewMode,
58-
fields,
59-
resources,
60-
selectedDate,
61-
} as SchedulerProps);
62-
}, [
63-
events,
64-
loading,
65-
view,
66-
resourceViewMode,
67-
fields,
68-
resources,
69-
selectedDate,
70-
]);
54+
updateProps(initial);
55+
}, [initial]);
7156

7257
const confirmEvent = (event: ProcessedEvent, action: EventActions) => {
7358
let updatedEvents: ProcessedEvent[];

src/lib/context/state/stateContext.ts

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export const defaultProps = {
6464
},
6565
recourseHeaderComponent: undefined,
6666
resourceViewMode: "default",
67+
direction: "ltr",
6768
} as SchedulerProps;
6869

6970
const StateContext = createContext<stateContext>({

src/lib/views/Day.tsx

+15-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const Day = () => {
4242
handleState,
4343
resources,
4444
resourceFields,
45+
direction,
4546
} = useAppState();
4647
const { startHour, endHour } = day!;
4748
const HOUR_STEP = 60;
@@ -202,7 +203,10 @@ const Day = () => {
202203
<table className="week_day_table">
203204
<tbody>
204205
<tr>
205-
<td className={isToday(selectedDate) ? "today_cell" : ""}>
206+
<td
207+
className={isToday(selectedDate) ? "today_cell" : ""}
208+
style={{ border: 0 }}
209+
>
206210
<TodayTypo date={selectedDate} />
207211
{renderMultiDayEvents(recousedEvents)}
208212
</td>
@@ -236,6 +240,16 @@ const Day = () => {
236240
</td>
237241
<td className="borderd">
238242
<table className="cells_table">
243+
<style>{`
244+
.cells_table tr:last-child td {
245+
border-width: ${
246+
direction === "rtl" ? "0 1px 0 0" : "0 0 0 1px"
247+
};
248+
}
249+
.cells_table td:first-child {
250+
border-${direction === "rtl" ? "right" : "left"}: 0;
251+
}
252+
`}</style>
239253
<thead>
240254
<tr>
241255
<td>{renderTodayEvents(recousedEvents)}</td>

0 commit comments

Comments
 (0)