intelicoreact 0.0.66 → 0.0.74

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 (82) hide show
  1. package/dist/Atomic/FormElements/CheckboxInput/CheckboxInput.js +6 -2
  2. package/dist/Atomic/FormElements/CheckboxInput/CheckboxInput.scss +91 -60
  3. package/dist/Atomic/FormElements/CheckboxInput/CheckboxInput.stories.js +2 -1
  4. package/dist/Atomic/FormElements/Dropdown/Dropdown.js +48 -17
  5. package/dist/Atomic/FormElements/Dropdown/Dropdown.scss +21 -3
  6. package/dist/Atomic/FormElements/Dropdown/Dropdown.stories.js +22 -6
  7. package/dist/Atomic/FormElements/InputDateRange/InputDateRange.js +24 -43
  8. package/dist/Atomic/FormElements/InputDateRange/InputDateRange.scss +98 -73
  9. package/dist/Atomic/FormElements/InputDateRange/InputDateRange.stories.js +3 -156
  10. package/dist/Atomic/FormElements/InputDateRange/components/Datepicker.js +11 -9
  11. package/dist/Atomic/FormElements/InputDateRange/components/SelectItem.js +3 -3
  12. package/dist/Atomic/FormElements/InputDateRange/dependencies.js +7 -7
  13. package/dist/Atomic/FormElements/Table/Table.scss +1 -1
  14. package/dist/Atomic/FormElements/Textarea/Textarea.scss +1 -1
  15. package/dist/Atomic/MainMenu/MainMenu.scss +2 -2
  16. package/dist/Atomic/UI/Accordion/Accordion.scss +2 -2
  17. package/dist/Atomic/UI/Arrow/Arrow.js +7 -8
  18. package/dist/Atomic/UI/Calendar/Calendar.js +3 -2
  19. package/dist/Atomic/UI/Calendar/Calendar.stories.js +3 -2
  20. package/dist/Atomic/UI/Status/Status.scss +1 -1
  21. package/dist/Molecular/Datepicker/Datepicker.js +451 -0
  22. package/dist/Molecular/Datepicker/Datepicker.scss +8 -0
  23. package/dist/Molecular/Datepicker/Datepicker.stories.js +44 -0
  24. package/dist/Molecular/Datepicker/components/Calendar.js +156 -0
  25. package/dist/scss/_vars.scss +3 -1
  26. package/dist/scss/main.scss +1 -1
  27. package/package.json +6 -4
  28. package/src/Atomic/FormElements/CheckboxInput/CheckboxInput.js +12 -2
  29. package/src/Atomic/FormElements/CheckboxInput/CheckboxInput.scss +91 -60
  30. package/src/Atomic/FormElements/CheckboxInput/CheckboxInput.stories.js +4 -3
  31. package/src/Atomic/FormElements/Dropdown/Dropdown.js +53 -19
  32. package/src/Atomic/FormElements/Dropdown/Dropdown.scss +21 -3
  33. package/src/Atomic/FormElements/Dropdown/Dropdown.stories.js +28 -15
  34. package/src/Atomic/FormElements/InputDateRange/InputDateRange.js +191 -213
  35. package/src/Atomic/FormElements/InputDateRange/InputDateRange.scss +98 -73
  36. package/src/Atomic/FormElements/InputDateRange/InputDateRange.stories.js +35 -123
  37. package/src/Atomic/FormElements/InputDateRange/components/Datepicker.js +10 -7
  38. package/src/Atomic/FormElements/InputDateRange/components/OpenedPart.js +2 -2
  39. package/src/Atomic/FormElements/InputDateRange/components/SelectItem.js +1 -1
  40. package/src/Atomic/FormElements/InputDateRange/dependencies.js +6 -6
  41. package/src/Atomic/FormElements/Table/Table.scss +1 -1
  42. package/src/Atomic/FormElements/Textarea/Textarea.scss +1 -1
  43. package/src/Atomic/MainMenu/MainMenu.scss +2 -2
  44. package/src/Atomic/UI/Accordion/Accordion.scss +2 -2
  45. package/src/Atomic/UI/Arrow/Arrow.js +5 -5
  46. package/src/Atomic/UI/Calendar/Calendar.js +2 -2
  47. package/src/Atomic/UI/Calendar/Calendar.stories.js +2 -1
  48. package/src/Atomic/UI/Status/Status.scss +1 -1
  49. package/src/Molecular/Datepicker/Datepicker.js +346 -0
  50. package/src/Molecular/Datepicker/Datepicker.scss +8 -0
  51. package/src/Molecular/Datepicker/Datepicker.stories.js +27 -0
  52. package/src/Molecular/Datepicker/components/Calendar.js +118 -0
  53. package/src/scss/_vars.scss +3 -1
  54. package/src/scss/main.scss +1 -1
  55. package/dist/scss/anme/_anme-bootstrap-grid.scss +0 -748
  56. package/dist/scss/anme/_anme-elements.scss +0 -269
  57. package/dist/scss/anme/_anme-grid.scss +0 -111
  58. package/dist/scss/anme/_anme-justify.scss +0 -111
  59. package/dist/scss/anme/_anme-mixins-media.scss +0 -116
  60. package/dist/scss/anme/_anme-mixins.scss +0 -166
  61. package/dist/scss/anme/_anme-normalize.scss +0 -8
  62. package/dist/scss/anme/_anme-overall.scss +0 -34
  63. package/dist/scss/anme/_anme-padding-margins.scss +0 -419
  64. package/dist/scss/anme/_anme-table.scss +0 -81
  65. package/dist/scss/anme/_anme-theme.scss +0 -275
  66. package/dist/scss/anme/_anme-vars.scss +0 -91
  67. package/dist/scss/anme/_code-styling.scss +0 -23
  68. package/dist/scss/anme/styles.scss +0 -12
  69. package/src/scss/anme/_anme-bootstrap-grid.scss +0 -748
  70. package/src/scss/anme/_anme-elements.scss +0 -269
  71. package/src/scss/anme/_anme-grid.scss +0 -111
  72. package/src/scss/anme/_anme-justify.scss +0 -111
  73. package/src/scss/anme/_anme-mixins-media.scss +0 -116
  74. package/src/scss/anme/_anme-mixins.scss +0 -166
  75. package/src/scss/anme/_anme-normalize.scss +0 -8
  76. package/src/scss/anme/_anme-overall.scss +0 -34
  77. package/src/scss/anme/_anme-padding-margins.scss +0 -419
  78. package/src/scss/anme/_anme-table.scss +0 -81
  79. package/src/scss/anme/_anme-theme.scss +0 -275
  80. package/src/scss/anme/_anme-vars.scss +0 -91
  81. package/src/scss/anme/_code-styling.scss +0 -23
  82. package/src/scss/anme/styles.scss +0 -12
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.default = void 0;
11
+
12
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
+
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
15
+
16
+ var _classnames = _interopRequireDefault(require("classnames"));
17
+
18
+ var _moment = _interopRequireDefault(require("moment"));
19
+
20
+ var _react = _interopRequireWildcard(require("react"));
21
+
22
+ var Icon = _interopRequireWildcard(require("react-feather"));
23
+
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
+
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
+
28
+ var Calendar = function Calendar(props) {
29
+ var date = props.date,
30
+ setDate = props.setDate,
31
+ startDate = props.startDate,
32
+ endDate = props.endDate,
33
+ _props$allowPrev = props.allowPrev,
34
+ allowPrev = _props$allowPrev === void 0 ? true : _props$allowPrev,
35
+ _props$allowNext = props.allowNext,
36
+ allowNext = _props$allowNext === void 0 ? true : _props$allowNext,
37
+ onClick = props.onClick,
38
+ onHover = props.onHover,
39
+ startPrevDate = props.startPrevDate,
40
+ endPrevDate = props.endPrevDate,
41
+ limitRange = props.limitRange;
42
+
43
+ var _useState = (0, _react.useState)({}),
44
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
45
+ days = _useState2[0],
46
+ setDays = _useState2[1];
47
+
48
+ var title = (0, _react.useMemo)(function () {
49
+ return "".concat((0, _moment.default)(date).format('MMM'), " ").concat((0, _moment.default)(date).format('YYYY'));
50
+ }, [date]);
51
+ (0, _react.useEffect)(function () {
52
+ var result = {};
53
+ var day = (0, _moment.default)(date).startOf('month');
54
+ var daysInMonth = day.daysInMonth();
55
+
56
+ for (var d = 0; d < daysInMonth; d += 1) {
57
+ var week = day.week();
58
+ if (day.month() === 11 && week === 1) week = 53;
59
+ if (day.month() === 0 && week === 53) week = 0;
60
+
61
+ if (!Object.prototype.hasOwnProperty.call(result, week)) {
62
+ result[week] = {};
63
+ }
64
+
65
+ result[week][day.weekday()] = {
66
+ date: day.toDate()
67
+ };
68
+ day.add(1, 'd');
69
+ }
70
+
71
+ setDays(result);
72
+ }, [date]);
73
+
74
+ var renderDay = function renderDay(week, dayOfWeek) {
75
+ var day = days[week][dayOfWeek];
76
+ var isFutureDay = day && (0, _moment.default)(day.date).isAfter((0, _moment.default)(), 'day');
77
+ var isPastDay = limitRange ? day && (0, _moment.default)(day.date).isBefore((0, _moment.default)().subtract(limitRange, 'days'), 'day') : null;
78
+ var isRangeEnd = day && ((0, _moment.default)(day.date).isSame(startDate, 'day') || (0, _moment.default)(day.date).isSame((0, _moment.default)(endDate).subtract(1, 'hour'), 'day'));
79
+ var isRangeInside = day && startDate && endDate && (0, _moment.default)(day.date).isAfter(startDate, 'day') && (0, _moment.default)(day.date).isBefore((0, _moment.default)(endDate).subtract(1, 'hour'), 'day');
80
+ var isPrevRangeEnd = day && ((0, _moment.default)(day.date).isSame(startPrevDate, 'day') || (0, _moment.default)(day.date).isSame((0, _moment.default)(endPrevDate).subtract(1, 'day'), 'day'));
81
+ var isPrevRangeInside = day && startPrevDate && endPrevDate && (0, _moment.default)(day.date).isAfter(startPrevDate, 'day') && (0, _moment.default)(day.date).isBefore((0, _moment.default)(endPrevDate).subtract(1, 'day'), 'day');
82
+ var classNames = (0, _classnames.default)('calendar__day', {
83
+ 'calendar__day--clickable': day
84
+ }, {
85
+ 'calendar__day--disabled': isFutureDay
86
+ }, {
87
+ 'calendar__day--disabled': isPastDay
88
+ }, {
89
+ 'calendar__day--range-end': isRangeEnd
90
+ }, {
91
+ 'calendar__day--range-inside': isRangeInside
92
+ }, {
93
+ 'calendar__day--prev-range-end': isPrevRangeEnd
94
+ }, {
95
+ 'calendar__day--prev-range-inside': isPrevRangeInside
96
+ });
97
+ return /*#__PURE__*/_react.default.createElement("div", {
98
+ key: "".concat(week, "_").concat(dayOfWeek),
99
+ className: classNames,
100
+ onClick: day && !isFutureDay ? function () {
101
+ return onClick(day.date);
102
+ } : null,
103
+ onMouseOver: day && !isFutureDay ? function () {
104
+ return onHover(day.date);
105
+ } : null,
106
+ onMouseLeave: function onMouseLeave() {
107
+ return onHover(null);
108
+ }
109
+ }, day && day.date.getDate());
110
+ };
111
+
112
+ var handlePrev = function handlePrev() {
113
+ setDate((0, _moment.default)(date).subtract(1, 'month').toDate());
114
+ };
115
+
116
+ var handleNext = function handleNext() {
117
+ setDate((0, _moment.default)(date).add(1, 'month').toDate());
118
+ };
119
+
120
+ return /*#__PURE__*/_react.default.createElement("div", {
121
+ className: "calendar"
122
+ }, /*#__PURE__*/_react.default.createElement("div", {
123
+ className: "calendar-header"
124
+ }, /*#__PURE__*/_react.default.createElement("div", {
125
+ className: "calendar-header__prev"
126
+ }, allowPrev && /*#__PURE__*/_react.default.createElement("div", {
127
+ onClick: handlePrev
128
+ }, /*#__PURE__*/_react.default.createElement(Icon.ChevronLeft, {
129
+ size: 16
130
+ }))), /*#__PURE__*/_react.default.createElement("div", {
131
+ className: "calendar-header__title"
132
+ }, title), /*#__PURE__*/_react.default.createElement("div", {
133
+ className: "calendar-header__next"
134
+ }, allowNext && /*#__PURE__*/_react.default.createElement("div", {
135
+ onClick: handleNext
136
+ }, /*#__PURE__*/_react.default.createElement(Icon.ChevronRight, {
137
+ size: 16
138
+ })))), /*#__PURE__*/_react.default.createElement("div", {
139
+ className: "calendar__week"
140
+ }, (0, _toConsumableArray2.default)(Array(7).keys()).map(function (dayOfWeek) {
141
+ return /*#__PURE__*/_react.default.createElement("div", {
142
+ key: "day-of-week_".concat(dayOfWeek),
143
+ className: "calendar__day calendar__day--title"
144
+ }, (0, _moment.default)().weekday(dayOfWeek).format('dd').charAt(0));
145
+ })), Object.keys(days).map(function (week, index) {
146
+ return /*#__PURE__*/_react.default.createElement("div", {
147
+ key: "week_".concat(index),
148
+ className: "calendar__week"
149
+ }, (0, _toConsumableArray2.default)(Array(7).keys()).map(function (dayOfWeek) {
150
+ return renderDay(week, dayOfWeek);
151
+ }));
152
+ }));
153
+ };
154
+
155
+ var _default = Calendar;
156
+ exports.default = _default;
@@ -1,4 +1,6 @@
1
1
  /* THEME COLORS*/
