Skip to content

Commit

Permalink
feat: extending accordion panels, better animation, better mobile sty…
Browse files Browse the repository at this point in the history
…ling
  • Loading branch information
hperrin committed Dec 14, 2021
1 parent 900906a commit 635da12
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 31 deletions.
58 changes: 48 additions & 10 deletions packages/accordion/_mixins.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@use 'sass:math';
@use '@material/animation/index' as animation;
@use '@material/elevation/index' as elevation;
@use '@material/theme/index' as theme;
@use '@material/feature-targeting/index' as feature-targeting;
Expand All @@ -7,7 +9,9 @@
$ripple-target: '.smui-accordion__header__ripple';
$panel-padding: 16px 24px !default;
$open-margin: 1rem;
$extend-width: 10px;
$transition-duration: 0.2s;
$content-transition-duration: 0.3s;
$divider-color-on-light-bg: rgba(0, 0, 0, 0.12) !default;
$divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;

Expand All @@ -34,8 +38,25 @@ $divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;
padding: 0;
margin-top: 0;
margin-bottom: 0;
transition: margin-top $transition-duration ease,
margin-bottom $transition-duration ease;
transition: animation.standard(margin-top, $transition-duration),
animation.standard(margin-bottom, $transition-duration);

&.smui-accordion__panel--extend {
// Adding width, left, and box-shadow to animate the scaling and
// elevation change as well.
transition: animation.standard(width, $transition-duration),
animation.standard(left, $transition-duration),
animation.standard(box-shadow, $transition-duration),
animation.standard(margin-top, $transition-duration),
animation.standard(margin-bottom, $transition-duration);
width: 100%;
left: 0;

&.smui-accordion__panel--open {
width: calc(100% + $extend-width);
left: math.div($extend-width, 2) * -1;
}
}

