@vkontakte/vkui 7.7.0 → 7.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -138,7 +138,7 @@ const warn = warnOnce('TabsItem');
138
138
  "aria-selected": selected,
139
139
  tabIndex: tabIndex,
140
140
  baseClassName: classNames("vkuiTabsItem__host", mode && stylesMode[mode], selected && "vkuiTabsItem__selected", sizeY !== 'regular' && sizeYClassNames[sizeY], withGaps && "vkuiTabsItem__withGaps", layoutFillMode !== 'auto' && fillModeClassNames[layoutFillMode]),
141
- onClick: _onClick,
141
+ onClick: controller ? _onClick : onClick,
142
142
  id: id
143
143
  }, restProps), {
144
144
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/TabsItem/TabsItem.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { usePrevious } from '../../hooks/usePrevious';\nimport { useDOM } from '../../lib/dom';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { AnchorHTMLAttributesOnly, HTMLAttributesWithRootRef } from '../../types';\nimport { TabsControllerContext } from '../Tabs/TabsControllerContext';\nimport { TabsModeContext } from '../Tabs/TabsModeContext';\nimport { Tappable, type TappableOmitProps } from '../Tappable/Tappable';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { Subhead } from '../Typography/Subhead/Subhead';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './TabsItem.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n};\n\nconst stylesMode = {\n default: styles.modeDefault,\n accent: styles.modeAccent,\n secondary: styles.modeSecondary,\n};\n\nconst fillModeClassNames = {\n stretched: styles.stretched,\n shrinked: styles.shrinked,\n};\n\nexport interface TabsItemProps\n extends HTMLAttributesWithRootRef<HTMLElement>,\n AnchorHTMLAttributesOnly,\n Pick<\n TappableOmitProps,\n | 'Component'\n | 'activeMode'\n | 'hoverMode'\n | 'hovered'\n | 'activated'\n | 'hasActive'\n | 'hasHover'\n | 'focusVisibleMode'\n > {\n /**\n * Добавляет иконку слева.\n *\n * - Для `mode=\"default\"` используйте иконки размером 24.\n * - Для всех остальных `mode` используйте иконки размером 20.\n */\n before?: React.ReactNode;\n /**\n * Добавляет элемент слева от `after`.\n *\n * - `React.ReactElement` – либо [`Badge`](https://vkui.io/components/badge) с параметром `mode=\"prominent\"`.\n * Либо [`Counter`](https://vkui.io/components/counter) с параметрами `mode=\"prominent\" size=\"s\"`.\n * - `number` – для показа текстового блока с переданным числом.\n */\n status?: React.ReactElement | number;\n /**\n * Добавляет иконку справа.\n *\n * Например, `<Icon16Dropdown />`.\n */\n after?: React.ReactNode;\n /**\n * Флаг для отображения выбранного состояния.\n */\n selected?: boolean;\n /**\n * Блокировка взаимодействия с компонентом.\n */\n disabled?: boolean;\n}\n\nconst warn = warnOnce('TabsItem');\n\n/**\n * @see https://vkui.io/components/tabs#tabs-item\n */\nexport const TabsItem = ({\n before,\n children,\n status,\n after,\n selected: selectedProp = false,\n role = 'tab',\n tabIndex: tabIndexProp,\n getRootRef,\n hoverMode = styles.hover,\n activeMode = '',\n hasActive = false,\n focusVisibleMode = 'inside',\n id,\n onClick,\n ...restProps\n}: TabsItemProps): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n const { mode, withGaps, layoutFillMode, scrollBehaviorToSelectedTab, withScrollToSelectedTab } =\n React.useContext(TabsModeContext);\n const controller = React.useContext(TabsControllerContext);\n let statusComponent = null;\n\n const isTabFlow = role === 'tab';\n\n const selected = selectedProp || (!!id && controller?.selectedTab === id);\n\n if (hasReactNode(status)) {\n statusComponent =\n typeof status === 'number' ? (\n <Subhead\n Component=\"span\"\n className={classNames(styles.status, styles.statusCount)}\n weight=\"2\"\n >\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </span>\n );\n }\n\n if (process.env.NODE_ENV === 'development' && isTabFlow) {\n if (!restProps['aria-controls']) {\n warn(`Передайте в \"aria-controls\" id контролируемого блока`, 'warn');\n } else if (!id) {\n warn(\n `Передайте \"id\" компоненту для использования в \"aria-labelledby\" контролируемого блока`,\n 'warn',\n );\n }\n }\n\n let tabIndex = tabIndexProp;\n if (isTabFlow && tabIndex === undefined) {\n tabIndex = selected ? 0 : -1;\n }\n\n const rootRef = useExternRef(getRootRef);\n\n const prevSelected = usePrevious(selected);\n const isInitialRender = prevSelected === undefined;\n const shouldScrollToSelected =\n withScrollToSelectedTab && !isInitialRender && prevSelected !== selected && selected;\n\n const { document } = useDOM();\n React.useEffect(\n function scrollToSelectedItem() {\n if (!shouldScrollToSelected || !rootRef.current || !document) {\n return;\n }\n\n const tabDOMRect = rootRef.current.getBoundingClientRect();\n const isTabVerticallyOutsideOfViewport =\n tabDOMRect.top < 0 || tabDOMRect.bottom > document.documentElement.clientHeight;\n\n /* проверяем, возможен ли вертикальный скролл, а он возможен для scrollIntoView если\n * элемент вертикально вне зоны видимости */\n if (isTabVerticallyOutsideOfViewport) {\n return;\n }\n\n /* Не все браузеры поддерживают используемые нами опции. */\n try {\n rootRef.current.scrollIntoView({\n inline: scrollBehaviorToSelectedTab,\n block: 'nearest',\n behavior: 'smooth',\n });\n } catch {\n /* Вызывать scrollIntoView с булевым аргументом не следует, потому что это повлечёт\n * вертикальный скролл.\n **/\n }\n },\n [rootRef, document, shouldScrollToSelected, scrollBehaviorToSelectedTab],\n );\n\n const _onClick: React.MouseEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n onClick?.(e);\n if (id) {\n controller?.onChange(id);\n }\n },\n [id, onClick, controller],\n );\n\n return (\n <Tappable\n getRootRef={rootRef}\n hoverMode={hoverMode}\n activeMode={activeMode}\n hasActive={hasActive}\n focusVisibleMode={focusVisibleMode}\n role={role}\n aria-selected={selected}\n tabIndex={tabIndex}\n baseClassName={classNames(\n styles.host,\n mode && stylesMode[mode],\n selected && styles.selected,\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n withGaps && styles.withGaps,\n layoutFillMode !== 'auto' && fillModeClassNames[layoutFillMode],\n )}\n onClick={_onClick}\n id={id}\n {...restProps}\n >\n {before && <div className={styles.before}>{before}</div>}\n <Headline\n Component=\"span\"\n className={styles.label}\n level={mode === 'default' ? '1' : '2'}\n weight=\"2\"\n >\n {children}\n </Headline>\n {statusComponent}\n {after && <div className={styles.after}>{after}</div>}\n {mode === 'default' && (\n <div className={styles.underline} aria-hidden data-selected={selected} />\n )}\n </Tappable>\n );\n};\n"],"names":["React","classNames","hasReactNode","useAdaptivity","useExternRef","usePrevious","useDOM","warnOnce","TabsControllerContext","TabsModeContext","Tappable","Headline","Subhead","VisuallyHidden","sizeYClassNames","none","compact","stylesMode","default","accent","secondary","fillModeClassNames","stretched","shrinked","warn","TabsItem","before","children","status","after","selected","selectedProp","role","tabIndex","tabIndexProp","getRootRef","hoverMode","activeMode","hasActive","focusVisibleMode","id","onClick","restProps","sizeY","mode","withGaps","layoutFillMode","scrollBehaviorToSelectedTab","withScrollToSelectedTab","useContext","controller","statusComponent","isTabFlow","selectedTab","Component","className","weight","span","process","env","NODE_ENV","undefined","rootRef","prevSelected","isInitialRender","shouldScrollToSelected","document","useEffect","scrollToSelectedItem","current","tabDOMRect","getBoundingClientRect","isTabVerticallyOutsideOfViewport","top","bottom","documentElement","clientHeight","scrollIntoView","inline","block","behavior","_onClick","useCallback","e","onChange","aria-selected","baseClassName","div","level","aria-hidden","data-selected"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/TabsItem/TabsItem.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { usePrevious } from '../../hooks/usePrevious';\nimport { useDOM } from '../../lib/dom';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { AnchorHTMLAttributesOnly, HTMLAttributesWithRootRef } from '../../types';\nimport { TabsControllerContext } from '../Tabs/TabsControllerContext';\nimport { TabsModeContext } from '../Tabs/TabsModeContext';\nimport { Tappable, type TappableOmitProps } from '../Tappable/Tappable';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { Subhead } from '../Typography/Subhead/Subhead';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './TabsItem.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n};\n\nconst stylesMode = {\n default: styles.modeDefault,\n accent: styles.modeAccent,\n secondary: styles.modeSecondary,\n};\n\nconst fillModeClassNames = {\n stretched: styles.stretched,\n shrinked: styles.shrinked,\n};\n\nexport interface TabsItemProps\n extends HTMLAttributesWithRootRef<HTMLElement>,\n AnchorHTMLAttributesOnly,\n Pick<\n TappableOmitProps,\n | 'Component'\n | 'activeMode'\n | 'hoverMode'\n | 'hovered'\n | 'activated'\n | 'hasActive'\n | 'hasHover'\n | 'focusVisibleMode'\n > {\n /**\n * Добавляет иконку слева.\n *\n * - Для `mode=\"default\"` используйте иконки размером 24.\n * - Для всех остальных `mode` используйте иконки размером 20.\n */\n before?: React.ReactNode;\n /**\n * Добавляет элемент слева от `after`.\n *\n * - `React.ReactElement` – либо [`Badge`](https://vkui.io/components/badge) с параметром `mode=\"prominent\"`.\n * Либо [`Counter`](https://vkui.io/components/counter) с параметрами `mode=\"prominent\" size=\"s\"`.\n * - `number` – для показа текстового блока с переданным числом.\n */\n status?: React.ReactElement | number;\n /**\n * Добавляет иконку справа.\n *\n * Например, `<Icon16Dropdown />`.\n */\n after?: React.ReactNode;\n /**\n * Флаг для отображения выбранного состояния.\n */\n selected?: boolean;\n /**\n * Блокировка взаимодействия с компонентом.\n */\n disabled?: boolean;\n}\n\nconst warn = warnOnce('TabsItem');\n\n/**\n * @see https://vkui.io/components/tabs#tabs-item\n */\nexport const TabsItem = ({\n before,\n children,\n status,\n after,\n selected: selectedProp = false,\n role = 'tab',\n tabIndex: tabIndexProp,\n getRootRef,\n hoverMode = styles.hover,\n activeMode = '',\n hasActive = false,\n focusVisibleMode = 'inside',\n id,\n onClick,\n ...restProps\n}: TabsItemProps): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n const { mode, withGaps, layoutFillMode, scrollBehaviorToSelectedTab, withScrollToSelectedTab } =\n React.useContext(TabsModeContext);\n const controller = React.useContext(TabsControllerContext);\n let statusComponent = null;\n\n const isTabFlow = role === 'tab';\n\n const selected = selectedProp || (!!id && controller?.selectedTab === id);\n\n if (hasReactNode(status)) {\n statusComponent =\n typeof status === 'number' ? (\n <Subhead\n Component=\"span\"\n className={classNames(styles.status, styles.statusCount)}\n weight=\"2\"\n >\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </span>\n );\n }\n\n if (process.env.NODE_ENV === 'development' && isTabFlow) {\n if (!restProps['aria-controls']) {\n warn(`Передайте в \"aria-controls\" id контролируемого блока`, 'warn');\n } else if (!id) {\n warn(\n `Передайте \"id\" компоненту для использования в \"aria-labelledby\" контролируемого блока`,\n 'warn',\n );\n }\n }\n\n let tabIndex = tabIndexProp;\n if (isTabFlow && tabIndex === undefined) {\n tabIndex = selected ? 0 : -1;\n }\n\n const rootRef = useExternRef(getRootRef);\n\n const prevSelected = usePrevious(selected);\n const isInitialRender = prevSelected === undefined;\n const shouldScrollToSelected =\n withScrollToSelectedTab && !isInitialRender && prevSelected !== selected && selected;\n\n const { document } = useDOM();\n React.useEffect(\n function scrollToSelectedItem() {\n if (!shouldScrollToSelected || !rootRef.current || !document) {\n return;\n }\n\n const tabDOMRect = rootRef.current.getBoundingClientRect();\n const isTabVerticallyOutsideOfViewport =\n tabDOMRect.top < 0 || tabDOMRect.bottom > document.documentElement.clientHeight;\n\n /* проверяем, возможен ли вертикальный скролл, а он возможен для scrollIntoView если\n * элемент вертикально вне зоны видимости */\n if (isTabVerticallyOutsideOfViewport) {\n return;\n }\n\n /* Не все браузеры поддерживают используемые нами опции. */\n try {\n rootRef.current.scrollIntoView({\n inline: scrollBehaviorToSelectedTab,\n block: 'nearest',\n behavior: 'smooth',\n });\n } catch {\n /* Вызывать scrollIntoView с булевым аргументом не следует, потому что это повлечёт\n * вертикальный скролл.\n **/\n }\n },\n [rootRef, document, shouldScrollToSelected, scrollBehaviorToSelectedTab],\n );\n\n const _onClick: React.MouseEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n onClick?.(e);\n if (id) {\n controller?.onChange(id);\n }\n },\n [id, onClick, controller],\n );\n\n return (\n <Tappable\n getRootRef={rootRef}\n hoverMode={hoverMode}\n activeMode={activeMode}\n hasActive={hasActive}\n focusVisibleMode={focusVisibleMode}\n role={role}\n aria-selected={selected}\n tabIndex={tabIndex}\n baseClassName={classNames(\n styles.host,\n mode && stylesMode[mode],\n selected && styles.selected,\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n withGaps && styles.withGaps,\n layoutFillMode !== 'auto' && fillModeClassNames[layoutFillMode],\n )}\n onClick={controller ? _onClick : onClick}\n id={id}\n {...restProps}\n >\n {before && <div className={styles.before}>{before}</div>}\n <Headline\n Component=\"span\"\n className={styles.label}\n level={mode === 'default' ? '1' : '2'}\n weight=\"2\"\n >\n {children}\n </Headline>\n {statusComponent}\n {after && <div className={styles.after}>{after}</div>}\n {mode === 'default' && (\n <div className={styles.underline} aria-hidden data-selected={selected} />\n )}\n </Tappable>\n );\n};\n"],"names":["React","classNames","hasReactNode","useAdaptivity","useExternRef","usePrevious","useDOM","warnOnce","TabsControllerContext","TabsModeContext","Tappable","Headline","Subhead","VisuallyHidden","sizeYClassNames","none","compact","stylesMode","default","accent","secondary","fillModeClassNames","stretched","shrinked","warn","TabsItem","before","children","status","after","selected","selectedProp","role","tabIndex","tabIndexProp","getRootRef","hoverMode","activeMode","hasActive","focusVisibleMode","id","onClick","restProps","sizeY","mode","withGaps","layoutFillMode","scrollBehaviorToSelectedTab","withScrollToSelectedTab","useContext","controller","statusComponent","isTabFlow","selectedTab","Component","className","weight","span","process","env","NODE_ENV","undefined","rootRef","prevSelected","isInitialRender","shouldScrollToSelected","document","useEffect","scrollToSelectedItem","current","tabDOMRect","getBoundingClientRect","isTabVerticallyOutsideOfViewport","top","bottom","documentElement","clientHeight","scrollIntoView","inline","block","behavior","_onClick","useCallback","e","onChange","aria-selected","baseClassName","div","level","aria-hidden","data-selected"],"mappings":"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"}
@@ -120,7 +120,7 @@ const warn = warnOnce('TabsItem');
120
120
  "aria-selected": selected,
