From 70a1be8c93182bb4a2e0416975afd955fe111f48 Mon Sep 17 00:00:00 2001 From: garronej Date: Wed, 7 May 2025 15:53:01 +0200 Subject: [PATCH 1/4] #228 --- package.json | 2 +- src/bin/shim_jsx_element.ts | 31 ++ src/bin/tools/SemVer.ts | 119 +++++++ src/bin/tools/crawl.ts | 35 ++ src/bin/tools/fs.rmSync.ts | 40 +++ src/bin/tools/transformCodebase.ts | 89 +++++ src/tools/ReactHTML.tsx | 510 ++++++++++++++++++++++++++++- 7 files changed, 823 insertions(+), 3 deletions(-) create mode 100644 src/bin/shim_jsx_element.ts create mode 100644 src/bin/tools/SemVer.ts create mode 100644 src/bin/tools/crawl.ts create mode 100644 src/bin/tools/fs.rmSync.ts create mode 100644 src/bin/tools/transformCodebase.ts diff --git a/package.json b/package.json index 5052e8d..f9f1654 100755 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ } }, "scripts": { - "build": "tsc && tsc -p tsconfig-esm.json", + "build": "tsc && tsc -p tsconfig-esm.json && ts-node src/bin/shim_jsx_element.ts", "start_spa": "yarn yarn_link && cd src/test/apps/spa && yarn start", "start_ssr": "yarn yarn_link && cd src/test/apps/ssr && yarn dev", "start_appdir": "yarn yarn_link && cd src/test/apps/next-appdir && yarn dev", diff --git a/src/bin/shim_jsx_element.ts b/src/bin/shim_jsx_element.ts new file mode 100644 index 0000000..c851ea1 --- /dev/null +++ b/src/bin/shim_jsx_element.ts @@ -0,0 +1,31 @@ +import { transformCodebase } from "./tools/transformCodebase"; +import { join as pathJoin } from "path"; + +function shimJsxElement(params: { distDirPath: string }) { + const { distDirPath } = params; + + transformCodebase({ + srcDirPath: distDirPath, + destDirPath: distDirPath, + transformSourceCode: ({ fileRelativePath, sourceCode }) => { + if (!fileRelativePath.endsWith(".d.ts")) { + return { modifiedSourceCode: sourceCode }; + } + + let modifiedSourceCode = sourceCode.toString("utf8"); + + modifiedSourceCode = modifiedSourceCode.replace( + /JSX\.Element/g, + 'import("react").ReactElement' + ); + + return { + modifiedSourceCode: Buffer.from(modifiedSourceCode, "utf8") + }; + } + }); +} + +shimJsxElement({ + distDirPath: pathJoin(process.cwd(), "dist") +}); diff --git a/src/bin/tools/SemVer.ts b/src/bin/tools/SemVer.ts new file mode 100644 index 0000000..9201c77 --- /dev/null +++ b/src/bin/tools/SemVer.ts @@ -0,0 +1,119 @@ +export type SemVer = { + major: number; + minor: number; + patch: number; + rc?: number; + parsedFrom: string; +}; + +export namespace SemVer { + const bumpTypes = ["major", "minor", "patch", "rc", "no bump"] as const; + + export type BumpType = typeof bumpTypes[number]; + + export function parse(versionStr: string): SemVer { + const match = versionStr.match( + /^v?([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-rc.([0-9]+))?$/ + ); + + if (!match) { + throw new Error(`${versionStr} is not a valid semantic version`); + } + + const semVer: Omit = { + major: parseInt(match[1]), + minor: parseInt(match[2]), + patch: (() => { + const str = match[3]; + + return str === undefined ? 0 : parseInt(str); + })(), + ...(() => { + const str = match[4]; + return str === undefined ? {} : { rc: parseInt(str) }; + })() + }; + + const initialStr = stringify(semVer); + + Object.defineProperty(semVer, "parsedFrom", { + enumerable: true, + get: function () { + const currentStr = stringify(this); + + if (currentStr !== initialStr) { + throw new Error( + `SemVer.parsedFrom can't be read anymore, the version have been modified from ${initialStr} to ${currentStr}` + ); + } + + return versionStr; + } + }); + + return semVer as any; + } + + export function stringify(v: Omit): string { + return `${v.major}.${v.minor}.${v.patch}${ + v.rc === undefined ? "" : `-rc.${v.rc}` + }`; + } + + /** + * + * v1 < v2 => -1 + * v1 === v2 => 0 + * v1 > v2 => 1 + * + */ + export function compare(v1: SemVer, v2: SemVer): -1 | 0 | 1 { + const sign = (diff: number): -1 | 0 | 1 => + diff === 0 ? 0 : diff < 0 ? -1 : 1; + const noUndefined = (n: number | undefined) => n ?? Infinity; + + for (const level of ["major", "minor", "patch", "rc"] as const) { + if (noUndefined(v1[level]) !== noUndefined(v2[level])) { + return sign(noUndefined(v1[level]) - noUndefined(v2[level])); + } + } + + return 0; + } + + /* + console.log(compare(parse("3.0.0-rc.3"), parse("3.0.0")) === -1 ) + console.log(compare(parse("3.0.0-rc.3"), parse("3.0.0-rc.4")) === -1 ) + console.log(compare(parse("3.0.0-rc.3"), parse("4.0.0")) === -1 ) + */ + + export function bumpType(params: { + versionBehind: string | SemVer; + versionAhead: string | SemVer; + }): BumpType | "no bump" { + const versionAhead = + typeof params.versionAhead === "string" + ? parse(params.versionAhead) + : params.versionAhead; + const versionBehind = + typeof params.versionBehind === "string" + ? parse(params.versionBehind) + : params.versionBehind; + + if (compare(versionBehind, versionAhead) === 1) { + throw new Error( + `Version regression ${stringify(versionBehind)} -> ${stringify( + versionAhead + )}` + ); + } + + for (const level of ["major", "minor", "patch", "rc"] as const) { + if (versionBehind[level] !== versionAhead[level]) { + return level; + } + } + + return "no bump"; + } +} diff --git a/src/bin/tools/crawl.ts b/src/bin/tools/crawl.ts new file mode 100644 index 0000000..86ba207 --- /dev/null +++ b/src/bin/tools/crawl.ts @@ -0,0 +1,35 @@ +import * as fs from "fs"; +import { join as pathJoin, relative as pathRelative } from "path"; + +const crawlRec = (dirPath: string, filePaths: string[]) => { + for (const basename of fs.readdirSync(dirPath)) { + const fileOrDirPath = pathJoin(dirPath, basename); + + if (fs.lstatSync(fileOrDirPath).isDirectory()) { + crawlRec(fileOrDirPath, filePaths); + + continue; + } + + filePaths.push(fileOrDirPath); + } +}; + +/** List all files in a given directory return paths relative to the dir_path */ +export function crawl(params: { + dirPath: string; + returnedPathsType: "absolute" | "relative to dirPath"; +}): string[] { + const { dirPath, returnedPathsType } = params; + + const filePaths: string[] = []; + + crawlRec(dirPath, filePaths); + + switch (returnedPathsType) { + case "absolute": + return filePaths; + case "relative to dirPath": + return filePaths.map(filePath => pathRelative(dirPath, filePath)); + } +} diff --git a/src/bin/tools/fs.rmSync.ts b/src/bin/tools/fs.rmSync.ts new file mode 100644 index 0000000..cf2f268 --- /dev/null +++ b/src/bin/tools/fs.rmSync.ts @@ -0,0 +1,40 @@ +import * as fs from "fs"; +import { join as pathJoin } from "path"; +import { SemVer } from "./SemVer"; + +/** + * Polyfill of fs.rmSync(dirPath, { "recursive": true }) + * For older version of Node + */ +export function rmSync( + dirPath: string, + options: { recursive: true; force?: true } +) { + if ( + SemVer.compare(SemVer.parse(process.version), SemVer.parse("14.14.0")) > + 0 + ) { + fs.rmSync(dirPath, options); + return; + } + + const { force = true } = options; + + if (force && !fs.existsSync(dirPath)) { + return; + } + + const removeDir_rec = (dirPath: string) => + fs.readdirSync(dirPath).forEach(basename => { + const fileOrDirPath = pathJoin(dirPath, basename); + + if (fs.lstatSync(fileOrDirPath).isDirectory()) { + removeDir_rec(fileOrDirPath); + return; + } else { + fs.unlinkSync(fileOrDirPath); + } + }); + + removeDir_rec(dirPath); +} diff --git a/src/bin/tools/transformCodebase.ts b/src/bin/tools/transformCodebase.ts new file mode 100644 index 0000000..142a152 --- /dev/null +++ b/src/bin/tools/transformCodebase.ts @@ -0,0 +1,89 @@ +import * as fs from "fs"; +import * as path from "path"; +import { crawl } from "./crawl"; +import { rmSync } from "./fs.rmSync"; + +type TransformSourceCode = (params: { + sourceCode: Buffer; + filePath: string; + fileRelativePath: string; +}) => + | { + modifiedSourceCode: Buffer; + newFileName?: string; + } + | undefined; + +/** + * Apply a transformation function to every file of directory + * If source and destination are the same this function can be used to apply the transformation in place + * like filtering out some files or modifying them. + * */ +export function transformCodebase(params: { + srcDirPath: string; + destDirPath: string; + transformSourceCode?: TransformSourceCode; +}) { + const { srcDirPath, transformSourceCode } = params; + + const isTargetSameAsSource = + path.relative(srcDirPath, params.destDirPath) === ""; + + const destDirPath = isTargetSameAsSource + ? path.join(srcDirPath, "..", "tmp_xOsPdkPsTdzPs34sOkHs") + : params.destDirPath; + + fs.mkdirSync(destDirPath, { + recursive: true + }); + + for (const fileRelativePath of crawl({ + dirPath: srcDirPath, + returnedPathsType: "relative to dirPath" + })) { + const filePath = path.join(srcDirPath, fileRelativePath); + const destFilePath = path.join(destDirPath, fileRelativePath); + + // NOTE: Optimization, if we don't need to transform the file, just copy + // it using the lower level implementation. + if (transformSourceCode === undefined) { + fs.mkdirSync(path.dirname(destFilePath), { + recursive: true + }); + + fs.copyFileSync(filePath, destFilePath); + + continue; + } + + const transformSourceCodeResult = transformSourceCode({ + sourceCode: fs.readFileSync(filePath), + filePath, + fileRelativePath + }); + + if (transformSourceCodeResult === undefined) { + continue; + } + + fs.mkdirSync(path.dirname(destFilePath), { + recursive: true + }); + + const { newFileName, modifiedSourceCode } = transformSourceCodeResult; + + fs.writeFileSync( + path.join( + path.dirname(destFilePath), + newFileName ?? path.basename(destFilePath) + ), + modifiedSourceCode + ); + } + + if (isTargetSameAsSource) { + rmSync(srcDirPath, { recursive: true }); + + fs.renameSync(destDirPath, srcDirPath); + } +} diff --git a/src/tools/ReactHTML.tsx b/src/tools/ReactHTML.tsx index e0bf651..63b2941 100644 --- a/src/tools/ReactHTML.tsx +++ b/src/tools/ReactHTML.tsx @@ -2,7 +2,513 @@ import type * as React from "react"; // If not available (React 19+), fallback to this: export type ReactHTML = { - [K in keyof JSX.IntrinsicElements]: ( - props: JSX.IntrinsicElements[K] + [K in keyof JSXIntrinsicElements]: ( + props: JSXIntrinsicElements[K] ) => React.ReactElement; }; + +export interface JSXIntrinsicElements { + // HTML + a: React.DetailedHTMLProps< + React.AnchorHTMLAttributes, + HTMLAnchorElement + >; + abbr: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + address: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + area: React.DetailedHTMLProps< + React.AreaHTMLAttributes, + HTMLAreaElement + >; + article: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + aside: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + audio: React.DetailedHTMLProps< + React.AudioHTMLAttributes, + HTMLAudioElement + >; + b: React.DetailedHTMLProps, HTMLElement>; + base: React.DetailedHTMLProps< + React.BaseHTMLAttributes, + HTMLBaseElement + >; + bdi: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + bdo: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + big: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + blockquote: React.DetailedHTMLProps< + React.BlockquoteHTMLAttributes, + HTMLQuoteElement + >; + body: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLBodyElement + >; + br: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLBRElement + >; + button: React.DetailedHTMLProps< + React.ButtonHTMLAttributes, + HTMLButtonElement + >; + canvas: React.DetailedHTMLProps< + React.CanvasHTMLAttributes, + HTMLCanvasElement + >; + caption: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + cite: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + code: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + col: React.DetailedHTMLProps< + React.ColHTMLAttributes, + HTMLTableColElement + >; + colgroup: React.DetailedHTMLProps< + React.ColgroupHTMLAttributes, + HTMLTableColElement + >; + data: React.DetailedHTMLProps< + React.DataHTMLAttributes, + HTMLDataElement + >; + datalist: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDataListElement + >; + dd: React.DetailedHTMLProps, HTMLElement>; + del: React.DetailedHTMLProps< + React.DelHTMLAttributes, + HTMLModElement + >; + details: React.DetailedHTMLProps< + React.DetailsHTMLAttributes, + HTMLDetailsElement + >; + dfn: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + dialog: React.DetailedHTMLProps< + React.DialogHTMLAttributes, + HTMLDialogElement + >; + div: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDivElement + >; + dl: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLDListElement + >; + dt: React.DetailedHTMLProps, HTMLElement>; + em: React.DetailedHTMLProps, HTMLElement>; + embed: React.DetailedHTMLProps< + React.EmbedHTMLAttributes, + HTMLEmbedElement + >; + fieldset: React.DetailedHTMLProps< + React.FieldsetHTMLAttributes, + HTMLFieldSetElement + >; + figcaption: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + figure: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + footer: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + form: React.DetailedHTMLProps< + React.FormHTMLAttributes, + HTMLFormElement + >; + h1: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHeadingElement + >; + h2: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHeadingElement + >; + h3: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHeadingElement + >; + h4: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHeadingElement + >; + h5: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHeadingElement + >; + h6: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHeadingElement + >; + head: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHeadElement + >; + header: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + hgroup: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + hr: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLHRElement + >; + html: React.DetailedHTMLProps< + React.HtmlHTMLAttributes, + HTMLHtmlElement + >; + i: React.DetailedHTMLProps, HTMLElement>; + iframe: React.DetailedHTMLProps< + React.IframeHTMLAttributes, + HTMLIFrameElement + >; + img: React.DetailedHTMLProps< + React.ImgHTMLAttributes, + HTMLImageElement + >; + input: React.DetailedHTMLProps< + React.InputHTMLAttributes, + HTMLInputElement + >; + ins: React.DetailedHTMLProps< + React.InsHTMLAttributes, + HTMLModElement + >; + kbd: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + keygen: React.DetailedHTMLProps< + React.KeygenHTMLAttributes, + HTMLElement + >; + label: React.DetailedHTMLProps< + React.LabelHTMLAttributes, + HTMLLabelElement + >; + legend: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLLegendElement + >; + li: React.DetailedHTMLProps< + React.LiHTMLAttributes, + HTMLLIElement + >; + link: React.DetailedHTMLProps< + React.LinkHTMLAttributes, + HTMLLinkElement + >; + main: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + map: React.DetailedHTMLProps< + React.MapHTMLAttributes, + HTMLMapElement + >; + mark: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + menu: React.DetailedHTMLProps< + React.MenuHTMLAttributes, + HTMLElement + >; + menuitem: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + meta: React.DetailedHTMLProps< + React.MetaHTMLAttributes, + HTMLMetaElement + >; + meter: React.DetailedHTMLProps< + React.MeterHTMLAttributes, + HTMLMeterElement + >; + nav: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + noindex: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + noscript: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + object: React.DetailedHTMLProps< + React.ObjectHTMLAttributes, + HTMLObjectElement + >; + ol: React.DetailedHTMLProps< + React.OlHTMLAttributes, + HTMLOListElement + >; + optgroup: React.DetailedHTMLProps< + React.OptgroupHTMLAttributes, + HTMLOptGroupElement + >; + option: React.DetailedHTMLProps< + React.OptionHTMLAttributes, + HTMLOptionElement + >; + output: React.DetailedHTMLProps< + React.OutputHTMLAttributes, + HTMLOutputElement + >; + p: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLParagraphElement + >; + param: React.DetailedHTMLProps< + React.ParamHTMLAttributes, + HTMLParamElement + >; + picture: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + pre: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLPreElement + >; + progress: React.DetailedHTMLProps< + React.ProgressHTMLAttributes, + HTMLProgressElement + >; + q: React.DetailedHTMLProps< + React.QuoteHTMLAttributes, + HTMLQuoteElement + >; + rp: React.DetailedHTMLProps, HTMLElement>; + rt: React.DetailedHTMLProps, HTMLElement>; + ruby: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + s: React.DetailedHTMLProps, HTMLElement>; + samp: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + slot: React.DetailedHTMLProps< + React.SlotHTMLAttributes, + HTMLSlotElement + >; + script: React.DetailedHTMLProps< + React.ScriptHTMLAttributes, + HTMLScriptElement + >; + section: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + select: React.DetailedHTMLProps< + React.SelectHTMLAttributes, + HTMLSelectElement + >; + small: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + source: React.DetailedHTMLProps< + React.SourceHTMLAttributes, + HTMLSourceElement + >; + span: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLSpanElement + >; + strong: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + style: React.DetailedHTMLProps< + React.StyleHTMLAttributes, + HTMLStyleElement + >; + sub: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + summary: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + sup: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + table: React.DetailedHTMLProps< + React.TableHTMLAttributes, + HTMLTableElement + >; + template: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLTemplateElement + >; + tbody: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLTableSectionElement + >; + td: React.DetailedHTMLProps< + React.TdHTMLAttributes, + HTMLTableDataCellElement + >; + textarea: React.DetailedHTMLProps< + React.TextareaHTMLAttributes, + HTMLTextAreaElement + >; + tfoot: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLTableSectionElement + >; + th: React.DetailedHTMLProps< + React.ThHTMLAttributes, + HTMLTableHeaderCellElement + >; + thead: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLTableSectionElement + >; + time: React.DetailedHTMLProps< + React.TimeHTMLAttributes, + HTMLTimeElement + >; + title: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLTitleElement + >; + tr: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLTableRowElement + >; + track: React.DetailedHTMLProps< + React.TrackHTMLAttributes, + HTMLTrackElement + >; + u: React.DetailedHTMLProps, HTMLElement>; + ul: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLUListElement + >; + "var": React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + video: React.DetailedHTMLProps< + React.VideoHTMLAttributes, + HTMLVideoElement + >; + wbr: React.DetailedHTMLProps< + React.HTMLAttributes, + HTMLElement + >; + webview: React.DetailedHTMLProps< + React.WebViewHTMLAttributes, + HTMLWebViewElement + >; + + // SVG + svg: React.SVGProps; + + animate: React.SVGProps; // TODO: It is SVGAnimateElement but is not in TypeScript's lib.dom.d.ts for now. + animateMotion: React.SVGProps; + animateTransform: React.SVGProps; // TODO: It is SVGAnimateTransformElement but is not in TypeScript's lib.dom.d.ts for now. + circle: React.SVGProps; + clipPath: React.SVGProps; + defs: React.SVGProps; + desc: React.SVGProps; + ellipse: React.SVGProps; + feBlend: React.SVGProps; + feColorMatrix: React.SVGProps; + feComponentTransfer: React.SVGProps; + feComposite: React.SVGProps; + feConvolveMatrix: React.SVGProps; + feDiffuseLighting: React.SVGProps; + feDisplacementMap: React.SVGProps; + feDistantLight: React.SVGProps; + feDropShadow: React.SVGProps; + feFlood: React.SVGProps; + feFuncA: React.SVGProps; + feFuncB: React.SVGProps; + feFuncG: React.SVGProps; + feFuncR: React.SVGProps; + feGaussianBlur: React.SVGProps; + feImage: React.SVGProps; + feMerge: React.SVGProps; + feMergeNode: React.SVGProps; + feMorphology: React.SVGProps; + feOffset: React.SVGProps; + fePointLight: React.SVGProps; + feSpecularLighting: React.SVGProps; + feSpotLight: React.SVGProps; + feTile: React.SVGProps; + feTurbulence: React.SVGProps; + filter: React.SVGProps; + foreignObject: React.SVGProps; + g: React.SVGProps; + image: React.SVGProps; + line: React.SVGProps; + linearGradient: React.SVGProps; + marker: React.SVGProps; + mask: React.SVGProps; + metadata: React.SVGProps; + mpath: React.SVGProps; + path: React.SVGProps; + pattern: React.SVGProps; + polygon: React.SVGProps; + polyline: React.SVGProps; + radialGradient: React.SVGProps; + rect: React.SVGProps; + stop: React.SVGProps; + switch: React.SVGProps; + symbol: React.SVGProps; + text: React.SVGProps; + textPath: React.SVGProps; + tspan: React.SVGProps; + use: React.SVGProps; + view: React.SVGProps; +} From 3f86023f73633469f665f4b891e959c305844d98 Mon Sep 17 00:00:00 2001 From: garronej Date: Wed, 7 May 2025 15:53:36 +0200 Subject: [PATCH 2/4] Release candidate --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f9f1654..1c90a88 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tss-react", - "version": "4.9.17", + "version": "4.9.18-rc.1", "description": "Type safe CSS-in-JS API heavily inspired by react-jss", "repository": { "type": "git", From e8316aabd49b32a0223a771cfb684c30be8f361d Mon Sep 17 00:00:00 2001 From: garronej Date: Wed, 7 May 2025 16:15:58 +0200 Subject: [PATCH 3/4] Avoid declaring embiant for enabeling skipLibCheck to be false (#228 follow up) --- src/makeStyles.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/makeStyles.tsx b/src/makeStyles.tsx index c6dcbb2..9ad07a5 100644 --- a/src/makeStyles.tsx +++ b/src/makeStyles.tsx @@ -18,12 +18,10 @@ import type { MuiThemeStyleOverridesPluginParams, MuiThemeLike } from "./mui/themeStyleOverridesPlugin"; +// @ts-expect-error: It's not declared but it's there. +import { __unsafe_useEmotionCache } from "@emotion/react"; -declare module "@emotion/react" { - export function __unsafe_useEmotionCache(): EmotionCache | null; -} - -import { __unsafe_useEmotionCache as useContextualCache } from "@emotion/react"; +const useContextualCache: () => EmotionCache | null = __unsafe_useEmotionCache; let counter = 0; From b43a10b43e616bf3fbe64c3b83651989df302233 Mon Sep 17 00:00:00 2001 From: garronej Date: Wed, 7 May 2025 16:17:31 +0200 Subject: [PATCH 4/4] Release candidate --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c90a88..d6c73de 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tss-react", - "version": "4.9.18-rc.1", + "version": "4.9.18-rc.2", "description": "Type safe CSS-in-JS API heavily inspired by react-jss", "repository": { "type": "git",