diff --git a/packages/next-yak/dist/index.cjs b/packages/next-yak/dist/index.cjs index 2ef6d6f8..51f3604f 100644 --- a/packages/next-yak/dist/index.cjs +++ b/packages/next-yak/dist/index.cjs @@ -1,2 +1,2 @@ -"use strict";var F=Object.create;var T=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var v=(t,e)=>{for(var s in e)T(t,s,{get:e[s],enumerable:!0})},d=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of O(e))!j.call(t,n)&&n!==s&&T(t,n,{get:()=>e[n],enumerable:!(o=w(e,n))||o.enumerable});return t};var E=(t,e,s)=>(s=t!=null?F(R(t)):{},d(e||!t||!t.__esModule?T(s,"default",{value:t,enumerable:!0}):s,t)),_=t=>d(T({},"__esModule",{value:!0}),t);var $={};v($,{YakThemeProvider:()=>y.YakThemeProvider,atoms:()=>h,css:()=>l,keyframes:()=>b,styled:()=>x,useTheme:()=>y.useTheme});module.exports=_($);var B=(...t)=>{let e=[],s=[],o={};for(let n of t)if(typeof n=="string")e.push(n);else if(typeof n=="function")s.push(n);else if(typeof n=="object"&&"style"in n)for(let r in n.style){let c=n.style[r];typeof c=="function"?s.push(a=>({style:{[r]:String(A(a,c))}})):o[r]=c}if(s.length===0){let n=e.join(" ");return()=>({className:n,style:o})}return n=>{let r=[...e],c={...o};for(let a=0;a{let n=e(t);for(;n;){if(typeof n=="function"){n=n(t);continue}else if(typeof n=="object"&&("className"in n&&n.className&&s.push(n.className),"style"in n&&n.style))for(let r in n.style)o[r]=n.style[r];break}},A=(t,e)=>{let s=e(t);if(typeof s=="function")return A(t,s);if(process.env.NODE_ENV==="development"&&typeof s!="string"&&typeof s!="number"&&!(s instanceof String))throw new Error(`Dynamic CSS functions must return a string or number but returned ${JSON.stringify(s)}`);return s},l=B;var p=E(require("react"),1),C=require("next-yak/context"),Y={},J=t=>Object.assign(p.default.forwardRef(t),{component:t}),X=t=>Object.assign(P(t),{attrs:e=>P(t,e)}),P=(t,e)=>(s,...o)=>{let n=l(s,...o),r=a=>K(a,typeof e=="function"?e(a):e);return J((a,S)=>{let f=e||n.length?(0,C.useTheme)():Y,m=r({theme:f,...a}),u=n(m),{theme:N,...g}=m,i=typeof t=="string"?H(g):N===f?g:m;return i.className=I(i.className,u.className),i.style="style"in i?{...i.style,...u.style}:u.style,typeof t!="string"&&"yak"in t?t.yak(i,S):(i.ref=S,p.default.createElement(t,{...i}))})},x=new Proxy(X,{get(t,e){return t(e)}});function H(t){let e={};for(let s in t)s.startsWith("$")||(e[s]=t[s]);return e}var I=(t,e)=>t?e?t+" "+e:t:e,k=t=>{let e={};for(let s in t)t[s]!==void 0&&(e[s]=t[s]);return e},K=(t,e)=>e?{..."$__attrs"in t?{...k(e),...t}:{...t,...k(e)},className:I(t.className,e.className),style:{...t.style||{},...e.style||{}},$__attrs:!0}:t;var h=(...t)=>{let e=t.join(" ");return()=>({className:e})};var b=(t,...e)=>t;var y=require("next-yak/context");0&&(module.exports={YakThemeProvider,atoms,css,keyframes,styled,useTheme}); +"use strict";var O=Object.create;var T=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var v=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var _=(t,e)=>{for(var s in e)T(t,s,{get:e[s],enumerable:!0})},A=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of j(e))!E.call(t,n)&&n!==s&&T(t,n,{get:()=>e[n],enumerable:!(o=R(e,n))||o.enumerable});return t};var B=(t,e,s)=>(s=t!=null?O(v(t)):{},A(e||!t||!t.__esModule?T(s,"default",{value:t,enumerable:!0}):s,t)),Y=t=>A(T({},"__esModule",{value:!0}),t);var U={};_(U,{YakThemeProvider:()=>y.YakThemeProvider,atoms:()=>b,css:()=>l,keyframes:()=>N,styled:()=>I,useTheme:()=>y.useTheme});module.exports=Y(U);var M=(...t)=>{let e=[],s=[],o={};for(let n of t)if(typeof n=="string")e.push(n);else if(typeof n=="function")s.push(n);else if(typeof n=="object"&&"style"in n)for(let r in n.style){let c=n.style[r];typeof c=="function"?s.push(a=>({style:{[r]:String(P(a,c))}})):o[r]=c}if(s.length===0){let n=e.join(" ");return()=>({className:n,style:o})}return n=>{let r=[...e],c={...o};for(let a=0;a{let n=e(t);for(;n;){if(typeof n=="function"){n=n(t);continue}else if(typeof n=="object"&&("className"in n&&n.className&&s.push(n.className),"style"in n&&n.style))for(let r in n.style)o[r]=n.style[r];break}},P=(t,e)=>{let s=e(t);if(typeof s=="function")return P(t,s);if(process.env.NODE_ENV==="development"&&typeof s!="string"&&typeof s!="number"&&!(s instanceof String))throw new Error(`Dynamic CSS functions must return a string or number but returned ${JSON.stringify(s)}`);return s},l=M;var p=B(require("react"),1),x=require("next-yak/context"),X={},H=t=>Object.assign(p.default.forwardRef(t),{yak:t}),K=t=>Object.assign(k(t),{attrs:e=>k(t,e)}),k=(t,e)=>(s,...o)=>{let n=l(s,...o),r=a=>L(a,typeof e=="function"?e(a):e);return H((a,S)=>{let f=e||n.length?(0,x.useTheme)():X,m=r({theme:f,...a}),u=n(m),{theme:F,...w}=m,g=F===f?w:m,d=typeof t!="string"&&"yak"in t,i=d?g:$(g);return i.className=h(i.className,u.className),i.style="style"in i?{...i.style,...u.style}:u.style,d?t.yak(i,S):(i.ref=S,p.default.createElement(t,{...i}))})},I=new Proxy(K,{get(t,e){return t(e)}});function $(t){let e={};for(let s in t)s.startsWith("$")||(e[s]=t[s]);return e}var h=(t,e)=>t?e?t+" "+e:t:e,C=t=>{let e={};for(let s in t)t[s]!==void 0&&(e[s]=t[s]);return e},L=(t,e)=>e?{..."$__attrs"in t?{...C(e),...t}:{...t,...C(e)},className:h(t.className,e.className),style:{...t.style||{},...e.style||{}},$__attrs:!0}:t;var b=(...t)=>{let e=t.join(" ");return()=>({className:e})};var N=(t,...e)=>t;var y=require("next-yak/context");0&&(module.exports={YakThemeProvider,atoms,css,keyframes,styled,useTheme}); //# sourceMappingURL=index.cjs.map \ No newline at end of file diff --git a/packages/next-yak/dist/index.cjs.map b/packages/next-yak/dist/index.cjs.map index 13a4bbd8..96bdfeee 100644 --- a/packages/next-yak/dist/index.cjs.map +++ b/packages/next-yak/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"sources":["../runtime/index.ts","../runtime/cssLiteral.tsx","../runtime/styled.tsx","../runtime/atoms.tsx","../runtime/keyframes.tsx"],"sourcesContent":["export { css } from \"./cssLiteral.js\";\nexport { styled } from \"./styled.js\";\nexport { atoms } from \"./atoms.js\";\nexport { keyframes } from \"./keyframes.js\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nexport { useTheme, YakThemeProvider } from \"next-yak/context\";\n\nexport type { YakTheme } from \"./context/index.d.ts\";\n","import type { YakTheme } from \"./index.d.ts\";\n\ntype ComponentStyles = (props: TProps) => {\n className: string;\n style?: {\n [key: string]: string;\n };\n};\n\nexport type CSSInterpolation =\n | string\n | number\n | undefined\n | null\n | false\n | ComponentStyles\n | {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n __yak: true;\n }\n | ((props: TProps) => CSSInterpolation);\n\ntype CSSStyles = {\n style: { [key: string]: string | ((props: TProps) => string) };\n};\n\ntype CSSFunction = (\n styles: TemplateStringsArray,\n ...values: CSSInterpolation[]\n) => ComponentStyles;\n\ntype PropsToClassNameFn = (props: unknown) =>\n | {\n className?: string;\n style?: Record;\n }\n | PropsToClassNameFn;\n\n/**\n * css() runtime factory of css``\n *\n * /!\\ next-yak transpiles css`` and styled``\n *\n * This changes the typings of the css`` and styled`` functions.\n * During development the user of next-yak wants to work with the\n * typings BEFORE compilation.\n *\n * Therefore this is only an internal function only and it must be cast to any\n * before exported to the user.\n */\nconst internalCssFactory = (\n ...args: Array>\n) => {\n const classNames: string[] = [];\n const dynamicCssFunctions: PropsToClassNameFn[] = [];\n const style: Record = {};\n for (const arg of args) {\n // A CSS-module class name which got auto generated during build from static css\n // e.g. css`color: red;`\n // compiled -> css(\"yak31e4\")\n if (typeof arg === \"string\") {\n classNames.push(arg);\n }\n // Dynamic CSS e.g.\n // css`${props => props.active && css`color: red;`}`\n // compiled -> css((props: { active: boolean }) => props.active && css(\"yak31e4\"))\n else if (typeof arg === \"function\") {\n dynamicCssFunctions.push(arg as unknown as PropsToClassNameFn);\n }\n // Dynamic CSS with css variables e.g.\n // css`transform: translate(${props => props.x}, ${props => props.y});`\n // compiled -> css(\"yak31e4\", { style: { \"--yakVarX\": props => props.x }, \"--yakVarY\": props => props.y }})\n else if (typeof arg === \"object\" && \"style\" in arg) {\n for (const key in arg.style) {\n const value = arg.style[key];\n if (typeof value === \"function\") {\n dynamicCssFunctions.push((props: unknown) => ({\n style: {\n [key]: String(\n // The value for a css value can be a theme dependent function e.g.:\n // const borderColor = (props: { theme: { mode: \"dark\" | \"light\" } }) => props.theme === \"dark\" ? \"black\" : \"white\";\n // css`border-color: ${borderColor};`\n // Therefore the value has to be extracted recursively\n recursivePropExecution(props, value),\n ),\n },\n }));\n } else {\n style[key] = value;\n }\n }\n }\n }\n\n // Non Dynamic CSS\n if (dynamicCssFunctions.length === 0) {\n const className = classNames.join(\" \");\n return () => ({ className, style });\n }\n\n return (props: unknown) => {\n const allClassNames: string[] = [...classNames];\n const allStyles: Record = { ...style };\n for (let i = 0; i < dynamicCssFunctions.length; i++) {\n unwrapProps(props, dynamicCssFunctions[i], allClassNames, allStyles);\n }\n return {\n className: allClassNames.join(\" \"),\n style: allStyles,\n };\n };\n};\n\n// Dynamic CSS with runtime logic\nconst unwrapProps = (\n props: unknown,\n fn: PropsToClassNameFn,\n classNames: string[],\n style: Record,\n) => {\n let result = fn(props);\n while (result) {\n if (typeof result === \"function\") {\n result = result(props);\n continue;\n } else if (typeof result === \"object\") {\n if (\"className\" in result && result.className) {\n classNames.push(result.className);\n }\n if (\"style\" in result && result.style) {\n for (const key in result.style) {\n style[key] = result.style[key];\n }\n }\n }\n break;\n }\n};\n\nconst recursivePropExecution = (\n props: unknown,\n fn: (props: unknown) => any,\n): string | number => {\n const result = fn(props);\n if (typeof result === \"function\") {\n return recursivePropExecution(props, result);\n }\n if (process.env.NODE_ENV === \"development\") {\n if (\n typeof result !== \"string\" &&\n typeof result !== \"number\" &&\n !(result instanceof String)\n ) {\n throw new Error(\n `Dynamic CSS functions must return a string or number but returned ${JSON.stringify(\n result,\n )}`,\n );\n }\n }\n return result;\n};\n\nexport const css = internalCssFactory as any as CSSFunction;\n","import { ForwardRefRenderFunction, FunctionComponent } from \"react\";\nimport { CSSInterpolation, css } from \"./cssLiteral.js\";\nimport React from \"react\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nimport { useTheme } from \"next-yak/context\";\nimport type { YakTheme } from \"./context/index.d.ts\";\n\n/** Symbol */\nconst noTheme = {};\n\n/**\n * Hack to hide .yak from the type definition and to deal with ExoticComponents\n */\nconst yakForwardRef: (\n component: ForwardRefRenderFunction,\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: `__yak` is undefined during runtime\n __yak: true;\n} = (component) =>\n Object.assign(React.forwardRef(component), { component }) as any;\n\n/**\n * All valid html tags\n */\ntype HtmlTags = keyof JSX.IntrinsicElements;\n\n/**\n * Return type of the provided props merged with the initial props\n * where the specified props are optional\n */\ntype AttrsMerged = Substitute<\n TBaseProps & { theme: YakTheme },\n TIn\n>;\n\n/**\n * The attrs function allows to add additional props to a styled component.\n * The props can be specified as an object or as a function that receives the\n * current props as argument.\n */\ntype Attrs<\n TBaseProps,\n TIn extends object = {},\n TOut extends AttrsMerged = AttrsMerged,\n> =\n | Partial\n | ((p: Substitute) => Partial);\n\n//\n// The `styled()` and `styled.` API\n//\n// The API design is inspired by styled-components:\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/constructors/styled.tsx\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/models/StyledComponent.ts\n//\n\nconst StyledFactory = (Component: HtmlTags | FunctionComponent) =>\n Object.assign(yakStyled(Component), {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n >(\n attrs: Attrs,\n ) => yakStyled(Component, attrs),\n });\n\nconst yakStyled = <\n T,\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n>(\n Component: FunctionComponent | HtmlTags,\n attrs?: Attrs,\n) => {\n return (\n styles: TemplateStringsArray,\n ...values: Array>\n ) => {\n const getRuntimeStyles = css(styles, ...values);\n const processAttrs = (props: Substitute) =>\n combineProps(\n props,\n typeof attrs === \"function\" ? (attrs as Function)(props) : attrs,\n );\n const yak = (props: Substitute, ref: unknown) => {\n // if the css component does not require arguments\n // it can be call without arguments and skip calling useTheme()\n //\n // `__yak` is NOT against the rule of hooks as\n // getRuntimeStyles is a constant defined outside of the component\n //\n // for example\n //\n // const Button = styled.button`color: red;`\n // ^ does not need to have access to theme\n //\n // const Button = styled.button`${({ theme }) => css`color: ${theme.color};`}`\n // ^ must be have acces to theme\n const theme = attrs || getRuntimeStyles.length ? useTheme() : noTheme;\n /** The combined props are passed into the styled`` literal functions */\n const combinedProps: Substitute = processAttrs({\n theme,\n ...props,\n } as Substitute);\n // execute all functions inside the style literal\n // e.g. styled.button`color: ${props => props.color};`\n const runtimeStyles = getRuntimeStyles(combinedProps as any);\n\n // delete the yak theme from the props\n // this must happen after the runtimeStyles are calculated\n // prevents passing the theme prop to the DOM element of a styled component\n const { theme: themeAfterAttr, ...combinedPropsWithoutTheme } =\n combinedProps as { theme?: unknown };\n\n // remove all props that start with a $ sign for string components e.g. \"button\" or \"div\"\n // so that they are not passed to the DOM element\n const filteredProps =\n typeof Component === \"string\"\n ? removePrefixedProperties(combinedPropsWithoutTheme)\n : themeAfterAttr === theme\n ? combinedPropsWithoutTheme\n : combinedProps;\n\n // yak provides a className and style prop that needs to be merged with the\n // user provided className and style prop\n (filteredProps as { className?: string }).className = mergeClassNames(\n (filteredProps as { className?: string }).className,\n runtimeStyles.className as string,\n );\n (filteredProps as { style?: React.CSSProperties }).style =\n \"style\" in filteredProps\n ? {\n ...(filteredProps as { style?: React.CSSProperties }).style,\n ...runtimeStyles.style,\n }\n : runtimeStyles.style;\n // if the styled(Component) syntax is used and the component is a yak component\n // we can call the yak function directly to avoid an unnecessary wrapper with an additional\n // forwardRef call\n if (typeof Component !== \"string\" && \"yak\" in Component) {\n return (\n Component as typeof Component & {\n yak: FunctionComponent;\n }\n ).yak(filteredProps, ref);\n }\n\n (filteredProps as { ref?: unknown }).ref = ref;\n return ;\n };\n return yakForwardRef(yak);\n };\n};\n\n/**\n * Type for the proxy object returned by `styled` that allows to\n * access all html tags as properties.\n */\ntype StyledLiteral = (\n styles: TemplateStringsArray,\n ...values: Array>\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: this is undefined during runtime\n __yak: true;\n};\n\n/**\n * The `styled` method works perfectly on all of your own or any third-party component,\n * as long as they attach the passed className prop to a DOM element.\n *\n * @usage\n *\n * ```tsx\n * const StyledLink = styled(Link)`\n * color: #BF4F74;\n * font-weight: bold;\n * `;\n * ```\n */\nexport const styled = new Proxy(\n StyledFactory as typeof StyledFactory & {\n [Tag in HtmlTags]: StyledLiteral & {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged<\n JSX.IntrinsicElements[Tag],\n TAttrsIn\n > = AttrsMerged,\n >(\n attrs: Attrs,\n ) => StyledLiteral>;\n };\n },\n {\n get(target, TagName: keyof JSX.IntrinsicElements) {\n return target(TagName);\n },\n },\n);\n\n// Remove all entries that start with a $ sign\nfunction removePrefixedProperties>(obj: T) {\n const result = {} as T;\n for (const key in obj) {\n if (!key.startsWith(\"$\")) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\nconst mergeClassNames = (a?: string, b?: string) => {\n if (!a) return b;\n if (!b) return a;\n return a + \" \" + b;\n};\n\nconst removeUndefined = (obj: T) => {\n const result = {} as T;\n for (const key in obj) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n return result;\n};\n\nconst combineProps = <\n T extends {\n className?: string;\n style?: React.CSSProperties;\n },\n>(\n props: T,\n newProps: T,\n) => {\n if (!newProps) return props;\n const combinedProps: T =\n \"$__attrs\" in props\n ? // allow overriding props when attrs was used previously\n {\n ...removeUndefined(newProps),\n ...props,\n }\n : {\n ...props,\n ...removeUndefined(newProps),\n };\n return {\n ...combinedProps,\n className: mergeClassNames(\n props.className as string,\n newProps.className as string,\n ),\n style: { ...(props.style || {}), ...(newProps.style || {}) },\n $__attrs: true,\n };\n};\n\n// util type to remove properties from an object\ntype FastOmit = {\n [K in keyof T as K extends U ? never : K]: T[K];\n};\n\n// util type to merge two objects\n// if a property is present in both objects the property from B is used\nexport type Substitute = FastOmit<\n A,\n keyof B\n> &\n B;\n","/**\n * Allows to use atomic CSS classes in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, atoms } from \"next-yak\";\n *\n * const Button = styled.button<{ $primary?: boolean }>`\n * ${atoms(\"text-teal-600\", \"text-base\", \"rounded-md\")}\n * ${props => props.$primary && atoms(\"shadow-md\")}\n * `;\n * ```\n */\nexport const atoms = (...atoms: string[]) => {\n const className = atoms.join(\" \");\n return () => ({ className });\n};\n","/**\n * Allows to use CSS keyframe animations in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, keyframes } from \"next-yak\";\n *\n * const rotate = keyframes`\n * from {\n * transform: rotate(0deg);\n * }\n * to {\n * transform: rotate(360deg);\n * }\n * `;\n *\n * const Spinner = styled.div`\n * animation: ${rotate} 1s linear infinite;\n * `;\n * ```\n */\nexport const keyframes = (\n styles: TemplateStringsArray,\n ...dynamic: never[]\n): string => {\n // during compilation all args of keyframe are compiled\n // to a string which references the animation name\n return styles as any as string;\n};\n"],"mappings":"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","names":["runtime_exports","__export","atoms","css","keyframes","styled","__toCommonJS","internalCssFactory","args","classNames","dynamicCssFunctions","style","arg","key","value","props","recursivePropExecution","className","allClassNames","allStyles","i","unwrapProps","fn","result","css","import_react","import_context","noTheme","yakForwardRef","component","React","StyledFactory","Component","yakStyled","attrs","styles","values","getRuntimeStyles","css","processAttrs","props","combineProps","ref","theme","combinedProps","runtimeStyles","themeAfterAttr","combinedPropsWithoutTheme","filteredProps","removePrefixedProperties","mergeClassNames","styled","target","TagName","obj","result","key","a","b","removeUndefined","newProps","atoms","className","keyframes","styles","dynamic","import_context"]} \ No newline at end of file +{"version":3,"sources":["../runtime/index.ts","../runtime/cssLiteral.tsx","../runtime/styled.tsx","../runtime/atoms.tsx","../runtime/keyframes.tsx"],"sourcesContent":["export { css } from \"./cssLiteral.js\";\nexport { styled } from \"./styled.js\";\nexport { atoms } from \"./atoms.js\";\nexport { keyframes } from \"./keyframes.js\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nexport { useTheme, YakThemeProvider } from \"next-yak/context\";\n\nexport type { YakTheme } from \"./context/index.d.ts\";\n","import type { YakTheme } from \"./index.d.ts\";\n\ntype ComponentStyles = (props: TProps) => {\n className: string;\n style?: {\n [key: string]: string;\n };\n};\n\nexport type CSSInterpolation =\n | string\n | number\n | undefined\n | null\n | false\n | ComponentStyles\n | {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n __yak: true;\n }\n | ((props: TProps) => CSSInterpolation);\n\ntype CSSStyles = {\n style: { [key: string]: string | ((props: TProps) => string) };\n};\n\ntype CSSFunction = (\n styles: TemplateStringsArray,\n ...values: CSSInterpolation[]\n) => ComponentStyles;\n\ntype PropsToClassNameFn = (props: unknown) =>\n | {\n className?: string;\n style?: Record;\n }\n | PropsToClassNameFn;\n\n/**\n * css() runtime factory of css``\n *\n * /!\\ next-yak transpiles css`` and styled``\n *\n * This changes the typings of the css`` and styled`` functions.\n * During development the user of next-yak wants to work with the\n * typings BEFORE compilation.\n *\n * Therefore this is only an internal function only and it must be cast to any\n * before exported to the user.\n */\nconst internalCssFactory = (\n ...args: Array>\n) => {\n const classNames: string[] = [];\n const dynamicCssFunctions: PropsToClassNameFn[] = [];\n const style: Record = {};\n for (const arg of args) {\n // A CSS-module class name which got auto generated during build from static css\n // e.g. css`color: red;`\n // compiled -> css(\"yak31e4\")\n if (typeof arg === \"string\") {\n classNames.push(arg);\n }\n // Dynamic CSS e.g.\n // css`${props => props.active && css`color: red;`}`\n // compiled -> css((props: { active: boolean }) => props.active && css(\"yak31e4\"))\n else if (typeof arg === \"function\") {\n dynamicCssFunctions.push(arg as unknown as PropsToClassNameFn);\n }\n // Dynamic CSS with css variables e.g.\n // css`transform: translate(${props => props.x}, ${props => props.y});`\n // compiled -> css(\"yak31e4\", { style: { \"--yakVarX\": props => props.x }, \"--yakVarY\": props => props.y }})\n else if (typeof arg === \"object\" && \"style\" in arg) {\n for (const key in arg.style) {\n const value = arg.style[key];\n if (typeof value === \"function\") {\n dynamicCssFunctions.push((props: unknown) => ({\n style: {\n [key]: String(\n // The value for a css value can be a theme dependent function e.g.:\n // const borderColor = (props: { theme: { mode: \"dark\" | \"light\" } }) => props.theme === \"dark\" ? \"black\" : \"white\";\n // css`border-color: ${borderColor};`\n // Therefore the value has to be extracted recursively\n recursivePropExecution(props, value),\n ),\n },\n }));\n } else {\n style[key] = value;\n }\n }\n }\n }\n\n // Non Dynamic CSS\n if (dynamicCssFunctions.length === 0) {\n const className = classNames.join(\" \");\n return () => ({ className, style });\n }\n\n return (props: unknown) => {\n const allClassNames: string[] = [...classNames];\n const allStyles: Record = { ...style };\n for (let i = 0; i < dynamicCssFunctions.length; i++) {\n unwrapProps(props, dynamicCssFunctions[i], allClassNames, allStyles);\n }\n return {\n className: allClassNames.join(\" \"),\n style: allStyles,\n };\n };\n};\n\n// Dynamic CSS with runtime logic\nconst unwrapProps = (\n props: unknown,\n fn: PropsToClassNameFn,\n classNames: string[],\n style: Record,\n) => {\n let result = fn(props);\n while (result) {\n if (typeof result === \"function\") {\n result = result(props);\n continue;\n } else if (typeof result === \"object\") {\n if (\"className\" in result && result.className) {\n classNames.push(result.className);\n }\n if (\"style\" in result && result.style) {\n for (const key in result.style) {\n style[key] = result.style[key];\n }\n }\n }\n break;\n }\n};\n\nconst recursivePropExecution = (\n props: unknown,\n fn: (props: unknown) => any,\n): string | number => {\n const result = fn(props);\n if (typeof result === \"function\") {\n return recursivePropExecution(props, result);\n }\n if (process.env.NODE_ENV === \"development\") {\n if (\n typeof result !== \"string\" &&\n typeof result !== \"number\" &&\n !(result instanceof String)\n ) {\n throw new Error(\n `Dynamic CSS functions must return a string or number but returned ${JSON.stringify(\n result,\n )}`,\n );\n }\n }\n return result;\n};\n\nexport const css = internalCssFactory as any as CSSFunction;\n","import { ForwardRefRenderFunction, FunctionComponent } from \"react\";\nimport { CSSInterpolation, css } from \"./cssLiteral.js\";\nimport React from \"react\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nimport { useTheme } from \"next-yak/context\";\nimport type { YakTheme } from \"./context/index.d.ts\";\n\n/** Symbol */\nconst noTheme = {};\n\n/**\n * Hack to hide .yak from the type definition and to deal with ExoticComponents\n */\nconst yakForwardRef: (\n component: ForwardRefRenderFunction,\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: `__yak` is undefined during runtime\n __yak: true;\n} = (component) =>\n Object.assign(React.forwardRef(component), { yak: component }) as any;\n\n/**\n * All valid html tags\n */\ntype HtmlTags = keyof JSX.IntrinsicElements;\n\n/**\n * Return type of the provided props merged with the initial props\n * where the specified props are optional\n */\ntype AttrsMerged = Substitute<\n TBaseProps & { theme: YakTheme },\n TIn\n>;\n\n/**\n * The attrs function allows to add additional props to a styled component.\n * The props can be specified as an object or as a function that receives the\n * current props as argument.\n */\ntype Attrs<\n TBaseProps,\n TIn extends object = {},\n TOut extends AttrsMerged = AttrsMerged,\n> =\n | Partial\n | ((p: Substitute) => Partial);\n\n//\n// The `styled()` and `styled.` API\n//\n// The API design is inspired by styled-components:\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/constructors/styled.tsx\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/models/StyledComponent.ts\n//\n\nconst StyledFactory = (Component: HtmlTags | FunctionComponent) =>\n Object.assign(yakStyled(Component), {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n >(\n attrs: Attrs,\n ) => yakStyled(Component, attrs),\n });\n\nconst yakStyled = <\n T,\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n>(\n Component: FunctionComponent | HtmlTags,\n attrs?: Attrs,\n) => {\n return (\n styles: TemplateStringsArray,\n ...values: Array>\n ) => {\n const getRuntimeStyles = css(styles, ...values);\n const processAttrs = (props: Substitute) =>\n combineProps(\n props,\n typeof attrs === \"function\" ? (attrs as Function)(props) : attrs,\n );\n const yak = (props: Substitute, ref: unknown) => {\n // if the css component does not require arguments\n // it can be call without arguments and skip calling useTheme()\n //\n // `__yak` is NOT against the rule of hooks as\n // getRuntimeStyles is a constant defined outside of the component\n //\n // for example\n //\n // const Button = styled.button`color: red;`\n // ^ does not need to have access to theme\n //\n // const Button = styled.button`${({ theme }) => css`color: ${theme.color};`}`\n // ^ must be have acces to theme\n const theme = attrs || getRuntimeStyles.length ? useTheme() : noTheme;\n // execute attrs\n const combinedProps: Substitute = processAttrs({\n theme,\n ...props,\n } as Substitute);\n // execute all functions inside the style literal\n // e.g. styled.button`color: ${props => props.color};`\n const runtimeStyles = getRuntimeStyles(combinedProps as any);\n\n // delete the yak theme from the props\n // this must happen after the runtimeStyles are calculated\n // prevents passing the theme prop to the DOM element of a styled component\n const { theme: themeAfterAttr, ...combinedPropsWithoutTheme } =\n combinedProps as { theme?: unknown };\n const propsBeforeFiltering =\n themeAfterAttr === theme ? combinedPropsWithoutTheme : combinedProps;\n\n const isYakComponent =\n typeof Component !== \"string\" && \"yak\" in Component;\n\n // remove all props that start with a $ sign for string components e.g. \"button\" or \"div\"\n // so that they are not passed to the DOM element\n const filteredProps = !isYakComponent\n ? removePrefixedProperties(propsBeforeFiltering)\n : propsBeforeFiltering;\n\n // yak provides a className and style prop that needs to be merged with the\n // user provided className and style prop\n (filteredProps as { className?: string }).className = mergeClassNames(\n (filteredProps as { className?: string }).className,\n runtimeStyles.className as string,\n );\n (filteredProps as { style?: React.CSSProperties }).style =\n \"style\" in filteredProps\n ? {\n ...(filteredProps as { style?: React.CSSProperties }).style,\n ...runtimeStyles.style,\n }\n : runtimeStyles.style;\n // if the styled(Component) syntax is used and the component is a yak component\n // we can call the yak function directly to avoid an unnecessary wrapper with an additional\n // forwardRef call\n if (isYakComponent) {\n return (\n Component as typeof Component & {\n yak: FunctionComponent;\n }\n ).yak(filteredProps, ref);\n }\n (filteredProps as { ref?: unknown }).ref = ref;\n return ;\n };\n return yakForwardRef(yak);\n };\n};\n\n/**\n * Type for the proxy object returned by `styled` that allows to\n * access all html tags as properties.\n */\ntype StyledLiteral = (\n styles: TemplateStringsArray,\n ...values: Array>\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: this is undefined during runtime\n __yak: true;\n};\n\n/**\n * The `styled` method works perfectly on all of your own or any third-party component,\n * as long as they attach the passed className prop to a DOM element.\n *\n * @usage\n *\n * ```tsx\n * const StyledLink = styled(Link)`\n * color: #BF4F74;\n * font-weight: bold;\n * `;\n * ```\n */\nexport const styled = new Proxy(\n StyledFactory as typeof StyledFactory & {\n [Tag in HtmlTags]: StyledLiteral & {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged<\n JSX.IntrinsicElements[Tag],\n TAttrsIn\n > = AttrsMerged,\n >(\n attrs: Attrs,\n ) => StyledLiteral>;\n };\n },\n {\n get(target, TagName: keyof JSX.IntrinsicElements) {\n return target(TagName);\n },\n },\n);\n\n// Remove all entries that start with a $ sign\nfunction removePrefixedProperties>(obj: T) {\n const result = {} as T;\n for (const key in obj) {\n if (!key.startsWith(\"$\")) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\nconst mergeClassNames = (a?: string, b?: string) => {\n if (!a) return b;\n if (!b) return a;\n return a + \" \" + b;\n};\n\nconst removeUndefined = (obj: T) => {\n const result = {} as T;\n for (const key in obj) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n return result;\n};\n\nconst combineProps = <\n T extends {\n className?: string;\n style?: React.CSSProperties;\n },\n>(\n props: T,\n newProps: T,\n) => {\n if (!newProps) return props;\n const combinedProps: T =\n \"$__attrs\" in props\n ? // allow overriding props when attrs was used previously\n {\n ...removeUndefined(newProps),\n ...props,\n }\n : {\n ...props,\n ...removeUndefined(newProps),\n };\n return {\n ...combinedProps,\n className: mergeClassNames(\n props.className as string,\n newProps.className as string,\n ),\n style: { ...(props.style || {}), ...(newProps.style || {}) },\n $__attrs: true,\n };\n};\n\n// util type to remove properties from an object\ntype FastOmit = {\n [K in keyof T as K extends U ? never : K]: T[K];\n};\n\n// util type to merge two objects\n// if a property is present in both objects the property from B is used\nexport type Substitute = FastOmit<\n A,\n keyof B\n> &\n B;\n","/**\n * Allows to use atomic CSS classes in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, atoms } from \"next-yak\";\n *\n * const Button = styled.button<{ $primary?: boolean }>`\n * ${atoms(\"text-teal-600\", \"text-base\", \"rounded-md\")}\n * ${props => props.$primary && atoms(\"shadow-md\")}\n * `;\n * ```\n */\nexport const atoms = (...atoms: string[]) => {\n const className = atoms.join(\" \");\n return () => ({ className });\n};\n","/**\n * Allows to use CSS keyframe animations in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, keyframes } from \"next-yak\";\n *\n * const rotate = keyframes`\n * from {\n * transform: rotate(0deg);\n * }\n * to {\n * transform: rotate(360deg);\n * }\n * `;\n *\n * const Spinner = styled.div`\n * animation: ${rotate} 1s linear infinite;\n * `;\n * ```\n */\nexport const keyframes = (\n styles: TemplateStringsArray,\n ...dynamic: never[]\n): string => {\n // during compilation all args of keyframe are compiled\n // to a string which references the animation name\n return styles as any as string;\n};\n"],"mappings":"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","names":["runtime_exports","__export","atoms","css","keyframes","styled","__toCommonJS","internalCssFactory","args","classNames","dynamicCssFunctions","style","arg","key","value","props","recursivePropExecution","className","allClassNames","allStyles","i","unwrapProps","fn","result","css","import_react","import_context","noTheme","yakForwardRef","component","React","StyledFactory","Component","yakStyled","attrs","styles","values","getRuntimeStyles","css","processAttrs","props","combineProps","ref","theme","combinedProps","runtimeStyles","themeAfterAttr","combinedPropsWithoutTheme","propsBeforeFiltering","isYakComponent","filteredProps","removePrefixedProperties","mergeClassNames","styled","target","TagName","obj","result","key","a","b","removeUndefined","newProps","atoms","className","keyframes","styles","dynamic","import_context"]} \ No newline at end of file diff --git a/packages/next-yak/dist/index.js b/packages/next-yak/dist/index.js index 2c103e67..d36590e7 100644 --- a/packages/next-yak/dist/index.js +++ b/packages/next-yak/dist/index.js @@ -1,2 +1,2 @@ -var k=(...t)=>{let e=[],n=[],i={};for(let s of t)if(typeof s=="string")e.push(s);else if(typeof s=="function")n.push(s);else if(typeof s=="object"&&"style"in s)for(let r in s.style){let c=s.style[r];typeof c=="function"?n.push(o=>({style:{[r]:String(S(o,c))}})):i[r]=c}if(n.length===0){let s=e.join(" ");return()=>({className:s,style:i})}return s=>{let r=[...e],c={...i};for(let o=0;o{let s=e(t);for(;s;){if(typeof s=="function"){s=s(t);continue}else if(typeof s=="object"&&("className"in s&&s.className&&n.push(s.className),"style"in s&&s.style))for(let r in s.style)i[r]=s.style[r];break}},S=(t,e)=>{let n=e(t);if(typeof n=="function")return S(t,n);if(process.env.NODE_ENV==="development"&&typeof n!="string"&&typeof n!="number"&&!(n instanceof String))throw new Error(`Dynamic CSS functions must return a string or number but returned ${JSON.stringify(n)}`);return n},y=k;import d from"react";import{useTheme as x}from"next-yak/context";var I={},h=t=>Object.assign(d.forwardRef(t),{component:t}),b=t=>Object.assign(f(t),{attrs:e=>f(t,e)}),f=(t,e)=>(n,...i)=>{let s=y(n,...i),r=o=>w(o,typeof e=="function"?e(o):e);return h((o,m)=>{let u=e||s.length?x():I,T=r({theme:u,...o}),l=s(T),{theme:P,...p}=T,a=typeof t=="string"?F(p):P===u?p:T;return a.className=A(a.className,l.className),a.style="style"in a?{...a.style,...l.style}:l.style,typeof t!="string"&&"yak"in t?t.yak(a,m):(a.ref=m,d.createElement(t,{...a}))})},N=new Proxy(b,{get(t,e){return t(e)}});function F(t){let e={};for(let n in t)n.startsWith("$")||(e[n]=t[n]);return e}var A=(t,e)=>t?e?t+" "+e:t:e,g=t=>{let e={};for(let n in t)t[n]!==void 0&&(e[n]=t[n]);return e},w=(t,e)=>e?{..."$__attrs"in t?{...g(e),...t}:{...t,...g(e)},className:A(t.className,e.className),style:{...t.style||{},...e.style||{}},$__attrs:!0}:t;var O=(...t)=>{let e=t.join(" ");return()=>({className:e})};var R=(t,...e)=>t;import{useTheme as D,YakThemeProvider as W}from"next-yak/context";export{W as YakThemeProvider,O as atoms,y as css,R as keyframes,N as styled,D as useTheme}; +var x=(...t)=>{let e=[],n=[],i={};for(let s of t)if(typeof s=="string")e.push(s);else if(typeof s=="function")n.push(s);else if(typeof s=="object"&&"style"in s)for(let r in s.style){let c=s.style[r];typeof c=="function"?n.push(o=>({style:{[r]:String(f(o,c))}})):i[r]=c}if(n.length===0){let s=e.join(" ");return()=>({className:s,style:i})}return s=>{let r=[...e],c={...i};for(let o=0;o{let s=e(t);for(;s;){if(typeof s=="function"){s=s(t);continue}else if(typeof s=="object"&&("className"in s&&s.className&&n.push(s.className),"style"in s&&s.style))for(let r in s.style)i[r]=s.style[r];break}},f=(t,e)=>{let n=e(t);if(typeof n=="function")return f(t,n);if(process.env.NODE_ENV==="development"&&typeof n!="string"&&typeof n!="number"&&!(n instanceof String))throw new Error(`Dynamic CSS functions must return a string or number but returned ${JSON.stringify(n)}`);return n},y=x;import A from"react";import{useTheme as h}from"next-yak/context";var b={},N=t=>Object.assign(A.forwardRef(t),{yak:t}),F=t=>Object.assign(g(t),{attrs:e=>g(t,e)}),g=(t,e)=>(n,...i)=>{let s=y(n,...i),r=o=>R(o,typeof e=="function"?e(o):e);return N((o,m)=>{let u=e||s.length?h():b,T=r({theme:u,...o}),l=s(T),{theme:k,...C}=T,p=k===u?C:T,S=typeof t!="string"&&"yak"in t,a=S?p:O(p);return a.className=P(a.className,l.className),a.style="style"in a?{...a.style,...l.style}:l.style,S?t.yak(a,m):(a.ref=m,A.createElement(t,{...a}))})},w=new Proxy(F,{get(t,e){return t(e)}});function O(t){let e={};for(let n in t)n.startsWith("$")||(e[n]=t[n]);return e}var P=(t,e)=>t?e?t+" "+e:t:e,d=t=>{let e={};for(let n in t)t[n]!==void 0&&(e[n]=t[n]);return e},R=(t,e)=>e?{..."$__attrs"in t?{...d(e),...t}:{...t,...d(e)},className:P(t.className,e.className),style:{...t.style||{},...e.style||{}},$__attrs:!0}:t;var j=(...t)=>{let e=t.join(" ");return()=>({className:e})};var v=(t,...e)=>t;import{useTheme as V,YakThemeProvider as q}from"next-yak/context";export{q as YakThemeProvider,j as atoms,y as css,v as keyframes,w as styled,V as useTheme}; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/next-yak/dist/index.js.map b/packages/next-yak/dist/index.js.map index 75a13d4a..3f70dbb5 100644 --- a/packages/next-yak/dist/index.js.map +++ b/packages/next-yak/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../runtime/cssLiteral.tsx","../runtime/styled.tsx","../runtime/atoms.tsx","../runtime/keyframes.tsx","../runtime/index.ts"],"sourcesContent":["import type { YakTheme } from \"./index.d.ts\";\n\ntype ComponentStyles = (props: TProps) => {\n className: string;\n style?: {\n [key: string]: string;\n };\n};\n\nexport type CSSInterpolation =\n | string\n | number\n | undefined\n | null\n | false\n | ComponentStyles\n | {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n __yak: true;\n }\n | ((props: TProps) => CSSInterpolation);\n\ntype CSSStyles = {\n style: { [key: string]: string | ((props: TProps) => string) };\n};\n\ntype CSSFunction = (\n styles: TemplateStringsArray,\n ...values: CSSInterpolation[]\n) => ComponentStyles;\n\ntype PropsToClassNameFn = (props: unknown) =>\n | {\n className?: string;\n style?: Record;\n }\n | PropsToClassNameFn;\n\n/**\n * css() runtime factory of css``\n *\n * /!\\ next-yak transpiles css`` and styled``\n *\n * This changes the typings of the css`` and styled`` functions.\n * During development the user of next-yak wants to work with the\n * typings BEFORE compilation.\n *\n * Therefore this is only an internal function only and it must be cast to any\n * before exported to the user.\n */\nconst internalCssFactory = (\n ...args: Array>\n) => {\n const classNames: string[] = [];\n const dynamicCssFunctions: PropsToClassNameFn[] = [];\n const style: Record = {};\n for (const arg of args) {\n // A CSS-module class name which got auto generated during build from static css\n // e.g. css`color: red;`\n // compiled -> css(\"yak31e4\")\n if (typeof arg === \"string\") {\n classNames.push(arg);\n }\n // Dynamic CSS e.g.\n // css`${props => props.active && css`color: red;`}`\n // compiled -> css((props: { active: boolean }) => props.active && css(\"yak31e4\"))\n else if (typeof arg === \"function\") {\n dynamicCssFunctions.push(arg as unknown as PropsToClassNameFn);\n }\n // Dynamic CSS with css variables e.g.\n // css`transform: translate(${props => props.x}, ${props => props.y});`\n // compiled -> css(\"yak31e4\", { style: { \"--yakVarX\": props => props.x }, \"--yakVarY\": props => props.y }})\n else if (typeof arg === \"object\" && \"style\" in arg) {\n for (const key in arg.style) {\n const value = arg.style[key];\n if (typeof value === \"function\") {\n dynamicCssFunctions.push((props: unknown) => ({\n style: {\n [key]: String(\n // The value for a css value can be a theme dependent function e.g.:\n // const borderColor = (props: { theme: { mode: \"dark\" | \"light\" } }) => props.theme === \"dark\" ? \"black\" : \"white\";\n // css`border-color: ${borderColor};`\n // Therefore the value has to be extracted recursively\n recursivePropExecution(props, value),\n ),\n },\n }));\n } else {\n style[key] = value;\n }\n }\n }\n }\n\n // Non Dynamic CSS\n if (dynamicCssFunctions.length === 0) {\n const className = classNames.join(\" \");\n return () => ({ className, style });\n }\n\n return (props: unknown) => {\n const allClassNames: string[] = [...classNames];\n const allStyles: Record = { ...style };\n for (let i = 0; i < dynamicCssFunctions.length; i++) {\n unwrapProps(props, dynamicCssFunctions[i], allClassNames, allStyles);\n }\n return {\n className: allClassNames.join(\" \"),\n style: allStyles,\n };\n };\n};\n\n// Dynamic CSS with runtime logic\nconst unwrapProps = (\n props: unknown,\n fn: PropsToClassNameFn,\n classNames: string[],\n style: Record,\n) => {\n let result = fn(props);\n while (result) {\n if (typeof result === \"function\") {\n result = result(props);\n continue;\n } else if (typeof result === \"object\") {\n if (\"className\" in result && result.className) {\n classNames.push(result.className);\n }\n if (\"style\" in result && result.style) {\n for (const key in result.style) {\n style[key] = result.style[key];\n }\n }\n }\n break;\n }\n};\n\nconst recursivePropExecution = (\n props: unknown,\n fn: (props: unknown) => any,\n): string | number => {\n const result = fn(props);\n if (typeof result === \"function\") {\n return recursivePropExecution(props, result);\n }\n if (process.env.NODE_ENV === \"development\") {\n if (\n typeof result !== \"string\" &&\n typeof result !== \"number\" &&\n !(result instanceof String)\n ) {\n throw new Error(\n `Dynamic CSS functions must return a string or number but returned ${JSON.stringify(\n result,\n )}`,\n );\n }\n }\n return result;\n};\n\nexport const css = internalCssFactory as any as CSSFunction;\n","import { ForwardRefRenderFunction, FunctionComponent } from \"react\";\nimport { CSSInterpolation, css } from \"./cssLiteral.js\";\nimport React from \"react\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nimport { useTheme } from \"next-yak/context\";\nimport type { YakTheme } from \"./context/index.d.ts\";\n\n/** Symbol */\nconst noTheme = {};\n\n/**\n * Hack to hide .yak from the type definition and to deal with ExoticComponents\n */\nconst yakForwardRef: (\n component: ForwardRefRenderFunction,\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: `__yak` is undefined during runtime\n __yak: true;\n} = (component) =>\n Object.assign(React.forwardRef(component), { component }) as any;\n\n/**\n * All valid html tags\n */\ntype HtmlTags = keyof JSX.IntrinsicElements;\n\n/**\n * Return type of the provided props merged with the initial props\n * where the specified props are optional\n */\ntype AttrsMerged = Substitute<\n TBaseProps & { theme: YakTheme },\n TIn\n>;\n\n/**\n * The attrs function allows to add additional props to a styled component.\n * The props can be specified as an object or as a function that receives the\n * current props as argument.\n */\ntype Attrs<\n TBaseProps,\n TIn extends object = {},\n TOut extends AttrsMerged = AttrsMerged,\n> =\n | Partial\n | ((p: Substitute) => Partial);\n\n//\n// The `styled()` and `styled.` API\n//\n// The API design is inspired by styled-components:\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/constructors/styled.tsx\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/models/StyledComponent.ts\n//\n\nconst StyledFactory = (Component: HtmlTags | FunctionComponent) =>\n Object.assign(yakStyled(Component), {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n >(\n attrs: Attrs,\n ) => yakStyled(Component, attrs),\n });\n\nconst yakStyled = <\n T,\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n>(\n Component: FunctionComponent | HtmlTags,\n attrs?: Attrs,\n) => {\n return (\n styles: TemplateStringsArray,\n ...values: Array>\n ) => {\n const getRuntimeStyles = css(styles, ...values);\n const processAttrs = (props: Substitute) =>\n combineProps(\n props,\n typeof attrs === \"function\" ? (attrs as Function)(props) : attrs,\n );\n const yak = (props: Substitute, ref: unknown) => {\n // if the css component does not require arguments\n // it can be call without arguments and skip calling useTheme()\n //\n // `__yak` is NOT against the rule of hooks as\n // getRuntimeStyles is a constant defined outside of the component\n //\n // for example\n //\n // const Button = styled.button`color: red;`\n // ^ does not need to have access to theme\n //\n // const Button = styled.button`${({ theme }) => css`color: ${theme.color};`}`\n // ^ must be have acces to theme\n const theme = attrs || getRuntimeStyles.length ? useTheme() : noTheme;\n /** The combined props are passed into the styled`` literal functions */\n const combinedProps: Substitute = processAttrs({\n theme,\n ...props,\n } as Substitute);\n // execute all functions inside the style literal\n // e.g. styled.button`color: ${props => props.color};`\n const runtimeStyles = getRuntimeStyles(combinedProps as any);\n\n // delete the yak theme from the props\n // this must happen after the runtimeStyles are calculated\n // prevents passing the theme prop to the DOM element of a styled component\n const { theme: themeAfterAttr, ...combinedPropsWithoutTheme } =\n combinedProps as { theme?: unknown };\n\n // remove all props that start with a $ sign for string components e.g. \"button\" or \"div\"\n // so that they are not passed to the DOM element\n const filteredProps =\n typeof Component === \"string\"\n ? removePrefixedProperties(combinedPropsWithoutTheme)\n : themeAfterAttr === theme\n ? combinedPropsWithoutTheme\n : combinedProps;\n\n // yak provides a className and style prop that needs to be merged with the\n // user provided className and style prop\n (filteredProps as { className?: string }).className = mergeClassNames(\n (filteredProps as { className?: string }).className,\n runtimeStyles.className as string,\n );\n (filteredProps as { style?: React.CSSProperties }).style =\n \"style\" in filteredProps\n ? {\n ...(filteredProps as { style?: React.CSSProperties }).style,\n ...runtimeStyles.style,\n }\n : runtimeStyles.style;\n // if the styled(Component) syntax is used and the component is a yak component\n // we can call the yak function directly to avoid an unnecessary wrapper with an additional\n // forwardRef call\n if (typeof Component !== \"string\" && \"yak\" in Component) {\n return (\n Component as typeof Component & {\n yak: FunctionComponent;\n }\n ).yak(filteredProps, ref);\n }\n\n (filteredProps as { ref?: unknown }).ref = ref;\n return ;\n };\n return yakForwardRef(yak);\n };\n};\n\n/**\n * Type for the proxy object returned by `styled` that allows to\n * access all html tags as properties.\n */\ntype StyledLiteral = (\n styles: TemplateStringsArray,\n ...values: Array>\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: this is undefined during runtime\n __yak: true;\n};\n\n/**\n * The `styled` method works perfectly on all of your own or any third-party component,\n * as long as they attach the passed className prop to a DOM element.\n *\n * @usage\n *\n * ```tsx\n * const StyledLink = styled(Link)`\n * color: #BF4F74;\n * font-weight: bold;\n * `;\n * ```\n */\nexport const styled = new Proxy(\n StyledFactory as typeof StyledFactory & {\n [Tag in HtmlTags]: StyledLiteral & {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged<\n JSX.IntrinsicElements[Tag],\n TAttrsIn\n > = AttrsMerged,\n >(\n attrs: Attrs,\n ) => StyledLiteral>;\n };\n },\n {\n get(target, TagName: keyof JSX.IntrinsicElements) {\n return target(TagName);\n },\n },\n);\n\n// Remove all entries that start with a $ sign\nfunction removePrefixedProperties>(obj: T) {\n const result = {} as T;\n for (const key in obj) {\n if (!key.startsWith(\"$\")) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\nconst mergeClassNames = (a?: string, b?: string) => {\n if (!a) return b;\n if (!b) return a;\n return a + \" \" + b;\n};\n\nconst removeUndefined = (obj: T) => {\n const result = {} as T;\n for (const key in obj) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n return result;\n};\n\nconst combineProps = <\n T extends {\n className?: string;\n style?: React.CSSProperties;\n },\n>(\n props: T,\n newProps: T,\n) => {\n if (!newProps) return props;\n const combinedProps: T =\n \"$__attrs\" in props\n ? // allow overriding props when attrs was used previously\n {\n ...removeUndefined(newProps),\n ...props,\n }\n : {\n ...props,\n ...removeUndefined(newProps),\n };\n return {\n ...combinedProps,\n className: mergeClassNames(\n props.className as string,\n newProps.className as string,\n ),\n style: { ...(props.style || {}), ...(newProps.style || {}) },\n $__attrs: true,\n };\n};\n\n// util type to remove properties from an object\ntype FastOmit = {\n [K in keyof T as K extends U ? never : K]: T[K];\n};\n\n// util type to merge two objects\n// if a property is present in both objects the property from B is used\nexport type Substitute = FastOmit<\n A,\n keyof B\n> &\n B;\n","/**\n * Allows to use atomic CSS classes in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, atoms } from \"next-yak\";\n *\n * const Button = styled.button<{ $primary?: boolean }>`\n * ${atoms(\"text-teal-600\", \"text-base\", \"rounded-md\")}\n * ${props => props.$primary && atoms(\"shadow-md\")}\n * `;\n * ```\n */\nexport const atoms = (...atoms: string[]) => {\n const className = atoms.join(\" \");\n return () => ({ className });\n};\n","/**\n * Allows to use CSS keyframe animations in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, keyframes } from \"next-yak\";\n *\n * const rotate = keyframes`\n * from {\n * transform: rotate(0deg);\n * }\n * to {\n * transform: rotate(360deg);\n * }\n * `;\n *\n * const Spinner = styled.div`\n * animation: ${rotate} 1s linear infinite;\n * `;\n * ```\n */\nexport const keyframes = (\n styles: TemplateStringsArray,\n ...dynamic: never[]\n): string => {\n // during compilation all args of keyframe are compiled\n // to a string which references the animation name\n return styles as any as string;\n};\n","export { css } from \"./cssLiteral.js\";\nexport { styled } from \"./styled.js\";\nexport { atoms } from \"./atoms.js\";\nexport { keyframes } from \"./keyframes.js\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nexport { useTheme, YakThemeProvider } from \"next-yak/context\";\n\nexport type { YakTheme } from \"./context/index.d.ts\";\n"],"mappings":"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","names":["internalCssFactory","args","classNames","dynamicCssFunctions","style","arg","key","value","props","recursivePropExecution","className","allClassNames","allStyles","i","unwrapProps","fn","result","css","React","useTheme","noTheme","yakForwardRef","component","StyledFactory","Component","yakStyled","attrs","styles","values","getRuntimeStyles","css","processAttrs","props","combineProps","ref","theme","combinedProps","runtimeStyles","themeAfterAttr","combinedPropsWithoutTheme","filteredProps","removePrefixedProperties","mergeClassNames","styled","target","TagName","obj","result","key","a","b","removeUndefined","newProps","atoms","className","keyframes","styles","dynamic","useTheme","YakThemeProvider"]} \ No newline at end of file +{"version":3,"sources":["../runtime/cssLiteral.tsx","../runtime/styled.tsx","../runtime/atoms.tsx","../runtime/keyframes.tsx","../runtime/index.ts"],"sourcesContent":["import type { YakTheme } from \"./index.d.ts\";\n\ntype ComponentStyles = (props: TProps) => {\n className: string;\n style?: {\n [key: string]: string;\n };\n};\n\nexport type CSSInterpolation =\n | string\n | number\n | undefined\n | null\n | false\n | ComponentStyles\n | {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n __yak: true;\n }\n | ((props: TProps) => CSSInterpolation);\n\ntype CSSStyles = {\n style: { [key: string]: string | ((props: TProps) => string) };\n};\n\ntype CSSFunction = (\n styles: TemplateStringsArray,\n ...values: CSSInterpolation[]\n) => ComponentStyles;\n\ntype PropsToClassNameFn = (props: unknown) =>\n | {\n className?: string;\n style?: Record;\n }\n | PropsToClassNameFn;\n\n/**\n * css() runtime factory of css``\n *\n * /!\\ next-yak transpiles css`` and styled``\n *\n * This changes the typings of the css`` and styled`` functions.\n * During development the user of next-yak wants to work with the\n * typings BEFORE compilation.\n *\n * Therefore this is only an internal function only and it must be cast to any\n * before exported to the user.\n */\nconst internalCssFactory = (\n ...args: Array>\n) => {\n const classNames: string[] = [];\n const dynamicCssFunctions: PropsToClassNameFn[] = [];\n const style: Record = {};\n for (const arg of args) {\n // A CSS-module class name which got auto generated during build from static css\n // e.g. css`color: red;`\n // compiled -> css(\"yak31e4\")\n if (typeof arg === \"string\") {\n classNames.push(arg);\n }\n // Dynamic CSS e.g.\n // css`${props => props.active && css`color: red;`}`\n // compiled -> css((props: { active: boolean }) => props.active && css(\"yak31e4\"))\n else if (typeof arg === \"function\") {\n dynamicCssFunctions.push(arg as unknown as PropsToClassNameFn);\n }\n // Dynamic CSS with css variables e.g.\n // css`transform: translate(${props => props.x}, ${props => props.y});`\n // compiled -> css(\"yak31e4\", { style: { \"--yakVarX\": props => props.x }, \"--yakVarY\": props => props.y }})\n else if (typeof arg === \"object\" && \"style\" in arg) {\n for (const key in arg.style) {\n const value = arg.style[key];\n if (typeof value === \"function\") {\n dynamicCssFunctions.push((props: unknown) => ({\n style: {\n [key]: String(\n // The value for a css value can be a theme dependent function e.g.:\n // const borderColor = (props: { theme: { mode: \"dark\" | \"light\" } }) => props.theme === \"dark\" ? \"black\" : \"white\";\n // css`border-color: ${borderColor};`\n // Therefore the value has to be extracted recursively\n recursivePropExecution(props, value),\n ),\n },\n }));\n } else {\n style[key] = value;\n }\n }\n }\n }\n\n // Non Dynamic CSS\n if (dynamicCssFunctions.length === 0) {\n const className = classNames.join(\" \");\n return () => ({ className, style });\n }\n\n return (props: unknown) => {\n const allClassNames: string[] = [...classNames];\n const allStyles: Record = { ...style };\n for (let i = 0; i < dynamicCssFunctions.length; i++) {\n unwrapProps(props, dynamicCssFunctions[i], allClassNames, allStyles);\n }\n return {\n className: allClassNames.join(\" \"),\n style: allStyles,\n };\n };\n};\n\n// Dynamic CSS with runtime logic\nconst unwrapProps = (\n props: unknown,\n fn: PropsToClassNameFn,\n classNames: string[],\n style: Record,\n) => {\n let result = fn(props);\n while (result) {\n if (typeof result === \"function\") {\n result = result(props);\n continue;\n } else if (typeof result === \"object\") {\n if (\"className\" in result && result.className) {\n classNames.push(result.className);\n }\n if (\"style\" in result && result.style) {\n for (const key in result.style) {\n style[key] = result.style[key];\n }\n }\n }\n break;\n }\n};\n\nconst recursivePropExecution = (\n props: unknown,\n fn: (props: unknown) => any,\n): string | number => {\n const result = fn(props);\n if (typeof result === \"function\") {\n return recursivePropExecution(props, result);\n }\n if (process.env.NODE_ENV === \"development\") {\n if (\n typeof result !== \"string\" &&\n typeof result !== \"number\" &&\n !(result instanceof String)\n ) {\n throw new Error(\n `Dynamic CSS functions must return a string or number but returned ${JSON.stringify(\n result,\n )}`,\n );\n }\n }\n return result;\n};\n\nexport const css = internalCssFactory as any as CSSFunction;\n","import { ForwardRefRenderFunction, FunctionComponent } from \"react\";\nimport { CSSInterpolation, css } from \"./cssLiteral.js\";\nimport React from \"react\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nimport { useTheme } from \"next-yak/context\";\nimport type { YakTheme } from \"./context/index.d.ts\";\n\n/** Symbol */\nconst noTheme = {};\n\n/**\n * Hack to hide .yak from the type definition and to deal with ExoticComponents\n */\nconst yakForwardRef: (\n component: ForwardRefRenderFunction,\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: `__yak` is undefined during runtime\n __yak: true;\n} = (component) =>\n Object.assign(React.forwardRef(component), { yak: component }) as any;\n\n/**\n * All valid html tags\n */\ntype HtmlTags = keyof JSX.IntrinsicElements;\n\n/**\n * Return type of the provided props merged with the initial props\n * where the specified props are optional\n */\ntype AttrsMerged = Substitute<\n TBaseProps & { theme: YakTheme },\n TIn\n>;\n\n/**\n * The attrs function allows to add additional props to a styled component.\n * The props can be specified as an object or as a function that receives the\n * current props as argument.\n */\ntype Attrs<\n TBaseProps,\n TIn extends object = {},\n TOut extends AttrsMerged = AttrsMerged,\n> =\n | Partial\n | ((p: Substitute) => Partial);\n\n//\n// The `styled()` and `styled.` API\n//\n// The API design is inspired by styled-components:\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/constructors/styled.tsx\n// https://github.com/styled-components/styled-components/blob/main/packages/styled-components/src/models/StyledComponent.ts\n//\n\nconst StyledFactory = (Component: HtmlTags | FunctionComponent) =>\n Object.assign(yakStyled(Component), {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n >(\n attrs: Attrs,\n ) => yakStyled(Component, attrs),\n });\n\nconst yakStyled = <\n T,\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged = AttrsMerged,\n>(\n Component: FunctionComponent | HtmlTags,\n attrs?: Attrs,\n) => {\n return (\n styles: TemplateStringsArray,\n ...values: Array>\n ) => {\n const getRuntimeStyles = css(styles, ...values);\n const processAttrs = (props: Substitute) =>\n combineProps(\n props,\n typeof attrs === \"function\" ? (attrs as Function)(props) : attrs,\n );\n const yak = (props: Substitute, ref: unknown) => {\n // if the css component does not require arguments\n // it can be call without arguments and skip calling useTheme()\n //\n // `__yak` is NOT against the rule of hooks as\n // getRuntimeStyles is a constant defined outside of the component\n //\n // for example\n //\n // const Button = styled.button`color: red;`\n // ^ does not need to have access to theme\n //\n // const Button = styled.button`${({ theme }) => css`color: ${theme.color};`}`\n // ^ must be have acces to theme\n const theme = attrs || getRuntimeStyles.length ? useTheme() : noTheme;\n // execute attrs\n const combinedProps: Substitute = processAttrs({\n theme,\n ...props,\n } as Substitute);\n // execute all functions inside the style literal\n // e.g. styled.button`color: ${props => props.color};`\n const runtimeStyles = getRuntimeStyles(combinedProps as any);\n\n // delete the yak theme from the props\n // this must happen after the runtimeStyles are calculated\n // prevents passing the theme prop to the DOM element of a styled component\n const { theme: themeAfterAttr, ...combinedPropsWithoutTheme } =\n combinedProps as { theme?: unknown };\n const propsBeforeFiltering =\n themeAfterAttr === theme ? combinedPropsWithoutTheme : combinedProps;\n\n const isYakComponent =\n typeof Component !== \"string\" && \"yak\" in Component;\n\n // remove all props that start with a $ sign for string components e.g. \"button\" or \"div\"\n // so that they are not passed to the DOM element\n const filteredProps = !isYakComponent\n ? removePrefixedProperties(propsBeforeFiltering)\n : propsBeforeFiltering;\n\n // yak provides a className and style prop that needs to be merged with the\n // user provided className and style prop\n (filteredProps as { className?: string }).className = mergeClassNames(\n (filteredProps as { className?: string }).className,\n runtimeStyles.className as string,\n );\n (filteredProps as { style?: React.CSSProperties }).style =\n \"style\" in filteredProps\n ? {\n ...(filteredProps as { style?: React.CSSProperties }).style,\n ...runtimeStyles.style,\n }\n : runtimeStyles.style;\n // if the styled(Component) syntax is used and the component is a yak component\n // we can call the yak function directly to avoid an unnecessary wrapper with an additional\n // forwardRef call\n if (isYakComponent) {\n return (\n Component as typeof Component & {\n yak: FunctionComponent;\n }\n ).yak(filteredProps, ref);\n }\n (filteredProps as { ref?: unknown }).ref = ref;\n return ;\n };\n return yakForwardRef(yak);\n };\n};\n\n/**\n * Type for the proxy object returned by `styled` that allows to\n * access all html tags as properties.\n */\ntype StyledLiteral = (\n styles: TemplateStringsArray,\n ...values: Array>\n) => FunctionComponent & {\n // type only identifier to allow targeting components\n // e.g. styled.svg`${Button}:hover & { fill: red; }`\n // warning: this is undefined during runtime\n __yak: true;\n};\n\n/**\n * The `styled` method works perfectly on all of your own or any third-party component,\n * as long as they attach the passed className prop to a DOM element.\n *\n * @usage\n *\n * ```tsx\n * const StyledLink = styled(Link)`\n * color: #BF4F74;\n * font-weight: bold;\n * `;\n * ```\n */\nexport const styled = new Proxy(\n StyledFactory as typeof StyledFactory & {\n [Tag in HtmlTags]: StyledLiteral & {\n attrs: <\n TAttrsIn extends object = {},\n TAttrsOut extends AttrsMerged<\n JSX.IntrinsicElements[Tag],\n TAttrsIn\n > = AttrsMerged,\n >(\n attrs: Attrs,\n ) => StyledLiteral>;\n };\n },\n {\n get(target, TagName: keyof JSX.IntrinsicElements) {\n return target(TagName);\n },\n },\n);\n\n// Remove all entries that start with a $ sign\nfunction removePrefixedProperties>(obj: T) {\n const result = {} as T;\n for (const key in obj) {\n if (!key.startsWith(\"$\")) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\nconst mergeClassNames = (a?: string, b?: string) => {\n if (!a) return b;\n if (!b) return a;\n return a + \" \" + b;\n};\n\nconst removeUndefined = (obj: T) => {\n const result = {} as T;\n for (const key in obj) {\n if (obj[key] !== undefined) {\n result[key] = obj[key];\n }\n }\n return result;\n};\n\nconst combineProps = <\n T extends {\n className?: string;\n style?: React.CSSProperties;\n },\n>(\n props: T,\n newProps: T,\n) => {\n if (!newProps) return props;\n const combinedProps: T =\n \"$__attrs\" in props\n ? // allow overriding props when attrs was used previously\n {\n ...removeUndefined(newProps),\n ...props,\n }\n : {\n ...props,\n ...removeUndefined(newProps),\n };\n return {\n ...combinedProps,\n className: mergeClassNames(\n props.className as string,\n newProps.className as string,\n ),\n style: { ...(props.style || {}), ...(newProps.style || {}) },\n $__attrs: true,\n };\n};\n\n// util type to remove properties from an object\ntype FastOmit = {\n [K in keyof T as K extends U ? never : K]: T[K];\n};\n\n// util type to merge two objects\n// if a property is present in both objects the property from B is used\nexport type Substitute = FastOmit<\n A,\n keyof B\n> &\n B;\n","/**\n * Allows to use atomic CSS classes in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, atoms } from \"next-yak\";\n *\n * const Button = styled.button<{ $primary?: boolean }>`\n * ${atoms(\"text-teal-600\", \"text-base\", \"rounded-md\")}\n * ${props => props.$primary && atoms(\"shadow-md\")}\n * `;\n * ```\n */\nexport const atoms = (...atoms: string[]) => {\n const className = atoms.join(\" \");\n return () => ({ className });\n};\n","/**\n * Allows to use CSS keyframe animations in a styled or css block\n *\n * @usage\n *\n * ```tsx\n * import { styled, keyframes } from \"next-yak\";\n *\n * const rotate = keyframes`\n * from {\n * transform: rotate(0deg);\n * }\n * to {\n * transform: rotate(360deg);\n * }\n * `;\n *\n * const Spinner = styled.div`\n * animation: ${rotate} 1s linear infinite;\n * `;\n * ```\n */\nexport const keyframes = (\n styles: TemplateStringsArray,\n ...dynamic: never[]\n): string => {\n // during compilation all args of keyframe are compiled\n // to a string which references the animation name\n return styles as any as string;\n};\n","export { css } from \"./cssLiteral.js\";\nexport { styled } from \"./styled.js\";\nexport { atoms } from \"./atoms.js\";\nexport { keyframes } from \"./keyframes.js\";\n\n// the following export is not relative as \"next-yak/context\"\n// links to one file for react server components and\n// to another file for classic react components\nexport { useTheme, YakThemeProvider } from \"next-yak/context\";\n\nexport type { YakTheme } from \"./context/index.d.ts\";\n"],"mappings":"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","names":["internalCssFactory","args","classNames","dynamicCssFunctions","style","arg","key","value","props","recursivePropExecution","className","allClassNames","allStyles","i","unwrapProps","fn","result","css","React","useTheme","noTheme","yakForwardRef","component","StyledFactory","Component","yakStyled","attrs","styles","values","getRuntimeStyles","css","processAttrs","props","combineProps","ref","theme","combinedProps","runtimeStyles","themeAfterAttr","combinedPropsWithoutTheme","propsBeforeFiltering","isYakComponent","filteredProps","removePrefixedProperties","mergeClassNames","styled","target","TagName","obj","result","key","a","b","removeUndefined","newProps","atoms","className","keyframes","styles","dynamic","useTheme","YakThemeProvider"]} \ No newline at end of file diff --git a/packages/next-yak/package.json b/packages/next-yak/package.json index 1e4f49db..719ec171 100644 --- a/packages/next-yak/package.json +++ b/packages/next-yak/package.json @@ -1,6 +1,6 @@ { "name": "next-yak", - "version": "0.0.34", + "version": "0.0.36", "type": "module", "types": "./dist/", "exports": { diff --git a/packages/next-yak/runtime/__tests__/attrs.test.tsx b/packages/next-yak/runtime/__tests__/attrs.test.tsx index b8cc412e..75e60a60 100644 --- a/packages/next-yak/runtime/__tests__/attrs.test.tsx +++ b/packages/next-yak/runtime/__tests__/attrs.test.tsx @@ -256,18 +256,6 @@ it("should work with data and aria attributes", () => { `); }); -// it("merge attrs", () => { -// const Comp = styled.button -// .attrs(() => ({ -// type: "button", -// tabIndex: 0, -// })) -// .attrs(() => ({ -// type: "submit", -// }))``; -// expect(TestRenderer.create().toJSON()).toMatchInlineSnapshot(); -// }); - it("merge attrs when inheriting SC", () => { const Parent = styled.button.attrs(() => ({ type: "button", @@ -506,7 +494,6 @@ it("should have access to theme", () => { ).toJSON(), ).toMatchInlineSnapshot(`
 {
     ).toJSON(),
   ).toMatchInlineSnapshot(`
     
diff --git a/packages/next-yak/runtime/__tests__/styled.test.tsx b/packages/next-yak/runtime/__tests__/styled.test.tsx
index b372fc26..f6f47db9 100644
--- a/packages/next-yak/runtime/__tests__/styled.test.tsx
+++ b/packages/next-yak/runtime/__tests__/styled.test.tsx
@@ -88,6 +88,35 @@ it("should filter out properties starting with $", () => {
   `);
 });
 
+it("should filter out properties starting with $ when passing to custom", () => {
+  let forwardedProps = null;
+  const Component = ({ className, style, ...props }) => {
+    forwardedProps = props;
+    return null;
+  };
+  const StyledComponent = styled(Component)``;
+  render();
+
+  expect(forwardedProps).toEqual({});
+});
+
+it("should forward properties to the next yak component", () => {
+  const Component = styled.input.attrs(({ $text }) => ({
+    "aria-label": $text,
+  }))``;
+  const StyledComponent = styled(Component)``;
+  const { container } = render();
+
+  expect(container).toMatchInlineSnapshot(`
+    
+ +
+ `); +}); + it("should concatenate classNames", () => { const Component = styled.input("className1"); @@ -242,7 +271,7 @@ it("should remove theme if styled element", () => { `); }); -it("should not remove theme if theme is passed to element", () => { +it("should keep theme if theme is passed to element", () => { const ThemePrinter = ({ theme, ...props }: { theme?: unknown }) => (
{JSON.stringify(theme)}
); diff --git a/packages/next-yak/runtime/styled.tsx b/packages/next-yak/runtime/styled.tsx index a6d74b98..39f4d65e 100644 --- a/packages/next-yak/runtime/styled.tsx +++ b/packages/next-yak/runtime/styled.tsx @@ -22,7 +22,7 @@ const yakForwardRef: ( // warning: `__yak` is undefined during runtime __yak: true; } = (component) => - Object.assign(React.forwardRef(component), { component }) as any; + Object.assign(React.forwardRef(component), { yak: component }) as any; /** * All valid html tags @@ -116,15 +116,17 @@ const yakStyled = < // prevents passing the theme prop to the DOM element of a styled component const { theme: themeAfterAttr, ...combinedPropsWithoutTheme } = combinedProps as { theme?: unknown }; + const propsBeforeFiltering = + themeAfterAttr === theme ? combinedPropsWithoutTheme : combinedProps; + + const isYakComponent = + typeof Component !== "string" && "yak" in Component; // remove all props that start with a $ sign for string components e.g. "button" or "div" // so that they are not passed to the DOM element - const filteredProps = - typeof Component === "string" - ? removePrefixedProperties(combinedPropsWithoutTheme) - : themeAfterAttr === theme - ? combinedPropsWithoutTheme - : combinedProps; + const filteredProps = !isYakComponent + ? removePrefixedProperties(propsBeforeFiltering) + : propsBeforeFiltering; // yak provides a className and style prop that needs to be merged with the // user provided className and style prop @@ -142,14 +144,13 @@ const yakStyled = < // if the styled(Component) syntax is used and the component is a yak component // we can call the yak function directly to avoid an unnecessary wrapper with an additional // forwardRef call - if (typeof Component !== "string" && "yak" in Component) { + if (isYakComponent) { return ( Component as typeof Component & { yak: FunctionComponent; } ).yak(filteredProps, ref); } - (filteredProps as { ref?: unknown }).ref = ref; return ; };