@rio-cloud/rio-uikit 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.DS_Store +0 -0
  2. package/components/applicationHeader/ApplicationHeader.js +3 -1
  3. package/components/applicationLayout/ApplicationLayoutBody.js +2 -1
  4. package/components/assetTree/Tree.d.ts +21 -4
  5. package/components/assetTree/TreeLeaf.js +13 -1
  6. package/components/assetTree/TreeNode.js +9 -1
  7. package/components/saveableInput/SaveableDateInput.d.ts +8 -0
  8. package/components/saveableInput/SaveableDateInput.js +16 -8
  9. package/components/saveableInput/SaveableInput.d.ts +8 -0
  10. package/components/saveableInput/SaveableInput.js +4 -3
  11. package/components/table/TableSettingsListContainer.js +1 -1
  12. package/lib/es/components/applicationHeader/ApplicationHeader.js +3 -1
  13. package/lib/es/components/applicationLayout/ApplicationLayoutBody.js +2 -1
  14. package/lib/es/components/assetTree/Tree.d.ts +21 -4
  15. package/lib/es/components/assetTree/TreeLeaf.js +13 -1
  16. package/lib/es/components/assetTree/TreeNode.js +9 -1
  17. package/lib/es/components/saveableInput/SaveableDateInput.d.ts +8 -0
  18. package/lib/es/components/saveableInput/SaveableDateInput.js +16 -8
  19. package/lib/es/components/saveableInput/SaveableInput.d.ts +8 -0
  20. package/lib/es/components/saveableInput/SaveableInput.js +4 -3
  21. package/lib/es/styles/variables/colors/colors.json +77 -77
  22. package/lib/es/utils/init/initCSS.js +1 -1
  23. package/lib/es/version.json +1 -1
  24. package/package.json +11 -21
  25. package/styles/variables/colors/colors.json +77 -77
  26. package/utils/init/initCSS.js +1 -1
  27. package/version.json +1 -1
  28. package/lib/es/utils/init/printPoweredByRIO.d.ts +0 -1
  29. package/lib/es/utils/init/printPoweredByRIO.js +0 -16
  30. package/utils/init/printPoweredByRIO.d.ts +0 -1
  31. package/utils/init/printPoweredByRIO.js +0 -12
package/.DS_Store CHANGED
Binary file
@@ -21,7 +21,9 @@ export const ApplicationHeader = forwardRef((props, ref) => {
21
21
  return typeof value === 'number' && Math.round(value);
22
22
  }
23
23
  }, [contentRect]);
24
- const containerWidth = getContentRect('width') || 0;
24
+ // If container width cannot be properly read initially, fall back to window width.
25
+ // This fixes ugly jumping on mobile header and desktop header on mount.
26
+ const containerWidth = getContentRect('width') || window.innerWidth;
25
27
  const isMobileWidth = containerWidth <= SCREEN_SM;
26
28
  const hasActionBarItems = !isEmpty(actionBarItems);
27
29
  const wrapperClassNames = classNames('ApplicationHeader', 'user-select-none', isMobileWidth && 'mobile', className && className);
