import * as React from 'react' import styled, { ThemeProvider } from 'styled-components' import { defineMessages, useIntl } from 'react-intl' import { Avatar, ButtonEmpty, Tooltip } from '@planview/pv-uikit' import { Cancel } from '@planview/pv-icons' import { DarkWithRedFalcon } from '../logos' import { zindex, theme, borderRadius, shadow, sizePx, spacingPx, text, breakpoints, size, useTheme, overflow, } from '@planview/pv-utilities' import type { ProductSwitcherOrganization } from '../types' import { BaseToolbarSeparator } from '../../separator' import { PlanviewSymbolLight } from '../../logos/components' const OuterWrap = styled.div<{ theme: zindex.ZIndexThemeRecord }>` position: absolute; z-index: ${(props) => props.theme.zindex}; width: 320px; background-color: ${theme.backgroundNeutral0}; ${borderRadius.small}; ${shadow.regular}; ${breakpoints.phone` top: 0; left: 0; width: 100%; height:100%; border-radius: 0; box-shadow: none; `} ` const Header = styled.div` display: flex; justify-content: space-between; align-items: center; padding: 0 ${spacingPx.small}; height: ${sizePx.medium}; ${text.h1}; color: ${theme.textPrimary}; min-width: 0; ` const LogoSeparator = styled(BaseToolbarSeparator)` margin: 0 ${spacingPx.small}; ` const OrgBlock = styled.div` flex: 1 1 auto; display: flex; height: ${sizePx.small}; align-items: center; min-width: 0; ` const OrgAvatar = styled.div` flex: 0 0 auto; display: grid; place-content: center; ` const OrgTextBlock = styled.div` flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; ` const OrgName = styled.div` ${text.regular}; color: ${theme.textPrimary}; ${overflow.ellipsis}; ` const OrgDomain = styled.div` ${text.small}; color: ${theme.textSecondary}; ${overflow.ellipsis}; ` const PlanviewLogo = styled.div` flex: 0 0 auto; display: grid; place-content: center; ` const StyledPlanviewFalcon = styled(PlanviewSymbolLight)` height: 31px; ` const ListWrap = styled.ul` margin: 0; padding: 0; max-height: calc(100vh - ${size.medium * 3}px); overflow: auto; ${breakpoints.phone` max-height: calc(100% - ${size.medium * 2}px); `} ` type Props = { /** Must have one ore more ProductSwitcherListItem components as children */ children: React.ReactNode /** Used by the container to enable keyboard navigation of the list */ onKeyDown: React.KeyboardEventHandler /** Will render organization branding when provided */ organization?: ProductSwitcherOrganization /** Called when the list closes */ onClose: () => void } const messages = defineMessages({ menuLabel: { defaultMessage: 'Planview product switcher', description: 'Product switcher accessibility label for menu (screen reader only)', id: 'pvds.toolbar.productSwitcherMenuLabel', }, menuLabelWithOrg: { defaultMessage: 'Planview product switcher for {name} domain {domain}', description: 'Product switcher accessibility label for menu (screen reader only) when co-branded with an organization. Name will be organization name and domain will be a shorter identifier for the organization.', id: 'pvds.toolbar.productSwitcherMenuLabelWithOrg', }, closeButton: { defaultMessage: 'Close', description: 'Label for close button in header', id: 'pvds.toolbar.productSwitcherListHeaderCloseButton', }, listHeader: { defaultMessage: 'Products', description: 'Product switcher list header', id: 'pvds.toolbar.productSwitcherListHeader', }, }) const ProductSwitcherListImpl: React.ForwardRefRenderFunction< HTMLDivElement, Props > = ( { children, organization, onKeyDown, onClose }, ref ): React.JSX.Element => { const isMobile = window.innerWidth <= breakpoints.PHONE const intl = useIntl() const { theme } = useTheme() const avatar = organization?.avatar ? theme === 'dark' ? organization.avatar.dark : organization.avatar.light : undefined const headerContent = ( <> {organization ? ( ) : ( )} {organization && ( <> {!avatar ? null : typeof avatar === 'string' ? ( ) : ( React.cloneElement(avatar, { size: 'medium', }) )} {organization.name} {organization.domain} )} ) return ( {isMobile ? (
{headerContent} } />
) : (
{headerContent}
)} {children}
) } /** * Implements the [Design System specs](https://design.planview.com/components/product-switcher/product-switcher-panel/anatomy) * */ const ProductSwitcherList = React.forwardRef(ProductSwitcherListImpl) export { ProductSwitcherList } export default ProductSwitcherList