@wandelbots/wandelbots-js-react-components 2.40.0-pr.feature-seperate-timer.383.0494cf4 → 2.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/components/CycleTimer/DefaultVariant.d.ts.map +1 -1
  2. package/dist/components/CycleTimer/SmallVariant.d.ts.map +1 -1
  3. package/dist/components/CycleTimer/index.d.ts +5 -4
  4. package/dist/components/CycleTimer/index.d.ts.map +1 -1
  5. package/dist/components/CycleTimer/types.d.ts +3 -2
  6. package/dist/components/CycleTimer/types.d.ts.map +1 -1
  7. package/dist/components/CycleTimer/useTimerLogic.d.ts +2 -1
  8. package/dist/components/CycleTimer/useTimerLogic.d.ts.map +1 -1
  9. package/dist/components/TabBar.d.ts +2 -0
  10. package/dist/components/TabBar.d.ts.map +1 -1
  11. package/dist/index.cjs +47 -47
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.ts +0 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +4840 -5249
  16. package/dist/index.js.map +1 -1
  17. package/package.json +1 -1
  18. package/src/components/CycleTimer/DefaultVariant.tsx +2 -0
  19. package/src/components/CycleTimer/SmallVariant.tsx +5 -2
  20. package/src/components/CycleTimer/index.tsx +5 -4
  21. package/src/components/CycleTimer/types.ts +3 -1
  22. package/src/components/CycleTimer/useTimerLogic.ts +96 -40
  23. package/src/components/CycleTimer/utils.ts +3 -3
  24. package/src/components/TabBar.tsx +35 -8
  25. package/src/i18n/locales/de/translations.json +0 -1
  26. package/src/i18n/locales/en/translations.json +0 -1
  27. package/src/index.ts +0 -1
  28. package/dist/components/Timer/Timer.d.ts +0 -3
  29. package/dist/components/Timer/Timer.d.ts.map +0 -1
  30. package/dist/components/Timer/TimerDefaultVariant.d.ts +0 -10
  31. package/dist/components/Timer/TimerDefaultVariant.d.ts.map +0 -1
  32. package/dist/components/Timer/TimerSmallVariant.d.ts +0 -11
  33. package/dist/components/Timer/TimerSmallVariant.d.ts.map +0 -1
  34. package/dist/components/Timer/index.d.ts +0 -19
  35. package/dist/components/Timer/index.d.ts.map +0 -1
  36. package/dist/components/Timer/types.d.ts +0 -36
  37. package/dist/components/Timer/types.d.ts.map +0 -1
  38. package/dist/components/Timer/useTimerAnimations.d.ts +0 -11
  39. package/dist/components/Timer/useTimerAnimations.d.ts.map +0 -1
  40. package/dist/components/Timer/useTimerLogic.d.ts +0 -20
  41. package/dist/components/Timer/useTimerLogic.d.ts.map +0 -1
  42. package/dist/components/Timer/utils.d.ts +0 -9
  43. package/dist/components/Timer/utils.d.ts.map +0 -1
  44. package/src/components/Timer/Timer.ts +0 -2
  45. package/src/components/Timer/TimerDefaultVariant.tsx +0 -140
  46. package/src/components/Timer/TimerSmallVariant.tsx +0 -140
  47. package/src/components/Timer/index.tsx +0 -101
  48. package/src/components/Timer/types.ts +0 -38
  49. package/src/components/Timer/useTimerAnimations.ts +0 -94
  50. package/src/components/Timer/useTimerLogic.ts +0 -214
  51. package/src/components/Timer/utils.ts +0 -15
