Skip to content

Commit 006903f

Browse files
committed
feat: new accordion component
1 parent 4c8f582 commit 006903f

38 files changed

+1263
-105
lines changed

MIGRATING.md

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ https://github.com/material-components/material-components-web/blob/master/CHANG
2424

2525
### Components
2626

27+
- Accordion
28+
- A new component!
2729
- Autocomplete
2830
- A new component! Huge shoutout to [Lorenzo Fiore](https://github.com/fiorelorenzo/) who originally authored the component!
2931
- Badge

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ If you need help using SMUI, join the new [Discord server](https://discord.gg/aF
6060

6161
Click a component/package below to go to the documentation. (Note that this documentation is a work in progress. The demo code should be your main source of truth for how something works.)
6262

63+
- [Accordion](packages/accordion/README.md)
6364
- [Badge](packages/badge/README.md)
6465
- [Banner](packages/banner/README.md)
6566
- [Button](packages/button/README.md)

packages/accordion/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Svelte Material UI - Accordion
2+
3+
A group of panels that expand to show their content.
4+
5+
# Installation
6+
7+
```sh
8+
npm install --save-dev @smui-extra/accordion
9+
```
10+
11+
# Examples and Usage Information
12+
13+
https://sveltematerialui.com/demo/accordion

packages/accordion/_index.scss

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@use 'smui-theme';
2+
@use './style';
3+
4+
@forward './mixins' show core-styles;

packages/accordion/_mixins.scss

+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
@use '@material/elevation/index' as elevation;
2+
@use '@material/theme/index' as theme;
3+
@use '@material/feature-targeting/index' as feature-targeting;
4+
@use '@material/typography/index' as typography;
5+
@use '@material/ripple/ripple' as ripple;
6+
7+
$ripple-target: '.smui-accordion__header__ripple';
8+
$panel-padding: 16px 24px !default;
9+
$open-margin: 1rem;
10+
$transition-duration: 0.2s;
11+
$divider-color-on-light-bg: rgba(0, 0, 0, 0.12) !default;
12+
$divider-color-on-dark-bg: rgba(255, 255, 255, 0.2) !default;
13+
14+
@mixin core-styles($query: feature-targeting.all()) {
15+
$feat-color: feature-targeting.create-target($query, color);
16+
$feat-animation: feature-targeting.create-target($query, animation);
17+
$feat-structure: feature-targeting.create-target($query, structure);
18+
19+
@include ripple.common($query);
20+
21+
.smui-accordion {
22+
display: block;
23+
position: relative;
24+
z-index: 0;
25+
26+
.smui-accordion__panel {
27+
@include ripple.surface($query: $query, $ripple-target: $ripple-target);
28+
@include ripple.radius-bounded(
29+
$query: $query,
30+
$ripple-target: $ripple-target
31+
);
32+
33+
position: relative;
34+
padding: 0;
35+
margin-top: 0;
36+
margin-bottom: 0;
37+
transition: margin-top $transition-duration ease,
38+
margin-bottom $transition-duration ease;
39+
40+
&.smui-accordion__panel--raised,
41+
&.smui-paper--unelevated {
42+
// Create a separator line.
43+
border-top-width: 1px;
44+
border-top-style: solid;
45+
border-top-color: if(
46+
theme.tone(theme.$background) == 'dark',
47+
$divider-color-on-dark-bg,
48+
$divider-color-on-light-bg
49+
);
50+
}
51+
52+
// The shadow needs to go on a :before element so it doesn't cover the
53+
// previous panel.
54+
// Credit: https://blog.dudak.me/2014/css-shadows-under-adjacent-elements/
55+
&.smui-paper.smui-accordion__panel--raised {
56+
z-index: auto;
57+
will-change: auto;
58+
59+
&::before {
60+
content: '';
61+
position: absolute;
62+
top: 0;
63+
bottom: 0;
64+
left: 0;
65+
right: 0;
66+
z-index: -1;
67+
}
68+
}
69+
&.smui-accordion__panel--raised {
70+
@include panel-elevation($query: $query);
71+
72+
&.smui-paper--color-primary {
73+
@include panel-elevation(primary, $query: $query);
74+
}
75+
76+
&.smui-paper--color-secondary {
77+
@include panel-elevation(secondary, $query: $query);
78+
}
79+
}
80+
81+
&.smui-accordion__panel--raised,
82+
&.smui-paper--unelevated {
83+
// Hide the separator line.
84+
85+
&:first-child {
86+
border-top-width: 0;
87+
}
88+
89+
&:last-child {
90+
border-top-left-radius: 0;
91+
border-top-right-radius: 0;
92+
}
93+
94+
&.smui-accordion__panel--open,
95+
&.smui-accordion__panel--open + .smui-accordion__panel {
96+
border-top-width: 0;
97+
}
98+
}
99+
100+
// Hide top border on not first child outlined panels.
101+
&.smui-paper--outlined {
102+
&:nth-child(1n + 2) {
103+
border-top-width: 0;
104+
}
105+
106+
&.smui-accordion__panel--open,
107+
&.smui-accordion__panel--open + .smui-accordion__panel {
108+
border-top-width: 1px;
109+
}
110+
}
111+
112+
// Square off the corners of all but the first and last panels.
113+
&:first-child:not(:last-child) {
114+
border-bottom-left-radius: 0;
115+
border-bottom-right-radius: 0;
116+
}
117+
&:not(:first-child, :last-child) {
118+
border-radius: 0;
119+
}
120+
121+
& > .smui-accordion__header {
122+
@include typography.typography(body1);
123+
124+
display: flex;
125+
cursor: pointer;
126+
127+
.smui-accordion__header__title {
128+
padding: $panel-padding;
129+
flex-grow: 1;
130+
131+
&.smui-accordion__header__title--with-description {
132+
width: 30%;
133+
max-width: 280px;
134+
}
135+
}
136+
137+
.smui-accordion__header__description {
138+
opacity: 0.48;
139+
padding: $panel-padding;
140+
flex-grow: 1;
141+
}
142+
143+
.smui-accordion__header__icon {
144+
align-self: center;
145+
flex-shrink: 1;
146+
margin: $panel-padding;
147+
margin-top: 0;
148+
margin-bottom: 0;
149+
}
150+
151+
#{$ripple-target} {
152+
@include feature-targeting.targets($feat-structure) {
153+
position: absolute;
154+
// Ripple needs content-box as the box sizing and box-sizing: border-box
155+
// is often set as a default, so we override that here.
156+
box-sizing: content-box;
157+
width: 100%;
158+
height: 100%;
159+
overflow: hidden;
160+
z-index: 0;
161+
}
162+
}
163+
}
164+
165+
&.smui-accordion__panel--disabled {
166+
& > .smui-accordion__header {
167+
cursor: initial;
168+
}
169+
170+
& > .smui-accordion__header,
171+
& > .smui-paper__content {
172+
opacity: 0.38;
173+
}
174+
}
175+
176+
& > .smui-paper__content {
177+
padding: $panel-padding;
178+
overflow: hidden;
179+
transition: height $transition-duration ease,
180+
padding $transition-duration ease;
181+
box-sizing: content-box;
182+
height: 0;
183+
}
184+
185+
&:not(.smui-accordion__panel--open) > .smui-paper__content {
186+
padding-top: 0;
187+
padding-bottom: 0;
188+
}
189+
190+
&.smui-accordion__panel--open {
191+
margin-top: $open-margin;
192+
margin-bottom: $open-margin;
193+
194+
& > .smui-paper__content {
195+
height: auto;
196+
}
197+
}
198+
}
199+
}
200+
}
201+
202+
@mixin panel-elevation(
203+
$color: elevation.$baseline-color,
204+
$query: feature-targeting.all()
205+
) {
206+
@for $i from 0 through 24 {
207+
&.smui-accordion__panel--elevation-z#{$i}::before {
208+
@include elevation.elevation($i, $color, $query: $query);
209+
}
210+
}
211+
}

