Skip to content

Commit

Permalink
feat(kit): Time & DateTime support AM / PM formats (#1708)
Browse files Browse the repository at this point in the history
  • Loading branch information
nsbarsukov authored Oct 9, 2024
1 parent 68d19fc commit 98ce35e
Show file tree
Hide file tree
Showing 44 changed files with 1,380 additions and 122 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module.exports = {
rules: {
'react/display-name': 'off',
'react/react-in-jsx-scope': 'off',
'no-irregular-whitespace': 'off',
},
},
],
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('DateTime | Separator', () => {
it('rejects dot as separator', () => {
cy.get('@input')
.type('1412.')
.should('have.value', '14/12')
.should('have.value', '14/12/')
.type('2000')
.should('have.value', '14/12/2000');
});
Expand Down Expand Up @@ -57,7 +57,7 @@ describe('DateTime | Separator', () => {
.type('14')
.should('have.value', '14')
.type('12.')
.should('have.value', '14-12');
.should('have.value', '14-12-');
});
});
});
422 changes: 422 additions & 0 deletions projects/demo-integrations/src/tests/kit/time/time-meridiem.cy.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ describe('Time', () => {

describe('max hours 11', () => {
beforeEach(() => {
cy.visit(`/${DemoPath.Time}/API?mode=HH&timeSegmentMaxValues$=1`);
cy.visit(`/${DemoPath.Time}/API?mode=HH&timeSegmentMaxValues$=2`);
cy.get('#demo-content input')
.should('be.visible')
.first()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {DemoPath} from '@demo/constants';

import {range} from '../../utils';

describe('Time | [timeSegmentMaxValues] property', () => {
describe('{hours: 5, minutes: 5, seconds: 5, milliseconds: 5}', () => {
beforeEach(() => {
cy.visit(`/${DemoPath.Time}/API?mode=HH:MM&timeSegmentMaxValues$=2`);
cy.visit(`/${DemoPath.Time}/API?mode=HH:MM&timeSegmentMaxValues$=3`);
cy.get('#demo-content input')
.should('be.visible')
.first()
Expand Down Expand Up @@ -152,7 +154,3 @@ describe('Time | [timeSegmentMaxValues] property', () => {
});
});
});

function range(from: number, to: number): number[] {
return new Array(to - from + 1).fill(null).map((_, i) => from + i);
}
7 changes: 7 additions & 0 deletions projects/demo-integrations/src/tests/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function range(from: number, to: number): number[] {
return new Array(to - from + 1).fill(null).map((_, i) => from + i);
}

export function withCaretLabel(value: string, caretIndex: number): string {
return `${value.slice(0, caretIndex)}|${value.slice(caretIndex)}`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export default class SupportedInputTypesDocPageComponent {
};

protected getInput(type: HTMLInputElement['type']): string {
// eslint-disable-next-line no-irregular-whitespace
return `<input type="${type}" />`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {DateTimeMaskDocExample1} from './examples/1-date-time-localization/compo
import {DateTimeMaskDocExample2} from './examples/2-date-time-separator/component';
import {DateTimeMaskDocExample3} from './examples/3-min-max/component';
import {DateTimeMaskDocExample4} from './examples/4-time-step/component';
import {DateTimeMaskDocExample5} from './examples/5-am-pm/component';

type GeneratorOptions = Required<
NonNullable<Parameters<typeof maskitoDateTimeOptionsGenerator>[0]>
Expand All @@ -28,6 +29,7 @@ type GeneratorOptions = Required<
DateTimeMaskDocExample2,
DateTimeMaskDocExample3,
DateTimeMaskDocExample4,
DateTimeMaskDocExample5,
MaskitoDirective,
ReactiveFormsModule,
TuiAddonDoc,
Expand Down Expand Up @@ -62,6 +64,10 @@ export default class DateTimeMaskDocComponent implements GeneratorOptions {
),
};

protected readonly amPmExample: Record<string, TuiRawLoaderContent> = {
[DocExamplePrimaryTab.MaskitoOptions]: import('./examples/5-am-pm/mask.ts?raw'),
};

protected apiPageControl = new FormControl('');

protected readonly dateModeOptions = [
Expand All @@ -72,8 +78,11 @@ export default class DateTimeMaskDocComponent implements GeneratorOptions {

protected readonly timeModeOptions = [
'HH:MM',
'HH:MM AA',
'HH:MM:SS',
'HH:MM:SS AA',
'HH:MM:SS.MSS',
'HH:MM:SS.MSS AA',
] as const satisfies readonly MaskitoTimeMode[];

protected readonly minMaxOptions = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,22 @@
</ng-template>
<date-time-mask-doc-example-4 />
</tui-doc-example>

<tui-doc-example
id="am-pm"
heading="AM / PM"
[content]="amPmExample"
[description]="amPmDescription"
>
<ng-template #amPmDescription>
Any
<code>timeMode</code>
ending with
<code>AA</code>
is 12-hour time format with meridiem part.
</ng-template>
<date-time-mask-doc-example-5 />
</tui-doc-example>
</ng-template>

<ng-template pageTab>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {MaskitoDirective} from '@maskito/angular';
import {TuiInputModule, TuiTextfieldControllerModule} from '@taiga-ui/legacy';

import mask from './mask';

@Component({
standalone: true,
selector: 'date-time-mask-doc-example-5',
imports: [
FormsModule,
MaskitoDirective,
TuiInputModule,
TuiTextfieldControllerModule,
],
template: `
<tui-input
tuiTextfieldCustomContent="@tui.calendar"
[style.max-width.rem]="30"
[tuiTextfieldFiller]="filler"
[(ngModel)]="value"
>
With 12-hour time format
<input
inputmode="decimal"
tuiTextfieldLegacy
[maskito]="mask"
/>
</tui-input>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DateTimeMaskDocExample5 {
protected value = '20/09/2020, 03:30 PM';
protected readonly filler = 'mm/dd/yyyy, hh:mm aa';
protected readonly mask = mask;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {maskitoDateTimeOptionsGenerator} from '@maskito/kit';

export default maskitoDateTimeOptionsGenerator({
dateMode: 'dd/mm/yyyy',
timeMode: 'HH:MM AA',
dateSeparator: '/',
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import mask from './mask';
[style.max-width.rem]="20"
[(ngModel)]="value"
>
HH:MM:SS
Enter 24-hour time format
<input
inputmode="decimal"
tuiTextfieldLegacy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import mask from './mask';
template: `
<tui-input
tuiTextfieldCustomContent="@tui.clock"
tuiTextfieldFiller="hh:mm"
tuiTextfieldFiller="HH:MM AA"
[style.max-width.rem]="20"
[tuiTextfieldLabelOutside]="true"
[(ngModel)]="value"
>
Enter 12-hour time format
<input
inputmode="decimal"
tuiTextfieldLegacy
Expand All @@ -32,6 +32,6 @@ import mask from './mask';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TimeMaskDocExample2 {
protected value = '11:59';
protected readonly mask = mask;
protected value = '03:30 PM';
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@ import {maskitoUpdateElement} from '@maskito/core';
import {maskitoEventHandler, maskitoTimeOptionsGenerator} from '@maskito/kit';

const timeOptions = maskitoTimeOptionsGenerator({
mode: 'HH:MM',
timeSegmentMaxValues: {hours: 12},
mode: 'HH:MM AA',
});

export default {
...timeOptions,
plugins: [
...timeOptions.plugins,
maskitoEventHandler('blur', (element) => {
const [hours = '', minutes = ''] = element.value.split(':');

maskitoUpdateElement(
element,
[hours, minutes].map((segment) => segment.padEnd(2, '0')).join(':'),
);
if (element.value.length >= 'HH:MM'.length && !element.value.endsWith('M')) {
maskitoUpdateElement(element, `${element.value} AM`);
}
}),
],
} satisfies MaskitoOptions;
21 changes: 19 additions & 2 deletions projects/demo/src/pages/kit/time/examples/3-step/mask.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import {maskitoTimeOptionsGenerator} from '@maskito/kit';
import type {MaskitoOptions} from '@maskito/core';
import {maskitoUpdateElement} from '@maskito/core';
import {maskitoEventHandler, maskitoTimeOptionsGenerator} from '@maskito/kit';

export default maskitoTimeOptionsGenerator({
const timeOptions = maskitoTimeOptionsGenerator({
mode: 'HH:MM:SS',
step: 1,
});

export default {
...timeOptions,
plugins: [
...timeOptions.plugins,
maskitoEventHandler('blur', (element) => {
const [hh = '', mm = '', ss = ''] = element.value.split(':');

maskitoUpdateElement(
element,
[hh, mm, ss].map((segment) => segment.padEnd(2, '0')).join(':'),
);
}),
],
} satisfies MaskitoOptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {MaskitoDirective} from '@maskito/angular';
import {TuiTextfield} from '@taiga-ui/core';
import {TuiSegmented} from '@taiga-ui/kit';

import mask from './mask';

@Component({
standalone: true,
selector: 'time-mask-doc-example-4',
imports: [FormsModule, MaskitoDirective, TuiSegmented, TuiTextfield],
template: `
<tui-textfield
filler="HH:MM"
[style.max-width.rem]="20"
[tuiTextfieldCleaner]="false"
>
<input
inputmode="decimal"
tuiTextfield
[maskito]="mask"
[(ngModel)]="value"
/>
<tui-segmented>
<button type="button">AM</button>
<button type="button">PM</button>
</tui-segmented>
</tui-textfield>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TimeMaskDocExample4 {
protected value = '03:30';
protected readonly mask = mask;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {maskitoTimeOptionsGenerator} from '@maskito/kit';

export default maskitoTimeOptionsGenerator({
mode: 'HH:MM',
timeSegmentMaxValues: {hours: 12},
timeSegmentMinValues: {hours: 1},
});
Loading

0 comments on commit 98ce35e

Please sign in to comment.