@uxf/ui 11.0.0-beta.21 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/_file-input-base/file-input-base.d.ts +1 -0
  2. package/_file-input-base/file-input-base.js +9 -7
  3. package/_select-base/_select-base.d.ts +1 -0
  4. package/_select-base/_select-base.js +14 -5
  5. package/avatar-file-input/avatar-file-input.d.ts +10 -2
  6. package/avatar-file-input/avatar-file-input.js +27 -11
  7. package/calendar/calendar-day-cell.js +5 -2
  8. package/calendar/utils/get-class-names-from-flags.d.ts +2 -0
  9. package/calendar/utils/get-class-names-from-flags.js +10 -0
  10. package/checkbox-input/checkbox-input.d.ts +1 -0
  11. package/checkbox-input/checkbox-input.js +8 -3
  12. package/combobox/combobox.js +2 -1
  13. package/create-component-preview-page/ui-components.d.ts +15 -0
  14. package/create-component-preview-page/ui-components.js +15 -0
  15. package/create-component-preview-page/ui-readmes.js +68 -62
  16. package/css/avatar-file-input.css +97 -67
  17. package/css/checkbox-input.css +9 -1
  18. package/date-picker/date-picker.d.ts +7 -4
  19. package/date-picker/date-picker.js +3 -2
  20. package/date-picker/date-picker.stories.js +38 -1
  21. package/date-picker-input/date-picker-input.d.ts +8 -3
  22. package/date-picker-input/date-picker-input.js +9 -7
  23. package/date-picker-input/date-picker-input.stories.js +2 -1
  24. package/date-range-picker/date-range-picker.d.ts +4 -1
  25. package/date-range-picker/date-range-picker.js +1 -0
  26. package/date-range-picker-input/README.md +9 -1
  27. package/date-range-picker-input/date-range-picker-input.d.ts +4 -1
  28. package/date-range-picker-input/date-range-picker-input.js +1 -1
  29. package/dropzone/dropzone-input.d.ts +1 -0
  30. package/dropzone/dropzone-input.js +11 -5
  31. package/dropzone/dropzone-list.d.ts +1 -0
  32. package/dropzone/dropzone-list.js +2 -2
  33. package/file-input/file-input.d.ts +2 -2
  34. package/file-input/file-input.js +11 -2
  35. package/image-gallery/README.md +8 -0
  36. package/message/README.md +25 -1
  37. package/multi-combobox/_multi-combobox-base.js +26 -4
  38. package/package.json +4 -4
  39. package/radio-group/radio-group.d.ts +1 -1
  40. package/tabs/tabs.d.ts +1 -0
  41. package/tabs/tabs.js +2 -1
  42. package/utils/validator/validator-exceptions.d.ts +3 -0
  43. package/utils/validator/validator-exceptions.js +7 -0
