kopia lustrzana https://github.com/shoelace-style/shoelace
Scaffold relative time component
rodzic
72c77446c4
commit
8a08302bb7
|
@ -52,6 +52,7 @@
|
|||
- [Format Bytes](/components/format-bytes.md)
|
||||
- [Format Number](/components/format-number.md)
|
||||
- [Include](/components/include.md)
|
||||
- [Relative Time](/components/relative-time.md)
|
||||
- [Resize Observer](/components/resize-observer.md)
|
||||
- [Theme](/components/theme.md)
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
# Relative Time
|
||||
|
||||
[component-header:sl-relative-time]
|
||||
|
||||
Outputs a localized time phrase relative to the current time.
|
||||
|
||||
Localization is handled by the browser's [Intl.RelativeTimeFormat API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat) so there'e no need to load language packs.
|
||||
|
||||
```html preview
|
||||
<sl-relative-time date="2011-11-11T16:56:20-04:00"></sl-relative-time><br>
|
||||
```
|
||||
|
||||
The `date` prop must be a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object or a string that [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) can interpret. 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, 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 proper parsing.
|
||||
|
||||
?> [The Intl.RelativeTimeFormat API is available in all major browsers](https://caniuse.com/mdn-javascript_builtins_intl_relativetimeformat), but it first became available to Safari in version 14. If you need to support Safari 13, you'll need to [use a polyfill](https://github.com/catamphetamine/relative-time-format).
|
||||
|
||||
## Examples
|
||||
|
||||
### Keeping Time in Sync
|
||||
|
||||
Use the `sync` attribute to update the displayed value as time passes.
|
||||
|
||||
```html preview
|
||||
<div class="relative-time-sync">
|
||||
<sl-relative-time sync></sl-relative-time>
|
||||
<br><br>
|
||||
<sl-button>Reset</sl-button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const container = document.querySelector('.relative-time-sync');
|
||||
const button = container.querySelector('sl-button');
|
||||
const relativeTime = container.querySelector('sl-relative-time');
|
||||
|
||||
relativeTime.date = new Date();
|
||||
button.addEventListener('click', () => relativeTime.date = new Date());
|
||||
</script>
|
||||
```
|
||||
|
||||
### Formatting Styles
|
||||
|
||||
You can change the way times are formatted with the `format` attribute. Note that some locales may show the same result for `narrow` and `short` formats.
|
||||
|
||||
```html preview
|
||||
<sl-relative-time date="2020-07-15T09:17:00" format="narrow"></sl-relative-time><br>
|
||||
<sl-relative-time date="2020-07-15T09:17:00" format="short"></sl-relative-time><br>
|
||||
<sl-relative-time date="2020-07-15T09:17:00" format="long"></sl-relative-time>
|
||||
```
|
||||
|
||||
### Localization
|
||||
|
||||
Use the `locale` attribute to set the desired locale.
|
||||
|
||||
```html preview
|
||||
English: <sl-relative-time date="2020-07-15T09:17:00" locale="en-US"></sl-relative-time><br>
|
||||
Chinese: <sl-relative-time date="2020-07-15T09:17:00" locale="zh-CN"></sl-relative-time><br>
|
||||
German: <sl-relative-time date="2020-07-15T09:17:00" locale="de-DE"></sl-relative-time><br>
|
||||
Russian: <sl-relative-time date="2020-07-15T09:17:00" locale="ru-RU"></sl-relative-time>
|
||||
```
|
||||
|
||||
[component-metadata:sl-relative-time]
|
|
@ -9,6 +9,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
|
|||
## Next
|
||||
|
||||
- Added `sl-format-number` component
|
||||
- Added `sl-relative-time` component
|
||||
- Added `closable` prop to `sl-tab`
|
||||
- Added experimental `sl-resize-observer` utility
|
||||
- Added experimental `sl-theme` utility and updated theming documentation
|
||||
|
|
|
@ -897,6 +897,24 @@ export namespace Components {
|
|||
*/
|
||||
"value": number;
|
||||
}
|
||||
interface SlRelativeTime {
|
||||
/**
|
||||
* The date from which to calculate time from.
|
||||
*/
|
||||
"date": Date | string;
|
||||
/**
|
||||
* The formatting style to use.
|
||||
*/
|
||||
"format": 'long' | 'short' | 'narrow';
|
||||
/**
|
||||
* The locale to use when formatting the number.
|
||||
*/
|
||||
"locale": string;
|
||||
/**
|
||||
* When `auto`, values such as "yesterday" and "tomorrow" will be shown when possible. When `always`, values such as "1 day ago" and "in 1 day" will be shown.
|
||||
*/
|
||||
"numeric": 'always' | 'auto';
|
||||
}
|
||||
interface SlResizeObserver {
|
||||
}
|
||||
interface SlResponsiveEmbed {
|
||||
|
@ -1434,6 +1452,12 @@ declare global {
|
|||
prototype: HTMLSlRatingElement;
|
||||
new (): HTMLSlRatingElement;
|
||||
};
|
||||
interface HTMLSlRelativeTimeElement extends Components.SlRelativeTime, HTMLStencilElement {
|
||||
}
|
||||
var HTMLSlRelativeTimeElement: {
|
||||
prototype: HTMLSlRelativeTimeElement;
|
||||
new (): HTMLSlRelativeTimeElement;
|
||||
};
|
||||
interface HTMLSlResizeObserverElement extends Components.SlResizeObserver, HTMLStencilElement {
|
||||
}
|
||||
var HTMLSlResizeObserverElement: {
|
||||
|
@ -1544,6 +1568,7 @@ declare global {
|
|||
"sl-radio": HTMLSlRadioElement;
|
||||
"sl-range": HTMLSlRangeElement;
|
||||
"sl-rating": HTMLSlRatingElement;
|
||||
"sl-relative-time": HTMLSlRelativeTimeElement;
|
||||
"sl-resize-observer": HTMLSlResizeObserverElement;
|
||||
"sl-responsive-embed": HTMLSlResponsiveEmbedElement;
|
||||
"sl-select": HTMLSlSelectElement;
|
||||
|
@ -2477,6 +2502,24 @@ declare namespace LocalJSX {
|
|||
*/
|
||||
"value"?: number;
|
||||
}
|
||||
interface SlRelativeTime {
|
||||
/**
|
||||
* The date from which to calculate time from.
|
||||
*/
|
||||
"date"?: Date | string;
|
||||
/**
|
||||
* The formatting style to use.
|
||||
*/
|
||||
"format"?: 'long' | 'short' | 'narrow';
|
||||
/**
|
||||
* The locale to use when formatting the number.
|
||||
*/
|
||||
"locale"?: string;
|
||||
/**
|
||||
* When `auto`, values such as "yesterday" and "tomorrow" will be shown when possible. When `always`, values such as "1 day ago" and "in 1 day" will be shown.
|
||||
*/
|
||||
"numeric"?: 'always' | 'auto';
|
||||
}
|
||||
interface SlResizeObserver {
|
||||
/**
|
||||
* Emitted when the element is resized.
|
||||
|
@ -2862,6 +2905,7 @@ declare namespace LocalJSX {
|
|||
"sl-radio": SlRadio;
|
||||
"sl-range": SlRange;
|
||||
"sl-rating": SlRating;
|
||||
"sl-relative-time": SlRelativeTime;
|
||||
"sl-resize-observer": SlResizeObserver;
|
||||
"sl-responsive-embed": SlResponsiveEmbed;
|
||||
"sl-select": SlSelect;
|
||||
|
@ -2912,6 +2956,7 @@ declare module "@stencil/core" {
|
|||
"sl-radio": LocalJSX.SlRadio & JSXBase.HTMLAttributes<HTMLSlRadioElement>;
|
||||
"sl-range": LocalJSX.SlRange & JSXBase.HTMLAttributes<HTMLSlRangeElement>;
|
||||
"sl-rating": LocalJSX.SlRating & JSXBase.HTMLAttributes<HTMLSlRatingElement>;
|
||||
"sl-relative-time": LocalJSX.SlRelativeTime & JSXBase.HTMLAttributes<HTMLSlRelativeTimeElement>;
|
||||
"sl-resize-observer": LocalJSX.SlResizeObserver & JSXBase.HTMLAttributes<HTMLSlResizeObserverElement>;
|
||||
"sl-responsive-embed": LocalJSX.SlResponsiveEmbed & JSXBase.HTMLAttributes<HTMLSlResponsiveEmbedElement>;
|
||||
"sl-select": LocalJSX.SlSelect & JSXBase.HTMLAttributes<HTMLSlSelectElement>;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import { Component, Prop, State, h } from '@stencil/core';
|
||||
|
||||
/**
|
||||
* @since 2.0
|
||||
* @status stable
|
||||
*/
|
||||
|
||||
@Component({
|
||||
tag: 'sl-relative-time',
|
||||
shadow: true
|
||||
})
|
||||
export class RelativeTime {
|
||||
@State() displayTime = '';
|
||||
|
||||
/** The date from which to calculate time from. */
|
||||
@Prop() date: Date | string;
|
||||
|
||||
/** The locale to use when formatting the number. */
|
||||
@Prop() locale: string;
|
||||
|
||||
/** The formatting style to use. */
|
||||
@Prop() format: 'long' | 'short' | 'narrow' = 'long';
|
||||
|
||||
/**
|
||||
* When `auto`, values such as "yesterday" and "tomorrow" will be shown when possible. When `always`, values such as
|
||||
* "1 day ago" and "in 1 day" will be shown.
|
||||
*/
|
||||
@Prop() numeric: 'always' | 'auto' = 'auto';
|
||||
|
||||
render() {
|
||||
const date = new Date(this.date);
|
||||
|
||||
if (isNaN(date.getSeconds())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// // @ts-ignore - https://caniuse.com/mdn-javascript_builtins_intl_relativetimeformat
|
||||
// new Intl.RelativeTimeFormat(this.locale, {
|
||||
// numeric: this.numeric,
|
||||
// style: this.type
|
||||
// }).format(this.value, this.unit);
|
||||
|
||||
return <time dateTime={date.toISOString()}>{this.displayTime}</time>;
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue