@deque/cauldron-react 6.5.0-canary.dbafa2f9 → 6.6.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.
@@ -1,11 +1,12 @@
1
- import React, { InputHTMLAttributes, Ref } from 'react';
1
+ import React, { InputHTMLAttributes } from 'react';
2
2
  export interface CheckboxProps extends InputHTMLAttributes<HTMLInputElement> {
3
3
  id: string;
4
4
  label: React.ReactNode;
5
5
  labelDescription?: React.ReactNode;
6
6
  error?: React.ReactNode;
7
7
  customIcon?: React.ReactNode;
8
- checkboxRef?: Ref<HTMLInputElement>;
8
+ checkboxRef?: React.ForwardedRef<HTMLInputElement>;
9
+ indeterminate?: boolean;
9
10
  }
10
11
  declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLInputElement>>;
11
12
  export default Checkbox;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { ContentNode } from '../../types';
3
+ import Button from '../Button';
4
+ import Tooltip from '../Tooltip';
5
+ type ButtonProps = React.ComponentProps<typeof Button>;
6
+ export interface CopyButtonProps extends Omit<ButtonProps, 'onCopy' | 'onClick'> {
7
+ value: string;
8
+ variant?: Extract<ButtonProps['variant'], 'primary' | 'secondary' | 'tertiary'>;
9
+ children?: ContentNode;
10
+ notificationLabel?: ContentNode;
11
+ hideVisibleLabel?: boolean;
12
+ tooltipPlacement?: React.ComponentProps<typeof Tooltip>['placement'];
13
+ onCopy?: (text: string) => void;
14
+ }
15
+ declare const CopyButton: React.ForwardRefExoticComponent<Omit<CopyButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
16
+ export default CopyButton;
@@ -2,13 +2,14 @@ import React from 'react';
2
2
  interface TagProps {
3
3
  children: React.ReactNode;
4
4
  className?: string;
5
+ size?: 'default' | 'small';
5
6
  }
6
7
  export declare const TagLabel: {
7
8
  ({ children, className, ...other }: TagProps): React.JSX.Element;
8
9
  displayName: string;
9
10
  };
10
11
  declare const Tag: {
11
- ({ children, className, ...other }: TagProps): React.JSX.Element;
12
+ ({ children, className, size, ...other }: TagProps): React.JSX.Element;
12
13
  displayName: string;
13
14
  };
14
15
  export default Tag;
package/lib/copy.js CHANGED
@@ -25,14 +25,13 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
25
25
  var _path;
26
26
  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); }
27
27
  const SvgCopy = props => /*#__PURE__*/React__namespace.createElement("svg", _extends({
28
- overflow: "visible",
29
- preserveAspectRatio: "none",
30
- viewBox: "0 0 24 24",
28
+ fill: "none",
29
+ xmlns: "http://www.w3.org/2000/svg",
30
+ viewBox: "-1 -1 19 19",
31
31
  height: 24,
32
32
  width: 24
33
33
  }, props), _path || (_path = /*#__PURE__*/React__namespace.createElement("path", {
34
- d: "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z",
35
- vectorEffect: "non-scaling-stroke",
34
+ d: "M7 0C5.9 0 5 .9 5 2v7c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2V2c0-1.1-.9-2-2-2H7ZM2 5C.9 5 0 5.9 0 7v7c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2v-2H9v2H2V7h2V5H2Z",
36
35
  fill: "currentColor"
37
36
  })));
38
37
 
package/lib/index.d.ts CHANGED
@@ -58,6 +58,7 @@ export { default as Combobox, ComboboxOption, ComboboxGroup } from './components
58
58
  export { default as Popover } from './components/Popover';
59
59
  export { default as Timeline, TimelineItem } from './components/Timeline';
60
60
  export { default as TextEllipsis } from './components/TextEllipsis';
61
+ export { default as CopyButton } from './components/CopyButton';
61
62
  /**
62
63
  * Helpers / Utils
63
64
  */
