Skip to content

Commit 32d2300

Browse files
committed
fix(md-render): fix cloneElement type error and include tables improvements
- Fix TypeScript build error: type isValidElement<Record<string, unknown>> so cloneElement accepts data-block prop - Column sidebar: use CSS min() for responsive width instead of fixed 400px - Table: boolean cell toggle only fires when clicking the checkbox element directly (via data-boolean-cell-toggle), not anywhere on the cell - Table: double-clicking a boolean cell no longer opens edit mode - Table: move row-select mousedown to the <td> to widen the hit target - Table: run/stop button prevents row-select on mousedown - Table: SelectAllCheckbox made keyboard-accessible; checkbox is pointer-events-none
1 parent 51db465 commit 32d2300

5 files changed

Lines changed: 74 additions & 38 deletions

File tree

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,9 @@ const STATIC_MARKDOWN_COMPONENTS = {
487487
pre: ({ children }: { children?: React.ReactNode }) => (
488488
<>
489489
{Children.map(children, (child) =>
490-
isValidElement(child) ? cloneElement(child, { 'data-block': 'true' }) : child
490+
isValidElement<Record<string, unknown>>(child)
491+
? cloneElement(child, { 'data-block': 'true' })
492+
: child
491493
) ?? children}
492494
</>
493495
),

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-sidebar/column-sidebar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import {
6363
} from '@/hooks/queries/tables'
6464
import { useWorkflowState, workflowKeys } from '@/hooks/queries/workflows'
6565
import type { WorkflowMetadata } from '@/stores/workflows/registry/types'
66+
import { COLUMN_SIDEBAR_WIDTH_CSS } from '../table/constants'
6667
import { COLUMN_TYPE_OPTIONS, type SidebarColumnType } from './column-types'
6768

6869
export type ColumnConfigState =
@@ -1017,9 +1018,10 @@ export function ColumnSidebar({
10171018
role='dialog'
10181019
aria-label='Configure column'
10191020
className={cn(
1020-
'absolute top-0 right-0 bottom-0 z-[var(--z-modal)] flex w-[400px] flex-col overflow-hidden border-[var(--border)] border-l bg-[var(--bg)] shadow-overlay transition-transform duration-200 ease-out',
1021+
'absolute top-0 right-0 bottom-0 z-[var(--z-modal)] flex flex-col overflow-hidden border-[var(--border)] border-l bg-[var(--bg)] shadow-md transition-transform duration-200 ease-out',
10211022
open ? 'translate-x-0' : 'translate-x-full'
10221023
)}
1024+
style={{ width: COLUMN_SIDEBAR_WIDTH_CSS }}
10231025
>
10241026
<div className='flex h-full flex-col'>
10251027
<div className='flex items-center justify-between border-[var(--border)] border-b px-3 py-2'>

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table/cells/cell-content.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ export function CellContent({
119119
<div
120120
className={cn('flex min-h-[20px] items-center justify-center', isEditing && 'invisible')}
121121
>
122-
<Checkbox size='sm' checked={Boolean(value)} className='pointer-events-none' />
122+
<span data-boolean-cell-toggle className='inline-flex'>
123+
<Checkbox size='sm' checked={Boolean(value)} className='pointer-events-none' />
124+
</span>
123125
</div>
124126
)
125127
} else if (!isNull && column.type === 'json') {

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ export const SELECTION_TINT_BG = 'bg-[rgba(37,99,235,0.06)]'
44
/** Default column width in pixels. Used as a fallback when a column hasn't
55
* been measured yet and as the initial width for newly-added columns. */
66
export const COL_WIDTH = 160
7+
8+
/** Column config sidebar width: roomy by default, bounded on narrow screens. */
9+
export const COLUMN_SIDEBAR_WIDTH_CSS = 'min(480px, calc(100vw - 48px))'

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table/table.tsx

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import { RowModal } from '../row-modal'
6666
import { TableFilter } from '../table-filter'
6767
import { CellContent } from './cells/cell-content'
6868
import { ExpandedCellPopover } from './cells/expanded-cell-popover'
69-
import { COL_WIDTH, SELECTION_TINT_BG } from './constants'
69+
import { COL_WIDTH, COLUMN_SIDEBAR_WIDTH_CSS, SELECTION_TINT_BG } from './constants'
7070
import { ColumnHeaderMenu } from './headers/column-header-menu'
7171
import { COLUMN_TYPE_ICONS } from './headers/column-type-icon'
7272
import { WorkflowGroupMetaCell } from './headers/workflow-group-meta-cell'
@@ -94,8 +94,6 @@ const COL_WIDTH_AUTO_FIT_MAX = 1000
9494
// row-by-row.
9595
const CHECKBOX_COL_WIDTH = 56
9696
const ADD_COL_WIDTH = 120
97-
/** Width of the column-config slideout (matches `column-sidebar.tsx`'s `w-[400px]`). */
98-
const COLUMN_SIDEBAR_WIDTH = 400
9997
const SKELETON_COL_COUNT = 4
10098
const SKELETON_ROW_COUNT = 10
10199
const ROW_HEIGHT_ESTIMATE = 35
@@ -1218,29 +1216,35 @@ export function Table({
12181216
return () => cancelAnimationFrame(rafId)
12191217
}, [selectionAnchor, selectionFocus, isColumnSelection])
12201218

1221-
const handleCellClick = useCallback((rowId: string, columnName: string) => {
1222-
const column = columnsRef.current.find((c) => c.name === columnName)
1223-
if (column?.type === 'boolean') {
1224-
if (!canEditRef.current) return
1225-
const row = rowsRef.current.find((r) => r.id === rowId)
1226-
if (row) {
1227-
toggleBooleanCell(rowId, columnName, row.data[columnName])
1219+
const handleCellClick = useCallback(
1220+
(rowId: string, columnName: string, options?: { toggleBoolean?: boolean }) => {
1221+
const column = columnsRef.current.find((c) => c.name === columnName)
1222+
if (column?.type === 'boolean') {
1223+
if (!options?.toggleBoolean || !canEditRef.current) return
1224+
const row = rowsRef.current.find((r) => r.id === rowId)
1225+
if (row) {
1226+
toggleBooleanCell(rowId, columnName, row.data[columnName])
1227+
}
1228+
return
12281229
}
1229-
return
1230-
}
12311230

1232-
const current = editingCellRef.current
1233-
if (current && current.rowId === rowId && current.columnName === columnName) return
1234-
setEditingCell(null)
1235-
setInitialCharacter(null)
1236-
}, [])
1231+
const current = editingCellRef.current
1232+
if (current && current.rowId === rowId && current.columnName === columnName) return
1233+
setEditingCell(null)
1234+
setInitialCharacter(null)
1235+
},
1236+
[]
1237+
)
12371238

12381239
// The cell has `select-none` which suppresses programmatic selection, so we
12391240
// override `user-select` on the inner element until the next click. The popover
12401241
// only opens when the leaf's scroll dimensions exceed its client dimensions
12411242
// (workflow cells nest text inside a span with its own `overflow-clip`).
12421243
const handleCellDoubleClick = useCallback(
12431244
(rowId: string, columnName: string, columnKey: string) => {
1245+
const column = columnsRef.current.find((c) => c.key === columnKey)
1246+
if (column?.type === 'boolean') return
1247+
12441248
setSelectionFocus(null)
12451249
setIsColumnSelection(false)
12461250

@@ -2080,11 +2084,11 @@ export function Table({
20802084
* The two panels are mutually exclusive (each opener closes the other).
20812085
*/
20822086
const logPanelWidth = useLogDetailsUIStore((state) => state.panelWidth)
2083-
const sidebarReservedPx = configState
2084-
? COLUMN_SIDEBAR_WIDTH
2087+
const sidebarReservedWidth = configState
2088+
? COLUMN_SIDEBAR_WIDTH_CSS
20852089
: executionDetailsId
2086-
? logPanelWidth
2087-
: 0
2090+
? `${logPanelWidth}px`
2091+
: '0px'
20882092

20892093
const handleConfigureColumn = useCallback((columnName: string) => {
20902094
setExecutionDetailsId(null)
@@ -2578,8 +2582,8 @@ export function Table({
25782582
<div
25792583
className='relative h-fit'
25802584
style={{
2581-
width: `${tableWidth + sidebarReservedPx}px`,
2582-
paddingRight: sidebarReservedPx,
2585+
width: `calc(${tableWidth}px + ${sidebarReservedWidth})`,
2586+
paddingRight: sidebarReservedWidth,
25832587
}}
25842588
>
25852589
<table
@@ -2989,7 +2993,7 @@ interface DataRowProps {
29892993
initialCharacter: string | null
29902994
pendingCellValue: Record<string, unknown> | null
29912995
normalizedSelection: NormalizedSelection | null
2992-
onClick: (rowId: string, columnName: string) => void
2996+
onClick: (rowId: string, columnName: string, options?: { toggleBoolean?: boolean }) => void
29932997
onDoubleClick: (rowId: string, columnName: string, columnKey: string) => void
29942998
onSave: (rowId: string, columnName: string, value: unknown, reason: SaveReason) => void
29952999
onCancel: () => void
@@ -3115,15 +3119,15 @@ const DataRow = React.memo(function DataRow({
31153119

31163120
return (
31173121
<tr onContextMenu={(e) => onContextMenu(e, row)}>
3118-
<td className={cn(CELL_CHECKBOX, 'cursor-pointer')}>
3122+
<td
3123+
className={cn(CELL_CHECKBOX, 'cursor-pointer')}
3124+
onMouseDown={(e) => {
3125+
if (e.button !== 0) return
3126+
onRowToggle(rowIndex, e.shiftKey)
3127+
}}
3128+
>
31193129
<div className='flex items-center justify-center gap-1'>
3120-
<div
3121-
className='group/checkbox flex h-[20px] w-[24px] shrink-0 items-center justify-center'
3122-
onMouseDown={(e) => {
3123-
if (e.button !== 0) return
3124-
onRowToggle(rowIndex, e.shiftKey)
3125-
}}
3126-
>
3130+
<div className='group/checkbox flex h-[20px] w-[24px] shrink-0 items-center justify-center'>
31273131
<span
31283132
className={cn(
31293133
'text-[var(--text-tertiary)] text-xs tabular-nums',
@@ -3147,6 +3151,9 @@ const DataRow = React.memo(function DataRow({
31473151
aria-label={runningCount > 0 ? `Stop ${runningCount} running` : 'Run row'}
31483152
title={runningCount > 0 ? `Stop ${runningCount} running` : 'Run row'}
31493153
className='ml-auto flex h-[20px] w-[20px] shrink-0 items-center justify-center rounded text-[var(--text-primary)] transition-colors hover-hover:bg-[var(--surface-2)]'
3154+
onMouseDown={(e) => {
3155+
e.stopPropagation()
3156+
}}
31503157
onClick={() => {
31513158
if (runningCount > 0) {
31523159
onStopRow(row.id)
@@ -3192,7 +3199,13 @@ const DataRow = React.memo(function DataRow({
31923199
onCellMouseDown(rowIndex, colIndex, e.shiftKey)
31933200
}}
31943201
onMouseEnter={() => onCellMouseEnter(rowIndex, colIndex)}
3195-
onClick={() => onClick(row.id, column.name)}
3202+
onClick={(e) =>
3203+
onClick(row.id, column.name, {
3204+
toggleBoolean: Boolean(
3205+
(e.target as HTMLElement).closest('[data-boolean-cell-toggle]')
3206+
),
3207+
})
3208+
}
31963209
onDoubleClick={() => onDoubleClick(row.id, column.name, column.key)}
31973210
>
31983211
{isHighlighted && (isMultiCell || isRowChecked) && (
@@ -3307,9 +3320,23 @@ const SelectAllCheckbox = React.memo(function SelectAllCheckbox({
33073320
onCheckedChange: () => void
33083321
}) {
33093322
return (
3310-
<th className={CELL_HEADER_CHECKBOX}>
3323+
<th
3324+
className={cn(CELL_HEADER_CHECKBOX, 'cursor-pointer')}
3325+
role='checkbox'
3326+
aria-checked={checked}
3327+
tabIndex={0}
3328+
onMouseDown={(e) => {
3329+
if (e.button !== 0) return
3330+
onCheckedChange()
3331+
}}
3332+
onKeyDown={(e) => {
3333+
if (e.key !== ' ' && e.key !== 'Enter') return
3334+
e.preventDefault()
3335+
onCheckedChange()
3336+
}}
3337+
>
33113338
<div className='flex items-center justify-center'>
3312-
<Checkbox size='sm' checked={checked} onCheckedChange={onCheckedChange} />
3339+
<Checkbox size='sm' checked={checked} className='pointer-events-none' />
33133340
</div>
33143341
</th>
33153342
)

0 commit comments

Comments
 (0)