@spaced-out/ui-design-system 0.1.121 → 0.1.123
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 +15 -0
- package/lib/components/Input/Input.js +4 -2
- package/lib/components/Input/Input.js.flow +12 -4
- package/lib/components/Input/Input.module.css +12 -0
- package/lib/components/PageTitle/PageTitle.js +3 -1
- package/lib/components/PageTitle/PageTitle.js.flow +5 -1
- package/lib/components/RangeSlider/RangeSlider.js +43 -4
- package/lib/components/RangeSlider/RangeSlider.js.flow +61 -3
- package/lib/components/RangeSlider/RangeSlider.module.css +19 -3
- package/lib/components/SideMenuLink/SideMenuLink.js +21 -4
- package/lib/components/SideMenuLink/SideMenuLink.js.flow +72 -38
- package/lib/components/SideMenuLink/SideMenuLink.module.css +29 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
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.1.123](https://github.com/spaced-out/ui-design-system/compare/v0.1.122...v0.1.123) (2024-08-26)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* [GDS-429] side menu link accordion and href inclusion ([#251](https://github.com/spaced-out/ui-design-system/issues/251)) ([e54f712](https://github.com/spaced-out/ui-design-system/commit/e54f712b6e450c80ca70aad3565fe1be8820bbb9))
|
|
11
|
+
|
|
12
|
+
### [0.1.122](https://github.com/spaced-out/ui-design-system/compare/v0.1.121...v0.1.122) (2024-08-22)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* ↕️ added option to hide spinner for number input, exposes wrapper classname for input ([05267ee](https://github.com/spaced-out/ui-design-system/commit/05267eeef9dd984d5e6d6030f778ed197d518cf0))
|
|
18
|
+
* 🛝 slider enhancements to add value input in the right slot, min max range indicators as config ([eecd31a](https://github.com/spaced-out/ui-design-system/commit/eecd31ae53dd460f08d7c31ea648d0aa20d3ca1d))
|
|
19
|
+
|
|
5
20
|
### [0.1.121](https://github.com/spaced-out/ui-design-system/compare/v0.1.120...v0.1.121) (2024-08-20)
|
|
6
21
|
|
|
7
22
|
|
|
@@ -59,6 +59,7 @@ const Input_ = (props, ref) => {
|
|
|
59
59
|
boxRef,
|
|
60
60
|
onKeyDown,
|
|
61
61
|
disallowExponents,
|
|
62
|
+
hideNumberSpinner,
|
|
62
63
|
...inputProps
|
|
63
64
|
} = props;
|
|
64
65
|
const [showPassword, setShowPassword] = React.useState(false);
|
|
@@ -84,7 +85,7 @@ const Input_ = (props, ref) => {
|
|
|
84
85
|
className: (0, _classify.classify)(_InputModule.default.wrapper, {
|
|
85
86
|
[_InputModule.default.filled]: controlledInputFilled ?? false,
|
|
86
87
|
[_InputModule.default.withError]: error ?? false
|
|
87
|
-
})
|
|
88
|
+
}, classNames?.wrapper)
|
|
88
89
|
}, Boolean(label) && /*#__PURE__*/React.createElement("div", {
|
|
89
90
|
className: _InputModule.default.info
|
|
90
91
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -99,7 +100,8 @@ const Input_ = (props, ref) => {
|
|
|
99
100
|
[_InputModule.default.medium]: size === 'medium',
|
|
100
101
|
[_InputModule.default.small]: size === 'small',
|
|
101
102
|
[_InputModule.default.locked]: locked,
|
|
102
|
-
[_InputModule.default.color]: type === 'color'
|
|
103
|
+
[_InputModule.default.color]: type === 'color',
|
|
104
|
+
[_InputModule.default.hideNumberSpinner]: hideNumberSpinner
|
|
103
105
|
}, classNames?.box),
|
|
104
106
|
onClick: !(disabled || locked) ? onContainerClick : null,
|
|
105
107
|
ref: boxRef
|
|
@@ -13,6 +13,7 @@ type ClassNames = $ReadOnly<{
|
|
|
13
13
|
box?: string,
|
|
14
14
|
iconLeft?: string,
|
|
15
15
|
iconRight?: string,
|
|
16
|
+
wrapper?: string,
|
|
16
17
|
}>;
|
|
17
18
|
|
|
18
19
|
export const EXPONENT_CHARACTER_LIST = ['E', 'e'];
|
|
@@ -80,6 +81,7 @@ export type InputProps = {
|
|
|
80
81
|
* Only values which are equal to the basis for stepping (min if specified, value otherwise, and an
|
|
81
82
|
* appropriate default value if neither of those is provided) are valid. */
|
|
82
83
|
step?: string,
|
|
84
|
+
hideNumberSpinner?: boolean,
|
|
83
85
|
...
|
|
84
86
|
};
|
|
85
87
|
|
|
@@ -111,6 +113,7 @@ const Input_ = (props: InputProps, ref): React.Node => {
|
|
|
111
113
|
boxRef,
|
|
112
114
|
onKeyDown,
|
|
113
115
|
disallowExponents,
|
|
116
|
+
hideNumberSpinner,
|
|
114
117
|
...inputProps
|
|
115
118
|
} = props;
|
|
116
119
|
|
|
@@ -142,10 +145,14 @@ const Input_ = (props: InputProps, ref): React.Node => {
|
|
|
142
145
|
|
|
143
146
|
return (
|
|
144
147
|
<div
|
|
145
|
-
className={classify(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
className={classify(
|
|
149
|
+
css.wrapper,
|
|
150
|
+
{
|
|
151
|
+
[css.filled]: controlledInputFilled ?? false,
|
|
152
|
+
[css.withError]: error ?? false,
|
|
153
|
+
},
|
|
154
|
+
classNames?.wrapper,
|
|
155
|
+
)}
|
|
149
156
|
>
|
|
150
157
|
{Boolean(label) && (
|
|
151
158
|
<div className={css.info}>
|
|
@@ -165,6 +172,7 @@ const Input_ = (props: InputProps, ref): React.Node => {
|
|
|
165
172
|
[css.small]: size === 'small',
|
|
166
173
|
[css.locked]: locked,
|
|
167
174
|
[css.color]: type === 'color',
|
|
175
|
+
[css.hideNumberSpinner]: hideNumberSpinner,
|
|
168
176
|
},
|
|
169
177
|
classNames?.box,
|
|
170
178
|
)}
|
|
@@ -172,3 +172,15 @@ input::placeholder {
|
|
|
172
172
|
min-height: size18;
|
|
173
173
|
border-radius: borderRadiusXSmall;
|
|
174
174
|
}
|
|
175
|
+
|
|
176
|
+
.hideNumberSpinner input[type='number']::-webkit-outer-spin-button,
|
|
177
|
+
.hideNumberSpinner input[type='number']::-webkit-inner-spin-button {
|
|
178
|
+
-webkit-appearance: none;
|
|
179
|
+
margin: 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* Hide spinner in Firefox */
|
|
183
|
+
.hideNumberSpinner input[type='number'] {
|
|
184
|
+
appearance: textfield;
|
|
185
|
+
-moz-appearance: textfield;
|
|
186
|
+
}
|
|
@@ -218,7 +218,9 @@ const PageTitle = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
218
218
|
}, /*#__PURE__*/React.createElement("div", {
|
|
219
219
|
className: _PageTitleModule.default.headerWithBackBtn
|
|
220
220
|
}, showBackButton && /*#__PURE__*/React.createElement(_Tooltip.Tooltip, {
|
|
221
|
-
title: "Navigate Back"
|
|
221
|
+
title: "Navigate Back",
|
|
222
|
+
delayMotionDuration: "slow",
|
|
223
|
+
placement: "top-start"
|
|
222
224
|
}, /*#__PURE__*/React.createElement(_Button.Button, {
|
|
223
225
|
onClick: handleBack,
|
|
224
226
|
type: "tertiary",
|
|
@@ -239,7 +239,11 @@ export const PageTitle: React$AbstractComponent<
|
|
|
239
239
|
<div className={classify(css.leftSlot, classNames?.leftSlot)}>
|
|
240
240
|
<div className={css.headerWithBackBtn}>
|
|
241
241
|
{showBackButton && (
|
|
242
|
-
<Tooltip
|
|
242
|
+
<Tooltip
|
|
243
|
+
title="Navigate Back"
|
|
244
|
+
delayMotionDuration="slow"
|
|
245
|
+
placement="top-start"
|
|
246
|
+
>
|
|
243
247
|
<Button
|
|
244
248
|
onClick={handleBack}
|
|
245
249
|
type="tertiary"
|
|
@@ -8,6 +8,8 @@ var React = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _color = require("../../styles/variables/_color");
|
|
9
9
|
var _classify = _interopRequireDefault(require("../../utils/classify"));
|
|
10
10
|
var _Button = require("../Button");
|
|
11
|
+
var _Input = require("../Input");
|
|
12
|
+
var _Text = require("../Text");
|
|
11
13
|
var _RangeSliderModule = _interopRequireDefault(require("./RangeSlider.module.css"));
|
|
12
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
15
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -30,12 +32,29 @@ const RangeSlider = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
30
32
|
hideLeftBtn,
|
|
31
33
|
hideRightBtn,
|
|
32
34
|
ariaLabel = 'Slider',
|
|
35
|
+
showRange,
|
|
36
|
+
hideValueInput,
|
|
33
37
|
...restInputProps
|
|
34
38
|
} = _ref;
|
|
35
39
|
const progress = (value - min) / (max - min) * 100;
|
|
36
40
|
const btnLeftDisabled = disabled || value <= min;
|
|
37
41
|
const btnRightDisabled = disabled || value >= max;
|
|
38
42
|
const progressColor = disabled ? _color.colorTextDisabled : _color.colorFillPrimary;
|
|
43
|
+
const handleInputChange = e => {
|
|
44
|
+
let inputValue = parseFloat(e.currentTarget.value);
|
|
45
|
+
|
|
46
|
+
// Validate and adjust the value
|
|
47
|
+
if (isNaN(inputValue) || inputValue < min) {
|
|
48
|
+
inputValue = min;
|
|
49
|
+
} else if (inputValue > max) {
|
|
50
|
+
inputValue = max;
|
|
51
|
+
} else if (step > 0) {
|
|
52
|
+
const nearestStep = Math.round(inputValue / step) * step;
|
|
53
|
+
inputValue = Math.round(nearestStep * 100) / 100; // Adjust to nearest valid step
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
onChange?.(inputValue);
|
|
57
|
+
};
|
|
39
58
|
const handleChange = e => {
|
|
40
59
|
emitRoundedValue(e.currentTarget.value);
|
|
41
60
|
};
|
|
@@ -50,14 +69,17 @@ const RangeSlider = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
50
69
|
className: (0, _classify.default)(_RangeSliderModule.default.wrapper, {
|
|
51
70
|
[_RangeSliderModule.default.disabled]: disabled
|
|
52
71
|
}, classNames?.wrapper)
|
|
53
|
-
}, !hideLeftBtn && /*#__PURE__*/React.createElement(_Button.Button, {
|
|
72
|
+
}, !hideLeftBtn && !showRange && /*#__PURE__*/React.createElement(_Button.Button, {
|
|
54
73
|
type: "ghost",
|
|
55
74
|
iconLeftName: iconLeftName,
|
|
56
75
|
size: btnLeftSize,
|
|
57
76
|
ariaLabel: "Decrease Value",
|
|
58
77
|
disabled: btnLeftDisabled,
|
|
59
78
|
onClick: () => emitRoundedValue(value - step)
|
|
60
|
-
}), /*#__PURE__*/React.createElement(
|
|
79
|
+
}), showRange && /*#__PURE__*/React.createElement(_Text.BodySmall, {
|
|
80
|
+
className: _RangeSliderModule.default.rangeText,
|
|
81
|
+
color: disabled ? 'disabled' : 'primary'
|
|
82
|
+
}, min), /*#__PURE__*/React.createElement("div", {
|
|
61
83
|
className: _RangeSliderModule.default.sliderContainer
|
|
62
84
|
}, /*#__PURE__*/React.createElement("input", _extends({}, restInputProps, {
|
|
63
85
|
type: "range",
|
|
@@ -80,14 +102,31 @@ const RangeSlider = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
80
102
|
length: (max - min) / step + 1
|
|
81
103
|
}, (_, index) => /*#__PURE__*/React.createElement("option", {
|
|
82
104
|
key: index,
|
|
83
|
-
value: min + index * step
|
|
84
|
-
|
|
105
|
+
value: min + index * step,
|
|
106
|
+
className: (0, _classify.default)({
|
|
107
|
+
[_RangeSliderModule.default.disabled]: disabled
|
|
108
|
+
})
|
|
109
|
+
})))), showRange && /*#__PURE__*/React.createElement(_Text.BodySmall, {
|
|
110
|
+
className: _RangeSliderModule.default.rangeText,
|
|
111
|
+
color: disabled ? 'disabled' : 'primary'
|
|
112
|
+
}, max), !hideRightBtn && !showRange && /*#__PURE__*/React.createElement(_Button.Button, {
|
|
85
113
|
type: "ghost",
|
|
86
114
|
iconRightName: iconRightName,
|
|
87
115
|
size: btnRightSize,
|
|
88
116
|
ariaLabel: "Increase Value",
|
|
89
117
|
disabled: btnRightDisabled,
|
|
90
118
|
onClick: () => emitRoundedValue(value + step)
|
|
119
|
+
}), !hideValueInput && /*#__PURE__*/React.createElement(_Input.Input, {
|
|
120
|
+
size: "small",
|
|
121
|
+
type: "number",
|
|
122
|
+
value: String(value),
|
|
123
|
+
classNames: {
|
|
124
|
+
wrapper: _RangeSliderModule.default.valueInputWrapper
|
|
125
|
+
},
|
|
126
|
+
disabled: disabled,
|
|
127
|
+
onChange: handleInputChange,
|
|
128
|
+
disallowExponents: true,
|
|
129
|
+
hideNumberSpinner: true
|
|
91
130
|
}));
|
|
92
131
|
});
|
|
93
132
|
exports.RangeSlider = RangeSlider;
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
import classify from '../../utils/classify';
|
|
11
11
|
import type {ButtonSize} from '../Button';
|
|
12
12
|
import {Button, BUTTON_SIZE} from '../Button';
|
|
13
|
+
import {Input} from '../Input';
|
|
14
|
+
import {BodySmall} from '../Text';
|
|
13
15
|
|
|
14
16
|
import css from './RangeSlider.module.css';
|
|
15
17
|
|
|
@@ -32,6 +34,8 @@ export type RangeSliderProps = {
|
|
|
32
34
|
hideRightBtn?: boolean,
|
|
33
35
|
classNames?: ClassNames,
|
|
34
36
|
ariaLabel?: string,
|
|
37
|
+
showRange?: boolean,
|
|
38
|
+
hideValueInput?: boolean,
|
|
35
39
|
...
|
|
36
40
|
};
|
|
37
41
|
|
|
@@ -56,6 +60,8 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
56
60
|
hideLeftBtn,
|
|
57
61
|
hideRightBtn,
|
|
58
62
|
ariaLabel = 'Slider',
|
|
63
|
+
showRange,
|
|
64
|
+
hideValueInput,
|
|
59
65
|
...restInputProps
|
|
60
66
|
}: RangeSliderProps,
|
|
61
67
|
ref,
|
|
@@ -67,6 +73,22 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
67
73
|
|
|
68
74
|
const progressColor = disabled ? colorTextDisabled : colorFillPrimary;
|
|
69
75
|
|
|
76
|
+
const handleInputChange = (e: SyntheticEvent<HTMLInputElement>) => {
|
|
77
|
+
let inputValue = parseFloat(e.currentTarget.value);
|
|
78
|
+
|
|
79
|
+
// Validate and adjust the value
|
|
80
|
+
if (isNaN(inputValue) || inputValue < min) {
|
|
81
|
+
inputValue = min;
|
|
82
|
+
} else if (inputValue > max) {
|
|
83
|
+
inputValue = max;
|
|
84
|
+
} else if (step > 0) {
|
|
85
|
+
const nearestStep = Math.round(inputValue / step) * step;
|
|
86
|
+
inputValue = Math.round(nearestStep * 100) / 100; // Adjust to nearest valid step
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
onChange?.(inputValue);
|
|
90
|
+
};
|
|
91
|
+
|
|
70
92
|
const handleChange = (e: SyntheticEvent<HTMLInputElement>) => {
|
|
71
93
|
emitRoundedValue(e.currentTarget.value);
|
|
72
94
|
};
|
|
@@ -87,7 +109,7 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
87
109
|
classNames?.wrapper,
|
|
88
110
|
)}
|
|
89
111
|
>
|
|
90
|
-
{!hideLeftBtn && (
|
|
112
|
+
{!hideLeftBtn && !showRange && (
|
|
91
113
|
<Button
|
|
92
114
|
type="ghost"
|
|
93
115
|
iconLeftName={iconLeftName}
|
|
@@ -98,6 +120,15 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
98
120
|
/>
|
|
99
121
|
)}
|
|
100
122
|
|
|
123
|
+
{showRange && (
|
|
124
|
+
<BodySmall
|
|
125
|
+
className={css.rangeText}
|
|
126
|
+
color={disabled ? 'disabled' : 'primary'}
|
|
127
|
+
>
|
|
128
|
+
{min}
|
|
129
|
+
</BodySmall>
|
|
130
|
+
)}
|
|
131
|
+
|
|
101
132
|
<div className={css.sliderContainer}>
|
|
102
133
|
<input
|
|
103
134
|
{...restInputProps}
|
|
@@ -123,12 +154,26 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
123
154
|
by allowing user-defined brackets or ranges for tick marks.
|
|
124
155
|
*/}
|
|
125
156
|
{Array.from({length: (max - min) / step + 1}, (_, index) => (
|
|
126
|
-
<option
|
|
157
|
+
<option
|
|
158
|
+
key={index}
|
|
159
|
+
value={min + index * step}
|
|
160
|
+
className={classify({[css.disabled]: disabled})}
|
|
161
|
+
/>
|
|
127
162
|
))}
|
|
128
163
|
</datalist>
|
|
129
164
|
)}
|
|
130
165
|
</div>
|
|
131
|
-
|
|
166
|
+
|
|
167
|
+
{showRange && (
|
|
168
|
+
<BodySmall
|
|
169
|
+
className={css.rangeText}
|
|
170
|
+
color={disabled ? 'disabled' : 'primary'}
|
|
171
|
+
>
|
|
172
|
+
{max}
|
|
173
|
+
</BodySmall>
|
|
174
|
+
)}
|
|
175
|
+
|
|
176
|
+
{!hideRightBtn && !showRange && (
|
|
132
177
|
<Button
|
|
133
178
|
type="ghost"
|
|
134
179
|
iconRightName={iconRightName}
|
|
@@ -138,6 +183,19 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
138
183
|
onClick={() => emitRoundedValue(value + step)}
|
|
139
184
|
/>
|
|
140
185
|
)}
|
|
186
|
+
|
|
187
|
+
{!hideValueInput && (
|
|
188
|
+
<Input
|
|
189
|
+
size="small"
|
|
190
|
+
type="number"
|
|
191
|
+
value={String(value)}
|
|
192
|
+
classNames={{wrapper: css.valueInputWrapper}}
|
|
193
|
+
disabled={disabled}
|
|
194
|
+
onChange={handleInputChange}
|
|
195
|
+
disallowExponents
|
|
196
|
+
hideNumberSpinner
|
|
197
|
+
/>
|
|
198
|
+
)}
|
|
141
199
|
</div>
|
|
142
200
|
);
|
|
143
201
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
@value (colorFillPrimary, colorGrayLightest, colorBackgroundTertiary, colorFocusPrimary, colorTextDisabled) from '../../styles/variables/_color.css';
|
|
2
|
-
@value (sizeFluid, size4, size20, size2) from '../../styles/variables/_size.css';
|
|
3
|
-
@value (
|
|
2
|
+
@value (sizeFluid, size4, size20, size2, size34) from '../../styles/variables/_size.css';
|
|
3
|
+
@value (spaceXXSmall, spaceNone) from '../../styles/variables/_space.css';
|
|
4
4
|
@value (borderRadiusLarge, borderRadiusCircle, borderWidthTertiary, borderWidthNone) from '../../styles/variables/_border.css';
|
|
5
5
|
|
|
6
6
|
@value thumbSize: size20;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
display: flex;
|
|
11
11
|
align-items: center;
|
|
12
12
|
width: sizeFluid;
|
|
13
|
-
gap:
|
|
13
|
+
gap: spaceXXSmall;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.sliderContainer {
|
|
@@ -119,3 +119,19 @@ input[type='range']:focus::-moz-range-thumb {
|
|
|
119
119
|
padding-inline: spaceNone;
|
|
120
120
|
white-space: nowrap;
|
|
121
121
|
}
|
|
122
|
+
|
|
123
|
+
.sliderTicks option.disabled {
|
|
124
|
+
background-color: colorTextDisabled;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.rangeText {
|
|
128
|
+
display: flex;
|
|
129
|
+
min-width: size34;
|
|
130
|
+
min-height: size34;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
align-items: center;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.valueInputWrapper {
|
|
136
|
+
max-width: 58px;
|
|
137
|
+
}
|
|
@@ -9,6 +9,7 @@ var _classify = _interopRequireDefault(require("../../utils/classify"));
|
|
|
9
9
|
var _Button = require("../Button");
|
|
10
10
|
var _ConditionalWrapper = require("../ConditionalWrapper");
|
|
11
11
|
var _Icon = require("../Icon");
|
|
12
|
+
var _Link = require("../Link");
|
|
12
13
|
var _Text = require("../Text");
|
|
13
14
|
var _Tooltip = require("../Tooltip");
|
|
14
15
|
var _SideMenuLinkModule = _interopRequireDefault(require("./SideMenuLink.module.css"));
|
|
@@ -189,6 +190,10 @@ const SideMenuLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
189
190
|
onChange,
|
|
190
191
|
tabIndex = 0,
|
|
191
192
|
tooltip,
|
|
193
|
+
isGroupMenuLink = false,
|
|
194
|
+
linkComponent: LinkComponent,
|
|
195
|
+
rightSlot,
|
|
196
|
+
to,
|
|
192
197
|
...restButtonProps
|
|
193
198
|
} = _ref;
|
|
194
199
|
const selected = selectedValue === pageNameKey;
|
|
@@ -197,6 +202,15 @@ const SideMenuLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
197
202
|
onChange && onChange(e, pageNameKey);
|
|
198
203
|
};
|
|
199
204
|
return /*#__PURE__*/React.createElement(_ConditionalWrapper.ConditionalWrapper, {
|
|
205
|
+
condition: to !== undefined,
|
|
206
|
+
wrapper: children => /*#__PURE__*/React.createElement(_Link.Link, {
|
|
207
|
+
to: to,
|
|
208
|
+
tabIndex: -1,
|
|
209
|
+
linkComponent: LinkComponent,
|
|
210
|
+
onClick: e => e.preventDefault(),
|
|
211
|
+
className: _SideMenuLinkModule.default.linkComponent
|
|
212
|
+
}, children)
|
|
213
|
+
}, /*#__PURE__*/React.createElement(_ConditionalWrapper.ConditionalWrapper, {
|
|
200
214
|
condition: Boolean(!opened && !inActive),
|
|
201
215
|
wrapper: children => /*#__PURE__*/React.createElement(_Tooltip.Tooltip, _extends({
|
|
202
216
|
body: MENU_NAME_LIST[pageNameKey].title
|
|
@@ -219,10 +233,13 @@ const SideMenuLink = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
219
233
|
size: "medium",
|
|
220
234
|
color: _Text.TEXT_COLORS.inverseSecondary,
|
|
221
235
|
className: _SideMenuLinkModule.default.menuIcon
|
|
222
|
-
}) : null,
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
236
|
+
}) : null, opened ? /*#__PURE__*/React.createElement("div", {
|
|
237
|
+
className: _SideMenuLinkModule.default.menuLabelContainer
|
|
238
|
+
}, pageNameKey && MENU_NAME_LIST[pageNameKey] ? isGroupMenuLink ? /*#__PURE__*/React.createElement(_Text.SubTitleSmall, {
|
|
239
|
+
className: _SideMenuLinkModule.default.groupMenuLinkText
|
|
240
|
+
}, MENU_NAME_LIST[pageNameKey].title) : /*#__PURE__*/React.createElement(_Text.BodyMedium, {
|
|
241
|
+
className: _SideMenuLinkModule.default.menuLinkText
|
|
242
|
+
}, MENU_NAME_LIST[pageNameKey].title) : null, rightSlot ? rightSlot : null) : null)));
|
|
226
243
|
});
|
|
227
244
|
exports.SideMenuLink = SideMenuLink;
|
|
228
245
|
SideMenuLink.displayName = 'SideMenuLink';
|
|
@@ -6,7 +6,9 @@ import classify from '../../utils/classify';
|
|
|
6
6
|
import {UnstyledButton} from '../Button';
|
|
7
7
|
import {ConditionalWrapper} from '../ConditionalWrapper';
|
|
8
8
|
import {Icon} from '../Icon';
|
|
9
|
-
import {
|
|
9
|
+
import type {BaseLinkProps} from '../Link';
|
|
10
|
+
import {Link} from '../Link';
|
|
11
|
+
import {BodyMedium, SubTitleSmall, TEXT_COLORS} from '../Text';
|
|
10
12
|
import type {BaseTooltipProps} from '../Tooltip';
|
|
11
13
|
import {Tooltip} from '../Tooltip';
|
|
12
14
|
|
|
@@ -189,6 +191,10 @@ export type SideMenuLinkProps = {
|
|
|
189
191
|
onChange?: (e: SyntheticEvent<HTMLElement>, newValue: string) => mixed,
|
|
190
192
|
tabIndex?: number,
|
|
191
193
|
tooltip?: BaseTooltipProps,
|
|
194
|
+
isGroupMenuLink?: boolean,
|
|
195
|
+
to?: string,
|
|
196
|
+
rightSlot?: React.Node,
|
|
197
|
+
linkComponent?: React.AbstractComponent<BaseLinkProps, ?HTMLAnchorElement>,
|
|
192
198
|
...
|
|
193
199
|
};
|
|
194
200
|
|
|
@@ -206,6 +212,10 @@ export const SideMenuLink: React$AbstractComponent<
|
|
|
206
212
|
onChange,
|
|
207
213
|
tabIndex = 0,
|
|
208
214
|
tooltip,
|
|
215
|
+
isGroupMenuLink = false,
|
|
216
|
+
linkComponent: LinkComponent,
|
|
217
|
+
rightSlot,
|
|
218
|
+
to,
|
|
209
219
|
...restButtonProps
|
|
210
220
|
}: SideMenuLinkProps,
|
|
211
221
|
ref,
|
|
@@ -218,49 +228,73 @@ export const SideMenuLink: React$AbstractComponent<
|
|
|
218
228
|
|
|
219
229
|
return (
|
|
220
230
|
<ConditionalWrapper
|
|
221
|
-
condition={
|
|
231
|
+
condition={to !== undefined}
|
|
222
232
|
wrapper={(children) => (
|
|
223
|
-
<
|
|
233
|
+
<Link
|
|
234
|
+
to={to}
|
|
235
|
+
tabIndex={-1}
|
|
236
|
+
linkComponent={LinkComponent}
|
|
237
|
+
onClick={(e) => e.preventDefault()}
|
|
238
|
+
className={css.linkComponent}
|
|
239
|
+
>
|
|
224
240
|
{children}
|
|
225
|
-
</
|
|
241
|
+
</Link>
|
|
226
242
|
)}
|
|
227
243
|
>
|
|
228
|
-
<
|
|
229
|
-
{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
[css.disabled]: disabled,
|
|
235
|
-
[css.inActive]: inActive,
|
|
236
|
-
[css.closed]: !opened,
|
|
237
|
-
},
|
|
238
|
-
classNames?.wrapper,
|
|
244
|
+
<ConditionalWrapper
|
|
245
|
+
condition={Boolean(!opened && !inActive)}
|
|
246
|
+
wrapper={(children) => (
|
|
247
|
+
<Tooltip body={MENU_NAME_LIST[pageNameKey].title} {...tooltip}>
|
|
248
|
+
{children}
|
|
249
|
+
</Tooltip>
|
|
239
250
|
)}
|
|
240
|
-
onClick={onChangeHandler}
|
|
241
|
-
ref={ref}
|
|
242
|
-
tabIndex={disabled ? -1 : tabIndex}
|
|
243
|
-
disabled={disabled}
|
|
244
|
-
key={pageNameKey}
|
|
245
251
|
>
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
252
|
+
<UnstyledButton
|
|
253
|
+
{...restButtonProps}
|
|
254
|
+
className={classify(
|
|
255
|
+
css.linkWrapper,
|
|
256
|
+
{
|
|
257
|
+
[css.selected]: selected,
|
|
258
|
+
[css.disabled]: disabled,
|
|
259
|
+
[css.inActive]: inActive,
|
|
260
|
+
[css.closed]: !opened,
|
|
261
|
+
},
|
|
262
|
+
classNames?.wrapper,
|
|
263
|
+
)}
|
|
264
|
+
onClick={onChangeHandler}
|
|
265
|
+
ref={ref}
|
|
266
|
+
tabIndex={disabled ? -1 : tabIndex}
|
|
267
|
+
disabled={disabled}
|
|
268
|
+
key={pageNameKey}
|
|
269
|
+
>
|
|
270
|
+
{pageNameKey && MENU_NAME_LIST[pageNameKey] ? (
|
|
271
|
+
<Icon
|
|
272
|
+
type={MENU_NAME_LIST[pageNameKey].iconType}
|
|
273
|
+
name={MENU_NAME_LIST[pageNameKey].iconName}
|
|
274
|
+
size="medium"
|
|
275
|
+
color={TEXT_COLORS.inverseSecondary}
|
|
276
|
+
className={css.menuIcon}
|
|
277
|
+
/>
|
|
278
|
+
) : null}
|
|
279
|
+
{opened ? (
|
|
280
|
+
<div className={css.menuLabelContainer}>
|
|
281
|
+
{pageNameKey && MENU_NAME_LIST[pageNameKey] ? (
|
|
282
|
+
isGroupMenuLink ? (
|
|
283
|
+
<SubTitleSmall className={css.groupMenuLinkText}>
|
|
284
|
+
{MENU_NAME_LIST[pageNameKey].title}
|
|
285
|
+
</SubTitleSmall>
|
|
286
|
+
) : (
|
|
287
|
+
<BodyMedium className={css.menuLinkText}>
|
|
288
|
+
{MENU_NAME_LIST[pageNameKey].title}
|
|
289
|
+
</BodyMedium>
|
|
290
|
+
)
|
|
291
|
+
) : null}
|
|
292
|
+
|
|
293
|
+
{rightSlot ? rightSlot : null}
|
|
294
|
+
</div>
|
|
295
|
+
) : null}
|
|
296
|
+
</UnstyledButton>
|
|
297
|
+
</ConditionalWrapper>
|
|
264
298
|
</ConditionalWrapper>
|
|
265
299
|
);
|
|
266
300
|
},
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
colorSideMenuBackgroundDefault,
|
|
9
9
|
colorSideMenuBackgroundHovered,
|
|
10
10
|
colorSideMenuBackgroundSelected,
|
|
11
|
+
colorGroupMenuTextDefault,
|
|
11
12
|
colorFocusPrimary
|
|
12
13
|
) from '../../styles/variables/_color.css';
|
|
13
14
|
@value ( spaceNone, spaceXXSmall, spaceXSmall, spaceSmall ) from '../../styles/variables/_space.css';
|
|
@@ -62,22 +63,47 @@
|
|
|
62
63
|
color: colorSideMenuIconDefault;
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
.linkComponent {
|
|
67
|
+
width: sizeFluid;
|
|
68
|
+
text-decoration: none;
|
|
69
|
+
}
|
|
70
|
+
|
|
65
71
|
.linkWrapper.selected {
|
|
66
72
|
background: colorSideMenuBackgroundSelected;
|
|
67
73
|
color: colorTextInversePrimary;
|
|
68
74
|
}
|
|
69
75
|
|
|
70
|
-
.linkWrapper.selected .menuIcon
|
|
76
|
+
.linkWrapper.selected .menuIcon,
|
|
77
|
+
.linkWrapper.selected .menuLinkText {
|
|
71
78
|
color: colorSideMenuIconActive;
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
.linkWrapper:
|
|
81
|
+
.linkWrapper:hover .menuIcon {
|
|
75
82
|
color: colorSideMenuIconActive;
|
|
76
83
|
}
|
|
77
84
|
|
|
78
|
-
.
|
|
85
|
+
.groupMenuLinkText {
|
|
79
86
|
color: inherit;
|
|
80
87
|
margin-right: spaceSmall;
|
|
81
88
|
white-space: nowrap;
|
|
82
89
|
padding-right: spaceXXSmall;
|
|
83
90
|
}
|
|
91
|
+
|
|
92
|
+
.menuLinkText {
|
|
93
|
+
color: colorGroupMenuTextDefault;
|
|
94
|
+
margin-right: spaceSmall;
|
|
95
|
+
white-space: nowrap;
|
|
96
|
+
padding-right: spaceXXSmall;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.linkWrapper:hover .menuLinkText {
|
|
100
|
+
color: colorSideMenuIconActive;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.menuLabelContainer {
|
|
104
|
+
color: inherit;
|
|
105
|
+
display: flex;
|
|
106
|
+
flex: 1;
|
|
107
|
+
justify-content: space-between;
|
|
108
|
+
padding-right: spaceXSmall;
|
|
109
|
+
}
|