this.gui 1.0.16 → 1.0.18

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 (104) hide show
  1. package/README.md +191 -23
  2. package/dist/style.css +1 -1
  3. package/dist/this-gui.es.js +2879 -1945
  4. package/dist/this-gui.umd.js +24 -24
  5. package/package.json +3 -4
  6. package/src/App.jsx +19 -40
  7. package/src/CreatePage.jsx +61 -0
  8. package/src/MDXEditor.jsx +51 -0
  9. package/src/Page.jsx +28 -0
  10. package/src/PageDashboard.jsx +56 -0
  11. package/src/SiteBuilder.jsx +95 -26
  12. package/src/example.json +43 -0
  13. package/src/scripts/ComponentRegistry.js +70 -0
  14. package/src/scripts/postinstall.js +60 -10
  15. package/src/scripts/renderComponents.js +11 -0
  16. package/src/stories/Atoms/Badge/Badge.css +1 -0
  17. package/src/stories/Atoms/Badge/Badge.stories.jsx +1 -0
  18. package/src/stories/Atoms/Button/Button.css +259 -58
  19. package/src/stories/Atoms/Button/Button.jsx +8 -11
  20. package/src/stories/Atoms/Button/Button.stories.jsx +65 -40
  21. package/src/stories/Atoms/Container/Container.css +420 -39
  22. package/src/stories/Atoms/Container/Container.jsx +98 -36
  23. package/src/stories/Atoms/Container/Container.stories.jsx +120 -79
  24. package/src/stories/Atoms/Grid/Grid.css +160 -0
  25. package/src/stories/Atoms/Grid/Grid.jsx +43 -0
  26. package/src/stories/Atoms/Grid/Grid.stories.jsx +84 -0
  27. package/src/stories/Atoms/Link/Link.css +6 -26
  28. package/src/stories/Atoms/Link/Link.jsx +11 -21
  29. package/src/stories/Atoms/ProgressBar/ProgressBar.css +1 -1
  30. package/src/stories/Atoms/ProgressBar/ProgressBar.jsx +1 -1
  31. package/src/stories/Atoms/ProgressBar/ProgressBar.stories.jsx +1 -1
  32. package/src/stories/Atoms/Section/Section.css +268 -0
  33. package/src/stories/Atoms/Section/Section.jsx +63 -0
  34. package/src/stories/Atoms/Section/Section.stories.jsx +46 -0
  35. package/src/stories/Atoms/TextArea/TextArea.css +1 -0
  36. package/src/stories/Atoms/TextArea/TextArea.jsx +1 -0
  37. package/src/stories/Atoms/TextArea/TextArea.stories.jsx +1 -0
  38. package/src/stories/Atoms/TextInput/TextInput.css +1 -0
  39. package/src/stories/Atoms/TextInput/TextInput.jsx +1 -0
  40. package/src/stories/Atoms/TextInput/TextInput.stories.jsx +1 -0
  41. package/src/stories/Atoms/Toggle/Toggle.css +1 -0
  42. package/src/stories/Atoms/Toggle/Toggle.jsx +1 -0
  43. package/src/stories/Atoms/Toggle/Toggle.stories.jsx +1 -0
  44. package/src/stories/Atoms/Tooltip/Tooltip.css +1 -0
  45. package/src/stories/Atoms/Tooltip/Tooltip.jsx +1 -0
  46. package/src/stories/Atoms/Tooltip/Tooltip.stories.jsx +1 -0
  47. package/src/stories/Atoms/Video/Video.css +1 -0
  48. package/src/stories/Atoms/Video/Video.jsx +1 -0
  49. package/src/stories/Atoms/Video/Video.stories.jsx +1 -0
  50. package/src/stories/Atoms/index.js +4 -0
  51. package/src/stories/Atoms/meta_Atoms.js +4 -1
  52. package/src/stories/Layouts/Accordion/Accordion.css +285 -8
  53. package/src/stories/Layouts/Accordion/Accordion.jsx +62 -19
  54. package/src/stories/Layouts/Accordion/Accordion.stories.jsx +30 -19
  55. package/src/stories/Layouts/index.js +0 -6
  56. package/src/stories/Layouts/meta_Layouts.js +2 -5
  57. package/src/stories/Molecules/Accordion/Accordion.css +1 -1
  58. package/src/stories/Molecules/Accordion/Accordion.jsx +1 -1
  59. package/src/stories/Molecules/Accordion/Accordion.stories.jsx +1 -1
  60. package/src/stories/Molecules/AudioPlayer/AudioPlayer.css +95 -2
  61. package/src/stories/Molecules/AudioPlayer/AudioPlayer.jsx +232 -13
  62. package/src/stories/Molecules/AudioPlayer/AudioPlayer.stories.jsx +46 -11
  63. package/src/stories/Molecules/AvatarWithName/AvatarWithName.css +128 -2
  64. package/src/stories/Molecules/AvatarWithName/AvatarWithName.jsx +69 -14
  65. package/src/stories/Molecules/AvatarWithName/AvatarWithName.stories.jsx +12 -12
  66. package/src/stories/Molecules/Breadcrumbs/Breadcrumbs.css +145 -2
  67. package/src/stories/Molecules/Breadcrumbs/Breadcrumbs.jsx +39 -13
  68. package/src/stories/Molecules/Breadcrumbs/Breadcrumbs.stories.jsx +27 -11
  69. package/src/stories/Molecules/ButtonGroup/ButtonGroup.css +463 -2
  70. package/src/stories/Molecules/ButtonGroup/ButtonGroup.jsx +34 -12
  71. package/src/stories/Molecules/ButtonGroup/ButtonGroup.stories.jsx +36 -12
  72. package/src/stories/Molecules/Card/Card.css +39 -2
  73. package/src/stories/Molecules/Card/Card.jsx +80 -13
  74. package/src/stories/Molecules/Card/Card.stories.jsx +27 -13
  75. package/src/stories/Molecules/ComparisonTable/ComparisonTable.css +33 -2
  76. package/src/stories/Molecules/ComparisonTable/ComparisonTable.jsx +91 -12
  77. package/src/stories/Molecules/ComparisonTable/ComparisonTable.stories.jsx +73 -12
  78. package/src/stories/Molecules/Dropdown/Dropdown.css +192 -0
  79. package/src/stories/Molecules/Dropdown/Dropdown.jsx +96 -0
  80. package/src/stories/Molecules/Dropdown/Dropdown.stories.jsx +45 -0
  81. package/src/stories/Molecules/index.js +2 -1
  82. package/src/stories/Molecules/meta_Molecules.js +6 -3
  83. package/src/themes/styles/neurons/light.css +94 -204
  84. package/dist/Styles.md +0 -446
  85. package/dist/context.md +0 -942
  86. package/src/Theme.jsx +0 -28
  87. package/src/components/CodeBlock.jsx +0 -22
  88. package/src/components/ComponentFactory.jsx +0 -36
  89. package/src/components/ComponentRegistry.js +0 -21
  90. package/src/scripts/generateComponents.js +0 -166
  91. package/src/scripts/verifyLayouts.js +0 -175
  92. package/src/scripts/verifyMolecules.js +0 -158
  93. package/src/scripts/verifyTemplates.js +0 -154
  94. package/src/scripts/verify_and_install_atoms.js +0 -211
  95. package/src/stories/Layouts/DropdownMenu/DropdownMenu.css +0 -16
  96. package/src/stories/Layouts/DropdownMenu/DropdownMenu.jsx +0 -31
  97. package/src/stories/Layouts/DropdownMenu/DropdownMenu.stories.jsx +0 -28
  98. package/src/stories/Layouts/Grid/Grid.css +0 -4
  99. package/src/stories/Layouts/Grid/Grid.jsx +0 -13
  100. package/src/stories/Layouts/Grid/Grid.stories.jsx +0 -28
  101. package/src/stories/Layouts/Section/Section.css +0 -16
  102. package/src/stories/Layouts/Section/Section.jsx +0 -31
  103. package/src/stories/Layouts/Section/Section.stories.jsx +0 -28
  104. /package/src/themes/{README.md → README_Styles.md} +0 -0
