Skip to content

Commit 91849a4

Browse files
Gururajj77ariellalgilmorelaurenmriceadamalston
authored
feat: low contrast content switcher implementation (#18923)
* feat: low contrast content switcher implementation * feat: added the new prop and classnames * feat: added new states for lc content switcher * feat: added dashes for each item * feat: added disabled styles * fix(content-switcher): exporting tokens * fix(border-color): low-contrast specfic * fix(content-switcher): cleanup * feat: modified the anime stuff * fix(content-switcher): low contrast overrides/cleanup * feat: added icon filling for disabled state * feat: added avt tests * fix: reordered storybook props * test: fixed tests * fix(lc): resolve conflicts * fix(lc): remove commented styles * fix(content-switcher): cornerssss * fix(switcher): focus and icon hover * test: added tests around low contrast feature * fix(content-switcher): types * Update packages/themes/tasks/builders/modules-content-switcher-tokens.js Co-authored-by: Adam Alston <[email protected]> * test: added assertions to all classes * chore: updated copyrights * chore: updated copyright notices * fix(content-switcher): all corners hovering --------- Co-authored-by: ariellalgilmore <[email protected]> Co-authored-by: Lauren Rice <[email protected]> Co-authored-by: Adam Alston <[email protected]>
1 parent 184bbaf commit 91849a4

File tree

22 files changed

+805
-58
lines changed

22 files changed

+805
-58
lines changed

e2e/components/ContentSwitcher/ContentSwitcher-test.avt.e2e.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,32 @@ test.describe('@avt ContentSwitcher', () => {
7272
await page.keyboard.press('ArrowRight');
7373
await expect(thirdIconTab).toBeVisible();
7474
});
75+
76+
test('@avt-low-contrast ContentSwitcher', async ({ page }) => {
77+
await visitStory(page, {
78+
component: 'ContentSwitcher',
79+
id: 'components-contentswitcher--low-contrast',
80+
globals: {
81+
theme: 'white',
82+
},
83+
args: {
84+
lowContrast: true,
85+
},
86+
});
87+
await expect(page).toHaveNoACViolations('ContentSwitcher (low contrast)');
88+
});
89+
90+
test('@avt-low-contrast ContentSwitcher icon only', async ({ page }) => {
91+
await visitStory(page, {
92+
component: 'ContentSwitcher',
93+
id: 'components-contentswitcher--low-contrast-icon-only',
94+
globals: {
95+
theme: 'white',
96+
},
97+
args: {
98+
lowContrast: true,
99+
},
100+
});
101+
await expect(page).toHaveNoACViolations('ContentSwitcher (low contrast)');
102+
});
75103
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Code generated by carbon-components-react. DO NOT EDIT.
2+
//
3+
// Copyright IBM Corp. 2018, 2023
4+
//
5+
// This source code is licensed under the Apache-2.0 license found in the
6+
// LICENSE file in the root directory of this source tree.
7+
//
8+
9+
@forward '@carbon/styles/scss/components/content-switcher/tokens';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Code generated by carbon-components. DO NOT EDIT.
2+
//
3+
// Copyright IBM Corp. 2018, 2023
4+
//
5+
// This source code is licensed under the Apache-2.0 license found in the
6+
// LICENSE file in the root directory of this source tree.
7+
//
8+
9+
@forward '@carbon/styles/scss/components/content-switcher/tokens';

packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Array [
9898
"container03",
9999
"container04",
100100
"container05",
101+
"contentSwitcherTokens",
101102
"coolGray",
102103
"coolGray10",
103104
"coolGray100",
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Code generated by @carbon/react. DO NOT EDIT.
2+
//
3+
// Copyright IBM Corp. 2018, 2023
4+
//
5+
// This source code is licensed under the Apache-2.0 license found in the
6+
// LICENSE file in the root directory of this source tree.
7+
//
8+
9+
@forward '@carbon/styles/scss/components/content-switcher/tokens';

packages/react/src/components/ContentSwitcher/ContentSwitcher-test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,51 @@ describe('ContentSwitcher - RTL', () => {
134134
'cds--content-switcher--lg'
135135
);
136136
});
137+
138+
it('should have the correct attributes when lowContrast prop is used', () => {
139+
const { container } = render(
140+
<ContentSwitcher onChange={() => {}} lowContrast>
141+
<Switch name="one" text="First section" />
142+
<Switch name="two" text="Second section" />
143+
<Switch name="three" text="Third section" />
144+
</ContentSwitcher>
145+
);
146+
147+
const attributes = Array.from(container.firstChild.attributes).reduce(
148+
(acc, { name, value }) => ({ ...acc, [name]: value }),
149+
{}
150+
);
151+
152+
expect(attributes).toEqual({
153+
class:
154+
'cds--content-switcher cds--content-switcher--low-contrast cds--layout-constraint--size__default-md cds--layout-constraint--size__min-sm cds--layout-constraint--size__max-lg',
155+
role: 'tablist',
156+
});
157+
});
158+
159+
it('should have the correct attributes with iconOnly version when lowContrast is used', () => {
160+
// Mock the IconSwitch component
161+
const IconSwitch = (props) => <Switch {...props} />;
162+
IconSwitch.displayName = 'IconSwitch';
163+
164+
const { container } = render(
165+
<ContentSwitcher onChange={() => {}} lowContrast>
166+
<IconSwitch name="one" />
167+
<IconSwitch name="two" />
168+
<IconSwitch name="three" />
169+
</ContentSwitcher>
170+
);
171+
172+
const attributes = Array.from(container.firstChild.attributes).reduce(
173+
(acc, { name, value }) => ({ ...acc, [name]: value }),
174+
{}
175+
);
176+
177+
expect(attributes).toEqual({
178+
class:
179+
'cds--content-switcher cds--content-switcher--icon-only cds--content-switcher--low-contrast cds--layout-constraint--size__default-md cds--layout-constraint--size__min-sm cds--layout-constraint--size__max-lg',
180+
role: 'tablist',
181+
});
182+
});
137183
});
138184
});

