@aristobyte-ui/dropdown 1.0.112 → 2.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.
@@ -0,0 +1,64 @@
1
+ @use '@aristobyte-ui/utils/aristobyte-ui.settings' as *;
2
+
3
+ .dropdown {
4
+ width: max-content;
5
+
6
+ &__button {
7
+ width: max-content;
8
+ }
9
+
10
+ &__box {
11
+ &-variant--default &-options {
12
+ background-color: $color-default;
13
+ }
14
+
15
+ &-variant--primary &-options {
16
+ background-color: $color-primary;
17
+ }
18
+
19
+ &-variant--secondary &-options {
20
+ background-color: $color-secondary;
21
+ }
22
+
23
+ &-variant--warning &-options {
24
+ background-color: $color-warning;
25
+ }
26
+
27
+ &-variant--error &-options {
28
+ background-color: $color-error;
29
+ }
30
+
31
+ &-variant--success &-options {
32
+ background-color: $color-success;
33
+ }
34
+
35
+ &-overlay {
36
+ backdrop-filter: blur(12px);
37
+ height: 100%;
38
+ left: 0;
39
+ position: fixed;
40
+ top: 0;
41
+ width: 100%;
42
+ z-index: 99999999999;
43
+ }
44
+
45
+ &-options {
46
+ align-items: flex-start;
47
+ border-radius: 8px; //TODO: change to dynamic
48
+ box-shadow:
49
+ 0 4px 6px rgba(0, 0, 0, 0.04),
50
+ 0 12px 24px rgba(0, 0, 0, 0.1);
51
+ display: flex;
52
+ flex-direction: column;
53
+ opacity: 1;
54
+ min-width: 300px;
55
+ padding: 4px;
56
+ position: absolute;
57
+ transition:
58
+ transform 200ms $cubic-bezier-secondary,
59
+ opacity 150ms ease;
60
+ width: 100%;
61
+ z-index: 99999999999;
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,133 @@
1
+ 'use client';
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __read = (this && this.__read) || function (o, n) {
14
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
15
+ if (!m) return o;
16
+ var i = m.call(o), r, ar = [], e;
17
+ try {
18
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
19
+ }
20
+ catch (error) { e = { error: error }; }
21
+ finally {
22
+ try {
23
+ if (r && !r.done && (m = i["return"])) m.call(i);
24
+ }
25
+ finally { if (e) throw e.error; }
26
+ }
27
+ return ar;
28
+ };
29
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
30
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
31
+ if (ar || !(i in from)) {
32
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
33
+ ar[i] = from[i];
34
+ }
35
+ }
36
+ return to.concat(ar || Array.prototype.slice.call(from));
37
+ };
38
+ import * as React from 'react';
39
+ import { AnimatePresence, motion } from 'framer-motion';
40
+ import { DropdownOption } from '../DropdownOption';
41
+ import { Button } from '@aristobyte-ui/button';
42
+ import { Portal } from '@aristobyte-ui/utils';
43
+ import './Dropdown.scss';
44
+ export var Dropdown = function (_a) {
45
+ 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;
46
+ var _l = __read(React.useState(initiallyOpened), 2), isOpened = _l[0], setIsOpened = _l[1];
47
+ var _m = __read(React.useState(value ? [value] : []), 2), selected = _m[0], setSelected = _m[1];
48
+ var _o = __read(React.useState({
49
+ top: 0,
50
+ left: 0,
51
+ width: 0,
52
+ }), 2), position = _o[0], setPosition = _o[1];
53
+ var _p = __read(React.useState(0), 2), dropdownHeight = _p[0], setDropdownHeight = _p[1];
54
+ var _q = __read(React.useState(0), 2), buttonHeight = _q[0], setButtonHeight = _q[1];
55
+ var buttonRef = React.useRef(null);
56
+ var boxRef = React.useRef(null);
57
+ var uniqueId = React.useId();
58
+ React.useLayoutEffect(function () {
59
+ if (!isOpened) {
60
+ return;
61
+ }
62
+ if (boxRef.current) {
63
+ setDropdownHeight(boxRef.current.getBoundingClientRect().height);
64
+ }
65
+ if (buttonRef.current) {
66
+ setButtonHeight(buttonRef.current.getBoundingClientRect().height);
67
+ }
68
+ }, [isOpened]);
69
+ var options = React.Children.toArray(children).filter(function (child) {
70
+ return React.isValidElement(child) && child.type === DropdownOption;
71
+ });
72
+ var isValidValue = function () {
73
+ return !!options.find(function (_a) {
74
+ var props = _a.props;
75
+ return props.value === value;
76
+ });
77
+ };
78
+ var handleChange = function (currentRadioValue) {
79
+ onChange === null || onChange === void 0 ? void 0 : onChange(currentRadioValue);
80
+ if (!choice) {
81
+ setSelected([currentRadioValue]);
82
+ setIsOpened(false);
83
+ return;
84
+ }
85
+ if (choice === 'single') {
86
+ setSelected([currentRadioValue]);
87
+ }
88
+ if (choice === 'multiple') {
89
+ setSelected(function (prev) {
90
+ return prev.includes(currentRadioValue) ? prev.filter(function (v) { return v !== currentRadioValue; }) : __spreadArray(__spreadArray([], __read(prev), false), [currentRadioValue], false);
91
+ });
92
+ }
93
+ };
94
+ var handleToggle = function (e) {
95
+ var _a;
96
+ if (disabled)
97
+ return;
98
+ var rect = (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
99
+ if (!rect)
100
+ return;
101
+ var spaceBelow = window.innerHeight - rect.bottom;
102
+ var spaceAbove = rect.top;
103
+ var shouldOpenUpwards = dropdownHeight > 0 && spaceBelow < dropdownHeight && spaceAbove > dropdownHeight;
104
+ var finalPosition = {
105
+ top: shouldOpenUpwards
106
+ ? rect.top + window.scrollY - dropdownHeight - buttonHeight / 2
107
+ : rect.top + window.scrollY + buttonHeight + 6,
108
+ left: rect.left + window.scrollX,
109
+ width: rect.width,
110
+ };
111
+ setPosition(finalPosition);
112
+ if (button === null || button === void 0 ? void 0 : button.onClick)
113
+ button.onClick(e);
114
+ setIsOpened(function (prev) { return !prev; });
115
+ };
116
+ if (!isValidValue()) {
117
+ throw new Error('The "value" prop did not match with any of the DropdownOption "value" prop');
118
+ }
119
+ return (React.createElement(React.Fragment, null,
120
+ React.createElement("div", { className: "dropdown ".concat(className) },
121
+ React.createElement(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)),
122
+ React.createElement(Portal, null,
123
+ React.createElement(AnimatePresence, null, isOpened && (React.createElement("div", { className: "dropdown__box ".concat("dropdown__box-variant--".concat(variant)), style: style },
124
+ React.createElement(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); } }),
125
+ React.createElement(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: {
126
+ top: position.top,
127
+ left: position.left,
128
+ width: position.width,
129
+ } }, options.map(function (_a) {
130
+ var props = _a.props;
131
+ return (React.createElement(DropdownOption, __assign({}, props, { variant: variant, appearance: appearance, key: "".concat(props.value, "-").concat(uniqueId), selectedValues: selected, onChange: function () { return handleChange(props.value); } })));
132
+ }))))))));
133
+ };
@@ -0,0 +1,68 @@
1
+ @use '@aristobyte-ui/utils/aristobyte-ui.settings' as *;
2
+
3
+ .dropdown-option {
4
+ align-items: center;
5
+ border-radius: 8px; //TODO: change to dynamic
6
+ color: $white;
7
+ display: flex;
8
+ font-size: 14px;
9
+ font-weight: 500;
10
+ gap: 10px;
11
+ padding: 10px 16px;
12
+ text-align: left;
13
+ transition: all 120ms ease-out;
14
+ width: 100%;
15
+
16
+ &-variant {
17
+ &--default:hover {
18
+ background-color: $color-default-hover;
19
+ }
20
+
21
+ &--primary:hover {
22
+ background-color: $color-primary-hover;
23
+ }
24
+
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
+ }
41
+
42
+ &--disabled,
43
+ &--disabled:hover {
44
+ background-color: $color-default-disabled;
45
+ cursor: auto;
46
+ opacity: 0.5;
47
+ }
48
+
49
+ &__title {
50
+ color: $white;
51
+ }
52
+
53
+ &__description {
54
+ color: rgba($white, 0.6);
55
+ }
56
+
57
+ &__tick {
58
+ color: rgba($white, 0.6);
59
+ opacity: 0;
60
+ transform: scale(0, 0.7) translate(0, 10px);
61
+ transition: all 120ms ease-out;
62
+
63
+ &--active {
64
+ opacity: 1;
65
+ transform: scale(1) translate(0);
66
+ }
67
+ }
68
+ }
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import { Icons } from '@aristobyte-ui/utils';
3
+ import './DropdownOption.scss';
4
+ export var DropdownOption = function (_a) {
5
+ var variant = _a.variant, children = _a.children, value = _a.value, selectedValues = _a.selectedValues, onChange = _a.onChange, description = _a.description, disabled = _a.disabled, _b = _a.style, style = _b === void 0 ? {} : _b;
6
+ var uniqueId = React.useId();
7
+ return (React.createElement("button", { style: style, key: uniqueId, disabled: disabled, className: "".concat('dropdown-option', " ").concat("dropdown-option-variant--".concat(variant), " ").concat(disabled ? 'dropdown-option--disabled' : ''), onClick: onChange },
8
+ React.createElement("div", { className: 'dropdown-option__content' },
9
+ React.createElement("h3", { className: 'dropdown-option__title' }, children),
10
+ React.createElement("p", { className: 'dropdown-option__description' }, description)),
11
+ React.createElement("div", { className: "".concat('dropdown-option__tick', " ").concat((selectedValues === null || selectedValues === void 0 ? void 0 : selectedValues.includes(value)) ? 'dropdown-option__tick--active' : '') },
12
+ React.createElement(Icons.Success, { size: 18 }))));
13
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./Dropdown";
2
+ export * from "./DropdownOption";
@@ -0,0 +1 @@
1
+ export * from './components';
@@ -0,0 +1,64 @@
1
+ @use '@aristobyte-ui/utils/aristobyte-ui.settings' as *;
2
+
3
+ .dropdown {
4
+ width: max-content;
5
+
6
+ &__button {
7
+ width: max-content;
8
+ }
9
+
10
+ &__box {
11
+ &-variant--default &-options {
12
+ background-color: $color-default;
13
+ }
14
+
15
+ &-variant--primary &-options {
16
+ background-color: $color-primary;
17
+ }
18
+
19
+ &-variant--secondary &-options {
20
+ background-color: $color-secondary;
21
+ }
22
+
23
+ &-variant--warning &-options {
24
+ background-color: $color-warning;
25
+ }
26
+
27
+ &-variant--error &-options {
28
+ background-color: $color-error;
29
+ }
30
+
31
+ &-variant--success &-options {
32
+ background-color: $color-success;
33
+ }
34
+
35
+ &-overlay {
36
+ backdrop-filter: blur(12px);
37
+ height: 100%;
38
+ left: 0;
39
+ position: fixed;
40
+ top: 0;
41
+ width: 100%;
42
+ z-index: 99999999999;
43
+ }
44
+
45
+ &-options {
46
+ align-items: flex-start;
47
+ border-radius: 8px; //TODO: change to dynamic
48
+ box-shadow:
49
+ 0 4px 6px rgba(0, 0, 0, 0.04),
50
+ 0 12px 24px rgba(0, 0, 0, 0.1);
51
+ display: flex;
52
+ flex-direction: column;
53
+ opacity: 1;
54
+ min-width: 300px;
55
+ padding: 4px;
56
+ position: absolute;
57
+ transition:
58
+ transform 200ms $cubic-bezier-secondary,
59
+ opacity 150ms ease;
60
+ width: 100%;
61
+ z-index: 99999999999;
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ 'use client';
3
+ var __assign = (this && this.__assign) || function () {
4
+ __assign = Object.assign || function(t) {
5
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
6
+ s = arguments[i];
7
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
8
+ t[p] = s[p];
9
+ }
10
+ return t;
11
+ };
12
+ return __assign.apply(this, arguments);
13
+ };
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ var __read = (this && this.__read) || function (o, n) {
48
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
49
+ if (!m) return o;
50
+ var i = m.call(o), r, ar = [], e;
51
+ try {
52
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
53
+ }
54
+ catch (error) { e = { error: error }; }
55
+ finally {
56
+ try {
57
+ if (r && !r.done && (m = i["return"])) m.call(i);
58
+ }
59
+ finally { if (e) throw e.error; }
60
+ }
61
+ return ar;
62
+ };
63
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
64
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
65
+ if (ar || !(i in from)) {
66
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
67
+ ar[i] = from[i];
68
+ }
69
+ }
70
+ return to.concat(ar || Array.prototype.slice.call(from));
71
+ };
72
+ Object.defineProperty(exports, "__esModule", { value: true });
73
+ exports.Dropdown = void 0;
74
+ var React = __importStar(require("react"));
75
+ var framer_motion_1 = require("framer-motion");
76
+ var DropdownOption_1 = require("../DropdownOption");
77
+ var button_1 = require("@aristobyte-ui/button");
78
+ var utils_1 = require("@aristobyte-ui/utils");
79
+ require("./Dropdown.scss");
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({
85
+ top: 0,
86
+ left: 0,
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);
92
+ var boxRef = React.useRef(null);
93
+ var uniqueId = React.useId();
94
+ React.useLayoutEffect(function () {
95
+ if (!isOpened) {
96
+ 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]);
105
+ var options = React.Children.toArray(children).filter(function (child) {
106
+ return React.isValidElement(child) && child.type === DropdownOption_1.DropdownOption;
107
+ });
108
+ var isValidValue = function () {
109
+ return !!options.find(function (_a) {
110
+ var props = _a.props;
111
+ return props.value === value;
112
+ });
113
+ };
114
+ var handleChange = function (currentRadioValue) {
115
+ onChange === null || onChange === void 0 ? void 0 : onChange(currentRadioValue);
116
+ if (!choice) {
117
+ setSelected([currentRadioValue]);
118
+ setIsOpened(false);
119
+ return;
120
+ }
121
+ if (choice === 'single') {
122
+ setSelected([currentRadioValue]);
123
+ }
124
+ if (choice === 'multiple') {
125
+ setSelected(function (prev) {
126
+ return prev.includes(currentRadioValue) ? prev.filter(function (v) { return v !== currentRadioValue; }) : __spreadArray(__spreadArray([], __read(prev), false), [currentRadioValue], false);
127
+ });
128
+ }
129
+ };
130
+ var handleToggle = function (e) {
131
+ var _a;
132
+ if (disabled)
133
+ 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
+ if (button === null || button === void 0 ? void 0 : button.onClick)
149
+ button.onClick(e);
150
+ setIsOpened(function (prev) { return !prev; });
151
+ };
152
+ if (!isValidValue()) {
153
+ throw new Error('The "value" prop did not match with any of the DropdownOption "value" prop');
154
+ }
155
+ 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)),
158
+ 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 },
160
+ 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
+ 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
+ top: position.top,
163
+ left: position.left,
164
+ width: position.width,
165
+ } }, options.map(function (_a) {
166
+ var props = _a.props;
167
+ return (React.createElement(DropdownOption_1.DropdownOption, __assign({}, props, { variant: variant, appearance: appearance, key: "".concat(props.value, "-").concat(uniqueId), selectedValues: selected, onChange: function () { return handleChange(props.value); } })));
168
+ }))))))));
169
+ };
170
+ exports.Dropdown = Dropdown;
@@ -0,0 +1,68 @@
1
+ @use '@aristobyte-ui/utils/aristobyte-ui.settings' as *;
2
+
3
+ .dropdown-option {
4
+ align-items: center;
5
+ border-radius: 8px; //TODO: change to dynamic
6
+ color: $white;
7
+ display: flex;
8
+ font-size: 14px;
9
+ font-weight: 500;
10
+ gap: 10px;
11
+ padding: 10px 16px;
12
+ text-align: left;
13
+ transition: all 120ms ease-out;
14
+ width: 100%;
15
+
16
+ &-variant {
17
+ &--default:hover {
18
+ background-color: $color-default-hover;
19
+ }
20
+
21
+ &--primary:hover {
22
+ background-color: $color-primary-hover;
23
+ }
24
+
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
+ }
41
+
42
+ &--disabled,
43
+ &--disabled:hover {
44
+ background-color: $color-default-disabled;
45
+ cursor: auto;
46
+ opacity: 0.5;
47
+ }
48
+
49
+ &__title {
50
+ color: $white;
51
+ }
52
+
53
+ &__description {
54
+ color: rgba($white, 0.6);
55
+ }
56
+
57
+ &__tick {
58
+ color: rgba($white, 0.6);
59
+ opacity: 0;
60
+ transform: scale(0, 0.7) translate(0, 10px);
61
+ transition: all 120ms ease-out;
62
+
63
+ &--active {
64
+ opacity: 1;
65
+ transform: scale(1) translate(0);
66
+ }
67
+ }
68
+ }
@@ -0,0 +1,50 @@
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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DropdownOption = void 0;
37
+ var React = __importStar(require("react"));
38
+ var utils_1 = require("@aristobyte-ui/utils");
39
+ require("./DropdownOption.scss");
40
+ var DropdownOption = function (_a) {
41
+ var variant = _a.variant, children = _a.children, value = _a.value, selectedValues = _a.selectedValues, onChange = _a.onChange, description = _a.description, disabled = _a.disabled, _b = _a.style, style = _b === void 0 ? {} : _b;
42
+ var uniqueId = React.useId();
43
+ return (React.createElement("button", { style: style, key: uniqueId, disabled: disabled, className: "".concat('dropdown-option', " ").concat("dropdown-option-variant--".concat(variant), " ").concat(disabled ? 'dropdown-option--disabled' : ''), onClick: onChange },
44
+ React.createElement("div", { className: 'dropdown-option__content' },
45
+ React.createElement("h3", { className: 'dropdown-option__title' }, children),
46
+ React.createElement("p", { className: 'dropdown-option__description' }, description)),
47
+ React.createElement("div", { className: "".concat('dropdown-option__tick', " ").concat((selectedValues === null || selectedValues === void 0 ? void 0 : selectedValues.includes(value)) ? 'dropdown-option__tick--active' : '') },
48
+ React.createElement(utils_1.Icons.Success, { size: 18 }))));
49
+ };
50
+ exports.DropdownOption = DropdownOption;
@@ -0,0 +1,18 @@
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("./Dropdown"), exports);
18
+ __exportStar(require("./DropdownOption"), exports);
@@ -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("./components"), exports);
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": "1.0.112",
4
+ "version": "2.0.0",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "author": "AristoByte <info@aristobyte.com>",
@@ -9,7 +9,7 @@
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/aristobyte-team/aristobyte-ui.git",
12
- "directory": "packages/jest-config"
12
+ "directory": "packages/dropdown"
13
13
  },
