(
`${prefixCls}-item`,
{
[`${prefixCls}-item-selected`]:
- segmentedOption.value === visualSelected,
+ segmentedOption.value === rawValue && !thumbShow,
},
)}
- checked={segmentedOption.value === selected}
+ checked={segmentedOption.value === rawValue}
onChange={handleChange}
{...segmentedOption}
/>
diff --git a/tests/__snapshots__/index.spec.tsx.snap b/tests/__snapshots__/index.spec.tsx.snap
index 95de403..dd56eb3 100644
--- a/tests/__snapshots__/index.spec.tsx.snap
+++ b/tests/__snapshots__/index.spec.tsx.snap
@@ -110,7 +110,7 @@ exports[`rc-segmented render segmented ok 1`] = `
`;
-exports[`rc-segmented render segmented with CSSMotion 1`] = `
+exports[`rc-segmented render segmented with CSSMotion basic 1`] = `
diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx
index f9aa2f0..a7a0392 100644
--- a/tests/index.spec.tsx
+++ b/tests/index.spec.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import { render, act, fireEvent } from '@testing-library/react';
import Segmented from '../src';
-import type { SegmentedValue } from '../src';
jest.mock('rc-motion/lib/util/motion', () => {
return {
@@ -24,6 +23,15 @@ describe('rc-segmented', () => {
});
}
+ function exceptThumbHaveStyle(container: HTMLElement, matchStyle: object) {
+ const styleText = container
+ .querySelector('.rc-segmented-thumb')
+ ?.getAttribute('data-test-style');
+ const style = JSON.parse(styleText!) || {};
+
+ expect(style).toMatchObject(matchStyle);
+ }
+
beforeEach(() => {
jest.useFakeTimers();
});
@@ -260,105 +268,133 @@ describe('rc-segmented', () => {
container.querySelector('.rc-segmented-item-selected')?.textContent,
).toContain('Web3');
- // Motion end
- fireEvent.animationEnd(container.querySelector('.rc-segmented-thumb')!);
- act(() => {
- jest.runAllTimers();
- });
-
// change it strangely
fireEvent.change(container.querySelector('.control')!, {
target: { value: 'Web4' },
});
- // invalid changes
- expect(
- container.querySelector('.rc-segmented-item-selected')?.textContent,
- ).toContain('Web3');
+ // invalid changes: Should not active any item to make sure it's single source of truth
+ expect(container.querySelector('.rc-segmented-item-selected')).toBeFalsy();
});
- it('render segmented with CSSMotion', () => {
- const handleValueChange = jest.fn();
- const { container, asFragment } = render(
- handleValueChange(value)}
- />,
- );
- expect(asFragment().firstChild).toMatchSnapshot();
-
- expectMatchChecked(container, [true, false, false]);
- expect(container.querySelectorAll('.rc-segmented-item')[0]).toHaveClass(
- 'rc-segmented-item-selected',
- );
+ describe('render segmented with CSSMotion', () => {
+ it('basic', () => {
+ const handleValueChange = jest.fn();
+ const { container, asFragment } = render(
+ handleValueChange(value)}
+ />,
+ );
+ expect(asFragment().firstChild).toMatchSnapshot();
- fireEvent.click(container.querySelectorAll('.rc-segmented-item-input')[2]);
- expect(handleValueChange).toBeCalledWith('Web3');
- expectMatchChecked(container, [false, false, true]);
+ expectMatchChecked(container, [true, false, false]);
+ expect(container.querySelectorAll('.rc-segmented-item')[0]).toHaveClass(
+ 'rc-segmented-item-selected',
+ );
- expect(container.querySelectorAll('.rc-segmented-thumb')[0]).toHaveClass(
- 'rc-segmented-thumb-motion',
- );
+ // >>> Click: Web3
+ fireEvent.click(
+ container.querySelectorAll('.rc-segmented-item-input')[2],
+ );
+ expect(handleValueChange).toBeCalledWith('Web3');
+ expectMatchChecked(container, [false, false, true]);
- // thumb appeared at `iOS`
- expect(container.querySelectorAll('.rc-segmented-thumb')[0]).toHaveStyle({
- transform: 'translateX(0px)',
- width: '62px',
- });
+ expect(container.querySelectorAll('.rc-segmented-thumb')[0]).toHaveClass(
+ 'rc-segmented-thumb-motion',
+ );
- // Motion => active
- act(() => {
- jest.runAllTimers();
- });
+ // thumb appeared at `iOS`
+ exceptThumbHaveStyle(container, {
+ '--thumb-start-left': '0px',
+ '--thumb-start-width': '62px',
+ });
+
+ // Motion => active
+ act(() => {
+ jest.runAllTimers();
+ });
+
+ // Motion enter end
+ fireEvent.animationEnd(container.querySelector('.rc-segmented-thumb')!);
+ act(() => {
+ jest.runAllTimers();
+ });
+
+ // thumb should disappear
+ expect(container.querySelector('.rc-segmented-thumb')).toBeFalsy();
+
+ // >>> Click: Android
+ fireEvent.click(
+ container.querySelectorAll('.rc-segmented-item-input')[1],
+ );
+ expect(handleValueChange).toBeCalledWith('Android');
+ expectMatchChecked(container, [false, true, false]);
- // Motion enter end
- fireEvent.animationEnd(container.querySelector('.rc-segmented-thumb')!);
- act(() => {
- jest.runAllTimers();
- });
+ // thumb should move
+ expect(container.querySelector('.rc-segmented-thumb')).toHaveClass(
+ 'rc-segmented-thumb-motion',
+ );
- // Motion leave end
- fireEvent.animationEnd(container.querySelector('.rc-segmented-thumb')!);
- act(() => {
- jest.runAllTimers();
+ // thumb appeared at `Web3`
+ exceptThumbHaveStyle(container, {
+ '--thumb-start-left': '180px',
+ '--thumb-start-width': '76px',
+ });
+
+ // Motion appear end
+ act(() => {
+ jest.runAllTimers();
+ });
+ exceptThumbHaveStyle(container, {
+ '--thumb-active-left': '62px',
+ '--thumb-active-width': '118px',
+ });
+ fireEvent.animationEnd(container.querySelector('.rc-segmented-thumb')!);
+ act(() => {
+ jest.runAllTimers();
+ });
+
+ // thumb should disappear
+ expect(container.querySelector('.rc-segmented-thumb')).toBeFalsy();
});
- // thumb should disappear
- expect(container.querySelector('.rc-segmented-thumb')).toBeFalsy();
+ it('quick switch', () => {
+ const { container } = render(
+ ,
+ );
- // change selection again
- fireEvent.click(container.querySelectorAll('.rc-segmented-item-input')[1]);
- expect(handleValueChange).toBeCalledWith('Android');
- expectMatchChecked(container, [false, true, false]);
+ // >>> Click: Web3
+ fireEvent.click(
+ container.querySelectorAll('.rc-segmented-item-input')[2],
+ );
- // thumb should move
- expect(container.querySelector('.rc-segmented-thumb')).toHaveClass(
- 'rc-segmented-thumb-motion',
- );
+ // Motion to active
+ act(() => {
+ jest.runAllTimers();
+ });
+ expect(container.querySelector('.rc-segmented-thumb')).toHaveClass(
+ 'rc-segmented-thumb-motion-appear-active',
+ );
- // thumb appeared at `Web3`
- expect(container.querySelector('.rc-segmented-thumb')).toHaveStyle({
- transform: 'translateX(180px)',
- width: '76px',
- });
+ exceptThumbHaveStyle(container, {
+ '--thumb-active-left': '180px',
+ '--thumb-active-width': '76px',
+ });
- // Motion enter end
- act(() => {
- jest.runAllTimers();
- });
- fireEvent.animationEnd(container.querySelector('.rc-segmented-thumb')!);
- act(() => {
- jest.runAllTimers();
- });
+ // >>> Click: IOS
+ fireEvent.click(
+ container.querySelectorAll('.rc-segmented-item-input')[0],
+ );
- // Motion leave end
- fireEvent.animationEnd(container.querySelector('.rc-segmented-thumb')!);
- act(() => {
- jest.runAllTimers();
+ exceptThumbHaveStyle(container, {
+ '--thumb-active-left': '0px',
+ '--thumb-active-width': '62px',
+ });
});
-
- // thumb should disappear
- expect(container.querySelector('.rc-segmented-thumb')).toBeFalsy();
});
it('render segmented with options null/undefined', () => {
diff --git a/tests/setup.ts b/tests/setup.ts
index 8fa23d1..b9329bd 100644
--- a/tests/setup.ts
+++ b/tests/setup.ts
@@ -13,7 +13,9 @@ Object.defineProperties(window.HTMLElement.prototype, {
offsetLeft: {
get() {
let offsetLeft = 0;
- const childList: HTMLElement[] = Array.from(this.parentNode.children);
+ const childList: HTMLElement[] = Array.from(
+ (this.parentNode as HTMLElement).querySelectorAll('.rc-segmented-item'),
+ );
for (let i = 0; i < childList.length; i++) {
const child = childList[i];
const lastChild = childList[i - 1];