@widergy/energy-ui 3.171.3 → 3.172.1
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 +19 -2
- package/dist/components/UTButton/constants.js +2 -0
- package/dist/components/UTButton/index.js +6 -3
- package/dist/components/UTButton/stories/UTButtonSizes.stories.js +16 -1
- package/dist/components/UTButton/stories/storiesConstants.js +26 -0
- package/dist/components/UTButton/styles.module.scss +10 -0
- package/dist/components/UTButton/theme.js +1 -1
- package/dist/components/UTButton/utils.js +1 -4
- package/dist/components/UTDataCategory/theme.js +1 -1
- package/dist/components/UTDataElement/README.md +1 -1
- package/dist/components/UTPaper/index.js +3 -1
- package/dist/components/UTSelect/UTSelectFixedBottomOption.stories.js +171 -0
- package/dist/components/UTSelect/versions/V1/README.md +19 -0
- package/dist/components/UTSelect/versions/V1/components/ListboxComponent/index.js +48 -16
- package/dist/components/UTSelect/versions/V1/components/ListboxComponent/styles.module.scss +11 -0
- package/dist/components/UTSelect/versions/V1/index.js +39 -15
- package/dist/components/UTSelect/versions/V1/types.js +6 -0
- package/dist/components/UTTracker/UTTracker.stories.js +332 -0
- package/dist/esm/components/UTButton/constants.js +2 -0
- package/dist/esm/components/UTButton/index.js +6 -3
- package/dist/esm/components/UTButton/stories/UTButtonSizes.stories.js +15 -0
- package/dist/esm/components/UTButton/stories/storiesConstants.js +26 -0
- package/dist/esm/components/UTButton/styles.module.scss +10 -0
- package/dist/esm/components/UTButton/theme.js +1 -1
- package/dist/esm/components/UTButton/utils.js +1 -4
- package/dist/esm/components/UTDataCategory/theme.js +2 -2
- package/dist/esm/components/UTDataElement/README.md +1 -1
- package/dist/esm/components/UTPaper/index.js +3 -1
- package/dist/esm/components/UTSelect/UTSelectFixedBottomOption.stories.js +163 -0
- package/dist/esm/components/UTSelect/versions/V1/README.md +19 -0
- package/dist/esm/components/UTSelect/versions/V1/components/ListboxComponent/index.js +49 -17
- package/dist/esm/components/UTSelect/versions/V1/components/ListboxComponent/styles.module.scss +11 -0
- package/dist/esm/components/UTSelect/versions/V1/index.js +39 -15
- package/dist/esm/components/UTSelect/versions/V1/types.js +6 -0
- package/dist/esm/components/UTTracker/UTTracker.stories.js +325 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
|
-
## [3.
|
|
1
|
+
## [3.172.1](https://github.com/widergy/energy-ui/compare/v3.172.0...v3.172.1) (2026-07-03)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
* [
|
|
6
|
+
* [DIS-1108] ajustes utbutton ([#824](https://github.com/widergy/energy-ui/issues/824)) ([46b1ef8](https://github.com/widergy/energy-ui/commit/46b1ef8e07217bd75451b962236f98790c544f4b))
|
|
7
|
+
|
|
8
|
+
# [3.172.0](https://github.com/widergy/energy-ui/compare/v3.171.3...v3.172.0) (2026-07-02)
|
|
9
|
+
|
|
10
|
+
### Novedades y Mejoras
|
|
11
|
+
|
|
12
|
+
* En los selectores desplegables, ahora es posible fijar una opción al pie de la lista que permanece siempre visible, incluso al filtrar por búsqueda o al no encontrar resultados. [#830](https://github.com/widergy/Energy-UI/pull/830) [AXCH-1900](https://widergy.atlassian.net/browse/AXCH-1900)
|
|
13
|
+
|
|
14
|
+
### Correcciones
|
|
15
|
+
|
|
16
|
+
* Mejoras internas de la plataforma. [`56be941`](https://github.com/widergy/Energy-UI/commit/56be941)
|
|
17
|
+
|
|
18
|
+
## [3.171.3](https://github.com/widergy/energy-ui/compare/v3.171.2...v3.171.3) (2026-06-29)
|
|
19
|
+
|
|
20
|
+
### Correcciones
|
|
21
|
+
|
|
22
|
+
* Al tocar un marcador en el mapa, este ahora queda visible por encima de otros marcadores cercanos o superpuestos. [#829](https://github.com/widergy/Energy-UI/pull/829) [CX-2712](https://widergy.atlassian.net/browse/CX-2712)
|
|
23
|
+
* Mejoras internas de la plataforma. [`caa1f1a`](https://github.com/widergy/Energy-UI/commit/caa1f1a)
|
|
7
24
|
|
|
8
25
|
## [3.171.2](https://github.com/widergy/energy-ui/compare/v3.171.1...v3.171.2) (2026-06-27)
|
|
9
26
|
|
|
@@ -24,6 +24,8 @@ const ICON_PLACEMENTS = exports.ICON_PLACEMENTS = {
|
|
|
24
24
|
const DEFAULT_PROPS = exports.DEFAULT_PROPS = {
|
|
25
25
|
colorTheme: 'secondary',
|
|
26
26
|
disabled: false,
|
|
27
|
+
fullHeight: false,
|
|
28
|
+
fullWidth: false,
|
|
27
29
|
hideTextOnResponsive: false,
|
|
28
30
|
iconPlacement: ICON_PLACEMENTS.left,
|
|
29
31
|
loading: false,
|
|
@@ -29,6 +29,8 @@ const UTButton = _ref => {
|
|
|
29
29
|
count,
|
|
30
30
|
dataTestId,
|
|
31
31
|
disabled,
|
|
32
|
+
fullHeight,
|
|
33
|
+
fullWidth,
|
|
32
34
|
hideTextOnResponsive,
|
|
33
35
|
Icon,
|
|
34
36
|
iconPlacement,
|
|
@@ -58,7 +60,6 @@ const UTButton = _ref => {
|
|
|
58
60
|
} = (0, _react.useMemo)(() => (0, _utils.getIconProps)({
|
|
59
61
|
className: icon,
|
|
60
62
|
colorTheme,
|
|
61
|
-
hasContent: !!children,
|
|
62
63
|
hideTextOnResponsive,
|
|
63
64
|
Icon,
|
|
64
65
|
iconPlacement,
|
|
@@ -66,7 +67,7 @@ const UTButton = _ref => {
|
|
|
66
67
|
RightIcon,
|
|
67
68
|
size,
|
|
68
69
|
variant
|
|
69
|
-
}), [colorTheme,
|
|
70
|
+
}), [colorTheme, hideTextOnResponsive, icon, Icon, iconPlacement, LeftIcon, RightIcon, size, variant]);
|
|
70
71
|
const LeftIconToShow = LeftIconComponent && /*#__PURE__*/_react.default.createElement(LeftIconComponent, _extends({}, leftIconBaseProps, leftIconProps));
|
|
71
72
|
const RightIconToShow = RightIconComponent && /*#__PURE__*/_react.default.createElement(RightIconComponent, _extends({}, rightIconBaseProps, rightIconProps));
|
|
72
73
|
const counterColorTheme = (0, _utils.getCounterColorTheme)(colorTheme, variant);
|
|
@@ -80,7 +81,7 @@ const UTButton = _ref => {
|
|
|
80
81
|
}), children), RightIconToShow);
|
|
81
82
|
return /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
82
83
|
classes: materialButtonClasses,
|
|
83
|
-
className: "\n ".concat(_stylesModule.default["padding".concat((0, _componentUtils.capitalize)(size))], "\n ").concat(hideTextOnResponsive && _stylesModule.default.hideTextOnResponsive, "\n ").concat(!hideTextOnResponsive && !children && _stylesModule.default.noChildren, "\n "),
|
|
84
|
+
className: "\n ".concat(_stylesModule.default["padding".concat((0, _componentUtils.capitalize)(size))], "\n ").concat(fullHeight && _stylesModule.default.fullHeight, "\n ").concat(fullWidth && _stylesModule.default.fullWidth, "\n ").concat(hideTextOnResponsive && _stylesModule.default.hideTextOnResponsive, "\n ").concat(!hideTextOnResponsive && !children && _stylesModule.default.noChildren, "\n "),
|
|
84
85
|
"data-testid": dataTestId,
|
|
85
86
|
disabled: disabled || loading,
|
|
86
87
|
onClick: onClick,
|
|
@@ -98,6 +99,8 @@ UTButton.propTypes = {
|
|
|
98
99
|
count: _propTypes.number,
|
|
99
100
|
dataTestId: _propTypes.string,
|
|
100
101
|
disabled: _propTypes.bool,
|
|
102
|
+
fullHeight: _propTypes.bool,
|
|
103
|
+
fullWidth: _propTypes.bool,
|
|
101
104
|
hideTextOnResponsive: _propTypes.bool,
|
|
102
105
|
/**
|
|
103
106
|
* @deprecated Use LeftIcon or RightIcon instead.
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default = exports.Small = exports.Medium = exports.Large = void 0;
|
|
6
|
+
exports.default = exports.Small = exports.Medium = exports.Large = exports.FullHeight = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
7
8
|
var _ = _interopRequireDefault(require(".."));
|
|
8
9
|
var _storiesConstants = require("./storiesConstants");
|
|
9
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -37,4 +38,18 @@ const Large = exports.Large = {
|
|
|
37
38
|
children: 'Large Size',
|
|
38
39
|
size: 'large'
|
|
39
40
|
}
|
|
41
|
+
};
|
|
42
|
+
const FullHeight = exports.FullHeight = {
|
|
43
|
+
args: {
|
|
44
|
+
children: 'Full Height',
|
|
45
|
+
fullHeight: true
|
|
46
|
+
},
|
|
47
|
+
render: args => /*#__PURE__*/_react.default.createElement("div", {
|
|
48
|
+
style: {
|
|
49
|
+
display: 'flex',
|
|
50
|
+
height: 80,
|
|
51
|
+
border: '1px dashed #ccc',
|
|
52
|
+
padding: 8
|
|
53
|
+
}
|
|
54
|
+
}, /*#__PURE__*/_react.default.createElement(_.default, args))
|
|
40
55
|
};
|
|
@@ -93,6 +93,30 @@ const COMMON_ARG_TYPES = exports.COMMON_ARG_TYPES = {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
},
|
|
96
|
+
fullHeight: {
|
|
97
|
+
control: 'boolean',
|
|
98
|
+
description: 'Si es `true`, el botón ocupa el alto completo de su contenedor padre. Desactiva el `min-height` por tamaño.',
|
|
99
|
+
table: {
|
|
100
|
+
defaultValue: {
|
|
101
|
+
summary: _constants.DEFAULT_PROPS.fullHeight
|
|
102
|
+
},
|
|
103
|
+
type: {
|
|
104
|
+
summary: 'boolean'
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
fullWidth: {
|
|
109
|
+
control: 'boolean',
|
|
110
|
+
description: 'Si es `true`, el botón ocupa el ancho completo de su contenedor padre. Desactiva el `min-width`.',
|
|
111
|
+
table: {
|
|
112
|
+
defaultValue: {
|
|
113
|
+
summary: _constants.DEFAULT_PROPS.fullWidth
|
|
114
|
+
},
|
|
115
|
+
type: {
|
|
116
|
+
summary: 'boolean'
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
96
120
|
hideTextOnResponsive: {
|
|
97
121
|
control: 'boolean',
|
|
98
122
|
description: 'Si es `true` y hay ícono, el contenido del botón no se muestra en dispositivos móviles.',
|
|
@@ -222,6 +246,8 @@ const COMMON_ARGS = exports.COMMON_ARGS = {
|
|
|
222
246
|
colorTheme: _constants.DEFAULT_PROPS.colorTheme,
|
|
223
247
|
dataTestId: 'customButtonId',
|
|
224
248
|
disabled: _constants.DEFAULT_PROPS.disabled,
|
|
249
|
+
fullHeight: _constants.DEFAULT_PROPS.fullHeight,
|
|
250
|
+
fullWidth: _constants.DEFAULT_PROPS.fullWidth,
|
|
225
251
|
hideTextOnResponsive: _constants.DEFAULT_PROPS.hideTextOnResponsive,
|
|
226
252
|
loading: _constants.DEFAULT_PROPS.loading,
|
|
227
253
|
size: _constants.DEFAULT_PROPS.size,
|
|
@@ -65,6 +65,16 @@ $small-icon: var(--UT-button-icon-size-sm, 1.25rem);
|
|
|
65
65
|
padding: var(--UT-button-padding-xs, 0.25rem) var(--UT-button-padding-sm, 0.5rem);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
.fullHeight {
|
|
69
|
+
min-height: unset;
|
|
70
|
+
height: 100%;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.fullWidth {
|
|
74
|
+
min-width: unset;
|
|
75
|
+
width: 100%;
|
|
76
|
+
}
|
|
77
|
+
|
|
68
78
|
.hideTextOnResponsive {
|
|
69
79
|
.textContainer {
|
|
70
80
|
@media #{$mobile} {
|
|
@@ -50,7 +50,7 @@ const variantsColorTheme = (theme, colorTheme, variant) => {
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
[_constants.VARIANTS_NAMES.outlined]: {
|
|
53
|
-
border: "1px solid ".concat(
|
|
53
|
+
border: "1px solid ".concat(lightTheme['04']),
|
|
54
54
|
fill: colorTheme === _constants.COLORS_MAPPER.gray ? actionTheme['04'] : actionTheme['05'],
|
|
55
55
|
'&:hover': {
|
|
56
56
|
backgroundColor: colorTheme === _constants.COLORS_MAPPER.gray ? lightTheme['03'] : actionTheme['01'],
|
|
@@ -15,7 +15,6 @@ const buildSingleIconProps = _ref => {
|
|
|
15
15
|
let {
|
|
16
16
|
className,
|
|
17
17
|
colorTheme,
|
|
18
|
-
hasContent,
|
|
19
18
|
hideTextOnResponsive,
|
|
20
19
|
Icon,
|
|
21
20
|
size,
|
|
@@ -24,7 +23,7 @@ const buildSingleIconProps = _ref => {
|
|
|
24
23
|
if (!Icon) return null;
|
|
25
24
|
return {
|
|
26
25
|
IconComponent: (0, _componentUtils.isUTIcon)(Icon) ? _UTIcon.default : Icon,
|
|
27
|
-
className: "\n ".concat(_stylesModule.default.baseIcon, "\n ").concat(className, "\n ").concat(
|
|
26
|
+
className: "\n ".concat(_stylesModule.default.baseIcon, "\n ").concat(className, "\n ").concat(_stylesModule.default.icon, "\n ").concat(hideTextOnResponsive ? _stylesModule.default["adaptableIcon".concat((0, _componentUtils.capitalize)(size))] : '', "\n "),
|
|
28
27
|
...((0, _componentUtils.isUTIcon)(Icon) ? {
|
|
29
28
|
colorTheme: getButtonElementColorTheme(colorTheme, variant),
|
|
30
29
|
name: Icon
|
|
@@ -35,7 +34,6 @@ const getIconProps = _ref2 => {
|
|
|
35
34
|
let {
|
|
36
35
|
className,
|
|
37
36
|
colorTheme,
|
|
38
|
-
hasContent,
|
|
39
37
|
hideTextOnResponsive,
|
|
40
38
|
Icon,
|
|
41
39
|
iconPlacement,
|
|
@@ -49,7 +47,6 @@ const getIconProps = _ref2 => {
|
|
|
49
47
|
const commonParams = {
|
|
50
48
|
className,
|
|
51
49
|
colorTheme,
|
|
52
|
-
hasContent,
|
|
53
50
|
hideTextOnResponsive,
|
|
54
51
|
size,
|
|
55
52
|
variant
|
|
@@ -11,7 +11,7 @@ const backgroundColor = function (theme, area) {
|
|
|
11
11
|
const colorTheme = areaProps.colorTheme || _Palette.COLOR_THEMES.light;
|
|
12
12
|
const actionPaletteColors = ((_theme$Palette = theme.Palette) === null || _theme$Palette === void 0 ? void 0 : _theme$Palette.actions) || theme.Palette;
|
|
13
13
|
const areaColor = actionPaletteColors[colorTheme];
|
|
14
|
-
const shade = areaProps.shade || (_Palette.COLOR_THEMES.light === colorTheme ?
|
|
14
|
+
const shade = areaProps.shade || (_Palette.COLOR_THEMES.light === colorTheme ? _Palette.COLOR_SHADES.shade03 : _Palette.COLOR_SHADES.shade01);
|
|
15
15
|
return {
|
|
16
16
|
backgroundColor: area ? areaColor[shade] : 'transparent'
|
|
17
17
|
};
|
|
@@ -15,15 +15,17 @@ const UTPaper = _ref => {
|
|
|
15
15
|
let {
|
|
16
16
|
children,
|
|
17
17
|
classes,
|
|
18
|
+
className,
|
|
18
19
|
...otherProps
|
|
19
20
|
} = _ref;
|
|
20
21
|
return /*#__PURE__*/_react.default.createElement(_core.Paper, _extends({}, otherProps, {
|
|
21
|
-
className: classes.paper
|
|
22
|
+
className: "".concat(classes.paper).concat(className ? " ".concat(className) : '')
|
|
22
23
|
}), children);
|
|
23
24
|
};
|
|
24
25
|
UTPaper.propTypes = {
|
|
25
26
|
children: _propTypes.object,
|
|
26
27
|
classes: (0, _propTypes.objectOf)(_propTypes.string),
|
|
28
|
+
className: _propTypes.string,
|
|
27
29
|
otherProps: _propTypes.object
|
|
28
30
|
};
|
|
29
31
|
var _default = exports.default = (0, _WithTheme.default)(_theme.retrieveStyle)(UTPaper);
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.SeleccionMultiple = exports.ListaLarga = exports.ListaCorta = exports.ConCategorias = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _propTypes = require("prop-types");
|
|
9
|
+
var _2 = _interopRequireDefault(require("."));
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
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); }
|
|
12
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
13
|
+
const OPTIONS = [{
|
|
14
|
+
name: 'Electricidad',
|
|
15
|
+
value: 'electricity'
|
|
16
|
+
}, {
|
|
17
|
+
name: 'Gas natural',
|
|
18
|
+
value: 'gas'
|
|
19
|
+
}, {
|
|
20
|
+
name: 'Agua potable',
|
|
21
|
+
value: 'water'
|
|
22
|
+
}, {
|
|
23
|
+
name: 'Energía solar',
|
|
24
|
+
value: 'solar'
|
|
25
|
+
}, {
|
|
26
|
+
name: 'Biomasa',
|
|
27
|
+
value: 'biomass'
|
|
28
|
+
}];
|
|
29
|
+
const OPTIONS_WITH_CATEGORIES = [{
|
|
30
|
+
name: 'Residencial bajo',
|
|
31
|
+
value: 'res-low',
|
|
32
|
+
category: 'Residencial'
|
|
33
|
+
}, {
|
|
34
|
+
name: 'Residencial medio',
|
|
35
|
+
value: 'res-mid',
|
|
36
|
+
category: 'Residencial'
|
|
37
|
+
}, {
|
|
38
|
+
name: 'Residencial alto',
|
|
39
|
+
value: 'res-high',
|
|
40
|
+
category: 'Residencial'
|
|
41
|
+
}, {
|
|
42
|
+
name: 'Comercial pequeño',
|
|
43
|
+
value: 'com-sm',
|
|
44
|
+
category: 'Comercial'
|
|
45
|
+
}, {
|
|
46
|
+
name: 'Comercial grande',
|
|
47
|
+
value: 'com-lg',
|
|
48
|
+
category: 'Comercial'
|
|
49
|
+
}, {
|
|
50
|
+
name: 'Industrial liviano',
|
|
51
|
+
value: 'ind-sm',
|
|
52
|
+
category: 'Industrial'
|
|
53
|
+
}, {
|
|
54
|
+
name: 'Industrial pesado',
|
|
55
|
+
value: 'ind-lg',
|
|
56
|
+
category: 'Industrial'
|
|
57
|
+
}];
|
|
58
|
+
const LONG_OPTIONS = Array.from({
|
|
59
|
+
length: 20
|
|
60
|
+
}, (_, i) => ({
|
|
61
|
+
name: "Opci\xF3n ".concat(i + 1),
|
|
62
|
+
value: "opt-".concat(i + 1)
|
|
63
|
+
}));
|
|
64
|
+
const wrapperStyle = {
|
|
65
|
+
maxWidth: '360px',
|
|
66
|
+
padding: '1rem'
|
|
67
|
+
};
|
|
68
|
+
const SelectWrapper = _ref => {
|
|
69
|
+
let {
|
|
70
|
+
multiple,
|
|
71
|
+
...props
|
|
72
|
+
} = _ref;
|
|
73
|
+
const [value, setValue] = (0, _react.useState)(multiple ? [] : null);
|
|
74
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
75
|
+
style: wrapperStyle
|
|
76
|
+
}, /*#__PURE__*/_react.default.createElement(_2.default, _extends({}, props, {
|
|
77
|
+
multiple: multiple,
|
|
78
|
+
onChange: setValue,
|
|
79
|
+
value: value,
|
|
80
|
+
version: "V1"
|
|
81
|
+
})));
|
|
82
|
+
};
|
|
83
|
+
SelectWrapper.propTypes = {
|
|
84
|
+
multiple: _propTypes.bool,
|
|
85
|
+
title: _propTypes.string
|
|
86
|
+
};
|
|
87
|
+
var _default = exports.default = {
|
|
88
|
+
component: _2.default,
|
|
89
|
+
title: 'Energy-UI/UTSelect/Con opción fija'
|
|
90
|
+
};
|
|
91
|
+
const ListaLarga = exports.ListaLarga = {
|
|
92
|
+
name: 'Lista larga',
|
|
93
|
+
args: {
|
|
94
|
+
fixedBottomOption: {
|
|
95
|
+
name: 'Otro motivo',
|
|
96
|
+
value: 'other'
|
|
97
|
+
},
|
|
98
|
+
options: LONG_OPTIONS,
|
|
99
|
+
placeholder: 'Seleccioná una opción',
|
|
100
|
+
title: 'Con opción fija al final (lista larga)'
|
|
101
|
+
},
|
|
102
|
+
parameters: {
|
|
103
|
+
docs: {
|
|
104
|
+
description: {
|
|
105
|
+
story: 'La prop `fixedBottomOption` agrega una opción fija debajo del scroll, siempre visible independientemente del término de búsqueda. Útil para opciones como "Otro motivo".'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
render: args => /*#__PURE__*/_react.default.createElement(SelectWrapper, args)
|
|
110
|
+
};
|
|
111
|
+
const ListaCorta = exports.ListaCorta = {
|
|
112
|
+
name: 'Lista corta',
|
|
113
|
+
args: {
|
|
114
|
+
fixedBottomOption: {
|
|
115
|
+
name: 'Otro motivo',
|
|
116
|
+
value: 'other'
|
|
117
|
+
},
|
|
118
|
+
options: OPTIONS,
|
|
119
|
+
placeholder: 'Seleccioná una opción',
|
|
120
|
+
title: 'Con opción fija al final (lista corta)'
|
|
121
|
+
},
|
|
122
|
+
parameters: {
|
|
123
|
+
docs: {
|
|
124
|
+
description: {
|
|
125
|
+
story: 'La opción fija también se muestra cuando la lista es corta y no hay scroll. Si el usuario filtra y no hay coincidencias, la opción fija permanece visible.'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
render: args => /*#__PURE__*/_react.default.createElement(SelectWrapper, args)
|
|
130
|
+
};
|
|
131
|
+
const ConCategorias = exports.ConCategorias = {
|
|
132
|
+
name: 'Con categorías',
|
|
133
|
+
args: {
|
|
134
|
+
fixedBottomOption: {
|
|
135
|
+
name: 'Otro motivo',
|
|
136
|
+
value: 'other'
|
|
137
|
+
},
|
|
138
|
+
options: OPTIONS_WITH_CATEGORIES,
|
|
139
|
+
placeholder: 'Seleccioná una opción',
|
|
140
|
+
title: 'Con categorías y opción fija'
|
|
141
|
+
},
|
|
142
|
+
parameters: {
|
|
143
|
+
docs: {
|
|
144
|
+
description: {
|
|
145
|
+
story: 'La opción fija convive con opciones agrupadas por categoría. El divider y la opción fija siempre quedan por debajo de todos los grupos.'
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
render: args => /*#__PURE__*/_react.default.createElement(SelectWrapper, args)
|
|
150
|
+
};
|
|
151
|
+
const SeleccionMultiple = exports.SeleccionMultiple = {
|
|
152
|
+
name: 'Selección múltiple',
|
|
153
|
+
args: {
|
|
154
|
+
fixedBottomOption: {
|
|
155
|
+
name: 'Otro motivo',
|
|
156
|
+
value: 'other'
|
|
157
|
+
},
|
|
158
|
+
multiple: true,
|
|
159
|
+
options: OPTIONS,
|
|
160
|
+
placeholder: 'Seleccioná una o más opciones',
|
|
161
|
+
title: 'Selección múltiple con opción fija'
|
|
162
|
+
},
|
|
163
|
+
parameters: {
|
|
164
|
+
docs: {
|
|
165
|
+
description: {
|
|
166
|
+
story: 'Con `multiple={true}` la opción fija se comporta como cualquier otra: se puede seleccionar y deseleccionar de forma independiente. El valor es un array que incluye `fixedBottomOption.value` cuando está marcada.'
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
render: args => /*#__PURE__*/_react.default.createElement(SelectWrapper, args)
|
|
171
|
+
};
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
| disableFilterOptions | bool | false | Disables option filtering, showing all options even when typing in the search field. |
|
|
21
21
|
| error | string | | Error message to display below the input field. |
|
|
22
22
|
| errorDataTestId | string | | Test ID for the error validation component. |
|
|
23
|
+
| fixedBottomOption | object | | Option rendered below the scrollable list, always visible regardless of the search term. Shape: `{ name: string, value: string \| number }`. |
|
|
23
24
|
| freeWidth | bool | false | Allows the dropdown to have a free width instead of matching the input width. |
|
|
24
25
|
| helpText | string | | Help text displayed below the input field. |
|
|
25
26
|
| icon | string | | Icon name to display in the input field. |
|
|
@@ -67,6 +68,24 @@ The `action` prop accepts an object with the following properties:
|
|
|
67
68
|
|
|
68
69
|
## Features
|
|
69
70
|
|
|
71
|
+
### `fixedBottomOption`
|
|
72
|
+
|
|
73
|
+
`fixedBottomOption` adds a pinned option at the bottom of the dropdown list, rendered outside the scrollable area so it's always visible regardless of scroll position or active search term. Useful for "catch-all" options like "Other reason".
|
|
74
|
+
|
|
75
|
+
```jsx
|
|
76
|
+
<UTSelect
|
|
77
|
+
version="V1"
|
|
78
|
+
options={categorizedOptions}
|
|
79
|
+
fixedBottomOption={{ name: 'Otro motivo', value: 'other' }}
|
|
80
|
+
onChange={handleSelect}
|
|
81
|
+
/>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- The fixed option is excluded from `filteredOptions` — if it's also present in `options`, it's automatically deduplicated by value.
|
|
85
|
+
- When no options match the search term, `noMatchesText` is shown but the fixed option remains visible.
|
|
86
|
+
- The option is visually separated from the list by a divider.
|
|
87
|
+
- When selected, `onChange` receives the option's value (same behavior as any other option).
|
|
88
|
+
|
|
70
89
|
### `withAutoReset`
|
|
71
90
|
|
|
72
91
|
`withAutoReset` is a prop that controls the behavior of the `UTSelect` component when the selected value is no longer available in the current options. This prop ensures that the selected value resets to `null` if the chosen option is no longer valid. When an auto-reset occurs, the options are re-sorted to ensure the list is up-to-date with the current selections.
|
|
@@ -16,11 +16,13 @@ var _stylesModule = _interopRequireDefault(require("./styles.module.scss"));
|
|
|
16
16
|
var _constants2 = require("./constants");
|
|
17
17
|
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
18
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
19
20
|
const ListboxComponent = _ref => {
|
|
20
21
|
let {
|
|
21
22
|
CustomRow,
|
|
22
23
|
dataTestId,
|
|
23
24
|
filteredOptions,
|
|
25
|
+
fixedBottomOption,
|
|
24
26
|
handleSelectionChange,
|
|
25
27
|
horizontalSpacing = _constants.SPACING.SMALL,
|
|
26
28
|
itemDataTestId,
|
|
@@ -32,28 +34,54 @@ const ListboxComponent = _ref => {
|
|
|
32
34
|
} = _ref;
|
|
33
35
|
const hasNoOptions = (0, _react.useMemo)(() => (0, _isEmpty.default)(filteredOptions), [filteredOptions]);
|
|
34
36
|
const maxHeightValid = (0, _react.useMemo)(() => (0, _isFinite.default)(maxHeight) ? maxHeight : _constants2.DEFAULT_MAX_HEIGHT, [maxHeight]);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
maxHeight: maxHeightValid
|
|
37
|
+
const fixedSectionRef = (0, _react.useRef)(null);
|
|
38
|
+
const [reservedHeight, setReservedHeight] = (0, _react.useState)(0);
|
|
39
|
+
(0, _react.useLayoutEffect)(() => {
|
|
40
|
+
if (fixedSectionRef.current) {
|
|
41
|
+
setReservedHeight(fixedSectionRef.current.offsetHeight);
|
|
41
42
|
}
|
|
42
|
-
},
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
}, [fixedBottomOption]);
|
|
44
|
+
const scrollMaxHeight = maxHeightValid - reservedHeight;
|
|
45
|
+
const handleFixedOptionChange = newValues => {
|
|
46
|
+
if (!multiple && newValues.length === 0) {
|
|
47
|
+
handleSelectionChange([fixedBottomOption.value]);
|
|
48
|
+
} else {
|
|
49
|
+
handleSelectionChange(newValues);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const checkListProps = {
|
|
53
|
+
CustomRow,
|
|
54
|
+
horizontalSpacing,
|
|
46
55
|
isSimple: !multiple,
|
|
47
|
-
itemDataTestId
|
|
56
|
+
itemDataTestId,
|
|
48
57
|
onChange: handleSelectionChange,
|
|
49
|
-
options: filteredOptions,
|
|
50
58
|
reversed: true,
|
|
51
59
|
showSelectAll: false,
|
|
52
60
|
value: multiple ? value : [value],
|
|
53
|
-
variant:
|
|
54
|
-
version:
|
|
55
|
-
verticalSpacing
|
|
56
|
-
}
|
|
61
|
+
variant: 'button',
|
|
62
|
+
version: 'V1',
|
|
63
|
+
verticalSpacing
|
|
64
|
+
};
|
|
65
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
66
|
+
className: _stylesModule.default.listbox
|
|
67
|
+
}, hasNoOptions ? /*#__PURE__*/_react.default.createElement(_UTLabel.default, {
|
|
68
|
+
colorTheme: "gray",
|
|
69
|
+
className: _stylesModule.default.noOptionsLabel
|
|
70
|
+
}, noMatchesText) : /*#__PURE__*/_react.default.createElement(_reactPerfectScrollbar.default, {
|
|
71
|
+
style: {
|
|
72
|
+
maxHeight: scrollMaxHeight
|
|
73
|
+
}
|
|
74
|
+
}, /*#__PURE__*/_react.default.createElement(_UTCheckList.default, _extends({}, checkListProps, {
|
|
75
|
+
dataTestId: dataTestId,
|
|
76
|
+
options: filteredOptions
|
|
77
|
+
}))), fixedBottomOption && /*#__PURE__*/_react.default.createElement("div", {
|
|
78
|
+
ref: fixedSectionRef
|
|
79
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
80
|
+
className: _stylesModule.default.fixedOptionDivider
|
|
81
|
+
}), /*#__PURE__*/_react.default.createElement(_UTCheckList.default, _extends({}, checkListProps, {
|
|
82
|
+
onChange: handleFixedOptionChange,
|
|
83
|
+
options: [fixedBottomOption]
|
|
84
|
+
}))));
|
|
57
85
|
};
|
|
58
86
|
ListboxComponent.propTypes = {
|
|
59
87
|
CustomRow: _propTypes.elementType,
|
|
@@ -62,6 +90,10 @@ ListboxComponent.propTypes = {
|
|
|
62
90
|
name: _propTypes.string,
|
|
63
91
|
value: (0, _propTypes.oneOfType)([_propTypes.string, _propTypes.number])
|
|
64
92
|
})),
|
|
93
|
+
fixedBottomOption: (0, _propTypes.shape)({
|
|
94
|
+
name: _propTypes.string,
|
|
95
|
+
value: (0, _propTypes.oneOfType)([_propTypes.string, _propTypes.number])
|
|
96
|
+
}),
|
|
65
97
|
handleSelectionChange: _propTypes.func,
|
|
66
98
|
horizontalSpacing: _propTypes.string,
|
|
67
99
|
itemDataTestId: _propTypes.string,
|