mirror of
https://gitee.com/zhangsken/opencode.git
synced 2026-10-16 10:30:01 +08:00
feat(desktop): refine review and file panel controls
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { createSignal, For, Show, type ParentProps } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { AppIcon } from "@opencode/ui/app-icon"
|
||||
import { Icon } from "@opencode/ui/icon"
|
||||
import { Spinner } from "@opencode/ui/spinner"
|
||||
@@ -6,11 +7,12 @@ import { Menu } from "@opencode/ui/menu"
|
||||
import { SplitButton, SplitButtonAction, SplitButtonMenuTrigger } from "@opencode/ui/split-button"
|
||||
import { Tooltip } from "@opencode/ui/tooltip"
|
||||
import { useLanguage } from "@/runtime/i18n/language"
|
||||
import { type OpenApp, useOpenInApp } from "@/session/files/open-in-app"
|
||||
import { type OpenApp, type OpenInAppState } from "@/session/files/open-in-app"
|
||||
|
||||
export function OpenInAppButton(props: { directory: () => string }) {
|
||||
export function OpenInAppButton(props: { directory: () => string; state: OpenInAppState }) {
|
||||
const language = useLanguage()
|
||||
const state = useOpenInApp({ path: props.directory })
|
||||
const state = props.state
|
||||
const [menu, setMenu] = createStore({ open: false })
|
||||
|
||||
return (
|
||||
<Show when={props.directory() && state.canOpen()}>
|
||||
@@ -39,8 +41,8 @@ export function OpenInAppButton(props: { directory: () => string }) {
|
||||
gutter={4}
|
||||
modal={false}
|
||||
placement="bottom-end"
|
||||
open={state.menu.open}
|
||||
onOpenChange={(open) => state.setMenu("open", open)}
|
||||
open={menu.open}
|
||||
onOpenChange={(open) => setMenu("open", open)}
|
||||
>
|
||||
<Menu.Trigger
|
||||
as={SplitButtonMenuTrigger}
|
||||
@@ -52,7 +54,7 @@ export function OpenInAppButton(props: { directory: () => string }) {
|
||||
</Menu.Trigger>
|
||||
<Menu.Portal>
|
||||
<Menu.Content class="open-in-app-v2-menu">
|
||||
<OpenInAppMenuItemsV2 state={state} close={() => state.setMenu("open", false)} />
|
||||
<OpenInAppMenuItemsV2 state={state} close={() => setMenu("open", false)} />
|
||||
</Menu.Content>
|
||||
</Menu.Portal>
|
||||
</Menu>
|
||||
@@ -61,8 +63,6 @@ export function OpenInAppButton(props: { directory: () => string }) {
|
||||
)
|
||||
}
|
||||
|
||||
type OpenInAppState = ReturnType<typeof useOpenInApp>
|
||||
|
||||
function OpenInAppMenuItemsV2(props: {
|
||||
state: OpenInAppState
|
||||
path?: () => string
|
||||
|
||||
@@ -167,7 +167,6 @@ export function useOpenInApp(input: { path: () => string }) {
|
||||
})
|
||||
|
||||
const [prefs, setPrefs] = persisted(Persist.global("open.app"), OpenAppPreferences, { app: "finder" })
|
||||
const [menu, setMenu] = createStore({ open: false })
|
||||
const [openRequest, setOpenRequest] = createStore({
|
||||
app: undefined as OpenApp | undefined,
|
||||
})
|
||||
@@ -225,14 +224,14 @@ export function useOpenInApp(input: { path: () => string }) {
|
||||
opening,
|
||||
current,
|
||||
options,
|
||||
menu,
|
||||
setMenu,
|
||||
openPath,
|
||||
selectApp,
|
||||
copyPath,
|
||||
}
|
||||
}
|
||||
|
||||
export type OpenInAppState = ReturnType<typeof useOpenInApp>
|
||||
|
||||
function checkAppExists(platform: ReturnType<typeof usePlatform>, app: string) {
|
||||
const cached = appExistence.get(app)
|
||||
if (cached) return cached
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createStore } from "solid-js/store"
|
||||
import { createQuery, keepPreviousData } from "@tanstack/solid-query"
|
||||
import { Icon } from "@opencode/ui/icon"
|
||||
import { SessionFilePanelV2, SessionFilePanelV2Empty } from "@opencode/session-ui/v2/session-file-panel-v2"
|
||||
import { SessionReviewV2Sidebar } from "@opencode/session-ui/v2/session-review-v2"
|
||||
import { SessionReviewV2Sidebar, SessionReviewV2SidebarToggle } from "@opencode/session-ui/v2/session-review-v2"
|
||||
import FileTreeV2, { type Kind } from "@/session/files/file-tree-v2"
|
||||
import { useFile } from "@/workspaces/files/model"
|
||||
import { useLanguage } from "@/runtime/i18n/language"
|
||||
@@ -101,12 +101,24 @@ export function SessionFileBrowserTab(props: {
|
||||
// unmounts the whole panel on every file-tab switch and resets sidebar scroll.
|
||||
return (
|
||||
<SessionFilePanelV2
|
||||
toolbar={false}
|
||||
toolbar={!props.mobile && !props.placeholder && !sidebarOpened()}
|
||||
toolbarStart={<span class="truncate font-[530]">{title()}</span>}
|
||||
sidebarCollapsed={!sidebarOpened()}
|
||||
sidebarToggleGap={10}
|
||||
sidebarToggle={
|
||||
!props.mobile && (
|
||||
<SessionReviewV2SidebarToggle
|
||||
opened={sidebarOpened()}
|
||||
disabled={props.placeholder}
|
||||
onToggle={props.state.toggleSidebar}
|
||||
/>
|
||||
)
|
||||
}
|
||||
sidebar={
|
||||
<SessionReviewV2Sidebar
|
||||
open={sidebarOpened()}
|
||||
transition={props.state.sidebarTransition()}
|
||||
title={<span class="truncate">{title()}</span>}
|
||||
title={<span class="truncate font-[530]">{title()}</span>}
|
||||
filter={filter()}
|
||||
onFilterChange={setFilter}
|
||||
onFilterKeyDown={onFilterKeyDown}
|
||||
|
||||
@@ -28,6 +28,7 @@ const fileBrowserTabPanelID = "session-side-panel-file-browser-tabpanel"
|
||||
import { SessionContextTab } from "@/session/files/session-context-tab"
|
||||
import { SortableTab } from "@/session/files/tab"
|
||||
import { OpenInAppButton } from "@/session/files/open-in-app-button"
|
||||
import type { OpenInAppState } from "@/session/files/open-in-app"
|
||||
import { useCommand } from "@/shell/commands/command"
|
||||
import { useFile, type SelectedLineRange } from "@/workspaces/files/model"
|
||||
import { useLanguage } from "@/runtime/i18n/language"
|
||||
@@ -67,7 +68,7 @@ export function SessionSidePanel(props: {
|
||||
reviewHasFocusableContent: boolean
|
||||
reviewCount: number
|
||||
reviewPanel: () => JSX.Element
|
||||
reviewSidebarToggle: (disabled: boolean) => JSX.Element
|
||||
openInApp: OpenInAppState
|
||||
fileBrowserState: SessionFileBrowserState
|
||||
activeDiff?: string
|
||||
focusReviewDiff: (path: string) => void
|
||||
@@ -329,9 +330,6 @@ export function SessionSidePanel(props: {
|
||||
onCleanup(stop)
|
||||
}}
|
||||
>
|
||||
<div class="session-review-v2-sidebar-toggle-slot h-full shrink-0 sticky start-0 z-10 flex items-center justify-center bg-v2-background-bg-base">
|
||||
{props.reviewSidebarToggle(activeTab() === SESSION_OPEN_FILE_TAB)}
|
||||
</div>
|
||||
<Show when={reviewTab() && props.canReview}>
|
||||
<Tabs.Trigger
|
||||
value="review"
|
||||
@@ -552,7 +550,14 @@ export function SessionSidePanel(props: {
|
||||
onPointerDown={(event) => event.stopPropagation()}
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
>
|
||||
<OpenInAppButton directory={projectDirectory} />
|
||||
<Show
|
||||
when={
|
||||
activeTab() !== "review" ||
|
||||
(!props.hasReview && props.fileBrowserState.sidebarOpened())
|
||||
}
|
||||
>
|
||||
<OpenInAppButton directory={projectDirectory} state={props.openInApp} />
|
||||
</Show>
|
||||
<Show when={reviewVisible()}>
|
||||
<div class="size-7 shrink-0" aria-hidden />
|
||||
</Show>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
SESSION_REVIEW_V2_SIDEBAR_WIDTH_MIN,
|
||||
SessionReviewV2,
|
||||
SessionReviewV2Sidebar,
|
||||
SessionReviewV2SidebarToggle,
|
||||
} from "@opencode/session-ui/v2/session-review-v2"
|
||||
import { SessionReviewFilePreviewV2 } from "@opencode/session-ui/v2/session-review-file-preview-v2"
|
||||
import { DiffChanges } from "@opencode/ui/diff-changes"
|
||||
@@ -31,11 +32,14 @@ import {
|
||||
} from "@/session/review/review-diff-kinds"
|
||||
import type { ReviewPanelState } from "@/session/review/panel-state"
|
||||
import { applyFileListKeyDown, SessionFileList } from "@/session/files/list"
|
||||
import { OpenInAppButton } from "@/session/files/open-in-app-button"
|
||||
import type { OpenInAppState } from "@/session/files/open-in-app"
|
||||
|
||||
type ReviewDiff = FileDiffInfo
|
||||
|
||||
export type ReviewPanelProps = {
|
||||
title?: JSX.Element
|
||||
collapsedTitle?: JSX.Element
|
||||
empty?: JSX.Element
|
||||
diffs: ReviewDiff[]
|
||||
diffsReady: boolean
|
||||
@@ -56,7 +60,7 @@ export type ReviewPanelProps = {
|
||||
fileList?: "tree" | "flat"
|
||||
}
|
||||
|
||||
export function ReviewPanel(props: ReviewPanelProps) {
|
||||
export function ReviewPanel(props: ReviewPanelProps & { openInApp: OpenInAppState }) {
|
||||
const sdk = useWorkspaceLocation()
|
||||
const serverSDK = useServerSDK()
|
||||
const readFile = async (path: string) =>
|
||||
@@ -68,12 +72,19 @@ export function ReviewPanel(props: ReviewPanelProps) {
|
||||
return undefined
|
||||
})
|
||||
|
||||
return <ReviewPanelView {...props} readFile={readFile} />
|
||||
return (
|
||||
<ReviewPanelView
|
||||
{...props}
|
||||
readFile={readFile}
|
||||
toolbarAction={<OpenInAppButton directory={() => sdk().directory} state={props.openInApp} />}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export function ReviewPanelView(
|
||||
props: ReviewPanelProps & {
|
||||
readFile?: (path: string) => Promise<{ type: "text"; content: string } | undefined>
|
||||
toolbarAction?: JSX.Element
|
||||
},
|
||||
) {
|
||||
const diffs = createMemo(() => props.diffs.filter(filterRenderableDiff))
|
||||
@@ -124,10 +135,16 @@ export function ReviewPanelView(
|
||||
|
||||
return (
|
||||
<SessionReviewV2
|
||||
title={props.title}
|
||||
title={props.collapsedTitle ?? props.title}
|
||||
stats={<DiffChanges changes={diffs()} />}
|
||||
empty={props.empty}
|
||||
sidebarOpen={props.state.sidebarOpened()}
|
||||
sidebarToggle={
|
||||
<SessionReviewV2SidebarToggle
|
||||
opened={props.state.sidebarOpened()}
|
||||
onToggle={props.state.toggleSidebar}
|
||||
/>
|
||||
}
|
||||
sidebar={
|
||||
// Always mounted: the sidebar header hosts the changes-mode dropdown,
|
||||
// which must stay reachable when the current mode has zero diffs.
|
||||
@@ -148,6 +165,7 @@ export function ReviewPanelView(
|
||||
files={navigationFiles()}
|
||||
onSelectFile={props.onSelectFile}
|
||||
diffStyle={props.diffStyle}
|
||||
toolbarAction={props.toolbarAction}
|
||||
onDiffStyleChange={props.onDiffStyleChange}
|
||||
expandMode={props.state.expandMode()}
|
||||
onExpandModeChange={props.state.setExpandMode}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { SessionReviewEmptyChangesV2 } from "@opencode/session-ui/v2/session-review-empty-changes-v2"
|
||||
import { SessionReviewV2SidebarToggle } from "@opencode/session-ui/v2/session-review-v2"
|
||||
import { Select } from "@opencode/ui/select"
|
||||
import { Tabs } from "@opencode/ui/tabs"
|
||||
import { Icon } from "@opencode/ui/icon"
|
||||
@@ -9,6 +8,8 @@ import { For, Match, Show, Suspense, Switch, lazy, createEffect, onCleanup, type
|
||||
import { createStore } from "solid-js/store"
|
||||
import { useLanguage } from "@/runtime/i18n/language"
|
||||
import { useSettings } from "@/settings/model"
|
||||
import { useWorkspaceLocation } from "@/workspaces/location"
|
||||
import { useOpenInApp, type OpenInAppState } from "@/session/files/open-in-app"
|
||||
import { SessionSidePanel } from "../files/session-side-panel"
|
||||
import { ReviewPanel } from "./panel"
|
||||
import { SessionReviewTab } from "./review-tab"
|
||||
@@ -132,6 +133,9 @@ export function SessionDesktopReview(props: {
|
||||
btw: SessionBtwModel
|
||||
present?: boolean
|
||||
}) {
|
||||
const location = useWorkspaceLocation()
|
||||
const openInApp = useOpenInApp({ path: () => location().directory })
|
||||
|
||||
return (
|
||||
<Suspense>
|
||||
<SessionSidePanel
|
||||
@@ -141,14 +145,8 @@ export function SessionDesktopReview(props: {
|
||||
hasReview={props.review.hasChanges()}
|
||||
reviewHasFocusableContent={props.review.hasChanges() || props.review.panelState.sidebarOpened()}
|
||||
reviewCount={props.review.count()}
|
||||
reviewPanel={() => <ReviewPanelContent review={props.review} />}
|
||||
reviewSidebarToggle={(disabled) => (
|
||||
<SessionReviewV2SidebarToggle
|
||||
opened={props.review.panelState.sidebarOpened()}
|
||||
disabled={disabled}
|
||||
onToggle={props.review.panelState.toggleSidebar}
|
||||
/>
|
||||
)}
|
||||
reviewPanel={() => <ReviewPanelContent review={props.review} openInApp={openInApp} />}
|
||||
openInApp={openInApp}
|
||||
fileBrowserState={props.review.panelState}
|
||||
activeDiff={props.review.activeFile()}
|
||||
focusReviewDiff={props.review.focusFile}
|
||||
@@ -200,12 +198,14 @@ function ReviewContent(props: { review: SessionReviewModel }) {
|
||||
)
|
||||
}
|
||||
|
||||
function ReviewPanelContent(props: { review: SessionReviewModel }) {
|
||||
function ReviewPanelContent(props: { review: SessionReviewModel; openInApp: OpenInAppState }) {
|
||||
return (
|
||||
<div class="flex flex-col h-full overflow-hidden bg-v2-background-bg-base contain-strict">
|
||||
<Show when={props.review.panelRendered()}>
|
||||
<ReviewPanel
|
||||
openInApp={props.openInApp}
|
||||
title={<ReviewTitle review={props.review} />}
|
||||
collapsedTitle={<ReviewTitle review={props.review} />}
|
||||
empty={<ReviewPanelEmpty review={props.review} />}
|
||||
diffs={props.review.diffs()}
|
||||
diffsReady={props.review.ready()}
|
||||
@@ -238,14 +238,26 @@ function ReviewTitle(props: { review: SessionReviewModel }) {
|
||||
}
|
||||
return (
|
||||
<Show when={props.review.canReview()}>
|
||||
<Select
|
||||
options={props.review.options()}
|
||||
current={props.review.mode()}
|
||||
label={label}
|
||||
placement="bottom-start"
|
||||
gutter={6}
|
||||
onSelect={(option) => option && props.review.setMode(option)}
|
||||
/>
|
||||
<Show
|
||||
when={props.review.options().length === 1}
|
||||
fallback={
|
||||
<Select
|
||||
options={props.review.options()}
|
||||
current={props.review.mode()}
|
||||
label={label}
|
||||
placement="bottom-start"
|
||||
gutter={6}
|
||||
onSelect={(option) => option && props.review.setMode(option)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<span
|
||||
data-slot="session-review-source-label"
|
||||
class="inline-flex h-6 items-center ps-2 pe-1 text-[13px] leading-[var(--line-height-compact)] font-[530] tracking-[-0.04px] text-v2-text-text-base"
|
||||
>
|
||||
{label(props.review.options()[0]!)}
|
||||
</span>
|
||||
</Show>
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,13 +3,22 @@ import "./session-review-v2.css"
|
||||
|
||||
export function SessionFilePanelV2(props: {
|
||||
sidebar?: JSX.Element
|
||||
sidebarToggle?: JSX.Element
|
||||
sidebarToggleGap?: 2 | 10
|
||||
sidebarCollapsed?: boolean
|
||||
toolbar: boolean
|
||||
toolbarStart?: JSX.Element
|
||||
toolbarEnd?: JSX.Element
|
||||
children?: JSX.Element
|
||||
}) {
|
||||
return (
|
||||
<div data-component="session-review-v2">
|
||||
<div
|
||||
data-component="session-review-v2"
|
||||
data-sidebar-toggle={props.sidebarToggle ? "" : undefined}
|
||||
data-sidebar-toggle-gap={props.sidebarToggleGap}
|
||||
data-sidebar-collapsed={props.sidebarCollapsed ? "" : undefined}
|
||||
>
|
||||
<div data-slot="session-review-v2-sidebar-toggle">{props.sidebarToggle}</div>
|
||||
<div data-slot="session-review-v2-body">
|
||||
{props.sidebar}
|
||||
<div data-slot="session-review-v2-preview">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
[data-component="session-review-v2"] {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
@@ -7,6 +8,13 @@
|
||||
background: var(--v2-background-bg-base);
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"] [data-slot="session-review-v2-sidebar-toggle"] {
|
||||
position: absolute;
|
||||
inset-block-start: 9.5px;
|
||||
inset-inline-start: 8px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"] [data-slot="session-review-v2-body"] {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
@@ -68,6 +76,14 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"][data-sidebar-toggle] [data-slot="session-review-v2-sidebar-header"] {
|
||||
box-sizing: border-box;
|
||||
height: 48px;
|
||||
padding-block: 0;
|
||||
padding-inline-start: 46px;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2-sidebar-root"] [data-slot="session-review-v2-sidebar-title"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -83,6 +99,10 @@
|
||||
margin-inline-start: 8px;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"][data-sidebar-toggle] [data-slot="session-review-v2-sidebar-title"] {
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2-sidebar-root"]
|
||||
[data-slot="session-review-v2-sidebar-title"]
|
||||
[data-component="select-v2-root"] {
|
||||
@@ -231,16 +251,29 @@
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"] [data-slot="session-review-v2-toolbar"] {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
padding-inline-start: 8px;
|
||||
height: 48px;
|
||||
padding-block: 0;
|
||||
padding-inline: 8px 12px;
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid var(--border-weaker-base, var(--v2-border-border-weak));
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"][data-sidebar-toggle][data-sidebar-collapsed]
|
||||
[data-slot="session-review-v2-toolbar"] {
|
||||
padding-inline-start: 46px;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"][data-sidebar-toggle-gap="10"] [data-slot="session-review-v2-sidebar-header"],
|
||||
[data-component="session-review-v2"][data-sidebar-toggle-gap="10"][data-sidebar-collapsed]
|
||||
[data-slot="session-review-v2-toolbar"] {
|
||||
padding-inline-start: 54px;
|
||||
}
|
||||
|
||||
[data-component="session-review-v2"] [data-slot="session-review-v2-toolbar-group"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -26,10 +26,12 @@ export type SessionReviewV2Props = {
|
||||
empty?: JSX.Element
|
||||
sidebarOpen?: boolean
|
||||
sidebar?: JSX.Element
|
||||
sidebarToggle?: JSX.Element
|
||||
activeFile?: string
|
||||
files: string[]
|
||||
onSelectFile: (file: string) => void
|
||||
diffStyle: SessionReviewDiffStyle
|
||||
toolbarAction?: JSX.Element
|
||||
onDiffStyleChange?: (style: SessionReviewDiffStyle) => void
|
||||
expandMode: SessionReviewExpandMode
|
||||
onExpandModeChange: (mode: SessionReviewExpandMode) => void
|
||||
@@ -265,6 +267,7 @@ export function SessionReviewV2(props: SessionReviewV2Props) {
|
||||
|
||||
const toolbarEnd = () => (
|
||||
<>
|
||||
{props.toolbarAction}
|
||||
<SegmentedControl
|
||||
value={props.expandMode}
|
||||
onChange={(value) => {
|
||||
@@ -313,7 +316,9 @@ export function SessionReviewV2(props: SessionReviewV2Props) {
|
||||
return (
|
||||
<SessionFilePanelV2
|
||||
sidebar={props.sidebar}
|
||||
toolbar={props.hasDiffs}
|
||||
sidebarToggle={props.sidebarToggle}
|
||||
sidebarCollapsed={props.sidebarOpen === false}
|
||||
toolbar={props.hasDiffs || props.sidebarOpen === false}
|
||||
toolbarStart={toolbarStart()}
|
||||
toolbarEnd={toolbarEnd()}
|
||||
>
|
||||
|
||||
@@ -646,61 +646,12 @@
|
||||
[data-component="tabs"]
|
||||
.session-review-v2-tabs-bar
|
||||
[data-slot="tabs-list"]
|
||||
> .sticky:not(.session-review-v2-sidebar-toggle-slot) {
|
||||
> .sticky {
|
||||
left: auto;
|
||||
right: auto;
|
||||
inset-inline-end: 0;
|
||||
}
|
||||
|
||||
:root
|
||||
body
|
||||
#review-panel
|
||||
[data-component="tabs"]
|
||||
.session-review-v2-tabs-bar
|
||||
[data-slot="tabs-list"]
|
||||
> .session-review-v2-sidebar-toggle-slot.sticky {
|
||||
left: auto;
|
||||
right: auto;
|
||||
inset-inline-start: 0;
|
||||
padding-inline-end: 0;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
bottom: auto;
|
||||
inset-inline-start: auto;
|
||||
inset-inline-end: 100%;
|
||||
transform: translateY(-50%);
|
||||
width: 12px;
|
||||
height: 28px;
|
||||
background-color: var(--v2-background-bg-base);
|
||||
background-image: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
inset-inline-start: 100%;
|
||||
inset-inline-end: auto;
|
||||
transform: translateY(-50%);
|
||||
width: 8px;
|
||||
height: 28px;
|
||||
pointer-events: none;
|
||||
background: linear-gradient(90deg, var(--v2-background-bg-base), transparent);
|
||||
}
|
||||
|
||||
&:dir(rtl)::after {
|
||||
background: linear-gradient(270deg, var(--v2-background-bg-base), transparent);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"]::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
:root body #review-panel [data-component="tabs"] .session-review-v2-open-in-app-slot {
|
||||
flex-shrink: 0;
|
||||
margin-inline-start: auto;
|
||||
|
||||
Reference in New Issue
Block a user