storybook-addon-grid
Version:
Column guides for your stories
133 lines (127 loc) • 3.59 kB
JavaScript
// src/chromatic.ts
import isChromatic from "chromatic/isChromatic";
// src/Grids.tsx
import React2 from "react";
import { createPortal } from "react-dom";
import { useAddonState, useParameter } from "storybook/manager-api";
import { CacheProvider, createCache } from "storybook/theming";
// src/constants.ts
var ADDON_ID = "storybook-addon-grid";
var PARAM_KEY = "grid";
// src/ui.tsx
import React from "react";
import { Global, styled } from "storybook/theming";
var MAX_COLUMNS = 24;
var Wrapper = styled.div({
position: "relative",
zIndex: 1,
opacity: 0,
pointerEvents: "none",
'&[data-visible="true"]': {
opacity: 1
}
});
var Grid = styled.div(
({ gap, gutter, maxWidth, columns }) => {
let gutterRight = "0", gutterLeft = "0";
if (Array.isArray(gutter)) {
[gutterLeft, gutterRight] = gutter;
} else if (gutter != null) {
gutterLeft = gutterRight = gutter;
}
return {
position: "fixed",
inset: "0",
display: "grid",
gridTemplateColumns: `repeat(min(${columns}, ${MAX_COLUMNS}), 1fr)`,
gridTemplateRows: "100%",
gridColumnGap: gap,
width: "100%",
height: "100%",
margin: "0 auto",
maxWidth,
padding: `0 ${gutterRight} 0 ${gutterLeft}`,
boxSizing: "border-box"
};
}
);
var Column = styled.div(({ color }) => ({
width: "100%",
height: "100%",
backgroundColor: color
}));
function Grids({
visible,
columns = 12,
gap = "20px",
color = "rgba(255, 0, 0, 0.1)",
gutter = "50px",
maxWidth = "1024px"
}) {
let columnDivs = React.useMemo(
() => Array.from({
length: typeof columns === "number" ? columns : MAX_COLUMNS
}).map((_, index) => <Column key={index} color={color} />),
[columns, color]
);
let gridNodes = <Grid gap={gap} gutter={gutter} maxWidth={maxWidth} columns={columns}>{columnDivs}</Grid>;
return <>
<Global styles={{
[`#root`]: {
position: "relative",
zIndex: 0
}
}} />
<Wrapper data-addon-id={ADDON_ID} data-visible={visible}>{gridNodes}</Wrapper>
</>;
}
// src/Grids.tsx
function ManagerRenderedGrids() {
let { columns, gap, color, gutter, maxWidth, disable } = useParameter(PARAM_KEY, {});
let [state] = useAddonState(ADDON_ID);
return <Grids columns={columns} color={color} gap={gap} visible={disable != null ? !disable : state?.visible ?? false} gutter={gutter} maxWidth={maxWidth} />;
}
var styleCache = /* @__PURE__ */ new WeakMap();
var ManagerRenderedGridsContainer = React2.memo(
function ManagerRenderedGridsContainer2() {
let previewIframe = document.querySelector(
"#storybook-preview-iframe"
);
if (!previewIframe)
return null;
let iframeDocument = previewIframe.contentWindow?.document;
if (!iframeDocument)
return null;
let head = iframeDocument.head;
if (!head || !iframeDocument.body)
return null;
if (!styleCache.has(head))
styleCache.set(
head,
createCache({
key: ADDON_ID,
container: head
})
);
return createPortal(
<CacheProvider value={styleCache.get(head)}><ManagerRenderedGrids /></CacheProvider>,
iframeDocument.body
);
}
);
var withGrid = (StoryFn, context) => {
let { grid: gridParams } = context.parameters;
return <>
{StoryFn()}
{gridParams != null && gridParams.disable !== true && <Grids visible {...gridParams} />}
</>;
};
// src/chromatic.ts
var parameters = {
[PARAM_KEY]: {}
};
var decorators = isChromatic() ? [withGrid] : [];
export {
decorators,
parameters
};