@iobroker/gui-components 10.3.16 → 10.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/build/Components/AnimatedIcons/IconCopyToClipboard.d.ts +25 -0
- package/build/Components/AnimatedIcons/IconCopyToClipboard.js +84 -0
- package/build/Components/AnimatedIcons/IconCopyToClipboard.js.map +1 -0
- package/build/Components/AnimatedIcons/IconFilter.d.ts +23 -0
- package/build/Components/AnimatedIcons/IconFilter.js +26 -0
- package/build/Components/AnimatedIcons/IconFilter.js.map +1 -0
- package/build/Components/AnimatedIcons/IconFolder.d.ts +6 -0
- package/build/Components/AnimatedIcons/IconFolder.js +2 -1
- package/build/Components/AnimatedIcons/IconFolder.js.map +1 -1
- package/build/Components/AnimatedIcons/IconThemeMode.d.ts +22 -0
- package/build/Components/AnimatedIcons/IconThemeMode.js +32 -0
- package/build/Components/AnimatedIcons/IconThemeMode.js.map +1 -0
- package/build/Components/AnimatedIcons/IconUpload.d.ts +24 -0
- package/build/Components/AnimatedIcons/IconUpload.js +37 -0
- package/build/Components/AnimatedIcons/IconUpload.js.map +1 -0
- package/build/Components/AnimatedIcons/common.d.ts +2 -0
- package/build/Components/AnimatedIcons/common.js +64 -5
- package/build/Components/AnimatedIcons/common.js.map +1 -1
- package/build/Components/ColorPicker.js +4 -3
- package/build/Components/ColorPicker.js.map +1 -1
- package/build/Components/FileBrowser.d.ts +6 -0
- package/build/Components/FileBrowser.js +54 -12
- package/build/Components/FileBrowser.js.map +1 -1
- package/build/Components/FileViewer.js +3 -2
- package/build/Components/FileViewer.js.map +1 -1
- package/build/Components/ObjectBrowser/ObjectBrowserClass.d.ts +6 -0
- package/build/Components/ObjectBrowser/ObjectBrowserClass.js +66 -6
- package/build/Components/ObjectBrowser/ObjectBrowserClass.js.map +1 -1
- package/build/Components/ObjectBrowser/contextMenu.js +3 -2
- package/build/Components/ObjectBrowser/contextMenu.js.map +1 -1
- package/build/Components/ObjectBrowser/renderLeaf.js +55 -76
- package/build/Components/ObjectBrowser/renderLeaf.js.map +1 -1
- package/build/Components/ObjectBrowser/rowAnimation.d.ts +25 -1
- package/build/Components/ObjectBrowser/rowAnimation.js +46 -19
- package/build/Components/ObjectBrowser/rowAnimation.js.map +1 -1
- package/build/Components/ObjectBrowser/skeleton.d.ts +15 -0
- package/build/Components/ObjectBrowser/skeleton.js +106 -0
- package/build/Components/ObjectBrowser/skeleton.js.map +1 -0
- package/build/Components/ObjectBrowser/styles.js +16 -11
- package/build/Components/ObjectBrowser/styles.js.map +1 -1
- package/build/Components/ObjectBrowser/toolbar.js +18 -14
- package/build/Components/ObjectBrowser/toolbar.js.map +1 -1
- package/build/Components/ObjectBrowser/utils.d.ts +2 -0
- package/build/Components/ObjectBrowser/utils.js +2 -0
- package/build/Components/ObjectBrowser/utils.js.map +1 -1
- package/build/Components/ToggleThemeMenu.js +11 -8
- package/build/Components/ToggleThemeMenu.js.map +1 -1
- package/build/Components/TreeTable.d.ts +16 -0
- package/build/Components/TreeTable.js +106 -18
- package/build/Components/TreeTable.js.map +1 -1
- package/build/Components/UploadImage.d.ts +22 -0
- package/build/Components/UploadImage.js +119 -16
- package/build/Components/UploadImage.js.map +1 -1
- package/build/Dialogs/ComplexCron.js +3 -2
- package/build/Dialogs/ComplexCron.js.map +1 -1
- package/build/Dialogs/Error.js +3 -2
- package/build/Dialogs/Error.js.map +1 -1
- package/build/index.d.ts +4 -0
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"./src/","sources":["Components/AnimatedIcons/common.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright 2026 Denis Haev (bluefox) <dogafox@gmail.com>\n *\n * MIT License\n *\n * Shared parts of the animated icons: props, size, the style sheet and helpers.\n * The icons are plain CSS/SVG (no animation library). They use `currentColor`, so they take the color of the\n * surrounding text or button, and they have the size of the MUI icons.\n */\nimport type React from 'react';\nimport { useEffect, useInsertionEffect, useRef, type CSSProperties } from 'react';\n\nexport interface AnimatedIconProps {\n /** Size like the MUI icons: 'small' (20 px), 'medium' (24 px, default), 'large' (35 px), 'inherit', pixels or e.g. '2em' */\n fontSize?: 'inherit' | 'small' | 'medium' | 'large' | number | `${number}${'px' | 'em' | 'rem' | '%'}`;\n /** Class name for the root element */\n className?: string;\n /** Styles for the root element, e.g. `color` */\n style?: CSSProperties;\n /** Accessible name. Without it, the icon is decorative and hidden from screen readers. */\n ariaLabel?: string;\n}\n\nconst SIZES: Record<string, string> = {\n small: '1.25rem',\n medium: '1.5rem',\n large: '2.1875rem',\n inherit: 'inherit',\n};\n\nconst STYLE_ID = 'iob-animated-icons';\n\nconst styles = `\n/* zero specificity: MUI may set the size, e.g. 20 px for the start icon of a Button, like for its own icons */\n:where(.iob-ani) { font-size: 1.5rem; }\n.iob-ani { display: inline-block; position: relative; width: 1em; height: 1em; flex-shrink: 0; vertical-align: middle; line-height: 0; user-select: none; }\n.iob-ani > svg, .iob-ani-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: visible; }\n\n/* Play / pause: two halves of the triangle become the two bars */\n.iob-ani-pp-a, .iob-ani-pp-b { position: absolute; inset: 0; background: currentColor; transition: clip-path 0.32s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s ease; }\n.iob-ani-pp-a { clip-path: polygon(33.33% 20.83%, 56.25% 35.42%, 56.25% 64.58%, 33.33% 79.17%); }\n.iob-ani-pp-b { clip-path: polygon(56.25% 35.42%, 79.17% 50%, 79.17% 50%, 56.25% 64.58%); }\n.iob-ani-on .iob-ani-pp-a { clip-path: polygon(25% 20.83%, 41.67% 20.83%, 41.67% 79.17%, 25% 79.17%); }\n.iob-ani-on .iob-ani-pp-b { clip-path: polygon(58.33% 20.83%, 75% 20.83%, 75% 79.17%, 58.33% 79.17%); }\n.iob-ani-pp-ring { opacity: 0; transition: opacity 0.2s; }\n.iob-ani-pp-ring circle { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-dasharray: 0.22 0.78; }\n.iob-ani-pp-pending .iob-ani-pp-ring { opacity: 1; animation: iob-ani-spin 0.9s linear infinite; }\n.iob-ani-pp-pending .iob-ani-pp-a, .iob-ani-pp-pending .iob-ani-pp-b { transform: scale(0.72); }\n\n/* Status LED */\n.iob-ani-led-dot, .iob-ani-led-ping { position: absolute; left: 20%; top: 20%; width: 60%; height: 60%; border-radius: 50%; background-color: var(--iob-ani-led); }\n.iob-ani-led-dot { transition: background-color 0.3s; box-shadow: inset 0 -0.05em 0.1em rgba(0, 0, 0, 0.28); }\n.iob-ani-led-ping { opacity: 0; }\n.iob-ani-led-blink .iob-ani-led-dot, .iob-ani-led-blink .iob-ani-led-own { animation: iob-ani-breathe 1.6s ease-in-out infinite; }\n.iob-ani-led-ping.iob-ani-led-full { left: 0; top: 0; width: 100%; height: 100%; }\n.iob-ani-led-own { display: flex; align-items: center; justify-content: center; line-height: normal; }\n\n/* Result: circle and mark draw themselves */\n:where(.iob-ani-res-success) { color: #4CAF50; }\n:where(.iob-ani-res-warning) { color: #FF9800; }\n:where(.iob-ani-res-error) { color: #F44336; }\n.iob-ani-res svg * { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; stroke-dashoffset: 1; }\n.iob-ani-res-circle { transform: rotate(-90deg); transform-origin: 12px 12px; animation: iob-ani-draw 0.45s cubic-bezier(0.65, 0, 0.35, 1) forwards; }\n.iob-ani-res-mark { animation: iob-ani-draw 0.3s cubic-bezier(0.65, 0, 0.35, 1) 0.35s forwards; }\n.iob-ani-res-mark2 { animation: iob-ani-draw 0.3s cubic-bezier(0.65, 0, 0.35, 1) 0.5s forwards; }\n.iob-ani-res-error svg, .iob-ani-res-warning svg { animation: iob-ani-shake 0.4s 0.75s; }\n\n/* Refresh */\n.iob-ani-rf-done { opacity: 0; }\n.iob-ani-rf-done path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; stroke-dashoffset: 1; }\n\n/* Bell */\n.iob-ani-bell-body { transform-origin: 12px 3px; }\n\n/* Menu / arrow: three bars, the icon turns by 180 degrees */\n.iob-ani-menu-rot { transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-menu-open .iob-ani-menu-rot { transform: rotate(180deg); }\n.iob-ani-menu-right .iob-ani-menu-flip { transform: scaleX(-1); }\n.iob-ani-menu-bar { position: absolute; left: 0.125em; width: 0.75em; height: 0.0834em; margin-top: -0.0417em; border-radius: 0.02em; background: currentColor; transform-origin: 100% 50%; transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-menu-b1 { top: 0.2917em; }\n.iob-ani-menu-b2 { top: 0.5em; }\n.iob-ani-menu-b3 { top: 0.7083em; }\n.iob-ani-menu-open .iob-ani-menu-b1 { transform: translate(-0.0417em, 0.2083em) rotate(45deg) scaleX(0.63); }\n.iob-ani-menu-open .iob-ani-menu-b2 { transform: translateX(-0.0417em) scaleX(0.889); }\n.iob-ani-menu-open .iob-ani-menu-b3 { transform: translate(-0.0417em, -0.2083em) rotate(-45deg) scaleX(0.63); }\n\n/* Trash: the lid opens on hover of the icon or of its button */\n.iob-ani-trash-lid { transform-origin: 5px 6px; transition: transform 0.25s cubic-bezier(0.3, 1.5, 0.6, 1); }\n.iob-ani-trash-open .iob-ani-trash-lid,\n.iob-ani-trash:hover .iob-ani-trash-lid,\n:is(button, a, [role=\"button\"]):hover .iob-ani-trash .iob-ani-trash-lid,\n:is(button, a, [role=\"button\"]):focus-visible .iob-ani-trash .iob-ani-trash-lid { transform: translateY(-1.5px) rotate(-18deg); }\n\n/* Expert mode: mortarboard, outlined when off and filled when on */\n.iob-ani-expert-hat { transform-origin: 12px 12px; }\n.iob-ani-expert-shape { fill: currentColor; fill-opacity: 0; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; transition: fill-opacity 0.18s ease; }\n.iob-ani-expert-on .iob-ani-expert-shape { fill-opacity: 1; transition-delay: 0.12s; }\n.iob-ani-expert-tassel { transform-origin: 21.2px 9.1px; }\n.iob-ani-expert-cord { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; }\n.iob-ani-expert-tuft { fill: currentColor; stroke: currentColor; stroke-width: 0.8; stroke-linejoin: round; }\n\n/* Folder: closed, the front flap lies on the back like a closed folder; open, it folds down. The closed\n shape covers both until the flap starts to move, so the closed folder looks exactly like IconClosed */\n.iob-ani-folder path { fill: currentColor; }\n.iob-ani-folder-front { transform-origin: 104px 448px; transform: scaleY(1.1667) skewX(29.1deg); transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-folder-open .iob-ani-folder-front { transform: none; transition: transform 0.32s cubic-bezier(0.3, 1.35, 0.5, 1); }\n.iob-ani-folder-closed { transition: opacity 0.06s linear 0.18s; }\n.iob-ani-folder-open .iob-ani-folder-closed { opacity: 0; transition-delay: 0s; }\n\n/* Connection */\n.iob-ani-wifi path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; transition: opacity 0.3s; }\n.iob-ani-wifi circle { fill: currentColor; transition: opacity 0.3s; }\n.iob-ani-wifi .iob-ani-wifi-slash { stroke-dasharray: 1 1; stroke-dashoffset: 1; transition: stroke-dashoffset 0.35s cubic-bezier(0.65, 0, 0.35, 1); }\n.iob-ani-wifi-disconnected .iob-ani-wifi-slash { stroke-dashoffset: 0; }\n.iob-ani-wifi-disconnected .iob-ani-wifi-w { opacity: 0.35; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w { animation: iob-ani-wave 1.5s ease-in-out infinite; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w1 { animation-delay: 0.18s; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w2 { animation-delay: 0.36s; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w3 { animation-delay: 0.54s; }\n\n@keyframes iob-ani-spin { to { transform: rotate(360deg); } }\n@keyframes iob-ani-draw { to { stroke-dashoffset: 0; } }\n@keyframes iob-ani-breathe { 50% { opacity: 0.35; } }\n@keyframes iob-ani-wave { 0%, 100% { opacity: 0.25; } 30% { opacity: 1; } }\n@keyframes iob-ani-shake { 20% { transform: translateX(-1.5px); } 40% { transform: translateX(1.5px); } 60% { transform: translateX(-1px); } 80% { transform: translateX(1px); } }\n\n@media (prefers-reduced-motion: reduce) {\n .iob-ani-pp-a, .iob-ani-pp-b, .iob-ani-menu-rot, .iob-ani-menu-bar, .iob-ani-trash-lid, .iob-ani-expert-shape, .iob-ani-folder-front, .iob-ani-folder-closed { transition-duration: 0.01ms; transition-delay: 0s; }\n .iob-ani-pp-pending .iob-ani-pp-ring { animation: iob-ani-breathe 1.2s ease-in-out infinite; }\n .iob-ani-res svg, .iob-ani-res svg * { animation: none !important; stroke-dashoffset: 0; }\n}\n`;\n\n/** Puts the style sheet of the animated icons into the page, once and before the first paint */\nexport function useAnimatedIconStyles(): void {\n useInsertionEffect(() => {\n if (!window.document.getElementById(STYLE_ID)) {\n const style = window.document.createElement('style');\n style.setAttribute('id', STYLE_ID);\n style.innerHTML = styles;\n window.document.head.appendChild(style);\n }\n }, []);\n}\n\n/** Properties of the root element: class, size and accessibility */\nexport function rootProps(props: AnimatedIconProps, className: string): React.HTMLAttributes<HTMLSpanElement> {\n // Without fontSize the size comes from the style sheet (24 px), so that MUI can change it like for its own icons\n let fontSize: string | number | undefined;\n if (typeof props.fontSize === 'number') {\n fontSize = props.fontSize;\n } else if (props.fontSize) {\n fontSize = SIZES[props.fontSize] || props.fontSize;\n }\n return {\n className: `iob-ani ${className}${props.className ? ` ${props.className}` : ''}`,\n style: fontSize === undefined ? props.style : { fontSize, ...props.style },\n role: props.ariaLabel ? 'img' : undefined,\n 'aria-label': props.ariaLabel,\n 'aria-hidden': props.ariaLabel ? undefined : true,\n };\n}\n\n/** True if the user asked the system for less motion */\nexport function prefersReducedMotion(): boolean {\n return !!window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n}\n\n/** Plays a one-time animation (Web Animations API), unless the user wants less motion */\nexport function play(\n element: Element | null | undefined,\n keyframes: Keyframe[],\n options: KeyframeAnimationOptions,\n): Animation | null {\n if (!element?.animate || prefersReducedMotion()) {\n return null;\n }\n return element.animate(keyframes, options);\n}\n\n/** Calls `onChange` when `value` changes, but not on the first render */\nexport function useChange<T>(value: T, onChange: (value: T, previous: T) => void): void {\n const previous = useRef(value);\n const callback = useRef(onChange);\n useEffect(() => {\n callback.current = onChange;\n });\n useEffect(() => {\n if (!Object.is(previous.current, value)) {\n const old = previous.current;\n previous.current = value;\n callback.current(value, old);\n }\n }, [value]);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"./src/","sources":["Components/AnimatedIcons/common.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright 2026 Denis Haev (bluefox) <dogafox@gmail.com>\n *\n * MIT License\n *\n * Shared parts of the animated icons: props, size, the style sheet and helpers.\n * The icons are plain CSS/SVG (no animation library). They use `currentColor`, so they take the color of the\n * surrounding text or button, and they have the size of the MUI icons.\n */\nimport type React from 'react';\nimport { useEffect, useId, useInsertionEffect, useRef, type CSSProperties } from 'react';\n\nexport interface AnimatedIconProps {\n /** Size like the MUI icons: 'small' (20 px), 'medium' (24 px, default), 'large' (35 px), 'inherit', pixels or e.g. '2em' */\n fontSize?: 'inherit' | 'small' | 'medium' | 'large' | number | `${number}${'px' | 'em' | 'rem' | '%'}`;\n /** Class name for the root element */\n className?: string;\n /** Styles for the root element, e.g. `color` */\n style?: CSSProperties;\n /** Accessible name. Without it, the icon is decorative and hidden from screen readers. */\n ariaLabel?: string;\n}\n\nconst SIZES: Record<string, string> = {\n small: '1.25rem',\n medium: '1.5rem',\n large: '2.1875rem',\n inherit: 'inherit',\n};\n\nconst STYLE_ID = 'iob-animated-icons';\n\nconst styles = `\n/* zero specificity: MUI may set the size, e.g. 20 px for the start icon of a Button, like for its own icons */\n:where(.iob-ani) { font-size: 1.5rem; }\n.iob-ani { display: inline-block; position: relative; width: 1em; height: 1em; flex-shrink: 0; vertical-align: middle; line-height: 0; user-select: none; }\n.iob-ani > svg, .iob-ani-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: visible; }\n\n/* Play / pause: two halves of the triangle become the two bars */\n.iob-ani-pp-a, .iob-ani-pp-b { position: absolute; inset: 0; background: currentColor; transition: clip-path 0.32s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s ease; }\n.iob-ani-pp-a { clip-path: polygon(33.33% 20.83%, 56.25% 35.42%, 56.25% 64.58%, 33.33% 79.17%); }\n.iob-ani-pp-b { clip-path: polygon(56.25% 35.42%, 79.17% 50%, 79.17% 50%, 56.25% 64.58%); }\n.iob-ani-on .iob-ani-pp-a { clip-path: polygon(25% 20.83%, 41.67% 20.83%, 41.67% 79.17%, 25% 79.17%); }\n.iob-ani-on .iob-ani-pp-b { clip-path: polygon(58.33% 20.83%, 75% 20.83%, 75% 79.17%, 58.33% 79.17%); }\n.iob-ani-pp-ring { opacity: 0; transition: opacity 0.2s; }\n.iob-ani-pp-ring circle { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-dasharray: 0.22 0.78; }\n.iob-ani-pp-pending .iob-ani-pp-ring { opacity: 1; animation: iob-ani-spin 0.9s linear infinite; }\n.iob-ani-pp-pending .iob-ani-pp-a, .iob-ani-pp-pending .iob-ani-pp-b { transform: scale(0.72); }\n\n/* Status LED */\n.iob-ani-led-dot, .iob-ani-led-ping { position: absolute; left: 20%; top: 20%; width: 60%; height: 60%; border-radius: 50%; background-color: var(--iob-ani-led); }\n.iob-ani-led-dot { transition: background-color 0.3s; box-shadow: inset 0 -0.05em 0.1em rgba(0, 0, 0, 0.28); }\n.iob-ani-led-ping { opacity: 0; }\n.iob-ani-led-blink .iob-ani-led-dot, .iob-ani-led-blink .iob-ani-led-own { animation: iob-ani-breathe 1.6s ease-in-out infinite; }\n.iob-ani-led-ping.iob-ani-led-full { left: 0; top: 0; width: 100%; height: 100%; }\n.iob-ani-led-own { display: flex; align-items: center; justify-content: center; line-height: normal; }\n\n/* Result: circle and mark draw themselves */\n:where(.iob-ani-res-success) { color: #4CAF50; }\n:where(.iob-ani-res-warning) { color: #FF9800; }\n:where(.iob-ani-res-error) { color: #F44336; }\n.iob-ani-res svg * { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; stroke-dashoffset: 1; }\n.iob-ani-res-circle { transform: rotate(-90deg); transform-origin: 12px 12px; animation: iob-ani-draw 0.45s cubic-bezier(0.65, 0, 0.35, 1) forwards; }\n.iob-ani-res-mark { animation: iob-ani-draw 0.3s cubic-bezier(0.65, 0, 0.35, 1) 0.35s forwards; }\n.iob-ani-res-mark2 { animation: iob-ani-draw 0.3s cubic-bezier(0.65, 0, 0.35, 1) 0.5s forwards; }\n.iob-ani-res-error svg, .iob-ani-res-warning svg { animation: iob-ani-shake 0.4s 0.75s; }\n\n/* Refresh */\n.iob-ani-rf-done { opacity: 0; }\n.iob-ani-rf-done path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1 1; stroke-dashoffset: 1; }\n\n/* Bell */\n.iob-ani-bell-body { transform-origin: 12px 3px; }\n\n/* Menu / arrow: three bars, the icon turns by 180 degrees */\n.iob-ani-menu-rot { transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-menu-open .iob-ani-menu-rot { transform: rotate(180deg); }\n.iob-ani-menu-right .iob-ani-menu-flip { transform: scaleX(-1); }\n.iob-ani-menu-bar { position: absolute; left: 0.125em; width: 0.75em; height: 0.0834em; margin-top: -0.0417em; border-radius: 0.02em; background: currentColor; transform-origin: 100% 50%; transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-menu-b1 { top: 0.2917em; }\n.iob-ani-menu-b2 { top: 0.5em; }\n.iob-ani-menu-b3 { top: 0.7083em; }\n.iob-ani-menu-open .iob-ani-menu-b1 { transform: translate(-0.0417em, 0.2083em) rotate(45deg) scaleX(0.63); }\n.iob-ani-menu-open .iob-ani-menu-b2 { transform: translateX(-0.0417em) scaleX(0.889); }\n.iob-ani-menu-open .iob-ani-menu-b3 { transform: translate(-0.0417em, -0.2083em) rotate(-45deg) scaleX(0.63); }\n\n/* Trash: the lid opens on hover of the icon or of its button or menu item */\n.iob-ani-trash-lid { transform-origin: 5px 6px; transition: transform 0.25s cubic-bezier(0.3, 1.5, 0.6, 1); }\n.iob-ani-trash-open .iob-ani-trash-lid,\n.iob-ani-trash:hover .iob-ani-trash-lid,\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):hover .iob-ani-trash .iob-ani-trash-lid,\n:is(button, a, [role=\"button\"], [role=\"menuitem\"]):focus-visible .iob-ani-trash .iob-ani-trash-lid { transform: translateY(-1.5px) rotate(-18deg); }\n\n/* Expert mode: mortarboard, outlined when off and filled when on */\n.iob-ani-expert-hat { transform-origin: 12px 12px; }\n.iob-ani-expert-shape { fill: currentColor; fill-opacity: 0; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; transition: fill-opacity 0.18s ease; }\n.iob-ani-expert-on .iob-ani-expert-shape { fill-opacity: 1; transition-delay: 0.12s; }\n.iob-ani-expert-tassel { transform-origin: 21.2px 9.1px; }\n.iob-ani-expert-cord { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; }\n.iob-ani-expert-tuft { fill: currentColor; stroke: currentColor; stroke-width: 0.8; stroke-linejoin: round; }\n\n/* Folder: closed, the front flap lies on the back like a closed folder; open, it folds down. The closed\n shape covers both until the flap starts to move, so the closed folder looks exactly like IconClosed */\n.iob-ani-folder path { fill: currentColor; }\n.iob-ani-folder-front { transform-origin: 104px 448px; transform: scaleY(1.1667) skewX(29.1deg); transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-folder-open .iob-ani-folder-front { transform: none; transition: transform 0.32s cubic-bezier(0.3, 1.35, 0.5, 1); }\n.iob-ani-folder-closed { transition: opacity 0.06s linear 0.18s; }\n.iob-ani-folder-open .iob-ani-folder-closed { opacity: 0; transition-delay: 0s; }\n/* toggleOnHover: shows the other state while the mouse is over the icon or its button, e.g. \"expand all\" */\n.iob-ani-folder-hover:not(.iob-ani-folder-open):hover .iob-ani-folder-front,\n:is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .iob-ani-folder-hover:not(.iob-ani-folder-open) .iob-ani-folder-front { transform: none; transition: transform 0.32s cubic-bezier(0.3, 1.35, 0.5, 1); }\n.iob-ani-folder-hover:not(.iob-ani-folder-open):hover .iob-ani-folder-closed,\n:is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .iob-ani-folder-hover:not(.iob-ani-folder-open) .iob-ani-folder-closed { opacity: 0; transition-delay: 0s; }\n.iob-ani-folder-hover.iob-ani-folder-open:hover .iob-ani-folder-front,\n:is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .iob-ani-folder-hover.iob-ani-folder-open .iob-ani-folder-front { transform: scaleY(1.1667) skewX(29.1deg); transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-folder-hover.iob-ani-folder-open:hover .iob-ani-folder-closed,\n:is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .iob-ani-folder-hover.iob-ani-folder-open .iob-ani-folder-closed { opacity: 1; transition-delay: 0.18s; }\n\n/* Copy to clipboard: the copy slides out of the original, then a check mark is drawn in it */\n.iob-ani-copy svg * { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }\n.iob-ani-copy .iob-ani-copy-check { opacity: 0; stroke-width: 2.2; stroke-dasharray: 1 1; stroke-dashoffset: 1; }\n.iob-ani-click { cursor: pointer; }\n\n/* Theme: sun (light), ring (blue), half filled (colored) or moon (dark). The shadow of the moon is a mask. */\n.iob-ani-theme-disc { fill: currentColor; fill-opacity: 1; stroke: currentColor; stroke-width: 2; transform-origin: 12px 12px; transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), fill-opacity 0.3s; }\n.iob-ani-theme-half { fill: currentColor; opacity: 0; transition: opacity 0.3s; }\n.iob-ani-theme-rays { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; transform-origin: 12px 12px; transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s; }\n.iob-ani-theme-cut { transform: translate(8px, -8px); transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1); }\n.iob-ani-theme-blue .iob-ani-theme-disc, .iob-ani-theme-colored .iob-ani-theme-disc { fill-opacity: 0; }\n.iob-ani-theme-colored .iob-ani-theme-half { opacity: 1; }\n/* the rays are 45 degrees apart: turned by 45 degrees they look the same, but they spin on the change */\n.iob-ani-theme-blue .iob-ani-theme-rays { transform: rotate(45deg); }\n.iob-ani-theme-colored .iob-ani-theme-rays { transform: rotate(90deg); }\n.iob-ani-theme-dark .iob-ani-theme-disc { transform: scale(1.55); }\n.iob-ani-theme-dark .iob-ani-theme-cut { transform: none; transition-delay: 0.08s; }\n.iob-ani-theme-dark .iob-ani-theme-rays { transform: rotate(-90deg) scale(0.4); opacity: 0; }\n\n/* Upload: the arrow moves up into the bar */\n.iob-ani-up path { fill: currentColor; }\n.iob-ani-up-arrow { transition: transform 0.2s ease-out; }\n.iob-ani-up:hover .iob-ani-up-arrow,\n:is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .iob-ani-up .iob-ani-up-arrow { transform: translateY(-2px); }\n.iob-ani-up-ready .iob-ani-up-arrow { animation: iob-ani-up-bob 0.8s ease-in-out infinite; }\n.iob-ani-up-uploading .iob-ani-up-arrow { animation: iob-ani-up-rise 1.1s linear infinite; }\n.iob-ani-up-uploading .iob-ani-up-bar { animation: iob-ani-up-bar 1.1s ease-out infinite; }\n@keyframes iob-ani-up-rise {\n 0% { transform: translateY(15px); animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1); }\n 35%, 50% { transform: translateY(0); animation-timing-function: cubic-bezier(0.6, 0, 0.8, 0.4); }\n 100% { transform: translateY(-15px); }\n}\n@keyframes iob-ani-up-bar { 0%, 84% { transform: none; } 92% { transform: translateY(-1.2px); } }\n@keyframes iob-ani-up-bob { 50% { transform: translateY(-2.5px); } }\n\n/* Filter: a red cross shows that a click removes the filter; it jumps away when the filter is cleared */\n.iob-ani-filter-funnel { fill: currentColor; stroke: currentColor; stroke-width: 1; }\n:where(.iob-ani-filter-x) { color: #F44336; }\n.iob-ani-filter-x { fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; transform-origin: 19px 16.75px; opacity: 0; transform: translate(3px, -5px) rotate(90deg) scale(0.2); transition: transform 0.3s cubic-bezier(0.5, -0.4, 0.8, 0.6), opacity 0.2s 0.1s; }\n.iob-ani-filter-on .iob-ani-filter-x { opacity: 1; transform: none; transition: transform 0.35s cubic-bezier(0.3, 1.6, 0.5, 1), opacity 0.1s; }\n.iob-ani-filter-on:hover .iob-ani-filter-x,\n:is(button, a, [role=\"button\"]):is(:hover, :focus-visible) .iob-ani-filter-on .iob-ani-filter-x { transform: rotate(90deg); }\n\n/* Connection */\n.iob-ani-wifi path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; transition: opacity 0.3s; }\n.iob-ani-wifi circle { fill: currentColor; transition: opacity 0.3s; }\n.iob-ani-wifi .iob-ani-wifi-slash { stroke-dasharray: 1 1; stroke-dashoffset: 1; transition: stroke-dashoffset 0.35s cubic-bezier(0.65, 0, 0.35, 1); }\n.iob-ani-wifi-disconnected .iob-ani-wifi-slash { stroke-dashoffset: 0; }\n.iob-ani-wifi-disconnected .iob-ani-wifi-w { opacity: 0.35; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w { animation: iob-ani-wave 1.5s ease-in-out infinite; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w1 { animation-delay: 0.18s; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w2 { animation-delay: 0.36s; }\n.iob-ani-wifi-connecting .iob-ani-wifi-w3 { animation-delay: 0.54s; }\n\n@keyframes iob-ani-spin { to { transform: rotate(360deg); } }\n@keyframes iob-ani-draw { to { stroke-dashoffset: 0; } }\n@keyframes iob-ani-breathe { 50% { opacity: 0.35; } }\n@keyframes iob-ani-wave { 0%, 100% { opacity: 0.25; } 30% { opacity: 1; } }\n@keyframes iob-ani-shake { 20% { transform: translateX(-1.5px); } 40% { transform: translateX(1.5px); } 60% { transform: translateX(-1px); } 80% { transform: translateX(1px); } }\n\n@media (prefers-reduced-motion: reduce) {\n .iob-ani-pp-a, .iob-ani-pp-b, .iob-ani-menu-rot, .iob-ani-menu-bar, .iob-ani-trash-lid, .iob-ani-expert-shape, .iob-ani-folder-front, .iob-ani-folder-closed,\n .iob-ani-theme-disc, .iob-ani-theme-half, .iob-ani-theme-rays, .iob-ani-theme-cut, .iob-ani-up-arrow, .iob-ani-filter-x { transition-duration: 0.01ms !important; transition-delay: 0s !important; }\n .iob-ani-pp-pending .iob-ani-pp-ring { animation: iob-ani-breathe 1.2s ease-in-out infinite; }\n .iob-ani-up-ready .iob-ani-up-arrow, .iob-ani-up-uploading .iob-ani-up-bar { animation: none; }\n .iob-ani-up-uploading .iob-ani-up-arrow { animation: iob-ani-breathe 1.2s ease-in-out infinite; }\n .iob-ani-res svg, .iob-ani-res svg * { animation: none !important; stroke-dashoffset: 0; }\n}\n`;\n\n/** Puts the style sheet of the animated icons into the page, once and before the first paint */\nexport function useAnimatedIconStyles(): void {\n useInsertionEffect(() => {\n if (!window.document.getElementById(STYLE_ID)) {\n const style = window.document.createElement('style');\n style.setAttribute('id', STYLE_ID);\n style.innerHTML = styles;\n window.document.head.appendChild(style);\n }\n }, []);\n}\n\n/** Properties of the root element: class, size and accessibility */\nexport function rootProps(props: AnimatedIconProps, className: string): React.HTMLAttributes<HTMLSpanElement> {\n // Without fontSize the size comes from the style sheet (24 px), so that MUI can change it like for its own icons\n let fontSize: string | number | undefined;\n if (typeof props.fontSize === 'number') {\n fontSize = props.fontSize;\n } else if (props.fontSize) {\n fontSize = SIZES[props.fontSize] || props.fontSize;\n }\n return {\n className: `iob-ani ${className}${props.className ? ` ${props.className}` : ''}`,\n style: fontSize === undefined ? props.style : { fontSize, ...props.style },\n role: props.ariaLabel ? 'img' : undefined,\n 'aria-label': props.ariaLabel,\n 'aria-hidden': props.ariaLabel ? undefined : true,\n };\n}\n\n/** Unique ID for a mask or a clip path of one icon (the IDs of `useId` contain characters like `:` or `«`) */\nexport function useSvgId(name: string): string {\n return `iob-ani-${name}-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`;\n}\n\n/** True if the user asked the system for less motion */\nexport function prefersReducedMotion(): boolean {\n return !!window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n}\n\n/** Plays a one-time animation (Web Animations API), unless the user wants less motion */\nexport function play(\n element: Element | null | undefined,\n keyframes: Keyframe[],\n options: KeyframeAnimationOptions,\n): Animation | null {\n if (!element?.animate || prefersReducedMotion()) {\n return null;\n }\n return element.animate(keyframes, options);\n}\n\n/** Calls `onChange` when `value` changes, but not on the first render */\nexport function useChange<T>(value: T, onChange: (value: T, previous: T) => void): void {\n const previous = useRef(value);\n const callback = useRef(onChange);\n useEffect(() => {\n callback.current = onChange;\n });\n useEffect(() => {\n if (!Object.is(previous.current, value)) {\n const old = previous.current;\n previous.current = value;\n callback.current(value, old);\n }\n }, [value]);\n}\n"]}
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
import React, { Component } from 'react';
|
|
17
17
|
import { RgbaColorPicker, RgbColorPicker } from 'react-colorful';
|
|
18
18
|
import { TextField, Popover, IconButton, Button, Box, Tooltip, MenuItem, Select } from '@mui/material';
|
|
19
|
-
import {
|
|
19
|
+
import { Colorize as IconColorize } from '@mui/icons-material';
|
|
20
|
+
import { IconTrash } from './AnimatedIcons/IconTrash';
|
|
20
21
|
import { I18n } from '../i18n';
|
|
21
22
|
const RECENT_COLORS_KEY = 'iob-color-picker-recent';
|
|
22
23
|
const MAX_RECENT_COLORS = 12;
|
|
@@ -642,7 +643,7 @@ export class ColorPicker extends Component {
|
|
|
642
643
|
React.createElement(Tooltip, { title: I18n.t('ra_Clear color') },
|
|
643
644
|
React.createElement("span", null,
|
|
644
645
|
React.createElement(IconButton, { size: "small", disabled: !textValue, onClick: this.handleClear },
|
|
645
|
-
React.createElement(
|
|
646
|
+
React.createElement(IconTrash, { fontSize: "small" }))))),
|
|
646
647
|
this.renderSwatches(this.props.customPalette || [], I18n.t('ra_Palette')),
|
|
647
648
|
this.renderSwatches(this.props.noRecentColors ? [] : this.state.recentColors, I18n.t('ra_Recently used colors'))));
|
|
648
649
|
}
|
|
@@ -658,7 +659,7 @@ export class ColorPicker extends Component {
|
|
|
658
659
|
mr: textValue ? undefined : 1,
|
|
659
660
|
}, onChange: e => this.handleTextChange(e.target.value) })),
|
|
660
661
|
!this.props.noInputField && textValue ? (React.createElement(IconButton, { disabled: this.props.disabled, onClick: this.handleClear, size: "small", style: hasLabel ? styles.delButton : undefined },
|
|
661
|
-
React.createElement(
|
|
662
|
+
React.createElement(IconTrash, null))) : null,
|
|
662
663
|
React.createElement(Box, { component: "div", onClick: e => !this.props.disabled && this.handleClick(e), title: I18n.t('ra_Select color'), sx: {
|
|
663
664
|
...styles.swatch,
|
|
664
665
|
...(this.props.disabled ? styles.swatchDisabled : undefined),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPicker.js","sourceRoot":"./src/","sources":["Components/ColorPicker.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright 2018-2026 Denis Haev (bluefox) <dogafox@gmail.com>\n *\n * Licensed under the Creative Commons Attribution-NonCommercial License, Version 4.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://creativecommons.org/licenses/by-nc/4.0/legalcode.txt\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { Component, type CSSProperties } from 'react';\nimport { RgbaColorPicker, RgbColorPicker, type RgbaColor } from 'react-colorful';\n\nimport { TextField, Popover, IconButton, Button, Box, Tooltip, MenuItem, Select } from '@mui/material';\n\nimport { Delete as IconDelete, Colorize as IconColorize } from '@mui/icons-material';\n\nimport { I18n } from '../i18n';\n\nimport type { IobTheme } from '../types';\n\n/** Color in the `{ r, g, b, a }` notation. Kept for backwards compatibility with `react-color`. */\nexport interface RGBColor {\n r: number;\n g: number;\n b: number;\n a?: number;\n}\n\n/** Notation used for the value that is reported via `onChange`. */\nexport type ColorPickerFormat = 'hex' | 'rgb' | 'hsl';\n\nconst RECENT_COLORS_KEY = 'iob-color-picker-recent';\nconst MAX_RECENT_COLORS = 12;\n\n/** Small checkerboard, so a semi-transparent color is recognizable as such */\nconst ALPHA_BACKGROUND =\n 'linear-gradient(45deg, #c0c0c0 25%, transparent 25%), linear-gradient(-45deg, #c0c0c0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #c0c0c0 75%), linear-gradient(-45deg, transparent 75%, #c0c0c0 75%)';\n\nconst ALPHA_BACKGROUND_SIZE = '8px 8px';\nconst ALPHA_BACKGROUND_POSITION = '0 0, 0 4px, 4px -4px, -4px 0px';\n\nconst styles: Record<string, any> = {\n swatch: {\n mt: '16px',\n p: '4px',\n backgroundColor: 'background.paper',\n borderRadius: '6px',\n boxShadow: '0 0 0 1px rgba(128,128,128,.35)',\n display: 'inline-block',\n cursor: 'pointer',\n verticalAlign: 'middle',\n transition: 'box-shadow 0.15s ease-in-out',\n '&:hover': {\n boxShadow: '0 0 0 2px rgba(128,128,128,.6)',\n },\n },\n swatchDisabled: {\n opacity: 0.5,\n cursor: 'default',\n '&:hover': {\n boxShadow: '0 0 0 1px rgba(128,128,128,.35)',\n },\n },\n color: {\n height: 14,\n borderRadius: '3px',\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n },\n delButton: {\n marginTop: 16,\n },\n textDense: {\n mt: 0,\n mb: 0,\n },\n popover: {\n '& .MuiPaper-root': {\n borderRadius: '12px',\n },\n },\n // The chrome around the react-colorful area\n pickerWrapper: (theme: IobTheme) => ({\n p: '12px',\n backgroundColor: theme.palette.background.paper,\n borderRadius: '12px',\n display: 'flex',\n flexDirection: 'column',\n gap: '10px',\n // restyle react-colorful, so it fits into the ioBroker themes\n '& .react-colorful': {\n width: '100%',\n height: 'auto',\n gap: '10px',\n },\n '& .react-colorful__saturation': {\n borderRadius: '8px',\n border: 'none',\n height: 150,\n boxShadow: 'none',\n },\n '& .react-colorful__hue, & .react-colorful__alpha': {\n height: 14,\n borderRadius: '7px',\n },\n '& .react-colorful__alpha': {\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n },\n '& .react-colorful__last-control': {\n borderRadius: '7px',\n },\n '& .react-colorful__pointer': {\n width: 18,\n height: 18,\n borderWidth: 2,\n },\n '& .react-colorful__saturation-pointer': {\n width: 20,\n height: 20,\n },\n }),\n controlRow: {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n },\n preview: {\n width: 28,\n height: 28,\n flexShrink: 0,\n borderRadius: '6px',\n boxShadow: '0 0 0 1px rgba(128,128,128,.35) inset',\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n },\n valueInput: {\n flexGrow: 1,\n minWidth: 60,\n '& .MuiInputBase-input': {\n fontFamily: 'monospace',\n fontSize: '0.75rem',\n textOverflow: 'ellipsis',\n },\n },\n formatSelect: {\n flexShrink: 0,\n fontSize: '0.7rem',\n opacity: 0.75,\n '& .MuiSelect-select': {\n py: '4px',\n pl: '2px',\n pr: '18px !important',\n },\n '& .MuiSelect-icon': {\n right: 0,\n },\n },\n sectionTitle: {\n fontSize: '0.7rem',\n opacity: 0.6,\n textTransform: 'uppercase',\n letterSpacing: '0.06em',\n },\n swatchRow: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '4px',\n mt: '4px',\n },\n paletteItem: {\n width: 22,\n height: 22,\n p: 0,\n minWidth: 22,\n borderRadius: '5px',\n boxShadow: '0 0 0 1px rgba(128,128,128,.35) inset',\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n '&:hover': {\n boxShadow: '0 0 0 2px rgba(128,128,128,.7) inset',\n },\n },\n fill: {\n width: '100%',\n height: '100%',\n borderRadius: 'inherit',\n },\n};\n\nconst DEFAULT_COLOR: RgbaColor = { r: 0, g: 0, b: 0, a: 1 };\n\nlet canvasContext: CanvasRenderingContext2D | null | undefined;\n\n/**\n * Normalize any CSS color notation (color names, `color()`, ...) with the help of a canvas.\n *\n * @param color The color string to normalize.\n * @returns the normalized color as `#rrggbb`/`rgba(...)` string or null if the string is no valid color.\n */\nfunction normalizeCssColor(color: string): string | null {\n if (canvasContext === undefined) {\n canvasContext = typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d');\n }\n if (!canvasContext) {\n return null;\n }\n // `fillStyle` keeps its previous value if the assigned string is no valid color,\n // so it must be probed with two different defaults\n canvasContext.fillStyle = '#000000';\n canvasContext.fillStyle = color;\n const first = canvasContext.fillStyle;\n canvasContext.fillStyle = '#ffffff';\n canvasContext.fillStyle = color;\n\n return first === canvasContext.fillStyle ? first : null;\n}\n\n/**\n * Convert h, s, l (0..1) to r, g, b (0..255).\n *\n * @param h The hue in the range 0..1.\n * @param s The saturation in the range 0..1.\n * @param l The lightness in the range 0..1.\n */\nfunction hsl2rgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n if (!s) {\n const v = Math.round(l * 255);\n return { r: v, g: v, b: v };\n }\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n let _t = t;\n if (_t < 0) {\n _t += 1;\n }\n if (_t > 1) {\n _t -= 1;\n }\n if (_t < 1 / 6) {\n return p + (q - p) * 6 * _t;\n }\n if (_t < 1 / 2) {\n return q;\n }\n if (_t < 2 / 3) {\n return p + (q - p) * (2 / 3 - _t) * 6;\n }\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n return {\n r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hue2rgb(p, q, h) * 255),\n b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),\n };\n}\n\n/**\n * Convert r, g, b (0..255) to h (0..360), s, l (0..100).\n *\n * @param color The color to convert.\n */\nfunction rgb2hsl(color: RgbaColor): { h: number; s: number; l: number } {\n const r = color.r / 255;\n const g = color.g / 255;\n const b = color.b / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l: Math.round(l * 100) };\n }\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n let h: number;\n if (max === r) {\n h = (g - b) / d + (g < b ? 6 : 0);\n } else if (max === g) {\n h = (b - r) / d + 2;\n } else {\n h = (r - g) / d + 4;\n }\n\n return { h: Math.round((h / 6) * 360), s: Math.round(s * 100), l: Math.round(l * 100) };\n}\n\n/**\n * Clamp a number into the given range.\n *\n * @param value The value to clamp.\n * @param min The lower limit.\n * @param max The upper limit.\n */\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n/**\n * Read a color channel that may be given as `128` or as `50%`.\n *\n * @param value The channel as string.\n * @param max The maximal value of this channel.\n */\nfunction readChannel(value: string, max: number): number {\n const trimmed = value.trim();\n const parsed = parseFloat(trimmed);\n if (Number.isNaN(parsed)) {\n return 0;\n }\n return clamp(Math.round(trimmed.endsWith('%') ? (parsed / 100) * max : parsed), 0, max);\n}\n\n/**\n * Read the alpha channel that may be given as `0.5` or as `50%`.\n *\n * @param value The alpha channel as string or undefined if it is not given.\n */\nfunction readAlpha(value: string | undefined): number {\n if (value === undefined || value === '') {\n return 1;\n }\n const trimmed = value.trim();\n const parsed = trimmed.endsWith('%') ? parseFloat(trimmed) / 100 : parseFloat(trimmed);\n\n return Number.isNaN(parsed) ? 1 : clamp(parsed, 0, 1);\n}\n\n/**\n * Parse any CSS color notation into `{ r, g, b, a }`.\n *\n * Supported are `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, `rgb()`, `rgba()`, `hsl()`, `hsla()` (comma or space\n * separated, with or without the `/ alpha` part) and every color name the browser knows.\n *\n * @param color The color string to parse.\n * @returns the parsed color or null if the string could not be interpreted.\n */\nexport function parseColor(color: string): RgbaColor | null {\n if (!color || typeof color !== 'string') {\n return null;\n }\n const str = color.trim().toLowerCase();\n if (!str) {\n return null;\n }\n if (str === 'transparent') {\n return { r: 0, g: 0, b: 0, a: 0 };\n }\n\n const hex = /^#([\\da-f]{3,8})$/.exec(str);\n if (hex) {\n const h = hex[1];\n if (h.length === 3 || h.length === 4) {\n return {\n r: parseInt(h[0] + h[0], 16),\n g: parseInt(h[1] + h[1], 16),\n b: parseInt(h[2] + h[2], 16),\n a: h.length === 4 ? Math.round((parseInt(h[3] + h[3], 16) / 255) * 100) / 100 : 1,\n };\n }\n if (h.length === 6 || h.length === 8) {\n return {\n r: parseInt(h.substring(0, 2), 16),\n g: parseInt(h.substring(2, 4), 16),\n b: parseInt(h.substring(4, 6), 16),\n a: h.length === 8 ? Math.round((parseInt(h.substring(6, 8), 16) / 255) * 100) / 100 : 1,\n };\n }\n return null;\n }\n\n const func = /^(rgba?|hsla?)\\(([^)]*)\\)$/.exec(str);\n if (func) {\n // both `1, 2, 3, 0.5` and `1 2 3 / 50%` are valid\n const parts = func[2]\n .replace('/', ',')\n .split(/[\\s,]+/)\n .filter(part => part !== '');\n\n if (parts.length < 3) {\n return null;\n }\n if (func[1].startsWith('rgb')) {\n return {\n r: readChannel(parts[0], 255),\n g: readChannel(parts[1], 255),\n b: readChannel(parts[2], 255),\n a: readAlpha(parts[3]),\n };\n }\n const hue = ((parseFloat(parts[0]) % 360) + 360) % 360;\n const rgb = hsl2rgb(\n hue / 360,\n clamp(parseFloat(parts[1]) / 100, 0, 1),\n clamp(parseFloat(parts[2]) / 100, 0, 1),\n );\n\n return { ...rgb, a: readAlpha(parts[3]) };\n }\n\n // color names and everything else the browser understands\n const normalized = normalizeCssColor(str);\n\n return normalized && normalized !== str ? parseColor(normalized) : null;\n}\n\n/**\n * Render `{ r, g, b, a }` in the requested notation.\n *\n * @param color The color to render.\n * @param format The desired notation.\n * @param noAlpha If true, the alpha channel is dropped.\n * @returns the color as CSS string.\n */\nexport function formatColor(color: RgbaColor, format: ColorPickerFormat, noAlpha?: boolean): string {\n const alpha = noAlpha ? 1 : (color.a ?? 1);\n const opaque = alpha >= 1;\n const rounded = Math.round(alpha * 100) / 100;\n\n if (format === 'hex') {\n const hex = `#${color.r.toString(16).padStart(2, '0')}${color.g.toString(16).padStart(2, '0')}${color.b.toString(16).padStart(2, '0')}`;\n const hexAlpha = Math.round(alpha * 255)\n .toString(16)\n .padStart(2, '0');\n\n return opaque ? hex : `${hex}${hexAlpha}`;\n }\n if (format === 'hsl') {\n const { h, s, l } = rgb2hsl(color);\n\n return opaque ? `hsl(${h}, ${s}%, ${l}%)` : `hsla(${h}, ${s}%, ${l}%, ${rounded})`;\n }\n\n return opaque ? `rgb(${color.r}, ${color.g}, ${color.b})` : `rgba(${color.r}, ${color.g}, ${color.b}, ${rounded})`;\n}\n\n/**\n * Guess the notation of the given color string.\n *\n * @param color The color string.\n */\nfunction detectFormat(color: string): ColorPickerFormat | null {\n const str = (color || '').trim().toLowerCase();\n if (str.startsWith('#')) {\n return 'hex';\n }\n if (str.startsWith('rgb')) {\n return 'rgb';\n }\n if (str.startsWith('hsl')) {\n return 'hsl';\n }\n return null;\n}\n\ninterface EyeDropperInstance {\n open: (options?: { signal?: AbortSignal }) => Promise<{ sRGBHex: string }>;\n}\n\n/**\n * Read the `EyeDropper` constructor, which is not part of the DOM types yet.\n */\nfunction getEyeDropper(): (new () => EyeDropperInstance) | undefined {\n if (typeof window === 'undefined') {\n return undefined;\n }\n return (window as unknown as Record<string, unknown>).EyeDropper as (new () => EyeDropperInstance) | undefined;\n}\n\ninterface ColorPickerProps {\n /** Set to true to disable the color picker. */\n disabled?: boolean;\n /** The currently selected color. */\n value?: string;\n /** @deprecated The currently selected color use value */\n color?: string;\n /** The color change callback. */\n onChange: (rgba: string) => void;\n /** Label of the color picker. */\n label?: string;\n /** @deprecated TLabel of the color picker use label */\n name?: string;\n /** Additional styling for this component. */\n style?: CSSProperties;\n /** The CSS class name. */\n className?: string;\n /** Predefined colors that are offered below the picker. */\n customPalette?: string[];\n /** Do not show the text field with the color value, only the color bar. */\n noInputField?: boolean;\n /** Width of the color bar. */\n barWidth?: number;\n sx?: Record<string, any>;\n /** @deprecated the theme is taken from the MUI context */\n theme?: IobTheme;\n /** Hide the alpha slider and always report a fully opaque color. */\n noAlpha?: boolean;\n /** Notation of the reported value. If not set, it is taken from the incoming value and defaults to `rgb`. */\n format?: ColorPickerFormat;\n /** Do not offer the recently used colors. */\n noRecentColors?: boolean;\n /** Width of the picker popup in pixels. Default 280. */\n pickerWidth?: number;\n /** ID of the text field. Must be set if more than one color picker is rendered at the same time. */\n id?: string;\n}\n\ninterface ColorPickerState {\n displayColorPicker: boolean;\n /** The working color of the picker. Always valid, even if no color is selected. */\n rgba: RgbaColor;\n /** The text shown in the input field. An empty string means \"no color selected\". */\n textValue: string;\n format: ColorPickerFormat;\n anchorEl: HTMLDivElement | null;\n recentColors: string[];\n}\n\n/**\n * A color picker component with alpha channel, eye dropper and HEX/RGB/HSL notations.\n */\nexport class ColorPicker extends Component<ColorPickerProps, ColorPickerState> {\n /**\n * Constructor for the color picker.\n *\n * @param props The properties.\n */\n constructor(props: ColorPickerProps) {\n super(props);\n const value = props.value || props.color || '';\n\n this.state = {\n displayColorPicker: false,\n rgba: parseColor(value) || { ...DEFAULT_COLOR },\n textValue: value,\n format: props.format || detectFormat(value) || 'rgb',\n anchorEl: null,\n recentColors: [],\n };\n }\n\n /**\n * If the props are updated from outside, they should override the state\n *\n * @param prevProps The previous properties.\n */\n componentDidUpdate(prevProps: ColorPickerProps): void {\n const prevValue = prevProps.value ?? prevProps.color ?? '';\n const value = this.props.value ?? this.props.color ?? '';\n\n // React only on real changes from outside. If the value equals what is shown, it is the own echo.\n if (prevValue !== value && value !== this.state.textValue) {\n this.setState({\n rgba: parseColor(value) || { ...DEFAULT_COLOR },\n textValue: value,\n format: this.props.format || detectFormat(value) || this.state.format,\n });\n } else if (this.props.format && this.props.format !== prevProps.format) {\n this.setState({ format: this.props.format });\n }\n }\n\n /**\n * Convert the given color to hex ('#rrggbb') or rgba ('rgba(r,g,b,a)') format.\n *\n * @param color The color to convert.\n * @param isHex If true, the color will be converted to hex format.\n * @returns the hex or rgba representation of the given color.\n */\n static getColor(color: string | { rgb: RGBColor } | RGBColor, isHex?: boolean): string {\n if (color && typeof color === 'object') {\n const oColor = color as { rgb: RGBColor };\n const rColor: RGBColor = oColor.rgb ? oColor.rgb : (color as RGBColor);\n\n if (isHex) {\n return `#${rColor.r.toString(16).padStart(2, '0')}${rColor.g.toString(16).padStart(2, '0')}${rColor.b.toString(16).padStart(2, '0')}`;\n }\n return `rgba(${rColor.r},${rColor.g},${rColor.b},${rColor.a ?? 1})`;\n }\n if (typeof color === 'string') {\n return isHex ? ColorPicker.rgb2hex(color || '') : color || '';\n }\n return '';\n }\n\n /**\n * Convert rgb() or rgba() format to hex format #rrggbb.\n *\n * @param rgb The color in rgb() or rgba() format. if not in this format, the color will be returned as is.\n */\n static rgb2hex(rgb: string): string {\n const m = /^rgba?[\\s+]?\\([\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?/i.exec(rgb);\n\n if (m) {\n const r = parseInt(m[1], 10).toString(16).padStart(2, '0');\n const g = parseInt(m[2], 10).toString(16).padStart(2, '0');\n const b = parseInt(m[3], 10).toString(16).padStart(2, '0');\n\n return m?.length === 4 ? `#${r}${g}${b}` : rgb;\n }\n return rgb;\n }\n\n /**\n * Read the recently used colors from the local storage.\n */\n static readRecentColors(): string[] {\n try {\n const stored = window.localStorage.getItem(RECENT_COLORS_KEY);\n const parsed: unknown = stored ? JSON.parse(stored) : null;\n\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === 'string').slice(0, MAX_RECENT_COLORS);\n }\n } catch {\n // ignore a broken or unavailable local storage\n }\n return [];\n }\n\n /**\n * Remember the given color as recently used.\n *\n * @param color The color to remember.\n */\n storeRecentColor(color: string): void {\n if (this.props.noRecentColors || !color || this.state.recentColors[0] === color) {\n return;\n }\n const recentColors = [color, ...this.state.recentColors.filter(item => item !== color)].slice(\n 0,\n MAX_RECENT_COLORS,\n );\n\n this.setState({ recentColors });\n\n try {\n window.localStorage.setItem(RECENT_COLORS_KEY, JSON.stringify(recentColors));\n } catch {\n // ignore an unavailable local storage\n }\n }\n\n private handleClick = (e: React.MouseEvent<HTMLDivElement>): void => {\n const open = !this.state.displayColorPicker;\n\n this.setState({\n displayColorPicker: open,\n anchorEl: open ? e.currentTarget : null,\n // read the recent colors on every open, so colors picked in another instance show up too\n recentColors: open && !this.props.noRecentColors ? ColorPicker.readRecentColors() : this.state.recentColors,\n });\n };\n\n private handleClose = (): void => {\n this.storeRecentColor(this.state.textValue);\n this.setState({ displayColorPicker: false, anchorEl: null });\n };\n\n /**\n * The user moved a slider, clicked a swatch or used the eye dropper.\n *\n * @param rgba The new color.\n */\n private handleColorChange = (rgba: RgbaColor): void => {\n const textValue = formatColor(rgba, this.state.format, this.props.noAlpha);\n\n this.setState({ rgba, textValue }, () => this.props.onChange?.(textValue));\n };\n\n /**\n * The user typed into the input field. The text is taken as it is and only parsed for the preview.\n *\n * @param textValue The entered text.\n */\n private handleTextChange = (textValue: string): void => {\n const rgba = parseColor(textValue);\n\n this.setState({ textValue, rgba: rgba || this.state.rgba }, () => this.props.onChange?.(textValue));\n };\n\n /**\n * Switch between the #rrggbb, rgba() and hsla() notations.\n *\n * @param format The new notation.\n */\n private handleFormatChange = (format: ColorPickerFormat): void => {\n if (!this.state.textValue) {\n this.setState({ format });\n return;\n }\n const textValue = formatColor(this.state.rgba, format, this.props.noAlpha);\n\n this.setState({ format, textValue }, () => this.props.onChange?.(textValue));\n };\n\n private handleClear = (): void => {\n this.setState({ textValue: '', rgba: { ...DEFAULT_COLOR } }, () => this.props.onChange?.(''));\n };\n\n private handleEyeDropper = (): void => {\n const EyeDropper = getEyeDropper();\n if (!EyeDropper) {\n return;\n }\n\n void new EyeDropper()\n .open()\n .then(result => {\n const rgba = parseColor(result.sRGBHex);\n if (rgba) {\n // the eye dropper always returns an opaque color, so the current alpha is kept\n this.handleColorChange({ ...rgba, a: this.props.noAlpha ? 1 : (this.state.rgba.a ?? 1) });\n }\n })\n .catch(() => {\n // the user aborted the selection with ESC\n });\n };\n\n /**\n * Render a row of predefined colors.\n *\n * @param colors The colors to show.\n * @param title The title above the row.\n */\n renderSwatches(colors: string[], title: string): React.JSX.Element | null {\n if (!colors.length) {\n return null;\n }\n return (\n <Box component=\"div\">\n <Box\n component=\"div\"\n sx={styles.sectionTitle}\n >\n {title}\n </Box>\n <Box\n component=\"div\"\n sx={styles.swatchRow}\n >\n {colors.map((color, i) => (\n <Button\n sx={styles.paletteItem}\n key={`${color}_${i}`}\n title={color}\n onClick={() => {\n const rgba = parseColor(color);\n if (rgba) {\n this.handleColorChange(rgba);\n } else {\n this.handleTextChange(color);\n }\n }}\n >\n <Box\n component=\"div\"\n sx={styles.fill}\n style={{ background: color }}\n />\n </Button>\n ))}\n </Box>\n </Box>\n );\n }\n\n renderPicker(): React.JSX.Element {\n const { rgba, textValue, format } = this.state;\n const Picker = this.props.noAlpha ? RgbColorPicker : RgbaColorPicker;\n\n return (\n <Box\n component=\"div\"\n sx={styles.pickerWrapper}\n style={{ width: this.props.pickerWidth || 280 }}\n >\n <Picker\n color={rgba}\n onChange={(color: RgbaColor | { r: number; g: number; b: number }) =>\n this.handleColorChange({ a: rgba.a ?? 1, ...color })\n }\n />\n <Box\n component=\"div\"\n sx={styles.controlRow}\n >\n {getEyeDropper() ? (\n <Tooltip title={I18n.t('ra_Pick color from screen')}>\n <IconButton\n size=\"small\"\n onClick={this.handleEyeDropper}\n >\n <IconColorize fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n ) : null}\n <Box\n component=\"div\"\n sx={styles.preview}\n >\n <Box\n component=\"div\"\n sx={styles.fill}\n style={{ background: textValue || 'transparent' }}\n />\n </Box>\n <TextField\n variant=\"standard\"\n size=\"small\"\n sx={styles.valueInput}\n value={textValue}\n placeholder={I18n.t('ra_Select color')}\n onChange={e => this.handleTextChange(e.target.value)}\n />\n <Select\n variant=\"standard\"\n disableUnderline\n sx={styles.formatSelect}\n value={format}\n onChange={e => this.handleFormatChange(e.target.value)}\n >\n <MenuItem value=\"hex\">HEX</MenuItem>\n <MenuItem value=\"rgb\">RGB</MenuItem>\n <MenuItem value=\"hsl\">HSL</MenuItem>\n </Select>\n <Tooltip title={I18n.t('ra_Clear color')}>\n <span>\n <IconButton\n size=\"small\"\n disabled={!textValue}\n onClick={this.handleClear}\n >\n <IconDelete fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n </Box>\n {this.renderSwatches(this.props.customPalette || [], I18n.t('ra_Palette'))}\n {this.renderSwatches(\n this.props.noRecentColors ? [] : this.state.recentColors,\n I18n.t('ra_Recently used colors'),\n )}\n </Box>\n );\n }\n\n render(): React.JSX.Element {\n const style = { ...(this.props.style || {}) };\n style.position = 'relative';\n const { textValue } = this.state;\n const hasLabel = !!(this.props.label || this.props.name);\n\n return (\n <Box\n component=\"div\"\n style={style}\n sx={this.props.sx || undefined}\n className={this.props.className || ''}\n >\n {this.props.noInputField ? null : (\n <TextField\n disabled={this.props.disabled}\n variant=\"standard\"\n id={this.props.id || 'ar_color_picker_name'}\n label={this.props.label || this.props.name}\n value={textValue}\n margin=\"dense\"\n sx={{\n '&.MuiFormControl-root': styles.textDense,\n width: textValue ? 'calc(100% - 80px)' : 'calc(100% - 56px)',\n mr: textValue ? undefined : 1,\n }}\n onChange={e => this.handleTextChange(e.target.value)}\n />\n )}\n {!this.props.noInputField && textValue ? (\n <IconButton\n disabled={this.props.disabled}\n onClick={this.handleClear}\n size=\"small\"\n style={hasLabel ? styles.delButton : undefined}\n >\n <IconDelete />\n </IconButton>\n ) : null}\n <Box\n component=\"div\"\n onClick={e => !this.props.disabled && this.handleClick(e)}\n title={I18n.t('ra_Select color')}\n sx={{\n ...styles.swatch,\n ...(this.props.disabled ? styles.swatchDisabled : undefined),\n marginTop: this.props.noInputField || !hasLabel ? 0 : undefined,\n }}\n >\n <Box\n component=\"div\"\n sx={{\n ...styles.color,\n border: textValue ? undefined : '1px dashed #888',\n boxSizing: 'border-box',\n }}\n style={{\n width: this.props.noInputField ? this.props.barWidth || 16 : this.props.barWidth || 36,\n }}\n >\n <Box\n component=\"div\"\n sx={styles.fill}\n style={{ background: textValue || 'transparent' }}\n />\n </Box>\n </Box>\n {this.state.displayColorPicker && !this.props.disabled ? (\n <Popover\n sx={styles.popover}\n anchorEl={this.state.anchorEl}\n open={!0}\n onClose={this.handleClose}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n >\n {this.renderPicker()}\n </Popover>\n ) : null}\n </Box>\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ColorPicker.js","sourceRoot":"./src/","sources":["Components/ColorPicker.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright 2018-2026 Denis Haev (bluefox) <dogafox@gmail.com>\n *\n * Licensed under the Creative Commons Attribution-NonCommercial License, Version 4.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://creativecommons.org/licenses/by-nc/4.0/legalcode.txt\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { Component, type CSSProperties } from 'react';\nimport { RgbaColorPicker, RgbColorPicker, type RgbaColor } from 'react-colorful';\n\nimport { TextField, Popover, IconButton, Button, Box, Tooltip, MenuItem, Select } from '@mui/material';\n\nimport { Colorize as IconColorize } from '@mui/icons-material';\nimport { IconTrash } from './AnimatedIcons/IconTrash';\n\nimport { I18n } from '../i18n';\n\nimport type { IobTheme } from '../types';\n\n/** Color in the `{ r, g, b, a }` notation. Kept for backwards compatibility with `react-color`. */\nexport interface RGBColor {\n r: number;\n g: number;\n b: number;\n a?: number;\n}\n\n/** Notation used for the value that is reported via `onChange`. */\nexport type ColorPickerFormat = 'hex' | 'rgb' | 'hsl';\n\nconst RECENT_COLORS_KEY = 'iob-color-picker-recent';\nconst MAX_RECENT_COLORS = 12;\n\n/** Small checkerboard, so a semi-transparent color is recognizable as such */\nconst ALPHA_BACKGROUND =\n 'linear-gradient(45deg, #c0c0c0 25%, transparent 25%), linear-gradient(-45deg, #c0c0c0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #c0c0c0 75%), linear-gradient(-45deg, transparent 75%, #c0c0c0 75%)';\n\nconst ALPHA_BACKGROUND_SIZE = '8px 8px';\nconst ALPHA_BACKGROUND_POSITION = '0 0, 0 4px, 4px -4px, -4px 0px';\n\nconst styles: Record<string, any> = {\n swatch: {\n mt: '16px',\n p: '4px',\n backgroundColor: 'background.paper',\n borderRadius: '6px',\n boxShadow: '0 0 0 1px rgba(128,128,128,.35)',\n display: 'inline-block',\n cursor: 'pointer',\n verticalAlign: 'middle',\n transition: 'box-shadow 0.15s ease-in-out',\n '&:hover': {\n boxShadow: '0 0 0 2px rgba(128,128,128,.6)',\n },\n },\n swatchDisabled: {\n opacity: 0.5,\n cursor: 'default',\n '&:hover': {\n boxShadow: '0 0 0 1px rgba(128,128,128,.35)',\n },\n },\n color: {\n height: 14,\n borderRadius: '3px',\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n },\n delButton: {\n marginTop: 16,\n },\n textDense: {\n mt: 0,\n mb: 0,\n },\n popover: {\n '& .MuiPaper-root': {\n borderRadius: '12px',\n },\n },\n // The chrome around the react-colorful area\n pickerWrapper: (theme: IobTheme) => ({\n p: '12px',\n backgroundColor: theme.palette.background.paper,\n borderRadius: '12px',\n display: 'flex',\n flexDirection: 'column',\n gap: '10px',\n // restyle react-colorful, so it fits into the ioBroker themes\n '& .react-colorful': {\n width: '100%',\n height: 'auto',\n gap: '10px',\n },\n '& .react-colorful__saturation': {\n borderRadius: '8px',\n border: 'none',\n height: 150,\n boxShadow: 'none',\n },\n '& .react-colorful__hue, & .react-colorful__alpha': {\n height: 14,\n borderRadius: '7px',\n },\n '& .react-colorful__alpha': {\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n },\n '& .react-colorful__last-control': {\n borderRadius: '7px',\n },\n '& .react-colorful__pointer': {\n width: 18,\n height: 18,\n borderWidth: 2,\n },\n '& .react-colorful__saturation-pointer': {\n width: 20,\n height: 20,\n },\n }),\n controlRow: {\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n },\n preview: {\n width: 28,\n height: 28,\n flexShrink: 0,\n borderRadius: '6px',\n boxShadow: '0 0 0 1px rgba(128,128,128,.35) inset',\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n },\n valueInput: {\n flexGrow: 1,\n minWidth: 60,\n '& .MuiInputBase-input': {\n fontFamily: 'monospace',\n fontSize: '0.75rem',\n textOverflow: 'ellipsis',\n },\n },\n formatSelect: {\n flexShrink: 0,\n fontSize: '0.7rem',\n opacity: 0.75,\n '& .MuiSelect-select': {\n py: '4px',\n pl: '2px',\n pr: '18px !important',\n },\n '& .MuiSelect-icon': {\n right: 0,\n },\n },\n sectionTitle: {\n fontSize: '0.7rem',\n opacity: 0.6,\n textTransform: 'uppercase',\n letterSpacing: '0.06em',\n },\n swatchRow: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '4px',\n mt: '4px',\n },\n paletteItem: {\n width: 22,\n height: 22,\n p: 0,\n minWidth: 22,\n borderRadius: '5px',\n boxShadow: '0 0 0 1px rgba(128,128,128,.35) inset',\n backgroundImage: ALPHA_BACKGROUND,\n backgroundSize: ALPHA_BACKGROUND_SIZE,\n backgroundPosition: ALPHA_BACKGROUND_POSITION,\n '&:hover': {\n boxShadow: '0 0 0 2px rgba(128,128,128,.7) inset',\n },\n },\n fill: {\n width: '100%',\n height: '100%',\n borderRadius: 'inherit',\n },\n};\n\nconst DEFAULT_COLOR: RgbaColor = { r: 0, g: 0, b: 0, a: 1 };\n\nlet canvasContext: CanvasRenderingContext2D | null | undefined;\n\n/**\n * Normalize any CSS color notation (color names, `color()`, ...) with the help of a canvas.\n *\n * @param color The color string to normalize.\n * @returns the normalized color as `#rrggbb`/`rgba(...)` string or null if the string is no valid color.\n */\nfunction normalizeCssColor(color: string): string | null {\n if (canvasContext === undefined) {\n canvasContext = typeof document === 'undefined' ? null : document.createElement('canvas').getContext('2d');\n }\n if (!canvasContext) {\n return null;\n }\n // `fillStyle` keeps its previous value if the assigned string is no valid color,\n // so it must be probed with two different defaults\n canvasContext.fillStyle = '#000000';\n canvasContext.fillStyle = color;\n const first = canvasContext.fillStyle;\n canvasContext.fillStyle = '#ffffff';\n canvasContext.fillStyle = color;\n\n return first === canvasContext.fillStyle ? first : null;\n}\n\n/**\n * Convert h, s, l (0..1) to r, g, b (0..255).\n *\n * @param h The hue in the range 0..1.\n * @param s The saturation in the range 0..1.\n * @param l The lightness in the range 0..1.\n */\nfunction hsl2rgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n if (!s) {\n const v = Math.round(l * 255);\n return { r: v, g: v, b: v };\n }\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n let _t = t;\n if (_t < 0) {\n _t += 1;\n }\n if (_t > 1) {\n _t -= 1;\n }\n if (_t < 1 / 6) {\n return p + (q - p) * 6 * _t;\n }\n if (_t < 1 / 2) {\n return q;\n }\n if (_t < 2 / 3) {\n return p + (q - p) * (2 / 3 - _t) * 6;\n }\n return p;\n };\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n\n return {\n r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hue2rgb(p, q, h) * 255),\n b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),\n };\n}\n\n/**\n * Convert r, g, b (0..255) to h (0..360), s, l (0..100).\n *\n * @param color The color to convert.\n */\nfunction rgb2hsl(color: RgbaColor): { h: number; s: number; l: number } {\n const r = color.r / 255;\n const g = color.g / 255;\n const b = color.b / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n\n if (max === min) {\n return { h: 0, s: 0, l: Math.round(l * 100) };\n }\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n let h: number;\n if (max === r) {\n h = (g - b) / d + (g < b ? 6 : 0);\n } else if (max === g) {\n h = (b - r) / d + 2;\n } else {\n h = (r - g) / d + 4;\n }\n\n return { h: Math.round((h / 6) * 360), s: Math.round(s * 100), l: Math.round(l * 100) };\n}\n\n/**\n * Clamp a number into the given range.\n *\n * @param value The value to clamp.\n * @param min The lower limit.\n * @param max The upper limit.\n */\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n/**\n * Read a color channel that may be given as `128` or as `50%`.\n *\n * @param value The channel as string.\n * @param max The maximal value of this channel.\n */\nfunction readChannel(value: string, max: number): number {\n const trimmed = value.trim();\n const parsed = parseFloat(trimmed);\n if (Number.isNaN(parsed)) {\n return 0;\n }\n return clamp(Math.round(trimmed.endsWith('%') ? (parsed / 100) * max : parsed), 0, max);\n}\n\n/**\n * Read the alpha channel that may be given as `0.5` or as `50%`.\n *\n * @param value The alpha channel as string or undefined if it is not given.\n */\nfunction readAlpha(value: string | undefined): number {\n if (value === undefined || value === '') {\n return 1;\n }\n const trimmed = value.trim();\n const parsed = trimmed.endsWith('%') ? parseFloat(trimmed) / 100 : parseFloat(trimmed);\n\n return Number.isNaN(parsed) ? 1 : clamp(parsed, 0, 1);\n}\n\n/**\n * Parse any CSS color notation into `{ r, g, b, a }`.\n *\n * Supported are `#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`, `rgb()`, `rgba()`, `hsl()`, `hsla()` (comma or space\n * separated, with or without the `/ alpha` part) and every color name the browser knows.\n *\n * @param color The color string to parse.\n * @returns the parsed color or null if the string could not be interpreted.\n */\nexport function parseColor(color: string): RgbaColor | null {\n if (!color || typeof color !== 'string') {\n return null;\n }\n const str = color.trim().toLowerCase();\n if (!str) {\n return null;\n }\n if (str === 'transparent') {\n return { r: 0, g: 0, b: 0, a: 0 };\n }\n\n const hex = /^#([\\da-f]{3,8})$/.exec(str);\n if (hex) {\n const h = hex[1];\n if (h.length === 3 || h.length === 4) {\n return {\n r: parseInt(h[0] + h[0], 16),\n g: parseInt(h[1] + h[1], 16),\n b: parseInt(h[2] + h[2], 16),\n a: h.length === 4 ? Math.round((parseInt(h[3] + h[3], 16) / 255) * 100) / 100 : 1,\n };\n }\n if (h.length === 6 || h.length === 8) {\n return {\n r: parseInt(h.substring(0, 2), 16),\n g: parseInt(h.substring(2, 4), 16),\n b: parseInt(h.substring(4, 6), 16),\n a: h.length === 8 ? Math.round((parseInt(h.substring(6, 8), 16) / 255) * 100) / 100 : 1,\n };\n }\n return null;\n }\n\n const func = /^(rgba?|hsla?)\\(([^)]*)\\)$/.exec(str);\n if (func) {\n // both `1, 2, 3, 0.5` and `1 2 3 / 50%` are valid\n const parts = func[2]\n .replace('/', ',')\n .split(/[\\s,]+/)\n .filter(part => part !== '');\n\n if (parts.length < 3) {\n return null;\n }\n if (func[1].startsWith('rgb')) {\n return {\n r: readChannel(parts[0], 255),\n g: readChannel(parts[1], 255),\n b: readChannel(parts[2], 255),\n a: readAlpha(parts[3]),\n };\n }\n const hue = ((parseFloat(parts[0]) % 360) + 360) % 360;\n const rgb = hsl2rgb(\n hue / 360,\n clamp(parseFloat(parts[1]) / 100, 0, 1),\n clamp(parseFloat(parts[2]) / 100, 0, 1),\n );\n\n return { ...rgb, a: readAlpha(parts[3]) };\n }\n\n // color names and everything else the browser understands\n const normalized = normalizeCssColor(str);\n\n return normalized && normalized !== str ? parseColor(normalized) : null;\n}\n\n/**\n * Render `{ r, g, b, a }` in the requested notation.\n *\n * @param color The color to render.\n * @param format The desired notation.\n * @param noAlpha If true, the alpha channel is dropped.\n * @returns the color as CSS string.\n */\nexport function formatColor(color: RgbaColor, format: ColorPickerFormat, noAlpha?: boolean): string {\n const alpha = noAlpha ? 1 : (color.a ?? 1);\n const opaque = alpha >= 1;\n const rounded = Math.round(alpha * 100) / 100;\n\n if (format === 'hex') {\n const hex = `#${color.r.toString(16).padStart(2, '0')}${color.g.toString(16).padStart(2, '0')}${color.b.toString(16).padStart(2, '0')}`;\n const hexAlpha = Math.round(alpha * 255)\n .toString(16)\n .padStart(2, '0');\n\n return opaque ? hex : `${hex}${hexAlpha}`;\n }\n if (format === 'hsl') {\n const { h, s, l } = rgb2hsl(color);\n\n return opaque ? `hsl(${h}, ${s}%, ${l}%)` : `hsla(${h}, ${s}%, ${l}%, ${rounded})`;\n }\n\n return opaque ? `rgb(${color.r}, ${color.g}, ${color.b})` : `rgba(${color.r}, ${color.g}, ${color.b}, ${rounded})`;\n}\n\n/**\n * Guess the notation of the given color string.\n *\n * @param color The color string.\n */\nfunction detectFormat(color: string): ColorPickerFormat | null {\n const str = (color || '').trim().toLowerCase();\n if (str.startsWith('#')) {\n return 'hex';\n }\n if (str.startsWith('rgb')) {\n return 'rgb';\n }\n if (str.startsWith('hsl')) {\n return 'hsl';\n }\n return null;\n}\n\ninterface EyeDropperInstance {\n open: (options?: { signal?: AbortSignal }) => Promise<{ sRGBHex: string }>;\n}\n\n/**\n * Read the `EyeDropper` constructor, which is not part of the DOM types yet.\n */\nfunction getEyeDropper(): (new () => EyeDropperInstance) | undefined {\n if (typeof window === 'undefined') {\n return undefined;\n }\n return (window as unknown as Record<string, unknown>).EyeDropper as (new () => EyeDropperInstance) | undefined;\n}\n\ninterface ColorPickerProps {\n /** Set to true to disable the color picker. */\n disabled?: boolean;\n /** The currently selected color. */\n value?: string;\n /** @deprecated The currently selected color use value */\n color?: string;\n /** The color change callback. */\n onChange: (rgba: string) => void;\n /** Label of the color picker. */\n label?: string;\n /** @deprecated TLabel of the color picker use label */\n name?: string;\n /** Additional styling for this component. */\n style?: CSSProperties;\n /** The CSS class name. */\n className?: string;\n /** Predefined colors that are offered below the picker. */\n customPalette?: string[];\n /** Do not show the text field with the color value, only the color bar. */\n noInputField?: boolean;\n /** Width of the color bar. */\n barWidth?: number;\n sx?: Record<string, any>;\n /** @deprecated the theme is taken from the MUI context */\n theme?: IobTheme;\n /** Hide the alpha slider and always report a fully opaque color. */\n noAlpha?: boolean;\n /** Notation of the reported value. If not set, it is taken from the incoming value and defaults to `rgb`. */\n format?: ColorPickerFormat;\n /** Do not offer the recently used colors. */\n noRecentColors?: boolean;\n /** Width of the picker popup in pixels. Default 280. */\n pickerWidth?: number;\n /** ID of the text field. Must be set if more than one color picker is rendered at the same time. */\n id?: string;\n}\n\ninterface ColorPickerState {\n displayColorPicker: boolean;\n /** The working color of the picker. Always valid, even if no color is selected. */\n rgba: RgbaColor;\n /** The text shown in the input field. An empty string means \"no color selected\". */\n textValue: string;\n format: ColorPickerFormat;\n anchorEl: HTMLDivElement | null;\n recentColors: string[];\n}\n\n/**\n * A color picker component with alpha channel, eye dropper and HEX/RGB/HSL notations.\n */\nexport class ColorPicker extends Component<ColorPickerProps, ColorPickerState> {\n /**\n * Constructor for the color picker.\n *\n * @param props The properties.\n */\n constructor(props: ColorPickerProps) {\n super(props);\n const value = props.value || props.color || '';\n\n this.state = {\n displayColorPicker: false,\n rgba: parseColor(value) || { ...DEFAULT_COLOR },\n textValue: value,\n format: props.format || detectFormat(value) || 'rgb',\n anchorEl: null,\n recentColors: [],\n };\n }\n\n /**\n * If the props are updated from outside, they should override the state\n *\n * @param prevProps The previous properties.\n */\n componentDidUpdate(prevProps: ColorPickerProps): void {\n const prevValue = prevProps.value ?? prevProps.color ?? '';\n const value = this.props.value ?? this.props.color ?? '';\n\n // React only on real changes from outside. If the value equals what is shown, it is the own echo.\n if (prevValue !== value && value !== this.state.textValue) {\n this.setState({\n rgba: parseColor(value) || { ...DEFAULT_COLOR },\n textValue: value,\n format: this.props.format || detectFormat(value) || this.state.format,\n });\n } else if (this.props.format && this.props.format !== prevProps.format) {\n this.setState({ format: this.props.format });\n }\n }\n\n /**\n * Convert the given color to hex ('#rrggbb') or rgba ('rgba(r,g,b,a)') format.\n *\n * @param color The color to convert.\n * @param isHex If true, the color will be converted to hex format.\n * @returns the hex or rgba representation of the given color.\n */\n static getColor(color: string | { rgb: RGBColor } | RGBColor, isHex?: boolean): string {\n if (color && typeof color === 'object') {\n const oColor = color as { rgb: RGBColor };\n const rColor: RGBColor = oColor.rgb ? oColor.rgb : (color as RGBColor);\n\n if (isHex) {\n return `#${rColor.r.toString(16).padStart(2, '0')}${rColor.g.toString(16).padStart(2, '0')}${rColor.b.toString(16).padStart(2, '0')}`;\n }\n return `rgba(${rColor.r},${rColor.g},${rColor.b},${rColor.a ?? 1})`;\n }\n if (typeof color === 'string') {\n return isHex ? ColorPicker.rgb2hex(color || '') : color || '';\n }\n return '';\n }\n\n /**\n * Convert rgb() or rgba() format to hex format #rrggbb.\n *\n * @param rgb The color in rgb() or rgba() format. if not in this format, the color will be returned as is.\n */\n static rgb2hex(rgb: string): string {\n const m = /^rgba?[\\s+]?\\([\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?/i.exec(rgb);\n\n if (m) {\n const r = parseInt(m[1], 10).toString(16).padStart(2, '0');\n const g = parseInt(m[2], 10).toString(16).padStart(2, '0');\n const b = parseInt(m[3], 10).toString(16).padStart(2, '0');\n\n return m?.length === 4 ? `#${r}${g}${b}` : rgb;\n }\n return rgb;\n }\n\n /**\n * Read the recently used colors from the local storage.\n */\n static readRecentColors(): string[] {\n try {\n const stored = window.localStorage.getItem(RECENT_COLORS_KEY);\n const parsed: unknown = stored ? JSON.parse(stored) : null;\n\n if (Array.isArray(parsed)) {\n return parsed.filter((item): item is string => typeof item === 'string').slice(0, MAX_RECENT_COLORS);\n }\n } catch {\n // ignore a broken or unavailable local storage\n }\n return [];\n }\n\n /**\n * Remember the given color as recently used.\n *\n * @param color The color to remember.\n */\n storeRecentColor(color: string): void {\n if (this.props.noRecentColors || !color || this.state.recentColors[0] === color) {\n return;\n }\n const recentColors = [color, ...this.state.recentColors.filter(item => item !== color)].slice(\n 0,\n MAX_RECENT_COLORS,\n );\n\n this.setState({ recentColors });\n\n try {\n window.localStorage.setItem(RECENT_COLORS_KEY, JSON.stringify(recentColors));\n } catch {\n // ignore an unavailable local storage\n }\n }\n\n private handleClick = (e: React.MouseEvent<HTMLDivElement>): void => {\n const open = !this.state.displayColorPicker;\n\n this.setState({\n displayColorPicker: open,\n anchorEl: open ? e.currentTarget : null,\n // read the recent colors on every open, so colors picked in another instance show up too\n recentColors: open && !this.props.noRecentColors ? ColorPicker.readRecentColors() : this.state.recentColors,\n });\n };\n\n private handleClose = (): void => {\n this.storeRecentColor(this.state.textValue);\n this.setState({ displayColorPicker: false, anchorEl: null });\n };\n\n /**\n * The user moved a slider, clicked a swatch or used the eye dropper.\n *\n * @param rgba The new color.\n */\n private handleColorChange = (rgba: RgbaColor): void => {\n const textValue = formatColor(rgba, this.state.format, this.props.noAlpha);\n\n this.setState({ rgba, textValue }, () => this.props.onChange?.(textValue));\n };\n\n /**\n * The user typed into the input field. The text is taken as it is and only parsed for the preview.\n *\n * @param textValue The entered text.\n */\n private handleTextChange = (textValue: string): void => {\n const rgba = parseColor(textValue);\n\n this.setState({ textValue, rgba: rgba || this.state.rgba }, () => this.props.onChange?.(textValue));\n };\n\n /**\n * Switch between the #rrggbb, rgba() and hsla() notations.\n *\n * @param format The new notation.\n */\n private handleFormatChange = (format: ColorPickerFormat): void => {\n if (!this.state.textValue) {\n this.setState({ format });\n return;\n }\n const textValue = formatColor(this.state.rgba, format, this.props.noAlpha);\n\n this.setState({ format, textValue }, () => this.props.onChange?.(textValue));\n };\n\n private handleClear = (): void => {\n this.setState({ textValue: '', rgba: { ...DEFAULT_COLOR } }, () => this.props.onChange?.(''));\n };\n\n private handleEyeDropper = (): void => {\n const EyeDropper = getEyeDropper();\n if (!EyeDropper) {\n return;\n }\n\n void new EyeDropper()\n .open()\n .then(result => {\n const rgba = parseColor(result.sRGBHex);\n if (rgba) {\n // the eye dropper always returns an opaque color, so the current alpha is kept\n this.handleColorChange({ ...rgba, a: this.props.noAlpha ? 1 : (this.state.rgba.a ?? 1) });\n }\n })\n .catch(() => {\n // the user aborted the selection with ESC\n });\n };\n\n /**\n * Render a row of predefined colors.\n *\n * @param colors The colors to show.\n * @param title The title above the row.\n */\n renderSwatches(colors: string[], title: string): React.JSX.Element | null {\n if (!colors.length) {\n return null;\n }\n return (\n <Box component=\"div\">\n <Box\n component=\"div\"\n sx={styles.sectionTitle}\n >\n {title}\n </Box>\n <Box\n component=\"div\"\n sx={styles.swatchRow}\n >\n {colors.map((color, i) => (\n <Button\n sx={styles.paletteItem}\n key={`${color}_${i}`}\n title={color}\n onClick={() => {\n const rgba = parseColor(color);\n if (rgba) {\n this.handleColorChange(rgba);\n } else {\n this.handleTextChange(color);\n }\n }}\n >\n <Box\n component=\"div\"\n sx={styles.fill}\n style={{ background: color }}\n />\n </Button>\n ))}\n </Box>\n </Box>\n );\n }\n\n renderPicker(): React.JSX.Element {\n const { rgba, textValue, format } = this.state;\n const Picker = this.props.noAlpha ? RgbColorPicker : RgbaColorPicker;\n\n return (\n <Box\n component=\"div\"\n sx={styles.pickerWrapper}\n style={{ width: this.props.pickerWidth || 280 }}\n >\n <Picker\n color={rgba}\n onChange={(color: RgbaColor | { r: number; g: number; b: number }) =>\n this.handleColorChange({ a: rgba.a ?? 1, ...color })\n }\n />\n <Box\n component=\"div\"\n sx={styles.controlRow}\n >\n {getEyeDropper() ? (\n <Tooltip title={I18n.t('ra_Pick color from screen')}>\n <IconButton\n size=\"small\"\n onClick={this.handleEyeDropper}\n >\n <IconColorize fontSize=\"small\" />\n </IconButton>\n </Tooltip>\n ) : null}\n <Box\n component=\"div\"\n sx={styles.preview}\n >\n <Box\n component=\"div\"\n sx={styles.fill}\n style={{ background: textValue || 'transparent' }}\n />\n </Box>\n <TextField\n variant=\"standard\"\n size=\"small\"\n sx={styles.valueInput}\n value={textValue}\n placeholder={I18n.t('ra_Select color')}\n onChange={e => this.handleTextChange(e.target.value)}\n />\n <Select\n variant=\"standard\"\n disableUnderline\n sx={styles.formatSelect}\n value={format}\n onChange={e => this.handleFormatChange(e.target.value)}\n >\n <MenuItem value=\"hex\">HEX</MenuItem>\n <MenuItem value=\"rgb\">RGB</MenuItem>\n <MenuItem value=\"hsl\">HSL</MenuItem>\n </Select>\n <Tooltip title={I18n.t('ra_Clear color')}>\n <span>\n <IconButton\n size=\"small\"\n disabled={!textValue}\n onClick={this.handleClear}\n >\n <IconTrash fontSize=\"small\" />\n </IconButton>\n </span>\n </Tooltip>\n </Box>\n {this.renderSwatches(this.props.customPalette || [], I18n.t('ra_Palette'))}\n {this.renderSwatches(\n this.props.noRecentColors ? [] : this.state.recentColors,\n I18n.t('ra_Recently used colors'),\n )}\n </Box>\n );\n }\n\n render(): React.JSX.Element {\n const style = { ...(this.props.style || {}) };\n style.position = 'relative';\n const { textValue } = this.state;\n const hasLabel = !!(this.props.label || this.props.name);\n\n return (\n <Box\n component=\"div\"\n style={style}\n sx={this.props.sx || undefined}\n className={this.props.className || ''}\n >\n {this.props.noInputField ? null : (\n <TextField\n disabled={this.props.disabled}\n variant=\"standard\"\n id={this.props.id || 'ar_color_picker_name'}\n label={this.props.label || this.props.name}\n value={textValue}\n margin=\"dense\"\n sx={{\n '&.MuiFormControl-root': styles.textDense,\n width: textValue ? 'calc(100% - 80px)' : 'calc(100% - 56px)',\n mr: textValue ? undefined : 1,\n }}\n onChange={e => this.handleTextChange(e.target.value)}\n />\n )}\n {!this.props.noInputField && textValue ? (\n <IconButton\n disabled={this.props.disabled}\n onClick={this.handleClear}\n size=\"small\"\n style={hasLabel ? styles.delButton : undefined}\n >\n <IconTrash />\n </IconButton>\n ) : null}\n <Box\n component=\"div\"\n onClick={e => !this.props.disabled && this.handleClick(e)}\n title={I18n.t('ra_Select color')}\n sx={{\n ...styles.swatch,\n ...(this.props.disabled ? styles.swatchDisabled : undefined),\n marginTop: this.props.noInputField || !hasLabel ? 0 : undefined,\n }}\n >\n <Box\n component=\"div\"\n sx={{\n ...styles.color,\n border: textValue ? undefined : '1px dashed #888',\n boxSizing: 'border-box',\n }}\n style={{\n width: this.props.noInputField ? this.props.barWidth || 16 : this.props.barWidth || 36,\n }}\n >\n <Box\n component=\"div\"\n sx={styles.fill}\n style={{ background: textValue || 'transparent' }}\n />\n </Box>\n </Box>\n {this.state.displayColorPicker && !this.props.disabled ? (\n <Popover\n sx={styles.popover}\n anchorEl={this.state.anchorEl}\n open={!0}\n onClose={this.handleClose}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n >\n {this.renderPicker()}\n </Popover>\n ) : null}\n </Box>\n );\n }\n}\n"]}
|
|
@@ -138,6 +138,10 @@ interface FileBrowserState {
|
|
|
138
138
|
showTypesMenu: HTMLButtonElement | null;
|
|
139
139
|
restrictToFolder: string;
|
|
140
140
|
pathFocus: boolean;
|
|
141
|
+
/** The reload button was clicked and the folders are being read again */
|
|
142
|
+
reloading: boolean;
|
|
143
|
+
/** Dropped files are being uploaded */
|
|
144
|
+
uploading: boolean;
|
|
141
145
|
}
|
|
142
146
|
export declare class FileBrowserClass extends Component<FileBrowserProps, FileBrowserState> {
|
|
143
147
|
private readonly imagePrefix;
|
|
@@ -166,6 +170,8 @@ export declare class FileBrowserClass extends Component<FileBrowserProps, FileBr
|
|
|
166
170
|
constructor(props: FileBrowserProps);
|
|
167
171
|
static getDerivedStateFromProps(props: FileBrowserProps, state: FileBrowserState): Partial<FileBrowserState> | null;
|
|
168
172
|
loadFolders(): Promise<void>;
|
|
173
|
+
/** Reads all folders again; the reload button turns meanwhile */
|
|
174
|
+
reload(): void;
|
|
169
175
|
scrollToSelected(): void;
|
|
170
176
|
componentDidMount(): Promise<void>;
|
|
171
177
|
componentWillUnmount(): void;
|
|
@@ -7,14 +7,18 @@
|
|
|
7
7
|
import React, { Component } from 'react';
|
|
8
8
|
import Dropzone from 'react-dropzone';
|
|
9
9
|
import { LinearProgress, ListItemIcon, ListItemText, Menu, MenuItem, Tooltip, Toolbar, IconButton, Fab, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button, Input, Breadcrumbs, Box, Checkbox, FormControlLabel, } from '@mui/material';
|
|
10
|
+
import { alpha } from '@mui/material/styles';
|
|
10
11
|
// MUI Icons
|
|
11
|
-
import { ArrowBack as IconBack, AudioFile as TypeIconAudio, Bookmark as JsonIcon, BookmarkBorder as CssIcon, Brightness6 as Brightness5Icon, Close as CloseIcon, Code as JSIcon, CreateNewFolder as AddFolderIcon,
|
|
12
|
+
import { ArrowBack as IconBack, AudioFile as TypeIconAudio, Bookmark as JsonIcon, BookmarkBorder as CssIcon, Brightness6 as Brightness5Icon, Close as CloseIcon, Code as JSIcon, CreateNewFolder as AddFolderIcon, Description as HtmlIcon, Edit as EditIcon, FolderOpen as EmptyFilterIcon, FolderSpecial as RestrictedIcon, FontDownload as TypeIconTxt, Image as TypeIconImages, InsertDriveFile as FileIcon, KeyboardReturn as EnterIcon, List as IconList, MusicNote as MusicIcon, SaveAlt as DownloadIcon, Videocam as TypeIconVideo, ViewModule as IconTile, } from '@mui/icons-material';
|
|
12
13
|
import { DialogError } from '../Dialogs/Error';
|
|
13
14
|
import { Utils } from './Utils';
|
|
14
15
|
import { DialogTextInput } from '../Dialogs/TextInput';
|
|
15
16
|
// Custom Icons
|
|
16
17
|
import { IconExpertMode } from './AnimatedIcons/IconExpertMode';
|
|
17
18
|
import { IconFolder } from './AnimatedIcons/IconFolder';
|
|
19
|
+
import { IconTrash } from './AnimatedIcons/IconTrash';
|
|
20
|
+
import { IconRefresh } from './AnimatedIcons/IconRefresh';
|
|
21
|
+
import { IconUpload } from './AnimatedIcons/IconUpload';
|
|
18
22
|
import { IconClosed } from '../icons/IconClosed';
|
|
19
23
|
import { IconNoIcon } from '../icons/IconNoIcon';
|
|
20
24
|
import { Icon } from './Icon';
|
|
@@ -286,6 +290,18 @@ const styles = {
|
|
|
286
290
|
alignItems: 'center',
|
|
287
291
|
justifyContent: 'center',
|
|
288
292
|
}),
|
|
293
|
+
/** Files are dragged over the drop area: its border pulses */
|
|
294
|
+
uploadCenterDivDragging: (theme) => ({
|
|
295
|
+
borderColor: theme.palette.primary.main,
|
|
296
|
+
animation: 'iob-fb-drop-pulse 1.2s ease-in-out infinite',
|
|
297
|
+
'@keyframes iob-fb-drop-pulse': {
|
|
298
|
+
'0%': { boxShadow: `0 0 0 0 ${alpha(theme.palette.primary.main, 0.4)}` },
|
|
299
|
+
'70%, 100%': { boxShadow: `0 0 0 14px ${alpha(theme.palette.primary.main, 0)}` },
|
|
300
|
+
},
|
|
301
|
+
'@media (prefers-reduced-motion: reduce)': {
|
|
302
|
+
animation: 'none',
|
|
303
|
+
},
|
|
304
|
+
}),
|
|
289
305
|
uploadCenterIcon: {
|
|
290
306
|
width: '25%',
|
|
291
307
|
height: '25%',
|
|
@@ -493,6 +509,8 @@ export class FileBrowserClass extends Component {
|
|
|
493
509
|
restrictToFolder: props.restrictToFolder || '',
|
|
494
510
|
pathFocus: false,
|
|
495
511
|
suppressDeleteConfirm: false,
|
|
512
|
+
reloading: false,
|
|
513
|
+
uploading: false,
|
|
496
514
|
};
|
|
497
515
|
this.imagePrefix = this.props.imagePrefix || './files/';
|
|
498
516
|
this.levelPadding = this.props.levelPadding || 20;
|
|
@@ -542,6 +560,12 @@ export class FileBrowserClass extends Component {
|
|
|
542
560
|
this.initialReadFinished = true;
|
|
543
561
|
});
|
|
544
562
|
}
|
|
563
|
+
/** Reads all folders again; the reload button turns meanwhile */
|
|
564
|
+
reload() {
|
|
565
|
+
this.setState({ folders: {}, reloading: true }, () => this.loadFolders()
|
|
566
|
+
.catch(error => console.error(`Cannot load folders: ${error}`))
|
|
567
|
+
.finally(() => this.mounted && this.setState({ reloading: false })));
|
|
568
|
+
}
|
|
545
569
|
scrollToSelected() {
|
|
546
570
|
if (this.mounted) {
|
|
547
571
|
const el = document.getElementById(this.state.selected);
|
|
@@ -1032,7 +1056,7 @@ export class FileBrowserClass extends Component {
|
|
|
1032
1056
|
this.setState({ deleteItem: item.id });
|
|
1033
1057
|
}
|
|
1034
1058
|
}, sx: styles[`itemDeleteButton${this.state.viewType}`], size: "large" },
|
|
1035
|
-
React.createElement(
|
|
1059
|
+
React.createElement(IconTrash, { fontSize: "small", open: this.state.deleteItem === item.id }))) : this.state.viewType === TABLE && this.props.allowDelete ? (React.createElement(Box, { component: "div", sx: styles[`itemDeleteButton${this.state.viewType}`] })) : null));
|
|
1036
1060
|
}
|
|
1037
1061
|
renderBackFolder() {
|
|
1038
1062
|
return (React.createElement(Box, { component: "div", key: this.state.currentDir, id: this.state.currentDir, onClick: e => this.changeFolder(e), title: this.props.t('ra_Back to %s', getParentDir(this.state.currentDir)), className: "browserItem", sx: Utils.getStyle(this.props.theme, styles[`item${this.state.viewType}`], styles[`itemFolder${this.state.viewType}`]) },
|
|
@@ -1182,7 +1206,7 @@ export class FileBrowserClass extends Component {
|
|
|
1182
1206
|
this.setState({ deleteItem: item.id });
|
|
1183
1207
|
}
|
|
1184
1208
|
}, sx: styles[`itemDeleteButton${this.state.viewType}`], size: "large" },
|
|
1185
|
-
React.createElement(
|
|
1209
|
+
React.createElement(IconTrash, { fontSize: "small", open: this.state.deleteItem === item.id }))) : this.state.viewType === TABLE && this.props.allowDelete ? (React.createElement(Box, { component: "div", sx: styles[`itemDeleteButton${this.state.viewType}`] })) : null));
|
|
1186
1210
|
}
|
|
1187
1211
|
renderItems(folderId) {
|
|
1188
1212
|
if (this.state.folders?.[folderId]) {
|
|
@@ -1281,8 +1305,8 @@ export class FileBrowserClass extends Component {
|
|
|
1281
1305
|
this.setState({ filterEmpty: !this.state.filterEmpty });
|
|
1282
1306
|
}, size: "small" },
|
|
1283
1307
|
React.createElement(EmptyFilterIcon, { fontSize: "small" })),
|
|
1284
|
-
React.createElement(IconButton, { edge: "start", title: this.props.t('ra_Reload files'), style: styles.menuButton, color: "inherit", "aria-label": "reload files",
|
|
1285
|
-
React.createElement(
|
|
1308
|
+
React.createElement(IconButton, { edge: "start", title: this.props.t('ra_Reload files'), style: styles.menuButton, color: "inherit", "aria-label": "reload files", disabled: this.state.reloading, onClick: () => this.reload(), size: "small" },
|
|
1309
|
+
React.createElement(IconRefresh, { fontSize: "small", loading: this.state.reloading })),
|
|
1286
1310
|
this.props.allowCreateFolder ? (React.createElement(IconButton, { edge: "start", disabled: !this.state.selected ||
|
|
1287
1311
|
!isInFolder ||
|
|
1288
1312
|
(!!this.limitToPath &&
|
|
@@ -1294,7 +1318,7 @@ export class FileBrowserClass extends Component {
|
|
|
1294
1318
|
(!!this.limitToPath &&
|
|
1295
1319
|
!this.state.selected.startsWith(`${this.limitToPath}/`) &&
|
|
1296
1320
|
this.limitToPath !== this.state.selected), title: this.props.t('ra_Upload file'), style: styles.menuButton, color: "inherit", "aria-label": "upload file", onClick: () => this.setState({ uploadFile: true }), size: "small" },
|
|
1297
|
-
React.createElement(
|
|
1321
|
+
React.createElement(IconUpload, { fontSize: "small", uploading: this.state.uploading }))) : null,
|
|
1298
1322
|
this.props.showTypeSelector && IconType ? (React.createElement(Tooltip, { title: this.props.t('ra_Filter files'), slotProps: { popper: { sx: styles.tooltip } } },
|
|
1299
1323
|
React.createElement(IconButton, { size: "small", onClick: e => this.setState({ showTypesMenu: e.target }) },
|
|
1300
1324
|
React.createElement(IconType, { fontSize: "small" })))) : null,
|
|
@@ -1331,7 +1355,7 @@ export class FileBrowserClass extends Component {
|
|
|
1331
1355
|
this.setState({ deleteItem: this.state.selected });
|
|
1332
1356
|
}
|
|
1333
1357
|
}, size: "small" },
|
|
1334
|
-
React.createElement(
|
|
1358
|
+
React.createElement(IconTrash, { fontSize: "small", open: !!this.state.deleteItem && this.state.deleteItem === this.state.selected }))))) : null));
|
|
1335
1359
|
}
|
|
1336
1360
|
findItem(id, folders) {
|
|
1337
1361
|
folders = folders || this.state.folders;
|
|
@@ -1517,20 +1541,38 @@ export class FileBrowserClass extends Component {
|
|
|
1517
1541
|
React.createElement(CloseIcon, null)),
|
|
1518
1542
|
React.createElement(Dropzone, { key: "dropzone", onDragEnter: () => this.setState({ uploadFile: 'dragging' }), onDragLeave: () => this.setState({ uploadFile: true }), onDrop: acceptedFiles => {
|
|
1519
1543
|
let count = acceptedFiles.length;
|
|
1544
|
+
if (!count) {
|
|
1545
|
+
this.setState({ uploadFile: true });
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
this.setState({ uploading: true });
|
|
1549
|
+
// a file that cannot be read or written does not keep the upload icon moving
|
|
1550
|
+
const failed = () => {
|
|
1551
|
+
if (!--count) {
|
|
1552
|
+
this.setState({ uploading: false });
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1520
1555
|
acceptedFiles.forEach(file => {
|
|
1521
1556
|
const reader = new FileReader();
|
|
1522
|
-
reader.onabort = () =>
|
|
1523
|
-
|
|
1557
|
+
reader.onabort = () => {
|
|
1558
|
+
console.log('file reading was aborted');
|
|
1559
|
+
failed();
|
|
1560
|
+
};
|
|
1561
|
+
reader.onerror = () => {
|
|
1562
|
+
console.log('file reading has failed');
|
|
1563
|
+
failed();
|
|
1564
|
+
};
|
|
1524
1565
|
reader.onload = () => {
|
|
1525
1566
|
const parentFolder = this.findFirstFolder(this.state.selected);
|
|
1526
1567
|
if (!parentFolder) {
|
|
1527
1568
|
window.alert(this.props.t('ra_Invalid parent folder!'));
|
|
1569
|
+
failed();
|
|
1528
1570
|
}
|
|
1529
1571
|
else {
|
|
1530
1572
|
const id = `${parentFolder}/${file.name}`;
|
|
1531
1573
|
void this.uploadFile(id, reader.result).then(() => {
|
|
1532
1574
|
if (!--count) {
|
|
1533
|
-
this.setState({ uploadFile: false }, () => {
|
|
1575
|
+
this.setState({ uploadFile: false, uploading: false }, () => {
|
|
1534
1576
|
if (this.supportSubscribes) {
|
|
1535
1577
|
// open current folder
|
|
1536
1578
|
const expanded = [...this.state.expanded];
|
|
@@ -1565,9 +1607,9 @@ export class FileBrowserClass extends Component {
|
|
|
1565
1607
|
...(this.state.uploadFile === 'dragging' ? styles.uploadDivDragging : undefined),
|
|
1566
1608
|
}, ...getRootProps() },
|
|
1567
1609
|
React.createElement("input", { ...getInputProps() }),
|
|
1568
|
-
React.createElement(Box, { component: "div", sx: styles.uploadCenterDiv },
|
|
1610
|
+
React.createElement(Box, { component: "div", sx: Utils.getStyle(this.props.theme, styles.uploadCenterDiv, this.state.uploadFile === 'dragging' ? styles.uploadCenterDivDragging : undefined) },
|
|
1569
1611
|
React.createElement("div", { style: styles.uploadCenterTextAndIcon },
|
|
1570
|
-
React.createElement(
|
|
1612
|
+
React.createElement(IconUpload, { style: styles.uploadCenterIcon, ready: this.state.uploadFile === 'dragging', uploading: this.state.uploading }),
|
|
1571
1613
|
React.createElement("div", { style: styles.uploadCenterText }, this.state.uploadFile === 'dragging'
|
|
1572
1614
|
? this.props.t('ra_Drop file here')
|
|
1573
1615
|
: this.props.t('ra_Place your files here or click here to open the browse dialog'))))))),
|