@deque/cauldron-react 6.5.0-canary.946b10da → 6.5.0-canary.c570eceb

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.
@@ -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;
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
@@ -4098,6 +4098,95 @@ var TextEllipsis = React__default["default"].forwardRef(function (_a, ref) {
4098
4098
  });
4099
4099
  TextEllipsis.displayName = 'TextEllipsis';
4100
4100
 
4101
+ function copyTextToClipboard(text) {
4102
+ return tslib.__awaiter(this, void 0, void 0, function () {
4103
+ var copied, element, range, selection;
4104
+ return tslib.__generator(this, function (_a) {
4105
+ switch (_a.label) {
4106
+ case 0:
4107
+ copied = false;
4108
+ if (!('clipboard' in navigator)) return [3 /*break*/, 5];
4109
+ _a.label = 1;
4110
+ case 1:
4111
+ _a.trys.push([1, 3, , 4]);
4112
+ return [4 /*yield*/, navigator.clipboard.writeText(text)];
4113
+ case 2:
4114
+ _a.sent();
4115
+ copied = true;
4116
+ return [3 /*break*/, 4];
4117
+ case 3:
4118
+ _a.sent();
4119
+ return [3 /*break*/, 4];
4120
+ case 4: return [3 /*break*/, 6];
4121
+ case 5:
4122
+ element = document.createElement('span');
4123
+ element.textContent = text;
4124
+ element.setAttribute('aria-hidden', 'true');
4125
+ element.style.position = 'absolute';
4126
+ element.style.height = '1px';
4127
+ element.style.width = '1px';
4128
+ element.style.overflow = 'hidden';
4129
+ element.style.clip = 'rect(1px, 1px, 1px, 1px)';
4130
+ element.style.marginTop = '-1px';
4131
+ element.style.webkitUserSelect = 'text';
4132
+ element.style.userSelect = 'text';
4133
+ document.body.appendChild(element);
4134
+ range = document.createRange();
4135
+ selection = document.getSelection();
4136
+ range.selectNodeContents(element);
4137
+ selection === null || selection === void 0 ? void 0 : selection.addRange(range);
4138
+ try {
4139
+ document.execCommand(text);
4140
+ copied = true;
4141
+ }
4142
+ catch (ex) {
4143
+ // no fallback
4144
+ }
4145
+ element.remove();
4146
+ _a.label = 6;
4147
+ case 6: return [2 /*return*/, copied];
4148
+ }
4149
+ });
4150
+ });
4151
+ }
4152
+
4153
+ var NOTIFICATION_TIMEOUT_MS = 2000;
4154
+ var CopyButton = React.forwardRef(function (_a, ref) {
4155
+ 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"]);
4156
+ var _g = tslib.__read(React.useState(false), 2), copied = _g[0], setCopied = _g[1];
4157
+ var copyButtonRef = useSharedRef(ref);
4158
+ var handleClick = React.useCallback(function () {
4159
+ copyTextToClipboard(value);
4160
+ setCopied(true);
4161
+ if (typeof onCopy === 'function') {
4162
+ onCopy(value);
4163
+ }
4164
+ }, [value, onCopy]);
4165
+ React.useEffect(function () {
4166
+ var timeoutId = setTimeout(function () {
4167
+ setCopied(false);
4168
+ }, NOTIFICATION_TIMEOUT_MS);
4169
+ return function () {
4170
+ clearTimeout(timeoutId);
4171
+ };
4172
+ }, [copied]);
4173
+ // The visibility of the tooltip only needs to be controlled
4174
+ // when we are visually displaying the notification label
4175
+ var showTooltip = hideVisibleLabel && !copied ? undefined : copied ? true : false;
4176
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
4177
+ React__default["default"].createElement(Button, tslib.__assign({ className: classNames__default["default"](className, {
4178
+ 'Button--condensed': hideVisibleLabel
4179
+ }), ref: copyButtonRef, variant: variant, onClick: handleClick }, props),
4180
+ React__default["default"].createElement(Icon, { type: copied ? 'check-solid' : 'copy' }),
4181
+ hideVisibleLabel ? React__default["default"].createElement(Offscreen, null, children) : children),
4182
+ React__default["default"].createElement(Tooltip, { target: copyButtonRef, placement: tooltipPlacement, association: "none", show: showTooltip }, hideVisibleLabel && !copied ? children : notificationLabel),
4183
+ typeof document !== 'undefined' &&
4184
+ reactDom.createPortal(React__default["default"].createElement(Offscreen, { "aria-live": "polite" }, copied ? notificationLabel : ' '),
4185
+ // eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc
4186
+ document.body)));
4187
+ });
4188
+ CopyButton.displayName = 'CopyButton';
4189
+
4101
4190
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
4102
4191
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
4103
4192
  var ThemeContext = React.createContext({
@@ -4192,6 +4281,7 @@ exports.ColumnRight = ColumnRight;
4192
4281
  exports.Combobox = Combobox;
4193
4282
  exports.ComboboxGroup = ComboboxGroup;
4194
4283
  exports.ComboboxOption = ComboboxOption;
4284
+ exports.CopyButton = CopyButton;
4195
4285
  exports.DescriptionDetails = DescriptionDetails;
4196
4286
  exports.DescriptionList = DescriptionList;
4197
4287
  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.946b10da",
3
+ "version": "6.5.0-canary.c570eceb",
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
  }