diff --git a/packages/kaspersky-components/helpers/useIntersectionChildren.ts b/packages/kaspersky-components/helpers/useIntersectionChildren.ts index 2f30afd..0a6695d 100644 --- a/packages/kaspersky-components/helpers/useIntersectionChildren.ts +++ b/packages/kaspersky-components/helpers/useIntersectionChildren.ts @@ -1,19 +1,24 @@ import { RefObject, useMemo } from 'react' import { useResizeObserver } from './useResizeObserver' -/** Find position last inside element */ -export const useIntersectionChildren = (ref: RefObject, padding = 0): number | undefined => { +/** The hook calculates the intersection of the container and its children, returns the index of last fitting child + + @param ref External container ref + @param padding Padding to consider when intersecting + @param wrapperQuerySelector selector of internal container + @param renderCounter flag to trigger the recalculation + */ +export const useIntersectionChildren = (ref: RefObject, padding = 0, wrapperQuerySelector?: string, renderCounter?: number): number | undefined => { const { right: containerRight } = useResizeObserver(ref) ?? { right: 0 } return useMemo(() => { - const container = ref.current - if (container === null) return undefined + const container = wrapperQuerySelector ? ref.current?.querySelector(wrapperQuerySelector) : ref.current + if (container === null || container === undefined) return undefined const children = new Array(container.children.length) .fill(null) .map((_, i) => container.children[i]) - const res = children.findIndex((child) => child.getBoundingClientRect().right + padding > containerRight) return res === -1 ? undefined : Math.max(res - 1, 0) - }, [containerRight, ref]) + }, [containerRight, ref, padding, renderCounter]) } diff --git a/packages/kaspersky-components/src/indicator/index.ts b/packages/kaspersky-components/src/indicator/index.ts index e6c1cd5..43d64d9 100644 --- a/packages/kaspersky-components/src/indicator/index.ts +++ b/packages/kaspersky-components/src/indicator/index.ts @@ -1 +1,2 @@ export * from './Indicator' +export * from './types' diff --git a/packages/kaspersky-components/src/tabs/Tabs.stories.tsx b/packages/kaspersky-components/src/tabs/Tabs.stories.tsx index 79a42e7..4dd9745 100644 --- a/packages/kaspersky-components/src/tabs/Tabs.stories.tsx +++ b/packages/kaspersky-components/src/tabs/Tabs.stories.tsx @@ -1,17 +1,25 @@ -import React from 'react' +import { useLocalization } from '@helpers/localization/useLocalization' +import { badges } from '@sb/badges' +import { withMeta } from '@sb/components/Meta' +import { sbHideControls } from '@sb/helpers' +import { Button } from '@src/button' +import { IndicatorMode } from '@src/indicator' +import { IndicatorModes } from '@src/indicator/types' +import { Textbox } from '@src/input' +import { Space } from '@src/space' +import { H3 } from '@src/typography' import { Meta, StoryObj } from '@storybook/react' +import React from 'react' +import styled from 'styled-components' + +import { Placeholder } from '@kl/icons/16' + import MetaData from './__meta__/meta.json' +import { Tabs, GroupTabs } from './Tabs' import { TabsProps } from './types' -import { Tabs } from './Tabs' -import { badges } from '@sb/badges' -import { withMeta } from '@helpers/hocs/MetaComponent/withMeta' -import { sbHideControls } from '@helpers/storybookHelpers' -import { Placeholder } from '@kaspersky/icons/16' -import { Button, GroupTabs, H3, Space } from '..' -import styled from 'styled-components' const meta: Meta = { - title: 'Atoms/Tabs', + title: 'Hexa UI Components/Tabs', component: Tabs, argTypes: { ...sbHideControls(['onChange', 'onTabClick', 'style', 'destroyInactiveTabPane', 'theme', 'className', 'type']) @@ -30,7 +38,7 @@ const meta: Meta = { klId: 'tabs-kl-id' }, parameters: { - badges: [badges.reviewedByDesign], + badges: [badges.stable, badges.reviewedByDesign], docs: { page: withMeta(MetaData) }, @@ -57,62 +65,142 @@ export const Basic: Story = {} export const WithIconAndNumber: Story = { render: (args: TabsProps) => ( - } key="1"> + } />} + key="1" + > Content of Tab Pane 1 } />} + tab={} />} key="2" > Content of Tab Pane 2 } number={5} /> + } iconAfter={} /> } key="3" > Content of Tab Pane 3 - - ) -} - -export const WithIndicator: Story = { - render: (args: TabsProps) => ( - - } key="1"> - Content of Tab Pane 1 + } key="4"> + Content of Tab Pane 4 } - key="2" + tab={ + } number={5} /> + } + key="5" > - Content of Tab Pane 2 + Content of Tab Pane 5 } />} - key="3" + tab={ + } number={5} /> + } + key="6" > - Content of Tab Pane 3 + Content of Tab Pane 6 } - number={5} - /> + } iconAfter={} number={5} /> } - key="4" + key="7" > - Content of Tab Pane 4 + Content of Tab Pane 7 ) } +type StoryTabsProps = TabsProps & { indicatorMode: IndicatorMode } + +export const WithIndicator: StoryObj = { + render: (args: StoryTabsProps) => { + const { indicatorMode, ...props } = args + return ( + + } + key="1" + > + Content of Tab Pane 1 + + } + key="2" + > + Content of Tab Pane 2 + + } + />} + key="3" + > + Content of Tab Pane 3 + + } + /> + } + key="4" + > + Content of Tab Pane 4 + + } + number={5} + /> + } + key="5" + > + Content of Tab Pane 5 + + } + iconAfter={} + number={5} + /> + } + key="6" + > + Content of Tab Pane 6 + + + ) + }, + argTypes: { + indicatorMode: { + control: 'select', + options: IndicatorModes, + description: 'Indicator mode' + } + } +} + export const WithDisabled: Story = { render: (args: TabsProps) => ( @@ -148,24 +236,29 @@ export const WithDisabled: Story = { ) } +const generateTabs = (length = 15, tabText = 'Tab', contentText = 'Content of tab') => Array.from({ length: length }, (_, i) => i).map((i) => ({ + text: tabText, + disabled: i === 8, + content: contentText + ' ' + (i + 1) + } +)) + export const CollapsedHorizontalGroup: Story = { - render: (props: TabsProps) => ( - - {[ - ...Array.from({ length: 15 }, (_, i) => i) - ].map((i) => ( - } /> - } - key={i + 1} - disabled={i === 8} - > - Content of tab {i + 1} - - ))} - - ) + render: (props: TabsProps) => { + return ( + + {generateTabs(20, 'tabs.dropdown.more').map((el, i) => }/> + } + key={i + 1} + disabled={el.disabled} + > + {el.content} + + )} + ) + } } const RightButton =