Skip to content

Commit

Permalink
feat: add RootComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
SevereCloud committed Aug 22, 2023
1 parent edcc8bb commit 643c310
Show file tree
Hide file tree
Showing 90 changed files with 525 additions and 607 deletions.
6 changes: 3 additions & 3 deletions packages/vkui/src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import { HasRootRef } from '../../types';
import { RootComponent } from '../RootComponent/RootComponent';
import { AccordionSummary } from './AccordionSummary';
import styles from './Accordion.module.css';

Expand All @@ -16,8 +16,8 @@ export type AccordionProps = React.DetailsHTMLAttributes<HTMLDetailsElement> &
* @since 5.3.0
* @see https://vkcom.github.io/VKUI/#/Accordion
*/
export const Accordion = ({ getRootRef, className, ...restProps }: AccordionProps) => (
<details className={classNames(styles['Accordion'], className)} ref={getRootRef} {...restProps} />
export const Accordion = (props: AccordionProps) => (
<RootComponent Component="details" baseClassName={styles['Accordion']} {...props} />
);

Accordion.Summary = AccordionSummary;
19 changes: 6 additions & 13 deletions packages/vkui/src/components/AspectRatio/AspectRatio.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import { CSSCustomProperties, HasRootRef } from '../../types';
import { CSSCustomProperties, HTMLAttributesWithRootRef } from '../../types';
import { RootComponent } from '../RootComponent/RootComponent';
import styles from './AspectRatio.module.css';

export interface AspectRatioProps
extends React.HTMLAttributes<HTMLDivElement>,
HasRootRef<HTMLDivElement> {
export interface AspectRatioProps extends HTMLAttributesWithRootRef<HTMLDivElement> {
className?: string;
/**
* По умолчанию, вложенный контент будет растягиваться и заполнять весь блок.
Expand All @@ -29,8 +28,6 @@ export function AspectRatio({
ratio,
children,
mode = 'stretch',
className,
getRootRef,
style: styleProp,
...props
}: AspectRatioProps): JSX.Element {
Expand All @@ -39,17 +36,13 @@ export function AspectRatio({
};

return (
<div
className={classNames(
<RootComponent
baseClassName={classNames(
styles.AspectRatio,
mode === 'stretch' && styles['AspectRatio--mode-stretch'],
className,
)}
style={{ ...styleProp, ...style }}
ref={getRootRef}
{...props}
>
{children}
</div>
/>
);
}
12 changes: 9 additions & 3 deletions packages/vkui/src/components/Badge/Badge.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import { HTMLAttributesWithRootRef } from '../../types';
import { RootComponent } from '../RootComponent/RootComponent';
import styles from './Badge.module.css';

const stylesMode = {
new: styles['Badge--mode-new'],
prominent: styles['Badge--mode-prominent'],
};

export interface BadgeProps extends React.HTMLAttributes<HTMLElement> {
export interface BadgeProps extends HTMLAttributesWithRootRef<HTMLSpanElement> {
mode: 'new' | 'prominent';
}

/**
* @see https://vkcom.github.io/VKUI/#/Badge
*/
export const Badge = ({ mode = 'new', className, ...restProps }: BadgeProps) => (
<span className={classNames(styles['Badge'], stylesMode[mode], className)} {...restProps} />
export const Badge = ({ mode = 'new', ...restProps }: BadgeProps) => (
<RootComponent
Component="span"
baseClassName={classNames(styles['Badge'], stylesMode[mode])}
{...restProps}
/>
);
16 changes: 7 additions & 9 deletions packages/vkui/src/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { Icon24Cancel, Icon24Chevron, Icon24Dismiss, Icon24DismissDark } from '@
import { classNames, hasReactNode } from '@vkontakte/vkjs';
import { usePlatform } from '../../hooks/usePlatform';
import { Platform } from '../../lib/platform';
import { HasRootRef } from '../../types';
import { HTMLAttributesWithRootRef } from '../../types';
import { IconButton } from '../IconButton/IconButton';
import { RootComponent } from '../RootComponent/RootComponent';
import { Tappable } from '../Tappable/Tappable';
import { Headline } from '../Typography/Headline/Headline';
import { Subhead } from '../Typography/Subhead/Subhead';
Expand All @@ -17,7 +18,7 @@ const stylesSize = {
m: styles['Banner--size-m'],
};

export interface BannerProps extends React.HTMLAttributes<HTMLDivElement>, HasRootRef<HTMLElement> {
export interface BannerProps extends HTMLAttributesWithRootRef<HTMLDivElement> {
/**
* Тип баннера.
*/
Expand Down Expand Up @@ -105,8 +106,6 @@ export const Banner = ({
actions,
onDismiss,
dismissLabel = 'Скрыть',
className,
getRootRef,
noPadding,
...restProps
}: BannerProps) => {
Expand Down Expand Up @@ -151,18 +150,17 @@ export const Banner = ({
);

return (
<section
<RootComponent
Component="section"
{...restProps}
className={classNames(
baseClassName={classNames(
styles['Banner'],
!noPadding && styles['Banner--withPadding'],
platform === Platform.IOS && styles['Banner--ios'],
mode === 'image' && styles['Banner--mode-image'],
stylesSize[size],
mode === 'image' && imageTheme === 'dark' && styles['Banner--inverted'],
className,
)}
ref={getRootRef}
>
{asideMode === 'expand' ? (
<Tappable
Expand Down Expand Up @@ -195,6 +193,6 @@ export const Banner = ({
)}
</div>
)}
</section>
</RootComponent>
);
};
11 changes: 5 additions & 6 deletions packages/vkui/src/components/BaseGallery/BaseGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useExternRef } from '../../hooks/useExternRef';
import { useGlobalEventListener } from '../../hooks/useGlobalEventListener';
import { useDOM } from '../../lib/dom';
import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
import { RootComponent } from '../RootComponent/RootComponent';
import { ScrollArrow } from '../ScrollArrow/ScrollArrow';
import { Touch, TouchEvent } from '../Touch/Touch';
import { calcMax, calcMin } from './helpers';
Expand Down Expand Up @@ -50,7 +51,6 @@ export const BaseGallery = ({
align = 'left',
showArrows,
getRef,
className,
arrowSize = 'l',
...restProps
}: BaseGalleryProps) => {
Expand Down Expand Up @@ -311,16 +311,15 @@ export const BaseGallery = ({
const isDraggable = isDraggableProp && !layoutState.current.isFullyVisible;

return (
<div
<RootComponent
{...restProps}
className={classNames(
baseClassName={classNames(
styles['BaseGallery'],
align === 'center' && styles['BaseGallery--align-center'],
slideWidth === 'custom' && styles['BaseGallery--custom-width'],
isDraggable && styles['BaseGallery--draggable'],
className,
)}
ref={rootRef}
getRootRef={rootRef}
>
<Touch
className={styles['BaseGallery__viewport']}
Expand Down Expand Up @@ -377,6 +376,6 @@ export const BaseGallery = ({
size={arrowSize}
/>
)}
</div>
</RootComponent>
);
};
5 changes: 2 additions & 3 deletions packages/vkui/src/components/BaseGallery/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { HasAlign, HasRef, HasRootRef } from '../../types';
import { HasAlign, HasRef, HTMLAttributesWithRootRef } from '../../types';
import { ScrollArrowProps } from '../ScrollArrow/ScrollArrow';
import { TouchEvent, TouchEventHandler } from '../Touch/Touch';

Expand All @@ -26,9 +26,8 @@ export interface LayoutState {
}

export interface BaseGalleryProps
extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'onDragStart' | 'onDragEnd'>,
extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'onChange' | 'onDragStart' | 'onDragEnd'>,
HasAlign,
HasRootRef<HTMLDivElement>,
HasRef<HTMLElement> {
slideWidth?: string | number;
slideIndex?: number;
Expand Down
20 changes: 6 additions & 14 deletions packages/vkui/src/components/ButtonGroup/ButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import type { AlignType, HasRootRef } from '../../types';
import type { AlignType, HTMLAttributesWithRootRef } from '../../types';
import { RootComponent } from '../RootComponent/RootComponent';
import styles from './ButtonGroup.module.css';

const stylesMode = {
Expand All @@ -20,9 +21,7 @@ const stylesAlign = {
right: styles['ButtonGroup--align-right'],
};

export interface ButtonGroupProps
extends React.HTMLAttributes<HTMLDivElement>,
HasRootRef<HTMLDivElement> {
export interface ButtonGroupProps extends HTMLAttributesWithRootRef<HTMLDivElement> {
/**
* Задает расположение элементов внутри группы, вертикальное или горизонтальное.
*/
Expand Down Expand Up @@ -51,26 +50,19 @@ export const ButtonGroup = ({
gap = 'm',
stretched = false,
align = 'left' /* NOTE: Чтобы блоки по-умолчанию не растягивались на всю ширину контейнера */,
getRootRef,
className,
children,
...restProps
}: ButtonGroupProps) => {
return (
<div
className={classNames(
className,
<RootComponent
baseClassName={classNames(
styles.ButtonGroup,
stylesMode[mode],
gap !== 'none' && stylesGap[gap],
stretched && styles['ButtonGroup--stretched'],
stylesAlign[align],
)}
role="group"
ref={getRootRef}
{...restProps}
>
{children}
</div>
/>
);
};
21 changes: 7 additions & 14 deletions packages/vkui/src/components/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { isFirstDay, isLastDay, navigateDate, setTimeEqual } from '../../lib/cal
import { isSameDay, isSameMonth } from '../../lib/date';
import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
import { warnOnce } from '../../lib/warnOnce';
import { HasRootRef } from '../../types';
import { HTMLAttributesWithRootRef } from '../../types';
import { CalendarDays, CalendarDaysProps } from '../CalendarDays/CalendarDays';
import { CalendarHeader, CalendarHeaderProps } from '../CalendarHeader/CalendarHeader';
import { CalendarTime, CalendarTimeProps } from '../CalendarTime/CalendarTime';
import { RootComponent } from '../RootComponent/RootComponent';
import styles from './Calendar.module.css';

export interface CalendarProps
extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>,
extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'onChange'>,
Pick<CalendarTimeProps, 'changeHoursAriaLabel' | 'changeMinutesAriaLabel'>,
Pick<
CalendarHeaderProps,
Expand All @@ -27,8 +28,7 @@ export interface CalendarProps
| 'prevMonthProps'
| 'nextMonthProps'
>,
Pick<CalendarDaysProps, 'dayProps' | 'listenDayChangesForUpdate'>,
HasRootRef<HTMLDivElement> {
Pick<CalendarDaysProps, 'dayProps' | 'listenDayChangesForUpdate'> {
value?: Date;
disablePast?: boolean;
disableFuture?: boolean;
Expand Down Expand Up @@ -68,7 +68,6 @@ export const Calendar = ({
enableTime = false,
doneButtonText,
weekStartsOn = 1,
getRootRef,
disablePickers,
changeHoursAriaLabel,
changeMinutesAriaLabel,
Expand All @@ -88,7 +87,6 @@ export const Calendar = ({
prevMonthProps,
nextMonthProps,
dayProps,
className,
listenDayChangesForUpdate,
...props
}: CalendarProps) => {
Expand Down Expand Up @@ -155,14 +153,9 @@ export const Calendar = ({
);

return (
<div
<RootComponent
{...props}
ref={getRootRef}
className={classNames(
styles['Calendar'],
size === 's' && styles['Calendar--size-s'],
className,
)}
baseClassName={classNames(styles['Calendar'], size === 's' && styles['Calendar--size-s'])}
>
<CalendarHeader
viewDate={externalViewDate || viewDate}
Expand Down Expand Up @@ -211,6 +204,6 @@ export const Calendar = ({
/>
</div>
)}
</div>
</RootComponent>
);
};
16 changes: 10 additions & 6 deletions packages/vkui/src/components/CalendarDays/CalendarDays.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import { useExternRef } from '../../hooks/useExternRef';
import { useTodayDate } from '../../hooks/useTodayDate';
import { getDaysNames, getWeeks } from '../../lib/calendar';
import { isSameDay, isSameMonth } from '../../lib/date';
import { HTMLAttributesWithRootRef } from '../../types';
import { CalendarDay, CalendarDayElementProps } from '../CalendarDay/CalendarDay';
import { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';
import { RootComponent } from '../RootComponent/RootComponent';
import { Footnote } from '../Typography/Footnote/Footnote';
import styles from './CalendarDays.module.css';

export interface CalendarDaysProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
export interface CalendarDaysProps
extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'onChange'> {
value?: Date | Array<Date | null>;
viewDate: Date;
weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6;
Expand Down Expand Up @@ -49,12 +53,12 @@ export const CalendarDays = ({
size,
showNeighboringMonth = false,
dayProps,
className,
listenDayChangesForUpdate = false,
getRootRef,
...props
}: CalendarDaysProps) => {
const { locale } = useConfigProvider();
const ref = React.useRef<HTMLDivElement>(null);
const ref = useExternRef(getRootRef);
const now = useTodayDate(listenDayChangesForUpdate);

const weeks = React.useMemo(() => getWeeks(viewDate, weekStartsOn), [weekStartsOn, viewDate]);
Expand All @@ -70,11 +74,11 @@ export const CalendarDays = ({

ref.current?.focus();
},
[onDayChange],
[onDayChange, ref],
);

return (
<div {...props} className={classNames(styles['CalendarDays'], className)} ref={ref}>
<RootComponent {...props} baseClassName={styles['CalendarDays']} getRootRef={ref}>
<div
className={classNames(
styles['CalendarDays__row'],
Expand Down Expand Up @@ -124,6 +128,6 @@ export const CalendarDays = ({
})}
</div>
))}
</div>
</RootComponent>
);
};
Loading

0 comments on commit 643c310

Please sign in to comment.