Skip to content

Commit

Permalink
refactor: integrate dropdown for fullscreen mode
Browse files Browse the repository at this point in the history
  • Loading branch information
sun-mota committed Dec 6, 2024
1 parent 5c6c131 commit cb3ee00
Show file tree
Hide file tree
Showing 11 changed files with 397 additions and 216 deletions.
182 changes: 111 additions & 71 deletions components/datepicker/demo/api.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions components/datepicker/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

<!-- If additional elements are needed for the demo, add them here. -->
<script src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-accordion@latest/dist/auro-accordion__bundled.js" type="module"></script>
<script src="https://cdn.jsdelivr.net/npm/@aurodesignsystem/auro-button@latest/dist/auro-button__bundled.js" type="module"></script>

<script type="module" data-demo-script="true">
import { initExamples } from "./index.min.js";
Expand Down
182 changes: 111 additions & 71 deletions components/datepicker/demo/index.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion components/datepicker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"sass:render": "sass-render --load-path=../../node_modules 'src/**/*.css' -t ../../node_modules/@aurodesignsystem/auro-library/scripts/build/staticStyles-template.js",
"serve": "web-dev-server",
"test": "wtr --config \"../../packages/config/src/web-test-runner.config.mjs\" --coverage",
"test:watch": "wtr --watch",
"test:watch": "wtr --config \"../../packages/config/src/web-test-runner.config.mjs\" --watch",
"types": "tsc --project tsconfig.json",
"lint": "npm-run-all scssLint esLint",
"scssLint": "stylelint \"./src/**/*.scss\"",
Expand Down
140 changes: 84 additions & 56 deletions components/datepicker/src/auro-calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { RangeDatepicker } from './vendor/wc-range-datepicker/range-datepicker.j
import chevronLeft from '@alaskaairux/icons/dist/icons/interface/chevron-left.mjs';
import chevronRight from '@alaskaairux/icons/dist/icons/interface/chevron-right.mjs';

import AuroLibraryRuntimeUtils from '@aurodesignsystem/auro-library/scripts/utils/runtimeUtils.mjs';

import { AuroDatepickerUtilities } from './utilities.js';
import { CalendarUtilities } from './utilitiesCalendar.js';
import { UtilitiesCalendarRender } from './utilitiesCalendarRender.js';
Expand Down Expand Up @@ -74,10 +76,17 @@ export class AuroCalendar extends RangeDatepicker {
*/
this.numCalendars = undefined;


/**
* @private
*/
this.isVisible = false;


/**
* @private
*/
this.mobileBreakpoint = 660;
this.slots = {};
}

