Add sl-format-date component

pull/282/head
Cory LaViska 2020-11-25 16:18:07 -05:00
rodzic 511fd2ac7e
commit b7f70fcf8a
4 zmienionych plików z 261 dodań i 0 usunięć

Wyświetl plik

@ -50,6 +50,7 @@
- Utility Components
- [Animation](/components/animation.md)
- [Format Bytes](/components/format-bytes.md)
- [Format Date](/components/format-date.md)
- [Format Number](/components/format-number.md)
- [Include](/components/include.md)
- [Relative Time](/components/relative-time.md)

Wyświetl plik

@ -0,0 +1,64 @@
# Format Date
[component-header:sl-format-date]
Formats a date/time using the specified locale and options.
Localization is handled by the browser's [`Intl.DateTimeFormat` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat). No language packs are required.
```html preview
<!-- Shoelace 2 release date 🎉 -->
<sl-format-date date="2020-07-15T09:17:00-04:00"></sl-format-date>
```
The `date` prop determines the date/time to use when formatting. It must be a string that [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) can interpret or a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object set via JavaScript. If omitted, the current date/time will be assumed.
?> When using strings, avoid ambiguous dates such as `03/04/2020` which can be interpreted as March 4 or April 3 depending on the user's browser and locale. Instead, always use a valid [ISO 8601 date time string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#Date_Time_String_Format) to ensure the date will be parsed properly by all clients.
## Examples
### Date & Time Formatting
Formatting options are based on those found in the [`Intl.DateTimeFormat` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat). When formatting options are provided, the date/time will be formatted according to those values. When no formatting options are provided, a localized, numeric date will be displayed instead.
```html preview
<!-- Human-readable date -->
<sl-format-date month="long" day="numeric" year="numeric"></sl-format-date><br>
<!-- Time -->
<sl-format-date hour="numeric" minute="numeric"></sl-format-date><br>
<!-- Weekday -->
<sl-format-date weekday="long"></sl-format-date><br>
<!-- Month -->
<sl-format-date month="long"></sl-format-date><br>
<!-- Year -->
<sl-format-date year="numeric"></sl-format-date><br>
<!-- No formatting options -->
<sl-format-date></sl-format-date>
```
### Hour Formatting
By default, the browser will determine whether to use 12-hour or 24-hour time. To force one or the other, set the `hourFormat` prop to `12` or `24`.
```html preview
<sl-format-date hour="numeric" minute="numeric" hour-format="12"></sl-format-date><br>
<sl-format-date hour="numeric" minute="numeric" hour-format="24"></sl-format-date>
```
### Localization
Use the `locale` attribute to set the date/time formatting locale.
```html preview
English: <sl-format-date locale="en"></sl-format-date><br>
French: <sl-format-date locale="fr"></sl-format-date><br>
Russian: <sl-format-date locale="ru"></sl-format-date><br>
```
[component-metadata:sl-format-date]

121
src/components.d.ts vendored
Wyświetl plik

