@uxf/ui 1.0.0-beta.101 → 1.0.0-beta.103

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 (44) hide show
  1. package/combobox/combobox.d.ts +8 -6
  2. package/combobox/combobox.js +3 -2
  3. package/combobox/combobox.stories.d.ts +1 -2
  4. package/config/icons-config.d.ts +1 -1
  5. package/config/icons-config.js +1 -1
  6. package/config/icons.d.ts +15 -0
  7. package/config/icons.js +3 -0
  8. package/css/dropzone.css +81 -0
  9. package/css/input.css +3 -3
  10. package/css/loader.css +13 -1
  11. package/css/tooltip.css +9 -0
  12. package/dropzone/dropzone-input.d.ts +18 -0
  13. package/dropzone/dropzone-input.js +120 -0
  14. package/dropzone/dropzone-list.d.ts +10 -0
  15. package/dropzone/dropzone-list.js +67 -0
  16. package/dropzone/dropzone.stories.d.ts +12 -0
  17. package/dropzone/dropzone.stories.js +98 -0
  18. package/dropzone/index.d.ts +6 -0
  19. package/dropzone/index.js +6 -0
  20. package/dropzone/types.d.ts +10 -0
  21. package/{file-input → dropzone}/types.js +0 -0
  22. package/file-input/file-input-base.d.ts +1 -2
  23. package/loader/loader.d.ts +5 -2
  24. package/loader/loader.js +3 -2
  25. package/loader/loader.stories.d.ts +1 -1
  26. package/loader/loader.stories.js +2 -1
  27. package/mutli-combobox/multi-combobox.d.ts +9 -7
  28. package/mutli-combobox/multi-combobox.js +13 -11
  29. package/mutli-combobox/multi-combobox.stories.d.ts +1 -2
  30. package/package.json +3 -2
  31. package/tooltip/index.d.ts +1 -0
  32. package/tooltip/index.js +17 -0
  33. package/tooltip/tooltip.d.ts +7 -0
  34. package/tooltip/tooltip.js +79 -0
  35. package/tooltip/tooltip.stories.d.ts +7 -0
  36. package/tooltip/tooltip.stories.js +19 -0
  37. package/tooltip/use-tooltip.d.ts +28 -0
  38. package/tooltip/use-tooltip.js +35 -0
  39. package/types/file-response.d.ts +12 -0
  40. package/types/file-response.js +2 -0
  41. package/types/index.d.ts +1 -0
  42. package/types/index.js +1 -0
  43. package/utils/icons-config.js +15 -0
  44. package/file-input/types.d.ts +0 -7
@@ -2,13 +2,15 @@ import { Placement } from "@floating-ui/react";
2
2
  import React, { ReactNode } from "react";
3
3
  import { IconsSet } from "../icon/theme";
4
4
  import { FormControlProps } from "../types";
