This commit is contained in:
Cory LaViska
2021-12-23 11:23:14 -05:00
parent 45edfeee2d
commit 2ceccd201a
14 changed files with 41 additions and 23 deletions

View File

@@ -2,7 +2,7 @@
[component-header:sl-split-panel]
Split panels display two panels alongside each other, often allowing the user to resize them.
Split panels display two adjacent panels, allowing the user to reposition them.
```html preview
<sl-split-panel>
@@ -19,7 +19,7 @@ Split panels display two panels alongside each other, often allowing the user to
### Initial Position
To set the initial position of the split in pixels, use the `position` attribute. If you need to set the initial value as a percentage, use the `setPositionPercentage()` method instead.
To set the initial position in pixels, use the `position` attribute. If you need to set the initial value as a percentage, use the `setPositionAsPercentage()` method instead. If no position is provided, it will default to half of the available space.
```html preview
<sl-split-panel position="200">
@@ -34,7 +34,7 @@ To set the initial position of the split in pixels, use the `position` attribute
### Vertical
Add the `vertical` attribute to render the split panel in a vertical orientation where the start and end panels are stacked.
Add the `vertical` attribute to render the split panel in a vertical orientation where the start and end panels are stacked. You also need to set a height when using the vertical orientation.
```html preview
<sl-split-panel vertical style="height: 400px;">
@@ -49,7 +49,7 @@ Add the `vertical` attribute to render the split panel in a vertical orientation
### Snapping
To snap panels at specific locations, add the `snap` attribute with one or more space-separated values. Values can be in pixels or percentages. For example, to snap the panel at `100px` and `50%`, use `snap="100px 50%"`. To customize how close the divider must be before snapping, use the `snap-threshold` attribute.
To snap panels at specific positions while dragging, add the `snap` attribute with one or more space-separated values. Values must be in pixels or percentages. For example, to snap the panel at `100px` and `50%`, use `snap="100px 50%"`. You can also customize how close the divider must be before snapping with the `snap-threshold` attribute.
```html preview
<div class="split-panel-snapping">
@@ -94,7 +94,7 @@ To snap panels at specific locations, add the `snap` attribute with one or more
### Disabled
Add the `disabled` attribute to prevent the split panel from being resized.
Add the `disabled` attribute to prevent the split panel from being repositioned.
```html preview
<sl-split-panel disabled>
@@ -109,13 +109,13 @@ Add the `disabled` attribute to prevent the split panel from being resized.
### Setting the Primary Panel
By default, `start` is the primary panel and `end` is the secondary panel. When the host element is resized, the primary panel will maintain its size and the secondary panel will grow or shrink to fit the remaining space. You can change the primary panel using the `primary` attribute.
By default, both panels will grow or shrink proportionally when the host element is resized. If a primary panel is designated, it will maintain its size and the secondary panel will grow or shrink to fit the remaining space. You can set the primary panel to `start` or `end` using the `primary` attribute.
Try resizing the example below with each option and notice how panels respond.
Try resizing the example below with each option and notice how the panels respond.
```html preview
<div class="split-panel-primary">
<sl-split-panel primary="start">
<sl-split-panel>
<div slot="start" style="height: 200px; background: var(--sl-color-neutral-50); display: flex; align-items: center; justify-content: center;">
Start
</div>
@@ -124,7 +124,8 @@ Try resizing the example below with each option and notice how panels respond.
</div>
</sl-split-panel>
<sl-select value="start" style="max-width: 200px; margin-top: 1rem;">
<sl-select label="Primary Panel" value="" style="max-width: 200px; margin-top: 1rem;">
<sl-menu-item value="">None</sl-menu-item>
<sl-menu-item value="start">Start</sl-menu-item>
<sl-menu-item value="end">End</sl-menu-item>
</sl-select>
@@ -156,7 +157,7 @@ To set a minimum or maximum size of the primary panel, use the `--min` and `--ma
### Nested Split Panels
Create complex layouts that can be resized independently by nesting split panels.
Create complex layouts that can be repositioned independently by nesting split panels.
```html preview
<sl-split-panel>

