@jsonresume/jsonresume-theme-professional 1.0.19 → 1.0.21

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/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # @jsonresume/jsonresume-theme-professional
2
+
3
+ ## 1.0.21
4
+
5
+ ### Patch Changes
6
+
7
+ - 304a130: Theme curation wave: full JSON Resume section coverage and SSR fixes.
8
+
9
+ - Add missing sections (Interests, Certificates, et al.) across 15+ themes so every registered theme renders all schema sections
10
+ - tokyo-modernist: inline styled-components (fixes webpack resolution SSR crash) — re-enabled in the registry
11
+ - tailwind: fix social-icon SSR crash, add 7 missing sections with missing-data guards — re-enabled in the registry
12
+ - Register previously orphaned desert-modern and elegant-pink themes with metadata
13
+ - @jsonresume/core@0.3.2
14
+
15
+ ## 1.0.20
16
+
17
+ ### Patch Changes
18
+
19
+ - 965cf57: use @jsonresume/core/ssr renderResumeDocument
20
+ - Updated dependencies [ff09f75]
21
+ - @jsonresume/core@0.3.1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2014-2026 JSON Resume contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { renderToString } from "react-dom/server";
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { renderToStaticMarkup } from "react-dom/server";
3
3
  import o, { useState, useMemo, useEffect, useContext, useDebugValue, createElement, useRef } from "react";
4
4
  import { marked } from "marked";
5
5
  import { FaMapPin, FaEnvelope, FaPhoneAlt, FaLink, FaLinkedin, FaGithub, FaTwitter } from "react-icons/fa";
