@elliemae/ds-read-more 3.16.0 → 3.16.1

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.
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
18
18
  return to;
19
19
  };
20
20
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
25
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
26
  mod
23
27
  ));
@@ -37,7 +41,7 @@ var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
37
41
  var import_ds_system = require("@elliemae/ds-system");
38
42
  var import_ds_tooltip = require("@elliemae/ds-tooltip");
39
43
  var import_ds_shared = require("@elliemae/ds-shared");
40
- var import_MoreLessButton = require("./MoreLessButton");
44
+ var import_MoreLessButton = require("./MoreLessButton.js");
41
45
  const Text = import_ds_system.styled.span`
42
46
  display: -webkit-box;
43
47
  -webkit-line-clamp: ${({ lines, expanded }) => expanded ? "unset" : lines};
@@ -137,14 +141,25 @@ const DSReadMore = (props) => {
137
141
  ] });
138
142
  };
139
143
  const DSReadMoreProps = {
144
+ /** Ammount of lines after you want to display an ellipsis + more/less button */
140
145
  lines: import_ds_props_helpers.PropTypes.number.description("Ammount of lines after you want to display an ellipsis + more/less button").defaultValue(2),
146
+ /** Label which will appear on the 'More' button */
141
147
  more: import_ds_props_helpers.PropTypes.string.description("Label which will appear on the 'More' button").defaultValue("more"),
148
+ /** Label which will appear on the 'Less' button */
142
149
  less: import_ds_props_helpers.PropTypes.string.description("Label which will appear on the 'Less' button").defaultValue("less"),
150
+ /** Function which will execute when the user click the 'More' button */
143
151
  onMore: import_ds_props_helpers.PropTypes.func.description("Function which will execute when the user click the 'More' button"),
152
+ /** Function which will execute when the user click the 'Less' button */
144
153
  onLess: import_ds_props_helpers.PropTypes.func.description("Function which will execute when the user click the 'Less' button"),
154
+ /** The text content you want displayed */
145
155
  content: import_ds_props_helpers.PropTypes.string.description("The text content you want displayed").isRequired,
156
+ /** 'The type of button for more/less button' */
146
157
  buttonType: import_ds_props_helpers.PropTypes.oneOf(["primary", "secondary", "text", "link"]).description("The type for the more/less button").defaultValue("link"),
158
+ /**
159
+ * ['s', 'm', 'l']
160
+ */
147
161
  size: import_ds_props_helpers.PropTypes.oneOf(import_ds_shared.dsBasicSizes).description("Size of the button").defaultValue("s"),
162
+ /** The text you want to appear when truncating */
148
163
  ellipsis: import_ds_props_helpers.PropTypes.string.description("The text you want to appear when truncating").defaultValue("..."),
149
164
  withTooltip: import_ds_props_helpers.PropTypes.bool.description("Whether to show expandable tooltip on ellipsis focus instead of expandable buttons").defaultValue("false")
150
165
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/DSReadMore.tsx", "../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["/* eslint-disable max-lines */\nimport React, { useLayoutEffect, useRef, useState } from 'react';\nimport type { WeakValidationMap } from 'react';\nimport { useOnElementResize } from '@elliemae/ds-utilities';\nimport { describe, PropTypes } from '@elliemae/ds-props-helpers';\nimport { styled } from '@elliemae/ds-system';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip';\nimport { dsBasicSizes } from '@elliemae/ds-shared';\nimport { MoreLessButton } from './MoreLessButton';\nimport type { DSReadMoreT } from './index.d';\n\nconst Text = styled.span<{ lines: number; expanded: boolean }>`\n display: -webkit-box;\n -webkit-line-clamp: ${({ lines, expanded }) => (expanded ? 'unset' : lines)};\n -webkit-box-orient: vertical;\n -webkit-hyphens: auto;\n -moz-hyphens: auto;\n -ms-hyphens: auto;\n hyphens: auto;\n word-break: break-all;\n`;\n\n// offsetHeight + 2 takes into consideration any size of the button\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 2 < scrollHeight;\n\n// Searchs the optimum cut on the text to have the button in the same line\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n const text = element.innerText;\n let left = 1;\n let right = text.length;\n let textEnd = 0;\n while (left <= right) {\n const middle = (left + right) / 2;\n element.innerText = content.slice(0, middle);\n if (overflows(parent)) right = middle - 1;\n else {\n left = middle + 1;\n textEnd = middle;\n }\n }\n element.innerText = content.slice(0, textEnd);\n};\n\nconst noop = () => {};\n\nconst DSReadMore = (props: DSReadMoreT) => {\n const {\n lines = 2,\n more = 'more',\n less = 'less',\n onMore = noop,\n onLess = noop,\n content,\n ellipsis = '...',\n withTooltip = false,\n } = props;\n const textRef = useRef<HTMLSpanElement>(null);\n const textWrapperRef = useRef<HTMLSpanElement>(null);\n const [showButton, setShowButton] = useState(false);\n const [expanded, setExpanded] = 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 setShowButton(expanded || overflows(parentElement));\n if (!expanded && overflows(parentElement)) {\n binSearchTextOverflow(textElement, parentElement, content);\n }\n }\n }, [lines, content, expanded, showButton, withTooltip, more, less, width, height]);\n\n const toggleExpanded = (newExpanded: boolean) => {\n setExpanded(newExpanded);\n if (newExpanded) onMore();\n else onLess();\n };\n\n return (\n <Text ref={textWrapperRef} lines={lines} expanded={expanded}>\n <span ref={textRef} data-testid=\"ds-read_more-text\" aria-label={content}>\n {content}\n </span>\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? less : more}\n ellipsis={ellipsis}\n dataTestId=\"ds-read_more-button\"\n />\n )}\n {withTooltip && showButton && (\n <div\n style={{\n display: 'inline-block',\n }}\n >\n <DSTooltipV3 text={content}>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ariaLabel={content}\n ellipsis={ellipsis}\n withTooltip={withTooltip}\n dataTestId=\"ds-read_more-tooltip-button\"\n />\n </DSTooltipV3>\n </div>\n )}\n </Text>\n );\n};\n\nconst DSReadMoreProps = {\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 type of button for more/less button' */\n buttonType: PropTypes.oneOf(['primary', 'secondary', 'text', 'link'])\n .description('The type for the more/less button')\n .defaultValue('link'),\n /**\n * ['s', 'm', 'l']\n */\n size: PropTypes.oneOf(dsBasicSizes as string[])\n .description('Size of the button')\n .defaultValue('s'),\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} as WeakValidationMap<unknown>;\n\nDSReadMore.propTypes = DSReadMoreProps;\n\nconst DSReadMoreWithSchema = describe(DSReadMore);\n\nDSReadMoreWithSchema.propTypes = DSReadMoreProps;\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;ADoFnB;AAnFJ,mBAAyD;AAEzD,0BAAmC;AACnC,8BAAoC;AACpC,uBAAuB;AACvB,wBAA4B;AAC5B,uBAA6B;AAC7B,4BAA+B;AAG/B,MAAM,OAAO,wBAAO;AAAA;AAAA,wBAEI,CAAC,EAAE,OAAO,SAAS,MAAO,WAAW,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUvE,MAAM,YAAY,CAAC,EAAE,cAAc,aAAa,MAC9C,eAAe,IAAI;AAGrB,MAAM,wBAAwB,CAAC,SAAsB,QAAqB,YAAoB;AAC5F,QAAM,OAAO,QAAQ;AACrB,MAAI,OAAO;AACX,MAAI,QAAQ,KAAK;AACjB,MAAI,UAAU;AACd,SAAO,QAAQ,OAAO;AACpB,UAAM,UAAU,OAAO,SAAS;AAChC,YAAQ,YAAY,QAAQ,MAAM,GAAG,MAAM;AAC3C,QAAI,UAAU,MAAM;AAAG,cAAQ,SAAS;AAAA,SACnC;AACH,aAAO,SAAS;AAChB,gBAAU;AAAA,IACZ;AAAA,EACF;AACA,UAAQ,YAAY,QAAQ,MAAM,GAAG,OAAO;AAC9C;AAEA,MAAM,OAAO,MAAM;AAAC;AAEpB,MAAM,aAAa,CAAC,UAAuB;AACzC,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA,IACA,WAAW;AAAA,IACX,cAAc;AAAA,EAChB,IAAI;AACJ,QAAM,cAAU,qBAAwB,IAAI;AAC5C,QAAM,qBAAiB,qBAAwB,IAAI;AACnD,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAClD,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAG9C,QAAM,EAAE,OAAO,OAAO,QAAI,wCAAmB,cAAc;AAE3D,oCAAgB,MAAM;AACpB,UAAM,cAAc,QAAQ;AAC5B,UAAM,gBAAgB,eAAe;AACrC,QAAI,iBAAiB,aAAa;AAChC,kBAAY,YAAY;AACxB,oBAAc,YAAY,UAAU,aAAa,CAAC;AAClD,UAAI,CAAC,YAAY,UAAU,aAAa,GAAG;AACzC,8BAAsB,aAAa,eAAe,OAAO;AAAA,MAC3D;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,UAAU,YAAY,aAAa,MAAM,MAAM,OAAO,MAAM,CAAC;AAEjF,QAAM,iBAAiB,CAAC,gBAAyB;AAC/C,gBAAY,WAAW;AACvB,QAAI;AAAa,aAAO;AAAA;AACnB,aAAO;AAAA,EACd;AAEA,SACE,6CAAC,QAAK,KAAK,gBAAgB,OAAc,UACvC;AAAA,gDAAC,UAAK,KAAK,SAAS,eAAY,qBAAoB,cAAY,SAC7D,mBACH;AAAA,IACC,cAAc,CAAC,eACd;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAO,WAAW,OAAO;AAAA,QACzB,SAAS,MAAM,eAAe,CAAC,QAAQ;AAAA,QACvC,WAAW,WAAW,OAAO;AAAA,QAC7B;AAAA,QACA,YAAW;AAAA;AAAA,IACb;AAAA,IAED,eAAe,cACd;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,QACX;AAAA,QAEA,sDAAC,iCAAY,MAAM,SACjB;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAM;AAAA,YACN,WAAW;AAAA,YACX;AAAA,YACA;AAAA,YACA,YAAW;AAAA;AAAA,QACb,GACF;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;AAEA,MAAM,kBAAkB;AAAA,EAEtB,OAAO,kCAAU,OACd,YAAY,2EAA2E,EACvF,aAAa,CAAC;AAAA,EAEjB,MAAM,kCAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA,EAEtG,MAAM,kCAAU,OAAO,YAAY,8CAA8C,EAAE,aAAa,MAAM;AAAA,EAEtG,QAAQ,kCAAU,KAAK,YAAY,mEAAmE;AAAA,EAEtG,QAAQ,kCAAU,KAAK,YAAY,mEAAmE;AAAA,EAEtG,SAAS,kCAAU,OAAO,YAAY,qCAAqC,EAAE;AAAA,EAG7E,YAAY,kCAAU,MAAM,CAAC,WAAW,aAAa,QAAQ,MAAM,CAAC,EACjE,YAAY,mCAAmC,EAC/C,aAAa,MAAM;AAAA,EAItB,MAAM,kCAAU,MAAM,6BAAwB,EAC3C,YAAY,oBAAoB,EAChC,aAAa,GAAG;AAAA,EAGnB,UAAU,kCAAU,OAAO,YAAY,6CAA6C,EAAE,aAAa,KAAK;AAAA,EACxG,aAAa,kCAAU,KACpB,YAAY,oFAAoF,EAChG,aAAa,OAAO;AACzB;AAEA,WAAW,YAAY;AAEvB,MAAM,2BAAuB,kCAAS,UAAU;AAEhD,qBAAqB,YAAY;AAGjC,IAAO,qBAAQ;",
4
+ "sourcesContent": ["/* eslint-disable max-lines */\nimport React, { useLayoutEffect, useRef, useState } from 'react';\nimport type { WeakValidationMap } from 'react';\nimport { useOnElementResize } from '@elliemae/ds-utilities';\nimport { describe, PropTypes } from '@elliemae/ds-props-helpers';\nimport { styled } from '@elliemae/ds-system';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip';\nimport { dsBasicSizes } from '@elliemae/ds-shared';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport type { DSReadMoreT } from './index.d';\n\nconst Text = styled.span<{ lines: number; expanded: boolean }>`\n display: -webkit-box;\n -webkit-line-clamp: ${({ lines, expanded }) => (expanded ? 'unset' : lines)};\n -webkit-box-orient: vertical;\n -webkit-hyphens: auto;\n -moz-hyphens: auto;\n -ms-hyphens: auto;\n hyphens: auto;\n word-break: break-all;\n`;\n\n// offsetHeight + 2 takes into consideration any size of the button\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 2 < scrollHeight;\n\n// Searchs the optimum cut on the text to have the button in the same line\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n const text = element.innerText;\n let left = 1;\n let right = text.length;\n let textEnd = 0;\n while (left <= right) {\n const middle = (left + right) / 2;\n element.innerText = content.slice(0, middle);\n if (overflows(parent)) right = middle - 1;\n else {\n left = middle + 1;\n textEnd = middle;\n }\n }\n element.innerText = content.slice(0, textEnd);\n};\n\nconst noop = () => {};\n\nconst DSReadMore = (props: DSReadMoreT) => {\n const {\n lines = 2,\n more = 'more',\n less = 'less',\n onMore = noop,\n onLess = noop,\n content,\n ellipsis = '...',\n withTooltip = false,\n } = props;\n const textRef = useRef<HTMLSpanElement>(null);\n const textWrapperRef = useRef<HTMLSpanElement>(null);\n const [showButton, setShowButton] = useState(false);\n const [expanded, setExpanded] = 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 setShowButton(expanded || overflows(parentElement));\n if (!expanded && overflows(parentElement)) {\n binSearchTextOverflow(textElement, parentElement, content);\n }\n }\n }, [lines, content, expanded, showButton, withTooltip, more, less, width, height]);\n\n const toggleExpanded = (newExpanded: boolean) => {\n setExpanded(newExpanded);\n if (newExpanded) onMore();\n else onLess();\n };\n\n return (\n <Text ref={textWrapperRef} lines={lines} expanded={expanded}>\n <span ref={textRef} data-testid=\"ds-read_more-text\" aria-label={content}>\n {content}\n </span>\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? less : more}\n ellipsis={ellipsis}\n dataTestId=\"ds-read_more-button\"\n />\n )}\n {withTooltip && showButton && (\n <div\n style={{\n display: 'inline-block',\n }}\n >\n <DSTooltipV3 text={content}>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ariaLabel={content}\n ellipsis={ellipsis}\n withTooltip={withTooltip}\n dataTestId=\"ds-read_more-tooltip-button\"\n />\n </DSTooltipV3>\n </div>\n )}\n </Text>\n );\n};\n\nconst DSReadMoreProps = {\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 type of button for more/less button' */\n buttonType: PropTypes.oneOf(['primary', 'secondary', 'text', 'link'])\n .description('The type for the more/less button')\n .defaultValue('link'),\n /**\n * ['s', 'm', 'l']\n */\n size: PropTypes.oneOf(dsBasicSizes as string[])\n .description('Size of the button')\n .defaultValue('s'),\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} as WeakValidationMap<unknown>;\n\nDSReadMore.propTypes = DSReadMoreProps;\n\nconst DSReadMoreWithSchema = describe(DSReadMore);\n\nDSReadMoreWithSchema.propTypes = DSReadMoreProps;\n\nexport { DSReadMore, DSReadMoreWithSchema };\nexport default DSReadMore;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
18
18
  return to;
19
19
  };
20
20
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
25
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
26
  mod
23
27
  ));
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/MoreLessButton.tsx", "../../../../scripts/build/transpile/react-shim.js"],
4
4
  "sourcesContent": ["import React from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport { DSButtonV2 } from '@elliemae/ds-button';\nimport type { MoreLessButtonT } from './index.d';\n\nconst StyledButton = styled(DSButtonV2)<{ withTooltip?: boolean }>`\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`;\nconst MoreLessButton = (props: MoreLessButtonT) => {\n const { expanded, ariaLabel, label, onClick, ellipsis, withTooltip, dataTestId } = props;\n\n return (\n <span>\n {expanded || withTooltip ? ' ' : ellipsis}\n\n <StyledButton\n withTooltip={withTooltip}\n aria-label={ariaLabel}\n buttonType=\"text\"\n onClick={onClick}\n aria-hidden\n size=\"s\"\n data-testid={dataTestId}\n >\n {label}\n </StyledButton>\n </span>\n );\n};\n\nexport { MoreLessButton };\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADwBnB;AAvBJ,uBAAuB;AACvB,uBAA2B;AAG3B,MAAM,mBAAe,yBAAO,2BAAU;AAAA;AAAA,WAE3B,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAQ3E,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM;AAAA;AAAA,uBAEnE,CAAC,EAAE,YAAY,MAAO,cAAc,KAAK;AAAA;AAAA;AAGhE,MAAM,iBAAiB,CAAC,UAA2B;AACjD,QAAM,EAAE,UAAU,WAAW,OAAO,SAAS,UAAU,aAAa,WAAW,IAAI;AAEnF,SACE,6CAAC,UACE;AAAA,gBAAY,cAAc,MAAM;AAAA,IAEjC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,cAAY;AAAA,QACZ,YAAW;AAAA,QACX;AAAA,QACA,eAAW;AAAA,QACX,MAAK;AAAA,QACL,eAAa;AAAA,QAEZ;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;",
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADwBnB;AAvBJ,uBAAuB;AACvB,uBAA2B;AAG3B,MAAM,mBAAe,yBAAO,2BAAU;AAAA;AAAA,WAE3B,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAQhF,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,uBAExE,CAAC,EAAE,YAAY,MAAO,cAAc,KAAK;AAAA;AAAA;AAGhE,MAAM,iBAAiB,CAAC,UAA2B;AACjD,QAAM,EAAE,UAAU,WAAW,OAAO,SAAS,UAAU,aAAa,WAAW,IAAI;AAEnF,SACE,6CAAC,UACE;AAAA,gBAAY,cAAc,MAAM;AAAA,IAEjC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,cAAY;AAAA,QACZ,YAAW;AAAA,QACX;AAAA,QACA,eAAW;AAAA,QACX,MAAK;AAAA,QACL,eAAa;AAAA,QAEZ;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -14,6 +14,10 @@ var __copyProps = (to, from, except, desc) => {
14
14
  return to;
15
15
  };
16
16
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
17
21
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
18
22
  mod
19
23
  ));
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.d.tsx", "../../../../scripts/build/transpile/react-shim.js"],
4
4
  "sourcesContent": ["export interface DSReadMoreT {\n lines: number;\n more: string;\n less: string;\n onMore: () => void;\n onLess: () => void;\n content: string;\n ellipsis: string;\n withTooltip?: boolean;\n}\n\nexport interface MoreLessButtonT {\n expanded: boolean;\n label: string;\n onClick?: () => void;\n ellipsis: string;\n withTooltip?: boolean;\n ariaLabel: string;\n dataTestId: string;\n}\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;ACAA,YAAuB;",
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;ACAA,YAAuB;",
6
6
  "names": []
7
7
  }
package/dist/cjs/index.js CHANGED
@@ -19,6 +19,10 @@ var __copyProps = (to, from, except, desc) => {
19
19
  };
20
20
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
21
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
26
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
27
  mod
24
28
  ));
@@ -29,6 +33,6 @@ __export(src_exports, {
29
33
  });
30
34
  module.exports = __toCommonJS(src_exports);
31
35
  var React = __toESM(require("react"));
32
- __reExport(src_exports, require("./DSReadMore"), module.exports);
33
- var import_DSReadMore = __toESM(require("./DSReadMore"));
36
+ __reExport(src_exports, require("./DSReadMore.js"), module.exports);
37
+ var import_DSReadMore = __toESM(require("./DSReadMore.js"));
34
38
  //# 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 * from './DSReadMore';\nexport { default } from './DSReadMore';\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,wBAAc,yBAAd;AACA,wBAAwB;",
4
+ "sourcesContent": ["export * from './DSReadMore.js';\nexport { default } from './DSReadMore.js';\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,wBAAc,4BAAd;AACA,wBAAwB;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "type": "commonjs",
3
+ "sideEffects": [
4
+ "*.css",
5
+ "*.scss"
6
+ ]
7
+ }
@@ -6,7 +6,7 @@ import { describe, PropTypes } from "@elliemae/ds-props-helpers";
6
6
  import { styled } from "@elliemae/ds-system";
7
7
  import { DSTooltipV3 } from "@elliemae/ds-tooltip";
8
8
  import { dsBasicSizes } from "@elliemae/ds-shared";
9
- import { MoreLessButton } from "./MoreLessButton";
9
+ import { MoreLessButton } from "./MoreLessButton.js";
10
10
  const Text = styled.span`