2
+ @use "sass:math";
3
+
2
4
  $color--secondary: #f06d8d;
3
5
  $color--primary: #6b81dd;
4
6
  $color--dark: #1e1e2d;
@@ -43,4 +45,4 @@ $h4-fs: 22px;
43
45
  $h4-lh: 1.18;
44
46
 
45
47
  $txt: 14px;
46
- $txt--lh: (20 / 14);
48
+ $txt--lh: math.div(20, 14);
@@ -1,5 +1,5 @@
1
1
  @import './fonts';
2
- @import './anme/styles.scss';
2
+ @import '~anme/scss/styles.scss';
3
3
 
4
4
  body {
5
5
  font-family: 'Roboto', sans-serif;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "intelicoreact",
3
- "version": "0.0.66",
4
- "description": "Inputmask fixes",
3
+ "version": "0.0.74",
4
+ "description": "Date range fixes and dropdown refactor",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -14,13 +14,15 @@
14
14
  "moment-timezone": "^0.5.34",
15
15
  "react": "^17.0.2",
16
16
  "react-feather": "^2.0.9",
17
- "react-input-mask": "^2.0.4"
17
+ "react-input-mask": "^2.0.4",
18
+ "classnames": "^2.3.1"
18
19
  },
19
20
  "devDependencies": {
20
21
  "@babel/cli": "^7.15.7",
21
22
  "@babel/core": "^7.15.5",
22
23
  "@babel/polyfill": "^7.12.1",
23
24
  "@babel/preset-env": "^7.15.6",
24
- "classnames": "^2.3.1"
25
+ "anme": "^1.0.0"
26
+
25
27
  }
