@vaadin/split-layout 25.3.0-alpha2 → 25.3.0-alpha3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -79,9 +79,28 @@
79
79
  "declarations": [
80
80
  {
81
81
  "kind": "class",
82
- "description": "`<vaadin-split-layout>` is a Web Component implementing a split layout for two\ncontent elements with a draggable splitter between them.\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\n### Horizontal and Vertical Layouts\n\nBy default, the split's orientation is horizontal, meaning that the content elements are\npositioned side by side in a flex container with a horizontal layout.\n\nYou can change the split mode to vertical by setting the `orientation` attribute to `\"vertical\"`:\n\n```html\n<vaadin-split-layout orientation=\"vertical\">\n <div>Content on the top</div>\n <div>Content on the bottom</div>\n</vaadin-split-layout>\n```\n\n### Layouts Combination\n\nFor the layout contents, we usually use `<div>` elements in the examples,\nalthough you can use any other elements as well.\n\nFor instance, in order to have a nested vertical split layout inside a\nhorizontal one, you can include `<vaadin-split-layout>` as a content element\ninside another split layout:\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <vaadin-split-layout orientation=\"vertical\">\n <div>Second content element</div>\n <div>Third content element</div>\n </vaadin-split-layout>\n</vaadin-split-layout>\n```\n\nYou can also trigger the vertical mode in JavaScript by setting the property:\n`splitLayout.orientation = \"vertical\";`.\n\n### Split Layout Element Height\n\n`<vaadin-split-layout>` element itself is a flex container. It does not inherit\nthe parent height by default, but rather sets its height depending on the\ncontent.\n\nYou can use CSS to set the fixed height for the split layout, as usual with any\nblock element:\n\n```html\n<vaadin-split-layout style=\"height: 200px;\">\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\nIt is possible to define percentage height as well. Note that you have to set\nthe parent height in order to make percentages work correctly. In the following\nexample, the `<body>` is resized to fill the entire viewport, and the\n`<vaadin-split-layout>` element is set to take 100% height of the `<body>`:\n\n```html\n<body style=\"height: 100vh; margin: 0;\">\n <vaadin-split-layout style=\"height: 100%;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\nAlternatively, you can use a flexbox layout to make `<vaadin-split-layout>`\nfill up the parent:\n\n```html\n<body style=\"height: 100vh; margin: 0; display: flex;\">\n <vaadin-split-layout style=\"flex: 1;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\n### Initial Splitter Position\n\nThe initial splitter position is determined from the sizes of the content elements\ninside the split layout. Therefore, changing `width` on the content elements\naffects the initial splitter position for the horizontal layouts, while `height`\naffects the vertical ones.\n\nNote that when the total size of the content elements does not fit the layout,\nthe content elements are scaled proportionally.\n\nWhen setting initial sizes with relative units, such as percentages, it is\nrecommended to assign the size for both content elements:\n\n```html\n<vaadin-split-layout>\n <div style=\"width: 75%;\">Three fourths</div>\n <div style=\"width: 25%;\">One fourth</div>\n</vaadin-split-layout>\n```\n\n### Size Limits\n\nThe `min-width`/`min-height`, and `max-width`/`max-height` CSS size values\nfor the content elements are respected and used to limit the splitter position\nwhen it is dragged.\n\nIt is preferred to set the limits only for a single content element, in order\nto avoid size conflicts:\n\n```html\n<vaadin-split-layout>\n <div style=\"min-width: 50px; max-width: 150px;\">First</div>\n <div>Second</div>\n</vaadin-split-layout>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------|--------------\n`splitter` | Split element\n`handle` | The handle of the splitter\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:----------------------------------------------|\n| `--vaadin-split-layout-handle-size` |\n| `--vaadin-split-layout-handle-target-size` |\n| `--vaadin-split-layout-splitter-background` |\n| `--vaadin-split-layout-splitter-size` |\n| `--vaadin-split-layout-splitter-target-size` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
82
+ "description": "`<vaadin-split-layout>` is a Web Component implementing a split layout for two\ncontent elements with a draggable splitter between them.\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\n### Horizontal and Vertical Layouts\n\nBy default, the split's orientation is horizontal, meaning that the content elements are\npositioned side by side in a flex container with a horizontal layout.\n\nYou can change the split mode to vertical by setting the `orientation` attribute to `\"vertical\"`:\n\n```html\n<vaadin-split-layout orientation=\"vertical\">\n <div>Content on the top</div>\n <div>Content on the bottom</div>\n</vaadin-split-layout>\n```\n\n### Layouts Combination\n\nFor the layout contents, we usually use `<div>` elements in the examples,\nalthough you can use any other elements as well.\n\nFor instance, in order to have a nested vertical split layout inside a\nhorizontal one, you can include `<vaadin-split-layout>` as a content element\ninside another split layout:\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <vaadin-split-layout orientation=\"vertical\">\n <div>Second content element</div>\n <div>Third content element</div>\n </vaadin-split-layout>\n</vaadin-split-layout>\n```\n\nYou can also trigger the vertical mode in JavaScript by setting the property:\n`splitLayout.orientation = \"vertical\";`.\n\n### Split Layout Element Height\n\n`<vaadin-split-layout>` element itself is a flex container. It does not inherit\nthe parent height by default, but rather sets its height depending on the\ncontent.\n\nYou can use CSS to set the fixed height for the split layout, as usual with any\nblock element:\n\n```html\n<vaadin-split-layout style=\"height: 200px;\">\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\nIt is possible to define percentage height as well. Note that you have to set\nthe parent height in order to make percentages work correctly. In the following\nexample, the `<body>` is resized to fill the entire viewport, and the\n`<vaadin-split-layout>` element is set to take 100% height of the `<body>`:\n\n```html\n<body style=\"height: 100vh; margin: 0;\">\n <vaadin-split-layout style=\"height: 100%;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\nAlternatively, you can use a flexbox layout to make `<vaadin-split-layout>`\nfill up the parent:\n\n```html\n<body style=\"height: 100vh; margin: 0; display: flex;\">\n <vaadin-split-layout style=\"flex: 1;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\n### Initial Splitter Position\n\nThe initial splitter position is determined from the sizes of the content elements\ninside the split layout. Therefore, changing `width` on the content elements\naffects the initial splitter position for the horizontal layouts, while `height`\naffects the vertical ones.\n\nNote that when the total size of the content elements does not fit the layout,\nthe content elements are scaled proportionally.\n\nWhen setting initial sizes with relative units, such as percentages, it is\nrecommended to assign the size for both content elements:\n\n```html\n<vaadin-split-layout>\n <div style=\"width: 75%;\">Three fourths</div>\n <div style=\"width: 25%;\">One fourth</div>\n</vaadin-split-layout>\n```\n\n### Size Limits\n\nThe `min-width`/`min-height`, and `max-width`/`max-height` CSS size values\nfor the content elements are respected and used to limit the splitter position\nwhen it is dragged.\n\nIt is preferred to set the limits only for a single content element, in order\nto avoid size conflicts:\n\n```html\n<vaadin-split-layout>\n <div style=\"min-width: 50px; max-width: 150px;\">First</div>\n <div>Second</div>\n</vaadin-split-layout>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------|--------------\n`splitter` | Split element\n`handle` | The handle of the splitter\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|------------\n`focus-ring` | Set when the splitter is focused using the keyboard\n`focused` | Set when the splitter is focused\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:----------------------------------------------|\n| `--vaadin-split-layout-handle-size` |\n| `--vaadin-split-layout-handle-target-size` |\n| `--vaadin-split-layout-splitter-background` |\n| `--vaadin-split-layout-splitter-size` |\n| `--vaadin-split-layout-splitter-target-size` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Keyboard Interaction\n\nThe splitter is focusable and can be moved with the keyboard:\n\nKey | Action\n-----------------------------|--------------\n`Arrow Down` / `Arrow Right` | Grow the primary content element by a small step\n`Arrow Up` / `Arrow Left` | Shrink the primary content element by a small step\n`Page Up` / `Page Down` | Grow / shrink by a larger step (10% of the available size)\n`Home` / `End` | Collapse the primary / secondary content element",
83
83
  "name": "SplitLayout",
84
84
  "members": [
85
+ {
86
+ "kind": "field",
87
+ "name": "i18n",
88
+ "privacy": "public",
89
+ "type": {
90
+ "text": "Object"
91
+ },
92
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following JSON structure and default values:\n\n```\n{\n // Accessible label of the resize separator.\n separator: 'Resize separator'\n}\n```",
93
+ "attribute": "i18n",
94
+ "return": {
95
+ "type": {
96
+ "text": "!Object"
97
+ }
98
+ },
99
+ "inheritedFrom": {
100
+ "name": "I18nMixin",
101
+ "package": "@vaadin/component-base/src/i18n-mixin.js"
102
+ }
103
+ },
85
104
  {
86
105
  "kind": "field",
87
106
  "name": "orientation",
@@ -103,7 +122,7 @@
103
122
  "type": {
104
123
  "text": "CustomEvent"
105
124
  },
106
- "description": "Fired after dragging the splitter have ended.",
125
+ "description": "Fired after resizing the splitter via pointer or keyboard has ended.",
107
126
  "inheritedFrom": {
108
127
  "name": "SplitLayoutMixin",
109
128
  "module": "src/vaadin-split-layout-mixin.js"
@@ -115,6 +134,18 @@
115
134
  "name": "SplitLayoutMixin",
116
135
  "module": "src/vaadin-split-layout-mixin.js"
117
136
  },
137
+ {
138
+ "name": "I18nMixin",
139
+ "package": "@vaadin/component-base/src/i18n-mixin.js"
140
+ },
141
+ {
142
+ "name": "FocusMixin",
143
+ "package": "@vaadin/a11y-base/src/focus-mixin.js"
144
+ },
145
+ {
146
+ "name": "KeyboardMixin",
147
+ "package": "@vaadin/a11y-base/src/keyboard-mixin.js"
148
+ },
118
149
  {
119
150
  "name": "ElementMixin",
120
151
  "package": "@vaadin/component-base/src/element-mixin.js"
@@ -139,6 +170,18 @@
139
170
  "tagName": "vaadin-split-layout",
140
171
  "customElement": true,
141
172
  "attributes": [
173
+ {
174
+ "name": "i18n",
175
+ "type": {
176
+ "text": "Object"
177
+ },
178
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nShould be overridden by subclasses to provide a custom JSDoc with the\ndefault I18N properties.",
179
+ "fieldName": "i18n",
180
+ "inheritedFrom": {
181
+ "name": "I18nMixin",
182
+ "package": "@vaadin/component-base/src/i18n-mixin.js"
183
+ }
184
+ },
142
185
  {
143
186
  "name": "orientation",
144
187
  "type": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/split-layout",
3
- "version": "25.3.0-alpha2",
3
+ "version": "25.3.0-alpha3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -35,16 +35,17 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "@open-wc/dedupe-mixin": "^1.3.0",
38
- "@vaadin/component-base": "25.3.0-alpha2",
39
- "@vaadin/vaadin-themable-mixin": "25.3.0-alpha2",
38
+ "@vaadin/a11y-base": "25.3.0-alpha3",
39
+ "@vaadin/component-base": "25.3.0-alpha3",
40
+ "@vaadin/vaadin-themable-mixin": "25.3.0-alpha3",
40
41
  "lit": "^3.0.0"
41
42
  },
42
43
  "devDependencies": {
43
- "@vaadin/aura": "25.3.0-alpha2",
44
- "@vaadin/chai-plugins": "25.3.0-alpha2",
45
- "@vaadin/test-runner-commands": "25.3.0-alpha2",
44
+ "@vaadin/aura": "25.3.0-alpha3",
45
+ "@vaadin/chai-plugins": "25.3.0-alpha3",
46
+ "@vaadin/test-runner-commands": "25.3.0-alpha3",
46
47
  "@vaadin/testing-helpers": "^2.0.0",
47
- "@vaadin/vaadin-lumo-styles": "25.3.0-alpha2",
48
+ "@vaadin/vaadin-lumo-styles": "25.3.0-alpha3",
48
49
  "sinon": "^22.0.0"
49
50
  },
50
51
  "customElements": "custom-elements.json",
@@ -52,5 +53,5 @@
52
53
  "web-types.json",
53
54
  "web-types.lit.json"
54
55
  ],
55
- "gitHead": "52eba6153ecf8bfaae44bcb727595e77d90b963c"
56
+ "gitHead": "ba0c4c55ea219eadd9aefe244f53e87803a066c8"
56
57
  }
@@ -36,7 +36,8 @@ export const splitLayoutStyles = css`
36
36
  --_splitter-target-size: var(--vaadin-split-layout-splitter-target-size, 8px);
37
37
  --_handle-size: var(--vaadin-split-layout-handle-size, 4px);
38
38
  --_handle-target-size: var(--vaadin-split-layout-handle-target-size, 32px);
39
- background: var(--vaadin-split-layout-splitter-background, var(--vaadin-background-container-strong));
39
+ --_splitter-background: var(--vaadin-split-layout-splitter-background, var(--vaadin-background-container-strong));
40
+ background: var(--_splitter-background);
40
41
  flex: none;
41
42
  position: relative;
42
43
  z-index: 1;
@@ -44,19 +45,21 @@ export const splitLayoutStyles = css`
44
45
  display: flex;
45
46
  align-items: center;
46
47
  justify-content: center;
48
+ outline: none;
47
49
  }
48
50
 
49
51
  [part='splitter']::after {
50
52
  content: '';
51
53
  inset: 0 calc((var(--_splitter-target-size) - var(--_splitter-size)) / -2);
52
54
  position: absolute;
55
+ z-index: -1;
53
56
  }
54
57
 
55
58
  :host([orientation='vertical']) [part='splitter']::after {
56
59
  inset: calc((var(--_splitter-target-size) - var(--_splitter-size)) / -2) 0;
57
60
  }
58
61
 
59
- :host(:not([orientation='vertical'])) > [part='splitter'] {
62
+ :host([orientation='horizontal']) > [part='splitter'] {
60
63
  cursor: ew-resize;
61
64
  width: var(--_splitter-size);
62
65
  }
@@ -66,6 +69,18 @@ export const splitLayoutStyles = css`
66
69
  height: var(--_splitter-size);
67
70
  }
68
71
 
72
+ :host([focus-ring]) [part='splitter']::after {
73
+ outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
74
+ }
75
+
76
+ :host([orientation='horizontal'][focus-ring]) [part='splitter']::after {
77
+ inset-block: var(--vaadin-focus-ring-width, 2px);
78
+ }
79
+
80
+ :host([orientation='vertical'][focus-ring]) [part='splitter']::after {
81
+ inset-inline: var(--vaadin-focus-ring-width, 2px);
82
+ }
83
+
69
84
  [part='handle'] {
70
85
  background: var(--vaadin-split-layout-handle-background, var(--vaadin-text-color-secondary));
71
86
  border-radius: var(--vaadin-radius-m);
@@ -100,11 +115,21 @@ export const splitLayoutStyles = css`
100
115
  --vaadin-split-layout-handle-size: 3px;
101
116
  }
102
117
 
118
+ :host([theme~='small'][focus-ring]) > [part='splitter'] {
119
+ background: transparent;
120
+
121
+ &::after {
122
+ background: linear-gradient(var(--_splitter-background), var(--_splitter-background))
123
+ var(--vaadin-background-color);
124
+ }
125
+ }
126
+
103
127
  :host([theme~='small']) [part='splitter'] [part='handle'] {
104
128
  opacity: 0;
105
129
  }
106
130
 
107
- :host([theme~='small']) [part='splitter']:active [part='handle'] {
131
+ :host([theme~='small']) [part='splitter']:active [part='handle'],
132
+ :host([theme~='small'][focus-ring]) [part='splitter'] [part='handle'] {
108
133
  opacity: 1;
109
134
  }
110
135
 
@@ -3,8 +3,16 @@
3
3
  * Copyright (c) 2016 - 2026 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import { timeOut } from '@vaadin/component-base/src/async.js';
7
+ import { Debouncer } from '@vaadin/component-base/src/debounce.js';
6
8
  import { addListener } from '@vaadin/component-base/src/gestures.js';
7
9
 
10
+ // Step in pixels used for resizing with the arrow keys.
11
+ const ARROW_STEP = 16;
12
+
13
+ // Fraction of the available size used for resizing with the Page Up / Page Down keys.
14
+ const PAGE_STEP = 0.1;
15
+
8
16
  export const SplitLayoutMixin = (superClass) =>
9
17
  class SplitLayoutMixin extends superClass {
10
18
  static get properties() {
@@ -23,6 +31,14 @@ export const SplitLayoutMixin = (superClass) =>
23
31
 
24
32
  /** @private */
25
33
  _previousSecondaryPointerEvents: String,
34
+
35
+ /**
36
+ * The primary content element size as a percentage.
37
+ * @private
38
+ */
39
+ __valueNow: {
40
+ type: Number,
41
+ },
26
42
  };
27
43
  }
28
44
 
@@ -38,14 +54,154 @@ export const SplitLayoutMixin = (superClass) =>
38
54
  });
39
55
 
40
56
  this._processChildren();
57
+ this.__updateValueNow();
41
58
  });
