import React, { createContext, useContext, useMemo } from "react"; import { StyleSheet, useWindowDimensions, View, ViewStyle } from "react-native"; // Tipe untuk span type SpanValue = { base?: number; md?: number; lg?: number; }; // Props untuk Grid.Col interface ColProps { children: React.ReactNode; span?: number | SpanValue; style?: ViewStyle; } // Props untuk Grid interface GridProps { children: React.ReactNode; gap?: number; columns?: number; containerStyle?: ViewStyle; } // Context untuk menyimpan konfigurasi grid type GridContextType = { gap: number; columns: number; }; const GridContext = createContext({ gap: 0, columns: 12, }); const useGrid = () => useContext(GridContext); // Helper untuk menentukan span berdasarkan lebar layar const getSpan = ( spanProp: number | SpanValue | undefined, width: number ): number => { if (typeof spanProp === "number") return spanProp; const span = spanProp || { base: 12 }; if (width >= 992 && span.lg) return span.lg; if (width >= 768 && span.md) return span.md; return span.base ?? 12; }; // Grid Component const GridComponent: React.FC = ({ children, gap = 6, columns = 12, containerStyle, }) => { const contextValue = useMemo(() => ({ gap, columns }), [gap, columns]); return ( {React.Children.map(children, (child) => React.isValidElement(child) ? React.cloneElement(child as React.ReactElement, {}) : child )} ); }; // Grid.Col Component const Col: React.FC = ({ children, span, style }) => { const { gap, columns } = useGrid(); const { width } = useWindowDimensions(); const colSpan = getSpan(span, width); const margin = gap / 2; const styles = StyleSheet.create({ col: { flexBasis: `${(100 / columns) * colSpan}%`, paddingVertical: margin, // marginBottom: gap, marginBlock: gap, }, }); return {children}; }; // Export bersama-sama const Grid = Object.assign(GridComponent, { Col }); export default Grid; // Styles const styles = StyleSheet.create({ container: { flexDirection: "row", flexWrap: "wrap", justifyContent: "flex-start", marginInline: 0.1 }, });