Skip to content

Feature: TimePicker's minutes/seconds list multiplicity#2836

Open
Realetive wants to merge 7 commits into
devfrom
feature/TimePickerGrid-multiplicity
Open

Feature: TimePicker's minutes/seconds list multiplicity#2836
Realetive wants to merge 7 commits into
devfrom
feature/TimePickerGrid-multiplicity

Conversation

@Realetive
Copy link
Copy Markdown
Collaborator

@Realetive Realetive commented Jun 4, 2026

PLASMA-WEB

TimePicker

  • добавлена пропсы multiplicityMinutes и multiplicitySeconds для TimePickerGrid
  • обновлён сторибук
  • добавлены тесты

TimePickerGrid

  • добавлено управление отображаемым списком минут и секунд через «кратность»
  • добавлены тесты

What/why changed

Реализована возможность управления отображаемым списком минут и секунд в TimePicker'е, кратным 1 (поведение по умолчанию, т. е. все 60 минут/секунд), 5, 10, 15, 20, 30. Добавлена валидация вводимого значения с округлением к ближайшему валидному числу. Добавлен фолбэк при попытке передать «кратность» вне разрешённого списка чисел (1, 5, 10, 15, 20, 30). На новый функционал добавлены тесты и обновлён сторибук.

Summary by CodeRabbit

  • New Features
    • TimePicker now supports multiplicityMinutes and multiplicitySeconds properties to control minute and second increments in time selection (1, 5, 10, 15, 20, or 30 increments).
📦 Published PR as canary version: Canary Versions

✨ Test out this PR locally via:

npm install @salutejs/plasma-asdk@0.378.0-canary.2836.26952968753.0
npm install @salutejs/plasma-b2c@1.620.0-canary.2836.26952968753.0
npm install @salutejs/plasma-core@1.228.0-canary.2836.26952968753.0
npm install @salutejs/plasma-giga@0.347.0-canary.2836.26952968753.0
npm install @salutejs/plasma-homeds@0.347.0-canary.2836.26952968753.0
npm install @salutejs/plasma-hope@1.374.0-canary.2836.26952968753.0
npm install @salutejs/plasma-icons@1.239.0-canary.2836.26952968753.0
npm install @salutejs/plasma-new-hope@0.364.0-canary.2836.26952968753.0
npm install @salutejs/plasma-tokens-b2b@1.56.0-canary.2836.26952968753.0
npm install @salutejs/plasma-tokens-b2c@0.67.0-canary.2836.26952968753.0
npm install @salutejs/plasma-tokens-web@1.71.0-canary.2836.26952968753.0
npm install @salutejs/plasma-tokens@1.140.0-canary.2836.26952968753.0
npm install @salutejs/plasma-typo@0.44.0-canary.2836.26952968753.0
npm install @salutejs/plasma-ui@1.350.0-canary.2836.26952968753.0
npm install @salutejs/plasma-web@1.622.0-canary.2836.26952968753.0
npm install @salutejs/sdds-bizcom@0.352.0-canary.2836.26952968753.0
npm install @salutejs/sdds-cs@0.356.0-canary.2836.26952968753.0
npm install @salutejs/sdds-dfa@0.350.0-canary.2836.26952968753.0
npm install @salutejs/sdds-finai@0.343.0-canary.2836.26952968753.0
npm install @salutejs/sdds-insol@0.347.0-canary.2836.26952968753.0
npm install @salutejs/sdds-netology@0.351.0-canary.2836.26952968753.0
npm install @salutejs/sdds-os@0.22.0-canary.2836.26952968753.0
npm install @salutejs/sdds-platform-ai@0.351.0-canary.2836.26952968753.0
npm install @salutejs/sdds-sbcom@0.352.0-canary.2836.26952968753.0
npm install @salutejs/sdds-scan@0.350.0-canary.2836.26952968753.0
npm install @salutejs/sdds-serv@0.351.0-canary.2836.26952968753.0
npm install @salutejs/core-themes@0.31.0-canary.2836.26952968753.0
npm install @salutejs/plasma-themes@0.52.0-canary.2836.26952968753.0
npm install @salutejs/sdds-themes@0.67.0-canary.2836.26952968753.0
npm install @salutejs/sdds-api-tests@0.9.0-canary.2836.26952968753.0
npm install @salutejs/plasma-cy-utils@0.158.0-canary.2836.26952968753.0
npm install @salutejs/plasma-sb-utils@0.228.0-canary.2836.26952968753.0
npm install @salutejs/plasma-tokens-utils@0.52.0-canary.2836.26952968753.0
# or 
yarn add @salutejs/plasma-asdk@0.378.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-b2c@1.620.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-core@1.228.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-giga@0.347.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-homeds@0.347.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-hope@1.374.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-icons@1.239.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-new-hope@0.364.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-tokens-b2b@1.56.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-tokens-b2c@0.67.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-tokens-web@1.71.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-tokens@1.140.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-typo@0.44.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-ui@1.350.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-web@1.622.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-bizcom@0.352.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-cs@0.356.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-dfa@0.350.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-finai@0.343.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-insol@0.347.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-netology@0.351.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-os@0.22.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-platform-ai@0.351.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-sbcom@0.352.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-scan@0.350.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-serv@0.351.0-canary.2836.26952968753.0
yarn add @salutejs/core-themes@0.31.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-themes@0.52.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-themes@0.67.0-canary.2836.26952968753.0
yarn add @salutejs/sdds-api-tests@0.9.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-cy-utils@0.158.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-sb-utils@0.228.0-canary.2836.26952968753.0
yarn add @salutejs/plasma-tokens-utils@0.52.0-canary.2836.26952968753.0

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds step-based multiplicity configuration to TimePicker and TimePickerGrid, allowing minute and second selection increments to be controlled via multiplicityMinutes and multiplicitySeconds props. The feature includes a new type definition, utility functions for stepped column generation and rounding, component integration, comprehensive tests, and Storybook examples.

