Skip to content

Commit

Permalink
1.2.5
Browse files Browse the repository at this point in the history
* improve logic to set default transition and auto duration
* add reduced motion support
* split collapseStyles computed
* add nested example
* update readme
  • Loading branch information
smastrom committed Jul 26, 2023
1 parent 3d775b0 commit 9820505
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 133 deletions.
38 changes: 27 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,17 @@ const isExpanded = ref(false)
</template>
```

## Automatic transition
## Automatic transition (default behavior)

By default, as long as **no class** is added to the `Collapse` element, this transition is automatically added to the element:
By default, if no height transition is specified the following one is automatically added to the Collapse element:

`height var(--vc-auto-duration) cubic-bezier(0.33, 1, 0.68, 1)`

`var(--vc-auto-duration)` corresponds to the optimal transition duration which is automatically calculated according to the content height.
`--vc-auto-duration` is calculated in background and corresponds to an optimal transition duration based on your content height.

<br />

This is the usage I recommend: keep Collapse clean without any class and forget about it. Instead focus on styling its content and wrapper.
This is the recommended way to use this package unless you want to customize the transition.

> :warning: If you really want to add classes to Collapse, you will have to add the height transition manually as displayed below.
## Custom Transition / Duration
## Custom transition

If you prefer to use a custom duration or easing, add a class to Collapse that transitions the `height` property:

Expand All @@ -104,7 +100,7 @@ If you prefer to use a custom duration or easing, add a class to Collapse that t

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

## Multiple transitions
### Multiple transitions

To transition other properties use the attribute `data-collapse`:

Expand Down Expand Up @@ -219,7 +215,11 @@ function scrollIntoView(index) {
</template>
```

## Make it accessible
## Accessibility

`vue-collapsed` automatically detects if users prefer reduced motion and will disable transitions accordingly while keeping the same API behavior (emitting events and post-transition styles).

You should only add `aria` attributes to the Collapse element according to your use case.

```vue
<script setup>
Expand Down Expand Up @@ -255,6 +255,22 @@ function handleCollapse() {
</template>
```

## Manually disable transitions

```vue
<template>
<Collapse :when="isExpanded" class="instant-collapse">
<p>This is a paragraph.</p>
</Collapse>
</template>
<style>
.instant-collapse {
transition: none;
}
</style>
```

## License

MIT
7 changes: 1 addition & 6 deletions demo/Accordion.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@ function handleAccordion(selectedIndex: number) {
<ExampleHeader title="Accordion" href="Accordion.vue" hint="Using reactive()" />
<div v-for="(question, index) in questions" :key="question.title" class="Section">
<button
:class="[
'Panel',
{
Active: question.isExpanded,
},
]"
:class="['Panel', { Active: question.isExpanded }]"
@click="handleAccordion(index)"
>
{{ question.title }}
Expand Down
15 changes: 12 additions & 3 deletions demo/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Accordion from './Accordion.vue'
import IndividualControl from './IndividualControl.vue'
import WithCallbacks from './WithCallbacks.vue'
import AdvancedControl from './AdvancedControl.vue'
import NestedCollapse from './NestedCollapse.vue'
</script>

<template>
Expand Down Expand Up @@ -31,9 +32,10 @@ import AdvancedControl from './AdvancedControl.vue'
<main>
<SingleCollapse />
<Accordion />
<IndividualControl />
<WithCallbacks />
<AdvancedControl />
<IndividualControl />
<NestedCollapse />
</main>

