Skip to content

feat: data collection reference row#3585

Merged
FaithAdekunle merged 2 commits intomainfrom
data-collection-reference-row
Mar 11, 2026
Merged

feat: data collection reference row#3585
FaithAdekunle merged 2 commits intomainfrom
data-collection-reference-row

Conversation

@FaithAdekunle
Copy link
Copy Markdown
Contributor

@FaithAdekunle FaithAdekunle commented Mar 4, 2026

Description

Adds support for “reference rows” in the experimental OneDataCollection Table visualization so consumers can visually distinguish specific records (e.g. baselines/targets) via a slanted background pattern.

In the current financial workspace custom table, each column value in the parent row represents the sum of the Labor Cost and Employee Cost values.
The Agreement Cost is also displayed as a child row, but it does not contribute to the total shown in the parent row. To make this clear, the Agreement Cost row is displayed as a reference row with a distinct visual style, indicating that its values are informational only and excluded from the parent total calculation.
Screenshot 2026-03-09 at 09 11 26

This PR supports the migration of the Financial Workspace table to OneDataCollection, which currently lacks support for reference rows. The change ensures we can adopt OneDataCollection while preserving the existing visual behavior, where Agreement Cost appears as a reference row to indicate that it is informational and excluded from the parent row total (Labor Cost + Employee Cost).
Screenshot 2026-03-09 at 09 17 54

Link to Figma Design

Implementation details

  • Extends TableVisualizationOptions with an isReferenceRow(item) predicate.
  • Threads the predicate through TableCollection → Row/NestedRow and applies a striped background class when it matches.
  • Updates Storybook docs/stories and mock data to demonstrate reference rows.

Copilot AI review requested due to automatic review settings March 4, 2026 08:54
@github-actions github-actions bot added feat react Changes affect packages/react labels Mar 4, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 4, 2026

✅ No New Circular Dependencies

No new circular dependencies detected. Current count: 0

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for “reference rows” in the experimental OneDataCollection Table visualization so consumers can visually distinguish specific records (e.g. baselines/targets) via a slanted background pattern.

Changes:

  • Extends TableVisualizationOptions with an isReferenceRow(item) predicate.
  • Threads the predicate through TableCollectionRow/NestedRow and applies a striped background class when it matches.
  • Updates Storybook docs/stories and mock data to demonstrate reference rows.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/types.ts Adds isReferenceRow option and documents the feature.
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/components/Row.tsx Applies the reference-row background styling and passes the predicate into nested row rendering.
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/components/NestedRow.tsx Extends nested row props to carry the reference-row predicate through recursion.
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/Table.tsx Plumbs isReferenceRow from visualization options into row rendering (flat + grouped).
packages/react/src/experimental/OneDataCollection/stories/visualizations/table/table.stories.tsx Adds a Storybook story showcasing reference rows (including frozen columns).
packages/react/src/experimental/OneDataCollection/stories/visualizations/table/table.mdx Documents isReferenceRow and includes an example + canvas.
packages/react/src/experimental/OneDataCollection/stories/mockData.tsx Adds mock visualization wiring for reference rows.

Comment on lines +179 to +195
@@ -182,7 +191,8 @@ const RowComponentInner = <
"after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-px after:w-full after:bg-f1-border-secondary after:content-['']",
noBorder && "after:bg-white-100",
disableHover && "hover:bg-transparent",
isSelected && "bg-f1-background-selected-secondary"
isSelected && "bg-f1-background-selected-secondary",
isReferenceRow && referenceRowClass
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference row background is applied on the , but some cells (notably sticky right item-actions, and sticky cells when horizontally scrolled) render with an explicit solid background in experimental/OneTable/TableCell (e.g. bg-f1-background / before:bg-f1-background). That will cover the slanted pattern, so the “full row” treatment won’t actually be visible across all columns. Consider propagating the reference-row state into TableCell (e.g. via a data-attribute on the row and group-data selectors, or a CSS var for the row background that sticky cells use) so sticky cells can render the same pattern (and matching hover behavior).

Copilot uses AI. Check for mistakes.
disableHover && "hover:bg-transparent",
isSelected && "bg-f1-background-selected-secondary"
isSelected && "bg-f1-background-selected-secondary",
isReferenceRow && referenceRowClass
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isSelected and isReferenceRow can both be true, but the current class order applies the reference background after the selected background, which will override the selected styling (due to bg-* conflicts). If selected state should remain visually apparent, make the precedence explicit (e.g. selected wins over reference, or implement a combined style that preserves both).

Suggested change
isReferenceRow && referenceRowClass
isReferenceRow && !isSelected && referenceRowClass

Copilot uses AI. Check for mistakes.
Comment on lines +180 to +181
// Applies the slanted stripe pattern to the whole reference row.
// This is the base background that creates the visual "reference" treatment.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments explain what the code is doing rather than why (and restate what the class name already implies). Consider removing them or rewriting to capture the intent/constraint (e.g. why the specific gradient values are needed, or what design requirement it satisfies).

