@elliemae/ds-read-more 3.53.0-alpha.1 → 3.53.0-alpha.3
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.
- package/dist/cjs/DSReadMore.js +25 -12
- package/dist/cjs/DSReadMore.js.map +2 -2
- package/dist/cjs/MoreLessButton.js +26 -28
- package/dist/cjs/MoreLessButton.js.map +2 -2
- package/dist/cjs/{DSReadMoreDefinitions.js → constants/index.js} +13 -8
- package/dist/cjs/constants/index.js.map +7 -0
- package/dist/cjs/index.js +6 -4
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/react-desc-prop-types.js +3 -2
- package/dist/cjs/react-desc-prop-types.js.map +2 -2
- package/dist/cjs/styled.js +17 -12
- package/dist/cjs/styled.js.map +2 -2
- package/dist/cjs/useReadMoreTruncate.js +50 -37
- package/dist/cjs/useReadMoreTruncate.js.map +2 -2
- package/dist/cjs/utils.js +40 -0
- package/dist/cjs/utils.js.map +7 -0
- package/dist/esm/DSReadMore.js +23 -10
- package/dist/esm/DSReadMore.js.map +2 -2
- package/dist/esm/MoreLessButton.js +26 -28
- package/dist/esm/MoreLessButton.js.map +2 -2
- package/dist/esm/{DSReadMoreDefinitions.js → constants/index.js} +10 -5
- package/dist/esm/constants/index.js.map +7 -0
- package/dist/esm/index.js +9 -1
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/react-desc-prop-types.js +3 -1
- package/dist/esm/react-desc-prop-types.js.map +2 -2
- package/dist/esm/styled.js +15 -10
- package/dist/esm/styled.js.map +2 -2
- package/dist/esm/useReadMoreTruncate.js +50 -37
- package/dist/esm/useReadMoreTruncate.js.map +2 -2
- package/dist/esm/utils.js +10 -0
- package/dist/esm/utils.js.map +7 -0
- package/dist/types/MoreLessButton.d.ts +0 -1
- package/dist/types/constants/index.d.ts +33 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/react-desc-prop-types.d.ts +5 -4
- package/dist/types/styled.d.ts +8 -5
- package/dist/types/tests/DSReadMore.PUI-14965.test.d.ts +1 -0
- package/dist/types/tests/DSReadMore.a11y.test.d.ts +1 -0
- package/dist/types/tests/DSReadMore.data-testid.test.d.ts +1 -0
- package/dist/types/tests/DSReadMore.default-props.test.d.ts +1 -0
- package/dist/types/tests/DSReadMore.events.test.d.ts +1 -0
- package/dist/types/tests/DSReadMore.exports.test.d.ts +1 -0
- package/dist/types/tests/DSReadMore.get-owner-props.test.d.ts +1 -0
- package/dist/types/tests/DSReadMore.keyboard.test.d.ts +1 -0
- package/dist/types/tests/playwright/DSReadMore.ControlledTestRenderer.d.ts +1 -0
- package/dist/types/tests/playwright/DSReadMore.test.playwright.d.ts +1 -0
- package/dist/types/useOnElementResize.d.ts +1 -1
- package/dist/types/useReadMoreTruncate.d.ts +1 -1
- package/dist/types/utils.d.ts +16 -0
- package/package.json +10 -8
- package/dist/cjs/DSReadMoreDefinitions.js.map +0 -7
- package/dist/esm/DSReadMoreDefinitions.js.map +0 -7
- package/dist/types/DSReadMoreDefinitions.d.ts +0 -12
package/dist/cjs/DSReadMore.js
CHANGED
|
@@ -35,14 +35,16 @@ __export(DSReadMore_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(DSReadMore_exports);
|
|
36
36
|
var React = __toESM(require("react"));
|
|
37
37
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
38
|
-
var
|
|
38
|
+
var import_ds_accessibility = require("@elliemae/ds-accessibility");
|
|
39
39
|
var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
|
|
40
40
|
var import_ds_tooltip_v3 = require("@elliemae/ds-tooltip-v3");
|
|
41
|
+
var import_react = require("react");
|
|
41
42
|
var import_MoreLessButton = require("./MoreLessButton.js");
|
|
43
|
+
var import_constants = require("./constants/index.js");
|
|
42
44
|
var import_react_desc_prop_types = require("./react-desc-prop-types.js");
|
|
43
45
|
var import_styled = require("./styled.js");
|
|
44
46
|
var import_useReadMoreTruncate = require("./useReadMoreTruncate.js");
|
|
45
|
-
var
|
|
47
|
+
var import_utils = require("./utils.js");
|
|
46
48
|
const DSReadMore = (props) => {
|
|
47
49
|
const propsWithDefault = (0, import_ds_props_helpers.useMemoMergePropsWithDefault)(props, import_react_desc_prop_types.defaultProps);
|
|
48
50
|
const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;
|
|
@@ -51,13 +53,23 @@ const DSReadMore = (props) => {
|
|
|
51
53
|
const toggleExpanded = (0, import_react.useCallback)(
|
|
52
54
|
(newExpanded) => {
|
|
53
55
|
setExpanded(newExpanded);
|
|
54
|
-
if (newExpanded)
|
|
55
|
-
|
|
56
|
+
if (newExpanded) {
|
|
57
|
+
onMore();
|
|
58
|
+
} else {
|
|
59
|
+
onLess();
|
|
60
|
+
}
|
|
56
61
|
},
|
|
57
62
|
[onMore, onLess, setExpanded]
|
|
58
63
|
);
|
|
59
64
|
const getOwnerProps = (0, import_react.useCallback)(() => propsWithDefault, [propsWithDefault]);
|
|
60
|
-
const getOwnerPropsArguments = (0, import_react.useCallback)(() => ({}), []);
|
|
65
|
+
const getOwnerPropsArguments = (0, import_react.useCallback)(() => ({ expanded }), [expanded]);
|
|
66
|
+
const getReadMoreDescribedByText = (0, import_react.useCallback)(() => {
|
|
67
|
+
if (withTooltip) {
|
|
68
|
+
return "shows the full text for sighted users but the full text is already there for screen readers";
|
|
69
|
+
}
|
|
70
|
+
return `${expanded ? "collapse" : "expand"} the full text for sighted users but the full text is already there for screen readers`;
|
|
71
|
+
}, [expanded, withTooltip]);
|
|
72
|
+
const isSafariBrowser = (0, import_react.useMemo)(() => (0, import_utils.isSafari)(), []);
|
|
61
73
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
62
74
|
import_styled.StyledTextWrapper,
|
|
63
75
|
{
|
|
@@ -66,19 +78,22 @@ const DSReadMore = (props) => {
|
|
|
66
78
|
expanded,
|
|
67
79
|
getOwnerProps,
|
|
68
80
|
getOwnerPropsArguments,
|
|
81
|
+
isSafari: isSafariBrowser,
|
|
69
82
|
...xstyledProps,
|
|
70
83
|
children: [
|
|
71
84
|
srOnlyText,
|
|
85
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ds_accessibility.ScreenReaderOnly, { id: "ds-read_more-text-disclaimer", "aria-hidden": true, children: getReadMoreDescribedByText() }),
|
|
72
86
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
73
87
|
import_styled.StyledTextContent,
|
|
74
88
|
{
|
|
75
|
-
lines,
|
|
76
|
-
expanded,
|
|
77
89
|
innerRef: textRef,
|
|
78
90
|
"data-testid": "ds-read_more-text",
|
|
79
91
|
...textProps,
|
|
80
92
|
getOwnerProps,
|
|
81
93
|
getOwnerPropsArguments,
|
|
94
|
+
lines,
|
|
95
|
+
expanded,
|
|
96
|
+
isSafari: isSafariBrowser,
|
|
82
97
|
children: content
|
|
83
98
|
}
|
|
84
99
|
),
|
|
@@ -88,9 +103,8 @@ const DSReadMore = (props) => {
|
|
|
88
103
|
expanded,
|
|
89
104
|
label: expanded ? less : more,
|
|
90
105
|
onClick: () => toggleExpanded(!expanded),
|
|
91
|
-
ariaLabel: expanded ? "Read less" : "Read more",
|
|
92
106
|
ellipsis,
|
|
93
|
-
dataTestId:
|
|
107
|
+
dataTestId: import_constants.DSReadMoreDataTestIds.READ_MORE_BUTTON,
|
|
94
108
|
getOwnerProps,
|
|
95
109
|
getOwnerPropsArguments
|
|
96
110
|
}
|
|
@@ -100,10 +114,9 @@ const DSReadMore = (props) => {
|
|
|
100
114
|
{
|
|
101
115
|
expanded,
|
|
102
116
|
label: "...",
|
|
103
|
-
ariaLabel: expanded ? "Read less" : "Read more",
|
|
104
117
|
ellipsis,
|
|
105
118
|
withTooltip,
|
|
106
|
-
dataTestId:
|
|
119
|
+
dataTestId: import_constants.DSReadMoreDataTestIds.READ_MORE_TOOLTIP_BUTTON,
|
|
107
120
|
getOwnerProps,
|
|
108
121
|
getOwnerPropsArguments
|
|
109
122
|
}
|
|
@@ -112,7 +125,7 @@ const DSReadMore = (props) => {
|
|
|
112
125
|
}
|
|
113
126
|
);
|
|
114
127
|
};
|
|
115
|
-
DSReadMore.displayName =
|
|
128
|
+
DSReadMore.displayName = import_constants.DSReadMoreName;
|
|
116
129
|
const DSReadMoreWithSchema = (0, import_ds_props_helpers.describe)(DSReadMore);
|
|
117
130
|
DSReadMoreWithSchema.propTypes = import_react_desc_prop_types.DSReadMorePropTypesSchema;
|
|
118
131
|
var DSReadMore_default = DSReadMore;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/DSReadMore.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["import
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["import { ScreenReaderOnly } from '@elliemae/ds-accessibility';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { useCallback, useMemo } from 'react';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './constants/index.js';\nimport { DSReadMorePropTypesSchema, defaultProps, type DSReadMoreT } from './react-desc-prop-types.js';\nimport { StyledTextContent, StyledTextWrapper, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { isSafari } from './utils.js';\n\nconst DSReadMore = (props: DSReadMoreT.Props) => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSReadMoreT.InternalProps>(props, defaultProps);\n const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;\n\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const { textWrapperRef, textRef, showButton, expanded, setExpanded, textProps, srOnlyText } =\n useReadMoreTruncate(propsWithDefault);\n\n const toggleExpanded = useCallback(\n (newExpanded: boolean) => {\n setExpanded(newExpanded);\n if (newExpanded) {\n onMore();\n } else {\n onLess();\n }\n },\n [onMore, onLess, setExpanded],\n );\n\n const getOwnerProps = useCallback(() => propsWithDefault, [propsWithDefault]);\n const getOwnerPropsArguments = useCallback(() => ({ expanded }), [expanded]);\n const getReadMoreDescribedByText = useCallback(() => {\n if (withTooltip) {\n return 'shows the full text for sighted users but the full text is already there for screen readers';\n }\n return `${expanded ? 'collapse' : 'expand'} the full text for sighted users but the full text is already there for screen readers`;\n }, [expanded, withTooltip]);\n\n const isSafariBrowser = useMemo(() => isSafari(), []);\n\n return (\n <StyledTextWrapper\n innerRef={textWrapperRef}\n lines={lines}\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n isSafari={isSafariBrowser}\n {...xstyledProps}\n >\n {srOnlyText}\n {/**\n * Hidden from screen readers unless referenced by `aria-describedby`\n * Ensures the text is only read when associated with a control\n * Prevents it from being focusable or announced independently\n */}\n <ScreenReaderOnly id=\"ds-read_more-text-disclaimer\" aria-hidden>\n {getReadMoreDescribedByText()}\n </ScreenReaderOnly>\n\n <StyledTextContent\n innerRef={textRef}\n data-testid=\"ds-read_more-text\"\n {...textProps}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n lines={lines}\n expanded={expanded}\n isSafari={isSafariBrowser}\n >\n {content}\n </StyledTextContent>\n\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ellipsis={ellipsis}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n )}\n\n {withTooltip && showButton && (\n <StyledTooltipWrapper getOwnerProps={getOwnerProps} getOwnerPropsArguments={getOwnerPropsArguments}>\n <DSTooltipV3 text={content} wrapWords>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ellipsis={ellipsis}\n withTooltip={withTooltip}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_TOOLTIP_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n </DSTooltipV3>\n </StyledTooltipWrapper>\n )}\n </StyledTextWrapper>\n );\n};\n\nDSReadMore.displayName = DSReadMoreName;\nconst DSReadMoreWithSchema = describe(DSReadMore);\nDSReadMoreWithSchema.propTypes = DSReadMorePropTypesSchema;\n\nexport { DSReadMore, DSReadMoreWithSchema };\nexport default DSReadMore;\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;AD4CnB;AA5CJ,8BAAiC;AACjC,8BAA2E;AAC3E,2BAA4B;AAC5B,mBAAqC;AACrC,4BAA+B;AAC/B,uBAAsD;AACtD,mCAA0E;AAC1E,oBAA2E;AAC3E,iCAAoC;AACpC,mBAAyB;AAEzB,MAAM,aAAa,CAAC,UAA6B;AAC/C,QAAM,uBAAmB,sDAAwD,OAAO,yCAAY;AACpG,QAAM,EAAE,OAAO,MAAM,MAAM,SAAS,aAAa,UAAU,QAAQ,OAAO,IAAI;AAE9E,QAAM,mBAAe,4CAAmB,gBAAgB;AAExD,QAAM,EAAE,gBAAgB,SAAS,YAAY,UAAU,aAAa,WAAW,WAAW,QACxF,gDAAoB,gBAAgB;AAEtC,QAAM,qBAAiB;AAAA,IACrB,CAAC,gBAAyB;AACxB,kBAAY,WAAW;AACvB,UAAI,aAAa;AACf,eAAO;AAAA,MACT,OAAO;AACL,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,QAAQ,WAAW;AAAA,EAC9B;AAEA,QAAM,oBAAgB,0BAAY,MAAM,kBAAkB,CAAC,gBAAgB,CAAC;AAC5E,QAAM,6BAAyB,0BAAY,OAAO,EAAE,SAAS,IAAI,CAAC,QAAQ,CAAC;AAC3E,QAAM,iCAA6B,0BAAY,MAAM;AACnD,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AACA,WAAO,GAAG,WAAW,aAAa,QAAQ;AAAA,EAC5C,GAAG,CAAC,UAAU,WAAW,CAAC;AAE1B,QAAM,sBAAkB,sBAAQ,UAAM,uBAAS,GAAG,CAAC,CAAC;AAEpD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACT,GAAG;AAAA,MAEH;AAAA;AAAA,QAMD,4CAAC,4CAAiB,IAAG,gCAA+B,eAAW,MAC5D,qCAA2B,GAC9B;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU;AAAA,YACV,eAAY;AAAA,YACX,GAAG;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YAET;AAAA;AAAA,QACH;AAAA,QAEC,cAAc,CAAC,eACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAO,WAAW,OAAO;AAAA,YACzB,SAAS,MAAM,eAAe,CAAC,QAAQ;AAAA,YACvC;AAAA,YACA,YAAY,uCAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QAGD,eAAe,cACd,4CAAC,sCAAqB,eAA8B,wBAClD,sDAAC,oCAAY,MAAM,SAAS,WAAS,MACnC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,YAAY,uCAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF,GACF,GACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,WAAW,cAAc;AACzB,MAAM,2BAAuB,kCAAS,UAAU;AAChD,qBAAqB,YAAY;AAGjC,IAAO,qBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -35,33 +35,31 @@ var React = __toESM(require("react"));
|
|
|
35
35
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
36
|
var import_styled = require("./styled.js");
|
|
37
37
|
const MoreLessButton = (props) => {
|
|
38
|
-
const {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
)
|
|
65
|
-
] });
|
|
38
|
+
const { expanded, label, onClick, ellipsis, withTooltip, dataTestId, getOwnerProps, getOwnerPropsArguments } = props;
|
|
39
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
40
|
+
import_styled.StyledButtonWrapper,
|
|
41
|
+
{
|
|
42
|
+
expanded,
|
|
43
|
+
getOwnerProps,
|
|
44
|
+
getOwnerPropsArguments,
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, children: expanded || withTooltip ? " " : ellipsis }),
|
|
47
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
48
|
+
import_styled.StyledButton,
|
|
49
|
+
{
|
|
50
|
+
withTooltip,
|
|
51
|
+
buttonType: "text",
|
|
52
|
+
onClick,
|
|
53
|
+
size: "s",
|
|
54
|
+
"data-testid": dataTestId,
|
|
55
|
+
getOwnerProps,
|
|
56
|
+
getOwnerPropsArguments,
|
|
57
|
+
"aria-describedby": "ds-read_more-text-disclaimer",
|
|
58
|
+
children: label
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
);
|
|
66
64
|
};
|
|
67
65
|
//# sourceMappingURL=MoreLessButton.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/MoreLessButton.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["import React from 'react';\nimport { StyledButton, StyledButtonWrapper } from './styled.js';\n\ninterface MoreLessButtonProps {\n expanded: boolean;\n label: string;\n onClick?: () => void;\n ellipsis: string;\n withTooltip?: boolean;\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["import React from 'react';\nimport { StyledButton, StyledButtonWrapper } from './styled.js';\n\ninterface MoreLessButtonProps {\n expanded: boolean;\n label: string;\n onClick?: () => void;\n ellipsis: string;\n withTooltip?: boolean;\n dataTestId: string;\n getOwnerProps: () => object;\n getOwnerPropsArguments: () => object;\n}\n\nconst MoreLessButton = (props: MoreLessButtonProps) => {\n const { expanded, label, onClick, ellipsis, withTooltip, dataTestId, getOwnerProps, getOwnerPropsArguments } = props;\n\n return (\n <StyledButtonWrapper\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n >\n <span aria-hidden>{expanded || withTooltip ? ' ' : ellipsis}</span>\n\n <StyledButton\n withTooltip={withTooltip}\n buttonType=\"text\"\n onClick={onClick}\n size=\"s\"\n data-testid={dataTestId}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n aria-describedby=\"ds-read_more-text-disclaimer\"\n >\n {label}\n </StyledButton>\n </StyledButtonWrapper>\n );\n};\n\nexport { MoreLessButton };\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADkBnB;AAjBJ,oBAAkD;AAalD,MAAM,iBAAiB,CAAC,UAA+B;AACrD,QAAM,EAAE,UAAU,OAAO,SAAS,UAAU,aAAa,YAAY,eAAe,uBAAuB,IAAI;AAE/G,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MAEA;AAAA,oDAAC,UAAK,eAAW,MAAE,sBAAY,cAAc,MAAM,UAAS;AAAA,QAE5D;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,YAAW;AAAA,YACX;AAAA,YACA,MAAK;AAAA,YACL,eAAa;AAAA,YACb;AAAA,YACA;AAAA,YACA,oBAAiB;AAAA,YAEhB;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EACF;AAEJ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -26,27 +26,32 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var
|
|
30
|
-
__export(
|
|
29
|
+
var constants_exports = {};
|
|
30
|
+
__export(constants_exports, {
|
|
31
31
|
DSReadMoreDataTestIds: () => DSReadMoreDataTestIds,
|
|
32
32
|
DSReadMoreName: () => DSReadMoreName,
|
|
33
|
-
DSReadMoreSlots: () => DSReadMoreSlots
|
|
33
|
+
DSReadMoreSlots: () => DSReadMoreSlots,
|
|
34
|
+
READ_MORE_DATA_TESTID: () => READ_MORE_DATA_TESTID,
|
|
35
|
+
READ_MORE_SLOTS: () => READ_MORE_SLOTS
|
|
34
36
|
});
|
|
35
|
-
module.exports = __toCommonJS(
|
|
37
|
+
module.exports = __toCommonJS(constants_exports);
|
|
36
38
|
var React = __toESM(require("react"));
|
|
37
39
|
var import_lodash_es = require("lodash-es");
|
|
38
40
|
var import_ds_system = require("@elliemae/ds-system");
|
|
39
41
|
const DSReadMoreName = "DSReadmore";
|
|
40
|
-
const
|
|
42
|
+
const READ_MORE_SLOTS = {
|
|
41
43
|
ROOT: "root",
|
|
42
44
|
TEXT_CONTENT: "text-content",
|
|
43
45
|
TOOLTIP_WRAPPER: "tooltip-wrapper",
|
|
44
46
|
BUTTON_WRAPPER: "button-wrapper",
|
|
45
47
|
BUTTON: "button"
|
|
46
48
|
};
|
|
47
|
-
const
|
|
49
|
+
const DSReadMoreSlots = READ_MORE_SLOTS;
|
|
50
|
+
const READ_MORE_DATA_TESTID = {
|
|
48
51
|
...(0, import_lodash_es.omit)((0, import_ds_system.slotObjectToDataTestIds)(DSReadMoreName, DSReadMoreSlots), "BUTTON"),
|
|
49
52
|
READ_MORE_BUTTON: "ds-read_more-button",
|
|
50
|
-
READ_MORE_TOOLTIP_BUTTON: "ds-read_more-tooltip-button"
|
|
53
|
+
READ_MORE_TOOLTIP_BUTTON: "ds-read_more-tooltip-button",
|
|
54
|
+
READ_MORE_TEXT: "ds-read_more-text"
|
|
51
55
|
};
|
|
52
|
-
|
|
56
|
+
const DSReadMoreDataTestIds = READ_MORE_DATA_TESTID;
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/constants/index.tsx", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import { omit } from 'lodash-es';\nimport { slotObjectToDataTestIds } from '@elliemae/ds-system';\n\nexport const DSReadMoreName = 'DSReadmore';\n// we are naming this with the ${component_name}_slots convention to namespace & avoid errors on duplicate exports variables in aggregators\nexport const READ_MORE_SLOTS = {\n ROOT: 'root',\n TEXT_CONTENT: 'text-content',\n TOOLTIP_WRAPPER: 'tooltip-wrapper',\n BUTTON_WRAPPER: 'button-wrapper',\n BUTTON: 'button',\n} as const;\n\n// keeping legacy code to avoid breaking changes, the code above this is the new convention\nexport const DSReadMoreSlots = READ_MORE_SLOTS;\n\n// we are naming this with the ${component_name}_data_testid convention to namespace & avoid errors on duplicate exports variables in aggregators\nexport const READ_MORE_DATA_TESTID = {\n ...omit(slotObjectToDataTestIds(DSReadMoreName, DSReadMoreSlots), 'BUTTON'),\n READ_MORE_BUTTON: 'ds-read_more-button',\n READ_MORE_TOOLTIP_BUTTON: 'ds-read_more-tooltip-button',\n READ_MORE_TEXT: 'ds-read_more-text',\n};\n\n// keeping legacy code to avoid breaking changes\nexport const DSReadMoreDataTestIds = READ_MORE_DATA_TESTID;\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,uBAAqB;AACrB,uBAAwC;AAEjC,MAAM,iBAAiB;AAEvB,MAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,QAAQ;AACV;AAGO,MAAM,kBAAkB;AAGxB,MAAM,wBAAwB;AAAA,EACnC,OAAG,2BAAK,0CAAwB,gBAAgB,eAAe,GAAG,QAAQ;AAAA,EAC1E,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,gBAAgB;AAClB;AAGO,MAAM,wBAAwB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -29,15 +29,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var index_exports = {};
|
|
30
30
|
__export(index_exports, {
|
|
31
31
|
DSReadMore: () => import_DSReadMore.DSReadMore,
|
|
32
|
-
DSReadMoreDataTestIds: () =>
|
|
33
|
-
DSReadMoreName: () =>
|
|
34
|
-
DSReadMoreSlots: () =>
|
|
32
|
+
DSReadMoreDataTestIds: () => import_constants.DSReadMoreDataTestIds,
|
|
33
|
+
DSReadMoreName: () => import_constants.DSReadMoreName,
|
|
34
|
+
DSReadMoreSlots: () => import_constants.DSReadMoreSlots,
|
|
35
35
|
DSReadMoreWithSchema: () => import_DSReadMore.DSReadMoreWithSchema,
|
|
36
|
+
READ_MORE_DATA_TESTID: () => import_constants.READ_MORE_DATA_TESTID,
|
|
37
|
+
READ_MORE_SLOTS: () => import_constants.READ_MORE_SLOTS,
|
|
36
38
|
useReadMoreTruncate: () => import_useReadMoreTruncate.useReadMoreTruncate
|
|
37
39
|
});
|
|
38
40
|
module.exports = __toCommonJS(index_exports);
|
|
39
41
|
var React = __toESM(require("react"));
|
|
40
42
|
var import_DSReadMore = require("./DSReadMore.js");
|
|
41
|
-
var
|
|
43
|
+
var import_constants = require("./constants/index.js");
|
|
42
44
|
var import_useReadMoreTruncate = require("./useReadMoreTruncate.js");
|
|
43
45
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["export { DSReadMore, DSReadMoreWithSchema } from './DSReadMore.js';\nexport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,wBAAiD;AACjD,
|
|
4
|
+
"sourcesContent": ["export { DSReadMore, DSReadMoreWithSchema } from './DSReadMore.js';\nexport {\n DSReadMoreName,\n DSReadMoreSlots,\n READ_MORE_SLOTS,\n DSReadMoreDataTestIds,\n READ_MORE_DATA_TESTID,\n} from './constants/index.js';\nexport type { DSReadMoreT } from './react-desc-prop-types.js';\nexport { useReadMoreTruncate } from './useReadMoreTruncate.js';\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,wBAAiD;AACjD,uBAMO;AAEP,iCAAoC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -35,7 +35,7 @@ __export(react_desc_prop_types_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(react_desc_prop_types_exports);
|
|
36
36
|
var React = __toESM(require("react"));
|
|
37
37
|
var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
|
|
38
|
-
var
|
|
38
|
+
var import_constants = require("./constants/index.js");
|
|
39
39
|
const defaultProps = {
|
|
40
40
|
lines: 2,
|
|
41
41
|
more: "more",
|
|
@@ -48,6 +48,7 @@ const defaultProps = {
|
|
|
48
48
|
withTooltip: false
|
|
49
49
|
};
|
|
50
50
|
const DSReadMorePropTypes = {
|
|
51
|
+
...(0, import_ds_props_helpers.getPropsPerSlotPropTypes)(import_constants.DSReadMoreName, import_constants.READ_MORE_SLOTS),
|
|
51
52
|
...import_ds_props_helpers.globalAttributesPropTypes,
|
|
52
53
|
...import_ds_props_helpers.xstyledPropTypes,
|
|
53
54
|
/** Ammount of lines after you want to display an ellipsis + more/less button */
|
|
@@ -65,7 +66,7 @@ const DSReadMorePropTypes = {
|
|
|
65
66
|
/** The text you want to appear when truncating */
|
|
66
67
|
ellipsis: import_ds_props_helpers.PropTypes.string.description("The text you want to appear when truncating").defaultValue("..."),
|
|
67
68
|
withTooltip: import_ds_props_helpers.PropTypes.bool.description("Whether to show expandable tooltip on ellipsis focus instead of expandable buttons").defaultValue("false"),
|
|
68
|
-
...(0, import_ds_props_helpers.getPropsPerDatatestIdPropTypes)(
|
|
69
|
+
...(0, import_ds_props_helpers.getPropsPerDatatestIdPropTypes)(import_constants.DSReadMoreDataTestIds)
|
|
69
70
|
};
|
|
70
71
|
const DSReadMorePropTypesSchema = DSReadMorePropTypes;
|
|
71
72
|
//# sourceMappingURL=react-desc-prop-types.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/react-desc-prop-types.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-empty-interface */\nimport {\n getPropsPerDatatestIdPropTypes,\n globalAttributesPropTypes,\n PropTypes,\n xstyledPropTypes,\n} from '@elliemae/ds-props-helpers';\nimport type {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable max-lines */\n/* eslint-disable @typescript-eslint/no-empty-interface */\nimport {\n getPropsPerDatatestIdPropTypes,\n getPropsPerSlotPropTypes,\n globalAttributesPropTypes,\n PropTypes,\n xstyledPropTypes,\n} from '@elliemae/ds-props-helpers';\n\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';\nimport { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport { DSReadMoreDataTestIds, DSReadMoreName, READ_MORE_SLOTS } from './constants/index.js';\n\nexport namespace DSReadMoreT {\n type PropsT<D, R, O, E> = Partial<D> & R & O & Omit<GlobalAttributesT<E>, keyof D | keyof R | keyof O> & XstyledProps;\n type InternalPropsT<D, R, O, E> = D & R & O & Omit<GlobalAttributesT<E>, keyof D | keyof R | keyof O> & XstyledProps;\n\n export interface DefaultProps {\n lines: number;\n more: string;\n less: string;\n onMore: () => void;\n onLess: () => void;\n ellipsis: string;\n withTooltip: boolean;\n }\n\n export interface OptionalProps\n extends TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSReadMoreName, typeof READ_MORE_SLOTS> {}\n\n export interface RequiredProps {\n content: string;\n }\n\n export type Props = PropsT<DefaultProps, RequiredProps, OptionalProps, HTMLSpanElement>;\n\n export type InternalProps = InternalPropsT<DefaultProps, RequiredProps, OptionalProps, HTMLSpanElement>;\n}\n\nexport const defaultProps: DSReadMoreT.DefaultProps = {\n lines: 2,\n more: 'more',\n less: 'less',\n onMore: () => {},\n onLess: () => {},\n ellipsis: '...',\n withTooltip: false,\n};\n\nexport const DSReadMorePropTypes: DSPropTypesSchema<DSReadMoreT.Props> = {\n ...getPropsPerSlotPropTypes(DSReadMoreName, READ_MORE_SLOTS),\n ...globalAttributesPropTypes,\n ...xstyledPropTypes,\n /** Ammount of lines after you want to display an ellipsis + more/less button */\n lines: PropTypes.number\n .description('Ammount of lines after you want to display an ellipsis + more/less button')\n .defaultValue(2),\n /** Label which will appear on the 'More' button */\n more: PropTypes.string.description(\"Label which will appear on the 'More' button\").defaultValue('more'),\n /** Label which will appear on the 'Less' button */\n less: PropTypes.string.description(\"Label which will appear on the 'Less' button\").defaultValue('less'),\n /** Function which will execute when the user click the 'More' button */\n onMore: PropTypes.func.description(\"Function which will execute when the user click the 'More' button\"),\n /** Function which will execute when the user click the 'Less' button */\n onLess: PropTypes.func.description(\"Function which will execute when the user click the 'Less' button\"),\n /** The text content you want displayed */\n content: PropTypes.string.description('The text content you want displayed').isRequired,\n\n /** The text you want to appear when truncating */\n ellipsis: PropTypes.string.description('The text you want to appear when truncating').defaultValue('...'),\n withTooltip: PropTypes.bool\n .description('Whether to show expandable tooltip on ellipsis focus instead of expandable buttons')\n .defaultValue('false'),\n ...getPropsPerDatatestIdPropTypes(DSReadMoreDataTestIds),\n};\n\nexport const DSReadMorePropTypesSchema = DSReadMorePropTypes as unknown as ValidationMap<DSReadMoreT.Props>;\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAMO;AAIP,uBAAuE;AA4BhE,MAAM,eAAyC;AAAA,EACpD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ,MAAM;AAAA,EAAC;AAAA,EACf,QAAQ,MAAM;AAAA,EAAC;AAAA,EACf,UAAU;AAAA,EACV,aAAa;AACf;AAEO,MAAM,sBAA4D;AAAA,EACvE,OAAG,kDAAyB,iCAAgB,gCAAe;AAAA,EAC3D,GAAG;AAAA,EACH,GAAG;AAAA;AAAA,EAEH,OAAO,kCAAU,OACd,YAAY,2EAA2E,EACvF,aAAa,CAAC;AAAA;AAAA,EAEjB,MAAM,kCAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA;AAAA,EAEtG,MAAM,kCAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA;AAAA,EAEtG,QAAQ,kCAAU,KAAK,YAAY,mEAAmE;AAAA;AAAA,EAEtG,QAAQ,kCAAU,KAAK,YAAY,mEAAmE;AAAA;AAAA,EAEtG,SAAS,kCAAU,OAAO,YAAY,qCAAqC,EAAE;AAAA;AAAA,EAG7E,UAAU,kCAAU,OAAO,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAAA,EACxG,aAAa,kCAAU,KACpB,YAAY,oFAAoF,EAChG,aAAa,OAAO;AAAA,EACvB,OAAG,wDAA+B,sCAAqB;AACzD;AAEO,MAAM,4BAA4B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cjs/styled.js
CHANGED
|
@@ -39,8 +39,8 @@ module.exports = __toCommonJS(styled_exports);
|
|
|
39
39
|
var React = __toESM(require("react"));
|
|
40
40
|
var import_ds_system = require("@elliemae/ds-system");
|
|
41
41
|
var import_ds_button_v2 = require("@elliemae/ds-button-v2");
|
|
42
|
-
var
|
|
43
|
-
const StyledTextWrapper = (0, import_ds_system.styled)("span", { name:
|
|
42
|
+
var import_constants = require("./constants/index.js");
|
|
43
|
+
const StyledTextWrapper = (0, import_ds_system.styled)("span", { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.ROOT })`
|
|
44
44
|
position: relative;
|
|
45
45
|
/**
|
|
46
46
|
* PUI-16110 - [ReadMore] Autotriggered-Visually broken in safari + Sequoia
|
|
@@ -51,10 +51,9 @@ const StyledTextWrapper = (0, import_ds_system.styled)("span", { name: import_DS
|
|
|
51
51
|
* - Avoids -webkit-line-clamp: 1 which breaks layout and can cause infinite ResizeObserver loops.
|
|
52
52
|
* - Instead, uses flex + white-space + overflow hidden for single-line truncation.
|
|
53
53
|
*/
|
|
54
|
-
${({ lines, expanded }) => lines === 1 && !expanded ? `
|
|
54
|
+
${({ lines, isSafari, expanded }) => lines === 1 && isSafari && !expanded ? `
|
|
55
55
|
display: flex;
|
|
56
56
|
align-items: baseline;
|
|
57
|
-
overflow: hidden;
|
|
58
57
|
white-space: nowrap;
|
|
59
58
|
` : `
|
|
60
59
|
display: -webkit-box;
|
|
@@ -66,23 +65,29 @@ const StyledTextWrapper = (0, import_ds_system.styled)("span", { name: import_DS
|
|
|
66
65
|
-moz-hyphens: auto;
|
|
67
66
|
-ms-hyphens: auto;
|
|
68
67
|
hyphens: auto;
|
|
69
|
-
|
|
68
|
+
overflow-wrap: break-word;
|
|
69
|
+
white-space: pre-wrap;
|
|
70
70
|
${import_ds_system.xStyledCommonProps}
|
|
71
71
|
`;
|
|
72
|
-
const StyledTextContent = (0, import_ds_system.styled)("span", { name:
|
|
73
|
-
${({ lines, expanded }) => lines === 1 && !expanded ? `
|
|
72
|
+
const StyledTextContent = (0, import_ds_system.styled)("span", { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.TEXT_CONTENT })`
|
|
73
|
+
${({ lines, expanded, isSafari }) => lines === 1 && isSafari && !expanded ? `
|
|
74
74
|
flex: 1 1 auto;
|
|
75
|
-
overflow:
|
|
75
|
+
overflow-x: clip;
|
|
76
76
|
white-space: nowrap;
|
|
77
77
|
text-overflow: clip;
|
|
78
78
|
` : ""}
|
|
79
79
|
`;
|
|
80
|
-
const StyledTooltipWrapper = (0, import_ds_system.styled)("div", { name:
|
|
80
|
+
const StyledTooltipWrapper = (0, import_ds_system.styled)("div", { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.TOOLTIP_WRAPPER })`
|
|
81
81
|
display: inline-block;
|
|
82
82
|
`;
|
|
83
|
-
const StyledButtonWrapper = (0, import_ds_system.styled)("span", { name:
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const StyledButtonWrapper = (0, import_ds_system.styled)("span", { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.BUTTON_WRAPPER })`
|
|
84
|
+
flex: none;
|
|
85
|
+
display: -webkit-inline-box;
|
|
86
|
+
-webkit-line-clamp: 2;
|
|
87
|
+
-webkit-box-orient: vertical;
|
|
88
|
+
`;
|
|
89
|
+
const StyledButton = (0, import_ds_system.styled)(import_ds_button_v2.DSButtonV3, { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.BUTTON })`
|
|
90
|
+
padding: ${({ theme }) => `0 ${theme.space.xxxs}`};
|
|
86
91
|
color: ${({ withTooltip, theme }) => withTooltip ? "inherit" : `${theme.colors.brand["600"]}`};
|
|
87
92
|
border: 0;
|
|
88
93
|
margin: 0;
|
package/dist/cjs/styled.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/styled.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["import { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,uBAA2C;AAC3C,0BAA2B;AAC3B,
|
|
4
|
+
"sourcesContent": ["import { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSButtonV3 } from '@elliemae/ds-button-v2';\nimport { DSReadMoreName, DSReadMoreSlots } from './constants/index.js';\n\nexport const StyledTextWrapper = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.ROOT })<{\n lines: number;\n expanded: boolean;\n isSafari: boolean;\n}>`\n position: relative;\n /**\n * PUI-16110 - [ReadMore] Autotriggered-Visually broken in safari + Sequoia\n * -----------------------------------\n * In Safari 17.4+ (macOS Sequoia), using scrollHeight or offsetHeight with line-clamp\n * can break the layout and, potentially, trigger infinite loops through ResizeObserver.\n *\n * - Avoids -webkit-line-clamp: 1 which breaks layout and can cause infinite ResizeObserver loops.\n * - Instead, uses flex + white-space + overflow hidden for single-line truncation.\n */\n ${({ lines, isSafari, expanded }) =>\n lines === 1 && isSafari && !expanded\n ? `\n display: flex;\n align-items: baseline;\n white-space: nowrap;\n `\n : `\n display: -webkit-box;\n -webkit-line-clamp: ${expanded ? 'unset' : lines};\n -webkit-box-orient: vertical;\n `}\n\n -webkit-hyphens: auto;\n -moz-hyphens: auto;\n -ms-hyphens: auto;\n hyphens: auto;\n overflow-wrap: break-word;\n white-space: pre-wrap;\n ${xStyledCommonProps}\n`;\n\nexport const StyledTextContent = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.TEXT_CONTENT })<{\n lines: number;\n expanded: boolean;\n isSafari: boolean;\n}>`\n ${({ lines, expanded, isSafari }) =>\n lines === 1 && isSafari && !expanded\n ? `\n flex: 1 1 auto;\n overflow-x: clip;\n white-space: nowrap;\n text-overflow: clip;\n `\n : ''}\n`;\n\nexport const StyledTooltipWrapper = styled('div', { name: DSReadMoreName, slot: DSReadMoreSlots.TOOLTIP_WRAPPER })`\n display: inline-block;\n`;\n\nexport const StyledButtonWrapper = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.BUTTON_WRAPPER })<{\n expanded: boolean;\n}>`\n flex: none;\n display: -webkit-inline-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n`;\n\nexport const StyledButton = styled(DSButtonV3, { name: DSReadMoreName, slot: DSReadMoreSlots.BUTTON })<{\n withTooltip?: boolean;\n}>`\n padding: ${({ theme }) => `0 ${theme.space.xxxs}`};\n color: ${({ withTooltip, theme }) => (withTooltip ? 'inherit' : `${theme.colors.brand['600']}`)};\n border: 0;\n margin: 0;\n font-size: 12px;\n min-width: 0px;\n height: auto;\n text-transform: unset;\n &:hover:not([disabled]) {\n color: ${({ withTooltip, theme }) => (withTooltip ? 'inherit' : `${theme.colors.brand['600']}`)};\n background-color: transparent;\n text-decoration: ${({ withTooltip }) => (withTooltip ? '' : 'underline')};\n }\n`;\n\nexport const ScreenReaderOnly = styled.span`\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n height: 100%;\n overflow: hidden;\n position: absolute;\n width: 100%;\n`;\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,uBAA2C;AAC3C,0BAA2B;AAC3B,uBAAgD;AAEzC,MAAM,wBAAoB,yBAAO,QAAQ,EAAE,MAAM,iCAAgB,MAAM,iCAAgB,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAehG,CAAC,EAAE,OAAO,UAAU,SAAS,MAC7B,UAAU,KAAK,YAAY,CAAC,WACxB;AAAA;AAAA;AAAA;AAAA,MAKA;AAAA;AAAA,0BAEkB,WAAW,UAAU,KAAK;AAAA;AAAA,GAEjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQC,mCAAkB;AAAA;AAGf,MAAM,wBAAoB,yBAAO,QAAQ,EAAE,MAAM,iCAAgB,MAAM,iCAAgB,aAAa,CAAC;AAAA,IAKxG,CAAC,EAAE,OAAO,UAAU,SAAS,MAC7B,UAAU,KAAK,YAAY,CAAC,WACxB;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,EAAE;AAAA;AAGH,MAAM,2BAAuB,yBAAO,OAAO,EAAE,MAAM,iCAAgB,MAAM,iCAAgB,gBAAgB,CAAC;AAAA;AAAA;AAI1G,MAAM,0BAAsB,yBAAO,QAAQ,EAAE,MAAM,iCAAgB,MAAM,iCAAgB,eAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AASzG,MAAM,mBAAe,yBAAO,gCAAY,EAAE,MAAM,iCAAgB,MAAM,iCAAgB,OAAO,CAAC;AAAA,aAGxF,CAAC,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,IAAI,EAAE;AAAA,WACxC,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM,KAAK,CAAC,EAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAQpF,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM,KAAK,CAAC,EAAG;AAAA;AAAA,uBAE5E,CAAC,EAAE,YAAY,MAAO,cAAc,KAAK,WAAY;AAAA;AAAA;AAIrE,MAAM,mBAAmB,wBAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -36,19 +36,21 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
36
36
|
var import_react = require("react");
|
|
37
37
|
var import_useOnElementResize = require("./useOnElementResize.js");
|
|
38
38
|
var import_styled = require("./styled.js");
|
|
39
|
-
|
|
39
|
+
var import_utils = require("./utils.js");
|
|
40
|
+
const overflows = ({ offsetHeight, scrollHeight }) => offsetHeight + 4 < scrollHeight;
|
|
40
41
|
const binSearchTextOverflow = (element, parent, content) => {
|
|
41
|
-
|
|
42
|
-
let
|
|
43
|
-
let right = text.length;
|
|
42
|
+
let left = 0;
|
|
43
|
+
let right = content.length;
|
|
44
44
|
let textEnd = 0;
|
|
45
|
+
element.innerText = content;
|
|
45
46
|
while (left <= right) {
|
|
46
|
-
const
|
|
47
|
-
element.innerText = content.slice(0,
|
|
48
|
-
if (overflows(parent))
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
textEnd =
|
|
47
|
+
const mid = Math.floor((left + right) / 2);
|
|
48
|
+
element.innerText = content.slice(0, mid);
|
|
49
|
+
if (overflows(parent)) {
|
|
50
|
+
right = mid - 1;
|
|
51
|
+
} else {
|
|
52
|
+
textEnd = mid;
|
|
53
|
+
left = mid + 1;
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
element.innerText = content.slice(0, textEnd);
|
|
@@ -60,38 +62,49 @@ const useReadMoreTruncate = ({ lines, content }) => {
|
|
|
60
62
|
const [showButton, setShowButton] = (0, import_react.useState)(false);
|
|
61
63
|
const { width, height } = (0, import_useOnElementResize.useOnElementResize)(textWrapperRef);
|
|
62
64
|
(0, import_react.useLayoutEffect)(() => {
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
setShowButton(expanded || isTruncated);
|
|
79
|
-
return;
|
|
65
|
+
const textEl = textRef.current;
|
|
66
|
+
const wrapperEl = textWrapperRef.current;
|
|
67
|
+
if (!textEl || !wrapperEl) return;
|
|
68
|
+
textEl.innerText = content;
|
|
69
|
+
if (lines === 1 && (0, import_utils.isSafari)()) {
|
|
70
|
+
const computed = getComputedStyle(textEl);
|
|
71
|
+
const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;
|
|
72
|
+
const canvas = document.createElement("canvas");
|
|
73
|
+
const ctx = canvas.getContext("2d");
|
|
74
|
+
let truncated = false;
|
|
75
|
+
if (ctx) {
|
|
76
|
+
ctx.font = font;
|
|
77
|
+
const measuredWidth = ctx.measureText(content).width;
|
|
78
|
+
truncated = measuredWidth > wrapperEl.clientWidth;
|
|
80
79
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
setShowButton(expanded || truncated);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const isOverflowing = overflows({
|
|
84
|
+
offsetHeight: wrapperEl.offsetHeight,
|
|
85
|
+
scrollHeight: wrapperEl.scrollHeight
|
|
86
|
+
});
|
|
87
|
+
setShowButton(expanded || isOverflowing);
|
|
88
|
+
if (!expanded && isOverflowing) {
|
|
89
|
+
const doBinaryTruncate = () => {
|
|
90
|
+
if (!textEl || !wrapperEl) return;
|
|
91
|
+
requestAnimationFrame(() => {
|
|
92
|
+
binSearchTextOverflow(textEl, wrapperEl, content);
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
if ("fonts" in document && document.fonts.ready) {
|
|
96
|
+
document.fonts.ready.then(() => {
|
|
97
|
+
doBinaryTruncate();
|
|
98
|
+
}).catch(() => {
|
|
99
|
+
setTimeout(doBinaryTruncate, 0);
|
|
100
|
+
});
|
|
101
|
+
} else {
|
|
102
|
+
setTimeout(doBinaryTruncate, 0);
|
|
85
103
|
}
|
|
86
104
|
}
|
|
87
105
|
}, [lines, content, expanded, width, height]);
|
|
88
106
|
const srOnlyText = (0, import_react.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_styled.ScreenReaderOnly, { children: content }), [content]);
|
|
89
|
-
const textProps = (0, import_react.useMemo)(
|
|
90
|
-
() => ({
|
|
91
|
-
"aria-hidden": true
|
|
92
|
-
}),
|
|
93
|
-
[]
|
|
94
|
-
);
|
|
107
|
+
const textProps = (0, import_react.useMemo)(() => ({ "aria-hidden": true }), []);
|
|
95
108
|
return {
|
|
96
109
|
textWrapperRef,
|
|
97
110
|
textRef,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/useReadMoreTruncate.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-misused-promises */\n/* eslint-disable max-statements */\n/* eslint-disable complexity */\n// useReadMoreTruncate.tsx\nimport React, { useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useOnElementResize } from './useOnElementResize.js';\nimport type { DSReadMoreT } from './react-desc-prop-types.js';\nimport { ScreenReaderOnly } from './styled.js';\nimport { isSafari } from './utils.js';\n\n// offsetHeight + margin/buffer to avoid subpixel errors\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 4 < scrollHeight;\n\n/**\n * binSearchTextOverflow slices the content until there's no overflow.\n * It assumes `element` is the <span> node containing the text, and `parent`\n * is the wrapper with the height/clamp applied.\n */\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n let left = 0;\n let right = content.length;\n let textEnd = 0;\n\n // Place the full text before starting\n element.innerText = content;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n element.innerText = content.slice(0, mid);\n\n if (overflows(parent)) {\n // Still overflowing \u2192 reduce\n right = mid - 1;\n } else {\n // No overflow \u2192 we can increase\n textEnd = mid;\n left = mid + 1;\n }\n }\n\n element.innerText = content.slice(0, textEnd);\n};\n\nexport const useReadMoreTruncate = ({ lines, content }: Pick<DSReadMoreT.InternalProps, 'lines' | 'content'>) => {\n const textWrapperRef = useRef<HTMLSpanElement>(null);\n const textRef = useRef<HTMLSpanElement>(null);\n\n const [expanded, setExpanded] = useState(false);\n const [showButton, setShowButton] = useState(false);\n\n // Detect container size changes\n const { width, height } = useOnElementResize(textWrapperRef);\n\n useLayoutEffect(() => {\n const textEl = textRef.current;\n const wrapperEl = textWrapperRef.current;\n if (!textEl || !wrapperEl) return;\n\n // 1) Always reset the text to \"content\"\n textEl.innerText = content;\n\n // 2) Case lines === 1: measure with canvas\n if (lines === 1 && isSafari()) {\n const computed = getComputedStyle(textEl);\n const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;\n\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n let truncated = false;\n\n if (ctx) {\n ctx.font = font;\n const measuredWidth = ctx.measureText(content).width;\n truncated = measuredWidth > wrapperEl.clientWidth;\n }\n\n setShowButton(expanded || truncated);\n // No need to truncate char by char in single-line: hiding with CSS is enough.\n return;\n }\n\n // 3) For multiline: first check native overflow\n const isOverflowing = overflows({\n offsetHeight: wrapperEl.offsetHeight,\n scrollHeight: wrapperEl.scrollHeight,\n });\n setShowButton(expanded || isOverflowing);\n\n // 4) If not expanded and there is overflow, adjust the slice with binary search\n if (!expanded && isOverflowing) {\n // Function that executes binSearchTextOverflow\n const doBinaryTruncate = () => {\n if (!textEl || !wrapperEl) return;\n requestAnimationFrame(() => {\n binSearchTextOverflow(textEl, wrapperEl, content);\n });\n };\n\n // If the browser supports document.fonts, wait for them to load.\n if ('fonts' in document && document.fonts.ready) {\n document.fonts.ready\n .then(() => {\n doBinaryTruncate();\n })\n .catch(() => {\n // If fonts.ready fails, fall back to timeout\n setTimeout(doBinaryTruncate, 0);\n });\n } else {\n // Fallback for browsers without the Font Loading API\n setTimeout(doBinaryTruncate, 0);\n }\n }\n }, [lines, content, expanded, width, height]);\n\n // Hidden text for screen readers (always the full string)\n const srOnlyText = useMemo(() => <ScreenReaderOnly>{content}</ScreenReaderOnly>, [content]);\n\n // Mark the visible content as aria-hidden\n const textProps = useMemo(() => ({ 'aria-hidden': true }), []);\n\n return {\n textWrapperRef,\n textRef,\n showButton,\n expanded,\n setExpanded,\n textProps,\n srOnlyText,\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADqHY;AAjHnC,mBAAkE;AAClE,gCAAmC;AAEnC,oBAAiC;AACjC,mBAAyB;AAGzB,MAAM,YAAY,CAAC,EAAE,cAAc,aAAa,MAC9C,eAAe,IAAI;AAOrB,MAAM,wBAAwB,CAAC,SAAsB,QAAqB,YAAoB;AAC5F,MAAI,OAAO;AACX,MAAI,QAAQ,QAAQ;AACpB,MAAI,UAAU;AAGd,UAAQ,YAAY;AAEpB,SAAO,QAAQ,OAAO;AACpB,UAAM,MAAM,KAAK,OAAO,OAAO,SAAS,CAAC;AACzC,YAAQ,YAAY,QAAQ,MAAM,GAAG,GAAG;AAExC,QAAI,UAAU,MAAM,GAAG;AAErB,cAAQ,MAAM;AAAA,IAChB,OAAO;AAEL,gBAAU;AACV,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,UAAQ,YAAY,QAAQ,MAAM,GAAG,OAAO;AAC9C;AAEO,MAAM,sBAAsB,CAAC,EAAE,OAAO,QAAQ,MAA4D;AAC/G,QAAM,qBAAiB,qBAAwB,IAAI;AACnD,QAAM,cAAU,qBAAwB,IAAI;AAE5C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAGlD,QAAM,EAAE,OAAO,OAAO,QAAI,8CAAmB,cAAc;AAE3D,oCAAgB,MAAM;AACpB,UAAM,SAAS,QAAQ;AACvB,UAAM,YAAY,eAAe;AACjC,QAAI,CAAC,UAAU,CAAC,UAAW;AAG3B,WAAO,YAAY;AAGnB,QAAI,UAAU,SAAK,uBAAS,GAAG;AAC7B,YAAM,WAAW,iBAAiB,MAAM;AACxC,YAAM,OAAO,GAAG,SAAS,UAAU,IAAI,SAAS,QAAQ,IAAI,SAAS,UAAU;AAE/E,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,YAAM,MAAM,OAAO,WAAW,IAAI;AAClC,UAAI,YAAY;AAEhB,UAAI,KAAK;AACP,YAAI,OAAO;AACX,cAAM,gBAAgB,IAAI,YAAY,OAAO,EAAE;AAC/C,oBAAY,gBAAgB,UAAU;AAAA,MACxC;AAEA,oBAAc,YAAY,SAAS;AAEnC;AAAA,IACF;AAGA,UAAM,gBAAgB,UAAU;AAAA,MAC9B,cAAc,UAAU;AAAA,MACxB,cAAc,UAAU;AAAA,IAC1B,CAAC;AACD,kBAAc,YAAY,aAAa;AAGvC,QAAI,CAAC,YAAY,eAAe;AAE9B,YAAM,mBAAmB,MAAM;AAC7B,YAAI,CAAC,UAAU,CAAC,UAAW;AAC3B,8BAAsB,MAAM;AAC1B,gCAAsB,QAAQ,WAAW,OAAO;AAAA,QAClD,CAAC;AAAA,MACH;AAGA,UAAI,WAAW,YAAY,SAAS,MAAM,OAAO;AAC/C,iBAAS,MAAM,MACZ,KAAK,MAAM;AACV,2BAAiB;AAAA,QACnB,CAAC,EACA,MAAM,MAAM;AAEX,qBAAW,kBAAkB,CAAC;AAAA,QAChC,CAAC;AAAA,MACL,OAAO;AAEL,mBAAW,kBAAkB,CAAC;AAAA,MAChC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,UAAU,OAAO,MAAM,CAAC;AAG5C,QAAM,iBAAa,sBAAQ,MAAM,4CAAC,kCAAkB,mBAAQ,GAAqB,CAAC,OAAO,CAAC;AAG1F,QAAM,gBAAY,sBAAQ,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC,CAAC;AAE7D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|