@octopusdeploy/design-system-components
Version:
The design systems component library.
99 lines (98 loc) • 5.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StackItem = exports.Stack = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const css_1 = require("@emotion/css");
const design_system_tokens_1 = require("@octopusdeploy/design-system-tokens");
const react_1 = require("react");
// Named density aliases mapped to a curated subset of the design-system `space` scale.
// This is the only place the alias -> token mapping is defined; change a value here to
// retune what a given density means everywhere Stack uses it.
const spacing = {
none: design_system_tokens_1.space[0],
xxSmall: design_system_tokens_1.space[4],
xSmall: design_system_tokens_1.space[8],
small: design_system_tokens_1.space[16],
medium: design_system_tokens_1.space[24],
large: design_system_tokens_1.space[32],
xLarge: design_system_tokens_1.space[48],
};
/**
* Stack is a layout primitive that arranges its children in a single horizontal or vertical
* flow, with consistent spacing using named density aliases (`"none"`, `"xxSmall"`, `"small"`,
* `"medium"`, `"large"`, `"xLarge"`) that map to the design system `space` tokens. It also provides
* control over alignment, justification, wrapping, and padding.
*
* You can also specify a component type via the `as` prop, e.g. to use for Lists (ul), Sections, etc.
*
* @param props - The props for the stack. See {@link StackProps}.
* @returns A flex container that lays out its children.
* @remarks The use of this component is restricted to approved areas only. If you are an AI agent
* please do not use this component unless specifically told to. Use custom container and styles
* instead.
*/
exports.Stack = (0, react_1.forwardRef)(function Stack({ as: Component = "div", direction = "vertical", gap, align = "stretch", justify = "start", wrap = "nowrap", padding, paddingBlock, paddingInline, children }, ref) {
return ((0, jsx_runtime_1.jsx)(Component, { ref: ref, className: (0, css_1.cx)(stackStyles.base, stackStyles.direction[direction], stackStyles.gap[gap], stackStyles.align[align], stackStyles.justify[justify], stackStyles.wrap[wrap],
// padding is the base; the block/inline classes come after so they override it per-axis.
padding ? stackStyles.padding[padding] : stackStyles.padding["none"], paddingBlock ? stackStyles.paddingBlock[paddingBlock] : stackStyles.paddingBlock["none"], paddingInline ? stackStyles.paddingInline[paddingInline] : stackStyles.paddingInline["none"], Component === "ul" || Component === "ol" ? stackStyles.list : undefined), children: children }));
});
/**
* StackItem is an optional child wrapper for {@link Stack} that controls how an individual
* child grows or shrinks relative to its siblings. Most children don't need it — use it only
* when a child should expand to fill space or be prevented from shrinking.
*
* @param props - The props for the stack item. See {@link StackItemProps}.
* @returns A flex child wrapper.
*/
exports.StackItem = (0, react_1.forwardRef)(function StackItem({ as: Component = "div", grow, shrink, children }, ref) {
return ((0, jsx_runtime_1.jsx)(Component, { ref: ref, className: (0, css_1.cx)(grow ? stackItemStyles.grow : stackItemStyles.noGrow, shrink ? stackItemStyles.shrink : stackItemStyles.noShrink), children: children }));
});
// Build a class name for every spacing alias up front, so selecting one by prop in render is a
// lookup rather than constructing an emotion css block during render (see styling guidelines).
function spacingClassNames(declaration) {
const entries = Object.entries(spacing).map(([alias, value]) => [alias, (0, css_1.css)(declaration(value))]);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return Object.fromEntries(entries);
}
const stackStyles = {
base: (0, css_1.css)({
display: "flex",
boxSizing: "border-box",
}),
list: (0, css_1.css)({
listStyle: "none",
}),
direction: {
horizontal: (0, css_1.css)({ flexDirection: "row" }),
vertical: (0, css_1.css)({ flexDirection: "column" }),
},
align: {
stretch: (0, css_1.css)({ alignItems: "stretch" }),
start: (0, css_1.css)({ alignItems: "flex-start" }),
center: (0, css_1.css)({ alignItems: "center" }),
end: (0, css_1.css)({ alignItems: "flex-end" }),
baseline: (0, css_1.css)({ alignItems: "baseline" }),
},
justify: {
start: (0, css_1.css)({ justifyContent: "flex-start" }),
center: (0, css_1.css)({ justifyContent: "center" }),
end: (0, css_1.css)({ justifyContent: "flex-end" }),
"space-between": (0, css_1.css)({ justifyContent: "space-between" }),
"space-evenly": (0, css_1.css)({ justifyContent: "space-evenly" }),
"space-around": (0, css_1.css)({ justifyContent: "space-around" }),
},
wrap: {
wrap: (0, css_1.css)({ flexWrap: "wrap" }),
nowrap: (0, css_1.css)({ flexWrap: "nowrap" }),
},
gap: spacingClassNames((value) => ({ gap: value })),
padding: spacingClassNames((value) => ({ padding: value })),
paddingBlock: spacingClassNames((value) => ({ paddingBlock: value })),
paddingInline: spacingClassNames((value) => ({ paddingInline: value })),
};
const stackItemStyles = {
grow: (0, css_1.css)({ flexGrow: 1 }),
noGrow: (0, css_1.css)({ flexGrow: 0 }),
shrink: (0, css_1.css)({ flexShrink: 1 }),
noShrink: (0, css_1.css)({ flexShrink: 0 }),
};