UNPKG

@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
"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