@deque/cauldron-react 6.2.1 → 6.3.0-canary.39049805

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,6 +1,5 @@
1
1
  import React from 'react';
2
- interface BreadcrumbLinkProps extends Omit<React.LinkHTMLAttributes<HTMLLinkElement>, 'as'> {
3
- as?: React.ElementType;
4
- }
5
- declare const BreadcrumbLink: React.ForwardRefExoticComponent<BreadcrumbLinkProps & React.RefAttributes<HTMLElement>>;
2
+ import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
3
+ type BreadcrumbLinkProps = PolymorphicProps<React.LinkHTMLAttributes<HTMLLinkElement>>;
4
+ declare const BreadcrumbLink: PolymorphicComponent<BreadcrumbLinkProps>;
6
5
  export default BreadcrumbLink;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- interface Props extends React.HTMLAttributes<HTMLElement> {
2
+ import type { PolymorphicComponent, PolymorphicProps } from '../../utils/polymorphicComponent';
3
+ interface FieldWrapProps extends PolymorphicProps<React.HTMLAttributes<HTMLElement>> {
3
4
  children: React.ReactNode;
4
- as?: React.ElementType | string;
5
5
  }
6
- declare const FieldWrap: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLElement>>;
6
+ declare const FieldWrap: PolymorphicComponent<FieldWrapProps>;
7
7
  export default FieldWrap;
@@ -1,14 +1,8 @@
1
- /**
2
- * Unfortunately, eslint does not recognize the Polymorphic component has propTypes set
3
- *
4
- * We might be able to remove this if we upgrade eslint and associated plugins
5
- * See: https://github.com/dequelabs/cauldron/issues/451
6
- */
7
1
  import React from 'react';
8
- import * as Polymorphic from '../../utils/polymorphic-type';
9
2
  import { IconType } from '../Icon';
10
3
  import { TooltipProps } from '../Tooltip';
11
- export interface IconButtonOwnProps {
4
+ import { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
5
+ export interface IconButtonProps extends PolymorphicProps<React.HTMLAttributes<HTMLButtonElement>, 'button'> {
12
6
  icon: IconType;
13
7
  label: React.ReactNode;
14
8
  tooltipPlacement?: TooltipProps['placement'];
@@ -17,12 +11,5 @@ export interface IconButtonOwnProps {
17
11
  variant?: 'primary' | 'secondary' | 'error';
18
12
  large?: boolean;
19
13
  }
20
- type PolymorphicIconButton = Polymorphic.ForwardRefComponent<'button', IconButtonOwnProps>;
21
- /**
22
- * Unfortunately, eslint does not recognize that this Polymorphic component has a displayName set
23
- *
24
- * We might be able to remove this if we upgrade eslint and associated plugins
25
- * See: https://github.com/dequelabs/cauldron/issues/451
26
- */
27
- declare const IconButton: PolymorphicIconButton;
14
+ declare const IconButton: PolymorphicComponent<IconButtonProps, "button">;
28
15
  export default IconButton;
@@ -4,8 +4,5 @@ export interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement>
4
4
  variant?: 'button' | 'button-secondary';
5
5
  thin?: boolean;
6
6
  }
7
- declare const Link: {
8
- ({ children, linkRef, className, variant, thin, ...other }: LinkProps): React.JSX.Element;
9
- displayName: string;
10
- };
7
+ declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
11
8
  export default Link;
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import type { ListboxOption } from './ListboxContext';
3
3
  import type { ListboxValue } from './ListboxOption';
4
- interface ListboxProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onSelect'> {
5
- as?: React.ElementType | string;
4
+ import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
5
+ interface ListboxProps extends PolymorphicProps<Omit<React.HTMLAttributes<HTMLElement>, 'onSelect'>> {
6
6
  value?: ListboxValue;
7
7
  navigation?: 'cycle' | 'bound';
8
8
  onSelectionChange?: <T extends HTMLElement = HTMLElement>({ value }: {
@@ -12,5 +12,5 @@ interface ListboxProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onSelect
12
12
  }) => void;
13
13
  onActiveChange?: (option: ListboxOption) => void;
14
14
  }
15
- declare const Listbox: React.ForwardRefExoticComponent<ListboxProps & React.RefAttributes<HTMLElement>>;
15
+ declare const Listbox: PolymorphicComponent<ListboxProps>;
16
16
  export default Listbox;
@@ -1,9 +1,9 @@
1
1
  import { ContentNode } from '../../types';
2
2
  import React from 'react';
3
- interface ListboxGroupProps extends React.HTMLAttributes<HTMLElement> {
4
- as?: React.ElementType | string;
3
+ import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
4
+ interface ListboxGroupProps extends PolymorphicProps<React.HTMLAttributes<HTMLElement>> {
5
5
  groupLabelProps?: React.HTMLAttributes<HTMLLIElement>;
6
6
  label: ContentNode;
7
7
  }
8
- declare const ListboxGroup: React.ForwardRefExoticComponent<ListboxGroupProps & React.RefAttributes<HTMLElement>>;
8
+ declare const ListboxGroup: PolymorphicComponent<ListboxGroupProps>;
9
9
  export default ListboxGroup;
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
+ import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
2
3
  export type ListboxValue = Readonly<string | number | undefined>;
3
- interface ListboxOptionsProps extends React.HTMLAttributes<HTMLElement> {
4
- as?: React.ElementType | string;
4
+ interface ListboxOptionProps extends PolymorphicProps<React.HTMLAttributes<HTMLElement>> {
5
5
  value?: ListboxValue;
6
6
  disabled?: boolean;
7
7
  activeClass?: string;
8
8
  }
9
- declare const ListboxOption: React.ForwardRefExoticComponent<ListboxOptionsProps & React.RefAttributes<HTMLElement>>;
9
+ declare const ListboxOption: PolymorphicComponent<ListboxOptionProps>;
10
10
  export default ListboxOption;
@@ -0,0 +1,13 @@
1
+ import React, { ChangeEvent, InputHTMLAttributes } from 'react';
2
+ import type { ContentNode } from '../../types';
3
+ interface SearchFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
4
+ label: ContentNode;
5
+ value?: string;
6
+ defaultValue?: string;
7
+ onChange?: (value: string, e: ChangeEvent<HTMLInputElement>) => void;
8
+ hideLabel?: boolean;
9
+ isForm?: boolean;
10
+ trailingChildren?: React.ReactNode;
11
+ }
12
+ declare const SearchField: React.ForwardRefExoticComponent<SearchFieldProps & React.RefAttributes<HTMLInputElement>>;
13
+ export default SearchField;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { type TooltipProps } from '../Tooltip';
3
+ import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
4
+ interface TextEllipsisProps extends PolymorphicProps<React.HTMLAttributes<HTMLElement>> {
5
+ children: string;
6
+ maxLines?: number;
7
+ refProp?: string;
8
+ tooltipProps?: Omit<TooltipProps, 'target' | 'association'>;
9
+ }
10
+ declare const TextEllipsis: PolymorphicComponent<TextEllipsisProps>;
11
+ export default TextEllipsis;
@@ -5,7 +5,7 @@ export interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {
5
5
  className?: string;
6
6
  target: React.RefObject<HTMLElement> | HTMLElement;
7
7
  variant?: 'text' | 'info' | 'big';
8
- association?: 'aria-labelledby' | 'aria-describedby';
8
+ association?: 'aria-labelledby' | 'aria-describedby' | 'none';
9
9
  show?: boolean | undefined;
10
10
  placement?: Placement;
11
11
  portal?: React.RefObject<HTMLElement> | HTMLElement;
@@ -0,0 +1,7 @@
1
+ import React, { HTMLAttributes, ReactNode } from 'react';
2
+ export interface TextFieldWrapperProps extends HTMLAttributes<HTMLDivElement> {
3
+ children: ReactNode;
4
+ className?: string;
5
+ }
6
+ declare const TextFieldWrapper: React.ForwardRefExoticComponent<TextFieldWrapperProps & React.RefAttributes<HTMLDivElement>>;
7
+ export default TextFieldWrapper;
package/lib/index.d.ts CHANGED
@@ -30,6 +30,7 @@ export { default as Checkbox } from './components/Checkbox';
30
30
  export { default as Tooltip, TooltipHead, TooltipContent } from './components/Tooltip';
31
31
  export { default as TooltipTabstop } from './components/TooltipTabstop';
32
32
  export { default as TextField } from './components/TextField';
33
+ export { default as SearchField } from './components/SearchField';
33
34
  export { default as ClickOutsideListener } from './components/ClickOutsideListener';
34
35
  export { default as ExpandCollapsePanel, PanelTrigger } from './components/ExpandCollapsePanel';
35
36
  export { default as Sidebar, SideBarItem } from './components/SideBar';
@@ -54,6 +55,7 @@ export { default as Listbox, ListboxOption, ListboxGroup } from './components/Li
54
55
  export { default as Combobox, ComboboxOption, ComboboxGroup } from './components/Combobox';
55
56
  export { default as Popover } from './components/Popover';
56
57
  export { default as Timeline, TimelineItem } from './components/Timeline';
58
+ export { default as TextEllipsis } from './components/TextEllipsis';
57
59
  /**
58
60
  * Helpers / Utils
59
61
  */
package/lib/index.js CHANGED
@@ -1601,6 +1601,43 @@ var Button = React.forwardRef(function (_a, ref) {
1601
1601
  });
1602
1602
  Button.displayName = 'Button';
1603
1603
 
1604
+ /**
1605
+ * Returns a unique set of id refs from the provided string
1606
+ * @param ids - string of id refs
1607
+ */
1608
+ function idRefs(ids) {
1609
+ if (!ids || !ids.trim()) {
1610
+ return new Set();
1611
+ }
1612
+ return new Set(ids.trim().split(/\s+/));
1613
+ }
1614
+ /**
1615
+ * Returns an updated id ref string with the provided id value added
1616
+ * @param ids - string of id refs
1617
+ * @param id - id to add
1618
+ */
1619
+ function addIdRef(ids, id) {
1620
+ return tslib.__spreadArray([], tslib.__read(idRefs(ids).add(id)), false).join(' ');
1621
+ }
1622
+ /**
1623
+ * Returns an updated id ref string with the provided id value removed
1624
+ * @param ids - string of id refs
1625
+ * @param id - id to remove
1626
+ */
1627
+ function removeIdRef(_ids, id) {
1628
+ var ids = idRefs(_ids);
1629
+ ids.delete(id);
1630
+ return tslib.__spreadArray([], tslib.__read(ids), false).join(' ');
1631
+ }
1632
+ /**
1633
+ * Returns if an id ref string contains the provided id value
1634
+ * @param ids - string of id refs
1635
+ * @param id - id to check if it exists in the provided idRef string
1636
+ */
1637
+ function hasIdRef(ids, id) {
1638
+ return idRefs(ids).has(id);
1639
+ }
1640
+
1604
1641
  var TIP_HIDE_DELAY = 100;
1605
1642
  // fires a custom "cauldron:tooltip:show" / "cauldron:tooltip:hide" event
1606
1643
  // to allow projects using cauldron to hook into when a tooltip is shown/hidden
@@ -1622,6 +1659,7 @@ function Tooltip(_a) {
1622
1659
  var _j = tslib.__read(React.useState(null), 2), targetElement = _j[0], setTargetElement = _j[1];
1623
1660
  var _k = tslib.__read(React.useState(null), 2), tooltipElement = _k[0], setTooltipElement = _k[1];
1624
1661
  var _l = tslib.__read(React.useState(null), 2), arrowElement = _l[0], setArrowElement = _l[1];
1662
+ var hasAriaAssociation = association !== 'none';
1625
1663
  var _m = reactPopper.usePopper(targetElement, tooltipElement, {
1626
1664
  placement: initialPlacement,
1627
1665
  modifiers: [
@@ -1723,11 +1761,19 @@ function Tooltip(_a) {
1723
1761
  }, [tooltipElement, show, hide]);
1724
1762
  // Keep the target's id in sync
1725
1763
  React.useEffect(function () {
1726
- var attrText = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute(association);
1727
- if (!(attrText === null || attrText === void 0 ? void 0 : attrText.includes(id || ''))) {
1728
- targetElement === null || targetElement === void 0 ? void 0 : targetElement.setAttribute(association, [id, attrText].filter(Boolean).join(' '));
1764
+ if (hasAriaAssociation) {
1765
+ var idRefs = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute(association);
1766
+ if (!hasIdRef(idRefs, id)) {
1767
+ targetElement === null || targetElement === void 0 ? void 0 : targetElement.setAttribute(association, addIdRef(idRefs, id));
1768
+ }
1729
1769
  }
1730
- }, [targetElement, id]);
1770
+ return function () {
1771
+ if (targetElement && hasAriaAssociation) {
1772
+ var idRefs = targetElement.getAttribute(association);
1773
+ targetElement.setAttribute(association, removeIdRef(idRefs, id));
1774
+ }
1775
+ };
1776
+ }, [targetElement, id, association]);
1731
1777
  return (React__default["default"].createElement(React__default["default"].Fragment, null, (showTooltip || hideElementOnHidden) && isBrowser()
1732
1778
  ? reactDom.createPortal(React__default["default"].createElement("div", tslib.__assign({ id: id, className: classNames__default["default"]('Tooltip', "Tooltip--".concat(placement), className, {
1733
1779
  TooltipInfo: variant === 'info',
@@ -1751,13 +1797,6 @@ var TooltipContent = function (_a) {
1751
1797
  return (React__default["default"].createElement("div", tslib.__assign({ className: classNames__default["default"]('TooltipContent', className) }, other)));
1752
1798
  };
1753
1799
 
1754
- /**
1755
- * Unfortunately, eslint does not recognize that this Polymorphic component has a displayName set
1756
- *
1757
- * We might be able to remove this if we upgrade eslint and associated plugins
1758
- * See: https://github.com/dequelabs/cauldron/issues/451
1759
- */
1760
- // eslint-disable-next-line react/display-name
1761
1800
  var IconButton = React.forwardRef(function (_a, ref) {
1762
1801
  var _b = _a.as, Component = _b === void 0 ? 'button' : _b, icon = _a.icon, label = _a.label, _c = _a.tooltipPlacement, tooltipPlacement = _c === void 0 ? 'auto' : _c, tooltipVariant = _a.tooltipVariant, tooltipPortal = _a.tooltipPortal, className = _a.className, _d = _a.variant, variant = _d === void 0 ? 'secondary' : _d, disabled = _a.disabled, _e = _a.tabIndex, tabIndex = _e === void 0 ? 0 : _e, large = _a.large, other = tslib.__rest(_a, ["as", "icon", "label", "tooltipPlacement", "tooltipVariant", "tooltipPortal", "className", "variant", "disabled", "tabIndex", "large"]);
1763
1802
  var internalRef = React.useRef();
@@ -1968,15 +2007,15 @@ var Toast = /** @class */ (function (_super) {
1968
2007
  return Toast;
1969
2008
  }(React__default["default"].Component));
1970
2009
 
1971
- var Link = function (_a) {
2010
+ var Link = React.forwardRef(function (_a, ref) {
1972
2011
  var children = _a.children, linkRef = _a.linkRef, className = _a.className, variant = _a.variant, thin = _a.thin, other = tslib.__rest(_a, ["children", "linkRef", "className", "variant", "thin"]);
1973
- return (React__default["default"].createElement("a", tslib.__assign({ ref: linkRef, className: classNames__default["default"](className, {
2012
+ return (React__default["default"].createElement("a", tslib.__assign({ ref: ref || linkRef, className: classNames__default["default"](className, {
1974
2013
  Link: !variant,
1975
2014
  'Button--primary': variant === 'button',
1976
2015
  'Button--secondary': variant === 'button-secondary',
1977
2016
  'Button--thin': thin
1978
2017
  }) }, other), children));
1979
- };
2018
+ });
1980
2019
  Link.displayName = 'Link';
1981
2020
 
1982
2021
  var Loader = React__default["default"].forwardRef(function (_a, ref) {
@@ -1998,19 +2037,6 @@ var randomId = function () {
1998
2037
  return "x_".concat(i++, "_").concat(num);
1999
2038
  };
2000
2039
 
2001
- /**
2002
- * Adds an id to a token list attribute if its not already present in the list
2003
- */
2004
- var tokenList = function (id, currentVal) {
2005
- if (currentVal === void 0) { currentVal = ''; }
2006
- var values = currentVal.split(' ');
2007
- if (values.includes(id)) {
2008
- return currentVal;
2009
- }
2010
- values.push(id);
2011
- return values.join(' ').trim();
2012
- };
2013
-
2014
2040
  var Select = React__default["default"].forwardRef(function (_a, ref) {
2015
2041
  var options = _a.options, children = _a.children, disabled = _a.disabled, label = _a.label, id = _a.id, required = _a.required, _b = _a.requiredText, requiredText = _b === void 0 ? 'Required' : _b, error = _a.error, value = _a.value, ariaDescribedby = _a["aria-describedby"], defaultValue = _a.defaultValue, onChange = _a.onChange, rest = tslib.__rest(_a, ["options", "children", "disabled", "label", "id", "required", "requiredText", "error", "value", 'aria-describedby', "defaultValue", "onChange"]);
2016
2042
  if (options && children) {
@@ -2044,7 +2070,7 @@ var Select = React__default["default"].forwardRef(function (_a, ref) {
2044
2070
  dynamicProps.defaultValue = defaultValue;
2045
2071
  }
2046
2072
  if (error) {
2047
- dynamicProps['aria-describedby'] = tokenList(errorId, ariaDescribedby);
2073
+ dynamicProps['aria-describedby'] = addIdRef(ariaDescribedby, errorId);
2048
2074
  }
2049
2075
  // In order to support controlled selects, we
2050
2076
  // have to attach an `onChange` to the select.
@@ -2260,10 +2286,10 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2260
2286
  }, []), errorId = _f.errorId, labelDescriptionId = _f.labelDescriptionId;
2261
2287
  var ariaDescribedbyId = ariaDescribedby;
2262
2288
  if (error) {
2263
- ariaDescribedbyId = tokenList(errorId, ariaDescribedbyId);
2289
+ ariaDescribedbyId = addIdRef(ariaDescribedbyId, errorId);
2264
2290
  }
2265
2291
  if (labelDescription) {
2266
- ariaDescribedbyId = tokenList(labelDescriptionId, ariaDescribedbyId);
2292
+ ariaDescribedbyId = addIdRef(ariaDescribedbyId, labelDescriptionId);
2267
2293
  }
2268
2294
  return (React__default["default"].createElement("div", { className: "Checkbox__wrap" },
2269
2295
  React__default["default"].createElement("div", { className: classNames__default["default"]('Checkbox is--flex-row', className) },
@@ -2349,7 +2375,7 @@ var TextField = /** @class */ (function (_super) {
2349
2375
  var Field = multiline ? 'textarea' : 'input';
2350
2376
  var inputProps = {
2351
2377
  'aria-describedby': error
2352
- ? tokenList(this.errorId, ariaDescribedby)
2378
+ ? addIdRef(ariaDescribedby, this.errorId)
2353
2379
  : ariaDescribedby
2354
2380
  };
2355
2381
  return (React__default["default"].createElement("div", { className: "Field" },
@@ -2396,6 +2422,44 @@ var TextField = /** @class */ (function (_super) {
2396
2422
  return TextField;
2397
2423
  }(React__default["default"].Component));
2398
2424
 
2425
+ var TextFieldWrapper = React.forwardRef(function (_a, ref) {
2426
+ var className = _a.className, children = _a.children, otherProps = tslib.__rest(_a, ["className", "children"]);
2427
+ return (React__default["default"].createElement("div", tslib.__assign({ className: classNames__default["default"]('TextFieldWrapper', className) }, otherProps, { ref: ref }), children));
2428
+ });
2429
+ TextFieldWrapper.displayName = 'TextFieldWrapper';
2430
+
2431
+ var SearchField = React.forwardRef(function (_a, ref) {
2432
+ var label = _a.label, _b = _a.defaultValue, defaultValue = _b === void 0 ? '' : _b, onChange = _a.onChange, _c = _a.hideLabel, hideLabel = _c === void 0 ? false : _c, _d = _a.placeholder, placeholder = _d === void 0 ? 'Search...' : _d, _e = _a.isForm, isForm = _e === void 0 ? true : _e, propId = _a.id, propValue = _a.value, trailingChildren = _a.trailingChildren, otherProps = tslib.__rest(_a, ["label", "defaultValue", "onChange", "hideLabel", "placeholder", "isForm", "id", "value", "trailingChildren"]);
2433
+ var isControlled = typeof propValue !== 'undefined';
2434
+ var _f = tslib.__read(React.useState(isControlled ? propValue : defaultValue), 2), value = _f[0], setValue = _f[1];
2435
+ var _g = tslib.__read(propId ? [propId] : nextId.useId(1, 'search-field'), 1), id = _g[0];
2436
+ var inputId = React.useRef(id).current;
2437
+ var handleChange = function (e) {
2438
+ var newValue = e.target.value;
2439
+ if (typeof onChange === 'function') {
2440
+ onChange(newValue, e);
2441
+ }
2442
+ if (isControlled) {
2443
+ return;
2444
+ }
2445
+ setValue(newValue);
2446
+ };
2447
+ var Field = isForm ? 'form' : 'div';
2448
+ if (typeof trailingChildren === 'string') {
2449
+ trailingChildren = React__default["default"].createElement("span", null, trailingChildren);
2450
+ }
2451
+ return (React__default["default"].createElement(Field, { role: isForm ? 'search' : undefined, className: "SearchField", "aria-labelledby": isForm ? "".concat(inputId, "-label") : undefined },
2452
+ hideLabel ? (React__default["default"].createElement(Offscreen, null,
2453
+ React__default["default"].createElement("label", { htmlFor: inputId, id: "".concat(inputId, "-label") }, label))) : (React__default["default"].createElement("label", { className: "Field__label", htmlFor: inputId, id: "".concat(inputId, "-label") }, label)),
2454
+ React__default["default"].createElement(TextFieldWrapper, { className: classNames__default["default"]({
2455
+ 'TextFieldWrapper--disabled': otherProps.disabled
2456
+ }) },
2457
+ React__default["default"].createElement(Icon, { type: "magnifying-glass", className: "SearchField__search-icon" }),
2458
+ React__default["default"].createElement("input", tslib.__assign({ id: inputId, value: value, onChange: handleChange, placeholder: placeholder, ref: ref }, otherProps, { className: classNames__default["default"](otherProps.className, 'Field__text-input'), type: "search" })),
2459
+ trailingChildren)));
2460
+ });
2461
+ SearchField.displayName = 'SearchField';
2462
+
2399
2463
  SyntaxHighlighter__default["default"].registerLanguage('javascript', js__default["default"]);
2400
2464
  SyntaxHighlighter__default["default"].registerLanguage('css', css__default["default"]);
2401
2465
  SyntaxHighlighter__default["default"].registerLanguage('html', xml__default["default"]);
@@ -3489,7 +3553,9 @@ var ComboboxOption = React.forwardRef(function (_a, ref) {
3489
3553
  }
3490
3554
  return (React__default["default"].createElement(ListboxOption, tslib.__assign({ as: "li", className: classNames__default["default"]('ComboboxOption', className, {
3491
3555
  'ComboboxOption--disabled': disabled
3492
- }), activeClass: "ComboboxOption--active", ref: comboboxOptionRef, disabled: disabled, id: id, value: propValue }, props),
3556
+ }), activeClass: "ComboboxOption--active",
3557
+ // @ts-expect-error use HTMLElement even though the underlying element is an li element
3558
+ ref: comboboxOptionRef, disabled: disabled, id: id, value: propValue }, props),
3493
3559
  React__default["default"].createElement("span", null,
3494
3560
  React__default["default"].createElement(ComboboxMatch, null, children),
3495
3561
  description && (React__default["default"].createElement("div", { className: "ComboboxOption__description" }, description))),
@@ -3702,7 +3768,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
3702
3768
  noMatchingOptions));
3703
3769
  var errorId = "".concat(id, "-error");
3704
3770
  var inputProps = tslib.__assign(tslib.__assign({}, props), { 'aria-describedby': error
3705
- ? tokenList(errorId, ariaDescribedby)
3771
+ ? addIdRef(ariaDescribedby, errorId)
3706
3772
  : ariaDescribedby });
3707
3773
  return (React__default["default"].createElement("div", { id: id, className: classNames__default["default"]('Combobox', className), ref: comboboxRef },
3708
3774
  name && React__default["default"].createElement("input", { type: "hidden", name: name, value: formValue }),
@@ -3712,9 +3778,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
3712
3778
  }), id: "".concat(id, "-label"), htmlFor: "".concat(id, "-input") },
3713
3779
  React__default["default"].createElement("span", null, label),
3714
3780
  isRequired && (React__default["default"].createElement("span", { className: "Field__required-text" }, requiredText))),
3715
- React__default["default"].createElement("div", { className: classNames__default["default"]('Combobox__input', {
3716
- 'Combobox__input--error': hasError
3717
- }),
3781
+ React__default["default"].createElement(TextFieldWrapper, { className: classNames__default["default"]({ 'TextFieldWrapper--error': hasError }),
3718
3782
  // We're handling click here to open the listbox when the wrapping element is clicked,
3719
3783
  // there's already keyboard handlers to open the listbox on the input element
3720
3784
  onClick: handleInputClick },
@@ -3893,6 +3957,51 @@ function TimelineItem(_a) {
3893
3957
  React__default["default"].createElement("div", { className: "TimelineItem__details" }, children)));
3894
3958
  }
3895
3959
 
3960
+ var TextEllipsis = React__default["default"].forwardRef(function (_a, ref) {
3961
+ var className = _a.className, children = _a.children, maxLines = _a.maxLines, as = _a.as, tooltipProps = _a.tooltipProps, props = tslib.__rest(_a, ["className", "children", "maxLines", "as", "tooltipProps"]);
3962
+ var Element = 'div';
3963
+ var sharedRef = useSharedRef(ref);
3964
+ var _b = tslib.__read(React.useState(false), 2), showTooltip = _b[0], setShowTooltip = _b[1];
3965
+ if (as) {
3966
+ Element = as;
3967
+ }
3968
+ else if (showTooltip) {
3969
+ props = Object.assign({
3970
+ role: 'button',
3971
+ 'aria-disabled': true,
3972
+ tabIndex: 0
3973
+ }, props);
3974
+ }
3975
+ if (typeof maxLines === 'number') {
3976
+ props.style = tslib.__assign({ WebkitLineClamp: maxLines || 2 }, props.style);
3977
+ }
3978
+ React.useEffect(function () {
3979
+ var listener = function () {
3980
+ requestAnimationFrame(function () {
3981
+ var overflowElement = sharedRef.current;
3982
+ if (!overflowElement) {
3983
+ return;
3984
+ }
3985
+ var hasOverflow = typeof maxLines === 'number'
3986
+ ? overflowElement.clientHeight < overflowElement.scrollHeight
3987
+ : overflowElement.clientWidth < overflowElement.scrollWidth;
3988
+ setShowTooltip(hasOverflow);
3989
+ });
3990
+ };
3991
+ var observer = new ResizeObserver(listener);
3992
+ observer.observe(sharedRef.current);
3993
+ return function () {
3994
+ observer === null || observer === void 0 ? void 0 : observer.disconnect();
3995
+ };
3996
+ }, []);
3997
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
3998
+ React__default["default"].createElement(Element, tslib.__assign({ className: classNames__default["default"]('TextEllipsis', className, {
3999
+ 'TextEllipsis--multiline': !!maxLines
4000
+ }), ref: sharedRef }, props), children),
4001
+ showTooltip && (React__default["default"].createElement(Tooltip, tslib.__assign({ target: sharedRef, association: "none" }, tooltipProps), children))));
4002
+ });
4003
+ TextEllipsis.displayName = 'TextEllipsis';
4004
+
3896
4005
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
3897
4006
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
3898
4007
  var ThemeContext = React.createContext({
@@ -4029,6 +4138,7 @@ exports.ProgressBar = ProgressBar;
4029
4138
  exports.RadioCardGroup = RadioCardGroup;
4030
4139
  exports.RadioGroup = RadioGroup;
4031
4140
  exports.Scrim = Scrim;
4141
+ exports.SearchField = SearchField;
4032
4142
  exports.Select = Select;
4033
4143
  exports.SideBar = SideBar;
4034
4144
  exports.SideBarItem = SideBarItem;
@@ -4049,6 +4159,7 @@ exports.Tabs = Tabs;
4049
4159
  exports.Tag = Tag;
4050
4160
  exports.TagButton = TagButton;
4051
4161
  exports.TagLabel = TagLabel;
4162
+ exports.TextEllipsis = TextEllipsis;
4052
4163
  exports.TextField = TextField;
4053
4164
  exports.ThemeContext = ThemeContext;
4054
4165
  exports.ThemeProvider = ThemeProvider;
@@ -0,0 +1,25 @@
1
+ type IdRefs = string | null | undefined;
2
+ /**
3
+ * Returns a unique set of id refs from the provided string
4
+ * @param ids - string of id refs
5
+ */
6
+ export default function idRefs(ids: IdRefs): Set<string>;
7
+ /**
8
+ * Returns an updated id ref string with the provided id value added
9
+ * @param ids - string of id refs
10
+ * @param id - id to add
11
+ */
12
+ export declare function addIdRef(ids: IdRefs, id: string): string;
13
+ /**
14
+ * Returns an updated id ref string with the provided id value removed
15
+ * @param ids - string of id refs
16
+ * @param id - id to remove
17
+ */
18
+ export declare function removeIdRef(_ids: IdRefs, id: string): string;
19
+ /**
20
+ * Returns if an id ref string contains the provided id value
21
+ * @param ids - string of id refs
22
+ * @param id - id to check if it exists in the provided idRef string
23
+ */
24
+ export declare function hasIdRef(ids: IdRefs, id: string): boolean;
25
+ export {};
@@ -0,0 +1,10 @@
1
+ import type * as React from 'react';
2
+ type Merge<P1 = {}, P2 = {}> = Omit<P1, keyof P2> & P2;
3
+ export type PolymorphicProps<Props = {}, ElementType extends React.ElementType = React.ElementType> = Props & {
4
+ as?: ElementType;
5
+ };
6
+ export type PolymorphicComponentProps<Props = {}, ElementType extends React.ElementType = React.ElementType> = Merge<ElementType extends keyof JSX.IntrinsicElements ? React.PropsWithRef<JSX.IntrinsicElements[ElementType]> : ElementType extends React.ElementType ? React.ComponentPropsWithRef<ElementType> : never, PolymorphicProps<Props, ElementType>>;
7
+ export type PolymorphicComponent<Props = {}, ElementType extends React.ElementType = React.ElementType> = Merge<React.ForwardRefExoticComponent<Props>, {
8
+ <T extends React.ElementType = ElementType>(props: PolymorphicComponentProps<Props, T>): React.ReactElement | null;
9
+ }>;
10
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "6.2.1",
3
+ "version": "6.3.0-canary.39049805",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Fully accessible react components library for Deque Cauldron",
6
6
  "homepage": "https://cauldron.dequelabs.com/",
@@ -1,40 +0,0 @@
1
- /**
2
- * Based on @radix-ui/polymorphic:
3
- * https://github.com/radix-ui/primitives/blob/main/packages/react/polymorphic/src/polymorphic.ts
4
- */
5
- import * as React from 'react';
6
- type Merge<P1 = {}, P2 = {}> = Omit<P1, keyof P2> & P2;
7
- /**
8
- * Infers the OwnProps if E is a ForwardRefExoticComponentWithAs
9
- */
10
- type OwnProps<E> = E extends ForwardRefComponent<any, infer P> ? P : {};
11
- /**
12
- * Infers the JSX.IntrinsicElement if E is a ForwardRefExoticComponentWithAs
13
- */
14
- type IntrinsicElement<E> = E extends ForwardRefComponent<infer I, any> ? I : never;
15
- type ForwardRefExoticComponent<E, OwnProps> = React.ForwardRefExoticComponent<Merge<E extends React.ElementType ? React.ComponentPropsWithRef<E> : never, OwnProps & {
16
- as?: E;
17
- }>>;
18
- interface ForwardRefComponent<IntrinsicElementString, OwnProps = {}
19
- /**
20
- * Extends original type to ensure built in React types play nice
21
- * with polymorphic components still e.g. `React.ElementRef` etc.
22
- */
23
- > extends ForwardRefExoticComponent<IntrinsicElementString, OwnProps> {
24
- /**
25
- * When `as` prop is passed, use this overload.
26
- * Merges original own props (without DOM props) and the inferred props
27
- * from `as` element with the own props taking precendence.
28
- *
29
- * We explicitly avoid `React.ElementType` and manually narrow the prop types
30
- * so that events are typed when using JSX.IntrinsicElements.
31
- */
32
- <As = IntrinsicElementString>(props: As extends '' ? {
33
- as: keyof JSX.IntrinsicElements;
34
- } : As extends React.ComponentType<infer P> ? Merge<P, OwnProps & {
35
- as: As;
36
- }> : As extends keyof JSX.IntrinsicElements ? Merge<JSX.IntrinsicElements[As], OwnProps & {
37
- as: As;
38
- }> : never): React.ReactElement | null;
39
- }
40
- export { ForwardRefComponent, OwnProps, IntrinsicElement, Merge };
@@ -1,2 +0,0 @@
1
- declare function recursivelyRemoveIds(element: React.ReactNode): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>[] | null | undefined;
2
- export default recursivelyRemoveIds;
@@ -1,5 +0,0 @@
1
- /**
2
- * Adds an id to a token list attribute if its not already present in the list
3
- */
4
- declare const tokenList: (id: string, currentVal?: string) => string;
5
- export default tokenList;