Skip to content

Commit 731fd6c

Browse files
feat: add support for custom slot container classes (#44)
1 parent 4e057e9 commit 731fd6c

File tree

6 files changed

+54
-23
lines changed

6 files changed

+54
-23
lines changed

docs/content/1.getting-started/2.usage.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ import { SplitPanel } from '@directus/vue-split-panel';
121121
How close the divider must be to a snap point for snapping to occur.
122122
Defaults to `12`
123123
::
124+
125+
::field{name="ui" type="{ start?: string, divider?: string, end?: string }"}
126+
Inject additional classes in the slot container elements.
127+
::
124128
::
125129

126130
### Emits

packages/vue-split-panel/playground/src/App.vue

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@ const collapsed = ref(false);
77
</script>
88

99
<template>
10-
<SplitPanel id="panels-root" v-model:size="size" v-model:collapsed="collapsed" collapsible :collapse-threshold="100" :min-size="250" :max-size="400" size-unit="px">
10+
<SplitPanel
11+
id="panels-root"
12+
v-model:size="size"
13+
v-model:collapsed="collapsed"
14+
collapsible
15+
:collapse-threshold="100"
16+
:min-size="250"
17+
:max-size="400"
18+
size-unit="px"
19+
:ui="{
20+
divider: 'my-custom-class',
21+
}"
22+
>
1123
<template #start>
1224
<div id="a" class="panel">
1325
Panel A

packages/vue-split-panel/src/SplitPanel.vue

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,22 @@ defineExpose({ collapse, expand, toggle });
108108
<template>
109109
<div
110110
ref="split-panel"
111-
class="split-panel"
112-
:class="[orientation, collapseTransitionState, { collapsed, dragging: isDragging }]"
111+
class="sp-root"
112+
:class="[
113+
`sp-${orientation}`,
114+
`sp-${collapseTransitionState}`,
115+
{ 'sp-collapsed': collapsed, 'sp-dragging': isDragging },
116+
]"
113117
data-testid="root"
114118
@transitionend="onTransitionEnd"
115119
>
116-
<div class="start" data-testid="start">
120+
<div class="sp-start" :class="ui?.start" data-testid="start">
117121
<slot name="start" />
118122
</div>
119123
<div
120124
ref="divider"
121-
class="divider"
122-
:class="[{ disabled }, orientation]"
125+
class="sp-divider"
126+
:class="[{ 'sp-disabled': disabled }, `sp-${orientation}`, ui?.divider]"
123127
:tabindex="disabled ? undefined : 0"
124128
role="separator"
125129
:aria-valuenow="sizePercentage"
@@ -134,54 +138,54 @@ defineExpose({ collapse, expand, toggle });
134138
<div />
135139
</slot>
136140
</div>
137-
<div class="end" data-testid="end">
141+
<div class="sp-end" :class="ui?.end" data-testid="end">
138142
<slot name="end" />
139143
</div>
140144
</div>
141145
</template>
142146

143147
<style scoped>
144-
.split-panel {
148+
.sp-root {
145149
display: grid;
146150
147-
&.horizontal {
151+
&.sp-horizontal {
148152
transition-property: grid-template-columns;
149153
grid-template-columns: v-bind(gridTemplate);
150154
151-
&.dragging {
155+
&.sp-dragging {
152156
cursor: ew-resize;
153157
}
154158
}
155159
156-
&.vertical {
160+
&.sp-vertical {
157161
grid-template-rows: v-bind(gridTemplate);
158162
transition-property: grid-template-rows;
159163
160-
&.dragging {
164+
&.sp-dragging {
161165
cursor: ns-resize;
162166
}
163167
}
164168
165-
&.dragging {
169+
&.sp-dragging {
166170
user-select: none;
167171
}
168172
169-
&.collapsing {
173+
&.sp-collapsing {
170174
transition-duration: v-bind(transitionDuration);
171175
transition-timing-function: v-bind(transitionTimingFunctionCollapse);
172176
}
173177
174-
&.expanding {
178+
&.sp-expanding {
175179
transition-duration: v-bind(transitionDuration);
176180
transition-timing-function: v-bind(transitionTimingFunctionExpand);
177181
}
178182
}
179183
180-
.start, .end {
184+
.sp-start, .sp-end {
181185
overflow: hidden;
182186
}
183187
184-
.divider {
188+
.sp-divider {
185189
position: relative;
186190
z-index: 1;
187191
@@ -193,7 +197,7 @@ defineExpose({ collapse, expand, toggle });
193197
}
194198
}
195199
196-
&.horizontal {
200+
&.sp-horizontal {
197201
block-size: 100%;
198202
inline-size: max-content;
199203
@@ -206,7 +210,7 @@ defineExpose({ collapse, expand, toggle });
206210
}
207211
}
208212
209-
&.vertical {
213+
&.sp-vertical {
210214
inline-size: 100%;
211215
block-size: max-content;
212216

packages/vue-split-panel/src/types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ export type Direction = 'ltr' | 'rtl';
33
export type Primary = 'start' | 'end';
44
export type SizeUnit = '%' | 'px';
55

6+
export interface UiClasses {
7+
start?: string;
8+
divider?: string;
9+
end?: string;
10+
}
11+
612
export interface SplitPanelProps {
713
/**
814
* Sets the split panel's orientation
@@ -84,4 +90,9 @@ export interface SplitPanelProps {
8490
* @default 12
8591
*/
8692
snapThreshold?: number;
93+
94+
/**
95+
* Inject additional classes into the elements that split-panel renders
96+
*/
97+
ui?: UiClasses;
8798
}

packages/vue-split-panel/tests/collapse.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@ describe('collapse', () => {
88
props: { collapsed: true },
99
});
1010

11-
expect(wrapper.find('[data-testid="root"]').classes()).toContain('collapsed');
11+
expect(wrapper.find('[data-testid="root"]').classes()).toContain('sp-collapsed');
1212
});
1313

1414
it('is not collapsed when collapsed is set to false', () => {
1515
const wrapper = mount(SplitPanel, {
1616
props: { collapsed: false },
1717
});
1818

19-
expect(wrapper.find('[data-testid="root"]').classes()).not.toContain('collapsed');
19+
expect(wrapper.find('[data-testid="root"]').classes()).not.toContain('sp-collapsed');
2020
});
2121

2222
it('can be collapsed through a prop even when collapsible is false', () => {
2323
const wrapper = mount(SplitPanel, {
2424
props: { collapsible: false, collapsed: true },
2525
});
2626

27-
expect(wrapper.find('[data-testid="root"]').classes()).toContain('collapsed');
27+
expect(wrapper.find('[data-testid="root"]').classes()).toContain('sp-collapsed');
2828
});
2929

3030
it('sets size to 0 when collapsed', async () => {

packages/vue-split-panel/tests/mounting.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe('basic mounting and rendering', () => {
3131

3232
it('renders default divider div when no divider slot content is given', () => {
3333
const wrapper = mount(SplitPanel);
34-
const divider = wrapper.find('.divider');
34+
const divider = wrapper.find('[data-testid="divider"]');
3535

3636
expect(divider.exists()).toBe(true);
3737
expect(divider.find('div').exists()).toBe(true);

0 commit comments

Comments
 (0)