mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Updates to header, multi select behavior, add link button
This commit is contained in:
parent
8b732602a5
commit
ae991fb5cd
6 changed files with 146 additions and 202 deletions
|
|
@ -18,7 +18,7 @@ const CaretButton = (): JSX.Element => {
|
|||
width: '20px',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
bg: '#6A6968',
|
||||
bg: '$ctaBlue',
|
||||
border: '0px solid transparent',
|
||||
borderTopRightRadius: '5px',
|
||||
borderBottomRightRadius: '5px',
|
||||
|
|
@ -38,7 +38,8 @@ export const SplitButton = (props: SplitButtonProps): JSX.Element => {
|
|||
css={{
|
||||
display: 'flex',
|
||||
minWidth: '70px',
|
||||
bg: '#6A6968',
|
||||
bg: '$ctaBlue',
|
||||
color: '#EDEDED',
|
||||
fontSize: '12px',
|
||||
fontFamily: '$inter',
|
||||
border: '0px solid transparent',
|
||||
|
|
|
|||
|
|
@ -64,15 +64,14 @@ export function LibraryGridCard(props: LinkedItemCardProps): JSX.Element {
|
|||
css={{
|
||||
pl: '0px',
|
||||
padding: '0px',
|
||||
width: '320px',
|
||||
width: '293px',
|
||||
height: '100%',
|
||||
minHeight: '270px',
|
||||
background: 'white',
|
||||
borderRadius: '5px',
|
||||
borderWidth: '1px',
|
||||
borderStyle: 'solid',
|
||||
borderStyle: 'none',
|
||||
overflow: 'hidden',
|
||||
borderColor: '$thBorderColor',
|
||||
cursor: 'pointer',
|
||||
'@media (max-width: 930px)': {
|
||||
m: '15px',
|
||||
|
|
@ -88,6 +87,10 @@ export function LibraryGridCard(props: LinkedItemCardProps): JSX.Element {
|
|||
setIsHovered(false)
|
||||
}}
|
||||
onClick={(event) => {
|
||||
if (props.multiSelectMode !== 'off') {
|
||||
props.setIsChecked(props.item.id, !props.isChecked)
|
||||
return
|
||||
}
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
window.open(
|
||||
`/${props.viewer.profile.username}/${props.item.slug}`,
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export function LibraryListCard(props: LinkedItemCardProps): JSX.Element {
|
|||
height: '100%',
|
||||
cursor: 'pointer',
|
||||
gap: '10px',
|
||||
border: '1px solid $grayBorder',
|
||||
borderStyle: 'none',
|
||||
borderBottom: 'none',
|
||||
borderRadius: '6px',
|
||||
width: '100vw',
|
||||
|
|
@ -82,16 +82,14 @@ export function LibraryListCard(props: LinkedItemCardProps): JSX.Element {
|
|||
'@media (min-width: 1600px)': {
|
||||
width: '1340px',
|
||||
},
|
||||
boxShadow:
|
||||
'0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);',
|
||||
'@media (max-width: 930px)': {
|
||||
boxShadow: 'unset',
|
||||
borderRadius: 'unset',
|
||||
},
|
||||
}}
|
||||
alignment="start"
|
||||
distribution="start"
|
||||
onClick={(event) => {
|
||||
if (props.multiSelectMode !== 'off') {
|
||||
props.setIsChecked(props.item.id, !props.isChecked)
|
||||
return
|
||||
}
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
window.open(
|
||||
`/${props.viewer.profile.username}/${props.item.slug}`,
|
||||
|
|
|
|||
|
|
@ -633,12 +633,7 @@ const Footer = (): JSX.Element => {
|
|||
},
|
||||
}}
|
||||
>
|
||||
<PrimaryDropdown
|
||||
showThemeSection={true}
|
||||
showAddLinkModal={() => {
|
||||
console.log('show')
|
||||
}}
|
||||
/>
|
||||
<PrimaryDropdown showThemeSection={true} />
|
||||
<SpanBox css={{ marginLeft: 'auto', marginRight: '5px' }}>
|
||||
<SplitButton title="Add Link" />
|
||||
</SpanBox>
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ type LibraryHeaderProps = {
|
|||
showFilterMenu: boolean
|
||||
setShowFilterMenu: (show: boolean) => void
|
||||
|
||||
showAddLinkModal: () => void
|
||||
|
||||
numItemsSelected: number
|
||||
multiSelectMode: MultiSelectMode
|
||||
setMultiSelectMode: (mode: MultiSelectMode) => void
|
||||
|
|
@ -80,16 +78,15 @@ const controlWidths = (
|
|||
width: '95%',
|
||||
'@mdDown': {
|
||||
width: multiSelectMode !== 'off' ? '100%' : '95%',
|
||||
display: multiSelectMode !== 'off' ? 'flex' : 'none',
|
||||
},
|
||||
'@media (min-width: 930px)': {
|
||||
width: layout == 'GRID_LAYOUT' ? '660px' : '640px',
|
||||
width: layout == 'GRID_LAYOUT' ? '640px' : '640px',
|
||||
},
|
||||
'@media (min-width: 1280px)': {
|
||||
width: '1000px',
|
||||
width: '950px',
|
||||
},
|
||||
'@media (min-width: 1600px)': {
|
||||
width: '1340px',
|
||||
width: '1260px',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -100,9 +97,7 @@ export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
|
|||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('scroll', () =>
|
||||
setSmall(window.pageYOffset > 200)
|
||||
)
|
||||
window.addEventListener('scroll', () => setSmall(window.scrollY > 40))
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
|
@ -114,22 +109,19 @@ export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
|
|||
css={{
|
||||
top: '0',
|
||||
right: '0',
|
||||
left: LIBRARY_LEFT_MENU_WIDTH,
|
||||
zIndex: 5,
|
||||
bg: '$thLibraryBackground',
|
||||
position: 'fixed',
|
||||
left: LIBRARY_LEFT_MENU_WIDTH,
|
||||
height: small ? '60px' : DEFAULT_HEADER_HEIGHT,
|
||||
bg: 'red',
|
||||
transition: '0.5s',
|
||||
'@mdDown': {
|
||||
left: '0px',
|
||||
right: '0',
|
||||
height: small ? '60px' : DEFAULT_HEADER_HEIGHT,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{/* These will display/hide depending on breakpoints */}
|
||||
<LargeHeaderLayout {...props} />
|
||||
<SmallHeaderLayout {...props} />
|
||||
</VStack>
|
||||
|
||||
{/* This spacer is put in to push library content down
|
||||
|
|
@ -147,15 +139,6 @@ function LargeHeaderLayout(props: LibraryHeaderProps): JSX.Element {
|
|||
initialValue: [],
|
||||
isSessionStorage: false,
|
||||
})
|
||||
const [small, setSmall] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.addEventListener('scroll', () =>
|
||||
setSmall(window.pageYOffset > 200)
|
||||
)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<HStack
|
||||
|
|
@ -163,75 +146,50 @@ function LargeHeaderLayout(props: LibraryHeaderProps): JSX.Element {
|
|||
distribution="start"
|
||||
css={{
|
||||
gap: '10px',
|
||||
paddingLeft: '50px',
|
||||
paddingRight: '50px',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
'@mdDown': {
|
||||
display: 'none',
|
||||
},
|
||||
...controlWidths(props.layout, props.multiSelectMode),
|
||||
}}
|
||||
>
|
||||
<HeaderCheckboxIcon />
|
||||
<HeaderSearchIcon />
|
||||
|
||||
<SpanBox css={{ display: 'flex', marginLeft: 'auto' }}>
|
||||
{props.layout == 'LIST_LAYOUT' ? (
|
||||
<HeaderToggleGridIcon />
|
||||
) : (
|
||||
<HeaderToggleListIcon />
|
||||
)}
|
||||
</SpanBox>
|
||||
</HStack>
|
||||
)
|
||||
}
|
||||
|
||||
function SmallHeaderLayout(props: LibraryHeaderProps): JSX.Element {
|
||||
const [showInlineSearch, setShowInlineSearch] = useState(false)
|
||||
|
||||
return (
|
||||
<HStack
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
bg: '$thBackground3',
|
||||
'@md': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{showInlineSearch ? (
|
||||
<HStack css={{ pl: '10px', pr: '0px', width: '100%' }}>
|
||||
<SearchBox {...props} compact={true} />
|
||||
<Button
|
||||
style="cancelGeneric"
|
||||
onClick={(event) => {
|
||||
setShowInlineSearch(false)
|
||||
event.preventDefault()
|
||||
}}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
{props.multiSelectMode !== 'off' ? (
|
||||
<HStack alignment="center" css={{ width: '100% ' }}>
|
||||
<MultiSelectControls {...props} />
|
||||
</HStack>
|
||||
) : (
|
||||
<>
|
||||
{props.multiSelectMode === 'off' && <MenuHeaderButton {...props} />}
|
||||
<ControlButtonBox
|
||||
handleLinkSubmission={props.handleLinkSubmission}
|
||||
layout={props.layout}
|
||||
updateLayout={props.updateLayout}
|
||||
setShowInlineSearch={setShowInlineSearch}
|
||||
numItemsSelected={props.numItemsSelected}
|
||||
multiSelectMode={props.multiSelectMode}
|
||||
setMultiSelectMode={props.setMultiSelectMode}
|
||||
showAddLinkModal={props.showAddLinkModal}
|
||||
performMultiSelectAction={props.performMultiSelectAction}
|
||||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={props.applySearchQuery}
|
||||
allowSelectMultiple={props.allowSelectMultiple}
|
||||
/>
|
||||
<SpanBox
|
||||
css={{
|
||||
display: 'none',
|
||||
'@mdDown': { display: 'flex' },
|
||||
}}
|
||||
>
|
||||
<MenuHeaderButton {...props} />
|
||||
</SpanBox>
|
||||
<Button
|
||||
style="plainIcon"
|
||||
onClick={(e) => {
|
||||
props.setMultiSelectMode('visible')
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
<HeaderCheckboxIcon />
|
||||
</Button>
|
||||
<HeaderSearchIcon />
|
||||
<Button
|
||||
style="plainIcon"
|
||||
css={{ display: 'flex', marginLeft: 'auto' }}
|
||||
onClick={(e) => {
|
||||
props.updateLayout(
|
||||
props.layout == 'GRID_LAYOUT' ? 'LIST_LAYOUT' : 'GRID_LAYOUT'
|
||||
)
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
{props.layout == 'LIST_LAYOUT' ? (
|
||||
<HeaderToggleGridIcon />
|
||||
) : (
|
||||
<HeaderToggleListIcon />
|
||||
)}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</HStack>
|
||||
|
|
@ -468,8 +426,6 @@ type ControlButtonBoxProps = {
|
|||
updateLayout: (layout: LayoutType) => void
|
||||
setShowInlineSearch?: (show: boolean) => void
|
||||
|
||||
showAddLinkModal: () => void
|
||||
|
||||
allowSelectMultiple: boolean
|
||||
|
||||
numItemsSelected: number
|
||||
|
|
@ -667,97 +623,87 @@ const MuliSelectControl = (props: ControlButtonBoxProps): JSX.Element => {
|
|||
)
|
||||
}
|
||||
|
||||
function ControlButtonBox(props: ControlButtonBoxProps): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<HStack
|
||||
alignment="center"
|
||||
distribution={props.multiSelectMode !== 'off' ? 'center' : 'start'}
|
||||
css={{
|
||||
gap: '10px',
|
||||
...controlWidths(props.layout, props.multiSelectMode),
|
||||
}}
|
||||
>
|
||||
<MuliSelectControl {...props} />
|
||||
{props.multiSelectMode !== 'off' && (
|
||||
<SpanBox
|
||||
css={{
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
gap: '2px',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<SpanBox
|
||||
css={{
|
||||
color: '#55B938',
|
||||
paddingLeft: '5px',
|
||||
fontSize: '12px',
|
||||
fontWeight: '600',
|
||||
fontFamily: '$inter',
|
||||
'@xlgDown': {
|
||||
paddingLeft: '5px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{props.numItemsSelected}{' '}
|
||||
<SpanBox
|
||||
css={{
|
||||
'@media (max-width: 1280px)': { display: 'none' },
|
||||
}}
|
||||
>
|
||||
selected
|
||||
</SpanBox>
|
||||
</SpanBox>
|
||||
</SpanBox>
|
||||
)}
|
||||
{props.multiSelectMode !== 'off' ? (
|
||||
<>
|
||||
<MultiSelectControls {...props} />
|
||||
<SpanBox css={{ flex: 1 }}></SpanBox>
|
||||
</>
|
||||
) : (
|
||||
<SearchControlButtonBox {...props} />
|
||||
)}
|
||||
</HStack>
|
||||
// function ControlButtonBox(props: ControlButtonBoxProps): JSX.Element {
|
||||
// return (
|
||||
// <>
|
||||
|
||||
{props.setShowInlineSearch && props.multiSelectMode === 'off' && (
|
||||
<HStack
|
||||
alignment="center"
|
||||
distribution="end"
|
||||
css={{
|
||||
marginLeft: 'auto',
|
||||
marginRight: '20px',
|
||||
width: '100px',
|
||||
height: '100%',
|
||||
gap: '20px',
|
||||
'@md': {
|
||||
display: 'none',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
style="ghost"
|
||||
onClick={() => {
|
||||
props.setShowInlineSearch && props.setShowInlineSearch(true)
|
||||
}}
|
||||
css={{
|
||||
display: 'flex',
|
||||
}}
|
||||
>
|
||||
<MagnifyingGlass
|
||||
size={20}
|
||||
color={theme.colors.graySolid.toString()}
|
||||
/>
|
||||
</Button>
|
||||
<PrimaryDropdown
|
||||
showThemeSection={true}
|
||||
layout={props.layout}
|
||||
updateLayout={props.updateLayout}
|
||||
showAddLinkModal={props.showAddLinkModal}
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
// <SpanBox
|
||||
// css={{
|
||||
// flex: 1,
|
||||
// display: 'flex',
|
||||
// gap: '2px',
|
||||
// alignItems: 'center',
|
||||
// }}
|
||||
// >
|
||||
// <SpanBox
|
||||
// css={{
|
||||
// color: '#55B938',
|
||||
// paddingLeft: '5px',
|
||||
// fontSize: '12px',
|
||||
// fontWeight: '600',
|
||||
// fontFamily: '$inter',
|
||||
// '@xlgDown': {
|
||||
// paddingLeft: '5px',
|
||||
// },
|
||||
// }}
|
||||
// >
|
||||
// {props.numItemsSelected}{' '}
|
||||
// <SpanBox
|
||||
// css={{
|
||||
// '@media (max-width: 1280px)': { display: 'none' },
|
||||
// }}
|
||||
// >
|
||||
// selected
|
||||
// </SpanBox>
|
||||
// </SpanBox>
|
||||
// </SpanBox>
|
||||
// )}
|
||||
// {/* {props.multiSelectMode !== 'off' ? (
|
||||
// <>
|
||||
// <MultiSelectControls {...props} />
|
||||
// <SpanBox css={{ flex: 1 }}></SpanBox>
|
||||
// </>
|
||||
// ) : (
|
||||
// <SearchControlButtonBox {...props} />
|
||||
// )} */}
|
||||
// {/* </HStack> */}
|
||||
|
||||
// // {props.setShowInlineSearch && props.multiSelectMode === 'off' && (
|
||||
// // <HStack
|
||||
// // alignment="center"
|
||||
// // distribution="end"
|
||||
// // css={{
|
||||
// // marginLeft: 'auto',
|
||||
// // marginRight: '20px',
|
||||
// // width: '100px',
|
||||
// // height: '100%',
|
||||
// // gap: '20px',
|
||||
// // '@md': {
|
||||
// // display: 'none',
|
||||
// // },
|
||||
// // }}
|
||||
// // >
|
||||
// // <Button
|
||||
// // style="ghost"
|
||||
// // onClick={() => {
|
||||
// // props.setShowInlineSearch && props.setShowInlineSearch(true)
|
||||
// // }}
|
||||
// // css={{
|
||||
// // display: 'flex',
|
||||
// // }}
|
||||
// // >
|
||||
// // <MagnifyingGlass
|
||||
// // size={20}
|
||||
// // color={theme.colors.graySolid.toString()}
|
||||
// // />
|
||||
// // </Button>
|
||||
// // <PrimaryDropdown
|
||||
// // showThemeSection={true}
|
||||
// // layout={props.layout}
|
||||
// // updateLayout={props.updateLayout}
|
||||
// // />
|
||||
// // </HStack>
|
||||
// // )}
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -129,7 +129,8 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } =
|
|||
grayBorderHover: 'hsl(0 0% 78.0%)',
|
||||
grayText: '#6A6968',
|
||||
|
||||
// Semantic Colors
|
||||
ctaBlue: '#007AFF',
|
||||
|
||||
highlightBackground: '255, 210, 52',
|
||||
recommendedHighlightBackground: '#E5FFE5',
|
||||
highlight: '#FFD234',
|
||||
|
|
@ -172,7 +173,7 @@ export const { styled, css, theme, getCssText, globalCss, keyframes, config } =
|
|||
thBackgroundActive: '#FFEA9F',
|
||||
thBackgroundContrast: '#FFFFFF',
|
||||
thLeftMenuBackground: '#FCFCFC',
|
||||
thLibraryBackground: '#F3F3F3',
|
||||
thLibraryBackground: '#FFFFFF',
|
||||
thLibrarySearchbox: '#FCFCFC',
|
||||
thLibraryMenuPrimary: '#3D3D3D',
|
||||
thLibraryMenuSecondary: '#3D3D3D',
|
||||
|
|
@ -285,7 +286,7 @@ const darkThemeSpec = {
|
|||
thBackgroundActive: '#3D3D3D',
|
||||
thBackgroundContrast: '#000000',
|
||||
thLeftMenuBackground: '#343434',
|
||||
thLibraryBackground: '#333333',
|
||||
thLibraryBackground: '#2A2A2A',
|
||||
thLibrarySearchbox: '#3D3D3D',
|
||||
thLibraryMenuPrimary: '#EBEBEB',
|
||||
thLibraryMenuSecondary: '#EBEBEB',
|
||||
|
|
|
|||
Loading…
Reference in a new issue