@spark-web/action-dropdown 1.0.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.
- package/CHANGELOG.md +38 -0
- package/README.md +30 -0
- package/dist/declarations/src/action-dropdown.d.ts +31 -0
- package/dist/declarations/src/index.d.ts +2 -0
- package/dist/spark-web-action-dropdown.cjs.d.ts +2 -0
- package/dist/spark-web-action-dropdown.cjs.dev.js +169 -0
- package/dist/spark-web-action-dropdown.cjs.js +7 -0
- package/dist/spark-web-action-dropdown.cjs.prod.js +169 -0
- package/dist/spark-web-action-dropdown.esm.js +161 -0
- package/package.json +40 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# @spark-web/action-dropdown
|
|
2
|
+
|
|
3
|
+
## 1.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#748](https://github.com/brighte-labs/spark-web/pull/748)
|
|
8
|
+
[`17d237b`](https://github.com/brighte-labs/spark-web/commit/17d237b97cf01c3b97f0440d49c6d82dd821c905)
|
|
9
|
+
Thanks [@jacobporci-brighte](https://github.com/jacobporci-brighte)! - add
|
|
10
|
+
@spark-web/combobox as a dependency
|
|
11
|
+
|
|
12
|
+
## 1.0.0
|
|
13
|
+
|
|
14
|
+
### Major Changes
|
|
15
|
+
|
|
16
|
+
- [#745](https://github.com/brighte-labs/spark-web/pull/745)
|
|
17
|
+
[`d64cd8f`](https://github.com/brighte-labs/spark-web/commit/d64cd8f8e1692992b4597b563b9ba0bdcda25f6c)
|
|
18
|
+
Thanks [@jacobporci-brighte](https://github.com/jacobporci-brighte)! - New
|
|
19
|
+
Action Dropdown component
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
[[`80d9c15`](https://github.com/brighte-labs/spark-web/commit/80d9c156a40bbcd2b1a91a2d0403b3c8e9b47b4e)]:
|
|
25
|
+
- @spark-web/theme@5.13.0
|
|
26
|
+
- @spark-web/utils@5.1.0
|
|
27
|
+
- @spark-web/a11y@5.3.0
|
|
28
|
+
- @spark-web/icon@5.1.0
|
|
29
|
+
- @spark-web/text@5.3.0
|
|
30
|
+
- @spark-web/box@6.0.0
|
|
31
|
+
|
|
32
|
+
## 1.0.0
|
|
33
|
+
|
|
34
|
+
### Major Changes
|
|
35
|
+
|
|
36
|
+
- Initial release of ActionDropdown component
|
|
37
|
+
- Pill-shaped button that opens dropdown menu of actions
|
|
38
|
+
- Each action triggers onClick callback when selected
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @spark-web/action-dropdown
|
|
2
|
+
|
|
3
|
+
A pill-shaped button component that displays a dropdown menu of actions when
|
|
4
|
+
clicked.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { ActionDropdown } from '@spark-web/action-dropdown';
|
|
10
|
+
|
|
11
|
+
const MyComponent = () => (
|
|
12
|
+
<ActionDropdown
|
|
13
|
+
label="Actions"
|
|
14
|
+
actions={[
|
|
15
|
+
{
|
|
16
|
+
label: 'Edit',
|
|
17
|
+
value: 'edit',
|
|
18
|
+
onClick: data => console.log('Edit clicked', data),
|
|
19
|
+
data: { id: 1 },
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: 'Delete',
|
|
23
|
+
value: 'delete',
|
|
24
|
+
onClick: data => console.log('Delete clicked', data),
|
|
25
|
+
data: { id: 1 },
|
|
26
|
+
},
|
|
27
|
+
]}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DataAttributeMap } from '@spark-web/utils/internal';
|
|
2
|
+
type ActionItem<T = unknown> = {
|
|
3
|
+
/** Display label for the action */
|
|
4
|
+
label: string;
|
|
5
|
+
/** Unique identifier for the action */
|
|
6
|
+
value: string;
|
|
7
|
+
/** Callback when this action is clicked */
|
|
8
|
+
onClick: (item: T) => void;
|
|
9
|
+
/** Additional data to pass to onClick */
|
|
10
|
+
data?: T;
|
|
11
|
+
/** Whether this action is disabled */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type ActionDropdownProps<T = unknown> = {
|
|
15
|
+
/** Sets data attributes on the component. */
|
|
16
|
+
data?: DataAttributeMap;
|
|
17
|
+
/** The text to display on the button */
|
|
18
|
+
label: string;
|
|
19
|
+
/** Array of actions the user can select from */
|
|
20
|
+
actions: ActionItem<T>[];
|
|
21
|
+
/** Whether the dropdown is disabled */
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
/** Whether the menu should use a portal, and where it should attach. */
|
|
24
|
+
menuPortalTarget?: HTMLElement | null;
|
|
25
|
+
/** Width of the control button */
|
|
26
|
+
controlWidth?: string | number;
|
|
27
|
+
/** Width of the dropdown menu */
|
|
28
|
+
menuWidth?: string | number;
|
|
29
|
+
};
|
|
30
|
+
export declare const ActionDropdown: <T>({ data, label, actions, disabled, menuPortalTarget, controlWidth, menuWidth, }: ActionDropdownProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from "./declarations/src/index.js";
|
|
2
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhcmstd2ViLWFjdGlvbi1kcm9wZG93bi5janMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4vZGVjbGFyYXRpb25zL3NyYy9pbmRleC5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBIn0=
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
6
|
+
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
|
|
7
|
+
var a11y = require('@spark-web/a11y');
|
|
8
|
+
var reactSelectOverrides = require('@spark-web/combobox/src/react-select-overrides');
|
|
9
|
+
var icon = require('@spark-web/icon');
|
|
10
|
+
var text = require('@spark-web/text');
|
|
11
|
+
var theme = require('@spark-web/theme');
|
|
12
|
+
var ReactSelect = require('react-select');
|
|
13
|
+
var jsxRuntime = require('@emotion/react/jsx-runtime');
|
|
14
|
+
|
|
15
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
16
|
+
|
|
17
|
+
var ReactSelect__default = /*#__PURE__*/_interopDefault(ReactSelect);
|
|
18
|
+
|
|
19
|
+
var isBrowser = typeof window !== 'undefined';
|
|
20
|
+
var ActionDropdown = function ActionDropdown(_ref) {
|
|
21
|
+
_ref.data;
|
|
22
|
+
var label = _ref.label,
|
|
23
|
+
actions = _ref.actions,
|
|
24
|
+
_ref$disabled = _ref.disabled,
|
|
25
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
26
|
+
menuPortalTarget = _ref.menuPortalTarget,
|
|
27
|
+
controlWidth = _ref.controlWidth,
|
|
28
|
+
_ref$menuWidth = _ref.menuWidth,
|
|
29
|
+
menuWidth = _ref$menuWidth === void 0 ? '100%' : _ref$menuWidth;
|
|
30
|
+
var theme$1 = theme.useTheme();
|
|
31
|
+
var reactSelectTheme = reactSelectOverrides.useReactSelectThemeOverride();
|
|
32
|
+
|
|
33
|
+
// Use the same text styling as combobox
|
|
34
|
+
var _useText = text.useText({
|
|
35
|
+
baseline: false,
|
|
36
|
+
tone: 'neutral',
|
|
37
|
+
size: 'standard',
|
|
38
|
+
weight: 'regular'
|
|
39
|
+
}),
|
|
40
|
+
_useText2 = _slicedToArray(_useText, 2),
|
|
41
|
+
responsiveTextStyles = _useText2[0],
|
|
42
|
+
textStyles = _useText2[1];
|
|
43
|
+
var focusRingStyles = a11y.useFocusRing({
|
|
44
|
+
always: true
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Handle option selection - trigger the onClick callback
|
|
48
|
+
var handleChange = function handleChange(selectedOption) {
|
|
49
|
+
if (selectedOption !== null && selectedOption !== void 0 && selectedOption.onClick) {
|
|
50
|
+
selectedOption.onClick(selectedOption.data);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Custom components
|
|
55
|
+
var customComponents = {
|
|
56
|
+
DropdownIndicator: function DropdownIndicator(props) {
|
|
57
|
+
return jsxRuntime.jsx(ReactSelect.components.DropdownIndicator, _objectSpread(_objectSpread({}, props), {}, {
|
|
58
|
+
children: jsxRuntime.jsx(icon.ChevronDownIcon, {
|
|
59
|
+
size: "xxsmall",
|
|
60
|
+
tone: "muted"
|
|
61
|
+
})
|
|
62
|
+
}));
|
|
63
|
+
},
|
|
64
|
+
IndicatorSeparator: function IndicatorSeparator() {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Custom styles with text styling from combobox
|
|
70
|
+
var customStyles = {
|
|
71
|
+
control: function control(provided, state) {
|
|
72
|
+
var _theme$components$tex, _theme$components$tex2, _theme$components$tex3, _theme$components$tex4, _theme$components$tex5, _theme$components$tex6, _theme$components$tex7;
|
|
73
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
74
|
+
borderRadius: '24px',
|
|
75
|
+
minHeight: '48px',
|
|
76
|
+
paddingLeft: '16px',
|
|
77
|
+
paddingRight: '8px',
|
|
78
|
+
cursor: 'pointer',
|
|
79
|
+
width: controlWidth || 'auto',
|
|
80
|
+
minWidth: controlWidth || 'auto',
|
|
81
|
+
marginLeft: 'auto'
|
|
82
|
+
}, {
|
|
83
|
+
borderColor: (_theme$components$tex = theme$1.components.textInput) === null || _theme$components$tex === void 0 ? void 0 : _theme$components$tex.borderColor
|
|
84
|
+
}), state.isFocused ? (_theme$components$tex2 = (_theme$components$tex3 = theme$1.components.textInput) === null || _theme$components$tex3 === void 0 ? void 0 : _theme$components$tex3.focused) !== null && _theme$components$tex2 !== void 0 ? _theme$components$tex2 : focusRingStyles : (_theme$components$tex4 = theme$1.components.textInput) !== null && _theme$components$tex4 !== void 0 && _theme$components$tex4.boxShadow ? {
|
|
85
|
+
boxShadow: (_theme$components$tex5 = theme$1.components.textInput) === null || _theme$components$tex5 === void 0 ? void 0 : _theme$components$tex5.boxShadow
|
|
86
|
+
} : {}), (_theme$components$tex6 = theme$1.components.textInput) !== null && _theme$components$tex6 !== void 0 && _theme$components$tex6.hover ? {
|
|
87
|
+
':hover': (_theme$components$tex7 = theme$1.components.textInput) === null || _theme$components$tex7 === void 0 ? void 0 : _theme$components$tex7.hover
|
|
88
|
+
} : {});
|
|
89
|
+
},
|
|
90
|
+
dropdownIndicator: function dropdownIndicator(provided, state) {
|
|
91
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
92
|
+
transitionProperty: 'transform',
|
|
93
|
+
transitionTimingFunction: 'linear',
|
|
94
|
+
transitionDuration: '150ms'
|
|
95
|
+
}, state.isFocused ? {
|
|
96
|
+
transform: 'rotate(180deg)'
|
|
97
|
+
} : {});
|
|
98
|
+
},
|
|
99
|
+
singleValue: function singleValue(provided) {
|
|
100
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
101
|
+
fontWeight: '500',
|
|
102
|
+
color: 'inherit' // Use inherited text color
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
option: function option(provided, state) {
|
|
106
|
+
var _theme$components$tex8, _theme$components$tex9, _theme$components$tex0, _theme$components$tex1, _theme$components$tex10;
|
|
107
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
108
|
+
backgroundColor: 'transparent',
|
|
109
|
+
// Remove default background
|
|
110
|
+
color: 'inherit',
|
|
111
|
+
// Use inherited text color
|
|
112
|
+
borderRadius: (_theme$components$tex8 = theme$1.components.textInput) === null || _theme$components$tex8 === void 0 || (_theme$components$tex8 = _theme$components$tex8.menuOption) === null || _theme$components$tex8 === void 0 ? void 0 : _theme$components$tex8.borderRadius
|
|
113
|
+
}, state.isSelected && {
|
|
114
|
+
backgroundColor: (_theme$components$tex9 = theme$1.components.textInput) === null || _theme$components$tex9 === void 0 || (_theme$components$tex9 = _theme$components$tex9.menuOption) === null || _theme$components$tex9 === void 0 || (_theme$components$tex9 = _theme$components$tex9.selected) === null || _theme$components$tex9 === void 0 ? void 0 : _theme$components$tex9.backgroundColor,
|
|
115
|
+
color: (_theme$components$tex0 = theme$1.components.textInput) === null || _theme$components$tex0 === void 0 || (_theme$components$tex0 = _theme$components$tex0.menuOption) === null || _theme$components$tex0 === void 0 || (_theme$components$tex0 = _theme$components$tex0.selected) === null || _theme$components$tex0 === void 0 ? void 0 : _theme$components$tex0.color
|
|
116
|
+
}), state.isFocused && {
|
|
117
|
+
backgroundColor: (_theme$components$tex1 = theme$1.components.textInput) === null || _theme$components$tex1 === void 0 || (_theme$components$tex1 = _theme$components$tex1.menuOption) === null || _theme$components$tex1 === void 0 || (_theme$components$tex1 = _theme$components$tex1.focused) === null || _theme$components$tex1 === void 0 ? void 0 : _theme$components$tex1.backgroundColor,
|
|
118
|
+
color: 'inherit'
|
|
119
|
+
}), {}, {
|
|
120
|
+
'&:active': {
|
|
121
|
+
backgroundColor: (_theme$components$tex10 = theme$1.components.textInput) === null || _theme$components$tex10 === void 0 || (_theme$components$tex10 = _theme$components$tex10.menuOption) === null || _theme$components$tex10 === void 0 || (_theme$components$tex10 = _theme$components$tex10.active) === null || _theme$components$tex10 === void 0 ? void 0 : _theme$components$tex10.backgroundColor
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
menu: function menu(provided) {
|
|
126
|
+
var _theme$components$tex11, _theme$components$tex12, _theme$components$tex13;
|
|
127
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
128
|
+
width: menuWidth,
|
|
129
|
+
minWidth: menuWidth,
|
|
130
|
+
padding: (_theme$components$tex11 = theme$1.components.textInput) === null || _theme$components$tex11 === void 0 || (_theme$components$tex11 = _theme$components$tex11.menu) === null || _theme$components$tex11 === void 0 ? void 0 : _theme$components$tex11.padding,
|
|
131
|
+
boxShadow: (_theme$components$tex12 = theme$1.components.textInput) === null || _theme$components$tex12 === void 0 || (_theme$components$tex12 = _theme$components$tex12.menu) === null || _theme$components$tex12 === void 0 ? void 0 : _theme$components$tex12.boxShadow,
|
|
132
|
+
borderRadius: (_theme$components$tex13 = theme$1.components.textInput) === null || _theme$components$tex13 === void 0 || (_theme$components$tex13 = _theme$components$tex13.menu) === null || _theme$components$tex13 === void 0 ? void 0 : _theme$components$tex13.borderRadius
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
menuList: function menuList(provided) {
|
|
136
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
137
|
+
padding: 0,
|
|
138
|
+
display: 'flex',
|
|
139
|
+
flexDirection: 'column',
|
|
140
|
+
gap: theme$1.spacing.xsmall
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
return jsxRuntime.jsx(ReactSelect__default["default"], {
|
|
145
|
+
value: {
|
|
146
|
+
label: label,
|
|
147
|
+
value: 'current'
|
|
148
|
+
},
|
|
149
|
+
options: actions,
|
|
150
|
+
onChange: handleChange,
|
|
151
|
+
isDisabled: disabled,
|
|
152
|
+
isSearchable: false,
|
|
153
|
+
components: customComponents,
|
|
154
|
+
styles: _objectSpread(_objectSpread({}, customStyles), {}, {
|
|
155
|
+
menuPortal: function menuPortal(provided) {
|
|
156
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
157
|
+
zIndex: theme$1.elevation.modal,
|
|
158
|
+
pointerEvents: 'all'
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
menuPortalTarget: menuPortalTarget !== null && menuPortalTarget !== void 0 ? menuPortalTarget : isBrowser ? document.body : undefined,
|
|
163
|
+
blurInputOnSelect: true,
|
|
164
|
+
closeMenuOnSelect: true,
|
|
165
|
+
theme: reactSelectTheme
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
exports.ActionDropdown = ActionDropdown;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
6
|
+
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
|
|
7
|
+
var a11y = require('@spark-web/a11y');
|
|
8
|
+
var reactSelectOverrides = require('@spark-web/combobox/src/react-select-overrides');
|
|
9
|
+
var icon = require('@spark-web/icon');
|
|
10
|
+
var text = require('@spark-web/text');
|
|
11
|
+
var theme = require('@spark-web/theme');
|
|
12
|
+
var ReactSelect = require('react-select');
|
|
13
|
+
var jsxRuntime = require('@emotion/react/jsx-runtime');
|
|
14
|
+
|
|
15
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
16
|
+
|
|
17
|
+
var ReactSelect__default = /*#__PURE__*/_interopDefault(ReactSelect);
|
|
18
|
+
|
|
19
|
+
var isBrowser = typeof window !== 'undefined';
|
|
20
|
+
var ActionDropdown = function ActionDropdown(_ref) {
|
|
21
|
+
_ref.data;
|
|
22
|
+
var label = _ref.label,
|
|
23
|
+
actions = _ref.actions,
|
|
24
|
+
_ref$disabled = _ref.disabled,
|
|
25
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
26
|
+
menuPortalTarget = _ref.menuPortalTarget,
|
|
27
|
+
controlWidth = _ref.controlWidth,
|
|
28
|
+
_ref$menuWidth = _ref.menuWidth,
|
|
29
|
+
menuWidth = _ref$menuWidth === void 0 ? '100%' : _ref$menuWidth;
|
|
30
|
+
var theme$1 = theme.useTheme();
|
|
31
|
+
var reactSelectTheme = reactSelectOverrides.useReactSelectThemeOverride();
|
|
32
|
+
|
|
33
|
+
// Use the same text styling as combobox
|
|
34
|
+
var _useText = text.useText({
|
|
35
|
+
baseline: false,
|
|
36
|
+
tone: 'neutral',
|
|
37
|
+
size: 'standard',
|
|
38
|
+
weight: 'regular'
|
|
39
|
+
}),
|
|
40
|
+
_useText2 = _slicedToArray(_useText, 2),
|
|
41
|
+
responsiveTextStyles = _useText2[0],
|
|
42
|
+
textStyles = _useText2[1];
|
|
43
|
+
var focusRingStyles = a11y.useFocusRing({
|
|
44
|
+
always: true
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Handle option selection - trigger the onClick callback
|
|
48
|
+
var handleChange = function handleChange(selectedOption) {
|
|
49
|
+
if (selectedOption !== null && selectedOption !== void 0 && selectedOption.onClick) {
|
|
50
|
+
selectedOption.onClick(selectedOption.data);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Custom components
|
|
55
|
+
var customComponents = {
|
|
56
|
+
DropdownIndicator: function DropdownIndicator(props) {
|
|
57
|
+
return jsxRuntime.jsx(ReactSelect.components.DropdownIndicator, _objectSpread(_objectSpread({}, props), {}, {
|
|
58
|
+
children: jsxRuntime.jsx(icon.ChevronDownIcon, {
|
|
59
|
+
size: "xxsmall",
|
|
60
|
+
tone: "muted"
|
|
61
|
+
})
|
|
62
|
+
}));
|
|
63
|
+
},
|
|
64
|
+
IndicatorSeparator: function IndicatorSeparator() {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Custom styles with text styling from combobox
|
|
70
|
+
var customStyles = {
|
|
71
|
+
control: function control(provided, state) {
|
|
72
|
+
var _theme$components$tex, _theme$components$tex2, _theme$components$tex3, _theme$components$tex4, _theme$components$tex5, _theme$components$tex6, _theme$components$tex7;
|
|
73
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
74
|
+
borderRadius: '24px',
|
|
75
|
+
minHeight: '48px',
|
|
76
|
+
paddingLeft: '16px',
|
|
77
|
+
paddingRight: '8px',
|
|
78
|
+
cursor: 'pointer',
|
|
79
|
+
width: controlWidth || 'auto',
|
|
80
|
+
minWidth: controlWidth || 'auto',
|
|
81
|
+
marginLeft: 'auto'
|
|
82
|
+
}, {
|
|
83
|
+
borderColor: (_theme$components$tex = theme$1.components.textInput) === null || _theme$components$tex === void 0 ? void 0 : _theme$components$tex.borderColor
|
|
84
|
+
}), state.isFocused ? (_theme$components$tex2 = (_theme$components$tex3 = theme$1.components.textInput) === null || _theme$components$tex3 === void 0 ? void 0 : _theme$components$tex3.focused) !== null && _theme$components$tex2 !== void 0 ? _theme$components$tex2 : focusRingStyles : (_theme$components$tex4 = theme$1.components.textInput) !== null && _theme$components$tex4 !== void 0 && _theme$components$tex4.boxShadow ? {
|
|
85
|
+
boxShadow: (_theme$components$tex5 = theme$1.components.textInput) === null || _theme$components$tex5 === void 0 ? void 0 : _theme$components$tex5.boxShadow
|
|
86
|
+
} : {}), (_theme$components$tex6 = theme$1.components.textInput) !== null && _theme$components$tex6 !== void 0 && _theme$components$tex6.hover ? {
|
|
87
|
+
':hover': (_theme$components$tex7 = theme$1.components.textInput) === null || _theme$components$tex7 === void 0 ? void 0 : _theme$components$tex7.hover
|
|
88
|
+
} : {});
|
|
89
|
+
},
|
|
90
|
+
dropdownIndicator: function dropdownIndicator(provided, state) {
|
|
91
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
92
|
+
transitionProperty: 'transform',
|
|
93
|
+
transitionTimingFunction: 'linear',
|
|
94
|
+
transitionDuration: '150ms'
|
|
95
|
+
}, state.isFocused ? {
|
|
96
|
+
transform: 'rotate(180deg)'
|
|
97
|
+
} : {});
|
|
98
|
+
},
|
|
99
|
+
singleValue: function singleValue(provided) {
|
|
100
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
101
|
+
fontWeight: '500',
|
|
102
|
+
color: 'inherit' // Use inherited text color
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
option: function option(provided, state) {
|
|
106
|
+
var _theme$components$tex8, _theme$components$tex9, _theme$components$tex0, _theme$components$tex1, _theme$components$tex10;
|
|
107
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
108
|
+
backgroundColor: 'transparent',
|
|
109
|
+
// Remove default background
|
|
110
|
+
color: 'inherit',
|
|
111
|
+
// Use inherited text color
|
|
112
|
+
borderRadius: (_theme$components$tex8 = theme$1.components.textInput) === null || _theme$components$tex8 === void 0 || (_theme$components$tex8 = _theme$components$tex8.menuOption) === null || _theme$components$tex8 === void 0 ? void 0 : _theme$components$tex8.borderRadius
|
|
113
|
+
}, state.isSelected && {
|
|
114
|
+
backgroundColor: (_theme$components$tex9 = theme$1.components.textInput) === null || _theme$components$tex9 === void 0 || (_theme$components$tex9 = _theme$components$tex9.menuOption) === null || _theme$components$tex9 === void 0 || (_theme$components$tex9 = _theme$components$tex9.selected) === null || _theme$components$tex9 === void 0 ? void 0 : _theme$components$tex9.backgroundColor,
|
|
115
|
+
color: (_theme$components$tex0 = theme$1.components.textInput) === null || _theme$components$tex0 === void 0 || (_theme$components$tex0 = _theme$components$tex0.menuOption) === null || _theme$components$tex0 === void 0 || (_theme$components$tex0 = _theme$components$tex0.selected) === null || _theme$components$tex0 === void 0 ? void 0 : _theme$components$tex0.color
|
|
116
|
+
}), state.isFocused && {
|
|
117
|
+
backgroundColor: (_theme$components$tex1 = theme$1.components.textInput) === null || _theme$components$tex1 === void 0 || (_theme$components$tex1 = _theme$components$tex1.menuOption) === null || _theme$components$tex1 === void 0 || (_theme$components$tex1 = _theme$components$tex1.focused) === null || _theme$components$tex1 === void 0 ? void 0 : _theme$components$tex1.backgroundColor,
|
|
118
|
+
color: 'inherit'
|
|
119
|
+
}), {}, {
|
|
120
|
+
'&:active': {
|
|
121
|
+
backgroundColor: (_theme$components$tex10 = theme$1.components.textInput) === null || _theme$components$tex10 === void 0 || (_theme$components$tex10 = _theme$components$tex10.menuOption) === null || _theme$components$tex10 === void 0 || (_theme$components$tex10 = _theme$components$tex10.active) === null || _theme$components$tex10 === void 0 ? void 0 : _theme$components$tex10.backgroundColor
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
menu: function menu(provided) {
|
|
126
|
+
var _theme$components$tex11, _theme$components$tex12, _theme$components$tex13;
|
|
127
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
128
|
+
width: menuWidth,
|
|
129
|
+
minWidth: menuWidth,
|
|
130
|
+
padding: (_theme$components$tex11 = theme$1.components.textInput) === null || _theme$components$tex11 === void 0 || (_theme$components$tex11 = _theme$components$tex11.menu) === null || _theme$components$tex11 === void 0 ? void 0 : _theme$components$tex11.padding,
|
|
131
|
+
boxShadow: (_theme$components$tex12 = theme$1.components.textInput) === null || _theme$components$tex12 === void 0 || (_theme$components$tex12 = _theme$components$tex12.menu) === null || _theme$components$tex12 === void 0 ? void 0 : _theme$components$tex12.boxShadow,
|
|
132
|
+
borderRadius: (_theme$components$tex13 = theme$1.components.textInput) === null || _theme$components$tex13 === void 0 || (_theme$components$tex13 = _theme$components$tex13.menu) === null || _theme$components$tex13 === void 0 ? void 0 : _theme$components$tex13.borderRadius
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
menuList: function menuList(provided) {
|
|
136
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
137
|
+
padding: 0,
|
|
138
|
+
display: 'flex',
|
|
139
|
+
flexDirection: 'column',
|
|
140
|
+
gap: theme$1.spacing.xsmall
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
return jsxRuntime.jsx(ReactSelect__default["default"], {
|
|
145
|
+
value: {
|
|
146
|
+
label: label,
|
|
147
|
+
value: 'current'
|
|
148
|
+
},
|
|
149
|
+
options: actions,
|
|
150
|
+
onChange: handleChange,
|
|
151
|
+
isDisabled: disabled,
|
|
152
|
+
isSearchable: false,
|
|
153
|
+
components: customComponents,
|
|
154
|
+
styles: _objectSpread(_objectSpread({}, customStyles), {}, {
|
|
155
|
+
menuPortal: function menuPortal(provided) {
|
|
156
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
157
|
+
zIndex: theme$1.elevation.modal,
|
|
158
|
+
pointerEvents: 'all'
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
menuPortalTarget: menuPortalTarget !== null && menuPortalTarget !== void 0 ? menuPortalTarget : isBrowser ? document.body : undefined,
|
|
163
|
+
blurInputOnSelect: true,
|
|
164
|
+
closeMenuOnSelect: true,
|
|
165
|
+
theme: reactSelectTheme
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
exports.ActionDropdown = ActionDropdown;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
|
|
2
|
+
import _slicedToArray from '@babel/runtime/helpers/esm/slicedToArray';
|
|
3
|
+
import { useFocusRing } from '@spark-web/a11y';
|
|
4
|
+
import { useReactSelectThemeOverride } from '@spark-web/combobox/src/react-select-overrides';
|
|
5
|
+
import { ChevronDownIcon } from '@spark-web/icon';
|
|
6
|
+
import { useText } from '@spark-web/text';
|
|
7
|
+
import { useTheme } from '@spark-web/theme';
|
|
8
|
+
import ReactSelect, { components } from 'react-select';
|
|
9
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
10
|
+
|
|
11
|
+
var isBrowser = typeof window !== 'undefined';
|
|
12
|
+
var ActionDropdown = function ActionDropdown(_ref) {
|
|
13
|
+
_ref.data;
|
|
14
|
+
var label = _ref.label,
|
|
15
|
+
actions = _ref.actions,
|
|
16
|
+
_ref$disabled = _ref.disabled,
|
|
17
|
+
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
18
|
+
menuPortalTarget = _ref.menuPortalTarget,
|
|
19
|
+
controlWidth = _ref.controlWidth,
|
|
20
|
+
_ref$menuWidth = _ref.menuWidth,
|
|
21
|
+
menuWidth = _ref$menuWidth === void 0 ? '100%' : _ref$menuWidth;
|
|
22
|
+
var theme = useTheme();
|
|
23
|
+
var reactSelectTheme = useReactSelectThemeOverride();
|
|
24
|
+
|
|
25
|
+
// Use the same text styling as combobox
|
|
26
|
+
var _useText = useText({
|
|
27
|
+
baseline: false,
|
|
28
|
+
tone: 'neutral',
|
|
29
|
+
size: 'standard',
|
|
30
|
+
weight: 'regular'
|
|
31
|
+
}),
|
|
32
|
+
_useText2 = _slicedToArray(_useText, 2),
|
|
33
|
+
responsiveTextStyles = _useText2[0],
|
|
34
|
+
textStyles = _useText2[1];
|
|
35
|
+
var focusRingStyles = useFocusRing({
|
|
36
|
+
always: true
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Handle option selection - trigger the onClick callback
|
|
40
|
+
var handleChange = function handleChange(selectedOption) {
|
|
41
|
+
if (selectedOption !== null && selectedOption !== void 0 && selectedOption.onClick) {
|
|
42
|
+
selectedOption.onClick(selectedOption.data);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Custom components
|
|
47
|
+
var customComponents = {
|
|
48
|
+
DropdownIndicator: function DropdownIndicator(props) {
|
|
49
|
+
return jsx(components.DropdownIndicator, _objectSpread(_objectSpread({}, props), {}, {
|
|
50
|
+
children: jsx(ChevronDownIcon, {
|
|
51
|
+
size: "xxsmall",
|
|
52
|
+
tone: "muted"
|
|
53
|
+
})
|
|
54
|
+
}));
|
|
55
|
+
},
|
|
56
|
+
IndicatorSeparator: function IndicatorSeparator() {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Custom styles with text styling from combobox
|
|
62
|
+
var customStyles = {
|
|
63
|
+
control: function control(provided, state) {
|
|
64
|
+
var _theme$components$tex, _theme$components$tex2, _theme$components$tex3, _theme$components$tex4, _theme$components$tex5, _theme$components$tex6, _theme$components$tex7;
|
|
65
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
66
|
+
borderRadius: '24px',
|
|
67
|
+
minHeight: '48px',
|
|
68
|
+
paddingLeft: '16px',
|
|
69
|
+
paddingRight: '8px',
|
|
70
|
+
cursor: 'pointer',
|
|
71
|
+
width: controlWidth || 'auto',
|
|
72
|
+
minWidth: controlWidth || 'auto',
|
|
73
|
+
marginLeft: 'auto'
|
|
74
|
+
}, {
|
|
75
|
+
borderColor: (_theme$components$tex = theme.components.textInput) === null || _theme$components$tex === void 0 ? void 0 : _theme$components$tex.borderColor
|
|
76
|
+
}), state.isFocused ? (_theme$components$tex2 = (_theme$components$tex3 = theme.components.textInput) === null || _theme$components$tex3 === void 0 ? void 0 : _theme$components$tex3.focused) !== null && _theme$components$tex2 !== void 0 ? _theme$components$tex2 : focusRingStyles : (_theme$components$tex4 = theme.components.textInput) !== null && _theme$components$tex4 !== void 0 && _theme$components$tex4.boxShadow ? {
|
|
77
|
+
boxShadow: (_theme$components$tex5 = theme.components.textInput) === null || _theme$components$tex5 === void 0 ? void 0 : _theme$components$tex5.boxShadow
|
|
78
|
+
} : {}), (_theme$components$tex6 = theme.components.textInput) !== null && _theme$components$tex6 !== void 0 && _theme$components$tex6.hover ? {
|
|
79
|
+
':hover': (_theme$components$tex7 = theme.components.textInput) === null || _theme$components$tex7 === void 0 ? void 0 : _theme$components$tex7.hover
|
|
80
|
+
} : {});
|
|
81
|
+
},
|
|
82
|
+
dropdownIndicator: function dropdownIndicator(provided, state) {
|
|
83
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
84
|
+
transitionProperty: 'transform',
|
|
85
|
+
transitionTimingFunction: 'linear',
|
|
86
|
+
transitionDuration: '150ms'
|
|
87
|
+
}, state.isFocused ? {
|
|
88
|
+
transform: 'rotate(180deg)'
|
|
89
|
+
} : {});
|
|
90
|
+
},
|
|
91
|
+
singleValue: function singleValue(provided) {
|
|
92
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
93
|
+
fontWeight: '500',
|
|
94
|
+
color: 'inherit' // Use inherited text color
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
option: function option(provided, state) {
|
|
98
|
+
var _theme$components$tex8, _theme$components$tex9, _theme$components$tex0, _theme$components$tex1, _theme$components$tex10;
|
|
99
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, provided), responsiveTextStyles), textStyles), {}, {
|
|
100
|
+
backgroundColor: 'transparent',
|
|
101
|
+
// Remove default background
|
|
102
|
+
color: 'inherit',
|
|
103
|
+
// Use inherited text color
|
|
104
|
+
borderRadius: (_theme$components$tex8 = theme.components.textInput) === null || _theme$components$tex8 === void 0 || (_theme$components$tex8 = _theme$components$tex8.menuOption) === null || _theme$components$tex8 === void 0 ? void 0 : _theme$components$tex8.borderRadius
|
|
105
|
+
}, state.isSelected && {
|
|
106
|
+
backgroundColor: (_theme$components$tex9 = theme.components.textInput) === null || _theme$components$tex9 === void 0 || (_theme$components$tex9 = _theme$components$tex9.menuOption) === null || _theme$components$tex9 === void 0 || (_theme$components$tex9 = _theme$components$tex9.selected) === null || _theme$components$tex9 === void 0 ? void 0 : _theme$components$tex9.backgroundColor,
|
|
107
|
+
color: (_theme$components$tex0 = theme.components.textInput) === null || _theme$components$tex0 === void 0 || (_theme$components$tex0 = _theme$components$tex0.menuOption) === null || _theme$components$tex0 === void 0 || (_theme$components$tex0 = _theme$components$tex0.selected) === null || _theme$components$tex0 === void 0 ? void 0 : _theme$components$tex0.color
|
|
108
|
+
}), state.isFocused && {
|
|
109
|
+
backgroundColor: (_theme$components$tex1 = theme.components.textInput) === null || _theme$components$tex1 === void 0 || (_theme$components$tex1 = _theme$components$tex1.menuOption) === null || _theme$components$tex1 === void 0 || (_theme$components$tex1 = _theme$components$tex1.focused) === null || _theme$components$tex1 === void 0 ? void 0 : _theme$components$tex1.backgroundColor,
|
|
110
|
+
color: 'inherit'
|
|
111
|
+
}), {}, {
|
|
112
|
+
'&:active': {
|
|
113
|
+
backgroundColor: (_theme$components$tex10 = theme.components.textInput) === null || _theme$components$tex10 === void 0 || (_theme$components$tex10 = _theme$components$tex10.menuOption) === null || _theme$components$tex10 === void 0 || (_theme$components$tex10 = _theme$components$tex10.active) === null || _theme$components$tex10 === void 0 ? void 0 : _theme$components$tex10.backgroundColor
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
menu: function menu(provided) {
|
|
118
|
+
var _theme$components$tex11, _theme$components$tex12, _theme$components$tex13;
|
|
119
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
120
|
+
width: menuWidth,
|
|
121
|
+
minWidth: menuWidth,
|
|
122
|
+
padding: (_theme$components$tex11 = theme.components.textInput) === null || _theme$components$tex11 === void 0 || (_theme$components$tex11 = _theme$components$tex11.menu) === null || _theme$components$tex11 === void 0 ? void 0 : _theme$components$tex11.padding,
|
|
123
|
+
boxShadow: (_theme$components$tex12 = theme.components.textInput) === null || _theme$components$tex12 === void 0 || (_theme$components$tex12 = _theme$components$tex12.menu) === null || _theme$components$tex12 === void 0 ? void 0 : _theme$components$tex12.boxShadow,
|
|
124
|
+
borderRadius: (_theme$components$tex13 = theme.components.textInput) === null || _theme$components$tex13 === void 0 || (_theme$components$tex13 = _theme$components$tex13.menu) === null || _theme$components$tex13 === void 0 ? void 0 : _theme$components$tex13.borderRadius
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
menuList: function menuList(provided) {
|
|
128
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
129
|
+
padding: 0,
|
|
130
|
+
display: 'flex',
|
|
131
|
+
flexDirection: 'column',
|
|
132
|
+
gap: theme.spacing.xsmall
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
return jsx(ReactSelect, {
|
|
137
|
+
value: {
|
|
138
|
+
label: label,
|
|
139
|
+
value: 'current'
|
|
140
|
+
},
|
|
141
|
+
options: actions,
|
|
142
|
+
onChange: handleChange,
|
|
143
|
+
isDisabled: disabled,
|
|
144
|
+
isSearchable: false,
|
|
145
|
+
components: customComponents,
|
|
146
|
+
styles: _objectSpread(_objectSpread({}, customStyles), {}, {
|
|
147
|
+
menuPortal: function menuPortal(provided) {
|
|
148
|
+
return _objectSpread(_objectSpread({}, provided), {}, {
|
|
149
|
+
zIndex: theme.elevation.modal,
|
|
150
|
+
pointerEvents: 'all'
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}),
|
|
154
|
+
menuPortalTarget: menuPortalTarget !== null && menuPortalTarget !== void 0 ? menuPortalTarget : isBrowser ? document.body : undefined,
|
|
155
|
+
blurInputOnSelect: true,
|
|
156
|
+
closeMenuOnSelect: true,
|
|
157
|
+
theme: reactSelectTheme
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export { ActionDropdown };
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spark-web/action-dropdown",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"homepage": "https://github.com/brighte-labs/spark-web#readme",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/brighte-labs/spark-web.git",
|
|
8
|
+
"directory": "packages/action-dropdown"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/spark-web-action-dropdown.cjs.js",
|
|
11
|
+
"module": "dist/spark-web-action-dropdown.esm.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"CHANGELOG.md",
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@babel/runtime": "^7.25.0",
|
|
19
|
+
"@emotion/react": "^11.14.0",
|
|
20
|
+
"@spark-web/a11y": "^5.3.0",
|
|
21
|
+
"@spark-web/box": "^6.0.0",
|
|
22
|
+
"@spark-web/combobox": "^6.0.0",
|
|
23
|
+
"@spark-web/icon": "^5.1.0",
|
|
24
|
+
"@spark-web/text": "^5.3.0",
|
|
25
|
+
"@spark-web/utils": "^5.1.0",
|
|
26
|
+
"react-select": "^5.4.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@spark-web/theme": "^5.13.0",
|
|
30
|
+
"@types/react": "^19.1.0",
|
|
31
|
+
"react": "^19.1.0"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@spark-web/theme": "^5.13.0",
|
|
35
|
+
"react": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=14"
|
|
39
|
+
}
|
|
40
|
+
}
|