styled-components
Version:
Fast, expressive styling for React.
976 lines (946 loc) • 122 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
(global = global || self, factory(global.styled = {}, global.React));
})(this, (function (exports, React) { 'use strict';
var _a$1, _b;
const SC_ATTR = (typeof process !== 'undefined' &&
typeof process.env !== 'undefined' &&
(process.env.REACT_APP_SC_ATTR || process.env.SC_ATTR)) ||
'data-styled';
const SC_ATTR_ACTIVE = 'active';
const SC_ATTR_VERSION = 'data-styled-version';
const SC_VERSION = "6.4.1";
const SPLITTER = '/*!sc*/\n';
const IS_BROWSER = typeof window !== 'undefined' && typeof document !== 'undefined';
function readSpeedyFlag(name) {
if (typeof process !== 'undefined' && typeof process.env !== 'undefined') {
const val = process.env[name];
if (val !== undefined && val !== '') {
return val !== 'false';
}
}
return undefined;
}
const DISABLE_SPEEDY = Boolean(typeof SC_DISABLE_SPEEDY === 'boolean'
? SC_DISABLE_SPEEDY
: ((_b = (_a$1 = readSpeedyFlag('REACT_APP_SC_DISABLE_SPEEDY')) !== null && _a$1 !== void 0 ? _a$1 : readSpeedyFlag('SC_DISABLE_SPEEDY')) !== null && _b !== void 0 ? _b : (typeof process !== 'undefined' && typeof process.env !== 'undefined'
? "development" !== 'production'
: true)));
const KEYFRAMES_ID_PREFIX = 'sc-keyframes-';
// Shared empty execution context when generating static styles
const STATIC_EXECUTION_CONTEXT = {};
const EMPTY_ARRAY = Object.freeze([]);
const EMPTY_OBJECT = Object.freeze({});
/**
* If the Object prototype is frozen, the "toString" property is non-writable. This means that any objects which inherit this property
* cannot have the property changed using a "=" assignment operator. If using strict mode, attempting that will cause an error. If not using
* strict mode, attempting that will be silently ignored.
*
* If the Object prototype is frozen, inherited non-writable properties can still be shadowed using one of two mechanisms:
*
* 1. ES6 class methods: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#methods
* 2. Using the `Object.defineProperty()` static method:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
*
* However, this project uses Babel to transpile ES6 classes, and transforms ES6 class methods to use the assignment operator instead:
* https://babeljs.io/docs/babel-plugin-transform-class-properties#options
*
* Therefore, the most compatible way to shadow the prototype's "toString" property is to define a new "toString" property on this object.
*/
function setToString(object, toStringFn) {
Object.defineProperty(object, 'toString', { value: toStringFn });
}
var errorMap = { "1": "Cannot create styled-component for component: %s.\n\n", "2": "Can't collect styles once you've consumed a `ServerStyleSheet`'s styles! `ServerStyleSheet` is a one off instance for each server-side render cycle.\n\n- Are you trying to reuse it across renders?\n- Are you accidentally calling collectStyles twice?\n\n", "3": "Streaming SSR is only supported in a Node.js environment; Please do not try to call this method in the browser.\n\n", "4": "The `StyleSheetManager` expects a valid target or sheet prop!\n\n- Does this error occur on the client and is your target falsy?\n- Does this error occur on the server and is the sheet falsy?\n\n", "5": "The clone method cannot be used on the client!\n\n- Are you running in a client-like environment on the server?\n- Are you trying to run SSR on the client?\n\n", "6": "Trying to insert a new style tag, but the given Node is unmounted!\n\n- Are you using a custom target that isn't mounted?\n- Does your document not have a valid head element?\n- Have you accidentally removed a style tag manually?\n\n", "7": "ThemeProvider: Please return an object from your \"theme\" prop function, e.g.\n\n```js\ntheme={() => ({})}\n```\n\n", "8": "ThemeProvider: Please make your \"theme\" prop an object.\n\n", "9": "Missing document `<head>`\n\n", "10": "Cannot find a StyleSheet instance. Usually this happens if there are multiple copies of styled-components loaded at once. Check out this issue for how to troubleshoot and fix the common cases where this situation can happen: https://github.com/styled-components/styled-components/issues/1941#issuecomment-417862021\n\n", "11": "_This error was replaced with a dev-time warning, it will be deleted for v4 final._ [createGlobalStyle] received children which will not be rendered. Please use the component without passing children elements.\n\n", "12": "It seems you are interpolating a keyframe declaration (%s) into an untagged string. Please wrap your string in the css\\`\\` helper which ensures the styles are injected correctly. See https://styled-components.com/docs/api#css\n\n", "13": "%s is not a styled component and cannot be referred to via component selector. See https://styled-components.com/docs/advanced#referring-to-other-components for more details.\n\n", "14": "ThemeProvider: \"theme\" prop is required.\n\n", "15": "A stylis plugin has been supplied that is not named. We need a name for each plugin to be able to prevent styling collisions between different stylis configurations within the same app. Before you pass your plugin to `<StyleSheetManager stylisPlugins={[]}>`, please make sure each plugin is uniquely-named, e.g.\n\n```js\nObject.defineProperty(importedPlugin, 'name', { value: 'some-unique-name' });\n```\n\n", "16": "Reached the limit of how many styled components may be created at group %s.\nYou may only create up to 1,073,741,824 components. If you're creating components dynamically,\nas for instance in your render method then you may be running into this limitation.\n\n", "17": "CSSStyleSheet could not be found on HTMLStyleElement.\nHas styled-components' style tag been unmounted or altered by another script?\n\n", "18": "Accessing `useTheme` hook outside of a `<ThemeProvider>` element.\n\n```jsx\nimport { useTheme } from 'styled-components';\nexport function StyledCompoent({ children }) {\n const theme = useTheme();\n return <div style={{ width: theme.sizes.full }}>{children}</div>;\n}\n\nimport { StyledComponent } from './StyledComponent';\nimport { theme } from './theme';\nexport function App() {\n return (\n <ThemeProvider theme={theme}>\n <StyledComponent />\n </ThemeProvider>\n );\n}\n```\n\nIf you need access to the theme in an uncertain composition scenario, `React.useContext(ThemeContext)` will not emit an error if there is no `ThemeProvider` ancestor.\n" };
const ERRORS = errorMap ;
/**
* super basic version of sprintf
*/
function format(...args) {
let a = args[0];
const b = [];
for (let c = 1, len = args.length; c < len; c += 1) {
b.push(args[c]);
}
b.forEach(d => {
a = a.replace(/%[a-z]/, d);
});
return a;
}
/**
* Create an error file out of errors.md for development and a simple web link to the full errors
* in production mode.
*/
function throwStyledComponentsError(code, ...interpolations) {
{
return new Error(format(ERRORS[code], ...interpolations).trim());
}
}
/** Create a GroupedTag with an underlying Tag implementation */
const makeGroupedTag = (tag) => {
return new DefaultGroupedTag(tag);
};
const BASE_SIZE = 1 << 9;
const DefaultGroupedTag = class DefaultGroupedTag {
constructor(tag) {
this.groupSizes = new Uint32Array(BASE_SIZE);
this.length = BASE_SIZE;
this.tag = tag;
this._cGroup = 0;
this._cIndex = 0;
}
indexOfGroup(group) {
if (group === this._cGroup)
return this._cIndex;
let index = this._cIndex;
if (group > this._cGroup) {
for (let i = this._cGroup; i < group; i++) {
index += this.groupSizes[i];
}
}
else {
for (let i = this._cGroup - 1; i >= group; i--) {
index -= this.groupSizes[i];
}
}
this._cGroup = group;
this._cIndex = index;
return index;
}
insertRules(group, rules) {
if (group >= this.groupSizes.length) {
const oldBuffer = this.groupSizes;
const oldSize = oldBuffer.length;
let newSize = oldSize;
while (group >= newSize) {
newSize <<= 1;
if (newSize < 0) {
throw throwStyledComponentsError(16, `${group}`);
}
}
this.groupSizes = new Uint32Array(newSize);
this.groupSizes.set(oldBuffer);
this.length = newSize;
for (let i = oldSize; i < newSize; i++) {
this.groupSizes[i] = 0;
}
}
let ruleIndex = this.indexOfGroup(group + 1);
let insertedCount = 0;
for (let i = 0, l = rules.length; i < l; i++) {
if (this.tag.insertRule(ruleIndex, rules[i])) {
this.groupSizes[group]++;
ruleIndex++;
insertedCount++;
}
}
// Keep cache consistent: groups after the insertion point shift forward
if (insertedCount > 0 && this._cGroup > group) {
this._cIndex += insertedCount;
}
}
clearGroup(group) {
if (group < this.length) {
const length = this.groupSizes[group];
const startIndex = this.indexOfGroup(group);
const endIndex = startIndex + length;
this.groupSizes[group] = 0;
for (let i = startIndex; i < endIndex; i++) {
this.tag.deleteRule(startIndex);
}
// Keep cache consistent: groups after the cleared group shift backward
if (length > 0 && this._cGroup > group) {
this._cIndex -= length;
}
}
}
getGroup(group) {
let css = '';
if (group >= this.length || this.groupSizes[group] === 0) {
return css;
}
const length = this.groupSizes[group];
const startIndex = this.indexOfGroup(group);
const endIndex = startIndex + length;
for (let i = startIndex; i < endIndex; i++) {
css += this.tag.getRule(i) + SPLITTER;
}
return css;
}
};
const MAX_SMI = 1 << (31 - 1);
let groupIDRegister = new Map();
let reverseRegister = new Map();
let nextFreeGroup = 1;
const getGroupForId = (id) => {
if (groupIDRegister.has(id)) {
return groupIDRegister.get(id);
}
while (reverseRegister.has(nextFreeGroup)) {
nextFreeGroup++;
}
const group = nextFreeGroup++;
if (((group | 0) < 0 || group > MAX_SMI)) {
throw throwStyledComponentsError(16, `${group}`);
}
groupIDRegister.set(id, group);
reverseRegister.set(group, id);
return group;
};
const getIdForGroup = (group) => {
return reverseRegister.get(group);
};
const setGroupForId = (id, group) => {
// move pointer
nextFreeGroup = group + 1;
groupIDRegister.set(id, group);
reverseRegister.set(group, id);
};
const SELECTOR = `style[${SC_ATTR}][${SC_ATTR_VERSION}="${SC_VERSION}"]`;
const MARKER_RE = new RegExp(`^${SC_ATTR}\\.g(\\d+)\\[id="([\\w\\d-]+)"\\].*?"([^"]*)`);
/**
* Type guard to check if a node is a ShadowRoot.
* Uses instanceof when available, with duck-typing fallback for cross-realm scenarios.
*/
const isShadowRoot = (node) => {
return ((typeof ShadowRoot !== 'undefined' && node instanceof ShadowRoot) ||
('host' in node &&
// https://dom.spec.whatwg.org/#dom-node-document_fragment_node
node.nodeType === 11));
};
/**
* Extract the container (Document or ShadowRoot) from an InsertionTarget.
* If the target is a ShadowRoot, return it directly.
* If the target is an HTMLElement, return its root node if it's a ShadowRoot, otherwise return document.
*/
const getRehydrationContainer = (target) => {
if (!target) {
return document;
}
// Check if target is a ShadowRoot
if (isShadowRoot(target)) {
return target;
}
// Check if target is an HTMLElement inside a ShadowRoot
if ('getRootNode' in target) {
const root = target.getRootNode();
if (isShadowRoot(root)) {
return root;
}
}
return document;
};
const outputSheet = (sheet) => {
const tag = sheet.getTag();
const { length } = tag;
let css = '';
for (let group = 0; group < length; group++) {
const id = getIdForGroup(group);
if (id === undefined)
continue;
const names = sheet.names.get(id);
if (names === undefined || !names.size)
continue;
const rules = tag.getGroup(group);
if (rules.length === 0)
continue;
const selector = SC_ATTR + '.g' + group + '[id="' + id + '"]';
let content = '';
for (const name of names) {
if (name.length > 0) {
content += name + ',';
}
}
// NOTE: It's easier to collect rules and have the marker
// after the actual rules to simplify the rehydration
css += rules + selector + '{content:"' + content + '"}' + SPLITTER;
}
return css;
};
const rehydrateNamesFromContent = (sheet, id, content) => {
const names = content.split(',');
let name;
for (let i = 0, l = names.length; i < l; i++) {
if ((name = names[i])) {
sheet.registerName(id, name);
}
}
};
const rehydrateSheetFromTag = (sheet, style) => {
var _a;
const parts = ((_a = style.textContent) !== null && _a !== void 0 ? _a : '').split(SPLITTER);
const rules = [];
for (let i = 0, l = parts.length; i < l; i++) {
const part = parts[i].trim();
if (!part)
continue;
const marker = part.match(MARKER_RE);
if (marker) {
const group = parseInt(marker[1], 10) | 0;
const id = marker[2];
if (group !== 0) {
// Rehydrate componentId to group index mapping
setGroupForId(id, group);
// Rehydrate names and rules
// looks like: data-styled.g11[id="idA"]{content:"nameA,"}
rehydrateNamesFromContent(sheet, id, marker[3]);
sheet.getTag().insertRules(group, rules);
}
rules.length = 0;
}
else {
rules.push(part);
}
}
};
const rehydrateSheet = (sheet) => {
const container = getRehydrationContainer(sheet.options.target);
const nodes = container.querySelectorAll(SELECTOR);
for (let i = 0, l = nodes.length; i < l; i++) {
const node = nodes[i];
if (node && node.getAttribute(SC_ATTR) !== SC_ATTR_ACTIVE) {
rehydrateSheetFromTag(sheet, node);
if (node.parentNode) {
node.parentNode.removeChild(node);
}
}
}
};
/**
* Resolve a CSP nonce from available sources (in priority order):
* 1. <meta property="csp-nonce"> (Vite puts nonce in the `nonce` attr)
* 2. <meta name="sc-nonce"> (SC convention, nonce in `content` attr)
* 3. __webpack_nonce__ global (legacy)
*
* For Next.js/Remix, pass nonces explicitly via StyleSheetManager or
* ServerStyleSheet instead—auto-detection doesn't apply to header-based nonces.
*/
let cached = false;
function getNonce() {
if (cached !== false)
return cached;
if (typeof document !== 'undefined') {
// Vite sets the nonce in the `nonce` attribute. Browsers expose this via
// the .nonce DOM property but return "" from getAttribute('nonce').
const viteMeta = document.head.querySelector('meta[property="csp-nonce"]');
if (viteMeta)
return (cached = viteMeta.nonce || viteMeta.getAttribute('content') || undefined);
const scMeta = document.head.querySelector('meta[name="sc-nonce"]');
if (scMeta)
return (cached = scMeta.getAttribute('content') || undefined);
}
return (cached = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : undefined);
}
/** Find last style element if any inside target */
const findLastStyleTag = (target) => {
const arr = Array.from(target.querySelectorAll(`style[${SC_ATTR}]`));
return arr[arr.length - 1];
};
/** Create a style element inside `target` or <head> after the last */
const makeStyleTag = (target, nonce) => {
const head = document.head;
const parent = target || head;
const style = document.createElement('style');
const prevStyle = findLastStyleTag(parent);
const nextSibling = prevStyle !== undefined ? prevStyle.nextSibling : null;
style.setAttribute(SC_ATTR, SC_ATTR_ACTIVE);
style.setAttribute(SC_ATTR_VERSION, SC_VERSION);
const resolvedNonce = nonce || getNonce();
if (resolvedNonce)
style.setAttribute('nonce', resolvedNonce);
parent.insertBefore(style, nextSibling);
return style;
};
/** Get the CSSStyleSheet instance for a given style element */
const getSheet = (tag) => {
var _a;
if (tag.sheet) {
return tag.sheet;
}
// Avoid Firefox quirk where the style element might not have a sheet property.
// Use the tag's root node to find styleSheets — document.styleSheets doesn't
// include sheets inside shadow roots.
const root = tag.getRootNode();
const styleSheets = (_a = root.styleSheets) !== null && _a !== void 0 ? _a : document.styleSheets;
for (let i = 0, l = styleSheets.length; i < l; i++) {
const sheet = styleSheets[i];
if (sheet.ownerNode === tag) {
return sheet;
}
}
throw throwStyledComponentsError(17);
};
/** Create a CSSStyleSheet-like tag depending on the environment */
const makeTag = ({ isServer, useCSSOMInjection, target, nonce }) => {
if (useCSSOMInjection) {
return new CSSOMTag(target, nonce);
}
else {
return new TextTag(target, nonce);
}
};
const CSSOMTag = class CSSOMTag {
constructor(target, nonce) {
this.element = makeStyleTag(target, nonce);
// Avoid Edge bug where empty style elements don't create sheets
this.element.appendChild(document.createTextNode(''));
this.sheet = getSheet(this.element);
this.length = 0;
}
insertRule(index, rule) {
try {
this.sheet.insertRule(rule, index);
this.length++;
return true;
}
catch (_error) {
return false;
}
}
deleteRule(index) {
this.sheet.deleteRule(index);
this.length--;
}
getRule(index) {
const rule = this.sheet.cssRules[index];
// Avoid IE11 quirk where cssText is inaccessible on some invalid rules
if (rule && rule.cssText) {
return rule.cssText;
}
else {
return '';
}
}
};
/** A Tag that emulates the CSSStyleSheet API but uses text nodes */
const TextTag = class TextTag {
constructor(target, nonce) {
this.element = makeStyleTag(target, nonce);
this.nodes = this.element.childNodes;
this.length = 0;
}
insertRule(index, rule) {
if (index <= this.length && index >= 0) {
const node = document.createTextNode(rule);
const refNode = this.nodes[index];
this.element.insertBefore(node, refNode || null);
this.length++;
return true;
}
else {
return false;
}
}
deleteRule(index) {
this.element.removeChild(this.nodes[index]);
this.length--;
}
getRule(index) {
if (index < this.length) {
return this.nodes[index].textContent;
}
else {
return '';
}
}
};
let SHOULD_REHYDRATE = IS_BROWSER;
const defaultOptions = {
isServer: !IS_BROWSER,
useCSSOMInjection: !DISABLE_SPEEDY,
};
/** Contains the main stylesheet logic for stringification and caching */
class StyleSheet {
/** Register a group ID to give it an index */
static registerId(id) {
return getGroupForId(id);
}
constructor(options = EMPTY_OBJECT, globalStyles = {}, names) {
this.options = Object.assign(Object.assign({}, defaultOptions), options);
this.gs = globalStyles;
this.keyframeIds = new Set();
this.names = new Map(names);
this.server = !!options.isServer;
// We rehydrate only once and use the sheet that is created first
if (!this.server && IS_BROWSER && SHOULD_REHYDRATE) {
SHOULD_REHYDRATE = false;
rehydrateSheet(this);
}
setToString(this, () => outputSheet(this));
}
rehydrate() {
if (!this.server && IS_BROWSER) {
rehydrateSheet(this);
}
}
reconstructWithOptions(options, withNames = true) {
const newSheet = new StyleSheet(Object.assign(Object.assign({}, this.options), options), this.gs, (withNames && this.names) || undefined);
newSheet.keyframeIds = new Set(this.keyframeIds);
// If we're reconstructing with a new target on the client, check if the container changed
// This handles the case where StyleSheetManager's target prop changes (e.g., from undefined to shadowRoot)
// We only rehydrate if the container (Document or ShadowRoot) actually changes
if (!this.server && IS_BROWSER && options.target !== this.options.target) {
const oldContainer = getRehydrationContainer(this.options.target);
const newContainer = getRehydrationContainer(options.target);
if (oldContainer !== newContainer) {
rehydrateSheet(newSheet);
}
}
return newSheet;
}
allocateGSInstance(id) {
return (this.gs[id] = (this.gs[id] || 0) + 1);
}
/** Lazily initialises a GroupedTag for when it's actually needed */
getTag() {
return this.tag || (this.tag = makeGroupedTag(makeTag(this.options)));
}
/** Check whether a name is known for caching */
hasNameForId(id, name) {
var _a, _b;
return (_b = (_a = this.names.get(id)) === null || _a === void 0 ? void 0 : _a.has(name)) !== null && _b !== void 0 ? _b : false;
}
/** Mark a group's name as known for caching */
registerName(id, name) {
getGroupForId(id);
if (id.startsWith(KEYFRAMES_ID_PREFIX)) {
this.keyframeIds.add(id);
}
const existing = this.names.get(id);
if (existing) {
existing.add(name);
}
else {
this.names.set(id, new Set([name]));
}
}
/** Insert new rules which also marks the name as known */
insertRules(id, name, rules) {
this.registerName(id, name);
this.getTag().insertRules(getGroupForId(id), rules);
}
/** Clears all cached names for a given group ID */
clearNames(id) {
if (this.names.has(id)) {
this.names.get(id).clear();
}
}
/** Clears all rules for a given group ID */
clearRules(id) {
this.getTag().clearGroup(getGroupForId(id));
this.clearNames(id);
}
/** Clears the entire tag which deletes all rules but not its names */
clearTag() {
// NOTE: This does not clear the names, since it's only used during SSR
// so that we can continuously output only new rules
this.tag = undefined;
}
}
const cssTagged = new WeakSet();
/**
* CSS properties that accept unitless numeric values.
* Inlined from @emotion/unitless with IE-only entries removed
* (boxFlex, boxFlexGroup, boxOrdinalGroup, flexPositive, flexNegative,
* flexOrder, msGridRow, msGridRowSpan, msGridColumn, msGridColumnSpan).
*/
const unitless = {
animationIterationCount: 1,
aspectRatio: 1,
borderImageOutset: 1,
borderImageSlice: 1,
borderImageWidth: 1,
columnCount: 1,
columns: 1,
flex: 1,
flexGrow: 1,
flexShrink: 1,
gridRow: 1,
gridRowEnd: 1,
gridRowSpan: 1,
gridRowStart: 1,
gridColumn: 1,
gridColumnEnd: 1,
gridColumnSpan: 1,
gridColumnStart: 1,
fontWeight: 1,
lineHeight: 1,
opacity: 1,
order: 1,
orphans: 1,
scale: 1,
tabSize: 1,
widows: 1,
zIndex: 1,
zoom: 1,
WebkitLineClamp: 1,
fillOpacity: 1,
floodOpacity: 1,
stopOpacity: 1,
strokeDasharray: 1,
strokeDashoffset: 1,
strokeMiterlimit: 1,
strokeOpacity: 1,
strokeWidth: 1,
};
// Taken from https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/shared/dangerousStyleValue.js
function addUnitIfNeeded(name, value) {
// https://github.com/amilajack/eslint-plugin-flowtype-errors/issues/133
if (value == null || typeof value === 'boolean' || value === '') {
return '';
}
if (typeof value === 'number' && value !== 0 && !(name in unitless) && !name.startsWith('--')) {
return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers except for CSS variables
}
return String(value).trim();
}
function getComponentName(target) {
return ((typeof target === 'string' && target ) ||
target.displayName ||
target.name ||
'Component');
}
// Shared character-code constants for fast charCodeAt comparisons.
// Inlined at call sites by V8 after the first optimization pass.
const DOUBLE_QUOTE = 34; // "
const SINGLE_QUOTE = 39; // '
const SLASH = 47; // /
const ASTERISK = 42; // *
const BACKSLASH = 92; // \
const OPEN_BRACE = 123; // {
const CLOSE_BRACE = 125; // }
const SEMICOLON = 59; // ;
const NEWLINE = 10; // \n
const OPEN_PAREN = 40; // (
const CLOSE_PAREN = 41; // )
const HYPHEN = 45; // -
const UPPER_A = 65; // A
const UPPER_Z = 90; // Z
/** Offset from an ASCII uppercase letter to its lowercase counterpart. */
const UPPER_TO_LOWER = 32;
/**
* Hyphenates a camelcased CSS property name, for example:
*
* > hyphenateStyleName('backgroundColor')
* < "background-color"
* > hyphenateStyleName('MozTransition')
* < "-moz-transition"
* > hyphenateStyleName('msTransition')
* < "-ms-transition"
*
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
* is converted to `-ms-`.
*/
function hyphenateStyleName(string) {
// CSS variable prefix (`--*`) passes through untouched.
if (string.charCodeAt(0) === HYPHEN && string.charCodeAt(1) === HYPHEN) {
return string;
}
let output = '';
for (let i = 0; i < string.length; i++) {
const code = string.charCodeAt(i);
if (code >= UPPER_A && code <= UPPER_Z) {
output += '-' + String.fromCharCode(code + UPPER_TO_LOWER);
}
else {
output += string[i];
}
}
return output.startsWith('ms-') ? '-' + output : output;
}
function isFunction(test) {
return typeof test === 'function';
}
const KEYFRAMES_SYMBOL = Symbol.for('sc-keyframes');
function isKeyframes(value) {
return typeof value === 'object' && value !== null && KEYFRAMES_SYMBOL in value;
}
function isPlainObject(x) {
return (x !== null &&
typeof x === 'object' &&
x.constructor.name === Object.name &&
/* check for reasonable markers that the object isn't an element for react & preact/compat */
!('props' in x && x.$$typeof));
}
function isStatelessFunction(test) {
return isFunction(test) && !(test.prototype && test.prototype.isReactComponent);
}
/** Type guard that returns true if the target is a styled component. */
function isStyledComponent(target) {
return typeof target === 'object' && 'styledComponentId' in target;
}
/**
* It's falsish not falsy because 0 is allowed.
*/
const isFalsish = (chunk) => chunk === undefined || chunk === null || chunk === false || chunk === '';
const CLIENT_REFERENCE = Symbol.for('react.client.reference');
function isClientReference(chunk) {
return chunk.$$typeof === CLIENT_REFERENCE;
}
// React encodes $$id as "modulePath#exportName"
function warnClientReference(ref) {
const id = ref.$$id;
const label = (id && id.includes('#') ? id.split('#').pop() : id) || ref.name || 'unknown';
console.warn(`Interpolating a client component (${label}) as a selector is not supported in server components. The component selector pattern requires access to the component's internal class name, which is not available across the server/client boundary. Use a plain CSS class selector instead.`);
}
/** Internal accumulator form — avoids allocating a temp array per nesting level. */
function objToCssArrayInto(obj, rules) {
for (const key in obj) {
const val = obj[key];
if (!obj.hasOwnProperty(key) || isFalsish(val))
continue;
if ((Array.isArray(val) && cssTagged.has(val)) || isFunction(val)) {
rules.push(hyphenateStyleName(key) + ':', val, ';');
}
else if (isPlainObject(val)) {
rules.push(key + ' {');
objToCssArrayInto(val, rules);
rules.push('}');
}
else {
rules.push(hyphenateStyleName(key) + ': ' + addUnitIfNeeded(key, val) + ';');
}
}
}
function flatten(chunk, executionContext, styleSheet, stylisInstance, result = []) {
if (isFalsish(chunk)) {
return result;
}
const t = typeof chunk;
if (t === 'string') {
result.push(chunk);
return result;
}
if (t === 'function') {
if (isClientReference(chunk)) {
warnClientReference(chunk);
return result;
}
if (isStatelessFunction(chunk) && executionContext) {
const fnResult = chunk(executionContext);
if (typeof fnResult === 'object' &&
!Array.isArray(fnResult) &&
!isKeyframes(fnResult) &&
!isPlainObject(fnResult) &&
fnResult !== null) {
console.error(`${getComponentName(chunk)} is not a styled component and cannot be referred to via component selector. See https://styled-components.com/docs/advanced#referring-to-other-components for more details.`);
}
return flatten(fnResult, executionContext, styleSheet, stylisInstance, result);
}
else {
result.push(chunk);
return result;
}
}
if (Array.isArray(chunk)) {
for (let i = 0; i < chunk.length; i++) {
flatten(chunk[i], executionContext, styleSheet, stylisInstance, result);
}
return result;
}
if (isStyledComponent(chunk)) {
result.push(`.${chunk.styledComponentId}`);
return result;
}
if (isKeyframes(chunk)) {
if (styleSheet) {
chunk.inject(styleSheet, stylisInstance);
result.push(chunk.getName(stylisInstance));
}
else {
result.push(chunk);
}
return result;
}
// Module-level client reference proxies (typeof 'object') pass isPlainObject — catch before
if (isClientReference(chunk)) {
warnClientReference(chunk);
return result;
}
if (isPlainObject(chunk)) {
objToCssArrayInto(chunk, result);
return result;
}
result.push(chunk.toString());
return result;
}
function isStaticRules(rules) {
for (let i = 0; i < rules.length; i += 1) {
const rule = rules[i];
if (isFunction(rule) && !isStyledComponent(rule)) {
// functions are allowed to be static if they're just being
// used to get the classname of a nested styled component
return false;
}
}
return true;
}
/**
* Convenience function for joining strings to form className chains
*/
function joinStrings(a, b) {
return a && b ? a + ' ' + b : a || b || '';
}
function joinStringArray(arr, sep) {
return arr.join(sep || '');
}
class GlobalStyle {
constructor(rules, componentId) {
/** @internal Per-instance rule cache for shared-group rebuild. */
this.instanceRules = new Map();
this.rules = rules;
this.componentId = componentId;
this.isStatic = isStaticRules(rules);
// Pre-register the shared group so global styles defined before
// components always appear before them in the stylesheet.
StyleSheet.registerId(this.componentId);
}
removeStyles(instance, styleSheet) {
this.instanceRules.delete(instance);
this.rebuildGroup(styleSheet);
}
renderStyles(instance, executionContext, styleSheet, stylis) {
const id = this.componentId;
if (this.isStatic) {
if (!styleSheet.hasNameForId(id, id + instance)) {
const entry = this.computeRules(instance, executionContext, styleSheet, stylis);
styleSheet.insertRules(id, entry.name, entry.rules);
}
else if (!this.instanceRules.has(instance)) {
// Rehydrated style: populate cache so rebuildGroup can restore
// survivors if another instance unmounts.
this.computeRules(instance, executionContext, styleSheet, stylis);
}
return;
}
// Compute new rules; skip CSSOM rebuild if CSS is unchanged.
// The fast-path is only safe on the client where the tag persists between renders.
// During SSR, clearTag() destroys the tag between requests, so we must always rebuild.
const prev = this.instanceRules.get(instance);
this.computeRules(instance, executionContext, styleSheet, stylis);
if (!styleSheet.server && prev) {
const a = prev.rules;
const b = this.instanceRules.get(instance).rules;
if (a.length === b.length) {
let same = true;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
same = false;
break;
}
}
if (same)
return;
}
}
this.rebuildGroup(styleSheet);
}
computeRules(instance, executionContext, styleSheet, stylis) {
const flatCSS = joinStringArray(flatten(this.rules, executionContext, styleSheet, stylis));
const entry = {
name: this.componentId + instance,
rules: stylis(flatCSS, ''),
};
this.instanceRules.set(instance, entry);
return entry;
}
/**
* Clear all CSS rules in the shared group and re-insert from surviving instances.
* Must run synchronously — no yielding between clear and re-insert.
*/
rebuildGroup(styleSheet) {
const id = this.componentId;
styleSheet.clearRules(id);
for (const entry of this.instanceRules.values()) {
styleSheet.insertRules(id, entry.name, entry.rules);
}
}
}
var e="-ms-";var r="-moz-";var a="-webkit-";var c="comm";var n="rule";var s="decl";var i="@import";var v="@namespace";var b="@keyframes";var g="@layer";var $=Math.abs;var m=String.fromCharCode;var x=Object.assign;function y(e,r){return A(e,0)^45?(((r<<2^A(e,0))<<2^A(e,1))<<2^A(e,2))<<2^A(e,3):0}function j(e){return e.trim()}function z(e,r){return (e=r.exec(e))?e[0]:e}function C(e,r,a){return e.replace(r,a)}function O(e,r,a){return e.indexOf(r,a)}function A(e,r){return e.charCodeAt(r)|0}function M(e,r,a){return e.slice(r,a)}function S(e){return e.length}function q(e){return e.length}function B(e,r){return r.push(e),e}function D(e,r){return e.map(r).join("")}function E(e,r){return e.filter((function(e){return !z(e,r)}))}var F=1;var G=1;var H=0;var I=0;var J=0;var K="";function L(e,r,a,c,n,s,t,u){return {value:e,root:r,parent:a,type:c,props:n,children:s,line:F,column:G,length:t,return:"",siblings:u}}function N(e,r){return x(L("",null,null,"",null,null,0,e.siblings),e,{length:-e.length},r)}function P(e){while(e.root)e=N(e.root,{children:[e]});B(e,e.siblings);}function Q(){return J}function R(){J=I>0?A(K,--I):0;if(G--,J===10)G=1,F--;return J}function T(){J=I<H?A(K,I++):0;if(G++,J===10)G=1,F++;return J}function U(){return A(K,I)}function V(){return I}function W(e,r){return M(K,e,r)}function X(e){switch(e){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function Y(e){return F=G=1,H=S(K=e),I=0,[]}function Z(e){return K="",e}function _(e){return j(W(I-1,ne(e===91?e+2:e===40?e+1:e)))}function re(e){while(J=U())if(J<33)T();else break;return X(e)>2||X(J)>3?"":" "}function ce(e,r){while(--r&&T())if(J<48||J>102||J>57&&J<65||J>70&&J<97)break;return W(e,V()+(r<6&&U()==32&&T()==32))}function ne(e){while(T())switch(J){case e:return I;case 34:case 39:if(e!==34&&e!==39)ne(J);break;case 40:if(e===41)ne(e);break;case 92:T();break}return I}function se(e,r){while(T())if(e+J===47+10)break;else if(e+J===42+42&&U()===47)break;return "/*"+W(r,I-1)+"*"+m(e===47?e:T())}function te(e){while(!X(U()))T();return W(e,I)}function ue(e){return Z(ie("",null,null,null,[""],e=Y(e),0,[0],e))}function ie(e,r,a,c,n,s,t,u,i){var f=0;var o=0;var l=t;var p=0;var v=0;var b=0;var h=1;var w=1;var d=1;var g=0;var k="";var x=n;var y=s;var j=c;var z=k;while(w)switch(b=g,g=T()){case 40:if(b!=108&&A(z,l-1)==58){if(O(z+=C(_(g),"&","&\f"),"&\f",$(f?u[f-1]:0))!=-1)d=-1;break}case 34:case 39:case 91:z+=_(g);break;case 9:case 10:case 13:case 32:z+=re(b);break;case 92:z+=ce(V()-1,7);continue;case 47:switch(U()){case 42:case 47:B(oe(se(T(),V()),r,a,i),i);if((X(b||1)==5||X(U()||1)==5)&&S(z)&&M(z,-1,void 0)!==" ")z+=" ";break;default:z+="/";}break;case 123*h:u[f++]=S(z)*d;case 125*h:case 59:case 0:switch(g){case 0:case 125:w=0;case 59+o:if(d==-1)z=C(z,/\f/g,"");if(v>0&&(S(z)-l||h===0&&b===47))B(v>32?le(z+";",c,a,l-1,i):le(C(z," ","")+";",c,a,l-2,i),i);break;case 59:z+=";";default:B(j=fe(z,r,a,f,o,n,u,k,x=[],y=[],l,s),s);if(g===123)if(o===0)ie(z,r,j,j,x,s,l,u,y);else {switch(p){case 99:if(A(z,3)===110)break;case 108:if(A(z,2)===97)break;default:o=0;case 100:case 109:case 115:}if(o)ie(e,j,j,c&&B(fe(e,j,j,0,0,n,u,k,n,x=[],l,y),y),n,y,l,u,c?x:y);else ie(z,j,j,j,[""],y,0,u,y);}}f=o=v=0,h=d=1,k=z="",l=t;break;case 58:l=1+S(z),v=b;default:if(h<1)if(g==123)--h;else if(g==125&&h++==0&&R()==125)continue;switch(z+=m(g),g*h){case 38:d=o>0?1:(z+="\f",-1);break;case 44:u[f++]=(S(z)-1)*d,d=1;break;case 64:if(U()===45)z+=_(T());p=U(),o=l=S(k=z+=te(V())),g++;break;case 45:if(b===45&&S(z)==2)h=0;}}return s}function fe(e,r,a,c,s,t,u,i,f,o,l,p){var v=s-1;var b=s===0?t:[""];var h=q(b);for(var w=0,d=0,g=0;w<c;++w)for(var k=0,m=M(e,v+1,v=$(d=u[w])),x=e;k<h;++k)if(x=j(d>0?b[k]+" "+m:C(m,/&\f/g,b[k])))f[g++]=x;return L(e,r,a,s===0?n:i,f,o,l,p)}function oe(e,r,a,n){return L(e,r,a,c,m(Q()),M(e,2,-2),0,n)}function le(e,r,a,c,n){return L(e,r,a,s,M(e,0,c),M(e,c+1,-1),c,n)}function pe(c,n,s){switch(y(c,n)){case 5103:return a+"print-"+c+c;case 5737:case 4201:case 3177:case 3433:case 1641:case 4457:case 2921:case 5572:case 6356:case 5844:case 3191:case 6645:case 3005:case 4215:case 6389:case 5109:case 5365:case 5621:case 3829:case 6391:case 5879:case 5623:case 6135:case 4599:return a+c+c;case 4855:return a+c.replace("add","source-over").replace("substract","source-out").replace("intersect","source-in").replace("exclude","xor")+c;case 4789:return r+c+c;case 5349:case 4246:case 4810:case 6968:case 2756:return a+c+r+c+e+c+c;case 5936:switch(A(c,n+11)){case 114:return a+c+e+C(c,/[svh]\w+-[tblr]{2}/,"tb")+c;case 108:return a+c+e+C(c,/[svh]\w+-[tblr]{2}/,"tb-rl")+c;case 45:return a+c+e+C(c,/[svh]\w+-[tblr]{2}/,"lr")+c}case 6828:case 4268:case 2903:return a+c+e+c+c;case 6165:return a+c+e+"flex-"+c+c;case 5187:return a+c+C(c,/(\w+).+(:[^]+)/,a+"box-$1$2"+e+"flex-$1$2")+c;case 5443:return a+c+e+"flex-item-"+C(c,/flex-|-self/g,"")+(!z(c,/flex-|baseline/)?e+"grid-row-"+C(c,/flex-|-self/g,""):"")+c;case 4675:return a+c+e+"flex-line-pack"+C(c,/align-content|flex-|-self/g,"")+c;case 5548:return a+c+e+C(c,"shrink","negative")+c;case 5292:return a+c+e+C(c,"basis","preferred-size")+c;case 6060:return a+"box-"+C(c,"-grow","")+a+c+e+C(c,"grow","positive")+c;case 4554:return a+C(c,/([^-])(transform)/g,"$1"+a+"$2")+c;case 6187:return C(C(C(c,/(zoom-|grab)/,a+"$1"),/(image-set)/,a+"$1"),c,"")+c;case 5495:case 3959:return C(c,/(image-set\([^]*)/,a+"$1"+"$`$1");case 4968:return C(C(c,/(.+:)(flex-)?(.*)/,a+"box-pack:$3"+e+"flex-pack:$3"),/space-between/,"justify")+a+c+c;case 4200:if(!z(c,/flex-|baseline/))return e+"grid-column-align"+M(c,n)+c;break;case 2592:case 3360:return e+C(c,"template-","")+c;case 4384:case 3616:if(s&&s.some((function(e,r){return n=r,z(e.props,/grid-\w+-end/)}))){return ~O(c+(s=s[n].value),"span",0)?c:e+C(c,"-start","")+c+e+"grid-row-span:"+(~O(s,"span",0)?z(s,/\d+/):+z(s,/\d+/)-+z(c,/\d+/))+";"}return e+C(c,"-start","")+c;case 4896:case 4128:return s&&s.some((function(e){return z(e.props,/grid-\w+-start/)}))?c:e+C(C(c,"-end","-span"),"span ","")+c;case 4095:case 3583:case 4068:case 2532:return C(c,/(.+)-inline(.+)/,a+"$1$2")+c;case 8116:case 7059:case 5753:case 5535:case 5445:case 5701:case 4933:case 4677:case 5533:case 5789:case 5021:case 4765:if(S(c)-1-n>6)switch(A(c,n+1)){case 109:if(A(c,n+4)!==45)break;case 102:return C(c,/(.+:)(.+)-([^]+)/,"$1"+a+"$2-$3"+"$1"+r+(A(c,n+3)==108?"$3":"$2-$3"))+c;case 115:return ~O(c,"stretch",0)?pe(C(c,"stretch","fill-available"),n,s)+c:c}break;case 5152:case 5920:return C(c,/(.+?):(\d+)(\s*\/\s*(span)?\s*(\d+))?(.*)/,(function(r,a,n,s,t,u,i){return e+a+":"+n+i+(s?e+a+"-span:"+(t?u:+u-+n)+i:"")+c}));case 4949:if(A(c,n+6)===121)return C(c,":",":"+a)+c;break;case 6444:switch(A(c,A(c,14)===45?18:11)){case 120:return C(c,/(.+:)([^;\s!]+)(;|(\s+)?!.+)?/,"$1"+a+(A(c,14)===45?"inline-":"")+"box$3"+"$1"+a+"$2$3"+"$1"+e+"$2box$3")+c;case 100:return C(c,":",":"+e)+c}break;case 5719:case 2647:case 2135:case 3927:case 2391:return C(c,"scroll-","scroll-snap-")+c}return c}function ve(e,r){var a="";for(var c=0;c<e.length;c++)a+=r(e[c],c,e,r)||"";return a}function be(e,r,a,t){switch(e.type){case g:if(e.children.length)break;case i:case v:case s:return e.return=e.return||e.value;case c:return "";case b:return e.return=e.value+"{"+ve(e.children,t)+"}";case n:if(!S(e.value=e.props.join(",")))return ""}return S(a=ve(e.children,t))?e.return=e.value+"{"+a+"}":""}function he(e){var r=q(e);return function(a,c,n,s){var t="";for(var u=0;u<r;u++)t+=e[u](a,c,n,s)||"";return t}}function we(e){return function(r){if(!r.root)if(r=r.return)e(r);}}function de(c,t,u,i){if(c.length>-1)if(!c.return)switch(c.type){case s:c.return=pe(c.value,c.length,u);return;case b:return ve([N(c,{value:C(c.value,"@","@"+a)})],i);case n:if(c.length)return D(u=c.props,(function(n){switch(z(n,i=/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":P(N(c,{props:[C(n,/:(read-\w+)/,":"+r+"$1")]}));P(N(c,{props:[n]}));x(c,{props:E(u,i)});break;case"::placeholder":P(N(c,{props:[C(n,/:(plac\w+)/,":"+a+"input-$1")]}));P(N(c,{props:[C(n,/:(plac\w+)/,":"+r+"$1")]}));P(N(c,{props:[C(n,/:(plac\w+)/,e+"input-$1")]}));P(N(c,{props:[n]}));x(c,{props:E(u,i)});break}return ""}))}}
const SEED$1 = 5381;
// When we have separate strings it's useful to run a progressive
// version of djb2 where we pretend that we're still looping over
// the same string
const phash = (h, x) => {
let i = x.length;
while (i) {
h = (h * 33) ^ x.charCodeAt(--i);
}
return h;
};
// This is a djb2 hashing function
const hash = (x) => {
return phash(SEED$1, x);
};
const AMP_REGEX = /&/g;
/**
* Check if a quote at position i is escaped. A quote is escaped when preceded
* by an ODD number of backslashes (\", \\\", etc.). An even number means the
* backslashes themselves are escaped and the quote is real (\\", \\\\", etc.).
*/
function isEscaped(css, i) {
let backslashes = 0;
while (--i >= 0 && css.charCodeAt(i) === BACKSLASH)
backslashes++;
return (backslashes & 1) === 1;
}
/**
* Unified CSS preprocessor: strips JS-style line comments (//) and validates
* brace balance in a single pass. Handles strings, parenthesized expressions
* (any function call), and block comments with one shared state machine.
*
* Fast paths:
* - No // and no } → return unchanged (zero work)
* - No // but has } → brace-only validation (lightweight single pass)
* - Has // → full unified pass (strip comments + count braces simultaneously)
*/
function preprocessCSS(css) {
const hasLineComments = css.indexOf('//') !== -1;
const hasCloseBrace = css.indexOf('}') !== -1;
if (!hasLineComments && !hasCloseBrace)
return css;
if (!hasLineComments)
return sanitizeBraces(css);
const len = css.length;
let out = '';
let start = 0;
let i = 0;
let inString = 0;
let parenDepth = 0;
let braceDepth = 0;
let modified = false;
while (i < len) {
const code = css.charCodeAt(i);
if ((code === DOUBLE_QUOTE || code === SINGLE_QUOTE) && !isEscaped(css, i)) {
if (inString === 0) {
inString = code;
}
else if (inString === code) {
inString = 0;
}
i++;
continue;
}
if (inString !== 0) {
i++;
continue;
}
if (code === SLASH && i + 1 < len && css.charCodeAt(i + 1) === ASTERISK) {
i += 2;
while (i + 1 < len && !(css.charCodeAt(i) === ASTERISK && css.charCodeAt(i + 1) === SLASH)) {
i++;
}
i += 2;
continue;
}
if (code === OPEN_PAREN) {
parenDepth++;
i++;
continue;
}
if (code === CLOSE_PAREN) {
if (parenDepth > 0)
parenDepth--;
i++;
continue;
}