@aristobyte-ui/dropdown 2.12.0 → 2.13.1

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.
@@ -8,18 +8,43 @@
8
8
  }
9
9
 
10
10
  &__box {
11
- @mixin dropdown-variant($name, $color) {
12
- &-variant--#{$name} &-options {
11
+ @mixin dropdown-surface($name, $color) {
12
+ &.dropdown__box-variant--#{$name}.dropdown__box-appearance--solid &-options {
13
13
  background-color: $color;
14
+ border: 1px solid $color;
15
+ }
16
+
17
+ &.dropdown__box-variant--#{$name}.dropdown__box-appearance--outline &-options {
18
+ background-color: rgba($color, 0.5);
19
+ border: 1px solid $color;
20
+ }
21
+
22
+ &.dropdown__box-variant--#{$name}.dropdown__box-appearance--outline-dashed &-options {
23
+ background-color: rgba($color, 0.5);
24
+ border: 1px dashed $color;
25
+ }
26
+
27
+ &.dropdown__box-variant--#{$name}.dropdown__box-appearance--no-outline &-options {
28
+ background-color: rgba($color, 0.5);
29
+ border: 1px solid transparent;
30
+ }
31
+
32
+ &.dropdown__box-variant--#{$name}.dropdown__box-appearance--glowing &-options {
33
+ background-color: rgba($color, 0.5);
34
+ border: 1px solid $color;
35
+ box-shadow:
36
+ 0 0 8px rgba($color, 0.5),
37
+ 0 0 16px rgba($color, 0.4),
38
+ 0 0 24px rgba($color, 0.3);
14
39
  }
15
40
  }
16
41
 
17
- @include dropdown-variant('default', $color-default);
18
- @include dropdown-variant('primary', $color-primary);
19
- @include dropdown-variant('secondary', $color-secondary);
20
- @include dropdown-variant('warning', $color-warning);
21
- @include dropdown-variant('error', $color-error);
22
- @include dropdown-variant('success', $color-success);
42
+ @include dropdown-surface('default', $color-default);
43
+ @include dropdown-surface('primary', $color-primary);
44
+ @include dropdown-surface('secondary', $color-secondary);
45
+ @include dropdown-surface('warning', $color-warning);
46
+ @include dropdown-surface('error', $color-error);
47
+ @include dropdown-surface('success', $color-success);
23
48
 
