@canonical/react-components 3.1.1 → 3.2.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.
@@ -10,7 +10,8 @@ export type MultiSelectProps = {
10
10
  disabled?: boolean;
11
11
  error?: string;
12
12
  selectedItems?: MultiSelectItem[];
13
- help?: string;
13
+ help?: ReactNode;
14
+ helpClassName?: string;
14
15
  label?: string | null;
15
16
  listSelected?: boolean;
16
17
  onDeselectItem?: (item: MultiSelectItem) => void;
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.MultiSelectDropdown = exports.MultiSelect = void 0;
7
7
  var _propTypes = _interopRequireDefault(require("prop-types"));
8
+ var _classnames = _interopRequireDefault(require("classnames"));
8
9
  var _react = _interopRequireWildcard(require("react"));
9
10
  require("./MultiSelect.scss");
10
11
  var _index = require("../../index");
@@ -179,13 +180,16 @@ const MultiSelect = _ref4 => {
179
180
  scrollOverflow = false,
180
181
  isSortedAlphabetically = true,
181
182
  hasSelectedItemsFirst = true,
182
- id
183
+ id,
184
+ help,
185
+ helpClassName
183
186
  } = _ref4;
184
187
  const buttonRef = (0, _react.useRef)(null);
185
188
  const [isDropdownOpen, setIsDropdownOpen] = (0, _react.useState)(false);
186
189
  const [filter, setFilter] = (0, _react.useState)("");
187
190
  const [internalSelectedItems, setInternalSelectedItems] = (0, _react.useState)([]);
188
191
  const selectedItems = externalSelectedItems || internalSelectedItems;
192
+ const helpId = (0, _react.useId)();
189
193
  const updateItems = newItems => {
190
194
  const uniqueItems = Array.from(new Set(newItems));
191
195
  setInternalSelectedItems(uniqueItems);
@@ -212,7 +216,7 @@ const MultiSelect = _ref4 => {
212
216
  type: "button"
213
217
  }, "Clear"));
214
218
  }
215
- return /*#__PURE__*/_react.default.createElement(_index.ContextualMenu, {
219
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_index.ContextualMenu, {
216
220
  className: "multi-select",
217
221
  onToggleMenu: isOpen => {
218
222
  if (!isOpen) {
@@ -276,7 +280,8 @@ const MultiSelect = _ref4 => {
276
280
  className: "multi-select__condensed-text"
277
281
  }, listSelected && selectedItems.length > 0 ? selectedItemsLabel : placeholder !== null && placeholder !== void 0 ? placeholder : "Select items")),
278
282
  visible: isDropdownOpen,
279
- scrollOverflow: scrollOverflow
283
+ scrollOverflow: scrollOverflow,
284
+ "aria-describedby": help ? helpId : undefined
280
285
  }, /*#__PURE__*/_react.default.createElement(MultiSelectDropdown, {
281
286
  id: dropdownId,
282
287
  isOpen: isDropdownOpen,
@@ -290,7 +295,10 @@ const MultiSelect = _ref4 => {
290
295
  footer: footer,
291
296
  sortFn: isSortedAlphabetically ? sortAlphabetically : () => 0,
292
297
  hasSelectedItemsFirst: hasSelectedItemsFirst
293
- }));
298
+ })), help && /*#__PURE__*/_react.default.createElement("p", {
299
+ className: (0, _classnames.default)("p-form-help-text", helpClassName),
300
+ id: helpId
301
+ }, help));
294
302
  };
295
303
  exports.MultiSelect = MultiSelect;
296
304
  MultiSelect.propTypes = {
@@ -301,7 +309,8 @@ MultiSelect.propTypes = {
301
309
  value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]).isRequired,
302
310
  group: _propTypes.default.string
303
311
  })),
304
- help: _propTypes.default.string,
312
+ help: _propTypes.default.node,
313
+ helpClassName: _propTypes.default.string,
305
314
  label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.oneOf([null])]),
306
315
  listSelected: _propTypes.default.bool,
307
316
  onDeselectItem: _propTypes.default.func,
@@ -8,3 +8,4 @@ export declare const SearchExample: Story;
8
8
  export declare const WithDisabledItems: Story;
9
9
  export declare const WithoutSorting: Story;
10
10
  export declare const Disabled: Story;
11
+ export declare const HelpText: Story;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.WithoutSorting = exports.WithDisabledItems = exports.SearchExample = exports.Disabled = exports.CondensedExample = void 0;
6
+ exports.default = exports.WithoutSorting = exports.WithDisabledItems = exports.SearchExample = exports.HelpText = exports.Disabled = exports.CondensedExample = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _MultiSelect = require("./MultiSelect");
9
9
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -114,4 +114,10 @@ const Disabled = exports.Disabled = {
114
114
  ...CondensedExample.args,
115
115
  disabled: true
116
116
  }
