@greensight/gds
Version:
Greensight Design System
436 lines (426 loc) • 13.9 kB
JavaScript
import { B as BREAKPOINTS_NAMES, a as _objectWithoutProperties, j as jsx, e as _extends, f as useTheme$1, _ as _objectSpread2, b as _defineProperty, g as _typeof } from './useTheme-DPU-Td50.js';
import { useMemo, createContext, useContext } from 'react';
import { b as baseTheme } from './typography-BmZOWRkU.js';
/**
* Converts any type to array (arrays are included).
*/
var toArray = function toArray(arg) {
var _ref;
return (_ref = []).concat.apply(_ref, [arg]);
};
/**
* Custom hook to get your theme object in React components from ThemeProvider.
*/
var useTheme = function useTheme() {
return useTheme$1();
};
/**
* Strict check on object type.
*/
var isObject = function isObject(item) {
return _typeof(item) === 'object' && !Array.isArray(item) && item !== null;
};
var BREAKPOINT_INDICES = new Map();
BREAKPOINTS_NAMES.forEach(function (e, i) {
return BREAKPOINT_INDICES.set(e, i);
});
/**
* Calculate CSS Object from component props with `AllowMedia` type (user can pass object with breakpoints through prop). CSS property can be calculated based on multiple props.
*/
var useCSSProperty = function useCSSProperty(_ref) {
var name = _ref.name,
props = _ref.props,
condition = _ref.condition,
transform = _ref.transform;
var _useTheme = useTheme(),
layout = _useTheme.layout;
var layoutTheme = layout || baseTheme.layout;
var breakpoints = layoutTheme.breakpoints;
return useMemo(function () {
if (condition !== undefined && !condition) return;
var propsValues = Object.values(props);
var isUndefined = propsValues.every(function (value) {
return value === undefined;
});
if (isUndefined) return;
var mediaProp = propsValues.find(function (value) {
return isObject(value);
});
if (!mediaProp) return setValue(name, props, transform);
return Object.keys(mediaProp).sort(function (a, b) {
return BREAKPOINT_INDICES.get(a) - BREAKPOINT_INDICES.get(b);
}).reduce(function (acc, bp) {
var nameIndex = BREAKPOINT_INDICES.get(bp);
var nextBp = nameIndex !== -1 && BREAKPOINTS_NAMES[nameIndex - 1];
var breakpointProps = {};
for (var key in props) {
var value = props[key];
breakpointProps[key] = !isObject(value) ? value : value[bp];
}
var rule = setValue(name, breakpointProps, transform);
return _objectSpread2(_objectSpread2({}, acc), nextBp ? _defineProperty({}, "@media (max-width: ".concat(breakpoints[nextBp] - 1, "px)"), rule) : rule);
}, {});
}, [breakpoints, condition, name, props, transform]);
};
var setValue = function setValue(name, props, transform) {
return _defineProperty({}, name, transform ? transform(props) : Object.values(props)[0]);
};
/** Импорт React нужен для tsc. */
var LayoutContext = /*#__PURE__*/createContext(undefined);
var useLayout = function useLayout() {
var context = useContext(LayoutContext);
if (!context) {
throw new Error('This component must be used within a <Layout> component');
}
return context;
};
var _excluded$1 = ["children", "col", "row", "area", "justify", "align", "order", "grow", "css"];
/**
* Inner `Layout` component for creating layout cells.
*/
var Item = function Item(_ref) {
var children = _ref.children,
colProp = _ref.col,
rowProp = _ref.row,
areaProp = _ref.area,
justify = _ref.justify,
alignProp = _ref.align,
orderProp = _ref.order,
growProp = _ref.grow,
css = _ref.css,
props = _objectWithoutProperties(_ref, _excluded$1);
var context = useLayout();
var gridColumn = useCSSProperty({
name: 'gridColumn',
props: {
col: colProp
},
condition: context.type === 'grid',
transform: function transform(_ref2) {
var col = _ref2.col;
if (Array.isArray(col)) return "".concat(col[0], " / ").concat(col[1]);
if (Number.isInteger(col)) return "span ".concat(col);
return col;
}
});
var gridRow = useCSSProperty({
name: 'gridRow',
props: {
row: rowProp
},
condition: context.type === 'grid',
transform: function transform(_ref3) {
var row = _ref3.row;
if (Array.isArray(row)) return "".concat(row[0], " / ").concat(row[1]);
if (Number.isInteger(row)) return "span ".concat(row);
return row;
}
});
var gridArea = useCSSProperty({
name: 'gridArea',
props: {
area: areaProp
},
condition: context.type === 'grid'
});
var justifySelf = useCSSProperty({
name: 'justifySelf',
props: {
justify: justify
},
condition: context.type === 'grid'
});
var alignSelf = useCSSProperty({
name: 'alignSelf',
props: {
align: alignProp
},
transform: function transform(_ref4) {
var align = _ref4.align;
if (context.type === 'flex' && (align === 'start' || align === 'end')) return "flex-".concat(align);
return align;
}
});
var order = useCSSProperty({
name: 'order',
props: {
order: orderProp
}
});
var flexGrow = useCSSProperty({
name: 'flexGrow',
props: {
grow: growProp,
auto: context.auto
},
condition: context.type === 'flex',
transform: function transform(_ref5) {
var grow = _ref5.grow,
auto = _ref5.auto;
if (auto) return 1;
return !Number.isInteger(grow) ? Number(grow) : grow;
}
});
var padding = useCSSProperty({
name: 'padding',
props: {
gap: context.gap
},
condition: context.type === 'flex',
transform: function transform(_ref6) {
var gap = _ref6.gap;
if (Array.isArray(gap)) return "".concat(gap[0], "px 0 0 ").concat(gap[1], "px");
return "".concat(gap, "px 0 0 ").concat(gap, "px");
}
});
var flexBasis = useCSSProperty({
name: 'flexBasis',
props: {
col: colProp,
auto: context.auto
},
condition: context.type === 'flex',
transform: function transform(_ref7) {
var col = _ref7.col,
auto = _ref7.auto;
if (auto) return auto;
if (typeof context.cols === 'number' && Number.isInteger(Number(col))) return "".concat(Math.floor(100 * col * 100 / context.cols) / 100, "%");
return col;
}
});
var layoutItemCss = useMemo(function () {
return [padding, order, flexGrow, flexBasis, justifySelf, alignSelf, gridColumn, gridRow, gridArea, css];
}, [padding, order, flexGrow, flexBasis, justifySelf, alignSelf, gridColumn, gridRow, gridArea, css]);
return jsx("div", _extends({
css: layoutItemCss
}, props), children);
};
var _excluded = ["type", "inline", "cols", "rows", "areas", "gap", "justify", "align", "autoRows", "autoCols", "direction", "dense", "reverse", "wrap", "auto", "css", "children"];
/**
* Component for creating typical grid and flex layouts.
*/
var LayoutComponent = function LayoutComponent(_ref) {
var _ref$type = _ref.type,
typeProp = _ref$type === void 0 ? 'grid' : _ref$type,
inlineProp = _ref.inline,
colsProp = _ref.cols,
rowsProp = _ref.rows,
areasProp = _ref.areas,
gapProp = _ref.gap,
justifyProp = _ref.justify,
alignProp = _ref.align,
autoRowsProp = _ref.autoRows,
autoColsProp = _ref.autoCols,
directionProp = _ref.direction,
denseProp = _ref.dense,
reverseProp = _ref.reverse,
_ref$wrap = _ref.wrap,
wrapProp = _ref$wrap === void 0 ? true : _ref$wrap,
autoProp = _ref.auto,
css = _ref.css,
children = _ref.children,
props = _objectWithoutProperties(_ref, _excluded);
var _useTheme = useTheme(),
layout = _useTheme.layout;
var layoutTheme = layout || baseTheme.layout;
var defaultGap = gapProp !== null && gapProp !== void 0 ? gapProp : layoutTheme.gap;
var defaultCols = colsProp !== null && colsProp !== void 0 ? colsProp : layoutTheme.cols;
var context = useMemo(function () {
return {
type: typeProp,
gap: defaultGap,
cols: defaultCols,
auto: autoProp
};
}, [typeProp, autoProp, defaultGap, defaultCols]);
var display = useCSSProperty({
name: 'display',
props: {
type: context.type,
inline: inlineProp
},
transform: function transform(_ref2) {
var type = _ref2.type,
inline = _ref2.inline;
return inline ? "inline-".concat(type) : type;
}
});
var gridTemplateColumns = useCSSProperty({
name: 'gridTemplateColumns',
props: {
cols: context.cols,
auto: context.auto
},
condition: context.type === 'grid' && !areasProp,
transform: function transform(_ref3) {
var cols = _ref3.cols,
auto = _ref3.auto;
if (auto) return "repeat(auto-fill, minmax(".concat(auto, "px, 1fr))");
if (Number.isInteger(cols)) return "repeat(".concat(cols, ", 1fr)");
var arr = toArray(cols);
return arr.map(function (val) {
return Number.isInteger(val) ? "".concat(val, "fr") : val;
}).join(' ');
}
});
var gridTemplateRows = useCSSProperty({
name: 'gridTemplateRows',
props: {
rows: rowsProp
},
condition: context.type === 'grid' && !areasProp,
transform: function transform(_ref4) {
var rows = _ref4.rows;
if (Number.isInteger(rows)) return "repeat(".concat(rows, ", 1fr)");
var arr = toArray(rows);
return arr.map(function (val) {
return Number.isInteger(val) ? "".concat(val, "fr") : val;
}).join(' ');
}
});
var gridTemplateAreas = useCSSProperty({
name: 'gridTemplateAreas',
props: {
areas: areasProp
},
condition: context.type === 'grid',
transform: function transform(_ref5) {
var areas = _ref5.areas;
var arr = toArray(areas);
return arr.map(function (val) {
return "\"".concat(val, "\"");
}).join(' ');
}
});
var gridGap = useCSSProperty({
name: 'gridGap',
props: {
gap: context.gap
},
condition: context.type === 'grid',
transform: function transform(_ref6) {
var gap = _ref6.gap;
if (Array.isArray(gap)) return "".concat(gap[0], "px ").concat(gap[1], "px");
return gap;
}
});
var margin = useCSSProperty({
name: 'margin',
props: {
gap: context.gap
},
condition: context.type === 'flex',
transform: function transform(_ref7) {
var gap = _ref7.gap;
if (Array.isArray(gap)) return "-".concat(gap[0], "px 0 0 -").concat(gap[1], "px");
return "-".concat(gap, "px 0 0 -").concat(gap, "px");
}
});
var justifyItems = useCSSProperty({
name: 'justifyItems',
props: {
justify: justifyProp
},
condition: context.type === 'grid'
});
var justifyContent = useCSSProperty({
name: 'justifyContent',
props: {
justify: justifyProp
},
condition: context.type === 'flex',
transform: function transform(_ref8) {
var justify = _ref8.justify;
if (justify === 'start' || justify === 'end') return "flex-".concat(justify);
return justify;
}
});
var alignItems = useCSSProperty({
name: 'alignItems',
props: {
align: alignProp
},
transform: function transform(_ref9) {
var align = _ref9.align;
if (context.type === 'flex' && (align === 'start' || align === 'end')) return "flex-".concat(align);
return align;
}
});
var gridAutoRows = useCSSProperty({
name: 'gridAutoRows',
props: {
autoRows: autoRowsProp
},
condition: context.type === 'grid',
transform: function transform(_ref10) {
var autoRows = _ref10.autoRows;
var arr = toArray(autoRows);
return arr.map(function (val) {
return Number.isInteger(val) ? "".concat(val, "fr") : val;
}).join(' ');
}
});
var gridAutoColumns = useCSSProperty({
name: 'gridAutoColumns',
props: {
autoCols: autoColsProp
},
condition: context.type === 'grid',
transform: function transform(_ref11) {
var autoCols = _ref11.autoCols;
var arr = toArray(autoCols);
return arr.map(function (val) {
return Number.isInteger(val) ? "".concat(val, "fr") : val;
}).join(' ');
}
});
var gridAutoFlow = useCSSProperty({
name: 'gridAutoFlow',
props: {
direction: directionProp,
dense: denseProp
},
condition: context.type === 'grid' && (directionProp === 'column' || !!denseProp),
transform: function transform(_ref12) {
var direction = _ref12.direction,
dense = _ref12.dense;
return "".concat(direction === 'column' ? 'column' : '').concat(dense ? ' dense' : '').trim();
}
});
var flexDirection = useCSSProperty({
name: 'flexDirection',
props: {
direction: directionProp,
reverse: reverseProp
},
condition: context.type === 'flex',
transform: function transform(_ref13) {
var direction = _ref13.direction,
reverse = _ref13.reverse;
return "".concat(direction === 'column' ? 'column' : 'row').concat(reverse ? '-reverse' : '');
}
});
var flexWrap = useCSSProperty({
name: 'flexWrap',
props: {
wrap: wrapProp
},
condition: context.type === 'flex',
transform: function transform(_ref14) {
var wrap = _ref14.wrap;
return wrap ? 'wrap' : 'nowrap';
}
});
var layoutCss = useMemo(function () {
return [display, margin, flexWrap, flexDirection, justifyItems, justifyContent, alignItems, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridAutoColumns, gridAutoRows, gridAutoFlow, gridGap, css];
}, [display, margin, flexWrap, flexDirection, justifyItems, justifyContent, alignItems, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridAutoColumns, gridAutoRows, gridAutoFlow, gridGap, css]);
return jsx(LayoutContext.Provider, {
value: context
}, jsx("div", _extends({
css: layoutCss
}, props), children));
};
var Layout = Object.assign(LayoutComponent, {
Item: Item
});
export { Layout as L };