@spaced-out/ui-design-system 0.1.118 → 0.1.120

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,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.1.120](https://github.com/spaced-out/ui-design-system/compare/v0.1.119...v0.1.120) (2024-08-19)
6
+
7
+
8
+ ### Features
9
+
10
+ * 🛝 new range slider component ([#254](https://github.com/spaced-out/ui-design-system/issues/254)) ([5631aa3](https://github.com/spaced-out/ui-design-system/commit/5631aa30bc9794e4400b0b88938dc2700a94939d))
11
+
12
+ ### [0.1.119](https://github.com/spaced-out/ui-design-system/compare/v0.1.118...v0.1.119) (2024-08-16)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * disabled state fix for link with icon ([a0c3a2a](https://github.com/spaced-out/ui-design-system/commit/a0c3a2aa035e0639a625d51c95c3e96dabd2a7fa))
18
+
5
19
  ### [0.1.118](https://github.com/spaced-out/ui-design-system/compare/v0.1.117...v0.1.118) (2024-08-05)
6
20
 
7
21
 
@@ -115,7 +115,9 @@ const Link = /*#__PURE__*/React.forwardRef((_ref, ref) => {
115
115
  name: iconLeftName,
116
116
  size: iconLeftSize,
117
117
  type: iconLeftType,
118
- className: _typographyModule.default[color]
118
+ className: (0, _classify.default)(_typographyModule.default[color], {
119
+ [_typographyModule.default.disabled]: disabled
120
+ })
119
121
  }), /*#__PURE__*/React.createElement(_ConditionalWrapper.ConditionalWrapper, {
120
122
  condition: Boolean(iconLeftName || iconRightName),
121
123
  wrapper: children => /*#__PURE__*/React.createElement("span", {
@@ -186,7 +186,7 @@ export const Link: React$AbstractComponent<LinkProps, ?HTMLAnchorElement> =
186
186
  name={iconLeftName}
187
187
  size={iconLeftSize}
188
188
  type={iconLeftType}
189
- className={css[color]}
189
+ className={classify(css[color], {[css.disabled]: disabled})}
190
190
  />
191
191
  )}
192
192
 
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RangeSlider = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _color = require("../../styles/variables/_color");
9
+ var _classify = _interopRequireDefault(require("../../utils/classify"));
10
+ var _Icon = require("../Icon");
11
+ var _RangeSliderModule = _interopRequireDefault(require("./RangeSlider.module.css"));
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+ 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); }
14
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
15
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
16
+ const RangeSlider = /*#__PURE__*/React.forwardRef((_ref, ref) => {
17
+ let {
18
+ classNames,
19
+ disabled,
20
+ min = 0,
21
+ max = 100,
22
+ step = 1,
23
+ value = min,
24
+ onChange,
25
+ showTicks,
26
+ iconLeftName = 'minus',
27
+ iconLeftSize = _Icon.ICON_SIZE.small,
28
+ iconLeftType,
29
+ iconRightName = 'plus',
30
+ iconRightSize = _Icon.ICON_SIZE.small,
31
+ iconRightType,
32
+ hideLeftIcon,
33
+ hideRightIcon,
34
+ ...restInputProps
35
+ } = _ref;
36
+ const progress = (value - min) / (max - min) * 100;
37
+ const iconLeftDisabled = disabled || value <= min;
38
+ const iconRightDisabled = disabled || value >= max;
39
+
40
+ /**
41
+ * Note(Nishant): This needs to be done because the Clickable Icon
42
+ * does not support disable prop currently. This can become a refactor
43
+ * task once we bake in disable support to Clickable Icon variation
44
+ */
45
+ const LeftIconComponent = iconLeftDisabled ? _Icon.Icon : _Icon.ClickableIcon;
46
+ const RightIconComponent = iconRightDisabled ? _Icon.Icon : _Icon.ClickableIcon;
47
+ const progressColor = disabled ? _color.colorTextDisabled : _color.colorFillPrimary;
48
+ const handleChange = e => {
49
+ emitRoundedValue(e.currentTarget.value);
50
+ };
51
+ const emitRoundedValue = value => {
52
+ const newValue = parseFloat(value);
53
+ const roundedValue = Math.round(newValue * 100) / 100; // Rounds to two decimal places
54
+ onChange?.(roundedValue);
55
+ };
56
+ return /*#__PURE__*/React.createElement("div", {
57
+ ref: ref,
58
+ "data-testid": "RangeSlider",
59
+ className: (0, _classify.default)(_RangeSliderModule.default.wrapper, {
60
+ [_RangeSliderModule.default.disabled]: disabled
61
+ }, classNames?.wrapper)
62
+ }, !hideLeftIcon && /*#__PURE__*/React.createElement(LeftIconComponent, _extends({
63
+ name: iconLeftName,
64
+ size: iconLeftSize,
65
+ type: iconLeftType,
66
+ color: iconLeftDisabled ? 'disabled' : 'primary'
67
+ }, !(disabled || value <= min) && {
68
+ onClick: () => emitRoundedValue(value - step)
69
+ })), /*#__PURE__*/React.createElement("div", {
70
+ className: _RangeSliderModule.default.sliderContainer
71
+ }, /*#__PURE__*/React.createElement("input", _extends({}, restInputProps, {
72
+ type: "range",
73
+ min: min,
74
+ max: max,
75
+ step: step,
76
+ value: value,
77
+ onChange: handleChange,
78
+ className: _RangeSliderModule.default.slider,
79
+ list: showTicks ? 'ticks' : undefined,
80
+ disabled: disabled,
81
+ style: {
82
+ background: `linear-gradient(to right, ${progressColor} ${progress}%, ${_color.colorGrayLightest} ${progress}%)`
83
+ }
84
+ })), showTicks && step > 0 && /*#__PURE__*/React.createElement("datalist", {
85
+ id: "ticks",
86
+ className: _RangeSliderModule.default.sliderTicks
87
+ }, Array.from({
88
+ length: (max - min) / step + 1
89
+ }, (_, index) => /*#__PURE__*/React.createElement("option", {
90
+ key: index,
91
+ value: min + index * step
92
+ })))), !hideRightIcon && /*#__PURE__*/React.createElement(RightIconComponent, _extends({
93
+ name: iconRightName,
94
+ size: iconRightSize,
95
+ type: iconRightType,
96
+ color: iconRightDisabled ? 'disabled' : 'primary'
97
+ }, !(disabled || value >= max) && {
98
+ onClick: () => emitRoundedValue(value + step)
99
+ })));
100
+ });
101
+ exports.RangeSlider = RangeSlider;
@@ -0,0 +1,155 @@
1
+ // @flow strict
2
+
3
+ import * as React from 'react';
4
+
5
+ import {
6
+ colorFillPrimary,
7
+ colorGrayLightest,
8
+ colorTextDisabled,
9
+ } from '../../styles/variables/_color';
10
+ import classify from '../../utils/classify';
11
+ import type {IconSize, IconType} from '../Icon';
12
+ import {ClickableIcon, Icon, ICON_SIZE} from '../Icon';
13
+
14
+ import css from './RangeSlider.module.css';
15
+
16
+
17
+ type ClassNames = $ReadOnly<{wrapper?: string}>;
18
+
19
+ export type RangeSliderProps = {
20
+ min?: number,
21
+ max?: number,
22
+ step?: number,
23
+ value?: number,
24
+ onChange?: (value: number) => void, // We don't want to send in the event because the icon buttons also modify the value
25
+ showTicks?: boolean,
26
+ iconLeftName?: string,
27
+ iconLeftType?: IconType,
28
+ iconLeftSize?: IconSize,
29
+ iconRightName?: string,
30
+ iconRightType?: IconType,
31
+ iconRightSize?: IconSize,
32
+ disabled?: boolean,
33
+ hideLeftIcon?: boolean,
34
+ hideRightIcon?: boolean,
35
+ classNames?: ClassNames,
36
+ ...
37
+ };
38
+
39
+ export const RangeSlider: React$AbstractComponent<
40
+ RangeSliderProps,
41
+ HTMLDivElement,
42
+ > = React.forwardRef<RangeSliderProps, HTMLDivElement>(
43
+ (
44
+ {
45
+ classNames,
46
+ disabled,
47
+ min = 0,
48
+ max = 100,
49
+ step = 1,
50
+ value = min,
51
+ onChange,
52
+ showTicks,
53
+ iconLeftName = 'minus',
54
+ iconLeftSize = ICON_SIZE.small,
55
+ iconLeftType,
56
+ iconRightName = 'plus',
57
+ iconRightSize = ICON_SIZE.small,
58
+ iconRightType,
59
+ hideLeftIcon,
60
+ hideRightIcon,
61
+ ...restInputProps
62
+ }: RangeSliderProps,
63
+ ref,
64
+ ) => {
65
+ const progress = ((value - min) / (max - min)) * 100;
66
+
67
+ const iconLeftDisabled = disabled || value <= min;
68
+ const iconRightDisabled = disabled || value >= max;
69
+
70
+ /**
71
+ * Note(Nishant): This needs to be done because the Clickable Icon
72
+ * does not support disable prop currently. This can become a refactor
73
+ * task once we bake in disable support to Clickable Icon variation
74
+ */
75
+ const LeftIconComponent = iconLeftDisabled ? Icon : ClickableIcon;
76
+ const RightIconComponent = iconRightDisabled ? Icon : ClickableIcon;
77
+
78
+ const progressColor = disabled ? colorTextDisabled : colorFillPrimary;
79
+
80
+ const handleChange = (e: SyntheticEvent<HTMLInputElement>) => {
81
+ emitRoundedValue(e.currentTarget.value);
82
+ };
83
+
84
+ const emitRoundedValue = (value: number | string) => {
85
+ const newValue = parseFloat(value);
86
+ const roundedValue = Math.round(newValue * 100) / 100; // Rounds to two decimal places
87
+ onChange?.(roundedValue);
88
+ };
89
+
90
+ return (
91
+ <div
92
+ ref={ref}
93
+ data-testid="RangeSlider"
94
+ className={classify(
95
+ css.wrapper,
96
+ {[css.disabled]: disabled},
97
+ classNames?.wrapper,
98
+ )}
99
+ >
100
+ {!hideLeftIcon && (
101
+ <LeftIconComponent
102
+ name={iconLeftName}
103
+ size={iconLeftSize}
104
+ type={iconLeftType}
105
+ color={iconLeftDisabled ? 'disabled' : 'primary'}
106
+ {...(!(disabled || value <= min) && {
107
+ onClick: () => emitRoundedValue(value - step),
108
+ })}
109
+ />
110
+ )}
111
+
112
+ <div className={css.sliderContainer}>
113
+ <input
114
+ {...restInputProps}
115
+ type="range"
116
+ min={min}
117
+ max={max}
118
+ step={step}
119
+ value={value}
120
+ onChange={handleChange}
121
+ className={css.slider}
122
+ list={showTicks ? 'ticks' : undefined}
123
+ disabled={disabled}
124
+ style={{
125
+ background: `linear-gradient(to right, ${progressColor} ${progress}%, ${colorGrayLightest} ${progress}%)`,
126
+ }}
127
+ />
128
+ {showTicks && step > 0 && (
129
+ <datalist id="ticks" className={css.sliderTicks}>
130
+ {/*
131
+ Note(Nishant): Currently, ticks are shown based on the step value.
132
+ This can be easily extended in the future to support custom tick intervals
133
+ by allowing user-defined brackets or ranges for tick marks.
134
+ */}
135
+ {Array.from({length: (max - min) / step + 1}, (_, index) => (
136
+ <option key={index} value={min + index * step} />
137
+ ))}
138
+ </datalist>
139
+ )}
140
+ </div>
141
+ {!hideRightIcon && (
142
+ <RightIconComponent
143
+ name={iconRightName}
144
+ size={iconRightSize}
145
+ type={iconRightType}
146
+ color={iconRightDisabled ? 'disabled' : 'primary'}
147
+ {...(!(disabled || value >= max) && {
148
+ onClick: () => emitRoundedValue(value + step),
149
+ })}
150
+ />
151
+ )}
152
+ </div>
153
+ );
154
+ },
155
+ );
@@ -0,0 +1,121 @@
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';
4
+ @value (borderRadiusLarge, borderRadiusCircle, borderWidthTertiary, borderWidthNone) from '../../styles/variables/_border.css';
5
+
6
+ @value thumbSize: size20;
7
+ @value tickSize: size2;
8
+
9
+ .wrapper {
10
+ display: flex;
11
+ align-items: center;
12
+ width: sizeFluid;
13
+ gap: calc(spaceXSmall * 2);
14
+ }
15
+
16
+ .sliderContainer {
17
+ display: flex;
18
+ flex-flow: column;
19
+ align-items: center;
20
+ position: relative;
21
+ width: sizeFluid;
22
+ }
23
+
24
+ .slider {
25
+ display: flex;
26
+ align-items: center;
27
+ -webkit-appearance: none;
28
+ appearance: none;
29
+ width: sizeFluid;
30
+ height: size4;
31
+ background-color: colorGrayLightest;
32
+ border-radius: borderRadiusLarge;
33
+ outline: none;
34
+ cursor: pointer;
35
+ }
36
+
37
+ .slider::-webkit-slider-thumb {
38
+ -webkit-appearance: none;
39
+ appearance: none;
40
+ width: thumbSize;
41
+ height: thumbSize;
42
+ border-radius: borderRadiusCircle;
43
+ background: colorFillPrimary;
44
+ cursor: progress;
45
+ border: borderWidthTertiary solid colorBackgroundTertiary;
46
+ cursor: move; /* fallback if grab cursor is unsupported */
47
+ cursor: grab;
48
+ cursor: -webkit-grab;
49
+ }
50
+
51
+ .slider:active::-webkit-slider-thumb {
52
+ cursor: grabbing;
53
+ cursor: -webkit-grabbing;
54
+ }
55
+
56
+ .disabled .slider::-webkit-slider-thumb {
57
+ background: colorTextDisabled; /* Disabled thumb color */
58
+ cursor: not-allowed;
59
+ }
60
+
61
+ .slider::-moz-range-thumb {
62
+ width: thumbSize;
63
+ height: thumbSize;
64
+ border-radius: borderRadiusCircle;
65
+ background: colorFillPrimary;
66
+ cursor: progress;
67
+ border: borderWidthTertiary solid colorBackgroundTertiary;
68
+ cursor: move; /* fallback if grab cursor is unsupported */
69
+ cursor: grab;
70
+ cursor: -moz-grab;
71
+ }
72
+
73
+ .slider:active::-moz-range-thumb {
74
+ cursor: grabbing;
75
+ cursor: -moz-grabbing;
76
+ }
77
+
78
+ .disabled .slider::-moz-range-thumb {
79
+ background: colorTextDisabled; /* Disabled thumb color */
80
+ cursor: not-allowed;
81
+ }
82
+
83
+ /***** Focus Styles *****/
84
+ /* Removes default focus */
85
+ input[type='range']:focus {
86
+ outline: none;
87
+ }
88
+
89
+ input[type='range']:focus::-webkit-slider-thumb {
90
+ box-shadow: borderWidthNone borderWidthNone borderWidthNone
91
+ borderWidthTertiary colorFocusPrimary;
92
+ }
93
+
94
+ input[type='range']:focus::-moz-range-thumb {
95
+ box-shadow: borderWidthNone borderWidthNone borderWidthNone
96
+ borderWidthTertiary colorFocusPrimary;
97
+ }
98
+
99
+ .sliderTicks {
100
+ display: flex;
101
+ position: absolute;
102
+ top: calc(spaceXXSmall / 4);
103
+ width: sizeFluid;
104
+ justify-content: space-between;
105
+ pointer-events: none; /* Prevent ticks from interfering with slider interaction */
106
+ padding: spaceNone calc(thumbSize / 2); /* Half of thumb size */
107
+ }
108
+
109
+ .sliderTicks option {
110
+ display: flex;
111
+ background-color: colorFillPrimary;
112
+ width: tickSize;
113
+ height: tickSize;
114
+ border-radius: borderRadiusLarge;
115
+ display: flex;
116
+ padding-block-start: spaceNone;
117
+ padding-block-end: spaceNone;
118
+ min-block-size: tickSize;
119
+ padding-inline: spaceNone;
120
+ white-space: nowrap;
121
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _RangeSlider = require("./RangeSlider");
7
+ Object.keys(_RangeSlider).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _RangeSlider[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _RangeSlider[key];
14
+ }
15
+ });
16
+ });
@@ -0,0 +1,3 @@
1
+ // @flow strict
2
+
3
+ export * from './RangeSlider';
@@ -454,6 +454,17 @@ Object.keys(_RadioButton).forEach(function (key) {
454
454
  }
455
455
  });
456
456
  });
457
+ var _RangeSlider = require("./RangeSlider");
458
+ Object.keys(_RangeSlider).forEach(function (key) {
459
+ if (key === "default" || key === "__esModule") return;
460
+ if (key in exports && exports[key] === _RangeSlider[key]) return;
461
+ Object.defineProperty(exports, key, {
462
+ enumerable: true,
463
+ get: function () {
464
+ return _RangeSlider[key];
465
+ }
466
+ });
467
+ });
457
468
  var _SearchInput = require("./SearchInput");
458
469
  Object.keys(_SearchInput).forEach(function (key) {
459
470
  if (key === "default" || key === "__esModule") return;
@@ -41,6 +41,7 @@ export * from './Pagination';
41
41
  export * from './Panel';
42
42
  export * from './ProgressDonut';
43
43
  export * from './RadioButton';
44
+ export * from './RangeSlider';
44
45
  export * from './SearchInput';
45
46
  export * from './Shimmer';
46
47
  export * from './SideMenuLink';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.1.118",
3
+ "version": "0.1.120",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {