Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit 5c511ee

Browse files
committed
skeleton of calendar column type
1 parent 115f68f commit 5c511ee

File tree

8 files changed

+243
-7
lines changed

8 files changed

+243
-7
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@types/react-dom": "17.0.14",
3232
"@types/react-table": "7.7.11",
3333
"@types/react-window": "1.8.5",
34+
"@types/react-calendar": "3.5.0",
3435
"@types/react-beautiful-dnd": "13.1.2",
3536
"@types/react-csv": "1.1.2",
3637
"@types/luxon": "2.3.2",
@@ -62,6 +63,7 @@
6263
"react-popper": "2.3.0",
6364
"react-table": "7.7.0",
6465
"react-window": "1.8.7",
66+
"react-calendar": "3.7.0",
6567
"regenerator-runtime": "0.13.9",
6668
"luxon": "2.4.0"
6769
}

src/components/Cell.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import NoteInfo from "services/NoteInfo";
88
import PopperSelectPortal from "components/portals/PopperSelectPortal";
99
import { CellContext } from "components/contexts/CellContext";
1010
import { c } from "helpers/StylesHelper";
11+
import CalendarPortal from "./portals/CalendarPortal";
1112

1213
/**
1314
* Obtain the path of the file inside cellValue
@@ -136,7 +137,13 @@ export default function DefaultCell(cellProperties: Cell) {
136137
/>
137138
</CellContext.Provider>
138139
);
139-
140+
/** Calendar option */
141+
case DataTypes.CALENDAR:
142+
return (
143+
<CellContext.Provider value={{ value, setValue }}>
144+
<CalendarPortal state={(cellProperties as any).initialState} />
145+
</CellContext.Provider>
146+
);
140147
/** Default option */
141148
default:
142149
LOGGER.warn(`Unknown data type: ${dataType}`);

src/components/Columns.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,23 @@ async function columnOptions(
157157
};
158158
}
159159

