Skip to content

Commit cfdfd00

Browse files
committed
date picker as modal #19
1 parent e617fd0 commit cfdfd00

File tree

12 files changed

+175
-111
lines changed

12 files changed

+175
-111
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ data.json
2121
# Exclude macOS Finder (System Explorer) View States
2222
.DS_Store
2323

24+
obsidian.css
25+
2426
!exampleVault/.obsidian
2527

2628
exampleVault/.obsidian/*

exampleVault/examples fg.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ multi_select:
1515
- option a
1616
- option c
1717
time1: 10:17
18-
suggest: test
18+
suggest: "[[other note.md|other note]]"
1919
---
2020

2121
## Components

exampleVault/other note.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
tags: test
33
title: This is an example of how the meta bind
44
select: option a
5-
date: Tuesday, June 14th 2022
5+
date: Saturday, June 18th 2022
66
time: 19:20
77
multi-select:
88
- option b

src/inputFields/DatePicker/Calender.svelte

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,25 @@
1212
export let year: number;
1313
1414
// local vars to help in render
15-
let cells;
15+
let cells: number[];
1616
1717
// function helpers
1818
function onChange(date: number) {
1919
dispatch('dateChange', moment(new Date(year, month, date)));
2020
}
2121
22+
function selectCell(value: number | undefined) {
23+
if (value) {
24+
onChange(value);
25+
}
26+
}
27+
28+
function selectCellKey(event: KeyboardEvent, value: number | undefined) {
29+
if (event.key === ' ') {
30+
selectCell(value);
31+
}
32+
}
33+
2234
$: cells = getDateRows(month, year);
2335
</script>
2436

@@ -31,23 +43,22 @@
3143
display: flex;
3244
justify-content: space-around;
3345
flex-wrap: wrap;
34-
gap: 2px;
35-
background: var(--background-primary);
46+
gap: var(--size-4-1);
47+
background: var(--background-secondary);
3648
border-radius: var(--meta-bind-plugin-border-radius);
37-
margin-bottom: 2px;
49+
margin-bottom: var(--size-4-1);;
3850
}
3951
4052
.calendar-content {
4153
display: grid;
4254
flex-wrap: wrap;
4355
grid-template-columns: repeat(7, 1fr);
44-
gap: 2px;
56+
gap: var(--size-4-1);
4557
}
4658
4759
.cell {
4860
min-width: 40px;
49-
height: 30px;
50-
padding: 5px;
61+
padding: var(--size-4-2);
5162
display: flex;
5263
justify-content: center;
5364
align-items: center;
@@ -64,15 +75,15 @@
6475
}
6576
6677
.selected {
67-
background: var(--background-modifier-success);
78+
background: var(--interactive-accent);
6879
}
6980
7081
.highlight:hover {
7182
background: var(--interactive-hover);
7283
}
7384
7485
.selected.highlight:hover {
75-
background: green;
86+
background: var(--interactive-accent-hover);
7687
}
7788
</style>
7889

@@ -89,7 +100,8 @@
89100
{#each cells as value (uuid())}
90101
<div
91102
class="cell"
92-
on:click={value ? () => onChange(value) : () => {}}
103+
on:click={() => selectCell(value)}
104+
on:keydown={(event) => selectCellKey(event, value)}
93105
class:highlight={value}
94106
class:content-cell={value}
95107
class:selected={selectedDate.year() === year && selectedDate.month() === month && selectedDate.date() === value}>

src/inputFields/DatePicker/DatePicker.svelte

Lines changed: 22 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,16 @@
44
import {getMonthName} from './DatePickerInputSvelteHelpers.js';
55
import {moment} from 'obsidian';
66
import type {Moment} from 'moment';
7-
import Icon from './Icon.svelte';
87
98
const dispatch = createEventDispatcher();
109
1110
export let selectedDate: Moment = moment();
12-
export let dateFormat: string = 'dddd, MMMM Do YYYY';
1311
export let dateChangeCallback: (date: Moment) => void;
1412
15-
export let alignRight: boolean;
16-
1713
let date: number;
1814
let month: number;
1915
let year: number;
20-
let showDatePicker: boolean;
16+
let isDatePickerVisible: boolean;
2117
2218
// so that these change with props
2319
$: {
@@ -54,52 +50,22 @@
5450
}
5551
5652
function onDateChange(d: { detail: Moment }): void {
57-
showDatePicker = false;
53+
isDatePickerVisible = false;
5854
selectedDate = d.detail;
5955
dateChangeCallback(d.detail);
6056
}
6157
</script>
6258

6359
<style>
64-
.date-picker-input {
65-
position: relative;
66-
color: var(--text-normal);
67-
display: inline-block;
68-
}
6960
7061
.date-picker {
71-
position: absolute;
72-
top: 35px;
73-
display: inline-block;
74-
background: var(--background-secondary);
75-
border-radius: var(--meta-bind-plugin-border-radius);
76-
border: var(--meta-bind-plugin-border-width) solid var(--background-modifier-border);
77-
padding: 10px;
78-
z-index: 1000000;
79-
}
80-
81-
.date-picker-text {
82-
background: var(--background-secondary);
83-
border-radius: var(--meta-bind-plugin-border-radius);
84-
border: var(--meta-bind-plugin-border-width) solid var(--background-modifier-border);
85-
padding: 5px 5px 5px 7px;
86-
cursor: pointer;
87-
width: fit-content;
88-
display: inline-block;
89-
}
90-
91-
.date-picker-close-layer {
92-
position: fixed;
93-
top: 0;
94-
left: 0;
95-
width: 100vw;
96-
height: 100vh;
97-
z-index: 900000; /* so it overlays everything except the date picker*/
62+
display: block;
63+
padding: var(--size-4-4);
9864
}
9965
10066
.date-picker-header {
10167
display: flex;
102-
gap: 5px;
68+
gap: var(--size-4-2);
10369
align-items: center;
10470
justify-content: space-around;
10571
}
@@ -108,15 +74,15 @@
10874
flex: 1;
10975
text-align: center;
11076
display: flex;
111-
gap: 5px;
77+
gap: var(--size-4-2);
11278
align-items: center;
11379
justify-content: center;
11480
width: min-content;
11581
}
11682
11783
.date-picker-header-text-year {
11884
width: 60px;
119-
padding: 5px;
85+
padding: var(--size-4-2);
12086
}
12187
12288
.date-picker-header-text-month {
@@ -128,29 +94,20 @@
12894
}
12995
</style>
13096

