@spaced-out/ui-design-system 0.2.0 → 0.2.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/lib/components/SideMenuLink/SideMenuLink.js +5 -3
- package/lib/components/SideMenuLink/SideMenuLink.js.flow +7 -3
- package/lib/components/TruncatedTextWithTooltip/TruncatedTextWithTooltip.js +28 -45
- package/lib/components/TruncatedTextWithTooltip/TruncatedTextWithTooltip.js.flow +40 -63
- package/lib/components/TruncatedTextWithTooltip/TruncatedTextWithTooltip.module.css +3 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.2.2-beta.0](https://github.com/spaced-out/ui-design-system/compare/v0.2.1...v0.2.2-beta.0) (2024-09-30)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* support lines in truncate text with tooltip ([#272](https://github.com/spaced-out/ui-design-system/issues/272)) ([e8e4d3c](https://github.com/spaced-out/ui-design-system/commit/e8e4d3c3def11b2efd9f86f43ec03197891b1cb5))
|
|
11
|
+
|
|
12
|
+
### [0.2.1](https://github.com/spaced-out/ui-design-system/compare/v0.2.0...v0.2.1) (2024-09-30)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* 🖼️ support for custom text in sidemenu link component ([#271](https://github.com/spaced-out/ui-design-system/issues/271)) ([3fd98b8](https://github.com/spaced-out/ui-design-system/commit/3fd98b8ba58c1b60b164a1d43ea5a47c503eaed1))
|
|
18
|
+
|
|
5
19
|
## [0.2.0](https://github.com/spaced-out/ui-design-system/compare/v0.1.130...v0.2.0) (2024-09-27)
|
|
6
20
|
|
|
7
21
|
|
|
@@ -194,6 +194,7 @@ const SideMenuLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
194
194
|
linkComponent: LinkComponent,
|
|
195
195
|
rightSlot,
|
|
196
196
|
to,
|
|
197
|
+
customTitle,
|
|
197
198
|
...restButtonProps
|
|
198
199
|
} = _ref;
|
|
199
200
|
const selected = selectedValue === pageNameKey;
|
|
@@ -201,6 +202,7 @@ const SideMenuLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
201
202
|
const onChangeHandler = e => {
|
|
202
203
|
onChange && onChange(e, pageNameKey);
|
|
203
204
|
};
|
|
205
|
+
const linkTitle = customTitle || MENU_NAME_LIST[pageNameKey].title;
|
|
204
206
|
return /*#__PURE__*/React.createElement(_ConditionalWrapper.ConditionalWrapper, {
|
|
205
207
|
condition: to !== undefined,
|
|
206
208
|
wrapper: children => /*#__PURE__*/React.createElement(_Link.Link, {
|
|
@@ -215,7 +217,7 @@ const SideMenuLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
215
217
|
}, /*#__PURE__*/React.createElement(_ConditionalWrapper.ConditionalWrapper, {
|
|
216
218
|
condition: Boolean(!opened && !inActive),
|
|
217
219
|
wrapper: children => /*#__PURE__*/React.createElement(_Tooltip.Tooltip, _extends({
|
|
218
|
-
body:
|
|
220
|
+
body: linkTitle
|
|
219
221
|
}, tooltip), children)
|
|
220
222
|
}, /*#__PURE__*/React.createElement(_Button.UnstyledButton, _extends({}, restButtonProps, {
|
|
221
223
|
className: (0, _classify.default)(_SideMenuLinkModule.default.linkWrapper, {
|
|
@@ -239,9 +241,9 @@ const SideMenuLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
239
241
|
className: _SideMenuLinkModule.default.menuLabelContainer
|
|
240
242
|
}, pageNameKey && MENU_NAME_LIST[pageNameKey] ? isGroupMenuLink ? /*#__PURE__*/React.createElement(_Text.SubTitleSmall, {
|
|
241
243
|
className: _SideMenuLinkModule.default.groupMenuLinkText
|
|
242
|
-
},
|
|
244
|
+
}, linkTitle) : /*#__PURE__*/React.createElement(_Text.BodyMedium, {
|
|
243
245
|
className: _SideMenuLinkModule.default.menuLinkText
|
|
244
|
-
},
|
|
246
|
+
}, linkTitle) : null, rightSlot ? rightSlot : null) : null)));
|
|
245
247
|
});
|
|
246
248
|
exports.SideMenuLink = SideMenuLink;
|
|
247
249
|
SideMenuLink.displayName = 'SideMenuLink';
|
|
@@ -183,6 +183,7 @@ type ClassNames = $ReadOnly<{wrapper?: string}>;
|
|
|
183
183
|
export type SideMenuLinkProps = {
|
|
184
184
|
classNames?: ClassNames,
|
|
185
185
|
children?: React.Node,
|
|
186
|
+
customTitle?: string,
|
|
186
187
|
pageNameKey: string,
|
|
187
188
|
disabled?: boolean,
|
|
188
189
|
hovered?: boolean,
|
|
@@ -216,6 +217,7 @@ export const SideMenuLink: React$AbstractComponent<
|
|
|
216
217
|
linkComponent: LinkComponent,
|
|
217
218
|
rightSlot,
|
|
218
219
|
to,
|
|
220
|
+
customTitle,
|
|
219
221
|
...restButtonProps
|
|
220
222
|
}: SideMenuLinkProps,
|
|
221
223
|
ref,
|
|
@@ -226,6 +228,8 @@ export const SideMenuLink: React$AbstractComponent<
|
|
|
226
228
|
onChange && onChange(e, pageNameKey);
|
|
227
229
|
};
|
|
228
230
|
|
|
231
|
+
const linkTitle = customTitle || MENU_NAME_LIST[pageNameKey].title;
|
|
232
|
+
|
|
229
233
|
return (
|
|
230
234
|
<ConditionalWrapper
|
|
231
235
|
condition={to !== undefined}
|
|
@@ -246,7 +250,7 @@ export const SideMenuLink: React$AbstractComponent<
|
|
|
246
250
|
<ConditionalWrapper
|
|
247
251
|
condition={Boolean(!opened && !inActive)}
|
|
248
252
|
wrapper={(children) => (
|
|
249
|
-
<Tooltip body={
|
|
253
|
+
<Tooltip body={linkTitle} {...tooltip}>
|
|
250
254
|
{children}
|
|
251
255
|
</Tooltip>
|
|
252
256
|
)}
|
|
@@ -283,11 +287,11 @@ export const SideMenuLink: React$AbstractComponent<
|
|
|
283
287
|
{pageNameKey && MENU_NAME_LIST[pageNameKey] ? (
|
|
284
288
|
isGroupMenuLink ? (
|
|
285
289
|
<SubTitleSmall className={css.groupMenuLinkText}>
|
|
286
|
-
{
|
|
290
|
+
{linkTitle}
|
|
287
291
|
</SubTitleSmall>
|
|
288
292
|
) : (
|
|
289
293
|
<BodyMedium className={css.menuLinkText}>
|
|
290
|
-
{
|
|
294
|
+
{linkTitle}
|
|
291
295
|
</BodyMedium>
|
|
292
296
|
)
|
|
293
297
|
) : null}
|
|
@@ -6,8 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.TruncatedTextWithTooltip = void 0;
|
|
7
7
|
var React = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _debounce = _interopRequireDefault(require("lodash/debounce"));
|
|
9
|
-
var
|
|
9
|
+
var _useWindowSize = require("../../hooks/useWindowSize");
|
|
10
10
|
var _classify = _interopRequireDefault(require("../../utils/classify"));
|
|
11
|
+
var _ConditionalWrapper = require("../ConditionalWrapper");
|
|
11
12
|
var _Tooltip = require("../Tooltip");
|
|
12
13
|
var _TruncatedTextWithTooltipModule = _interopRequireDefault(require("./TruncatedTextWithTooltip.module.css"));
|
|
13
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -20,57 +21,39 @@ const TruncatedTextWithTooltip = _ref => {
|
|
|
20
21
|
children,
|
|
21
22
|
tooltip,
|
|
22
23
|
wrapText = false,
|
|
24
|
+
line = 1,
|
|
25
|
+
wordBreak = 'break-all',
|
|
23
26
|
...props
|
|
24
27
|
} = _ref;
|
|
28
|
+
const {
|
|
29
|
+
width
|
|
30
|
+
} = (0, _useWindowSize.useWindowSize)();
|
|
25
31
|
const [showMouseTip, setShowMouseTip] = React.useState(false);
|
|
26
32
|
const truncatedRef = React.useRef();
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
const checkIfTextOverflowing = React.useMemo(() => (0, _debounce.default)(() => {
|
|
34
|
+
if (!wrapText && truncatedRef && truncatedRef.current && truncatedRef.current.scrollHeight > truncatedRef.current.clientHeight) {
|
|
35
|
+
setShowMouseTip(true);
|
|
36
|
+
} else {
|
|
37
|
+
setShowMouseTip(false);
|
|
31
38
|
}
|
|
32
39
|
}, 200), []);
|
|
33
|
-
|
|
34
|
-
// Running only on mount and unmount
|
|
35
|
-
React.useEffect(() => {
|
|
36
|
-
const span = truncatedRef.current;
|
|
37
|
-
if (span) {
|
|
38
|
-
// Note(Nishant): This is a fix for the issue where the parent width is not set
|
|
39
|
-
// explicitly by the calling component, for truncation to work the parent wrapper should
|
|
40
|
-
// have a defined width. For cases where width is not set the component would set the
|
|
41
|
-
// width of the parent to 100%(sizeFluid) for the auto truncation to kick in
|
|
42
|
-
const parent = span.parentNode;
|
|
43
|
-
if (parent && parent instanceof HTMLElement) {
|
|
44
|
-
const computedStyles = window.getComputedStyle(parent);
|
|
45
|
-
const computedWidth = computedStyles.getPropertyValue('width');
|
|
46
|
-
const clientWidth = parent.clientWidth;
|
|
47
|
-
if (computedWidth !== `${clientWidth}px`) {
|
|
48
|
-
// Set the parent width to 100% if not explicitly set
|
|
49
|
-
parent.style.width = _size.sizeFluid;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
window.addEventListener('resize', checkWidths);
|
|
54
|
-
return () => {
|
|
55
|
-
window.removeEventListener('resize', checkWidths);
|
|
56
|
-
};
|
|
57
|
-
}, [checkWidths]);
|
|
58
40
|
React.useEffect(() => {
|
|
59
|
-
|
|
60
|
-
}, [children]);
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
41
|
+
checkIfTextOverflowing();
|
|
42
|
+
}, [width, line, children, wrapText]);
|
|
43
|
+
const styles = {
|
|
44
|
+
'--line-clamp': wrapText ? 'unset' : line,
|
|
45
|
+
'--word-break': wordBreak
|
|
46
|
+
};
|
|
47
|
+
return /*#__PURE__*/React.createElement(_ConditionalWrapper.ConditionalWrapper, {
|
|
48
|
+
condition: Boolean(showMouseTip),
|
|
49
|
+
wrapper: children => /*#__PURE__*/React.createElement(_Tooltip.Tooltip, _extends({}, tooltip, {
|
|
50
|
+
body: tooltip?.body ?? children,
|
|
51
|
+
elevation: tooltip?.elevation ?? 'toast'
|
|
52
|
+
}), children)
|
|
53
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
54
|
+
className: (0, _classify.default)(_TruncatedTextWithTooltipModule.default.truncateLineClamp, classNames?.wrapper),
|
|
55
|
+
style: styles,
|
|
72
56
|
ref: truncatedRef
|
|
73
|
-
}
|
|
74
|
-
return content;
|
|
57
|
+
}, children));
|
|
75
58
|
};
|
|
76
59
|
exports.TruncatedTextWithTooltip = TruncatedTextWithTooltip;
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import debounce from 'lodash/debounce';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {useWindowSize} from '../../hooks/useWindowSize';
|
|
7
7
|
import classify from '../../utils/classify';
|
|
8
|
+
import {ConditionalWrapper} from '../ConditionalWrapper';
|
|
8
9
|
import type {BaseTooltipProps} from '../Tooltip';
|
|
9
10
|
import {Tooltip} from '../Tooltip';
|
|
10
11
|
|
|
@@ -17,6 +18,8 @@ export type TruncatedTextWithTooltipProps = {
|
|
|
17
18
|
children?: React.Node,
|
|
18
19
|
tooltip?: BaseTooltipProps,
|
|
19
20
|
classNames?: ClassNames,
|
|
21
|
+
line?: number,
|
|
22
|
+
wordBreak?: string,
|
|
20
23
|
wrapText?: boolean,
|
|
21
24
|
...
|
|
22
25
|
};
|
|
@@ -26,85 +29,59 @@ export const TruncatedTextWithTooltip = ({
|
|
|
26
29
|
children,
|
|
27
30
|
tooltip,
|
|
28
31
|
wrapText = false,
|
|
32
|
+
line = 1,
|
|
33
|
+
wordBreak = 'break-all',
|
|
29
34
|
...props
|
|
30
35
|
}: TruncatedTextWithTooltipProps): React.Node => {
|
|
36
|
+
const {width} = useWindowSize();
|
|
31
37
|
const [showMouseTip, setShowMouseTip] = React.useState(false);
|
|
32
38
|
const truncatedRef = React.useRef<?HTMLSpanElement>();
|
|
33
39
|
|
|
34
|
-
const
|
|
40
|
+
const checkIfTextOverflowing = React.useMemo(
|
|
35
41
|
() =>
|
|
36
42
|
debounce(() => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
if (
|
|
44
|
+
!wrapText &&
|
|
45
|
+
truncatedRef &&
|
|
46
|
+
truncatedRef.current &&
|
|
47
|
+
truncatedRef.current.scrollHeight > truncatedRef.current.clientHeight
|
|
48
|
+
) {
|
|
49
|
+
setShowMouseTip(true);
|
|
50
|
+
} else {
|
|
51
|
+
setShowMouseTip(false);
|
|
41
52
|
}
|
|
42
53
|
}, 200),
|
|
43
54
|
[],
|
|
44
55
|
);
|
|
45
|
-
|
|
46
|
-
// Running only on mount and unmount
|
|
47
|
-
React.useEffect(() => {
|
|
48
|
-
const span = truncatedRef.current;
|
|
49
|
-
|
|
50
|
-
if (span) {
|
|
51
|
-
// Note(Nishant): This is a fix for the issue where the parent width is not set
|
|
52
|
-
// explicitly by the calling component, for truncation to work the parent wrapper should
|
|
53
|
-
// have a defined width. For cases where width is not set the component would set the
|
|
54
|
-
// width of the parent to 100%(sizeFluid) for the auto truncation to kick in
|
|
55
|
-
const parent = span.parentNode;
|
|
56
|
-
if (parent && parent instanceof HTMLElement) {
|
|
57
|
-
const computedStyles = window.getComputedStyle(parent);
|
|
58
|
-
const computedWidth = computedStyles.getPropertyValue('width');
|
|
59
|
-
const clientWidth = parent.clientWidth;
|
|
60
|
-
|
|
61
|
-
if (computedWidth !== `${clientWidth}px`) {
|
|
62
|
-
// Set the parent width to 100% if not explicitly set
|
|
63
|
-
parent.style.width = sizeFluid;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
window.addEventListener('resize', checkWidths);
|
|
69
|
-
|
|
70
|
-
return () => {
|
|
71
|
-
window.removeEventListener('resize', checkWidths);
|
|
72
|
-
};
|
|
73
|
-
}, [checkWidths]);
|
|
74
|
-
|
|
75
56
|
React.useEffect(() => {
|
|
76
|
-
|
|
77
|
-
}, [children]);
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
57
|
+
checkIfTextOverflowing();
|
|
58
|
+
}, [width, line, children, wrapText]);
|
|
59
|
+
|
|
60
|
+
const styles = {
|
|
61
|
+
'--line-clamp': wrapText ? 'unset' : line,
|
|
62
|
+
'--word-break': wordBreak,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<ConditionalWrapper
|
|
67
|
+
condition={Boolean(showMouseTip)}
|
|
68
|
+
wrapper={(children) => (
|
|
69
|
+
<Tooltip
|
|
70
|
+
{...tooltip}
|
|
71
|
+
body={tooltip?.body ?? children}
|
|
72
|
+
elevation={tooltip?.elevation ?? 'toast'}
|
|
73
|
+
>
|
|
74
|
+
{children}
|
|
75
|
+
</Tooltip>
|
|
76
|
+
)}
|
|
84
77
|
>
|
|
85
78
|
<span
|
|
86
|
-
{
|
|
87
|
-
|
|
79
|
+
className={classify(css.truncateLineClamp, classNames?.wrapper)}
|
|
80
|
+
style={styles}
|
|
88
81
|
ref={truncatedRef}
|
|
89
82
|
>
|
|
90
83
|
{children}
|
|
91
84
|
</span>
|
|
92
|
-
</
|
|
93
|
-
) : (
|
|
94
|
-
<span
|
|
95
|
-
{...props}
|
|
96
|
-
className={classify(
|
|
97
|
-
{
|
|
98
|
-
[css.truncatedText]: !wrapText,
|
|
99
|
-
[css.wrapText]: wrapText,
|
|
100
|
-
},
|
|
101
|
-
classNames?.wrapper,
|
|
102
|
-
)}
|
|
103
|
-
ref={truncatedRef}
|
|
104
|
-
>
|
|
105
|
-
{children}
|
|
106
|
-
</span>
|
|
85
|
+
</ConditionalWrapper>
|
|
107
86
|
);
|
|
108
|
-
|
|
109
|
-
return content;
|
|
110
87
|
};
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
display: flex;
|
|
5
|
-
width: sizeFluid;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.truncatedText {
|
|
9
|
-
width: sizeFluid;
|
|
10
|
-
text-overflow: ellipsis;
|
|
11
|
-
overflow: hidden;
|
|
12
|
-
white-space: nowrap;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.wrapText,
|
|
16
|
-
.truncatedText {
|
|
17
|
-
width: sizeFluid;
|
|
1
|
+
.truncateLineClamp {
|
|
2
|
+
composes: truncate from '../../styles/typography.module.css';
|
|
3
|
+
white-space: normal;
|
|
18
4
|
}
|