kopia lustrzana https://github.com/shoelace-style/shoelace
localize 2.0
rodzic
3dc92ae8e8
commit
4900bbf989
|
@ -1,5 +1,5 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import commentParser from 'comment-parser';
|
import { parse } from 'comment-parser';
|
||||||
import pascalCase from 'pascal-case';
|
import pascalCase from 'pascal-case';
|
||||||
|
|
||||||
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
||||||
|
@ -39,7 +39,7 @@ export default {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const parsed = commentParser.parse(customComments + '\n */');
|
const parsed = parse(customComments + '\n */');
|
||||||
parsed[0].tags?.map(t => {
|
parsed[0].tags?.map(t => {
|
||||||
switch (t.tag) {
|
switch (t.tag) {
|
||||||
// Animations
|
// Animations
|
||||||
|
|
File diff suppressed because one or more lines are too long
Przed Szerokość: | Wysokość: | Rozmiar: 750 KiB Po Szerokość: | Wysokość: | Rozmiar: 750 KiB |
Plik diff jest za duży
Load Diff
|
@ -42,6 +42,7 @@
|
||||||
"@lit-labs/react": "^1.0.1",
|
"@lit-labs/react": "^1.0.1",
|
||||||
"@popperjs/core": "^2.7.0",
|
"@popperjs/core": "^2.7.0",
|
||||||
"@shoelace-style/animations": "^1.1.0",
|
"@shoelace-style/animations": "^1.1.0",
|
||||||
|
"@shoelace-style/localize": "^2.0.0",
|
||||||
"color": "^4.0.2",
|
"color": "^4.0.2",
|
||||||
"lit": "^2.0.2",
|
"lit": "^2.0.2",
|
||||||
"qr-creator": "^1.0.0"
|
"qr-creator": "^1.0.0"
|
||||||
|
|
|
@ -48,6 +48,8 @@ mkdirp.sync(outdir);
|
||||||
'./src/shoelace.ts',
|
'./src/shoelace.ts',
|
||||||
// Components
|
// Components
|
||||||
...(await glob('./src/components/**/!(*.(style|test)).ts')),
|
...(await glob('./src/components/**/!(*.(style|test)).ts')),
|
||||||
|
// Translations
|
||||||
|
...(await glob('./src/translations/**/*.ts')),
|
||||||
// Public utilities
|
// Public utilities
|
||||||
...(await glob('./src/utilities/**/!(*.(style|test)).ts')),
|
...(await glob('./src/utilities/**/!(*.(style|test)).ts')),
|
||||||
// Theme stylesheets
|
// Theme stylesheets
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { styleMap } from 'lit/directives/style-map.js';
|
||||||
import { emit } from '../../internal/event';
|
import { emit } from '../../internal/event';
|
||||||
import { watch } from '../../internal/watch';
|
import { watch } from '../../internal/watch';
|
||||||
import { clamp } from '../../internal/math';
|
import { clamp } from '../../internal/math';
|
||||||
|
import { LocalizeController } from '../../utilities/localize';
|
||||||
import type SlDropdown from '../dropdown/dropdown';
|
import type SlDropdown from '../dropdown/dropdown';
|
||||||
import type SlInput from '../input/input';
|
import type SlInput from '../input/input';
|
||||||
import color from 'color';
|
import color from 'color';
|
||||||
|
@ -56,6 +57,7 @@ const hasEyeDropper = 'EyeDropper' in window;
|
||||||
@customElement('sl-color-picker')
|
@customElement('sl-color-picker')
|
||||||
export default class SlColorPicker extends LitElement {
|
export default class SlColorPicker extends LitElement {
|
||||||
static styles = styles;
|
static styles = styles;
|
||||||
|
private localize = new LocalizeController(this);
|
||||||
|
|
||||||
@query('[part="input"]') input: SlInput;
|
@query('[part="input"]') input: SlInput;
|
||||||
@query('[part="preview"]') previewButton: HTMLButtonElement;
|
@query('[part="preview"]') previewButton: HTMLButtonElement;
|
||||||
|
@ -136,6 +138,9 @@ export default class SlColorPicker extends LitElement {
|
||||||
'#fff'
|
'#fff'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** The locale to render the component in. */
|
||||||
|
@property() lang: string;
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
|
@ -627,7 +632,6 @@ export default class SlColorPicker extends LitElement {
|
||||||
const x = this.saturation;
|
const x = this.saturation;
|
||||||
const y = 100 - this.lightness;
|
const y = 100 - this.lightness;
|
||||||
|
|
||||||
// TODO - i18n for format, copy, and eye dropper buttons
|
|
||||||
const colorPicker = html`
|
const colorPicker = html`
|
||||||
<div
|
<div
|
||||||
part="base"
|
part="base"
|
||||||
|
@ -730,7 +734,7 @@ export default class SlColorPicker extends LitElement {
|
||||||
type="button"
|
type="button"
|
||||||
part="preview"
|
part="preview"
|
||||||
class="color-picker__preview color-picker__transparent-bg"
|
class="color-picker__preview color-picker__transparent-bg"
|
||||||
aria-label="Copy"
|
aria-label=${this.localize.term('copy')}
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
'--preview-color': `hsla(${this.hue}deg, ${this.saturation}%, ${this.lightness}%, ${this.alpha / 100})`
|
'--preview-color': `hsla(${this.hue}deg, ${this.saturation}%, ${this.lightness}%, ${this.alpha / 100})`
|
||||||
})}
|
})}
|
||||||
|
@ -757,7 +761,7 @@ export default class SlColorPicker extends LitElement {
|
||||||
${!this.noFormatToggle
|
${!this.noFormatToggle
|
||||||
? html`
|
? html`
|
||||||
<sl-button
|
<sl-button
|
||||||
aria-label="Change format"
|
aria-label=${this.localize.term('toggle_color_format')}
|
||||||
exportparts="base:format-button"
|
exportparts="base:format-button"
|
||||||
@click=${this.handleFormatToggle}
|
@click=${this.handleFormatToggle}
|
||||||
>
|
>
|
||||||
|
@ -768,7 +772,11 @@ export default class SlColorPicker extends LitElement {
|
||||||
${hasEyeDropper
|
${hasEyeDropper
|
||||||
? html`
|
? html`
|
||||||
<sl-button exportparts="base:eye-dropper-button" @click=${this.handleEyeDropper}>
|
<sl-button exportparts="base:eye-dropper-button" @click=${this.handleEyeDropper}>
|
||||||
<sl-icon library="system" name="eyedropper" label="Select a color from the screen"></sl-icon>
|
<sl-icon
|
||||||
|
library="system"
|
||||||
|
name="eyedropper"
|
||||||
|
label=${this.localize.term('select_a_color_from_the_screen')}
|
||||||
|
></sl-icon>
|
||||||
</sl-button>
|
</sl-button>
|
||||||
`
|
`
|
||||||
: ''}
|
: ''}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { customElement, property } from 'lit/decorators.js';
|
||||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { styleMap } from 'lit/directives/style-map.js';
|
import { styleMap } from 'lit/directives/style-map.js';
|
||||||
|
import { LocalizeController } from '../../utilities/localize';
|
||||||
import styles from './progress-bar.styles';
|
import styles from './progress-bar.styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,6 +24,7 @@ import styles from './progress-bar.styles';
|
||||||
@customElement('sl-progress-bar')
|
@customElement('sl-progress-bar')
|
||||||
export default class SlProgressBar extends LitElement {
|
export default class SlProgressBar extends LitElement {
|
||||||
static styles = styles;
|
static styles = styles;
|
||||||
|
private localize = new LocalizeController(this);
|
||||||
|
|
||||||
/** The current progress, 0 to 100. */
|
/** The current progress, 0 to 100. */
|
||||||
@property({ type: Number, reflect: true }) value = 0;
|
@property({ type: Number, reflect: true }) value = 0;
|
||||||
|
@ -30,8 +32,11 @@ export default class SlProgressBar extends LitElement {
|
||||||
/** When true, percentage is ignored, the label is hidden, and the progress bar is drawn in an indeterminate state. */
|
/** When true, percentage is ignored, the label is hidden, and the progress bar is drawn in an indeterminate state. */
|
||||||
@property({ type: Boolean, reflect: true }) indeterminate = false;
|
@property({ type: Boolean, reflect: true }) indeterminate = false;
|
||||||
|
|
||||||
/** The progress bar's aria label. */
|
/** A custom label for the progress bar's aria label. */
|
||||||
@property() label = 'Progress'; // TODO - i18n
|
@property() label: string;
|
||||||
|
|
||||||
|
/** The locale to render the component in. */
|
||||||
|
@property() lang: string;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
|
@ -43,7 +48,7 @@ export default class SlProgressBar extends LitElement {
|
||||||
})}
|
})}
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
title=${ifDefined(this.title)}
|
title=${ifDefined(this.title)}
|
||||||
aria-label=${ifDefined(this.label)}
|
aria-label=${this.label || this.localize.term('progress')}
|
||||||
aria-valuemin="0"
|
aria-valuemin="0"
|
||||||
aria-valuemax="100"
|
aria-valuemax="100"
|
||||||
aria-valuenow=${this.indeterminate ? 0 : this.value}
|
aria-valuenow=${this.indeterminate ? 0 : this.value}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { LitElement, html } from 'lit';
|
import { LitElement, html } from 'lit';
|
||||||
import { customElement, property, query, state } from 'lit/decorators.js';
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
||||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
import { LocalizeController } from '../../utilities/localize';
|
||||||
import styles from './progress-ring.styles';
|
import styles from './progress-ring.styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +20,7 @@ import styles from './progress-ring.styles';
|
||||||
@customElement('sl-progress-ring')
|
@customElement('sl-progress-ring')
|
||||||
export default class SlProgressRing extends LitElement {
|
export default class SlProgressRing extends LitElement {
|
||||||
static styles = styles;
|
static styles = styles;
|
||||||
|
private localize = new LocalizeController(this);
|
||||||
|
|
||||||
@query('.progress-ring__indicator') indicator: SVGCircleElement;
|
@query('.progress-ring__indicator') indicator: SVGCircleElement;
|
||||||
|
|
||||||
|
@ -28,8 +29,11 @@ export default class SlProgressRing extends LitElement {
|
||||||
/** The current progress, 0 to 100. */
|
/** The current progress, 0 to 100. */
|
||||||
@property({ type: Number, reflect: true }) value = 0;
|
@property({ type: Number, reflect: true }) value = 0;
|
||||||
|
|
||||||
/** The progress ring's aria label. */
|
/** A custom label for the progress ring's aria label. */
|
||||||
@property() label = 'Progress'; // TODO - i18n
|
@property() label: string;
|
||||||
|
|
||||||
|
/** The locale to render the component in. */
|
||||||
|
@property() lang: string;
|
||||||
|
|
||||||
updated(changedProps: Map<string, any>) {
|
updated(changedProps: Map<string, any>) {
|
||||||
super.updated(changedProps);
|
super.updated(changedProps);
|
||||||
|
@ -54,7 +58,7 @@ export default class SlProgressRing extends LitElement {
|
||||||
part="base"
|
part="base"
|
||||||
class="progress-ring"
|
class="progress-ring"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
aria-label=${ifDefined(this.label)}
|
aria-label=${this.label || this.localize.term('progress')}
|
||||||
aria-valuemin="0"
|
aria-valuemin="0"
|
||||||
aria-valuemax="100"
|
aria-valuemax="100"
|
||||||
aria-valuenow="${this.value}"
|
aria-valuenow="${this.value}"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { emit } from '../../internal/event';
|
||||||
import { watch } from '../../internal/watch';
|
import { watch } from '../../internal/watch';
|
||||||
import { getOffset } from '../../internal/offset';
|
import { getOffset } from '../../internal/offset';
|
||||||
import { scrollIntoView } from '../../internal/scroll';
|
import { scrollIntoView } from '../../internal/scroll';
|
||||||
|
import { LocalizeController } from '../../utilities/localize';
|
||||||
import type SlTab from '../tab/tab';
|
import type SlTab from '../tab/tab';
|
||||||
import type SlTabPanel from '../tab-panel/tab-panel';
|
import type SlTabPanel from '../tab-panel/tab-panel';
|
||||||
import styles from './tab-group.styles';
|
import styles from './tab-group.styles';
|
||||||
|
@ -36,6 +37,7 @@ import '../icon-button/icon-button';
|
||||||
@customElement('sl-tab-group')
|
@customElement('sl-tab-group')
|
||||||
export default class SlTabGroup extends LitElement {
|
export default class SlTabGroup extends LitElement {
|
||||||
static styles = styles;
|
static styles = styles;
|
||||||
|
private localize = new LocalizeController(this);
|
||||||
|
|
||||||
@query('.tab-group') tabGroup: HTMLElement;
|
@query('.tab-group') tabGroup: HTMLElement;
|
||||||
@query('.tab-group__body') body: HTMLElement;
|
@query('.tab-group__body') body: HTMLElement;
|
||||||
|
@ -62,6 +64,9 @@ export default class SlTabGroup extends LitElement {
|
||||||
/** Disables the scroll arrows that appear when tabs overflow. */
|
/** Disables the scroll arrows that appear when tabs overflow. */
|
||||||
@property({ attribute: 'no-scroll-controls', type: Boolean }) noScrollControls = false;
|
@property({ attribute: 'no-scroll-controls', type: Boolean }) noScrollControls = false;
|
||||||
|
|
||||||
|
/** The locale to render the component in. */
|
||||||
|
@property() lang: string;
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
|
@ -339,7 +344,6 @@ export default class SlTabGroup extends LitElement {
|
||||||
this.syncIndicator();
|
this.syncIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - i18n scroll to start/end labels
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
|
@ -363,7 +367,7 @@ export default class SlTabGroup extends LitElement {
|
||||||
exportparts="base:scroll-button"
|
exportparts="base:scroll-button"
|
||||||
name="chevron-left"
|
name="chevron-left"
|
||||||
library="system"
|
library="system"
|
||||||
label="Scroll to start"
|
label=${this.localize.term('scroll_to_start')}
|
||||||
@click=${this.handleScrollToStart}
|
@click=${this.handleScrollToStart}
|
||||||
></sl-icon-button>
|
></sl-icon-button>
|
||||||
`
|
`
|
||||||
|
@ -383,7 +387,7 @@ export default class SlTabGroup extends LitElement {
|
||||||
exportparts="base:scroll-button"
|
exportparts="base:scroll-button"
|
||||||
name="chevron-right"
|
name="chevron-right"
|
||||||
library="system"
|
library="system"
|
||||||
label="Scroll to end"
|
label=${this.localize.term('scroll_to_end')}
|
||||||
@click=${this.handleScrollToEnd}
|
@click=${this.handleScrollToEnd}
|
||||||
></sl-icon-button>
|
></sl-icon-button>
|
||||||
`
|
`
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { LitElement, html } from 'lit';
|
||||||
import { customElement, property, query } from 'lit/decorators.js';
|
import { customElement, property, query } from 'lit/decorators.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
import { emit } from '../../internal/event';
|
import { emit } from '../../internal/event';
|
||||||
|
import { LocalizeController } from '../../utilities/localize';
|
||||||
import styles from './tab.styles';
|
import styles from './tab.styles';
|
||||||
|
|
||||||
import '../icon-button/icon-button';
|
import '../icon-button/icon-button';
|
||||||
|
@ -24,6 +25,7 @@ let id = 0;
|
||||||
@customElement('sl-tab')
|
@customElement('sl-tab')
|
||||||
export default class SlTab extends LitElement {
|
export default class SlTab extends LitElement {
|
||||||
static styles = styles;
|
static styles = styles;
|
||||||
|
private localize = new LocalizeController(this);
|
||||||
|
|
||||||
@query('.tab') tab: HTMLElement;
|
@query('.tab') tab: HTMLElement;
|
||||||
|
|
||||||
|
@ -41,6 +43,9 @@ export default class SlTab extends LitElement {
|
||||||
/** Draws the tab in a disabled state. */
|
/** Draws the tab in a disabled state. */
|
||||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||||
|
|
||||||
|
/** The locale to render the component in. */
|
||||||
|
@property() lang: string;
|
||||||
|
|
||||||
/** Sets focus to the tab. */
|
/** Sets focus to the tab. */
|
||||||
focus(options?: FocusOptions) {
|
focus(options?: FocusOptions) {
|
||||||
this.tab.focus(options);
|
this.tab.focus(options);
|
||||||
|
@ -59,7 +64,6 @@ export default class SlTab extends LitElement {
|
||||||
// If the user didn't provide an ID, we'll set one so we can link tabs and tab panels with aria labels
|
// If the user didn't provide an ID, we'll set one so we can link tabs and tab panels with aria labels
|
||||||
this.id = this.id || this.componentId;
|
this.id = this.id || this.componentId;
|
||||||
|
|
||||||
// TODO - i18n close label
|
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
part="base"
|
part="base"
|
||||||
|
@ -80,7 +84,7 @@ export default class SlTab extends LitElement {
|
||||||
<sl-icon-button
|
<sl-icon-button
|
||||||
name="x"
|
name="x"
|
||||||
library="system"
|
library="system"
|
||||||
label="Close"
|
label=${this.localize.term('close')}
|
||||||
exportparts="base:close-button"
|
exportparts="base:close-button"
|
||||||
class="tab__close-button"
|
class="tab__close-button"
|
||||||
@click=${this.handleCloseClick}
|
@click=${this.handleCloseClick}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { registerTranslation } from '../utilities/localize';
|
||||||
|
import type { Translation } from '../utilities/localize';
|
||||||
|
|
||||||
|
const translation: Translation = {
|
||||||
|
$code: 'en',
|
||||||
|
$name: 'English',
|
||||||
|
$dir: 'ltr',
|
||||||
|
|
||||||
|
close: 'Close',
|
||||||
|
copy: 'Copy',
|
||||||
|
progress: 'Progress',
|
||||||
|
scroll_to_end: 'Scroll to end',
|
||||||
|
scroll_to_start: 'Scroll to start',
|
||||||
|
select_a_color_from_the_screen: 'Select a color from the screen',
|
||||||
|
toggle_color_format: 'Toggle color format'
|
||||||
|
};
|
||||||
|
|
||||||
|
registerTranslation(translation);
|
||||||
|
|
||||||
|
export default translation;
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { registerTranslation } from '../utilities/localize';
|
||||||
|
import type { Translation } from '../utilities/localize';
|
||||||
|
|
||||||
|
const translation: Translation = {
|
||||||
|
$code: 'es',
|
||||||
|
$name: 'Español',
|
||||||
|
$dir: 'ltr',
|
||||||
|
|
||||||
|
close: 'Cerrar',
|
||||||
|
copy: 'Copiar',
|
||||||
|
progress: 'Progreso',
|
||||||
|
scroll_to_end: 'Desplazarse hasta el final',
|
||||||
|
scroll_to_start: 'Desplácese para comenzar',
|
||||||
|
select_a_color_from_the_screen: 'Seleccione un color de la pantalla',
|
||||||
|
toggle_color_format: 'Alternar formato de color'
|
||||||
|
};
|
||||||
|
|
||||||
|
registerTranslation(translation);
|
||||||
|
|
||||||
|
export default translation;
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Register English as the default/fallback language
|
||||||
|
import '../translations/en';
|
||||||
|
|
||||||
|
// Export functions from the localize lib so we have one central place to import them from
|
||||||
|
export * from '@shoelace-style/localize';
|
Ładowanie…
Reference in New Issue