@window-splitter/vue 0.8.5

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.
@@ -0,0 +1,796 @@
1
+ import type { Meta, StoryObj } from "@storybook/vue3";
2
+ import { dedent } from "ts-dedent";
3
+ import PanelGroup from "./PanelGroup.vue";
4
+ import Panel from "./Panel.vue";
5
+ import PanelResizer from "./PanelResizer.vue";
6
+ import { onMounted, ref, useTemplateRef } from "vue";
7
+ import { spring } from "framer-motion";
8
+ import { PanelGroupHandle, PanelHandle } from "@window-splitter/interface";
9
+ import { GroupMachineContextValue } from "@window-splitter/state";
10
+
11
+ const meta: Meta<typeof PanelGroup> = {
12
+ title: "WindowSplitter/Vue",
13
+ component: PanelGroup,
14
+ subcomponents: {
15
+ Panel,
16
+ PanelResizer,
17
+ },
18
+ };
19
+ export default meta;
20
+
21
+ type Story = StoryObj<typeof PanelGroup>;
22
+
23
+ // More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
24
+ export const Simple = {
25
+ render: (args: { handle: { value: PanelGroupHandle | null } }) => ({
26
+ components: { PanelGroup, Panel, PanelResizer },
27
+ setup() {
28
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
29
+ onMounted(() => {
30
+ if (args.handle) {
31
+ args.handle.value = handle.value;
32
+ }
33
+ });
34
+ return { handle };
35
+ },
36
+ template: dedent/*html*/ `
37
+ <PanelGroup
38
+ class="panel-group"
39
+ :style="{ height: '200px' }"
40
+ ref="handle"
41
+ >
42
+ <Panel class="panel">Panel 1</Panel>
43
+ <PanelResizer class="panel-resizer" size="10px" />
44
+ <Panel class="panel" min="100px">Panel 2</Panel>
45
+ </PanelGroup>
46
+ `,
47
+ }),
48
+ };
49
+
50
+ export const Autosave = {
51
+ render: (args: { handle: { value: PanelGroupHandle | null } }) => ({
52
+ components: { PanelGroup, Panel, PanelResizer },
53
+ setup() {
54
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
55
+ onMounted(() => {
56
+ if (args.handle) {
57
+ args.handle.value = handle.value;
58
+ }
59
+ });
60
+ return { handle };
61
+ },
62
+ template: dedent/*html*/ `
63
+ <PanelGroup
64
+ class="panel-group"
65
+ ref="handle"
66
+ autosaveId="autosave-example-vue"
67
+ >
68
+ <Panel class="panel" id="panel-1">Panel 1</Panel>
69
+ <PanelResizer class="panel-resizer" id="resizer" size="10px" />
70
+ <Panel class="panel" id="panel-2">Panel 2</Panel>
71
+ </PanelGroup>
72
+ `,
73
+ }),
74
+ };
75
+
76
+ export const AutosaveCookie = {
77
+ render: (args: {
78
+ handle: { value: PanelGroupHandle | null };
79
+ snapshot: GroupMachineContextValue;
80
+ }) => ({
81
+ components: { PanelGroup, Panel, PanelResizer },
82
+ setup() {
83
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
84
+ onMounted(() => {
85
+ if (args.handle) {
86
+ args.handle.value = handle.value;
87
+ }
88
+ });
89
+ return { handle, snapshot: args.snapshot };
90
+ },
91
+ template: dedent/*html*/ `
92
+ <PanelGroup
93
+ ref="handle"
94
+ autosaveId="autosave-cookie-vue"
95
+ autosaveStrategy="cookie"
96
+ :style="{ height: '200px', width: '502px' }"
97
+ class="panel-group"
98
+ :snapshot="snapshot"
99
+ >
100
+ <Panel class="panel" id="panel-1">Panel 1</Panel>
101
+ <PanelResizer class="panel-resizer" id="resizer1" size="10px" />
102
+ <Panel class="panel" id="panel-2">Panel 2</Panel>
103
+ </PanelGroup>
104
+ `,
105
+ }),
106
+ };
107
+
108
+ export const AutosaveCollapsible = {
109
+ render: (args: {
110
+ handle: { value: PanelGroupHandle | null };
111
+ onCollapseChange: (collapsed: boolean) => void;
112
+ }) => ({
113
+ components: { PanelGroup, Panel, PanelResizer },
114
+ setup() {
115
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
116
+ onMounted(() => {
117
+ if (args.handle) {
118
+ args.handle.value = handle.value;
119
+ }
120
+ });
121
+ return { handle, onCollapseChange: args.onCollapseChange };
122
+ },
123
+ template: dedent/*html*/ `
124
+ <PanelGroup
125
+ ref="handle"
126
+ class="panel-group"
127
+ autosaveId="autosave-example-2"
128
+ >
129
+ <Panel
130
+ class="panel"
131
+ id="panel-1"
132
+ collapsible
133
+ collapsedSize="100px"
134
+ min="140px"
135
+ @collapse-change="onCollapseChange"
136
+ >
137
+ Collapsible
138
+ </Panel>
139
+ <PanelResizer class="panel-resizer" id="resizer" size="10px" />
140
+ <Panel class="panel" id="panel-2">Panel 2</Panel>
141
+ </PanelGroup>
142
+ `,
143
+ }),
144
+ };
145
+
146
+ export const DynamicConstraints = {
147
+ render: (args: { handle: { value: PanelGroupHandle | null } }) => ({
148
+ components: { PanelGroup, Panel, PanelResizer },
149
+ setup() {
150
+ const customOn = ref(false);
151
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
152
+ onMounted(() => {
153
+ if (args.handle) {
154
+ args.handle.value = handle.value;
155
+ }
156
+ });
157
+ return { customOn, handle };
158
+ },
159
+ template: dedent/*html*/ `
160
+ <PanelGroup class="panel-group" ref="handle" :style="{ width: '1000px' }">
161
+ <Panel default="100px" :min="customOn ? '200px' : '100px'" class="panel">
162
+ <div>Panel 1</div>
163
+ </Panel>
164
+ <PanelResizer class="panel-resizer" size="10px" />
165
+ <Panel min="100px" class="panel">
166
+ <div>Panel 2</div>
167
+ </Panel>
168
+ <PanelResizer class="panel-resizer" size="10px" />
169
+ <Panel
170
+ class="panel"
171
+ :min="customOn ? '100px' : '400px'"
172
+ :max="customOn ? '300px' : '700px'"
173
+ >
174
+ <div>Panel 3</div>
175
+ </Panel>
176
+ </PanelGroup>
177
+
178
+ <button type="button" @click="() => customOn = !customOn">
179
+ Toggle Custom
180
+ </button>
181
+ `,
182
+ }),
183
+ };
184
+
185
+ export const SimpleMin: Story = {
186
+ render: () => ({
187
+ components: { PanelGroup, Panel, PanelResizer },
188
+ template: dedent/*html*/ `
189
+ <PanelGroup class="panel-group">
190
+ <Panel min="100px" class="panel">
191
+ <div>Panel 1</div>
192
+ </Panel>
193
+ <PanelResizer class="panel-resizer" size="10px" />
194
+ <Panel min="100px" class="panel">
195
+ <div>Panel 2</div>
196
+ </Panel>
197
+ <PanelResizer class="panel-resizer" size="10px" />
198
+ <Panel min="100px" class="panel">
199
+ <div>Panel 3</div>
200
+ </Panel>
201
+ </PanelGroup>
202
+ `,
203
+ }),
204
+ };
205
+
206
+ export const SimpleMinMax: Story = {
207
+ render: () => ({
208
+ components: { PanelGroup, Panel, PanelResizer },
209
+ template: dedent/*html*/ `
210
+ <PanelGroup class="panel-group">
211
+ <Panel min="100px" max="200px" class="panel">
212
+ <div>Panel 1</div>
213
+ </Panel>
214
+ <PanelResizer class="panel-resizer" size="10px" />
215
+ <Panel min="100px" class="panel">
216
+ <div>Panel 2</div>
217
+ </Panel>
218
+ <PanelResizer class="panel-resizer" size="20px" />
219
+ <Panel min="100px" class="panel">
220
+ <div>Panel 3</div>
221
+ </Panel>
222
+ </PanelGroup>
223
+ `,
224
+ }),
225
+ };
226
+
227
+ export const SimpleConstraints: Story = {
228
+ render: () => ({
229
+ components: { PanelGroup, Panel, PanelResizer },
230
+ template: dedent/*html*/ `
231
+ <PanelGroup class="panel-group">
232
+ <Panel min="100px" max="50%" class="panel">
233
+ <div>Panel 1</div>
234
+ </Panel>
235
+ <PanelResizer class="panel-resizer" size="10px" />
236
+ <Panel class="panel">
237
+ <div>Panel 2</div>
238
+ </Panel>
239
+ </PanelGroup>
240
+ `,
241
+ }),
242
+ };
243
+
244
+ export const HorizontalLayout: Story = {
245
+ render: () => ({
246
+ components: { PanelGroup, Panel, PanelResizer },
247
+ template: dedent/*html*/ `
248
+ <PanelGroup orientation="horizontal" class="panel-group">
249
+ <Panel default="30%" min="20%" class="panel">
250
+ left
251
+ </Panel>
252
+ <PanelResizer class="panel-resizer" size="10px" />
253
+ <Panel min="20%" class="panel">middle</Panel>
254
+ <PanelResizer class="panel-resizer" size="10px" />
255
+ <Panel default="30%" min="20%" class="panel">
256
+ right
257
+ </Panel>
258
+ </PanelGroup>
259
+ `,
260
+ }),
261
+ };
262
+
263
+ export const VerticalLayout = {
264
+ render: (args: { handle: { value: PanelGroupHandle | null } }) => ({
265
+ components: { PanelGroup, Panel, PanelResizer },
266
+ setup() {
267
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
268
+ onMounted(() => {
269
+ if (args.handle) {
270
+ args.handle.value = handle.value;
271
+ }
272
+ });
273
+ return { handle };
274
+ },
275
+ template: dedent/*html*/ `
276
+ <PanelGroup
277
+ ref="handle"
278
+ orientation="vertical"
279
+ :style="{ height: '322px' }"
280
+ class="panel-group"
281
+ >
282
+ <Panel default="30%" min="20%" class="panel">
283
+ top
284
+ </Panel>
285
+ <PanelResizer class="panel-resizer" size="10px" />
286
+ <Panel min="20%" class="panel">middle</Panel>
287
+ <PanelResizer class="panel-resizer" size="10px" />
288
+ <Panel default="30%" min="20%" class="panel">
289
+ bottom
290
+ </Panel>
291
+ </PanelGroup>
292
+ `,
293
+ }),
294
+ };
295
+
296
+ export const VerticalLayout2: Story = {
297
+ render: () => ({
298
+ components: { PanelGroup, Panel, PanelResizer },
299
+ template: dedent/*html*/ `
300
+ <PanelGroup
301
+ orientation="vertical"
302
+ :style="{ height: 'calc(100vh - 100px)' }"
303
+ class="panel-group"
304
+ >
305
+ <Panel default="200px" min="200px" class="panel">
306
+ top
307
+ </Panel>
308
+ <PanelResizer class="panel-resizer" size="10px" />
309
+ <Panel
310
+ min="200px"
311
+ collapsedSize="60px"
312
+ defaultCollapsed
313
+ collapsible
314
+ class="panel"
315
+ >
316
+ middle
317
+ </Panel>
318
+ </PanelGroup>
319
+ `,
320
+ }),
321
+ };
322
+
323
+ export const NestedGroups: Story = {
324
+ render: () => ({
325
+ components: { PanelGroup, Panel, PanelResizer },
326
+ template: dedent/*html*/ `
327
+ <PanelGroup
328
+ orientation="horizontal"
329
+ :style="{
330
+ border: '1px solid rgba(0, 0, 0, 0.3)',
331
+ 'border-radius': '12px',
332
+ height: '400px',
333
+ }"
334
+ class="panel-group"
335
+ >
336
+ <Panel min="10%">1</Panel>
337
+ <PanelResizer class="panel-resizer" size="10px" />
338
+ <Panel min="10%">
339
+ <PanelGroup orientation="vertical">
340
+ <Panel min="10%">2-1</Panel>
341
+ <PanelResizer class="panel-resizer" size="10px" />
342
+ <Panel min="10%">
343
+ <PanelGroup orientation="horizontal">
344
+ <Panel min="20%">2-2-1</Panel>
345
+ <PanelResizer class="panel-resizer" size="10px" />
346
+ <Panel min="20%">2-2-2</Panel>
347
+ </PanelGroup>
348
+ </Panel>
349
+ </PanelGroup>
350
+ </Panel>
351
+ <PanelResizer class="panel-resizer" size="10px" />
352
+ <Panel min="10%">3</Panel>
353
+ </PanelGroup>
354
+ `,
355
+ }),
356
+ };
357
+
358
+ export const WithOverflow: Story = {
359
+ render: () => ({
360
+ components: { PanelGroup, Panel, PanelResizer },
361
+ template: dedent/*html*/ `
362
+ <PanelGroup
363
+ :style="{ height: '400px' }"
364
+ class="panel-group"
365
+ >
366
+ <Panel min="200px" class="panel">
367
+ <div
368
+ :style="{
369
+ overflow: 'auto',
370
+ height: '100%',
371
+ 'box-sizing': 'border-box',
372
+ }"
373
+ >
374
+ <p>
375
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
376
+ euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi, eu
377
+ tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
378
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
379
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
380
+ eu tincidunt nisl nisl eu nisl.
381
+ </p>
382
+ <p>
383
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
384
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
385
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
386
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
387
+ eu tincidunt nisl nisl eu nisl.
388
+ </p>
389
+ <p>
390
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
391
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
392
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
393
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
394
+ eu tincidunt nisl nisl eu nisl.
395
+ </p>
396
+ <p>
397
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
398
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
399
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
400
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
401
+ eu tincidunt nisl nisl eu nisl.
402
+ </p>
403
+ <p>
404
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
405
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
406
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
407
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
408
+ eu tincidunt nisl nisl eu nisl.
409
+ </p>
410
+ </div>
411
+ </Panel>
412
+ <PanelResizer class="panel-resizer" size="10px" />
413
+ <Panel min="200px" class="panel">
414
+ <div
415
+ :style="{
416
+ overflow: 'auto',
417
+ padding: '40px',
418
+ height: '100%',
419
+ 'box-sizing': 'border-box',
420
+ }"
421
+ >
422
+ <p>
423
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
424
+ euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi, eu
425
+ tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
426
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
427
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
428
+ eu tincidunt nisl nisl eu nisl.
429
+ </p>
430
+ <p>
431
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
432
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
433
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
434
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
435
+ eu tincidunt nisl nisl eu nisl.
436
+ </p>
437
+ <p>
438
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
439
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
440
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
441
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
442
+ eu tincidunt nisl nisl eu nisl.
443
+ </p>
444
+ <p>
445
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
446
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
447
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
448
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
449
+ eu tincidunt nisl nisl eu nisl.
450
+ </p>
451
+ <p>
452
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
453
+ eu tincidunt nisl nisl eu nisl. Sed euismod, nisl eget ultricies
454
+ ultrices, nunc nisi aliquam nisi, eu tincidunt nisl nisl eu nisl.
455
+ Sed euismod, nisl eget ultricies ultrices, nunc nisi aliquam nisi,
456
+ eu tincidunt nisl nisl eu nisl.
457
+ </p>
458
+ </div>
459
+ </Panel>
460
+ </PanelGroup>
461
+ `,
462
+ }),
463
+ };
464
+
465
+ export const Collapsible = {
466
+ render: (args: {
467
+ handle: { value: PanelGroupHandle | null };
468
+ leftHandle?: { value: PanelHandle | null };
469
+ rightHandle?: { value: PanelHandle | null };
470
+ }) => ({
471
+ components: { PanelGroup, Panel, PanelResizer },
472
+ setup() {
473
+ const collapsed = ref(true);
474
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
475
+ const leftHandle = useTemplateRef<PanelHandle>("leftHandle");
476
+ const rightHandle = useTemplateRef<PanelHandle>("rightHandle");
477
+ onMounted(() => {
478
+ if (args.handle) {
479
+ args.handle.value = handle.value;
480
+ }
481
+ if (args.leftHandle) {
482
+ args.leftHandle.value = leftHandle.value;
483
+ }
484
+ if (args.rightHandle) {
485
+ args.rightHandle.value = rightHandle.value;
486
+ }
487
+ });
488
+ return { collapsed, handle, leftHandle, rightHandle };
489
+ },
490
+ template: dedent/*html*/ `
491
+ <PanelGroup class="panel-group" ref="handle">
492
+ <Panel
493
+ min="100px"
494
+ ref="leftHandle"
495
+ collapsible
496
+ collapsedSize="60px"
497
+ :style="{ border: '10px solid green', 'box-sizing': 'border-box' }"
498
+ >
499
+ <div>1</div>
500
+ </Panel>
501
+ <PanelResizer class="panel-resizer" size="10px" />
502
+ <Panel min="100px" class="panel">
503
+ <div>2</div>
504
+ </Panel>
505
+ <PanelResizer class="panel-resizer" id="resizer-2" size="10px" />
506
+ <Panel
507
+ min="100px"
508
+ collapsible
509
+ ref="rightHandle"
510
+ collapsedSize="60px"
511
+ :collapseAnimation="{ easing: 'bounce', duration: 1000 }"
512
+ :style="{ border: '10px solid blue', 'box-sizing': 'border-box' }"
513
+ :collapsed="collapsed"
514
+ @collapse-change="collapsed = !collapsed"
515
+ >
516
+ <div>3</div>
517
+ </Panel>
518
+ </PanelGroup>
519
+ `,
520
+ }),
521
+ };
522
+
523
+ export const CustomCollapseAnimation: Story = {
524
+ render: () => ({
525
+ components: { PanelGroup, Panel, PanelResizer },
526
+ setup() {
527
+ const springFn = spring({
528
+ keyframes: [0, 1],
529
+ velocity: 1,
530
+ stiffness: 100,
531
+ damping: 10,
532
+ mass: 1.0,
533
+ });
534
+
535
+ return { springFn };
536
+ },
537
+ template: dedent/*html*/ `
538
+ <PanelGroup class="panel-group">
539
+ <Panel
540
+ min="100px"
541
+ collapsible
542
+ collapsedSize="60px"
543
+ :style="{ border: '10px solid green', 'box-sizing': 'border-box' }"
544
+ class="panel"
545
+ >
546
+ 1
547
+ </Panel>
548
+ <PanelResizer class="panel-resizer" size="10px" />
549
+ <Panel min="100px" class="panel">2</Panel>
550
+ <PanelResizer class="panel-resizer" size="10px" />
551
+ <Panel
552
+ class="panel"
553
+ :style="{ border: '10px solid blue', 'box-sizing': 'border-box' }"
554
+ min="100px"
555
+ collapsible
556
+ collapsedSize="60px"
557
+ defaultCollapsed
558
+ :collapseAnimation="{
559
+ easing: (t) => springFn.next(t * 1000).value,
560
+ duration: 1000,
561
+ }"
562
+ >
563
+ 3
564
+ </Panel>
565
+ </PanelGroup>
566
+ `,
567
+ }),
568
+ };
569
+
570
+ export const ImperativePanel: Story = {
571
+ render: () => ({
572
+ components: { PanelGroup, Panel, PanelResizer },
573
+ setup() {
574
+ const groupRef = useTemplateRef<PanelGroupHandle>("groupRef");
575
+ const panelRef = useTemplateRef<PanelHandle>("panelRef");
576
+
577
+ return {
578
+ groupRef,
579
+ panelRef,
580
+ alert: (...args: string[]) => alert(args.join(", ")),
581
+ };
582
+ },
583
+ template: dedent/*html*/ `
584
+ <PanelGroup class="panel-group" ref="groupRef">
585
+ <Panel
586
+ ref="panelRef"
587
+ min="100px"
588
+ class="panel"
589
+ collapsible
590
+ collapsedSize="60px"
591
+ >
592
+ 1
593
+ </Panel>
594
+ <PanelResizer class="panel-resizer" size="10px" />
595
+ <Panel min="100px" class="panel">2</Panel>
596
+ <PanelResizer class="panel-resizer" size="10px" />
597
+ <Panel
598
+ min="100px"
599
+ collapsible
600
+ collapsedSize="60px"
601
+ defaultCollapsed
602
+ class="panel"
603
+ >
604
+ 3
605
+ </Panel>
606
+ </PanelGroup>
607
+
608
+ <div>
609
+ <button
610
+ type="button"
611
+ @click="() => alert('Sizes:', groupRef?.getPixelSizes())"
612
+ >
613
+ Get pixel sizes
614
+ </button>
615
+ <button
616
+ type="button"
617
+ @click="() => alert('Sizes:', groupRef?.getPercentageSizes())"
618
+ >
619
+ Get percentage sizes
620
+ </button>
621
+ <button
622
+ type="button"
623
+ @click="() => groupRef?.setSizes(['200px', '10px', '50%', '10px', '150px'])"
624
+ >
625
+ Override sizes
626
+ </button>
627
+ </div>
628
+
629
+ <div>
630
+ <button type="button" @click="() => panelRef?.collapse()">
631
+ Collapse
632
+ </button>
633
+ <button
634
+ type="button"
635
+ @click="() => alert('Collapsed: ' + panelRef?.isCollapsed())"
636
+ >
637
+ Is Collapsed?
638
+ </button>
639
+ <button type="button" @click="() => panelRef?.expand()">
640
+ Expand
641
+ </button>
642
+ <button
643
+ type="button"
644
+ @click="() => alert('Expanded: ' + panelRef?.isExpanded())"
645
+ >
646
+ Is Expanded?
647
+ </button>
648
+ <button type="button" @click="() => alert('Id: ' + panelRef?.getId())">
649
+ Get Id
650
+ </button>
651
+ <button
652
+ type="button"
653
+ @click="() => alert('Size: ' + panelRef?.getPixelSize())"
654
+ >
655
+ Get Pixel Size
656
+ </button>
657
+ <button
658
+ type="button"
659
+ @click="() => alert('Percentage: ' + panelRef?.getPercentageSize())"
660
+ >
661
+ Get Percentage Size
662
+ </button>
663
+ <button type="button" @click="() => panelRef?.setSize('30px')">
664
+ Set size to 100px
665
+ </button>
666
+ <button type="button" @click="() => panelRef?.setSize('50%')">
667
+ Set size to 50%
668
+ </button>
669
+ </div>
670
+ `,
671
+ }),
672
+ };
673
+
674
+ export const ConditionalPanel = {
675
+ render: (args: { handle: { value: PanelGroupHandle | null } }) => ({
676
+ components: { PanelGroup, Panel, PanelResizer },
677
+ setup() {
678
+ const handle = useTemplateRef<PanelGroupHandle>("handle");
679
+ const isExpanded = ref(false);
680
+ onMounted(() => {
681
+ if (args.handle) {
682
+ args.handle.value = handle.value;
683
+ }
684
+ });
685
+ return { handle, isExpanded };
686
+ },
687
+ template: dedent/*html*/ `
688
+ <PanelGroup class="panel-group" ref="handle">
689
+ <Panel id="panel-1" min="100px" collapsible collapsedSize="60px" class="panel">
690
+ <div>1</div>
691
+ </Panel>
692
+ <PanelResizer class="panel-resizer" id="handle-1" size="10px" />
693
+ <Panel id="panel-2" min="100px" class="panel">
694
+ <div>2</div>
695
+ </Panel>
696
+
697
+ <template v-if="isExpanded">
698
+ <PanelResizer class="panel-resizer" id="handle-2" size="10px" />
699
+ <Panel id="panel-3" min="100px" class="panel">
700
+ 3
701
+ <button type="button" @click="isExpanded = false">
702
+ Close
703
+ </button>
704
+ </Panel>
705
+ </template>
706
+ </PanelGroup>
707
+
708
+ <button type="button" @click="isExpanded = true">
709
+ Expand
710
+ </button>
711
+ `,
712
+ }),
713
+ };
714
+
715
+ export const ConditionalPanelComplex: Story = {
716
+ render: () => ({
717
+ components: { PanelGroup, Panel, PanelResizer },
718
+ setup() {
719
+ const isExpanded = ref(false);
720
+ return { isExpanded };
721
+ },
722
+ template: dedent/*html*/ `
723
+ <PanelGroup class="panel-group">
724
+ <Panel id="panel-1" min="100px" collapsible collapsedSize="60px" class="panel">
725
+ <div>1</div>
726
+ </Panel>
727
+ <PanelResizer id="handle-1" class="panel-resizer" size="10px" />
728
+ <Panel id="panel-2" min="100px" class="panel">
729
+ <div>2</div>
730
+ </Panel>
731
+ <PanelResizer id="handle-2" class="panel-resizer" size="10px" />
732
+ <Panel id="panel-3" min="100px" class="panel">
733
+ <div>3</div>
734
+ </Panel>
735
+ <template v-if="isExpanded">
736
+ <PanelResizer id="handle-3" class="panel-resizer" size="10px" />
737
+ <Panel id="panel-4" min="100px" class="panel">
738
+ expanded
739
+ <button type="button" @click="isExpanded = false">
740
+ Close
741
+ </button>
742
+ </Panel>
743
+ </template>
744
+ <PanelResizer id="handle-4" class="panel-resizer" size="10px" />
745
+ <Panel id="panel-5" min="200px"
746
+ min="200px"
747
+ collapsible
748
+ collapsedSize="60px"
749
+ defaultCollapsed
750
+ id="panel-5"
751
+ >
752
+ <div>4</div>
753
+ </Panel>
754
+ </PanelGroup>
755
+ <button type="button" @click="isExpanded = true">
756
+ Expand
757
+ </button>
758
+ `,
759
+ }),
760
+ };
761
+
762
+ export const WithDefaultWidth: Story = {
763
+ render: () => ({
764
+ components: { PanelGroup, Panel, PanelResizer },
765
+ template: dedent/*html*/ `
766
+ <PanelGroup :style="{ height: '400px' }" class="panel-group">
767
+ <Panel :style="{ 'background-color': '#333366' }" class="panel" />
768
+ <PanelResizer size="3px" />
769
+ <Panel
770
+ default="100px"
771
+ min="100px"
772
+ max="400px"
773
+ :style="{ 'background-color': '#ff3366' }"
774
+ class="panel"
775
+ />
776
+ </PanelGroup>
777
+ `,
778
+ }),
779
+ };
780
+
781
+ export const StaticAtRest: Story = {
782
+ render: () => ({
783
+ components: { PanelGroup, Panel, PanelResizer },
784
+ template: dedent/*html*/ `
785
+ <PanelGroup :style="{ height: '200px' }" class="panel-group">
786
+ <Panel min="100px" max="300px" isStaticAtRest class="panel">
787
+ Panel 1
788
+ </Panel>
789
+ <PanelResizer class="panel-resizer" size="10px" />
790
+ <Panel min="100px" class="panel">Panel 2</Panel>
791
+ <PanelResizer class="panel-resizer" size="10px" />
792
+ <Panel min="100px" class="panel">Panel 3</Panel>
793
+ </PanelGroup>
794
+ `,
795
+ }),
796
+ };