14
14
  "bugs": {
15
15
  "url": "https://github.com/aristobyte-team/aristobyte-ui.git/issues"
@@ -42,39 +42,14 @@
42
42
  "publishConfig": {
43
43
  "access": "public"
44
44
  },
45
- "main": "dist/index.js",
46
- "module": "dist/index.mjs",
47
- "types": "dist/index.d.ts",
48
- "exports": {
49
- ".": {
50
- "import": "./dist/index.mjs",
51
- "require": "./dist/index.js"
52
- }
53
- },
54
- "scripts": {
55
- "build": "tsup",
56
- "lint": "eslint . --max-warnings 0",
57
- "generate:component": "turbo gen react-component",
58
- "check-types": "tsc --noEmit"
59
- },
45
+ "main": "dist/lib/main/index.js",
46
+ "module": "dist/es/main/index.js",
60
47
  "peerDependencies": {
61
48
  "react": "^19.1.0",
62
49
  "react-dom": "^19.1.0"
63
50
  },
64
51
  "dependencies": {
65
- "@aristobyte-ui/button": "^1.0.112",
66
- "@aristobyte-ui/utils": "^1.0.112",
67
- "framer-motion": "^12.23.12"
68
- },
69
- "devDependencies": {
70
- "@aristobyte-ui/eslint-config": "^1.0.112",
71
- "@aristobyte-ui/typescript-config": "^1.0.112",
72
- "@turbo/gen": "^2.5.0",
73
- "@types/node": "^24.3.0",
74
- "@types/react": "19.1.0",
75
- "@types/react-dom": "19.1.1",
76
- "eslint": "^9.27.0",
77
- "tsup": "^8.5.0",
78
- "typescript": "^5.8.3"
52
+ "@aristobyte-ui/button": "^2.0.0",
53
+ "@aristobyte-ui/utils": "^2.0.0"
79
54
  }
80
55
  }
