@portosaur/theme 0.1.5 → 0.2.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 (31) hide show
  1. package/package.json +10 -3
  2. package/src/plugins/theme.mjs +2 -0
  3. package/theme/DocCategoryGeneratedIndexPage/index.jsx +4 -10
  4. package/theme/MDXComponents.jsx +1 -1
  5. package/theme/Root.jsx +1 -1
  6. package/theme/components/AboutSection/index.jsx +89 -249
  7. package/theme/components/ContactSection/index.jsx +72 -153
  8. package/theme/components/ExperienceSection/index.jsx +35 -106
  9. package/theme/components/HeroSection/index.jsx +64 -186
  10. package/theme/components/NavArrow/index.jsx +38 -55
  11. package/theme/components/NoteIndex/index.jsx +50 -116
  12. package/theme/components/Preview/components/FeedbackStates.jsx +45 -190
  13. package/theme/components/Preview/components/FileTabs.jsx +17 -24
  14. package/theme/components/Preview/components/PreviewContent.jsx +37 -62
  15. package/theme/components/Preview/components/PreviewHeader.jsx +146 -380
  16. package/theme/components/Preview/components/Triggers/Pv.jsx +50 -78
  17. package/theme/components/Preview/components/Triggers/SrcPv.jsx +16 -47
  18. package/theme/components/Preview/components/Triggers/index.jsx +2 -2
  19. package/theme/components/Preview/components/ViewerWindow.jsx +160 -268
  20. package/theme/components/Preview/index.jsx +3 -3
  21. package/theme/components/Preview/renderers/CodeRenderer.jsx +81 -109
  22. package/theme/components/Preview/renderers/ImageRenderer.jsx +30 -67
  23. package/theme/components/Preview/renderers/PdfRenderer.jsx +31 -52
  24. package/theme/components/Preview/renderers/WebRenderer.jsx +18 -32
  25. package/theme/components/Preview/state/index.jsx +46 -30
  26. package/theme/components/ProjectsSection/index.jsx +278 -573
  27. package/theme/components/SocialLinks/index.jsx +43 -55
  28. package/theme/components/Tooltip/index.jsx +28 -39
  29. package/theme/pages/index.jsx +23 -87
  30. package/theme/pages/notes.jsx +26 -104
  31. package/theme/pages/tasks.jsx +220 -903
@@ -5,6 +5,7 @@ import ImageRenderer from "../renderers/ImageRenderer";
5
5
  import PdfRenderer from "../renderers/PdfRenderer";
6
6
  import WebRenderer from "../renderers/WebRenderer";
7
7
  import CodeRenderer from "../renderers/CodeRenderer";