160+
function isCalendar(): TableColumn {
161+
LOGGER.debug(`<= columnOptions`, `return calendar column`);
162+
return {
163+
...tableRow,
164+
dataType: DataTypes.CALENDAR,
165+
options: options,
166+
};
167+
}
168+
160169
// Record of options
161170
let inputs: Record<string, any> = {};
162171
inputs[DataTypes.TEXT] = isText;
163172
inputs[DataTypes.NUMBER] = isNumber;
164173
inputs[DataTypes.SELECT] = isSelect;
165174
inputs[DataTypes.MARKDOWN] = isMarkdown;
166175
inputs[DataTypes.NEW_COLUMN] = isNewColumn;
176+
inputs[DataTypes.CALENDAR] = isCalendar;
167177
if (inputs.hasOwnProperty(column.input)) {
168178
return await inputs[column.input]();
169179
} else {

src/components/HeaderMenu.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,22 @@ const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
7272

7373
// Manage errors
7474
const [labelStateInvalid, setLabelStateInvalid] = useState(false);
75+
76+
/** Event driven actions */
7577
useEffect(() => {
78+
// Throw event if created changed to expand or collapse the menu
7679
if (created) {
7780
setExpanded(true);
7881
}
7982
}, [created]);
8083

8184
useEffect(() => {
85+
// Throw event if label is changed
8286
setLabelState(labelState);
8387
}, [labelState]);
8488

8589
useEffect(() => {
90+
// Throw event if inputRef changed to focus on when it exists
8691
if (inputRef) {
8792
inputRef.focus();
8893
inputRef.select();
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { TableDataType } from "cdm/FolderModel";
2+
import { CellContext } from "components/contexts/CellContext";
3+
import { StyleVariables } from "helpers/Constants";
4+
import React, { useContext, useState } from "react";
5+
import Calendar from "react-calendar";
6+
import ReactDOM from "react-dom";
7+
import { usePopper } from "react-popper";
8+
9+
type CalendarProps = {
10+
intialState: TableDataType;
11+
};
12+
const CalendarPortal = (calendarProps: any) => {
13+
const [calendarState, setCalendarState] = useState(new Date());
14+
const [showCalendar, setShowCalendar] = useState(false);
15+
// Selector reference state
16+
const [calendarRef, setCalendarRef] = useState(null);
17+
// Selector popper state
18+
const [selectPop, setSelectPop] = useState(null);
19+
const { styles, attributes } = usePopper(calendarRef, selectPop);
20+
/** state of cell value */
21+
const { value, setValue } = useContext(CellContext);
22+
function handleCalendarChange(date: Date) {
23+
setCalendarState(date);
24+
setShowCalendar(false);
25+
}
26+
function renderCalendar() {
27+
return (
28+
<div
29+
className="menu"
30+
ref={setSelectPop}
31+
{...attributes.popper}
32+
style={{
33+
...styles.popper,
34+
zIndex: 4,
35+
minWidth: 200,
36+
maxWidth: 320,
37+
padding: "0.75rem",
38+
background: StyleVariables.BACKGROUND_SECONDARY,
39+
}}
40+
>
41+
<Calendar onChange={handleCalendarChange} value={calendarState} />
42+
</div>
43+
);
44+
}
45+
return (
46+
<>
47+
<div
48+
className="data-input calendar"
49+
ref={setCalendarRef}
50+
onClick={() => setShowCalendar(!showCalendar)}
51+
onBlur={() => setShowCalendar(false)}
52+
>
53+
<span>{value.value}</span>
54+
</div>
55+
{showCalendar &&
56+
ReactDOM.createPortal(
57+
renderCalendar(),
58+
document.getElementById("popper-container")
59+
)}
60+
</>
61+
);
62+
};
63+
export default CalendarPortal;

src/components/portals/PopperSelectPortal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ const PopperSelectPortal = (popperProps: PopperProps) => {
176176
</div>
177177
{domReady
178178
? ReactDOM.createPortal(
179-
PortalSelect(),
180-
document.getElementById("popper-container")
181-
)
179+
PortalSelect(),
180+
document.getElementById("popper-container")
181+
)
182182
: null}
183183
</>
184184
);

src/helpers/Constants.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const DataTypes = Object.freeze({
2222
TEXT: 'text',
2323
SELECT: 'select',
2424
MARKDOWN: 'markdown',
25+
CALENDAR: 'calendar',
2526
NEW_COLUMN: 'new_column'
2627
});
2728

@@ -65,7 +66,7 @@ export const MetadataDatabaseColumns = Object.freeze({
6566
},
6667
CREATED: {
6768
key: MetadataColumns.CREATED,
68-
input: DataTypes.TEXT,
69+
input: DataTypes.CALENDAR,
6970
label: MetadataLabels.CREATED,
7071
accessor: MetadataColumns.CREATED,
7172
isMetadata: true,
@@ -75,7 +76,7 @@ export const MetadataDatabaseColumns = Object.freeze({
7576
},
7677
MODIFIED: {
7778
key: MetadataColumns.MODIFIED,
78-
input: DataTypes.TEXT,
79+
input: DataTypes.CALENDAR,
7980
label: MetadataLabels.MODIFIED,
8081
accessor: MetadataColumns.MODIFIED,
8182
isMetadata: true,

styles.css

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
2-
32
.database-plugin__html {
43
box-sizing: border-box;
54
}
@@ -332,4 +331,153 @@
332331
*/
333332
.configuration-section-container-developer {
334333
background-color: var(--background-modifier-error)
334+
}
335+
336+
/*
337+
* React calendar styles
338+
*/
339+
.react-calendar {
340+
width: 350px;
341+
max-width: 100%;
342+
background: white;
343+
border: 1px solid #a0a096;
344+
font-family: Arial, Helvetica, sans-serif;
345+
line-height: 1.125em;
346+
}
347+
348+
.react-calendar--doubleView {
349+
width: 700px;
350+
}
351+
352+
.react-calendar--doubleView .react-calendar__viewContainer {
353+
display: flex;
354+
margin: -0.5em;
355+
}
356+
357+
.react-calendar--doubleView .react-calendar__viewContainer>* {
358+
width: 50%;
359+
margin: 0.5em;
360+
}
361+
362+
.react-calendar,
363+
.react-calendar *,
364+
.react-calendar *:before,
365+
.react-calendar *:after {
366+
-moz-box-sizing: border-box;
367+
-webkit-box-sizing: border-box;
368+
box-sizing: border-box;
369+
}
370+
371+
.react-calendar button {
372+
margin: 0;
373+
border: 0;
374+
outline: none;
375+
}
376+
377+
.react-calendar button:enabled:hover {
378+
cursor: pointer;
379+
}
380+
381+
.react-calendar__navigation {
382+
height: 44px;
383+
margin-bottom: 1em;
384+
}
385+
386+
.react-calendar__navigation button {
387+
min-width: 44px;
388+
background: none;
389+
}
390+
391+
.react-calendar__navigation button:enabled:hover,
392+
.react-calendar__navigation button:enabled:focus {
393+
background-color: #e6e6e6;
394+
}
395+
396+
.react-calendar__navigation button[disabled] {
397+
background-color: #f0f0f0;
398+
}
399+
400+
.react-calendar__month-view__weekdays {
401+
text-align: center;
402+
text-transform: uppercase;
403+
font-weight: bold;
404+
font-size: 0.75em;
405+
}
406+
407+
.react-calendar__month-view__weekdays__weekday {
408+
padding: 0.5em;
409+
}
410+
411+
.react-calendar__month-view__weekNumbers {
412+
font-weight: bold;
413+
}
414+
415+
.react-calendar__month-view__weekNumbers .react-calendar__tile {
416+
display: flex;
417+
align-items: center;
418+
justify-content: center;
419+
font-size: 0.75em;
420+
padding: calc(0.75em / 0.75) calc(0.5em / 0.75);
421+
}
422+
423+
.react-calendar__month-view__days__day--weekend {
424+
color: #d10000;
425+
}
426+
427+
.react-calendar__month-view__days__day--neighboringMonth {
428+
color: #757575;
429+
}
430+
431+
.react-calendar__year-view .react-calendar__tile,
432+
.react-calendar__decade-view .react-calendar__tile,
433+
.react-calendar__century-view .react-calendar__tile {
434+
padding: 2em 0.5em;
435+
}
436+
437+
.react-calendar__tile {
438+
max-width: 100%;
439+
text-align: center;
440+
padding: 0.75em 0.5em;
441+
background: none;
442+
}
443+
444+
.react-calendar__tile:disabled {
445+
background-color: #f0f0f0;
446+
}
447+
448+
.react-calendar__tile:enabled:hover,
449+
.react-calendar__tile:enabled:focus {
450+
background-color: #e6e6e6;
451+
}
452+
453+
.react-calendar__tile--now {
454+
background: #ffff76;
455+
}
456+
457+
.react-calendar__tile--now:enabled:hover,
458+
.react-calendar__tile--now:enabled:focus {
459+
background: #ffffa9;
460+
}
461+
462+
.react-calendar__tile--hasActive {
463+
background: #76baff;
464+
}
465+
466+
.react-calendar__tile--hasActive:enabled:hover,
467+
.react-calendar__tile--hasActive:enabled:focus {
468+
background: #a9d4ff;
469+
}
470+
471+
.react-calendar__tile--active {
472+
background: #006edc;
473+
color: white;
474+
}
475+
476+
.react-calendar__tile--active:enabled:hover,
477+
.react-calendar__tile--active:enabled:focus {
478+
background: #1087ff;
479+
}
480+
481+
.react-calendar--selectRange .react-calendar__tile--hover {
482+
background-color: #e6e6e6;
335483
}

0 commit comments

Comments
 (0)