@@ -1,116 +1,146 @@
1
1
  .uxf-avatar-file-input {
2
- align-items: center;
3
- display: flex;
4
- gap: theme("spacing.4");
5
-
6
- &__input {
7
- display: none;
2
+ &.is-disabled .uxf-avatar-file-input__inner-wrapper {
3
+ cursor: not-allowed;
8
4
  }
9
5
 
10
- &--variant-default {
11
- .uxf-avatar-file-input__label {
12
- border-radius: theme("borderRadius.full");
13
- }
6
+ &__inner-wrapper {
7
+ align-items: center;
8
+ display: flex;
9
+ gap: theme("spacing.4");
10
+ margin-top: theme("spacing.2");
14
11
  }
15
12
 
16
- &__label {
17
- @apply transition-all duration-75;
18
-
19
- align-items: center;
20
- border-style: dashed;
21
- border-width: theme("borderWidth.2");
13
+ &__input {
22
14
  cursor: pointer;
23
- display: flex;
15
+ flex-shrink: 0;
24
16
  height: theme("height.20");
25
- justify-content: center;
17
+ position: relative;
26
18
  width: theme("width.20");
27
19
 
28
- :root .light & {
29
- border-color: theme("colors.lightBorder");
30
- }
31
-
32
- :root .dark & {
33
- border-color: theme("colors.darkBorder");
34
- }
20
+ &:hover .uxf-avatar-file-input__input-empty {
21
+ :root .light & {
22
+ --bg-color: theme("colors.lightBorder/.25");
23
+ }
35
24
 
36
- &-wrapper {
37
- align-items: center;
38
- display: flex;
39
- gap: theme("spacing.4");
25
+ :root .dark & {
26
+ --bg-color: theme("colors.darkBorder/.25");
27
+ }
40
28
  }
41
29
 
42
- &-icon {
30
+ &.is-invalid .uxf-avatar-file-input__input-empty {
43
31
  :root .light & {
44
- color: theme("colors.lightLow");
32
+ --bg-color: theme("colors.error.DEFAULT/.05");
33
+ --border-color: var(--color);
34
+ --color: theme("colors.error.DEFAULT");
45
35
  }
46
36
 
47
37
  :root .dark & {
48
- color: theme("colors.lightBorder");
38
+ --bg-color: theme("colors.error.DEFAULT/.05");
39
+ --border-color: var(--color);
40
+ --color: theme("colors.error.DEFAULT");
49
41
  }
42
+ }
50
43
 
51
- &.is-invalid {
44
+ &.is-disabled {
45
+ pointer-events: none;
46
+
47
+ .uxf-avatar-file-input__input-empty {
52
48
  :root .light & {
53
- color: theme("colors.error.DEFAULT");
49
+ --border-color: var(--color);
50
+ --color: theme("colors.lightBorder");
54
51
  }
55
52
 
56
53
  :root .dark & {
57
- color: theme("colors.error.DEFAULT");
54
+ --border-color: var(--color);
55
+ --color: theme("colors.darkBorder");
58
56
  }
59
57
  }
58
+
59
+ .uxf-avatar-file-input__input-avatar {
60
+ opacity: 0.5;
61
+ }
60
62
  }
63
+ }
64
+
65
+ &__input-element {
66
+ @apply sr-only;
61
67
 
62
- &:hover {
68
+ &:focus-visible + .uxf-avatar-file-input__input-empty {
63
69
  border-width: theme("borderWidth.4");
64
- }
65
70
 
66
- &.is-invalid {
67
- :root .light & {
68
- border-color: theme("colors.error.DEFAULT");
71
+ /* :root .light & {
72
+ --bg-color: theme("colors.primary.DEFAULT/.05");
73
+ --border-color: var(--color);
74
+ --color: theme("colors.primary.DEFAULT");
69
75
  }
70
76
 
71
77
  :root .dark & {
72
- border-color: theme("colors.error.DEFAULT");
73
- }
78
+ --bg-color: theme("colors.primary.DEFAULT/.05");
79
+ --border-color: var(--color);
80
+ --color: theme("colors.primary.DEFAULT");
81
+ */
74
82
  }
83
+ }
75
84
 
76
- &.is-disabled {
77
- background-color: theme("colors.lightLow/.20");
78
- cursor: not-allowed;
79
-
80
- &:hover {
81
- border-width: theme("borderWidth.2");
82
- }
83
- }
85
+ &__input-avatar {
86
+ border-radius: inherit;
87
+ display: flex;
88
+ height: 100%;
89
+ width: 100%;
84
90
  }
85
91
 
86
- &__label-text {
87
- @apply text-sm shadow-sm;
92
+ &__input-empty {
93
+ --bg-color: transparent;
88
94
 
89
- border: theme("borderWidth.DEFAULT") solid theme("colors.gray.300");
90
- padding: theme("spacing[1.5]") theme("spacing.3");
91
- text-align: center;
95
+ @apply transition-all duration-75;
96
+
97
+ align-items: center;
98
+ background-color: var(--bg-color);
99
+ border: theme("borderWidth.2") dashed var(--border-color);
100
+ border-radius: inherit;
101
+ display: flex;
102
+ height: 100%;
103
+ justify-content: center;
104
+ width: 100%;
92
105
 
93
106
  :root .light & {
94
- color: theme("colors.lightHigh");
107
+ --color: theme("colors.lightMedium");
108
+ --border-color: theme("colors.lightBorder");
95
109
  }
96
110
 
97
111
  :root .dark & {
98
- color: theme("colors.lightBorder");
112
+ --color: theme("colors.darkMedium");
113
+ --border-color: theme("colors.darkBorder");
99
114
  }
115
+ }
100
116
 
101
- &.is-invalid {
102
- :root .light & {
103
- color: theme("colors.error.DEFAULT");
104
- }
117
+ &__input-empty-icon {
118
+ color: var(--color);
119
+ height: theme("width.6");
120
+ width: theme("width.6");
121
+ }
105
122
 
106
- :root .dark & {
107
- color: theme("colors.error.DEFAULT");
108
- }
123
+ &__controls-buttons {
124
+ align-items: flex-start;
125
+ display: flex;
126
+ flex-direction: column;
127
+ gap: theme("spacing.2");
128
+ justify-content: center;
129
+ }
130
+
131
+ &__controls-button--remove .uxf-button__text {
132
+ color: theme("colors.error.DEFAULT");
133
+ }
134
+
135
+ &--variant-default {
136
+ .uxf-avatar-file-input__input {
137
+ border-radius: theme("borderRadius.full");
109
138
  }
110
139
  }
111
140
 
112
- &__image {
113
- height: theme("height.20");
114
- width: theme("width.20");
141
+ &--variant-square {
142
+ .uxf-avatar-file-input__input {
143
+ border-radius: 0;
144
+ }
115
145
  }
116
146
  }
@@ -1,6 +1,8 @@
1
1
  .uxf-checkbox-input {
2
+ margin-top: 4px;
3
+
2
4
  &__wrapper {
3
- @apply flex items-center justify-between space-x-3;
5
+ @apply flex justify-between space-x-3;
4
6
  }
5
7
 
6
8
  &__label {
@@ -15,6 +17,12 @@
15
17
  }
16
18
  }
17
19
 
20
+ &__label--subtitle {
21
+ color: theme("colors.error.DEFAULT");
22
+ display: block;
23
+ font-size: theme("fontSize.caption");
24
+ }
25
+
18
26
  &.is-disabled,
19
27
  &.is-readonly {
20
28
  & + .uxf-checkbox-input__label {
@@ -1,13 +1,16 @@
1
1
  import { OnDateChangeType } from "@uxf/datepicker/hooks/use-date-picker";
2
+ import { DatesConfig } from "@uxf/datepicker/utils/types";
2
3
  import { FC, ReactNode } from "react";
3
4
  export interface DatePickerProps {
5
+ bottomContent?: ReactNode;
4
6
  closePopoverHandler?: () => void;
5
- onChange: (data: OnDateChangeType) => void;
6
- selectedDate: Date | null;
7
- minDate?: Date;
7
+ datesConfig?: DatesConfig[];
8
8
  maxDate?: Date;
9
+ minDate?: Date;
10
+ onChange: (data: OnDateChangeType) => void;
9
11
  preventScroll?: boolean;
12
+ selectedDate: Date | null;
13
+ /** @deprecated */
10
14
  unavailableDates?: Date[];
11
- bottomContent?: ReactNode;
12
15
  }
13
16
  export declare const DatePicker: FC<DatePickerProps>;
@@ -16,10 +16,11 @@ const DatePicker = (props) => {
16
16
  props.onChange(data);
17
17
  (_a = props.closePopoverHandler) === null || _a === void 0 ? void 0 : _a.call(props);
18
18
  },
19
- selectedDate: props.selectedDate,
20
- minBookingDate: props.minDate,
19
+ datesConfig: props.datesConfig,
21
20
  maxBookingDate: props.maxDate,
21
+ minBookingDate: props.minDate,
22
22
  preventScroll: props.preventScroll,
23
+ selectedDate: props.selectedDate,
23
24
  unavailableDates: props.unavailableDates,
24
25
  });
25
26
  return (react_1.default.createElement(date_picker_context_1.DatePickerContext.Provider, { value: datePickerProps },
@@ -22,8 +22,12 @@ 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
+ };
25
28
  Object.defineProperty(exports, "__esModule", { value: true });
26
29
  exports.Default = void 0;
30
+ const dayjs_1 = __importDefault(require("dayjs"));
27
31
  const react_1 = __importStar(require("react"));
28
32
  const action_1 = require("../utils/action");
29
33
  const date_picker_1 = require("./date-picker");
@@ -31,12 +35,45 @@ exports.default = {
31
35
  title: "UI/DatePicker",
32
36
  component: date_picker_1.DatePicker,
33
37
  };
38
+ const today = (0, dayjs_1.default)();
39
+ const unavailableDates = [
40
+ today.toDate(),
41
+ today.add(5, "days").toDate(),
42
+ today.add(6, "days").toDate(),
43
+ today.add(7, "days").toDate(),
44
+ today.add(11, "days").toDate(),
45
+ today.add(12, "days").toDate(),
46
+ ];
47
+ const datesConfig = [
48
+ {
49
+ flag: "flag-1",
50
+ dates: [today.add(5, "days").toDate(), today.add(6, "days").toDate()],
51
+ },
52
+ {
53
+ flag: "flag-2",
54
+ dates: [today.add(3, "days").toDate()],
55
+ isDisabled: true,
56
+ },
57
+ {
58
+ dates: [today.add(8, "days").toDate()],
59
+ isDisabled: true,
60
+ },
61
+ ];
34
62
  function Default() {
35
63
  const [value, setValue] = (0, react_1.useState)(null);
36
64
  const onChange = (0, action_1.action)("onChange", setValue);
37
65
  const onClose = () => null;
38
66
  const testDatePickers = (react_1.default.createElement(react_1.default.Fragment, null,
39
- react_1.default.createElement(date_picker_1.DatePicker, { closePopoverHandler: onClose, onChange: onChange, selectedDate: value })));
67
+ react_1.default.createElement("p", { className: "text-lg" }, "Date picker"),
68
+ react_1.default.createElement(date_picker_1.DatePicker, { closePopoverHandler: onClose, onChange: onChange, selectedDate: value }),
69
+ react_1.default.createElement("p", { className: "text-lg" }, "Date picker with unavailable dates"),
70
+ react_1.default.createElement(date_picker_1.DatePicker, { onChange: onChange, selectedDate: value, unavailableDates: unavailableDates }),
71
+ react_1.default.createElement("p", { className: "text-lg" }, "Date picker with dates config"),
72
+ react_1.default.createElement("ul", null,
73
+ react_1.default.createElement("li", null, "now + 5 days & now + 6 day -> flag-1 className, not disabled"),
74
+ react_1.default.createElement("li", null, "now + 3 days -> flag-2 className, disabled"),
75
+ react_1.default.createElement("li", null, "now + 8 days -> no custom className, disabled")),
76
+ react_1.default.createElement(date_picker_1.DatePicker, { onChange: onChange, selectedDate: value, datesConfig: datesConfig })));
40
77
  return (react_1.default.createElement(react_1.default.Fragment, null,
41
78
  react_1.default.createElement("div", { className: "light max-w-[640px] space-y-4 rounded bg-white p-8" }, testDatePickers),
42
79
  react_1.default.createElement("div", { className: "dark max-w-[640px] space-y-4 rounded bg-gray-900 p-8 text-white" }, testDatePickers)));
@@ -1,14 +1,19 @@
1
+ import { DatesConfig } from "@uxf/datepicker/utils/types";
1
2
  import React, { ReactNode } from "react";
2
3
  import { InputWithPopoverProps } from "../_input-with-popover";
3
4
  export declare const ALLOWED_DATE_FORMAT: string[];
4
5
  export declare const DISPLAY_DATE_FORMAT = "D. M. YYYY";
5
6
  export declare const OUTPUT_DATE_FORMAT = "YYYY-MM-DD";
6
7
  export interface DatePickerInputProps extends Omit<InputWithPopoverProps<string | null>, "children" | "placeholder" | "triggerElement"> {
8
+ allowedDateFormats?: string[];
9
+ bottomContent?: ReactNode;
10
+ datesConfig?: DatesConfig[];
11
+ displayDateFormat?: string;
12
+ maxDate?: string;
13
+ minDate?: string;
7
14
  placeholder?: string;
8
15
  triggerElement?: ReactNode;
9
- minDate?: string;
10
- maxDate?: string;
16
+ /** @deprecated */
11
17
  unavailableDates?: Date[];
12
- bottomContent?: ReactNode;
13
18
  }
14
19
  export declare const DatePickerInput: React.ForwardRefExoticComponent<DatePickerInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -38,10 +38,10 @@ const icon_1 = require("../icon");
38
38
  exports.ALLOWED_DATE_FORMAT = ["D. M. YYYY", "DD. MM. YYYY", "D.M.YYYY", "DD.MM.YYYY"];
39
39
  exports.DISPLAY_DATE_FORMAT = "D. M. YYYY";
40
40
  exports.OUTPUT_DATE_FORMAT = "YYYY-MM-DD";
41
- function getValue(value) {
41
+ function getValue(value, format) {
42
42
  const parsedValue = (0, dayjs_1.default)(value, exports.OUTPUT_DATE_FORMAT, true);
43
43
  if (value && parsedValue.isValid()) {
44
- return parsedValue.format(exports.DISPLAY_DATE_FORMAT);
44
+ return parsedValue.format(format);
45
45
  }
46
46
  return value !== null && value !== void 0 ? value : "";
47
47
  }
@@ -60,26 +60,28 @@ function getBoundaryDate(value) {
60
60
  return undefined;
61
61
  }
62
62
  exports.DatePickerInput = (0, react_1.forwardRef)((props, ref) => {
63
- var _a, _b;
63
+ var _a, _b, _c, _d;
64
64
  const onChange = props.onChange;
65
65
  const className = (0, cx_1.cx)("uxf-date-picker-input", props.className);
66
+ const displayDateFormat = (_a = props.displayDateFormat) !== null && _a !== void 0 ? _a : exports.DISPLAY_DATE_FORMAT;
67
+ const allowedDateFormats = (_b = props.allowedDateFormats) !== null && _b !== void 0 ? _b : exports.ALLOWED_DATE_FORMAT;
66
68
  const onInputChange = (0, react_1.useCallback)((value) => {
67
- const parsedValue = (0, dayjs_1.default)(value, exports.ALLOWED_DATE_FORMAT, true);
69
+ const parsedValue = (0, dayjs_1.default)(value, allowedDateFormats, true);
68
70
  if (value !== "" && parsedValue.isValid()) {
69
71
  onChange(parsedValue.format(exports.OUTPUT_DATE_FORMAT));
70
72
  }
71
73
  else {
72
74
  onChange(value === "" ? null : value);
73
75
  }
74
- }, [onChange]);
76
+ }, [allowedDateFormats, onChange]);
75
77
  const onDatePickerChange = (0, react_1.useCallback)((value) => {
76
78
  const parsedValue = (0, dayjs_1.default)(value);
77
79
  onChange(value ? parsedValue.format(exports.OUTPUT_DATE_FORMAT) : null);
78
80
  }, [onChange]);
79
- const value = getValue(props.value);
81
+ const value = getValue(props.value, displayDateFormat);
80
82
  const selectedDate = getSelectedDate(props.value);
81
83
  const parsedMinDate = getBoundaryDate(props.minDate);
82
84
  const parsedMaxDate = getBoundaryDate(props.maxDate);
83
- return (react_1.default.createElement(_input_with_popover_1._InputWithPopover, { ...props, className: className, onChange: onInputChange, placeholder: (_a = props.placeholder) !== null && _a !== void 0 ? _a : (0, dayjs_1.default)().format(exports.DISPLAY_DATE_FORMAT), ref: ref, value: value, triggerElement: (_b = props.triggerElement) !== null && _b !== void 0 ? _b : react_1.default.createElement(icon_1.Icon, { name: "calendar", size: 20 }) }, ({ close }) => (react_1.default.createElement(date_picker_1.DatePicker, { minDate: parsedMinDate, maxDate: parsedMaxDate, closePopoverHandler: close, onChange: onDatePickerChange, preventScroll: true, selectedDate: selectedDate, unavailableDates: props.unavailableDates, bottomContent: props.bottomContent }))));
85
+ return (react_1.default.createElement(_input_with_popover_1._InputWithPopover, { ...props, className: className, onChange: onInputChange, placeholder: (_c = props.placeholder) !== null && _c !== void 0 ? _c : (0, dayjs_1.default)().format(displayDateFormat), ref: ref, value: value, triggerElement: (_d = props.triggerElement) !== null && _d !== void 0 ? _d : react_1.default.createElement(icon_1.Icon, { name: "calendar", size: 20 }) }, ({ close }) => (react_1.default.createElement(date_picker_1.DatePicker, { bottomContent: props.bottomContent, closePopoverHandler: close, datesConfig: props.datesConfig, maxDate: parsedMaxDate, minDate: parsedMinDate, onChange: onDatePickerChange, preventScroll: true, selectedDate: selectedDate, unavailableDates: props.unavailableDates }))));
84
86
  });
85
87
  exports.DatePickerInput.displayName = "UxfUiDatePickerInput";
@@ -41,7 +41,8 @@ function Default() {
41
41
  react_1.default.createElement(date_picker_input_1.DatePickerInput, { id: "date-test-disabled", isDisabled: true, label: "Datum disabled", name: "date-disabled", onChange: onChange, value: date }),
42
42
  react_1.default.createElement(date_picker_input_1.DatePickerInput, { id: "date-test-readonly", isReadOnly: true, label: "Datum readonly", name: "date-readonly", onChange: onChange, value: date }),
43
43
  react_1.default.createElement(date_picker_input_1.DatePickerInput, { id: "date-test-invalid", isClearable: true, isInvalid: true, label: "Datum invalid", name: "date-invalid", onChange: onChange, value: date }),
44
- react_1.default.createElement(date_picker_input_1.DatePickerInput, { id: "date-test-invalid", isClearable: true, minDate: "2023-06-06", maxDate: "2023-06-12", label: "Min/max", name: "date-invalid", onChange: onChange, placeholder: "", value: date })));
44
+ react_1.default.createElement(date_picker_input_1.DatePickerInput, { id: "date-test-invalid", isClearable: true, minDate: "2023-06-06", maxDate: "2023-06-12", label: "Min/max", name: "date-invalid", onChange: onChange, placeholder: "", value: date }),
45
+ react_1.default.createElement(date_picker_input_1.DatePickerInput, { allowedDateFormats: ["MM/DD/YYYY", "M/D/YYYY"], displayDateFormat: "MM/DD/YYYY", id: "date-custom-format", isClearable: true, label: "Datum s vlastn\u00EDm form\u00E1tem (US)", name: "date", onChange: onChange, value: date })));
45
46
  return (react_1.default.createElement(react_1.default.Fragment, null,
46
47
  react_1.default.createElement("div", { className: "light max-w-[640px] space-y-4 rounded bg-white p-8" }, testDatePickers),
47
48
  react_1.default.createElement("div", { className: "dark max-w-[640px] space-y-4 rounded bg-gray-900 p-8 text-white" }, testDatePickers)));
@@ -1,11 +1,14 @@
1
+ import { DatesConfig } from "@uxf/datepicker/utils/types";
1
2
  import { FC, PropsWithChildren, ReactNode } from "react";
2
3
  import { DateRangePickerValueType } from "./types";
3
4
  export interface DateRangePickerProps {
5
+ bottomContent?: ReactNode;
4
6
  closePopoverHandler: () => void;
7
+ datesConfig?: DatesConfig[];
5
8
  numberOfMonths?: number;
6
9
  onChange: (data: DateRangePickerValueType) => void;
7
10
  selectedDates: DateRangePickerValueType;
11
+ /** @deprecated */
8
12
  unavailableDates?: Date[];
9
- bottomContent?: ReactNode;
10
13
  }
11
14
  export declare const DateRangePicker: FC<PropsWithChildren<DateRangePickerProps>>;
@@ -36,6 +36,7 @@ const DateRangePicker = (props) => {
36
36
  setFocusedInput(data.endDate ? use_date_range_picker_1.START_DATE : data.focusedInput);
37
37
  }, [props]);
38
38
  const dateRangePickerProps = (0, use_date_range_picker_1.useDateRangePicker)({
39
+ datesConfig: props.datesConfig,
39
40
  endDate: ((_a = props.selectedDates) === null || _a === void 0 ? void 0 : _a.to) || null,
40
41
  firstDayOfWeek: 1,
41
42
  focusedInput: focusedInput,
@@ -1 +1,9 @@
1
- # DateRangePickerInput
1
+ # DateRangePickerInput
2
+
3
+ ## CSS dependencies
4
+
5
+ ```css
6
+ @import url("@uxf/ui/button/button.css");
7
+ @import url("@uxf/ui/calendar/calendar.css");
8
+ @import url("@uxf/ui/date-picker/date-picker.css");
9
+ ```
@@ -1,3 +1,4 @@
1
+ import { DatesConfig } from "@uxf/datepicker/utils/types";
1
2
  import React, { ReactNode } from "react";
2
3
  import { InputWithPopoverProps } from "../_input-with-popover";
3
4
  export declare const ALLOWED_DATE_FORMAT: string[];
@@ -8,10 +9,12 @@ export declare const splitValueToRange: (value: string | undefined | null) => {
8
9
  to: string | undefined;
9
10
  };
10
11
  export interface DateRangePickerInputProps extends Omit<InputWithPopoverProps<string | null>, "children" | "placeholder" | "triggerElement"> {
12
+ bottomContent?: ReactNode;
13
+ datesConfig?: DatesConfig[];
11
14
  numberOfMonths?: number;
12
15
  placeholder?: string;
13
16
  triggerElement?: ReactNode;
17
+ /** @deprecated */
14
18
  unavailableDates?: Date[];
15
- bottomContent?: ReactNode;
16
19
  }
17
20
  export declare const DateRangePickerInput: React.ForwardRefExoticComponent<DateRangePickerInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -57,6 +57,6 @@ exports.DateRangePickerInput = (0, react_1.forwardRef)((props, ref) => {
57
57
  const selectedDates = props.value
58
58
  ? { from: parsedFrom.isValid() ? parsedFrom.toDate() : null, to: parsedTo.isValid() ? parsedTo.toDate() : null }
59
59
  : null;
60
- return (react_1.default.createElement(_input_with_popover_1._InputWithPopover, { ...restProps, placeholder: props.placeholder || "Vyberte datum...", ref: ref, triggerElement: (_a = props.triggerElement) !== null && _a !== void 0 ? _a : react_1.default.createElement(icon_1.Icon, { name: "calendar", size: 20 }), value: (_b = props.value) !== null && _b !== void 0 ? _b : "" }, ({ close }) => (react_1.default.createElement(date_range_picker_1.DateRangePicker, { bottomContent: props.bottomContent, closePopoverHandler: close, numberOfMonths: numberOfMonths, onChange: onDatePickerChange, selectedDates: selectedDates, unavailableDates: props.unavailableDates }))));
60
+ return (react_1.default.createElement(_input_with_popover_1._InputWithPopover, { ...restProps, placeholder: props.placeholder || "Vyberte datum...", ref: ref, triggerElement: (_a = props.triggerElement) !== null && _a !== void 0 ? _a : react_1.default.createElement(icon_1.Icon, { name: "calendar", size: 20 }), value: (_b = props.value) !== null && _b !== void 0 ? _b : "" }, ({ close }) => (react_1.default.createElement(date_range_picker_1.DateRangePicker, { bottomContent: props.bottomContent, closePopoverHandler: close, datesConfig: props.datesConfig, numberOfMonths: numberOfMonths, onChange: onDatePickerChange, selectedDates: selectedDates, unavailableDates: props.unavailableDates }))));
61
61
  });
62
62
  exports.DateRangePickerInput.displayName = "UxfUiDatePickerInput";
@@ -4,6 +4,7 @@ import { IconName } from "../icon/types";
4
4
  import { Accept, DropzoneFile } from "./types";
5
5
  export interface DropzoneInputProps extends FormControlProps<DropzoneFile[] | undefined> {
6
6
  accept?: Accept;
7
+ className?: string;
7
8
  helperText?: ReactNode;
8
9
  icon?: IconName;
9
10
  id?: string;
@@ -51,7 +51,7 @@ function progressHandler(progressEvent, file, onValuesChange, values) {
51
51
  }
52
52
  }
53
53
  function fileUploadedHandler(uploadedFile, dropzoneFile, onValuesChange, values) {
54
- if (values) {
54
+ if (values && uploadedFile) {
55
55
  onValuesChange(values.map((f) => f.id === dropzoneFile.id ? { ...uploadedFile, progress: 100, originalFile: f.originalFile } : f));
56
56
  }
57
57
  }
@@ -63,9 +63,10 @@ function fileRejectedHandler(err, dropzoneFile, onValuesChange, values, onUpload
63
63
  }
64
64
  }
65
65
  exports.DropzoneInput = (0, react_1.forwardRef)((props, ref) => {
66
- var _a;
66
+ var _a, _b;
67
67
  const refValue = (0, react_1.useRef)();
68
68
  refValue.current = props.value;
69
+ const inputRef = (0, react_1.useRef)(null);
69
70
  const handleFileDrop = async (acceptedFiles) => {
70
71
  const files = acceptedFiles.map((file) => ({
71
72
  ...fileToFileResponse(file),
@@ -77,6 +78,11 @@ exports.DropzoneInput = (0, react_1.forwardRef)((props, ref) => {
77
78
  const onChange = (values) => {
78
79
  props.onChange(values);
79
80
  refValue.current = values;
81
+ // this ensures that the input is cleared after the upload, so there is no problem with uploading the same file again
82
+ const inputNode = inputRef.current;
83
+ if (inputNode) {
84
+ inputNode.value = "";
85
+ }
80
86
  };
81
87
  for (const file of files) {
82
88
  if (!file.originalFile) {
@@ -107,19 +113,19 @@ exports.DropzoneInput = (0, react_1.forwardRef)((props, ref) => {
107
113
  const labelOnCLick = (e) => {
108
114
  e.stopPropagation();
109
115
  };
110
- return (react_1.default.createElement("div", { className: "uxf-dropzone" },
116
+ return (react_1.default.createElement("div", { className: `uxf-dropzone ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}` },
111
117
  react_1.default.createElement("label", { ...getRootProps({
112
118
  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"),
113
119
  onClick: labelOnCLick,
114
120
  }), ref: (0, composeRefs_1.composeRefs)(ref, rootRef) },
115
- react_1.default.createElement(icon_1.Icon, { className: "uxf-dropzone__label__icon", name: (_a = props.icon) !== null && _a !== void 0 ? _a : "cloud" }),
121
+ react_1.default.createElement(icon_1.Icon, { className: "uxf-dropzone__label__icon", name: (_b = props.icon) !== null && _b !== void 0 ? _b : "cloud" }),
116
122
  typeof props.label === "string" ? react_1.default.createElement("span", null, props.label) : props.label,
117
123
  react_1.default.createElement("input", { ...getInputProps({
118
124
  className: "uxf-dropzone__input",
119
125
  id: props.id,
120
126
  name: props.name,
121
127
  type: "file",
122
- }) })),
128
+ }), ref: inputRef })),
123
129
  props.helperText && (react_1.default.createElement("div", { className: (0, cx_1.cx)("uxf-helper-text", props.isInvalid && classes_1.CLASSES.IS_INVALID) }, props.helperText))));
124
130
  });
125
131
  exports.DropzoneInput.displayName = "UxfUiDropzoneInput";
@@ -2,6 +2,7 @@ import { FormControlProps } from "@uxf/ui/types";
2
2
  import { FC, ReactNode } from "react";
3
3
  import { DropzoneFile } from "./types";
4
4
  export interface DropzoneListProps extends FormControlProps<DropzoneFile[] | undefined> {
5
+ className?: string;
5
6
  errorText?: string;
6
7
  onAbortWarning?: string;
7
8
  onRemoveWarning?: string;
@@ -40,7 +40,7 @@ function formatBytes(bytes, decimals = 2) {
40
40
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
41
41
  }
42
42
  const DropzoneList = (props) => {
43
- var _a, _b;
43
+ var _a, _b, _c;
44
44
  const context = (0, react_1.useContext)(context_1.UiContext);
45
45
  const onRemove = (file, isUploading) => () => {
46
46
  var _a;
@@ -58,7 +58,7 @@ const DropzoneList = (props) => {
58
58
  if (((_a = props.value) === null || _a === void 0 ? void 0 : _a.length) === 0) {
59
59
  return null;
60
60
  }
61
- return (react_1.default.createElement("ul", { className: "uxf-dropzone-list" }, (_b = props.value) === null || _b === void 0 ? void 0 : _b.map((file) => {
61
+ return (react_1.default.createElement("ul", { className: `uxf-dropzone-list ${(_b = props.className) !== null && _b !== void 0 ? _b : ""}` }, (_c = props.value) === null || _c === void 0 ? void 0 : _c.map((file) => {
62
62
  var _a, _b, _c;
63
63
  const isUploading = file.id < 0 && !file.error;
64
64
  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 },
@@ -5,11 +5,11 @@ import { FileInputBaseProps } from "../_file-input-base";
5
5
  export interface FileInputProps extends FileInputBaseProps, Clearable {
6
6
  className?: string;
7
7
  helperText?: ReactNode;
8
- label?: ReactNode;
9
8
  hiddenLabel?: boolean;
9
+ label?: ReactNode;
10
10
  placeholder?: string;
11
- uploadButtonLabel?: string;
12
11
  size?: keyof InputGroupSizes;
12
+ uploadButtonLabel?: string;
13
13
  variant?: keyof InputGroupVariants;
14
14
  }
15
15
  export declare const FileInput: React.ForwardRefExoticComponent<FileInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.FileInput = void 0;
27
27
  const classes_1 = require("@uxf/core/constants/classes");
28
28
  const useInputFocus_1 = require("@uxf/core/hooks/useInputFocus");
29
+ const composeRefs_1 = require("@uxf/core/utils/composeRefs");
29
30
  const cx_1 = require("@uxf/core/utils/cx");
30
31
  const context_1 = require("@uxf/ui/context");
31
32
  const input_1 = require("@uxf/ui/input");
@@ -51,13 +52,21 @@ exports.FileInput = (0, react_1.forwardRef)((props, ref) => {
51
52
  setIsUploading(false);
52
53
  return response;
53
54
  };
55
+ const onChange = (value, event) => {
56
+ const inputNode = innerRef.current;
57
+ // this ensures that the input is cleared after the upload, so there is no problem with uploading the same file again
58
+ if (!value && inputNode) {
59
+ inputNode.value = "";
60
+ }
61
+ props.onChange(value, event);
62
+ };
54
63
  return (react_1.default.createElement(form_component_1.FormComponent, { className: (0, cx_1.cx)(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), errorId: errorId, form: props.form, helperText: props.helperText, inputId: id, isRequired: props.isRequired, label: props.label, hiddenLabel: props.hiddenLabel },
55
64
  react_1.default.createElement(react_1.default.Fragment, null,
56
- react_1.default.createElement(_file_input_base_1._FileInputBase, { accept: props.accept, "aria-describedby": errorId, "aria-invalid": props.isInvalid, className: `uxf-file-input__input ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, form: props.form, id: id, isDisabled: props.isDisabled || isUploading, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, name: props.name, onBlur: input.onBlur, onChange: props.onChange, onFocus: input.onFocus, onUploadError: props.onUploadError, onUploadFile: onUploadFile, ref: ref, value: props.value }),
65
+ react_1.default.createElement(_file_input_base_1._FileInputBase, { accept: props.accept, "aria-describedby": errorId, "aria-invalid": props.isInvalid, className: `uxf-file-input__input ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, form: props.form, id: id, isDisabled: props.isDisabled || isUploading, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, isRequired: props.isRequired, maxFileSize: props.maxFileSize, name: props.name, onBlur: input.onBlur, onChange: onChange, onFocus: input.onFocus, onUploadError: props.onUploadError, onUploadFile: onUploadFile, ref: (0, composeRefs_1.composeRefs)(ref, innerRef), value: props.value }),
57
66
  react_1.default.createElement("label", { className: (0, cx_1.cx)("uxf-input", "uxf-file-input__label", input.focused && classes_1.CLASSES.IS_FOCUSED, (props.isDisabled || props.isReadOnly) && classes_1.CLASSES.IS_DISABLED, props.isInvalid && classes_1.CLASSES.IS_INVALID, isUploading && classes_1.CLASSES.IS_LOADING, isUploading && "uxf-file-input__label--has-right-addon", `uxf-input--size-${(_b = props.size) !== null && _b !== void 0 ? _b : "default"}`, `uxf-input--variant-${(_c = props.variant) !== null && _c !== void 0 ? _c : "default"}`), htmlFor: id },
58
67
  react_1.default.createElement("div", { className: "uxf-input__left-addon uxf-file-input__label__button" }, !isUploading ? ((_d = props.uploadButtonLabel) !== null && _d !== void 0 ? _d : "Vyberte soubor") : (react_1.default.createElement(loader_1.Loader, { className: "uxf-file-input__label__loader", size: "sm" }))),
59
68
  react_1.default.createElement("div", { className: "uxf-file-input__label__wrapper" },
60
69
  (context === null || context === void 0 ? void 0 : context.domain) && props.value ? (react_1.default.createElement("a", { className: "uxf-file-input__label__wrapper__file-name-link", href: (0, get_file_url_1.getFileUrl)(context.domain, props.value), target: "_blank", rel: "noreferrer noopenner" }, fileName)) : (react_1.default.createElement("span", { className: "uxf-file-input__label__wrapper__file-name" }, fileName)),
61
- props.value && !props.isDisabled && !props.isReadOnly && props.isClearable && (react_1.default.createElement(input_1.Input.RemoveButton, { onChange: props.onChange })))))));
70
+ props.value && !props.isDisabled && !props.isReadOnly && props.isClearable && (react_1.default.createElement(input_1.Input.RemoveButton, { onChange: onChange })))))));
62
71
  });
63
72
  exports.FileInput.displayName = "UxfUiFileInput";
@@ -0,0 +1,8 @@
1
+ # Image Gallery
2
+
3
+ ## CSS dependencies
4
+
5
+ ```css
6
+ @import url("@uxf/ui/icon/icon.css");
7
+ @import url("@uxf/ui/image-gallery/image-gallery.css");
8
+ ```