Scroller component (#907)

* add term

* add scroller component

* update color in docs

* prettier

* add vertical example

* use CSS

* add word

* rework shadows and add opt outs

* add examples

* update docs

* Add missing closing tag in 'Adding Content' example

* fix jsdoc

* fix safari pixels

* add changelog entry

---------

Co-authored-by: lindsaym-fa <dev@lindsaym.design>
This commit is contained in:
Cory LaViska
2025-05-15 16:12:36 -04:00
committed by GitHub
parent 40ea444c48
commit f5d1b74e00
35 changed files with 489 additions and 0 deletions

View File

@@ -148,6 +148,7 @@
"scrollbars",
"scrollend",
"scroller",
"Scrollers",
"Segoe",
"semibold",
"shadowrootmode",

View File

@@ -0,0 +1,31 @@
<svg width="96" height="64" viewBox="0 0 96 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 1H84C90.0751 1 95 5.92487 95 12V52C95 58.0751 90.0751 63 84 63H12C5.92487 63 1 58.0751 1 52V12C1 5.92487 5.92487 1 12 1Z" fill="var(--wa-color-surface-default)"/>
<path d="M12 1H84C90.0751 1 95 5.92487 95 12V52C95 58.0751 90.0751 63 84 63H12C5.92487 63 1 58.0751 1 52V12C1 5.92487 5.92487 1 12 1Z" stroke="var(--wa-color-surface-border)" stroke-width="2"/>
<rect x="12" y="12" width="24" height="4" rx="2" fill="var(--wa-color-neutral-fill-quiet)"/>
<rect x="12" y="21" width="24" height="4" rx="2" fill="var(--wa-color-neutral-fill-quiet)"/>
<rect x="12" y="30" width="24" height="4" rx="2" fill="var(--wa-color-neutral-fill-quiet)"/>
<rect x="44" y="12" width="24" height="4" rx="2" fill="var(--wa-color-neutral-fill-quiet)"/>
<rect x="44" y="21" width="24" height="4" rx="2" fill="var(--wa-color-neutral-fill-quiet)"/>
<rect x="44" y="30" width="24" height="4" rx="2" fill="var(--wa-color-neutral-fill-quiet)"/>
<rect x="76" y="12" width="20" height="4" rx="2" fill="url(#paint0_linear_302_2)"/>
<rect x="76" y="21" width="20" height="4" rx="2" fill="url(#paint1_linear_302_2)"/>
<rect x="76" y="30" width="20" height="4" rx="2" fill="url(#paint2_linear_302_2)"/>
<rect x="4" y="44" width="88" height="16" rx="8" fill="var(--wa-color-neutral-fill-normal)"/>
<path d="M85.8438 51.6562C86.0469 51.8438 86.0469 52.1719 85.8438 52.3594L82.8438 55.3594C82.6562 55.5625 82.3281 55.5625 82.1406 55.3594C81.9375 55.1719 81.9375 54.8438 82.1406 54.6562L84.7812 52L82.1406 49.3594C81.9375 49.1719 81.9375 48.8438 82.1406 48.6562C82.3281 48.4531 82.6562 48.4531 82.8438 48.6562L85.8438 51.6562Z" fill="var(--wa-color-neutral-border-loud)"/>
<path d="M10.1406 51.6562L13.1406 48.6562C13.3281 48.4531 13.6562 48.4531 13.8438 48.6562C14.0469 48.8438 14.0469 49.1719 13.8438 49.3594L11.2031 52L13.8438 54.6562C14.0469 54.8438 14.0469 55.1719 13.8438 55.3594C13.6562 55.5625 13.3281 55.5625 13.1406 55.3594L10.1406 52.3594C9.9375 52.1719 9.9375 51.8438 10.1406 51.6562Z" fill="var(--wa-color-neutral-border-loud)"/>
<path d="M20 52C20 49.7909 21.7909 48 24 48H48C50.2091 48 52 49.7909 52 52V52C52 54.2091 50.2091 56 48 56H24C21.7909 56 20 54.2091 20 52V52Z" fill="var(--wa-color-neutral-border-loud)"/>
<defs>
<linearGradient id="paint0_linear_302_2" x1="76" y1="14" x2="96" y2="14" gradientUnits="userSpaceOnUse">
<stop offset="0.533654" stop-color="var(--wa-color-neutral-fill-quiet)"/>
<stop offset="1" stop-color="var(--wa-color-neutral-fill-quiet)" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_302_2" x1="76" y1="23" x2="96" y2="23" gradientUnits="userSpaceOnUse">
<stop offset="0.533654" stop-color="var(--wa-color-neutral-fill-quiet)"/>
<stop offset="1" stop-color="var(--wa-color-neutral-fill-quiet)" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_302_2" x1="76" y1="32" x2="96" y2="32" gradientUnits="userSpaceOnUse">
<stop offset="0.533654" stop-color="var(--wa-color-neutral-fill-quiet)"/>
<stop offset="1" stop-color="var(--wa-color-neutral-fill-quiet)" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,151 @@
---
title: Scroller
description: Scrollers create an accessible container while providing visual cues that help users identify and navigate through content that scrolls.
layout: component
tags: [organization]
icon: scroller
---
```html {.example}
<wa-scroller id="scroller__overview">
<table>
<tr>
<th>Party Role</th>
<th>Combat Style</th>
<th>Group Size</th>
<th>Campaign Setting</th>
<th>Signature Traits</th>
</tr>
<tr>
<td>Warrior</td>
<td>Melee Tank</td>
<td>1-2</td>
<td>Forgotten Realms</td>
<td>Plate-armored swordmaster who taunts foes.</td>
</tr>
<tr>
<td>Rogue</td>
<td>Stealth Striker</td>
<td>1</td>
<td>Eberron</td>
<td>Shadowy lockpick with daggers and a secret gold stash.</td>
</tr>
<tr>
<td>Wizard</td>
<td>Spell Slinger</td>
<td>1</td>
<td>Greyhawk</td>
<td>Robe-clad mage hurling fireballs from a messy spellbook.</td>
</tr>
<tr>
<td>Cleric</td>
<td>Divine Support</td>
<td>1</td>
<td>Ravnica</td>
<td>Holy healer with a glowing amulet and sneaky ale habit.</td>
</tr>
<tr>
<td>Bard</td>
<td>Charisma King</td>
<td>1</td>
<td>Dragonlance</td>
<td>Lute-playing charmer with magical songs and bad puns.</td>
</tr>
</table>
</wa-scroller>
<style>
#scroller__overview {
table {
margin-block: 0;
}
th,
td {
white-space: nowrap;
}
th:nth-child(5),
td:nth-child(5) {
min-width: 50ch;
white-space: wrap;
}
}
</style>
```
## Examples
### Adding Content
The scroller component automatically provides a scrollable container for any content that exceeds the available space. Simply add your content as children of the `<wa-scroller>` element, and it will handle the rest.
```html {.example}
<wa-scroller>
<div style="width: 1200px; padding: 1rem;">
<h3>Superhero Team Roles Guide</h3>
<div class="wa-grid" style="--wa-grid-columns: 4; --wa-grid-gap: var(--wa-spacing-l);">
<div>
<h4>Team Leaders</h4>
<p>Charismatic captains like Captain America or Cyclops are the heart of any superteam, rallying everyone with epic speeches and killer strategies. Theyre the ones calling the shots in a cosmic showdown, keeping the squad focused when Thanos or Magneto crashes the party.</p>
</div>
<div>
<h4>Heavy Hitters</h4>
<p>Powerhouses like Thor or Hulk bring the boom, smashing through villain lairs or alien armadas. Their job is to land the big punches, but they gotta pace themselves to avoid stealing the spotlight from sneakier teammates.</p>
</div>
<div>
<h4>Tech Geniuses</h4>
<p>Brainiacs like Iron Man or Mr. Fantastic keep the team one step ahead with gadgets and gizmos. Theyre crafting quinjets or hacking evil AI, always ready with a snarky quip while saving the day from a computer terminal.</p>
</div>
<div>
<h4>Stealth Specialists</h4>
<p>Ninja-like heroes like Black Widow or Nightcrawler slip through the shadows, gathering intel or pulling off surprise attacks. Theyre the glue that makes risky plans work, coordinating with the team to flip a losing fight into a win.</p>
</div>
</div>
</div>
</wa-scroller>
```
### Orientation
Set the `orientation` attribute to `vertical` and provide a height to create a vertical scroller.
```html {.example}
<wa-scroller orientation="vertical" style="max-height: 300px;">
<p>Superhero movies are the ultimate popcorn-fueled thrill rides, turning comic book pages into cinematic rollercoasters. Back in the early 2000s, films like X-Men and Spider-Man kicked open the door, proving tights and teamwork could pack theaters. Those early flicks leaned on practical effects and heart—like Tobey Maguires earnest web-slinger saving a train—making us believe a guy in spandex could be a hero. They werent perfect, but they set the stage for the genre to become a cultural juggernaut.</p>
<p>By the 2010s, the Marvel Cinematic Universe turned superhero films into a shared saga, like a comic crossover event on steroids. The Avengers in 2012 was a game-changer, tossing Iron Mans snark, Thors hammer, and Caps shield into one epic brawl. Directors learned to balance humor, heart, and explosions, while studios figured out how to make every movie feel like a chapter in a bigger story. Even standalone hits like Wonder Woman brought fresh vibes, with Gal Gadots lasso-wielding warrior stealing hearts and smashing box office records.</p>
<p>Today, superhero flicks are a global obsession, from Deadpools chimichanga-fueled chaos to Black Panthers Wakandan pride. Theyre not just about powers—theyre about characters we root for, like Rocket Raccoons scrappy loyalty or Harley Quinns wild energy. Fans dissect trailers like detectives, theorizing about multiverses and cameos, while memes of sad Affleck or dancing Groot flood the internet. Whether its a gritty Joker origin or a cosmic Guardians adventure, these movies keep us glued to our seats, dreaming of heroism and one-liners thatd make even Tony Stark jealous.</p>
</wa-scroller>
```
### Without a Shadow
Use the `without-shadow` attribute to remove the fading shadow effect at the edges of the scroller, which typically indicates more content is available.
```html {.example}
<wa-scroller without-shadow>
<div style="width: 1500px;">
<p>Gaming consoles are like time machines for nerds, zapping us from pixelated 2D adventures to jaw-dropping cinematic worlds. Back in the 90s, the Super Nintendo was the cool kid on the block, using a 16-bit chip to pull off tricks like Mode 7, which made Mario Karts tracks feel like they were zooming right at you. It was like wizardry for a kid with a chunky controller, turning flat sprites into pseudo-3D races that had us yelling at our TVs when we got hit by a red shell.</p>
<p>Fast-forward to today, and consoles like the PlayStation 5 and Xbox Series X are basically supercomputers in sleek boxes. Theyre packing enough power to make games look like Hollywood blockbusters, with lighting so real you can practically feel the sun glare in Spider-Man: Miles Morales. These machines can handle massive open worlds, like the sprawling lands of Elden Ring, without breaking a sweat, letting you swing swords or race cars while your living room feels like a sci-fi movie set. Its a far cry from the SNES days, but the vibes the same: pure, controller-gripping fun.</p>
<p>What makes consoles the heart of gaming culture is how they bring everyone together, from casual players to hardcore speedrunners. Whether its your uncle fumbling through Super Mario World in 92 or your best friend screaming during a late-night Call of Duty match, consoles are the ultimate couch co-op machines. Modern systems even let you stream your clutch Fortnite wins to the world or jump into crossplay with PC pals. From the GameCubes quirky handle to the Switchs grab-and-go joy-cons, every consoles got its own personality, making every era of gaming feel like a legendary chapter in a never-ending quest.</p>
</div>
</wa-scroller>
```
### Without a Scrollbar
Use the `without-scrollbar` attribute to hide the scrollbar while maintaining scroll functionality. This creates a cleaner visual appearance but may reduce usability on content that needs a clear scrolling indicator.
```html {.example}
<wa-scroller without-scrollbar>
<div style="width: 1500px;">
<p>Dungeons & Dragons 5e is the blockbuster superhero flick of tabletop RPGs, turning every session into an epic tavern brawl or dragon-slaying saga. Unlike the old 3.5e days, where youd stack +30 bonuses like a mathlete on a mission, 5e keeps things chill with skill checks capping around +11—like a +5 from your slick Charisma and +6 from being a pro at persuasion. This means even a squad of scrappy kobolds can give your level 10 barbarian a bad day if you roll poorly. Its like the games saying, “Sure, youre a hero, but dont get cocky!”</p>
<p>The advantage and disadvantage system is 5es secret sauce, making every dice roll feel like a movie cliffhanger. Instead of juggling a dozen modifiers, you just roll two d20s and take the better (or worse) one, which shakes out to about a +5 or -5 vibe shift. Its like your rogues got a lucky charm when sneaking past guards or a cursed boot when dodging a fireball. This keeps the games flow snappy, so youre not stuck crunching numbers when you could be roleplaying a dramatic speech to charm a dragon or bluffing your way out of a bandit ambush.</p>
<p>5es world is built for storytelling, not just stat sheets, and thats why its the king of game nights. The rules are flexible enough for your DM to whip up a haunted forest crawl or a pirate ship heist without needing a PhD in game design. Classes like the warlock let you make shady pacts with cosmic entities, while feats like Tavern Brawler turn your monk into a bar-fighting legend who can knock out goblins with a chair. Whether youre a newbie rolling your first d20 or a veteran plotting a castle siege, 5es vibe is all about epic moments—like when your partys wizard crits on a fireball and you all cheer like you just won the Super Bowl.</p>
</div>
</wa-scroller>
```
:::warning
Hiding scrollbars can negatively impact accessibility. Users who rely on visible scrollbars to navigate content may have difficulty recognizing that content is scrollable or controlling their scrolling position. Consider the needs of all users when implementing this option.
:::

View File

@@ -16,6 +16,7 @@ During the alpha period, things might break! We take breaking changes very serio
- 🚨 BREAKING: Renamed `<image-comparer>` to `<wa-comparer>` and improved compatibility for non-image content
- 🚨 BREAKING: Added slot detection to `<wa-dialog>` and `<wa-drawer>` so you don't need to specify `with-header` and `with-footer`; headers are on by default now, but you can use the `without-header` attribute to turn them off
- Added a new free component: `<wa-scroller>` (#1 of 14 per stretch goals)
- Added support for Duotone Thin, Light, and Regular styles and the Sharp Duotone family of styles to `<wa-icon>`
- Fixed a bug that caused `<wa-radio-group>` to have an undesired margin below it
- Fixed a bug in the Matter theme that prevented clicks on form control labels to not focus the control

View File

@@ -0,0 +1,128 @@
:host {
--shadow-color: var(--wa-color-surface-default);
--shadow-size: 2rem;
/* private (defined dynamically) */
--start-shadow-opacity: 0;
--end-shadow-opacity: 0;
display: block;
position: relative;
max-width: 100%;
isolation: isolate;
overflow: hidden;
}
:host([orientation='vertical']) {
display: flex;
flex-direction: column;
height: 100%;
}
#content {
border-radius: inherit;
scroll-behavior: smooth;
scrollbar-width: thin;
/* Prevent text in mobile Safari from being larger when the container width larger than the viewport */
-webkit-text-size-adjust: 100%;
&:focus {
outline: none;
}
&:focus-visible {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
}
:host([without-scrollbar]) #content {
scrollbar-width: none;
}
:host([orientation='horizontal']) #content {
overflow-x: auto;
overflow-y: hidden;
}
:host([orientation='vertical']) #content {
flex: 1 1 auto;
min-height: 0; /* This is crucial for flex children to respect overflow */
overflow-x: hidden;
overflow-y: auto;
}
/* Horizontal shadows */
:host([orientation='horizontal']) {
#start-shadow,
#end-shadow {
position: absolute;
top: 0;
bottom: 0;
width: var(--shadow-size);
pointer-events: none;
}
#start-shadow {
opacity: var(--start-shadow-opacity);
}
#end-shadow {
opacity: var(--end-shadow-opacity);
}
#start-shadow {
&:dir(ltr) {
left: 0;
background: linear-gradient(to right, var(--shadow-color), transparent 100%);
}
&:dir(rtl) {
right: 0;
background: linear-gradient(to left, var(--shadow-color), transparent 100%);
}
}
#end-shadow {
&:dir(ltr) {
right: 0;
background: linear-gradient(to left, var(--shadow-color), transparent 100%);
}
&:dir(rtl) {
left: 0;
background: linear-gradient(to right, var(--shadow-color), transparent 100%);
}
}
}
/* Vertical shadows */
:host([orientation='vertical']) {
#start-shadow,
#end-shadow {
position: absolute;
right: 0;
left: 0;
height: var(--shadow-size);
pointer-events: none;
}
#start-shadow {
opacity: var(--start-shadow-opacity);
}
#end-shadow {
opacity: var(--end-shadow-opacity);
}
#start-shadow {
top: 0;
background: linear-gradient(to bottom, var(--shadow-color), transparent 100%);
}
#end-shadow {
bottom: 0;
background: linear-gradient(to top, var(--shadow-color), transparent 100%);
}
}

