[
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# next.js\n/.next/\n/out/\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# local env files\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\n# vercel\n.vercel\n"
  },
  {
    "path": ".nvmrc",
    "content": "v18.17.0\n"
  },
  {
    "path": "README.md",
    "content": "# 🍃 Next.js Leaflet Starter\n\nJumpstart your new Next.js mapping project with Leaflet!\n\n## ⚡ Quick Deploy\n[![Deploy with Vercel Now](https://zeit.co/button)](https://vercel.com/import/project?template=https://github.com/colbyfayock/next-leaflet-starter) [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/colbyfayock/next-leaflet-starter)\n\n\n## 🧰 What This Includes\n* [Next.js](https://nextjs.org/)\n* [Leaflet](https://leafletjs.com/)\n* [React Leaflet](https://react-leaflet.js.org)\n\n## 🚀 Getting Started\n\n### Requirements\n\n### Quick Start\n\n```\nnpx create-next-app -e https://github.com/colbyfayock/next-leaflet-starter\n```\n\n### Running the Project\nFirst, run the development server:\n\n```bash\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) with your browser to see the result.\n\nYou can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.\n"
  },
  {
    "path": "jsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \"./\",\n    \"paths\": {\n      \"@components/*\": [ \"src/components/*\" ],\n      \"@styles/*\": [ \"src/styles/*\" ]\n    }\n  }\n}"
  },
  {
    "path": "next.config.js",
    "content": "const path = require('path');\nconst CopyPlugin = require('copy-webpack-plugin');\n\n/** @type {import('next').NextConfig} */\n\nconst nextConfig = {\n  reactStrictMode: true,\n  webpack: (config) => {\n    config.plugins.push(\n      new CopyPlugin({\n        patterns: [\n          {\n            from: 'node_modules/leaflet/dist/images',\n            to: path.resolve(__dirname, 'public', 'leaflet', 'images')\n          },\n        ],\n      }),\n    )\n    return config\n  }\n}\n\nmodule.exports = nextConfig;"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"next-leaflet-starter\",\n  \"homepage\": \"https://next-leaflet-starter.netlify.app\",\n  \"version\": \"0.1.0\",\n  \"license\": \"MIT\",\n  \"author\": \"Colby Fayock <hello@colbyfayock.com>\",\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"export\": \"next export\",\n    \"start\": \"next start\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/colbyfayock/next-leaflet-starter\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/colbyfayock/next-leaflet-starter/issues\"\n  },\n  \"dependencies\": {\n    \"copy-webpack-plugin\": \"^11.0.0\",\n    \"leaflet\": \"^1.9.4\",\n    \"next\": \"^14.0.1\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-icons\": \"^4.11.0\",\n    \"react-leaflet\": \"^4.2.1\",\n    \"sass\": \"^1.69.5\"\n  }\n}\n"
  },
  {
    "path": "src/components/Button/Button.js",
    "content": "import Link from 'next/link';\nimport styles from './Button.module.scss';\n\nconst Button = ({children, href, className, ...rest}) => {\n  let buttonClassName = styles.button;\n\n  if (className) {\n    buttonClassName = `${buttonClassName} ${className}`;\n  }\n\n  const buttonProps = {\n    className: buttonClassName,\n    ...rest,\n  };\n\n  if (href) {\n    if ( href.startsWith('/') ) {\n      return (\n        <Link href={href} {...buttonProps}>\n          {children}\n        </Link>\n      );\n    }\n    return (\n      <a href={href} {...buttonProps}>\n        {children}\n      </a>\n    );\n  }\n\n  return (\n    <button {...buttonProps}>\n      {children}\n    </button>\n  );\n};\n\nexport default Button;\n"
  },
  {
    "path": "src/components/Button/Button.module.scss",
    "content": "@import \"@styles/settings/_settings\";\n\n.button {\n  display: inline-flex;\n  justify-content: center;\n  align-items: center;\n  color: white;\n  font-size: 1em;\n  font-weight: bold;\n  font-family: inherit;\n  text-transform: uppercase;\n  text-align: center;\n  text-decoration: none;\n  background-color: $color-green;\n  padding: 1em 1.4em;\n  border: 0;\n  border-radius: .2em;\n  cursor: pointer;\n\n  &:hover {\n    background-color: lighten($color-green, 10);\n  }\n\n  &:disabled {\n    color: rgba(white, 0.5);\n    background-color: lighten($color-green, 10);\n    cursor: default;\n    opacity: .6;\n  }\n}"
  },
  {
    "path": "src/components/Button/index.js",
    "content": "export { default } from './Button';\n"
  },
  {
    "path": "src/components/Container/Container.js",
    "content": "import styles from './Container.module.scss';\n\nconst Container = ({ children, className, ...rest }) => {\n  let containerClassName = styles.container;\n\n  if (className) {\n    containerClassName = `${containerClassName} ${className}`;\n  }\n\n  return (\n    <div className={containerClassName} {...rest}>\n      {children}\n    </div>\n  );\n};\n\nexport default Container;\n"
  },
  {
    "path": "src/components/Container/Container.module.scss",
    "content": ".container {\n  width: 100%;\n  max-width: 1024px;\n  padding: 0 2em;\n  margin: 0 auto;\n\n  @media (max-width: 720px) {\n    padding: 0 1em;\n  }\n\n  h2,\n  h3,\n  h4,\n  p,\n  ul {\n    &:first-child {\n      margin-top: 0;\n    }\n\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n}\n"
  },
  {
    "path": "src/components/Container/index.js",
    "content": "export { default } from './Container';\n"
  },
  {
    "path": "src/components/Footer/Footer.js",
    "content": "import Container from '@components/Container';\n\nimport styles from './Footer.module.scss';\n\nconst Footer = ({ ...rest }) => {\n  return (\n    <footer className={styles.footer} {...rest}>\n      <Container className={`${styles.footerContainer} ${styles.footerLegal}`}>\n        <p>\n          &copy; <a href=\"https://spacejelly.dev\">Next.js Leaflet Starter</a>, {new Date().getFullYear()}\n        </p>\n      </Container>\n    </footer>\n  );\n};\n\nexport default Footer;\n"
  },
  {
    "path": "src/components/Footer/Footer.module.scss",
    "content": "@import \"@styles/settings/_settings\";\n\n.footer {\n  width: 100%;\n  color: white;\n  background-color: black;\n  padding: 1.2em 0;\n\n  a {\n    color: inherit;\n  }\n\n  p {\n\n    margin: 0 0 .5em;\n\n    &:last-child {\n      margin-bottom: 0;\n    }\n\n  }\n}\n\n.footerContainer {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  justify-content: center;\n  flex-direction: column;\n  margin-bottom: 0.4em;\n\n  @media (max-width: 720px) {\n    flex-wrap: wrap;\n  }\n\n  &:last-child {\n    margin-bottom: 0;\n  }\n}\n\n.footerLinks {\n  display: flex;\n  list-style: none;\n  padding: 0;\n  margin: 0 2em;\n\n  @media (max-width: 720px) {\n    width: 100%;\n    align-items: center;\n    justify-content: center;\n    margin: 0;\n  }\n\n  li {\n    margin: 0 0.8em;\n\n    &:first-child {\n      margin-left: 0;\n    }\n\n    &:last-child {\n      margin-right: 0;\n    }\n  }\n\n  a {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    text-decoration: none;\n\n    svg {\n      margin-right: 0.4em;\n    }\n  }\n}\n\n.footerLegal {\n  a {\n    text-decoration: underline;\n  }\n}\n"
  },
  {
    "path": "src/components/Footer/index.js",
    "content": "export { default } from './Footer';\n"
  },
  {
    "path": "src/components/Header/Header.js",
    "content": "import Link from 'next/link';\nimport { FaGithub } from 'react-icons/fa';\n\nimport Container from '@components/Container';\n\nimport styles from './Header.module.scss';\n\nconst Header = () => {\n  return (\n    <header className={styles.header}>\n      <Container className={styles.headerContainer}>\n        <p className={styles.headerTitle}>\n          <Link href=\"/\">\n            Next.js Leaflet Starter\n          </Link>\n        </p>\n        <ul className={styles.headerLinks}>\n          <li>\n            <a href=\"https://github.com/colbyfayock/next-leaflet-starter\" rel=\"noreferrer\">\n              <FaGithub />\n            </a>\n          </li>\n        </ul>\n      </Container>\n    </header>\n  );\n};\n\nexport default Header;\n"
  },
  {
    "path": "src/components/Header/Header.module.scss",
    "content": "@import \"@styles/settings/_settings\";\n\n.header {\n  width: 100%;\n  font-size: 1em;\n  color: white;\n  background-color: black;\n  padding: 1em 0;\n  margin: 0;\n}\n\n.headerContainer {\n\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 100%;\n\n}\n\n.headerTitle {\n  font-size: 1.6em;\n  font-weight: bold;\n  margin: 0;\n}\n\n.headerLogo {\n  height: 1.6em;\n}\n\n.headerLinks {\n  display: flex;\n  list-style: none;\n  padding: 0;\n  margin: 0;\n\n  li {\n    margin: 0 0.8em;\n\n    &:first-child {\n      margin-left: 0;\n    }\n\n    &:last-child {\n      margin-right: 0;\n    }\n  }\n\n  a {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n\n    svg {\n      margin-right: 0.4em;\n    }\n  }\n}\n"
  },
  {
    "path": "src/components/Header/index.js",
    "content": "export { default } from './Header';\n"
  },
  {
    "path": "src/components/Layout/Layout.js",
    "content": "import Head from 'next/head';\n\nimport Header from '@components/Header';\nimport Footer from '@components/Footer';\n\nimport styles from './Layout.module.scss';\n\nconst Layout = ({ children, className, ...rest }) => {\n  return (\n    <div className={styles.layout}>\n      <Head>\n        <link rel=\"icon\" href=\"/favicon.ico\" />\n      </Head>\n      <Header />\n      <main className={styles.main}>{children}</main>\n      <Footer />\n    </div>\n  );\n};\n\nexport default Layout;\n"
  },
  {
    "path": "src/components/Layout/Layout.module.scss",
    "content": ".layout {\n  display: grid;\n  grid-template-rows: auto 1fr auto;\n  overflow: hidden;\n  min-height: 100vh;\n}\n\n.main {\n  padding: 0 0 3em;\n}\n"
  },
  {
    "path": "src/components/Layout/index.js",
    "content": "export { default } from './Layout';\n"
  },
  {
    "path": "src/components/Map/DynamicMap.js",
    "content": "import { useEffect } from 'react';\nimport Leaflet from 'leaflet';\nimport * as ReactLeaflet from 'react-leaflet';\nimport 'leaflet/dist/leaflet.css';\n\nimport styles from './Map.module.scss';\n\nconst { MapContainer } = ReactLeaflet;\n\nconst Map = ({ children, className, width, height, ...rest }) => {\n  let mapClassName = styles.map;\n\n  if ( className ) {\n    mapClassName = `${mapClassName} ${className}`;\n  }\n\n  useEffect(() => {\n    (async function init() {\n      delete Leaflet.Icon.Default.prototype._getIconUrl;\n      Leaflet.Icon.Default.mergeOptions({\n        iconRetinaUrl: 'leaflet/images/marker-icon-2x.png',\n        iconUrl: 'leaflet/images/marker-icon.png',\n        shadowUrl: 'leaflet/images/marker-shadow.png',\n      });\n    })();\n  }, []);\n\n  return (\n    <MapContainer className={mapClassName} {...rest}>\n      {children(ReactLeaflet, Leaflet)}\n    </MapContainer>\n  )\n}\n\nexport default Map;\n"
  },
  {
    "path": "src/components/Map/Map.js",
    "content": "import dynamic from 'next/dynamic';\n\nconst DynamicMap = dynamic(() => import('./DynamicMap'), {\n  ssr: false\n});\n\n// Set default sizing to control aspect ratio which will scale responsively\n// but also help avoid layout shift\n\nconst DEFAULT_WIDTH = 600;\nconst DEFAULT_HEIGHT = 600;\n\nconst Map = (props) => {\n  const { width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT } = props;\n  return (\n    <div style={{ aspectRatio: width / height }}>\n      <DynamicMap {...props} />\n    </div>\n  )\n}\n\nexport default Map;"
  },
  {
    "path": "src/components/Map/Map.module.scss",
    "content": ".map {\n  width: 100%;\n  height: 100%;\n}"
  },
  {
    "path": "src/components/Map/index.js",
    "content": "export { default } from './Map';"
  },
  {
    "path": "src/components/Section/Section.js",
    "content": "import { forwardRef } from 'react';\n\nimport styles from './Section.module.scss';\n\nconst Section = forwardRef(function Section(props, ref) {\n  const { children, className, backgroundColor, ...rest } = props;\n\n  let sectionClassName = styles.section;\n\n  if (className) {\n    sectionClassName = `${sectionClassName} ${className}`;\n  }\n\n  return (\n    <section ref={ref} className={sectionClassName} data-background-color={backgroundColor} {...rest}>\n      {children}\n    </section>\n  );\n});\n\nexport default Section;\n"
  },
  {
    "path": "src/components/Section/Section.module.scss",
    "content": ".section {\n  padding: 1em 0;\n  margin: 1em 0;\n\n  @media (min-width: 720px) {\n    padding: 2em 0;\n    margin: 3em 0;\n  }\n}\n"
  },
  {
    "path": "src/components/Section/index.js",
    "content": "export { default } from './Section';\n"
  },
  {
    "path": "src/pages/_app.js",
    "content": "import '@styles/globals.scss'\n\nfunction MyApp({ Component, pageProps }) {\n  return <Component {...pageProps} />\n}\n\nexport default MyApp\n"
  },
  {
    "path": "src/pages/api/hello.js",
    "content": "// Next.js API route support: https://nextjs.org/docs/api-routes/introduction\n\nexport default (req, res) => {\n  res.statusCode = 200\n  res.json({ name: 'John Doe' })\n}\n"
  },
  {
    "path": "src/pages/index.js",
    "content": "import Head from 'next/head';\n\nimport Layout from '@components/Layout';\nimport Section from '@components/Section';\nimport Container from '@components/Container';\nimport Map from '@components/Map';\nimport Button from '@components/Button';\n\nimport styles from '@styles/Home.module.scss';\n\nconst DEFAULT_CENTER = [38.907132, -77.036546]\n\nexport default function Home() {\n  return (\n    <Layout>\n      <Head>\n        <title>Next.js Leaflet Starter</title>\n        <meta name=\"description\" content=\"Create mapping apps with Next.js Leaflet Starter\" />\n        <link rel=\"icon\" href=\"/favicon.ico\" />\n      </Head>\n\n      <Section>\n        <Container>\n          <h1 className={styles.title}>\n            Next.js Leaflet Starter\n          </h1>\n\n          <Map className={styles.homeMap} width=\"800\" height=\"400\" center={DEFAULT_CENTER} zoom={12}>\n            {({ TileLayer, Marker, Popup }) => (\n              <>\n                <TileLayer\n                  url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\n                  attribution=\"&copy; <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors\"\n                />\n                <Marker position={DEFAULT_CENTER}>\n                  <Popup>\n                    A pretty CSS3 popup. <br /> Easily customizable.\n                  </Popup>\n                </Marker>\n              </>\n            )}\n          </Map>\n\n          <p className={styles.description}>\n            <code className={styles.code}>npx create-next-app -e https://github.com/colbyfayock/next-leaflet-starter</code>\n          </p>\n\n          <p className={styles.view}>\n            <Button href=\"https://github.com/colbyfayock/next-leaflet-starter\">Vew on GitHub</Button>\n          </p>\n        </Container>\n      </Section>\n    </Layout>\n  )\n}\n"
  },
  {
    "path": "src/styles/Home.module.scss",
    "content": ".title {\n  font-size: 3rem;\n  line-height: 1.15;\n  text-align: center;\n  margin: 0 0 1em;\n}\n\n.description {\n  font-size: 1.5rem;\n  line-height: 1.5;\n  text-align: center;\n}\n\n.view {\n  text-align: center;\n  margin-top: 3em;\n}\n\n.code {\n  background: #fafafa;\n  border-radius: 5px;\n  padding: 0.75rem;\n  font-size: 1.1rem;\n  font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,\n    Bitstream Vera Sans Mono, Courier New, monospace;\n}"
  },
  {
    "path": "src/styles/globals.scss",
    "content": "html,\nbody {\n  padding: 0;\n  margin: 0;\n  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,\n    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;\n}\n\na {\n  color: inherit;\n  text-decoration: none;\n}\n\n* {\n  box-sizing: border-box;\n}\n\nimg {\n  max-width: 100%;\n  height: auto;\n}"
  },
  {
    "path": "src/styles/settings/__colors.scss",
    "content": "$color-green: #5fbb9d;"
  },
  {
    "path": "src/styles/settings/_settings.scss",
    "content": "@import \"_colors\";"
  }
]