Skip to content

Commit

Permalink
Add Nextjs demo application and deploy through sst.
Browse files Browse the repository at this point in the history
  • Loading branch information
brenzy committed May 29, 2024
1 parent 777301b commit f94f51b
Show file tree
Hide file tree
Showing 33 changed files with 2,247 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
npm run tokens:ci
- name: Build projects 🏗
run: npx nx run demo:build --skip-nx-cache
run: npx nx run next-demo:build --skip-nx-cache

- name: Lint
run: npm run lint:ci
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/deployment-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
npm run tokens:ci
- name: Build Demo App
run: npx nx run demo:build --skip-nx-cache
run: npx nx run next-demo:build --skip-nx-cache

- name: Lint
run: npm run lint:ci
Expand All @@ -60,7 +60,7 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1

## Deploy remix demo app with SST
## Deploy Nextjs demo app with SST
- name: Deploy Demo App to AWS
run: npx sst deploy --stage radius-pr

Expand All @@ -80,4 +80,4 @@ jobs:
with:
issue-number: ${{ github.event.pull_request.number }}
body: |
Demo App Preview: https://d11mwnosflssyy.cloudfront.net/
Demo App Preview: https://d3vy1i1e5adgl7.cloudfront.net
4 changes: 2 additions & 2 deletions .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
run: npm ci

- name: Build Demo App
run: npx nx run demo:build --skip-nx-cache
run: npx nx run next-demo:build --skip-nx-cache

## Run lint, test, and build for all affected projects
- run: NX_CLOUD_AUTH_TOKEN=${{ secrets.NX_CLOUD_AUTH_TOKEN }} npx nx affected --target=lint --parallel=3
Expand All @@ -53,6 +53,6 @@ jobs:
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1

## Deploy remix demo app with SST
## Deploy Nextjs demo app with SST
- name: Deploy Demo App to AWS
run: npx sst deploy --stage prod
2 changes: 1 addition & 1 deletion .github/workflows/merge-chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
npm run tokens:ci
- name: Build projects 🏗
run: npx nx run demo:build --skip-nx-cache
run: npx nx run next-demo:build --skip-nx-cache

# 👇 Adds Chromatic as a step in the workflow
- name: Publish to Chromatic
Expand Down
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,14 @@ apps/demo/public/brand/*
# Environment Variables
*.env

.nx/cache
.nx/cache

# Next.js
.next
out

# sst
.sst

# open-next
.open-next
2 changes: 1 addition & 1 deletion apps/demo/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": ["../../.eslintrc.json"],
"extends": ["../../.eslintrc"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
Expand Down
18 changes: 18 additions & 0 deletions apps/next-demo/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc"],
"ignorePatterns": ["!**/*", ".next/*", ".open-next/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
2 changes: 2 additions & 0 deletions apps/next-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
public/brand

24 changes: 24 additions & 0 deletions apps/next-demo/hooks/use-is-scrolled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useEffect, useState } from 'react';

/**
* A hook that returns true if the window has been scrolled, false otherwise.
*/
export const useIsScrolled = () => {
const [isScrolled, setIsScrolled] = useState(false);

useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 0);
};

// Call handleScroll immediately after the component mounts
handleScroll();

window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);

return isScrolled;
};
6 changes: 6 additions & 0 deletions apps/next-demo/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
declare module '*.svg' {
const content: any;
export const ReactComponent: any;
export default content;
}
11 changes: 11 additions & 0 deletions apps/next-demo/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: 'next-demo',
preset: '../../jest.preset.js',
transform: {
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest',
'^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/next/babel'] }],
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/apps/next-demo',
};
5 changes: 5 additions & 0 deletions apps/next-demo/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
16 changes: 16 additions & 0 deletions apps/next-demo/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
eslint: { ignoreDuringBuilds: true },
// Hardcode the dependencies here instead of getting them from the nx next plugin
// because sst calls build from the package.json and does not have access to the
// dependency graph.
transpilePackages: [
'@rangle/radius-foundations',
'@rangle/radius-react-core-components',
'@rangle/radius-shared',
'@rangle/radius-react-examples',
],
compiler: {
// For other options, see https://nextjs.org/docs/architecture/nextjs-compiler#emotion
emotion: true,
},
};
29 changes: 29 additions & 0 deletions apps/next-demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "next-demo",
"version": "0.0.1",
"scripts": {
"load-assets": "pwd && cp -r ../../libs/foundations/src/generated/brand public",
"dev": "npm run load-assets && npx next dev",
"build": "npm run load-assets && npx next build",
"start": "npx next start"
},
"dependencies": {
"@emotion/cache": "11.11.0",
"@emotion/css": "11.11.2",
"@emotion/react": "11.11.4",
"@emotion/server": "11.11.0",
"@emotion/styled": "11.11.0",
"axios": "1.6.8",
"next": "14.0.4",
"react": "18.3.1",
"react-dom": "18.3.1",
"sharp": "0.32.6",
"typescript": "5.4.5"
},
"devDependencies": {
"@nx/next": "^19.1.0",
"sst": "^2.42.0",
"aws-cdk-lib": "2.142.1",
"constructs": "10.3.0"
}
}
178 changes: 178 additions & 0 deletions apps/next-demo/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import '@rangle/radius-foundations/styles';
import { AppProps } from 'next/app';
import Head from 'next/head';
import { useState } from 'react';
import { ThemeContext } from '../shared/contexts';
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
const cache = createCache({ key: 'next' });
import { RadiusAutoLayout } from '@rangle/radius-react-core-components';
import { RadiusNav } from '@rangle/radius-react-examples';
import {
Github,
Figma,
ThemeBrush,
Twitter,
LinkedIn,
Instagram,
Youtube,
LightMode,
DarkMode,
radiusTokens,
} from '@rangle/radius-foundations';
import { css } from '@emotion/css';
import { useIsScrolled } from '../hooks/use-is-scrolled';

function CustomApp({ Component, pageProps }: AppProps) {
/** Temp helper to fix icon type collision due to the way they are exported */
type IconType = React.ComponentType<React.SVGProps<SVGSVGElement>>;

const modes = ['dark-mode', 'light-mode'];
const themes = ['wellness', 'healthcare'];
/** This should be integrated into a Page layout component, currently a WIP in design */
const pageMaxWidth = 1280;
const isScrolled = useIsScrolled();

const [mode, setMode] = useState(1);
const [theme, setTheme] = useState(1);

const toggleMode = () => {
setMode(mode ^ 1);
};

const toggleTheme = () => {
setTheme(theme ^ 1);
};

return (
<>
<Head>
<title>Radius Next Demo Application</title>
</Head>
<CacheProvider value={cache}>
<main className={`${themes[theme]} ${modes[mode]}`}>
<ThemeContext.Provider value={themes[theme]}>
<RadiusAutoLayout
width="fill-parent"
height="hug-contents"
fill={radiusTokens.component.color.navigation.background}
className={css`
position: sticky;
top: 0;
margin-bottom: calc(
var(${radiusTokens.component.spacing.layouts.gap.vertical}) *
-1
) !important;
box-shadow: ${isScrolled
? `var(${radiusTokens.component.shadow.navigation.scroll});`
: ''};
`}
>
<RadiusNav
linkIcons={[
{
'aria-label': 'See source on Github',
title: 'See source on Github',
href: 'https://github.com/rangle/radius-monorepo-react',
// I think they are currently using different instances of react types
icon: Github as IconType,
},
{
'aria-label': 'See designs on Figma',
title: 'See designs on Figma',
href: 'https://www.figma.com/file/zpDGiKGaY35SEnfKB2uzeZ/Radius-Demo-Site?type=design&t=GqzqcLwssKZzV8o7-0',
icon: Figma as IconType,
},
{
'aria-label': mode
? 'Switch to dark mode'
: 'Switch to light mode',
title: mode
? 'Switch to dark mode'
: 'Switch to light mode',
as: 'button',
onClick: toggleMode,
icon: (mode ? DarkMode : LightMode) as IconType,
},
{
'aria-label': `Switch to ${themes[theme ^ 1]} theme`,
title: `Switch to ${themes[theme ^ 1]} theme`,
as: 'button',
onClick: toggleTheme,
icon: ThemeBrush,
},
]}
logos={
<>
<a
href="#content"
data-radius-watch-token-changes
data-radius-target-selector="img"
data-radius-target-attribute="src"
data-radius-replace-value="/brand/{--brand}/assets/primary-logo-{--mode}.svg"
>
<RadiusAutoLayout
as="img"
alt={`${themes[theme]} logo`}
src={`/brand/${themes[theme]}/assets/primary-logo-light-mode.svg`}
style={{
height: `var(${radiusTokens.component.sizing.navigation.primaryLogo})`,
}}
/>
</a>
</>
}
navItems={[
{
href: '#',
label: 'Menu Item 1',
selected: true,
},
{
href: '#',
label: 'Menu Item 2',
},
{
href: '#',
label: 'Menu Item 3',
},
]}
socials={[
{
icon: Twitter as IconType,
href: '#',
'aria-label': 'Descriptive text',
},
{
icon: LinkedIn as IconType,
href: '#',
'aria-label': 'Descriptive text',
},
{
icon: Instagram as IconType,
href: '#',
'aria-label': 'Descriptive text',
},
{
icon: Youtube as IconType,
href: '#',
'aria-label': 'Descriptive text',
},
]}
className={css`
margin: 0 auto;
max-width: ${pageMaxWidth}px;
`}
// TODO: shadow is now a page-level concern since we are adding wrappers
// hasShadow={isScrolled}
/>
</RadiusAutoLayout>
<Component {...pageProps} />
</ThemeContext.Provider>
</main>
</CacheProvider>
</>
);
}

export default CustomApp;
Loading

0 comments on commit f94f51b

Please sign in to comment.