Skip to content

Commit 8372285

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(ui): preserve shared tag actions and product styling fallbacks
1 parent 7737344 commit 8372285

8 files changed

Lines changed: 115 additions & 47 deletions

File tree

‎apps/sim/app/_styles/globals.css‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,10 @@ input[type="search"]::-ms-clear {
13581358
background-color: transparent !important;
13591359
color: var(--text-tertiary) !important;
13601360
}
1361+
1362+
html[data-panel-active-tab] .panel-container [data-tab-button] span {
1363+
color: inherit !important;
1364+
}
13611365
}
13621366

13631367
/**

‎apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/document-tags-modal/document-tags-modal.tsx‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
ChipModalField,
1313
ChipModalFooter,
1414
ChipModalHeader,
15-
handleKeyboardActivation,
1615
Label,
1716
} from '@sim/emcn'
1817
import { createLogger } from '@sim/logger'
@@ -386,13 +385,8 @@ export function DocumentTagsModal({
386385
{documentTags.map((tag, index) => (
387386
<div key={tag.displayName} className='space-y-2'>
388387
<KnowledgeTagRow
389-
role='button'
390-
tabIndex={0}
391-
onClick={() => startEditingTag(index)}
392-
onKeyDown={(event) => {
393-
if (event.target !== event.currentTarget) return
394-
handleKeyboardActivation(event, () => startEditingTag(index))
395-
}}
388+
onActivate={() => startEditingTag(index)}
389+
activateLabel={`Edit ${tag.displayName}`}
396390
name={tag.displayName}
397391
typeLabel={FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType}
398392
detail={formatValueForDisplay(tag.value, tag.fieldType)}

‎apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/base-tags-modal/base-tags-modal.tsx‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
ChipModalFooter,
1313
ChipModalHeader,
1414
type ComboboxOption,
15-
handleKeyboardActivation,
1615
} from '@sim/emcn'
1716
import { createLogger } from '@sim/logger'
1817
import { getDocumentIcon } from '@/components/icons/document-icons'
@@ -272,13 +271,8 @@ export function BaseTagsModal({ open, onOpenChange, knowledgeBaseId }: BaseTagsM
272271
return (
273272
<KnowledgeTagRow
274273
key={tag.id}
275-
role='button'
276-
tabIndex={0}
277-
onClick={() => handleViewDocuments(tag)}
278-
onKeyDown={(event) => {
279-
if (event.target !== event.currentTarget) return
280-
handleKeyboardActivation(event, () => handleViewDocuments(tag))
281-
}}
274+
onActivate={() => handleViewDocuments(tag)}
275+
activateLabel={`View documents for ${tag.displayName}`}
282276
name={tag.displayName}
283277
typeLabel={FIELD_TYPE_LABELS[tag.fieldType] || tag.fieldType}
284278
detail={
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/** @vitest-environment jsdom */
2+
import { act } from 'react'
3+
import { createRoot, type Root } from 'react-dom/client'
4+
import { afterEach, describe, expect, it, vi } from 'vitest'
5+
import { KnowledgeTagRow } from './knowledge-tag-row'
6+
7+
let root: Root | undefined
8+
let container: HTMLDivElement | undefined
9+
10+
afterEach(() => {
11+
act(() => root?.unmount())
12+
container?.remove()
13+
})
14+
15+
describe('KnowledgeTagRow actions', () => {
16+
it('keeps activation and removal as separate keyboard-accessible buttons', () => {
17+
Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true })
18+
container = document.createElement('div')
19+
document.body.appendChild(container)
20+
root = createRoot(container)
21+
const onActivate = vi.fn()
22+
const onRemove = vi.fn()
23+
24+
act(() =>
25+
root?.render(
26+
<KnowledgeTagRow
27+
name='Customer'
28+
typeLabel='Text'
29+
detail='3 documents'
30+
activateLabel='View documents for Customer'
31+
removeLabel='Delete tag'
32+
onActivate={onActivate}
33+
onRemove={onRemove}
34+
/>
35+
)
36+
)
37+
38+
const buttons = container.querySelectorAll('button')
39+
expect(buttons).toHaveLength(2)
40+
expect(buttons[0].contains(buttons[1])).toBe(false)
41+
expect(buttons[0].getAttribute('type')).toBe('button')
42+
expect(buttons[0].getAttribute('aria-label')).toBe('View documents for Customer')
43+
44+
act(() => buttons[0].click())
45+
expect(onActivate).toHaveBeenCalledTimes(1)
46+
expect(onRemove).not.toHaveBeenCalled()
47+
48+
act(() => buttons[1].click())
49+
expect(onActivate).toHaveBeenCalledTimes(1)
50+
expect(onRemove).toHaveBeenCalledTimes(1)
51+
})
52+
})
Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import type { HTMLAttributes, MouseEventHandler, ReactNode } from 'react'
1+
import type { MouseEventHandler, ReactNode } from 'react'
22
import { Button, cn } from '@sim/emcn'
33
import { Trash } from '@sim/emcn/icons'
44

