@rpg-engine/long-bow 0.6.37 → 0.6.39

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.6.37",
3
+ "version": "0.6.39",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -0,0 +1,41 @@
1
+ import React, { useState } from 'react';
2
+
3
+ export const ZoomableImage: React.FC<{ src: string; alt: string }> = ({
4
+ src,
5
+ alt,
6
+ }) => {
7
+ const [isHovered, setIsHovered] = useState(false);
8
+ const [zoomPosition, setZoomPosition] = useState({ x: 50, y: 50 });
9
+
10
+ const handleMouseMove = (
11
+ e: React.MouseEvent<HTMLImageElement, MouseEvent>
12
+ ) => {
13
+ const {
14
+ left,
15
+ top,
16
+ width,
17
+ height,
18
+ } = e.currentTarget.getBoundingClientRect();
19
+ const x = ((e.clientX - left) / width) * 100;
20
+ const y = ((e.clientY - top) / height) * 100;
21
+ setZoomPosition({ x, y });
22
+ };
23
+
24
+ return (
25
+ <img
26
+ src={src}
27
+ alt={alt}
28
+ onMouseMove={handleMouseMove}
29
+ onMouseEnter={() => setIsHovered(true)}
30
+ onMouseLeave={() => setIsHovered(false)}
31
+ style={{
32
+ width: '100%',
33
+ height: '100%',
34
+ objectFit: 'cover',
35
+ transform: isHovered ? 'scale(1.5)' : 'scale(1)',
36
+ transformOrigin: `${zoomPosition.x}% ${zoomPosition.y}%`,
37
+ transition: 'transform 0.3s ease',
38
+ }}
39
+ />
40
+ );
41
+ };
@@ -19,6 +19,9 @@ interface IStepperProps {
19
19
  };
20
20
  onError?: (message: string) => void;
21
21
  useSideArrows?: boolean; // New prop to control arrow position
22
+ styles?: {
23
+ stepperProgressColor?: string;
24
+ };
22
25
  }
23
26
 
24
27
  export const Stepper: React.FC<IStepperProps> = ({
@@ -26,6 +29,7 @@ export const Stepper: React.FC<IStepperProps> = ({
26
29
  finalCTAButton,
27
30
  onError,
28
31
  useSideArrows = false, // Default to false for backwards compatibility
32
+ styles,
29
33
  }) => {
30
34
  const [currentStep, setCurrentStep] = useState(0);
31
35
 
@@ -101,6 +105,7 @@ export const Stepper: React.FC<IStepperProps> = ({
101
105
  <ProgressIndicator
102
106
  key={i}
103
107
  isActive={i <= currentStep}
108
+ stepperProgressColor={styles?.stepperProgressColor}
104
109
  onClick={() => onStepChange(i)}
105
110
  />
106
111
  ))}
@@ -174,11 +179,14 @@ const StepperFooter = styled.div`
174
179
  align-items: center;
175
180
  `;
176
181
 
177
- const ProgressIndicator = styled.div<{ isActive: boolean }>`
182
+ const ProgressIndicator = styled.div<{
183
+ isActive: boolean;
184
+ stepperProgressColor?: string;
185
+ }>`
178
186
  width: 20px;
179
187
  height: 20px;
180
- background-color: ${({ isActive }) =>
181
- isActive ? uiColors.orange : uiColors.lightGray};
188
+ background-color: ${({ isActive, stepperProgressColor }) =>
189
+ isActive ? stepperProgressColor || uiColors.orange : uiColors.lightGray};
182
190
  margin: 0 5px;
183
191
  transition: background-color 0.3s;
184
192
  opacity: ${({ isActive }) => (isActive ? 1 : 0.25)};
@@ -1,6 +1,7 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import styled, { CSSProperties } from 'styled-components';
3
3
  import { uiColors } from '../../constants/uiColors';
4
+ import { ZoomableImage } from '../Image/ZoomableImage';
4
5
  import { Stepper } from '../Stepper';
5
6
  import { DynamicText } from '../typography/DynamicText';
6
7
 
@@ -27,27 +28,27 @@ export const TutorialStepper = React.memo(
27
28
  <LessonContainer key={index} className="lesson-container">
28
29
  <LessonTitle className="lesson-title">{lesson.title}</LessonTitle>
29
30
  {lesson.image && (
30
- <LessonImage className="lesson-image" style={imageStyle}>
31
- {lesson.imageUrl ? (
32
- <a
33
- href={lesson.imageUrl}
34
- target="_blank"
35
- rel="noopener noreferrer"
36
- >
37
- <img
31
+ <LessonImageWrapper className="lesson-image-wrapper">
32
+ <LessonImage className="lesson-image" style={imageStyle}>
33
+ {lesson.imageUrl ? (
34
+ <a
35
+ href={lesson.imageUrl}
36
+ target="_blank"
37
+ rel="noopener noreferrer"
38
+ >
39
+ <ZoomableImage
40
+ src={lesson.image}
41
+ alt={lesson.title || 'Tutorial image'}
42
+ />
43
+ </a>
44
+ ) : (
45
+ <ZoomableImage
38
46
  src={lesson.image}
39
47
  alt={lesson.title || 'Tutorial image'}
40
- loading="lazy"
41
48
  />
42
- </a>
43
- ) : (
44
- <img
45
- src={lesson.image}
46
- alt={lesson.title || 'Tutorial image'}
47
- loading="lazy"
48
- />
49
- )}
50
- </LessonImage>
49
+ )}
50
+ </LessonImage>
51
+ </LessonImageWrapper>
51
52
  )}
52
53
  <LessonFooter className="lesson-footer">
53
54
  {lesson.body && (
@@ -80,6 +81,35 @@ export const TutorialStepper = React.memo(
80
81
  }
81
82
  );
82
83
 
84
+ const LessonImageWrapper = styled.div`
85
+ width: 100%;
86
+ max-width: 500px;
87
+ margin: 1rem auto;
88
+ aspect-ratio: 16 / 9;
89
+ overflow: hidden;
90
+ border-radius: 10px;
91
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
92
+ `;
93
+
94
+ const LessonImage = styled.div`
95
+ width: 100%;
96
+ height: 100%;
97
+ position: relative;
98
+ `;
99
+
100
+ const LessonContainer = styled.div`
101
+ display: flex;
102
+ flex-direction: column;
103
+ justify-content: flex-start;
104
+ min-height: 200px;
105
+ padding: 1rem;
106
+ padding-top: 0;
107
+
108
+ p {
109
+ font-size: 0.7rem !important;
110
+ }
111
+ `;
112
+
83
113
  const LessonBody = styled.div``;
84
114
 
85
115
  const Container = styled.div`
@@ -95,31 +125,7 @@ const LessonFooter = styled.div`
95
125
  margin-top: 1rem;
96
126
  `;
97
127
 
98
- const LessonImage = styled.div`
99
- display: flex;
100
- justify-content: center;
101
- align-items: center;
102
- width: 100%;
103
- height: auto;
104
- max-width: 500px;
105
- margin: auto;
106
-
107
- img {
108
- max-width: 100%;
109
- max-height: 100%;
110
- object-fit: contain;
111
- border-radius: 10px;
112
- }
113
- `;
114
-
115
128
  const LessonTitle = styled.h1`
116
129
  color: ${uiColors.yellow} !important;
117
130
  font-size: 0.8rem !important;
118
131
  `;
119
-
120
- const LessonContainer = styled.div`
121
- display: flex;
122
- flex-direction: column;
123
- justify-content: space-between;
124
- min-height: 200px; /* Match with StepperBody for consistent height */
125
- `;