View File

@@ -0,0 +1,10 @@
import { expect, fixture, html } from '@open-wc/testing';
import '../../../dist/webawesome.js';
describe('<wa-scroller>', () => {
it('should render a component', async () => {
const el = await fixture(html` <wa-scroller></wa-scroller> `);
expect(el).to.exist;
});
});

View File

@@ -0,0 +1,139 @@
import { html } from 'lit';
import { customElement, eventOptions, property, query, state } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import { LocalizeController } from '../../utilities/localize.js';
import styles from './scroller.css';
/**
* @summary Scrollers create an accessible container while providing visual cues that help users identify and navigate
* through content that scrolls.
* @documentation https://backers.webawesome.com/docs/components/card
* @status stable
* @since 3.0
*
* @slot - The content to show inside the scroller.
*
* @cssproperty [--shadow-color=var(--wa-color-surface-default)] - The base color of the shadow.
* @cssproperty [--shadow-size=2rem] - The size of the shadow.
*
* @csspart content - The container that wraps the slotted content.
*/
@customElement('wa-scroller')
export default class WaScroller extends WebAwesomeElement {
static shadowStyle = [styles];
private readonly localize = new LocalizeController(this);
private resizeObserver = new ResizeObserver(() => this.updateScroll());
@query('#content') content: HTMLElement;
@state() canScroll = false;
/** The scroller's orientation. */
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';
/** Removes the visible scrollbar. */
@property({ attribute: 'without-scrollbar', type: Boolean, reflect: true }) withoutScrollbar = false;
/** Removes the shadows. */
@property({ attribute: 'without-shadow', type: Boolean, reflect: true }) withoutShadow = false;
connectedCallback() {
super.connectedCallback();
this.resizeObserver.observe(this);
}
disconnectedCallback() {
super.disconnectedCallback();
this.resizeObserver.disconnect();
}
private handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Home') {
event.preventDefault();
this.content.scrollTo({
left: this.orientation === 'horizontal' ? 0 : undefined,
top: this.orientation === 'vertical' ? 0 : undefined,
});
}
if (event.key === 'End') {
event.preventDefault();
this.content.scrollTo({
left: this.orientation === 'horizontal' ? this.content.scrollWidth : undefined,
top: this.orientation === 'vertical' ? this.content.scrollHeight : undefined,
});
}
}
private handleSlotChange() {
this.updateScroll();
}
@eventOptions({ passive: true })
private updateScroll() {
if (this.orientation === 'horizontal') {
const clientWidth = Math.ceil(this.content.clientWidth);
const scrollLeft = Math.abs(Math.ceil(this.content.scrollLeft));
const scrollWidth = Math.ceil(this.content.scrollWidth);
// Calculate total scrollable width
const maxScroll = scrollWidth - clientWidth;
this.canScroll = maxScroll > 0;
// Calculate shadow opacities based on first/last 2% of scroll
const startShadowOpacity = Math.min(1, scrollLeft / (maxScroll * 0.05));
const endShadowOpacity = Math.min(1, (maxScroll - scrollLeft) / (maxScroll * 0.05));
// Update CSS custom properties
this.style.setProperty('--start-shadow-opacity', String(startShadowOpacity || 0));
this.style.setProperty('--end-shadow-opacity', String(endShadowOpacity || 0));
} else {
const clientHeight = Math.ceil(this.content.clientHeight);
const scrollTop = Math.abs(Math.ceil(this.content.scrollTop));
const scrollHeight = Math.ceil(this.content.scrollHeight);
// Calculate total scrollable height
const maxScroll = scrollHeight - clientHeight;
this.canScroll = maxScroll > 0;
// Calculate shadow opacities based on first/last 2% of scroll
const startShadowOpacity = Math.min(1, scrollTop / (maxScroll * 0.05));
const endShadowOpacity = Math.min(1, (maxScroll - scrollTop) / (maxScroll * 0.05));
// Update CSS custom properties
this.style.setProperty('--start-shadow-opacity', String(startShadowOpacity || 0));
this.style.setProperty('--end-shadow-opacity', String(endShadowOpacity || 0));
}
}
render() {
return html`
${this.withoutShadow
? ''
: html`
<div id="start-shadow" part="start-shadow" aria-hidden="true"></div>
<div id="end-shadow" part="end-shadow" aria-hidden="true"></div>
`}
<div
id="content"
part="content"
role="region"
aria-label=${this.localize.term('scrollableRegion')}
aria-orientation=${this.orientation}
tabindex=${this.canScroll ? '0' : '-1'}
@keydown=${this.handleKeyDown}
@scroll=${this.updateScroll}
>
<slot @slotchange=${this.handleSlotChange}></slot>
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'wa-scroller': WaScroller;
}
}

View File

@@ -28,6 +28,7 @@ const translation: Translation = {
progress: 'مقدار التقدم',
remove: 'حذف',
resize: 'تغيير الحجم',
scrollableRegion: 'منطقة قابلة للتمرير',
scrollToEnd: 'الانتقال الى النهاية',
scrollToStart: 'الانتقال الى البداية',
selectAColorFromTheScreen: 'اختر لون من الشاشة',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Průběh',
remove: 'Odstranit',
resize: 'Změnit velikost',
scrollableRegion: 'Posunovatelná oblast',
scrollToEnd: 'Scrollovat na konec',
scrollToStart: 'Scrollovat na začátek',
selectAColorFromTheScreen: 'Vybrat barvu z obrazovky',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Status',
remove: 'Fjern',
resize: 'Tilpas størrelse',
scrollableRegion: 'Rullebar region',
scrollToEnd: 'Scroll til slut',
scrollToStart: 'Scroll til start',
selectAColorFromTheScreen: 'Vælg en farve fra skærmen',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Fortschritt',
remove: 'Entfernen',
resize: 'Größe ändern',
scrollableRegion: 'Scrollbarer Bereich',
scrollToEnd: 'Zum Ende scrollen',
scrollToStart: 'Zum Anfang scrollen',
selectAColorFromTheScreen: 'Farbe vom Bildschirm auswählen',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Progress',
remove: 'Remove',
resize: 'Resize',
scrollableRegion: 'Scrollable region',
scrollToEnd: 'Scroll to end',
scrollToStart: 'Scroll to start',
selectAColorFromTheScreen: 'Select a color from the screen',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Progreso',
remove: 'Eliminar',
resize: 'Cambiar el tamaño',
scrollableRegion: 'Región desplazable',
scrollToEnd: 'Desplazarse hasta el final',
scrollToStart: 'Desplazarse al inicio',
selectAColorFromTheScreen: 'Seleccione un color de la pantalla',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'پیشرفت',
remove: 'حذف',
resize: 'تغییر اندازه',
scrollableRegion: 'ناحیه قابل اسکرول',
scrollToEnd: 'پیمایش به انتها',
scrollToStart: 'پیمایش به ابتدا',
selectAColorFromTheScreen: 'انتخاب یک رنگ از صفحه نمایش',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Edistyminen',
remove: 'Poista',
resize: 'Muuta kokoa',
scrollableRegion: 'Vieritettävä alue',
scrollToEnd: 'Vieritä loppuun',
scrollToStart: 'Vieritä alkuun',
selectAColorFromTheScreen: 'Valitse väri näytöltä',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Progrès',
remove: 'Retirer',
resize: 'Redimensionner',
scrollableRegion: 'Région défilante',
scrollToEnd: `Faire défiler jusqu'à la fin`,
scrollToStart: `Faire défiler jusqu'au début`,
selectAColorFromTheScreen: `Sélectionnez une couleur à l'écran`,

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'התקדמות',
remove: 'לְהַסִיר',
resize: 'שנה גודל',
scrollableRegion: 'אזור גלילה',
scrollToEnd: 'גלול עד הסוף',
scrollToStart: 'גלול להתחלה',
selectAColorFromTheScreen: 'בחור צבע מהמסך',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Napredak',
remove: 'Makni',
resize: 'Promijeni veličinu',
scrollableRegion: 'Područje s mogućnošću pomicanja',
scrollToEnd: 'Skrolaj do kraja',
scrollToStart: 'Skrolaj na početak',
selectAColorFromTheScreen: 'Odaberi boju sa ekrana',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Folyamat',
remove: 'Eltávolítás',
resize: 'Átméretezés',
scrollableRegion: 'Görgethető terület',
scrollToEnd: 'Görgessen a végére',
scrollToStart: 'Görgessen az elejére',
selectAColorFromTheScreen: 'Szín választása a képernyőről',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Kemajuan',
remove: 'Hapus',
resize: 'Ubah ukuran',
scrollableRegion: 'Area yang dapat digulir',
scrollToEnd: 'Gulir ke akhir',
scrollToStart: 'Gulir ke awal',
selectAColorFromTheScreen: 'Pilih warna dari layar',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Avanzamento',
remove: 'Rimuovi',
resize: 'Ridimensiona',
scrollableRegion: 'Area scorrevole',
scrollToEnd: 'Scorri alla fine',
scrollToStart: "Scorri all'inizio",
selectAColorFromTheScreen: 'Seleziona un colore dalla schermo',

View File

@@ -25,6 +25,7 @@ const translation: Translation = {
progress: '進行',
remove: '削除',
resize: 'サイズ変更',
scrollableRegion: 'スクロール可能領域',
scrollToEnd: '最後にスクロールする',
scrollToStart: '最初にスクロールする',
selectAColorFromTheScreen: '画面から色を選択してください',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Fremdrift',
remove: 'Fjern',
resize: 'Endre størrelse',
scrollableRegion: 'Rullbar region',
scrollToEnd: 'Rull til slutten',
scrollToStart: 'Rull til starten',
selectAColorFromTheScreen: 'Velg en farge fra skjermen',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Voortgang',
remove: 'Verwijderen',
resize: 'Formaat wijzigen',
scrollableRegion: 'Scrollbaar gebied',
scrollToEnd: 'Scroll naar einde',
scrollToStart: 'Scroll naar begin',
selectAColorFromTheScreen: 'Selecteer een kleur van het scherm',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Framdrift',
remove: 'Fjern',
resize: 'Endre storleik',
scrollableRegion: 'Rullbar region',
scrollToEnd: 'Rull til slutten',
scrollToStart: 'Rull til starten',
selectAColorFromTheScreen: 'Vel ein farge frå skjermen',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Postęp',
remove: 'Usunąć',
resize: 'Zmień rozmiar',
scrollableRegion: 'Obszar przewijalny',
scrollToEnd: 'Przewiń do końca',
scrollToStart: 'Przewiń do początku',
selectAColorFromTheScreen: 'Próbkuj z ekranu',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Progresso',
remove: 'Remover',
resize: 'Mudar o tamanho',
scrollableRegion: 'Região rolável',
scrollToEnd: 'Rolar até o final',
scrollToStart: 'Rolar até o início',
selectAColorFromTheScreen: 'Selecionar uma cor da tela',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Прогресс',
remove: 'Удалить',
resize: 'Изменить размер',
scrollableRegion: 'Scrollable region',
scrollToEnd: 'Пролистать до конца',
scrollToStart: 'Пролистать к началу',
selectAColorFromTheScreen: 'Выберите цвет на экране',

View File

@@ -28,6 +28,7 @@ const translation: Translation = {
progress: 'Napredek',
remove: 'Odstrani',
resize: 'Spremeni velikost',
scrollableRegion: 'Področje za drsenje',
scrollToEnd: 'Pomakni se na konec',
scrollToStart: 'Pomakni se na začetek',
selectAColorFromTheScreen: 'Izberite barvo z zaslona',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'Framsteg',
remove: 'Ta bort',
resize: 'Ändra storlek',
scrollableRegion: 'Scrollbart område',
scrollToEnd: 'Skrolla till slutet',
scrollToStart: 'Skrolla till början',
selectAColorFromTheScreen: 'Välj en färg från skärmen',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: 'İlerleme',
remove: 'Kaldır',
resize: 'Yeniden boyutlandır',
scrollableRegion: 'Kaydırılabilir alan',
scrollToEnd: 'Sona kay',
scrollToStart: 'Başa kay',
selectAColorFromTheScreen: 'Ekrandan bir renk seçin',

View File

@@ -28,6 +28,7 @@ const translation: Translation = {
progress: 'Поступ',
remove: 'Видалити',
resize: 'Змінити розмір',
scrollableRegion: 'Область з можливістю прокрутки',
scrollToEnd: 'Прокрутити в кінець',
scrollToStart: 'Прокрутити на початок',
selectAColorFromTheScreen: 'Виберіть колір на екрані',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: '进度',
remove: '删除',
resize: '调整大小',
scrollableRegion: '可滚动区域',
scrollToEnd: '滚动至页尾',
scrollToStart: '滚动至页首',
selectAColorFromTheScreen: '从屏幕中选择一种颜色',

View File

@@ -26,6 +26,7 @@ const translation: Translation = {
progress: '進度',
remove: '移除',
resize: '調整大小',
scrollableRegion: '可捲動区域',
scrollToEnd: '捲至頁尾',
scrollToStart: '捲至頁首',
selectAColorFromTheScreen: '從螢幕中選擇一種顏色',

View File

@@ -37,6 +37,7 @@ export interface Translation extends DefaultTranslation {
progress: string;
remove: string;
resize: string;
scrollableRegion: string;
scrollToEnd: string;
scrollToStart: string;
selectAColorFromTheScreen: string;