react-icons/bs#BsArrowUpShort JavaScript Examples
The following examples show how to use
react-icons/bs#BsArrowUpShort.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: LineageFilter.jsx From covince with MIT License | 4 votes |
LineageFilter = (props) => {
const {
allSelected,
className,
emptyMessage,
fixedLayout,
heading = defaultHeading,
isMobile,
sortedLineages,
toggleAll,
toggleLineage
} = props
const isScrolling = useMemo(() => {
return fixedLayout || sortedLineages.length > (isMobile ? 9 : 10)
}, [fixedLayout, sortedLineages, isMobile])
const sections = useMemo(() => {
if (!isScrolling) {
return [sortedLineages]
}
const sectionSize = isMobile ? 9 : 8
const _sections = []
const numSections = Math.ceil(sortedLineages.length / sectionSize) || 1
for (let i = 0; i < numSections; i++) {
const start = i * sectionSize
_sections.push(sortedLineages.slice(start, start + sectionSize))
}
return _sections
}, [sortedLineages, isMobile])
const { nomenclature } = useNomenclature()
const isLarge = useScreen('lg')
const gridStyle = useMemo(() => {
const style = {
scrollSnapAlign: 'start',
scrollSnapStop: 'always'
}
if (isMobile) {
return style
}
const numLineages = sortedLineages.length
const maxColumns = isScrolling ? 4 : 5
const numColumns =
isLarge && fixedLayout
? maxColumns
: Math.max(2, Math.min(Math.ceil(numLineages / 2), maxColumns))
return {
...style,
gridTemplateColumns: `repeat(${numColumns}, minmax(0, 1fr))`
}
}, [sortedLineages, fixedLayout, isScrolling, isMobile, isLarge])
const scrollContainer = useRef()
const userScrolled = useRef(false)
const doScroll = useCallback((direction) => {
const { height } = scrollContainer.current.getBoundingClientRect()
scrollContainer.current.scrollBy({
top: height * direction,
behavior: 'smooth'
})
userScrolled.current = true
}, [])
const sectionRefs = useRef([])
const [currentSection, setCurrentSection] = useState(null)
useEffect(() => {
const callback = entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const index = (sectionRefs.current).indexOf(entry.target)
setCurrentSection(index)
}
})
}
const observer = new IntersectionObserver(callback, {
root: scrollContainer.current,
threshold: 0.6
})
sectionRefs.current.filter(s => s).forEach(section => {
observer.observe(section)
})
return function cleanup () {
observer.disconnect()
}
}, [sections])
const scrollUpBtnRef = useRef(null)
const scrollDownBtnRef = useRef(null)
useEffect(() => {
if (isMobile || userScrolled.current === false) {
return
}
if (currentSection === 0) {
scrollDownBtnRef.current.focus()
} else if (currentSection === sections.length - 1) {
scrollUpBtnRef.current.focus()
}
}, [isMobile, currentSection])
return (
<div className={className}>
<header className='flex justify-between space-x-6'>
{heading}
<div className='flex items-center'>
<label
htmlFor='lineage_toggle_all'
className='pr-2 text-primary text-xs uppercase tracking-wide font-bold leading-5'
>
toggle all
</label>
<Checkbox
className='text-xs text-primary mx-auto flex-row-reverse'
id='lineage_toggle_all'
checked={allSelected}
onChange={toggleAll}
/>
</div>
</header>
<div className='md:flex md:mt-0.5'>
<form
ref={scrollContainer}
className={classNames(
'overflow-auto hide-scrollbars flex-grow -mx-4 md:-mx-2 flex md:flex-col md:h-16',
{ 'md:-mx-1': fixedLayout }
)}
style={{ scrollSnapType: isMobile ? 'x mandatory' : 'y mandatory' }}
>
{sections.map((lineages, i) => (
<section
key={`lineages-${i}`}
ref={el => { sectionRefs.current[i] = el }}
className={classNames(
'w-full h-full flex-shrink-0 flex flex-wrap content-start px-4 md:px-0 md:grid md:gap-0.5 relative',
{ 'md:px-1': fixedLayout }
)}
style={gridStyle}
>
{ lineages.length > 0
? lineages.map(({ lineage, active, colour, title = lineage, primaryText, secondaryText = lineage }) => (
<Checkbox
key={lineage}
className={classNames(
'w-1/3 my-1 h-7 md:my-0',
fixedLayout ? 'md:w-24 md:mx-0.5' : 'md:w-auto md:mx-2',
{
'md:mb-1': isScrolling && nomenclature.length === 0
}
)}
title={title}
style={{ color: colour }}
id={`lineage_filter_${lineage}`}
checked={active}
onChange={() => toggleLineage(lineage)}
>
{primaryText ? <span className={classNames('block text-gray-700 dark:text-gray-100')}>{primaryText}</span> : null}
<span className={classNames({ 'text-xs tracking-wide leading-none text-gray-500 dark:text-gray-300': primaryText })}>{secondaryText}</span>
</Checkbox>
))
: <>
<div className={classNames({ 'lg:w-24 lg:mx-0.5': fixedLayout })} />
<div className='absolute inset-0 flex items-center justify-center'>
{emptyMessage}
</div>
</> }
</section>
))}
</form>
{(sections.length > 1 || (!isMobile && fixedLayout)) && (
isMobile
? <ol className='list-none p-1 flex justify-center space-x-2'>
{ sections.map((_, i) =>
<li
key={`section-indicator-${i}`}
className={classNames(
'rounded-full bg-gray-500 dark:bg-gray-300 w-2 h-2 transition-opacity',
{ 'opacity-50': i !== currentSection || 0 }
)}
/>
)}
</ol>
: <form onSubmit={e => e.preventDefault()}
className={classNames(
'flex flex-col justify-center relative left-1 pb-1 space-y-0.5 md:ml-2',
{ 'lg:ml-0': fixedLayout }
)}
>
<Button
ref={scrollUpBtnRef}
title='Previous lineages'
className='w-6 h-6 !p-0 flex items-center text-gray-700 dark:text-gray-200 transition-opacity disabled:opacity-50'
onClick={() => doScroll(-1)}
disabled={currentSection === 0 || null}
>
<BsArrowUpShort className='fill-current w-6 h-6'/>
</Button>
<Button
ref={scrollDownBtnRef}
title='Next lineages'
className='w-6 h-6 !p-0 flex items-center text-gray-700 dark:text-gray-200 transition-opacity disabled:opacity-50'
onClick={() => doScroll(1)}
disabled={currentSection === sections.length - 1}
>
<BsArrowDownShort className='fill-current w-6 h-6'/>
</Button>
</form>
)}
</div>
</div>
)
}
Example #2
Source File: LocationFilter.jsx From covince with MIT License | 4 votes |
LocationFilter = (props) => {
const {
className, loading, onChange,
category, heading, subheading, showOverviewButton, loadOverview, overview,
isSearching, setIsSearching, filteredItems, searchTerm, setSearchTerm
} = props
const searchButtonRef = useRef()
const onSearchClose = useCallback(() => {
setIsSearching(false)
}, [setIsSearching])
const previousIsSearching = useRef()
useEffect(() => {
if (previousIsSearching.current === true && isSearching === false) {
searchButtonRef.current.focus()
}
previousIsSearching.current = isSearching
}, [isSearching])
const isMobile = useMobile()
const { ontology } = useConfig()
const { noun_plural, search_placeholder = noun_plural } = ontology.area
return (
<div className={className}>
{ isSearching
? <>
<div className='flex justify-between items-center h-6 mb-3'>
<DescriptiveHeading className='whitespace-nowrap'>
Search
</DescriptiveHeading>
<Button
className='box-content relative z-10 h-6 pt-0 pb-0 pl-1 pr-1'
title='Close'
onClick={onSearchClose}
>
<HiX className='h-4 w-4 fill-current text-gray-600 dark:text-gray-300' />
</Button>
</div>
<ComboBox
ariaLabel='Areas'
items={filteredItems}
onChange={setSearchTerm}
onClose={onSearchClose}
onSelect={onChange}
placeholder={search_placeholder}
popover={isMobile ? MobilePopover : undefined}
value={searchTerm}
/>
</>
: <>
<div className='flex justify-between items-center h-6'>
<DescriptiveHeading className='whitespace-nowrap'>
{category}
</DescriptiveHeading>
{ showOverviewButton &&
<Button
title='Return to overview'
className='relative z-10 -top-0.5 h-6 pl-0.5 pr-2 flex items-center !text-primary hover:bg-gray-50'
onClick={loadOverview}
tabIndex={isSearching ? '-1' : undefined}
>
<BsArrowUpShort className='h-6 w-6 fill-current' />
{overview.short_heading}
</Button> }
</div>
<div className='flex justify-between space-x-2 w-full'>
<div className='flex-shrink min-w-0'>
<Heading className='relative z-0 leading-6 truncate my-0.5'>
{heading}
</Heading>
<p className='text-sm leading-6 h-6 text-gray-600 dark:text-gray-400 font-medium'>
{subheading}
</p>
</div>
<Button
ref={searchButtonRef}
className='flex-shrink-0 h-10 md:h-8 w-11 md:w-9 flex items-center justify-center mt-0.5'
onClick={() => setIsSearching(true)} title='Search areas'
tabIndex={isSearching ? '-1' : undefined}
>
<BsSearch className='flex-shrink-0 h-5 md:h-4 w-5 md:w-4 text-current' />
</Button>
</div>
</> }
<FadeTransition in={loading}>
<div className='bg-white dark:bg-gray-700 absolute inset-1 grid place-content-center z-10'>
<Spinner className='text-gray-500 dark:text-gray-300 w-6 h-6 mt-2' />
</div>
</FadeTransition>
</div>
)
}