24
49
  &-overlay {
25
50
  backdrop-filter: blur(12px);
@@ -9,7 +9,6 @@ export interface IDropdown {
9
9
  variant?: 'default' | 'primary' | 'secondary' | 'success' | 'error' | 'warning';
10
10
  appearance?: 'solid' | 'outline' | 'outline-dashed' | 'no-outline' | 'glowing';
11
11
  onChange?: (newValue: string) => void;
12
- initiallyOpened?: boolean;
13
12
  choice?: 'multiple' | 'single';
14
13
  placeholder?: string;
15
14
  disabled?: boolean;
@@ -78,30 +78,33 @@ var button_1 = require("@aristobyte-ui/button");
78
78
  var utils_1 = require("@aristobyte-ui/utils");
79
79
  require("./Dropdown.scss");
80
80
  var Dropdown = function (_a) {
81
- var children = _a.children, value = _a.value, onChange = _a.onChange, _b = _a.appearance, appearance = _b === void 0 ? 'outline' : _b, _c = _a.variant, variant = _c === void 0 ? 'default' : _c, _d = _a.placeholder, placeholder = _d === void 0 ? 'Select' : _d, _e = _a.choice, choice = _e === void 0 ? 'single' : _e, _f = _a.className, className = _f === void 0 ? '' : _f, _g = _a.initiallyOpened, initiallyOpened = _g === void 0 ? false : _g, _h = _a.disabled, disabled = _h === void 0 ? false : _h, _j = _a.button, button = _j === void 0 ? {} : _j, _k = _a.style, style = _k === void 0 ? {} : _k;
82
- var _l = __read(React.useState(initiallyOpened), 2), isOpened = _l[0], setIsOpened = _l[1];
83
- var _m = __read(React.useState(value ? [value] : []), 2), selected = _m[0], setSelected = _m[1];
84
- var _o = __read(React.useState({
81
+ var children = _a.children, value = _a.value, onChange = _a.onChange, _b = _a.appearance, appearance = _b === void 0 ? 'outline' : _b, _c = _a.variant, variant = _c === void 0 ? 'default' : _c, _d = _a.placeholder, placeholder = _d === void 0 ? 'Select' : _d, _e = _a.choice, choice = _e === void 0 ? 'single' : _e, _f = _a.className, className = _f === void 0 ? '' : _f, _g = _a.disabled, disabled = _g === void 0 ? false : _g, _h = _a.button, button = _h === void 0 ? {} : _h, _j = _a.style, style = _j === void 0 ? {} : _j;
82
+ var _k = __read(React.useState(false), 2), isOpened = _k[0], setIsOpened = _k[1];
83
+ var _l = __read(React.useState(value ? [value] : []), 2), selected = _l[0], setSelected = _l[1];
84
+ var _m = __read(React.useState({
85
85
  top: 0,
86
86
  left: 0,
87
87
  width: 0,
88
- }), 2), position = _o[0], setPosition = _o[1];
89
- var _p = __read(React.useState(0), 2), dropdownHeight = _p[0], setDropdownHeight = _p[1];
90
- var _q = __read(React.useState(0), 2), buttonHeight = _q[0], setButtonHeight = _q[1];
91
- var buttonRef = React.useRef(null);
88
+ }), 2), position = _m[0], setPosition = _m[1];
89
+ var buttonContainerRef = React.useRef(null);
92
90
  var boxRef = React.useRef(null);
93
91
  var uniqueId = React.useId();
94
- React.useLayoutEffect(function () {
95
- if (!isOpened) {
92
+ var computePosition = React.useCallback(function () {
93
+ if (!buttonContainerRef.current || !boxRef.current)
96
94
  return;
97
- }
98
- if (boxRef.current) {
99
- setDropdownHeight(boxRef.current.getBoundingClientRect().height);
100
- }
101
- if (buttonRef.current) {
102
- setButtonHeight(buttonRef.current.getBoundingClientRect().height);
103
- }
104
- }, [isOpened]);
95
+ var rect = buttonContainerRef.current.getBoundingClientRect();
96
+ var dropdownRect = boxRef.current.getBoundingClientRect();
97
+ var spaceBelow = window.innerHeight - rect.bottom;
98
+ var spaceAbove = rect.top;
99
+ var shouldOpenUpwards = spaceBelow < dropdownRect.height && spaceAbove > dropdownRect.height;
100
+ setPosition({
101
+ top: shouldOpenUpwards
102
+ ? rect.top + window.scrollY - dropdownRect.height - rect.height / 2
103
+ : rect.top + window.scrollY + rect.height + 6,
104
+ left: rect.left + window.scrollX,
105
+ width: rect.width,
106
+ });
107
+ }, []);
105
108
  var options = React.Children.toArray(children).filter(function (child) {
106
109
  return React.isValidElement(child) && child.type === DropdownOption_1.DropdownOption;
107
110
  });
@@ -128,35 +131,35 @@ var Dropdown = function (_a) {
128
131
  }
129
132
  };
130
133
  var handleToggle = function (e) {
131
- var _a;
132
134
  if (disabled)
133
135
  return;
134
- var rect = (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
135
- if (!rect)
136
- return;
137
- var spaceBelow = window.innerHeight - rect.bottom;
138
- var spaceAbove = rect.top;
139
- var shouldOpenUpwards = dropdownHeight > 0 && spaceBelow < dropdownHeight && spaceAbove > dropdownHeight;
140
- var finalPosition = {
141
- top: shouldOpenUpwards
142
- ? rect.top + window.scrollY - dropdownHeight - buttonHeight / 2
143
- : rect.top + window.scrollY + buttonHeight + 6,
144
- left: rect.left + window.scrollX,
145
- width: rect.width,
146
- };
147
- setPosition(finalPosition);
148
136
  if (button === null || button === void 0 ? void 0 : button.onClick)
149
137
  button.onClick(e);
150
138
  setIsOpened(function (prev) { return !prev; });
151
139
  };
140
+ React.useLayoutEffect(function () {
141
+ if (!isOpened)
142
+ return;
143
+ var raf = requestAnimationFrame(function () {
144
+ computePosition();
145
+ });
146
+ var handleResize = function () { return computePosition(); };
147
+ window.addEventListener('resize', handleResize);
148
+ window.addEventListener('scroll', handleResize, true);
149
+ return function () {
150
+ cancelAnimationFrame(raf);
151
+ window.removeEventListener('resize', handleResize);
152
+ window.removeEventListener('scroll', handleResize, true);
153
+ };
154
+ }, [isOpened, computePosition, options.length]);
152
155
  if (!isValidValue()) {
153
156
  throw new Error('The "value" prop did not match with any of the DropdownOption "value" prop');
154
157
  }
155
158
  return (React.createElement(React.Fragment, null,
156
- React.createElement("div", { className: "dropdown ".concat(className) },
157
- React.createElement(button_1.Button, { onClick: handleToggle, className: "dropdown__button ".concat((button === null || button === void 0 ? void 0 : button.className) || ''), appearance: (button === null || button === void 0 ? void 0 : button.appearance) || appearance, variant: (button === null || button === void 0 ? void 0 : button.variant) || variant, disabled: (button === null || button === void 0 ? void 0 : button.disabled) || disabled, ref: buttonRef }, placeholder)),
159
+ React.createElement("div", { className: "dropdown ".concat(className), ref: buttonContainerRef },
160
+ React.createElement(button_1.Button, { onClick: handleToggle, className: "dropdown__button ".concat((button === null || button === void 0 ? void 0 : button.className) || ''), appearance: (button === null || button === void 0 ? void 0 : button.appearance) || appearance, variant: (button === null || button === void 0 ? void 0 : button.variant) || variant, disabled: (button === null || button === void 0 ? void 0 : button.disabled) || disabled }, placeholder)),
158
161
  React.createElement(utils_1.Portal, null,
159
- React.createElement(framer_motion_1.AnimatePresence, null, isOpened && (React.createElement("div", { className: "dropdown__box ".concat("dropdown__box-variant--".concat(variant)), style: style },
162
+ React.createElement(framer_motion_1.AnimatePresence, null, isOpened && (React.createElement("div", { className: "dropdown__box dropdown__box-variant--".concat(variant, " dropdown__box-appearance--").concat(appearance), style: style },
160
163
  React.createElement(framer_motion_1.motion.div, { className: "dropdown__box-overlay", initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.3, ease: 'easeIn' }, onClick: function () { return setIsOpened(false); } }),
161
164
  React.createElement(framer_motion_1.motion.div, { ref: boxRef, className: "dropdown__box-options", initial: { opacity: 0, y: 20, scale: 0.95 }, animate: { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: 20, scale: 0.95 }, transition: { duration: 0.2, ease: 'easeIn' }, style: {
162
165
  top: position.top,
@@ -2,7 +2,7 @@
2
2
 
3
3
  .dropdown-option {
4
4
  align-items: center;
5
- border-radius: 8px; // TODO: change to dynamic
5
+ border-radius: 8px; //TODO: change to dynamic
6
6
  color: $white;
7
7
  display: flex;
8
8
  font-size: 14px;
@@ -13,18 +13,31 @@
13
13
  transition: all 120ms ease-out;
14
14
  width: 100%;
15
15
 
16
- @mixin dropdown-option-variant($name, $hover-color) {
17
- &-variant--#{$name}:hover {
18
- background-color: $hover-color;
16
+ &-variant {
17
+ &--default:hover {
18
+ background-color: $color-default-hover;
19
+ }
20
+
21
+ &--primary:hover {
22
+ background-color: $color-primary-hover;
19
23
  }
20
- }
21
24
 
22
- @include dropdown-option-variant('default', $color-default-hover);
23
- @include dropdown-option-variant('primary', $color-primary-hover);
24
- @include dropdown-option-variant('secondary', $color-secondary-hover);
25
- @include dropdown-option-variant('warning', $color-warning-hover);
26
- @include dropdown-option-variant('error', $color-error-hover);
27
- @include dropdown-option-variant('success', $color-success-hover);
25
+ &--secondary:hover {
26
+ background-color: $color-secondary-hover;
27
+ }
28
+
29
+ &--warning:hover {
30
+ background-color: $color-warning-hover;
31
+ }
32
+
33
+ &--error:hover {
34
+ background-color: $color-error-hover;
35
+ }
36
+
37
+ &--success:hover {
38
+ background-color: $color-success-hover;
39
+ }
40
+ }
28
41
 
29
42
  &--disabled,
30
43
  &--disabled:hover {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aristobyte-ui/dropdown",
3
3
  "description": "react dropdown component with trigger button, dropdownoptions, placement variants, fully typed typescript support, and composable integration with aristobyte ui button",
4
- "version": "2.12.0",
4
+ "version": "2.13.1",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "author": "AristoByte <info@aristobyte.com>",
@@ -52,8 +52,8 @@
52
52
  "sass": "^1.97.3"
53
53
  },
54
54
  "dependencies": {
55
- "@aristobyte-ui/button": "^2.12.0",
56
- "@aristobyte-ui/utils": "^2.12.0"
55
+ "@aristobyte-ui/button": "^2.13.1",
56
+ "@aristobyte-ui/utils": "^2.13.1"
57
57
  },
58
58
  "exports": {
59
59
  ".": {