131-
<div class="date-picker-input">
132-
<div class="date-picker-text" on:click={() => showDatePicker = true}>
133-
{selectedDate.format(dateFormat)}
134-
<Icon iconName="calendar"/>
135-
</div>
136-
{#if showDatePicker}
137-
<div class="date-picker-close-layer" on:click={() => showDatePicker = false}></div>
138-
<div class="date-picker" style="{alignRight ? 'left: auto; right: 0;' : 'right: auto; left: 0;'}">
139-
<div class="date-picker-header">
140-
<button class="month-switch-button" on:click={prevMonth}>Prev</button>
141-
<div class="date-picker-header-text">
142-
<span class="date-picker-header-text-month">{getMonthName(month)}</span>
143-
<input class="date-picker-header-text-year" type="number" value="{year.toString()}"
144-
on:input="{changeYear}">
145-
</div>
146-
<button class="month-switch-button" on:click={nextMonth}>Next</button>
147-
</div>
148-
<Calender
149-
on:dateChange={onDateChange}
150-
month={month}
151-
year={year}
152-
selectedDate={selectedDate}>
153-
</Calender>
97+
<div class="date-picker">
98+
<div class="date-picker-header">
99+
<button class="month-switch-button" on:click={prevMonth}>Prev</button>
100+
<div class="date-picker-header-text">
101+
<span class="date-picker-header-text-month">{getMonthName(month)}</span>
102+
<input class="date-picker-header-text-year" type="number" value="{year.toString()}"
103+
on:input="{changeYear}">
154104
</div>
155-
{/if}
105+
<button class="month-switch-button" on:click={nextMonth}>Next</button>
106+
</div>
107+
<Calender
108+
on:dateChange={onDateChange}
109+
month={month}
110+
year={year}
111+
selectedDate={selectedDate}>
112+
</Calender>
156113
</div>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script lang="ts">
2+
import {moment} from 'obsidian';
3+
import type {Moment} from 'moment';
4+
import Icon from '../../utils/Icon.svelte';
5+
6+
export let showDatePicker: () => void;
7+
8+
export let selectedDate: Moment = moment();
9+
export let dateFormat: string = 'dddd, MMMM Do YYYY';
10+
11+
export function updateValue(value: Moment) {
12+
selectedDate = value;
13+
}
14+
15+
function datePicker(event: MouseEvent) {
16+
showDatePicker();
17+
}
18+
19+
function datePickerKey(event: KeyboardEvent) {
20+
if (event.key === ' ') {
21+
showDatePicker();
22+
}
23+
}
24+
</script>
25+
26+
<style>
27+
.date-picker-input {
28+
background: var(--background-secondary);
29+
border-radius: var(--meta-bind-plugin-border-radius);
30+
border: var(--meta-bind-plugin-border-width) solid var(--background-modifier-border);
31+
padding: 5px 5px 5px 7px;
32+
cursor: pointer;
33+
position: relative;
34+
color: var(--text-normal);
35+
display: inline-flex;
36+
align-items: center;
37+
gap: 5px;
38+
}
39+
40+
.date-picker-text {
41+
display: inline-block;
42+
}
43+
</style>
44+
45+
<div
46+
class="date-picker-input"
47+
on:click={datePicker}
48+
on:keydown={datePickerKey}>
49+
<div class="date-picker-text">
50+
<span>{selectedDate.format(dateFormat)}</span>
51+
</div>
52+
<Icon iconName="calendar"/>
53+
</div>

src/inputFields/DatePicker/DatePickerInputField.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { InputFieldMarkdownRenderChild } from '../../InputFieldMarkdownRenderChild';
22
import { AbstractInputField } from '../AbstractInputField';
33
import { MetaBindInternalError } from '../../utils/Utils';
4-
import DatePicker from './DatePicker.svelte';
4+
import DatePickerInput from './DatePickerInput.svelte';
55
import { moment } from 'obsidian';
66
import { DateParser } from '../../parsers/DateParser';
7-
import { InputFieldArgumentType } from '../../parsers/InputFieldDeclarationParser';
7+
import { DatePickerModal } from './DatePickerModal';
8+
import { Moment } from 'moment';
89

910
export class DatePickerInputField extends AbstractInputField {
1011
container: HTMLDivElement | undefined;
11-
component: DatePicker | undefined;
12+
component: DatePickerInput | undefined;
13+
modal: DatePickerModal | undefined;
1214
date: moment.Moment;
1315

1416
constructor(inputFieldMarkdownRenderChild: InputFieldMarkdownRenderChild, onValueChange: (value: any) => void | Promise<void>) {
@@ -48,15 +50,22 @@ export class DatePickerInputField extends AbstractInputField {
4850
return this.container;
4951
}
5052

51-
datePickerValueChanged(date: moment.Moment): void {
53+
datePickerValueChanged(date: Moment): void {
5254
this.date = date;
55+
this.component?.updateValue(this.date);
56+
this.modal?.close();
5357
// console.log('date picker value change', this.date);
5458

5559
if (this.date.isValid()) {
5660
this.onValueChange(this.getValue());
5761
}
5862
}
5963

64+
showDatePicker(): void {
65+
this.modal = new DatePickerModal(this.inputFieldMarkdownRenderChild.plugin.app, this);
66+
this.modal.open();
67+
}
68+
6069
render(container: HTMLDivElement): void {
6170
console.debug(`meta-bind | render datePickerInputField ${this.inputFieldMarkdownRenderChild.uid}`);
6271

@@ -68,14 +77,14 @@ export class DatePickerInputField extends AbstractInputField {
6877
this.onValueChange(this.getValue());
6978
}
7079

71-
this.component = new DatePicker({
80+
this.component = new DatePickerInput({
7281
target: container,
7382
props: {
74-
alignRight: this.inputFieldMarkdownRenderChild.getArgument(InputFieldArgumentType.ALIGN_RIGHT)?.value,
75-
selectedDate: this.date,
7683
dateFormat: this.inputFieldMarkdownRenderChild.plugin.settings.preferredDateFormat,
77-
dateChangeCallback: (date: moment.Moment) => this.datePickerValueChanged(date),
84+
showDatePicker: () => this.showDatePicker(),
7885
},
7986
});
87+
88+
this.component.updateValue(this.date);
8089
}
8190
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { App, Modal } from 'obsidian';
2+
import { Moment } from 'moment';
3+
import DatePicker from './DatePicker.svelte';
4+
import { DatePickerInputField } from './DatePickerInputField';
5+
6+
export class DatePickerModal extends Modal {
7+
opener: DatePickerInputField;
8+
9+
constructor(app: App, opener: DatePickerInputField) {
10+
super(app);
11+
this.opener = opener;
12+
}
13+
14+
public onOpen(): void {
15+
const { contentEl } = this;
16+
17+
new DatePicker({
18+
target: contentEl,
19+
props: {
20+
selectedDate: this.opener.date,
21+
dateChangeCallback: (value: Moment) => this.opener.datePickerValueChanged(value),
22+
},
23+
});
24+
}
25+
}

0 commit comments

Comments
 (0)