11
11
  display: -webkit-box;
12
12
  -webkit-line-clamp: ${({ lines, expanded }) => expanded ? "unset" : lines};
@@ -106,14 +106,25 @@ const DSReadMore = (props) => {
106
106
  ] });
107
107
  };
108
108
  const DSReadMoreProps = {
109
+ /** Ammount of lines after you want to display an ellipsis + more/less button */
109
110
  lines: PropTypes.number.description("Ammount of lines after you want to display an ellipsis + more/less button").defaultValue(2),
111
+ /** Label which will appear on the 'More' button */
110
112
  more: PropTypes.string.description("Label which will appear on the 'More' button").defaultValue("more"),
113
+ /** Label which will appear on the 'Less' button */
111
114
  less: PropTypes.string.description("Label which will appear on the 'Less' button").defaultValue("less"),
115
+ /** Function which will execute when the user click the 'More' button */
112
116
  onMore: PropTypes.func.description("Function which will execute when the user click the 'More' button"),
117
+ /** Function which will execute when the user click the 'Less' button */
113
118
  onLess: PropTypes.func.description("Function which will execute when the user click the 'Less' button"),
119
+ /** The text content you want displayed */
114
120
  content: PropTypes.string.description("The text content you want displayed").isRequired,
121
+ /** 'The type of button for more/less button' */
115
122
  buttonType: PropTypes.oneOf(["primary", "secondary", "text", "link"]).description("The type for the more/less button").defaultValue("link"),
123
+ /**
124
+ * ['s', 'm', 'l']
125
+ */
116
126
  size: PropTypes.oneOf(dsBasicSizes).description("Size of the button").defaultValue("s"),
127
+ /** The text you want to appear when truncating */
117
128
  ellipsis: PropTypes.string.description("The text you want to appear when truncating").defaultValue("..."),
118
129
  withTooltip: PropTypes.bool.description("Whether to show expandable tooltip on ellipsis focus instead of expandable buttons").defaultValue("false")
119
130
  };
