Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sidebar Navigation #306

Draft
wants to merge 45 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
cd5f698
Figma export script
cbfrance Jul 17, 2023
1b38253
First pass exporting tailwind styles (not good)
cbfrance Jul 17, 2023
ded13fd
Second pass TailWind export as prototype
cbfrance Jul 17, 2023
674deae
WIP Prototyping with Figma Tailwind export
cbfrance Jul 17, 2023
653935d
WIP cleanup
cbfrance Aug 11, 2023
8d29e1c
WIP with Bart
cbfrance Aug 11, 2023
20e571c
Refine layout
cbfrance Aug 11, 2023
905adaa
Handle active state
cbfrance Aug 11, 2023
b739e03
SidebarNavigation based on DocMenu, with Cloud links
cbfrance Aug 11, 2023
d61cf40
Add placeholder
cbfrance Aug 11, 2023
ddd2f31
Add currentTeam
cbfrance Aug 11, 2023
6ea18a9
WIP icons
cbfrance Aug 12, 2023
bb84b14
Refine icon testing strategy
cbfrance Aug 12, 2023
52d44c0
Refine typography, layout
cbfrance Aug 14, 2023
6b38865
Navigation active indicator WIP
cbfrance Aug 14, 2023
7542f37
Refine borders
cbfrance Aug 14, 2023
c50dc26
Refactor nesting to avoid validation errors
cbfrance Aug 14, 2023
c6e048e
Refactoring active indicators WIP
cbfrance Aug 14, 2023
15db6fd
Refactor depth-specific active indicators
cbfrance Aug 14, 2023
a9d8447
Refactor transition
cbfrance Aug 14, 2023
ff91f6a
Render organization logo
cbfrance Aug 14, 2023
692a3a9
Refine header
cbfrance Aug 14, 2023
c304cca
WIP refactoring, fixing nested offsets
cbfrance Aug 16, 2023
f6d49f5
Active indicator offsets
cbfrance Aug 16, 2023
42074ac
Refine spacing
cbfrance Aug 16, 2023
5c40b89
Add right-side menu
cbfrance Aug 16, 2023
7d5527a
Refine viewport height
cbfrance Aug 16, 2023
017f25e
Add footer
cbfrance Aug 16, 2023
a10501f
Refine footer
cbfrance Aug 17, 2023
5329c67
NavigationLayout WIP
cbfrance Aug 17, 2023
b67d9b3
Fix interfaces, paths, icon size prop
cbfrance Aug 17, 2023
017a3c9
Remove relative paths
cbfrance Aug 17, 2023
00986de
Refine tests
cbfrance Aug 18, 2023
814b5d6
Refactor tests to use interface as args
cbfrance Aug 18, 2023
064c8cf
Fix relative paths
cbfrance Aug 18, 2023
1195e46
Refine assertions
cbfrance Aug 18, 2023
951d79f
Relax icon types to avoid warnings, WIP bg img
cbfrance Aug 18, 2023
cc15b8e
Add logo
cbfrance Aug 18, 2023
3ddfd35
Merge branch 'main' into chrisf/navigation-side
cbfrance Aug 21, 2023
7429826
Merge branch 'main' into chrisf/navigation-side
Aug 25, 2023
4a3b354
fix build by updating dependencies
Aug 25, 2023
b9a68e7
add rollup raw plugin for vite parity
Aug 29, 2023
cb0d643
add declaration files to the build tsconfig
Aug 29, 2023
49f8dd4
update type declarations
Aug 29, 2023
4838880
remove svgr
Aug 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"css.customData": ["./.vscode/css-data.json"],
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.tsdk": "node_modules/typescript/lib",
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"eslint.validate": ["javascript", "typescript", "vue"]
"eslint.validate": ["javascript", "typescript", "vue"],
"editor.formatOnPaste": true,
"editor.formatOnSave": true
}
13 changes: 13 additions & 0 deletions components/NavigationLayout/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script lang="ts" setup>
import NavigationLayout from '@cypress-design/vue-navigationlayout'
</script>

# NavigationLayout

<DemoWrapper>
<div>Demo Here</div>
</DemoWrapper>

Describe your component here.

