@chayns-components/core 5.5.9 → 5.5.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +12 -0
- package/lib/cjs/components/copyable-content/CopyableContent.js +10 -19
- package/lib/cjs/components/copyable-content/CopyableContent.js.map +1 -1
- package/lib/cjs/components/copyable-content/CopyableContent.styles.js +14 -5
- package/lib/cjs/components/copyable-content/CopyableContent.styles.js.map +1 -1
- package/lib/cjs/hooks/useStickyActionPosition.js +90 -0
- package/lib/cjs/hooks/useStickyActionPosition.js.map +1 -0
- package/lib/esm/components/copyable-content/CopyableContent.js +11 -19
- package/lib/esm/components/copyable-content/CopyableContent.js.map +1 -1
- package/lib/esm/components/copyable-content/CopyableContent.styles.js +14 -5
- package/lib/esm/components/copyable-content/CopyableContent.styles.js.map +1 -1
- package/lib/esm/hooks/useStickyActionPosition.js +83 -0
- package/lib/esm/hooks/useStickyActionPosition.js.map +1 -0
- package/lib/types/components/copyable-content/CopyableContent.styles.d.ts +7 -5
- package/lib/types/hooks/useStickyActionPosition.d.ts +14 -0
- package/package.json +2 -2
package/AGENTS.md
CHANGED
|
@@ -1533,6 +1533,18 @@ import { CopyableContent } from '@chayns-components/core';
|
|
|
1533
1533
|
/>
|
|
1534
1534
|
```
|
|
1535
1535
|
|
|
1536
|
+
#### Nested Scroll Container
|
|
1537
|
+
|
|
1538
|
+
```tsx
|
|
1539
|
+
<CopyableContent
|
|
1540
|
+
content={Array.from(
|
|
1541
|
+
{ length: 12 },
|
|
1542
|
+
(_, index) =>
|
|
1543
|
+
`### Update ${index + 1}\n\nDas Organisationsteam hat die aktuelle Rückmeldung zusammengefasst. Bitte prüft die offenen Punkte und gebt bis Freitag Bescheid, falls sich bei eurer Planung noch etwas geändert hat.`,
|
|
1544
|
+
).join('\n\n')}
|
|
1545
|
+
/>
|
|
1546
|
+
```
|
|
1547
|
+
|
|
1536
1548
|
### Props
|
|
1537
1549
|
|
|
1538
1550
|
No prop documentation available.
|
|
@@ -9,21 +9,22 @@ var _textstring = require("@chayns-components/textstring");
|
|
|
9
9
|
var _chaynsApi = require("chayns-api");
|
|
10
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
11
|
var _textStrings = _interopRequireDefault(require("../../constants/textStrings"));
|
|
12
|
+
var _useStickyActionPosition = require("../../hooks/useStickyActionPosition");
|
|
12
13
|
var _SharingContextMenu = _interopRequireDefault(require("../sharing-context-menu/SharingContextMenu"));
|
|
13
14
|
var _Icon = _interopRequireDefault(require("../icon/Icon"));
|
|
14
15
|
var _CopyableContent = require("./CopyableContent.styles");
|
|
15
16
|
var _copyableContentClipboard = require("./copyableContentClipboard");
|
|
16
17
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
18
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
18
|
-
const STICKY_ACTION_OFFSET = 8;
|
|
19
19
|
const CopyableContent = ({
|
|
20
20
|
content,
|
|
21
21
|
children,
|
|
22
22
|
copiedMessage,
|
|
23
23
|
copyFailedMessage
|
|
24
24
|
}) => {
|
|
25
|
-
const
|
|
25
|
+
const rootRef = (0, _react.useRef)(null);
|
|
26
26
|
const actionGroupRef = (0, _react.useRef)(null);
|
|
27
|
+
const stickyActionPosition = (0, _useStickyActionPosition.useStickyActionPosition)(rootRef, actionGroupRef);
|
|
27
28
|
const defaultCopyButtonText = (0, _textstring.useTextstringValue)({
|
|
28
29
|
textstring: (0, _textstring.ttsToITextString)(_textStrings.default.components.copyableContent.copy)
|
|
29
30
|
});
|
|
@@ -37,20 +38,6 @@ const CopyableContent = ({
|
|
|
37
38
|
textstring: (0, _textstring.ttsToITextString)(_textStrings.default.components.copyableContent.share)
|
|
38
39
|
});
|
|
39
40
|
const html = (0, _react.useMemo)(() => (0, _format.formatStringToHtml)(content).html, [content]);
|
|
40
|
-
(0, _react.useEffect)(() => {
|
|
41
|
-
const updateStickyState = () => {
|
|
42
|
-
var _actionGroupRef$curre;
|
|
43
|
-
const actionGroupTop = (_actionGroupRef$curre = actionGroupRef.current) === null || _actionGroupRef$curre === void 0 ? void 0 : _actionGroupRef$curre.getBoundingClientRect().top;
|
|
44
|
-
setIsActionGroupSticky(actionGroupTop !== undefined && actionGroupTop <= STICKY_ACTION_OFFSET);
|
|
45
|
-
};
|
|
46
|
-
updateStickyState();
|
|
47
|
-
document.addEventListener('scroll', updateStickyState, true);
|
|
48
|
-
window.addEventListener('resize', updateStickyState);
|
|
49
|
-
return () => {
|
|
50
|
-
document.removeEventListener('scroll', updateStickyState, true);
|
|
51
|
-
window.removeEventListener('resize', updateStickyState);
|
|
52
|
-
};
|
|
53
|
-
}, []);
|
|
54
41
|
const handleCopy = (0, _react.useCallback)(async () => {
|
|
55
42
|
try {
|
|
56
43
|
await (0, _copyableContentClipboard.copyableContentToClipboard)(content);
|
|
@@ -70,11 +57,15 @@ const CopyableContent = ({
|
|
|
70
57
|
}
|
|
71
58
|
}, [content, copiedMessage, defaultCopiedMessage, defaultCopyFailedMessage, copyFailedMessage]);
|
|
72
59
|
return /*#__PURE__*/_react.default.createElement(_CopyableContent.StyledCopyableContent, {
|
|
73
|
-
className: "copyable-content"
|
|
60
|
+
className: "copyable-content",
|
|
61
|
+
ref: rootRef
|
|
74
62
|
}, /*#__PURE__*/_react.default.createElement(_CopyableContent.StyledCopyableContentActions, {
|
|
63
|
+
$fixedRight: stickyActionPosition.fixedRight,
|
|
64
|
+
$fixedTop: stickyActionPosition.fixedTop,
|
|
65
|
+
$isFixed: stickyActionPosition.isFixed,
|
|
75
66
|
ref: actionGroupRef
|
|
76
67
|
}, /*#__PURE__*/_react.default.createElement(_CopyableContent.StyledCopyableContentActionGroup, null, /*#__PURE__*/_react.default.createElement(_CopyableContent.StyledCopyableContentButton, {
|
|
77
|
-
$isSticky:
|
|
68
|
+
$isSticky: stickyActionPosition.isSticky,
|
|
78
69
|
"aria-label": defaultCopyButtonText,
|
|
79
70
|
onClick: () => {
|
|
80
71
|
void handleCopy();
|
|
@@ -86,7 +77,7 @@ const CopyableContent = ({
|
|
|
86
77
|
link: content,
|
|
87
78
|
shouldUseDefaultTriggerStyles: false
|
|
88
79
|
}, /*#__PURE__*/_react.default.createElement(_CopyableContent.StyledCopyableContentButton, {
|
|
89
|
-
$isSticky:
|
|
80
|
+
$isSticky: stickyActionPosition.isSticky,
|
|
90
81
|
"aria-label": shareText,
|
|
91
82
|
type: "button"
|
|
92
83
|
}, /*#__PURE__*/_react.default.createElement(_Icon.default, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyableContent.js","names":["_format","require","_textstring","_chaynsApi","_react","_interopRequireWildcard","_textStrings","_interopRequireDefault","_SharingContextMenu","_Icon","_CopyableContent","_copyableContentClipboard","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","STICKY_ACTION_OFFSET","CopyableContent","content","children","copiedMessage","copyFailedMessage","isActionGroupSticky","setIsActionGroupSticky","useState","actionGroupRef","useRef","defaultCopyButtonText","useTextstringValue","textstring","ttsToITextString","textStrings","components","copyableContent","copy","defaultCopiedMessage","copied","defaultCopyFailedMessage","copyFailed","shareText","share","html","useMemo","formatStringToHtml","useEffect","updateStickyState","_actionGroupRef$curre","actionGroupTop","current","getBoundingClientRect","top","undefined","document","addEventListener","window","removeEventListener","handleCopy","useCallback","copyableContentToClipboard","createDialog","showCloseIcon","text","toastType","ToastType","SUCCESS","type","DialogType","TOAST","open","ERROR","createElement","StyledCopyableContent","className","StyledCopyableContentActions","ref","StyledCopyableContentActionGroup","StyledCopyableContentButton","$isSticky","onClick","icons","link","shouldUseDefaultTriggerStyles","StyledCopyableContentBody","dangerouslySetInnerHTML","__html","displayName","_default","exports"],"sources":["../../../../src/components/copyable-content/CopyableContent.tsx"],"sourcesContent":["import { formatStringToHtml } from '@chayns-components/format';\nimport { ttsToITextString, useTextstringValue } from '@chayns-components/textstring';\nimport { createDialog, DialogType, ToastType } from 'chayns-api';\nimport React, { FC, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport textStrings from '../../constants/textStrings';\nimport SharingContextMenu from '../sharing-context-menu/SharingContextMenu';\nimport Icon from '../icon/Icon';\nimport {\n StyledCopyableContent,\n StyledCopyableContentActionGroup,\n StyledCopyableContentActions,\n StyledCopyableContentBody,\n StyledCopyableContentButton,\n} from './CopyableContent.styles';\nimport { copyableContentToClipboard } from './copyableContentClipboard';\n\nexport type CopyableContentProps = {\n content: string;\n children?: ReactNode;\n copiedMessage?: string;\n copyFailedMessage?: string;\n};\n\nconst STICKY_ACTION_OFFSET = 8;\n\nconst CopyableContent: FC<CopyableContentProps> = ({\n content,\n children,\n copiedMessage,\n copyFailedMessage,\n}) => {\n const [isActionGroupSticky, setIsActionGroupSticky] = useState(false);\n\n const actionGroupRef = useRef<HTMLDivElement>(null);\n\n const defaultCopyButtonText = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copy),\n });\n const defaultCopiedMessage = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copied),\n });\n const defaultCopyFailedMessage = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copyFailed),\n });\n const shareText = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.share),\n });\n\n const html = useMemo(() => formatStringToHtml(content).html, [content]);\n\n useEffect(() => {\n const updateStickyState = () => {\n const actionGroupTop = actionGroupRef.current?.getBoundingClientRect().top;\n setIsActionGroupSticky(\n actionGroupTop !== undefined && actionGroupTop <= STICKY_ACTION_OFFSET,\n );\n };\n\n updateStickyState();\n document.addEventListener('scroll', updateStickyState, true);\n window.addEventListener('resize', updateStickyState);\n\n return () => {\n document.removeEventListener('scroll', updateStickyState, true);\n window.removeEventListener('resize', updateStickyState);\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n try {\n await copyableContentToClipboard(content);\n void createDialog({\n showCloseIcon: true,\n text: copiedMessage ?? defaultCopiedMessage,\n toastType: ToastType.SUCCESS,\n type: DialogType.TOAST,\n }).open();\n } catch {\n void createDialog({\n showCloseIcon: true,\n text: copyFailedMessage ?? defaultCopyFailedMessage,\n toastType: ToastType.ERROR,\n type: DialogType.TOAST,\n }).open();\n }\n }, [content, copiedMessage, defaultCopiedMessage, defaultCopyFailedMessage, copyFailedMessage]);\n\n return (\n <StyledCopyableContent className=\"copyable-content\">\n <StyledCopyableContentActions ref={actionGroupRef}>\n <StyledCopyableContentActionGroup>\n <StyledCopyableContentButton\n $isSticky={isActionGroupSticky}\n aria-label={defaultCopyButtonText}\n onClick={() => {\n void handleCopy();\n }}\n type=\"button\"\n >\n <Icon icons={['fa-light fa-copy']} />\n </StyledCopyableContentButton>\n <SharingContextMenu link={content} shouldUseDefaultTriggerStyles={false}>\n <StyledCopyableContentButton\n $isSticky={isActionGroupSticky}\n aria-label={shareText}\n type=\"button\"\n >\n <Icon icons={['fa fa-share-nodes']} />\n </StyledCopyableContentButton>\n </SharingContextMenu>\n </StyledCopyableContentActionGroup>\n </StyledCopyableContentActions>\n <StyledCopyableContentBody>\n {children ?? <div dangerouslySetInnerHTML={{ __html: html }} />}\n </StyledCopyableContentBody>\n </StyledCopyableContent>\n );\n};\n\nCopyableContent.displayName = 'CopyableContent';\n\nexport default CopyableContent;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"CopyableContent.js","names":["_format","require","_textstring","_chaynsApi","_react","_interopRequireWildcard","_textStrings","_interopRequireDefault","_useStickyActionPosition","_SharingContextMenu","_Icon","_CopyableContent","_copyableContentClipboard","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","CopyableContent","content","children","copiedMessage","copyFailedMessage","rootRef","useRef","actionGroupRef","stickyActionPosition","useStickyActionPosition","defaultCopyButtonText","useTextstringValue","textstring","ttsToITextString","textStrings","components","copyableContent","copy","defaultCopiedMessage","copied","defaultCopyFailedMessage","copyFailed","shareText","share","html","useMemo","formatStringToHtml","handleCopy","useCallback","copyableContentToClipboard","createDialog","showCloseIcon","text","toastType","ToastType","SUCCESS","type","DialogType","TOAST","open","ERROR","createElement","StyledCopyableContent","className","ref","StyledCopyableContentActions","$fixedRight","fixedRight","$fixedTop","fixedTop","$isFixed","isFixed","StyledCopyableContentActionGroup","StyledCopyableContentButton","$isSticky","isSticky","onClick","icons","link","shouldUseDefaultTriggerStyles","StyledCopyableContentBody","dangerouslySetInnerHTML","__html","displayName","_default","exports"],"sources":["../../../../src/components/copyable-content/CopyableContent.tsx"],"sourcesContent":["import { formatStringToHtml } from '@chayns-components/format';\nimport { ttsToITextString, useTextstringValue } from '@chayns-components/textstring';\nimport { createDialog, DialogType, ToastType } from 'chayns-api';\nimport React, { FC, ReactNode, useCallback, useMemo, useRef } from 'react';\nimport textStrings from '../../constants/textStrings';\nimport { useStickyActionPosition } from '../../hooks/useStickyActionPosition';\nimport SharingContextMenu from '../sharing-context-menu/SharingContextMenu';\nimport Icon from '../icon/Icon';\nimport {\n StyledCopyableContent,\n StyledCopyableContentActionGroup,\n StyledCopyableContentActions,\n StyledCopyableContentBody,\n StyledCopyableContentButton,\n} from './CopyableContent.styles';\nimport { copyableContentToClipboard } from './copyableContentClipboard';\n\nexport type CopyableContentProps = {\n content: string;\n children?: ReactNode;\n copiedMessage?: string;\n copyFailedMessage?: string;\n};\n\nconst CopyableContent: FC<CopyableContentProps> = ({\n content,\n children,\n copiedMessage,\n copyFailedMessage,\n}) => {\n const rootRef = useRef<HTMLElement>(null);\n const actionGroupRef = useRef<HTMLDivElement>(null);\n const stickyActionPosition = useStickyActionPosition(rootRef, actionGroupRef);\n\n const defaultCopyButtonText = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copy),\n });\n const defaultCopiedMessage = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copied),\n });\n const defaultCopyFailedMessage = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copyFailed),\n });\n const shareText = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.share),\n });\n\n const html = useMemo(() => formatStringToHtml(content).html, [content]);\n\n const handleCopy = useCallback(async () => {\n try {\n await copyableContentToClipboard(content);\n void createDialog({\n showCloseIcon: true,\n text: copiedMessage ?? defaultCopiedMessage,\n toastType: ToastType.SUCCESS,\n type: DialogType.TOAST,\n }).open();\n } catch {\n void createDialog({\n showCloseIcon: true,\n text: copyFailedMessage ?? defaultCopyFailedMessage,\n toastType: ToastType.ERROR,\n type: DialogType.TOAST,\n }).open();\n }\n }, [content, copiedMessage, defaultCopiedMessage, defaultCopyFailedMessage, copyFailedMessage]);\n\n return (\n <StyledCopyableContent className=\"copyable-content\" ref={rootRef}>\n <StyledCopyableContentActions\n $fixedRight={stickyActionPosition.fixedRight}\n $fixedTop={stickyActionPosition.fixedTop}\n $isFixed={stickyActionPosition.isFixed}\n ref={actionGroupRef}\n >\n <StyledCopyableContentActionGroup>\n <StyledCopyableContentButton\n $isSticky={stickyActionPosition.isSticky}\n aria-label={defaultCopyButtonText}\n onClick={() => {\n void handleCopy();\n }}\n type=\"button\"\n >\n <Icon icons={['fa-light fa-copy']} />\n </StyledCopyableContentButton>\n <SharingContextMenu link={content} shouldUseDefaultTriggerStyles={false}>\n <StyledCopyableContentButton\n $isSticky={stickyActionPosition.isSticky}\n aria-label={shareText}\n type=\"button\"\n >\n <Icon icons={['fa fa-share-nodes']} />\n </StyledCopyableContentButton>\n </SharingContextMenu>\n </StyledCopyableContentActionGroup>\n </StyledCopyableContentActions>\n <StyledCopyableContentBody>\n {children ?? <div dangerouslySetInnerHTML={{ __html: html }} />}\n </StyledCopyableContentBody>\n </StyledCopyableContent>\n );\n};\n\nCopyableContent.displayName = 'CopyableContent';\n\nexport default CopyableContent;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -33,15 +33,24 @@ const StyledCopyableContent = exports.StyledCopyableContent = _styledComponents.
|
|
|
33
33
|
}) => theme.text};
|
|
34
34
|
`;
|
|
35
35
|
const StyledCopyableContentActions = exports.StyledCopyableContentActions = _styledComponents.default.div`
|
|
36
|
-
position:
|
|
37
|
-
|
|
36
|
+
position: ${({
|
|
37
|
+
$isFixed
|
|
38
|
+
}) => $isFixed ? 'fixed' : 'sticky'};
|
|
39
|
+
top: ${({
|
|
40
|
+
$fixedTop,
|
|
41
|
+
$isFixed
|
|
42
|
+
}) => $isFixed ? `${$fixedTop}px` : 'var(--copyable-content-action-inset)'};
|
|
43
|
+
right: ${({
|
|
44
|
+
$fixedRight,
|
|
45
|
+
$isFixed
|
|
46
|
+
}) => $isFixed ? `${$fixedRight}px` : 'auto'};
|
|
38
47
|
z-index: 1;
|
|
39
48
|
display: flex;
|
|
40
49
|
justify-content: flex-end;
|
|
41
50
|
height: calc(var(--copyable-content-action-size) + var(--copyable-content-action-inset));
|
|
42
|
-
margin-top:
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
margin-top: ${({
|
|
52
|
+
$isFixed
|
|
53
|
+
}) => $isFixed ? '0' : 'calc((var(--copyable-content-action-size) + var(--copyable-content-action-inset)) * -1)'};
|
|
45
54
|
padding-right: var(--copyable-content-action-inset);
|
|
46
55
|
`;
|
|
47
56
|
const StyledCopyableContentActionGroup = exports.StyledCopyableContentActionGroup = _styledComponents.default.div`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyableContent.styles.js","names":["_styledComponents","_interopRequireDefault","require","e","__esModule","default","StyledCopyableContent","exports","styled","section","theme","cardBorderRadius","cardBackgroundOpacity","text","StyledCopyableContentActions","div","StyledCopyableContentActionGroup","StyledCopyableContentButton","button","$isSticky","buttonBackgroundColor","StyledCopyableContentBody","headline","primary"],"sources":["../../../../src/components/copyable-content/CopyableContent.styles.ts"],"sourcesContent":["import type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport styled from 'styled-components';\n\ntype StyledCopyableContentProps = WithTheme<unknown>;\n\nexport const StyledCopyableContent = styled.section<StyledCopyableContentProps>`\n --copyable-content-action-size: 32px;\n --copyable-content-action-inset: 8px;\n\n min-width: 0;\n max-width: 100%;\n overflow-x: clip;\n overflow-wrap: anywhere;\n padding-top: calc(\n var(--copyable-content-action-size) + var(--copyable-content-action-inset) * 2\n );\n border-radius: ${({ theme }) => theme.cardBorderRadius}px;\n background-color: rgba(\n ${({ theme }) => theme['secondary-100-rgb']},\n ${({ theme }) => theme.cardBackgroundOpacity}\n );\n color: ${({ theme }) => theme.text};\n`;\n\ntype StyledCopyableContentButtonProps = WithTheme<{\n $isSticky: boolean;\n}>;\n\nexport const StyledCopyableContentActions = styled.div<
|
|
1
|
+
{"version":3,"file":"CopyableContent.styles.js","names":["_styledComponents","_interopRequireDefault","require","e","__esModule","default","StyledCopyableContent","exports","styled","section","theme","cardBorderRadius","cardBackgroundOpacity","text","StyledCopyableContentActions","div","$isFixed","$fixedTop","$fixedRight","StyledCopyableContentActionGroup","StyledCopyableContentButton","button","$isSticky","buttonBackgroundColor","StyledCopyableContentBody","headline","primary"],"sources":["../../../../src/components/copyable-content/CopyableContent.styles.ts"],"sourcesContent":["import type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport styled from 'styled-components';\n\ntype StyledCopyableContentProps = WithTheme<unknown>;\n\nexport const StyledCopyableContent = styled.section<StyledCopyableContentProps>`\n --copyable-content-action-size: 32px;\n --copyable-content-action-inset: 8px;\n\n min-width: 0;\n max-width: 100%;\n overflow-x: clip;\n overflow-wrap: anywhere;\n padding-top: calc(\n var(--copyable-content-action-size) + var(--copyable-content-action-inset) * 2\n );\n border-radius: ${({ theme }) => theme.cardBorderRadius}px;\n background-color: rgba(\n ${({ theme }) => theme['secondary-100-rgb']},\n ${({ theme }) => theme.cardBackgroundOpacity}\n );\n color: ${({ theme }) => theme.text};\n`;\n\ntype StyledCopyableContentButtonProps = WithTheme<{\n $isSticky: boolean;\n}>;\n\ntype StyledCopyableContentActionsProps = {\n $fixedRight: number;\n $fixedTop: number;\n $isFixed: boolean;\n};\n\nexport const StyledCopyableContentActions = styled.div<StyledCopyableContentActionsProps>`\n position: ${({ $isFixed }) => ($isFixed ? 'fixed' : 'sticky')};\n top: ${({ $fixedTop, $isFixed }) =>\n $isFixed ? `${$fixedTop}px` : 'var(--copyable-content-action-inset)'};\n right: ${({ $fixedRight, $isFixed }) => ($isFixed ? `${$fixedRight}px` : 'auto')};\n z-index: 1;\n display: flex;\n justify-content: flex-end;\n height: calc(var(--copyable-content-action-size) + var(--copyable-content-action-inset));\n margin-top: ${({ $isFixed }) =>\n $isFixed\n ? '0'\n : 'calc((var(--copyable-content-action-size) + var(--copyable-content-action-inset)) * -1)'};\n padding-right: var(--copyable-content-action-inset);\n`;\n\nexport const StyledCopyableContentActionGroup = styled.div`\n display: flex;\n gap: 4px;\n height: var(--copyable-content-action-size);\n`;\n\nexport const StyledCopyableContentButton = styled.button<StyledCopyableContentButtonProps>`\n box-sizing: border-box;\n border: 1px solid ${({ $isSticky, theme }) => ($isSticky ? theme['202'] : 'transparent')};\n border-radius: 4px;\n width: var(--copyable-content-action-size);\n height: var(--copyable-content-action-size);\n padding: 0;\n cursor: pointer;\n background-color: ${({ $isSticky, theme }) => ($isSticky ? theme['100'] : 'transparent')};\n color: ${({ theme }) => theme.text};\n box-shadow: ${({ $isSticky }) => ($isSticky ? '0 2px 8px rgba(0, 0, 0, 0.16)' : 'none')};\n transition:\n background-color 0.15s ease,\n border-color 0.15s ease,\n box-shadow 0.15s ease,\n transform 0.15s ease;\n\n &:hover {\n background-color: rgba(${({ theme }) => theme['text-rgb']}, 0.1);\n box-shadow: inset 0 0 0 1px rgba(${({ theme }) => theme['text-rgb']}, 0.06);\n }\n\n &:active {\n transform: scale(0.9);\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.buttonBackgroundColor};\n outline-offset: 2px;\n }\n`;\n\nexport const StyledCopyableContentBody = styled.div<StyledCopyableContentProps>`\n min-width: 0;\n max-width: 100%;\n overflow-wrap: anywhere;\n padding: 0 12px 12px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6,\n p,\n ul,\n ol,\n blockquote {\n margin: 0 0 12px;\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n color: ${({ theme }) => theme.headline};\n }\n\n ul,\n ol {\n padding-left: 24px;\n }\n\n blockquote {\n padding-left: 12px;\n border-left: 3px solid ${({ theme }) => theme['202']};\n }\n\n a {\n color: ${({ theme }) => theme.primary};\n overflow-wrap: anywhere;\n }\n\n > :last-child {\n margin-bottom: 0;\n }\n`;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useStickyActionPosition = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
const STICKY_ACTION_INSET = 8;
|
|
9
|
+
const STICKY_ACTION_SIZE = 32;
|
|
10
|
+
const initialPosition = {
|
|
11
|
+
fixedRight: 0,
|
|
12
|
+
fixedTop: STICKY_ACTION_INSET,
|
|
13
|
+
isFixed: false,
|
|
14
|
+
isSticky: false
|
|
15
|
+
};
|
|
16
|
+
const isScrollable = element => {
|
|
17
|
+
const {
|
|
18
|
+
overflow,
|
|
19
|
+
overflowY
|
|
20
|
+
} = window.getComputedStyle(element);
|
|
21
|
+
return /auto|scroll|overlay/.test(`${overflow} ${overflowY}`);
|
|
22
|
+
};
|
|
23
|
+
const getScrollableAncestor = element => {
|
|
24
|
+
let parent = element.parentElement;
|
|
25
|
+
while (parent) {
|
|
26
|
+
if (isScrollable(parent)) {
|
|
27
|
+
return parent;
|
|
28
|
+
}
|
|
29
|
+
parent = parent.parentElement;
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Keeps an action group visible inside the nearest nested scroll container.
|
|
36
|
+
* Native sticky positioning is retained for document scrolling; a fixed-position
|
|
37
|
+
* fallback only applies when the component is hosted in an element scroll container.
|
|
38
|
+
*/
|
|
39
|
+
const useStickyActionPosition = (rootRef, actionRef) => {
|
|
40
|
+
const [position, setPosition] = (0, _react.useState)(initialPosition);
|
|
41
|
+
(0, _react.useEffect)(() => {
|
|
42
|
+
const root = rootRef.current;
|
|
43
|
+
const action = actionRef.current;
|
|
44
|
+
if (!root || !action) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const scrollContainer = getScrollableAncestor(root);
|
|
48
|
+
const updatePosition = () => {
|
|
49
|
+
const rootRect = root.getBoundingClientRect();
|
|
50
|
+
const containerTop = (scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.getBoundingClientRect().top) ?? 0;
|
|
51
|
+
const fixedTop = containerTop + STICKY_ACTION_INSET;
|
|
52
|
+
const isSticky = rootRect.top <= fixedTop;
|
|
53
|
+
const isFixed = Boolean(scrollContainer && isSticky && rootRect.bottom > fixedTop + STICKY_ACTION_SIZE);
|
|
54
|
+
const fixedRight = Math.max(0, window.innerWidth - rootRect.right);
|
|
55
|
+
setPosition(currentPosition => {
|
|
56
|
+
if (currentPosition.fixedRight === fixedRight && currentPosition.fixedTop === fixedTop && currentPosition.isFixed === isFixed && currentPosition.isSticky === isSticky) {
|
|
57
|
+
return currentPosition;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
fixedRight,
|
|
61
|
+
fixedTop,
|
|
62
|
+
isFixed,
|
|
63
|
+
isSticky
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
updatePosition();
|
|
68
|
+
scrollContainer === null || scrollContainer === void 0 || scrollContainer.addEventListener('scroll', updatePosition, {
|
|
69
|
+
passive: true
|
|
70
|
+
});
|
|
71
|
+
window.addEventListener('scroll', updatePosition, {
|
|
72
|
+
passive: true
|
|
73
|
+
});
|
|
74
|
+
window.addEventListener('resize', updatePosition);
|
|
75
|
+
const resizeObserver = typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(updatePosition);
|
|
76
|
+
resizeObserver === null || resizeObserver === void 0 || resizeObserver.observe(root);
|
|
77
|
+
if (scrollContainer) {
|
|
78
|
+
resizeObserver === null || resizeObserver === void 0 || resizeObserver.observe(scrollContainer);
|
|
79
|
+
}
|
|
80
|
+
return () => {
|
|
81
|
+
scrollContainer === null || scrollContainer === void 0 || scrollContainer.removeEventListener('scroll', updatePosition);
|
|
82
|
+
window.removeEventListener('scroll', updatePosition);
|
|
83
|
+
window.removeEventListener('resize', updatePosition);
|
|
84
|
+
resizeObserver === null || resizeObserver === void 0 || resizeObserver.disconnect();
|
|
85
|
+
};
|
|
86
|
+
}, [actionRef, rootRef]);
|
|
87
|
+
return position;
|
|
88
|
+
};
|
|
89
|
+
exports.useStickyActionPosition = useStickyActionPosition;
|
|
90
|
+
//# sourceMappingURL=useStickyActionPosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStickyActionPosition.js","names":["_react","require","STICKY_ACTION_INSET","STICKY_ACTION_SIZE","initialPosition","fixedRight","fixedTop","isFixed","isSticky","isScrollable","element","overflow","overflowY","window","getComputedStyle","test","getScrollableAncestor","parent","parentElement","undefined","useStickyActionPosition","rootRef","actionRef","position","setPosition","useState","useEffect","root","current","action","scrollContainer","updatePosition","rootRect","getBoundingClientRect","containerTop","top","Boolean","bottom","Math","max","innerWidth","right","currentPosition","addEventListener","passive","resizeObserver","ResizeObserver","observe","removeEventListener","disconnect","exports"],"sources":["../../../src/hooks/useStickyActionPosition.ts"],"sourcesContent":["import { RefObject, useEffect, useState } from 'react';\n\nconst STICKY_ACTION_INSET = 8;\nconst STICKY_ACTION_SIZE = 32;\n\ntype StickyActionPosition = {\n fixedRight: number;\n fixedTop: number;\n isFixed: boolean;\n isSticky: boolean;\n};\n\nconst initialPosition: StickyActionPosition = {\n fixedRight: 0,\n fixedTop: STICKY_ACTION_INSET,\n isFixed: false,\n isSticky: false,\n};\n\nconst isScrollable = (element: HTMLElement) => {\n const { overflow, overflowY } = window.getComputedStyle(element);\n\n return /auto|scroll|overlay/.test(`${overflow} ${overflowY}`);\n};\n\nconst getScrollableAncestor = (element: HTMLElement) => {\n let parent = element.parentElement;\n\n while (parent) {\n if (isScrollable(parent)) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n\n return undefined;\n};\n\n/**\n * Keeps an action group visible inside the nearest nested scroll container.\n * Native sticky positioning is retained for document scrolling; a fixed-position\n * fallback only applies when the component is hosted in an element scroll container.\n */\nexport const useStickyActionPosition = (\n rootRef: RefObject<HTMLElement>,\n actionRef: RefObject<HTMLElement>,\n): StickyActionPosition => {\n const [position, setPosition] = useState<StickyActionPosition>(initialPosition);\n\n useEffect(() => {\n const root = rootRef.current;\n const action = actionRef.current;\n\n if (!root || !action) {\n return undefined;\n }\n\n const scrollContainer = getScrollableAncestor(root);\n\n const updatePosition = () => {\n const rootRect = root.getBoundingClientRect();\n const containerTop = scrollContainer?.getBoundingClientRect().top ?? 0;\n const fixedTop = containerTop + STICKY_ACTION_INSET;\n const isSticky = rootRect.top <= fixedTop;\n const isFixed = Boolean(\n scrollContainer && isSticky && rootRect.bottom > fixedTop + STICKY_ACTION_SIZE,\n );\n const fixedRight = Math.max(0, window.innerWidth - rootRect.right);\n\n setPosition((currentPosition) => {\n if (\n currentPosition.fixedRight === fixedRight &&\n currentPosition.fixedTop === fixedTop &&\n currentPosition.isFixed === isFixed &&\n currentPosition.isSticky === isSticky\n ) {\n return currentPosition;\n }\n\n return { fixedRight, fixedTop, isFixed, isSticky };\n });\n };\n\n updatePosition();\n scrollContainer?.addEventListener('scroll', updatePosition, { passive: true });\n window.addEventListener('scroll', updatePosition, { passive: true });\n window.addEventListener('resize', updatePosition);\n\n const resizeObserver =\n typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(updatePosition);\n resizeObserver?.observe(root);\n\n if (scrollContainer) {\n resizeObserver?.observe(scrollContainer);\n }\n\n return () => {\n scrollContainer?.removeEventListener('scroll', updatePosition);\n window.removeEventListener('scroll', updatePosition);\n window.removeEventListener('resize', updatePosition);\n resizeObserver?.disconnect();\n };\n }, [actionRef, rootRef]);\n\n return position;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { formatStringToHtml } from '@chayns-components/format';
|
|
2
2
|
import { ttsToITextString, useTextstringValue } from '@chayns-components/textstring';
|
|
3
3
|
import { createDialog, DialogType, ToastType } from 'chayns-api';
|
|
4
|
-
import React, { useCallback,
|
|
4
|
+
import React, { useCallback, useMemo, useRef } from 'react';
|
|
5
5
|
import textStrings from '../../constants/textStrings';
|
|
6
|
+
import { useStickyActionPosition } from '../../hooks/useStickyActionPosition';
|
|
6
7
|
import SharingContextMenu from '../sharing-context-menu/SharingContextMenu';
|
|
7
8
|
import Icon from '../icon/Icon';
|
|
8
9
|
import { StyledCopyableContent, StyledCopyableContentActionGroup, StyledCopyableContentActions, StyledCopyableContentBody, StyledCopyableContentButton } from './CopyableContent.styles';
|
|
9
10
|
import { copyableContentToClipboard } from './copyableContentClipboard';
|
|
10
|
-
const STICKY_ACTION_OFFSET = 8;
|
|
11
11
|
const CopyableContent = ({
|
|
12
12
|
content,
|
|
13
13
|
children,
|
|
14
14
|
copiedMessage,
|
|
15
15
|
copyFailedMessage
|
|
16
16
|
}) => {
|
|
17
|
-
const
|
|
17
|
+
const rootRef = useRef(null);
|
|
18
18
|
const actionGroupRef = useRef(null);
|
|
19
|
+
const stickyActionPosition = useStickyActionPosition(rootRef, actionGroupRef);
|
|
19
20
|
const defaultCopyButtonText = useTextstringValue({
|
|
20
21
|
textstring: ttsToITextString(textStrings.components.copyableContent.copy)
|
|
21
22
|
});
|
|
@@ -29,19 +30,6 @@ const CopyableContent = ({
|
|
|
29
30
|
textstring: ttsToITextString(textStrings.components.copyableContent.share)
|
|
30
31
|
});
|
|
31
32
|
const html = useMemo(() => formatStringToHtml(content).html, [content]);
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
const updateStickyState = () => {
|
|
34
|
-
const actionGroupTop = actionGroupRef.current?.getBoundingClientRect().top;
|
|
35
|
-
setIsActionGroupSticky(actionGroupTop !== undefined && actionGroupTop <= STICKY_ACTION_OFFSET);
|
|
36
|
-
};
|
|
37
|
-
updateStickyState();
|
|
38
|
-
document.addEventListener('scroll', updateStickyState, true);
|
|
39
|
-
window.addEventListener('resize', updateStickyState);
|
|
40
|
-
return () => {
|
|
41
|
-
document.removeEventListener('scroll', updateStickyState, true);
|
|
42
|
-
window.removeEventListener('resize', updateStickyState);
|
|
43
|
-
};
|
|
44
|
-
}, []);
|
|
45
33
|
const handleCopy = useCallback(async () => {
|
|
46
34
|
try {
|
|
47
35
|
await copyableContentToClipboard(content);
|
|
@@ -61,11 +49,15 @@ const CopyableContent = ({
|
|
|
61
49
|
}
|
|
62
50
|
}, [content, copiedMessage, defaultCopiedMessage, defaultCopyFailedMessage, copyFailedMessage]);
|
|
63
51
|
return /*#__PURE__*/React.createElement(StyledCopyableContent, {
|
|
64
|
-
className: "copyable-content"
|
|
52
|
+
className: "copyable-content",
|
|
53
|
+
ref: rootRef
|
|
65
54
|
}, /*#__PURE__*/React.createElement(StyledCopyableContentActions, {
|
|
55
|
+
$fixedRight: stickyActionPosition.fixedRight,
|
|
56
|
+
$fixedTop: stickyActionPosition.fixedTop,
|
|
57
|
+
$isFixed: stickyActionPosition.isFixed,
|
|
66
58
|
ref: actionGroupRef
|
|
67
59
|
}, /*#__PURE__*/React.createElement(StyledCopyableContentActionGroup, null, /*#__PURE__*/React.createElement(StyledCopyableContentButton, {
|
|
68
|
-
$isSticky:
|
|
60
|
+
$isSticky: stickyActionPosition.isSticky,
|
|
69
61
|
"aria-label": defaultCopyButtonText,
|
|
70
62
|
onClick: () => {
|
|
71
63
|
void handleCopy();
|
|
@@ -77,7 +69,7 @@ const CopyableContent = ({
|
|
|
77
69
|
link: content,
|
|
78
70
|
shouldUseDefaultTriggerStyles: false
|
|
79
71
|
}, /*#__PURE__*/React.createElement(StyledCopyableContentButton, {
|
|
80
|
-
$isSticky:
|
|
72
|
+
$isSticky: stickyActionPosition.isSticky,
|
|
81
73
|
"aria-label": shareText,
|
|
82
74
|
type: "button"
|
|
83
75
|
}, /*#__PURE__*/React.createElement(Icon, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyableContent.js","names":["formatStringToHtml","ttsToITextString","useTextstringValue","createDialog","DialogType","ToastType","React","useCallback","
|
|
1
|
+
{"version":3,"file":"CopyableContent.js","names":["formatStringToHtml","ttsToITextString","useTextstringValue","createDialog","DialogType","ToastType","React","useCallback","useMemo","useRef","textStrings","useStickyActionPosition","SharingContextMenu","Icon","StyledCopyableContent","StyledCopyableContentActionGroup","StyledCopyableContentActions","StyledCopyableContentBody","StyledCopyableContentButton","copyableContentToClipboard","CopyableContent","content","children","copiedMessage","copyFailedMessage","rootRef","actionGroupRef","stickyActionPosition","defaultCopyButtonText","textstring","components","copyableContent","copy","defaultCopiedMessage","copied","defaultCopyFailedMessage","copyFailed","shareText","share","html","handleCopy","showCloseIcon","text","toastType","SUCCESS","type","TOAST","open","ERROR","createElement","className","ref","$fixedRight","fixedRight","$fixedTop","fixedTop","$isFixed","isFixed","$isSticky","isSticky","onClick","icons","link","shouldUseDefaultTriggerStyles","dangerouslySetInnerHTML","__html","displayName"],"sources":["../../../../src/components/copyable-content/CopyableContent.tsx"],"sourcesContent":["import { formatStringToHtml } from '@chayns-components/format';\nimport { ttsToITextString, useTextstringValue } from '@chayns-components/textstring';\nimport { createDialog, DialogType, ToastType } from 'chayns-api';\nimport React, { FC, ReactNode, useCallback, useMemo, useRef } from 'react';\nimport textStrings from '../../constants/textStrings';\nimport { useStickyActionPosition } from '../../hooks/useStickyActionPosition';\nimport SharingContextMenu from '../sharing-context-menu/SharingContextMenu';\nimport Icon from '../icon/Icon';\nimport {\n StyledCopyableContent,\n StyledCopyableContentActionGroup,\n StyledCopyableContentActions,\n StyledCopyableContentBody,\n StyledCopyableContentButton,\n} from './CopyableContent.styles';\nimport { copyableContentToClipboard } from './copyableContentClipboard';\n\nexport type CopyableContentProps = {\n content: string;\n children?: ReactNode;\n copiedMessage?: string;\n copyFailedMessage?: string;\n};\n\nconst CopyableContent: FC<CopyableContentProps> = ({\n content,\n children,\n copiedMessage,\n copyFailedMessage,\n}) => {\n const rootRef = useRef<HTMLElement>(null);\n const actionGroupRef = useRef<HTMLDivElement>(null);\n const stickyActionPosition = useStickyActionPosition(rootRef, actionGroupRef);\n\n const defaultCopyButtonText = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copy),\n });\n const defaultCopiedMessage = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copied),\n });\n const defaultCopyFailedMessage = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.copyFailed),\n });\n const shareText = useTextstringValue({\n textstring: ttsToITextString(textStrings.components.copyableContent.share),\n });\n\n const html = useMemo(() => formatStringToHtml(content).html, [content]);\n\n const handleCopy = useCallback(async () => {\n try {\n await copyableContentToClipboard(content);\n void createDialog({\n showCloseIcon: true,\n text: copiedMessage ?? defaultCopiedMessage,\n toastType: ToastType.SUCCESS,\n type: DialogType.TOAST,\n }).open();\n } catch {\n void createDialog({\n showCloseIcon: true,\n text: copyFailedMessage ?? defaultCopyFailedMessage,\n toastType: ToastType.ERROR,\n type: DialogType.TOAST,\n }).open();\n }\n }, [content, copiedMessage, defaultCopiedMessage, defaultCopyFailedMessage, copyFailedMessage]);\n\n return (\n <StyledCopyableContent className=\"copyable-content\" ref={rootRef}>\n <StyledCopyableContentActions\n $fixedRight={stickyActionPosition.fixedRight}\n $fixedTop={stickyActionPosition.fixedTop}\n $isFixed={stickyActionPosition.isFixed}\n ref={actionGroupRef}\n >\n <StyledCopyableContentActionGroup>\n <StyledCopyableContentButton\n $isSticky={stickyActionPosition.isSticky}\n aria-label={defaultCopyButtonText}\n onClick={() => {\n void handleCopy();\n }}\n type=\"button\"\n >\n <Icon icons={['fa-light fa-copy']} />\n </StyledCopyableContentButton>\n <SharingContextMenu link={content} shouldUseDefaultTriggerStyles={false}>\n <StyledCopyableContentButton\n $isSticky={stickyActionPosition.isSticky}\n aria-label={shareText}\n type=\"button\"\n >\n <Icon icons={['fa fa-share-nodes']} />\n </StyledCopyableContentButton>\n </SharingContextMenu>\n </StyledCopyableContentActionGroup>\n </StyledCopyableContentActions>\n <StyledCopyableContentBody>\n {children ?? <div dangerouslySetInnerHTML={{ __html: html }} />}\n </StyledCopyableContentBody>\n </StyledCopyableContent>\n );\n};\n\nCopyableContent.displayName = 'CopyableContent';\n\nexport default CopyableContent;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -26,15 +26,24 @@ export const StyledCopyableContent = styled.section`
|
|
|
26
26
|
}) => theme.text};
|
|
27
27
|
`;
|
|
28
28
|
export const StyledCopyableContentActions = styled.div`
|
|
29
|
-
position:
|
|
30
|
-
|
|
29
|
+
position: ${({
|
|
30
|
+
$isFixed
|
|
31
|
+
}) => $isFixed ? 'fixed' : 'sticky'};
|
|
32
|
+
top: ${({
|
|
33
|
+
$fixedTop,
|
|
34
|
+
$isFixed
|
|
35
|
+
}) => $isFixed ? `${$fixedTop}px` : 'var(--copyable-content-action-inset)'};
|
|
36
|
+
right: ${({
|
|
37
|
+
$fixedRight,
|
|
38
|
+
$isFixed
|
|
39
|
+
}) => $isFixed ? `${$fixedRight}px` : 'auto'};
|
|
31
40
|
z-index: 1;
|
|
32
41
|
display: flex;
|
|
33
42
|
justify-content: flex-end;
|
|
34
43
|
height: calc(var(--copyable-content-action-size) + var(--copyable-content-action-inset));
|
|
35
|
-
margin-top:
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
margin-top: ${({
|
|
45
|
+
$isFixed
|
|
46
|
+
}) => $isFixed ? '0' : 'calc((var(--copyable-content-action-size) + var(--copyable-content-action-inset)) * -1)'};
|
|
38
47
|
padding-right: var(--copyable-content-action-inset);
|
|
39
48
|
`;
|
|
40
49
|
export const StyledCopyableContentActionGroup = styled.div`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyableContent.styles.js","names":["styled","StyledCopyableContent","section","theme","cardBorderRadius","cardBackgroundOpacity","text","StyledCopyableContentActions","div","StyledCopyableContentActionGroup","StyledCopyableContentButton","button","$isSticky","buttonBackgroundColor","StyledCopyableContentBody","headline","primary"],"sources":["../../../../src/components/copyable-content/CopyableContent.styles.ts"],"sourcesContent":["import type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport styled from 'styled-components';\n\ntype StyledCopyableContentProps = WithTheme<unknown>;\n\nexport const StyledCopyableContent = styled.section<StyledCopyableContentProps>`\n --copyable-content-action-size: 32px;\n --copyable-content-action-inset: 8px;\n\n min-width: 0;\n max-width: 100%;\n overflow-x: clip;\n overflow-wrap: anywhere;\n padding-top: calc(\n var(--copyable-content-action-size) + var(--copyable-content-action-inset) * 2\n );\n border-radius: ${({ theme }) => theme.cardBorderRadius}px;\n background-color: rgba(\n ${({ theme }) => theme['secondary-100-rgb']},\n ${({ theme }) => theme.cardBackgroundOpacity}\n );\n color: ${({ theme }) => theme.text};\n`;\n\ntype StyledCopyableContentButtonProps = WithTheme<{\n $isSticky: boolean;\n}>;\n\nexport const StyledCopyableContentActions = styled.div<
|
|
1
|
+
{"version":3,"file":"CopyableContent.styles.js","names":["styled","StyledCopyableContent","section","theme","cardBorderRadius","cardBackgroundOpacity","text","StyledCopyableContentActions","div","$isFixed","$fixedTop","$fixedRight","StyledCopyableContentActionGroup","StyledCopyableContentButton","button","$isSticky","buttonBackgroundColor","StyledCopyableContentBody","headline","primary"],"sources":["../../../../src/components/copyable-content/CopyableContent.styles.ts"],"sourcesContent":["import type { WithTheme } from '../color-scheme-provider/ColorSchemeProvider';\nimport styled from 'styled-components';\n\ntype StyledCopyableContentProps = WithTheme<unknown>;\n\nexport const StyledCopyableContent = styled.section<StyledCopyableContentProps>`\n --copyable-content-action-size: 32px;\n --copyable-content-action-inset: 8px;\n\n min-width: 0;\n max-width: 100%;\n overflow-x: clip;\n overflow-wrap: anywhere;\n padding-top: calc(\n var(--copyable-content-action-size) + var(--copyable-content-action-inset) * 2\n );\n border-radius: ${({ theme }) => theme.cardBorderRadius}px;\n background-color: rgba(\n ${({ theme }) => theme['secondary-100-rgb']},\n ${({ theme }) => theme.cardBackgroundOpacity}\n );\n color: ${({ theme }) => theme.text};\n`;\n\ntype StyledCopyableContentButtonProps = WithTheme<{\n $isSticky: boolean;\n}>;\n\ntype StyledCopyableContentActionsProps = {\n $fixedRight: number;\n $fixedTop: number;\n $isFixed: boolean;\n};\n\nexport const StyledCopyableContentActions = styled.div<StyledCopyableContentActionsProps>`\n position: ${({ $isFixed }) => ($isFixed ? 'fixed' : 'sticky')};\n top: ${({ $fixedTop, $isFixed }) =>\n $isFixed ? `${$fixedTop}px` : 'var(--copyable-content-action-inset)'};\n right: ${({ $fixedRight, $isFixed }) => ($isFixed ? `${$fixedRight}px` : 'auto')};\n z-index: 1;\n display: flex;\n justify-content: flex-end;\n height: calc(var(--copyable-content-action-size) + var(--copyable-content-action-inset));\n margin-top: ${({ $isFixed }) =>\n $isFixed\n ? '0'\n : 'calc((var(--copyable-content-action-size) + var(--copyable-content-action-inset)) * -1)'};\n padding-right: var(--copyable-content-action-inset);\n`;\n\nexport const StyledCopyableContentActionGroup = styled.div`\n display: flex;\n gap: 4px;\n height: var(--copyable-content-action-size);\n`;\n\nexport const StyledCopyableContentButton = styled.button<StyledCopyableContentButtonProps>`\n box-sizing: border-box;\n border: 1px solid ${({ $isSticky, theme }) => ($isSticky ? theme['202'] : 'transparent')};\n border-radius: 4px;\n width: var(--copyable-content-action-size);\n height: var(--copyable-content-action-size);\n padding: 0;\n cursor: pointer;\n background-color: ${({ $isSticky, theme }) => ($isSticky ? theme['100'] : 'transparent')};\n color: ${({ theme }) => theme.text};\n box-shadow: ${({ $isSticky }) => ($isSticky ? '0 2px 8px rgba(0, 0, 0, 0.16)' : 'none')};\n transition:\n background-color 0.15s ease,\n border-color 0.15s ease,\n box-shadow 0.15s ease,\n transform 0.15s ease;\n\n &:hover {\n background-color: rgba(${({ theme }) => theme['text-rgb']}, 0.1);\n box-shadow: inset 0 0 0 1px rgba(${({ theme }) => theme['text-rgb']}, 0.06);\n }\n\n &:active {\n transform: scale(0.9);\n }\n\n &:focus-visible {\n outline: 2px solid ${({ theme }) => theme.buttonBackgroundColor};\n outline-offset: 2px;\n }\n`;\n\nexport const StyledCopyableContentBody = styled.div<StyledCopyableContentProps>`\n min-width: 0;\n max-width: 100%;\n overflow-wrap: anywhere;\n padding: 0 12px 12px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6,\n p,\n ul,\n ol,\n blockquote {\n margin: 0 0 12px;\n }\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n color: ${({ theme }) => theme.headline};\n }\n\n ul,\n ol {\n padding-left: 24px;\n }\n\n blockquote {\n padding-left: 12px;\n border-left: 3px solid ${({ theme }) => theme['202']};\n }\n\n a {\n color: ${({ theme }) => theme.primary};\n overflow-wrap: anywhere;\n }\n\n > :last-child {\n margin-bottom: 0;\n }\n`;\n"],"mappings":"AACA,OAAOA,MAAM,MAAM,mBAAmB;AAItC,OAAO,MAAMC,qBAAqB,GAAGD,MAAM,CAACE,OAAmC;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,CAAC;EAAEC;AAAM,CAAC,KAAKA,KAAK,CAACC,gBAAgB;AAC1D;AACA,UAAU,CAAC;EAAED;AAAM,CAAC,KAAKA,KAAK,CAAC,mBAAmB,CAAC;AACnD,UAAU,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK,CAACE,qBAAqB;AACpD;AACA,aAAa,CAAC;EAAEF;AAAM,CAAC,KAAKA,KAAK,CAACG,IAAI;AACtC,CAAC;AAYD,OAAO,MAAMC,4BAA4B,GAAGP,MAAM,CAACQ,GAAsC;AACzF,gBAAgB,CAAC;EAAEC;AAAS,CAAC,KAAMA,QAAQ,GAAG,OAAO,GAAG,QAAS;AACjE,WAAW,CAAC;EAAEC,SAAS;EAAED;AAAS,CAAC,KAC3BA,QAAQ,GAAG,GAAGC,SAAS,IAAI,GAAG,sCAAsC;AAC5E,aAAa,CAAC;EAAEC,WAAW;EAAEF;AAAS,CAAC,KAAMA,QAAQ,GAAG,GAAGE,WAAW,IAAI,GAAG,MAAO;AACpF;AACA;AACA;AACA;AACA,kBAAkB,CAAC;EAAEF;AAAS,CAAC,KACvBA,QAAQ,GACF,GAAG,GACH,yFAAyF;AACvG;AACA,CAAC;AAED,OAAO,MAAMG,gCAAgC,GAAGZ,MAAM,CAACQ,GAAG;AAC1D;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMK,2BAA2B,GAAGb,MAAM,CAACc,MAAwC;AAC1F;AACA,wBAAwB,CAAC;EAAEC,SAAS;EAAEZ;AAAM,CAAC,KAAMY,SAAS,GAAGZ,KAAK,CAAC,KAAK,CAAC,GAAG,aAAc;AAC5F;AACA;AACA;AACA;AACA;AACA,wBAAwB,CAAC;EAAEY,SAAS;EAAEZ;AAAM,CAAC,KAAMY,SAAS,GAAGZ,KAAK,CAAC,KAAK,CAAC,GAAG,aAAc;AAC5F,aAAa,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK,CAACG,IAAI;AACtC,kBAAkB,CAAC;EAAES;AAAU,CAAC,KAAMA,SAAS,GAAG,+BAA+B,GAAG,MAAO;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,CAAC;EAAEZ;AAAM,CAAC,KAAKA,KAAK,CAAC,UAAU,CAAC;AACjE,2CAA2C,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK,CAAC,UAAU,CAAC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK,CAACa,qBAAqB;AACvE;AACA;AACA,CAAC;AAED,OAAO,MAAMC,yBAAyB,GAAGjB,MAAM,CAACQ,GAA+B;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,CAAC;EAAEL;AAAM,CAAC,KAAKA,KAAK,CAACe,QAAQ;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,CAAC;EAAEf;AAAM,CAAC,KAAKA,KAAK,CAAC,KAAK,CAAC;AAC5D;AACA;AACA;AACA,iBAAiB,CAAC;EAAEA;AAAM,CAAC,KAAKA,KAAK,CAACgB,OAAO;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
const STICKY_ACTION_INSET = 8;
|
|
3
|
+
const STICKY_ACTION_SIZE = 32;
|
|
4
|
+
const initialPosition = {
|
|
5
|
+
fixedRight: 0,
|
|
6
|
+
fixedTop: STICKY_ACTION_INSET,
|
|
7
|
+
isFixed: false,
|
|
8
|
+
isSticky: false
|
|
9
|
+
};
|
|
10
|
+
const isScrollable = element => {
|
|
11
|
+
const {
|
|
12
|
+
overflow,
|
|
13
|
+
overflowY
|
|
14
|
+
} = window.getComputedStyle(element);
|
|
15
|
+
return /auto|scroll|overlay/.test(`${overflow} ${overflowY}`);
|
|
16
|
+
};
|
|
17
|
+
const getScrollableAncestor = element => {
|
|
18
|
+
let parent = element.parentElement;
|
|
19
|
+
while (parent) {
|
|
20
|
+
if (isScrollable(parent)) {
|
|
21
|
+
return parent;
|
|
22
|
+
}
|
|
23
|
+
parent = parent.parentElement;
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Keeps an action group visible inside the nearest nested scroll container.
|
|
30
|
+
* Native sticky positioning is retained for document scrolling; a fixed-position
|
|
31
|
+
* fallback only applies when the component is hosted in an element scroll container.
|
|
32
|
+
*/
|
|
33
|
+
export const useStickyActionPosition = (rootRef, actionRef) => {
|
|
34
|
+
const [position, setPosition] = useState(initialPosition);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const root = rootRef.current;
|
|
37
|
+
const action = actionRef.current;
|
|
38
|
+
if (!root || !action) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const scrollContainer = getScrollableAncestor(root);
|
|
42
|
+
const updatePosition = () => {
|
|
43
|
+
const rootRect = root.getBoundingClientRect();
|
|
44
|
+
const containerTop = scrollContainer?.getBoundingClientRect().top ?? 0;
|
|
45
|
+
const fixedTop = containerTop + STICKY_ACTION_INSET;
|
|
46
|
+
const isSticky = rootRect.top <= fixedTop;
|
|
47
|
+
const isFixed = Boolean(scrollContainer && isSticky && rootRect.bottom > fixedTop + STICKY_ACTION_SIZE);
|
|
48
|
+
const fixedRight = Math.max(0, window.innerWidth - rootRect.right);
|
|
49
|
+
setPosition(currentPosition => {
|
|
50
|
+
if (currentPosition.fixedRight === fixedRight && currentPosition.fixedTop === fixedTop && currentPosition.isFixed === isFixed && currentPosition.isSticky === isSticky) {
|
|
51
|
+
return currentPosition;
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
fixedRight,
|
|
55
|
+
fixedTop,
|
|
56
|
+
isFixed,
|
|
57
|
+
isSticky
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
updatePosition();
|
|
62
|
+
scrollContainer?.addEventListener('scroll', updatePosition, {
|
|
63
|
+
passive: true
|
|
64
|
+
});
|
|
65
|
+
window.addEventListener('scroll', updatePosition, {
|
|
66
|
+
passive: true
|
|
67
|
+
});
|
|
68
|
+
window.addEventListener('resize', updatePosition);
|
|
69
|
+
const resizeObserver = typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(updatePosition);
|
|
70
|
+
resizeObserver?.observe(root);
|
|
71
|
+
if (scrollContainer) {
|
|
72
|
+
resizeObserver?.observe(scrollContainer);
|
|
73
|
+
}
|
|
74
|
+
return () => {
|
|
75
|
+
scrollContainer?.removeEventListener('scroll', updatePosition);
|
|
76
|
+
window.removeEventListener('scroll', updatePosition);
|
|
77
|
+
window.removeEventListener('resize', updatePosition);
|
|
78
|
+
resizeObserver?.disconnect();
|
|
79
|
+
};
|
|
80
|
+
}, [actionRef, rootRef]);
|
|
81
|
+
return position;
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=useStickyActionPosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStickyActionPosition.js","names":["useEffect","useState","STICKY_ACTION_INSET","STICKY_ACTION_SIZE","initialPosition","fixedRight","fixedTop","isFixed","isSticky","isScrollable","element","overflow","overflowY","window","getComputedStyle","test","getScrollableAncestor","parent","parentElement","undefined","useStickyActionPosition","rootRef","actionRef","position","setPosition","root","current","action","scrollContainer","updatePosition","rootRect","getBoundingClientRect","containerTop","top","Boolean","bottom","Math","max","innerWidth","right","currentPosition","addEventListener","passive","resizeObserver","ResizeObserver","observe","removeEventListener","disconnect"],"sources":["../../../src/hooks/useStickyActionPosition.ts"],"sourcesContent":["import { RefObject, useEffect, useState } from 'react';\n\nconst STICKY_ACTION_INSET = 8;\nconst STICKY_ACTION_SIZE = 32;\n\ntype StickyActionPosition = {\n fixedRight: number;\n fixedTop: number;\n isFixed: boolean;\n isSticky: boolean;\n};\n\nconst initialPosition: StickyActionPosition = {\n fixedRight: 0,\n fixedTop: STICKY_ACTION_INSET,\n isFixed: false,\n isSticky: false,\n};\n\nconst isScrollable = (element: HTMLElement) => {\n const { overflow, overflowY } = window.getComputedStyle(element);\n\n return /auto|scroll|overlay/.test(`${overflow} ${overflowY}`);\n};\n\nconst getScrollableAncestor = (element: HTMLElement) => {\n let parent = element.parentElement;\n\n while (parent) {\n if (isScrollable(parent)) {\n return parent;\n }\n\n parent = parent.parentElement;\n }\n\n return undefined;\n};\n\n/**\n * Keeps an action group visible inside the nearest nested scroll container.\n * Native sticky positioning is retained for document scrolling; a fixed-position\n * fallback only applies when the component is hosted in an element scroll container.\n */\nexport const useStickyActionPosition = (\n rootRef: RefObject<HTMLElement>,\n actionRef: RefObject<HTMLElement>,\n): StickyActionPosition => {\n const [position, setPosition] = useState<StickyActionPosition>(initialPosition);\n\n useEffect(() => {\n const root = rootRef.current;\n const action = actionRef.current;\n\n if (!root || !action) {\n return undefined;\n }\n\n const scrollContainer = getScrollableAncestor(root);\n\n const updatePosition = () => {\n const rootRect = root.getBoundingClientRect();\n const containerTop = scrollContainer?.getBoundingClientRect().top ?? 0;\n const fixedTop = containerTop + STICKY_ACTION_INSET;\n const isSticky = rootRect.top <= fixedTop;\n const isFixed = Boolean(\n scrollContainer && isSticky && rootRect.bottom > fixedTop + STICKY_ACTION_SIZE,\n );\n const fixedRight = Math.max(0, window.innerWidth - rootRect.right);\n\n setPosition((currentPosition) => {\n if (\n currentPosition.fixedRight === fixedRight &&\n currentPosition.fixedTop === fixedTop &&\n currentPosition.isFixed === isFixed &&\n currentPosition.isSticky === isSticky\n ) {\n return currentPosition;\n }\n\n return { fixedRight, fixedTop, isFixed, isSticky };\n });\n };\n\n updatePosition();\n scrollContainer?.addEventListener('scroll', updatePosition, { passive: true });\n window.addEventListener('scroll', updatePosition, { passive: true });\n window.addEventListener('resize', updatePosition);\n\n const resizeObserver =\n typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(updatePosition);\n resizeObserver?.observe(root);\n\n if (scrollContainer) {\n resizeObserver?.observe(scrollContainer);\n }\n\n return () => {\n scrollContainer?.removeEventListener('scroll', updatePosition);\n window.removeEventListener('scroll', updatePosition);\n window.removeEventListener('resize', updatePosition);\n resizeObserver?.disconnect();\n };\n }, [actionRef, rootRef]);\n\n return position;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,11 +3,12 @@ export declare const StyledCopyableContent: import("styled-components/dist/types
|
|
|
3
3
|
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "theme"> & {
|
|
4
4
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
5
5
|
}, never>>> & string;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
6
|
+
type StyledCopyableContentActionsProps = {
|
|
7
|
+
$fixedRight: number;
|
|
8
|
+
$fixedTop: number;
|
|
9
|
+
$isFixed: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const StyledCopyableContentActions: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof StyledCopyableContentActionsProps> & StyledCopyableContentActionsProps, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof StyledCopyableContentActionsProps> & StyledCopyableContentActionsProps, never>>> & string;
|
|
11
12
|
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;
|
|
12
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"> & {
|
|
13
14
|
$isSticky: boolean;
|
|
@@ -23,3 +24,4 @@ export declare const StyledCopyableContentBody: import("styled-components/dist/t
|
|
|
23
24
|
}, never> & Partial<Pick<import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "theme"> & {
|
|
24
25
|
theme: import("../color-scheme-provider/ColorSchemeProvider").Theme;
|
|
25
26
|
}, never>>> & string;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
type StickyActionPosition = {
|
|
3
|
+
fixedRight: number;
|
|
4
|
+
fixedTop: number;
|
|
5
|
+
isFixed: boolean;
|
|
6
|
+
isSticky: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Keeps an action group visible inside the nearest nested scroll container.
|
|
10
|
+
* Native sticky positioning is retained for document scrolling; a fixed-position
|
|
11
|
+
* fallback only applies when the component is hosted in an element scroll container.
|
|
12
|
+
*/
|
|
13
|
+
export declare const useStickyActionPosition: (rootRef: RefObject<HTMLElement>, actionRef: RefObject<HTMLElement>) => StickyActionPosition;
|
|
14
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chayns-components/core",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.10",
|
|
4
4
|
"description": "A set of beautiful React components for developing your own applications with chayns.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"browserslist": [
|
|
@@ -94,5 +94,5 @@
|
|
|
94
94
|
"publishConfig": {
|
|
95
95
|
"access": "public"
|
|
96
96
|
},
|
|
97
|
-
"gitHead": "
|
|
97
|
+
"gitHead": "ada2a8d95d50f5fb2761a73d1db59659bdbd2491"
|
|
98
98
|
}
|