117
+ };
118
+ const HelpText = exports.HelpText = {
119
+ args: {
120
+ ...CondensedExample.args,
121
+ help: /*#__PURE__*/_react.default.createElement("span", null, "This is a help text, that should appear underneath the component.")
122
+ }
117
123
  };
@@ -10,7 +10,8 @@ export type MultiSelectProps = {
10
10
  disabled?: boolean;
11
11
  error?: string;
12
12
  selectedItems?: MultiSelectItem[];
13
- help?: string;
13
+ help?: ReactNode;
14
+ helpClassName?: string;
14
15
  label?: string | null;
15
16
  listSelected?: boolean;
16
17
  onDeselectItem?: (item: MultiSelectItem) => void;
@@ -3,6 +3,7 @@ var _excluded = ["items", "selectedItems", "disabledItems", "header", "updateIte
3
3
  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); }
4
4
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
5
5
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
6
+ import classNames from "classnames";
6
7
  import React, { useEffect, useId, useMemo, useRef, useState } from "react";
7
8
  import "./MultiSelect.scss";
8
9
  import { Button, CheckboxInput, ContextualMenu, SearchBox } from "../../index";
@@ -172,13 +173,16 @@ export var MultiSelect = _ref4 => {
172
173
  scrollOverflow = false,
173
174
  isSortedAlphabetically = true,
174
175
  hasSelectedItemsFirst = true,
175
- id
176
+ id,
177
+ help,
178
+ helpClassName
176
179
  } = _ref4;
177
180
  var buttonRef = useRef(null);
178
181
  var [isDropdownOpen, setIsDropdownOpen] = useState(false);
179
182
  var [filter, setFilter] = useState("");
180
183
  var [internalSelectedItems, setInternalSelectedItems] = useState([]);
181
184
  var selectedItems = externalSelectedItems || internalSelectedItems;
185
+ var helpId = useId();
182
186
  var updateItems = newItems => {
183
187
  var uniqueItems = Array.from(new Set(newItems));
184
188
  setInternalSelectedItems(uniqueItems);
@@ -205,7 +209,7 @@ export var MultiSelect = _ref4 => {
205
209
  type: "button"
206
210
  }, "Clear"));
207
211
  }
208
- return /*#__PURE__*/React.createElement(ContextualMenu, {
212
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ContextualMenu, {
209
213
  className: "multi-select",
210
214
  onToggleMenu: isOpen => {
211
215
  if (!isOpen) {
@@ -269,7 +273,8 @@ export var MultiSelect = _ref4 => {
269
273
  className: "multi-select__condensed-text"
270
274
  }, listSelected && selectedItems.length > 0 ? selectedItemsLabel : placeholder !== null && placeholder !== void 0 ? placeholder : "Select items")),
271
275
  visible: isDropdownOpen,
272
- scrollOverflow: scrollOverflow
276
+ scrollOverflow: scrollOverflow,
277
+ "aria-describedby": help ? helpId : undefined
273
278
  }, /*#__PURE__*/React.createElement(MultiSelectDropdown, {
274
279
  id: dropdownId,
275
280
  isOpen: isDropdownOpen,
@@ -283,7 +288,10 @@ export var MultiSelect = _ref4 => {
283
288
  footer: footer,
284
289
  sortFn: isSortedAlphabetically ? sortAlphabetically : () => 0,
285
290
  hasSelectedItemsFirst: hasSelectedItemsFirst
286
- }));
291
+ })), help && /*#__PURE__*/React.createElement("p", {
292
+ className: classNames("p-form-help-text", helpClassName),
293
+ id: helpId
294
+ }, help));
287
295
  };
288
296
  MultiSelect.propTypes = {
289
297
  disabled: _pt.bool,
@@ -293,7 +301,8 @@ MultiSelect.propTypes = {
293
301
  value: _pt.oneOfType([_pt.string, _pt.number]).isRequired,
294
302
  group: _pt.string
295
303
  })),
296
- help: _pt.string,
304
+ help: _pt.node,
305
+ helpClassName: _pt.string,
297
306
  label: _pt.oneOfType([_pt.string, _pt.oneOf([null])]),
298
307
  listSelected: _pt.bool,
299
308
  onDeselectItem: _pt.func,
@@ -8,3 +8,4 @@ export declare const SearchExample: Story;
8
8
  export declare const WithDisabledItems: Story;
9
9
  export declare const WithoutSorting: Story;
10
10
  export declare const Disabled: Story;
11
+ export declare const HelpText: Story;
@@ -108,4 +108,9 @@ export var Disabled = {
108
108
  args: _objectSpread(_objectSpread({}, CondensedExample.args), {}, {
109
109
  disabled: true
110
110
  })
111
+ };
112
+ export var HelpText = {
113
+ args: _objectSpread(_objectSpread({}, CondensedExample.args), {}, {
114
+ help: /*#__PURE__*/React.createElement("span", null, "This is a help text, that should appear underneath the component.")
115
+ })
111
116
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonical/react-components",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "author": {