@mailstep/design-system 0.10.7 → 0.11.1
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/package.json +1 -1
- package/ui/Blocks/ImageList/components/AddPhoto/constants.d.ts +2 -0
- package/ui/Blocks/ImageList/components/AddPhoto/constants.js +5 -0
- package/ui/Blocks/ImageList/components/AddPhoto/hooks/useImageUpload.d.ts +11 -0
- package/ui/Blocks/ImageList/components/AddPhoto/hooks/useImageUpload.js +34 -0
- package/ui/Blocks/ImageList/components/AddPhoto/index.d.ts +2 -2
- package/ui/Blocks/ImageList/components/AddPhoto/index.js +14 -22
- package/ui/Blocks/ImageList/components/AddPhoto/styles.d.ts +4 -0
- package/ui/Blocks/ImageList/components/AddPhoto/styles.js +13 -1
- package/ui/Blocks/Tabs/hooks/useTabs.d.ts +1 -1
- package/ui/Blocks/Tabs/hooks/useTabs.js +16 -4
- package/ui/Blocks/Tabs/index.d.ts +1 -1
- package/ui/Blocks/Tabs/types.d.ts +5 -1
- package/ui/Blocks/Tabs/utils/constants.d.ts +1 -0
- package/ui/Blocks/Tabs/utils/constants.js +4 -0
- package/ui/Blocks/Tabs/utils/getDefaultTab.d.ts +4 -0
- package/ui/Blocks/Tabs/utils/getDefaultTab.js +7 -0
- package/ui/Blocks/Tabs/utils/getInitialTab.d.ts +9 -0
- package/ui/Blocks/Tabs/utils/getInitialTab.js +12 -0
- package/ui/Blocks/Tabs/utils/index.d.ts +6 -0
- package/ui/Blocks/Tabs/utils/index.js +7 -0
- package/ui/Blocks/Tabs/utils/isSelectableTab.d.ts +8 -0
- package/ui/Blocks/Tabs/utils/isSelectableTab.js +7 -0
- package/ui/Blocks/Tabs/utils/readTabFromUrl.d.ts +8 -0
- package/ui/Blocks/Tabs/utils/readTabFromUrl.js +16 -0
- package/ui/Blocks/Tabs/utils/writeTabToUrl.d.ts +7 -0
- package/ui/Blocks/Tabs/utils/writeTabToUrl.js +10 -0
- package/ui/Elements/DatePicker/DatePicker.d.ts +1 -1
- package/ui/Elements/DatePicker/DatePicker.js +18 -25
- package/ui/Elements/DatePicker/Datetime/components/{Timepicker.d.ts → Timepicker/Timepicker.d.ts} +2 -2
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/Timepicker.js +181 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/constants.d.ts +5 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/constants.js +8 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/index.d.ts +1 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/index.js +2 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/styles.d.ts +3 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/styles.js +48 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/index.d.ts +3 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/index.js +4 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/padTime.d.ts +3 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/padTime.js +4 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/parseTimeField.d.ts +3 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/parseTimeField.js +8 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/sanitizeTimeField.d.ts +3 -0
- package/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/sanitizeTimeField.js +4 -0
- package/ui/Elements/DatePicker/Datetime/views/DaysView.js +2 -1
- package/ui/Elements/DatePicker/components/DatePickerInput/DatePickerInput.d.ts +15 -0
- package/ui/Elements/DatePicker/components/DatePickerInput/DatePickerInput.js +33 -0
- package/ui/Elements/DatePicker/components/DatePickerInput/index.d.ts +1 -0
- package/ui/Elements/DatePicker/components/DatePickerInput/index.js +2 -0
- package/ui/index.js +1 -1
- package/ui/Elements/DatePicker/Datetime/components/Timepicker.js +0 -168
package/package.json
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ChangeEvent } from 'react';
|
|
2
|
+
import { type ImageUploadProps } from '../../../types';
|
|
3
|
+
type Props = {
|
|
4
|
+
onImageUpload?: (props: ImageUploadProps) => Promise<void>;
|
|
5
|
+
};
|
|
6
|
+
type HookType = (props: Props) => {
|
|
7
|
+
handleImageUpload: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
8
|
+
hasInvalidFormat: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare const useImageUpload: HookType;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import "../constants.js";
|
|
2
|
+
import { useCallback, useState } from "react";
|
|
3
|
+
//#region packages/ui/Blocks/ImageList/components/AddPhoto/hooks/useImageUpload.ts
|
|
4
|
+
const useImageUpload = ({ onImageUpload }) => {
|
|
5
|
+
const [hasInvalidFormat, setHasInvalidFormat] = useState(false);
|
|
6
|
+
return {
|
|
7
|
+
handleImageUpload: useCallback((event) => {
|
|
8
|
+
const input = event.target;
|
|
9
|
+
const file = input?.files?.[0];
|
|
10
|
+
if (!file) {
|
|
11
|
+
setHasInvalidFormat(false);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (!file.type.startsWith("image/")) {
|
|
15
|
+
input.value = "";
|
|
16
|
+
setHasInvalidFormat(true);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
setHasInvalidFormat(false);
|
|
20
|
+
const reader = new FileReader();
|
|
21
|
+
reader.readAsDataURL(file);
|
|
22
|
+
reader.onload = async () => {
|
|
23
|
+
await onImageUpload?.({
|
|
24
|
+
base64image: reader.result?.split(",").pop(),
|
|
25
|
+
base64WithDataDeclaration: reader.result,
|
|
26
|
+
file
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}, [onImageUpload]),
|
|
30
|
+
hasInvalidFormat
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { useImageUpload };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
2
|
import { type ImageUploadProps } from '../../types';
|
|
3
|
-
|
|
3
|
+
type AddPhotoProps = {
|
|
4
4
|
onImageUpload?: (props: ImageUploadProps) => Promise<void>;
|
|
5
5
|
isDisabled?: boolean;
|
|
6
6
|
hasRemove?: boolean;
|
|
7
|
-
}
|
|
7
|
+
};
|
|
8
8
|
export declare const AddPhoto: FC<AddPhotoProps>;
|
|
9
9
|
export {};
|
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
import { AddPhoto as AddPhoto$1 } from "../../../../Elements/Icon/icons/AddPhoto.js";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import ErrorMessage from "../../../../Elements/ErrorMessage/ErrorMessage.js";
|
|
3
|
+
import "../../../../Elements/ErrorMessage/index.js";
|
|
4
|
+
import "./constants.js";
|
|
5
|
+
import { useImageUpload } from "./hooks/useImageUpload.js";
|
|
6
|
+
import { Container, ErrorWrapper, HiddenInput, Wrapper } from "./styles.js";
|
|
4
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
8
|
//#region packages/ui/Blocks/ImageList/components/AddPhoto/index.tsx
|
|
6
|
-
const IMAGE_MIME_PREFIX = "image/";
|
|
7
9
|
const AddPhoto = ({ onImageUpload, isDisabled, hasRemove }) => {
|
|
8
|
-
const handleImageUpload =
|
|
9
|
-
const input = event.target;
|
|
10
|
-
const file = input?.files?.[0];
|
|
11
|
-
if (!file?.type.startsWith(IMAGE_MIME_PREFIX)) {
|
|
12
|
-
input.value = "";
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const reader = new FileReader();
|
|
16
|
-
reader.readAsDataURL(file);
|
|
17
|
-
reader.onload = async () => {
|
|
18
|
-
await onImageUpload?.({
|
|
19
|
-
base64image: reader.result?.split(",").pop(),
|
|
20
|
-
base64WithDataDeclaration: reader.result,
|
|
21
|
-
file
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
}, [onImageUpload]);
|
|
10
|
+
const { handleImageUpload, hasInvalidFormat } = useImageUpload({ onImageUpload });
|
|
25
11
|
if (!onImageUpload) return null;
|
|
26
|
-
return /* @__PURE__ */ jsxs(Container, {
|
|
12
|
+
return /* @__PURE__ */ jsxs(Wrapper, { children: [/* @__PURE__ */ jsxs(Container, {
|
|
27
13
|
isDisabled,
|
|
28
14
|
hasRemove,
|
|
29
15
|
children: [/* @__PURE__ */ jsx(HiddenInput, {
|
|
@@ -36,7 +22,13 @@ const AddPhoto = ({ onImageUpload, isDisabled, hasRemove }) => {
|
|
|
36
22
|
width: "36",
|
|
37
23
|
height: "36"
|
|
38
24
|
})]
|
|
39
|
-
})
|
|
25
|
+
}), hasInvalidFormat && /* @__PURE__ */ jsx(ErrorWrapper, {
|
|
26
|
+
hasRemove,
|
|
27
|
+
children: /* @__PURE__ */ jsx(ErrorMessage, {
|
|
28
|
+
appearance: "inline",
|
|
29
|
+
children: "Unsupported file format"
|
|
30
|
+
})
|
|
31
|
+
})] });
|
|
40
32
|
};
|
|
41
33
|
//#endregion
|
|
42
34
|
export { AddPhoto };
|
|
@@ -3,3 +3,7 @@ export declare const Container: import("styled-components").StyledComponent<"div
|
|
|
3
3
|
hasRemove?: boolean;
|
|
4
4
|
}, never>;
|
|
5
5
|
export declare const HiddenInput: import("styled-components").StyledComponent<"input", import("@xstyled/styled-components").Theme, {}, never>;
|
|
6
|
+
export declare const Wrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
7
|
+
export declare const ErrorWrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {
|
|
8
|
+
hasRemove?: boolean;
|
|
9
|
+
}, never>;
|
|
@@ -26,5 +26,17 @@ const HiddenInput = styled$1.input`
|
|
|
26
26
|
height: 100%;
|
|
27
27
|
cursor: pointer;
|
|
28
28
|
`;
|
|
29
|
+
const Wrapper = styled$1.div`
|
|
30
|
+
position: relative;
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
`;
|
|
33
|
+
const ErrorWrapper = styled$1.div`
|
|
34
|
+
position: absolute;
|
|
35
|
+
top: ${({ hasRemove }) => hasRemove ? "100px" : "85px"};
|
|
36
|
+
left: 0;
|
|
37
|
+
width: 85px;
|
|
38
|
+
line-height: 1.2;
|
|
39
|
+
text-align: center;
|
|
40
|
+
`;
|
|
29
41
|
//#endregion
|
|
30
|
-
export { Container, HiddenInput };
|
|
42
|
+
export { Container, ErrorWrapper, HiddenInput, Wrapper };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { UseTabsHook } from '../types';
|
|
1
|
+
import type { UseTabsHook } from '../types';
|
|
2
2
|
export declare const useTabs: UseTabsHook;
|
|
@@ -1,13 +1,25 @@
|
|
|
1
|
+
import "../utils/constants.js";
|
|
2
|
+
import { getInitialTab } from "../utils/getInitialTab.js";
|
|
3
|
+
import { writeTabToUrl } from "../utils/writeTabToUrl.js";
|
|
1
4
|
import { useCallback, useState } from "react";
|
|
2
5
|
//#region packages/ui/Blocks/Tabs/hooks/useTabs.ts
|
|
3
|
-
const useTabs = (
|
|
4
|
-
const
|
|
5
|
-
const [activeTab, setActiveTab] = useState(
|
|
6
|
+
const useTabs = (tabsDefinition, options = {}) => {
|
|
7
|
+
const { syncWithUrl = false, queryParam = "tab" } = options;
|
|
8
|
+
const [activeTab, setActiveTab] = useState(() => getInitialTab({
|
|
9
|
+
tabsDefinition,
|
|
10
|
+
syncWithUrl,
|
|
11
|
+
queryParam
|
|
12
|
+
}));
|
|
6
13
|
return {
|
|
7
14
|
activeTab,
|
|
8
15
|
onTabSwitch: useCallback((value) => {
|
|
9
16
|
setActiveTab(value);
|
|
10
|
-
|
|
17
|
+
if (!syncWithUrl) return;
|
|
18
|
+
writeTabToUrl({
|
|
19
|
+
value,
|
|
20
|
+
queryParam
|
|
21
|
+
});
|
|
22
|
+
}, [syncWithUrl, queryParam])
|
|
11
23
|
};
|
|
12
24
|
};
|
|
13
25
|
//#endregion
|
|
@@ -21,7 +21,11 @@ export type TabElementProps = {
|
|
|
21
21
|
onTabSwitch: (tab: number) => void;
|
|
22
22
|
minWidth?: string | string[];
|
|
23
23
|
};
|
|
24
|
-
export type
|
|
24
|
+
export type UseTabsOptions = {
|
|
25
|
+
syncWithUrl?: boolean;
|
|
26
|
+
queryParam?: string;
|
|
27
|
+
};
|
|
28
|
+
export type UseTabsHook = (tabsDefinition: TabDefinition[], options?: UseTabsOptions) => {
|
|
25
29
|
activeTab: number;
|
|
26
30
|
onTabSwitch: (tab: number) => void;
|
|
27
31
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TAB_PARAM = "tab";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TabDefinition } from '../types';
|
|
2
|
+
type GetInitialTabProps = {
|
|
3
|
+
tabsDefinition: TabDefinition[];
|
|
4
|
+
syncWithUrl: boolean;
|
|
5
|
+
queryParam: string;
|
|
6
|
+
};
|
|
7
|
+
type GetInitialTabType = (props: GetInitialTabProps) => number;
|
|
8
|
+
export declare const getInitialTab: GetInitialTabType;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getDefaultTab } from "./getDefaultTab.js";
|
|
2
|
+
import { readTabFromUrl } from "./readTabFromUrl.js";
|
|
3
|
+
//#region packages/ui/Blocks/Tabs/utils/getInitialTab.ts
|
|
4
|
+
const getInitialTab = ({ tabsDefinition, syncWithUrl, queryParam }) => {
|
|
5
|
+
if (!syncWithUrl) return getDefaultTab(tabsDefinition);
|
|
6
|
+
return readTabFromUrl({
|
|
7
|
+
tabsDefinition,
|
|
8
|
+
queryParam
|
|
9
|
+
}) ?? getDefaultTab(tabsDefinition);
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { getInitialTab };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { TAB_PARAM } from './constants';
|
|
2
|
+
export { getDefaultTab } from './getDefaultTab';
|
|
3
|
+
export { getInitialTab } from './getInitialTab';
|
|
4
|
+
export { isSelectableTab } from './isSelectableTab';
|
|
5
|
+
export { readTabFromUrl } from './readTabFromUrl';
|
|
6
|
+
export { writeTabToUrl } from './writeTabToUrl';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TAB_PARAM } from "./constants.js";
|
|
2
|
+
import { getDefaultTab } from "./getDefaultTab.js";
|
|
3
|
+
import { isSelectableTab } from "./isSelectableTab.js";
|
|
4
|
+
import { readTabFromUrl } from "./readTabFromUrl.js";
|
|
5
|
+
import { getInitialTab } from "./getInitialTab.js";
|
|
6
|
+
import { writeTabToUrl } from "./writeTabToUrl.js";
|
|
7
|
+
export { TAB_PARAM, getDefaultTab, getInitialTab, isSelectableTab, readTabFromUrl, writeTabToUrl };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TabDefinition } from '../types';
|
|
2
|
+
type IsSelectableTabProps = {
|
|
3
|
+
tabsDefinition: TabDefinition[];
|
|
4
|
+
value: number;
|
|
5
|
+
};
|
|
6
|
+
type IsSelectableTabType = (props: IsSelectableTabProps) => boolean;
|
|
7
|
+
export declare const isSelectableTab: IsSelectableTabType;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TabDefinition } from '../types';
|
|
2
|
+
type ReadTabFromUrlProps = {
|
|
3
|
+
tabsDefinition: TabDefinition[];
|
|
4
|
+
queryParam: string;
|
|
5
|
+
};
|
|
6
|
+
type ReadTabFromUrlType = (props: ReadTabFromUrlProps) => number | null;
|
|
7
|
+
export declare const readTabFromUrl: ReadTabFromUrlType;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { isSelectableTab } from "./isSelectableTab.js";
|
|
2
|
+
//#region packages/ui/Blocks/Tabs/utils/readTabFromUrl.ts
|
|
3
|
+
const readTabFromUrl = ({ tabsDefinition, queryParam }) => {
|
|
4
|
+
if (typeof window === "undefined") return null;
|
|
5
|
+
const raw = new URLSearchParams(window.location.search).get(queryParam);
|
|
6
|
+
if (raw === null || raw.trim() === "") return null;
|
|
7
|
+
const value = Number(raw);
|
|
8
|
+
if (!Number.isInteger(value)) return null;
|
|
9
|
+
if (!isSelectableTab({
|
|
10
|
+
tabsDefinition,
|
|
11
|
+
value
|
|
12
|
+
})) return null;
|
|
13
|
+
return value;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { readTabFromUrl };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region packages/ui/Blocks/Tabs/utils/writeTabToUrl.ts
|
|
2
|
+
const writeTabToUrl = ({ value, queryParam }) => {
|
|
3
|
+
if (typeof window === "undefined") return;
|
|
4
|
+
const url = new URL(window.location.href);
|
|
5
|
+
if (url.searchParams.get(queryParam) === String(value)) return;
|
|
6
|
+
url.searchParams.set(queryParam, String(value));
|
|
7
|
+
window.history.replaceState(null, "", `${url.pathname}${url.search}${url.hash}`);
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { writeTabToUrl };
|
|
@@ -22,7 +22,7 @@ export type DatePickerType = DatetimepickerProps & {
|
|
|
22
22
|
isSecondDatePicker?: boolean;
|
|
23
23
|
others?: DateTimeOthers;
|
|
24
24
|
onClear?: () => void;
|
|
25
|
-
onInputChange?: () => void;
|
|
25
|
+
onInputChange?: (value: string) => void;
|
|
26
26
|
onChangeOthers?: (others: DateTimeOthers) => void;
|
|
27
27
|
};
|
|
28
28
|
declare const _default: React.NamedExoticComponent<DatePickerType>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { LanguageContext } from "../../ThemeProvider/ThemeProvider.js";
|
|
2
2
|
import SpaceAround_default from "../SpaceAround/index.js";
|
|
3
|
-
import Input_default from "../../Forms/Input/index.js";
|
|
4
3
|
import Datetime from "./Datetime/DateTime.js";
|
|
4
|
+
import { DatePickerInput } from "./components/DatePickerInput/DatePickerInput.js";
|
|
5
|
+
import "./components/DatePickerInput/index.js";
|
|
5
6
|
import { DatePickerBase } from "./styles.js";
|
|
6
7
|
import React, { useCallback, useContext } from "react";
|
|
7
8
|
import { x } from "@xstyled/styled-components";
|
|
8
9
|
import { jsx } from "react/jsx-runtime";
|
|
9
|
-
import moment from "moment";
|
|
10
10
|
import "moment/dist/locale/cs";
|
|
11
11
|
import "moment/dist/locale/el";
|
|
12
12
|
import "moment/dist/locale/it";
|
|
@@ -15,34 +15,27 @@ import "moment/dist/locale/sk";
|
|
|
15
15
|
//#region packages/ui/Elements/DatePicker/DatePicker.tsx
|
|
16
16
|
const defaultDateFormat = "DD.MM.YYYY";
|
|
17
17
|
const DatePicker = ({ name, value, initialViewDate, error, label, disabled, isValidDate, onChange, dateFormat = defaultDateFormat, timeFormat = false, open, secondValue = null, input, icon = true, showInputLabel = false, showCalendarLabel = true, spaceAround = false, className, onClear, onInputChange, ...passProps }) => {
|
|
18
|
-
const format = `${dateFormat}${timeFormat ? ` ${timeFormat}` : ``}`;
|
|
19
|
-
const isValid = !!value && moment(value, format, true).isValid();
|
|
20
|
-
const stringValue = isValid ? moment(value, format).format(format) : value;
|
|
21
18
|
const locale = useContext(LanguageContext);
|
|
22
|
-
const handleRenderInput = useCallback((
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
icon: icon ? "calendar" : void 0,
|
|
26
|
-
name,
|
|
27
|
-
error,
|
|
28
|
-
disabled,
|
|
29
|
-
isInvalid: !!error,
|
|
30
|
-
onChange: onInputChange,
|
|
31
|
-
label: showInputLabel ? label : void 0,
|
|
32
|
-
value: stringValue,
|
|
33
|
-
onFocus: openCalendar,
|
|
34
|
-
iconOnClick: openCalendar,
|
|
35
|
-
onClear,
|
|
36
|
-
autoComplete: "off"
|
|
37
|
-
});
|
|
38
|
-
}, [
|
|
19
|
+
const handleRenderInput = useCallback((inputProps, openCalendar) => /* @__PURE__ */ jsx(DatePickerInput, {
|
|
20
|
+
inputProps,
|
|
21
|
+
openCalendar,
|
|
39
22
|
name,
|
|
40
|
-
|
|
23
|
+
label,
|
|
41
24
|
error,
|
|
25
|
+
disabled,
|
|
26
|
+
icon,
|
|
27
|
+
showInputLabel,
|
|
28
|
+
onClear,
|
|
29
|
+
onInputChange
|
|
30
|
+
}), [
|
|
31
|
+
name,
|
|
42
32
|
label,
|
|
33
|
+
error,
|
|
34
|
+
disabled,
|
|
35
|
+
icon,
|
|
43
36
|
showInputLabel,
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
onClear,
|
|
38
|
+
onInputChange
|
|
46
39
|
]);
|
|
47
40
|
const handleRenderView = useCallback((_, renderCalendar) => {
|
|
48
41
|
if (label && !showInputLabel) return /* @__PURE__ */ jsx(x.div, {
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import Icon from "../../../../Icon/Icon.js";
|
|
2
|
+
import { FooterRow } from "../FooterRow.js";
|
|
3
|
+
import { FooterRowLabel } from "../FooterRowLabel.js";
|
|
4
|
+
import "./constants.js";
|
|
5
|
+
import { TimeButton, TimeField, TimeWrapper } from "./styles.js";
|
|
6
|
+
import { padTime } from "./utils/padTime.js";
|
|
7
|
+
import { parseTimeField } from "./utils/parseTimeField.js";
|
|
8
|
+
import { sanitizeTimeField } from "./utils/sanitizeTimeField.js";
|
|
9
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
10
|
+
import { x } from "@xstyled/styled-components";
|
|
11
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { i18n } from "@lingui/core";
|
|
13
|
+
//#region packages/ui/Elements/DatePicker/Datetime/components/Timepicker/Timepicker.tsx
|
|
14
|
+
const Timepicker = ({ setTime, value, disabled }) => {
|
|
15
|
+
const hours = value?.getHours?.() ?? 0;
|
|
16
|
+
const minutes = value?.getMinutes?.() ?? 0;
|
|
17
|
+
const [hoursValue, setHoursValue] = useState(padTime(hours));
|
|
18
|
+
const [minutesValue, setMinutesValue] = useState(padTime(minutes));
|
|
19
|
+
const isHoursEdited = useRef(false);
|
|
20
|
+
const isMinutesEdited = useRef(false);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (isHoursEdited.current) return;
|
|
23
|
+
setHoursValue(padTime(hours));
|
|
24
|
+
}, [hours]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (isMinutesEdited.current) return;
|
|
27
|
+
setMinutesValue(padTime(minutes));
|
|
28
|
+
}, [minutes]);
|
|
29
|
+
const commitTime = useCallback((type, nextValue) => {
|
|
30
|
+
if (!value) return;
|
|
31
|
+
setTime(type, nextValue);
|
|
32
|
+
}, [setTime, value]);
|
|
33
|
+
const changeHours = useCallback((nextValue) => {
|
|
34
|
+
setHoursValue(padTime(nextValue));
|
|
35
|
+
commitTime("hours", nextValue);
|
|
36
|
+
}, [commitTime]);
|
|
37
|
+
const changeMinutes = useCallback((nextValue) => {
|
|
38
|
+
setMinutesValue(padTime(nextValue));
|
|
39
|
+
commitTime("minutes", nextValue);
|
|
40
|
+
}, [commitTime]);
|
|
41
|
+
const increaseHours = useCallback(() => {
|
|
42
|
+
changeHours((parseTimeField(hoursValue, hours) + 1) % 24);
|
|
43
|
+
}, [
|
|
44
|
+
changeHours,
|
|
45
|
+
hoursValue,
|
|
46
|
+
hours
|
|
47
|
+
]);
|
|
48
|
+
const decreaseHours = useCallback(() => {
|
|
49
|
+
changeHours((parseTimeField(hoursValue, hours) - 1 + 24) % 24);
|
|
50
|
+
}, [
|
|
51
|
+
changeHours,
|
|
52
|
+
hoursValue,
|
|
53
|
+
hours
|
|
54
|
+
]);
|
|
55
|
+
const increaseMinutes = useCallback(() => {
|
|
56
|
+
changeMinutes((parseTimeField(minutesValue, minutes) + 5) % 60);
|
|
57
|
+
}, [
|
|
58
|
+
changeMinutes,
|
|
59
|
+
minutesValue,
|
|
60
|
+
minutes
|
|
61
|
+
]);
|
|
62
|
+
const decreaseMinutes = useCallback(() => {
|
|
63
|
+
changeMinutes((parseTimeField(minutesValue, minutes) - 5 + 60) % 60);
|
|
64
|
+
}, [
|
|
65
|
+
changeMinutes,
|
|
66
|
+
minutesValue,
|
|
67
|
+
minutes
|
|
68
|
+
]);
|
|
69
|
+
const onHoursChange = useCallback((e) => {
|
|
70
|
+
const nextValue = sanitizeTimeField(e.target.value);
|
|
71
|
+
setHoursValue(nextValue);
|
|
72
|
+
const parsed = parseTimeField(nextValue, NaN);
|
|
73
|
+
if (Number.isNaN(parsed) || parsed > 23) return;
|
|
74
|
+
commitTime("hours", parsed);
|
|
75
|
+
}, [commitTime]);
|
|
76
|
+
const onMinutesChange = useCallback((e) => {
|
|
77
|
+
const nextValue = sanitizeTimeField(e.target.value);
|
|
78
|
+
setMinutesValue(nextValue);
|
|
79
|
+
const parsed = parseTimeField(nextValue, NaN);
|
|
80
|
+
if (Number.isNaN(parsed) || parsed > 59) return;
|
|
81
|
+
commitTime("minutes", parsed);
|
|
82
|
+
}, [commitTime]);
|
|
83
|
+
const onFieldClick = useCallback((e) => {
|
|
84
|
+
e.currentTarget.select();
|
|
85
|
+
}, []);
|
|
86
|
+
const onHoursFocus = useCallback((e) => {
|
|
87
|
+
isHoursEdited.current = true;
|
|
88
|
+
e.target.select();
|
|
89
|
+
}, []);
|
|
90
|
+
const onMinutesFocus = useCallback((e) => {
|
|
91
|
+
isMinutesEdited.current = true;
|
|
92
|
+
e.target.select();
|
|
93
|
+
}, []);
|
|
94
|
+
const onHoursBlur = useCallback(() => {
|
|
95
|
+
isHoursEdited.current = false;
|
|
96
|
+
const parsed = parseTimeField(hoursValue, NaN);
|
|
97
|
+
setHoursValue(padTime(!Number.isNaN(parsed) && parsed <= 23 ? parsed : hours));
|
|
98
|
+
}, [hoursValue, hours]);
|
|
99
|
+
const onMinutesBlur = useCallback(() => {
|
|
100
|
+
isMinutesEdited.current = false;
|
|
101
|
+
const parsed = parseTimeField(minutesValue, NaN);
|
|
102
|
+
setMinutesValue(padTime(!Number.isNaN(parsed) && parsed <= 59 ? parsed : minutes));
|
|
103
|
+
}, [minutesValue, minutes]);
|
|
104
|
+
return /* @__PURE__ */ jsxs(FooterRow, {
|
|
105
|
+
disabled,
|
|
106
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Icon, { icon: "clock" }), /* @__PURE__ */ jsx(FooterRowLabel, { children: i18n._({
|
|
107
|
+
id: "dataGrid.filterCell.time",
|
|
108
|
+
message: "Time"
|
|
109
|
+
}) })] }), /* @__PURE__ */ jsx(x.div, {
|
|
110
|
+
display: "flex",
|
|
111
|
+
flexDirection: "column",
|
|
112
|
+
alignItems: "flex-start",
|
|
113
|
+
pt: "4px",
|
|
114
|
+
w: "fit-content",
|
|
115
|
+
children: /* @__PURE__ */ jsxs(x.div, {
|
|
116
|
+
display: "flex",
|
|
117
|
+
alignItems: "center",
|
|
118
|
+
children: [
|
|
119
|
+
/* @__PURE__ */ jsxs(x.div, {
|
|
120
|
+
display: "flex",
|
|
121
|
+
flexDirection: "column",
|
|
122
|
+
children: [/* @__PURE__ */ jsx(TimeButton, {
|
|
123
|
+
disabled,
|
|
124
|
+
onClick: increaseHours,
|
|
125
|
+
type: "button",
|
|
126
|
+
children: "‹"
|
|
127
|
+
}), /* @__PURE__ */ jsx(TimeButton, {
|
|
128
|
+
disabled,
|
|
129
|
+
onClick: decreaseHours,
|
|
130
|
+
type: "button",
|
|
131
|
+
children: "›"
|
|
132
|
+
})]
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ jsxs(TimeWrapper, { children: [
|
|
135
|
+
/* @__PURE__ */ jsx(TimeField, {
|
|
136
|
+
value: hoursValue,
|
|
137
|
+
disabled,
|
|
138
|
+
inputMode: "numeric",
|
|
139
|
+
maxLength: 2,
|
|
140
|
+
onChange: onHoursChange,
|
|
141
|
+
onFocus: onHoursFocus,
|
|
142
|
+
onClick: onFieldClick,
|
|
143
|
+
onBlur: onHoursBlur
|
|
144
|
+
}),
|
|
145
|
+
/* @__PURE__ */ jsx(x.div, {
|
|
146
|
+
mx: "1px",
|
|
147
|
+
children: ":"
|
|
148
|
+
}),
|
|
149
|
+
/* @__PURE__ */ jsx(TimeField, {
|
|
150
|
+
value: minutesValue,
|
|
151
|
+
disabled,
|
|
152
|
+
inputMode: "numeric",
|
|
153
|
+
maxLength: 2,
|
|
154
|
+
onChange: onMinutesChange,
|
|
155
|
+
onFocus: onMinutesFocus,
|
|
156
|
+
onClick: onFieldClick,
|
|
157
|
+
onBlur: onMinutesBlur
|
|
158
|
+
})
|
|
159
|
+
] }),
|
|
160
|
+
/* @__PURE__ */ jsxs(x.div, {
|
|
161
|
+
display: "flex",
|
|
162
|
+
flexDirection: "column",
|
|
163
|
+
children: [/* @__PURE__ */ jsx(TimeButton, {
|
|
164
|
+
disabled,
|
|
165
|
+
onClick: increaseMinutes,
|
|
166
|
+
type: "button",
|
|
167
|
+
children: "‹"
|
|
168
|
+
}), /* @__PURE__ */ jsx(TimeButton, {
|
|
169
|
+
disabled,
|
|
170
|
+
onClick: decreaseMinutes,
|
|
171
|
+
type: "button",
|
|
172
|
+
children: "›"
|
|
173
|
+
})]
|
|
174
|
+
})
|
|
175
|
+
]
|
|
176
|
+
})
|
|
177
|
+
})]
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
//#endregion
|
|
181
|
+
export { Timepicker };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region packages/ui/Elements/DatePicker/Datetime/components/Timepicker/constants.ts
|
|
2
|
+
const HOURS_COUNT = 24;
|
|
3
|
+
const MINUTES_COUNT = 60;
|
|
4
|
+
const MINUTES_STEP = 5;
|
|
5
|
+
const MAX_HOURS = 23;
|
|
6
|
+
const MAX_MINUTES = 59;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { HOURS_COUNT, MAX_HOURS, MAX_MINUTES, MINUTES_COUNT, MINUTES_STEP };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Timepicker } from './Timepicker';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const TimeButton: import("styled-components").StyledComponent<"button", import("@xstyled/styled-components").Theme, {}, never>;
|
|
2
|
+
export declare const TimeWrapper: import("styled-components").StyledComponent<"div", import("@xstyled/styled-components").Theme, {}, never>;
|
|
3
|
+
export declare const TimeField: import("styled-components").StyledComponent<"input", import("@xstyled/styled-components").Theme, {}, never>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import styled$1 from "@xstyled/styled-components";
|
|
2
|
+
import { th as th$1 } from "@xstyled/system";
|
|
3
|
+
//#region packages/ui/Elements/DatePicker/Datetime/components/Timepicker/styles.ts
|
|
4
|
+
const TimeButton = styled$1.button`
|
|
5
|
+
transform: rotate(90deg);
|
|
6
|
+
font-size: 20px;
|
|
7
|
+
line-height: 1;
|
|
8
|
+
margin: -3px 0;
|
|
9
|
+
padding: 0;
|
|
10
|
+
background-color: transparent !important;
|
|
11
|
+
border: none;
|
|
12
|
+
color: ${th$1("colors.lightGray4")};
|
|
13
|
+
&:disabled:hover {
|
|
14
|
+
color: ${th$1("colors.lightGray4")};
|
|
15
|
+
cursor: default;
|
|
16
|
+
}
|
|
17
|
+
&:hover {
|
|
18
|
+
color: ${th$1("colors.red2")};
|
|
19
|
+
background-color: transparent !important;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
const TimeWrapper = styled$1.div`
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: baseline;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
border: 1px solid ${th$1("colors.lightGray2")};
|
|
27
|
+
border-radius: 6px;
|
|
28
|
+
padding: 3px 8px;
|
|
29
|
+
margin: 0 4px;
|
|
30
|
+
`;
|
|
31
|
+
const TimeField = styled$1.input`
|
|
32
|
+
font-size: 16px;
|
|
33
|
+
font-weight: 600;
|
|
34
|
+
line-height: 20px;
|
|
35
|
+
width: 24px;
|
|
36
|
+
text-align: center;
|
|
37
|
+
margin: 0;
|
|
38
|
+
padding: 0;
|
|
39
|
+
border: none;
|
|
40
|
+
outline: none;
|
|
41
|
+
background-color: transparent;
|
|
42
|
+
color: ${th$1("colors.blue2")};
|
|
43
|
+
&:disabled {
|
|
44
|
+
opacity: 0.5;
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { TimeButton, TimeField, TimeWrapper };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region packages/ui/Elements/DatePicker/Datetime/components/Timepicker/utils/parseTimeField.ts
|
|
2
|
+
const parseTimeField = (text, fallback) => {
|
|
3
|
+
if (text === "") return fallback;
|
|
4
|
+
const parsed = Number(text);
|
|
5
|
+
return Number.isNaN(parsed) ? fallback : parsed;
|
|
6
|
+
};
|
|
7
|
+
//#endregion
|
|
8
|
+
export { parseTimeField };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DateRepeater } from "../components/DateRepeater.js";
|
|
2
|
-
import { Timepicker } from "../components/Timepicker.js";
|
|
2
|
+
import { Timepicker } from "../components/Timepicker/Timepicker.js";
|
|
3
|
+
import "../components/Timepicker/index.js";
|
|
3
4
|
import ViewNavigation from "../components/ViewNavigation.js";
|
|
4
5
|
import React from "react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type FC, type InputHTMLAttributes } from 'react';
|
|
2
|
+
type DatePickerInputProps = {
|
|
3
|
+
inputProps: InputHTMLAttributes<HTMLInputElement>;
|
|
4
|
+
openCalendar: () => void;
|
|
5
|
+
name?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
icon?: boolean;
|
|
10
|
+
showInputLabel?: boolean;
|
|
11
|
+
onClear?: () => void;
|
|
12
|
+
onInputChange?: (value: string) => void;
|
|
13
|
+
};
|
|
14
|
+
export declare const DatePickerInput: FC<DatePickerInputProps>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import Input_default from "../../../../Forms/Input/index.js";
|
|
2
|
+
import { useCallback, useState } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region packages/ui/Elements/DatePicker/components/DatePickerInput/DatePickerInput.tsx
|
|
5
|
+
const DatePickerInput = ({ inputProps, openCalendar, name, label, error, disabled, icon, showInputLabel, onClear, onInputChange }) => {
|
|
6
|
+
const [typedValue, setTypedValue] = useState(null);
|
|
7
|
+
const handleChange = useCallback((e) => {
|
|
8
|
+
setTypedValue(e.target.value);
|
|
9
|
+
inputProps.onChange?.(e);
|
|
10
|
+
onInputChange?.(e.target.value);
|
|
11
|
+
}, [inputProps, onInputChange]);
|
|
12
|
+
const handleBlur = useCallback(() => {
|
|
13
|
+
setTypedValue(null);
|
|
14
|
+
}, []);
|
|
15
|
+
return /* @__PURE__ */ jsx(Input_default, {
|
|
16
|
+
type: "text",
|
|
17
|
+
icon: icon ? "calendar" : void 0,
|
|
18
|
+
name,
|
|
19
|
+
error,
|
|
20
|
+
disabled,
|
|
21
|
+
isInvalid: !!error,
|
|
22
|
+
onChange: handleChange,
|
|
23
|
+
onBlur: handleBlur,
|
|
24
|
+
label: showInputLabel ? label : void 0,
|
|
25
|
+
value: typedValue ?? inputProps.value,
|
|
26
|
+
onFocus: openCalendar,
|
|
27
|
+
iconOnClick: openCalendar,
|
|
28
|
+
onClear,
|
|
29
|
+
autoComplete: "off"
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { DatePickerInput };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DatePickerInput } from './DatePickerInput';
|
package/ui/index.js
CHANGED
|
@@ -133,8 +133,8 @@ import SpaceAroundWrap from "./Elements/SpaceAround/SpaceAround.js";
|
|
|
133
133
|
import SpaceAround_default from "./Elements/SpaceAround/index.js";
|
|
134
134
|
import Select_default from "./Elements/Select/index.js";
|
|
135
135
|
import SingleSelect_default from "./Elements/SingleSelect/index.js";
|
|
136
|
-
import Input_default from "./Forms/Input/index.js";
|
|
137
136
|
import { DatePickerRepeat, TimePickerRepeat } from "./Elements/DatePicker/Datetime/types.js";
|
|
137
|
+
import Input_default from "./Forms/Input/index.js";
|
|
138
138
|
import DatePicker_default from "./Elements/DatePicker/index.js";
|
|
139
139
|
import { useEvent } from "./Blocks/CommonGrid/hooks/useEvent.js";
|
|
140
140
|
import { useAddFilter } from "./Blocks/CommonGrid/hooks/useAddFilter.js";
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import Icon from "../../../Icon/Icon.js";
|
|
2
|
-
import { FooterRow } from "./FooterRow.js";
|
|
3
|
-
import { FooterRowLabel } from "./FooterRowLabel.js";
|
|
4
|
-
import { useCallback, useEffect, useState } from "react";
|
|
5
|
-
import styled$1, { x } from "@xstyled/styled-components";
|
|
6
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
import { th as th$1 } from "@xstyled/system";
|
|
8
|
-
import { i18n } from "@lingui/core";
|
|
9
|
-
//#region packages/ui/Elements/DatePicker/Datetime/components/Timepicker.tsx
|
|
10
|
-
const Btn = styled$1.button`
|
|
11
|
-
transform: rotate(90deg);
|
|
12
|
-
font-size: 18px;
|
|
13
|
-
margin: -4px 0;
|
|
14
|
-
background-color: transparent !important;
|
|
15
|
-
border: none;
|
|
16
|
-
color: ${th$1("colors.lightGray4")};
|
|
17
|
-
&:disabled:hover {
|
|
18
|
-
color: ${th$1("colors.lightGray4")};
|
|
19
|
-
cursor: default;
|
|
20
|
-
}
|
|
21
|
-
&:hover {
|
|
22
|
-
color: ${th$1("colors.red2")};
|
|
23
|
-
background-color: transparent !important;
|
|
24
|
-
}
|
|
25
|
-
`;
|
|
26
|
-
const TimeWrapper = styled$1.div`
|
|
27
|
-
display: flex;
|
|
28
|
-
align-items: baseline;
|
|
29
|
-
justify-content: center;
|
|
30
|
-
border: 1px solid ${th$1("colors.lightGray2")};
|
|
31
|
-
border-radius: 6px;
|
|
32
|
-
padding: 0 4px;
|
|
33
|
-
margin: 0 4px;
|
|
34
|
-
`;
|
|
35
|
-
const Hours = styled$1.input`
|
|
36
|
-
font-size: 14px;
|
|
37
|
-
font-weight: 600;
|
|
38
|
-
width: 17px;
|
|
39
|
-
margin: 0;
|
|
40
|
-
padding: 0;
|
|
41
|
-
border: none;
|
|
42
|
-
outline: none;
|
|
43
|
-
background-color: transparent;
|
|
44
|
-
color: #22394E;
|
|
45
|
-
&:disabled {
|
|
46
|
-
opacity: 0.5;
|
|
47
|
-
}
|
|
48
|
-
`;
|
|
49
|
-
const Minutes = styled$1.input`
|
|
50
|
-
font-weight: 600;
|
|
51
|
-
font-size: 14px;
|
|
52
|
-
width: 18px;
|
|
53
|
-
margin: 0;
|
|
54
|
-
padding: 0;
|
|
55
|
-
border: none;
|
|
56
|
-
outline: none;
|
|
57
|
-
background-color: transparent;
|
|
58
|
-
color: #22394E;
|
|
59
|
-
&:disabled {
|
|
60
|
-
opacity: 0.5;
|
|
61
|
-
}
|
|
62
|
-
`;
|
|
63
|
-
const regExp = "^[0-9]*$";
|
|
64
|
-
const Timepicker = ({ setTime, value, disabled }) => {
|
|
65
|
-
const initialHours = value?.getHours?.() ?? 0;
|
|
66
|
-
const initialMinutes = value?.getMinutes?.() ?? 0;
|
|
67
|
-
const [hours, setHours] = useState(initialHours);
|
|
68
|
-
const [minutes, setMinutes] = useState(initialMinutes);
|
|
69
|
-
const increaseHour = useCallback(() => {
|
|
70
|
-
setHours((prev) => (prev + 1) % 24);
|
|
71
|
-
}, []);
|
|
72
|
-
const decreaseHour = useCallback(() => {
|
|
73
|
-
setHours((prev) => prev === 0 ? 23 : prev - 1);
|
|
74
|
-
}, []);
|
|
75
|
-
const increaseMinutes = useCallback(() => {
|
|
76
|
-
setMinutes((prev) => (prev + 5) % 60);
|
|
77
|
-
}, []);
|
|
78
|
-
const decreaseMinutes = useCallback(() => {
|
|
79
|
-
setMinutes((prev) => (prev - 5 + 60) % 60);
|
|
80
|
-
}, []);
|
|
81
|
-
const onHoursChange = useCallback((e) => {
|
|
82
|
-
if (e.target.value.match(regExp) && Number(e.target.value) <= 23) setHours(Number(e.target.value));
|
|
83
|
-
else setHours(0);
|
|
84
|
-
}, []);
|
|
85
|
-
const onMinutesChange = useCallback((e) => {
|
|
86
|
-
if (e.target.value.match(regExp) && Number(e.target.value) <= 59) setMinutes(Number(e.target.value));
|
|
87
|
-
else setMinutes(0);
|
|
88
|
-
}, []);
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
value && setTime("hours", hours);
|
|
91
|
-
}, [hours]);
|
|
92
|
-
useEffect(() => {
|
|
93
|
-
value && setTime("minutes", minutes);
|
|
94
|
-
}, [minutes]);
|
|
95
|
-
useEffect(() => {
|
|
96
|
-
setHours(initialHours);
|
|
97
|
-
}, [initialHours]);
|
|
98
|
-
useEffect(() => {
|
|
99
|
-
setMinutes(initialMinutes);
|
|
100
|
-
}, [initialMinutes]);
|
|
101
|
-
return /* @__PURE__ */ jsxs(FooterRow, {
|
|
102
|
-
disabled,
|
|
103
|
-
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Icon, { icon: "clock" }), /* @__PURE__ */ jsx(FooterRowLabel, { children: i18n._({
|
|
104
|
-
id: "dataGrid.filterCell.time",
|
|
105
|
-
message: "Time"
|
|
106
|
-
}) })] }), /* @__PURE__ */ jsx(x.div, {
|
|
107
|
-
display: "flex",
|
|
108
|
-
flexDirection: "column",
|
|
109
|
-
alignItems: "flex-start",
|
|
110
|
-
pt: "4px",
|
|
111
|
-
w: "fit-content",
|
|
112
|
-
children: /* @__PURE__ */ jsxs(x.div, {
|
|
113
|
-
display: "flex",
|
|
114
|
-
alignItems: "center",
|
|
115
|
-
children: [
|
|
116
|
-
/* @__PURE__ */ jsxs(x.div, {
|
|
117
|
-
display: "flex",
|
|
118
|
-
flexDirection: "column",
|
|
119
|
-
children: [/* @__PURE__ */ jsx(Btn, {
|
|
120
|
-
disabled,
|
|
121
|
-
onClick: increaseHour,
|
|
122
|
-
type: "button",
|
|
123
|
-
children: "‹"
|
|
124
|
-
}), /* @__PURE__ */ jsx(Btn, {
|
|
125
|
-
disabled,
|
|
126
|
-
onClick: decreaseHour,
|
|
127
|
-
type: "button",
|
|
128
|
-
children: "›"
|
|
129
|
-
})]
|
|
130
|
-
}),
|
|
131
|
-
/* @__PURE__ */ jsxs(TimeWrapper, { children: [
|
|
132
|
-
/* @__PURE__ */ jsx(Hours, {
|
|
133
|
-
value: String(hours).padStart(2, "0"),
|
|
134
|
-
disabled,
|
|
135
|
-
onChange: onHoursChange
|
|
136
|
-
}),
|
|
137
|
-
/* @__PURE__ */ jsx(x.div, {
|
|
138
|
-
mx: "1px",
|
|
139
|
-
children: ":"
|
|
140
|
-
}),
|
|
141
|
-
/* @__PURE__ */ jsx(Minutes, {
|
|
142
|
-
value: String(minutes).padStart(2, "0"),
|
|
143
|
-
disabled,
|
|
144
|
-
onChange: onMinutesChange
|
|
145
|
-
})
|
|
146
|
-
] }),
|
|
147
|
-
/* @__PURE__ */ jsxs(x.div, {
|
|
148
|
-
display: "flex",
|
|
149
|
-
flexDirection: "column",
|
|
150
|
-
children: [/* @__PURE__ */ jsx(Btn, {
|
|
151
|
-
disabled,
|
|
152
|
-
onClick: increaseMinutes,
|
|
153
|
-
type: "button",
|
|
154
|
-
children: "‹"
|
|
155
|
-
}), /* @__PURE__ */ jsx(Btn, {
|
|
156
|
-
disabled,
|
|
157
|
-
onClick: decreaseMinutes,
|
|
158
|
-
type: "button",
|
|
159
|
-
children: "›"
|
|
160
|
-
})]
|
|
161
|
-
})
|
|
162
|
-
]
|
|
163
|
-
})
|
|
164
|
-
})]
|
|
165
|
-
});
|
|
166
|
-
};
|
|
167
|
-
//#endregion
|
|
168
|
-
export { Timepicker };
|