@uxf/ui 11.53.1 → 11.54.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.
@@ -1,5 +1,6 @@
1
- import React, { HTMLAttributes } from "react";
1
+ import React, { HTMLAttributes, ReactNode } from "react";
2
2
  export interface AvatarProps extends HTMLAttributes<HTMLDivElement> {
3
3
  src?: string;
4
+ placeholder?: ReactNode;
4
5
  }
5
6
  export declare const Avatar: React.ForwardRefExoticComponent<AvatarProps & React.RefAttributes<HTMLDivElement>>;
package/avatar/avatar.js CHANGED
@@ -28,7 +28,8 @@ const cx_1 = require("@uxf/core/utils/cx");
28
28
  const react_1 = __importStar(require("react"));
29
29
  const icon_1 = require("../icon");
30
30
  exports.Avatar = (0, react_1.forwardRef)((props, ref) => {
31
+ var _a;
31
32
  const avatarClassName = (0, cx_1.cx)("uxf-avatar", props.className);
32
- return (react_1.default.createElement("div", { className: avatarClassName, ref: ref }, props.src ? react_1.default.createElement("img", { alt: "", className: "uxf-avatar__image", src: props.src }) : react_1.default.createElement(icon_1.Icon, { name: "user", size: 16 })));
33
+ return (react_1.default.createElement("div", { className: avatarClassName, ref: ref }, props.src ? (react_1.default.createElement("img", { alt: "", className: "uxf-avatar__image", src: props.src })) : (((_a = props.placeholder) !== null && _a !== void 0 ? _a : react_1.default.createElement(icon_1.Icon, { name: "user", size: 16 })))));
33
34
  });
34
35
  exports.Avatar.displayName = "UxfUiAvatar";
@@ -55,7 +55,7 @@ exports.AvatarFileInput = (0, react_1.forwardRef)((props, ref) => {
55
55
  inputNode.value = "";
56
56
  }
57
57
  };
58
- return (react_1.default.createElement(form_component_1.FormComponent, { className: rootClassName, errorId: props.id, helperText: props.helperText, hiddenLabel: props.hiddenLabel, inputId: id, label: props.label, name: props.name },
58
+ return (react_1.default.createElement(form_component_1.FormComponent, { className: rootClassName, errorId: props.id, helperText: props.helperText, hiddenLabel: props.hiddenLabel, inputId: id, isRequired: props.isRequired, label: props.label, name: props.name },
59
59
  react_1.default.createElement("div", { className: "uxf-avatar-file-input__inner-wrapper" },
60
60
  react_1.default.createElement("div", { className: (0, cx_1.cx)("uxf-avatar-file-input__input", stateClassName), onClick: onSelectFile },
61
61
  react_1.default.createElement(_file_input_base_1._FileInputBase, { accept: (_c = props.accept) !== null && _c !== void 0 ? _c : "image/*", "aria-describedby": errorId, "aria-invalid": props.isInvalid, className: "uxf-avatar-file-input__input-element", form: props.form, id: id, isDisabled: props.isDisabled, isFocused: props.isFocused, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, maxFileSize: props.maxFileSize, name: props.name, onBlur: input.onBlur, onChange: props.onChange, onFocus: input.onFocus, onUploadError: props.onUploadError, onUploadFile: props.onUploadFile, ref: (0, compose_refs_1.composeRefs)(innerRef, ref), value: props.value }),
@@ -34,6 +34,7 @@
34
34
  }
35
35
 
36
36
  &__dismissable {
37
+ max-height: 100vh;
37
38
  padding-top: theme("spacing.11");
38
39
 
39
40
  &:hover {
@@ -41,8 +42,10 @@
41
42
  }
42
43
 
43
44
  &.is-collapsed {
45
+ max-height: calc(var(--last-flash-message-height) + 60px);
44
46
  padding-right: theme("spacing.5");
45
47
  scrollbar-width: none;
48
+ transition: max-height 0.3s ease;
46
49
  }
47
50
  }
48
51
 
package/css/textarea.css CHANGED
@@ -24,12 +24,15 @@
24
24
  display: block;
25
25
  outline: none;
26
26
  overflow-y: hidden;
27
- resize: none;
28
27
  width: 100%;
29
28
 
30
29
  &::placeholder {
31
30
  color: theme("colors.gray.400");
32
31
  }
32
+
33
+ &--is-auto-height-enabled {
34
+ resize: none;
35
+ }
33
36
  }
34
37
 
35
38
  &.is-focused {
@@ -28,6 +28,7 @@ const show_1 = require("@uxf/core-react/components/show");
28
28
  const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
29
29
  const handle_rejected_files_1 = require("@uxf/ui/dropzone/handle-rejected-files");
30
30
  const react_1 = __importStar(require("react"));
31
+ const text_input_1 = require("../text-input");
31
32
  const toggle_1 = require("../toggle");
32
33
  const action_1 = require("../utils/action");
33
34
  const upload_file_mock_1 = require("../utils/mocks/upload-file.mock");
@@ -48,11 +49,10 @@ function Default() {
48
49
  react_1.default.createElement(toggle_1.Toggle, { label: "Only images upload", name: "toggle", onChange: () => setHasOnlyImagesAllowed((prev) => !prev), value: hasOnlyImagesAllowed }),
49
50
  react_1.default.createElement("div", { className: "flex items-center" },
50
51
  react_1.default.createElement(toggle_1.Toggle, { label: "Limit file count", name: "toggle", onChange: () => setIsFileCountLimited((prev) => !prev), value: isFileCountLimited }),
51
- react_1.default.createElement("input", { className: "w-20", onChange: (event) => setFileCountLimit(parseInt(event.target.value, 10)), type: "number", value: fileCountLimit })),
52
+ react_1.default.createElement(text_input_1.TextInput, { className: "w-20", name: "limit-file-count", onChange: (value) => setFileCountLimit(parseInt(value, 10)), type: "number", value: fileCountLimit.toString() })),
52
53
  react_1.default.createElement("div", { className: "flex items-center" },
53
54
  react_1.default.createElement(toggle_1.Toggle, { label: "Limit file size", name: "toggle", onChange: () => setIsFileSizeLimited((prev) => !prev), value: isFileSizeLimited }),
54
- react_1.default.createElement("input", { className: "w-20", onChange: (event) => setFileSizeLimit(parseInt(event.target.value, 10)), type: "number", value: fileSizeLimit }),
55
- "MB"),
55
+ react_1.default.createElement(text_input_1.TextInput, { className: "w-28", name: "limit-file-size", onChange: (value) => setFileSizeLimit(parseInt(value, 10)), rightElement: "MB", type: "number", value: fileSizeLimit.toString() })),
56
56
  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 }),
57
57
  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 }),
