Skip to content

Commit

Permalink
feat(Header): add props before, beforeTitle, afterTitle, beforeSubtit…
Browse files Browse the repository at this point in the history
…le, afterSubtitle (#7202)

- Добавил пропс `before` для отображения иконки слева от контента
- Добавил пропс `beforeTitle` для отображения иконки слева от заголовка
- Добавил пропс `afterTitle` для отображения иконки справа от заголовка
- Добавил пропс `beforeSubtitle` для отображения иконки слева от подзаголовка
- Добавил пропс `afterSubtitle` для отображения иконки справа от подзаголовка
- Добавил новые состояния в скриншотные тесты
- Добавил примеры использования в документацию
- Добавил `story` в `storybook` с новыми фичами
  • Loading branch information
EldarMuhamethanov authored Aug 27, 2024
1 parent a1dd8c8 commit d491080
Show file tree
Hide file tree
Showing 15 changed files with 249 additions and 34 deletions.
47 changes: 47 additions & 0 deletions packages/vkui/src/components/Header/Header.e2e-playground.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import {
Icon12Fire,
Icon12Tag,
Icon16LockOutline,
Icon16UnlockOutline,
Icon28UserCircleFillBlue,
} from '@vkontakte/icons';
import { ComponentPlayground, type ComponentPlaygroundProps } from '@vkui-e2e/playground-helpers';
import { Counter } from '../Counter/Counter';
import { Link } from '../Link/Link';
Expand Down Expand Up @@ -49,6 +56,46 @@ export const HeaderPlayground = (props: ComponentPlaygroundProps) => {
mode: ['primary'],
size: ['regular', 'large'],
},
{
mode: ['primary'],
children: ['Кто может оставлять записи на моей странице'],
before: [<Icon28UserCircleFillBlue key="user" />],
},
{
mode: ['primary'],
children: ['Кто может оставлять записи на моей странице'],
beforeTitle: [<Icon16LockOutline key="beforeTitle" />],
},
{
mode: ['primary'],
children: ['Кто может оставлять записи на моей странице'],
afterTitle: [<Icon16UnlockOutline key="afterTitle" />],
multiline: [undefined, true],
},
{
mode: ['primary'],
children: ['Кто может оставлять записи на моей странице'],
subtitle: ['SOHN — Conrad'],
beforeSubtitle: [<Icon12Tag key="beforeSubtitle" />],
},
{
mode: ['primary'],
children: ['Кто может оставлять записи на моей странице'],
subtitle: ['SOHN — Conrad'],
afterSubtitle: [<Icon12Fire key="afterSubtitle" />],
multiline: [undefined, true],
},
{
mode: ['primary', 'secondary', 'tertiary'],
children: ['Кто может оставлять записи на моей странице'],
before: [<Icon28UserCircleFillBlue key="user" />],
beforeTitle: [<Icon16LockOutline key="beforeTitle" />],
afterTitle: [<Icon16UnlockOutline key="afterTitle" />],
beforeSubtitle: [<Icon12Tag key="beforeSubtitle" />],
afterSubtitle: [<Icon12Fire key="afterSubtitle" />],
subtitle: ['SOHN — Conrad'],
multiline: [undefined, true],
},
]}
>
{({ children, ...restProps }: HeaderProps) => (
Expand Down
51 changes: 46 additions & 5 deletions packages/vkui/src/components/Header/Header.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,46 @@
font-family: var(--vkui--font_family_base);
}

.Header__before,
.Header__subtitleBefore,
.Header__subtitleAfter,
.Header__content__before,
.Header__content__after {
display: flex;
flex-shrink: 0;
}

.Header__before {
align-self: center;
margin-inline-end: var(--vkui--spacing_size_m);
margin-block-start: var(--vkui--spacing_size_3xs);
}

.Header__before--withSubtitle {
margin-block-start: var(--vkui--spacing_size_s);
}

.Header__subtitleWrapper {
display: flex;
align-items: center;
}

.Header__subtitleBefore {
margin-inline-end: var(--vkui--spacing_size_xs);
}

.Header__subtitleAfter {
margin-inline-start: var(--vkui--spacing_size_xs);
}

.Header__content__before {
margin-inline-end: var(--vkui--spacing_size_xs);
}

.Header__content__after {
margin-inline-start: var(--vkui--spacing_size_xs);
}

.Header__main {
flex: 1 0 0;
min-inline-size: 0;
Expand All @@ -27,6 +67,7 @@
.Header__content--multiline {
white-space: initial;
word-break: break-word;
flex-grow: 1;
}

.Header__subtitle {
Expand All @@ -41,7 +82,7 @@

.Header__indicator {
color: var(--vkui--color_text_secondary);
margin-inline-start: 6px;
margin-inline-start: var(--vkui--spacing_size_xs);
flex-shrink: 0;
}

Expand Down Expand Up @@ -104,12 +145,12 @@
margin-block-end: 9px;
}

.Header__subtitle {
.Header__subtitleWrapper {
margin-block-end: 7px;
}

/* Компенсируем 1 пиксель из-за паддинга в .Header--mode-primary */
.Header--mode-primary .Header__subtitle {
.Header--mode-primary .Header__subtitleWrapper {
margin-block-end: 6px;
}

Expand Down Expand Up @@ -147,7 +188,7 @@
:global(.vkuiInternalGroup--mode-card)
> :global(.vkuiInternalTappable):first-child
> .Header:not(.Header--mode-tertiary) {
margin-block-start: -4px;
margin-block-start: calc(-1 * var(--vkui--spacing_size_xs));
}

@media (--sizeX-regular) {
Expand All @@ -157,7 +198,7 @@
:global(.vkuiInternalGroup--sizeX-none.vkuiInternalGroup--mode-none)
> :global(.vkuiInternalTappable):first-child
> .Header:not(.Header--mode-tertiary) {
margin-block-start: -4px;
margin-block-start: calc(-1 * var(--vkui--spacing_size_xs));
}
}

Expand Down
34 changes: 34 additions & 0 deletions packages/vkui/src/components/Header/Header.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ const story: Meta<HeaderProps> = {
component: Header,
parameters: { ...CanvasFullLayout, ...DisableCartesianParam },
argTypes: {
before: createFieldWithPresets({
iconSizes: ['28'],
requiredIcons: ['Icon28UserCircleFillBlue'],
}),
beforeTitle: createFieldWithPresets({
iconSizes: ['16'],
requiredIcons: ['Icon16LockOutline'],
}),
afterTitle: createFieldWithPresets({
iconSizes: ['16'],
requiredIcons: ['Icon16UnlockOutline'],
}),
beforeSubtitle: createFieldWithPresets({
iconSizes: ['12'],
requiredIcons: ['Icon12Tag'],
}),
afterSubtitle: createFieldWithPresets({
iconSizes: ['12'],
requiredIcons: ['Icon12Fire'],
}),
aside: createFieldWithPresets({
iconSizes: [],
additionalPresets: {
Expand Down Expand Up @@ -83,3 +103,17 @@ export const WithCounter: Story = {
withVKUILayout,
],
};

export const WithAllFeatures: Story = {
...Playground,
args: {
...Playground.args,
before: 'Icon28UserCircleFillBlue',
beforeTitle: 'Icon16LockOutline',
afterTitle: 'Icon16UnlockOutline',
beforeSubtitle: 'Icon12Tag',
afterSubtitle: 'Icon12Fire',
subtitle: 'SOHN — Conrad',
aside: <Link>Показать все</Link>,
},
};
62 changes: 53 additions & 9 deletions packages/vkui/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@ export interface HeaderProps extends HTMLAttributesWithRootRef<HTMLElement>, Has
*/
indicator?: React.ReactNode;
multiline?: boolean;
/**
* Иконка слева (рекомендуется использовать размер 28px)
*/
before?: React.ReactNode;
/**
* Иконка слева от title (рекомендуется использовать размер 16px)
*/
beforeTitle?: React.ReactNode;
/**
* Иконка справа от title (рекомендуется использовать размер 16px)
*/
afterTitle?: React.ReactNode;
/**
* Иконка слева от subtitle (рекомендуется использовать размер 12px)
*/
beforeSubtitle?: React.ReactNode;
/**
* Иконка справа от subtitle (рекомендуется использовать размер 12px)
*/
afterSubtitle?: React.ReactNode;
}

type HeaderContentProps = Pick<HeaderProps, 'children' | 'mode' | 'size' | 'className'> &
Expand Down Expand Up @@ -83,6 +103,11 @@ export const Header = ({
indicator,
aside,
multiline,
before,
beforeTitle,
afterTitle,
beforeSubtitle,
afterSubtitle,
...restProps
}: HeaderProps): React.ReactNode => {
return (
Expand All @@ -96,13 +121,24 @@ export const Header = ({
hasReactNode(subtitle) && styles['Header--with-subtitle'],
)}
>
{before && (
<div
className={classNames(
styles['Header__before'],
subtitle && styles['Header__before--withSubtitle'],
)}
>
{before}
</div>
)}
<div className={styles['Header__main']}>
<HeaderContent
className={styles['Header__content']}
Component={Component}
mode={mode}
size={size}
>
{beforeTitle && <div className={styles['Header__content__before']}>{beforeTitle}</div>}
<span
className={classNames(
styles['Header__content-in'],
Expand All @@ -111,23 +147,31 @@ export const Header = ({
>
{children}
</span>
{afterTitle && <div className={styles['Header__content__after']}>{afterTitle}</div>}
{hasReactNode(indicator) && (
<Footnote className={styles['Header__indicator']} weight="2">
{indicator}
</Footnote>
)}
</HeaderContent>

{hasReactNode(subtitle) && (
<Subhead
className={classNames(
styles['Header__subtitle'],
multiline && styles['Header__content--multiline'],
<div className={styles['Header__subtitleWrapper']}>
{beforeSubtitle && (
<div className={styles['Header__subtitleBefore']}>{beforeSubtitle}</div>
)}
Component={subtitleComponent}
>
{subtitle}
</Subhead>
<Subhead
className={classNames(
styles['Header__subtitle'],
multiline && styles['Header__content--multiline'],
)}
Component={subtitleComponent}
>
{subtitle}
</Subhead>
{afterSubtitle && (
<div className={styles['Header__subtitleAfter']}>{afterSubtitle}</div>
)}
</div>
)}
</div>

Expand Down
49 changes: 49 additions & 0 deletions packages/vkui/src/components/Header/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,55 @@ const Example = () => {
Большой заголовок
</Header>
</Group>
<Group>
<Header
mode="primary"
before={<Icon28UserCircleFillBlue />}
beforeTitle={<Icon16LockOutline />}
afterTitle={<Icon16UnlockOutline />}
beforeSubtitle={<Icon12Tag />}
afterSubtitle={<Icon12Fire />}
subtitle="SOHN — Conrad"
subtitleComponent="h3"
indicator={
<Counter size="s" mode="prominent">
3
</Counter>
}
aside={
<Link>
Показать все
{platform === 'vkcom' && <Icon12ChevronOutline />}
</Link>
}
>
Плейлисты
</Header>
<Header
mode="primary"
before={<Icon28UserCircleFillBlue />}
beforeTitle={<Icon16LockOutline />}
afterTitle={<Icon16UnlockOutline />}
beforeSubtitle={<Icon12Tag />}
afterSubtitle={<Icon12Fire />}
subtitle="SOHN — Conrad"
subtitleComponent="h3"
multiline
indicator={
<Counter size="s" mode="prominent">
3
</Counter>
}
aside={
<Link>
Показать все
{platform === 'vkcom' && <Icon12ChevronOutline />}
</Link>
}
>
Плейлисты
</Header>
</Group>
</Panel>
</View>
);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit d491080

Please sign in to comment.