packages/react/src/components/ContentSwitcher/ContentSwitcher.stories.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,33 @@ export const IconOnlyWithLayer = (args) => (
114114
</WithLayer>
115115
);
116116

117+
export const lowContrast = (args) => (
118+
<ContentSwitcher lowContrast {...args}>
119+
<Switch name="one" text="First section" />
120+
<Switch name="two" text="Second section" />
121+
<Switch name="three" text="Third section" />
122+
</ContentSwitcher>
123+
);
124+
lowContrast.argTypes = {
125+
...sharedArgTypes,
126+
};
127+
128+
export const lowContrastIconOnly = (args) => (
129+
<ContentSwitcher lowContrast onChange={() => {}} {...args}>
130+
<IconSwitch name="one" text="Table of Contents">
131+
<TableOfContents />
132+
</IconSwitch>
133+
<IconSwitch name="two" text="Workspace Test">
134+
<Workspace />
135+
</IconSwitch>
136+
<IconSwitch name="three" text="View Mode">
137+
<ViewMode_2 />
138+
</IconSwitch>
139+
</ContentSwitcher>
140+
);
141+
lowContrastIconOnly.argTypes = {
142+
...sharedArgTypes,
143+
};
117144
IconOnlyWithLayer.argTypes = {
118145
...sharedArgTypes,
119146
};

packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ export interface ContentSwitcherProps
4141
* been deprecated in favor of the new `Layer` component. It will be removed in the next major release.
4242
*/
4343
light?: boolean;
44-
44+
/**
45+
* `true` to use the low contrast version.
46+
*/
47+
lowContrast?: boolean;
4548
/**
4649
* Specify an `onChange` handler that is called whenever the ContentSwitcher
4750
* changes which item is selected
@@ -103,6 +106,11 @@ export default class ContentSwitcher extends React.Component<
103106
'been deprecated. It will be removed in the next major release.'
104107
),
105108

109+
/**
110+
* `true` to use the low contrast version.
111+
*/
112+
lowContrast: PropTypes.bool,
113+
106114
/**
107115
* Specify an `onChange` handler that is called whenever the ContentSwitcher
108116
* changes which item is selected
@@ -198,6 +206,7 @@ export default class ContentSwitcher extends React.Component<
198206
children,
199207
className,
200208
light,
209+
lowContrast,
201210
// eslint-disable-next-line @typescript-eslint/no-unused-vars
202211
selectedIndex = 0,
203212
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -217,6 +226,7 @@ export default class ContentSwitcher extends React.Component<
217226
[`${prefix}--content-switcher--${size}`]: size, // TODO: V12 - Remove this class
218227
[`${prefix}--layout--size-${size}`]: size,
219228
[`${prefix}--content-switcher--icon-only`]: isIconOnly,
229+
[`${prefix}--content-switcher--low-contrast`]: lowContrast,
220230
});
221231

222232
return (

packages/styles/__tests__/__snapshots__/styles-test.js.snap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ Array [
207207
"importPath": "@carbon/styles/scss/components/content-switcher",
208208
"relativePath": "scss/components/content-switcher",
209209
},
210+
Object {
211+
"filepath": "scss/components/content-switcher/_tokens.scss",
212+
"importPath": "@carbon/styles/scss/components/content-switcher/tokens",
213+
"relativePath": "scss/components/content-switcher/tokens",
214+
},
210215
Object {
211216
"filepath": "scss/components/copy-button/_copy-button.scss",
212217
"importPath": "@carbon/styles/scss/components/copy-button/copy-button",

packages/styles/files.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const files = [
6060
'scss/components/contained-list/_index.scss',
6161
'scss/components/content-switcher/_content-switcher.scss',
6262
'scss/components/content-switcher/_index.scss',
63+
'scss/components/content-switcher/_tokens.scss',
6364
'scss/components/copy-button/_copy-button.scss',
6465
'scss/components/copy-button/_index.scss',
6566
'scss/components/data-table/_data-table.scss',

packages/styles/scss/_zone.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
@use './components/notification/tokens' as notification;
1919
@use './components/tag/tokens' as tag;
2020
@use './components/icon-indicator/tokens' as icon-indicator;
21+
@use './components/content-switcher/tokens' as content-switcher;
2122

2223
/// Specify a Map of zones where the key will be used as part of the selector
2324
/// and the value will be a map used to emit CSS Custom Properties for all color
@@ -33,7 +34,8 @@ $-components: (
3334
button.$button-tokens,
3435
notification.$notification-tokens,
3536
tag.$tag-tokens,
36-
icon-indicator.$status-tokens
37+
icon-indicator.$status-tokens,
38+
content-switcher.$content-switcher-tokens
3739
);
3840

3941
@each $name, $theme in $zones {

0 commit comments

Comments
 (0)