@k-int/stripes-kint-components 4.6.1 → 4.7.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 CHANGED
@@ -1,5 +1,12 @@
1
- ## 4.6.1 2023-04-14
1
+ ## 4.7.1 2023-06-09
2
+ * Fixed rogue CSS from ComboButton
3
+
4
+ ## 4.7.0 2023-06-06
2
5
  * Added success callout to SettingsFormContainer
6
+ * Bumped @rehooks/local-storage dep to ^2.4.4
7
+ * Added indexing to ActionList parent div for uniqueness for screen readers
8
+ * Added aria-label to default Fields within ActionList
9
+ * ComboButton - new component for buttonm with one primary and multiple ancillary actions.
3
10
 
4
11
  ## 4.6.0 2023-04-14
5
12
  * ERM-2884 Regex with lookbehind causes render failure in Safari
package/es/index.js CHANGED
@@ -47,7 +47,8 @@ var _exportNames = {
47
47
  useSelectedOption: true,
48
48
  FormattedKintMessage: true,
49
49
  ResponsiveButtonGroup: true,
50
- SettingsFormContainer: true
50
+ SettingsFormContainer: true,
51
+ ComboButton: true
51
52
  };
52
53
  Object.defineProperty(exports, "ActionList", {
53
54
  enumerable: true,
@@ -55,6 +56,12 @@ Object.defineProperty(exports, "ActionList", {
55
56
  return _ActionList.default;
56
57
  }
57
58
  });
59
+ Object.defineProperty(exports, "ComboButton", {
60
+ enumerable: true,
61
+ get: function () {
62
+ return _ComboButton.default;
63
+ }
64
+ });
58
65
  Object.defineProperty(exports, "CustomPropertiesEdit", {
59
66
  enumerable: true,
60
67
  get: function () {
@@ -371,6 +378,7 @@ var _RichSelect = _interopRequireWildcard(require("./lib/RichSelect"));
371
378
  var _FormattedKintMessage = _interopRequireDefault(require("./lib/FormattedKintMessage"));
372
379
  var _ResponsiveButtonGroup = _interopRequireDefault(require("./lib/ResponsiveButtonGroup"));
373
380
  var _SettingsFormContainer = _interopRequireDefault(require("./lib/SettingsFormContainer"));
381
+ var _ComboButton = _interopRequireDefault(require("./lib/ComboButton"));
374
382
  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); }
375
383
  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; }
376
384
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -173,7 +173,7 @@ const ActionListFieldArray = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
173
173
  if (data.id === editing || !data.id && editing === 'NEW_ROW') {
174
174
  // Render the save/cancel buttons
175
175
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
176
- id: "action-button-parent",
176
+ id: "action-button-parent-".concat(data.rowIndex + 1),
177
177
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
178
178
  buttonStyle: "primary",
179
179
  disabled: hasValidationErrors || submitting || pristine,
@@ -215,7 +215,7 @@ const ActionListFieldArray = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
215
215
  });
216
216
  }