121
121
  tabIndex: tabIndex,
122
122
  baseClassName: classNames(styles.host, mode && stylesMode[mode], selected && styles.selected, sizeY !== 'regular' && sizeYClassNames[sizeY], withGaps && styles.withGaps, layoutFillMode !== 'auto' && fillModeClassNames[layoutFillMode]),
123
- onClick: _onClick,
123
+ onClick: controller ? _onClick : onClick,
124
124
  id: id,
125
125
  ...restProps,
126
126
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/TabsItem/TabsItem.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { usePrevious } from '../../hooks/usePrevious';\nimport { useDOM } from '../../lib/dom';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { AnchorHTMLAttributesOnly, HTMLAttributesWithRootRef } from '../../types';\nimport { TabsControllerContext } from '../Tabs/TabsControllerContext';\nimport { TabsModeContext } from '../Tabs/TabsModeContext';\nimport { Tappable, type TappableOmitProps } from '../Tappable/Tappable';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { Subhead } from '../Typography/Subhead/Subhead';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './TabsItem.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n};\n\nconst stylesMode = {\n default: styles.modeDefault,\n accent: styles.modeAccent,\n secondary: styles.modeSecondary,\n};\n\nconst fillModeClassNames = {\n stretched: styles.stretched,\n shrinked: styles.shrinked,\n};\n\nexport interface TabsItemProps\n extends HTMLAttributesWithRootRef<HTMLElement>,\n AnchorHTMLAttributesOnly,\n Pick<\n TappableOmitProps,\n | 'Component'\n | 'activeMode'\n | 'hoverMode'\n | 'hovered'\n | 'activated'\n | 'hasActive'\n | 'hasHover'\n | 'focusVisibleMode'\n > {\n /**\n * Добавляет иконку слева.\n *\n * - Для `mode=\"default\"` используйте иконки размером 24.\n * - Для всех остальных `mode` используйте иконки размером 20.\n */\n before?: React.ReactNode;\n /**\n * Добавляет элемент слева от `after`.\n *\n * - `React.ReactElement` – либо [`Badge`](https://vkui.io/components/badge) с параметром `mode=\"prominent\"`.\n * Либо [`Counter`](https://vkui.io/components/counter) с параметрами `mode=\"prominent\" size=\"s\"`.\n * - `number` – для показа текстового блока с переданным числом.\n */\n status?: React.ReactElement | number;\n /**\n * Добавляет иконку справа.\n *\n * Например, `<Icon16Dropdown />`.\n */\n after?: React.ReactNode;\n /**\n * Флаг для отображения выбранного состояния.\n */\n selected?: boolean;\n /**\n * Блокировка взаимодействия с компонентом.\n */\n disabled?: boolean;\n}\n\nconst warn = warnOnce('TabsItem');\n\n/**\n * @see https://vkui.io/components/tabs#tabs-item\n */\nexport const TabsItem = ({\n before,\n children,\n status,\n after,\n selected: selectedProp = false,\n role = 'tab',\n tabIndex: tabIndexProp,\n getRootRef,\n hoverMode = styles.hover,\n activeMode = '',\n hasActive = false,\n focusVisibleMode = 'inside',\n id,\n onClick,\n ...restProps\n}: TabsItemProps): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n const { mode, withGaps, layoutFillMode, scrollBehaviorToSelectedTab, withScrollToSelectedTab } =\n React.useContext(TabsModeContext);\n const controller = React.useContext(TabsControllerContext);\n let statusComponent = null;\n\n const isTabFlow = role === 'tab';\n\n const selected = selectedProp || (!!id && controller?.selectedTab === id);\n\n if (hasReactNode(status)) {\n statusComponent =\n typeof status === 'number' ? (\n <Subhead\n Component=\"span\"\n className={classNames(styles.status, styles.statusCount)}\n weight=\"2\"\n >\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </span>\n );\n }\n\n if (process.env.NODE_ENV === 'development' && isTabFlow) {\n if (!restProps['aria-controls']) {\n warn(`Передайте в \"aria-controls\" id контролируемого блока`, 'warn');\n } else if (!id) {\n warn(\n `Передайте \"id\" компоненту для использования в \"aria-labelledby\" контролируемого блока`,\n 'warn',\n );\n }\n }\n\n let tabIndex = tabIndexProp;\n if (isTabFlow && tabIndex === undefined) {\n tabIndex = selected ? 0 : -1;\n }\n\n const rootRef = useExternRef(getRootRef);\n\n const prevSelected = usePrevious(selected);\n const isInitialRender = prevSelected === undefined;\n const shouldScrollToSelected =\n withScrollToSelectedTab && !isInitialRender && prevSelected !== selected && selected;\n\n const { document } = useDOM();\n React.useEffect(\n function scrollToSelectedItem() {\n if (!shouldScrollToSelected || !rootRef.current || !document) {\n return;\n }\n\n const tabDOMRect = rootRef.current.getBoundingClientRect();\n const isTabVerticallyOutsideOfViewport =\n tabDOMRect.top < 0 || tabDOMRect.bottom > document.documentElement.clientHeight;\n\n /* проверяем, возможен ли вертикальный скролл, а он возможен для scrollIntoView если\n * элемент вертикально вне зоны видимости */\n if (isTabVerticallyOutsideOfViewport) {\n return;\n }\n\n /* Не все браузеры поддерживают используемые нами опции. */\n try {\n rootRef.current.scrollIntoView({\n inline: scrollBehaviorToSelectedTab,\n block: 'nearest',\n behavior: 'smooth',\n });\n } catch {\n /* Вызывать scrollIntoView с булевым аргументом не следует, потому что это повлечёт\n * вертикальный скролл.\n **/\n }\n },\n [rootRef, document, shouldScrollToSelected, scrollBehaviorToSelectedTab],\n );\n\n const _onClick: React.MouseEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n onClick?.(e);\n if (id) {\n controller?.onChange(id);\n }\n },\n [id, onClick, controller],\n );\n\n return (\n <Tappable\n getRootRef={rootRef}\n hoverMode={hoverMode}\n activeMode={activeMode}\n hasActive={hasActive}\n focusVisibleMode={focusVisibleMode}\n role={role}\n aria-selected={selected}\n tabIndex={tabIndex}\n baseClassName={classNames(\n styles.host,\n mode && stylesMode[mode],\n selected && styles.selected,\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n withGaps && styles.withGaps,\n layoutFillMode !== 'auto' && fillModeClassNames[layoutFillMode],\n )}\n onClick={_onClick}\n id={id}\n {...restProps}\n >\n {before && <div className={styles.before}>{before}</div>}\n <Headline\n Component=\"span\"\n className={styles.label}\n level={mode === 'default' ? '1' : '2'}\n weight=\"2\"\n >\n {children}\n </Headline>\n {statusComponent}\n {after && <div className={styles.after}>{after}</div>}\n {mode === 'default' && (\n <div className={styles.underline} aria-hidden data-selected={selected} />\n )}\n </Tappable>\n );\n};\n"],"names":["React","classNames","hasReactNode","useAdaptivity","useExternRef","usePrevious","useDOM","warnOnce","TabsControllerContext","TabsModeContext","Tappable","Headline","Subhead","VisuallyHidden","styles","sizeYClassNames","none","sizeYNone","compact","sizeYCompact","stylesMode","default","modeDefault","accent","modeAccent","secondary","modeSecondary","fillModeClassNames","stretched","shrinked","warn","TabsItem","before","children","status","after","selected","selectedProp","role","tabIndex","tabIndexProp","getRootRef","hoverMode","hover","activeMode","hasActive","focusVisibleMode","id","onClick","restProps","sizeY","mode","withGaps","layoutFillMode","scrollBehaviorToSelectedTab","withScrollToSelectedTab","useContext","controller","statusComponent","isTabFlow","selectedTab","Component","className","statusCount","weight","span","process","env","NODE_ENV","undefined","rootRef","prevSelected","isInitialRender","shouldScrollToSelected","document","useEffect","scrollToSelectedItem","current","tabDOMRect","getBoundingClientRect","isTabVerticallyOutsideOfViewport","top","bottom","documentElement","clientHeight","scrollIntoView","inline","block","behavior","_onClick","useCallback","e","onChange","aria-selected","baseClassName","host","div","label","level","underline","aria-hidden","data-selected"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/TabsItem/TabsItem.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { usePrevious } from '../../hooks/usePrevious';\nimport { useDOM } from '../../lib/dom';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { AnchorHTMLAttributesOnly, HTMLAttributesWithRootRef } from '../../types';\nimport { TabsControllerContext } from '../Tabs/TabsControllerContext';\nimport { TabsModeContext } from '../Tabs/TabsModeContext';\nimport { Tappable, type TappableOmitProps } from '../Tappable/Tappable';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { Subhead } from '../Typography/Subhead/Subhead';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport styles from './TabsItem.module.css';\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n compact: styles.sizeYCompact,\n};\n\nconst stylesMode = {\n default: styles.modeDefault,\n accent: styles.modeAccent,\n secondary: styles.modeSecondary,\n};\n\nconst fillModeClassNames = {\n stretched: styles.stretched,\n shrinked: styles.shrinked,\n};\n\nexport interface TabsItemProps\n extends HTMLAttributesWithRootRef<HTMLElement>,\n AnchorHTMLAttributesOnly,\n Pick<\n TappableOmitProps,\n | 'Component'\n | 'activeMode'\n | 'hoverMode'\n | 'hovered'\n | 'activated'\n | 'hasActive'\n | 'hasHover'\n | 'focusVisibleMode'\n > {\n /**\n * Добавляет иконку слева.\n *\n * - Для `mode=\"default\"` используйте иконки размером 24.\n * - Для всех остальных `mode` используйте иконки размером 20.\n */\n before?: React.ReactNode;\n /**\n * Добавляет элемент слева от `after`.\n *\n * - `React.ReactElement` – либо [`Badge`](https://vkui.io/components/badge) с параметром `mode=\"prominent\"`.\n * Либо [`Counter`](https://vkui.io/components/counter) с параметрами `mode=\"prominent\" size=\"s\"`.\n * - `number` – для показа текстового блока с переданным числом.\n */\n status?: React.ReactElement | number;\n /**\n * Добавляет иконку справа.\n *\n * Например, `<Icon16Dropdown />`.\n */\n after?: React.ReactNode;\n /**\n * Флаг для отображения выбранного состояния.\n */\n selected?: boolean;\n /**\n * Блокировка взаимодействия с компонентом.\n */\n disabled?: boolean;\n}\n\nconst warn = warnOnce('TabsItem');\n\n/**\n * @see https://vkui.io/components/tabs#tabs-item\n */\nexport const TabsItem = ({\n before,\n children,\n status,\n after,\n selected: selectedProp = false,\n role = 'tab',\n tabIndex: tabIndexProp,\n getRootRef,\n hoverMode = styles.hover,\n activeMode = '',\n hasActive = false,\n focusVisibleMode = 'inside',\n id,\n onClick,\n ...restProps\n}: TabsItemProps): React.ReactNode => {\n const { sizeY = 'none' } = useAdaptivity();\n const { mode, withGaps, layoutFillMode, scrollBehaviorToSelectedTab, withScrollToSelectedTab } =\n React.useContext(TabsModeContext);\n const controller = React.useContext(TabsControllerContext);\n let statusComponent = null;\n\n const isTabFlow = role === 'tab';\n\n const selected = selectedProp || (!!id && controller?.selectedTab === id);\n\n if (hasReactNode(status)) {\n statusComponent =\n typeof status === 'number' ? (\n <Subhead\n Component=\"span\"\n className={classNames(styles.status, styles.statusCount)}\n weight=\"2\"\n >\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden>&nbsp;</VisuallyHidden>\n {status}\n </span>\n );\n }\n\n if (process.env.NODE_ENV === 'development' && isTabFlow) {\n if (!restProps['aria-controls']) {\n warn(`Передайте в \"aria-controls\" id контролируемого блока`, 'warn');\n } else if (!id) {\n warn(\n `Передайте \"id\" компоненту для использования в \"aria-labelledby\" контролируемого блока`,\n 'warn',\n );\n }\n }\n\n let tabIndex = tabIndexProp;\n if (isTabFlow && tabIndex === undefined) {\n tabIndex = selected ? 0 : -1;\n }\n\n const rootRef = useExternRef(getRootRef);\n\n const prevSelected = usePrevious(selected);\n const isInitialRender = prevSelected === undefined;\n const shouldScrollToSelected =\n withScrollToSelectedTab && !isInitialRender && prevSelected !== selected && selected;\n\n const { document } = useDOM();\n React.useEffect(\n function scrollToSelectedItem() {\n if (!shouldScrollToSelected || !rootRef.current || !document) {\n return;\n }\n\n const tabDOMRect = rootRef.current.getBoundingClientRect();\n const isTabVerticallyOutsideOfViewport =\n tabDOMRect.top < 0 || tabDOMRect.bottom > document.documentElement.clientHeight;\n\n /* проверяем, возможен ли вертикальный скролл, а он возможен для scrollIntoView если\n * элемент вертикально вне зоны видимости */\n if (isTabVerticallyOutsideOfViewport) {\n return;\n }\n\n /* Не все браузеры поддерживают используемые нами опции. */\n try {\n rootRef.current.scrollIntoView({\n inline: scrollBehaviorToSelectedTab,\n block: 'nearest',\n behavior: 'smooth',\n });\n } catch {\n /* Вызывать scrollIntoView с булевым аргументом не следует, потому что это повлечёт\n * вертикальный скролл.\n **/\n }\n },\n [rootRef, document, shouldScrollToSelected, scrollBehaviorToSelectedTab],\n );\n\n const _onClick: React.MouseEventHandler<HTMLElement> = React.useCallback(\n (e) => {\n onClick?.(e);\n if (id) {\n controller?.onChange(id);\n }\n },\n [id, onClick, controller],\n );\n\n return (\n <Tappable\n getRootRef={rootRef}\n hoverMode={hoverMode}\n activeMode={activeMode}\n hasActive={hasActive}\n focusVisibleMode={focusVisibleMode}\n role={role}\n aria-selected={selected}\n tabIndex={tabIndex}\n baseClassName={classNames(\n styles.host,\n mode && stylesMode[mode],\n selected && styles.selected,\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n withGaps && styles.withGaps,\n layoutFillMode !== 'auto' && fillModeClassNames[layoutFillMode],\n )}\n onClick={controller ? _onClick : onClick}\n id={id}\n {...restProps}\n >\n {before && <div className={styles.before}>{before}</div>}\n <Headline\n Component=\"span\"\n className={styles.label}\n level={mode === 'default' ? '1' : '2'}\n weight=\"2\"\n >\n {children}\n </Headline>\n {statusComponent}\n {after && <div className={styles.after}>{after}</div>}\n {mode === 'default' && (\n <div className={styles.underline} aria-hidden data-selected={selected} />\n )}\n </Tappable>\n );\n};\n"],"names":["React","classNames","hasReactNode","useAdaptivity","useExternRef","usePrevious","useDOM","warnOnce","TabsControllerContext","TabsModeContext","Tappable","Headline","Subhead","VisuallyHidden","styles","sizeYClassNames","none","sizeYNone","compact","sizeYCompact","stylesMode","default","modeDefault","accent","modeAccent","secondary","modeSecondary","fillModeClassNames","stretched","shrinked","warn","TabsItem","before","children","status","after","selected","selectedProp","role","tabIndex","tabIndexProp","getRootRef","hoverMode","hover","activeMode","hasActive","focusVisibleMode","id","onClick","restProps","sizeY","mode","withGaps","layoutFillMode","scrollBehaviorToSelectedTab","withScrollToSelectedTab","useContext","controller","statusComponent","isTabFlow","selectedTab","Component","className","statusCount","weight","span","process","env","NODE_ENV","undefined","rootRef","prevSelected","isInitialRender","shouldScrollToSelected","document","useEffect","scrollToSelectedItem","current","tabDOMRect","getBoundingClientRect","isTabVerticallyOutsideOfViewport","top","bottom","documentElement","clientHeight","scrollIntoView","inline","block","behavior","_onClick","useCallback","e","onChange","aria-selected","baseClassName","host","div","label","level","underline","aria-hidden","data-selected"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "version": "7.7.0",
3
+ "version": "7.7.1",
4
4
  "name": "@vkontakte/vkui",
5
5
  "description": "VKUI library",
6
6
  "module": "./dist/index.js",
@@ -212,7 +212,7 @@ export const TabsItem = ({
212
212
  withGaps && styles.withGaps,
213
213
  layoutFillMode !== 'auto' && fillModeClassNames[layoutFillMode],
214
214
  )}
215
- onClick={_onClick}
215
+ onClick={controller ? _onClick : onClick}
216
216
  id={id}
217
217
  {...restProps}
218
218
  >