styled-components 6.4.0-prerelease.5 → 6.4.0-prerelease.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +4 -0
  2. package/dist/constructors/createGlobalStyle.d.ts +10 -0
  3. package/dist/constructors/css.d.ts +12 -0
  4. package/dist/constructors/keyframes.d.ts +11 -0
  5. package/dist/constructors/styled.d.ts +8 -0
  6. package/dist/hoc/withTheme.d.ts +1 -0
  7. package/dist/models/ComponentStyle.d.ts +1 -2
  8. package/dist/models/InlineStyle.d.ts +11 -0
  9. package/dist/models/ServerStyleSheet.d.ts +10 -0
  10. package/dist/models/StyleSheetManager.d.ts +1 -0
  11. package/dist/native/index.d.ts +18 -2
  12. package/dist/styled-components.browser.cjs.js +3 -3
  13. package/dist/styled-components.browser.cjs.js.map +1 -1
  14. package/dist/styled-components.browser.esm.js +2 -2
  15. package/dist/styled-components.browser.esm.js.map +1 -1
  16. package/dist/styled-components.cjs.js +3 -3
  17. package/dist/styled-components.cjs.js.map +1 -1
  18. package/dist/styled-components.esm.js +3 -3
  19. package/dist/styled-components.esm.js.map +1 -1
  20. package/dist/styled-components.js +183 -90
  21. package/dist/styled-components.js.map +1 -1
  22. package/dist/styled-components.min.js +3 -3
  23. package/dist/styled-components.min.js.map +1 -1
  24. package/dist/utils/escape.d.ts +0 -4
  25. package/dist/utils/hash.d.ts +1 -0
  26. package/dist/utils/isStyledComponent.d.ts +1 -0
  27. package/native/dist/constructors/createGlobalStyle.d.ts +10 -0
  28. package/native/dist/constructors/css.d.ts +12 -0
  29. package/native/dist/constructors/keyframes.d.ts +11 -0
  30. package/native/dist/constructors/styled.d.ts +8 -0
  31. package/native/dist/dist/constructors/createGlobalStyle.d.ts +10 -0
  32. package/native/dist/dist/constructors/css.d.ts +12 -0
  33. package/native/dist/dist/constructors/keyframes.d.ts +11 -0
  34. package/native/dist/dist/constructors/styled.d.ts +8 -0
  35. package/native/dist/dist/hoc/withTheme.d.ts +1 -0
  36. package/native/dist/dist/models/ComponentStyle.d.ts +1 -2
  37. package/native/dist/dist/models/InlineStyle.d.ts +11 -0
  38. package/native/dist/dist/models/ServerStyleSheet.d.ts +10 -0
  39. package/native/dist/dist/models/StyleSheetManager.d.ts +1 -0
  40. package/native/dist/dist/native/index.d.ts +18 -2
  41. package/native/dist/dist/utils/escape.d.ts +0 -4
  42. package/native/dist/dist/utils/hash.d.ts +1 -0
  43. package/native/dist/dist/utils/isStyledComponent.d.ts +1 -0
  44. package/native/dist/hoc/withTheme.d.ts +1 -0
  45. package/native/dist/models/ComponentStyle.d.ts +1 -2
  46. package/native/dist/models/InlineStyle.d.ts +11 -0
  47. package/native/dist/models/ServerStyleSheet.d.ts +10 -0
  48. package/native/dist/models/StyleSheetManager.d.ts +1 -0
  49. package/native/dist/native/index.d.ts +18 -2
  50. package/native/dist/styled-components.native.cjs.js +1 -1
  51. package/native/dist/styled-components.native.cjs.js.map +1 -1
  52. package/native/dist/styled-components.native.esm.js +1 -1
  53. package/native/dist/styled-components.native.esm.js.map +1 -1
  54. package/native/dist/utils/escape.d.ts +0 -4
  55. package/native/dist/utils/hash.d.ts +1 -0
  56. package/native/dist/utils/isStyledComponent.d.ts +1 -0
  57. package/native/package.json +7 -2
  58. package/package.json +5 -5
@@ -11,7 +11,7 @@
11
11
  'data-styled';
12
12
  const SC_ATTR_ACTIVE = 'active';
13
13
  const SC_ATTR_VERSION = 'data-styled-version';
14
- const SC_VERSION = "6.4.0-prerelease.5";
14
+ const SC_VERSION = "6.4.0-prerelease.8";
15
15
  const SPLITTER = '/*!sc*/\n';