static get styles() {
Expand Down Expand Up @@ -146,76 +155,84 @@ export class AuroCalendar extends RangeDatepicker {
* @returns {Object} Returns the auro-calendar-months HTML.
*/
renderAllCalendars() {
this.utilCalRender.setFirstRenderableMonthDate(this);
if (this.isVisible) {
this.utilCalRender.setFirstRenderableMonthDate(this);

const mobileLayout = window.innerWidth < this.mobileBreakpoint;
let renderedHtml = undefined;
const dropdown = AuroLibraryRuntimeUtils.prototype.closestElement('auro-dropdown, [auro-dropdown]', this);
const dropdownbib = dropdown ? dropdown.bibContent : AuroLibraryRuntimeUtils.prototype.closestElement('auro-dropdownbib', this);
const mobileLayout = dropdownbib.hasAttribute('isfullscreen');
this.utilCalRender.determineNumCalendarsToRender(this, mobileLayout);

// Determine which month to render first
let dateMatches = undefined;
let renderedHtml = undefined;

if (!mobileLayout && this.centralDate) {
// On Desktop start the calendar at the central date if it exists, then minDate and finally the current date.
if (this.centralDate) {
dateMatches = this.util.datesMatch(this.firstRenderedMonth, this.util.convertDateToFirstOfMonth(this.centralDate));
// Determine which month to render first
let dateMatches = undefined;

if (!dateMatches) {
this.firstRenderedMonth = this.util.convertDateToFirstOfMonth(this.centralDate);
}
} else if (this.minDate) {
dateMatches = this.util.datesMatch(this.firstRenderedMonth, this.util.convertDateToFirstOfMonth(this.minDate));
if (!mobileLayout && this.centralDate) {
// On Desktop start the calendar at the central date if it exists, then minDate and finally the current date.
if (this.centralDate) {
dateMatches = this.util.datesMatch(this.firstRenderedMonth, this.util.convertDateToFirstOfMonth(this.centralDate));

if (!dateMatches) {
this.firstRenderedMonth = this.util.convertDateToFirstOfMonth(this.minDate);
}
} else {
const now = new Date();
if (!dateMatches) {
this.firstRenderedMonth = this.util.convertDateToFirstOfMonth(this.centralDate);
}
} else if (this.minDate) {
dateMatches = this.util.datesMatch(this.firstRenderedMonth, this.util.convertDateToFirstOfMonth(this.minDate));

if (!dateMatches) {
this.firstRenderedMonth = this.util.convertDateToFirstOfMonth(this.minDate);
}
} else {
const now = new Date();

dateMatches = this.util.datesMatch(this.firstRenderedMonth, this.util.convertDateToFirstOfMonth(now));
dateMatches = this.util.datesMatch(this.firstRenderedMonth, this.util.convertDateToFirstOfMonth(now));

if (!dateMatches) {
this.firstRenderedMonth = this.util.convertDateToFirstOfMonth(now);
if (!dateMatches) {
this.firstRenderedMonth = this.util.convertDateToFirstOfMonth(now);
}
}
} else {
// On mobile start the calendar at the previously determined first renderable month.
this.firstRenderedMonth = this.firstMonthRenderable;
}
} else {
// On mobile start the calendar at the previously determined first renderable month.
this.firstRenderedMonth = this.firstMonthRenderable;
}

// Add the first calendar to the HTML
const firstMonth = this.firstRenderedMonth.getMonth() + 1;
const firstYear = this.firstRenderedMonth.getFullYear();
// Add the first calendar to the HTML
const firstMonth = this.firstRenderedMonth.getMonth() + 1;
const firstYear = this.firstRenderedMonth.getFullYear();

renderedHtml = html`${renderedHtml}${this.utilCalRender.renderCalendar(this, firstMonth, firstYear)}`;
renderedHtml = html`${renderedHtml}${this.utilCalRender.renderCalendar(this, firstMonth, firstYear)}`;

// Loop through the number of remaining calendars to render and add the HTML
let newMonthDate = undefined;
// Loop through the number of remaining calendars to render and add the HTML
let newMonthDate = undefined;

for (let cal = 0; cal < this.numCalendars - 1; cal += 1) {
for (let cal = 0; cal < this.numCalendars - 1; cal += 1) {

const date = newMonthDate || this.firstRenderedMonth;
const date = newMonthDate || this.firstRenderedMonth;

const oldMonth = date.getMonth() + 1;
const oldYear = date.getFullYear();
const oldMonth = date.getMonth() + 1;
const oldYear = date.getFullYear();

let newMonth = undefined;
let newYear = undefined;
let newMonth = undefined;
let newYear = undefined;

if (oldMonth === 12) {
newMonth = 1;
newYear = oldYear + 1;
} else {
newMonth = oldMonth + 1;
newYear = oldYear;
}
if (oldMonth === 12) {
newMonth = 1;
newYear = oldYear + 1;
} else {
newMonth = oldMonth + 1;
newYear = oldYear;
}

const newMonthDateStr = `${newMonth}/1/${newYear}`;
newMonthDate = new Date(newMonthDateStr);
const newMonthDateStr = `${newMonth}/1/${newYear}`;
newMonthDate = new Date(newMonthDateStr);

renderedHtml = html`${renderedHtml}${this.utilCalRender.renderCalendar(this, newMonth, newYear)}`;
}
renderedHtml = html`${renderedHtml}${this.utilCalRender.renderCalendar(this, newMonth, newYear)}`;
}

return renderedHtml;
this.allCalendarHtml = renderedHtml;
} else {
this.allCalendarHtml = null;
}
}

/**
Expand Down Expand Up @@ -247,13 +264,22 @@ export class AuroCalendar extends RangeDatepicker {
}));
});

this.utilCalRender.determineNumCalendarsToRender(this);

window.addEventListener('resize', () => {
this.utilCalRender.determineNumCalendarsToRender(this);
this.renderAllCalendars();
});
}

toggleVisibility(visibility) {
this.isVisible = visibility;

// wait for dropdownbib's fullscreen attribute
setTimeout(() => this.renderAllCalendars());
}

injectSlot(slotName, nodes) {
this.slots[slotName] = nodes;
}

updated(changedProperties) {
if (changedProperties.has('noRange')) {
this.noRangeChanged(this.noRange, changedProperties.get('noRange'));
Expand All @@ -270,20 +296,22 @@ export class AuroCalendar extends RangeDatepicker {
if (changedProperties.has('centralDate')) {
this.utilCal.centralDateChanged(this);
}

this.renderAllCalendars();
}

render() {
return html`
<div class="calendarWrapper">
<div class="mobileHeader">
<div class="headerDateFrom">
<span class="mobileDateLabel"><slot name="mobileDateLabel"></slot></span>
<span class="mobileDateLabel">${this.slots.mobileDateLabel}</span>
<slot name="mobileDateFromStr"></slot>
</div>
<div class="headerDateTo"><slot name="mobileDateToStr"></slot></div>
</div>
<div class="calendars">
${this.renderAllCalendars(this)}
${this.allCalendarHtml}
</div>
<div class="mobileFooter">
<div class="mobileFooterActions">
Expand Down
17 changes: 15 additions & 2 deletions components/datepicker/src/auro-datepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@ export class AuroDatePicker extends LitElement {
this.setAttribute('aria-expanded', this.dropdown.isPopoverVisible);
this.notifyDatepickerToggled();

this.calendar.toggleVisibility(this.dropdown.isPopoverVisible);

if (this.dropdown.getAttribute('data-show')) {
if (this.forceScrollOnNextMobileCalendarRender) {
this.calendar.scrollMonthIntoView(this.calendarFocusDate);
Expand Down Expand Up @@ -542,6 +544,12 @@ export class AuroDatePicker extends LitElement {
});

this.calendar.addEventListener('auroCalendar-centralDateChanged', (event) => {
const match = this.util.datesMatch(event.detail.date, this.centralDate);

if (!match) {
this.calendarRenderUtil.updateCentralDate(this, event.detail.date);
}

this.notifyMonthChanged(event);
});
}
Expand Down Expand Up @@ -850,6 +858,11 @@ export class AuroDatePicker extends LitElement {
}
}

handleSlotToSlot(event) {
const slot = this.querySelector(`[slot='${event.target.name}']`);
this.calendar.injectSlot(event.target.name, slot.cloneNode(true));
}

firstUpdated() {
// Add the tag name as an attribute if it is different than the component name
this.runtimeUtils.handleComponentTagRename(this, 'auro-datepicker');
Expand All @@ -876,6 +889,7 @@ export class AuroDatePicker extends LitElement {
?error="${this.validity !== undefined && this.validity !== 'valid'}"
disableEventShow
noHideOnThisFocusLoss
mobileFullscreenBreakpoint="sm"
part="dropdown">
<div slot="trigger" class="dpTriggerContent" part="trigger">
<${this.inputTag}
Expand Down Expand Up @@ -921,9 +935,8 @@ export class AuroDatePicker extends LitElement {
.maxDate="${this.maxDate}"
.minDate="${this.minDate}"
part="calendar"
@auroCalendar-centralDateChanged="${this.handleCalendarCentralDateChange}"
>
<slot slot="mobileDateLabel" name="mobileDateLabel"></slot>
<slot slot="mobileDateLabel" name="mobileDateLabel" @slotchange="${this.handleSlotToSlot}"></slot>
<span slot="mobileDateFromStr">${this.value ? this.getMobileDateStr(this.value) : html`<span class="placeholderDate">MM/DD/YYYY</span>`}</span>
${this.range ? html`<span slot="mobileDateToStr">${this.valueEnd ? this.getMobileDateStr(this.valueEnd) : html`<span class="placeholderDate">MM/DD/YYYY</span>`}</span>` : undefined}
</auro-calendar>
Expand Down
1 change: 1 addition & 0 deletions components/datepicker/src/styles/style-auro-calendar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
.calendarWrapper {
display: flex;
height: 100%;
max-height: 100dvh;

flex-direction: column;
overflow: auto hidden;
Expand Down
2 changes: 1 addition & 1 deletion components/datepicker/src/styles/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@

.calendarWrapper {
display: flex;
height: 100%;
height: 100dvh;
flex-direction: row;
justify-content: center;
}
Expand Down
1 change: 0 additions & 1 deletion components/datepicker/src/utilitiesCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ export class CalendarUtilities {

// calculate the new central date
const newCentralDate = new Date(elem.centralDate).setMonth(new Date(elem.centralDate).getMonth() + increment);

// set the new central date to the first day of the month
elem.centralDate = this.util.convertDateToFirstOfMonth(newCentralDate);
}
Expand Down
10 changes: 6 additions & 4 deletions components/datepicker/src/utilitiesCalendarRender.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ export class UtilitiesCalendarRender {
/**
* Determines how many calendar months can be rendered based on the screen size and defined range.
* @param {Object} elem - The auro-calendar element.
* @param {Boolean} isMobile - true if it's to render for mobile view
* @private
* @returns {Number} Returns the maximum number of months that can be rendered.
*/
maximumRenderableMonths(elem) {
maximumRenderableMonths(elem, isMobile) {
const definedRangeMonths = this.determineDefinedCalendarRange(elem);

// number of calendars that could be rendered at a time
Expand All @@ -56,7 +57,7 @@ export class UtilitiesCalendarRender {
}

// change the max calendar number when viewed on mobile
if (window.innerWidth < elem.mobileBreakpoint) {
if (isMobile) {
// use definedRangeMonths if we have it otherwise default to 12
numCalendars = definedRangeMonths || 12; // eslint-disable-line no-magic-numbers
}
Expand All @@ -74,13 +75,14 @@ export class UtilitiesCalendarRender {
/**
* Determines the number of months rendered inside the calendar.
* @param {Object} elem - The auro-calendar element.
* @param {Boolean} isMobile - true if it's to render for mobile view
* @private
* @returns {void}
*/
determineNumCalendarsToRender(elem) {
determineNumCalendarsToRender(elem, isMobile) {
// 1. Determine the maximum number of months that can be rendered.
// This is based on the screen size and the defined range of months.
const maxRenderableMonths = this.maximumRenderableMonths(elem);
const maxRenderableMonths = this.maximumRenderableMonths(elem, isMobile);

// 2. Start by assuming we can render the max number of months.
let calendarCount = maxRenderableMonths;
Expand Down
Loading

0 comments on commit cb3ee00

Please sign in to comment.