@onereach/ui-components 2.72.1 → 2.72.2-beta.2260.0

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.
Files changed (56) hide show
  1. package/dist/bundled/v2/{OrSidebar-c95ef614.js → OrSidebar-64cc9127.js} +92 -86
  2. package/dist/bundled/v2/OrSidebarCollapseButton-fcc085c7.js +235 -0
  3. package/dist/bundled/v2/components/index.js +2 -1
  4. package/dist/bundled/v2/components/or-sidebar-v3/OrSidebar.stories3.d.ts +36 -1
  5. package/dist/bundled/v2/components/or-sidebar-v3/OrSidebar.vue.d.ts +49 -4
  6. package/dist/bundled/v2/components/or-sidebar-v3/index.js +13 -1
  7. package/dist/bundled/v2/components/or-sidebar-v3/partials/OrSidebarCollapseButton.stories3.d.ts +12 -0
  8. package/dist/bundled/v2/components/or-sidebar-v3/partials/OrSidebarCollapseButton.vue.d.ts +53 -0
  9. package/dist/bundled/v2/components/or-sidebar-v3/partials/index.d.ts +1 -0
  10. package/dist/bundled/v2/components/or-sidebar-v3/partials/index.js +18 -0
  11. package/dist/bundled/v2/components/or-sidebar-v3/styles.d.ts +9 -1
  12. package/dist/bundled/v2/index.js +3 -2
  13. package/dist/bundled/v3/{OrSidebar.vue_vue_type_script_lang-ce0b152c.js → OrSidebar.vue_vue_type_script_lang-a150808b.js} +75 -80
  14. package/dist/bundled/v3/OrSidebarCollapseButton.vue_vue_type_script_lang-d3e3cd4f.js +185 -0
  15. package/dist/bundled/v3/components/index.js +2 -1
  16. package/dist/bundled/v3/components/or-sidebar-v3/OrSidebar.stories3.d.ts +36 -1
  17. package/dist/bundled/v3/components/or-sidebar-v3/OrSidebar.vue.d.ts +49 -4
  18. package/dist/bundled/v3/components/or-sidebar-v3/index.js +16 -2
  19. package/dist/bundled/v3/components/or-sidebar-v3/partials/OrSidebarCollapseButton.stories3.d.ts +12 -0
  20. package/dist/bundled/v3/components/or-sidebar-v3/partials/OrSidebarCollapseButton.vue.d.ts +53 -0
  21. package/dist/bundled/v3/components/or-sidebar-v3/partials/index.d.ts +1 -0
  22. package/dist/bundled/v3/components/or-sidebar-v3/partials/index.js +17 -0
  23. package/dist/bundled/v3/components/or-sidebar-v3/styles.d.ts +9 -1
  24. package/dist/bundled/v3/index.js +26 -9
  25. package/dist/esm/v2/{OrSidebar-fabc7bc9.js → OrSidebar-a10424d2.js} +92 -86
  26. package/dist/esm/v2/OrSidebarCollapseButton-3b461dfe.js +233 -0
  27. package/dist/esm/v2/components/index.js +2 -1
  28. package/dist/esm/v2/components/or-sidebar-v3/OrSidebar.stories3.d.ts +36 -1
  29. package/dist/esm/v2/components/or-sidebar-v3/OrSidebar.vue.d.ts +49 -4
  30. package/dist/esm/v2/components/or-sidebar-v3/index.js +13 -1
  31. package/dist/esm/v2/components/or-sidebar-v3/partials/OrSidebarCollapseButton.stories3.d.ts +12 -0
  32. package/dist/esm/v2/components/or-sidebar-v3/partials/OrSidebarCollapseButton.vue.d.ts +53 -0
  33. package/dist/esm/v2/components/or-sidebar-v3/partials/index.d.ts +1 -0
  34. package/dist/esm/v2/components/or-sidebar-v3/partials/index.js +16 -0
  35. package/dist/esm/v2/components/or-sidebar-v3/styles.d.ts +9 -1
  36. package/dist/esm/v2/index.js +2 -1
  37. package/dist/esm/v3/{OrSidebar-a62972f5.js → OrSidebar-3be35e8d.js} +81 -89
  38. package/dist/esm/v3/OrSidebarCollapseButton-30d0033b.js +204 -0
  39. package/dist/esm/v3/components/index.js +2 -1
  40. package/dist/esm/v3/components/or-sidebar-v3/OrSidebar.stories3.d.ts +36 -1
  41. package/dist/esm/v3/components/or-sidebar-v3/OrSidebar.vue.d.ts +49 -4
  42. package/dist/esm/v3/components/or-sidebar-v3/index.js +12 -1
  43. package/dist/esm/v3/components/or-sidebar-v3/partials/OrSidebarCollapseButton.stories3.d.ts +12 -0
  44. package/dist/esm/v3/components/or-sidebar-v3/partials/OrSidebarCollapseButton.vue.d.ts +53 -0
  45. package/dist/esm/v3/components/or-sidebar-v3/partials/index.d.ts +1 -0
  46. package/dist/esm/v3/components/or-sidebar-v3/partials/index.js +15 -0
  47. package/dist/esm/v3/components/or-sidebar-v3/styles.d.ts +9 -1
  48. package/dist/esm/v3/index.js +2 -1
  49. package/package.json +2 -3
  50. package/src/components/or-sidebar-v3/OrSidebar.docs.mdx +6 -0
  51. package/src/components/or-sidebar-v3/OrSidebar.stories3.ts +253 -12
  52. package/src/components/or-sidebar-v3/OrSidebar.vue +130 -23
  53. package/src/components/or-sidebar-v3/partials/OrSidebarCollapseButton.stories3.ts +48 -0
  54. package/src/components/or-sidebar-v3/partials/OrSidebarCollapseButton.vue +74 -0
  55. package/src/components/or-sidebar-v3/partials/index.ts +1 -0
  56. package/src/components/or-sidebar-v3/styles.ts +164 -9
