Skip to content
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
34 changes: 34 additions & 0 deletions .changeset/lucky-gifts-tie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
"@patternfly/elements": major
---

Added `<pf-v6-timestamp>` replacing `<pf-v5-timestamp>`. Timestamp now follows
PatternFly v6 design specs.

```html
<pf-v6-timestamp date="Mon Jan 2 15:04:05 EST 2006"
date-format="full"
time-format="long">
</pf-v6-timestamp>
```

**Breaking Changes from v5**

- `<pf-v5-timestamp>` renamed to `<pf-v6-timestamp>`
- `utc` boolean attribute replaced with `time-zone` string attribute accepting
any IANA timezone identifier (e.g. `time-zone="UTC"`,
`time-zone="America/New_York"`)
- `hour-12` boolean attribute replaced with `hour-cycle` enum attribute
accepting Intl values: `h11`, `h12`, `h23`, `h24`
- `help-text` attribute removed; tooltip styling is a composition pattern
using `<pf-v5-tooltip>` wrapping
- `date` getter now returns ISO 8601 string instead of locale-formatted string
- `display-suffix` no longer auto-set to "UTC" when using UTC timezone; set
`display-suffix="UTC"` explicitly if needed

**New features**

- `time-zone` attribute for any IANA timezone, not just UTC
- `hour-cycle` attribute for precise hour format control
- Default slot for custom display content
- v6 design tokens
81 changes: 36 additions & 45 deletions core/pfe-core/controllers/timestamp-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,49 @@ import type { ReactiveController, ReactiveControllerHost } from 'lit';

export type DateTimeFormat = 'full' | 'long' | 'medium' | 'short';

export type HourCycle = 'h11' | 'h12' | 'h23' | 'h24';

export interface TimestampOptions {
dateFormat?: DateTimeFormat;
timeFormat?: DateTimeFormat;
customFormat?: Intl.DateTimeFormatOptions;
displaySuffix: string;
locale: Intl.LocalesArgument;
relative: boolean;
utc: boolean;
hour12: boolean;
displaySuffix?: string;
locale?: Intl.LocalesArgument;
relative?: boolean;
timeZone?: string;
hourCycle?: HourCycle;
}

const defaults = {
dateFormat: undefined,
timeFormat: undefined,
customFormat: undefined,
displaySuffix: '',
locale: undefined,
relative: false,
utc: false,
hour12: false,
} as const;
const optionKeys: Record<keyof TimestampOptions, true> = {
dateFormat: true,
timeFormat: true,
customFormat: true,
displaySuffix: true,
locale: true,
relative: true,
timeZone: true,
hourCycle: true,
};

export class TimestampController implements ReactiveController {
static #isTimestampOptionKey(prop: PropertyKey): prop is keyof TimestampOptions {
return prop in defaults;
return prop in optionKeys;
}

// When Temporal reaches baseline, replace with Temporal.Instant;
// timeZone and hourCycle options already align with Temporal's API
#date = new Date();

#options: TimestampOptions = {} as TimestampOptions;
#options: Partial<TimestampOptions> = {};

#host: ReactiveControllerHost;

get localeString(): string {
return this.#date.toLocaleString(this.#options.locale);
}

get date(): Date {
return this.#date;
}

set date(string) {
this.#date = new Date(string);
set date(value: string | Date) {
this.#date = new Date(value);
}

get isoString(): string {
Expand All @@ -54,38 +54,29 @@ export class TimestampController implements ReactiveController {
get time(): string {
if (this.#options.relative) {
return this.#getTimeRelative();
} else {
let { displaySuffix } = this.#options;
const { locale } = this.#options;
if (this.#options.utc) {
displaySuffix ||= 'UTC';
}
const localeString = this.#date.toLocaleString(locale, this.#options.customFormat ?? {
hour12: this.#options.hour12,
timeStyle: this.#options.timeFormat,
dateStyle: this.#options.dateFormat,
...this.#options.utc && { timeZone: 'UTC' },
});

return `${localeString} ${displaySuffix ?? ''}`.trim();
}
const { displaySuffix, locale, timeZone, hourCycle } = this.#options;
const localeString = this.#date.toLocaleString(locale, this.#options.customFormat ?? {
hourCycle,
timeStyle: this.#options.timeFormat,
dateStyle: this.#options.dateFormat,
timeZone,
});
return `${localeString}${displaySuffix ? ` ${displaySuffix}` : ''}`;
}

constructor(host: ReactiveControllerHost, options?: Partial<TimestampOptions>) {
this.#host = host;
host.addController(this);
for (const [name, value] of Object.entries(this.#options)) {
// @ts-expect-error: seems typescript compiler isn't up to the task here
this.#options[name] = options?.[name] ?? value;
if (options) {
Object.assign(this.#options, options);
}
}

hostConnected?(): void;

/**
* Based off of Github Relative Time
* https://github.com/github/time-elements/blob/master/src/relative-time.js
*/
// When Temporal reaches baseline, replace Intl.RelativeTimeFormat usage
// with Temporal.Duration and Temporal.Now.instant() for precise unit selection
#getTimeRelative() {
const date = this.#date;
const { locale } = this.#options;
Expand Down Expand Up @@ -129,7 +120,7 @@ export class TimestampController implements ReactiveController {

set(prop: PropertyKey, value: unknown): void {
if (TimestampController.#isTimestampOptionKey(prop)) {
// @ts-expect-error: seems typescript compiler isn't up to the task here
// @ts-expect-error: dynamic property assignment from element willUpdate
this.#options[prop] = value;
this.#host.requestUpdate();
}
Expand Down
2 changes: 1 addition & 1 deletion docs/main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import '@patternfly/elements/pf-v5-tabs/pf-v5-tabs.js';
import '@patternfly/elements/pf-v5-text-area/pf-v5-text-area.js';
import '@patternfly/elements/pf-v5-text-input/pf-v5-text-input.js';
import '@patternfly/elements/pf-v5-tile/pf-v5-tile.js';
import '@patternfly/elements/pf-v5-timestamp/pf-v5-timestamp.js';
import '@patternfly/elements/pf-v6-timestamp/pf-v6-timestamp.js';
import '@patternfly/elements/pf-v5-tooltip/pf-v5-tooltip.js';

// if `/v2/` path load icons from static directory
Expand Down
64 changes: 0 additions & 64 deletions elements/pf-v5-timestamp/README.md

This file was deleted.

17 changes: 0 additions & 17 deletions elements/pf-v5-timestamp/demo/basic-formats.html

This file was deleted.

23 changes: 0 additions & 23 deletions elements/pf-v5-timestamp/demo/custom-format.html

This file was deleted.

25 changes: 0 additions & 25 deletions elements/pf-v5-timestamp/demo/custom-tooltip.html

This file was deleted.

13 changes: 0 additions & 13 deletions elements/pf-v5-timestamp/demo/index.html

This file was deleted.

25 changes: 0 additions & 25 deletions elements/pf-v5-timestamp/demo/relative-format-with-tooltip.html

This file was deleted.

18 changes: 0 additions & 18 deletions elements/pf-v5-timestamp/demo/relative-format.html

This file was deleted.

25 changes: 0 additions & 25 deletions elements/pf-v5-timestamp/demo/tooltip.html

This file was deleted.

Loading
Loading