@react-email/button 0.2.1-tailwindv4.0 → 0.2.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/button.tsx"],"sourcesContent":[],"mappings":";;;KAIY,WAAA,GAAc,SAAS,KAAA,CAAM;;EAA7B,UAAA,aAAW,CAAA;IAAA,aAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;IAAY,YAAM,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;;;AAA+B,cAmC3D,MAnC2D,EAmCrD,KAAA,CAAA,yBAnCqD,CAmCrD,QAnCqD,CAmCrD,IAnCqD,CAmCrD,KAAA,CAAA,iBAnCqD,CAmCrD,KAAA,CAAA,oBAnCqD,CAmCrD,iBAnCqD,CAAA,EAmCrD,iBAnCqD,CAAA,EAAA,KAAA,CAAA,CAAA,GAmCrD,KAAA,CAAA,aAnCqD,CAmCrD,iBAnCqD,CAAA,CAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/button.tsx"],"sourcesContent":[],"mappings":";;;KAIY,WAAA,GAAc,SAAS,KAAA,CAAM;;EAA7B,UAAA,aAAW,CAAA;IAAiD,aAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;IAAA,YAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;;;AAAA,cAmC3D,MAnC2D,EAmCrD,KAAA,CAAA,yBAnCqD,CAmCrD,QAnCqD,CAmCrD,IAnCqD,CAmCrD,KAAA,CAAA,iBAnCqD,CAmCrD,KAAA,CAAA,oBAnCqD,CAmCrD,iBAnCqD,CAAA,EAmCrD,iBAnCqD,CAAA,EAAA,KAAA,CAAA,CAAA,GAmCrD,KAAA,CAAA,aAnCqD,CAmCrD,iBAnCqD,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/button.tsx"],"sourcesContent":[],"mappings":";;;KAIY,WAAA,GAAc,SAAS,KAAA,CAAM;;EAA7B,UAAA,aAAW,CAAA;IAAA,aAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;IAAY,YAAM,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;;;AAA+B,cAmC3D,MAnC2D,EAmCrD,KAAA,CAAA,yBAnCqD,CAmCrD,QAnCqD,CAmCrD,IAnCqD,CAmCrD,KAAA,CAAA,iBAnCqD,CAmCrD,KAAA,CAAA,oBAnCqD,CAmCrD,iBAnCqD,CAAA,EAmCrD,iBAnCqD,CAAA,EAAA,KAAA,CAAA,CAAA,GAmCrD,KAAA,CAAA,aAnCqD,CAmCrD,iBAnCqD,CAAA,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/button.tsx"],"sourcesContent":[],"mappings":";;;KAIY,WAAA,GAAc,SAAS,KAAA,CAAM;;EAA7B,UAAA,aAAW,CAAA;IAAiD,aAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;IAAA,YAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,SAAA;;;AAAA,cAmC3D,MAnC2D,EAmCrD,KAAA,CAAA,yBAnCqD,CAmCrD,QAnCqD,CAmCrD,IAnCqD,CAmCrD,KAAA,CAAA,iBAnCqD,CAmCrD,KAAA,CAAA,oBAnCqD,CAmCrD,iBAnCqD,CAAA,EAmCrD,iBAnCqD,CAAA,EAAA,KAAA,CAAA,CAAA,GAmCrD,KAAA,CAAA,aAnCqD,CAmCrD,iBAnCqD,CAAA,CAAA"}
package/dist/index.js CHANGED
@@ -138,8 +138,7 @@ function computeFontWidthAndSpaceCount(expectedWidth) {
138
138
  }