Changes

TimePicker multiplicity feature

Layer / File(s) Summary
Multiplicity type contract and grid props
packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.types.ts
Introduces TimePickerMultiplicity type (1 | 5 | 10 | 15 | 20 | 30) and extends TimePickerGridProps with optional multiplicityMinutes and multiplicitySeconds props.
Utility functions for step-based column and value handling
packages/plasma-new-hope/src/components/TimePickerGrid/utils/index.ts
Updates getColumnsFromFormat to accept optional multiplicity parameters; extends range helper to support configurable step; adds new roundToMultiplicity helper for rounding values to the nearest step multiple.
TimePickerGrid integration with multiplicities
packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx
TimePickerGrid passes multiplicity props to getColumnsFromFormat for stepped column generation and rounds parsed minute/second values to configured multiplicities using roundToMultiplicity.
TimePicker prop forwarding to grid
packages/plasma-new-hope/src/components/TimePicker/TimePicker.tsx, packages/plasma-new-hope/src/components/TimePicker/TimePicker.types.ts
TimePicker imports TimePickerMultiplicity, extends BasicProps with multiplicity props, destructures them from component props, and forwards both values to StyledTimePickerGrid.
Component tests, API validation, and Storybook examples
packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.component-test.tsx, packages/plasma-new-hope/src/examples/components/TimePicker/TimePicker.stories.tsx, utils/api-tests/src/components/TimePicker/TimePicker.api.test.tsx
Cypress component tests validate TimePickerGrid rendering with minute/second multiplicities and value rounding; API tests verify prop types and reject invalid values; Storybook stories showcase minute and second multiplicity usage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A picker for time, now with steps so divine,
Multiplicities five, ten, fifteen align!
From utils that round to grid columns that skip,
Your minute-to-second increments now take a trip! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main feature added: multiplicity control for TimePicker's minute and second lists, which aligns with all substantive changes across the files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/TimePickerGrid-multiplicity

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Theme Builder app deployed!