<footer>
Expand All @@ -55,6 +57,7 @@ import AdvancedControl from './AdvancedControl.vue'
--ForegroundColorLight: #929292;
--BackgroundColor: #1a1a1a;
--BackgroundAlternateColor: #242424;
--ArticleBorder: 1px solid var(--ForegroundColorLight);
}
* {
box-sizing: border-box;
Expand Down Expand Up @@ -178,12 +181,12 @@ footer {
background: var(--BackgroundAlternateColor);
width: 100%;
max-width: 600px;
border-top: 1px solid var(--ForegroundColorLight);
border-top: var(--ArticleBorder);
margin: 0;
}
.Section:last-of-type {
border-bottom: 1px solid var(--ForegroundColorLight);
border-bottom: var(--ArticleBorder);
}
.Section button {
Expand All @@ -194,6 +197,12 @@ footer {
cursor: pointer;
}
.NestedCollapse {
margin: 0 20px 20px;
border-top: var(--ArticleBorder);
border-bottom: var(--ArticleBorder);
}
.CollapseContent {
padding: 0 10px 10px;
margin: 0;
Expand Down
7 changes: 1 addition & 6 deletions demo/IndividualControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ const collapseAttrs = computed(() =>
<button
v-bind="toggleAttrs[index]"
@click="handleIndividual(index)"
:class="[
'Panel',
{
Active: question.isExpanded,
},
]"
:class="['Panel', { Active: question.isExpanded }]"
>
{{ question.title }}
</button>
Expand Down
70 changes: 70 additions & 0 deletions demo/NestedCollapse.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<script lang="ts" setup>
import { reactive } from 'vue'
import ExampleHeader from './ExampleHeader.vue'
const nested = reactive({
first: true, // Initial value
second: false,
third: false,
fourth: false,
})
const innerText = `
As an interesting side note, as a head without a body, I envy the dead. Kids don't
turn rotten just from watching TV. Bender, I didn't know you liked cooking. That's so
cute. That's right, baby. I ain't your loverboy Flexo, the guy you love so much. You
even love anyone pretending to be him! I'll tell them you went down prying the
wedding ring off his cold, dead finger.
`
</script>

<template>
<article class="Wrapper">
<ExampleHeader
title="Nested Collapse"
href="NestedCollapse.vue"
hint="Multiple collapse nested"
/>

<div class="Section">
<button @click="nested.first = !nested.first" :class="['Panel', { Active: nested.first }]">
1. Hello buddy, how are you today?
</button>

<Collapse :when="nested.first">
<p class="CollapseContent">{{ innerText }}</p>

<div class="NestedCollapse">
<button
@click="nested.second = !nested.second"
:class="['Panel', { Active: nested.second }]"
>
2. Hello buddy, how are you today?
</button>

<Collapse :when="nested.second">
<p class="CollapseContent">{{ innerText }}</p>

<div class="NestedCollapse">
<button
@click="nested.third = !nested.third"
:class="['Panel', { Active: nested.third }]"
>
3. Hello buddy, how are you today?
</button>

<Collapse :when="nested.third">
<p class="CollapseContent">
{{ innerText }}
</p>
</Collapse>
</div>
</Collapse>
</div>
</Collapse>
</div>
</article>
</template>

<!-- Check styles in App.vue -->
8 changes: 2 additions & 6 deletions demo/SingleCollapse.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts" setup>
import { computed, ref } from 'vue'
import ExampleHeader from './ExampleHeader.vue'
const isExpanded = ref(false)
Expand Down Expand Up @@ -38,12 +39,7 @@ const collapseAttrs = {
<button
v-bind="toggleAttrs"
@click="handleCollapse"
:class="[
'Panel',
{
Active: isExpanded,
},
]"
:class="['Panel', { Active: isExpanded }]"
>
Hello buddy, how are you today?
</button>
Expand Down
29 changes: 12 additions & 17 deletions demo/WithCallbacks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import ExampleHeader from './ExampleHeader.vue'
import fakeData from './fakeData.json'
const collapseRefs = ref<Element[]>([])
const indexToScroll = ref(-1)
let isBusy = false
let indexToScroll = -1
let isCollapsing = false
const questions = reactive(
fakeData.map(({ title, answer }) => ({ title, answer, isExpanded: false }))
Expand All @@ -27,20 +27,20 @@ function scrollIntoView(index: number) {
}
function onExpanded(index: number) {
indexToScroll.value = index
if (!isBusy) {
indexToScroll = index
if (!isCollapsing) {
scrollIntoView(index)
}
}
function onCollapse() {
isBusy = true
isCollapsing = true
}
function onCollapsed() {
if (isBusy && indexToScroll.value !== -1) {
scrollIntoView(indexToScroll.value)
isBusy = false
if (isCollapsing && indexToScroll !== -1) {
scrollIntoView(indexToScroll)
isCollapsing = false
}
}
</script>
Expand All @@ -61,22 +61,17 @@ function onCollapsed() {
ref="collapseRefs"
>
<button
:class="[
'Panel',
{
Active: question.isExpanded,
},
]"
:class="['Panel', { Active: question.isExpanded }]"
@click="handleAccordion(index)"
>
{{ question.title }}
</button>
<Collapse
as="section"
:when="question.isExpanded"
:onExpanded="() => onExpanded(index)"
:onCollapse="onCollapse"
:onCollapsed="onCollapsed"
@expanded="() => onExpanded(index)"
@collapse="onCollapse"
@collapsed="onCollapsed"
>
<p class="CollapseContent">
{{ question.answer }}
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-collapsed",
"version": "1.2.0",
"version": "1.2.5",
"private": false,
"description": "Dynamic CSS height transition from any to auto and vice versa for Vue 3. Accordion ready.",
"keywords": [
Expand Down Expand Up @@ -49,7 +49,7 @@
"devDependencies": {
"@babel/types": "^7.22.5",
"@rollup/plugin-terser": "^0.4.3",
"@types/node": "^18.17.0",
"@types/node": "^18.17.1",
"@vitejs/plugin-vue": "^4.2.3",
"cypress": "^12.17.2",
"cypress-wait-frames": "^0.9.4",
Expand All @@ -62,6 +62,6 @@
"vite": "^4.4.7",
"vite-plugin-dts": "^1.7.3",
"vue": "^3.3.4",
"vue-tsc": "^1.8.6"
"vue-tsc": "^1.8.8"
}
}
Loading

0 comments on commit 9820505

Please sign in to comment.