@cloud-ru/ds-fields 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/LICENSE +201 -0
- package/README.md +888 -0
- package/dist/cjs/components/FieldColor/FieldColor.d.ts +48 -0
- package/dist/cjs/components/FieldColor/FieldColor.js +147 -0
- package/dist/cjs/components/FieldColor/index.d.ts +1 -0
- package/dist/cjs/components/FieldColor/index.js +17 -0
- package/dist/cjs/components/FieldColor/styles.module.css +79 -0
- package/dist/cjs/components/FieldColor/utils.d.ts +7 -0
- package/dist/cjs/components/FieldColor/utils.js +19 -0
- package/dist/cjs/components/FieldCombo/FieldCombo.d.ts +91 -0
- package/dist/cjs/components/FieldCombo/FieldCombo.js +200 -0
- package/dist/cjs/components/FieldCombo/index.d.ts +1 -0
- package/dist/cjs/components/FieldCombo/index.js +17 -0
- package/dist/cjs/components/FieldDate/FieldDate.d.ts +2 -0
- package/dist/cjs/components/FieldDate/FieldDate.js +369 -0
- package/dist/cjs/components/FieldDate/constants.d.ts +10 -0
- package/dist/cjs/components/FieldDate/constants.js +13 -0
- package/dist/cjs/components/FieldDate/index.d.ts +3 -0
- package/dist/cjs/components/FieldDate/index.js +19 -0
- package/dist/cjs/components/FieldDate/mask.d.ts +20 -0
- package/dist/cjs/components/FieldDate/mask.js +117 -0
- package/dist/cjs/components/FieldDate/styles.module.css +43 -0
- package/dist/cjs/components/FieldDate/types.d.ts +100 -0
- package/dist/cjs/components/FieldDate/types.js +2 -0
- package/dist/cjs/components/FieldDate/utils.d.ts +3 -0
- package/dist/cjs/components/FieldDate/utils.js +8 -0
- package/dist/cjs/components/FieldSecure/FieldSecure.d.ts +64 -0
- package/dist/cjs/components/FieldSecure/FieldSecure.js +158 -0
- package/dist/cjs/components/FieldSecure/index.d.ts +1 -0
- package/dist/cjs/components/FieldSecure/index.js +17 -0
- package/dist/cjs/components/FieldSelect/FieldSelect.d.ts +2 -0
- package/dist/cjs/components/FieldSelect/FieldSelect.js +360 -0
- package/dist/cjs/components/FieldSelect/constants.d.ts +4 -0
- package/dist/cjs/components/FieldSelect/constants.js +7 -0
- package/dist/cjs/components/FieldSelect/index.d.ts +3 -0
- package/dist/cjs/components/FieldSelect/index.js +19 -0
- package/dist/cjs/components/FieldSelect/styles.module.css +92 -0
- package/dist/cjs/components/FieldSelect/types.d.ts +197 -0
- package/dist/cjs/components/FieldSelect/types.js +2 -0
- package/dist/cjs/components/FieldSelect/utils.d.ts +19 -0
- package/dist/cjs/components/FieldSelect/utils.js +104 -0
- package/dist/cjs/components/FieldSlider/FieldSlider.d.ts +92 -0
- package/dist/cjs/components/FieldSlider/FieldSlider.js +196 -0
- package/dist/cjs/components/FieldSlider/index.d.ts +2 -0
- package/dist/cjs/components/FieldSlider/index.js +18 -0
- package/dist/cjs/components/FieldSlider/styles.module.css +44 -0
- package/dist/cjs/components/FieldSlider/types.d.ts +4 -0
- package/dist/cjs/components/FieldSlider/types.js +2 -0
- package/dist/cjs/components/FieldSlider/utils/generateAllowedValues.d.ts +1 -0
- package/dist/cjs/components/FieldSlider/utils/generateAllowedValues.js +16 -0
- package/dist/cjs/components/FieldSlider/utils/getClosestMark.d.ts +4 -0
- package/dist/cjs/components/FieldSlider/utils/getClosestMark.js +16 -0
- package/dist/cjs/components/FieldSlider/utils/getMarkLabel.d.ts +2 -0
- package/dist/cjs/components/FieldSlider/utils/getMarkLabel.js +7 -0
- package/dist/cjs/components/FieldSlider/utils/getTextFieldValue.d.ts +2 -0
- package/dist/cjs/components/FieldSlider/utils/getTextFieldValue.js +9 -0
- package/dist/cjs/components/FieldSlider/utils/index.d.ts +5 -0
- package/dist/cjs/components/FieldSlider/utils/index.js +21 -0
- package/dist/cjs/components/FieldSlider/utils/isMarkObject.d.ts +6 -0
- package/dist/cjs/components/FieldSlider/utils/isMarkObject.js +6 -0
- package/dist/cjs/components/FieldStepper/FieldStepper.d.ts +81 -0
- package/dist/cjs/components/FieldStepper/FieldStepper.js +160 -0
- package/dist/cjs/components/FieldStepper/index.d.ts +1 -0
- package/dist/cjs/components/FieldStepper/index.js +17 -0
- package/dist/cjs/components/FieldStepper/styles.module.css +78 -0
- package/dist/cjs/components/FieldStepper/utils.d.ts +14 -0
- package/dist/cjs/components/FieldStepper/utils.js +45 -0
- package/dist/cjs/components/FieldText/FieldText.d.ts +11 -0
- package/dist/cjs/components/FieldText/FieldText.js +14 -0
- package/dist/cjs/components/FieldText/index.d.ts +1 -0
- package/dist/cjs/components/FieldText/index.js +17 -0
- package/dist/cjs/components/FieldTextArea/FieldTextArea.d.ts +95 -0
- package/dist/cjs/components/FieldTextArea/FieldTextArea.js +114 -0
- package/dist/cjs/components/FieldTextArea/index.d.ts +1 -0
- package/dist/cjs/components/FieldTextArea/index.js +17 -0
- package/dist/cjs/components/FieldTextArea/styles.module.css +123 -0
- package/dist/cjs/components/FieldTime/FieldTime.d.ts +74 -0
- package/dist/cjs/components/FieldTime/FieldTime.js +167 -0
- package/dist/cjs/components/FieldTime/index.d.ts +2 -0
- package/dist/cjs/components/FieldTime/index.js +17 -0
- package/dist/cjs/components/FieldTime/mask.d.ts +3 -0
- package/dist/cjs/components/FieldTime/mask.js +24 -0
- package/dist/cjs/components/FieldTime/styles.module.css +3 -0
- package/dist/cjs/components/index.d.ts +14 -0
- package/dist/cjs/components/index.js +32 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButton.d.ts +35 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButton.js +47 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.d.ts +26 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.js +24 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/constants.d.ts +9 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/constants.js +12 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/index.d.ts +4 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/index.js +20 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/styles.module.css +204 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/types.d.ts +4 -0
- package/dist/cjs/components/shared/helperComponents/FieldElementButton/types.js +2 -0
- package/dist/cjs/components/shared/helperComponents/FieldShell/FieldShell.d.ts +43 -0
- package/dist/cjs/components/shared/helperComponents/FieldShell/FieldShell.js +22 -0
- package/dist/cjs/components/shared/helperComponents/FieldShell/index.d.ts +1 -0
- package/dist/cjs/components/shared/helperComponents/FieldShell/index.js +17 -0
- package/dist/cjs/components/shared/helperComponents/FieldShell/styles.module.css +11 -0
- package/dist/cjs/components/shared/hooks/useCopyButton.d.ts +20 -0
- package/dist/cjs/components/shared/hooks/useCopyButton.js +58 -0
- package/dist/cjs/components/shared/index.d.ts +4 -0
- package/dist/cjs/components/shared/index.js +20 -0
- package/dist/cjs/components/shared/styles.module.css +673 -0
- package/dist/cjs/components/shared/utils.d.ts +69 -0
- package/dist/cjs/components/shared/utils.js +104 -0
- package/dist/cjs/constants.d.ts +61 -0
- package/dist/cjs/constants.js +76 -0
- package/dist/cjs/hooks/index.d.ts +1 -0
- package/dist/cjs/hooks/index.js +17 -0
- package/dist/cjs/hooks/useAdaptiveAutoFocus.d.ts +7 -0
- package/dist/cjs/hooks/useAdaptiveAutoFocus.js +10 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +19 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/segments/index.d.ts +2 -0
- package/dist/cjs/segments/index.js +18 -0
- package/dist/cjs/segments/segments.d.ts +22 -0
- package/dist/cjs/segments/segments.js +46 -0
- package/dist/cjs/segments/useSegmentedMask.d.ts +43 -0
- package/dist/cjs/segments/useSegmentedMask.js +282 -0
- package/dist/cjs/style.css +1350 -0
- package/dist/esm/components/FieldColor/FieldColor.d.ts +48 -0
- package/dist/esm/components/FieldColor/FieldColor.js +141 -0
- package/dist/esm/components/FieldColor/index.d.ts +1 -0
- package/dist/esm/components/FieldColor/index.js +1 -0
- package/dist/esm/components/FieldColor/styles.module.css +79 -0
- package/dist/esm/components/FieldColor/utils.d.ts +7 -0
- package/dist/esm/components/FieldColor/utils.js +16 -0
- package/dist/esm/components/FieldCombo/FieldCombo.d.ts +91 -0
- package/dist/esm/components/FieldCombo/FieldCombo.js +194 -0
- package/dist/esm/components/FieldCombo/index.d.ts +1 -0
- package/dist/esm/components/FieldCombo/index.js +1 -0
- package/dist/esm/components/FieldDate/FieldDate.d.ts +2 -0
- package/dist/esm/components/FieldDate/FieldDate.js +363 -0
- package/dist/esm/components/FieldDate/constants.d.ts +10 -0
- package/dist/esm/components/FieldDate/constants.js +10 -0
- package/dist/esm/components/FieldDate/index.d.ts +3 -0
- package/dist/esm/components/FieldDate/index.js +3 -0
- package/dist/esm/components/FieldDate/mask.d.ts +20 -0
- package/dist/esm/components/FieldDate/mask.js +111 -0
- package/dist/esm/components/FieldDate/styles.module.css +43 -0
- package/dist/esm/components/FieldDate/types.d.ts +100 -0
- package/dist/esm/components/FieldDate/types.js +1 -0
- package/dist/esm/components/FieldDate/utils.d.ts +3 -0
- package/dist/esm/components/FieldDate/utils.js +5 -0
- package/dist/esm/components/FieldSecure/FieldSecure.d.ts +64 -0
- package/dist/esm/components/FieldSecure/FieldSecure.js +152 -0
- package/dist/esm/components/FieldSecure/index.d.ts +1 -0
- package/dist/esm/components/FieldSecure/index.js +1 -0
- package/dist/esm/components/FieldSelect/FieldSelect.d.ts +2 -0
- package/dist/esm/components/FieldSelect/FieldSelect.js +354 -0
- package/dist/esm/components/FieldSelect/constants.d.ts +4 -0
- package/dist/esm/components/FieldSelect/constants.js +4 -0
- package/dist/esm/components/FieldSelect/index.d.ts +3 -0
- package/dist/esm/components/FieldSelect/index.js +3 -0
- package/dist/esm/components/FieldSelect/styles.module.css +92 -0
- package/dist/esm/components/FieldSelect/types.d.ts +197 -0
- package/dist/esm/components/FieldSelect/types.js +1 -0
- package/dist/esm/components/FieldSelect/utils.d.ts +19 -0
- package/dist/esm/components/FieldSelect/utils.js +93 -0
- package/dist/esm/components/FieldSlider/FieldSlider.d.ts +92 -0
- package/dist/esm/components/FieldSlider/FieldSlider.js +190 -0
- package/dist/esm/components/FieldSlider/index.d.ts +2 -0
- package/dist/esm/components/FieldSlider/index.js +2 -0
- package/dist/esm/components/FieldSlider/styles.module.css +44 -0
- package/dist/esm/components/FieldSlider/types.d.ts +4 -0
- package/dist/esm/components/FieldSlider/types.js +1 -0
- package/dist/esm/components/FieldSlider/utils/generateAllowedValues.d.ts +1 -0
- package/dist/esm/components/FieldSlider/utils/generateAllowedValues.js +13 -0
- package/dist/esm/components/FieldSlider/utils/getClosestMark.d.ts +4 -0
- package/dist/esm/components/FieldSlider/utils/getClosestMark.js +13 -0
- package/dist/esm/components/FieldSlider/utils/getMarkLabel.d.ts +2 -0
- package/dist/esm/components/FieldSlider/utils/getMarkLabel.js +4 -0
- package/dist/esm/components/FieldSlider/utils/getTextFieldValue.d.ts +2 -0
- package/dist/esm/components/FieldSlider/utils/getTextFieldValue.js +6 -0
- package/dist/esm/components/FieldSlider/utils/index.d.ts +5 -0
- package/dist/esm/components/FieldSlider/utils/index.js +5 -0
- package/dist/esm/components/FieldSlider/utils/isMarkObject.d.ts +6 -0
- package/dist/esm/components/FieldSlider/utils/isMarkObject.js +3 -0
- package/dist/esm/components/FieldStepper/FieldStepper.d.ts +81 -0
- package/dist/esm/components/FieldStepper/FieldStepper.js +154 -0
- package/dist/esm/components/FieldStepper/index.d.ts +1 -0
- package/dist/esm/components/FieldStepper/index.js +1 -0
- package/dist/esm/components/FieldStepper/styles.module.css +78 -0
- package/dist/esm/components/FieldStepper/utils.d.ts +14 -0
- package/dist/esm/components/FieldStepper/utils.js +38 -0
- package/dist/esm/components/FieldText/FieldText.d.ts +11 -0
- package/dist/esm/components/FieldText/FieldText.js +11 -0
- package/dist/esm/components/FieldText/index.d.ts +1 -0
- package/dist/esm/components/FieldText/index.js +1 -0
- package/dist/esm/components/FieldTextArea/FieldTextArea.d.ts +95 -0
- package/dist/esm/components/FieldTextArea/FieldTextArea.js +108 -0
- package/dist/esm/components/FieldTextArea/index.d.ts +1 -0
- package/dist/esm/components/FieldTextArea/index.js +1 -0
- package/dist/esm/components/FieldTextArea/styles.module.css +123 -0
- package/dist/esm/components/FieldTime/FieldTime.d.ts +74 -0
- package/dist/esm/components/FieldTime/FieldTime.js +161 -0
- package/dist/esm/components/FieldTime/index.d.ts +2 -0
- package/dist/esm/components/FieldTime/index.js +1 -0
- package/dist/esm/components/FieldTime/mask.d.ts +3 -0
- package/dist/esm/components/FieldTime/mask.js +20 -0
- package/dist/esm/components/FieldTime/styles.module.css +3 -0
- package/dist/esm/components/index.d.ts +14 -0
- package/dist/esm/components/index.js +12 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButton.d.ts +35 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButton.js +41 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.d.ts +26 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.js +21 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/constants.d.ts +9 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/constants.js +9 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/index.d.ts +4 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/index.js +4 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/styles.module.css +204 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/types.d.ts +4 -0
- package/dist/esm/components/shared/helperComponents/FieldElementButton/types.js +1 -0
- package/dist/esm/components/shared/helperComponents/FieldShell/FieldShell.d.ts +43 -0
- package/dist/esm/components/shared/helperComponents/FieldShell/FieldShell.js +16 -0
- package/dist/esm/components/shared/helperComponents/FieldShell/index.d.ts +1 -0
- package/dist/esm/components/shared/helperComponents/FieldShell/index.js +1 -0
- package/dist/esm/components/shared/helperComponents/FieldShell/styles.module.css +11 -0
- package/dist/esm/components/shared/hooks/useCopyButton.d.ts +20 -0
- package/dist/esm/components/shared/hooks/useCopyButton.js +55 -0
- package/dist/esm/components/shared/index.d.ts +4 -0
- package/dist/esm/components/shared/index.js +4 -0
- package/dist/esm/components/shared/styles.module.css +673 -0
- package/dist/esm/components/shared/utils.d.ts +69 -0
- package/dist/esm/components/shared/utils.js +91 -0
- package/dist/esm/constants.d.ts +61 -0
- package/dist/esm/constants.js +73 -0
- package/dist/esm/hooks/index.d.ts +1 -0
- package/dist/esm/hooks/index.js +1 -0
- package/dist/esm/hooks/useAdaptiveAutoFocus.d.ts +7 -0
- package/dist/esm/hooks/useAdaptiveAutoFocus.js +7 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/segments/index.d.ts +2 -0
- package/dist/esm/segments/index.js +2 -0
- package/dist/esm/segments/segments.d.ts +22 -0
- package/dist/esm/segments/segments.js +43 -0
- package/dist/esm/segments/useSegmentedMask.d.ts +43 -0
- package/dist/esm/segments/useSegmentedMask.js +279 -0
- package/dist/esm/style.css +1350 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/package.json +62 -0
- package/src/components/FieldColor/FieldColor.tsx +426 -0
- package/src/components/FieldColor/index.ts +1 -0
- package/src/components/FieldColor/styles.module.scss +120 -0
- package/src/components/FieldColor/utils.ts +17 -0
- package/src/components/FieldCombo/FieldCombo.tsx +495 -0
- package/src/components/FieldCombo/index.ts +1 -0
- package/src/components/FieldDate/FieldDate.tsx +658 -0
- package/src/components/FieldDate/constants.ts +11 -0
- package/src/components/FieldDate/index.ts +3 -0
- package/src/components/FieldDate/mask.ts +123 -0
- package/src/components/FieldDate/styles.module.scss +56 -0
- package/src/components/FieldDate/types.ts +124 -0
- package/src/components/FieldDate/utils.ts +7 -0
- package/src/components/FieldSecure/FieldSecure.tsx +398 -0
- package/src/components/FieldSecure/index.ts +1 -0
- package/src/components/FieldSelect/FieldSelect.tsx +689 -0
- package/src/components/FieldSelect/constants.ts +4 -0
- package/src/components/FieldSelect/index.ts +3 -0
- package/src/components/FieldSelect/styles.module.scss +104 -0
- package/src/components/FieldSelect/types.ts +212 -0
- package/src/components/FieldSelect/utils.ts +134 -0
- package/src/components/FieldSlider/FieldSlider.tsx +502 -0
- package/src/components/FieldSlider/index.ts +2 -0
- package/src/components/FieldSlider/styles.module.scss +47 -0
- package/src/components/FieldSlider/types.ts +5 -0
- package/src/components/FieldSlider/utils/generateAllowedValues.ts +13 -0
- package/src/components/FieldSlider/utils/getClosestMark.ts +21 -0
- package/src/components/FieldSlider/utils/getMarkLabel.ts +7 -0
- package/src/components/FieldSlider/utils/getTextFieldValue.ts +8 -0
- package/src/components/FieldSlider/utils/index.ts +5 -0
- package/src/components/FieldSlider/utils/isMarkObject.ts +7 -0
- package/src/components/FieldStepper/FieldStepper.tsx +457 -0
- package/src/components/FieldStepper/index.ts +1 -0
- package/src/components/FieldStepper/styles.module.scss +98 -0
- package/src/components/FieldStepper/utils.ts +44 -0
- package/src/components/FieldText/FieldText.tsx +27 -0
- package/src/components/FieldText/index.ts +1 -0
- package/src/components/FieldTextArea/FieldTextArea.tsx +374 -0
- package/src/components/FieldTextArea/index.ts +1 -0
- package/src/components/FieldTextArea/styles.module.scss +192 -0
- package/src/components/FieldTime/FieldTime.tsx +401 -0
- package/src/components/FieldTime/index.ts +2 -0
- package/src/components/FieldTime/mask.ts +22 -0
- package/src/components/FieldTime/styles.module.scss +3 -0
- package/src/components/index.ts +14 -0
- package/src/components/shared/helperComponents/FieldElementButton/FieldElementButton.tsx +127 -0
- package/src/components/shared/helperComponents/FieldElementButton/FieldElementButtonList.tsx +72 -0
- package/src/components/shared/helperComponents/FieldElementButton/constants.ts +10 -0
- package/src/components/shared/helperComponents/FieldElementButton/index.ts +4 -0
- package/src/components/shared/helperComponents/FieldElementButton/styles.module.scss +137 -0
- package/src/components/shared/helperComponents/FieldElementButton/types.ts +6 -0
- package/src/components/shared/helperComponents/FieldShell/FieldShell.tsx +100 -0
- package/src/components/shared/helperComponents/FieldShell/index.ts +1 -0
- package/src/components/shared/helperComponents/FieldShell/styles.module.scss +13 -0
- package/src/components/shared/hooks/useCopyButton.tsx +103 -0
- package/src/components/shared/index.ts +4 -0
- package/src/components/shared/styles.module.scss +409 -0
- package/src/components/shared/utils.ts +128 -0
- package/src/constants.ts +73 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAdaptiveAutoFocus.ts +16 -0
- package/src/index.ts +3 -0
- package/src/segments/index.ts +2 -0
- package/src/segments/segments.ts +74 -0
- package/src/segments/useSegmentedMask.ts +361 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { DATE_MODE } from './constants';
|
|
2
|
+
|
|
3
|
+
/** Маска поддерживает только `date` / `date-time` (range собирается из двух одиночных масок). */
|
|
4
|
+
export type MaskMode = typeof DATE_MODE.Date | typeof DATE_MODE.DateTime;
|
|
5
|
+
|
|
6
|
+
const DATE_LEN = 8;
|
|
7
|
+
const DATE_TIME_LEN = 12;
|
|
8
|
+
const DATE_TIME_SECONDS_LEN = 14;
|
|
9
|
+
|
|
10
|
+
// Плейсхолдер по умолчанию — RU (ДД.ММ.ГГГГ), как в легаси @snack-uikit/fields и Figma.
|
|
11
|
+
// Структура парсинга остаётся числовой (DD/MM/YYYY[/HH/mm/ss]) — плейсхолдер только визуальный.
|
|
12
|
+
const RU_DATE = 'ДД.ММ.ГГГГ';
|
|
13
|
+
// Время отделяется запятой (паритет с легаси `ДД.ММ.ГГГГ, чч:мм:сс`).
|
|
14
|
+
const TIME_SEPARATOR = ', ';
|
|
15
|
+
|
|
16
|
+
function totalLen(mode: MaskMode, showSeconds: boolean): number {
|
|
17
|
+
if (mode === DATE_MODE.Date) {
|
|
18
|
+
return DATE_LEN;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return showSeconds ? DATE_TIME_SECONDS_LEN : DATE_TIME_LEN;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getMaskString(mode: MaskMode, showSeconds = true): string {
|
|
25
|
+
if (mode === DATE_MODE.Date) {
|
|
26
|
+
return RU_DATE;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return showSeconds ? `${RU_DATE}${TIME_SEPARATOR}чч:мм:сс` : `${RU_DATE}${TIME_SEPARATOR}чч:мм`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type Segment = { len: number; max: number; separator: string };
|
|
33
|
+
|
|
34
|
+
function buildSegments(mode: MaskMode, showSeconds: boolean): Segment[] {
|
|
35
|
+
const base: Segment[] = [
|
|
36
|
+
{ len: 2, max: 31, separator: '' }, // day
|
|
37
|
+
{ len: 2, max: 12, separator: '.' }, // month
|
|
38
|
+
{ len: 4, max: 9999, separator: '.' }, // year
|
|
39
|
+
];
|
|
40
|
+
if (mode === DATE_MODE.DateTime) {
|
|
41
|
+
base.push({ len: 2, max: 23, separator: TIME_SEPARATOR }); // hour
|
|
42
|
+
base.push({ len: 2, max: 59, separator: ':' }); // minute
|
|
43
|
+
if (showSeconds) {
|
|
44
|
+
base.push({ len: 2, max: 59, separator: ':' }); // second
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return base;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Принимает любую строку, оставляет только цифры и форматирует под `DD.MM.YYYY[, HH:mm[:ss]]`.
|
|
52
|
+
*
|
|
53
|
+
* Две UX-механики, призванные не дать пользователю набрать невалидный сегмент:
|
|
54
|
+
* 1. **Авто-prefix `0`**: если первая цифра 2-цифрового сегмента превышает максимально допустимую
|
|
55
|
+
* «десятку» (`day` → > 3, `month` → > 1, `hour` → > 2, `minute`/`second` → > 5), цифра трактуется
|
|
56
|
+
* как «единицы» и в начало сегмента добавляется ноль. Пример: `5` для day → `05.`,
|
|
57
|
+
* фокус автоматически уезжает на следующий сегмент.
|
|
58
|
+
* 2. **Clamp полной двойки**: если набрано две цифры и значение превышает `max` сегмента —
|
|
59
|
+
* значение прижимается к верхней границе. Пример: `55` для day → `31`, `99` для month → `12`.
|
|
60
|
+
*/
|
|
61
|
+
export function formatMask(input: string, mode: MaskMode, showSeconds = true): string {
|
|
62
|
+
const maxLen = totalLen(mode, showSeconds);
|
|
63
|
+
const segments = buildSegments(mode, showSeconds);
|
|
64
|
+
let stream = input.replace(/\D/g, '').slice(0, maxLen);
|
|
65
|
+
let out = '';
|
|
66
|
+
for (const seg of segments) {
|
|
67
|
+
if (stream.length === 0) break;
|
|
68
|
+
out += seg.separator;
|
|
69
|
+
// Auto-zero-prefix: если первая цифра > floor(max/10), сегмент не может начаться этой цифрой —
|
|
70
|
+
// считаем её цифрой «единиц» и дописываем `0` перед ней.
|
|
71
|
+
if (seg.len === 2) {
|
|
72
|
+
const first = Number(stream[0]);
|
|
73
|
+
const firstMax = Math.floor(seg.max / 10);
|
|
74
|
+
if (first > firstMax) {
|
|
75
|
+
out += `0${stream[0]}`;
|
|
76
|
+
stream = stream.slice(1);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const raw = stream.slice(0, seg.len);
|
|
81
|
+
stream = stream.slice(seg.len);
|
|
82
|
+
if (raw.length === seg.len) {
|
|
83
|
+
const n = Number(raw);
|
|
84
|
+
out += n > seg.max ? String(seg.max).padStart(seg.len, '0') : raw;
|
|
85
|
+
} else {
|
|
86
|
+
out += raw;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Парсит `DD.MM.YYYY` или `DD.MM.YYYY, HH:mm[:ss]` в `Date`. Возвращает `undefined` при невалидной/неполной строке. */
|
|
93
|
+
export function parseMask(input: string, mode: MaskMode, showSeconds = true): Date | undefined {
|
|
94
|
+
const digits = input.replace(/\D/g, '');
|
|
95
|
+
const expected = totalLen(mode, showSeconds);
|
|
96
|
+
if (digits.length !== expected) return undefined;
|
|
97
|
+
|
|
98
|
+
const day = Number(digits.slice(0, 2));
|
|
99
|
+
const month = Number(digits.slice(2, 4)) - 1;
|
|
100
|
+
const year = Number(digits.slice(4, 8));
|
|
101
|
+
const hour = mode === DATE_MODE.DateTime ? Number(digits.slice(8, 10)) : 0;
|
|
102
|
+
const minute = mode === DATE_MODE.DateTime ? Number(digits.slice(10, 12)) : 0;
|
|
103
|
+
const second = mode === DATE_MODE.DateTime && showSeconds ? Number(digits.slice(12, 14)) : 0;
|
|
104
|
+
|
|
105
|
+
if (year < 1 || month < 0 || month > 11 || day < 1 || day > 31) return undefined;
|
|
106
|
+
if (hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59) return undefined;
|
|
107
|
+
|
|
108
|
+
const d = new Date(year, month, day, hour, minute, second);
|
|
109
|
+
// Отбраковать «перетекание» вроде 30 февраля → 2 марта.
|
|
110
|
+
if (d.getDate() !== day || d.getMonth() !== month || d.getFullYear() !== year) return undefined;
|
|
111
|
+
return d;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Форматирует `Date` в строку под маску — для синхронизации с input при внешнем onChange. */
|
|
115
|
+
export function dateToMaskString(value: Date, mode: MaskMode, showSeconds = true): string {
|
|
116
|
+
const pad = (n: number) => String(n).padStart(2, '0');
|
|
117
|
+
const head = `${pad(value.getDate())}.${pad(value.getMonth() + 1)}.${value.getFullYear()}`;
|
|
118
|
+
if (mode !== DATE_MODE.DateTime) {
|
|
119
|
+
return head;
|
|
120
|
+
}
|
|
121
|
+
const time = `${pad(value.getHours())}:${pad(value.getMinutes())}${showSeconds ? `:${pad(value.getSeconds())}` : ''}`;
|
|
122
|
+
return `${head}${TIME_SEPARATOR}${time}`;
|
|
123
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/field.module' as field;
|
|
3
|
+
|
|
4
|
+
$sizes: 's', 'm', 'l';
|
|
5
|
+
|
|
6
|
+
.trigger {
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
|
|
9
|
+
&[data-disabled='true'] {
|
|
10
|
+
cursor: not-allowed;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&[data-readonly='true'] {
|
|
14
|
+
cursor: default;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.rangeInputs {
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
flex: 1 1 0;
|
|
21
|
+
align-items: center;
|
|
22
|
+
min-width: 0;
|
|
23
|
+
|
|
24
|
+
@each $size in $sizes {
|
|
25
|
+
[data-size='#{$size}'] & {
|
|
26
|
+
gap: base.simple-var(field.$field, 'anatomy', 'size', $size, 'fieldContainer', 'contentWrapper', 'inputLine', 'gap');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// From-инпут периода прижат к первой дате слева, разделитель идёт сразу за ним,
|
|
32
|
+
// to-инпут (flex: 1 1 0) забирает остаток.
|
|
33
|
+
// Fallback: ширина резервируется по длине маски (--field-date-mask-ch — длина placeholderMask,
|
|
34
|
+
// пробрасывается компонентом на .rangeInputs) в ch (масштабируется со шрифтом, без px-хардкода).
|
|
35
|
+
// ch считается по моноширинному `0`, а реальные цифры/точки уже → остаётся небольшой хвост справа,
|
|
36
|
+
// но ввод идёт слева направо (естественно).
|
|
37
|
+
.rangeInputFrom {
|
|
38
|
+
flex: 0 0 auto;
|
|
39
|
+
width: calc(var(--field-date-mask-ch, 10) * 1ch);
|
|
40
|
+
text-align: start;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Где поддерживается field-sizing — инпут сам ужимается ровно по контенту: хвоста нет,
|
|
44
|
+
// разделитель прижат к дате, ввод по-прежнему слева направо. max-width страхует от переполнения.
|
|
45
|
+
@supports (field-sizing: content) {
|
|
46
|
+
.rangeInputFrom {
|
|
47
|
+
field-sizing: content;
|
|
48
|
+
width: auto;
|
|
49
|
+
max-width: calc(var(--field-date-mask-ch, 10) * 1ch);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.rangeSeparator {
|
|
54
|
+
flex-shrink: 0;
|
|
55
|
+
color: base.$sn-theme-color-available-version-textTertiary;
|
|
56
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { CalendarDropdownProps } from '@cloud-ru/ds-calendar';
|
|
2
|
+
import { FieldDecoratorProps, Size, ValidationState } from '@cloud-ru/ds-field-decorator';
|
|
3
|
+
import { ValueOf, WithSupportProps } from '@cloud-ru/ds-utils';
|
|
4
|
+
import { FocusEvent, ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
import { FieldLayoutPresets } from '../../hooks';
|
|
7
|
+
import { DATE_MODE } from './constants';
|
|
8
|
+
|
|
9
|
+
export type DateMode = ValueOf<typeof DATE_MODE>;
|
|
10
|
+
|
|
11
|
+
/** Значение одиночной даты/даты-времени. */
|
|
12
|
+
export type DateValue = Date | undefined;
|
|
13
|
+
|
|
14
|
+
/** Значение периода (`[from, to]`). */
|
|
15
|
+
export type DateRangeValue = [DateValue, DateValue];
|
|
16
|
+
|
|
17
|
+
type FieldDateDecoratorProps = Omit<FieldDecoratorProps, 'children' | 'validationState' | 'size'>;
|
|
18
|
+
|
|
19
|
+
type CalendarPassthrough = Pick<
|
|
20
|
+
CalendarDropdownProps,
|
|
21
|
+
| 'today'
|
|
22
|
+
| 'showHolidays'
|
|
23
|
+
| 'buildCellProps'
|
|
24
|
+
| 'locale'
|
|
25
|
+
| 'presets'
|
|
26
|
+
| 'placement'
|
|
27
|
+
| 'closeOnApply'
|
|
28
|
+
| 'closeOnPopstate'
|
|
29
|
+
| 'open'
|
|
30
|
+
| 'onOpenChange'
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
type CommonFieldDateProps = WithSupportProps<
|
|
34
|
+
FieldDateDecoratorProps &
|
|
35
|
+
CalendarPassthrough & {
|
|
36
|
+
/** Размер */
|
|
37
|
+
size?: Size;
|
|
38
|
+
/** Состояние валидации */
|
|
39
|
+
validationState?: ValidationState;
|
|
40
|
+
/** CSS-класс корня `FieldDecorator` */
|
|
41
|
+
className?: string;
|
|
42
|
+
/** CSS-класс оболочки поля */
|
|
43
|
+
fieldClassName?: string;
|
|
44
|
+
/** Placeholder в триггере, когда нет значения */
|
|
45
|
+
placeholder?: string;
|
|
46
|
+
/**
|
|
47
|
+
* `aria-label` поля начала периода (режим `date-range`).
|
|
48
|
+
* @default 'Начало периода'
|
|
49
|
+
*/
|
|
50
|
+
labelFrom?: string;
|
|
51
|
+
/**
|
|
52
|
+
* `aria-label` поля конца периода (режим `date-range`).
|
|
53
|
+
* @default 'Конец периода'
|
|
54
|
+
*/
|
|
55
|
+
labelTo?: string;
|
|
56
|
+
/** Иконка перед текстом (если не задано — `CalendarSVG`) */
|
|
57
|
+
iconBefore?: ReactNode;
|
|
58
|
+
/** Деактивировано */
|
|
59
|
+
disabled?: boolean;
|
|
60
|
+
/** Read-only режим */
|
|
61
|
+
readonly?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Фон поля (acrylic)
|
|
64
|
+
* @default true
|
|
65
|
+
*/
|
|
66
|
+
background?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Показывать кнопку очистки значения (✕). Активна, когда есть значение и поле не disabled/readonly.
|
|
69
|
+
* @default true
|
|
70
|
+
*/
|
|
71
|
+
showClearButton?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Показывать кнопку копирования значения (только при `readonly` и непустом значении).
|
|
74
|
+
* @default true
|
|
75
|
+
*/
|
|
76
|
+
showCopyButton?: boolean;
|
|
77
|
+
/** Колбек после копирования значения в буфер */
|
|
78
|
+
onCopyButtonClick?(): void;
|
|
79
|
+
/**
|
|
80
|
+
* Показывать секунды в режиме `date-time` (в маске и в выпадающем календаре).
|
|
81
|
+
* @default true
|
|
82
|
+
*/
|
|
83
|
+
showSeconds?: boolean;
|
|
84
|
+
/** HTML-атрибут `id` для input (и `for` у label) */
|
|
85
|
+
id?: string;
|
|
86
|
+
/** HTML-атрибут `name` для input */
|
|
87
|
+
name?: string;
|
|
88
|
+
/** Автофокус input при монтировании. На mobile выключается адаптивно (см. `layoutPresets`) */
|
|
89
|
+
autoFocus?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Переопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен
|
|
92
|
+
* (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`.
|
|
93
|
+
*/
|
|
94
|
+
layoutPresets?: FieldLayoutPresets;
|
|
95
|
+
/** Колбек фокуса input */
|
|
96
|
+
onFocus?(event: FocusEvent<HTMLInputElement>): void;
|
|
97
|
+
/** Колбек блюра input */
|
|
98
|
+
onBlur?(event: FocusEvent<HTMLInputElement>): void;
|
|
99
|
+
}
|
|
100
|
+
>;
|
|
101
|
+
|
|
102
|
+
export type FieldDateSingleProps = CommonFieldDateProps & {
|
|
103
|
+
/** Режим выбора даты. По умолчанию `'date'`. */
|
|
104
|
+
mode?: typeof DATE_MODE.Date | typeof DATE_MODE.DateTime;
|
|
105
|
+
/** Управляемое значение */
|
|
106
|
+
value?: DateValue;
|
|
107
|
+
/** Неуправляемое значение по умолчанию */
|
|
108
|
+
defaultValue?: DateValue;
|
|
109
|
+
/** Колбек смены значения */
|
|
110
|
+
onChange?(value: DateValue): void;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export type FieldDateRangeProps = CommonFieldDateProps & {
|
|
114
|
+
/** Режим выбора периода */
|
|
115
|
+
mode: typeof DATE_MODE.DateRange;
|
|
116
|
+
/** Управляемое значение */
|
|
117
|
+
value?: DateRangeValue;
|
|
118
|
+
/** Неуправляемое значение по умолчанию */
|
|
119
|
+
defaultValue?: DateRangeValue;
|
|
120
|
+
/** Колбек смены значения */
|
|
121
|
+
onChange?(value: DateRangeValue): void;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export type FieldDateProps = FieldDateSingleProps | FieldDateRangeProps;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DATE_MODE } from './constants';
|
|
2
|
+
import { FieldDateProps, FieldDateRangeProps } from './types';
|
|
3
|
+
|
|
4
|
+
/** Type-guard: режим выбора периода (range) против одиночной даты/даты-времени. */
|
|
5
|
+
export function isRange(props: FieldDateProps): props is FieldDateRangeProps {
|
|
6
|
+
return props.mode === DATE_MODE.DateRange;
|
|
7
|
+
}
|