From 220608708e41c86204bdf24b80374d167249b818 Mon Sep 17 00:00:00 2001 From: Prasanth-Boyina <139340256+Prasanth-Boyina@users.noreply.github.com> Date: Fri, 12 Apr 2024 08:33:51 +0530 Subject: [PATCH] Range selection in calendar (#1034) * Enhancement(`ngx-calendar`): Supports selecting a range of dates with hours and minutes --- projects/swimlane/ngx-ui/CHANGELOG.md | 2 + .../calendar/calendar-select.enum.ts | 4 + .../calendar/calendar.component.html | 138 ++++++++++- .../calendar/calendar.component.scss | 221 +++++++++++++++++- .../components/calendar/calendar.component.ts | 155 ++++++++++++ .../components/calendar/calendar.module.ts | 5 +- .../calendar/calender.component.spec.ts | 109 +++++++++ .../calendar-page.component.html | 210 ++++++++++------- .../calendar-page/calendar-page.component.ts | 4 + 9 files changed, 754 insertions(+), 94 deletions(-) create mode 100644 projects/swimlane/ngx-ui/src/lib/components/calendar/calendar-select.enum.ts diff --git a/projects/swimlane/ngx-ui/CHANGELOG.md b/projects/swimlane/ngx-ui/CHANGELOG.md index 90d7b6af3..9e5069fe3 100644 --- a/projects/swimlane/ngx-ui/CHANGELOG.md +++ b/projects/swimlane/ngx-ui/CHANGELOG.md @@ -2,6 +2,8 @@ ## HEAD (unreleased) +- Enhancement(`ngx-calendar`): Supports selecting a range of dates with hours and minutes + ## 47.0.0 (2023-02-12) - Breaking: Angular 17 support diff --git a/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar-select.enum.ts b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar-select.enum.ts new file mode 100644 index 000000000..576de206d --- /dev/null +++ b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar-select.enum.ts @@ -0,0 +1,4 @@ +export enum CalendarSelect { + Single = 'single', + Range = 'range' +} diff --git a/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.html b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.html index 96b68dd08..8afea0c14 100644 --- a/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.html +++ b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.html @@ -2,14 +2,28 @@
|
+ |
+
+ |
+
diff --git a/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.scss b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.scss
index fafc95284..c64c8be58 100644
--- a/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.scss
+++ b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.scss
@@ -1,4 +1,5 @@
@import 'colors/variables';
+@import 'forms/inputs';
$calendar-bg: $color-blue-grey-800;
$calendar-border: $color-blue-grey-700;
@@ -8,6 +9,7 @@ $calendar-hover-bg: $color-blue-400;
$calendar-today-bg: $color-blue-grey-750;
$calendar-active-bg: $color-blue-400;
$calendar-active-text: $color-grey-050;
+$calendar-range-bg: $color-blue-700;
$calendar-day-text: $color-blue-grey-350;
$calendar-month-current: $color-blue-grey-750;
@@ -19,8 +21,7 @@ $calendar-month-current: $color-blue-grey-750;
display: inline-block;
border: 1px solid $calendar-border;
width: 270px;
- padding: 0.5rem;
- height: 270px;
+ padding: 0.5rem 0rem;
.ngx-calendar-wrap {
flex: 1 1 100%;
@@ -72,6 +73,10 @@ $calendar-month-current: $color-blue-grey-750;
}
}
+ td {
+ padding: 0px;
+ }
+
.day-name,
.day-cell {
margin: 0.1rem 0.2rem;
@@ -80,6 +85,14 @@ $calendar-month-current: $color-blue-grey-750;
width: 1.8rem;
height: 1.8rem;
}
+ .day-name,
+ .day-cell2 {
+ line-height: 1.8rem;
+ text-align: center;
+ width: 34px;
+ height: 32px;
+ margin: 0.1rem 0.2rem;
+ }
.day-container {
margin-top: 0;
@@ -87,10 +100,13 @@ $calendar-month-current: $color-blue-grey-750;
.day-row {
display: flex;
-
.day-cell {
flex: 1 0 30px;
}
+ .day-cell2 {
+ flex: 1 0 30px;
+ margin: 0.1rem 0rem;
+ }
}
.day {
@@ -128,6 +144,165 @@ $calendar-month-current: $color-blue-grey-750;
}
}
}
+
+ button.day2 {
+ color: $calendar-active-text;
+ height: 100%;
+ width: 100%;
+ max-height: 34px;
+ max-width: 32px;
+ line-height: 100%;
+ border-radius: 50%;
+ text-align: center;
+ transition: background 200ms;
+ padding: 0;
+ position: relative;
+
+ &.prev-month,
+ &.next-month {
+ color: $calendar-day-text;
+ opacity: 0.2;
+ }
+
+ &.today {
+ background: $calendar-today-bg;
+ }
+
+ &.active {
+ background: $calendar-active-bg;
+ color: $calendar-active-text;
+ }
+
+ &.extreme1 {
+ position: relative;
+ &:not(.extreme2) {
+ &:before {
+ content: '';
+ position: absolute;
+ top: 0%;
+ left: 50%;
+ right: -10%;
+ bottom: 0%;
+ background: $calendar-range-bg;
+ z-index: 1;
+ opacity: 50%;
+ text-align: center;
+ }
+ &:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: $calendar-active-bg;
+ border-radius: 50%;
+ z-index: 2;
+ text-align: center;
+ }
+ }
+ }
+ &.extreme2 {
+ position: relative;
+ outline: 2px solid transparent;
+ &:not(.extreme1) {
+ &:before {
+ content: '';
+ position: absolute;
+ top: 0%;
+ left: -9.9%;
+ right: 50%;
+ bottom: 0%;
+ background: $calendar-range-bg;
+ z-index: 1;
+ opacity: 50%;
+ }
+ &:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: $calendar-bg;
+ outline: 2px solid #1483ff;
+ outline-offset: -1px;
+ border-radius: 50%;
+ z-index: 2;
+ }
+ }
+ }
+ &.range {
+ color: $calendar-active-text;
+ margin: 0rem 0rem;
+ max-width: initial;
+ flex: 1 1 30px;
+ &:before {
+ content: '';
+ position: absolute;
+ top: -0%;
+ left: -0%;
+ right: -0%;
+ bottom: -0%;
+ background: $calendar-range-bg;
+ z-index: 1;
+ opacity: 50%;
+ text-align: center;
+ }
+ &:hover {
+ &:not([disabled]) {
+ outline: 2px solid #1483ff;
+ outline-offset: 1px;
+ z-index: 2;
+ border-radius: 50%;
+ max-width: 32px;
+ max-height: 34px;
+ &:before {
+ content: '';
+ position: absolute;
+ top: -0%;
+ left: -9.9%;
+ right: -10%;
+ bottom: -0%;
+ background: $calendar-range-bg;
+ z-index: 1;
+ opacity: 50%;
+ text-align: center;
+ }
+ }
+ }
+ &.today {
+ border-radius: 50%;
+ max-width: 32px;
+ max-height: 34px;
+ background: $calendar-today-bg;
+ &:before {
+ content: '';
+ position: absolute;
+ top: -0%;
+ left: -9.9%;
+ right: -10%;
+ bottom: -0%;
+ background: $calendar-range-bg;
+ z-index: 1;
+ opacity: 50%;
+ text-align: center;
+ }
+ }
+ }
+ .day-num {
+ position: relative;
+ z-index: 4;
+ color: $calendar-active-text;
+ }
+ &:hover:not(.extremes) {
+ &:hover:not([disabled]) {
+ outline: 2px solid #1483ff;
+ outline-offset: 1px;
+ border-radius: 50%;
+ }
+ }
+ }
}
.months-container,
@@ -197,3 +372,43 @@ $calendar-month-current: $color-blue-grey-750;
}
}
}
+
+.time-row {
+ background: $calendar-bg;
+ border-top: 1px solid $calendar-border;
+ border-bottom: 1px solid $calendar-border;
+ padding: 24px 18px 6px 18px;
+
+ flex-direction: row;
+ box-sizing: border-box;
+ display: flex;
+ place-content: stretch center;
+ align-items: baseline;
+ justify-content: space-between;
+
+ > * {
+ flex: 0 0 calc(15% - 6px);
+ }
+
+ .ngx-input {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 0;
+ width: 73px;
+ height: 46px;
+
+ .ngx-input-underline {
+ background-color: $color-input-text;
+ }
+ }
+
+ button.ampm {
+ color: $color-blue-grey-500;
+
+ &.selected {
+ color: $color-white;
+ background-color: #818fa933;
+ opacity: 20;
+ }
+ }
+}
diff --git a/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.ts b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.ts
index 27526fff5..6791199c8 100644
--- a/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.ts
+++ b/projects/swimlane/ngx-ui/src/lib/components/calendar/calendar.component.ts
@@ -20,6 +20,7 @@ import { getDecadeStartYear } from './utils/get-decade-start-year/get-decade-sta
import { CalendarDay } from './calendar-day.interface';
import { CalendarMonth } from './calendar-month.type';
import { CalendarView } from './calendar-view.enum';
+import { CalendarSelect } from './calendar-select.enum';
import { KeyboardKeys } from '../../enums/keyboard-keys.enum';
const CALENDAR_VALUE_ACCESSOR = {
@@ -28,6 +29,11 @@ const CALENDAR_VALUE_ACCESSOR = {
multi: true
};
+export interface CalendarDateRange {
+ startDate: Date | undefined;
+ endDate: Date | undefined;
+}
+
@Component({
selector: 'ngx-calendar',
exportAs: 'ngxCalendar',
@@ -53,6 +59,9 @@ export class CalendarComponent implements OnInit, AfterViewInit, ControlValueAcc
@Input() daysOfWeek: string[] = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
@Input() timezone: string;
@Input() inputFormats: Array
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CalendarBasic-Current Date:
- {{curDate1}}
+ + Current Date: + {{ curDate1 }} - + Min/Max Dates-Min Date: - {{minDate}} and Max Date: - {{maxDate}} + + Min Date: {{ minDate }} and Max Date: + {{ maxDate }} - + DisabledTimezones- -Local: {{dateTz | amDateFormat: 'LL zz' }}-UTC: {{dateTz | amTimeZone: 'utc' | amDateFormat: 'LL zz' }}-JST: {{dateTz | amTimeZone: 'Asia/Tokyo' | amDateFormat: 'LL zz' }}-Local: {{ dateTz | amDateFormat: 'LL zz' }}+UTC: {{ dateTz | amTimeZone: 'utc' | amDateFormat: 'LL zz' }}+JST: {{ dateTz | amTimeZone: 'Asia/Tokyo' | amDateFormat: 'LL zz' }}+- + + Select Range+Min view and Default view- -Min view: "date" default view: "date"-Min view: "date" default view: "date"+Current Date: - {{curDate4}} + + Current Date: + {{ curDate4 }} - - Min view: "date" default view: "month"-Min view: "date" default view: "month"+Current Date: - {{curDate5}} + + Current Date: + {{ curDate5 }} - Min view: "month" default view: "year"-Min view: "month" default view: "year"+Current Date: - {{curDate6}} + + Current Date: + {{ curDate6 }} - + Flexible Width- -Table of ContentsComponent Inputs Component Outputs -+ Component Inputs
+ Component Outputs
|