diff --git a/components/common/Footer.jsx b/components/common/Footer.jsx
index 5bd9438..0d4327d 100644
--- a/components/common/Footer.jsx
+++ b/components/common/Footer.jsx
@@ -9,7 +9,6 @@ const FooterWrap = styled.footer`
font-weight: 400;
letter-spacing: -.01em;
font-family: "SF Pro Text","SF Pro Icons","Helvetica Neue","Helvetica","Arial",sans-serif;
- min-width: 1024px;
overflow: hidden;
position: relative;
z-index: 1;
diff --git a/components/common/Header.jsx b/components/common/Header.jsx
index 4f930fe..7c3e428 100644
--- a/components/common/Header.jsx
+++ b/components/common/Header.jsx
@@ -5,6 +5,8 @@ import styled from 'styled-components'
import { ExternalLink } from "react-feather"
import Button from '@/components/common/Button';
import { Container } from '@/components/common/layout';
+import { mediaQueries } from '@/styles/breakpoints';
+import navigation from '@/data/navigation';
const Nav = styled.nav`
position: relative;
@@ -69,6 +71,9 @@ const MenuTray = styled.div`
display: flex;
align-items: center;
gap: 24px;
+ @media ${mediaQueries.sm} {
+ display: none;
+ }
`;
const MenuItems = styled.ul``;
const MenuItem = styled.li`
@@ -92,6 +97,7 @@ const MenuItem = styled.li`
&& a {
color: var(--foreground-color) !important;
opacity: 0.5;import { Container } from '@/components/common/Container';
+import { mediaQueries } from '../../styles/mediaQueries';
}
` : ``}
@@ -127,40 +133,18 @@ function Header() {
-
-
-
-
-
-
+ {navigation.map(item => {
+ const isExternal = item.href.match(/(https?:\/\/[\w\d.-]+)/gi);
+
+ return (
+
+ );
+ })}
diff --git a/components/common/Site.jsx b/components/common/Site.jsx
index 84b041a..b4a0dd2 100644
--- a/components/common/Site.jsx
+++ b/components/common/Site.jsx
@@ -2,6 +2,7 @@ import React, { useEffect, useContext } from "react";
import theme from "@/styles/theme";
import { ThemeProvider } from "styled-components";
import useColorScheme from "@/hooks/useColorScheme";
+import useWindowDimensions from '../../hooks/useWindowDimensions';
export const SiteContext = React.createContext({});
@@ -13,11 +14,10 @@ export const useSite = () => useContext(SiteContext);
const Site = ({ children }) => {
const { colorScheme, setColorScheme } = useColorScheme();
-
- console.log({ colorScheme })
+ const windowDimensions = useWindowDimensions();
return (
-
+
{children}
diff --git a/components/common/Typography.jsx b/components/common/Typography.jsx
index 29ad0e9..7182274 100644
--- a/components/common/Typography.jsx
+++ b/components/common/Typography.jsx
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import styled from 'styled-components';
-import getTypographyStyles from '../../styles/getTypographyStyles';
+import getTypographyStyles from '@/styles/getTypographyStyles';
const TypographyWrap = styled.p`
${({ variant }) => getTypographyStyles(variant)}
diff --git a/components/common/layout/Grid.jsx b/components/common/layout/Grid.jsx
index ceed243..49b8096 100644
--- a/components/common/layout/Grid.jsx
+++ b/components/common/layout/Grid.jsx
@@ -7,7 +7,6 @@ const Grid = styled.div`
${({ columns }) => getResponsivePropStyles(columns, (val) => `grid-template-columns: repeat(${val}, 1fr);`)}
${({ rowHeight }) => getResponsivePropStyles(rowHeight, (val) => `grid-auto-rows: ${getSpacing(val)};`)}
${({ gap }) => getResponsivePropStyles(gap, (val) => `gap: ${getSpacing(val)};`)}
-
`;
export default Grid;
diff --git a/components/common/layout/GridItem.jsx b/components/common/layout/GridItem.jsx
index b88e3d1..eaa1165 100644
--- a/components/common/layout/GridItem.jsx
+++ b/components/common/layout/GridItem.jsx
@@ -1,6 +1,7 @@
import React from "react";
import styled from "styled-components"
import getResponsivePropStyles from '@/styles/getResponsivePropStyles';
+import useVisibilityProps from '../../../hooks/useVisibilityProps';
const GridItemWrap = styled.div`
${({ $width }) => getResponsivePropStyles($width, (val) => `grid-column-start: ${Number(val ?? 1)} span;`)}
@@ -10,9 +11,11 @@ const GridItemWrap = styled.div`
`;
const GridItem = ({ children, width, height, as, ...props }) => {
- return (
+ const isVisible = useVisibilityProps(props);
+
+ return isVisible ? (
{children}
- )
+ ) : null;
}
export default GridItem;
diff --git a/components/common/layout/Section.jsx b/components/common/layout/Section.jsx
index ad30e6a..7c53ddf 100644
--- a/components/common/layout/Section.jsx
+++ b/components/common/layout/Section.jsx
@@ -2,6 +2,7 @@ import styled from "styled-components";
import RestrictedContainer from "./Container"
import getSpacing from '@/styles/spacing';
import getResponsivePropStyles from '@/styles/getResponsivePropStyles';
+import useVisibilityProps from "@/hooks/useVisibilityProps";
const SectionWrap = styled.section`
${({ gutter, gutterTop, gutterY }) => getResponsivePropStyles((gutterTop ?? gutterY ?? gutter ?? 8), (val) => `
@@ -24,6 +25,9 @@ const FullWidthContainer = styled.div`
export default function Section (props) {
let { children, className, contained, gutter, gutterTop, gutterBottom, gutterLeft, gutterRight, gutterX = true, gutterY } = props;
const Container = contained ? RestrictedContainer : FullWidthContainer;
+ const isVisible = useVisibilityProps(props);
+
+ if (!isVisible) return null;
const defaultGutterX = 3;
const defaultGutterY = 8;
diff --git a/components/pages/home/sections/FeaturesSection.jsx b/components/pages/home/sections/FeaturesSection.jsx
index 0249037..ff5a548 100644
--- a/components/pages/home/sections/FeaturesSection.jsx
+++ b/components/pages/home/sections/FeaturesSection.jsx
@@ -12,8 +12,8 @@ const FeaturesSection = () => {
This is a description of the features section.
-
-
+
+
Feature Title 1
@@ -22,7 +22,7 @@ const FeaturesSection = () => {
-
+
Feature Title 2
@@ -31,7 +31,7 @@ const FeaturesSection = () => {
-
+
Feature Title 4
@@ -40,7 +40,7 @@ const FeaturesSection = () => {
-
+
Feature Title 2
@@ -49,7 +49,7 @@ const FeaturesSection = () => {
-
+
Feature Title 3
diff --git a/components/pages/home/sections/IntroFeaturesSection.jsx b/components/pages/home/sections/IntroFeaturesSection.jsx
index 8a8dc24..285b4a2 100644
--- a/components/pages/home/sections/IntroFeaturesSection.jsx
+++ b/components/pages/home/sections/IntroFeaturesSection.jsx
@@ -6,7 +6,7 @@ import { Grid, GridItem, Section, Stack } from '@/components/common/layout';
const IntroFeaturesSection = () => {
return (
-
+
diff --git a/components/pages/home/sections/MoreFeaturesSection.jsx b/components/pages/home/sections/MoreFeaturesSection.jsx
index 3c760f2..347a1b7 100644
--- a/components/pages/home/sections/MoreFeaturesSection.jsx
+++ b/components/pages/home/sections/MoreFeaturesSection.jsx
@@ -12,8 +12,8 @@ const MoreFeaturesSection = () => {
This is a description of the features section.
-
-
+
+
Feature Title 1
@@ -22,7 +22,7 @@ const MoreFeaturesSection = () => {
-
+
Feature Title 4
@@ -31,7 +31,7 @@ const MoreFeaturesSection = () => {
-
+
Feature Title 2
@@ -40,7 +40,7 @@ const MoreFeaturesSection = () => {
-
+
Feature Title 3
@@ -49,7 +49,7 @@ const MoreFeaturesSection = () => {
-
+
Feature Title 2
diff --git a/components/pages/home/sections/SocialSection.jsx b/components/pages/home/sections/SocialSection.jsx
index bd6193f..188bfa4 100644
--- a/components/pages/home/sections/SocialSection.jsx
+++ b/components/pages/home/sections/SocialSection.jsx
@@ -6,7 +6,7 @@ import { Grid, GridItem, Section, Stack } from '@/components/common/layout';
const SocialSection = () => {
return (
-
+
{
This is a description of the why CodeEdit section.
-
+
diff --git a/data/navigation.js b/data/navigation.js
new file mode 100644
index 0000000..a4b4445
--- /dev/null
+++ b/data/navigation.js
@@ -0,0 +1,28 @@
+const navigation = [
+ {
+ href: '/',
+ label: 'CodeEdit',
+ },
+ {
+ href: 'whats-new',
+ label: 'What’s Included',
+ },
+ {
+ href: 'resources',
+ label: 'Resources',
+ },
+ {
+ href: 'developer',
+ label: 'Developer',
+ },
+ {
+ href: 'extensions',
+ label: 'Extensions',
+ },
+ {
+ href: 'https://github.com/CodeEditApp/CodeEdit',
+ label: 'GitHub',
+ },
+];
+
+export default navigation;
diff --git a/hooks/useVisibilityProps.js b/hooks/useVisibilityProps.js
new file mode 100644
index 0000000..ec42a2b
--- /dev/null
+++ b/hooks/useVisibilityProps.js
@@ -0,0 +1,52 @@
+import { useSite } from '@/components/common/Site';
+
+const useVisibilityProps = (props) => {
+ const {
+ windowDimensions: { breakpoint },
+ } = useSite();
+ const { show, hide } = props;
+
+ if (Object.hasOwnProperty.call(props, 'hide')) {
+ if (hide === true) {
+ return false;
+ }
+ if (typeof hide === 'string') {
+ if (hide === breakpoint) {
+ return false;
+ }
+ }
+ if (Array.isArray(hide)) {
+ if (hide.includes(breakpoint)) {
+ return false;
+ }
+ } else if (typeof hide === 'object') {
+ if (hide[breakpoint]) {
+ return false;
+ }
+ }
+ }
+
+ if (Object.hasOwnProperty.call(props, 'show')) {
+ if (!show) {
+ return false;
+ }
+ if (typeof show === 'string') {
+ if (show !== breakpoint) {
+ return false;
+ }
+ }
+ if (Array.isArray(show)) {
+ if (!show.includes(breakpoint)) {
+ return false;
+ }
+ } else if (typeof show === 'object') {
+ if (!show[breakpoint]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+};
+
+export default useVisibilityProps;
diff --git a/hooks/useWindowDimensions.js b/hooks/useWindowDimensions.js
new file mode 100644
index 0000000..33ec625
--- /dev/null
+++ b/hooks/useWindowDimensions.js
@@ -0,0 +1,26 @@
+import { getBreakpoint } from '@/styles/breakpoints';
+import { useState, useEffect } from 'react';
+
+const useWindowDimensions = () => {
+ const [windowDimensions, setWindowDimensions] = useState({});
+
+ useEffect(() => {
+ const handleResize = () => {
+ setWindowDimensions({
+ width: window.innerWidth,
+ height: window.innerHeight,
+ breakpoint: getBreakpoint(window.innerWidth),
+ });
+ };
+
+ window.addEventListener('resize', handleResize);
+
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ };
+ }, []);
+
+ return windowDimensions;
+};
+
+export default useWindowDimensions;
diff --git a/jsconfig.json b/jsconfig.json
index 46ced15..ae4d99a 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -3,9 +3,10 @@
"baseUrl": ".",
"paths": {
"@/components/*": ["./components/*"],
+ "@/data/*": ["./data/*"],
"@/hooks/*": ["./hooks/*"],
- "@/utils/*": ["./utils/*"],
- "@/styles/*": ["./styles/*"]
+ "@/styles/*": ["./styles/*"],
+ "@/utils/*": ["./utils/*"]
}
}
}
diff --git a/styles/breakpoints.js b/styles/breakpoints.js
new file mode 100644
index 0000000..76e3773
--- /dev/null
+++ b/styles/breakpoints.js
@@ -0,0 +1,75 @@
+export const breakpoints = {
+ xs: 500,
+ sm: 767,
+ md: 1068,
+ lg: 1440,
+ xl: 9999,
+};
+
+export const getBreakpoint = (width) => {
+ const { xs, sm, md, lg } = breakpoints;
+
+ if (width <= xs) {
+ return 'xs';
+ }
+ if (width > xs && width <= sm) {
+ return 'sm';
+ }
+ if (width > sm && width <= md) {
+ return 'md';
+ }
+ if (width > md && width <= lg) {
+ return 'lg';
+ }
+ if (width > lg) {
+ return 'xl';
+ }
+};
+
+export const mediaQueries = {
+ // small phones
+ xs: `only screen and (max-width: ${breakpoints.xs}px)`,
+ // most phones
+ sm: `only screen and (max-width: ${breakpoints.sm}px)`,
+ // tablets
+ md: `only screen and (max-width: ${breakpoints.md}px)`,
+ // large tablets and small desktops
+ lg: `only screen and (max-width: ${breakpoints.lg}px)`,
+ // large desktops
+ xl: `only screen and (min-width: ${breakpoints.lg + 1}px)`,
+};
+
+////////////////////////////////////
+// ... xs | sm | md | lg | xl ... //
+// ============================== //
+// min xs : 0 - Infinity //
+// ...------------------------... //
+// only xs : 0 - 499 //
+// ...----| //
+// max xs : 0 - 499 //
+// ...----| //
+// min sm : 500 - Infinity //
+// |-------------------... //
+// only sm : 500 - 733 //
+// |----| //
+// max sm : 0 - 734 //
+// ...---------| //
+// min md : 734 - Infinity //
+// |--------------... //
+// only md : 734 - 1068 //
+// |----| //
+// max md : 0 - 1068 //
+// ...--------------| //
+// min lg : 0 - 1440 //
+// ...-------------------| //
+// only lg : 0 - 1440 //
+// |----| //
+// max lg : 0 - 1440 //
+// ...-------------------| //
+// min xl : 1441 - Infinity //
+// |----... //
+// only xl : 1441 - Infinity //
+// |----... //
+// max xl : 0 - Infinity //
+// ...------------------------... //
+////////////////////////////////////
diff --git a/styles/getResponsivePropStyles.js b/styles/getResponsivePropStyles.js
index cf83ba4..0e1b269 100644
--- a/styles/getResponsivePropStyles.js
+++ b/styles/getResponsivePropStyles.js
@@ -1,4 +1,4 @@
-import mediaQueries from './mediaQueries';
+import { mediaQueries } from './breakpoints';
const getMediaQueryStyle = (size, val, getStyle) =>
Object.keys(val).includes(size)
diff --git a/styles/getTypographyStyles.js b/styles/getTypographyStyles.js
index 07b3634..4025751 100644
--- a/styles/getTypographyStyles.js
+++ b/styles/getTypographyStyles.js
@@ -1,4 +1,4 @@
-import mediaQueries from './mediaQueries';
+import { mediaQueries } from './breakpoints';
const getTypographyStyles = (variant) => {
switch (variant) {
diff --git a/styles/mediaQueries.js b/styles/mediaQueries.js
deleted file mode 100644
index 713f9ea..0000000
--- a/styles/mediaQueries.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const mediaQueries = {
- // small phones
- xs: `only screen and (max-width: 500px)`,
- // most phones
- sm: `only screen and (max-width: 734px)`,
- // tablets
- md: `only screen and (max-width: 1068px)`,
- // large tablets and small desktops
- lg: `only screen and (max-width: 1440px)`,
- // large desktops
- xl: `only screen and (min-width: 1441px)`,
-};
-
-export default mediaQueries;
diff --git a/styles/theme.js b/styles/theme.js
index 35dd7b4..d31824f 100644
--- a/styles/theme.js
+++ b/styles/theme.js
@@ -1,4 +1,4 @@
-import mediaQueries from './mediaQueries';
+import { mediaQueries } from './breakpoints';
import getResponsivePropStyles from './getResponsivePropStyles';
const theme = {