217
217
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
218
- id: "action-button-parent",
218
+ id: "action-button-parent-".concat(data.rowIndex + 1),
219
219
  children: actions === null || actions === void 0 ? void 0 : actions.map(action => {
220
220
  let actionFunction;
221
221
  if (action.callback) {
@@ -356,6 +356,8 @@ const ActionListFieldArray = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) =>
356
356
  };
357
357
  const validateFunction = validateFields !== null && validateFields !== void 0 && validateFields[key] ? validateFields === null || validateFields === void 0 ? void 0 : validateFields[key](passedObject) : null;
358
358
  returnValue = fieldComponents[key] ? fieldComponents[key](passedObject) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFinalForm.Field, {
359
+ ariaLabel: key // TODO at the moment the only way to override this is passing in an entire fieldComponent.
360
+ ,
359
361
  autoFocus: autoFocus,
360
362
  component: _components.TextField,
361
363
  marginBottom0: true,
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = require("react");
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+ var _classnames = _interopRequireDefault(require("classnames"));
10
+ var _components = require("@folio/stripes/components");
11
+ var _ResponsiveButtonGroup = _interopRequireDefault(require("../../../styles/ResponsiveButtonGroup.css"));
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+ // FIXME we should probably store the shared styles in a more aptly named file
15
+
16
+ /*
17
+ * ComboButton component, can either act as Primary/Bonus buttons in a dropdown
18
+ * OR it can act as a popover rendered besides a button.
19
+ * If neither are provided it will act as an ordinary button
20
+ */const ComboButton = _ref => {
21
+ let {
22
+ children,
23
+ dropdownButtons = [],
24
+ // These MUST be buttons
25
+ dropdownProps = {},
26
+ dropdownRender,
27
+ marginBottom0,
28
+ // Will ONLY control the margin of the dropdown/main button
29
+ popoverProps = {},
30
+ triggerProps,
31
+ ...buttonProps
32
+ } = _ref;
33
+ const [open, setOpen] = (0, _react.useState)(false);
34
+ const onToggle = (0, _react.useCallback)(() => setOpen(!open), [open, setOpen]);
35
+
36
+ // FIXME a lot of this is shared with ResponsiveButtonGroup
37
+ const styledDropdownButtons = (0, _react.useMemo)(() => dropdownButtons === null || dropdownButtons === void 0 ? void 0 : dropdownButtons.map(button => {
38
+ return /*#__PURE__*/(0, _react.cloneElement)(button, {
39
+ buttonStyle: 'dropdownItem'
40
+ });
41
+ }), [dropdownButtons]);
42
+
43
+ // eslint-disable-next-line react/prop-types
44
+ const renderActionMenuContent = (0, _react.useCallback)(() => /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.DropdownMenu, {
45
+ children: [...styledDropdownButtons]
46
+ }), [styledDropdownButtons]);
47
+ const renderTrigger = (0, _react.useCallback)(_ref2 => {
48
+ var _buttonProps$buttonSt;
49
+ let {
50
+ onToggle: toggleFunc,
51
+ triggerRef,
52
+ keyHandler,
53
+ open: openState,
54
+ ariaProps,
55
+ getTriggerProps
56
+ } = _ref2;
57
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
58
+ ref: triggerRef,
59
+ "aria-label": "menu",
60
+ buttonClass: (0, _classnames.default)(_ResponsiveButtonGroup.default.width100, _ResponsiveButtonGroup.default.dropdownButtonClass, {
61
+ ["".concat(_ResponsiveButtonGroup.default.marginBottom)]: !marginBottom0
62
+ }, {
63
+ ["".concat(_ResponsiveButtonGroup.default.marginBottom0)]: marginBottom0
64
+ }),
65
+ buttonStyle: (_buttonProps$buttonSt = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.buttonStyle) !== null && _buttonProps$buttonSt !== void 0 ? _buttonProps$buttonSt : 'default',
66
+ onClick: toggleFunc,
67
+ onKeyDown: keyHandler,
68
+ type: "button",
69
+ ...getTriggerProps(),
70
+ ...ariaProps,
71
+ ...triggerProps,
72
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Icon, {
73
+ icon: openState ? 'triangle-up' : 'triangle-down',
74
+ iconPosition: "end"
75
+ })
76
+ });
77
+ }, [buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.buttonStyle, triggerProps, marginBottom0]);
78
+ let comboTrigger;
79
+ if (dropdownButtons.length > 0) {
80
+ comboTrigger = /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Dropdown, {
81
+ className: _ResponsiveButtonGroup.default.dropdownClass,
82
+ onToggle: onToggle,
83
+ open: open,
84
+ renderMenu: renderActionMenuContent,
85
+ renderTrigger: renderTriggerProps => renderTrigger(renderTriggerProps),
86
+ ...dropdownProps
87
+ }, "combobutton-dropdown-toggle");
88
+ } else if (dropdownRender) {
89
+ comboTrigger = /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Popover, {
90
+ onToggle: onToggle,
91
+ open: open,
92
+ renderTrigger: _ref3 => {
93
+ let {
94
+ open: openState,
95
+ ref,
96
+ toggle
97
+ } = _ref3;
98
+ return renderTrigger({
99
+ getTriggerProps: () => {},
100
+ onToggle: toggle,
101
+ open: openState,
102
+ triggerRef: ref
103
+ });
104
+ },
105
+ ...popoverProps,
106
+ children: dropdownRender
107
+ });
108
+ }
109
+ if (comboTrigger) {
110
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
111
+ className: (0, _classnames.default)(_ResponsiveButtonGroup.default.buttonGroup),
112
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
113
+ marginBottom0: marginBottom0,
114
+ ...buttonProps,
115
+ children: children
116
+ }), comboTrigger]
117
+ });
118
+ }
119
+
120
+ // Fallback, acts as a normal button
121
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
122
+ marginBottom0: marginBottom0,
123
+ ...buttonProps,
124
+ children: children
125
+ });
126
+ };
127
+ ComboButton.propTypes = {
128
+ children: _propTypes.default.node,
129
+ dropdownButtons: _propTypes.default.arrayOf(_propTypes.default.node),
130
+ dropdownProps: _propTypes.default.object,
131
+ dropdownRender: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]),
132
+ id: _propTypes.default.string,
133
+ marginBottom0: _propTypes.default.bool,
134
+ popoverProps: _propTypes.default.object,
135
+ triggerProps: _propTypes.default.object
136
+ };
137
+ var _default = ComboButton;
138
+ exports.default = _default;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _ComboButton.default;
10
+ }
11
+ });
12
+ var _ComboButton = _interopRequireDefault(require("./ComboButton"));
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k-int/stripes-kint-components",
3
- "version": "4.6.1",
3
+ "version": "4.7.1",
4
4
  "description": "Stripes Component library for K-Int specific applications",