16
16
  const IS_BROWSER = typeof window !== 'undefined' && typeof document !== 'undefined';
17
17
  function readSpeedyFlag(name) {
@@ -273,11 +273,11 @@
273
273
  continue;
274
274
  const selector = SC_ATTR + '.g' + group + '[id="' + id + '"]';
275
275
  let content = '';
276
- names.forEach(name => {
276
+ for (const name of names) {
277
277
  if (name.length > 0) {
278
278
  content += name + ',';
279
279
  }
280
- });
280
+ }
281
281
  // NOTE: It's easier to collect rules and have the marker
282
282
  // after the actual rules to simplify the rehydration
283
283
  css += rules + selector + '{content:"' + content + '"}' + SPLITTER;
@@ -658,7 +658,7 @@
658
658
  return '';
659
659
  }
660
660
  if (typeof value === 'number' && value !== 0 && !(name in unitless) && !name.startsWith('--')) {
661
- return `${value}px`; // Presumes implicit 'px' suffix for unitless numbers except for CSS variables
661
+ return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers except for CSS variables
662
662
  }
663
663
  return String(value).trim();
664
664
  }
@@ -723,6 +723,7 @@
723
723
  return isFunction(test) && !(test.prototype && test.prototype.isReactComponent);
724
724
  }
725
725
 
726
+ /** Type guard that returns true if the target is a styled component. */
726
727
  function isStyledComponent(target) {
727
728
  return typeof target === 'object' && 'styledComponentId' in target;
728
729
  }
@@ -739,13 +740,13 @@
739
740
  continue;
740
741
  // @ts-expect-error Property 'isCss' does not exist on type 'any[]'
741
742
  if ((Array.isArray(val) && val.isCss) || isFunction(val)) {
742
- rules.push(`${hyphenateStyleName(key)}:`, val, ';');
743
+ rules.push(hyphenateStyleName(key) + ':', val, ';');
743
744
  }
744
745
  else if (isPlainObject(val)) {
745
- rules.push(`${key} {`, ...objToCssArray(val), '}');
746
+ rules.push(key + ' {', ...objToCssArray(val), '}');
746
747
  }
747
748
  else {
748
- rules.push(`${hyphenateStyleName(key)}: ${addUnitIfNeeded(key, val)};`);
749
+ rules.push(hyphenateStyleName(key) + ': ' + addUnitIfNeeded(key, val) + ';');
749
750
  }
750
751
  }
751
752
  return rules;
@@ -825,7 +826,7 @@
825
826
  * Convenience function for joining strings to form className chains
826
827
  */
827
828
  function joinStrings(a, b) {
828
- return a && b ? `${a} ${b}` : a || b || '';
829
+ return a && b ? a + ' ' + b : a || b || '';
829
830
  }
830
831
  function joinStringArray(arr, sep) {
831
832
  return arr.join(sep || '');
@@ -898,9 +899,9 @@
898
899
  rebuildGroup(styleSheet) {
899
900
  const id = this.componentId;
900
901
  styleSheet.clearRules(id);
901
- this.instanceRules.forEach(entry => {
902
+ for (const entry of this.instanceRules.values()) {
902
903
  styleSheet.insertRules(id, entry.name, entry.rules);
903
- });
904
+ }
904
905
  }
905
906
  }
906
907
 
@@ -1167,22 +1168,26 @@
1167
1168
  * Takes an element and recurses through it's rules added the namespace to the start of each selector.
1168
1169
  * Takes into account media queries by recursing through child rules if they are present.
1169
1170
  */