@@ -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", "/* eslint-disable max-lines */\nimport React, { useLayoutEffect, useRef, useState } from 'react';\nimport type { WeakValidationMap } from 'react';\nimport { useOnElementResize } from '@elliemae/ds-utilities';\nimport { describe, PropTypes } from '@elliemae/ds-props-helpers';\nimport { styled } from '@elliemae/ds-system';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip';\nimport { dsBasicSizes } from '@elliemae/ds-shared';\nimport { MoreLessButton } from './MoreLessButton';\nimport type { DSReadMoreT } from './index.d';\n\nconst Text = styled.span<{ lines: number; expanded: boolean }>`\n display: -webkit-box;\n -webkit-line-clamp: ${({ lines, expanded }) => (expanded ? 'unset' : lines)};\n -webkit-box-orient: vertical;\n -webkit-hyphens: auto;\n -moz-hyphens: auto;\n -ms-hyphens: auto;\n hyphens: auto;\n word-break: break-all;\n`;\n\n// offsetHeight + 2 takes into consideration any size of the button\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 2 < scrollHeight;\n\n// Searchs the optimum cut on the text to have the button in the same line\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n const text = element.innerText;\n let left = 1;\n let right = text.length;\n let textEnd = 0;\n while (left <= right) {\n const middle = (left + right) / 2;\n element.innerText = content.slice(0, middle);\n if (overflows(parent)) right = middle - 1;\n else {\n left = middle + 1;\n textEnd = middle;\n }\n }\n element.innerText = content.slice(0, textEnd);\n};\n\nconst noop = () => {};\n\nconst DSReadMore = (props: DSReadMoreT) => {\n const {\n lines = 2,\n more = 'more',\n less = 'less',\n onMore = noop,\n onLess = noop,\n content,\n ellipsis = '...',\n withTooltip = false,\n } = props;\n const textRef = useRef<HTMLSpanElement>(null);\n const textWrapperRef = useRef<HTMLSpanElement>(null);\n const [showButton, setShowButton] = useState(false);\n const [expanded, setExpanded] = 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 setShowButton(expanded || overflows(parentElement));\n if (!expanded && overflows(parentElement)) {\n binSearchTextOverflow(textElement, parentElement, content);\n }\n }\n }, [lines, content, expanded, showButton, withTooltip, more, less, width, height]);\n\n const toggleExpanded = (newExpanded: boolean) => {\n setExpanded(newExpanded);\n if (newExpanded) onMore();\n else onLess();\n };\n\n return (\n <Text ref={textWrapperRef} lines={lines} expanded={expanded}>\n <span ref={textRef} data-testid=\"ds-read_more-text\" aria-label={content}>\n {content}\n </span>\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? less : more}\n ellipsis={ellipsis}\n dataTestId=\"ds-read_more-button\"\n />\n )}\n {withTooltip && showButton && (\n <div\n style={{\n display: 'inline-block',\n }}\n >\n <DSTooltipV3 text={content}>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ariaLabel={content}\n ellipsis={ellipsis}\n withTooltip={withTooltip}\n dataTestId=\"ds-read_more-tooltip-button\"\n />\n </DSTooltipV3>\n </div>\n )}\n </Text>\n );\n};\n\nconst DSReadMoreProps = {\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 type of button for more/less button' */\n buttonType: PropTypes.oneOf(['primary', 'secondary', 'text', 'link'])\n .description('The type for the more/less button')\n .defaultValue('link'),\n /**\n * ['s', 'm', 'l']\n */\n size: PropTypes.oneOf(dsBasicSizes as string[])\n .description('Size of the button')\n .defaultValue('s'),\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} as WeakValidationMap<unknown>;\n\nDSReadMore.propTypes = DSReadMoreProps;\n\nconst DSReadMoreWithSchema = describe(DSReadMore);\n\nDSReadMoreWithSchema.propTypes = DSReadMoreProps;\n\nexport { DSReadMore, DSReadMoreWithSchema };\nexport default DSReadMore;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport React, { useLayoutEffect, useRef, useState } from 'react';\nimport type { WeakValidationMap } from 'react';\nimport { useOnElementResize } from '@elliemae/ds-utilities';\nimport { describe, PropTypes } from '@elliemae/ds-props-helpers';\nimport { styled } from '@elliemae/ds-system';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip';\nimport { dsBasicSizes } from '@elliemae/ds-shared';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport type { DSReadMoreT } from './index.d';\n\nconst Text = styled.span<{ lines: number; expanded: boolean }>`\n display: -webkit-box;\n -webkit-line-clamp: ${({ lines, expanded }) => (expanded ? 'unset' : lines)};\n -webkit-box-orient: vertical;\n -webkit-hyphens: auto;\n -moz-hyphens: auto;\n -ms-hyphens: auto;\n hyphens: auto;\n word-break: break-all;\n`;\n\n// offsetHeight + 2 takes into consideration any size of the button\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 2 < scrollHeight;\n\n// Searchs the optimum cut on the text to have the button in the same line\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n const text = element.innerText;\n let left = 1;\n let right = text.length;\n let textEnd = 0;\n while (left <= right) {\n const middle = (left + right) / 2;\n element.innerText = content.slice(0, middle);\n if (overflows(parent)) right = middle - 1;\n else {\n left = middle + 1;\n textEnd = middle;\n }\n }\n element.innerText = content.slice(0, textEnd);\n};\n\nconst noop = () => {};\n\nconst DSReadMore = (props: DSReadMoreT) => {\n const {\n lines = 2,\n more = 'more',\n less = 'less',\n onMore = noop,\n onLess = noop,\n content,\n ellipsis = '...',\n withTooltip = false,\n } = props;\n const textRef = useRef<HTMLSpanElement>(null);\n const textWrapperRef = useRef<HTMLSpanElement>(null);\n const [showButton, setShowButton] = useState(false);\n const [expanded, setExpanded] = 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 setShowButton(expanded || overflows(parentElement));\n if (!expanded && overflows(parentElement)) {\n binSearchTextOverflow(textElement, parentElement, content);\n }\n }\n }, [lines, content, expanded, showButton, withTooltip, more, less, width, height]);\n\n const toggleExpanded = (newExpanded: boolean) => {\n setExpanded(newExpanded);\n if (newExpanded) onMore();\n else onLess();\n };\n\n return (\n <Text ref={textWrapperRef} lines={lines} expanded={expanded}>\n <span ref={textRef} data-testid=\"ds-read_more-text\" aria-label={content}>\n {content}\n </span>\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ariaLabel={expanded ? less : more}\n ellipsis={ellipsis}\n dataTestId=\"ds-read_more-button\"\n />\n )}\n {withTooltip && showButton && (\n <div\n style={{\n display: 'inline-block',\n }}\n >\n <DSTooltipV3 text={content}>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ariaLabel={content}\n ellipsis={ellipsis}\n withTooltip={withTooltip}\n dataTestId=\"ds-read_more-tooltip-button\"\n />\n </DSTooltipV3>\n </div>\n )}\n </Text>\n );\n};\n\nconst DSReadMoreProps = {\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 type of button for more/less button' */\n buttonType: PropTypes.oneOf(['primary', 'secondary', 'text', 'link'])\n .description('The type for the more/less button')\n .defaultValue('link'),\n /**\n * ['s', 'm', 'l']\n */\n size: PropTypes.oneOf(dsBasicSizes as string[])\n .description('Size of the button')\n .defaultValue('s'),\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} as WeakValidationMap<unknown>;\n\nDSReadMore.propTypes = DSReadMoreProps;\n\nconst DSReadMoreWithSchema = describe(DSReadMore);\n\nDSReadMoreWithSchema.propTypes = DSReadMoreProps;\n\nexport { DSReadMore, DSReadMoreWithSchema };\nexport default DSReadMore;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../scripts/build/transpile/react-shim.js", "../../src/MoreLessButton.tsx"],
4
4
  "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React from 'react';\nimport { styled } from '@elliemae/ds-system';\nimport { DSButtonV2 } from '@elliemae/ds-button';\nimport type { MoreLessButtonT } from './index.d';\n\nconst StyledButton = styled(DSButtonV2)<{ withTooltip?: boolean }>`\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`;\nconst MoreLessButton = (props: MoreLessButtonT) => {\n const { expanded, ariaLabel, label, onClick, ellipsis, withTooltip, dataTestId } = props;\n\n return (\n <span>\n {expanded || withTooltip ? ' ' : ellipsis}\n\n <StyledButton\n withTooltip={withTooltip}\n aria-label={ariaLabel}\n buttonType=\"text\"\n onClick={onClick}\n aria-hidden\n size=\"s\"\n data-testid={dataTestId}\n >\n {label}\n </StyledButton>\n </span>\n );\n};\n\nexport { MoreLessButton };\n"],
