@jobber/components 2.87.0 → 2.88.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.
- package/CHANGELOG.md +11 -0
- package/MultiSelect.d.ts +1 -0
- package/MultiSelect.js +17 -0
- package/dist/Checkbox/Checkbox.d.ts +2 -1
- package/dist/Checkbox/index.js +7 -37
- package/dist/Checkbox-785a79a5.js +42 -0
- package/dist/MultiSelect/DropDownMenu.d.ts +15 -0
- package/dist/MultiSelect/MultiSelect.d.ts +22 -0
- package/dist/MultiSelect/index.d.ts +1 -0
- package/dist/MultiSelect/index.js +197 -0
- package/dist/MultiSelect/types.d.ts +13 -0
- package/dist/MultiSelect/utils.d.ts +3 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,17 @@ menu: Changelog
|
|
|
8
8
|
All notable changes to this project will be documented in this file.
|
|
9
9
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
10
10
|
|
|
11
|
+
# [2.88.0](https://github.com/GetJobber/atlantis/compare/@jobber/components@2.87.0...@jobber/components@2.88.0) (2022-11-16)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **components:** MultiSelect component ([#932](https://github.com/GetJobber/atlantis/issues/932)) ([c47a80d](https://github.com/GetJobber/atlantis/commit/c47a80d55dbfb72815386e699cda30e44fe8d9fc))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
11
22
|
# [2.87.0](https://github.com/GetJobber/atlantis/compare/@jobber/components@2.86.2...@jobber/components@2.87.0) (2022-11-02)
|
|
12
23
|
|
|
13
24
|
|
package/MultiSelect.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./dist/MultiSelect";
|
package/MultiSelect.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var MultiSelect = require("./dist/MultiSelect");
|
|
8
|
+
|
|
9
|
+
Object.keys(MultiSelect).forEach(function(key) {
|
|
10
|
+
if (key === "default" || key === "__esModule") return;
|
|
11
|
+
Object.defineProperty(exports, key, {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function get() {
|
|
14
|
+
return MultiSelect[key];
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -34,6 +34,7 @@ interface BaseCheckboxProps {
|
|
|
34
34
|
*/
|
|
35
35
|
readonly description?: string;
|
|
36
36
|
onChange?(newValue: boolean): void;
|
|
37
|
+
onFocus?(): void;
|
|
37
38
|
}
|
|
38
39
|
interface CheckboxLabelProps extends BaseCheckboxProps {
|
|
39
40
|
/**
|
|
@@ -48,5 +49,5 @@ interface CheckboxChildrenProps extends BaseCheckboxProps {
|
|
|
48
49
|
readonly children?: ReactElement;
|
|
49
50
|
}
|
|
50
51
|
declare type CheckboxProps = XOR<CheckboxLabelProps, CheckboxChildrenProps>;
|
|
51
|
-
export declare function Checkbox({ checked, defaultChecked, disabled, label, name, value, indeterminate, description, children, onChange, }: CheckboxProps): JSX.Element;
|
|
52
|
+
export declare function Checkbox({ checked, defaultChecked, disabled, label, name, value, indeterminate, description, children, onChange, onFocus, }: CheckboxProps): JSX.Element;
|
|
52
53
|
export {};
|
package/dist/Checkbox/index.js
CHANGED
|
@@ -2,46 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
var Checkbox = require('../Checkbox-785a79a5.js');
|
|
6
|
+
require('react');
|
|
7
|
+
require('classnames');
|
|
8
|
+
require('../style-inject.es-dcee06b6.js');
|
|
9
|
+
require('../Icon-d5ad1a6d.js');
|
|
10
10
|
require('@jobber/design');
|
|
11
|
+
require('../Text-9bc093e9.js');
|
|
11
12
|
require('../Typography-7e542a72.js');
|
|
12
13
|
require('../tslib.es6-5b50eb8e.js');
|
|
13
14
|
|
|
14
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
15
15
|
|
|
16
|
-
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
17
|
-
var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
var styles = {"checkbox":"_2y-hp0B8BHvB6C7hj0uluY","wrapper":"_36KUbFCcSPE7xHQsQ4PC2D","disabled":"Kvt2p9_Z8Ln_jkPQEYuMI","checkHolder":"_3MnEDfs7rk_9yjl2XNHSuc","input":"MEL3ANaAvLYMAoMbYSmCb","checkBox":"_1T-pYuzX7l9EyzvIri_U22","indeterminate":"_3TAyEYP42fVPKOg97qm5Ue","label":"C10gHWu17R4Nw-PFWmtvT","description":"_1wsib2K8k6XRKTFbeIeq4n"};
|
|
21
|
-
styleInject_es.styleInject(css);
|
|
22
|
-
|
|
23
|
-
function Checkbox(_a) {
|
|
24
|
-
var _b;
|
|
25
|
-
var checked = _a.checked, defaultChecked = _a.defaultChecked, disabled = _a.disabled, label = _a.label, name = _a.name, value = _a.value, _c = _a.indeterminate, indeterminate = _c === void 0 ? false : _c, description = _a.description, children = _a.children, onChange = _a.onChange;
|
|
26
|
-
var wrapperClassName = classnames__default["default"](styles.wrapper, disabled && styles.disabled);
|
|
27
|
-
var inputClassName = classnames__default["default"](styles.input, (_b = {},
|
|
28
|
-
_b[styles.indeterminate] = indeterminate,
|
|
29
|
-
_b));
|
|
30
|
-
var iconName = indeterminate ? "minus2" : "checkmark";
|
|
31
|
-
var labelText = label ? React__default["default"].createElement(Text.Text, null, label) : children;
|
|
32
|
-
return (React__default["default"].createElement("div", { className: styles.checkbox },
|
|
33
|
-
React__default["default"].createElement("label", { className: wrapperClassName },
|
|
34
|
-
React__default["default"].createElement("span", { className: styles.checkHolder },
|
|
35
|
-
React__default["default"].createElement("input", { type: "checkbox", checked: checked, defaultChecked: defaultChecked, className: inputClassName, "aria-label": label, onChange: handleChange, value: value, name: name, disabled: disabled }),
|
|
36
|
-
React__default["default"].createElement("span", { className: styles.checkBox },
|
|
37
|
-
React__default["default"].createElement(Icon.Icon, { name: iconName, size: "small", color: "white" }))),
|
|
38
|
-
labelText && React__default["default"].createElement("span", { className: styles.label }, labelText)),
|
|
39
|
-
description && (React__default["default"].createElement("div", { className: styles.description },
|
|
40
|
-
React__default["default"].createElement(Text.Text, { variation: "subdued", size: "small" }, description)))));
|
|
41
|
-
function handleChange(event) {
|
|
42
|
-
var newChecked = event.currentTarget.checked;
|
|
43
|
-
onChange && onChange(newChecked);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
exports.Checkbox = Checkbox;
|
|
17
|
+
exports.Checkbox = Checkbox.Checkbox;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var classnames = require('classnames');
|
|
5
|
+
var styleInject_es = require('./style-inject.es-dcee06b6.js');
|
|
6
|
+
var Icon = require('./Icon-d5ad1a6d.js');
|
|
7
|
+
var Text = require('./Text-9bc093e9.js');
|
|
8
|
+
|
|
9
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
10
|
+
|
|
11
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
12
|
+
var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
|
|
13
|
+
|
|
14
|
+
var css = "._2y-hp0B8BHvB6C7hj0uluY {\n display: inline-block;\n}\n\n._36KUbFCcSPE7xHQsQ4PC2D {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n cursor: pointer;\n}\n\n.Kvt2p9_Z8Ln_jkPQEYuMI {\n cursor: not-allowed;\n}\n\n._3MnEDfs7rk_9yjl2XNHSuc {\n position: relative;\n}\n\n.MEL3ANaAvLYMAoMbYSmCb {\n /* Hide checkbox on UI but not screen readers and still allow focus state */\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n -webkit-clip-path: inset(100%);\n clip-path: inset(100%);\n white-space: nowrap;\n}\n\n._1T-pYuzX7l9EyzvIri_U22 {\n display: -ms-flexbox;\n display: flex;\n width: var(--space-base);\n height: var(--space-base);\n box-sizing: border-box;\n border: var(--border-thick) solid var(--color-interactive);\n border-radius: var(--radius-base);\n background-color: var(--color-surface);\n transition: all 200ms;\n -ms-flex-pack: center;\n justify-content: center;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.Kvt2p9_Z8Ln_jkPQEYuMI ._1T-pYuzX7l9EyzvIri_U22 {\n border-color: var(--color-disabled--secondary);\n}\n\n.Kvt2p9_Z8Ln_jkPQEYuMI p {\n color: var(--color-disabled);\n}\n\n.Kvt2p9_Z8Ln_jkPQEYuMI ._1T-pYuzX7l9EyzvIri_U22 > * {\n opacity: 0;\n}\n\n.MEL3ANaAvLYMAoMbYSmCb._3TAyEYP42fVPKOg97qm5Ue + ._1T-pYuzX7l9EyzvIri_U22,\n.MEL3ANaAvLYMAoMbYSmCb:checked + ._1T-pYuzX7l9EyzvIri_U22 {\n border-color: var(--color-interactive);\n background-color: var(--color-interactive);\n}\n\n.MEL3ANaAvLYMAoMbYSmCb:focus + ._1T-pYuzX7l9EyzvIri_U22 {\n box-shadow: var(--shadow-focus);\n}\n\n.Kvt2p9_Z8Ln_jkPQEYuMI .MEL3ANaAvLYMAoMbYSmCb._3TAyEYP42fVPKOg97qm5Ue + ._1T-pYuzX7l9EyzvIri_U22,\n.Kvt2p9_Z8Ln_jkPQEYuMI .MEL3ANaAvLYMAoMbYSmCb:checked + ._1T-pYuzX7l9EyzvIri_U22 {\n border-color: var(--color-disabled--secondary);\n background-color: var(--color-disabled--secondary);\n}\n\n.Kvt2p9_Z8Ln_jkPQEYuMI .MEL3ANaAvLYMAoMbYSmCb._3TAyEYP42fVPKOg97qm5Ue + ._1T-pYuzX7l9EyzvIri_U22 > *,\n.Kvt2p9_Z8Ln_jkPQEYuMI .MEL3ANaAvLYMAoMbYSmCb:checked + ._1T-pYuzX7l9EyzvIri_U22 > * {\n opacity: 1;\n}\n\n.C10gHWu17R4Nw-PFWmtvT {\n margin: 0 var(--space-small);\n}\n\n._1wsib2K8k6XRKTFbeIeq4n {\n margin-bottom: var(--space-small);\n padding-left: var(--space-large);\n}\n";
|
|
15
|
+
var styles = {"checkbox":"_2y-hp0B8BHvB6C7hj0uluY","wrapper":"_36KUbFCcSPE7xHQsQ4PC2D","disabled":"Kvt2p9_Z8Ln_jkPQEYuMI","checkHolder":"_3MnEDfs7rk_9yjl2XNHSuc","input":"MEL3ANaAvLYMAoMbYSmCb","checkBox":"_1T-pYuzX7l9EyzvIri_U22","indeterminate":"_3TAyEYP42fVPKOg97qm5Ue","label":"C10gHWu17R4Nw-PFWmtvT","description":"_1wsib2K8k6XRKTFbeIeq4n"};
|
|
16
|
+
styleInject_es.styleInject(css);
|
|
17
|
+
|
|
18
|
+
function Checkbox(_a) {
|
|
19
|
+
var _b;
|
|
20
|
+
var checked = _a.checked, defaultChecked = _a.defaultChecked, disabled = _a.disabled, label = _a.label, name = _a.name, value = _a.value, _c = _a.indeterminate, indeterminate = _c === void 0 ? false : _c, description = _a.description, children = _a.children, onChange = _a.onChange, onFocus = _a.onFocus;
|
|
21
|
+
var wrapperClassName = classnames__default["default"](styles.wrapper, disabled && styles.disabled);
|
|
22
|
+
var inputClassName = classnames__default["default"](styles.input, (_b = {},
|
|
23
|
+
_b[styles.indeterminate] = indeterminate,
|
|
24
|
+
_b));
|
|
25
|
+
var iconName = indeterminate ? "minus2" : "checkmark";
|
|
26
|
+
var labelText = label ? React__default["default"].createElement(Text.Text, null, label) : children;
|
|
27
|
+
return (React__default["default"].createElement("div", { className: styles.checkbox },
|
|
28
|
+
React__default["default"].createElement("label", { className: wrapperClassName },
|
|
29
|
+
React__default["default"].createElement("span", { className: styles.checkHolder },
|
|
30
|
+
React__default["default"].createElement("input", { type: "checkbox", checked: checked, defaultChecked: defaultChecked, className: inputClassName, "aria-label": label, onChange: handleChange, value: value, name: name, disabled: disabled, onFocus: onFocus }),
|
|
31
|
+
React__default["default"].createElement("span", { className: styles.checkBox },
|
|
32
|
+
React__default["default"].createElement(Icon.Icon, { name: iconName, size: "small", color: "white" }))),
|
|
33
|
+
labelText && React__default["default"].createElement("span", { className: styles.label }, labelText)),
|
|
34
|
+
description && (React__default["default"].createElement("div", { className: styles.description },
|
|
35
|
+
React__default["default"].createElement(Text.Text, { variation: "subdued", size: "small" }, description)))));
|
|
36
|
+
function handleChange(event) {
|
|
37
|
+
var newChecked = event.currentTarget.checked;
|
|
38
|
+
onChange && onChange(newChecked);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
exports.Checkbox = Checkbox;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { Dispatch } from "react";
|
|
2
|
+
import { Options } from "./types";
|
|
3
|
+
interface DropDownMenuProps {
|
|
4
|
+
/**
|
|
5
|
+
* List of options to be selected
|
|
6
|
+
* @default false
|
|
7
|
+
*/
|
|
8
|
+
readonly options: Options;
|
|
9
|
+
/**
|
|
10
|
+
* Change handler.
|
|
11
|
+
*/
|
|
12
|
+
setOptions: Dispatch<React.SetStateAction<Options>>;
|
|
13
|
+
}
|
|
14
|
+
export declare function DropDownMenu({ options, setOptions }: DropDownMenuProps): JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { Dispatch } from "react";
|
|
2
|
+
import { Options } from "./types";
|
|
3
|
+
interface MultiSelectProps {
|
|
4
|
+
/**
|
|
5
|
+
* The label to be displayed by default when no options are selected
|
|
6
|
+
*/
|
|
7
|
+
readonly defaultLabel: string;
|
|
8
|
+
/**
|
|
9
|
+
* The label to be displayed when all options are selected
|
|
10
|
+
*/
|
|
11
|
+
readonly allSelectedLabel: string;
|
|
12
|
+
/**
|
|
13
|
+
* List of options to be checked
|
|
14
|
+
*/
|
|
15
|
+
readonly options: Options;
|
|
16
|
+
/**
|
|
17
|
+
* Change handler
|
|
18
|
+
*/
|
|
19
|
+
onOptionsChange: Dispatch<React.SetStateAction<Options>>;
|
|
20
|
+
}
|
|
21
|
+
export declare function MultiSelect({ defaultLabel, allSelectedLabel, options, onOptionsChange, }: MultiSelectProps): JSX.Element;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MultiSelect } from "./MultiSelect";
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib_es6 = require('../tslib.es6-5b50eb8e.js');
|
|
6
|
+
var React = require('react');
|
|
7
|
+
var classnames = require('classnames');
|
|
8
|
+
var hooks = require('@jobber/hooks');
|
|
9
|
+
var styleInject_es = require('../style-inject.es-dcee06b6.js');
|
|
10
|
+
var Checkbox = require('../Checkbox-785a79a5.js');
|
|
11
|
+
var Text = require('../Text-9bc093e9.js');
|
|
12
|
+
var Icon = require('../Icon-d5ad1a6d.js');
|
|
13
|
+
require('../Typography-7e542a72.js');
|
|
14
|
+
require('@jobber/design');
|
|
15
|
+
|
|
16
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
17
|
+
|
|
18
|
+
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
19
|
+
var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
|
|
20
|
+
|
|
21
|
+
var css$1 = "._5SXg5kHN1rObHmXNp_iaJ {\n position: relative;\n width: 100%;\n}\n\n._3DcjSBXtI1-sptltr_DPIh {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: row;\n flex-direction: row;\n -ms-flex-pack: justify;\n justify-content: space-between;\n -ms-flex-align: center;\n align-items: center;\n padding-top: calc(var(--space-base) - var(--space-smallest));\n padding-bottom: calc(var(--space-base) - var(--space-smallest));\n padding-left: var(--space-base);\n padding-right: var(--space-base);\n border: var(--border-base) solid var(--color-border);\n border-radius: var(--radius-base);\n}\n\n._3DcjSBXtI1-sptltr_DPIh p {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n._5SXg5kHN1rObHmXNp_iaJ:hover,\n._5SXg5kHN1rObHmXNp_iaJ._3DcjSBXtI1-sptltr_DPIh {\n cursor: pointer;\n caret-color: transparent;\n}\n\n._3DcjSBXtI1-sptltr_DPIh:focus,\n._3DcjSBXtI1-sptltr_DPIh.y1fw0Iy-QRJk5kSWc6TU {\n box-shadow: var(--shadow-focus);\n outline: none;\n}\n";
|
|
22
|
+
var styles$1 = {"multiSelectContainer":"_5SXg5kHN1rObHmXNp_iaJ","multiSelect":"_3DcjSBXtI1-sptltr_DPIh","active":"y1fw0Iy-QRJk5kSWc6TU"};
|
|
23
|
+
styleInject_es.styleInject(css$1);
|
|
24
|
+
|
|
25
|
+
var css = "._3fnWzTcXADLV1Cck8AvQXx {\n display: -ms-flexbox;\n display: flex;\n position: absolute;\n z-index: var(--elevation-menu);\n width: 100%;\n max-height: calc(var(--space-extravagant) * 5);\n box-shadow: var(--shadow-base);\n margin: 0;\n padding: 0;\n border: var(--border-base) solid var(--color-border);\n border-radius: var(--radius-large);\n overflow: auto;\n background-color: var(--color-surface);\n -ms-flex-direction: column;\n flex-direction: column;\n scroll-behavior: smooth;\n}\n\n._3fnWzTcXADLV1Cck8AvQXx li {\n list-style: none;\n}\n\n._1ujGx9WtIEWz5g_6vsrhJM {\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n padding: var(--space-small) var(--space-base);\n cursor: pointer;\n transition: all var(--timing-base);\n}\n\n._1ujGx9WtIEWz5g_6vsrhJM:focus,\n._1ujGx9WtIEWz5g_6vsrhJM._3X26eN0ET6mLwNPXpC98so {\n background-color: var(--color-surface--hover);\n outline-color: var(--color-focus);\n}\n";
|
|
26
|
+
var styles = {"dropDownMenuContainer":"_3fnWzTcXADLV1Cck8AvQXx","option":"_1ujGx9WtIEWz5g_6vsrhJM","active":"_3X26eN0ET6mLwNPXpC98so"};
|
|
27
|
+
styleInject_es.styleInject(css);
|
|
28
|
+
|
|
29
|
+
function handleKeyboardShortcut(setupKeyListeners) {
|
|
30
|
+
function callback(event) {
|
|
31
|
+
var metaKey = event.metaKey, ctrlKey = event.ctrlKey, key = event.key, target = event.target;
|
|
32
|
+
var shouldTriggerShortcut = target instanceof HTMLButtonElement ? metaKey || ctrlKey : true;
|
|
33
|
+
if (!shouldTriggerShortcut)
|
|
34
|
+
return;
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
event.stopPropagation();
|
|
37
|
+
setupKeyListeners(key);
|
|
38
|
+
}
|
|
39
|
+
return { callback: callback };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function DropDownMenu(_a) {
|
|
43
|
+
var options = _a.options, setOptions = _a.setOptions;
|
|
44
|
+
var _b = tslib_es6.__read(React.useState(0), 2), highlightedIndex = _b[0], setHighlightedIndex = _b[1];
|
|
45
|
+
var menuDiv = React.useRef();
|
|
46
|
+
var handleOptionClick = React.useCallback(function (clickedOption) {
|
|
47
|
+
setOptions(function (current) {
|
|
48
|
+
return current.map(function (option) {
|
|
49
|
+
if (option.label == clickedOption.label) {
|
|
50
|
+
return tslib_es6.__assign(tslib_es6.__assign({}, option), { checked: !clickedOption.checked });
|
|
51
|
+
}
|
|
52
|
+
return option;
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}, []);
|
|
56
|
+
function handleOptionHover(event, index) {
|
|
57
|
+
event.preventDefault();
|
|
58
|
+
setHighlightedIndex(index);
|
|
59
|
+
}
|
|
60
|
+
function handleOptionFocus(index) {
|
|
61
|
+
setHighlightedIndex(index);
|
|
62
|
+
if (menuDiv.current) {
|
|
63
|
+
var option = menuDiv.current.children[index].querySelector("input");
|
|
64
|
+
option === null || option === void 0 ? void 0 : option.focus();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function scrollMenuIfItemNotInView(menuDivElement, direction) {
|
|
68
|
+
var itemDiv = menuDivElement.querySelector(":nth-child(" + (highlightedIndex + 1) + ")");
|
|
69
|
+
if (!itemDiv)
|
|
70
|
+
return;
|
|
71
|
+
var menuTop = menuDivElement.getBoundingClientRect().top;
|
|
72
|
+
var _a = itemDiv.getBoundingClientRect(), itemTop = _a.top, itemHeight = _a.height, itemBottom = _a.bottom;
|
|
73
|
+
var itemTrueBottom = itemBottom + itemHeight;
|
|
74
|
+
var menuBottom = menuDivElement.getBoundingClientRect().bottom;
|
|
75
|
+
if (direction == "up" && itemTop - itemHeight < menuTop) {
|
|
76
|
+
menuDivElement.scrollTop -= itemHeight;
|
|
77
|
+
}
|
|
78
|
+
else if (direction == "down" && itemTrueBottom > menuBottom) {
|
|
79
|
+
menuDivElement.scrollTop += itemHeight;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function setupKeyListeners(key) {
|
|
83
|
+
switch (key) {
|
|
84
|
+
case "Enter":
|
|
85
|
+
case " ": {
|
|
86
|
+
if (highlightedIndex >= 0) {
|
|
87
|
+
handleOptionClick(options[highlightedIndex]);
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case "ArrowDown": {
|
|
92
|
+
var newIndex = Math.min(options.length - 1, highlightedIndex + 1);
|
|
93
|
+
handleOptionFocus(newIndex);
|
|
94
|
+
scrollMenuIfItemNotInView(menuDiv.current, "down");
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case "ArrowUp": {
|
|
98
|
+
var newIndex = Math.max(0, highlightedIndex - 1);
|
|
99
|
+
handleOptionFocus(newIndex);
|
|
100
|
+
scrollMenuIfItemNotInView(menuDiv.current, "up");
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
hooks.useOnKeyDown(handleKeyboardShortcut(setupKeyListeners).callback, [
|
|
106
|
+
"Enter",
|
|
107
|
+
" ",
|
|
108
|
+
"ArrowDown",
|
|
109
|
+
"ArrowUp",
|
|
110
|
+
]);
|
|
111
|
+
React.useEffect(function () {
|
|
112
|
+
// focus first option
|
|
113
|
+
handleOptionFocus(0);
|
|
114
|
+
}, [menuDiv]);
|
|
115
|
+
return (React__default["default"].createElement("ul", { "data-testid": "dropdown-menu", className: styles.dropDownMenuContainer, ref: menuDiv }, options.map(function (option, index) {
|
|
116
|
+
var _a;
|
|
117
|
+
var optionClass = classnames__default["default"](styles.option, (_a = {},
|
|
118
|
+
_a[styles.active] = index === highlightedIndex,
|
|
119
|
+
_a));
|
|
120
|
+
return (React__default["default"].createElement("li", { key: index + "-" + option.label, className: optionClass, onClick: function (event) {
|
|
121
|
+
event.stopPropagation();
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
handleOptionClick(option);
|
|
124
|
+
}, onMouseOver: function (e) { return handleOptionHover(e, index); } },
|
|
125
|
+
React__default["default"].createElement(Checkbox.Checkbox, { label: option.label, checked: option.checked, onFocus: function () { return setHighlightedIndex(index); } })));
|
|
126
|
+
})));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// eslint-disable-next-line max-statements
|
|
130
|
+
function MultiSelect(_a) {
|
|
131
|
+
var _b;
|
|
132
|
+
var defaultLabel = _a.defaultLabel, allSelectedLabel = _a.allSelectedLabel, options = _a.options, onOptionsChange = _a.onOptionsChange;
|
|
133
|
+
var _c = tslib_es6.__read(React.useState(defaultLabel), 2), label = _c[0], setLabel = _c[1];
|
|
134
|
+
var _d = tslib_es6.__read(React.useState(false), 2), menuVisible = _d[0], setMenuVisible = _d[1];
|
|
135
|
+
var _e = tslib_es6.__read(React.useState(false), 2), focused = _e[0], setFocused = _e[1];
|
|
136
|
+
var multiSelectContainer = React.useRef();
|
|
137
|
+
var multiSelectRef = React.useRef();
|
|
138
|
+
var multiSelectClass = classnames__default["default"](styles$1.multiSelect, (_b = {},
|
|
139
|
+
_b[styles$1.active] = menuVisible,
|
|
140
|
+
_b));
|
|
141
|
+
function handleMenuVisibility() {
|
|
142
|
+
multiSelectRef.current.focus();
|
|
143
|
+
setMenuVisible(!menuVisible);
|
|
144
|
+
}
|
|
145
|
+
var handleClickOutside = function (e) {
|
|
146
|
+
var _a;
|
|
147
|
+
if (!((_a = multiSelectContainer === null || multiSelectContainer === void 0 ? void 0 : multiSelectContainer.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
|
|
148
|
+
setMenuVisible(false);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
function setupKeyListeners(key) {
|
|
152
|
+
switch (key) {
|
|
153
|
+
case "Enter":
|
|
154
|
+
case " ": {
|
|
155
|
+
if (focused) {
|
|
156
|
+
setMenuVisible(!menuVisible);
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case "Escape": {
|
|
161
|
+
multiSelectRef.current.focus();
|
|
162
|
+
setMenuVisible(false);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
hooks.useOnKeyDown(handleKeyboardShortcut(setupKeyListeners).callback, [
|
|
168
|
+
"Enter",
|
|
169
|
+
" ",
|
|
170
|
+
"Escape",
|
|
171
|
+
]);
|
|
172
|
+
React.useEffect(function () {
|
|
173
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
174
|
+
return function () { return document.removeEventListener("mousedown", handleClickOutside); };
|
|
175
|
+
});
|
|
176
|
+
React.useEffect(function () {
|
|
177
|
+
var selected = options.filter(function (option) { return option.checked; });
|
|
178
|
+
if (selected.length === 0) {
|
|
179
|
+
setLabel(defaultLabel);
|
|
180
|
+
}
|
|
181
|
+
else if (selected.length == options.length) {
|
|
182
|
+
setLabel(allSelectedLabel);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
var selectedLabels_1 = [];
|
|
186
|
+
selected.forEach(function (option) { return selectedLabels_1.push(option.label); });
|
|
187
|
+
setLabel(selectedLabels_1.join(", "));
|
|
188
|
+
}
|
|
189
|
+
}, [options]);
|
|
190
|
+
return (React__default["default"].createElement("div", { ref: multiSelectContainer, className: styles$1.multiSelectContainer },
|
|
191
|
+
React__default["default"].createElement("div", { "data-testid": "multi-select", className: multiSelectClass, onClick: handleMenuVisibility, onFocus: function () { return setFocused(true); }, onBlur: function () { return setFocused(false); }, tabIndex: 0, ref: multiSelectRef, role: "button", "aria-label": defaultLabel + ": " + label, "aria-multiselectable": true, "aria-haspopup": true },
|
|
192
|
+
React__default["default"].createElement(Text.Text, null, label),
|
|
193
|
+
React__default["default"].createElement(Icon.Icon, { name: "arrowDown" })),
|
|
194
|
+
menuVisible && (React__default["default"].createElement(DropDownMenu, { options: options, setOptions: onOptionsChange }))));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
exports.MultiSelect = MultiSelect;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.88.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"> 1%",
|
|
85
85
|
"IE 10"
|
|
86
86
|
],
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "15a72adbab0696fe4908f2d72bfd5071c7481284"
|
|
88
88
|
}
|