styled-components 6.4.0-prerelease.0 → 6.4.0-prerelease.2

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.
@@ -10,7 +10,7 @@
10
10
  'data-styled';
11
11
  var SC_ATTR_ACTIVE = 'active';
12
12
  var SC_ATTR_VERSION = 'data-styled-version';
13
- var SC_VERSION = "6.4.0-prerelease.0";
13
+ var SC_VERSION = "6.4.0-prerelease.2";
14
14
  var SPLITTER = '/*!sc*/\n';
15
15
  var IS_BROWSER = typeof window !== 'undefined' && typeof document !== 'undefined';
16
16
  var DISABLE_SPEEDY = Boolean(typeof SC_DISABLE_SPEEDY === 'boolean'
@@ -902,40 +902,74 @@
902
902
 
903
903
  var GlobalStyle = /** @class */ (function () {
904
904
  function GlobalStyle(rules, componentId) {
905
+ /** @internal Per-instance rule cache for shared-group rebuild. */
906
+ this.instanceRules = new Map();
905
907
  this.rules = rules;
906
908
  this.componentId = componentId;
907
909
  this.isStatic = isStaticRules(rules);
908
- // pre-register the first instance to ensure global styles
909
- // load before component ones
910
- StyleSheet.registerId(this.componentId + 1);
910
+ // Pre-register the shared group so global styles defined before
911
+ // components always appear before them in the stylesheet.
912
+ StyleSheet.registerId(this.componentId);
911
913
  }
912
- GlobalStyle.prototype.createStyles = function (instance, executionContext, styleSheet, stylis) {
913
- var flatCSS = joinStringArray(flatten(this.rules, executionContext, styleSheet, stylis));
914
- var css = stylis(flatCSS, '');
915
- var id = this.componentId + instance;
916
- // NOTE: We use the id as a name as well, since these rules never change
917
- styleSheet.insertRules(id, id, css);
918
- };
919
914
  GlobalStyle.prototype.removeStyles = function (instance, styleSheet) {
920
- styleSheet.clearRules(this.componentId + instance);
915
+ this.instanceRules.delete(instance);
916
+ this.rebuildGroup(styleSheet);
921
917
  };
922
918
  GlobalStyle.prototype.renderStyles = function (instance, executionContext, styleSheet, stylis) {
923
- if (instance > 2)
924
- StyleSheet.registerId(this.componentId + instance);
925
- var id = this.componentId + instance;
926
- // For static styles that don't change based on props,
927
- // only inject once and don't remove/re-add on every render.
928
- // This prevents issues with React StrictMode where the effect cleanup
929
- // from the simulated unmount runs after the re-render.
919
+ var id = this.componentId;
930
920
  if (this.isStatic) {
931
- if (!styleSheet.hasNameForId(id, id)) {
932
- this.createStyles(instance, executionContext, styleSheet, stylis);
921
+ if (!styleSheet.hasNameForId(id, id + instance)) {
922
+ var entry = this.computeRules(instance, executionContext, styleSheet, stylis);
923
+ styleSheet.insertRules(id, entry.name, entry.rules);
924
+ }
925
+ else if (!this.instanceRules.has(instance)) {
926
+ // Rehydrated style: populate cache so rebuildGroup can restore
927
+ // survivors if another instance unmounts.
928
+ this.computeRules(instance, executionContext, styleSheet, stylis);
933
929
  }
934
930
  return;
935
931
  }
936
- // NOTE: Remove old styles, then inject the new ones
937
- this.removeStyles(instance, styleSheet);
938
- this.createStyles(instance, executionContext, styleSheet, stylis);
932
+ // Compute new rules; skip CSSOM rebuild if CSS is unchanged.
933
+ // The fast-path is only safe on the client where the tag persists between renders.
934
+ // During SSR, clearTag() destroys the tag between requests, so we must always rebuild.
935
+ var prev = this.instanceRules.get(instance);
936
+ this.computeRules(instance, executionContext, styleSheet, stylis);
937
+ if (!styleSheet.server && prev) {
938
+ var a = prev.rules;
939
+ var b = this.instanceRules.get(instance).rules;
940
+ if (a.length === b.length) {
941
+ var same = true;
942
+ for (var i = 0; i < a.length; i++) {
943
+ if (a[i] !== b[i]) {
944
+ same = false;
945
+ break;
946
+ }
947
+ }
948
+ if (same)
949
+ return;
950
+ }
951
+ }
952
+ this.rebuildGroup(styleSheet);
953
+ };
954
+ GlobalStyle.prototype.computeRules = function (instance, executionContext, styleSheet, stylis) {
955
+ var flatCSS = joinStringArray(flatten(this.rules, executionContext, styleSheet, stylis));
956
+ var entry = {
957
+ name: this.componentId + instance,
958
+ rules: stylis(flatCSS, ''),
959
+ };
960
+ this.instanceRules.set(instance, entry);
961
+ return entry;
962
+ };
963
+ /**
964
+ * Clear all CSS rules in the shared group and re-insert from surviving instances.
965
+ * Must run synchronously — no yielding between clear and re-insert.
966
+ */
967
+ GlobalStyle.prototype.rebuildGroup = function (styleSheet) {
968
+ var id = this.componentId;
969
+ styleSheet.clearRules(id);
970
+ this.instanceRules.forEach(function (entry) {
971
+ styleSheet.insertRules(id, entry.name, entry.rules);
972
+ });
939
973
  };
940
974
  return GlobalStyle;
941
975
  }());
@@ -1542,16 +1576,21 @@
1542
1576
  {
1543
1577
  checkDynamicCreation(styledComponentId);
1544
1578
  }
1545
- // Use a WeakMap to maintain stable instances per stylesheet
1546
- var instanceMap = new WeakMap();
1547
1579
  var GlobalStyleComponent = function (props) {
1548
1580
  var ssc = useStyleSheetContext();
1549
1581
  var theme = React.useContext(ThemeContext) ;
1550
- // Get or create instance ID for this stylesheet
1551
- var instance = instanceMap.get(ssc.styleSheet);
1552
- if (instance === undefined) {
1553
- instance = ssc.styleSheet.allocateGSInstance(styledComponentId);
1554
- instanceMap.set(ssc.styleSheet, instance);
1582
+ // Each mount needs a unique instance ID for the shared-group instanceRules cache.
1583
+ // false is a build-time constant: the dead branch is entirely eliminated,
1584
+ // so React never sees a conditional hook call.
1585
+ // Server bundle: direct allocation (one-shot renders, no stability needed).
1586
+ // Browser bundle: useRef for stable ID across re-renders + useLayoutEffect cleanup.
1587
+ var instance;
1588
+ {
1589
+ var instanceRef = React.useRef(null);
1590
+ if (instanceRef.current === null) {
1591
+ instanceRef.current = ssc.styleSheet.allocateGSInstance(styledComponentId);
1592
+ }
1593
+ instance = instanceRef.current;
1555
1594
  }
1556
1595
  if (// @ts-expect-error invariant check
1557
1596
  React.Children.count(props.children)) {
@@ -1560,6 +1599,13 @@
1560
1599
  if (rules.some(function (rule) { return typeof rule === 'string' && rule.indexOf('@import') !== -1; })) {
1561
1600
  console.warn("Please do not use @import CSS syntax in createGlobalStyle at this time, as the CSSOM APIs we use in production do not handle it well. Instead, we recommend using a library such as react-helmet to inject a typical <link> meta tag to the stylesheet, or simply embedding it manually in your index.html <head> section for a simpler app.");
1562
1601
  }
1602
+ // Render styles during component execution for server environments.
1603
+ // Uses false (build-time constant) OR styleSheet.server (runtime flag set by
1604
+ // ServerStyleSheet) because some bundlers (Turbopack) resolve the browser entry
1605
+ // for SSR of client components, making false false on the server.
1606
+ if (ssc.styleSheet.server) {
1607
+ renderStyles(instance, props, ssc.styleSheet, theme, ssc.stylis);
1608
+ }
1563
1609
  // Client-side lifecycle: render styles in effect and clean up on unmount.
1564
1610
  // false and IS_RSC are build/module-level constants, so this doesn't violate rules of hooks.
1565
1611
  {
@@ -1572,6 +1618,11 @@
1572
1618
  };
1573
1619
  }, [instance, props, ssc.styleSheet, theme, ssc.stylis]);
1574
1620
  }
1621
+ // Clean up server instance cache — no useLayoutEffect cleanup runs on the
1622
+ // server, so instanceRules would grow unboundedly across SSR requests.
1623
+ if (ssc.styleSheet.server) {
1624
+ globalStyle.instanceRules.delete(instance);
1625
+ }
1575
1626
  return null;
1576
1627
  };
1577
1628
  function renderStyles(instance, props, styleSheet, theme, stylis) {
@@ -1601,6 +1652,11 @@
1601
1652
  this.name = name;
1602
1653
  this.id = "sc-keyframes-".concat(name);
1603
1654
  this.rules = rules;
1655
+ // Eagerly register the group so keyframes defined before components
1656
+ // get a lower group ID and appear before them in the stylesheet.
1657
+ // Uses getGroupForId directly (not StyleSheet.registerId) because
1658
+ // GroupIDAllocator is pure JS — safe for native builds.
1659
+ getGroupForId(this.id);
1604
1660
  setToString(this, function () {
1605
1661
  throw throwStyledComponentsError(12, String(_this.name));
1606
1662
  });