@elliemae/ds-read-more 3.70.0-next.9 → 3.70.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/DSReadMore.js +2 -1
- package/dist/cjs/DSReadMore.js.map +2 -2
- package/dist/cjs/package.json +1 -4
- package/dist/cjs/react-desc-prop-types.js.map +2 -2
- package/dist/cjs/useReadMoreTruncate.js +1 -1
- package/dist/cjs/useReadMoreTruncate.js.map +2 -2
- package/dist/esm/DSReadMore.js +2 -1
- package/dist/esm/DSReadMore.js.map +2 -2
- package/dist/esm/package.json +1 -4
- package/dist/esm/react-desc-prop-types.js.map +2 -2
- package/dist/esm/useReadMoreTruncate.js +1 -1
- package/dist/esm/useReadMoreTruncate.js.map +2 -2
- package/dist/types/DSReadMore.d.ts +1 -1
- package/dist/types/MoreLessButton.d.ts +2 -1
- package/package.json +13 -13
- package/dist/types/tests/DSReadMore.PUI-14965.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.a11y.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.data-testid.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.default-props.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.events.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.exports.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.get-owner-props.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.keyboard.test.d.ts +0 -1
- package/dist/types/tests/DSReadMore.test.d.ts +0 -1
- package/dist/types/tests/playwright/DSReadMore.ControlledTestRenderer.d.ts +0 -1
- package/dist/types/tests/playwright/DSReadMore.test.playwright.d.ts +0 -1
- package/dist/types/typescript-testing/typescript-read-more-valid.d.ts +0 -1
package/dist/cjs/DSReadMore.js
CHANGED
|
@@ -61,7 +61,8 @@ const DSReadMore = (props) => {
|
|
|
61
61
|
const getOwnerProps = (0, import_react.useCallback)(() => propsWithDefault, [propsWithDefault]);
|
|
62
62
|
const getOwnerPropsArguments = (0, import_react.useCallback)(() => ({ expanded }), [expanded]);
|
|
63
63
|
const readMoreDescribedByText = (0, import_react.useMemo)(() => {
|
|
64
|
-
if (withTooltip)
|
|
64
|
+
if (withTooltip)
|
|
65
|
+
return "shows the full text for sighted users but the full text is already there for screen readers";
|
|
65
66
|
return `${expanded ? "collapse" : "expand"} the full text for sighted users but the full text is already there for screen readers`;
|
|
66
67
|
}, [expanded, withTooltip]);
|
|
67
68
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
@@ -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 { ScreenReaderOnly } from '@elliemae/ds-accessibility';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { useCallback, useMemo } from 'react';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './constants/index.js';\nimport { DSReadMorePropTypesSchema, defaultProps, type DSReadMoreT } from './react-desc-prop-types.js';\nimport { StyledTextContent, StyledTextWrapper, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { IS_SAFARI } from './utils.js';\n\nconst DSReadMore = (props: DSReadMoreT.Props) => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSReadMoreT.InternalProps>(props, defaultProps);\n const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;\n\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const { textWrapperRef, textRef, showButton, expanded, setExpanded } = 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(() => ({ expanded }), [expanded]);\n\n const readMoreDescribedByText = useMemo(() => {\n if (withTooltip)
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["import { ScreenReaderOnly } from '@elliemae/ds-accessibility';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { useCallback, useMemo } from 'react';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './constants/index.js';\nimport { DSReadMorePropTypesSchema, defaultProps, type DSReadMoreT } from './react-desc-prop-types.js';\nimport { StyledTextContent, StyledTextWrapper, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { IS_SAFARI } from './utils.js';\n\nconst DSReadMore = (props: DSReadMoreT.Props) => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSReadMoreT.InternalProps>(props, defaultProps);\n const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;\n\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const { textWrapperRef, textRef, showButton, expanded, setExpanded } = 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(() => ({ expanded }), [expanded]);\n\n const readMoreDescribedByText = useMemo(() => {\n if (withTooltip)\n return 'shows the full text for sighted users but the full text is already there for screen readers';\n return `${expanded ? 'collapse' : 'expand'} the full text for sighted users but the full text is already there for screen readers`;\n }, [expanded, withTooltip]);\n\n return (\n <StyledTextWrapper\n innerRef={textWrapperRef}\n lines={lines}\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n isSafari={IS_SAFARI}\n {...xstyledProps}\n >\n <ScreenReaderOnly>{content}</ScreenReaderOnly>\n {/**\n * Hidden from screen readers unless referenced by `aria-describedby`\n * Ensures the text is only read when associated with a control\n * Prevents it from being focusable or announced independently\n */}\n <ScreenReaderOnly id=\"ds-read_more-text-disclaimer\" aria-hidden>\n {readMoreDescribedByText}\n </ScreenReaderOnly>\n\n <StyledTextContent\n innerRef={textRef}\n data-testid=\"ds-read_more-text\"\n aria-hidden\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n lines={lines}\n expanded={expanded}\n isSafari={IS_SAFARI}\n >\n {content}\n </StyledTextContent>\n\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ellipsis={ellipsis}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n )}\n\n {withTooltip && showButton && (\n <StyledTooltipWrapper getOwnerProps={getOwnerProps} getOwnerPropsArguments={getOwnerPropsArguments}>\n <DSTooltipV3 text={content} wrapWords>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ellipsis={ellipsis}\n withTooltip={withTooltip}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_TOOLTIP_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n </DSTooltipV3>\n </StyledTooltipWrapper>\n )}\n </StyledTextWrapper>\n );\n};\n\nDSReadMore.displayName = DSReadMoreName;\nconst DSReadMoreWithSchema = describe(DSReadMore);\nDSReadMoreWithSchema.propTypes = DSReadMorePropTypesSchema;\n\nexport { DSReadMore, DSReadMoreWithSchema };\nexport default DSReadMore;\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADsCnB;AAtCJ,8BAAiC;AACjC,8BAA2E;AAC3E,2BAA4B;AAC5B,mBAAqC;AACrC,4BAA+B;AAC/B,uBAAsD;AACtD,mCAA0E;AAC1E,oBAA2E;AAC3E,iCAAoC;AACpC,mBAA0B;AAE1B,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,YAAY,QAAI,gDAAoB,gBAAgB;AAE3G,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,EAAE,SAAS,IAAI,CAAC,QAAQ,CAAC;AAE3E,QAAM,8BAA0B,sBAAQ,MAAM;AAC5C,QAAI;AACF,aAAO;AACT,WAAO,GAAG,WAAW,aAAa,QAAQ;AAAA,EAC5C,GAAG,CAAC,UAAU,WAAW,CAAC;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACT,GAAG;AAAA,MAEJ;AAAA,oDAAC,4CAAkB,mBAAQ;AAAA,QAM3B,4CAAC,4CAAiB,IAAG,gCAA+B,eAAW,MAC5D,mCACH;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU;AAAA,YACV,eAAY;AAAA,YACZ,eAAW;AAAA,YACX;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YAET;AAAA;AAAA,QACH;AAAA,QAEC,cAAc,CAAC,eACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAO,WAAW,OAAO;AAAA,YACzB,SAAS,MAAM,eAAe,CAAC,QAAQ;AAAA,YACvC;AAAA,YACA,YAAY,uCAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QAGD,eAAe,cACd,4CAAC,sCAAqB,eAA8B,wBAClD,sDAAC,oCAAY,MAAM,SAAS,WAAS,MACnC;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,YAAY,uCAAsB;AAAA,YAClC;AAAA,YACA;AAAA;AAAA,QACF,GACF,GACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,WAAW,cAAc;AACzB,MAAM,2BAAuB,kCAAS,UAAU;AAChD,qBAAqB,YAAY;AAGjC,IAAO,qBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cjs/package.json
CHANGED
|
@@ -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
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADEvB,8BAMO;AAIP,uBAAuE;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable max-lines */\n\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 extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSReadMoreName,\n typeof READ_MORE_SLOTS\n > {}\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;AA8BhE,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,KAAK;AAAA,EACrB,OAAG,wDAA+B,sCAAqB;AACzD;AAEO,MAAM,4BAA4B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -64,7 +64,7 @@ const checkSafariSingleLine = (textEl, wrapperEl, content) => {
|
|
|
64
64
|
};
|
|
65
65
|
const scheduleBinaryTruncate = (textEl, wrapperEl, content) => {
|
|
66
66
|
const run = () => requestAnimationFrame(() => binSearchTextOverflow(textEl, wrapperEl, content));
|
|
67
|
-
if ("fonts" in document
|
|
67
|
+
if ("fonts" in document) {
|
|
68
68
|
document.fonts.ready.then(run).catch(() => setTimeout(run, 0));
|
|
69
69
|
} else {
|
|
70
70
|
setTimeout(run, 0);
|
|
@@ -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 { useLayoutEffect, useRef, useState } from 'react';\nimport { useOnElementResize } from './useOnElementResize.js';\nimport type { DSReadMoreT } from './react-desc-prop-types.js';\nimport { IS_SAFARI } from './utils.js';\n\n// offsetHeight + margin/buffer to avoid subpixel errors\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 4 < scrollHeight;\n\n/**\n * binSearchTextOverflow slices the content until there's no overflow.\n * It assumes `element` is the <span> node containing the text, and `parent`\n * is the wrapper with the height/clamp applied.\n */\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n let left = 0;\n let right = content.length;\n let textEnd = 0;\n\n 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 right = mid - 1;\n } else {\n textEnd = mid;\n left = mid + 1;\n }\n }\n\n element.innerText = content.slice(0, textEnd);\n};\n\nconst checkSafariSingleLine = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string): boolean => {\n const computed = getComputedStyle(textEl);\n const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) return false;\n ctx.font = font;\n return ctx.measureText(content).width > wrapperEl.clientWidth;\n};\n\nconst scheduleBinaryTruncate = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string) => {\n const run = () => requestAnimationFrame(() => binSearchTextOverflow(textEl, wrapperEl, content));\n if ('fonts' in document
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkD;AAClD,gCAAmC;AAEnC,mBAA0B;AAG1B,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;AAEd,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;AACrB,cAAQ,MAAM;AAAA,IAChB,OAAO;AACL,gBAAU;AACV,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,UAAQ,YAAY,QAAQ,MAAM,GAAG,OAAO;AAC9C;AAEA,MAAM,wBAAwB,CAAC,QAAqB,WAAwB,YAA6B;AACvG,QAAM,WAAW,iBAAiB,MAAM;AACxC,QAAM,OAAO,GAAG,SAAS,UAAU,IAAI,SAAS,QAAQ,IAAI,SAAS,UAAU;AAC/E,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,OAAO;AACX,SAAO,IAAI,YAAY,OAAO,EAAE,QAAQ,UAAU;AACpD;AAEA,MAAM,yBAAyB,CAAC,QAAqB,WAAwB,YAAoB;AAC/F,QAAM,MAAM,MAAM,sBAAsB,MAAM,sBAAsB,QAAQ,WAAW,OAAO,CAAC;AAC/F,MAAI,WAAW,
|
|
4
|
+
"sourcesContent": ["import { useLayoutEffect, useRef, useState } from 'react';\nimport { useOnElementResize } from './useOnElementResize.js';\nimport type { DSReadMoreT } from './react-desc-prop-types.js';\nimport { IS_SAFARI } from './utils.js';\n\n// offsetHeight + margin/buffer to avoid subpixel errors\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 4 < scrollHeight;\n\n/**\n * binSearchTextOverflow slices the content until there's no overflow.\n * It assumes `element` is the <span> node containing the text, and `parent`\n * is the wrapper with the height/clamp applied.\n */\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n let left = 0;\n let right = content.length;\n let textEnd = 0;\n\n 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 right = mid - 1;\n } else {\n textEnd = mid;\n left = mid + 1;\n }\n }\n\n element.innerText = content.slice(0, textEnd);\n};\n\nconst checkSafariSingleLine = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string): boolean => {\n const computed = getComputedStyle(textEl);\n const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) return false;\n ctx.font = font;\n return ctx.measureText(content).width > wrapperEl.clientWidth;\n};\n\nconst scheduleBinaryTruncate = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string) => {\n const run = () => requestAnimationFrame(() => binSearchTextOverflow(textEl, wrapperEl, content));\n if ('fonts' in document) {\n document.fonts.ready.then(run).catch(() => setTimeout(run, 0));\n } else {\n setTimeout(run, 0);\n }\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 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 textEl.innerText = content;\n\n if (lines === 1 && IS_SAFARI) {\n const truncated = checkSafariSingleLine(textEl, wrapperEl, content);\n setShowButton(expanded || truncated);\n return;\n }\n\n const isOverflowing = overflows({ offsetHeight: wrapperEl.offsetHeight, scrollHeight: wrapperEl.scrollHeight });\n setShowButton(expanded || isOverflowing);\n\n if (!expanded && isOverflowing) {\n scheduleBinaryTruncate(textEl, wrapperEl, content);\n }\n }, [lines, content, expanded, width, height]);\n\n return { textWrapperRef, textRef, showButton, expanded, setExpanded };\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAkD;AAClD,gCAAmC;AAEnC,mBAA0B;AAG1B,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;AAEd,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;AACrB,cAAQ,MAAM;AAAA,IAChB,OAAO;AACL,gBAAU;AACV,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,UAAQ,YAAY,QAAQ,MAAM,GAAG,OAAO;AAC9C;AAEA,MAAM,wBAAwB,CAAC,QAAqB,WAAwB,YAA6B;AACvG,QAAM,WAAW,iBAAiB,MAAM;AACxC,QAAM,OAAO,GAAG,SAAS,UAAU,IAAI,SAAS,QAAQ,IAAI,SAAS,UAAU;AAC/E,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,OAAO;AACX,SAAO,IAAI,YAAY,OAAO,EAAE,QAAQ,UAAU;AACpD;AAEA,MAAM,yBAAyB,CAAC,QAAqB,WAAwB,YAAoB;AAC/F,QAAM,MAAM,MAAM,sBAAsB,MAAM,sBAAsB,QAAQ,WAAW,OAAO,CAAC;AAC/F,MAAI,WAAW,UAAU;AACvB,aAAS,MAAM,MAAM,KAAK,GAAG,EAAE,MAAM,MAAM,WAAW,KAAK,CAAC,CAAC;AAAA,EAC/D,OAAO;AACL,eAAW,KAAK,CAAC;AAAA,EACnB;AACF;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;AAElD,QAAM,EAAE,OAAO,OAAO,QAAI,8CAAmB,cAAc;AAE3D,oCAAgB,MAAM;AACpB,UAAM,SAAS,QAAQ;AACvB,UAAM,YAAY,eAAe;AACjC,QAAI,CAAC,UAAU,CAAC,UAAW;AAE3B,WAAO,YAAY;AAEnB,QAAI,UAAU,KAAK,wBAAW;AAC5B,YAAM,YAAY,sBAAsB,QAAQ,WAAW,OAAO;AAClE,oBAAc,YAAY,SAAS;AACnC;AAAA,IACF;AAEA,UAAM,gBAAgB,UAAU,EAAE,cAAc,UAAU,cAAc,cAAc,UAAU,aAAa,CAAC;AAC9G,kBAAc,YAAY,aAAa;AAEvC,QAAI,CAAC,YAAY,eAAe;AAC9B,6BAAuB,QAAQ,WAAW,OAAO;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,UAAU,OAAO,MAAM,CAAC;AAE5C,SAAO,EAAE,gBAAgB,SAAS,YAAY,UAAU,YAAY;AACtE;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/DSReadMore.js
CHANGED
|
@@ -26,7 +26,8 @@ const DSReadMore = (props) => {
|
|
|
26
26
|
const getOwnerProps = useCallback(() => propsWithDefault, [propsWithDefault]);
|
|
27
27
|
const getOwnerPropsArguments = useCallback(() => ({ expanded }), [expanded]);
|
|
28
28
|
const readMoreDescribedByText = useMemo(() => {
|
|
29
|
-
if (withTooltip)
|
|
29
|
+
if (withTooltip)
|
|
30
|
+
return "shows the full text for sighted users but the full text is already there for screen readers";
|
|
30
31
|
return `${expanded ? "collapse" : "expand"} the full text for sighted users but the full text is already there for screen readers`;
|
|
31
32
|
}, [expanded, withTooltip]);
|
|
32
33
|
return /* @__PURE__ */ jsxs(
|
|
@@ -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 { ScreenReaderOnly } from '@elliemae/ds-accessibility';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { useCallback, useMemo } from 'react';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './constants/index.js';\nimport { DSReadMorePropTypesSchema, defaultProps, type DSReadMoreT } from './react-desc-prop-types.js';\nimport { StyledTextContent, StyledTextWrapper, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { IS_SAFARI } from './utils.js';\n\nconst DSReadMore = (props: DSReadMoreT.Props) => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSReadMoreT.InternalProps>(props, defaultProps);\n const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;\n\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const { textWrapperRef, textRef, showButton, expanded, setExpanded } = 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(() => ({ expanded }), [expanded]);\n\n const readMoreDescribedByText = useMemo(() => {\n if (withTooltip)
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { ScreenReaderOnly } from '@elliemae/ds-accessibility';\nimport { describe, useGetXstyledProps, useMemoMergePropsWithDefault } from '@elliemae/ds-props-helpers';\nimport { DSTooltipV3 } from '@elliemae/ds-tooltip-v3';\nimport { useCallback, useMemo } from 'react';\nimport { MoreLessButton } from './MoreLessButton.js';\nimport { DSReadMoreDataTestIds, DSReadMoreName } from './constants/index.js';\nimport { DSReadMorePropTypesSchema, defaultProps, type DSReadMoreT } from './react-desc-prop-types.js';\nimport { StyledTextContent, StyledTextWrapper, StyledTooltipWrapper } from './styled.js';\nimport { useReadMoreTruncate } from './useReadMoreTruncate.js';\nimport { IS_SAFARI } from './utils.js';\n\nconst DSReadMore = (props: DSReadMoreT.Props) => {\n const propsWithDefault = useMemoMergePropsWithDefault<DSReadMoreT.InternalProps>(props, defaultProps);\n const { lines, more, less, content, withTooltip, ellipsis, onMore, onLess } = propsWithDefault;\n\n const xstyledProps = useGetXstyledProps(propsWithDefault);\n\n const { textWrapperRef, textRef, showButton, expanded, setExpanded } = 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(() => ({ expanded }), [expanded]);\n\n const readMoreDescribedByText = useMemo(() => {\n if (withTooltip)\n return 'shows the full text for sighted users but the full text is already there for screen readers';\n return `${expanded ? 'collapse' : 'expand'} the full text for sighted users but the full text is already there for screen readers`;\n }, [expanded, withTooltip]);\n\n return (\n <StyledTextWrapper\n innerRef={textWrapperRef}\n lines={lines}\n expanded={expanded}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n isSafari={IS_SAFARI}\n {...xstyledProps}\n >\n <ScreenReaderOnly>{content}</ScreenReaderOnly>\n {/**\n * Hidden from screen readers unless referenced by `aria-describedby`\n * Ensures the text is only read when associated with a control\n * Prevents it from being focusable or announced independently\n */}\n <ScreenReaderOnly id=\"ds-read_more-text-disclaimer\" aria-hidden>\n {readMoreDescribedByText}\n </ScreenReaderOnly>\n\n <StyledTextContent\n innerRef={textRef}\n data-testid=\"ds-read_more-text\"\n aria-hidden\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n lines={lines}\n expanded={expanded}\n isSafari={IS_SAFARI}\n >\n {content}\n </StyledTextContent>\n\n {showButton && !withTooltip && (\n <MoreLessButton\n expanded={expanded}\n label={expanded ? less : more}\n onClick={() => toggleExpanded(!expanded)}\n ellipsis={ellipsis}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n )}\n\n {withTooltip && showButton && (\n <StyledTooltipWrapper getOwnerProps={getOwnerProps} getOwnerPropsArguments={getOwnerPropsArguments}>\n <DSTooltipV3 text={content} wrapWords>\n <MoreLessButton\n expanded={expanded}\n label=\"...\"\n ellipsis={ellipsis}\n withTooltip={withTooltip}\n dataTestId={DSReadMoreDataTestIds.READ_MORE_TOOLTIP_BUTTON}\n getOwnerProps={getOwnerProps}\n getOwnerPropsArguments={getOwnerPropsArguments}\n />\n </DSTooltipV3>\n </StyledTooltipWrapper>\n )}\n </StyledTextWrapper>\n );\n};\n\nDSReadMore.displayName = DSReadMoreName;\nconst DSReadMoreWithSchema = describe(DSReadMore);\nDSReadMoreWithSchema.propTypes = DSReadMorePropTypesSchema;\n\nexport { DSReadMore, DSReadMoreWithSchema };\nexport default DSReadMore;\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACsCnB,SASE,KATF;AAtCJ,SAAS,wBAAwB;AACjC,SAAS,UAAU,oBAAoB,oCAAoC;AAC3E,SAAS,mBAAmB;AAC5B,SAAS,aAAa,eAAe;AACrC,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB,sBAAsB;AACtD,SAAS,2BAA2B,oBAAsC;AAC1E,SAAS,mBAAmB,mBAAmB,4BAA4B;AAC3E,SAAS,2BAA2B;AACpC,SAAS,iBAAiB;AAE1B,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,YAAY,IAAI,oBAAoB,gBAAgB;AAE3G,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,EAAE,SAAS,IAAI,CAAC,QAAQ,CAAC;AAE3E,QAAM,0BAA0B,QAAQ,MAAM;AAC5C,QAAI;AACF,aAAO;AACT,WAAO,GAAG,WAAW,aAAa,QAAQ;AAAA,EAC5C,GAAG,CAAC,UAAU,WAAW,CAAC;AAE1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACT,GAAG;AAAA,MAEJ;AAAA,4BAAC,oBAAkB,mBAAQ;AAAA,QAM3B,oBAAC,oBAAiB,IAAG,gCAA+B,eAAW,MAC5D,mCACH;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU;AAAA,YACV,eAAY;AAAA,YACZ,eAAW;AAAA,YACX;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YAET;AAAA;AAAA,QACH;AAAA,QAEC,cAAc,CAAC,eACd;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAO,WAAW,OAAO;AAAA,YACzB,SAAS,MAAM,eAAe,CAAC,QAAQ;AAAA,YACvC;AAAA,YACA,YAAY,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;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
|
}
|
package/dist/esm/package.json
CHANGED
|
@@ -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
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;ACEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,uBAAuB,gBAAgB,uBAAuB;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\n\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 extends TypescriptHelpersT.PropsForGlobalOnSlots<\n typeof DSReadMoreName,\n typeof READ_MORE_SLOTS\n > {}\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;AA8BhE,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,KAAK;AAAA,EACrB,GAAG,+BAA+B,qBAAqB;AACzD;AAEO,MAAM,4BAA4B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -31,7 +31,7 @@ const checkSafariSingleLine = (textEl, wrapperEl, content) => {
|
|
|
31
31
|
};
|
|
32
32
|
const scheduleBinaryTruncate = (textEl, wrapperEl, content) => {
|
|
33
33
|
const run = () => requestAnimationFrame(() => binSearchTextOverflow(textEl, wrapperEl, content));
|
|
34
|
-
if ("fonts" in document
|
|
34
|
+
if ("fonts" in document) {
|
|
35
35
|
document.fonts.ready.then(run).catch(() => setTimeout(run, 0));
|
|
36
36
|
} else {
|
|
37
37
|
setTimeout(run, 0);
|
|
@@ -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 { useLayoutEffect, useRef, useState } from 'react';\nimport { useOnElementResize } from './useOnElementResize.js';\nimport type { DSReadMoreT } from './react-desc-prop-types.js';\nimport { IS_SAFARI } from './utils.js';\n\n// offsetHeight + margin/buffer to avoid subpixel errors\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 4 < scrollHeight;\n\n/**\n * binSearchTextOverflow slices the content until there's no overflow.\n * It assumes `element` is the <span> node containing the text, and `parent`\n * is the wrapper with the height/clamp applied.\n */\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n let left = 0;\n let right = content.length;\n let textEnd = 0;\n\n 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 right = mid - 1;\n } else {\n textEnd = mid;\n left = mid + 1;\n }\n }\n\n element.innerText = content.slice(0, textEnd);\n};\n\nconst checkSafariSingleLine = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string): boolean => {\n const computed = getComputedStyle(textEl);\n const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) return false;\n ctx.font = font;\n return ctx.measureText(content).width > wrapperEl.clientWidth;\n};\n\nconst scheduleBinaryTruncate = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string) => {\n const run = () => requestAnimationFrame(() => binSearchTextOverflow(textEl, wrapperEl, content));\n if ('fonts' in document
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,iBAAiB,QAAQ,gBAAgB;AAClD,SAAS,0BAA0B;AAEnC,SAAS,iBAAiB;AAG1B,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;AAEd,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;AACrB,cAAQ,MAAM;AAAA,IAChB,OAAO;AACL,gBAAU;AACV,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,UAAQ,YAAY,QAAQ,MAAM,GAAG,OAAO;AAC9C;AAEA,MAAM,wBAAwB,CAAC,QAAqB,WAAwB,YAA6B;AACvG,QAAM,WAAW,iBAAiB,MAAM;AACxC,QAAM,OAAO,GAAG,SAAS,UAAU,IAAI,SAAS,QAAQ,IAAI,SAAS,UAAU;AAC/E,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,OAAO;AACX,SAAO,IAAI,YAAY,OAAO,EAAE,QAAQ,UAAU;AACpD;AAEA,MAAM,yBAAyB,CAAC,QAAqB,WAAwB,YAAoB;AAC/F,QAAM,MAAM,MAAM,sBAAsB,MAAM,sBAAsB,QAAQ,WAAW,OAAO,CAAC;AAC/F,MAAI,WAAW,
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useLayoutEffect, useRef, useState } from 'react';\nimport { useOnElementResize } from './useOnElementResize.js';\nimport type { DSReadMoreT } from './react-desc-prop-types.js';\nimport { IS_SAFARI } from './utils.js';\n\n// offsetHeight + margin/buffer to avoid subpixel errors\nconst overflows = ({ offsetHeight, scrollHeight }: { offsetHeight: number; scrollHeight: number }) =>\n offsetHeight + 4 < scrollHeight;\n\n/**\n * binSearchTextOverflow slices the content until there's no overflow.\n * It assumes `element` is the <span> node containing the text, and `parent`\n * is the wrapper with the height/clamp applied.\n */\nconst binSearchTextOverflow = (element: HTMLElement, parent: HTMLElement, content: string) => {\n let left = 0;\n let right = content.length;\n let textEnd = 0;\n\n 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 right = mid - 1;\n } else {\n textEnd = mid;\n left = mid + 1;\n }\n }\n\n element.innerText = content.slice(0, textEnd);\n};\n\nconst checkSafariSingleLine = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string): boolean => {\n const computed = getComputedStyle(textEl);\n const font = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d');\n if (!ctx) return false;\n ctx.font = font;\n return ctx.measureText(content).width > wrapperEl.clientWidth;\n};\n\nconst scheduleBinaryTruncate = (textEl: HTMLElement, wrapperEl: HTMLElement, content: string) => {\n const run = () => requestAnimationFrame(() => binSearchTextOverflow(textEl, wrapperEl, content));\n if ('fonts' in document) {\n document.fonts.ready.then(run).catch(() => setTimeout(run, 0));\n } else {\n setTimeout(run, 0);\n }\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 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 textEl.innerText = content;\n\n if (lines === 1 && IS_SAFARI) {\n const truncated = checkSafariSingleLine(textEl, wrapperEl, content);\n setShowButton(expanded || truncated);\n return;\n }\n\n const isOverflowing = overflows({ offsetHeight: wrapperEl.offsetHeight, scrollHeight: wrapperEl.scrollHeight });\n setShowButton(expanded || isOverflowing);\n\n if (!expanded && isOverflowing) {\n scheduleBinaryTruncate(textEl, wrapperEl, content);\n }\n }, [lines, content, expanded, width, height]);\n\n return { textWrapperRef, textRef, showButton, expanded, setExpanded };\n};\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,iBAAiB,QAAQ,gBAAgB;AAClD,SAAS,0BAA0B;AAEnC,SAAS,iBAAiB;AAG1B,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;AAEd,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;AACrB,cAAQ,MAAM;AAAA,IAChB,OAAO;AACL,gBAAU;AACV,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,UAAQ,YAAY,QAAQ,MAAM,GAAG,OAAO;AAC9C;AAEA,MAAM,wBAAwB,CAAC,QAAqB,WAAwB,YAA6B;AACvG,QAAM,WAAW,iBAAiB,MAAM;AACxC,QAAM,OAAO,GAAG,SAAS,UAAU,IAAI,SAAS,QAAQ,IAAI,SAAS,UAAU;AAC/E,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,OAAO;AACX,SAAO,IAAI,YAAY,OAAO,EAAE,QAAQ,UAAU;AACpD;AAEA,MAAM,yBAAyB,CAAC,QAAqB,WAAwB,YAAoB;AAC/F,QAAM,MAAM,MAAM,sBAAsB,MAAM,sBAAsB,QAAQ,WAAW,OAAO,CAAC;AAC/F,MAAI,WAAW,UAAU;AACvB,aAAS,MAAM,MAAM,KAAK,GAAG,EAAE,MAAM,MAAM,WAAW,KAAK,CAAC,CAAC;AAAA,EAC/D,OAAO;AACL,eAAW,KAAK,CAAC;AAAA,EACnB;AACF;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;AAElD,QAAM,EAAE,OAAO,OAAO,IAAI,mBAAmB,cAAc;AAE3D,kBAAgB,MAAM;AACpB,UAAM,SAAS,QAAQ;AACvB,UAAM,YAAY,eAAe;AACjC,QAAI,CAAC,UAAU,CAAC,UAAW;AAE3B,WAAO,YAAY;AAEnB,QAAI,UAAU,KAAK,WAAW;AAC5B,YAAM,YAAY,sBAAsB,QAAQ,WAAW,OAAO;AAClE,oBAAc,YAAY,SAAS;AACnC;AAAA,IACF;AAEA,UAAM,gBAAgB,UAAU,EAAE,cAAc,UAAU,cAAc,cAAc,UAAU,aAAa,CAAC;AAC9G,kBAAc,YAAY,aAAa;AAEvC,QAAI,CAAC,YAAY,eAAe;AAC9B,6BAAuB,QAAQ,WAAW,OAAO;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,UAAU,OAAO,MAAM,CAAC;AAE5C,SAAO,EAAE,gBAAgB,SAAS,YAAY,UAAU,YAAY;AACtE;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type DSReadMoreT } from './react-desc-prop-types.js';
|
|
2
2
|
declare const DSReadMore: {
|
|
3
|
-
(props: DSReadMoreT.Props): import("react
|
|
3
|
+
(props: DSReadMoreT.Props): import("react").JSX.Element;
|
|
4
4
|
displayName: string;
|
|
5
5
|
};
|
|
6
6
|
declare const DSReadMoreWithSchema: import("@elliemae/ds-props-helpers/dist/types/propTypes/types.js").DocumentedReactComponent<DSReadMoreT.Props>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
interface MoreLessButtonProps {
|
|
2
3
|
expanded: boolean;
|
|
3
4
|
label: string;
|
|
@@ -8,5 +9,5 @@ interface MoreLessButtonProps {
|
|
|
8
9
|
getOwnerProps: () => object;
|
|
9
10
|
getOwnerPropsArguments: () => object;
|
|
10
11
|
}
|
|
11
|
-
declare const MoreLessButton: (props: MoreLessButtonProps) =>
|
|
12
|
+
declare const MoreLessButton: (props: MoreLessButtonProps) => React.JSX.Element;
|
|
12
13
|
export { MoreLessButton };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-read-more",
|
|
3
|
-
"version": "3.70.0-
|
|
3
|
+
"version": "3.70.0-rc.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Read More",
|
|
6
6
|
"files": [
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "https://
|
|
25
|
+
"url": "https://github.com/intcx/PLATFORM-UI.dimsum.git"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
28
28
|
"pnpm": ">=9",
|
|
@@ -36,23 +36,23 @@
|
|
|
36
36
|
"indent": 4
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@elliemae/ds-accessibility": "3.70.0-
|
|
40
|
-
"@elliemae/ds-
|
|
41
|
-
"@elliemae/ds-
|
|
42
|
-
"@elliemae/ds-
|
|
43
|
-
"@elliemae/ds-
|
|
39
|
+
"@elliemae/ds-accessibility": "3.70.0-rc.0",
|
|
40
|
+
"@elliemae/ds-props-helpers": "3.70.0-rc.0",
|
|
41
|
+
"@elliemae/ds-system": "3.70.0-rc.0",
|
|
42
|
+
"@elliemae/ds-tooltip-v3": "3.70.0-rc.0",
|
|
43
|
+
"@elliemae/ds-button-v2": "3.70.0-rc.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"jest": "^30.0.0",
|
|
47
|
-
"styled-components": "~5.3.
|
|
48
|
-
"@elliemae/ds-monorepo-devops": "3.70.0-
|
|
49
|
-
"@elliemae/ds-test-utils": "3.70.0-
|
|
47
|
+
"styled-components": "~5.3.11",
|
|
48
|
+
"@elliemae/ds-monorepo-devops": "3.70.0-rc.0",
|
|
49
|
+
"@elliemae/ds-test-utils": "3.70.0-rc.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"lodash-es": "^4.
|
|
52
|
+
"lodash-es": "^4.18.1",
|
|
53
53
|
"react": "^18.3.1",
|
|
54
54
|
"react-dom": "^18.3.1",
|
|
55
|
-
"styled-components": "~5.3.
|
|
55
|
+
"styled-components": "~5.3.11"
|
|
56
56
|
},
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public",
|
|
@@ -67,4 +67,4 @@
|
|
|
67
67
|
"build": "cross-env NODE_ENV=production node ../../../scripts/build/build.mjs",
|
|
68
68
|
"checkDeps": "npx -yes ../../util/ds-codemods check-missing-packages --projectFolderPath=\"./\" --ignorePackagesGlobPattern=\"\" --ignoreFilesGlobPattern=\"**/test-ables/*,**/tests/*\""
|
|
69
69
|
}
|
|
70
|
-
}
|
|
70
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const ControlledTestRenderer: import("react").FunctionComponent<import("react").JSX.IntrinsicAttributes>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|