package/dist/index.d.mts DELETED
@@ -1,35 +0,0 @@
1
- import * as React from 'react';
2
- import { IButton } from '@aristobyte-ui/button';
3
-
4
- interface IDropdownOption {
5
- variant?: "default" | "primary" | "secondary" | "success" | "error" | "warning";
6
- appearance?: "solid" | "outline" | "outline-dashed" | "no-outline" | "glowing";
7
- children: string;
8
- value: string;
9
- onChange?: () => void;
10
- selectedValues?: string[];
11
- description?: string;
12
- icon?: string;
13
- disabled?: boolean;
14
- choice?: "multiple" | "single";
15
- style?: React.CSSProperties;
16
- }
17
- declare const DropdownOption: React.FC<IDropdownOption>;
18
-
19
- interface IDropdown {
20
- children: React.ReactElement<IDropdownOption> | React.ReactElement<IDropdownOption>[];
21
- value: string;
22
- button?: Omit<IButton, "children" | "dangerouslySetInnerHTML">;
23
- variant?: "default" | "primary" | "secondary" | "success" | "error" | "warning";
24
- appearance?: "solid" | "outline" | "outline-dashed" | "no-outline" | "glowing";
25
- onChange?: (newValue: string) => void;
26
- initiallyOpened?: boolean;
27
- choice?: "multiple" | "single";
28
- placeholder?: string;
29
- disabled?: boolean;
30
- className?: string;
31
- style?: React.CSSProperties;
32
- }
33
- declare const Dropdown: React.FC<IDropdown>;
34
-
35
- export { Dropdown, DropdownOption, type IDropdown, type IDropdownOption };
package/dist/index.d.ts DELETED
@@ -1,35 +0,0 @@
1
- import * as React from 'react';
2
- import { IButton } from '@aristobyte-ui/button';
3
-
4
- interface IDropdownOption {
5
- variant?: "default" | "primary" | "secondary" | "success" | "error" | "warning";
6
- appearance?: "solid" | "outline" | "outline-dashed" | "no-outline" | "glowing";
7
- children: string;
8
- value: string;
9
- onChange?: () => void;
10
- selectedValues?: string[];
11
- description?: string;
12
- icon?: string;
13
- disabled?: boolean;
14
- choice?: "multiple" | "single";
15
- style?: React.CSSProperties;
16
- }
17
- declare const DropdownOption: React.FC<IDropdownOption>;
18
-
19
- interface IDropdown {
20
- children: React.ReactElement<IDropdownOption> | React.ReactElement<IDropdownOption>[];
21
- value: string;
22
- button?: Omit<IButton, "children" | "dangerouslySetInnerHTML">;
23
- variant?: "default" | "primary" | "secondary" | "success" | "error" | "warning";
24
- appearance?: "solid" | "outline" | "outline-dashed" | "no-outline" | "glowing";
25
- onChange?: (newValue: string) => void;
26
- initiallyOpened?: boolean;
27
- choice?: "multiple" | "single";
28
- placeholder?: string;
29
- disabled?: boolean;
30
- className?: string;
31
- style?: React.CSSProperties;
32
- }
33
- declare const Dropdown: React.FC<IDropdown>;
34
-
35
- export { Dropdown, DropdownOption, type IDropdown, type IDropdownOption };
package/dist/index.js DELETED
@@ -1,239 +0,0 @@
1
- "use client";
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
-
31
- // index.ts
32
- var index_exports = {};
33
- __export(index_exports, {
34
- Dropdown: () => Dropdown,
35
- DropdownOption: () => DropdownOption
36
- });
37
- module.exports = __toCommonJS(index_exports);
38
-
39
- // components/Dropdown/index.tsx
40
- var React2 = __toESM(require("react"));
41
- var import_framer_motion = require("framer-motion");
42
-
43
- // components/DropdownOption/index.tsx
44
- var React = __toESM(require("react"));
45
- var import_utils = require("@aristobyte-ui/utils");
46
- var import_jsx_runtime = require("react/jsx-runtime");
47
- var DropdownOption = ({
48
- variant,
49
- children,
50
- value,
51
- selectedValues,
52
- onChange,
53
- // icon,
54
- description,
55
- disabled,
56
- style = {}
57
- }) => {
58
- const uniqueId = React.useId();
59
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
60
- "button",
61
- {
62
- style,
63
- disabled,
64
- className: `dropdown-option dropdown-option-variant--${variant} ${disabled ? "dropdown-option--disabled" : ""}`,
65
- onClick: onChange,
66
- children: [
67
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dropdown-option__content", children: [
68
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "dropdown-option__title", children }),
69
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dropdown-option__description", children: description })
70
- ] }),
71
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
72
- "div",
73
- {
74
- className: `dropdown-option__tick ${(selectedValues == null ? void 0 : selectedValues.includes(value)) ? "dropdown-option__tick--active" : ""}`,
75
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_utils.Icons.Success, { size: 18 })
76
- }
77
- )
78
- ]
79
- },
80
- uniqueId
81
- );
82
- };
83
-
84
- // components/Dropdown/index.tsx
85
- var import_button = require("@aristobyte-ui/button");
86
- var import_utils2 = require("@aristobyte-ui/utils");
87
- var import_jsx_runtime2 = require("react/jsx-runtime");
88
- var import_react = require("react");
89
- var Dropdown = ({
90
- children,
91
- value,
92
- onChange,
93
- appearance = "outline",
94
- variant = "default",
95
- placeholder = "Select",
96
- choice = "single",
97
- className = "",
98
- initiallyOpened = false,
99
- disabled = false,
100
- button = {},
101
- style = {}
102
- }) => {
103
- const [isOpened, setIsOpened] = React2.useState(initiallyOpened);
104
- const [selected, setSelected] = React2.useState(
105
- value ? [value] : []
106
- );
107
- const [position, setPosition] = React2.useState({
108
- top: 0,
109
- left: 0,
110
- width: 0
111
- });
112
- const [dropdownHeight, setDropdownHeight] = React2.useState(0);
113
- const [buttonHeight, setButtonHeight] = React2.useState(0);
114
- const buttonRef = React2.useRef(null);
115
- const boxRef = React2.useRef(null);
116
- const uniqueId = React2.useId();
117
- React2.useLayoutEffect(() => {
118
- if (!isOpened) {
119
- return;
120
- }
121
- if (boxRef.current) {
122
- setDropdownHeight(boxRef.current.getBoundingClientRect().height);
123
- }
124
- if (buttonRef.current) {
125
- setButtonHeight(buttonRef.current.getBoundingClientRect().height);
126
- }
127
- }, [isOpened]);
128
- const options = React2.Children.toArray(children).filter(
129
- (child) => React2.isValidElement(child) && child.type === DropdownOption
130
- );
131
- const isValidValue = () => {
132
- return !!options.find(({ props }) => props.value === value);
133
- };
134
- const handleChange = (currentRadioValue) => {
135
- onChange == null ? void 0 : onChange(currentRadioValue);
136
- if (!choice) {
137
- setSelected([currentRadioValue]);
138
- setIsOpened(false);
139
- return;
140
- }
141
- if (choice === "single") {
142
- setSelected([currentRadioValue]);
143
- }
144
- if (choice === "multiple") {
145
- setSelected(
146
- (prev) => prev.includes(currentRadioValue) ? prev.filter((v) => v !== currentRadioValue) : [...prev, currentRadioValue]
147
- );
148
- }
149
- };
150
- const handleToggle = (e) => {
151
- var _a;
152
- if (disabled) return;
153
- const rect = (_a = buttonRef.current) == null ? void 0 : _a.getBoundingClientRect();
154
- if (!rect) return;
155
- const spaceBelow = window.innerHeight - rect.bottom;
156
- const spaceAbove = rect.top;
157
- const shouldOpenUpwards = dropdownHeight > 0 && spaceBelow < dropdownHeight && spaceAbove > dropdownHeight;
158
- const finalPosition = {
159
- top: shouldOpenUpwards ? rect.top + window.scrollY - dropdownHeight - buttonHeight / 2 : rect.top + window.scrollY + buttonHeight + 6,
160
- left: rect.left + window.scrollX,
161
- width: rect.width
162
- };
163
- setPosition(finalPosition);
164
- if (button == null ? void 0 : button.onClick) button.onClick(e);
165
- setIsOpened((prev) => !prev);
166
- };
167
- if (!isValidValue()) {
168
- throw new Error(
169
- 'The "value" prop did not match with any of the DropdownOption "value" prop'
170
- );
171
- }
172
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
173
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `dropdown ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
174
- import_button.Button,
175
- {
176
- onClick: handleToggle,
177
- className: `${"dropdown__button"} ${(button == null ? void 0 : button.className) || ""}`,
178
- appearance: (button == null ? void 0 : button.appearance) || appearance,
179
- variant: (button == null ? void 0 : button.variant) || variant,
180
- disabled: (button == null ? void 0 : button.disabled) || disabled,
181
- ...{ ref: buttonRef },
182
- children: placeholder
183
- }
184
- ) }),
185
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_utils2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_framer_motion.AnimatePresence, { children: isOpened && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
186
- "div",
187
- {
188
- className: `dropdown__box dropdown__box-variant--${variant}`,
189
- style,
190
- children: [
191
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
192
- import_framer_motion.motion.div,
193
- {
194
- className: "dropdown__box-overlay",
195
- initial: { opacity: 0 },
196
- animate: { opacity: 1 },
197
- exit: { opacity: 0 },
198
- transition: { duration: 0.3, ease: "easeIn" },
199
- onClick: () => setIsOpened(false)
200
- }
201
- ),
202
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
203
- import_framer_motion.motion.div,
204
- {
205
- ref: boxRef,
206
- className: "dropdown__box-options",
207
- initial: { opacity: 0, y: 20, scale: 0.95 },
208
- animate: { opacity: 1, y: 0, scale: 1 },
209
- exit: { opacity: 0, y: 20, scale: 0.95 },
210
- transition: { duration: 0.2, ease: "easeIn" },
211
- style: {
212
- top: position.top,
213
- left: position.left,
214
- width: position.width
215
- },
216
- children: options.map(({ props }) => /* @__PURE__ */ (0, import_react.createElement)(
217
- DropdownOption,
218
- {
219
- ...props,
220
- variant,
221
- appearance,
222
- key: `${props.value}-${uniqueId}`,
223
- selectedValues: selected,
224
- onChange: () => handleChange(props.value)
225
- }
226
- ))
227
- }
228
- )
229
- ]
230
- }
231
- ) }) })
232
- ] });
233
- };
234
- // Annotate the CommonJS export names for ESM import in node:
235
- 0 && (module.exports = {
236
- Dropdown,
237
- DropdownOption
238
- });
239
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../index.ts","../components/Dropdown/index.tsx","../components/DropdownOption/index.tsx"],"sourcesContent":["export * from \"./components\";\n","\"use client\";\n\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"framer-motion\";\n\nimport { DropdownOption, type IDropdownOption } from \"../DropdownOption\";\nimport { Button, type IButton } from \"@aristobyte-ui/button\";\nimport { Portal } from \"@aristobyte-ui/utils\";\n\ntype PositionType = {\n top: 0;\n left: 0;\n width: 0;\n};\n\nexport interface IDropdown {\n children:\n | React.ReactElement<IDropdownOption>\n | React.ReactElement<IDropdownOption>[];\n value: string;\n button?: Omit<IButton, \"children\" | \"dangerouslySetInnerHTML\">;\n variant?:\n | \"default\"\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"error\"\n | \"warning\";\n appearance?:\n | \"solid\"\n | \"outline\"\n | \"outline-dashed\"\n | \"no-outline\"\n | \"glowing\";\n onChange?: (newValue: string) => void;\n initiallyOpened?: boolean;\n choice?: \"multiple\" | \"single\";\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const Dropdown: React.FC<IDropdown> = ({\n children,\n value,\n onChange,\n appearance = \"outline\",\n variant = \"default\",\n placeholder = \"Select\",\n choice = \"single\",\n className = \"\",\n initiallyOpened = false,\n disabled = false,\n button = {},\n style = {},\n}) => {\n const [isOpened, setIsOpened] = React.useState<boolean>(initiallyOpened);\n const [selected, setSelected] = React.useState<string[]>(\n value ? [value] : []\n );\n const [position, setPosition] = React.useState<PositionType>({\n top: 0,\n left: 0,\n width: 0,\n });\n const [dropdownHeight, setDropdownHeight] = React.useState(0);\n const [buttonHeight, setButtonHeight] = React.useState(0);\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const uniqueId = React.useId();\n\n React.useLayoutEffect(() => {\n if (!isOpened) {\n return;\n }\n\n if (boxRef.current) {\n setDropdownHeight(boxRef.current.getBoundingClientRect().height);\n }\n\n if (buttonRef.current) {\n setButtonHeight(buttonRef.current.getBoundingClientRect().height);\n }\n }, [isOpened]);\n\n const options = React.Children.toArray(children).filter(\n (child): child is React.ReactElement<IDropdownOption> =>\n React.isValidElement(child) && child.type === DropdownOption\n );\n\n const isValidValue = () => {\n return !!options.find(({ props }) => props.value === value);\n };\n\n const handleChange = (currentRadioValue: string) => {\n onChange?.(currentRadioValue);\n if (!choice) {\n setSelected([currentRadioValue]);\n setIsOpened(false);\n return;\n }\n\n if (choice === \"single\") {\n setSelected([currentRadioValue]);\n }\n\n if (choice === \"multiple\") {\n setSelected((prev) =>\n prev.includes(currentRadioValue)\n ? prev.filter((v) => v !== currentRadioValue)\n : [...prev, currentRadioValue]\n );\n }\n };\n\n const handleToggle = (\n e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement, MouseEvent>\n ) => {\n if (disabled) return;\n\n const rect = buttonRef.current?.getBoundingClientRect();\n if (!rect) return;\n\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n\n const shouldOpenUpwards =\n dropdownHeight > 0 &&\n spaceBelow < dropdownHeight &&\n spaceAbove > dropdownHeight;\n\n const finalPosition = {\n top: shouldOpenUpwards\n ? rect.top + window.scrollY - dropdownHeight - buttonHeight / 2\n : rect.top + window.scrollY + buttonHeight + 6,\n left: rect.left + window.scrollX,\n width: rect.width,\n } as PositionType;\n\n setPosition(finalPosition);\n\n if (button?.onClick) button.onClick(e);\n\n setIsOpened((prev) => !prev);\n };\n\n if (!isValidValue()) {\n throw new Error(\n 'The \"value\" prop did not match with any of the DropdownOption \"value\" prop'\n );\n }\n\n return (\n <>\n <div className={`dropdown ${className}`}>\n <Button\n onClick={handleToggle}\n className={`${\"dropdown__button\"} ${button?.className || \"\"}`}\n appearance={button?.appearance || appearance}\n variant={button?.variant || variant}\n disabled={button?.disabled || disabled}\n {...{ ref: buttonRef }}\n >\n {placeholder}\n </Button>\n </div>\n\n <Portal>\n <AnimatePresence>\n {isOpened && (\n <div\n className={`dropdown__box dropdown__box-variant--${variant}`}\n style={style}\n >\n <motion.div\n className={\"dropdown__box-overlay\"}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3, ease: \"easeIn\" }}\n onClick={() => setIsOpened(false)}\n />\n <motion.div\n ref={boxRef}\n className={\"dropdown__box-options\"}\n initial={{ opacity: 0, y: 20, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 20, scale: 0.95 }}\n transition={{ duration: 0.2, ease: \"easeIn\" }}\n style={{\n top: position.top,\n left: position.left,\n width: position.width,\n }}\n >\n {options.map(({ props }) => (\n <DropdownOption\n {...props}\n variant={variant}\n appearance={appearance}\n key={`${props.value}-${uniqueId}`}\n selectedValues={selected}\n onChange={() => handleChange(props.value)}\n />\n ))}\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n </Portal>\n </>\n );\n};\n","import * as React from \"react\";\n\nimport { Icons } from \"@aristobyte-ui/utils\";\n\nexport interface IDropdownOption {\n variant?:\n | \"default\"\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"error\"\n | \"warning\";\n appearance?:\n | \"solid\"\n | \"outline\"\n | \"outline-dashed\"\n | \"no-outline\"\n | \"glowing\";\n children: string;\n value: string;\n onChange?: () => void;\n selectedValues?: string[];\n description?: string;\n icon?: string;\n disabled?: boolean;\n choice?: \"multiple\" | \"single\";\n style?: React.CSSProperties;\n}\n\nexport const DropdownOption: React.FC<IDropdownOption> = ({\n variant,\n children,\n value,\n selectedValues,\n onChange,\n // icon,\n description,\n disabled,\n style = {},\n}) => {\n const uniqueId = React.useId();\n return (\n <button\n style={style}\n key={uniqueId}\n disabled={disabled}\n className={`dropdown-option dropdown-option-variant--${variant} ${disabled ? \"dropdown-option--disabled\" : \"\"}`}\n onClick={onChange}\n >\n <div className={\"dropdown-option__content\"}>\n <h3 className={\"dropdown-option__title\"}>{children}</h3>\n <p className={\"dropdown-option__description\"}>{description}</p>\n </div>\n <div\n className={`dropdown-option__tick ${selectedValues?.includes(value) ? \"dropdown-option__tick--active\" : \"\"}`}\n >\n <Icons.Success size={18} />\n </div>\n </button>\n );\n};\n"],"mappings":"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","names":["React","import_utils","import_jsx_runtime"]}
package/dist/index.mjs DELETED
@@ -1,202 +0,0 @@
1
- "use client";
2
-
3
- // components/Dropdown/index.tsx
4
- import * as React2 from "react";
5
- import { AnimatePresence, motion } from "framer-motion";
6
-
7
- // components/DropdownOption/index.tsx
8
- import * as React from "react";
9
- import { Icons } from "@aristobyte-ui/utils";
10
- import { jsx, jsxs } from "react/jsx-runtime";
11
- var DropdownOption = ({
12
- variant,
13
- children,
14
- value,
15
- selectedValues,
16
- onChange,
17
- // icon,
18
- description,
19
- disabled,
20
- style = {}
21
- }) => {
22
- const uniqueId = React.useId();
23
- return /* @__PURE__ */ jsxs(
24
- "button",
25
- {
26
- style,
27
- disabled,
28
- className: `dropdown-option dropdown-option-variant--${variant} ${disabled ? "dropdown-option--disabled" : ""}`,
29
- onClick: onChange,
30
- children: [
31
- /* @__PURE__ */ jsxs("div", { className: "dropdown-option__content", children: [
32
- /* @__PURE__ */ jsx("h3", { className: "dropdown-option__title", children }),
33
- /* @__PURE__ */ jsx("p", { className: "dropdown-option__description", children: description })
34
- ] }),
35
- /* @__PURE__ */ jsx(
36
- "div",
37
- {
38
- className: `dropdown-option__tick ${(selectedValues == null ? void 0 : selectedValues.includes(value)) ? "dropdown-option__tick--active" : ""}`,
39
- children: /* @__PURE__ */ jsx(Icons.Success, { size: 18 })
40
- }
41
- )
42
- ]
43
- },
44
- uniqueId
45
- );
46
- };
47
-
48
- // components/Dropdown/index.tsx
49
- import { Button } from "@aristobyte-ui/button";
50
- import { Portal } from "@aristobyte-ui/utils";
51
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
52
- import { createElement } from "react";
53
- var Dropdown = ({
54
- children,
55
- value,
56
- onChange,
57
- appearance = "outline",
58
- variant = "default",
59
- placeholder = "Select",
60
- choice = "single",
61
- className = "",
62
- initiallyOpened = false,
63
- disabled = false,
64
- button = {},
65
- style = {}
66
- }) => {
67
- const [isOpened, setIsOpened] = React2.useState(initiallyOpened);
68
- const [selected, setSelected] = React2.useState(
69
- value ? [value] : []
70
- );
71
- const [position, setPosition] = React2.useState({
72
- top: 0,
73
- left: 0,
74
- width: 0
75
- });
76
- const [dropdownHeight, setDropdownHeight] = React2.useState(0);
77
- const [buttonHeight, setButtonHeight] = React2.useState(0);
78
- const buttonRef = React2.useRef(null);
79
- const boxRef = React2.useRef(null);
80
- const uniqueId = React2.useId();
81
- React2.useLayoutEffect(() => {
82
- if (!isOpened) {
83
- return;
84
- }
85
- if (boxRef.current) {
86
- setDropdownHeight(boxRef.current.getBoundingClientRect().height);
87
- }
88
- if (buttonRef.current) {
89
- setButtonHeight(buttonRef.current.getBoundingClientRect().height);
90
- }
91
- }, [isOpened]);
92
- const options = React2.Children.toArray(children).filter(
93
- (child) => React2.isValidElement(child) && child.type === DropdownOption
94
- );
95
- const isValidValue = () => {
96
- return !!options.find(({ props }) => props.value === value);
97
- };
98
- const handleChange = (currentRadioValue) => {
99
- onChange == null ? void 0 : onChange(currentRadioValue);
100
- if (!choice) {
101
- setSelected([currentRadioValue]);
102
- setIsOpened(false);
103
- return;
104
- }
105
- if (choice === "single") {
106
- setSelected([currentRadioValue]);
107
- }
108
- if (choice === "multiple") {
109
- setSelected(
110
- (prev) => prev.includes(currentRadioValue) ? prev.filter((v) => v !== currentRadioValue) : [...prev, currentRadioValue]
111
- );
112
- }
113
- };
114
- const handleToggle = (e) => {
115
- var _a;
116
- if (disabled) return;
117
- const rect = (_a = buttonRef.current) == null ? void 0 : _a.getBoundingClientRect();
118
- if (!rect) return;
119
- const spaceBelow = window.innerHeight - rect.bottom;
120
- const spaceAbove = rect.top;
121
- const shouldOpenUpwards = dropdownHeight > 0 && spaceBelow < dropdownHeight && spaceAbove > dropdownHeight;
122
- const finalPosition = {
123
- top: shouldOpenUpwards ? rect.top + window.scrollY - dropdownHeight - buttonHeight / 2 : rect.top + window.scrollY + buttonHeight + 6,
124
- left: rect.left + window.scrollX,
125
- width: rect.width
126
- };
127
- setPosition(finalPosition);
128
- if (button == null ? void 0 : button.onClick) button.onClick(e);
129
- setIsOpened((prev) => !prev);
130
- };
131
- if (!isValidValue()) {
132
- throw new Error(
133
- 'The "value" prop did not match with any of the DropdownOption "value" prop'
134
- );
135
- }
136
- return /* @__PURE__ */ jsxs2(Fragment, { children: [
137
- /* @__PURE__ */ jsx2("div", { className: `dropdown ${className}`, children: /* @__PURE__ */ jsx2(
138
- Button,
139
- {
140
- onClick: handleToggle,
141
- className: `${"dropdown__button"} ${(button == null ? void 0 : button.className) || ""}`,
142
- appearance: (button == null ? void 0 : button.appearance) || appearance,
143
- variant: (button == null ? void 0 : button.variant) || variant,
144
- disabled: (button == null ? void 0 : button.disabled) || disabled,
145
- ...{ ref: buttonRef },
146
- children: placeholder
147
- }
148
- ) }),
149
- /* @__PURE__ */ jsx2(Portal, { children: /* @__PURE__ */ jsx2(AnimatePresence, { children: isOpened && /* @__PURE__ */ jsxs2(
150
- "div",
151
- {
152
- className: `dropdown__box dropdown__box-variant--${variant}`,
153
- style,
154
- children: [
155
- /* @__PURE__ */ jsx2(
156
- motion.div,
157
- {
158
- className: "dropdown__box-overlay",
159
- initial: { opacity: 0 },
160
- animate: { opacity: 1 },
161
- exit: { opacity: 0 },
162
- transition: { duration: 0.3, ease: "easeIn" },
163
- onClick: () => setIsOpened(false)
164
- }
165
- ),
166
- /* @__PURE__ */ jsx2(
167
- motion.div,
168
- {
169
- ref: boxRef,
170
- className: "dropdown__box-options",
171
- initial: { opacity: 0, y: 20, scale: 0.95 },
172
- animate: { opacity: 1, y: 0, scale: 1 },
173
- exit: { opacity: 0, y: 20, scale: 0.95 },
174
- transition: { duration: 0.2, ease: "easeIn" },
175
- style: {
176
- top: position.top,
177
- left: position.left,
178
- width: position.width
179
- },
180
- children: options.map(({ props }) => /* @__PURE__ */ createElement(
181
- DropdownOption,
182
- {
183
- ...props,
184
- variant,
185
- appearance,
186
- key: `${props.value}-${uniqueId}`,
187
- selectedValues: selected,
188
- onChange: () => handleChange(props.value)
189
- }
190
- ))
191
- }
192
- )
193
- ]
194
- }
195
- ) }) })
196
- ] });
197
- };
198
- export {
199
- Dropdown,
200
- DropdownOption
201
- };
202
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../components/Dropdown/index.tsx","../components/DropdownOption/index.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"framer-motion\";\n\nimport { DropdownOption, type IDropdownOption } from \"../DropdownOption\";\nimport { Button, type IButton } from \"@aristobyte-ui/button\";\nimport { Portal } from \"@aristobyte-ui/utils\";\n\ntype PositionType = {\n top: 0;\n left: 0;\n width: 0;\n};\n\nexport interface IDropdown {\n children:\n | React.ReactElement<IDropdownOption>\n | React.ReactElement<IDropdownOption>[];\n value: string;\n button?: Omit<IButton, \"children\" | \"dangerouslySetInnerHTML\">;\n variant?:\n | \"default\"\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"error\"\n | \"warning\";\n appearance?:\n | \"solid\"\n | \"outline\"\n | \"outline-dashed\"\n | \"no-outline\"\n | \"glowing\";\n onChange?: (newValue: string) => void;\n initiallyOpened?: boolean;\n choice?: \"multiple\" | \"single\";\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const Dropdown: React.FC<IDropdown> = ({\n children,\n value,\n onChange,\n appearance = \"outline\",\n variant = \"default\",\n placeholder = \"Select\",\n choice = \"single\",\n className = \"\",\n initiallyOpened = false,\n disabled = false,\n button = {},\n style = {},\n}) => {\n const [isOpened, setIsOpened] = React.useState<boolean>(initiallyOpened);\n const [selected, setSelected] = React.useState<string[]>(\n value ? [value] : []\n );\n const [position, setPosition] = React.useState<PositionType>({\n top: 0,\n left: 0,\n width: 0,\n });\n const [dropdownHeight, setDropdownHeight] = React.useState(0);\n const [buttonHeight, setButtonHeight] = React.useState(0);\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const boxRef = React.useRef<HTMLDivElement>(null);\n const uniqueId = React.useId();\n\n React.useLayoutEffect(() => {\n if (!isOpened) {\n return;\n }\n\n if (boxRef.current) {\n setDropdownHeight(boxRef.current.getBoundingClientRect().height);\n }\n\n if (buttonRef.current) {\n setButtonHeight(buttonRef.current.getBoundingClientRect().height);\n }\n }, [isOpened]);\n\n const options = React.Children.toArray(children).filter(\n (child): child is React.ReactElement<IDropdownOption> =>\n React.isValidElement(child) && child.type === DropdownOption\n );\n\n const isValidValue = () => {\n return !!options.find(({ props }) => props.value === value);\n };\n\n const handleChange = (currentRadioValue: string) => {\n onChange?.(currentRadioValue);\n if (!choice) {\n setSelected([currentRadioValue]);\n setIsOpened(false);\n return;\n }\n\n if (choice === \"single\") {\n setSelected([currentRadioValue]);\n }\n\n if (choice === \"multiple\") {\n setSelected((prev) =>\n prev.includes(currentRadioValue)\n ? prev.filter((v) => v !== currentRadioValue)\n : [...prev, currentRadioValue]\n );\n }\n };\n\n const handleToggle = (\n e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement, MouseEvent>\n ) => {\n if (disabled) return;\n\n const rect = buttonRef.current?.getBoundingClientRect();\n if (!rect) return;\n\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n\n const shouldOpenUpwards =\n dropdownHeight > 0 &&\n spaceBelow < dropdownHeight &&\n spaceAbove > dropdownHeight;\n\n const finalPosition = {\n top: shouldOpenUpwards\n ? rect.top + window.scrollY - dropdownHeight - buttonHeight / 2\n : rect.top + window.scrollY + buttonHeight + 6,\n left: rect.left + window.scrollX,\n width: rect.width,\n } as PositionType;\n\n setPosition(finalPosition);\n\n if (button?.onClick) button.onClick(e);\n\n setIsOpened((prev) => !prev);\n };\n\n if (!isValidValue()) {\n throw new Error(\n 'The \"value\" prop did not match with any of the DropdownOption \"value\" prop'\n );\n }\n\n return (\n <>\n <div className={`dropdown ${className}`}>\n <Button\n onClick={handleToggle}\n className={`${\"dropdown__button\"} ${button?.className || \"\"}`}\n appearance={button?.appearance || appearance}\n variant={button?.variant || variant}\n disabled={button?.disabled || disabled}\n {...{ ref: buttonRef }}\n >\n {placeholder}\n </Button>\n </div>\n\n <Portal>\n <AnimatePresence>\n {isOpened && (\n <div\n className={`dropdown__box dropdown__box-variant--${variant}`}\n style={style}\n >\n <motion.div\n className={\"dropdown__box-overlay\"}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3, ease: \"easeIn\" }}\n onClick={() => setIsOpened(false)}\n />\n <motion.div\n ref={boxRef}\n className={\"dropdown__box-options\"}\n initial={{ opacity: 0, y: 20, scale: 0.95 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 20, scale: 0.95 }}\n transition={{ duration: 0.2, ease: \"easeIn\" }}\n style={{\n top: position.top,\n left: position.left,\n width: position.width,\n }}\n >\n {options.map(({ props }) => (\n <DropdownOption\n {...props}\n variant={variant}\n appearance={appearance}\n key={`${props.value}-${uniqueId}`}\n selectedValues={selected}\n onChange={() => handleChange(props.value)}\n />\n ))}\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n </Portal>\n </>\n );\n};\n","import * as React from \"react\";\n\nimport { Icons } from \"@aristobyte-ui/utils\";\n\nexport interface IDropdownOption {\n variant?:\n | \"default\"\n | \"primary\"\n | \"secondary\"\n | \"success\"\n | \"error\"\n | \"warning\";\n appearance?:\n | \"solid\"\n | \"outline\"\n | \"outline-dashed\"\n | \"no-outline\"\n | \"glowing\";\n children: string;\n value: string;\n onChange?: () => void;\n selectedValues?: string[];\n description?: string;\n icon?: string;\n disabled?: boolean;\n choice?: \"multiple\" | \"single\";\n style?: React.CSSProperties;\n}\n\nexport const DropdownOption: React.FC<IDropdownOption> = ({\n variant,\n children,\n value,\n selectedValues,\n onChange,\n // icon,\n description,\n disabled,\n style = {},\n}) => {\n const uniqueId = React.useId();\n return (\n <button\n style={style}\n key={uniqueId}\n disabled={disabled}\n className={`dropdown-option dropdown-option-variant--${variant} ${disabled ? \"dropdown-option--disabled\" : \"\"}`}\n onClick={onChange}\n >\n <div className={\"dropdown-option__content\"}>\n <h3 className={\"dropdown-option__title\"}>{children}</h3>\n <p className={\"dropdown-option__description\"}>{description}</p>\n </div>\n <div\n className={`dropdown-option__tick ${selectedValues?.includes(value) ? \"dropdown-option__tick--active\" : \"\"}`}\n >\n <Icons.Success size={18} />\n </div>\n </button>\n );\n};\n"],"mappings":"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","names":["React","jsx","jsxs"]}