@@ -1,140 +0,0 @@
1
- import { Box, Fade, Typography } from "@mui/material"
2
- import { Gauge } from "@mui/x-charts"
3
- import { useTheme } from "@mui/material/styles"
4
- import { useTranslation } from "react-i18next"
5
- import type { TimerState, TimerAnimationState } from "./types"
6
- import { formatTime } from "./utils"
7
-
8
- interface TimerDefaultVariantProps {
9
- timerState: TimerState
10
- animationState: TimerAnimationState
11
- hasError: boolean
12
- className?: string
13
- }
14
-
15
- export const TimerDefaultVariant = ({
16
- timerState,
17
- animationState,
18
- hasError,
19
- className,
20
- }: TimerDefaultVariantProps) => {
21
- const { t } = useTranslation()
22
- const theme = useTheme()
23
- const { elapsedTime, currentProgress } = timerState
24
- const { showErrorAnimation, showPauseAnimation, showMainText } = animationState
25
-
26
- return (
27
- <Box
28
- className={className}
29
- sx={{
30
- position: "relative",
31
- width: 264,
32
- height: 264,
33
- display: "flex",
34
- alignItems: "center",
35
- justifyContent: "center",
36
- }}
37
- >
38
- <Gauge
39
- width={264}
40
- height={264}
41
- value={currentProgress}
42
- valueMin={0}
43
- valueMax={100}
44
- innerRadius="85%"
45
- outerRadius="100%"
46
- margin={0}
47
- skipAnimation={true}
48
- text={() => ""}
49
- sx={{
50
- opacity: showPauseAnimation || showErrorAnimation ? 0.6 : 1,
51
- transition: "opacity 0.5s ease-out",
52
- [`& .MuiGauge-valueArc`]: {
53
- fill: hasError
54
- ? theme.palette.error.light
55
- : theme.palette.success.main,
56
- transition: "fill 0.5s ease-out",
57
- },
58
- [`& .MuiGauge-referenceArc`]: {
59
- fill: "#171927",
60
- stroke: "transparent",
61
- strokeWidth: 0,
62
- transition:
63
- "fill 0.5s ease-out, stroke 0.5s ease-out, stroke-width 0.5s ease-out",
64
- },
65
- [`& .MuiGauge-valueText`]: {
66
- display: "none",
67
- },
68
- [`& .MuiGauge-text`]: {
69
- display: "none",
70
- },
71
- }}
72
- />
73
-
74
- {/* Center content overlay */}
75
- <Box
76
- sx={{
77
- position: "absolute",
78
- top: "50%",
79
- left: "50%",
80
- transform: "translate(-50%, -50%)",
81
- width: 225,
82
- height: 225,
83
- borderRadius: "50%",
84
- backgroundColor: "#292B3F",
85
- display: "flex",
86
- flexDirection: "column",
87
- alignItems: "center",
88
- justifyContent: "center",
89
- textAlign: "center",
90
- gap: 1,
91
- transition: "background-color 0.5s ease-out",
92
- }}
93
- >
94
- {/* Main display */}
95
- <Box
96
- sx={{
97
- position: "relative",
98
- height: "48px",
99
- display: "flex",
100
- alignItems: "center",
101
- justifyContent: "center",
102
- marginBottom: 0.5,
103
- }}
104
- >
105
- {/* Error text */}
106
- <Fade in={showMainText && hasError} timeout={200}>
107
- <Typography
108
- variant="h6"
109
- sx={{
110
- position: "absolute",
111
- fontSize: "16px",
112
- fontWeight: 500,
113
- color: theme.palette.error.light,
114
- }}
115
- >
116
- {t("timer.error")}
117
- </Typography>
118
- </Fade>
119
-
120
- {/* Timer display */}
121
- <Fade in={showMainText && !hasError} timeout={300}>
122
- <Typography
123
- variant="h1"
124
- sx={{
125
- position: "absolute",
126
- fontSize: "48px",
127
- fontWeight: 500,
128
- color: theme.palette.text.primary,
129
- lineHeight: 1,
130
- letterSpacing: "-0.5px",
131
- }}
132
- >
133
- {formatTime(elapsedTime)}
134
- </Typography>
135
- </Fade>
136
- </Box>
137
- </Box>
138
- </Box>
139
- )
140
- }
@@ -1,140 +0,0 @@
1
- import { Box, Typography } from "@mui/material"
2
- import { useTheme } from "@mui/material/styles"
3
- import { useTranslation } from "react-i18next"
4
- import type { TimerState, TimerAnimationState } from "./types"
5
- import { formatTime } from "./utils"
6
-
7
- interface TimerSmallVariantProps {
8
- timerState: TimerState
9
- animationState: TimerAnimationState
10
- hasError: boolean
11
- compact: boolean
12
- className?: string
13
- }
14
-
15
- export const TimerSmallVariant = ({
16
- timerState,
17
- animationState,
18
- hasError,
19
- compact,
20
- className,
21
- }: TimerSmallVariantProps) => {
22
- const { t } = useTranslation()
23
- const theme = useTheme()
24
- const { elapsedTime, currentProgress } = timerState
25
- const { showErrorAnimation, showPauseAnimation } = animationState
26
-
27
- // Simple text-only mode for compact variant
28
- if (compact) {
29
- return (
30
- <Box
31
- className={className}
32
- sx={{
33
- display: "flex",
34
- alignItems: "center",
35
- m: 0,
36
- }}
37
- >
38
- <Typography
39
- variant="body2"
40
- sx={{
41
- color: hasError
42
- ? theme.palette.error.light
43
- : theme.palette.text.primary,
44
- fontSize: "14px",
45
- transition: "color 0.5s ease-out",
46
- }}
47
- >
48
- {hasError ? t("timer.error") : formatTime(elapsedTime)}
49
- </Typography>
50
- </Box>
51
- )
52
- }
53
-
54
- return (
55
- <Box
56
- className={className}
57
- sx={{
58
- display: "flex",
59
- alignItems: "center",
60
- m: 0,
61
- gap: 1,
62
- }}
63
- >
64
- {/* Animated progress ring icon */}
65
- <Box
66
- sx={{
67
- width: 20,
68
- height: 20,
69
- display: "flex",
70
- alignItems: "center",
71
- justifyContent: "center",
72
- opacity: showPauseAnimation || showErrorAnimation ? 0.6 : 1,
73
- transition: "opacity 0.5s ease-out",
74
- }}
75
- >
76
- <svg
77
- width="20"
78
- height="20"
79
- viewBox="0 0 20 20"
80
- style={{ transform: "rotate(-90deg)" }}
81
- role="img"
82
- aria-label="Timer progress"
83
- >
84
- <circle
85
- cx="10"
86
- cy="10"
87
- r="8"
88
- fill="none"
89
- stroke={
90
- hasError
91
- ? theme.palette.error.light
92
- : theme.palette.success.main
93
- }
94
- strokeWidth="2"
95
- opacity={0.3}
96
- style={{
97
- transition: "stroke 0.8s ease-in-out, opacity 2s ease-in-out",
98
- }}
99
- />
100
- <circle
101
- cx="10"
102
- cy="10"
103
- r="8"
104
- fill="none"
105
- stroke={
106
- hasError
107
- ? theme.palette.error.light
108
- : theme.palette.success.main
109
- }
110
- strokeWidth="2"
111
- strokeLinecap="round"
112
- strokeDasharray={`${2 * Math.PI * 8}`}
113
- strokeDashoffset={`${2 * Math.PI * 8 * (1 - currentProgress / 100)}`}
114
- style={{
115
- transition:
116
- "stroke-dashoffset 0.1s ease-out, stroke 0.8s ease-in-out, opacity 2s ease-in-out",
117
- }}
118
- />
119
- </svg>
120
- </Box>
121
-
122
- {/* Timer text display */}
123
- <Typography
124
- variant="body2"
125
- sx={{
126
- color: hasError
127
- ? theme.palette.error.light
128
- : theme.palette.text.primary,
129
- fontSize: "14px",
130
- lineHeight: "normal",
131
- letterSpacing: "normal",
132
- transition:
133
- "color 0.8s ease-in-out, font-size 0.3s ease-out, opacity 2s ease-in-out",
134
- }}
135
- >
136
- {hasError ? t("timer.error") : formatTime(elapsedTime)}
137
- </Typography>
138
- </Box>
139
- )
140
- }
@@ -1,101 +0,0 @@
1
- import { observer } from "mobx-react-lite"
2
- import { useEffect } from "react"
3
- import { externalizeComponent } from "../../externalizeComponent"
4
- import { TimerDefaultVariant } from "./TimerDefaultVariant"
5
- import { TimerSmallVariant } from "./TimerSmallVariant"
6
- import type { TimerProps } from "./types"
7
- import { useTimerAnimations } from "./useTimerAnimations"
8
- import { useTimerLogic } from "./useTimerLogic"
9
-
10
- /**
11
- * A simple count-up timer component with visual progress indication
12
- *
13
- * Features:
14
- * - Count-up timer that tracks elapsed time
15
- * - Visual progress gauge that cycles every minute
16
- * - Two display variants: large circular gauge (default) or small icon with text
17
- * - Full timer control: start, pause, resume, reset functionality
18
- * - Support for starting with elapsed time (resume mid-session)
19
- * - Error state support: pauses timer and shows error styling
20
- * - Smooth progress animations with spring physics
21
- * - Fully localized with i18next
22
- * - Material-UI theming integration
23
- */
24
- export const Timer = externalizeComponent(
25
- observer(
26
- ({
27
- onTimerReady,
28
- autoStart = true,
29
- variant = "default",
30
- compact = false,
31
- className,
32
- hasError = false,
33
- }: TimerProps) => {
34
- // Initialize animation hooks
35
- const {
36
- animationState,
37
- triggerPauseAnimation,
38
- triggerErrorAnimation,
39
- clearErrorAnimation,
40
- setInitialAnimationState,
41
- cleanup,
42
- } = useTimerAnimations()
43
-
44
- // Initialize timer logic
45
- const { timerState, controls } = useTimerLogic({
46
- autoStart,
47
- hasError,
48
- onPauseAnimation: triggerPauseAnimation,
49
- onErrorAnimation: triggerErrorAnimation,
50
- onClearErrorAnimation: clearErrorAnimation,
51
- })
52
-
53
- // Set initial animation state
54
- useEffect(() => {
55
- setInitialAnimationState()
56
- }, [setInitialAnimationState])
57
-
58
- // Provide controls to parent component
59
- useEffect(() => {
60
- let isMounted = true
61
- const timeoutId = setTimeout(() => {
62
- if (isMounted) {
63
- onTimerReady(controls)
64
- }
65
- }, 0)
66
-
67
- return () => {
68
- isMounted = false
69
- clearTimeout(timeoutId)
70
- }
71
- }, [onTimerReady, controls])
72
-
73
- // Cleanup on unmount
74
- useEffect(() => {
75
- return cleanup
76
- }, [cleanup])
77
-
78
- // Render appropriate variant
79
- if (variant === "small") {
80
- return (
81
- <TimerSmallVariant
82
- timerState={timerState}
83
- animationState={animationState}
84
- hasError={hasError}
85
- compact={compact}
86
- className={className}
87
- />
88
- )
89
- }
90
-
91
- return (
92
- <TimerDefaultVariant
93
- timerState={timerState}
94
- animationState={animationState}
95
- hasError={hasError}
96
- className={className}
97
- />
98
- )
99
- },
100
- ),
101
- )
@@ -1,38 +0,0 @@
1
- export interface TimerControls {
2
- start: (elapsedSeconds?: number) => void
3
- pause: () => void
4
- resume: () => void
5
- reset: () => void
6
- isPaused: () => boolean
7
- }
8
-
9
- export interface TimerProps {
10
- /**
11
- * Callback that receives the timer control functions
12
- */
13
- onTimerReady: (controls: TimerControls) => void
14
- /** Whether the timer should start automatically when initialized */
15
- autoStart?: boolean
16
- /** Visual variant of the timer */
17
- variant?: "default" | "small"
18
- /** For small variant: whether to show compact display */
19
- compact?: boolean
20
- /** Additional CSS classes */
21
- className?: string
22
- /** Whether the timer is in an error state (pauses timer and shows error styling) */
23
- hasError?: boolean
24
- }
25
-
26
- export interface TimerState {
27
- elapsedTime: number
28
- isRunning: boolean
29
- isPausedState: boolean
30
- currentProgress: number
31
- wasRunningBeforeError: boolean
32
- }
33
-
34
- export interface TimerAnimationState {
35
- showPauseAnimation: boolean
36
- showErrorAnimation: boolean
37
- showMainText: boolean
38
- }
@@ -1,94 +0,0 @@
1
- import { useCallback, useRef, useState } from "react"
2
- import type { TimerAnimationState } from "./types"
3
-
4
- export const useTimerAnimations = () => {
5
- const [animationState, setAnimationState] = useState<TimerAnimationState>({
6
- showPauseAnimation: false,
7
- showErrorAnimation: false,
8
- showMainText: true,
9
- })
10
-
11
- // Refs for managing timeouts
12
- const pauseAnimationTimeoutRef = useRef<NodeJS.Timeout | null>(null)
13
- const errorAnimationTimeoutRef = useRef<NodeJS.Timeout | null>(null)
14
- const fadeTimeoutRef = useRef<NodeJS.Timeout | null>(null)
15
-
16
- const triggerPauseAnimation = useCallback(() => {
17
- setAnimationState((prev) => ({ ...prev, showPauseAnimation: true }))
18
-
19
- if (pauseAnimationTimeoutRef.current) {
20
- clearTimeout(pauseAnimationTimeoutRef.current)
21
- }
22
-
23
- pauseAnimationTimeoutRef.current = setTimeout(() => {
24
- setAnimationState((prev) => ({ ...prev, showPauseAnimation: false }))
25
- }, 800)
26
- }, [])
27
-
28
- const triggerErrorAnimation = useCallback(() => {
29
- setAnimationState((prev) => ({ ...prev, showErrorAnimation: true }))
30
-
31
- if (errorAnimationTimeoutRef.current) {
32
- clearTimeout(errorAnimationTimeoutRef.current)
33
- }
34
-
35
- errorAnimationTimeoutRef.current = setTimeout(() => {
36
- setAnimationState((prev) => ({ ...prev, showErrorAnimation: false }))
37
- }, 600)
38
- }, [])
39
-
40
- const clearErrorAnimation = useCallback(() => {
41
- setAnimationState((prev) => ({ ...prev, showErrorAnimation: false }))
42
- if (errorAnimationTimeoutRef.current) {
43
- clearTimeout(errorAnimationTimeoutRef.current)
44
- }
45
- }, [])
46
-
47
- const triggerFadeTransition = useCallback(() => {
48
- setAnimationState((prev) => ({
49
- ...prev,
50
- showMainText: false,
51
- }))
52
-
53
- if (fadeTimeoutRef.current) {
54
- clearTimeout(fadeTimeoutRef.current)
55
- }
56
-
57
- fadeTimeoutRef.current = setTimeout(() => {
58
- setAnimationState((prev) => ({
59
- ...prev,
60
- showMainText: true,
61
- }))
62
- }, 200)
63
- }, [])
64
-
65
- const setInitialAnimationState = useCallback(() => {
66
- setAnimationState((prev) => ({
67
- ...prev,
68
- showMainText: true,
69
- }))
70
- }, [])
71
-
72
- // Cleanup function
73
- const cleanup = useCallback(() => {
74
- if (pauseAnimationTimeoutRef.current) {
75
- clearTimeout(pauseAnimationTimeoutRef.current)
76
- }
77
- if (errorAnimationTimeoutRef.current) {
78
- clearTimeout(errorAnimationTimeoutRef.current)
79
- }
80
- if (fadeTimeoutRef.current) {
81
- clearTimeout(fadeTimeoutRef.current)
82
- }
83
- }, [])
84
-
85
- return {
86
- animationState,
87
- triggerPauseAnimation,
88
- triggerErrorAnimation,
89
- clearErrorAnimation,
90
- triggerFadeTransition,
91
- setInitialAnimationState,
92
- cleanup,
93
- }
94
- }