@chayns-components/core 5.5.24 → 5.5.26
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/AGENTS.md +44 -0
- package/lib/cjs/components/copyable-content/CopyableContent.js +10 -1
- package/lib/cjs/components/copyable-content/CopyableContent.js.map +1 -1
- package/lib/cjs/components/copyable-content/CopyableContent.styles.js +62 -40
- package/lib/cjs/components/copyable-content/CopyableContent.styles.js.map +1 -1
- package/lib/cjs/components/copyable-content/CopyableContent.test.js +38 -4
- package/lib/cjs/components/copyable-content/CopyableContent.test.js.map +1 -1
- package/lib/cjs/components/truncation/Truncation.js +61 -149
- package/lib/cjs/components/truncation/Truncation.js.map +1 -1
- package/lib/cjs/components/truncation/Truncation.styles.js +3 -4
- package/lib/cjs/components/truncation/Truncation.styles.js.map +1 -1
- package/lib/cjs/components/truncation/Truncation.test.js +61 -0
- package/lib/cjs/components/truncation/Truncation.test.js.map +1 -0
- package/lib/esm/components/copyable-content/CopyableContent.js +11 -2
- package/lib/esm/components/copyable-content/CopyableContent.js.map +1 -1
- package/lib/esm/components/copyable-content/CopyableContent.styles.js +61 -39
- package/lib/esm/components/copyable-content/CopyableContent.styles.js.map +1 -1
- package/lib/esm/components/copyable-content/CopyableContent.test.js +38 -4
- package/lib/esm/components/copyable-content/CopyableContent.test.js.map +1 -1
- package/lib/esm/components/truncation/Truncation.js +61 -149
- package/lib/esm/components/truncation/Truncation.js.map +1 -1
- package/lib/esm/components/truncation/Truncation.styles.js +2 -3
- package/lib/esm/components/truncation/Truncation.styles.js.map +1 -1
- package/lib/esm/components/truncation/Truncation.test.js +58 -0
- package/lib/esm/components/truncation/Truncation.test.js.map +1 -0
- package/lib/types/components/copyable-content/CopyableContent.styles.d.ts +16 -6
- package/lib/types/components/truncation/Truncation.d.ts +1 -1
- package/lib/types/components/truncation/Truncation.styles.d.ts +1 -1
- package/package.json +2 -2
- package/lib/cjs/utils/truncation.js +0 -42
- package/lib/cjs/utils/truncation.js.map +0 -1
- package/lib/esm/utils/truncation.js +0 -35
- package/lib/esm/utils/truncation.js.map +0 -1
- package/lib/types/utils/truncation.d.ts +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Truncation.js","names":["React","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","ClampPosition","debounce","truncateElement","StyledMotionTruncationContent","StyledTruncation","StyledTruncationClamp","StyledTruncationClampFocusWrapper","StyledTruncationClampWrapper","StyledTruncationPseudoContent","Textstring","TextstringProvider","ttsToITextString","textStrings","useKeyboardFocusHighlighting","useIsomorphicLayoutEffect","window","Truncation","collapsedHeight","clampPosition","Right","isOpen","moreLabel","lessLabel","onChange","children","shouldEnableKeyboardHighlighting","shouldShowKeyboardHighlighting","internalIsOpen","setInternalIsOpen","showClamp","setShowClamp","newCollapsedHeight","setNewCollapsedHeight","originalHeight","setOriginalHeight","shouldShowCollapsedElement","setShouldShowCollapsedElement","hasSizeChanged","setHasSizeChanged","initialRender","setInitialRender","shouldSkipChangeCheck","setShouldSkipChangeCheck","originalSmallHeight","setOriginalSmallHeight","originalBigHeight","setOriginalBigHeight","parentRef","pseudoChildrenRef","childrenRef","originalChildrenRef","hasCollapsed","isAnimating","hasSizeRecentlyChanged","canResetSizeChanged","handleClampClick","event","current","handleClampKeyDown","key","preventDefault","currentTarget","click","setTimeout","handleAnimationEnd","offsetHeight","firstChild","removeChild","appendChild","style","visibility","resizeObserver","ResizeObserver","entries","observedHeight","contentRect","height","observe","disconnect","ts","components","truncation","internalMoreLabel","createElement","textstring","more","internalLessLabel","less","className","ref","animate","initial","transition","type","duration","onAnimationComplete","onAnimationStart","$position","libraryName","$shouldShowKeyboardHighlighting","onClick","onKeyDown","role","tabIndex"],"sources":["../../../../src/components/truncation/Truncation.tsx"],"sourcesContent":["import React, {\n FC,\n KeyboardEventHandler,\n MouseEvent,\n MouseEventHandler,\n ReactElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { ClampPosition } from '../../types/truncation';\nimport { debounce } from '../../utils/debounce';\nimport { truncateElement } from '../../utils/truncation';\nimport {\n StyledMotionTruncationContent,\n StyledTruncation,\n StyledTruncationClamp,\n StyledTruncationClampFocusWrapper,\n StyledTruncationClampWrapper,\n StyledTruncationPseudoContent,\n} from './Truncation.styles';\nimport { Textstring, TextstringProvider, ttsToITextString } from '@chayns-components/textstring';\nimport textStrings from '../../constants/textStrings';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\n\nexport type TruncationProps = {\n /**\n * The elements that should be expanding or collapsing.\n */\n children: ReactElement;\n /**\n * The position of the clamp.\n */\n clampPosition?: ClampPosition;\n /**\n * The height of the children Element in it`s collapsed state.\n */\n collapsedHeight?: number;\n /**\n * If set to true, the content is exposed.\n */\n isOpen?: boolean;\n /**\n * A text that should be displayed if the content is expanded.\n */\n lessLabel?: string;\n /**\n * A text that should be displayed if the content is collapsed.\n */\n moreLabel?: string;\n /**\n * Function to be executed when the component is expanding or collapsing.\n */\n onChange?: (event: MouseEvent<HTMLAnchorElement>, isOpen: boolean) => void;\n /**\n * Enables keyboard-only focus highlighting.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n};\n\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n\nconst Truncation: FC<TruncationProps> = ({\n collapsedHeight = 150,\n clampPosition = ClampPosition.Right,\n isOpen,\n moreLabel,\n lessLabel,\n onChange,\n children,\n shouldEnableKeyboardHighlighting,\n}) => {\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(\n shouldEnableKeyboardHighlighting,\n );\n\n const [internalIsOpen, setInternalIsOpen] = useState(false);\n const [showClamp, setShowClamp] = useState(true);\n const [newCollapsedHeight, setNewCollapsedHeight] = useState(collapsedHeight);\n const [originalHeight, setOriginalHeight] = useState(0);\n const [shouldShowCollapsedElement, setShouldShowCollapsedElement] = useState(true);\n const [hasSizeChanged, setHasSizeChanged] = useState(false);\n const [initialRender, setInitialRender] = useState(true);\n const [shouldSkipChangeCheck, setShouldSkipChangeCheck] = useState(false);\n\n const [originalSmallHeight, setOriginalSmallHeight] = useState(0);\n const [originalBigHeight, setOriginalBigHeight] = useState(0);\n\n useEffect(() => {\n setInitialRender(false);\n }, []);\n\n const parentRef = useRef<HTMLDivElement>(null);\n const pseudoChildrenRef = useRef<HTMLDivElement>(null);\n const childrenRef = useRef<HTMLDivElement>(null);\n const originalChildrenRef = useRef<HTMLDivElement>(null);\n const hasCollapsed = useRef(false);\n const isAnimating = useRef(false);\n const hasSizeRecentlyChanged = useRef(false);\n const canResetSizeChanged = useRef(true);\n\n useEffect(() => {\n if (typeof isOpen === 'boolean') {\n setInternalIsOpen(isOpen);\n setShowClamp(!isOpen);\n }\n }, [isOpen]);\n\n // Changes the state of the truncation\n const handleClampClick = useCallback<MouseEventHandler<HTMLAnchorElement>>(\n (event) => {\n setInternalIsOpen((current) => {\n if (typeof onChange === 'function') {\n onChange(event, !current);\n }\n\n return !current;\n });\n },\n [onChange],\n );\n\n const handleClampKeyDown = useCallback<KeyboardEventHandler<HTMLAnchorElement>>((event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.currentTarget.click();\n }\n }, []);\n\n useEffect(() => {\n if (children) {\n setShouldSkipChangeCheck(true);\n\n window.setTimeout(() => {\n setShouldSkipChangeCheck(false);\n }, 200);\n }\n }, [children]);\n\n const handleAnimationEnd = useCallback(() => {\n hasCollapsed.current = true;\n isAnimating.current = false;\n\n if (canResetSizeChanged.current) {\n setHasSizeChanged(false);\n canResetSizeChanged.current = false;\n }\n\n window.setTimeout(() => {\n hasSizeRecentlyChanged.current = false;\n }, 10);\n\n setShouldShowCollapsedElement(!internalIsOpen);\n\n window.setTimeout(() => {\n hasCollapsed.current = false;\n }, 30);\n }, [internalIsOpen]);\n\n useEffect(() => {\n if (!pseudoChildrenRef.current) {\n return;\n }\n\n setOriginalHeight(pseudoChildrenRef.current.offsetHeight);\n setOriginalBigHeight(pseudoChildrenRef.current.offsetHeight);\n\n truncateElement(pseudoChildrenRef.current, collapsedHeight);\n\n setNewCollapsedHeight(pseudoChildrenRef.current.offsetHeight);\n setOriginalSmallHeight(pseudoChildrenRef.current.offsetHeight);\n }, [collapsedHeight, pseudoChildrenRef, children]);\n\n // Checks if the clamp should be shown\n useEffect(() => {\n if (\n pseudoChildrenRef.current &&\n (!hasSizeChanged || shouldSkipChangeCheck) &&\n !initialRender\n ) {\n setShowClamp(originalHeight > newCollapsedHeight);\n }\n }, [\n shouldSkipChangeCheck,\n collapsedHeight,\n hasSizeChanged,\n initialRender,\n newCollapsedHeight,\n originalHeight,\n children,\n ]);\n\n useEffect(() => {\n if (childrenRef.current && pseudoChildrenRef.current && originalChildrenRef.current) {\n while (childrenRef.current.firstChild) {\n childrenRef.current.removeChild(childrenRef.current.firstChild);\n }\n\n childrenRef.current.appendChild(\n shouldShowCollapsedElement && !internalIsOpen\n ? pseudoChildrenRef.current\n : originalChildrenRef.current,\n );\n\n parentRef.current?.appendChild(\n shouldShowCollapsedElement && !internalIsOpen\n ? originalChildrenRef.current\n : pseudoChildrenRef.current,\n );\n\n (childrenRef.current.children[0] as HTMLDivElement).style.visibility = 'visible';\n }\n }, [children, internalIsOpen, shouldShowCollapsedElement]);\n\n useIsomorphicLayoutEffect(() => {\n if (originalChildrenRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n if (entries && entries[0]) {\n const observedHeight = entries[0].contentRect.height;\n\n setOriginalHeight(\n observedHeight < originalBigHeight ? originalBigHeight : observedHeight,\n );\n\n if (\n !hasCollapsed.current &&\n !isAnimating.current &&\n !hasSizeRecentlyChanged.current\n ) {\n void debounce(() => {\n canResetSizeChanged.current = true;\n }, 250)();\n\n setHasSizeChanged(true);\n hasSizeRecentlyChanged.current = true;\n }\n }\n });\n\n resizeObserver.observe(originalChildrenRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }\n\n return () => {};\n }, [originalBigHeight, children]);\n\n useIsomorphicLayoutEffect(() => {\n if (pseudoChildrenRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n if (entries && entries[0]) {\n const observedHeight = entries[0].contentRect.height;\n\n setNewCollapsedHeight(\n observedHeight < originalSmallHeight ? originalSmallHeight : observedHeight,\n );\n\n if (\n !hasCollapsed.current &&\n !isAnimating.current &&\n !hasSizeRecentlyChanged.current\n ) {\n void debounce(() => {\n canResetSizeChanged.current = true;\n }, 250)();\n\n setHasSizeChanged(true);\n hasSizeRecentlyChanged.current = true;\n }\n }\n });\n\n resizeObserver.observe(pseudoChildrenRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }\n\n return () => {};\n }, [originalSmallHeight, children]);\n\n const ts = textStrings.components.truncation;\n\n const internalMoreLabel = moreLabel ?? <Textstring textstring={ttsToITextString(ts.more)} />;\n const internalLessLabel = lessLabel ?? <Textstring textstring={ttsToITextString(ts.less)} />;\n\n return useMemo(\n () => (\n <StyledTruncation className=\"beta-chayns-truncation\" ref={parentRef}>\n <StyledTruncationPseudoContent ref={pseudoChildrenRef}>\n {children}\n </StyledTruncationPseudoContent>\n <StyledTruncationPseudoContent ref={originalChildrenRef}>\n {children}\n </StyledTruncationPseudoContent>\n <StyledMotionTruncationContent\n animate={{ height: internalIsOpen ? originalHeight : newCollapsedHeight }}\n initial={false}\n transition={{ type: 'tween', duration: hasSizeChanged ? 0 : 0.2 }}\n onAnimationComplete={handleAnimationEnd}\n onAnimationStart={() => {\n isAnimating.current = true;\n }}\n ref={childrenRef}\n />\n {showClamp && (\n <StyledTruncationClampWrapper $position={clampPosition}>\n <TextstringProvider libraryName=\"@chayns-components-core\">\n <StyledTruncationClampFocusWrapper\n $shouldShowKeyboardHighlighting={shouldShowKeyboardHighlighting}\n >\n <StyledTruncationClamp\n onClick={handleClampClick}\n onKeyDown={handleClampKeyDown}\n role=\"button\"\n tabIndex={0}\n >\n {internalIsOpen ? internalLessLabel : internalMoreLabel}\n </StyledTruncationClamp>\n </StyledTruncationClampFocusWrapper>\n </TextstringProvider>\n </StyledTruncationClampWrapper>\n )}\n </StyledTruncation>\n ),\n [\n children,\n clampPosition,\n handleAnimationEnd,\n handleClampClick,\n handleClampKeyDown,\n hasSizeChanged,\n internalIsOpen,\n lessLabel,\n moreLabel,\n newCollapsedHeight,\n originalHeight,\n shouldShowKeyboardHighlighting,\n showClamp,\n ],\n );\n};\n\nexport default Truncation;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"Truncation.js","names":["Textstring","TextstringProvider","ttsToITextString","React","useCallback","useEffect","useLayoutEffect","useRef","useState","useKeyboardFocusHighlighting","textStrings","ClampPosition","StyledMotionTruncationContent","StyledTruncation","StyledTruncationClamp","StyledTruncationClampFocusWrapper","StyledTruncationClampWrapper","StyledTruncationContent","useIsomorphicLayoutEffect","window","Truncation","collapsedHeight","clampPosition","Right","isOpen","lessLabel","moreLabel","onChange","children","shouldEnableKeyboardHighlighting","shouldShowKeyboardHighlighting","contentRef","pendingObservedHeight","internalIsOpen","setInternalIsOpen","Boolean","contentHeight","setContentHeight","current","frame","updateContentHeight","entries","Math","max","contentRect","height","undefined","requestAnimationFrame","scrollHeight","getBoundingClientRect","resizeObserver","ResizeObserver","mutationObserver","MutationObserver","observe","characterData","childList","subtree","disconnect","cancelAnimationFrame","handleClampClick","event","handleClampKeyDown","key","preventDefault","currentTarget","click","internalMoreLabel","createElement","textstring","components","truncation","more","internalLessLabel","less","hasOverflow","collapsedContentHeight","min","targetHeight","className","animate","initial","transition","type","duration","ref","$position","libraryName","$shouldShowKeyboardHighlighting","onClick","onKeyDown","role","tabIndex"],"sources":["../../../../src/components/truncation/Truncation.tsx"],"sourcesContent":["import { Textstring, TextstringProvider, ttsToITextString } from '@chayns-components/textstring';\nimport React, {\n FC,\n KeyboardEventHandler,\n MouseEvent,\n MouseEventHandler,\n ReactElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting';\nimport textStrings from '../../constants/textStrings';\nimport { ClampPosition } from '../../types/truncation';\nimport {\n StyledMotionTruncationContent,\n StyledTruncation,\n StyledTruncationClamp,\n StyledTruncationClampFocusWrapper,\n StyledTruncationClampWrapper,\n StyledTruncationContent,\n} from './Truncation.styles';\n\nexport type TruncationProps = {\n /**\n * The elements that should be expanding or collapsing.\n */\n children: ReactElement;\n /**\n * The position of the clamp.\n */\n clampPosition?: ClampPosition;\n /**\n * The height of the children element in its collapsed state.\n */\n collapsedHeight?: number;\n /**\n * If set to true, the content is exposed.\n */\n isOpen?: boolean;\n /**\n * A text that should be displayed if the content is expanded.\n */\n lessLabel?: string;\n /**\n * A text that should be displayed if the content is collapsed.\n */\n moreLabel?: string;\n /**\n * Function to be executed when the component is expanding or collapsing.\n */\n onChange?: (event: MouseEvent<HTMLAnchorElement>, isOpen: boolean) => void;\n /**\n * Enables keyboard-only focus highlighting.\n */\n shouldEnableKeyboardHighlighting?: boolean;\n};\n\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n\nconst Truncation: FC<TruncationProps> = ({\n collapsedHeight = 150,\n clampPosition = ClampPosition.Right,\n isOpen,\n lessLabel,\n moreLabel,\n onChange,\n children,\n shouldEnableKeyboardHighlighting,\n}) => {\n const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(\n shouldEnableKeyboardHighlighting,\n );\n const contentRef = useRef<HTMLDivElement>(null);\n const pendingObservedHeight = useRef(0);\n const [internalIsOpen, setInternalIsOpen] = useState(Boolean(isOpen));\n const [contentHeight, setContentHeight] = useState(0);\n\n useEffect(() => {\n if (typeof isOpen === 'boolean') {\n setInternalIsOpen(isOpen);\n }\n }, [isOpen]);\n\n useIsomorphicLayoutEffect(() => {\n if (!contentRef.current) {\n return () => {};\n }\n\n let frame: number | undefined;\n const updateContentHeight = (entries?: ResizeObserverEntry[]) => {\n pendingObservedHeight.current = Math.max(\n pendingObservedHeight.current,\n entries?.[0]?.contentRect.height ?? 0,\n );\n\n if (frame !== undefined) {\n return;\n }\n\n frame = window.requestAnimationFrame(() => {\n frame = undefined;\n\n if (!contentRef.current) {\n return;\n }\n\n setContentHeight(\n Math.max(\n pendingObservedHeight.current,\n contentRef.current.scrollHeight,\n contentRef.current.getBoundingClientRect().height,\n ),\n );\n pendingObservedHeight.current = 0;\n });\n };\n\n const resizeObserver = new ResizeObserver((entries) => updateContentHeight(entries));\n const mutationObserver = new MutationObserver(() => updateContentHeight());\n\n resizeObserver.observe(contentRef.current);\n mutationObserver.observe(contentRef.current, {\n characterData: true,\n childList: true,\n subtree: true,\n });\n updateContentHeight();\n\n return () => {\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n\n if (frame !== undefined) {\n window.cancelAnimationFrame(frame);\n }\n };\n }, [children]);\n\n const handleClampClick = useCallback<MouseEventHandler<HTMLAnchorElement>>(\n (event) => {\n setInternalIsOpen((current) => {\n onChange?.(event, !current);\n return !current;\n });\n },\n [onChange],\n );\n\n const handleClampKeyDown = useCallback<KeyboardEventHandler<HTMLAnchorElement>>((event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.currentTarget.click();\n }\n }, []);\n\n const internalMoreLabel = moreLabel ?? (\n <Textstring textstring={ttsToITextString(textStrings.components.truncation.more)} />\n );\n const internalLessLabel = lessLabel ?? (\n <Textstring textstring={ttsToITextString(textStrings.components.truncation.less)} />\n );\n const hasOverflow = contentHeight > collapsedHeight;\n const collapsedContentHeight = Math.min(contentHeight || collapsedHeight, collapsedHeight);\n const targetHeight = internalIsOpen ? contentHeight || collapsedHeight : collapsedContentHeight;\n\n return (\n <StyledTruncation className=\"beta-chayns-truncation\">\n <StyledMotionTruncationContent\n animate={{ height: targetHeight }}\n initial={false}\n transition={{ type: 'tween', duration: 0.2 }}\n >\n <StyledTruncationContent ref={contentRef}>{children}</StyledTruncationContent>\n </StyledMotionTruncationContent>\n {hasOverflow && (\n <StyledTruncationClampWrapper $position={clampPosition}>\n <TextstringProvider libraryName=\"@chayns-components-core\">\n <StyledTruncationClampFocusWrapper\n $shouldShowKeyboardHighlighting={shouldShowKeyboardHighlighting}\n >\n <StyledTruncationClamp\n onClick={handleClampClick}\n onKeyDown={handleClampKeyDown}\n role=\"button\"\n tabIndex={0}\n >\n {internalIsOpen ? internalLessLabel : internalMoreLabel}\n </StyledTruncationClamp>\n </StyledTruncationClampFocusWrapper>\n </TextstringProvider>\n </StyledTruncationClampWrapper>\n )}\n </StyledTruncation>\n );\n};\n\nexport default Truncation;\n"],"mappings":"AAAA,SAASA,UAAU,EAAEC,kBAAkB,EAAEC,gBAAgB,QAAQ,+BAA+B;AAChG,OAAOC,KAAK,IAMRC,WAAW,EACXC,SAAS,EACTC,eAAe,EACfC,MAAM,EACNC,QAAQ,QACL,OAAO;AACd,SAASC,4BAA4B,QAAQ,0CAA0C;AACvF,OAAOC,WAAW,MAAM,6BAA6B;AACrD,SAASC,aAAa,QAAQ,wBAAwB;AACtD,SACIC,6BAA6B,EAC7BC,gBAAgB,EAChBC,qBAAqB,EACrBC,iCAAiC,EACjCC,4BAA4B,EAC5BC,uBAAuB,QACpB,qBAAqB;AAqC5B,MAAMC,yBAAyB,GAAG,OAAOC,MAAM,KAAK,WAAW,GAAGb,eAAe,GAAGD,SAAS;AAE7F,MAAMe,UAA+B,GAAGA,CAAC;EACrCC,eAAe,GAAG,GAAG;EACrBC,aAAa,GAAGX,aAAa,CAACY,KAAK;EACnCC,MAAM;EACNC,SAAS;EACTC,SAAS;EACTC,QAAQ;EACRC,QAAQ;EACRC;AACJ,CAAC,KAAK;EACF,MAAMC,8BAA8B,GAAGrB,4BAA4B,CAC/DoB,gCACJ,CAAC;EACD,MAAME,UAAU,GAAGxB,MAAM,CAAiB,IAAI,CAAC;EAC/C,MAAMyB,qBAAqB,GAAGzB,MAAM,CAAC,CAAC,CAAC;EACvC,MAAM,CAAC0B,cAAc,EAAEC,iBAAiB,CAAC,GAAG1B,QAAQ,CAAC2B,OAAO,CAACX,MAAM,CAAC,CAAC;EACrE,MAAM,CAACY,aAAa,EAAEC,gBAAgB,CAAC,GAAG7B,QAAQ,CAAC,CAAC,CAAC;EAErDH,SAAS,CAAC,MAAM;IACZ,IAAI,OAAOmB,MAAM,KAAK,SAAS,EAAE;MAC7BU,iBAAiB,CAACV,MAAM,CAAC;IAC7B;EACJ,CAAC,EAAE,CAACA,MAAM,CAAC,CAAC;EAEZN,yBAAyB,CAAC,MAAM;IAC5B,IAAI,CAACa,UAAU,CAACO,OAAO,EAAE;MACrB,OAAO,MAAM,CAAC,CAAC;IACnB;IAEA,IAAIC,KAAyB;IAC7B,MAAMC,mBAAmB,GAAIC,OAA+B,IAAK;MAC7DT,qBAAqB,CAACM,OAAO,GAAGI,IAAI,CAACC,GAAG,CACpCX,qBAAqB,CAACM,OAAO,EAC7BG,OAAO,GAAG,CAAC,CAAC,EAAEG,WAAW,CAACC,MAAM,IAAI,CACxC,CAAC;MAED,IAAIN,KAAK,KAAKO,SAAS,EAAE;QACrB;MACJ;MAEAP,KAAK,GAAGpB,MAAM,CAAC4B,qBAAqB,CAAC,MAAM;QACvCR,KAAK,GAAGO,SAAS;QAEjB,IAAI,CAACf,UAAU,CAACO,OAAO,EAAE;UACrB;QACJ;QAEAD,gBAAgB,CACZK,IAAI,CAACC,GAAG,CACJX,qBAAqB,CAACM,OAAO,EAC7BP,UAAU,CAACO,OAAO,CAACU,YAAY,EAC/BjB,UAAU,CAACO,OAAO,CAACW,qBAAqB,CAAC,CAAC,CAACJ,MAC/C,CACJ,CAAC;QACDb,qBAAqB,CAACM,OAAO,GAAG,CAAC;MACrC,CAAC,CAAC;IACN,CAAC;IAED,MAAMY,cAAc,GAAG,IAAIC,cAAc,CAAEV,OAAO,IAAKD,mBAAmB,CAACC,OAAO,CAAC,CAAC;IACpF,MAAMW,gBAAgB,GAAG,IAAIC,gBAAgB,CAAC,MAAMb,mBAAmB,CAAC,CAAC,CAAC;IAE1EU,cAAc,CAACI,OAAO,CAACvB,UAAU,CAACO,OAAO,CAAC;IAC1Cc,gBAAgB,CAACE,OAAO,CAACvB,UAAU,CAACO,OAAO,EAAE;MACzCiB,aAAa,EAAE,IAAI;MACnBC,SAAS,EAAE,IAAI;MACfC,OAAO,EAAE;IACb,CAAC,CAAC;IACFjB,mBAAmB,CAAC,CAAC;IAErB,OAAO,MAAM;MACTU,cAAc,CAACQ,UAAU,CAAC,CAAC;MAC3BN,gBAAgB,CAACM,UAAU,CAAC,CAAC;MAE7B,IAAInB,KAAK,KAAKO,SAAS,EAAE;QACrB3B,MAAM,CAACwC,oBAAoB,CAACpB,KAAK,CAAC;MACtC;IACJ,CAAC;EACL,CAAC,EAAE,CAACX,QAAQ,CAAC,CAAC;EAEd,MAAMgC,gBAAgB,GAAGxD,WAAW,CAC/ByD,KAAK,IAAK;IACP3B,iBAAiB,CAAEI,OAAO,IAAK;MAC3BX,QAAQ,GAAGkC,KAAK,EAAE,CAACvB,OAAO,CAAC;MAC3B,OAAO,CAACA,OAAO;IACnB,CAAC,CAAC;EACN,CAAC,EACD,CAACX,QAAQ,CACb,CAAC;EAED,MAAMmC,kBAAkB,GAAG1D,WAAW,CAA2CyD,KAAK,IAAK;IACvF,IAAIA,KAAK,CAACE,GAAG,KAAK,OAAO,IAAIF,KAAK,CAACE,GAAG,KAAK,GAAG,EAAE;MAC5CF,KAAK,CAACG,cAAc,CAAC,CAAC;MACtBH,KAAK,CAACI,aAAa,CAACC,KAAK,CAAC,CAAC;IAC/B;EACJ,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMC,iBAAiB,GAAGzC,SAAS,iBAC/BvB,KAAA,CAAAiE,aAAA,CAACpE,UAAU;IAACqE,UAAU,EAAEnE,gBAAgB,CAACQ,WAAW,CAAC4D,UAAU,CAACC,UAAU,CAACC,IAAI;EAAE,CAAE,CACtF;EACD,MAAMC,iBAAiB,GAAGhD,SAAS,iBAC/BtB,KAAA,CAAAiE,aAAA,CAACpE,UAAU;IAACqE,UAAU,EAAEnE,gBAAgB,CAACQ,WAAW,CAAC4D,UAAU,CAACC,UAAU,CAACG,IAAI;EAAE,CAAE,CACtF;EACD,MAAMC,WAAW,GAAGvC,aAAa,GAAGf,eAAe;EACnD,MAAMuD,sBAAsB,GAAGlC,IAAI,CAACmC,GAAG,CAACzC,aAAa,IAAIf,eAAe,EAAEA,eAAe,CAAC;EAC1F,MAAMyD,YAAY,GAAG7C,cAAc,GAAGG,aAAa,IAAIf,eAAe,GAAGuD,sBAAsB;EAE/F,oBACIzE,KAAA,CAAAiE,aAAA,CAACvD,gBAAgB;IAACkE,SAAS,EAAC;EAAwB,gBAChD5E,KAAA,CAAAiE,aAAA,CAACxD,6BAA6B;IAC1BoE,OAAO,EAAE;MAAEnC,MAAM,EAAEiC;IAAa,CAAE;IAClCG,OAAO,EAAE,KAAM;IACfC,UAAU,EAAE;MAAEC,IAAI,EAAE,OAAO;MAAEC,QAAQ,EAAE;IAAI;EAAE,gBAE7CjF,KAAA,CAAAiE,aAAA,CAACnD,uBAAuB;IAACoE,GAAG,EAAEtD;EAAW,GAAEH,QAAkC,CAClD,CAAC,EAC/B+C,WAAW,iBACRxE,KAAA,CAAAiE,aAAA,CAACpD,4BAA4B;IAACsE,SAAS,EAAEhE;EAAc,gBACnDnB,KAAA,CAAAiE,aAAA,CAACnE,kBAAkB;IAACsF,WAAW,EAAC;EAAyB,gBACrDpF,KAAA,CAAAiE,aAAA,CAACrD,iCAAiC;IAC9ByE,+BAA+B,EAAE1D;EAA+B,gBAEhE3B,KAAA,CAAAiE,aAAA,CAACtD,qBAAqB;IAClB2E,OAAO,EAAE7B,gBAAiB;IAC1B8B,SAAS,EAAE5B,kBAAmB;IAC9B6B,IAAI,EAAC,QAAQ;IACbC,QAAQ,EAAE;EAAE,GAEX3D,cAAc,GAAGwC,iBAAiB,GAAGN,iBACnB,CACQ,CACnB,CACM,CAEpB,CAAC;AAE3B,CAAC;AAED,eAAe/C,UAAU","ignoreList":[]}
|
|
@@ -12,9 +12,8 @@ export const StyledMotionTruncationContent = styled(motion.div)`
|
|
|
12
12
|
overflow: hidden;
|
|
13
13
|
position: relative;
|
|
14
14
|
`;
|
|
15
|
-
export const
|
|
16
|
-
|
|
17
|
-
position: absolute;
|
|
15
|
+
export const StyledTruncationContent = styled.div`
|
|
16
|
+
min-width: 0;
|
|
18
17
|
width: 100%;
|
|
19
18
|
`;
|
|
20
19
|
export const StyledTruncationClampWrapper = styled.div`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Truncation.styles.js","names":["motion","styled","css","ClampPosition","keyboardFocusHighlightingRingCss","StyledTruncation","div","StyledMotionTruncationContent","
|
|
1
|
+
{"version":3,"file":"Truncation.styles.js","names":["motion","styled","css","ClampPosition","keyboardFocusHighlightingRingCss","StyledTruncation","div","StyledMotionTruncationContent","StyledTruncationContent","StyledTruncationClampWrapper","$position","Left","Middle","StyledTruncationClampFocusWrapper","$shouldShowKeyboardHighlighting","StyledTruncationClamp","a"],"sources":["../../../../src/components/truncation/Truncation.styles.ts"],"sourcesContent":["import { motion } from 'motion/react';\nimport styled, { css } from 'styled-components';\nimport { ClampPosition } from '../../types/truncation';\nimport type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport { keyboardFocusHighlightingRingCss } from '../../utils/keyboardFocusHighlighting.styles';\n\nexport const StyledTruncation = styled.div`\n position: relative;\n overflow: hidden;\n`;\n\n// Fix framer-motion bug\nexport const StyledMotionTruncationContent = styled(motion.div)`\n overflow: hidden;\n position: relative;\n`;\n\nexport const StyledTruncationContent = styled.div`\n min-width: 0;\n width: 100%;\n`;\n\ntype StyledTruncationClampWrapperProps = WithTheme<{ $position: ClampPosition }>;\n\nexport const StyledTruncationClampWrapper = styled.div<StyledTruncationClampWrapperProps>`\n display: flex;\n\n ${({ $position }) => {\n switch ($position) {\n case ClampPosition.Left:\n return css`\n justify-content: left;\n `;\n case ClampPosition.Middle:\n return css`\n justify-content: center;\n `;\n default:\n return css`\n justify-content: right;\n `;\n }\n }}\n`;\n\ntype StyledTruncationClampProps = {\n $shouldShowKeyboardHighlighting: boolean;\n};\n\nexport const StyledTruncationClampFocusWrapper = styled.div<StyledTruncationClampProps>`\n display: inline-block;\n border-radius: 3px;\n\n ${({ $shouldShowKeyboardHighlighting }) =>\n $shouldShowKeyboardHighlighting &&\n css`\n &:focus-within {\n transition: none;\n ${keyboardFocusHighlightingRingCss};\n color: inherit;\n }\n `}\n`;\n\nexport const StyledTruncationClamp = styled.a`\n cursor: pointer;\n z-index: 2;\n display: inline-block;\n line-height: 1.2;\n`;\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,cAAc;AACrC,OAAOC,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAC/C,SAASC,aAAa,QAAQ,wBAAwB;AAEtD,SAASC,gCAAgC,QAAQ,8CAA8C;AAE/F,OAAO,MAAMC,gBAAgB,GAAGJ,MAAM,CAACK,GAAG;AAC1C;AACA;AACA,CAAC;;AAED;AACA,OAAO,MAAMC,6BAA6B,GAAGN,MAAM,CAACD,MAAM,CAACM,GAAG,CAAC;AAC/D;AACA;AACA,CAAC;AAED,OAAO,MAAME,uBAAuB,GAAGP,MAAM,CAACK,GAAG;AACjD;AACA;AACA,CAAC;AAID,OAAO,MAAMG,4BAA4B,GAAGR,MAAM,CAACK,GAAsC;AACzF;AACA;AACA,MAAM,CAAC;EAAEI;AAAU,CAAC,KAAK;EACjB,QAAQA,SAAS;IACb,KAAKP,aAAa,CAACQ,IAAI;MACnB,OAAOT,GAAG;AAC1B;AACA,iBAAiB;IACL,KAAKC,aAAa,CAACS,MAAM;MACrB,OAAOV,GAAG;AAC1B;AACA,iBAAiB;IACL;MACI,OAAOA,GAAG;AAC1B;AACA,iBAAiB;EACT;AACJ,CAAC;AACL,CAAC;AAMD,OAAO,MAAMW,iCAAiC,GAAGZ,MAAM,CAACK,GAA+B;AACvF;AACA;AACA;AACA,MAAM,CAAC;EAAEQ;AAAgC,CAAC,KAClCA,+BAA+B,IAC/BZ,GAAG;AACX;AACA;AACA,kBAAkBE,gCAAgC;AAClD;AACA;AACA,SAAS;AACT,CAAC;AAED,OAAO,MAAMW,qBAAqB,GAAGd,MAAM,CAACe,CAAC;AAC7C;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import Truncation from './Truncation';
|
|
5
|
+
vi.mock('@chayns-components/textstring', () => ({
|
|
6
|
+
Textstring: () => 'Mehr anzeigen',
|
|
7
|
+
TextstringProvider: ({
|
|
8
|
+
children
|
|
9
|
+
}) => children,
|
|
10
|
+
ttsToITextString: vi.fn()
|
|
11
|
+
}));
|
|
12
|
+
const resizeObserverCallbacks = [];
|
|
13
|
+
class ResizeObserverMock {
|
|
14
|
+
constructor(callback) {
|
|
15
|
+
resizeObserverCallbacks.push(callback);
|
|
16
|
+
}
|
|
17
|
+
disconnect() {}
|
|
18
|
+
observe() {}
|
|
19
|
+
unobserve() {}
|
|
20
|
+
}
|
|
21
|
+
vi.stubGlobal('ResizeObserver', ResizeObserverMock);
|
|
22
|
+
const triggerResize = height => {
|
|
23
|
+
resizeObserverCallbacks.forEach(callback => {
|
|
24
|
+
callback([{
|
|
25
|
+
contentRect: {
|
|
26
|
+
height
|
|
27
|
+
}
|
|
28
|
+
}]);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
resizeObserverCallbacks.length = 0;
|
|
33
|
+
});
|
|
34
|
+
describe('Truncation', () => {
|
|
35
|
+
it('shows the more action when content exceeds the collapsed height', async () => {
|
|
36
|
+
render(/*#__PURE__*/React.createElement(Truncation, {
|
|
37
|
+
collapsedHeight: 100
|
|
38
|
+
}, /*#__PURE__*/React.createElement("div", null, "Long content")));
|
|
39
|
+
triggerResize(240);
|
|
40
|
+
await waitFor(() => {
|
|
41
|
+
expect(screen.getByRole('button', {
|
|
42
|
+
name: 'Mehr anzeigen'
|
|
43
|
+
})).toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
it('keeps short content expanded without a more action', async () => {
|
|
47
|
+
render(/*#__PURE__*/React.createElement(Truncation, {
|
|
48
|
+
collapsedHeight: 100
|
|
49
|
+
}, /*#__PURE__*/React.createElement("div", null, "Short content")));
|
|
50
|
+
triggerResize(64);
|
|
51
|
+
await waitFor(() => {
|
|
52
|
+
expect(screen.queryByRole('button', {
|
|
53
|
+
name: 'Mehr anzeigen'
|
|
54
|
+
})).not.toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=Truncation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Truncation.test.js","names":["render","screen","waitFor","React","afterEach","describe","expect","it","vi","Truncation","mock","Textstring","TextstringProvider","children","ttsToITextString","fn","resizeObserverCallbacks","ResizeObserverMock","constructor","callback","push","disconnect","observe","unobserve","stubGlobal","triggerResize","height","forEach","contentRect","length","createElement","collapsedHeight","getByRole","name","toBeInTheDocument","queryByRole","not"],"sources":["../../../../src/components/truncation/Truncation.test.tsx"],"sourcesContent":["import { render, screen, waitFor } from '@testing-library/react';\nimport React from 'react';\nimport { afterEach, describe, expect, it, vi } from 'vitest';\nimport Truncation from './Truncation';\n\nvi.mock('@chayns-components/textstring', () => ({\n Textstring: () => 'Mehr anzeigen',\n TextstringProvider: ({ children }: { children: React.ReactNode }) => children,\n ttsToITextString: vi.fn(),\n}));\n\ntype ResizeObserverCallback = (entries: ResizeObserverEntry[]) => void;\n\nconst resizeObserverCallbacks: ResizeObserverCallback[] = [];\n\nclass ResizeObserverMock {\n constructor(callback: ResizeObserverCallback) {\n resizeObserverCallbacks.push(callback);\n }\n\n disconnect() {}\n\n observe() {}\n\n unobserve() {}\n}\n\nvi.stubGlobal('ResizeObserver', ResizeObserverMock);\n\nconst triggerResize = (height: number) => {\n resizeObserverCallbacks.forEach((callback) => {\n callback([\n {\n contentRect: { height } as DOMRectReadOnly,\n } as ResizeObserverEntry,\n ]);\n });\n};\n\nafterEach(() => {\n resizeObserverCallbacks.length = 0;\n});\n\ndescribe('Truncation', () => {\n it('shows the more action when content exceeds the collapsed height', async () => {\n render(\n <Truncation collapsedHeight={100}>\n <div>Long content</div>\n </Truncation>,\n );\n\n triggerResize(240);\n\n await waitFor(() => {\n expect(screen.getByRole('button', { name: 'Mehr anzeigen' })).toBeInTheDocument();\n });\n });\n\n it('keeps short content expanded without a more action', async () => {\n render(\n <Truncation collapsedHeight={100}>\n <div>Short content</div>\n </Truncation>,\n );\n\n triggerResize(64);\n\n await waitFor(() => {\n expect(screen.queryByRole('button', { name: 'Mehr anzeigen' })).not.toBeInTheDocument();\n });\n });\n});\n"],"mappings":"AAAA,SAASA,MAAM,EAAEC,MAAM,EAAEC,OAAO,QAAQ,wBAAwB;AAChE,OAAOC,KAAK,MAAM,OAAO;AACzB,SAASC,SAAS,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,QAAQ;AAC5D,OAAOC,UAAU,MAAM,cAAc;AAErCD,EAAE,CAACE,IAAI,CAAC,+BAA+B,EAAE,OAAO;EAC5CC,UAAU,EAAEA,CAAA,KAAM,eAAe;EACjCC,kBAAkB,EAAEA,CAAC;IAAEC;EAAwC,CAAC,KAAKA,QAAQ;EAC7EC,gBAAgB,EAAEN,EAAE,CAACO,EAAE,CAAC;AAC5B,CAAC,CAAC,CAAC;AAIH,MAAMC,uBAAiD,GAAG,EAAE;AAE5D,MAAMC,kBAAkB,CAAC;EACrBC,WAAWA,CAACC,QAAgC,EAAE;IAC1CH,uBAAuB,CAACI,IAAI,CAACD,QAAQ,CAAC;EAC1C;EAEAE,UAAUA,CAAA,EAAG,CAAC;EAEdC,OAAOA,CAAA,EAAG,CAAC;EAEXC,SAASA,CAAA,EAAG,CAAC;AACjB;AAEAf,EAAE,CAACgB,UAAU,CAAC,gBAAgB,EAAEP,kBAAkB,CAAC;AAEnD,MAAMQ,aAAa,GAAIC,MAAc,IAAK;EACtCV,uBAAuB,CAACW,OAAO,CAAER,QAAQ,IAAK;IAC1CA,QAAQ,CAAC,CACL;MACIS,WAAW,EAAE;QAAEF;MAAO;IAC1B,CAAC,CACJ,CAAC;EACN,CAAC,CAAC;AACN,CAAC;AAEDtB,SAAS,CAAC,MAAM;EACZY,uBAAuB,CAACa,MAAM,GAAG,CAAC;AACtC,CAAC,CAAC;AAEFxB,QAAQ,CAAC,YAAY,EAAE,MAAM;EACzBE,EAAE,CAAC,iEAAiE,EAAE,YAAY;IAC9EP,MAAM,cACFG,KAAA,CAAA2B,aAAA,CAACrB,UAAU;MAACsB,eAAe,EAAE;IAAI,gBAC7B5B,KAAA,CAAA2B,aAAA,cAAK,cAAiB,CACd,CAChB,CAAC;IAEDL,aAAa,CAAC,GAAG,CAAC;IAElB,MAAMvB,OAAO,CAAC,MAAM;MAChBI,MAAM,CAACL,MAAM,CAAC+B,SAAS,CAAC,QAAQ,EAAE;QAAEC,IAAI,EAAE;MAAgB,CAAC,CAAC,CAAC,CAACC,iBAAiB,CAAC,CAAC;IACrF,CAAC,CAAC;EACN,CAAC,CAAC;EAEF3B,EAAE,CAAC,oDAAoD,EAAE,YAAY;IACjEP,MAAM,cACFG,KAAA,CAAA2B,aAAA,CAACrB,UAAU;MAACsB,eAAe,EAAE;IAAI,gBAC7B5B,KAAA,CAAA2B,aAAA,cAAK,eAAkB,CACf,CAChB,CAAC;IAEDL,aAAa,CAAC,EAAE,CAAC;IAEjB,MAAMvB,OAAO,CAAC,MAAM;MAChBI,MAAM,CAACL,MAAM,CAACkC,WAAW,CAAC,QAAQ,EAAE;QAAEF,IAAI,EAAE;MAAgB,CAAC,CAAC,CAAC,CAACG,GAAG,CAACF,iBAAiB,CAAC,CAAC;IAC3F,CAAC,CAAC;EACN,CAAC,CAAC;AACN,CAAC,CAAC","ignoreList":[]}
|
|
@@ -1,30 +1,40 @@
|
|
|
1
1
|
import { CopyableContentAppearance } from './CopyableContent.types';
|
|
2
|
-
export declare
|
|
2
|
+
export declare enum CopyableContentColorMode {
|
|
3
|
+
Dark = "dark",
|
|
4
|
+
Light = "light"
|
|
5
|
+
}
|
|
6
|
+
export declare const StyledCopyableContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "theme" | "$colorMode" | "$appearance"> & {
|
|
3
7
|
$appearance: CopyableContentAppearance;
|
|
8
|
+
$colorMode: CopyableContentColorMode;
|
|
4
9
|
} & {
|
|
5
10
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
6
|
-
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "theme" | "$appearance"> & {
|
|
11
|
+
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "theme" | "$colorMode" | "$appearance"> & {
|
|
7
12
|
$appearance: CopyableContentAppearance;
|
|
13
|
+
$colorMode: CopyableContentColorMode;
|
|
8
14
|
} & {
|
|
9
15
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
10
16
|
}, never>>> & string;
|
|
11
17
|
export declare const StyledCopyableContentActions: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
|
|
12
18
|
export declare const StyledCopyableContentActionGroup: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
|
|
13
|
-
export declare const StyledCopyableContentButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "theme" | "$isSticky"> & {
|
|
19
|
+
export declare const StyledCopyableContentButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "theme" | "$colorMode" | "$isSticky"> & {
|
|
20
|
+
$colorMode: CopyableContentColorMode;
|
|
14
21
|
$isSticky: boolean;
|
|
15
22
|
} & {
|
|
16
23
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
17
|
-
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "theme" | "$isSticky"> & {
|
|
24
|
+
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "theme" | "$colorMode" | "$isSticky"> & {
|
|
25
|
+
$colorMode: CopyableContentColorMode;
|
|
18
26
|
$isSticky: boolean;
|
|
19
27
|
} & {
|
|
20
28
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
21
29
|
}, never>>> & string;
|
|
22
30
|
export declare const StyledCopyableContentTruncation: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
|
|
23
|
-
export declare const StyledCopyableContentBody: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "theme" | "$shouldShowPadding"> & {
|
|
31
|
+
export declare const StyledCopyableContentBody: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "theme" | "$colorMode" | "$shouldShowPadding"> & {
|
|
32
|
+
$colorMode: CopyableContentColorMode;
|
|
24
33
|
$shouldShowPadding?: boolean;
|
|
25
34
|
} & {
|
|
26
35
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
27
|
-
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "theme" | "$shouldShowPadding"> & {
|
|
36
|
+
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "theme" | "$colorMode" | "$shouldShowPadding"> & {
|
|
37
|
+
$colorMode: CopyableContentColorMode;
|
|
28
38
|
$shouldShowPadding?: boolean;
|
|
29
39
|
} & {
|
|
30
40
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
@@ -5,7 +5,7 @@ export declare const StyledMotionTruncationContent: import("styled-components/di
|
|
|
5
5
|
}, never> & Partial<Pick<Omit<Omit<import("framer-motion").HTMLMotionProps<"div">, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
6
6
|
ref?: ((instance: HTMLDivElement | null) => void | React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | React.RefObject<HTMLDivElement> | null | undefined;
|
|
7
7
|
}, never>>> & string & Omit<import("framer-motion").ForwardRefComponent<HTMLDivElement, import("framer-motion").HTMLMotionProps<"div">>, keyof React.Component<any, {}, any>>;
|
|
8
|
-
export declare const
|
|
8
|
+
export declare const StyledTruncationContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
|
|
9
9
|
export declare const StyledTruncationClampWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "theme" | "$position"> & {
|
|
10
10
|
$position: ClampPosition;
|
|
11
11
|
} & {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chayns-components/core",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.26",
|
|
4
4
|
"description": "A set of beautiful React components for developing your own applications with chayns.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"browserslist": [
|
|
@@ -93,5 +93,5 @@
|
|
|
93
93
|
"publishConfig": {
|
|
94
94
|
"access": "public"
|
|
95
95
|
},
|
|
96
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "92d9195193d59f3180f001b3545b34167476d6a7"
|
|
97
97
|
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.truncateElement = void 0;
|
|
7
|
-
const doesElementOverflow = (element, referenceHeight) => element.scrollHeight > referenceHeight;
|
|
8
|
-
const doesElementHasOnlyText = element => {
|
|
9
|
-
// Check if element has no child elements.
|
|
10
|
-
if (element.children.length === 0) {
|
|
11
|
-
// If element has text (not empty), it is only text.
|
|
12
|
-
return element.textContent !== '';
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Element has child elements or no text, so it's not only text.
|
|
16
|
-
return false;
|
|
17
|
-
};
|
|
18
|
-
const removeLastLeafElement = element => {
|
|
19
|
-
// remove last element of html element where the last element is a leaf element and its content is a string
|
|
20
|
-
const {
|
|
21
|
-
lastElementChild,
|
|
22
|
-
lastChild
|
|
23
|
-
} = element;
|
|
24
|
-
if (lastElementChild && !doesElementHasOnlyText(lastElementChild) && lastElementChild.hasChildNodes()) {
|
|
25
|
-
removeLastLeafElement(lastElementChild);
|
|
26
|
-
} else if (lastChild && lastChild.nodeType === Node.TEXT_NODE && lastChild.textContent && lastChild.textContent.length > 25) {
|
|
27
|
-
lastChild.textContent = `${lastChild.textContent.substring(0, lastChild.textContent.length - 25)} ...`;
|
|
28
|
-
} else if (lastElementChild && doesElementHasOnlyText(lastElementChild) && lastElementChild.textContent && lastElementChild.textContent.length > 25) {
|
|
29
|
-
lastElementChild.textContent = `${lastElementChild.textContent.substring(0, lastElementChild.textContent.length - 25)} ...`;
|
|
30
|
-
} else if (lastChild) {
|
|
31
|
-
element.removeChild(lastChild);
|
|
32
|
-
} else if (lastElementChild) {
|
|
33
|
-
element.removeChild(lastElementChild);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
const truncateElement = (element, referenceHeight) => {
|
|
37
|
-
while (doesElementOverflow(element, referenceHeight)) {
|
|
38
|
-
removeLastLeafElement(element);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
exports.truncateElement = truncateElement;
|
|
42
|
-
//# sourceMappingURL=truncation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"truncation.js","names":["doesElementOverflow","element","referenceHeight","scrollHeight","doesElementHasOnlyText","children","length","textContent","removeLastLeafElement","lastElementChild","lastChild","hasChildNodes","nodeType","Node","TEXT_NODE","substring","removeChild","truncateElement","exports"],"sources":["../../../src/utils/truncation.ts"],"sourcesContent":["const doesElementOverflow = (element: HTMLElement, referenceHeight: number): boolean =>\n element.scrollHeight > referenceHeight;\n\nconst doesElementHasOnlyText = (element: HTMLElement): boolean => {\n // Check if element has no child elements.\n if (element.children.length === 0) {\n // If element has text (not empty), it is only text.\n return element.textContent !== '';\n }\n\n // Element has child elements or no text, so it's not only text.\n return false;\n};\n\nconst removeLastLeafElement = (element: HTMLElement) => {\n // remove last element of html element where the last element is a leaf element and its content is a string\n const { lastElementChild, lastChild } = element;\n\n if (\n lastElementChild &&\n !doesElementHasOnlyText(lastElementChild as HTMLElement) &&\n lastElementChild.hasChildNodes()\n ) {\n removeLastLeafElement(lastElementChild as HTMLElement);\n } else if (\n lastChild &&\n lastChild.nodeType === Node.TEXT_NODE &&\n lastChild.textContent &&\n lastChild.textContent.length > 25\n ) {\n lastChild.textContent = `${lastChild.textContent.substring(0, lastChild.textContent.length - 25)} ...`;\n } else if (\n lastElementChild &&\n doesElementHasOnlyText(lastElementChild as HTMLElement) &&\n lastElementChild.textContent &&\n lastElementChild.textContent.length > 25\n ) {\n lastElementChild.textContent = `${lastElementChild.textContent.substring(\n 0,\n lastElementChild.textContent.length - 25,\n )} ...`;\n } else if (lastChild) {\n element.removeChild(lastChild);\n } else if (lastElementChild) {\n element.removeChild(lastElementChild);\n }\n};\nexport const truncateElement = (element: HTMLElement, referenceHeight: number) => {\n while (doesElementOverflow(element, referenceHeight)) {\n removeLastLeafElement(element);\n }\n};\n"],"mappings":";;;;;;AAAA,MAAMA,mBAAmB,GAAGA,CAACC,OAAoB,EAAEC,eAAuB,KACtED,OAAO,CAACE,YAAY,GAAGD,eAAe;AAE1C,MAAME,sBAAsB,GAAIH,OAAoB,IAAc;EAC9D;EACA,IAAIA,OAAO,CAACI,QAAQ,CAACC,MAAM,KAAK,CAAC,EAAE;IAC/B;IACA,OAAOL,OAAO,CAACM,WAAW,KAAK,EAAE;EACrC;;EAEA;EACA,OAAO,KAAK;AAChB,CAAC;AAED,MAAMC,qBAAqB,GAAIP,OAAoB,IAAK;EACpD;EACA,MAAM;IAAEQ,gBAAgB;IAAEC;EAAU,CAAC,GAAGT,OAAO;EAE/C,IACIQ,gBAAgB,IAChB,CAACL,sBAAsB,CAACK,gBAA+B,CAAC,IACxDA,gBAAgB,CAACE,aAAa,CAAC,CAAC,EAClC;IACEH,qBAAqB,CAACC,gBAA+B,CAAC;EAC1D,CAAC,MAAM,IACHC,SAAS,IACTA,SAAS,CAACE,QAAQ,KAAKC,IAAI,CAACC,SAAS,IACrCJ,SAAS,CAACH,WAAW,IACrBG,SAAS,CAACH,WAAW,CAACD,MAAM,GAAG,EAAE,EACnC;IACEI,SAAS,CAACH,WAAW,GAAG,GAAGG,SAAS,CAACH,WAAW,CAACQ,SAAS,CAAC,CAAC,EAAEL,SAAS,CAACH,WAAW,CAACD,MAAM,GAAG,EAAE,CAAC,MAAM;EAC1G,CAAC,MAAM,IACHG,gBAAgB,IAChBL,sBAAsB,CAACK,gBAA+B,CAAC,IACvDA,gBAAgB,CAACF,WAAW,IAC5BE,gBAAgB,CAACF,WAAW,CAACD,MAAM,GAAG,EAAE,EAC1C;IACEG,gBAAgB,CAACF,WAAW,GAAG,GAAGE,gBAAgB,CAACF,WAAW,CAACQ,SAAS,CACpE,CAAC,EACDN,gBAAgB,CAACF,WAAW,CAACD,MAAM,GAAG,EAC1C,CAAC,MAAM;EACX,CAAC,MAAM,IAAII,SAAS,EAAE;IAClBT,OAAO,CAACe,WAAW,CAACN,SAAS,CAAC;EAClC,CAAC,MAAM,IAAID,gBAAgB,EAAE;IACzBR,OAAO,CAACe,WAAW,CAACP,gBAAgB,CAAC;EACzC;AACJ,CAAC;AACM,MAAMQ,eAAe,GAAGA,CAAChB,OAAoB,EAAEC,eAAuB,KAAK;EAC9E,OAAOF,mBAAmB,CAACC,OAAO,EAAEC,eAAe,CAAC,EAAE;IAClDM,qBAAqB,CAACP,OAAO,CAAC;EAClC;AACJ,CAAC;AAACiB,OAAA,CAAAD,eAAA,GAAAA,eAAA","ignoreList":[]}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
const doesElementOverflow = (element, referenceHeight) => element.scrollHeight > referenceHeight;
|
|
2
|
-
const doesElementHasOnlyText = element => {
|
|
3
|
-
// Check if element has no child elements.
|
|
4
|
-
if (element.children.length === 0) {
|
|
5
|
-
// If element has text (not empty), it is only text.
|
|
6
|
-
return element.textContent !== '';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// Element has child elements or no text, so it's not only text.
|
|
10
|
-
return false;
|
|
11
|
-
};
|
|
12
|
-
const removeLastLeafElement = element => {
|
|
13
|
-
// remove last element of html element where the last element is a leaf element and its content is a string
|
|
14
|
-
const {
|
|
15
|
-
lastElementChild,
|
|
16
|
-
lastChild
|
|
17
|
-
} = element;
|
|
18
|
-
if (lastElementChild && !doesElementHasOnlyText(lastElementChild) && lastElementChild.hasChildNodes()) {
|
|
19
|
-
removeLastLeafElement(lastElementChild);
|
|
20
|
-
} else if (lastChild && lastChild.nodeType === Node.TEXT_NODE && lastChild.textContent && lastChild.textContent.length > 25) {
|
|
21
|
-
lastChild.textContent = `${lastChild.textContent.substring(0, lastChild.textContent.length - 25)} ...`;
|
|
22
|
-
} else if (lastElementChild && doesElementHasOnlyText(lastElementChild) && lastElementChild.textContent && lastElementChild.textContent.length > 25) {
|
|
23
|
-
lastElementChild.textContent = `${lastElementChild.textContent.substring(0, lastElementChild.textContent.length - 25)} ...`;
|
|
24
|
-
} else if (lastChild) {
|
|
25
|
-
element.removeChild(lastChild);
|
|
26
|
-
} else if (lastElementChild) {
|
|
27
|
-
element.removeChild(lastElementChild);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
export const truncateElement = (element, referenceHeight) => {
|
|
31
|
-
while (doesElementOverflow(element, referenceHeight)) {
|
|
32
|
-
removeLastLeafElement(element);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
//# sourceMappingURL=truncation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"truncation.js","names":["doesElementOverflow","element","referenceHeight","scrollHeight","doesElementHasOnlyText","children","length","textContent","removeLastLeafElement","lastElementChild","lastChild","hasChildNodes","nodeType","Node","TEXT_NODE","substring","removeChild","truncateElement"],"sources":["../../../src/utils/truncation.ts"],"sourcesContent":["const doesElementOverflow = (element: HTMLElement, referenceHeight: number): boolean =>\n element.scrollHeight > referenceHeight;\n\nconst doesElementHasOnlyText = (element: HTMLElement): boolean => {\n // Check if element has no child elements.\n if (element.children.length === 0) {\n // If element has text (not empty), it is only text.\n return element.textContent !== '';\n }\n\n // Element has child elements or no text, so it's not only text.\n return false;\n};\n\nconst removeLastLeafElement = (element: HTMLElement) => {\n // remove last element of html element where the last element is a leaf element and its content is a string\n const { lastElementChild, lastChild } = element;\n\n if (\n lastElementChild &&\n !doesElementHasOnlyText(lastElementChild as HTMLElement) &&\n lastElementChild.hasChildNodes()\n ) {\n removeLastLeafElement(lastElementChild as HTMLElement);\n } else if (\n lastChild &&\n lastChild.nodeType === Node.TEXT_NODE &&\n lastChild.textContent &&\n lastChild.textContent.length > 25\n ) {\n lastChild.textContent = `${lastChild.textContent.substring(0, lastChild.textContent.length - 25)} ...`;\n } else if (\n lastElementChild &&\n doesElementHasOnlyText(lastElementChild as HTMLElement) &&\n lastElementChild.textContent &&\n lastElementChild.textContent.length > 25\n ) {\n lastElementChild.textContent = `${lastElementChild.textContent.substring(\n 0,\n lastElementChild.textContent.length - 25,\n )} ...`;\n } else if (lastChild) {\n element.removeChild(lastChild);\n } else if (lastElementChild) {\n element.removeChild(lastElementChild);\n }\n};\nexport const truncateElement = (element: HTMLElement, referenceHeight: number) => {\n while (doesElementOverflow(element, referenceHeight)) {\n removeLastLeafElement(element);\n }\n};\n"],"mappings":"AAAA,MAAMA,mBAAmB,GAAGA,CAACC,OAAoB,EAAEC,eAAuB,KACtED,OAAO,CAACE,YAAY,GAAGD,eAAe;AAE1C,MAAME,sBAAsB,GAAIH,OAAoB,IAAc;EAC9D;EACA,IAAIA,OAAO,CAACI,QAAQ,CAACC,MAAM,KAAK,CAAC,EAAE;IAC/B;IACA,OAAOL,OAAO,CAACM,WAAW,KAAK,EAAE;EACrC;;EAEA;EACA,OAAO,KAAK;AAChB,CAAC;AAED,MAAMC,qBAAqB,GAAIP,OAAoB,IAAK;EACpD;EACA,MAAM;IAAEQ,gBAAgB;IAAEC;EAAU,CAAC,GAAGT,OAAO;EAE/C,IACIQ,gBAAgB,IAChB,CAACL,sBAAsB,CAACK,gBAA+B,CAAC,IACxDA,gBAAgB,CAACE,aAAa,CAAC,CAAC,EAClC;IACEH,qBAAqB,CAACC,gBAA+B,CAAC;EAC1D,CAAC,MAAM,IACHC,SAAS,IACTA,SAAS,CAACE,QAAQ,KAAKC,IAAI,CAACC,SAAS,IACrCJ,SAAS,CAACH,WAAW,IACrBG,SAAS,CAACH,WAAW,CAACD,MAAM,GAAG,EAAE,EACnC;IACEI,SAAS,CAACH,WAAW,GAAG,GAAGG,SAAS,CAACH,WAAW,CAACQ,SAAS,CAAC,CAAC,EAAEL,SAAS,CAACH,WAAW,CAACD,MAAM,GAAG,EAAE,CAAC,MAAM;EAC1G,CAAC,MAAM,IACHG,gBAAgB,IAChBL,sBAAsB,CAACK,gBAA+B,CAAC,IACvDA,gBAAgB,CAACF,WAAW,IAC5BE,gBAAgB,CAACF,WAAW,CAACD,MAAM,GAAG,EAAE,EAC1C;IACEG,gBAAgB,CAACF,WAAW,GAAG,GAAGE,gBAAgB,CAACF,WAAW,CAACQ,SAAS,CACpE,CAAC,EACDN,gBAAgB,CAACF,WAAW,CAACD,MAAM,GAAG,EAC1C,CAAC,MAAM;EACX,CAAC,MAAM,IAAII,SAAS,EAAE;IAClBT,OAAO,CAACe,WAAW,CAACN,SAAS,CAAC;EAClC,CAAC,MAAM,IAAID,gBAAgB,EAAE;IACzBR,OAAO,CAACe,WAAW,CAACP,gBAAgB,CAAC;EACzC;AACJ,CAAC;AACD,OAAO,MAAMQ,eAAe,GAAGA,CAAChB,OAAoB,EAAEC,eAAuB,KAAK;EAC9E,OAAOF,mBAAmB,CAACC,OAAO,EAAEC,eAAe,CAAC,EAAE;IAClDM,qBAAqB,CAACP,OAAO,CAAC;EAClC;AACJ,CAAC","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const truncateElement: (element: HTMLElement, referenceHeight: number) => void;
|