Skip to content

Commit ff81ed3

Browse files
authored
feat: adds styled icon base component (#1791)
1 parent 18b6650 commit ff81ed3

File tree

7 files changed

+54
-33
lines changed

7 files changed

+54
-33
lines changed

packages/accordions/src/elements/accordion/components/Header.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ const HeaderComponent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement
6464
>
6565
{children}
6666
<StyledRotateIcon
67-
isCompact={isCompact}
68-
isHovered={isHovered}
69-
isRotated={isExpanded}
70-
isCollapsible={isCollapsible}
67+
$isCompact={isCompact}
68+
$isHovered={isHovered}
69+
$isRotated={isExpanded}
70+
$isCollapsible={isCollapsible}
7171
onMouseOver={composeEventHandlers(onMouseOver, () => setIsHovered(true))}
7272
onMouseOut={composeEventHandlers(onMouseOut, () => setIsHovered(false))}
7373
>

packages/accordions/src/elements/timeline/components/Content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const ContentComponent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElemen
1717
return (
1818
<>
1919
<StyledSeparator>
20-
<StyledItemIcon surfaceColor={surfaceColor}>{icon || <CircleIcon />}</StyledItemIcon>
20+
<StyledItemIcon $surfaceColor={surfaceColor}>{icon || <CircleIcon />}</StyledItemIcon>
2121
</StyledSeparator>
2222
<StyledTimelineContent ref={ref} {...props} />
2323
</>

packages/accordions/src/styled/accordion/StyledRotateIcon.spec.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,39 @@ describe('StyledRotateIcon', () => {
2626
);
2727
});
2828

29-
it('renders isRotated styling correctly', () => {
29+
it('renders $isRotated styling correctly', () => {
3030
const { container } = render(
31-
<StyledRotateIcon isRotated>
31+
<StyledRotateIcon $isRotated>
3232
<svg />
3333
</StyledRotateIcon>
3434
);
3535

3636
expect(container.firstChild).toHaveStyleRule('transform', 'rotate(+180deg)');
3737
});
3838

39-
it('renders isCompact styling correctly', () => {
39+
it('renders $isCompact styling correctly', () => {
4040
const { container } = render(
41-
<StyledRotateIcon isCompact>
41+
<StyledRotateIcon $isCompact>
4242
<svg />
4343
</StyledRotateIcon>
4444
);
4545

4646
expect(container.firstChild).toHaveStyleRule('padding', '6px 12px');
4747
});
4848

49-
it('renders isRotated styling correctly for RTL', () => {
49+
it('renders $isRotated styling correctly for RTL', () => {
5050
const { container } = renderRtl(
51-
<StyledRotateIcon isRotated>
51+
<StyledRotateIcon $isRotated>
5252
<svg />
5353
</StyledRotateIcon>
5454
);
5555

5656
expect(container.firstChild).toHaveStyleRule('transform', 'rotate(-180deg)');
5757
});
5858

59-
it('renders isHovered styling correctly', () => {
59+
it('renders $isHovered styling correctly', () => {
6060
const { container } = render(
61-
<StyledRotateIcon isHovered>
61+
<StyledRotateIcon $isHovered>
6262
<svg />
6363
</StyledRotateIcon>
6464
);

packages/accordions/src/styled/accordion/StyledRotateIcon.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,28 @@
55
* found at http://www.apache.org/licenses/LICENSE-2.0.
66
*/
77

8-
import { cloneElement, Children } from 'react';
98
import styled, { css, ThemeProps, DefaultTheme } from 'styled-components';
10-
import { getColorV8, retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden/react-theming';
9+
import {
10+
getColorV8,
11+
retrieveComponentStyles,
12+
DEFAULT_THEME,
13+
StyledBaseIcon
14+
} from '@zendeskgarden/react-theming';
1115

1216
const COMPONENT_ID = 'accordions.rotate_icon';
1317

1418
interface IStyledRotateIcon {
15-
isCompact?: boolean;
19+
$isCompact?: boolean;
20+
$isRotated?: boolean;
21+
$isHovered?: boolean;
22+
$isCollapsible?: boolean;
1623
}
1724

1825
const colorStyles = (props: ThemeProps<DefaultTheme> & any) => {
19-
const showColor = props.isCollapsible || !props.isRotated;
26+
const showColor = props.$isCollapsible || !props.$isRotated;
2027
let color = getColorV8('neutralHue', 600, props.theme);
2128

22-
if (showColor && props.isHovered) {
29+
if (showColor && props.$isHovered) {
2330
color = getColorV8('primaryHue', 600, props.theme);
2431
}
2532

@@ -32,21 +39,17 @@ const colorStyles = (props: ThemeProps<DefaultTheme> & any) => {
3239
`;
3340
};
3441

35-
export const StyledRotateIcon = styled(
36-
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
37-
({ children, isRotated, isHovered, isCompact, isCollapsible, ...props }) =>
38-
cloneElement(Children.only(children), props)
39-
).attrs({
42+
export const StyledRotateIcon = styled(StyledBaseIcon).attrs({
4043
'data-garden-id': COMPONENT_ID,
4144
'data-garden-version': PACKAGE_VERSION
4245
})<IStyledRotateIcon>`
43-
transform: ${props => props.isRotated && `rotate(${props.theme.rtl ? '-' : '+'}180deg)`};
46+
transform: ${props => props.$isRotated && `rotate(${props.theme.rtl ? '-' : '+'}180deg)`};
4447
transition:
4548
transform 0.25s ease-in-out,
4649
color 0.1s ease-in-out;
4750
box-sizing: content-box;
4851
padding: ${props =>
49-
props.isCompact
52+
props.$isCompact
5053
? `${props.theme.space.base * 1.5}px ${props.theme.space.base * 3}px`
5154
: `${props.theme.space.base * 5}px`};
5255
width: ${props => props.theme.iconSizes.md};

packages/accordions/src/styled/timeline/StyledItemIcon.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,32 @@
55
* found at http://www.apache.org/licenses/LICENSE-2.0.
66
*/
77

8-
import { cloneElement, Children } from 'react';
98
import styled from 'styled-components';
109
import { math } from 'polished';
11-
import { getColorV8, retrieveComponentStyles, DEFAULT_THEME } from '@zendeskgarden/react-theming';
10+
import {
11+
getColorV8,
12+
retrieveComponentStyles,
13+
DEFAULT_THEME,
14+
StyledBaseIcon
15+
} from '@zendeskgarden/react-theming';
1216

1317
const COMPONENT_ID = 'timeline.icon';
1418

1519
interface IStyledItemIcon {
16-
surfaceColor?: string;
20+
$surfaceColor?: string;
1721
}
1822

1923
/**
2024
* 1. Odd sizing allows the timeline line to center respective of the circle icon.
2125
*/
22-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
23-
export const StyledItemIcon = styled(({ surfaceColor, children, ...props }) =>
24-
cloneElement(Children.only(children), props)
25-
).attrs({
26+
export const StyledItemIcon = styled(StyledBaseIcon).attrs({
2627
'data-garden-id': COMPONENT_ID,
2728
'data-garden-version': PACKAGE_VERSION
2829
})<IStyledItemIcon>`
2930
z-index: 1;
3031
box-sizing: content-box;
3132
background-color: ${props =>
32-
props.surfaceColor || getColorV8('background', 600 /* default shade */, props.theme)};
33+
props.$surfaceColor || getColorV8('background', 600 /* default shade */, props.theme)};
3334
padding: ${props => props.theme.space.base}px 0;
3435
width: ${props => math(`${props.theme.iconSizes.sm} + 1`)}; /* [1] */
3536
height: ${props => math(`${props.theme.iconSizes.sm} + 1`)}; /* [1] */

packages/theming/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export { useWindow } from './utils/useWindow';
2424
export { useText } from './utils/useText';
2525
export { default as menuStyles } from './utils/menuStyles';
2626
export { focusStyles, SELECTOR_FOCUS_VISIBLE } from './utils/focusStyles';
27+
export { StyledBaseIcon } from './utils/StyledBaseIcon';
2728

2829
export {
2930
ARROW_POSITION,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright Zendesk, Inc.
3+
*
4+
* Use of this source code is governed under the Apache License, Version 2.0
5+
* found at http://www.apache.org/licenses/LICENSE-2.0.
6+
*/
7+
8+
import styled from 'styled-components';
9+
import React, { Children } from 'react';
10+
11+
// eslint-disable-next-line @typescript-eslint/no-unused-vars,garden-local/require-default-theme
12+
export const StyledBaseIcon = styled(({ children, theme, ...props }) =>
13+
React.cloneElement(Children.only(children), props)
14+
)`
15+
/* stylelint-disable no-empty-block */
16+
`;

0 commit comments

Comments
 (0)