@vaadin/split-layout 24.2.0-dev.e9803eea7 → 24.3.0-alpha1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/split-layout",
3
- "version": "24.2.0-dev.e9803eea7",
3
+ "version": "24.3.0-alpha1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -21,6 +21,8 @@
21
21
  "type": "module",
22
22
  "files": [
23
23
  "src",
24
+ "!src/vaadin-lit-split-layout.d.ts",
25
+ "!src/vaadin-lit-split-layout.js",
24
26
  "theme",
25
27
  "vaadin-*.d.ts",
26
28
  "vaadin-*.js",
@@ -35,20 +37,21 @@
35
37
  "polymer"
36
38
  ],
37
39
  "dependencies": {
40
+ "@open-wc/dedupe-mixin": "^1.3.0",
38
41
  "@polymer/polymer": "^3.0.0",
39
- "@vaadin/component-base": "24.2.0-dev.e9803eea7",
40
- "@vaadin/vaadin-lumo-styles": "24.2.0-dev.e9803eea7",
41
- "@vaadin/vaadin-material-styles": "24.2.0-dev.e9803eea7",
42
- "@vaadin/vaadin-themable-mixin": "24.2.0-dev.e9803eea7"
42
+ "@vaadin/component-base": "24.3.0-alpha1",
43
+ "@vaadin/vaadin-lumo-styles": "24.3.0-alpha1",
44
+ "@vaadin/vaadin-material-styles": "24.3.0-alpha1",
45
+ "@vaadin/vaadin-themable-mixin": "24.3.0-alpha1"
43
46
  },
44
47
  "devDependencies": {
45
48
  "@esm-bundle/chai": "^4.3.4",
46
- "@vaadin/testing-helpers": "^0.4.3",
49
+ "@vaadin/testing-helpers": "^0.5.0",
47
50
  "sinon": "^13.0.2"
48
51
  },
49
52
  "web-types": [
50
53
  "web-types.json",
51
54
  "web-types.lit.json"
52
55
  ],
