Skip to content

Commit d7c8c79

Browse files
authored
Merge pull request #184 from eccenca/feature/improveAccordionWhitespace-CMEM-5947
Improve accordion whitespace (CMEM-5947)
2 parents 7964ffe + 63c94b5 commit d7c8c79

6 files changed

Lines changed: 184 additions & 51 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
1212
- monitor application wide dropzones for dragged elements via data attributes attached to body element containing the data transfer type of drag over events.
1313
- `<ReactFlow />`
1414
- `dropzoneFor` property can be used to mark react flow canvas as matching area to drop dragged elements.
15+
- `<Accordion />`, `<AccordionItem />`
16+
- `whitespaceSize` property to define how much whitespace is used on top and bottom inside the header and content of an accordion item.
17+
- `separationSize` property defines how much space is used for the separation between an accordion item and the next one.
1518

1619
### Fixed
1720

@@ -22,6 +25,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
2225

2326
- basic styles for Uppy widget were improved and moved to its own component folder
2427

28+
### Deprecated
29+
30+
- `<Accordion />`
31+
- `size` property in favour of `whitespaceSize`
32+
- `<AccordionItem />`
33+
- `condensed` property in favour of `whitespaceSize="none"`
34+
2535
## [23.7.0] - 2024-06-26
2636

2737
### Added

src/components/Accordion/Accordion.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,24 @@ import { Accordion as CarbonAccordion, AccordionProps as CarbonAccordionProps }
33

44
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
55