5
5
  "sideEffects": [
6
6
  "*.css"
@@ -20,7 +20,7 @@
20
20
  "prepare": "yarn build"
21
21
  },
22
22
  "dependencies": {
23
- "@rehooks/local-storage": "2.4.0",
23
+ "@rehooks/local-storage": "^2.4.4",
24
24
  "compose-function": "^3.0.3",
25
25
  "react-resize-detector": "^7.1.2",
26
26
  "zustand": "^4.0.0"
package/src/index.js CHANGED
@@ -107,3 +107,5 @@ export { default as FormattedKintMessage } from './lib/FormattedKintMessage';
107
107
  export { default as ResponsiveButtonGroup } from './lib/ResponsiveButtonGroup';
108
108
 
109
109
  export { default as SettingsFormContainer } from './lib/SettingsFormContainer';
110
+
111
+ export { default as ComboButton } from './lib/ComboButton';
@@ -176,7 +176,7 @@ const ActionListFieldArray = forwardRef(({
176
176
  if (data.id === editing || (!data.id && editing === 'NEW_ROW')) {
177
177
  // Render the save/cancel buttons
178
178
  return (
179
- <div id="action-button-parent">
179
+ <div id={`action-button-parent-${data.rowIndex + 1}`}>
180
180
  <Button
181
181
  key={`save[${data.rowIndex}]`}
182
182
  buttonStyle="primary"
@@ -225,7 +225,7 @@ const ActionListFieldArray = forwardRef(({
225
225
  }
226
226
 
227
227
  return (
228
- <div id="action-button-parent">
228
+ <div id={`action-button-parent-${data.rowIndex + 1}`}>
229
229
  {actions?.map(action => {
230
230
  let actionFunction;
231
231
  if (action.callback) {
@@ -379,6 +379,7 @@ const ActionListFieldArray = forwardRef(({
379
379
  fieldComponents[key] ?
380
380
  fieldComponents[key](passedObject) :
381
381
  <Field
382
+ ariaLabel={key} // TODO at the moment the only way to override this is passing in an entire fieldComponent.
382
383
  autoFocus={autoFocus}
383
384
  component={TextField}
384
385
  marginBottom0
@@ -0,0 +1,161 @@
1
+ import { cloneElement, useCallback, useMemo, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ import classnames from 'classnames';
5
+
6
+ import {
7
+ Button,
8
+ Dropdown,
9
+ DropdownMenu,
10
+ Icon,
11
+ Popover
12
+ } from '@folio/stripes/components';
13
+
14
+ // FIXME we should probably store the shared styles in a more aptly named file
15
+ import css from '../../../styles/ResponsiveButtonGroup.css';
16
+
17
+ /*
18
+ * ComboButton component, can either act as Primary/Bonus buttons in a dropdown
19
+ * OR it can act as a popover rendered besides a button.
20
+ * If neither are provided it will act as an ordinary button
21
+ */
22
+
23
+ const ComboButton = ({
24
+ children,
25
+ dropdownButtons = [], // These MUST be buttons
26
+ dropdownProps = {},
27
+ dropdownRender,
28
+ marginBottom0, // Will ONLY control the margin of the dropdown/main button
29
+ popoverProps = {},
30
+ triggerProps,
31
+ ...buttonProps
32
+ }) => {
33
+ const [open, setOpen] = useState(false);
34
+ const onToggle = useCallback(() => setOpen(!open), [open, setOpen]);
35
+
36
+ // FIXME a lot of this is shared with ResponsiveButtonGroup
37
+ const styledDropdownButtons = useMemo(() => (
38
+ dropdownButtons
39
+ ?.map(button => {
40
+ return cloneElement(button, { buttonStyle: 'dropdownItem' });
41
+ })
42
+ ), [dropdownButtons]);
43
+
44
+ // eslint-disable-next-line react/prop-types
45
+ const renderActionMenuContent = useCallback(() => (
46
+ <DropdownMenu>
47
+ {[...styledDropdownButtons]}
48
+ </DropdownMenu>
49
+ ), [styledDropdownButtons]);
50
+
51
+ const renderTrigger = useCallback(({
52
+ onToggle: toggleFunc,
53
+ triggerRef,
54
+ keyHandler,
55
+ open: openState,
56
+ ariaProps,
57
+ getTriggerProps
58
+ }) => (
59
+ <Button
60
+ ref={triggerRef}
61
+ aria-label="menu"
62
+ buttonClass={
63
+ classnames(
64
+ css.width100,
65
+ css.dropdownButtonClass,
66
+ { [`${css.marginBottom}`]: !marginBottom0 },
67
+ { [`${css.marginBottom0}`]: marginBottom0 }
68
+ )
69
+ }
70
+ buttonStyle={buttonProps?.buttonStyle ?? 'default'}
71
+ onClick={toggleFunc}
72
+ onKeyDown={keyHandler}
73
+ type="button"
74
+ {...getTriggerProps()}
75
+ {...ariaProps}
76
+ {...triggerProps}
77
+ >
78
+ <Icon icon={openState ? 'triangle-up' : 'triangle-down'} iconPosition="end" />
79
+ </Button>
80
+ ), [
81
+ buttonProps?.buttonStyle,
82
+ triggerProps,
83
+ marginBottom0
84
+ ]);
85
+
86
+ let comboTrigger;
87
+ if (dropdownButtons.length > 0) {
88
+ comboTrigger = <Dropdown
89
+ key="combobutton-dropdown-toggle"
90
+ className={css.dropdownClass}
91
+ onToggle={onToggle}
92
+ open={open}
93
+ renderMenu={renderActionMenuContent}
94
+ renderTrigger={(renderTriggerProps) => renderTrigger(renderTriggerProps)}
95
+ {...dropdownProps}
96
+ />;
97
+ } else if (dropdownRender) {
98
+ comboTrigger = (
99
+ <Popover
100
+ onToggle={onToggle}
101
+ open={open}
102
+ renderTrigger={({ open: openState, ref, toggle }) => renderTrigger({
103
+ getTriggerProps: () => {},
104
+ onToggle: toggle,
105
+ open: openState,
106
+ triggerRef: ref
107
+ })}
108
+ {...popoverProps}
109
+ >
110
+ {dropdownRender}
111
+ </Popover>
112
+ );
113
+ }
114
+
115
+ if (comboTrigger) {
116
+ return (
117
+ <div
118
+ className={
119
+ classnames(
120
+ css.buttonGroup,
121
+ )
122
+ }
123
+ >
124
+ <Button
125
+ marginBottom0={marginBottom0}
126
+ {...buttonProps}
127
+ >
128
+ {children}
129
+ </Button>
130
+ {comboTrigger}
131
+ </div>
132
+ );
133
+ }
134
+
135
+
136
+ // Fallback, acts as a normal button
137
+ return (
138
+ <Button
139
+ marginBottom0={marginBottom0}
140
+ {...buttonProps}
141
+ >
142
+ {children}
143
+ </Button>
144
+ );
145
+ };
146
+
147
+ ComboButton.propTypes = {
148
+ children: PropTypes.node,
149
+ dropdownButtons: PropTypes.arrayOf(PropTypes.node),
150
+ dropdownProps: PropTypes.object,
151
+ dropdownRender: PropTypes.oneOfType([
152
+ PropTypes.func,
153
+ PropTypes.node
154
+ ]),
155
+ id: PropTypes.string,
156
+ marginBottom0: PropTypes.bool,
157
+ popoverProps: PropTypes.object,
158
+ triggerProps: PropTypes.object,
159
+ };
160
+
161
+ export default ComboButton;
@@ -0,0 +1 @@
1
+ export { default } from './ComboButton';
@@ -40,10 +40,15 @@
40
40
  margin-left: -1px;
41
41
  }
42
42
 
43
- & > :not(:first-child):not(:last-child),
44
- & > :not(:first-child):not(:last-child)::before {
45
- border-radius: 0;
46
- }
43
+ & > :not(:first-child):not(:last-child),
44
+ & > :not(:first-child):not(:last-child)::before {
45
+ border-radius: 0;
46
+ }
47
+ }
48
+
49
+ .dropdownButtonClass, .dropdownButtonClass::before {
50
+ border-top-left-radius: 0;
51
+ border-bottom-left-radius: 0;
47
52
  }
48
53
 
49
54
  [dir="rtl"] {
@@ -69,22 +74,19 @@
69
74
  margin-right: -1px;
70
75
  }
71
76
  }
77
+
78
+ .dropdownButtonClass, .dropdownButtonClass::before {
79
+ border-top-right-radius: 0;
80
+ border-bottom-right-radius: 0;
81
+ border-top-left-radius: var(--radius);
82
+ border-bottom-left-radius: var(--radius);
83
+ }
72
84
  }
73
85
 
74
86
  .dropdownClass {
75
87
  padding: 0 !important; /* As always, this sucks but is forced on us by stripes bad css ordering */
76
88
  }
77
89
 
78
- .dropdownButtonClass {
79
- border-top-left-radius: 0;
80
- border-bottom-left-radius: 0;
81
- }
82
-
83
- .dropdownButtonClass::before {
84
- border-top-left-radius: 0;
85
- border-bottom-left-radius: 0;
86
- }
87
-
88
90
  .hidden {
89
91
  visibility: hidden;
90
92
  }