53
- "gitHead": "a065b79b9d5a189e457fab312cc8aff0d7f2f910"
56
+ "gitHead": "9ca6f3ca220a777e8eea181a1f5717e39a732240"
54
57
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { Constructor } from '@open-wc/dedupe-mixin';
7
+
8
+ export declare function SplitLayoutMixin<T extends Constructor<HTMLElement>>(
9
+ base: T,
10
+ ): Constructor<SplitLayoutMixinClass> & T;
11
+
12
+ export declare class SplitLayoutMixinClass {
13
+ /**
14
+ * The split layout's orientation. Possible values are: `horizontal|vertical`.
15
+ */
16
+ orientation: 'horizontal' | 'vertical';
17
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { addListener } from '@vaadin/component-base/src/gestures.js';
7
+
8
+ /**
9
+ * @polymerMixin
10
+ */
11
+ export const SplitLayoutMixin = (superClass) =>
12
+ class SplitLayoutMixin extends superClass {
13
+ static get properties() {
14
+ return {
15
+ /**
16
+ * The split layout's orientation. Possible values are: `horizontal|vertical`.
17
+ * @type {string}
18
+ */
19
+ orientation: {
20
+ type: String,
21
+ reflectToAttribute: true,
22
+ value: 'horizontal',
23
+ },
24
+
25
+ /** @private */
26
+ _previousPrimaryPointerEvents: String,
27
+
28
+ /** @private */
29
+ _previousSecondaryPointerEvents: String,
30
+ };
31
+ }
32
+
33
+ /** @protected */
34
+ ready() {
35
+ super.ready();
36
+
37
+ this._processChildren();
38
+
39
+ this.__observer = new MutationObserver((mutations) => {
40
+ mutations.forEach((mutation) => {
41
+ this._cleanupNodes(mutation.removedNodes);
42
+ });
43
+
44
+ this._processChildren();
45
+ });
46
+
47
+ this.__observer.observe(this, { childList: true });
48
+
49
+ const splitter = this.$.splitter;
50
+ addListener(splitter, 'track', this._onHandleTrack.bind(this));
51
+ addListener(splitter, 'down', this._setPointerEventsNone.bind(this));
52
+ addListener(splitter, 'up', this._restorePointerEvents.bind(this));
53
+ }
54
+
55
+ /** @private */
56
+ _cleanupNodes(nodes) {
57
+ nodes.forEach((node) => {
58
+ if (!(node.parentElement instanceof this.constructor)) {
59
+ node.removeAttribute('slot');
60
+ }
61
+ });
62
+ }
63
+
64
+ /** @private */
65
+ _processChildren() {
66
+ [...this.children].forEach((child, i) => {
67
+ if (i === 0) {
68
+ this._primaryChild = child;
69
+ child.setAttribute('slot', 'primary');
70
+ } else if (i === 1) {
71
+ this._secondaryChild = child;
72
+ child.setAttribute('slot', 'secondary');
73
+ } else {
74
+ child.removeAttribute('slot');
75
+ }
76
+ });
77
+ }
78
+
79
+ /** @private */
80
+ _setFlexBasis(element, flexBasis, containerSize) {
81
+ flexBasis = Math.max(0, Math.min(flexBasis, containerSize));
82
+ if (flexBasis === 0) {
83
+ // Pure zero does not play well in Safari
84
+ flexBasis = 0.000001;
85
+ }
86
+ element.style.flex = `1 1 ${flexBasis}px`;
87
+ }
88
+
89
+ /** @private */
90
+ _setPointerEventsNone(event) {
91
+ if (!this._primaryChild || !this._secondaryChild) {
92
+ return;
93
+ }
94
+ this._previousPrimaryPointerEvents = this._primaryChild.style.pointerEvents;
95
+ this._previousSecondaryPointerEvents = this._secondaryChild.style.pointerEvents;
96
+ this._primaryChild.style.pointerEvents = 'none';
97
+ this._secondaryChild.style.pointerEvents = 'none';
98
+
99
+ event.preventDefault();
100
+ }
101
+
102
+ /** @private */
103
+ _restorePointerEvents() {
104
+ if (!this._primaryChild || !this._secondaryChild) {
105
+ return;
106
+ }
107
+ this._primaryChild.style.pointerEvents = this._previousPrimaryPointerEvents;
108
+ this._secondaryChild.style.pointerEvents = this._previousSecondaryPointerEvents;
109
+ }
110
+
111
+ /** @private */
112
+ _onHandleTrack(event) {
113
+ if (!this._primaryChild || !this._secondaryChild) {
114
+ return;
115
+ }
116
+
117
+ const size = this.orientation === 'vertical' ? 'height' : 'width';
118
+ if (event.detail.state === 'start') {
119
+ this._startSize = {
120
+ container: this.getBoundingClientRect()[size] - this.$.splitter.getBoundingClientRect()[size],
121
+ primary: this._primaryChild.getBoundingClientRect()[size],
122
+ secondary: this._secondaryChild.getBoundingClientRect()[size],
123
+ };
124
+
125
+ return;
126
+ }
127
+
128
+ const distance = this.orientation === 'vertical' ? event.detail.dy : event.detail.dx;
129
+ const isRtl = this.orientation !== 'vertical' && this.__isRTL;
130
+ const dirDistance = isRtl ? -distance : distance;
131
+
132
+ this._setFlexBasis(this._primaryChild, this._startSize.primary + dirDistance, this._startSize.container);
133
+ this._setFlexBasis(this._secondaryChild, this._startSize.secondary - dirDistance, this._startSize.container);
134
+
135
+ if (event.detail.state === 'end') {
136
+ this.dispatchEvent(new CustomEvent('splitter-dragend'));
137
+
138
+ delete this._startSize;
139
+ }
140
+ }
141
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { CSSResult } from 'lit';
7
+
8
+ export const splitLayoutStyles: CSSResult;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { css } from 'lit';
7
+
8
+ export const splitLayoutStyles = css`
9
+ :host {
10
+ display: flex;
11
+ overflow: hidden !important;
12
+ transform: translateZ(0);
13
+ }
14
+
15
+ :host([hidden]) {
16
+ display: none !important;
17
+ }
18
+
19
+ :host([orientation='vertical']) {
20
+ flex-direction: column;
21
+ }
22
+
23
+ :host ::slotted(*) {
24
+ flex: 1 1 auto;
25
+ overflow: auto;
26
+ -webkit-overflow-scrolling: touch;
27
+ }
28
+
29
+ [part='splitter'] {
30
+ flex: none;
31
+ position: relative;
32
+ z-index: 1;
33
+ overflow: visible;
34
+ min-width: 8px;
35
+ min-height: 8px;
36
+ }
37
+
38
+ :host(:not([orientation='vertical'])) > [part='splitter'] {
39
+ cursor: ew-resize;
40
+ }
41
+
42
+ :host([orientation='vertical']) > [part='splitter'] {
43
+ cursor: ns-resize;
44
+ }
45
+
46
+ [part='handle'] {
47
+ width: 40px;
48
+ height: 40px;
49
+ position: absolute;
50
+ top: 50%;
51
+ left: 50%;
52
+ transform: translate3d(-50%, -50%, 0);
53
+ }
54
+
55
+ @media (forced-colors: active) {
56
+ [part~='splitter'] {
57
+ outline: 1px solid;
58
+ }
59
+
60
+ [part~='handle']::after {
61
+ background-color: AccentColor !important;
62
+ forced-color-adjust: none;
63
+ }
64
+ }
65
+ `;
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
7
7
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
8
+ import { SplitLayoutMixin } from './vaadin-split-layout-mixin.js';
8
9
 
9
10
  export interface SplitLayoutCustomEventMap {
10
11
  'splitter-dragend': Event;
@@ -150,12 +151,7 @@ export interface SplitLayoutEventMap extends HTMLElementEventMap, SplitLayoutCus
150
151
  *
151
152
  * @fires {Event} splitter-dragend - Fired after dragging the splitter have ended.
152
153
  */
153
- declare class SplitLayout extends ElementMixin(ThemableMixin(HTMLElement)) {
154
- /**
155
- * The split layout's orientation. Possible values are: `horizontal|vertical`.
156
- */
157
- orientation: 'horizontal' | 'vertical';
158
-
154
+ declare class SplitLayout extends SplitLayoutMixin(ElementMixin(ThemableMixin(HTMLElement))) {
159
155
  addEventListener<K extends keyof SplitLayoutEventMap>(
160
156
  type: K,
161
157
  listener: (this: SplitLayout, ev: SplitLayoutEventMap[K]) => void,
@@ -3,11 +3,14 @@
3
3
  * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
7
6
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
7
+ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
8
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
9
- import { addListener } from '@vaadin/component-base/src/gestures.js';
10
- import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
+ import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10
+ import { SplitLayoutMixin } from './vaadin-split-layout-mixin.js';
11
+ import { splitLayoutStyles } from './vaadin-split-layout-styles.js';
12
+
13
+ registerStyles('vaadin-split-layout', splitLayoutStyles, { moduleId: 'vaadin-split-layout-styles' });
11
14
 
12
15
  /**
13
16
  * `<vaadin-split-layout>` is a Web Component implementing a split layout for two
@@ -147,70 +150,15 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
147
150
  *
148
151
  * @fires {Event} splitter-dragend - Fired after dragging the splitter have ended.
149
152
  *
153
+ * @customElement
150
154
  * @extends HTMLElement
151
155
  * @mixes ElementMixin
156
+ * @mixes SplitLayoutMixin
152
157
  * @mixes ThemableMixin
153
158
  */
154
- class SplitLayout extends ElementMixin(ThemableMixin(PolymerElement)) {
159
+ class SplitLayout extends SplitLayoutMixin(ElementMixin(ThemableMixin(PolymerElement))) {
155
160
  static get template() {
156
161
  return html`
157
- <style>
158
- :host {
159
- display: flex;
160
- overflow: hidden !important;
161
- transform: translateZ(0);
162
- }
163
-
164
- :host([hidden]) {
165
- display: none !important;
166
- }
167
-
168
- :host([orientation='vertical']) {
169
- flex-direction: column;
170
- }
171
-
172
- :host ::slotted(*) {
173
- flex: 1 1 auto;
174
- overflow: auto;
175
- -webkit-overflow-scrolling: touch;
176
- }
177
-
178
- [part='splitter'] {
179
- flex: none;
180
- position: relative;
181
- z-index: 1;
182
- overflow: visible;
183
- min-width: 8px;
184
- min-height: 8px;
185
- }
186
-
187
- :host(:not([orientation='vertical'])) > [part='splitter'] {
188
- cursor: ew-resize;
189
- }
190
-
191
- :host([orientation='vertical']) > [part='splitter'] {
192
- cursor: ns-resize;
193
- }
194
-
195
- [part='handle'] {
196
- width: 40px;
197
- height: 40px;
198
- position: absolute;
199
- top: 50%;
200
- left: 50%;
201
- transform: translate3d(-50%, -50%, 0);
202
- }
203
-
204
- @media (forced-colors: active) {
205
- [part~='splitter'] {
206
- outline: 1px solid;
207
- }
208
- [part~='handle']::after {
209
- background-color: AccentColor !important;
210
- forced-color-adjust: none;
211
- }
212
- }
213
- </style>
214
162
  <slot id="primary" name="primary"></slot>
215
163
  <div part="splitter" id="splitter">
216
164
  <div part="handle"></div>
@@ -223,127 +171,6 @@ class SplitLayout extends ElementMixin(ThemableMixin(PolymerElement)) {
223
171
  return 'vaadin-split-layout';
224
172
  }
225
173
 
226
- static get properties() {
227
- return {
228
- /**
229
- * The split layout's orientation. Possible values are: `horizontal|vertical`.
230
- * @type {string}
231
- */
232
- orientation: {
233
- type: String,
234
- reflectToAttribute: true,
235
- value: 'horizontal',
236
- },
237
-
238
- /** @private */
239
- _previousPrimaryPointerEvents: String,
240
-
241
- /** @private */
242
- _previousSecondaryPointerEvents: String,
243
- };
244
- }
245
-
246
- /** @protected */
247
- ready() {
248
- super.ready();
249
- this.__observer = new FlattenedNodesObserver(this, (info) => {
250
- this._cleanupNodes(info.removedNodes);
251
- this._processChildren();
252
- });
253
-
254
- const splitter = this.$.splitter;
255
- addListener(splitter, 'track', this._onHandleTrack.bind(this));
256
- addListener(splitter, 'down', this._setPointerEventsNone.bind(this));
257
- addListener(splitter, 'up', this._restorePointerEvents.bind(this));
258
- }
259
-
260
- /** @private */
261
- _cleanupNodes(nodes) {
262
- nodes.forEach((node) => {
263
- if (!(node.parentElement instanceof SplitLayout)) {
264
- node.removeAttribute('slot');
265
- }
266
- });
267
- }
268
-
269
- /** @private */
270
- _processChildren() {
271
- [...this.children].forEach((child, i) => {
272
- if (i === 0) {
273
- this._primaryChild = child;
274
- child.setAttribute('slot', 'primary');
275
- } else if (i === 1) {
276
- this._secondaryChild = child;
277
- child.setAttribute('slot', 'secondary');
278
- } else {
279
- child.removeAttribute('slot');
280
- }
281
- });
282
- }
283
-
284
- /** @private */
285
- _setFlexBasis(element, flexBasis, containerSize) {
286
- flexBasis = Math.max(0, Math.min(flexBasis, containerSize));
287
- if (flexBasis === 0) {
288
- // Pure zero does not play well in Safari
289
- flexBasis = 0.000001;
290
- }
291
- element.style.flex = `1 1 ${flexBasis}px`;
292
- }
293
-
294
- /** @private */
295
- _setPointerEventsNone(event) {
296
- if (!this._primaryChild || !this._secondaryChild) {
297
- return;
298
- }
299
- this._previousPrimaryPointerEvents = this._primaryChild.style.pointerEvents;
300
- this._previousSecondaryPointerEvents = this._secondaryChild.style.pointerEvents;
301
- this._primaryChild.style.pointerEvents = 'none';
302
- this._secondaryChild.style.pointerEvents = 'none';
303
-
304
- event.preventDefault();
305
- }
306
-
307
- /** @private */
308
- _restorePointerEvents() {
309
- if (!this._primaryChild || !this._secondaryChild) {
310
- return;
311
- }
312
- this._primaryChild.style.pointerEvents = this._previousPrimaryPointerEvents;
313
- this._secondaryChild.style.pointerEvents = this._previousSecondaryPointerEvents;
314
- }
315
-
316
- /** @private */
317
- _onHandleTrack(event) {
318
- if (!this._primaryChild || !this._secondaryChild) {
319
- return;
320
- }
321
-
322
- const size = this.orientation === 'vertical' ? 'height' : 'width';
323
- if (event.detail.state === 'start') {
324
- this._startSize = {
325
- container: this.getBoundingClientRect()[size] - this.$.splitter.getBoundingClientRect()[size],
326
- primary: this._primaryChild.getBoundingClientRect()[size],
327
- secondary: this._secondaryChild.getBoundingClientRect()[size],
328
- };
329
-
330
- return;
331
- }
332
-
333
- const distance = this.orientation === 'vertical' ? event.detail.dy : event.detail.dx;
334
- const isRtl = this.orientation !== 'vertical' && this.__isRTL;
335
- const dirDistance = isRtl ? -distance : distance;
336
-
337
- this._setFlexBasis(this._primaryChild, this._startSize.primary + dirDistance, this._startSize.container);
338
- this._setFlexBasis(this._secondaryChild, this._startSize.secondary - dirDistance, this._startSize.container);
339
-
340
- if (event.detail.state === 'end') {
341
- this.dispatchEvent(new CustomEvent('splitter-dragend'));
342
-
343
- delete this._startSize;
344
- }
345
- }
346
-
347
174
  /**
348
175
  * Fired after dragging the splitter have ended.
349
176
  *
@@ -351,6 +178,6 @@ class SplitLayout extends ElementMixin(ThemableMixin(PolymerElement)) {
351
178
  */
352
179
  }
353
180
 
354
- customElements.define(SplitLayout.is, SplitLayout);
181
+ defineCustomElement(SplitLayout);
355
182
 
356
183
  export { SplitLayout };
@@ -25,7 +25,8 @@ registerStyles(
25
25
  [part='handle']::after {
26
26
  content: '';
27
27
  display: block;
28
- width: 4px;
28
+ --_handle-size: 4px;
29
+ width: var(--_handle-size);
29
30
  height: 100%;
30
31
  max-width: 100%;
31
32
  max-height: 100%;
@@ -36,18 +37,13 @@ registerStyles(
36
37
 
37
38
  :host([orientation='vertical']) [part='handle']::after {
38
39
  width: 100%;
39
- height: 4px;
40
+ height: var(--_handle-size);
40
41
  }
41
42
 
42
43
  /* Hover style */
43
- [part='splitter']:hover [part='handle']::after {
44
- background-color: var(--lumo-contrast-40pct);
45
- }
46
-
47
- /* Disable hover for touch devices */
48
- @media (pointer: coarse) {
44
+ @media (any-hover: hover) {
49
45
  [part='splitter']:hover [part='handle']::after {
50
- background-color: var(--lumo-contrast-30pct);
46
+ background-color: var(--lumo-contrast-40pct);
51
47
  }
52
48
  }
53
49
 
@@ -62,36 +58,31 @@ registerStyles(
62
58
  border-top: 1px solid var(--lumo-contrast-10pct);
63
59
  }
64
60
 
65
- :host([theme~='small']) > [part='splitter'],
66
- :host([theme~='minimal']) > [part='splitter'] {
61
+ :host(:is([theme~='small'], [theme~='minimal'])) > [part='splitter'] {
67
62
  min-width: 0;
68
63
  min-height: 0;
69
64
  background-color: transparent;
70
65
  }
71
66
 
72
- :host([theme~='small']) > [part='splitter']::after,
73
- :host([theme~='minimal']) > [part='splitter']::after {
67
+ :host(:is([theme~='small'], [theme~='minimal'])) > [part='splitter']::after {
74
68
  content: '';
75
69
  position: absolute;
76
70
  inset: -4px;
77
71
  }
78
72
 
79
- :host([theme~='small']) > [part='splitter'] > [part='handle']::after,
80
- :host([theme~='minimal']) > [part='splitter'] > [part='handle']::after {
81
- opacity: 0;
73
+ :host(:is([theme~='small'], [theme~='minimal'])) > [part='splitter'] > [part='handle'] {
74
+ left: calc(50% - 0.5px);
75
+ top: calc(50% - 0.5px);
82
76
  }
83
77
 
84
- :host([theme~='small']) > [part='splitter']:hover > [part='handle']::after,
85
- :host([theme~='small']) > [part='splitter']:active > [part='handle']::after,
86
- :host([theme~='minimal']) > [part='splitter']:hover > [part='handle']::after,
87
- :host([theme~='minimal']) > [part='splitter']:active > [part='handle']::after {
88
- opacity: 1;
78
+ :host(:is([theme~='small'], [theme~='minimal'])) > [part='splitter'] > [part='handle']::after {
79
+ opacity: 0;
80
+ --_handle-size: 5px;
89
81
  }
90
82
 
91
- /* RTL specific styles */
92
- :host([theme~='small'][dir='rtl']) > [part='splitter'] {
93
- border-left: auto;
94
- border-right: 1px solid var(--lumo-contrast-10pct);
83
+ :host(:is([theme~='small'], [theme~='minimal'])) > [part='splitter']:hover > [part='handle']::after,
84
+ :host(:is([theme~='small'], [theme~='minimal'])) > [part='splitter']:active > [part='handle']::after {
85
+ opacity: 1;
95
86
  }
96
87
  `,
97
88
  { moduleId: 'lumo-split-layout' },
package/web-types.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/web-types",
3
+ "name": "@vaadin/split-layout",
4
+ "version": "24.3.0-alpha1",
5
+ "description-markup": "markdown",
6
+ "contributions": {
7
+ "html": {
8
+ "elements": [
9
+ {
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 | Theme for Element\n----------------|----------------|----------------\n`splitter` | Split element | vaadin-split-layout\n`handle` | The handle of the splitter | vaadin-split-layout\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
12
+ "attributes": [
13
+ {
14
+ "name": "orientation",
15
+ "description": "The split layout's orientation. Possible values are: `horizontal|vertical`.",
16
+ "value": {
17
+ "type": [
18
+ "string"
19
+ ]
20
+ }
21
+ },
22
+ {
23
+ "name": "theme",
24
+ "description": "The theme variants to apply to the component.",
25
+ "value": {
26
+ "type": [
27
+ "string",
28
+ "null",
29
+ "undefined"
30
+ ]
31
+ }
32
+ }
33
+ ],
34
+ "js": {
35
+ "properties": [
36
+ {
37
+ "name": "orientation",
38
+ "description": "The split layout's orientation. Possible values are: `horizontal|vertical`.",
39
+ "value": {
40
+ "type": [
41
+ "string"
42
+ ]
43
+ }
44
+ }
45
+ ],
46
+ "events": [
47
+ {
48
+ "name": "splitter-dragend",
49
+ "description": "Fired after dragging the splitter have ended."
50
+ }
51
+ ]
52
+ }
53
+ }
54
+ ]
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/web-types",
3
+ "name": "@vaadin/split-layout",
4
+ "version": "24.3.0-alpha1",
5
+ "description-markup": "markdown",
6
+ "framework": "lit",
7
+ "framework-config": {
8
+ "enable-when": {
9
+ "node-packages": [
10
+ "lit"
11
+ ]
12
+ }
13
+ },
14
+ "contributions": {
15
+ "html": {
16
+ "elements": [
17
+ {
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 | Theme for Element\n----------------|----------------|----------------\n`splitter` | Split element | vaadin-split-layout\n`handle` | The handle of the splitter | vaadin-split-layout\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.",
20
+ "extension": true,
21
+ "attributes": [
22
+ {
23
+ "name": ".orientation",
24
+ "description": "The split layout's orientation. Possible values are: `horizontal|vertical`.",
25
+ "value": {
26
+ "kind": "expression"
27
+ }
28
+ },
29
+ {
30
+ "name": "@splitter-dragend",
31
+ "description": "Fired after dragging the splitter have ended.",
32
+ "value": {
33
+ "kind": "expression"
34
+ }
35
+ }
36
+ ]
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ }