Grabbed dndbeyond's source code
``` ~/go/bin/sourcemapper -output ddb -jsurl https://media.dndbeyond.com/character-app/static/js/main.90aa78c5.js ```
This commit is contained in:
+37
@@ -0,0 +1,37 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { GlobalStyles as MuiGlobalStyles } from '@mui/styled-engine';
|
||||
import useTheme from '../useTheme';
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
function GlobalStyles({
|
||||
styles,
|
||||
themeId,
|
||||
defaultTheme = {}
|
||||
}) {
|
||||
const upperTheme = useTheme(defaultTheme);
|
||||
const globalStyles = typeof styles === 'function' ? styles(themeId ? upperTheme[themeId] || upperTheme : upperTheme) : styles;
|
||||
return /*#__PURE__*/_jsx(MuiGlobalStyles, {
|
||||
styles: globalStyles
|
||||
});
|
||||
}
|
||||
process.env.NODE_ENV !== "production" ? GlobalStyles.propTypes /* remove-proptypes */ = {
|
||||
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
||||
// │ These PropTypes are generated from the TypeScript type definitions. │
|
||||
// │ To update them, edit the TypeScript types and run `pnpm proptypes`. │
|
||||
// └─────────────────────────────────────────────────────────────────────┘
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
defaultTheme: PropTypes.object,
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
styles: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.array, PropTypes.func, PropTypes.number, PropTypes.object, PropTypes.string, PropTypes.bool]),
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
themeId: PropTypes.string
|
||||
} : void 0;
|
||||
export default GlobalStyles;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
||||
const _excluded = ["value"];
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
const RtlContext = /*#__PURE__*/React.createContext();
|
||||
function RtlProvider(_ref) {
|
||||
let {
|
||||
value
|
||||
} = _ref,
|
||||
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
||||
return /*#__PURE__*/_jsx(RtlContext.Provider, _extends({
|
||||
value: value != null ? value : true
|
||||
}, props));
|
||||
}
|
||||
process.env.NODE_ENV !== "production" ? RtlProvider.propTypes = {
|
||||
children: PropTypes.node,
|
||||
value: PropTypes.bool
|
||||
} : void 0;
|
||||
export const useRtl = () => {
|
||||
const value = React.useContext(RtlContext);
|
||||
return value != null ? value : false;
|
||||
};
|
||||
export default RtlProvider;
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
const _excluded = ["component", "direction", "spacing", "divider", "children", "className", "useFlexGap"];
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import clsx from 'clsx';
|
||||
import deepmerge from '@mui/utils/deepmerge';
|
||||
import generateUtilityClass from '@mui/utils/generateUtilityClass';
|
||||
import composeClasses from '@mui/utils/composeClasses';
|
||||
import systemStyled from '../styled';
|
||||
import useThemePropsSystem from '../useThemeProps';
|
||||
import { extendSxProp } from '../styleFunctionSx';
|
||||
import createTheme from '../createTheme';
|
||||
import { handleBreakpoints, mergeBreakpointsInOrder, resolveBreakpointValues } from '../breakpoints';
|
||||
import { createUnarySpacing, getValue } from '../spacing';
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
const defaultTheme = createTheme();
|
||||
// widening Theme to any so that the consumer can own the theme structure.
|
||||
const defaultCreateStyledComponent = systemStyled('div', {
|
||||
name: 'MuiStack',
|
||||
slot: 'Root',
|
||||
overridesResolver: (props, styles) => styles.root
|
||||
});
|
||||
function useThemePropsDefault(props) {
|
||||
return useThemePropsSystem({
|
||||
props,
|
||||
name: 'MuiStack',
|
||||
defaultTheme
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array with the separator React element interspersed between
|
||||
* each React node of the input children.
|
||||
*
|
||||
* > joinChildren([1,2,3], 0)
|
||||
* [1,0,2,0,3]
|
||||
*/
|
||||
function joinChildren(children, separator) {
|
||||
const childrenArray = React.Children.toArray(children).filter(Boolean);
|
||||
return childrenArray.reduce((output, child, index) => {
|
||||
output.push(child);
|
||||
if (index < childrenArray.length - 1) {
|
||||
output.push( /*#__PURE__*/React.cloneElement(separator, {
|
||||
key: `separator-${index}`
|
||||
}));
|
||||
}
|
||||
return output;
|
||||
}, []);
|
||||
}
|
||||
const getSideFromDirection = direction => {
|
||||
return {
|
||||
row: 'Left',
|
||||
'row-reverse': 'Right',
|
||||
column: 'Top',
|
||||
'column-reverse': 'Bottom'
|
||||
}[direction];
|
||||
};
|
||||
export const style = ({
|
||||
ownerState,
|
||||
theme
|
||||
}) => {
|
||||
let styles = _extends({
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}, handleBreakpoints({
|
||||
theme
|
||||
}, resolveBreakpointValues({
|
||||
values: ownerState.direction,
|
||||
breakpoints: theme.breakpoints.values
|
||||
}), propValue => ({
|
||||
flexDirection: propValue
|
||||
})));
|
||||
if (ownerState.spacing) {
|
||||
const transformer = createUnarySpacing(theme);
|
||||
const base = Object.keys(theme.breakpoints.values).reduce((acc, breakpoint) => {
|
||||
if (typeof ownerState.spacing === 'object' && ownerState.spacing[breakpoint] != null || typeof ownerState.direction === 'object' && ownerState.direction[breakpoint] != null) {
|
||||
acc[breakpoint] = true;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
const directionValues = resolveBreakpointValues({
|
||||
values: ownerState.direction,
|
||||
base
|
||||
});
|
||||
const spacingValues = resolveBreakpointValues({
|
||||
values: ownerState.spacing,
|
||||
base
|
||||
});
|
||||
if (typeof directionValues === 'object') {
|
||||
Object.keys(directionValues).forEach((breakpoint, index, breakpoints) => {
|
||||
const directionValue = directionValues[breakpoint];
|
||||
if (!directionValue) {
|
||||
const previousDirectionValue = index > 0 ? directionValues[breakpoints[index - 1]] : 'column';
|
||||
directionValues[breakpoint] = previousDirectionValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
const styleFromPropValue = (propValue, breakpoint) => {
|
||||
if (ownerState.useFlexGap) {
|
||||
return {
|
||||
gap: getValue(transformer, propValue)
|
||||
};
|
||||
}
|
||||
return {
|
||||
// The useFlexGap={false} implement relies on each child to give up control of the margin.
|
||||
// We need to reset the margin to avoid double spacing.
|
||||
'& > :not(style):not(style)': {
|
||||
margin: 0
|
||||
},
|
||||
'& > :not(style) ~ :not(style)': {
|
||||
[`margin${getSideFromDirection(breakpoint ? directionValues[breakpoint] : ownerState.direction)}`]: getValue(transformer, propValue)
|
||||
}
|
||||
};
|
||||
};
|
||||
styles = deepmerge(styles, handleBreakpoints({
|
||||
theme
|
||||
}, spacingValues, styleFromPropValue));
|
||||
}
|
||||
styles = mergeBreakpointsInOrder(theme.breakpoints, styles);
|
||||
return styles;
|
||||
};
|
||||
export default function createStack(options = {}) {
|
||||
const {
|
||||
// This will allow adding custom styled fn (for example for custom sx style function)
|
||||
createStyledComponent = defaultCreateStyledComponent,
|
||||
useThemeProps = useThemePropsDefault,
|
||||
componentName = 'MuiStack'
|
||||
} = options;
|
||||
const useUtilityClasses = () => {
|
||||
const slots = {
|
||||
root: ['root']
|
||||
};
|
||||
return composeClasses(slots, slot => generateUtilityClass(componentName, slot), {});
|
||||
};
|
||||
const StackRoot = createStyledComponent(style);
|
||||
const Stack = /*#__PURE__*/React.forwardRef(function Grid(inProps, ref) {
|
||||
const themeProps = useThemeProps(inProps);
|
||||
const props = extendSxProp(themeProps); // `color` type conflicts with html color attribute.
|
||||
const {
|
||||
component = 'div',
|
||||
direction = 'column',
|
||||
spacing = 0,
|
||||
divider,
|
||||
children,
|
||||
className,
|
||||
useFlexGap = false
|
||||
} = props,
|
||||
other = _objectWithoutPropertiesLoose(props, _excluded);
|
||||
const ownerState = {
|
||||
direction,
|
||||
spacing,
|
||||
useFlexGap
|
||||
};
|
||||
const classes = useUtilityClasses();
|
||||
return /*#__PURE__*/_jsx(StackRoot, _extends({
|
||||
as: component,
|
||||
ownerState: ownerState,
|
||||
ref: ref,
|
||||
className: clsx(classes.root, className)
|
||||
}, other, {
|
||||
children: divider ? joinChildren(children, divider) : children
|
||||
}));
|
||||
});
|
||||
process.env.NODE_ENV !== "production" ? Stack.propTypes /* remove-proptypes */ = {
|
||||
children: PropTypes.node,
|
||||
direction: PropTypes.oneOfType([PropTypes.oneOf(['column-reverse', 'column', 'row-reverse', 'row']), PropTypes.arrayOf(PropTypes.oneOf(['column-reverse', 'column', 'row-reverse', 'row'])), PropTypes.object]),
|
||||
divider: PropTypes.node,
|
||||
spacing: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])), PropTypes.number, PropTypes.object, PropTypes.string]),
|
||||
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
||||
} : void 0;
|
||||
return Stack;
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
'use client';
|
||||
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import * as React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ThemeProvider as MuiThemeProvider, useTheme as usePrivateTheme } from '@mui/private-theming';
|
||||
import exactProp from '@mui/utils/exactProp';
|
||||
import { ThemeContext as StyledEngineThemeContext } from '@mui/styled-engine';
|
||||
import useThemeWithoutDefault from '../useThemeWithoutDefault';
|
||||
import RtlProvider from '../RtlProvider';
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
const EMPTY_THEME = {};
|
||||
function useThemeScoping(themeId, upperTheme, localTheme, isPrivate = false) {
|
||||
return React.useMemo(() => {
|
||||
const resolvedTheme = themeId ? upperTheme[themeId] || upperTheme : upperTheme;
|
||||
if (typeof localTheme === 'function') {
|
||||
const mergedTheme = localTheme(resolvedTheme);
|
||||
const result = themeId ? _extends({}, upperTheme, {
|
||||
[themeId]: mergedTheme
|
||||
}) : mergedTheme;
|
||||
// must return a function for the private theme to NOT merge with the upper theme.
|
||||
// see the test case "use provided theme from a callback" in ThemeProvider.test.js
|
||||
if (isPrivate) {
|
||||
return () => result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return themeId ? _extends({}, upperTheme, {
|
||||
[themeId]: localTheme
|
||||
}) : _extends({}, upperTheme, localTheme);
|
||||
}, [themeId, upperTheme, localTheme, isPrivate]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This component makes the `theme` available down the React tree.
|
||||
* It should preferably be used at **the root of your component tree**.
|
||||
*
|
||||
* <ThemeProvider theme={theme}> // existing use case
|
||||
* <ThemeProvider theme={{ id: theme }}> // theme scoping
|
||||
*/
|
||||
function ThemeProvider(props) {
|
||||
const {
|
||||
children,
|
||||
theme: localTheme,
|
||||
themeId
|
||||
} = props;
|
||||
const upperTheme = useThemeWithoutDefault(EMPTY_THEME);
|
||||
const upperPrivateTheme = usePrivateTheme() || EMPTY_THEME;
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (upperTheme === null && typeof localTheme === 'function' || themeId && upperTheme && !upperTheme[themeId] && typeof localTheme === 'function') {
|
||||
console.error(['MUI: You are providing a theme function prop to the ThemeProvider component:', '<ThemeProvider theme={outerTheme => outerTheme} />', '', 'However, no outer theme is present.', 'Make sure a theme is already injected higher in the React tree ' + 'or provide a theme object.'].join('\n'));
|
||||
}
|
||||
}
|
||||
const engineTheme = useThemeScoping(themeId, upperTheme, localTheme);
|
||||
const privateTheme = useThemeScoping(themeId, upperPrivateTheme, localTheme, true);
|
||||
const rtlValue = engineTheme.direction === 'rtl';
|
||||
return /*#__PURE__*/_jsx(MuiThemeProvider, {
|
||||
theme: privateTheme,
|
||||
children: /*#__PURE__*/_jsx(StyledEngineThemeContext.Provider, {
|
||||
value: engineTheme,
|
||||
children: /*#__PURE__*/_jsx(RtlProvider, {
|
||||
value: rtlValue,
|
||||
children: children
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
process.env.NODE_ENV !== "production" ? ThemeProvider.propTypes /* remove-proptypes */ = {
|
||||
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
||||
// │ These PropTypes are generated from the TypeScript type definitions. │
|
||||
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
||||
// └─────────────────────────────────────────────────────────────────────┘
|
||||
/**
|
||||
* Your component tree.
|
||||
*/
|
||||
children: PropTypes.node,
|
||||
/**
|
||||
* A theme object. You can provide a function to extend the outer theme.
|
||||
*/
|
||||
theme: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,
|
||||
/**
|
||||
* The design system's unique id for getting the corresponded theme when there are multiple design systems.
|
||||
*/
|
||||
themeId: PropTypes.string
|
||||
} : void 0;
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
process.env.NODE_ENV !== "production" ? ThemeProvider.propTypes = exactProp(ThemeProvider.propTypes) : void 0;
|
||||
}
|
||||
export default ThemeProvider;
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import responsivePropType from './responsivePropType';
|
||||
import style from './style';
|
||||
import compose from './compose';
|
||||
import { createUnaryUnit, getValue } from './spacing';
|
||||
import { handleBreakpoints } from './breakpoints';
|
||||
export function borderTransform(value) {
|
||||
if (typeof value !== 'number') {
|
||||
return value;
|
||||
}
|
||||
return `${value}px solid`;
|
||||
}
|
||||
function createBorderStyle(prop, transform) {
|
||||
return style({
|
||||
prop,
|
||||
themeKey: 'borders',
|
||||
transform
|
||||
});
|
||||
}
|
||||
export const border = createBorderStyle('border', borderTransform);
|
||||
export const borderTop = createBorderStyle('borderTop', borderTransform);
|
||||
export const borderRight = createBorderStyle('borderRight', borderTransform);
|
||||
export const borderBottom = createBorderStyle('borderBottom', borderTransform);
|
||||
export const borderLeft = createBorderStyle('borderLeft', borderTransform);
|
||||
export const borderColor = createBorderStyle('borderColor');
|
||||
export const borderTopColor = createBorderStyle('borderTopColor');
|
||||
export const borderRightColor = createBorderStyle('borderRightColor');
|
||||
export const borderBottomColor = createBorderStyle('borderBottomColor');
|
||||
export const borderLeftColor = createBorderStyle('borderLeftColor');
|
||||
export const outline = createBorderStyle('outline', borderTransform);
|
||||
export const outlineColor = createBorderStyle('outlineColor');
|
||||
|
||||
// false positive
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
export const borderRadius = props => {
|
||||
if (props.borderRadius !== undefined && props.borderRadius !== null) {
|
||||
const transformer = createUnaryUnit(props.theme, 'shape.borderRadius', 4, 'borderRadius');
|
||||
const styleFromPropValue = propValue => ({
|
||||
borderRadius: getValue(transformer, propValue)
|
||||
});
|
||||
return handleBreakpoints(props, props.borderRadius, styleFromPropValue);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
borderRadius.propTypes = process.env.NODE_ENV !== 'production' ? {
|
||||
borderRadius: responsivePropType
|
||||
} : {};
|
||||
borderRadius.filterProps = ['borderRadius'];
|
||||
const borders = compose(border, borderTop, borderRight, borderBottom, borderLeft, borderColor, borderTopColor, borderRightColor, borderBottomColor, borderLeftColor, borderRadius, outline, outlineColor);
|
||||
export default borders;
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import PropTypes from 'prop-types';
|
||||
import deepmerge from '@mui/utils/deepmerge';
|
||||
import merge from './merge';
|
||||
|
||||
// The breakpoint **start** at this value.
|
||||
// For instance with the first breakpoint xs: [xs, sm[.
|
||||
export const values = {
|
||||
xs: 0,
|
||||
// phone
|
||||
sm: 600,
|
||||
// tablet
|
||||
md: 900,
|
||||
// small laptop
|
||||
lg: 1200,
|
||||
// desktop
|
||||
xl: 1536 // large screen
|
||||
};
|
||||
const defaultBreakpoints = {
|
||||
// Sorted ASC by size. That's important.
|
||||
// It can't be configured as it's used statically for propTypes.
|
||||
keys: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
up: key => `@media (min-width:${values[key]}px)`
|
||||
};
|
||||
export function handleBreakpoints(props, propValue, styleFromPropValue) {
|
||||
const theme = props.theme || {};
|
||||
if (Array.isArray(propValue)) {
|
||||
const themeBreakpoints = theme.breakpoints || defaultBreakpoints;
|
||||
return propValue.reduce((acc, item, index) => {
|
||||
acc[themeBreakpoints.up(themeBreakpoints.keys[index])] = styleFromPropValue(propValue[index]);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
if (typeof propValue === 'object') {
|
||||
const themeBreakpoints = theme.breakpoints || defaultBreakpoints;
|
||||
return Object.keys(propValue).reduce((acc, breakpoint) => {
|
||||
// key is breakpoint
|
||||
if (Object.keys(themeBreakpoints.values || values).indexOf(breakpoint) !== -1) {
|
||||
const mediaKey = themeBreakpoints.up(breakpoint);
|
||||
acc[mediaKey] = styleFromPropValue(propValue[breakpoint], breakpoint);
|
||||
} else {
|
||||
const cssKey = breakpoint;
|
||||
acc[cssKey] = propValue[cssKey];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
const output = styleFromPropValue(propValue);
|
||||
return output;
|
||||
}
|
||||
function breakpoints(styleFunction) {
|
||||
// false positive
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
const newStyleFunction = props => {
|
||||
const theme = props.theme || {};
|
||||
const base = styleFunction(props);
|
||||
const themeBreakpoints = theme.breakpoints || defaultBreakpoints;
|
||||
const extended = themeBreakpoints.keys.reduce((acc, key) => {
|
||||
if (props[key]) {
|
||||
acc = acc || {};
|
||||
acc[themeBreakpoints.up(key)] = styleFunction(_extends({
|
||||
theme
|
||||
}, props[key]));
|
||||
}
|
||||
return acc;
|
||||
}, null);
|
||||
return merge(base, extended);
|
||||
};
|
||||
newStyleFunction.propTypes = process.env.NODE_ENV !== 'production' ? _extends({}, styleFunction.propTypes, {
|
||||
xs: PropTypes.object,
|
||||
sm: PropTypes.object,
|
||||
md: PropTypes.object,
|
||||
lg: PropTypes.object,
|
||||
xl: PropTypes.object
|
||||
}) : {};
|
||||
newStyleFunction.filterProps = ['xs', 'sm', 'md', 'lg', 'xl', ...styleFunction.filterProps];
|
||||
return newStyleFunction;
|
||||
}
|
||||
export function createEmptyBreakpointObject(breakpointsInput = {}) {
|
||||
var _breakpointsInput$key;
|
||||
const breakpointsInOrder = (_breakpointsInput$key = breakpointsInput.keys) == null ? void 0 : _breakpointsInput$key.reduce((acc, key) => {
|
||||
const breakpointStyleKey = breakpointsInput.up(key);
|
||||
acc[breakpointStyleKey] = {};
|
||||
return acc;
|
||||
}, {});
|
||||
return breakpointsInOrder || {};
|
||||
}
|
||||
export function removeUnusedBreakpoints(breakpointKeys, style) {
|
||||
return breakpointKeys.reduce((acc, key) => {
|
||||
const breakpointOutput = acc[key];
|
||||
const isBreakpointUnused = !breakpointOutput || Object.keys(breakpointOutput).length === 0;
|
||||
if (isBreakpointUnused) {
|
||||
delete acc[key];
|
||||
}
|
||||
return acc;
|
||||
}, style);
|
||||
}
|
||||
export function mergeBreakpointsInOrder(breakpointsInput, ...styles) {
|
||||
const emptyBreakpoints = createEmptyBreakpointObject(breakpointsInput);
|
||||
const mergedOutput = [emptyBreakpoints, ...styles].reduce((prev, next) => deepmerge(prev, next), {});
|
||||
return removeUnusedBreakpoints(Object.keys(emptyBreakpoints), mergedOutput);
|
||||
}
|
||||
|
||||
// compute base for responsive values; e.g.,
|
||||
// [1,2,3] => {xs: true, sm: true, md: true}
|
||||
// {xs: 1, sm: 2, md: 3} => {xs: true, sm: true, md: true}
|
||||
export function computeBreakpointsBase(breakpointValues, themeBreakpoints) {
|
||||
// fixed value
|
||||
if (typeof breakpointValues !== 'object') {
|
||||
return {};
|
||||
}
|
||||
const base = {};
|
||||
const breakpointsKeys = Object.keys(themeBreakpoints);
|
||||
if (Array.isArray(breakpointValues)) {
|
||||
breakpointsKeys.forEach((breakpoint, i) => {
|
||||
if (i < breakpointValues.length) {
|
||||
base[breakpoint] = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
breakpointsKeys.forEach(breakpoint => {
|
||||
if (breakpointValues[breakpoint] != null) {
|
||||
base[breakpoint] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return base;
|
||||
}
|
||||
export function resolveBreakpointValues({
|
||||
values: breakpointValues,
|
||||
breakpoints: themeBreakpoints,
|
||||
base: customBase
|
||||
}) {
|
||||
const base = customBase || computeBreakpointsBase(breakpointValues, themeBreakpoints);
|
||||
const keys = Object.keys(base);
|
||||
if (keys.length === 0) {
|
||||
return breakpointValues;
|
||||
}
|
||||
let previous;
|
||||
return keys.reduce((acc, breakpoint, i) => {
|
||||
if (Array.isArray(breakpointValues)) {
|
||||
acc[breakpoint] = breakpointValues[i] != null ? breakpointValues[i] : breakpointValues[previous];
|
||||
previous = i;
|
||||
} else if (typeof breakpointValues === 'object') {
|
||||
acc[breakpoint] = breakpointValues[breakpoint] != null ? breakpointValues[breakpoint] : breakpointValues[previous];
|
||||
previous = breakpoint;
|
||||
} else {
|
||||
acc[breakpoint] = breakpointValues;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
export default breakpoints;
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
import _formatMuiErrorMessage from "@mui/utils/formatMuiErrorMessage";
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import clamp from '@mui/utils/clamp';
|
||||
/**
|
||||
* Returns a number whose value is limited to the given range.
|
||||
* @param {number} value The value to be clamped
|
||||
* @param {number} min The lower boundary of the output range
|
||||
* @param {number} max The upper boundary of the output range
|
||||
* @returns {number} A number in the range [min, max]
|
||||
*/
|
||||
function clampWrapper(value, min = 0, max = 1) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (value < min || value > max) {
|
||||
console.error(`MUI: The value provided ${value} is out of range [${min}, ${max}].`);
|
||||
}
|
||||
}
|
||||
return clamp(value, min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a color from CSS hex format to CSS rgb format.
|
||||
* @param {string} color - Hex color, i.e. #nnn or #nnnnnn
|
||||
* @returns {string} A CSS rgb color string
|
||||
*/
|
||||
export function hexToRgb(color) {
|
||||
color = color.slice(1);
|
||||
const re = new RegExp(`.{1,${color.length >= 6 ? 2 : 1}}`, 'g');
|
||||
let colors = color.match(re);
|
||||
if (colors && colors[0].length === 1) {
|
||||
colors = colors.map(n => n + n);
|
||||
}
|
||||
return colors ? `rgb${colors.length === 4 ? 'a' : ''}(${colors.map((n, index) => {
|
||||
return index < 3 ? parseInt(n, 16) : Math.round(parseInt(n, 16) / 255 * 1000) / 1000;
|
||||
}).join(', ')})` : '';
|
||||
}
|
||||
function intToHex(int) {
|
||||
const hex = int.toString(16);
|
||||
return hex.length === 1 ? `0${hex}` : hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object with the type and values of a color.
|
||||
*
|
||||
* Note: Does not support rgb % values.
|
||||
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @returns {object} - A MUI color object: {type: string, values: number[]}
|
||||
*/
|
||||
export function decomposeColor(color) {
|
||||
// Idempotent
|
||||
if (color.type) {
|
||||
return color;
|
||||
}
|
||||
if (color.charAt(0) === '#') {
|
||||
return decomposeColor(hexToRgb(color));
|
||||
}
|
||||
const marker = color.indexOf('(');
|
||||
const type = color.substring(0, marker);
|
||||
if (['rgb', 'rgba', 'hsl', 'hsla', 'color'].indexOf(type) === -1) {
|
||||
throw new Error(process.env.NODE_ENV !== "production" ? `MUI: Unsupported \`${color}\` color.
|
||||
The following formats are supported: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color().` : _formatMuiErrorMessage(9, color));
|
||||
}
|
||||
let values = color.substring(marker + 1, color.length - 1);
|
||||
let colorSpace;
|
||||
if (type === 'color') {
|
||||
values = values.split(' ');
|
||||
colorSpace = values.shift();
|
||||
if (values.length === 4 && values[3].charAt(0) === '/') {
|
||||
values[3] = values[3].slice(1);
|
||||
}
|
||||
if (['srgb', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec-2020'].indexOf(colorSpace) === -1) {
|
||||
throw new Error(process.env.NODE_ENV !== "production" ? `MUI: unsupported \`${colorSpace}\` color space.
|
||||
The following color spaces are supported: srgb, display-p3, a98-rgb, prophoto-rgb, rec-2020.` : _formatMuiErrorMessage(10, colorSpace));
|
||||
}
|
||||
} else {
|
||||
values = values.split(',');
|
||||
}
|
||||
values = values.map(value => parseFloat(value));
|
||||
return {
|
||||
type,
|
||||
values,
|
||||
colorSpace
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a channel created from the input color.
|
||||
*
|
||||
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @returns {string} - The channel for the color, that can be used in rgba or hsla colors
|
||||
*/
|
||||
export const colorChannel = color => {
|
||||
const decomposedColor = decomposeColor(color);
|
||||
return decomposedColor.values.slice(0, 3).map((val, idx) => decomposedColor.type.indexOf('hsl') !== -1 && idx !== 0 ? `${val}%` : val).join(' ');
|
||||
};
|
||||
export const private_safeColorChannel = (color, warning) => {
|
||||
try {
|
||||
return colorChannel(color);
|
||||
} catch (error) {
|
||||
if (warning && process.env.NODE_ENV !== 'production') {
|
||||
console.warn(warning);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a color object with type and values to a string.
|
||||
* @param {object} color - Decomposed color
|
||||
* @param {string} color.type - One of: 'rgb', 'rgba', 'hsl', 'hsla', 'color'
|
||||
* @param {array} color.values - [n,n,n] or [n,n,n,n]
|
||||
* @returns {string} A CSS color string
|
||||
*/
|
||||
export function recomposeColor(color) {
|
||||
const {
|
||||
type,
|
||||
colorSpace
|
||||
} = color;
|
||||
let {
|
||||
values
|
||||
} = color;
|
||||
if (type.indexOf('rgb') !== -1) {
|
||||
// Only convert the first 3 values to int (i.e. not alpha)
|
||||
values = values.map((n, i) => i < 3 ? parseInt(n, 10) : n);
|
||||
} else if (type.indexOf('hsl') !== -1) {
|
||||
values[1] = `${values[1]}%`;
|
||||
values[2] = `${values[2]}%`;
|
||||
}
|
||||
if (type.indexOf('color') !== -1) {
|
||||
values = `${colorSpace} ${values.join(' ')}`;
|
||||
} else {
|
||||
values = `${values.join(', ')}`;
|
||||
}
|
||||
return `${type}(${values})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a color from CSS rgb format to CSS hex format.
|
||||
* @param {string} color - RGB color, i.e. rgb(n, n, n)
|
||||
* @returns {string} A CSS rgb color string, i.e. #nnnnnn
|
||||
*/
|
||||
export function rgbToHex(color) {
|
||||
// Idempotent
|
||||
if (color.indexOf('#') === 0) {
|
||||
return color;
|
||||
}
|
||||
const {
|
||||
values
|
||||
} = decomposeColor(color);
|
||||
return `#${values.map((n, i) => intToHex(i === 3 ? Math.round(255 * n) : n)).join('')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a color from hsl format to rgb format.
|
||||
* @param {string} color - HSL color values
|
||||
* @returns {string} rgb color values
|
||||
*/
|
||||
export function hslToRgb(color) {
|
||||
color = decomposeColor(color);
|
||||
const {
|
||||
values
|
||||
} = color;
|
||||
const h = values[0];
|
||||
const s = values[1] / 100;
|
||||
const l = values[2] / 100;
|
||||
const a = s * Math.min(l, 1 - l);
|
||||
const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||
let type = 'rgb';
|
||||
const rgb = [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];
|
||||
if (color.type === 'hsla') {
|
||||
type += 'a';
|
||||
rgb.push(values[3]);
|
||||
}
|
||||
return recomposeColor({
|
||||
type,
|
||||
values: rgb
|
||||
});
|
||||
}
|
||||
/**
|
||||
* The relative brightness of any point in a color space,
|
||||
* normalized to 0 for darkest black and 1 for lightest white.
|
||||
*
|
||||
* Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
||||
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @returns {number} The relative brightness of the color in the range 0 - 1
|
||||
*/
|
||||
export function getLuminance(color) {
|
||||
color = decomposeColor(color);
|
||||
let rgb = color.type === 'hsl' || color.type === 'hsla' ? decomposeColor(hslToRgb(color)).values : color.values;
|
||||
rgb = rgb.map(val => {
|
||||
if (color.type !== 'color') {
|
||||
val /= 255; // normalized
|
||||
}
|
||||
return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
|
||||
});
|
||||
|
||||
// Truncate at 3 digits
|
||||
return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the contrast ratio between two colors.
|
||||
*
|
||||
* Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
||||
* @param {string} foreground - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
|
||||
* @param {string} background - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
|
||||
* @returns {number} A contrast ratio value in the range 0 - 21.
|
||||
*/
|
||||
export function getContrastRatio(foreground, background) {
|
||||
const lumA = getLuminance(foreground);
|
||||
const lumB = getLuminance(background);
|
||||
return (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the absolute transparency of a color.
|
||||
* Any existing alpha values are overwritten.
|
||||
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @param {number} value - value to set the alpha channel to in the range 0 - 1
|
||||
* @returns {string} A CSS color string. Hex input values are returned as rgb
|
||||
*/
|
||||
export function alpha(color, value) {
|
||||
color = decomposeColor(color);
|
||||
value = clampWrapper(value);
|
||||
if (color.type === 'rgb' || color.type === 'hsl') {
|
||||
color.type += 'a';
|
||||
}
|
||||
if (color.type === 'color') {
|
||||
color.values[3] = `/${value}`;
|
||||
} else {
|
||||
color.values[3] = value;
|
||||
}
|
||||
return recomposeColor(color);
|
||||
}
|
||||
export function private_safeAlpha(color, value, warning) {
|
||||
try {
|
||||
return alpha(color, value);
|
||||
} catch (error) {
|
||||
if (warning && process.env.NODE_ENV !== 'production') {
|
||||
console.warn(warning);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Darkens a color.
|
||||
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @param {number} coefficient - multiplier in the range 0 - 1
|
||||
* @returns {string} A CSS color string. Hex input values are returned as rgb
|
||||
*/
|
||||
export function darken(color, coefficient) {
|
||||
color = decomposeColor(color);
|
||||
coefficient = clampWrapper(coefficient);
|
||||
if (color.type.indexOf('hsl') !== -1) {
|
||||
color.values[2] *= 1 - coefficient;
|
||||
} else if (color.type.indexOf('rgb') !== -1 || color.type.indexOf('color') !== -1) {
|
||||
for (let i = 0; i < 3; i += 1) {
|
||||
color.values[i] *= 1 - coefficient;
|
||||
}
|
||||
}
|
||||
return recomposeColor(color);
|
||||
}
|
||||
export function private_safeDarken(color, coefficient, warning) {
|
||||
try {
|
||||
return darken(color, coefficient);
|
||||
} catch (error) {
|
||||
if (warning && process.env.NODE_ENV !== 'production') {
|
||||
console.warn(warning);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lightens a color.
|
||||
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @param {number} coefficient - multiplier in the range 0 - 1
|
||||
* @returns {string} A CSS color string. Hex input values are returned as rgb
|
||||
*/
|
||||
export function lighten(color, coefficient) {
|
||||
color = decomposeColor(color);
|
||||
coefficient = clampWrapper(coefficient);
|
||||
if (color.type.indexOf('hsl') !== -1) {
|
||||
color.values[2] += (100 - color.values[2]) * coefficient;
|
||||
} else if (color.type.indexOf('rgb') !== -1) {
|
||||
for (let i = 0; i < 3; i += 1) {
|
||||
color.values[i] += (255 - color.values[i]) * coefficient;
|
||||
}
|
||||
} else if (color.type.indexOf('color') !== -1) {
|
||||
for (let i = 0; i < 3; i += 1) {
|
||||
color.values[i] += (1 - color.values[i]) * coefficient;
|
||||
}
|
||||
}
|
||||
return recomposeColor(color);
|
||||
}
|
||||
export function private_safeLighten(color, coefficient, warning) {
|
||||
try {
|
||||
return lighten(color, coefficient);
|
||||
} catch (error) {
|
||||
if (warning && process.env.NODE_ENV !== 'production') {
|
||||
console.warn(warning);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Darken or lighten a color, depending on its luminance.
|
||||
* Light colors are darkened, dark colors are lightened.
|
||||
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla(), color()
|
||||
* @param {number} coefficient=0.15 - multiplier in the range 0 - 1
|
||||
* @returns {string} A CSS color string. Hex input values are returned as rgb
|
||||
*/
|
||||
export function emphasize(color, coefficient = 0.15) {
|
||||
return getLuminance(color) > 0.5 ? darken(color, coefficient) : lighten(color, coefficient);
|
||||
}
|
||||
export function private_safeEmphasize(color, coefficient, warning) {
|
||||
try {
|
||||
return emphasize(color, coefficient);
|
||||
} catch (error) {
|
||||
if (warning && process.env.NODE_ENV !== 'production') {
|
||||
console.warn(warning);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blend a transparent overlay color with a background color, resulting in a single
|
||||
* RGB color.
|
||||
* @param {string} background - CSS color
|
||||
* @param {string} overlay - CSS color
|
||||
* @param {number} opacity - Opacity multiplier in the range 0 - 1
|
||||
* @param {number} [gamma=1.0] - Gamma correction factor. For gamma-correct blending, 2.2 is usual.
|
||||
*/
|
||||
export function blend(background, overlay, opacity, gamma = 1.0) {
|
||||
const blendChannel = (b, o) => Math.round((b ** (1 / gamma) * (1 - opacity) + o ** (1 / gamma) * opacity) ** gamma);
|
||||
const backgroundColor = decomposeColor(background);
|
||||
const overlayColor = decomposeColor(overlay);
|
||||
const rgb = [blendChannel(backgroundColor.values[0], overlayColor.values[0]), blendChannel(backgroundColor.values[1], overlayColor.values[1]), blendChannel(backgroundColor.values[2], overlayColor.values[2])];
|
||||
return recomposeColor({
|
||||
type: 'rgb',
|
||||
values: rgb
|
||||
});
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import merge from './merge';
|
||||
function compose(...styles) {
|
||||
const handlers = styles.reduce((acc, style) => {
|
||||
style.filterProps.forEach(prop => {
|
||||
acc[prop] = style;
|
||||
});
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// false positive
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
const fn = props => {
|
||||
return Object.keys(props).reduce((acc, prop) => {
|
||||
if (handlers[prop]) {
|
||||
return merge(acc, handlers[prop](props));
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
fn.propTypes = process.env.NODE_ENV !== 'production' ? styles.reduce((acc, style) => Object.assign(acc, style.propTypes), {}) : {};
|
||||
fn.filterProps = styles.reduce((acc, style) => acc.concat(style.filterProps), []);
|
||||
return fn;
|
||||
}
|
||||
export default compose;
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
||||
const _excluded = ["className", "component"];
|
||||
import * as React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import styled from '@mui/styled-engine';
|
||||
import styleFunctionSx, { extendSxProp } from './styleFunctionSx';
|
||||
import useTheme from './useTheme';
|
||||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
export default function createBox(options = {}) {
|
||||
const {
|
||||
themeId,
|
||||
defaultTheme,
|
||||
defaultClassName = 'MuiBox-root',
|
||||
generateClassName
|
||||
} = options;
|
||||
const BoxRoot = styled('div', {
|
||||
shouldForwardProp: prop => prop !== 'theme' && prop !== 'sx' && prop !== 'as'
|
||||
})(styleFunctionSx);
|
||||
const Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
|
||||
const theme = useTheme(defaultTheme);
|
||||
const _extendSxProp = extendSxProp(inProps),
|
||||
{
|
||||
className,
|
||||
component = 'div'
|
||||
} = _extendSxProp,
|
||||
other = _objectWithoutPropertiesLoose(_extendSxProp, _excluded);
|
||||
return /*#__PURE__*/_jsx(BoxRoot, _extends({
|
||||
as: component,
|
||||
ref: ref,
|
||||
className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
|
||||
theme: themeId ? theme[themeId] || theme : theme
|
||||
}, other));
|
||||
});
|
||||
return Box;
|
||||
}
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
||||
const _excluded = ["ownerState"],
|
||||
_excluded2 = ["variants"],
|
||||
_excluded3 = ["name", "slot", "skipVariantsResolver", "skipSx", "overridesResolver"];
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import styledEngineStyled, { internal_processStyles as processStyles } from '@mui/styled-engine';
|
||||
import { isPlainObject } from '@mui/utils/deepmerge';
|
||||
import capitalize from '@mui/utils/capitalize';
|
||||
import getDisplayName from '@mui/utils/getDisplayName';
|
||||
import createTheme from './createTheme';
|
||||
import styleFunctionSx from './styleFunctionSx';
|
||||
function isEmpty(obj) {
|
||||
return Object.keys(obj).length === 0;
|
||||
}
|
||||
|
||||
// https://github.com/emotion-js/emotion/blob/26ded6109fcd8ca9875cc2ce4564fee678a3f3c5/packages/styled/src/utils.js#L40
|
||||
function isStringTag(tag) {
|
||||
return typeof tag === 'string' &&
|
||||
// 96 is one less than the char code
|
||||
// for "a" so this is checking that
|
||||
// it's a lowercase character
|
||||
tag.charCodeAt(0) > 96;
|
||||
}
|
||||
|
||||
// Update /system/styled/#api in case if this changes
|
||||
export function shouldForwardProp(prop) {
|
||||
return prop !== 'ownerState' && prop !== 'theme' && prop !== 'sx' && prop !== 'as';
|
||||
}
|
||||
export const systemDefaultTheme = createTheme();
|
||||
const lowercaseFirstLetter = string => {
|
||||
if (!string) {
|
||||
return string;
|
||||
}
|
||||
return string.charAt(0).toLowerCase() + string.slice(1);
|
||||
};
|
||||
function resolveTheme({
|
||||
defaultTheme,
|
||||
theme,
|
||||
themeId
|
||||
}) {
|
||||
return isEmpty(theme) ? defaultTheme : theme[themeId] || theme;
|
||||
}
|
||||
function defaultOverridesResolver(slot) {
|
||||
if (!slot) {
|
||||
return null;
|
||||
}
|
||||
return (props, styles) => styles[slot];
|
||||
}
|
||||
function processStyleArg(callableStyle, _ref) {
|
||||
let {
|
||||
ownerState
|
||||
} = _ref,
|
||||
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
||||
const resolvedStylesArg = typeof callableStyle === 'function' ? callableStyle(_extends({
|
||||
ownerState
|
||||
}, props)) : callableStyle;
|
||||
if (Array.isArray(resolvedStylesArg)) {
|
||||
return resolvedStylesArg.flatMap(resolvedStyle => processStyleArg(resolvedStyle, _extends({
|
||||
ownerState
|
||||
}, props)));
|
||||
}
|
||||
if (!!resolvedStylesArg && typeof resolvedStylesArg === 'object' && Array.isArray(resolvedStylesArg.variants)) {
|
||||
const {
|
||||
variants = []
|
||||
} = resolvedStylesArg,
|
||||
otherStyles = _objectWithoutPropertiesLoose(resolvedStylesArg, _excluded2);
|
||||
let result = otherStyles;
|
||||
variants.forEach(variant => {
|
||||
let isMatch = true;
|
||||
if (typeof variant.props === 'function') {
|
||||
isMatch = variant.props(_extends({
|
||||
ownerState
|
||||
}, props, ownerState));
|
||||
} else {
|
||||
Object.keys(variant.props).forEach(key => {
|
||||
if ((ownerState == null ? void 0 : ownerState[key]) !== variant.props[key] && props[key] !== variant.props[key]) {
|
||||
isMatch = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (isMatch) {
|
||||
if (!Array.isArray(result)) {
|
||||
result = [result];
|
||||
}
|
||||
result.push(typeof variant.style === 'function' ? variant.style(_extends({
|
||||
ownerState
|
||||
}, props, ownerState)) : variant.style);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return resolvedStylesArg;
|
||||
}
|
||||
export default function createStyled(input = {}) {
|
||||
const {
|
||||
themeId,
|
||||
defaultTheme = systemDefaultTheme,
|
||||
rootShouldForwardProp = shouldForwardProp,
|
||||
slotShouldForwardProp = shouldForwardProp
|
||||
} = input;
|
||||
const systemSx = props => {
|
||||
return styleFunctionSx(_extends({}, props, {
|
||||
theme: resolveTheme(_extends({}, props, {
|
||||
defaultTheme,
|
||||
themeId
|
||||
}))
|
||||
}));
|
||||
};
|
||||
systemSx.__mui_systemSx = true;
|
||||
return (tag, inputOptions = {}) => {
|
||||
// Filter out the `sx` style function from the previous styled component to prevent unnecessary styles generated by the composite components.
|
||||
processStyles(tag, styles => styles.filter(style => !(style != null && style.__mui_systemSx)));
|
||||
const {
|
||||
name: componentName,
|
||||
slot: componentSlot,
|
||||
skipVariantsResolver: inputSkipVariantsResolver,
|
||||
skipSx: inputSkipSx,
|
||||
// TODO v6: remove `lowercaseFirstLetter()` in the next major release
|
||||
// For more details: https://github.com/mui/material-ui/pull/37908
|
||||
overridesResolver = defaultOverridesResolver(lowercaseFirstLetter(componentSlot))
|
||||
} = inputOptions,
|
||||
options = _objectWithoutPropertiesLoose(inputOptions, _excluded3);
|
||||
|
||||
// if skipVariantsResolver option is defined, take the value, otherwise, true for root and false for other slots.
|
||||
const skipVariantsResolver = inputSkipVariantsResolver !== undefined ? inputSkipVariantsResolver :
|
||||
// TODO v6: remove `Root` in the next major release
|
||||
// For more details: https://github.com/mui/material-ui/pull/37908
|
||||
componentSlot && componentSlot !== 'Root' && componentSlot !== 'root' || false;
|
||||
const skipSx = inputSkipSx || false;
|
||||
let label;
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (componentName) {
|
||||
// TODO v6: remove `lowercaseFirstLetter()` in the next major release
|
||||
// For more details: https://github.com/mui/material-ui/pull/37908
|
||||
label = `${componentName}-${lowercaseFirstLetter(componentSlot || 'Root')}`;
|
||||
}
|
||||
}
|
||||
let shouldForwardPropOption = shouldForwardProp;
|
||||
|
||||
// TODO v6: remove `Root` in the next major release
|
||||
// For more details: https://github.com/mui/material-ui/pull/37908
|
||||
if (componentSlot === 'Root' || componentSlot === 'root') {
|
||||
shouldForwardPropOption = rootShouldForwardProp;
|
||||
} else if (componentSlot) {
|
||||
// any other slot specified
|
||||
shouldForwardPropOption = slotShouldForwardProp;
|
||||
} else if (isStringTag(tag)) {
|
||||
// for string (html) tag, preserve the behavior in emotion & styled-components.
|
||||
shouldForwardPropOption = undefined;
|
||||
}
|
||||
const defaultStyledResolver = styledEngineStyled(tag, _extends({
|
||||
shouldForwardProp: shouldForwardPropOption,
|
||||
label
|
||||
}, options));
|
||||
const transformStyleArg = stylesArg => {
|
||||
// On the server Emotion doesn't use React.forwardRef for creating components, so the created
|
||||
// component stays as a function. This condition makes sure that we do not interpolate functions
|
||||
// which are basically components used as a selectors.
|
||||
if (typeof stylesArg === 'function' && stylesArg.__emotion_real !== stylesArg || isPlainObject(stylesArg)) {
|
||||
return props => processStyleArg(stylesArg, _extends({}, props, {
|
||||
theme: resolveTheme({
|
||||
theme: props.theme,
|
||||
defaultTheme,
|
||||
themeId
|
||||
})
|
||||
}));
|
||||
}
|
||||
return stylesArg;
|
||||
};
|
||||
const muiStyledResolver = (styleArg, ...expressions) => {
|
||||
let transformedStyleArg = transformStyleArg(styleArg);
|
||||
const expressionsWithDefaultTheme = expressions ? expressions.map(transformStyleArg) : [];
|
||||
if (componentName && overridesResolver) {
|
||||
expressionsWithDefaultTheme.push(props => {
|
||||
const theme = resolveTheme(_extends({}, props, {
|
||||
defaultTheme,
|
||||
themeId
|
||||
}));
|
||||
if (!theme.components || !theme.components[componentName] || !theme.components[componentName].styleOverrides) {
|
||||
return null;
|
||||
}
|
||||
const styleOverrides = theme.components[componentName].styleOverrides;
|
||||
const resolvedStyleOverrides = {};
|
||||
// TODO: v7 remove iteration and use `resolveStyleArg(styleOverrides[slot])` directly
|
||||
Object.entries(styleOverrides).forEach(([slotKey, slotStyle]) => {
|
||||
resolvedStyleOverrides[slotKey] = processStyleArg(slotStyle, _extends({}, props, {
|
||||
theme
|
||||
}));
|
||||
});
|
||||
return overridesResolver(props, resolvedStyleOverrides);
|
||||
});
|
||||
}
|
||||
if (componentName && !skipVariantsResolver) {
|
||||
expressionsWithDefaultTheme.push(props => {
|
||||
var _theme$components;
|
||||
const theme = resolveTheme(_extends({}, props, {
|
||||
defaultTheme,
|
||||
themeId
|
||||
}));
|
||||
const themeVariants = theme == null || (_theme$components = theme.components) == null || (_theme$components = _theme$components[componentName]) == null ? void 0 : _theme$components.variants;
|
||||
return processStyleArg({
|
||||
variants: themeVariants
|
||||
}, _extends({}, props, {
|
||||
theme
|
||||
}));
|
||||
});
|
||||
}
|
||||
if (!skipSx) {
|
||||
expressionsWithDefaultTheme.push(systemSx);
|
||||
}
|
||||
const numOfCustomFnsApplied = expressionsWithDefaultTheme.length - expressions.length;
|
||||
if (Array.isArray(styleArg) && numOfCustomFnsApplied > 0) {
|
||||
const placeholders = new Array(numOfCustomFnsApplied).fill('');
|
||||
// If the type is array, than we need to add placeholders in the template for the overrides, variants and the sx styles.
|
||||
transformedStyleArg = [...styleArg, ...placeholders];
|
||||
transformedStyleArg.raw = [...styleArg.raw, ...placeholders];
|
||||
}
|
||||
const Component = defaultStyledResolver(transformedStyleArg, ...expressionsWithDefaultTheme);
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
let displayName;
|
||||
if (componentName) {
|
||||
displayName = `${componentName}${capitalize(componentSlot || '')}`;
|
||||
}
|
||||
if (displayName === undefined) {
|
||||
displayName = `Styled(${getDisplayName(tag)})`;
|
||||
}
|
||||
Component.displayName = displayName;
|
||||
}
|
||||
if (tag.muiName) {
|
||||
Component.muiName = tag.muiName;
|
||||
}
|
||||
return Component;
|
||||
};
|
||||
if (defaultStyledResolver.withConfig) {
|
||||
muiStyledResolver.withConfig = defaultStyledResolver.withConfig;
|
||||
}
|
||||
return muiStyledResolver;
|
||||
};
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* A universal utility to style components with multiple color modes. Always use it from the theme object.
|
||||
* It works with:
|
||||
* - [Basic theme](https://mui.com/material-ui/customization/dark-mode/)
|
||||
* - [CSS theme variables](https://mui.com/material-ui/experimental-api/css-theme-variables/overview/)
|
||||
* - Zero-runtime engine
|
||||
*
|
||||
* Tips: Use an array over object spread and place `theme.applyStyles()` last.
|
||||
*
|
||||
* ✅ [{ background: '#e5e5e5' }, theme.applyStyles('dark', { background: '#1c1c1c' })]
|
||||
*
|
||||
* 🚫 { background: '#e5e5e5', ...theme.applyStyles('dark', { background: '#1c1c1c' })}
|
||||
*
|
||||
* @example
|
||||
* 1. using with `styled`:
|
||||
* ```jsx
|
||||
* const Component = styled('div')(({ theme }) => [
|
||||
* { background: '#e5e5e5' },
|
||||
* theme.applyStyles('dark', {
|
||||
* background: '#1c1c1c',
|
||||
* color: '#fff',
|
||||
* }),
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* 2. using with `sx` prop:
|
||||
* ```jsx
|
||||
* <Box sx={theme => [
|
||||
* { background: '#e5e5e5' },
|
||||
* theme.applyStyles('dark', {
|
||||
* background: '#1c1c1c',
|
||||
* color: '#fff',
|
||||
* }),
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* 3. theming a component:
|
||||
* ```jsx
|
||||
* extendTheme({
|
||||
* components: {
|
||||
* MuiButton: {
|
||||
* styleOverrides: {
|
||||
* root: ({ theme }) => [
|
||||
* { background: '#e5e5e5' },
|
||||
* theme.applyStyles('dark', {
|
||||
* background: '#1c1c1c',
|
||||
* color: '#fff',
|
||||
* }),
|
||||
* ],
|
||||
* },
|
||||
* }
|
||||
* }
|
||||
* })
|
||||
*```
|
||||
*/
|
||||
export default function applyStyles(key, styles) {
|
||||
// @ts-expect-error this is 'any' type
|
||||
const theme = this;
|
||||
if (theme.vars && typeof theme.getColorSchemeSelector === 'function') {
|
||||
// If CssVarsProvider is used as a provider,
|
||||
// returns '* :where([data-mui-color-scheme="light|dark"]) &'
|
||||
const selector = theme.getColorSchemeSelector(key).replace(/(\[[^\]]+\])/, '*:where($1)');
|
||||
return {
|
||||
[selector]: styles
|
||||
};
|
||||
}
|
||||
if (theme.palette.mode === key) {
|
||||
return styles;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
const _excluded = ["values", "unit", "step"];
|
||||
// Sorted ASC by size. That's important.
|
||||
// It can't be configured as it's used statically for propTypes.
|
||||
export const breakpointKeys = ['xs', 'sm', 'md', 'lg', 'xl'];
|
||||
const sortBreakpointsValues = values => {
|
||||
const breakpointsAsArray = Object.keys(values).map(key => ({
|
||||
key,
|
||||
val: values[key]
|
||||
})) || [];
|
||||
// Sort in ascending order
|
||||
breakpointsAsArray.sort((breakpoint1, breakpoint2) => breakpoint1.val - breakpoint2.val);
|
||||
return breakpointsAsArray.reduce((acc, obj) => {
|
||||
return _extends({}, acc, {
|
||||
[obj.key]: obj.val
|
||||
});
|
||||
}, {});
|
||||
};
|
||||
|
||||
// Keep in mind that @media is inclusive by the CSS specification.
|
||||
export default function createBreakpoints(breakpoints) {
|
||||
const {
|
||||
// The breakpoint **start** at this value.
|
||||
// For instance with the first breakpoint xs: [xs, sm).
|
||||
values = {
|
||||
xs: 0,
|
||||
// phone
|
||||
sm: 600,
|
||||
// tablet
|
||||
md: 900,
|
||||
// small laptop
|
||||
lg: 1200,
|
||||
// desktop
|
||||
xl: 1536 // large screen
|
||||
},
|
||||
unit = 'px',
|
||||
step = 5
|
||||
} = breakpoints,
|
||||
other = _objectWithoutPropertiesLoose(breakpoints, _excluded);
|
||||
const sortedValues = sortBreakpointsValues(values);
|
||||
const keys = Object.keys(sortedValues);
|
||||
function up(key) {
|
||||
const value = typeof values[key] === 'number' ? values[key] : key;
|
||||
return `@media (min-width:${value}${unit})`;
|
||||
}
|
||||
function down(key) {
|
||||
const value = typeof values[key] === 'number' ? values[key] : key;
|
||||
return `@media (max-width:${value - step / 100}${unit})`;
|
||||
}
|
||||
function between(start, end) {
|
||||
const endIndex = keys.indexOf(end);
|
||||
return `@media (min-width:${typeof values[start] === 'number' ? values[start] : start}${unit}) and ` + `(max-width:${(endIndex !== -1 && typeof values[keys[endIndex]] === 'number' ? values[keys[endIndex]] : end) - step / 100}${unit})`;
|
||||
}
|
||||
function only(key) {
|
||||
if (keys.indexOf(key) + 1 < keys.length) {
|
||||
return between(key, keys[keys.indexOf(key) + 1]);
|
||||
}
|
||||
return up(key);
|
||||
}
|
||||
function not(key) {
|
||||
// handle first and last key separately, for better readability
|
||||
const keyIndex = keys.indexOf(key);
|
||||
if (keyIndex === 0) {
|
||||
return up(keys[1]);
|
||||
}
|
||||
if (keyIndex === keys.length - 1) {
|
||||
return down(keys[keyIndex]);
|
||||
}
|
||||
return between(key, keys[keys.indexOf(key) + 1]).replace('@media', '@media not all and');
|
||||
}
|
||||
return _extends({
|
||||
keys,
|
||||
values: sortedValues,
|
||||
up,
|
||||
down,
|
||||
between,
|
||||
only,
|
||||
not,
|
||||
unit
|
||||
}, other);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { createUnarySpacing } from '../spacing';
|
||||
|
||||
// The different signatures imply different meaning for their arguments that can't be expressed structurally.
|
||||
// We express the difference with variable names.
|
||||
|
||||
export default function createSpacing(spacingInput = 8) {
|
||||
// Already transformed.
|
||||
if (spacingInput.mui) {
|
||||
return spacingInput;
|
||||
}
|
||||
|
||||
// Material Design layouts are visually balanced. Most measurements align to an 8dp grid, which aligns both spacing and the overall layout.
|
||||
// Smaller components, such as icons, can align to a 4dp grid.
|
||||
// https://m2.material.io/design/layout/understanding-layout.html
|
||||
const transform = createUnarySpacing({
|
||||
spacing: spacingInput
|
||||
});
|
||||
const spacing = (...argsInput) => {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!(argsInput.length <= 4)) {
|
||||
console.error(`MUI: Too many arguments provided, expected between 0 and 4, got ${argsInput.length}`);
|
||||
}
|
||||
}
|
||||
const args = argsInput.length === 0 ? [1] : argsInput;
|
||||
return args.map(argument => {
|
||||
const output = transform(argument);
|
||||
return typeof output === 'number' ? `${output}px` : output;
|
||||
}).join(' ');
|
||||
};
|
||||
spacing.mui = true;
|
||||
return spacing;
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
||||
const _excluded = ["breakpoints", "palette", "spacing", "shape"];
|
||||
import deepmerge from '@mui/utils/deepmerge';
|
||||
import createBreakpoints from './createBreakpoints';
|
||||
import shape from './shape';
|
||||
import createSpacing from './createSpacing';
|
||||
import styleFunctionSx from '../styleFunctionSx/styleFunctionSx';
|
||||
import defaultSxConfig from '../styleFunctionSx/defaultSxConfig';
|
||||
import applyStyles from './applyStyles';
|
||||
function createTheme(options = {}, ...args) {
|
||||
const {
|
||||
breakpoints: breakpointsInput = {},
|
||||
palette: paletteInput = {},
|
||||
spacing: spacingInput,
|
||||
shape: shapeInput = {}
|
||||
} = options,
|
||||
other = _objectWithoutPropertiesLoose(options, _excluded);
|
||||
const breakpoints = createBreakpoints(breakpointsInput);
|
||||
const spacing = createSpacing(spacingInput);
|
||||
let muiTheme = deepmerge({
|
||||
breakpoints,
|
||||
direction: 'ltr',
|
||||
components: {},
|
||||
// Inject component definitions.
|
||||
palette: _extends({
|
||||
mode: 'light'
|
||||
}, paletteInput),
|
||||
spacing,
|
||||
shape: _extends({}, shape, shapeInput)
|
||||
}, other);
|
||||
muiTheme.applyStyles = applyStyles;
|
||||
muiTheme = args.reduce((acc, argument) => deepmerge(acc, argument), muiTheme);
|
||||
muiTheme.unstable_sxConfig = _extends({}, defaultSxConfig, other == null ? void 0 : other.unstable_sxConfig);
|
||||
muiTheme.unstable_sx = function sx(props) {
|
||||
return styleFunctionSx({
|
||||
sx: props,
|
||||
theme: this
|
||||
});
|
||||
};
|
||||
return muiTheme;
|
||||
}
|
||||
export default createTheme;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
const shape = {
|
||||
borderRadius: 4
|
||||
};
|
||||
export default shape;
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
import style from './style';
|
||||
import compose from './compose';
|
||||
import { createUnaryUnit, getValue } from './spacing';
|
||||
import { handleBreakpoints } from './breakpoints';
|
||||
import responsivePropType from './responsivePropType';
|
||||
|
||||
// false positive
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
export const gap = props => {
|
||||
if (props.gap !== undefined && props.gap !== null) {
|
||||
const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'gap');
|
||||
const styleFromPropValue = propValue => ({
|
||||
gap: getValue(transformer, propValue)
|
||||
});
|
||||
return handleBreakpoints(props, props.gap, styleFromPropValue);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
gap.propTypes = process.env.NODE_ENV !== 'production' ? {
|
||||
gap: responsivePropType
|
||||
} : {};
|
||||
gap.filterProps = ['gap'];
|
||||
|
||||
// false positive
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
export const columnGap = props => {
|
||||
if (props.columnGap !== undefined && props.columnGap !== null) {
|
||||
const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'columnGap');
|
||||
const styleFromPropValue = propValue => ({
|
||||
columnGap: getValue(transformer, propValue)
|
||||
});
|
||||
return handleBreakpoints(props, props.columnGap, styleFromPropValue);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
columnGap.propTypes = process.env.NODE_ENV !== 'production' ? {
|
||||
columnGap: responsivePropType
|
||||
} : {};
|
||||
columnGap.filterProps = ['columnGap'];
|
||||
|
||||
// false positive
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
export const rowGap = props => {
|
||||
if (props.rowGap !== undefined && props.rowGap !== null) {
|
||||
const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'rowGap');
|
||||
const styleFromPropValue = propValue => ({
|
||||
rowGap: getValue(transformer, propValue)
|
||||
});
|
||||
return handleBreakpoints(props, props.rowGap, styleFromPropValue);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
rowGap.propTypes = process.env.NODE_ENV !== 'production' ? {
|
||||
rowGap: responsivePropType
|
||||
} : {};
|
||||
rowGap.filterProps = ['rowGap'];
|
||||
export const gridColumn = style({
|
||||
prop: 'gridColumn'
|
||||
});
|
||||
export const gridRow = style({
|
||||
prop: 'gridRow'
|
||||
});
|
||||
export const gridAutoFlow = style({
|
||||
prop: 'gridAutoFlow'
|
||||
});
|
||||
export const gridAutoColumns = style({
|
||||
prop: 'gridAutoColumns'
|
||||
});
|
||||
export const gridAutoRows = style({
|
||||
prop: 'gridAutoRows'
|
||||
});
|
||||
export const gridTemplateColumns = style({
|
||||
prop: 'gridTemplateColumns'
|
||||
});
|
||||
export const gridTemplateRows = style({
|
||||
prop: 'gridTemplateRows'
|
||||
});
|
||||
export const gridTemplateAreas = style({
|
||||
prop: 'gridTemplateAreas'
|
||||
});
|
||||
export const gridArea = style({
|
||||
prop: 'gridArea'
|
||||
});
|
||||
const grid = compose(gap, columnGap, rowGap, gridColumn, gridRow, gridAutoFlow, gridAutoColumns, gridAutoRows, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridArea);
|
||||
export default grid;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
export default function memoize(fn) {
|
||||
const cache = {};
|
||||
return arg => {
|
||||
if (cache[arg] === undefined) {
|
||||
cache[arg] = fn(arg);
|
||||
}
|
||||
return cache[arg];
|
||||
};
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import deepmerge from '@mui/utils/deepmerge';
|
||||
function merge(acc, item) {
|
||||
if (!item) {
|
||||
return acc;
|
||||
}
|
||||
return deepmerge(acc, item, {
|
||||
clone: false // No need to clone deep, it's way faster.
|
||||
});
|
||||
}
|
||||
export default merge;
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import style from './style';
|
||||
import compose from './compose';
|
||||
export function paletteTransform(value, userValue) {
|
||||
if (userValue === 'grey') {
|
||||
return userValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
export const color = style({
|
||||
prop: 'color',
|
||||
themeKey: 'palette',
|
||||
transform: paletteTransform
|
||||
});
|
||||
export const bgcolor = style({
|
||||
prop: 'bgcolor',
|
||||
cssProperty: 'backgroundColor',
|
||||
themeKey: 'palette',
|
||||
transform: paletteTransform
|
||||
});
|
||||
export const backgroundColor = style({
|
||||
prop: 'backgroundColor',
|
||||
themeKey: 'palette',
|
||||
transform: paletteTransform
|
||||
});
|
||||
const palette = compose(color, bgcolor, backgroundColor);
|
||||
export default palette;
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import style from './style';
|
||||
import compose from './compose';
|
||||
import { handleBreakpoints, values as breakpointsValues } from './breakpoints';
|
||||
export function sizingTransform(value) {
|
||||
return value <= 1 && value !== 0 ? `${value * 100}%` : value;
|
||||
}
|
||||
export const width = style({
|
||||
prop: 'width',
|
||||
transform: sizingTransform
|
||||
});
|
||||
export const maxWidth = props => {
|
||||
if (props.maxWidth !== undefined && props.maxWidth !== null) {
|
||||
const styleFromPropValue = propValue => {
|
||||
var _props$theme, _props$theme2;
|
||||
const breakpoint = ((_props$theme = props.theme) == null || (_props$theme = _props$theme.breakpoints) == null || (_props$theme = _props$theme.values) == null ? void 0 : _props$theme[propValue]) || breakpointsValues[propValue];
|
||||
if (!breakpoint) {
|
||||
return {
|
||||
maxWidth: sizingTransform(propValue)
|
||||
};
|
||||
}
|
||||
if (((_props$theme2 = props.theme) == null || (_props$theme2 = _props$theme2.breakpoints) == null ? void 0 : _props$theme2.unit) !== 'px') {
|
||||
return {
|
||||
maxWidth: `${breakpoint}${props.theme.breakpoints.unit}`
|
||||
};
|
||||
}
|
||||
return {
|
||||
maxWidth: breakpoint
|
||||
};
|
||||
};
|
||||
return handleBreakpoints(props, props.maxWidth, styleFromPropValue);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
maxWidth.filterProps = ['maxWidth'];
|
||||
export const minWidth = style({
|
||||
prop: 'minWidth',
|
||||
transform: sizingTransform
|
||||
});
|
||||
export const height = style({
|
||||
prop: 'height',
|
||||
transform: sizingTransform
|
||||
});
|
||||
export const maxHeight = style({
|
||||
prop: 'maxHeight',
|
||||
transform: sizingTransform
|
||||
});
|
||||
export const minHeight = style({
|
||||
prop: 'minHeight',
|
||||
transform: sizingTransform
|
||||
});
|
||||
export const sizeWidth = style({
|
||||
prop: 'size',
|
||||
cssProperty: 'width',
|
||||
transform: sizingTransform
|
||||
});
|
||||
export const sizeHeight = style({
|
||||
prop: 'size',
|
||||
cssProperty: 'height',
|
||||
transform: sizingTransform
|
||||
});
|
||||
export const boxSizing = style({
|
||||
prop: 'boxSizing'
|
||||
});
|
||||
const sizing = compose(width, maxWidth, minWidth, height, maxHeight, minHeight, boxSizing);
|
||||
export default sizing;
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
import responsivePropType from './responsivePropType';
|
||||
import { handleBreakpoints } from './breakpoints';
|
||||
import { getPath } from './style';
|
||||
import merge from './merge';
|
||||
import memoize from './memoize';
|
||||
const properties = {
|
||||
m: 'margin',
|
||||
p: 'padding'
|
||||
};
|
||||
const directions = {
|
||||
t: 'Top',
|
||||
r: 'Right',
|
||||
b: 'Bottom',
|
||||
l: 'Left',
|
||||
x: ['Left', 'Right'],
|
||||
y: ['Top', 'Bottom']
|
||||
};
|
||||
const aliases = {
|
||||
marginX: 'mx',
|
||||
marginY: 'my',
|
||||
paddingX: 'px',
|
||||
paddingY: 'py'
|
||||
};
|
||||
|
||||
// memoize() impact:
|
||||
// From 300,000 ops/sec
|
||||
// To 350,000 ops/sec
|
||||
const getCssProperties = memoize(prop => {
|
||||
// It's not a shorthand notation.
|
||||
if (prop.length > 2) {
|
||||
if (aliases[prop]) {
|
||||
prop = aliases[prop];
|
||||
} else {
|
||||
return [prop];
|
||||
}
|
||||
}
|
||||
const [a, b] = prop.split('');
|
||||
const property = properties[a];
|
||||
const direction = directions[b] || '';
|
||||
return Array.isArray(direction) ? direction.map(dir => property + dir) : [property + direction];
|
||||
});
|
||||
export const marginKeys = ['m', 'mt', 'mr', 'mb', 'ml', 'mx', 'my', 'margin', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'marginX', 'marginY', 'marginInline', 'marginInlineStart', 'marginInlineEnd', 'marginBlock', 'marginBlockStart', 'marginBlockEnd'];
|
||||
export const paddingKeys = ['p', 'pt', 'pr', 'pb', 'pl', 'px', 'py', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'paddingX', 'paddingY', 'paddingInline', 'paddingInlineStart', 'paddingInlineEnd', 'paddingBlock', 'paddingBlockStart', 'paddingBlockEnd'];
|
||||
const spacingKeys = [...marginKeys, ...paddingKeys];
|
||||
export function createUnaryUnit(theme, themeKey, defaultValue, propName) {
|
||||
var _getPath;
|
||||
const themeSpacing = (_getPath = getPath(theme, themeKey, false)) != null ? _getPath : defaultValue;
|
||||
if (typeof themeSpacing === 'number') {
|
||||
return abs => {
|
||||
if (typeof abs === 'string') {
|
||||
return abs;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (typeof abs !== 'number') {
|
||||
console.error(`MUI: Expected ${propName} argument to be a number or a string, got ${abs}.`);
|
||||
}
|
||||
}
|
||||
return themeSpacing * abs;
|
||||
};
|
||||
}
|
||||
if (Array.isArray(themeSpacing)) {
|
||||
return abs => {
|
||||
if (typeof abs === 'string') {
|
||||
return abs;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!Number.isInteger(abs)) {
|
||||
console.error([`MUI: The \`theme.${themeKey}\` array type cannot be combined with non integer values.` + `You should either use an integer value that can be used as index, or define the \`theme.${themeKey}\` as a number.`].join('\n'));
|
||||
} else if (abs > themeSpacing.length - 1) {
|
||||
console.error([`MUI: The value provided (${abs}) overflows.`, `The supported values are: ${JSON.stringify(themeSpacing)}.`, `${abs} > ${themeSpacing.length - 1}, you need to add the missing values.`].join('\n'));
|
||||
}
|
||||
}
|
||||
return themeSpacing[abs];
|
||||
};
|
||||
}
|
||||
if (typeof themeSpacing === 'function') {
|
||||
return themeSpacing;
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
console.error([`MUI: The \`theme.${themeKey}\` value (${themeSpacing}) is invalid.`, 'It should be a number, an array or a function.'].join('\n'));
|
||||
}
|
||||
return () => undefined;
|
||||
}
|
||||
export function createUnarySpacing(theme) {
|
||||
return createUnaryUnit(theme, 'spacing', 8, 'spacing');
|
||||
}
|
||||
export function getValue(transformer, propValue) {
|
||||
if (typeof propValue === 'string' || propValue == null) {
|
||||
return propValue;
|
||||
}
|
||||
const abs = Math.abs(propValue);
|
||||
const transformed = transformer(abs);
|
||||
if (propValue >= 0) {
|
||||
return transformed;
|
||||
}
|
||||
if (typeof transformed === 'number') {
|
||||
return -transformed;
|
||||
}
|
||||
return `-${transformed}`;
|
||||
}
|
||||
export function getStyleFromPropValue(cssProperties, transformer) {
|
||||
return propValue => cssProperties.reduce((acc, cssProperty) => {
|
||||
acc[cssProperty] = getValue(transformer, propValue);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
function resolveCssProperty(props, keys, prop, transformer) {
|
||||
// Using a hash computation over an array iteration could be faster, but with only 28 items,
|
||||
// it's doesn't worth the bundle size.
|
||||
if (keys.indexOf(prop) === -1) {
|
||||
return null;
|
||||
}
|
||||
const cssProperties = getCssProperties(prop);
|
||||
const styleFromPropValue = getStyleFromPropValue(cssProperties, transformer);
|
||||
const propValue = props[prop];
|
||||
return handleBreakpoints(props, propValue, styleFromPropValue);
|
||||
}
|
||||
function style(props, keys) {
|
||||
const transformer = createUnarySpacing(props.theme);
|
||||
return Object.keys(props).map(prop => resolveCssProperty(props, keys, prop, transformer)).reduce(merge, {});
|
||||
}
|
||||
export function margin(props) {
|
||||
return style(props, marginKeys);
|
||||
}
|
||||
margin.propTypes = process.env.NODE_ENV !== 'production' ? marginKeys.reduce((obj, key) => {
|
||||
obj[key] = responsivePropType;
|
||||
return obj;
|
||||
}, {}) : {};
|
||||
margin.filterProps = marginKeys;
|
||||
export function padding(props) {
|
||||
return style(props, paddingKeys);
|
||||
}
|
||||
padding.propTypes = process.env.NODE_ENV !== 'production' ? paddingKeys.reduce((obj, key) => {
|
||||
obj[key] = responsivePropType;
|
||||
return obj;
|
||||
}, {}) : {};
|
||||
padding.filterProps = paddingKeys;
|
||||
function spacing(props) {
|
||||
return style(props, spacingKeys);
|
||||
}
|
||||
spacing.propTypes = process.env.NODE_ENV !== 'production' ? spacingKeys.reduce((obj, key) => {
|
||||
obj[key] = responsivePropType;
|
||||
return obj;
|
||||
}, {}) : {};
|
||||
spacing.filterProps = spacingKeys;
|
||||
export default spacing;
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import capitalize from '@mui/utils/capitalize';
|
||||
import responsivePropType from './responsivePropType';
|
||||
import { handleBreakpoints } from './breakpoints';
|
||||
export function getPath(obj, path, checkVars = true) {
|
||||
if (!path || typeof path !== 'string') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if CSS variables are used
|
||||
if (obj && obj.vars && checkVars) {
|
||||
const val = `vars.${path}`.split('.').reduce((acc, item) => acc && acc[item] ? acc[item] : null, obj);
|
||||
if (val != null) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return path.split('.').reduce((acc, item) => {
|
||||
if (acc && acc[item] != null) {
|
||||
return acc[item];
|
||||
}
|
||||
return null;
|
||||
}, obj);
|
||||
}
|
||||
export function getStyleValue(themeMapping, transform, propValueFinal, userValue = propValueFinal) {
|
||||
let value;
|
||||
if (typeof themeMapping === 'function') {
|
||||
value = themeMapping(propValueFinal);
|
||||
} else if (Array.isArray(themeMapping)) {
|
||||
value = themeMapping[propValueFinal] || userValue;
|
||||
} else {
|
||||
value = getPath(themeMapping, propValueFinal) || userValue;
|
||||
}
|
||||
if (transform) {
|
||||
value = transform(value, userValue, themeMapping);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function style(options) {
|
||||
const {
|
||||
prop,
|
||||
cssProperty = options.prop,
|
||||
themeKey,
|
||||
transform
|
||||
} = options;
|
||||
|
||||
// false positive
|
||||
// eslint-disable-next-line react/function-component-definition
|
||||
const fn = props => {
|
||||
if (props[prop] == null) {
|
||||
return null;
|
||||
}
|
||||
const propValue = props[prop];
|
||||
const theme = props.theme;
|
||||
const themeMapping = getPath(theme, themeKey) || {};
|
||||
const styleFromPropValue = propValueFinal => {
|
||||
let value = getStyleValue(themeMapping, transform, propValueFinal);
|
||||
if (propValueFinal === value && typeof propValueFinal === 'string') {
|
||||
// Haven't found value
|
||||
value = getStyleValue(themeMapping, transform, `${prop}${propValueFinal === 'default' ? '' : capitalize(propValueFinal)}`, propValueFinal);
|
||||
}
|
||||
if (cssProperty === false) {
|
||||
return value;
|
||||
}
|
||||
return {
|
||||
[cssProperty]: value
|
||||
};
|
||||
};
|
||||
return handleBreakpoints(props, propValue, styleFromPropValue);
|
||||
};
|
||||
fn.propTypes = process.env.NODE_ENV !== 'production' ? {
|
||||
[prop]: responsivePropType
|
||||
} : {};
|
||||
fn.filterProps = [prop];
|
||||
return fn;
|
||||
}
|
||||
export default style;
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
import { padding, margin } from '../spacing';
|
||||
import { borderRadius, borderTransform } from '../borders';
|
||||
import { gap, rowGap, columnGap } from '../cssGrid';
|
||||
import { paletteTransform } from '../palette';
|
||||
import { maxWidth, sizingTransform } from '../sizing';
|
||||
const defaultSxConfig = {
|
||||
// borders
|
||||
border: {
|
||||
themeKey: 'borders',
|
||||
transform: borderTransform
|
||||
},
|
||||
borderTop: {
|
||||
themeKey: 'borders',
|
||||
transform: borderTransform
|
||||
},
|
||||
borderRight: {
|
||||
themeKey: 'borders',
|
||||
transform: borderTransform
|
||||
},
|
||||
borderBottom: {
|
||||
themeKey: 'borders',
|
||||
transform: borderTransform
|
||||
},
|
||||
borderLeft: {
|
||||
themeKey: 'borders',
|
||||
transform: borderTransform
|
||||
},
|
||||
borderColor: {
|
||||
themeKey: 'palette'
|
||||
},
|
||||
borderTopColor: {
|
||||
themeKey: 'palette'
|
||||
},
|
||||
borderRightColor: {
|
||||
themeKey: 'palette'
|
||||
},
|
||||
borderBottomColor: {
|
||||
themeKey: 'palette'
|
||||
},
|
||||
borderLeftColor: {
|
||||
themeKey: 'palette'
|
||||
},
|
||||
outline: {
|
||||
themeKey: 'borders',
|
||||
transform: borderTransform
|
||||
},
|
||||
outlineColor: {
|
||||
themeKey: 'palette'
|
||||
},
|
||||
borderRadius: {
|
||||
themeKey: 'shape.borderRadius',
|
||||
style: borderRadius
|
||||
},
|
||||
// palette
|
||||
color: {
|
||||
themeKey: 'palette',
|
||||
transform: paletteTransform
|
||||
},
|
||||
bgcolor: {
|
||||
themeKey: 'palette',
|
||||
cssProperty: 'backgroundColor',
|
||||
transform: paletteTransform
|
||||
},
|
||||
backgroundColor: {
|
||||
themeKey: 'palette',
|
||||
transform: paletteTransform
|
||||
},
|
||||
// spacing
|
||||
p: {
|
||||
style: padding
|
||||
},
|
||||
pt: {
|
||||
style: padding
|
||||
},
|
||||
pr: {
|
||||
style: padding
|
||||
},
|
||||
pb: {
|
||||
style: padding
|
||||
},
|
||||
pl: {
|
||||
style: padding
|
||||
},
|
||||
px: {
|
||||
style: padding
|
||||
},
|
||||
py: {
|
||||
style: padding
|
||||
},
|
||||
padding: {
|
||||
style: padding
|
||||
},
|
||||
paddingTop: {
|
||||
style: padding
|
||||
},
|
||||
paddingRight: {
|
||||
style: padding
|
||||
},
|
||||
paddingBottom: {
|
||||
style: padding
|
||||
},
|
||||
paddingLeft: {
|
||||
style: padding
|
||||
},
|
||||
paddingX: {
|
||||
style: padding
|
||||
},
|
||||
paddingY: {
|
||||
style: padding
|
||||
},
|
||||
paddingInline: {
|
||||
style: padding
|
||||
},
|
||||
paddingInlineStart: {
|
||||
style: padding
|
||||
},
|
||||
paddingInlineEnd: {
|
||||
style: padding
|
||||
},
|
||||
paddingBlock: {
|
||||
style: padding
|
||||
},
|
||||
paddingBlockStart: {
|
||||
style: padding
|
||||
},
|
||||
paddingBlockEnd: {
|
||||
style: padding
|
||||
},
|
||||
m: {
|
||||
style: margin
|
||||
},
|
||||
mt: {
|
||||
style: margin
|
||||
},
|
||||
mr: {
|
||||
style: margin
|
||||
},
|
||||
mb: {
|
||||
style: margin
|
||||
},
|
||||
ml: {
|
||||
style: margin
|
||||
},
|
||||
mx: {
|
||||
style: margin
|
||||
},
|
||||
my: {
|
||||
style: margin
|
||||
},
|
||||
margin: {
|
||||
style: margin
|
||||
},
|
||||
marginTop: {
|
||||
style: margin
|
||||
},
|
||||
marginRight: {
|
||||
style: margin
|
||||
},
|
||||
marginBottom: {
|
||||
style: margin
|
||||
},
|
||||
marginLeft: {
|
||||
style: margin
|
||||
},
|
||||
marginX: {
|
||||
style: margin
|
||||
},
|
||||
marginY: {
|
||||
style: margin
|
||||
},
|
||||
marginInline: {
|
||||
style: margin
|
||||
},
|
||||
marginInlineStart: {
|
||||
style: margin
|
||||
},
|
||||
marginInlineEnd: {
|
||||
style: margin
|
||||
},
|
||||
marginBlock: {
|
||||
style: margin
|
||||
},
|
||||
marginBlockStart: {
|
||||
style: margin
|
||||
},
|
||||
marginBlockEnd: {
|
||||
style: margin
|
||||
},
|
||||
// display
|
||||
displayPrint: {
|
||||
cssProperty: false,
|
||||
transform: value => ({
|
||||
'@media print': {
|
||||
display: value
|
||||
}
|
||||
})
|
||||
},
|
||||
display: {},
|
||||
overflow: {},
|
||||
textOverflow: {},
|
||||
visibility: {},
|
||||
whiteSpace: {},
|
||||
// flexbox
|
||||
flexBasis: {},
|
||||
flexDirection: {},
|
||||
flexWrap: {},
|
||||
justifyContent: {},
|
||||
alignItems: {},
|
||||
alignContent: {},
|
||||
order: {},
|
||||
flex: {},
|
||||
flexGrow: {},
|
||||
flexShrink: {},
|
||||
alignSelf: {},
|
||||
justifyItems: {},
|
||||
justifySelf: {},
|
||||
// grid
|
||||
gap: {
|
||||
style: gap
|
||||
},
|
||||
rowGap: {
|
||||
style: rowGap
|
||||
},
|
||||
columnGap: {
|
||||
style: columnGap
|
||||
},
|
||||
gridColumn: {},
|
||||
gridRow: {},
|
||||
gridAutoFlow: {},
|
||||
gridAutoColumns: {},
|
||||
gridAutoRows: {},
|
||||
gridTemplateColumns: {},
|
||||
gridTemplateRows: {},
|
||||
gridTemplateAreas: {},
|
||||
gridArea: {},
|
||||
// positions
|
||||
position: {},
|
||||
zIndex: {
|
||||
themeKey: 'zIndex'
|
||||
},
|
||||
top: {},
|
||||
right: {},
|
||||
bottom: {},
|
||||
left: {},
|
||||
// shadows
|
||||
boxShadow: {
|
||||
themeKey: 'shadows'
|
||||
},
|
||||
// sizing
|
||||
width: {
|
||||
transform: sizingTransform
|
||||
},
|
||||
maxWidth: {
|
||||
style: maxWidth
|
||||
},
|
||||
minWidth: {
|
||||
transform: sizingTransform
|
||||
},
|
||||
height: {
|
||||
transform: sizingTransform
|
||||
},
|
||||
maxHeight: {
|
||||
transform: sizingTransform
|
||||
},
|
||||
minHeight: {
|
||||
transform: sizingTransform
|
||||
},
|
||||
boxSizing: {},
|
||||
// typography
|
||||
fontFamily: {
|
||||
themeKey: 'typography'
|
||||
},
|
||||
fontSize: {
|
||||
themeKey: 'typography'
|
||||
},
|
||||
fontStyle: {
|
||||
themeKey: 'typography'
|
||||
},
|
||||
fontWeight: {
|
||||
themeKey: 'typography'
|
||||
},
|
||||
letterSpacing: {},
|
||||
textTransform: {},
|
||||
lineHeight: {},
|
||||
textAlign: {},
|
||||
typography: {
|
||||
cssProperty: false,
|
||||
themeKey: 'typography'
|
||||
}
|
||||
};
|
||||
export default defaultSxConfig;
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import _extends from "@babel/runtime/helpers/esm/extends";
|
||||
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
||||
const _excluded = ["sx"];
|
||||
import { isPlainObject } from '@mui/utils/deepmerge';
|
||||
import defaultSxConfig from './defaultSxConfig';
|
||||
const splitProps = props => {
|
||||
var _props$theme$unstable, _props$theme;
|
||||
const result = {
|
||||
systemProps: {},
|
||||
otherProps: {}
|
||||
};
|
||||
const config = (_props$theme$unstable = props == null || (_props$theme = props.theme) == null ? void 0 : _props$theme.unstable_sxConfig) != null ? _props$theme$unstable : defaultSxConfig;
|
||||
Object.keys(props).forEach(prop => {
|
||||
if (config[prop]) {
|
||||
result.systemProps[prop] = props[prop];
|
||||
} else {
|
||||
result.otherProps[prop] = props[prop];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
export default function extendSxProp(props) {
|
||||
const {
|
||||
sx: inSx
|
||||
} = props,
|
||||
other = _objectWithoutPropertiesLoose(props, _excluded);
|
||||
const {
|
||||
systemProps,
|
||||
otherProps
|
||||
} = splitProps(other);
|
||||
let finalSx;
|
||||
if (Array.isArray(inSx)) {
|
||||
finalSx = [systemProps, ...inSx];
|
||||
} else if (typeof inSx === 'function') {
|
||||
finalSx = (...args) => {
|
||||
const result = inSx(...args);
|
||||
if (!isPlainObject(result)) {
|
||||
return systemProps;
|
||||
}
|
||||
return _extends({}, systemProps, result);
|
||||
};
|
||||
} else {
|
||||
finalSx = _extends({}, systemProps, inSx);
|
||||
}
|
||||
return _extends({}, otherProps, {
|
||||
sx: finalSx
|
||||
});
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
import capitalize from '@mui/utils/capitalize';
|
||||
import merge from '../merge';
|
||||
import { getPath, getStyleValue as getValue } from '../style';
|
||||
import { handleBreakpoints, createEmptyBreakpointObject, removeUnusedBreakpoints } from '../breakpoints';
|
||||
import defaultSxConfig from './defaultSxConfig';
|
||||
function objectsHaveSameKeys(...objects) {
|
||||
const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []);
|
||||
const union = new Set(allKeys);
|
||||
return objects.every(object => union.size === Object.keys(object).length);
|
||||
}
|
||||
function callIfFn(maybeFn, arg) {
|
||||
return typeof maybeFn === 'function' ? maybeFn(arg) : maybeFn;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export function unstable_createStyleFunctionSx() {
|
||||
function getThemeValue(prop, val, theme, config) {
|
||||
const props = {
|
||||
[prop]: val,
|
||||
theme
|
||||
};
|
||||
const options = config[prop];
|
||||
if (!options) {
|
||||
return {
|
||||
[prop]: val
|
||||
};
|
||||
}
|
||||
const {
|
||||
cssProperty = prop,
|
||||
themeKey,
|
||||
transform,
|
||||
style
|
||||
} = options;
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO v6: remove, see https://github.com/mui/material-ui/pull/38123
|
||||
if (themeKey === 'typography' && val === 'inherit') {
|
||||
return {
|
||||
[prop]: val
|
||||
};
|
||||
}
|
||||
const themeMapping = getPath(theme, themeKey) || {};
|
||||
if (style) {
|
||||
return style(props);
|
||||
}
|
||||
const styleFromPropValue = propValueFinal => {
|
||||
let value = getValue(themeMapping, transform, propValueFinal);
|
||||
if (propValueFinal === value && typeof propValueFinal === 'string') {
|
||||
// Haven't found value
|
||||
value = getValue(themeMapping, transform, `${prop}${propValueFinal === 'default' ? '' : capitalize(propValueFinal)}`, propValueFinal);
|
||||
}
|
||||
if (cssProperty === false) {
|
||||
return value;
|
||||
}
|
||||
return {
|
||||
[cssProperty]: value
|
||||
};
|
||||
};
|
||||
return handleBreakpoints(props, val, styleFromPropValue);
|
||||
}
|
||||
function styleFunctionSx(props) {
|
||||
var _theme$unstable_sxCon;
|
||||
const {
|
||||
sx,
|
||||
theme = {}
|
||||
} = props || {};
|
||||
if (!sx) {
|
||||
return null; // Emotion & styled-components will neglect null
|
||||
}
|
||||
const config = (_theme$unstable_sxCon = theme.unstable_sxConfig) != null ? _theme$unstable_sxCon : defaultSxConfig;
|
||||
|
||||
/*
|
||||
* Receive `sxInput` as object or callback
|
||||
* and then recursively check keys & values to create media query object styles.
|
||||
* (the result will be used in `styled`)
|
||||
*/
|
||||
function traverse(sxInput) {
|
||||
let sxObject = sxInput;
|
||||
if (typeof sxInput === 'function') {
|
||||
sxObject = sxInput(theme);
|
||||
} else if (typeof sxInput !== 'object') {
|
||||
// value
|
||||
return sxInput;
|
||||
}
|
||||
if (!sxObject) {
|
||||
return null;
|
||||
}
|
||||
const emptyBreakpoints = createEmptyBreakpointObject(theme.breakpoints);
|
||||
const breakpointsKeys = Object.keys(emptyBreakpoints);
|
||||
let css = emptyBreakpoints;
|
||||
Object.keys(sxObject).forEach(styleKey => {
|
||||
const value = callIfFn(sxObject[styleKey], theme);
|
||||
if (value !== null && value !== undefined) {
|
||||
if (typeof value === 'object') {
|
||||
if (config[styleKey]) {
|
||||
css = merge(css, getThemeValue(styleKey, value, theme, config));
|
||||
} else {
|
||||
const breakpointsValues = handleBreakpoints({
|
||||
theme
|
||||
}, value, x => ({
|
||||
[styleKey]: x
|
||||
}));
|
||||
if (objectsHaveSameKeys(breakpointsValues, value)) {
|
||||
css[styleKey] = styleFunctionSx({
|
||||
sx: value,
|
||||
theme
|
||||
});
|
||||
} else {
|
||||
css = merge(css, breakpointsValues);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
css = merge(css, getThemeValue(styleKey, value, theme, config));
|
||||
}
|
||||
}
|
||||
});
|
||||
return removeUnusedBreakpoints(breakpointsKeys, css);
|
||||
}
|
||||
return Array.isArray(sx) ? sx.map(traverse) : traverse(sx);
|
||||
}
|
||||
return styleFunctionSx;
|
||||
}
|
||||
const styleFunctionSx = unstable_createStyleFunctionSx();
|
||||
styleFunctionSx.filterProps = ['sx'];
|
||||
export default styleFunctionSx;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import createStyled from './createStyled';
|
||||
const styled = createStyled();
|
||||
export default styled;
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
|
||||
import { getThemeProps } from '../useThemeProps';
|
||||
import useTheme from '../useThemeWithoutDefault';
|
||||
|
||||
/**
|
||||
* @deprecated Not used internally. Use `MediaQueryListEvent` from lib.dom.d.ts instead.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated Not used internally. Use `MediaQueryList` from lib.dom.d.ts instead.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated Not used internally. Use `(event: MediaQueryListEvent) => void` instead.
|
||||
*/
|
||||
|
||||
function useMediaQueryOld(query, defaultMatches, matchMedia, ssrMatchMedia, noSsr) {
|
||||
const [match, setMatch] = React.useState(() => {
|
||||
if (noSsr && matchMedia) {
|
||||
return matchMedia(query).matches;
|
||||
}
|
||||
if (ssrMatchMedia) {
|
||||
return ssrMatchMedia(query).matches;
|
||||
}
|
||||
|
||||
// Once the component is mounted, we rely on the
|
||||
// event listeners to return the correct matches value.
|
||||
return defaultMatches;
|
||||
});
|
||||
useEnhancedEffect(() => {
|
||||
let active = true;
|
||||
if (!matchMedia) {
|
||||
return undefined;
|
||||
}
|
||||
const queryList = matchMedia(query);
|
||||
const updateMatch = () => {
|
||||
// Workaround Safari wrong implementation of matchMedia
|
||||
// TODO can we remove it?
|
||||
// https://github.com/mui/material-ui/pull/17315#issuecomment-528286677
|
||||
if (active) {
|
||||
setMatch(queryList.matches);
|
||||
}
|
||||
};
|
||||
updateMatch();
|
||||
// TODO: Use `addEventListener` once support for Safari < 14 is dropped
|
||||
queryList.addListener(updateMatch);
|
||||
return () => {
|
||||
active = false;
|
||||
queryList.removeListener(updateMatch);
|
||||
};
|
||||
}, [query, matchMedia]);
|
||||
return match;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-useless-concat -- Workaround for https://github.com/webpack/webpack/issues/14814
|
||||
const maybeReactUseSyncExternalStore = React['useSyncExternalStore' + ''];
|
||||
function useMediaQueryNew(query, defaultMatches, matchMedia, ssrMatchMedia, noSsr) {
|
||||
const getDefaultSnapshot = React.useCallback(() => defaultMatches, [defaultMatches]);
|
||||
const getServerSnapshot = React.useMemo(() => {
|
||||
if (noSsr && matchMedia) {
|
||||
return () => matchMedia(query).matches;
|
||||
}
|
||||
if (ssrMatchMedia !== null) {
|
||||
const {
|
||||
matches
|
||||
} = ssrMatchMedia(query);
|
||||
return () => matches;
|
||||
}
|
||||
return getDefaultSnapshot;
|
||||
}, [getDefaultSnapshot, query, ssrMatchMedia, noSsr, matchMedia]);
|
||||
const [getSnapshot, subscribe] = React.useMemo(() => {
|
||||
if (matchMedia === null) {
|
||||
return [getDefaultSnapshot, () => () => {}];
|
||||
}
|
||||
const mediaQueryList = matchMedia(query);
|
||||
return [() => mediaQueryList.matches, notify => {
|
||||
// TODO: Use `addEventListener` once support for Safari < 14 is dropped
|
||||
mediaQueryList.addListener(notify);
|
||||
return () => {
|
||||
mediaQueryList.removeListener(notify);
|
||||
};
|
||||
}];
|
||||
}, [getDefaultSnapshot, matchMedia, query]);
|
||||
const match = maybeReactUseSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||||
return match;
|
||||
}
|
||||
export default function useMediaQuery(queryInput, options = {}) {
|
||||
const theme = useTheme();
|
||||
// Wait for jsdom to support the match media feature.
|
||||
// All the browsers MUI support have this built-in.
|
||||
// This defensive check is here for simplicity.
|
||||
// Most of the time, the match media logic isn't central to people tests.
|
||||
const supportMatchMedia = typeof window !== 'undefined' && typeof window.matchMedia !== 'undefined';
|
||||
const {
|
||||
defaultMatches = false,
|
||||
matchMedia = supportMatchMedia ? window.matchMedia : null,
|
||||
ssrMatchMedia = null,
|
||||
noSsr = false
|
||||
} = getThemeProps({
|
||||
name: 'MuiUseMediaQuery',
|
||||
props: options,
|
||||
theme
|
||||
});
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (typeof queryInput === 'function' && theme === null) {
|
||||
console.error(['MUI: The `query` argument provided is invalid.', 'You are providing a function without a theme in the context.', 'One of the parent elements needs to use a ThemeProvider.'].join('\n'));
|
||||
}
|
||||
}
|
||||
let query = typeof queryInput === 'function' ? queryInput(theme) : queryInput;
|
||||
query = query.replace(/^@media( ?)/m, '');
|
||||
|
||||
// TODO: Drop `useMediaQueryOld` and use `use-sync-external-store` shim in `useMediaQueryNew` once the package is stable
|
||||
const useMediaQueryImplementation = maybeReactUseSyncExternalStore !== undefined ? useMediaQueryNew : useMediaQueryOld;
|
||||
const match = useMediaQueryImplementation(query, defaultMatches, matchMedia, ssrMatchMedia, noSsr);
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
React.useDebugValue({
|
||||
query,
|
||||
match
|
||||
});
|
||||
}
|
||||
return match;
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import createTheme from './createTheme';
|
||||
import useThemeWithoutDefault from './useThemeWithoutDefault';
|
||||
export const systemDefaultTheme = createTheme();
|
||||
function useTheme(defaultTheme = systemDefaultTheme) {
|
||||
return useThemeWithoutDefault(defaultTheme);
|
||||
}
|
||||
export default useTheme;
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import resolveProps from '@mui/utils/resolveProps';
|
||||
export default function getThemeProps(params) {
|
||||
const {
|
||||
theme,
|
||||
name,
|
||||
props
|
||||
} = params;
|
||||
if (!theme || !theme.components || !theme.components[name] || !theme.components[name].defaultProps) {
|
||||
return props;
|
||||
}
|
||||
return resolveProps(theme.components[name].defaultProps, props);
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
'use client';
|
||||
|
||||
import getThemeProps from './getThemeProps';
|
||||
import useTheme from '../useTheme';
|
||||
export default function useThemeProps({
|
||||
props,
|
||||
name,
|
||||
defaultTheme,
|
||||
themeId
|
||||
}) {
|
||||
let theme = useTheme(defaultTheme);
|
||||
if (themeId) {
|
||||
theme = theme[themeId] || theme;
|
||||
}
|
||||
const mergedProps = getThemeProps({
|
||||
theme,
|
||||
name,
|
||||
props
|
||||
});
|
||||
return mergedProps;
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import { ThemeContext } from '@mui/styled-engine';
|
||||
function isObjectEmpty(obj) {
|
||||
return Object.keys(obj).length === 0;
|
||||
}
|
||||
function useTheme(defaultTheme = null) {
|
||||
const contextTheme = React.useContext(ThemeContext);
|
||||
return !contextTheme || isObjectEmpty(contextTheme) ? defaultTheme : contextTheme;
|
||||
}
|
||||
export default useTheme;
|
||||
Reference in New Issue
Block a user