@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 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(css.wrapper, {
146
- [css.filled]: controlledInputFilled ?? false,
147
- [css.withError]: error ?? false,
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 title="Navigate Back">
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("div", {
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
- })))), !hideRightBtn && /*#__PURE__*/React.createElement(_Button.Button, {
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 key={index} value={min + index * step} />
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
- {!hideRightBtn && (
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 (spaceXSmall, spaceXXSmall, spaceNone) from '../../styles/variables/_space.css';
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: calc(spaceXSmall * 2);
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, pageNameKey && MENU_NAME_LIST[pageNameKey] && opened ? /*#__PURE__*/React.createElement(_Text.SubTitleSmall, {
223
- color: _Text.TEXT_COLORS.inverseSecondary,
224
- className: _SideMenuLinkModule.default.menuText
225
- }, MENU_NAME_LIST[pageNameKey].title) : null));
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 {SubTitleSmall, TEXT_COLORS} from '../Text';
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={Boolean(!opened && !inActive)}
231
+ condition={to !== undefined}
222
232
  wrapper={(children) => (
223
- <Tooltip body={MENU_NAME_LIST[pageNameKey].title} {...tooltip}>
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
- </Tooltip>
241
+ </Link>
226
242
  )}
227
243
  >
228
- <UnstyledButton
229
- {...restButtonProps}
230
- className={classify(
231
- css.linkWrapper,
232
- {
233
- [css.selected]: selected,
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
- {pageNameKey && MENU_NAME_LIST[pageNameKey] ? (
247
- <Icon
248
- type={MENU_NAME_LIST[pageNameKey].iconType}
249
- name={MENU_NAME_LIST[pageNameKey].iconName}
250
- size="medium"
251
- color={TEXT_COLORS.inverseSecondary}
252
- className={css.menuIcon}
253
- />
254
- ) : null}
255
- {pageNameKey && MENU_NAME_LIST[pageNameKey] && opened ? (
256
- <SubTitleSmall
257
- color={TEXT_COLORS.inverseSecondary}
258
- className={css.menuText}
259
- >
260
- {MENU_NAME_LIST[pageNameKey].title}
261
- </SubTitleSmall>
262
- ) : null}
263
- </UnstyledButton>
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:not(.inActive):hover .menuIcon {
81
+ .linkWrapper:hover .menuIcon {
75
82
  color: colorSideMenuIconActive;
76
83
  }
77
84
 
78
- .menuText {
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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.1.121",
3
+ "version": "0.1.123",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {