@iobroker/gui-components 10.3.15 → 10.3.16

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.
@@ -15,7 +15,7 @@ import { IconDocumentReadOnly } from '../../icons/IconDocumentReadOnly';
15
15
  import { Icon } from '../Icon';
16
16
  import { IconTrash } from '../AnimatedIcons/IconTrash';
17
17
  import { IconFolder } from '../AnimatedIcons/IconFolder';
18
- import { ButtonIcon, colGrow, colWidth, binarySearch, findEnumsForObjectAsIds, findFunctionsForObject, findRoomsForObject, formatValue, getCustomValue, getIdFieldTooltip, getObjectTooltip, getValueStyle, isNonExpertId, COLOR_NAME_USERDATA, COLOR_NAME_ALIAS, COLOR_NAME_JAVASCRIPT, COLOR_NAME_SYSTEM, COLOR_NAME_SYSTEM_ADAPTER, ROW_HEIGHT, } from './utils';
18
+ import { ButtonIcon, colGrow, colWidth, binarySearch, findEnumsForObjectAsIds, findFunctionsForObject, findRoomsForObject, formatValue, getCustomValue, getIdFieldTooltip, getObjectTooltip, getValueStyle, isNonExpertId, COLOR_NAME_USERDATA, COLOR_NAME_ALIAS, COLOR_NAME_JAVASCRIPT, COLOR_NAME_SYSTEM, COLOR_NAME_SYSTEM_ADAPTER, ROW_HEIGHT, TREND_DURATION, } from './utils';
19
19
  import { styles } from './styles';
20
20
  import { COLOR_NAME_CONNECTED_DARK, COLOR_NAME_CONNECTED_LIGHT, COLOR_NAME_DISCONNECTED_DARK, COLOR_NAME_DISCONNECTED_LIGHT, COLOR_NAME_ERROR_DARK, COLOR_NAME_ERROR_LIGHT, DEFAULT_DATE_FORMAT, ITEM_IMAGES, } from './constants';
21
21
  export function renderTooltipAccessControl(that, acl) {
@@ -179,6 +179,35 @@ export function renderColumnButtons(that, id, item) {
179
179
  React.createElement(IconConfig, { style: styles.cellButtonsButtonIcon }))) : null,
180
180
  ];
181
181
  }
182
+ const TREND_ARROW = {
183
+ up: 'M12 3L20.5 12.5H15V21H9V12.5H3.5Z',
184
+ down: 'M12 21L20.5 11.5H15V3H9V11.5H3.5Z',
185
+ };
186
+ /** The arrow of a row that is mounted again (e.g. after scrolling) continues where it was */
187
+ function continueTrendAnimation(el) {
188
+ if (el) {
189
+ el.style.animationDelay = `${Number(el.dataset.shown) - Date.now()}ms`;
190
+ }
191
+ }
192
+ /**
193
+ * Returns the last change of a number or a boolean of this state, if it is still to be shown
194
+ */
195
+ function getValueTrend(that, id) {
196
+ const trend = that.valueTrends[id];
197
+ if (!trend) {
198
+ return undefined;
199
+ }
200
+ const now = Date.now();
201
+ if (trend.shown === undefined) {
202
+ trend.shown = now;
203
+ }
204
+ // A change of a row that was not visible is not shown later
205
+ if (now - trend.shown > TREND_DURATION || now - trend.ts > TREND_DURATION + 1000) {
206
+ delete that.valueTrends[id];
207
+ return undefined;
208
+ }
209
+ return trend;
210
+ }
182
211
  /**
183
212
  * This function renders the value in different forms in the table
184
213
  *
@@ -206,8 +235,11 @@ export function renderColumnValue(that, id, item, narrowStyleWithDetails) {
206
235
  }
207
236
  that.recordState(id, id);
208
237
  const state = that.states[id];
238
+ const trend = getValueTrend(that, id);
209
239
  let info = item.data.state;
210
240
  if (!info) {
241
+ // A boolean that just changed flips, like a switch
242
+ const flip = trend?.dir === 'toggle' && Date.now() - trend.ts < 1000 ? ' iob-ob-flip' : '';
211
243
  const { valText } = formatValue({
212
244
  state,
213
245
  obj: obj,
@@ -219,7 +251,7 @@ export function renderColumnValue(that, id, item, narrowStyleWithDetails) {
219
251
  });
220
252
  const valTextRx = [];
221
253
  item.data.state = { valTextRx };
222
- valTextRx.push(React.createElement("span", { className: `newValueBrowser-${that.props.themeType || 'light'}`, key: `${valText.v.toString()}valText`, style: {
254
+ valTextRx.push(React.createElement("span", { className: `newValueBrowser-${that.props.themeType || 'light'}${flip}`, key: `${valText.v.toString()}valText`, style: {
223
255
  whiteSpace: 'nowrap',
224
256
  display: 'inline-block',
225
257
  overflow: 'hidden',
@@ -269,6 +301,14 @@ export function renderColumnValue(that, id, item, narrowStyleWithDetails) {
269
301
  ];
270
302
  }
271
303
  }
304
+ // A number that just changed shows for some seconds, if it went up or down
305
+ if (val && val === info.valTextRx && (trend?.dir === 'up' || trend?.dir === 'down')) {
306
+ const arrow = (React.createElement("span", { key: `trend${trend.ts}`, ref: continueTrendAnimation, "data-shown": trend.shown, className: `iob-ob-trend iob-ob-trend-${trend.dir}`, "aria-hidden": "true" },
307
+ React.createElement("svg", { viewBox: "0 0 24 24" },
308
+ React.createElement("path", { d: TREND_ARROW[trend.dir] }))));
309
+ const copyIndex = val.findIndex(el => el.key === 'cc');
310
+ val = copyIndex === -1 ? [...val, arrow] : [...val.slice(0, copyIndex), arrow, ...val.slice(copyIndex)];
311
+ }
272
312
  return (React.createElement(Tooltip, { key: "value", title: that.state.tooltipInfo?.el, slotProps: {
273
313
  popper: { sx: styles.cellValueTooltipBox },
274
314
  tooltip: { sx: styles.cellValueTooltip },