refactor format-bytes to use Intl

pull/661/head
Cory LaViska 2022-01-27 08:56:51 -05:00
rodzic 8194d627ee
commit f70961e67d
5 zmienionych plików z 45 dodań i 50 usunięć

Wyświetl plik

@ -38,6 +38,7 @@
"FOUC",
"FOUCE",
"fullscreen",
"giga",
"globby",
"Grayscale",
"haspopup",
@ -69,6 +70,8 @@
"novalidate",
"outdir",
"ParamagicDev",
"peta",
"petabit",
"popperjs",
"progressbar",
"radiogroup",
@ -92,6 +95,7 @@
"tablist",
"tabpanel",
"templating",
"tera",
"textareas",
"transitionend",
"Triaging",
@ -107,7 +111,15 @@
"Webpacker",
"wordmark"
],
"ignorePaths": ["package.json", "package-lock.json", ".vscode/**", "src/translations/!(en).ts", "**/*.min.js"],
"ignoreRegExpList": ["(^|[^a-z])sl[a-z]*(^|[^a-z])"],
"ignorePaths": [
"package.json",
"package-lock.json",
".vscode/**",
"src/translations/!(en).ts",
"**/*.min.js"
],
"ignoreRegExpList": [
"(^|[^a-z])sl[a-z]*(^|[^a-z])"
],
"useGitignore": true
}

Wyświetl plik

@ -77,13 +77,13 @@ const App = () => (
### Formatting Bits
To get the value in bits, set the `unit` attribute to `bits`.
To get the value in bits, set the `unit` attribute to `bit`.
```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>
<sl-format-bytes value="12" unit="bit"></sl-format-bytes><br>
<sl-format-bytes value="1200" unit="bit"></sl-format-bytes><br>
<sl-format-bytes value="1200000" unit="bit"></sl-format-bytes><br>
<sl-format-bytes value="1200000000" unit="bit"></sl-format-bytes>
```
```jsx react
@ -91,10 +91,10 @@ import { SlFormatBytes } from '@shoelace-style/shoelace/dist/react';
const App = () => (
<>
<SlFormatBytes value="12" unit="bits" /><br />
<SlFormatBytes value="1200" unit="bits" /><br />
<SlFormatBytes value="1200000" unit="bits" /><br />
<SlFormatBytes value="1200000000" unit="bits" />
<SlFormatBytes value="12" unit="bit" /><br />
<SlFormatBytes value="1200" unit="bit" /><br />
<SlFormatBytes value="1200000" unit="bit" /><br />
<SlFormatBytes value="1200000000" unit="bit" />
</>
);
```

Wyświetl plik

@ -8,9 +8,11 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
## Next
- 🚨 BREAKING: the `unit` property of `<sl-format-bytes>` has changed to `byte | bit` instead of `bytes | bits`
- Fixed a bug that caused `<sl-progress-ring>` to render the wrong size when `--track-width` was increased [#656](https://github.com/shoelace-style/shoelace/issues/656)
- Implemented stricter linting to improve consistency and reduce errors, which resulted in many small refactors throughout the codebase [#647](https://github.com/shoelace-style/shoelace/pull/647)
- Improved accessibility of `<sl-dialog>` and `<sl-drawer>` by making the title an `<h2>` and adding a label to the close button
- Refactored `<sl-format-byte>` to use `Intl.NumberFormat` so it supports localization
- Refactored themes so utility styles are no longer injected as `<style>` elements to support stricter CSP rules [#571](https://github.com/shoelace-style/shoelace/issues/571)
- Restored the nicer animation on `<sl-spinner>` and verified it works in Safari
- Updated minimum Node version to 14.17

Wyświetl plik

@ -1,9 +1,9 @@
import { LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { formatBytes } from '~/internal/number';
import { LocalizeController } from '~/utilities/localize';
/**
* @since 2.0
* @status stable
*/
@ -15,15 +15,30 @@ export default class SlFormatBytes extends LitElement {
@property({ type: Number }) value = 0;
/** The unit to display. */
@property() unit: 'bytes' | 'bits' = 'bytes';
@property() unit: 'byte' | 'bit' = 'byte';
/** Determines how to display the result, e.g. "100 bytes", "100 b", or "100b". */
@property() display: 'long' | 'short' | 'narrow' = 'short';
/** The locale to use when formatting the number. */
@property() lang: string;
render() {
return formatBytes(this.value, {
unit: this.unit,
formatter: num => this.localize.number(num)
if (isNaN(this.value)) {
return '';
}
const bitPrefixes = ['', 'kilo', 'mega', 'giga', 'tera']; // petabit isn't a supported unit
const bytePrefixes = ['', 'kilo', 'mega', 'giga', 'tera', 'peta'];
const prefix = this.unit === 'bit' ? bitPrefixes : bytePrefixes;
const index = Math.max(0, Math.min(Math.floor(Math.log10(this.value) / 3), prefix.length - 1));
const unit = prefix[index] + this.unit;
const valueToFormat = parseFloat((this.value / Math.pow(1000, index)).toPrecision(3));
return this.localize.number(valueToFormat, {
style: 'unit',
unit,
unitDisplay: this.display
});
}
}

Wyświetl plik

@ -1,34 +0,0 @@
const numberFormatter = new Intl.NumberFormat();
/**
* Formats a number to a human-readable string of bytes or bits such as "100 MB"
*/
export function formatBytes(bytes: number, options: FormatBytesOptions) {
options = {
unit: 'bytes',
formatter: (num: number) => numberFormatter.format(num),
...options
};
const byteUnits = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const bitUnits = ['b', 'kbit', 'Mbit', 'Gbit', 'Tbit', 'Pbit', 'Ebit', 'Zbit', 'Ybit']; // cspell:disable-line
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 = parseFloat((bytes / Math.pow(1000, i)).toPrecision(3));
const numString = options.formatter?.(num) ?? num;
const prefix = isNegative ? '-' : '';
return `${prefix}${numString} ${units[i]}`;
}
interface FormatBytesOptions {
unit?: 'bytes' | 'bits';
formatter?: (number: number) => string;
}