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

feat(date-picker): add option to show week numbers #1605

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion .storybook/stories/datepicker/date-container.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,22 @@ export default {
argTypes: {
// inputs
clrPosition: { control: 'radio', options: CLR_MENU_POSITIONS },
clrShowWeekNumbers: { control: 'boolean' },
// methods
addGrid: { control: { disable: true }, table: { disable: true } },
controlClass: { control: { disable: true }, table: { disable: true } },
},
args: {
// inputs
clrPosition: 'bottom-left',
clrShowWeekNumbers: true,
},
};

const DatePickerTemplate: StoryFn = args => ({
template: `
<div style="margin-top: 300px; display: flex; justify-content: center">
<clr-date-container [clrPosition]="clrPosition">
<clr-date-container [clrPosition]="clrPosition" [clrShowWeekNumbers]="clrShowWeekNumbers">
<label>Date</label>
<input type="date" autocomplete="off" clrDate />
</clr-date-container>
Expand Down
22 changes: 17 additions & 5 deletions projects/angular/clarity.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -653,14 +653,16 @@ export class ClrCalendar implements OnDestroy {
// Warning: (ae-forgotten-export) The symbol "DateNavigationService" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "DatepickerFocusService" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "DateIOService" needs to be exported by the entry point index.d.ts
constructor(_localeHelperService: LocaleHelperService, _dateNavigationService: DateNavigationService, _datepickerFocusService: DatepickerFocusService, _dateIOService: DateIOService, _elRef: ElementRef<HTMLElement>);
constructor(_localeHelperService: LocaleHelperService, _dateNavigationService: DateNavigationService, _datepickerFocusService: DatepickerFocusService, _dateIOService: DateIOService, _elRef: ElementRef<HTMLElement>, commonStringsService: ClrCommonStringsService);
// Warning: (ae-forgotten-export) The symbol "CalendarModel" needs to be exported by the entry point index.d.ts
//
// (undocumented)
get calendar(): CalendarModel;
// Warning: (ae-forgotten-export) The symbol "CalendarViewModel" needs to be exported by the entry point index.d.ts
calendarViewModel: CalendarViewModel;
// (undocumented)
commonStringsService: ClrCommonStringsService;
// (undocumented)
get focusedDay(): DayModel;
// Warning: (ae-forgotten-export) The symbol "ClrDayOfWeek" needs to be exported by the entry point index.d.ts
get localeDays(): ReadonlyArray<ClrDayOfWeek>;
Expand All @@ -672,9 +674,11 @@ export class ClrCalendar implements OnDestroy {
// (undocumented)
get selectedDay(): DayModel;
// (undocumented)
showWeekNumbers: boolean;
// (undocumented)
get today(): DayModel;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<ClrCalendar, "clr-calendar", never, {}, {}, never, never, false, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<ClrCalendar, "clr-calendar", never, { "showWeekNumbers": "clrShowWeekNumbers"; }, {}, never, never, false, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<ClrCalendar, never>;
}
Expand Down Expand Up @@ -971,6 +975,8 @@ export interface ClrCommonStrings {
datepickerToggleChangeDateLabel: string;
// (undocumented)
datepickerToggleChooseDateLabel: string;
// (undocumented)
datepickerWeekNumber: string;
detailExpandableAriaLabel: string;
detailPaneEnd: string;
detailPaneStart: string;
Expand Down Expand Up @@ -2022,7 +2028,9 @@ export class ClrDateContainer extends ClrAbstractContainer implements AfterViewI
// (undocumented)
protected renderer: Renderer2;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<ClrDateContainer, "clr-date-container", never, { "clrPosition": "clrPosition"; }, {}, never, ["label", "[clrDate]", "clr-control-helper", "clr-control-error", "clr-control-success"], false, [{ directive: typeof i1_6.ClrPopoverHostDirective; inputs: {}; outputs: {}; }]>;
showWeekNumbers: boolean;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<ClrDateContainer, "clr-date-container", never, { "showWeekNumbers": "clrShowWeekNumbers"; "clrPosition": "clrPosition"; }, {}, never, ["label", "[clrDate]", "clr-control-helper", "clr-control-error", "clr-control-success"], false, [{ directive: typeof i1_6.ClrPopoverHostDirective; inputs: {}; outputs: {}; }]>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<ClrDateContainer, [null, null, null, null, null, null, null, null, null, null, { optional: true; }, null, null]>;
}
Expand Down Expand Up @@ -2114,7 +2122,9 @@ export class ClrDatepickerViewManager {
get isMonthView(): boolean;
get isYearView(): boolean;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<ClrDatepickerViewManager, "clr-datepicker-view-manager", never, {}, {}, never, never, false, never>;
showWeekNumbers: boolean;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<ClrDatepickerViewManager, "clr-datepicker-view-manager", never, { "showWeekNumbers": "clrShowWeekNumbers"; }, {}, never, never, false, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<ClrDatepickerViewManager, never>;
}
Expand Down Expand Up @@ -2150,9 +2160,11 @@ export class ClrDaypicker {
nextMonth(): void;
previousMonth(): void;
// (undocumented)
showWeekNumbers: boolean;
// (undocumented)
get yearAttrString(): string;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<ClrDaypicker, "clr-daypicker", never, {}, {}, never, never, false, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<ClrDaypicker, "clr-daypicker", never, { "showWeekNumbers": "clrShowWeekNumbers"; }, {}, never, never, false, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<ClrDaypicker, never>;
}
Expand Down
4 changes: 4 additions & 0 deletions projects/angular/src/forms/datepicker/STYLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
| --clr-calendar-active-focus-cell-background-color | Focused cell background color |
| --clr-calendar-container-height | Calendar container height |
| --clr-calendar-weekday-font-size | Calendar week day font size |
| --clr-calendar-week-number-font-size | Calendar week number font size |
| --clr-calendar-week-number-separator-color | Border color for the week number separator |
| --clr-calendar-picker-btn-font-size | Calendar picker button font size |
| --clr-calendar-picker-btn-font-weight | Calendar picker button font weight |

Expand All @@ -37,6 +39,8 @@
| day-btn | Day button inside calendar |
| weekday | Weekday table heading |
| weekdays | Weekdays table row wrapper |
| week-number | Calendar week number column heading |
| week-number-cell | Calendar week number column cell |
| month | Month buttons inside month picker |
| monthpicker | Main month picker element |
| monthpicker-trigger | Month picker button trigger |
Expand Down
24 changes: 22 additions & 2 deletions projects/angular/src/forms/datepicker/_datepicker.clarity.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@
box-shadow: tokens.$cds-alias-object-shadow-100;
overflow: hidden;
z-index: map.get(variables.$clr-layers, dropdown-menu);

&.show-week-numbers {
width: datepicker-variables.$clr-calendar-with-week-number-width;
}
}

.calendar-header {
Expand All @@ -98,7 +102,7 @@
}

.calendar-table {
// clr-calendar have dispaly: inline, preventing flex from having an effect.
// clr-calendar have display: inline, preventing flex from having an effect.
flex: 1 1 auto;

//Dimensions
Expand All @@ -123,7 +127,8 @@
flex: 0 0 datepicker-variables.$clr-calendar-click-target;
}

.weekday {
.weekday,
.week-number {
@include mixins.generate-typography-token(
'SECONDARY-13-SB-CPT',
(
Expand All @@ -132,6 +137,21 @@
);
}

.week-number-cell {
@include mixins.generate-typography-token(
'SECONDARY-13-RG-EXP',
(
font-size: datepicker-variables.$clr-calendar-week-number-font-size,
)
);
}

.week-number,
.week-number-cell {
border-right: tokens.$cds-alias-object-border-width-100 solid
datepicker-variables.$clr-calendar-week-number-separator-color;
}

.calendar-btn {
@include generate-calendar-button();
@include generate-calendar-focus-style();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@
--clr-calendar-btn-active-color: #{tokens.$cds-alias-object-interaction-color-active};
--clr-calendar-btn-active-color-bg: #{tokens.$cds-alias-object-interaction-background-active};

--clr-calendar-week-number-separator-color: #{tokens.$cds-alias-object-border-color-tint};

// Dimensions

// Typography
--clr-calendar-weekday-font-size: #{tokens.$cds-global-typography-font-size-3};
--clr-calendar-week-number-font-size: #{tokens.$cds-global-typography-font-size-2};
--clr-calendar-today-date-cell-font-weight: #{tokens.$cds-global-typography-font-weight-semibold};

--clr-calendar-picker-btn-font-size: #{tokens.$cds-global-typography-font-size-6};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ $clr-calendar-background-color: var(--clr-calendar-background-color) !default;
$clr-calendar-border-color: var(--clr-calendar-border-color) !default;
$clr-calendar-margin-top: #{tokens.$cds-global-space-4};
$clr-calendar-padding: #{tokens.$cds-global-space-7};
$clr-calendar-week-number-separator-color: var(--clr-calendar-week-number-separator-color) !default;

// (7 days in the week * 36px + 2 * 16px padding + 2px for border
$clr-calendar-width: calc(
calc(7 * #{tokens.$cds-global-space-11}) + calc(2 * #{tokens.$cds-global-space-7}) +
calc(2 * #{tokens.$cds-alias-object-border-width-100})
);

// 1 extra square for the week number
$clr-calendar-with-week-number-width: calc($clr-calendar-width + #{tokens.$cds-global-space-11});

//(8 = 6 date rows + 1 row for day heading + 1 row for calendar switches and month/year pickers) + 2 * 16px padding + 2px for border
$clr-calendar-height: calc(
calc(8 * #{tokens.$cds-global-space-11}) + calc(2 * #{tokens.$cds-global-space-7}) +
Expand Down Expand Up @@ -48,6 +52,7 @@ $clr-calendar-active-focus-cell-background-color: var(--clr-calendar-active-focu
$clr-calendar-active-cell-color: var(--clr-calendar-active-cell-color) !default;

$clr-calendar-weekday-font-size: var(--clr-calendar-weekday-font-size);
$clr-calendar-week-number-font-size: var(--clr-calendar-week-number-font-size);

$clr-switcher-width: calc($clr-calendar-click-target * 3);

Expand Down
8 changes: 8 additions & 0 deletions projects/angular/src/forms/datepicker/calendar.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
<table class="calendar-table" role="presentation">
<tr class="calendar-row weekdays">
<th
*ngIf="showWeekNumbers"
[attr.aria-label]="commonStringsService.keys.datepickerWeekNumber"
class="calendar-cell week-number"
>
#
</th>
<th *ngFor="let day of localeDays" class="calendar-cell weekday">
<span [attr.aria-label]="day.day">{{day.narrow}}</span>
</th>
</tr>
<tr class="calendar-row" *ngFor="let row of calendarViewModel.calendarView">
<td class="calendar-cell week-number-cell" *ngIf="showWeekNumbers">{{row[0].dayModel.toDate() | date: 'w'}}</td>
<td *ngFor="let dayView of row" class="calendar-cell">
<clr-day [clrDayView]="dayView" aria-hidden="true"></clr-day>
</td>
Expand Down
34 changes: 32 additions & 2 deletions projects/angular/src/forms/datepicker/calendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Component } from '@angular/core';

import { TestContext } from '../../data/datagrid/helpers.spec';
import { Keys } from '../../utils/enums/keys.enum';
import { ClrCommonStringsService } from '../../utils/i18n/common-strings.service';
import { ClrPopoverToggleService } from '../../utils/popover/providers/popover-toggle.service';
import { ClrCalendar } from './calendar';
import { DayModel } from './model/day.model';
Expand Down Expand Up @@ -38,6 +39,7 @@ export default function () {
LocaleHelperService,
DatepickerFocusService,
DateFormControlService,
ClrCommonStringsService,
]);
});

Expand All @@ -51,6 +53,32 @@ export default function () {
const days: HTMLElement[] = context.clarityElement.querySelectorAll('.weekdays .calendar-cell');
expect(days.length).toBe(7);
});

it('does not render week number header by default', () => {
const weekNumberHeader: HTMLElement = context.clarityElement.querySelector('.week-number');
expect(weekNumberHeader).toBeNull();
});

it('does not render week numbers by default', () => {
const weekNumbers: HTMLElement[] = context.clarityElement.querySelectorAll('.week-number-cell');
expect(weekNumbers.length).toBe(0);
});

it('renders week number header when enabled', () => {
context.testComponent.showWeekNumbers = true;
context.detectChanges();

const weekNumberHeader: HTMLElement = context.clarityElement.querySelector('.week-number');
expect(weekNumberHeader).not.toBeNull();
});

it('renders week numbers when enabled', () => {
context.testComponent.showWeekNumbers = true;
context.detectChanges();

const weekNumbers: HTMLElement[] = context.clarityElement.querySelectorAll('.week-number-cell');
expect(weekNumbers.length).toBe(6);
});
});

describe('Typescript API', () => {
Expand Down Expand Up @@ -165,6 +193,8 @@ export default function () {
}

@Component({
template: `<clr-calendar></clr-calendar>`,
template: `<clr-calendar [clrShowWeekNumbers]="showWeekNumbers"></clr-calendar>`,
})
class TestComponent {}
class TestComponent {
showWeekNumbers = false;
}
8 changes: 6 additions & 2 deletions projects/angular/src/forms/datepicker/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { Component, ElementRef, HostListener, OnDestroy } from '@angular/core';
import { Component, ElementRef, HostListener, Input, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

import { Keys } from '../../utils/enums/keys.enum';
import { normalizeKey } from '../../utils/focus/key-focus/util';
import { ClrCommonStringsService } from '../../utils/i18n/common-strings.service';
import { ClrDayOfWeek } from './interfaces/day-of-week.interface';
import { CalendarViewModel } from './model/calendar-view.model';
import { CalendarModel } from './model/calendar.model';
Expand All @@ -25,6 +26,8 @@ import { NO_OF_DAYS_IN_A_WEEK } from './utils/constants';
templateUrl: './calendar.html',
})
export class ClrCalendar implements OnDestroy {
@Input('clrShowWeekNumbers') showWeekNumbers = false;

/**
* Calendar View Model to generate the Calendar.
*/
Expand All @@ -37,7 +40,8 @@ export class ClrCalendar implements OnDestroy {
private _dateNavigationService: DateNavigationService,
private _datepickerFocusService: DatepickerFocusService,
private _dateIOService: DateIOService,
private _elRef: ElementRef<HTMLElement>
private _elRef: ElementRef<HTMLElement>,
public commonStringsService: ClrCommonStringsService
) {
this.generateCalendarView();
this.initializeSubscriptions();
Expand Down
3 changes: 3 additions & 0 deletions projects/angular/src/forms/datepicker/date-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { ViewManagerService } from './providers/view-manager.service';
</button>
<clr-datepicker-view-manager
*clrPopoverContent="open; at: popoverPosition; outsideClickToClose: true; scrollToClose: true"
[clrShowWeekNumbers]="showWeekNumbers"
cdkTrapFocus
></clr-datepicker-view-manager>
</div>
Expand Down Expand Up @@ -94,6 +95,8 @@ import { ViewManagerService } from './providers/view-manager.service';
},
})
export class ClrDateContainer extends ClrAbstractContainer implements AfterViewInit {
@Input('clrShowWeekNumbers') showWeekNumbers = false;

focus = false;

private toggleButton: ElementRef<HTMLButtonElement>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@

<clr-monthpicker *ngIf="isMonthView"></clr-monthpicker>
<clr-yearpicker *ngIf="isYearView"></clr-yearpicker>
<clr-daypicker *ngIf="isDayView"></clr-daypicker>
<clr-daypicker *ngIf="isDayView" [clrShowWeekNumbers]="showWeekNumbers"></clr-daypicker>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { Component } from '@angular/core';
import { Component, Input } from '@angular/core';

import { ClrCommonStringsService } from '../../utils/i18n/common-strings.service';
import { DatepickerFocusService } from './providers/datepicker-focus.service';
Expand All @@ -19,10 +19,13 @@ import { ViewManagerService } from './providers/view-manager.service';
'[class.datepicker]': 'true',
'[attr.aria-modal]': 'true',
'[attr.aria-label]': 'commonStrings.keys.datepickerDialogLabel',
'[class.show-week-numbers]': 'showWeekNumbers && isDayView',
role: 'dialog',
},
})
export class ClrDatepickerViewManager {
@Input('clrShowWeekNumbers') showWeekNumbers = false;

constructor(public commonStrings: ClrCommonStringsService, private viewManagerService: ViewManagerService) {}

/**
Expand Down
2 changes: 1 addition & 1 deletion projects/angular/src/forms/datepicker/daypicker.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@
</button>
</div>
</div>
<clr-calendar></clr-calendar>
<clr-calendar [clrShowWeekNumbers]="showWeekNumbers"></clr-calendar>
<div class="clr-sr-only">{{commonStrings.keys.modalContentEnd}}</div>
4 changes: 3 additions & 1 deletion projects/angular/src/forms/datepicker/daypicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { Component } from '@angular/core';
import { Component, Input } from '@angular/core';

import { ClrCommonStringsService } from '../../utils/i18n/common-strings.service';
import { DateNavigationService } from './providers/date-navigation.service';
Expand All @@ -18,6 +18,8 @@ import { ViewManagerService } from './providers/view-manager.service';
host: { '[class.daypicker]': 'true', role: 'application' },
})
export class ClrDaypicker {
@Input('clrShowWeekNumbers') showWeekNumbers = false;

constructor(
private _viewManagerService: ViewManagerService,
private _dateNavigationService: DateNavigationService,
Expand Down
1 change: 1 addition & 0 deletions projects/angular/src/utils/i18n/common-strings.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export const commonStringsDefault: ClrCommonStrings = {
datepickerSelectMonthText: 'Select month, the current month is {CALENDAR_MONTH}',
datepickerSelectYearText: 'Select year, the current year is {CALENDAR_YEAR}',
datepickerSelectedLabel: '{FULL_DATE} - Selected',
datepickerWeekNumber: 'Week number',
// Stack View
stackViewChanged: 'Value changed.',
// Responsive Nav
Expand Down
Loading
Loading