@elliemae/ds-read-more 3.53.0-beta.8 → 3.53.0-next.10

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.
Files changed (42) hide show
  1. package/dist/cjs/DSReadMore.js +9 -6
  2. package/dist/cjs/DSReadMore.js.map +2 -2
  3. package/dist/cjs/{DSReadMoreDefinitions.js → constants/index.js} +13 -8
  4. package/dist/cjs/constants/index.js.map +7 -0
  5. package/dist/cjs/index.js +6 -4
  6. package/dist/cjs/index.js.map +2 -2
  7. package/dist/cjs/react-desc-prop-types.js +3 -2
  8. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  9. package/dist/cjs/styled.js +6 -6
  10. package/dist/cjs/styled.js.map +2 -2
  11. package/dist/cjs/useReadMoreTruncate.js +41 -34
  12. package/dist/cjs/useReadMoreTruncate.js.map +2 -2
  13. package/dist/esm/DSReadMore.js +6 -3
  14. package/dist/esm/DSReadMore.js.map +2 -2
  15. package/dist/esm/{DSReadMoreDefinitions.js → constants/index.js} +10 -5
  16. package/dist/esm/constants/index.js.map +7 -0
  17. package/dist/esm/index.js +9 -1
  18. package/dist/esm/index.js.map +2 -2
  19. package/dist/esm/react-desc-prop-types.js +3 -1
  20. package/dist/esm/react-desc-prop-types.js.map +2 -2
  21. package/dist/esm/styled.js +1 -1
  22. package/dist/esm/styled.js.map +1 -1
  23. package/dist/esm/useReadMoreTruncate.js +41 -34
  24. package/dist/esm/useReadMoreTruncate.js.map +2 -2
  25. package/dist/types/constants/index.d.ts +25 -0
  26. package/dist/types/index.d.ts +1 -1
  27. package/dist/types/react-desc-prop-types.d.ts +6 -4
  28. package/dist/types/styled.d.ts +2 -1
  29. package/dist/types/tests/DSReadMore.a11y.test.d.ts +1 -0
  30. package/dist/types/tests/DSReadMore.data-testid.test.d.ts +1 -0
  31. package/dist/types/tests/DSReadMore.default-props.test.d.ts +1 -0
  32. package/dist/types/tests/DSReadMore.events.test.d.ts +1 -0
  33. package/dist/types/tests/DSReadMore.exports.test.d.ts +1 -0
  34. package/dist/types/tests/DSReadMore.keyboard.test.d.ts +1 -0
  35. package/dist/types/tests/playwright/DSReadMore.ControlledTestRenderer.d.ts +1 -0
  36. package/dist/types/tests/playwright/DSReadMore.test.playwright.d.ts +1 -0
  37. package/dist/types/useOnElementResize.d.ts +1 -1
  38. package/dist/types/useReadMoreTruncate.d.ts +1 -1
  39. package/package.json +8 -8
  40. package/dist/cjs/DSReadMoreDefinitions.js.map +0 -7
  41. package/dist/esm/DSReadMoreDefinitions.js.map +0 -7
  42. package/dist/types/DSReadMoreDefinitions.d.ts +0 -12
@@ -42,7 +42,7 @@ var import_MoreLessButton = require("./MoreLessButton.js");
42
42
  var import_react_desc_prop_types = require("./react-desc-prop-types.js");
43
43
  var import_styled = require("./styled.js");
44
44
  var import_useReadMoreTruncate = require("./useReadMoreTruncate.js");
45
- var import_DSReadMoreDefinitions = require("./DSReadMoreDefinitions.js");
45
+ var import_constants = require("./constants/index.js");
46
46
  const DSReadMore = (props) => {
47
47
  const propsWithDefault = (0, import_ds_props_helpers.useMemoMergePropsWithDefault)(props, import_react_desc_prop_types.defaultProps);
48
48
  const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;
@@ -51,8 +51,11 @@ const DSReadMore = (props) => {
51
51
  const toggleExpanded = (0, import_react.useCallback)(
52
52
  (newExpanded) => {
53
53
  setExpanded(newExpanded);
54
- if (newExpanded) onMore();
55
- else onLess();
54
+ if (newExpanded) {
55
+ onMore();
56
+ } else {
57
+ onLess();
58
+ }
56
59
  },
57
60
  [onMore, onLess, setExpanded]
58
61
  );
@@ -90,7 +93,7 @@ const DSReadMore = (props) => {
90
93
  onClick: () => toggleExpanded(!expanded),
91
94
  ariaLabel: expanded ? "Read less" : "Read more",
92
95
  ellipsis,
93
- dataTestId: import_DSReadMoreDefinitions.DSReadMoreDataTestIds.READ_MORE_BUTTON,
96
+ dataTestId: import_constants.DSReadMoreDataTestIds.READ_MORE_BUTTON,
94
97
  getOwnerProps,
95
98
  getOwnerPropsArguments
96
99
  }
@@ -103,7 +106,7 @@ const DSReadMore = (props) => {
103
106
  ariaLabel: expanded ? "Read less" : "Read more",
104
107
  ellipsis,
105
108
  withTooltip,
106
- dataTestId: import_DSReadMoreDefinitions.DSReadMoreDataTestIds.READ_MORE_TOOLTIP_BUTTON,
109
+ dataTestId: import_constants.DSReadMoreDataTestIds.READ_MORE_TOOLTIP_BUTTON,
107
110
  getOwnerProps,
108
111
  getOwnerPropsArguments
109
112
  }
@@ -112,7 +115,7 @@ const DSReadMore = (props) => {
112
115
  }
113
116
  );
114
117
  };
115
- DSReadMore.displayName = import_DSReadMoreDefinitions.DSReadMoreName;
118
+ DSReadMore.displayName = import_constants.DSReadMoreName;
116
119
  const DSReadMoreWithSchema = (0, import_ds_props_helpers.describe)(DSReadMore);
117
120
  DSReadMoreWithSchema.propTypes = import_react_desc_prop_types.DSReadMorePropTypesSchema;
