@uxf/ui 11.34.0 → 11.35.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/button/button.d.ts +1 -1
- package/button-list/button-list.js +3 -2
- package/chip/chip.d.ts +2 -0
- package/chip/chip.js +3 -2
- package/combobox/combobox.js +10 -8
- package/combobox/combobox.spec.js +2 -2
- package/combobox/combobox.stories.d.ts +2 -9
- package/combobox/combobox.stories.js +14 -41
- package/css/pagination.css +2 -2
- package/dropdown/dropdown.d.ts +2 -0
- package/dropdown/dropdown.js +3 -2
- package/dropzone/README.md +99 -1
- package/dropzone/dropzone-input.d.ts +4 -2
- package/dropzone/dropzone-input.js +5 -16
- package/dropzone/dropzone-list.d.ts +5 -2
- package/dropzone/dropzone-list.js +8 -7
- package/dropzone/dropzone.stories.d.ts +1 -2
- package/dropzone/dropzone.stories.js +29 -37
- package/dropzone/handle-rejected-files.d.ts +2 -0
- package/dropzone/handle-rejected-files.js +17 -0
- package/dropzone/index.d.ts +2 -1
- package/list-item/list-item.d.ts +2 -0
- package/list-item/list-item.js +3 -2
- package/package.json +4 -4
- package/text-link/text-link.d.ts +2 -0
- package/text-link/text-link.js +3 -2
- /package/{button → utils}/next-link.d.ts +0 -0
- /package/{button → utils}/next-link.js +0 -0
package/button/button.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { UseAnchorProps } from "@uxf/core-react/hooks/use-anchor-props";
|
|
2
2
|
import { ButtonColors, ButtonSizes, ButtonVariants } from "@uxf/ui/button/theme";
|
|
3
3
|
import React, { AnchorHTMLAttributes } from "react";
|
|
4
|
-
import { NextLink } from "
|
|
4
|
+
import { NextLink } from "../utils/next-link";
|
|
5
5
|
export type ButtonVariant = keyof ButtonVariants;
|
|
6
6
|
export type ButtonSize = keyof ButtonSizes;
|
|
7
7
|
export type ButtonColor = keyof ButtonColors;
|
|
@@ -36,12 +36,13 @@ const use_dropdown_1 = require("../hooks/use-dropdown");
|
|
|
36
36
|
const icon_1 = require("../icon");
|
|
37
37
|
const MenuButton = (0, react_3.forwardRef)((props, ref) => {
|
|
38
38
|
// eslint-disable-next-line react/destructuring-assignment,@typescript-eslint/no-unused-vars
|
|
39
|
-
const { variant, color, isIconButton, isFullWidth, size, icon, label, className, ...restProps } = props;
|
|
39
|
+
const { as = "a", variant, color, isIconButton, isFullWidth, size, icon, label, className, ...restProps } = props;
|
|
40
|
+
const Component = as;
|
|
40
41
|
const anchorProps = (0, use_anchor_props_1.useAnchorProps)({
|
|
41
42
|
...restProps,
|
|
42
43
|
className: (0, cx_1.cx)("uxf-button-list__menu-button", `uxf-button-list__menu-button--color-${color !== null && color !== void 0 ? color : "default"}`, `uxf-button-list__menu-button--variant-${variant !== null && variant !== void 0 ? variant : "default"}`, className),
|
|
43
44
|
});
|
|
44
|
-
return (react_3.default.createElement(
|
|
45
|
+
return (react_3.default.createElement(Component, { ref: ref, ...anchorProps },
|
|
45
46
|
icon && react_3.default.createElement(icon_1.Icon, { className: "uxf-button-list__menu-button-icon", name: icon }),
|
|
46
47
|
label && react_3.default.createElement("span", { className: "uxf-button-list__menu-button-label" }, label)));
|
|
47
48
|
});
|
package/chip/chip.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { UseAnchorProps } from "@uxf/core-react/hooks/use-anchor-props";
|
|
2
2
|
import { ChipColor, ChipSize, ChipVariant } from "@uxf/ui/chip/theme";
|
|
3
3
|
import React, { AnchorHTMLAttributes, MouseEventHandler } from "react";
|
|
4
|
+
import { NextLink } from "../utils/next-link";
|
|
4
5
|
export interface ChipProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "color" | "type">, UseAnchorProps {
|
|
6
|
+
as?: NextLink | "a";
|
|
5
7
|
color?: ChipColor;
|
|
6
8
|
onClose?: MouseEventHandler;
|
|
7
9
|
size?: ChipSize;
|
package/chip/chip.js
CHANGED
|
@@ -42,14 +42,15 @@ const CloseButton = (props) => {
|
|
|
42
42
|
};
|
|
43
43
|
exports.Chip = (0, react_1.forwardRef)((props, ref) => {
|
|
44
44
|
var _a, _b, _c;
|
|
45
|
-
const { children, className, onClose, suppressFocus, tabIndex, ...restProps } = props;
|
|
45
|
+
const { as = "a", children, className, onClose, suppressFocus, tabIndex, ...restProps } = props;
|
|
46
46
|
const chipClassName = (0, cx_1.cx)("uxf-chip", `uxf-chip--color-${(_a = props.color) !== null && _a !== void 0 ? _a : "default"}`, `uxf-chip--size-${(_b = props.size) !== null && _b !== void 0 ? _b : "default"}`, `uxf-chip--variant-${(_c = props.variant) !== null && _c !== void 0 ? _c : "default"}`, (0, is_not_nil_1.isNotNil)(onClose) && "has-button", className);
|
|
47
|
+
const Component = as;
|
|
47
48
|
const anchorProps = (0, use_anchor_props_1.useAnchorProps)({
|
|
48
49
|
className: (0, cx_1.cx)(chipClassName),
|
|
49
50
|
tabIndex: suppressFocus ? -1 : tabIndex,
|
|
50
51
|
...restProps,
|
|
51
52
|
});
|
|
52
|
-
return (react_1.default.createElement(
|
|
53
|
+
return (react_1.default.createElement(Component, { ref: ref, ...anchorProps },
|
|
53
54
|
typeof children === "string" ? react_1.default.createElement("span", { className: "uxf-chip__text" }, children) : children,
|
|
54
55
|
(0, is_not_nil_1.isNotNil)(onClose) && react_1.default.createElement(CloseButton, { onClose: onClose })));
|
|
55
56
|
});
|
package/combobox/combobox.js
CHANGED
|
@@ -57,28 +57,30 @@ function Options(props) {
|
|
|
57
57
|
})) : (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage))));
|
|
58
58
|
}
|
|
59
59
|
Options.displayName = "UxfUiComboboxOptions";
|
|
60
|
+
// eslint-disable-next-line complexity
|
|
60
61
|
function Combobox(props) {
|
|
61
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
62
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
62
63
|
const isAsync = (0, is_not_nil_1.isNotNil)(props.loadOptions);
|
|
63
64
|
const [query, setQuery] = (0, react_3.useState)("");
|
|
64
|
-
const
|
|
65
|
+
const asyncOptions = (0, use_async_loading_1.useAsyncLoading)(query, (_a = props.options) !== null && _a !== void 0 ? _a : empty_array_1.EMPTY_ARRAY, props.loadOptions);
|
|
66
|
+
const options = isAsync ? asyncOptions : ((_b = props.options) !== null && _b !== void 0 ? _b : empty_array_1.EMPTY_ARRAY);
|
|
65
67
|
const filteredData = (0, is_empty_1.isEmpty)(query) || isAsync ? options : options.filter((item) => (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query)));
|
|
66
68
|
const emptyMessage = (0, is_empty_1.isEmpty)(query)
|
|
67
|
-
? ((
|
|
69
|
+
? ((_c = props.noQueryMessage) !== null && _c !== void 0 ? _c : "Pro zobrazení možností začněte psát")
|
|
68
70
|
: (0, is_empty_1.isEmpty)(options)
|
|
69
|
-
? ((
|
|
70
|
-
: ((
|
|
71
|
+
? ((_d = props.noOptionsMessage) !== null && _d !== void 0 ? _d : "Nabídka neosahuje žádné položky")
|
|
72
|
+
: ((_e = props.notFoundMessage) !== null && _e !== void 0 ? _e : "Nic nenalezeno");
|
|
71
73
|
const clearQuery = () => setQuery("");
|
|
72
74
|
const onChange = (v) => props.onChange(v);
|
|
73
75
|
const onInputChange = (event) => setQuery(event.target.value);
|
|
74
76
|
const displayValue = (item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.label) !== null && _a !== void 0 ? _a : ""; };
|
|
75
|
-
const selectedOption = (
|
|
77
|
+
const selectedOption = (_f = props.value) !== null && _f !== void 0 ? _f : null;
|
|
76
78
|
const generatedId = (0, react_3.useId)();
|
|
77
|
-
const id = (
|
|
79
|
+
const id = (_g = props.id) !== null && _g !== void 0 ? _g : generatedId;
|
|
78
80
|
const innerRef = (0, react_3.useRef)(null);
|
|
79
81
|
const errorId = props.isInvalid ? `${id}--error-message` : undefined;
|
|
80
82
|
const input = (0, use_input_focus_1.useInputFocus)(innerRef, props.onBlur, props.onFocus);
|
|
81
|
-
const dropdown = (0, use_dropdown_1.useDropdown)((
|
|
83
|
+
const dropdown = (0, use_dropdown_1.useDropdown)((_h = props.dropdownPlacement) !== null && _h !== void 0 ? _h : "bottom", (_j = props.dropdownMatchesInputWidth) !== null && _j !== void 0 ? _j : true, props.dropdownMaxHeight, props.dropdownStrategy);
|
|
82
84
|
const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(innerRef, props.inputGroupRef, dropdown.refs.setReference), [dropdown.refs.setReference, props.inputGroupRef]);
|
|
83
85
|
const isNotInteractive = props.isDisabled || props.isReadOnly;
|
|
84
86
|
return (react_3.default.createElement(react_2.Combobox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-combobox", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: isNotInteractive, form: props.form, name: props.name, onChange: onChange, style: props.style, value: selectedOption }, (renderProps) => (react_3.default.createElement(react_3.default.Fragment, null,
|
|
@@ -6,5 +6,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
const snap_test_1 = require("../utils/snap-test");
|
|
8
8
|
const combobox_stories_1 = require("./combobox.stories");
|
|
9
|
-
(0, snap_test_1.snapTest)("render default stories", react_1.default.createElement(combobox_stories_1.
|
|
10
|
-
(0, snap_test_1.snapTest)("render async stories", react_1.default.createElement(combobox_stories_1.
|
|
9
|
+
(0, snap_test_1.snapTest)("render default stories", react_1.default.createElement(combobox_stories_1.SynchronousOptions, null));
|
|
10
|
+
(0, snap_test_1.snapTest)("render async stories", react_1.default.createElement(combobox_stories_1.AsynchronousOptions, null));
|
|
@@ -1,10 +1,3 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
declare
|
|
4
|
-
title: string;
|
|
5
|
-
component: typeof Combobox;
|
|
6
|
-
};
|
|
7
|
-
export default _default;
|
|
8
|
-
export declare function Default(): React.JSX.Element;
|
|
9
|
-
export declare function Async(): React.JSX.Element;
|
|
10
|
-
export declare function ComponentStructure(): React.JSX.Element;
|
|
2
|
+
export declare function SynchronousOptions(): React.JSX.Element;
|
|
3
|
+
export declare function AsynchronousOptions(): React.JSX.Element;
|
|
@@ -22,61 +22,34 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
30
|
-
exports.
|
|
31
|
-
exports.ComponentStructure = ComponentStructure;
|
|
26
|
+
exports.SynchronousOptions = SynchronousOptions;
|
|
27
|
+
exports.AsynchronousOptions = AsynchronousOptions;
|
|
32
28
|
const react_1 = __importStar(require("react"));
|
|
33
29
|
const action_1 = require("../utils/action");
|
|
34
|
-
const component_structure_analyzer_1 = __importDefault(require("../utils/component-structure-analyzer"));
|
|
35
30
|
const index_1 = require("./index");
|
|
36
|
-
|
|
37
|
-
title: "UI/Combobox",
|
|
38
|
-
component: index_1.Combobox,
|
|
39
|
-
};
|
|
40
|
-
const options = [
|
|
31
|
+
const OPTIONS = [
|
|
41
32
|
{ id: "one", label: "Option one" },
|
|
42
33
|
{ id: "two", label: "Option two disabled", disabled: true },
|
|
43
34
|
{ id: "three", label: "Option three" },
|
|
44
35
|
{ id: "four", label: "Option with diacritics (ěščřžýáíé)" },
|
|
45
36
|
];
|
|
46
|
-
function
|
|
37
|
+
function SynchronousOptions() {
|
|
47
38
|
const [value, setValue] = (0, react_1.useState)(null);
|
|
48
|
-
const onChange = (0, action_1.action)("onChange",
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
react_1.default.createElement(index_1.Combobox, { id: "combobox-1", label: "Combobox", name: "combobox", onChange: onChange, options: options, placeholder: "Vyberte...", value: value }),
|
|
55
|
-
react_1.default.createElement(index_1.Combobox, { helperText: "Start typing to see options...", id: "combobox-1", label: "Combobox with helper text", name: "combobox", onChange: onChange, options: options, placeholder: "Vyberte...", value: value }),
|
|
56
|
-
react_1.default.createElement(index_1.Combobox, { helperText: "Error message", id: "combobox-1", isInvalid: true, isRequired: true, label: "Combobox invalid", name: "combobox", onChange: onChange, options: options, placeholder: "Vyberte...", value: value }),
|
|
57
|
-
react_1.default.createElement(index_1.Combobox, { dropdownPlacement: "top", id: "combobox-1", isClearable: true, label: "Combobox with dropdown top", name: "combobox", onChange: onChange, options: options, placeholder: "Vyberte...", value: value }),
|
|
58
|
-
react_1.default.createElement(index_1.Combobox, { id: "combobox-render", isClearable: true, label: "RenderOption", name: "combobox", onChange: onChange, options: options, placeholder: "Vyberte...", renderOption: (option, isSelected) => (react_1.default.createElement(react_1.default.Fragment, null,
|
|
39
|
+
const onChange = (0, action_1.action)("onChange", setValue);
|
|
40
|
+
return (react_1.default.createElement("div", { className: "space-y-4 p-4" },
|
|
41
|
+
react_1.default.createElement(index_1.Combobox, { helperText: "Start typing to see options...", id: "combobox-1", label: "Combobox", name: "combobox", onChange: onChange, options: OPTIONS, placeholder: "Vyberte...", value: value }),
|
|
42
|
+
react_1.default.createElement(index_1.Combobox, { helperText: "Error message", id: "combobox-1", isInvalid: true, isRequired: true, label: "Combobox invalid", name: "combobox", onChange: onChange, options: OPTIONS, placeholder: "Vyberte...", value: value }),
|
|
43
|
+
react_1.default.createElement(index_1.Combobox, { dropdownPlacement: "top", id: "combobox-1", isClearable: true, label: "Combobox with dropdown top", name: "combobox", onChange: onChange, options: OPTIONS, placeholder: "Vyberte...", value: value }),
|
|
44
|
+
react_1.default.createElement(index_1.Combobox, { id: "combobox-render", isClearable: true, label: "RenderOption", name: "combobox", onChange: onChange, options: OPTIONS, placeholder: "Vyberte...", renderOption: (option, isSelected) => (react_1.default.createElement(react_1.default.Fragment, null,
|
|
59
45
|
"Option: ",
|
|
60
46
|
option.label,
|
|
61
47
|
isSelected && " (selected)")), value: value })));
|
|
62
|
-
return (react_1.default.createElement("div", { className: "flex flex-col lg:flex-row" },
|
|
63
|
-
react_1.default.createElement("div", { className: "space-y-2 p-20 lg:w-1/2" }, storyComboboxes)));
|
|
64
48
|
}
|
|
65
|
-
function
|
|
49
|
+
function AsynchronousOptions() {
|
|
66
50
|
const [value, setValue] = (0, react_1.useState)(null);
|
|
67
|
-
const onChange = (0, action_1.action)("onChange",
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
setValue(v);
|
|
71
|
-
});
|
|
72
|
-
const loadOptions = (query) => Promise.resolve(options.filter((option) => !query || option.label.toLowerCase().includes(query.toLowerCase())));
|
|
73
|
-
const storyComboboxes = (react_1.default.createElement("div", { className: "space-y-8" },
|
|
51
|
+
const onChange = (0, action_1.action)("onChange", setValue);
|
|
52
|
+
const loadOptions = (query) => Promise.resolve(OPTIONS.filter((option) => !query || option.label.toLowerCase().includes(query.toLowerCase())));
|
|
53
|
+
return (react_1.default.createElement("div", { className: "p-4" },
|
|
74
54
|
react_1.default.createElement(index_1.Combobox, { id: "combobox-1", label: "Combobox", loadOptions: loadOptions, name: "combobox", onChange: onChange, placeholder: "Vyberte...", value: value })));
|
|
75
|
-
return (react_1.default.createElement("div", { className: "flex flex-col lg:flex-row" },
|
|
76
|
-
react_1.default.createElement("div", { className: "space-y-2 p-20 lg:w-1/2" }, storyComboboxes)));
|
|
77
|
-
}
|
|
78
|
-
function ComponentStructure() {
|
|
79
|
-
const [value, onChange] = (0, react_1.useState)(null);
|
|
80
|
-
return (react_1.default.createElement(component_structure_analyzer_1.default, null,
|
|
81
|
-
react_1.default.createElement(index_1.Combobox, { helperText: "Start typing to see options...", id: "combobox-structure", label: "Combobox with helper text", name: "combobox", onChange: onChange, options: options, value: value })));
|
|
82
55
|
}
|
package/css/pagination.css
CHANGED
package/dropdown/dropdown.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { UseAnchorProps } from "@uxf/core-react/hooks/use-anchor-props";
|
|
2
2
|
import React, { AnchorHTMLAttributes, HTMLAttributes } from "react";
|
|
3
|
+
import { NextLink } from "../utils/next-link";
|
|
3
4
|
export interface DropdownItemProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "type">, UseAnchorProps {
|
|
5
|
+
as?: NextLink | "a";
|
|
4
6
|
}
|
|
5
7
|
type ItemsProps = HTMLAttributes<HTMLDivElement>;
|
|
6
8
|
export type DropdownItemsProps = HTMLDivElement;
|
package/dropdown/dropdown.js
CHANGED
|
@@ -29,13 +29,14 @@ const cx_1 = require("@uxf/core/utils/cx");
|
|
|
29
29
|
const react_1 = __importStar(require("react"));
|
|
30
30
|
const Item = (0, react_1.forwardRef)((props, ref) => {
|
|
31
31
|
// eslint-disable-next-line react/destructuring-assignment
|
|
32
|
-
const { children, className, ...restProps } = props;
|
|
32
|
+
const { as = "a", children, className, ...restProps } = props;
|
|
33
|
+
const Component = as;
|
|
33
34
|
const anchorProps = (0, use_anchor_props_1.useAnchorProps)({
|
|
34
35
|
className: `uxf-dropdown__item ${className || ""}`,
|
|
35
36
|
role: "menuitem",
|
|
36
37
|
...restProps,
|
|
37
38
|
});
|
|
38
|
-
return (react_1.default.createElement(
|
|
39
|
+
return (react_1.default.createElement(Component, { ref: ref, ...anchorProps }, children));
|
|
39
40
|
});
|
|
40
41
|
Item.displayName = "UxfUiDropdownItem";
|
|
41
42
|
const Items = (0, react_1.forwardRef)((props, ref) => {
|
package/dropzone/README.md
CHANGED
|
@@ -1,8 +1,106 @@
|
|
|
1
1
|
# Dropzone
|
|
2
2
|
|
|
3
|
+
---
|
|
4
|
+
|
|
3
5
|
## CSS dependencies
|
|
4
6
|
|
|
5
7
|
```css
|
|
6
8
|
@import url("@uxf/ui/icon/icon.css");
|
|
7
9
|
@import url("@uxf/ui/dropzone/dropzone.css");
|
|
8
|
-
```
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
#### The Dropzone component is split into two parts:
|
|
15
|
+
|
|
16
|
+
1. `<Dropzone />` (**DropzoneInput**): This handles file input via drag-and-drop or file selection. It manages file upload and validation.
|
|
17
|
+
2. `<Dropzone.List />`: Displays the uploaded files and allows managing them (e.g., removing files) and provides the upload status of files. It works with the same `value` and `onChange` properties as the main `Dropzone` component to ensure synchronization between the uploaded files and their display.
|
|
18
|
+
|
|
19
|
+
### **getDropzoneState**
|
|
20
|
+
---
|
|
21
|
+
This function returns the current status of the uploaded files. It can be used to determine whether the Dropzone component should be disabled or not.
|
|
22
|
+
|
|
23
|
+
The status can be one of the following: `"ERROR" | "OK" | "UPLOADING"`
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
const { status } = getDropzoneState(files);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Component Overview
|
|
30
|
+
---
|
|
31
|
+
### How it works:
|
|
32
|
+
|
|
33
|
+
- `value` and `onChange`: Both components share the same `value`, which represents the list of uploaded files, and `onChange`, which updates that list. This ensures that the files selected for upload are consistent with what is displayed in the file list.
|
|
34
|
+
- We can use the `getDropzoneState` function to determine the current status of the uploaded files. This status can be used to disable the Dropzone component while files are being uploaded.
|
|
35
|
+
- We can use the `onDropRejected` prop to handle rejected files. This prop is called when the user tries to upload files that exceed the size limit or the maximum number of files allowed. We can use this prop to display an error message to the user.
|
|
36
|
+
|
|
37
|
+
Example of handling rejected files:
|
|
38
|
+
```tsx
|
|
39
|
+
const handleDropRejectedFiles = async (fileRejections: FileRejection[]) => {
|
|
40
|
+
const bigFiles = fileRejections.filter((rejection) =>
|
|
41
|
+
rejection.errors.some((error) => error.code === ErrorCode.FileTooLarge),
|
|
42
|
+
);
|
|
43
|
+
const tooManyFiles = fileRejections.filter((rejection) =>
|
|
44
|
+
rejection.errors.some((error) => error.code === ErrorCode.TooManyFiles),
|
|
45
|
+
);
|
|
46
|
+
if (isNotEmpty(bigFiles)) {
|
|
47
|
+
alert(
|
|
48
|
+
`Tyto soubory jsou příliš velké a nebyly nahrány: ${bigFiles.map((file) => file.file.name).join(", ")}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (isNotEmpty(tooManyFiles)) {
|
|
52
|
+
alert(`Bylo nahráno příliš mnoho souborů. Maximální počet souborů je ${fileCountLimit}`);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Basic Example:
|
|
58
|
+
---
|
|
59
|
+
This example shows how to use the **Dropzone** component with useState to manage file uploads:
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import React, {useState} from "react";
|
|
63
|
+
import {Dropzone} from "./path/to/dropzone";
|
|
64
|
+
import {DropzoneFile} from "./path/to/dropzone/types";
|
|
65
|
+
import {uploadFile} from "@uxf/ui/utils/mocks/upload-file.mock";
|
|
66
|
+
|
|
67
|
+
function BasicExample() {
|
|
68
|
+
// Store uploaded files in state
|
|
69
|
+
const [files, setFiles] = useState<DropzoneFile[]>([]);
|
|
70
|
+
|
|
71
|
+
// Get the current status of uploaded files
|
|
72
|
+
const { status } = getDropzoneState(files);
|
|
73
|
+
|
|
74
|
+
// Confirm file removal
|
|
75
|
+
const onRemoveConfirm = (): Promise<boolean> => Promise.resolve(confirm("Do you want to delete the file?"));
|
|
76
|
+
|
|
77
|
+
// Handle upload errors
|
|
78
|
+
const onUploadError = (error: unknown) => {
|
|
79
|
+
console.error(error);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<div>
|
|
84
|
+
{/* Dropzone component for uploading files */}
|
|
85
|
+
<Dropzone
|
|
86
|
+
isDisabled={status === "UPLOADING"}
|
|
87
|
+
onChange={setFiles}
|
|
88
|
+
onUploadError={onUploadError}
|
|
89
|
+
onUploadFile={uploadFile}
|
|
90
|
+
value={files}
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
{/* List of uploaded files */}
|
|
94
|
+
<Dropzone.List
|
|
95
|
+
onChange={setFiles}
|
|
96
|
+
onRemoveConfirm={onRemoveConfirm}
|
|
97
|
+
value={files}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Advanced Example:
|
|
105
|
+
---
|
|
106
|
+
This example shows how to use the **Dropzone** component with limited file types and sizes:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FileResponse } from "@uxf/core/types";
|
|
2
2
|
import { FormControlProps, UploadOptions } from "@uxf/ui/types";
|
|
3
3
|
import React, { CSSProperties, ReactNode } from "react";
|
|
4
|
+
import { FileRejection } from "react-dropzone";
|
|
4
5
|
import { IconName } from "../icon/types";
|
|
5
6
|
import { Accept, DropzoneFile } from "./types";
|
|
6
7
|
export interface DropzoneInputProps extends FormControlProps<DropzoneFile[] | undefined> {
|
|
@@ -9,12 +10,13 @@ export interface DropzoneInputProps extends FormControlProps<DropzoneFile[] | un
|
|
|
9
10
|
helperText?: ReactNode;
|
|
10
11
|
icon?: IconName;
|
|
11
12
|
id?: string;
|
|
13
|
+
isNotClickable?: boolean;
|
|
14
|
+
isNotDraggable?: boolean;
|
|
12
15
|
label?: ReactNode;
|
|
13
16
|
maxFileSize?: number;
|
|
14
17
|
maxFilesCount?: number;
|
|
15
18
|
minFileSize?: number;
|
|
16
|
-
|
|
17
|
-
noDrag?: boolean;
|
|
19
|
+
onDropRejected?: (fileRejections: FileRejection[]) => void;
|
|
18
20
|
onUploadError?: (err: unknown) => void;
|
|
19
21
|
onUploadFile: (file: File, options?: UploadOptions) => Promise<FileResponse>;
|
|
20
22
|
style?: CSSProperties;
|
|
@@ -30,7 +30,6 @@ const cx_1 = require("@uxf/core/utils/cx");
|
|
|
30
30
|
const react_1 = __importStar(require("react"));
|
|
31
31
|
const react_dropzone_1 = require("react-dropzone");
|
|
32
32
|
const icon_1 = require("../icon");
|
|
33
|
-
const validator_exceptions_1 = require("../utils/validator/validator-exceptions");
|
|
34
33
|
function fileToFileResponse(file) {
|
|
35
34
|
return {
|
|
36
35
|
id: -Math.round(Math.random() * 100000000),
|
|
@@ -68,16 +67,6 @@ exports.DropzoneInput = (0, react_1.forwardRef)((props, ref) => {
|
|
|
68
67
|
var _a, _b;
|
|
69
68
|
const refValue = (0, react_1.useRef)();
|
|
70
69
|
refValue.current = props.value;
|
|
71
|
-
const handleFileRejected = async (fileRejections) => {
|
|
72
|
-
fileRejections.forEach((fileRejection) => {
|
|
73
|
-
if (props.maxFileSize && fileRejection.file.size > props.maxFileSize) {
|
|
74
|
-
if (props.onUploadError) {
|
|
75
|
-
props.onUploadError(validator_exceptions_1.ValidatorExceptions.MaxFileSize);
|
|
76
|
-
}
|
|
77
|
-
throw validator_exceptions_1.ValidatorExceptions.MaxFileSize;
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
70
|
const handleFileDrop = async (acceptedFiles, inputRef) => {
|
|
82
71
|
const files = acceptedFiles.map((file) => ({
|
|
83
72
|
...fileToFileResponse(file),
|
|
@@ -116,18 +105,18 @@ exports.DropzoneInput = (0, react_1.forwardRef)((props, ref) => {
|
|
|
116
105
|
maxSize: props.maxFileSize,
|
|
117
106
|
minSize: props.minFileSize,
|
|
118
107
|
multiple: props.maxFilesCount !== 1,
|
|
119
|
-
noClick: props.
|
|
120
|
-
noDrag: props.
|
|
108
|
+
noClick: props.isNotClickable,
|
|
109
|
+
noDrag: props.isNotDraggable,
|
|
121
110
|
onDrop: (acceptedFiles) => handleFileDrop(acceptedFiles, inputRef),
|
|
122
|
-
preventDropOnDocument: props.
|
|
123
|
-
onDropRejected:
|
|
111
|
+
preventDropOnDocument: props.isNotDraggable,
|
|
112
|
+
onDropRejected: props.onDropRejected,
|
|
124
113
|
});
|
|
125
114
|
const labelOnCLick = (e) => {
|
|
126
115
|
e.stopPropagation();
|
|
127
116
|
};
|
|
128
117
|
return (react_1.default.createElement("div", { className: `uxf-dropzone ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, style: props.style },
|
|
129
118
|
react_1.default.createElement("label", { ...getRootProps({
|
|
130
|
-
className: (0, cx_1.cx)("uxf-dropzone__label", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.
|
|
119
|
+
className: (0, cx_1.cx)("uxf-dropzone__label", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.isNotClickable && "cursor-auto"),
|
|
131
120
|
onClick: labelOnCLick,
|
|
132
121
|
}), ref: (0, compose_refs_1.composeRefs)(ref, rootRef) },
|
|
133
122
|
react_1.default.createElement(icon_1.Icon, { className: "uxf-dropzone__label__icon", name: (_b = props.icon) !== null && _b !== void 0 ? _b : "cloud" }),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FormControlProps } from "@uxf/ui/types";
|
|
2
|
-
import { CSSProperties,
|
|
2
|
+
import React, { CSSProperties, ReactNode } from "react";
|
|
3
3
|
import { DropzoneFile } from "./types";
|
|
4
4
|
export interface DropzoneListProps extends FormControlProps<DropzoneFile[] | undefined> {
|
|
5
5
|
className?: string;
|
|
@@ -9,4 +9,7 @@ export interface DropzoneListProps extends FormControlProps<DropzoneFile[] | und
|
|
|
9
9
|
renderItem?: (file: DropzoneFile) => ReactNode;
|
|
10
10
|
style?: CSSProperties;
|
|
11
11
|
}
|
|
12
|
-
export declare
|
|
12
|
+
export declare function DropzoneList(props: DropzoneListProps): React.JSX.Element | null;
|
|
13
|
+
export declare namespace DropzoneList {
|
|
14
|
+
var displayName: string;
|
|
15
|
+
}
|
|
@@ -23,7 +23,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.DropzoneList =
|
|
26
|
+
exports.DropzoneList = DropzoneList;
|
|
27
|
+
const hide_1 = require("@uxf/core-react/components/hide");
|
|
27
28
|
const classes_1 = require("@uxf/core/constants/classes");
|
|
28
29
|
const cx_1 = require("@uxf/core/utils/cx");
|
|
29
30
|
const context_1 = require("@uxf/ui/context");
|
|
@@ -39,7 +40,7 @@ function formatBytes(bytes, decimals = 2) {
|
|
|
39
40
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
40
41
|
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
+
function DropzoneList(props) {
|
|
43
44
|
var _a, _b, _c;
|
|
44
45
|
const context = (0, react_1.useContext)(context_1.UiContext);
|
|
45
46
|
const handleRemove = (file, value, isUploading) => {
|
|
@@ -76,10 +77,10 @@ const DropzoneList = (props) => {
|
|
|
76
77
|
react_1.default.createElement("div", { className: "uxf-dropzone-list__item__block" },
|
|
77
78
|
isUploading ? (react_1.default.createElement(loader_1.Loader, { size: "sm" })) : (!file.error &&
|
|
78
79
|
((_c = file.originalFile) === null || _c === void 0 ? void 0 : _c.size) && (react_1.default.createElement("span", { className: "uxf-dropzone-list__item__block__file-size" }, formatBytes(file.originalFile.size)))),
|
|
79
|
-
react_1.default.createElement(
|
|
80
|
-
react_1.default.createElement(
|
|
80
|
+
react_1.default.createElement(hide_1.Hide, { when: Boolean(props.isDisabled) },
|
|
81
|
+
react_1.default.createElement("button", { className: "uxf-dropzone-list__item__block__remove-button", onClick: onRemove(file, isUploading), type: "button" },
|
|
82
|
+
react_1.default.createElement(icon_1.Icon, { className: "uxf-dropzone-list__item__block__remove-button__icon", name: "xmarkLarge" }))))),
|
|
81
83
|
Boolean(file.error) && (react_1.default.createElement("span", { className: (0, cx_1.cx)("uxf-helper-text", classes_1.CLASSES.IS_INVALID) }, props.errorText || "File upload error")))));
|
|
82
84
|
})));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
exports.DropzoneList.displayName = "UxfUiDropzoneList";
|
|
85
|
+
}
|
|
86
|
+
DropzoneList.displayName = "UxfUiDropzoneList";
|
|
@@ -2,9 +2,8 @@ import React from "react";
|
|
|
2
2
|
declare const _default: {
|
|
3
3
|
title: string;
|
|
4
4
|
component: React.ForwardRefExoticComponent<import("./dropzone-input").DropzoneInputProps & React.RefAttributes<HTMLDivElement>> & {
|
|
5
|
-
List:
|
|
5
|
+
List: typeof import("./dropzone-list").DropzoneList;
|
|
6
6
|
};
|
|
7
7
|
};
|
|
8
8
|
export default _default;
|
|
9
9
|
export declare function Default(): React.JSX.Element;
|
|
10
|
-
export declare function ComponentStructure(): React.JSX.Element;
|
|
@@ -22,54 +22,46 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
26
|
exports.Default = Default;
|
|
30
|
-
|
|
31
|
-
const
|
|
27
|
+
const show_1 = require("@uxf/core-react/components/show");
|
|
28
|
+
const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
|
|
29
|
+
const handle_rejected_files_1 = require("@uxf/ui/dropzone/handle-rejected-files");
|
|
32
30
|
const react_1 = __importStar(require("react"));
|
|
33
|
-
const
|
|
34
|
-
const context_1 = require("../context");
|
|
35
|
-
const message_1 = require("../message");
|
|
31
|
+
const toggle_1 = require("../toggle");
|
|
36
32
|
const action_1 = require("../utils/action");
|
|
37
|
-
const get_dropzone_state_1 = require("../utils/get-dropzone-state");
|
|
38
33
|
const upload_file_mock_1 = require("../utils/mocks/upload-file.mock");
|
|
39
34
|
const index_1 = require("./index");
|
|
40
35
|
exports.default = {
|
|
41
36
|
title: "UI/Dropzone",
|
|
42
37
|
component: index_1.Dropzone,
|
|
43
38
|
};
|
|
39
|
+
const MB_SIZE = 1024 * 1024;
|
|
44
40
|
function Default() {
|
|
41
|
+
const [isDisabled, setIsDisabled] = (0, react_1.useState)(false);
|
|
42
|
+
const [isFileCountLimited, setIsFileCountLimited] = (0, react_1.useState)(false);
|
|
43
|
+
const [fileCountLimit, setFileCountLimit] = (0, react_1.useState)(1);
|
|
44
|
+
const [isFileSizeLimited, setIsFileSizeLimited] = (0, react_1.useState)(false);
|
|
45
|
+
const [fileSizeLimit, setFileSizeLimit] = (0, react_1.useState)(1);
|
|
46
|
+
const [hasOnlyImagesAllowed, setHasOnlyImagesAllowed] = (0, react_1.useState)(false);
|
|
45
47
|
const [files, setFiles] = (0, react_1.useState)([]);
|
|
46
48
|
const onChange = (0, action_1.action)("onChange", setFiles);
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
react_1.default.createElement(index_1.Dropzone, { accept: { "image/*": [] }, label: "Only images upload", name: "dropzone-only-images", onChange: onChange, onUploadFile: upload_file_mock_1.uploadFile, value: files }),
|
|
66
|
-
react_1.default.createElement(index_1.Dropzone, { label: "Single file upload", maxFilesCount: 1, name: "dropzone-single-file", onChange: onChange, onUploadFile: upload_file_mock_1.uploadFile, value: files }),
|
|
67
|
-
react_1.default.createElement(index_1.Dropzone, { isDisabled: true, label: "Disabled dropzone", name: "dropzone-disabled", onChange: onChange, onUploadFile: upload_file_mock_1.uploadFile, value: files }),
|
|
68
|
-
react_1.default.createElement(index_1.Dropzone.List, { errorText: "Chyba p\u0159i nahr\u00E1v\u00E1n\u00ED souboru", name: "dropzone-error-message", onChange: onChange, onRemoveConfirm: onRemoveConfirm, value: files }),
|
|
69
|
-
react_1.default.createElement(index_1.Dropzone.List, { name: "dropzone-list", onChange: onChange, onRemoveConfirm: onRemoveConfirm, renderItem: (file) => (react_1.default.createElement("li", { key: file.id },
|
|
70
|
-
react_1.default.createElement("pre", { className: "text-wrap" }, JSON.stringify(file, null, 4)))), value: files })));
|
|
71
|
-
}
|
|
72
|
-
function ComponentStructure() {
|
|
73
|
-
return (react_1.default.createElement(component_structure_analyzer_1.default, null,
|
|
74
|
-
react_1.default.createElement(index_1.Dropzone, null)));
|
|
49
|
+
const onRemoveConfirm = () => Promise.resolve(confirm("Do you want to delete the file?"));
|
|
50
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
51
|
+
react_1.default.createElement(toggle_1.Toggle, { label: "Disabled", name: "toggle", onChange: () => setIsDisabled((prev) => !prev), value: isDisabled }),
|
|
52
|
+
react_1.default.createElement(toggle_1.Toggle, { label: "Only images upload", name: "toggle", onChange: () => setHasOnlyImagesAllowed((prev) => !prev), value: hasOnlyImagesAllowed }),
|
|
53
|
+
react_1.default.createElement("div", { className: "flex items-center" },
|
|
54
|
+
react_1.default.createElement(toggle_1.Toggle, { label: "Limit file count", name: "toggle", onChange: () => setIsFileCountLimited((prev) => !prev), value: isFileCountLimited }),
|
|
55
|
+
react_1.default.createElement("input", { className: "w-20", onChange: (event) => setFileCountLimit(parseInt(event.target.value, 10)), type: "number", value: fileCountLimit })),
|
|
56
|
+
react_1.default.createElement("div", { className: "flex items-center" },
|
|
57
|
+
react_1.default.createElement(toggle_1.Toggle, { label: "Limit file size", name: "toggle", onChange: () => setIsFileSizeLimited((prev) => !prev), value: isFileSizeLimited }),
|
|
58
|
+
react_1.default.createElement("input", { className: "w-20", onChange: (event) => setFileSizeLimit(parseInt(event.target.value, 10)), type: "number", value: fileSizeLimit }),
|
|
59
|
+
"MB"),
|
|
60
|
+
react_1.default.createElement(index_1.Dropzone, { accept: hasOnlyImagesAllowed ? { "image/*": [] } : undefined, isDisabled: isDisabled, label: "Use drag and drop or click to upload", maxFileSize: isFileSizeLimited ? fileSizeLimit * MB_SIZE : undefined, maxFilesCount: isFileCountLimited ? fileCountLimit : undefined, name: "dropzone-disabled-drag-and-drop", onChange: onChange, onDropRejected: (fileRejections) => (0, handle_rejected_files_1.handleRejectedFiles)(fileRejections, fileCountLimit), onUploadFile: upload_file_mock_1.uploadFile, value: files }),
|
|
61
|
+
react_1.default.createElement(index_1.Dropzone.List, { className: "mt-6", errorText: "Chyba p\u0159i nahr\u00E1v\u00E1n\u00ED souboru", isDisabled: isDisabled, name: "dropzone-error-message", onChange: onChange, onRemoveConfirm: onRemoveConfirm, value: files }),
|
|
62
|
+
react_1.default.createElement(show_1.Show, { when: (0, is_not_empty_1.isNotEmpty)(files) },
|
|
63
|
+
react_1.default.createElement("div", { className: "mt-6" },
|
|
64
|
+
react_1.default.createElement("p", null, "File response:"),
|
|
65
|
+
react_1.default.createElement(index_1.Dropzone.List, { className: "w-max bg-gray-200 p-4", name: "dropzone-list", onChange: onChange, onRemoveConfirm: onRemoveConfirm, renderItem: (file) => (react_1.default.createElement("li", { key: file.id },
|
|
66
|
+
react_1.default.createElement("pre", { className: "text-wrap" }, JSON.stringify(file, null, 4)))), value: files })))));
|
|
75
67
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleRejectedFiles = handleRejectedFiles;
|
|
4
|
+
const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
|
|
5
|
+
const react_dropzone_1 = require("react-dropzone");
|
|
6
|
+
async function handleRejectedFiles(fileRejections, fileCountLimit) {
|
|
7
|
+
const bigFiles = fileRejections.filter((rejection) => rejection.errors.some((error) => error.code === react_dropzone_1.ErrorCode.FileTooLarge));
|
|
8
|
+
const tooManyFiles = fileRejections.filter((rejection) => rejection.errors.some((error) => error.code === react_dropzone_1.ErrorCode.TooManyFiles));
|
|
9
|
+
if ((0, is_not_empty_1.isNotEmpty)(bigFiles)) {
|
|
10
|
+
// eslint-disable-next-line no-alert
|
|
11
|
+
alert(`Tyto soubory jsou příliš velké a nebyly nahrány: ${bigFiles.map((file) => file.file.name).join(", ")}`);
|
|
12
|
+
}
|
|
13
|
+
if ((0, is_not_empty_1.isNotEmpty)(tooManyFiles)) {
|
|
14
|
+
// eslint-disable-next-line no-alert
|
|
15
|
+
alert(`Bylo nahráno příliš mnoho souborů. Maximální počet souborů je ${fileCountLimit}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
package/dropzone/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { DropzoneList } from "./dropzone-list";
|
|
1
2
|
export type { DropzoneInputProps } from "./dropzone-input";
|
|
2
3
|
export type { DropzoneListProps } from "./dropzone-list";
|
|
3
4
|
export declare const Dropzone: import("react").ForwardRefExoticComponent<import("./dropzone-input").DropzoneInputProps & import("react").RefAttributes<HTMLDivElement>> & {
|
|
4
|
-
List:
|
|
5
|
+
List: typeof DropzoneList;
|
|
5
6
|
};
|
package/list-item/list-item.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { UseAnchorProps } from "@uxf/core-react/hooks/use-anchor-props";
|
|
2
2
|
import React, { AnchorHTMLAttributes, ReactNode } from "react";
|
|
3
3
|
import { IconName } from "../icon/types";
|
|
4
|
+
import { NextLink } from "../utils/next-link";
|
|
4
5
|
export interface ListItemProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "type">, UseAnchorProps {
|
|
6
|
+
as?: NextLink | "a";
|
|
5
7
|
endIcon?: IconName;
|
|
6
8
|
endElement?: ReactNode;
|
|
7
9
|
}
|
package/list-item/list-item.js
CHANGED
|
@@ -30,12 +30,13 @@ const react_1 = __importStar(require("react"));
|
|
|
30
30
|
const icon_1 = require("../icon");
|
|
31
31
|
exports.ListItem = (0, react_1.forwardRef)((props, ref) => {
|
|
32
32
|
// eslint-disable-next-line react/destructuring-assignment
|
|
33
|
-
const { className, children, endElement, endIcon, ...restProps } = props;
|
|
33
|
+
const { as = "a", className, children, endElement, endIcon, ...restProps } = props;
|
|
34
|
+
const Component = as;
|
|
34
35
|
const anchorProps = (0, use_anchor_props_1.useAnchorProps)({
|
|
35
36
|
...restProps,
|
|
36
37
|
className: (0, cx_1.cx)("uxf-list-item", className),
|
|
37
38
|
});
|
|
38
|
-
return (react_1.default.createElement(
|
|
39
|
+
return (react_1.default.createElement(Component, { ref: ref, ...anchorProps },
|
|
39
40
|
react_1.default.createElement("span", { className: "uxf-list-item__inner" }, children),
|
|
40
41
|
endElement && react_1.default.createElement("span", { className: "uxf-list-item__end-element-wrapper" }, endElement),
|
|
41
42
|
endIcon && (react_1.default.createElement("span", { className: "uxf-list-item__end-icon-wrapper" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxf/ui",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.35.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@floating-ui/react": "0.26.23",
|
|
19
19
|
"@headlessui/react": "1.7.14",
|
|
20
|
-
"@uxf/core": "11.
|
|
21
|
-
"@uxf/core-react": "11.
|
|
20
|
+
"@uxf/core": "11.35.0",
|
|
21
|
+
"@uxf/core-react": "11.35.0",
|
|
22
22
|
"@uxf/datepicker": "11.32.0",
|
|
23
|
-
"@uxf/styles": "11.
|
|
23
|
+
"@uxf/styles": "11.35.0",
|
|
24
24
|
"color2k": "2.0.3",
|
|
25
25
|
"dayjs": "1.11.13",
|
|
26
26
|
"jump.js": "1.0.2",
|
package/text-link/text-link.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { UseAnchorProps } from "@uxf/core-react/hooks/use-anchor-props";
|
|
2
2
|
import { TextLinkVariants } from "@uxf/ui/text-link/theme";
|
|
3
3
|
import React, { AnchorHTMLAttributes } from "react";
|
|
4
|
+
import { NextLink } from "../utils/next-link";
|
|
4
5
|
export type TextLinkVariant = keyof TextLinkVariants;
|
|
5
6
|
export interface TextLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "type">, UseAnchorProps {
|
|
7
|
+
as?: NextLink | "a";
|
|
6
8
|
variant?: TextLinkVariant;
|
|
7
9
|
}
|
|
8
10
|
export declare const TextLink: React.ForwardRefExoticComponent<TextLinkProps & React.RefAttributes<HTMLAnchorElement>>;
|
package/text-link/text-link.js
CHANGED
|
@@ -29,11 +29,12 @@ const cx_1 = require("@uxf/core/utils/cx");
|
|
|
29
29
|
const react_1 = __importStar(require("react"));
|
|
30
30
|
exports.TextLink = (0, react_1.forwardRef)((props, ref) => {
|
|
31
31
|
// eslint-disable-next-line react/destructuring-assignment
|
|
32
|
-
const { className, children, variant, ...restProps } = props;
|
|
32
|
+
const { as = "a", className, children, variant, ...restProps } = props;
|
|
33
|
+
const Component = as;
|
|
33
34
|
const anchorProps = (0, use_anchor_props_1.useAnchorProps)({
|
|
34
35
|
...restProps,
|
|
35
36
|
className: (0, cx_1.cx)("uxf-text-link", `uxf-text-link--variant-${variant !== null && variant !== void 0 ? variant : "default"}`, className),
|
|
36
37
|
});
|
|
37
|
-
return (react_1.default.createElement(
|
|
38
|
+
return (react_1.default.createElement(Component, { ref: ref, ...anchorProps }, children));
|
|
38
39
|
});
|
|
39
40
|
exports.TextLink.displayName = "UxfUiTextLink";
|
|
File without changes
|
|
File without changes
|