package/lib/index.js CHANGED
@@ -2325,23 +2325,27 @@ var RadioCardGroup = function (_a) {
2325
2325
  RadioCardGroup.displayName = 'RadioCardGroup';
2326
2326
 
2327
2327
  var Checkbox = React.forwardRef(function (_a, ref) {
2328
- var id = _a.id, label = _a.label, labelDescription = _a.labelDescription, error = _a.error, checkboxRef = _a.checkboxRef, className = _a.className, onChange = _a.onChange, onFocus = _a.onFocus, onBlur = _a.onBlur, ariaDescribedby = _a["aria-describedby"], _b = _a.disabled, disabled = _b === void 0 ? false : _b, _c = _a.checked, checked = _c === void 0 ? false : _c; _a.children; var other = tslib.__rest(_a, ["id", "label", "labelDescription", "error", "checkboxRef", "className", "onChange", "onFocus", "onBlur", 'aria-describedby', "disabled", "checked", "children"]);
2329
- var _d = tslib.__read(React.useState(checked), 2), isChecked = _d[0], setIsChecked = _d[1];
2330
- var _e = tslib.__read(React.useState(false), 2), focused = _e[0], setFocused = _e[1];
2328
+ var id = _a.id, label = _a.label, labelDescription = _a.labelDescription, error = _a.error, checkboxRef = _a.checkboxRef, className = _a.className, onChange = _a.onChange, onFocus = _a.onFocus, onBlur = _a.onBlur, ariaDescribedby = _a["aria-describedby"], _b = _a.disabled, disabled = _b === void 0 ? false : _b, _c = _a.checked, checked = _c === void 0 ? false : _c, _d = _a.indeterminate, indeterminate = _d === void 0 ? false : _d; _a.children; var other = tslib.__rest(_a, ["id", "label", "labelDescription", "error", "checkboxRef", "className", "onChange", "onFocus", "onBlur", 'aria-describedby', "disabled", "checked", "indeterminate", "children"]);
2329
+ var _e = tslib.__read(React.useState(checked), 2), isChecked = _e[0], setIsChecked = _e[1];
2330
+ var _f = tslib.__read(React.useState(indeterminate), 2), isIndeterminate = _f[0], setIsIndeterminate = _f[1];
2331
+ var _g = tslib.__read(React.useState(false), 2), focused = _g[0], setFocused = _g[1];
2331
2332
  var checkRef = React.useRef(null);
2332
2333
  React.useEffect(function () {
2333
2334
  setIsChecked(checked);
2334
2335
  }, [checked]);
2336
+ React.useEffect(function () {
2337
+ setIsIndeterminate(indeterminate);
2338
+ }, [indeterminate]);
2335
2339
  var refProp = ref || checkboxRef;
2336
2340
  if (typeof refProp === 'function') {
2337
2341
  refProp(checkRef.current);
2338
2342
  }
2339
- var _f = React.useMemo(function () {
2343
+ var _h = React.useMemo(function () {
2340
2344
  return {
2341
2345
  labelDescriptionId: nextId__default["default"](),
2342
2346
  errorId: nextId__default["default"]()
2343
2347
  };
2344
- }, []), errorId = _f.errorId, labelDescriptionId = _f.labelDescriptionId;
2348
+ }, []), errorId = _h.errorId, labelDescriptionId = _h.labelDescriptionId;
2345
2349
  var ariaDescribedbyId = ariaDescribedby;
2346
2350
  if (error) {
2347
2351
  ariaDescribedbyId = addIdRef(ariaDescribedbyId, errorId);
@@ -2349,6 +2353,21 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2349
2353
  if (labelDescription) {
2350
2354
  ariaDescribedbyId = addIdRef(ariaDescribedbyId, labelDescriptionId);
2351
2355
  }
2356
+ var iconType = isChecked
2357
+ ? 'checkbox-checked'
2358
+ : 'checkbox-unchecked';
2359
+ React.useEffect(function () {
2360
+ var input;
2361
+ if (refProp && typeof refProp !== 'function') {
2362
+ input = refProp.current;
2363
+ }
2364
+ else {
2365
+ input = checkRef.current;
2366
+ }
2367
+ if (input) {
2368
+ input.indeterminate = isIndeterminate;
2369
+ }
2370
+ }, [isIndeterminate, refProp, checkRef]);
2352
2371
  return (React__default["default"].createElement("div", { className: "Checkbox__wrap" },
2353
2372
  React__default["default"].createElement("div", { className: classNames__default["default"]('Checkbox is--flex-row', className) },
2354
2373
  React__default["default"].createElement("input", tslib.__assign({ id: id, ref: typeof refProp === 'function' || !refProp ? checkRef : refProp, type: "checkbox", checked: isChecked, disabled: disabled, onFocus: function (e) {
@@ -2362,6 +2381,9 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2362
2381
  onBlur(e);
2363
2382
  }
2364
2383
  }, "aria-describedby": ariaDescribedbyId, onChange: function (e) {
2384
+ if (isIndeterminate) {
2385
+ setIsIndeterminate(false);
2386
+ }
2365
2387
  setIsChecked(e.target.checked);
2366
2388
  if (onChange) {
2367
2389
  onChange(e);
@@ -2374,10 +2396,10 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2374
2396
  'Checkbox__overlay--disabled': disabled,
2375
2397
  'Checkbox__overlay--focused': focused,
2376
2398
  'Field--has-error': error
2377
- }), type: isChecked ? 'checkbox-checked' : 'checkbox-unchecked', "aria-hidden": "true", onClick: function () {
2399
+ }), type: iconType, "aria-hidden": "true", onClick: function () {
2378
2400
  var _a, _b;
2379
2401
  if (refProp && typeof refProp !== 'function') {
2380
- (_a = refProp === null || refProp === void 0 ? void 0 : refProp.current) === null || _a === void 0 ? void 0 : _a.click();
2402
+ (_a = refProp.current) === null || _a === void 0 ? void 0 : _a.click();
2381
2403
  }
2382
2404
  else {
2383
2405
  (_b = checkRef.current) === null || _b === void 0 ? void 0 : _b.click();
@@ -2634,8 +2656,10 @@ var TagLabel = function (_a) {
2634
2656
  };
2635
2657
  TagLabel.displayName = 'TagLabel';
2636
2658
  var Tag = function (_a) {
2637
- var children = _a.children, className = _a.className, other = tslib.__rest(_a, ["children", "className"]);
2638
- return (React__default["default"].createElement("div", tslib.__assign({ className: classNames__default["default"]('Tag', className) }, other), children));
2659
+ var children = _a.children, className = _a.className, _b = _a.size, size = _b === void 0 ? 'default' : _b, other = tslib.__rest(_a, ["children", "className", "size"]);
2660
+ return (React__default["default"].createElement("div", tslib.__assign({ className: classNames__default["default"]('Tag', className, {
2661
+ 'Tag--small': size === 'small'
2662
+ }) }, other), children));
2639
2663
  };
2640
2664
  Tag.displayName = 'Tag';
2641
2665
 
@@ -4096,6 +4120,95 @@ var TextEllipsis = React__default["default"].forwardRef(function (_a, ref) {
4096
4120
  });
4097
4121
  TextEllipsis.displayName = 'TextEllipsis';
4098
4122
 
4123
+ function copyTextToClipboard(text) {
4124
+ return tslib.__awaiter(this, void 0, void 0, function () {
4125
+ var copied, element, range, selection;
4126
+ return tslib.__generator(this, function (_a) {
4127
+ switch (_a.label) {
4128
+ case 0:
4129
+ copied = false;
4130
+ if (!('clipboard' in navigator)) return [3 /*break*/, 5];
4131
+ _a.label = 1;
4132
+ case 1:
4133
+ _a.trys.push([1, 3, , 4]);
4134
+ return [4 /*yield*/, navigator.clipboard.writeText(text)];
4135
+ case 2:
4136
+ _a.sent();
4137
+ copied = true;
4138
+ return [3 /*break*/, 4];
4139
+ case 3:
4140
+ _a.sent();
4141
+ return [3 /*break*/, 4];
4142
+ case 4: return [3 /*break*/, 6];
4143
+ case 5:
4144
+ element = document.createElement('span');
4145
+ element.textContent = text;
4146
+ element.setAttribute('aria-hidden', 'true');
4147
+ element.style.position = 'absolute';
4148
+ element.style.height = '1px';
4149
+ element.style.width = '1px';
4150
+ element.style.overflow = 'hidden';
4151
+ element.style.clip = 'rect(1px, 1px, 1px, 1px)';
4152
+ element.style.marginTop = '-1px';
4153
+ element.style.webkitUserSelect = 'text';
4154
+ element.style.userSelect = 'text';
4155
+ document.body.appendChild(element);
4156
+ range = document.createRange();
4157
+ selection = document.getSelection();
4158
+ range.selectNodeContents(element);
4159
+ selection === null || selection === void 0 ? void 0 : selection.addRange(range);
4160
+ try {
4161
+ document.execCommand(text);
4162
+ copied = true;
4163
+ }
4164
+ catch (ex) {
4165
+ // no fallback
4166
+ }
4167
+ element.remove();
4168
+ _a.label = 6;
4169
+ case 6: return [2 /*return*/, copied];
4170
+ }
4171
+ });
4172
+ });
4173
+ }
4174
+
4175
+ var NOTIFICATION_TIMEOUT_MS = 2000;
4176
+ var CopyButton = React.forwardRef(function (_a, ref) {
4177
+ var className = _a.className, value = _a.value, _b = _a.variant, variant = _b === void 0 ? 'tertiary' : _b, _c = _a.children, children = _c === void 0 ? 'Copy' : _c, _d = _a.notificationLabel, notificationLabel = _d === void 0 ? 'Copied' : _d, _e = _a.hideVisibleLabel, hideVisibleLabel = _e === void 0 ? false : _e, _f = _a.tooltipPlacement, tooltipPlacement = _f === void 0 ? 'auto' : _f, onCopy = _a.onCopy, props = tslib.__rest(_a, ["className", "value", "variant", "children", "notificationLabel", "hideVisibleLabel", "tooltipPlacement", "onCopy"]);
4178
+ var _g = tslib.__read(React.useState(false), 2), copied = _g[0], setCopied = _g[1];
4179
+ var copyButtonRef = useSharedRef(ref);
4180
+ var handleClick = React.useCallback(function () {
4181
+ copyTextToClipboard(value);
4182
+ setCopied(true);
4183
+ if (typeof onCopy === 'function') {
4184
+ onCopy(value);
4185
+ }
4186
+ }, [value, onCopy]);
4187
+ React.useEffect(function () {
4188
+ var timeoutId = setTimeout(function () {
4189
+ setCopied(false);
4190
+ }, NOTIFICATION_TIMEOUT_MS);
4191
+ return function () {
4192
+ clearTimeout(timeoutId);
4193
+ };
4194
+ }, [copied]);
4195
+ // The visibility of the tooltip only needs to be controlled
4196
+ // when we are visually displaying the notification label
4197
+ var showTooltip = hideVisibleLabel && !copied ? undefined : copied ? true : false;
4198
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
4199
+ React__default["default"].createElement(Button, tslib.__assign({ className: classNames__default["default"](className, {
4200
+ 'Button--condensed': hideVisibleLabel
4201
+ }), ref: copyButtonRef, variant: variant, onClick: handleClick }, props),
4202
+ React__default["default"].createElement(Icon, { type: copied ? 'check-solid' : 'copy' }),
4203
+ hideVisibleLabel ? React__default["default"].createElement(Offscreen, null, children) : children),
4204
+ React__default["default"].createElement(Tooltip, { target: copyButtonRef, placement: tooltipPlacement, association: "none", show: showTooltip }, hideVisibleLabel && !copied ? children : notificationLabel),
4205
+ typeof document !== 'undefined' &&
4206
+ reactDom.createPortal(React__default["default"].createElement(Offscreen, { "aria-live": "polite" }, copied ? notificationLabel : ' '),
4207
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc
4208
+ document.body)));
4209
+ });
4210
+ CopyButton.displayName = 'CopyButton';
4211
+
4099
4212
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
4100
4213
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
4101
4214
  var ThemeContext = React.createContext({
@@ -4190,6 +4303,7 @@ exports.ColumnRight = ColumnRight;
4190
4303
  exports.Combobox = Combobox;
4191
4304
  exports.ComboboxGroup = ComboboxGroup;
4192
4305
  exports.ComboboxOption = ComboboxOption;
4306
+ exports.CopyButton = CopyButton;
4193
4307
  exports.DescriptionDetails = DescriptionDetails;
4194
4308
  exports.DescriptionList = DescriptionList;
4195
4309
  exports.DescriptionListItem = DescriptionListItem;
@@ -0,0 +1 @@
1
+ export default function copyTextToClipboard(text: string): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "6.5.0-canary.dbafa2f9",
3
+ "version": "6.6.0",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Fully accessible react components library for Deque Cauldron",
6
6
  "homepage": "https://cauldron.dequelabs.com/",
@@ -93,7 +93,8 @@
93
93
  "exclude": [
94
94
  "lib",
95
95
  "coverage",
96
- "test/**/*.js"
96
+ "test/**/*.js",
97
+ "test/**/*.e2e.tsx"
97
98
  ]
98
99
  }
99
100
  }