UNPKG

@octopusdeploy/design-system-components

Version:
99 lines (98 loc) 5.53 kB
"use strict"; 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 }), };