@@ -1,25 +1,244 @@
1
-
2
- import React from 'react';
1
+ //this.GUI/src/stories/Molecules/AudioPlayer/AudioPlayer.jsx
2
+ import React, { useRef, useState, useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
+ import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaStepForward, FaStepBackward } from 'react-icons/fa';
4
5
  import './AudioPlayer.css';
5
6
 
6
- /**
7
- * AudioPlayer component
8
- */
9
- export const AudioPlayer = (props) => {
7
+ export const AudioPlayer = ({
8
+ playlist,
9
+ autoPlay = false,
10
+ loop = false,
11
+ muted = false,
12
+ size = 'medium',
13
+ color = 'classy-color-1',
14
+ className = '',
15
+ style = {},
16
+ showMedia = true,
17
+ ...props
18
+ }) => {
19
+ const audioRef = useRef(null);
20
+ const [isPlaying, setIsPlaying] = useState(autoPlay);
21
+ const [isMuted, setIsMuted] = useState(muted);
22
+ const [volume, setVolume] = useState(muted ? 0 : 1);
23
+ const [currentTime, setCurrentTime] = useState(0);
24
+ const [duration, setDuration] = useState(0);
25
+ const [currentTrack, setCurrentTrack] = useState(playlist[0]);
26
+ const [currentTrackIndex, setCurrentTrackIndex] = useState(0);
27
+
28
+ useEffect(() => {
29
+ const audio = audioRef.current;
30
+ if (audio) {
31
+ audio.volume = volume;
32
+ audio.muted = isMuted;
33
+ if (autoPlay) {
34
+ audio.play().catch(() => setIsPlaying(false));
35
+ }
36
+ }
37
+ }, [volume, isMuted, autoPlay, currentTrack]);
38
+
39
+ const togglePlayPause = () => {
40
+ const audio = audioRef.current;
41
+ if (!audio) return;
42
+
43
+ if (isPlaying) {
44
+ audio.pause();
45
+ } else {
46
+ audio.play().catch(() => setIsPlaying(false));
47
+ }
48
+ setIsPlaying(!isPlaying);
49
+ };
50
+
51
+ const handleTimeUpdate = () => {
52
+ const audio = audioRef.current;
53
+ if (audio) {
54
+ setCurrentTime(audio.currentTime);
55
+ }
56
+ };
57
+
58
+ const handleLoadedMetadata = () => {
59
+ const audio = audioRef.current;
60
+ if (audio) {
61
+ setDuration(audio.duration);
62
+ }
63
+ };
64
+
65
+ const handleVolumeChange = (e) => {
66
+ const newVolume = parseFloat(e.target.value);
67
+ setVolume(newVolume);
68
+ setIsMuted(newVolume === 0);
69
+ };
70
+
71
+ const toggleMute = () => {
72
+ setIsMuted(!isMuted);
73
+ setVolume(!isMuted ? 0 : 1);
74
+ };
75
+
76
+ const handleSeekChange = (e) => {
77
+ const seekTime = parseFloat(e.target.value);
78
+ const audio = audioRef.current;
79
+ if (audio) {
80
+ audio.currentTime = seekTime;
81
+ setCurrentTime(seekTime);
82
+ }
83
+ };
84
+
85
+ const formatTime = (time) => {
86
+ if (isNaN(time)) return '00:00';
87
+ const minutes = Math.floor(time / 60);
88
+ const seconds = Math.floor(time % 60);
89
+ const paddedSeconds = seconds < 10 ? `0${seconds}` : seconds;
90
+ return `${minutes}:${paddedSeconds}`;
91
+ };
92
+
93
+ const nextTrack = () => {
94
+ const nextIndex = (currentTrackIndex + 1) % playlist.length;
95
+ setCurrentTrackIndex(nextIndex);
96
+ setCurrentTrack(playlist[nextIndex]);
97
+ };
98
+
99
+ const prevTrack = () => {
100
+ const prevIndex = (currentTrackIndex - 1 + playlist.length) % playlist.length;
101
+ setCurrentTrackIndex(prevIndex);
102
+ setCurrentTrack(playlist[prevIndex]);
103
+ };
104
+
105
+ const handleTrackClick = (track, index) => {
106
+ setCurrentTrack(track);
107
+ setCurrentTrackIndex(index);
108
+ setIsPlaying(false); // Reset play state to allow clicking a new track.
109
+ };
110
+
111
+ const variantClass = `audio-player--${size}`;
112
+ const colorClass = `audio-player--${color}`;
113
+ const combinedClassName = `audio-player ${variantClass} ${colorClass} ${className}`.trim();
114
+
10
115
  return (
11
- <div className="audioplayer" {...props}>
12
- {/* Component implementation */}
116
+ <div className={combinedClassName} style={style} {...props}>
117
+ {showMedia && currentTrack.image && (
118
+ <div className="audio-player__media">
119
+ <img src={currentTrack.image} alt={currentTrack.title} />
120
+ </div>
121
+ )}
122
+
123
+ {/* Display Track Name Above Timeline */}
124
+ <div className="audio-player__track-name">{currentTrack.title}</div>
125
+
126
+ <div className="audio-player__controls">
127
+ <audio
128
+ ref={audioRef}
129
+ src={currentTrack.src}
130
+ loop={loop}
131
+ onTimeUpdate={handleTimeUpdate}
132
+ onLoadedMetadata={handleLoadedMetadata}
133
+ onEnded={nextTrack}
134
+ >
135
+ Your browser does not support the audio element.
136
+ </audio>
137
+ <button
138
+ className="audio-player__prev"
139
+ onClick={prevTrack}
140
+ aria-label="Previous Track"
141
+ >
142
+ <FaStepBackward />
143
+ </button>
144
+ <button
145
+ className="audio-player__play-pause"
146
+ onClick={togglePlayPause}
147
+ aria-label={isPlaying ? 'Pause' : 'Play'}
148
+ >
149
+ {isPlaying ? <FaPause /> : <FaPlay />}
150
+ </button>
151
+ <button
152
+ className="audio-player__next"
153
+ onClick={nextTrack}
154
+ aria-label="Next Track"
155
+ >
156
+ <FaStepForward />
157
+ </button>
158
+ </div>
159
+
160
+ {/* Timeline with Seek and Time */}
161
+ <div className="audio-player__seek">
162
+ <input
163
+ type="range"
164
+ className="audio-player__seek-slider"
165
+ min="0"
166
+ max={duration}
167
+ step="0.1"
168
+ value={currentTime}
169
+ onChange={handleSeekChange}
170
+ aria-label="Seek Slider"
171
+ />
172
+ <div className="audio-player__time">{formatTime(currentTime)} / {formatTime(duration)}</div>
173
+ </div>
174
+
175
+ <div className="audio-player__volume-container">
176
+ <button
177
+ className="audio-player__mute"
178
+ onClick={toggleMute}
179
+ aria-label={isMuted ? 'Unmute' : 'Mute'}
180
+ >
181
+ {isMuted ? <FaVolumeMute /> : <FaVolumeUp />}
182
+ </button>
183
+ <input
184
+ type="range"
185
+ className="audio-player__volume-slider"
186
+ min="0"
187
+ max="1"
188
+ step="0.01"
189
+ value={isMuted ? 0 : volume}
190
+ onChange={handleVolumeChange}
191
+ aria-label="Volume Slider"
192
+ />
193
+ </div>
194
+
195
+ {/* Playlist with Border */}
196
+ <div className="audio-player__playlist">
197
+ <ul>
198
+ {playlist.map((track, index) => (
199
+ <li
200
+ key={index}
201
+ className={`audio-player__track ${index === currentTrackIndex ? 'active' : ''}`}
202
+ onClick={() => handleTrackClick(track, index)}
203
+ >
204
+ {track.title}
205
+ </li>
206
+ ))}
207
+ </ul>
208
+ </div>
13
209
  </div>
14
210
  );
15
211
  };
16
212
 
17
213
  AudioPlayer.propTypes = {
18
- // Define prop types here
214
+ playlist: PropTypes.arrayOf(
215
+ PropTypes.shape({
216
+ src: PropTypes.string.isRequired,
217
+ title: PropTypes.string.isRequired,
218
+ image: PropTypes.string, // Optional album cover or media
219
+ })
220
+ ).isRequired,
221
+ autoPlay: PropTypes.bool,
222
+ loop: PropTypes.bool,
223
+ muted: PropTypes.bool,
224
+ size: PropTypes.oneOf(['small', 'medium']),
225
+ color: PropTypes.oneOf([
226
+ 'classy-color-1', 'classy-color-2', 'classy-color-3', 'classy-color-4', 'classy-color-5',
227
+ 'small-switch-color-1', 'small-switch-color-2',
228
+ 'natural-color-1', 'natural-color-2', 'natural-color-3',
229
+ 'grey-friend-1', 'grey-friend-2',
230
+ 'shade-1', 'shade-2', 'shade-3', 'shade-4',
231
+ ]),
232
+ className: PropTypes.string,
233
+ style: PropTypes.object,
234
+ showMedia: PropTypes.bool,
19
235
  };
20
236
 
21
237
  AudioPlayer.defaultProps = {
22
- // Define default props here
23
- };
24
-
25
- export default AudioPlayer;
238
+ autoPlay: false,
239
+ loop: false,
240
+ muted: false,
241
+ size: 'medium',
242
+ color: 'classy-color-1',
243
+ showMedia: true,
244
+ };
@@ -1,20 +1,55 @@
1
-
1
+ //this.GUI/src/stories/Molecules/AudioPlayer/AudioPlayer.stories.jsx
2
+ import React from 'react';
2
3
  import { AudioPlayer } from './AudioPlayer';