5
- export declare type ComboboxValue = number | string;
6
- export declare type ComboboxOption<T = ComboboxValue> = {
7
- disabled?: boolean;
8
- id: T;
5
+ export declare type ComboboxValueId = number | string;
6
+ export declare type ComboboxValue<ValueId = ComboboxValueId> = {
7
+ id: ValueId;
9
8
  label: string;
10
9
  };
11
- export interface ComboboxProps<Value = ComboboxValue, Option = ComboboxOption<Value>> extends FormControlProps<Value | null> {
10
+ export interface ComboboxOption<ValueId = ComboboxValueId> extends ComboboxValue<ValueId> {
11
+ disabled?: boolean;
12
+ }
13
+ export interface ComboboxProps<ValueId = ComboboxValueId, Option = ComboboxOption<ValueId>> extends FormControlProps<Option | null> {
12
14
  className?: string;
13
15
  dropdownPlacement?: Placement;
14
16
  helperText?: ReactNode;
@@ -22,4 +24,4 @@ export interface ComboboxProps<Value = ComboboxValue, Option = ComboboxOption<Va
22
24
  placeholder?: string;
23
25
  renderOption?: (option: Option) => ReactNode;
24
26
  }
25
- export declare const Combobox: React.ForwardRefExoticComponent<ComboboxProps<ComboboxValue, ComboboxOption<ComboboxValue>> & React.RefAttributes<HTMLDivElement>>;
27
+ export declare const Combobox: React.ForwardRefExoticComponent<ComboboxProps<ComboboxValueId, ComboboxOption<ComboboxValueId>> & React.RefAttributes<HTMLDivElement>>;
@@ -36,6 +36,7 @@ const use_dropdown_1 = require("../hooks/use-dropdown");
36
36
  const icon_1 = require("../icon");
37
37
  const label_1 = require("../label");
38
38
  const use_async_loading_1 = require("../hooks/use-async-loading");
39
+ // TODO make the component generic ComboboxProps<T>
39
40
  exports.Combobox = (0, forwardRef_1.forwardRef)("Combobox", (props, ref) => {
40
41
  var _a, _b, _c, _d;
41
42
  const generatedId = (0, react_2.useId)();
@@ -43,7 +44,7 @@ exports.Combobox = (0, forwardRef_1.forwardRef)("Combobox", (props, ref) => {
43
44
  const isAsync = !!props.loadOptions;
44
45
  const [query, setQuery] = (0, react_2.useState)("");
45
46
  const options = (0, use_async_loading_1.useAsyncLoading)(query, (_b = props.options) !== null && _b !== void 0 ? _b : [], props.loadOptions);
46
- const selectedOption = options.find((option) => option.id === props.value);
47
+ const selectedOption = options.find((option) => { var _a; return option.id === ((_a = props.value) === null || _a === void 0 ? void 0 : _a.id); });
47
48
  const filteredData = query === "" || isAsync ? options : options.filter((item) => (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query)));
48
49
  const innerRef = (0, react_2.useRef)(null);
49
50
  const errorId = props.isInvalid ? `${id}--error-message` : undefined;
@@ -51,7 +52,7 @@ exports.Combobox = (0, forwardRef_1.forwardRef)("Combobox", (props, ref) => {
51
52
  const dropdown = (0, use_dropdown_1.useDropdown)((_c = props.dropdownPlacement) !== null && _c !== void 0 ? _c : "bottom", true);
52
53
  const stableRef = (0, react_2.useMemo)(() => (0, composeRefs_1.composeRefs)(innerRef, ref, dropdown.reference), [ref, dropdown.reference]);
53
54
  const iconName = (_d = props.iconName) !== null && _d !== void 0 ? _d : "chevronDown";
54
- return (react_2.default.createElement(react_1.Combobox, { as: "div", className: (0, cx_1.cx)("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), onChange: (v) => { var _a; return (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, v.id); }, value: selectedOption, disabled: props.isDisabled || props.isReadOnly }, (renderProps) => (react_2.default.createElement(react_2.default.Fragment, null,
55
+ return (react_2.default.createElement(react_1.Combobox, { as: "div", className: (0, cx_1.cx)("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), onChange: (v) => { var _a; return (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, v); }, value: selectedOption, disabled: props.isDisabled || props.isReadOnly }, (renderProps) => (react_2.default.createElement(react_2.default.Fragment, null,
55
56
  react_2.default.createElement(react_1.Combobox.Label, { as: label_1.Label, isHidden: props.hiddenLabel, onClick: props.isDisabled || props.isReadOnly ? undefined : input.focus }, props.label),
56
57
  react_2.default.createElement(react_1.Combobox.Button, { as: "div", className: (0, cx_1.cx)("uxf-combobox__button", (renderProps.open || input.focused) && classes_1.CLASSES.IS_FOCUSED, renderProps.disabled && classes_1.CLASSES.IS_DISABLED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isInvalid && classes_1.CLASSES.IS_INVALID, dropdown.placement === "bottom" && "is-open--bottom", dropdown.placement === "top" && "is-open--top", renderProps.open && classes_1.CLASSES.IS_OPEN), onBlur: input.onBlur, onFocus: input.onFocus, tabIndex: props.isDisabled || props.isReadOnly ? undefined : 0, ref: stableRef, "aria-invalid": props.isInvalid, "aria-describedby": errorId },
57
58
  react_2.default.createElement(react_1.Combobox.Input, { className: (0, cx_1.cx)("uxf-combobox__input"), displayValue: (item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.label) !== null && _a !== void 0 ? _a : ""; }, onBlur: props.onBlur, onChange: (event) => setQuery(event.target.value), placeholder: props.placeholder, ref: stableRef, type: "text" }),
@@ -1,8 +1,7 @@
1
1
  import React from "react";
2
- import { ComboboxValue } from "./combobox";
3
2
  declare const _default: {
4
3
  title: string;
5
- component: React.ForwardRefExoticComponent<import("./combobox").ComboboxProps<ComboboxValue, import("./combobox").ComboboxOption<ComboboxValue>> & React.RefAttributes<HTMLDivElement>>;
4
+ component: React.ForwardRefExoticComponent<import("./combobox").ComboboxProps<import("./combobox").ComboboxValueId, import("./combobox").ComboboxOption<import("./combobox").ComboboxValueId>> & React.RefAttributes<HTMLDivElement>>;
6
5
  };
7
6
  export default _default;
8
7
  export declare function Default(): JSX.Element;
@@ -1,2 +1,2 @@
1
- export declare const ICONS_VERSION = "1673628509595";
1
+ export declare const ICONS_VERSION = "1674059698879";
2
2
  export declare const ICON_SPRITE = "/.storybook/static-assets/icons-generated/_icon-sprite.svg";
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ICON_SPRITE = exports.ICONS_VERSION = void 0;
4
- exports.ICONS_VERSION = "1673628509595";
4
+ exports.ICONS_VERSION = "1674059698879";
5
5
  exports.ICON_SPRITE = "/.storybook/static-assets/icons-generated/_icon-sprite.svg";
package/config/icons.d.ts CHANGED
@@ -51,6 +51,18 @@ export declare const ICONS: {
51
51
  readonly w: 640;
52
52
  readonly h: 512;
53
53
  };
54
+ readonly file: {
55
+ readonly w: 384;
56
+ readonly h: 512;
57
+ };
58
+ readonly imageFile: {
59
+ readonly w: 384;
60
+ readonly h: 512;
61
+ };
62
+ readonly videoFile: {
63
+ readonly w: 384;
64
+ readonly h: 512;
65
+ };
54
66
  readonly user: {
55
67
  readonly w: 448;
56
68
  readonly h: 512;
@@ -76,6 +88,9 @@ declare module "@uxf/ui/icon/theme" {
76
88
  "chevronsRight": true;
77
89
  "chevronUp": true;
78
90
  "cloud": true;
91
+ "file": true;
92
+ "imageFile": true;
93
+ "videoFile": true;
79
94
  "user": true;
80
95
  "xmarkLarge": true;
81
96
  }
package/config/icons.js CHANGED
@@ -16,6 +16,9 @@ exports.ICONS = {
16
16
  "chevronsRight": { w: 512, h: 512 },
17
17
  "chevronUp": { w: 512, h: 512 },
18
18
  "cloud": { w: 640, h: 512 },
19
+ "file": { w: 384, h: 512 },
20
+ "imageFile": { w: 384, h: 512 },
21
+ "videoFile": { w: 384, h: 512 },
19
22
  "user": { w: 448, h: 512 },
20
23
  "xmarkLarge": { w: 448, h: 512 },
21
24
  };
@@ -0,0 +1,81 @@
1
+ .uxf-dropzone {
2
+ @apply rounded-lg focus:outline-none;
3
+
4
+ &__input {
5
+ @apply sr-only;
6
+ }
7
+
8
+ &__label {
9
+ @apply flex flex-col space-y-2 items-center justify-center p-4 border-2 border-lightBorder border-dashed
10
+ rounded-inherit cursor-pointer text-lightLow text-[14px];
11
+
12
+ &__icon {
13
+ @apply h-6;
14
+ }
15
+
16
+ &.is-invalid {
17
+ @apply border-error-600;
18
+ }
19
+
20
+ &.is-disabled {
21
+ @apply bg-lightBorder/50 cursor-not-allowed;
22
+ }
23
+ }
24
+ }
25
+
26
+ .uxf-dropzone-list {
27
+ @apply space-y-2;
28
+
29
+ &__item-wrapper {
30
+ @apply flex flex-col items-start justify-start space-y-1;
31
+ }
32
+
33
+ &__item {
34
+ @apply overflow-scroll border px-4 py-3 shadow-sm sm:rounded-md sm:px-6 flex w-full
35
+ items-center justify-between space-x-6;
36
+
37
+ :root .light & {
38
+ @apply border-lightBorder text-lightMedium;
39
+ }
40
+
41
+ :root .dark & {
42
+ @apply border-gray-700 bg-gray-800 text-gray-200;
43
+ }
44
+
45
+ &.is-invalid {
46
+ :root .light & {
47
+ @apply border-error-600 text-error-600;
48
+ }
49
+
50
+ :root .dark & {
51
+ @apply border-error-600 text-error-600;
52
+ }
53
+ }
54
+
55
+ &__block {
56
+ @apply flex items-center space-x-4 min-w-0;
57
+
58
+ &:nth-child(2) {
59
+ @apply shrink-0;
60
+ }
61
+
62
+ &__icon {
63
+ @apply h-6;
64
+ }
65
+
66
+ &__file-name {
67
+ @apply truncate;
68
+ }
69
+
70
+ &__file-size {
71
+ @apply whitespace-nowrap shrink-0;
72
+ }
73
+
74
+ &__remove-button {
75
+ &__icon {
76
+ @apply h-4;
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
package/css/input.css CHANGED
@@ -31,10 +31,10 @@
31
31
 
32
32
  &__left-addon,
33
33
  &__right-addon {
34
- @apply border px-2 bg-gray-100;
34
+ @apply border px-2;
35
35
 
36
36
  :root .light & {
37
- @apply border-gray-200;
37
+ @apply border-gray-200 bg-gray-100;
38
38
  }
39
39
 
40
40
  :root .dark & {
@@ -198,7 +198,7 @@
198
198
  }
199
199
 
200
200
  :root .light & {
201
- -webkit-box-shadow: inset 0 0 0 1000px theme("colors.gray.100");
201
+ -webkit-box-shadow: inset 0 0 0 1000px theme("colors.white");
202
202
  }
203
203
  }
204
204
  }
package/css/loader.css CHANGED
@@ -7,5 +7,17 @@
7
7
  .uxf-loader {
8
8
  animation: spinner 1.2s linear infinite;
9
9
 
10
- @apply inline-block h-12 w-12 rounded-full border-r-4 border-t-4 border-r-transparent border-t-current;
10
+ @apply inline-block rounded-full border-r-transparent border-t-current;
11
+
12
+ &--size-default {
13
+ @apply h-12 w-12 border-r-4 border-t-4;
14
+ }
15
+
16
+ &--size-lg {
17
+ @apply h-24 w-24 border-r-8 border-t-8;
18
+ }
19
+
20
+ &--size-sm {
21
+ @apply h-6 w-6 border-r-2 border-t-2;
22
+ }
11
23
  }
@@ -0,0 +1,9 @@
1
+ .uxf-tooltip {
2
+ &__content {
3
+ @apply w-max max-w-[calc(100vw-20px)] bg-lightHigh p-3 text-white rounded-lg;
4
+ }
5
+
6
+ &__arrow {
7
+ @apply bg-lightHigh rounded-sm;
8
+ }
9
+ }
@@ -0,0 +1,18 @@
1
+ import { FileResponse, FormControlProps, UploadOptions } from "@uxf/ui/types";
2
+ import React, { ReactNode } from "react";
3
+ import { IconName } from "../icon/types";
4
+ import { Accept, DropzoneFile } from "./types";
5
+ export interface DropzoneInputProps extends FormControlProps<DropzoneFile[]> {
6
+ accept?: Accept;
7
+ helperText?: ReactNode;
8
+ icon?: IconName;
9
+ label?: ReactNode;
10
+ maxFileSize?: number;
11
+ maxFilesCount?: number;
12
+ minFileSize?: number;
13
+ noClick?: boolean;
14
+ noDrag?: boolean;
15
+ onUploadError?: (err: unknown) => void;
16
+ onUploadFile: (file: File, options?: UploadOptions) => Promise<FileResponse>;
17
+ }
18
+ export declare const DropzoneInput: React.ForwardRefExoticComponent<DropzoneInputProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,120 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.DropzoneInput = void 0;
27
+ const classes_1 = require("@uxf/core/constants/classes");
28
+ const composeRefs_1 = require("@uxf/core/utils/composeRefs");
29
+ const cx_1 = require("@uxf/core/utils/cx");
30
+ const react_1 = __importStar(require("react"));
31
+ const react_dropzone_1 = require("react-dropzone");
32
+ const icon_1 = require("../icon");
33
+ function fileToFileResponse(file) {
34
+ const nameParts = file.name.split(".");
35
+ return {
36
+ id: -Math.round(Math.random() * 100000000),
37
+ uuid: "00000000-0000-0000-0000-000000000000",
38
+ name: nameParts.slice(0, -1).join("."),
39
+ extension: nameParts[nameParts.length - 1],
40
+ };
41
+ }
42
+ function progressHandler(progressEvent, file, onValuesChange, values) {
43
+ if (onValuesChange && values) {
44
+ onValuesChange(values.map((f) => f.id === file.id
45
+ ? {
46
+ ...f,
47
+ progress: progressEvent.lengthComputable
48
+ ? Math.round((progressEvent.loaded / progressEvent.total) * 100)
49
+ : null,
50
+ }
51
+ : f));
52
+ }
53
+ }
54
+ function fileUploadedHandler(uploadedFile, dropzoneFile, onValuesChange, values) {
55
+ if (onValuesChange && values) {
56
+ onValuesChange(values.map((f) => f.id === dropzoneFile.id ? { ...uploadedFile, progress: 100, originalFile: f.originalFile } : f));
57
+ }
58
+ }
59
+ function fileRejectedHandler(err, dropzoneFile, onValuesChange, values, onUploadError) {
60
+ onUploadError === null || onUploadError === void 0 ? void 0 : onUploadError(err);
61
+ dropzoneFile.error = err;
62
+ if (onValuesChange && values) {
63
+ onValuesChange(values.map((f) => (f.id === dropzoneFile.id ? { ...f, error: err } : f)));
64
+ }
65
+ }
66
+ exports.DropzoneInput = (0, react_1.forwardRef)((props, ref) => {
67
+ var _a;
68
+ const refValue = (0, react_1.useRef)();
69
+ refValue.current = props.value;
70
+ const handleFileDrop = async (acceptedFiles) => {
71
+ if (!props.onChange) {
72
+ return;
73
+ }
74
+ const files = acceptedFiles.map((file) => ({
75
+ ...fileToFileResponse(file),
76
+ abortController: new AbortController(),
77
+ originalFile: file,
78
+ progress: 0,
79
+ }));
80
+ props.onChange(props.value ? [...props.value, ...files] : files);
81
+ for (const file of files) {
82
+ if (!file.originalFile) {
83
+ file.error = "File not found";
84
+ continue;
85
+ }
86
+ props
87
+ .onUploadFile(file.originalFile, {
88
+ abortController: file.abortController,
89
+ onUploadProgress: (e) => progressHandler(e, file, props.onChange, refValue.current),
90
+ })
91
+ .then((res) => fileUploadedHandler(res, file, props.onChange, refValue.current))
92
+ .catch((err) => fileRejectedHandler(err, file, props.onChange, refValue.current, props.onUploadError));
93
+ }
94
+ };
95
+ const { getRootProps, getInputProps, rootRef } = (0, react_dropzone_1.useDropzone)({
96
+ accept: props.accept,
97
+ disabled: props.isDisabled,
98
+ maxFiles: props.maxFilesCount,
99
+ maxSize: props.maxFileSize,
100
+ minSize: props.minFileSize,
101
+ multiple: props.maxFilesCount !== 1,
102
+ noClick: props.noClick,
103
+ noDrag: props.noDrag,
104
+ onDrop: handleFileDrop,
105
+ preventDropOnDocument: props.noDrag,
106
+ });
107
+ return (react_1.default.createElement("div", { className: "uxf-dropzone" },
108
+ react_1.default.createElement("label", { ...getRootProps({
109
+ className: (0, cx_1.cx)("uxf-dropzone__label", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.noClick && "cursor-auto"),
110
+ }), ref: (0, composeRefs_1.composeRefs)(ref, rootRef) },
111
+ react_1.default.createElement(icon_1.Icon, { className: "uxf-dropzone__label__icon", name: (_a = props.icon) !== null && _a !== void 0 ? _a : "cloud" }),
112
+ typeof props.label === "string" ? react_1.default.createElement("span", null, props.label) : props.label,
113
+ react_1.default.createElement("input", { ...getInputProps({
114
+ className: "uxf-dropzone__input",
115
+ name: props.name,
116
+ type: "file",
117
+ }) })),
118
+ props.helperText && (react_1.default.createElement("div", { className: (0, cx_1.cx)("uxf-helper-text", props.isInvalid && classes_1.CLASSES.IS_INVALID) }, props.helperText))));
119
+ });
120
+ exports.DropzoneInput.displayName = "DropzoneInput";
@@ -0,0 +1,10 @@
1
+ import { FC, ReactNode } from "react";
2
+ import { FormControlProps } from "../types";
3
+ import { DropzoneFile } from "./types";
4
+ export interface DropzoneListProps extends FormControlProps<DropzoneFile[]> {
5
+ errorText?: string;
6
+ onAbortWarning?: string;
7
+ onRemoveWarning?: string;
8
+ renderItem?: (file: DropzoneFile) => ReactNode;
9
+ }
10
+ export declare const DropzoneList: FC<DropzoneListProps>;
@@ -0,0 +1,67 @@
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
+ exports.DropzoneList = void 0;
7
+ const classes_1 = require("@uxf/core/constants/classes");
8
+ const cx_1 = require("@uxf/core/utils/cx");
9
+ const react_1 = __importDefault(require("react"));
10
+ const icon_1 = require("../icon");
11
+ const loader_1 = require("../loader/loader");
12
+ function formatBytes(bytes, decimals = 2) {
13
+ const k = 1024;
14
+ const dm = decimals < 0 ? 0 : decimals;
15
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
16
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
17
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
18
+ }
19
+ function getIconName(extension) {
20
+ switch (extension) {
21
+ case "jpg":
22
+ case "jpeg":
23
+ case "png":
24
+ case "gif":
25
+ return "imageFile";
26
+ case "mp4":
27
+ case "avi":
28
+ case "mov":
29
+ return "videoFile";
30
+ default:
31
+ return "file";
32
+ }
33
+ }
34
+ const DropzoneList = (props) => {
35
+ const onRemove = (file, isUploading) => () => {
36
+ var _a, _b, _c;
37
+ // eslint-disable-next-line no-alert
38
+ if (isUploading && props.value && confirm(props.onAbortWarning || "Do you want to abort the file?")) {
39
+ (_a = file.abortController) === null || _a === void 0 ? void 0 : _a.abort();
40
+ (_b = props.onChange) === null || _b === void 0 ? void 0 : _b.call(props, props.value.filter((f) => f.id !== file.id));
41
+ return;
42
+ }
43
+ // eslint-disable-next-line no-alert
44
+ if (!isUploading && props.value && confirm(props.onRemoveWarning || "Do you want to delete the file?")) {
45
+ (_c = props.onChange) === null || _c === void 0 ? void 0 : _c.call(props, props.value.filter((f) => f.id !== file.id));
46
+ }
47
+ };
48
+ if (!props.value || props.value.length === 0) {
49
+ return null;
50
+ }
51
+ return (react_1.default.createElement("ul", { className: "uxf-dropzone-list" }, props.value.map((file) => {
52
+ var _a, _b, _c;
53
+ const isUploading = file.id < 0 && !file.error;
54
+ return ((_b = (_a = props.renderItem) === null || _a === void 0 ? void 0 : _a.call(props, file)) !== null && _b !== void 0 ? _b : (react_1.default.createElement("li", { className: "uxf-dropzone-list__item-wrapper", key: file.id },
55
+ react_1.default.createElement("div", { className: (0, cx_1.cx)("uxf-dropzone-list__item", !!file.error && classes_1.CLASSES.IS_INVALID) },
56
+ react_1.default.createElement("div", { className: "uxf-dropzone-list__item__block" },
57
+ react_1.default.createElement(icon_1.Icon, { className: "uxf-dropzone-list__item__block__icon", name: getIconName(file.extension) }),
58
+ react_1.default.createElement("span", { className: "uxf-dropzone-list__item__block__file-name" }, file.name + "." + file.extension)),
59
+ react_1.default.createElement("div", { className: "uxf-dropzone-list__item__block" },
60
+ isUploading ? (react_1.default.createElement(loader_1.Loader, { size: "sm" })) : (!file.error &&
61
+ ((_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)))),
62
+ react_1.default.createElement("button", { className: "uxf-dropzone-list__item__block__remove-button", onClick: onRemove(file, isUploading), type: "button" },
63
+ react_1.default.createElement(icon_1.Icon, { className: "uxf-dropzone-list__item__block__remove-button__icon", name: "xmarkLarge" })))),
64
+ !!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")))));
65
+ })));
66
+ };
67
+ exports.DropzoneList = DropzoneList;
@@ -0,0 +1,12 @@
1
+ import { FileResponse, UploadOptions } from "@uxf/ui/types/file-response";
2
+ import React from "react";
3
+ declare const _default: {
4
+ title: string;
5
+ component: React.ForwardRefExoticComponent<import("./dropzone-input").DropzoneInputProps & React.RefAttributes<HTMLDivElement>> & {
6
+ List: React.FC<import("./dropzone-list").DropzoneListProps>;
7
+ };
8
+ };
9
+ export default _default;
10
+ export declare function uploadFile(file: File, uploadOptions?: UploadOptions): Promise<FileResponse>;
11
+ export declare function Default(): JSX.Element;
12
+ export declare function ComponentStructure(): JSX.Element;
@@ -0,0 +1,98 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.ComponentStructure = exports.Default = exports.uploadFile = void 0;
30
+ const component_structure_analyzer_1 = __importDefault(require("@uxf/ui/utils/component-structure-analyzer"));
31
+ const react_1 = __importStar(require("react"));
32
+ const index_1 = require("./index");
33
+ exports.default = {
34
+ title: "UI/Dropzone",
35
+ component: index_1.Dropzone,
36
+ };
37
+ function getRandomUuid() {
38
+ return "00000000-0000-0000-0000-000000000000"
39
+ .split("-")
40
+ .map((el) => Array(el.length)
41
+ .fill(0)
42
+ .map(() => Math.round(Math.random() * 9).toString())
43
+ .join(""))
44
+ .join("-");
45
+ }
46
+ function uploadFile(file, uploadOptions) {
47
+ // axios.put("/api/upload", file, { signal: uploadOptions?.abortController?.signal });
48
+ return new Promise((resolve) => {
49
+ const time = file.size / 10;
50
+ const interval = time / 10;
51
+ let loaded = 0;
52
+ const timeoutTimer = window.setTimeout(() => {
53
+ const nameParts = file.name.split(".");
54
+ resolve({
55
+ id: Math.round(Math.random() * 100000000),
56
+ uuid: getRandomUuid(),
57
+ name: nameParts.slice(0, -1).join("."),
58
+ extension: nameParts[nameParts.length - 1],
59
+ });
60
+ }, time);
61
+ const intervalTimer = window.setInterval(() => {
62
+ var _a, _b;
63
+ if ((_a = uploadOptions === null || uploadOptions === void 0 ? void 0 : uploadOptions.abortController) === null || _a === void 0 ? void 0 : _a.signal.aborted) {
64
+ clearInterval(intervalTimer);
65
+ clearTimeout(timeoutTimer);
66
+ return;
67
+ }
68
+ loaded += (file.size / time) * interval;
69
+ (_b = uploadOptions === null || uploadOptions === void 0 ? void 0 : uploadOptions.onUploadProgress) === null || _b === void 0 ? void 0 : _b.call(uploadOptions, {
70
+ lengthComputable: true,
71
+ loaded,
72
+ total: file.size,
73
+ });
74
+ }, interval);
75
+ });
76
+ }
77
+ exports.uploadFile = uploadFile;
78
+ function Default() {
79
+ const [files, setFiles] = (0, react_1.useState)([]);
80
+ const storyDropzone = (react_1.default.createElement("div", { className: "space-y-2" },
81
+ react_1.default.createElement(index_1.Dropzone, { helperText: "Disabled drag 'n' drop", label: "Use drag and drop or click to upload", noDrag: true, onChange: setFiles, onUploadFile: uploadFile, value: files }),
82
+ react_1.default.createElement(index_1.Dropzone, { helperText: "Disabled onClick upload", label: react_1.default.createElement("span", { className: "rounded-lg bg-primary-600 px-4 py-2 font-bold text-white" }, "JSX label"), noClick: true, onChange: setFiles, onUploadFile: uploadFile, value: files }),
83
+ react_1.default.createElement(index_1.Dropzone, { accept: { "image/*": [] }, label: "Only images upload", onChange: setFiles, onUploadFile: uploadFile, value: files }),
84
+ react_1.default.createElement(index_1.Dropzone, { label: "Single file upload", maxFilesCount: 1, onChange: setFiles, onUploadFile: uploadFile, value: files }),
85
+ react_1.default.createElement(index_1.Dropzone, { isDisabled: true, label: "Disabled dropzone", onChange: setFiles, onUploadFile: uploadFile, value: files }),
86
+ react_1.default.createElement(index_1.Dropzone.List, { errorText: "Chyba p\u0159i nahr\u00E1v\u00E1n\u00ED souboru", onAbortWarning: "Opravdu chcete p\u0159eru\u0161it nahr\u00E1v\u00E1n\u00ED?", onChange: setFiles, onRemoveWarning: "Opravdu chcete soubor smazat?", value: files }),
87
+ react_1.default.createElement(index_1.Dropzone.List, { onChange: setFiles, value: files, renderItem: (file) => (react_1.default.createElement("li", { key: file.id },
88
+ react_1.default.createElement("pre", null, JSON.stringify(file, null, 4)))) })));
89
+ return (react_1.default.createElement("div", { className: "flex flex-col lg:flex-row" },
90
+ react_1.default.createElement("div", { className: "light space-y-2 p-20 lg:w-1/2" }, storyDropzone),
91
+ react_1.default.createElement("div", { className: "dark space-y-2 bg-gray-900 p-20 lg:w-1/2" }, storyDropzone)));
92
+ }
93
+ exports.Default = Default;
94
+ function ComponentStructure() {
95
+ return (react_1.default.createElement(component_structure_analyzer_1.default, null,
96
+ react_1.default.createElement(index_1.Dropzone, null)));
97
+ }
98
+ exports.ComponentStructure = ComponentStructure;
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ export { DropzoneInputProps } from "./dropzone-input";
3
+ export { DropzoneListProps } from "./dropzone-list";
4
+ export declare const Dropzone: import("react").ForwardRefExoticComponent<import("./dropzone-input").DropzoneInputProps & import("react").RefAttributes<HTMLDivElement>> & {
5
+ List: import("react").FC<import("./dropzone-list").DropzoneListProps>;
6
+ };
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Dropzone = void 0;
4
+ const dropzone_input_1 = require("./dropzone-input");
5
+ const dropzone_list_1 = require("./dropzone-list");
6
+ exports.Dropzone = Object.assign(dropzone_input_1.DropzoneInput, { List: dropzone_list_1.DropzoneList });
@@ -0,0 +1,10 @@
1
+ import { FileResponse } from "@uxf/ui/types";
2
+ export interface DropzoneFile extends FileResponse {
3
+ abortController?: AbortController;
4
+ error?: unknown;
5
+ originalFile?: File;
6
+ progress: number | null;
7
+ }
8
+ export interface Accept {
9
+ [key: string]: string[];
10
+ }
File without changes
@@ -1,6 +1,5 @@
1
+ import { FileResponse, FormControlProps } from "@uxf/ui/types";
1
2
  import React from "react";
2
- import { FormControlProps } from "../types";
3
- import { FileResponse } from "./types";
4
3
  export interface BaseFileInputProps extends FormControlProps<string> {
5
4
  "aria-describedby"?: string;
6
5
  accept?: string;
@@ -1,2 +1,5 @@
1
- import React from "react";
2
- export declare const Loader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
1
+ import React, { HTMLAttributes } from "react";
2
+ export interface LoaderProps extends HTMLAttributes<HTMLDivElement> {
3
+ size?: "default" | "lg" | "sm";
4
+ }
5
+ export declare const Loader: React.ForwardRefExoticComponent<LoaderProps & React.RefAttributes<HTMLDivElement>>;
package/loader/loader.js CHANGED
@@ -5,9 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Loader = void 0;
7
7
  const cx_1 = require("@uxf/core/utils/cx");
8
- const react_1 = __importDefault(require("react"));
9
8
  const forwardRef_1 = require("@uxf/core/utils/forwardRef");
9
+ const react_1 = __importDefault(require("react"));
10
10
  exports.Loader = (0, forwardRef_1.forwardRef)("Loader", (props, ref) => {
11
- const loaderClassName = (0, cx_1.cx)("uxf-loader", props.className);
11
+ var _a;
12
+ const loaderClassName = (0, cx_1.cx)("uxf-loader", `uxf-loader--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, props.className);
12
13
  return react_1.default.createElement("span", { ref: ref, className: loaderClassName });
13
14
  });
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  declare const _default: {
3
3
  title: string;
4
- component: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
4
+ component: React.ForwardRefExoticComponent<import("./loader").LoaderProps & React.RefAttributes<HTMLDivElement>>;
5
5
  };
6
6
  export default _default;
7
7
  export declare function Default(): JSX.Element;
@@ -12,8 +12,9 @@ exports.default = {
12
12
  };
13
13
  function Default() {
14
14
  const loaders = (react_1.default.createElement(react_1.default.Fragment, null,
15
+ react_1.default.createElement(loader_1.Loader, { size: "sm" }),
15
16
  react_1.default.createElement(loader_1.Loader, null),
16
- react_1.default.createElement(loader_1.Loader, { className: "h-6 w-6" })));
17
+ react_1.default.createElement(loader_1.Loader, { size: "lg" })));
17
18
  return (react_1.default.createElement("div", { className: "flex flex-col lg:flex-row" },
18
19
  react_1.default.createElement("div", { className: "light space-y-4 space-x-4 rounded bg-white p-8" }, loaders),
19
20
  react_1.default.createElement("div", { className: "dark space-y-4 space-x-4 rounded bg-gray-900 p-8 text-white" }, loaders)));
@@ -3,14 +3,16 @@ import React, { ReactNode } from "react";
3
3
  import { ChipColor } from "../chip";
4
4
  import { IconsSet } from "../icon/theme";
5
5
  import { FormControlProps } from "../types";
6
- export declare type MultiComboboxValue = number | string;
7
- export declare type MultiComboboxOption<T = MultiComboboxValue> = {
8
- color?: ChipColor;
9
- disabled?: boolean;
10
- id: T;
6
+ export declare type MultiComboboxValueId = number | string;
7
+ export declare type MultiComboboxValue<ValueId = MultiComboboxValueId> = {
8
+ id: ValueId;
11
9
  label: string;
12
10
  };
13
- export interface MultiComboboxProps<Value = MultiComboboxValue[], Option = MultiComboboxOption> extends FormControlProps<Value | null> {
11
+ export interface MultiComboboxOption<ValueId = MultiComboboxValueId> extends MultiComboboxValue<ValueId> {
12
+ color?: ChipColor;
13
+ disabled?: boolean;
14
+ }
15
+ export interface MultiComboboxProps<ValueId = MultiComboboxValueId, Option = MultiComboboxOption<ValueId>> extends FormControlProps<Option[] | null> {
14
16
  className?: string;
15
17
  dropdownPlacement?: Placement;
16
18
  helperText?: ReactNode;
@@ -25,4 +27,4 @@ export interface MultiComboboxProps<Value = MultiComboboxValue[], Option = Multi
25
27
  renderOption?: (option: Option) => ReactNode;
26
28
  withCheckboxes?: boolean;
27
29
  }
28
- export declare const MultiCombobox: React.ForwardRefExoticComponent<MultiComboboxProps<MultiComboboxValue[], MultiComboboxOption<MultiComboboxValue>> & React.RefAttributes<HTMLDivElement>>;
30
+ export declare const MultiCombobox: React.ForwardRefExoticComponent<MultiComboboxProps<MultiComboboxValueId, MultiComboboxOption<MultiComboboxValueId>> & React.RefAttributes<HTMLDivElement>>;
@@ -45,12 +45,12 @@ exports.MultiCombobox = (0, forwardRef_1.forwardRef)("MultiCombobox", (props, re
45
45
  const isAsync = !!props.loadOptions;
46
46
  const [query, setQuery] = (0, react_2.useState)("");
47
47
  const options = (0, use_async_loading_1.useAsyncLoading)(query, (_b = props.options) !== null && _b !== void 0 ? _b : [], props.loadOptions);
48
- const [selectedOptions, setSelectedOptions] = (0, react_2.useState)(() => options.filter((option) => { var _a; return (_a = props.value) === null || _a === void 0 ? void 0 : _a.includes(option.id); }));
48
+ const [selectedOptions, setSelectedOptions] = (0, react_2.useState)(() => options.filter((option) => { var _a; return (_a = props.value) === null || _a === void 0 ? void 0 : _a.some((v) => v.id === option.id); }));
49
49
  const filteredData = isAsync
50
50
  ? options
51
51
  : options.filter((item) => {
52
52
  var _a;
53
- return (!((_a = props.value) === null || _a === void 0 ? void 0 : _a.includes(item.id)) || props.withCheckboxes) &&
53
+ return (!((_a = props.value) === null || _a === void 0 ? void 0 : _a.some((v) => v.id === item.id)) || props.withCheckboxes) &&
54
54
  (query === "" || (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query)));
55
55
  });
56
56
  const innerRef = (0, react_2.useRef)(null);
@@ -59,19 +59,21 @@ exports.MultiCombobox = (0, forwardRef_1.forwardRef)("MultiCombobox", (props, re
59
59
  const dropdown = (0, use_dropdown_1.useDropdown)((_c = props.dropdownPlacement) !== null && _c !== void 0 ? _c : "bottom", true);
60
60
  const stableRef = (0, react_2.useMemo)(() => (0, composeRefs_1.composeRefs)(innerRef, ref, dropdown.reference), [ref, dropdown.reference]);
61
61
  const iconName = (_d = props.iconName) !== null && _d !== void 0 ? _d : "chevronDown";
62
- const handleRemove = (value) => () => {
62
+ const handleRemove = (valueId) => () => {
63
63
  var _a, _b, _c;
64
- setSelectedOptions((prev) => prev.filter((v) => v.id !== value));
65
- (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, (_c = (_b = props.value) === null || _b === void 0 ? void 0 : _b.filter((v) => v !== value)) !== null && _c !== void 0 ? _c : []);
64
+ setSelectedOptions((prev) => prev.filter((v) => v.id !== valueId));
65
+ (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, (_c = (_b = props.value) === null || _b === void 0 ? void 0 : _b.filter((v) => v.id !== valueId)) !== null && _c !== void 0 ? _c : []);
66
66
  };
67
- const handleCheckboxChange = (value) => (checked) => {
67
+ const handleCheckboxChange = (valueId) => (checked) => {
68
68
  var _a, _b, _c, _d;
69
- if (((_a = props.value) === null || _a === void 0 ? void 0 : _a.includes(value)) && !checked) {
70
- handleRemove(value)();
69
+ if (((_a = props.value) === null || _a === void 0 ? void 0 : _a.some((v) => v.id === valueId)) && !checked) {
70
+ handleRemove(valueId)();
71
71
  return;
72
72
  }
73
- if (!((_b = props.value) === null || _b === void 0 ? void 0 : _b.includes(value)) && checked) {
74
- (_c = props.onChange) === null || _c === void 0 ? void 0 : _c.call(props, [...((_d = props.value) !== null && _d !== void 0 ? _d : []), value]);
73
+ const newOption = options.find((o) => o.id === valueId);
74
+ //adding new option if not in value
75
+ if (!((_b = props.value) === null || _b === void 0 ? void 0 : _b.some((v) => v.id === valueId)) && checked && newOption) {
76
+ (_c = props.onChange) === null || _c === void 0 ? void 0 : _c.call(props, [...((_d = props.value) !== null && _d !== void 0 ? _d : []), newOption]);
75
77
  }
76
78
  };
77
79
  const handleInputKeyDown = (event) => {
@@ -83,7 +85,7 @@ exports.MultiCombobox = (0, forwardRef_1.forwardRef)("MultiCombobox", (props, re
83
85
  const handleComboboxValueChange = (v) => {
84
86
  var _a;
85
87
  setSelectedOptions(v);
86
- (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, v.map((option) => option.id));
88
+ (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, v.map((option) => option));
87
89
  setQuery("");
88
90
  };
89
91
  return (react_2.default.createElement(react_1.Combobox, { as: "div", className: (0, cx_1.cx)("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), disabled: props.isDisabled || props.isReadOnly, multiple: true, onChange: handleComboboxValueChange, value: selectedOptions }, (renderProps) => (react_2.default.createElement(react_2.default.Fragment, null,
@@ -1,9 +1,8 @@
1
1
  import React from "react";
2
2
  import { MultiComboboxOption } from "./index";
3
- import { MultiComboboxValue } from "./multi-combobox";
4
3
  declare const _default: {
5
4
  title: string;
6
- component: React.ForwardRefExoticComponent<import("./multi-combobox").MultiComboboxProps<MultiComboboxValue[], MultiComboboxOption<MultiComboboxValue>> & React.RefAttributes<HTMLDivElement>>;
5
+ component: React.ForwardRefExoticComponent<import("./multi-combobox").MultiComboboxProps<import("./multi-combobox").MultiComboboxValueId, MultiComboboxOption<import("./multi-combobox").MultiComboboxValueId>> & React.RefAttributes<HTMLDivElement>>;
7
6
  };
8
7
  export default _default;
9
8
  export declare function Default(): JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/ui",
3
- "version": "1.0.0-beta.101",
3
+ "version": "1.0.0-beta.103",
4
4
  "description": "",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -20,7 +20,8 @@
20
20
  "@uxf/styles": "^2.1.2",
21
21
  "color2k": "^2.0.1",
22
22
  "dayjs": "^1.11.7",
23
- "jump.js": "^1.0.2"
23
+ "jump.js": "^1.0.2",
24
+ "react-dropzone": "^14.2.3"
24
25
  },
25
26
  "devDependencies": {
26
27
  "@types/jump.js": "^1.0.4",
@@ -0,0 +1 @@
1
+ export * from "./tooltip";
@@ -0,0 +1,17 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./tooltip"), exports);
@@ -0,0 +1,7 @@
1
+ import React, { ReactElement, ReactNode } from "react";
2
+ import { TooltipOptions } from "./use-tooltip";
3
+ export interface TooltipProps extends Omit<TooltipOptions, "arrowRef"> {
4
+ children: ReactElement;
5
+ content: ReactNode;
6
+ }
7
+ export declare const Tooltip: React.ForwardRefExoticComponent<TooltipProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,79 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.Tooltip = void 0;
27
+ const react_1 = require("@floating-ui/react");
28
+ const react_2 = __importStar(require("react"));
29
+ const forwardRef_1 = require("@uxf/core/utils/forwardRef");
30
+ const use_tooltip_1 = require("./use-tooltip");
31
+ const composeRefs_1 = require("@uxf/core/utils/composeRefs");
32
+ const STATIC_SIDES = {
33
+ top: "bottom",
34
+ right: "left",
35
+ bottom: "top",
36
+ left: "right",
37
+ };
38
+ exports.Tooltip = (0, forwardRef_1.forwardRef)("Tooltip", ({ children, content, ...options }, ref) => {
39
+ var _a, _b, _c, _d;
40
+ const arrowRef = (0, react_2.useRef)(null);
41
+ const tooltip = (0, use_tooltip_1.useTooltip)({ arrowRef, ...options });
42
+ const { getReferenceProps, getFloatingProps } = (0, react_1.useInteractions)([
43
+ (0, react_1.useHover)(tooltip.context, { delay: 200, handleClose: (0, react_1.safePolygon)() }),
44
+ (0, react_1.useFocus)(tooltip.context),
45
+ (0, react_1.useRole)(tooltip.context, { role: "tooltip" }),
46
+ (0, react_1.useDismiss)(tooltip.context),
47
+ ]);
48
+ const arrowX = (_a = tooltip.middlewareData.arrow) === null || _a === void 0 ? void 0 : _a.x;
49
+ const arrowY = (_b = tooltip.middlewareData.arrow) === null || _b === void 0 ? void 0 : _b.y;
50
+ const staticSide = STATIC_SIDES[tooltip.placement.split("-")[0]];
51
+ const stableRef = (0, react_2.useMemo)(() => (0, composeRefs_1.composeRefs)(ref, tooltip.reference, children.ref), [ref, tooltip.reference, children]);
52
+ return (react_2.default.createElement(react_2.default.Fragment, null,
53
+ (0, react_2.cloneElement)(children, getReferenceProps({
54
+ ref: stableRef,
55
+ ...children.props,
56
+ "data-state": tooltip.open ? "open" : "closed",
57
+ })),
58
+ tooltip.open && (react_2.default.createElement("div", { ...getFloatingProps({
59
+ ref: tooltip.floating,
60
+ style: {
61
+ position: tooltip.strategy,
62
+ top: (_c = tooltip.y) !== null && _c !== void 0 ? _c : 0,
63
+ left: (_d = tooltip.x) !== null && _d !== void 0 ? _d : 0,
64
+ visibility: tooltip.x === null ? "hidden" : "visible",
65
+ },
66
+ className: "uxf-tooltip__content",
67
+ }) },
68
+ content,
69
+ react_2.default.createElement("div", { className: "uxf-tooltip__arrow", ref: arrowRef, style: {
70
+ height: "16px",
71
+ left: arrowX !== undefined ? `${arrowX}px` : "",
72
+ position: "absolute",
73
+ top: arrowY !== undefined ? `${arrowY}px` : "",
74
+ transform: "rotate(45deg)",
75
+ width: "16px",
76
+ zIndex: "-1",
77
+ [staticSide]: "-6px",
78
+ } })))));
79
+ });
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ declare const _default: {
3
+ title: string;
4
+ component: React.ForwardRefExoticComponent<import("./tooltip").TooltipProps & React.RefAttributes<HTMLElement>>;
5
+ };
6
+ export default _default;
7
+ export declare function Default(): JSX.Element;
@@ -0,0 +1,19 @@
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
+ exports.Default = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const tooltip_1 = require("./tooltip");
9
+ const chip_1 = require("../chip");
10
+ exports.default = {
11
+ title: "UI/Tooltip",
12
+ component: tooltip_1.Tooltip,
13
+ };
14
+ function Default() {
15
+ const sides = ["top", "bottom", "bottom-start", "left", "right"];
16
+ return (react_1.default.createElement("div", { className: "grid h-96 place-items-center" }, sides.map((placement) => (react_1.default.createElement(tooltip_1.Tooltip, { content: "My tooltip content", key: placement, placement: placement },
17
+ react_1.default.createElement(chip_1.Chip, { color: "green" }, placement))))));
18
+ }
19
+ exports.Default = Default;
@@ -0,0 +1,28 @@
1
+ import { MutableRefObject } from "react";
2
+ import { Placement } from "@floating-ui/react";
3
+ export interface TooltipOptions {
4
+ arrowRef: MutableRefObject<null>;
5
+ offset?: number;
6
+ placement?: Placement;
7
+ shiftPadding?: number;
8
+ }
9
+ export declare function useTooltip(options: TooltipOptions): {
10
+ placement: Placement;
11
+ strategy: import("@floating-ui/react").Strategy;
12
+ middlewareData: import("@floating-ui/react").MiddlewareData;
13
+ x: number | null;
14
+ y: number | null;
15
+ update: () => void;
16
+ reference: (node: import("@floating-ui/react").ReferenceType | null) => void;
17
+ floating: (node: HTMLElement | null) => void;
18
+ positionReference: (node: import("@floating-ui/react").ReferenceType | null) => void;
19
+ context: import("@floating-ui/react").FloatingContext<import("@floating-ui/react").ReferenceType>;
20
+ refs: import("@floating-ui/react").ExtendedRefs<import("@floating-ui/react").ReferenceType>;
21
+ elements: import("@floating-ui/react").ExtendedElements<import("@floating-ui/react").ReferenceType>;
22
+ isPositioned: boolean;
23
+ getReferenceProps: (userProps?: import("react").HTMLProps<Element> | undefined) => Record<string, unknown>;
24
+ getFloatingProps: (userProps?: import("react").HTMLProps<HTMLElement> | undefined) => Record<string, unknown>;
25
+ getItemProps: (userProps?: import("react").HTMLProps<HTMLElement> | undefined) => Record<string, unknown>;
26
+ open: boolean;
27
+ setOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
28
+ };
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTooltip = void 0;
4
+ const react_1 = require("react");
5
+ const react_2 = require("@floating-ui/react");
6
+ function useTooltip(options) {
7
+ var _a, _b;
8
+ const [open, setOpen] = (0, react_1.useState)(false);
9
+ const data = (0, react_2.useFloating)({
10
+ placement: options.placement,
11
+ open,
12
+ onOpenChange: setOpen,
13
+ whileElementsMounted: react_2.autoUpdate,
14
+ middleware: [
15
+ (0, react_2.offset)((_a = options.offset) !== null && _a !== void 0 ? _a : 16),
16
+ (0, react_2.flip)(),
17
+ (0, react_2.shift)({ padding: (_b = options.shiftPadding) !== null && _b !== void 0 ? _b : 8 }),
18
+ (0, react_2.arrow)({ element: options.arrowRef }),
19
+ ],
20
+ });
21
+ const context = data.context;
22
+ const hover = (0, react_2.useHover)(context, {
23
+ move: false,
24
+ });
25
+ const dismiss = (0, react_2.useDismiss)(context);
26
+ const role = (0, react_2.useRole)(context, { role: "tooltip" });
27
+ const interactions = (0, react_2.useInteractions)([hover, dismiss, role]);
28
+ return (0, react_1.useMemo)(() => ({
29
+ open,
30
+ setOpen,
31
+ ...interactions,
32
+ ...data,
33
+ }), [open, setOpen, interactions, data]);
34
+ }
35
+ exports.useTooltip = useTooltip;
@@ -0,0 +1,12 @@
1
+ export interface FileResponse {
2
+ extension: string;
3
+ id: number;
4
+ name: string;
5
+ namespace?: string | null;
6
+ uuid: string;
7
+ }
8
+ export interface UploadOptions {
9
+ abortController?: AbortController;
10
+ onUploadProgress?: (progressEvent: UploadProgressEvent) => void;
11
+ }
12
+ export declare type UploadProgressEvent = Pick<ProgressEvent, "lengthComputable" | "loaded" | "total">;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/types/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./color";
2
2
  export * from "./form-control-props";
3
+ export * from "./file-response";
package/types/index.js CHANGED
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./color"), exports);
18
18
  __exportStar(require("./form-control-props"), exports);
19
+ __exportStar(require("./file-response"), exports);
@@ -65,6 +65,21 @@ module.exports = {
65
65
  height: 512,
66
66
  data: `<path d="M144 480C64.5 480 0 415.5 0 336c0-62.8 40.2-116.2 96.2-135.9-.1-2.7-.2-5.4-.2-8.1 0-88.4 71.6-160 160-160 59.3 0 111 32.2 138.7 80.2C409.9 102 428.3 96 448 96c53 0 96 43 96 96 0 12.2-2.3 23.8-6.4 34.6C596 238.4 640 290.1 640 352c0 70.7-57.3 128-128 128H144zm79-217c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l39-39V392c0 13.3 10.7 24 24 24s24-10.7 24-24V257.9l39 39c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-80-80c-9.4-9.4-24.6-9.4-33.9 0l-80 80z" fill="currentColor"/>`,
67
67
  },
68
+ file: {
69
+ width: 384,
70
+ height: 512,
71
+ data: `<path d="M0 64C0 28.65 28.65 0 64 0h165.5c17 0 33.2 6.743 45.2 18.75l90.6 90.55c12 12 18.7 28.2 18.7 45.2V448c0 35.3-28.7 64-64 64H64c-35.35 0-64-28.7-64-64V64zm336 384V160h-80c-17.7 0-32-14.3-32-32V48H64c-8.84 0-16 7.16-16 16v384c0 8.8 7.16 16 16 16h256c8.8 0 16-7.2 16-16z" fill="currentColor" />`,
72
+ },
73
+ imageFile: {
74
+ width: 384,
75
+ height: 512,
76
+ data: `<path d="m365.3 93.38-74.63-74.64C278.6 6.742 262.3 0 245.4 0H64C28.65 0 0 28.65 0 64l.0065 384c0 35.34 28.65 64 64 64H320c35.2 0 64-28.8 64-64V138.6c0-16.9-6.7-33.2-18.7-45.22zM336 448c0 8.836-7.164 16-16 16H64.02c-8.838 0-16-7.164-16-16L48 64.13c0-8.836 7.164-16 16-16h160V128c0 17.67 14.33 32 32 32h79.1v288zM215.3 292c-4.68 0-9.051 2.34-11.65 6.234L164 357.8l-11.68-17.53c-2.62-3.97-7.02-6.27-11.62-6.27-4.682 0-9.053 2.34-11.65 6.234l-46.67 70c-2.865 4.297-3.131 9.82-.6953 14.37C84.09 429.2 88.84 432 93.1 432h196c5.163 0 9.907-2.844 12.34-7.395 2.436-4.551 2.17-10.07-.6953-14.37l-74.67-112C224.4 294.3 220 292 215.3 292zm-87.3-4c17.67 0 32-14.33 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z" fill="currentColor" />`,
77
+ },
78
+ videoFile: {
79
+ width: 384,
80
+ height: 512,
81
+ data: `<path d="m365.3 93.38-74.63-74.64C278.6 6.742 262.3 0 245.4 0H64C28.65 0 0 28.65 0 64l.0065 384c0 35.34 28.65 64 64 64H320c35.2 0 64-28.8 64-64V138.6c0-16.9-6.7-33.2-18.7-45.22zM336 448c0 8.836-7.164 16-16 16H64.02c-8.838 0-16-7.164-16-16L48 64.13c0-8.836 7.164-16 16-16h160V128c0 17.67 14.33 32 32 32h79.1v288zm-96-160c0-17.67-14.33-32-32-32h-96c-17.67 0-32 14.33-32 32v96c0 17.67 14.33 32 32 32h96c17.67 0 32-14.33 32-32v-16.52l43.84 30.2c8.46 5.82 20.16-.08 20.16-10.28V284.6c0-10.16-11.64-16.16-20.16-10.32L240 304.5V288z" fill="currentColor" />`,
82
+ },
68
83
  user: {
69
84
  width: 448,
70
85
  height: 512,
@@ -1,7 +0,0 @@
1
- export interface FileResponse {
2
- extension: string;
3
- id: number;
4
- name: string;
5
- namespace?: string | null;
6
- uuid: string;
7
- }