42
59
 
43
60
  this.__observer.observe(this, { childList: true });
44
61
 
45
62
  const splitter = this.$.splitter;
46
63
  addListener(splitter, 'track', this._onHandleTrack.bind(this));
47
- addListener(splitter, 'down', this._setPointerEventsNone.bind(this));
48
- addListener(splitter, 'up', this._restorePointerEvents.bind(this));
64
+ addListener(splitter, 'down', this.__onSplitterDown.bind(this));
65
+ addListener(splitter, 'up', this.__onSplitterUp.bind(this));
66
+ }
67
+
68
+ /** @protected */
69
+ updated(props) {
70
+ super.updated(props);
71
+
72
+ if (props.has('orientation')) {
73
+ this.__updateValueNow();
74
+ }
75
+ }
76
+
77
+ /** @protected */
78
+ disconnectedCallback() {
79
+ super.disconnectedCallback();
80
+
81
+ this.__dragEndDebouncer?.cancel();
82
+ }
83
+
84
+ /**
85
+ * @param {FocusOptions=} options
86
+ * @protected
87
+ * @override
88
+ */
89
+ focus(options) {
90
+ this.$?.splitter?.focus(options);
91
+
92
+ super.focus(options);
93
+ }
94
+
95
+ /**
96
+ * Override method inherited from `FocusMixin`
97
+ * to only handle events from the splitter.
98
+ *
99
+ * @param {FocusEvent} event
100
+ * @return {boolean}
101
+ * @protected
102
+ * @override
103
+ */
104
+ _shouldSetFocus(event) {
105
+ return event.composedPath()[0] === this.$.splitter;
106
+ }
107
+
108
+ /**
109
+ * Override method inherited from `FocusMixin`
110
+ * to only handle events from the splitter.
111
+ *
112
+ * @param {FocusEvent} event
113
+ * @return {boolean}
114
+ * @protected
115
+ * @override
116
+ */
117
+ _shouldRemoveFocus(event) {
118
+ return event.relatedTarget !== this.$.splitter;
119
+ }
120
+
121
+ /**
122
+ * Override method inherited from `KeyboardMixin` to resize the layout when
123
+ * the splitter is focused and an arrow, page or home/end key is pressed.
124
+ *
125
+ * @param {KeyboardEvent} event
126
+ * @protected
127
+ * @override
128
+ */
129
+ _onKeyDown(event) {
130
+ if (event.composedPath()[0] !== this.$.splitter || !this._primaryChild || !this._secondaryChild) {
131
+ return;
132
+ }
133
+
134
+ const { container, primary } = this.__getSizes();
135
+ let newPrimary = primary;
136
+
137
+ switch (event.key) {
138
+ case 'ArrowDown':
139
+ newPrimary = primary + ARROW_STEP;
140
+ break;
141
+ case 'ArrowUp':
142
+ newPrimary = primary - ARROW_STEP;
143
+ break;
144
+ case 'ArrowRight':
145
+ newPrimary = primary + (this.__isRTL ? -ARROW_STEP : ARROW_STEP);
146
+ break;
147
+ case 'ArrowLeft':
148
+ newPrimary = primary + (this.__isRTL ? ARROW_STEP : -ARROW_STEP);
149
+ break;
150
+ case 'PageDown':
151
+ newPrimary = primary + container * PAGE_STEP;
152
+ break;
153
+ case 'PageUp':
154
+ newPrimary = primary - container * PAGE_STEP;
155
+ break;
156
+ case 'Home':
157
+ newPrimary = 0;
158
+ break;
159
+ case 'End':
160
+ newPrimary = container;
161
+ break;
162
+ default:
163
+ return;
164
+ }
165
+
166
+ event.preventDefault();
167
+ event.stopPropagation();
168
+
169
+ // Force focus-ring if focused earlier with a pointer
170
+ this.toggleAttribute('focus-ring', true);
171
+
172
+ this._setFlexBasis(this._primaryChild, newPrimary, container);
173
+ this._setFlexBasis(this._secondaryChild, container - newPrimary, container);
174
+ this.__updateValueNow();
175
+
176
+ this.__dragEndDebouncer = Debouncer.debounce(this.__dragEndDebouncer, timeOut.after(200), () => {
177
+ this.dispatchEvent(new CustomEvent('splitter-dragend'));
178
+ });
179
+ }
180
+
181
+ /**
182
+ * Returns the available container size and the current content element sizes
183
+ * in pixels, measured along the resize axis. Sizes are read from the rendered
184
+ * layout on every call so that CSS min/max limits are always respected.
185
+ *
186
+ * @return {{ container: number, primary: number, secondary: number }}
187
+ * @private
188
+ */
189
+ __getSizes() {
190
+ const size = this.orientation === 'vertical' ? 'height' : 'width';
191
+ return {
192
+ container: this.getBoundingClientRect()[size] - this.$.splitter.getBoundingClientRect()[size],
193
+ primary: this._primaryChild.getBoundingClientRect()[size],
194
+ secondary: this._secondaryChild.getBoundingClientRect()[size],
195
+ };
196
+ }
197
+
198
+ /** @private */
199
+ __updateValueNow() {
200
+ if (!this._primaryChild || !this._secondaryChild) {
201
+ return;
202
+ }
203
+ const { container, primary } = this.__getSizes();
204
+ this.__valueNow = container > 0 ? Math.round((primary / container) * 100) : 0;
49
205
  }
