Skip to content

Commit ebf4b4d

Browse files
authored
1.2.0 (#14)
* up deps * improve type generation * convert from h to vue, replace props with emits, add auto transition * replace props to emits in tests * edit demo * edit readme * register global component in demo * added missing watch from prev file * bump 1.2.0 * edit readme
1 parent 23fe3d3 commit ebf4b4d

16 files changed

+378
-362
lines changed

README.md

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ Dynamic CSS height transition from _any to auto_ and vice versa. Accordion ready
77

88
[Examples and Demo](https://vue-collapsed.netlify.com) - [Stackblitz](https://stackblitz.com/edit/vue-dmjqey?file=src/App.vue)
99

10-
> :bulb: Requires Vue v3.0.0 or above.
11-
1210
<br />
1311

1412
Check out my other packages for Vue 3:
@@ -37,15 +35,20 @@ npm i -S vue-collapsed
3735

3836
## Props
3937

40-
| name | description | type | required |
41-
| ------------- | ----------------------------------------- | ----------------------------- | ------------------ |
42-
| `when` | Value to control collapse | boolean | :white_check_mark: |
43-
| `baseHeight` | Collapsed height in px, defaults to `0`. | number | :x: |
44-
| `as` | Tag to use instead of `div` | _keyof_ HTMLElementTagNameMap | :x: |
45-
| `onExpand` | Callback on expand transition start | () => void | :x: |
46-
| `onExpanded` | Callback on expand transition completed | () => void | :x: |
47-
| `onCollapse` | Callback on collapse transition start | () => void | :x: |
48-
| `onCollapsed` | Callback on collapse transition completed | () => void | :x: |
38+
| Name | Description | Type | Required |
39+
| ------------ | ---------------------------------------- | ----------------------------- | ------------------ |
40+
| `when` | Value to control collapse | boolean | :white_check_mark: |
41+
| `baseHeight` | Collapsed height in px, defaults to `0`. | number | :x: |
42+
| `as` | Tag to use instead of `div` | _keyof_ HTMLElementTagNameMap | :x: |
43+
44+
## Emits
45+
46+
| Name | Description | Type |
47+
| ------------ | ----------------------------- | ---------- |
48+
| `@expand` | Expand transition start | () => void |
49+
| `@expanded` | Expand transition completed | () => void |
50+
| `@collapse` | Collapse transition start | () => void |
51+
| `@collapsed` | Collapse transition completed | () => void |
4952

5053
## Usage
5154

@@ -58,36 +61,43 @@ const isExpanded = ref(false)
5861
</script>
5962
6063
<template>
61-
<button @click="isExpanded = !isExpanded">This a panel.</button>
62-
<Collapse :when="isExpanded" class="v-collapse">
64+
<button @click="isExpanded = !isExpanded">Trigger</button>
65+
66+
<Collapse :when="isExpanded">
6367
<p>This is a paragraph.</p>
6468
</Collapse>
6569
</template>
66-
67-
<style>
68-
.v-collapse {
69-
transition: height 300ms cubic-bezier(0.33, 1, 0.68, 1);
70-
}
71-
</style>
7270
```
7371

74-
## Auto Duration
72+
## Automatic Transition / Duration
73+
74+
By default, as long as no class is added to the `Collapse` element, `vue-collapsed` will add this transition for you:
75+
76+
`height var(--vc-auto-duration) cubic-bezier(0.33, 1, 0.68, 1)`
7577

76-
Vue Collapsed automatically calculates the optimal duration according to the content height. Use it by referencing the variable `--vc-auto-duration`:
78+
`var(--vc-auto-duration)` corresponds to the optimal transition duration which is automatically calculated according to the content height.
79+
80+
If you prefer to use a custom duration or easing, add a class to Collapse that transitions the `height` property:
81+
82+
```vue
83+
<Collapse :when="isExpanded" class="v-collapse">
84+
<p>This is a paragraph.</p>
85+
</Collapse>
86+
```
7787

7888
```css
7989
.v-collapse {
80-
transition: height var(--vc-auto-duration) ease-out;
90+
transition: height 300ms ease-out;
8191
}
8292
```
8393

8494
:bulb: Use [calc()](https://developer.mozilla.org/en-US/docs/Web/CSS/calc) to control the speed, _e.g. `calc(var(--vc-auto-duration) * 0.75)`_.
8595

8696
:bulb: Find a full list of easings at [easings.net](https://easings.net).
8797

88-
## Additional transitions/styles
98+
## Multiple transitions
8999

90-
To transition other properties or add granular styles use the attribute `data-collapse`:
100+
To transition other properties use the attribute `data-collapse`:
91101

92102
| Transition | From | Enter | Leave |
93103
| ---------- | ----------- | ------------ | ----------- |
@@ -115,7 +125,7 @@ Above values can also be accessed using `v-slot`:
115125

116126
```vue
117127
<Collapse :when="isExpanded" class="v-collapse" v-slot="{ state }">
118-
{{ state === 'collapsing' ? 'Collapsing...' : null }}
128+
{{ state === 'collapsing' ? 'Collapsing the content...' : null }}
119129
</Collapse>
120130
```
121131

@@ -164,19 +174,13 @@ function handleAccordion(selectedIndex) {
164174
<button @click="handleAccordion(index)">
165175
{{ question.title }}
166176
</button>
167-
<Collapse :when="questions[index].isExpanded" class="v-collapse">
177+
<Collapse :when="questions[index].isExpanded">
168178
<p>
169179
{{ question.answer }}
170180
</p>
171181
</Collapse>
172182
</div>
173183
</template>
174-
175-
<style>
176-
.v-collapse {
177-
transition: height var(--vc-auto-duration) cubic-bezier(0.33, 1, 0.68, 1);
178-
}
179-
</style>
180184
```
181185

182186
## Example - Callbacks
@@ -197,23 +201,13 @@ function scrollIntoView(index) {
197201
<button @click="handleAccordion(index)">
198202
{{ question.title }}
199203
</button>
200-
<Collapse
201-
:when="questions[index].isExpanded"
202-
:onExpanded="() => scrollIntoView(index)"
203-
class="v-collapse"
204-
>
204+
<Collapse :when="questions[index].isExpanded" @expanded="() => scrollIntoView(index)">
205205
<p>
206206
{{ question.answer }}
207207
</p>
208208
</Collapse>
209209
</div>
210210
</template>
211-
212-
<style>
213-
.v-collapse {
214-
transition: height var(--vc-auto-duration) cubic-bezier(0.33, 1, 0.68, 1);
215-
}
216-
</style>
217211
```
218212

219213
## Make it accessible
@@ -245,17 +239,11 @@ function handleCollapse() {
245239
<template>
246240
<div>
247241
<button v-bind="toggleAttrs" @click="handleCollapse">This a panel.</button>
248-
<Collapse v-bind="collapseAttrs" :when="isExpanded" class="v-collapse">
242+
<Collapse v-bind="collapseAttrs" :when="isExpanded">
249243
<p>This is a paragraph.</p>
250244
</Collapse>
251245
</div>
252246
</template>
253-
254-
<style>
255-
.v-collapse {
256-
transition: height var(--vc-auto-duration) cubic-bezier(0.33, 1, 0.68, 1);
257-
}
258-
</style>
259247
```
260248

261249
## License

demo/Accordion.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script setup lang="ts">
22
import { reactive } from 'vue'
3+
34
import ExampleHeader from './ExampleHeader.vue'
5+
46
import fakeData from './fakeData.json'
57
68
const questions = reactive(
@@ -36,8 +38,8 @@ function handleAccordion(selectedIndex: number) {
3638
{{ question.title }}
3739
</button>
3840

39-
<Collapse as="section" :when="question.isExpanded" class="v-collapse">
40-
<p>
41+
<Collapse as="section" :when="question.isExpanded">
42+
<p class="CollapseContent">
4143
{{ question.answer }}
4244
</p>
4345
</Collapse>

demo/AdvancedControl.vue

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
<script lang="ts" setup>
22
import { ref } from 'vue'
3+
34
import ExampleHeader from './ExampleHeader.vue'
45
56
const isExpanded = ref(true)
67
78
function handleCollapse() {
89
isExpanded.value = !isExpanded.value
910
}
10-
11-
function capitalize(string: string) {
12-
return string && string[0].toUpperCase() + string.slice(1)
13-
}
1411
</script>
1512

1613
<template>
@@ -25,7 +22,7 @@ function capitalize(string: string) {
2522
<div class="InnerElement">
2623
<button @click="handleCollapse">Toggle</button>
2724

28-
{{ capitalize(state) }}{{ state.endsWith('ing') ? '...' : '.' }}
25+
{{ state }}{{ state.endsWith('ing') ? '...' : '.' }}
2926
</div>
3027
</Collapse>
3128
</article>
@@ -34,6 +31,7 @@ function capitalize(string: string) {
3431
<style>
3532
.AdvancedCollapse {
3633
--easing-dur: calc(var(--vc-auto-duration) * 1.5) cubic-bezier(0.33, 1, 0.68, 1);
34+
3735
transition: height var(--easing-dur), background-color var(--easing-dur),
3836
border-radius var(--easing-dur);
3937
}
@@ -60,6 +58,7 @@ function capitalize(string: string) {
6058
font-size: 1.75rem;
6159
color: var(--BackgroundColor);
6260
height: 400px;
61+
text-transform: capitalize;
6362
}
6463
6564
.InnerElement button {

demo/App.vue

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,7 @@ footer {
194194
cursor: pointer;
195195
}
196196
197-
.v-collapse {
198-
transition: height var(--vc-auto-duration) cubic-bezier(0.33, 1, 0.68, 1);
199-
}
200-
201-
.v-collapse p {
197+
.CollapseContent {
202198
padding: 0 10px 10px;
203199
margin: 0;
204200
color: var(--ForegroundColorLight);
@@ -226,7 +222,7 @@ footer {
226222
padding: 20px 10px;
227223
}
228224
229-
.v-collapse p {
225+
.CollapseContent {
230226
padding: 0 20px 20px;
231227
margin: 0;
232228
color: var(--ForegroundColorLight);

demo/IndividualControl.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script setup lang="ts">
22
import { ref, computed } from 'vue'
3+
34
import ExampleHeader from './ExampleHeader.vue'
5+
46
import fakeData from './fakeData.json'
57
68
const questions = ref(
@@ -58,8 +60,8 @@ const collapseAttrs = computed(() =>
5860
>
5961
{{ question.title }}
6062
</button>
61-
<Collapse :when="question.isExpanded" class="v-collapse" v-bind="collapseAttrs[index]">
62-
<p>
63+
<Collapse :when="question.isExpanded" v-bind="collapseAttrs[index]">
64+
<p class="CollapseContent">
6365
{{ question.answer }}
6466
</p>
6567
</Collapse>

demo/SingleCollapse.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ const collapseAttrs = {
4747
>
4848
Hello buddy, how are you today?
4949
</button>
50-
<Collapse v-bind="collapseAttrs" :when="isExpanded" class="v-collapse">
51-
<p>
50+
<Collapse v-bind="collapseAttrs" :when="isExpanded">
51+
<p class="CollapseContent">
5252
As an interesting side note, as a head without a body, I envy the dead. Kids don't
5353
turn rotten just from watching TV. Bender, I didn't know you liked cooking. That's so
5454
cute. That's right, baby. I ain't your loverboy Flexo, the guy you love so much. You

demo/WithCallbacks.vue

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<script setup lang="ts">
22
import { reactive, ref } from 'vue'
3+
34
import ExampleHeader from './ExampleHeader.vue'
5+
46
import fakeData from './fakeData.json'
57
68
const collapseRefs = ref<Element[]>([])
79
const indexToScroll = ref(-1)
8-
const isBusy = ref(false)
10+
11+
let isBusy = false
912
1013
const questions = reactive(
1114
fakeData.map(({ title, answer }) => ({ title, answer, isExpanded: false }))
@@ -25,19 +28,19 @@ function scrollIntoView(index: number) {
2528
2629
function onExpanded(index: number) {
2730
indexToScroll.value = index
28-
if (!isBusy.value) {
31+
if (!isBusy) {
2932
scrollIntoView(index)
3033
}
3134
}
3235
3336
function onCollapse() {
34-
isBusy.value = true
37+
isBusy = true
3538
}
3639
3740
function onCollapsed() {
38-
if (isBusy.value && indexToScroll.value !== -1) {
41+
if (isBusy && indexToScroll.value !== -1) {
3942
scrollIntoView(indexToScroll.value)
40-
isBusy.value = false
43+
isBusy = false
4144
}
4245
}
4346
</script>
@@ -71,12 +74,11 @@ function onCollapsed() {
7174
<Collapse
7275
as="section"
7376
:when="question.isExpanded"
74-
class="v-collapse"
7577
:onExpanded="() => onExpanded(index)"
7678
:onCollapse="onCollapse"
7779
:onCollapsed="onCollapsed"
7880
>
79-
<p>
81+
<p class="CollapseContent">
8082
{{ question.answer }}
8183
</p>
8284
</Collapse>

demo/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Collapse } from '../src'
1+
import Collapse from '../src/Collapse.vue'
22
import { createApp } from 'vue'
33
import App from './App.vue'
44

package.json

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-collapsed",
3-
"version": "1.1.3",
3+
"version": "1.2.0",
44
"private": false,
55
"description": "Dynamic CSS height transition from any to auto and vice versa for Vue 3. Accordion ready.",
66
"keywords": [
@@ -33,6 +33,7 @@
3333
],
3434
"scripts": {
3535
"build": "rimraf dist && vite build",
36+
"postbuild": "pnpm pack",
3637
"build:app": "vite build --mode app",
3738
"dev": "vite",
3839
"prepare": "husky install",
@@ -46,21 +47,21 @@
4647
"*.{ts,vue,md}": "prettier --write"
4748
},
4849
"devDependencies": {
49-
"@babel/types": "^7.21.4",
50-
"@rollup/plugin-terser": "^0.4.1",
51-
"@types/node": "^18.16.1",
52-
"@vitejs/plugin-vue": "^4.2.1",
53-
"cypress": "^12.11.0",
50+
"@babel/types": "^7.22.5",
51+
"@rollup/plugin-terser": "^0.4.3",
52+
"@types/node": "^18.17.0",
53+
"@vitejs/plugin-vue": "^4.2.3",
54+
"cypress": "^12.17.2",
5455
"cypress-wait-frames": "^0.9.4",
5556
"husky": "^8.0.3",
56-
"lint-staged": "^13.2.2",
57-
"playwright-webkit": "^1.33.0",
57+
"lint-staged": "^13.2.3",
58+
"playwright-webkit": "^1.36.2",
5859
"prettier": "^2.8.8",
5960
"rimraf": "^4.4.1",
6061
"typescript": "^4.9.5",
61-
"vite": "^4.3.3",
62+
"vite": "^4.4.7",
6263
"vite-plugin-dts": "^1.7.3",
63-
"vue": "^3.2.47",
64-
"vue-tsc": "^1.6.0"
64+
"vue": "^3.3.4",
65+
"vue-tsc": "^1.8.6"
6566
}
6667
}

0 commit comments

Comments
 (0)