139
139
  const Button = react.forwardRef(({ children, style, target = "_blank",...props }, ref) => {
140
140
  const { paddingTop, paddingRight, paddingBottom, paddingLeft } = parsePadding(style ?? {});
141
- const y = (paddingTop ?? 0) + (paddingBottom ?? 0);
142
- const textRaise = pxToPt(y);
141
+ const textRaise = pxToPt((paddingTop ?? 0) + (paddingBottom ?? 0));
143
142
  const [plFontWidth, plSpaceCount] = computeFontWidthAndSpaceCount(paddingLeft ?? 0);
144
143
  const [prFontWidth, prSpaceCount] = computeFontWidthAndSpaceCount(paddingRight ?? 0);
145
144
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
@@ -175,7 +174,6 @@ const Button = react.forwardRef(({ children, style, target = "_blank",...props }
175
174
  });
176
175
  });
177
176
  Button.displayName = "Button";
178
- Button.tailwindTreatAsElement = true;
179
177
 
180
178
  //#endregion
181
179
  exports.Button = Button;
package/dist/index.mjs CHANGED
@@ -113,8 +113,7 @@ function computeFontWidthAndSpaceCount(expectedWidth) {
113
113
  }
114
114
  const Button = React.forwardRef(({ children, style, target = "_blank",...props }, ref) => {
115
115
  const { paddingTop, paddingRight, paddingBottom, paddingLeft } = parsePadding(style ?? {});
116
- const y = (paddingTop ?? 0) + (paddingBottom ?? 0);
117
- const textRaise = pxToPt(y);
116
+ const textRaise = pxToPt((paddingTop ?? 0) + (paddingBottom ?? 0));
118
117
  const [plFontWidth, plSpaceCount] = computeFontWidthAndSpaceCount(paddingLeft ?? 0);
119
118
  const [prFontWidth, prSpaceCount] = computeFontWidthAndSpaceCount(paddingRight ?? 0);
120
119
  return /* @__PURE__ */ jsxs("a", {
@@ -150,7 +149,6 @@ const Button = React.forwardRef(({ children, style, target = "_blank",...props }
150
149
  });
151
150
  });
152
151
  Button.displayName = "Button";
153
- Button.tailwindTreatAsElement = true;
154
152
 
155
153
  //#endregion
156
154
  export { Button };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["paddingTop: string | number | undefined","paddingRight: string | number | undefined","paddingBottom: string | number | undefined","paddingLeft: string | number | undefined"],"sources":["../src/utils/parse-padding.ts","../src/utils/px-to-pt.ts","../src/button.tsx"],"sourcesContent":["type PaddingType = string | number | undefined;\n\ninterface PaddingProperties {\n padding?: PaddingType;\n paddingTop?: PaddingType;\n paddingRight?: PaddingType;\n paddingBottom?: PaddingType;\n paddingLeft?: PaddingType;\n}\n\n/**\n * converts padding value to `px` equivalent.\n * @example \"1em\" =\\> 16\n */\nexport function convertToPx(value: PaddingType) {\n let px = 0;\n\n if (!value) {\n return px;\n }\n\n if (typeof value === 'number') {\n return value;\n }\n\n const matches = /^([\\d.]+)(px|em|rem|%)$/.exec(value);\n\n if (matches && matches.length === 3) {\n const numValue = Number.parseFloat(matches[1]);\n const unit = matches[2];\n\n switch (unit) {\n case 'px':\n return numValue;\n case 'em':\n case 'rem':\n px = numValue * 16;\n return px;\n case '%':\n px = (numValue / 100) * 600;\n return px;\n default:\n return numValue;\n }\n }\n return 0;\n}\n\nfunction parsePaddingValue(value: PaddingType) {\n if (typeof value === 'number')\n return {\n paddingTop: value,\n paddingBottom: value,\n paddingLeft: value,\n paddingRight: value,\n };\n\n if (typeof value === 'string') {\n const values = value.toString().trim().split(/\\s+/);\n\n if (values.length === 1) {\n return {\n paddingTop: values[0],\n paddingBottom: values[0],\n paddingLeft: values[0],\n paddingRight: values[0],\n };\n }\n\n if (values.length === 2) {\n return {\n paddingTop: values[0],\n paddingRight: values[1],\n paddingBottom: values[0],\n paddingLeft: values[1],\n };\n }\n\n if (values.length === 3) {\n return {\n paddingTop: values[0],\n paddingRight: values[1],\n paddingBottom: values[2],\n paddingLeft: values[1],\n };\n }\n\n if (values.length === 4) {\n return {\n paddingTop: values[0],\n paddingRight: values[1],\n paddingBottom: values[2],\n paddingLeft: values[3],\n };\n }\n }\n\n return {\n paddingTop: undefined,\n paddingBottom: undefined,\n paddingLeft: undefined,\n paddingRight: undefined,\n };\n}\n\n/**\n * Parses all the values out of a padding string to get the value for all padding props in `px`\n * @example e.g. \"10px\" =\\> pt: 10, pr: 10, pb: 10, pl: 10\n */\nexport function parsePadding(properties: PaddingProperties) {\n let paddingTop: string | number | undefined;\n let paddingRight: string | number | undefined;\n let paddingBottom: string | number | undefined;\n let paddingLeft: string | number | undefined;\n\n for (const [key, value] of Object.entries(properties)) {\n if (key === 'padding') {\n ({ paddingTop, paddingBottom, paddingLeft, paddingRight } =\n parsePaddingValue(value));\n } else if (key === 'paddingTop') {\n paddingTop = value;\n } else if (key === 'paddingRight') {\n paddingRight = value;\n } else if (key === 'paddingBottom') {\n paddingBottom = value;\n } else if (key === 'paddingLeft') {\n paddingLeft = value;\n }\n }\n\n return {\n paddingTop: paddingTop ? convertToPx(paddingTop) : undefined,\n paddingRight: paddingRight ? convertToPx(paddingRight) : undefined,\n paddingBottom: paddingBottom ? convertToPx(paddingBottom) : undefined,\n paddingLeft: paddingLeft ? convertToPx(paddingLeft) : undefined,\n };\n}\n","export const pxToPt = (px: number | undefined): number | undefined =>\n typeof px === 'number' && !Number.isNaN(Number(px))\n ? (px * 3) / 4\n : undefined;\n","import * as React from 'react';\nimport { parsePadding } from './utils/parse-padding';\nimport { pxToPt } from './utils/px-to-pt';\n\nexport type ButtonProps = Readonly<React.ComponentPropsWithoutRef<'a'>>;\n\nconst maxFontWidth = 5;\n\n/**\n * Computes a msoFontWidth \\<= 5 and a count of space characters that,\n * when applied, end up being as close to `expectedWidth` as possible.\n */\nfunction computeFontWidthAndSpaceCount(expectedWidth: number) {\n if (expectedWidth === 0) return [0, 0] as const;\n\n let smallestSpaceCount = 0;\n\n const computeRequiredFontWidth = () => {\n if (smallestSpaceCount > 0) {\n return expectedWidth / smallestSpaceCount / 2;\n }\n\n return Number.POSITIVE_INFINITY;\n };\n\n while (computeRequiredFontWidth() > maxFontWidth) {\n smallestSpaceCount++;\n }\n\n return [computeRequiredFontWidth(), smallestSpaceCount] as const;\n}\n\ndeclare module 'react' {\n interface CSSProperties {\n msoPaddingAlt?: string | number | undefined;\n msoTextRaise?: string | number | undefined;\n }\n}\n\nexport const Button = React.forwardRef<HTMLAnchorElement, ButtonProps>(\n ({ children, style, target = '_blank', ...props }, ref) => {\n const { paddingTop, paddingRight, paddingBottom, paddingLeft } =\n parsePadding(style ?? {});\n\n const y = (paddingTop ?? 0) + (paddingBottom ?? 0);\n const textRaise = pxToPt(y);\n\n const [plFontWidth, plSpaceCount] = computeFontWidthAndSpaceCount(\n paddingLeft ?? 0,\n );\n const [prFontWidth, prSpaceCount] = computeFontWidthAndSpaceCount(\n paddingRight ?? 0,\n );\n\n return (\n <a\n {...props}\n ref={ref}\n style={{\n lineHeight: '100%',\n textDecoration: 'none',\n display: 'inline-block',\n maxWidth: '100%',\n msoPaddingAlt: '0px',\n ...style,\n paddingTop,\n paddingRight,\n paddingBottom,\n paddingLeft,\n }}\n target={target}\n >\n <span\n dangerouslySetInnerHTML={{\n // The `&#8202;` is as close to `1px` of an empty character as we can get, then, we use the `mso-font-width`\n // to scale it according to what padding the developer wants. `mso-font-width` also does not allow for percentages\n // >= 500% so we need to add extra spaces accordingly.\n //\n // See https://github.com/resend/react-email/issues/1512 for why we do not use letter-spacing instead.\n __html: `<!--[if mso]><i style=\"mso-font-width:${\n plFontWidth * 100\n }%;mso-text-raise:${textRaise}\" hidden>${'&#8202;'.repeat(\n plSpaceCount,\n )}</i><![endif]-->`,\n }}\n />\n <span\n style={{\n maxWidth: '100%',\n display: 'inline-block',\n lineHeight: '120%',\n msoPaddingAlt: '0px',\n msoTextRaise: pxToPt(paddingBottom),\n }}\n >\n {children}\n </span>\n <span\n dangerouslySetInnerHTML={{\n __html: `<!--[if mso]><i style=\"mso-font-width:${\n prFontWidth * 100\n }%\" hidden>${'&#8202;'.repeat(\n prSpaceCount,\n )}&#8203;</i><![endif]-->`,\n }}\n />\n </a>\n );\n },\n);\n\nButton.displayName = 'Button';\n(Button as any).tailwindTreatAsElement = true;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["paddingTop: string | number | undefined","paddingRight: string | number | undefined","paddingBottom: string | number | undefined","paddingLeft: string | number | undefined"],"sources":["../src/utils/parse-padding.ts","../src/utils/px-to-pt.ts","../src/button.tsx"],"sourcesContent":["type PaddingType = string | number | undefined;\n\ninterface PaddingProperties {\n padding?: PaddingType;\n paddingTop?: PaddingType;\n paddingRight?: PaddingType;\n paddingBottom?: PaddingType;\n paddingLeft?: PaddingType;\n}\n\n/**\n * converts padding value to `px` equivalent.\n * @example \"1em\" =\\> 16\n */\nexport function convertToPx(value: PaddingType) {\n let px = 0;\n\n if (!value) {\n return px;\n }\n\n if (typeof value === 'number') {\n return value;\n }\n\n const matches = /^([\\d.]+)(px|em|rem|%)$/.exec(value);\n\n if (matches && matches.length === 3) {\n const numValue = Number.parseFloat(matches[1]);\n const unit = matches[2];\n\n switch (unit) {\n case 'px':\n return numValue;\n case 'em':\n case 'rem':\n px = numValue * 16;\n return px;\n case '%':\n px = (numValue / 100) * 600;\n return px;\n default:\n return numValue;\n }\n }\n return 0;\n}\n\nfunction parsePaddingValue(value: PaddingType) {\n if (typeof value === 'number')\n return {\n paddingTop: value,\n paddingBottom: value,\n paddingLeft: value,\n paddingRight: value,\n };\n\n if (typeof value === 'string') {\n const values = value.toString().trim().split(/\\s+/);\n\n if (values.length === 1) {\n return {\n paddingTop: values[0],\n paddingBottom: values[0],\n paddingLeft: values[0],\n paddingRight: values[0],\n };\n }\n\n if (values.length === 2) {\n return {\n paddingTop: values[0],\n paddingRight: values[1],\n paddingBottom: values[0],\n paddingLeft: values[1],\n };\n }\n\n if (values.length === 3) {\n return {\n paddingTop: values[0],\n paddingRight: values[1],\n paddingBottom: values[2],\n paddingLeft: values[1],\n };\n }\n\n if (values.length === 4) {\n return {\n paddingTop: values[0],\n paddingRight: values[1],\n paddingBottom: values[2],\n paddingLeft: values[3],\n };\n }\n }\n\n return {\n paddingTop: undefined,\n paddingBottom: undefined,\n paddingLeft: undefined,\n paddingRight: undefined,\n };\n}\n\n/**\n * Parses all the values out of a padding string to get the value for all padding props in `px`\n * @example e.g. \"10px\" =\\> pt: 10, pr: 10, pb: 10, pl: 10\n */\nexport function parsePadding(properties: PaddingProperties) {\n let paddingTop: string | number | undefined;\n let paddingRight: string | number | undefined;\n let paddingBottom: string | number | undefined;\n let paddingLeft: string | number | undefined;\n\n for (const [key, value] of Object.entries(properties)) {\n if (key === 'padding') {\n ({ paddingTop, paddingBottom, paddingLeft, paddingRight } =\n parsePaddingValue(value));\n } else if (key === 'paddingTop') {\n paddingTop = value;\n } else if (key === 'paddingRight') {\n paddingRight = value;\n } else if (key === 'paddingBottom') {\n paddingBottom = value;\n } else if (key === 'paddingLeft') {\n paddingLeft = value;\n }\n }\n\n return {\n paddingTop: paddingTop ? convertToPx(paddingTop) : undefined,\n paddingRight: paddingRight ? convertToPx(paddingRight) : undefined,\n paddingBottom: paddingBottom ? convertToPx(paddingBottom) : undefined,\n paddingLeft: paddingLeft ? convertToPx(paddingLeft) : undefined,\n };\n}\n","export const pxToPt = (px: number | undefined): number | undefined =>\n typeof px === 'number' && !Number.isNaN(Number(px))\n ? (px * 3) / 4\n : undefined;\n","import * as React from 'react';\nimport { parsePadding } from './utils/parse-padding';\nimport { pxToPt } from './utils/px-to-pt';\n\nexport type ButtonProps = Readonly<React.ComponentPropsWithoutRef<'a'>>;\n\nconst maxFontWidth = 5;\n\n/**\n * Computes a msoFontWidth \\<= 5 and a count of space characters that,\n * when applied, end up being as close to `expectedWidth` as possible.\n */\nfunction computeFontWidthAndSpaceCount(expectedWidth: number) {\n if (expectedWidth === 0) return [0, 0] as const;\n\n let smallestSpaceCount = 0;\n\n const computeRequiredFontWidth = () => {\n if (smallestSpaceCount > 0) {\n return expectedWidth / smallestSpaceCount / 2;\n }\n\n return Number.POSITIVE_INFINITY;\n };\n\n while (computeRequiredFontWidth() > maxFontWidth) {\n smallestSpaceCount++;\n }\n\n return [computeRequiredFontWidth(), smallestSpaceCount] as const;\n}\n\ndeclare module 'react' {\n interface CSSProperties {\n msoPaddingAlt?: string | number | undefined;\n msoTextRaise?: string | number | undefined;\n }\n}\n\nexport const Button = React.forwardRef<HTMLAnchorElement, ButtonProps>(\n ({ children, style, target = '_blank', ...props }, ref) => {\n const { paddingTop, paddingRight, paddingBottom, paddingLeft } =\n parsePadding(style ?? {});\n\n const y = (paddingTop ?? 0) + (paddingBottom ?? 0);\n const textRaise = pxToPt(y);\n\n const [plFontWidth, plSpaceCount] = computeFontWidthAndSpaceCount(\n paddingLeft ?? 0,\n );\n const [prFontWidth, prSpaceCount] = computeFontWidthAndSpaceCount(\n paddingRight ?? 0,\n );\n\n return (\n <a\n {...props}\n ref={ref}\n style={{\n lineHeight: '100%',\n textDecoration: 'none',\n display: 'inline-block',\n maxWidth: '100%',\n msoPaddingAlt: '0px',\n ...style,\n paddingTop,\n paddingRight,\n paddingBottom,\n paddingLeft,\n }}\n target={target}\n >\n <span\n dangerouslySetInnerHTML={{\n // The `&#8202;` is as close to `1px` of an empty character as we can get, then, we use the `mso-font-width`\n // to scale it according to what padding the developer wants. `mso-font-width` also does not allow for percentages\n // >= 500% so we need to add extra spaces accordingly.\n //\n // See https://github.com/resend/react-email/issues/1512 for why we do not use letter-spacing instead.\n __html: `<!--[if mso]><i style=\"mso-font-width:${\n plFontWidth * 100\n }%;mso-text-raise:${textRaise}\" hidden>${'&#8202;'.repeat(\n plSpaceCount,\n )}</i><![endif]-->`,\n }}\n />\n <span\n style={{\n maxWidth: '100%',\n display: 'inline-block',\n lineHeight: '120%',\n msoPaddingAlt: '0px',\n msoTextRaise: pxToPt(paddingBottom),\n }}\n >\n {children}\n </span>\n <span\n dangerouslySetInnerHTML={{\n __html: `<!--[if mso]><i style=\"mso-font-width:${\n prFontWidth * 100\n }%\" hidden>${'&#8202;'.repeat(\n prSpaceCount,\n )}&#8203;</i><![endif]-->`,\n }}\n />\n </a>\n );\n },\n);\n\nButton.displayName = 'Button';\n"],"mappings":";;;;;;;;AAcA,SAAgB,YAAY,OAAoB;CAC9C,IAAI,KAAK;AAET,KAAI,CAAC,MACH,QAAO;AAGT,KAAI,OAAO,UAAU,SACnB,QAAO;CAGT,MAAM,UAAU,0BAA0B,KAAK,MAAM;AAErD,KAAI,WAAW,QAAQ,WAAW,GAAG;EACnC,MAAM,WAAW,OAAO,WAAW,QAAQ,GAAG;AAG9C,UAFa,QAAQ,IAErB;GACE,KAAK,KACH,QAAO;GACT,KAAK;GACL,KAAK;AACH,SAAK,WAAW;AAChB,WAAO;GACT,KAAK;AACH,SAAM,WAAW,MAAO;AACxB,WAAO;GACT,QACE,QAAO;;;AAGb,QAAO;;AAGT,SAAS,kBAAkB,OAAoB;AAC7C,KAAI,OAAO,UAAU,SACnB,QAAO;EACL,YAAY;EACZ,eAAe;EACf,aAAa;EACb,cAAc;EACf;AAEH,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,SAAS,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,MAAM;AAEnD,MAAI,OAAO,WAAW,EACpB,QAAO;GACL,YAAY,OAAO;GACnB,eAAe,OAAO;GACtB,aAAa,OAAO;GACpB,cAAc,OAAO;GACtB;AAGH,MAAI,OAAO,WAAW,EACpB,QAAO;GACL,YAAY,OAAO;GACnB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,aAAa,OAAO;GACrB;AAGH,MAAI,OAAO,WAAW,EACpB,QAAO;GACL,YAAY,OAAO;GACnB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,aAAa,OAAO;GACrB;AAGH,MAAI,OAAO,WAAW,EACpB,QAAO;GACL,YAAY,OAAO;GACnB,cAAc,OAAO;GACrB,eAAe,OAAO;GACtB,aAAa,OAAO;GACrB;;AAIL,QAAO;EACL,YAAY;EACZ,eAAe;EACf,aAAa;EACb,cAAc;EACf;;;;;;AAOH,SAAgB,aAAa,YAA+B;CAC1D,IAAIA;CACJ,IAAIC;CACJ,IAAIC;CACJ,IAAIC;AAEJ,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,CACnD,KAAI,QAAQ,UACV,EAAC,CAAE,YAAY,eAAe,aAAa,gBACzC,kBAAkB,MAAM;UACjB,QAAQ,aACjB,cAAa;UACJ,QAAQ,eACjB,gBAAe;UACN,QAAQ,gBACjB,iBAAgB;UACP,QAAQ,cACjB,eAAc;AAIlB,QAAO;EACL,YAAY,aAAa,YAAY,WAAW,GAAG;EACnD,cAAc,eAAe,YAAY,aAAa,GAAG;EACzD,eAAe,gBAAgB,YAAY,cAAc,GAAG;EAC5D,aAAa,cAAc,YAAY,YAAY,GAAG;EACvD;;;;;ACvIH,MAAa,UAAU,OACrB,OAAO,OAAO,YAAY,CAAC,OAAO,MAAM,OAAO,GAAG,CAAC,GAC9C,KAAK,IAAK,IACX;;;;ACGN,MAAM,eAAe;;;;;AAMrB,SAAS,8BAA8B,eAAuB;AAC5D,KAAI,kBAAkB,EAAG,QAAO,CAAC,GAAG,EAAE;CAEtC,IAAI,qBAAqB;CAEzB,MAAM,iCAAiC;AACrC,MAAI,qBAAqB,EACvB,QAAO,gBAAgB,qBAAqB;AAG9C,SAAO,OAAO;;AAGhB,QAAO,0BAA0B,GAAG,aAClC;AAGF,QAAO,CAAC,0BAA0B,EAAE,mBAAmB;;AAUzD,MAAa,SAAS,MAAM,YACzB,EAAE,UAAU,OAAO,SAAS,SAAU,GAAG,SAAS,QAAQ;CACzD,MAAM,EAAE,YAAY,cAAc,eAAe,gBAC/C,aAAa,SAAS,EAAE,CAAC;CAG3B,MAAM,YAAY,QADP,cAAc,MAAM,iBAAiB,GACrB;CAE3B,MAAM,CAAC,aAAa,gBAAgB,8BAClC,eAAe,EAChB;CACD,MAAM,CAAC,aAAa,gBAAgB,8BAClC,gBAAgB,EACjB;AAED,QACE,qBAAC;EACC,GAAI;EACC;EACL,OAAO;GACL,YAAY;GACZ,gBAAgB;GAChB,SAAS;GACT,UAAU;GACV,eAAe;GACf,GAAG;GACH;GACA;GACA;GACA;GACD;EACO;;GAER,oBAAC,UACC,yBAAyB,EAMvB,QAAQ,yCACN,cAAc,IACf,mBAAmB,UAAU,WAAW,UAAU,OACjD,aACD,CAAC,mBACH,GACD;GACF,oBAAC;IACC,OAAO;KACL,UAAU;KACV,SAAS;KACT,YAAY;KACZ,eAAe;KACf,cAAc,OAAO,cAAc;KACpC;IAEA;KACI;GACP,oBAAC,UACC,yBAAyB,EACvB,QAAQ,yCACN,cAAc,IACf,YAAY,UAAU,OACrB,aACD,CAAC,0BACH,GACD;;GACA;EAGT;AAED,OAAO,cAAc"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-email/button",
3
- "version": "0.2.1-tailwindv4.0",
3
+ "version": "0.2.1",
4
4
  "description": "A link that is styled to look like a button",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -32,14 +32,14 @@
32
32
  "email"
33
33
  ],
34
34
  "engines": {
35
- "node": ">=18.0.0"
35
+ "node": ">=20.0.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": "^18.0 || ^19.0 || ^19.0.0-rc"
39
39
  },
40
40
  "devDependencies": {
41
41
  "typescript": "5.8.3",
42
- "@react-email/render": "1.3.1",
42
+ "@react-email/render": "2.0.1",
43
43
  "tsconfig": "0.0.0"
44
44
  },
45
45
  "publishConfig": {