fix(devex): project dropdown menu for breadcrumbs + fixes (#34740)
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 135 KiB |
@@ -25,6 +25,7 @@
|
||||
);
|
||||
--content-padding: calc(var(--total-height) * 0.1);
|
||||
--content-height: calc(var(--total-height) - 2 * var(--content-padding));
|
||||
--content-font-size: calc(0.75rem + 0.0625rem * var(--breadcrumbs-compaction-rate));
|
||||
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
@@ -32,7 +33,7 @@
|
||||
width: 100%;
|
||||
height: var(--total-height);
|
||||
padding: 0 1rem;
|
||||
font-size: calc(0.75rem + 0.0625rem * var(--breadcrumbs-compaction-rate));
|
||||
font-size: var(--content-font-size);
|
||||
font-weight: 600;
|
||||
line-height: 1rem;
|
||||
pointer-events: auto;
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ErrorBoundary } from '~/layout/ErrorBoundary'
|
||||
import { breadcrumbsLogic } from '~/layout/navigation/Breadcrumbs/breadcrumbsLogic'
|
||||
import { navigationLogic } from '~/layout/navigation/navigationLogic'
|
||||
import { panelLayoutLogic } from '~/layout/panel-layout/panelLayoutLogic'
|
||||
import { ProjectDropdownMenu } from '~/layout/panel-layout/ProjectDropdownMenu'
|
||||
import { PROJECT_TREE_KEY } from '~/layout/panel-layout/ProjectTree/ProjectTree'
|
||||
import { projectTreeDataLogic } from '~/layout/panel-layout/ProjectTree/projectTreeDataLogic'
|
||||
import { projectTreeLogic } from '~/layout/panel-layout/ProjectTree/projectTreeLogic'
|
||||
@@ -248,6 +249,18 @@ function Breadcrumb({ breadcrumb, here, isOnboarding }: BreadcrumbProps): JSX.El
|
||||
</Component>
|
||||
)
|
||||
|
||||
if (breadcrumb.isPopoverProject) {
|
||||
return (
|
||||
<ProjectDropdownMenu
|
||||
buttonProps={{
|
||||
size: 'xxs',
|
||||
className:
|
||||
'-mr-1 [font-size:var(--content-font-size)] text-secondary p-0 hover:text-primary hover:bg-transparent',
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (breadcrumb.popover) {
|
||||
return (
|
||||
<Popover
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Tooltip } from '@posthog/lemon-ui'
|
||||
import { actions, connect, kea, listeners, path, props, reducers, selectors } from 'kea'
|
||||
import { subscriptions } from 'kea-subscriptions'
|
||||
import { FEATURE_FLAGS } from 'lib/constants'
|
||||
import { UploadedLogo } from 'lib/lemon-ui/UploadedLogo/UploadedLogo'
|
||||
|
||||
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
|
||||
import { identifierToHuman, objectsEqual, stripHTTP } from 'lib/utils'
|
||||
import { organizationLogic } from 'scenes/organizationLogic'
|
||||
@@ -12,8 +11,6 @@ import { sceneLogic } from 'scenes/sceneLogic'
|
||||
import { teamLogic } from 'scenes/teamLogic'
|
||||
import { userLogic } from 'scenes/userLogic'
|
||||
|
||||
import { OrganizationSwitcherOverlay } from '~/layout/navigation/OrganizationSwitcher'
|
||||
import { ProjectSwitcherOverlay } from '~/layout/navigation/ProjectSwitcher'
|
||||
import { Breadcrumb, ProjectTreeRef } from '~/types'
|
||||
|
||||
import type { breadcrumbsLogicType } from './breadcrumbsLogicType'
|
||||
@@ -127,26 +124,8 @@ export const breadcrumbsLogic = kea<breadcrumbsLogicType>([
|
||||
{ equalityCheck: objectsEqual },
|
||||
],
|
||||
appBreadcrumbs: [
|
||||
(s) => [
|
||||
s.preflight,
|
||||
s.sceneConfig,
|
||||
s.activeScene,
|
||||
s.user,
|
||||
s.currentOrganization,
|
||||
s.currentProject,
|
||||
s.currentTeam,
|
||||
s.featureFlags,
|
||||
],
|
||||
(
|
||||
preflight,
|
||||
sceneConfig,
|
||||
activeScene,
|
||||
user,
|
||||
currentOrganization,
|
||||
currentProject,
|
||||
currentTeam,
|
||||
featureFlags
|
||||
) => {
|
||||
(s) => [s.preflight, s.sceneConfig, s.activeScene, s.user, s.currentProject, s.currentTeam, s.featureFlags],
|
||||
(preflight, sceneConfig, activeScene, user, currentProject, currentTeam, featureFlags) => {
|
||||
const breadcrumbs: Breadcrumb[] = []
|
||||
if (!activeScene || !sceneConfig) {
|
||||
return breadcrumbs
|
||||
@@ -171,28 +150,6 @@ export const breadcrumbsLogic = kea<breadcrumbsLogicType>([
|
||||
name: stripHTTP(preflight.site_url),
|
||||
})
|
||||
}
|
||||
// Organization
|
||||
if (sceneConfig.organizationBased || sceneConfig.projectBased) {
|
||||
if (!currentOrganization) {
|
||||
return breadcrumbs
|
||||
}
|
||||
breadcrumbs.push({
|
||||
key: 'organization',
|
||||
symbol: (
|
||||
<Tooltip title={currentOrganization.name} placement="left">
|
||||
<UploadedLogo
|
||||
name={currentOrganization.name}
|
||||
entityId={currentOrganization.id}
|
||||
mediaId={currentOrganization.logo_media_id}
|
||||
size="xsmall"
|
||||
/>
|
||||
</Tooltip>
|
||||
),
|
||||
popover: {
|
||||
overlay: <OrganizationSwitcherOverlay />,
|
||||
},
|
||||
})
|
||||
}
|
||||
// Project
|
||||
if (sceneConfig.projectBased) {
|
||||
if (!currentProject || !currentTeam) {
|
||||
@@ -202,9 +159,7 @@ export const breadcrumbsLogic = kea<breadcrumbsLogicType>([
|
||||
key: 'project',
|
||||
name: featureFlags[FEATURE_FLAGS.ENVIRONMENTS] ? currentProject.name : currentTeam.name,
|
||||
tag: featureFlags[FEATURE_FLAGS.ENVIRONMENTS] ? currentTeam.name : null,
|
||||
popover: {
|
||||
overlay: <ProjectSwitcherOverlay />,
|
||||
},
|
||||
isPopoverProject: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ export function OrganizationDropdownMenu(): JSX.Element {
|
||||
>
|
||||
<Combobox>
|
||||
<Combobox.Search placeholder="Filter organizations..." />
|
||||
<Combobox.Content className="max-h-[calc(90vh-100px)]">
|
||||
<Combobox.Content>
|
||||
<Label intent="menu" className="px-2">
|
||||
Organizations
|
||||
</Label>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { LemonSnack, Link } from '@posthog/lemon-ui'
|
||||
import { useActions, useValues } from 'kea'
|
||||
import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic'
|
||||
import { IconBlank } from 'lib/lemon-ui/icons'
|
||||
import { ButtonGroupPrimitive, ButtonPrimitive } from 'lib/ui/Button/ButtonPrimitives'
|
||||
import { ButtonGroupPrimitive, ButtonPrimitive, ButtonPrimitiveProps } from 'lib/ui/Button/ButtonPrimitives'
|
||||
import { Combobox } from 'lib/ui/Combobox/Combobox'
|
||||
import { Label } from 'lib/ui/Label/Label'
|
||||
import {
|
||||
@@ -30,7 +30,7 @@ export function ProjectName({ team }: { team: TeamBasicType }): JSX.Element {
|
||||
)
|
||||
}
|
||||
|
||||
export function ProjectDropdownMenu(): JSX.Element | null {
|
||||
export function ProjectDropdownMenu({ buttonProps }: { buttonProps?: ButtonPrimitiveProps }): JSX.Element | null {
|
||||
const { preflight } = useValues(preflightLogic)
|
||||
const { guardAvailableFeature } = useValues(upgradeModalLogic)
|
||||
const { closeAccountPopover } = useActions(navigationLogic)
|
||||
@@ -45,6 +45,7 @@ export function ProjectDropdownMenu(): JSX.Element | null {
|
||||
data-attr="tree-navbar-project-dropdown-button"
|
||||
className="flex-1 min-w-0 max-w-fit"
|
||||
size="sm"
|
||||
{...buttonProps}
|
||||
>
|
||||
<span className="truncate font-semibold">{currentTeam.name ?? 'Project'}</span>
|
||||
<IconChevronRight
|
||||
@@ -66,7 +67,7 @@ export function ProjectDropdownMenu(): JSX.Element | null {
|
||||
>
|
||||
<Combobox>
|
||||
<Combobox.Search placeholder="Filter projects..." />
|
||||
<Combobox.Content className="max-h-[calc(90vh-100px)]">
|
||||
<Combobox.Content>
|
||||
<Label intent="menu" className="px-2">
|
||||
Projects
|
||||
</Label>
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
PopoverPrimitiveTrigger,
|
||||
} from 'lib/ui/PopoverPrimitive/PopoverPrimitive'
|
||||
import { forwardRef, Fragment, useEffect, useRef, useState } from 'react'
|
||||
import { ScrollableShadows } from '../ScrollableShadows/ScrollableShadows'
|
||||
|
||||
type Category = { label: string; value: string; hint?: string; icon?: React.ReactNode }
|
||||
type Suggestion = { label: string; value: string; hint?: string; icon?: React.ReactNode }
|
||||
@@ -292,9 +293,13 @@ export const SearchAutocomplete = forwardRef<HTMLDivElement, SearchAutocompleteP
|
||||
setSuggestions(newSuggestions)
|
||||
setCurrentHint(newHint)
|
||||
}}
|
||||
className="primitive-menu-content min-w-[var(--radix-popover-trigger-width)] max-w-none"
|
||||
className="primitive-menu-content min-w-[var(--radix-popover-trigger-width)] max-w-none max-h-[calc(var(--radix-popover-content-available-height)-var(--radix-popover-trigger-height))]"
|
||||
>
|
||||
<ul className="flex flex-col gap-px p-1">
|
||||
<ScrollableShadows
|
||||
direction="vertical"
|
||||
styledScrollbars
|
||||
innerClassName="primitive-menu-content-inner"
|
||||
>
|
||||
<ListBox.Item asChild key={value} aria-disabled="true">
|
||||
<ButtonPrimitive
|
||||
menuItem
|
||||
@@ -340,7 +345,7 @@ export const SearchAutocomplete = forwardRef<HTMLDivElement, SearchAutocompleteP
|
||||
<IconInfo /> {currentHint}
|
||||
</ButtonPrimitive>
|
||||
)}
|
||||
</ul>
|
||||
</ScrollableShadows>
|
||||
</PopoverPrimitiveContent>
|
||||
)}
|
||||
</PopoverPrimitive>
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
:root {
|
||||
--button-padding-x-xxs: 4px;
|
||||
--button-padding-x-xs: 4px;
|
||||
--button-padding-x-sm: 4px;
|
||||
--button-padding-x-base: 6px;
|
||||
--button-padding-x-lg: 8px;
|
||||
--button-padding-y-xxs: 3px;
|
||||
--button-padding-y-xs: 3px;
|
||||
--button-padding-y-sm: 3px;
|
||||
--button-padding-y-base: 5px;
|
||||
--button-padding-y-lg: 7px;
|
||||
--button-height-xxs: 20px;
|
||||
--button-height-xs: 24px;
|
||||
--button-height-sm: 28px;
|
||||
--button-height-base: 30px;
|
||||
--button-height-base-tall: 45px;
|
||||
@@ -97,6 +103,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button-primitive--height-xxs {
|
||||
height: var(--button-height-xxs);
|
||||
|
||||
&.icon-only {
|
||||
width: var(--button-height-xxs);
|
||||
}
|
||||
}
|
||||
|
||||
.button-primitive--height-xs {
|
||||
height: var(--button-height-xs);
|
||||
|
||||
&.icon-only {
|
||||
width: var(--button-height-xs);
|
||||
}
|
||||
}
|
||||
|
||||
.button-primitive--height-sm {
|
||||
height: var(--button-height-sm);
|
||||
|
||||
@@ -129,6 +151,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
.button-primitive--size-xxs {
|
||||
padding-right: var(--button-padding-x-xxs);
|
||||
padding-left: var(--button-padding-x-xxs);
|
||||
|
||||
svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-primitive--size-xs {
|
||||
padding-right: var(--button-padding-x-xs);
|
||||
padding-left: var(--button-padding-x-xs);
|
||||
|
||||
svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-primitive--size-sm {
|
||||
padding-right: var(--button-padding-x-sm);
|
||||
padding-left: var(--button-padding-x-sm);
|
||||
|
||||
@@ -11,7 +11,7 @@ import React, { createContext, forwardRef, ReactNode, useContext } from 'react'
|
||||
|
||||
type ButtonVariant = 'default' | 'outline'
|
||||
|
||||
export type ButtonSize = 'sm' | 'base' | 'lg' | 'fit' | 'base-tall'
|
||||
export type ButtonSize = 'xxs' | 'xs' | 'sm' | 'base' | 'lg' | 'fit' | 'base-tall'
|
||||
|
||||
interface ButtonGroupContextValue {
|
||||
sizeContext: ButtonSize
|
||||
@@ -124,6 +124,8 @@ export const buttonPrimitiveVariants = cva({
|
||||
outline: 'button-primitive--variant-outline',
|
||||
},
|
||||
size: {
|
||||
xxs: `button-primitive--size-xxs button-primitive--height-xxs text-sm`,
|
||||
xs: `button-primitive--size-xs button-primitive--height-xs text-sm`,
|
||||
sm: `button-primitive--size-sm button-primitive--height-sm text-sm`,
|
||||
base: `button-primitive--size-base button-primitive--height-base text-sm`,
|
||||
'base-tall': `button-primitive--size-base-tall button-primitive--height-base-tall text-sm`,
|
||||
@@ -159,7 +161,7 @@ export const buttonPrimitiveVariants = cva({
|
||||
false: '',
|
||||
},
|
||||
hasSideActionRight: {
|
||||
true: 'rounded-md',
|
||||
true: 'rounded',
|
||||
false: '',
|
||||
},
|
||||
isSideActionRight: {
|
||||
@@ -177,23 +179,22 @@ export const buttonPrimitiveVariants = cva({
|
||||
{
|
||||
hasSideActionRight: true,
|
||||
size: 'sm',
|
||||
className: `
|
||||
pr-[calc(var(--button-height-sm)+var(--button-padding-x-sm))]
|
||||
`,
|
||||
className: 'pr-[calc(var(--button-height-sm)+var(--button-padding-x-sm))]',
|
||||
},
|
||||
{
|
||||
hasSideActionRight: true,
|
||||
size: 'base',
|
||||
className: `
|
||||
pr-[calc(var(--button-height-base)+var(--button-padding-x-base))]
|
||||
`,
|
||||
className: 'pr-[calc(var(--button-height-base)+var(--button-padding-x-base))]',
|
||||
},
|
||||
{
|
||||
hasSideActionRight: true,
|
||||
size: 'lg',
|
||||
className: `
|
||||
pr-[calc(var(--button-height-lg)+var(--button-padding-x-lg))]
|
||||
`,
|
||||
className: 'pr-[calc(var(--button-height-lg)+var(--button-padding-x-lg))]',
|
||||
},
|
||||
{
|
||||
hasSideActionRight: true,
|
||||
menuItem: true,
|
||||
className: 'rounded-sm',
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -103,6 +103,12 @@ const InnerCombobox = forwardRef<ListBoxHandle, ComboboxProps>(({ children, clas
|
||||
virtualFocus
|
||||
role="listbox"
|
||||
id="combobox-listbox"
|
||||
style={
|
||||
{
|
||||
// Match text input base height with p-1 padding
|
||||
'--combobox-search-height': 'calc(var(--text-input-height-base) + (var(--spacing) * 2))',
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</ListBox>
|
||||
@@ -134,6 +140,7 @@ const Search = ({ placeholder = 'Search...', className, autoFocus = true }: Sear
|
||||
placeholder={placeholder}
|
||||
autoFocus={autoFocus}
|
||||
role="combobox"
|
||||
size="default"
|
||||
aria-controls="combobox-listbox"
|
||||
/>
|
||||
</div>
|
||||
@@ -198,7 +205,12 @@ interface ContentProps {
|
||||
|
||||
const Content = ({ className, children }: ContentProps): JSX.Element => {
|
||||
return (
|
||||
<div className={cn('primitive-menu-content max-h-[300px] max-w-none border-transparent', className)}>
|
||||
<div
|
||||
className={cn(
|
||||
'primitive-menu-content max-h-[calc(var(--radix-popover-content-available-height)-var(--combobox-search-height)-var(--radix-popper-anchor-height))] max-w-none border-transparent',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<ScrollableShadows
|
||||
direction="vertical"
|
||||
styledScrollbars
|
||||
|
||||
@@ -44,7 +44,10 @@ const ContextMenuSubContent = React.forwardRef<
|
||||
<ContextMenuPrimitive.SubContent
|
||||
ref={ref}
|
||||
collisionPadding={collisionPadding}
|
||||
className={cn('primitive-menu-content', className)}
|
||||
className={cn(
|
||||
'primitive-menu-content max-h-[var(--radix-context-menu-content-available-height)]',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollableShadows direction="vertical" styledScrollbars innerClassName="primitive-menu-content-inner">
|
||||
@@ -64,7 +67,10 @@ const ContextMenuContent = React.forwardRef<
|
||||
<ContextMenuPrimitive.Content
|
||||
ref={ref}
|
||||
collisionPadding={collisionPadding}
|
||||
className={cn(`primitive-menu-content`, className)}
|
||||
className={cn(
|
||||
`primitive-menu-content max-h-[var(--radix-context-menu-content-available-height)]`,
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollableShadows direction="vertical" styledScrollbars innerClassName="primitive-menu-content-inner">
|
||||
|
||||
@@ -17,16 +17,18 @@ function PopoverPrimitiveContent({
|
||||
...props
|
||||
}: React.ComponentProps<typeof PopoverPrimitiveBase.Content>): JSX.Element {
|
||||
return (
|
||||
<PopoverPrimitiveBase.Content
|
||||
data-slot="popover-content"
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'primitive-menu-content data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 outline-hidden',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
<PopoverPrimitiveBase.Portal>
|
||||
<PopoverPrimitiveBase.Content
|
||||
data-slot="popover-content"
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'primitive-menu-content data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 outline-hidden',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitiveBase.Portal>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
:root {
|
||||
--text-input-height-sm: 28px;
|
||||
--text-input-height-base: 30px;
|
||||
--text-input-height-lg: 40px;
|
||||
}
|
||||
@@ -1,17 +1,18 @@
|
||||
import './TextInputPrimitive.scss'
|
||||
import { cva, type VariantProps } from 'cva'
|
||||
import { cn } from 'lib/utils/css-classes'
|
||||
import { forwardRef, useCallback, useEffect, useRef } from 'react'
|
||||
|
||||
const textInputVariants = cva({
|
||||
base: 'w-full rounded border border-primary p-2 text-sm outline-none focus-visible:border-secondary',
|
||||
base: 'text-input-primitive w-full rounded border border-primary p-2 text-sm outline-none focus-visible:border-secondary',
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'border-primary bg-surface-primary hover:border-secondary',
|
||||
},
|
||||
size: {
|
||||
default: 'h-[30px]',
|
||||
sm: 'h-[28px] px-2',
|
||||
lg: 'h-[40px] px-4',
|
||||
sm: 'h-[var(--text-input-height-sm)]',
|
||||
default: 'h-[var(--text-input-height-base)]',
|
||||
lg: 'h-[var(--text-input-height-lg)]',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
||||
@@ -1611,7 +1611,6 @@
|
||||
gap: 1px;
|
||||
min-width: 8rem;
|
||||
max-width: 200px;
|
||||
max-height: calc(90vh - 100px);
|
||||
overflow: hidden;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--bg-surface-primary);
|
||||
@@ -1624,7 +1623,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
max-height: calc(90vh - 100px);
|
||||
padding: var(--spacing);
|
||||
}
|
||||
|
||||
|
||||
@@ -3861,6 +3861,8 @@ interface BreadcrumbBase {
|
||||
key: string | number | [scene: Scene | string, key: string | number]
|
||||
/** Whether to show a custom popover */
|
||||
popover?: Pick<PopoverProps, 'overlay' | 'matchWidth'>
|
||||
/** Whether to show a custom popover for the project */
|
||||
isPopoverProject?: boolean
|
||||
}
|
||||
export interface LinkBreadcrumb extends BreadcrumbBase {
|
||||
/** Name to display. */
|
||||
|
||||