26
28
  }
@@ -3,11 +3,21 @@ import cn from 'classnames';
3
3
 
4
4
  import './CheckboxInput.scss';
5
5
 
6
- const CheckboxInput = ({ label, id, value, onChange, disabled, className }) => {
6
+ const CheckboxInput = ({ label, id, value, onChange, disabled, className, isStark }) => {
7
7
  return (
8
8
  <label className={cn('checkbox-input', className, { [`checkbox-input_disabled`]: disabled })} htmlFor={id}>
9
9
  <div className={cn(`checkbox-input__input`, { [`checkbox-input__input_checked`]: value })}>
10
- <input id={id} type="checkbox" className="checkbox-input__checkbox" onChange={e => onChange(!value, e)} checked={value} disabled={disabled} />
10
+ <input
11
+ id={id}
12
+ type="checkbox"
13
+ className="checkbox-input__checkbox"
14
+ onChange={(e) => onChange(!value, e)}
15
+ checked={value}
16
+ disabled={disabled}
17
+ ref={(elem) => {
18
+ if (elem) elem.indeterminate = isStark;
19
+ }}
20
+ />
11
21
  <span className="checkbox-input__mark" />
12
22
  </div>
13
23
  {label && <div className="checkbox-input__label">{label}</div>}
@@ -1,76 +1,107 @@
1
1
  .checkbox-input {
2
- display: flex;
3
- align-items: center;
4
- cursor: pointer;
2
+ display: flex;
3
+ align-items: center;
4
+ cursor: pointer;
5
+
6
+ &_disabled {
7
+ opacity: 0.5;
8
+ pointer-events: none;
9
+ cursor: auto;
10
+ }
5
11
 
6
- &_disabled {
7
- opacity: .5;
8
- pointer-events: none;
9
- cursor: auto;
12
+ &:hover {
13
+ .checkbox-input__input {
14
+ background-color: rgba(#6b81dd, 0.2);
10
15
  }
16
+ }
17
+
18
+ &__input {
19
+ position: relative;
20
+ height: 14px;
21
+ width: 14px;
22
+ min-width: 14px;
23
+ border: 1px solid #9aa0b9;
24
+ border-radius: 2px;
25
+ overflow: hidden;
26
+ margin-right: 5px;
27
+ cursor: pointer;
28
+ transition: background-color 0.2s ease;
29
+ background-color: #ffff;
11
30
 
12
- &:hover {
13
- .checkbox-input__input {
14
- background-color: rgba(#6b81dd, .2);
15
- }
31
+ &_checked {
32
+ border-color: #6b81dd;
16
33
  }
17
34
 
18
- &__input {
19
- position: relative;
20
- height: 14px;
21
- width: 14px;
22
- min-width: 14px;
23
- border: 1px solid #9AA0B9;
24
- border-radius: 2px;
25
- overflow: hidden;
26
- margin-right: 5px;
27
- cursor: pointer;
28
- transition: background-color .2s ease;
29
- background-color: #ffff;
35
+ .checkbox-input__checkbox:checked ~ .checkbox-input__mark {
36
+ display: block;
37
+ }
38
+ }
30
39
 
31
- &_checked {
32
- border-color: #6b81dd;
33
- }
40
+ &__checkbox {
41
+ opacity: 0;
42
+ position: absolute;
43
+ height: 0;
44
+ width: 0;
45
+ }
34
46
 
35
- .checkbox-input__checkbox:checked ~ .checkbox-input__mark {
36
- display: block;
37
- }
47
+ &__mark {
48
+ display: none;
49
+ position: absolute;
50
+ width: 14px;
51
+ height: 14px;
52
+ background-color: #6b81dd;
38
53
 
54
+ &:after {
55
+ content: "";
56
+ position: absolute;
57
+ top: -2px;
58
+ bottom: 0;
59
+ left: 0;
60
+ right: 0;
61
+ margin: auto;
62
+ width: 4px;
63
+ height: 8px;
64
+ border: solid white;
65
+ border-radius: 2px;
66
+ border-width: 0 2px 2px 0;
67
+ transform: rotate(45deg);
39
68
  }
69
+ }
40
70
 
41
- &__checkbox {
42
- opacity: 0;
43
- position: absolute;
44
- height: 0;
45
- width: 0;
46
- }
71
+ &__label {
72
+ font-size: 13px;
73
+ user-select: none;
74
+ }
47
75
 
48
- &__mark {
49
- display: none;
76
+ input[type="checkbox" i] {
77
+ &:indeterminate {
78
+ display: block;
79
+ width: 100%;
80
+ height: 100%;
81
+ &:after {
82
+ content: "";
50
83
  position: absolute;
51
- width: 14px;
52
- height: 14px;
84
+ top: 0;
85
+ bottom: 0;
86
+ left: 0;
87
+ right: 0;
88
+ margin: auto;
89
+ width: 100%;
90
+ height: 100%;
53
91
  background-color: #6b81dd;
54
-
55
- &:after {
56
- content: '';
57
- position: absolute;
58
- top: -2px;
59
- bottom: 0;
60
- left: 0;
61
- right: 0;
62
- margin: auto;
63
- width: 4px;
64
- height: 8px;
65
- border: solid white;
66
- border-radius: 2px;
67
- border-width: 0 2px 2px 0;
68
- transform: rotate(45deg);
69
- }
70
- }
71
-
72
- &__label{
73
- font-size: 13px;
74
- user-select: none;
92
+ }
93
+ &:before {
94
+ content: "";
95
+ position: absolute;
96
+ top: 50%;
97
+ left: 50%;
98
+ transform: translate(-50%, -50%);
99
+ width: 65%;
100
+ border: solid white;
101
+ border-radius: 2px;
102
+ border-width: 0 2px 2px 0;
103
+ z-index: 1;
104
+ }
75
105
  }
106
+ }
76
107
  }
@@ -5,10 +5,10 @@ global.lng = 'en';
5
5
 
6
6
  export default {
7
7
  title: 'Form Elements/CheckboxInput',
8
- component: CheckboxInput
8
+ component: CheckboxInput,
9
9
  };
10
10
 
11
- const Template = args => {
11
+ const Template = (args) => {
12
12
  const { value: argsValue } = args;
13
13
  const [value, setValue] = useState(argsValue);
14
14
 
@@ -21,5 +21,6 @@ Checkbox.args = {
21
21
  label: 'Test label',
22
22
  value: true,
23
23
  disabled: false,
24
- forced: false
24
+ forced: false,
25
+ isStark: true,
25
26
  };
@@ -1,17 +1,16 @@
1
1
  import React, { useState, useRef, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
  import { Check, ChevronDown, ChevronUp } from 'react-feather';
4
- import Label from '../Label/Label';
5
4
 
6
5
  import './Dropdown.scss';
7
6
 
8
7
  const RC = 'dropdown';
9
8
 
10
- const Dropdown = ({ options, value, error, onChange, placeholder, className, isSearchable }) => {
9
+ const Dropdown = ({ options, value, error, onChange, placeholder, className, isSearchable, entity }) => {
11
10
  const [isOpen, setIsOpen] = useState(false);
12
11
  const [searchValue, setSearchValue] = useState('');
13
12
  const dropdownRef = useRef(null);
14
-
13
+ if (!options) return null;
15
14
  const filteredGroups = options
16
15
  .filter(item => item.items?.length)
17
16
  .map(item => ({ ...item, items: item.items.filter(el => el?.label?.toLowerCase().includes(searchValue?.toLowerCase() || '')) }))
@@ -23,6 +22,38 @@ const Dropdown = ({ options, value, error, onChange, placeholder, className, isS
23
22
 
24
23
  const filteredOptions = [...filteredItems, ...filteredGroups];
25
24
 
25
+ const modalBtnTrigger = entity && entity !== '' && typeof entity === 'string';
26
+ const onChangeHandler = item => {
27
+ setIsOpen(false);
28
+ setSearchValue(null);
29
+ onChange(item.value);
30
+ };
31
+ // decorator
32
+ const getDepends = getDependsTrigger => {
33
+ const newOnChange = e => {
34
+ if (e.value === 'open_modal') {
35
+ onChange('open_modal');
36
+ } else {
37
+ onChangeHandler(e);
38
+ }
39
+ };
40
+
41
+ // add pseudo option
42
+ const newOptions = [
43
+ {
44
+ label: `New ${entity}`,
45
+ value: 'open_modal',
46
+ className: 'dropdown__list-item--modal'
47
+ },
48
+ ...filteredOptions
49
+ ];
50
+
51
+ return {
52
+ onChange: changeItem => (getDependsTrigger ? newOnChange(changeItem) : onChangeHandler(changeItem)),
53
+ options: getDependsTrigger ? newOptions : options
54
+ };
55
+ };
56
+
26
57
  const handleClickOutside = event => {
27
58
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
28
59
  setIsOpen(false);
@@ -30,12 +61,6 @@ const Dropdown = ({ options, value, error, onChange, placeholder, className, isS
30
61
  }
31
62
  };
32
63
 
33
- const onChangeHandler = item => {
34
- setIsOpen(false);
35
- setSearchValue(null);
36
- onChange(item.value);
37
- };
38
-
39
64
  const onSearchHandler = name => {
40
65
  setSearchValue(name);
41
66
  };
@@ -43,11 +68,13 @@ const Dropdown = ({ options, value, error, onChange, placeholder, className, isS
43
68
  const hightlightedText = text =>
44
69
  searchValue ? text?.replace(new RegExp(searchValue, 'i'), match => `<span class="bg--yellow">${match}</span>`) : text;
45
70
 
71
+ const depend = getDepends(modalBtnTrigger);
72
+
46
73
  const getMarkupForElement = item =>
47
74
  item.label.toLowerCase().includes(searchValue?.toLowerCase() || '') ? (
48
75
  <button
49
76
  key={item.value}
50
- onClick={() => onChangeHandler(item)}
77
+ onClick={() => depend.onChange(item)}
51
78
  className={cn(`${RC}__list-item`, { [`${RC}__list-item_active`]: item.value === value }, { [`${RC}__list-item_disabled`]: item.disabled })}
52
79
  >
53
80
  <span className={cn(`${RC}__active-icon`, { [`${RC}__active-icon_active`]: item.value === value })}>
@@ -58,9 +85,10 @@ const Dropdown = ({ options, value, error, onChange, placeholder, className, isS
58
85
  ) : null;
59
86
 
60
87
  useEffect(() => {
88
+ if (!value) setSearchValue(null);
61
89
  document.addEventListener('click', handleClickOutside, true);
62
90
  return () => document.removeEventListener('click', handleClickOutside, true);
63
- });
91
+ }, [value]);
64
92
 
65
93
  const filteredOptionList = filteredOption =>
66
94
  filteredOption.items?.length > 0 ? (
@@ -75,19 +103,25 @@ const Dropdown = ({ options, value, error, onChange, placeholder, className, isS
75
103
 
76
104
  return (
77
105
  <div className={cn(RC, className)} ref={dropdownRef}>
78
- <button className={`${RC}__trigger input__wrap ${!value ? 'placeholder' : ''} ${error ? 'error' : ''}`} onClick={() => !isSearchable ? setIsOpen(!isOpen) : null}>
106
+ <button
107
+ className={`${RC}__trigger input__wrap ${!value ? 'placeholder' : ''} ${error ? 'error' : ''}`}
108
+ onClick={() => (!isSearchable ? setIsOpen(!isOpen) : null)}
109
+ >
79
110
  {isSearchable ? (
80
111
  <input
81
112
  className={`${RC}__input`}
82
- value={searchValue ?? selectedLabel}
83
- onChange={e => onSearchHandler(e.target.value)}
113
+ value={searchValue || filteredOptions.find(el => el.value === value)?.label || ''}
114
+ onChange={e => {
115
+ onSearchHandler(e.target.value);
116
+ }}
84
117
  placeholder={placeholder}
85
- onFocus={() => setIsOpen(true)}
118
+ onFocus={e => {
119
+ e.target.select();
120
+ setIsOpen(true);
121
+ }}
86
122
  />
87
123
  ) : (
88
- <span className="text">
89
- {selectedLabel || placeholder}
90
- </span>
124
+ <span className="text">{selectedLabel || placeholder}</span>
91
125
  )}
92
126
  <span className={cn(`${RC}__arrow`, { [`${RC}__arrow_active`]: isOpen })} onClick={() => setIsOpen(!isOpen)}>
93
127
  {isOpen ? <ChevronUp /> : <ChevronDown />}
@@ -95,7 +129,7 @@ const Dropdown = ({ options, value, error, onChange, placeholder, className, isS
95
129
  </button>
96
130
  {isOpen && filteredOptions.length > 0 && (
97
131
  <div className={`${RC}__list`}>
98
- {filteredOptions.map(filteredOption =>
132
+ {depend.options.map(filteredOption =>
99
133
  filteredOption.items?.length ? filteredOptionList(filteredOption) : getMarkupForElement(filteredOption)
100
134
  )}
101
135
  </div>
@@ -5,6 +5,7 @@
5
5
  flex-direction: column;
6
6
  position: relative;
7
7
  width: 100%;
8
+ border-radius: 7px;
8
9
 
9
10
  &__trigger {
10
11
  background: #ffffff;
@@ -28,8 +29,8 @@
28
29
  &.error {
29
30
  border-color: $color--secondary;
30
31
  }
31
- &.placeholder .text{
32
- opacity: .7;
32
+ &.placeholder .text {
33
+ opacity: 0.7;
33
34
  }
34
35
  }
35
36
 
@@ -85,7 +86,24 @@
85
86
  width: 100%;
86
87
  height: 24px;
87
88
  white-space: nowrap;
88
-
89
+ overflow-x: hidden;
90
+
91
+ &--modal {
92
+ color: #1f7499;
93
+ font-size: 14px;
94
+ line-height: 20px;
95
+ letter-spacing: 0.2px;
96
+ position: relative;
97
+ &:after {
98
+ content: "";
99
+ position: absolute;
100
+ bottom: -2px;
101
+ height: 1px;
102
+ width: 300%;
103
+ transform: translateX(-50%);
104
+ background-color: #e8e9ec;
105
+ }
106
+ }
89
107
  &:hover,
90
108
  &_active {
91
109
  background: $color--gray--gentle;