4
+ import './AudioPlayer.css';
3
5
 
4
- // Storybook configuration for AudioPlayer component
5
6
  export default {
6
- title: 'Molecules/MediaMolecules/AudioPlayer',
7
+ title: 'Molecules/Media/AudioPlayer',
7
8
  component: AudioPlayer,
8
- parameters: {
9
- layout: 'centered',
10
- },
11
9
  argTypes: {
12
- // Define argTypes here
10
+ autoPlay: { control: 'boolean', defaultValue: false },
11
+ loop: { control: 'boolean', defaultValue: false },
12
+ muted: { control: 'boolean', defaultValue: false },
13
+ size: {
14
+ control: 'select',
15
+ options: ['small', 'medium'],
16
+ defaultValue: 'medium',
17
+ },
18
+ color: {
19
+ control: 'select',
20
+ options: [
21
+ 'classy-color-1', 'classy-color-2', 'classy-color-3', 'classy-color-4', 'classy-color-5',
22
+ 'small-switch-color-1', 'small-switch-color-2',
23
+ 'natural-color-1', 'natural-color-2', 'natural-color-3',
24
+ 'grey-friend-1', 'grey-friend-2',
25
+ 'shade-1', 'shade-2', 'shade-3', 'shade-4',
26
+ ],
27
+ defaultValue: 'classy-color-1',
28
+ },
29
+ showMedia: { control: 'boolean', defaultValue: true },
13
30
  },
14
31
  };
