@zeytal/grid
Version:
Small layout grid utility. Align everything perfectly. Simplify your responsive design coding process without sacrificing effectiveness. Hit G on your keyboard to toggle your grid on and off.
234 lines (230 loc) • 14.5 kB
JavaScript
"use strict";
"use client";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.tsx
var index_exports = {};
__export(index_exports, {
GridOverlay: () => GridOverlay
});
module.exports = __toCommonJS(index_exports);
var import_react = require("react");
// #style-inject:#style-inject
function styleInject(css, { insertAt } = {}) {
if (!css || typeof document === "undefined") return;
const head = document.head || document.getElementsByTagName("head")[0];
const style = document.createElement("style");
style.type = "text/css";
if (insertAt === "top") {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
// src/styles.css
styleInject('*,\n::before,\n::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n:root,\n.dark-mode,\n.light-mode .invert-theme {\n --grid-blue-400: 212 100% 23%;\n --grid-blue-700: 214 100% 50%;\n --grid-teal-400: 170 100% 13%;\n --grid-teal-700: 173 100% 33%;\n --grid-green-400: 138 100% 14%;\n --grid-green-700: 140 100% 34%;\n --grid-amber-400: 32 100% 18%;\n --grid-amber-700: 41 100% 50%;\n --grid-red-400: 353 75% 25%;\n --grid-red-700: 355 87% 57%;\n --grid-purple-400: 278 64% 28%;\n --grid-purple-700: 274 64% 54%;\n}\n.gd-pointer-events-none {\n pointer-events: none;\n}\n.gd-pointer-events-auto {\n pointer-events: auto;\n}\n.gd-fixed {\n position: fixed;\n}\n.gd-absolute {\n position: absolute;\n}\n.gd-relative {\n position: relative;\n}\n.gd-inset-x-0 {\n left: 0;\n right: 0;\n}\n.gd-inset-y-0 {\n top: 0;\n bottom: 0;\n}\n.gd-left-1\\/2 {\n left: 50%;\n}\n.gd-z-50 {\n z-index: 50;\n}\n.gd-z-\\[9999\\] {\n z-index: 9999;\n}\n.gd-flex {\n display: flex;\n}\n.gd-h-full {\n height: 100%;\n}\n.gd-w-full {\n width: 100%;\n}\n.gd--translate-x-1\\/2 {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.gd-overflow-hidden {\n overflow: hidden;\n}\n.gd-rounded-\\[999px\\] {\n border-radius: 999px;\n}\n.gd-border-\\[1px\\] {\n border-width: 1px;\n}\n.gd-border-l-\\[1px\\] {\n border-left-width: 1px;\n}\n.gd-border-current {\n border-color: currentColor;\n}\n.gd-border-l-current {\n border-left-color: currentColor;\n}\n.gd-bg-\\[black\\] {\n --tw-bg-opacity: 1;\n background-color: rgb(0 0 0 / var(--tw-bg-opacity, 1));\n}\n.gd-px-\\[12px\\] {\n padding-left: 12px;\n padding-right: 12px;\n}\n.gd-py-\\[4px\\] {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.gd-font-sans {\n font-family:\n ui-sans-serif,\n system-ui,\n sans-serif,\n "Apple Color Emoji",\n "Segoe UI Emoji",\n "Segoe UI Symbol",\n "Noto Color Emoji";\n}\n.gd-text-\\[white\\]\\/\\[0\\.9\\] {\n color: rgb(255 255 255 / 0.9);\n}\n.gd-shadow-\\[0_0_5px_0_rgba\\(0\\,0\\,0\\,1\\)\\] {\n --tw-shadow: 0 0 5px 0 rgba(0,0,0,1);\n --tw-shadow-colored: 0 0 5px 0 var(--tw-shadow-color);\n box-shadow:\n var(--tw-ring-offset-shadow, 0 0 #0000),\n var(--tw-ring-shadow, 0 0 #0000),\n var(--tw-shadow);\n}\n.last\\:gd-border-r-\\[1px\\]:last-child {\n border-right-width: 1px;\n}\n.last\\:gd-border-r-current:last-child {\n border-right-color: currentColor;\n}\n.data-\\[hud-position\\=bottom\\]\\:gd-bottom-\\[16px\\][data-hud-position=bottom] {\n bottom: 16px;\n}\n.data-\\[hud-position\\=top\\]\\:gd-top-\\[16px\\][data-hud-position=top] {\n top: 16px;\n}\n.data-\\[active\\=false\\]\\:gd-hidden[data-active=false] {\n display: none;\n}\n.data-\\[color\\=amber\\]\\:gd-bg-amber-700\\/\\[0\\.1\\][data-color=amber] {\n background-color: hsl(var(--grid-amber-700) / 0.1);\n}\n.data-\\[color\\=blue\\]\\:gd-bg-blue-700\\/\\[0\\.1\\][data-color=blue] {\n background-color: hsl(var(--grid-blue-700) / 0.1);\n}\n.data-\\[color\\=green\\]\\:gd-bg-green-700\\/\\[0\\.1\\][data-color=green] {\n background-color: hsl(var(--grid-green-700) / 0.1);\n}\n.data-\\[color\\=purple\\]\\:gd-bg-purple-700\\/\\[0\\.1\\][data-color=purple] {\n background-color: hsl(var(--grid-purple-700) / 0.1);\n}\n.data-\\[color\\=red\\]\\:gd-bg-red-700\\/\\[0\\.1\\][data-color=red] {\n background-color: hsl(var(--grid-red-700) / 0.1);\n}\n.data-\\[color\\=teal\\]\\:gd-bg-teal-700\\/\\[0\\.1\\][data-color=teal] {\n background-color: hsl(var(--grid-teal-700) / 0.1);\n}\n.data-\\[color\\=amber\\]\\:gd-text-amber-400[data-color=amber] {\n color: hsl(var(--grid-amber-400));\n}\n.data-\\[color\\=blue\\]\\:gd-text-blue-400[data-color=blue] {\n color: hsl(var(--grid-blue-400));\n}\n.data-\\[color\\=green\\]\\:gd-text-green-400[data-color=green] {\n color: hsl(var(--grid-green-400));\n}\n.data-\\[color\\=purple\\]\\:gd-text-purple-400[data-color=purple] {\n color: hsl(var(--grid-purple-400));\n}\n.data-\\[color\\=red\\]\\:gd-text-red-400[data-color=red] {\n color: hsl(var(--grid-red-400));\n}\n.data-\\[color\\=teal\\]\\:gd-text-teal-400[data-color=teal] {\n color: hsl(var(--grid-teal-400));\n}\n');
// src/index.tsx
var import_jsx_runtime = require("react/jsx-runtime");
var defaultBreakpoints = {
"0x": {
columns: 24,
gutter: 0
},
"320x": {
columns: 24,
gutter: 0
},
"400x": {
columns: 24,
gutter: 0
},
"480x": {
columns: 24,
gutter: 0
},
"576x": {
columns: 24,
gutter: 0
},
"672x": {
columns: 24,
gutter: 0
},
"768x": {
columns: 24,
gutter: 0
},
"896x": {
columns: 24,
gutter: 0
},
"1024x": {
columns: 24,
gutter: 0
},
"1152x": {
columns: 24,
gutter: 0
},
"1280x": {
columns: 24,
gutter: 0
},
"1408x": {
columns: 24,
gutter: 0
},
"1536x": {
columns: 24,
gutter: 0
},
"1920x": {
columns: 24,
gutter: 0
}
};
var colors = [
"blue",
"teal",
"green",
"amber",
"red",
"purple"
];
function GridOverlay({
breakpoints = defaultBreakpoints,
active = true,
maxWidth = "last-breakpoint"
}) {
const [isActive, setIsActive] = (0, import_react.useState)(active);
const [columnsNumber, setColumnsNumber] = (0, import_react.useState)(breakpoints["0x"].columns);
const [gutterSize, setGutterSize] = (0, import_react.useState)(0);
const [selectedBreakpoint, setSelectedBreakpoint] = (0, import_react.useState)("");
const [color, setColor] = (0, import_react.useState)(colors[0]);
const [HUDPosition, setHUDPosition] = (0, import_react.useState)("top");
const breakpointValues = Object.entries(breakpoints).map(
([key, value], index) => ({
name: key,
width: parseInt(key.replace("x", ""), 10),
columns: value.columns,
gutter: (value.gutter ?? 0) >= 0 ? value.gutter ?? 0 : 0,
color: colors[index % colors.length]
})
);
const computeColumns = () => {
if (!breakpointValues[0]) return;
const width = window.innerWidth;
const breakpoint = breakpointValues.reduce(
(previousBreakpoint, currentBreakpoint) => {
return width >= currentBreakpoint.width && currentBreakpoint.width > previousBreakpoint.width ? currentBreakpoint : previousBreakpoint;
},
breakpointValues[0]
);
setColumnsNumber(breakpoint.columns);
setGutterSize(breakpoint.gutter);
setSelectedBreakpoint(breakpoint.name);
setColor(breakpoint.color);
};
(0, import_react.useEffect)(() => {
computeColumns();
window.addEventListener("resize", computeColumns);
return () => {
window.removeEventListener("resize", computeColumns);
};
}, []);
const toggleGrid = ({ isComposing, key }) => {
if (isComposing || !key || key.toLowerCase() !== "g") return;
setIsActive((prevState) => !prevState);
};
(0, import_react.useEffect)(() => {
document.addEventListener("keydown", toggleGrid);
return () => {
document.removeEventListener("keydown", toggleGrid);
};
}, []);
const changeHUDPosition = () => {
if (HUDPosition === "top") {
setHUDPosition("bottom");
} else {
setHUDPosition("top");
}
};
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
"data-active": isActive,
className: "gd-pointer-events-none gd-relative gd-z-[9999] data-[active=false]:gd-hidden",
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
"div",
{
className: [
"gd-fixed gd-inset-x-0 gd-inset-y-0 gd-z-50 gd-flex gd-h-full",
"data-[color=blue]:gd-bg-blue-700/[0.1] data-[color=blue]:gd-text-blue-400",
"data-[color=teal]:gd-bg-teal-700/[0.1] data-[color=teal]:gd-text-teal-400",
"data-[color=green]:gd-bg-green-700/[0.1] data-[color=green]:gd-text-green-400",
"data-[color=amber]:gd-bg-amber-700/[0.1] data-[color=amber]:gd-text-amber-400",
"data-[color=red]:gd-bg-red-700/[0.1] data-[color=red]:gd-text-red-400",
"data-[color=purple]:gd-bg-purple-700/[0.1] data-[color=purple]:gd-text-purple-400"
].join(" "),
"data-color": color,
style: {
maxWidth: maxWidth === "last-breakpoint" ? breakpointValues.slice(-1)[0]?.width ?? void 0 : void 0,
marginLeft: maxWidth === "last-breakpoint" ? "auto" : void 0,
marginRight: maxWidth === "last-breakpoint" ? "auto" : void 0
},
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"button",
{
type: "button",
className: "gd-pointer-events-auto gd-absolute gd-left-1/2 gd--translate-x-1/2 gd-overflow-hidden gd-rounded-[999px] gd-border-[1px] gd-border-current gd-bg-[black] gd-shadow-[0_0_5px_0_rgba(0,0,0,1)] data-[hud-position=bottom]:gd-bottom-[16px] data-[hud-position=top]:gd-top-[16px]",
onClick: changeHUDPosition,
"data-hud-position": HUDPosition,
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "gd-font-medium gd-px-[12px] gd-py-[4px] gd-font-sans gd-text-[white]/[0.9]", children: selectedBreakpoint })
}
),
Array.from({ length: columnsNumber }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
className: "gd-h-full gd-w-full gd-border-l-[1px] gd-border-l-current last:gd-border-r-[1px] last:gd-border-r-current",
style: { paddingLeft: gutterSize, paddingRight: gutterSize },
children: gutterSize > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "gd-h-full gd-w-full gd-border-l-[1px] gd-border-l-current last:gd-border-r-[1px] last:gd-border-r-current" })
},
index
))
]
}
)
}
);
}
GridOverlay.displayName = "GridOverlay";
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
GridOverlay
});
//# sourceMappingURL=index.cjs.map