5
- "mappings": "AAAA,YAAY,WAAW;ACwBnB,SAGE,KAHF;AAvBJ,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAG3B,MAAM,eAAe,OAAO,UAAU;AAAA;AAAA,WAE3B,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAQ3E,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM;AAAA;AAAA,uBAEnE,CAAC,EAAE,YAAY,MAAO,cAAc,KAAK;AAAA;AAAA;AAGhE,MAAM,iBAAiB,CAAC,UAA2B;AACjD,QAAM,EAAE,UAAU,WAAW,OAAO,SAAS,UAAU,aAAa,WAAW,IAAI;AAEnF,SACE,qBAAC,UACE;AAAA,gBAAY,cAAc,MAAM;AAAA,IAEjC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,cAAY;AAAA,QACZ,YAAW;AAAA,QACX;AAAA,QACA,eAAW;AAAA,QACX,MAAK;AAAA,QACL,eAAa;AAAA,QAEZ;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;",
5
+ "mappings": "AAAA,YAAY,WAAW;ACwBnB,SAGE,KAHF;AAvBJ,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAG3B,MAAM,eAAe,OAAO,UAAU;AAAA;AAAA,WAE3B,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAQhF,CAAC,EAAE,aAAa,MAAM,MAAO,cAAc,YAAY,GAAG,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,uBAExE,CAAC,EAAE,YAAY,MAAO,cAAc,KAAK;AAAA;AAAA;AAGhE,MAAM,iBAAiB,CAAC,UAA2B;AACjD,QAAM,EAAE,UAAU,WAAW,OAAO,SAAS,UAAU,aAAa,WAAW,IAAI;AAEnF,SACE,qBAAC,UACE;AAAA,gBAAY,cAAc,MAAM;AAAA,IAEjC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,cAAY;AAAA,QACZ,YAAW;AAAA,QACX;AAAA,QACA,eAAW;AAAA,QACX,MAAK;AAAA,QACL,eAAa;AAAA,QAEZ;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;",
6
6
  "names": []