@@ -3,8 +3,11 @@ import OrSidebarDocs from './OrSidebar.docs.mdx';
3
3
  import OrSidebar from './OrSidebar.vue';
4
4
  import { OrSidebarPlacement } from './props';
5
5
  import { action } from '@storybook/addon-actions';
6
+ import { ref } from 'vue-demi';
6
7
  import * as Faker from 'faker';
7
8
  import { OrButtonV3 as OrButton } from '../or-button-v3';
9
+ import { OrIconButtonV3 as OrIconButton } from '../or-icon-button-v3';
10
+ import { OrTabsV3 as OrTabs, TabsItem } from '../or-tabs-v3';
8
11
 
9
12
  export default {
10
13
  title: 'Components/Sidebar',
@@ -39,6 +42,15 @@ export default {
39
42
  control: { type: 'text' },
40
43
  },
41
44
 
45
+ toolbar: {
46
+ type: {
47
+ name: 'string',
48
+ required: false,
49
+ },
50
+
51
+ control: { type: 'text' },
52
+ },
53
+
42
54
  // Props
43
55
  width: {
44
56
  control: { type: 'number' },
@@ -52,11 +64,17 @@ export default {
52
64
  control: { type: 'select' },
53
65
  options: Object.values(OrSidebarPlacement),
54
66
  },
67
+
68
+ draggable: {
69
+ control: { type: 'boolean' },
70
+ },
71
+
72
+ collapsible: {
73
+ control: { type: 'boolean' },
74
+ },
55
75
  },
56
76
 
57
77
  parameters: {
58
- layout: 'centered',
59
-
60
78
  docs: {
61
79
  page: OrSidebarDocs,
62
80
  },
@@ -67,6 +85,7 @@ const DefaultTemplate: StoryFn<typeof OrSidebar> = (args) => ({
67
85
  components: {
68
86
  OrSidebar,
69
87
  OrButton,
88
+ OrIconButton,
70
89
  },
71
90
 
72
91
  setup() {
@@ -75,14 +94,24 @@ const DefaultTemplate: StoryFn<typeof OrSidebar> = (args) => ({
75
94
 
76
95
  methods: {
77
96
  onChangeWidth: action('change:width'),
97
+ onOpen: action('open'),
98
+ onClose: action('close'),
78
99
  },
79
100
 
80
101
  template: `
81
- <div style="display: flex; flex-direction: row; border: 1px solid gray; max-height: 500px">
82
- <div style="flex-grow: 1; overflow: auto">
83
- ${Faker.lorem.paragraphs(3)}
102
+ <div style="display: flex; flex-direction: row; border: 1px solid gray; height: 650px">
103
+ <div
104
+ class="theme-background-surface-1 dark:theme-background-surface-1-dark text-on-background dark:text-on-background-dark"
105
+ style="flex-grow: 1; overflow: auto; padding: 16px"
106
+ >
107
+ ${Faker.lorem.paragraphs(10)}
84
108
  </div>
85
- <OrSidebar v-bind="args" @change:width="onChangeWidth">
109
+ <OrSidebar
110
+ v-bind="args"
111
+ @change:width="onChangeWidth"
112
+ @open="onOpen"
113
+ @close="onClose"
114
+ >
86
115
  <template v-if="${!!args.header}" v-slot:header>
87
116
  ${args.header}
88
117
  </template>
@@ -92,6 +121,9 @@ const DefaultTemplate: StoryFn<typeof OrSidebar> = (args) => ({
92
121
  <template v-if="${!!args.footer}" v-slot:footer>
93
122
  ${args.footer}
94
123
  </template>
124
+ <template v-if="${!!args.toolbar}" v-slot:toolbar>
125
+ ${args.toolbar}
126
+ </template>
95
127
  </OrSidebar>
96
128
  </div>
97
129
  `,
@@ -101,6 +133,7 @@ const LeftTemplate: StoryFn<typeof OrSidebar> = (args) => ({
101
133
  components: {
102
134
  OrSidebar,
103
135
  OrButton,
136
+ OrIconButton,
104
137
  },
105
138
 
106
139
  setup() {
@@ -109,11 +142,18 @@ const LeftTemplate: StoryFn<typeof OrSidebar> = (args) => ({
109
142
 
110
143
  methods: {
111
144
  onChangeWidth: action('change:width'),
145
+ onOpen: action('open'),
146
+ onClose: action('close'),
112
147
  },
113
148
 
114
149
  template: `
115
- <div style="display: flex; flex-direction: row; border: 1px solid gray; max-height: 500px">
116
- <OrSidebar v-bind="args" @change:width="onChangeWidth">
150
+ <div style="display: flex; flex-direction: row; border: 1px solid gray; height: 650px">
151
+ <OrSidebar
152
+ v-bind="args"
153
+ @change:width="onChangeWidth"
154
+ @open="onOpen"
155
+ @close="onClose"
156
+ >
117
157
  <template v-if="${!!args.header}" v-slot:header>
118
158
  ${args.header}
119
159
  </template>
@@ -123,14 +163,150 @@ const LeftTemplate: StoryFn<typeof OrSidebar> = (args) => ({
123
163
  <template v-if="${!!args.footer}" v-slot:footer>
124
164
  ${args.footer}
125
165
  </template>
166
+ <template v-if="${!!args.toolbar}" v-slot:toolbar>
167
+ ${args.toolbar}
168
+ </template>
126
169
  </OrSidebar>
127
- <div style="flex-grow: 1; overflow: auto">
128
- ${Faker.lorem.paragraphs(3)}
170
+ <div
171
+ class="theme-background-surface-1 dark:theme-background-surface-1-dark text-on-background dark:text-on-background-dark"
172
+ style="flex-grow: 1; overflow: auto; padding: 16px"
173
+ >
174
+ ${Faker.lorem.paragraphs(10)}
175
+ </div>
176
+ </div>
177
+ `,
178
+ });
179
+
180
+ const TabsTemplate: StoryFn<typeof OrSidebar> = (args) => ({
181
+ components: {
182
+ OrSidebar,
183
+ OrButton,
184
+ OrIconButton,
185
+ OrTabs,
186
+ },
187
+
188
+ setup() {
189
+ // State
190
+ const model = ref<string>();
191
+
192
+ return {
193
+ args,
194
+ model,
195
+ };
196
+ },
197
+
198
+ methods: {
199
+ onChangeWidth: action('change:width'),
200
+ onOpen: action('open'),
201
+ onClose: action('close'),
202
+ },
203
+
204
+ template: `
205
+ <div style="display: flex; flex-direction: row; border: 1px solid gray; height: 650px">
206
+ <div
207
+ class="theme-background-surface-1 dark:theme-background-surface-1-dark text-on-background dark:text-on-background-dark"
208
+ style="flex-grow: 1; overflow: auto; padding: 16px"
209
+ >
210
+ ${Faker.lorem.paragraphs(10)}
129
211
  </div>
212
+ <OrSidebar
213
+ v-bind="args"
214
+ @change:width="onChangeWidth"
215
+ @open="onOpen"
216
+ @close="onClose"
217
+ >
218
+ <template v-if="${!!args.header}" v-slot:header>
219
+ ${args.header}
220
+ </template>
221
+ <template v-if="${!!args.default}" v-slot:default>
222
+ ${args.default}
223
+ </template>
224
+ <template v-else v-slot:default>
225
+ <or-tabs
226
+ v-model="model"
227
+ :items="args.items"
228
+ >
229
+ <template v-for="item in args.items" #[item.value]>
230
+ {{ item.label }} Content
231
+ ${Faker.lorem.paragraphs(3)}
232
+ </template>
233
+ </or-tabs>
234
+ </template>
235
+ <template v-if="${!!args.footer}" v-slot:footer>
236
+ ${args.footer}
237
+ </template>
238
+ <template v-if="${!!args.toolbar}" v-slot:toolbar>
239
+ ${args.toolbar}
240
+ </template>
241
+ </OrSidebar>
130
242
  </div>
131
243
  `,
132
244
  });
133
245
 
246
+ const longToolbar = `
247
+ <or-icon-button
248
+ icon="refresh"
249
+ color="inherit"
250
+ />
251
+ <hr class="w-full border-outline-variant dark:border-outline-variant-dark" />
252
+ <or-icon-button
253
+ icon="add"
254
+ color="inherit"
255
+ />
256
+ <or-icon-button
257
+ icon="zoom_out_map"
258
+ color="inherit"
259
+ />
260
+ <or-icon-button
261
+ icon="remove"
262
+ color="inherit"
263
+ />
264
+ <hr class="w-full border-outline-variant dark:border-outline-variant-dark" />
265
+ <or-icon-button
266
+ icon="description"
267
+ color="inherit"
268
+ />
269
+ <or-icon-button
270
+ icon="tab_unselected"
271
+ color="inherit"
272
+ />
273
+ <hr class="w-full border-outline-variant dark:border-outline-variant-dark" />
274
+ <or-icon-button
275
+ icon="create_new_folder"
276
+ color="inherit"
277
+ />
278
+ <or-icon-button
279
+ icon="content_paste"
280
+ color="inherit"
281
+ />
282
+ <or-icon-button
283
+ icon="location_on"
284
+ color="inherit"
285
+ />
286
+ <or-icon-button
287
+ icon="copy_all"
288
+ color="inherit"
289
+ />
290
+ <or-icon-button
291
+ icon="call_split"
292
+ color="inherit"
293
+ />
294
+ <hr class="w-full border-outline-variant dark:border-outline-variant-dark" />
295
+ <or-icon-button
296
+ icon="sell"
297
+ color="inherit"
298
+ />
299
+ <div class="mt-auto" />
300
+ <or-icon-button
301
+ icon="terminal"
302
+ color="inherit"
303
+ />
304
+ <or-icon-button
305
+ icon="delete"
306
+ color="inherit"
307
+ />
308
+ `;
309
+
134
310
  export const Default = DefaultTemplate.bind({});
135
311
  Default.args = {
136
312
  header: 'Header',
@@ -138,11 +314,24 @@ Default.args = {
138
314
  footer: 'Footer',
139
315
  };
140
316
 
141
- export const WithMinimumWidth = DefaultTemplate.bind({});
142
- WithMinimumWidth.args = {
317
+ export const WithCustomWidthConstraints = DefaultTemplate.bind({});
318
+ WithCustomWidthConstraints.args = {
143
319
  ...Default.args,
144
320
  width: 250,
145
321
  minimumWidth: 200,
322
+ maximumWidth: 500,
323
+ };
324
+
325
+ export const NotDraggable = DefaultTemplate.bind({});
326
+ NotDraggable.args = {
327
+ ...Default.args,
328
+ draggable: false,
329
+ };
330
+
331
+ export const Collapsible = DefaultTemplate.bind({});
332
+ Collapsible.args = {
333
+ ...Default.args,
334
+ collapsible: true,
146
335
  };
147
336
 
148
337
  export const OnlyContent = DefaultTemplate.bind({});
@@ -167,8 +356,60 @@ WithFooter.args = {
167
356
  `,
168
357
  };
169
358
 
359
+ export const WithToolbar = DefaultTemplate.bind({});
360
+ WithToolbar.args = {
361
+ ...OnlyContent.args,
362
+ toolbar: longToolbar,
363
+ };
364
+
365
+ export const CollapsibleWithToolbar = DefaultTemplate.bind({});
366
+ CollapsibleWithToolbar.args = {
367
+ ...WithToolbar.args,
368
+ collapsible: true,
369
+ };
370
+
371
+ export const WithTabs = TabsTemplate.bind({});
372
+ WithTabs.args = {
373
+ minimumWidth: 352,
374
+ header: 'Headline',
375
+ items: Array.from<string, TabsItem>([
376
+ 'Alfa',
377
+ 'Bravo',
378
+ 'Charlie',
379
+ 'Delta',
380
+ 'Echo',
381
+ 'Foxtrot',
382
+ 'Golf',
383
+ 'Hotel',
384
+ 'India',
385
+ 'Juliett',
386
+ ], (item) => ({
387
+ value: item.toLowerCase(),
388
+ label: item,
389
+ })),
390
+ footer: `
391
+ <div style="display: flex; flex-direction: row; justify-content: end; gap: 16px">
392
+ <or-button color="danger" variant="outlined">Delete</or-button>
393
+ <or-button variant="outlined" class="ml-auto">Cancel</or-button>
394
+ <or-button>Save</or-button>
395
+ </div>
396
+ `,
397
+ };
398
+
170
399
  export const LeftSidebar = LeftTemplate.bind({});
171
400
  LeftSidebar.args = {
172
401
  ...Default.args,
173
402
  side: 'left',
174
403
  };
404
+
405
+ export const WithLeftToolbar = LeftTemplate.bind({});
406
+ WithLeftToolbar.args = {
407
+ ...LeftSidebar.args,
408
+ toolbar: longToolbar,
409
+ };
410
+
411
+ export const CollapsibleWithWithLeftToolbar = LeftTemplate.bind({});
412
+ CollapsibleWithWithLeftToolbar.args = {
413
+ ...WithLeftToolbar.args,
414
+ collapsible: true,
415
+ };
@@ -2,28 +2,55 @@
2
2
  <aside
3
3
  ref="root"
4
4
  :class="rootStyles"
5
- :style="sidebarStyle"
6
5
  >
7
6
  <div
8
- ref="resizeBar"
9
- :class="resizeStyles"
10
- />
11
- <div :class="mainStyles">
7
+ v-if="side === 'right' && isShowingToolbar"
8
+ :class="toolbarStyles"
9
+ >
10
+ <slot name="toolbar" />
11
+ </div>
12
+ <div
13
+ :class="sidebarStyles"
14
+ :style="sidebarStyle"
15
+ >
12
16
  <div
13
- v-if="$slots.header"
14
- :class="headerStyles"
17
+ v-if="draggable && !isCollapsed"
18
+ ref="resizeBar"
19
+ :class="resizeStyles"
20
+ />
21
+ <or-sidebar-collapse-button
22
+ v-if="collapsible"
23
+ v-model="isCollapsed"
24
+ :class="collapsibleButtonStyles"
25
+ :side="side"
26
+ />
27
+ <div
28
+ v-show="!isCollapsed"
29
+ :class="mainStyles"
15
30
  >
16
- <slot name="header" />
31
+ <div
32
+ v-if="$slots.header"
33
+ :class="headerStyles"
34
+ >
35
+ <slot name="header" />
36
+ </div>
37
+ <div :class="contentStyles">
38
+ <slot />
39
+ </div>
17
40
  </div>
18
- <div :class="contentStyles">
19
- <slot />
41
+ <div
42
+ v-if="$slots.footer"
43
+ v-show="!isCollapsed"
44
+ :class="footerStyles"
45
+ >
46
+ <slot name="footer" />
20
47
  </div>
21
48
  </div>
22
49
  <div
23
- v-if="$slots.footer"
24
- :class="footerStyles"
50
+ v-if="side === 'left' && isShowingToolbar"
51
+ :class="toolbarStyles"
25
52
  >
26
- <slot name="footer" />
53
+ <slot name="toolbar" />
27
54
  </div>
28
55
  </aside>
29
56
  </template>
@@ -31,34 +58,48 @@
31
58
  <script lang="ts">
32
59
  import { useDraggable, useElementBounding } from '@vueuse/core';
33
60
  import _ from 'lodash';
34
- import { computed, defineComponent, PropType, ref, watch } from 'vue-demi';
61
+ import { computed, defineComponent, PropType, ref, watch, useSlots } from 'vue-demi';
35
62
  import { OrSidebarPlacement } from './props';
36
63
  import {
37
64
  SidebarRoot,
38
- SidebarRootSides,
65
+ SidebarBar,
66
+ SidebarToolbar,
67
+ CollapsibleSidebarToolbar,
68
+ SidebarSides,
69
+ SidebarToolbarSides,
39
70
  SidebarResize,
40
71
  SidebarResizeSides,
72
+ SidebarCollapseButton,
73
+ SidebarCollapseButtonSides,
41
74
  SidebarResizingSides,
42
75
  SidebarMain,
43
76
  SidebarHeader,
44
77
  SidebarContent,
45
78
  SidebarFooter,
46
79
  } from './styles';
80
+ import { OrSidebarCollapseButton } from './partials';
47
81
 
48
82
  export default defineComponent({
49
83
  name: 'OrSidebar',
50
84
 
85
+ components: {
86
+ OrSidebarCollapseButton,
87
+ },
88
+
51
89
  props: {
52
90
  width: {
53
91
  type: Number,
54
- required: false,
55
- default: 0,
92
+ default: 320,
56
93
  validator: (value?: any) => _.isNumber(value) && value >= 0,
57
94
  },
58
95
  minimumWidth: {
59
96
  type: Number,
60
- required: false,
61
- default: 350,
97
+ default: 256,
98
+ validator: (value?: any) => _.isNumber(value) && value >= 0,
99
+ },
100
+ maximumWidth: {
101
+ type: Number,
102
+ default: 384,
62
103
  validator: (value?: any) => _.isNumber(value) && value >= 0,
63
104
  },
64
105
  /**
@@ -73,9 +114,27 @@ export default defineComponent({
73
114
  default: OrSidebarPlacement.right,
74
115
  validator: (value?: any) => _.includes(_.values(OrSidebarPlacement), value),
75
116
  },
117
+ draggable: {
118
+ type: Boolean,
119
+ default: true,
120
+ },
121
+ collapsible: {
122
+ type: Boolean,
123
+ default: false,
124
+ },
76
125
  },
77
126
 
78
- emits: ['change:width'],
127
+ emits: [
128
+ 'change:width',
129
+ 'open',
130
+ 'close',
131
+ ],
132
+
133
+ expose: [
134
+ 'root',
135
+ 'open',
136
+ 'close',
137
+ ],
79
138
 
80
139
  setup(props, { emit }) {
81
140
  // Refs
@@ -84,20 +143,37 @@ export default defineComponent({
84
143
 
85
144
  const parentContainer = computed(() => root.value?.parentElement);
86
145
 
146
+ // Slots
147
+ const { toolbar: toolbarSlot } = useSlots();
148
+
87
149
  // State
88
150
  const startPositionX = ref(0);
89
151
  const isResizing = ref(false);
152
+ const isCollapsed = ref(false);
153
+ const maximumWidth = ref(props.maximumWidth || 384);
90
154
  const localWidth = ref(props.width >= props.minimumWidth ? props.width : props.minimumWidth);
91
155
 
156
+ const isShowingToolbar = computed(() => !!toolbarSlot);
157
+
92
158
  // Styles
93
159
  const sidebarStyle = computed(() => ({
94
- width: localWidth.value + 'px',
160
+ width: (isCollapsed.value ? 16 : localWidth.value) + 'px',
95
161
  }));
96
162
 
97
163
  const rootStyles = computed(() => [
98
164
  'or-sidebar',
99
165
  ...SidebarRoot,
100
- ...SidebarRootSides[props.side],
166
+ ]);
167
+
168
+ const sidebarStyles = computed(() => [
169
+ ...SidebarBar,
170
+ ...SidebarSides[props.side],
171
+ ]);
172
+
173
+ const toolbarStyles = computed(() => [
174
+ ...SidebarToolbar,
175
+ ...(props.collapsible ? CollapsibleSidebarToolbar : []),
176
+ ...SidebarToolbarSides[props.side],
101
177
  ]);
102
178
 
103
179
  const resizeStyles = computed(() => [
@@ -106,6 +182,11 @@ export default defineComponent({
106
182
  ...(isResizing.value ? SidebarResizingSides[props.side] : []),
107
183
  ]);
108
184
 
185
+ const collapsibleButtonStyles = computed(() => [
186
+ ...SidebarCollapseButton,
187
+ ...SidebarCollapseButtonSides[props.side],
188
+ ]);
189
+
109
190
  const mainStyles = computed(() => [...SidebarMain]);
110
191
 
111
192
  const headerStyles = computed(() => [...SidebarHeader]);
@@ -137,7 +218,16 @@ export default defineComponent({
137
218
  },
138
219
  });
139
220
 
140
- const { width: maximumWidth } = useElementBounding(parentContainer);
221
+ // Methods
222
+ function open(): void {
223
+ isCollapsed.value = false;
224
+ }
225
+
226
+ function close(): void {
227
+ isCollapsed.value = true;
228
+ }
229
+
230
+ const { width: containerWidth } = useElementBounding(parentContainer);
141
231
 
142
232
  watch(() => props.width, (newValue: number) => {
143
233
  if (newValue !== localWidth.value) {
@@ -150,24 +240,41 @@ export default defineComponent({
150
240
  if (newMinimum > localWidth.value) localWidth.value = newMinimum;
151
241
  });
152
242
 
243
+ watch(() => props.maximumWidth, (newMaximum: number) => {
244
+ if (newMaximum < maximumWidth.value) maximumWidth.value = newMaximum;
245
+ });
246
+
247
+ watch(containerWidth, (newMaximum: number) => {
248
+ if (newMaximum < maximumWidth.value) maximumWidth.value = newMaximum;
249
+ });
250
+
153
251
  watch(maximumWidth, (newMaximum: number) => {
154
252
  if (newMaximum < localWidth.value) localWidth.value = newMaximum;
155
253
  });
156
254
 
157
255
  watch(localWidth, (val: number) => emit('change:width', val));
158
256
 
257
+ watch(isCollapsed, (val: boolean) => emit(val ? 'close' : 'open'));
258
+
159
259
  return {
160
260
  root,
161
261
  resizeBar,
162
262
  isResizing,
263
+ isCollapsed,
163
264
  localWidth,
265
+ isShowingToolbar,
164
266
  sidebarStyle,
165
267
  rootStyles,
268
+ sidebarStyles,
269
+ toolbarStyles,
166
270
  resizeStyles,
271
+ collapsibleButtonStyles,
167
272
  mainStyles,
168
273
  headerStyles,
169
274
  contentStyles,
170
275
  footerStyles,
276
+ open,
277
+ close,
171
278
  };
172
279
  },
173
280
  });
@@ -0,0 +1,48 @@
1
+ import { Meta, StoryFn } from '@storybook/vue3';
2
+ import OrSidebarCollapseButton from './OrSidebarCollapseButton.vue';
3
+ import { OrSidebarPlacement } from '../props';
4
+ import { action } from '@storybook/addon-actions';
5
+ import { ref } from 'vue-demi';
6
+
7
+ export default {
8
+ title: 'Components/Sidebar/Parts/CollapseButton',
9
+ component: OrSidebarCollapseButton,
10
+
11
+ argTypes: {
12
+ // Props
13
+ modelValue: {
14
+ control: { type: 'boolean' },
15
+ },
16
+
17
+ side: {
18
+ control: { type: 'select' },
19
+ options: Object.values(OrSidebarPlacement),
20
+ },
21
+ },
22
+ } as Meta<typeof OrSidebarCollapseButton>;
23
+
24
+ const DefaultTemplate: StoryFn<typeof OrSidebarCollapseButton> = (args) => ({
25
+ components: {
26
+ OrSidebarCollapseButton,
27
+ },
28
+
29
+ setup() {
30
+ const collapsed = ref<boolean>(!!args.modelValue);
31
+
32
+ return {
33
+ args,
34
+ collapsed,
35
+ };
36
+ },
37
+
38
+ methods: {
39
+ onUpdateModelValue: action('update:modelValue'),
40
+ },
41
+
42
+ template: '<OrSidebarCollapseButton v-model="collapsed" v-bind="args" @update:modelValue="onUpdateModelValue" />',
43
+ });
44
+
45
+ export const Default = DefaultTemplate.bind({});
46
+ Default.args = {
47
+ side: OrSidebarPlacement.right,
48
+ };