View File

@@ -10,6 +10,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
- 🚨 BREAKING: changed the `type` attribute to `variant` in `<sl-alert>`, `<sl-badge>`, `<sl-button>`, and `<sl-tag>` since it's more appropriate and to disambiguate from other `type` attributes
- 🚨 BREAKING: removed `base` part from `<sl-divider>` to simplify the styling API
- Added experimental `<sl-split-panel>` component
- Added `focus()` and `blur()` methods to `<sl-select>` [#625](https://github.com/shoelace-style/shoelace/pull/625)
- Fixed bug where setting `tooltipFormatter` on `<sl-range>` in JSX causes React@experimental to error out
- Added the `sl-` prefix to generated ids for `<sl-tab>` and `<sl-tab-panel>`

View File

@@ -11,8 +11,7 @@ import styles from './split-panel.styles';
* @since 2.0
* @status experimental
*
* @event sl-reposition - Emitted when the divider is repositioned.
* @event {{ entries: ResizeObserverEntry[] }} sl-resize - Emitted when the container is resized.
* @event sl-reposition - Emitted when the divider's position changes.
*
* @csspart divider - The divider that separates both panels.
*
@@ -30,6 +29,7 @@ export default class SlSplitPanel extends LitElement {
static styles = styles;
private localize = new LocalizeController(this);
private positionPercentage: number;
private resizeObserver: ResizeObserver;
private size: number;
@@ -47,10 +47,11 @@ export default class SlSplitPanel extends LitElement {
@property({ type: Boolean, reflect: true }) disabled = false;
/**
* When the host element is resized, the primary panel will maintain its size and the other panel will grow or shrink to
* fit the remaining space.
* When the host element is resized, the primary panel will maintain its size and the other panel will grow or shrink
* to fit the remaining space. If no primary panel is set, both panels will resize proportionally when the host
* element is resized.
*/
@property() primary: 'start' | 'end' = 'start';
@property() primary: 'start' | 'end';
/**
* One or more space-separated values at which the divider should snap. Values can be in pixels or percentages, e.g.
@@ -79,6 +80,8 @@ export default class SlSplitPanel extends LitElement {
if (!this.position) {
this.position = this.size / 2;
}
this.positionPercentage = this.getPositionAsPercentage();
}
handleDrag(event: Event) {
@@ -142,6 +145,7 @@ export default class SlSplitPanel extends LitElement {
}
this.position = clamp(newPosition, 0, this.size);
this.positionPercentage = this.getPositionAsPercentage();
});
}
@@ -151,7 +155,7 @@ export default class SlSplitPanel extends LitElement {
}
if (['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {
let newPercentage = this.getPositionPercentage();
let newPercentage = this.getPositionAsPercentage();
let incr = (event.shiftKey ? 10 : 1) * (this.primary === 'end' ? -1 : 1);
event.preventDefault();
@@ -174,7 +178,7 @@ export default class SlSplitPanel extends LitElement {
newPercentage = clamp(newPercentage, 0, 100);
this.setPositionPercentage(newPercentage);
this.setPositionAsPercentage(newPercentage);
}
}
@@ -187,11 +191,14 @@ export default class SlSplitPanel extends LitElement {
const { width, height } = entries[0].contentRect;
this.size = this.vertical ? height : width;
emit(this, 'sl-resize', { detail: { entries } });
// Resize proportionally when a primary panel isn't set
if (!this.primary && this.positionPercentage) {
this.setPositionAsPercentage(this.positionPercentage);
}
}
/** Gets the divider's position as a percentage of the container's size. */
getPositionPercentage() {
getPositionAsPercentage() {
if (this.size === 0) {
return 0;
}
@@ -200,7 +207,7 @@ export default class SlSplitPanel extends LitElement {
}
/** Sets the divider position as a percentage of the container's size. */
setPositionPercentage(value: number) {
setPositionAsPercentage(value: number) {
this.position = clamp(this.size * (value / 100), 0, this.size);
}
@@ -235,7 +242,7 @@ export default class SlSplitPanel extends LitElement {
class="divider"
tabindex=${ifDefined(this.disabled ? undefined : '0')}
role="separator"
aria-label=${this.localize.term('drag_to_resize')}
aria-label=${this.localize.term('resize')}
@keydown=${this.handleKeyDown}
@mousedown=${this.handleDrag}
@touchstart=${this.handleDrag}

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'Schliessen',
copy: 'Kopieren',
progress: 'Fortschritt',
resize: 'Größe ändern',
scroll_to_end: 'Zum Ende scrollen',
scroll_to_start: 'Zum Anfang scrollen',
select_a_color_from_the_screen: 'Wähle eine Farbe vom Bildschirm',

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'Schließen',
copy: 'Kopieren',
progress: 'Fortschritt',
resize: 'Größe ändern',
scroll_to_end: 'Zum Ende scrollen',
scroll_to_start: 'Zum Anfang scrollen',
select_a_color_from_the_screen: 'Wähle eine Farbe vom Bildschirm',

View File

@@ -8,8 +8,8 @@ const translation: Translation = {
close: 'Close',
copy: 'Copy',
drag_to_resize: 'Drag to resize',
progress: 'Progress',
resize: 'Resize',
scroll_to_end: 'Scroll to end',
scroll_to_start: 'Scroll to start',
select_a_color_from_the_screen: 'Select a color from the screen',

View File

@@ -8,8 +8,8 @@ const translation: Translation = {
close: 'Cerrar',
copy: 'Copiar',
drag_to_resize: 'Arrastra para cambiar el tamaño',
progress: 'Progreso',
resize: 'Cambiar el tamaño',
scroll_to_end: 'Desplazarse hasta el final',
scroll_to_start: 'Desplazarse al inicio',
select_a_color_from_the_screen: 'Seleccione un color de la pantalla',

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'Fermer',
copy: 'Copier',
progress: 'Progrès',
resize: 'Redimensionner',
scroll_to_end: `Faire défiler jusqu'à la fin`,
scroll_to_start: `Faire défiler jusqu'au début`,
select_a_color_from_the_screen: `Sélectionnez une couleur à l'écran`,

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'סגור',
copy: 'העתק',
progress: 'התקדמות',
resize: 'שנה גודל',
scroll_to_end: 'גלול עד הסוף',
scroll_to_start: 'גלול להתחלה',
select_a_color_from_the_screen: 'בחור צבע מהמסך',

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: '閉じる',
copy: 'コピー',
progress: '進行',
resize: 'サイズ変更',
scroll_to_end: '最後にスクロールする',
scroll_to_start: '最初にスクロールする',
select_a_color_from_the_screen: '画面から色を選択してください',

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'Sluiten',
copy: 'Kopiëren',
progress: 'Voortgang',
resize: 'Formaat wijzigen',
scroll_to_end: 'Scroll naar einde',
scroll_to_start: 'Scroll naar begin',
select_a_color_from_the_screen: 'Selecteer een kleur van het scherm',

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'Zamknij',
copy: 'Kopiuj',
progress: 'Postęp',
resize: 'Zmień rozmiar',
scroll_to_end: 'Przewiń do końca',
scroll_to_start: 'Przewiń do początku',
select_a_color_from_the_screen: 'Próbkuj z ekranu',

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'Fechar',
copy: 'Copiar',
progress: 'Progresso',
resize: 'Mudar o tamanho',
scroll_to_end: 'Rolar até o final',
scroll_to_start: 'Rolar até o começo',
select_a_color_from_the_screen: 'Selecionar uma cor da tela',

View File

@@ -9,6 +9,7 @@ const translation: Translation = {
close: 'Закрыть',
copy: 'Скопировать',
progress: 'Прогресс',
resize: 'Изменить размер',
scroll_to_end: 'Пролистать до конца',
scroll_to_start: 'Пролистать к началу',
select_a_color_from_the_screen: 'Выберите цвет на экране',