kopia lustrzana https://github.com/shoelace-style/shoelace
Add format-bytes utility component
rodzic
ac31a16b8e
commit
26d04a9b2e
|
@ -48,6 +48,9 @@
|
|||
- [Textarea](/components/textarea.md)
|
||||
- [Tooltip](/components/tooltip.md)
|
||||
|
||||
- Utility Components
|
||||
- [Format Bytes](/components/format-bytes.md)
|
||||
|
||||
- Design Tokens
|
||||
- [Typography](/tokens/typography.md)
|
||||
- [Color](/tokens/color.md)
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# Format Bytes
|
||||
|
||||
[component-header:sl-format-bytes]
|
||||
|
||||
Formats a number as a human readable bytes value.
|
||||
|
||||
```html preview
|
||||
<div class="format-bytes-overview">
|
||||
The file is <sl-format-bytes value="1000"></sl-format-bytes> in size.
|
||||
<br><br>
|
||||
<sl-input type="number" value="1000" label="Value" style="max-width: 180px;"></sl-input>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const container = document.querySelector('.format-bytes-overview');
|
||||
const formatter = container.querySelector('sl-format-bytes');
|
||||
const input = container.querySelector('sl-input');
|
||||
|
||||
input.addEventListener('slInput', () => formatter.value = input.value || 0);
|
||||
</script>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
### Formatting Bytes
|
||||
|
||||
Set the `value` attribute to a number to get the value in bytes.
|
||||
|
||||
```html preview
|
||||
<sl-format-bytes value="12"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200000"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200000000"></sl-format-bytes>
|
||||
```
|
||||
|
||||
### Formatting Bits
|
||||
|
||||
To get the value in bits, set the `unit` attribute to `bits`.
|
||||
|
||||
```html preview
|
||||
<sl-format-bytes value="12" unit="bits"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200" unit="bits"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200000" unit="bits"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200000000" unit="bits"></sl-format-bytes>
|
||||
```
|
||||
|
||||
### Localization
|
||||
|
||||
Use the `locale` attribute to set the number formatting locale.
|
||||
|
||||
```html preview
|
||||
<sl-format-bytes value="12" locale="de"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200" locale="de"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200000" locale="de"></sl-format-bytes><br>
|
||||
<sl-format-bytes value="1200000000" locale="de"></sl-format-bytes>
|
||||
```
|
||||
|
||||
[component-metadata:sl-format-bytes]
|
|
@ -401,6 +401,20 @@ export namespace Components {
|
|||
*/
|
||||
"submit": () => Promise<void>;
|
||||
}
|
||||
interface SlFormatBytes {
|
||||
/**
|
||||
* The locale to use when formatting the number.
|
||||
*/
|
||||
"locale": string;
|
||||
/**
|
||||
* The unit to display.
|
||||
*/
|
||||
"unit": 'bytes' | 'bits';
|
||||
/**
|
||||
* The number to format in bytes.
|
||||
*/
|
||||
"value": number;
|
||||
}
|
||||
interface SlIcon {
|
||||
/**
|
||||
* An alternative description to use for accessibility. If omitted, the name or src will be used to generate it.
|
||||
|
@ -1088,6 +1102,12 @@ declare global {
|
|||
prototype: HTMLSlFormElement;
|
||||
new (): HTMLSlFormElement;
|
||||
};
|
||||
interface HTMLSlFormatBytesElement extends Components.SlFormatBytes, HTMLStencilElement {
|
||||
}
|
||||
var HTMLSlFormatBytesElement: {
|
||||
prototype: HTMLSlFormatBytesElement;
|
||||
new (): HTMLSlFormatBytesElement;
|
||||
};
|
||||
interface HTMLSlIconElement extends Components.SlIcon, HTMLStencilElement {
|
||||
}
|
||||
var HTMLSlIconElement: {
|
||||
|
@ -1241,6 +1261,7 @@ declare global {
|
|||
"sl-drawer": HTMLSlDrawerElement;
|
||||
"sl-dropdown": HTMLSlDropdownElement;
|
||||
"sl-form": HTMLSlFormElement;
|
||||
"sl-format-bytes": HTMLSlFormatBytesElement;
|
||||
"sl-icon": HTMLSlIconElement;
|
||||
"sl-icon-button": HTMLSlIconButtonElement;
|
||||
"sl-image-comparer": HTMLSlImageComparerElement;
|
||||
|
@ -1714,6 +1735,20 @@ declare namespace LocalJSX {
|
|||
*/
|
||||
"onSlSubmit"?: (event: CustomEvent<any>) => void;
|
||||
}
|
||||
interface SlFormatBytes {
|
||||
/**
|
||||
* The locale to use when formatting the number.
|
||||
*/
|
||||
"locale"?: string;
|
||||
/**
|
||||
* The unit to display.
|
||||
*/
|
||||
"unit"?: 'bytes' | 'bits';
|
||||
/**
|
||||
* The number to format in bytes.
|
||||
*/
|
||||
"value"?: number;
|
||||
}
|
||||
interface SlIcon {
|
||||
/**
|
||||
* An alternative description to use for accessibility. If omitted, the name or src will be used to generate it.
|
||||
|
@ -2370,6 +2405,7 @@ declare namespace LocalJSX {
|
|||
"sl-drawer": SlDrawer;
|
||||
"sl-dropdown": SlDropdown;
|
||||
"sl-form": SlForm;
|
||||
"sl-format-bytes": SlFormatBytes;
|
||||
"sl-icon": SlIcon;
|
||||
"sl-icon-button": SlIconButton;
|
||||
"sl-image-comparer": SlImageComparer;
|
||||
|
@ -2413,6 +2449,7 @@ declare module "@stencil/core" {
|
|||
"sl-drawer": LocalJSX.SlDrawer & JSXBase.HTMLAttributes<HTMLSlDrawerElement>;
|
||||
"sl-dropdown": LocalJSX.SlDropdown & JSXBase.HTMLAttributes<HTMLSlDropdownElement>;
|
||||
"sl-form": LocalJSX.SlForm & JSXBase.HTMLAttributes<HTMLSlFormElement>;
|
||||
"sl-format-bytes": LocalJSX.SlFormatBytes & JSXBase.HTMLAttributes<HTMLSlFormatBytesElement>;
|
||||
"sl-icon": LocalJSX.SlIcon & JSXBase.HTMLAttributes<HTMLSlIconElement>;
|
||||
"sl-icon-button": LocalJSX.SlIconButton & JSXBase.HTMLAttributes<HTMLSlIconButtonElement>;
|
||||
"sl-image-comparer": LocalJSX.SlImageComparer & JSXBase.HTMLAttributes<HTMLSlImageComparerElement>;
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import { Component, Prop } from '@stencil/core';
|
||||
import { formatBytes } from '../../utilities/number';
|
||||
|
||||
/**
|
||||
* @since 2.0
|
||||
* @status stable
|
||||
*/
|
||||
|
||||
@Component({
|
||||
tag: 'sl-format-bytes',
|
||||
shadow: true
|
||||
})
|
||||
export class FormatBytes {
|
||||
/** The number to format in bytes. */
|
||||
@Prop() value = 0;
|
||||
|
||||
/** The unit to display. */
|
||||
@Prop() unit: 'bytes' | 'bits' = 'bytes';
|
||||
|
||||
/** The locale to use when formatting the number. */
|
||||
@Prop() locale: string;
|
||||
|
||||
render() {
|
||||
return formatBytes(this.value, {
|
||||
unit: this.unit,
|
||||
locale: this.locale
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// Formats a number to a human-readable string of bytes or bits such as "100 MB"
|
||||
//
|
||||
export function formatBytes(bytes: number, options: FormatBytesOptions) {
|
||||
options = Object.assign(
|
||||
{
|
||||
unit: 'bytes',
|
||||
locale: undefined
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
const byteUnits = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
const bitUnits = ['b', 'kbit', 'Mbit', 'Gbit', 'Tbit', 'Pbit', 'Ebit', 'Zbit', 'Ybit'];
|
||||
const units = options.unit === 'bytes' ? byteUnits : bitUnits;
|
||||
const isNegative = bytes < 0;
|
||||
|
||||
bytes = Math.abs(bytes);
|
||||
if (bytes === 0) return '0 B';
|
||||
|
||||
const i = Math.min(Math.floor(Math.log10(bytes) / 3), units.length - 1);
|
||||
const num = Number((bytes / Math.pow(1000, i)).toPrecision(3));
|
||||
const numString = num.toLocaleString(options.locale);
|
||||
const prefix = isNegative ? '-' : '';
|
||||
|
||||
return `${prefix}${numString} ${units[i]}`;
|
||||
}
|
||||
|
||||
interface FormatBytesOptions {
|
||||
unit?: 'bytes' | 'bits';
|
||||
locale?: string;
|
||||
}
|
Ładowanie…
Reference in New Issue