50
206
 
51
207
  /** @private */
@@ -108,7 +264,10 @@ export const SplitLayoutMixin = (superClass) =>
108
264
  }
109
265
 
110
266
  /** @private */
111
- _setPointerEventsNone(event) {
267
+ __onSplitterDown(event) {
268
+ // Reset the drag flag on every new pointer interaction.
269
+ this.__dragged = false;
270
+
112
271
  if (!this._primaryChild || !this._secondaryChild) {
113
272
  return;
114
273
  }
@@ -121,7 +280,13 @@ export const SplitLayoutMixin = (superClass) =>
121
280
  }
122
281
 
123
282
  /** @private */
124
- _restorePointerEvents() {
283
+ __onSplitterUp() {
284
+ // Focus the splitter on a plain click so it can be moved with the keyboard,
285
+ // but not after a drag, to avoid moving focus away from where the user was.
286
+ if (!this.__dragged) {
287
+ this.$.splitter.focus({ preventScroll: true });
288
+ }
289
+
125
290
  if (!this._primaryChild || !this._secondaryChild) {
126
291
  return;
127
292
  }
@@ -135,13 +300,9 @@ export const SplitLayoutMixin = (superClass) =>
135
300
  return;
136
301
  }
137
302
 
138
- const size = this.orientation === 'vertical' ? 'height' : 'width';
139
303
  if (event.detail.state === 'start') {
140
- this._startSize = {
141
- container: this.getBoundingClientRect()[size] - this.$.splitter.getBoundingClientRect()[size],
142
- primary: this._primaryChild.getBoundingClientRect()[size],
143
- secondary: this._secondaryChild.getBoundingClientRect()[size],
144
- };
304
+ this.__dragged = true;
305
+ this._startSize = this.__getSizes();
145
306
 
146
307
  return;
147
308
  }
@@ -152,6 +313,7 @@ export const SplitLayoutMixin = (superClass) =>
152
313
 
153
314
  this._setFlexBasis(this._primaryChild, this._startSize.primary + dirDistance, this._startSize.container);
154
315
  this._setFlexBasis(this._secondaryChild, this._startSize.secondary - dirDistance, this._startSize.container);
316
+ this.__updateValueNow();
155
317
 
156
318
  if (event.detail.state === 'end') {
157
319
  this.dispatchEvent(new CustomEvent('splitter-dragend'));
@@ -3,10 +3,17 @@
3
3
  * Copyright (c) 2016 - 2026 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
7
+ import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js';
6
8
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
9
+ import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
7
10
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
11
  import { SplitLayoutMixin } from './vaadin-split-layout-mixin.js';
9
12
 
13
+ export interface SplitLayoutI18n {
14
+ separator?: string;
15
+ }
16
+
10
17
  export interface SplitLayoutCustomEventMap {
11
18
  'splitter-dragend': Event;
12
19
  }
@@ -147,6 +154,13 @@ export interface SplitLayoutEventMap extends HTMLElementEventMap, SplitLayoutCus
147
154
  * `splitter` | Split element
148
155
  * `handle` | The handle of the splitter
149
156
  *
157
+ * The following state attributes are available for styling:
158
+ *
159
+ * Attribute | Description
160
+ * ---------------|------------
161
+ * `focus-ring` | Set when the splitter is focused using the keyboard
162
+ * `focused` | Set when the splitter is focused
163
+ *
150
164
  * The following custom CSS properties are available for styling:
151
165
  *
152
166
  * Custom CSS property |
@@ -159,9 +173,38 @@ export interface SplitLayoutEventMap extends HTMLElementEventMap, SplitLayoutCus
159
173
  *
160
174
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
161
175
  *
162
- * @fires {Event} splitter-dragend - Fired after dragging the splitter have ended.
176
+ * ### Keyboard Interaction
177
+ *
178
+ * The splitter is focusable and can be moved with the keyboard:
179
+ *
180
+ * Key | Action
181
+ * -----------------------------|--------------
182
+ * `Arrow Down` / `Arrow Right` | Grow the primary content element by a small step
183
+ * `Arrow Up` / `Arrow Left` | Shrink the primary content element by a small step
184
+ * `Page Up` / `Page Down` | Grow / shrink by a larger step (10% of the available size)
185
+ * `Home` / `End` | Collapse the primary / secondary content element
186
+ *
187
+ * @fires {Event} splitter-dragend - Fired after resizing the splitter via pointer or keyboard has ended.
163
188
  */
164
- declare class SplitLayout extends SplitLayoutMixin(ElementMixin(ThemableMixin(HTMLElement))) {
189
+ declare class SplitLayout extends SplitLayoutMixin(
190
+ FocusMixin(KeyboardMixin(ElementMixin(ThemableMixin(I18nMixin<typeof HTMLElement, SplitLayoutI18n>(HTMLElement))))),
191
+ ) {
192
+ /**
193
+ * The object used to localize this component. To change the default
194
+ * localization, replace this with an object that provides all properties, or
195
+ * just the individual properties you want to change.
196
+ *
197
+ * The object has the following JSON structure and default values:
198
+ *
199
+ * ```
200
+ * {
201
+ * // Accessible label of the resize separator.
202
+ * separator: 'Resize separator'
203
+ * }
204
+ * ```
205
+ */
206
+ i18n: SplitLayoutI18n;
207
+
165
208
  addEventListener<K extends keyof SplitLayoutEventMap>(
166
209
  type: K,
167
210
  listener: (this: SplitLayout, ev: SplitLayoutEventMap[K]) => void,
@@ -4,14 +4,22 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { html, LitElement } from 'lit';
7
+ import { ifDefined } from 'lit/directives/if-defined.js';
8
+ import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
9
+ import { KeyboardMixin } from '@vaadin/a11y-base/src/keyboard-mixin.js';
7
10
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
11
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
12
+ import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
9
13
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
14
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
11
15
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
12
16
  import { splitLayoutStyles } from './styles/vaadin-split-layout-base-styles.js';
13
17
  import { SplitLayoutMixin } from './vaadin-split-layout-mixin.js';
14
18
 
19
+ const DEFAULT_I18N = {
20
+ separator: 'Resize separator',
21
+ };
22
+
15
23
  /**
16
24
  * `<vaadin-split-layout>` is a Web Component implementing a split layout for two
17
25
  * content elements with a draggable splitter between them.
@@ -146,6 +154,13 @@ import { SplitLayoutMixin } from './vaadin-split-layout-mixin.js';
146
154
  * `splitter` | Split element
147
155
  * `handle` | The handle of the splitter
148
156
  *
157
+ * The following state attributes are available for styling:
158
+ *
159
+ * Attribute | Description
160
+ * ---------------|------------
161
+ * `focus-ring` | Set when the splitter is focused using the keyboard
162
+ * `focused` | Set when the splitter is focused
163
+ *
149
164
  * The following custom CSS properties are available for styling:
150
165
  *
151
166
  * Custom CSS property |
@@ -158,12 +173,25 @@ import { SplitLayoutMixin } from './vaadin-split-layout-mixin.js';
158
173
  *
159
174
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
160
175
  *
161
- * @fires {Event} splitter-dragend - Fired after dragging the splitter have ended.
176
+ * ### Keyboard Interaction
177
+ *
178
+ * The splitter is focusable and can be moved with the keyboard:
179
+ *
180
+ * Key | Action
181
+ * -----------------------------|--------------
182
+ * `Arrow Down` / `Arrow Right` | Grow the primary content element by a small step
183
+ * `Arrow Up` / `Arrow Left` | Shrink the primary content element by a small step
184
+ * `Page Up` / `Page Down` | Grow / shrink by a larger step (10% of the available size)
185
+ * `Home` / `End` | Collapse the primary / secondary content element
186
+ *
187
+ * @fires {Event} splitter-dragend - Fired after resizing the splitter via pointer or keyboard has ended.
162
188
  *
163
189
  * @customElement vaadin-split-layout
164
190
  * @extends HTMLElement
165
191
  */
166
- class SplitLayout extends SplitLayoutMixin(ElementMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
192
+ class SplitLayout extends SplitLayoutMixin(
193
+ I18nMixin(FocusMixin(KeyboardMixin(ElementMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))))),
194
+ ) {
167
195
  static get is() {
168
196
  return 'vaadin-split-layout';
169
197
  }
@@ -176,11 +204,51 @@ class SplitLayout extends SplitLayoutMixin(ElementMixin(ThemableMixin(PolylitMix
176
204
  return { ...super.lumoInjector, includeBaseStyles: true };
177
205
  }
178
206
 
207
+ static get defaultI18n() {
208
+ return DEFAULT_I18N;
209
+ }
210
+
211
+ /**
212
+ * The object used to localize this component. To change the default
213
+ * localization, replace this with an object that provides all properties, or
214
+ * just the individual properties you want to change.
215
+ *
216
+ * The object has the following JSON structure and default values:
217
+ *
218
+ * ```
219
+ * {
220
+ * // Accessible label of the resize separator.
221
+ * separator: 'Resize separator'
222
+ * }
223
+ * ```
224
+ *
225
+ * @return {!Object}
226
+ */
227
+ get i18n() {
228
+ return super.i18n;
229
+ }
230
+
231
+ set i18n(value) {
232
+ super.i18n = value;
233
+ }
234
+
179
235
  /** @protected */
180
236
  render() {
181
237
  return html`
182
238
  <slot id="primary" name="primary"></slot>
183
- <div part="splitter" id="splitter">
239
+ <div
240
+ part="splitter"
241
+ id="splitter"
242
+ role="slider"
243
+ tabindex="0"
244
+ aria-label="${this.__effectiveI18n.separator}"
245
+ aria-valuemin="0"
246
+ aria-valuemax="100"
247
+ aria-valuenow="${ifDefined(this.__valueNow)}"
248
+ aria-valuetext="${ifDefined(this.__valueNow === undefined ? undefined : `${this.__valueNow}%`)}"
249
+ aria-orientation="${this.orientation === 'vertical' ? 'vertical' : 'horizontal'}"
250
+ @focusin="${this.__updateValueNow}"
251
+ >
184
252
  <div part="handle"></div>
185
253
  </div>
186
254
  <slot id="secondary" name="secondary"></slot>
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/split-layout",
4
- "version": "25.3.0-alpha2",
4
+ "version": "25.3.0-alpha3",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-split-layout",
11
- "description": "`<vaadin-split-layout>` is a Web Component implementing a split layout for two\ncontent elements with a draggable splitter between them.\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\n### Horizontal and Vertical Layouts\n\nBy default, the split's orientation is horizontal, meaning that the content elements are\npositioned side by side in a flex container with a horizontal layout.\n\nYou can change the split mode to vertical by setting the `orientation` attribute to `\"vertical\"`:\n\n```html\n<vaadin-split-layout orientation=\"vertical\">\n <div>Content on the top</div>\n <div>Content on the bottom</div>\n</vaadin-split-layout>\n```\n\n### Layouts Combination\n\nFor the layout contents, we usually use `<div>` elements in the examples,\nalthough you can use any other elements as well.\n\nFor instance, in order to have a nested vertical split layout inside a\nhorizontal one, you can include `<vaadin-split-layout>` as a content element\ninside another split layout:\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <vaadin-split-layout orientation=\"vertical\">\n <div>Second content element</div>\n <div>Third content element</div>\n </vaadin-split-layout>\n</vaadin-split-layout>\n```\n\nYou can also trigger the vertical mode in JavaScript by setting the property:\n`splitLayout.orientation = \"vertical\";`.\n\n### Split Layout Element Height\n\n`<vaadin-split-layout>` element itself is a flex container. It does not inherit\nthe parent height by default, but rather sets its height depending on the\ncontent.\n\nYou can use CSS to set the fixed height for the split layout, as usual with any\nblock element:\n\n```html\n<vaadin-split-layout style=\"height: 200px;\">\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\nIt is possible to define percentage height as well. Note that you have to set\nthe parent height in order to make percentages work correctly. In the following\nexample, the `<body>` is resized to fill the entire viewport, and the\n`<vaadin-split-layout>` element is set to take 100% height of the `<body>`:\n\n```html\n<body style=\"height: 100vh; margin: 0;\">\n <vaadin-split-layout style=\"height: 100%;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\nAlternatively, you can use a flexbox layout to make `<vaadin-split-layout>`\nfill up the parent:\n\n```html\n<body style=\"height: 100vh; margin: 0; display: flex;\">\n <vaadin-split-layout style=\"flex: 1;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\n### Initial Splitter Position\n\nThe initial splitter position is determined from the sizes of the content elements\ninside the split layout. Therefore, changing `width` on the content elements\naffects the initial splitter position for the horizontal layouts, while `height`\naffects the vertical ones.\n\nNote that when the total size of the content elements does not fit the layout,\nthe content elements are scaled proportionally.\n\nWhen setting initial sizes with relative units, such as percentages, it is\nrecommended to assign the size for both content elements:\n\n```html\n<vaadin-split-layout>\n <div style=\"width: 75%;\">Three fourths</div>\n <div style=\"width: 25%;\">One fourth</div>\n</vaadin-split-layout>\n```\n\n### Size Limits\n\nThe `min-width`/`min-height`, and `max-width`/`max-height` CSS size values\nfor the content elements are respected and used to limit the splitter position\nwhen it is dragged.\n\nIt is preferred to set the limits only for a single content element, in order\nto avoid size conflicts:\n\n```html\n<vaadin-split-layout>\n <div style=\"min-width: 50px; max-width: 150px;\">First</div>\n <div>Second</div>\n</vaadin-split-layout>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------|--------------\n`splitter` | Split element\n`handle` | The handle of the splitter\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:----------------------------------------------|\n| `--vaadin-split-layout-handle-size` |\n| `--vaadin-split-layout-handle-target-size` |\n| `--vaadin-split-layout-splitter-background` |\n| `--vaadin-split-layout-splitter-size` |\n| `--vaadin-split-layout-splitter-target-size` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
11
+ "description": "`<vaadin-split-layout>` is a Web Component implementing a split layout for two\ncontent elements with a draggable splitter between them.\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\n### Horizontal and Vertical Layouts\n\nBy default, the split's orientation is horizontal, meaning that the content elements are\npositioned side by side in a flex container with a horizontal layout.\n\nYou can change the split mode to vertical by setting the `orientation` attribute to `\"vertical\"`:\n\n```html\n<vaadin-split-layout orientation=\"vertical\">\n <div>Content on the top</div>\n <div>Content on the bottom</div>\n</vaadin-split-layout>\n```\n\n### Layouts Combination\n\nFor the layout contents, we usually use `<div>` elements in the examples,\nalthough you can use any other elements as well.\n\nFor instance, in order to have a nested vertical split layout inside a\nhorizontal one, you can include `<vaadin-split-layout>` as a content element\ninside another split layout:\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <vaadin-split-layout orientation=\"vertical\">\n <div>Second content element</div>\n <div>Third content element</div>\n </vaadin-split-layout>\n</vaadin-split-layout>\n```\n\nYou can also trigger the vertical mode in JavaScript by setting the property:\n`splitLayout.orientation = \"vertical\";`.\n\n### Split Layout Element Height\n\n`<vaadin-split-layout>` element itself is a flex container. It does not inherit\nthe parent height by default, but rather sets its height depending on the\ncontent.\n\nYou can use CSS to set the fixed height for the split layout, as usual with any\nblock element:\n\n```html\n<vaadin-split-layout style=\"height: 200px;\">\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\nIt is possible to define percentage height as well. Note that you have to set\nthe parent height in order to make percentages work correctly. In the following\nexample, the `<body>` is resized to fill the entire viewport, and the\n`<vaadin-split-layout>` element is set to take 100% height of the `<body>`:\n\n```html\n<body style=\"height: 100vh; margin: 0;\">\n <vaadin-split-layout style=\"height: 100%;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\nAlternatively, you can use a flexbox layout to make `<vaadin-split-layout>`\nfill up the parent:\n\n```html\n<body style=\"height: 100vh; margin: 0; display: flex;\">\n <vaadin-split-layout style=\"flex: 1;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\n### Initial Splitter Position\n\nThe initial splitter position is determined from the sizes of the content elements\ninside the split layout. Therefore, changing `width` on the content elements\naffects the initial splitter position for the horizontal layouts, while `height`\naffects the vertical ones.\n\nNote that when the total size of the content elements does not fit the layout,\nthe content elements are scaled proportionally.\n\nWhen setting initial sizes with relative units, such as percentages, it is\nrecommended to assign the size for both content elements:\n\n```html\n<vaadin-split-layout>\n <div style=\"width: 75%;\">Three fourths</div>\n <div style=\"width: 25%;\">One fourth</div>\n</vaadin-split-layout>\n```\n\n### Size Limits\n\nThe `min-width`/`min-height`, and `max-width`/`max-height` CSS size values\nfor the content elements are respected and used to limit the splitter position\nwhen it is dragged.\n\nIt is preferred to set the limits only for a single content element, in order\nto avoid size conflicts:\n\n```html\n<vaadin-split-layout>\n <div style=\"min-width: 50px; max-width: 150px;\">First</div>\n <div>Second</div>\n</vaadin-split-layout>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------|--------------\n`splitter` | Split element\n`handle` | The handle of the splitter\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|------------\n`focus-ring` | Set when the splitter is focused using the keyboard\n`focused` | Set when the splitter is focused\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:----------------------------------------------|\n| `--vaadin-split-layout-handle-size` |\n| `--vaadin-split-layout-handle-target-size` |\n| `--vaadin-split-layout-splitter-background` |\n| `--vaadin-split-layout-splitter-size` |\n| `--vaadin-split-layout-splitter-target-size` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Keyboard Interaction\n\nThe splitter is focusable and can be moved with the keyboard:\n\nKey | Action\n-----------------------------|--------------\n`Arrow Down` / `Arrow Right` | Grow the primary content element by a small step\n`Arrow Up` / `Arrow Left` | Shrink the primary content element by a small step\n`Page Up` / `Page Down` | Grow / shrink by a larger step (10% of the available size)\n`Home` / `End` | Collapse the primary / secondary content element",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "orientation",
@@ -33,6 +33,15 @@
33
33
  ],
34
34
  "js": {
35
35
  "properties": [
36
+ {
37
+ "name": "i18n",
38
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following JSON structure and default values:\n\n```\n{\n // Accessible label of the resize separator.\n separator: 'Resize separator'\n}\n```",
39
+ "value": {
40
+ "type": [
41
+ "Object"
42
+ ]
43
+ }
44
+ },
36
45
  {
37
46
  "name": "orientation",
38
47
  "description": "The split layout's orientation. Possible values are: `horizontal|vertical`.",
@@ -46,7 +55,7 @@
46
55
  "events": [
47
56
  {
48
57
  "name": "splitter-dragend",
49
- "description": "Fired after dragging the splitter have ended."
58
+ "description": "Fired after resizing the splitter via pointer or keyboard has ended."
50
59
  }
51
60
  ]
52
61
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/split-layout",
4
- "version": "25.3.0-alpha2",
4
+ "version": "25.3.0-alpha3",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,9 +16,16 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-split-layout",
19
- "description": "`<vaadin-split-layout>` is a Web Component implementing a split layout for two\ncontent elements with a draggable splitter between them.\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\n### Horizontal and Vertical Layouts\n\nBy default, the split's orientation is horizontal, meaning that the content elements are\npositioned side by side in a flex container with a horizontal layout.\n\nYou can change the split mode to vertical by setting the `orientation` attribute to `\"vertical\"`:\n\n```html\n<vaadin-split-layout orientation=\"vertical\">\n <div>Content on the top</div>\n <div>Content on the bottom</div>\n</vaadin-split-layout>\n```\n\n### Layouts Combination\n\nFor the layout contents, we usually use `<div>` elements in the examples,\nalthough you can use any other elements as well.\n\nFor instance, in order to have a nested vertical split layout inside a\nhorizontal one, you can include `<vaadin-split-layout>` as a content element\ninside another split layout:\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <vaadin-split-layout orientation=\"vertical\">\n <div>Second content element</div>\n <div>Third content element</div>\n </vaadin-split-layout>\n</vaadin-split-layout>\n```\n\nYou can also trigger the vertical mode in JavaScript by setting the property:\n`splitLayout.orientation = \"vertical\";`.\n\n### Split Layout Element Height\n\n`<vaadin-split-layout>` element itself is a flex container. It does not inherit\nthe parent height by default, but rather sets its height depending on the\ncontent.\n\nYou can use CSS to set the fixed height for the split layout, as usual with any\nblock element:\n\n```html\n<vaadin-split-layout style=\"height: 200px;\">\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\nIt is possible to define percentage height as well. Note that you have to set\nthe parent height in order to make percentages work correctly. In the following\nexample, the `<body>` is resized to fill the entire viewport, and the\n`<vaadin-split-layout>` element is set to take 100% height of the `<body>`:\n\n```html\n<body style=\"height: 100vh; margin: 0;\">\n <vaadin-split-layout style=\"height: 100%;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\nAlternatively, you can use a flexbox layout to make `<vaadin-split-layout>`\nfill up the parent:\n\n```html\n<body style=\"height: 100vh; margin: 0; display: flex;\">\n <vaadin-split-layout style=\"flex: 1;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\n### Initial Splitter Position\n\nThe initial splitter position is determined from the sizes of the content elements\ninside the split layout. Therefore, changing `width` on the content elements\naffects the initial splitter position for the horizontal layouts, while `height`\naffects the vertical ones.\n\nNote that when the total size of the content elements does not fit the layout,\nthe content elements are scaled proportionally.\n\nWhen setting initial sizes with relative units, such as percentages, it is\nrecommended to assign the size for both content elements:\n\n```html\n<vaadin-split-layout>\n <div style=\"width: 75%;\">Three fourths</div>\n <div style=\"width: 25%;\">One fourth</div>\n</vaadin-split-layout>\n```\n\n### Size Limits\n\nThe `min-width`/`min-height`, and `max-width`/`max-height` CSS size values\nfor the content elements are respected and used to limit the splitter position\nwhen it is dragged.\n\nIt is preferred to set the limits only for a single content element, in order\nto avoid size conflicts:\n\n```html\n<vaadin-split-layout>\n <div style=\"min-width: 50px; max-width: 150px;\">First</div>\n <div>Second</div>\n</vaadin-split-layout>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------|--------------\n`splitter` | Split element\n`handle` | The handle of the splitter\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:----------------------------------------------|\n| `--vaadin-split-layout-handle-size` |\n| `--vaadin-split-layout-handle-target-size` |\n| `--vaadin-split-layout-splitter-background` |\n| `--vaadin-split-layout-splitter-size` |\n| `--vaadin-split-layout-splitter-target-size` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
19
+ "description": "`<vaadin-split-layout>` is a Web Component implementing a split layout for two\ncontent elements with a draggable splitter between them.\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\n### Horizontal and Vertical Layouts\n\nBy default, the split's orientation is horizontal, meaning that the content elements are\npositioned side by side in a flex container with a horizontal layout.\n\nYou can change the split mode to vertical by setting the `orientation` attribute to `\"vertical\"`:\n\n```html\n<vaadin-split-layout orientation=\"vertical\">\n <div>Content on the top</div>\n <div>Content on the bottom</div>\n</vaadin-split-layout>\n```\n\n### Layouts Combination\n\nFor the layout contents, we usually use `<div>` elements in the examples,\nalthough you can use any other elements as well.\n\nFor instance, in order to have a nested vertical split layout inside a\nhorizontal one, you can include `<vaadin-split-layout>` as a content element\ninside another split layout:\n\n```html\n<vaadin-split-layout>\n <div>First content element</div>\n <vaadin-split-layout orientation=\"vertical\">\n <div>Second content element</div>\n <div>Third content element</div>\n </vaadin-split-layout>\n</vaadin-split-layout>\n```\n\nYou can also trigger the vertical mode in JavaScript by setting the property:\n`splitLayout.orientation = \"vertical\";`.\n\n### Split Layout Element Height\n\n`<vaadin-split-layout>` element itself is a flex container. It does not inherit\nthe parent height by default, but rather sets its height depending on the\ncontent.\n\nYou can use CSS to set the fixed height for the split layout, as usual with any\nblock element:\n\n```html\n<vaadin-split-layout style=\"height: 200px;\">\n <div>First content element</div>\n <div>Second content element</div>\n</vaadin-split-layout>\n```\n\nIt is possible to define percentage height as well. Note that you have to set\nthe parent height in order to make percentages work correctly. In the following\nexample, the `<body>` is resized to fill the entire viewport, and the\n`<vaadin-split-layout>` element is set to take 100% height of the `<body>`:\n\n```html\n<body style=\"height: 100vh; margin: 0;\">\n <vaadin-split-layout style=\"height: 100%;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\nAlternatively, you can use a flexbox layout to make `<vaadin-split-layout>`\nfill up the parent:\n\n```html\n<body style=\"height: 100vh; margin: 0; display: flex;\">\n <vaadin-split-layout style=\"flex: 1;\">\n <div>First</div>\n <div>Second</div>\n </vaadin-split-layout>\n</body>\n```\n\n### Initial Splitter Position\n\nThe initial splitter position is determined from the sizes of the content elements\ninside the split layout. Therefore, changing `width` on the content elements\naffects the initial splitter position for the horizontal layouts, while `height`\naffects the vertical ones.\n\nNote that when the total size of the content elements does not fit the layout,\nthe content elements are scaled proportionally.\n\nWhen setting initial sizes with relative units, such as percentages, it is\nrecommended to assign the size for both content elements:\n\n```html\n<vaadin-split-layout>\n <div style=\"width: 75%;\">Three fourths</div>\n <div style=\"width: 25%;\">One fourth</div>\n</vaadin-split-layout>\n```\n\n### Size Limits\n\nThe `min-width`/`min-height`, and `max-width`/`max-height` CSS size values\nfor the content elements are respected and used to limit the splitter position\nwhen it is dragged.\n\nIt is preferred to set the limits only for a single content element, in order\nto avoid size conflicts:\n\n```html\n<vaadin-split-layout>\n <div style=\"min-width: 50px; max-width: 150px;\">First</div>\n <div>Second</div>\n</vaadin-split-layout>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------|--------------\n`splitter` | Split element\n`handle` | The handle of the splitter\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------|------------\n`focus-ring` | Set when the splitter is focused using the keyboard\n`focused` | Set when the splitter is focused\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:----------------------------------------------|\n| `--vaadin-split-layout-handle-size` |\n| `--vaadin-split-layout-handle-target-size` |\n| `--vaadin-split-layout-splitter-background` |\n| `--vaadin-split-layout-splitter-size` |\n| `--vaadin-split-layout-splitter-target-size` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Keyboard Interaction\n\nThe splitter is focusable and can be moved with the keyboard:\n\nKey | Action\n-----------------------------|--------------\n`Arrow Down` / `Arrow Right` | Grow the primary content element by a small step\n`Arrow Up` / `Arrow Left` | Shrink the primary content element by a small step\n`Page Up` / `Page Down` | Grow / shrink by a larger step (10% of the available size)\n`Home` / `End` | Collapse the primary / secondary content element",
20
20
  "extension": true,
21
21
  "attributes": [
22
+ {
23
+ "name": ".i18n",
24
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following JSON structure and default values:\n\n```\n{\n // Accessible label of the resize separator.\n separator: 'Resize separator'\n}\n```",
25
+ "value": {
26
+ "kind": "expression"
27
+ }
28
+ },
22
29
  {
23
30
  "name": ".orientation",
24
31
  "description": "The split layout's orientation. Possible values are: `horizontal|vertical`.",
@@ -28,7 +35,7 @@
28
35
  },
29
36
  {
30
37
  "name": "@splitter-dragend",
31
- "description": "Fired after dragging the splitter have ended.",
38
+ "description": "Fired after resizing the splitter via pointer or keyboard has ended.",
32
39
  "value": {
33
40
  "kind": "expression"
34
41
  }