[figma::NavigationLayout (to be updated)](https://www.figma.com/file/...)
104 changes: 104 additions & 0 deletions components/NavigationLayout/assertions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/// <reference types="cypress" />

import type { NavigationLayoutInterface } from '@cypress-design/constants-navigationlayout'
import type {
NavGroup,
NavItemLink,
IconInterface,
} from '@cypress-design/constants-SidebarNavigation'

import { IconGeneralPlaceholder } from '@cypress-design/react-icon'

// TODO: consider how to remove this interface, it seems probably unnecessary
interface IconGeneralPlaceholderProps extends IconInterface {}

// Data for SidebarNavigation
const menuItems: (NavItemLink | NavGroup)[] = [
{
text: 'Foo navigation item',
href: '#',
icon: IconGeneralPlaceholder as React.FC<IconGeneralPlaceholderProps>,
active: false,
},
{
text: 'Bar navigation item',
icon: IconGeneralPlaceholder,
items: [
{
text: 'Sub-item',
href: '#',
active: false,
},
{
text: 'Sub-item',
href: '#',
active: true,
},
{
text: 'Sub-item',
href: '#',
active: false,
},
],
},
{
text: 'Baz navigation item',
href: '#',
icon: IconGeneralPlaceholder,
},
]

// Data for NavigationLayout
const navigationLayoutStoryData = {
items: menuItems,
currentProject: 'Design System',
currentOrganization: {
name: 'Gatsby',
icon: IconGeneralPlaceholder,
},
projects: [
{ id: '1', label: 'project1' },
{ id: '2', label: 'project2' },
],
navigation: [
{
name: 'Cypress',
href: '#',
icon: IconGeneralPlaceholder,
current: true,
},
],
}

export default function assertions(
mountStory: (args: NavigationLayoutInterface) => void,
): void {
context('at 1280x720 resolution', () => {
beforeEach(() => {
cy.viewport(1280, 720)
})

it('renders', () => {
mountStory(navigationLayoutStoryData)

cy.get('nav').should('be.visible')
})
})

context('at iphone-5 resolution', () => {
beforeEach(() => {
cy.viewport('iphone-5')
})

it('displays mobile menu on click', () => {
mountStory(navigationLayoutStoryData)
// cy.get('nav .desktop-menu').should('not.be.visible')
// cy.get('nav .mobile-menu')
// .should('be.visible')
// .find('i.hamburger')
// .click()

// cy.get('ul.slideout-menu').should('be.visible')
})
})
}
23 changes: 23 additions & 0 deletions components/NavigationLayout/constants/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@cypress-design/constants-navigationlayout",
"private": true,
"version": "0.0.1",
"files": [
"*"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsc --project ./tsconfig.json"
},
"dependencies": {
"@cypress-design/constants-sidebarnavigation": "*"
},
"license": "MIT"
}
29 changes: 29 additions & 0 deletions components/NavigationLayout/constants/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type {
NavGroup,
NavItemLink,
} from '@cypress-design/constants-sidebarnavigation'

interface NavigationItem {
name: string
href: string
icon: any
current?: boolean
}

interface Project {
id: string
label: string
}

interface Organization {
name: string
icon: any
}

export interface NavigationLayoutInterface {
items: (NavItemLink | NavGroup)[]
currentProject: string
currentOrganization: Organization
projects: Project[]
navigation: NavigationItem[]
}
12 changes: 12 additions & 0 deletions components/NavigationLayout/constants/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../../../tsconfig.json",
"include": ["src/*.ts"],
"compilerOptions": {
"rootDir": "./src",
"noEmit": false,
"declaration": true,
"declarationMap": true,
"outDir": "dist",
"types": []
}
}
1 change: 1 addition & 0 deletions components/NavigationLayout/react/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @cypress-design/react-navigationlayout
22 changes: 22 additions & 0 deletions components/NavigationLayout/react/NavigationLayout.rootstory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react'

import type { NavigationLayoutInterface } from '@cypress-design/constants-navigationlayout'
import NavigationLayout from '@cypress-design/react-navigationlayout'

export default ({
items,
currentProject,
currentOrganization,
projects,
icon,
}: NavigationLayoutInterface) => {
return (
<NavigationLayout
items={items}
currentOrganization={currentOrganization}
currentProject={currentProject}
projects={projects}
icon={icon}
/>
)
}
139 changes: 139 additions & 0 deletions components/NavigationLayout/react/NavigationLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import * as React from 'react'
// import clsx from 'clsx'
// import { SharedSettings } from '@cypress-design/constants-navigationlayout'