5-
interface KnowledgeTagRowProps
6-
extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'className'> {
5+
interface KnowledgeTagRowProps {
76
name: string
87
typeLabel: string
98
detail: ReactNode
109
truncateDetail?: boolean
10+
activateLabel: string
1111
removeLabel: string
12+
onActivate: MouseEventHandler<HTMLButtonElement>
1213
onRemove: MouseEventHandler<HTMLButtonElement>
1314
}
1415

@@ -18,38 +19,45 @@ export function KnowledgeTagRow({
1819
typeLabel,
1920
detail,
2021
truncateDetail = false,
22+
activateLabel,
2123
removeLabel,
24+
onActivate,
2225
onRemove,
23-
...props
2426
}: KnowledgeTagRowProps) {
2527
return (
26-
<div
27-
{...props}
28-
className='flex cursor-pointer items-center gap-2 rounded-sm border p-2 hover-hover:bg-[var(--surface-2)]'
29-
>
30-
<span className='min-w-0 truncate text-[var(--text-primary)] text-caption'>{name}</span>
31-
<span className='rounded-sm bg-[var(--surface-3)] px-1.5 py-0.5 text-[var(--text-muted)] text-micro'>
32-
{typeLabel}
33-
</span>
34-
<div className='mb-[-1.5px] h-[14px] w-[1.25px] shrink-0 rounded-full bg-[var(--border-1)]' />
35-
<span
36-
className={cn(
37-
'min-w-0 flex-1 text-[var(--text-muted)] text-caption',
38-
truncateDetail && 'truncate'
39-
)}
28+
<div className='flex items-center rounded-sm border hover-hover:bg-[var(--surface-2)]'>
29+
<button
30+
type='button'
31+
onClick={onActivate}
32+
aria-label={activateLabel}
33+
className='flex min-w-0 flex-1 cursor-pointer items-center gap-2 p-2 text-left'
4034
>
41-
{detail}
42-
</span>
43-
<div className='flex shrink-0 items-center gap-1'>
44-
<Button
45-
aria-label={removeLabel}
46-
variant='ghost-destructive-muted'
47-
onClick={onRemove}
48-
size='icon'
35+
<span className='min-w-0 truncate text-[var(--text-primary)] text-caption'>{name}</span>
36+
<span className='rounded-sm bg-[var(--surface-3)] px-1.5 py-0.5 text-[var(--text-muted)] text-micro'>
37+
{typeLabel}
38+
</span>
39+
<span
40+
aria-hidden='true'
41+
className='mb-[-1.5px] h-[14px] w-[1.25px] shrink-0 rounded-full bg-[var(--border-1)]'
42+
/>
43+
<span
44+
className={cn(
45+
'min-w-0 flex-1 text-[var(--text-muted)] text-caption',
46+
truncateDetail && 'truncate'
47+
)}
4948
>
50-
<Trash className='size-3' />
51-
</Button>
52-
</div>
49+
{detail}
50+
</span>
51+
</button>
52+
<Button
53+
aria-label={removeLabel}
54+
variant='ghost-destructive-muted'
55+
onClick={onRemove}
56+
size='icon'
57+
className='mr-2'
58+
>
59+
<Trash className='size-3' />
60+
</Button>
5361
</div>
5462
)
5563
}

‎apps/sim/app/workspace/[workspaceId]/logs/logs.tsx‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,7 +1585,13 @@ function LogsFilterPanel({ searchQuery, onSearchQueryChange }: LogsFilterPanelPr
15851585
</div>
15861586

15871587
{filtersActive && (
1588-
<Chip variant='border-shadow' fullWidth onClick={handleClearFilters} align='center'>
1588+
<Chip
1589+
variant='border-shadow'
1590+
fullWidth
1591+
onClick={handleClearFilters}
1592+
align='center'
1593+
className='h-[32px]'
1594+
>
15891595
Clear All Filters
15901596
</Chip>
15911597
)}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.description {
2+
color: var(--text-muted);
3+
}
4+
5+
@supports (color: color-mix(in srgb, red, blue)) {
6+
.description {
7+
color: color-mix(in srgb, var(--text-muted) 60%, transparent);
8+
}
9+
}

‎apps/sim/components/auth/public-auth-header.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ReactNode } from 'react'
2+
import styles from './public-auth-header.module.css'
23

34
interface PublicAuthHeaderProps {
45
title: ReactNode
@@ -12,7 +13,7 @@ export function PublicAuthHeader({ title, description }: PublicAuthHeaderProps)
1213
<h1 className='text-balance text-[var(--text-primary)] text-display leading-[110%] tracking-[-0.02em]'>
1314
{title}
1415
</h1>
15-
<p className='text-[color-mix(in_srgb,var(--text-muted)_60%,transparent)] text-lg leading-[125%] tracking-[0.02em]'>
16+
<p className={`${styles.description} text-lg leading-[125%] tracking-[0.02em]`}>
1617
{description}
1718
</p>
1819
</div>

0 commit comments

Comments
 (0)