Skip to content

Commit

Permalink
feat(plasma-ui): add labels for time pickers
Browse files Browse the repository at this point in the history
  • Loading branch information
Yakutoc committed Sep 28, 2023
1 parent ce870b5 commit c6cf110
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 4 deletions.
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.
8 changes: 8 additions & 0 deletions packages/plasma-ui/src/components/Pickers/Pickers.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ interface TimePickerStoryProps extends TimePickerProps {
optionsHours: boolean;
optionsMinutes: boolean;
optionsSeconds: boolean;
hoursLabel?: string;
minutesLabel?: string;
secondsLabel?: string;
hasLabel?: boolean;
}

// eslint-disable-next-line @typescript-eslint/naming-convention, camelcase
Expand Down Expand Up @@ -355,6 +359,10 @@ Time_Picker.args = {
visibleItems: 3,
step: 1,
infiniteScroll: true,
hoursLabel: '',
minutesLabel: '',
secondsLabel: '',
hasLabel: false,
};

// eslint-disable-next-line @typescript-eslint/naming-convention
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,49 @@ describe('plasma-ui: TimePicker', () => {
}
});
});

it('label', () => {
mount(
<CypressTestDecorator>
<TimePicker
value={new Date(1980, 8, 1, 0, 28, 59)}
min={new Date(1975, 1, 1, 0, 15, 29)}
max={new Date(1985, 10, 30, 12, 30, 30)}
hasLabel
/>
</CypressTestDecorator>,
);

cy.matchImageSnapshot();
});

it('label with controls', () => {
mount(
<CypressTestDecorator>
<TimePicker
value={new Date(1980, 8, 1, 0, 28, 59)}
min={new Date(1975, 1, 1, 0, 15, 29)}
max={new Date(1985, 10, 30, 12, 30, 30)}
hasLabel
onChange={noop}
controls
/>
</CypressTestDecorator>,
);

// отключение анимаций на всех div'ах внутри окружения, TODO: перенести в plasma-cy-utils?
cy.get('div').invoke('attr', 'style', 'transition: unset; animation: none; scroll-snap-type: none;');

cy.get('div > div:nth-child(1)').contains('03').click({ force: true });
cy.wait(150);
cy.get('div > div:nth-child(3)').contains('04').click({ force: true });
cy.wait(150);
cy.get('div > div:nth-child(5)').contains('06').click({ force: true });

cy.wait(1000);

cy.matchImageSnapshot();
});
});

describe('plasma-ui: TimePicker update value', () => {
Expand Down
68 changes: 64 additions & 4 deletions packages/plasma-ui/src/components/Pickers/TimePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,51 @@
import React from 'react';
import styled from 'styled-components';
import { useIsomorphicLayoutEffect } from '@salutejs/plasma-core';
import { whiteTertiary, footnote1 } from '@salutejs/plasma-tokens';

import { PickerDots } from './PickerDots';
import { SimpleTimePicker, SimpleTimePickerProps } from './SimpleTimePicker';
import { getNewDate, getNormalizeValues, getRange, getTimeValues, getValuesInRange, isChanged } from './utils';
import type { PickerItem, TimeType } from './types';
import type { PickerItem, TimeType, PickerSize } from './types';
import { DEFAULT_PICKER_SIZE } from './types';

const StyledWrapper = styled.div`
display: flex;
width: max-content;
align-items: stretch;
`;

const labelFontSize: Record<PickerSize, string> = {
l: '0.875rem',
s: '0.75rem',
xs: '0.625rem',
};

const StyledSimpleTimePicker = styled(SimpleTimePicker)`
&[data-label] {
margin-top: 2rem;
}
&[data-label]::before {
content: attr(data-label);
position: absolute;
left: 0;
margin-top: ${({ controls }) => (controls ? '-2.5rem' : '-1.5rem')};
width: 100%;
color: ${whiteTertiary};
${footnote1};
font-weight: normal;
font-size: ${({ size = DEFAULT_PICKER_SIZE }) => labelFontSize[size]};
}
&[data-label] + ${PickerDots} {
&::before,
&::after {
top: calc(50% + 1rem);
}
}
`;

const defaultOptions = {
hours: true,
minutes: true,
Expand Down Expand Up @@ -66,6 +99,26 @@ export interface TimePickerProps extends Omit<SimpleTimePickerProps, 'type' | 'r
* Сменить WAI-ARIA Label списка годов.
*/
hoursAriaLabel?: string;

/**
* Label для picker "часов"
*/
hoursLabel?: string;

/**
* Label для picker "минуты"
*/
minutesLabel?: string;

/**
* Label для picker "секунды"
*/
secondsLabel?: string;

/**
* Показывать ли label для picker "секунды", "минуты" и т.д.
*/
hasLabel?: boolean;
}

/**
Expand All @@ -92,6 +145,10 @@ export const TimePicker = ({
hoursAriaLabel,
infiniteScroll,
disableScrollSnapAlign = false,
hoursLabel,
minutesLabel,
secondsLabel,
hasLabel = false,
...rest
}: TimePickerProps) => {
const normalizeValues = React.useMemo(() => getNormalizeValues(getTimeValues, getSeconds)(value, min, max), [
Expand Down Expand Up @@ -217,7 +274,7 @@ export const TimePicker = ({
return (
<StyledWrapper id={id} {...rest}>
{options.hours && (
<SimpleTimePicker
<StyledSimpleTimePicker
id={id}
type="hours"
autofocus={autofocus}
Expand All @@ -232,11 +289,12 @@ export const TimePicker = ({
onChange={onHoursChange}
aria-label={hoursAriaLabel}
disableScrollSnapAlign={disableScrollSnapAlign}
data-label={hasLabel ? hoursLabel || 'часов' : null}
/>
)}
{options.hours && options.minutes && <PickerDots $size={size} />}
{options.minutes && (
<SimpleTimePicker
<StyledSimpleTimePicker
id={id}
type="minutes"
autofocus={autofocus && !options.hours}
Expand All @@ -251,11 +309,12 @@ export const TimePicker = ({
onChange={onMinutesChange}
aria-label={minutesAriaLabel}
disableScrollSnapAlign={disableScrollSnapAlign}
data-label={hasLabel ? minutesLabel || 'минут' : null}
/>
)}
{options.minutes && options.seconds && <PickerDots $size={size} />}
{options.seconds && (
<SimpleTimePicker
<StyledSimpleTimePicker
id={id}
type="seconds"
autofocus={autofocus && !options.hours && !options.minutes}
Expand All @@ -270,6 +329,7 @@ export const TimePicker = ({
onChange={onSecondsChange}
aria-label={secondsAriaLabel}
disableScrollSnapAlign={disableScrollSnapAlign}
data-label={hasLabel ? secondsLabel || 'секунд' : null}
/>
)}
{enableNativeControl && <input type="hidden" value={value.toISOString()} name={name} />}
Expand Down

0 comments on commit c6cf110

Please sign in to comment.