@ -468,6 +468,60 @@ export namespace Components {
*/
"value": number;
}
interface SlFormatDate {
/**
* The date/time to format. If not set, the current date and time will be used.
*/
"date": Date | string;
/**
* The format for displaying the day.
*/
"day": 'numeric' | '2-digit';
/**
* The format for displaying the era.
*/
"era": 'narrow' | 'short' | 'long';
/**
* The format for displaying the hour.
*/
"hour": 'numeric' | '2-digit';
/**
* When set, 24 hour time will always be used.
*/
"hourFormat": 'auto' | '12' | '24';
/**
* The locale to use when formatting the date/time.
*/
"locale": string;
/**
* The format for displaying the minute.
*/
"minute": 'numeric' | '2-digit';
/**
* The format for displaying the month.
*/
"month": 'numeric' | '2-digit' | 'narrow' | 'short' | 'long';
/**
* The format for displaying the second.
*/
"second": 'numeric' | '2-digit';
/**
* The time zone to express the time in.
*/
"timeZone": string;
/**
* The format for displaying the time.
*/
"timeZoneName": 'short' | 'long';
/**
* The format for displaying the weekday.
*/
"weekday": 'narrow' | 'short' | 'long';
/**
* The format for displaying the year.
*/
"year": 'numeric' | '2-digit';
}
interface SlFormatNumber {
/**
* The currency to use when formatting. Must be an ISO 4217 currency code such as `USD` or `EUR`.
@ -1360,6 +1414,12 @@ declare global {
prototype: HTMLSlFormatBytesElement;
new (): HTMLSlFormatBytesElement;
};
interface HTMLSlFormatDateElement extends Components.SlFormatDate, HTMLStencilElement {
}
var HTMLSlFormatDateElement: {
prototype: HTMLSlFormatDateElement;
new (): HTMLSlFormatDateElement;
};
interface HTMLSlFormatNumberElement extends Components.SlFormatNumber, HTMLStencilElement {
}
var HTMLSlFormatNumberElement: {
@ -1556,6 +1616,7 @@ declare global {
"sl-dropdown": HTMLSlDropdownElement;
"sl-form": HTMLSlFormElement;
"sl-format-bytes": HTMLSlFormatBytesElement;
"sl-format-date": HTMLSlFormatDateElement;
"sl-format-number": HTMLSlFormatNumberElement;
"sl-icon": HTMLSlIconElement;
"sl-icon-button": HTMLSlIconButtonElement;
@ -2082,6 +2143,60 @@ declare namespace LocalJSX {
*/
"value"?: number;
}
interface SlFormatDate {
/**
* The date/time to format. If not set, the current date and time will be used.
*/
"date"?: Date | string;
/**
* The format for displaying the day.
*/
"day"?: 'numeric' | '2-digit';
/**
* The format for displaying the era.
*/
"era"?: 'narrow' | 'short' | 'long';
/**
* The format for displaying the hour.
*/
"hour"?: 'numeric' | '2-digit';
/**
* When set, 24 hour time will always be used.
*/
"hourFormat"?: 'auto' | '12' | '24';
/**
* The locale to use when formatting the date/time.
*/
"locale"?: string;
/**
* The format for displaying the minute.
*/
"minute"?: 'numeric' | '2-digit';
/**
* The format for displaying the month.
*/
"month"?: 'numeric' | '2-digit' | 'narrow' | 'short' | 'long';
/**
* The format for displaying the second.
*/
"second"?: 'numeric' | '2-digit';
/**
* The time zone to express the time in.
*/
"timeZone"?: string;
/**
* The format for displaying the time.
*/
"timeZoneName"?: 'short' | 'long';
/**
* The format for displaying the weekday.
*/
"weekday"?: 'narrow' | 'short' | 'long';
/**
* The format for displaying the year.
*/
"year"?: 'numeric' | '2-digit';
}
interface SlFormatNumber {
/**
* The currency to use when formatting. Must be an ISO 4217 currency code such as `USD` or `EUR`.
@ -2373,6 +2488,10 @@ declare namespace LocalJSX {
interface SlMenuLabel {
}
interface SlProgressBar {
/**
* When true, percentage is ignored, the label is hidden, and the progress bar is drawn in an indeterminate state.
*/
"indeterminate"?: boolean;
/**
* The progress bar's percentage, 0 to 100.
*/
@ -2897,6 +3016,7 @@ declare namespace LocalJSX {
"sl-dropdown": SlDropdown;
"sl-form": SlForm;
"sl-format-bytes": SlFormatBytes;
"sl-format-date": SlFormatDate;
"sl-format-number": SlFormatNumber;
"sl-icon": SlIcon;
"sl-icon-button": SlIconButton;
@ -2948,6 +3068,7 @@ declare module "@stencil/core" {
"sl-dropdown": LocalJSX.SlDropdown & JSXBase.HTMLAttributes<HTMLSlDropdownElement>;
"sl-form": LocalJSX.SlForm & JSXBase.HTMLAttributes<HTMLSlFormElement>;
"sl-format-bytes": LocalJSX.SlFormatBytes & JSXBase.HTMLAttributes<HTMLSlFormatBytesElement>;
"sl-format-date": LocalJSX.SlFormatDate & JSXBase.HTMLAttributes<HTMLSlFormatDateElement>;
"sl-format-number": LocalJSX.SlFormatNumber & JSXBase.HTMLAttributes<HTMLSlFormatNumberElement>;
"sl-icon": LocalJSX.SlIcon & JSXBase.HTMLAttributes<HTMLSlIconElement>;
"sl-icon-button": LocalJSX.SlIconButton & JSXBase.HTMLAttributes<HTMLSlIconButtonElement>;

Wyświetl plik

@ -0,0 +1,75 @@
import { Component, Prop } from '@stencil/core';
/**
* @since 2.0
* @status stable
*/
@Component({
tag: 'sl-format-date',
shadow: true
})
export class FormatBytes {
/** The date/time to format. If not set, the current date and time will be used. */
@Prop() date: Date | string = new Date();
/** The locale to use when formatting the date/time. */
@Prop() locale: string;
/** The format for displaying the weekday. */
@Prop() weekday: 'narrow' | 'short' | 'long';
/** The format for displaying the era. */
@Prop() era: 'narrow' | 'short' | 'long';
/** The format for displaying the year. */
@Prop() year: 'numeric' | '2-digit';
/** The format for displaying the month. */
@Prop() month: 'numeric' | '2-digit' | 'narrow' | 'short' | 'long';
/** The format for displaying the day. */
@Prop() day: 'numeric' | '2-digit';
/** The format for displaying the hour. */
@Prop() hour: 'numeric' | '2-digit';
/** The format for displaying the minute. */
@Prop() minute: 'numeric' | '2-digit';
/** The format for displaying the second. */
@Prop() second: 'numeric' | '2-digit';
/** The format for displaying the time. */
@Prop() timeZoneName: 'short' | 'long';
/** The time zone to express the time in. */
@Prop() timeZone: string;
/** When set, 24 hour time will always be used. */
@Prop() hourFormat: 'auto' | '12' | '24' = 'auto';
render() {
const date = new Date(this.date);
const hour12 = this.hourFormat === 'auto' ? undefined : this.hourFormat === '12';
// Check for an invalid date
if (isNaN(date.getMilliseconds())) {
return;
}
return new Intl.DateTimeFormat(this.locale, {
weekday: this.weekday,
era: this.era,
year: this.year,
month: this.month,
day: this.day,
hour: this.hour,
minute: this.minute,
second: this.second,
timeZoneName: this.timeZoneName,
timeZone: this.timeZone,
hour12: hour12
}).format(date);
}
}