@spaced-out/ui-design-system 0.0.19 → 0.0.20

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 CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.0.20](https://github.com/spaced-out/ui-design-system/compare/v0.0.19...v0.0.20) (2023-02-08)
6
+
7
+
8
+ ### Features
9
+
10
+ * added flow checks in pre commit hook ([e60677c](https://github.com/spaced-out/ui-design-system/commit/e60677c1f7e7c8eb688485eddda04223fef397cd))
11
+ * composemenu and separated menuoptionsbutton ([#58](https://github.com/spaced-out/ui-design-system/issues/58)) ([f4fc49e](https://github.com/spaced-out/ui-design-system/commit/f4fc49ee90da9b231929132f70e2df8d52e33a1a))
12
+
5
13
  ### [0.0.19](https://github.com/spaced-out/ui-design-system/compare/v0.0.18...v0.0.19) (2023-02-06)
6
14
 
7
15
 
@@ -21,6 +21,7 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
21
21
  const Dropdown = _ref => {
22
22
  let {
23
23
  options,
24
+ composeOptions,
24
25
  size,
25
26
  classNames,
26
27
  placeholder = 'Select...',
@@ -79,7 +80,7 @@ const Dropdown = _ref => {
79
80
  e.stopPropagation();
80
81
  onOpen();
81
82
  }
82
- })), isOpen && options && /*#__PURE__*/React.createElement("div", {
83
+ })), isOpen && (options || composeOptions) && /*#__PURE__*/React.createElement("div", {
83
84
  onClickCapture: cancelNext,
84
85
  ref: floating,
85
86
  style: {
@@ -92,6 +93,7 @@ const Dropdown = _ref => {
92
93
  }, /*#__PURE__*/React.createElement(_Menu.Menu, {
93
94
  isFluid: true,
94
95
  options: options,
96
+ composeOptions: composeOptions,
95
97
  onSelect: option => {
96
98
  handleSelect(option);
97
99
  clickAway();
@@ -42,11 +42,13 @@ export type DropdownProps = {
42
42
  size?: 'medium' | 'small',
43
43
  required?: boolean,
44
44
  options?: Array<MenuOption>,
45
+ composeOptions?: Array<Array<MenuOption>>,
45
46
  selectedOption?: MenuOption,
46
47
  };
47
48
 
48
49
  export const Dropdown = ({
49
50
  options,
51
+ composeOptions,
50
52
  size,
51
53
  classNames,
52
54
  placeholder = 'Select...',
@@ -99,7 +101,7 @@ export const Dropdown = ({
99
101
  }}
100
102
  />
101
103
 
102
- {isOpen && options && (
104
+ {isOpen && (options || composeOptions) && (
103
105
  <div
104
106
  onClickCapture={cancelNext}
105
107
  ref={floating}
@@ -114,6 +116,7 @@ export const Dropdown = ({
114
116
  <Menu
115
117
  isFluid
116
118
  options={options}
119
+ composeOptions={composeOptions}
117
120
  onSelect={(option) => {
118
121
  handleSelect(option);
119
122
  clickAway();
@@ -6,23 +6,44 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.Menu = void 0;
7
7
  var React = _interopRequireWildcard(require("react"));
8
8
  var _classify = require("../../utils/classify");
9
- var _Button = require("../Button");
10
- var _Icon = require("../Icon");
11
- var _Truncate = require("../Truncate");
9
+ var _MenuOptionButton = require("./MenuOptionButton.js");
12
10
  var _MenuModule = _interopRequireDefault(require("./Menu.module.css"));
13
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
12
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
13
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
-
14
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
15
+ const RenderOption = _ref => {
16
+ let {
17
+ options,
18
+ composeOptions,
19
+ ...restProps
20
+ } = _ref;
21
+ if (options && Array.isArray(options) && options.length) {
22
+ return /*#__PURE__*/React.createElement(React.Fragment, null, options.map(option => /*#__PURE__*/React.createElement(React.Fragment, {
23
+ key: option.key
24
+ }, /*#__PURE__*/React.createElement(_MenuOptionButton.MenuOptionButton, _extends({
25
+ option: option
26
+ }, restProps)))));
27
+ }
28
+ if (composeOptions && Array.isArray(composeOptions) && composeOptions.length) {
29
+ return /*#__PURE__*/React.createElement(React.Fragment, null, composeOptions.map((composeMenuOptions, index) =>
30
+ /*#__PURE__*/
31
+ // eslint-disable-next-line react/no-array-index-key
32
+ React.createElement("span", {
33
+ className: _MenuModule.default.menuDivider,
34
+ key: index
35
+ }, composeMenuOptions.map(option => /*#__PURE__*/React.createElement(React.Fragment, {
36
+ key: option.key
37
+ }, /*#__PURE__*/React.createElement(_MenuOptionButton.MenuOptionButton, _extends({
38
+ option: option
39
+ }, restProps)))))));
40
+ }
41
+ };
17
42
  const Menu = props => {
18
43
  const {
19
- options,
20
- onSelect,
21
- selectedOption,
22
44
  classNames,
23
45
  size = 'medium',
24
46
  width,
25
- menuDisabled,
26
47
  isFluid = true
27
48
  } = props;
28
49
  return /*#__PURE__*/React.createElement("div", {
@@ -34,50 +55,6 @@ const Menu = props => {
34
55
  style: {
35
56
  width
36
57
  }
37
- }, options.map(_ref => {
38
- let {
39
- key,
40
- label,
41
- secondaryLabel,
42
- iconLeft,
43
- iconLeftType,
44
- iconRight,
45
- iconRightType,
46
- disabled
47
- } = _ref;
48
- return /*#__PURE__*/React.createElement(_Button.UnstyledButton, {
49
- className: (0, _classify.classify)(_MenuModule.default.option, {
50
- [_MenuModule.default.selected]: key === selectedOption?.key,
51
- [_MenuModule.default.optionSmall]: size === 'small',
52
- [_MenuModule.default.optionMedium]: size === 'medium',
53
- [_MenuModule.default.disabled]: menuDisabled || disabled,
54
- [_MenuModule.default.withIconLeft]: !!iconLeft,
55
- [_MenuModule.default.withIconRight]: !!iconRight
56
- }),
57
- key: key,
58
- disabled: menuDisabled || disabled,
59
- onClick: () => onSelect && onSelect({
60
- key,
61
- label
62
- }),
63
- autoFocus: selectedOption?.key === key
64
- }, !!iconLeft && /*#__PURE__*/React.createElement(_Icon.Icon, {
65
- name: iconLeft,
66
- type: iconLeftType,
67
- size: "small",
68
- className: _MenuModule.default.icon
69
- }), /*#__PURE__*/React.createElement("div", {
70
- className: _MenuModule.default.optionTextContainer
71
- }, /*#__PURE__*/React.createElement("div", {
72
- className: _MenuModule.default.optionTextLabel
73
- }, /*#__PURE__*/React.createElement(_Truncate.Truncate, null, label)), !!secondaryLabel && /*#__PURE__*/React.createElement("div", {
74
- className: _MenuModule.default.optionTextSecondaryLabel
75
- }, /*#__PURE__*/React.createElement(_Truncate.Truncate, null, secondaryLabel))), !!iconRight && /*#__PURE__*/React.createElement(_Icon.Icon, {
76
- name: iconRight,
77
- type: iconRightType,
78
- size: "small",
79
- className: (0, _classify.classify)(_MenuModule.default.icon, _MenuModule.default.rightIcon)
80
- }));
81
- }));
58
+ }, /*#__PURE__*/React.createElement(RenderOption, props));
82
59
  };
83
60
  exports.Menu = Menu;
@@ -2,10 +2,9 @@
2
2
  import * as React from 'react';
3
3
 
4
4
  import {classify} from '../../utils/classify';
5
- import {UnstyledButton} from '../Button';
6
- import {Icon} from '../Icon';
7
5
  import type {IconType} from '../Icon/Icon.js';
8
- import {Truncate} from '../Truncate';
6
+
7
+ import {MenuOptionButton} from './MenuOptionButton.js';
9
8
 
10
9
  import css from './Menu.module.css';
11
10
 
@@ -23,8 +22,9 @@ export type MenuOption = {
23
22
  disabled?: boolean,
24
23
  };
25
24
 
25
+ // Render first available option set
26
+
26
27
  export type MenuProps = {
27
- options: Array<MenuOption>,
28
28
  onSelect?: (option: MenuOption) => mixed,
29
29
  selectedOption?: MenuOption,
30
30
  classNames?: ClassNames,
@@ -32,19 +32,54 @@ export type MenuProps = {
32
32
  width?: string,
33
33
  menuDisabled?: boolean,
34
34
  isFluid?: boolean,
35
+ ...MenuOptionTypes,
36
+ };
37
+
38
+ export type MenuOptionTypes = {
39
+ options?: Array<MenuOption>,
40
+ composeOptions?: Array<Array<MenuOption>>,
41
+ };
42
+
43
+ const RenderOption = ({
44
+ options,
45
+ composeOptions,
46
+ ...restProps
47
+ }: MenuProps): React.Node => {
48
+ if (options && Array.isArray(options) && options.length) {
49
+ return (
50
+ <>
51
+ {options.map((option) => (
52
+ <React.Fragment key={option.key}>
53
+ <MenuOptionButton option={option} {...restProps} />
54
+ </React.Fragment>
55
+ ))}
56
+ </>
57
+ );
58
+ }
59
+ if (
60
+ composeOptions &&
61
+ Array.isArray(composeOptions) &&
62
+ composeOptions.length
63
+ ) {
64
+ return (
65
+ <>
66
+ {composeOptions.map((composeMenuOptions, index) => (
67
+ // eslint-disable-next-line react/no-array-index-key
68
+ <span className={css.menuDivider} key={index}>
69
+ {composeMenuOptions.map((option) => (
70
+ <React.Fragment key={option.key}>
71
+ <MenuOptionButton option={option} {...restProps} />
72
+ </React.Fragment>
73
+ ))}
74
+ </span>
75
+ ))}
76
+ </>
77
+ );
78
+ }
35
79
  };
36
80
 
37
81
  export const Menu = (props: MenuProps): React.Node => {
38
- const {
39
- options,
40
- onSelect,
41
- selectedOption,
42
- classNames,
43
- size = 'medium',
44
- width,
45
- menuDisabled,
46
- isFluid = true,
47
- } = props;
82
+ const {classNames, size = 'medium', width, isFluid = true} = props;
48
83
 
49
84
  return (
50
85
  <div
@@ -55,62 +90,7 @@ export const Menu = (props: MenuProps): React.Node => {
55
90
  })}
56
91
  style={{width}}
57
92
  >
58
- {options.map(
59
- ({
60
- key,
61
- label,
62
- secondaryLabel,
63
- iconLeft,
64
- iconLeftType,
65
- iconRight,
66
- iconRightType,
67
- disabled,
68
- }) => (
69
- <UnstyledButton
70
- className={classify(css.option, {
71
- [css.selected]: key === selectedOption?.key,
72
- [css.optionSmall]: size === 'small',
73
- [css.optionMedium]: size === 'medium',
74
- [css.disabled]: menuDisabled || disabled,
75
- [css.withIconLeft]: !!iconLeft,
76
- [css.withIconRight]: !!iconRight,
77
- })}
78
- key={key}
79
- disabled={menuDisabled || disabled}
80
- onClick={() => onSelect && onSelect({key, label})}
81
- autoFocus={selectedOption?.key === key}
82
- >
83
- {!!iconLeft && (
84
- <Icon
85
- name={iconLeft}
86
- type={iconLeftType}
87
- size="small"
88
- className={css.icon}
89
- />
90
- )}
91
- <div className={css.optionTextContainer}>
92
- <div className={css.optionTextLabel}>
93
- <Truncate>{label}</Truncate>
94
- </div>
95
-
96
- {!!secondaryLabel && (
97
- <div className={css.optionTextSecondaryLabel}>
98
- <Truncate>{secondaryLabel}</Truncate>
99
- </div>
100
- )}
101
- </div>
102
-
103
- {!!iconRight && (
104
- <Icon
105
- name={iconRight}
106
- type={iconRightType}
107
- size="small"
108
- className={classify(css.icon, css.rightIcon)}
109
- />
110
- )}
111
- </UnstyledButton>
112
- ),
113
- )}
93
+ <RenderOption {...props} />
114
94
  </div>
115
95
  );
116
96
  };
@@ -160,3 +160,12 @@
160
160
  .disabled .optionTextSecondaryLabel {
161
161
  color: colorTextDisabled;
162
162
  }
163
+
164
+ .menuDivider:not(:first-of-type) {
165
+ border-top: borderWidthPrimary solid colorBorderPrimary;
166
+ padding: spaceXSmall;
167
+ }
168
+
169
+ .menuDivider {
170
+ padding: spaceXSmall;
171
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.MenuOptionButton = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _classify = require("../../utils/classify");
9
+ var _Button = require("../Button");
10
+ var _Icon = require("../Icon");
11
+ var _Truncate = require("../Truncate");
12
+ var _MenuModule = _interopRequireDefault(require("./Menu.module.css"));
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
+
17
+ const MenuOptionButton = props => {
18
+ const {
19
+ option,
20
+ size,
21
+ onSelect,
22
+ selectedOption,
23
+ menuDisabled
24
+ } = props;
25
+ const {
26
+ key,
27
+ label,
28
+ secondaryLabel,
29
+ iconLeft,
30
+ iconLeftType,
31
+ iconRight,
32
+ iconRightType,
33
+ disabled
34
+ } = option;
35
+ return /*#__PURE__*/React.createElement(_Button.UnstyledButton, {
36
+ className: (0, _classify.classify)(_MenuModule.default.option, {
37
+ [_MenuModule.default.selected]: key === selectedOption?.key,
38
+ [_MenuModule.default.optionSmall]: size === 'small',
39
+ [_MenuModule.default.optionMedium]: size === 'medium',
40
+ [_MenuModule.default.disabled]: menuDisabled || disabled,
41
+ [_MenuModule.default.withIconLeft]: !!iconLeft,
42
+ [_MenuModule.default.withIconRight]: !!iconRight
43
+ }),
44
+ disabled: menuDisabled || disabled,
45
+ onClick: () => onSelect && onSelect(option),
46
+ autoFocus: selectedOption?.key === key
47
+ }, !!iconLeft && /*#__PURE__*/React.createElement(_Icon.Icon, {
48
+ name: iconLeft,
49
+ type: iconLeftType,
50
+ size: "small",
51
+ className: _MenuModule.default.icon
52
+ }), /*#__PURE__*/React.createElement("div", {
53
+ className: _MenuModule.default.optionTextContainer
54
+ }, /*#__PURE__*/React.createElement("div", {
55
+ className: _MenuModule.default.optionTextLabel
56
+ }, /*#__PURE__*/React.createElement(_Truncate.Truncate, null, label)), !!secondaryLabel && /*#__PURE__*/React.createElement("div", {
57
+ className: _MenuModule.default.optionTextSecondaryLabel
58
+ }, /*#__PURE__*/React.createElement(_Truncate.Truncate, null, secondaryLabel))), !!iconRight && /*#__PURE__*/React.createElement(_Icon.Icon, {
59
+ name: iconRight,
60
+ type: iconRightType,
61
+ size: "small",
62
+ className: (0, _classify.classify)(_MenuModule.default.icon, _MenuModule.default.rightIcon)
63
+ }));
64
+ };
65
+ exports.MenuOptionButton = MenuOptionButton;
@@ -0,0 +1,83 @@
1
+ // @flow strict
2
+ import * as React from 'react';
3
+
4
+ import {classify} from '../../utils/classify';
5
+ import {UnstyledButton} from '../Button';
6
+ import {Icon} from '../Icon';
7
+ import {Truncate} from '../Truncate';
8
+
9
+ import type {MenuOption} from './Menu.js';
10
+
11
+ import css from './Menu.module.css';
12
+
13
+
14
+ type ClassNames = $ReadOnly<{wrapper?: string}>;
15
+
16
+ export type MenuOptionProps = {
17
+ option: MenuOption,
18
+ onSelect?: (option: MenuOption) => mixed,
19
+ selectedOption?: MenuOption,
20
+ classNames?: ClassNames,
21
+ size?: 'medium' | 'small',
22
+ width?: string,
23
+ menuDisabled?: boolean,
24
+ isFluid?: boolean,
25
+ };
26
+
27
+ export const MenuOptionButton = (props: MenuOptionProps): React.Node => {
28
+ const {option, size, onSelect, selectedOption, menuDisabled} = props;
29
+ const {
30
+ key,
31
+ label,
32
+ secondaryLabel,
33
+ iconLeft,
34
+ iconLeftType,
35
+ iconRight,
36
+ iconRightType,
37
+ disabled,
38
+ } = option;
39
+ return (
40
+ <UnstyledButton
41
+ className={classify(css.option, {
42
+ [css.selected]: key === selectedOption?.key,
43
+ [css.optionSmall]: size === 'small',
44
+ [css.optionMedium]: size === 'medium',
45
+ [css.disabled]: menuDisabled || disabled,
46
+ [css.withIconLeft]: !!iconLeft,
47
+ [css.withIconRight]: !!iconRight,
48
+ })}
49
+ disabled={menuDisabled || disabled}
50
+ onClick={() => onSelect && onSelect(option)}
51
+ autoFocus={selectedOption?.key === key}
52
+ >
53
+ {!!iconLeft && (
54
+ <Icon
55
+ name={iconLeft}
56
+ type={iconLeftType}
57
+ size="small"
58
+ className={css.icon}
59
+ />
60
+ )}
61
+ <div className={css.optionTextContainer}>
62
+ <div className={css.optionTextLabel}>
63
+ <Truncate>{label}</Truncate>
64
+ </div>
65
+
66
+ {!!secondaryLabel && (
67
+ <div className={css.optionTextSecondaryLabel}>
68
+ <Truncate>{secondaryLabel}</Truncate>
69
+ </div>
70
+ )}
71
+ </div>
72
+
73
+ {!!iconRight && (
74
+ <Icon
75
+ name={iconRight}
76
+ type={iconRightType}
77
+ size="small"
78
+ className={classify(css.icon, css.rightIcon)}
79
+ />
80
+ )}
81
+ </UnstyledButton>
82
+ );
83
+ };
@@ -9,4 +9,11 @@ Object.defineProperty(exports, "Menu", {
9
9
  return _Menu.Menu;
10
10
  }
11
11
  });
12
- var _Menu = require("./Menu");
12
+ Object.defineProperty(exports, "MenuOptionButton", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _MenuOptionButton.MenuOptionButton;
16
+ }
17
+ });
18
+ var _Menu = require("./Menu");
19
+ var _MenuOptionButton = require("./MenuOptionButton.js");
@@ -2,3 +2,4 @@
2
2
 
3
3
  export type {MenuOption, MenuProps} from './Menu';
4
4
  export {Menu} from './Menu';
5
+ export {MenuOptionButton} from './MenuOptionButton.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {
@@ -115,7 +115,7 @@
115
115
  },
116
116
  "husky": {
117
117
  "hooks": {
118
- "pre-commit": "lint-staged",
118
+ "pre-commit": "lint-staged && yarn flow",
119
119
  "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
120
120
  }
121
121
  },