Suggested change
// Applies the slanted stripe pattern to the whole reference row.
// This is the base background that creates the visual "reference" treatment.
// Visual treatment for "reference" rows: a subtle diagonal stripe that remains legible
// on top of hover/selection backgrounds while being distinguishable from regular rows.

Copilot uses AI. Check for mistakes.

/**
* Marks one or more rows as reference rows.
* Reference rows are rendered with a slanted background pattern across the full row.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring says the reference pattern is rendered “across the full row”, but with the current implementation (pattern only on the ) some cells can paint an explicit background (e.g. sticky cells / item actions), which prevents the pattern from being visible across all columns. Either adjust the wording to match the actual behavior or update the implementation so all cells (including sticky) show the reference treatment.

Suggested change
* Reference rows are rendered with a slanted background pattern across the full row.
* Reference rows are rendered with a slanted background pattern to distinguish them.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 4, 2026

📦 Alpha Package Version Published

Use pnpm i github:factorialco/f0#npm/alpha-pr-3585 to install the package

Use pnpm i github:factorialco/f0#f7d67e08cf2334f73bac36e653402f5b4a15dde6 to install this specific commit

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 4, 2026

🔍 Visual review for your branch is published 🔍

Here are the links to:

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 4, 2026

Coverage Report for packages/react

Status Category Percentage Covered / Total
🔵 Lines 43.72% 9240 / 21131
🔵 Statements 43.09% 9505 / 22056
🔵 Functions 35.57% 2084 / 5858
🔵 Branches 33.9% 5641 / 16636
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/react/src/experimental/OneDataCollection/__stories__/mockData.tsx 0% 0% 0% 0% 80-1890
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/Table.tsx 74.19% 52.5% 60.71% 74.44% 55-71, 225-229, 397, 445, 476-555, 572, 597-676
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/types.ts 100% 100% 100% 100%
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/components/NestedRow.tsx 85.96% 78.12% 90% 85.96% 131, 160, 242, 263-291, 318-325
packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/components/Row.tsx 100% 78.04% 100% 100%
packages/react/src/experimental/OneTable/TableCell/index.tsx 78.26% 63.63% 50% 78.26% 227-236
Generated in workflow #11620 for commit 16c4431 by the Vitest Coverage Report Action

@FaithAdekunle FaithAdekunle marked this pull request as ready for review March 4, 2026 09:12
@FaithAdekunle FaithAdekunle requested a review from a team as a code owner March 4, 2026 09:12
Comment on lines +90 to +94

/**
* Marks rows as reference rows. Reference rows are rendered with a slanted background pattern.
*/
isReferenceRow?: (item: T) => boolean
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just wondering, what if tomorrow we want another type of "reference" rows with another background pattern completely different? Maybe we should let each item define its own reference type, starting with one type for now

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference row is purely a visual concept. I don't see the need for label. I do however understand the advantage in supporting different reference types

@FaithAdekunle FaithAdekunle force-pushed the data-collection-reference-row branch from 4e26306 to 00c9061 Compare March 8, 2026 17:03
Copilot AI review requested due to automatic review settings March 9, 2026 09:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Comment on lines +79 to +87
const stripedLines =
"repeating-linear-gradient(45deg,transparent_0px,transparent_8px,hsl(var(--neutral-20))_8px,hsl(var(--neutral-20))_9px)"

const stickyScrolledBase =
"before:absolute before:inset-0 before:z-[-1] before:h-[calc(100%-1px)] before:w-full before:transition-all before:content-[''] after:absolute after:inset-x-0 after:bottom-0 after:h-px after:w-full after:bg-f1-border-secondary after:content-['']"

