kopia lustrzana https://github.com/shoelace-style/shoelace
refactor format-bytes to use Intl
rodzic
8194d627ee
commit
f70961e67d
16
cspell.json
16
cspell.json
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
Ładowanie…
Reference in New Issue