// TODO fix this import, it I think it should be like this:
// import { SidebarNavigation } from '@cypress-design/SidebarNavigation'
import SidebarNavigation from '@cypress-design/react-sidebarnavigation'
import { NavigationLayoutInterface } from '@cypress-design/constants-navigationlayout'

import { Fragment, useState } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'

export default function NavigationLayout({
items,
currentProject,
currentOrganization,
projects,
}: NavigationLayoutInterface) {
const [sidebarOpen, setSidebarOpen] = useState(false)

return (
<>
<div>
<Transition.Root show={sidebarOpen} as={Fragment}>
<Dialog
as="div"
className="relative z-50 lg:hidden"
onClose={setSidebarOpen}
>
<Transition.Child
as={Fragment}
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-gray-900/80" />
</Transition.Child>

<div className="fixed inset-0 flex">
<Transition.Child
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="-translate-x-full"
>
<Dialog.Panel className="relative mr-16 flex w-full max-w-xs flex-1">
<Transition.Child
as={Fragment}
enter="ease-in-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in-out duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="absolute left-full top-0 flex w-16 justify-center pt-5">
<button
type="button"
className="-m-2.5 p-2.5"
onClick={() => setSidebarOpen(false)}
>
<span className="sr-only">Close sidebar</span>
<XMarkIcon
className="h-6 w-6 text-white"
aria-hidden="true"
/>
</button>
</div>
</Transition.Child>
<SidebarNavigation
items={items}
currentProject={currentProject}
currentOrganization={currentOrganization}
projects={projects}
/>
</Dialog.Panel>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>

{/* Static sidebar for desktop */}
<div className="hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-72 lg:flex-col">
{/* Sidebar component, swap this element with another sidebar if you like */}
<div className="flex grow flex-col gap-y-5 overflow-y-auto border-r border-gray-200 bg-white px-6">
<SidebarNavigation
items={items}
currentProject={currentProject}
currentOrganization={currentOrganization}
projects={projects}
/>
</div>
</div>

<div className="sticky top-0 z-40 flex items-center gap-x-6 bg-white px-4 py-4 shadow-sm sm:px-6 lg:hidden">
<button
type="button"
className="-m-2.5 p-2.5 text-gray-700 lg:hidden"
onClick={() => setSidebarOpen(true)}
>
<span className="sr-only">Open sidebar</span>
<Bars3Icon className="h-6 w-6" aria-hidden="true" />
</button>
<div className="flex-1 text-sm font-semibold leading-6 text-gray-900">
Cypress
</div>
<a href="#">
<span className="sr-only">Eric Kostom</span>
<img
className="h-8 w-8 rounded-full bg-gray-50"
// src=""
alt=""
/>
</a>
</div>

<main className="lg:pl-72">
<div className="xl:pl-96">
<div className="px-4 py-10 sm:px-6 lg:px-8 lg:py-6">
<p>Hello main area</p>
</div>
</div>
</main>

<aside className="fixed inset-y-0 left-72 hidden w-96 overflow-y-auto border-r border-gray-200 px-4 py-6 sm:px-6 lg:px-8 xl:block">
{/* Secondary column (hidden on smaller screens) */}
<p>Cypress Support</p>
</aside>
</div>
</>
)
}
31 changes: 31 additions & 0 deletions components/NavigationLayout/react/NavigationLayoutReact.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react'
import { mount } from 'cypress/react18'
import NavigationLayoutStory from './NavigationLayout.rootstory'
import assertions from '../assertions'
import { NavigationLayoutInterface } from '../constants/dist'

describe(
'NavigationLayout',
{ viewportHeight: 800, viewportWidth: 300 },
() => {
function mountStory(args: NavigationLayoutInterface) {
const {
items,
currentProject,
currentOrganization,
projects,
navigation,
} = args
mount(
<NavigationLayoutStory
items={items}
currentProject={currentProject}
currentOrganization={currentOrganization}
projects={projects}
navigation={navigation}
/>,
)
}
assertions(mountStory)
},
)
Loading
Loading