const stickyScrollClasses: Record<ReferenceType, string> = {
none: `bg-f1-background ${stickyScrolledBase} before:bg-f1-background group-hover:before:bg-f1-background-hover`,
striped: `bg-f1-background bg-[${stripedLines}] [background-size:100%_100px] ${stickyScrolledBase} before:bg-[${stripedLines},_var(--f1-background)] before:[background-size:100%_100px,_100%_100%] group-hover:before:bg-[${stripedLines},_var(--f1-background-hover)] group-hover:before:[background-size:100%_100px,_100%_100%]`,
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Tailwind class strings for the striped sticky state are built using template interpolation (e.g. bg-[${stripedLines}]). Tailwind’s content scanner won’t pick up interpolated arbitrary-value classes, so the corresponding CSS likely won’t be generated and the striped background won’t render. Inline the full arbitrary-value classes as plain string literals (or switch to a style={{ backgroundImage: ... }} approach for the gradients) so Tailwind can statically detect them.

Suggested change
const stripedLines =
"repeating-linear-gradient(45deg,transparent_0px,transparent_8px,hsl(var(--neutral-20))_8px,hsl(var(--neutral-20))_9px)"
const stickyScrolledBase =
"before:absolute before:inset-0 before:z-[-1] before:h-[calc(100%-1px)] before:w-full before:transition-all before:content-[''] after:absolute after:inset-x-0 after:bottom-0 after:h-px after:w-full after:bg-f1-border-secondary after:content-['']"
const stickyScrollClasses: Record<ReferenceType, string> = {
none: `bg-f1-background ${stickyScrolledBase} before:bg-f1-background group-hover:before:bg-f1-background-hover`,
striped: `bg-f1-background bg-[${stripedLines}] [background-size:100%_100px] ${stickyScrolledBase} before:bg-[${stripedLines},_var(--f1-background)] before:[background-size:100%_100px,_100%_100%] group-hover:before:bg-[${stripedLines},_var(--f1-background-hover)] group-hover:before:[background-size:100%_100px,_100%_100%]`,
const stickyScrolledBase =
"before:absolute before:inset-0 before:z-[-1] before:h-[calc(100%-1px)] before:w-full before:transition-all before:content-[''] after:absolute after:inset-x-0 after:bottom-0 after:h-px after:w-full after:bg-f1-border-secondary after:content-['']"
const stickyScrollClasses: Record<ReferenceType, string> = {
none: `bg-f1-background ${stickyScrolledBase} before:bg-f1-background group-hover:before:bg-f1-background-hover`,
striped: `bg-f1-background bg-[repeating-linear-gradient(45deg,transparent_0px,transparent_8px,hsl(var(--neutral-20))_8px,hsl(var(--neutral-20))_9px)] [background-size:100%_100px] ${stickyScrolledBase} before:bg-[repeating-linear-gradient(45deg,transparent_0px,transparent_8px,hsl(var(--neutral-20))_8px,hsl(var(--neutral-20))_9px),_var(--f1-background)] before:[background-size:100%_100px,_100%_100%] group-hover:before:bg-[repeating-linear-gradient(45deg,transparent_0px,transparent_8px,hsl(var(--neutral-20))_8px,hsl(var(--neutral-20))_9px),_var(--f1-background-hover)] group-hover:before:[background-size:100%_100px,_100%_100%]`,

Copilot uses AI. Check for mistakes.
isFirstCellWithTableChildren,
SPACING_FACTOR,
} from "./utils/nested"
import { ReferenceType } from "@/experimental/OneDataCollection/visualizations/collection/Table"
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReferenceType is a type-only export, but it’s imported as a value import from the OneDataCollection Table module. This risks (1) a circular dependency between experimental/OneTable and experimental/OneDataCollection, and (2) a runtime import of a type that doesn’t exist in the emitted JS depending on the bundler. Prefer import type { ReferenceType } from "@/experimental/OneDataCollection/visualizations/collection/Table/types" or (ideally) move/shared this type in OneTable so OneTable doesn’t depend on OneDataCollection.

Suggested change
import { ReferenceType } from "@/experimental/OneDataCollection/visualizations/collection/Table"
import type { ReferenceType } from "@/experimental/OneDataCollection/visualizations/collection/Table/types"

Copilot uses AI. Check for mistakes.
Comment on lines 185 to 187
const isSelected = id !== undefined && selectedItems.has(id)
const referenceRowType = referenceRowTypeFn?.(item) ?? "none"

Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

referenceRowType is added as a new user-facing table option and affects rendering, but there’s no corresponding unit test asserting that reference rows receive the expected styling (and that sticky cells preserve the reference-row background when scrolled). Since this table already has a comprehensive test suite, please add coverage for this new option.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +73 to +74
/** Optional predicate to mark a row as reference row with slanted background pattern. */
referenceRowType?: (item: R) => "none" | "striped"
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NestedRow types referenceRowType as a hardcoded union ("none" | "striped") instead of reusing the shared ReferenceType type from ../types. This creates duplication and makes future additions (new reference row styles) easy to miss. Import and reuse ReferenceType here for consistency with Row.tsx and the public options type.

Copilot uses AI. Check for mistakes.
Comment on lines +102 to +106
/**
* Marks one or more rows as reference rows.
* Reference rows are rendered with a slanted background pattern across the full row.
*/
referenceRowType?: (item: R) => ReferenceType
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description mentions adding an isReferenceRow(item) predicate, but the shipped public API is referenceRowType(item). Please align the PR description (or rename the option) so consumers and reviewers aren’t looking for the wrong API.

Copilot uses AI. Check for mistakes.
{
type: "table",
options: {
referenceRowType: (item) => item.status === "inactive" ? 'striped' | 'none',
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example for referenceRowType is invalid TypeScript: the ternary uses ? 'striped' | 'none' instead of ? "striped" : "none". As written, readers will copy/paste a broken snippet. Please fix the example expression (and ideally match the string quote style used elsewhere in the docs).

Suggested change
referenceRowType: (item) => item.status === "inactive" ? 'striped' | 'none',
referenceRowType: (item) =>
item.status === "inactive" ? "striped" : "none",

Copilot uses AI. Check for mistakes.
@FaithAdekunle FaithAdekunle requested a review from sauldom102 March 9, 2026 09:45
@FaithAdekunle FaithAdekunle force-pushed the data-collection-reference-row branch from 81ced33 to 16c4431 Compare March 11, 2026 07:45
@FaithAdekunle FaithAdekunle merged commit 820243f into main Mar 11, 2026
20 checks passed
@FaithAdekunle FaithAdekunle deleted the data-collection-reference-row branch March 11, 2026 07:57
@eliseo-juan eliseo-juan mentioned this pull request Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat react Changes affect packages/react

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants