Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement(Datepicker) implementation with confirmation buttons util #592

Open
wants to merge 22 commits into
base: v2-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7e1f83f
enhancement(Datepicker) refactor styling to accomply with material m3…
gselderslaghs Dec 27, 2024
a12be61
enhancement(Datepicker) refinement on daterange styling, revert day c…
gselderslaghs Dec 27, 2024
b8c344b
enhancement(Datepicker) refactor all modal related selectors #558
gselderslaghs Dec 27, 2024
1e9c276
enhancement(Datepicker) refactor modal css selectors
gselderslaghs Dec 27, 2024
b599ff2
enhancement(Datepicker) implemented input field callback functions #558
gselderslaghs Dec 27, 2024
4f5c37a
enhancement(Datepicker) allow user specified end date element #558
gselderslaghs Dec 27, 2024
ae8a06a
enhancement(Datepicker) implemented date format rendering in supporti…
gselderslaghs Dec 27, 2024
9c455bb
enhancement(Datepicker) implemented open by default option #558
gselderslaghs Dec 27, 2024
3bcbccf
enhancement(Datepicker) fix inconsistency in datepicker days rendering
gselderslaghs Dec 27, 2024
695cbe9
fix failing spec tests
gselderslaghs Dec 27, 2024
bd83553
enhancement(Datepicker) add daterange class programmatically for date…
gselderslaghs Dec 27, 2024
29ff969
enhancement(Datepicker) fixed classmapping calendar day element css s…
gselderslaghs Dec 28, 2024
2c4e2ae
enhancement(Datepicker) add implemented day selector classes without …
gselderslaghs Dec 28, 2024
b53f1ff
test(Datepicker) refactor failing test; fix change is an invalid keyb…
gselderslaghs Jan 13, 2025
ca0afc0
Merge branch 'confirmation-container-util' into datepicker-confirmati…
gselderslaghs Jan 14, 2025
f8bd01e
enhancement(Datepicker) implementation with confirmation buttons util…
gselderslaghs Jan 14, 2025
6d2e849
Merge branch 'datepicker-spectest' into datepicker-confirmation-butto…
gselderslaghs Jan 15, 2025
a211b0c
enhancement(Datepicker) set autoSubmit to true by default
gselderslaghs Jan 15, 2025
b618678
test(Datepicker) remove confirm click from existing tests since autoS…
gselderslaghs Jan 15, 2025
2e48662
format test function
gselderslaghs Jan 15, 2025
2d5d175
test(Datepicker) refactor to depend on user input value validation
gselderslaghs Jan 15, 2025
11f9548
remove unused variable
gselderslaghs Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 89 additions & 20 deletions sass/components/_datepicker.scss
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
/* Modal */
.datepicker-modal {
// @removed since v2.2.1
/*.datepicker-modal {
max-width: 325px;
// @removed since v2.2.1-dev regarding Material M3 standards
min-width: 300px;
max-height: none;
}
}*/

.datepicker-container.modal-content {
.datepicker-container {
display: flex;
flex-direction: column;
max-width: 325px;
padding: 0;
background-color: var(--md-sys-color-surface);
}
Expand Down Expand Up @@ -43,6 +46,11 @@
vertical-align: middle;
}

.select-year input,
.select-month input {
background-color: transparent;
}

.select-year input {
width: 50px;
}
Expand Down Expand Up @@ -75,9 +83,11 @@
/* Date Display */
.datepicker-date-display {
flex: 1 auto;
background-color: var(--md-sys-color-primary);
color: var(--md-sys-color-on-primary);
// @removed since v2.2.1-dev regarding Material M3 standards
// background-color: var(--md-sys-color-primary);
// color: var(--md-sys-color-on-primary);
padding: 20px 22px;
border-bottom: 1px solid var(--md-sys-color-surface-variant-light);
font-weight: 500;

.year-text {
Expand All @@ -93,6 +103,12 @@
line-height: 47px;
font-weight: 500;
}

.daterange & {
.date-text {
font-size: 1.8rem;
}
}
}


Expand Down Expand Up @@ -124,46 +140,98 @@
color: var(--md-sys-color-on-surface-variant);
}

td {
.datepicker-day {
color: var(--md-sys-color-on-background);

&.is-today {
color: var(--md-sys-color-primary);
}

&.is-selected {
/*&.is-selected button {
background-color: var(--md-sys-color-primary);
color: var(--md-sys-color-on-primary);
}

&.is-outside-current-month,
&.is-disabled {
color: var(--md-sys-color-on-surface);
pointer-events: none;
}
}*/

border-radius: 50%;
// border-radius: 50%;
padding: 0;
}
}

// @todo
.datepicker-day.has-event {}
// @todo
.datepicker-day.is-inrange {}
// @todo
.datepicker-day.is-startrange {}
// @todo
.datepicker-day.is-endrange {}

.datepicker-day.is-daterange-start,
.datepicker-day.is-daterange-end,
.datepicker-day.is-daterange {
position: relative;

&:before {
position: absolute;
top: 5px;
width: 100%;
height: 34px;
content: '';
background-color: var(--md-sys-color-primary-container);
z-index: 0;
}
}

.datepicker-day.is-daterange-start:before,
.datepicker-day.is-daterange-end:before {
width: 50%;
}

.datepicker-day.is-daterange-start:before {
left: 50%;
}

.datepicker-day.is-daterange .datepicker-day-button:before {
background-color: var(--md-sys-color-primary-container);
}

.datepicker-day-button {
background-color: transparent;
border: none;
line-height: 38px;
line-height: 34px;
display: block;
width: 100%;
width: 34px;
border-radius: 50%;
margin: 5px;
padding: 0 5px;
cursor: pointer;
color: inherit;

position: relative;
z-index: 1;

&:hover {
background-color: rgba(var(--md-sys-color-primary-numeric), 0.06);
}

&:focus {
background-color: rgba(var(--md-sys-color-primary-numeric), 0.18);
border-color: var(--md-sys-color-primary);
}

.is-selected & {
background-color: var(--md-sys-color-primary);
color: var(--md-sys-color-on-primary);

&:focus {
background-color: var(--md-sys-color-surface-variant);
color: var(--md-sys-color-primary);
}
}

&.is-outside-current-month button,
&.is-disabled button {
color: var(--md-sys-color-on-surface);
pointer-events: none;
}
}

Expand Down Expand Up @@ -192,7 +260,8 @@

/* Media Queries */
@media #{$medium-and-up} {
.datepicker-modal {
// @removed since v2.2.1-dev regarding Material M3 standards
/*.datepicker-modal {
max-width: 625px;
}

Expand All @@ -212,5 +281,5 @@

.datepicker-day-button {
line-height: 44px;
}
}*/
}
111 changes: 74 additions & 37 deletions spec/tests/datepicker/datepickerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ describe('Datepicker Plugin', () => {
it('can have a string format', (done) => {
const input = document.querySelector('#datepickerInput');
const today = new Date();
M.Datepicker.init(input, { format: 'mm/dd/yyyy' });
M.Datepicker.init(input, { format: 'mm/dd/yyyy', openByDefault: true });
const datepicker = M.Datepicker.getInstance(input);
//datepicker.open();
setTimeout(() => {
const day1 = document.querySelector('.datepicker-modal button[data-day="1"]');
const day1 = document.querySelector('.datepicker-container button[data-day="1"]');
day1.click();
document.querySelector('.datepicker-done').click();
// Removed since autoSubmit option
// document.querySelector('.datepicker-done').click();
setTimeout(() => {
const year = today.getFullYear();
const month = today.getMonth() + 1;
Expand All @@ -37,64 +38,55 @@ describe('Datepicker Plugin', () => {
const input = document.querySelector('#datepickerInput');
const today = new Date();
const formatFn = `${today.getFullYear() - 100}-${today.getMonth() + 1}-99`;
M.Datepicker.init(input, { format: formatFn });
M.Datepicker.init(input, { format: formatFn, openByDefault: true });
const datepicker = M.Datepicker.getInstance(input);
//datepicker.open();
setTimeout(() => {
const day1 = document.querySelector('.datepicker-modal button[data-day="1"]');
const day1 = document.querySelector('.datepicker-container button[data-day="1"]');
day1.click();
document.querySelector('.datepicker-done').click();
// Removed since autoSubmit option
// document.querySelector('.datepicker-done').click();
setTimeout(() => {
const year = today.getFullYear() - 100;
const month = today.getMonth() + 1;
expect(datepicker.toString()).toEqual(`${year}-${month < 10 ? `0${month}` : month}-99`);
expect(datepicker.toString()).toEqual(`${year}-${month}-99`);
done();
}, 400);
}, 400);
});

it('can change the calendar modal selected date by input', (done) => {
const input = document.querySelector('#datepickerInput');
M.Datepicker.init(input, { format: 'mm/dd/yyyy' });
M.Datepicker.init(input, { format: 'mm/dd/yyyy', openByDefault: true });
const today = new Date();
const month = today.getMonth();
const year = today.getFullYear() - 44;
const day = 11;
input.value = `${month < 10 ? `0${month}` : month}/${day}/${year}`;
input.dispatchEvent(new KeyboardEvent('change', { bubbles: true, cancelable: true }));
keydown(input, 13);
input.value = `${month + 1}/${day}/${year}`;
input.dispatchEvent(new InputEvent('change', { bubbles: true, cancelable: true }));
input.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, cancelable: true, keyCode: 13 }));
setTimeout(() => {
// expect(document.querySelector('.datepicker-modal')).toHaveClass(
// 'open',
// 'modal should be shown after input is submitted.'
// );
const selectMonthElem = document.querySelector('.datepicker-select.orig-select-month');
const selectYearElem = document.querySelector('.datepicker-select.orig-select-year');
const selectedDayElem = document.querySelector(`.datepicker-row td[data-day="${day}"]`);
expect(
selectMonthElem.querySelector('option[selected="selected"]').value ===
(month - 1).toString()
).toEqual(
true,
`selected month should be ${month}, given value ${selectMonthElem.querySelector('option[selected="selected"]').value}`
);
expect(
selectYearElem.querySelector('option[selected="selected"]').value === year.toString()
).toEqual(
true,
`selected year should be ${year}, given value ${selectYearElem.querySelector('option[selected="selected"]').value}`
);
expect(selectedDayElem.classList.contains('is-selected')).toEqual(
true,
`selected day should be ${day}, given value ${selectedDayElem.classList}`
);
expect(selectMonthElem.querySelector('option[selected="selected"]').value)
.withContext(
'selected month does not match'
).toBe((month).toString());
expect(selectYearElem.querySelector('option[selected="selected"]').value)
.withContext(
'selected year does not match'
).toBe(year.toString());
expect(selectedDayElem.classList.contains('is-selected')).withContext(
'selected day does not match'
).toBe(true);
done();
}, 10);
});

it('should have a date range input field if date range option is enabled', (done) => {
const input = document.querySelector('#datepickerInput');
M.Datepicker.init(input, { isDateRange: true });
M.Datepicker.init(input, { isDateRange: true, openByDefault: true });
setTimeout(() => {
expect(document.querySelector('.datepicker-end-date')).toExist(
'end date input should exist'
Expand All @@ -105,21 +97,66 @@ describe('Datepicker Plugin', () => {

it('should have multiple input fields if multiple select option is enabled and multiple dates are selected', (done) => {
const input = document.querySelector('#datepickerInput');
M.Datepicker.init(input, { isMultipleSelection: true });
M.Datepicker.init(input, { isMultipleSelection: true, openByDefault: true });
const datepicker = M.Datepicker.getInstance(input);
datepicker.open();
setTimeout(() => {
for (let i = 1; i < 4; i++) {
for (let i = 1; i <= 3; i++) {
setTimeout(() => {
document.querySelector(`.datepicker-modal button[data-day="${i}"]`).click();
document.querySelector(`.datepicker-container button[data-day="${i}"]`).click();
}, i * 10);
}
setTimeout(() => {
document.querySelector('.datepicker-done').click();
// Removed since autoSubmit option
// document.querySelector('.datepicker-done').click();
expect(document.querySelectorAll('.datepicker').length === 3).toEqual(true);
done();
}, 40);
}, 10);
});

it('should integrate action util buttons by option', (done) => {
const input = document.querySelector('#datepickerInput');
M.Datepicker.init(input, { format: 'mm/dd/yyyy', autoSubmit: false, showClearBtn: true });
const today = new Date();
const clearBtn = document.querySelector('.datepicker-clear');
const cancelBtn = document.querySelector('.btn-cancel');
const confirmBtn = document.querySelector('.btn-confirm');
const year = today.getFullYear();
const month = today.getMonth() + 1;
const day = today.getDay() <= 26 ? today.getDay() + 2 : today.getDay() - 2;

setTimeout(() => {
expect(clearBtn).toExist('clear button should exist');
expect(cancelBtn).toExist('cancel should exist');
expect(confirmBtn).toExist('confirm should exist');
let dayEl = document.querySelector(`.datepicker-container button[data-day="${day}"]`);
dayEl.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
confirmBtn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
setTimeout(() => {
expect(input.value)
.withContext('value should change with confirm interaction')
.toEqual(`${month < 10 ? `0${month}` : month}/0${day}/${year}`);
dayEl = document.querySelector('.datepicker-container button[data-day="1"]');
dayEl.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
cancelBtn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
setTimeout(() => {
expect(input.value)
.withContext('value should not change with cancel interaction')
.toEqual(`${month < 10 ? `0${month}` : month}/0${day}/${year}`);
clearBtn.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
setTimeout(() => {
expect(input.value.length)
.withContext('input field should be empty with clear interaction')
.toEqual(0);
expect(document.querySelector('.datepicker-container button.is-selected'))
.withContext('there should be no selected day with clear interaction')
.toBe(null);
done();
}, 10);
}, 10);
}, 10);
});
});
});
});
Loading
Loading