@@ -40,7 +40,8 @@ const ApplicationLayoutBody = forwardRef((props, ref) => {
40
40
  const scrollWrapper = moduleContentRef.current.container;
41
41
  const scrollingElement = scrollWrapper.firstElementChild;
42
42
  const currentScroll = scrollingElement?.scrollTop ?? 0;
43
- if (currentScroll > 0) {
43
+ const scrollThreshold = 10;
44
+ if (currentScroll > scrollThreshold) {
44
45
  window.requestAnimationFrame(handleToTop);
45
46
  scrollingElement?.scrollTo(0, currentScroll - currentScroll / 5);
46
47
  scrollWrapper.classList.add('is-scrolling-to-top');
@@ -23,6 +23,8 @@ export type TreeGroup = {
23
23
  disabled?: boolean;
24
24
  /**
25
25
  * The rioglyph icon name for a group.
26
+ *
27
+ * The prefix `rioglyph-` can be omitted.
26
28
  */
27
29
  icon?: string;
28
30
  /**
@@ -45,13 +47,28 @@ export type TreeItem = {
45
47
  */
46
48
  info?: string | React.ReactNode;
47
49
  /**
48
- * The type of an item which is also the name of the respective rioglyph icon without the prefix
49
- * `rioglyph-`.
50
+ * The primary type of the item.
51
+ *
52
+ * This is also used as the fallback icon name and refers to the name of the respective
53
+ * rioglyph icon (excluding the `rioglyph-` prefix).
50
54
  */
51
55
  type: string;
52
56
  /**
53
- * The sub type of an item which is also the name of the respective rioglyph icon without the prefix.
54
- * This could be used to show a secondary paired icon like for fuel type.
57
+ * Optional icon override for the item.
58
+ *
59
+ * - If set to a string (e.g. `'truck'`), this icon will be used explicitly.
60
+ * - If set to `undefined`, the `type` property will be used as the fallback icon.
61
+ * - If set to `null`, no icon will be rendered, even if `type` is defined.
62
+ *
63
+ * This allows full control over the icon behavior while maintaining backward compatibility with type-based icons.
64
+ */
65
+ icon?: string | null;
66
+ /**
67
+ * Optional sub-type of the item.
68
+ *
69
+ * This refers to the name of an additional rioglyph icon (excluding the `rioglyph-` prefix),
70
+ * typically used to render a secondary icon next to the primary one (e.g. for fuel type or
71
+ * equipment variations).
55
72
  */
56
73
  subType?: string;
57
74
  /**
@@ -5,9 +5,21 @@ import classNames from 'classnames';
5
5
  import isObject from 'lodash/fp/isObject';
6
6
  import Checkbox from '../checkbox/Checkbox';
7
7
  import RadioButton from '../radiobutton/RadioButton';
8
+ const getIconRenderInfo = (item) => {
9
+ if (item.icon === null) {
10
+ // explicit opt-out
11
+ return { primaryIcon: null, subIcon: null };
12
+ }
13
+ // fallback to type
14
+ const primaryIcon = item.icon ?? item.type;
15
+ // treat subType as pair icon name
16
+ const subIcon = item.subType ?? null;
17
+ return { primaryIcon, subIcon };
18
+ };
8
19
  const TreeLeaf = React.memo((props) => {
9
20
  const { item, hasMultiselect, showRadioButtons, isSelected, onSelectItem, onActiveItem } = props;
10
21
  const treeNodeClassNames = classNames('TreeLeaf', 'form-group margin-bottom-0', isSelected && 'active', item.className && item.className);
11
- return (_jsxs("div", { className: treeNodeClassNames, "data-key": item.id, children: [hasMultiselect && _jsx(Checkbox, { className: 'TreeCheckbox', checked: isSelected, onClick: onSelectItem }), !hasMultiselect && showRadioButtons && (_jsx(RadioButton, { className: 'TreeRadioButton', checked: isSelected, onChange: onSelectItem })), _jsxs("span", { className: 'TreeLabel TreeLabelName', onClick: onActiveItem, children: [!item.subType && _jsx("span", { className: `rioglyph rioglyph-${item.type}` }), item.subType && (_jsxs("span", { className: 'rioglyph-icon-pair', children: [_jsx("span", { className: `rioglyph rioglyph-${item.type}` }), _jsx("span", { className: `rioglyph rioglyph-${item.subType}` })] })), _jsxs("span", { className: 'TreeLabelNameText', children: [_jsx("span", { className: 'TreeLabelNameTextHeadline', children: isObject(item.name) ? (_jsxs(_Fragment, { children: [_jsx("span", { className: 'text-light margin-right-3', children: item.name.firstName }), _jsx("span", { children: item.name.lastName })] })) : (item.name) }), item.info && _jsx("span", { className: 'TreeLabelNameTextSubline', children: item.info })] })] })] }));
22
+ const { primaryIcon, subIcon } = getIconRenderInfo(item);
23
+ return (_jsxs("div", { className: treeNodeClassNames, "data-key": item.id, children: [hasMultiselect && _jsx(Checkbox, { className: 'TreeCheckbox', checked: isSelected, onClick: onSelectItem }), !hasMultiselect && showRadioButtons && (_jsx(RadioButton, { className: 'TreeRadioButton', checked: isSelected, onChange: onSelectItem })), _jsxs("span", { className: 'TreeLabel TreeLabelName', onClick: onActiveItem, children: [primaryIcon && !subIcon && _jsx("span", { className: `rioglyph rioglyph-${primaryIcon}` }), primaryIcon && subIcon && (_jsxs("span", { className: 'rioglyph-icon-pair', children: [_jsx("span", { className: `rioglyph rioglyph-${primaryIcon}` }), _jsx("span", { className: `rioglyph rioglyph-${subIcon}` })] })), _jsxs("span", { className: 'TreeLabelNameText', children: [_jsx("span", { className: 'TreeLabelNameTextHeadline', children: isObject(item.name) ? (_jsxs(_Fragment, { children: [_jsx("span", { className: 'text-light margin-right-3', children: item.name.firstName }), _jsx("span", { children: item.name.lastName })] })) : (item.name) }), item.info && _jsx("span", { className: 'TreeLabelNameTextSubline', children: item.info })] })] })] }));
12
24
  });
13
25
  export default TreeLeaf;
@@ -2,10 +2,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import classNames from 'classnames';
4
4
  import Checkbox from '../checkbox/Checkbox';
5
+ // Add prefix `rioglyph-` if icon is given and does not start with the prefix
6
+ const withRioglyphPrefix = (name) => {
7
+ if (!name) {
8
+ return null;
9
+ }
10
+ return name.startsWith('rioglyph-') ? name : `rioglyph-${name}`;
11
+ };
5
12
  const TreeNode = React.memo((props) => {
6
13
  const { node, hasMultiselect = false, isSelected = false, isIndeterminate = false, onToggleNode, onSelect } = props;
7
14
  const treeNodeClassNames = classNames('TreeNode', 'from-group', isSelected && 'checked', node.className && node.className);
8
15
  const hasChildren = !!node.items.length;
9
- return (_jsxs("div", { className: treeNodeClassNames, "data-key": node.id, onClick: () => hasChildren && onToggleNode(node.id), children: [hasMultiselect && (_jsx(Checkbox, { className: 'TreeCheckbox', checked: isSelected, disabled: node.disabled, indeterminate: isIndeterminate, onClick: () => onSelect(node, isIndeterminate) })), _jsxs("span", { className: 'TreeLabel TreeLabelName', children: [node.icon && _jsx("span", { className: `rioglyph ${node.icon}` }), _jsx("span", { className: 'TreeLabelNameText', children: _jsx("span", { className: 'TreeLabelNameTextHeadline', children: node.name }) }), _jsx("span", { className: 'TreeLabelCount label label-muted label-filled label-condensed', children: node.items.length }), _jsx("span", { className: `TreeLabelExpander rioglyph rioglyph-chevron-down ${hasChildren ? '' : 'text-color-light'}` })] })] }));
16
+ const iconName = withRioglyphPrefix(node.icon);
17
+ return (_jsxs("div", { className: treeNodeClassNames, "data-key": node.id, onClick: () => hasChildren && onToggleNode(node.id), children: [hasMultiselect && (_jsx(Checkbox, { className: 'TreeCheckbox', checked: isSelected, disabled: node.disabled, indeterminate: isIndeterminate, onClick: () => onSelect(node, isIndeterminate) })), _jsxs("span", { className: 'TreeLabel TreeLabelName', children: [iconName && _jsx("span", { className: `rioglyph ${iconName}` }), _jsx("span", { className: 'TreeLabelNameText', children: _jsx("span", { className: 'TreeLabelNameTextHeadline', children: node.name }) }), _jsx("span", { className: 'TreeLabelCount label label-muted label-filled label-condensed', children: node.items.length }), _jsx("span", { className: `TreeLabelExpander rioglyph rioglyph-chevron-down ${hasChildren ? '' : 'text-color-light'}` })] })] }));
10
18
  });
11
19
  export default TreeNode;
@@ -17,6 +17,14 @@ export type SaveableDateInputProps = {
17
17
  * @default true
18
18
  */
19
19
  isValid?: boolean;
20
+ /**
21
+ * This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false.
22
+ */
23
+ errorMessage?: string | React.ReactNode;
24
+ /**
25
+ * Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false.
26
+ */
27
+ hideErrorIcon?: boolean;
20
28
  /**
21
29
  * Callback function triggered when the value changes and is saved.
22
30
  * @param value
@@ -14,7 +14,7 @@ const DEFAULT_BUTTON_STYLE = 'primary';
14
14
  // - close edit mode only if date is valid - or close edit mode and reset to initial value -> customizable via prop
15
15
  // Keep picker open until user has clicked save, otherwise he might forget to click save if the dropdown closes automatically
16
16
  const SaveableDateInput = (props) => {
17
- const { placeholder, value: externalValue = '', isValid = true, onValueChanged = noop, onInputChange, // for controlled usage
17
+ const { placeholder, value: externalValue = '', isValid = true, errorMessage, hideErrorIcon = false, onValueChanged = noop, onInputChange, // for controlled usage
18
18
  onEnterEdit = noop, onExitEdit = noop, onCancel = noop, buttonStyle = DEFAULT_BUTTON_STYLE, inputClassName, inputProps, invalidExitBehavior = 'stay-open', datePickerProps = {}, disabled = false, className, ...remainingProps } = props;
19
19
  // if callback is provided, assume it is controlled case
20
20
  const isControlledCase = onInputChange !== undefined;
@@ -105,18 +105,26 @@ const SaveableDateInput = (props) => {
105
105
  }
106
106
  };
107
107
  const handleCloseDropdown = () => setIsPickerOpen(false);
108
- const wrapperClasses = classNames('form-group', className);
108
+ const wrapperClasses = classNames('form-group', !isValid && 'has-feedback has-error', className);
109
109
  const buttonIconClasses = classNames('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');
110
110
  const dateInputClasses = classNames('margin-0 width-100pct', inputClassName);
111
111
  // Button should be disabled if:
112
112
  // - Component is disabled, OR
113
113
  // - In edit mode and invalid input (and behavior is stay-open)
114
114
  const disableButton = disabled || (editInput && !isValid && invalidExitBehavior === 'stay-open');
115
- return (_jsx("div", { ref: wrapperRef, ...remainingProps, className: wrapperClasses, children: _jsxs("div", { className: 'input-group', children: [_jsx(DatePicker, { ...datePickerProps, open: isPickerOpen, className: dateInputClasses, inputProps: {
116
- ...inputProps,
117
- placeholder,
118
- disabled: !editInput,
119
- style: { borderTopRightRadius: 0, borderBottomRightRadius: 0 },
120
- }, value: inputValue, onChange: handleDateChange, onClose: handleCloseDropdown }), _jsx("div", { className: 'input-group-btn', children: _jsx(Button, { ref: buttonRef, bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: _jsx("span", { className: buttonIconClasses }) }) })] }) }));
115
+ let inputStyle = {
116
+ borderTopRightRadius: 0,
117
+ borderBottomRightRadius: 0,
118
+ };
119
+ if (!isValid && hideErrorIcon) {
120
+ // If the error icon shall not be shown, remove the input padding to avoid cutting of the date value
121
+ inputStyle = { ...inputStyle, paddingRight: '10px' };
122
+ }
123
+ return (_jsxs("div", { ref: wrapperRef, ...remainingProps, className: wrapperClasses, children: [_jsxs("div", { className: 'input-group', children: [_jsx(DatePicker, { ...datePickerProps, open: isPickerOpen, className: dateInputClasses, inputProps: {
124
+ ...inputProps,
125
+ placeholder,
126
+ disabled: !editInput,
127
+ style: inputStyle,
128
+ }, value: inputValue, onChange: handleDateChange, onClose: handleCloseDropdown }), !isValid && !hideErrorIcon && (_jsx("span", { className: 'right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' })), _jsx("div", { className: 'input-group-btn', children: _jsx(Button, { ref: buttonRef, bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: _jsx("span", { className: buttonIconClasses }) }) })] }), !isValid && errorMessage && (_jsx("span", { className: 'help-block z-index-max', children: _jsx("span", { children: errorMessage }) }))] }));
121
129
  };
122
130
  export default SaveableDateInput;
@@ -25,6 +25,14 @@ export type SaveableInputProps = {
25
25
  * @default true
26
26
  */
27
27
  isValid?: boolean;
28
+ /**
29
+ * This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false.
30
+ */
31
+ errorMessage?: string | React.ReactNode;
32
+ /**
33
+ * Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false.
34
+ */
35
+ hideErrorIcon?: boolean;
28
36
  /**
29
37
  * Callback function triggered when the value changes.
30
38
  * @param value
@@ -29,7 +29,7 @@ const useFocus = (isEditable) => {
29
29
  // [x] allow for unit and icon
30
30
  // [x] disabled input
31
31
  const SaveableInput = (props) => {
32
- const { placeholder, fixedPreviousValue = '', previousValue = '', value: externalValue = '', isValid = true, onValueChanged = noop, onInputChange, onEsc = noop, onEnterEdit = noop, buttonStyle = DEFAULT_BUTTON_STYLE, inputClassName, inputProps, icon, unit, disabled = false, className, ...remainingProps } = props;
32
+ const { placeholder, fixedPreviousValue = '', previousValue = '', value: externalValue = '', isValid = true, errorMessage, hideErrorIcon = false, onValueChanged = noop, onInputChange, onEsc = noop, onEnterEdit = noop, buttonStyle = DEFAULT_BUTTON_STYLE, inputClassName, inputProps, icon, unit, disabled = false, className, ...remainingProps } = props;
33
33
  const externalOldValue = previousValue || fixedPreviousValue;
34
34
  const [inputValue, setInputValue] = useState(externalValue);
35
35
  const [oldInputValue, setOldInputValue] = useState(externalOldValue);
@@ -106,12 +106,13 @@ const SaveableInput = (props) => {
106
106
  const handleFocus = () => setIsFocused(true);
107
107
  const handleBlur = () => setIsFocused(false);
108
108
  const showOldValue = !isEmpty(oldInputValue) && oldInputValue !== inputValue && !editInput;
109
- const wrapperClasses = classNames('form-group', className);
109
+ const wrapperClasses = classNames('form-group', !isValid && 'has-feedback has-error', className);
110
110
  const inputClasses = classNames('form-control', showOldValue && 'padding-bottom-0 padding-top-10 text-size-12', unit && 'padding-right-50', // This value is not perfect as with longer units it might conflict with the value
111
+ !unit && !isValid && hideErrorIcon && 'padding-right-10', // remove the padding for the error icon if not needed
111
112
  inputClassName);
112
113
  const oldValueClasses = classNames('position-absolute', 'top-2', 'left-10', 'margin-left-3', 'text-size-10', 'text-decoration-line-through', icon && 'padding-left-20');
113
114
  const buttonIconClasses = classNames('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');
114
115
  const disableButton = (editInput && !isValid) || disabled;
115
- return (_jsx("div", { ...remainingProps, className: wrapperClasses, children: _jsxs("div", { className: 'input-group', children: [icon && (_jsx("span", { className: 'input-group-addon', children: _jsx("span", { className: `rioglyph ${icon}`, "aria-hidden": 'true', "aria-label": 'input icon' }) })), _jsx("input", { type: 'text', ref: inputRef, placeholder: placeholder, className: inputClasses, value: inputValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, disabled: !editInput, ...inputProps }), unit && (_jsx("div", { className: 'position-absolute right-0 margin-right-50', "aria-label": 'unit', children: unit })), showOldValue && (_jsx("div", { className: oldValueClasses, "aria-label": 'previous value', children: oldInputValue })), _jsx("div", { className: 'input-group-btn', children: _jsx(Button, { bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: _jsx("span", { className: buttonIconClasses }) }) })] }) }));
116
+ return (_jsxs("div", { ...remainingProps, className: wrapperClasses, children: [_jsxs("div", { className: 'input-group', children: [icon && (_jsx("span", { className: 'input-group-addon', children: _jsx("span", { className: `rioglyph ${icon}`, "aria-hidden": 'true', "aria-label": 'input icon' }) })), _jsx("input", { type: 'text', ref: inputRef, placeholder: placeholder, className: inputClasses, value: inputValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, disabled: !editInput, ...inputProps }), unit && (_jsx("div", { className: 'position-absolute right-0 margin-right-50', "aria-label": 'unit', children: unit })), showOldValue && (_jsx("div", { className: oldValueClasses, "aria-label": 'previous value', children: oldInputValue })), _jsx("div", { className: 'input-group-btn', children: _jsx(Button, { bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: _jsx("span", { className: buttonIconClasses }) }) })] }), !isValid && !hideErrorIcon && !unit && (_jsx("span", { className: 'right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' })), !isValid && errorMessage && (_jsx("span", { className: 'help-block z-index-max', children: _jsx("span", { children: errorMessage }) }))] }));
116
117
  };
117
118
  export default SaveableInput;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useCallback, useState } from 'react';
3
3
  import { closestCenter, DndContext, KeyboardSensor, PointerSensor, useSensor, useSensors, } from '@dnd-kit/core';
4
- import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, } from '@dnd-kit/sortable';
4
+ import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable';
5
5
  import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
6
6
  import TableSettingsListItem from './TableSettingsListItem';
7
7
  export const TableSettingsListContainer = (props) => {
@@ -25,7 +25,9 @@ exports.ApplicationHeader = (0, react_1.forwardRef)((props, ref) => {
25
25
  return typeof value === 'number' && Math.round(value);
26
26
  }
27
27
  }, [contentRect]);
28
- const containerWidth = getContentRect('width') || 0;
28
+ // If container width cannot be properly read initially, fall back to window width.
29
+ // This fixes ugly jumping on mobile header and desktop header on mount.
30
+ const containerWidth = getContentRect('width') || window.innerWidth;
29
31
  const isMobileWidth = containerWidth <= SCREEN_SM;
30
32
  const hasActionBarItems = !(0, isEmpty_1.default)(actionBarItems);
31
33
  const wrapperClassNames = (0, classnames_1.default)('ApplicationHeader', 'user-select-none', isMobileWidth && 'mobile', className && className);
@@ -43,7 +43,8 @@ const ApplicationLayoutBody = (0, react_1.forwardRef)((props, ref) => {
43
43
  const scrollWrapper = moduleContentRef.current.container;
44
44
  const scrollingElement = scrollWrapper.firstElementChild;
45
45
  const currentScroll = scrollingElement?.scrollTop ?? 0;
46
- if (currentScroll > 0) {
46
+ const scrollThreshold = 10;
47
+ if (currentScroll > scrollThreshold) {
47
48
  window.requestAnimationFrame(handleToTop);
48
49
  scrollingElement?.scrollTo(0, currentScroll - currentScroll / 5);
49
50
  scrollWrapper.classList.add('is-scrolling-to-top');
@@ -23,6 +23,8 @@ export type TreeGroup = {
23
23
  disabled?: boolean;
24
24
  /**
25
25
  * The rioglyph icon name for a group.
26
+ *
27
+ * The prefix `rioglyph-` can be omitted.
26
28
  */
27
29
  icon?: string;
28
30
  /**
@@ -45,13 +47,28 @@ export type TreeItem = {
45
47
  */
46
48
  info?: string | React.ReactNode;
47
49
  /**
48
- * The type of an item which is also the name of the respective rioglyph icon without the prefix
49
- * `rioglyph-`.
50
+ * The primary type of the item.
51
+ *
52
+ * This is also used as the fallback icon name and refers to the name of the respective
53
+ * rioglyph icon (excluding the `rioglyph-` prefix).
50
54
  */
51
55
  type: string;
52
56
  /**
53
- * The sub type of an item which is also the name of the respective rioglyph icon without the prefix.
54
- * This could be used to show a secondary paired icon like for fuel type.
57
+ * Optional icon override for the item.
58
+ *
59
+ * - If set to a string (e.g. `'truck'`), this icon will be used explicitly.
60
+ * - If set to `undefined`, the `type` property will be used as the fallback icon.
61
+ * - If set to `null`, no icon will be rendered, even if `type` is defined.
62
+ *
63
+ * This allows full control over the icon behavior while maintaining backward compatibility with type-based icons.
64
+ */
65
+ icon?: string | null;
66
+ /**
67
+ * Optional sub-type of the item.
68
+ *
69
+ * This refers to the name of an additional rioglyph icon (excluding the `rioglyph-` prefix),
70
+ * typically used to render a secondary icon next to the primary one (e.g. for fuel type or
71
+ * equipment variations).
55
72
  */
56
73
  subType?: string;
57
74
  /**
@@ -8,9 +8,21 @@ const classnames_1 = tslib_1.__importDefault(require("classnames"));
8
8
  const isObject_1 = tslib_1.__importDefault(require("lodash/fp/isObject"));
9
9
  const Checkbox_1 = tslib_1.__importDefault(require("../checkbox/Checkbox"));
10
10
  const RadioButton_1 = tslib_1.__importDefault(require("../radiobutton/RadioButton"));
11
+ const getIconRenderInfo = (item) => {
12
+ if (item.icon === null) {
13
+ // explicit opt-out
14
+ return { primaryIcon: null, subIcon: null };
15
+ }
16
+ // fallback to type
17
+ const primaryIcon = item.icon ?? item.type;
18
+ // treat subType as pair icon name
19
+ const subIcon = item.subType ?? null;
20
+ return { primaryIcon, subIcon };
21
+ };
11
22
  const TreeLeaf = react_1.default.memo((props) => {
12
23
  const { item, hasMultiselect, showRadioButtons, isSelected, onSelectItem, onActiveItem } = props;
13
24
  const treeNodeClassNames = (0, classnames_1.default)('TreeLeaf', 'form-group margin-bottom-0', isSelected && 'active', item.className && item.className);
14
- return ((0, jsx_runtime_1.jsxs)("div", { className: treeNodeClassNames, "data-key": item.id, children: [hasMultiselect && (0, jsx_runtime_1.jsx)(Checkbox_1.default, { className: 'TreeCheckbox', checked: isSelected, onClick: onSelectItem }), !hasMultiselect && showRadioButtons && ((0, jsx_runtime_1.jsx)(RadioButton_1.default, { className: 'TreeRadioButton', checked: isSelected, onChange: onSelectItem })), (0, jsx_runtime_1.jsxs)("span", { className: 'TreeLabel TreeLabelName', onClick: onActiveItem, children: [!item.subType && (0, jsx_runtime_1.jsx)("span", { className: `rioglyph rioglyph-${item.type}` }), item.subType && ((0, jsx_runtime_1.jsxs)("span", { className: 'rioglyph-icon-pair', children: [(0, jsx_runtime_1.jsx)("span", { className: `rioglyph rioglyph-${item.type}` }), (0, jsx_runtime_1.jsx)("span", { className: `rioglyph rioglyph-${item.subType}` })] })), (0, jsx_runtime_1.jsxs)("span", { className: 'TreeLabelNameText', children: [(0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameTextHeadline', children: (0, isObject_1.default)(item.name) ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: 'text-light margin-right-3', children: item.name.firstName }), (0, jsx_runtime_1.jsx)("span", { children: item.name.lastName })] })) : (item.name) }), item.info && (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameTextSubline', children: item.info })] })] })] }));
25
+ const { primaryIcon, subIcon } = getIconRenderInfo(item);
26
+ return ((0, jsx_runtime_1.jsxs)("div", { className: treeNodeClassNames, "data-key": item.id, children: [hasMultiselect && (0, jsx_runtime_1.jsx)(Checkbox_1.default, { className: 'TreeCheckbox', checked: isSelected, onClick: onSelectItem }), !hasMultiselect && showRadioButtons && ((0, jsx_runtime_1.jsx)(RadioButton_1.default, { className: 'TreeRadioButton', checked: isSelected, onChange: onSelectItem })), (0, jsx_runtime_1.jsxs)("span", { className: 'TreeLabel TreeLabelName', onClick: onActiveItem, children: [primaryIcon && !subIcon && (0, jsx_runtime_1.jsx)("span", { className: `rioglyph rioglyph-${primaryIcon}` }), primaryIcon && subIcon && ((0, jsx_runtime_1.jsxs)("span", { className: 'rioglyph-icon-pair', children: [(0, jsx_runtime_1.jsx)("span", { className: `rioglyph rioglyph-${primaryIcon}` }), (0, jsx_runtime_1.jsx)("span", { className: `rioglyph rioglyph-${subIcon}` })] })), (0, jsx_runtime_1.jsxs)("span", { className: 'TreeLabelNameText', children: [(0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameTextHeadline', children: (0, isObject_1.default)(item.name) ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: 'text-light margin-right-3', children: item.name.firstName }), (0, jsx_runtime_1.jsx)("span", { children: item.name.lastName })] })) : (item.name) }), item.info && (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameTextSubline', children: item.info })] })] })] }));
15
27
  });
16
28
  exports.default = TreeLeaf;
@@ -5,10 +5,18 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const classnames_1 = tslib_1.__importDefault(require("classnames"));
7
7
  const Checkbox_1 = tslib_1.__importDefault(require("../checkbox/Checkbox"));
8
+ // Add prefix `rioglyph-` if icon is given and does not start with the prefix
9
+ const withRioglyphPrefix = (name) => {
10
+ if (!name) {
11
+ return null;
12
+ }
13
+ return name.startsWith('rioglyph-') ? name : `rioglyph-${name}`;
14
+ };
8
15
  const TreeNode = react_1.default.memo((props) => {
9
16
  const { node, hasMultiselect = false, isSelected = false, isIndeterminate = false, onToggleNode, onSelect } = props;
10
17
  const treeNodeClassNames = (0, classnames_1.default)('TreeNode', 'from-group', isSelected && 'checked', node.className && node.className);
11
18
  const hasChildren = !!node.items.length;
12
- return ((0, jsx_runtime_1.jsxs)("div", { className: treeNodeClassNames, "data-key": node.id, onClick: () => hasChildren && onToggleNode(node.id), children: [hasMultiselect && ((0, jsx_runtime_1.jsx)(Checkbox_1.default, { className: 'TreeCheckbox', checked: isSelected, disabled: node.disabled, indeterminate: isIndeterminate, onClick: () => onSelect(node, isIndeterminate) })), (0, jsx_runtime_1.jsxs)("span", { className: 'TreeLabel TreeLabelName', children: [node.icon && (0, jsx_runtime_1.jsx)("span", { className: `rioglyph ${node.icon}` }), (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameText', children: (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameTextHeadline', children: node.name }) }), (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelCount label label-muted label-filled label-condensed', children: node.items.length }), (0, jsx_runtime_1.jsx)("span", { className: `TreeLabelExpander rioglyph rioglyph-chevron-down ${hasChildren ? '' : 'text-color-light'}` })] })] }));
19
+ const iconName = withRioglyphPrefix(node.icon);
20
+ return ((0, jsx_runtime_1.jsxs)("div", { className: treeNodeClassNames, "data-key": node.id, onClick: () => hasChildren && onToggleNode(node.id), children: [hasMultiselect && ((0, jsx_runtime_1.jsx)(Checkbox_1.default, { className: 'TreeCheckbox', checked: isSelected, disabled: node.disabled, indeterminate: isIndeterminate, onClick: () => onSelect(node, isIndeterminate) })), (0, jsx_runtime_1.jsxs)("span", { className: 'TreeLabel TreeLabelName', children: [iconName && (0, jsx_runtime_1.jsx)("span", { className: `rioglyph ${iconName}` }), (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameText', children: (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelNameTextHeadline', children: node.name }) }), (0, jsx_runtime_1.jsx)("span", { className: 'TreeLabelCount label label-muted label-filled label-condensed', children: node.items.length }), (0, jsx_runtime_1.jsx)("span", { className: `TreeLabelExpander rioglyph rioglyph-chevron-down ${hasChildren ? '' : 'text-color-light'}` })] })] }));
13
21
  });
14
22
  exports.default = TreeNode;
@@ -17,6 +17,14 @@ export type SaveableDateInputProps = {
17
17
  * @default true
18
18
  */
19
19
  isValid?: boolean;
20
+ /**
21
+ * This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false.
22
+ */
23
+ errorMessage?: string | React.ReactNode;
24
+ /**
25
+ * Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false.
26
+ */
27
+ hideErrorIcon?: boolean;
20
28
  /**
21
29
  * Callback function triggered when the value changes and is saved.
22
30
  * @param value
@@ -17,7 +17,7 @@ const DEFAULT_BUTTON_STYLE = 'primary';
17
17
  // - close edit mode only if date is valid - or close edit mode and reset to initial value -> customizable via prop
18
18
  // Keep picker open until user has clicked save, otherwise he might forget to click save if the dropdown closes automatically
19
19
  const SaveableDateInput = (props) => {
20
- const { placeholder, value: externalValue = '', isValid = true, onValueChanged = noop_1.default, onInputChange, // for controlled usage
20
+ const { placeholder, value: externalValue = '', isValid = true, errorMessage, hideErrorIcon = false, onValueChanged = noop_1.default, onInputChange, // for controlled usage
21
21
  onEnterEdit = noop_1.default, onExitEdit = noop_1.default, onCancel = noop_1.default, buttonStyle = DEFAULT_BUTTON_STYLE, inputClassName, inputProps, invalidExitBehavior = 'stay-open', datePickerProps = {}, disabled = false, className, ...remainingProps } = props;
22
22
  // if callback is provided, assume it is controlled case
23
23
  const isControlledCase = onInputChange !== undefined;
@@ -108,18 +108,26 @@ const SaveableDateInput = (props) => {
108
108
  }
109
109
  };
110
110
  const handleCloseDropdown = () => setIsPickerOpen(false);
111
- const wrapperClasses = (0, classnames_1.default)('form-group', className);
111
+ const wrapperClasses = (0, classnames_1.default)('form-group', !isValid && 'has-feedback has-error', className);
112
112
  const buttonIconClasses = (0, classnames_1.default)('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');
113
113
  const dateInputClasses = (0, classnames_1.default)('margin-0 width-100pct', inputClassName);
114
114
  // Button should be disabled if:
115
115
  // - Component is disabled, OR
116
116
  // - In edit mode and invalid input (and behavior is stay-open)
117
117
  const disableButton = disabled || (editInput && !isValid && invalidExitBehavior === 'stay-open');
118
- return ((0, jsx_runtime_1.jsx)("div", { ref: wrapperRef, ...remainingProps, className: wrapperClasses, children: (0, jsx_runtime_1.jsxs)("div", { className: 'input-group', children: [(0, jsx_runtime_1.jsx)(DatePicker_1.default, { ...datePickerProps, open: isPickerOpen, className: dateInputClasses, inputProps: {
119
- ...inputProps,
120
- placeholder,
121
- disabled: !editInput,
122
- style: { borderTopRightRadius: 0, borderBottomRightRadius: 0 },
123
- }, value: inputValue, onChange: handleDateChange, onClose: handleCloseDropdown }), (0, jsx_runtime_1.jsx)("div", { className: 'input-group-btn', children: (0, jsx_runtime_1.jsx)(Button_1.default, { ref: buttonRef, bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: (0, jsx_runtime_1.jsx)("span", { className: buttonIconClasses }) }) })] }) }));
118
+ let inputStyle = {
119
+ borderTopRightRadius: 0,
120
+ borderBottomRightRadius: 0,
121
+ };
122
+ if (!isValid && hideErrorIcon) {
123
+ // If the error icon shall not be shown, remove the input padding to avoid cutting of the date value
124
+ inputStyle = { ...inputStyle, paddingRight: '10px' };
125
+ }
126
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: wrapperRef, ...remainingProps, className: wrapperClasses, children: [(0, jsx_runtime_1.jsxs)("div", { className: 'input-group', children: [(0, jsx_runtime_1.jsx)(DatePicker_1.default, { ...datePickerProps, open: isPickerOpen, className: dateInputClasses, inputProps: {
127
+ ...inputProps,
128
+ placeholder,
129
+ disabled: !editInput,
130
+ style: inputStyle,
131
+ }, value: inputValue, onChange: handleDateChange, onClose: handleCloseDropdown }), !isValid && !hideErrorIcon && ((0, jsx_runtime_1.jsx)("span", { className: 'right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' })), (0, jsx_runtime_1.jsx)("div", { className: 'input-group-btn', children: (0, jsx_runtime_1.jsx)(Button_1.default, { ref: buttonRef, bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: (0, jsx_runtime_1.jsx)("span", { className: buttonIconClasses }) }) })] }), !isValid && errorMessage && ((0, jsx_runtime_1.jsx)("span", { className: 'help-block z-index-max', children: (0, jsx_runtime_1.jsx)("span", { children: errorMessage }) }))] }));
124
132
  };
125
133
  exports.default = SaveableDateInput;
@@ -25,6 +25,14 @@ export type SaveableInputProps = {
25
25
  * @default true
26
26
  */
27
27
  isValid?: boolean;
28
+ /**
29
+ * This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the "isValid" prop is set to false.
30
+ */
31
+ errorMessage?: string | React.ReactNode;
32
+ /**
33
+ * Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop is set to false.
34
+ */
35
+ hideErrorIcon?: boolean;
28
36
  /**
29
37
  * Callback function triggered when the value changes.
30
38
  * @param value
@@ -32,7 +32,7 @@ const useFocus = (isEditable) => {
32
32
  // [x] allow for unit and icon
33
33
  // [x] disabled input
34
34
  const SaveableInput = (props) => {
35
- const { placeholder, fixedPreviousValue = '', previousValue = '', value: externalValue = '', isValid = true, onValueChanged = noop_1.default, onInputChange, onEsc = noop_1.default, onEnterEdit = noop_1.default, buttonStyle = DEFAULT_BUTTON_STYLE, inputClassName, inputProps, icon, unit, disabled = false, className, ...remainingProps } = props;
35
+ const { placeholder, fixedPreviousValue = '', previousValue = '', value: externalValue = '', isValid = true, errorMessage, hideErrorIcon = false, onValueChanged = noop_1.default, onInputChange, onEsc = noop_1.default, onEnterEdit = noop_1.default, buttonStyle = DEFAULT_BUTTON_STYLE, inputClassName, inputProps, icon, unit, disabled = false, className, ...remainingProps } = props;
36
36
  const externalOldValue = previousValue || fixedPreviousValue;
37
37
  const [inputValue, setInputValue] = (0, react_1.useState)(externalValue);
38
38
  const [oldInputValue, setOldInputValue] = (0, react_1.useState)(externalOldValue);
@@ -109,12 +109,13 @@ const SaveableInput = (props) => {
109
109
  const handleFocus = () => setIsFocused(true);
110
110
  const handleBlur = () => setIsFocused(false);
111
111
  const showOldValue = !(0, isEmpty_1.default)(oldInputValue) && oldInputValue !== inputValue && !editInput;
112
- const wrapperClasses = (0, classnames_1.default)('form-group', className);
112
+ const wrapperClasses = (0, classnames_1.default)('form-group', !isValid && 'has-feedback has-error', className);
113
113
  const inputClasses = (0, classnames_1.default)('form-control', showOldValue && 'padding-bottom-0 padding-top-10 text-size-12', unit && 'padding-right-50', // This value is not perfect as with longer units it might conflict with the value
114
+ !unit && !isValid && hideErrorIcon && 'padding-right-10', // remove the padding for the error icon if not needed
114
115
  inputClassName);
115
116
  const oldValueClasses = (0, classnames_1.default)('position-absolute', 'top-2', 'left-10', 'margin-left-3', 'text-size-10', 'text-decoration-line-through', icon && 'padding-left-20');
116
117
  const buttonIconClasses = (0, classnames_1.default)('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');
117
118
  const disableButton = (editInput && !isValid) || disabled;
118
- return ((0, jsx_runtime_1.jsx)("div", { ...remainingProps, className: wrapperClasses, children: (0, jsx_runtime_1.jsxs)("div", { className: 'input-group', children: [icon && ((0, jsx_runtime_1.jsx)("span", { className: 'input-group-addon', children: (0, jsx_runtime_1.jsx)("span", { className: `rioglyph ${icon}`, "aria-hidden": 'true', "aria-label": 'input icon' }) })), (0, jsx_runtime_1.jsx)("input", { type: 'text', ref: inputRef, placeholder: placeholder, className: inputClasses, value: inputValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, disabled: !editInput, ...inputProps }), unit && ((0, jsx_runtime_1.jsx)("div", { className: 'position-absolute right-0 margin-right-50', "aria-label": 'unit', children: unit })), showOldValue && ((0, jsx_runtime_1.jsx)("div", { className: oldValueClasses, "aria-label": 'previous value', children: oldInputValue })), (0, jsx_runtime_1.jsx)("div", { className: 'input-group-btn', children: (0, jsx_runtime_1.jsx)(Button_1.default, { bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: (0, jsx_runtime_1.jsx)("span", { className: buttonIconClasses }) }) })] }) }));
119
+ return ((0, jsx_runtime_1.jsxs)("div", { ...remainingProps, className: wrapperClasses, children: [(0, jsx_runtime_1.jsxs)("div", { className: 'input-group', children: [icon && ((0, jsx_runtime_1.jsx)("span", { className: 'input-group-addon', children: (0, jsx_runtime_1.jsx)("span", { className: `rioglyph ${icon}`, "aria-hidden": 'true', "aria-label": 'input icon' }) })), (0, jsx_runtime_1.jsx)("input", { type: 'text', ref: inputRef, placeholder: placeholder, className: inputClasses, value: inputValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, disabled: !editInput, ...inputProps }), unit && ((0, jsx_runtime_1.jsx)("div", { className: 'position-absolute right-0 margin-right-50', "aria-label": 'unit', children: unit })), showOldValue && ((0, jsx_runtime_1.jsx)("div", { className: oldValueClasses, "aria-label": 'previous value', children: oldInputValue })), (0, jsx_runtime_1.jsx)("div", { className: 'input-group-btn', children: (0, jsx_runtime_1.jsx)(Button_1.default, { bsStyle: buttonStyle, iconOnly: true, onClick: handleToggleInput, disabled: disableButton, children: (0, jsx_runtime_1.jsx)("span", { className: buttonIconClasses }) }) })] }), !isValid && !hideErrorIcon && !unit && ((0, jsx_runtime_1.jsx)("span", { className: 'right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' })), !isValid && errorMessage && ((0, jsx_runtime_1.jsx)("span", { className: 'help-block z-index-max', children: (0, jsx_runtime_1.jsx)("span", { children: errorMessage }) }))] }));
119
120
  };
120
121
  exports.default = SaveableInput;
@@ -1,79 +1,79 @@
1
1
  {
2
- "always-color-white": "#ffffff",
3
- "always-color-black": "#000000",
4
- "color-white": "#ffffff",
5
- "color-black": "#000000",
6
- "gray-darkest": "#2a3740",
7
- "gray-darker": "#4C5667",
8
- "gray-dark": "#697A8B",
9
- "gray": "#A7AFBB",
10
- "gray-light": "#D0D8DE",
11
- "gray-lighter": "#E5EBF0",
12
- "gray-lightest": "#f6f8f9",
13
- "gray-decent": "#fcfcfd",
14
- "brand-primary": "#30b4c0",
15
- "brand-secondary": "#b23672",
16
- "brand-primary-decent": "#f4fbfc",
17
- "brand-secondary-decent": "#fbf5f8",
18
- "brand-info": "#4B80A6",
19
- "brand-success": "#5cb85c",
20
- "brand-warning": "#ff8e3c",
21
- "brand-danger": "#e22837",
22
- "brand-info-decent": "#f5f8fb",
23
- "brand-success-decent": "#f6fbf5",
24
- "brand-warning-decent": "#fdf5f0",
25
- "brand-danger-decent": "#fdf3f3",
26
- "color-code": "#f3f3f4",
27
- "color-status-available": "#239b7d",
28
- "color-status-driving": "#3690ae",
29
- "color-status-resting": "#626b72",
30
- "color-status-working": "#94488b",
31
- "color-map-marker-text": "#ffffff",
32
- "color-map-marker-active": "#ffffff",
33
- "color-map-marker-asset": "#2a3740",
34
- "color-map-marker-poi": "#d63f7f",
35
- "color-map-marker-geofence": "#f9636e",
36
- "color-map-marker-route": "#36afd7",
37
- "color-map-marker-info": "#3f759b",
38
- "color-map-marker-success": "#5cb85c",
39
- "color-map-marker-warning": "#ff8e3c",
40
- "color-map-marker-danger": "#e22837",
41
- "color-map-marker-restrictions": "#8F68ED",
42
- "color-rating-1": "#e22837",
43
- "color-rating-2": "#ff8e3c",
44
- "color-rating-3": "#f8c575",
45
- "color-rating-4": "#5cb85c",
46
- "color-rating-5": "#4b924c",
47
- "color-highlight-darkest": "#154b56",
48
- "color-highlight-darker": "#206e7e",
49
- "color-highlight-dark": "#268897",
50
- "color-highlight": "#30b4c0",
51
- "color-highlight-light": "#8ddbe3",
52
- "color-highlight-lighter": "#cef0f3",
53
- "color-highlight-lightest": "#ebf9fa",
54
- "color-highlight-decent": "#f3fbfc",
55
- "color-coldplay-wine": "#520D4E",
56
- "color-coldplay-aubergine": "#5a4876",
57
- "color-coldplay-kashmir": "#536E8B",
58
- "color-coldplay-fountain": "#67abc5",
59
- "color-coldplay-turquoise": "#4ECCC1",
60
- "color-coldplay-bermuda": "#79D4B3",
61
- "color-coldplay-moos": "#A1DAA3",
62
- "color-coldplay-primrose": "#C7E291",
63
- "color-coldplay-khaki": "#F0EB83",
64
- "color-warmup-crimson": "#31144F",
65
- "color-warmup-victoria": "#493D6D",
66
- "color-warmup-cadillac": "#7E3E72",
67
- "color-warmup-raspberry": "#B23672",
68
- "color-warmup-cerise": "#E72472",
69
- "color-warmup-charm": "#C9778D",
70
- "color-warmup-salmon": "#F19588",
71
- "color-warmup-cherokee": "#F5BB89",
72
- "color-warmup-corn": "#FDE082",
73
- "color-spectrum-indigo": "#8e96eb",
74
- "color-spectrum-violet": "#ad91f3",
75
- "color-spectrum-purple": "#c08eeb",
76
- "color-spectrum-fuchsia": "#dc82e9",
77
- "color-spectrum-pink": "#e878b6",
78
- "color-spectrum-rose": "#ef7186"
2
+ "always-color-white": "#ffffff ",
3
+ "always-color-black": "#000000 ",
4
+ "color-white": "#ffffff ",
5
+ "color-black": "#000000 ",
6
+ "gray-darkest": "#2a3740 ",
7
+ "gray-darker": "#4c5667 ",
8
+ "gray-dark": "#697a8b ",
9
+ "gray": "#a7afbb ",
10
+ "gray-light": "#d0d8de ",
11
+ "gray-lighter": "#e5ebf0 ",
12
+ "gray-lightest": "#f6f8f9 ",
13
+ "gray-decent": "#fcfcfd ",
14
+ "brand-primary": "#30b4c0 ",
15
+ "brand-secondary": "#b23672 ",
16
+ "brand-primary-decent": "#f4fbfc ",
17
+ "brand-secondary-decent": "#fbf5f8 ",
18
+ "brand-info": "#4b80a6 ",
19
+ "brand-success": "#5cb85c ",
20
+ "brand-warning": "#ff8e3c ",
21
+ "brand-danger": "#e22837 ",
22
+ "brand-info-decent": "#f5f8fb ",
23
+ "brand-success-decent": "#f6fbf5 ",
24
+ "brand-warning-decent": "#fdf5f0 ",
25
+ "brand-danger-decent": "#fdf3f3 ",
26
+ "color-code": "#f3f3f4 ",
27
+ "color-status-available": "#239b7d ",
28
+ "color-status-driving": "#3690ae ",
29
+ "color-status-resting": "#626b72 ",
30
+ "color-status-working": "#94488b ",
31
+ "color-map-marker-text": "#ffffff ",
32
+ "color-map-marker-active": "#ffffff ",
33
+ "color-map-marker-asset": "#2a3740 ",
34
+ "color-map-marker-poi": "#d63f7f ",
35
+ "color-map-marker-geofence": "#f9636e ",
36
+ "color-map-marker-route": "#36afd7 ",
37
+ "color-map-marker-info": "#3f759b ",
38
+ "color-map-marker-success": "#5cb85c ",
39
+ "color-map-marker-warning": "#ff8e3c ",
40
+ "color-map-marker-danger": "#e22837 ",
41
+ "color-map-marker-restrictions": "#8f68ed ",
42
+ "color-rating-1": "#e22837 ",
43
+ "color-rating-2": "#ff8e3c ",
44
+ "color-rating-3": "#f8c575 ",
45
+ "color-rating-4": "#5cb85c ",
46
+ "color-rating-5": "#4b924c ",
47
+ "color-highlight-darkest": "#154b56 ",
48
+ "color-highlight-darker": "#206e7e ",
49
+ "color-highlight-dark": "#268897 ",
50
+ "color-highlight": "#30b4c0 ",
51
+ "color-highlight-light": "#8ddbe3 ",
52
+ "color-highlight-lighter": "#cef0f3 ",
53
+ "color-highlight-lightest": "#ebf9fa ",
54
+ "color-highlight-decent": "#f3fbfc ",
55
+ "color-coldplay-wine": "#520d4e ",
56
+ "color-coldplay-aubergine": "#5a4876 ",
57
+ "color-coldplay-kashmir": "#536e8b ",
58
+ "color-coldplay-fountain": "#67abc5 ",
59
+ "color-coldplay-turquoise": "#4eccc1 ",
60
+ "color-coldplay-bermuda": "#79d4b3 ",
61
+ "color-coldplay-moos": "#a1daa3 ",
62
+ "color-coldplay-primrose": "#c7e291 ",
63
+ "color-coldplay-khaki": "#f0eb83 ",
64
+ "color-warmup-crimson": "#31144f ",
65
+ "color-warmup-victoria": "#493d6d ",
66
+ "color-warmup-cadillac": "#7e3e72 ",
67
+ "color-warmup-raspberry": "#b23672 ",
68
+ "color-warmup-cerise": "#e72472 ",
69
+ "color-warmup-charm": "#c9778d ",
70
+ "color-warmup-salmon": "#f19588 ",
71
+ "color-warmup-cherokee": "#f5bb89 ",
72
+ "color-warmup-corn": "#fde082 ",
73
+ "color-spectrum-indigo": "#8e96eb ",
74
+ "color-spectrum-violet": "#ad91f3 ",
75
+ "color-spectrum-purple": "#c08eeb ",
76
+ "color-spectrum-fuchsia": "#dc82e9 ",
77
+ "color-spectrum-pink": "#e878b6 ",
78
+ "color-spectrum-rose": "#ef7186 "
79
79
  }
@@ -20,7 +20,7 @@ const initCSS = () => {
20
20
  }
21
21
  (0, initConfig_1.debug)('Checking for UIKIT CSS in document head.');
22
22
  const hasUikitCssLink = documentHasAnyOf(['link[href*="rio-uikit.css"]', 'link[href*="rio-uikit-core.css"]']);
23
- const isUikitDemoPage = documentHas('style[data-vite-dev-id*="uikit.less"]');
23
+ const isUikitDemoPage = documentHas('style[data-vite-dev-id*="uikit.scss"]');
24
24
  const hasUikitBrandCssLink = documentHasAnyOf([
25
25
  'link[href*="man-uikit.css"]',
26
26
  'link[href*="vw-uikit.css"]',
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.9.0"
2
+ "version": "1.10.0"
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rio-cloud/rio-uikit",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "The RIO UIKIT component library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,6 +25,7 @@
25
25
  "build:style-traton": "vite build --mode style-traton",
26
26
  "build:style-xmas": "vite build --mode style-xmas",
27
27
  "build:rioglyph": "svgo -f rioglyph/svgs && vite build --mode rioglyph",
28
+ "build:rioglyph-local": "svgo -f rioglyph/svgs && vite build --mode rioglyph-local",
28
29
  "fixCssMinified": "node tools/fixCssMinified.mjs",
29
30
  "format-code": "npm run format-code:uikit && npm run format-code:demo",
30
31
  "format-code:uikit": "biome format --write src",
@@ -45,35 +46,24 @@
45
46
  "main": "lib/es/index.js",
46
47
  "module": "index.js",
47
48
  "types": "index.d.ts",
48
- "less": "./styles/css/rio-uikit.less",
49
49
  "files": [
50
50
  "**/*.*"
51
51
  ],
52
- "exports": {
53
- ".": {
54
- "import": "./index.js",
55
- "types": "./index.d.ts"
56
- },
57
- "./*": {
58
- "import": "./*.js",
59
- "types": "./*.d.ts"
60
- }
61
- },
62
52
  "devDependencies": {
63
- "@biomejs/biome": "2.0.5",
53
+ "@biomejs/biome": "2.1.2",
64
54
  "@testing-library/dom": "10.4.0",
65
55
  "@testing-library/jest-dom": "6.6.3",
66
56
  "@testing-library/react": "16.3.0",
67
57
  "@testing-library/react-hooks": "8.0.1",
68
58
  "@testing-library/user-event": "14.6.1",
69
59
  "@types/heremaps": "3.1.14",
70
- "@types/lodash": "4.17.18",
60
+ "@types/lodash": "4.17.20",
71
61
  "@types/qs": "6.14.0",
72
62
  "@types/react": "18.3.18",
73
63
  "@types/react-dom": "18.3.5",
74
64
  "@types/react-redux": "7.1.34",
75
65
  "@types/resize-observer-browser": "0.1.11",
76
- "@vitejs/plugin-react": "4.6.0",
66
+ "@vitejs/plugin-react": "4.7.0",
77
67
  "@vitest/coverage-c8": "0.33.0",
78
68
  "autoprefixer": "10.4.21",
79
69
  "backstopjs": "6.3.25",
@@ -81,7 +71,6 @@
81
71
  "dotenv": "16.5.0",
82
72
  "jsdom": "26.1.0",
83
73
  "jsdom-global": "3.0.2",
84
- "less": "4.3.0",
85
74
  "license-checker": "25.0.1",
86
75
  "postcss": "8.5.6",
87
76
  "postcss-preset-env": "8.5.1",
@@ -91,8 +80,9 @@
91
80
  "react-dom": "18.0.0",
92
81
  "react-intl": "6.6.8",
93
82
  "rollup-plugin-copy": "3.5.0",
83
+ "sass": "^1.89.2",
94
84
  "strip-ansi": "7.1.0",
95
- "svgo": "3.3.2",
85
+ "svgo": "4.0.0",
96
86
  "tiny-invariant": "1.3.3",
97
87
  "typescript": "5.8.3",
98
88
  "vite": "6.3.5",
@@ -106,11 +96,11 @@
106
96
  },
107
97
  "dependencies": {
108
98
  "@dnd-kit/core": "6.3.1",
109
- "@dnd-kit/modifiers": "6.0.1",
110
- "@dnd-kit/sortable": "7.0.2",
99
+ "@dnd-kit/modifiers": "9.0.0",
100
+ "@dnd-kit/sortable": "10.0.0",
111
101
  "@formkit/auto-animate": "0.8.2",
112
102
  "@popperjs/core": "2.11.8",
113
- "@tanstack/react-virtual": "^3.13.11",
103
+ "@tanstack/react-virtual": "^3.13.12",
114
104
  "classnames": "2.5.1",
115
105
  "driver.js": "1.3.6",
116
106
  "events": "3.3.0",
@@ -123,7 +113,7 @@
123
113
  "prop-types": "15.8.1",
124
114
  "qs": "6.14.0",
125
115
  "react-bootstrap": "1.6.4",
126
- "react-content-loader": "7.0.2",
116
+ "react-content-loader": "7.1.1",
127
117
  "react-custom-scrollbars-2": "4.5.0",
128
118
  "react-datetime": "github:rio-cloud/react-datetime#v3.1.1-1-merged",
129
119
  "react-dropzone": "14.3.8",
@@ -1,79 +1,79 @@
1
1
  {
2
- "always-color-white": "#ffffff",
3
- "always-color-black": "#000000",
4
- "color-white": "#ffffff",
5
- "color-black": "#000000",
6
- "gray-darkest": "#2a3740",
7
- "gray-darker": "#4C5667",
8
- "gray-dark": "#697A8B",
9
- "gray": "#A7AFBB",
10
- "gray-light": "#D0D8DE",
11
- "gray-lighter": "#E5EBF0",
12
- "gray-lightest": "#f6f8f9",
13
- "gray-decent": "#fcfcfd",
14
- "brand-primary": "#30b4c0",
15
- "brand-secondary": "#b23672",
16
- "brand-primary-decent": "#f4fbfc",
17
- "brand-secondary-decent": "#fbf5f8",
18
- "brand-info": "#4B80A6",
19
- "brand-success": "#5cb85c",
20
- "brand-warning": "#ff8e3c",
21
- "brand-danger": "#e22837",
22
- "brand-info-decent": "#f5f8fb",
23
- "brand-success-decent": "#f6fbf5",
24
- "brand-warning-decent": "#fdf5f0",
25
- "brand-danger-decent": "#fdf3f3",
26
- "color-code": "#f3f3f4",
27
- "color-status-available": "#239b7d",
28
- "color-status-driving": "#3690ae",
29
- "color-status-resting": "#626b72",
30
- "color-status-working": "#94488b",
31
- "color-map-marker-text": "#ffffff",
32
- "color-map-marker-active": "#ffffff",
33
- "color-map-marker-asset": "#2a3740",
34
- "color-map-marker-poi": "#d63f7f",
35
- "color-map-marker-geofence": "#f9636e",
36
- "color-map-marker-route": "#36afd7",
37
- "color-map-marker-info": "#3f759b",
38
- "color-map-marker-success": "#5cb85c",
39
- "color-map-marker-warning": "#ff8e3c",
40
- "color-map-marker-danger": "#e22837",
41
- "color-map-marker-restrictions": "#8F68ED",
42
- "color-rating-1": "#e22837",
43
- "color-rating-2": "#ff8e3c",
44
- "color-rating-3": "#f8c575",
45
- "color-rating-4": "#5cb85c",
46
- "color-rating-5": "#4b924c",
47
- "color-highlight-darkest": "#154b56",
48
- "color-highlight-darker": "#206e7e",
49
- "color-highlight-dark": "#268897",
50
- "color-highlight": "#30b4c0",
51
- "color-highlight-light": "#8ddbe3",
52
- "color-highlight-lighter": "#cef0f3",
53
- "color-highlight-lightest": "#ebf9fa",
54
- "color-highlight-decent": "#f3fbfc",
55
- "color-coldplay-wine": "#520D4E",
56
- "color-coldplay-aubergine": "#5a4876",
57
- "color-coldplay-kashmir": "#536E8B",
58
- "color-coldplay-fountain": "#67abc5",
59
- "color-coldplay-turquoise": "#4ECCC1",
60
- "color-coldplay-bermuda": "#79D4B3",
61
- "color-coldplay-moos": "#A1DAA3",
62
- "color-coldplay-primrose": "#C7E291",
63
- "color-coldplay-khaki": "#F0EB83",
64
- "color-warmup-crimson": "#31144F",
65
- "color-warmup-victoria": "#493D6D",
66
- "color-warmup-cadillac": "#7E3E72",
67
- "color-warmup-raspberry": "#B23672",
68
- "color-warmup-cerise": "#E72472",
69
- "color-warmup-charm": "#C9778D",
70
- "color-warmup-salmon": "#F19588",
71
- "color-warmup-cherokee": "#F5BB89",
72
- "color-warmup-corn": "#FDE082",
73
- "color-spectrum-indigo": "#8e96eb",
74
- "color-spectrum-violet": "#ad91f3",
75
- "color-spectrum-purple": "#c08eeb",
76
- "color-spectrum-fuchsia": "#dc82e9",
77
- "color-spectrum-pink": "#e878b6",
78
- "color-spectrum-rose": "#ef7186"
2
+ "always-color-white": "#ffffff ",
3
+ "always-color-black": "#000000 ",
4
+ "color-white": "#ffffff ",
5
+ "color-black": "#000000 ",
6
+ "gray-darkest": "#2a3740 ",
7
+ "gray-darker": "#4c5667 ",
8
+ "gray-dark": "#697a8b ",
9
+ "gray": "#a7afbb ",
10
+ "gray-light": "#d0d8de ",
11
+ "gray-lighter": "#e5ebf0 ",
12
+ "gray-lightest": "#f6f8f9 ",
13
+ "gray-decent": "#fcfcfd ",
14
+ "brand-primary": "#30b4c0 ",
15
+ "brand-secondary": "#b23672 ",
16
+ "brand-primary-decent": "#f4fbfc ",
17
+ "brand-secondary-decent": "#fbf5f8 ",
18
+ "brand-info": "#4b80a6 ",
19
+ "brand-success": "#5cb85c ",
20
+ "brand-warning": "#ff8e3c ",
21
+ "brand-danger": "#e22837 ",
22
+ "brand-info-decent": "#f5f8fb ",
23
+ "brand-success-decent": "#f6fbf5 ",
24
+ "brand-warning-decent": "#fdf5f0 ",
25
+ "brand-danger-decent": "#fdf3f3 ",
26
+ "color-code": "#f3f3f4 ",
27
+ "color-status-available": "#239b7d ",
28
+ "color-status-driving": "#3690ae ",
29
+ "color-status-resting": "#626b72 ",
30
+ "color-status-working": "#94488b ",
31
+ "color-map-marker-text": "#ffffff ",
32
+ "color-map-marker-active": "#ffffff ",
33
+ "color-map-marker-asset": "#2a3740 ",
34
+ "color-map-marker-poi": "#d63f7f ",
35
+ "color-map-marker-geofence": "#f9636e ",
36
+ "color-map-marker-route": "#36afd7 ",
37
+ "color-map-marker-info": "#3f759b ",
38
+ "color-map-marker-success": "#5cb85c ",
39
+ "color-map-marker-warning": "#ff8e3c ",
40
+ "color-map-marker-danger": "#e22837 ",
41
+ "color-map-marker-restrictions": "#8f68ed ",
42
+ "color-rating-1": "#e22837 ",
43
+ "color-rating-2": "#ff8e3c ",
44
+ "color-rating-3": "#f8c575 ",
45
+ "color-rating-4": "#5cb85c ",
46
+ "color-rating-5": "#4b924c ",
47
+ "color-highlight-darkest": "#154b56 ",
48
+ "color-highlight-darker": "#206e7e ",
49
+ "color-highlight-dark": "#268897 ",
50
+ "color-highlight": "#30b4c0 ",
51
+ "color-highlight-light": "#8ddbe3 ",
52
+ "color-highlight-lighter": "#cef0f3 ",
53
+ "color-highlight-lightest": "#ebf9fa ",
54
+ "color-highlight-decent": "#f3fbfc ",
55
+ "color-coldplay-wine": "#520d4e ",
56
+ "color-coldplay-aubergine": "#5a4876 ",
57
+ "color-coldplay-kashmir": "#536e8b ",
58
+ "color-coldplay-fountain": "#67abc5 ",
59
+ "color-coldplay-turquoise": "#4eccc1 ",
60
+ "color-coldplay-bermuda": "#79d4b3 ",
61
+ "color-coldplay-moos": "#a1daa3 ",
62
+ "color-coldplay-primrose": "#c7e291 ",
63
+ "color-coldplay-khaki": "#f0eb83 ",
64
+ "color-warmup-crimson": "#31144f ",
65
+ "color-warmup-victoria": "#493d6d ",
66
+ "color-warmup-cadillac": "#7e3e72 ",
67
+ "color-warmup-raspberry": "#b23672 ",
68
+ "color-warmup-cerise": "#e72472 ",
69
+ "color-warmup-charm": "#c9778d ",
70
+ "color-warmup-salmon": "#f19588 ",
71
+ "color-warmup-cherokee": "#f5bb89 ",
72
+ "color-warmup-corn": "#fde082 ",
73
+ "color-spectrum-indigo": "#8e96eb ",
74
+ "color-spectrum-violet": "#ad91f3 ",
75
+ "color-spectrum-purple": "#c08eeb ",
76
+ "color-spectrum-fuchsia": "#dc82e9 ",
77
+ "color-spectrum-pink": "#e878b6 ",
78
+ "color-spectrum-rose": "#ef7186 "
79
79
  }
@@ -17,7 +17,7 @@ export const initCSS = () => {
17
17
  }
18
18
  debug('Checking for UIKIT CSS in document head.');
19
19
  const hasUikitCssLink = documentHasAnyOf(['link[href*="rio-uikit.css"]', 'link[href*="rio-uikit-core.css"]']);
20
- const isUikitDemoPage = documentHas('style[data-vite-dev-id*="uikit.less"]');
20
+ const isUikitDemoPage = documentHas('style[data-vite-dev-id*="uikit.scss"]');
21
21
  const hasUikitBrandCssLink = documentHasAnyOf([
22
22
  'link[href*="man-uikit.css"]',
23
23
  'link[href*="vw-uikit.css"]',
package/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.9.0"
2
+ "version": "1.10.0"
3
3
  }
@@ -1 +0,0 @@
1
- export declare const printPoweredByRIO: () => void;
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.printPoweredByRIO = void 0;
4
- const version_json_1 = require("../../version.json");
5
- const initConfig_1 = require("./initConfig");
6
- const logStyled = (message) => console.log('%c%s', 'color: #697a8b;', message);
7
- const printPoweredByRIO = () => {
8
- logStyled('- - - - - - - - - - - - - - - - - -');
9
- const message = [`RIO UIKIT Version ${version_json_1.version}\nhttps://uikit.developers.rio.cloud`];
10
- if (initConfig_1.isProd && !initConfig_1.isInIframe) {
11
- message.push('\n\nYou are a Developer? RIO is hiring!\nšŸ‘‰ https://rio.cloud/en/career šŸ‘ˆ');
12
- }
13
- logStyled(message.join(''));
14
- logStyled('- - - - - - - - - - - - - - - - - -');
15
- };
16
- exports.printPoweredByRIO = printPoweredByRIO;
@@ -1 +0,0 @@
1
- export declare const printPoweredByRIO: () => void;
@@ -1,12 +0,0 @@
1
- import { version } from '../../version.json';
2
- import { isInIframe, isProd } from './initConfig';
3
- const logStyled = (message) => console.log('%c%s', 'color: #697a8b;', message);
4
- export const printPoweredByRIO = () => {
5
- logStyled('- - - - - - - - - - - - - - - - - -');
6
- const message = [`RIO UIKIT Version ${version}\nhttps://uikit.developers.rio.cloud`];
7
- if (isProd && !isInIframe) {
8
- message.push('\n\nYou are a Developer? RIO is hiring!\nšŸ‘‰ https://rio.cloud/en/career šŸ‘ˆ');
9
- }
10
- logStyled(message.join(''));
11
- logStyled('- - - - - - - - - - - - - - - - - -');
12
- };