@via-profit/ui-kit 0.8.0 → 0.9.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.
Files changed (68) hide show
  1. package/Autocomplete/AutocompleteContainer.d.ts +13 -0
  2. package/Autocomplete/AutocompleteContainer.js +46 -7
  3. package/Badge/BadgeBase.d.ts +10 -1
  4. package/Badge/BadgeBase.js +9 -2
  5. package/Badge/BadgeDot.d.ts +4 -0
  6. package/Badge/BadgeDot.js +20 -0
  7. package/Badge/BadgeStyled.js +67 -26
  8. package/Badge/index.d.ts +4 -4
  9. package/CHANGELOG.md +12 -0
  10. package/EmptyState/EmptyStateAction.d.ts +4 -0
  11. package/EmptyState/EmptyStateAction.js +16 -0
  12. package/EmptyState/EmptyStateContainer.d.ts +8 -0
  13. package/EmptyState/EmptyStateContainer.js +34 -0
  14. package/EmptyState/EmptyStateContent.d.ts +4 -0
  15. package/EmptyState/EmptyStateContent.js +15 -0
  16. package/EmptyState/EmptyStateIcon.d.ts +4 -0
  17. package/EmptyState/EmptyStateIcon.js +38 -0
  18. package/EmptyState/EmptyStateTitle.d.ts +4 -0
  19. package/EmptyState/EmptyStateTitle.js +13 -0
  20. package/EmptyState/index.d.ts +82 -0
  21. package/EmptyState/index.js +61 -0
  22. package/FileDropzone/FileDropzoneArea.d.ts +24 -0
  23. package/FileDropzone/FileDropzoneArea.js +81 -0
  24. package/FileDropzone/index.d.ts +107 -0
  25. package/FileDropzone/index.js +169 -0
  26. package/FileDropzone/utils.d.ts +9 -0
  27. package/FileDropzone/utils.js +42 -0
  28. package/HintPopover/HintPopoverButton.d.ts +4 -0
  29. package/HintPopover/HintPopoverButton.js +67 -0
  30. package/HintPopover/HintPopoverContainer.d.ts +4 -0
  31. package/HintPopover/HintPopoverContainer.js +52 -0
  32. package/HintPopover/index.d.ts +67 -0
  33. package/HintPopover/index.js +71 -0
  34. package/InfoNote/InfoNoteContainer.d.ts +14 -0
  35. package/InfoNote/InfoNoteContainer.js +56 -0
  36. package/InfoNote/InfoNoteContent.d.ts +4 -0
  37. package/InfoNote/InfoNoteContent.js +16 -0
  38. package/InfoNote/InfoNoteIcon.d.ts +9 -0
  39. package/InfoNote/InfoNoteIcon.js +47 -0
  40. package/InfoNote/InfoNoteTitle.d.ts +4 -0
  41. package/InfoNote/InfoNoteTitle.js +13 -0
  42. package/InfoNote/index.d.ts +65 -0
  43. package/InfoNote/index.js +59 -0
  44. package/Skeleton/index.d.ts +39 -0
  45. package/Skeleton/index.js +69 -0
  46. package/esm/Autocomplete/AutocompleteContainer.js +46 -7
  47. package/esm/Badge/BadgeBase.js +9 -2
  48. package/esm/Badge/BadgeDot.js +15 -0
  49. package/esm/Badge/BadgeStyled.js +67 -26
  50. package/esm/EmptyState/EmptyStateAction.js +11 -0
  51. package/esm/EmptyState/EmptyStateContainer.js +29 -0
  52. package/esm/EmptyState/EmptyStateContent.js +10 -0
  53. package/esm/EmptyState/EmptyStateIcon.js +33 -0
  54. package/esm/EmptyState/EmptyStateTitle.js +8 -0
  55. package/esm/EmptyState/index.js +42 -0
  56. package/esm/FileDropzone/FileDropzoneArea.js +76 -0
  57. package/esm/FileDropzone/index.js +148 -0
  58. package/esm/FileDropzone/utils.js +37 -0
  59. package/esm/HintPopover/HintPopoverButton.js +62 -0
  60. package/esm/HintPopover/HintPopoverContainer.js +47 -0
  61. package/esm/HintPopover/index.js +52 -0
  62. package/esm/InfoNote/InfoNoteContainer.js +49 -0
  63. package/esm/InfoNote/InfoNoteContent.js +11 -0
  64. package/esm/InfoNote/InfoNoteIcon.js +42 -0
  65. package/esm/InfoNote/InfoNoteTitle.js +8 -0
  66. package/esm/InfoNote/index.js +40 -0
  67. package/esm/Skeleton/index.js +64 -0
  68. package/package.json +121 -1