@@ -43,38 +43,46 @@ var isPropValid = /* @__PURE__ */ memoize(
43
43
  function getDefaultExportFromCjs(x2) {
44
44
  return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
45
45
  }
46
- var shallowequal = function shallowEqual(objA, objB, compare, compareContext) {
47
- var ret = compare ? compare.call(compareContext, objA, objB) : void 0;
48
- if (ret !== void 0) {
49
- return !!ret;
50
- }
51
- if (objA === objB) {
52
- return true;
53
- }
54
- if (typeof objA !== "object" || !objA || typeof objB !== "object" || !objB) {
55
- return false;
56
- }
57
- var keysA = Object.keys(objA);
58
- var keysB = Object.keys(objB);
59
- if (keysA.length !== keysB.length) {
60
- return false;
61
- }
62
- var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
63
- for (var idx = 0; idx < keysA.length; idx++) {
64
- var key = keysA[idx];
65
- if (!bHasOwnProperty(key)) {
46
+ var shallowequal;
47
+ var hasRequiredShallowequal;
48
+ function requireShallowequal() {
49
+ if (hasRequiredShallowequal) return shallowequal;
50
+ hasRequiredShallowequal = 1;
51
+ shallowequal = function shallowEqual(objA, objB, compare, compareContext) {
52
+ var ret = compare ? compare.call(compareContext, objA, objB) : void 0;
53
+ if (ret !== void 0) {
54
+ return !!ret;
55
+ }
56
+ if (objA === objB) {
57
+ return true;
58
+ }
59
+ if (typeof objA !== "object" || !objA || typeof objB !== "object" || !objB) {
66
60
  return false;
67
61
  }
68
- var valueA = objA[key];
69
- var valueB = objB[key];
70
- ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;
71
- if (ret === false || ret === void 0 && valueA !== valueB) {
62
+ var keysA = Object.keys(objA);
63
+ var keysB = Object.keys(objB);
64
+ if (keysA.length !== keysB.length) {
72
65
  return false;
73
66
  }
74
- }
75
- return true;
76
- };
77
- const p = /* @__PURE__ */ getDefaultExportFromCjs(shallowequal);
67
+ var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
68
+ for (var idx = 0; idx < keysA.length; idx++) {
69
+ var key = keysA[idx];
70
+ if (!bHasOwnProperty(key)) {
71
+ return false;
72
+ }
73
+ var valueA = objA[key];
74
+ var valueB = objB[key];
75
+ ret = compare ? compare.call(compareContext, valueA, valueB, key) : void 0;
76
+ if (ret === false || ret === void 0 && valueA !== valueB) {
77
+ return false;
78
+ }
79
+ }
80
+ return true;
81
+ };
82
+ return shallowequal;
83
+ }
84
+ var shallowequalExports = requireShallowequal();
85
+ const p = /* @__PURE__ */ getDefaultExportFromCjs(shallowequalExports);
78
86
  var MS = "-ms-";
79
87
  var MOZ = "-moz-";
80
88
  var WEBKIT = "-webkit-";
@@ -1271,6 +1279,66 @@ var vt = /^\s*<\/[a-z]/i, gt = (function() {
1271
1279
  "production" !== process.env.NODE_ENV && "undefined" != typeof navigator && "ReactNative" === navigator.product && console.warn("It looks like you've imported 'styled-components' on React Native.\nPerhaps you're looking to import 'styled-components/native'?\nRead more about this at https://www.styled-components.com/docs/basics#react-native");
1272
1280
  var wt = "__sc-".concat(f, "__");
1273
1281
  "production" !== process.env.NODE_ENV && "test" !== process.env.NODE_ENV && "undefined" != typeof window && (window[wt] || (window[wt] = 0), 1 === window[wt] && console.warn("It looks like there are several instances of 'styled-components' initialized in this application. This may cause dynamic styles to not render properly, errors during the rehydration process, a missing theme prop, and makes your application bigger without good reason.\n\nSee https://s-c.sh/2BAXzed for more info."), window[wt] += 1);
1282
+ const CSS_RESET = "<style>*,*::before,*::after{box-sizing:border-box}html,body{margin:0;padding:0}body{-webkit-font-smoothing:antialiased}</style>";
1283
+ const TOKENS_CSS_HREF = "https://unpkg.com/@jsonresume/core/dist/tokens.css";
1284
+ const FONTS_PRECONNECT = '<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>';
1285
+ function isHref(value) {
1286
+ return /^(https?:)?\/\//.test(value) || value.trim().startsWith("<link");
1287
+ }
1288
+ function familyParam(family) {
1289
+ const [name, ...rest] = String(family).split(":");
1290
+ const encodedName = name.trim().replace(/\s+/g, "+");
1291
+ return rest.length ? `${encodedName}:${rest.join(":")}` : encodedName;
1292
+ }
1293
+ function googleFontsLinks(families) {
1294
+ if (!Array.isArray(families) || families.length === 0) return "";
1295
+ const passthrough = [];
1296
+ const names = [];
1297
+ for (const entry of families) {
1298
+ if (entry == null || entry === "") continue;
1299
+ if (isHref(entry)) passthrough.push(entry);
1300
+ else names.push(entry);
1301
+ }
1302
+ const links = passthrough.map(
1303
+ (href) => href.trim().startsWith("<link") ? href : `<link href="${href}" rel="stylesheet">`
1304
+ );
1305
+ if (names.length > 0) {
1306
+ const query = names.map(familyParam).join("&family=");
1307
+ links.unshift(
1308
+ `<link href="https://fonts.googleapis.com/css2?family=${query}&display=swap" rel="stylesheet">`
1309
+ );
1310
+ }
1311
+ if (links.length === 0) return "";
1312
+ return FONTS_PRECONNECT + links.join("");
1313
+ }
1314
+ function renderResumeDocument(element, options = {}) {
1315
+ const {
1316
+ fonts,
1317
+ title,
1318
+ lang = "en",
1319
+ dir = "ltr",
1320
+ reset = false,
1321
+ head = "",
1322
+ headAfterStyles = "",
1323
+ includeTokensCss = true,
1324
+ bodyClass
1325
+ } = options;
1326
+ const sheet = new gt();
1327
+ let html;
1328
+ let styleTags;
1329
+ try {
1330
+ html = renderToStaticMarkup(sheet.collectStyles(element));
1331
+ styleTags = sheet.getStyleTags();
1332
+ } finally {
1333
+ sheet.seal();
1334
+ }
1335
+ const fontLinks = googleFontsLinks(fonts);
1336
+ const tokensLink = includeTokensCss ? `<link rel="stylesheet" href="${TOKENS_CSS_HREF}">` : "";
1337
+ const resetTag = reset ? CSS_RESET : "";
1338
+ const titleTag = title ? `<title>${title}</title>` : "";
1339
+ const bodyAttr = bodyClass ? ` class="${bodyClass}"` : "";
1340
+ return `<!DOCTYPE html><html lang="${lang}" dir="${dir}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">` + fontLinks + tokensLink + resetTag + head + styleTags + headAfterStyles + titleTag + `</head><body${bodyAttr}>${html}</body></html>`;
1341
+ }
1274
1342
  const Section = dt.div`
1275
1343
  max-width: 700px;
1276
1344
  margin: 0 auto 18px;
@@ -1600,7 +1668,7 @@ const OneLineList = ({ name, items }) => {
1600
1668
  name,
1601
1669
  ":"
1602
1670
  ] }),
1603
- /* @__PURE__ */ jsx(List, { children: /* @__PURE__ */ jsx("div", { class: "secondary", children: items?.join(", ") }) })
1671
+ /* @__PURE__ */ jsx(List, { children: /* @__PURE__ */ jsx("div", { className: "secondary", children: items?.join(", ") }) })
1604
1672
  ] });
1605
1673
  };
1606
1674
  const Skills = ({ skills }) => {
@@ -1687,30 +1755,29 @@ const Resume = ({ resume }) => {
1687
1755
  ] });
1688
1756
  };
1689
1757
  const render = (resume) => {
1690
- const sheet = new gt();
1691
- const html = renderToString(sheet.collectStyles(/* @__PURE__ */ jsx(Resume, { resume })));
1692
- const styles = sheet.getStyleTags();
1693
- return `<!DOCTYPE html><head>
1694
- <title>${resume.basics.name} - Resume</title>
1695
- <meta charset="utf-8">
1696
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
1697
- <style>
1758
+ return renderResumeDocument(
1759
+ /* @__PURE__ */ jsx("main", { children: /* @__PURE__ */ jsx(Resume, { resume }) }),
1760
+ {
1761
+ head: `<style>
1698
1762
  @font-face {
1699
1763
  font-family: LatinModern;
1700
1764
  font-style: normal;
1701
1765
  font-weight: normal;
1766
+ font-display: swap;
1702
1767
  src: url("/fonts/lmroman10-regular.otf") format("opentype");
1703
1768
  }
1704
1769
 
1705
1770
  @font-face {
1706
1771
  font-family: LatinModern;
1707
1772
  font-weight: bold;
1773
+ font-display: swap;
1708
1774
  src: url("/fonts/lmroman10-bold.otf") format("opentype");
1709
1775
  }
1710
1776
 
1711
1777
  @font-face {
1712
1778
  font-family: LatinModern;
1713
1779
  font-style: italic;
1780
+ font-display: swap;
1714
1781
  src: url("/fonts/lmroman10-italic.otf") format("opentype");
1715
1782
  }
1716
1783
 
@@ -1718,18 +1785,21 @@ const render = (resume) => {
1718
1785
  font-family: LatinModernSans;
1719
1786
  font-style: normal;
1720
1787
  font-weight: normal;
1788
+ font-display: swap;
1721
1789
  src: url("/fonts/lmsans10-regular.otf") format("opentype");
1722
1790
  }
1723
1791
 
1724
1792
  @font-face {
1725
1793
  font-family: LatinModernSans;
1726
1794
  font-weight: bold;
1795
+ font-display: swap;
1727
1796
  src: url("/fonts/lmsans10-bold.otf") format("opentype");
1728
1797
  }
1729
1798
 
1730
1799
  @font-face {
1731
1800
  font-family: LatinModernSans;
1732
1801
  font-style: italic;
1802
+ font-display: swap;
1733
1803
  src: url("/fonts/lmsans10-italic.otf") format("opentype");
1734
1804
  }
1735
1805
 
@@ -1775,8 +1845,13 @@ const render = (resume) => {
1775
1845
 
1776
1846
 
1777
1847
 
1778
- </style>
1779
- ${styles}</head><body>${html}</body></html>`;
1848
+ </style>`,
1849
+ lang: "en",
1850
+ dir: "ltr",
1851
+ title: `${resume.basics.name} - Resume`,
1852
+ includeTokensCss: false
1853
+ }
1854
+ );
1780
1855
  };
1781
1856
  export {
1782
1857
  Resume,
package/package.json CHANGED
@@ -1,28 +1,24 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@jsonresume/jsonresume-theme-professional",
4
- "version": "1.0.19",
4
+ "version": "1.0.21",
5
5
  "main": "./src/index.jsx",
6
6
  "license": "MIT",
7
7
  "devDependencies": {
8
- "@repo/eslint-config-custom": "workspace:^",
9
8
  "react": "^19.2.0",
10
9
  "styled-components": "^6.1.19",
11
10
  "@vitejs/plugin-react": "^4.3.4",
12
- "vite": "^5.4.21"
11
+ "vite": "^6.4.3",
12
+ "@repo/eslint-config-custom": "^0.0.0"
13
13
  },
14
14
  "peerDependencies": {
15
15
  "styled-components": "^6"
16
16
  },
17
- "scripts": {
18
- "lint": "eslint src || exit 0",
19
- "publish": "npm publish --access public",
20
- "build": "vite build"
21
- },
22
17
  "dependencies": {
23
18
  "marked": "^16.3.0",
24
19
  "prismjs": "^1.29.0",
25
- "react-icons": "^5.0.1"
20
+ "react-icons": "^5.0.1",
21
+ "@jsonresume/core": "0.3.2"
26
22
  },
27
23
  "exports": {
28
24
  ".": {
@@ -33,5 +29,9 @@
33
29
  "import": "./dist/index.js",
34
30
  "default": "./dist/index.js"
35
31
  }
32
+ },
33
+ "scripts": {
34
+ "lint": "eslint src || exit 0",
35
+ "build": "vite build"
36
36
  }
37
- }
37
+ }
package/src/index.jsx CHANGED
@@ -1,32 +1,32 @@
1
- import { renderToString } from 'react-dom/server';
2
- import { ServerStyleSheet } from 'styled-components';
1
+ import { renderResumeDocument } from '@jsonresume/core/ssr';
3
2
  import Resume from './ui/Resume';
4
3
 
5
4
  export const render = (resume) => {
6
- const sheet = new ServerStyleSheet();
7
- const html = renderToString(sheet.collectStyles(<Resume resume={resume} />));
8
- const styles = sheet.getStyleTags();
9
- return `<!DOCTYPE html><head>
10
- <title>${resume.basics.name} - Resume</title>
11
- <meta charset="utf-8">
12
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
13
- <style>
5
+ return renderResumeDocument(
6
+ <main>
7
+ <Resume resume={resume} />
8
+ </main>,
9
+ {
10
+ head: `<style>
14
11
  @font-face {
15
12
  font-family: LatinModern;
16
13
  font-style: normal;
17
14
  font-weight: normal;
15
+ font-display: swap;
18
16
  src: url("/fonts/lmroman10-regular.otf") format("opentype");
19
17
  }
20
18
 
21
19
  @font-face {
22
20
  font-family: LatinModern;
23
21
  font-weight: bold;
22
+ font-display: swap;
24
23
  src: url("/fonts/lmroman10-bold.otf") format("opentype");
25
24
  }
26
25
 
27
26
  @font-face {
28
27
  font-family: LatinModern;
29
28
  font-style: italic;
29
+ font-display: swap;
30
30
  src: url("/fonts/lmroman10-italic.otf") format("opentype");
31
31
  }
32
32
 
@@ -34,18 +34,21 @@ export const render = (resume) => {
34
34
  font-family: LatinModernSans;
35
35
  font-style: normal;
36
36
  font-weight: normal;
37
+ font-display: swap;
37
38
  src: url("/fonts/lmsans10-regular.otf") format("opentype");
38
39
  }
39
40
 
40
41
  @font-face {
41
42
  font-family: LatinModernSans;
42
43
  font-weight: bold;
44
+ font-display: swap;
43
45
  src: url("/fonts/lmsans10-bold.otf") format("opentype");
44
46
  }
45
47
 
46
48
  @font-face {
47
49
  font-family: LatinModernSans;
48
50
  font-style: italic;
51
+ font-display: swap;
49
52
  src: url("/fonts/lmsans10-italic.otf") format("opentype");
50
53
  }
51
54
 
@@ -91,8 +94,13 @@ export const render = (resume) => {
91
94
 
92
95
 
93
96
 
94
- </style>
95
- ${styles}</head><body>${html}</body></html>`;
97
+ </style>`,
98
+ lang: 'en',
99
+ dir: 'ltr',
100
+ title: `${resume.basics.name} - Resume`,
101
+ includeTokensCss: false,
102
+ }
103
+ );
96
104
  };
97
105
 
98
106
  export { Resume };
@@ -21,7 +21,7 @@ const OneLineList = ({ name, items }) => {
21
21
  <Container>
22
22
  <Name>{name}:</Name>
23
23
  <List>
24
- <div class="secondary">{items?.join(', ')}</div>
24
+ <div className="secondary">{items?.join(', ')}</div>
25
25
  </List>
26
26
  </Container>
27
27
  );
@@ -1,11 +0,0 @@
1
-
2
- > @jsonresume/jsonresume-theme-professional@1.0.18 build /Users/ajaxdavis/repos/jsonresume.org/packages/themes/jsonresume-theme-professional
3
- > vite build
4
-
5
- The CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
6
- vite v5.4.21 building SSR bundle for production...
7
- transforming...
8
- ✓ 36 modules transformed.
9
- rendering chunks...
10
- dist/index.mjs 74.83 kB
11
- ✓ built in 1.58s