diff --git a/docs/examples/animated.tsx b/docs/examples/animated.tsx index c28d62fa..f6118acb 100644 --- a/docs/examples/animated.tsx +++ b/docs/examples/animated.tsx @@ -1,6 +1,6 @@ import React from 'react'; import Tabs from '../../src'; -import type { CSSMotionProps } from 'rc-motion'; +import type { CSSMotionProps } from '@rc-component/motion'; import '../../assets/index.less'; import './animated.less'; diff --git a/jest.config.js b/jest.config.js index 520a138f..54a5210c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -13,12 +13,13 @@ const compileModules = [ const ignoreList = []; // cnpm use `_` as prefix -['', '_'].forEach((prefix) => { - compileModules.forEach((module) => { +['', '_'].forEach(prefix => { + compileModules.forEach(module => { ignoreList.push(`${prefix}${module}`); }); }); module.exports = { transformIgnorePatterns: [`/node_modules/(?!${ignoreList.join('|')})[^/]+?/(?!(es)/)`], + setupFiles: ['./tests/setup.ts'], }; diff --git a/package.json b/package.json index aae924cf..195e16d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "rc-tabs", - "version": "15.5.0", + "name": "@rc-component/tabs", + "version": "1.0.0", "description": "tabs ui component for react", "keywords": [ "react", @@ -38,12 +38,12 @@ }, "dependencies": { "@babel/runtime": "^7.11.2", - "classnames": "2.x", + "@rc-component/motion": "^1.0.0", + "@rc-component/resize-observer": "^1.0.0", + "@rc-component/util": "^1.2.0", + "classnames": "^2.5.1", "rc-dropdown": "~4.2.0", - "rc-menu": "~9.16.0", - "rc-motion": "^2.6.2", - "rc-resize-observer": "^1.0.0", - "rc-util": "^5.34.1" + "rc-menu": "~9.16.0" }, "devDependencies": { "@rc-component/father-plugin": "^1.0.0", @@ -55,8 +55,9 @@ "@types/enzyme": "^3.10.5", "@types/jest": "^29.4.0", "@types/keyv": "4.2.0", - "@types/react": "^18.2.42", - "@types/react-dom": "^18.0.11", + "@types/node": "^22.12.0", + "@types/react": "^19.0.8", + "@types/react-dom": "^19.0.3", "@umijs/fabric": "^4.0.1", "coveralls": "^3.0.6", "cross-env": "^7.0.2", diff --git a/src/TabNavList/OperationNode.tsx b/src/TabNavList/OperationNode.tsx index 972da8fd..357837e7 100644 --- a/src/TabNavList/OperationNode.tsx +++ b/src/TabNavList/OperationNode.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import Dropdown from 'rc-dropdown'; import Menu, { MenuItem } from 'rc-menu'; -import KeyCode from 'rc-util/lib/KeyCode'; +import KeyCode from '@rc-component/util/lib/KeyCode'; import * as React from 'react'; import { useEffect, useState } from 'react'; import type { EditableConfig, Tab, TabsLocale, MoreProps } from '../interface'; diff --git a/src/TabNavList/index.tsx b/src/TabNavList/index.tsx index 332974da..79ca5694 100644 --- a/src/TabNavList/index.tsx +++ b/src/TabNavList/index.tsx @@ -1,8 +1,8 @@ /* eslint-disable react-hooks/exhaustive-deps */ import classNames from 'classnames'; -import ResizeObserver from 'rc-resize-observer'; -import useEvent from 'rc-util/lib/hooks/useEvent'; -import { useComposeRef } from 'rc-util/lib/ref'; +import ResizeObserver from '@rc-component/resize-observer'; +import useEvent from '@rc-component/util/lib/hooks/useEvent'; +import { useComposeRef } from '@rc-component/util/lib/ref'; import * as React from 'react'; import { useEffect, useRef, useState } from 'react'; import TabContext from '../TabContext'; diff --git a/src/TabPanelList/index.tsx b/src/TabPanelList/index.tsx index 0957bbb6..058bc8af 100644 --- a/src/TabPanelList/index.tsx +++ b/src/TabPanelList/index.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames'; -import CSSMotion from 'rc-motion'; +import CSSMotion from '@rc-component/motion'; import * as React from 'react'; import type { AnimatedConfig, TabPosition } from '../interface'; import TabContext from '../TabContext'; diff --git a/src/Tabs.tsx b/src/Tabs.tsx index 7d6df768..21aea45e 100644 --- a/src/Tabs.tsx +++ b/src/Tabs.tsx @@ -1,7 +1,7 @@ // Accessibility https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role import classNames from 'classnames'; -import useMergedState from 'rc-util/lib/hooks/useMergedState'; -import isMobile from 'rc-util/lib/isMobile'; +import useMergedState from '@rc-component/util/lib/hooks/useMergedState'; +import isMobile from '@rc-component/util/lib/isMobile'; import * as React from 'react'; import { useEffect, useState } from 'react'; import TabContext from './TabContext'; diff --git a/src/hooks/useAnimateConfig.ts b/src/hooks/useAnimateConfig.ts index a7cb2698..ebc6f428 100644 --- a/src/hooks/useAnimateConfig.ts +++ b/src/hooks/useAnimateConfig.ts @@ -1,4 +1,4 @@ -import warning from 'rc-util/lib/warning'; +import warning from '@rc-component/util/lib/warning'; import type { TabsProps } from '..'; import type { AnimatedConfig } from '../interface'; diff --git a/src/hooks/useIndicator.ts b/src/hooks/useIndicator.ts index 4195c36f..b025fea9 100644 --- a/src/hooks/useIndicator.ts +++ b/src/hooks/useIndicator.ts @@ -1,4 +1,4 @@ -import raf from 'rc-util/lib/raf'; +import raf from '@rc-component/util/lib/raf'; import React, { useEffect, useRef, useState } from 'react'; import type { TabOffset } from '../interface'; @@ -20,7 +20,8 @@ const useIndicator = (options: UseIndicatorOptions) => { const { size, align = 'center' } = indicator; const [inkStyle, setInkStyle] = useState(); - const inkBarRafRef = useRef(); + + const inkBarRafRef = useRef(undefined); const getLength = React.useCallback( (origin: number) => { diff --git a/src/hooks/useTouchMove.ts b/src/hooks/useTouchMove.ts index f8073ede..dc85c4d0 100644 --- a/src/hooks/useTouchMove.ts +++ b/src/hooks/useTouchMove.ts @@ -18,7 +18,7 @@ export default function useTouchMove( const [lastTimestamp, setLastTimestamp] = useState(0); const [lastTimeDiff, setLastTimeDiff] = useState(0); const [lastOffset, setLastOffset] = useState<{ x: number; y: number }>(); - const motionRef = useRef(); + const motionRef = useRef(undefined); // ========================= Events ========================= // >>> Touch events @@ -76,7 +76,7 @@ export default function useTouchMove( } // >>> Wheel event - const lastWheelDirectionRef = useRef<'x' | 'y'>(); + const lastWheelDirectionRef = useRef<'x' | 'y'>(undefined); function onWheel(e: WheelEvent) { const { deltaX, deltaY } = e; diff --git a/src/hooks/useUpdate.ts b/src/hooks/useUpdate.ts index 3a66c446..12e3f9ec 100644 --- a/src/hooks/useUpdate.ts +++ b/src/hooks/useUpdate.ts @@ -1,14 +1,14 @@ -import { useLayoutUpdateEffect } from 'rc-util/lib/hooks/useLayoutEffect'; +import { useLayoutUpdateEffect } from '@rc-component/util/lib/hooks/useLayoutEffect'; import { useRef, useState } from 'react'; /** * Help to merge callback with `useLayoutEffect`. * One time will only trigger once. */ -export default function useUpdate(callback: VoidFunction): () => void { +function useUpdate(callback: VoidFunction): () => void { const [count, setCount] = useState(0); const effectRef = useRef(0); - const callbackRef = useRef(); + const callbackRef = useRef(undefined); callbackRef.current = callback; // Trigger on `useLayoutEffect` @@ -56,3 +56,5 @@ export function useUpdateState( return [state.current, updater]; } + +export default useUpdate; diff --git a/src/interface.ts b/src/interface.ts index ea7958af..68d0fd20 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -1,15 +1,17 @@ -import type { CSSMotionProps } from 'rc-motion'; +import type { CSSMotionProps } from '@rc-component/motion'; import type React from 'react'; import type { TabNavListProps } from './TabNavList'; import type { TabPaneProps } from './TabPanelList/TabPane'; -import { DropdownProps } from 'rc-dropdown/lib/Dropdown'; +import type { DropdownProps } from 'rc-dropdown/lib/Dropdown'; export type TriggerProps = { trigger?: 'hover' | 'click'; -} +}; + export type moreIcon = React.ReactNode; + export type MoreProps = { - icon?: moreIcon, + icon?: moreIcon; } & Omit; export type SizeInfo = [width: number, height: number]; @@ -45,7 +47,7 @@ type RenderTabBarProps = { mobile: boolean; editable: EditableConfig; locale: TabsLocale; - more: MoreProps, + more: MoreProps; tabBarGutter: number; onTabClick: (key: string, e: React.MouseEvent | React.KeyboardEvent) => void; onTabScroll: OnTabScroll; diff --git a/tests/common/util.tsx b/tests/common/util.tsx index b19cd35d..f4617a99 100644 --- a/tests/common/util.tsx +++ b/tests/common/util.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-invalid-this */ import { act } from '@testing-library/react'; -import { _rs as onEsResize } from 'rc-resize-observer/es/utils/observerUtil'; -import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil'; +import { _rs as onEsResize } from '@rc-component/resize-observer/es/utils/observerUtil'; +import { _rs as onLibResize } from '@rc-component/resize-observer/lib/utils/observerUtil'; import React from 'react'; import Tabs from '../../src'; import type { TabsProps } from '../../src/Tabs'; diff --git a/tests/index.test.tsx b/tests/index.test.tsx index db5bc7d9..ca8bf251 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -1,6 +1,6 @@ import '@testing-library/dom'; import { act, fireEvent, render, screen } from '@testing-library/react'; -import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import { spyElementPrototypes } from '@rc-component/util/lib/test/domHook'; import React from 'react'; import Tabs from '../src'; import type { TabsProps } from '../src/Tabs'; diff --git a/tests/mobile.test.tsx b/tests/mobile.test.tsx index 5e0a2130..995388b7 100644 --- a/tests/mobile.test.tsx +++ b/tests/mobile.test.tsx @@ -1,12 +1,12 @@ import { render } from '@testing-library/react'; -import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import { spyElementPrototypes } from '@rc-component/util/lib/test/domHook'; import React from 'react'; import { act } from 'react-dom/test-utils'; import type { TabsProps } from '../src'; import Tabs from '../src'; import { btnOffsetPosition, getOffsetSizeFunc, getTransformX } from './common/util'; -jest.mock('rc-util/lib/isMobile', () => () => true); +jest.mock('@rc-component/util/lib/isMobile', () => () => true); describe('Tabs.Mobile', () => { const tabCount = 100; diff --git a/tests/operation-overflow.test.tsx b/tests/operation-overflow.test.tsx index b48abe0c..47b3df77 100644 --- a/tests/operation-overflow.test.tsx +++ b/tests/operation-overflow.test.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-invalid-this */ import { render } from '@testing-library/react'; -import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import { spyElementPrototypes } from '@rc-component/util/lib/test/domHook'; import { act } from 'react-dom/test-utils'; import { getOffsetSizeFunc, getTabs, triggerResize } from './common/util'; diff --git a/tests/overflow.test.tsx b/tests/overflow.test.tsx index 509bbae6..173fb0b4 100644 --- a/tests/overflow.test.tsx +++ b/tests/overflow.test.tsx @@ -1,6 +1,6 @@ import { act, fireEvent, render } from '@testing-library/react'; -import KeyCode from 'rc-util/lib/KeyCode'; -import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import KeyCode from '@rc-component/util/lib/KeyCode'; +import { spyElementPrototypes } from '@rc-component/util/lib/test/domHook'; import React from 'react'; import type { TabsProps } from '../src'; import Tabs from '../src'; @@ -95,12 +95,14 @@ describe('Tabs.Overflow', () => { it('should open dropdown on click when moreTrigger is set to click', () => { jest.useFakeTimers(); const onChange = jest.fn(); - const { container, unmount } = render(getTabs({ onChange, more: {icon: '...', trigger: 'click'} })); + const { container, unmount } = render( + getTabs({ onChange, more: { icon: '...', trigger: 'click' } }), + ); triggerResize(container); act(() => { jest.runAllTimers(); }); - const button = container.querySelector('.rc-tabs-nav-more') + const button = container.querySelector('.rc-tabs-nav-more'); fireEvent.click(button); act(() => { jest.runAllTimers(); diff --git a/tests/rtl.test.tsx b/tests/rtl.test.tsx index 04277169..1fd0566a 100644 --- a/tests/rtl.test.tsx +++ b/tests/rtl.test.tsx @@ -1,6 +1,5 @@ -import { render } from '@testing-library/react'; -import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; -import { act } from 'react-dom/test-utils'; +import { render, act } from '@testing-library/react'; +import { spyElementPrototypes } from '@rc-component/util/lib/test/domHook'; import { getOffsetSizeFunc, getTabs, getTransformX, triggerResize } from './common/util'; // Same as `overflow.test.tsx` but use in RTL diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 00000000..41a53a49 --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,6 @@ +// Mock ResizeObserver +global.ResizeObserver = class ResizeObserver { + observe() {} + unobserve() {} + disconnect() {} +}; diff --git a/tests/swipe.js b/tests/swipe.js deleted file mode 100644 index 27b97e9f..00000000 --- a/tests/swipe.js +++ /dev/null @@ -1,96 +0,0 @@ -/* eslint-disable no-undef */ -import React, { Component } from 'react'; -import { mount, render } from 'enzyme'; -import { renderToJson } from 'enzyme-to-json'; -import Tabs, { TabPane } from '../src'; -import SwipeableTabContent from '../src/SwipeableTabContent'; -import SwipeableInkTabBar from '../src/SwipeableInkTabBar'; - -const contentStyle = { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - height: '5rem', - backgroundColor: '#fff', -}; - -const makeTabPane = key => ( - -
{`选项${key}内容`}
-
-); - -const makeMultiTabPane = count => { - const result = []; - for (let i = 0; i < count; i++) { - result.push(makeTabPane(i)); - } - return result; -}; - -class NormalTabs extends Component { - render() { - return ( -
- { - this.root = root; - }} - defaultActiveKey="8" - renderTabBar={() => ( - { - this.tabBar = tabBar; - }} - /> - )} - renderTabContent={() => } - > - {makeMultiTabPane(11)} - -
- ); - } -} -describe('rc-swipeable-tabs', () => { - it('should render Slider with correct DOM structure', () => { - const wrapper = render(); - expect(renderToJson(wrapper)).toMatchSnapshot(); - }); - it('create and nav should works', () => { - const wrapper = render(); - expect(wrapper.find('.rc-tabs').length).toBe(1); - expect(wrapper.find('.rc-tabs-tab').length).toBe(11); - }); - - it('default active should works', () => { - const wrapper = mount(); - expect(wrapper.find('.rc-tabs-tab').length).toBe(11); - expect(wrapper.instance().root.state.activeKey).toBe('8'); - expect( - wrapper - .find('.rc-tabs-tab') - .at(8) - .hasClass('rc-tabs-tab-active'), - ).toBe(true); - }); - - it('onChange and onTabClick should works', () => { - const handleChange = jest.fn(); - const handleTabClick = jest.fn(); - const wrapper = mount( - } - renderTabContent={() => } - onChange={handleChange} - > - {makeMultiTabPane(11)} - , - ); - const targetTab = wrapper.find('.rc-tabs-tab').at(6); - targetTab.simulate('click'); - expect(handleTabClick).toHaveBeenCalledWith('6', expect.anything()); - expect(handleChange).toHaveBeenCalledWith('6'); - }); -}); diff --git a/tsconfig.json b/tsconfig.json index aeeacaa4..6db17cfe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,29 +3,16 @@ "target": "esnext", "moduleResolution": "node", "baseUrl": "./", - "lib": [ - "dom", - "es2017" - ], + "lib": ["dom", "es2017"], "jsx": "react", "declaration": true, "skipLibCheck": true, "esModuleInterop": true, "paths": { - "@/*": [ - "src/*" - ], - "@@/*": [ - ".dumi/tmp/*" - ], - "rc-tabs": [ - "src/" - ] + "@/*": ["src/*"], + "@@/*": [".dumi/tmp/*"], + "rc-tabs": ["src/"] } }, - "include": [ - ".dumirc.ts", - "**/*.ts", - "**/*.tsx" - ] -} \ No newline at end of file + "include": [".dumirc.ts", "**/*.ts", "**/*.tsx", "tests/swipe.js"] +}