@@ -0,0 +1,82 @@
1
+ import React from 'react';
2
+ import { EmptyStateContainerProps } from './EmptyStateContainer';
3
+ import { EmptyStateIconProps } from './EmptyStateIcon';
4
+ import { EmptyStateTitleProps } from './EmptyStateTitle';
5
+ import { EmptyStateContentProps } from './EmptyStateContent';
6
+ import { EmptyStateActionProps } from './EmptyStateAction';
7
+ export type EmptyStateProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> & {
8
+ /**
9
+ * The short line: what is empty («Заявок нет»)
10
+ */
11
+ readonly title?: React.ReactNode;
12
+ /**
13
+ * The explanation: why it is empty and what to do
14
+ */
15
+ readonly children?: React.ReactNode;
16
+ /**
17
+ * The next step: one or two buttons
18
+ */
19
+ readonly action?: React.ReactNode;
20
+ /**
21
+ * Replaces the empty box. `false` — no illustration
22
+ */
23
+ readonly icon?: React.ReactNode;
24
+ /**
25
+ * Takes the whole height of the parent and stands in its middle
26
+ * Default: false
27
+ */
28
+ readonly fullHeight?: boolean;
29
+ readonly overrides?: EmptyStateOverrides;
30
+ };
31
+ export interface EmptyStateOverrides {
32
+ /**
33
+ * The column in the middle; gets `fullHeight`
34
+ */
35
+ readonly Container?: React.ComponentType<EmptyStateContainerProps & React.RefAttributes<HTMLDivElement>>;
36
+ /**
37
+ * The illustration; the own one from `icon` comes in `children`
38
+ */
39
+ readonly Icon?: React.ComponentType<EmptyStateIconProps & React.RefAttributes<HTMLSpanElement>>;
40
+ /**
41
+ * The title. Rendered only with `title`
42
+ */
43
+ readonly Title?: React.ComponentType<EmptyStateTitleProps & React.RefAttributes<HTMLDivElement>>;
44
+ /**
45
+ * The explanation. Rendered only with `children`
46
+ */
47
+ readonly Content?: React.ComponentType<EmptyStateContentProps & React.RefAttributes<HTMLDivElement>>;
48
+ /**
49
+ * The buttons. Rendered only with `action`
50
+ */
51
+ readonly Action?: React.ComponentType<EmptyStateActionProps & React.RefAttributes<HTMLDivElement>>;
52
+ }
53
+ export * from './EmptyStateContainer';
54
+ export * from './EmptyStateIcon';
55
+ export * from './EmptyStateTitle';
56
+ export * from './EmptyStateContent';
57
+ export * from './EmptyStateAction';
58
+ declare const _default: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "title"> & {
59
+ /**
60
+ * The short line: what is empty («Заявок нет»)
61
+ */
62
+ readonly title?: React.ReactNode;
63
+ /**
64
+ * The explanation: why it is empty and what to do
65
+ */
66
+ readonly children?: React.ReactNode;
67
+ /**
68
+ * The next step: one or two buttons
69
+ */
70
+ readonly action?: React.ReactNode;
71
+ /**
72
+ * Replaces the empty box. `false` — no illustration
73
+ */
74
+ readonly icon?: React.ReactNode;
75
+ /**
76
+ * Takes the whole height of the parent and stands in its middle
77
+ * Default: false
78
+ */
79
+ readonly fullHeight?: boolean;
80
+ readonly overrides?: EmptyStateOverrides;
81
+ } & React.RefAttributes<HTMLDivElement>>;
82
+ export default _default;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __rest = (this && this.__rest) || function (s, e) {
17
+ var t = {};
18
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
19
+ t[p] = s[p];
20
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
21
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
22
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
23
+ t[p[i]] = s[p[i]];
24
+ }
25
+ return t;
26
+ };
27
+ var __importDefault = (this && this.__importDefault) || function (mod) {
28
+ return (mod && mod.__esModule) ? mod : { "default": mod };
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ const react_1 = __importDefault(require("react"));
32
+ const EmptyStateContainer_1 = __importDefault(require("./EmptyStateContainer"));
33
+ const EmptyStateIcon_1 = __importDefault(require("./EmptyStateIcon"));
34
+ const EmptyStateTitle_1 = __importDefault(require("./EmptyStateTitle"));
35
+ const EmptyStateContent_1 = __importDefault(require("./EmptyStateContent"));
36
+ const EmptyStateAction_1 = __importDefault(require("./EmptyStateAction"));
37
+ /**
38
+ * The empty list, the nothing found, the not chosen yet: the illustration, what is empty
39
+ * and what to do next
40
+ */
41
+ const EmptyState = (props, ref) => {
42
+ const { title, children, action, icon, fullHeight = false, overrides } = props, nativeProps = __rest(props, ["title", "children", "action", "icon", "fullHeight", "overrides"]);
43
+ const overridesMap = react_1.default.useMemo(() => ({
44
+ Container: (overrides === null || overrides === void 0 ? void 0 : overrides.Container) || EmptyStateContainer_1.default,
45
+ Icon: (overrides === null || overrides === void 0 ? void 0 : overrides.Icon) || EmptyStateIcon_1.default,
46
+ Title: (overrides === null || overrides === void 0 ? void 0 : overrides.Title) || EmptyStateTitle_1.default,
47
+ Content: (overrides === null || overrides === void 0 ? void 0 : overrides.Content) || EmptyStateContent_1.default,
48
+ Action: (overrides === null || overrides === void 0 ? void 0 : overrides.Action) || EmptyStateAction_1.default,
49
+ }), [overrides]);
50
+ return (react_1.default.createElement(overridesMap.Container, Object.assign({}, nativeProps, { fullHeight: fullHeight, ref: ref }),
51
+ icon !== false && react_1.default.createElement(overridesMap.Icon, null, icon),
52
+ title && react_1.default.createElement(overridesMap.Title, null, title),
53
+ children && react_1.default.createElement(overridesMap.Content, null, children),
54
+ action && react_1.default.createElement(overridesMap.Action, null, action)));
55
+ };
56
+ __exportStar(require("./EmptyStateContainer"), exports);
57
+ __exportStar(require("./EmptyStateIcon"), exports);
58
+ __exportStar(require("./EmptyStateTitle"), exports);
59
+ __exportStar(require("./EmptyStateContent"), exports);
60
+ __exportStar(require("./EmptyStateAction"), exports);
61
+ exports.default = react_1.default.forwardRef(EmptyState);
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ export type FileDropzoneAreaProps = React.HTMLAttributes<HTMLDivElement> & {
3
+ /**
4
+ * A file is dragged over the area
5
+ */
6
+ readonly active: boolean;
7
+ /**
8
+ * The file is chosen: the solid border instead of the dashed one
9
+ */
10
+ readonly filled: boolean;
11
+ readonly disabled: boolean;
12
+ };
13
+ declare const _default: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
14
+ /**
15
+ * A file is dragged over the area
16
+ */
17
+ readonly active: boolean;
18
+ /**
19
+ * The file is chosen: the solid border instead of the dashed one
20
+ */
21
+ readonly filled: boolean;
22
+ readonly disabled: boolean;
23
+ } & React.RefAttributes<HTMLDivElement>>;
24
+ export default _default;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const react_1 = __importDefault(require("react"));
18
+ const styled_1 = __importDefault(require("@emotion/styled"));
19
+ const react_2 = require("@emotion/react");
20
+ const StyledArea = styled_1.default.div `
21
+ box-sizing: border-box;
22
+ display: flex;
23
+ width: 100%;
24
+ min-height: 6.5em;
25
+ padding: 1em;
26
+ border-radius: ${({ theme }) => theme.shape.radiusFactor * 1.6}em;
27
+ border: 1px ${({ $filled }) => ($filled ? 'solid' : 'dashed')}
28
+ ${({ theme, $active }) => ($active ? theme.color.accentPrimary : theme.color.textSecondary.alpha(0.45)).toString()};
29
+ background-color: ${({ theme, $active }) => ($active
30
+ ? theme.color.accentPrimary.alpha(0.1)
31
+ : theme.color.textPrimary.alpha(0.03)).toString()};
32
+ color: ${({ theme }) => theme.color.textPrimary.toString()};
33
+ transition:
34
+ border-color 120ms ease-out,
35
+ background-color 120ms ease-out;
36
+
37
+ ${({ $filled, $disabled, theme }) => !$filled &&
38
+ !$disabled &&
39
+ (0, react_2.css) `
40
+ cursor: pointer;
41
+
42
+ &:hover,
43
+ &:focus-visible {
44
+ border-color: ${theme.color.accentPrimary.toString()};
45
+ }
46
+ `}
47
+
48
+ ${({ $filled }) => $filled
49
+ ? (0, react_2.css) `
50
+ flex-direction: row;
51
+ align-items: center;
52
+ gap: 0.75em;
53
+ `
54
+ : (0, react_2.css) `
55
+ flex-direction: column;
56
+ align-items: center;
57
+ justify-content: center;
58
+ gap: 0.3em;
59
+ text-align: center;
60
+ `}
61
+
62
+ ${({ $disabled }) => $disabled &&
63
+ (0, react_2.css) `
64
+ opacity: 0.5;
65
+ cursor: default;
66
+ `}
67
+
68
+ &:focus-visible {
69
+ outline: 2px solid ${({ theme }) => theme.color.accentPrimary.alpha(0.4).toString()};
70
+ outline-offset: 2px;
71
+ }
72
+ `;
73
+ /**
74
+ * The area: without the file — the icon and two lines in the middle (it chooses the file),
75
+ * with the file — the row of the file
76
+ */
77
+ const FileDropzoneArea = (props, ref) => {
78
+ const { active, filled, disabled } = props, nativeProps = __rest(props, ["active", "filled", "disabled"]);
79
+ return (react_1.default.createElement(StyledArea, Object.assign({}, nativeProps, { "$active": active, "$filled": filled, "$disabled": disabled, ref: ref })));
80
+ };
81
+ exports.default = react_1.default.forwardRef(FileDropzoneArea);
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import { FileDropzoneAreaProps } from './FileDropzoneArea';
3
+ import { formatFileSize, isFileAccepted } from './utils';
4
+ export { formatFileSize, isFileAccepted };
5
+ export type FileDropzoneRejectReason = 'type' | 'size';
6
+ export type FileDropzoneProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> & {
7
+ /**
8
+ * The chosen file, `null` — no file
9
+ */
10
+ readonly value: File | null;
11
+ /**
12
+ * Called with the chosen file or `null` when the file is removed
13
+ */
14
+ readonly onChange: (file: File | null) => void;
15
+ /**
16
+ * The types of the files, as `accept` of the input: `image/png`, `image/*`, `.pdf`
17
+ */
18
+ readonly accept?: string;
19
+ /**
20
+ * The maximum size of the file in bytes
21
+ */
22
+ readonly maxSize?: number;
23
+ /**
24
+ * The file is not taken: the type is not in `accept` or it is larger than `maxSize`
25
+ */
26
+ readonly onReject?: (file: File, reason: FileDropzoneRejectReason) => void;
27
+ /**
28
+ * The line of the empty area
29
+ * Default: `Choose a file`
30
+ */
31
+ readonly label?: React.ReactNode;
32
+ /**
33
+ * The second line of the empty area: the types and the size
34
+ */
35
+ readonly hint?: React.ReactNode;
36
+ /**
37
+ * Default: `Replace`
38
+ */
39
+ readonly replaceLabel?: React.ReactNode;
40
+ /**
41
+ * The name of the delete button for the screen readers and its tooltip
42
+ * Default: `Remove the file`
43
+ */
44
+ readonly removeLabel?: string;
45
+ /**
46
+ * The size of the chosen file
47
+ * Default: `formatFileSize` — «54.1 KB»
48
+ */
49
+ readonly formatSize?: (bytes: number) => React.ReactNode;
50
+ readonly disabled?: boolean;
51
+ readonly overrides?: FileDropzoneOverrides;
52
+ };
53
+ export interface FileDropzoneOverrides {
54
+ /**
55
+ * The area with the border: without the file and with it (`filled`)
56
+ */
57
+ readonly Area?: React.ComponentType<FileDropzoneAreaProps & React.RefAttributes<HTMLDivElement>>;
58
+ }
59
+ export * from './FileDropzoneArea';
60
+ declare const _default: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> & {
61
+ /**
62
+ * The chosen file, `null` — no file
63
+ */
64
+ readonly value: File | null;
65
+ /**
66
+ * Called with the chosen file or `null` when the file is removed
67
+ */
68
+ readonly onChange: (file: File | null) => void;
69
+ /**
70
+ * The types of the files, as `accept` of the input: `image/png`, `image/*`, `.pdf`
71
+ */
72
+ readonly accept?: string;
73
+ /**
74
+ * The maximum size of the file in bytes
75
+ */
76
+ readonly maxSize?: number;
77
+ /**
78
+ * The file is not taken: the type is not in `accept` or it is larger than `maxSize`
79
+ */
80
+ readonly onReject?: (file: File, reason: FileDropzoneRejectReason) => void;
81
+ /**
82
+ * The line of the empty area
83
+ * Default: `Choose a file`
84
+ */
85
+ readonly label?: React.ReactNode;
86
+ /**
87
+ * The second line of the empty area: the types and the size
88
+ */
89
+ readonly hint?: React.ReactNode;
90
+ /**
91
+ * Default: `Replace`
92
+ */
93
+ readonly replaceLabel?: React.ReactNode;
94
+ /**
95
+ * The name of the delete button for the screen readers and its tooltip
96
+ * Default: `Remove the file`
97
+ */
98
+ readonly removeLabel?: string;
99
+ /**
100
+ * The size of the chosen file
101
+ * Default: `formatFileSize` — «54.1 KB»
102
+ */
103
+ readonly formatSize?: (bytes: number) => React.ReactNode;
104
+ readonly disabled?: boolean;
105
+ readonly overrides?: FileDropzoneOverrides;
106
+ } & React.RefAttributes<HTMLDivElement>>;
107
+ export default _default;
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __rest = (this && this.__rest) || function (s, e) {
17
+ var t = {};
18
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
19
+ t[p] = s[p];
20
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
21
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
22
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
23
+ t[p[i]] = s[p[i]];
24
+ }
25
+ return t;
26
+ };
27
+ var __importDefault = (this && this.__importDefault) || function (mod) {
28
+ return (mod && mod.__esModule) ? mod : { "default": mod };
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.isFileAccepted = exports.formatFileSize = void 0;
32
+ const react_1 = __importDefault(require("react"));
33
+ const styled_1 = __importDefault(require("@emotion/styled"));
34
+ const Button_1 = __importDefault(require("../Button"));
35
+ const FileDropzoneArea_1 = __importDefault(require("./FileDropzoneArea"));
36
+ const utils_1 = require("./utils");
37
+ Object.defineProperty(exports, "formatFileSize", { enumerable: true, get: function () { return utils_1.formatFileSize; } });
38
+ Object.defineProperty(exports, "isFileAccepted", { enumerable: true, get: function () { return utils_1.isFileAccepted; } });
39
+ const Icon = styled_1.default.span `
40
+ flex: none;
41
+ display: inline-flex;
42
+ font-size: 1.5em;
43
+ color: ${({ theme }) => theme.color.textSecondary.toString()};
44
+ `;
45
+ const Label = styled_1.default.span `
46
+ font-size: 0.875em;
47
+ font-weight: 600;
48
+ `;
49
+ const Hint = styled_1.default.span `
50
+ font-size: 0.75em;
51
+ color: ${({ theme }) => theme.color.textSecondary.toString()};
52
+ `;
53
+ const FileText = styled_1.default.span `
54
+ flex: 1;
55
+ min-width: 0;
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 0.15em;
59
+ text-align: left;
60
+ `;
61
+ /**
62
+ * The long name in one line: the whole name is in the tooltip
63
+ */
64
+ const FileName = (0, styled_1.default)(Label) `
65
+ white-space: nowrap;
66
+ overflow: hidden;
67
+ text-overflow: ellipsis;
68
+ `;
69
+ const Path = styled_1.default.path `
70
+ fill: currentColor;
71
+ `;
72
+ const UploadIcon = () => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24", "aria-hidden": true },
73
+ react_1.default.createElement(Path, { d: "M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM19 18H6c-2.21 0-4-1.79-4-4 0-2.05 1.53-3.76 3.56-3.97l1.07-.11.5-.95A5.469 5.469 0 0 1 12 6c2.62 0 4.88 1.86 5.39 4.43l.3 1.5 1.53.11A2.98 2.98 0 0 1 22 15c0 1.65-1.35 3-3 3zM8 13h2.55v3h2.9v-3H16l-4-4z" })));
74
+ const FileIcon = () => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24", "aria-hidden": true },
75
+ react_1.default.createElement(Path, { d: "M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6zm2-6h8v2H8zm0 3h5v2H8z" })));
76
+ const TrashIcon = () => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24", "aria-hidden": true },
77
+ react_1.default.createElement(Path, { d: "M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z" })));
78
+ /**
79
+ * The file by the click or by the drop: one area with the dashed border. The chosen file
80
+ * is the row with its name and size, «Replace» and the delete button; a new file can be
81
+ * dropped onto it too
82
+ */
83
+ const FileDropzone = (props, ref) => {
84
+ const { value, onChange, accept, maxSize, onReject, label = 'Choose a file', hint, replaceLabel = 'Replace', removeLabel = 'Remove the file', formatSize = utils_1.formatFileSize, disabled = false, overrides } = props, nativeProps = __rest(props, ["value", "onChange", "accept", "maxSize", "onReject", "label", "hint", "replaceLabel", "removeLabel", "formatSize", "disabled", "overrides"]);
85
+ const AreaComponent = (overrides === null || overrides === void 0 ? void 0 : overrides.Area) || FileDropzoneArea_1.default;
86
+ const inputRef = react_1.default.useRef(null);
87
+ // dragenter/dragleave fire on every child: the counter keeps the highlight steady
88
+ const dragDepthRef = react_1.default.useRef(0);
89
+ const [isDragActive, setDragActive] = react_1.default.useState(false);
90
+ const take = (file) => {
91
+ if (!file) {
92
+ return;
93
+ }
94
+ if (!(0, utils_1.isFileAccepted)(file, accept)) {
95
+ onReject === null || onReject === void 0 ? void 0 : onReject(file, 'type');
96
+ return;
97
+ }
98
+ if (typeof maxSize === 'number' && file.size > maxSize) {
99
+ onReject === null || onReject === void 0 ? void 0 : onReject(file, 'size');
100
+ return;
101
+ }
102
+ onChange(file);
103
+ };
104
+ const choose = () => {
105
+ var _a;
106
+ if (!disabled) {
107
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
108
+ }
109
+ };
110
+ const dropHandlers = disabled
111
+ ? {}
112
+ : {
113
+ onDragEnter: (event) => {
114
+ event.preventDefault();
115
+ dragDepthRef.current += 1;
116
+ setDragActive(true);
117
+ },
118
+ onDragOver: (event) => {
119
+ event.preventDefault();
120
+ },
121
+ onDragLeave: () => {
122
+ dragDepthRef.current = Math.max(0, dragDepthRef.current - 1);
123
+ if (dragDepthRef.current === 0) {
124
+ setDragActive(false);
125
+ }
126
+ },
127
+ onDrop: (event) => {
128
+ var _a;
129
+ event.preventDefault();
130
+ dragDepthRef.current = 0;
131
+ setDragActive(false);
132
+ take((_a = event.dataTransfer.files) === null || _a === void 0 ? void 0 : _a[0]);
133
+ },
134
+ };
135
+ const input = (react_1.default.createElement("input", { hidden: true, ref: inputRef, type: "file", accept: accept, disabled: disabled,
136
+ // the input is inside the area: its click must not reach the area and open the dialog again
137
+ onClick: event => event.stopPropagation(), onChange: event => {
138
+ var _a;
139
+ const file = (_a = event.currentTarget.files) === null || _a === void 0 ? void 0 : _a[0];
140
+ // the same file can be chosen again after the removal
141
+ event.currentTarget.value = '';
142
+ take(file);
143
+ } }));
144
+ if (value) {
145
+ return (react_1.default.createElement(AreaComponent, Object.assign({}, nativeProps, dropHandlers, { active: isDragActive, filled: true, disabled: disabled, ref: ref }),
146
+ input,
147
+ react_1.default.createElement(Icon, null,
148
+ react_1.default.createElement(FileIcon, null)),
149
+ react_1.default.createElement(FileText, null,
150
+ react_1.default.createElement(FileName, { title: value.name }, value.name),
151
+ react_1.default.createElement(Hint, null, formatSize(value.size))),
152
+ react_1.default.createElement(Button_1.default, { type: "button", variant: "plain", disabled: disabled, onClick: choose }, replaceLabel),
153
+ react_1.default.createElement(Button_1.default, { type: "button", variant: "plain", color: "error", iconOnly: true, disabled: disabled, title: removeLabel, "aria-label": removeLabel, onClick: () => onChange(null) },
154
+ react_1.default.createElement(TrashIcon, null))));
155
+ }
156
+ return (react_1.default.createElement(AreaComponent, Object.assign({ role: "button", tabIndex: disabled ? -1 : 0, "aria-disabled": disabled || undefined }, nativeProps, dropHandlers, { active: isDragActive, filled: false, disabled: disabled, onClick: choose, onKeyDown: event => {
157
+ if (event.key === 'Enter' || event.key === ' ') {
158
+ event.preventDefault();
159
+ choose();
160
+ }
161
+ }, ref: ref }),
162
+ input,
163
+ react_1.default.createElement(Icon, null,
164
+ react_1.default.createElement(UploadIcon, null)),
165
+ react_1.default.createElement(Label, null, label),
166
+ hint && react_1.default.createElement(Hint, null, hint)));
167
+ };
168
+ __exportStar(require("./FileDropzoneArea"), exports);
169
+ exports.default = react_1.default.forwardRef(FileDropzone);
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The file matches `accept` of the input: the MIME types (`image/png`), the groups (`image/*`)
3
+ * and the extensions (`.pdf`). The empty `accept` takes any file
4
+ */
5
+ export declare const isFileAccepted: (file: File, accept?: string) => boolean;
6
+ /**
7
+ * «54.1 KB», «2.3 MB»: the decimal units, as the file managers show
8
+ */
9
+ export declare const formatFileSize: (bytes: number) => string;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatFileSize = exports.isFileAccepted = void 0;
4
+ /**
5
+ * The file matches `accept` of the input: the MIME types (`image/png`), the groups (`image/*`)
6
+ * and the extensions (`.pdf`). The empty `accept` takes any file
7
+ */
8
+ const isFileAccepted = (file, accept) => {
9
+ if (!accept) {
10
+ return true;
11
+ }
12
+ const name = file.name.toLowerCase();
13
+ const type = file.type.toLowerCase();
14
+ return accept
15
+ .split(',')
16
+ .map(item => item.trim().toLowerCase())
17
+ .filter(Boolean)
18
+ .some(item => {
19
+ if (item.startsWith('.')) {
20
+ return name.endsWith(item);
21
+ }
22
+ if (item.endsWith('/*')) {
23
+ return type.startsWith(item.slice(0, -1));
24
+ }
25
+ return type === item;
26
+ });
27
+ };
28
+ exports.isFileAccepted = isFileAccepted;
29
+ /**
30
+ * «54.1 KB», «2.3 MB»: the decimal units, as the file managers show
31
+ */
32
+ const formatFileSize = (bytes) => {
33
+ const units = ['B', 'KB', 'MB', 'GB'];
34
+ let value = bytes;
35
+ let unit = 0;
36
+ while (value >= 1000 && unit < units.length - 1) {
37
+ value /= 1000;
38
+ unit += 1;
39
+ }
40
+ return `${unit === 0 ? value : value.toFixed(1).replace(/\.0$/, '')} ${units[unit]}`;
41
+ };
42
+ exports.formatFileSize = formatFileSize;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export type HintPopoverButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
3
+ declare const _default: React.ForwardRefExoticComponent<HintPopoverButtonProps & React.RefAttributes<HTMLButtonElement>>;
4
+ export default _default;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const react_1 = __importDefault(require("react"));
18
+ const styled_1 = __importDefault(require("@emotion/styled"));
19
+ /**
20
+ * The color of the text around: the button stands in the text, in the label of a field,
21
+ * in a colored header of the dialog
22
+ */
23
+ const StyledButton = styled_1.default.button `
24
+ box-sizing: content-box;
25
+ display: inline-flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ margin: 0 0.15em;
29
+ padding: 0.2em;
30
+ border: none;
31
+ border-radius: 50%;
32
+ background: none;
33
+ font: inherit;
34
+ font-size: 1em;
35
+ line-height: 1;
36
+ color: inherit;
37
+ opacity: 0.6;
38
+ cursor: pointer;
39
+ vertical-align: middle;
40
+ transition:
41
+ opacity 120ms ease-out,
42
+ background-color 120ms ease-out;
43
+
44
+ &:hover,
45
+ &:focus-visible,
46
+ &[aria-expanded='true'] {
47
+ opacity: 1;
48
+ background-color: color-mix(in srgb, currentColor 15%, transparent);
49
+ }
50
+
51
+ &:focus-visible {
52
+ outline: 2px solid ${({ theme }) => theme.color.accentPrimary.toString()};
53
+ outline-offset: 1px;
54
+ }
55
+ `;
56
+ const Path = styled_1.default.path `
57
+ fill: currentColor;
58
+ `;
59
+ /**
60
+ * «?» in the circle. `children` replaces the icon
61
+ */
62
+ const HintPopoverButton = (props, ref) => {
63
+ const { children } = props, nativeProps = __rest(props, ["children"]);
64
+ return (react_1.default.createElement(StyledButton, Object.assign({ type: "button" }, nativeProps, { ref: ref }), children !== null && children !== void 0 ? children : (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24", "aria-hidden": true },
65
+ react_1.default.createElement(Path, { d: "M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z" })))));
66
+ };
67
+ exports.default = react_1.default.forwardRef(HintPopoverButton);
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export type HintPopoverContainerProps = React.HTMLAttributes<HTMLDivElement>;
3
+ declare const _default: React.ForwardRefExoticComponent<HintPopoverContainerProps & React.RefAttributes<HTMLDivElement>>;
4
+ export default _default;