58
58
  react_1.default.createElement(show_1.Show, { when: (0, is_not_empty_1.isNotEmpty)(files) },
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.FlashMessages = void 0;
27
27
  const react_1 = require("@headlessui/react");
28
28
  const use_clickable_props_1 = require("@uxf/core-react/hooks/use-clickable-props");
29
+ const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
29
30
  const react_2 = __importStar(require("react"));
30
31
  const flash_message_1 = require("./flash-message");
31
32
  exports.FlashMessages = (0, react_2.forwardRef)((props, ref) => {
@@ -82,13 +83,20 @@ exports.FlashMessages = (0, react_2.forwardRef)((props, ref) => {
82
83
  closeAll: innerRef.current.closeAll,
83
84
  open: innerRef.current.open,
84
85
  }), []);
86
+ const dismissableContainerRef = (0, react_2.useRef)(null);
85
87
  const clickableProps = (0, use_clickable_props_1.useClickableProps)({
86
- className: `uxf-flash-messages__dismissable ${isCollapsed ? "is-collapsed" : ""}`,
88
+ className: `uxf-flash-messages__dismissable ${isCollapsed ? "is-collapsed" : "is-expanded"}`,
87
89
  onMouseEnter: () => setIsCollapsed(false),
88
- onMouseLeave: () => setIsCollapsed(true),
90
+ onMouseLeave: () => {
91
+ // scroll back down in case of having too many flash messages and scrolled up
92
+ if ((0, is_not_nil_1.isNotNil)(dismissableContainerRef.current)) {
93
+ dismissableContainerRef.current.scrollTop = dismissableContainerRef.current.scrollHeight;
94
+ }
95
+ setIsCollapsed(true);
96
+ },
89
97
  });
90
- return notifications.length > 0 ? (react_2.default.createElement("div", { className: "uxf-flash-messages" },
91
- dismissableNotifications.length > 0 && (react_2.default.createElement("div", { ...clickableProps },
98
+ return notifications.length > 0 ? (react_2.default.createElement("div", { className: "uxf-flash-messages", style: { "--last-flash-message-height": `${lastToastHeight}px` } },
99
+ dismissableNotifications.length > 0 && (react_2.default.createElement("div", { ref: dismissableContainerRef, ...clickableProps },
92
100
  react_2.default.createElement("div", null, dismissableNotifications.map((notification, index) => {
93
101
  const isLast = index === dismissableNotifications.length - 1;
94
102
  return (react_2.default.createElement(react_1.Transition, { appear: true, className: "uxf-flash-message-wrapper", enterFrom: "uxf-flash-message-wrapper--enter-from", enterTo: "uxf-flash-message-wrapper--enter-to", key: notification.id, ref: isLast ? lastToastRef : null, show: true, style: isLast
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/ui",
3
- "version": "11.53.1",
3
+ "version": "11.54.0",
4
4
  "description": "",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -23,10 +23,10 @@
23
23
  "dependencies": {
24
24
  "@floating-ui/react": "0.26.28",
25
25
  "@headlessui/react": "1.7.19",
26
- "@uxf/core": "11.53.1",
27
- "@uxf/core-react": "11.53.1",
26
+ "@uxf/core": "11.54.0",
27
+ "@uxf/core-react": "11.54.0",
28
28
  "@uxf/datepicker": "11.50.0",
29
- "@uxf/styles": "11.53.1",
29
+ "@uxf/styles": "11.54.0",
30
30
  "color2k": "2.0.3",
31
31
  "dayjs": "1.11.13",
32
32
  "jump.js": "1.0.2",
@@ -34,7 +34,7 @@ const cx_1 = require("@uxf/core/utils/cx");
34
34
  const react_1 = __importStar(require("react"));
35
35
  const form_component_1 = require("../form-component");
36
36
  exports.Textarea = (0, react_1.forwardRef)((props, ref) => {
37
- var _a, _b;
37
+ var _a, _b, _c;
38
38
  const innerRef = (0, react_1.useRef)(null);
39
39
  const input = (0, use_input_focus_1.useInputFocus)(innerRef, props.onBlur, props.onFocus);
40
40
  const generatedId = (0, react_1.useId)();
@@ -43,15 +43,17 @@ exports.Textarea = (0, react_1.forwardRef)((props, ref) => {
43
43
  const rootClassName = (0, cx_1.cx)("uxf-textarea", ((_b = props.isFocused) !== null && _b !== void 0 ? _b : input.focused) && classes_1.CLASSES.IS_FOCUSED, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.className);
44
44
  const handleChange = (event) => props.onChange(event.target.value, event);
45
45
  const focusTextareaOnWrapperClick = () => { var _a; return (_a = innerRef.current) === null || _a === void 0 ? void 0 : _a.focus(); };
46
+ const rows = (_c = props.rows) !== null && _c !== void 0 ? _c : 4;
46
47
  (0, use_isomorphic_layout_effect_1.useIsomorphicLayoutEffect)(() => {
47
48
  const node = innerRef.current;
48
49
  if (!node || props.disableAutoHeight) {
49
50
  return;
50
51
  }
51
- (0, adjust_textarea_height_1.adjustTextareaHeight)(node, props.rows);
52
- }, [props.disableAutoHeight, props.rows, props.value]);
52
+ const cleanup = (0, adjust_textarea_height_1.adjustTextareaHeight)(node, rows);
53
+ return () => cleanup();
54
+ }, [props.disableAutoHeight, rows]);
53
55
  return (react_1.default.createElement(form_component_1.FormComponent, { className: rootClassName, errorId: errorId, form: props.form, helperText: props.helperText, hiddenLabel: props.hiddenLabel, inputId: id, isRequired: props.isRequired, label: props.label, name: props.name },
54
56
  react_1.default.createElement("div", { className: "uxf-textarea__wrapper", onClick: focusTextareaOnWrapperClick, style: props.style },
55
- react_1.default.createElement("textarea", { "aria-describedby": errorId, "aria-invalid": props.isInvalid, autoComplete: props.autoComplete, className: "uxf-textarea__element", disabled: props.isDisabled, form: props.form, id: id, maxLength: props.maxLength, minLength: props.minLength, name: props.name, onBlur: input.onBlur, onChange: handleChange, onFocus: input.onFocus, placeholder: props.placeholder, readOnly: props.isReadOnly, ref: (0, compose_refs_1.composeRefs)(innerRef, ref), required: props.isRequired, rows: props.rows, value: props.value }))));
57
+ react_1.default.createElement("textarea", { "aria-describedby": errorId, "aria-invalid": props.isInvalid, autoComplete: props.autoComplete, className: (0, cx_1.cx)("uxf-textarea__element", !props.disableAutoHeight && rows >= 1 && "uxf-textarea__element--is-auto-height-enabled"), disabled: props.isDisabled, form: props.form, id: id, maxLength: props.maxLength, minLength: props.minLength, name: props.name, onBlur: input.onBlur, onChange: handleChange, onFocus: input.onFocus, placeholder: props.placeholder, readOnly: props.isReadOnly, ref: (0, compose_refs_1.composeRefs)(innerRef, ref), required: props.isRequired, rows: rows, value: props.value }))));
56
58
  });
57
59
  exports.Textarea.displayName = "UxfUiTextarea";