Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(DirectionProvider): add direction to ConfigProvider #8236

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
00bd349
feat(DirectionProvider): add direction to ConfigProvider and refactor…
EldarMuhamethanov Jan 16, 2025
be81fec
Merge branch 'master' into e.muhamethanov/rtl/direction-provider
EldarMuhamethanov Feb 3, 2025
c388653
fix: fix playground with direction
EldarMuhamethanov Feb 3, 2025
7d136f1
Merge branch 'master' into e.muhamethanov/rtl/direction-provider
EldarMuhamethanov Feb 4, 2025
f6e8919
test: fix tests with rtl
EldarMuhamethanov Feb 4, 2025
a869e69
feat(DirectionProvider): add story
EldarMuhamethanov Feb 4, 2025
459b6e8
doc(DirectionProvider): add documentation
EldarMuhamethanov Feb 4, 2025
568dd60
fix(Calendar,CalendarRange): remove context
EldarMuhamethanov Feb 4, 2025
31bfedc
fix: run prettier
EldarMuhamethanov Feb 4, 2025
9d84b68
test: update screenshot
EldarMuhamethanov Feb 4, 2025
c46a80a
Merge branch 'master' into e.muhamethanov/rtl/direction-provider
EldarMuhamethanov Feb 5, 2025
3264b3e
Merge branch 'master' into e.muhamethanov/rtl/direction-provider
EldarMuhamethanov Feb 11, 2025
b437947
doc(ConfigProvider): add info about direction in props
EldarMuhamethanov Feb 11, 2025
b5db80c
doc: add @since to doc
EldarMuhamethanov Feb 11, 2025
0bb67a6
Merge branch 'master' into e.muhamethanov/rtl/direction-provider
EldarMuhamethanov Feb 12, 2025
855b4cf
Merge remote-tracking branch 'origin/e.muhamethanov/rtl/direction-pro…
EldarMuhamethanov Feb 12, 2025
dc17935
fix(Gallery): replace useDirection to useConfigDirection
EldarMuhamethanov Feb 12, 2025
4919a81
fix: improve auto detect direction
EldarMuhamethanov Feb 12, 2025
885f241
fix: improve auto detect direction
EldarMuhamethanov Feb 12, 2025
0f9ce0d
fix(Gallery): fix screenshot
EldarMuhamethanov Feb 12, 2025
610cc81
feat(SSR): add prop direction
EldarMuhamethanov Feb 12, 2025
37a4548
Merge branch 'master' into e.muhamethanov/rtl/direction-provider
EldarMuhamethanov Feb 13, 2025
7ab313f
Merge branch 'master' into e.muhamethanov/rtl/direction-provider
EldarMuhamethanov Feb 14, 2025
550b194
fix: fix autodetect direction
EldarMuhamethanov Feb 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import { useDirection } from '../../../hooks/useDirection';
import { useExternRef } from '../../../hooks/useExternRef';
import { useConfigDirection } from '../../../hooks/useConfigDirection';
import {
getBadgeIconSizeByImageBaseSize,
ImageBase,
Expand All @@ -26,12 +25,10 @@ export interface AvatarBadgeWithPresetProps
export const AvatarBadgeWithPreset: React.FC<AvatarBadgeWithPresetProps> = ({
preset = 'online',
className,
getRootRef,
...restProps
}: AvatarBadgeWithPresetProps) => {
const [directionRef, textDirection = 'ltr'] = useDirection<HTMLDivElement>();
const isRtl = textDirection === 'rtl';
const rootRef = useExternRef(getRootRef, directionRef);
const direction = useConfigDirection();
const isRtl = direction === 'rtl';
const { size } = React.useContext(ImageBaseContext);
const badgeSize = getBadgeIconSizeByImageBaseSize(size);
const isOnlinePreset = preset === 'online';
Expand All @@ -42,7 +39,6 @@ export const AvatarBadgeWithPreset: React.FC<AvatarBadgeWithPresetProps> = ({
<ImageBase.Badge
background="stroke"
className={classNames(styles.host, isRtl && styles.rtl, presetClassName, className)}
getRootRef={rootRef}
{...restProps}
>
<Icon width={badgeSize} height={badgeSize} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Calendar, type CalendarProps } from './Calendar';

export const CalendarPlayground = (props: ComponentPlaygroundProps) => {
return (
<ComponentPlayground
<ComponentPlayground<CalendarProps>
{...props}
propSets={[
{
Expand Down Expand Up @@ -65,7 +65,7 @@ export const CalendarPlayground = (props: ComponentPlaygroundProps) => {
},
{
value: [new Date('1970-05-05')],
dir: ['rtl'],
$direction: 'rtl',
},
]}
>
Expand Down
153 changes: 68 additions & 85 deletions packages/vkui/src/components/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@
import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import { isSameDay, isSameMonth } from 'date-fns';
import {
CalendarDirectionContext,
type CalendarDirectionContextProps,
} from '../../context/CalendarDirectionContext';
import { useCalendar } from '../../hooks/useCalendar';
import { useDirection } from '../../hooks/useDirection';
import { useExternRef } from '../../hooks/useExternRef';
import { clamp, isFirstDay, isLastDay, navigateDate, setTimeEqual } from '../../lib/calendar';
import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
import { warnOnce } from '../../lib/warnOnce';
Expand Down Expand Up @@ -174,8 +168,6 @@ export const Calendar = ({
minDateTime,
maxDateTime,
});
const [directionRef, textDirection = 'ltr'] = useDirection();
const rootRef = useExternRef(directionRef, getRootRef);

useIsomorphicLayoutEffect(() => {
if (value) {
Expand Down Expand Up @@ -223,83 +215,74 @@ export const Calendar = ({
[value],
);

const directionContextValue = React.useMemo<CalendarDirectionContextProps>(
() => ({
direction: textDirection,
}),
[textDirection],
);

return (
<CalendarDirectionContext.Provider value={directionContextValue}>
<RootComponent
{...props}
baseClassName={classNames(styles.host, size === 's' && styles.sizeS)}
getRootRef={rootRef}
>
<CalendarHeader
viewDate={externalViewDate || viewDate}
onChange={setViewDate}
onNextMonth={setNextMonth}
onPrevMonth={setPrevMonth}
disablePickers={disablePickers || size === 's'}
className={styles.header}
prevMonthLabel={prevMonthLabel}
nextMonthLabel={nextMonthLabel}
changeMonthLabel={changeMonthLabel}
changeYearLabel={changeYearLabel}
prevMonthIcon={prevMonthIcon}
nextMonthIcon={nextMonthIcon}
prevMonthProps={prevMonthProps}
nextMonthProps={nextMonthProps}
isMonthDisabled={isMonthDisabled}
isYearDisabled={isYearDisabled}
nextMonthButtonTestId={nextMonthButtonTestId}
prevMonthButtonTestId={prevMonthButtonTestId}
monthDropdownTestId={monthDropdownTestId}
yearDropdownTestId={yearDropdownTestId}
/>
<CalendarDays
viewDate={externalViewDate || viewDate}
value={value}
weekStartsOn={weekStartsOn}
isDayFocused={isDayFocused}
tabIndex={0}
aria-label={changeDayLabel}
onKeyDown={handleKeyDown}
onDayChange={onDayChange}
isDayActive={isDayActive}
isDaySelectionStart={isFirstDay}
isDaySelectionEnd={isLastDay}
isDayDisabled={isDayDisabled}
onBlur={resetSelectedDay}
showNeighboringMonth={showNeighboringMonth}
size={size}
dayProps={dayProps}
listenDayChangesForUpdate={listenDayChangesForUpdate}
renderDayContent={renderDayContent}
dayTestId={dayTestId}
/>
{enableTime && value && size !== 's' && (
<div className={styles.time}>
<CalendarTime
value={value}
onChange={onChange}
onDoneButtonClick={onDoneButtonClick}
doneButtonText={doneButtonText}
doneButtonDisabled={doneButtonDisabled}
doneButtonShow={doneButtonShow}
DoneButton={DoneButton}
changeHoursLabel={changeHoursLabel}
changeMinutesLabel={changeMinutesLabel}
isDayDisabled={minDateTime || maxDateTime ? isDayDisabled : undefined}
minutesTestId={minutesTestId}
hoursTestId={hoursTestId}
doneButtonTestId={doneButtonTestId}
/>
</div>
)}
</RootComponent>
</CalendarDirectionContext.Provider>
<RootComponent
{...props}
baseClassName={classNames(styles.host, size === 's' && styles.sizeS)}
getRootRef={getRootRef}
>
<CalendarHeader
viewDate={externalViewDate || viewDate}
onChange={setViewDate}
onNextMonth={setNextMonth}
onPrevMonth={setPrevMonth}
disablePickers={disablePickers || size === 's'}
className={styles.header}
prevMonthLabel={prevMonthLabel}
nextMonthLabel={nextMonthLabel}
changeMonthLabel={changeMonthLabel}
changeYearLabel={changeYearLabel}
prevMonthIcon={prevMonthIcon}
nextMonthIcon={nextMonthIcon}
prevMonthProps={prevMonthProps}
nextMonthProps={nextMonthProps}
isMonthDisabled={isMonthDisabled}
isYearDisabled={isYearDisabled}
nextMonthButtonTestId={nextMonthButtonTestId}
prevMonthButtonTestId={prevMonthButtonTestId}
monthDropdownTestId={monthDropdownTestId}
yearDropdownTestId={yearDropdownTestId}
/>
<CalendarDays
viewDate={externalViewDate || viewDate}
value={value}
weekStartsOn={weekStartsOn}
isDayFocused={isDayFocused}
tabIndex={0}
aria-label={changeDayLabel}
onKeyDown={handleKeyDown}
onDayChange={onDayChange}
isDayActive={isDayActive}
isDaySelectionStart={isFirstDay}
isDaySelectionEnd={isLastDay}
isDayDisabled={isDayDisabled}
onBlur={resetSelectedDay}
showNeighboringMonth={showNeighboringMonth}
size={size}
dayProps={dayProps}
listenDayChangesForUpdate={listenDayChangesForUpdate}
renderDayContent={renderDayContent}
dayTestId={dayTestId}
/>
{enableTime && value && size !== 's' && (
<div className={styles.time}>
<CalendarTime
value={value}
onChange={onChange}
onDoneButtonClick={onDoneButtonClick}
doneButtonText={doneButtonText}
doneButtonDisabled={doneButtonDisabled}
doneButtonShow={doneButtonShow}
DoneButton={DoneButton}
changeHoursLabel={changeHoursLabel}
changeMinutesLabel={changeMinutesLabel}
isDayDisabled={minDateTime || maxDateTime ? isDayDisabled : undefined}
minutesTestId={minutesTestId}
hoursTestId={hoursTestId}
doneButtonTestId={doneButtonTestId}
/>
</div>
)}
</RootComponent>
);
};
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
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.
4 changes: 1 addition & 3 deletions packages/vkui/src/components/CalendarDay/CalendarDay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import * as React from 'react';
import { classNames } from '@vkontakte/vkjs';
import { useCalendarDirectionContext } from '../../context/CalendarDirectionContext';
import { ENABLE_KEYBOARD_INPUT_EVENT_NAME } from '../../hooks/useKeyboardInputTracker';
import { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';
import { Tappable } from '../Tappable/Tappable';
Expand Down Expand Up @@ -67,9 +66,8 @@ export const CalendarDay: React.FC<CalendarDayProps> = React.memo(
testId,
...restProps
}: CalendarDayProps) => {
const { locale } = useConfigProvider();
const { locale, direction } = useConfigProvider();
const ref = React.useRef<HTMLElement>(null);
const { direction } = useCalendarDirectionContext();
const onClick = React.useCallback(() => onChange(day), [day, onChange]);
const handleEnter = React.useCallback(() => onEnter?.(day), [day, onEnter]);
const handleLeave = React.useCallback(() => onLeave?.(day), [day, onLeave]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
} from '@vkontakte/icons';
import { classNames } from '@vkontakte/vkjs';
import { addMonths, setMonth, setYear, subMonths } from 'date-fns';
import { useCalendarDirectionContext } from '../../context/CalendarDirectionContext';
import { DEFAULT_MAX_YEAR, DEFAULT_MIN_YEAR, getMonths, getYears } from '../../lib/calendar';
import type { HTMLAttributesWithRootRef } from '../../types';
import { AdaptivityProvider } from '../AdaptivityProvider/AdaptivityProvider';
Expand Down Expand Up @@ -104,8 +103,7 @@ export const CalendarHeader = ({
nextMonthButtonTestId,
...restProps
}: CalendarHeaderProps): React.ReactNode => {
const { locale } = useConfigProvider();
const { direction } = useCalendarDirectionContext();
const { locale, direction } = useConfigProvider();

const onMonthsChange = React.useCallback(
(_: ChangeEvent<HTMLSelectElement>, newValue: SelectProps['value']) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const CalendarRangePlayground = (props: ComponentPlaygroundProps) => {
},
{
value: [rangeValue],
dir: ['rtl'],
$direction: 'rtl',
},
]}
>
Expand Down
Loading