Date/Time picker React component for Obsidian. This uses the ObsidianApp helper function mentioned above. Tested on Mac and iPhone.
Obsidian View
Date Time Picker Component Example.md:
# Date Time Picker Component Example
Component example that allows a user to pick a date/time and fills in a markdown field with the selected results
My Date:: 2022-02-02
\```jsx:
<DateTimePickerComponent
fieldName="My Date"
/>
\```
DateTimePickerComponent.md
const DateTimePickerComponentFunction = () => {
const [dateTime, setDateTime] = useState(null);
const [isWithTime, setIsWithTime] = useState(false);
const [init, setInit] = useState(false);
const isDark = document.querySelector('body.theme-dark') !== null;
const inputStyle = {
'color-scheme': isDark ? 'dark' : 'light',
backgroundColor: 'var(--background-modifier-form-field)',
border: '1px solid var(--background-modifier-border)',
color: 'var(--text-normal)',
fontFamily: "'Inter', sans-serif",
padding: '5px 14px',
fontSize: '16px',
borderRadius: '4px',
outline: 'none',
height: '30px',
};
const initialize = async () => {
const fileDateTimeValue = await getFileDateTimeValue();
const fileDateTime = fileDateTimeValue ? fileDateTimeValue : null;
if (
fileDateTime !== dateTime
&& fileDateTime !== null
) {
updateDateTime(fileDateTime);
}
setInit(true);
}
const getFileDateTimeValue = async () => {
const fileContents = await ObsidianApp().getFileContent();
return ObsidianApp().getFieldValueAndPosition(props.fieldName, fileContents)?.value;
}
const updateContent = async () => {
const fileDateTimeValue = await getFileDateTimeValue();
const fileDateTime = fileDateTimeValue ? fileDateTimeValue : null;
const newTime = isWithTime ? ` ${getDateFromString(dateTime)
.toLocaleString('en-US', { timeStyle: 'short'})}` :
'';
const newDate = `${getDateFromString(dateTime)
.toISOString()
.split('T')[0]}${newTime}`;
if (fileDateTime !== newDate) {
ObsidianApp().setFileFieldContent(props.fieldName, newDate);
}
};
const getDateFromString = (dateString) => {
return new Date(dateString.replace(/-/g, '/'));
}
const updateDateTime = (newDateTimeString) => {
const hasTime = newDateTimeString.includes('M');
if (isWithTime !== hasTime) {
setIsWithTime(hasTime);
}
setDateTime(newDateTimeString);
};
useEffect(() => {
initialize();
}, []);
useEffect(() => {
if (!init) return;
updateContent();
}, [dateTime]);
const toggleDate = (e) => {
const newValue = !isWithTime;
setIsWithTime(newValue);
};
const handleDateChange = (e) => {
setDateTime(e.target.value.replace('T', ' '));
};
return (
<>
<div style={{display: 'flex'}}>
{isWithTime ? (
<>
<label className="input-label" htmlFor="datetime-local-picker">Pick a date </label>
<input
style={inputStyle}
type="datetime-local"
name="datetime-local-picker"
value={dateTime ? getDateFromString(`${dateTime} GMT`).toISOString().slice(0, 16) : null}
onChange={handleDateChange}
id="datetime-local-picker" />
</>
) : (
<>
<label className="input-label" htmlFor="date-picker">Pick a date </label>
<input
style={inputStyle}
type="date"
name="date-picker"
value={dateTime?.split(' ')[0]}
onChange={handleDateChange}
id="date-picker" />
</>
)}
<>
<div style={{display: 'flex'}}>
<label> Include time? </label>
<div class="setting-item-control" onClick={toggleDate}>
<div className={`checkbox-container ${isWithTime ? 'is-enabled' : ''}`}></div>
</div>
</div>
</>
</div>
</>
);
};
return DateTimePickerComponentFunction();