@deque/cauldron-react 6.2.1-canary.fca8b9e6 → 6.3.0-canary.2fa4aa02

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;
@@ -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,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;
package/lib/index.d.ts CHANGED
@@ -55,6 +55,7 @@ export { default as Listbox, ListboxOption, ListboxGroup } from './components/Li
55
55
  export { default as Combobox, ComboboxOption, ComboboxGroup } from './components/Combobox';
56
56
  export { default as Popover } from './components/Popover';
57
57
  export { default as Timeline, TimelineItem } from './components/Timeline';
58
+ export { default as TextEllipsis } from './components/TextEllipsis';
58
59
  /**
59
60
  * Helpers / Utils
60
61
  */
package/lib/index.js CHANGED
@@ -1659,6 +1659,7 @@ function Tooltip(_a) {
1659
1659
  var _j = tslib.__read(React.useState(null), 2), targetElement = _j[0], setTargetElement = _j[1];
1660
1660
  var _k = tslib.__read(React.useState(null), 2), tooltipElement = _k[0], setTooltipElement = _k[1];
1661
1661
  var _l = tslib.__read(React.useState(null), 2), arrowElement = _l[0], setArrowElement = _l[1];
1662
+ var hasAriaAssociation = association !== 'none';
1662
1663
  var _m = reactPopper.usePopper(targetElement, tooltipElement, {
1663
1664
  placement: initialPlacement,
1664
1665
  modifiers: [
@@ -1760,14 +1761,16 @@ function Tooltip(_a) {
1760
1761
  }, [tooltipElement, show, hide]);
1761
1762
  // Keep the target's id in sync
1762
1763
  React.useEffect(function () {
1763
- var idRefs = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute(association);
1764
- if (!hasIdRef(idRefs, id)) {
1765
- targetElement === null || targetElement === void 0 ? void 0 : targetElement.setAttribute(association, addIdRef(idRefs, id));
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
+ }
1766
1769
  }
1767
1770
  return function () {
1768
- if (targetElement) {
1769
- var idRefs_1 = targetElement.getAttribute(association);
1770
- targetElement.setAttribute(association, removeIdRef(idRefs_1, id));
1771
+ if (targetElement && hasAriaAssociation) {
1772
+ var idRefs = targetElement.getAttribute(association);
1773
+ targetElement.setAttribute(association, removeIdRef(idRefs, id));
1771
1774
  }
1772
1775
  };
1773
1776
  }, [targetElement, id, association]);
@@ -1794,13 +1797,6 @@ var TooltipContent = function (_a) {
1794
1797
  return (React__default["default"].createElement("div", tslib.__assign({ className: classNames__default["default"]('TooltipContent', className) }, other)));
1795
1798
  };
1796
1799
 
1797
- /**
1798
- * Unfortunately, eslint does not recognize that this Polymorphic component has a displayName set
1799
- *
1800
- * We might be able to remove this if we upgrade eslint and associated plugins
1801
- * See: https://github.com/dequelabs/cauldron/issues/451
1802
- */
1803
- // eslint-disable-next-line react/display-name
1804
1800
  var IconButton = React.forwardRef(function (_a, ref) {
1805
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"]);
1806
1802
  var internalRef = React.useRef();
@@ -3557,7 +3553,9 @@ var ComboboxOption = React.forwardRef(function (_a, ref) {
3557
3553
  }
3558
3554
  return (React__default["default"].createElement(ListboxOption, tslib.__assign({ as: "li", className: classNames__default["default"]('ComboboxOption', className, {
3559
3555
  'ComboboxOption--disabled': disabled
3560
- }), 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),
3561
3559
  React__default["default"].createElement("span", null,
3562
3560
  React__default["default"].createElement(ComboboxMatch, null, children),
3563
3561
  description && (React__default["default"].createElement("div", { className: "ComboboxOption__description" }, description))),
@@ -3959,6 +3957,51 @@ function TimelineItem(_a) {
3959
3957
  React__default["default"].createElement("div", { className: "TimelineItem__details" }, children)));
3960
3958
  }
3961
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
+
3962
4005
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
3963
4006
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
3964
4007
  var ThemeContext = React.createContext({
@@ -4116,6 +4159,7 @@ exports.Tabs = Tabs;
4116
4159
  exports.Tag = Tag;
4117
4160
  exports.TagButton = TagButton;
4118
4161
  exports.TagLabel = TagLabel;
4162
+ exports.TextEllipsis = TextEllipsis;
4119
4163
  exports.TextField = TextField;
4120
4164
  exports.ThemeContext = ThemeContext;
4121
4165
  exports.ThemeProvider = ThemeProvider;
@@ -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-canary.fca8b9e6",
3
+ "version": "6.3.0-canary.2fa4aa02",
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 };