From 18735a7ae56a0f48cc9cdf5aa53b0345e6bbe78c Mon Sep 17 00:00:00 2001 From: Marc Stammerjohann <8985933+marcjulian@users.noreply.github.com> Date: Wed, 29 Jan 2025 11:03:30 +0100 Subject: [PATCH] feat(date-picker): define formatDate as global config --- .../date-picker--config.example.ts | 59 +++++++++++++++++++ .../date-picker--format.example.ts | 22 +++++-- .../(date-picker)/date-picker.page.ts | 39 +++++++++++- libs/ui/date-picker/helm/src/index.ts | 2 + .../helm/src/lib/hlm-date-format.token.ts | 25 ++++++++ .../helm/src/lib/hlm-date-picker.component.ts | 15 ++--- 6 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--config.example.ts create mode 100644 libs/ui/date-picker/helm/src/lib/hlm-date-format.token.ts diff --git a/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--config.example.ts b/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--config.example.ts new file mode 100644 index 000000000..856a639e6 --- /dev/null +++ b/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--config.example.ts @@ -0,0 +1,59 @@ +import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { HlmDatePickerComponent, provideHlmDatePickerConfig } from '@spartan-ng/ui-date-picker-helm'; +import { DateTime } from 'luxon'; + +@Component({ + selector: 'spartan-date-picker-config', + standalone: true, + imports: [HlmDatePickerComponent, FormsModule], + template: ` + + Pick a date + + `, + providers: [ + provideHlmDatePickerConfig({ formatDate: (date: Date) => DateTime.fromJSDate(date).toFormat('dd.MM.yyyy') }), + ], + host: { + class: 'preview flex min-h-[350px] w-full justify-center p-10 items-center', + }, +}) +export class DatePickerConfigExampleComponent { + /** The minimum date */ + public minDate = new Date(2023, 0, 1); + + /** The maximum date */ + public maxDate = new Date(2030, 11, 31); +} + +export const datePickerConfigCode = ` +import { Component } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { HlmDatePickerComponent, provideHlmDatePickerConfig } from '@spartan-ng/ui-date-picker-helm'; +import { DateTime } from 'luxon'; + +@Component({ + selector: 'spartan-date-picker-config', + standalone: true, + imports: [HlmDatePickerComponent, FormsModule], + template: \` + + Pick a date + + \`, + providers: [ + provideHlmDatePickerConfig({ formatDate: (date: Date) => DateTime.fromJSDate(date).toFormat('dd.MM.yyyy') }), + ], + host: { + class: 'preview flex min-h-[350px] w-full justify-center p-10 items-center', + }, +}) +export class DatePickerConfigExampleComponent { + /** The minimum date */ + public minDate = new Date(2023, 0, 1); + + /** The maximum date */ + public maxDate = new Date(2030, 11, 31); +} +`; diff --git a/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--format.example.ts b/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--format.example.ts index aa57d4b23..c5e4ea647 100644 --- a/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--format.example.ts +++ b/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker--format.example.ts @@ -1,6 +1,6 @@ import { Component } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { HlmDatePickerComponent } from '@spartan-ng/ui-date-picker-helm'; +import { HlmDatePickerComponent, provideHlmDatePickerConfig } from '@spartan-ng/ui-date-picker-helm'; import { DateTime } from 'luxon'; @Component({ @@ -8,10 +8,14 @@ import { DateTime } from 'luxon'; standalone: true, imports: [HlmDatePickerComponent, FormsModule], template: ` - + Pick a date `, + providers: [ + // Global formatDate config + provideHlmDatePickerConfig({ formatDate: (date: Date) => DateTime.fromJSDate(date).toFormat('dd.MM.yyyy') }), + ], host: { class: 'preview flex min-h-[350px] w-full justify-center p-10 items-center', }, @@ -23,13 +27,14 @@ export class DatePickerFormatExampleComponent { /** The maximum date */ public maxDate = new Date(2030, 11, 31); - public dateFormat = (date: Date) => DateTime.fromJSDate(date).toFormat('dd.MM.yyyy'); + /** Overrides global formatDate */ + public formatDate = (date: Date) => DateTime.fromJSDate(date).toFormat('MMMM dd, yyyy'); } export const datePickerFormatCode = ` import { Component } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { HlmDatePickerComponent } from '@spartan-ng/ui-date-picker-helm'; +import { HlmDatePickerComponent, provideHlmDatePickerConfig } from '@spartan-ng/ui-date-picker-helm'; import { DateTime } from 'luxon'; @Component({ @@ -37,10 +42,14 @@ import { DateTime } from 'luxon'; standalone: true, imports: [HlmDatePickerComponent, FormsModule], template: \` - + Pick a date \`, + providers: [ + // Global formatDate config + provideHlmDatePickerConfig({ formatDate: (date: Date) => DateTime.fromJSDate(date).toFormat('dd.MM.yyyy') }), + ], host: { class: 'preview flex min-h-[350px] w-full justify-center p-10 items-center', }, @@ -52,6 +61,7 @@ export class DatePickerFormatExampleComponent { /** The maximum date */ public maxDate = new Date(2030, 11, 31); - public dateFormat = (date: Date) => DateTime.fromJSDate(date).toFormat('dd.MM.yyyy'); + /** Overrides global formatDate */ + public formatDate = (date: Date) => DateTime.fromJSDate(date).toFormat('MMMM dd, yyyy'); } `; diff --git a/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker.page.ts b/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker.page.ts index 39afc068b..733691c8c 100644 --- a/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker.page.ts +++ b/apps/app/src/app/pages/(components)/components/(date-picker)/date-picker.page.ts @@ -1,6 +1,6 @@ import type { RouteMeta } from '@analogjs/router'; import { Component } from '@angular/core'; -import { hlmH4 } from '@spartan-ng/ui-typography-helm'; +import { hlmCode, hlmH4, hlmP } from '@spartan-ng/ui-typography-helm'; import { CodeComponent } from '../../../../shared/code/code.component'; import { PageBottomNavLinkComponent } from '../../../../shared/layout/page-bottom-nav/page-bottom-nav-link.component'; import { PageBottomNavComponent } from '../../../../shared/layout/page-bottom-nav/page-bottom-nav.component'; @@ -10,6 +10,7 @@ import { SectionSubHeadingComponent } from '../../../../shared/layout/section-su import { TabsCliComponent } from '../../../../shared/layout/tabs-cli.component'; import { TabsComponent } from '../../../../shared/layout/tabs.component'; import { metaWith } from '../../../../shared/meta/meta.util'; +import { datePickerConfigCode, DatePickerConfigExampleComponent } from './date-picker--config.example'; import { datePickerFormCode, DatePickerFormExampleComponent } from './date-picker--form.example'; import { datePickerFormatCode, DatePickerFormatExampleComponent } from './date-picker--format.example'; import { codeSkeleton, DatePickerPreviewComponent, defaultCode, defaultImports } from './date-picker.preview'; @@ -33,6 +34,7 @@ export const routeMeta: RouteMeta = { PageBottomNavComponent, PageBottomNavLinkComponent, PageNavComponent, + DatePickerConfigExampleComponent, DatePickerFormatExampleComponent, DatePickerFormExampleComponent, ], @@ -61,14 +63,48 @@ export const routeMeta: RouteMeta = { Examples +

Custom Configs

+ +

+ Use + provideHlmDatePickerConfig + to provide custom configs for the date picker component throughout the application. +

+ +

+ formatDate: (date: T) => string; + defines the default format how the date should be displayed in the UI. +

+ + +
+ +
+ +
+

Format Date

+ +

+ Use + formatDate + input to override the global date format for the date picker component. +

+

Form

+

+ Sync the date to a form by adding + formControlName + to + hlm-date-picker + . +

@@ -88,6 +124,7 @@ export default class CardPageComponent { protected readonly defaultCode = defaultCode; protected readonly defaultImports = defaultImports; protected readonly codeSkeleton = codeSkeleton; + protected readonly datePickerConfigCode = datePickerConfigCode; protected readonly datePickerFormCode = datePickerFormCode; protected readonly datePickerFormatCode = datePickerFormatCode; } diff --git a/libs/ui/date-picker/helm/src/index.ts b/libs/ui/date-picker/helm/src/index.ts index 889a46d6d..2ec89c3be 100644 --- a/libs/ui/date-picker/helm/src/index.ts +++ b/libs/ui/date-picker/helm/src/index.ts @@ -1,6 +1,8 @@ import { NgModule } from '@angular/core'; import { HlmDatePickerComponent } from './lib/hlm-date-picker.component'; +export * from './lib/hlm-date-format.token'; + export * from './lib/hlm-date-picker.component'; @NgModule({ diff --git a/libs/ui/date-picker/helm/src/lib/hlm-date-format.token.ts b/libs/ui/date-picker/helm/src/lib/hlm-date-format.token.ts new file mode 100644 index 000000000..a0f992f35 --- /dev/null +++ b/libs/ui/date-picker/helm/src/lib/hlm-date-format.token.ts @@ -0,0 +1,25 @@ +import { inject, InjectionToken, ValueProvider } from '@angular/core'; + +export interface HlmDatePickerConfig { + /** + * Defines how the date should be displayed in the UI. + * + * @param date + * @returns formatted date + */ + formatDate: (date: T) => string; +} + +const defaultConfig: HlmDatePickerConfig = { + formatDate: (date) => (date instanceof Date ? date.toDateString() : `${date}`), +}; + +const HlmDatePickerConfigToken = new InjectionToken>('HlmDatePickerConfig'); + +export function provideHlmDatePickerConfig(config?: HlmDatePickerConfig): ValueProvider { + return { provide: HlmDatePickerConfigToken, useValue: { ...defaultConfig, ...config } }; +} + +export function injectHlmDatePickerConfig(): HlmDatePickerConfig { + return inject(HlmDatePickerConfigToken, { optional: true }) ?? (defaultConfig as HlmDatePickerConfig); +} diff --git a/libs/ui/date-picker/helm/src/lib/hlm-date-picker.component.ts b/libs/ui/date-picker/helm/src/lib/hlm-date-picker.component.ts index 151bee597..5fc848c9e 100644 --- a/libs/ui/date-picker/helm/src/lib/hlm-date-picker.component.ts +++ b/libs/ui/date-picker/helm/src/lib/hlm-date-picker.component.ts @@ -10,6 +10,7 @@ import { HlmCalendarComponent } from '@spartan-ng/ui-calendar-helm'; import { HlmIconDirective } from '@spartan-ng/ui-icon-helm'; import { HlmPopoverContentDirective } from '@spartan-ng/ui-popover-helm'; import type { ClassValue } from 'clsx'; +import { injectHlmDatePickerConfig } from './hlm-date-format.token'; export const HLM_DATE_PICKER_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, @@ -58,6 +59,8 @@ export const HLM_DATE_PICKER_VALUE_ACCESSOR = { }, }) export class HlmDatePickerComponent { + private readonly _config = injectHlmDatePickerConfig(); + public readonly userClass = input('', { alias: 'class' }); protected readonly _computedClass = computed(() => hlm( @@ -88,18 +91,12 @@ export class HlmDatePickerComponent { disabled: signal(this.disabled()), })); - public readonly dateFormat = input<(date: T) => string>((date) => - date instanceof Date ? date.toDateString() : `${date}`, - ); + /** Defines how the date should be displayed in the UI. */ + public readonly formatDate = input<(date: T) => string>(this._config.formatDate); protected readonly formattedDate = computed(() => { const date = this.date(); - - if (!date) { - return undefined; - } - - return this.dateFormat()(date); + return date ? this.formatDate()(date) : undefined; }); public readonly changed = output();