15
32
 
16
- export const Default = {
17
- args: {
18
- // Define default args here
33
+ const playlist = [
34
+ {
35
+ src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
36
+ title: 'Track 1',
37
+ image: 'https://via.placeholder.com/150?text=Track+1',
19
38
  },
20
- };
39
+ {
40
+ src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3',
41
+ title: 'Track 2',
42
+ image: 'https://via.placeholder.com/150?text=Track+2',
43
+ },
44
+ {
45
+ src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3',
46
+ title: 'Track 3',
47
+ image: 'https://via.placeholder.com/150?text=Track+3',
48
+ },
49
+ ];
50
+
51
+ export const DefaultAudioPlayer = () => <AudioPlayer playlist={playlist} />;
52
+ export const SmallAudioPlayer = () => <AudioPlayer size="small" playlist={playlist} />;
53
+ export const AutoplayAudioPlayer = () => <AudioPlayer autoPlay playlist={playlist} />;
54
+ export const AudioPlayerWithoutMedia = () => <AudioPlayer showMedia={false} playlist={playlist} />;
55
+ export const LoopingAudioPlayer = () => <AudioPlayer loop playlist={playlist} />;
@@ -1,4 +1,130 @@
1
+ /* this.GUI/src/stories/Molecules/AvatarWithName/AvatarWithName.css */
2
+ /* Base Styles */
3
+ .avatar-with-name {
4
+ display: inline-flex; /* This ensures that it behaves like an inline element */
5
+ align-items: center;
6
+ gap: 8px; /* Reduced gap between the avatar and the name */
7
+ cursor: pointer;
8
+ }
9
+
10
+ /* Ensure no auto-centering or alignment issues */
11
+ .avatar-with-name--below {
12
+ flex-direction: column; /* Stack the name below the avatar */
13
+ align-items: center; /* Keep the avatar and name centered with respect to each other */
14
+ text-align: center;
15
+ }
16
+
17
+ .avatar-with-name--side {
18
+ flex-direction: row; /* Place the name next to the avatar */
19
+ text-align: left; /* Ensure text is aligned correctly when the name is to the side */
20
+ align-items: center; /* Keep the avatar and name aligned vertically */
21
+ }
22
+
23
+ /* Size Variants */
24
+ .avatar-with-name--small .avatar-with-name__avatar img,
25
+ .avatar-with-name--small .avatar-with-name__avatar svg {
26
+ width: 40px;
27
+ height: 40px;
28
+ }
29
+
30
+ .avatar-with-name--medium .avatar-with-name__avatar img,
31
+ .avatar-with-name--medium .avatar-with-name__avatar svg {
32
+ width: 80px;
33
+ height: 80px;
34
+ }
35
+
36
+ .avatar-with-name--large .avatar-with-name__avatar img,
37
+ .avatar-with-name--large .avatar-with-name__avatar svg {
38
+ width: 120px;
39
+ height: 120px;
40
+ }
41
+
42
+ /* Name styling */
43
+ .avatar-with-name__name {
44
+ font-size: 1.1rem;
45
+ color: var(--text-color, #2C2C2C);
46
+ margin-top: 2px;
47
+ }
48
+
49
+ /* Avatar styling */
50
+ .avatar-with-name__avatar {
51
+ border-radius: 50%;
52
+ object-fit: cover;
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ background-color: #f0f0f0;
57
+ overflow: hidden;
58
+ }
1
59
 
2
- .avatarwithname {
3
- /* Default styles for AvatarWithName */
60
+ .avatar__default-icon {
61
+ width: 100%;
62
+ height: 100%;
4
63
  }
64
+
65
+ /* Modal Styles */
66
+ .avatar-modal {
67
+ position: fixed;
68
+ top: 0;
69
+ left: 0;
70
+ width: 100%;
71
+ height: 100%;
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ background-color: rgba(0, 0, 0, 0.5);
76
+ z-index: 1000;
77
+ }
78
+
79
+ .avatar-modal__content {
80
+ background-color: white;
81
+ padding: 16px;
82
+ border-radius: 8px;
83
+ text-align: center;
84
+ position: relative;
85
+ max-width: 300px;
86
+ width: 100%;
87
+ }
88
+
89
+ .avatar-modal__avatar-container {
90
+ display: flex;
91
+ justify-content: center; /* Center the avatar in the modal */
92
+ align-items: center;
93
+ }
94
+
95
+ .avatar-modal__avatar {
96
+ width: 150px;
97
+ height: 150px;
98
+ border-radius: 50%;
99
+ }
100
+
101
+ .avatar-modal__name {
102
+ margin-top: 16px;
103
+ font-size: 1.5rem;
104
+ font-weight: bold;
105
+ color: var(--text-color, #2C2C2C);
106
+ }
107
+
108
+ .avatar-modal__close {
109
+ position: absolute;
110
+ top: 10px;
111
+ right: 10px;
112
+ background: none;
113
+ border: none;
114
+ font-size: 1.5rem;
115
+ cursor: pointer;
116
+ }
117
+
118
+ /* Responsive Adjustments */
119
+ @media (max-width: 768px) {
120
+ .avatar-with-name--large .avatar-with-name__avatar img,
121
+ .avatar-with-name--large .avatar-with-name__avatar svg {
122
+ width: 100px;
123
+ height: 100px;
124
+ }
125
+
126
+ .avatar-modal__avatar {
127
+ width: 120px;
128
+ height: 120px;
129
+ }
130
+ }
@@ -1,25 +1,80 @@
1
-
2
- import React from 'react';
1
+ //this.GUI/src/stories/Molecules/AvatarWithName/AvatarWithName.jsx
2
+ import React, { useState } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import './AvatarWithName.css';
5
5
 
6
- /**
7
- * AvatarWithName component
8
- */
9
- export const AvatarWithName = (props) => {
6
+ const defaultAvatar = (
7
+ <svg
8
+ className="avatar__default-icon"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ viewBox="0 0 24 24"
11
+ fill="none"
12
+ stroke="currentColor"
13
+ strokeWidth="2"
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ >
17
+ <circle cx="12" cy="12" r="10"></circle>
18
+ <path d="M14.5 9a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"></path>
19
+ <path d="M12 14c-3.03 0-5.47 1.21-6 3h12c-.53-1.79-2.97-3-6-3z"></path>
20
+ </svg>
21
+ );
22
+
23
+ export const AvatarWithName = ({ imageSrc, name, namePosition, size, onClick }) => {
24
+ const [showModal, setShowModal] = useState(false);
25
+
26
+ const handleModalToggle = () => {
27
+ setShowModal(!showModal);
28
+ };
29
+
10
30
  return (
11
- <div className="avatarwithname" {...props}>
12
- {/* Component implementation */}
13
- </div>
31
+ <>
32
+ <div
33
+ className={`avatar-with-name avatar-with-name--${namePosition} avatar-with-name--${size}`}
34
+ onClick={handleModalToggle}
35
+ >
36
+ <div className="avatar-with-name__avatar">
37
+ {imageSrc ? (
38
+ <img src={imageSrc} alt={name} />
39
+ ) : (
40
+ defaultAvatar /* Display the default avatar if no imageSrc is provided */
41
+ )}
42
+ </div>
43
+ <div className="avatar-with-name__name">{name}</div>
44
+ </div>
45
+
46
+ {showModal && (
47
+ <div className="avatar-modal" onClick={handleModalToggle}>
48
+ <div className="avatar-modal__content" onClick={(e) => e.stopPropagation()}>
49
+ <button className="avatar-modal__close" onClick={handleModalToggle}>
50
+ &times;
51
+ </button>
52
+ <div className="avatar-modal__avatar-container">
53
+ <div className="avatar-modal__avatar">
54
+ {imageSrc ? (
55
+ <img src={imageSrc} alt={name} />
56
+ ) : (
57
+ defaultAvatar /* Use the default avatar in the modal if no imageSrc is provided */
58
+ )}
59
+ </div>
60
+ </div>
61
+ <div className="avatar-modal__name">{name}</div>
62
+ </div>
63
+ </div>
64
+ )}
65
+ </>
14
66
  );
15
67
  };
16
68
 
17
69
  AvatarWithName.propTypes = {
18
- // Define prop types here
70
+ imageSrc: PropTypes.string, // Image URL for the avatar
71
+ name: PropTypes.string.isRequired, // The name to display
72
+ namePosition: PropTypes.oneOf(['below', 'side']), // Position of the name relative to the avatar
73
+ size: PropTypes.oneOf(['small', 'medium', 'large']), // Size of the avatar
74
+ onClick: PropTypes.func, // Function to execute on click
19
75
  };
20
76
 
21
77
  AvatarWithName.defaultProps = {
22
- // Define default props here
23
- };
24
-
25
- export default AvatarWithName;
78
+ namePosition: 'below',
79
+ size: 'medium',
80
+ };
@@ -1,20 +1,20 @@
1
-
1
+ //this.GUI/src/stories/Molecules/AvatarWithName/AvatarWithName.stories.jsx
2
+ import React from 'react';
2
3
  import { AvatarWithName } from './AvatarWithName';
3
4
 
4
- // Storybook configuration for AvatarWithName component
5
5
  export default {
6
- title: 'Molecules/MediaMolecules/AvatarWithName',
6
+ title: 'Molecules/Display/AvatarWithName',
7
7
  component: AvatarWithName,
8
- parameters: {
9
- layout: 'centered',
10
- },
11
8
  argTypes: {
12
- // Define argTypes here
9
+ imageSrc: { control: 'text', defaultValue: 'https://via.placeholder.com/150' },
10
+ name: { control: 'text', defaultValue: 'John Doe' },
11
+ namePosition: { control: 'select', options: ['below', 'side'], defaultValue: 'below' },
12
+ size: { control: 'select', options: ['small', 'medium', 'large'], defaultValue: 'medium' },
13
13
  },
14
14
  };
15
15
 
16
- export const Default = {
17
- args: {
18
- // Define default args here
19
- },
20
- };
16
+ export const Default = (args) => <AvatarWithName {...args} />;
17
+
18
+ export const SideName = (args) => <AvatarWithName {...args} namePosition="side" />;
19
+ export const LargeAvatar = (args) => <AvatarWithName {...args} size="large" />;
20
+ export const SmallAvatar = (args) => <AvatarWithName {...args} size="small" />;