1170
- function recursivelySetNamepace(compiled, namespace) {
1171
- return compiled.map(rule => {
1171
+ function recursivelySetNamespace(compiled, namespace) {
1172
+ for (let i = 0; i < compiled.length; i++) {
1173
+ const rule = compiled[i];
1172
1174
  if (rule.type === 'rule') {
1173
1175
  // add the namespace to the start
1174
- rule.value = `${namespace} ${rule.value}`;
1176
+ rule.value = namespace + ' ' + rule.value;
1175
1177
  // add the namespace after each comma for subsequent selectors.
1176
- rule.value = rule.value.replaceAll(',', `,${namespace} `);
1177
- rule.props = rule.props.map(prop => {
1178
- return `${namespace} ${prop}`;
1179
- });
1178
+ rule.value = rule.value.replaceAll(',', ',' + namespace + ' ');
1179
+ const props = rule.props;
1180
+ const newProps = [];
1181
+ for (let j = 0; j < props.length; j++) {
1182
+ newProps[j] = namespace + ' ' + props[j];
1183
+ }
1184
+ rule.props = newProps;
1180
1185
  }
1181
1186
  if (Array.isArray(rule.children) && rule.type !== '@keyframes') {
1182
- rule.children = recursivelySetNamepace(rule.children, namespace);
1187
+ rule.children = recursivelySetNamespace(rule.children, namespace);
1183
1188
  }
1184
- return rule;
1185
- });
1189
+ }
1190
+ return compiled;
1186
1191
  }
1187
1192
  function createStylisInstance({ options = EMPTY_OBJECT, plugins = EMPTY_ARRAY, } = EMPTY_OBJECT) {
1188
1193
  let _componentId;
@@ -1251,9 +1256,9 @@
1251
1256
  _selector = selector;
1252
1257
  _selectorRegexp = undefined; // Reset for lazy creation per call
1253
1258
  const flatCSS = sanitizeCSS(stripLineComments(css));
1254
- let compiled = ue(prefix || selector ? `${prefix} ${selector} { ${flatCSS} }` : flatCSS);
1259
+ let compiled = ue(prefix || selector ? prefix + ' ' + selector + ' { ' + flatCSS + ' }' : flatCSS);
1255
1260
  if (options.namespace) {
1256
- compiled = recursivelySetNamepace(compiled, options.namespace);
1261
+ compiled = recursivelySetNamespace(compiled, options.namespace);
1257
1262
  }
1258
1263
  _stack = [];
1259
1264
  ve(compiled, _middleware);
@@ -1286,9 +1291,9 @@
1286
1291
  const StylisContext = React.createContext(undefined)
1287
1292
  ;
1288
1293
  function useStyleSheetContext() {
1289
- // Skip useContext if we're in an RSC environment without context support
1290
- return React.useContext(StyleSheetContext) ;
1294
+ return React.useContext(StyleSheetContext);
1291
1295
  }
1296
+ /** Configure style injection for descendant styled components (target element, stylis plugins, prop forwarding). */
1292
1297
  function StyleSheetManager(props) {
1293
1298
  // In RSC environments without context support, StyleSheetManager becomes a no-op
1294
1299
  if (!React.useMemo) {
@@ -1479,6 +1484,16 @@
1479
1484
  return addTag(flatten(interleave(styleStringArray, interpolations)));
1480
1485
  }
1481
1486
 
1487
+ /**
1488
+ * Create a component that injects global CSS when mounted. Supports theming and dynamic props.
1489
+ *
1490
+ * ```tsx
1491
+ * const GlobalStyle = createGlobalStyle`
1492
+ * body { margin: 0; font-family: system-ui; }
1493
+ * `;
1494
+ * // Render <GlobalStyle /> at the root of your app
1495
+ * ```
1496
+ */
1482
1497
  function createGlobalStyle(strings, ...interpolations) {
1483
1498
  const rules = css(strings, ...interpolations);
1484
1499
  const styledComponentId = `sc-global-${generateComponentId(JSON.stringify(rules))}`;
@@ -1710,6 +1725,17 @@
1710
1725
  }
1711
1726
  _a = KEYFRAMES_SYMBOL;
1712
1727
 
1728
+ /**
1729
+ * Define a CSS `@keyframes` animation with an automatically scoped name.
1730
+ *
1731
+ * ```tsx
1732
+ * const rotate = keyframes`
1733
+ * from { transform: rotate(0deg); }
1734
+ * to { transform: rotate(360deg); }
1735
+ * `;
1736
+ * const Spinner = styled.div`animation: ${rotate} 1s linear infinite;`;
1737
+ * ```
1738
+ */
1713
1739
  function keyframes(strings, ...interpolations) {
1714
1740
  /* Warning if you've used keyframes on React Native */
1715
1741
  if (typeof navigator !== 'undefined' &&
@@ -1815,6 +1841,7 @@
1815
1841
  return targetComponent;
1816
1842
  }
1817
1843
 
1844
+ /** Higher-order component that injects the current theme as a prop. Prefer `useTheme` in function components. */
1818
1845
  function withTheme(Component) {
1819
1846
  const WithTheme = React.forwardRef((props, ref) => {
1820
1847
  const theme = React.useContext(ThemeContext) ;
@@ -1828,6 +1855,16 @@
1828
1855
  return hoistNonReactStatics(WithTheme, Component);
1829
1856
  }
1830
1857
 
1858
+ /**
1859
+ * Collect styled-components CSS during server-side rendering.
1860
+ *
1861
+ * ```tsx
1862
+ * const sheet = new ServerStyleSheet();
1863
+ * const html = renderToString(sheet.collectStyles(<App />));
1864
+ * const styleTags = sheet.getStyleTags();
1865
+ * sheet.seal();
1866
+ * ```
1867
+ */
1831
1868
  class ServerStyleSheet {
1832
1869
  constructor({ nonce } = {}) {
1833
1870
  this._emitSheetCSS = () => {
@@ -1990,10 +2027,6 @@
1990
2027
  // Control characters and non-letter first symbols are not supported
1991
2028
  const escapeRegex = /[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~-]+/g;
1992
2029
  const dashesAtEnds = /(^-|-$)/g;
1993
- /**
1994
- * TODO: Explore using CSS.escape when it becomes more available
1995
- * in evergreen browsers.
1996
- */
1997
2030
  function escape(str) {
1998
2031
  return str // Replace all possible CSS selectors
1999
2032
  .replace(escapeRegex, '-') // Remove extraneous hyphens at the start and end
@@ -2047,9 +2080,6 @@
2047
2080
  class ComponentStyle {
2048
2081
  constructor(rules, componentId, baseStyle) {
2049
2082
  this.rules = rules;
2050
- this.staticRulesId = '';
2051
- this.isStatic =
2052
- "development" === 'production' ;
2053
2083
  this.componentId = componentId;
2054
2084
  this.baseHash = phash(SEED, componentId);
2055
2085
  this.baseStyle = baseStyle;
@@ -2061,42 +2091,48 @@
2061
2091
  let names = this.baseStyle
2062
2092
  ? this.baseStyle.generateAndInjectStyles(executionContext, styleSheet, stylis)
2063
2093
  : '';
2064
- // force dynamic classnames if user-supplied stylis plugins are in use
2065
- if (this.isStatic && !stylis.hash) {
2066
- if (this.staticRulesId && styleSheet.hasNameForId(this.componentId, this.staticRulesId)) {
2067
- names = joinStrings(names, this.staticRulesId);
2068
- }
2069
- else {
2070
- const cssStatic = joinStringArray(flatten(this.rules, executionContext, styleSheet, stylis));
2071
- const name = generateAlphabeticName(phash(this.baseHash, cssStatic) >>> 0);
2072
- if (!styleSheet.hasNameForId(this.componentId, name)) {
2073
- const cssStaticFormatted = stylis(cssStatic, '.' + name, undefined, this.componentId);
2074
- styleSheet.insertRules(this.componentId, name, cssStaticFormatted);
2075
- }
2076
- names = joinStrings(names, name);
2077
- this.staticRulesId = name;
2078
- }
2079
- }
2080
- else {
2081
- let dynamicHash = phash(this.baseHash, stylis.hash);
2094
+ {
2082
2095
  let css = '';
2083
2096
  for (let i = 0; i < this.rules.length; i++) {
2084
2097
  const partRule = this.rules[i];
2085
2098
  if (typeof partRule === 'string') {
2086
2099
  css += partRule;
2087
- dynamicHash = phash(dynamicHash, partRule);
2088
2100
  }
2089
2101
  else if (partRule) {
2090
- const partString = joinStringArray(flatten(partRule, executionContext, styleSheet, stylis));
2091
- // The same value can switch positions in the array, so we include "i" in the hash.
2092
- // Split into two phash calls to avoid temp string allocation (partString + i).
2093
- // phash processes right-to-left, so phash(h, a+b) === phash(phash(h, b), a).
2094
- dynamicHash = phash(phash(dynamicHash, String(i)), partString);
2095
- css += partString;
2102
+ // Fast path: inline function call for the common case (interpolation
2103
+ // returning a string). Avoids flatten's type dispatch and array alloc.
2104
+ if (isStatelessFunction(partRule)) {
2105
+ const fnResult = partRule(executionContext);
2106
+ if (typeof fnResult === 'string') {
2107
+ css += fnResult;
2108
+ }
2109
+ else if (fnResult !== undefined && fnResult !== null && fnResult !== false) {
2110
+ if (typeof fnResult === 'object' &&
2111
+ !Array.isArray(fnResult) &&
2112
+ !isKeyframes(fnResult) &&
2113
+ !isPlainObject(fnResult)) {
2114
+ console.error(`${getComponentName(partRule)} is not a styled component and cannot be referred to via component selector. See https://www.styled-components.com/docs/advanced#referring-to-other-components for more details.`);
2115
+ }
2116
+ css += joinStringArray(flatten(fnResult, executionContext, styleSheet, stylis));
2117
+ }
2118
+ }
2119
+ else {
2120
+ css += joinStringArray(flatten(partRule, executionContext, styleSheet, stylis));
2121
+ }
2096
2122
  }
2097
2123
  }
2098
2124
  if (css) {
2099
- const name = generateAlphabeticName(dynamicHash >>> 0);
2125
+ // Cache css->name to skip phash+generateName for repeat CSS strings.
2126
+ // The CSS string fully determines the class name for a given component,
2127
+ // so a Map lookup replaces O(cssLen) hashing on cache hit.
2128
+ if (!this.dynamicNameCache)
2129
+ this.dynamicNameCache = new Map();
2130
+ const cacheKey = stylis.hash ? stylis.hash + css : css;
2131
+ let name = this.dynamicNameCache.get(cacheKey);
2132
+ if (!name) {
2133
+ name = generateAlphabeticName(phash(phash(this.baseHash, stylis.hash), css) >>> 0);
2134
+ this.dynamicNameCache.set(cacheKey, name);
2135
+ }
2100
2136
  if (!styleSheet.hasNameForId(this.componentId, name)) {
2101
2137
  const cssFormatted = stylis(css, '.' + name, undefined, this.componentId);
2102
2138
  styleSheet.insertRules(this.componentId, name, cssFormatted);
@@ -2108,17 +2144,37 @@
2108
2144
  }
2109
2145
  }
2110
2146
 
2147
+ const hasOwn = Object.prototype.hasOwnProperty;
2111
2148
  const identifiers = {};
2112
2149
  /* We depend on components having unique IDs */
2113
2150
  function generateId(displayName, parentComponentId) {
2114
2151
  const name = typeof displayName !== 'string' ? 'sc' : escape(displayName);
2115
2152
  // Ensure that no displayName can lead to duplicate componentIds
2116
2153
  identifiers[name] = (identifiers[name] || 0) + 1;
2117
- const componentId = `${name}-${generateComponentId(
2118
- // SC_VERSION gives us isolation between multiple runtimes on the page at once
2119
- // this is improved further with use of the babel plugin "namespace" feature
2120
- SC_VERSION + name + identifiers[name])}`;
2121
- return parentComponentId ? `${parentComponentId}-${componentId}` : componentId;
2154
+ const componentId = name +
2155
+ '-' +
2156
+ generateComponentId(
2157
+ // SC_VERSION gives us isolation between multiple runtimes on the page at once
2158
+ // this is improved further with use of the babel plugin "namespace" feature
2159
+ SC_VERSION + name + identifiers[name]);
2160
+ return parentComponentId ? parentComponentId + '-' + componentId : componentId;
2161
+ }
2162
+ /**
2163
+ * Shallow-compare two context objects using a stored key count to avoid
2164
+ * a second iteration pass. Returns true if all own-property values match.
2165
+ */
2166
+ function shallowEqualContext(prev, next, prevKeyCount) {
2167
+ const a = prev;
2168
+ const b = next;
2169
+ let nextKeyCount = 0;
2170
+ for (const key in b) {
2171
+ if (hasOwn.call(b, key)) {
2172
+ nextKeyCount++;
2173
+ if (a[key] !== b[key])
2174
+ return false;
2175
+ }
2176
+ }
2177
+ return nextKeyCount === prevKeyCount;
2122
2178
  }
2123
2179
  function useInjectedStyle(componentStyle, resolvedAttrs, styleSheet, stylis) {
2124
2180
  const className = componentStyle.generateAndInjectStyles(resolvedAttrs, styleSheet, stylis);
@@ -2131,9 +2187,8 @@
2131
2187
  const context = Object.assign(Object.assign({}, props), {
2132
2188
  // unset, add `props.className` back at the end so props always "wins"
2133
2189
  className: undefined, theme });
2134
- let attrDef;
2135
- for (let i = 0; i < attrs.length; i += 1) {
2136
- attrDef = attrs[i];
2190
+ for (let i = 0; i < attrs.length; i++) {
2191
+ const attrDef = attrs[i];
2137
2192
  // Pass a shallow copy to function attrs so the callback's captured
2138
2193
  // reference isn't mutated by subsequent attrs processing (#3336).
2139
2194
  const resolvedAttrDef = isFunction(attrDef) ? attrDef(Object.assign({}, context)) : attrDef;
@@ -2158,46 +2213,81 @@
2158
2213
  return context;
2159
2214
  }
2160
2215
  let seenUnknownProps = new Set();
2161
- function useStyledComponentImpl(forwardedComponent, props, forwardedRef) {
2162
- const { attrs: componentAttrs, componentStyle, defaultProps, foldedComponentIds, styledComponentId, target, } = forwardedComponent;
2163
- const contextTheme = React.useContext(ThemeContext) ;
2164
- const ssc = useStyleSheetContext();
2165
- const shouldForwardProp = forwardedComponent.shouldForwardProp || ssc.shouldForwardProp;
2166
- if (React.useDebugValue) {
2167
- React.useDebugValue(styledComponentId);
2168
- }
2169
- // NOTE: the non-hooks version only subscribes to this when !componentStyle.isStatic,
2170
- // but that'd be against the rules-of-hooks. We could be naughty and do it anyway as it
2171
- // should be an immutable value, but behave for now.
2172
- const theme = determineTheme(props, contextTheme, defaultProps) || (EMPTY_OBJECT);
2173
- const context = resolveContext(componentAttrs, props, theme);
2174
- const elementToBeCreated = context.as || target;
2216
+ function buildPropsForElement(context, elementToBeCreated, theme, shouldForwardProp) {
2175
2217
  const propsForElement = {};
2176
2218
  for (const key in context) {
2177
- // @ts-expect-error context may have arbitrary properties from attrs
2178
2219
  if (context[key] === undefined) ;
2179
2220
  else if (key[0] === '$' || key === 'as' || (key === 'theme' && context.theme === theme)) ;
2180
2221
  else if (key === 'forwardedAs') {
2181
2222
  propsForElement.as = context.forwardedAs;
2182
2223
  }
2183
2224
  else if (!shouldForwardProp || shouldForwardProp(key, elementToBeCreated)) {
2184
- // @ts-expect-error context may have arbitrary properties from attrs
2185
2225
  propsForElement[key] = context[key];
2186
2226
  if (!shouldForwardProp &&
2187
2227
  "development" === 'development' &&
2188
2228
  !isPropValid(key) &&
2189
2229
  !seenUnknownProps.has(key) &&
2190
- // Only warn on DOM Element.
2191
2230
  domElements.has(elementToBeCreated)) {
2192
2231
  seenUnknownProps.add(key);
2193
2232
  console.warn(`styled-components: it looks like an unknown prop "${key}" is being sent through to the DOM, which will likely trigger a React console error. If you would like automatic filtering of unknown props, you can opt-into that behavior via \`<StyleSheetManager shouldForwardProp={...}>\` (connect an API like \`@emotion/is-prop-valid\`) or consider using transient props (\`$\` prefix for automatic filtering.)`);
2194
2233
  }
2195
2234
  }
2196
2235
  }
2197
- const generatedClassName = useInjectedStyle(componentStyle, context, ssc.styleSheet, ssc.stylis);
2236
+ return propsForElement;
2237
+ }
2238
+ function useStyledComponentImpl(forwardedComponent, props, forwardedRef) {
2239
+ const { attrs: componentAttrs, componentStyle, defaultProps, foldedComponentIds, styledComponentId, target, } = forwardedComponent;
2240
+ const contextTheme = React.useContext(ThemeContext) ;
2241
+ const ssc = useStyleSheetContext();
2242
+ const shouldForwardProp = forwardedComponent.shouldForwardProp || ssc.shouldForwardProp;
2243
+ if (React.useDebugValue) {
2244
+ React.useDebugValue(styledComponentId);
2245
+ }
2246
+ // NOTE: the non-hooks version only subscribes to this when !componentStyle.isStatic,
2247
+ // but that'd be against the rules-of-hooks. We could be naughty and do it anyway as it
2248
+ // should be an immutable value, but behave for now.
2249
+ const theme = determineTheme(props, contextTheme, defaultProps) || (EMPTY_OBJECT);
2250
+ let context;
2251
+ let generatedClassName;
2252
+ // Client-only render cache: skip resolveContext and generateAndInjectStyles
2253
+ // when props+theme haven't changed. propsForElement is always rebuilt since
2254
+ // it's mutated with className/ref after construction.
2255
+ // false and IS_RSC are build/module-level constants for dead-code elimination.
2256
+ {
2257
+ const renderCacheRef = React.useRef(null);
2258
+ const prev = renderCacheRef.current;
2259
+ if (prev !== null &&
2260
+ prev[1] === theme &&
2261
+ prev[2] === ssc.styleSheet &&
2262
+ prev[3] === ssc.stylis &&
2263
+ shallowEqualContext(prev[0], props, prev[4])) {
2264
+ context = prev[5];
2265
+ generatedClassName = prev[6];
2266
+ }
2267
+ else {
2268
+ context = resolveContext(componentAttrs, props, theme);
2269
+ generatedClassName = useInjectedStyle(componentStyle, context, ssc.styleSheet, ssc.stylis);
2270
+ let propsKeyCount = 0;
2271
+ for (const key in props) {
2272
+ if (hasOwn.call(props, key))
2273
+ propsKeyCount++;
2274
+ }
2275
+ renderCacheRef.current = [
2276
+ props,
2277
+ theme,
2278
+ ssc.styleSheet,
2279
+ ssc.stylis,
2280
+ propsKeyCount,
2281
+ context,
2282
+ generatedClassName,
2283
+ ];
2284
+ }
2285
+ }
2198
2286
  if (forwardedComponent.warnTooManyClasses) {
2199
2287
  forwardedComponent.warnTooManyClasses(generatedClassName);
2200
2288
  }
2289
+ const elementToBeCreated = context.as || target;
2290
+ const propsForElement = buildPropsForElement(context, elementToBeCreated, theme, shouldForwardProp);
2201
2291
  let classString = joinStrings(foldedComponentIds, styledComponentId);
2202
2292
  if (generatedClassName) {
2203
2293
  classString += ' ' + generatedClassName;
@@ -2205,15 +2295,10 @@
2205
2295
  if (context.className) {
2206
2296
  classString += ' ' + context.className;
2207
2297
  }
2208
- propsForElement[
2209
- // handle custom elements which React doesn't properly alias
2210
- isTag(elementToBeCreated) &&
2298
+ propsForElement[isTag(elementToBeCreated) &&
2211
2299
  !domElements.has(elementToBeCreated)
2212
2300
  ? 'class'
2213
2301
  : 'className'] = classString;
2214
- // forwardedRef is coming from React.forwardRef.
2215
- // But it might not exist. Since React 19 handles `ref` like a prop, it only define it if there is a value.
2216
- // We don't want to inject an empty ref.
2217
2302
  if (forwardedRef) {
2218
2303
  propsForElement.ref = forwardedRef;
2219
2304
  }
@@ -2226,7 +2311,7 @@
2226
2311
  const isCompositeComponent = !isTag(target);
2227
2312
  const { attrs = EMPTY_ARRAY, componentId = generateId(options.displayName, options.parentComponentId), displayName = generateDisplayName(target), } = options;
2228
2313
  const styledComponentId = options.displayName && options.componentId
2229
- ? `${escape(options.displayName)}-${options.componentId}`
2314
+ ? escape(options.displayName) + '-' + options.componentId
2230
2315
  : options.componentId || componentId;
2231
2316
  // fold the underlying StyledComponent attrs up (implicit extend)
2232
2317
  const finalAttrs = isTargetStyledComp && styledComponentTarget.attrs
@@ -2326,6 +2411,14 @@
2326
2411
  return templateFunction;
2327
2412
  }
2328
2413
 
2414
+ /**
2415
+ * Create a styled component from an HTML element or React component.
2416
+ *
2417
+ * ```tsx
2418
+ * const Button = styled.button`color: red;`;
2419
+ * const Link = styled(RouterLink)`text-decoration: none;`;
2420
+ * ```
2421
+ */
2329
2422
  const baseStyled = (tag) => constructWithOptions(createStyledComponent, tag);
2330
2423
  const styled = baseStyled;
2331
2424
  // Shorthands for all valid HTML Elements