8
+
8
9
  export default function PreviewContent({
9
10
  currentFile,
10
11
  fileType,
@@ -20,84 +21,58 @@ export default function PreviewContent({
20
21
  }) {
21
22
  const path = currentFile?.path;
22
23
  const isExternal = path?.startsWith("http") || path?.startsWith("//");
24
+
23
25
  if (!isOnline && isExternal) {
24
- return jsxDEV_7x81h0kn(
25
- OfflineState,
26
- { onRetry: retryFetch },
27
- undefined,
28
- false,
29
- undefined,
30
- this,
31
- );
26
+ return <OfflineState onRetry={retryFetch} />;
32
27
  }
28
+
33
29
  const errorMsg = fetchErrors?.[path];
34
30
  if (errorMsg) {
35
- return jsxDEV_7x81h0kn(
36
- ErrorState,
37
- { path, message: errorMsg, fileType, fileUrl, onRetry: retryFetch },
38
- undefined,
39
- false,
40
- undefined,
41
- this,
31
+ return (
32
+ <ErrorState
33
+ path={path}
34
+ message={errorMsg}
35
+ fileType={fileType}
36
+ fileUrl={fileUrl}
37
+ onRetry={retryFetch}
38
+ />
42
39
  );
43
40
  }
41
+
44
42
  if (textLoading && fileType === "text") {
45
- return jsxDEV_7x81h0kn(LoadingState, {}, undefined, false, undefined, this);
43
+ return <LoadingState />;
46
44
  }
45
+
47
46
  switch (fileType) {
48
47
  case "image":
49
- return jsxDEV_7x81h0kn(
50
- ImageRenderer,
51
- {
52
- fileUrl,
53
- label: currentFile.label,
54
- zoomLevel,
55
- onError: (msg) => setError(path, msg),
56
- },
57
- fileUrl,
58
- false,
59
- undefined,
60
- this,
48
+ return (
49
+ <ImageRenderer
50
+ fileUrl={fileUrl}
51
+ label={currentFile.label}
52
+ zoomLevel={zoomLevel}
53
+ onError={(msg) => setError(path, msg)}
54
+ />
61
55
  );
62
56
  case "pdf":
63
- return jsxDEV_7x81h0kn(
64
- PdfRenderer,
65
- { fileUrl, zoomLevel, onError: (msg) => setError(path, msg) },
66
- fileUrl,
67
- false,
68
- undefined,
69
- this,
57
+ return (
58
+ <PdfRenderer
59
+ fileUrl={fileUrl}
60
+ zoomLevel={zoomLevel}
61
+ onError={(msg) => setError(path, msg)}
62
+ />
70
63
  );
71
64
  case "web":
72
- return jsxDEV_7x81h0kn(
73
- WebRenderer,
74
- {
75
- fileUrl,
76
- label: currentFile.label,
77
- onError: (msg) => setError(path, msg),
78
- },
79
- fileUrl,
80
- false,
81
- undefined,
82
- this,
65
+ return (
66
+ <WebRenderer
67
+ fileUrl={fileUrl}
68
+ label={currentFile.label}
69
+ onError={(msg) => setError(path, msg)}
70
+ />
83
71
  );
84
72
  default: {
85
- if (!textContent)
86
- return jsxDEV_7x81h0kn(
87
- LoadingState,
88
- {},
89
- undefined,
90
- false,
91
- undefined,
92
- this,
93
- );
94
- return jsxDEV_7x81h0kn(
95
- CodeRenderer,
96
- { code: textContent, language: ext, zoomLevel },
97
- undefined,
98
- false,
99
- undefined,
100
- this,
73
+ if (!textContent) return <LoadingState />;
74
+ return (
75
+ <CodeRenderer code={textContent} language={ext} zoomLevel={zoomLevel} />
101
76
  );
102
77
  }
103
78
  }
@@ -1,12 +1,13 @@
1
1
  import React, { useState, useRef } from "react";
2
- import Tooltip from "../../Tooltip/index.js";
2
+ import Tooltip from "../../Tooltip/index.jsx";
3
3
  import styles from "../styles.module.css";
4
- import { PreviewMode } from "../state/index.js";
5
- import IconDock from "../../../assets/img/svg/icon-dock.svg";
6
- import IconPopup from "../../../assets/img/svg/icon-popup.svg";
7
- import IconSave from "../../../assets/img/svg/icon-save.svg";
8
- import IconLink from "../../../assets/img/svg/icon-link.svg";
9
- import IconClose from "../../../assets/img/svg/icon-close.svg";
4
+ import { PreviewMode } from "../state/index.jsx";
5
+ import IconDock from "../../../../assets/img/svg/icon-dock.svg";
6
+ import IconPopup from "../../../../assets/img/svg/icon-popup.svg";
7
+ import IconSave from "../../../../assets/img/svg/icon-save.svg";
8
+ import IconLink from "../../../../assets/img/svg/icon-link.svg";
9
+ import IconClose from "../../../../assets/img/svg/icon-close.svg";
10
+
10
11
  export default function PreviewHeader({
11
12
  displayTitle,
12
13
  fileType,
@@ -34,378 +35,143 @@ export default function PreviewHeader({
34
35
  : mode === "dock"
35
36
  ? "Open as PiP"
36
37
  : "Dock to side";
37
- return jsxDEV_7x81h0kn(
38
- Fragment_8vg9x3sq,
39
- {
40
- children: [
41
- mode === "dock" &&
42
- !isMobileSize &&
43
- jsxDEV_7x81h0kn(
44
- "div",
45
- {
46
- className: styles.revealHeader,
47
- children: jsxDEV_7x81h0kn(
48
- "h1",
49
- {
50
- className: styles.popupTitle,
51
- children: jsxDEV_7x81h0kn(
52
- "span",
53
- { className: styles.primaryText, children: "Preview " },
54
- undefined,
55
- false,
56
- undefined,
57
- this,
58
- ),
59
- },
60
- undefined,
61
- false,
62
- undefined,
63
- this,
64
- ),
65
- },
66
- undefined,
67
- false,
68
- undefined,
69
- this,
70
- ),
71
- jsxDEV_7x81h0kn(
72
- "div",
73
- {
74
- className: styles.popupHeader,
75
- children: [
76
- jsxDEV_7x81h0kn(
77
- "div",
78
- {
79
- className: styles.headerLeft,
80
- children: jsxDEV_7x81h0kn(
81
- "h4",
82
- {
83
- className: styles.popupTitle,
84
- children: jsxDEV_7x81h0kn(
85
- "span",
86
- {
87
- className: styles.baseTitleText,
88
- children: displayTitle,
89
- },
90
- undefined,
91
- false,
92
- undefined,
93
- this,
94
- ),
95
- },
96
- undefined,
97
- false,
98
- undefined,
99
- this,
100
- ),
101
- },
102
- undefined,
103
- false,
104
- undefined,
105
- this,
106
- ),
107
- jsxDEV_7x81h0kn(
108
- "div",
109
- {
110
- className: styles.headerControls,
111
- children: [
112
- !isMobileSize &&
113
- fileType !== "web" &&
114
- jsxDEV_7x81h0kn(
115
- "div",
116
- {
117
- className: styles.zoomDropdown,
118
- ref: zoomMenuRef,
119
- onMouseEnter: () => {
120
- if (zoomMenuTimer.current)
121
- clearTimeout(zoomMenuTimer.current);
122
- setShowZoomMenu(true);
123
- },
124
- onMouseLeave: () => {
125
- zoomMenuTimer.current = setTimeout(
126
- () => setShowZoomMenu(false),
127
- 150,
128
- );
129
- },
130
- children: [
131
- jsxDEV_7x81h0kn(
132
- "button",
133
- {
134
- onClick: () => setShowZoomMenu(!showZoomMenu),
135
- className: styles.zoomVal,
136
- title: "Change Zoom",
137
- children: [
138
- Math.round(zoomLevel * 100),
139
- "%",
140
- jsxDEV_7x81h0kn(
141
- "span",
142
- {
143
- className: styles.dropdownArrow,
144
- children: "",
145
- },
146
- undefined,
147
- false,
148
- undefined,
149
- this,
150
- ),
151
- ],
152
- },
153
- undefined,
154
- true,
155
- undefined,
156
- this,
157
- ),
158
- showZoomMenu &&
159
- jsxDEV_7x81h0kn(
160
- "div",
161
- {
162
- className: styles.zoomMenu,
163
- children: [0.5, 0.75, 1, 1.25, 1.5, 2].map(
164
- (level) =>
165
- jsxDEV_7x81h0kn(
166
- "button",
167
- {
168
- className: `${styles.zoomMenuItem} ${zoomLevel === level ? styles.zoomMenuItemActive : ""}`,
169
- onClick: () => {
170
- onZoomChange(level);
171
- setShowZoomMenu(false);
172
- },
173
- children:
174
- level === 1
175
- ? "100% (Fit)"
176
- : `${Math.round(level * 100)}%`,
177
- },
178
- level,
179
- false,
180
- undefined,
181
- this,
182
- ),
183
- ),
184
- },
185
- undefined,
186
- false,
187
- undefined,
188
- this,
189
- ),
190
- ],
191
- },
192
- undefined,
193
- true,
194
- undefined,
195
- this,
196
- ),
197
- fileType === "web"
198
- ? jsxDEV_7x81h0kn(
199
- Tooltip,
200
- {
201
- msg: "Open externally",
202
- position: "bottom",
203
- underline: false,
204
- children: jsxDEV_7x81h0kn(
205
- "a",
206
- {
207
- href: fileUrl,
208
- target: "_blank",
209
- rel: "noopener noreferrer",
210
- className: styles.headerAction,
211
- children: [
212
- jsxDEV_7x81h0kn(
213
- IconLink,
214
- { className: styles.headerIcon },
215
- undefined,
216
- false,
217
- undefined,
218
- this,
219
- ),
220
- jsxDEV_7x81h0kn(
221
- "span",
222
- {
223
- className: styles.btnText,
224
- children: "Visit",
225
- },
226
- undefined,
227
- false,
228
- undefined,
229
- this,
230
- ),
231
- ],
232
- },
233
- undefined,
234
- true,
235
- undefined,
236
- this,
237
- ),
238
- },
239
- undefined,
240
- false,
241
- undefined,
242
- this,
243
- )
244
- : jsxDEV_7x81h0kn(
245
- Tooltip,
246
- {
247
- msg: isDownloading
248
- ? "Downloading..."
249
- : "Download file",
250
- position: "bottom",
251
- underline: false,
252
- children: jsxDEV_7x81h0kn(
253
- "button",
254
- {
255
- onClick: onDownload,
256
- disabled: isDownloading,
257
- className: `${styles.headerAction} ${styles.downloadButton} ${isDownloading ? styles.headerActionDisabled : ""}`,
258
- children: [
259
- isDownloading
260
- ? jsxDEV_7x81h0kn(
261
- "div",
262
- { className: styles.spinnerSmall },
263
- undefined,
264
- false,
265
- undefined,
266
- this,
267
- )
268
- : jsxDEV_7x81h0kn(
269
- IconSave,
270
- { className: styles.headerIconSmall },
271
- undefined,
272
- false,
273
- undefined,
274
- this,
275
- ),
276
- jsxDEV_7x81h0kn(
277
- "span",
278
- {
279
- className: styles.btnText,
280
- children: isDownloading
281
- ? "Saving"
282
- : "Save",
283
- },
284
- undefined,
285
- false,
286
- undefined,
287
- this,
288
- ),
289
- ],
290
- },
291
- undefined,
292
- true,
293
- undefined,
294
- this,
295
- ),
296
- },
297
- undefined,
298
- false,
299
- undefined,
300
- this,
301
- ),
302
- modeSwitch &&
303
- jsxDEV_7x81h0kn(
304
- Tooltip,
305
- {
306
- msg: toggleTooltip,
307
- position: "bottom",
308
- underline: false,
309
- children: jsxDEV_7x81h0kn(
310
- "button",
311
- {
312
- onClick: onToggleMode,
313
- className: `${styles.headerAction} ${styles.dockToggle}`,
314
- children: [
315
- mode === "popup" || mode === "pip"
316
- ? jsxDEV_7x81h0kn(
317
- IconDock,
318
- { className: styles.headerIcon },
319
- undefined,
320
- false,
321
- undefined,
322
- this,
323
- )
324
- : jsxDEV_7x81h0kn(
325
- IconPopup,
326
- {
327
- className: `${styles.headerIcon} ${styles.iconPopupTweak}`,
328
- },
329
- undefined,
330
- false,
331
- undefined,
332
- this,
333
- ),
334
- showDockLabel &&
335
- jsxDEV_7x81h0kn(
336
- "span",
337
- {
338
- className: styles.btnText,
339
- children: toggleLabel,
340
- },
341
- undefined,
342
- false,
343
- undefined,
344
- this,
345
- ),
346
- ],
347
- },
348
- undefined,
349
- true,
350
- undefined,
351
- this,
352
- ),
353
- },
354
- undefined,
355
- false,
356
- undefined,
357
- this,
358
- ),
359
- jsxDEV_7x81h0kn(
360
- Tooltip,
361
- {
362
- msg: "Close",
363
- position: "bottom",
364
- underline: false,
365
- children: jsxDEV_7x81h0kn(
366
- "button",
367
- {
368
- onClick: onClose,
369
- className: `${styles.headerAction} ${styles.headerActionClose}`,
370
- children: jsxDEV_7x81h0kn(
371
- IconClose,
372
- { className: styles.headerIconSmall },
373
- undefined,
374
- false,
375
- undefined,
376
- this,
377
- ),
378
- },
379
- undefined,
380
- false,
381
- undefined,
382
- this,
383
- ),
384
- },
385
- undefined,
386
- false,
387
- undefined,
388
- this,
389
- ),
390
- ],
391
- },
392
- undefined,
393
- true,
394
- undefined,
395
- this,
396
- ),
397
- ],
398
- },
399
- undefined,
400
- true,
401
- undefined,
402
- this,
403
- ),
404
- ],
405
- },
406
- undefined,
407
- true,
408
- undefined,
409
- this,
38
+
39
+ return (
40
+ <>
41
+ {/* Reveal header shown only in dock mode on desktop */}
42
+ {mode === "dock" && !isMobileSize && (
43
+ <div className={styles.revealHeader}>
44
+ <h1 className={styles.popupTitle}>
45
+ <span className={styles.primaryText}>Preview </span>
46
+ </h1>
47
+ </div>
48
+ )}
49
+
50
+ {/* Main header bar */}
51
+ <div className={styles.popupHeader}>
52
+ {/* Title */}
53
+ <div className={styles.headerLeft}>
54
+ <h4 className={styles.popupTitle}>
55
+ <span className={styles.baseTitleText}>{displayTitle}</span>
56
+ </h4>
57
+ </div>
58
+
59
+ {/* Controls */}
60
+ <div className={styles.headerControls}>
61
+ {/* Zoom picker (desktop, non-web) */}
62
+ {!isMobileSize && fileType !== "web" && (
63
+ <div
64
+ className={styles.zoomDropdown}
65
+ ref={zoomMenuRef}
66
+ onMouseEnter={() => {
67
+ if (zoomMenuTimer.current) clearTimeout(zoomMenuTimer.current);
68
+ setShowZoomMenu(true);
69
+ }}
70
+ onMouseLeave={() => {
71
+ zoomMenuTimer.current = setTimeout(
72
+ () => setShowZoomMenu(false),
73
+ 150,
74
+ );
75
+ }}
76
+ >
77
+ <button
78
+ onClick={() => setShowZoomMenu(!showZoomMenu)}
79
+ className={styles.zoomVal}
80
+ title="Change Zoom"
81
+ >
82
+ {Math.round(zoomLevel * 100)}%
83
+ <span className={styles.dropdownArrow}>▼</span>
84
+ </button>
85
+
86
+ {showZoomMenu && (
87
+ <div className={styles.zoomMenu}>
88
+ {[0.5, 0.75, 1, 1.25, 1.5, 2].map((level) => (
89
+ <button
90
+ key={level}
91
+ className={`${styles.zoomMenuItem} ${zoomLevel === level ? styles.zoomMenuItemActive : ""}`}
92
+ onClick={() => {
93
+ onZoomChange(level);
94
+ setShowZoomMenu(false);
95
+ }}
96
+ >
97
+ {level === 1
98
+ ? "100% (Fit)"
99
+ : `${Math.round(level * 100)}%`}
100
+ </button>
101
+ ))}
102
+ </div>
103
+ )}
104
+ </div>
105
+ )}
106
+
107
+ {/* Open/Download action */}
108
+ {fileType === "web" ? (
109
+ <Tooltip msg="Open externally" position="bottom" underline={false}>
110
+ <a
111
+ href={fileUrl}
112
+ target="_blank"
113
+ rel="noopener noreferrer"
114
+ className={styles.headerAction}
115
+ >
116
+ <IconLink className={styles.headerIcon} />
117
+ <span className={styles.btnText}>Visit</span>
118
+ </a>
119
+ </Tooltip>
120
+ ) : (
121
+ <Tooltip
122
+ msg={isDownloading ? "Downloading..." : "Download file"}
123
+ position="bottom"
124
+ underline={false}
125
+ >
126
+ <button
127
+ onClick={onDownload}
128
+ disabled={isDownloading}
129
+ className={`${styles.headerAction} ${styles.downloadButton} ${isDownloading ? styles.headerActionDisabled : ""}`}
130
+ >
131
+ {isDownloading ? (
132
+ <div className={styles.spinnerSmall} />
133
+ ) : (
134
+ <IconSave className={styles.headerIconSmall} />
135
+ )}
136
+ <span className={styles.btnText}>
137
+ {isDownloading ? "Saving" : "Save"}
138
+ </span>
139
+ </button>
140
+ </Tooltip>
141
+ )}
142
+
143
+ {/* Mode toggle */}
144
+ {modeSwitch && (
145
+ <Tooltip msg={toggleTooltip} position="bottom" underline={false}>
146
+ <button
147
+ onClick={onToggleMode}
148
+ className={`${styles.headerAction} ${styles.dockToggle}`}
149
+ >
150
+ {mode === "popup" || mode === "pip" ? (
151
+ <IconDock className={styles.headerIcon} />
152
+ ) : (
153
+ <IconPopup
154
+ className={`${styles.headerIcon} ${styles.iconPopupTweak}`}
155
+ />
156
+ )}
157
+ {showDockLabel && (
158
+ <span className={styles.btnText}>{toggleLabel}</span>
159
+ )}
160
+ </button>
161
+ </Tooltip>
162
+ )}
163
+
164
+ {/* Close */}
165
+ <Tooltip msg="Close" position="bottom" underline={false}>
166
+ <button
167
+ onClick={onClose}
168
+ className={`${styles.headerAction} ${styles.headerActionClose}`}
169
+ >
170
+ <IconClose className={styles.headerIconSmall} />
171
+ </button>
172
+ </Tooltip>
173
+ </div>
174
+ </div>
175
+ </>
410
176
  );
411
177
  }