@iobroker/dm-gui-components 10.0.22 → 10.1.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.
- package/README.md +13 -0
- package/build/AnimatedIcons.d.ts +37 -0
- package/build/AnimatedIcons.js +108 -0
- package/build/AnimatedIcons.js.map +1 -0
- package/build/Communication.d.ts +7 -0
- package/build/Communication.js +43 -11
- package/build/Communication.js.map +1 -1
- package/build/DeviceCard.d.ts +25 -13
- package/build/DeviceCard.js +177 -282
- package/build/DeviceCard.js.map +1 -1
- package/build/DeviceControl.js +38 -26
- package/build/DeviceControl.js.map +1 -1
- package/build/DeviceImageUpload.d.ts +5 -1
- package/build/DeviceImageUpload.js +79 -62
- package/build/DeviceImageUpload.js.map +1 -1
- package/build/DeviceList.d.ts +8 -0
- package/build/DeviceList.js +74 -59
- package/build/DeviceList.js.map +1 -1
- package/build/DeviceStatus.d.ts +20 -4
- package/build/DeviceStatus.js +146 -191
- package/build/DeviceStatus.js.map +1 -1
- package/build/StatusIndicator.js +9 -37
- package/build/StatusIndicator.js.map +1 -1
- package/build/StatusPill.d.ts +18 -0
- package/build/StatusPill.js +30 -0
- package/build/StatusPill.js.map +1 -0
- package/build/Switch.d.ts +3 -0
- package/build/Switch.js +36 -26
- package/build/Switch.js.map +1 -1
- package/build/Utils.js +92 -60
- package/build/Utils.js.map +1 -1
- package/build/i18n/de.json +3 -0
- package/build/i18n/en.json +3 -0
- package/build/i18n/es.json +3 -0
- package/build/i18n/fr.json +3 -0
- package/build/i18n/it.json +3 -0
- package/build/i18n/nl.json +3 -0
- package/build/i18n/pl.json +3 -0
- package/build/i18n/pt.json +3 -0
- package/build/i18n/ru.json +3 -0
- package/build/i18n/uk.json +3 -0
- package/build/i18n/zh-cn.json +3 -0
- package/build/styles.d.ts +17 -0
- package/build/styles.js +226 -0
- package/build/styles.js.map +1 -0
- package/package.json +10 -10
package/build/Utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Utils.js","sourceRoot":"./src/","sources":["Utils.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport type { ActionBase, ControlBase, IndicatorColor } from './protocol/api';\nimport {\n Add,\n Article,\n BatteryAlert,\n BatteryChargingFull,\n BatteryFull,\n Bluetooth,\n BluetoothDisabled,\n Delete,\n Edit,\n FastForward,\n FastRewind,\n Fluorescent,\n Group,\n Info,\n Lightbulb,\n Link as LinkIcon,\n LinkOff,\n NotListedLocation,\n Pause,\n Person,\n PlayArrow,\n Power,\n QrCode,\n QuestionMark,\n Refresh,\n Search,\n Settings,\n Stop,\n Visibility,\n Upgrade,\n WbIncandescent,\n Wifi,\n WifiOff,\n Launch,\n} from '@mui/icons-material';\n\nimport { I18n, Icon, type IobTheme } from '@iobroker/gui-components';\n\n/**\n * Get Icon by font-awesome name. Do not use these names, use names from getIconByName\n *\n * @param icon font-awesome icon name\n * Only following font-awesome icons are supported:\n * - fa-trash-can, fa-trash\n * - fa-pen\n * - fa-redo-alt\n * - fa-plus\n * - fa-qrcode, qrcode\n * - fa-wifi\n * - fa-wifi-slash\n * - fa-bluetooth\n * - fa-bluetooth-slash\n * - fa-eye\n * - fa-search\n * - fa-unlink\n * - fa-link\n * - fa-search-location\n * - fa-play\n * - fa-stop\n * - fa-pause\n * @param color color of the icon\n */\nfunction getFaIcon(icon: string, color?: string): React.JSX.Element | null {\n const iconStyle = icon\n .split(' ')\n .map(s => s.trim())\n .filter(s => s !== 'fa-solid');\n\n if (iconStyle.includes('fa-trash-can') || iconStyle.includes('fa-trash')) {\n return <Delete style={{ color }} />;\n }\n if (iconStyle.includes('fa-pen')) {\n return <Edit style={{ color }} />;\n }\n if (iconStyle.includes('fa-redo-alt')) {\n return <Refresh style={{ color }} />;\n }\n if (iconStyle.includes('fa-plus')) {\n return <Add style={{ color }} />;\n }\n if (iconStyle.includes('fa-qrcode') || iconStyle.includes('qrcode')) {\n return <QrCode style={{ color }} />;\n }\n if (iconStyle.includes('fa-wifi')) {\n return <Wifi style={{ color }} />;\n }\n if (iconStyle.includes('fa-wifi-slash')) {\n return <WifiOff style={{ color }} />;\n }\n if (iconStyle.includes('fa-bluetooth')) {\n return <Bluetooth style={{ color }} />;\n }\n if (iconStyle.includes('fa-bluetooth-slash')) {\n return <BluetoothDisabled style={{ color }} />;\n }\n if (iconStyle.includes('fa-eye')) {\n return <Visibility style={{ color }} />;\n }\n if (iconStyle.includes('fa-search')) {\n return <Search style={{ color }} />;\n }\n if (iconStyle.includes('fa-unlink')) {\n return <LinkOff style={{ color }} />;\n }\n if (iconStyle.includes('fa-link')) {\n return <LinkIcon style={{ color }} />;\n }\n if (iconStyle.includes('fa-search-location')) {\n return <NotListedLocation style={{ color }} />;\n }\n if (iconStyle.includes('fa-play')) {\n return <PlayArrow style={{ color }} />;\n }\n if (iconStyle.includes('fa-stop')) {\n return <Stop style={{ color }} />;\n }\n if (iconStyle.includes('fa-pause')) {\n return <Pause style={{ color }} />;\n }\n return <QuestionMark style={{ color }} />;\n}\n\n/**\n * Get Icon by name or by action\n *\n * @param name action name\n * possible action or icon names are\n * - edit, rename\n * - delete\n * - refresh\n * - newDevice, new, add\n * - discover, search\n * - unpairDevice, unpair\n * - pairDevice, pair\n * - identify\n * - play\n * - stop\n * - pause\n * - forward, next\n * - rewind, previous\n * - lamp, light\n * - backlight\n * - dimmer\n * - socket\n * - settings\n * - users, group\n * - user\n * - qrcode\n * - identify\n * - info\n * - lines\n * - battery\n * - batteryLow, batteryAlert\n * - batteryCharging\n * @param altName icon name\n * @param color color of the icon\n * @param noDefaultIcon if true, no \"question mark\" icon will be returned for unknown names\n */\nfunction getIconByName(\n name: string,\n altName?: string,\n color?: string,\n noDefaultIcon?: boolean,\n): React.JSX.Element | null {\n if (name === 'edit' || name === 'rename' || altName === 'edit' || altName === 'rename') {\n return <Edit style={{ color }} />;\n }\n if (name === 'delete' || altName === 'delete') {\n return <Delete style={{ color }} />;\n }\n if (name === 'refresh' || altName === 'refresh') {\n return <Refresh style={{ color }} />;\n }\n if (\n name === 'newDevice' ||\n name === 'new' ||\n name === 'add' ||\n altName === 'newDevice' ||\n altName === 'new' ||\n altName === 'add'\n ) {\n return <Add style={{ color }} />;\n }\n if (name === 'discover' || name === 'search' || altName === 'discover' || altName === 'search') {\n return <Search style={{ color }} />;\n }\n if (name === 'unpairDevice' || name === 'unpair' || altName === 'unpairDevice' || altName === 'unpair') {\n return <LinkOff style={{ color }} />;\n }\n if (name === 'pairDevice' || name === 'pair' || altName === 'pairDevice' || altName === 'pair') {\n return <LinkIcon style={{ color }} />;\n }\n if (name === 'identify' || altName === 'identify') {\n return <NotListedLocation style={{ color }} />;\n }\n if (name === 'play' || altName === 'play') {\n return <PlayArrow style={{ color }} />;\n }\n if (name === 'stop' || altName === 'stop') {\n return <Stop style={{ color }} />;\n }\n if (name === 'pause' || altName === 'pause') {\n return <Pause style={{ color }} />;\n }\n if (name === 'forward' || name === 'next' || altName === 'forward' || altName === 'next') {\n return <FastForward style={{ color }} />;\n }\n if (name === 'rewind' || name === 'previous' || altName === 'rewind' || altName === 'previous') {\n return <FastRewind style={{ color }} />;\n }\n if (name === 'lamp' || name === 'light' || altName === 'lamp' || altName === 'light') {\n return <Lightbulb style={{ color }} />;\n }\n if (name === 'backlight' || altName === 'backlight') {\n return <Fluorescent style={{ color }} />;\n }\n if (name === 'dimmer' || altName === 'dimmer') {\n return <WbIncandescent style={{ color }} />;\n }\n if (name === 'socket' || altName === 'socket') {\n return <Power style={{ color }} />;\n }\n if (name === 'settings' || altName === 'settings') {\n return <Settings style={{ color }} />;\n }\n if (name === 'users' || name === 'group' || altName === 'users' || altName === 'group') {\n return <Group style={{ color }} />;\n }\n if (name === 'user' || altName === 'user') {\n return <Person style={{ color }} />;\n }\n if (name === 'update' || altName === 'update') {\n return <Upgrade style={{ color }} />;\n }\n if (name === 'qrcode' || altName === 'qrcode') {\n return <QrCode style={{ color }} />;\n }\n if (name === 'info' || altName === 'info') {\n return <Info style={{ color }} />;\n }\n if (name === 'lines' || altName === 'lines') {\n return <Article style={{ color }} />;\n }\n if (name === 'web' || altName === 'web') {\n return <Launch style={{ color }} />;\n }\n if (name === 'battery' || altName === 'battery') {\n return <BatteryFull style={{ color }} />;\n }\n if (name === 'batteryLow' || name === 'batteryAlert' || altName === 'batteryLow' || altName === 'batteryAlert') {\n return <BatteryAlert style={{ color }} />;\n }\n if (name === 'batteryCharging' || altName === 'batteryCharging') {\n return <BatteryChargingFull style={{ color }} />;\n }\n if (noDefaultIcon) {\n return null;\n }\n return <QuestionMark style={{ color }} />;\n}\n\nexport function renderControlIcon(\n action: ControlBase,\n colors?: { primary: string; secondary: string },\n value?: string | number | boolean | null,\n noDefaultIcon?: boolean,\n): React.JSX.Element | null {\n if (!action) {\n return null;\n }\n\n let color = (value && action.colorOn) || action.color || (action.state ? 'primary' : 'inherit');\n\n if (colors) {\n if (color === 'primary') {\n color = colors.primary;\n } else if (color === 'secondary') {\n color = colors.secondary;\n }\n }\n\n if (action.icon?.startsWith('fa-') || action.icon?.startsWith('fas')) {\n return getFaIcon(action.icon, color);\n }\n if (value && action.iconOn?.startsWith('data:image')) {\n return (\n <Icon\n src={action.iconOn}\n style={{ color }}\n />\n );\n }\n if (action.icon?.startsWith('data:image')) {\n return (\n <Icon\n src={action.icon}\n style={{ color }}\n />\n );\n }\n if (!noDefaultIcon) {\n return getIconByName(action.id, action.icon, color);\n }\n return null;\n}\n\n/**\n * Render an icon that is given as a plain name (and not as a part of an action or control)\n *\n * @param icon `fa-*` name, `data:image/...` string, URL or one of the names supported by `getIconByName`\n * @param color color of the icon\n * @param noDefaultIcon if true, no \"question mark\" icon will be returned for unknown or missing names\n */\nexport function renderIcon(icon?: string, color?: string, noDefaultIcon?: boolean): React.JSX.Element | null {\n if (!icon) {\n return noDefaultIcon ? null : <QuestionMark style={{ color }} />;\n }\n if (icon.startsWith('fa-') || icon.startsWith('fas')) {\n return getFaIcon(icon, color);\n }\n if (\n icon.startsWith('data:image') ||\n icon.startsWith('http://') ||\n icon.startsWith('https://') ||\n icon.includes('/') ||\n /\\.(png|jpe?g|svg|gif|webp|ico)$/i.test(icon)\n ) {\n return (\n <Icon\n src={icon}\n style={{ color }}\n />\n );\n }\n return getIconByName(icon, undefined, color, noDefaultIcon);\n}\n\n/**\n * Resolve the color of a status indicator.\n *\n * The semantic tokens use the same colors as the built-in status icons, but adapted to the theme,\n * so custom indicators do not look foreign next to connection, battery, warning and update.\n *\n * @param color semantic token, `primary`, `secondary` or an explicit CSS color\n * @param theme current theme\n */\nexport function getIndicatorColor(color: IndicatorColor | undefined, theme: IobTheme): string | undefined {\n if (!color) {\n return undefined;\n }\n const dark = theme.palette.mode === 'dark';\n\n switch (color) {\n case 'ok':\n return dark ? '#5cff5c' : '#00ac00';\n case 'warning':\n return dark ? '#ffa733' : '#da8200';\n case 'error':\n return dark ? '#ff5c5c' : '#ff0000';\n case 'info':\n return dark ? '#64b5f6' : '#2196f3';\n case 'inactive':\n return '#8a8a8a';\n case 'primary':\n return theme.palette.primary.main;\n case 'secondary':\n return theme.palette.secondary.main;\n default:\n return color;\n }\n}\n\nexport function renderActionIcon(action: ActionBase, noDefaultIcon?: boolean): React.JSX.Element | null {\n if (!action) {\n return null;\n }\n\n if (action.icon?.startsWith('fa-') || action.icon?.startsWith('fas')) {\n return getFaIcon(action.icon, action.color);\n }\n if (action.icon?.startsWith('data:image')) {\n return (\n <Icon\n src={action.icon}\n style={{ color: action.color }}\n />\n );\n }\n return getIconByName(action.id, action.icon, action.color, noDefaultIcon);\n}\n\nlet language: ioBroker.Languages;\n\n/**\n * Get Translation\n */\nexport function getTranslation(\n /** Text to translate */\n text: ioBroker.StringOrTranslated,\n noTranslation?: boolean,\n): string {\n language ||= I18n.getLanguage();\n\n if (typeof text === 'object') {\n return text[language] || text.en;\n }\n\n return noTranslation ? text : I18n.t(text);\n}\n\n/**\n * Resolve a possibly translated text into the current language.\n *\n * Unlike `getTranslation`, a plain string is returned untouched: device names, models and\n * manufacturers are data, not keys of the i18n dictionary.\n */\nexport function getText(text: ioBroker.StringOrTranslated | undefined): string | undefined {\n if (typeof text === 'object') {\n language ||= I18n.getLanguage();\n return text[language] || text.en;\n }\n\n return text;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Utils.js","sourceRoot":"./src/","sources":["Utils.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport type { ActionBase, ControlBase, IndicatorColor } from './protocol/api';\nimport {\n Add,\n Article,\n BatteryAlert,\n BatteryChargingFull,\n BatteryFull,\n Bluetooth,\n BluetoothDisabled,\n Edit,\n FastForward,\n FastRewind,\n Fluorescent,\n Group,\n Info,\n Lightbulb,\n Link as LinkIcon,\n LinkOff,\n NotListedLocation,\n Pause,\n Person,\n PlayArrow,\n Power,\n QrCode,\n QuestionMark,\n Refresh,\n Search,\n Settings,\n Stop,\n Visibility,\n Upgrade,\n WbIncandescent,\n Wifi,\n WifiOff,\n Launch,\n} from '@mui/icons-material';\n\nimport { I18n, Icon, IconPlayPause, IconTrash, type IobTheme } from '@iobroker/gui-components';\n\n/**\n * Class of an action symbol that shows what its button does while the mouse is over the button\n * (see `styles.ts`): the gear turns, the pen writes, the lamp glows...\n */\nconst HOVER = {\n spin: 'dm-ani dm-ani-spin',\n gear: 'dm-ani dm-ani-gear',\n turn: 'dm-ani dm-ani-turn',\n pen: 'dm-ani dm-ani-pen',\n hop: 'dm-ani dm-ani-hop',\n search: 'dm-ani dm-ani-search',\n nudge: 'dm-ani dm-ani-nudge',\n launch: 'dm-ani dm-ani-launch',\n glow: 'dm-ani dm-ani-glow',\n tick: 'dm-ani dm-ani-tick',\n};\n\ntype MuiIcon = typeof Edit;\n\n/** An MUI icon with the given hover animation */\nfunction animated(IconComponent: MuiIcon, hover: string | undefined, color?: string): React.JSX.Element {\n return (\n <IconComponent\n className={hover}\n style={{ color }}\n />\n );\n}\n\n/**\n * Get Icon by font-awesome name. Do not use these names, use names from getIconByName\n *\n * @param icon font-awesome icon name\n * Only following font-awesome icons are supported:\n * - fa-trash-can, fa-trash\n * - fa-pen\n * - fa-redo-alt\n * - fa-plus\n * - fa-qrcode, qrcode\n * - fa-wifi\n * - fa-wifi-slash\n * - fa-bluetooth\n * - fa-bluetooth-slash\n * - fa-eye\n * - fa-search\n * - fa-unlink\n * - fa-link\n * - fa-search-location\n * - fa-play\n * - fa-stop\n * - fa-pause\n * @param color color of the icon\n */\nfunction getFaIcon(icon: string, color?: string): React.JSX.Element | null {\n const iconStyle = icon\n .split(' ')\n .map(s => s.trim())\n .filter(s => s !== 'fa-solid');\n\n if (iconStyle.includes('fa-trash-can') || iconStyle.includes('fa-trash')) {\n // The lid opens while the mouse is over the button\n return <IconTrash style={{ color }} />;\n }\n if (iconStyle.includes('fa-pen')) {\n return animated(Edit, HOVER.pen, color);\n }\n if (iconStyle.includes('fa-redo-alt')) {\n return animated(Refresh, HOVER.spin, color);\n }\n if (iconStyle.includes('fa-plus')) {\n return animated(Add, HOVER.turn, color);\n }\n if (iconStyle.includes('fa-qrcode') || iconStyle.includes('qrcode')) {\n return animated(QrCode, HOVER.tick, color);\n }\n if (iconStyle.includes('fa-wifi')) {\n return <Wifi style={{ color }} />;\n }\n if (iconStyle.includes('fa-wifi-slash')) {\n return <WifiOff style={{ color }} />;\n }\n if (iconStyle.includes('fa-bluetooth')) {\n return <Bluetooth style={{ color }} />;\n }\n if (iconStyle.includes('fa-bluetooth-slash')) {\n return <BluetoothDisabled style={{ color }} />;\n }\n if (iconStyle.includes('fa-eye')) {\n return animated(Visibility, HOVER.tick, color);\n }\n if (iconStyle.includes('fa-search')) {\n return animated(Search, HOVER.search, color);\n }\n if (iconStyle.includes('fa-unlink')) {\n return <LinkOff style={{ color }} />;\n }\n if (iconStyle.includes('fa-link')) {\n return <LinkIcon style={{ color }} />;\n }\n if (iconStyle.includes('fa-search-location')) {\n return animated(NotListedLocation, HOVER.hop, color);\n }\n if (iconStyle.includes('fa-play')) {\n return animated(PlayArrow, HOVER.nudge, color);\n }\n if (iconStyle.includes('fa-stop')) {\n return <Stop style={{ color }} />;\n }\n if (iconStyle.includes('fa-pause')) {\n return <Pause style={{ color }} />;\n }\n return <QuestionMark style={{ color }} />;\n}\n\n/**\n * Get Icon by name or by action\n *\n * @param name action name\n * possible action or icon names are\n * - edit, rename\n * - delete\n * - refresh\n * - newDevice, new, add\n * - discover, search\n * - unpairDevice, unpair\n * - pairDevice, pair\n * - identify\n * - play\n * - stop\n * - pause\n * - forward, next\n * - rewind, previous\n * - lamp, light\n * - backlight\n * - dimmer\n * - socket\n * - settings\n * - users, group\n * - user\n * - qrcode\n * - identify\n * - info\n * - lines\n * - battery\n * - batteryLow, batteryAlert\n * - batteryCharging\n * @param altName icon name\n * @param color color of the icon\n * @param noDefaultIcon if true, no \"question mark\" icon will be returned for unknown names\n */\nfunction getIconByName(\n name: string,\n altName?: string,\n color?: string,\n noDefaultIcon?: boolean,\n): React.JSX.Element | null {\n const is = (...names: string[]): boolean => names.includes(name) || (!!altName && names.includes(altName));\n\n if (is('edit', 'rename')) {\n return animated(Edit, HOVER.pen, color);\n }\n if (is('delete')) {\n // The lid opens while the mouse is over the button\n return <IconTrash style={{ color }} />;\n }\n if (is('refresh')) {\n return animated(Refresh, HOVER.spin, color);\n }\n if (is('newDevice', 'new', 'add')) {\n return animated(Add, HOVER.turn, color);\n }\n if (is('discover', 'search')) {\n return animated(Search, HOVER.search, color);\n }\n if (is('unpairDevice', 'unpair')) {\n return <LinkOff style={{ color }} />;\n }\n if (is('pairDevice', 'pair')) {\n return <LinkIcon style={{ color }} />;\n }\n if (is('identify')) {\n return animated(NotListedLocation, HOVER.hop, color);\n }\n if (is('play')) {\n return animated(PlayArrow, HOVER.nudge, color);\n }\n if (is('stop')) {\n return <Stop style={{ color }} />;\n }\n if (is('pause')) {\n return <Pause style={{ color }} />;\n }\n if (is('forward', 'next')) {\n return animated(FastForward, HOVER.nudge, color);\n }\n if (is('rewind', 'previous')) {\n return <FastRewind style={{ color }} />;\n }\n if (is('lamp', 'light')) {\n return animated(Lightbulb, HOVER.glow, color);\n }\n if (is('backlight')) {\n return animated(Fluorescent, HOVER.glow, color);\n }\n if (is('dimmer')) {\n return animated(WbIncandescent, HOVER.glow, color);\n }\n if (is('socket')) {\n return <Power style={{ color }} />;\n }\n if (is('settings')) {\n return animated(Settings, HOVER.gear, color);\n }\n if (is('users', 'group')) {\n return <Group style={{ color }} />;\n }\n if (is('user')) {\n return <Person style={{ color }} />;\n }\n if (is('update')) {\n return animated(Upgrade, HOVER.hop, color);\n }\n if (is('qrcode')) {\n return animated(QrCode, HOVER.tick, color);\n }\n if (is('info')) {\n return animated(Info, HOVER.tick, color);\n }\n if (is('lines')) {\n return <Article style={{ color }} />;\n }\n if (is('web')) {\n return animated(Launch, HOVER.launch, color);\n }\n if (is('battery')) {\n return <BatteryFull style={{ color }} />;\n }\n if (is('batteryLow', 'batteryAlert')) {\n return <BatteryAlert style={{ color }} />;\n }\n if (is('batteryCharging')) {\n return <BatteryChargingFull style={{ color }} />;\n }\n if (noDefaultIcon) {\n return null;\n }\n return <QuestionMark style={{ color }} />;\n}\n\nexport function renderControlIcon(\n action: ControlBase,\n colors?: { primary: string; secondary: string },\n value?: string | number | boolean | null,\n noDefaultIcon?: boolean,\n): React.JSX.Element | null {\n if (!action) {\n return null;\n }\n\n let color = (value && action.colorOn) || action.color || (action.state ? 'primary' : 'inherit');\n\n if (colors) {\n if (color === 'primary') {\n color = colors.primary;\n } else if (color === 'secondary') {\n color = colors.secondary;\n }\n }\n\n // A play or pause toggle shows what a click does: play while it is stopped, pause while it runs.\n // The symbol morphs from one into the other.\n const isPlayPause =\n 'type' in action &&\n action.type === 'icon' &&\n !action.iconOn &&\n (action.id === 'play' ||\n action.id === 'pause' ||\n action.icon === 'play' ||\n action.icon === 'pause' ||\n action.icon === 'fa-play' ||\n action.icon === 'fa-pause');\n if (isPlayPause) {\n return (\n <IconPlayPause\n running={!!value}\n style={{ color }}\n />\n );\n }\n\n if (action.icon?.startsWith('fa-') || action.icon?.startsWith('fas')) {\n return getFaIcon(action.icon, color);\n }\n if (value && action.iconOn?.startsWith('data:image')) {\n return (\n <Icon\n src={action.iconOn}\n style={{ color }}\n />\n );\n }\n if (action.icon?.startsWith('data:image')) {\n return (\n <Icon\n src={action.icon}\n style={{ color }}\n />\n );\n }\n if (!noDefaultIcon) {\n return getIconByName(action.id, action.icon, color);\n }\n return null;\n}\n\n/**\n * Render an icon that is given as a plain name (and not as a part of an action or control)\n *\n * @param icon `fa-*` name, `data:image/...` string, URL or one of the names supported by `getIconByName`\n * @param color color of the icon\n * @param noDefaultIcon if true, no \"question mark\" icon will be returned for unknown or missing names\n */\nexport function renderIcon(icon?: string, color?: string, noDefaultIcon?: boolean): React.JSX.Element | null {\n if (!icon) {\n return noDefaultIcon ? null : <QuestionMark style={{ color }} />;\n }\n if (icon.startsWith('fa-') || icon.startsWith('fas')) {\n return getFaIcon(icon, color);\n }\n if (\n icon.startsWith('data:image') ||\n icon.startsWith('http://') ||\n icon.startsWith('https://') ||\n icon.includes('/') ||\n /\\.(png|jpe?g|svg|gif|webp|ico)$/i.test(icon)\n ) {\n return (\n <Icon\n src={icon}\n style={{ color }}\n />\n );\n }\n return getIconByName(icon, undefined, color, noDefaultIcon);\n}\n\n/**\n * Resolve the color of a status indicator.\n *\n * The semantic tokens use the same colors as the built-in status icons, but adapted to the theme,\n * so custom indicators do not look foreign next to connection, battery, warning and update.\n *\n * @param color semantic token, `primary`, `secondary` or an explicit CSS color\n * @param theme current theme\n */\nexport function getIndicatorColor(color: IndicatorColor | undefined, theme: IobTheme): string | undefined {\n if (!color) {\n return undefined;\n }\n const dark = theme.palette.mode === 'dark';\n\n switch (color) {\n case 'ok':\n return dark ? '#5cff5c' : '#00ac00';\n case 'warning':\n return dark ? '#ffa733' : '#da8200';\n case 'error':\n return dark ? '#ff5c5c' : '#ff0000';\n case 'info':\n return dark ? '#64b5f6' : '#2196f3';\n case 'inactive':\n return '#8a8a8a';\n case 'primary':\n return theme.palette.primary.main;\n case 'secondary':\n return theme.palette.secondary.main;\n default:\n return color;\n }\n}\n\nexport function renderActionIcon(action: ActionBase, noDefaultIcon?: boolean): React.JSX.Element | null {\n if (!action) {\n return null;\n }\n\n if (action.icon?.startsWith('fa-') || action.icon?.startsWith('fas')) {\n return getFaIcon(action.icon, action.color);\n }\n if (action.icon?.startsWith('data:image')) {\n return (\n <Icon\n src={action.icon}\n style={{ color: action.color }}\n />\n );\n }\n return getIconByName(action.id, action.icon, action.color, noDefaultIcon);\n}\n\nlet language: ioBroker.Languages;\n\n/**\n * Get Translation\n */\nexport function getTranslation(\n /** Text to translate */\n text: ioBroker.StringOrTranslated,\n noTranslation?: boolean,\n): string {\n language ||= I18n.getLanguage();\n\n if (typeof text === 'object') {\n return text[language] || text.en;\n }\n\n return noTranslation ? text : I18n.t(text);\n}\n\n/**\n * Resolve a possibly translated text into the current language.\n *\n * Unlike `getTranslation`, a plain string is returned untouched: device names, models and\n * manufacturers are data, not keys of the i18n dictionary.\n */\nexport function getText(text: ioBroker.StringOrTranslated | undefined): string | undefined {\n if (typeof text === 'object') {\n language ||= I18n.getLanguage();\n return text[language] || text.en;\n }\n\n return text;\n}\n"]}
|
package/build/i18n/de.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Bitte eingeben",
|
|
34
34
|
"refreshInstanceList": "Instanzliste aktualisieren",
|
|
35
35
|
"refreshTooltip": "Aktualisieren",
|
|
36
|
+
"resetFilters": "Filter zurücksetzen",
|
|
37
|
+
"resetFiltersTooltip": "Alle Filter zurücksetzen",
|
|
36
38
|
"rootInfoText": "Dies ist der Konfigurations-Manager. Wählen Sie unten eine Adapter-Instanz aus, um deren Geräte anzuzeigen, zu konfigurieren und zu aktualisieren.",
|
|
37
39
|
"selectInstanceText": "Bitte eine Instanz auswählen.",
|
|
38
40
|
"toClipboard": "in die Zwischenablage kopiert",
|
|
39
41
|
"updateAvailable": "Update verfügbar",
|
|
40
42
|
"updateConfirmation": "Möchten Sie das verfügbare Update installieren?",
|
|
43
|
+
"uploadImageTooltip": "Bild des Geräts hochladen",
|
|
41
44
|
"yesButtonText": "Ja"
|
|
42
45
|
}
|
package/build/i18n/en.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Please enter",
|
|
34
34
|
"refreshInstanceList": "Refresh instance list",
|
|
35
35
|
"refreshTooltip": "Refresh",
|
|
36
|
+
"resetFilters": "Reset filters",
|
|
37
|
+
"resetFiltersTooltip": "Reset all filters",
|
|
36
38
|
"rootInfoText": "This is the configuration manager. Select an adapter instance below to view, configure and update its devices.",
|
|
37
39
|
"selectInstanceText": "Please select instance",
|
|
38
40
|
"toClipboard": "to clipboard",
|
|
39
41
|
"updateAvailable": "Update available",
|
|
40
42
|
"updateConfirmation": "Do you want to install the available update?",
|
|
43
|
+
"uploadImageTooltip": "Upload an image of the device",
|
|
41
44
|
"yesButtonText": "Yes"
|
|
42
45
|
}
|
package/build/i18n/es.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Por favor escribe",
|
|
34
34
|
"refreshInstanceList": "Actualizar lista de instancias",
|
|
35
35
|
"refreshTooltip": "Actualizar",
|
|
36
|
+
"resetFilters": "Restablecer filtros",
|
|
37
|
+
"resetFiltersTooltip": "Restablecer todos los filtros",
|
|
36
38
|
"rootInfoText": "Este es el administrador de dispositivos. Seleccione una instancia de adaptador a continuación para ver, configurar y actualizar sus dispositivos.",
|
|
37
39
|
"selectInstanceText": "Por favor seleccione una instancia",
|
|
38
40
|
"toClipboard": "al portapapeles",
|
|
39
41
|
"updateAvailable": "Actualización disponible",
|
|
40
42
|
"updateConfirmation": "¿Desea instalar la actualización disponible?",
|
|
43
|
+
"uploadImageTooltip": "Subir una imagen del dispositivo",
|
|
41
44
|
"yesButtonText": "Sí"
|
|
42
45
|
}
|
package/build/i18n/fr.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Entrez s'il vous plait",
|
|
34
34
|
"refreshInstanceList": "Actualiser la liste des instances",
|
|
35
35
|
"refreshTooltip": "Rafraîchir",
|
|
36
|
+
"resetFilters": "Réinitialiser les filtres",
|
|
37
|
+
"resetFiltersTooltip": "Réinitialiser tous les filtres",
|
|
36
38
|
"rootInfoText": "Ceci est le gestionnaire d'appareils. Sélectionnez une instance d'adaptateur ci-dessous pour afficher, configurer et mettre à jour ses appareils.",
|
|
37
39
|
"selectInstanceText": "Veuillez sélectionner une instance",
|
|
38
40
|
"toClipboard": "au presse-papiers",
|
|
39
41
|
"updateAvailable": "Mise à jour disponible",
|
|
40
42
|
"updateConfirmation": "Voulez-vous installer la mise à jour disponible ?",
|
|
43
|
+
"uploadImageTooltip": "Téléverser une image de l'appareil",
|
|
41
44
|
"yesButtonText": "Oui"
|
|
42
45
|
}
|
package/build/i18n/it.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Prego entra",
|
|
34
34
|
"refreshInstanceList": "Aggiorna l'elenco delle istanze",
|
|
35
35
|
"refreshTooltip": "ricaricare",
|
|
36
|
+
"resetFilters": "Reimposta filtri",
|
|
37
|
+
"resetFiltersTooltip": "Reimposta tutti i filtri",
|
|
36
38
|
"rootInfoText": "Questo è il gestore dei dispositivi. Seleziona un'istanza dell'adattatore qui sotto per visualizzare, configurare e aggiornare i suoi dispositivi.",
|
|
37
39
|
"selectInstanceText": "Seleziona l'istanza",
|
|
38
40
|
"toClipboard": "negli appunti",
|
|
39
41
|
"updateAvailable": "Aggiornamento disponibile",
|
|
40
42
|
"updateConfirmation": "Vuoi installare l'aggiornamento disponibile?",
|
|
43
|
+
"uploadImageTooltip": "Carica un'immagine del dispositivo",
|
|
41
44
|
"yesButtonText": "SÌ"
|
|
42
45
|
}
|
package/build/i18n/nl.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Kom binnen alstublieft",
|
|
34
34
|
"refreshInstanceList": "Ververs de exemplaarlijst",
|
|
35
35
|
"refreshTooltip": "Vernieuwen",
|
|
36
|
+
"resetFilters": "Filters wissen",
|
|
37
|
+
"resetFiltersTooltip": "Alle filters wissen",
|
|
36
38
|
"rootInfoText": "Dit is de apparaatbeheerder. Selecteer hieronder een adapterinstantie om de apparaten te bekijken, te configureren en bij te werken.",
|
|
37
39
|
"selectInstanceText": "Selecteer een instantie",
|
|
38
40
|
"toClipboard": "naar klembord",
|
|
39
41
|
"updateAvailable": "Update beschikbaar",
|
|
40
42
|
"updateConfirmation": "Wilt u de beschikbare update installeren?",
|
|
43
|
+
"uploadImageTooltip": "Een afbeelding van het apparaat uploaden",
|
|
41
44
|
"yesButtonText": "Ja"
|
|
42
45
|
}
|
package/build/i18n/pl.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Podaj",
|
|
34
34
|
"refreshInstanceList": "Odśwież listę instancji",
|
|
35
35
|
"refreshTooltip": "Odświeżać",
|
|
36
|
+
"resetFilters": "Resetuj filtry",
|
|
37
|
+
"resetFiltersTooltip": "Resetuj wszystkie filtry",
|
|
36
38
|
"rootInfoText": "To jest menedżer urządzeń. Wybierz poniżej instancję adaptera, aby wyświetlić, skonfigurować i zaktualizować jej urządzenia.",
|
|
37
39
|
"selectInstanceText": "Proszę wybrać instancję",
|
|
38
40
|
"toClipboard": "do schowka",
|
|
39
41
|
"updateAvailable": "Dostępna aktualizacja",
|
|
40
42
|
"updateConfirmation": "Czy chcesz zainstalować dostępną aktualizację?",
|
|
43
|
+
"uploadImageTooltip": "Prześlij zdjęcie urządzenia",
|
|
41
44
|
"yesButtonText": "Tak"
|
|
42
45
|
}
|
package/build/i18n/pt.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Por favor, insira",
|
|
34
34
|
"refreshInstanceList": "Atualizar lista de instâncias",
|
|
35
35
|
"refreshTooltip": "Atualizar",
|
|
36
|
+
"resetFilters": "Redefinir filtros",
|
|
37
|
+
"resetFiltersTooltip": "Redefinir todos os filtros",
|
|
36
38
|
"rootInfoText": "Este é o gerenciador de dispositivos. Selecione uma instância de adaptador abaixo para visualizar, configurar e atualizar os seus dispositivos.",
|
|
37
39
|
"selectInstanceText": "Por favor, selecione uma instância.",
|
|
38
40
|
"toClipboard": "para a área de transferência",
|
|
39
41
|
"updateAvailable": "Atualização disponível",
|
|
40
42
|
"updateConfirmation": "Deseja instalar a atualização disponível?",
|
|
43
|
+
"uploadImageTooltip": "Carregar uma imagem do dispositivo",
|
|
41
44
|
"yesButtonText": "Sim"
|
|
42
45
|
}
|
package/build/i18n/ru.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Пожалуйста входите",
|
|
34
34
|
"refreshInstanceList": "Обновить список экземпляров",
|
|
35
35
|
"refreshTooltip": "Обновить",
|
|
36
|
+
"resetFilters": "Сбросить фильтры",
|
|
37
|
+
"resetFiltersTooltip": "Сбросить все фильтры",
|
|
36
38
|
"rootInfoText": "Это менеджер настроек устройств. Выберите экземпляр адаптера ниже, чтобы просматривать, настраивать и обновлять его устройства.",
|
|
37
39
|
"selectInstanceText": "Пожалуйста, выберите экземпляр.",
|
|
38
40
|
"toClipboard": "в буфер обмена",
|
|
39
41
|
"updateAvailable": "Доступно обновление",
|
|
40
42
|
"updateConfirmation": "Вы хотите установить доступное обновление?",
|
|
43
|
+
"uploadImageTooltip": "Загрузить изображение устройства",
|
|
41
44
|
"yesButtonText": "Да"
|
|
42
45
|
}
|
package/build/i18n/uk.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "Будь ласка введіть",
|
|
34
34
|
"refreshInstanceList": "Оновити список екземплярів",
|
|
35
35
|
"refreshTooltip": "Оновити",
|
|
36
|
+
"resetFilters": "Скинути фільтри",
|
|
37
|
+
"resetFiltersTooltip": "Скинути всі фільтри",
|
|
36
38
|
"rootInfoText": "Це менеджер пристроїв. Виберіть екземпляр адаптера нижче, щоб переглядати, налаштовувати та оновлювати його пристрої.",
|
|
37
39
|
"selectInstanceText": "Будь ласка, виберіть екземпляр",
|
|
38
40
|
"toClipboard": "в буфер обміну",
|
|
39
41
|
"updateAvailable": "Доступне оновлення",
|
|
40
42
|
"updateConfirmation": "Бажаєте встановити доступне оновлення?",
|
|
43
|
+
"uploadImageTooltip": "Завантажити зображення пристрою",
|
|
41
44
|
"yesButtonText": "Так"
|
|
42
45
|
}
|
package/build/i18n/zh-cn.json
CHANGED
|
@@ -33,10 +33,13 @@
|
|
|
33
33
|
"pleaseEnterValueText": "请输入",
|
|
34
34
|
"refreshInstanceList": "刷新实例列表",
|
|
35
35
|
"refreshTooltip": "刷新",
|
|
36
|
+
"resetFilters": "重置筛选",
|
|
37
|
+
"resetFiltersTooltip": "重置所有筛选",
|
|
36
38
|
"rootInfoText": "这是设备管理器。请在下方选择一个适配器实例,以查看、配置和更新其设备。",
|
|
37
39
|
"selectInstanceText": "请选择实例",
|
|
38
40
|
"toClipboard": "到剪贴板",
|
|
39
41
|
"updateAvailable": "有可用更新",
|
|
40
42
|
"updateConfirmation": "是否要安装可用的更新?",
|
|
43
|
+
"uploadImageTooltip": "上传设备图片",
|
|
41
44
|
"yesButtonText": "是的"
|
|
42
45
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { IobTheme } from '@iobroker/gui-components';
|
|
3
|
+
/** Puts the style sheet into the page once. Safe to call in a constructor, before the first paint. */
|
|
4
|
+
export declare function ensureDmStyles(): void;
|
|
5
|
+
/** The same for function components */
|
|
6
|
+
export declare function useDmStyles(): void;
|
|
7
|
+
/**
|
|
8
|
+
* The colors of the theme as CSS variables for the classes above.
|
|
9
|
+
*
|
|
10
|
+
* Cached per theme: the object is handed to every card, and a stable reference keeps the style
|
|
11
|
+
* comparison of React cheap.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getThemeVars(theme: IobTheme): React.CSSProperties;
|
|
14
|
+
/** Tone of a status pill: the color it is tinted with */
|
|
15
|
+
export type PillTone = 'ok' | 'warn' | 'err' | 'info';
|
|
16
|
+
/** Style that sets the tone of a pill */
|
|
17
|
+
export declare function toneStyle(tone?: PillTone): React.CSSProperties | undefined;
|
package/build/styles.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { useInsertionEffect } from 'react';
|
|
2
|
+
import { getIndicatorColor } from './Utils';
|
|
3
|
+
/**
|
|
4
|
+
* One style sheet for the cards, the status pills and the own animations.
|
|
5
|
+
*
|
|
6
|
+
* The list renders a few hundred cards. Plain classes are much cheaper than an `sx` property per element,
|
|
7
|
+
* and the theme reaches the classes through CSS variables (see `getThemeVars`).
|
|
8
|
+
*/
|
|
9
|
+
const STYLE_ID = 'iob-dm-styles';
|
|
10
|
+
const styles = `
|
|
11
|
+
/* ---------- Card ---------- */
|
|
12
|
+
.dm-card { box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; border-radius: 12px; border: 1px solid var(--dm-border); background-color: var(--dm-paper); background-image: var(--dm-overlay); color: var(--dm-text); font-size: 13px; line-height: 1.4; }
|
|
13
|
+
.dm-head { display: flex; align-items: center; gap: 12px; box-sizing: border-box; min-height: 72px; padding: 14px 6px 10px 14px; }
|
|
14
|
+
.dm-small .dm-head { gap: 10px; min-height: 56px; padding: 10px 2px 8px 10px; }
|
|
15
|
+
.dm-name { flex: 1; min-width: 0; font-size: 15px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; transition: color 0.3s; }
|
|
16
|
+
.dm-small .dm-name { font-size: 13.5px; }
|
|
17
|
+
.dm-head-end { align-self: flex-start; display: flex; align-items: center; margin-top: -4px; }
|
|
18
|
+
.dm-small .dm-head-end { margin-top: -6px; }
|
|
19
|
+
|
|
20
|
+
/* The device symbol: the place for the color of the device and for its LED */
|
|
21
|
+
.dm-avatar { position: relative; flex-shrink: 0; box-sizing: border-box; width: 44px; height: 44px; border-radius: 10px; display: flex; align-items: center; justify-content: center; background: var(--dm-accent); color: var(--dm-accent-text); transition: filter 0.4s, opacity 0.4s; }
|
|
22
|
+
.dm-small .dm-avatar { width: 34px; height: 34px; border-radius: 8px; }
|
|
23
|
+
.dm-avatar-img { background: var(--dm-tile); padding: 4px; }
|
|
24
|
+
.dm-avatar-glyph { width: 26px; height: 26px; }
|
|
25
|
+
.dm-small .dm-avatar-glyph { width: 20px; height: 20px; }
|
|
26
|
+
.dm-avatar-img .dm-avatar-glyph { width: 100%; height: 100%; object-fit: contain; }
|
|
27
|
+
.dm-avatar-letter { font-size: 20px; font-weight: 600; line-height: 1; text-transform: uppercase; }
|
|
28
|
+
.dm-small .dm-avatar-letter { font-size: 16px; }
|
|
29
|
+
.dm-avatar-led { position: absolute; right: -6px; bottom: -6px; display: flex; line-height: 0; font-size: 18px; border-radius: 50%; background-color: var(--dm-paper); background-image: var(--dm-overlay); }
|
|
30
|
+
.dm-small .dm-avatar-led { right: -5px; bottom: -5px; font-size: 15px; }
|
|
31
|
+
.dm-off .dm-avatar { filter: grayscale(1); opacity: 0.45; }
|
|
32
|
+
.dm-off .dm-name { color: var(--dm-text2); }
|
|
33
|
+
|
|
34
|
+
/* Image upload on the device symbol */
|
|
35
|
+
.dm-upload { position: absolute; inset: 0; border-radius: inherit; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.55); color: #fff; opacity: 0; transition: opacity 0.2s; cursor: pointer; }
|
|
36
|
+
.dm-avatar:hover .dm-upload, .dm-upload:focus-within, .dm-upload.dm-upload-busy { opacity: 1; }
|
|
37
|
+
.dm-upload input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
|
|
38
|
+
.dm-small .dm-upload .iob-ani { font-size: 18px; }
|
|
39
|
+
|
|
40
|
+
/* Status line */
|
|
41
|
+
.dm-status { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; min-height: 34px; padding: 0 12px 8px; color: var(--dm-text2); }
|
|
42
|
+
.dm-small .dm-status { gap: 2px 3px; min-height: 30px; padding: 0 8px 6px; }
|
|
43
|
+
.dm-status-end { margin-left: auto; display: flex; align-items: center; padding-left: 4px; }
|
|
44
|
+
|
|
45
|
+
/* A status value. Neutral while all is well; tinted with its color when it needs attention. */
|
|
46
|
+
.dm-pill.dm-pill { display: inline-flex; align-items: center; gap: 4px; box-sizing: border-box; height: 26px; padding: 0 6px; border: 0; border-radius: 7px; background-color: transparent; color: inherit; font-family: inherit; font-size: 12px; font-weight: 500; line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; text-decoration: none; }
|
|
47
|
+
.dm-small .dm-pill.dm-pill { padding: 0 4px; gap: 3px; }
|
|
48
|
+
.dm-pill > svg, .dm-pill > .iob-ani, .dm-pill .MuiSvgIcon-root { font-size: 18px; width: 18px; height: 18px; flex-shrink: 0; }
|
|
49
|
+
.dm-pill > img { width: 18px; height: 18px; }
|
|
50
|
+
.dm-pill-tone.dm-pill-tone { color: var(--dm-tone); background-color: color-mix(in srgb, var(--dm-tone) 15%, transparent); }
|
|
51
|
+
.dm-pill-btn.dm-pill-btn { cursor: pointer; transition: background-color 0.15s; }
|
|
52
|
+
.dm-pill-btn.dm-pill-btn:hover { background-color: var(--dm-hover); }
|
|
53
|
+
.dm-pill-tone.dm-pill-btn:hover { background-color: color-mix(in srgb, var(--dm-tone) 26%, transparent); }
|
|
54
|
+
.dm-pill-btn:focus-visible { outline: 2px solid var(--dm-focus); outline-offset: 1px; }
|
|
55
|
+
.dm-pill-btn.Mui-disabled { opacity: 0.6; }
|
|
56
|
+
.dm-pill-wrap { display: inline-flex; }
|
|
57
|
+
|
|
58
|
+
/* Facts: label and value */
|
|
59
|
+
.dm-facts { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 12px; row-gap: 2px; padding: 4px 14px 12px; }
|
|
60
|
+
.dm-small .dm-facts { column-gap: 8px; padding: 2px 10px 10px; font-size: 12px; }
|
|
61
|
+
.dm-fact-label { color: var(--dm-text2); font-size: 12px; white-space: nowrap; }
|
|
62
|
+
.dm-small .dm-fact-label { font-size: 11.5px; }
|
|
63
|
+
.dm-fact-value { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
64
|
+
.dm-fact-copy { display: flex; align-items: center; min-width: 0; gap: 2px; }
|
|
65
|
+
.dm-fact-copy > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
66
|
+
.dm-copy-btn.dm-copy-btn { padding: 3px; margin: -4px 0; color: var(--dm-text2); opacity: 0.6; transition: opacity 0.15s; }
|
|
67
|
+
.dm-fact-copy:hover .dm-copy-btn, .dm-copy-btn:focus-visible { opacity: 1; }
|
|
68
|
+
.dm-copy-btn .iob-ani { font-size: 16px; }
|
|
69
|
+
.dm-custom { padding: 0 14px 12px; }
|
|
70
|
+
.dm-small .dm-custom { padding: 0 10px 10px; }
|
|
71
|
+
|
|
72
|
+
/* Actions */
|
|
73
|
+
.dm-foot { margin-top: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; box-sizing: border-box; min-height: 44px; padding: 4px 8px; border-top: 1px solid var(--dm-border); }
|
|
74
|
+
.dm-small .dm-foot { gap: 0; min-height: 38px; padding: 2px 4px; }
|
|
75
|
+
.dm-small .dm-foot .MuiIconButton-sizeSmall { padding: 4px; }
|
|
76
|
+
.dm-small .dm-foot .MuiIconButton-sizeSmall > :is(svg, .iob-ani) { font-size: 20px; }
|
|
77
|
+
/* !important: the control sets its size inline */
|
|
78
|
+
.dm-small .dm-foot-end .MuiFab-root.MuiFab-root { width: 30px !important; height: 30px !important; min-height: 30px !important; }
|
|
79
|
+
.dm-foot-end { margin-left: auto; display: flex; align-items: center; gap: 4px; }
|
|
80
|
+
/* A control in the footer is a quiet round button; only a switched on control gets its color */
|
|
81
|
+
.dm-foot-end .MuiFab-root.MuiFab-root { width: 34px; height: 34px; min-height: 34px; box-shadow: none; }
|
|
82
|
+
.dm-foot-end .MuiFab-default.MuiFab-default { background-color: var(--dm-tile); color: var(--dm-text); }
|
|
83
|
+
.dm-foot-end .MuiFab-default.MuiFab-default:hover { background-color: var(--dm-hover); }
|
|
84
|
+
|
|
85
|
+
/* Skeleton: the same footprint as the card */
|
|
86
|
+
.dm-skeleton .dm-avatar { background: var(--dm-tile); }
|
|
87
|
+
|
|
88
|
+
/* Instance cards on the root page */
|
|
89
|
+
.dm-inst.dm-inst { width: 240px; margin: 10px; }
|
|
90
|
+
.dm-inst-small.dm-inst-small { width: 200px; margin: 5px; }
|
|
91
|
+
.dm-inst-area.dm-inst-area { display: flex; flex-direction: column; align-items: center; gap: 10px; height: 100%; padding: 20px 16px 18px; text-align: center; color: inherit; font-family: inherit; }
|
|
92
|
+
.dm-inst-small .dm-inst-area.dm-inst-area { flex-direction: row; justify-content: flex-start; gap: 10px; padding: 10px; text-align: left; }
|
|
93
|
+
.dm-inst .dm-avatar { width: 64px; height: 64px; border-radius: 14px; background: var(--dm-tile); padding: 8px; }
|
|
94
|
+
.dm-inst-small .dm-avatar { width: 38px; height: 38px; border-radius: 9px; padding: 5px; }
|
|
95
|
+
.dm-inst-id { font-size: 16px; font-weight: 600; overflow-wrap: anywhere; }
|
|
96
|
+
.dm-inst-small .dm-inst-id { font-size: 13.5px; }
|
|
97
|
+
.dm-inst-title { color: var(--dm-text2); font-size: 13px; }
|
|
98
|
+
.dm-inst-small .dm-inst-title { font-size: 12px; }
|
|
99
|
+
.dm-inst-small .dm-inst-text { min-width: 0; }
|
|
100
|
+
.dm-inst-small .dm-inst-text > div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
101
|
+
|
|
102
|
+
/* Empty list: what happened and what to do */
|
|
103
|
+
.dm-empty { box-sizing: border-box; width: 100%; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 56px 16px; color: var(--dm-text2); font-size: 14px; text-align: center; }
|
|
104
|
+
.dm-empty > .iob-ani, .dm-empty > svg { font-size: 48px; }
|
|
105
|
+
|
|
106
|
+
/* Confirmation after a successful action */
|
|
107
|
+
.dm-result { position: fixed; left: 50%; top: 50%; z-index: 1500; display: flex; align-items: center; justify-content: center; width: 84px; height: 84px; margin: -42px 0 0 -42px; border-radius: 50%; background-color: var(--dm-paper); background-image: var(--dm-overlay); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); pointer-events: none; animation: dm-result 1.25s ease forwards; }
|
|
108
|
+
.dm-result .iob-ani { font-size: 52px; }
|
|
109
|
+
.dm-toast { display: flex; align-items: center; gap: 10px; }
|
|
110
|
+
.dm-toast .iob-ani { font-size: 22px; }
|
|
111
|
+
|
|
112
|
+
/* ---------- Own animations ---------- */
|
|
113
|
+
|
|
114
|
+
/* Action symbols show what the button does while the mouse is over it */
|
|
115
|
+
.dm-ani.dm-ani { transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); }
|
|
116
|
+
.dm-ani-gear.dm-ani-gear { transition-duration: 0.6s; }
|
|
117
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-spin { transform: rotate(180deg); }
|
|
118
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-gear { transform: rotate(90deg); }
|
|
119
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-turn { transform: rotate(90deg); }
|
|
120
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-launch { transform: translate(1.5px, -1.5px); }
|
|
121
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-nudge { transform: translateX(2px); }
|
|
122
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-pen { animation: dm-pen 0.5s ease-in-out; }
|
|
123
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-hop { animation: dm-hop 0.5s ease-out; }
|
|
124
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-search { animation: dm-search 0.7s ease-in-out; }
|
|
125
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-glow { animation: dm-glow 0.6s ease-in-out; }
|
|
126
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani-tick { animation: dm-tick 0.4s ease-out; }
|
|
127
|
+
@keyframes dm-pen { 0%, 100% { transform: none; } 30% { transform: rotate(-14deg) translateY(-1px); } 65% { transform: rotate(8deg); } }
|
|
128
|
+
@keyframes dm-hop { 0%, 100% { transform: none; } 40% { transform: translateY(-3px); } 70% { transform: translateY(0.5px); } }
|
|
129
|
+
@keyframes dm-search { 0%, 100% { transform: none; } 25% { transform: translate(-1.5px, -1px); } 50% { transform: translate(1px, -1.5px); } 75% { transform: translate(1px, 1px); } }
|
|
130
|
+
@keyframes dm-glow { 0%, 100% { filter: none; } 50% { filter: drop-shadow(0 0 3px currentColor); } }
|
|
131
|
+
@keyframes dm-tick { 0%, 100% { transform: none; } 50% { transform: scale(1.15); } }
|
|
132
|
+
|
|
133
|
+
/* Battery: the charge slides to its level */
|
|
134
|
+
.dm-bat .dm-bat-body { fill: none; stroke: currentColor; stroke-width: 1.6; }
|
|
135
|
+
.dm-bat .dm-bat-cap { fill: currentColor; }
|
|
136
|
+
.dm-bat .dm-bat-fill { fill: var(--dm-bat, currentColor); transform-box: fill-box; transform-origin: 0 50%; transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1), fill 0.4s; }
|
|
137
|
+
.dm-bat-unknown .dm-bat-fill { opacity: 0.35; }
|
|
138
|
+
.dm-bat-charging .dm-bat-fill { animation: dm-bat-charge 1.8s ease-in-out infinite; }
|
|
139
|
+
.dm-bat .dm-bat-bolt { fill: currentColor; stroke: var(--dm-paper, #fff); stroke-width: 0.9; stroke-linejoin: round; paint-order: stroke; }
|
|
140
|
+
@keyframes dm-bat-charge { 0% { transform: scaleX(0.15); } 80%, 100% { transform: scaleX(1); } }
|
|
141
|
+
|
|
142
|
+
/* Signal: the bars light up one after another */
|
|
143
|
+
.dm-sig rect { fill: currentColor; opacity: 0.22; transition: opacity 0.3s; }
|
|
144
|
+
.dm-sig rect.dm-sig-on { opacity: 1; }
|
|
145
|
+
.dm-sig rect:nth-child(2) { transition-delay: 0.07s; }
|
|
146
|
+
.dm-sig rect:nth-child(3) { transition-delay: 0.14s; }
|
|
147
|
+
.dm-sig rect:nth-child(4) { transition-delay: 0.21s; }
|
|
148
|
+
|
|
149
|
+
/* Update: the arrow drops into the tray */
|
|
150
|
+
.dm-upd path { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
|
151
|
+
.dm-upd .dm-upd-arrow { transition: transform 0.25s ease-out; }
|
|
152
|
+
.dm-upd:hover .dm-upd-arrow, :is(button, a, [role="button"]):is(:hover, :focus-visible) .dm-upd .dm-upd-arrow { transform: translateY(2.5px); }
|
|
153
|
+
|
|
154
|
+
@keyframes dm-result { 0% { opacity: 0; transform: scale(0.7); } 12% { opacity: 1; transform: scale(1); } 78% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(0.92); } }
|
|
155
|
+
@keyframes dm-fade { 0%, 100% { opacity: 0; } 15%, 80% { opacity: 1; } }
|
|
156
|
+
|
|
157
|
+
@media (prefers-reduced-motion: reduce) {
|
|
158
|
+
.dm-ani.dm-ani, .dm-bat .dm-bat-fill, .dm-sig rect, .dm-upd .dm-upd-arrow, .dm-avatar, .dm-upload, .dm-name, .dm-switch, .dm-switch * { transition: none !important; }
|
|
159
|
+
:is(button, a, [role="button"], [role="menuitem"]):is(:hover, :focus-visible) .dm-ani { transform: none !important; animation: none !important; }
|
|
160
|
+
.dm-bat-charging .dm-bat-fill { animation: none; }
|
|
161
|
+
.dm-upd:hover .dm-upd-arrow, :is(button, a, [role="button"]):is(:hover, :focus-visible) .dm-upd .dm-upd-arrow { transform: none; }
|
|
162
|
+
.dm-result { animation-name: dm-fade; }
|
|
163
|
+
}
|
|
164
|
+
`;
|
|
165
|
+
let inserted = false;
|
|
166
|
+
/** Puts the style sheet into the page once. Safe to call in a constructor, before the first paint. */
|
|
167
|
+
export function ensureDmStyles() {
|
|
168
|
+
if (inserted || typeof window === 'undefined') {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
inserted = true;
|
|
172
|
+
let style = window.document.getElementById(STYLE_ID);
|
|
173
|
+
if (!style) {
|
|
174
|
+
style = window.document.createElement('style');
|
|
175
|
+
style.setAttribute('id', STYLE_ID);
|
|
176
|
+
window.document.head.appendChild(style);
|
|
177
|
+
}
|
|
178
|
+
// Also replaces the sheet of an older copy of this module (e.g. after a hot reload)
|
|
179
|
+
style.innerHTML = styles;
|
|
180
|
+
}
|
|
181
|
+
/** The same for function components */
|
|
182
|
+
export function useDmStyles() {
|
|
183
|
+
useInsertionEffect(ensureDmStyles, []);
|
|
184
|
+
}
|
|
185
|
+
const themeVarsCache = new WeakMap();
|
|
186
|
+
/**
|
|
187
|
+
* The colors of the theme as CSS variables for the classes above.
|
|
188
|
+
*
|
|
189
|
+
* Cached per theme: the object is handed to every card, and a stable reference keeps the style
|
|
190
|
+
* comparison of React cheap.
|
|
191
|
+
*/
|
|
192
|
+
export function getThemeVars(theme) {
|
|
193
|
+
let vars = themeVarsCache.get(theme);
|
|
194
|
+
if (!vars) {
|
|
195
|
+
const dark = theme.palette.mode === 'dark';
|
|
196
|
+
vars = {
|
|
197
|
+
'--dm-paper': theme.palette.background.paper,
|
|
198
|
+
// Like the elevation of the MUI paper: in the dark themes paper and page have the same color
|
|
199
|
+
'--dm-overlay': dark ? 'linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05))' : 'none',
|
|
200
|
+
// Not `palette.divider`: in some themes it has nearly the color of the card and the lines disappear
|
|
201
|
+
'--dm-border': dark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.12)',
|
|
202
|
+
'--dm-text': theme.palette.text.primary,
|
|
203
|
+
'--dm-text2': theme.palette.text.secondary,
|
|
204
|
+
'--dm-hover': theme.palette.action.hover,
|
|
205
|
+
'--dm-tile': dark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.05)',
|
|
206
|
+
'--dm-focus': theme.palette.primary.main,
|
|
207
|
+
'--dm-ok': getIndicatorColor('ok', theme),
|
|
208
|
+
'--dm-warn': getIndicatorColor('warning', theme),
|
|
209
|
+
'--dm-err': getIndicatorColor('error', theme),
|
|
210
|
+
'--dm-info': getIndicatorColor('info', theme),
|
|
211
|
+
};
|
|
212
|
+
themeVarsCache.set(theme, vars);
|
|
213
|
+
}
|
|
214
|
+
return vars;
|
|
215
|
+
}
|
|
216
|
+
const toneStyles = {
|
|
217
|
+
ok: { '--dm-tone': 'var(--dm-ok)' },
|
|
218
|
+
warn: { '--dm-tone': 'var(--dm-warn)' },
|
|
219
|
+
err: { '--dm-tone': 'var(--dm-err)' },
|
|
220
|
+
info: { '--dm-tone': 'var(--dm-info)' },
|
|
221
|
+
};
|
|
222
|
+
/** Style that sets the tone of a pill */
|
|
223
|
+
export function toneStyle(tone) {
|
|
224
|
+
return tone ? toneStyles[tone] : undefined;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"./src/","sources":["styles.ts"],"names":[],"mappings":"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","sourcesContent":["import type React from 'react';\nimport { useInsertionEffect } from 'react';\n\nimport type { IobTheme } from '@iobroker/gui-components';\n\nimport { getIndicatorColor } from './Utils';\n\n/**\n * One style sheet for the cards, the status pills and the own animations.\n *\n * The list renders a few hundred cards. Plain classes are much cheaper than an `sx` property per element,\n * and the theme reaches the classes through CSS variables (see `getThemeVars`).\n */\nconst STYLE_ID = 'iob-dm-styles';\n\nconst styles = `\n/* ---------- Card ---------- */\n.dm-card { box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; border-radius: 12px; border: 1px solid var(--dm-border); background-color: var(--dm-paper); background-image: var(--dm-overlay); color: var(--dm-text); font-size: 13px; line-height: 1.4; }\n.dm-head { display: flex; align-items: center; gap: 12px; box-sizing: border-box; min-height: 72px; padding: 14px 6px 10px 14px; }\n.dm-small .dm-head { gap: 10px; min-height: 56px; padding: 10px 2px 8px 10px; }\n.dm-name { flex: 1; min-width: 0; font-size: 15px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; transition: color 0.3s; }\n.dm-small .dm-name { font-size: 13.5px; }\n.dm-head-end { align-self: flex-start; display: flex; align-items: center; margin-top: -4px; }\n.dm-small .dm-head-end { margin-top: -6px; }\n\n/* The device symbol: the place for the color of the device and for its LED */\n.dm-avatar { position: relative; flex-shrink: 0; box-sizing: border-box; width: 44px; height: 44px; border-radius: 10px; display: flex; align-items: center; justify-content: center; background: var(--dm-accent); color: var(--dm-accent-text); transition: filter 0.4s, opacity 0.4s; }\n.dm-small .dm-avatar { width: 34px; height: 34px; border-radius: 8px; }\n.dm-avatar-img { background: var(--dm-tile); padding: 4px; }\n.dm-avatar-glyph { width: 26px; height: 26px; }\n.dm-small .dm-avatar-glyph { width: 20px; height: 20px; }\n.dm-avatar-img .dm-avatar-glyph { width: 100%; height: 100%; object-fit: contain; }\n.dm-avatar-letter { font-size: 20px; font-weight: 600; line-height: 1; text-transform: uppercase; }\n.dm-small .dm-avatar-letter { font-size: 16px; }\n.dm-avatar-led { position: absolute; right: -6px; bottom: -6px; display: flex; line-height: 0; font-size: 18px; border-radius: 50%; background-color: var(--dm-paper); background-image: var(--dm-overlay); }\n.dm-small .dm-avatar-led { right: -5px; bottom: -5px; font-size: 15px; }\n.dm-off .dm-avatar { filter: grayscale(1); opacity: 0.45; }\n.dm-off .dm-name { color: var(--dm-text2); }\n\n/* Image upload on the device symbol */\n.dm-upload { position: absolute; inset: 0; border-radius: inherit; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.55); color: #fff; opacity: 0; transition: opacity 0.2s; cursor: pointer; }\n.dm-avatar:hover .dm-upload, .dm-upload:focus-within, .dm-upload.dm-upload-busy { opacity: 1; }\n.dm-upload input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }\n.dm-small .dm-upload .iob-ani { font-size: 18px; }\n\n/* Status line */\n.dm-status { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; min-height: 34px; padding: 0 12px 8px; color: var(--dm-text2); }\n.dm-small .dm-status { gap: 2px 3px; min-height: 30px; padding: 0 8px 6px; }\n.dm-status-end { margin-left: auto; display: flex; align-items: center; padding-left: 4px; }\n\n/* A status value. Neutral while all is well; tinted with its color when it needs attention. */\n.dm-pill.dm-pill { display: inline-flex; align-items: center; gap: 4px; box-sizing: border-box; height: 26px; padding: 0 6px; border: 0; border-radius: 7px; background-color: transparent; color: inherit; font-family: inherit; font-size: 12px; font-weight: 500; line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; text-decoration: none; }\n.dm-small .dm-pill.dm-pill { padding: 0 4px; gap: 3px; }\n.dm-pill > svg, .dm-pill > .iob-ani, .dm-pill .MuiSvgIcon-root { font-size: 18px; width: 18px; height: 18px; flex-shrink: 0; }\n.dm-pill > img { width: 18px; height: 18px; }\n.dm-pill-tone.dm-pill-tone { color: var(--dm-tone); background-color: color-mix(in srgb, var(--dm-tone) 15%, transparent); }\n.dm-pill-btn.dm-pill-btn { cursor: pointer; transition: background-color 0.15s; }\n.dm-pill-btn.dm-pill-btn:hover { background-color: var(--dm-hover); }\n.dm-pill-tone.dm-pill-btn:hover { background-color: color-mix(in srgb, var(--dm-tone) 26%, transparent); }\n.dm-pill-btn:focus-visible { outline: 2px solid var(--dm-focus); outline-offset: 1px; }\n.dm-pill-btn.Mui-disabled { opacity: 0.6; }\n.dm-pill-wrap { display: inline-flex; }\n\n/* Facts: label and value */\n.dm-facts { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 12px; row-gap: 2px; padding: 4px 14px 12px; }\n.dm-small .dm-facts { column-gap: 8px; padding: 2px 10px 10px; font-size: 12px; }\n.dm-fact-label { color: var(--dm-text2); font-size: 12px; white-space: nowrap; }\n.dm-small .dm-fact-label { font-size: 11.5px; }\n.dm-fact-value { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dm-fact-copy { display: flex; align-items: center; min-width: 0; gap: 2px; }\n.dm-fact-copy > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dm-copy-btn.dm-copy-btn { padding: 3px; margin: -4px 0; color: var(--dm-text2); opacity: 0.6; transition: opacity 0.15s; }\n.dm-fact-copy:hover .dm-copy-btn, .dm-copy-btn:focus-visible { opacity: 1; }\n.dm-copy-btn .iob-ani { font-size: 16px; }\n.dm-custom { padding: 0 14px 12px; }\n.dm-small .dm-custom { padding: 0 10px 10px; }\n\n/* Actions */\n.dm-foot { margin-top: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; box-sizing: border-box; min-height: 44px; padding: 4px 8px; border-top: 1px solid var(--dm-border); }\n.dm-small .dm-foot { gap: 0; min-height: 38px; padding: 2px 4px; }\n.dm-small .dm-foot .MuiIconButton-sizeSmall { padding: 4px; }\n.dm-small .dm-foot .MuiIconButton-sizeSmall > :is(svg, .iob-ani) { font-size: 20px; }\n/* !important: the control sets its size inline */\n.dm-small .dm-foot-end .MuiFab-root.MuiFab-root { width: 30px !important; height: 30px !important; min-height: 30px !important; }\n.dm-foot-end { margin-left: auto; display: flex; align-items: center; gap: 4px; }\n/* A control in the footer is a quiet round button; only a switched on control gets its color */\n.dm-foot-end .MuiFab-root.MuiFab-root { width: 34px; height: 34px; min-height: 34px; box-shadow: none; }\n.dm-foot-end .MuiFab-default.MuiFab-default { background-color: var(--dm-tile); color: var(--dm-text); }\n.dm-foot-end .MuiFab-default.MuiFab-default:hover { background-color: var(--dm-hover); }\n\n/* Skeleton: the same footprint as the card */\n.dm-skeleton .dm-avatar { background: var(--dm-tile); }\n\n/* Instance cards on the root page */\n.dm-inst.dm-inst { width: 240px; margin: 10px; }\n.dm-inst-small.dm-inst-small { width: 200px; margin: 5px; }\n.dm-inst-area.dm-inst-area { display: flex; flex-direction: column; align-items: center; gap: 10px; height: 100%; padding: 20px 16px 18px; text-align: center; color: inherit; font-family: inherit; }\n.dm-inst-small .dm-inst-area.dm-inst-area { flex-direction: row; justify-content: flex-start; gap: 10px; padding: 10px; text-align: left; }\n.dm-inst .dm-avatar { width: 64px; height: 64px; border-radius: 14px; background: var(--dm-tile); padding: 8px; }\n.dm-inst-small .dm-avatar { width: 38px; height: 38px; border-radius: 9px; padding: 5px; }\n.dm-inst-id { font-size: 16px; font-weight: 600; overflow-wrap: anywhere; }\n.dm-inst-small .dm-inst-id { font-size: 13.5px; }\n.dm-inst-title { color: var(--dm-text2); font-size: 13px; }\n.dm-inst-small .dm-inst-title { font-size: 12px; }\n.dm-inst-small .dm-inst-text { min-width: 0; }\n.dm-inst-small .dm-inst-text > div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n/* Empty list: what happened and what to do */\n.dm-empty { box-sizing: border-box; width: 100%; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 56px 16px; color: var(--dm-text2); font-size: 14px; text-align: center; }\n.dm-empty > .iob-ani, .dm-empty > svg { font-size: 48px; }\n\n/* Confirmation after a successful action */\n.dm-result { position: fixed; left: 50%; top: 50%; z-index: 1500; display: flex; align-items: center; justify-content: center; width: 84px; height: 84px; margin: -42px 0 0 -42px; border-radius: 50%; background-color: var(--dm-paper); background-image: var(--dm-overlay); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); pointer-events: none; animation: dm-result 1.25s ease forwards; }\n.dm-result .iob-ani { font-size: 52px; }\n.dm-toast { display: flex; align-items: center; gap: 10px; }\n.dm-toast .iob-ani { font-size: 22px; }\n\n/* ---------- Own animations ---------- */\n\n/* Action symbols show what the button does while the mouse is over it */\n.dm-ani.dm-ani { transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); }\n.dm-ani-gear.dm-ani-gear { transition-duration: 0.6s; }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-spin { transform: rotate(180deg); }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-gear { transform: rotate(90deg); }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-turn { transform: rotate(90deg); }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-launch { transform: translate(1.5px, -1.5px); }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-nudge { transform: translateX(2px); }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-pen { animation: dm-pen 0.5s ease-in-out; }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-hop { animation: dm-hop 0.5s ease-out; }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-search { animation: dm-search 0.7s ease-in-out; }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-glow { animation: dm-glow 0.6s ease-in-out; }\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani-tick { animation: dm-tick 0.4s ease-out; }\n@keyframes dm-pen { 0%, 100% { transform: none; } 30% { transform: rotate(-14deg) translateY(-1px); } 65% { transform: rotate(8deg); } }\n@keyframes dm-hop { 0%, 100% { transform: none; } 40% { transform: translateY(-3px); } 70% { transform: translateY(0.5px); } }\n@keyframes dm-search { 0%, 100% { transform: none; } 25% { transform: translate(-1.5px, -1px); } 50% { transform: translate(1px, -1.5px); } 75% { transform: translate(1px, 1px); } }\n@keyframes dm-glow { 0%, 100% { filter: none; } 50% { filter: drop-shadow(0 0 3px currentColor); } }\n@keyframes dm-tick { 0%, 100% { transform: none; } 50% { transform: scale(1.15); } }\n\n/* Battery: the charge slides to its level */\n.dm-bat .dm-bat-body { fill: none; stroke: currentColor; stroke-width: 1.6; }\n.dm-bat .dm-bat-cap { fill: currentColor; }\n.dm-bat .dm-bat-fill { fill: var(--dm-bat, currentColor); transform-box: fill-box; transform-origin: 0 50%; transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1), fill 0.4s; }\n.dm-bat-unknown .dm-bat-fill { opacity: 0.35; }\n.dm-bat-charging .dm-bat-fill { animation: dm-bat-charge 1.8s ease-in-out infinite; }\n.dm-bat .dm-bat-bolt { fill: currentColor; stroke: var(--dm-paper, #fff); stroke-width: 0.9; stroke-linejoin: round; paint-order: stroke; }\n@keyframes dm-bat-charge { 0% { transform: scaleX(0.15); } 80%, 100% { transform: scaleX(1); } }\n\n/* Signal: the bars light up one after another */\n.dm-sig rect { fill: currentColor; opacity: 0.22; transition: opacity 0.3s; }\n.dm-sig rect.dm-sig-on { opacity: 1; }\n.dm-sig rect:nth-child(2) { transition-delay: 0.07s; }\n.dm-sig rect:nth-child(3) { transition-delay: 0.14s; }\n.dm-sig rect:nth-child(4) { transition-delay: 0.21s; }\n\n/* Update: the arrow drops into the tray */\n.dm-upd path { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }\n.dm-upd .dm-upd-arrow { transition: transform 0.25s ease-out; }\n.dm-upd:hover .dm-upd-arrow, :is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .dm-upd .dm-upd-arrow { transform: translateY(2.5px); }\n\n@keyframes dm-result { 0% { opacity: 0; transform: scale(0.7); } 12% { opacity: 1; transform: scale(1); } 78% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(0.92); } }\n@keyframes dm-fade { 0%, 100% { opacity: 0; } 15%, 80% { opacity: 1; } }\n\n@media (prefers-reduced-motion: reduce) {\n .dm-ani.dm-ani, .dm-bat .dm-bat-fill, .dm-sig rect, .dm-upd .dm-upd-arrow, .dm-avatar, .dm-upload, .dm-name, .dm-switch, .dm-switch * { transition: none !important; }\n :is(button, a, [role=\"button\"], [role=\"menuitem\"]):is(:hover, :focus-visible) .dm-ani { transform: none !important; animation: none !important; }\n .dm-bat-charging .dm-bat-fill { animation: none; }\n .dm-upd:hover .dm-upd-arrow, :is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .dm-upd .dm-upd-arrow { transform: none; }\n .dm-result { animation-name: dm-fade; }\n}\n`;\n\nlet inserted = false;\n\n/** Puts the style sheet into the page once. Safe to call in a constructor, before the first paint. */\nexport function ensureDmStyles(): void {\n if (inserted || typeof window === 'undefined') {\n return;\n }\n inserted = true;\n let style = window.document.getElementById(STYLE_ID);\n if (!style) {\n style = window.document.createElement('style');\n style.setAttribute('id', STYLE_ID);\n window.document.head.appendChild(style);\n }\n // Also replaces the sheet of an older copy of this module (e.g. after a hot reload)\n style.innerHTML = styles;\n}\n\n/** The same for function components */\nexport function useDmStyles(): void {\n useInsertionEffect(ensureDmStyles, []);\n}\n\nconst themeVarsCache = new WeakMap<IobTheme, React.CSSProperties>();\n\n/**\n * The colors of the theme as CSS variables for the classes above.\n *\n * Cached per theme: the object is handed to every card, and a stable reference keeps the style\n * comparison of React cheap.\n */\nexport function getThemeVars(theme: IobTheme): React.CSSProperties {\n let vars = themeVarsCache.get(theme);\n if (!vars) {\n const dark = theme.palette.mode === 'dark';\n vars = {\n '--dm-paper': theme.palette.background.paper,\n // Like the elevation of the MUI paper: in the dark themes paper and page have the same color\n '--dm-overlay': dark ? 'linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05))' : 'none',\n // Not `palette.divider`: in some themes it has nearly the color of the card and the lines disappear\n '--dm-border': dark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.12)',\n '--dm-text': theme.palette.text.primary,\n '--dm-text2': theme.palette.text.secondary,\n '--dm-hover': theme.palette.action.hover,\n '--dm-tile': dark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.05)',\n '--dm-focus': theme.palette.primary.main,\n '--dm-ok': getIndicatorColor('ok', theme),\n '--dm-warn': getIndicatorColor('warning', theme),\n '--dm-err': getIndicatorColor('error', theme),\n '--dm-info': getIndicatorColor('info', theme),\n } as React.CSSProperties;\n themeVarsCache.set(theme, vars);\n }\n return vars;\n}\n\n/** Tone of a status pill: the color it is tinted with */\nexport type PillTone = 'ok' | 'warn' | 'err' | 'info';\n\nconst toneStyles: Record<PillTone, React.CSSProperties> = {\n ok: { '--dm-tone': 'var(--dm-ok)' } as React.CSSProperties,\n warn: { '--dm-tone': 'var(--dm-warn)' } as React.CSSProperties,\n err: { '--dm-tone': 'var(--dm-err)' } as React.CSSProperties,\n info: { '--dm-tone': 'var(--dm-info)' } as React.CSSProperties,\n};\n\n/** Style that sets the tone of a pill */\nexport function toneStyle(tone?: PillTone): React.CSSProperties | undefined {\n return tone ? toneStyles[tone] : undefined;\n}\n"]}
|