@wandelbots/wandelbots-js-react-components 2.35.0 → 2.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -151
- package/dist/components/CopyableText.d.ts +3 -2
- package/dist/components/CopyableText.d.ts.map +1 -1
- package/dist/components/SelectableFab.d.ts +2 -1
- package/dist/components/SelectableFab.d.ts.map +1 -1
- package/dist/components/TabBar.d.ts +2 -0
- package/dist/components/TabBar.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +208 -208
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/components/CopyableText.tsx +70 -73
- package/src/components/LogViewer.tsx +1 -1
- package/src/components/SelectableFab.tsx +14 -15
- package/src/components/TabBar.tsx +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wandelbots/wandelbots-js-react-components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.36.0",
|
|
4
4
|
"description": "React UI toolkit for building applications on top of the Wandelbots platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
60
60
|
"@rollup/plugin-terser": "^0.4.4",
|
|
61
61
|
"@rollup/plugin-typescript": "^12.1.2",
|
|
62
|
-
"@storybook/addon-docs": "^9.1.
|
|
63
|
-
"@storybook/react-vite": "^9.1.
|
|
62
|
+
"@storybook/addon-docs": "^9.1.3",
|
|
63
|
+
"@storybook/react-vite": "^9.1.3",
|
|
64
64
|
"@storybook/test-runner": "^0.23.0",
|
|
65
65
|
"@svgr/rollup": "^8.1.0",
|
|
66
66
|
"@testing-library/jest-dom": "^6.6.3",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@vitejs/plugin-react": "^4.3.4",
|
|
73
73
|
"@wandelbots/nova-js": "^2.1.0",
|
|
74
74
|
"add": "^2.0.6",
|
|
75
|
-
"eslint-plugin-storybook": "^9.1.
|
|
75
|
+
"eslint-plugin-storybook": "^9.1.3",
|
|
76
76
|
"glob": "^11.0.1",
|
|
77
77
|
"http-server": "^14.1.1",
|
|
78
78
|
"husky": "^9.1.7",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
96
96
|
"rollup-plugin-postcss": "^4.0.2",
|
|
97
97
|
"semantic-release": "^24.2.3",
|
|
98
|
-
"storybook": "^9.1.
|
|
98
|
+
"storybook": "^9.1.3",
|
|
99
99
|
"storybook-preset-inline-svg": "^1.0.1",
|
|
100
100
|
"three": "^0.174.0",
|
|
101
101
|
"three-stdlib": "^2.35.14",
|
|
@@ -1,87 +1,84 @@
|
|
|
1
1
|
import { Stack, Tooltip, Typography, useTheme } from "@mui/material"
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect, useState } from "react"
|
|
3
3
|
|
|
4
|
-
export const CopyableText =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
ref: React.ForwardedRef<HTMLDivElement>,
|
|
14
|
-
) => {
|
|
15
|
-
const theme = useTheme()
|
|
16
|
-
const [tooltipOpen, setTooltipOpen] = useState(false)
|
|
4
|
+
export const CopyableText = (props: {
|
|
5
|
+
label?: string
|
|
6
|
+
value: string
|
|
7
|
+
ref?: React.Ref<HTMLDivElement>
|
|
8
|
+
}) => {
|
|
9
|
+
const { value, ref } = props
|
|
10
|
+
// Note: label prop is available but not currently used in the component
|
|
11
|
+
const theme = useTheme()
|
|
12
|
+
const [tooltipOpen, setTooltipOpen] = useState(false)
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
async function onCopyText(): Promise<boolean> {
|
|
15
|
+
if (!ref || !("current" in ref)) {
|
|
16
|
+
console.warn("No copy target found")
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
await navigator.clipboard.writeText(value)
|
|
21
|
+
console.log("Copied!")
|
|
22
|
+
setTooltipOpen(true)
|
|
23
|
+
return true
|
|
24
|
+
} catch (err) {
|
|
25
|
+
// Direct clipboard copy is not available in non-secure contexts
|
|
26
|
+
console.error(err)
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
// Let's fall back to selecting the text so the user can manually copy easily
|
|
29
|
+
const selection = window.getSelection()
|
|
30
|
+
if (selection && ref && "current" in ref && ref.current) {
|
|
34
31
|
const range = document.createRange()
|
|
35
|
-
range.selectNodeContents(ref.current
|
|
32
|
+
range.selectNodeContents(ref.current)
|
|
36
33
|
selection.removeAllRanges()
|
|
37
34
|
selection.addRange(range)
|
|
38
35
|
}
|
|
39
|
-
return false
|
|
40
36
|
}
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!tooltipOpen) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
const timeoutId = setTimeout(() => setTooltipOpen(false), 3000)
|
|
45
|
+
return () => {
|
|
46
|
+
timeoutId ? clearTimeout(timeoutId) : {}
|
|
47
|
+
}
|
|
48
|
+
}, [tooltipOpen])
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
return (
|
|
51
|
+
<Tooltip open={tooltipOpen} title="Copied!">
|
|
52
|
+
<Stack
|
|
53
|
+
justifyContent="center"
|
|
54
|
+
sx={{
|
|
55
|
+
height: "100%",
|
|
56
|
+
boxSizing: "border-box",
|
|
57
|
+
padding: "6px 12px",
|
|
58
|
+
background: theme.palette.backgroundPaperElevation?.[8],
|
|
59
|
+
borderRadius: "10px",
|
|
60
|
+
minWidth: "0",
|
|
61
|
+
cursor: "pointer",
|
|
62
|
+
}}
|
|
63
|
+
onClick={() => onCopyText()}
|
|
64
|
+
>
|
|
65
|
+
<Typography
|
|
66
|
+
ref={ref}
|
|
67
|
+
align="center"
|
|
56
68
|
sx={{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
pointerEvents: "none",
|
|
70
|
+
fontSize: "12px",
|
|
71
|
+
color: theme.palette.text.primary,
|
|
72
|
+
whiteSpace: "nowrap",
|
|
73
|
+
minWidth: 0,
|
|
74
|
+
textOverflow: "ellipsis",
|
|
75
|
+
width: "100%",
|
|
76
|
+
overflow: "hidden",
|
|
64
77
|
}}
|
|
65
|
-
onClick={() => onCopyText()}
|
|
66
78
|
>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
color: theme.palette.text.primary,
|
|
74
|
-
whiteSpace: "nowrap",
|
|
75
|
-
minWidth: 0,
|
|
76
|
-
textOverflow: "ellipsis",
|
|
77
|
-
width: "100%",
|
|
78
|
-
overflow: "hidden",
|
|
79
|
-
}}
|
|
80
|
-
>
|
|
81
|
-
{value}
|
|
82
|
-
</Typography>
|
|
83
|
-
</Stack>
|
|
84
|
-
</Tooltip>
|
|
85
|
-
)
|
|
86
|
-
},
|
|
87
|
-
)
|
|
79
|
+
{value}
|
|
80
|
+
</Typography>
|
|
81
|
+
</Stack>
|
|
82
|
+
</Tooltip>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
@@ -45,7 +45,7 @@ export const createLogMessage = (
|
|
|
45
45
|
level: LogLevel,
|
|
46
46
|
id?: string,
|
|
47
47
|
): LogMessage => ({
|
|
48
|
-
id: id || `${Date.now()}-${Math.random().toString(36).
|
|
48
|
+
id: id || `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
|
49
49
|
timestamp: new Date(),
|
|
50
50
|
message,
|
|
51
51
|
level,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Fab,
|
|
2
|
-
import { forwardRef, type Ref } from "react"
|
|
1
|
+
import { Fab, type FabProps, styled } from "@mui/material"
|
|
3
2
|
|
|
4
3
|
const StyledSelectableFab = styled(Fab, {
|
|
5
4
|
shouldForwardProp: (prop) => prop !== "selected",
|
|
@@ -34,18 +33,18 @@ const StyledSelectableFab = styled(Fab, {
|
|
|
34
33
|
|
|
35
34
|
type CodeFabProps = {
|
|
36
35
|
selected?: boolean
|
|
36
|
+
ref?: React.Ref<HTMLButtonElement>
|
|
37
37
|
} & Omit<FabProps, "variant" | "color">
|
|
38
38
|
|
|
39
|
-
export const SelectableFab =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
39
|
+
export const SelectableFab = (props: CodeFabProps) => {
|
|
40
|
+
const { ref, ...otherProps } = props
|
|
41
|
+
return (
|
|
42
|
+
<StyledSelectableFab
|
|
43
|
+
ref={ref}
|
|
44
|
+
selected={props.selected}
|
|
45
|
+
{...otherProps}
|
|
46
|
+
color={"secondary"}
|
|
47
|
+
variant="circular"
|
|
48
|
+
/>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
@@ -24,6 +24,8 @@ export interface TabBarProps {
|
|
|
24
24
|
onTabChange?: (index: number) => void
|
|
25
25
|
/** Additional styling */
|
|
26
26
|
sx?: SxProps
|
|
27
|
+
/** Ref to the root container element */
|
|
28
|
+
ref?: React.Ref<HTMLDivElement>
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
interface TabPanelProps {
|
|
@@ -55,7 +57,7 @@ function TabPanel(props: TabPanelProps) {
|
|
|
55
57
|
*/
|
|
56
58
|
export const TabBar = externalizeComponent(
|
|
57
59
|
observer((props: TabBarProps) => {
|
|
58
|
-
const { items, defaultActiveTab = 0, onTabChange, sx } = props
|
|
60
|
+
const { items, defaultActiveTab = 0, onTabChange, sx, ref } = props
|
|
59
61
|
const [activeTab, setActiveTab] = useState(defaultActiveTab)
|
|
60
62
|
|
|
61
63
|
const handleTabChange = (
|
|
@@ -68,6 +70,7 @@ export const TabBar = externalizeComponent(
|
|
|
68
70
|
|
|
69
71
|
return (
|
|
70
72
|
<Box
|
|
73
|
+
ref={ref}
|
|
71
74
|
sx={{ height: "100%", display: "flex", flexDirection: "column", ...sx }}
|
|
72
75
|
>
|
|
73
76
|
{/* Tabs */}
|