7
7
  }
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- export * from "./DSReadMore";
3
- import { default as default2 } from "./DSReadMore";
2
+ export * from "./DSReadMore.js";
3
+ import { default as default2 } from "./DSReadMore.js";
4
4
  export {
5
5
  default2 as default
6
6
  };
@@ -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 * from './DSReadMore';\nexport { default } from './DSReadMore';\n"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "export * from './DSReadMore.js';\nexport { default } from './DSReadMore.js';\n"],
5
5
  "mappings": "AAAA,YAAY,WAAW;ACAvB,cAAc;AACd,SAAS,WAAAA,gBAAe;",
6
6
  "names": ["default"]
7
7
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "type": "module",
3
+ "sideEffects": [
4
+ "*.css",
5
+ "*.scss"
6
+ ]
7
+ }
@@ -4,6 +4,6 @@ declare const DSReadMore: {
4
4
  (props: DSReadMoreT): JSX.Element;
5
5
  propTypes: React.WeakValidationMap<unknown>;
6
6
  };
7
- declare const DSReadMoreWithSchema: import("@elliemae/ds-props-helpers/dist/types/propTypes/types").DocumentedReactComponent<DSReadMoreT>;
7
+ declare const DSReadMoreWithSchema: import("@elliemae/ds-props-helpers/dist/types/propTypes/types.js").DocumentedReactComponent<DSReadMoreT>;
8
8
  export { DSReadMore, DSReadMoreWithSchema };
