Skip to content

Commit a22d21f

Browse files
tassoevanggazzo
authored andcommitted
feat: Tile component (#85)
1 parent 1af0fee commit a22d21f

File tree

182 files changed

+2745
-1098
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+2745
-1098
lines changed

packages/fuselage/babel.config.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ module.exports = {
55
],
66
plugins: [
77
'@babel/plugin-proposal-class-properties',
8-
'babel-plugin-styled-components',
8+
[
9+
'babel-plugin-styled-components',
10+
{
11+
displayName: false,
12+
fileName: false,
13+
minify: false,
14+
transpileTemplateLiterals: false,
15+
},
16+
],
917
],
1018
};
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
1-
import { useClassName, useToggle, useUniqueId } from '@rocket.chat/fuselage-hooks';
1+
import { useToggle, useUniqueId } from '@rocket.chat/fuselage-hooks';
22
import PropTypes from 'prop-types';
33
import React from 'react';
44

5-
import { useTheme } from '../../hooks/useTheme';
5+
import { createStyledComponent } from '../../styles';
66
import { Icon } from '../Icon';
77
import { ToggleSwitch } from '../ToggleSwitch';
8-
import { StyledAccordionItem, Bar, Title, Panel } from './styles';
8+
import styles from './styles';
9+
10+
const ItemContainer = createStyledComponent(styles, 'rcx-accordion-item', 'section');
11+
const ItemBar = createStyledComponent(styles, 'rcx-accordion-item__bar');
12+
const ItemTitle = createStyledComponent(styles, 'rcx-accordion-item__title', 'h1');
13+
const ItemPanel = createStyledComponent(styles, 'rcx-accordion-item__panel');
914