6+
import { AccordionItemProps } from "./AccordionItem";
7+
68
export interface AccordionProps extends Omit<CarbonAccordionProps, "className" | "size"> {
79
/**
810
* Additional CSS classes.
911
*/
1012
className?: string;
13+
/**
14+
* Defines how much whitespace is used on top and bottom inside the header and content of an accordion item.
15+
*/
16+
whitespaceSize?: AccordionItemProps["whitespaceSize"];
17+
/**
18+
* Defines how much space is used for the separation between an accordion item and the next one.
19+
*/
20+
separationSize?: AccordionItemProps["separationSize"];
1121
/**
1222
* How much space is used for the header of the each of the accordion items.
23+
* @deprecated Use ẁhitespaceSize` on `Accordion` or `AccordionItem` instead.
1324
*/
1425
size?: "small" | "medium" | "large";
1526
}
@@ -24,12 +35,28 @@ export const Accordion = ({
2435
children,
2536
className = "",
2637
align = "start",
38+
whitespaceSize = "medium",
39+
separationSize = "none",
2740
size = "medium",
2841
...otherProps
2942
}: AccordionProps) => {
43+
const headerWhitespaceSize = typeof whitespaceSize === "string" ? whitespaceSize : whitespaceSize.header;
44+
const contentWhitespaceSize = typeof whitespaceSize === "string" ? whitespaceSize : whitespaceSize.content;
3045
return (
3146
<CarbonAccordion
32-
className={`${eccgui}-accordion__container ` + className}
47+
className={
48+
`${eccgui}-accordion__container` +
49+
(headerWhitespaceSize !== "medium"
50+
? ` ${eccgui}-accordion__container--global-headerspace-${headerWhitespaceSize}`
51+
: "") +
52+
(contentWhitespaceSize !== "medium"
53+
? ` ${eccgui}-accordion__container--global-contentspace-${contentWhitespaceSize}`
54+
: "") +
55+
(separationSize !== "none"
56+
? ` ${eccgui}-accordion__container--global-separationspace-${separationSize}`
57+
: "") +
58+
(className ? ` ${className}` : "")
59+
}
3360
align={align}
3461
size={carbonAccordionSizeMapping[size]}
3562
{...otherProps}

src/components/Accordion/AccordionItem.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66

77
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
88

9+
type sizeOptions = "none" | "small" | "medium" | "large";
10+
911
export interface AccordionItemProps
1012
extends Omit<CarbonAccordionItemProps, "title" | "iconDescription" | "renderExpando"> {
1113
/**
@@ -20,8 +22,18 @@ export interface AccordionItemProps
2022
* use full available width for content
2123
*/
2224
fullWidth?: boolean;
25+
/**
26+
* Defines how much whitespace is used on top and bottom inside the header and content of an accordion item.
27+
* Seeting on `AccordionItem` overwrites the global setting on `Accordion`.
28+
*/
29+
whitespaceSize?: sizeOptions | { header: sizeOptions; content: sizeOptions };
30+
/**
31+
* Defines how much space is used for the separation between the accordion item and the next one.
32+
*/
33+
separationSize?: sizeOptions;
2334
/**
2435
* minimize white space and paddings
36+
* @deprecated Use `whitespaceSize="none"` on `Accordion` or `AccordionItem` instead.
2537
*/
2638
condensed?: boolean;
2739
/**
@@ -40,17 +52,28 @@ export const AccordionItem = ({
4052
className = "",
4153
fullWidth = false,
4254
elevated = false,
55+
whitespaceSize = "medium",
56+
separationSize = "none",
4357
condensed = false,
4458
noBorder = false,
4559
...otherProps
4660
}: AccordionItemProps) => {
61+
const headerWhitespaceSize = typeof whitespaceSize === "string" ? whitespaceSize : whitespaceSize.header;
62+
const contentWhitespaceSize = typeof whitespaceSize === "string" ? whitespaceSize : whitespaceSize.content;
4763
return (
4864
<CarbonAccordionItem
4965
className={
5066
`${eccgui}-accordion__item` +
5167
(className ? " " + className : "") +
5268
(fullWidth ? ` ${eccgui}-accordion__item--fullwidth` : "") +
5369
(elevated ? ` ${eccgui}-accordion__item--elevated` : "") +
70+
(headerWhitespaceSize !== "medium"
71+
? ` ${eccgui}-accordion__item--headerspace-${headerWhitespaceSize}`
72+
: "") +
73+
(contentWhitespaceSize !== "medium"
74+
? ` ${eccgui}-accordion__item--contentspace-${contentWhitespaceSize}`
75+
: "") +
76+
(separationSize !== "none" ? ` ${eccgui}-accordion__item--separationspace-${separationSize}` : "") +
5477
(condensed ? ` ${eccgui}-accordion__item--condensed` : "") +
5578
(noBorder ? ` ${eccgui}-accordion__item--noborder` : "")
5679
}

src/components/Accordion/Stories/Accordion.stories.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { ComponentMeta, ComponentStory } from "@storybook/react";
2+
import { Meta, StoryFn } from "@storybook/react";
33

44
import { Accordion, AccordionItem } from "../../../../index";
55
import { Default as AccordionStoryItem } from "../Stories/AccordionItem.stories";
@@ -13,10 +13,18 @@ export default {
1313
control: "none",
1414
description: "Elements to include into the Accordion component",
1515
},
16+
whitespaceSize: {
17+
control: "select",
18+
options: ["none", "small", "medium", "large"],
19+
},
20+
separationSize: {
21+
control: "select",
22+
options: ["none", "small", "medium", "large"],
23+
},
1624
},
17-
} as ComponentMeta<typeof Accordion>;
25+
} as Meta<typeof Accordion>;
1826

19-
const TemplateIcons: ComponentStory<typeof Accordion> = (args) => <Accordion {...args} />;
27+
const TemplateIcons: StoryFn<typeof Accordion> = (args) => <Accordion {...args} />;
2028
export const Default = TemplateIcons.bind({});
2129
Default.args = {
2230
children: [

src/components/Accordion/Stories/AccordionItem.stories.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22
import { LoremIpsum } from "react-lorem-ipsum";
3-
import { ComponentMeta, ComponentStory } from "@storybook/react";
3+
import { Meta, StoryFn } from "@storybook/react";
44

55
import { Accordion, AccordionItem, HtmlContentBlock } from "../../../../index";
66

@@ -12,10 +12,18 @@ export default {
1212
control: "none",
1313
description: "content of accordion item",
1414
},
15+
whitespaceSize: {
16+
control: "select",
17+
options: ["none", "small", "medium", "large"],
18+
},
19+
separationSize: {
20+
control: "select",
21+
options: ["none", "small", "medium", "large"],
22+
},
1523
},
16-
} as ComponentMeta<typeof AccordionItem>;
24+
} as Meta<typeof AccordionItem>;
1725

18-
const Template: ComponentStory<typeof AccordionItem> = (args) => (
26+
const Template: StoryFn<typeof AccordionItem> = (args) => (
1927
<Accordion>
2028
<AccordionItem {...args} />
2129
</Accordion>

src/components/Accordion/accordion.scss

Lines changed: 101 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,85 @@
11
// lib import
2+
@use "sass:color";
23
@use "~@carbon/styles/scss/components/accordion/accordion";
34
@include accordion.accordion;
45

56
// own vars
67
$eccgui-color-accordion-background-elevated: rgba($eccgui-color-accent, 0.1) !default;
78
$eccgui-color-accordion-toggler-hover: $menu-item-color-hover !default;
8-
$eccgui-color-accordion-toggler-elevated-hover: mix(
9+
$eccgui-color-accordion-toggler-elevated-hover: color.mix(
910
$eccgui-color-accordion-background-elevated,
1011
$eccgui-color-accordion-toggler-hover,
1112
50%
1213
) !default;
14+
$eccgui-size-accordion-header-baseheight: mini-units(5) !default;
15+
$eccgui-size-accordion-content-basespace: $eccgui-size-block-whitespace * 0.5 !default;
16+
$eccgui-size-accordion-separation: $eccgui-size-block-whitespace * 0.5 !default;
1317

1418
// changes
1519

20+
.#{$prefix}--accordion {
21+
--#{$eccgui}-accordion-header-height: #{$eccgui-size-accordion-header-baseheight};
22+
--#{$eccgui}-accordion-content-whitespace: #{$eccgui-size-accordion-content-basespace};
23+
--#{$eccgui}-accordion-separation: 0;
24+
}
25+
.#{$eccgui}-accordion__item--condensed,
26+
.#{$eccgui}-accordion__container--global-headerspace-none,
27+
.#{$eccgui}-accordion__item--headerspace-none {
28+
--#{$eccgui}-accordion-header-height: 0;
29+
}
30+
.#{$eccgui}-accordion__item--condensed,
31+
.#{$eccgui}-accordion__container--global-contentspace-none,
32+
.#{$eccgui}-accordion__item--contentspace-none {
33+
--#{$eccgui}-accordion-content-whitespace: #{$eccgui-size-block-whitespace * 0.25};
34+
}
35+
.#{$eccgui}-accordion__container--global-headerspace-small,
36+
.#{$eccgui}-accordion__item--headerspace-small {
37+
--#{$eccgui}-accordion-header-height: calc(
38+
#{$eccgui-size-accordion-header-baseheight} - #{$eccgui-size-block-whitespace * 0.5}
39+
);
40+
}
41+
.#{$eccgui}-accordion__container--global-contentspace-small,
42+
.#{$eccgui}-accordion__item--contentspace-small {
43+
--#{$eccgui}-accordion-content-whitespace: #{$eccgui-size-accordion-content-basespace * 0.5};
44+
}
45+
.#{$eccgui}-accordion__container--global-headerspace-large,
46+
.#{$eccgui}-accordion__item--headerspace-large {
47+
--#{$eccgui}-accordion-header-height: calc(
48+
#{$eccgui-size-accordion-header-baseheight} + #{$eccgui-size-block-whitespace * 0.5}
49+
);
50+
}
51+
.#{$eccgui}-accordion__container--global-contentspace-large,
52+
.#{$eccgui}-accordion__item--contentspace-large {
53+
--#{$eccgui}-accordion-content-whitespace: #{$eccgui-size-accordion-content-basespace * 1.5};
54+
}
55+
56+
.#{$eccgui}-accordion__container--global-separationspace-small,
57+
.#{$eccgui}-accordion__item--separationspace-small {
58+
--#{$eccgui}-accordion-separation: #{$eccgui-size-accordion-separation * 0.5};
59+
}
60+
.#{$eccgui}-accordion__container--global-separationspace-medium,
61+
.#{$eccgui}-accordion__item--separationspace-medium {
62+
--#{$eccgui}-accordion-separation: #{$eccgui-size-accordion-separation};
63+
}
64+
.#{$eccgui}-accordion__container--global-separationspace-large,
65+
.#{$eccgui}-accordion__item--separationspace-large {
66+
--#{$eccgui}-accordion-separation: #{$eccgui-size-accordion-separation * 1.5};
67+
}
68+
69+
.#{$eccgui}-accordion__item {
70+
&:not(:last-child) {
71+
margin-bottom: var(--#{$eccgui}-accordion-separation);
72+
}
73+
74+
[class*="#{$eccgui}-accordion__container--global-separationspace-"] &:not(.#{$eccgui}-accordion__item--noborder),
75+
&[class*="#{$eccgui}-accordion__item--separationspace-"]:not(.#{$eccgui}-accordion__item--noborder) {
76+
border-bottom: 1px solid var(--#{$prefix}-border-subtle);
77+
}
78+
}
79+
1680
.#{$prefix}--accordion__heading {
1781
align-items: center;
18-
min-height: mini-units(5);
82+
min-height: var(--#{$eccgui}-accordion-header-height, mini-units(5));
1983
color: inherit;
2084

2185
.#{$prefix}--accordion__arrow {
@@ -25,6 +89,23 @@ $eccgui-color-accordion-toggler-elevated-hover: mix(
2589
margin: 0 0 0 $eccgui-size-block-whitespace * 0.5;
2690
}
2791
}
92+
93+
.#{$eccgui}-accordion__item--condensed &,
94+
.#{$eccgui}-accordion__container--global-contentspace-none &,
95+
.#{$eccgui}-accordion__item--contentspace-none & {
96+
.#{$prefix}--accordion__arrow {
97+
margin: 0;
98+
}
99+
100+
.#{$prefix}--accordion__title {
101+
margin: 0 0 0 $eccgui-size-block-whitespace * 0.25;
102+
}
103+
}
104+
105+
&:hover::before,
106+
&:focus::before {
107+
background-color: $eccgui-color-accordion-toggler-hover;
108+
}
28109
}
29110

30111
.#{$prefix}--accordion__title {
@@ -43,15 +124,15 @@ $eccgui-color-accordion-toggler-elevated-hover: mix(
43124
position: fixed;
44125
left: -5000em;
45126
display: block;
46-
padding: $eccgui-size-block-whitespace * 0.5;
127+
padding: 0 $eccgui-size-block-whitespace * 0.5;
47128
margin: 0 calc(1rem + #{$eccgui-size-block-whitespace * 0.5}) 0 $eccgui-size-block-whitespace * 0.5;
48129
opacity: 0;
49130

50131
.#{$prefix}--accordion__item--active & {
51132
position: static;
52133
left: auto;
53-
padding: $eccgui-size-block-whitespace * 0.5 $eccgui-size-block-whitespace * 0.5 $eccgui-size-block-whitespace
54-
$eccgui-size-block-whitespace * 0.5;
134+
padding: calc(0.75 * var(--#{$eccgui}-accordion-content-whitespace)) $eccgui-size-block-whitespace * 0.5
135+
calc(1.25 * var(--#{$eccgui}-accordion-content-whitespace)) $eccgui-size-block-whitespace * 0.5;
55136
opacity: 1;
56137
}
57138

@@ -63,20 +144,28 @@ $eccgui-color-accordion-toggler-elevated-hover: mix(
63144
margin: 0;
64145
}
65146

147+
.#{$eccgui}-accordion__item--condensed &,
148+
.#{$eccgui}-accordion__container--global-contentspace-none &,
149+
.#{$eccgui}-accordion__item--contentspace-none & {
150+
padding-right: 0;
151+
padding-left: 0;
152+
}
153+
154+
.#{$eccgui}-accordion__item--condensed:not(.#{$eccgui}-accordion__item--fullwidth) &,
155+
.#{$prefix}--accordion--start.#{$eccgui}-accordion__container--global-contentspace-none &,
156+
.#{$prefix}--accordion--start
157+
.#{$eccgui}-accordion__item--contentspace-none:not(.#{$eccgui}-accordion__item--fullwidth)
158+
& {
159+
margin-left: calc(1rem + #{$eccgui-size-block-whitespace * 0.25});
160+
}
161+
66162
*,
67163
*::before,
68164
*::after {
69165
box-sizing: inherit;
70166
}
71167
}
72168

73-
.#{$prefix}--accordion__heading {
74-
&:hover::before,
75-
&:focus::before {
76-
background-color: $eccgui-color-accordion-toggler-hover;
77-
}
78-
}
79-
80169
.#{$eccgui}-accordion__item--elevated {
81170
background-color: $eccgui-color-accordion-background-elevated;
82171

@@ -95,35 +184,3 @@ $eccgui-color-accordion-toggler-elevated-hover: mix(
95184
border-bottom: none;
96185
}
97186
}
98-
99-
.#{$eccgui}-accordion__item--condensed {
100-
.#{$prefix}--accordion__heading {
101-
min-height: 0;
102-
padding: 0;
103-
line-height: 1em;
104-
105-
.#{$prefix}--accordion__arrow {
106-
margin: 0;
107-
108-
.#{$prefix}--accordion--start & {
109-
margin: 0;
110-
}
111-
}
112-
113-
.#{$prefix}--accordion__title {
114-
margin: 0 0 0 $eccgui-size-block-whitespace * 0.25;
115-
116-
.#{$prefix}--accordion--start & {
117-
margin: 0 0 0 $eccgui-size-block-whitespace * 0.25;
118-
}
119-
}
120-
}
121-
122-
.#{$prefix}--accordion__content {
123-
padding: $eccgui-size-block-whitespace * 0.25 0;
124-
125-
.#{$prefix}--accordion__item--active & {
126-
padding: $eccgui-size-block-whitespace * 0.25 0;
127-
}
128-
}
129-
}

0 commit comments

Comments
 (0)