&.smui-accordion__panel--raised,
&.smui-paper--unelevated {
Expand Down Expand Up @@ -127,17 +148,26 @@ $divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;
.smui-accordion__header__title {
padding: $panel-padding;
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

&.smui-accordion__header__title--with-description {
width: 30%;
flex-basis: 30%;
max-width: 280px;
box-sizing: border-box;
padding-inline-end: 0;
}
}

.smui-accordion__header__description {
opacity: 0.48;
padding: $panel-padding;
flex-basis: 0;
flex-grow: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.smui-accordion__header__icon {
Expand All @@ -146,6 +176,7 @@ $divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;
margin: $panel-padding;
margin-top: 0;
margin-bottom: 0;
margin-inline-start: 0;
}

#{$ripple-target} {
Expand Down Expand Up @@ -174,17 +205,23 @@ $divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;
}

& > .smui-paper__content {
padding: $panel-padding;
overflow: hidden;
transition: height $transition-duration ease,
padding $transition-duration ease;
box-sizing: content-box;
transition: animation.standard(height, $content-transition-duration),
animation.standard(padding, $content-transition-duration);
box-sizing: border-box;
height: 0;
}

&:not(.smui-accordion__panel--open) > .smui-paper__content {
padding: $panel-padding;
padding-top: 0;
padding-bottom: 0;

&.smui-accordion__content--no-transition {
transition: none;
}

&.smui-accordion__content--force-open {
height: auto;
padding: $panel-padding;
}
}

&.smui-accordion__panel--open {
Expand All @@ -193,6 +230,7 @@ $divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;

& > .smui-paper__content {
height: auto;
padding: $panel-padding;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/accordion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
},
"license": "Apache-2.0",
"dependencies": {
"@material/animation": "^13.0.0",
"@material/elevation": "^13.0.0",
"@material/feature-targeting": "^13.0.0",
"@material/ripple": "^13.0.0",
Expand Down
19 changes: 14 additions & 5 deletions packages/accordion/src/Panel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
'smui-accordion__panel--open': open,
'smui-accordion__panel--disabled': disabled,
'smui-accordion__panel--raised': variant === 'raised',
['smui-accordion__panel--elevation-z' + elevation]:
elevation !== 0 && variant === 'raised',
'smui-accordion__panel--extend': extend,
['smui-accordion__panel--elevation-z' +
(extend && open ? extendedElevation : elevation)]:
(elevation !== 0 && variant === 'raised') ||
(extendedElevation !== 0 && variant === 'raised' && extend && open),
})}
{color}
variant={variant === 'raised' ? 'unelevated' : variant}
Expand Down Expand Up @@ -42,6 +45,8 @@
export let elevation = 1;
export let open = false;
export let disabled = false;
export let extend = false;
export let extendedElevation = 3;
let element: PaperComponentDev;
let accessor: SMUIAccordionPanelAccessor;
Expand All @@ -64,12 +69,14 @@
// Calculate the height of the content and apply it. This lets the CSS
// animation run properly.
if (open) {
content.style.height = 'auto';
content.classList.add('smui-accordion__content--no-transition');
content.classList.add('smui-accordion__content--force-open');
// Force a reflow to get the height.
const { height } = content.getBoundingClientRect();
content.style.height = '';
content.classList.remove('smui-accordion__content--force-open');
// Force another reflow to reset the height.
content.getBoundingClientRect();
content.classList.remove('smui-accordion__content--no-transition');
content.style.height = height + 'px';
content.addEventListener(
'transitionend',
Expand All @@ -81,7 +88,9 @@
{ once: true }
);
} else {
content.style.height = content.clientHeight + 'px';
content.style.height = content.getBoundingClientRect().height + 'px';
// Force a reflow.
content.getBoundingClientRect();
requestAnimationFrame(() => {
if (content) {
content.style.height = '';
Expand Down
57 changes: 57 additions & 0 deletions packages/site/src/routes/demo/accordion/_Extend.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<div class="accordion-container">
<Accordion>
<Panel extend>
<Header>
Panel 1
<span slot="description">Description of panel 1.</span>
</Header>
<Content>
The content for panel 1.

<ul>
<li>Some</li>
<li>List</li>
<li>Items</li>
</ul>
</Content>
</Panel>
<Panel extend>
<Header>
Panel 2
<span slot="description">Description of panel 2.</span>
</Header>
<Content>The content for panel 2.</Content>
</Panel>
<Panel extend>
<Header>
Panel 3
<span slot="description">Description of panel 3.</span>
</Header>
<Content>
The content for panel 3.

<ul>
<li>Some</li>
<li>More</li>
<li>List</li>
<li>Items</li>
<li>To</li>
<li>Show</li>
<li>Big</li>
<li>Height</li>
</ul>
</Content>
</Panel>
<Panel extend>
<Header>
Panel 4
<span slot="description">Description of panel 4.</span>
</Header>
<Content>The content for panel 4.</Content>
</Panel>
</Accordion>
</div>

<script lang="ts">
import Accordion, { Panel, Header, Content } from '@smui-extra/accordion';
</script>
59 changes: 46 additions & 13 deletions packages/site/src/routes/demo/accordion/_PaperProps.svelte
Original file line number Diff line number Diff line change
@@ -1,45 +1,69 @@
<div class="accordion-container">
<Accordion>
<Panel square variant="outlined" bind:open={panel1Open}>
<Accordion class="demo-small-titles">
<Panel
square
variant="outlined"
color="primary"
extend
bind:open={panel1Open}
>
<Header>
Panel 1
<span slot="description">Description of panel 1.</span>
<IconButton slot="icon" toggle pressed={panel1Open}>
<Icon class="material-icons" on>expand_less</Icon>
<Icon class="material-icons">expand_more</Icon>
<Icon class="material-icons" on>unfold_less</Icon>
<Icon class="material-icons">unfold_more</Icon>
</IconButton>
</Header>
<Content>The content for panel 1.</Content>
</Panel>
<Panel square variant="outlined" bind:open={panel2Open}>
<Panel
square
variant="outlined"
color="secondary"
extend
bind:open={panel2Open}
>
<Header>
Panel 2
<span slot="description">Description of panel 2.</span>
<IconButton slot="icon" toggle pressed={panel2Open}>
<Icon class="material-icons" on>expand_less</Icon>
<Icon class="material-icons">expand_more</Icon>
<Icon class="material-icons" on>unfold_less</Icon>
<Icon class="material-icons">unfold_more</Icon>
</IconButton>
</Header>
<Content>The content for panel 2.</Content>
</Panel>
<Panel square variant="outlined" bind:open={panel3Open}>
<Panel
square
variant="outlined"
color="secondary"
extend
bind:open={panel3Open}
>
<Header>
Panel 3
<span slot="description">Description of panel 3.</span>
<IconButton slot="icon" toggle pressed={panel3Open}>
<Icon class="material-icons" on>expand_less</Icon>
<Icon class="material-icons">expand_more</Icon>
<Icon class="material-icons" on>unfold_less</Icon>
<Icon class="material-icons">unfold_more</Icon>
</IconButton>
</Header>
<Content>The content for panel 3.</Content>
</Panel>
<Panel square variant="outlined" bind:open={panel4Open}>
<Panel
square
variant="outlined"
color="secondary"
extend
bind:open={panel4Open}
>
<Header>
Panel 4
<span slot="description">Description of panel 4.</span>
<IconButton slot="icon" toggle pressed={panel4Open}>
<Icon class="material-icons" on>expand_less</Icon>
<Icon class="material-icons">expand_more</Icon>
<Icon class="material-icons" on>unfold_less</Icon>
<Icon class="material-icons">unfold_more</Icon>
</IconButton>
</Header>
<Content>The content for panel 4.</Content>
Expand All @@ -56,3 +80,12 @@
let panel3Open = false;
let panel4Open = false;
</script>

<style>
*
:global(.demo-small-titles
.smui-accordion__header__title--with-description) {
flex-basis: 20% !important;
max-width: 200px !important;
}
</style>
10 changes: 7 additions & 3 deletions packages/site/src/routes/demo/accordion/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@
</Demo>

<Demo component={Description} file="accordion/_Description.svelte">
Adding descriptions
Descriptions
</Demo>

<Demo component={Icon} file="accordion/_Icon.svelte">Toggle icons</Demo>

<Demo component={Extend} file="accordion/_Extend.svelte">
Extending panels
</Demo>

<Demo component={PrimaryColor} file="accordion/_PrimaryColor.svelte">
Primary color
</Demo>
Expand All @@ -48,6 +52,7 @@
import Simple from './_Simple.svelte';
import Multiple from './_Multiple.svelte';
import Extend from './_Extend.svelte';
import Description from './_Description.svelte';
import Icon from './_Icon.svelte';
import PrimaryColor from './_PrimaryColor.svelte';
Expand All @@ -62,8 +67,7 @@
}
* :global(.smui-accordion) {
margin: 0 auto 24px;
max-width: 800px;
margin: 0 12px 24px;
}
* :global(.smui-accordion:last-child) {
Expand Down

0 comments on commit 635da12

Please sign in to comment.