packages/accordion/_style.scss

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@use '@smui/paper/style' as paper-style;
2+
@use './mixins';
3+
4+
@include mixins.core-styles;

packages/accordion/package-lock.json

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/accordion/package.json

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "@smui-extra/accordion",
3+
"version": "6.0.0-beta.6",
4+
"description": "Svelte Material UI - Accordion",
5+
"type": "module",
6+
"module": "dist/index.js",
7+
"types": "src/index.ts",
8+
"keywords": [
9+
"svelte",
10+
"svelte3",
11+
"material-ui",
12+
"material-design",
13+
"material",
14+
"svelte-components",
15+
"sveltejs"
16+
],
17+
"scripts": {
18+
"build": "npm run build:js && npm run build:svelte && npm run build:sass",
19+
"build:js": "tsc -p . --outDir dist/ --rootDir src/",
20+
"build:svelte": "svelte-strip strip src/ dist",
21+
"build:sass": "sass --no-source-map -I node_modules -I ../smui-theme/node_modules -I ../../node_modules _style.scss bare.css",
22+
"clean": "git status --ignored -u --porcelain . | grep -v node_modules/ | grep -e '^!! ' | sed 's/^!! packages\\/[a-z-]*\\///g' | tr '\\n' ' ' | xargs rm",
23+
"prepare": "npm run build",
24+
"test": "echo \"Error: no test specified\" && exit 1"
25+
},
26+
"publishConfig": {
27+
"access": "public"
28+
},
29+
"repository": {
30+
"type": "git",
31+
"url": "git+https://github.com/hperrin/svelte-material-ui.git"
32+
},
33+
"author": "Hunter Perrin <[email protected]>",
34+
"bugs": {
35+
"url": "https://github.com/hperrin/svelte-material-ui/issues"
36+
},
37+
"license": "Apache-2.0",
38+
"dependencies": {
39+
"@material/elevation": "^13.0.0",
40+
"@material/feature-targeting": "^13.0.0",
41+
"@material/ripple": "^13.0.0",
42+
"@material/theme": "^13.0.0",
43+
"@material/typography": "^13.0.0",
44+
"@smui/common": "^6.0.0-beta.6",
45+
"@smui/paper": "^6.0.0-beta.6",
46+
"@smui/ripple": "^6.0.0-beta.6",
47+
"svelte2tsx": "^0.4.11"
48+
},
49+
"devDependencies": {
50+
"@tsconfig/svelte": "^2.0.1",
51+
"sass": "^1.44.0",
52+
"svelte-strip": "^1.0.0",
53+
"tslib": "^2.3.1",
54+
"typescript": "^4.5.2"
55+
}
56+
}

0 commit comments

Comments
 (0)