@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> </VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden> </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> </VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden> </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> </VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden> </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> </VisuallyHidden>\n {status}\n </Subhead>\n ) : (\n <span className={styles.status}>\n <VisuallyHidden> </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