118
121
  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 React, { useCallback } from 'react';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { type DSReadMoreT, DSReadMorePropTypesSchema, defaultProps } from './react-desc-prop-types.js';\nimport { StyledTextWrapper, StyledTextContent, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './DSReadMoreDefinitions.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) onMore();\n else onLess();\n },\n [onMore, onLess, setExpanded],\n );\n\n const getOwnerProps = useCallback(() => propsWithDefault, [propsWithDefault]);\n const getOwnerPropsArguments = useCallback(() => ({}), []);\n\n return (\n <StyledTextWrapper\n innerRef={textWrapperRef}\n lines={lines}\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n {...xstyledProps}\n >\n {srOnlyText}\n <StyledTextContent\n lines={lines}\n expanded={expanded}\n innerRef={textRef}\n data-testid=\"ds-read_more-text\"\n {...textProps}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n >\n {content}\n </StyledTextContent>\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? 'Read less' : 'Read more'}\n ellipsis={ellipsis}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n )}\n {withTooltip && showButton && (\n <StyledTooltipWrapper getOwnerProps={getOwnerProps} getOwnerPropsArguments={getOwnerPropsArguments}>\n <DSTooltipV3 text={content} wrapWords>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ariaLabel={expanded ? 'Read less' : 'Read more'}\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;\n\nconst DSReadMoreWithSchema = describe(DSReadMore);\n\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;AD+BnB;AA/BJ,mBAAmC;AACnC,8BAA2E;AAC3E,2BAA4B;AAC5B,4BAA+B;AAC/B,mCAA0E;AAC1E,oBAA2E;AAC3E,iCAAoC;AACpC,mCAAsD;AAEtD,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,YAAa,QAAO;AAAA,UACnB,QAAO;AAAA,IACd;AAAA,IACA,CAAC,QAAQ,QAAQ,WAAW;AAAA,EAC9B;AAEA,QAAM,oBAAgB,0BAAY,MAAM,kBAAkB,CAAC,gBAAgB,CAAC;AAC5E,QAAM,6BAAyB,0BAAY,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV,eAAY;AAAA,YACX,GAAG;AAAA,YACJ;AAAA,YACA;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACC,cAAc,CAAC,eACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAO,WAAW,OAAO;AAAA,YACzB,SAAS,MAAM,eAAe,CAAC,QAAQ;AAAA,YACvC,WAAW,WAAW,cAAc;AAAA,YACpC;AAAA,YACA,YAAY,mDAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QAED,eAAe,cACd,4CAAC,sCAAqB,eAA8B,wBAClD,sDAAC,oCAAY,MAAM,SAAS,WAAS,MACnC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAM;AAAA,YACN,WAAW,WAAW,cAAc;AAAA,YACpC;AAAA,YACA;AAAA,YACA,YAAY,mDAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF,GACF,GACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,WAAW,cAAc;AAEzB,MAAM,2BAAuB,kCAAS,UAAU;AAEhD,qBAAqB,YAAY;AAGjC,IAAO,qBAAQ;",
4
+ "sourcesContent": ["// DSReadMore.tsx\nimport React, { useCallback } from 'react';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { type DSReadMoreT, DSReadMorePropTypesSchema, defaultProps } from './react-desc-prop-types.js';\nimport { StyledTextWrapper, StyledTextContent, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './constants/index.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(() => ({}), []);\n\n return (\n <StyledTextWrapper\n innerRef={textWrapperRef}\n lines={lines}\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n {...xstyledProps}\n >\n {srOnlyText}\n\n <StyledTextContent\n lines={lines}\n expanded={expanded}\n innerRef={textRef}\n data-testid=\"ds-read_more-text\"\n {...textProps}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n >\n {content}\n </StyledTextContent>\n\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? 'Read less' : 'Read more'}\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 ariaLabel={expanded ? 'Read less' : 'Read more'}\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;ADmCnB;AAlCJ,mBAAmC;AACnC,8BAA2E;AAC3E,2BAA4B;AAC5B,4BAA+B;AAC/B,mCAA0E;AAC1E,oBAA2E;AAC3E,iCAAoC;AACpC,uBAAsD;AAEtD,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,CAAC,IAAI,CAAC,CAAC;AAEzD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QAED;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV,eAAY;AAAA,YACX,GAAG;AAAA,YACJ;AAAA,YACA;AAAA,YAEC;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,WAAW,WAAW,cAAc;AAAA,YACpC;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,WAAW,WAAW,cAAc;AAAA,YACpC;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
  }
@@ -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 DSReadMoreDefinitions_exports = {};
30
- __export(DSReadMoreDefinitions_exports, {
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(DSReadMoreDefinitions_exports);
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 DSReadMoreSlots = {
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 DSReadMoreDataTestIds = {
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
- //# sourceMappingURL=DSReadMoreDefinitions.js.map
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: () => import_DSReadMoreDefinitions.DSReadMoreDataTestIds,
33
- DSReadMoreName: () => import_DSReadMoreDefinitions.DSReadMoreName,
34
- DSReadMoreSlots: () => import_DSReadMoreDefinitions.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 import_DSReadMoreDefinitions = require("./DSReadMoreDefinitions.js");
43
+ var import_constants = require("./constants/index.js");
42
44
  var import_useReadMoreTruncate = require("./useReadMoreTruncate.js");
43
45
  //# sourceMappingURL=index.js.map
@@ -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 { DSReadMoreName, DSReadMoreSlots, DSReadMoreDataTestIds } from './DSReadMoreDefinitions.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;ACAA,YAAuB;ADAvB,wBAAiD;AACjD,mCAAuE;AAEvE,iCAAoC;",
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 import_DSReadMoreDefinitions = require("./DSReadMoreDefinitions.js");
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)(import_DSReadMoreDefinitions.DSReadMoreDataTestIds)
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 { WeakValidationMap } from 'react';\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { DSReadMoreDataTestIds } from './DSReadMoreDefinitions.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\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 ...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 WeakValidationMap<DSReadMoreT.Props>;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAKO;AAGP,mCAAsC;AA2B/B,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,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,kDAAqB;AACzD;AAEO,MAAM,4BAA4B;",
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
  }
@@ -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 import_DSReadMoreDefinitions = require("./DSReadMoreDefinitions.js");
43
- const StyledTextWrapper = (0, import_ds_system.styled)("span", { name: import_DSReadMoreDefinitions.DSReadMoreName, slot: import_DSReadMoreDefinitions.DSReadMoreSlots.ROOT })`
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
@@ -69,7 +69,7 @@ const StyledTextWrapper = (0, import_ds_system.styled)("span", { name: import_DS
69
69
  word-break: break-all;
70
70
  ${import_ds_system.xStyledCommonProps}
71
71
  `;
72
- const StyledTextContent = (0, import_ds_system.styled)("span", { name: import_DSReadMoreDefinitions.DSReadMoreName, slot: import_DSReadMoreDefinitions.DSReadMoreSlots.TEXT_CONTENT })`
72
+ const StyledTextContent = (0, import_ds_system.styled)("span", { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.TEXT_CONTENT })`
73
73
  ${({ lines, expanded }) => lines === 1 && !expanded ? `
74
74
  flex: 1 1 auto;
75
75
  overflow: hidden;
@@ -77,11 +77,11 @@ const StyledTextContent = (0, import_ds_system.styled)("span", { name: import_DS
77
77
  text-overflow: clip;
78
78
  ` : ""}
79
79
  `;
80
- const StyledTooltipWrapper = (0, import_ds_system.styled)("div", { name: import_DSReadMoreDefinitions.DSReadMoreName, slot: import_DSReadMoreDefinitions.DSReadMoreSlots.TOOLTIP_WRAPPER })`
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: import_DSReadMoreDefinitions.DSReadMoreName, slot: import_DSReadMoreDefinitions.DSReadMoreSlots.BUTTON_WRAPPER })``;
84
- const StyledButton = (0, import_ds_system.styled)(import_ds_button_v2.DSButtonV2, { name: import_DSReadMoreDefinitions.DSReadMoreName, slot: import_DSReadMoreDefinitions.DSReadMoreSlots.BUTTON })`
83
+ const StyledButtonWrapper = (0, import_ds_system.styled)("span", { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.BUTTON_WRAPPER })``;
84
+ const StyledButton = (0, import_ds_system.styled)(import_ds_button_v2.DSButtonV2, { name: import_constants.DSReadMoreName, slot: import_constants.DSReadMoreSlots.BUTTON })`
85
85
  padding: 0;
86
86
  color: ${({ withTooltip, theme }) => withTooltip ? "inherit" : `${theme.colors.brand["600"]}`};
87
87
  border: 0;
@@ -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 { DSButtonV2 } from '@elliemae/ds-button-v2';\nimport { DSReadMoreName, DSReadMoreSlots } from './DSReadMoreDefinitions.js';\n\nexport const StyledTextWrapper = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.ROOT })<{\n lines: number;\n expanded: 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, expanded }) =>\n lines === 1 && !expanded\n ? `\n display: flex;\n align-items: baseline;\n overflow: hidden;\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 word-break: break-all;\n ${xStyledCommonProps}\n`;\n\nexport const StyledTextContent = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.TEXT_CONTENT })<{\n lines: number;\n expanded: boolean;\n}>`\n ${({ lines, expanded }) =>\n lines === 1 && !expanded\n ? `\n flex: 1 1 auto;\n overflow: hidden;\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\nexport const StyledButton = styled(DSButtonV2, { name: DSReadMoreName, slot: DSReadMoreSlots.BUTTON })<{\n withTooltip?: boolean;\n}>`\n padding: 0;\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,mCAAgD;AAEzC,MAAM,wBAAoB,yBAAO,QAAQ,EAAE,MAAM,6CAAgB,MAAM,6CAAgB,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAchG,CAAC,EAAE,OAAO,SAAS,MACnB,UAAU,KAAK,CAAC,WACZ;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA;AAAA;AAAA,0BAEkB,WAAW,UAAU,KAAK;AAAA;AAAA,GAEjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOC,mCAAkB;AAAA;AAGf,MAAM,wBAAoB,yBAAO,QAAQ,EAAE,MAAM,6CAAgB,MAAM,6CAAgB,aAAa,CAAC;AAAA,IAIxG,CAAC,EAAE,OAAO,SAAS,MACnB,UAAU,KAAK,CAAC,WACZ;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,EAAE;AAAA;AAGH,MAAM,2BAAuB,yBAAO,OAAO,EAAE,MAAM,6CAAgB,MAAM,6CAAgB,gBAAgB,CAAC;AAAA;AAAA;AAI1G,MAAM,0BAAsB,yBAAO,QAAQ,EAAE,MAAM,6CAAgB,MAAM,6CAAgB,eAAe,CAAC;AAEzG,MAAM,mBAAe,yBAAO,gCAAY,EAAE,MAAM,6CAAgB,MAAM,6CAAgB,OAAO,CAAC;AAAA;AAAA,WAI1F,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;",
4
+ "sourcesContent": ["import { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSButtonV2 } 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}>`\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, expanded }) =>\n lines === 1 && !expanded\n ? `\n display: flex;\n align-items: baseline;\n overflow: hidden;\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 word-break: break-all;\n ${xStyledCommonProps}\n`;\n\nexport const StyledTextContent = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.TEXT_CONTENT })<{\n lines: number;\n expanded: boolean;\n}>`\n ${({ lines, expanded }) =>\n lines === 1 && !expanded\n ? `\n flex: 1 1 auto;\n overflow: hidden;\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\nexport const StyledButton = styled(DSButtonV2, { name: DSReadMoreName, slot: DSReadMoreSlots.BUTTON })<{\n withTooltip?: boolean;\n}>`\n padding: 0;\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,IAchG,CAAC,EAAE,OAAO,SAAS,MACnB,UAAU,KAAK,CAAC,WACZ;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA;AAAA;AAAA,0BAEkB,WAAW,UAAU,KAAK;AAAA;AAAA,GAEjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOC,mCAAkB;AAAA;AAGf,MAAM,wBAAoB,yBAAO,QAAQ,EAAE,MAAM,iCAAgB,MAAM,iCAAgB,aAAa,CAAC;AAAA,IAIxG,CAAC,EAAE,OAAO,SAAS,MACnB,UAAU,KAAK,CAAC,WACZ;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;AAEzG,MAAM,mBAAe,yBAAO,gCAAY,EAAE,MAAM,iCAAgB,MAAM,iCAAgB,OAAO,CAAC;AAAA;AAAA,WAI1F,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
  }
@@ -43,13 +43,13 @@ const binSearchTextOverflow = (element, parent, content) => {
43
43
  let textEnd = 0;
44
44
  element.innerText = content;
45
45
  while (left <= right) {
46
- const middle = Math.floor((left + right) / 2);
47
- element.innerText = content.slice(0, middle);
46
+ const mid = Math.floor((left + right) / 2);
47
+ element.innerText = content.slice(0, mid);
48
48
  if (overflows(parent)) {
49
- right = middle - 1;
49
+ right = mid - 1;
50
50
  } else {
51
- textEnd = middle;
52
- left = middle + 1;
51
+ textEnd = mid;
52
+ left = mid + 1;
53
53
  }
54
54
  }
55
55
  element.innerText = content.slice(0, textEnd);
@@ -61,40 +61,47 @@ const useReadMoreTruncate = ({ lines, content }) => {
61
61
  const [showButton, setShowButton] = (0, import_react.useState)(false);
62
62
  const { width, height } = (0, import_useOnElementResize.useOnElementResize)(textWrapperRef);
63
63
  (0, import_react.useLayoutEffect)(() => {
64
- const textElement = textRef.current;
65
- const parentElement = textWrapperRef.current;
66
- if (parentElement && textElement) {
67
- textElement.innerText = content;
68
- if (lines === 1) {
69
- const computed = getComputedStyle(textElement);
70
- const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;
71
- const canvas = document.createElement("canvas");
72
- const ctx = canvas.getContext("2d");
73
- let isTruncated = false;
74
- if (ctx) {
75
- ctx.font = font;
76
- const measuredWidth = ctx.measureText(content).width;
77
- isTruncated = measuredWidth > parentElement.clientWidth;
78
- }
79
- setShowButton(expanded || isTruncated);
80
- return;
64
+ const textEl = textRef.current;
65
+ const wrapperEl = textWrapperRef.current;
66
+ if (!textEl || !wrapperEl) return;
67
+ textEl.innerText = content;
68
+ if (lines === 1) {
69
+ const computed = getComputedStyle(textEl);
70
+ const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;
71
+ const canvas = document.createElement("canvas");
72
+ const ctx = canvas.getContext("2d");
73
+ let truncated = false;
74
+ if (ctx) {
75
+ ctx.font = font;
76
+ const measuredWidth = ctx.measureText(content).width;
77
+ truncated = measuredWidth > wrapperEl.clientWidth;
81
78
  }
82
- const isOverflowing = overflows(parentElement);
83
- setShowButton(expanded || isOverflowing);
84
- if (!expanded && isOverflowing) {
85
- setTimeout(() => {
86
- binSearchTextOverflow(textElement, parentElement, content);
87
- }, 0);
79
+ setShowButton(expanded || truncated);
80
+ return;
81
+ }
82
+ const isOverflowing = overflows({
83
+ offsetHeight: wrapperEl.offsetHeight,
84
+ scrollHeight: wrapperEl.scrollHeight
85
+ });
86
+ setShowButton(expanded || isOverflowing);
87
+ if (!expanded && isOverflowing) {
88
+ const doBinaryTruncate = () => {
89
+ if (!textEl || !wrapperEl) return;
90
+ binSearchTextOverflow(textEl, wrapperEl, content);
91
+ };
92
+ if ("fonts" in document && document.fonts.ready) {
93
+ document.fonts.ready.then(() => {
94
+ doBinaryTruncate();
95
+ }).catch(() => {
96
+ setTimeout(doBinaryTruncate, 0);
97
+ });
98
+ } else {
99
+ setTimeout(doBinaryTruncate, 0);
88
100
  }
89
101
  }
90
102
  }, [lines, content, expanded, width, height]);
91
103
  const srOnlyText = (0, import_react.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_styled.ScreenReaderOnly, { children: content }), [content]);
92
- const textProps = (0, import_react.useMemo)(
93
- () => ({
94
- "aria-hidden": true
95
- }),
96
- []
97
- );
104
+ const textProps = (0, import_react.useMemo)(() => ({ "aria-hidden": true }), []);
98
105
  return {
99
106
  textWrapperRef,
100
107
  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": ["import 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';\n\n// offsetHeight + margin helps account for subpixel differences and the button size\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 4 < scrollHeight;\n\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n let left = 0;\n let right = content.length;\n let textEnd = 0;\n\n // Reset text to full before starting\n element.innerText = content;\n\n while (left <= right) {\n const middle = Math.floor((left + right) / 2);\n element.innerText = content.slice(0, middle);\n\n if (overflows(parent)) {\n right = middle - 1;\n } else {\n textEnd = middle;\n left = middle + 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\n const [showButton, setShowButton] = useState(false);\n\n // We need to re-run the effect when the size of the container changes\n const { width, height } = useOnElementResize(textWrapperRef);\n\n useLayoutEffect(() => {\n const textElement = textRef.current;\n const parentElement = textWrapperRef.current;\n if (parentElement && textElement) {\n textElement.innerText = content;\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 * Instead of relying on overflow-based measurements, we calculate the actual pixel width\n * of the text using a canvas and compare it with the visible width of the wrapper.\n *\n * This method is layout-safe, does not force reflow, and works reliably across browsers.\n */\n if (lines === 1) {\n const computed = getComputedStyle(textElement);\n const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n let isTruncated = false;\n if (ctx) {\n ctx.font = font;\n const measuredWidth = ctx.measureText(content).width;\n isTruncated = measuredWidth > parentElement.clientWidth;\n }\n setShowButton(expanded || isTruncated);\n return;\n }\n\n const isOverflowing = overflows(parentElement);\n setShowButton(expanded || isOverflowing);\n if (!expanded && isOverflowing) {\n // we have a strange edge case where when removing the browser cache the text is not\n // truncated correctly, so we need to wait for the next frame\n // to make sure the text is truncated correctly\n // my supposition is that the text is not rendered yet becuase of the font loading\n setTimeout(() => {\n binSearchTextOverflow(textElement, parentElement, content);\n }, 0);\n }\n }\n }, [lines, content, expanded, width, height]);\n\n const srOnlyText = useMemo(() => <ScreenReaderOnly>{content}</ScreenReaderOnly>, [content]);\n\n const textProps = useMemo(\n () => ({\n 'aria-hidden': true,\n }),\n [],\n );\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;ADwFY;AAxFnC,mBAAkE;AAClE,gCAAmC;AAEnC,oBAAiC;AAGjC,MAAM,YAAY,CAAC,EAAE,cAAc,aAAa,MAC9C,eAAe,IAAI;AAErB,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,SAAS,KAAK,OAAO,OAAO,SAAS,CAAC;AAC5C,YAAQ,YAAY,QAAQ,MAAM,GAAG,MAAM;AAE3C,QAAI,UAAU,MAAM,GAAG;AACrB,cAAQ,SAAS;AAAA,IACnB,OAAO;AACL,gBAAU;AACV,aAAO,SAAS;AAAA,IAClB;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;AAE9C,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAGlD,QAAM,EAAE,OAAO,OAAO,QAAI,8CAAmB,cAAc;AAE3D,oCAAgB,MAAM;AACpB,UAAM,cAAc,QAAQ;AAC5B,UAAM,gBAAgB,eAAe;AACrC,QAAI,iBAAiB,aAAa;AAChC,kBAAY,YAAY;AAYxB,UAAI,UAAU,GAAG;AACf,cAAM,WAAW,iBAAiB,WAAW;AAC7C,cAAM,OAAO,GAAG,SAAS,UAAU,IAAI,SAAS,QAAQ,IAAI,SAAS,UAAU;AAC/E,cAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,cAAM,MAAM,OAAO,WAAW,IAAI;AAClC,YAAI,cAAc;AAClB,YAAI,KAAK;AACP,cAAI,OAAO;AACX,gBAAM,gBAAgB,IAAI,YAAY,OAAO,EAAE;AAC/C,wBAAc,gBAAgB,cAAc;AAAA,QAC9C;AACA,sBAAc,YAAY,WAAW;AACrC;AAAA,MACF;AAEA,YAAM,gBAAgB,UAAU,aAAa;AAC7C,oBAAc,YAAY,aAAa;AACvC,UAAI,CAAC,YAAY,eAAe;AAK9B,mBAAW,MAAM;AACf,gCAAsB,aAAa,eAAe,OAAO;AAAA,QAC3D,GAAG,CAAC;AAAA,MACN;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,UAAU,OAAO,MAAM,CAAC;AAE5C,QAAM,iBAAa,sBAAQ,MAAM,4CAAC,kCAAkB,mBAAQ,GAAqB,CAAC,OAAO,CAAC;AAE1F,QAAM,gBAAY;AAAA,IAChB,OAAO;AAAA,MACL,eAAe;AAAA,IACjB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
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';\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) {\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 binSearchTextOverflow(textEl, wrapperEl, content);\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;ADkHY;AA9GnC,mBAAkE;AAClE,gCAAmC;AAEnC,oBAAiC;AAGjC,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,GAAG;AACf,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,QAAQ,WAAW,OAAO;AAAA,MAClD;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
  }
@@ -7,7 +7,7 @@ import { MoreLessButton } from "./MoreLessButton.js";
7
7
  import { DSReadMorePropTypesSchema, defaultProps } from "./react-desc-prop-types.js";
8
8
  import { StyledTextWrapper, StyledTextContent, StyledTooltipWrapper } from "./styled.js";
9
9
  import { useReadMoreTruncate } from "./useReadMoreTruncate.js";
10
- import { DSReadMoreDataTestIds, DSReadMoreName } from "./DSReadMoreDefinitions.js";
10
+ import { DSReadMoreDataTestIds, DSReadMoreName } from "./constants/index.js";
11
11
  const DSReadMore = (props) => {
12
12
  const propsWithDefault = useMemoMergePropsWithDefault(props, defaultProps);
13
13
  const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;
@@ -16,8 +16,11 @@ const DSReadMore = (props) => {
16
16
  const toggleExpanded = useCallback(
17
17
  (newExpanded) => {
18
18
  setExpanded(newExpanded);
19
- if (newExpanded) onMore();
20
- else onLess();
19
+ if (newExpanded) {
20
+ onMore();
21
+ } else {
22
+ onLess();
23
+ }
21
24
  },
22
25
  [onMore, onLess, setExpanded]
23
26
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/DSReadMore.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useCallback } from 'react';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { type DSReadMoreT, DSReadMorePropTypesSchema, defaultProps } from './react-desc-prop-types.js';\nimport { StyledTextWrapper, StyledTextContent, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './DSReadMoreDefinitions.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) onMore();\n else onLess();\n },\n [onMore, onLess, setExpanded],\n );\n\n const getOwnerProps = useCallback(() => propsWithDefault, [propsWithDefault]);\n const getOwnerPropsArguments = useCallback(() => ({}), []);\n\n return (\n <StyledTextWrapper\n innerRef={textWrapperRef}\n lines={lines}\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n {...xstyledProps}\n >\n {srOnlyText}\n <StyledTextContent\n lines={lines}\n expanded={expanded}\n innerRef={textRef}\n data-testid=\"ds-read_more-text\"\n {...textProps}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n >\n {content}\n </StyledTextContent>\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? 'Read less' : 'Read more'}\n ellipsis={ellipsis}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n )}\n {withTooltip && showButton && (\n <StyledTooltipWrapper getOwnerProps={getOwnerProps} getOwnerPropsArguments={getOwnerPropsArguments}>\n <DSTooltipV3 text={content} wrapWords>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ariaLabel={expanded ? 'Read less' : 'Read more'}\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;\n\nconst DSReadMoreWithSchema = describe(DSReadMore);\n\nDSReadMoreWithSchema.propTypes = DSReadMorePropTypesSchema;\n\nexport { DSReadMore, DSReadMoreWithSchema };\nexport default DSReadMore;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;AC+BnB,SASE,KATF;AA/BJ,SAAgB,mBAAmB;AACnC,SAAS,UAAU,oBAAoB,oCAAoC;AAC3E,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAA2B,2BAA2B,oBAAoB;AAC1E,SAAS,mBAAmB,mBAAmB,4BAA4B;AAC3E,SAAS,2BAA2B;AACpC,SAAS,uBAAuB,sBAAsB;AAEtD,MAAM,aAAa,CAAC,UAA6B;AAC/C,QAAM,mBAAmB,6BAAwD,OAAO,YAAY;AACpG,QAAM,EAAE,OAAO,MAAM,MAAM,SAAS,aAAa,UAAU,QAAQ,OAAO,IAAI;AAE9E,QAAM,eAAe,mBAAmB,gBAAgB;AAExD,QAAM,EAAE,gBAAgB,SAAS,YAAY,UAAU,aAAa,WAAW,WAAW,IACxF,oBAAoB,gBAAgB;AAEtC,QAAM,iBAAiB;AAAA,IACrB,CAAC,gBAAyB;AACxB,kBAAY,WAAW;AACvB,UAAI,YAAa,QAAO;AAAA,UACnB,QAAO;AAAA,IACd;AAAA,IACA,CAAC,QAAQ,QAAQ,WAAW;AAAA,EAC9B;AAEA,QAAM,gBAAgB,YAAY,MAAM,kBAAkB,CAAC,gBAAgB,CAAC;AAC5E,QAAM,yBAAyB,YAAY,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV,eAAY;AAAA,YACX,GAAG;AAAA,YACJ;AAAA,YACA;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QACC,cAAc,CAAC,eACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAO,WAAW,OAAO;AAAA,YACzB,SAAS,MAAM,eAAe,CAAC,QAAQ;AAAA,YACvC,WAAW,WAAW,cAAc;AAAA,YACpC;AAAA,YACA,YAAY,sBAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QAED,eAAe,cACd,oBAAC,wBAAqB,eAA8B,wBAClD,8BAAC,eAAY,MAAM,SAAS,WAAS,MACnC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAM;AAAA,YACN,WAAW,WAAW,cAAc;AAAA,YACpC;AAAA,YACA;AAAA,YACA,YAAY,sBAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF,GACF,GACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,WAAW,cAAc;AAEzB,MAAM,uBAAuB,SAAS,UAAU;AAEhD,qBAAqB,YAAY;AAGjC,IAAO,qBAAQ;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "// DSReadMore.tsx\nimport React, { useCallback } from 'react';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { type DSReadMoreT, DSReadMorePropTypesSchema, defaultProps } from './react-desc-prop-types.js';\nimport { StyledTextWrapper, StyledTextContent, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './constants/index.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(() => ({}), []);\n\n return (\n <StyledTextWrapper\n innerRef={textWrapperRef}\n lines={lines}\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n {...xstyledProps}\n >\n {srOnlyText}\n\n <StyledTextContent\n lines={lines}\n expanded={expanded}\n innerRef={textRef}\n data-testid=\"ds-read_more-text\"\n {...textProps}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n >\n {content}\n </StyledTextContent>\n\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? 'Read less' : 'Read more'}\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 ariaLabel={expanded ? 'Read less' : 'Read more'}\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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACmCnB,SAUE,KAVF;AAlCJ,SAAgB,mBAAmB;AACnC,SAAS,UAAU,oBAAoB,oCAAoC;AAC3E,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAA2B,2BAA2B,oBAAoB;AAC1E,SAAS,mBAAmB,mBAAmB,4BAA4B;AAC3E,SAAS,2BAA2B;AACpC,SAAS,uBAAuB,sBAAsB;AAEtD,MAAM,aAAa,CAAC,UAA6B;AAC/C,QAAM,mBAAmB,6BAAwD,OAAO,YAAY;AACpG,QAAM,EAAE,OAAO,MAAM,MAAM,SAAS,aAAa,UAAU,QAAQ,OAAO,IAAI;AAE9E,QAAM,eAAe,mBAAmB,gBAAgB;AAExD,QAAM,EAAE,gBAAgB,SAAS,YAAY,UAAU,aAAa,WAAW,WAAW,IACxF,oBAAoB,gBAAgB;AAEtC,QAAM,iBAAiB;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,gBAAgB,YAAY,MAAM,kBAAkB,CAAC,gBAAgB,CAAC;AAC5E,QAAM,yBAAyB,YAAY,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QAED;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV,eAAY;AAAA,YACX,GAAG;AAAA,YACJ;AAAA,YACA;AAAA,YAEC;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,WAAW,WAAW,cAAc;AAAA,YACpC;AAAA,YACA,YAAY,sBAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QAGD,eAAe,cACd,oBAAC,wBAAqB,eAA8B,wBAClD,8BAAC,eAAY,MAAM,SAAS,WAAS,MACnC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAM;AAAA,YACN,WAAW,WAAW,cAAc;AAAA,YACpC;AAAA,YACA;AAAA,YACA,YAAY,sBAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF,GACF,GACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,WAAW,cAAc;AACzB,MAAM,uBAAuB,SAAS,UAAU;AAChD,qBAAqB,YAAY;AAGjC,IAAO,qBAAQ;",
6
6
  "names": []
7
7
  }
@@ -2,21 +2,26 @@ import * as React from "react";
2
2
  import { omit } from "lodash-es";
3
3
  import { slotObjectToDataTestIds } from "@elliemae/ds-system";
4
4
  const DSReadMoreName = "DSReadmore";
5
- const DSReadMoreSlots = {
5
+ const READ_MORE_SLOTS = {
6
6
  ROOT: "root",
7
7
  TEXT_CONTENT: "text-content",
8
8
  TOOLTIP_WRAPPER: "tooltip-wrapper",
9
9
  BUTTON_WRAPPER: "button-wrapper",
10
10
  BUTTON: "button"
11
11
  };
12
- const DSReadMoreDataTestIds = {
12
+ const DSReadMoreSlots = READ_MORE_SLOTS;
13
+ const READ_MORE_DATA_TESTID = {
13
14
  ...omit(slotObjectToDataTestIds(DSReadMoreName, DSReadMoreSlots), "BUTTON"),
14
15
  READ_MORE_BUTTON: "ds-read_more-button",
15
- READ_MORE_TOOLTIP_BUTTON: "ds-read_more-tooltip-button"
16
+ READ_MORE_TOOLTIP_BUTTON: "ds-read_more-tooltip-button",
17
+ READ_MORE_TEXT: "ds-read_more-text"
16
18
  };
19
+ const DSReadMoreDataTestIds = READ_MORE_DATA_TESTID;
17
20
  export {
18
21
  DSReadMoreDataTestIds,
19
22
  DSReadMoreName,
20
- DSReadMoreSlots
23
+ DSReadMoreSlots,
24
+ READ_MORE_DATA_TESTID,
25
+ READ_MORE_SLOTS
21
26
  };
22
- //# sourceMappingURL=DSReadMoreDefinitions.js.map
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/constants/index.tsx"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,YAAY;AACrB,SAAS,+BAA+B;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,GAAG,KAAK,wBAAwB,gBAAgB,eAAe,GAAG,QAAQ;AAAA,EAC1E,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,gBAAgB;AAClB;AAGO,MAAM,wBAAwB;",
6
+ "names": []
7
+ }
package/dist/esm/index.js CHANGED
@@ -1,6 +1,12 @@
1
1
  import * as React from "react";
2
2
  import { DSReadMore, DSReadMoreWithSchema } from "./DSReadMore.js";
3
- import { DSReadMoreName, DSReadMoreSlots, DSReadMoreDataTestIds } from "./DSReadMoreDefinitions.js";
3
+ import {
4
+ DSReadMoreName,
5
+ DSReadMoreSlots,
6
+ READ_MORE_SLOTS,
7
+ DSReadMoreDataTestIds,
8
+ READ_MORE_DATA_TESTID
9
+ } from "./constants/index.js";
4
10
  import { useReadMoreTruncate } from "./useReadMoreTruncate.js";
5
11
  export {
6
12
  DSReadMore,
@@ -8,6 +14,8 @@ export {
8
14
  DSReadMoreName,
9
15
  DSReadMoreSlots,
10
16
  DSReadMoreWithSchema,
17
+ READ_MORE_DATA_TESTID,
18
+ READ_MORE_SLOTS,
11
19
  useReadMoreTruncate
12
20
  };
13
21
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/index.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "export { DSReadMore, DSReadMoreWithSchema } from './DSReadMore.js';\nexport { DSReadMoreName, DSReadMoreSlots, DSReadMoreDataTestIds } from './DSReadMoreDefinitions.js';\nexport type { DSReadMoreT } from './react-desc-prop-types.js';\nexport { useReadMoreTruncate } from './useReadMoreTruncate.js';\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,YAAY,4BAA4B;AACjD,SAAS,gBAAgB,iBAAiB,6BAA6B;AAEvE,SAAS,2BAA2B;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,YAAY,4BAA4B;AACjD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,2BAA2B;",
6
6
  "names": []
7
7
  }
@@ -1,11 +1,12 @@
1
1
  import * as React from "react";
2
2
  import {
3
3
  getPropsPerDatatestIdPropTypes,
4
+ getPropsPerSlotPropTypes,
4
5
  globalAttributesPropTypes,
5
6
  PropTypes,
6
7
  xstyledPropTypes
7
8
  } from "@elliemae/ds-props-helpers";
8
- import { DSReadMoreDataTestIds } from "./DSReadMoreDefinitions.js";
9
+ import { DSReadMoreDataTestIds, DSReadMoreName, READ_MORE_SLOTS } from "./constants/index.js";
9
10
  const defaultProps = {
10
11
  lines: 2,
11
12
  more: "more",
@@ -18,6 +19,7 @@ const defaultProps = {
18
19
  withTooltip: false
19
20
  };
20
21
  const DSReadMorePropTypes = {
22
+ ...getPropsPerSlotPropTypes(DSReadMoreName, READ_MORE_SLOTS),
21
23
  ...globalAttributesPropTypes,
22
24
  ...xstyledPropTypes,
23
25
  /** Ammount of lines after you want to display an ellipsis + more/less button */
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/react-desc-prop-types.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* 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 { WeakValidationMap } from 'react';\nimport type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliemae/ds-props-helpers';\nimport { DSReadMoreDataTestIds } from './DSReadMoreDefinitions.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\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 ...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 WeakValidationMap<DSReadMoreT.Props>;\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,6BAA6B;AA2B/B,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,GAAG;AAAA,EACH,GAAG;AAAA;AAAA,EAEH,OAAO,UAAU,OACd,YAAY,2EAA2E,EACvF,aAAa,CAAC;AAAA;AAAA,EAEjB,MAAM,UAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA;AAAA,EAEtG,MAAM,UAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA;AAAA,EAEtG,QAAQ,UAAU,KAAK,YAAY,mEAAmE;AAAA;AAAA,EAEtG,QAAQ,UAAU,KAAK,YAAY,mEAAmE;AAAA;AAAA,EAEtG,SAAS,UAAU,OAAO,YAAY,qCAAqC,EAAE;AAAA;AAAA,EAG7E,UAAU,UAAU,OAAO,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAAA,EACxG,aAAa,UAAU,KACpB,YAAY,oFAAoF,EAChG,aAAa,OAAO;AAAA,EACvB,GAAG,+BAA+B,qBAAqB;AACzD;AAEO,MAAM,4BAA4B;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* 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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,uBAAuB,gBAAgB,uBAAuB;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,GAAG,yBAAyB,gBAAgB,eAAe;AAAA,EAC3D,GAAG;AAAA,EACH,GAAG;AAAA;AAAA,EAEH,OAAO,UAAU,OACd,YAAY,2EAA2E,EACvF,aAAa,CAAC;AAAA;AAAA,EAEjB,MAAM,UAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA;AAAA,EAEtG,MAAM,UAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA;AAAA,EAEtG,QAAQ,UAAU,KAAK,YAAY,mEAAmE;AAAA;AAAA,EAEtG,QAAQ,UAAU,KAAK,YAAY,mEAAmE;AAAA;AAAA,EAEtG,SAAS,UAAU,OAAO,YAAY,qCAAqC,EAAE;AAAA;AAAA,EAG7E,UAAU,UAAU,OAAO,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAAA,EACxG,aAAa,UAAU,KACpB,YAAY,oFAAoF,EAChG,aAAa,OAAO;AAAA,EACvB,GAAG,+BAA+B,qBAAqB;AACzD;AAEO,MAAM,4BAA4B;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { styled, xStyledCommonProps } from "@elliemae/ds-system";
3
3
  import { DSButtonV2 } from "@elliemae/ds-button-v2";
4
- import { DSReadMoreName, DSReadMoreSlots } from "./DSReadMoreDefinitions.js";
4
+ import { DSReadMoreName, DSReadMoreSlots } from "./constants/index.js";
5
5
  const StyledTextWrapper = styled("span", { name: DSReadMoreName, slot: DSReadMoreSlots.ROOT })`
