• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SAP / ui5-webcomponents-react / 12201755217

06 Dec 2024 03:44PM CUT coverage: 87.135% (-0.03%) from 87.165%
12201755217

Pull #6696

github

web-flow
Merge 9b52b2138 into 0715e49a7
Pull Request #6696: feat: update to UI5 Web Components 2.5.0

2922 of 3887 branches covered (75.17%)

21 of 21 new or added lines in 2 files covered. (100.0%)

3 existing lines in 2 files now uncovered.

5107 of 5861 relevant lines covered (87.14%)

51362.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.47
/packages/main/src/components/ExpandableText/index.tsx
1
'use client';
2

3
import LinkAccessibleRole from '@ui5/webcomponents/dist/types/LinkAccessibleRole.js';
4
import { useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base';
5
import { clsx } from 'clsx';
6
import { forwardRef, useId, useState } from 'react';
7
import { CLOSE_POPOVER, SHOW_FULL_TEXT, SHOW_LESS, SHOW_MORE } from '../../i18n/i18n-defaults.js';
8
import type { CommonProps } from '../../types/index.js';
9
import { Link } from '../../webComponents/index.js';
10
import { ResponsivePopover } from '../../webComponents/ResponsivePopover/index.js';
11
import type { TextPropTypes } from '../../webComponents/Text/index.js';
12
import { Text } from '../../webComponents/Text/index.js';
13
import { classNames, styleData } from './ExpandableText.module.css.js';
14

15
export interface ExpandableTextPropTypes extends Omit<TextPropTypes, 'maxLines' | 'children'>, CommonProps {
16
  /**
17
   * Determines the text to be displayed.
18
   */
19
  children?: string;
20
  /**
21
   * Specifies the maximum number of characters from the beginning of the text field that are shown initially.
22
   *
23
   * @default 100
24
   */
25
  maxCharacters?: number;
26
  /**
27
   * Determines if the full text should be displayed inside a `ResponsivePopover` or in-place.
28
   */
29
  showOverflowInPopover?: boolean;
30
  /**
31
   * Defines how white-space inside <code>Text</code> is handled. If set to true, sequences of white space are preserved.
32
   */
33
  renderWhitespace?: boolean;
34
}
35

36
/**
37
 * The `ExpandableText` component can be used to display long texts inside a table, list or form.
38
 *
39
 * Initially, only the first characters from the text are shown with a "Show More" link which allows the full text to be displayed. The `showOverflowInPopover` property determines if the full text will be displayed expanded in place (default) or in a popover (`showOverflowInPopover: true`). If the text is expanded a "Show Less" link is displayed, which allows collapsing the text field.
40
 *
41
 * @since 1.23.0
42
 */
43
const ExpandableText = forwardRef<HTMLSpanElement, ExpandableTextPropTypes>((props, ref) => {
426✔
44
  const { children, showOverflowInPopover, maxCharacters = 100, renderWhitespace, className, ...rest } = props;
97✔
45

46
  useStylesheet(styleData, ExpandableText.displayName);
97✔
47

48
  const [collapsed, setCollapsed] = useState(true);
97✔
49
  const [popoverOpen, setPopoverOpen] = useState(false);
97✔
50
  const uniqueId = useId();
97✔
51
  const i18nBundle = useI18nBundle('@ui5/webcomponents-react');
97✔
52
  const trimmedChildren = renderWhitespace ? children : children?.replace(/\s+/g, ' ').trim();
97✔
53
  const isOverflow = trimmedChildren?.length >= maxCharacters;
97✔
54
  const strippedChildren =
55
    isOverflow && (collapsed || showOverflowInPopover) ? trimmedChildren?.slice(0, maxCharacters) : children;
97✔
56

57
  const handleClick = () => {
97✔
58
    if (showOverflowInPopover) {
14✔
59
      setPopoverOpen((prev) => !prev);
6✔
60
    }
61
    setCollapsed((prev) => !prev);
14✔
62
  };
63

64
  const closePopover = () => {
97✔
UNCOV
65
    setCollapsed(true);
×
UNCOV
66
    setPopoverOpen(false);
×
67
  };
68

69
  return (
97✔
70
    <>
71
      <span className={clsx(classNames.expandableText, className)} {...rest} ref={ref}>
72
        <Text className={clsx(classNames.text, renderWhitespace && classNames.renderWhitespace)}>
127✔
73
          {strippedChildren}
74
        </Text>
75
        {isOverflow && (
170✔
76
          <>
77
            <span className={classNames.ellipsis}>{showOverflowInPopover || collapsed ? '… ' : ' '}</span>
207✔
78
            <Link
79
              accessibleName={
80
                showOverflowInPopover
73✔
81
                  ? collapsed
12✔
82
                    ? i18nBundle.getText(SHOW_FULL_TEXT)
83
                    : i18nBundle.getText(CLOSE_POPOVER)
84
                  : undefined
85
              }
86
              accessibleRole={LinkAccessibleRole.Button}
87
              accessibilityAttributes={showOverflowInPopover ? { hasPopup: 'dialog' } : { expanded: !collapsed }}
73✔
88
              onClick={handleClick}
89
              id={`${uniqueId}-link`}
90
            >
91
              {collapsed ? i18nBundle.getText(SHOW_MORE) : i18nBundle.getText(SHOW_LESS)}
73✔
92
            </Link>
93
          </>
94
        )}
95
      </span>
96
      {showOverflowInPopover && popoverOpen && (
112✔
97
        <ResponsivePopover opener={`${uniqueId}-link`} open onClose={closePopover} className={classNames.popover}>
98
          <Text className={clsx(classNames.text, renderWhitespace && classNames.renderWhitespace)}>{children}</Text>
3!
99
        </ResponsivePopover>
100
      )}
101
    </>
102
  );
103
});
104

105
ExpandableText.displayName = 'ExpandableText';
426✔
106

107
export { ExpandableText };
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc