@via-profit/ui-kit 0.7.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.
- package/Autocomplete/AutocompleteContainer.d.ts +13 -0
- package/Autocomplete/AutocompleteContainer.js +46 -7
- package/Badge/BadgeBase.d.ts +10 -1
- package/Badge/BadgeBase.js +9 -2
- package/Badge/BadgeDot.d.ts +4 -0
- package/Badge/BadgeDot.js +20 -0
- package/Badge/BadgeStyled.js +67 -26
- package/Badge/index.d.ts +4 -4
- package/CHANGELOG.md +20 -0
- package/EmptyState/EmptyStateAction.d.ts +4 -0
- package/EmptyState/EmptyStateAction.js +16 -0
- package/EmptyState/EmptyStateContainer.d.ts +8 -0
- package/EmptyState/EmptyStateContainer.js +34 -0
- package/EmptyState/EmptyStateContent.d.ts +4 -0
- package/EmptyState/EmptyStateContent.js +15 -0
- package/EmptyState/EmptyStateIcon.d.ts +4 -0
- package/EmptyState/EmptyStateIcon.js +38 -0
- package/EmptyState/EmptyStateTitle.d.ts +4 -0
- package/EmptyState/EmptyStateTitle.js +13 -0
- package/EmptyState/index.d.ts +82 -0
- package/EmptyState/index.js +61 -0
- package/FileDropzone/FileDropzoneArea.d.ts +24 -0
- package/FileDropzone/FileDropzoneArea.js +81 -0
- package/FileDropzone/index.d.ts +107 -0
- package/FileDropzone/index.js +169 -0
- package/FileDropzone/utils.d.ts +9 -0
- package/FileDropzone/utils.js +42 -0
- package/HintPopover/HintPopoverButton.d.ts +4 -0
- package/HintPopover/HintPopoverButton.js +67 -0
- package/HintPopover/HintPopoverContainer.d.ts +4 -0
- package/HintPopover/HintPopoverContainer.js +52 -0
- package/HintPopover/index.d.ts +67 -0
- package/HintPopover/index.js +71 -0
- package/InfoNote/InfoNoteContainer.d.ts +14 -0
- package/InfoNote/InfoNoteContainer.js +56 -0
- package/InfoNote/InfoNoteContent.d.ts +4 -0
- package/InfoNote/InfoNoteContent.js +16 -0
- package/InfoNote/InfoNoteIcon.d.ts +9 -0
- package/InfoNote/InfoNoteIcon.js +47 -0
- package/InfoNote/InfoNoteTitle.d.ts +4 -0
- package/InfoNote/InfoNoteTitle.js +13 -0
- package/InfoNote/index.d.ts +65 -0
- package/InfoNote/index.js +59 -0
- package/Modal/Drawer/DrawerInner.d.ts +6 -0
- package/Modal/Drawer/DrawerInner.js +91 -2
- package/Modal/Drawer/index.d.ts +8 -0
- package/Modal/Drawer/index.js +3 -3
- package/Modal/Drawer/useSwipeToClose.d.ts +30 -0
- package/Modal/Drawer/useSwipeToClose.js +238 -0
- package/Skeleton/index.d.ts +39 -0
- package/Skeleton/index.js +69 -0
- package/esm/Autocomplete/AutocompleteContainer.js +46 -7
- package/esm/Badge/BadgeBase.js +9 -2
- package/esm/Badge/BadgeDot.js +15 -0
- package/esm/Badge/BadgeStyled.js +67 -26
- package/esm/EmptyState/EmptyStateAction.js +11 -0
- package/esm/EmptyState/EmptyStateContainer.js +29 -0
- package/esm/EmptyState/EmptyStateContent.js +10 -0
- package/esm/EmptyState/EmptyStateIcon.js +33 -0
- package/esm/EmptyState/EmptyStateTitle.js +8 -0
- package/esm/EmptyState/index.js +42 -0
- package/esm/FileDropzone/FileDropzoneArea.js +76 -0
- package/esm/FileDropzone/index.js +148 -0
- package/esm/FileDropzone/utils.js +37 -0
- package/esm/HintPopover/HintPopoverButton.js +62 -0
- package/esm/HintPopover/HintPopoverContainer.js +47 -0
- package/esm/HintPopover/index.js +52 -0
- package/esm/InfoNote/InfoNoteContainer.js +49 -0
- package/esm/InfoNote/InfoNoteContent.js +11 -0
- package/esm/InfoNote/InfoNoteIcon.js +42 -0
- package/esm/InfoNote/InfoNoteTitle.js +8 -0
- package/esm/InfoNote/index.js +40 -0
- package/esm/Modal/Drawer/DrawerInner.js +91 -2
- package/esm/Modal/Drawer/index.js +3 -3
- package/esm/Modal/Drawer/useSwipeToClose.js +233 -0
- package/esm/Skeleton/index.js +64 -0
- package/package.json +126 -1
|
@@ -122,6 +122,19 @@ export interface AutocompleteProps<T, Multiple extends boolean | undefined = und
|
|
|
122
122
|
* The function that will be called at the moment when you change the input value of input element
|
|
123
123
|
*/
|
|
124
124
|
readonly onInputChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
125
|
+
/**
|
|
126
|
+
* The text of the field controlled by you: the free text which is the value itself
|
|
127
|
+
* (INN, the name, the address), the items are the suggestions only.\
|
|
128
|
+
* With it the field shows this text, not the text of the selected item, and does not
|
|
129
|
+
* clear or restore it on blur. The choice of an item calls `onChange(item)`: put the text
|
|
130
|
+
* of the item into `inputValue` yourself, if needed.\
|
|
131
|
+
* Pass it together with `onInputValueChange`
|
|
132
|
+
*/
|
|
133
|
+
readonly inputValue?: string;
|
|
134
|
+
/**
|
|
135
|
+
* Called with the new text of the field: on typing and on the clear button
|
|
136
|
+
*/
|
|
137
|
+
readonly onInputValueChange?: (inputValue: string) => void;
|
|
125
138
|
/**
|
|
126
139
|
* The function that will be called at the moment when you want to open the selectbox
|
|
127
140
|
*/
|
|
@@ -67,7 +67,7 @@ const AutocompleteMenuList = react_1.default.forwardRef((props, ref) => (react_1
|
|
|
67
67
|
AutocompleteMenuList.displayName = 'AutocompleteMenuList';
|
|
68
68
|
const MENU_OVERRIDES = { List: AutocompleteMenuList };
|
|
69
69
|
const Autocomplete = react_1.default.forwardRef((props, ref) => {
|
|
70
|
-
const { items, value, multiple, isOpen = false, isLoading = false, clearOnBlur = true, anchorPos = 'bottom-fill', alternativePlacements = ['bottom-fill', 'top-fill'], openOnFocus = true, autoFlip = true, viewportMargin, positionStrategy, requiredAsterisk, startIcon, fullWidth, placeholder, label, error, errorText, inputRef, filterItems, children, onChange, selectedItemToString, clearable = true, onInputChange, getOptionSelected, onRequestOpen = () => undefined, onRequestClose = () => undefined, overrides } = props, nativeInputProps = __rest(props, ["items", "value", "multiple", "isOpen", "isLoading", "clearOnBlur", "anchorPos", "alternativePlacements", "openOnFocus", "autoFlip", "viewportMargin", "positionStrategy", "requiredAsterisk", "startIcon", "fullWidth", "placeholder", "label", "error", "errorText", "inputRef", "filterItems", "children", "onChange", "selectedItemToString", "clearable", "onInputChange", "getOptionSelected", "onRequestOpen", "onRequestClose", "overrides"]);
|
|
70
|
+
const { items, value, multiple, isOpen = false, isLoading = false, clearOnBlur = true, anchorPos = 'bottom-fill', alternativePlacements = ['bottom-fill', 'top-fill'], openOnFocus = true, autoFlip = true, viewportMargin, positionStrategy, requiredAsterisk, startIcon, fullWidth, placeholder, label, error, errorText, inputRef, filterItems, children, onChange, selectedItemToString, clearable = true, onInputChange, inputValue: controlledInputValue, onInputValueChange, getOptionSelected, onRequestOpen = () => undefined, onRequestClose = () => undefined, overrides } = props, nativeInputProps = __rest(props, ["items", "value", "multiple", "isOpen", "isLoading", "clearOnBlur", "anchorPos", "alternativePlacements", "openOnFocus", "autoFlip", "viewportMargin", "positionStrategy", "requiredAsterisk", "startIcon", "fullWidth", "placeholder", "label", "error", "errorText", "inputRef", "filterItems", "children", "onChange", "selectedItemToString", "clearable", "onInputChange", "inputValue", "onInputValueChange", "getOptionSelected", "onRequestOpen", "onRequestClose", "overrides"]);
|
|
71
71
|
const menuRef = react_1.default.useRef(null);
|
|
72
72
|
const fieldInputRef = react_1.default.useRef(null);
|
|
73
73
|
const isFocusedRef = react_1.default.useRef(false);
|
|
@@ -77,10 +77,12 @@ const Autocomplete = react_1.default.forwardRef((props, ref) => {
|
|
|
77
77
|
const overridesMap = react_1.default.useMemo(() => ({
|
|
78
78
|
TextField: (overrides === null || overrides === void 0 ? void 0 : overrides.TextField) || TextField_1.default,
|
|
79
79
|
}), [overrides]);
|
|
80
|
+
const isInputControlled = typeof controlledInputValue === 'string';
|
|
80
81
|
const clear = react_1.default.useCallback(() => {
|
|
81
82
|
if (onChange) {
|
|
82
83
|
onChange((multiple ? [] : null));
|
|
83
84
|
}
|
|
85
|
+
onInputValueChange === null || onInputValueChange === void 0 ? void 0 : onInputValueChange('');
|
|
84
86
|
dispatch((0, context_1.actionSetPartial)({
|
|
85
87
|
filteredItems: items,
|
|
86
88
|
inputValue: '',
|
|
@@ -89,7 +91,7 @@ const Autocomplete = react_1.default.forwardRef((props, ref) => {
|
|
|
89
91
|
var _a;
|
|
90
92
|
(_a = fieldInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
91
93
|
}, 15);
|
|
92
|
-
}, [dispatch, onChange, items, multiple]);
|
|
94
|
+
}, [dispatch, onChange, onInputValueChange, items, multiple]);
|
|
93
95
|
/**
|
|
94
96
|
* API
|
|
95
97
|
*/
|
|
@@ -108,13 +110,27 @@ const Autocomplete = react_1.default.forwardRef((props, ref) => {
|
|
|
108
110
|
*/
|
|
109
111
|
const restoreInputValue = react_1.default.useCallback(() => {
|
|
110
112
|
// With multiple the field holds only the search text, the selected items are tags
|
|
111
|
-
|
|
113
|
+
// The controlled text is the value itself: it stays as it is
|
|
114
|
+
const newInputValue = isInputControlled
|
|
115
|
+
? controlledInputValue
|
|
116
|
+
: multiple || currentValue === null
|
|
117
|
+
? ''
|
|
118
|
+
: selectedItemToString(currentValue);
|
|
112
119
|
const newFilteredItems = applyFilterForItems(newInputValue, items);
|
|
113
120
|
dispatch((0, context_1.actionSetPartial)({
|
|
114
121
|
filteredItems: newFilteredItems,
|
|
115
122
|
inputValue: newInputValue,
|
|
116
123
|
}));
|
|
117
|
-
}, [
|
|
124
|
+
}, [
|
|
125
|
+
currentValue,
|
|
126
|
+
selectedItemToString,
|
|
127
|
+
multiple,
|
|
128
|
+
applyFilterForItems,
|
|
129
|
+
items,
|
|
130
|
+
dispatch,
|
|
131
|
+
isInputControlled,
|
|
132
|
+
controlledInputValue,
|
|
133
|
+
]);
|
|
118
134
|
const inputKeydownEvent = react_1.default.useCallback((event) => {
|
|
119
135
|
var _a, _b, _c, _d, _e;
|
|
120
136
|
if (!isFocusedRef.current) {
|
|
@@ -207,14 +223,35 @@ const Autocomplete = react_1.default.forwardRef((props, ref) => {
|
|
|
207
223
|
if (value === currentValue) {
|
|
208
224
|
return;
|
|
209
225
|
}
|
|
210
|
-
// With multiple the selected items are shown as tags and the search text is kept
|
|
211
|
-
|
|
226
|
+
// With multiple the selected items are shown as tags and the search text is kept,
|
|
227
|
+
// the controlled text is not replaced by the text of the item
|
|
228
|
+
dispatch((0, context_1.actionSetPartial)(multiple || isInputControlled
|
|
212
229
|
? { currentValue: value }
|
|
213
230
|
: {
|
|
214
231
|
currentValue: value,
|
|
215
232
|
inputValue: value === null ? '' : selectedItemToString(value),
|
|
216
233
|
}));
|
|
217
|
-
}, [
|
|
234
|
+
}, [
|
|
235
|
+
value,
|
|
236
|
+
multiple,
|
|
237
|
+
currentValue,
|
|
238
|
+
inputValue,
|
|
239
|
+
dispatch,
|
|
240
|
+
selectedItemToString,
|
|
241
|
+
isInputControlled,
|
|
242
|
+
]);
|
|
243
|
+
/**
|
|
244
|
+
* The controlled text: the field follows `inputValue`
|
|
245
|
+
*/
|
|
246
|
+
react_1.default.useEffect(() => {
|
|
247
|
+
if (!isInputControlled || controlledInputValue === inputValue) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
dispatch((0, context_1.actionSetPartial)({
|
|
251
|
+
inputValue: controlledInputValue,
|
|
252
|
+
filteredItems: applyFilterForItems(controlledInputValue, items),
|
|
253
|
+
}));
|
|
254
|
+
}, [isInputControlled, controlledInputValue, inputValue, dispatch, applyFilterForItems, items]);
|
|
218
255
|
react_1.default.useEffect(() => {
|
|
219
256
|
if (currentOpen && menuRef.current) {
|
|
220
257
|
menuRef.current.scrollToFirstSelected();
|
|
@@ -305,6 +342,7 @@ const Autocomplete = react_1.default.forwardRef((props, ref) => {
|
|
|
305
342
|
if (typeof onInputChange === 'function') {
|
|
306
343
|
onInputChange(event);
|
|
307
344
|
}
|
|
345
|
+
onInputValueChange === null || onInputValueChange === void 0 ? void 0 : onInputValueChange(event.currentTarget.value);
|
|
308
346
|
// If openOnFocus is false, but value is not empty
|
|
309
347
|
// we should open menu list if is not opened
|
|
310
348
|
if (!openOnFocus && isFocusedRef.current && !currentOpen && filteredItems.length > 0) {
|
|
@@ -328,6 +366,7 @@ const Autocomplete = react_1.default.forwardRef((props, ref) => {
|
|
|
328
366
|
filteredItems.length,
|
|
329
367
|
items,
|
|
330
368
|
onInputChange,
|
|
369
|
+
onInputValueChange,
|
|
331
370
|
onRequestClose,
|
|
332
371
|
onRequestOpen,
|
|
333
372
|
openOnFocus,
|
package/Badge/BadgeBase.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { BadgeIconWrapperProps } from './BadgeIconWrapper';
|
|
|
3
3
|
import { BadgeTextWrapperProps } from './BadgeTextWrapper';
|
|
4
4
|
import { BadgeContainerProps } from './BadgeContainer';
|
|
5
5
|
import { BadgeDeleteButtonProps } from './BadgeDeleteButton';
|
|
6
|
+
import { BadgeDotProps } from './BadgeDot';
|
|
6
7
|
type BadgeNativeProps = React.HTMLAttributes<HTMLSpanElement>;
|
|
7
8
|
export interface BadgeBaseProps extends Omit<BadgeNativeProps, 'color'> {
|
|
8
9
|
/**
|
|
@@ -15,13 +16,17 @@ export interface BadgeBaseProps extends Omit<BadgeNativeProps, 'color'> {
|
|
|
15
16
|
* ```
|
|
16
17
|
*/
|
|
17
18
|
readonly startIcon?: React.JSX.Element;
|
|
19
|
+
/**
|
|
20
|
+
* The colored dot before the text: the status (active, overdue, paid)
|
|
21
|
+
*/
|
|
22
|
+
readonly dot?: boolean;
|
|
18
23
|
/**
|
|
19
24
|
* Badge style variant\
|
|
20
25
|
* Allowed variants: `standard` or `outlined`\
|
|
21
26
|
* \
|
|
22
27
|
* **Default**: `standard`
|
|
23
28
|
*/
|
|
24
|
-
readonly variant?: 'standard' | 'outlined';
|
|
29
|
+
readonly variant?: 'standard' | 'outlined' | 'soft';
|
|
25
30
|
/**
|
|
26
31
|
* You can pass the primary, default, secondary name of the colors or your specified color value
|
|
27
32
|
*/
|
|
@@ -58,6 +63,10 @@ export interface BadgeBaseOverrides {
|
|
|
58
63
|
* Icon delete
|
|
59
64
|
*/
|
|
60
65
|
readonly ButtonDelete?: React.ComponentType<BadgeDeleteButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
66
|
+
/**
|
|
67
|
+
* The dot. Rendered only with `dot`
|
|
68
|
+
*/
|
|
69
|
+
readonly Dot?: React.ComponentType<BadgeDotProps & React.RefAttributes<HTMLSpanElement>>;
|
|
61
70
|
}
|
|
62
71
|
declare const _default: React.ForwardRefExoticComponent<BadgeBaseProps & React.RefAttributes<HTMLSpanElement>>;
|
|
63
72
|
export default _default;
|
package/Badge/BadgeBase.js
CHANGED
|
@@ -19,14 +19,16 @@ const BadgeIconWrapper_1 = __importDefault(require("./BadgeIconWrapper"));
|
|
|
19
19
|
const BadgeTextWrapper_1 = __importDefault(require("./BadgeTextWrapper"));
|
|
20
20
|
const BadgeContainer_1 = __importDefault(require("./BadgeContainer"));
|
|
21
21
|
const BadgeDeleteButton_1 = __importDefault(require("./BadgeDeleteButton"));
|
|
22
|
+
const BadgeDot_1 = __importDefault(require("./BadgeDot"));
|
|
22
23
|
const BadgeBase = (props, ref) => {
|
|
23
|
-
const { children, startIcon, color, variant, overrides, onDelete, deleteButtonLabel = 'Delete', onClick, onKeyDown } = props, nativeProps = __rest(props, ["children", "startIcon", "color", "variant", "overrides", "onDelete", "deleteButtonLabel", "onClick", "onKeyDown"]);
|
|
24
|
+
const { children, startIcon, dot = false, color, variant, overrides, onDelete, deleteButtonLabel = 'Delete', onClick, onKeyDown } = props, nativeProps = __rest(props, ["children", "startIcon", "dot", "color", "variant", "overrides", "onDelete", "deleteButtonLabel", "onClick", "onKeyDown"]);
|
|
24
25
|
const clickable = typeof onClick === 'function';
|
|
25
26
|
const overridesMap = react_1.default.useMemo(() => ({
|
|
26
27
|
TextWrapper: (overrides === null || overrides === void 0 ? void 0 : overrides.TextWrapper) || BadgeTextWrapper_1.default,
|
|
27
28
|
IconWrapper: (overrides === null || overrides === void 0 ? void 0 : overrides.IconWrapper) || BadgeIconWrapper_1.default,
|
|
28
29
|
Container: (overrides === null || overrides === void 0 ? void 0 : overrides.Container) || BadgeContainer_1.default,
|
|
29
30
|
ButtonDelete: (overrides === null || overrides === void 0 ? void 0 : overrides.ButtonDelete) || BadgeDeleteButton_1.default,
|
|
31
|
+
Dot: (overrides === null || overrides === void 0 ? void 0 : overrides.Dot) || BadgeDot_1.default,
|
|
30
32
|
}), [overrides]);
|
|
31
33
|
// A clickable badge acts as a button, so it is activated by Enter and Space too
|
|
32
34
|
const handleKeyDown = react_1.default.useCallback((event) => {
|
|
@@ -46,8 +48,13 @@ const BadgeBase = (props, ref) => {
|
|
|
46
48
|
onDelete === null || onDelete === void 0 ? void 0 : onDelete(event);
|
|
47
49
|
}, [onDelete]);
|
|
48
50
|
return (react_1.default.createElement(overridesMap.Container, Object.assign({ role: clickable ? 'button' : undefined, tabIndex: clickable ? 0 : undefined }, nativeProps, { onClick: onClick, onKeyDown: handleKeyDown, color: color, ref: ref }),
|
|
51
|
+
dot && react_1.default.createElement(overridesMap.Dot, null),
|
|
49
52
|
typeof startIcon !== 'undefined' && startIcon !== null && (react_1.default.createElement(overridesMap.IconWrapper, null, startIcon)),
|
|
50
53
|
react_1.default.createElement(overridesMap.TextWrapper, null, children),
|
|
51
|
-
typeof onDelete === 'function' && (react_1.default.createElement(overridesMap.ButtonDelete
|
|
54
|
+
typeof onDelete === 'function' && (react_1.default.createElement(overridesMap.ButtonDelete
|
|
55
|
+
// the pale soft badge has the colored icon, as the outlined one
|
|
56
|
+
, {
|
|
57
|
+
// the pale soft badge has the colored icon, as the outlined one
|
|
58
|
+
variant: variant === 'soft' ? 'outlined' : variant, onClick: handleDelete, color: color, "aria-label": deleteButtonLabel }))));
|
|
52
59
|
};
|
|
53
60
|
exports.default = react_1.default.forwardRef(BadgeBase);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const styled_1 = __importDefault(require("@emotion/styled"));
|
|
8
|
+
/**
|
|
9
|
+
* The color of the badge (`--badge-dot-color`), not the color of its text
|
|
10
|
+
*/
|
|
11
|
+
const StyledDot = styled_1.default.span `
|
|
12
|
+
flex: none;
|
|
13
|
+
width: 0.5em;
|
|
14
|
+
height: 0.5em;
|
|
15
|
+
margin-left: 0.55em;
|
|
16
|
+
border-radius: 50%;
|
|
17
|
+
background-color: var(--badge-dot-color, currentColor);
|
|
18
|
+
`;
|
|
19
|
+
const BadgeDot = (props, ref) => (react_1.default.createElement(StyledDot, Object.assign({ "aria-hidden": true }, props, { ref: ref })));
|
|
20
|
+
exports.default = react_1.default.forwardRef(BadgeDot);
|
package/Badge/BadgeStyled.js
CHANGED
|
@@ -70,6 +70,23 @@ const getOutlinedColors = (color, theme) => {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* The pale background of the color and the text of the same hue: dark on the light theme,
|
|
75
|
+
* light on the dark one. `$background` is the color itself
|
|
76
|
+
*/
|
|
77
|
+
const getSoftColors = (color, theme) => {
|
|
78
|
+
const base = color === 'primary'
|
|
79
|
+
? theme.color.accentPrimary
|
|
80
|
+
: color === 'secondary'
|
|
81
|
+
? theme.color.accentSecondary
|
|
82
|
+
: typeof color === 'undefined' || color === 'default'
|
|
83
|
+
? theme.color.textPrimary
|
|
84
|
+
: parseColor(String(color), theme.color.textPrimary);
|
|
85
|
+
return {
|
|
86
|
+
$background: base,
|
|
87
|
+
$color: theme.isDark ? base.lighten(60) : base.darken(60),
|
|
88
|
+
};
|
|
89
|
+
};
|
|
73
90
|
/**
|
|
74
91
|
* Both variants are one styled component: switching the variant (e.g. a toggling filter badge)
|
|
75
92
|
* must not remount the element, otherwise the focused badge loses the focus
|
|
@@ -78,42 +95,62 @@ const StyledBadge = (0, styled_1.default)(BadgeBase_1.default) `
|
|
|
78
95
|
border-style: solid;
|
|
79
96
|
border-width: ${tokens_1.BORDER_WIDTH};
|
|
80
97
|
border-color: ${({ $background }) => $background.toString()};
|
|
98
|
+
--badge-dot-color: ${({ $variant, $background, $color }) => ($variant === 'standard' ? $color : $background).toString()};
|
|
81
99
|
|
|
82
|
-
${({ $variant, $color, $background
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
${({ $variant, $color, $background }) => $variant === 'soft' &&
|
|
101
|
+
(0, react_2.css) `
|
|
102
|
+
color: ${$color.toString()};
|
|
103
|
+
background-color: ${$background.alpha(0.18).toString()};
|
|
104
|
+
border-color: transparent;
|
|
86
105
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
: (0, react_2.css) `
|
|
94
|
-
color: ${$color.toString()};
|
|
95
|
-
background-color: ${$background.toString()};
|
|
106
|
+
&:focus-visible {
|
|
107
|
+
outline-style: solid;
|
|
108
|
+
outline-width: 0.14em;
|
|
109
|
+
outline-color: ${$background.alpha(0.6).toString()};
|
|
110
|
+
}
|
|
111
|
+
`}
|
|
96
112
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
${({ $variant, $color, $background, theme }) => $variant === 'soft'
|
|
114
|
+
? ''
|
|
115
|
+
: $variant === 'outlined'
|
|
116
|
+
? (0, react_2.css) `
|
|
117
|
+
color: ${$color.darken(30).toString()};
|
|
118
|
+
background-color: transparent;
|
|
119
|
+
|
|
120
|
+
&:focus-visible {
|
|
121
|
+
outline-style: solid;
|
|
122
|
+
outline-width: 0.14em;
|
|
123
|
+
outline-color: ${$background.rgbString()};
|
|
124
|
+
}
|
|
125
|
+
`
|
|
126
|
+
: (0, react_2.css) `
|
|
127
|
+
color: ${$color.toString()};
|
|
128
|
+
background-color: ${$background.toString()};
|
|
129
|
+
|
|
130
|
+
&:focus-visible {
|
|
131
|
+
outline-color: ${$background.rgbString() === theme.color.accentPrimary.rgbString()
|
|
132
|
+
? theme.color.textPrimary.toString()
|
|
133
|
+
: theme.color.accentPrimary.toString()};
|
|
134
|
+
}
|
|
135
|
+
`}
|
|
103
136
|
|
|
104
137
|
${({ $clickable, $variant, $background }) => $clickable &&
|
|
105
138
|
(0, react_2.css) `
|
|
106
139
|
cursor: pointer;
|
|
107
140
|
|
|
108
141
|
&:hover {
|
|
109
|
-
${$variant === '
|
|
142
|
+
${$variant === 'soft'
|
|
110
143
|
? (0, react_2.css) `
|
|
111
|
-
background-color: ${$background.
|
|
144
|
+
background-color: ${$background.alpha(0.3).toString()};
|
|
112
145
|
`
|
|
113
|
-
:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
146
|
+
: $variant === 'outlined'
|
|
147
|
+
? (0, react_2.css) `
|
|
148
|
+
background-color: ${$background.darken(20).alpha(0.1).toString()};
|
|
149
|
+
`
|
|
150
|
+
: (0, react_2.css) `
|
|
151
|
+
background-color: ${$background.darken(30).toString()};
|
|
152
|
+
border-color: ${$background.darken(30).toString()};
|
|
153
|
+
`}
|
|
117
154
|
}
|
|
118
155
|
`}
|
|
119
156
|
${({ theme }) => (0, tokens_1.themeFocusRing)(theme)}
|
|
@@ -121,7 +158,11 @@ const StyledBadge = (0, styled_1.default)(BadgeBase_1.default) `
|
|
|
121
158
|
const BadgeStyled = (props, ref) => {
|
|
122
159
|
const { children, color, variant = 'standard', onClick } = props, restProps = __rest(props, ["children", "color", "variant", "onClick"]);
|
|
123
160
|
const theme = (0, react_2.useTheme)();
|
|
124
|
-
const { $background, $color } = react_1.default.useMemo(() => variant === '
|
|
161
|
+
const { $background, $color } = react_1.default.useMemo(() => variant === 'soft'
|
|
162
|
+
? getSoftColors(color, theme)
|
|
163
|
+
: variant === 'outlined'
|
|
164
|
+
? getOutlinedColors(color, theme)
|
|
165
|
+
: getStandardColors(color, theme), [color, variant, theme]);
|
|
125
166
|
return (react_1.default.createElement(StyledBadge, Object.assign({ "$variant": variant, "$clickable": typeof onClick === 'function', "$color": $color, "$background": $background, color: color, variant: variant, onClick: onClick }, restProps, { ref: ref }), children));
|
|
126
167
|
};
|
|
127
168
|
exports.default = react_1.default.forwardRef(BadgeStyled);
|
package/Badge/index.d.ts
CHANGED
|
@@ -4,19 +4,19 @@ import type { BadgeOutlinedProps } from './BadgeOutlined';
|
|
|
4
4
|
export type BadgeProps = (BadgeStandardProps | BadgeOutlinedProps) & {
|
|
5
5
|
/**
|
|
6
6
|
* Badge style variant\
|
|
7
|
-
* Allowed variants: `standard` or `
|
|
7
|
+
* Allowed variants: `standard`, `outlined` or `soft` (the pale background of the color)\
|
|
8
8
|
* \
|
|
9
9
|
* **Default**: `standard`
|
|
10
10
|
*/
|
|
11
|
-
readonly variant?: 'standard' | 'outlined';
|
|
11
|
+
readonly variant?: 'standard' | 'outlined' | 'soft';
|
|
12
12
|
};
|
|
13
13
|
declare const _default: React.ForwardRefExoticComponent<import("./BadgeBase").BadgeBaseProps & {
|
|
14
14
|
/**
|
|
15
15
|
* Badge style variant\
|
|
16
|
-
* Allowed variants: `standard` or `
|
|
16
|
+
* Allowed variants: `standard`, `outlined` or `soft` (the pale background of the color)\
|
|
17
17
|
* \
|
|
18
18
|
* **Default**: `standard`
|
|
19
19
|
*/
|
|
20
|
-
readonly variant?: "standard" | "outlined";
|
|
20
|
+
readonly variant?: "standard" | "outlined" | "soft";
|
|
21
21
|
} & React.RefAttributes<HTMLSpanElement>>;
|
|
22
22
|
export default _default;
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
Все заметные изменения пакета `@via-profit/ui-kit`. Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/), версии следуют [семантическому версионированию](https://semver.org/lang/ru/).
|
|
4
4
|
|
|
5
|
+
## 0.9.0 — 2026-10-19
|
|
6
|
+
|
|
7
|
+
### Добавлено
|
|
8
|
+
|
|
9
|
+
- **InfoNote** — информер: короткий текст в форме или карточке, который важно увидеть сразу. Варианты `info`, `success`, `warning`, `error` с цветами темы, заголовок `title`, своя иконка или без неё (`icon`), части `Container`, `Icon`, `Content`, `Title`;
|
|
10
|
+
- **FileDropzone** — загрузка файла: область, куда файл выбирают нажатием или перетаскивают. Выбранный файл — строка с именем и размером, кнопками «Заменить» и удаления. Проверка `accept` и `maxSize` с `onReject`, подписи на языке интерфейса, `formatSize` и функция `formatFileSize`, часть `Area`;
|
|
11
|
+
- **Badge**: вариант `soft` — бледная подложка цвета и текст того же оттенка (тёмный в светлой теме, светлый в тёмной) — и свойство `dot`: точка цвета бейджа перед текстом, для меток статуса. Часть `Dot`;
|
|
12
|
+
- **Autocomplete**: свободный текст с подсказками — `inputValue` и `onInputValueChange`. Текст поля — само значение (ИНН, название, адрес), список только подсказывает: поле не подменяет текст текстом выбранного элемента и не стирает его при уходе фокуса;
|
|
13
|
+
- **Skeleton** — заглушка загрузки: серая мерцающая фигура на месте содержимого. Варианты `text`, `rect`, `circle`, `pill`, размеры `width` и `height`; мерцание выключается при уменьшении движения в системе;
|
|
14
|
+
- **EmptyState** — пустое состояние: иллюстрация, что пусто (`title`), почему (`children`) и следующий шаг (`action`). Своя иллюстрация или без неё (`icon`), `fullHeight`, части `Container`, `Icon`, `Title`, `Content`, `Action`;
|
|
15
|
+
- **HintPopover** — кнопка «?», которая по нажатию открывает всплывающий блок с пояснением. Кнопка берёт цвет окружающего текста, подсказка закрывается кликом вне неё и Escape (фокус возвращается на кнопку), показывается поверх модальных окон. Свойства `label`, `placement`, `isOpen`/`onOpenChange`, части `Button` и `Container`.
|
|
16
|
+
|
|
17
|
+
## 0.8.0 — 2026-10-13
|
|
18
|
+
|
|
19
|
+
Drawer: закрытие свайпом.
|
|
20
|
+
|
|
21
|
+
### Добавлено
|
|
22
|
+
|
|
23
|
+
- **Modal**: свойство `swipeToClose` у `drawer` — панель закрывается свайпом к своему краю. Она следует за пальцем, короткий свайп возвращает её на место, прокручиваемое содержимое сначала прокручивается. На стороне, обращённой к странице, появляется полоска-ручка, за которую панель перетаскивается мышью.
|
|
24
|
+
|
|
5
25
|
## 0.7.0 — 2026-10-09
|
|
6
26
|
|
|
7
27
|
Swiper: дробный `slidesPerView` и `centered`, вертикальная прокрутка, затухание и бегущая лента.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const styled_1 = __importDefault(require("@emotion/styled"));
|
|
8
|
+
const StyledAction = styled_1.default.div `
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-wrap: wrap;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
gap: 0.5em;
|
|
13
|
+
margin-top: 0.5em;
|
|
14
|
+
`;
|
|
15
|
+
const EmptyStateAction = (props, ref) => react_1.default.createElement(StyledAction, Object.assign({}, props, { ref: ref }));
|
|
16
|
+
exports.default = react_1.default.forwardRef(EmptyStateAction);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type EmptyStateContainerProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
3
|
+
readonly fullHeight: boolean;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
6
|
+
readonly fullHeight: boolean;
|
|
7
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,34 @@
|
|
|
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 StyledContainer = styled_1.default.div `
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
align-items: center;
|
|
24
|
+
justify-content: center;
|
|
25
|
+
gap: 0.75em;
|
|
26
|
+
padding: 2em 1em;
|
|
27
|
+
text-align: center;
|
|
28
|
+
height: ${({ $fullHeight }) => ($fullHeight ? '100%' : 'auto')};
|
|
29
|
+
`;
|
|
30
|
+
const EmptyStateContainer = (props, ref) => {
|
|
31
|
+
const { fullHeight } = props, nativeProps = __rest(props, ["fullHeight"]);
|
|
32
|
+
return react_1.default.createElement(StyledContainer, Object.assign({}, nativeProps, { "$fullHeight": fullHeight, ref: ref }));
|
|
33
|
+
};
|
|
34
|
+
exports.default = react_1.default.forwardRef(EmptyStateContainer);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const styled_1 = __importDefault(require("@emotion/styled"));
|
|
8
|
+
const StyledContent = styled_1.default.div `
|
|
9
|
+
max-width: 22em;
|
|
10
|
+
font-size: 0.9em;
|
|
11
|
+
line-height: 1.45;
|
|
12
|
+
color: ${({ theme }) => theme.color.textSecondary.toString()};
|
|
13
|
+
`;
|
|
14
|
+
const EmptyStateContent = (props, ref) => react_1.default.createElement(StyledContent, Object.assign({}, props, { ref: ref }));
|
|
15
|
+
exports.default = react_1.default.forwardRef(EmptyStateContent);
|
|
@@ -0,0 +1,38 @@
|
|
|
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 StyledIcon = styled_1.default.span `
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
margin-bottom: 0.75em;
|
|
22
|
+
font-size: 6em;
|
|
23
|
+
color: ${({ theme }) => theme.color.textPrimary.alpha(0.6).toString()};
|
|
24
|
+
`;
|
|
25
|
+
const Path = styled_1.default.path `
|
|
26
|
+
fill: currentColor;
|
|
27
|
+
`;
|
|
28
|
+
/**
|
|
29
|
+
* The open empty box. `children` replaces it
|
|
30
|
+
*/
|
|
31
|
+
const EmptyStateIcon = (props, ref) => {
|
|
32
|
+
const { children } = props, nativeProps = __rest(props, ["children"]);
|
|
33
|
+
return (react_1.default.createElement(StyledIcon, Object.assign({ "aria-hidden": true }, 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 511.99 511.99" },
|
|
34
|
+
react_1.default.createElement(Path, { d: "M446.822 213.631l-190.827-63.256-190.827 63.256L.01 317.129l59.984 19.884V447.02l196 64.97 196-64.97V337.013l59.984-19.884zm-57.5 12.545l-133.327 44.195-133.327-44.195 133.327-44.195zm-343.52 74.527l35.627-56.592 151.67 50.276-35.626 56.591zm44.193 46.255L210.34 386.85l30.655-48.693v137.256l-151-50.054zm181 128.454V338.156l30.655 48.693 120.345-39.892v78.401zm43.522-124.433l-35.626-56.591 151.67-50.276 35.627 56.592zM240.995 0h30v100.174h-30z" }),
|
|
35
|
+
react_1.default.createElement(Path, { d: "M122.952 31.63h30v100.174h-30z", transform: "rotate(-30 137.947 81.722)" }),
|
|
36
|
+
react_1.default.createElement(Path, { d: "M323.951 66.717h100.174v30H323.951z", transform: "rotate(-60 374.044 81.724)" })))));
|
|
37
|
+
};
|
|
38
|
+
exports.default = react_1.default.forwardRef(EmptyStateIcon);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const styled_1 = __importDefault(require("@emotion/styled"));
|
|
8
|
+
const StyledTitle = styled_1.default.div `
|
|
9
|
+
font-weight: 600;
|
|
10
|
+
color: ${({ theme }) => theme.color.textPrimary.toString()};
|
|
11
|
+
`;
|
|
12
|
+
const EmptyStateTitle = (props, ref) => react_1.default.createElement(StyledTitle, Object.assign({}, props, { ref: ref }));
|
|
13
|
+
exports.default = react_1.default.forwardRef(EmptyStateTitle);
|