From 6a9f9943147be8248734e128993d4192d7a96ae5 Mon Sep 17 00:00:00 2001 From: webnoi Date: Sat, 22 Jul 2023 21:15:56 +0300 Subject: [PATCH] v1.0.6 --- README.md | 9 ++-- package.json | 7 +-- packages/utils/src/useIsFocusVisible.ts | 1 + packages/web/src/RippleButton/Ripple.tsx | 18 +++---- .../web/src/RippleButton/RippleButton.tsx | 2 +- .../web/src/RippleButton/TouchRipple.test.tsx | 39 +++++++------- packages/web/src/RippleButton/TouchRipple.tsx | 20 ++++---- .../src/RippleButton/touchRippleClasses.ts | 16 +++--- packages/web/src/Tab/tabClasses.ts | 44 ++++++++-------- packages/web/src/Tabs/TabScrollButton.tsx | 3 +- packages/web/src/Tabs/Tabs.test.tsx | 18 ++++--- packages/web/src/Tabs/Tabs.tsx | 24 ++++----- packages/web/src/Tabs/tabsClasses.ts | 51 +++++++++---------- release.sh | 1 + 14 files changed, 128 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index e69150f..ecda6c7 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ # MUI Tabs -[![License MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](https://github.com/bilaleren/mui-tabs/blob/master/LICENCE) [![NPM](https://img.shields.io/npm/v/mui-tabs.svg)](https://www.npmjs.com/package/mui-tabs) -[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) -[![npm downloads](https://img.shields.io/npm/dt/mui-tabs.svg)](#installation) +![](https://badgen.net/npm/license/mui-tabs) +![](https://badgen.net/packagephobia/install/mui-tabs) +![](https://badgen.net/bundlephobia/min/mui-tabs) +![](https://badgen.net/bundlephobia/minzip/mui-tabs) +![](https://badgen.net/npm/dw/mui-tabs) +![](https://badgen.net/npm/dm/mui-tabs) This package was developed based on the [Material UI Tabs](https://mui.com/components/tabs/#main-content) component. [See example](https://bilaleren.github.io/mui-tabs). diff --git a/package.json b/package.json index 51f78e9..1f016a7 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { "name": "mui-tabs", - "version": "1.0.5", + "version": "1.0.6", "private": true, "description": "Material UI tabs for React and React Native projects.", "author": "Bilal Eren", "license": "MIT", - "repository": "https://github.com/bilaleren/mui-tabs.git", - "main": "index.js", + "main": "./index.js", + "module": "./esm/index.js", "homepage": "https://bilaleren.github.io/mui-tabs", + "repository": "https://github.com/bilaleren/mui-tabs.git", "engines": { "node": ">=10" }, diff --git a/packages/utils/src/useIsFocusVisible.ts b/packages/utils/src/useIsFocusVisible.ts index 1b5a82b..4163955 100644 --- a/packages/utils/src/useIsFocusVisible.ts +++ b/packages/utils/src/useIsFocusVisible.ts @@ -168,6 +168,7 @@ function useIsFocusVisible(): UseIsFocusVisibleResult { isFocusVisibleRef.current = true return true } + return false } diff --git a/packages/web/src/RippleButton/Ripple.tsx b/packages/web/src/RippleButton/Ripple.tsx index 9f34db4..a48f55f 100644 --- a/packages/web/src/RippleButton/Ripple.tsx +++ b/packages/web/src/RippleButton/Ripple.tsx @@ -33,9 +33,7 @@ const Ripple: React.FC = (props: RippleProps) => { className, classes.ripple, classes.rippleVisible, - { - [classes.ripplePulsate]: pulsate - } + pulsate && classes.ripplePulsate ) const rippleStyles = { @@ -45,10 +43,11 @@ const Ripple: React.FC = (props: RippleProps) => { left: -(rippleSize / 2) + rippleX } - const childClassName = clsx(classes.child, { - [classes.childLeaving]: leaving, - [classes.childPulsate]: pulsate - }) + const childClassName = clsx( + classes.child, + leaving && classes.childLeaving, + pulsate && classes.childPulsate + ) if (!inProp && !leaving) { setLeaving(true) @@ -58,11 +57,8 @@ const Ripple: React.FC = (props: RippleProps) => { if (!inProp && onExited != null) { // react-transition-group#onExited const timeoutId = setTimeout(onExited, timeout) - return () => { - clearTimeout(timeoutId) - } + return () => clearTimeout(timeoutId) } - return undefined }, [onExited, inProp, timeout]) return ( diff --git a/packages/web/src/RippleButton/RippleButton.tsx b/packages/web/src/RippleButton/RippleButton.tsx index db73d4e..a1fe14d 100644 --- a/packages/web/src/RippleButton/RippleButton.tsx +++ b/packages/web/src/RippleButton/RippleButton.tsx @@ -4,9 +4,9 @@ import TouchRipple, { TouchRippleRefAttributes } from './TouchRipple' import clsx from 'clsx' +import TabButton, { TabButtonProps } from '../TabButton' import useForkRef from '@mui-tabs/utils/src/useForkRef' import useEventCallback from '@mui-tabs/utils/src/useEventCallback' -import TabButton, { TabButtonProps } from '../TabButton' import useIsFocusVisible from '@mui-tabs/utils/src/useIsFocusVisible' export interface RippleButtonActionRefAttributes { diff --git a/packages/web/src/RippleButton/TouchRipple.test.tsx b/packages/web/src/RippleButton/TouchRipple.test.tsx index e7ff89d..9e1f0ff 100644 --- a/packages/web/src/RippleButton/TouchRipple.test.tsx +++ b/packages/web/src/RippleButton/TouchRipple.test.tsx @@ -14,24 +14,29 @@ const noop = () => {} describe('', () => { const { clock, render } = createRenderer() - function renderTouchRipple(other?: TouchRippleProps) { + function createTouchRippleRenderer(props?: TouchRippleProps) { const touchRippleRef = React.createRef() const { container, unmount } = render( ) return { instance: touchRippleRef.current, + unmount, + queryRipple() { + return container.querySelector('.ripple') + }, queryAllActiveRipples() { return container.querySelectorAll( '.ripple-visible .child:not(.child-leaving)' @@ -39,17 +44,15 @@ describe('', () => { }, queryAllStoppingRipples() { return container.querySelectorAll('.ripple-visible .child-leaving') - }, - queryRipple() { - return container.querySelector('.ripple') - }, - unmount + } } } describe('prop: center', () => { it('should compute the right ripple dimensions', () => { - const { instance, queryRipple } = renderTouchRipple({ center: true }) + const { instance, queryRipple } = createTouchRippleRenderer({ + center: true + }) act(() => { instance!.start( @@ -68,7 +71,7 @@ describe('', () => { it('should create individual ripples', () => { const { instance, queryAllActiveRipples, queryAllStoppingRipples } = - renderTouchRipple() + createTouchRippleRenderer() expect(queryAllActiveRipples()).to.have.lengthOf(0) expect(queryAllStoppingRipples()).to.have.lengthOf(0) @@ -119,7 +122,7 @@ describe('', () => { describe('creating unique ripples', () => { it('should create a ripple', () => { const { instance, queryAllActiveRipples, queryAllStoppingRipples } = - renderTouchRipple() + createTouchRippleRenderer() act(() => { instance!.start( @@ -138,7 +141,7 @@ describe('', () => { it('should ignore a mousedown event after a touchstart event', () => { const { instance, queryAllActiveRipples, queryAllStoppingRipples } = - renderTouchRipple() + createTouchRippleRenderer() act(() => { instance!.start({ type: 'touchstart' }, { callback: noop }) @@ -155,7 +158,7 @@ describe('', () => { queryAllActiveRipples, queryAllStoppingRipples, queryRipple - } = renderTouchRipple({ + } = createTouchRippleRenderer({ center: true }) const clientX = 1 @@ -180,7 +183,7 @@ describe('', () => { it('should delay the display of the ripples', () => { const { instance, queryAllActiveRipples, queryAllStoppingRipples } = - renderTouchRipple() + createTouchRippleRenderer() expect(queryAllActiveRipples()).to.have.lengthOf(0) expect(queryAllStoppingRipples()).to.have.lengthOf(0) @@ -212,7 +215,7 @@ describe('', () => { it('should trigger the ripple for short touch interactions', () => { const { instance, queryAllActiveRipples, queryAllStoppingRipples } = - renderTouchRipple() + createTouchRippleRenderer() expect(queryAllActiveRipples()).to.have.lengthOf(0) expect(queryAllStoppingRipples()).to.have.lengthOf(0) @@ -247,7 +250,7 @@ describe('', () => { it('should interrupt the ripple schedule', () => { const { instance, queryAllActiveRipples, queryAllStoppingRipples } = - renderTouchRipple() + createTouchRippleRenderer() expect(queryAllActiveRipples()).to.have.lengthOf(0) expect(queryAllStoppingRipples()).to.have.lengthOf(0) @@ -270,7 +273,7 @@ describe('', () => { }) it('should not leak on multi-touch', function () { - const { instance, unmount } = renderTouchRipple() + const { instance, unmount } = createTouchRippleRenderer() instance!.start({ type: 'touchstart', touches: [{}] }, { callback: noop }) instance!.start({ type: 'touchstart', touches: [{}] }, { callback: noop }) diff --git a/packages/web/src/RippleButton/TouchRipple.tsx b/packages/web/src/RippleButton/TouchRipple.tsx index 3f4ecbb..7eb3230 100644 --- a/packages/web/src/RippleButton/TouchRipple.tsx +++ b/packages/web/src/RippleButton/TouchRipple.tsx @@ -89,24 +89,24 @@ const TouchRipple = React.forwardRef< , - ClassArray + ClassValue > -export const useTabClasses = ( - ownerState: TabOwnerState -): UseTabClassesReturn => { +export function useTabClasses(ownerState: TabOwnerState): UseTabClassesReturn { const { icon, label, iconPosition, selected, disabled, fullWidth, classes } = ownerState - const positionSuffix = iconPosition ? capitalize(iconPosition) : undefined + const iconPositionKey = + icon && iconPosition + ? (`iconPosition${capitalize(iconPosition)}` as keyof TabClasses) + : undefined return { root: [ @@ -69,11 +70,10 @@ export const useTabClasses = ( ], iconWrapper: [ tabClasses.iconWrapper, - icon && - positionSuffix && [ - tabClasses[`iconPosition${positionSuffix}` as keyof TabClasses], - classes[`iconPosition${positionSuffix}` as keyof TabClasses] - ], + iconPositionKey && [ + tabClasses[iconPositionKey], + classes[iconPositionKey] + ], classes.iconWrapper ] } diff --git a/packages/web/src/Tabs/TabScrollButton.tsx b/packages/web/src/Tabs/TabScrollButton.tsx index 52b59dc..5c34e78 100644 --- a/packages/web/src/Tabs/TabScrollButton.tsx +++ b/packages/web/src/Tabs/TabScrollButton.tsx @@ -53,6 +53,7 @@ const TabScrollButton = React.forwardRef< } = props const vertical = orientation === 'vertical' + const IconComponent = direction === 'left' ? ChevronLeft : ChevronRight return ( - {direction === 'left' ? : } + ) }) diff --git a/packages/web/src/Tabs/Tabs.test.tsx b/packages/web/src/Tabs/Tabs.test.tsx index 45045ac..f17d2e2 100644 --- a/packages/web/src/Tabs/Tabs.test.tsx +++ b/packages/web/src/Tabs/Tabs.test.tsx @@ -1,13 +1,13 @@ import * as React from 'react' import Tab from '../Tab' -import { expect } from 'chai' import { spy } from 'sinon' +import { expect } from 'chai' import tabsClasses from './tabsClasses' +import tabClasses from '../Tab/tabClasses' import { act } from '@testing-library/react' -import { fireEvent } from '@testing-library/dom' import { createRenderer } from '../test/utils' +import { fireEvent } from '@testing-library/dom' import Tabs, { TabsActionRefAttributes } from './Tabs' -import tabClasses from '../Tab/tabClasses' function findScrollButton( container: HTMLElement, @@ -20,12 +20,16 @@ function findScrollButton( function hasLeftScrollButton(container: HTMLElement): boolean { const button = findScrollButton(container, 'left') - return !!button && !button.classList.contains('tabs-scroll-buttons-disabled') + return !!( + button && !button.classList.contains('tabs-scroll-buttons-disabled') + ) } function hasRightScrollButton(container: HTMLElement): boolean { const button = findScrollButton(container, 'right') - return !!button && !button.classList.contains('tabs-scroll-buttons-disabled') + return !!( + button && !button.classList.contains('tabs-scroll-buttons-disabled') + ) } describe('', () => { @@ -894,9 +898,7 @@ describe('', () => { forceUpdate() - let style: CSSStyleDeclaration - - style = container.querySelector( + let style = container.querySelector( `.${tabsClasses.indicator}` )!.style diff --git a/packages/web/src/Tabs/Tabs.tsx b/packages/web/src/Tabs/Tabs.tsx index 77611bf..3749866 100644 --- a/packages/web/src/Tabs/Tabs.tsx +++ b/packages/web/src/Tabs/Tabs.tsx @@ -5,8 +5,8 @@ import ScrollbarSize from './ScrollbarSize' import animate from '@mui-tabs/utils/src/animate' import debounce from '@mui-tabs/utils/src/debounce' import type { TabValue, ChangeHandler } from '../types' -import ownerWindow from '@mui-tabs/utils/src/ownerWindow' import TabButton, { TabButtonProps } from '../TabButton' +import ownerWindow from '@mui-tabs/utils/src/ownerWindow' import getDocumentDir from '@mui-tabs/utils/src/getDocumentDir' import isReactFragment from '@mui-tabs/utils/src/isReactFragment' import useEventCallback from '@mui-tabs/utils/src/useEventCallback' @@ -17,10 +17,6 @@ import { getNormalizedScrollLeft } from '@mui-tabs/utils/src/scrollLeft' -type Maybe = T | null - -const TabsScrollbarSize = ScrollbarSize - export interface TabsActionRefAttributes { updateIndicator(): void updateScrollButtons(): void @@ -200,8 +196,8 @@ const Tabs: TabsWithForwardRef = React.forwardRef( }) const valueToIndex = new Map() - const tabsRef = React.useRef>(null) - const tabListRef = React.useRef>(null) + const tabsRef = React.useRef(null) + const tabListRef = React.useRef(null) const isRtl = direction === 'rtl' const scrollable = variant === 'scrollable' @@ -253,7 +249,7 @@ const Tabs: TabsWithForwardRef = React.forwardRef( } } - let tabMeta: Maybe = null + let tabMeta: DOMRect | null = null if (tabsNode && value !== false && tabListRef.current) { const children = tabListRef.current.children @@ -420,13 +416,13 @@ const Tabs: TabsWithForwardRef = React.forwardRef( return totalSize } - const handleStartScrollClick = () => { + const handleStartScrollClick = useEventCallback(() => { moveTabsScroll(-1 * getScrollSize()) - } + }) - const handleEndScrollClick = () => { + const handleEndScrollClick = useEventCallback(() => { moveTabsScroll(getScrollSize()) - } + }) const handleScrollbarSizeChange = React.useCallback( (scrollbarWidth: number) => { @@ -445,7 +441,7 @@ const Tabs: TabsWithForwardRef = React.forwardRef( return } - let nextScrollStart: Maybe = null + let nextScrollStart: number | null = null if (tabMeta[start] < tabsMeta[start]) { // left side of button is out of view @@ -642,7 +638,7 @@ const Tabs: TabsWithForwardRef = React.forwardRef( )} {scrollable && ( - , - ClassArray + ClassValue > -export const useTabsClasses = ( +export function useTabsClasses( ownerState: TabsOwnerState -): UseTabsClassesReturn => { +): UseTabsClassesReturn { const { fixed, classes, @@ -110,15 +110,12 @@ export const useTabsClasses = ( ], classes.scrollButtons ], - hideScrollbar: hideScrollbar - ? [tabsClasses.hideScrollbar, classes.hideScrollbar] - : [], - scrollableX: scrollableX - ? [tabsClasses.scrollableX, classes.scrollableX] - : [], - scrollableY: scrollableY - ? [tabsClasses.scrollableY, classes.scrollableY] - : [] + hideScrollbar: hideScrollbar && [ + tabsClasses.hideScrollbar, + classes.hideScrollbar + ], + scrollableX: scrollableX && [tabsClasses.scrollableX, classes.scrollableX], + scrollableY: scrollableY && [tabsClasses.scrollableY, classes.scrollableY] } } diff --git a/release.sh b/release.sh index 4d474b3..997a713 100755 --- a/release.sh +++ b/release.sh @@ -5,6 +5,7 @@ PACKAGE_NAME="$(node -p 'require("./package.json").name')" PACKAGE_VERSION="$(node -p 'require("./package.json").version')" TARBALL_PATH="$DIST_PATH/$PACKAGE_NAME-v$PACKAGE_VERSION.tgz" +yarn build cd "$DIST_PATH" || exit yarn pack yarn publish "$TARBALL_PATH" --new-version "$PACKAGE_VERSION"