9
9
  export default DSReadMore;
@@ -1,2 +1,2 @@
1
- export * from './DSReadMore';
2
- export { default } from './DSReadMore';
1
+ export * from './DSReadMore.js';
2
+ export { default } from './DSReadMore.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-read-more",
3
- "version": "3.16.0",
3
+ "version": "3.16.1",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Read More",
6
6
  "files": [
@@ -43,18 +43,18 @@
43
43
  "indent": 4
44
44
  },
45
45
  "dependencies": {
46
- "@elliemae/ds-button": "3.16.0",
47
- "@elliemae/ds-props-helpers": "3.16.0",
48
- "@elliemae/ds-shared": "3.16.0",
49
- "@elliemae/ds-system": "3.16.0",
50
- "@elliemae/ds-tooltip": "3.16.0",
51
- "@elliemae/ds-utilities": "3.16.0"
46
+ "@elliemae/ds-button": "3.16.1",
47
+ "@elliemae/ds-props-helpers": "3.16.1",
48
+ "@elliemae/ds-shared": "3.16.1",
49
+ "@elliemae/ds-system": "3.16.1",
50
+ "@elliemae/ds-tooltip": "3.16.1",
51
+ "@elliemae/ds-utilities": "3.16.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@testing-library/dom": "~8.19.0",
55
55
  "@testing-library/react": "~12.1.3",
56
56
  "@testing-library/user-event": "~13.5.0",
57
- "styled-components": "~5.3.6"
57
+ "styled-components": "~5.3.9"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "lodash": "~4.17.5",