1015
export const Item = React.forwardRef(function Item({
1116
children,
1217
className,
1318
defaultExpanded,
1419
disabled,
15-
expanded,
20+
expanded: propExpanded,
1621
tabIndex = 0,
1722
title,
1823
noncollapsible = !title,
1924
onToggle,
2025
onToggleEnabled,
2126
...props
2227
}, ref) {
23-
const classNames = {
24-
container: useClassName('rcx-accordion-item', {}, className),
25-
bar: useClassName('rcx-accordion-item__bar'),
26-
title: useClassName('rcx-accordion-item__title'),
27-
toggleBtn: useClassName('rcx-accordion-item__toggle-button'),
28+
const [stateExpanded, toggleStateExpanded] = useToggle(defaultExpanded);
29+
const expanded = propExpanded || stateExpanded;
30+
const toggleExpanded = () => {
31+
if (onToggle) {
32+
onToggle.call(event.currentTarget, event);
33+
return;
34+
}
35+
36+
toggleStateExpanded();
2837
};
29-
const theme = useTheme();
3038

31-
const [internalExpanded, toggleExpanded] = useToggle(defaultExpanded);
39+
const panelExpanded = noncollapsible || expanded;
3240

3341
const titleId = useUniqueId();
3442
const panelId = useUniqueId();
@@ -39,12 +47,6 @@ export const Item = React.forwardRef(function Item({
3947
}
4048

4149
event.currentTarget.blur();
42-
43-
if (onToggle) {
44-
onToggle.call(event.currentTarget, event);
45-
return;
46-
}
47-
4850
toggleExpanded();
4951
};
5052

@@ -60,11 +62,6 @@ export const Item = React.forwardRef(function Item({
6062
return;
6163
}
6264

63-
if (onToggle) {
64-
onToggle.call(event.currentTarget, event);
65-
return;
66-
}
67-
6865
toggleExpanded();
6966
}
7067
};
@@ -75,7 +72,7 @@ export const Item = React.forwardRef(function Item({
7572

7673
const collapsibleProps = {
7774
'aria-controls': panelId,
78-
'aria-expanded': expanded || internalExpanded ? 'true' : 'false',
75+
'aria-expanded': expanded ? 'true' : 'false',
7976
tabIndex: !disabled ? tabIndex : undefined,
8077
onClick: handleClick,
8178
onKeyDown: handleKeyDown,
@@ -87,33 +84,21 @@ export const Item = React.forwardRef(function Item({
8784
'aria-labelledby': titleId,
8885
};
8986

90-
return <StyledAccordionItem className={classNames.container} theme={theme} {...props}>
91-
{title && <Bar
92-
className={classNames.bar}
93-
disabled={disabled}
94-
expanded={expanded || internalExpanded}
95-
noncollapsible={noncollapsible}
96-
ref={ref}
97-
theme={theme}
98-
{...(noncollapsible ? nonCollapsibleProps : collapsibleProps)}
99-
>
100-
<Title className={classNames.bar} id={titleId} theme={theme}>{title}</Title>
87+
const barProps = noncollapsible ? nonCollapsibleProps : collapsibleProps;
88+
89+
return <ItemContainer className={className} {...props}>
90+
{title && <ItemBar modifiers={{ disabled, expanded }} ref={ref} {...barProps}>
91+
<ItemTitle id={titleId}>{title}</ItemTitle>
10192
{!noncollapsible && <>
10293
{(disabled || onToggleEnabled)
10394
&& <ToggleSwitch checked={!disabled} onClick={handleToggleClick} onChange={onToggleEnabled} />}
10495
<Icon name={'arrow-down'} />
10596
</>}
106-
</Bar>}
107-
<Panel
108-
className={classNames.panel}
109-
expanded={noncollapsible || expanded || internalExpanded}
110-
id={panelId}
111-
role='region'
112-
theme={theme}
113-
>
97+
</ItemBar>}
98+
<ItemPanel id={panelId} modifiers={{ expanded: panelExpanded }} role='region'>
11499
{children}
115-
</Panel>
116-
</StyledAccordionItem>;
100+
</ItemPanel>
101+
</ItemContainer>;
117102
});
118103

119104
Item.defaultProps = {
@@ -127,8 +112,12 @@ Item.propTypes = {
127112
defaultExpanded: PropTypes.bool,
128113
disabled: PropTypes.bool,
129114
expanded: PropTypes.bool,
115+
/** Is this component visible? */
116+
invisible: PropTypes.bool,
130117
tabIndex: PropTypes.number,
131118
title: PropTypes.string,
132119
onToggle: PropTypes.func,
133120
onToggleEnabled: PropTypes.func,
134121
};
122+
123+
Item.styled = ItemContainer;
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
import { useClassName } from '@rocket.chat/fuselage-hooks';
21
import PropTypes from 'prop-types';
32
import React from 'react';
43

5-
import { useTheme } from '../../hooks/useTheme';
4+
import { createStyledComponent } from '../../styles';
65
import { Item } from './Item';
7-
import { StyledAccordion } from './styles';
6+
import styles from './styles';
87

9-
export const Accordion = React.forwardRef(function Accordion({
10-
className,
11-
...props
12-
}, ref) {
13-
const compoundClassName = useClassName('rcx-accordion', {}, className);
14-
const theme = useTheme();
15-
return <StyledAccordion className={compoundClassName} ref={ref} theme={theme} {...props} />;
8+
const Container = createStyledComponent(styles, 'rcx-accordion');
9+
10+
export const Accordion = React.forwardRef(function Accordion(props, ref) {
11+
return <Container ref={ref} {...props} />;
1612
});
1713

1814
Accordion.displayName = 'Accordion';
@@ -22,3 +18,5 @@ Accordion.propTypes = {
2218
};
2319

2420
Accordion.Item = Item;
21+
22+
Accordion.styled = Container;
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import colors from '@rocket.chat/fuselage-tokens/colors';
22
import styled, { css } from 'styled-components';
33

4-
import box from '../../styles/box';
4+
import box from '../../styles/utilities/box';
55
import { clickable } from '../../styles/utilities/interactivity';
66
import { truncate, subtitleBold, subtitle } from '../../styles/utilities/typography';
7-
import { StyledIcon } from '../Icon/styles';
8-
import { toRem } from '../../styles/helpers';
7+
import { toRem } from '../../styles/utilities/common';
8+
import { Icon } from '../Icon';
9+
import { ToggleSwitch } from '../ToggleSwitch';
910

10-
export const StyledAccordion = styled.div`
11+
const Container = styled.div`
1112
${ box }
1213
1314
display: flex;
@@ -17,50 +18,37 @@ export const StyledAccordion = styled.div`
1718
border-bottom-color: ${ colors.dark300 };
1819
`;
1920

20-
export const StyledAccordionItem = styled.div`
21+
const ItemContainer = styled.div`
2122
${ box }
2223
2324
display: flex;
2425
flex-flow: column nowrap;
2526
`;
2627

27-
export const Bar = styled.div`
28+
const ItemBar = styled.div`
2829
${ box }
2930
3031
display: flex;
31-
flex-flow: row nowrap;
32-
33-
${ ({ theme }) => css`
34-
min-height: calc(2 * ${ theme.spaces.x32 } + ${ theme.sizes.x24 });
35-
` }
3632
37-
border-width: ${ ({ theme }) => theme.borders.width.x2 };
38-
border-color: ${ colors.dark300 } transparent transparent;
39-
${ ({ theme }) => css`
40-
padding:
41-
calc(${ theme.spaces.x32 } - ${ theme.borders.width.x2 })
42-
calc(${ theme.spaces.x8 } - ${ theme.borders.width.x2 });
43-
` }
33+
min-height: calc(2 * ${ ({ theme }) => theme.spaces.x32 } + ${ ({ theme }) => theme.sizes.x24 });
34+
padding:
35+
calc(${ ({ theme }) => theme.spaces.x32 } - ${ ({ theme }) => theme.borders.width.x2 })
36+
calc(${ ({ theme }) => theme.spaces.x8 } - ${ ({ theme }) => theme.borders.width.x2 });
37+
padding-block: calc(${ ({ theme }) => theme.spaces.x32 } - ${ ({ theme }) => theme.borders.width.x2 });
38+
padding-inline: calc(${ ({ theme }) => theme.spaces.x8 } - ${ ({ theme }) => theme.borders.width.x2 });
4439
4540
text-align: left;
41+
text-align: start;
4642
47-
${ ({ disabled, noncollapsible }) => !disabled && !noncollapsible && css`
48-
${ clickable }
49-
` }
50-
51-
& > .rcx-toggle-switch {
52-
margin: 0 ${ ({ theme }) => theme.sizes.x24 };
53-
}
43+
color: ${ ({ theme }) => theme.textColors.default };
5444
55-
& > ${ StyledIcon } {
56-
font-size: ${ ({ theme }) => theme.sizes.x24 };
45+
border-width: ${ ({ theme }) => theme.borders.width.x2 };
46+
border-color: ${ colors.dark300 } transparent transparent;
47+
flex-flow: row nowrap;
5748
58-
${ ({ expanded }) => expanded && css`
59-
transform: rotate(-180deg);
60-
` }
61-
}
49+
&[tabindex] {
50+
${ clickable }
6251
63-
${ ({ disabled, noncollapsible }) => !disabled && !noncollapsible && css`
6452
&.hover,
6553
&:hover {
6654
background-color: ${ colors.dark100 };
@@ -71,42 +59,70 @@ export const Bar = styled.div`
7159
border-color: ${ colors.blue500 };
7260
box-shadow: 0 0 0 ${ toRem(6) } ${ colors.blue100 };
7361
}
62+
}
63+
64+
& > ${ ToggleSwitch.styled } {
65+
margin: 0 ${ ({ theme }) => theme.sizes.x24 };
66+
margin-block: 0;
67+
margin-inline: ${ ({ theme }) => theme.sizes.x24 };
68+
}
69+
70+
& > ${ Icon.styled } {
71+
font-size: ${ ({ theme }) => theme.sizes.x24 };
72+
}
73+
74+
${ ({ modifiers }) => modifiers.expanded && css`
75+
& > ${ Icon.styled } {
76+
transform: rotate(-180deg);
77+
}
7478
` }
7579
76-
${ ({ disabled, theme }) => disabled && css`
80+
${ ({ modifiers, theme }) => modifiers.disabled && css`
81+
cursor: not-allowed;
82+
7783
color: ${ theme.textColors.disabled };
7884
background-color: ${ colors.dark100 };
7985
` }
8086
`;
8187

82-
export const Title = styled.h2`
88+
const ItemTitle = styled.h2`
8389
${ box }
8490
8591
flex: 1 1 0;
8692
87-
${ ({ disabled, theme }) => disabled && css`
88-
color: ${ theme.textColors.disabled };
89-
` }
90-
9193
${ ({ theme }) => subtitle(theme) }
9294
${ ({ theme }) => subtitleBold(theme) }
9395
${ truncate }
9496
`;
9597

96-
export const Panel = styled.div`
98+
const ItemPanel = styled.div`
9799
${ box }
98100
101+
visibility: hidden;
102+
99103
overflow: hidden;
100104
101105
height: 0;
102-
${ ({ theme }) => css`
103-
padding: 0 ${ theme.spaces.x8 };
104-
visibility: hidden;
105-
` }
106+
padding: 0 ${ ({ theme }) => theme.spaces.x8 };
107+
padding-block: 0;
108+
padding-inline: ${ ({ theme }) => theme.spaces.x8 };
106109
107-
${ ({ expanded, theme }) => expanded && css`
108-
height: auto;
109-
padding: ${ theme.spaces.x32 } ${ theme.spaces.x8 };
110+
${ ({ modifiers, theme }) => modifiers.expanded && css`
110111
visibility: visible;
112+
113+
height: auto;
114+
padding:
115+
${ theme.spaces.x32 }
116+
${ theme.spaces.x8 };
117+
padding-block: ${ theme.spaces.x32 };
118+
padding-inline: ${ theme.spaces.x8 };
111119
` }
112120
`;
121+
122+
export default {
123+
'rcx-accordion': Container,
124+
'rcx-accordion-item': ItemContainer,
125+
'rcx-accordion-item__bar': ItemBar,
126+
'rcx-accordion-item__title': ItemTitle,
127+
'rcx-accordion-item__panel': ItemPanel,
128+
};

0 commit comments

Comments
 (0)