Skip to content

Commit

Permalink
WIP(ui-top-nav-bar): add item and itemlist
Browse files Browse the repository at this point in the history
  • Loading branch information
joyenjoyer committed Sep 13, 2024
1 parent b93c859 commit 5bc2d60
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 62 deletions.
38 changes: 31 additions & 7 deletions packages/__docs__/src/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,7 @@ import {
} from 'react'

import { Alert } from '@instructure/ui-alerts'
import {
InstUISettingsProvider,
withStyle,
jsx,
Global
} from '@instructure/emotion'
import { InstUISettingsProvider, withStyle, jsx } from '@instructure/emotion'
import { Flex } from '@instructure/ui-flex'
import { Text } from '@instructure/ui-text'
import { View } from '@instructure/ui-view'
Expand All @@ -50,8 +45,14 @@ import { Link } from '@instructure/ui-link'
import { addMediaQueryMatchListener } from '@instructure/ui-responsive'
import type { QueriesMatching } from '@instructure/ui-responsive'
import {
IconHamburgerSolid,
IconAdminLine,
IconAlertsLine,
IconAnalyticsLine,
IconArrowOpenDownLine,
IconArrowOpenStartLine,
IconDashboardLine,
IconHeartLine,
IconUserLine,
IconXSolid
} from '@instructure/ui-icons'

Expand Down Expand Up @@ -799,6 +800,29 @@ class App extends Component<AppProps, AppState> {
</Link>
</MobileTopNav.BreadCrumb>
<MobileTopNav.Title>Courses</MobileTopNav.Title>
<MobileTopNav.ItemList>
<MobileTopNav.Item
leftIcon={<IconUserLine />}
rightIcon={<IconArrowOpenDownLine />}
onClick
>
Account
</MobileTopNav.Item>
<MobileTopNav.Item
leftIcon={<IconAdminLine />}
rightIcon={<IconArrowOpenDownLine />}
onClick
>
Admin
</MobileTopNav.Item>
<MobileTopNav.Item
leftIcon={<IconDashboardLine />}
rightIcon={<IconArrowOpenDownLine />}
onClick
>
Dashboard
</MobileTopNav.Item>
</MobileTopNav.ItemList>
</MobileTopNav>
<p>
1 Lorem ipsum dolor sit, amet consectetur adipisicing elit.
Expand Down
120 changes: 65 additions & 55 deletions packages/ui-top-nav-bar/src/MobileTopNav/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,23 @@
*/

/** @jsx jsx */
import { Children, Fragment, useState, useEffect } from 'react'
import type { PropsWithChildren } from 'react'
import React, {
Children,
Fragment,
PropsWithChildren,
useEffect,
useState
} from 'react'
import { jsx, useTheme } from '@instructure/emotion'
import type { MobileTopNavProps } from './props'

import { IconButton } from '@instructure/ui-buttons'
import { IconHamburgerLine, IconXLine } from '@instructure/ui-icons'
import {
generateItemListStyles,
generateItemStyles,
generateStyles
} from './styles'

/**
---
Expand All @@ -57,10 +67,10 @@ const MobileTopNav = ({
}

return (
<div css={styles.container(open)}>
<div css={styles.topBar}>
<div style={styles.container(open)}>
<div style={styles.topBar}>
{brand}
<span css={styles.btnRow}>
<span style={styles.btnRow}>
{!open && getSubComponent('BtnRow')}
<IconButton
withBackground={false}
Expand All @@ -77,6 +87,7 @@ const MobileTopNav = ({
<div style={styles.content(open)}>
{getSubComponent('BreadCrumb')}
{getSubComponent('Title')}
{getSubComponent('ItemList')}
<p>
1 Lorem ipsum dolor sit, amet consectetur adipisicing elit. Molestias
excepturi a blanditiis, aspernatur repellat repellendus dolores cum
Expand Down Expand Up @@ -148,72 +159,66 @@ const MobileTopNav = ({
)
}

const generateStyles = (props: MobileTopNavProps, theme: any) => {
const { lightMode } = props
return {
container: (open: boolean) => {
return {
height: '54px',
position: open ? 'fixed' : 'relative',
backgroundColor: lightMode
? theme.colors.ui.surfacePageSecondary
: theme.colors.ui.surfaceDark,
color: lightMode
? theme.colors.contrasts.grey125125
: theme.colors?.contrasts?.white1010,
width: '100%'
}
},
topBar: {
padding: `0 ${theme.spacing.small}`,
height: '54px',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
},
content: (open: boolean) => {
return {
padding: `0 ${theme.spacing.small}`,
height: open ? '100%' : '0px',
top: '54px',
bottom: 0,
left: 0,
right: 0,
overflow: open ? 'scroll' : 'hidden',
position: 'fixed',
backgroundColor: lightMode
? theme.colors.ui.surfacePageSecondary
: theme.colors.ui.surfaceDark,
color: lightMode
? theme.colors.contrasts.grey125125
: theme.colors?.contrasts?.white1010
}
},
btnRow: {
display: 'flex',
gap: '12px'
}
}
}

const BtnRow = ({ children }: PropsWithChildren) => {
return <Fragment>{children}</Fragment>
}

BtnRow.displayName = 'BtnRow'

const BreadCrumb = ({ children }: PropsWithChildren) => {
return <div css={{ margin: '24px 0' }}>{children}</div>
return <div style={{ margin: '24px 0' }}>{children}</div>
}

BreadCrumb.displayName = 'BreadCrumb'

const Title = ({ children }: PropsWithChildren) => {
return <div css={{ margin: '32px 0' }}>{children}</div>
return <div style={{ margin: '32px 0' }}>{children}</div>
}

Title.displayName = 'Title'

const ItemList = ({
children,
styles
}: PropsWithChildren & { styles: any }) => {
return (
<Fragment>
{Children.map(children, (child, index) => (
<Fragment>
{child}
{index < React.Children.count(children) - 1 && (
<div style={styles.divider}></div>
)}
</Fragment>
))}
</Fragment>
)
}

ItemList.displayName = 'ItemList'

const Item = ({
children,
leftIcon,
rightIcon,
onClick,
styles
}: PropsWithChildren & {
leftIcon: any
rightIcon: any
onClick: any
styles: any
}) => {
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
<div style={styles.container} onClick={onClick}>
{leftIcon && <div style={styles.leftIcon}>{leftIcon}</div>}
{children}
{rightIcon && <div style={styles.rightIcon}>{rightIcon}</div>}
</div>
)
}

const withStyles =
<ComponentOwnProps, ComponentStyle>(
generateStyles: (props: any, theme: any) => ComponentStyle
Expand All @@ -233,6 +238,11 @@ const SC: any = withStyles(generateStyles)(MobileTopNav)
SC.BtnRow = BtnRow
SC.BreadCrumb = BreadCrumb
SC.Title = Title
SC.ItemList = withStyles(generateItemListStyles)(ItemList)
// TODO investigate whether displayName should be added to the original component
SC.ItemList.displayName = 'ItemList'
SC.Item = withStyles(generateItemStyles)(Item) //withStyles(generateItemStyles)(Item)
SC.Item.displayName = 'Item'

export { SC as MobileTopNav }
export default SC
91 changes: 91 additions & 0 deletions packages/ui-top-nav-bar/src/MobileTopNav/styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 - present Instructure, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import type { MobileTopNavProps } from './props'

export const generateStyles = (props: MobileTopNavProps, theme: any) => {
const { lightMode } = props
return {
container: (open: boolean) => {
return {
height: '54px',
position: open ? 'fixed' : 'relative',
backgroundColor: lightMode
? theme.colors.ui.surfacePageSecondary
: theme.colors.ui.surfaceDark,
color: lightMode
? theme.colors.contrasts.grey125125
: theme.colors?.contrasts?.white1010,
width: '100%'
}
},
topBar: {
padding: `0 ${theme.spacing.small}`,
height: '54px',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
},
content: (open: boolean) => {
return {
padding: `0 ${theme.spacing.small}`,
height: open ? '100%' : '0px',
top: '3.375rem',
bottom: 0,
left: 0,
right: 0,
overflow: open ? 'scroll' : 'hidden',
position: 'fixed',
backgroundColor: lightMode
? theme.colors.ui.surfacePageSecondary
: theme.colors.ui.surfaceDark,
color: lightMode
? theme.colors.contrasts.grey125125
: theme.colors?.contrasts?.white1010
}
},
btnRow: {
display: 'flex',
gap: '12px'
}
}
}
export const generateItemListStyles = (_props: any, theme: any) => {
return {
divider: {
height: '0.0625rem',
overflow: 'hidden',
background: theme.colors.contrasts.grey1214
}
}
}
export const generateItemStyles = (_props: any, _theme: any) => {
return {
container: {
margin: '16px 0',
display: 'flex'
},
leftIcon: { paddingRight: '8px', fontSize: '18px' },
rightIcon: { marginLeft: 'auto', paddingRight: '8px', fontSize: '18px' }
}
}

0 comments on commit 5bc2d60

Please sign in to comment.