6
6
  position: relative;
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/styled.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSButtonV2 } from '@elliemae/ds-button-v2';\nimport { DSReadMoreName, DSReadMoreSlots } from './DSReadMoreDefinitions.js';\n\nexport const StyledTextWrapper = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.ROOT })<{\n lines: number;\n expanded: 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, expanded }) =>\n lines === 1 && !expanded\n ? `\n display: flex;\n align-items: baseline;\n overflow: hidden;\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 word-break: break-all;\n ${xStyledCommonProps}\n`;\n\nexport const StyledTextContent = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.TEXT_CONTENT })<{\n lines: number;\n expanded: boolean;\n}>`\n ${({ lines, expanded }) =>\n lines === 1 && !expanded\n ? `\n flex: 1 1 auto;\n overflow: hidden;\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\nexport const StyledButton = styled(DSButtonV2, { name: DSReadMoreName, slot: DSReadMoreSlots.BUTTON })<{\n withTooltip?: boolean;\n}>`\n padding: 0;\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"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSButtonV2 } 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}>`\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, expanded }) =>\n lines === 1 && !expanded\n ? `\n display: flex;\n align-items: baseline;\n overflow: hidden;\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 word-break: break-all;\n ${xStyledCommonProps}\n`;\n\nexport const StyledTextContent = styled('span', { name: DSReadMoreName, slot: DSReadMoreSlots.TEXT_CONTENT })<{\n lines: number;\n expanded: boolean;\n}>`\n ${({ lines, expanded }) =>\n lines === 1 && !expanded\n ? `\n flex: 1 1 auto;\n overflow: hidden;\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\nexport const StyledButton = styled(DSButtonV2, { name: DSReadMoreName, slot: DSReadMoreSlots.BUTTON })<{\n withTooltip?: boolean;\n}>`\n padding: 0;\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"],
5
5
  "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,QAAQ,0BAA0B;AAC3C,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB,uBAAuB;AAEzC,MAAM,oBAAoB,OAAO,QAAQ,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAchG,CAAC,EAAE,OAAO,SAAS,MACnB,UAAU,KAAK,CAAC,WACZ;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA;AAAA;AAAA,0BAEkB,WAAW,UAAU,KAAK;AAAA;AAAA,GAEjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOC,kBAAkB;AAAA;AAGf,MAAM,oBAAoB,OAAO,QAAQ,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,aAAa,CAAC;AAAA,IAIxG,CAAC,EAAE,OAAO,SAAS,MACnB,UAAU,KAAK,CAAC,WACZ;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,EAAE;AAAA;AAGH,MAAM,uBAAuB,OAAO,OAAO,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,gBAAgB,CAAC;AAAA;AAAA;AAI1G,MAAM,sBAAsB,OAAO,QAAQ,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,eAAe,CAAC;AAEzG,MAAM,eAAe,OAAO,YAAY,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,OAAO,CAAC;AAAA;AAAA,WAI1F,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,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -10,13 +10,13 @@ const binSearchTextOverflow = (element, parent, content) => {
10
10
  let textEnd = 0;
11
11
  element.innerText = content;
12
12
  while (left <= right) {
13
- const middle = Math.floor((left + right) / 2);
14
- element.innerText = content.slice(0, middle);
13
+ const mid = Math.floor((left + right) / 2);
14
+ element.innerText = content.slice(0, mid);
15
15
  if (overflows(parent)) {
16
- right = middle - 1;
16
+ right = mid - 1;
17
17
  } else {
18
- textEnd = middle;
19
- left = middle + 1;
18
+ textEnd = mid;
19
+ left = mid + 1;
20
20
  }
21
21
  }
22
22
  element.innerText = content.slice(0, textEnd);
@@ -28,40 +28,47 @@ const useReadMoreTruncate = ({ lines, content }) => {
28
28
  const [showButton, setShowButton] = useState(false);
29
29
  const { width, height } = useOnElementResize(textWrapperRef);
30
30
  useLayoutEffect(() => {
31
- const textElement = textRef.current;
32
- const parentElement = textWrapperRef.current;
33
- if (parentElement && textElement) {
34
- textElement.innerText = content;
35
- if (lines === 1) {
36
- const computed = getComputedStyle(textElement);
37
- const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;
38
- const canvas = document.createElement("canvas");
39
- const ctx = canvas.getContext("2d");
40
- let isTruncated = false;
41
- if (ctx) {
42
- ctx.font = font;
43
- const measuredWidth = ctx.measureText(content).width;
44
- isTruncated = measuredWidth > parentElement.clientWidth;
45
- }
46
- setShowButton(expanded || isTruncated);
47
- return;
31
+ const textEl = textRef.current;
32
+ const wrapperEl = textWrapperRef.current;
33
+ if (!textEl || !wrapperEl) return;
34
+ textEl.innerText = content;
35
+ if (lines === 1) {
36
+ const computed = getComputedStyle(textEl);
37
+ const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;
38
+ const canvas = document.createElement("canvas");
39
+ const ctx = canvas.getContext("2d");
40
+ let truncated = false;
41
+ if (ctx) {
42
+ ctx.font = font;
43
+ const measuredWidth = ctx.measureText(content).width;
44
+ truncated = measuredWidth > wrapperEl.clientWidth;
48
45
  }
49
- const isOverflowing = overflows(parentElement);
50
- setShowButton(expanded || isOverflowing);
51
- if (!expanded && isOverflowing) {
52
- setTimeout(() => {
53
- binSearchTextOverflow(textElement, parentElement, content);
54
- }, 0);
46
+ setShowButton(expanded || truncated);
47
+ return;
48
+ }
49
+ const isOverflowing = overflows({
50
+ offsetHeight: wrapperEl.offsetHeight,
51
+ scrollHeight: wrapperEl.scrollHeight
52
+ });
53
+ setShowButton(expanded || isOverflowing);
54
+ if (!expanded && isOverflowing) {
55
+ const doBinaryTruncate = () => {
56
+ if (!textEl || !wrapperEl) return;
57
+ binSearchTextOverflow(textEl, wrapperEl, content);
58
+ };
59
+ if ("fonts" in document && document.fonts.ready) {
60
+ document.fonts.ready.then(() => {
61
+ doBinaryTruncate();
62
+ }).catch(() => {
63
+ setTimeout(doBinaryTruncate, 0);
64
+ });
65
+ } else {
66
+ setTimeout(doBinaryTruncate, 0);
55
67
  }
56
68
  }
57
69
  }, [lines, content, expanded, width, height]);
58
70
  const srOnlyText = useMemo(() => /* @__PURE__ */ jsx(ScreenReaderOnly, { children: content }), [content]);
59
- const textProps = useMemo(
60
- () => ({
61
- "aria-hidden": true
62
- }),
63
- []
64
- );
71
+ const textProps = useMemo(() => ({ "aria-hidden": true }), []);
65
72
  return {
66
73
  textWrapperRef,
67
74
  textRef,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/useReadMoreTruncate.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import 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';\n\n// offsetHeight + margin helps account for subpixel differences and the button size\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 4 < scrollHeight;\n\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n let left = 0;\n let right = content.length;\n let textEnd = 0;\n\n // Reset text to full before starting\n element.innerText = content;\n\n while (left <= right) {\n const middle = Math.floor((left + right) / 2);\n element.innerText = content.slice(0, middle);\n\n if (overflows(parent)) {\n right = middle - 1;\n } else {\n textEnd = middle;\n left = middle + 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\n const [showButton, setShowButton] = useState(false);\n\n // We need to re-run the effect when the size of the container changes\n const { width, height } = useOnElementResize(textWrapperRef);\n\n useLayoutEffect(() => {\n const textElement = textRef.current;\n const parentElement = textWrapperRef.current;\n if (parentElement && textElement) {\n textElement.innerText = content;\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 * Instead of relying on overflow-based measurements, we calculate the actual pixel width\n * of the text using a canvas and compare it with the visible width of the wrapper.\n *\n * This method is layout-safe, does not force reflow, and works reliably across browsers.\n */\n if (lines === 1) {\n const computed = getComputedStyle(textElement);\n const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n let isTruncated = false;\n if (ctx) {\n ctx.font = font;\n const measuredWidth = ctx.measureText(content).width;\n isTruncated = measuredWidth > parentElement.clientWidth;\n }\n setShowButton(expanded || isTruncated);\n return;\n }\n\n const isOverflowing = overflows(parentElement);\n setShowButton(expanded || isOverflowing);\n if (!expanded && isOverflowing) {\n // we have a strange edge case where when removing the browser cache the text is not\n // truncated correctly, so we need to wait for the next frame\n // to make sure the text is truncated correctly\n // my supposition is that the text is not rendered yet becuase of the font loading\n setTimeout(() => {\n binSearchTextOverflow(textElement, parentElement, content);\n }, 0);\n }\n }\n }, [lines, content, expanded, width, height]);\n\n const srOnlyText = useMemo(() => <ScreenReaderOnly>{content}</ScreenReaderOnly>, [content]);\n\n const textProps = useMemo(\n () => ({\n 'aria-hidden': true,\n }),\n [],\n );\n\n return {\n textWrapperRef,\n textRef,\n showButton,\n expanded,\n setExpanded,\n textProps,\n srOnlyText,\n };\n};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACwFY;AAxFnC,SAAgB,iBAAiB,SAAS,QAAQ,gBAAgB;AAClE,SAAS,0BAA0B;AAEnC,SAAS,wBAAwB;AAGjC,MAAM,YAAY,CAAC,EAAE,cAAc,aAAa,MAC9C,eAAe,IAAI;AAErB,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,SAAS,KAAK,OAAO,OAAO,SAAS,CAAC;AAC5C,YAAQ,YAAY,QAAQ,MAAM,GAAG,MAAM;AAE3C,QAAI,UAAU,MAAM,GAAG;AACrB,cAAQ,SAAS;AAAA,IACnB,OAAO;AACL,gBAAU;AACV,aAAO,SAAS;AAAA,IAClB;AAAA,EACF;AAEA,UAAQ,YAAY,QAAQ,MAAM,GAAG,OAAO;AAC9C;AAEO,MAAM,sBAAsB,CAAC,EAAE,OAAO,QAAQ,MAA4D;AAC/G,QAAM,iBAAiB,OAAwB,IAAI;AACnD,QAAM,UAAU,OAAwB,IAAI;AAE5C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAGlD,QAAM,EAAE,OAAO,OAAO,IAAI,mBAAmB,cAAc;AAE3D,kBAAgB,MAAM;AACpB,UAAM,cAAc,QAAQ;AAC5B,UAAM,gBAAgB,eAAe;AACrC,QAAI,iBAAiB,aAAa;AAChC,kBAAY,YAAY;AAYxB,UAAI,UAAU,GAAG;AACf,cAAM,WAAW,iBAAiB,WAAW;AAC7C,cAAM,OAAO,GAAG,SAAS,UAAU,IAAI,SAAS,QAAQ,IAAI,SAAS,UAAU;AAC/E,cAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,cAAM,MAAM,OAAO,WAAW,IAAI;AAClC,YAAI,cAAc;AAClB,YAAI,KAAK;AACP,cAAI,OAAO;AACX,gBAAM,gBAAgB,IAAI,YAAY,OAAO,EAAE;AAC/C,wBAAc,gBAAgB,cAAc;AAAA,QAC9C;AACA,sBAAc,YAAY,WAAW;AACrC;AAAA,MACF;AAEA,YAAM,gBAAgB,UAAU,aAAa;AAC7C,oBAAc,YAAY,aAAa;AACvC,UAAI,CAAC,YAAY,eAAe;AAK9B,mBAAW,MAAM;AACf,gCAAsB,aAAa,eAAe,OAAO;AAAA,QAC3D,GAAG,CAAC;AAAA,MACN;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,UAAU,OAAO,MAAM,CAAC;AAE5C,QAAM,aAAa,QAAQ,MAAM,oBAAC,oBAAkB,mBAAQ,GAAqB,CAAC,OAAO,CAAC;AAE1F,QAAM,YAAY;AAAA,IAChB,OAAO;AAAA,MACL,eAAe;AAAA,IACjB;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* 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';\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) {\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 binSearchTextOverflow(textEl, wrapperEl, content);\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"],
5
+ "mappings": "AAAA,YAAY,WAAW;ACkHY;AA9GnC,SAAgB,iBAAiB,SAAS,QAAQ,gBAAgB;AAClE,SAAS,0BAA0B;AAEnC,SAAS,wBAAwB;AAGjC,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,iBAAiB,OAAwB,IAAI;AACnD,QAAM,UAAU,OAAwB,IAAI;AAE5C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAGlD,QAAM,EAAE,OAAO,OAAO,IAAI,mBAAmB,cAAc;AAE3D,kBAAgB,MAAM;AACpB,UAAM,SAAS,QAAQ;AACvB,UAAM,YAAY,eAAe;AACjC,QAAI,CAAC,UAAU,CAAC,UAAW;AAG3B,WAAO,YAAY;AAGnB,QAAI,UAAU,GAAG;AACf,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,QAAQ,WAAW,OAAO;AAAA,MAClD;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,aAAa,QAAQ,MAAM,oBAAC,oBAAkB,mBAAQ,GAAqB,CAAC,OAAO,CAAC;AAG1F,QAAM,YAAY,QAAQ,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
  }
@@ -0,0 +1,25 @@
1
+ export declare const DSReadMoreName = "DSReadmore";
2
+ export declare const READ_MORE_SLOTS: {
3
+ readonly ROOT: "root";
4
+ readonly TEXT_CONTENT: "text-content";
5
+ readonly TOOLTIP_WRAPPER: "tooltip-wrapper";
6
+ readonly BUTTON_WRAPPER: "button-wrapper";
7
+ readonly BUTTON: "button";
8
+ };
9
+ export declare const DSReadMoreSlots: {
10
+ readonly ROOT: "root";
11
+ readonly TEXT_CONTENT: "text-content";
12
+ readonly TOOLTIP_WRAPPER: "tooltip-wrapper";
13
+ readonly BUTTON_WRAPPER: "button-wrapper";
14
+ readonly BUTTON: "button";
15
+ };
16
+ export declare const READ_MORE_DATA_TESTID: {
17
+ READ_MORE_BUTTON: string;
18
+ READ_MORE_TOOLTIP_BUTTON: string;
19
+ READ_MORE_TEXT: string;
20
+ };
21
+ export declare const DSReadMoreDataTestIds: {
22
+ READ_MORE_BUTTON: string;
23
+ READ_MORE_TOOLTIP_BUTTON: string;
24
+ READ_MORE_TEXT: string;
25
+ };
@@ -1,4 +1,4 @@
1
1
  export { DSReadMore, DSReadMoreWithSchema } from './DSReadMore.js';
2
- export { DSReadMoreName, DSReadMoreSlots, DSReadMoreDataTestIds } from './DSReadMoreDefinitions.js';
2
+ export { DSReadMoreName, DSReadMoreSlots, READ_MORE_SLOTS, DSReadMoreDataTestIds, READ_MORE_DATA_TESTID, } from './constants/index.js';
3
3
  export type { DSReadMoreT } from './react-desc-prop-types.js';
4
4
  export { useReadMoreTruncate } from './useReadMoreTruncate.js';
@@ -1,5 +1,7 @@
1
- import type { WeakValidationMap } from 'react';
2
- import type { GlobalAttributesT, XstyledProps, DSPropTypesSchema } from '@elliemae/ds-props-helpers';
1
+ /// <reference types="prop-types" />
2
+ import type { GlobalAttributesT, XstyledProps, DSPropTypesSchema, ValidationMap } from '@elliemae/ds-props-helpers';
3
+ import { type TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';
4
+ import { DSReadMoreName, READ_MORE_SLOTS } from './constants/index.js';
3
5
  export declare namespace DSReadMoreT {
4
6
  type PropsT<D, R, O, E> = Partial<D> & R & O & Omit<GlobalAttributesT<E>, keyof D | keyof R | keyof O> & XstyledProps;
5
7
  type InternalPropsT<D, R, O, E> = D & R & O & Omit<GlobalAttributesT<E>, keyof D | keyof R | keyof O> & XstyledProps;
@@ -12,7 +14,7 @@ export declare namespace DSReadMoreT {
12
14
  ellipsis: string;
13
15
  withTooltip: boolean;
14
16
  }
15
- export interface OptionalProps {
17
+ export interface OptionalProps extends TypescriptHelpersT.PropsForGlobalOnSlots<typeof DSReadMoreName, typeof READ_MORE_SLOTS> {
16
18
  }
17
19
  export interface RequiredProps {
18
20
  content: string;
@@ -23,4 +25,4 @@ export declare namespace DSReadMoreT {
23
25
  }
24
26
  export declare const defaultProps: DSReadMoreT.DefaultProps;
25
27
  export declare const DSReadMorePropTypes: DSPropTypesSchema<DSReadMoreT.Props>;
26
- export declare const DSReadMorePropTypesSchema: WeakValidationMap<DSReadMoreT.Props>;
28
+ export declare const DSReadMorePropTypesSchema: ValidationMap<DSReadMoreT.Props>;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare const StyledTextWrapper: import("styled-components").StyledComponent<"span", import("@elliemae/ds-system").Theme, {
2
3
  lines: number;
3
4
  expanded: boolean;
@@ -9,6 +10,6 @@ export declare const StyledTextContent: import("styled-components").StyledCompon
9
10
  export declare const StyledTooltipWrapper: import("styled-components").StyledComponent<"div", import("@elliemae/ds-system").Theme, object & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"div">, never>;
10
11
  export declare const StyledButtonWrapper: import("styled-components").StyledComponent<"span", import("@elliemae/ds-system").Theme, object & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"span">, never>;
11
12
  export declare const StyledButton: import("styled-components").StyledComponent<import("react").ComponentType<import("@elliemae/ds-button-v2").DSButtonV2T.Props>, import("@elliemae/ds-system").Theme, {
12
- withTooltip?: boolean;
13
+ withTooltip?: boolean | undefined;
13
14
  } & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<import("react").ComponentType<import("@elliemae/ds-button-v2").DSButtonV2T.Props>>, never>;
14
15
  export declare const ScreenReaderOnly: import("styled-components").StyledComponent<"span", import("@elliemae/ds-system").Theme, object & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"span">, never>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export const ControlledTestRenderer: import("react").FunctionComponent<import("react").JSX.IntrinsicAttributes>;
@@ -1,2 +1,2 @@
1
1
  import type React from 'react';
2
- export declare const useOnElementResize: <T extends HTMLElement>(targetRef: React.RefObject<T>) => Record<"width" | "height", number>;
2
+ export declare const useOnElementResize: <T extends HTMLElement>(targetRef: React.RefObject<T>) => Record<'width' | 'height', number>;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { DSReadMoreT } from './react-desc-prop-types.js';
3
- export declare const useReadMoreTruncate: ({ lines, content }: Pick<DSReadMoreT.InternalProps, "lines" | "content">) => {
3
+ export declare const useReadMoreTruncate: ({ lines, content }: Pick<DSReadMoreT.InternalProps, 'lines' | 'content'>) => {
4
4
  textWrapperRef: React.RefObject<HTMLSpanElement>;
5
5
  textRef: React.RefObject<HTMLSpanElement>;
6
6
  showButton: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-read-more",
3
- "version": "3.53.0-beta.8",
3
+ "version": "3.53.0-next.10",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Read More",
6
6
  "files": [
@@ -36,16 +36,16 @@
36
36
  "indent": 4
37
37
  },
38
38
  "dependencies": {
39
- "@elliemae/ds-button-v2": "3.53.0-beta.8",
40
- "@elliemae/ds-props-helpers": "3.53.0-beta.8",
41
- "@elliemae/ds-tooltip-v3": "3.53.0-beta.8",
42
- "@elliemae/ds-system": "3.53.0-beta.8"
39
+ "@elliemae/ds-button-v2": "3.53.0-next.10",
40
+ "@elliemae/ds-props-helpers": "3.53.0-next.10",
41
+ "@elliemae/ds-system": "3.53.0-next.10",
42
+ "@elliemae/ds-tooltip-v3": "3.53.0-next.10"
43
43
  },
44
44
  "devDependencies": {
45
- "@elliemae/pui-cli": "9.0.0-next.65",
45
+ "@elliemae/pui-cli": "9.0.0-next.63",
46
46
  "jest": "~29.7.0",
47
47
  "styled-components": "~5.3.9",
48
- "@elliemae/ds-monorepo-devops": "3.53.0-beta.8"
48
+ "@elliemae/ds-monorepo-devops": "3.53.0-next.10"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "lodash-es": "^4.17.21",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "scripts": {
61
61
  "dev": "cross-env NODE_ENV=development node ../../../scripts/build/build.mjs --watch",
62
- "test": "pui-cli test --passWithNoTests --coverage=\"false\"",
62
+ "test": "pui-cli test --passWithNoTests --coverage=\"false\" && [ -n \"$CI\" ] || playwright test -c ./playwright.config.mjs",
63
63
  "lint": "node ../../../scripts/lint.mjs --fix",
64
64
  "lint:strict": "node ../../../scripts/lint-strict.mjs",
65
65
  "dts": "node ../../../scripts/dts.mjs",
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/DSReadMoreDefinitions.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\nexport const DSReadMoreSlots = {\n ROOT: 'root',\n TEXT_CONTENT: 'text-content',\n TOOLTIP_WRAPPER: 'tooltip-wrapper',\n BUTTON_WRAPPER: 'button-wrapper',\n BUTTON: 'button',\n};\n\nexport const DSReadMoreDataTestIds = {\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};\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;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;AAEO,MAAM,wBAAwB;AAAA,EACnC,OAAG,2BAAK,0CAAwB,gBAAgB,eAAe,GAAG,QAAQ;AAAA,EAC1E,kBAAkB;AAAA,EAClB,0BAA0B;AAC5B;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/DSReadMoreDefinitions.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { omit } from 'lodash-es';\nimport { slotObjectToDataTestIds } from '@elliemae/ds-system';\n\nexport const DSReadMoreName = 'DSReadmore';\n\nexport const DSReadMoreSlots = {\n ROOT: 'root',\n TEXT_CONTENT: 'text-content',\n TOOLTIP_WRAPPER: 'tooltip-wrapper',\n BUTTON_WRAPPER: 'button-wrapper',\n BUTTON: 'button',\n};\n\nexport const DSReadMoreDataTestIds = {\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};\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,YAAY;AACrB,SAAS,+BAA+B;AAEjC,MAAM,iBAAiB;AAEvB,MAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,QAAQ;AACV;AAEO,MAAM,wBAAwB;AAAA,EACnC,GAAG,KAAK,wBAAwB,gBAAgB,eAAe,GAAG,QAAQ;AAAA,EAC1E,kBAAkB;AAAA,EAClB,0BAA0B;AAC5B;",
6
- "names": []
7
- }
@@ -1,12 +0,0 @@
1
- export declare const DSReadMoreName = "DSReadmore";
2
- export declare const DSReadMoreSlots: {
3
- ROOT: string;
4
- TEXT_CONTENT: string;
5
- TOOLTIP_WRAPPER: string;
6
- BUTTON_WRAPPER: string;
7
- BUTTON: string;
8
- };
9
- export declare const DSReadMoreDataTestIds: {
10
- READ_MORE_BUTTON: string;
11
- READ_MORE_TOOLTIP_BUTTON: string;
12
- };