https://plasma.sberdevices.ru/pr/plasma-theme-builder-pr-2836/

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx`:
- Around line 61-64: The memo for columnsConfig is missing multiplicityMinutes
and multiplicitySeconds so getColumnsFromFormat(actualFormat,
multiplicityMinutes, multiplicitySeconds) can return stale values; update the
useMemo dependency array for the columnsConfig declaration to include
multiplicityMinutes and multiplicitySeconds (in addition to actualFormat) so
columnsConfig is recalculated when those props change.

In `@packages/plasma-new-hope/src/components/TimePickerGrid/utils/index.ts`:
- Around line 140-147: In range and roundToMultiplicity guard against
invalid/non-positive step and ensure rounded values stay within the selectable
set: in range(...) ensure step is normalized to at least 1 (e.g., if step <= 0
set step = 1) and compute length with Math.max(1, Math.ceil(number / step)) so
Array.from never gets an invalid length; in roundToMultiplicity(value, step)
return value unchanged if !step or step <= 1, otherwise compute rounded =
Math.round(value / step) * step and if rounded >= number clamp it down to number
- step (and ensure it never becomes negative) so you never return a value
outside the list produced by range.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d604be46-6498-47d1-8044-c159c6096aa4

📥 Commits

Reviewing files that changed from the base of the PR and between fcc43fb and 4e1de1b.

📒 Files selected for processing (8)
  • packages/plasma-new-hope/src/components/TimePicker/TimePicker.tsx
  • packages/plasma-new-hope/src/components/TimePicker/TimePicker.types.ts
  • packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.component-test.tsx
  • packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx
  • packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.types.ts
  • packages/plasma-new-hope/src/components/TimePickerGrid/utils/index.ts
  • packages/plasma-new-hope/src/examples/components/TimePicker/TimePicker.stories.tsx
  • utils/api-tests/src/components/TimePicker/TimePicker.api.test.tsx

Comment on lines +61 to +64
const columnsConfig = useMemo(
() => getColumnsFromFormat(actualFormat, multiplicityMinutes, multiplicitySeconds),
[actualFormat],
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx"

echo "== File head/context =="
sed -n '1,200p' "$FILE" | nl -ba

echo
echo "== Lines 40-90 (around useMemo) =="
sed -n '40,90p' "$FILE" | nl -ba

echo
echo "== Find definition/usages of multiplicityMinutes/multiplicitySeconds in this file =="
rg -n "multiplicity(Minutes|Seconds)" "$FILE" || true

echo
echo "== Find component props/type where these come from =="
rg -n "TimePickerGrid" "$FILE" || true
rg -n "interface|type|props|Props" "$FILE" || true

echo
echo "== Search repo for getColumnsFromFormat signature =="
rg -n "function getColumnsFromFormat|getColumnsFromFormat\\(" packages/plasma-new-hope/src/components/TimePickerGrid -S || true

# If not found in that directory, search broader within packages/plasma-new-hope/src
rg -n "getColumnsFromFormat\\(" packages/plasma-new-hope/src -S || true

Repository: salute-developers/plasma

Length of output: 153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx"

python3 - <<'PY'
from pathlib import Path
p = Path("packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx")
lines = p.read_text(encoding="utf-8").splitlines()
for i in range(1, min(len(lines), 140)+1):
    if 35 <= i <= 90 or i in (1,2,3) or i in (60,61,62,63,64,65,66):
        pass
PY

echo "== Lines 50-80 (with line numbers via python) =="
python3 - <<'PY'
from pathlib import Path
p = Path("packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx")
lines = p.read_text(encoding="utf-8").splitlines()
start, end = 45, 85
for i in range(start, end+1):
    if i <= len(lines):
        print(f"{i:4d}: {lines[i-1]}")
PY

echo
echo "== Lines containing useMemo =="
rg -n "useMemo\\(" "$FILE" || true

echo
echo "== Find definitions/usages of multiplicityMinutes/multiplicitySeconds in this file =="
rg -n "multiplicity(Minutes|Seconds)" "$FILE" || true

echo
echo "== Search for getColumnsFromFormat definition/signature (repo-local) =="
rg -n "getColumnsFromFormat" packages/plasma-new-hope/src/components/TimePickerGrid -S || true
rg -n "getColumnsFromFormat" packages/plasma-new-hope/src -S || true

Repository: salute-developers/plasma

Length of output: 3634


🏁 Script executed:

#!/bin/bash
set -euo pipefail

UTILS="packages/plasma-new-hope/src/components/TimePickerGrid/utils/index.ts"
echo "== Lines 1-120 of utils/index.ts =="
python3 - <<'PY'
from pathlib import Path
p=Path("packages/plasma-new-hope/src/components/TimePickerGrid/utils/index.ts")
lines=p.read_text(encoding="utf-8").splitlines()
for i in range(1, min(len(lines), 130)+1):
    if i<=120:
        print(f"{i:4d}: {lines[i-1]}")
PY

echo
echo "== Search within TimePickerGrid for roundToMultiplicity and columnsConfig usage =="
FILE="packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx"
rg -n "roundToMultiplicity|getColumnsFromFormat|columnsConfig" "$FILE" -n || true

Repository: salute-developers/plasma

Length of output: 5081


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx"

echo "== Lines 1-120 of TimePickerGrid.tsx =="
python3 - <<'PY'
from pathlib import Path
p=Path("packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx")
lines=p.read_text(encoding="utf-8").splitlines()
for i in range(1, min(len(lines), 130)+1):
    print(f"{i:4d}: {lines[i-1]}")
PY

Repository: salute-developers/plasma

Length of output: 5824


Fix stale columnsConfig memoization by adding multiplicity props to useMemo dependencies

getColumnsFromFormat(actualFormat, multiplicityMinutes, multiplicitySeconds) uses multiplicityMinutes/multiplicitySeconds to build the minutes/seconds ranges, but useMemo only depends on actualFormat, so columnsConfig can be stale when those props change.

Proposed fix
 const columnsConfig = useMemo(
     () => getColumnsFromFormat(actualFormat, multiplicityMinutes, multiplicitySeconds),
-    [actualFormat],
+    [actualFormat, multiplicityMinutes, multiplicitySeconds],
 );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const columnsConfig = useMemo(
() => getColumnsFromFormat(actualFormat, multiplicityMinutes, multiplicitySeconds),
[actualFormat],
);
const columnsConfig = useMemo(
() => getColumnsFromFormat(actualFormat, multiplicityMinutes, multiplicitySeconds),
[actualFormat, multiplicityMinutes, multiplicitySeconds],
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/plasma-new-hope/src/components/TimePickerGrid/TimePickerGrid.tsx`
around lines 61 - 64, The memo for columnsConfig is missing multiplicityMinutes
and multiplicitySeconds so getColumnsFromFormat(actualFormat,
multiplicityMinutes, multiplicitySeconds) can return stale values; update the
useMemo dependency array for the columnsConfig declaration to include
multiplicityMinutes and multiplicitySeconds (in addition to actualFormat) so
columnsConfig is recalculated when those props change.

Comment on lines +140 to +147
export const range = (number: number, padLength = 2, step = 1): string[] => {
if (step > number) step = number;
return Array.from({ length: Math.ceil(number / step) }, (_, i) => (i * step).toString().padStart(padLength, '0'));
};

export const roundToMultiplicity = (value: number, step?: number): number => {
if (!step || step <= 1) return value;
return Math.round(value / step) * step;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard invalid step values and clamp rounded output to selectable values.

Line 142 can throw on step <= 0 (Array.from with invalid length), and Line 147 can produce 60 for minutes/seconds (e.g. 59 with step 20), which is not present in the rendered list.

Proposed fix
+const ALLOWED_MULTIPLICITIES = [1, 5, 10, 15, 20, 30] as const;
+
+const normalizeStep = (step?: number): number => {
+    if (!Number.isFinite(step) || !step || step <= 0) return 1;
+    if (ALLOWED_MULTIPLICITIES.includes(step as (typeof ALLOWED_MULTIPLICITIES)[number])) return step;
+
+    return ALLOWED_MULTIPLICITIES.reduce((nearest, current) =>
+        Math.abs(current - step) < Math.abs(nearest - step) ? current : nearest,
+    );
+};
+
 export const range = (number: number, padLength = 2, step = 1): string[] => {
-    if (step > number) step = number;
-    return Array.from({ length: Math.ceil(number / step) }, (_, i) => (i * step).toString().padStart(padLength, '0'));
+    const safeStep = Math.min(normalizeStep(step), number);
+    return Array.from(
+        { length: Math.ceil(number / safeStep) },
+        (_, i) => (i * safeStep).toString().padStart(padLength, '0'),
+    );
 };
 
 export const roundToMultiplicity = (value: number, step?: number): number => {
-    if (!step || step <= 1) return value;
-    return Math.round(value / step) * step;
+    const safeStep = normalizeStep(step);
+    if (safeStep <= 1) return value;
+
+    const maxValid = Math.floor(59 / safeStep) * safeStep;
+    return Math.max(0, Math.min(maxValid, Math.round(value / safeStep) * safeStep));
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const range = (number: number, padLength = 2, step = 1): string[] => {
if (step > number) step = number;
return Array.from({ length: Math.ceil(number / step) }, (_, i) => (i * step).toString().padStart(padLength, '0'));
};
export const roundToMultiplicity = (value: number, step?: number): number => {
if (!step || step <= 1) return value;
return Math.round(value / step) * step;
const ALLOWED_MULTIPLICITIES = [1, 5, 10, 15, 20, 30] as const;
const normalizeStep = (step?: number): number => {
if (!Number.isFinite(step) || !step || step <= 0) return 1;
if (ALLOWED_MULTIPLICITIES.includes(step as (typeof ALLOWED_MULTIPLICITIES)[number])) return step;
return ALLOWED_MULTIPLICITIES.reduce((nearest, current) =>
Math.abs(current - step) < Math.abs(nearest - step) ? current : nearest,
);
};
export const range = (number: number, padLength = 2, step = 1): string[] => {
const safeStep = Math.min(normalizeStep(step), number);
return Array.from(
{ length: Math.ceil(number / safeStep) },
(_, i) => (i * safeStep).toString().padStart(padLength, '0'),
);
};
export const roundToMultiplicity = (value: number, step?: number): number => {
const safeStep = normalizeStep(step);
if (safeStep <= 1) return value;
const maxValid = Math.floor(59 / safeStep) * safeStep;
return Math.max(0, Math.min(maxValid, Math.round(value / safeStep) * safeStep));
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/plasma-new-hope/src/components/TimePickerGrid/utils/index.ts` around
lines 140 - 147, In range and roundToMultiplicity guard against
invalid/non-positive step and ensure rounded values stay within the selectable
set: in range(...) ensure step is normalized to at least 1 (e.g., if step <= 0
set step = 1) and compute length with Math.max(1, Math.ceil(number / step)) so
Array.from never gets an invalid length; in roundToMultiplicity(value, step)
return value unchanged if !step or step <= 1, otherwise compute rounded =
Math.round(value / step) * step and if rounded >= number clamp it down to number
- step (and ensure it never becomes negative) so you never return a value
outside the list produced by range.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Documentation preview deployed!

website: https://plasma.sberdevices.ru/pr/pr-2836/
asdk storybook: https://plasma.sberdevices.ru/pr/pr-2836/asdk-storybook/
b2c storybook: https://plasma.sberdevices.ru/pr/pr-2836/b2c-storybook/
giga storybook: https://plasma.sberdevices.ru/pr/pr-2836/giga-storybook/
homeds storybook: https://plasma.sberdevices.ru/pr/pr-2836/homeds-storybook/
new-hope storybook: https://plasma.sberdevices.ru/pr/pr-2836/new-hope-storybook/
web storybook: https://plasma.sberdevices.ru/pr/pr-2836/web-storybook/
sdds-bizcom storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-bizcom-storybook/
sdds-cs storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-cs-storybook/
sdds-dfa storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-dfa-storybook/
sdds-finai storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-finai-storybook/
sdds-insol storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-insol-storybook/
sdds-netology storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-netology-storybook/
sdds-os storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-os-storybook/
sdds-platform-ai storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-platform-ai-storybook/
sdds-sbcom storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-sbcom-storybook/
sdds-scan storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-scan-storybook/
sdds-serv storybook: https://plasma.sberdevices.ru/pr/pr-2836/sdds-serv-storybook/
ui storybook: https://plasma.sberdevices.ru/pr/pr-2836/ui-storybook/

@Yakutoc Yakutoc self-assigned this Jun 4, 2026
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не вижу тут валидации при вводе, если задана кратность. То есть multiplicityMinutes=5, а в инпут введут 13:13. Скорее всего нужно поведение, как при вводе некорректного значения для NumberInput https://plasma.sberdevices.ru/pr/pr-2836/new-hope-storybook/?path=/story/data-entry-numberinput--default&args=isManualInput:!true

Comment on lines +24 to +37
export const WithMultiplicityMinutes: StoryObj<TimePickerProps> = {
args: {
value: '00:00',
multiplicityMinutes: 5,
},
};

export const WithMultiplicitySeconds: StoryObj<TimePickerProps> = {
args: {
value: '00:00:00',
columnsQuantity: 3,
multiplicitySeconds: 20,
},
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эти стори дотюнить нужно, так как сейчас не работают

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants