Skip to content

Commit 2f64ab0

Browse files
committed
add a TierIndicator component
1 parent dcb7374 commit 2f64ab0

File tree

5 files changed

+171
-0
lines changed

5 files changed

+171
-0
lines changed

.changeset/moody-eyes-draw.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@sumup-oss/circuit-ui": minor
3+
---
4+
5+
Added a TierIndicator component for freemium plans.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Meta, Status, Props, Story } from "../../../../.storybook/components";
2+
import * as Stories from "./TierIndicator.stories";
3+
4+
<Meta of={Stories} />
5+
6+
# TierIndicator
7+
8+
The TierIndicator component is used to highlight freemium offerings in the UI.
9+
10+
<Status variant="stable" />
11+
12+
<Story of={Stories.Base} />
13+
<Props />
14+
15+
## Best practices
16+
17+
- Don’t pair the component with the SumUp logo or in a block of text.
18+
- Limit the usage of the tier indicators per screen, group together concerned features if possible.
19+
- The Indicator mark should be used to highlight freemium offerings only.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright 2025, SumUp Ltd.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
import { describe, expect, it } from 'vitest';
17+
18+
import { render, axe } from '../../util/test-utils.js';
19+
20+
import { TierIndicator } from './TierIndicator.js';
21+
22+
describe('TierIndicator', () => {
23+
it('should merge a custom class name with the default ones', () => {
24+
const className = 'foo';
25+
const { container } = render(
26+
<TierIndicator variant="plus" className={className} />,
27+
);
28+
const tierIndicator = container.querySelector('svg');
29+
expect(tierIndicator?.classList).toContain(className);
30+
});
31+
32+
it('should meet accessibility guidelines', async () => {
33+
const { container } = render(<TierIndicator variant="plus" />);
34+
const actual = await axe(container);
35+
expect(actual).toHaveNoViolations();
36+
});
37+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright 2025, SumUp Ltd.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
import { Stack } from '../../../../.storybook/components/index.js';
17+
18+
import { TierIndicator, type TierIndicatorProps } from './TierIndicator.js';
19+
20+
export default {
21+
title: 'Brand/TierIndicator',
22+
component: TierIndicator,
23+
tags: ['status:stable'],
24+
};
25+
26+
export const Base = (args: TierIndicatorProps) => <TierIndicator {...args} />;
27+
28+
export const Sizes = (args: TierIndicatorProps) => (
29+
<dl
30+
style={{
31+
display: 'flex',
32+
flexDirection: 'column',
33+
alignItems: 'flex-start',
34+
gap: 'var(--cui-spacings-giga)',
35+
}}
36+
>
37+
<Stack key="small">
38+
<dt>
39+
Size <strong>s</strong>:
40+
</dt>
41+
<dd>
42+
<TierIndicator {...args} size="s" />
43+
</dd>
44+
</Stack>
45+
<Stack key="medium">
46+
<dt>
47+
Size <strong>m</strong>:
48+
</dt>
49+
<dd>
50+
<TierIndicator {...args} size="m" />
51+
</dd>
52+
</Stack>
53+
<Stack key="large">
54+
<dt>
55+
{' '}
56+
Size <strong>l</strong>:
57+
</dt>
58+
<dd>
59+
<TierIndicator {...args} size="l" />
60+
</dd>
61+
</Stack>
62+
</dl>
63+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright 2025, SumUp Ltd.
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
import type { HTMLAttributes } from 'react';
17+
import { PlusTier } from '@sumup-oss/icons';
18+
19+
import { utilClasses } from '../../styles/utility.js';
20+
21+
export interface TierIndicatorProps extends HTMLAttributes<SVGElement> {
22+
/**
23+
* The tier name.
24+
*/
25+
variant: 'plus';
26+
/**
27+
* Choose from 3 sizes.
28+
* @default 'm'
29+
*/
30+
size?: 's' | 'm' | 'l';
31+
}
32+
const sizeMap: Record<string, '16' | '24' | '32'> = {
33+
s: '16',
34+
m: '24',
35+
l: '32',
36+
};
37+
38+
export const TierIndicator = ({
39+
size = 'm',
40+
variant = 'plus',
41+
...props
42+
}: TierIndicatorProps) => (
43+
<>
44+
<span className={utilClasses.hideVisually}>{variant}</span>
45+
<PlusTier aria-hidden="true" size={sizeMap[size]} {...props} />
46+
</>
47+
);

0 commit comments

Comments
 (0)